#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操作 //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操作 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; //获得所有曲线 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操作 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; //去除范围线本身 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); } //打断曲线 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; //计算最近的点 pc=(CCurveEx*)pOne->GetValue(); if(pc==pCurve) continue; if(pRect) { rp=pRect->CenterPoint(); for(int i=0;inum; 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) { //打断曲线 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) //为了防止重复打断时,引起打断后的曲线节点全部为同一坐标的情况 { 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; //如果打断后的曲线所有节点坐标全相同时不增加 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 &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] &xy, int nSortIndex) { if((int)xy.GetCount()<1) return; CCrossPoint t; CList 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(); //选择直线段外包矩形内的线段. 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) { }