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

1899 lines
35 KiB
C++

//-----------------------------------------------------------------------------+
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
// = FileName : TGGePoly2D 类
// = Version : ver2.0
// = Author : wlw
// = CreateDate : 2002-09-09
// = Description: TGGePoly2D 类定义
// = Maintainers:
//
//-----------------------------------------------------------------------------+
#include "StdAfx.h"
#include "TGGePoly2D.h"
#include "TADSGePointList.h"
#include "dbregion.h"
#include "TPushPrec.h"
#include "TAcDbObjectPtr.h"
#include "TGGePoly3D.h"
//#include "TGGeDirectionCurve.h"
#include "TList.h"
#include "TGGePolygonEx.h"
#include "TPointList.h"
#include "TchGlobalFunc.h"
#include "TchPrivateGlobalFunc.h"
#include "TchGlobalCurveFunc.h"
#include "geblok3d.h"
#include "geblok2d.h"
#include "TGGeCurveInline.h"
TGGePoly2D::TGGePoly2D()
: m_nFlag(0)
{
m_ardbulges.Reset();
}
TGGePoly2D::TGGePoly2D(const TEntitySet& ent)
{
TEntitySet entPLine = ent;
TCString sEntType;
TADSGePoint3d pt;
double dTAng = 0.0, dAng = 0.0;
entPLine.GetData(0, (TCHAR *)sEntType);
if (sEntType == _T("CIRCLE"))
{
TGGeCurveSegment cir(ent);
cir.AsPoly2D(*this);
return;
}
else if (sEntType == _T("LINE") || sEntType == _T("ARC"))
{
TGGeCurveSegment segTemp(ent);
if (!segTemp)
{
return;
}
segTemp.AsPoly2D(*this);
}
if ((sEntType != _T("POLYLINE") && sEntType != _T("LWPOLYLINE"))
|| entPLine.GetData(70, &m_nFlag) != RTNORM)
{
return;
}
int nFlag = m_nFlag;
if ((nFlag & 2) || (nFlag & 4) || (nFlag & 16) || (nFlag & 32) || (nFlag & 64))
{
return;
}
if (sEntType == _T("POLYLINE"))
{
OPENOBJ_BEGIN(entPLine, AcDb::kForRead, AcDb3dPolyline, pLine);
if (pLine != NULL)
{
AcDbObjectIterator* pIter = pLine->vertexIterator();
if (pIter != NULL)
{
for (pIter->start(); !pIter->done(); pIter->step())
{
AcDb3dPolylineVertex *pVertex = NULL;
acdbOpenObject(pVertex, pIter->objectId(), AcDb::kForRead);
if (pVertex != NULL)
{
if (pVertex->vertexType() == AcDb::k3dSimpleVertex)
{
m_ardbulges.Append(new double(0.0));
Append(new TADSGePoint3d(pVertex->position()));
}
pVertex->close();
}
}
delete pIter;
}
return;
}
OPENOBJ_END();
TEntitySet subEnt = entPLine;
while ( 1 )
{
TEntitySet sub_ent;
if (ads_entnext(subEnt, sub_ent) != RTNORM)
{
break;
}
subEnt = sub_ent;
subEnt.FreeGroups();
if (!subEnt.Is(_T("VERTEX")))
{
break;
}
subEnt.GetData(10, pt);
subEnt.GetData(42, &dTAng);
if (fabs(dTAng) < 1E-6)
{
m_ardbulges.Append(new double(0.0));
}
else
{
dAng = atan(dTAng) * 4.0;
m_ardbulges.Append(new double(dAng));
}
Append(new TADSGePoint3d(pt));
}
}
else
{
double dElevation = 0.0;
entPLine.GetData(38, &dElevation);
resbuf *ebuf = (resbuf *)(entPLine.groups);
if (!ebuf)
{
TchGeLib::adsout << _T("\nResbuf error");
}
while(ebuf)
{
resbuf *rb1 = GetResbufAtCode(ebuf, 10);
resbuf *rb2 = rb1 ? GetResbufAtCode(rb1, 42) : NULL;
if (rb1 && rb2)
{
dTAng = rb2->resval.rreal;
pt = rb1->resval.rpoint;
if (fabs(dTAng) < 1E-6)
{
m_ardbulges.Append(new double(0.0));
}
else
{
dAng = atan(dTAng) * 4.0;
m_ardbulges.Append(new double(dAng));
}
pt.z = dElevation;
Append(new TADSGePoint3d(pt));
ebuf = rb2->rbnext;
}
else
{
break;
}
}
}
}
TGGePoly2D::TGGePoly2D(int nflg)
: m_nFlag(nflg)
{
m_ardbulges.Reset();
}
TGGePoly2D::TGGePoly2D(const TGGePoly2D &src)
{
TADSGePointList::copyFrom(src);
m_ardbulges.Reset();
m_ardbulges.copyFrom( src.m_ardbulges );
m_nFlag = src.GetFlag();
}
TGGePoly2D::~TGGePoly2D()
{
}
void TGGePoly2D::CopyFrom(const TGGeEntity* pSrc)
{
if (this != pSrc && pSrc->IsKindOf(TGGeEntity::ePoly2D))
{
m_nFlag = ((TGGePoly2D*)pSrc)->m_nFlag;
copyFrom(*((TGGePoly2D*)pSrc));
m_ardbulges.copyFrom(((TGGePoly2D*)pSrc)->m_ardbulges);
}
}
int TGGePoly2D::operator !() const
{
return (Length() < 2 ? 1 : 0);
}
TGGePoly2D& TGGePoly2D::operator = (const TGGePoly2D &src)
{
if (this != &src)
{
Reset();
m_nFlag = src.m_nFlag;
for(int i = 0; i < src.Length(); i++)
{
const TADSGePoint3d &pt = src[i];
double val = src.m_ardbulges[i];
Append(new TADSGePoint3d(pt));
m_ardbulges.Append(new ads_real(val));
}
}
return *this;
}
int TGGePoly2D::IsValid(int nIndex) const
{
int nLen = Length();
if (nIndex < 0 || nIndex >= nLen)
{
return 0;
}
if (!(m_nFlag & 1) && nIndex == nLen - 1)
{
return 0;
}
return 1;
}
int TGGePoly2D::IsClosed() const
{
return ((m_nFlag & 0x01) ? 1 : 0);
}
bool TGGePoly2D::SetClosed()
{
if (Length() > 2)
{
m_nFlag = 1;
return true;
}
return false;
}
int TGGePoly2D::TotalSegments() const
{
int nLen = Length();
return (m_nFlag & 1) ? nLen : nLen - 1;
}
double TGGePoly2D::Area() const
{
return fabs(PathArea());
}
double TGGePoly2D::GetLength()const
{
double dLength = 0.0;
for (int i = 0; i < TotalSegments(); i++)
{
TGGeCurveSegment seg;
Nth(i, seg);
dLength += seg.GetLength();
}
return dLength;
}
void TGGePoly2D::Reset()
{
TDPtrList<TADSGePoint3d>::Reset();
m_ardbulges.Reset();
}
resbuf* TGGePoly2D::Fence(int nCirDiv)
{
TGGePoly pts;
if (MapToPolygon(pts, nCirDiv) == RTNORM)
{
return (IsClosed() ? pts.Fence() : pts.Polygon());
}
return NULL;
}
resbuf* TGGePoly2D::Polygon(int nCirDiv)
{
TGGePoly pts;
if (MapToPolygon(pts, nCirDiv) == RTNORM)
{
return pts.Polygon();
}
return NULL;
}
void TGGePoly2D::AppendNode(const TADSGePoint3d &pt, ads_real dBulge, AcDb::Visibility eVal)
{
assert(Length() == m_ardbulges.Length());
Append(new TADSGePoint3d(pt));
m_ardbulges.Append(new double(dBulge));
}
void TGGePoly2D::InsertNodeAt(int nIndex, const TADSGePoint3d &pt, double dBulge, AcDb::Visibility eVal)
{
if (nIndex >= Length())
{
AppendNode(pt, dBulge);
}
else
{
(*this)[nIndex];
Insert(new TADSGePoint3d(pt));
m_ardbulges[nIndex];
m_ardbulges.Insert(new double(dBulge));
}
}
void TGGePoly2D::InsertNodeAt(const TADSGePoint3d &pt, AcDb::Visibility eVal)
{
}
void TGGePoly2D::RemoveNode(long nIndex)
{
Remove(nIndex);
m_ardbulges.Remove(nIndex);
}
void TGGePoly2D::TransformBy(const AcGeMatrix3d &mat)
{
//lfy 2010-08-31 修改
BOOL bIsMirror = IsMirrorMatrix(mat);
for (int i = 0; i < Length(); i++)
{
TADSGePoint3d *pt = (*this)[i];
pt->TransformBy(mat);
// lfy 2010-08-31 修改,减少循环
if (bIsMirror)
{
*m_ardbulges[i] = -*(m_ardbulges[i]);
}
}
/*
if (IsMirrorMatrix(mat))
{
for (int m = 0; m < Length(); m++)
{
*m_ardbulges[m] = -*(m_ardbulges[m]);
}
}*/
}
TADSGePoint3d TGGePoly2D::GetPoint(int nIOFlag, ads_real dDist)
{
TADSGePoint3d ptPick;
TGGeCurveSegment curve;
if (Nth(0, curve) != RTNORM)
{
return ptPick;
}
if (nIOFlag == 0)
{
ptPick = curve.Offset(PathArea() > 0 ? OFFSET_RIGHT : OFFSET_LEFT, dDist, LS_FINITE).MidPoint();
}
else
{
ptPick = curve.Offset(PathArea() > 0 ? OFFSET_LEFT : OFFSET_RIGHT, dDist, LS_FINITE).MidPoint();
}
return ptPick;
}
TADSGePoint3d TGGePoly2D::GetInsidePoint()
{
assert(Length());
TGGePoly polyTemp;
MapToPolygon(polyTemp);
TGGePolygonEx polyEx(polyTemp);
TADSGePoint3d pt;
if (polyEx.GetInsidePoint(pt, TRUE) == RTNORM)
{
return pt;
}
return GetPoint(0, 10 * _DIST_SNAP);
}
ads_real TGGePoly2D::Distance2d() const
{
int nLen = TotalSegments();
double dRes = 0.0;
for (int i = 0; i < nLen; i++)
{
dRes += Distance2d(i);
}
return dRes;
}
ads_real TGGePoly2D::Distance2d(int nIndex) const
{
int nLen = Length();
if (nIndex < 0 || nIndex >= nLen)
{
return 0;
}
if (!(m_nFlag & 1) && nIndex == nLen - 1)
{
return 0;
}
TGGeCurveSegment seg;
Nth(nIndex, seg);
seg.SetElevation(0.0);
return seg.GetLength();
}
ads_real TGGePoly2D::Distance3d() const
{
int nLen = TotalSegments();
double dRes = 0.0;
for (int i = 0; i < nLen; i++)
{
dRes += Distance3d(i);
}
return dRes;
}
ads_real TGGePoly2D::Distance3d(int nIndex) const
{
int nLen = Length();
if (nIndex < 0 || nIndex >= nLen)
{
return 0;
}
if (!(m_nFlag & 1) && nIndex == nLen - 1)
{
return 0;
}
TGGeCurveSegment seg;
Nth(nIndex, seg);
return seg.GetLength();
}
int TGGePoly2D::HitTestOnCurve(const TADSGePoint3d &ptTest, double dTol) const
{
const TGGePoly2D &polyPath = *this;
TADSGePoint3d pt2d = ptTest;
for (int i = 0; i < polyPath.Length(); i++)
{
if (pt2d.Distance2d(polyPath[i]) < dTol)
{
return (i + 1);
}
}
TPushPrec vTemp(dTol, _angSnap);
int nEdgeNum = polyPath.TotalSegments();
for (i = 0; i < nEdgeNum; i++)
{
TGGeCurveSegment seg;
polyPath.Nth(i, seg);
seg.SetElevation(0.0);
if ((pt2d & seg) == PR_INSIDE)
{
return (-i - 1);
}
}
return 0;
}
inline int TGGePoly2D::Nth(int nIndex, TGGeCurveSegment &curve, AcDb::Visibility *pVal) const
{
if (!IsValid(nIndex))
{
return RTERROR;
}
static TGGeLine ln;
static TGGeArc arc;
int nflg = Nth(nIndex, ln, arc);
int nFlag = curve.m_nFlag;
int nRet = RTNORM;
switch(nflg)
{
case LINE_SEGMENT:
//curve = ln;
curve.m_startPoint = ln.m_startPoint;
curve.m_endPoint = ln.m_endPoint;
curve.m_dBulge = 0.0;
break;
case ARC_SEGMENT:
curve = arc;
break;
default:
nRet = RTERROR;
}
curve.m_nFlag = nFlag;
return nRet;
}
inline int TGGePoly2D::Nth(int nIndex, TGGeLine &xline, TGGeArc &xarc, AcDb::Visibility *pVal) const
{
if (!IsValid(nIndex))
{
return RTERROR;
}
int nLen = Length();
TADSGePoint3d p1 = (*this)[nIndex];
TADSGePoint3d p2;
if (nIndex == nLen - 1)
{
p2 = (*this)[0];
}
else
{
p2 = (*this)[nIndex + 1];
}
double dAng = m_ardbulges[nIndex];
if (fabs(dAng) > 1.0E-6)
{
xarc.Set(p1,p2,dAng);
return ARC_SEGMENT;
}
else
{
//xline.SetPoints(p1, p2);
xline.m_startPoint = p1;
xline.m_endPoint = p2;
return LINE_SEGMENT;
}
}
inline int TGGePoly2D::Nth(int nIndex, TGGeDirectionCurve &curve, AcDb::Visibility *pVal) const
{
if (!IsValid(nIndex))
{
return RTERROR;
}
int nLen = Length();
TADSGePoint3d p1 = (*this)[nIndex], p2;
if (nIndex == nLen - 1)
{
p2 = (*this)[0];
}
else
{
p2 = (*this)[nIndex + 1];
}
double dAng = m_ardbulges[nIndex];
curve.m_startPoint = p1;
curve.m_endPoint = p2;
curve.m_dBulge = dAng;
return RTNORM;
}
int TGGePoly2D::Make(const TCHAR *szlay) const
{
int nLen = Length();
if (nLen <= 1)
{
return RTERROR;
}
// LWPLINE
AcDbPolyline *pLwPoly = new AcDbPolyline(nLen);
for (int i = 0; i < nLen; i++)
{
double dBuge = tan(m_ardbulges[i] / 4.0);
pLwPoly->addVertexAt(i, (*this)[i].AsAcGePoint2d(), dBuge);
}
if (szlay)
{
AssureLayer(szlay, LAYSTAT_UNLOCK);
pLwPoly->setLayer(szlay);
}
pLwPoly->setClosed(m_nFlag ? Adesk::kTrue : Adesk::kFalse);
double dThickness = 0.0;
TGGetVar(_T("THICKNESS"), &dThickness);
pLwPoly->setThickness(dThickness);
pLwPoly->setElevation((*this)[0].z);
AddToModelSpace(pLwPoly, Adesk::kTrue);
return RTNORM;
}
int TGGePoly2D::MakeSegments(const TCHAR *szlay) const
{
int nLen = Length();
for (int i = 0; i < nLen; i++)
{
MakeSegment(i, szlay);
}
return RTNORM;
}
int TGGePoly2D::MakeSegment(int nIndex, const TCHAR *szlay) const
{
TGGeLine line;
TGGeArc arc;
int nrc = Nth(nIndex, line, arc);
if (nrc == LINE_SEGMENT)
{
line.Make(szlay);
}
else if (nrc == ARC_SEGMENT)
{
arc.Make(szlay);
}
return RTNORM;
}
// dDrt--ptRes所在的切向
// 按2d距离求点和方向,注意返回的点是3d
int TGGePoly2D::Polar2d(ads_real dis, TADSGePoint3d &ptRes, ads_real *dDrt) const
{
//lfy 2010-08-31 修改存取方式
int nLen = TotalSegments(), iNext = 0;
double dSum = 0.0, dAng = 0.0, dsita = 0.0;
TADSGePoint3d p1, p2, pt1, pt2;
for (int i = 0; i < nLen; i++)
{
dSum += Distance2d(i);
if (dSum > dis - _DIST_SNAP)
{
p1 = (*this)[i];
iNext = i + 1;
if (iNext >= Length())
{
iNext = 0;
}
p2 = (*this)[iNext];
dAng = m_ardbulges[i];
if (fabs(dAng) > 1E-6)
{
TGGeArc xarc(p1, p2, dAng);
dsita = (dSum - dis) / xarc.m_dRadius;
if (dAng > 0)
{
ads_polar(xarc.m_ptCenter, xarc.m_dendAngle - dsita, xarc.m_dRadius, ptRes);
if (dDrt)
{
*dDrt = AngleRangeTo2PI(xarc.m_dendAngle - dsita + PI / 2.0);
}
}
else
{
ads_polar(xarc.m_ptCenter, xarc.m_dstartAngle + dsita, xarc.m_dRadius, ptRes);
if (dDrt)
{
*dDrt = AngleRangeTo2PI(xarc.m_dstartAngle + dsita - PI / 2.0);
}
}
}
else
{
ads_polar(p2, ads_angle(p2, p1), dSum - dis, ptRes);
pt1 = p1;
pt2 = p2;
pt2.z = pt1.z;
ptRes.z += (p1.z - p2.z) / ads_distance(pt2, pt1) * (dSum - dis);
if (dDrt)
{
*dDrt = ads_angle(pt1, pt2);
}
}
return i;
}
}
return RTERROR;
}
int TGGePoly2D::Polar3d(ads_real dis, TADSGePoint3d &ptRes, TVector3D &vt) const
{
//lfy 2010-08-31 修改存取方式
int nLen = TotalSegments(), iNext = 0;
double dSum = 0.0, dAng = 0.0, dsita = 0.0;
TADSGePoint3d p1, p2, pt1, pt2;
double dDrt = 0.0;
for (int i = 0; i < nLen; i++)
{
dSum += Distance3d(i);
if (dSum > dis - _DIST_SNAP)
{
p1 = (*this)[i];
iNext = i + 1;
if (iNext >= Length())
{
iNext = 0;
}
p2 = (*this)[iNext];
dAng = m_ardbulges[i];
if (fabs(dAng) > 1E-6)
{
TGGeArc xarc(p1, p2, dAng);
dsita = (dSum - dis) / xarc.m_dRadius;
if (dAng > 0)
{
ads_polar(xarc.m_ptCenter, xarc.m_dendAngle - dsita, xarc.m_dRadius, ptRes);
dDrt = AngleRangeTo2PI(xarc.m_dendAngle - dsita + PI / 2.0);
}
else
{
ads_polar(xarc.m_ptCenter, xarc.m_dstartAngle + dsita, xarc.m_dRadius, ptRes);
dDrt = AngleRangeTo2PI(xarc.m_dstartAngle + dsita - PI / 2.0);
}
vt.x = cos(dDrt);
vt.y = sin(dDrt);
vt.z = 0;
}
else
{
vt = p2 - p1;
TVector3D vtNormal = vt;
((AcGeVector3d &)vtNormal).normalize();
vt = vtNormal;
vtNormal *= dis - dSum;
ptRes = p2 + vtNormal;
}
return i;
}
}
return RTERROR;
}
ads_real TGGePoly2D::PathArea() const
{
int i = 0;
int nflg;
TGGeArc arc;
TGGeLine line;
double dresult = 0.0;
while ((nflg = Nth(i, line, arc)) != RTERROR)
{
if (nflg == LINE_SEGMENT)
{
dresult += line.PathArea();
}
else if (m_ardbulges[i] > 0)
{
dresult += arc.PathArea();
}
else
{
dresult -= arc.PathArea();
}
i++;
}
return dresult;
}
int TGGePoly2D::MapToPolygon(TGGePoly &pts, int nCirDiv)
{
//lfy 2010-08-31 修改存取方式
pts.Reset();
int nLen = Length();
int i = 0, n = 0, nNum = 0, nRetFlag = 0;
TADSGePoint3d pt;
double dincrement = 0.0;
for (i = 0; i < nLen; i++)
{
if (fabs(*m_ardbulges[i]) < 1E-6)
{
pts.Append(new TADSGePoint3d(*(*this)[i]));
}
else if (i < nLen - 1 || IsClosed())
{
TGGeArc arc;
TGGeLine ll;
nRetFlag = Nth(i, ll, arc);
ASSERT(nRetFlag == ARC_SEGMENT);
//圆用30边做成
nNum = (int)(arc.Bulge() / (2.0 * PI) * nCirDiv);
nNum = max(nNum, 1);
dincrement = arc.Bulge() / nNum;
for (n = 0; n < nNum; n++)
{
if (*m_ardbulges[i] > 0)
{
ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt);
}
else
{
ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt);
}
pts.Append(new TADSGePoint3d(pt));
}
}
}
return RTNORM;
}
void TGGePoly2D::Disperse(TGGePoly2D &polyBase1, int nCirDivSeg) const
{
TGGePoly polyBase;
AsOpenPoly(polyBase, nCirDivSeg);
int nCount = polyBase.Length();
if (IsClosed())
{
nCount--;
}
for (int n = 0; n < nCount; n++)
{
polyBase1.AppendNode(*polyBase[n]);
}
polyBase1.SetFlag(m_nFlag);
}
int TGGePoly2D::AsOpenPoly(TGGePoly &pts, int nCirDiv) const
{
//lfy 2010-08-31 修改存取方式
pts.Reset();
int nLen = Length();
const TGGePoly2D &poly = *this;
int i = 0, n = 0, nNum = 0, nRetFlag = 0;
TADSGePoint3d pt;
double dincrement = 0.0;
TGGeArc arc;
TGGeLine ll;
for ( i = 0; i < nLen; i++)
{
if (fabs(m_ardbulges[i]) < 1E-6)
{
pts.Append(new TADSGePoint3d(poly[i]));
if (i == nLen - 1 && IsClosed())
{
//最后一点为起点
pts.Append(new TADSGePoint3d(poly[0]));
}
}
else
{
//Arc
if (!IsClosed() && i == nLen - 1)
{
//不封闭的最后一点
pts.Append(new TADSGePoint3d(poly[i]));
return RTNORM;
}
nRetFlag = Nth(i, ll, arc);
ASSERT(nRetFlag == ARC_SEGMENT);
nNum = (int)(arc.Bulge() / (2.0 * PI) * nCirDiv);
nNum = max(nNum, 1);
dincrement = arc.Bulge() / nNum;
if (i == nLen-1 && IsClosed())
{
//最后一封闭弧段
nNum += 1;
}
for (n = 0; n < nNum; n++)
{
if (m_ardbulges[i] > 0)
{
ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt);
}
else
{
ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt);
}
pts.Append(new TADSGePoint3d(pt));
}
}
}
return RTNORM;
}
int TGGePoly2D::MapToPolygon1(TGGePoly &pts, double dDeviation)
{
//lfy 2010-08-31 修改存取方式
pts.Reset();
int nLen = Length();
int i = 0, n = 0, nNum = 0, nRetFlag = 0, nCirDiv = 0;
TADSGePoint3d pt;
double dincrement = 0.0;
TGGeArc arc;
TADSGePoint3d* pPtScr = NULL;
TGGeLine ll;
for (i = 0; i < nLen; i++)
{
if (fabs(*m_ardbulges[i]) < 1E-6)
{
pPtScr = new TADSGePoint3d(*(*this)[i]);
pts.Append(pPtScr);
}
else if (i < nLen - 1 || IsClosed())
{
//不到最后一点或闭合的最后一段
nRetFlag = Nth(i, ll, arc);
ASSERT(nRetFlag == ARC_SEGMENT);
if (arc.GetLength() < _DIST_SNAP)
{
continue;
}
nCirDiv = GetCirDivNum(arc.m_dRadius, dDeviation);
nNum = (int)(arc.Bulge() / (2.0 * PI) * nCirDiv);
nNum = max(nNum, 1);
dincrement = arc.Bulge() / nNum;
for (n = 0; n < nNum; n++)
{
if (*m_ardbulges[i] > 0)
{
ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt);
}
else
{
ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt);
}
pts.Append(new TADSGePoint3d(pt));
}
}
}
return RTNORM;
}
void TGGePoly2D::Disperse1(TGGePoly2D &polyBase1, double dDeviation) const
{
TGGePoly polyBase;
AsOpenPoly1(polyBase, dDeviation);
int nCount = polyBase.Length();
if (IsClosed())
{
nCount--;
}
for (int n = 0; n<nCount; n++)
{
polyBase1.AppendNode(*polyBase[n]);
}
polyBase1.SetFlag(m_nFlag);
}
int TGGePoly2D::AsOpenPoly1(TGGePoly &pts, double dDeviation) const
{
pts.Reset();
int nLen = Length();
int i = 0, n = 0, nNum = 0, nRetFlag = 0, nCirDiv = 0;
TADSGePoint3d pt;
double dincrement = 0.0;
TGGeArc arc;
TGGeLine ll;
TADSGePoint3d* pPtScr = NULL;
TADSGePoint3d* pPtScr0 = NULL;
for (i = 0; i < nLen; i++)
{
if (fabs(m_ardbulges[i]) < 1E-6)
{
pPtScr = new TADSGePoint3d((*this)[i]);
pts.Append(pPtScr);
if (i == nLen - 1 && IsClosed())
{
pPtScr0 = new TADSGePoint3d((*this)[0]);
pts.Append(pPtScr0);
}
}
else
{
if (!IsClosed() && i == nLen - 1)
{
pPtScr = new TADSGePoint3d((*this)[i]);
pts.Append(pPtScr);
return RTNORM;
}
nRetFlag = Nth(i, ll, arc);
ASSERT(nRetFlag == ARC_SEGMENT);
nCirDiv = GetCirDivNum(arc.m_dRadius, dDeviation);
nNum = (int)(arc.Bulge() / (2.0 * PI) * nCirDiv);
nNum = max(nNum, 1);
dincrement = arc.Bulge() / nNum;
if (i == nLen - 1 && IsClosed())
{
nNum += 1;
}
for (n = 0; n < nNum; n++)
{
if (m_ardbulges[i] > 0)
{
ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt);
}
else
{
ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt);
}
pts.Append(new TADSGePoint3d(pt));
}
}
}
return RTNORM;
}
double TGGePoly2D::PathDistance2d(TADSGePoint3d ptHit) const
{
double nRet = 0.0;
int nHitLeft = HitTestOnCurve(ptHit);
if (nHitLeft < 0)
{
int iLeft = abs(nHitLeft) - 1;
TGGeDirectionCurve leftHitCurve;
Nth(iLeft, leftHitCurve);
nRet = leftHitCurve.PathDistance(ptHit);
for (int k = 0; k < iLeft; k++)
{
Nth(k, leftHitCurve);
nRet += leftHitCurve.GetLength();
}
}
// add by xlc on 110415 ptHit在顶点时计算路径长度
else if (nHitLeft > 0)
{
for (int k = 0; k < nHitLeft - 1; k++)
{
TGGeDirectionCurve leftHitCurve;
Nth(k, leftHitCurve);
nRet += leftHitCurve.GetLength();
}
}
return nRet;
}
int TGGePoly2D::CreatePface(int nCirDiv, const TCHAR *pszLay)
{
TGGePoly pts;
MapToPolygon(pts, nCirDiv);
return pts.CreatePface(pszLay);
}
int TGGePoly2D::GetExtend(ads_point lowPt, ads_point upPt) const
{
int nNum = TotalSegments();
if (!nNum)
{
return RTERROR;
}
TGGeCurveSegment seg;
TADSGePoint3d ptlow, ptup;
ptlow = ptup = ((*this)[0]);
for (int n = 0; n < nNum; n++)
{
if (Nth(n, seg) != RTNORM)
{
continue;
}
TADSGePoint3d pt1, pt2;
seg.GetExtend(pt1, pt2);
ptlow = Min(ptlow, pt1);
ptup = Max(ptup, pt2);
}
ptlow > lowPt;
ptup > upPt;
return RTNORM;
}
// 没有判断边重合的情况
BOOL TGGePoly2D::IsSelfIntersect() const
{
const TGGePoly2D &polyOutline = *this;
int nLen = polyOutline.Length();
TGGeArc arc;
for (int i = 0; i < nLen - 2; i++)
{
TGGeLine ln0(LS_FINITE);
polyOutline.Nth(i, ln0, arc);
if (ln0.GetLength() < _DIST_SNAP)
{
continue;
}
for (int j = i + 2; j < ((i == 0 && m_nFlag == 1) ? (nLen - 1) : nLen); j++)
{
TGGeLine ln1(LS_FINITE);
polyOutline.Nth(j, ln1, arc);
if (ln1.GetLength() < _DIST_SNAP)
{
continue;
}
TADSGePoint3d ptInt;
if (ln0.Intersection(&ln1, ptInt))
{
return TRUE;
}
}
}
return FALSE;
}
int TGGePoly2D::AppendSegment(const TGGeCurveSegment &curve, int bMinus, int bFinal)
{
if (bMinus)
{
Append(new TADSGePoint3d(curve.GetEndPoint()));
m_ardbulges.Append(new double(-curve.GetBulge()));
if (bFinal && !(m_nFlag & 0x01))
{
Append(new TADSGePoint3d(curve.GetStartPoint()));
m_ardbulges.Append(new double(0.0));
}
}
else
{
Append(new TADSGePoint3d(curve.GetStartPoint()));
m_ardbulges.Append(new double(curve.GetBulge()));
if (bFinal && !(m_nFlag & 0x01))
{
Append(new TADSGePoint3d(curve.GetEndPoint()));
m_ardbulges.Append(new double(0.0));
}
}
return RTNORM;
}
int TGGePoly2D::Compress(bool bUnionCurve)
{
if (Length() < 1)
{
return RTERROR;
}
const TGGePoly2D &poly = *this;
TList<TADSGePoint3d> ptList;
TList<double> anList;
ptList.AddTail(poly[0]);
for (long i = 1; i < Length(); i++)
{
if (ptList.GetCurData() != poly[i])
{
ptList.AddTail(poly[i]);
anList.AddTail(*(m_ardbulges[i - 1]));
}
}
anList.AddTail(*(m_ardbulges[i - 1]));
if (IsClosed())
{
if (ptList.GetLength() > 1 && poly[0] == ptList.GetCurData())
{
ptList.DelCur();
anList.DelCur();
}
}
if (ptList.GetLength() < Length())
{
Reset();
m_ardbulges.Reset();
for (ptList.MoveToFirst(), anList.MoveToFirst(); !ptList.IsOut(); ptList.MoveToNext(), anList.MoveToNext())
{
AppendNode(ptList.GetCurData(), anList.GetCurData());
}
}
if (!bUnionCurve)
{
return RTNORM;
}
TGGePoly2D destPoly(m_nFlag);
int nTotalSeg = TotalSegments();
TGGeCurveSegment curve;
int bMinusCurve = 0, bMinusSeg = 0, bMerged = 0;
for (int n = 0; n < nTotalSeg; n++)
{
TGGeCurveSegment seg;
Nth(n, seg);
if (!seg)
{
continue;
}
bMinusSeg = (*m_ardbulges[n] < -1.0E-8);
bMerged = 0;
if (!curve)
{
curve = seg;
bMinusCurve = bMinusSeg;
continue;
}
else
{
bMerged = MergeCurve(curve, seg, bMinusCurve, bMinusSeg);
}
if (!bMerged)
{
destPoly.AppendSegment(curve, bMinusCurve);
curve = seg;
bMinusCurve = bMinusSeg;
}
}
if (!curve)
{
return RTERROR;
}
else
{
destPoly.AppendSegment(curve, bMinusCurve, 1);
}
if ((destPoly.GetFlag() & 0x01) && destPoly.TotalSegments() >= 2)
{
int nTotalDest = destPoly.TotalSegments();
int bMinusFirst = (destPoly.GetBulge(0) < -1.0E-8);
int bMinusFinal = (destPoly.GetBulge(nTotalDest - 1) < -1.0E-8);
TGGeCurveSegment curveFirst, curveFinal;
destPoly.Nth(0, curveFirst);
destPoly.Nth(nTotalDest - 1, curveFinal);
if (MergeCurve(curveFinal, curveFirst, bMinusFinal, bMinusFirst))
{
if (bMinusFinal)
{
destPoly.SetBulge(0,-curveFinal.GetBulge());
destPoly.SetPointListAt(0, curveFinal.EndPoint());
}
else
{
destPoly.SetBulge(0, curveFinal.GetBulge());
destPoly.SetPointListAt(0, curveFinal.StartPoint());
}
destPoly.RemoveBugle(nTotalDest - 1);
destPoly.RemovePointListAt(nTotalDest - 1);
}
}
*this = destPoly;
return RTNORM;
}
int TGGePoly2D::Reverse()
{
if (Length() < 2)
{
return RTERROR;
}
TGGePoly2D destPoly;
int nTotalSeg = TotalSegments();
TGGeDirectionCurve cv;
for (int i = nTotalSeg - 1; i >= 0; i--)
{
Nth(i, cv);
destPoly.AppendNode(cv.EndPoint(), -cv.GetBulge());
}
if (!(m_nFlag & 0x01))
{
destPoly.AppendNode(*((*this)[0]), -(*m_ardbulges[nTotalSeg]));
}
destPoly.SetFlag(m_nFlag);
*this = destPoly;
return RTNORM;
}
int TGGePoly2D::Offset(ads_real dDist, TGGePoly2D &destPoly) const
{
int nTotalSeg = TotalSegments();
if (!nTotalSeg)
{
return RTERROR;
}
if (fabs(dDist) < _DIST_SNAP)
{
destPoly = *this;
return RTNORM;
}
destPoly.Reset();
destPoly.SetFlag(m_nFlag);
TGGeDirectionCurve finalMidSeg, lastSeg;
if (m_nFlag & 0x01)
{
Nth(nTotalSeg - 1, finalMidSeg);
lastSeg = finalMidSeg.Offset(dDist, LS_INFINITE);
if (!lastSeg)
{
return RTERROR;
}
}
TADSGePoint3d nextPt,pt1, pt2, curPt;
TGGeDirectionCurve curMidSeg, curSeg, nextMidSeg, nextSeg;
int nNum = 0, nextIndex = 0;
TGGeArc arc;
for (int i = 0; i < nTotalSeg; i++)
{
Nth(i, curMidSeg);
curSeg = curMidSeg.Offset(dDist, LS_INFINITE);
if (!curSeg)
{
return RTERROR;
}
if (!i)
{
// 求当前点
if (!lastSeg)
{
curPt = curSeg.GetStartPoint();
}
else
{
nNum = curSeg.Intersection(lastSeg, pt1, pt2);
if (nNum == 2)
{
curPt = TGGeLine(pt1, pt2).NearPoint(curSeg.GetStartPoint());
}
else if (nNum == 1)
{
curPt = pt1;
}
else
{
if (IsSameDrt(curSeg.IDirection(0), lastSeg.IDirection(1), _angSnap))
{
//同方向, 两段连接.
curPt = curSeg.GetStartPoint();
}
else
{
return RTERROR;
}
}
}
}
else
{
curPt = nextPt;
}
// 求下一个端点
if (i == nTotalSeg - 1 && !(m_nFlag & 0x01))
{
//不封闭的最后一段
nextPt = curSeg.GetEndPoint();
}
else
{
//为最后时下一段为起始
nextIndex = i >= nTotalSeg - 1 ? 0 : i + 1;
Nth(nextIndex, nextMidSeg);
nextSeg = nextMidSeg.Offset(dDist, LS_INFINITE);
if (!nextSeg)
{
return RTERROR;
}
nNum = curSeg.Intersection(nextSeg, pt1, pt2);
if (nNum == 2)
{
nextPt = TGGeLine(pt1, pt2).NearPoint(curSeg.GetEndPoint());
}
else if (nNum == 1)
{
nextPt = pt1;
}
else
{
if (IsSameDrt(curSeg.IDirection(1), nextSeg.IDirection(0), _angSnap))
{
nextPt = curSeg.GetEndPoint();
}
else
{
return RTERROR;
}
}
}
lastSeg = curSeg;
if (curSeg.Is(CURVE_ARC))
{
arc = curSeg.GetArc();
if (!curSeg.IsMinusArc())
{
//逆时针
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), curPt));
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), nextPt));
curSeg.SetBulge(arc.Bulge());
}
else
{
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), nextPt));
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), curPt));
curSeg.SetBulge(-arc.Bulge());
}
curSeg.SetStartPoint(curPt);
curSeg.SetEndPoint(nextPt);
}
assert(!curSeg.Is(CURVE_CIRCLE));
//加一段
destPoly.Append(new TADSGePoint3d(curPt));
destPoly.m_ardbulges.Append(new double(curSeg.GetBulge()));
if (i == nTotalSeg - 1 && !(m_nFlag & 0x01))
{
destPoly.Append(new TADSGePoint3d(nextPt));
destPoly.m_ardbulges.Append(new double(0.0));
}
}
return RTNORM;
}
int TGGePoly2D::HasArcSegment() const
{
for (int i = 0; i < TotalSegments(); i++)
{
if (fabs(m_ardbulges[i]) > 1.0E-6)
{
return 1;
}
}
return 0;
}
int TGGePoly2D::QuickOffset(ads_real dDist, TGGePoly2D &destPoly) const
{
const TGGePoly2D &basePoly = *this;
destPoly.Reset();
destPoly.m_nFlag = m_nFlag;
int nVertexNum = basePoly.Length();
TGGeDirectionCurve prevEdge;
int bIsClosed = ((basePoly.m_nFlag & 0x01) != 0);
if (bIsClosed)
{
basePoly.Nth(nVertexNum - 1, prevEdge);
}
TADSGePoint3d newVertex;
for (int j = 0; j < nVertexNum; j++)
{
TGGeDirectionCurve curEdge;
double dFromDirection, dToDirection;
if (j == nVertexNum - 1)
{
dToDirection = AngleRangeTo2PI(prevEdge.IDirection(1) - PI);
dFromDirection = prevEdge.IDirection(1);
if (bIsClosed)
{
basePoly.Nth(nVertexNum - 1, curEdge);
dFromDirection = AngleRangeTo2PI(curEdge.IDirection(0) - PI);
}
}
else
{
basePoly.Nth(j, curEdge);
dFromDirection = AngleRangeTo2PI(curEdge.IDirection(0) - PI);
dToDirection = curEdge.IDirection(0);
if (j > 0 || bIsClosed)
{
dToDirection = AngleRangeTo2PI(prevEdge.IDirection(1) - PI);
}
}
double dDirection = TGGeSector(dFromDirection, dToDirection).MidAngle();
const TADSGePoint3d &thisVertex = basePoly[j];
double dSinAng = fabs(sin(AngleRangeTo2PI(dDirection - dFromDirection)));
if (fabs(dSinAng) < 1E-6)
{
return RTERROR;
}
else
{
ads_polar(thisVertex, dDirection, dDist / dSinAng, newVertex);
}
destPoly.AppendNode(newVertex, m_ardbulges[j]);
prevEdge = curEdge;
}
TADSGePoint3d ptMid;
double dAbsBulge;
assert(TotalSegments() == destPoly.TotalSegments());
for (int i = 0; i < TotalSegments(); i++)
{
TGGeDirectionCurve cvSrc, cvDest, dv;
Nth(i, cvSrc);
destPoly.Nth(i, cvDest);
if (fabs(cvSrc.GetBulge()) > 1.0E-5)
{
TGGeDirectionCurve dv = cvSrc.Offset(dDist, LS_FINITE);
if (!dv)
{
return RTERROR;
}
dv.GetArc().MidPoint(ptMid);
TGGeArc ar(cvDest.GetStartPoint(), ptMid, cvDest.GetEndPoint());
dAbsBulge = ar.Bulge();
if (dAbsBulge < 1.0E-5)
{
return RTERROR;
}
*destPoly.m_ardbulges[i] = (cvSrc.GetBulge() > 0) ? dAbsBulge : -dAbsBulge;
}
}
return RTNORM;
}
AcDbRegion* TGGePoly2D::AsRegion() const
{
const TGGePoly2D &poly = *this;
if (!poly.IsClosed())
{
return NULL;
}
AcDbPolyline pline;
PolyConvert(poly, pline);
AcDbVoidPtrArray curveSegments;
curveSegments.append(&pline);
AcDbVoidPtrArray regions;
if (AcDbRegion::createFromCurves(curveSegments, regions) == Acad::eOk && regions.length() > 0)
{
AcDbRegion *regioni = (AcDbRegion *)regions[0];
regions.removeAt(0);
ReleaseEntSet(regions);
return regioni;
}
//如果整个pline创建region,不成功的时候,再炸开
AcDbVoidPtrArray explodeSegments;
pline.explode(explodeSegments);
AcDbVoidPtrArray regions2;
if (AcDbRegion::createFromCurves(curveSegments, regions2) == Acad::eOk && regions2.length() > 0)
{
AcDbRegion *regioni = (AcDbRegion *)regions2[0];
regions2.removeAt(0);
ReleaseEntSet(regions2);
return regioni;
}
ReleaseEntSet(explodeSegments);
return NULL;
}
bool TGGePoly2D::IsRegionInclude(const TGGePoly2D& poly) const
{
TGGePoly2D poly1, poly2;
poly1 = *this;
poly2 = poly;
poly1.SetElevation(0.0);
poly2.SetElevation(0.0);
AcDbRegion *pRegion1 = poly1.AsRegion();
AcDbRegion *pRegion2 = poly2.AsRegion();
double area0;
double area1;
if (pRegion1 != NULL && pRegion2 != NULL)
{
pRegion1->getArea(area0);
if (pRegion1->booleanOper(AcDb::kBoolUnite,pRegion2) == Acad::eOk)
{
pRegion1->getArea(area1);
if (fabs(area1 - area0) < 1E-6)
{
delete pRegion1;
delete pRegion2;
return true;
}
}
}
if (pRegion1 != NULL)
{
delete pRegion1;
}
if (pRegion2 != NULL)
{
delete pRegion2;
}
return false;
}
bool TGGePoly2D::IsRegionOverlap(const TGGePoly2D& poly) const
{
TGGePoly2D poly1, poly2;
poly1 = *this;
poly2 = poly;
poly1.SetElevation(0.0);
poly2.SetElevation(0.0);
AcDbRegion *pRegion1 = poly1.AsRegion();
AcDbRegion *pRegion2 = poly2.AsRegion();
double area;
if (pRegion1 != NULL && pRegion2 != NULL)
{
if (pRegion1->booleanOper(AcDb::kBoolIntersect, pRegion2) == Acad::eOk)
{
pRegion1->getArea(area);
if (area > 1E-6)
{
delete pRegion1;
delete pRegion2;
return true;
}
}
}
if (pRegion1 != NULL)
{
delete pRegion1;
}
if (pRegion2 != NULL)
{
delete pRegion2;
}
return false;
}
AcDbCurve* TGGePoly2D::AsAcDbCurve() const
{
AcDbPolyline* pLwPoly = new AcDbPolyline(Length());
double dBuge = 0.0;
for (int i = 0; i < Length(); i++)
{
dBuge = tan(m_ardbulges[i] / 4.0);
pLwPoly->addVertexAt(i, ((*this)[i]).AsAcGePoint2d(), dBuge);
}
if (Length() >0)
{
pLwPoly->setElevation((*this)[0].z);
}
pLwPoly->setClosed(IsClosed() ? Adesk::kTrue : Adesk::kFalse);
return pLwPoly;
}
bool TGGePoly2D::SetAcDbCurve(AcDbCurve*pCurve)
{
AcDbPolyline* pLwPoly = AcDbPolyline::cast(pCurve);
if (pLwPoly == NULL)
{
return false;
}
Reset();
double dElev = pLwPoly->elevation();
AcGePoint2d pt;
double dBulge = 0.0;
for (long i = 0; i < (long)pLwPoly->numVerts(); i++)
{
pLwPoly->getPointAt(i, pt);
pLwPoly->getBulgeAt(i, dBulge);
dBulge = atan(dBulge) * 4;
AppendNode(TADSGePoint3d(pt.x, pt.y, dElev), dBulge);
}
if (pLwPoly->isClosed())
{
m_nFlag = 1;
}
else
{
m_nFlag = 0;
}
return true;
}
void TGGePoly2D::SetFlag(int nFlag)
{
m_nFlag = nFlag;
}
int TGGePoly2D::GetFlag() const
{
return m_nFlag;
}
void TGGePoly2D::RemoveBugle(int nIndex)
{
m_ardbulges.Remove(nIndex);
}
void TGGePoly2D::AppendBugle(ads_real dBugle)
{
m_ardbulges.Append( new double(dBugle));
}
double TGGePoly2D::GetBulge(int nIndex) const
{
return m_ardbulges[nIndex];
}
void TGGePoly2D::SetBulge(int nIndex, double dBugle)
{
*m_ardbulges[nIndex] = dBugle;
}
void TGGePoly2D::SetPointListAt(int nIndex, const TADSGePoint3d& pt)
{
if (Length() > nIndex)
{
*((*this)[nIndex]) = pt;
}
}
void TGGePoly2D::RemovePointListAt(int nIndex)
{
if (Length() > nIndex)
{
Remove(nIndex);
}
}
void TGGePoly2D::AppendPointListAt(TADSGePoint3d* pPt)
{
Append(pPt);
}
TADSGePoint3d* TGGePoly2D::GetPointListAt(int nIndex)
{
return (*this)[nIndex];
}
const TADSGePoint3d& TGGePoly2D::GetPointListAt(int nIndex) const
{
return (*this)[nIndex];
}
TGGePoly3D TGGePoly2D::PlaneToWcs(const AcGeVector3d& normal)const
{
TGGePoly3D poly3d = *this;
AcGeMatrix3d mat;
mat.setToPlaneToWorld(normal);
poly3d.TransformBy(mat);
return poly3d;
}
int TGGePoly2D::SetBulges(const TDPtrList<double>& ardbulges)
{
if (ardbulges.Length() > 0)
{
m_ardbulges.Reset();
m_ardbulges.copyFrom(ardbulges);
return m_ardbulges.Length();
}
return -1;
}
int TGGePoly2D::GetBulges(TDPtrList<double>& ardbulges)
{
if (m_ardbulges.Length() > 0)
{
ardbulges.copyFrom(m_ardbulges);
return ardbulges.Length();
}
return -1;
}
TDPtrList<double>& TGGePoly2D::GetBulges()
{
return m_ardbulges;
}
bool TGGePoly2D::IsKindOf(TGGeEntity::TEntityId entType) const
{
switch(entType)
{
case TGGeEntity::eEntity:
case TGGeEntity::eCurve:
case TGGeEntity::ePoly2D:
return true;
}
return false;
}
TGGeEntity::TEntityId TGGePoly2D::Type() const
{
return TGGeEntity::ePoly2D;
}