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.

707 lines
18 KiB
C++

#include "StdAfx.h"
#include "Layer.h"
#include "LogMgr.h"
#include "GlobalDrawMgr.h"
#include "LaiPuLaserView.h"
#include "GlobalFunction.h"
#include "CommandRotato.h"
#include "CommandMirror.h"
#include "CommandMove.h"
#include "CommandReverse.h"
#include "CommandJion.h"
#include "CommandMgr.h"
#include "EasyOperationMgr.h"
#include "ObjComponentMgr.h"
#include "ObjCircle.h"
#include "ObjPline.h"
#include "Laser.h"
#include "CStringFuc.h"
#include "MsgBox.h"
CLayer gLayer;
CLayer::CLayer(void)
{
m_ObjContainer = &m_TmpObjContainer;//避免初始化的时候报错
m_bShowObjIdx = false;//是否显示obj 对象的索引idx
m_bShowObjPtCoord = true;
m_bDrawObj = true;//是否绘制obj
m_AreaCrossPtRange = 10;//用于创建扫描区域的交叉点范围
}
CLayer::~CLayer(void)
{
}
#if 1
void CLayer::Serialize(CArchive& ar)
{
// m_ObjContainer->Serialize(ar);
}
//绑定当前操作的ObjContainer
void CLayer::BindObjContainer(CObjContainer &Container)
{
//清除现在编辑状态
gCommandMgr.Reset();
//清空临时对象容器
ClearTmpObj();
//绑定新的容器
m_ObjContainer = &Container;
}
#endif
#if 1
void CLayer::Draw(CDC* pDC)
{
//if(m_bDrawObj)
{
DrawAllObj(pDC);
}
}
void CLayer::DrawAllObj(CDC* pDC)
{
m_ObjContainer->DrawAllObj(pDC);
//临时对象也要绘制
m_TmpObjContainer.DrawAllObj(pDC);
//绘制索引值
if(m_bShowObjIdx)
{
m_ObjContainer->DrawObjIdx(pDC);
}
//只在编辑模式显示
if(m_bShowObjPtCoord)
{
m_ObjContainer->DrawObjPtCoord(pDC);
}
}
//重绘选择的图形
void CLayer::XorRedrawObj(CDC* pDC,bool bNeedSel)
{
m_ObjContainer->XorRedrawObj(pDC,bNeedSel);
}
#endif
#if 1
void CLayer::AddObject(CObjBase *pMarkObject)
{
m_ObjContainer->AddObject(pMarkObject);
}
void CLayer::AddObject(Sptr<CObjBase> p)
{
m_ObjContainer->AddObject(p);
}
void CLayer::AddObject(CObjContainer &ObjContainer)
{
vector<Sptr<CObjBase>> &vec = ObjContainer.GetObjVec();
vector<Sptr<CObjBase>>::iterator iter = vec.begin();
vector<Sptr<CObjBase>>::iterator iter_end = vec.end();
for(;iter!=iter_end;iter++)
{
if((*iter).IsNull()==false)
{
(*iter)->SetSelected(false);
AddObject((*iter));
}
}
}
//删除选择项
void CLayer::DelSelObj()
{
m_ObjContainer->DelSelObj();
}
//删除ObjContainer 中指定的所有obj
void CLayer::DelObj(CObjContainer &ObjContainer)
{
vector<Sptr<CObjBase>> &vec = ObjContainer.GetObjVec();
vector<Sptr<CObjBase>>::iterator iter = vec.begin();
vector<Sptr<CObjBase>>::iterator iter_end = vec.end();
for(;iter!=iter_end;iter++)
{
if((*iter).IsNull()==false)
{
DelObj((*iter));
}
}
}
//删除指定的obj
void CLayer::DelObj(Sptr<CObjBase> p)
{
m_ObjContainer->DelObj(p);
}
#endif
#if 1
bool CLayer::HasSelObjectInRect(DbRect rect)
{
return m_ObjContainer->HasSelObjectInRect(rect);
}
bool CLayer::HasSelNodeInRect(DbRect rect)
{
return m_ObjContainer->HasSelNodeInRect(rect);
}
bool CLayer::HasObjectInRect(DbRect rect)
{
return m_ObjContainer->HasObjectInRect(rect);
}
//选择矩形区域内的对象(bNeedAllIn 表示需要在rect 里面才算)
bool CLayer::SelObjectInRect(DbRect rect,bool bNeedAllIn)
{
//不允许多选的时候先取消之前的选择
if(!gDraw->IsbMultipleSel())
{
SelAllObj();
RevSelAllObj();
}
if(gDraw->IsEditLayerObj())
{
if(m_ObjContainer->SelObjectInRect(rect,bNeedAllIn))
{
gEasyOperationMgr->Refresh();
return true;
}
}
//在这里同时处理元件对象的选择
if(gObjComponentMgr->SelObjectInRect(rect))
{
return true;
}
return false;
}
//获取第一个在rect 的obj
Sptr<CObjBase> CLayer::GetFirstObjInRect(DbRect &rect)
{
return m_ObjContainer->GetFirstObjInRect(rect);
}
Sptr<CObjBase> CLayer::GetFirstNodeObjInRect(DbRect &rect)
{
return m_ObjContainer->GetFirstNodeObjInRect(rect);
}
//是否有选择的obj
bool CLayer::HasObjSel()
{
return m_ObjContainer->HasObjSel();
}
//全选
void CLayer::SelAllObj()
{
m_ObjContainer->SelAllObj();
gEasyOperationMgr->Refresh();
//元件
gObjComponentMgr->SelAllObj();
}
//全不选
void CLayer::NotSelAllObj()
{
m_ObjContainer->NotSelAllObj();
//元件
gObjComponentMgr->NotSelAllObj();
gEasyOperationMgr->Refresh();
}
//反选
void CLayer::RevSelAllObj()
{
m_ObjContainer->RevSelAllObj();
gEasyOperationMgr->Refresh();
//元件
gObjComponentMgr->RevSelAllObj();
}
//删除所有的obj
void CLayer::DelAllObj()
{
SelAllObj();
DelSelObj();
}
//判断当前鼠标工具的类型
MOUSE_TOOL CLayer::JudgeMouseToolType(Dbxy pt)
{
MOUSE_TOOL type = _TOOL_POINT;
DbRect rect = gDraw->GetCurPointRect(pt);
if(HasSelNodeInRect(rect))
{
type = _TOOL_MOVE_NODE;
}
else if(HasSelObjectInRect(rect))
{
type = _TOOL_MOVE;
}
return type;
}
DbRect CLayer::GetSelObjRect()
{
return m_ObjContainer->GetSelObjRect();
}
//创建特殊对象属性(比如圆)
CMFCPropertyGridProperty *CLayer::CreatSpecialGridProperty(CModule *pModule)
{
return m_ObjContainer->CreatSpecialGridProperty(pModule);
}
//相应特殊属性的变化
void CLayer::OnSpecialPropertyChanged()
{
m_ObjContainer->OnSpecialPropertyChanged();
}
#endif
#if 1
//操作obj
void CLayer::OperateObj(SObjOperatePar &par,bool bAll)
{
m_ObjContainer->OperateObj(par,bAll);
}
//移动选择的obj (bAddUndo为是否加入撤销指令)
void CLayer::OnMove(double MoveX,double MoveY,bool bAddUndo)
{
if(HasObjSel())
{
//创建指令
CCommandMove *p = new CCommandMove;
SObjOperatePar par;
par.OpType = _OP_MOVE;
par.MoveX = MoveX;
par.MoveY = MoveY;
p->SetOperatePar(par);
//添加到队列
if(bAddUndo)
gCommandMgr.AddUndoCommand(p);
//执行指令
p->Excute();
}
}
//响应指定的旋转并处理撤销操作Angle 360度角
void CLayer::OnRotato(double Angle)
{
Dbxy pt = GetSelObjRect().GetCenterPt();
//obj 操作----------------------------
SObjOperatePar par;
par.OpType = _OP_ROTATO;
par.BasePt = pt;
par.Angle = Angle;
//创建undo 用的指令-----start
CCommandRotato *p = new CCommandRotato;
p->SetOperatePar(par);
gCommandMgr.AddUndoCommand(p);
p->Excute();
//创建undo 用的指令-----end
}
//直接旋转Angle (不加入UndoCommand 指令)Angle 360度角
void CLayer::Rotato(double Angle)
{
Dbxy pt = GetSelObjRect().GetCenterPt();
//obj 操作----------------------------
SObjOperatePar par;
par.OpType = _OP_ROTATO;
par.BasePt = pt;
par.Angle = Angle;
m_ObjContainer->OperateObj(par,false);
}
//响应镜像操作并处理撤销操作
void CLayer::OnMirror(X_OR_Y xy)
{
Dbxy pt = GetSelObjRect().GetCenterPt();
//obj 操作
SObjOperatePar par;
par.OpType = _OP_MIRROR;
par.BasePt = pt;
par.xy = xy;
//创建undo 用的指令-----start
CCommandMirror *p = new CCommandMirror;
p->SetOperatePar(par);
gCommandMgr.AddUndoCommand(p);
p->Excute();
}
//反转节点的顺序
void CLayer::OnReverseSelObj()
{
//obj 操作
SObjOperatePar par;
par.OpType = _OP_REVERSE;
//创建undo 用的指令-----start
CCommandReverse *p = new CCommandReverse;
p->SetOperatePar(par);
gCommandMgr.AddUndoCommand(p);
p->Excute();
}
//合并选择的图形
bool CLayer::OnJoin()
{
CObjBase *p = m_ObjContainer->JoinSelObj();
if(p)//合并成功
{
//创建撤销指令-----------------------------
CCommandJion *pCmd = new CCommandJion;
gCommandMgr.AddUndoCommand(pCmd);
Sptr<CObjBase> pObj(p);
pCmd->AddOpObj(pObj);
pObj->SetSelected(true);//合并后默认为选择状态
//删除被合并的obj
DelSelObj();
//添加合并后的obj
AddObject(pObj);
return true;
}
return false;
}
//分解选择的图形
void CLayer::OnExplode()
{
}
#endif
#if 1//捕捉
void CLayer::AddTmpObject(Sptr<CObjBase> p)
{
m_TmpObjContainer.AddObject(p);
}
void CLayer::ClearTmpObj()
{
m_TmpObjContainer.Clear();
}
//获取rect 范围内的所有线段保存到DataPtLineVec 中
void CLayer::GetLineInRect(DbRect &rect,vector<DbLine> &DataPtLineVec,bool bCatchTemp)
{
m_ObjContainer->GetLineInRect(rect,DataPtLineVec,bCatchTemp);
//临时对象
if(bCatchTemp)
{
vector<Sptr<CObjBase>> &vec = m_TmpObjContainer.GetObjVec();
vector<Sptr<CObjBase>>::iterator iter = vec.begin();
vector<Sptr<CObjBase>>::iterator iter_end = vec.end();
for(;iter!=iter_end;iter++)
{
if((iter+1)!=vec.end())//不要捕获最后一个临时点
{
(*iter)->GetLineInRect(rect,DataPtLineVec);
}
}
}
}
//获取和line 相交的所有交点到PointVec 中
void CLayer::GetIntersectPoint(DbLine &line,vector<Dbxy> &PointVec)
{
m_ObjContainer->GetIntersectPoint(line,PointVec);
}
bool CLayer::HasObjIntersectWithLine(DbLine &line)
{
return m_ObjContainer->HasObjIntersectWithLine(line);
}
//克隆当前选择的obj 到容器Vec 中
void CLayer::CloneObj(CObjContainer &ObjContainer,bool bNeedSel)
{
m_ObjContainer->CloneObj(ObjContainer,bNeedSel);
}
#endif
#if 1//group 操作
//将选择的group 参数绑定到指定的对话框上
void CLayer::BindingSelObjToDlg()
{
//先撤销所有绑定
GetFrame()->UnBindingDlg();
m_ObjContainer->BindingDlg();
}
//填充图形
void CLayer::FillObj(SFillPar FillPar,bool bNeedSel)
{
m_ObjContainer->FillObj(FillPar,bNeedSel);
}
#endif
#if 1
//提取所有点对象的中心点
void CLayer::GetAllPointObjPt(vector<Dbxy> &PtVec)
{
m_ObjContainer->GetAllPointObjPt(PtVec);
}
//设置所有选择obj 的笔号
void CLayer::SetSelObjPenNum(int num)
{
if(!gPenParMgr->IsSpecialPen(num))//不能设置特殊笔号
{
m_ObjContainer->SetSelObjPenNum(num);
NotSelAllObj();//全不选
}
}
void CLayer::SelborderObj(bool bNext)
{
m_ObjContainer->SelborderObj(bNext);
GetCurViewPtr()->RefreshView();
}
//选择的obj 插入到idx 的位置上(用于手动排序)
void CLayer::SelectedObjInsertToIdx(int idx)
{
m_ObjContainer->SelectedObjInsertToIdx(idx);
GetCurViewPtr()->RefreshView();
}
//逆序选择的obj
void CLayer::ReverseSelObj()
{
m_ObjContainer->ReverseSelObj();
GetCurViewPtr()->RefreshView();
}
//选择第一个obj
void CLayer::SelFirstObj()
{
m_ObjContainer->SelFirstObj();
GetCurViewPtr()->RefreshView();
}
#endif
#if 1
void CLayer::ResetAllMarkObj()
{
m_ObjContainer->ResetAllMarkObj();
}
void CLayer::CreatCircleByThreePt()
{
vector<Dbxy> PtVec;
vector<Sptr<CObjBase>> &vec = m_ObjContainer->GetObjVec();
vector<Sptr<CObjBase>>::iterator iter = vec.begin();
vector<Sptr<CObjBase>>::iterator iter_end = vec.end();
for(;iter!=iter_end;iter++)
{
PtVec.push_back((*iter)->GetCenterPt());
}
int size = PtVec.size();
if(size>=3)
{
CCirclePar CirclePar = CalCircleByThreePt(PtVec[0],PtVec[1],PtVec[2]);
CirclePar.DEdgeCnt = 100;
CObjCircle *pCircle = new CObjCircle;
pCircle->Creat(CirclePar);
AddObject(pCircle);
GetCurViewPtr()->RefreshView();
}
}
//旋转偏移obj (以坐标原点为基准)
void CLayer::OffsetRotatoObj(COffsetRotatoPar OffsetRotatoPar)
{
//以坐标原点旋转
Dbxy pt;
SObjOperatePar par;
par.OpType = _OP_ROTATO;
par.BasePt = pt;
par.Angle = OffsetRotatoPar.m_RotatoAng;
m_ObjContainer->OperateObj(par,false);
//以坐标原点旋转
par.OpType = _OP_MOVE;
par.MoveX = OffsetRotatoPar.m_Offset.x;
par.MoveY = OffsetRotatoPar.m_Offset.y;
m_ObjContainer->OperateObj(par,false);
}
#endif
#if 1
//创建单条扫描线
void CLayer::CreatOneLineObj(double Len)
{
Dbxy Pt1;
Dbxy Pt2;
CObjContainer &ObjContainer = GetObjContainer();
//在原来的位置上创建
if(ObjContainer.GetObjCnt()==1)
{
DbRect Rect = ObjContainer.GetObjRect(false);
Pt1 = Rect.GetCenterPt();
Pt2 = Rect.GetCenterPt();
}
if(gLaser->IsbScanByDirX())
{
Pt1.x -= Len/2;
Pt2.x += Len/2;
}
else
{
Pt1.y -= Len/2;
Pt2.y += Len/2;
}
DelAllObj();
CObjPline * pObjPline = new CObjPline;
pObjPline->Creat(Pt1,Pt2);
AddObject(pObjPline);
NotSelAllObj();
m_pView->RefreshView();
}
//移动对象
void CLayer::MoveScanObj(DIRECTION dir,double Dis)
{
CObjContainer &ObjContainer = GetObjContainer();
SelAllObj();
m_pView->MoveObjToPtByDir(dir,Dis);
NotSelAllObj();
m_pView->RefreshView();
}
//重置所有对象的扫描状态
void CLayer::ResetAllObjScaned()
{
vector<Sptr<CObjBase>> &vec = m_ObjContainer->GetObjVec();
vector<Sptr<CObjBase>>::iterator iter = vec.begin();
vector<Sptr<CObjBase>>::iterator iter_end = vec.end();
for(;iter!=iter_end;iter++)
{
(*iter)->SetbScaned(false);
}
}
#endif
#if 1
bool CompareLineY(double y1,double y2)
{
return y1>y2;
}
//快速生成扫描区域,一个圆和直线
void CLayer::QuickCreatScanArea(double AreaGap)
{
vector<double> LineCoordyVec;
vector<Dbxy> PointObjVec;//点对象容器
CObjBase *pCircle = NULL;
//删除所有对象
vector<Sptr<CObjBase>> &vec = m_ObjContainer->GetObjVec();
vector<Sptr<CObjBase>>::iterator iter = vec.begin();
vector<Sptr<CObjBase>>::iterator iter_end = vec.end();
for(;iter!=iter_end;iter++)
{
if((*iter)->GetType()==_TYPE_PLINE)
{
Dbxy pt = (*iter)->GetCenterPt();
LineCoordyVec.push_back(pt.y);
}
if((*iter)->GetType()==_TYPE_POINT)
{
Dbxy pt = (*iter)->GetCenterPt();
PointObjVec.push_back(pt);
}
//找到圆
if((*iter)->GetType()==_TYPE_CIRCLE)
{
pCircle = (*iter).GetPtr();
}
}
if(pCircle == NULL)
{
CMsgBox MsgBox;
MsgBox.Show("没有圆对象");
return;
}
DbRect rect = pCircle->GetRect();
if(pCircle)//上下各加1条线
{
LineCoordyVec.push_back(rect.T+0.01);
LineCoordyVec.push_back(rect.B-0.01);
}
CObjCircle CircleTem;//临时对象
CCirclePar ObjCirclePar;
Dbxy CenterPt = rect.GetCenterPt();
double Radius =rect.GetSize().w /2;
int EdgeCnt = 300;//边数多的圆
CircleTem.CreatByRadius(Radius,CenterPt,EdgeCnt);
//排序
sort(LineCoordyVec.begin(),LineCoordyVec.end(),CompareLineY);
//从上往下生成
vector<CObjBase *> AreaObjVec;
int size = LineCoordyVec.size();
for(int k=1;k<size;k++)
{
DIRECTION Dir = _DIR_M;
double ChangeSizeY = AreaGap;
if(k==1||k==(size-1))
{
ChangeSizeY /=2;
}
if(k==1)//第一个区域
{
Dir = _DIR_U;
}
if(k==(size-1))//最后一个区域
{
Dir = _DIR_D;
}
CObjBase *pAreaObj = CreatScanAreaObj(&CircleTem,PointObjVec,LineCoordyVec[k-1],LineCoordyVec[k],ChangeSizeY,Dir);
if(pAreaObj)
{
AreaObjVec.push_back(pAreaObj);
}
}
//删除原来的图形
DelAllObj();
//添加新的obj
size = AreaObjVec.size();
for(int k=0;k<size;k++)
{
if(AreaObjVec[k])
{
AddObject(AreaObjVec[k]);
}
}
SelAllObj();
m_pView->RefreshView();
}
CObjBase * CLayer::CreatScanAreaObj(CObjBase *pCircle,vector<Dbxy> PointObjVec,double Coordy1,double Coordy2,double ChangeSizeY,DIRECTION Dir)
{
if(!pCircle)
return NULL;
//生成区域对象
CObjPline *pPline = new CObjPline;
vector<CDataPoint>&PtContainer = pCircle->GetPtContainer();
int size = PtContainer.size();
CDataPoint FirstDataPoint;
bool bFirstPt = true;
for(int k=0;k<size;k++)
{
CDataPoint &DataPoint = PtContainer[k];
Dbxy Pt = DataPoint.GetPt();
if(Pt.y>=Coordy2 && Pt.y<=Coordy1)
{
int PointObjCnt = PointObjVec.size();
for(int i=0;i<PointObjCnt;i++)
{
if(CalDistance(Pt,PointObjVec[i])<m_AreaCrossPtRange)
{
DataPoint.SetPt(PointObjVec[i]);
break;
}
}
if(bFirstPt)//记录第一个点
{
FirstDataPoint = DataPoint;
bFirstPt = false;
}
pPline->AddDataPoint(DataPoint);
}
}
//闭合区域
pPline->AddDataPoint(FirstDataPoint);
//拉伸区域Y方向
{
SObjOperatePar par;
par.OpType = _OP_STRETCH;
DbRect rect = pPline->GetRect();
par.OldSize = rect.T - rect.B;
par.NewSize = (Coordy1-Coordy2)-ChangeSizeY;
par.Diff = par.NewSize-par.OldSize;
par.xy = _Y;
pPline->Operate(par);
}
//调整两端对象位置
{
SObjOperatePar par;
DbRect rect = pPline->GetRect();
par.OpType = _OP_MOVE;
par.MoveX = 0;
if(Dir==_DIR_U)
{
par.MoveY = Coordy1-rect.T;
}
else if(Dir==_DIR_D)
{
par.MoveY = Coordy2-rect.B;
}
else
{
par.MoveY = ((Coordy1+Coordy2)/2)-(rect.GetCenterPt().y);
}
pPline->Operate(par);
}
return pPline;
}
#endif