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.

304 lines
9.5 KiB
C++

#include "StdAfx.h"
#include "MouseToolCut.h"
#include "GlobalDrawMgr.h"
#include "Layer.h"
#include "GlobalFunction.h"
#include "LogMgr.h"
#include "ObjPline.h"
#include "CommandCut.h"
#include "CommandMgr.h"
#if 1//<2F><><EFBFBD><EFBFBD><EFBFBD>ñȽϺ<C8BD><CFBA><EFBFBD>
//<2F><><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>0<EFBFBD><30> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD>>0<><30>ֵ<EFBFBD><D6B5> <20><><EFBFBD>򷵻<EFBFBD>С<EFBFBD><D0A1>0<EFBFBD><30>ֵ
bool CompareDbPointX(Dbxy pt1,Dbxy pt2)
{
return pt1.x>pt2.x;
}
bool CompareDbPointY(Dbxy pt1,Dbxy pt2)
{
return pt1.y>pt2.y;
}
#endif
CMouseToolCut::CMouseToolCut(void)
{
}
CMouseToolCut::~CMouseToolCut(void)
{
}
void CMouseToolCut::OnLButtonDown(UINT nFlags, CPoint point,CClientDC &dc)
{
Dbxy pt = gDraw->CPoint2Dbxy(point);
DbRect rect = gDraw->GetCurPointRect(pt);
CutLineInRect(rect);
}
//<2F><><EFBFBD><EFBFBD>rect <20>е<EFBFBD>line
void CMouseToolCut::CutLineInRect(DbRect &rect)
{
CLayer &layer = gLayer;
if(!layer.HasObjectInRect(rect))
return;
//<2F><><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>rect <20><>obj -----------------------------------------------
Sptr<CObjBase> pObj = layer.GetFirstObjInRect(rect);
//<2F><><EFBFBD><EFBFBD>obj <20><>rect <20>еĵ<D0B5>һ<EFBFBD><D2BB>line -----------------------------------------------
Dbxy LinePt1,LinePt2;
GetFirstLineInRect(pObj,rect,LinePt1,LinePt2);
if(LinePt1.Equal(LinePt2))
return;
//<2F><><EFBFBD><EFBFBD>line <20>γɵľ<C9B5><C4BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5>߶ε<DFB6>LineVec -----------------------------------------------
vector<DbLine> LineVec;
DbRect LineRect = GetLineRect(LinePt1,LinePt2);
layer.GetLineInRect(LineRect,LineVec,false);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еĽ<D0B5><C4BD>㵽PointVec -----------------------------------------------
vector<Dbxy> PointVec;
CalAllIntersection(LinePt1,LinePt2,LineRect,LineVec,PointVec);
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD>ֻʣ<D6BB><CAA3><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>߶<EFBFBD><DFB6><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>޼<EFBFBD>
if(PointVec.empty())
return;
//<2F><><EFBFBD>ݽ<EFBFBD><DDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>obj -----------------------------------------------
CutObj(LinePt1,LinePt2,pObj,PointVec,rect);
}
//<2F><><EFBFBD>ñ<EFBFBD><C3B1>и<EFBFBD><D0B8>߶<EFBFBD><DFB6>γɵľ<C9B5><C4BE><EFBFBD>
DbRect CMouseToolCut::GetLineRect(const Dbxy &LinePt1,const Dbxy &LinePt2)
{
double MixGap = 0.01;
//<2F><><EFBFBD><EFBFBD>ˮƽ<CBAE><C6BD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Dbxy RectPt1 = LinePt1;
Dbxy RectPt2 = LinePt2;
if(IsTwoDbEqual(LinePt1.x,LinePt2.x))
{
RectPt1.x -= MixGap;
RectPt2.x += MixGap;
}
if(IsTwoDbEqual(LinePt1.y,LinePt2.y))
{
RectPt1.y += MixGap;
RectPt2.y -= MixGap;
}
DbRect LineRect(RectPt1,RectPt2);
return LineRect;
}
//<2F><><EFBFBD><EFBFBD>obj <20><>rect <20>еĵ<D0B5>һ<EFBFBD><D2BB>line
void CMouseToolCut::GetFirstLineInRect(Sptr<CObjBase> &pObj,DbRect &rect,Dbxy &LinePt1,Dbxy &LinePt2)
{
vector<DbLine> LineVec;
pObj->GetLineInRect(rect,LineVec);
LinePt1 = LineVec[0].m_pt1.GetPt();
LinePt2 = LineVec[0].m_pt2.GetPt();
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD>,<2C><><EFBFBD>浽PointVec <20><>
void CMouseToolCut::CalAllIntersection(Dbxy LinePt1,Dbxy LinePt2,DbRect &LineRect,vector<DbLine> &LineVec,vector<Dbxy> &PointVec)
{
vector<DbLine>::iterator iter = LineVec.begin();
vector<DbLine>::iterator iter_end = LineVec.end();
for(;iter!=iter_end;iter++)
{
Dbxy pt3 = (*iter).m_pt1.GetPt();
Dbxy pt4 = (*iter).m_pt2.GetPt();
if(pt3.Equal(pt4))//<2F><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>
{
continue;
}
if(IsTwoLineIntersect(LinePt1,LinePt2,pt3,pt4))
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Dbxy pt = CalIntersection(LinePt1,LinePt2,pt3,pt4);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>rect <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>벶׽<EBB2B6><D7BD>
if(IsPointInRect(pt,LineRect))
{
PointVec.push_back(pt);
}
}
}
}
//<2F><><EFBFBD>ݽ<EFBFBD><DDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޼<EFBFBD>obj
//rect <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>rect <20><>Χ
//pObj <20>ǵ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>еĶ<D0B5><C4B6><EFBFBD>
//PointVec <20><><EFBFBD>߶ν<DFB6><CEBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void CMouseToolCut::CutObj(Dbxy LinePt1,Dbxy LinePt2,Sptr<CObjBase> pObj,vector<Dbxy> &PointVec,DbRect &rect)
{
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>е<EFBFBD>-------------------------------------
Dbxy CutPt1,CutPt2;
if(GetCutPoint(LinePt1,LinePt2,PointVec,rect,CutPt1,CutPt2)==false)
{
return;
}
//<2F><>obj <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>------------------------------------------
CObjPline *pObj1 = NULL;
CObjPline *pObj2 = NULL;
CutObjExt(LinePt1,LinePt2,pObj,CutPt1,CutPt2,pObj1,pObj2);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>-----------------------------------
m_TmpObjContainer.Clear();
CreatCommandCut(pObj,pObj1,pObj2);
GetCurViewPtr()->RefreshView();
}
//<2F><><EFBFBD><EFBFBD><EFBFBD>޼<EFBFBD>ָ<EFBFBD><D6B8>
//pObj ʱ<>޼<EFBFBD>ǰobj
//pObj1<6A><31>pObj2 <20><><EFBFBD>޼<EFBFBD><DEBC><EFBFBD><EFBFBD><EFBFBD>obj
void CMouseToolCut::CreatCommandCut(Sptr<CObjBase> pObj,CObjPline *&pObj1,CObjPline *&pObj2)
{
CCommandCut *p = new CCommandCut;
p->AddOpObj(pObj);
AddToCmd(pObj1,p);
AddToCmd(pObj2,p);
m_TmpObjContainer.AllObjAddToLayer();
gCommandMgr.AddUndoCommand(p);
gLayer.DelObj(pObj);
}
void CMouseToolCut::AddToCmd(CObjPline *&pObj,CCommandCut *&pCommandCut)
{
if(pObj)
{
//<2F><><EFBFBD><EFBFBD><E6B5BD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
Sptr<CObjBase> sPtr(pObj);
m_TmpObjContainer.AddObject(sPtr);
pCommandCut->AddOpObj(sPtr);
}
else
{
delete pObj;
}
}
//<2F><>obj <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool CMouseToolCut::CutObjExt(Dbxy LinePt1,Dbxy LinePt2,Sptr<CObjBase> pObj,Dbxy CutPt1,Dbxy CutPt2,CObjPline *&pObj1,CObjPline *&pObj2)
{
vector<CDataPoint>&Container = pObj->GetPtContainer();
int size = Container.size();
Dbxy NearPt;//<2F><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>
Dbxy FarPt;//<2F>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD>ֵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
//<2F>ָ<EFBFBD><D6B8><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>------------------------------------------------------------
int i=0;
for(;i<size;i++)
{
Dbxy pt = Container[i].GetPt();
Dbxy Nextpt = Container[i+1].GetPt();
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>
if(IsSelLine(LinePt1,LinePt2,pt,Nextpt))
{
GetNearFarPoint(CutPt1,CutPt2,pt,NearPt,FarPt);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>obj <20>Ķ˵<C4B6>, <20><>û<EFBFBD>е<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
if(i==0 && (pt.Equal(CutPt1) || pt.Equal(CutPt2)))
{
i++;//break <20><><EFBFBD>Ժ<EFBFBD>i <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
break;
}
}
if(i==0)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
{
pObj1 = new CObjPline;
//<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
CDataPoint DataPoint(Container[i].GetPt());
DataPoint.SetIsNode(true);
pObj1->AddDataPoint(DataPoint);
}
else
{
pObj1->AddDataPoint(Container[i]);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>߶<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>߶Σ<DFB6><CEA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
if(IsSelLine(LinePt1,LinePt2,pt,Nextpt))
{
GetNearFarPoint(CutPt1,CutPt2,pt,NearPt,FarPt);
Dbxy pt = Container[i].GetPt();
if(!(pt == NearPt))//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD>ظ<EFBFBD><D8B8>ĵ<EFBFBD>2015-12-10
{
CDataPoint DataPoint(NearPt);
DataPoint.SetIsNode(true);
pObj1->AddDataPoint(DataPoint);
}
i++;//break <20><><EFBFBD>Ժ<EFBFBD>i <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
break;
}
}
//<2F>ָ<EFBFBD><D6B8>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD>--------------------------------------------------------------
if(!(i==size-1 && FarPt.Equal(Container[i].GetPt())))
{
bool bflg = true;
for(;i<size;i++)
{
if(bflg)//<2F>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ĵڶ<C4B5><DAB6><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ڶ<EFBFBD><DAB6>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD>
{
pObj2 = new CObjPline;
CDataPoint DataPoint(FarPt);
DataPoint.SetIsNode(true);
pObj2->AddDataPoint(DataPoint);
}
//<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD>
if(i==size-1)//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ǽڵ<C7BD>
{
CDataPoint DataPoint(Container[i].GetPt());
DataPoint.SetIsNode(true);
pObj2->AddDataPoint(DataPoint);
}
else
{
//<2F><><EFBFBD><EFBFBD>FarPt <20><><EFBFBD>ڵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>
if(!(bflg && FarPt.Equal(Container[i].GetPt())))
{
pObj2->AddDataPoint(Container[i]);
}
}
bflg = false;
}
}
return true;
}
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>е<EFBFBD>
bool CMouseToolCut::GetCutPoint(Dbxy LinePt1,Dbxy LinePt2,vector<Dbxy> &PointVec,DbRect &rect,Dbxy &CutPt1,Dbxy &CutPt2)
{
//<2F>ȵõ<C8B5><C3B5><EFBFBD><EFBFBD><EFBFBD>rect <20>߶εĽ<CEB5><C4BD><EFBFBD>--------------------------------------------------
Dbxy MousePt = IntersectionOfRectAndLine(LinePt1,LinePt2,rect);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MousePt <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>----------------------------------------------
PointVec.push_back(MousePt);
PointVec.push_back(LinePt1);
PointVec.push_back(LinePt2);
if(IsTwoDbEqual(LinePt1.x,LinePt2.x))//<2F><>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
//<2F><>y <20><><EFBFBD><EFBFBD>
sort(PointVec.begin(),PointVec.end(),CompareDbPointY);
}
else//<2F><><EFBFBD><EFBFBD>ֱ
{
//<2F><>x <20><><EFBFBD><EFBFBD>
sort(PointVec.begin(),PointVec.end(),CompareDbPointX);
}
vector<Dbxy>::iterator MousePtIter = find(PointVec.begin(),PointVec.end(),MousePt);
//ֻ<><D6BB><EFBFBD><EFBFBD>MousePtIter <20><><EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(MousePtIter==PointVec.end() || MousePtIter==PointVec.end()-1 || MousePtIter==PointVec.begin())
return false;
CutPt1 = (*(MousePtIter-1));
CutPt2 = (*(MousePtIter+1));
if(CutPt1.Equal(CutPt2))
return false;
return true;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>
bool CMouseToolCut::IsSelLine(Dbxy LinePt1,Dbxy LinePt2,Dbxy pt,Dbxy Nextpt)
{
return ((LinePt1.Equal(pt) && LinePt2.Equal(Nextpt))||(LinePt1.Equal(Nextpt) && LinePt2.Equal(pt)));
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pt <20>Ͻ<EFBFBD><CFBD>ĵ<EFBFBD>
void CMouseToolCut::GetNearFarPoint(Dbxy pt1,Dbxy pt2,Dbxy pt,Dbxy &NearPt,Dbxy &FarPt)
{
if(CalDistance(pt1,pt)<CalDistance(pt2,pt))
{
NearPt = pt1;
FarPt = pt2;
}
else
{
NearPt = pt2;
FarPt = pt1;
}
}