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.

562 lines
12 KiB
C++

1 month ago
#include "StdAfx.h"
#include ".\itembreakcurve.h"
#include "SigmaDoc.h"
#include "SigmaView.h"
#include "ActionListItem.h"
CItemBreakCurve::CItemBreakCurve(CSigmaDoc * ppDoc)
: CItemFocusRect(ppDoc)
, curPos(NULL)
, m_bRange(TRUE)
, m_nActionID(ID_EDIT_TOOL_BREAKS)
, m_bBreak(false)
{
this->SetType(ITEM_BREAK_CURVE);
m_pSelectCurve=new CItemSelectCurve(ppDoc);
m_pSelectCurve->SetNumber(-1);
m_bAutoDelete=TRUE;
m_bNoLineValue=FALSE;
m_bCountSelected = 0;
}
CItemBreakCurve::~CItemBreakCurve(void)
{
Clear();
}
void NItem::CItemBreakCurve::Clear(void)
{
if(m_pSelectCurve)
delete m_pSelectCurve;
m_pSelectCurve=NULL;
}
int CItemBreakCurve::GetSubMenu()
{
return 12;
}
void CItemBreakCurve::OnDraw(CXyDC* pDC)
{
if(m_pSelectCurve)
m_pSelectCurve->OnDraw(pDC);
}
void NItem::CItemBreakCurve::OnDraw(CXyDC* pXyDC, CDC* pDC)
{
OnDraw(pXyDC);
}
void CItemBreakCurve::OnRButtonDown(UINT nFlags, CPoint point)
{
//GetDoc()->DeleteItem();
}
void CItemBreakCurve::OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk)
{
if (m_pSelectCurve == NULL)
return;
GetDC()->Create(pDC);
if(m_pSelectCurve->GetSelectItem(0)==NULL || m_bRange==FALSE)
{
m_pSelectCurve->OnLButtonDown(pDC, nFlags,point, vk);
if(m_pSelectCurve->GetSelectCount()>1 && !m_bRange)
{
DelList.RemoveAll();
AddList.RemoveAll();
POSITION pos=m_pSelectCurve->GetSelectItem(0);
ASSERT(pos);
CCurveEx* pCurve=(CCurveEx*)GetDoc()->GetDraw()->GetAtValue(pos);
curPos=m_pSelectCurve->GetSelectItem(1);
ASSERT(curPos);
COne* pOne=(COne*)GetDoc()->GetDraw()->GetAt(curPos);
CPoint2D rp=GetDC()->GetReal(point);
if(ProcessCurve(pCurve,pOne,&rp))
{
//UNDO<44><4F><EFBFBD><EFBFBD>
//DelList.AddTail(curPos);
//CActionListItem* pItem=new CActionListItem(GetDoc(),m_nActionID);
//pItem->AddDeleteItem(DelList);
//pItem->AddAddItem(AddList);
//GetDoc()->SetActionItem(pItem);
//DelList.RemoveAll();
//AddList.RemoveAll();
}
m_pSelectCurve->RemoveAt(1);
curPos=NULL;
}
}
else
CItemFocusRect::OnLButtonDown(pDC, nFlags,point, vk);
}
int CItemBreakCurve::OnMouseMove(CDC *pDC, UINT nFlags, CPoint point)
{
if (m_pSelectCurve == NULL)
return 1;
if(m_pSelectCurve->GetSelectItem(0)==NULL || m_bRange==FALSE)
m_pSelectCurve->OnMouseMove(pDC, nFlags,point);
else
CItemFocusRect::OnMouseMove(pDC, nFlags,point);
return 1;
}
void CItemBreakCurve::DoLButtonUp(CDC *pDC)
{
ProcessLButtonUp();
m_bBreak = true;
delete m_pSelectCurve;
m_pSelectCurve = NULL;
}
void NItem::CItemBreakCurve::BreakCurveWithAction(CCurveEx* pCurve, CPositionList& list, CRect8* pRect)
{
DelList.RemoveAll();
AddList.RemoveAll();
BreakCurve(pCurve, list, pRect);
//UNDO<44><4F><EFBFBD><EFBFBD>
if(DelList.GetCount()>0 || AddList.GetCount()>0)
{
CActionListItem* pItem = new CActionListItem(GetDoc(), m_nActionID);
if (DelList.GetCount() > 0)
pItem->AddDeleteItem(DelList);
if (AddList.GetCount() > 0)
{
pItem->AddAddItem(AddList);
GetDoc()->InvalidateSelection(AddList);
}
GetDoc()->SetActionItem(pItem);
}
DelList.RemoveAll();
AddList.RemoveAll();
}
POSITION FindPosition(CPtrList& list, COne* pOther)
{
COne* pOne;
POSITION pb, pt;
pt=list.GetHeadPosition();
while(pt)
{
pb=pt;
pOne=(COne*)list.GetNext(pt);
if(pOne==pOther) return pb;
}
return NULL;
}
void NItem::CItemBreakCurve::BreakAllEditableCurve(CPositionList& list)
{
DelList.RemoveAll();
AddList.RemoveAll();
COne* pOne;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CPtrList pl;
POSITION pos,pt;
pos=list.GetHeadPosition();
while(pos)
{
pt=list.GetNext(pos);
pOne=GetDoc()->GetDraw()->GetAt(pt);
if(!pOne->IsCanEdit() || !pOne->IsView()) continue;
if(pOne->GetType()!=DOUBLEFOX_CURVE) continue;
pl.AddTail(pOne);
}
double len=pl.GetCount();
long count=0;
//GetDoc()->BeginProgress(ID_LAYERTREE_BREAK_CURVE);
pos=pl.GetHeadPosition();
while(pos)
{
AfxGetPublicFunction()->SetProgressPos(AfxGetPublicFunction()->FloatToLong(++count/len*100));
pOne=(COne*)pl.GetNext(pos);
BreakOne(pOne, pl);
//UNDO<44><4F><EFBFBD><EFBFBD>
if(DelList.GetCount()>0 || AddList.GetCount()>0)
{
CActionListItem* pItem=new CActionListItem(GetDoc(),ID_LAYERTREE_BREAK_CURVE);
if(DelList.GetCount()>0)
pItem->AddDeleteItem(DelList);
if(AddList.GetCount()>0)
{
pItem->AddAddItem(AddList);
GetDoc()->InvalidateSelection(AddList);
}
GetDoc()->SetActionItem(pItem);
GetDoc()->Modified();
}
DelList.RemoveAll();
AddList.RemoveAll();
}
//GetDoc()->EndProgress();
}
bool NItem::CItemBreakCurve::IsBreaked()
{
return m_bBreak;
}
int NItem::CItemBreakCurve::GetSelectCount()
{
if (m_pSelectCurve == NULL)
return 0;
return m_pSelectCurve->GetSelectCount();
}
void CItemBreakCurve::HightLightFirstCurve()
{
POSITION pos = m_pSelectCurve->GetSelectItem(0);
if (pos == 0)
return;
m_pSelectCurve->DrawSelectItem(pos);
}
void NItem::CItemBreakCurve::ProcessLButtonUp(void)
{
if (m_pSelectCurve == NULL)
return;
POSITION pos = m_pSelectCurve->GetSelectItem(0);
//ASSERT(pos != NULL);
if (pos == NULL)
return;
COne* pOne = (COne*)GetDoc()->GetDraw()->GetAt(pos);
CCurveEx* pCurve = (CCurveEx*)pOne->GetValue();
CRect8 rect = this->GetRect();
CPositionList list;
GetDoc()->GetDraw()->IsInRange(rect, list);
if (list.GetCount() == 0) return;
BreakCurveWithAction(pCurve, list, &rect);
}
int NItem::CItemBreakCurve::BreakOne(COne* pBaseOne, CPtrList& allBaseCurveList)
{
CRect8 rect;
CCurveEx* pCurve=(CCurveEx*)pBaseOne->GetValue();
rect=pBaseOne->GetRect();
CPositionList select;
if(GetDoc()->GetDraw()->IsInRange(rect, select)==0) return 0;
COne *pOther;
//ȥ<><C8A5><EFBFBD><EFBFBD>Χ<EFBFBD>߱<EFBFBD><DFB1><EFBFBD>
POSITION ps, pb, pg;
ps=select.GetHeadPosition();
while(ps)
{
pg=ps;
pb=select.GetNext(ps);
pOther=GetDoc()->GetDraw()->GetAt(pb);
if(pOther->GetType()!=DOUBLEFOX_CURVE)
select.RemoveAt(pg);
else if(FindPosition(allBaseCurveList, pOther))
select.RemoveAt(pg);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BreakCurve(pCurve, select, &rect);
return 1;
}
void NItem::CItemBreakCurve::BreakCurve(CCurveEx* pCurve, CPositionList& list, CRect8* pRect)
{
COne* pOne;
CCurveEx* pc;
CPoint2D rp;
CPoint2D tp;
CPoint2D* pCenterPoint=NULL;
POSITION p;
p=list.GetHeadPosition();
while(p)
{
curPos=list.GetNext(p);
pOne=(COne*)GetDoc()->GetDraw()->GetAt(curPos);
if(pOne->GetType()!=DOUBLEFOX_CURVE) continue;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>
pc=(CCurveEx*)pOne->GetValue();
if(pc==pCurve) continue;
if(pRect)
{
rp=pRect->CenterPoint();
for(int i=0;i<pc->num; i++)
{
tp.SetPoint(pc->x[i], pc->y[i]);
if(pRect->PtInRect(tp))
{
rp=tp;
break;
}
}
pCenterPoint=&rp;
}
if(ProcessCurve(pCurve,pOne,pCenterPoint))
DelList.AddTail(curPos);
}
}
int CItemBreakCurve::ProcessCurve(CCurveEx* pCurve, COne* pOne, CPoint2D* pPoint)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CCurveEx* pBreakCurve=(CCurveEx*)pOne->GetValue();
CCrossList list;
pBreakCurve->Cross(*(CCurve*)pCurve, list);
if(list.GetCount()==0) return 0;
BOOL bDoubleHeadTail=!m_bNoLineValue;
int count=0;
double zero=1e-300;
CCrossPoint p1,p2;
p1=list.GetHead();
if(list.GetCount()==1) //Ϊ<>˷<EFBFBD>ֹ<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>ʱ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϻ<EFBFBD><CFBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߽ڵ<DFBD>ȫ<EFBFBD><C8AB>Ϊͬһ<CDAC><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
if(fabs(pBreakCurve->l[0]-p1.x[0])<1e-10) return 0;
if(fabs(pBreakCurve->l[pBreakCurve->num-1]-p1.x[0])<1e-10) return 0;
}
pBreakCurve->GetCurve(pBreakCurve->l[0],p1.x[0]-zero,PointList, bDoubleHeadTail, m_bNoLineValue);
if(bDoubleHeadTail && !PointList.IsEmpty()) PointList.RemoveHead();
if(AddCurve(pOne)) count++;
POSITION pos=list.GetHeadPosition();
list.GetNext(pos);
while(pos)
{
p2=list.GetNext(pos);
pBreakCurve->GetCurve(p1.x[0]-zero,p2.x[0]-zero,PointList, bDoubleHeadTail, m_bNoLineValue);
if(AddCurve(pOne)) count++;
p1=p2;
}
pBreakCurve->GetCurve(p1.x[0]-zero,pBreakCurve->l[pBreakCurve->num-1],PointList, bDoubleHeadTail, m_bNoLineValue);
if(bDoubleHeadTail && !PointList.IsEmpty()) PointList.RemoveTail();
if(AddCurve(pOne)) count++;
return count;
}
POSITION CItemBreakCurve::AddCurve(COne* pBaseOne)
{
if(PointList.GetCount()<2 ) return NULL;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϻ<EFBFBD><CFBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>нڵ<D0BD><DAB5><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BOOL bDelete=TRUE;
POSITION pos=PointList.GetHeadPosition();
dfPoint dp, prevdp;
prevdp=PointList.GetNext(pos);
while(pos)
{
dp=PointList.GetNext(pos);
if(AfxGetPublicFunction()->Distance2(dp.x0, dp.y0, prevdp.x0, prevdp.y0)>1e-10)
{
bDelete=FALSE;
break;
}
prevdp=dp;
}
if(bDelete) return NULL;
CCurveEx* pBreakCurve=(CCurveEx*)pBaseOne->GetValue();
CCurveEx* pCurve=new CCurveEx((long)PointList.GetCount());
pCurve->CloneOtherParameter(*pBreakCurve);
pCurve->SetPoints(PointList,pBreakCurve->nPoint,pBreakCurve->bAutoLocation);
PointList.RemoveAll();
return AddCurve(pBaseOne,pCurve);
}
POSITION CItemBreakCurve::AddCurve(COne* pBaseOne, CCurveEx* pCurve)
{
if(curPos==NULL) return NULL;
COne *pOne=new COne;
pOne->SetType(pBaseOne->GetType());
pOne->value=pCurve;
pOne->SetLayer(pBaseOne->GetLayer());
if(pBaseOne->HowToViewCurve)
{
pOne->HowToViewCurve=new CHowToViewCurve();
*pOne->HowToViewCurve=*pBaseOne->HowToViewCurve;
}
if(pBaseOne->HowToViewPoint)
{
pOne->HowToViewPoint=new CHowToViewPoint();
*pOne->HowToViewPoint=*pBaseOne->HowToViewPoint;
}
pOne->color=pBaseOne->color;
if(pBaseOne->pHyperlink)
{
pOne->pHyperlink=new CHyperlinkMulti;
*pOne->pHyperlink=*pBaseOne->pHyperlink;
}
POSITION pos=InsertElementBefore(curPos,pOne,FALSE);
AddList.AddTail(pos);
return pos;
}
void CItemBreakCurve::sort_location(CList<CCrossPoint,CCrossPoint> &xy,CCrossPoint &cp,int nSortIndex)
{
int i,num;
CCrossPoint t;
POSITION p;
num=(int)xy.GetCount();
if(num<1)
{
xy.AddTail(cp);
return;
}
p=xy.GetHeadPosition( );
t=xy.GetAt(p);
if(cp.x[nSortIndex]<t.x[nSortIndex])
{
xy.AddHead(cp);
return;
}
if(num==1)
{
xy.AddTail(cp);
return;
}
for(i=0;i<num-1;++i)
{
xy.GetNext(p);
t=xy.GetAt(p);
if(cp.x[nSortIndex]<t.x[nSortIndex])
{
xy.InsertBefore(p,cp);
return;
}
}
xy.AddTail(cp);
}
void CItemBreakCurve::SortLocation(CList<CCrossPoint,CCrossPoint> &xy, int nSortIndex)
{
if((int)xy.GetCount()<1) return;
CCrossPoint t;
CList<CCrossPoint,CCrossPoint> list;
POSITION p;
p=xy.GetHeadPosition();
while(p)
{
t=xy.GetNext(p);
list.AddTail(t);
}
xy.RemoveAll();
p=list.GetHeadPosition();
while(p)
{
t=list.GetNext(p);
sort_location(xy,t,nSortIndex);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//class CItemBreakCurveDirect
CItemBreakCurveDirect::CItemBreakCurveDirect(CSigmaDoc * ppDoc)
: CItemBreakCurve(ppDoc)
//m_buttonStatus(0)
{
this->SetType(ITEM_BREAK_CURVE_DIRECT);
m_pItemCurve=new CItemCurve(ppDoc);
}
CItemBreakCurveDirect::~CItemBreakCurveDirect()
{
Clear();
}
void NItem::CItemBreakCurveDirect::Clear(void)
{
CItemBreakCurve::Clear();
if(m_pItemCurve) delete m_pItemCurve;
m_pItemCurve=NULL;
}
void NItem::CItemBreakCurveDirect::OnDraw(CXyDC* pXyDC, CDC* pDC)
{
m_pItemCurve->OnDraw(pXyDC, pDC);
}
void CItemBreakCurveDirect::OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk)
{
int count = m_pItemCurve->PointList.GetCount();
if (count < 2)
{
m_pItemCurve->OnLButtonDown(pDC, nFlags, point, vk);
}
count = m_pItemCurve->PointList.GetCount();
if (count == 2) {
CCurveEx * pCurve = new CCurveEx;
pCurve->SetPoints(m_pItemCurve->PointList, 2, TRUE);
m_pItemCurve->Reset();
if (pCurve->num < 2)
{
delete pCurve;
return;
}
CRect8 rt(1e300, -1e300, -1e300, 1e300);
pCurve->GetRange(rt);
rt.NormalizeRect();
//ѡ<><D1A1>ֱ<EFBFBD>߶<EFBFBD><DFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5>߶<EFBFBD>.
CPositionList list;
GetDoc()->GetDraw()->IsInRange(rt, list);
if (list.GetCount() == 0)
return;
BreakCurveWithAction(pCurve, list, NULL);
delete pCurve;
}
}
int CItemBreakCurveDirect::OnMouseMove(CDC* pDC, UINT nFlags, CPoint point)//, BYTE*& destBuffer, int& destLen)
{
return m_pItemCurve->OnMouseMove(pDC, nFlags, point);
}
void CItemBreakCurveDirect::OnRButtonDown(UINT nFlags, CPoint point)
{
}
BOOL CItemBreakCurveDirect::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar != VK_ESCAPE)
return FALSE;
if (m_pScreenDC == 0)
return FALSE;
if (m_pItemCurve->PointList.IsEmpty())
return TRUE;
m_pItemCurve->Reset();
return TRUE;
}
void CItemBreakCurveDirect::OnLButtonUp(CDC* pDC, UINT nFlags, CPoint point, int vk)
{
}