//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TPGeCurveMesh Àà // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TPGeCurveMesh ¶¨Òå // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #include "StdAfx.h" #include "TPGeCurveMesh.h" #include "TGMeshNode.h" #include "TGMeshEdge.h" #include "TListQuene.h" #include "TGRegion2D.h" #include "TGRegionEx2D.h" TPGeCurveMesh::TPGeCurveMesh() { } TPGeCurveMesh::~TPGeCurveMesh() { } bool TPGeCurveMesh::operator > (const TPGeCurveMesh&) const { return false; } bool TPGeCurveMesh::operator < (const TPGeCurveMesh&) const { return false; } TGMeshNode* TPGeCurveMesh::FindOrAddNode(const TGPoint&pt) { TGMeshNode*pNode = new TGMeshNode(pt); if(!m_allNode.SortIn(pNode)) { delete pNode; } return m_allNode.GetCurData(); } void TPGeCurveMesh::AppendCurve(const TPGeCurve2D*pCurve) { if((!pCurve->IsFinite(true) && !pCurve->IsFinite(false)) || pCurve->IsClosed()) { return; } TGPoint pt1,pt2; pCurve->GetStartPoint(pt1); pCurve->GetEndPoint(pt2); if(pt1.Equal2D(pt2)) { return; } m_allEdge.AddTail(new TGMeshEdge(pCurve,pCurve->IsFinite(true) ? FindOrAddNode(pt1) : NULL, pCurve->IsFinite(false) ? FindOrAddNode(pt2) : NULL)); } void TPGeCurveMesh::RemoveOpenEdge() { TListQuene quene; for(m_allNode.MoveToFirst(); !m_allNode.IsOut(); m_allNode.MoveToNext()) { if(m_allNode.GetCurData()->IsEndNode()) { quene.EnQuene(m_allNode.GetCurData()); } } while(!quene.IsEmpty()) { TGMeshNode*pNode; quene.DeQuene(pNode); TGMeshEdge*pEdge = pNode->GetOnlyEdge(); if(pEdge == NULL) { continue; } pNode->Clear(); pNode = pEdge->GetNextNode(pNode); if(pNode != NULL) { pNode->RemoveEdge(pEdge); if(pNode->IsEndNode()) { quene.EnQuene(pNode); } } pEdge->AddFlag(INVALID_EDGE); } for(m_allEdge.MoveToFirst();!m_allEdge.IsOut();m_allEdge.MoveToNext()) { if(m_allEdge.GetCurData()->Is(INVALID_EDGE)) { m_allEdge.DelCur(); } } } TPGeCurveMesh::TPGeCurveMesh(const TGObjectList&buf,bool bOnlyClose) { for(TGObject*const*p = buf.GetFirst();p != NULL;p = buf.GetNext(p)) { AppendCurve((const TPGeCurve2D*)(*p)); } for(m_allNode.MoveToFirst();!m_allNode.IsOut();m_allNode.MoveToNext()) { m_allNode.GetCurData()->Arrange(); } for(m_allEdge.MoveToFirst();!m_allEdge.IsOut();m_allEdge.MoveToNext()) { if(m_allEdge.GetCurData()->Is(DUP_EDGE)) { TGMeshEdge *pEdge = m_allEdge.GetCurData(); TGMeshNode* pNode1 = (TGMeshNode*)pEdge->GetNode(1),*pNode2 = (TGMeshNode*)pEdge->GetNode(2); if(pNode1 != NULL) { pNode1->RemoveEdge(pEdge); } if(pNode2 != NULL) { pNode2->RemoveEdge(pEdge); } m_allEdge.DelCur(); } } if(bOnlyClose) { RemoveOpenEdge(); } } void TPGeCurveMesh::FindAllMesh() { for(m_allEdge.MoveToFirst();!m_allEdge.IsOut();m_allEdge.MoveToNext()) { TGMeshEdge* pEdge = m_allEdge.GetCurData(); if(pEdge->IsNot(VISITED12)) { TGMesh* pMesh = pEdge->FindMesh(1); if(pMesh != NULL) { pMesh->ExplodeSelfCross(m_allMesh); m_allMesh << pMesh; } } if(pEdge->IsNot(VISITED21)) { TGMesh* pMesh = pEdge->FindMesh(2); if(pMesh != NULL) { pMesh->ExplodeSelfCross(m_allMesh); m_allMesh << pMesh; } } } } void TPGeCurveMesh::FindAllSDMesh() { for(m_allEdge.MoveToFirst();!m_allEdge.IsOut();m_allEdge.MoveToNext()) { TGMeshEdge* pEdge = m_allEdge.GetCurData(); if(pEdge->IsNot(VISITED12)) { TGMesh* pMesh = pEdge->FindSDMesh(); if(pMesh != NULL) { pMesh->ExplodeSelfCross(m_allMesh); m_allMesh << pMesh; } } } } void TPGeCurveMesh::Explode(TPDList &lstChildMesh) { for(m_allEdge.MoveToFirst();!m_allEdge.IsOut();m_allEdge.MoveToNext()) { TGMeshEdge *pEdge = m_allEdge.GetCurData(); if(pEdge->IsNot(VISITED)) { TPGeCurveMesh *pChild = new TPGeCurveMesh; TListQuene quene; pEdge->AddFlag(VISITED); quene.EnQuene(pEdge); while(!quene.IsEmpty()) { quene.DeQuene(pEdge); pChild->m_allEdge << pEdge; if(pEdge->m_pNode1 != NULL) { pChild->m_allNode.SortIn(pEdge->m_pNode1); } if(pEdge->m_pNode2 != NULL) { pChild->m_allNode.SortIn(pEdge->m_pNode2); } if(pEdge->m_pMesh1 != NULL) { pChild->m_allMesh.FindOrAddTail(pEdge->m_pMesh1); } if(pEdge->m_pMesh2 != NULL) { pChild->m_allMesh.FindOrAddTail(pEdge->m_pMesh2); } TGMeshNode *pNode = pEdge->m_pNode1; if(pNode != NULL) { for(pNode->m_lstEdge.MoveToFirst();!pNode->m_lstEdge.IsOut();pNode->m_lstEdge.MoveToNext()) { TGMeshEdge *pEdge1 = pNode->m_lstEdge.GetCurData(); if(pEdge1->IsNot(VISITED)) { pEdge1->AddFlag(VISITED); quene.EnQuene(pEdge1); } } } pNode = pEdge->m_pNode2; if(pNode != NULL) { for(pNode->m_lstEdge.MoveToFirst();!pNode->m_lstEdge.IsOut();pNode->m_lstEdge.MoveToNext()) { TGMeshEdge *pEdge1 = pNode->m_lstEdge.GetCurData(); if(pEdge1->IsNot(VISITED)) { pEdge1->AddFlag(VISITED); quene.EnQuene(pEdge1); } } } } lstChildMesh << pChild; } } for(m_allEdge.MoveToFirst();!m_allEdge.IsOut();m_allEdge.MoveToNext()) { TGMeshEdge *pEdge = m_allEdge.GetCurData(); pEdge->RemoveFlag(VISITED); m_allEdge.SetCurData(NULL); } m_allEdge.Clear(); for(m_allNode.MoveToFirst();!m_allNode.IsOut();m_allNode.MoveToNext()) { if(m_allNode.GetCurData()->m_lstEdge.GetLength() > 0) { m_allNode.FetchCur(); } } for(m_allMesh.MoveToFirst();!m_allMesh.IsOut();m_allMesh.MoveToNext()) { m_allMesh.SetCurData(NULL); } m_allMesh.Clear(); } void TPGeCurveMesh::CreateRegion(TGObjectList& lstRegion,TGObjectList&lstHole) { TGObjectList oListCCW,oListCW; for(m_allMesh.MoveToFirst();!m_allMesh.IsOut();m_allMesh.MoveToNext()) { TPGeCurve2D *pCurve = m_allMesh.GetCurData()->CreateCurve(); if(pCurve != NULL) { if(pCurve->IsClosed()) { if(pCurve->IsClockwise()) { pCurve->Reverse(); oListCW << pCurve; } else { oListCCW << pCurve; } } else { delete pCurve; } } } if(oListCCW.GetLength() == 1) { TGObjectList oList; oList.Conbine(oListCCW); oList.Conbine(oListCW); TGRegion2D *pRegion = new TGRegionEx2D(oList,false); if(!pRegion->IsValid()) { delete pRegion; } else { lstRegion << pRegion; } } else { for(oListCCW.MoveToFirst();!oListCCW.IsOut();oListCCW.MoveToNext()) { lstRegion << new TGRegionEx2D(oListCCW.GetCurCurve2D(),false); } for(oListCW.MoveToFirst();!oListCW.IsOut();oListCW.MoveToNext()) { lstHole << new TGRegionEx2D(oListCW.GetCurCurve2D(),false); } } }