484 lines
11 KiB
C++
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;
|
|
} |