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

484 lines
11 KiB
C++

#include "stdafx.h"
#include "AecCableTool.h"
#include "AecDbEwCable.h"
#include "AecDbEwFitting.h"
#include "AecDb3dRoadAxisLine.h"
#include "AecDbObjXDataMap.h"
extern Acad::ErrorStatus AddToModelSpace(AcDbEntity* pEnt,AcDbObjectId& id,AcDbDatabase* pDb,bool bClose);
AecCableTool::AecCableTool(void)
{
}
AecCableTool::~AecCableTool(void)
{
}
bool AecCableTool::CableExit(AecDbEwCable* pCable,AecInterface& inf,int nStyle,AcDbVoidPtrArray& arCablePtrs)
{
if (pCable == NULL )
return false;
AcDbRay ray;
ray.setBasePoint(inf.ptPos);
inf.vtDir.normalize();
ray.setUnitDir(inf.vtDir);
double dD = 0.0,dRatio = 0.0;
pCable->GetSpecialtyData()->GetAt(CABLE_D,dD);
pCable->GetSpecialtyData()->GetAt(CABLE_RATIO,dRatio);
double dR = 0.5 * dD * dRatio;
AcGePoint3d ptOn,ptMid,ptMid2;
AcDbCurve* pCurve = pCable->GetBaseCurve();
AecDb3dRoadAxisLine* pALine = AecDb3dRoadAxisLine::cast(pCurve);
if (pALine != NULL)
{
pALine->getClosestPointTo(inf.ptPos,ptOn,Adesk::kFalse);
AcGePoint3dArray arPts;
arPts.append(inf.ptPos);
ptMid = inf.ptPos;
ptMid -= inf.vtDir * dR;
arPts.append(ptMid);
AcDbRay ray2;
ray2.setBasePoint(ptOn);
ray2.setUnitDir(AcGeVector3d::kZAxis);//inf.vtDir
ray2.getClosestPointTo(ptMid,ptMid2,Adesk::kFalse);
arPts.append(ptMid2);
arPts.append(ptOn);
arPts.reverse();
if (nStyle == 0)//接线引出
{
AecDb3dRoadAxisLine* pAlnNew = new AecDb3dRoadAxisLine;
if ( pAlnNew->Create3dRoadAxisLine(dD,dRatio,arPts) )
{
AecDbEwCable* pCableNew = new AecDbEwCable;
pCableNew->GetSpecialtyData()->CopyFrom(pCable->GetSpecialtyData());
pCableNew->SetBaseCurve(pAlnNew);
pCableNew->SetSection(dD,0.0);
arCablePtrs.append(pCableNew);
DELETE_PTR(pAlnNew);
//TEST
//AcDbObjectId idT;
//pALine->setColorIndex(kMagenta);
//AddToModelSpace(pALine,idT,NULL,true);
return true;
}
else
{
DELETE_PTR(pAlnNew);
//TEST
//AcDbObjectId idT;
//pALine->setColorIndex(kMagenta);
//AddToModelSpace(pALine,idT,NULL,true);
acutPrintf(_T("\n选择的开孔和线缆由于不符合弯曲曲率无法引出!"));
return false;
}
}
else if( nStyle == 1)//整体引出
{
AcGePoint3dArray arPts2;
pALine->GetReferLineSegPoints(arPts2);
//找距离哪个点最近
int nNear = -1;
double dDist = -1.0,dDistT = 0.0;
for (int k = 0;k < arPts2.length();k++)
{
ptMid2 = arPts2.at(k);
dDistT = ptMid2.distanceTo(ptOn);
if (dDist < 1.e-10)
{
nNear = k;
dDist = dDistT;
}
else
{
if (dDistT - dDist < 1.e-2)//取最小
{
nNear = k;
dDist = dDistT;
}
}
}
AcGePoint3dArray arPtsL,arPtsR;
if (nNear > -1 && nNear < arPts2.length())
{
for (int k = 0;k < nNear;k++)//左边
{
arPtsL.append(arPts2.at(k));
}
for (int k = nNear;k < arPts2.length();k++)//右边
{
arPtsR.append(arPts2.at(k));
}
arPtsR.reverse();
arPtsL.append(arPts);
arPtsR.append(arPts);
if (arPtsL.length() > 1)
{
pALine->Create3dRoadAxisLine(dD,dRatio,arPtsL);
pCable->SetBaseCurve(pALine);
DELETE_PTR(pALine);
//TEST
//AcDbObjectId idT;
//pALine->setColorIndex(kMagenta);
//AddToModelSpace(pALine,idT,NULL,true);
}
if (arPtsR.length() > 1)
{
AecDb3dRoadAxisLine* pAlnNew = new AecDb3dRoadAxisLine;
if ( pAlnNew->Create3dRoadAxisLine(dD,dRatio,arPtsR) )
{
AecDbEwCable* pCableNew = new AecDbEwCable;
pCableNew->GetSpecialtyData()->CopyFrom(pCable->GetSpecialtyData());
pCableNew->SetBaseCurve(pAlnNew);
pCableNew->SetSection(dD,0.0);
arCablePtrs.append(pCableNew);
}
DELETE_PTR(pAlnNew);
}
return true;
}
}
DELETE_PTR(pALine);
}
else
{
acutPrintf(_T("\n线缆轨迹曲线不识别!引出线缆失败!"));
}
return false;
}
bool AecCableTool::UShapeAoid(AecDbEwCable* pCable,int nSegIndex,AcGeVector3d& vtOffset,double dFrom,double dL,double dVSpace,double dAngle,double dAngleB)
{
if (pCable == NULL)
return false;
if (nSegIndex == -1)
{
acutPrintf(_T("\n没有选择线缆的位置!避让失败!"));
return false;
}
int nCurve = nSegIndex;
AcDbCurve* pCurve = pCable->GetBaseCurve();
AecDb3dRoadAxisLine* pALine = AecDb3dRoadAxisLine::cast(pCurve);
if (pALine != NULL)
{
AcDbCurve* pSubCur = pALine->GetCurveSeg(nCurve);
if (pSubCur != NULL)
{
AcDbLine* pLine = AcDbLine::cast(pSubCur);
if (pLine != NULL)
{
double dLen = pLine->endPoint().distanceTo(pLine->startPoint());
if (dFrom + dL - dLen > 1.e-3)
{
DELETE_PTR(pALine);
acutPrintf(_T("\n避让开口太大,超出线缆!避让失败!"));
return false;
}
AcGeVector3d vtL = pLine->endPoint() - pLine->startPoint();
vtL.normalize();
double dX = dVSpace * fabs(tan(PI / 2.0 - dAngle * PI / 180.0));
double dX2 = dVSpace * fabs(tan(PI / 2.0 - dAngleB * PI / 180.0));
AcGePoint3d pt1 = pLine->startPoint() + vtL * dFrom;
AcGePoint3d pt2 = pt1 + vtOffset * dVSpace;
pt2 += vtL * dX;
AcGePoint3d pt4 = pt1 + vtL * dL;
AcGePoint3d pt3 = pt4 + vtOffset * dVSpace;
pt3 -= vtL * dX2;
AcGePoint3dArray arPtU;
arPtU.append(pt1);arPtU.append(pt2);arPtU.append(pt3);arPtU.append(pt4);
AcGePoint3dArray arPts;
pALine->GetReferLineSegPoints(arPts);
AcGeVector3d vtLU;
AcDbLine ln;
double dPar = 0.0;
for (int i = 0;i < arPts.length() - 1;i++)
{
ln.setStartPoint(arPts.at(i));
ln.setEndPoint(arPts.at(i+1));
if ( Acad::eOk == ln.getParamAtPoint(pt1,dPar))//落在此段
{
vtL = arPts.at(i+1) - arPts.at(i);
vtLU = arPtU.last() - arPtU.first();
if (vtL.isCodirectionalTo(vtLU))
{
arPtU.reverse();
}
pt2 = arPts.at(i);
pt3 = arPts.at(i+1);
for (int j = 0;j < arPtU.length();j++)
{
pt1 = arPtU.at(j);
arPts.insertAt(i+1,arPtU.at(j));
}
break;
}
}
double dD = 0.0,dRatio = 0.0;
pCable->GetSpecialtyData()->GetAt(CABLE_D,dD);
pCable->GetSpecialtyData()->GetAt(CABLE_RATIO,dRatio);
pALine->Create3dRoadAxisLine(dD,dRatio,arPts);
pCable->SetBaseCurve(pALine);//clone
DELETE_PTR(pALine);
return true;
}
else
{
acutPrintf(_T("\n选择的线缆位置不是直段位置,不能U弯避让!"));
}
}
}
return false;
}
extern AcGePoint3d MidPoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2);
AecDbEwCable* AecCableTool::MakeConnect(AecDbEwCable* pPipe1,AecDbEwCable* pPipe2)
{
if (pPipe1 == NULL || pPipe2 == NULL)
return NULL;
//要求收尾连续
AcDbCurve* pCurve1 = pPipe1->GetBaseCurve();
AcDbCurve* pCurve2 = pPipe2->GetBaseCurve();
AcDbLine* pLn1 = AcDbLine::cast(pCurve1);
AcDbLine* pLn2 = AcDbLine::cast(pCurve2);
if (pCurve1->isKindOf(AcDbArc::desc()) || pCurve2->isKindOf(AcDbArc::desc()))
{
return NULL;
}
AcGeVector3d vt1 = pLn1->endPoint() - pLn1->startPoint();
AcGeVector3d vt2 = pLn2->endPoint() - pLn2->startPoint();
vt1.normalize();vt2.normalize();
AcGePoint3d ptSta1,ptEnd1;
ptSta1 = pLn1->startPoint();
ptEnd1 = pLn1->endPoint();
// if (vt1.dotProduct(vt2) < -1.e-10)//方向相反
// {
// //修改pipe1的方向 reverse
// pLn1->setStartPoint(ptEnd1);
// pLn1->setEndPoint(ptSta1);
// }
//角度非常小的情况下
AcGePoint3d ptMid;
AcGeTol tol;
tol.setEqualPoint(1.e-2);
tol.setEqualVector(1.e-2);
if (vt1.isParallelTo(vt2,tol))
{
ptMid = MidPoint(pLn1->endPoint(),pLn2->startPoint());
pLn1->setEndPoint(ptMid);
pLn2->setStartPoint(ptMid);
pPipe1->SetBaseCurve(pLn1);
pPipe2->SetBaseCurve(pLn2);
return NULL;
}
double dRatio = 1.5;
if (!pPipe1->GetSpecialtyData()->GetAt(PIPE_RATIO,dRatio) )
{
dRatio = 1.5;
}
AecDbEwCable* pCable = AecCableTool::CreateElbow(pPipe1,pPipe2,dRatio);
return pCable;
/*AcGePlane plan;
AcGeVector3d vtNorm = vt2.crossProduct(vt1);
plan.set(ptEnd1,vtNorm);
AcGePoint3dArray arPts;
pLn1->intersectWith(pLn2,AcDb::kExtendBoth,plan,arPts);
if (arPts.length() == 1)
{
ptMid = arPts.first();
pLn1->setEndPoint(ptMid);
pLn2->setStartPoint(ptMid);
pPipe1->SetBaseCurve(pLn1);
pPipe2->SetBaseCurve(pLn2);
}
return true;*/
}
AecDbEwCable* AecCableTool::CreateElbow(AecDbEwCable* pPipe1,AecDbEwCable* pPipe2,double dRRato)
{
if (pPipe1 == NULL || pPipe2 == NULL)
return NULL;
AcDbCurve* pCrv1 = pPipe1->GetBaseCurve();
AcDbCurve* pCrv2 = pPipe2->GetBaseCurve();
if (pCrv1->isKindOf(AcDbArc::desc()) || pCrv2->isKindOf(AcDbArc::desc()))
{
return NULL;
}
AcGeVector3d vt1 = pPipe1->EndPoint() - pPipe1->StartPoint();
AcGeVector3d vt2 = pPipe2->EndPoint() - pPipe2->StartPoint();
vt1.normalize();vt2.normalize();
AcGePoint3d ptSta1,ptEnd1;
ptSta1 = pPipe1->StartPoint();
ptEnd1 = pPipe1->EndPoint();
if (vt1.dotProduct(vt2) < -1.e-10)//方向相反
{
//修改pipe1的方向 reverse
pPipe1->SetStartPoint(ptEnd1);
pPipe1->SetEndPoint(ptSta1);
}
AcGePoint3d ptMid;
if (vt1.isParallelTo(vt2))
{
ptMid = MidPoint(pPipe1->EndPoint(),pPipe2->StartPoint());
pPipe1->SetEndPoint(ptMid);
pPipe2->SetStartPoint(ptMid);
return NULL;
}
AcGePoint3dArray arPts;
AecInterface inf1,inf2;
AecInterface inf3,inf4;
arPts.removeAll();
AcGePlane plan;
AcGeVector3d vtNorm = vt2.crossProduct(vt1);
plan.set(ptEnd1,vtNorm);
pCrv1->intersectWith(pCrv2,AcDb::kExtendBoth,plan,arPts);
if (arPts.length() == 1)
{
ptMid = arPts.first();
//如果很小的角度,直接连接
double dAng = vt2.angleTo(vt1);
if (dAng - PI / 18.0 < 1.e-3 || dAng - 0.94 * PI > 1.e-3 )
{
pPipe1->SetEndPoint(ptMid);
pPipe2->SetStartPoint(ptMid);
DELETE_PTR(pCrv1);
DELETE_PTR(pCrv2);
return NULL;
}
pPipe1->GetInterface(1,inf1);
pPipe2->GetInterface(0,inf2);
AecDbEwCable* pElbow = AecCableTool::CreateElbow(pPipe1->GetSpecialtyData(),inf1.vtDir.negate(),inf2.vtDir.negate(),ptMid,dRRato);
if (pElbow != NULL)
{
pElbow->GetInterface(0,inf3);
pElbow->GetInterface(1,inf4);
if (inf3.vtDir.isParallelTo(inf1.vtDir) )
{
pPipe1->SetEndPoint(inf3.ptPos);
pPipe2->SetStartPoint(inf4.ptPos);
}
else
{
pPipe1->SetEndPoint(inf4.ptPos);
pPipe2->SetStartPoint(inf3.ptPos);
}
DELETE_PTR(pCrv1);
DELETE_PTR(pCrv2);
return pElbow;
}
}
DELETE_PTR(pCrv1);
DELETE_PTR(pCrv2);
return NULL;
}
AecDbEwCable* AecCableTool::CreateElbow(AecDbObjXDataMap* pMap,const AcGeVector3d& vtMaj,const AcGeVector3d& vtMin,const AcGePoint3d& ptMid,double dRRato)
{
AcGeVector3d vtMaj2 = vtMaj;
vtMaj2.negate();
AecDbEwFitting* pFit = new AecDbEwFitting;
pFit->GetSpecialtyData()->CopyFrom(pMap);
double dSweepAngle = vtMin.angleTo(vtMaj2);
AcGeVector3d vtNorm = vtMaj2.crossProduct(vtMin);
pFit->GetSpecialtyData()->SetAt(KEY_RUNTIME,eElbow);
pFit->GetSpecialtyData()->SetAt(PIPE_RATIO,dRRato);
pFit->GetSpecialtyData()->SetAt(PIPE_ELBOWANG,dSweepAngle);
pFit->GetSpecialtyData()->SetAt(KEY_FITSRV,KEY_FITWPIPE);
pFit->GetSpecialtyData()->SetAt(KEY_MAJBR,vtMaj2);
pFit->GetSpecialtyData()->SetAt(KEY_MINBR,vtMin);
pFit->GetSpecialtyData()->SetAt(KEY_NORMAL,vtNorm);
pFit->GetSpecialtyData()->SetAt(KEY_MID,ptMid);
AcDbArc* pArc = pFit->GetElbowArc();
DELETE_PTR(pFit);
if (pArc != NULL)
{
AecDbEwCable* pCableArc = new AecDbEwCable;
pCableArc->GetSpecialtyData()->CopyFrom(pMap);
pCableArc->SetBaseCurve(pArc);
double dD = 0.0;
pMap->GetAt(CABLE_D, dD);
pCableArc->SetSection(dD,0.0);
return pCableArc;
}
return NULL;
}