Files
envi-code/SourceCode/Code2026/tg_shs/shs_subgeLib/TGRegion2D.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

1185 lines
23 KiB
C++

//-----------------------------------------------------------------------------+
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
// = FileName : TGRegion2D.cpp
// = Version : ver2.0
// = Author : xlc
// = CreateDate : 2002-09-09
// = Description: 类的定义
// = Maintainers:
//
//-----------------------------------------------------------------------------+
#include "StdAfx.h"
#include "TGRegion2D.h"
#include "TPGeCurve2D.h"
#include "TGRegionEx2D.h"
#include "TGPolygonEx2D.h"
#include "TGPolygon2D.h"
#include "TPGeGraph.h"
#include "TPushMemVar.h"
#include "TProductid.h"
extern int g_nProductId;
IMPLEMENT_RUN_TIME_CLASS1(TGRegion2D,"TGRegion2D",TGObject2D)
TGRegion2D::~TGRegion2D()
{
}
bool TGRegion2D::IsValid() const
{
if (GetBoundaryNum()<1)
{
return false;
}
if (IsOutlineExist())
{
TPGeCurve2D&curve0 = Outline();
if (!curve0.IsValid() || curve0.IsSelfCross() ||
!(curve0.IsInfinite() || (curve0.IsClosed() && !curve0.IsClockwise())))
{
return false;
}
}
if (!IsHoleExist())
{
return true;
}
TGObjectList holes;
if (IsOutlineExist())
{
TGRegionEx2D face0(Outline(),false);
for (long i = 0;i<GetHoleNum();i++)
{
if (GetBoundary(i+1) == NULL)
{
return false;
}
TPGeCurve2D& curve1 = Hole(i);
if (!curve1.IsValid() || curve1.IsSelfCross() ||
!(curve1.IsInfinite() || (curve1.IsClosed() && curve1.IsClockwise())))
{
return false;
}
TPGeCurve2D* pNewCurve = (TPGeCurve2D*)curve1.Clone();
pNewCurve->Reverse();
TGRegionEx2D *pHole = new TGRegionEx2D(pNewCurve,false);
if (face0.IsInclude(*pHole))
{
holes.AddTail(pHole);
}
else
{
delete pHole;
return false;
}
}
}
else
{
for (long i = 0;i<GetHoleNum();i++)
{
if (GetBoundary(i+1) == NULL)
{
return false;
}
TPGeCurve2D& curve1 = Hole(i);
if (!curve1.IsValid() || curve1.IsSelfCross() ||
!(curve1.IsInfinite() || (curve1.IsClosed() && curve1.IsClockwise())))
{
return false;
}
TPGeCurve2D* pNewCurve = (TPGeCurve2D*)curve1.Clone();
pNewCurve->Reverse();
holes << new TGRegionEx2D(pNewCurve,false);
}
}
TGObjectList buf;
while(holes.GetLength()>1)
{
TGRegion2D *pFirst = (TGRegion2D*)(holes.Fetch(0));
buf << pFirst;
for (holes.MoveToFirst();!holes.IsOut();holes.MoveToNext())
{
if (pFirst->Inter(holes.GetCurRegion2D(),buf))
{
return false;
}
}
}
return IsAllowBoundaryInter()?true:!IsBoundaryInter();
}
bool TGRegion2D::IsInclude(const TGObject&obj) const
{
if (IS_CLASS(&obj,TGRegion2D))
{
TGObjectList left;
((const TGRegion2D&)obj).SubtractBy(*this,left);
return left.IsEmpty();
}
TGObjectList in,out;
Clip(obj,in,out,in);
return out.IsEmpty();
}
void TGRegion2D::SetElev(double elev)
{
long num = GetBoundaryNum();
for (long i = 0;i<num;i++)
{
TPGeCurve2D*pCurve = GetBoundary(i);
if (pCurve != NULL)
{
pCurve->SetElev(elev);
}
}
}
double TGRegion2D::GetElev() const
{
long num = GetBoundaryNum();
for (long i = 0;i<num;i++)
{
TPGeCurve2D*pCurve = GetBoundary(i);
if (pCurve != NULL)
{
return pCurve->GetElev();
}
}
return 0;
}
void TGRegion2D::TransformBy(const TGMatrix&matrix)
{
long num = GetBoundaryNum();
for (long i = 0;i<num;i++)
{
TPGeCurve2D* pCurve = GetBoundary(i);
if (pCurve != NULL)
{
pCurve->TransformBy(matrix);
}
}
}
bool TGRegion2D::Offset(double offset)
{
long num = GetBoundaryNum();
for (long i = 0;i<num;i++)
{
TPGeCurve2D* pCurve = GetBoundary(i);
if (pCurve != NULL && !pCurve->Offset(offset))
{
return false;
}
}
return true;
}
bool TGRegion2D::IsBoundaryInter() const
{
if (!IsHoleExist())
{
return false;
}
TDualPtrList<TPGeCurve2D*> curves;
for (long i = 0;i<GetBoundaryNum();i++)
{
TPGeCurve2D* pCurve = GetBoundary(i);
if (pCurve != NULL)
{
curves << GetBoundary(i);
}
}
TGObjectList buf;
while(curves.GetLength()>1)
{
curves.MoveToFirst();
TPGeCurve2D *pCurve0 = curves.GetCurData();
curves.DelCur();
for (curves.MoveToFirst();!curves.IsOut();curves.MoveToNext())
{
if (pCurve0->Intersect(*curves.GetCurData(),buf))
{
return true;
}
}
}
return false;
}
GRelation TGRegion2D::HitTest(const TGPoint&pt) const
{
if (IsOutlineExist())
{
GRelation r = Outline().HitTest(pt);
if (r.Is(GR_OUTSIDE))
{
return GR_OUT;
}
else if (r.Is(GR_IN))
{
return GR_IN|GR_EDGE;
}
}
for (long i = 0;i<GetHoleNum();i++)
{
GRelation r = Hole(i).HitTest(pt);
if (r.Is(GR_INSIDE))
{
return GR_OUT|GR_HOLE;
}
else if (r.Is(GR_IN))
{
return GR_IN|GR_EDGE|GR_HOLE;
}
}
return GR_IN;
}
void TGRegion2D::Clip(const TGObject &obj,TGObjectList&inList,TGObjectList&outList,TGObjectList&midList) const
{
TGObjectList in;
if (IsOutlineExist())
{
// modify by xlc on 110610 区分日照,影响速度
if (g_nProductId == kTSUN)
{
Outline().Cut(obj,in,outList,midList);
}
else
{
struct resbuf rb;
acedGetVar(_T("CMDNAMES"),&rb);
CString sCmd = rb.resval.rstring;
acutDelString(rb.resval.rstring);
sCmd.MakeUpper();
if (sCmd.Find(_T("TUPDSPACE")) >= 0) //modify by xlc on 110117 搜索房间时不改变精度(搜索房间时不考虑柱子)
{
Outline().Cut(obj,in,outList,midList);
}
else
{
//add by xlc on 100906 解决部分加粗不显示的问题
TPushMemVar<double> vPrec(g_distZero,1.0e-6);
Outline().Cut(obj,in,outList,midList);
}
}
if (in.IsEmpty())
{
return;
}
}
else
{
in << obj.Clone();
}
for (long i = 0;i<GetHoleNum();i++)
{
TGObjectList in1;
in1.Conbine(in);
in1.CutBy(Hole(i),outList,in,midList);
}
inList.Conbine(in);
}
bool TGRegion2D::Intersect(const TGObject&obj,TGObjectList&res) const
{
if (IS_CLASS(&obj,TGRegion2D))
{
return Inter((const TGRegion2D&)obj,res);
}
TGObjectList out,in;
Clip(obj,in,out,in);
if (in.IsEmpty())
{
return false;
}
else
{
res.Conbine(in);
return true;
}
}
bool TGRegion2D::GetExtend2D(TPGeExtend2D&ext) const
{
if (IsOutlineExist())
{
return Outline().GetExtend2D(ext);
}
else
{
return false;
}
}
void TGRegion2D::SubtractBy(const TGObjectList&faces,TGObjectList&res) const
{
TGObject*const*pCur = faces.GetFirst();
if (pCur == NULL)
{
res << Clone();
return;
}
const TGRegion2D& face = (const TGRegion2D&)(**pCur);
TGObjectList buf;
SubtractBy(face,buf);
if (buf.IsEmpty())
{
return;
}
for (pCur = faces.GetNext(pCur);pCur != NULL;pCur = faces.GetNext(pCur))
{
TGObjectList buf1;
const TGRegion2D&face = (const TGRegion2D&)(**pCur);
for (buf.MoveToFirst();!buf.IsOut();buf.MoveToNext())
{
buf.GetCurRegion2D().SubtractBy(face,buf1);
}
if (buf1.IsEmpty())
{
return;
}
buf.Clear();
buf.Conbine(buf1);
}
res.Conbine(buf);
}
void TGRegion2D::Normalize()
{
if (IsClosed() && Outline().IsClockwise())
{
Outline().Reverse();
}
for (long i = 1;i<GetBoundaryNum();i++)
{
TPGeCurve2D* pCurve = GetBoundary(i);
if (pCurve != NULL && pCurve->IsClosed() && !pCurve->IsClockwise())
{
pCurve->Reverse();
}
}
}
double TGRegion2D::Area() const
{
if (!IsClosed())
{
return 0;
}
double A = Outline().Area();
for (long i = 0;i<GetHoleNum();i++)
{
A -= Hole(i).Area();
}
return A;
}
TGPolygon2D* TGRegion2D::MLinearize(double paDist) const
{
if (!IsClosed())
{
return NULL;
}
if (IsHoleExist())
{
TGMLine2D* pMLine = Outline().MLinearize(paDist);
TGPolygonEx2D *pFace = new TGPolygonEx2D(*pMLine,false);
delete pMLine;
for (long i = 0;i<GetHoleNum();i++)
{
pFace->AppendHole(Hole(i).MLinearize(paDist),false);
}
return pFace;
}
else
{
TGMLine2D* pMLine = Outline().MLinearize(paDist);
TGPolygon2D *pFace = new TGPolygon2D(*pMLine,false);
delete pMLine;
return pFace;
}
}
bool TGRegion2D::Explode(TGObjectList&res) const
{
TGPolygon2D* pPoly = MLinearize();
if (pPoly == NULL)
{
return false;
}
res << pPoly;
return true;
}
bool TGRegion2D::Inter(const TGRegion2D&face,TGObjectList&res) const
{
if (!IsMayBoundaryInter() && !face.IsMayBoundaryInter())
{
if (!IsOutlineExist())
{
res << face.Clone();
return true;
}
else if (!face.IsOutlineExist())
{
res << Clone();
return true;
}
else
{
TGObjectList aInB,aOutB,aOnB,bInA,bOutA,bOnA;
for (long i = 0;i<GetBoundaryNum();i++)
{
face.Clip(*GetBoundary(i),aInB,aOutB,aOnB);
}
for (i = 0;i<face.GetBoundaryNum();i++)
{
Clip(*face.GetBoundary(i),bInA,bOutA,bOnA);
}
if (bOutA.IsEmpty() && aInB.IsEmpty())
{
res << face.Clone();
return true;
}
else if (aOutB.IsEmpty() && bInA.IsEmpty())
{
res << Clone();
return true;
}
else if (aInB.IsEmpty() || bInA.IsEmpty())
{
return false;
}
else
{
TGObjectList list,buf;
list.Conbine(aInB);
list.Conbine(bInA);
list.Conbine(aOnB);
if (Outline().IsClosed() && face.Outline().IsClosed())
{
CreateRegion2D(list,res,IsHoleExist() || face.IsHoleExist());
}
else
{
CreateRegion2DEx(list,res,IsHoleExist() || face.IsHoleExist());
}
return true;
}
}
}
else if (IsHoleExist())
{
TGObjectList buf;
if (IsOutlineExist())
{
if (!TGRegionEx2D(Outline(),false).Inter(face,buf))
{
return false;
}
}
else
{
buf.AddTail(face.Clone());
}
TGObjectList holes;
for (long i = 0;i<GetHoleNum();i++)
{
holes << new TGRegionEx2D(Hole(i),false);
holes.GetCurRegion2D().Outline().Reverse();
}
TGObjectList buf1;
for (buf.MoveToFirst();!buf.IsOut();buf.MoveToNext())
{
buf.GetCurRegion2D().SubtractBy(holes,buf1);
}
if (buf1.IsEmpty())
{
return false;
}
else
{
res.Conbine(buf1);
return true;
}
}
else
{
return face.Inter(*this,res);
}
}
void TGRegion2D::SubtractBy(const TGRegion2D&face,TGObjectList&res) const
{
if (!IsMayBoundaryInter() && !face.IsMayBoundaryInter())
{
if (!IsOutlineExist())
{
if (face.IsOutlineExist())
{
TGRegionEx2D *pFace = new TGRegionEx2D;
TPGeCurve2D *pCurve = (TPGeCurve2D*)(face.Outline().Clone());
pCurve->Reverse();
pFace->AppendHole(pCurve,false);
res << pFace;
}
for (long i = 0;i<face.GetHoleNum();i++)
{
TPGeCurve2D *pCurve = (TPGeCurve2D*)(face.Hole(i).Clone());
pCurve->Reverse();
res << new TGRegionEx2D(pCurve,false);
}
}
else if (!face.IsOutlineExist())
{
return;
}
else
{
TGObjectList aInB,aOutB,aOnB,bInA,bOutA,bOnA;
for (long i = 0;i<GetBoundaryNum();i++)
{
face.Clip(*GetBoundary(i),aInB,aOutB,aOnB);
}
for (i = 0;i<face.GetBoundaryNum();i++)
{
Clip(*face.GetBoundary(i),bInA,bOutA,bOnA);
}
if (aOutB.IsEmpty() && bInA.IsEmpty())
{
return;
}
else if (bOutA.IsEmpty() && aInB.IsEmpty())
{
TGObjectList list;
bInA.ReverseCurve2D();
list.Conbine(bInA);
list.Conbine(aOutB);
list.Conbine(aOnB);
if (Outline().IsClosed() && face.Outline().IsClosed())
{
CreateRegion2D(list,res,true);
}
else
{
CreateRegion2DEx(list,res,true);
}
}
else if (aInB.IsEmpty() || bInA.IsEmpty())
{
res << Clone();
}
else
{
TGObjectList list;
bInA.ReverseCurve2D();
list.Conbine(bInA);
list.Conbine(aOutB);
list.Conbine(aOnB);
if (Outline().IsClosed() && face.Outline().IsClosed())
{
CreateRegion2D(list,res,IsHoleExist() || face.IsHoleExist());
}
else
{
CreateRegion2DEx(list,res,IsHoleExist() || face.IsHoleExist());
}
}
}
}
else if (face.IsHoleExist())
{
if (face.IsOutlineExist())
{
SubtractBy(TGRegionEx2D(face.Outline(),false),res);
}
for (long i = 0;i<face.GetHoleNum();i++)
{
TGRegionEx2D hFace(face.Hole(i),false);
hFace.Outline().Reverse();
Inter(hFace,res);
}
}
else
{
TGObjectList buf;
TGRegionEx2D region0;
if (IsOutlineExist())
{
region0.SetOutline((TPGeCurve2D*)Outline().Clone(),false);
}
region0.SubtractBy(face,buf);
if (buf.IsEmpty())
{
return;
}
TGObjectList holes;
for (long i = 0;i<GetHoleNum();i++)
{
holes << new TGRegionEx2D(Hole(i),false);
holes.GetCurRegion2D().Outline().Reverse();
}
buf.MoveToFirst();
if (buf.GetCurRegion2D().IsHoleExist())
{
holes.Union(face);
TGRegionEx2D *pRes = new TGRegionEx2D(Outline(),false);
for (holes.MoveToFirst();!holes.IsOut();holes.MoveToNext())
{
TPGeCurve2D* pCurve = (TPGeCurve2D*)(holes.GetCurRegion2D().Outline().Clone());
pCurve->Reverse();
pRes->AppendHole(pCurve,false);
}
res << pRes;
}
else
{
for (buf.MoveToFirst();!buf.IsOut();buf.MoveToNext())
{
buf.GetCurRegion2D().SubtractBy(holes,res);
}
}
}
}
TGRegion2D* TGRegion2D::Union(const TGRegion2D&face) const
{
if (!IsMayBoundaryInter() && !face.IsMayBoundaryInter())
{
if (!IsOutlineExist())
{
return (TGRegion2D*)Clone();
}
else if (!face.IsOutlineExist())
{
return (TGRegion2D*)face.Clone();
}
else
{
TGObjectList aInB,aOutB,aOnB,bInA,bOutA,bOnA;
for (long i = 0;i<GetBoundaryNum();i++)
{
face.Clip(*GetBoundary(i),aInB,aOutB,aOnB);
}
for (i = 0;i<face.GetBoundaryNum();i++)
{
Clip(*face.GetBoundary(i),bInA,bOutA,bOnA);
}
if (bOutA.IsEmpty() && aInB.IsEmpty())
{
return (TGRegion2D*)Clone();
}
else if (aOutB.IsEmpty() && bInA.IsEmpty())
{
return (TGRegion2D*)face.Clone();
}
else if (aInB.IsEmpty() || bInA.IsEmpty())
{
if (aOnB.IsEmpty())
{
return NULL;
}
else
{
TGObjectList list,res;
list.Conbine(aOutB);
list.Conbine(bOutA);
if (Outline().IsClosed() && face.Outline().IsClosed())
{
CreateRegion2D(list,res,true);
}
else
{
CreateRegion2DEx(list,res,true);
}
return (TGRegion2D*)res.Fetch(0);
}
}
else
{
TGObjectList list,res;
list.Conbine(aOutB);
list.Conbine(bOutA);
list.Conbine(aOnB);
if (Outline().IsClosed() && face.Outline().IsClosed())
{
CreateRegion2D(list,res,true);
}
else
{
CreateRegion2DEx(list,res,true);
}
return (TGRegion2D*)res.Fetch(0);
}
}
}
else if (IsHoleExist())
{
TGRegion2D *pU0;
if (IsOutlineExist())
{
pU0 = TGRegionEx2D(Outline(),false).Union(face);
if (pU0 == NULL)
{
return NULL;
}
}
else
{
pU0 = new TGRegionEx2D;
}
TGObjectList holes;
for (long i = 0;i<GetHoleNum();i++)
{
TGRegionEx2D hFace(Hole(i),false);
hFace.Outline().Reverse();
hFace.SubtractBy(face,holes);
}
if (holes.IsEmpty())
{
return pU0;
}
else
{
TGRegionEx2D*pU1;
if (IS_TYPE(pU0,TGRegionEx2D))
{
pU1 = (TGRegionEx2D*)pU0;
}
else
{
pU1 = new TGRegionEx2D(*pU0);
delete pU0;
}
for (holes.MoveToFirst();!holes.IsOut();holes.MoveToNext())
{
TGRegion2D&hHole = holes.GetCurRegion2D();
if (hHole.IsHoleExist())
{
delete pU1;
return NULL;
}
TPGeCurve2D*pCurve = (TPGeCurve2D*)hHole.Outline().Clone();
pCurve->Reverse();
pU1->AppendHole(pCurve,false);
}
return pU1;
}
}
else
{
return face.Union(*this);
}
}
void TGRegion2D::CutBy(const TPGeCurve2D&curve,TGObjectList&left,TGObjectList&right) const
{
if (IsMayBoundaryInter())
{
TGObjectList lBuf,rBuf;
TGRegionEx2D region0;
if (IsOutlineExist())
{
region0.SetOutline((TPGeCurve2D*)Outline().Clone(),false);
}
region0.CutBy(curve,lBuf,rBuf);
if (lBuf.IsEmpty())
{
right << Clone();
}
else if (rBuf.IsEmpty())
{
left << Clone();
}
else
{
TGObjectList lHole,rHole;
for (long i = 0;i<GetHoleNum();i++)
{
TGRegionEx2D hFace(Hole(i),false);
hFace.Outline().Reverse();
hFace.CutBy(curve,lHole,rHole);
}
for (lBuf.MoveToFirst();!lBuf.IsOut();lBuf.MoveToNext())
{
lBuf.GetCurRegion2D().SubtractBy(lHole,left);
}
for (rBuf.MoveToFirst();!rBuf.IsOut();rBuf.MoveToNext())
{
rBuf.GetCurRegion2D().SubtractBy(rHole,right);
}
}
}
else if (!IsOutlineExist())
{
TGRegionEx2D *pLeft = new TGRegionEx2D(curve,false);
left << pLeft;
TPGeCurve2D *pCurve = (TPGeCurve2D*)curve.Clone();
pCurve->Reverse();
TGRegionEx2D *pRight = new TGRegionEx2D(pCurve,false);
right << pRight;
}
else
{
TGObjectList aInB,aOutB,aOnB,bInA,bOutA,bOnA;
for (long i = 0;i<GetBoundaryNum();i++)
{
curve.Cut(*GetBoundary(i),bInA,bOutA,bOnA);
}
Clip(curve,aInB,aOutB,aOnB);
if (bOutA.IsEmpty() && aInB.IsEmpty())
{
left << Clone();
}
else if (curve.IsClosed() && aOutB.IsEmpty() && bInA.IsEmpty())
{
bool bClockwise = curve.IsClockwise();
TPGeCurve2D*pNewCurve = (TPGeCurve2D*)curve.Clone();
if (bClockwise)
{
pNewCurve->Reverse();
}
left << new TGRegionEx2D(pNewCurve,false);
TGObjectList rList;
if (!bClockwise)
{
aInB.ReverseCurve2D();
}
rList.Conbine(aInB);
rList.Conbine(bOutA);
rList.Conbine(bOnA);
if (Outline().IsClosed())
{
CreateRegion2D(rList,right,true);
}
else
{
CreateRegion2DEx(rList,right,true);
}
}
else if (aInB.IsEmpty() || bInA.IsEmpty())
{
right << Clone();
}
else
{
bool bFinite = Outline().IsClosed();
TGObjectList lList,temp(aInB);
bool bClockwise = curve.IsClosed() && curve.IsClockwise();
if (bClockwise)
{
temp.ReverseCurve2D();
aOnB.ReverseCurve2D();
}
lList.Conbine(temp);
lList.Conbine(bInA);
lList.Conbine(aOnB);
if (bFinite)
{
CreateRegion2D(lList,left,IsHoleExist());
}
else
{
CreateRegion2DEx(lList,left,IsHoleExist());
}
TGObjectList rList;
if (!bClockwise)
{
aInB.ReverseCurve2D();
}
rList.Conbine(aInB);
rList.Conbine(bOutA);
rList.Conbine(bOnA);
if (bFinite)
{
CreateRegion2D(rList,right,IsHoleExist());
}
else
{
CreateRegion2DEx(rList,right,IsHoleExist());
}
}
}
}
TPGeCurve2D* TGRegion2D::GetBoundary(long i) const
{
return NULL;
}
long TGRegion2D::GetBoundaryNum() const
{
return 1;
}
bool TGRegion2D::IsOutlineExist() const
{
return GetBoundary(0) != NULL;
}
TPGeCurve2D& TGRegion2D::Outline() const
{
return *GetBoundary(0);
}
long TGRegion2D::GetHoleNum() const
{
return GetBoundaryNum()-1;
}
bool TGRegion2D::IsHoleExist() const
{
return GetBoundaryNum()>1;
}
TPGeCurve2D& TGRegion2D::Hole(long i) const
{
return *GetBoundary(i+1);
}
bool TGRegion2D::IsClosed() const
{
return IsOutlineExist() && Outline().IsClosed();
}
bool TGRegion2D::IsAllowBoundaryInter() const
{
return IsNot(NO_BOUNDARY_INTER);
}
bool TGRegion2D::IsMayBoundaryInter() const
{
return IsHoleExist() && (IsAllowBoundaryInter() || !IsClosed());
}
bool TGRegion2D::IsEntirePlane() const
{
return !IsHoleExist() && !IsOutlineExist();
}
void TGRegion2D::CreateRegion2D(TGObjectList &curves,TGObjectList &res,bool bCheckHole)const
{
TGObjectList closeCurves;
for (curves.MoveToFirst(); !curves.IsOut(); curves.MoveToNext())
{
TPGeCurve2D* pCurve = (TPGeCurve2D*)curves.GetCurData();
if (pCurve->IsClosed())
{
closeCurves << curves.FetchCur();
}
else if (!pCurve->IsCurveSeg())
{
curves.DelCur();
}
}
TPGeGraph g;
g.AppendEdge(curves);
g.FindCurve(closeCurves,closeCurves);
if (closeCurves.GetLength() == 1 || !bCheckHole)
{
for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext())
{
res << new TGRegionEx2D((TPGeCurve2D*)closeCurves.FetchCur(),false);
}
}
else
{
TList<TGRegionEx2D*> face;
for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext())
{
TPGeCurve2D* pCurve = (TPGeCurve2D*)closeCurves.GetCurData();
if (!pCurve->IsClockwise())
{
closeCurves.FetchCur();
TGRegionEx2D* pFace = new TGRegionEx2D(pCurve,false);
face << pFace;
res << pFace;
}
}
if (face.GetLength() == 1)
{
TGRegionEx2D *pFace = face.GetAt(0);
for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext())
{
pFace->AppendHole((TPGeCurve2D*)closeCurves.FetchCur(),false);
}
}
else
{
for (face.MoveToFirst(); !face.IsOut(); face.MoveToNext())
{
TGRegionEx2D *pFace = face.GetCurData();
TPGeCurve2D&outline = pFace->Outline();
for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext())
{
GRelation r = outline.HitTest(closeCurves.GetCurPData().GetSamplePoint());
if (r.Is(GR_INSIDE))
{
pFace->AppendHole((TPGeCurve2D*)closeCurves.FetchCur(),false);
}
}
}
}
}
}
void TGRegion2D::CreateRegion2DEx(TGObjectList &curves,TGObjectList &res,bool bCheckHole)const
{
TGObjectList closeCurves,infiniteCurves;
for (curves.MoveToFirst(); !curves.IsOut(); curves.MoveToNext())
{
TPGeCurve2D* pCurve = (TPGeCurve2D*)curves.GetCurData();
if (pCurve->IsClosed())
{
closeCurves << curves.FetchCur();
}
else if (!pCurve->IsFinite(true) && !pCurve->IsFinite(false))
{
infiniteCurves << curves.FetchCur();
}
}
TPGeGraph g;
g.AppendEdge(curves);
g.FindCurve(closeCurves,infiniteCurves);
TList<TGRegionEx2D*> face;
if (infiniteCurves.GetLength() == 2)
{
TPGeCurve2D *pCurve0 = (TPGeCurve2D*)infiniteCurves.Fetch(0);
TPGeCurve2D *pCurve1 = (TPGeCurve2D*)infiniteCurves.Fetch(0);
if (pCurve0->HitTest(pCurve1->GetSamplePoint()).Is(GR_RIGHT)
&& pCurve1->HitTest(pCurve0->GetSamplePoint()).Is(GR_RIGHT))
{
TGRegionEx2D* pRegion0 = new TGRegionEx2D(pCurve0,false);
TGRegionEx2D* pRegion1 = new TGRegionEx2D(pCurve1,false);
res << pRegion0 << pRegion1;
face << pRegion0 << pRegion1;
}
else
{
TGRegionEx2D *pRegion = new TGRegionEx2D(pCurve0,false);
pRegion->AppendHole(pCurve1,false);
res << pRegion;
face << pRegion;
}
}
else if (infiniteCurves.GetLength() == 1)
{
TGRegionEx2D *pRegion = new TGRegionEx2D((TPGeCurve2D*)infiniteCurves.Fetch(0),false);
res << pRegion;
face << pRegion;
}
if (!bCheckHole)
{
for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext())
{
res << new TGRegionEx2D((TPGeCurve2D*)closeCurves.FetchCur(),false);
}
}
else
{
for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext())
{
TPGeCurve2D* pCurve = (TPGeCurve2D*)closeCurves.GetCurData();
if (!pCurve->IsClockwise())
{
closeCurves.FetchCur();
TGRegionEx2D* pRegion = new TGRegionEx2D(pCurve,false);
face << pRegion;
res << pRegion;
}
}
if (face.IsEmpty() && !closeCurves.IsEmpty())
{
TGRegionEx2D *pRegion = new TGRegionEx2D;
face << pRegion;
res << pRegion;
}
if (face.GetLength() == 1)
{
TGRegionEx2D *pFace = face.GetAt(0);
for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext())
{
pFace->AppendHole((TPGeCurve2D*)closeCurves.FetchCur(),false);
}
}
else
{
for (face.MoveToFirst(); !face.IsOut(); face.MoveToNext())
{
TGRegionEx2D *pFace = face.GetCurData();
TPGeCurve2D&outline = pFace->Outline();
for (closeCurves.MoveToFirst(); !closeCurves.IsOut(); closeCurves.MoveToNext())
{
GRelation r = outline.HitTest(closeCurves.GetCurPData().GetSamplePoint());
if (r.Is(GR_INSIDE))
{
pFace->AppendHole((TPGeCurve2D*)closeCurves.FetchCur(),false);
}
}
}
}
}
}