Files
envi-code/SourceCode/Code2026/tg_shs/shs_subgeLib/TPGeCurveMesh.cpp
T
2026-09-28 15:28:50 +08:00

338 lines
6.9 KiB
C++

//-------------------------------------------------------------------------------------------------------+
// 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<TGMeshNode*> 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<TPGeCurveMesh> &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<TGMeshEdge*> 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);
}
}
}