You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

639 lines
17 KiB
C++

#include "StdAfx.h"
#include "MarkAreaMgr.h"
#include "CStringFuc.h"
#include "GlobalDrawMgr.h"
#include "FileMgr.h"
#include "LogMgr.h"
#include "ObjComponentMgr.h"
#include "WorkFileLable.h"
#include "WorkFileMgr.h"
#include "GlobalFunction.h"
#include "Layer.h"
#include "ObjPline.h"
#include "MsgBox.h"
#include "Mirror.h"
#define FILE_PATH _T("\\Parameter\\MarkArea\\MarkArea.par")
#define FIXED_FILE_PATH _T("\\Parameter\\MarkArea\\FixedMarkArea.par")//固定不变的(只能读)
CMarkAreaMgr *gMarkAreaMgr = new CMarkAreaMgr;
CMarkAreaMgr::CMarkAreaMgr(void)
{
m_CurSelIdx = -1;//当前选择的 索引值
m_bDraw = true;//是否绘制补偿区域
m_bDrawIdx = false;//是否显示area 的索引值
m_bShowReadDate = false;//显示实际数据
m_CenterCrossR = 2;//中心十字的半径mm
}
CMarkAreaMgr::~CMarkAreaMgr(void)
{
}
void CMarkAreaMgr::Ini()
{
SaveOrLoad(false);//读取文件
}
void CMarkAreaMgr::Draw(CDC* pDC)
{
if(!m_bDraw)
return;
int size = m_AreaVec.size();
for(int i=0;i<size;i++)
{
if(m_CurSelIdx==i)
{
m_AreaVec[i].Draw(pDC,true);
}
else
{
m_AreaVec[i].Draw(pDC,false);
}
if(m_bDrawIdx)
{
//中间绘制数字
CString str;
str.Format(_T("%d"),i+1);
gDraw->DrawTxt(pDC,str,m_AreaVec[i].GetBasePt());
}
}
}
//通过点来选择area ,一次只能选一个
void CMarkAreaMgr::SelAreaByPt(Dbxy pt)
{
int size = m_AreaVec.size();
for(int i=0;i<size;i++)
{
if(m_AreaVec[i].IsPtInArea(pt))
{
SetCurSelIdx(i);
break;
}
}
}
//选择第一个area
void CMarkAreaMgr::SelFristArea()
{
int size = m_AreaVec.size();
for(int i=0;i<size;i++)
{
if(i==0)
m_AreaVec[i].SetSelState(true);
else
m_AreaVec[i].SetSelState(false);
}
}
#if 1
//保存或者读取
void CMarkAreaMgr::SaveOrLoad(bool bSave,bool bFixed)
{
CFileMgr FileMgr;
char filepath[1024];
if(bFixed)
FileMgr.GetFullFilePath(filepath,FIXED_FILE_PATH);//获取完整路径
else
FileMgr.GetFullFilePath(filepath,FILE_PATH);//获取完整路径
if(bSave)
{
CFile file(filepath,CFile::modeReadWrite|CFile::modeCreate);
CArchive ar(&file,CArchive::store);
SaveOrLoadExt(ar);
}
else
{
CFile file;
if(file.Open(filepath,CFile::modeRead))
{
CArchive ar(&file,CArchive::load);
SaveOrLoadExt(ar);
//area移动到中心
MoveAllAreaToTargetPt(Dbxy(0,0));
}
else
{
gLogMgr->WriteDebugLog("标记区域文件读取失败", _LOG_ERROR);
}
}
}
void CMarkAreaMgr::SaveOrLoadExt(CArchive &ar)
{
int size = 0;
if(ar.IsStoring())
{
size = m_AreaVec.size();//area 的数量
ar<<size;
for(int i=0;i<size;i++)
{
m_AreaVec[i].Serialize(ar);
}
}
else
{
m_AreaVec.clear();//清空之前的area
ar>>size;
for(int i=0;i<size;i++)
{
CMarkArea Area;
Area.Serialize(ar);
m_AreaVec.push_back(Area);
}
}
}
#endif
#if 1
void CMarkAreaMgr::WriteWorkFileExt(vector<CLab> &LabVec)
{
int size = m_AreaVec.size();
for(int i=0;i<size;i++)
{
LabVec.push_back(CLab(LAB_MARK_AREA_START));
m_AreaVec[i].WriteWorkFile(LabVec);
LabVec.push_back(CLab(LAB_MARK_AREA_END));
}
}
void CMarkAreaMgr::ReadWorkFile(CLabVecRang &LabVecRang)
{
vector<CLabVecRang> LabVecRangVec;
CWorkFileMgr WorkFileMgr;
WorkFileMgr.SeparateStrVec(LabVecRang,LabVecRangVec,LAB_MARK_AREA_START,LAB_MARK_AREA_END);
//处理每个点
if(!LabVecRangVec.empty())
{
m_AreaVec.clear();
vector<CLabVecRang>::iterator iter = LabVecRangVec.begin();
vector<CLabVecRang>::iterator iter_end = LabVecRangVec.end();
for(;iter!=iter_end;iter++)
{
CMarkArea MarkArea;
MarkArea.ReadWorkFile(*iter);
m_AreaVec.push_back(MarkArea);
}
}
}
#endif
#if 1//编辑area 用的函数
void CMarkAreaMgr::Add()
{
if(m_AreaVec.empty())//新建
{
CMarkArea Area;
m_AreaVec.push_back(Area);
}
else//复制选中的
{
if(IdxValid(m_CurSelIdx))
{
CMarkArea Area(m_AreaVec[m_CurSelIdx]);
m_AreaVec.push_back(Area);
}
}
}
void CMarkAreaMgr::InsertList(CListCtrl &List)
{
int size = m_AreaVec.size();
for(int i=0;i<size;i++)
{
int idx = 0;
List.InsertItem(i," ");//插入一行
List.SetItemText(i,idx++,Int2CString(i+1));//序号
Dbxy Offset = m_AreaVec[i].GetOffset();//偏移
List.SetItemText(i,idx++,Db2CString(Offset.x));
List.SetItemText(i,idx++,Db2CString(Offset.y));
Dbxy Offset2 = m_AreaVec[i].GetOffset2();//偏移
List.SetItemText(i,idx++,Db2CString(Offset2.x));
List.SetItemText(i,idx++,Db2CString(Offset2.y));
}
}
//检查idx 是否有效
bool CMarkAreaMgr::IdxValid(int idx)
{
int size = m_AreaVec.size();
if(idx<0 || idx>= size)
return false;
return true;
}
void CMarkAreaMgr::DelSel(int &idx)
{
if(!IdxValid(idx))
return;
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
int i=0;
for(;iter!=iter_end;iter++)
{
if(i==idx)
{
m_AreaVec.erase(iter);
idx = -1;
break;
}
i++;
}
}
void CMarkAreaMgr::DelAll()
{
m_AreaVec.clear();
m_CurSelIdx = -1;//当前选择的 索引值
}
//操作idx 索引
void CMarkAreaMgr::OpArea(int idx,CMarkArea &Area,bool bRead)
{
if(!IdxValid(idx))
return;
ResetAllAreaSelState();
int size = m_AreaVec.size();
for(int i=0;i<size;i++)
{
if(idx == i)
{
if(bRead)
{
Area = m_AreaVec[i];
//设置选择状态
m_AreaVec[i].SetSelState(true);
}
else
{
m_AreaVec[i] = Area;
}
}
}
}
//调整顺序
void CMarkAreaMgr::Order(int &idx,bool bMoveUp)
{
int size = m_AreaVec.size();
if(bMoveUp)//前移
{
SwapArea(idx,idx-1);
}
else//后移
{
SwapArea(idx,idx+1);
}
}
void CMarkAreaMgr::SwapArea(int &idx1,int idx2)
{
if(!IdxValid(idx1) || !IdxValid(idx2))
return;
CMarkArea tmp = m_AreaVec[idx1];
m_AreaVec[idx1] = m_AreaVec[idx2];
m_AreaVec[idx2] = tmp;
//指向交换后的项
idx1 = idx2;
}
void CMarkAreaMgr::MoveAllArea(double Val,DIRECTION dir)
{
int size = m_AreaVec.size();
for(int i=0;i<size;i++)
{
Dbxy pt = m_AreaVec[i].GetBasePt();
if(dir==_DIR_L ||dir==_DIR_R)
pt.x += Val;
else
pt.y += Val;
m_AreaVec[i].SetBasePt(pt);
}
}
//移动Area 到中心点
void CMarkAreaMgr::MoveAllAreaToTargetPt(Dbxy TargetPt)
{
//获取所有area 的中心点
Dbxy CenterPt = GetAllAreaCenterPt();
Dbxy Offset;
Offset.x = TargetPt.x - CenterPt.x;
Offset.y = TargetPt.y - CenterPt.y;
int size = m_AreaVec.size();
for(int i=0;i<size;i++)
{
Dbxy pt = m_AreaVec[i].GetBasePt();
pt.x += Offset.x;
pt.y += Offset.y;
m_AreaVec[i].SetBasePt(pt);
}
CString s;
s.Format(_T("MoveAllAreaToTargetPt [Offset_x]= %f,[Offset_y]= %f"),Offset.x,Offset.y);
gLogMgr->WriteDebugLog(s);
}
#endif
#if 1
//收集加工数据入口
void CMarkAreaMgr::CollectWorkData(bool bNeedSel,CProduct &Product)
{
gLogMgr->WriteDebugLog("func : CMarkAreaMgr---->CollectWorkData");
//重置元件的收集状态
gObjComponentMgr->ResetObjCollectState(false);
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
(*iter).CollectWorkData(bNeedSel,Product);
}
}
//是否有加工数据
bool CMarkAreaMgr::HasWorkData()
{
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
if((*iter).HasWorkData())//只要一个area 有数据即可
{
return true;
}
}
gLogMgr->WriteDebugLog("没有加工数据",_LOG_ERROR);
return false;
}
//检查所有obj 搜集的数据是否一致
bool CMarkAreaMgr::CheckAllObjDataConsistency()
{
if(m_AreaVec.empty())
return false;
vector<Dbxy> BaseDataVec;//基础数据
//查找基础数据
{
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
if((*iter).HasWorkData())
{
vector<vector<Dbxy>> &DataVec = (*iter).GetDataVec();
BaseDataVec = DataVec[0];
break;
}
}
}
int BaseSize = BaseDataVec.size();//基础数据的点数
//所有数据和基础数据比较
if(BaseDataVec.empty())
return false;
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
if((*iter).HasWorkData())
{
vector<vector<Dbxy>> &DataVec = (*iter).GetDataVec();
vector<vector<Dbxy>>::iterator iter1 = DataVec.begin();
vector<vector<Dbxy>>::iterator iter1_end = DataVec.end();
for(;iter1!=iter1_end;iter1++)
{
vector<Dbxy> &ObjDataVec = (*iter1);
int size = ObjDataVec.size();
if(BaseSize != size)//数据点数不一致
return false;
Dbxy BaseOffset;//基础偏移值
for(int k=0;k<size;k++)
{
Dbxy Offset;//偏移值
Offset.x = ObjDataVec[k].x -BaseDataVec[k].x;
Offset.y = ObjDataVec[k].y -BaseDataVec[k].y;
if(k==0)
{
BaseOffset = Offset;
}
else
{
double eps = 0.04;//精度
if(!IsTwoDbEqual(BaseOffset.x,Offset.x,eps) || !IsTwoDbEqual(BaseOffset.y,Offset.y,eps))
{
return false;//有一个点不一致就算
}
}
}
}
}
}
return true;
}
//搜集数据源
void CMarkAreaMgr::CollectSrcWorkData()
{
gLogMgr->WriteDebugLog("func : CMarkAreaMgr---->CollectSrcWorkData");
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
(*iter).CollectSrcWorkData();
}
}
//清除数据源
void CMarkAreaMgr::ClearSrcWorkData()
{
gLogMgr->WriteDebugLog("func : CMarkAreaMgr---->ClearSrcWorkData");
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
(*iter).ClearSrcWorkData();
}
}
#endif
//根据obj 来阵列创建
void CMarkAreaMgr::ArrayCreat(int CntX,int CntY)
{
if(CntX<=0 || CntY<=0)
{
CMsgBox MsgBox;
MsgBox.Show("阵列数量错误!");
return;
}
if(!gObjComponentMgr->HasObj())
{
CMsgBox MsgBox;
MsgBox.Show("没有图形对象!");
return;
}
DbRect Rect = gObjComponentMgr->GetAllObjRect();
DbSize Size = Rect.GetSize();
Size.w += 2;//外扩一点
Size.h += 2;
DbSize Offset;
Offset.w = Size.w/CntX;
Offset.h = Size.h/CntY;
//不能大于振镜范围
DbSize MirrorSize = gMirror->GetRange();
if(Offset.w>MirrorSize.w || Offset.h>MirrorSize.h)
{
CMsgBox MsgBox;
CString s;
s.Format(_T("加工区域超出振镜范围[%0.0f][%0.0f]"),MirrorSize.w,MirrorSize.h);
MsgBox.Show(s);
return;
}
DelAll();//删除当前的area
CMarkArea Area(Dbxy(0,0),Offset);
Offset.h *=(-1);
bool flg = true;
for(int i=0;i<CntX;i++)
{
for(int j=0;j<CntY;j++)
{
CMarkArea AreaTmp(Area);
Dbxy BasePt;
BasePt.x += Offset.w*i*(-1);
if(flg)
{
BasePt.y += Offset.h*j;
}
else
{
BasePt.y += Offset.h*(CntY-j-1);
}
AreaTmp.SetBasePt(BasePt);
AreaTmp.SetSelState(false);
m_AreaVec.push_back(AreaTmp);
}
flg =!flg;
}
//移动到中心
MoveAllAreaToTargetPt(Dbxy(0,0));
}
void CMarkAreaMgr::ResetAllAreaSelState()
{
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
(*iter).SetSelState(false);
}
}
int CMarkAreaMgr::GetCurSelIdx()
{
int size = m_AreaVec.size();
if(m_CurSelIdx<size)
return m_CurSelIdx;
return -1;
}
void CMarkAreaMgr::SetAllMarkSize()
{
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
(*iter).UpdateSize();
}
}
void CMarkAreaMgr::ReReadFixMarkArea()
{
//重新读取参数保存的markaera 数据
DelAll();
SaveOrLoad(false,true);//从固定文件来读
}
//通过obj 对象来调整markarea 的中心点和范围
void CMarkAreaMgr::AdjustByObj()
{
gLogMgr->WriteDebugLog("func : Adjust MarkArea By Obj");
ReReadFixMarkArea();
double MaxSize = 0;
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
(*iter).AdjustByObj();
DbSize size = (*iter).GetSize();
if(size.w>MaxSize)
MaxSize = size.w;
if(size.h>MaxSize)
MaxSize = size.h;
}
CString LogStr;
LogStr.Format(_T("[MaxAreaSize] = [%.3f]"),MaxSize);
gLogMgr->WriteDebugLog(LogStr);
}
//计算markarea 的实际中心位置
void CMarkAreaMgr::CalRealBasePt(CProduct &Product)
{
gLogMgr->WriteDebugLog("func : CMarkAreaMgr---->CalRealBasePt");
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
(*iter).CalRealBasePt(Product);
}
}
//每个mark 中心创建一个十字对象用来测量
void CMarkAreaMgr::CreatCenterCrossObj()
{
CLayer &layer = GetLayerInstance();
//先删除所有obj
layer.DelAllObj();
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
Dbxy pt = (*iter).GetBasePt();
//创建多线段对象
CObjPline *pObjPline = new CObjPline;
{
Dbxy pt1(pt.x-m_CenterCrossR,pt.y);
CDataPoint DataPoint(pt1);
DataPoint.SetIsNode(true);
pObjPline->AddDataPoint(DataPoint);
}
{
Dbxy pt1(pt.x+m_CenterCrossR,pt.y);
CDataPoint DataPoint(pt1);
DataPoint.SetIsNode(true);
pObjPline->AddDataPoint(DataPoint);
}
{
Dbxy pt1(pt.x,pt.y+m_CenterCrossR);
CDataPoint DataPoint(pt1);
DataPoint.SetIsNode(true);
pObjPline->AddDataPoint(DataPoint);
}
{
Dbxy pt1(pt.x,pt.y-m_CenterCrossR);
CDataPoint DataPoint(pt1);
DataPoint.SetIsNode(true);
pObjPline->AddDataPoint(DataPoint);
}
layer.AddObject(pObjPline);
}
}
//获取所有area 的中心点
Dbxy CMarkAreaMgr::GetAllAreaCenterPt()
{
DbRect rect;
vector<CMarkArea>::iterator iter = m_AreaVec.begin();
vector<CMarkArea>::iterator iter_end = m_AreaVec.end();
for(;iter!=iter_end;iter++)
{
Dbxy pt = (*iter).GetBasePt();
AdjustRectByPoint(rect,pt);
}
return rect.GetCenterPt();
}