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

3106 lines
64 KiB
C++

//-----------------------------------------------------------------------------+
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
// = FileName : TBPloyLine.cpp
// = Version : ver2.0
// = Author : xlc
// = CreateDate : 2002-09-09
// = Description: 类的定义
// = Maintainers:
//
//-----------------------------------------------------------------------------+
#include "StdAfx.h"
#include "TBPloyLine.h"
#include <geray3d.h>
#include "TchGlobalFunc.h"
#include "TchPrivateGlobalFunc.h"
TBPloyLine::TBPloyLine()
{
m_bClosed = 0;
}
TBPloyLine::TBPloyLine(const TBPloyLine& bline)
{
ReleaseBasLst();
POSITION pos = bline.m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = bline.m_BNodeList.GetNext(pos);
TBNode* pNodeNew = new TBNode;
*pNodeNew = *pNode;
m_BNodeList.AddTail(pNodeNew);
}
m_bClosed = bline.m_bClosed;
}
TBPloyLine::~TBPloyLine()
{
POSITION pos = m_BNodeList.GetTailPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetPrev(pos);
if (pNode != NULL)
{
delete pNode;
}
}
m_BNodeList.RemoveAll();
pos = m_DNodeList.GetTailPosition();
while (pos != NULL)
{
TDNode* pNode = m_DNodeList.GetPrev(pos);
if (pNode != NULL)
{
delete pNode;
}
}
m_DNodeList.RemoveAll();
}
BOOL TBPloyLine::IsClosed() const
{
return m_bClosed;
}
void TBPloyLine::ReleaseAll()
{
ReleaseBasLst();
ReleaseDivLst();
m_bClosed = 0;
}
void TBPloyLine::ReleaseBasLst()
{
POSITION pos = m_BNodeList.GetTailPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetPrev(pos);
if (pNode != NULL)
{
delete pNode;
}
}
m_BNodeList.RemoveAll();
}
void TBPloyLine::ReleaseDivLst()
{
POSITION pos = m_DNodeList.GetTailPosition();
while (pos != NULL)
{
TDNode* pNode = m_DNodeList.GetPrev(pos);
if (pNode != NULL)
{
delete pNode;
}
}
m_DNodeList.RemoveAll();
}
TBPloyLine& TBPloyLine::operator = (const TBPloyLine& basLine)
{
ReleaseBasLst();
m_bClosed = basLine.m_bClosed;
POSITION pos = basLine.m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = basLine.m_BNodeList.GetNext(pos);
if (pNode != NULL)
{
TBNode* pNodeNew = new TBNode;
*pNodeNew = *pNode;
m_BNodeList.AddTail(pNodeNew);
}
}
ReCalcSValue();
return *this;
}
void TBPloyLine::RmvOverlapPt(double tol)
{
if (IsEmpty())
{
return;
}
if (GetLength(1) < TOL)
{
TBNode* pHead = Head();
TBNode* pTail = Tail();
pHead->m_eType = BLINESEG;
if (pHead->m_pArc != NULL)
{
delete pHead->m_pArc;
pHead->m_pArc = NULL;
}
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
POSITION posTemp = pos;
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNode != pHead && pNode != pTail)
{
delete pNode;
m_BNodeList.RemoveAt(posTemp);
}
}
return;
}
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
POSITION posThis = pos;
TBNode* pNode = m_BNodeList.GetNext(pos);
TBNode* pNodeNext = NULL;
if (pos != NULL)
{
pNodeNext = m_BNodeList.GetAt(pos);
}
if (pNodeNext != NULL && IsEqual(pNode->m_pt,pNodeNext->m_pt,tol))
{
if (m_BNodeList.GetCount() > 2)
{
m_BNodeList.RemoveAt(posThis);
delete pNode;
}
}
}
}
BOOL TBPloyLine::InsertBLineInto(TBNode* pNode,TBPloyLine* pBLine,BOOL LinkEdgeUnvisible)
{
if (pBLine == NULL)
{
return 1;
}
if (IsEmpty())
{
POSITION pos1 = pBLine->m_BNodeList.GetHeadPosition();
while (pos1 != NULL)
{
TBNode* pNode1 = pBLine->m_BNodeList.GetNext(pos1);
TBNode* pNodeNew = new TBNode(pNode1);
m_BNodeList.AddTail(pNodeNew);
}
return 1;
}
if (pNode == NULL)
{
pNode = Tail();
}
TBNodeList tempList;
BOOL bNextVisible = pNode->m_bVisible;
pNode->m_bVisible = 0;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNodeHere = m_BNodeList.GetNext(pos);
tempList.AddTail(pNodeHere);
if (pNodeHere == pNode)
{
POSITION pos1 = pBLine->m_BNodeList.GetHeadPosition();
while (pos1 != NULL)
{
TBNode* pNode1 = pBLine->m_BNodeList.GetNext(pos1);
TBNode* pNodeNew = new TBNode(pNode1);
if (pos1 == NULL && LinkEdgeUnvisible)
{
pNodeNew->m_bVisible = 0;
}
tempList.AddTail(pNodeNew);
}
TBNode* pNodeHereNew = new TBNode(pNodeHere);
pNodeHereNew->m_bVisible = bNextVisible;
tempList.AddTail(pNodeHereNew);//多增加一个结点
}
}
m_BNodeList.RemoveAll();
m_BNodeList.AddTail(&tempList);
ClearUp();
ReCalcSValue();
return 1;
}
TBNode* TBPloyLine::GetNodeRangedAt(double ds,double deta,BOOL bPercent)
{
if (IsEmpty())
{
return NULL;
}
double tLen = GetLength();
if (bPercent)
{
deta = fabs(tLen * deta);
}
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
POSITION posTemp = pos;
TBNode* pNode = m_BNodeList.GetNext(pos);
if (fabs(pNode->m_s - ds) < deta)
{
return pNode;
}
}
return NULL;
}
void TBPloyLine::ResetHead(TBNode* pHead)
{
if (!pHead)
{
return;
}
if (!m_bClosed)
{
return;
}
if (m_BNodeList.GetCount() == 0)
{
return;
}
TBNode* pNodeH = m_BNodeList.GetHead();
if (pNodeH == pHead)
{
return;
}
TBNodeList list1,list2;
BOOL bfront = 1;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNode == pHead)
{
bfront = 0;
}
if (bfront)
{
list1.AddTail(pNode);
}
else if (pos != NULL)
{
list2.AddTail(pNode);
}
}
TBNode* pTail1 = list1.GetTail();
TBNode* pNewTail = new TBNode(pTail1->m_eType,0.,pHead->m_pt);
list1.AddTail(pNewTail);
m_BNodeList.RemoveAll();
m_BNodeList.AddTail(&list2);
m_BNodeList.AddTail(&list1);
ReCalcSValue();
}
void TBPloyLine::ClearUp(double tol)
{
if (IsEmpty())
{
return;
}
RmvOverlapPt(tol);
MergeCoLine(tol);
}
void TBPloyLine::MergeCoArc(double tol)
{
if (IsEmpty())
{
return;
}
if (GetLength(1) < TOL)
{
TBNode* pHead = Head();
TBNode* pTail = Tail();
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
POSITION posTemp = pos;
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNode != pHead && pNode != pTail)
{
delete pNode;
m_BNodeList.RemoveAt(posTemp);
}
}
return;
}
TBNode* pNodePrev = NULL;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
POSITION posThis = pos;
TBNode* pNode = m_BNodeList.GetNext(pos);
TBNode* pNodeNext = NULL;
if (pos != NULL)
{
pNodeNext = m_BNodeList.GetAt(pos);
}
if (pNodePrev != NULL && pNodePrev->m_eType == BARCSEG &&
pNode->m_eType == BARCSEG && pNodePrev->m_pArc != NULL && pNode->m_pArc != NULL)
{
if (IsEqual(pNodePrev->m_pArc->m_centPt,pNode->m_pArc->m_centPt,tol) &&
(fabs(pNodePrev->m_pArc->m_R-pNode->m_pArc->m_R)<tol) &&
IsEqualSign(pNodePrev->m_pArc->m_centAngle,pNode->m_pArc->m_centAngle))
{
pNodePrev->m_pArc->m_centAngle += pNode->m_pArc->m_centAngle;
if (pNodeNext != NULL)
{
m_BNodeList.RemoveAt(posThis);
delete pNode;
pos = m_BNodeList.Find(pNodeNext);
continue;
}
else
{//末端点
delete pNode->m_pArc;
pNode->m_pArc = NULL;
}
}
}
pNodePrev = pNode;
}
if ((m_BNodeList.GetCount() > 2) && IsClosed())//去除首尾处多余的点。
{
TBNode* pNode = m_BNodeList.GetHead();
POSITION pos = m_BNodeList.GetTailPosition();
TBNode* pTailNode = m_BNodeList.GetPrev(pos);
TBNode* pNodePrev = m_BNodeList.GetAt(pos);
if (pNodePrev->m_eType == BARCSEG && pNode->m_eType == BARCSEG
&& pNodePrev->m_pArc != NULL && pNode->m_pArc != NULL)
{
if (IsEqual(pNodePrev->m_pArc->m_centPt,pNode->m_pArc->m_centPt,tol) &&
(fabs(pNodePrev->m_pArc->m_R-pNode->m_pArc->m_R)<tol) &&
IsEqualSign(pNodePrev->m_pArc->m_centAngle,pNode->m_pArc->m_centAngle))
{
pNode->m_pt = pNodePrev->m_pt;
pNode->m_pArc->m_startAngle = pNodePrev->m_pArc->m_startAngle;
pNode->m_pArc->m_centAngle += pNodePrev->m_pArc->m_centAngle;
pNodePrev->m_eType = BLINESEG;
delete pNodePrev->m_pArc;
pNodePrev->m_pArc = NULL;
m_BNodeList.RemoveTail();
delete pTailNode;
}
}
}
ReCalcSValue();
}
void TBPloyLine::MergeCoLine(double tol)
{
if (IsEmpty())
{
return;
}
if (GetLength(1) < TOL)
{
TBNode* pHead = Head();
TBNode* pTail = Tail();
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
POSITION posTemp = pos;
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNode != pHead && pNode != pTail)
{
delete pNode;
m_BNodeList.RemoveAt(posTemp);
}
}
return;
}
AcGeTol tol1;
tol1.setEqualPoint(tol);
TBNode* pNodePrev = NULL;
TBNode* pNodeNext = NULL;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
POSITION posTemp = pos;
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pos == NULL)
{
pNodeNext = NULL;
}
else
{
pNodeNext = m_BNodeList.GetAt(pos);
}
if (pNodePrev == NULL && pNodeNext != NULL && m_bClosed)
{//第一接点且封闭
TBNode* pNodePrevPrev = NULL;
POSITION pos1 = m_BNodeList.GetTailPosition();
if (pos1 != NULL)
{
pNodePrev = m_BNodeList.GetPrev(pos1);
}
if (pos1 != NULL)
{
pNodePrevPrev = m_BNodeList.GetPrev(pos1);
}
if (pNodePrevPrev != NULL && pNodePrevPrev != pNode)
{
AcGeLine3d line(pNodePrevPrev->m_pt,pNode->m_pt);
if (line.isOn(pNodeNext->m_pt,tol1) == Adesk::kTrue)
{
pNode->m_pt = pNodePrevPrev->m_pt;
delete pNodePrev;
m_BNodeList.RemoveAt(m_BNodeList.GetTailPosition());
pNodePrev = NULL;
pos = m_BNodeList.GetHeadPosition();
continue;
}
}
}
else if (pNodeNext != NULL && pNodePrev != NULL && pNodePrev->m_eType == BLINESEG && pNode->m_eType == BLINESEG)
{
AcGeLine3d line(pNodePrev->m_pt,pNode->m_pt);
if (line.isOn(pNodeNext->m_pt,tol1) == Adesk::kTrue)
{
delete pNode;
m_BNodeList.RemoveAt(posTemp);
pos = m_BNodeList.Find(pNodeNext);
continue;
}
}
pNodePrev = pNode;
}
ReCalcSValue();
}
TBPloyLine TBPloyLine::operator + (const TBPloyLine& basLine) const
{
if (IsEmpty())
{
return basLine;
}
if (basLine.IsEmpty())
{
return *this;
}
if (m_bClosed || basLine.m_bClosed)
{
return *this;
}
TBPloyLine blineThis(*this);
TBPloyLine blinePara(basLine);
TBNode* pHead1 = blineThis.m_BNodeList.GetHead();
TBNode* pTail1 = blineThis.m_BNodeList.GetTail();
TBNode* pHead2 = blinePara.m_BNodeList.GetHead();
TBNode* pTail2 = blinePara.m_BNodeList.GetTail();
if (pHead2 == NULL)
{
return *this;
}
if (pHead1 == NULL)
{
return blinePara;
}
if (IsEqual(pTail1->m_pt,pHead2->m_pt,TOL))
{
;
}
else if (IsEqual(pTail1->m_pt,pTail2->m_pt,TOL))
{
blinePara.Reverse();
}
else if (IsEqual(pHead1->m_pt,pHead2->m_pt,TOL))
{
blineThis.Reverse();
}
else if (IsEqual(pHead1->m_pt,pTail2->m_pt,TOL))
{
blineThis.Reverse();
blinePara.Reverse();
}
else
{
return *this;
}
TBPloyLine BLine;
POSITION pos = blineThis.m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = blineThis.m_BNodeList.GetNext(pos);
if (pos == NULL)
{
break;
}
TBNode* pNodeNew = new TBNode;
*pNodeNew = *pNode;
BLine.m_BNodeList.AddTail(pNodeNew);
}
pos = blinePara.m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = blinePara.m_BNodeList.GetNext(pos);
TBNode* pNodeNew = new TBNode;
*pNodeNew = *pNode;
BLine.m_BNodeList.AddTail(pNodeNew);
}
BLine.ReCalcSValue();
return BLine;
}
TBPloyLine& TBPloyLine::Reverse()
{
if (m_BNodeList.IsEmpty())
{
return *this;
}
TBNodeList tempList;
TBNode *pNodePre, *pNode;
double totLength;
POSITION pos = m_BNodeList.GetTailPosition();
pNode = m_BNodeList.GetPrev(pos);
totLength = pNode->m_s;
if (pNode->m_pArc != NULL)
{
if (pos == NULL)
{
delete pNode->m_pArc;
}
else if (pNode->m_pArc != m_BNodeList.GetAt(pos)->m_pArc)
{
delete pNode->m_pArc;
}
pNode->m_pArc = NULL;
}
for(pos = m_BNodeList.GetTailPosition(); pos; )
{
pNode = m_BNodeList.GetPrev(pos);
pNodePre = NULL;
if (pos != NULL)
{
pNodePre = m_BNodeList.GetAt(pos);
}
if (pNodePre != NULL)
{//不是第一点
pNode->m_s = totLength-pNode->m_s;
if (pNodePre->m_eType == BLINESEG)
{
pNode->m_eType = BLINESEG;
pNode->m_pArc = NULL;
}
else
{
pNode->m_pArc = pNodePre->m_pArc;
if (pNode->m_pArc != NULL)
{
pNode->m_eType = BARCSEG;
double startAng = pNode->m_pArc->m_startAngle + pNode->m_pArc->m_centAngle;
while (startAng >= 2 * PI)
{
startAng -= 2 * PI;
}
while (startAng < 0)
{
startAng += 2 * PI;
}
pNode->m_pArc->m_startAngle = startAng;
pNode->m_pArc->m_centAngle = -pNode->m_pArc->m_centAngle;
}
else
{
pNode->m_eType = BLINESEG;
}
}
}
else
{//原来的第一点
pNode->m_s = totLength;
pNode->m_eType = BLINESEG;
pNode->m_pArc = NULL;
}
tempList.AddTail(pNode);
}
//在链表中的位置反向
m_BNodeList.RemoveAll();
m_BNodeList.AddTail(&tempList);
tempList.RemoveAll();
return *this;
}
BOOL TBPloyLine::CheckClose()
{
if (IsEmpty())
{
m_bClosed = 0;
return 0;
}
if (GetLength() < TOL)
{
return 0;
}
TBNode* pStartNode = m_BNodeList.GetHead();
TBNode* pEndNode = m_BNodeList.GetTail();
double dist = (pEndNode->m_pt - pStartNode->m_pt).length();
if (( dist <= TOL) && (pEndNode != pStartNode))
{
m_bClosed = 1;
}
else
{
m_bClosed = 0;
}
return m_bClosed;
}
int TBPloyLine::IsWhere(TBPloyLine* pBLine)
{
if (pBLine == NULL)
{
return -1;
}
TBPloyLine BLine(*pBLine);
BLine.LinearizePLine(PI / 36.);
int bInternal0 = 1,count = 1,bInternal,HasOnePointIn = 0,HasOnePointOut = 0;
for(POSITION ps = BLine.m_BNodeList.GetHeadPosition(); ps;)
{
AcGePoint3d pt = BLine.m_BNodeList.GetNext(ps)->m_pt;
bInternal = IsPtInPolygon(pt);
if (count == 1)
{
bInternal0 = bInternal;
if (bInternal0 == 1)
{
HasOnePointIn = 1;
}
else if (bInternal0 == 0)
{
HasOnePointOut = 1;
}
count++;
continue;
}
else
{
if (bInternal0 == 0 && bInternal == 1 || bInternal0 == 1 && bInternal == 0)
{
return 3;//相交
}
bInternal0 = bInternal;
if (bInternal0 == 1)
{
HasOnePointIn = 1;
}
else if (bInternal0 == 0)
{
HasOnePointOut = 1;
}
}
}
if (HasOnePointOut)
{//BLine在THIS外部
return 2;
}
else
{//BLine在THIS内部
return 1;
}
}
BOOL TBPloyLine::Create(const TGGePolygonEx& polySrc)
{
TGGePolygonEx poly(polySrc);
int nCount = poly.Length();
if (nCount < 2)
{
return FALSE;
}
double SLength = 0.0;
TBNode* pNodePrevious = NULL;
AcGePoint3d pt1;
for(int i = 0; i < nCount; i++)
{
pt1 = (*poly[i]).AsAcGePoint3d();
if (pNodePrevious)
{
SLength += pNodePrevious->m_pt.distanceTo(pt1);
}
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
//wlw临时注释,3d炸碎崩
pNode->m_bVisible = *(poly.GetVisibleFlag()[i]);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
//封闭最后一点和第一点
pt1 = (*poly[0]).AsAcGePoint3d();
SLength += pNodePrevious->m_pt.distanceTo(pt1);
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
pNode->m_bVisible = *(poly.GetVisibleFlag()[nCount - 1]);
m_BNodeList.AddTail(pNode);
m_bClosed = TRUE;
return TRUE;
}
BOOL TBPloyLine::Create(const TGGePoly2D& poly)
{
//方法2:直接转换(高效率),缺点是不考虑poly的弧度
int nCount = poly.Length();
if (nCount < 2)
{
return FALSE;
}
double SLength = 0.0;
TBNode* pNodePrevious = NULL;
for(int i = 0; i < nCount; i++)
{
AcGePoint3d pt1 = poly[i];
if (pNodePrevious)
{
SLength += pNodePrevious->m_pt.distanceTo(pt1);
}
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
//封闭最后一点和第一点
if(poly.IsClosed())
{
AcGePoint3d pt1 = poly[0];
SLength += pNodePrevious->m_pt.distanceTo(pt1);
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
m_bClosed = TRUE;
}
return TRUE;
}
//新增函数,支持LINE,PLINE,CIRCLE,TRACE
BOOL TBPloyLine::Create(const AcDbEntity* pEntity)
{
if (pEntity == NULL)
{
return FALSE;
}
ReleaseBasLst();
double startUCSAng = 0;
int ret = 1;
if(pEntity->isKindOf(AcDbLine::desc()))
{
AcDbLine *pLine = AcDbLine::cast(pEntity);
if (pLine != NULL)
{
AcGePoint3d pt1 = pLine->startPoint();
AcGePoint3d pt2 = pLine->endPoint();
TBNode* pNode = new TBNode(BLINESEG,0.0,pt1);
m_BNodeList.AddTail(pNode);
double len = pt1.distanceTo(pt2);
pNode = new TBNode(BLINESEG,len,pt2);
m_BNodeList.AddTail(pNode);
}
}
else if(pEntity->isKindOf(AcDbArc::desc()))
{
AcDbArc *pArc = AcDbArc::cast(pEntity);
if (pArc != NULL)
{
AcGePoint3d cent = pArc->center();
double startAng = pArc->startAngle();
double endAng = pArc->endAngle();
//圆心角
double EntcAng;
if (endAng >= startAng)
{
EntcAng = endAng - startAng;
}
else
{
EntcAng = 2 * PI + endAng - startAng;
}
double radius = pArc->radius();
TBArc* pArcTemp = new TBArc(cent,radius,startAng,EntcAng);//ECS
AcGePoint3d ptStart = pArcTemp->GetStartPoint();//ECS
AcGePoint3d ptEnd = pArcTemp->GetEndPoint();//ECS
delete pArcTemp;
ads_point ads_pt1,ads_pt2,ads_pt3;
ARX2AdsPt(cent,ads_pt1);
ARX2AdsPt(ptStart,ads_pt2);
ARX2AdsPt(ptEnd,ads_pt3);
startAng = acutAngle(ads_pt1,ads_pt2);//UCS
endAng = acutAngle(ads_pt1,ads_pt3);//UCS
TBArc* pBLArc = new TBArc(cent,radius,startAng,EntcAng);
TBNode* pNode = new TBNode(BARCSEG,0.0,pBLArc->GetStartPoint(),pBLArc);
m_BNodeList.AddTail(pNode);
pNode = new TBNode(BARCSEG,pBLArc->Length(),pBLArc->GetEndPoint());
m_BNodeList.AddTail(pNode);
}
}
else if(pEntity->isKindOf(AcDbCircle::desc()))
{
AcDbCircle *pCircle = AcDbCircle::cast(pEntity);
if (pCircle != NULL)
{
//当是圆时,需要指定UCS起始角。
AcGePoint3d cent = pCircle->center();
//圆心角
double EntcAng = 2 * PI;
m_bClosed = 1;
TBArc* pBLArc = new TBArc(cent,pCircle->radius(),startUCSAng,EntcAng);
TBNode* pNode = new TBNode(BARCSEG,0.0,pBLArc->GetStartPoint(),pBLArc);
m_BNodeList.AddTail(pNode);
pNode = new TBNode(BARCSEG,pBLArc->Length(),pBLArc->GetEndPoint());
m_BNodeList.AddTail(pNode);
}
}
else if(pEntity->isKindOf(AcDbTrace::desc()))
{
AcDbTrace *pTrace = AcDbTrace::cast(pEntity);
if (pTrace != NULL)
{
AcGePoint3d pt1,pt2,pt3,pt4,ptStart,ptEnd;
pTrace->getPointAt(0,pt1);
pTrace->getPointAt(1,pt2);
pTrace->getPointAt(2,pt3);
pTrace->getPointAt(3,pt4);
ptStart.x = (pt1.x + pt2.x) / 2.;
ptStart.y = (pt1.y + pt2.y) / 2.;
ptEnd.x = (pt3.x + pt4.x) / 2.;
ptEnd.y = (pt3.y + pt4.y) / 2.;
TBNode* pNode = new TBNode(BLINESEG,0.0,ptStart);
m_BNodeList.AddTail(pNode);
double len = ptStart.distanceTo(ptEnd);
pNode = new TBNode(BLINESEG,len,ptEnd);
m_BNodeList.AddTail(pNode);
}
}
else if(pEntity->isKindOf(AcDbPolyline::desc()))
{
AcDbPolyline *pPoly = AcDbPolyline::cast(pEntity);
if (pPoly != NULL)
{
double SLength = 0.;
int nVerts = pPoly->numVerts();
if (nVerts < 2)
{
return 0;
}
double Level = pPoly->elevation();
TBNode* pNodePrevious = NULL;
for (int i = 0; i < nVerts; i++)
{
AcDbPolyline::SegType eSegType = pPoly->segType(i);
double Bulge = 0.0;
if (pPoly->getBulgeAt(i, Bulge) != Acad::eOk)
{
return 0;
}
AcGePoint2d pt2d;
if (pPoly->getPointAt(i, pt2d) != Acad::eOk)
{
return 0;
}
AcGePoint3d pt1, pt2;
pt1.set(pt2d.x, pt2d.y, Level);
if (pNodePrevious)
{
if (pNodePrevious->m_pArc)
{
SLength += pNodePrevious->m_pArc->m_R * fabs(pNodePrevious->m_pArc->m_centAngle);
}
else
{
SLength += pNodePrevious->m_pt.distanceTo(pt1);
}
}
if (eSegType != AcDbPolyline::kArc || fabs(Bulge) < fTOL)
{
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
else
{
if (i != nVerts - 1)
{
if (pPoly->getPointAt(i+1, pt2d) != Acad::eOk)
{
return 0;
}
}
else
{
if (pPoly->getPointAt(0, pt2d) != Acad::eOk)
{
return 0;
}
}
pt2.set(pt2d.x, pt2d.y, Level);
double CenterAng = 4 * atan(Bulge);
double angx, ang1, ang2;
angx = AngleToX(pt1, pt2);
if (Bulge > 0)
{
ang1 = angx + (PI - CenterAng) / 2.0;
ang2 = ang1 + CenterAng;
}
else
{
ang1 = angx - (PI + CenterAng) / 2.0;
ang2 = ang1 + CenterAng;
}
while (ang1 >= 2 * PI) ang1 -= 2 * PI;
while (ang1 < 0) ang1 += 2 * PI;
while (ang2 >= 2 * PI) ang2 -= 2 * PI;
while (ang2 < 0) ang2 += 2 * PI;
AcGePoint3d pt0, pt11, pt22, pt12, pt3, pt13, pt23;
double angxx, ll = pt1.distanceTo(pt2) / 2.0;
pt12.x = (pt1.x + pt2.x) / 2.0;
pt12.y = (pt1.y + pt2.y) / 2.0;
pt12.z = (pt1.z + pt2.z) / 2.0;
if (Bulge>0)
{
angxx = angx - PI / 2.0;
while (angxx < 0)
{
angxx += 2 * PI;
}
}
else
{
angxx = angx + PI / 2.0;
while (angxx >= 2 * PI)
{
angxx -= 2 * PI;
}
}
pt3 = polar(pt12, angxx, ll*fabs(Bulge));
pt13.x = (pt1.x+pt3.x) / 2.0;
pt13.y = (pt1.y+pt3.y) / 2.0;
pt13.z = (pt1.z+pt3.z) / 2.0;
pt23.x = (pt2.x+pt3.x) / 2.0;
pt23.y = (pt2.y+pt3.y) / 2.0;
pt23.z = (pt2.z+pt3.z) / 2.0;
angxx = AngleToX(pt1, pt3) + PI / 2.0;
while (angxx >= 2 * PI)
{
angxx -= 2 * PI;
}
pt11 = polar(pt13, angxx, ll);
angxx = AngleToX(pt3, pt2) + PI / 2.0;
while (angxx >= 2 * PI)
{
angxx -= 2 * PI;
}
pt22 = polar(pt23, angxx, ll);
ads_point ads_pt1, ads_pt11, ads_pt2, ads_pt22, ads_pt0;
ARX2AdsPt(pt13, ads_pt1);
ARX2AdsPt(pt11, ads_pt11);
ARX2AdsPt(pt23, ads_pt2);
ARX2AdsPt(pt22, ads_pt22);
if (acdbInters(ads_pt1, ads_pt11, ads_pt2, ads_pt22, FALSE, ads_pt0) == RTNORM)
{
Ads2ARXPt(ads_pt0, pt0);
}
else
{
return 0;
}
ang1 += PI;
ang2 += PI;
while (ang1 >= 2 * PI)
{
ang1 -= 2 * PI;
}
while (ang2 >= 2 * PI)
{
ang2 -= 2 * PI;
}
double radius = pt0.distanceTo(pt1);
TBArc* pBLArc = new TBArc;
pBLArc->m_centPt = pt0;
pBLArc->m_R = radius;
pBLArc->m_startAngle = ang1;
pBLArc->m_centAngle = CenterAng;
pBLArc->m_startPt = pt1;
pBLArc->m_endPt = pt2;
TBNode* pNode = new TBNode(BARCSEG,SLength,pt1,pBLArc);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
}
if (pPoly->isClosed())
{
AcGePoint2d pt2d;
if (pPoly->getPointAt(0, pt2d) != Acad::eOk)
{
return 0;
}
AcGePoint3d pt1, pt2;
pt1.set(pt2d.x, pt2d.y, Level);
if (pNodePrevious->m_pArc)
{
SLength+=pNodePrevious->m_pArc->m_R*fabs(pNodePrevious->m_pArc->m_centAngle);
}
else
{
SLength+=pNodePrevious->m_pt.distanceTo(pt1);
}
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
}
}
else if(pEntity->isKindOf(AcDb2dPolyline::desc()))
{
AcDb2dPolyline *pPoly = AcDb2dPolyline::cast(pEntity);
if(pPoly != NULL)
{
AcDbObjectIterator *pVertIter = pPoly->vertexIterator();
double SLength = 0.;
AcDbObjectId vertxId;
AcDb2dVertex *pVertex;
TBNode* pNodePrevious = NULL;
AcGePoint3d FirstPt;
double Level = pPoly->elevation();
BOOL bLast = 0;
for (int vertexNumber = 0; !pVertIter->done();vertexNumber++, pVertIter->step())
{
vertxId = pVertIter->objectId();
if (acdbOpenObject(pVertex, vertxId,AcDb::kForRead) != Acad::eOk)
{
return 0;
}
if (vertexNumber == 0)
{
FirstPt = pVertex->position();
}
double Bulge = pVertex->bulge();//凸度
AcGePoint3d pt1,pt2;
pt1 = pVertex->position();//ECS
pVertex->close();
pVertIter->step();
if (!pVertIter->done())
{//不是最后一点
AcDbObjectId vertxId2 = pVertIter->objectId();
AcDb2dVertex *pVertex2 = NULL;
if (acdbOpenObject(pVertex2, vertxId2,AcDb::kForRead) != Acad::eOk)
{
return 0;
}
pt2 = pVertex2->position();//ECS
pVertex2->close();
}
else
{
bLast = 1;
pt2 = FirstPt;
}
pVertIter->step(true);
pt1.z = Level;
pt2.z = Level;
if (pNodePrevious)
{
if (pNodePrevious->m_pArc)
{
SLength += pNodePrevious->m_pArc->m_R * fabs(pNodePrevious->m_pArc->m_centAngle);
}
else
{
SLength+=pNodePrevious->m_pt.distanceTo(pt1);
}
}
if (bLast && !pPoly->isClosed())
{
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
break;
}
if (fabs(Bulge) < fTOL)
{
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
if (bLast)
{
SLength += pt2.distanceTo(pt1);
TBNode* pNode = new TBNode(BLINESEG,SLength,pt2);
m_BNodeList.AddTail(pNode);
}
pNodePrevious = pNode;
}
else
{
double CenterAng = 4 * atan(Bulge);
double angx, ang1, ang2;
angx = AngleToX(pt1, pt2);
if (Bulge > 0)
{
ang1 = angx + (PI - CenterAng) / 2.0;
ang2 = ang1 + CenterAng;
}
else
{
ang1 = angx - (PI + CenterAng) / 2.0;
ang2 = ang1 + CenterAng;
}
while (ang1 >= 2 * PI)
{
ang1 -= 2 * PI;
}
while (ang1 < 0)
{
ang1 += 2 * PI;
}
while (ang2 >= 2 * PI)
{
ang2 -= 2 * PI;
}
while (ang2 < 0)
{
ang2 += 2 * PI;
}
AcGePoint3d pt0, pt11, pt22, pt12, pt3, pt13, pt23;
double angxx, ll = pt1.distanceTo(pt2) / 2.0;
pt12.x = (pt1.x + pt2.x) / 2.0;
pt12.y = (pt1.y + pt2.y) / 2.0;
pt12.z = (pt1.z + pt2.z) / 2.0;
if (Bulge > 0)
{
angxx = angx - PI / 2.0;
while (angxx < 0)
{
angxx += 2 * PI;
}
}
else
{
angxx = angx + PI / 2.0;
while (angxx >= 2 * PI)
{
angxx -= 2 * PI;
}
}
pt3 = polar(pt12, angxx, ll * fabs(Bulge));
pt13.x = (pt1.x + pt3.x) / 2.0;
pt13.y = (pt1.y + pt3.y) / 2.0;
pt13.z = (pt1.z + pt3.z) / 2.0;
pt23.x = (pt2.x + pt3.x) / 2.0;
pt23.y = (pt2.y + pt3.y) / 2.0;
pt23.z = (pt2.z + pt3.z) / 2.0;
angxx = AngleToX(pt1, pt3) + PI / 2.0;
while (angxx >= 2*PI)
{
angxx -= 2 * PI;
}
pt11 = polar(pt13, angxx, ll);
angxx = AngleToX(pt3, pt2) + PI / 2.0;
while (angxx >= 2 * PI)
{
angxx -= 2 * PI;
}
pt22 = polar(pt23, angxx, ll);
ads_point ads_pt1, ads_pt11, ads_pt2, ads_pt22, ads_pt0;
ARX2AdsPt(pt13, ads_pt1);
ARX2AdsPt(pt11, ads_pt11);
ARX2AdsPt(pt23, ads_pt2);
ARX2AdsPt(pt22, ads_pt22);
if (acdbInters(ads_pt1, ads_pt11, ads_pt2, ads_pt22, FALSE, ads_pt0) == RTNORM)
{
Ads2ARXPt(ads_pt0, pt0);
}
else
{
return 0;
}
ang1 += PI;
ang2 += PI;
while (ang1 >= 2*PI)
{
ang1 -= 2*PI;
}
while (ang2 >= 2*PI)
{
ang2 -= 2*PI;
}
double radius = pt0.distanceTo(pt1);
TBArc* pBLArc = new TBArc;
pBLArc->m_centPt = pt0;
pBLArc->m_R = radius;
pBLArc->m_startAngle = ang1;
pBLArc->m_centAngle = CenterAng;
pBLArc->m_startPt = pt1;
pBLArc->m_endPt = pt2;
TBNode* pNode = new TBNode(BARCSEG,SLength,pt1,pBLArc);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
}
if (pPoly->isClosed())
{
AcGePoint3d pt1 = FirstPt;
if (pNodePrevious->m_pArc)
{
SLength += pNodePrevious->m_pArc->m_R * fabs(pNodePrevious->m_pArc->m_centAngle);
}
else
{
SLength += pNodePrevious->m_pt.distanceTo(pt1);
}
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
}
}
else
{
return 0;
}
TBNode* pStartNode = m_BNodeList.GetHead();
TBNode* pEndNode = m_BNodeList.GetTail();
double dist = (pEndNode->m_pt - pStartNode->m_pt).length();
if (!pEntity->isKindOf(AcDbCircle::desc()))
{
if (( dist <= TOL) && (pEndNode != pStartNode))
{
m_bClosed = 1;
}
else
{
m_bClosed = 0;
}
}
return 1;
}
BOOL TBPloyLine::Create(AcDbObjectId& objId)
{
if (objId == NULL)
{
return 0;
}
double startUCSAng = 0;
ReleaseBasLst();
AcDbEntity* pEntity;
Acad::ErrorStatus retStat;
if ((retStat = acdbOpenObject(pEntity, objId, AcDb::kForRead)) != Acad::eOk)
{
acutPrintf(_T("acdbOpenEntity failed! retStat:%d"), retStat);
return 0;
}
CString strLineType = pEntity->isA()->dxfName();
int isParal = IsZParalECSAndUcs(objId);
if (!isParal && strLineType != _T("LINE"))
{//判断实体坐标系与用户坐标系的Z轴是否平行
AfxMessageBox(_T("ECS与UCS的Z轴不平行!"));
pEntity->close();
return 0;
}
int ret = 1;
if (strLineType == _T("LINE"))
{
AcDbLine* pLine = (AcDbLine*)(pEntity);
AcGePoint3d pt1 = pLine->startPoint();
AcGePoint3d pt2 = pLine->endPoint();
WCS2UCS(pt1);
WCS2UCS(pt2);
TBNode* pNode = new TBNode(BLINESEG,0.0,pt1);
m_BNodeList.AddTail(pNode);
double len = pt1.distanceTo(pt2);
pNode = new TBNode(BLINESEG,len,pt2);
m_BNodeList.AddTail(pNode);
}
else if (strLineType == _T("ARC"))
{
AcDbArc* pArc = (AcDbArc*)(pEntity);
AcGePoint3d cent = pArc->center();
double startAng = pArc->startAngle();
double endAng = pArc->endAngle();
double EntcAng; //圆心角
if (endAng >= startAng)
{
EntcAng = endAng - startAng;
}
else
{
EntcAng = 2 * PI + endAng - startAng;
}
if (isParal == 2)
{
EntcAng = -EntcAng;//反向
}
double radius = pArc->radius();
WCS2ECS(cent,objId);//先从WCS到ECS
TBArc* pArcTemp = new TBArc(cent,radius,startAng,EntcAng);//ECS
AcGePoint3d ptStart = pArcTemp->GetStartPoint();//ECS
AcGePoint3d ptEnd = pArcTemp->GetEndPoint();//ECS
delete pArcTemp;
ECS2UCS(cent,objId);//UCS
ECS2UCS(ptStart,objId);//UCS
ECS2UCS(ptEnd,objId);//UCS
ads_point ads_pt1,ads_pt2,ads_pt3;
ARX2AdsPt(cent,ads_pt1);
ARX2AdsPt(ptStart,ads_pt2);
ARX2AdsPt(ptEnd,ads_pt3);
startAng = acutAngle(ads_pt1,ads_pt2);//UCS
endAng = acutAngle(ads_pt1,ads_pt3);//UCS
TBArc* pBLArc = new TBArc(cent,radius,startAng,EntcAng);
TBNode* pNode = new TBNode(BARCSEG,0.0,pBLArc->GetStartPoint(),pBLArc);
m_BNodeList.AddTail(pNode);
pNode = new TBNode(BARCSEG,pBLArc->Length(),pBLArc->GetEndPoint());
m_BNodeList.AddTail(pNode);
}
else if (strLineType == _T("CIRCLE"))
{//当是圆时,需要指定UCS起始角。
AcDbCircle* pCircle = (AcDbCircle*)(pEntity);
AcGePoint3d cent = pCircle->center();
WCS2UCS(cent);
double EntcAng = 2 * PI;//圆心角
m_bClosed = 1;
TBArc* pBLArc = new TBArc(cent,pCircle->radius(),startUCSAng,EntcAng);
TBNode* pNode = new TBNode(BARCSEG,0.0,pBLArc->GetStartPoint(),pBLArc);
m_BNodeList.AddTail(pNode);
pNode = new TBNode(BARCSEG,pBLArc->Length(),pBLArc->GetEndPoint());
m_BNodeList.AddTail(pNode);
}
else if (strLineType == _T("TRACE"))
{
AcDbTrace* pTrace = (AcDbTrace*)(pEntity);
AcGePoint3d pt1,pt2,pt3,pt4,ptStart,ptEnd;
pTrace->getPointAt(0,pt1);
pTrace->getPointAt(1,pt2);
pTrace->getPointAt(2,pt3);
pTrace->getPointAt(3,pt4);
ptStart.x = (pt1.x + pt2.x) / 2.;
ptStart.y = (pt1.y + pt2.y) / 2.;
ptEnd.x = (pt3.x + pt4.x) / 2.;
ptEnd.y = (pt3.y + pt4.y) / 2.;
WCS2UCS(ptStart);
WCS2UCS(ptEnd);
TBNode* pNode = new TBNode(BLINESEG,0.0,ptStart);
m_BNodeList.AddTail(pNode);
double len = ptStart.distanceTo(ptEnd);
pNode = new TBNode(BLINESEG,len,ptEnd);
m_BNodeList.AddTail(pNode);
}
else if (strLineType == _T("LWPOLYLINE"))
{
AcDbPolyline* pPoly = (AcDbPolyline*)(pEntity);
double SLength = 0.;
int nVerts = pPoly->numVerts();
if (nVerts < 2)
{
pEntity->close();
return 0;
}
double Level = pPoly->elevation();
TBNode* pNodePrevious = NULL;
for (int i = 0; i < nVerts; i++)
{
AcDbPolyline::SegType eSegType = pPoly->segType(i);
double Bulge = 0.0;
if (pPoly->getBulgeAt(i, Bulge) != Acad::eOk)
{
pEntity->close();
return 0;
}
if (isParal == 2)
{
Bulge = -Bulge;
}
AcGePoint2d pt2d;
if (pPoly->getPointAt(i, pt2d) != Acad::eOk)
{
pEntity->close();
return 0;
}
AcGePoint3d pt1, pt2;
pt1.set(pt2d.x, pt2d.y, Level);
ECS2UCS(pt1, objId);//UCS
if (pNodePrevious)
{
if (pNodePrevious->m_pArc)
{
SLength += pNodePrevious->m_pArc->m_R * fabs(pNodePrevious->m_pArc->m_centAngle);
}
else
{
SLength += pNodePrevious->m_pt.distanceTo(pt1);
}
}
if (eSegType != AcDbPolyline::kArc || fabs(Bulge) < fTOL)
{
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
else
{
if (i != nVerts - 1)
{
if (pPoly->getPointAt(i + 1, pt2d) != Acad::eOk)
{
pEntity->close();
return 0;
}
}
else
{
if (pPoly->getPointAt(0, pt2d) != Acad::eOk)
{
pEntity->close();
return 0;
}
}
pt2.set(pt2d.x, pt2d.y, Level);
ECS2UCS(pt2, objId);//UCS
double CenterAng = 4 * atan(Bulge);
double angx, ang1, ang2;
angx=AngleToX(pt1, pt2);
if (Bulge > 0)
{
ang1 = angx + (PI - CenterAng) / 2.0;
ang2 = ang1 + CenterAng;
}
else
{
ang1 = angx - (PI + CenterAng) / 2.0;
ang2 = ang1 + CenterAng;
}
while (ang1 >= 2 * PI)
{
ang1 -= 2 * PI;
}
while (ang1 < 0)
{
ang1 += 2 * PI;
}
while (ang2 >= 2*PI)
{
ang2 -= 2*PI;
}
while (ang2 < 0)
{
ang2 += 2*PI;
}
AcGePoint3d pt0, pt11, pt22, pt12, pt3, pt13, pt23;
double angxx, ll = pt1.distanceTo(pt2) / 2.0;
pt12.x = (pt1.x + pt2.x) / 2.0;
pt12.y = (pt1.y + pt2.y) / 2.0;
pt12.z = (pt1.z + pt2.z) / 2.0;
if (Bulge > 0)
{
angxx= angx - PI / 2.0;
while (angxx < 0)
{
angxx += 2 * PI;
}
}
else
{
angxx = angx + PI / 2.0;
while (angxx >= 2 * PI)
{
angxx -= 2 * PI;
}
}
pt3 = polar(pt12, angxx, ll*fabs(Bulge));
pt13.x = (pt1.x + pt3.x) / 2.0;
pt13.y = (pt1.y + pt3.y) / 2.0;
pt13.z = (pt1.z + pt3.z) / 2.0;
pt23.x = (pt2.x + pt3.x) / 2.0;
pt23.y = (pt2.y + pt3.y) / 2.0;
pt23.z = (pt2.z + pt3.z) / 2.0;
angxx = AngleToX(pt1, pt3) + PI / 2.0;
while (angxx >= 2*PI)
{
angxx -= 2*PI;
}
pt11 = polar(pt13, angxx, ll);
angxx = AngleToX(pt3, pt2) + PI / 2.0;
while (angxx >= 2*PI)
{
angxx -= 2*PI;
}
pt22 = polar(pt23, angxx, ll);
ads_point ads_pt1, ads_pt11, ads_pt2, ads_pt22, ads_pt0;
ARX2AdsPt(pt13, ads_pt1);
ARX2AdsPt(pt11, ads_pt11);
ARX2AdsPt(pt23, ads_pt2);
ARX2AdsPt(pt22, ads_pt22);
if (acdbInters(ads_pt1, ads_pt11, ads_pt2, ads_pt22, FALSE, ads_pt0) == RTNORM)
{
Ads2ARXPt(ads_pt0, pt0);
}
else
{
pEntity->close();
return 0;
}
ang1 += PI;
ang2 += PI;
while (ang1 >= 2*PI)
{
ang1 -= 2*PI;
}
while (ang2 >= 2*PI)
{
ang2 -= 2*PI;
}
double radius = pt0.distanceTo(pt1);
TBArc* pBLArc = new TBArc;
pBLArc->m_centPt = pt0;
pBLArc->m_R = radius;
pBLArc->m_startAngle = ang1;
pBLArc->m_centAngle = CenterAng;
pBLArc->m_startPt = pt1;
pBLArc->m_endPt = pt2;
TBNode* pNode=new TBNode(BARCSEG,SLength,pt1,pBLArc);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
}
if (pPoly->isClosed())
{
AcGePoint2d pt2d;
if (pPoly->getPointAt(0, pt2d) != Acad::eOk)
{
pEntity->close();
return 0;
}
AcGePoint3d pt1, pt2;
pt1.set(pt2d.x, pt2d.y, Level);
ECS2UCS(pt1, objId);//UCS
if (pNodePrevious->m_pArc)
SLength += pNodePrevious->m_pArc->m_R*fabs(pNodePrevious->m_pArc->m_centAngle);
else
SLength += pNodePrevious->m_pt.distanceTo(pt1);
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
}
else if (strLineType == _T("POLYLINE"))
{
AcDb2dPolyline* pPoly = (AcDb2dPolyline*)(pEntity);
AcDbObjectIterator *pVertIter = pPoly->vertexIterator();
double SLength = 0.;
AcDbObjectId vertxId;
AcDb2dVertex *pVertex;
TBNode* pNodePrevious = NULL;
AcGePoint3d FirstPt;
double Level = pPoly->elevation();
BOOL bLast = 0;
for (int vertexNumber = 0; !pVertIter->done();vertexNumber++, pVertIter->step())
{
vertxId = pVertIter->objectId();
if (acdbOpenObject(pVertex, vertxId,AcDb::kForRead) != Acad::eOk)
{
pEntity->close();
return 0;
}
if (vertexNumber == 0) FirstPt = pVertex->position();
double Bulge = pVertex->bulge();//凸度
if (isParal == 2) Bulge = -Bulge;//UCS与ECS的Z轴反向平行
AcGePoint3d pt1,pt2;
pt1 = pVertex->position();//ECS
pVertex->close();
pVertIter->step();
if (!pVertIter->done())
{//不是最后一点
AcDbObjectId vertxId2 = pVertIter->objectId();
AcDb2dVertex *pVertex2 = NULL;
if (acdbOpenObject(pVertex2, vertxId2,AcDb::kForRead) != Acad::eOk)
{
pEntity->close();
return 0;
}
pt2 = pVertex2->position();//ECS
pVertex2->close();
}
else
{
bLast = 1;
pt2 = FirstPt;
}
pVertIter->step(true); //back
pt1.z = Level;
pt2.z = Level;
ECS2UCS(pt1,objId);//UCS
ECS2UCS(pt2,objId);//UCS
if (pNodePrevious)
{
if (pNodePrevious->m_pArc)
SLength += pNodePrevious->m_pArc->m_R*fabs(pNodePrevious->m_pArc->m_centAngle);
else
SLength += pNodePrevious->m_pt.distanceTo(pt1);
}
if (bLast && !pPoly->isClosed())
{
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
break;
}
if (fabs(Bulge)<fTOL)
{
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
if (bLast)
{
SLength += pt2.distanceTo(pt1);
TBNode* pNode = new TBNode(BLINESEG,SLength,pt2);
m_BNodeList.AddTail(pNode);
}
pNodePrevious = pNode;
}
else
{
double CenterAng = 4*atan(Bulge);
double angx, ang1, ang2;
angx = AngleToX(pt1, pt2);
if (Bulge>0)
{
ang1 = angx+(PI-CenterAng)/2.0;
ang2 = ang1+CenterAng;
}
else
{
ang1 = angx-(PI+CenterAng)/2.0;
ang2 = ang1+CenterAng;
}
while (ang1 >= 2*PI) ang1 -= 2*PI;
while (ang1<0) ang1 += 2*PI;
while (ang2 >= 2*PI) ang2 -= 2*PI;
while (ang2<0) ang2 += 2*PI;
AcGePoint3d pt0, pt11, pt22, pt12, pt3, pt13, pt23;
double angxx, ll = pt1.distanceTo(pt2)/2.0;
pt12.x = (pt1.x+pt2.x)/2.0;
pt12.y = (pt1.y+pt2.y)/2.0;
pt12.z = (pt1.z+pt2.z)/2.0;
if (Bulge>0)
{
angxx = angx-PI/2.0;
while (angxx<0) angxx += 2*PI;
}
else
{
angxx = angx+PI/2.0;
while (angxx >= 2*PI) angxx -= 2*PI;
}
pt3 = polar(pt12, angxx, ll*fabs(Bulge));
pt13.x = (pt1.x+pt3.x)/2.0;
pt13.y = (pt1.y+pt3.y)/2.0;
pt13.z = (pt1.z+pt3.z)/2.0;
pt23.x = (pt2.x+pt3.x)/2.0;
pt23.y = (pt2.y+pt3.y)/2.0;
pt23.z = (pt2.z+pt3.z)/2.0;
angxx = AngleToX(pt1, pt3)+PI/2.0;
while (angxx >= 2*PI) angxx -= 2*PI;
pt11 = polar(pt13, angxx, ll);
angxx = AngleToX(pt3, pt2)+PI/2.0;
while (angxx >= 2*PI) angxx -= 2*PI;
pt22 = polar(pt23, angxx, ll);
ads_point ads_pt1, ads_pt11, ads_pt2, ads_pt22, ads_pt0;
ARX2AdsPt(pt13, ads_pt1);
ARX2AdsPt(pt11, ads_pt11);
ARX2AdsPt(pt23, ads_pt2);
ARX2AdsPt(pt22, ads_pt22);
if (acdbInters(ads_pt1, ads_pt11, ads_pt2, ads_pt22, FALSE, ads_pt0) == RTNORM)
Ads2ARXPt(ads_pt0, pt0);
else
{
pEntity->close();
return 0;
}
ang1 += PI;
ang2 += PI;
while (ang1 >= 2*PI) ang1 -= 2*PI;
while (ang2 >= 2*PI) ang2 -= 2*PI;
double radius = pt0.distanceTo(pt1);
TBArc* pBLArc = new TBArc;
pBLArc->m_centPt = pt0;
pBLArc->m_R = radius;
pBLArc->m_startAngle = ang1;
pBLArc->m_centAngle = CenterAng;
pBLArc->m_startPt = pt1;
pBLArc->m_endPt = pt2;
TBNode* pNode = new TBNode(BARCSEG,SLength,pt1,pBLArc);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
}
if (pPoly->isClosed())
{
AcGePoint3d pt1 = FirstPt;
ECS2UCS(pt1, objId);//UCS
if (pNodePrevious->m_pArc)
SLength += pNodePrevious->m_pArc->m_R*fabs(pNodePrevious->m_pArc->m_centAngle);
else
SLength += pNodePrevious->m_pt.distanceTo(pt1);
TBNode* pNode = new TBNode(BLINESEG,SLength,pt1);
m_BNodeList.AddTail(pNode);
pNodePrevious = pNode;
}
}
else
{
pEntity->close();
return 0;
}
TBNode* pStartNode = m_BNodeList.GetHead();
TBNode* pEndNode = m_BNodeList.GetTail();
double dist = (pEndNode->m_pt - pStartNode->m_pt).length();
if (strLineType != _T("CIRCLE"))
{
if (( dist <= TOL) && (pEndNode != pStartNode))
m_bClosed = 1;
else m_bClosed = 0;
}
pEntity->close();
return 1;
}
TBNode* TBPloyLine::Head()
{
if (m_BNodeList.IsEmpty()) return NULL;
else return m_BNodeList.GetHead();
}
TBNode* TBPloyLine::Tail()
{
if (m_BNodeList.IsEmpty()) return NULL;
else return m_BNodeList.GetTail();
}
TBNode* TBPloyLine::GetNextNode(const TBNode* pNode)
{
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNodeCur = m_BNodeList.GetNext(pos);
if (pNodeCur == pNode)
{
if (pos == NULL) return NULL;
return m_BNodeList.GetAt(pos);
}
}
return NULL;
}
TBNode* TBPloyLine::GetPreNode(const TBNode* pNode)
{
POSITION pos = m_BNodeList.GetTailPosition();
while (pos != NULL)
{
TBNode* pNodeCur = m_BNodeList.GetPrev(pos);
if (pNodeCur == pNode)
{
if (pos == NULL) return NULL;
return m_BNodeList.GetAt(pos);
}
}
return NULL;
}
BOOL TBPloyLine::GetDNode(double s,TDNode* pDivNode)
{
if (m_BNodeList.IsEmpty())
{
return 0;
}
double TotaLen = GetLength();
if (TotaLen < TOL)
{
TBNode* pNode = Head();
if (pNode == NULL)
{
return 0;
}
pDivNode->m_angTng = 0.;
pDivNode->m_pt = pNode->m_pt;
pDivNode->m_s = 0.;
return 1;
}
if (s < -TOL || s - TotaLen > TOL )
{
return 0;
}
else if ( fabs(TotaLen - s) <= TOL )
{
s = TotaLen;
}
else if ( fabs(s) <= TOL)
{
s = 0.;
}
POSITION pos = m_BNodeList.GetHeadPosition();
TBNode* pNodePre = NULL;
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
double len = pNode->m_s;
if (((len - s) >= TOL) && pNodePre != NULL)
{
//等分点处于两拐点之间
//pNodePre == NULL则len一定为0
//从结点pNodePre处的相对S坐标
double relatedS = s - pNodePre->m_s;
if (pNodePre->m_eType == BLINESEG)
{
double lineSegLen = pNode->m_s - pNodePre->m_s;
pDivNode->m_angTng = AngleToX(pNodePre->m_pt,pNode->m_pt);
pDivNode->m_pt.x = pNodePre->m_pt.x + relatedS*cos(pDivNode->m_angTng);
pDivNode->m_pt.y = pNodePre->m_pt.y + relatedS*sin(pDivNode->m_angTng);
pDivNode->m_s = s;
return 1;
}
else if (pNodePre->m_eType == BARCSEG && pNodePre->m_pArc != NULL)
{
pDivNode->m_pt = pNodePre->m_pArc->GetPtAtS(relatedS);
double ang = AngleToX(pNodePre->m_pArc->m_centPt,pDivNode->m_pt);
if (pNodePre->m_pArc->m_centAngle<0)
{//顺时针
pDivNode->m_angTng = ang - PI / 2.;
while (pDivNode->m_angTng < 0)
{
pDivNode->m_angTng += 2*PI;
}
while (pDivNode->m_angTng >= 2*PI)
{
pDivNode->m_angTng -= 2*PI;
}
}
else
{
pDivNode->m_angTng = ang + PI / 2.;
while (pDivNode->m_angTng < 0)
{
pDivNode->m_angTng += 2*PI;
}
while (pDivNode->m_angTng >= 2*PI)
{
pDivNode->m_angTng -= 2*PI;
}
}
pDivNode->m_s = s;
return 1;
}
}
else if (fabs(s - len) < TOL)
{
//等分点处于基线拐点上
TBNode* pNodeNext = NULL;
if (pos != NULL)
{
pNodeNext = m_BNodeList.GetNext(pos);
}
if (pNodePre == NULL)
{//处于第一点
if (pNode->m_eType == BLINESEG)
{
if (pNodeNext == NULL)
{
return 0;
}
pDivNode->m_angTng = AngleToX(pNode->m_pt,pNodeNext->m_pt);
pDivNode->m_pt = pNode->m_pt;
pDivNode->m_s = s;
}
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
{
pDivNode->m_pt = pNode->m_pt;
double ang = AngleToX(pNode->m_pArc->m_centPt,pDivNode->m_pt);
if (pNode->m_pArc->m_centAngle < 0)
{//顺时针
pDivNode->m_angTng = ang - PI / 2.;
while (pDivNode->m_angTng < 0)
{
pDivNode->m_angTng += 2*PI;
}
while (pDivNode->m_angTng >= 2*PI)
{
pDivNode->m_angTng -= 2*PI;
}
}
else
{
pDivNode->m_angTng = ang + PI / 2.;
while (pDivNode->m_angTng < 0)
{
pDivNode->m_angTng += 2*PI;
}
while (pDivNode->m_angTng >= 2*PI)
{
pDivNode->m_angTng -= 2*PI;
}
}
pDivNode->m_s = s;
}
return 1;
}
else if (pNodeNext == NULL)
{//处于最后一个结点上pNodeFirst
if (pNodePre == NULL)
{
return 0;
}
if (pNodePre->m_eType == BLINESEG)
{
pDivNode->m_angTng = AngleToX(pNodePre->m_pt,pNode->m_pt);
pDivNode->m_pt = pNode->m_pt;
pDivNode->m_s = s;
}
else if (pNodePre->m_eType == BARCSEG)
{
pDivNode->m_pt = pNode->m_pt;
double ang = AngleToX(pNodePre->m_pArc->m_centPt,pDivNode->m_pt);
if (pNodePre->m_pArc->m_centAngle < 0)
{//顺时针
pDivNode->m_angTng = ang - PI / 2.;
while (pDivNode->m_angTng < 0)
{
pDivNode->m_angTng += 2*PI;
}
while (pDivNode->m_angTng >= 2*PI)
{
pDivNode->m_angTng -= 2*PI;
}
}
else
{
pDivNode->m_angTng = ang + PI / 2.;
while (pDivNode->m_angTng < 0)
{
pDivNode->m_angTng += 2*PI;
}
while (pDivNode->m_angTng >= 2*PI)
{
pDivNode->m_angTng -= 2*PI;
}
}
pDivNode->m_s = s;
}
return 1;
}
else
{//处于中间结点上
if (pNode->m_eType == BLINESEG)
{
double angIn;
double angOut = AngleToX(pNode->m_pt,pNodeNext->m_pt);
if (pNodePre->m_eType == BLINESEG)
{
angIn = AngleToX(pNodePre->m_pt,pNode->m_pt);
}
else
{
angIn = GetActAngOfArcOut(pNodePre);
}
if (fabs(angOut-angIn) <= PI)
{
pDivNode->m_angTng = (angOut + angIn) / 2.;
}
else
{
pDivNode->m_angTng = (angOut + angIn) / 2. + PI;
}
while (pDivNode->m_angTng >= 2*PI)
{
pDivNode->m_angTng -= 2*PI;
}
while (pDivNode->m_angTng < 0)
{
pDivNode->m_angTng += 2*PI;
}
pDivNode->m_pt = pNode->m_pt;
pDivNode->m_s = s;
return 1;
}
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
{
double angIn;
double angOut = GetActAngOfArcIn(pNode);
if (pNodePre->m_eType == BLINESEG)
{
AcGePoint3d pPre = pNodePre->m_pt;
AcGePoint3d pThis = pNode->m_pt;
UCS2WCS(pPre);
UCS2WCS(pThis);
angIn = AngleToX(pNodePre->m_pt,pNode->m_pt);
}
else
{
angIn = GetActAngOfArcOut(pNodePre);
}
if (fabs(angOut - angIn) <= PI)
{
pDivNode->m_angTng = (angOut + angIn) / 2.;
}
else
{
pDivNode->m_angTng = (angOut + angIn) /2. + PI;
}
while (pDivNode->m_angTng >= 2*PI)
{
pDivNode->m_angTng -= 2*PI;
}
while (pDivNode->m_angTng < 0)
{
pDivNode->m_angTng += 2*PI;
}
pDivNode->m_pt = pNode->m_pt;
pDivNode->m_s = s;
return 1;
}
}
}
pNodePre = pNode;
}
return 0;
}
double TBPloyLine::GetActAngOfArcIn(TBNode* pNode)
{
if (pNode == NULL)
{
return 0.;
}
if (pNode->m_pArc->m_centAngle >= 0)
{//逆时针
double ang = pNode->m_pArc->m_startAngle + PI / 2.;
while (ang >= 2*PI)
{
ang -= 2*PI;
}
return ang;
}
else
{
double ang = pNode->m_pArc->m_startAngle - PI / 2.;
while (ang < 0)
{
ang += 2*PI;
}
return ang;
}
}
double TBPloyLine::GetActAngOfArcOut(TBNode* pNode)
{
if (pNode == NULL)
{
return 0.;
}
if (pNode->m_pArc->m_centAngle >= 0)
{//逆时针
double ang = pNode->m_pArc->m_startAngle + PI/2. + pNode->m_pArc->m_centAngle;
while (ang >= 2*PI)
{
ang -= 2*PI;
}
return ang;
}
else
{
double ang = pNode->m_pArc->m_startAngle - PI/2. + pNode->m_pArc->m_centAngle;
while (ang < 0)
{
ang += 2*PI;
}
return ang;
}
}
void TBPloyLine::LinearizePLine(double dAng)
{
if (IsEmpty())
{
return;
}
ReleaseDivLst();
DivideByAng(dAng);
ReleaseBasLst();
double length = 0.;
TDNode* pNodePre = NULL;
for(POSITION pos = m_DNodeList.GetHeadPosition(); pos;)
{
TDNode* pNode = m_DNodeList.GetNext(pos);
if (m_bClosed && pos == NULL)
{
pNode = m_DNodeList.GetHead();
}
if (pNodePre != NULL)
{
length += pNodePre->m_pt.distanceTo(pNode->m_pt);
}
TBNode* pBasNode = new TBNode(BLINESEG,length,pNode->m_pt);
m_BNodeList.AddTail(pBasNode);
pNodePre = pNode;
}
}
void TBPloyLine::LinearizePLine(int nSegs)
{
if (IsEmpty()) return;
ReleaseDivLst();
DivideBySegs(nSegs,0);
ReleaseBasLst();
double length = 0.;
TDNode* pNodePre = NULL;
for(POSITION pos = m_DNodeList.GetHeadPosition(); pos;)
{
TDNode* pNode = m_DNodeList.GetNext(pos);
if (m_bClosed && pos == NULL)
{
pNode=m_DNodeList.GetHead();
}
if (pNodePre != NULL)
{
length += pNodePre->m_pt.distanceTo(pNode->m_pt);
}
TBNode* pBasNode = new TBNode(BLINESEG,length,pNode->m_pt);
m_BNodeList.AddTail(pBasNode);
pNodePre = pNode;
}
}
void TBPloyLine::DivideByAng(const double detaAng)
{//按角度,只划分圆弧
if (IsEmpty())
{
return;
}
if (detaAng < TOL)
{
return;
}
double Z0 = 0;
ReleaseDivLst();
double TotLength = GetLength();
if (TotLength < TOL)
{
int n = m_BNodeList.GetCount();
double detaZ = 0;
int i = 0;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
TDNode* pDieNode = new TDNode;
pDieNode->m_pt = pNode->m_pt;
pDieNode->m_pt.z = Z0+i*detaZ;
pDieNode->m_s = 0.;
pDieNode->m_angTng = 0.;
m_DNodeList.AddTail(pDieNode);
i++;
}
return;
}
double unitZ = 0;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
POSITION posTemp = pos;
TBNode* pNodeNext = NULL;
if (posTemp != NULL)
{
pNodeNext = m_BNodeList.GetNext(posTemp);//得到下一结点但不增加pos
}
double s = pNode->m_s;//结点S坐标
if (pNode->m_eType == BLINESEG)
{//直线
TDNode* pDieNode = new TDNode;
if (GetDNode(s,pDieNode))
{
m_DNodeList.AddTail(pDieNode);
pDieNode->m_pt.z = Z0+unitZ*s;
}
}
else
{//圆弧
if (pNodeNext != NULL)
{//不是最后一点
if (pNode->m_pArc != NULL)
{
double s0 = pNode->m_s;
double len = pNodeNext->m_s - s0; //线段长度
int nSeg = abs((int)(pNode->m_pArc->m_centAngle / detaAng + 0.5));//等分数
if (nSeg == 0)
{
nSeg = 1;
}
double detaS = len / nSeg;
if (detaS > TOL)
{//等分
for (int i = 0; i < nSeg; i++)
{
TDNode* pDieNode = new TDNode;
if (GetDNode(s0 + i * detaS,pDieNode))
{
m_DNodeList.AddTail(pDieNode);
pDieNode->m_pt.z = Z0 + unitZ * (s0 + i * detaS);
}
}
}
}
}
else
{//最后一点
TDNode* pDieNode = new TDNode;
if (GetDNode(s,pDieNode))
{
m_DNodeList.AddTail(pDieNode);
pDieNode->m_pt.z = Z0 + unitZ * s;
}
}
}
}
}
void TBPloyLine::DivideBySegs(const int nSegs,BOOL flag)
{
if (IsEmpty())
{
return;
}
if (nSegs == 0)
{
return;
}
double Z0 = 0;
ReleaseDivLst();
double TotLength = GetLength();
if (TotLength < TOL)
{
TBNode* pHead = Head();
if (pHead == NULL) return;
int n = nSegs;
double detaZ = 0;
for (int i = 0;i <= n;i++)
{
TDNode* pDieNode = new TDNode;
pDieNode->m_pt = pHead->m_pt;
pDieNode->m_pt.z = Z0 + i * detaZ;
pDieNode->m_s = 0.;
pDieNode->m_angTng = 0.;
m_DNodeList.AddTail(pDieNode);
}
return;
}
double unitZ = 0;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
POSITION posTemp = pos;
TBNode* pNodeNext = NULL;
if (posTemp != NULL)
{
pNodeNext = m_BNodeList.GetNext(posTemp);//得到下一结点但不增加pos
}
double s = pNode->m_s;//结点S坐标
if (pNode->m_eType == BLINESEG)
{
if (flag && pNodeNext != NULL)
{//不是最后一个结点
double s0 = pNode->m_s;
double len = pNodeNext->m_s - s0; //线段长度
double detaS = len / nSegs;
if (detaS > TOL)
{//等分
for (int i = 0; i < nSegs; i++)
{
TDNode* pDieNode = new TDNode;
if (GetDNode(s0 + i * detaS,pDieNode))
{
m_DNodeList.AddTail(pDieNode);
pDieNode->m_pt.z = Z0 + unitZ * (s0 + i * detaS);
}
}
}
}
else
{//不等分直线或pNodeNext == NULL(最后一点)
TDNode* pDieNode = new TDNode;
if (GetDNode(s,pDieNode))
{
m_DNodeList.AddTail(pDieNode);
pDieNode->m_pt.z = Z0 + unitZ * s;
}
}
}
else
{//圆弧
if (pNodeNext != NULL)
{//不是最后一点
double s0 = pNode->m_s;
double len = pNodeNext->m_s - s0; //线段长度
double detaS = len / nSegs;
if (detaS > TOL)
{//等分
for (int i = 0;i < nSegs; i++)
{
TDNode* pDieNode = new TDNode;
if (GetDNode(s0 + i * detaS, pDieNode))
{
m_DNodeList.AddTail(pDieNode);
pDieNode->m_pt.z = Z0 + unitZ * (s0 + i * detaS);
}
}
}
}
else
{//最后一点
TDNode* pDieNode = new TDNode;
if (GetDNode(s,pDieNode))
{
m_DNodeList.AddTail(pDieNode);
pDieNode->m_pt.z = Z0 + unitZ * s;
}
}
}
}
}
double TBPloyLine::GetLength(BOOL bReCalSCoord) const
{
if (IsEmpty())
{
return 0;
}
if (bReCalSCoord)
{
const_cast<TBPloyLine*>(this)->ReCalcSValue();
}
TBNode* pNode = m_BNodeList.GetTail();
if (pNode != NULL)
{
return pNode->m_s;
}
return 0.;
}
TBNode* TBPloyLine::GetMostLeftNode()
{
if (IsEmpty())
{
return NULL;
}
TBNode* temp = m_BNodeList.GetHead();
double value = temp->m_pt.x;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
double xMin;
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
{
xMin = pNode->m_pArc->GetMinX();
}
else xMin = pNode->m_pt.x;
if (xMin < value)
{
value = xMin;
temp = pNode;
}
}
return temp;
}
double TBPloyLine::GetMaxX()
{
if (IsEmpty())
{
return 0;
}
double value = m_BNodeList.GetHead()->m_pt.x;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNode->m_eType == BLINESEG)
{
if (pNode->m_pt.x > value)
{
value = pNode->m_pt.x;
}
}
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
{
double arcMax = pNode->m_pArc->GetMaxX();
if (arcMax > value)
{
value = arcMax;
}
}
}
return value;
}
double TBPloyLine::GetMinX()
{
if (IsEmpty())
{
return 0;
}
double value = m_BNodeList.GetHead()->m_pt.x;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNode->m_eType == BLINESEG)
{
if (pNode->m_pt.x < value)
{
value = pNode->m_pt.x;
}
}
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
{
double arcMin = pNode->m_pArc->GetMinX();
if (arcMin < value)
{
value = arcMin;
}
}
}
return value;
}
double TBPloyLine::GetMinY()
{
if (IsEmpty())
{
return 0;
}
double value = m_BNodeList.GetHead()->m_pt.y;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNode->m_eType == BLINESEG)
{
if (pNode->m_pt.y < value)
{
value = pNode->m_pt.y;
}
}
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
{
double arcMin = pNode->m_pArc->GetMinY();
if (arcMin < value)
{
value = arcMin;
}
}
}
return value;
}
double TBPloyLine::GetMaxY()
{
if (IsEmpty())
{
return 0;
}
double value = m_BNodeList.GetHead()->m_pt.y;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode=m_BNodeList.GetNext(pos);
if (pNode->m_eType == BLINESEG)
{
if (pNode->m_pt.y > value)
{
value = pNode->m_pt.y;
}
}
else if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
{
double arcMax = pNode->m_pArc->GetMaxY();
if (arcMax > value)
{
value = arcMax;
}
}
}
return value;
}
BOOL TBPloyLine::GetClockwise()
{
if (!m_bClosed)
{
return 0;
}
if (GetLength() < TOL)
{
return 0;
}
if (isCircle())
{
TBNode* pHead = Head();
if (pHead->m_pArc->m_centAngle > 0)
{
return 2;
}
else
{
return 1;
}
}
int nNode = 0;
AcGePoint3d pt0(0,0,0);
TBNode* pNodePrev = NULL;
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
pt0.x += pNode->m_pt.x;
pt0.y += pNode->m_pt.y;
pt0.z += pNode->m_pt.z;
nNode++;
}
pt0.x /= nNode;
pt0.y /= nNode;
pt0.z /= nNode;
double xigmaS = 0.;
pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNodePrev != NULL)
{
AcGePoint3d pt1 = pNodePrev->m_pt;
AcGePoint3d pt2 = pNode->m_pt;
double s = 0;
s = pt0.x * (pt1.y - pt2.y) + pt1.x * (pt2.y - pt0.y) + pt2.x * (pt0.y - pt1.y);
xigmaS += s;
}
pNodePrev = pNode;
}
if (xigmaS > fTOL)
{
return 2;
}
else if (xigmaS < -fTOL)
{
return 1;
}
else
{
return 0;
}
}
BOOL TBPloyLine::IsEmpty() const
{
return m_BNodeList.IsEmpty();
}
BOOL TBPloyLine::IsIntersectWith(double x,AcGePoint3d pt1,AcGePoint3d pt2) const
{
if (GetLength() < TOL)
{
return 0;
}
AcGeLineSeg3d line3d1(pt1,pt2);
POSITION pos = m_BNodeList.GetHeadPosition();
TBNode* pNodePre = NULL;
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNodePre != NULL)
{
if ((pNode->m_pt.x < x - fTOL) || (pNodePre->m_pt.x < x - fTOL))
{
if (IsEqual(pNode->m_pt,pt1) || IsEqual(pNode->m_pt,pt2) ||
IsEqual(pNodePre->m_pt,pt1) || IsEqual(pNodePre->m_pt,pt2))
{
pNodePre = pNode;
continue;
}
AcGeLineSeg3d line3d2(pNodePre->m_pt,pNode->m_pt);
AcGePoint3d secPt;
if (line3d1.intersectWith(line3d2,secPt) == Adesk::kTrue)
{
return 1;
}
}
}
pNodePre = pNode;
}
return 0;
}
BOOL TBPloyLine::IsPtInPolygon(AcGePoint3d& pt) const
{
if (IsEmpty() || !(IsClosed()))
{
return 0;
}
if (GetLength() < TOL)
{
return 0;
}
AcGeTol tol;
tol.setEqualPoint(TOL);
TBPloyLine* pNew = new TBPloyLine;
*pNew = *this;
if (pNew->HasArc())
{
pNew->LinearizePLine(PI / 36.);
}
AcGePoint3d pt1 = pt;
pt1.x += 100;
AcGeRay3d rayLine(pt,pt1); //以pt为起点的水平射线
POSITION pos = pNew->m_BNodeList.GetHeadPosition();
TBNode* pNodePre = NULL;
int nTotpt = 0; //射线与多边形的交点数
while (pos != NULL)
{
TBNode* pNode = pNew->m_BNodeList.GetNext(pos);
if (pNodePre != NULL)
{
AcGeLineSeg3d line3d(pNodePre->m_pt,pNode->m_pt); //得到直线段
AcGePoint3d secPt;
if (line3d.isOn(pt,tol))
{
return 2; //点在边上
}
if (IsOverlap(pt,pt1,pNodePre->m_pt,pNode->m_pt))
{
continue;
}
else if (rayLine.isOn(pNodePre->m_pt,tol) && (pNodePre->m_pt.y<pNode->m_pt.y))
{
nTotpt++;
}
else if (rayLine.isOn(pNode->m_pt,tol) && (pNode->m_pt.y<pNodePre->m_pt.y))
{
nTotpt++;
}
else if (line3d.intersectWith(rayLine,secPt) == Adesk::kTrue &&
!rayLine.isOn(pNode->m_pt,tol) && !rayLine.isOn(pNodePre->m_pt,tol))
{
nTotpt++;
}
}
pNodePre = pNode;
}
delete pNew;
if ((nTotpt + 1) % 2 == 0)
{
return 1;
}
else
{
return 0;
}
}
BOOL TBPloyLine::HasArc() const
{
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
{
return 1;
}
}
return 0;
}
BOOL TBPloyLine::isCircle() const
{
if (IsEmpty())
{
return 0;
}
TBPloyLine tempLine = *this;
tempLine.ClearUp();
TBNode* pHead = tempLine.Head();
if (pHead == NULL)
{
return 0;
}
if (tempLine.HasArc() && tempLine.m_BNodeList.GetCount() == 2 &&
fabs(fabs(pHead->m_pArc->m_centAngle) - 2 * PI) < TOL)
{
return 1;
}
return 0;
}
BOOL TBPloyLine::IsInXYPlane() const
{
TBNode* pHead = m_BNodeList.GetHead();
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
if (fabs(pHead->m_pt.z - pNode->m_pt.z) > TOL)
{
return 0;
}
}
return 1;
}
void TBPloyLine::MoveTo(AcGeVector3d& disp)
{
POSITION pos = m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
pNode->m_pt = pNode->m_pt + disp;
if (pNode->m_eType == BARCSEG && pNode->m_pArc != NULL)
{
pNode->m_pArc->m_centPt = pNode->m_pArc->m_centPt + disp;
}
}
}
void TBPloyLine::ReCalcSValue()
{
if (IsEmpty())
{
return;
}
POSITION pos = m_BNodeList.GetHeadPosition();
double len = 0.0;
TBNode* pNodePre = NULL;
while (pos != NULL)
{
TBNode* pNode = m_BNodeList.GetNext(pos);
if (pNodePre != NULL)
{
if (pNodePre->m_eType == BLINESEG)
{
len += pNodePre->m_pt.distanceTo(pNode->m_pt);
}
else if (pNodePre->m_eType == BARCSEG && pNodePre->m_pArc != NULL)
{
len += pNodePre->m_pArc->Length();
}
}
pNode->m_s = len;
pNodePre = pNode;
}
}
int TBPloyLine::IsZParalECSAndUcs(AcDbObjectId& objId)
{
AcDbEntity *pEnt;
acdbOpenObject(pEnt, objId, AcDb::kForRead);
CString DxfName = pEnt->isA()->dxfName();
if (DxfName == _T("LINE"))
{
AcDbLine* pLine = (AcDbLine*)(pEnt);
AcGePoint3d pt1 = pLine->startPoint();
AcGePoint3d pt2 = pLine->endPoint();
WCS2UCS(pt1);
WCS2UCS(pt2);
pEnt->close();
double d = pt1.distanceTo(pt2);
if (d <= TOL)
{
return 0;
}
if (fabs(pt1[Z] - pt2[Z]) / d >= TOL)
{
return 0;
}
return 1;
}
else
{
pEnt->close();
ads_point ads_ret,ads_pt = {0.,0.,1.};
ads_name pEntName;
acdbGetAdsName(pEntName,objId);
struct resbuf from,to;
from.restype = RTENAME;
ads_name_set(pEntName,from.resval.rlname); //ECS
to.restype = RTSHORT;
to.resval.rint = 1; //UCS
acedTrans(ads_pt,&from,&to,1,ads_ret); //按矢量转换
double tol = TOL;
if (fabs(ads_ret[X]) < TOL && fabs(ads_ret[Y]) < TOL && ads_ret[Z] >= 0.)
{
return 1;
}
else if (fabs(ads_ret[X]) < TOL && fabs(ads_ret[Y]) < TOL && ads_ret[Z] < 0.)
{
return 2;
}
else
{
return 0;
}
}
}
void TBPloyLine::WCS2ECS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
ARX2AdsPt(pt,ads_pt1);
ads_name pEntName;
acdbGetAdsName(pEntName,objId);
struct resbuf from,to;
from.restype = RTSHORT;
from.resval.rint = 0;
to.restype = RTENAME;
ads_name_set(pEntName,to.resval.rlname); //ECS
acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
Ads2ARXPt(ads_ret,pt);
}
void TBPloyLine::WCS2UCS(AcGePoint3d& pt,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
ARX2AdsPt(pt,ads_pt1);
struct resbuf from,to;
from.restype = RTSHORT;
from.resval.rint = 0; //WCS
to.restype = RTSHORT;
to.resval.rint = 1; //UCS
acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
Ads2ARXPt(ads_ret,pt);
}
void TBPloyLine::ECS2UCS(AcGePoint3d& pt,AcDbObjectId& objId,BOOL bVer)
{
ads_point ads_pt1,ads_ret;
ARX2AdsPt(pt,ads_pt1);
ads_name pEntName;
acdbGetAdsName(pEntName,objId);
struct resbuf from,to;
from.restype = RTENAME;
ads_name_set(pEntName,from.resval.rlname); //ECS
to.restype = RTSHORT;
to.resval.rint = 1;
acedTrans(ads_pt1,&from,&to,bVer,ads_ret);
Ads2ARXPt(ads_ret,pt);
}
AcGePoint3d TBPloyLine::polar(AcGePoint3d& pt0,double ang,double dist)
{
AcGePoint3d pt3d;
ads_point ads_pt,ads_ret;
ARX2AdsPt(pt0,ads_pt);
acutPolar(ads_pt,ang,dist,ads_ret);
Ads2ARXPt(ads_ret,pt3d);
return pt3d;
}
BOOL TBPloyLine::IsEqualSign(double x1,double x2)
{
if (x1 > fTOL && x2 > fTOL)
{
return 1;
}
if (x1 < fTOL && x2 < fTOL)
{
return 1;
}
return 0;
}