685 lines
14 KiB
C++
685 lines
14 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : 内部全局函数实现文件
|
|
// = Version : ver2.0
|
|
// = Author : tg
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: 全局函数的声明
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TchSubPrivateGlobalFunc.h"
|
|
#include "TGPoint2D.h"
|
|
#include "TPGeGLine2D.h"
|
|
#include "TPGeGLineRay2D.h"
|
|
#include "TPGeGLineSeg2D.h"
|
|
#include "TPGeCircle2D.h"
|
|
#include "TPGeArc2D.h"
|
|
#include "TGMLine2D.h"
|
|
#include "TGPLine2D.h"
|
|
#include "TGMCurve2D.h"
|
|
#include "TGPolygon2D.h"
|
|
#include "TGPolygonEx2D.h"
|
|
#include "TGRegionEx2D.h"
|
|
#include "TGPoint3D.h"
|
|
#include "TPGeGLine3D.h"
|
|
#include "TPGeGLineRay3D.h"
|
|
#include "TPGeGLineSeg3D.h"
|
|
#include "TGPCurve3D.h"
|
|
#include "TGMLine3D.h"
|
|
#include "TGMCurve3D.h"
|
|
#include "TGPlane3D.h"
|
|
#include "TPGeGraph.h"
|
|
|
|
double TchSubPrivate::GetAngle(const TPGeDscEdge &e0,const TPGeDscEdge &e1)
|
|
{
|
|
TPGeDscPoint *pPt,*pPt0,*pPt1;
|
|
if (e0.pPt0 == e1.pPt0)
|
|
{
|
|
pPt = e0.pPt0;
|
|
pPt0 = e0.pPt1;
|
|
pPt1 = e1.pPt1;
|
|
}
|
|
else if (e0.pPt0 == e1.pPt1)
|
|
{
|
|
pPt = e0.pPt0;
|
|
pPt0 = e0.pPt1;
|
|
pPt1 = e1.pPt0;
|
|
}
|
|
else if (e0.pPt1 == e1.pPt1)
|
|
{
|
|
pPt = e0.pPt1;
|
|
pPt0 = e0.pPt0;
|
|
pPt1 = e1.pPt0;
|
|
}
|
|
else
|
|
{
|
|
pPt = e0.pPt1;
|
|
pPt0 = e0.pPt0;
|
|
pPt1 = e1.pPt1;
|
|
}
|
|
|
|
TGVector2D vt0(*pPt,*pPt0),vt1(*pPt,*pPt1);
|
|
return vt1.GetAngleWith(vt0);
|
|
}
|
|
|
|
int TchSubPrivate::CompareEdge(const TPGeDscEdge &e0, const TPGeDscEdge &e1)
|
|
{
|
|
TPGeDscPoint *pPt,*pPt0,*pPt1;
|
|
if (e0.pPt0 == e1.pPt0)
|
|
{
|
|
pPt = e0.pPt0;
|
|
pPt0 = e0.pPt1;
|
|
pPt1 = e1.pPt1;
|
|
}
|
|
else if (e0.pPt0 == e1.pPt1)
|
|
{
|
|
pPt = e0.pPt0;
|
|
pPt0 = e0.pPt1;
|
|
pPt1 = e1.pPt0;
|
|
}
|
|
else if (e0.pPt1 == e1.pPt1)
|
|
{
|
|
pPt = e0.pPt1;
|
|
pPt0 = e0.pPt0;
|
|
pPt1 = e1.pPt0;
|
|
}
|
|
else
|
|
{
|
|
pPt = e0.pPt1;
|
|
pPt0 = e0.pPt0;
|
|
pPt1 = e1.pPt1;
|
|
}
|
|
|
|
TGVector2D vt0(*pPt,*pPt0), vt1(*pPt,*pPt1);
|
|
|
|
return vt0.GetAngle() > vt1.GetAngle();
|
|
}
|
|
|
|
int TchSubPrivate::LineInt2D(const TGPoint&pt1,const TGVector2D&vt1, const TGPoint&pt2,const TGVector2D&vt2, double&pa1)
|
|
{
|
|
TGVector2D vt3(pt2,pt1);
|
|
double A = vt1 * vt2,B = vt2 * vt3,C = vt1 * vt3;
|
|
if (EQUAL_ZERO(A))
|
|
{
|
|
double D = (fabs(B) + fabs(C)) / 2.0;
|
|
return EQUAL_ZEROD(D) ? INT_LINE : INT_NULL;
|
|
}
|
|
|
|
pa1 = B / A;
|
|
return INT_1PT;
|
|
}
|
|
|
|
int TchSubPrivate::LineInt2D(const TGPoint &pt1,const TGVector2D &vt1, const TGPoint &pt2,const TGVector2D &vt2, double &pa1,double &pa2)
|
|
{
|
|
TGVector2D vt3(pt2,pt1);
|
|
double A = vt1 * vt2,B = vt2 * vt3,C = vt1 * vt3;
|
|
if (EQUAL_ZERO(A))
|
|
{
|
|
double D = (fabs(B) + fabs(C)) / 2.0;
|
|
return EQUAL_ZEROD(D) ? INT_LINE : INT_NULL;
|
|
}
|
|
|
|
pa1 = B / A;
|
|
pa2 = C / A;
|
|
return INT_1PT;
|
|
}
|
|
|
|
int TchSubPrivate::LineCirInt2D(const TGPoint ¢er,double r, const TGPoint &pt,const TGVector2D &vt, TGPoint &pt1,TGPoint &pt2)
|
|
{
|
|
double x0 = pt.x - center.x;
|
|
double y0 = pt.y - center.y;
|
|
const double &a = vt.x;
|
|
const double &b = vt.y;
|
|
double B = 2 * (a * x0 + b * y0);
|
|
double t = -B / 2;
|
|
pt1.x = pt.x + vt.x * t;
|
|
pt1.y = pt.y + vt.y * t;
|
|
pt1.z = pt.z;
|
|
|
|
double d = Distance2D(pt1,center) - r;
|
|
if (EQUAL_ZEROD(d))
|
|
{
|
|
return INT_1PT;
|
|
}
|
|
|
|
double C = x0 * x0 + y0 * y0 - r * r;
|
|
double D = (B * B - 4 * C) / 4;
|
|
if (DOWN_ZERO(D))
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
else if (UP_ZERO(D))
|
|
{
|
|
double delt = sqrt(D);
|
|
if (UP_ZERO(delt))
|
|
{
|
|
double t1 = t - delt,t2 = t + delt;
|
|
pt1.x = pt.x + vt.x * t1;
|
|
pt1.y = pt.y + vt.y * t1;
|
|
pt1.z = pt.z;
|
|
pt2.x = pt.x + vt.x * t2;
|
|
pt2.y = pt.y + vt.y * t2;
|
|
pt2.z = pt.z;
|
|
return INT_2PT;
|
|
}
|
|
}
|
|
|
|
return INT_1PT;
|
|
}
|
|
|
|
int TchSubPrivate::LineCirInt2D(const TGPoint ¢er,double r, const TGPoint &pt,const TGVector2D &vt, double &pa1,double &pa2)
|
|
{
|
|
double x0 = pt.x - center.x;
|
|
double y0 = pt.y - center.y;
|
|
const double &a = vt.x,&b = vt.y;
|
|
double B = 2 * (a * x0 + b * y0);
|
|
pa1 = -B / 2;
|
|
|
|
double d = Distance2D(TGPoint(pt.x + vt.x * pa1,pt.y + vt.y * pa1),center) - r;
|
|
if (EQUAL_ZEROD(d))
|
|
{
|
|
return INT_1PT;
|
|
}
|
|
|
|
double C = x0 * x0 + y0 * y0 - r * r;
|
|
double D = (B * B - 4 * C) / 4;
|
|
if (DOWN_ZERO(D))
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
else if (UP_ZERO(D))
|
|
{
|
|
double delt = sqrt(D);
|
|
if (UP_ZERO(delt))
|
|
{
|
|
pa2 = pa1 + delt;
|
|
pa1 = pa1 - delt;
|
|
return INT_2PT;
|
|
}
|
|
}
|
|
|
|
return INT_1PT;
|
|
}
|
|
|
|
bool TchSubPrivate::LB_IsOk(const double &dn,const double &nw,double &tl,double &tu)
|
|
{
|
|
if (UP_ZERO(dn))
|
|
{
|
|
double t = nw / dn;
|
|
if (t > tu)
|
|
{
|
|
return false;
|
|
}
|
|
else if (t > tl)
|
|
{
|
|
tl = t;
|
|
}
|
|
}
|
|
else if (DOWN_ZERO(dn))
|
|
{
|
|
double t = nw / dn;
|
|
if (t < tl)
|
|
{
|
|
return false;
|
|
}
|
|
else if (t < tu)
|
|
{
|
|
tu = t;
|
|
}
|
|
}
|
|
else if (UP_ZERO(nw))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void TchSubPrivate::InitCircle2D(const TGPoint &pt0,const TGPoint &pt1,const TGPoint &pt2,TGPoint ¢er,double &r)
|
|
{
|
|
double pa;
|
|
TGVector2D vt0,vt1;
|
|
TGVector2D(pt0,pt1).GetLVertVector(vt0);
|
|
vt0.Normalize();
|
|
|
|
TGVector2D(pt1,pt2).GetLVertVector(vt1);
|
|
vt1.Normalize();
|
|
|
|
TGPoint pt00((pt0.x + pt1.x) / 2,(pt0.y + pt1.y) / 2),pt11((pt1.x + pt2.x) / 2,(pt1.y + pt2.y) / 2);
|
|
TchSubPrivate::LineInt2D(pt00,vt0,pt11,vt1,pa);
|
|
TchSubPrivate::LinePt2D(pt0,vt0,pa,center);
|
|
|
|
r = Distance2D(center,pt0);
|
|
}
|
|
|
|
void TchSubPrivate::InitCircle2D(const TGPoint &pt0,const TGPoint &pt1,double angle,TGPoint ¢er,double &r)
|
|
{
|
|
double len = Distance2D(pt0,pt1);
|
|
r = fabs(len / (2 * sin(angle / 2)));
|
|
|
|
TGVector2D vt0(pt0,pt1),vt;
|
|
vt0.GetLVertVector(vt);
|
|
vt.SetLength(fabs(r * cos(angle / 2)));
|
|
center.x = (pt0.x + pt1.x) / 2;
|
|
center.y = (pt0.y + pt1.y) / 2;
|
|
center.z = pt0.z;
|
|
|
|
if ((UP_ZEROA(angle) && (DOWN_ZEROA(angle - PI))) || DOWN_ZEROA(angle + PI))
|
|
{
|
|
center.x += vt.x;
|
|
center.y += vt.y;
|
|
}
|
|
else if ((DOWN_ZEROA(angle) && UP_ZEROA(angle + PI)) || UP_ZEROA(angle - PI))
|
|
{
|
|
center.x -= vt.x;
|
|
center.y -= vt.y;
|
|
}
|
|
}
|
|
|
|
int TchSubPrivate::CircleInt(const TGPoint ¢er1,double r1,
|
|
const TGPoint ¢er2,double r2,
|
|
TGPoint &pt1,TGPoint &pt2)
|
|
{
|
|
TGVector2D vt(center1,center2);
|
|
if (vt.IsNullVector())
|
|
{
|
|
double temp = r1 - r2;
|
|
if (EQUAL_ZEROD(temp))
|
|
{
|
|
return INT_CIRCLE;
|
|
}
|
|
else
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
double dist = vt.Length();
|
|
double dist1 = dist - fabs(r1 - r2);
|
|
if (DOWN_ZEROD(dist1))
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
|
|
double dist2 = dist - r1 - r2;
|
|
if (UP_ZEROD(dist2))
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
|
|
if (EQUAL_ZEROD(dist1))
|
|
{
|
|
vt *= r1 > r2 ? (r1 / dist) : (-r1 / dist);
|
|
pt1.x = center1.x + vt.x;
|
|
pt1.y = center1.y + vt.y;
|
|
pt1.z = center1.z;
|
|
return INT_1PT;
|
|
}
|
|
|
|
if (EQUAL_ZEROD(dist2))
|
|
{
|
|
vt *= (r1 / dist);
|
|
pt1.x = center1.x + vt.x;
|
|
pt1.y = center1.y + vt.y;
|
|
pt1.z = center1.z;
|
|
return INT_1PT;
|
|
}
|
|
|
|
double r12 = r1 * r1, r22 = r2 * r2, d2 = dist * dist;
|
|
if (r1 >= r2)
|
|
{
|
|
double cos = (r12 + d2 - r22) / (2 * r1 * dist);
|
|
double sin = sqrt(1 - cos * cos);
|
|
|
|
TGVector2D vt1;
|
|
vt.GetLVertVector(vt1);
|
|
vt.SetLength(r1 * cos);
|
|
vt1.SetLength(r1 * sin);
|
|
|
|
pt1.x = center1.x + vt.x + vt1.x;
|
|
pt1.y = center1.y + vt.y + vt1.y;
|
|
pt2.x = center1.x + vt.x - vt1.x;
|
|
pt2.y = center1.y + vt.y - vt1.y;
|
|
}
|
|
else
|
|
{
|
|
double cos = (r22 + d2 - r12) / (2 * r2 * dist);
|
|
double sin = sqrt(1 - cos * cos);
|
|
|
|
TGVector2D vt1;
|
|
vt.Reverse();
|
|
vt.GetLVertVector(vt1);
|
|
vt.SetLength(r2 * cos);
|
|
vt1.SetLength(r2 * sin);
|
|
|
|
pt1.x = center2.x + vt.x + vt1.x;
|
|
pt1.y = center2.y + vt.y + vt1.y;
|
|
pt2.x = center2.x + vt.x - vt1.x;
|
|
pt2.y = center2.y + vt.y - vt1.y;
|
|
}
|
|
|
|
pt1.z = center1.z;
|
|
pt2.z = center1.z;
|
|
return INT_2PT;
|
|
}
|
|
}
|
|
|
|
int TchSubPrivate::LineInt3D(const TGPoint &pt1,const TGVector3D &vt1,
|
|
const TGPoint &pt2,const TGVector3D &vt2,
|
|
double &pa1)
|
|
{
|
|
TGVector3D vt3(pt1,pt2);
|
|
vt3.Normalize();
|
|
|
|
if (!(vt1 * vt3).IsParallel(vt2 * vt3,true))
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
|
|
double temp = (vt2.y * vt1.x - vt2.x * vt1.y);
|
|
if (!EQUAL_ZERO(temp))
|
|
{
|
|
pa1 = (vt2.y * pt2.x - vt2.y * pt1.x - vt2.x * pt2.y + vt2.x * pt1.y) / temp;
|
|
return INT_1PT;
|
|
}
|
|
|
|
temp = (vt2.z * vt1.x - vt2.x * vt1.z);
|
|
if (!EQUAL_ZERO(temp))
|
|
{
|
|
pa1 = (vt2.z * pt2.x - vt2.z * pt1.x - vt2.x * pt2.z + vt2.x * pt1.z) / temp;
|
|
return INT_1PT;
|
|
}
|
|
|
|
temp = (vt2.y * vt1.z - vt2.z * vt1.y);
|
|
if (!EQUAL_ZERO(temp))
|
|
{
|
|
pa1 = (vt2.y * pt2.z - vt2.y * pt1.z - vt2.z * pt2.y + vt2.z * pt1.y) / temp;
|
|
return INT_1PT;
|
|
}
|
|
|
|
if (vt1.IsParallel(vt3,true))
|
|
{
|
|
return INT_LINE;
|
|
}
|
|
else
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
}
|
|
|
|
int TchSubPrivate::LinePlaneInt3D(double A,double B,double C,double D,
|
|
const TGPoint &pt0,const TGVector3D &vt,
|
|
double &pa)
|
|
{
|
|
TGVector3D vt1(A,B,C);
|
|
double n1 = vt1 & vt;
|
|
double n2 = -D - (vt1 & pt0);
|
|
if (EQUAL_ZERO(n1))
|
|
{
|
|
if (EQUAL_ZERO(n2))
|
|
{
|
|
return INT_LINE;
|
|
}
|
|
else
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
}
|
|
|
|
pa = n2 / n1;
|
|
return INT_1PT;
|
|
}
|
|
|
|
int TchSubPrivate::LinePlaneInt3D(double A,double B,double C,double D,
|
|
const TGPoint &pt0,const TGVector3D &vt, TGPoint &pt)
|
|
{
|
|
TGVector3D vt1(A,B,C);
|
|
double n1 = vt1 & vt;
|
|
double n2 = -D - (vt1 & pt0);
|
|
if (EQUAL_ZERO(n1))
|
|
{
|
|
if (EQUAL_ZERO(n2))
|
|
{
|
|
return INT_LINE;
|
|
}
|
|
else
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
}
|
|
|
|
double pa = n2 / n1;
|
|
pt.x = pt0.x + vt.x * pa;
|
|
pt.y = pt0.y + vt.y * pa;
|
|
pt.z = pt0.z + vt.z * pa;
|
|
|
|
return INT_1PT;
|
|
}
|
|
|
|
int TchSubPrivate::PlaneInt(double A1,double B1,double C1,double D1, double A2,double B2,double C2,double D2, TGPoint &pt,TGVector3D &vt)
|
|
{
|
|
double A3 = B1 * C2 - C1 * B2,B3 = C1 * A2 - A1 * C2,C3 = A1 * B2 - B1 * A2;
|
|
if (EQUAL_ZERO(A3) && EQUAL_ZERO(B3) && EQUAL_ZERO(C3))
|
|
{
|
|
double temp = A1 * D2 - A2 * D1;
|
|
if (EQUAL_ZERO(temp))
|
|
{
|
|
return INT_PLANE;
|
|
}
|
|
else
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
}
|
|
|
|
vt.x = A3;
|
|
vt.y = B3;
|
|
vt.z = C3;
|
|
|
|
if (!EQUAL_ZERO(C3))
|
|
{
|
|
pt.z = 0;
|
|
pt.x = (B1 * D2 - B2 * D1) / C3;
|
|
pt.y = (-A1 * D2 + A2 * D1) / C3;
|
|
}
|
|
else if (!EQUAL_ZERO(B3))
|
|
{
|
|
pt.y = 0;
|
|
pt.x = (-C1 * D2 + C2 * D1) / B3;
|
|
pt.z = (A1 * D2 - A2 * D1) / B3;
|
|
}
|
|
else if (!EQUAL_ZERO(A3))
|
|
{
|
|
pt.x = 0;
|
|
pt.z = (-B1 * D2 + B2 * D1) / A3;
|
|
pt.y = (C1 * D2 - C2 * D1) / A3;
|
|
}
|
|
else
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
|
|
vt.Normalize();
|
|
return INT_LINE;
|
|
}
|
|
void TchSubPrivate::CreateRegion2D(TGObjectList &curves,TGObjectList &res,bool bCheckHole)
|
|
{
|
|
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 TchSubPrivate::CreateRegion2DEx(TGObjectList &curves,TGObjectList &res,bool bCheckHole)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|