//-----------------------------------------------------------------------------+ // 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 #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)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)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)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(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.ym_pt.y)) { nTotpt++; } else if (rayLine.isOn(pNode->m_pt,tol) && (pNode->m_pt.ym_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; }