Files
envi-code/SourceCode/Code2026/Dimension/GePoly2D.cpp
T
2026-09-28 15:28:50 +08:00

1888 lines
34 KiB
C++

#include "StdAfx.h"
//#include "globalDefine.h"
#include "GePoly2D.h"
#include "ADSGePointList.h"
#include "dbregion.h"
#include "PushPrec.h"
#include "AcDbObjectPtr.h"
#include "GePoly3D.h"
#include "SHList.h"
#include "GePolygonEx.h"
#include "PointList.h"
#include "geblok3d.h"
#include "geblok2d.h"
#include "GeCurveInline.h"
GePoly2D::GePoly2D()
: m_nFlag(0)
{
m_ardbulges.Reset();
}
GePoly2D::GePoly2D(const EntitySet& ent)
{
EntitySet entPLine = ent;
TCString sEntType;
ADSGePoint3d pt;
double dTAng = 0.0, dAng = 0.0;
entPLine.GetData(0, (TCHAR*)sEntType);
if (sEntType == _T("CIRCLE"))
{
GeCurveSegment cir(ent);
cir.AsPoly2D(*this);
return;
}
else if (sEntType == _T("LINE") || sEntType == _T("ARC"))
{
GeCurveSegment 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 ADSGePoint3d(pVertex->position()));
}
pVertex->close();
}
}
delete pIter;
}
return;
}
OPENOBJ_END();
EntitySet subEnt = entPLine;
while ( 1 )
{
EntitySet 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 ADSGePoint3d(pt));
}
}
else
{
double dElevation = 0.0;
entPLine.GetData(38, &dElevation);
resbuf *ebuf = (resbuf *)(entPLine.groups);
if (!ebuf)
{
g_Option::instance().adsout << _T("\nResbuf error");
}
while(ebuf)
{
resbuf *rb1 = GlobalFunc::GetResbufAtCode(ebuf, 10);
resbuf *rb2 = rb1 ? GlobalFunc::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 ADSGePoint3d(pt));
ebuf = rb2->rbnext;
}
else
{
break;
}
}
}
}
GePoly2D::GePoly2D(int nflg)
: m_nFlag(nflg)
{
m_ardbulges.Reset();
}
GePoly2D::GePoly2D(const GePoly2D &src)
{
ADSGePointList::copyFrom(src);
m_ardbulges.Reset();
m_ardbulges.copyFrom( src.m_ardbulges );
m_nFlag = src.GetFlag();
}
GePoly2D::~GePoly2D()
{
}
void GePoly2D::CopyFrom(const GeEntity* pSrc)
{
if (this != pSrc && pSrc->IsKindOf(GeEntity::ePoly2D))
{
m_nFlag = ((GePoly2D*)pSrc)->m_nFlag;
copyFrom(*((GePoly2D*)pSrc));
m_ardbulges.copyFrom(((GePoly2D*)pSrc)->m_ardbulges);
}
}
int GePoly2D::operator !() const
{
return (Length() < 2 ? 1 : 0);
}
GePoly2D& GePoly2D::operator = (const GePoly2D &src)
{
if (this != &src)
{
Reset();
m_nFlag = src.m_nFlag;
for(int i = 0; i < src.Length(); i++)
{
const ADSGePoint3d &pt = src[i];
double val = src.m_ardbulges[i];
Append(new ADSGePoint3d(pt));
m_ardbulges.Append(new ads_real(val));
}
}
return *this;
}
int GePoly2D::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 GePoly2D::IsClosed() const
{
return ((m_nFlag & 0x01) ? 1 : 0);
}
bool GePoly2D::SetClosed()
{
if (Length() > 2)
{
m_nFlag = 1;
return true;
}
return false;
}
int GePoly2D::TotalSegments() const
{
int nLen = Length();
return (m_nFlag & 1) ? nLen : nLen - 1;
}
double GePoly2D::Area() const
{
return fabs(PathArea());
}
double GePoly2D::GetLength()const
{
double dLength = 0.0;
for (int i = 0; i < TotalSegments(); i++)
{
GeCurveSegment seg;
Nth(i, seg);
dLength += seg.GetLength();
}
return dLength;
}
void GePoly2D::Reset()
{
PtrList<ADSGePoint3d>::Reset();
m_ardbulges.Reset();
}
resbuf* GePoly2D::Fence(int nCirDiv)
{
GePoly pts;
if (MapToPolygon(pts, nCirDiv) == RTNORM)
{
return (IsClosed() ? pts.Fence() : pts.Polygon());
}
return NULL;
}
resbuf* GePoly2D::Polygon(int nCirDiv)
{
GePoly pts;
if (MapToPolygon(pts, nCirDiv) == RTNORM)
{
return pts.Polygon();
}
return NULL;
}
void GePoly2D::AppendNode(const ADSGePoint3d &pt, ads_real dBulge, AcDb::Visibility eVal)
{
assert(Length() == m_ardbulges.Length());
Append(new ADSGePoint3d(pt));
m_ardbulges.Append(new double(dBulge));
}
void GePoly2D::InsertNodeAt(int nIndex, const ADSGePoint3d &pt, double dBulge, AcDb::Visibility eVal)
{
if (nIndex >= Length())
{
AppendNode(pt, dBulge);
}
else
{
(*this)[nIndex];
Insert(new ADSGePoint3d(pt));
m_ardbulges[nIndex];
m_ardbulges.Insert(new double(dBulge));
}
}
void GePoly2D::InsertNodeAt(const ADSGePoint3d &pt, AcDb::Visibility eVal)
{
}
void GePoly2D::RemoveNode(long nIndex)
{
Remove(nIndex);
m_ardbulges.Remove(nIndex);
}
void GePoly2D::TransformBy(const AcGeMatrix3d &mat)
{
//lfy 2010-08-31 修改
BOOL bIsMirror = GlobalFunc::IsMirrorMatrix(mat);
for (int i = 0; i < Length(); i++)
{
ADSGePoint3d *pt = (*this)[i];
pt->TransformBy(mat);
// lfy 2010-08-31 修改,减少循环
if (bIsMirror)
{
*m_ardbulges[i] = -*(m_ardbulges[i]);
}
}
/*
if (GlobalFunc::IsMirrorMatrix(mat))
{
for (int m = 0; m < Length(); m++)
{
*m_ardbulges[m] = -*(m_ardbulges[m]);
}
}*/
}
ADSGePoint3d GePoly2D::GetPoint(int nIOFlag, ads_real dDist)
{
ADSGePoint3d ptPick;
GeCurveSegment 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;
}
ADSGePoint3d GePoly2D::GetInsidePoint()
{
assert(Length());
GePoly polyTemp;
MapToPolygon(polyTemp);
GePolygonEx polyEx(polyTemp);
ADSGePoint3d pt;
if (polyEx.GetInsidePoint(pt, TRUE) == RTNORM)
{
return pt;
}
return GetPoint(0, 10 * g_Option::instance()._DIST_SNAP);
}
ads_real GePoly2D::Distance2d() const
{
int nLen = TotalSegments();
double dRes = 0.0;
for (int i = 0; i < nLen; i++)
{
dRes += Distance2d(i);
}
return dRes;
}
ads_real GePoly2D::Distance2d(int nIndex) const
{
int nLen = Length();
if (nIndex < 0 || nIndex >= nLen)
{
return 0;
}
if (!(m_nFlag & 1) && nIndex == nLen - 1)
{
return 0;
}
GeCurveSegment seg;
Nth(nIndex, seg);
seg.SetElevation(0.0);
return seg.GetLength();
}
ads_real GePoly2D::Distance3d() const
{
int nLen = TotalSegments();
double dRes = 0.0;
for (int i = 0; i < nLen; i++)
{
dRes += Distance3d(i);
}
return dRes;
}
ads_real GePoly2D::Distance3d(int nIndex) const
{
int nLen = Length();
if (nIndex < 0 || nIndex >= nLen)
{
return 0;
}
if (!(m_nFlag & 1) && nIndex == nLen - 1)
{
return 0;
}
GeCurveSegment seg;
Nth(nIndex, seg);
return seg.GetLength();
}
int GePoly2D::HitTestOnCurve(const ADSGePoint3d &ptTest, double dTol) const
{
const GePoly2D &polyPath = *this;
ADSGePoint3d pt2d = ptTest;
for (int i = 0; i < polyPath.Length(); i++)
{
if (pt2d.Distance2d(polyPath[i]) < dTol)
{
return (i + 1);
}
}
PushPrec vTemp(dTol, g_DimOption::instance()._angSnap);
int nEdgeNum = polyPath.TotalSegments();
for (i = 0; i < nEdgeNum; i++)
{
GeCurveSegment seg;
polyPath.Nth(i, seg);
seg.SetElevation(0.0);
if ((pt2d & seg) == PR_INSIDE)
{
return (-i - 1);
}
}
return 0;
}
inline int GePoly2D::Nth(int nIndex, GeCurveSegment &curve, AcDb::Visibility *pVal) const
{
if (!IsValid(nIndex))
{
return RTERROR;
}
static GeLine ln;
static GeArc 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 GePoly2D::Nth(int nIndex, GeLine &xline, GeArc &xarc, AcDb::Visibility *pVal) const
{
if (!IsValid(nIndex))
{
return RTERROR;
}
int nLen = Length();
ADSGePoint3d p1 = (*this)[nIndex];
ADSGePoint3d 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 GePoly2D::Nth(int nIndex, GeDirectionCurve &curve, AcDb::Visibility *pVal) const
{
if (!IsValid(nIndex))
{
return RTERROR;
}
int nLen = Length();
ADSGePoint3d 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 GePoly2D::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)
{
GlobalFunc::AssureLayer(szlay, LAYSTAT_UNLOCK);
pLwPoly->setLayer(szlay);
}
pLwPoly->setClosed(m_nFlag ? Adesk::kTrue : Adesk::kFalse);
double dThickness = 0.0;
GlobalFunc::TGGetVar(_T("THICKNESS"), &dThickness);
pLwPoly->setThickness(dThickness);
pLwPoly->setElevation((*this)[0].z);
GlobalFunc::AddToModelSpace(pLwPoly, Adesk::kTrue);
return RTNORM;
}
int GePoly2D::MakeSegments(const TCHAR *szlay) const
{
int nLen = Length();
for (int i = 0; i < nLen; i++)
{
MakeSegment(i, szlay);
}
return RTNORM;
}
int GePoly2D::MakeSegment(int nIndex, const TCHAR *szlay) const
{
GeLine line;
GeArc 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 GePoly2D::Polar2d(ads_real dis, ADSGePoint3d &ptRes, ads_real *dDrt) const
{
//lfy 2010-08-31 修改存取方式
int nLen = TotalSegments(), iNext = 0;
double dSum = 0.0, dAng = 0.0, dsita = 0.0;
ADSGePoint3d p1, p2, pt1, pt2;
for (int i = 0; i < nLen; i++)
{
dSum += Distance2d(i);
if (dSum > dis - g_Option::instance()._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)
{
GeArc 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 = GlobalFunc::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 = GlobalFunc::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 GePoly2D::Polar3d(ads_real dis, ADSGePoint3d &ptRes, TVector3D &vt) const
{
//lfy 2010-08-31 修改存取方式
int nLen = TotalSegments(), iNext = 0;
double dSum = 0.0, dAng = 0.0, dsita = 0.0;
ADSGePoint3d p1, p2, pt1, pt2;
double dDrt = 0.0;
for (int i = 0; i < nLen; i++)
{
dSum += Distance3d(i);
if (dSum > dis - g_Option::instance()._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)
{
GeArc 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 = GlobalFunc::AngleRangeTo2PI(xarc.m_dendAngle - dsita + PI / 2.0);
}
else
{
ads_polar(xarc.m_ptCenter, xarc.m_dstartAngle + dsita, xarc.m_dRadius, ptRes);
dDrt = GlobalFunc::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 GePoly2D::PathArea() const
{
int i = 0;
int nflg;
GeArc arc;
GeLine 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 GePoly2D::MapToPolygon(GePoly &pts, int nCirDiv)
{
//lfy 2010-08-31 修改存取方式
pts.Reset();
int nLen = Length();
int i = 0, n = 0, nNum = 0, nRetFlag = 0;
ADSGePoint3d pt;
double dincrement = 0.0;
for (i = 0; i < nLen; i++)
{
if (fabs(*m_ardbulges[i]) < 1E-6)
{
pts.Append(new ADSGePoint3d(*(*this)[i]));
}
else if (i < nLen - 1 || IsClosed())
{
GeArc arc;
GeLine l;
nRetFlag = Nth(i, l, 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 ADSGePoint3d(pt));
}
}
}
return RTNORM;
}
void GePoly2D::Disperse(GePoly2D &polyBase1, int nCirDivSeg) const
{
GePoly 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 GePoly2D::AsOpenPoly(GePoly &pts, int nCirDiv) const
{
//lfy 2010-08-31 修改存取方式
pts.Reset();
int nLen = Length();
const GePoly2D &poly = *this;
int i = 0, n = 0, nNum = 0, nRetFlag = 0;
ADSGePoint3d pt;
double dincrement = 0.0;
GeArc arc;
for ( i = 0; i < nLen; i++)
{
if (fabs(m_ardbulges[i]) < 1E-6)
{
pts.Append(new ADSGePoint3d(poly[i]));
if (i == nLen - 1 && IsClosed())
{
//最后一点为起点
pts.Append(new ADSGePoint3d(poly[0]));
}
}
else
{
//Arc
if (!IsClosed() && i == nLen - 1)
{
//不封闭的最后一点
pts.Append(new ADSGePoint3d(poly[i]));
return RTNORM;
}
GeLine l;
nRetFlag = Nth(i, l, 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 ADSGePoint3d(pt));
}
}
}
return RTNORM;
}
int GePoly2D::MapToPolygon1(GePoly &pts, double dDeviation)
{
//lfy 2010-08-31 修改存取方式
pts.Reset();
int nLen = Length();
int i = 0, n = 0, nNum = 0, nRetFlag = 0, nCirDiv = 0;
ADSGePoint3d pt;
double dincrement = 0.0;
GeArc arc;
ADSGePoint3d* pPtScr = NULL;
for (i = 0; i < nLen; i++)
{
if (fabs(*m_ardbulges[i]) < 1E-6)
{
pPtScr = new ADSGePoint3d(*(*this)[i]);
pts.Append(pPtScr);
}
else if (i < nLen - 1 || IsClosed())
{
GeLine l;
//不到最后一点或闭合的最后一段
nRetFlag = Nth(i, l, arc);
ASSERT(nRetFlag == ARC_SEGMENT);
if (arc.GetLength() < g_Option::instance()._DIST_SNAP)
{
continue;
}
nCirDiv = GlobalFunc::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 ADSGePoint3d(pt));
}
}
}
return RTNORM;
}
void GePoly2D::Disperse1(GePoly2D &polyBase1, double dDeviation) const
{
GePoly 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 GePoly2D::AsOpenPoly1(GePoly &pts, double dDeviation) const
{
pts.Reset();
int nLen = Length();
int i = 0, n = 0, nNum = 0, nRetFlag = 0, nCirDiv = 0;
ADSGePoint3d pt;
double dincrement = 0.0;
GeArc arc;
ADSGePoint3d* pPtScr = NULL;
ADSGePoint3d* pPtScr0 = NULL;
for (i = 0; i < nLen; i++)
{
if (fabs(m_ardbulges[i]) < 1E-6)
{
pPtScr = new ADSGePoint3d((*this)[i]);
pts.Append(pPtScr);
if (i == nLen - 1 && IsClosed())
{
pPtScr0 = new ADSGePoint3d((*this)[0]);
pts.Append(pPtScr0);
}
}
else
{
if (!IsClosed() && i == nLen - 1)
{
pPtScr = new ADSGePoint3d((*this)[i]);
pts.Append(pPtScr);
return RTNORM;
}
GeLine l;
nRetFlag = Nth(i, l, arc);
ASSERT(nRetFlag == ARC_SEGMENT);
nCirDiv = GlobalFunc::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 ADSGePoint3d(pt));
}
}
}
return RTNORM;
}
double GePoly2D::PathDistance2d(ADSGePoint3d ptHit) const
{
double nRet = 0.0;
int nHitLeft = HitTestOnCurve(ptHit, g_Option::instance()._DIST_SNAP);
if (nHitLeft < 0)
{
int iLeft = abs(nHitLeft) - 1;
GeDirectionCurve 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++)
{
GeDirectionCurve leftHitCurve;
Nth(k, leftHitCurve);
nRet += leftHitCurve.GetLength();
}
}
return nRet;
}
int GePoly2D::CreatePface(int nCirDiv, const TCHAR *pszLay)
{
GePoly pts;
MapToPolygon(pts, nCirDiv);
return pts.CreatePface(pszLay);
}
int GePoly2D::GetExtend(ads_point lowPt, ads_point upPt) const
{
int nNum = TotalSegments();
if (!nNum)
{
return RTERROR;
}
GeCurveSegment seg;
ADSGePoint3d ptlow, ptup;
ptlow = ptup = ((*this)[0]);
for (int n = 0; n < nNum; n++)
{
if (Nth(n, seg) != RTNORM)
{
continue;
}
ADSGePoint3d pt1, pt2;
seg.GetExtend(pt1, pt2);
ptlow = Min(ptlow, pt1);
ptup = Max(ptup, pt2);
}
ptlow > lowPt;
ptup > upPt;
return RTNORM;
}
// 没有判断边重合的情况
BOOL GePoly2D::IsSelfIntersect() const
{
const GePoly2D &polyOutline = *this;
int nLen = polyOutline.Length();
GeArc arc;
for (int i = 0; i < nLen - 2; i++)
{
GeLine ln0(LS_FINITE);
polyOutline.Nth(i, ln0, arc);
if (ln0.GetLength() < g_Option::instance()._DIST_SNAP)
{
continue;
}
for (int j = i + 2; j < ((i == 0 && m_nFlag == 1) ? (nLen - 1) : nLen); j++)
{
GeLine ln1(LS_FINITE);
polyOutline.Nth(j, ln1, arc);
if (ln1.GetLength() < g_Option::instance()._DIST_SNAP)
{
continue;
}
ADSGePoint3d ptInt;
if (ln0.Intersection(&ln1, ptInt))
{
return TRUE;
}
}
}
return FALSE;
}
int GePoly2D::AppendSegment(const GeCurveSegment &curve, int bMinus, int bFinal)
{
if (bMinus)
{
Append(new ADSGePoint3d(curve.GetEndPoint()));
m_ardbulges.Append(new double(-curve.GetBulge()));
if (bFinal && !(m_nFlag & 0x01))
{
Append(new ADSGePoint3d(curve.GetStartPoint()));
m_ardbulges.Append(new double(0.0));
}
}
else
{
Append(new ADSGePoint3d(curve.GetStartPoint()));
m_ardbulges.Append(new double(curve.GetBulge()));
if (bFinal && !(m_nFlag & 0x01))
{
Append(new ADSGePoint3d(curve.GetEndPoint()));
m_ardbulges.Append(new double(0.0));
}
}
return RTNORM;
}
int GePoly2D::Compress(bool bUnionCurve)
{
if (Length() < 1)
{
return RTERROR;
}
const GePoly2D &poly = *this;
SHList<ADSGePoint3d> ptList;
SHList<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;
}
GePoly2D destPoly(m_nFlag);
int nTotalSeg = TotalSegments();
GeCurveSegment curve;
int bMinusCurve = 0, bMinusSeg = 0, bMerged = 0;
for (int n = 0; n < nTotalSeg; n++)
{
GeCurveSegment 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 = GlobalFunc::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);
GeCurveSegment curveFirst, curveFinal;
destPoly.Nth(0, curveFirst);
destPoly.Nth(nTotalDest - 1, curveFinal);
if (GlobalFunc::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 GePoly2D::Reverse()
{
if (Length() < 2)
{
return RTERROR;
}
GePoly2D destPoly;
int nTotalSeg = TotalSegments();
GeDirectionCurve 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 GePoly2D::Offset(ads_real dDist, GePoly2D &destPoly) const
{
int nTotalSeg = TotalSegments();
if (!nTotalSeg)
{
return RTERROR;
}
if (fabs(dDist) < g_Option::instance()._DIST_SNAP)
{
destPoly = *this;
return RTNORM;
}
destPoly.Reset();
destPoly.SetFlag(m_nFlag);
GeDirectionCurve finalMidSeg, lastSeg;
if (m_nFlag & 0x01)
{
Nth(nTotalSeg - 1, finalMidSeg);
lastSeg = finalMidSeg.Offset(dDist, LS_INFINITE);
if (!lastSeg)
{
return RTERROR;
}
}
ADSGePoint3d nextPt,pt1, pt2, curPt;
GeDirectionCurve curMidSeg, curSeg, nextMidSeg, nextSeg;
int nNum = 0, nextIndex = 0;
GeArc 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 = GeLine(pt1, pt2).NearPoint(curSeg.GetStartPoint());
}
else if (nNum == 1)
{
curPt = pt1;
}
else
{
if (IsSameDrt(curSeg.IDirection(0), lastSeg.IDirection(1), g_DimOption::instance()._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 = GeLine(pt1, pt2).NearPoint(curSeg.GetEndPoint());
}
else if (nNum == 1)
{
nextPt = pt1;
}
else
{
if (IsSameDrt(curSeg.IDirection(1), nextSeg.IDirection(0), g_DimOption::instance()._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 ADSGePoint3d(curPt));
destPoly.m_ardbulges.Append(new double(curSeg.GetBulge()));
if (i == nTotalSeg - 1 && !(m_nFlag & 0x01))
{
destPoly.Append(new ADSGePoint3d(nextPt));
destPoly.m_ardbulges.Append(new double(0.0));
}
}
return RTNORM;
}
int GePoly2D::HasArcSegment() const
{
for (int i = 0; i < TotalSegments(); i++)
{
if (fabs(m_ardbulges[i]) > 1.0E-6)
{
return 1;
}
}
return 0;
}
int GePoly2D::QuickOffset(ads_real dDist, GePoly2D &destPoly) const
{
const GePoly2D &basePoly = *this;
destPoly.Reset();
destPoly.m_nFlag = m_nFlag;
int nVertexNum = basePoly.Length();
GeDirectionCurve prevEdge;
int bIsClosed = ((basePoly.m_nFlag & 0x01) != 0);
if (bIsClosed)
{
basePoly.Nth(nVertexNum - 1, prevEdge);
}
ADSGePoint3d newVertex;
for (int j = 0; j < nVertexNum; j++)
{
GeDirectionCurve curEdge;
double dFromDirection, dToDirection;
if (j == nVertexNum - 1)
{
dToDirection = GlobalFunc::AngleRangeTo2PI(prevEdge.IDirection(1) - PI);
dFromDirection = prevEdge.IDirection(1);
if (bIsClosed)
{
basePoly.Nth(nVertexNum - 1, curEdge);
dFromDirection = GlobalFunc::AngleRangeTo2PI(curEdge.IDirection(0) - PI);
}
}
else
{
basePoly.Nth(j, curEdge);
dFromDirection = GlobalFunc::AngleRangeTo2PI(curEdge.IDirection(0) - PI);
dToDirection = curEdge.IDirection(0);
if (j > 0 || bIsClosed)
{
dToDirection = GlobalFunc::AngleRangeTo2PI(prevEdge.IDirection(1) - PI);
}
}
double dDirection = GeSector(dFromDirection, dToDirection).MidAngle();
const ADSGePoint3d &thisVertex = basePoly[j];
double dSinAng = fabs(sin(GlobalFunc::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;
}
ADSGePoint3d ptMid;
double dAbsBulge;
assert(TotalSegments() == destPoly.TotalSegments());
for (int i = 0; i < TotalSegments(); i++)
{
GeDirectionCurve cvSrc, cvDest, dv;
Nth(i, cvSrc);
destPoly.Nth(i, cvDest);
if (fabs(cvSrc.GetBulge()) > 1.0E-5)
{
GeDirectionCurve dv = cvSrc.Offset(dDist, LS_FINITE);
if (!dv)
{
return RTERROR;
}
dv.GetArc().MidPoint(ptMid);
GeArc 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* GePoly2D::AsRegion() const
{
const GePoly2D &poly = *this;
if (!poly.IsClosed())
{
return NULL;
}
AcDbPolyline pline;
GlobalFunc::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);
GlobalFunc::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);
GlobalFunc::ReleaseEntSet(regions2);
return regioni;
}
GlobalFunc::ReleaseEntSet(explodeSegments);
return NULL;
}
bool GePoly2D::IsRegionInclude(const GePoly2D& poly) const
{
GePoly2D 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 GePoly2D::IsRegionOverlap(const GePoly2D& poly) const
{
GePoly2D 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* GePoly2D::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 GePoly2D::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(ADSGePoint3d(pt.x, pt.y, dElev), dBulge);
}
if (pLwPoly->isClosed())
{
m_nFlag = 1;
}
else
{
m_nFlag = 0;
}
return true;
}
void GePoly2D::SetFlag(int nFlag)
{
m_nFlag = nFlag;
}
int GePoly2D::GetFlag() const
{
return m_nFlag;
}
void GePoly2D::RemoveBugle(int nIndex)
{
m_ardbulges.Remove(nIndex);
}
void GePoly2D::AppendBugle(ads_real dBugle)
{
m_ardbulges.Append( new double(dBugle));
}
double GePoly2D::GetBulge(int nIndex) const
{
return m_ardbulges[nIndex];
}
void GePoly2D::SetBulge(int nIndex, double dBugle)
{
*m_ardbulges[nIndex] = dBugle;
}
void GePoly2D::SetPointListAt(int nIndex, const ADSGePoint3d& pt)
{
if (Length() > nIndex)
{
*((*this)[nIndex]) = pt;
}
}
void GePoly2D::RemovePointListAt(int nIndex)
{
if (Length() > nIndex)
{
Remove(nIndex);
}
}
void GePoly2D::AppendPointListAt(ADSGePoint3d* pPt)
{
Append(pPt);
}
ADSGePoint3d* GePoly2D::GetPointListAt(int nIndex)
{
return (*this)[nIndex];
}
const ADSGePoint3d& GePoly2D::GetPointListAt(int nIndex) const
{
return (*this)[nIndex];
}
GePoly3D GePoly2D::PlaneToWcs(const AcGeVector3d& normal)const
{
GePoly3D poly3d = *this;
AcGeMatrix3d mat;
mat.setToPlaneToWorld(normal);
poly3d.TransformBy(mat);
return poly3d;
}
int GePoly2D::SetBulges(PtrList<double>& ardbulges)
{
if (ardbulges.Length() > 0)
{
m_ardbulges.Reset();
m_ardbulges.copyFrom(ardbulges);
return m_ardbulges.Length();
}
return -1;
}
int GePoly2D::GetBulges(PtrList<double>& ardbulges)
{
if (m_ardbulges.Length() > 0)
{
ardbulges.copyFrom(m_ardbulges);
return ardbulges.Length();
}
return -1;
}
PtrList<double>& GePoly2D::GetBulges()
{
return m_ardbulges;
}
bool GePoly2D::IsKindOf(GeEntity::TEntityId entType) const
{
switch(entType)
{
case GeEntity::eEntity:
case GeEntity::eCurve:
case GeEntity::ePoly2D:
return true;
}
return false;
}
GeEntity::TEntityId GePoly2D::Type() const
{
return GeEntity::ePoly2D;
}