#ifndef __CNCOBJ_H_INCLUDED_
#define __CNCOBJ_H_INCLUDED_
// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the CNCOBJ_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// CNCOBJ_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.



#include "cnccls.h"

#include <cali\curvecal.h>
#include <ocv\RobotSpaceMapE1.h>
#include <ocv\RobotSpaceMap.h>









//刀具补偿类型
enum  CUTTER_OFFSET{ CO_OFFSET_NONE = 101, CO_OFFSET_LEFT, CO_OFFSET_RIGHT };

//点胶参数（新版使用）
typedef struct __co_spray_params_{
	int    nOpenTime; //开启时间
	int    nCloseTime;//关闭时间
	int    nPulseNum;//次数
	double nTraceCoef;//跟踪系数
}CO_SPRAY_PARAMS;

//分板参数（新版使用）
typedef struct __co_cut_params_{
	double nStartZpos;  //开始切割的深度位置
	double nEndZpos;    //结束切割的深度位置
}CO_CUT_PARAMS;
 
 
typedef struct __co_scan_result_{
   
	 int horiCount;   //水平扫描数
	 int vertCount;   //垂直扫描数
	 RvScalar_f64  scale;   //新比例: pixelPermm
	 RvSize        pixelPlane;  //像素平面:   pixel^2
	 RvSize_f64    machPlane;   //机械平面 ： mm^2
}CO_SCAN_RESULT;





// This class is exported from the CncObj.dll
class CNCCLS_API CCncObj :public CCurveCal
{
public:
	CCncObj(void);
	virtual ~CCncObj(void);
	
	//cutter motion orientation
	enum {
	   CO_NORMAL=0, //默认走刀方向
	   CO_REVERSE,  //方向走刀
	};
	 
	enum{
		CO_DEFAULT =0,//正常
		CO_NOUP,      //加工后不提刀
		CO_TRANSIT,   //空走
		CO_SKIP,      //跳过
	};


	//显示内容,与扩展RV_UCS_XXXX的flag
	enum{
		CO_EDIT_FINE   = (1<<20),   //精调
		CO_SHOW_CUTTER = (1<<21),   //显示刀具
		//CO_FOCUSED     = (1<<22), //焦点
		//CO_EXCLUDED    = (1<<23), //排除, 使用跳过
		CO_DONE        = (1<<24),   //已经检查或加工过了
		CO_ANGLE       = (1<<25),   //显示角度
		CO_MOTION      = (1<<26),   //路径类型：常规，空走，跳过
		CO_CUTTER_UP   = (1<<27),   //提刀指示符号
	};
	 

	//坐标转换
	enum {
	   CC_DEF = 0, // 比例标定方式
	   CC_RSM    , // 坐标计算， 用于固定视场
	   CC_RSM_E1 , // 坐标计算，且考虑当前视场机械位置,这个用于移动视场
	};
	
  
	BOOL  IsFocused();
	void  SetFocus(BOOL flag);

	void  SetExclude(BOOL flag);
	BOOL  IsExcluded();
	

	//获得路径长度,机械坐标
	virtual double GetMacLength()=0;

	//起始和结束点, 以及方向控制的点的机械坐标，
	//这些点受方向控制 
	virtual RvPoint_f64 GetStartMacPos() ; 
	virtual RvPoint_f64 GetEndMacPos() ;
	virtual RvPoint_f64 GetOrientedMacPosAt(int index) ;
	

	//参考坐标与锚点机械坐标不一相同。
	virtual RvPoint_f64 GetReferMacPos() ;

	//获得对应机械坐标点的图像坐标
	//数量使用GetMacPosCount()获得
	//virtual RvPoint GetCounterCamPos(int index)=0;


	virtual int GetMacPosCount()=0;
	virtual RvPoint_f64 GetMacPosAt(int index) =0;
	virtual void SetMacPosAt(int index, RvPoint_f64 pos) =0;
	virtual RvPoint_f64* GetMacPosArray() =0; 

	int              GetCamPosCount(){ return GetMacPosCount(); };
	virtual RvPoint_f  GetCamPosAt(int index) =0;
	virtual void     SetCamPosAt(int index, RvPoint_f pos)=0;

	//图像的位置不同的锚点下时不一样的。
	//支持普通转换和CC_RSM，CC_RSM_E1 
	virtual void UpdateCamPos() = 0;
	virtual void UpdateMacPos() = 0;

	//双mark对齐计算: 偏移量，旋转中心，角度
	static RvOffset_f64  CalcAlignCoefs(RvPoint_f64 referPos1, RvPoint_f64 referPos2, \
		                                RvPoint_f64 targetPos1, RvPoint_f64 targetPos2, \
										RvPoint_f64* pCenter, double* pAngle);
	
	//单mark对齐计算:偏移量
	static RvOffset_f64  CalcAlignCoefs(RvPoint_f64 referPos , RvPoint_f64 targetPos);

	//镜像位置, referPos1和referPos2是参考直线上的两点
	static RvPoint_f64   CalcMirrorPos(RvPoint_f64 referPos1, RvPoint_f64 referPos2, RvPoint_f64 sourcePos);

	//生成矩阵位置，矩阵中元素位置包括原点
	static int           CalcMatrixPos(RvPoint_f64 originPos , RvPoint_f64 horiPos, RvPoint_f64 vertPos, \
		                               int   rows, int cols, RvPoint_f64* pArrOut, int arrSize);
 
	//计算调整后的新坐标
	static RvPoint_f64   CalcAlignPos(RvPoint_f64 src , double offsetX, double offsetY, double cx, double cy, double angle);
	static RvPoint_f64   CalcAlignPos(RvPoint_f64 src , double offsetX, double offsetY );

	static BOOL  IsArcClockWise(RvPoint start , RvPoint mid, RvPoint end);
	static BOOL  IsArcClockWise(RvPoint_f64 start , RvPoint_f64 mid, RvPoint_f64 end);



	//扫描全景图，根据产品的4个角落位置，和视野大小，和精度，计算扫描图尺寸（像素）和实际比例, 对应的机械平面大小
	//pixelsPerMm -输入/输出
	static  BOOL CalcScanViewSize(RvPoint_f64 leftTop, RvPoint_f64 rightTop, RvPoint_f64 rightBottom, RvPoint_f64 leftBottom, \
		                            RvSize_f64 fovSize, RvScalar_f64  pixelsPerMm, CO_SCAN_RESULT* pScanResult);

	//计算扫描图像素位置对应的机械位置
	static  RvPoint_f64 CalcScanViewMachPos(RvPoint pixPos, RvPoint_f64 machLefTop, RvSize_f64 fovSize, RvScalar_f64  pixelsPerMm); 

 
	//动态主轴相机坐标转换
	//virtual BOOL UpdateCamPos(double curMacX, double curMacY) = 0;
	//virtual BOOL UpdateMacPos(double curMacX, double curMacY) = 0;

	//移动机械坐标。
	void MoveMac(double dx, double dy, BOOL bUpdateCam);

	//移动到某个机械位置
	void MoveMacTo(double x, double y, BOOL bUpdateCam);

	//针对中心点旋转机械坐标
	void RotateMac(double cx, double cy, double angle, BOOL bUpdateCam);

	//支持旋转和平移
	void AlignMac(double offsetX, double offsetY, double cx, double cy, double angle, BOOL bUpdateCam);


	//移动视场位置,仅改变参考位置，不改变位置控制点位置
	//这样，当前视场的CCD位置变化时，加工元也跟着变动
	void MoveView(RvPoint_f64 curpos);


	//走刀方向
	int  GetOrientation();
	void ToppleOrientation();

	RvRect_f64 GetMacRect(){ return m_macRect;};

	static RvPoint_f64   CvtPix2Mac(RvPoint_f  camAnchor , RvPoint_f64  macAnchor, RvScalar_f64  ratio, float x, float y);
	static RvPoint_f     CvtMac2Pix(RvPoint_f64  macAnchor, RvPoint_f  camAnchor, RvScalar_f64  ratio, double x, double y);

	inline double CvtPix2Mac(float n, double ratio) { return n/RV_MAX(0.1, ratio); };
	inline float    CvtMac2Pix(double n, double ratio) { return (float)(n*ratio); };
 
	//移动视场的机械坐标转成图像坐标
	static BOOL  TransToCameraPos(CRobotSpaceMapE1* pRsmE1, RvPoint_f64 machPos, RvPoint_f64 curPos, RvPoint* pCamPos);
	static BOOL  TransToCameraPos(CRobotSpaceMapE1* pRsmE1, RvPoint_f64 machPos, RvPoint_f64 curPos, RvPoint_f* pCamPos);
	 
public:
	virtual void  ShowExtender(CDelegate* pDelegate,CLeadMark* pMark);
	virtual void  ShowGrabber(CDelegate* pDelegate, CLeadMark* pMark);	

	virtual CUCObj* Clone( CUCObj* twin);
	virtual BOOL Serialize(HANDLE device, BOOL bIn );


	//缩放图像坐标
	virtual void Scale(double scale){};
	virtual void Scale(double scaleX, double scaleY){};
	//旋转图像坐标
	virtual void Rotate(double cx, double cy, double angle){};

//
public:
 
	//调整加工元顶点时，自动计算对应的机械坐标
	//默认为FALSE.临时变量，不存储
	BOOL m_bAutoUpdateMacPos; //自动计算

	//机械坐标和图像坐标使用坐标空间换算类型
	//不存储
	int   m_nCcType;

	//,与机械位置对应的点
	//anchor pos
	RvPoint_f     m_apCam; //相机锚点, 

	//加工元的机械位置根据该位置确定
	//这个坐标与referpos不一样，有可能与其相等，也可能不等
	RvPoint_f64 m_apMac; //机械锚点，托盘视场为固定，主轴视场动态变化

	//比例,目前只有x,y: pix / mm
	RvScalar_f64 m_scalar; 

	//映射表,不能声明为static，因为可能有多个视场。
	//不存储
	//CRobotSpaceMap* m_pRsm;

	CRobotSpaceMapE1* m_pRsmE1;

	//当前机械位置:用于CC_RSM_E1计算机械坐标，临时变量
	RvPoint_f64  m_curMacPos;

//工艺变量，需要保存
public:

	//double m_nSpeed;  
	//double m_nAcc;    

	//union{
	//    double nTorque;     //扭力，锁附
	//	DWORD  nFreq;       //频率，点胶
	//	void*  pCustParams; //工艺参数，外部生成，外部释放, CNC OBJ不存储
	//}m_extra;

	double m_nCamWorkPos;    //z轴相机工作位置,过时，仅保留
	double m_nToolWorkPos;   //z轴工具工作位置,过时，仅保留
	
	//该参数用于分板，不保存
	float    m_toolRadius;	 

	//m_nToolUp参数已经合并，改成保留变量供将来使用
	//
 	int   m_nReserved;       //保留将来使用 

	//CO_DEFAULT :正常
	//	CO_NOUP  :加工后不提刀
	//	CO_TRANSIT:空走
	//	CO_SKIP:   跳过
	int   m_nMotionType; //移动类型
 
	int  m_nAppearanceFlags; // 扩展样式显示

protected :
	int m_nOrientation;

	RvPoint_f64 GetReferPoint(RvPoint_f64* pCpArr, int cpCnt);
	void CloneCtrlPos(CCncObj* pSrc, CCncObj* pDst);

	//pCamPts与pMacPts数量相等
	//根据m_nCcType进行机械坐标到像素坐标转换
	//不支持CC_RSM
	BOOL TransformToCam(RvPoint_f64* pMacPts, int count,RvPoint_f64* pCamPts);

	//转换单点图像坐标到机械坐标。
	BOOL TransformToMac(RvPoint_f camPos, RvPoint_f64* pMacPos);

	//矩形
	RvRect_f64   m_macRect;
private:
	

	
 
};





#endif