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.

343 lines
9.6 KiB
C++

#include "StdAfx.h"
#include "MarkArea.h"
#include "DrawSimpleShape.h"
#include "Layer.h"
#include "ProductMgr.h"
#include "Mirror.h"
#include "TemplateMgr.h"
#include "ObjComponentMgr.h"
#include "GlobalFunction.h"
#include "LogMgr.h"
#include "CommonFlowMgr.h"
#include "MarkAreaMgr.h"
#include "GlobalDrawMgr.h"
#define MIN_OBJ_CNT 5 //最少obj 数量
#define DATA_VECTOR_SIZE 800 //数据点容器的容量,避免push_back时vector 自动增长
#define DIGITAL_10000 10000
CMarkArea::CMarkArea()
{
UpdateSize();
m_bSel = false;//选择状态
}
CMarkArea::CMarkArea(Dbxy pt,DbSize size)
{
m_RealBasePt = m_BasePt = pt;//基准点
m_Size = size;//尺寸
}
CMarkArea::~CMarkArea(void)
{
}
#if 1
void CMarkArea::Serialize(CArchive& ar)
{
if(ar.IsStoring())
{
ar<<m_BasePt.x;
ar<<m_BasePt.y;
ar<<m_Size.w+DIGITAL_10000;//用来和旧版的区分
ar<<m_Size.h;
ar<<m_Offset.x;
ar<<m_Offset.y;
ar<<m_Offset2.x;
ar<<m_Offset2.y;
}
else
{
ar>>m_BasePt.x;
ar>>m_BasePt.y;
double val;
ar>>val;
bool bNewVersions = (val>=DIGITAL_10000);
if(bNewVersions)
val -= DIGITAL_10000;
m_Size.w = val;
ar>>m_Size.h;
ar>>m_Offset.x;
ar>>m_Offset.y;
if(bNewVersions)
{
ar>>m_Offset2.x;
ar>>m_Offset2.y;
}
else
{
m_Offset2.x = m_Offset.x;
m_Offset2.y = m_Offset.y;
}
}
}
void CMarkArea::WriteWorkFile(vector<CLab> &LabVec)
{
LabVec.push_back(CLab(LAB_NULL,m_BasePt.x));
LabVec.push_back(CLab(LAB_NULL,m_BasePt.y));
LabVec.push_back(CLab(LAB_NULL,m_Size.w));
LabVec.push_back(CLab(LAB_NULL,m_Size.h));
LabVec.push_back(CLab(LAB_NULL,m_Offset.x));
LabVec.push_back(CLab(LAB_NULL,m_Offset.y));
}
void CMarkArea::ReadWorkFile(CLabVecRang &LabVecRang)
{
int idx = LabVecRang.GetStart();
m_BasePt.x = LabVecRang.GetDouble(idx++);
m_BasePt.y = LabVecRang.GetDouble(idx++);
m_Size.w = LabVecRang.GetDouble(idx++);
m_Size.h = LabVecRang.GetDouble(idx++);
m_Offset.x = LabVecRang.GetDouble(idx++);
m_Offset.y = LabVecRang.GetDouble(idx++);
}
//更新尺寸为振镜范围
void CMarkArea::UpdateSize()
{
m_Size = gMirror->GetRange();
}
//获取area 的理论范围
DbRect CMarkArea::GetRect()
{
DbRect rect(m_BasePt,m_Size);
return rect;
}
void CMarkArea::Draw(CDC* pDC,bool bSel)
{
CPen pen;
if(bSel || m_bSel)
{
pen.CreatePen(PS_DOT,1,RGB_RED);
}
else
{
pen.CreatePen(PS_DOT,1,RGB_PINK);
}
DbSize size = GetSize();
DbRect rect;
rect.Creat(m_BasePt,size);
//绘制外框
DrawRect(pDC,pen,rect,false);
//选择状态时在中间区域绘制网格线
if(m_bSel)
{
Drawgridding(pDC,pen,rect,1);
}
//显示实际数据
if(gMarkAreaMgr->IsbShowReadDate())
{
vector<vector<Dbxy>> &DataVec = m_WorkData.GetDataVec();
gDraw->DrawDbxyVec(pDC,DataVec,m_BasePt);
}
}
bool CMarkArea::IsPtInArea(Dbxy pt)
{
return IsPointInRect(pt,DbRect(m_BasePt,m_Size));
}
void CMarkArea::SetBasePt(Dbxy pt)
{
m_BasePt = pt;
SetRealBasePt(pt);
}
#endif
#if 1
//获取实际中心位置
Dbxy CMarkArea::GetRealBasePt()
{
if(m_RealBasePt.Equal(Dbxy(0,0)))
m_RealBasePt = m_BasePt;
return m_RealBasePt;
}
//计算实际中心点
void CMarkArea::CalRealBasePt(CProduct &Product)
{
//计算markarea 的实际中心位置
m_RealBasePt = Product.TheoryPtToRealPt(m_BasePt);
}
//搜集layer 内的obj
void CMarkArea::CollectLayerObj(CObjContainer &ObjContainer)
{
//获得layer 的obj 容器直接操作
CLayer &Layer = CLayer::Instance();
CObjContainer &LayerObjContainer = Layer.GetObjContainer();
vector<Sptr<CObjBase>> &ObjVec = LayerObjContainer.GetObjVec();
//依次判断每个obj 需要加入哪个markarea
DbRect Rect = GetRect();
vector<Sptr<CObjBase>>::iterator iter = ObjVec.begin();
vector<Sptr<CObjBase>>::iterator iter_end = ObjVec.end();
for(;iter!=iter_end;iter++)
{
if((*iter)->IsInRect(Rect,false))//只要一个数据点在rect 内都算
{
ObjContainer.AddObject((*iter));
}
}
}
//搜集元件对象(被收集的obj 会被标记,防止被其他的area 重复收集)
void CMarkArea::CollectComponentObj(vector<vector<Dbxy>> &vec,bool bNeedSel)
{
//收集area 内的数据
gObjComponentMgr->CollectWorkData(GetRect(),vec,bNeedSel);
}
//通过数据范围来调整area 的中心和尺寸
void CMarkArea::AdjustByObj()
{
//获得area 内的数据范围
DbRect DataRect = gObjComponentMgr->SetMarkedStateRect(GetRect(),false);
DbSize size = DataRect.GetSize();
if(size.w>0 && size.h>0)
{
m_BasePt = DataRect.GetCenterPt();
m_Size = size;
}
}
//清除数据源
void CMarkArea::ClearSrcWorkData()
{
m_SrcWorkData.Clear();
m_DecWorkData.Clear();
//分配足够的空间
m_SrcWorkData.Resize(DATA_VECTOR_SIZE);
m_DecWorkData.Resize(DATA_VECTOR_SIZE);
}
//搜集数据源
void CMarkArea::CollectSrcWorkData()
{
CollectComponentObj(m_SrcWorkData.GetDataVec(),false);
m_DecWorkData = m_SrcWorkData;//复制一份
}
//是否有工作数据
bool CMarkArea::HasWorkData()
{
if(m_bSelMarkMode)
return !m_WorkData.Empty();
else//全部加工时使用之前就准备好的数据,提高速度
return (!m_DecWorkData.Empty() && m_bNeedMark);
}
//检查是否需要加工
bool CMarkArea::CheckbNeedMark()
{
m_bNeedMark = gObjComponentMgr->HasObjInRect(GetRect());
return m_bNeedMark;
}
#endif
//搜集在area 范围内的obj 数据(Product 是当前要加工的工件,主要用来偏移旋转数据)
void CMarkArea::CollectWorkData(bool bNeedSel,CProduct &Product)
{
gLogMgr->WriteDebugLog("func : CMarkArea---->CollectWorkData");
m_bSelMarkMode = bNeedSel;//是否为选择加工模式
//不要移动area 的中心
m_RealBasePt = m_BasePt;
//将相对于layer 中心的数据转换为area 实际中心的数据
//数据的偏移调整(每个area 的单独调整量+ 整体性的调整量)
Dbxy Offset;
{
Dbxy AllOffset2;
AllOffset2 = gCommonFlowMgr->GetAdjustOffsetAll();
Offset.x = AllOffset2.x;//-m_RealBasePt.x;
Offset.y = AllOffset2.y;// -m_RealBasePt.y;
}
if(bNeedSel)
{
m_WorkData.Clear();
m_SpecialWorkData.Clear();//特殊刀对象
vector<vector<Dbxy>> &WorkDataVec = m_WorkData.GetDataVec();
vector<vector<Dbxy>> &SpecialWorkDataVec = m_SpecialWorkData.GetDataVec();
//先搜集元件对象数据-----------------------------------
CollectComponentObj(WorkDataVec,bNeedSel);
//收集特殊对象增加的数据
gCommonFlowMgr->SetbCollectSpecialObj(true);
CollectComponentObj(SpecialWorkDataVec,bNeedSel);
gCommonFlowMgr->SetbCollectSpecialObj(false);
//如果没有收集到原件的数据才搜集layer 中obj 的数据
if(WorkDataVec.empty() && !gObjComponentMgr->HasObj())
{
//先找到在area 内的obj
CObjContainer ObjContainer;
CollectLayerObj(ObjContainer);
//提取obj 的数据点(理论值) 这些数据是相对于layer 中心的坐标
ObjContainer.GetObjPtData(WorkDataVec,bNeedSel);
}
bool HasData = false;//判断有没有数据
{
vector<vector<Dbxy>>::iterator iter = WorkDataVec.begin();
vector<vector<Dbxy>>::iterator iter_end = WorkDataVec.end();
for(;iter!=iter_end;iter++)
{
if(!(*iter).empty())
{
HasData = true;
break;
}
}
}
if(!HasData)
{
WorkDataVec.clear();
SpecialWorkDataVec.clear();
return;
}
Product.TheoryDataToRealData(WorkDataVec, m_BasePt,Offset);
Product.TheoryDataToRealData(SpecialWorkDataVec, m_BasePt,Offset);
return;
//根据抓取两个mark 来计算拉伸数据
if(gCommonFlowMgr->IsbStretchDataToRealSize())
{
Product.StretchDataToRealSize(WorkDataVec);
Product.StretchDataToRealSize(SpecialWorkDataVec);
}
//根据旋转偏移计算数据的实际值(相对于layer 中心)
Product.TheoryDataToRealData(WorkDataVec,Offset);
Product.TheoryDataToRealData(SpecialWorkDataVec,Offset);
}
else//全部加工时使用之前准备好的数据
{
//检查是否需要加工
if(CheckbNeedMark())
{
Product.TheoryDataToRealData(m_SrcWorkData.GetDataVec(),m_DecWorkData.GetDataVec(),Offset);
}
}
}
bool CMarkArea::DrawObjComponentVec(vector<Sptr<CObjComponent>> &vec,CDC* pDC,bool bSel)
{
vector<Sptr<CObjComponent>>::iterator iter = vec.begin();
vector<Sptr<CObjComponent>>::iterator iter_end = vec.end();
for(;iter!=iter_end;iter++)
{
(*iter)->Draw(pDC);
if(IsShiftKeyDown())
return false;
}
return true;
}
//获取加工数据容器
vector<vector<Dbxy>> &CMarkArea::GetDataVec()
{
if(m_bSelMarkMode)
return m_WorkData.GetDataVec();
else//全部加工时使用之前就准备好的数据,提高速度
return m_DecWorkData.GetDataVec();
}
//获取特殊对象的数据
vector<vector<Dbxy>> &CMarkArea::GetSpecialDataVec()
{
return m_SpecialWorkData.GetDataVec();
}
bool CMarkArea::HasSpecialWorkData()
{
return !m_SpecialWorkData.Empty();
}