#include "stdafx.h" #include "dbgrip.h" #include "AecDb3dRoadAxisLine.h" #include "aecdbentitybase.h" #include "MFCDbDwgFiler.h" #include "KTCADUtilityEx.h" #include "KTTempTol.h" #include "CoreTools.h" static const Adesk::UInt16 kColorByBlock = 0; static const Adesk::UInt16 kRed = 1; static const Adesk::UInt16 kYellow = 2; static const Adesk::UInt16 kGreen = 3; static const Adesk::UInt16 kCyan = 4; static const Adesk::UInt16 kBlue = 5; static const Adesk::UInt16 kMagenta = 6; static const Adesk::UInt16 kWhite = 7; static const Adesk::UInt16 kColorByLayer = 256; #ifndef GRIP_MAXNUM_SHEW #define GRIP_MAXNUM_SHEW 3000 #endif extern Acad::ErrorStatus AddToModelSpace(AcDbEntity* pEnt,AcDbDatabase* pDb = NULL,bool bClose = true); extern AcGePoint3d MidPoint(const AcGePoint3d& pt1,const AcGePoint3d& pt2); extern AcGePoint3d GetArcMidPoint(AcDbArc *pArc); extern AcDbArc *FormatArc(const AcGePoint3d &ptGe1, const AcGePoint3d &ptGe2, const AcGePoint3d &ptGe3); namespace { static void FreeBuffer(int n, AcDbVoidPtrArray& arEntPtrs) { AcDbEntity* pEnt = NULL; while (arEntPtrs.length() > n) { pEnt = (AcDbEntity*)arEntPtrs.last(); DELETE_PTR(pEnt); arEntPtrs.removeLast(); } } double getLength(AcDbPolyline *p) { double dE(.0), d(.0); p->getEndParam(dE); p->getDistAtParam(dE, d); return d; } } Adesk::UInt32 AecDb3dRoadAxisLine::kCurrentVersionNumber = 4; ACRX_DXF_DEFINE_MEMBERS(AecDb3dRoadAxisLine, AecDbCurveBase, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning, AEC_ROADAXISLINE, "AecDb3dRoadAxisLine" "|Product Desc: shanghua earthworm app obj" "|Company: shanghua inc" "|WEB Address: www.shanghuasoft.com") AecDb3dRoadAxisLine::AecDb3dRoadAxisLine(void) { m_nInfActive = -1; m_pGripAppData = new GripAppData[GRIP_MAXNUM_SHEW]; m_ptDR.set(0, 0); } AecDb3dRoadAxisLine::~AecDb3dRoadAxisLine(void) { FreeBuffer(0,m_arCurvePtrs); delete [] m_pGripAppData; } bool AecDb3dRoadAxisLine::IsLinesOnOneLineAndConnect(AcDbCurve* pLast,AcDbCurve* pNext) { AcDbLine* pLnLast = AcDbLine::cast(pLast); AcDbLine* pLnNext = AcDbLine::cast(pNext); if (pLnLast != NULL && pLnNext != NULL) { AcGeVector3d vtDir1 = pLnLast->endPoint() - pLnLast->startPoint(); vtDir1.normalize(); AcGeVector3d vtDir2 = pLnNext->endPoint() - pLnNext->startPoint(); vtDir2.normalize(); if (vtDir1.isParallelTo(vtDir2))//平行 { AcGePoint3d ptSta1 = pLnLast->startPoint(); AcGePoint3d ptEnd1 = pLnLast->endPoint(); AcGePoint3d ptSta2 = pLnNext->startPoint(); AcGePoint3d ptEnd2 = pLnNext->endPoint(); if (ptSta1.distanceTo(ptSta2) < 1.e-3)// { pLnLast->setStartPoint(ptEnd2); return true; } if (ptEnd1.distanceTo(ptSta2) < 1.e-3) { pLnLast->setEndPoint(ptEnd2); return true; } if (ptSta1.distanceTo(ptEnd2) < 1.e-3) { pLnLast->setStartPoint(ptSta2); return true; } if (ptEnd1.distanceTo(ptEnd2) < 1.e-3) { pLnLast->setEndPoint(ptSta2); return true; } } } return false; } Acad::ErrorStatus AecDb3dRoadAxisLine::AppendCurveSeg(const AcDbCurve* pCurve) { AssertWriteEnabled(); // double dE = 0,dL = 0; pCurve->getEndParam(dE); pCurve->getDistAtParam(dE, dL); if (fabs(dL) < 1.e-6) return Acad::eInvalidInput; //只支持直线和圆弧 AcDbLine* pLine = AcDbLine::cast(pCurve); AcDbArc* pArc = AcDbArc::cast(pCurve); AcDbPolyline* pPl = AcDbPolyline::cast(pCurve); if (pPl != NULL) { pPl->explode(m_arCurvePtrs); return Acad::eOk; } if (pLine == NULL && pArc == NULL ) { return Acad::eInvalidInput; } AcDbCurve* pCurveCln = NULL; if (m_arCurvePtrs.isEmpty()) { if (pCurveCln == NULL) pCurveCln = (AcDbCurve*)pCurve->clone(); // AcGePoint3d pt1,pt2,pt3,pt4; // pCurve->getStartPoint(pt1); // pCurve->getEndPoint(pt2); // // pCurveCln->getStartPoint(pt3); // pCurveCln->getEndPoint(pt4); m_arCurvePtrs.append(pCurveCln); } else { AcGePoint3d ptSta,ptEnd; AcGePoint3d ptSta1,ptEnd1; if (pCurveCln == NULL) pCurveCln = (AcDbCurve*)pCurve->clone(); AcDbCurve* pLast = (AcDbCurve*)m_arCurvePtrs.last(); if ( pLast != NULL) { pLast->getStartPoint(ptSta); pLast->getEndPoint(ptEnd); pCurveCln->getStartPoint(ptSta1); pCurveCln->getEndPoint(ptEnd1); /* if ( ( ptSta1.distanceTo(ptSta) < 1.e-3 ) || ( ptSta1.distanceTo(ptEnd) < 1.e-3 ) )//能接上 { if (ptSta1.distanceTo(ptSta) < 1.e-3 )//保证顺序 { #if ARX > 17 pCurveCln->reverseCurve(); #else #endif } //判断pLast和 pCurveCln是否共线相连接 if (IsLinesOnOneLineAndConnect(pLast,pCurveCln)) { return Acad::eOk; } else { m_arCurvePtrs.append( pCurveCln ); } return Acad::eOk; } if ( ( ptEnd1.distanceTo(ptSta) < 1.e-3 ) || ( ptEnd1.distanceTo(ptEnd) < 1.e-3 ) )//能接上 { if ( ptEnd1.distanceTo(ptEnd) < 1.e-3)//保证顺序 { #if ARX > 17 pCurveCln->reverseCurve(); #else #endif } //判断pLast和 pCurveCln是否共线相连接 if (IsLinesOnOneLineAndConnect(pLast,pCurveCln)) { return Acad::eOk; } else { m_arCurvePtrs.append( pCurveCln ); } MakeSureDirByFirstLine(); return Acad::eOk; }*/ } //判断pLast和 pCurveCln是否共线相连接 if (IsLinesOnOneLineAndConnect(pLast, pCurveCln)) { return Acad::eOk; } else { m_arCurvePtrs.append(pCurveCln); } //确保整体是按第一条直线sta-end走向 MakeSureDirByFirstLine(); } return Acad::eOk; } void AecDb3dRoadAxisLine::MakeSureDirByFirstLine() { //AssertWriteEnabled(); //MakeEndToEnd(); } Acad::ErrorStatus AecDb3dRoadAxisLine::RemoveLast(bool bDelete ) { AssertWriteEnabled(); if (!m_arCurvePtrs.isEmpty()) { AcDbCurve* pLast = (AcDbCurve*)m_arCurvePtrs.last(); m_arCurvePtrs.removeLast(); if (bDelete) DELETE_PTR(pLast); return Acad::eOk; } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::RemoveFirst(bool bDelete) { AssertWriteEnabled(); if (!m_arCurvePtrs.isEmpty()) { AcDbCurve* pLast = (AcDbCurve*)m_arCurvePtrs.first(); m_arCurvePtrs.removeFirst(); if (bDelete) DELETE_PTR(pLast); return Acad::eOk; } return Acad::eInvalidInput; } AcDbCurve* AecDb3dRoadAxisLine::GetCurveSeg(int nIndex) const { assertReadEnabled(); if (nIndex > -1 && nIndex < m_arCurvePtrs.length() ) { return (AcDbCurve*)m_arCurvePtrs.at(nIndex); } return NULL; } bool AecDb3dRoadAxisLine::GetInterface(AcArray& arInfs) const { assertReadEnabled(); AcArray arInfsT; for (int i = 0;i < m_arCurvePtrs.length();i++) { arInfsT.removeAll(); GetInterface(i,arInfsT); arInfs.append(arInfsT); } return !arInfs.isEmpty(); } int AecDb3dRoadAxisLine::GetInterfaceCount() const { assertReadEnabled(); return GetCurveSegCount() * 2; } int AecDb3dRoadAxisLine::GetActiveInf() const { assertReadEnabled(); return m_nInfActive; } void AecDb3dRoadAxisLine::SetActiveInf(int nIndex) { AssertWriteEnabled(); m_nInfActive = nIndex; } int AecDb3dRoadAxisLine::GetInterface(int nIndex,AcArray& arInfs) const { assertReadEnabled(); AcDbCurve* pCurve = GetCurveSeg(nIndex); if (pCurve != NULL) { double dSta = 0.0,dEnd = 0.0; pCurve->getStartParam(dSta); pCurve->getEndParam(dEnd); AecInterface inf; pCurve->getStartPoint(inf.ptPos); pCurve->getFirstDeriv(dSta,inf.vtDir); inf.dGasket = 0; arInfs.append(inf); pCurve->getEndPoint(inf.ptPos); pCurve->getFirstDeriv(dEnd,inf.vtDir); inf.dGasket = 0; arInfs.append(inf); } return arInfs.length(); } bool AecDb3dRoadAxisLine::TransformAssocInf(int nIndex,int nInf,const AcGeMatrix3d& xform) { AssertWriteEnabled(); AcDbCurve* pBaseCurve = GetCurveSeg(nIndex); if (pBaseCurve == NULL) return false; AcArray arInf; GetInterface(nIndex,arInf); if (nInf > -1 && nInf < arInf.length() ) { AecInterface& inf = arInf.at(nInf); AcGePoint3d ptGe = inf.ptPos; ptGe.transformBy(xform); AcGeVector3d vtDirNew = ptGe - inf.ptPos; double dAngle = vtDirNew.angleTo(inf.vtDir); if ( dAngle - 0.028 * PI < 1.e-2 || dAngle - 0.972 * PI > 1.e-2 )//平行,则为拉伸 5 或 175-180 度的范围内 { AcDbLine* pLine = AcDbLine::cast(pBaseCurve); if (pLine != NULL)//直管 { AcGePoint3d ptSta,ptEnd; ptSta = pLine->startPoint(); ptEnd = pLine->endPoint(); if (inf.ptPos.distanceTo(ptSta) < 1.e-2) { pLine->setStartPoint(ptGe);//新位置 return false;//不在继续发消息 } if (inf.ptPos.distanceTo(ptEnd) < 1.e-2) { pLine->setEndPoint(ptGe);//新位置 return false;//不在继续发消息 } } AcDbArc* pArc = AcDbArc::cast(pBaseCurve);//弧管 if (pArc != NULL) { pBaseCurve->transformBy(xform); return true; } } else//整体移动 { pBaseCurve->transformBy(xform); } } return true;//继续发消息 } int AecDb3dRoadAxisLine::GetCurveSegCount() const { assertReadEnabled(); return m_arCurvePtrs.length(); } int AecDb3dRoadAxisLine::GetCurveDirs(AcArray& arCurveDir,double dTol ) const { assertReadEnabled(); //获取曲线的序 AcGePoint3d ptSta,ptEnd; getStartPoint(ptSta); AcGePoint3dArray arPts; arPts.append(ptSta); CurveDir crDir; AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); pCurve->getStartPoint(ptSta); pCurve->getEndPoint(ptEnd); if (ptEnd.distanceTo(arPts.last()) < dTol) { crDir.bDir = false; crDir.pCurve = pCurve; arCurveDir.append(crDir); arPts.append(ptSta); continue; } if (ptSta.distanceTo(arPts.last()) < dTol) { crDir.bDir = true; crDir.pCurve = pCurve; arCurveDir.append(crDir); arPts.append(ptEnd); continue; } } return arCurveDir.length(); } Acad::ErrorStatus AecDb3dRoadAxisLine::AddGripPoint(const AcGePoint3d& ptBr) { AssertWriteEnabled(); //获取曲线的序 CurveDir crDir; AcArray arCurveDir; GetCurveDirs(arCurveDir); AcDbCurve* pCurve = NULL; //打断 AcGePoint3d ptOn; getClosestPointTo(ptBr,ptOn); AcGePoint3dArray arPts; arPts.append(ptOn); double dPara = 0.0; AcDbVoidPtrArray arCurPtrs; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if (Acad::eOk == pCurve->getParamAtPoint(ptOn,dPara)) { pCurve->getSplitCurves(arPts,arCurPtrs); if (arCurPtrs.length() == 2) { crDir = arCurveDir.at(i); if (crDir.bDir) { m_arCurvePtrs.setAt(i,arCurPtrs.first()); m_arCurvePtrs.insertAt(i+1,arCurPtrs.last()); } else { m_arCurvePtrs.setAt(i,arCurPtrs.last()); m_arCurvePtrs.insertAt(i+1,arCurPtrs.first()); } delete pCurve; return Acad::eOk; } else { FreeBuffer(0,arCurPtrs); } } } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::ImpGetGripPoints(AcGePoint3dArray &gripPoints, AcDbIntArray &osnapModes, AcDbIntArray &geomIds) const { assertReadEnabled(); //只取直线中点,过渡圆弧中点,起始点 KTTempTol tol(1.e-6); AcGePoint3d ptGe1,ptGe2,ptM; double dS = 0, dE = 0; AcArray arCurveDir; GetCurveDirs(arCurveDir); if (arCurveDir.length() != m_arCurvePtrs.length()) return Acad::eOk; AcDbCurve *pCurve = NULL; for (int i = 0; i < m_arCurvePtrs.length(); i++) { pCurve = (AcDbCurve *)m_arCurvePtrs.at(i); pCurve->getStartPoint(ptGe1); pCurve->getEndPoint(ptGe2); //起点 CurveDir &cDir = arCurveDir.at(i); gripPoints.append(cDir.bDir ? ptGe1 : ptGe2); geomIds.append(i); //中点 pCurve->getStartParam(dS); pCurve->getEndParam(dE); pCurve->getPointAtParam(0.5 * (dS + dE), ptM); gripPoints.append(ptM); geomIds.append(i); //终点 if (i == m_arCurvePtrs.length() - 1) { CurveDir &cDir = arCurveDir.last(); gripPoints.append(cDir.bDir ? ptGe2 : ptGe1); geomIds.append(i); } } return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::GetSegIndexOnGripIndex(AcDbIntArray& segIndexes, AcDbIntArray& gripPoses) const { assertReadEnabled(); AcArray arCurveDir; GetCurveDirs(arCurveDir); AcDbCurve *pCurve = NULL; for (int i = 0; i < m_arCurvePtrs.length(); i++) { //起点 CurveDir &cDir = arCurveDir.at(i); gripPoses.append(cDir.bDir ? 0 : 2); segIndexes.append(i); //中点 segIndexes.append(i); gripPoses.append(1); if (i == m_arCurvePtrs.length() - 1) { gripPoses.append(2); segIndexes.append(i); } } return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::subGetGripPoints(AcDbGripDataPtrArray& grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d& curViewDir, const int bitflags) const { assertReadEnabled(); AcGePoint3dArray gripPoints; AcDbIntArray osnapModes,geomIds; ImpGetGripPoints(gripPoints, osnapModes, geomIds); AcDbGripData *p = NULL; for (int i = 0; i < gripPoints.length(); ++i) { memset(&m_pGripAppData[i], 0, sizeof(GripAppData)); m_pGripAppData[i].ptGrip = gripPoints.at(i); m_pGripAppData[i].nPos = i; m_pGripAppData[i].nIndex = i; if (i < geomIds.length()) m_pGripAppData[i].nSegIndex = geomIds.at(i); p = new AcDbGripData; p->setGripPoint(gripPoints.at(i)); p->setAppData((void*)&m_pGripAppData[i]); grips.append(p); } return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::subMoveGripPointsAt(const AcDbVoidPtrArray& appData,const AcGeVector3d& offset,const int bitflags) { AssertWriteEnabled(); if (!appData.isEmpty()) { GripAppData * pAppData = (GripAppData *)appData.first(); if (pAppData != NULL) { AcDbIntArray indices,geomids; indices.append(pAppData->nIndex); geomids.append(pAppData->nSubSegIndex); return ImpMoveGripPointsAt(indices, geomids,offset); } } return Acad::eOk; } bool AecDb3dRoadAxisLine::MarkeArcSegFit(int nLast, int nNext, double dD, double dRatio) { AssertWriteEnabled(); int nSegCount = m_arCurvePtrs.length(); if (nLast > -1 && nLast < nSegCount && nNext > -1 && nNext < nSegCount) { int nCur = (nLast + nNext) / 2; AcDbCurve *pLast = (AcDbCurve*)m_arCurvePtrs.at(nLast); AcDbCurve *pNext = (AcDbCurve*)m_arCurvePtrs.at(nNext); AcDbCurve *pCur = (AcDbCurve *)m_arCurvePtrs.at(nCur); AcDbArc *pArc = NULL; AcDbArc *pArcLast = AcDbArc::cast(pCur); if (pArcLast != NULL) { pArc = AecDb3dRoadAxisLine::FilletLineAndLine(pLast, pNext, dD, dRatio); if (pArc != NULL) { m_arCurvePtrs.setAt(nCur, pArc); delete pArcLast; } } } return true; } bool AecDb3dRoadAxisLine::MarkeArcSegFit(const AcGePoint3d &pt1, const AcGePoint3d &pt2, double dD, double dRatio) { AssertWriteEnabled(); AcDbCurve *pCurve = NULL; AcDbCurve *pCurveLast = NULL; AcDbCurve *pCurveNext = NULL; double dPa = 0.0; for (int i = 0; i < m_arCurvePtrs.length(); i++) { pCurve = (AcDbCurve *)m_arCurvePtrs.at(i); if (Acad::eOk == pCurve->getParamAtPoint(pt1, dPa)) { pCurveLast = pCurve; } if (Acad::eOk == pCurve->getParamAtPoint(pt2, dPa)) { pCurveNext = pCurve; } if (pCurveLast != NULL && pCurveNext != NULL && pCurveLast != pCurveNext) { AcDbArc *pArc = FilletLineAndLine(pCurveLast, pCurveNext, dD, dRatio); if (pArc != NULL) { int nPos1 = m_arCurvePtrs.find(pCurveLast); int nPos2 = m_arCurvePtrs.find(pCurveNext); m_arCurvePtrs.insertAt(__max(nPos1, nPos2), pArc); //前一段 int nPosMax = __max(nPos1, nPos2); int nPosMin = __min(nPos1, nPos2); if (nPosMin > 0) { AcDbCurve *pLL = (AcDbCurve *)m_arCurvePtrs.at(nPosMin - 1); AcDbCurve *pNN = (AcDbCurve *)m_arCurvePtrs.at(nPosMin); pArc = FilletLineAndLine(pLL, pNN, dD, dRatio); if (pArc != NULL) { nPos1 = m_arCurvePtrs.find(pLL); nPos2 = m_arCurvePtrs.find(pNN); m_arCurvePtrs.insertAt(__max(nPos1, nPos2), pArc); } } } return true; } } return false; } static int GetPointPosOnLine(AcDbLine *pLn1, const AcGePoint3d &pt) { if (pLn1->startPoint().distanceTo(pt) < pLn1->endPoint().distanceTo(pt)) { return 0; } return 1; } static int SetLineConnect(AcDbLine *pLn1, const AcGePoint3d &ptInt1, int nPos) { if (nPos == 0) pLn1->setStartPoint(ptInt1); else pLn1->setEndPoint(ptInt1); return 1; } static int SetLineConnect(AcDbLine *pLn1,const AcGePoint3d& ptInt1) { int nPos = 0; if (pLn1->startPoint().distanceTo(ptInt1) < pLn1->endPoint().distanceTo(ptInt1)) { pLn1->setStartPoint(ptInt1); } else { pLn1->setEndPoint(ptInt1); nPos = 1; } return nPos; } static void SetLineConnect(AcDbLine *pLn1, int nPos1, AcDbLine *pLn2, int nPos2, const AcGePoint3d & ptInt1) { if (nPos1 == 0) pLn1->setStartPoint(ptInt1); else pLn1->setEndPoint(ptInt1); if (nPos2 == 0) pLn2->setStartPoint(ptInt1); else pLn2->setEndPoint(ptInt1); } static AcDbArc *TangentLnAndArc(AcDbLine *pLine, AcDbArc *pArc, double dR) { AcDbArc *pArcT = NULL; AcGePoint3d ptS = pLine->startPoint(); AcGePoint3d ptE = pLine->endPoint(); AcGePoint3d ptS1, ptE1, ptInt; pArc->getStartPoint(ptS1); pArc->getEndPoint(ptE1); if (ptS.distanceTo(ptS1) < 1.e-2) ptInt = ptS; if (ptE.distanceTo(ptS1) < 1.e-2) ptInt = ptE; if (ptS.distanceTo(ptE1) < 1.e-2) ptInt = ptS; if (ptE.distanceTo(ptE1) < 1.e-2) ptInt = ptE; AcGePoint3d ptC, ptT,pt2; AcGeVector3d vt = ptE - ptS; AcGeVector3d vtN = pArc->normal(); //如果line 和 arc 相切,则不倒圆 AcGeVector3d vt2 = ptInt - pArc->center(); if (vt2.isPerpendicularTo(vt)) { return NULL; } AcGePoint3dArray arPts; pLine->intersectWith(pArc, AcDb::kOnBothOperands, arPts); if (arPts.isEmpty()) { return NULL; } ptInt = arPts.first(); double dP = 0.0; pArc->getParamAtPoint(ptInt, dP); arPts.removeAll(); if (Acad::eOk == pArc->getPointAtParam(dP + 0.01, pt2)) { arPts.append(pt2); } if (Acad::eOk == pArc->getPointAtParam(dP - 0.01, pt2)) { arPts.append(pt2); } if (arPts.isEmpty()) return NULL; pt2 = arPts.first(); AcGeVector3d vt1 = pt2 - ptInt; vt1.normalize(); vt2 = MidPoint(ptS, ptE) - ptInt; vt2.normalize(); AcGeVector3d vt3 = vt1 + vt2; vt3.normalize(); AcDbLine lnX; lnX.setStartPoint(ptInt); ptT = ptInt + vt3 * 20000.0 * dR; lnX.setEndPoint(ptT); AcGeVector3d vtV = vt; vtV.rotateBy(PI / 2.0, vtN); vtV.normalize(); AcDbLine ln1, ln2; ptS += vtV * dR; ptE += vtV * dR; ln1.setStartPoint(ptS); ln1.setEndPoint(ptE); ptS -= vtV * 2.0 * dR; ptE -= vtV * 2.0 * dR; ln2.setStartPoint(ptS); ln2.setEndPoint(ptE); //圆心轨迹1 AcDbLine *pLnOk = NULL; ln1.intersectWith(&lnX, AcDb::kExtendThis, arPts); if (!arPts.isEmpty()) { pLnOk = &ln1; } arPts.removeAll(); ln2.intersectWith(&lnX, AcDb::kExtendThis, arPts); if (!arPts.isEmpty()) { pLnOk = &ln2; } if (pLnOk == NULL) return NULL; //圆心轨迹2 AcDbCircle cir1; cir1.setCenter(pArc->center()); cir1.setRadius(pArc->radius() - dR); AcDbCircle cir2; cir2.setCenter(pArc->center()); cir2.setRadius(pArc->radius() + dR); AcGePoint3dArray arCenPts; arPts.removeAll(); cir1.intersectWith(pLnOk, AcDb::kOnBothOperands, arPts); if (!arPts.isEmpty()) { arCenPts.append(arPts.first()); } arPts.removeAll(); cir2.intersectWith(pLnOk, AcDb::kOnBothOperands, arPts); if (!arPts.isEmpty()) { arCenPts.append(arPts.first()); } if (!arCenPts.isEmpty()) { AcGePoint3d pt1, pt2; ptC = arCenPts.first(); pLine->getClosestPointTo(ptC, ptT); pt1 = ptT; if (pLine->startPoint().distanceTo(ptT) < pLine->endPoint().distanceTo(ptT)) { pLine->setStartPoint(ptT); } else { pLine->setEndPoint(ptT); } pArc->getClosestPointTo(ptC, ptT); pt2 = ptT; pt2 = MidPoint(pt1, pt2); vt = pt2 - ptC; vt.normalize(); pt2 = ptC + vt * dR; pArcT = FormatArc(pt1, pt2, ptT); //更新pArc arPts.removeAll(); arPts.append(ptT); AcDbVoidPtrArray arArcPtrs; pArc->getSplitCurves(arPts, arArcPtrs); if (!arArcPtrs.isEmpty()) { AcDbArc *pArc1 = (AcDbArc *)arArcPtrs.first(); AcDbArc *pArc2 = (AcDbArc *)arArcPtrs.last(); AcDbArc *pArcUp = NULL; pArc1->getStartPoint(ptS); pArc1->getEndPoint(ptE); if (ptS.distanceTo(ptInt) < 1.e-2) { pArcUp = pArc2; } if (ptE.distanceTo(ptInt) < 1.e-2) { pArcUp = pArc2; } pArc2->getStartPoint(ptS); pArc2->getEndPoint(ptE); if (ptS.distanceTo(ptInt) < 1.e-2) { pArcUp = pArc1; } if (ptE.distanceTo(ptInt) < 1.e-2) { pArcUp = pArc1; } if (pArcUp != NULL) { pArc->setStartAngle(pArcUp->startAngle()); pArc->setEndAngle(pArcUp->endAngle()); } } } return pArcT; } static bool TangentArcAndArc(AcDbArc *pArc1, AcDbArc *pArc2, double dR) { //圆弧1 圆弧2 之间相切 更改Arc1,2 return false; } static void SetCurveEndPoint(AcDbCurve* pCrv, AcGePoint3d& ptE) { AcDbLine *pLn = AcDbLine::cast(pCrv); if (pLn != NULL) { pLn->setEndPoint(ptE); } AcDbArc *pArc = AcDbArc::cast(pCrv); if (pArc != NULL) { AcGePoint3d ptS, ptM; pArc->getStartPoint(ptS); ptM = GetArcMidPoint(pArc); AcDbArc *pArcNew = FormatArc(ptS, ptM, ptE); if (pArcNew != NULL) { pArc->setStartAngle(pArcNew->startAngle()); pArc->setEndAngle(pArcNew->endAngle()); pArc->setCenter(pArcNew->center()); pArc->setRadius(pArcNew->radius()); delete pArcNew; } } } static void SetCurveStartPoint(AcDbCurve *pCrv, AcGePoint3d &ptS) { AcDbLine *pLn = AcDbLine::cast(pCrv); if (pLn != NULL) { pLn->setStartPoint(ptS); } AcDbArc *pArc = AcDbArc::cast(pCrv); if (pArc != NULL) { AcGePoint3d ptE, ptM; pArc->getEndPoint(ptE); ptM = GetArcMidPoint(pArc); AcDbArc *pArcNew = FormatArc(ptS, ptM, ptE); if (pArcNew != NULL) { pArc->setStartAngle(pArcNew->startAngle()); pArc->setEndAngle(pArcNew->endAngle()); pArc->setCenter(pArcNew->center()); pArc->setRadius(pArcNew->radius()); delete pArcNew; } } } Acad::ErrorStatus AecDb3dRoadAxisLine::ImpMoveGripPointsAt(const AcDbIntArray &indices, const AcDbIntArray &geomids,const AcGeVector3d &offset) { //获取曲线的序 AcArray arCurveDir; GetCurveDirs(arCurveDir); if (arCurveDir.isEmpty()) return Acad::eOk; if (indices.isEmpty()) return Acad::eOk; AcGePoint2d pt2d; bool bHasRadio = false;// ReadDandRatio(pt2d);2024-3-14 int nGripIndex = indices.first(); int nCurSeg = -1, nGripPos = -1,nLastSeg = 0,nNextSeg = -1; int nCrvCount = m_arCurvePtrs.length(); //acutPrintf(_T("\nGrip : %d"), nGripIndex); AcDbIntArray arSegIndexes, gripPoses; GetSegIndexOnGripIndex(arSegIndexes, gripPoses); nCurSeg = arSegIndexes.at(nGripIndex); nGripPos = gripPoses.at(nGripIndex); nLastSeg = nCurSeg - 1; nNextSeg = nCurSeg + 1; bool bSetSta = false, bSetEnd = false; AcGePoint3d ptS, ptE, ptMid,ptS0,ptE0; if (nCurSeg < nCrvCount && nCurSeg > -1) { AcDbCurve *pCurCrv = (AcDbCurve *)m_arCurvePtrs.at(nCurSeg); if (pCurCrv != NULL) { switch (nGripPos) { case 0://Sta { pCurCrv->getStartPoint(ptS); //如果Start接上段 if (nLastSeg > -1) { AcDbCurve* pLastCrv = (AcDbCurve *)m_arCurvePtrs.at(nLastSeg); if (pLastCrv != NULL) { pLastCrv->getStartPoint(ptS0); pLastCrv->getEndPoint(ptE0); if (ptS.distanceTo(ptS0) < 1.e-3)//接上sta { ptS += offset; SetCurveStartPoint(pCurCrv, ptS); bSetSta = true; SetCurveStartPoint(pLastCrv, ptS); } else if (ptS.distanceTo(ptE0) < 1.e-3)//接上end { ptS += offset; SetCurveStartPoint(pCurCrv, ptS); bSetSta = true; SetCurveEndPoint(pLastCrv, ptS); } } } //Start如果是接下段 if (nNextSeg < nCrvCount) { AcDbCurve *pNextCrv = (AcDbCurve *)m_arCurvePtrs.at(nNextSeg); if (pNextCrv != NULL) { pNextCrv->getStartPoint(ptS0); pNextCrv->getEndPoint(ptE0); if (ptS.distanceTo(ptS0) < 1.e-3)//接上sta { ptS += offset; SetCurveStartPoint(pCurCrv, ptS); bSetSta = true; SetCurveStartPoint(pNextCrv, ptS); } else if (ptS.distanceTo(ptE0) < 1.e-3)//接上end { ptS += offset; SetCurveStartPoint(pCurCrv, ptS); bSetSta = true; SetCurveEndPoint(pNextCrv, ptS); } } } if (!bSetSta) { ptS += offset; SetCurveStartPoint(pCurCrv, ptS); } break; } case 1://Mid { AcDbLine *pLnCur = AcDbLine::cast(pCurCrv); if (pLnCur != NULL) { pCurCrv->getStartPoint(ptS); if (nLastSeg > -1) { AcDbCurve *pLastCrv = (AcDbCurve *)m_arCurvePtrs.at(nLastSeg); if (pLastCrv != NULL) { pLastCrv->getStartPoint(ptS0); pLastCrv->getEndPoint(ptE0); if (ptS.distanceTo(ptS0) < 1.e-3)//接上sta { ptS += offset; SetCurveStartPoint(pLastCrv, ptS); } else if (ptS.distanceTo(ptE0) < 1.e-3)//接上end { ptS += offset; SetCurveEndPoint(pLastCrv, ptS); } } } if (nNextSeg < nCrvCount) { AcDbCurve *pNextCrv = (AcDbCurve *)m_arCurvePtrs.at(nNextSeg); if (pNextCrv != NULL) { pNextCrv->getStartPoint(ptS0); pNextCrv->getEndPoint(ptE0); if (ptS.distanceTo(ptS0) < 1.e-3)//接上sta { ptS += offset; SetCurveStartPoint(pNextCrv, ptS); } else if (ptS.distanceTo(ptE0) < 1.e-3)//接上end { ptS += offset; SetCurveEndPoint(pNextCrv, ptS); } } } pCurCrv->getEndPoint(ptE); if (nLastSeg > -1) { AcDbCurve *pLastCrv = (AcDbCurve *)m_arCurvePtrs.at(nLastSeg); if (pLastCrv != NULL) { pLastCrv->getStartPoint(ptS0); pLastCrv->getEndPoint(ptE0); if (ptE.distanceTo(ptS0) < 1.e-3)//接上sta { ptE += offset; SetCurveStartPoint(pLastCrv, ptE); } else if (ptE.distanceTo(ptE0) < 1.e-3)//接上end { ptE += offset; SetCurveEndPoint(pLastCrv, ptE); } } } if (nNextSeg < nCrvCount) { AcDbCurve *pNextCrv = (AcDbCurve *)m_arCurvePtrs.at(nNextSeg); if (pNextCrv != NULL) { pNextCrv->getStartPoint(ptS0); pNextCrv->getEndPoint(ptE0); if (ptE.distanceTo(ptS0) < 1.e-3)//接上sta { ptE += offset; SetCurveStartPoint(pNextCrv, ptE); } else if (ptE.distanceTo(ptE0) < 1.e-3)//接上end { ptE += offset; SetCurveEndPoint(pNextCrv, ptE); } } } pCurCrv->getStartPoint(ptS); pCurCrv->getEndPoint(ptE); ptS += offset; ptE += offset; pLnCur->setStartPoint(ptS); pLnCur->setEndPoint(ptE); } AcDbArc *pArcCur = AcDbArc::cast(pCurCrv); if (pArcCur != NULL) { ptMid = GetArcMidPoint(pArcCur); ptMid += offset; pArcCur->getStartPoint(ptS); pArcCur->getEndPoint(ptE); AcDbArc* pArcNew = FormatArc(ptS, ptMid, ptE); if (pArcNew != NULL) { pArcCur->setStartAngle(pArcNew->startAngle()); pArcCur->setEndAngle(pArcNew->endAngle()); pArcCur->setCenter(pArcNew->center()); pArcCur->setRadius(pArcNew->radius()); delete pArcNew; } } break; } case 2://End { pCurCrv->getEndPoint(ptE); if (nLastSeg > -1) { AcDbCurve *pLastCrv = (AcDbCurve *)m_arCurvePtrs.at(nLastSeg); if (pLastCrv != NULL) { pLastCrv->getStartPoint(ptS0); pLastCrv->getEndPoint(ptE0); if (ptE.distanceTo(ptS0) < 1.e-3)//接上sta { bSetEnd = true; ptE += offset; SetCurveEndPoint(pCurCrv, ptE); SetCurveStartPoint(pLastCrv, ptE); } else if (ptE.distanceTo(ptE0) < 1.e-3)//接上end { bSetEnd = true; ptE += offset; SetCurveEndPoint(pCurCrv, ptE); SetCurveEndPoint(pLastCrv, ptE); } } } if (nNextSeg < nCrvCount) { AcDbCurve *pNextCrv = (AcDbCurve *)m_arCurvePtrs.at(nNextSeg); if (pNextCrv != NULL) { pNextCrv->getStartPoint(ptS0); pNextCrv->getEndPoint(ptE0); if (ptE.distanceTo(ptS0) < 1.e-3)//接上sta { bSetEnd = true; ptE += offset; SetCurveEndPoint(pCurCrv, ptE); SetCurveStartPoint(pNextCrv, ptE); } else if (ptE.distanceTo(ptE0) < 1.e-3)//接上end { bSetEnd = true; ptE += offset; SetCurveEndPoint(pCurCrv, ptE); SetCurveEndPoint(pNextCrv, ptE); } } } if (!bSetEnd) { ptE += offset; SetCurveEndPoint(pCurCrv, ptE); } break; } default: break; } } } return Acad::eOk; } bool AecDb3dRoadAxisLine::AddPathHd(LPCTSTR pszHd) { assertWriteEnabled(); m_arPathHds.Add(pszHd); return true; } bool AecDb3dRoadAxisLine::GetPathHd(int i, CString &sHd) const { assertReadEnabled(); if (i > -1 && i < m_arPathHds.GetSize()) { sHd = m_arPathHds.GetAt(i); return true; } return false; } int AecDb3dRoadAxisLine::GetPathHdCount() const { assertReadEnabled(); return m_arPathHds.GetCount(); } void AecDb3dRoadAxisLine::RemovePathHd(int i) { assertWriteEnabled(); if (i > -1 && i < m_arPathHds.GetSize()) { m_arPathHds.RemoveAt(i); } } void AecDb3dRoadAxisLine::RemoveAllPathHd() { assertWriteEnabled(); m_arPathHds.RemoveAll(); } Acad::ErrorStatus AecDb3dRoadAxisLine::subErase(Adesk::Boolean erasing) { if (!m_arPathHds.IsEmpty()) { AecDbObjXDataMap xData; xData.Read(this, KEY_APP); double dOD = 0.0; xData.GetAt(PIPE_OD,dOD); CString sSys; xData.GetAt(KEY_SYS, sSys); //电缆 外径 mm if (dOD > 1.e-1) { struct resbuf *pRb = acutNewRb(AcDb::kDxfXdInteger16); pRb->resval.rint = erasing ? TRUE : FALSE; struct resbuf * pRb1 = acutNewRb(AcDb::kDxfXdAsciiString); acutNewString((LPCTSTR)sSys, pRb1->resval.rstring); struct resbuf *pRb2 = acutNewRb(AcDb::kDxfReal); pRb2->resval.rreal = dOD; pRb->rbnext = pRb1; pRb1->rbnext = pRb2; pRb2->rbnext = NULL; CString sHd,sHd2; AcDbObjectId id; for (int i = 0;i < m_arPathHds.GetSize();i++) { sHd2 = m_arPathHds.GetAt(i); sHd = sHd2; int nPos = sHd2.ReverseFind(_T('-')); if (nPos != -1) { sHd = sHd2.Mid(0, nPos); } AcDbHandle hd(sHd); if (Acad::eOk == acdbCurDwg()->getAcDbObjectId(id,false,hd)) { AcDbEntity *pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite)) { AecDbCurveBase *pCurBase = AecDbCurveBase::cast(pEnt); if (pCurBase != NULL) { pCurBase->SendUserData(pRb); } AecDbEntityBase *pEntBase = AecDbEntityBase::cast(pEnt); if (pEntBase != NULL) { pEntBase->SendUserData(pRb); } pEnt->close(); } } } } } return Acad::eOk; } void AecDb3dRoadAxisLine::subList() const { acutPrintf(_T("\n隧道轴线 : AEC_ROADAXISLINE")); acutPrintf(_T("\n隧道轴线段数:%d"),GetCurveSegCount()); acutPrintf(_T("\n总长 %g :"), getLength()); acutPrintf(_T("\n过度隧道半径:%d"), m_ptDR.x); acutPrintf(_T("\n过度曲率:%d"), m_ptDR.y); AecDbObjXDataMap xData; if (xData.Read((AcDbObject *)this, KEY_APP)) { xData.List(); } AcGePoint3d ptSta; getStartPoint(ptSta); acutPrintf(_T("\n起点 : %g,%g,%g"),ptSta.x,ptSta.y,ptSta.z); AcGePoint3d ptEnd; getEndPoint(ptEnd); acutPrintf(_T("\n终点 : %g,%g,%g"),ptEnd.x,ptEnd.y,ptEnd.z); if (!m_arPathHds.IsEmpty()) { acutPrintf(_T("\n路径信息:")); for (int i = 0;i < m_arPathHds.GetSize();i++) { acutPrintf(_T("\n经过路径句柄%s:"),m_arPathHds.GetAt(i)); } } acutPrintf(_T("\n段信息:")); AcDbCurve* pCurve = NULL; for(int i = 0;i < m_arCurvePtrs.length();i++) { acutPrintf(_T("\n第%d段信息:"),i+1); pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if (pCurve != NULL) { #ifndef ZWCAD pCurve->list(); #endif } } } Acad::ErrorStatus AecDb3dRoadAxisLine::subGetGeomExtents(AcDbExtents& extents) const { assertReadEnabled(); AcDbExtents extT; AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); pCurve->getGeomExtents(extT); extents.addExt(extT); } return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::copyFrom(const AcRxObject* pSrc) { AssertWriteEnabled(); m_arCurvePtrs.removeAll(); AecDb3dRoadAxisLine* pAxLn = AecDb3dRoadAxisLine::cast(pSrc); if (pAxLn != NULL) { AcDbCurve* pCurve = NULL,*pCln = NULL; for (int i = 0;i < pAxLn->m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)pAxLn->m_arCurvePtrs.at(i); if (!pCurve) continue; pCln = (AcDbCurve*)pCurve->clone(); if (pCln != NULL) { m_arCurvePtrs.append(pCln); } } struct resbuf* pRb = pAxLn->xData(); if (pRb != NULL) { setXData(pRb); acutRelRb(pRb); } m_ptDR = pAxLn->m_ptDR; } return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::ReMakeSureCopy(AcDbCurve* pCurTo,AcDbCurve* pCurFr) { //!!! AcDbLine* pLn = AcDbLine::cast(pCurTo); if (pLn != NULL) { AcDbLine* pLn2 = AcDbLine::cast(pCurFr); if (pLn2 != NULL) { pLn->setStartPoint(pLn2->startPoint()); pLn->setEndPoint(pLn2->endPoint()); } } AcDbArc* pArc = AcDbArc::cast(pCurTo); if (pArc != NULL) { AcDbArc* pArc2 = AcDbArc::cast(pCurFr); if (pArc2 != NULL) { pArc->setCenter(pArc2->center()); pArc->setRadius(pArc2->radius()); pArc->setStartAngle(pArc2->startAngle()); pArc->setEndAngle(pArc2->endAngle()); } } AcDbCircle* pCir = AcDbCircle::cast(pCurTo); if (pCir != NULL) { AcDbCircle* pCir2 = AcDbCircle::cast(pCurFr); if (pCir2 != NULL) { pCir->setCenter(pCir2->center()); pCir->setRadius(pCir2->radius()); } } AcDbPolyline* pPl = AcDbPolyline::cast(pCurTo); if (pPl != NULL) { AcDbPolyline* pPl2 = AcDbPolyline::cast(pCurFr); if (pPl2 != NULL) { while(pPl->numVerts() > 0) { pPl->removeVertexAt(0); } AcGePoint2d pt2d; double dBulge = 0.0,dSta = 0.0,dEnd = 0.0; for (int i = 0;i < pPl2->numVerts();i++) { pPl2->getPointAt(i,pt2d); pPl2->getBulgeAt(i,dBulge); pPl2->getWidthsAt(i,dSta,dEnd); pPl->addVertexAt(i,pt2d,dBulge,dSta,dEnd);; } } } return Acad::eOk; } bool AecDb3dRoadAxisLine::ReMakeSureCopy(AecDb3dRoadAxisLine* pRoad2) { if (pRoad2 != NULL) { if ( GetCurveSegCount() == pRoad2->GetCurveSegCount() ) { AcDbCurve* pCurveTo = NULL,*pCurveFr = NULL; for (int i = 0;i < GetCurveSegCount();i++) { pCurveTo = GetCurveSeg(i); pCurveFr = pRoad2->GetCurveSeg(i); AecDb3dRoadAxisLine::ReMakeSureCopy(pCurveTo,pCurveFr); } } } return true; } Acad::ErrorStatus AecDb3dRoadAxisLine::subTransformBy(const AcGeMatrix3d &xform) { AssertWriteEnabled(); AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); pCurve->transformBy(xform); } return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::subIntersectWith( const AcDbEntity* ent, AcDb::Intersect intType, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { assertReadEnabled(); AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if ( Acad::eOk == pCurve->intersectWith(ent,intType,points,thisGsMarker,otherGsMarker)) { } } return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::subIntersectWith( const AcDbEntity* ent, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { assertReadEnabled(); AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if ( Acad::eOk == pCurve->intersectWith(ent,intType,projPlane,points,thisGsMarker,otherGsMarker)) { } } return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::subExplode(AcDbVoidPtrArray& entitySet) const { assertReadEnabled(); AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); entitySet.append((AcDbCurve*)pCurve->clone()); } return Acad::eOk; } Adesk::Boolean AecDb3dRoadAxisLine::isPlanar() const { return Adesk::kFalse; } Acad::ErrorStatus AecDb3dRoadAxisLine::getPlane(AcGePlane&, AcDb::Planarity&) const { return Acad::eOk; } #if ARX>17 Acad::ErrorStatus AecDb3dRoadAxisLine::reverseCurve() { AssertWriteEnabled(); m_arCurvePtrs.reverse(); AcGePoint3d ptSta,ptEnd; AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); AcDbLine* pLn = AcDbLine::cast(pCurve); if (pLn != NULL) { ptSta = pLn->startPoint(); ptEnd = pLn->endPoint(); pLn->setStartPoint(ptEnd); pLn->setEndPoint(ptSta); } } return Acad::eOk; } #endif Adesk::Boolean AecDb3dRoadAxisLine::isClosed() const { assertReadEnabled(); AcGePoint3d ptSta,ptEnd; if ( Acad::eOk == getStartPoint(ptSta) && Acad::eOk == getEndPoint(ptEnd) ) { if ( ptSta.distanceTo(ptEnd) < 1.e-3) { return Adesk::kTrue; } } return Adesk::kFalse; } //是否是周期函数 Adesk::Boolean AecDb3dRoadAxisLine::isPeriodic() const { assertReadEnabled(); return Adesk::kFalse; } Acad::ErrorStatus AecDb3dRoadAxisLine::getStartParam(double ¶m) const { assertReadEnabled(); param = 0.; return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::getEndParam(double ¶m) const { assertReadEnabled(); double dEnd = 0.0,dDist = 0.0; AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); pCurve->getEndParam(dEnd); pCurve->getDistAtParam(dEnd,dDist); param += dDist; } return Acad::eOk; } void AecDb3dRoadAxisLine::ImpGetEnd2End(AcDbVoidPtrArray& arGet, AcGePoint3d& ptOn,double dTol /* = 1.e-3*/) { AcGePoint3d ptSta, ptEnd; AcDbCurve *pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve *)m_arCurvePtrs.at(i); pCurve->getStartPoint(ptSta); pCurve->getEndPoint(ptEnd); if (ptSta.distanceTo(ptOn) <= dTol) { arGet.append(pCurve); ptOn = ptEnd; m_arCurvePtrs.removeAt(i); i = -1;//从头开始 continue; } if (ptEnd.distanceTo(ptOn) < dTol) { arGet.append(pCurve); ptOn = ptSta; m_arCurvePtrs.removeAt(i); i = -1;//从头开始 continue; } } } Acad::ErrorStatus AecDb3dRoadAxisLine::MakeEndToEnd() { AcDbVoidPtrArray arLeft, arRight; AcDbCurve *pCurve = NULL; if (!m_arCurvePtrs.isEmpty()) { pCurve = (AcDbCurve *)m_arCurvePtrs.first(); AcGePoint3d ptSta, ptEnd; pCurve->getStartPoint(ptSta); pCurve->getEndPoint(ptEnd); double dTol = 1.e-2;// //断开 m_arCurvePtrs.remove(pCurve); ImpGetEnd2End(arLeft, ptSta,dTol); ImpGetEnd2End(arRight, ptEnd,dTol); m_arCurvePtrs.removeAll(); arLeft.reverse(); m_arCurvePtrs.append(arLeft); m_arCurvePtrs.append(pCurve); m_arCurvePtrs.append(arRight); } return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::getStartPoint(AcGePoint3d &pt) const { assertReadEnabled(); double dTol = 1.e-6;//毫米默认 struct resbuf rb; acedGetVar(_T("INSUNITS"), &rb); if (rb.resval.rint == AcDb::kUnitsMeters) { dTol = 1.e-3;//米 } else if (rb.resval.rint == AcDb::kUnitsCentimeters) { dTol = 1.e-4;//厘米 } else if (rb.resval.rint == AcDb::kUnitsMillimeters) { dTol = 1.e-6;//毫米 } else if (rb.resval.rint == AcDb::kUnitsDecimeters) { dTol = 1.e-5;//分米 } KTTempTol tol(dTol); AcDbCurve* pCurve = NULL; if (!m_arCurvePtrs.isEmpty()) { //在添加时已经保证顺序,所以直接去末端起点 pCurve = (AcDbCurve*)m_arCurvePtrs.first();// AcGePoint3d ptS,ptE; pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); AcGePoint3dArray arPts; arPts.append(ptS); arPts.append(ptE); if (m_arCurvePtrs.length() >= 2)//有两根 { //next AcDbCurve *pCurve1 = (AcDbCurve *)m_arCurvePtrs.at(1); AcGePoint3d ptS2, ptE2; pCurve1->getStartPoint(ptS2); pCurve1->getEndPoint(ptE2); int nPos = -1; if ( arPts.find(ptS2, nPos, 0) ) { arPts.removeAt(nPos); pt = arPts.first(); return Acad::eOk; } if (arPts.find(ptE2, nPos, 0)) { arPts.removeAt(nPos); pt = arPts.first(); return Acad::eOk; } } else { pt = ptS; return Acad::eOk; } } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::getEndPoint(AcGePoint3d& pt) const { double dTol = 1.e-6;//毫米默认 struct resbuf rb; acedGetVar(_T("INSUNITS"), &rb); if (rb.resval.rint == AcDb::kUnitsMeters) { dTol = 1.e-3;//米 } else if (rb.resval.rint == AcDb::kUnitsCentimeters) { dTol = 1.e-4;//厘米 } else if (rb.resval.rint == AcDb::kUnitsMillimeters) { dTol = 1.e-6;//毫米 } else if (rb.resval.rint == AcDb::kUnitsDecimeters) { dTol = 1.e-5;//分米 } KTTempTol tol(dTol); AcDbCurve *pCurve = NULL; if (!m_arCurvePtrs.isEmpty()) { //在添加时已经保证顺序,所以直接去末端起点 pCurve = (AcDbCurve *)m_arCurvePtrs.last();// AcGePoint3d ptS, ptE; pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); AcGePoint3dArray arPts; arPts.append(ptS); arPts.append(ptE); if (m_arCurvePtrs.length() >= 2)//有两根 { int nTail = m_arCurvePtrs.length() - 1; AcDbCurve *pCurve1 = (AcDbCurve *)m_arCurvePtrs.at(nTail - 1); AcGePoint3d ptS2, ptE2; pCurve1->getStartPoint(ptS2); pCurve1->getEndPoint(ptE2); int nPos = -1; if (arPts.find(ptS2, nPos, 0)) { arPts.removeAt(nPos); pt = arPts.last(); return Acad::eOk; } if (arPts.find(ptE2, nPos, 0)) { arPts.removeAt(nPos); pt = arPts.last(); return Acad::eOk; } } else { pt = ptE; return Acad::eOk; } } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::getPointAtParam(double dParam, AcGePoint3d &ptGe) const { assertReadEnabled(); //获取曲线的序 AcArray arCurveDir; GetCurveDirs(arCurveDir); //param 为长度 AcDbCurve* pCurve = NULL; if (!m_arCurvePtrs.isEmpty()) { double dEnd = 0.0,dLenT = 0.0,dDist = 0.0; if (fabs(dParam) < 1.e-6) { return getStartPoint(ptGe); } AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); pCurve->getEndParam(dEnd); pCurve->getDistAtParam(dEnd,dLenT); dDist += dLenT; if (dParam - dDist < 1.e-10)//落在此段 { const CurveDir& dir = arCurveDir.at(i); dDist -= dLenT;//恢复前面的总长 dParam -= dDist;//本段距离位置 if (dir.bDir)//顺序 { } else { dParam = dLenT - dParam; } if (fabs(dParam) < 1.e-6)//认为为起点 { pCurve->getStartPoint(ptGe); return Acad::eOk; } //在添加时已经保证顺序,所以取Distpos return pCurve->getPointAtDist(dParam,ptGe); } } } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::getParamAtPoint(const AcGePoint3d &givenPnt, double ¶m)const { // 假设 givenPnt 在线上 assertReadEnabled(); AcDbCurve* pCurve = NULL; if (m_arCurvePtrs.length() == 1) { pCurve = (AcDbCurve*)m_arCurvePtrs.first(); return pCurve->getParamAtPoint(givenPnt,param); } //获取曲线的序 AcArray arCurveDir; GetCurveDirs(arCurveDir); AcGePoint3d ptOn; Acad::ErrorStatus es; double dDistHere = 0.0,dDist = 0.0,dEnd = 0.0,dLen = 0.0,dDistT = 0.0; for (int i = 0;i < arCurveDir.length();i++) { const CurveDir& cDir = arCurveDir.at(i); pCurve = cDir.pCurve; pCurve->getClosestPointTo(givenPnt,ptOn,Adesk::kTrue); if ( Acad::eOk == (es = pCurve->getDistAtPoint(ptOn,dDistHere)))//落在本段 { if (cDir.bDir)//正序 { param = dDistHere + dDist; } else//反序 { pCurve->getEndParam(dEnd); pCurve->getDistAtParam(dEnd,dDistT); param =(dDistT - dDistHere) + dDist; } return Acad::eOk; } else { //继续,加长度 pCurve->getEndParam(dEnd); pCurve->getDistAtParam(dEnd,dLen); dDist += dLen; } } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::getDistAtParam(double param, double &dist) const { assertReadEnabled(); //长度距离为参数 dist = param; return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::getParamAtDist(double dist, double ¶m) const { assertReadEnabled(); param = dist; return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::getDistAtPoint(const AcGePoint3d &pt, double &dist)const { assertReadEnabled(); return getParamAtPoint(pt, dist); } Acad::ErrorStatus AecDb3dRoadAxisLine::getPointAtDist(double dist, AcGePoint3d &pt) const { assertReadEnabled(); return getPointAtParam(dist, pt); } Acad::ErrorStatus AecDb3dRoadAxisLine::getFirstDeriv(double param, AcGeVector3d &firstDeriv) const { assertReadEnabled(); //获取曲线的序 CurveDir crDir; AcArray arCurveDir; GetCurveDirs(arCurveDir); AcDbCurve* pCurve = NULL; //param为距离 AcGePoint3d ptGe; if ( Acad::eOk == getPointAtParam(param,ptGe) ) { AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if ( Acad::eOk == pCurve->getFirstDeriv(ptGe,firstDeriv))//落在本段 { crDir = arCurveDir.at(i); if (!crDir.bDir)//反序 { firstDeriv.negate(); } return Acad::eOk; } } } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::getFirstDeriv(const AcGePoint3d& ptGe, AcGeVector3d &firstDeriv) const { assertReadEnabled(); //获取曲线的序 CurveDir crDir; AcArray arCurveDir; GetCurveDirs(arCurveDir); AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if ( Acad::eOk == pCurve->getFirstDeriv(ptGe,firstDeriv))//落在本段 { crDir = arCurveDir.at(i); if (!crDir.bDir)//反序 { firstDeriv.negate(); } return Acad::eOk; } } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::getSecondDeriv(double param, AcGeVector3d &secDeriv) const { assertReadEnabled(); //获取曲线的序 CurveDir crDir; AcArray arCurveDir; GetCurveDirs(arCurveDir); AcDbCurve* pCurve = NULL; //param为距离 AcGePoint3d ptGe; if ( Acad::eOk == getPointAtParam(param,ptGe) ) { for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if ( Acad::eOk == pCurve->getSecondDeriv(ptGe,secDeriv))//落在本段 { crDir = arCurveDir.at(i); if (!crDir.bDir)//反序 { secDeriv.negate(); } return Acad::eOk; } } } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::getSecondDeriv(const AcGePoint3d& ptGe, AcGeVector3d &secDeriv) const { assertReadEnabled(); //获取曲线的序 AcArray arCurveDir; GetCurveDirs(arCurveDir); AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if ( Acad::eOk == pCurve->getSecondDeriv(ptGe,secDeriv))//落在本段 { return Acad::eOk; } } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::getClosestPointTo(const AcGePoint3d &givenPnt, AcGePoint3d &pointOnCurve, Adesk::Boolean extend /*= Adesk::kFalse*/) const { assertReadEnabled(); AcGePoint3d ptOn,ptClosePt; double dDist = -1.0,dDistT = 0.0; AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if ( Acad::eOk == pCurve->getClosestPointTo(givenPnt,ptOn,( i ==0 || i == m_arCurvePtrs.length() - 1) ? extend : Adesk::kFalse ) )//中间不许extend { dDistT = ptOn.distanceTo(givenPnt); if (dDist < -0.9 )//是-1.0首次 { if (dDistT > -1.e-6) { dDist = dDistT; ptClosePt = ptOn; } } else { if (dDistT - dDist < 1.e-6) { dDist = dDistT; ptClosePt = ptOn; } } } } if (dDist > -1.e-10) { pointOnCurve = ptClosePt; return Acad::eOk; } return Acad::eInvalidInput; } int AecDb3dRoadAxisLine::getClosestPointToIndex(const AcGePoint3d& givenPnt,AcGePoint3d& pointOnCurve) const { AcGePoint3d ptClosePt,ptOn; int nIndex = -1; double dDist = -1.0,dDistT = 0.0; AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if ( Acad::eOk == pCurve->getClosestPointTo(givenPnt,ptOn,Adesk::kFalse ) )//中间不许extend { dDistT = ptOn.distanceTo(givenPnt); if (dDist < -0.9 )//是-1.0首次 { if (dDistT > -1.e-6) { dDist = dDistT; ptClosePt = ptOn; nIndex = i; } } else { if (dDistT - dDist < 1.e-6) { dDist = dDistT; ptClosePt = ptOn; nIndex = i; } } } } if (dDist > -1.e-10) { pointOnCurve = ptClosePt; return nIndex; } return -1; } Acad::ErrorStatus AecDb3dRoadAxisLine::getClosestPointTo(const AcGePoint3d& givenPnt, const AcGeVector3d& direction, AcGePoint3d& pointOnCurve, Adesk::Boolean extend /*= Adesk::kFalse*/) const { assertReadEnabled(); AcGePoint3d ptOn,ptClosePt; double dDist = -1.0,dDistT = 0.0; AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if ( Acad::eOk == pCurve->getClosestPointTo(givenPnt,direction,ptOn,( i == 0 || i == m_arCurvePtrs.length() - 1) ? extend : Adesk::kFalse) )//中间不许extend { dDistT = ptOn.distanceTo(givenPnt); if (dDist < -0.9 )//是-1.0首次 { if (dDistT > -1.e-6) { dDist = dDistT; ptClosePt = ptOn; } } else { if (dDistT - dDist < 1.e-6) { dDist = dDistT; ptClosePt = ptOn; } } } } if (dDist > -1.e-10) { pointOnCurve = ptClosePt; return Acad::eOk; } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::getSplitCurves(const AcGeDoubleArray& params, AcDbVoidPtrArray& curveSegments) const { assertReadEnabled(); //暂时不实现 return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDb3dRoadAxisLine::getSplitCurves(const AcGePoint3dArray& points, AcDbVoidPtrArray& curveSegments) const { assertReadEnabled(); //暂时不实现 return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDb3dRoadAxisLine::extend(double newParam) { //暂时不实现 return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDb3dRoadAxisLine::extend(Adesk::Boolean extendStart, const AcGePoint3d& toPoint) { //暂时不实现 return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDb3dRoadAxisLine::getSpline(AcDbSpline*& spline) const { //暂时不实现 return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDb3dRoadAxisLine::getArea(double& dArea) const { assertReadEnabled(); //暂时不实现 return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDb3dRoadAxisLine::getOffsetCurves(double offsetDist, AcDbVoidPtrArray &offsetCurves) const { assertReadEnabled(); AecDb3dRoadAxisLine *pRoadAL = (AecDb3dRoadAxisLine *)this->clone(); if (pRoadAL != NULL) { pRoadAL->offset(offsetDist); offsetCurves.append(pRoadAL); } return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::getOffsetCurvesGivenPlaneNormal(const AcGeVector3d& normal, double offsetDist,AcDbVoidPtrArray& offsetCurves) const { assertReadEnabled(); AcDbPolyline* pPl = ConvertTo2dPline(); if (pPl != NULL) { pPl->getOffsetCurvesGivenPlaneNormal(normal,offsetDist,offsetCurves); delete pPl; return Acad::eOk; } //其他暂时不实现 return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDb3dRoadAxisLine::getProjectedCurve(const AcGePlane& plan, const AcGeVector3d& projDir, AcDbCurve*& projCrv) const { assertReadEnabled(); AcDbCurve* pCurve = NULL; AcDbCurve* pProjCrvT = NULL; AcDbVoidPtrArray arCurPtrs,arpResult; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if (pCurve != NULL) { pProjCrvT = NULL; pCurve->getProjectedCurve(plan,projDir,pProjCrvT); if (pProjCrvT != NULL) { arCurPtrs.append(pProjCrvT); } } } AcDbCurve* pBaseCurve = KTCADUtilityEx::ConvertBoundCurve(arCurPtrs, arpResult); if (pBaseCurve != NULL) { projCrv = pBaseCurve; return Acad::eOk; } return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDb3dRoadAxisLine::getOrthoProjectedCurve(const AcGePlane& plan, AcDbCurve*& projCrv) const { assertReadEnabled(); AcDbCurve* pCurve = NULL; AcDbCurve* pProjCrvT = NULL; AcGeVector3d vt; AcDbVoidPtrArray arCurPtrs,arpResult; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if (pCurve != NULL) { pProjCrvT = NULL; AcDbArc* pArc = AcDbArc::cast(pCurve); if (pArc != NULL) { vt = pArc->normal(); if (vt.isParallelTo(plan.normal())) { AcDbArc* pArcCln = (AcDbArc*)pArc->clone(); AcGePoint3d ptCen = pArc->center(); ptCen = plan.closestPointTo(ptCen); pArcCln->setCenter(ptCen); pProjCrvT = pArcCln; } } else { pCurve->getOrthoProjectedCurve(plan,pProjCrvT); } if (pProjCrvT != NULL) { arCurPtrs.append(pProjCrvT); } } } AcDbCurve* pBaseCurve = KTCADUtilityEx::ConvertBoundCurve(arCurPtrs, arpResult); if (pBaseCurve != NULL) { projCrv = pBaseCurve; return Acad::eOk; } return Acad::eNotImplementedYet; } #if ARX>18 Acad::ErrorStatus AecDb3dRoadAxisLine::getAcGeCurve ( AcGeCurve3d*& pGeCurve,const AcGeTol& tol) const { assertReadEnabled(); return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDb3dRoadAxisLine::setFromAcGeCurve ( const AcGeCurve3d& geCurve,AcGeVector3d *normal, const AcGeTol& tol) { AssertWriteEnabled(); return Acad::eNotImplementedYet; } #endif AcDbCurve* AecDb3dRoadAxisLine::BaseCurveDwgInFields(LPCTSTR pszCurve) { ////[LINE...][ARC...][LINE...][ARC...] CString sText = pszCurve; int nPos = sText.Find(_T(':')); if (nPos != -1) { CString sClass = sText.Mid(0,nPos); CString sData = sText.Mid(nPos + 1); if (sClass.CompareNoCase(_T("LINE")) == 0) { CStringArray arData; CoreTools::SplitStrintToArray(sData,arData,_T(',')); //%g,%g,%g,%g,%g,%g,%g,%g,%g if (arData.GetSize() == 9) { AcGePoint3d ptSta,ptEnd; AcGeVector3d vtNor; ptSta.set(_ttof(arData.GetAt(0)),_ttof(arData.GetAt(1)),_ttof(arData.GetAt(2))); ptEnd.set(_ttof(arData.GetAt(3)),_ttof(arData.GetAt(4)),_ttof(arData.GetAt(5))); vtNor.set(_ttof(arData.GetAt(6)),_ttof(arData.GetAt(7)),_ttof(arData.GetAt(8))); AcDbLine* pLine = new AcDbLine; pLine->setStartPoint(ptSta); pLine->setEndPoint(ptEnd); pLine->setNormal(vtNor); return pLine; } } else if (sClass.CompareNoCase(_T("ARC")) == 0) { //%g,%g,%g,%g,%g,%g,%g,%g,%g CStringArray arData; CoreTools::SplitStrintToArray(sData,arData,_T(',')); if (arData.GetSize() == 9) { AcGePoint3d ptCen; double dRad,dSta,dEnd; AcGeVector3d vtNor; ptCen.set(_ttof(arData.GetAt(0)),_ttof(arData.GetAt(1)),_ttof(arData.GetAt(2))); dRad = _ttof(arData.GetAt(3));dSta = _ttof(arData.GetAt(4));dEnd = _ttof(arData.GetAt(5)); vtNor.set(_ttof(arData.GetAt(6)),_ttof(arData.GetAt(7)),_ttof(arData.GetAt(8))); AcDbArc* pArc = new AcDbArc; pArc->setCenter(ptCen);pArc->setRadius(dRad); pArc->setStartAngle(dSta);pArc->setEndAngle(dEnd); pArc->setNormal(vtNor); return pArc; } } } return NULL; } AcDbCurve* AecDb3dRoadAxisLine::BaseCurveDwgInFields(AcDbDwgFiler* pFiler) { TCHAR* pszClass = NULL; pFiler->readString(&pszClass); AcRxObject* pRx = acrxClassDictionary->at(pszClass); if (pRx != NULL) { acutDelString(pszClass); AcRxClass* pRxClass = (AcRxClass* )pRx; AcDbCurve* pBaseCurve = (AcDbCurve*)pRxClass->create(); AcGeVector3d vtNorm; AcDbLine* pLine = AcDbLine::cast(pBaseCurve); if (pLine != NULL) { AcGePoint3d ptSta,ptEnd; pFiler->readPoint3d(&ptSta); pFiler->readPoint3d(&ptEnd); pFiler->readVector3d(&vtNorm); pLine->setStartPoint(ptSta); pLine->setEndPoint(ptEnd); pLine->setNormal(vtNorm); return pBaseCurve; } AcDbArc* pArc = AcDbArc::cast(pBaseCurve); if (pArc != NULL) { AcGePoint3d ptCen; double dRad = 0.0,dSta = 0.0,dEnd = 0.0; pFiler->readPoint3d(&ptCen); pFiler->readDouble(&dRad); pFiler->readDouble(&dSta); pFiler->readDouble(&dEnd); pFiler->readVector3d(&vtNorm); pArc->setCenter(ptCen); pArc->setRadius(dRad); pArc->setStartAngle(dSta); pArc->setEndAngle(dEnd); pArc->setNormal(vtNorm); return pBaseCurve; } } return NULL; } bool AecDb3dRoadAxisLine::GetAsString(CString& sScript) const { assertReadEnabled(); CString sCurve = _T(""); AcDbCurve* pCurve = NULL; int nLen = m_arCurvePtrs.length(); for (int i = 0;i < nLen;i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); sCurve = _T(""); BaseCurveDwgOutFields(pCurve,sCurve); if (!sCurve.IsEmpty()) sScript += sCurve; } return true; } bool AecDb3dRoadAxisLine::SetFromString(LPCTSTR pszScript) { AssertWriteEnabled(); //[LINE...][ARC...][LINE...][ARC...] CString sScript = pszScript; if (sScript.IsEmpty()) return false; CStringArray arSegs; CoreTools::SplitStrintToArray(pszScript,arSegs,_T(']')); FreeBuffer(0,m_arCurvePtrs); m_arCurvePtrs.removeAll(); CString sSeg; for (int i = 0;i < arSegs.GetSize();i++) { sSeg = arSegs.GetAt(i); sSeg.TrimLeft(_T('[')); AcDbCurve* pCurve = BaseCurveDwgInFields(sSeg); if (pCurve != NULL) { m_arCurvePtrs.append(pCurve); } } return !m_arCurvePtrs.isEmpty(); } Acad::ErrorStatus AecDb3dRoadAxisLine::setColorIndex(Adesk::UInt16 color, Adesk::Boolean doSubents /*= true*/) { assertWriteEnabled(); AcDbCurve *pCurve = NULL; for (int i = 0; i < m_arCurvePtrs.length(); i++) { pCurve = (AcDbCurve *)m_arCurvePtrs.at(i); pCurve->setColorIndex(color, doSubents); } return AcDbCurve::setColorIndex(color, doSubents); } Acad::ErrorStatus AecDb3dRoadAxisLine::setLayer(const ACHAR *newVal,Adesk::Boolean doSubents /*= true*/,bool allowHiddenLayer /*= false*/) { assertWriteEnabled(); AcDbCurve *pCurve = NULL; for (int i = 0; i < m_arCurvePtrs.length(); i++) { pCurve = (AcDbCurve *)m_arCurvePtrs.at(i); pCurve->setLayer(newVal, doSubents); } return AcDbCurve::setLayer(newVal, doSubents); } Acad::ErrorStatus AecDb3dRoadAxisLine::setLayer(AcDbObjectId newVal,Adesk::Boolean doSubents /*= true*/,bool allowHiddenLayer /*= false*/) { assertWriteEnabled(); AcDbCurve *pCurve = NULL; for (int i = 0; i < m_arCurvePtrs.length(); i++) { pCurve = (AcDbCurve *)m_arCurvePtrs.at(i); pCurve->setLayer(newVal, doSubents); } return AcDbCurve::setLayer(newVal, doSubents); } Acad::ErrorStatus AecDb3dRoadAxisLine::setLinetype(const ACHAR *newVal, Adesk::Boolean doSubents /*= true*/) { assertWriteEnabled(); AcDbCurve *pCurve = NULL; for (int i = 0; i < m_arCurvePtrs.length(); i++) { pCurve = (AcDbCurve *)m_arCurvePtrs.at(i); pCurve->setLinetype(newVal, doSubents); } return AcDbCurve::setLinetype(newVal, doSubents); } Acad::ErrorStatus AecDb3dRoadAxisLine::setLinetype(AcDbObjectId newVal, Adesk::Boolean doSubents /*= true*/) { assertWriteEnabled(); AcDbCurve *pCurve = NULL; for (int i = 0; i < m_arCurvePtrs.length(); i++) { pCurve = (AcDbCurve *)m_arCurvePtrs.at(i); pCurve->setLinetype(newVal, doSubents); } return AcDbCurve::setLinetype(newVal, doSubents); } Acad::ErrorStatus AecDb3dRoadAxisLine::dwgInFields(AcDbDwgFiler* pFiler) { AssertWriteEnabled(); Acad::ErrorStatus es = Acad::eOk; if ( !pFiler->isKindOf(CMFCDbDwgFiler::desc())) { es = AecDbCurveBase::dwgInFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; } Adesk::UInt32 version = 0; if ((es = pFiler->readUInt32(&version)) != Acad::eOk) return (es); if (version > AecDb3dRoadAxisLine::kCurrentVersionNumber) return (Acad::eMakeMeProxy); FreeBuffer(0,m_arCurvePtrs); m_arCurvePtrs.removeAll(); Adesk::UInt32 nLen = 0; pFiler->readUInt32(&nLen); TCHAR* pszClassName = NULL; AcDbCurve* pCurve = NULL; for (int i = 0;i < nLen;i++) { if ( !pFiler->isKindOf(CMFCDbDwgFiler::desc()))//CAD方式 { if (version > 3) { pCurve = BaseCurveDwgInFields(pFiler); m_arCurvePtrs.append(pCurve); } else { pFiler->readString(&pszClassName); AcRxObject* pRx = acrxClassDictionary->at(pszClassName); if (pRx != NULL) { AcRxClass* pRxClass = (AcRxClass* )pRx; pCurve = (AcDbCurve*)pRxClass->create(); es = pCurve->dwgInFields(pFiler); #ifndef ZWCAD pCurve->list(); #endif m_arCurvePtrs.append(pCurve);//此处禁止调用AppendCurveSeg ,否则导致assertwrite出错 } } } else { pCurve = BaseCurveDwgInFields(pFiler); m_arCurvePtrs.append(pCurve);//此处禁止调用AppendCurveSeg ,否则导致assertwrite出错 } } pFiler->readInt16(&m_nInfActive); if ( version > 1) { pFiler->readPoint2d(&m_ptDR); } if (version > 2) { nLen = 0; pFiler->readUInt32(&nLen); m_arPathHds.RemoveAll(); TCHAR *pszHd = NULL; for (int i = 0;i < nLen;i++) { pszHd = NULL; pFiler->readString(&pszHd); if (pszHd != NULL) { m_arPathHds.Add(pszHd); } } } return (pFiler->filerStatus()); } Acad::ErrorStatus AecDb3dRoadAxisLine::BaseCurveDwgOutFields(AcDbCurve* pBaseCurve,CString& sCurve) const { assertReadEnabled(); if (pBaseCurve != NULL) { AcDbLine* pLine = AcDbLine::cast(pBaseCurve); if (pLine != NULL) { //[LINE:sta,end,normal] //[LINE:%g,%g,%g,%g,%g,%g,%g,%g,%g] AcGePoint3d ptSta = pLine->startPoint(); AcGePoint3d ptEnd = pLine->endPoint(); AcGeVector3d vtNorm = pLine->normal(); sCurve.Format(_T("[LINE:%.9f,%.9f,%.9f,%.9f,%.9f,%.9f,%.9f,%.9f,%.9f]"),ptSta.x,ptSta.y,ptSta.z,ptEnd.x,ptEnd.y,ptEnd.z,vtNorm.x,vtNorm.y,vtNorm.z); return Acad::eOk; } AcDbArc* pArc = AcDbArc::cast(pBaseCurve); if (pArc != NULL) { //[ARC:cen,rad,staa,enda,normal] //[ARC:%g,%g,%g,%g,%g,%g,%g,%g,%g] AcGePoint3d ptCen = pArc->center(); AcGeVector3d vtNorm = pArc->normal(); sCurve.Format(_T("[ARC:%.9f,%.9f,%.9f,%.9f,%.9f,%.9f,%.9f,%.9f,%.9f]"),ptCen.x,ptCen.y,ptCen.z,pArc->radius(),pArc->startAngle(),pArc->endAngle(),vtNorm.x,vtNorm.y,vtNorm.z); return Acad::eOk; } } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::BaseCurveDwgOutFields(AcDbCurve* pBaseCurve,AcDbDwgFiler* pFiler) const { assertReadEnabled(); if (pBaseCurve != NULL) { LPCTSTR pszClass = pBaseCurve->isA()->name(); pFiler->writeString(pszClass); AcDbLine* pLine = AcDbLine::cast(pBaseCurve); if (pLine != NULL) { pFiler->writePoint3d(pLine->startPoint()); pFiler->writePoint3d(pLine->endPoint()); pFiler->writeVector3d(pLine->normal()); return Acad::eOk; } AcDbArc* pArc = AcDbArc::cast(pBaseCurve); if (pArc != NULL) { pFiler->writePoint3d(pArc->center()); pFiler->writeDouble(pArc->radius()); pFiler->writeDouble(pArc->startAngle()); pFiler->writeDouble(pArc->endAngle()); pFiler->writeVector3d(pArc->normal()); return Acad::eOk; } } return Acad::eInvalidInput; } Acad::ErrorStatus AecDb3dRoadAxisLine::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); //----- Save parent class information first. Acad::ErrorStatus es = Acad::eOk; if ( !pFiler->isKindOf(CMFCDbDwgFiler::desc())) { es = AecDbCurveBase::dwgOutFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; } if ((es = pFiler->writeUInt32(AecDb3dRoadAxisLine::kCurrentVersionNumber)) != Acad::eOk) return (es); Adesk::UInt32 nLen = m_arCurvePtrs.length(); pFiler->writeUInt32(nLen); AcDbCurve* pCurve = NULL; for (int i = 0;i < nLen;i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if ( !pFiler->isKindOf(CMFCDbDwgFiler::desc()))//CAD方式 { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if (AecDb3dRoadAxisLine::kCurrentVersionNumber > 3) { BaseCurveDwgOutFields(pCurve, pFiler); } else { pFiler->writeString(pCurve->isA()->name()); es = pCurve->dwgOutFields(pFiler); } } else { BaseCurveDwgOutFields(pCurve,pFiler); } } pFiler->writeInt16(m_nInfActive); if (AecDb3dRoadAxisLine::kCurrentVersionNumber > 1)//新加 { pFiler->writePoint2d(m_ptDR); } if (AecDb3dRoadAxisLine::kCurrentVersionNumber > 2)//新加 { nLen = m_arPathHds.GetSize(); pFiler->writeUInt32(nLen); CString sHd; for (int i = 0;i < nLen;i++) { sHd = m_arPathHds.GetAt(i); pFiler->writeString((const TCHAR *)sHd); } } return (pFiler->filerStatus()); } Acad::ErrorStatus AecDb3dRoadAxisLine::dxfInFields(AcDbDxfFiler* pFiler) { AssertWriteEnabled(); //----- Read parent class information first. Acad::ErrorStatus es = AecDbCurveBase::dxfInFields(pFiler); if (es != Acad::eOk) return (es); //...不用实现 return (pFiler->filerStatus()); } Acad::ErrorStatus AecDb3dRoadAxisLine::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled(); //----- Save parent class information first. Acad::ErrorStatus es = AecDbCurveBase::dxfOutFields(pFiler); if (es != Acad::eOk) return (es); //...不用实现 return (pFiler->filerStatus()); } Acad::ErrorStatus AecDb3dRoadAxisLine::Draw2d(AcGiDraw &dc) const { assertReadEnabled(); AcDb::LineWeight lwBk = dc.GetLineWeight(); double dLwbk = dc.GetLineWidth(); AcGePoint2d ptDR; bool bHasRadio = ReadDandRatio(ptDR); if (bHasRadio) { dc.SetLineWeight(AcDb::kLnWt100); dc.SetLineWidth(AcDb::kLnWt100); } //图层 AcDbObjectId idLay = dc.GetLayerId(); dc.SetLayer(layerId()); AcDbEntity* pEnt = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pEnt = (AcDbEntity*)m_arCurvePtrs.at(i); dc.DrawEntity(*pEnt); } dc.SetLineWeight(lwBk); dc.SetLineWidth(dLwbk); dc.SetLayer(idLay); return Acad::eOk; } Acad::ErrorStatus AecDb3dRoadAxisLine::Draw3d(AcGiDraw &dc) const { assertReadEnabled(); AcGePoint2d ptDR(0, 0); bool bHasRadio = ReadDandRatio(ptDR); double dR = 0.5 * ptDR.x * ptDR.y; //if (!bHasRadio) { return Draw2d(dc); } //三维太慢 //图层 AcDbObjectId idLay = dc.GetLayerId(); dc.SetLayer(layerId()); int nCrBk = dc.GetColor(); dc.SetColor(colorIndex()); if (Has3DBuffer()) { AcDbEntity *pEnt = NULL; const AcDbVoidPtrArray &ar3D = Get3DBuffer(); for (int i = 0; i < ar3D.length(); i++) { pEnt = (AcDbEntity *)ar3D.at(i); dc.SetColor(pEnt->colorIndex()); dc.DrawEntity(*pEnt); } dc.SetLayer(idLay); dc.SetColor(nCrBk); return Acad::eOk; } AcDbCurve *pCurve = NULL; AcDbEntity* p3dEnt = NULL; for (int i = 0; i < m_arCurvePtrs.length(); i++) { pCurve = (AcDbCurve *)m_arCurvePtrs.at(i); p3dEnt = dc.DrawPipe(pCurve, dR); if (p3dEnt != NULL) { Add3DBuffer(p3dEnt); } } dc.SetLayer(idLay); return Acad::eOk; } AcDbArc* MakeLineLineTangentArc(AcDbLine* pLineL,AcDbLine* pLineN,const AcGePoint3d& ptConnect,double dR) { if (pLineL == NULL || pLineN == NULL) return NULL; AcGePoint3d ptSta1,ptEnd1; AcGePoint3d ptSta2,ptEnd2; pLineL->getStartPoint(ptSta1); pLineL->getEndPoint(ptEnd1); pLineN->getStartPoint(ptSta2); pLineN->getEndPoint(ptEnd2); KTTempTol tol(1.e-6); AcGeVector3d vt1; if (ptConnect.distanceTo(ptSta1) < 1.e-2) { vt1 = ptEnd1 - ptConnect; } else { vt1 = ptSta1 - ptConnect; } AcGeVector3d vt2; if (ptConnect.distanceTo(ptSta2) < 1.e-2) { vt2 = ptEnd2 - ptConnect; } else { vt2 = ptSta2 - ptConnect; } vt1.normalize(); vt2.normalize(); AcGeVector3d vt3 = vt1 + vt2; vt3.normalize(); double dAngle = vt3.angleTo(vt1); double dL = dR / fabs(sin(dAngle)); vt3 *= dL; AcGePoint3d ptCen = ptConnect + vt3; AcGePoint3d ptOn1,ptOn2,ptMid; pLineL->getClosestPointTo(ptCen,ptOn1,Adesk::kTrue); pLineN->getClosestPointTo(ptCen,ptOn2,Adesk::kTrue); AcGeVector3d vtT1 = ptOn1 - pLineL->startPoint(); vtT1.normalize(); AcGeVector3d vtT2 = ptOn1 - pLineL->endPoint(); vtT2.normalize(); vtT1 = ptOn2 - pLineN->startPoint(); vtT1.normalize(); vtT2 = ptOn2 - pLineN->endPoint(); vtT2.normalize(); vt3.normalize(); ptMid = ptCen - vt3 * dR; double dPar = 0.0; if ( Acad::eOk == pLineL->getParamAtPoint(ptOn1,dPar) && Acad::eOk == pLineN->getParamAtPoint(ptOn2,dPar))//必须在直线上,否则异形了 { AcDbArc* pArcNew = FormatArc(ptOn1,ptMid,ptOn2); if (pArcNew != NULL) { //修改直线段 AcGePoint3dArray arPts1; arPts1.append(pLineL->startPoint()); arPts1.append(pLineL->endPoint()); arPts1.append(ptOn1); int nPos1 = arPts1.find(ptConnect); if (nPos1 != -1) { arPts1.removeAt(nPos1); } //修改直线段 AcGePoint3dArray arPts2; arPts2.append(pLineN->startPoint()); arPts2.append(pLineN->endPoint()); arPts2.append(ptOn2); int nPos2 = arPts2.find(ptConnect); if (nPos2 != -1) { arPts2.removeAt(nPos2); } if (arPts1.length() == 2 && arPts2.length() == 2) { pLineL->setStartPoint(arPts1.first()); pLineL->setEndPoint(arPts1.last()); pLineN->setStartPoint(arPts2.first()); pLineN->setEndPoint(arPts2.last()); return pArcNew; } delete pArcNew; } } return NULL; } bool CalCenPointByOffset(AcDbLine* pLine,AcDbArc* pArc,double dR,AcGePoint3d& ptCen,bool bExtendLine = false) { if (pLine == NULL || pArc == NULL) return false; double dR1 = pArc->radius(); if (dR1 - dR < 1.e-10)//必须比dR大,才能偏移 return false; AcDbVoidPtrArray arOffsetL; pLine->getOffsetCurves(dR,arOffsetL); pLine->getOffsetCurves(-dR,arOffsetL); AcDbArc* pArc1 = (AcDbArc*)pArc->clone(); pArc1->setRadius(dR1 - dR); AcDbArc* pArc2 = (AcDbArc*)pArc->clone(); pArc2->setRadius(dR + dR1); AcDbVoidPtrArray arOffsetR; arOffsetR.append(pArc1); arOffsetR.append(pArc2); AcDbEntity* pEnt1 = NULL; AcDbEntity* pEnt2 = NULL; AcGePoint3dArray arPts; for (int i = 0;i < arOffsetL.length();i++) { pEnt1 = (AcDbEntity*)arOffsetL.at(i); for (int j = 0;j < arOffsetR.length();j++) { pEnt2 = (AcDbEntity*)arOffsetR.at(j); pEnt1->intersectWith(pEnt2,bExtendLine ? AcDb::kExtendThis : AcDb::kOnBothOperands,arPts); if (!arPts.isEmpty()) { ptCen = arPts.first(); FreeBuffer(0,arOffsetL); FreeBuffer(0,arOffsetR); return true; } } } FreeBuffer(0,arOffsetL); FreeBuffer(0,arOffsetR); return false; } bool ModifyArc(AcDbArc* pArcNew,AcGePoint3d& ptBreak,const AcGePoint3d& ptOnRemove) { if (pArcNew == NULL) return false; AcGePoint3dArray arPts; arPts.append(ptBreak); AcDbVoidPtrArray arCurPtrs; pArcNew->getSplitCurves(arPts,arCurPtrs); double dPara = 0.0; AcDbArc* pArc = NULL; for (int i = 0;i < arCurPtrs.length();i++) { pArc = (AcDbArc*)arCurPtrs.at(i); if (Acad::eOk == pArc->getParamAtPoint(ptOnRemove,dPara)) { pArcNew->setStartAngle(pArc->startAngle()); pArcNew->setEndAngle(pArc->endAngle()); arCurPtrs.removeAt(i); FreeBuffer(0,arCurPtrs); return true; } } return false; } AcDbArc*AecDb3dRoadAxisLine::FilletLineAndArc(AcDbLine* pLineL,AcDbArc* pArcN,const AcGePoint3d& ptConnect,double dR) { AcGeVector3d vt1 = pLineL->endPoint() - pLineL->startPoint(); AcGeVector3d vtNOrm = pArcN->normal(); if (vt1.isPerpendicularTo(vtNOrm)) { //偏移求交法求圆心 AcGePoint3d ptCen; if (CalCenPointByOffset(pLineL,pArcN,dR,ptCen)) { AcGePoint3d ptOn1,ptOn2,ptMid; pLineL->getClosestPointTo(ptCen,ptOn1,Adesk::kTrue); pArcN->getClosestPointTo(ptCen,ptOn2,Adesk::kTrue); double dPa = 0.0; if ( Acad::eOk == pLineL->getParamAtPoint(ptOn1,dPa) && Acad::eOk == pArcN->getParamAtPoint(ptOn2,dPa))//必须在线上,否则异形了 { AcGeVector3d vt1 = ptOn1 - ptCen; AcGeVector3d vt2 = ptOn2 - ptCen; vt1.normalize();vt2.normalize(); AcGeVector3d vt3 = vt1 + vt2; vt3.normalize(); ptMid = ptCen + vt3 * dR; AcDbArc* pArcNew = FormatArc(ptOn1,ptMid,ptOn2); if (pArcNew != NULL) { //修改直线段 AcGePoint3dArray arPts1; arPts1.append(pLineL->startPoint()); arPts1.append(pLineL->endPoint()); arPts1.append(ptOn1); int nPos1 = arPts1.find(ptConnect); if (nPos1 != -1) { arPts1.removeAt(nPos1); } //修改圆弧 if ( ModifyArc(pArcNew,ptOn2,ptConnect) ) { if (arPts1.length() == 2) { pLineL->setStartPoint(arPts1.first()); pLineL->setEndPoint(arPts1.last()); return pArcNew; } } } } } } else//斜交,不共面 { } return NULL; } AcDbArc* AecDb3dRoadAxisLine::FilletLineAndLine(AcDbCurve* pCurveLast,AcDbCurve* pCurveNext,double dD,double dRatio) { if (pCurveLast == NULL) return NULL; if (pCurveNext == NULL) return NULL; double dR = dD * 0.5 * dRatio;//切线弧的半径 AcDbArc* pArc = NULL; AcDbLine* pLnLast = AcDbLine::cast(pCurveLast); AcDbLine* pLnNext = AcDbLine::cast(pCurveNext); //前后都是直线的情况 if (pLnLast != NULL && pLnNext != NULL) { AcGePoint3dArray arPts; pLnLast->intersectWith(pLnNext,AcDb::kExtendBoth,arPts); if (!arPts.isEmpty()) { AcGePoint3d ptInt = arPts.first(); AcGeVector3d vtLast = MidPoint(pLnLast->startPoint(), pLnLast->endPoint()) - ptInt; AcGeVector3d vtNext = MidPoint(pLnNext->startPoint(), pLnNext->endPoint()) - ptInt; vtLast.normalize(); vtNext.normalize(); AcGeVector3d vtHalf = vtLast + vtNext; AcGeVector3d vtRL = vtHalf.orthoProject(vtLast); AcGeVector3d vtRR = vtHalf.orthoProject(vtNext); vtRL.normalize(); vtRR.normalize(); vtRL *= dR; vtRR *= dR; AcDbLine lnL(pLnLast->startPoint() + vtRL,pLnLast->endPoint() + vtRL); AcDbLine lnR(pLnNext->startPoint() + vtRR,pLnNext->endPoint() + vtRR); arPts.removeAll(); lnL.intersectWith(&lnR,AcDb::kExtendBoth,arPts); if (!arPts.isEmpty()) { AcGePoint3d ptCen = arPts.first(); vtHalf = ptCen - ptInt; vtLast = vtHalf - vtRL; vtNext = vtHalf - vtRR; AcGePoint3d pt1 = ptInt + vtLast; AcGePoint3d pt2 = ptInt + vtNext; vtHalf.normalize(); vtHalf.negate(); vtHalf *= dR; AcGePoint3d ptMid = ptCen + vtHalf; pArc = FormatArc(pt1,ptMid,pt2); double dDis1 = pLnLast->startPoint().distanceTo(ptInt); double dDis2 = pLnLast->endPoint().distanceTo(ptInt); if (dDis1 < dDis2) { pLnLast->setStartPoint(pt1); } else { pLnLast->setEndPoint(pt1); } dDis1 = pLnNext->startPoint().distanceTo(ptInt); dDis2 = pLnNext->endPoint().distanceTo(ptInt); if (dDis1 < dDis2) { pLnNext->setStartPoint(pt2); } else { pLnNext->setEndPoint(pt2); } } } } else { AcDbArc *pArcLast = AcDbArc::cast(pCurveLast); AcDbLine *pLnNext = AcDbLine::cast(pCurveNext); if (pArcLast != NULL && pLnNext != NULL) { //求切 pArc = TangentLnAndArc(pLnNext, pArcLast,dR); } AcDbArc* pArcNext = AcDbArc::cast(pCurveNext); if (pLnLast != NULL && pArcNext != NULL) { //求切 pArc = TangentLnAndArc(pLnLast, pArcNext,dR); } if (pArcLast != NULL && pArcNext != NULL) { //求切 TangentArcAndArc(pArcLast, pArcNext, dR); } } return pArc; } bool AecDb3dRoadAxisLine::Create3dRoadAxisLine(double dD,double dRatio) { AssertWriteEnabled(); AcGePoint2d pt2d; bool bHasRatio = ReadDandRatio(pt2d); SaveDandRatio(dD, dRatio); bHasRatio = false;//2024-3-14 AcDbArc* pArc = NULL; AcDbCurve* pCurveLast = NULL; AcDbCurve* pCurveNext = NULL; AcDbCurve *pCurve = NULL; AcDbLine *pLn = NULL; double dR = 0.0; bool bRemoveOk = false; AcDbVoidPtrArray arCurNewPtrs,arLinePtrs,arRemove; for (int i = 0; i < m_arCurvePtrs.length(); i++) { pCurve = (AcDbCurve *)m_arCurvePtrs.at(i); pLn = AcDbLine::cast(pCurve); if (pLn != NULL) { arLinePtrs.append(pCurve); } else { bRemoveOk = false; if (bHasRatio) { AcDbArc *pArc = AcDbArc::cast(pCurve); if (pArc != NULL) { dR = pArc->radius(); if (fabs(dR - 0.5 * pt2d.x * pt2d.y) < 1.e-3) { //去除 bRemoveOk = true; } else { arLinePtrs.append(pCurve); } } } else { AcDbArc *pArc = AcDbArc::cast(pCurve); if (pArc != NULL) { dR = pArc->radius(); if (dR > 0.5 * dD * dRatio) { arLinePtrs.append(pCurve); } else { bRemoveOk = true; } } } if (bRemoveOk) arRemove.append(pCurve); } } for (int i = 0;i < arLinePtrs.length() - 1;i++) { pCurveLast = (AcDbCurve* )arLinePtrs.at(i); pCurveNext = (AcDbCurve* )arLinePtrs.at(i+1); pArc = FilletLineAndLine(pCurveLast,pCurveNext,dD,dRatio); if (pArc != NULL) { arCurNewPtrs.append(pCurveLast); arCurNewPtrs.append(pArc); } else { arCurNewPtrs.append(pCurveLast); } } if (pCurveNext != NULL) arCurNewPtrs.append(pCurveNext); if (!arCurNewPtrs.isEmpty()) { m_arCurvePtrs.removeAll(); FreeBuffer(0, arRemove); m_arCurvePtrs.append(arCurNewPtrs); return true; } return false; } //拟合 bool AecDb3dRoadAxisLine::Create3dRoadAxisLine(double dD,double dRatio,const AcGePoint3dArray& arPts) { AssertWriteEnabled(); if (arPts.length() < 2) return false; AcGeVector3d vt1,vt2,vtMaj,vtMin; AcGePoint3d pt1,pt2,pt3,ptFr; double dSweepAng = 0.0; double dR = dD * dRatio; AcDbLine* pLn = NULL; AcDbVoidPtrArray arLnPtrs; for (int i = 0;i < arPts.length() - 1;i++) { pt1 = arPts.at(i); pt2 = arPts.at(i + 1); pLn = new AcDbLine; pLn->setStartPoint(pt1); pLn->setEndPoint(pt2); arLnPtrs.append(pLn); } double dSweepAngle = 0.0,dSta = 0.0,dEnd = 0.0; AcDbVoidPtrArray arCurPtrs; AcGeVector3d vtSta,vtEnd; AcGePoint3d ptSta,ptEnd,ptMid; AecInterface inf1,inf2; AecInterface inf3,inf4; AcDbLine* pPipe1 = NULL,*pPipe2 = NULL; for (int i = 0;i < arLnPtrs.length() - 1;i++) { pPipe1 = (AcDbLine*)arLnPtrs.at(i); pPipe2 = (AcDbLine*)arLnPtrs.at(i + 1); arCurPtrs.append(pPipe1); inf1.ptPos = pPipe1->endPoint(); inf1.vtDir = pPipe1->endPoint() - pPipe1->startPoint(); inf2.ptPos = pPipe2->startPoint(); inf2.vtDir = pPipe2->startPoint() - pPipe2->endPoint(); if (!inf1.vtDir.isParallelTo(inf2.vtDir))//不平行 { vtMaj = inf1.vtDir; vtMin = inf2.vtDir; vtMin.negate(); ptMid = inf1.ptPos; AcGePoint3dArray arPtInts; pPipe1->intersectWith(pPipe2,AcDb::kExtendBoth,arPtInts); if (!arPtInts.isEmpty()) { ptMid = arPtInts.first(); } dSweepAngle = vtMin.angleTo(vtMaj); AcDbArc* pArcElbow = KTCADUtilityEx::FormatArc(vtMaj, vtMin, ptMid, ptFr, dSweepAngle, dD, dRatio); if (pArcElbow != NULL)//可以合成ARC { pArcElbow->getStartParam(dSta); pArcElbow->getEndParam(dEnd); pArcElbow->getFirstDeriv(dSta,vtSta); pArcElbow->getFirstDeriv(dEnd,vtEnd); pArcElbow->getStartPoint(ptSta); pArcElbow->getEndPoint(ptEnd); if (vtSta.isParallelTo(inf1.vtDir)) { pPipe1->setEndPoint(ptSta); } if (vtEnd.isParallelTo(inf1.vtDir)) { pPipe1->setEndPoint(ptEnd); } if (vtSta.isParallelTo(inf2.vtDir)) { pPipe2->setStartPoint(ptSta); } if (vtEnd.isParallelTo(inf2.vtDir)) { pPipe2->setStartPoint(ptEnd); } arCurPtrs.append(pArcElbow); } } else//平行 { //... } } if (!arLnPtrs.isEmpty()) { arCurPtrs.append(arLnPtrs.last()); } FreeBuffer(0,m_arCurvePtrs); //AcAxDocLock lock; AcDbCurve* pCurveTmp = NULL; for (int k = 0;k < arCurPtrs.length();k++) { pCurveTmp = (AcDbCurve*)arCurPtrs.at(k); pCurveTmp->getStartPoint(ptSta); pCurveTmp->getEndPoint(ptEnd); //添加并首尾排序 AppendCurveSeg(pCurveTmp); DELETE_PTR(pCurveTmp); //m_arCurvePtrs.append(pCurveTmp); //pCurve->setColorIndex(kRed); //AddToModelSpace(pCurve); } SaveDandRatio(dD, dRatio); return GetCurveSegCount() > 0 ? true : false; } bool AecDb3dRoadAxisLine::SplitToLineSegs(const AcDbCurve* pCurve,int nSegs,AcDbVoidPtrArray& arLnPtrs,const AcGePoint3d& ptLast) const { if (pCurve == NULL) return false; int nPoints = nSegs + 1; double dSta = 0.0,dEnd = 0.0; pCurve->getStartParam(dSta); pCurve->getEndParam(dEnd); AcGePoint3d ptOn,pt2; AcGePoint3dArray arPts; double dStep = (dEnd - dSta) / nSegs; for (int i = 0;i < nPoints;i++ ) { pCurve->getPointAtParam(dSta + dStep * i,ptOn); arPts.append(ptOn); } if (ptLast.distanceTo(arPts.first()) > 1.e-1) { arPts.reverse(); } AcDbLine* pLn = NULL; for (int k = 0;k < arPts.length() - 1;k++) { pLn = new AcDbLine(arPts.at(k),arPts.at(k+1)); arLnPtrs.append(pLn); } return true; } AecDb3dRoadAxisLine* AecDb3dRoadAxisLine::GetFittedRoadAxisLine(double dD,double dRatio) const { assertReadEnabled(); AcDbVoidPtrArray arCurNewPtrs; AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); arCurNewPtrs.append((AcDbCurve*)pCurve->clone()); } if (arCurNewPtrs.length() == 1) { AecDb3dRoadAxisLine* pRoadAx = new AecDb3dRoadAxisLine; pRoadAx->m_arCurvePtrs.append(arCurNewPtrs); pRoadAx->SaveDandRatio(dD, dRatio); return pRoadAx; } AcDbArc* pArc = NULL; AcDbCurve* pCurveL = NULL; AcDbCurve* pCurveN = NULL; AcDbVoidPtrArray arCurNewPtrs2; for (int i = 0;i < arCurNewPtrs.length() - 1;i++) { pCurveL = (AcDbCurve*)arCurNewPtrs.at(i); pCurveN = (AcDbCurve*)arCurNewPtrs.at(i+1); pArc = AecDb3dRoadAxisLine::FilletLineAndLine(pCurveL,pCurveN,dD,dRatio); if (pArc != NULL) { arCurNewPtrs2.append(pCurveL); arCurNewPtrs2.append(pArc); } else { arCurNewPtrs2.append(pCurveL); } } if (pCurveN != NULL) arCurNewPtrs2.append(pCurveN); AecDb3dRoadAxisLine* pRoadAx = new AecDb3dRoadAxisLine; pRoadAx->m_arCurvePtrs.append(arCurNewPtrs2); AcGePoint2d pt; ReadDandRatio(pt); pRoadAx->SaveDandRatio(pt.x,pt.y); return pRoadAx; } bool AecDb3dRoadAxisLine::GetReferLineSegPoints(AcGePoint3dArray& arPts, bool bArcFit/* = true*/) const { assertReadEnabled(); AcGePoint3d ptSta,ptEnd; getStartPoint(ptSta); arPts.append(ptSta); AcDbVoidPtrArray arLnPtrsAll; AcDbCurve* pLastLn = NULL; AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); AcDbLine* pLine = AcDbLine::cast(pCurve); if (pLine != NULL) { if (pLastLn == NULL) { pLastLn = pLine; } else { AcGePoint3dArray arPts2; pLine->intersectWith(pLastLn,AcDb::kExtendBoth,arPts2); if (!arPts2.isEmpty()) { arPts.append(arPts2.first()); } pLastLn = pLine; } } AcDbArc* pArc = AcDbArc::cast(pCurve); if (pArc != NULL)//圆弧分成n段 { if (bArcFit) { //10米一个段 double dLen = fabs((pArc->endAngle() - pArc->startAngle()) * pArc->radius()); int nSegs = (int)(dLen / 10.0 + 0.5); if (nSegs < 1) nSegs = 2; AcDbVoidPtrArray arLnPtrs; SplitToLineSegs(pArc,nSegs,arLnPtrs,arPts.last()); for (int k = 0;k < arLnPtrs.length();k++) { pCurve = (AcDbCurve*)arLnPtrs.at(k); pLine = AcDbLine::cast(pCurve); if (pLine != NULL) { if (pLastLn == NULL) { pLastLn = pLine; } else { AcGePoint3dArray arPts2; pLine->intersectWith(pLastLn,AcDb::kExtendBoth,arPts2); if (!arPts2.isEmpty()) { arPts.append(arPts2.first()); } pLastLn = pLine; } } } if (!arLnPtrs.isEmpty()) { arLnPtrsAll.append(arLnPtrs); } } else //不拟合,取拐点 { //... } } } getEndPoint(ptEnd); arPts.append(ptEnd); return !arPts.isEmpty(); } bool AecDb3dRoadAxisLine::SaveDandRatio(double dD,double dRatio) { AssertWriteEnabled(); m_ptDR.set(dD, dRatio); struct resbuf* pRb = NULL,*pTempNext = NULL; struct resbuf* pTemp = NULL; pTemp = acutNewRb(AcDb::kDxfRegAppName); acutNewString(_T("RATIO"),pTemp->resval.rstring); pRb = pTemp; pTempNext = acutNewRb(AcDb::kDxfXdReal); pTempNext->resval.rreal = dD; pTempNext->rbnext = NULL; pTemp->rbnext = pTempNext; pTemp = pTempNext; pTempNext = NULL; pTempNext = acutNewRb(AcDb::kDxfXdReal); pTempNext->resval.rreal = dRatio; pTempNext->rbnext = NULL; pTemp->rbnext = pTempNext; pTemp = pTempNext; pTempNext = NULL; // 扩展数据 struct resbuf* pTmpRb = xData(_T("RATIO")); if (pTmpRb != NULL) { //存在清空 struct resbuf* pTmp = acutNewRb(AcDb::kDxfRegAppName); pTmp->rbnext = NULL; acutNewString(_T("RATIO"),pTmp->resval.rstring); setXData(pTmp); acutRelRb(pTmpRb); acutRelRb(pTmp); } // 注册扩展数据链表 acdbRegApp(_T("RATIO")); Acad::ErrorStatus es = setXData(pRb); acutRelRb(pRb); return (es == Acad::eOk); } bool AecDb3dRoadAxisLine::ReadDandRatio(AcGePoint2d& ptDRatio) const { assertReadEnabled(); ptDRatio = m_ptDR; if (ptDRatio.x < 1.e-1 || ptDRatio.y < 1.e-1) { // 扩展数据 struct resbuf* pTmpRb = xData(_T("RATIO")); if (pTmpRb != NULL) { struct resbuf* pTmp = pTmpRb; struct resbuf* pTmpRadio = NULL; while(pTmp != NULL) { if (pTmp->restype == AcDb::kDxfXdReal)// { ptDRatio.x = pTmp->resval.rreal; pTmpRadio = pTmp->rbnext; if (pTmpRadio != NULL && pTmpRadio->restype == AcDb::kDxfXdReal) { ptDRatio.y = pTmpRadio->resval.rreal; acutRelRb(pTmpRb); break; } } pTmp = pTmp->rbnext; } } } if (ptDRatio.x > 1.e-1 && ptDRatio.y > 1.e-1) return true; return false; } bool AecDb3dRoadAxisLine::ReCreate3dRoadAxisLine(double dD,double dRatio) { AssertWriteEnabled(); if (dRatio > 1.e-3 && dD > 1.e-2) { AcGePoint3dArray arPts; GetReferLineSegPoints(arPts); return Create3dRoadAxisLine(dD,dRatio,arPts); } return false; } Acad::ErrorStatus AecDb3dRoadAxisLine::subGetOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { assertReadEnabled(); AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); pCurve->getOsnapPoints(osnapMode,gsSelectionMark,pickPoint,lastPoint,viewXform,snapPoints,geomIds); } return Acad::eOk; } int GetSamplePointLines(AcDbCurve* pCrv, AcDbVoidPtrArray& arpResult) { double dSta = 0.0, dEnd = 0.0,dLen = 0.0; AcGePoint3dArray arPoints; pCrv->getStartParam(dSta); pCrv->getEndParam(dEnd); pCrv->getDistAtParam(dEnd,dLen); int nSegCount = 20; struct resbuf rb; acedGetVar(_T("INSUNITS"), &rb); if (rb.resval.rint == AcDb::kUnitsMeters) //当前图是米制 { nSegCount = (int)(dLen / 1.0 + 0.5);//1米每段 if (nSegCount <= 1) { nSegCount = 2; } } double dStep = (dEnd - dSta) / nSegCount; AcGePoint3d ptGeT; for (int i = 0; i <= nSegCount; i++) { if ( Acad::eOk == pCrv->getPointAtParam(dSta + i * dStep, ptGeT) ) { arPoints.append(ptGeT); } } AcDbLine* pLn = NULL; for (int i = 0;i < arPoints.length() - 1;i++) { pLn = new AcDbLine(arPoints.at(i),arPoints.at(i+1)); arpResult.append(pLn); } return arpResult.length(); } AcDbCurve* AecDb3dRoadAxisLine::GetBaseCurve(bool bOrthoProjectToXY) const { assertReadEnabled(); AcDbCurve* pBaseCurve = NULL; AcDbCurve* pCurve = NULL,*pProjXY = NULL; AcDbVoidPtrArray arCurPtrs,arpResult; if (bOrthoProjectToXY) { for (int i = 0;i < GetCurveSegCount();i++) { pCurve = GetCurveSeg(i); if (pCurve != NULL) { if ( Acad::eOk != pCurve->explode(arCurPtrs) ) { arCurPtrs.append((AcDbCurve*)pCurve->clone()); } } } AcDbLine* pLn = NULL; AcDbArc* pArc = NULL; AcGePoint3d ptCen; for (int i = 0;i < arCurPtrs.length();i++) { pCurve = (AcDbCurve*)arCurPtrs.at(i); //acutPrintf(_T("\nes = %s"),pCurve->isA()->name()); pLn = AcDbLine::cast(pCurve); if (pLn != NULL) { pLn->setNormal(AcGeVector3d::kZAxis); } pArc = AcDbArc::cast(pCurve); if (pArc != NULL) { AcGeVector3d vt = pArc->normal(); AcGeLine3d lnSeg; lnSeg.set(AcGePoint3d::kOrigin,vt); if (AcGePlane::kXYPlane.isParallelTo(lnSeg) )//投影为直线 { AcGePoint3d ptSta,ptEnd; pArc->getStartPoint(ptSta); pArc->getEndPoint(ptEnd); pLn = new AcDbLine(ptSta,ptEnd); pLn->setNormal(AcGeVector3d::kZAxis); arCurPtrs.setAt(i,pLn); delete pCurve; pCurve = pLn; } else if (AcGePlane::kXYPlane.isPerpendicularTo(lnSeg)) { //投影为圆弧 AcDbArc* pArcCln = (AcDbArc*)pArc->clone(); ptCen = pArcCln->center(); ptCen.z = 0.0; pArcCln->setCenter(ptCen); arpResult.append(pArcCln); continue; } } pProjXY = NULL; Acad::ErrorStatus es = pCurve->getOrthoProjectedCurve(AcGePlane::kXYPlane,pProjXY); //acutPrintf(_T("\nes = %s"),pProjXY->isA()->name()); if ( pProjXY != NULL) { if (pProjXY->isKindOf(AcDbLine::desc()) || pProjXY->isKindOf(AcDbArc::desc())) { arpResult.append(pProjXY); } else { //分化为n段 GetSamplePointLines(pProjXY,arpResult); delete pProjXY; pProjXY = NULL; } } } FreeBuffer(0,arCurPtrs); arCurPtrs.removeAll(); pBaseCurve = KTCADUtilityEx::ConvertBoundCurve(arpResult, arCurPtrs); } else//不投影,不确定能否合成其他面的多义线 { for (int i = 0;i < GetCurveSegCount();i++) { pCurve = GetCurveSeg(i); if (pCurve != NULL) { arCurPtrs.append((AcDbCurve*)pCurve->clone()); } } pBaseCurve = KTCADUtilityEx::ConvertBoundCurve(arCurPtrs, arpResult); } return pBaseCurve; } AcDbCurve* AecDb3dRoadAxisLine::GetCurveByDist(const double &dist) const { AcGePoint3d pt(AcGePoint3d::kOrigin); double len(.0), d; for (int i = 0; i < m_arCurvePtrs.length(); ++i) { AcDbCurve *pCurve = (AcDbCurve*)m_arCurvePtrs[i]; if (!pCurve) continue; if (Acad::eOk != pCurve->getEndPoint(pt)) continue; if (Acad::eOk != pCurve->getDistAtPoint(pt, d)) continue; len += d; if (len >= dist) return pCurve; } return NULL; } AcDbCurve* AecDb3dRoadAxisLine::GetCurveByPoint(const AcGePoint3d &pt) const { for (int i = 0; i < m_arCurvePtrs.length(); ++i) { AcDbCurve *pCurve((AcDbCurve*)m_arCurvePtrs[i]); if (!pCurve) continue; AcGePoint3d ptOn; pCurve->getClosestPointTo(pt,ptOn,Adesk::kTrue); double dOn = 0.0; if (Acad::eOk == pCurve->getParamAtPoint(ptOn,dOn)) { return pCurve; } } return NULL; } bool AecDb3dRoadAxisLine::IsSubTangentContinue() const { //获取曲线的序 AcArray arCurveDir; GetCurveDirs(arCurveDir); if (arCurveDir.length() != m_arCurvePtrs.length()) return false; KTTempTol tol(1.e-6); AcGeVector3d vtPre,vtNxt; double dPre = 0.0,dNxt = 0.0; AcDbCurve* pCurvePre = NULL; AcDbCurve* pCurveNxt = NULL; for (int i = 0;i < m_arCurvePtrs.length() - 1;i++) { pCurvePre = (AcDbCurve*)m_arCurvePtrs.at(i); pCurveNxt = (AcDbCurve*)m_arCurvePtrs.at(i+1); CurveDir& cDirPre = arCurveDir.at(i); CurveDir& cDirNxt = arCurveDir.at(i+1); if (cDirPre.bDir) { pCurvePre->getEndParam(dPre); } else { pCurvePre->getStartParam(dPre); } if (cDirNxt.bDir) { pCurveNxt->getStartParam(dNxt); } else { pCurveNxt->getEndParam(dNxt); } pCurvePre->getFirstDeriv(dPre,vtPre); pCurveNxt->getFirstDeriv(dNxt,vtNxt); if (!vtPre.isParallelTo(vtNxt)) { return false; } } return true; } //尝试转成2d polyline AcDbPolyline* AecDb3dRoadAxisLine::ConvertTo2dPline() const { assertReadEnabled(); double dLen = 0.0,dLenT = 0.0; double dEnd = 0.0; AcDbVoidPtrArray arCurPtrs,arResult; AcDbCurve* pCurveCln = NULL; AcDbCurve* pCurve = NULL; double dEl = 0.0; AcGePoint3d ptS,ptE; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); if (!pCurve) continue; pCurve->getEndParam(dEnd); pCurve->getDistAtParam(dEnd,dLenT); dLen += dLenT; pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); if ( fabs(ptS.z - ptE.z) < 1.e-10)//同标高 { dEl = ptS.z; } else { return NULL;//不等标高 } pCurveCln = (AcDbCurve*)pCurve->clone(); if (pCurveCln != NULL) { arCurPtrs.append(pCurveCln); } } dLenT = 0.0; AcDbCurve* pCrv = KTCADUtilityEx::ConvertBoundCurve(arCurPtrs,arResult); if (pCrv != NULL) { FreeBuffer(0,arResult); AcDbPolyline* pPl = AcDbPolyline::cast(pCrv); if (pPl != NULL) { pPl->setElevation(dEl); return pPl; } else { delete pCrv; } } return NULL; } bool GetSamplePoints(AcDbCurve* pSubCrv,double dFitLen,AcGePoint3dArray& arSubPts) { if (pSubCrv != NULL && dFitLen > 1.e-6) { double dEnd = 0.0,dDis = 0.0,dSta = 0.0; pSubCrv->getEndParam(dEnd); pSubCrv->getStartParam(dSta); pSubCrv->getDistAtParam(dEnd,dDis); int nNumVerts = (int)(dDis / dFitLen) + 1; double dStep = (dEnd - dSta) / nNumVerts; AcGePoint3d ptTemp; for (int i = 0; i <= nNumVerts; i++) //2 米 等 分 { pSubCrv->getPointAtParam(dSta + dStep * i, ptTemp); arSubPts.append(ptTemp); } return true; } return false; } extern AcDb3dPolyline* Format3dPolyline(const AcGePoint3dArray& arPts); void AecDb3dRoadAxisLine::ConvertTo3dPline(AcGePoint3dArray& arPts,double dFitLen/* = 10.0*/) const { assertReadEnabled(); //获取曲线的序 CurveDir crDir; AcArray arCurveDir; GetCurveDirs(arCurveDir); AcGePoint3d ptSta,ptEnd,ptTemp; AcGePoint3dArray arSubPts; AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); crDir = arCurveDir.at(i); arSubPts.removeAll(); AcDbLine* pLn = AcDbLine::cast(pCurve); if (pLn != NULL) { ptSta = pLn->startPoint(); ptEnd = pLn->endPoint(); arSubPts.append(ptSta); arSubPts.append(ptEnd); if (!crDir.bDir)//反序 { arSubPts.reverse(); } } AcDbArc* pArc = AcDbArc::cast(pCurve); if (pArc != NULL) { GetSamplePoints(pArc,dFitLen,arSubPts); if (!crDir.bDir)//反序 { arSubPts.reverse(); } } AcDbPolyline* pPl = AcDbPolyline::cast(pCurve); if (pPl != NULL) { AecDb3dRoadAxisLine ax; ax.AppendCurveSeg(pPl); ax.ConvertTo3dPline(arSubPts); if (!crDir.bDir)//反序 { arSubPts.reverse(); } } for (int ii = 0;ii < arSubPts.length();ii++) { ptTemp = arSubPts.at(ii); if (arPts.find(ptTemp) == -1) { arPts.append(ptTemp); } } } } //尝试转成3d polyline,拟合方法 AcDb3dPolyline* AecDb3dRoadAxisLine::ConvertTo3dPline(double dFitLen/* = 10.0*/) const { assertReadEnabled(); //获取曲线的序 CurveDir crDir; AcArray arCurveDir; GetCurveDirs(arCurveDir); AcGePoint3d ptSta,ptEnd,ptTemp; AcGePoint3dArray arPts,arSubPts; KTTempTol tol(1.e-3); AcDbCurve* pCurve = NULL; for (int i = 0;i < m_arCurvePtrs.length();i++) { pCurve = (AcDbCurve*)m_arCurvePtrs.at(i); crDir = arCurveDir.at(i); arSubPts.removeAll(); AcDbLine* pLn = AcDbLine::cast(pCurve); if (pLn != NULL) { ptSta = pLn->startPoint(); ptEnd = pLn->endPoint(); arSubPts.append(ptSta); arSubPts.append(ptEnd); if (!crDir.bDir)//反序 { arSubPts.reverse(); } } AcDbArc* pArc = AcDbArc::cast(pCurve); if (pArc != NULL) { //最大为正120边形 double dThisFit = dFitLen; double dC = 2.0 * PI * pArc->radius(); int nNL = (int)(dC / dFitLen); if (nNL > 120) { dThisFit = dC / 120.0; } GetSamplePoints(pArc,dThisFit,arSubPts); if (!crDir.bDir)//反序 { arSubPts.reverse(); } } AcDbPolyline* pPl = AcDbPolyline::cast(pCurve); if (pPl != NULL) { AecDb3dRoadAxisLine ax; ax.AppendCurveSeg(pPl); ax.ConvertTo3dPline(arSubPts,dFitLen); if (!crDir.bDir)//反序 { arSubPts.reverse(); } } for (int ii = 0;ii < arSubPts.length();ii++) { ptTemp = arSubPts.at(ii); if (arPts.find(ptTemp) == -1) { arPts.append(ptTemp); } } } return Format3dPolyline(arPts); } //空间偏移 Acad::ErrorStatus AecDb3dRoadAxisLine::offset(double dOffset) { acedAlert(_T("空间放样线偏移即将实现!")); return Acad::eOk; } double AecDb3dRoadAxisLine::getLength() const { double dLen = 0.0,dE = 0.0, dDis = 0.0; AcDbCurve *pCurve = NULL; for (int i = 0; i < m_arCurvePtrs.length(); i++) { pCurve = (AcDbCurve *)m_arCurvePtrs.at(i); dE = 0.0, dDis = 0.0; pCurve->getEndParam(dE); pCurve->getDistAtParam(dE, dDis); dLen += fabs(dDis); } return dLen; } const AecDbObjXDataMap* AecDb3dRoadAxisLine::GetSpecialtyData() const { assertReadEnabled(); return &m_mapSpecXData; } AecDbObjXDataMap* AecDb3dRoadAxisLine::GetSpecialtyData(AcDb::OpenMode bMode) { switch (bMode) { case AcDb::kForRead: { assertReadEnabled(); break; } case AcDb::kForWrite: { if (!isWriteEnabled()) { upgradeOpen(); } AssertWriteEnabled(); break; } case AcDb::kForNotify: { assertReadEnabled(); } default: break; } return &m_mapSpecXData; }