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

4474 lines
95 KiB
C++

#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<AecInterface>& arInfs) const
{
assertReadEnabled();
AcArray<AecInterface> 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<AecInterface>& 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<AecInterface> 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<CurveDir>& 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<CurveDir> 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<CurveDir> 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<CurveDir> 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<CurveDir> 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 &param) const
{
assertReadEnabled();
param = 0.;
return Acad::eOk;
}
Acad::ErrorStatus AecDb3dRoadAxisLine::getEndParam(double &param) 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<CurveDir> 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 &param)const
{
// 假设 givenPnt 在线上
assertReadEnabled();
AcDbCurve* pCurve = NULL;
if (m_arCurvePtrs.length() == 1)
{
pCurve = (AcDbCurve*)m_arCurvePtrs.first();
return pCurve->getParamAtPoint(givenPnt,param);
}
//获取曲线的序
AcArray<CurveDir> 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 &param) 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<CurveDir> 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<CurveDir> 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<CurveDir> 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<CurveDir> 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<CurveDir> 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<CurveDir> 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<CurveDir> 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;
}