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

2963 lines
68 KiB
C++

#include "StdAfx.h"
#include "CCableRouting.h"
#include "implement/AecDbXEquipment.h"
#include "AecDbEwEquipment.h"
#include "AecDbECableTray.h"
#include "AecDbEcFitting.h"
#include "AecDbEwFlexiblePipe.h"
#include "AecDb3dRoadAxisLine.h"
#include "AecDbDirPosition.h"
#include <algorithm>
#include "CLJCKDlg.h"
#include "KTSetting.h"
#include "KTTempTol.h"
#include "coretools.h"
//
//槽式;托盘式;梯架式;
//
#ifndef DXF_EQU
#define DXF_EQU _T("AEC_DBWEQUIPMENT,AEC_DBXEQUIPMENT,AEC_DBPARAEQUI")
#define DXF_PATH _T("LINE,LWPOLYLINE,AEC_ROADAXISLINE,AEC_EWFPIPE")
#define DXF_TRAY_FPIPE _T("AEC_DBCABTRY,AEC_EWFPIPE,AEC_ROADAXISLINE")
#define DXF_DIRPS _T("AEC_DIRPS")
#endif
#ifndef EL_SYS
#define HIGH_V _T("高压")
#define LOW_V _T("低压")
#define KVV _T("控制")
#define MSGV _T("通讯")
#define MSGV2 _T("信号")
#define MSGV3 _T("仪表")
#endif
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;
AcGePoint3d DLLIMPEXP MidPoint(const AcGePoint3d &pt1, const AcGePoint3d &pt2);
CableRoutePath::CableRoutePath()
{
m_nColorIndex = kWhite;
m_idRd.setNull();
m_dTol = 1.e-3;
/*struct resbuf rb;
acedGetVar(_T("INSUNITS"), &rb);
if (rb.resval.rint == AcDb::kUnitsMeters)
{
m_dTol = 1.e-3;//米
}
else if (rb.resval.rint == AcDb::kUnitsCentimeters)
{
m_dTol = 1.e-4;//厘米
}
else if (rb.resval.rint == AcDb::kUnitsMillimeters)
{
m_dTol = 1.e-6;//毫米
}
else if (rb.resval.rint == AcDb::kUnitsDecimeters)
{
m_dTol = 1.e-5;//分米
}*/
}
CableRoutePath::~CableRoutePath()
{
DeleteAll();
}
void CableRoutePath::DeleteAll()
{
while(!m_arPathSegs.isEmpty())
{
idPathSeg &seg = m_arPathSegs.last();
if (seg.pLine != NULL)
{
delete seg.pLine;
}
m_arPathSegs.removeLast();
}
}
bool CableRoutePath::HasLineSeg(const idPathStep &idps)
{
AcGePoint3d ptS, ptE;
for (int i = 0; i < m_arPathSegs.length(); i++)
{
const idPathSeg &ips = m_arPathSegs.at(i);
ips.pLine->getStartPoint(ptS);
ips.pLine->getEndPoint(ptE);
if (ptS.distanceTo(idps.ptGe[0]) < 1.e-1 &&
ptE.distanceTo(idps.ptGe[1]) < 1.e-1)
return true;
else if (ptS.distanceTo(idps.ptGe[1]) < 1.e-1 &&
ptE.distanceTo(idps.ptGe[0]) < 1.e-1)
return true;
}
return false;
}
bool CableRoutePath::HasLineSeg(const AcGePoint3d& ptGe0,const AcGePoint3d& ptGe1)
{
AcGePoint3d ptS, ptE;
for (int i = 0; i < m_arPathSegs.length(); i++)
{
const idPathSeg &ips = m_arPathSegs.at(i);
ips.pLine->getStartPoint(ptS);
ips.pLine->getEndPoint(ptE);
if (ptS.distanceTo(ptGe0) < 1.e-1 &&
ptE.distanceTo(ptGe1) < 1.e-1)
return true;
else if (ptS.distanceTo(ptGe1) < 1.e-1 &&
ptE.distanceTo(ptGe0) < 1.e-1)
return true;
}
return false;
}
bool CableRoutePath::IsPassByLockPath(const AcDbObjectIdArray &arIdsPassBy)
{
if (arIdsPassBy.isEmpty())
return true;
AcDbObjectIdArray arBkLock;
arBkLock.append(arIdsPassBy);
//arIdsPassBy 必须在 m_arPathSegs 中
for (int i = 0; i < m_arPathSegs.length(); i++)
{
const idPathSeg &ips = m_arPathSegs.at(i);
//ips.id;
arBkLock.remove(ips.id);
}
if (arBkLock.isEmpty())
return true;
return false;
}
void CableRoutePath::removeLast()
{
if (!m_arPathSegs.isEmpty())
{
idPathSeg &seg = m_arPathSegs.last();
if (seg.pLine != NULL)
{
delete seg.pLine;
}
m_arPathSegs.removeLast();
}
}
void CableRoutePath::removeFirst()
{
if (!m_arPathSegs.isEmpty())
{
idPathSeg &seg = m_arPathSegs.first();
if (seg.pLine != NULL)
{
delete seg.pLine;
}
m_arPathSegs.removeFirst();
}
}
void CableRoutePath::SetCableData(const CableData &data)
{
memcpy(&m_cabData, &data, sizeof(CableData));
}
Acad::ErrorStatus CableRoutePath::AppendCurveSeg(AcDbCurve *pCurve, const AcDbObjectId &id, double dSize[3],LPCTSTR pszPathNo)
{
if (pCurve == NULL)
return Acad::eInvalidInput;
idPathSeg ips;
ips.id = id;
ips.pLine = pCurve;
_tcscpy(ips.szPathNo, _T(""));
_tcscpy(ips.szNo, _T(""));
memcpy(ips.dSize, dSize, sizeof(double) * 3);
if (pszPathNo != NULL)
{
_tcscpy(ips.szPathNo, pszPathNo);
}
m_arPathSegs.append(ips);
return Acad::eOk;
}
AcDbCurve * CableRoutePath::getEndCurveSeg()
{
AcDbCurve *pCurve = NULL;
if (!m_arPathSegs.isEmpty())
{
idPathSeg &ips = m_arPathSegs.last();
pCurve = ips.pLine;
}
return pCurve;
}
Acad::ErrorStatus CableRoutePath::getStartPoint(AcGePoint3d &pt) const
{
if (!m_arPathSegs.isEmpty())
{
KTTempTol tol(m_dTol);
if (m_arPathSegs.length() == 1)
{
const idPathSeg &ips = m_arPathSegs.first();
return ips.pLine->getStartPoint(pt);
}
else
{
const idPathSeg &ips0 = m_arPathSegs.at(0);
const idPathSeg &ips1 = m_arPathSegs.at(1);
AcGePoint3d pt0,pt1,pt2,pt3;
ips0.pLine->getStartPoint(pt0);
ips0.pLine->getEndPoint(pt1);
AcGePoint3dArray arPts;
arPts.append(pt0);
arPts.append(pt1);
ips1.pLine->getStartPoint(pt2);
ips1.pLine->getEndPoint(pt3);
int nPos = -1;
if (arPts.find(pt2, nPos, 0))
{
arPts.removeAt(nPos);
pt = arPts.first();
return Acad::eOk;
}
if (arPts.find(pt3, nPos, 0))
{
arPts.removeAt(nPos);
pt = arPts.first();
return Acad::eOk;
}
}
}
return Acad::eOutOfMemory;
}
Acad::ErrorStatus CableRoutePath::getEndPoint(AcGePoint3d &pt) const
{
if (!m_arPathSegs.isEmpty())
{
KTTempTol tol(m_dTol);
if (m_arPathSegs.length() == 1)
{
const idPathSeg &ips = m_arPathSegs.last();
return ips.pLine->getEndPoint(pt);
}
else
{
int nTail = m_arPathSegs.length() - 1;
const idPathSeg &ips0 = m_arPathSegs.at(nTail);
const idPathSeg &ips1 = m_arPathSegs.at(nTail - 1);
AcGePoint3d pt0, pt1, pt2, pt3;
ips0.pLine->getStartPoint(pt0);
ips0.pLine->getEndPoint(pt1);
AcGePoint3dArray arPts;
arPts.append(pt0);
arPts.append(pt1);
ips1.pLine->getStartPoint(pt2);
ips1.pLine->getEndPoint(pt3);
int nPos = -1;
if (arPts.find(pt0, nPos, 0))
{
arPts.removeAt(nPos);
pt = arPts.last();
return Acad::eOk;
}
if (arPts.find(pt3, nPos, 0))
{
arPts.removeAt(nPos);
pt = arPts.last();
return Acad::eOk;
}
}
}
return Acad::eOutOfMemory;
}
Adesk::UInt16 CableRoutePath::colorIndex() const
{
return m_nColorIndex;
}
Acad::ErrorStatus CableRoutePath::setColorIndex(Adesk::UInt16 nColorIndex)
{
m_nColorIndex = nColorIndex;
return Acad::eOk;
}
double CableRoutePath::length() const
{
double dLen = 0.0,dE = 0,dL = 0;
for (int i = 0; i < m_arPathSegs.length(); i++)
{
const idPathSeg &ips = m_arPathSegs.at(i);
ips.pLine->getEndParam(dE);
ips.pLine->getDistAtParam(dE, dL);
dLen += fabs(dL);
}
return dLen;
}
void CableRoutePath::GetPathSteps(CString &sPathSteps) const
{
CString sStep;
for (int i = 0; i < m_arPathSegs.length(); i++)
{
const idPathSeg &ips = m_arPathSegs.at(i);
sStep.Format(_T("%s_%s"),ips.szPathNo,ips.szNo);
if (sStep.GetLength() > 1)
{
sPathSteps += sStep;
sPathSteps += _T("-");
}
}
sPathSteps.TrimRight(_T('-'));
}
Acad::ErrorStatus CableRoutePath::copyFrom(CableRoutePath *pPath)
{
if (pPath == NULL)
return Acad::eInvalidInput;
m_nColorIndex = pPath->m_nColorIndex;
m_cabData = pPath->m_cabData;
DeleteAll();
idPathSeg segNew;
for (int i = 0;i < pPath->m_arPathSegs.length();i++)
{
idPathSeg &seg = pPath->m_arPathSegs.at(i);
segNew.id = seg.id;
segNew.pLine = (AcDbCurve *)seg.pLine->clone();
_tcscpy(segNew.szPathNo, seg.szPathNo);
_tcscpy(segNew.szNo, seg.szNo);
m_arPathSegs.append(segNew);
}
return Acad::eOk;
}
AecDb3dRoadAxisLine *CableRoutePath::GetPathRoadAxLine() const
{
AecDb3dRoadAxisLine *pRd = new AecDb3dRoadAxisLine;
for (int i = 0;i < m_arPathSegs.length();i++)
{
const idPathSeg &ips = m_arPathSegs.at(i);
pRd->AppendCurveSeg(ips.pLine);
pRd->AddPathHd(ips.szPathNo);
}
pRd->SaveDandRatio(m_cabData.dD, 1.0);
pRd->setColorIndex(m_nColorIndex);
return pRd;
}
bool CableRoutePath::Add2ModelSpace(LPCTSTR pszFr,LPCTSTR pszTo)
{
AecDb3dRoadAxisLine* pRd = CableRoutePath::GetPathRoadAxLine();
if (pRd != NULL)
{
pRd->SaveDandRatio(m_cabData.dD, 1.0);
AcDbObjectId idLayCable = KTSetting::InitLayer(_T("LAY_CABLE"), true);
pRd->setLayer(idLayCable);
//写入电缆数据,扩展数据
AecDbObjXDataMap xData;
xData.SetAt(KEY_SPEC,m_cabData.szSpec);
xData.SetAt(KEY_SYS, m_cabData.szSys);
xData.SetAt(KEY_SECNAME, m_cabData.szSect);
xData.SetAt(KEY_V, m_cabData.dV);
xData.SetAt(PIPE_OD, m_cabData.dD);
Adesk::UInt16 nColor = kRed;
//按照系统重新设置颜色
CString sSys = m_cabData.szSys;
if (sSys.Find(HIGH_V) != -1)
nColor = kRed;
else if (sSys.Find(LOW_V) != -1)
nColor = kYellow;
else if (sSys.Find(KVV) != -1)
nColor = kGreen;
else if (sSys.Find(MSGV) != -1)
nColor = kCyan;
else if (sSys.Find(MSGV2) != -1)
nColor = kBlue;
else if (sSys.Find(MSGV3) != -1)
nColor = kMagenta;
/*
* #ifndef EL_SYS
#define HIGH_V _T("高压")
#define LOW_V _T("低压")
#define KVV _T("控制")
#define MSGV _T("通讯")
#define MSGV2 _T("信号")
#define MSGV3 _T("仪表")
#endif
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;
*/
if (pszFr != NULL && pszTo != NULL)
{
xData.SetAt(KEY_START, pszFr);
xData.SetAt(KEY_END, pszTo);
}
pRd->setColorIndex(nColor);
m_idRd = CoreTools::AddToModelSpace(pRd,false);
xData.Write(pRd,KEY_APP);
//pRd->setVisibility(AcDb::kInvisible);
pRd->close();
}
return m_idRd.isValid();
}
AcDbObjectId CableRoutePath::GetRoadAxLineId() const
{
return m_idRd;
}
bool CableRoutePath::EraseRoadAxLine()
{
AcDbEntity *pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, m_idRd, AcDb::kForWrite))
{
pEnt->erase();
pEnt->close();
}
m_idRd.setNull();
return true;
}
bool CableRoutePath::GetEndIdPathSeg(idPathSeg &idPs) const
{
if (!m_arPathSegs.isEmpty())
{
idPs = m_arPathSegs.last();
return true;
}
return false;
}
static bool IsSameAsSysUse(LPCTSTR pszSys1,LPCTSTR pszSysD)
{
CString sSys1 = pszSys1;
CString sSysD = pszSysD;
//sSysPt
//控制和通讯(<450-750v);仪表(24v);动力低压(0.6-1kv);动力高压[3-110kv);
//syscab 含有如下
/*
#define HIGH_V _T("高压")
#define LOW_V _T("低压")
#define KVV _T("控制")
#define MSGV _T("通讯")
#define MSGV2 _T("信号")
#define MSGV3 _T("仪表")
*/
//sSysPt 和 sSysCab 都含有上述define 是,为系统匹配
CStringList arSHv, arSLv;
CStringList arKMSG;
arSHv.AddTail(HIGH_V);
arSLv.AddTail(LOW_V);
arKMSG.AddTail(KVV); arKMSG.AddTail(MSGV); arKMSG.AddTail(MSGV2); arKMSG.AddTail(MSGV3);
//高压是否相同
CString sCmn;
bool bThis = false, bThat = false;
for (POSITION ps = arSHv.GetHeadPosition(); ps != NULL;)
{
sCmn = arSHv.GetNext(ps);
if (sSys1.Find(sCmn) != -1)
bThis = true;
if (sSysD.Find(sCmn) != -1)
bThat = true;
}
if (bThis && bThat)
return true;
//低压是否相同
bThis = false, bThat = false;
for (POSITION ps = arSLv.GetHeadPosition(); ps != NULL;)
{
sCmn = arSLv.GetNext(ps);
if (sSys1.Find(sCmn) != -1)
bThis = true;
if (sSysD.Find(sCmn) != -1)
bThat = true;
}
if (bThis && bThat)
return true;
//控制通讯
bThis = false, bThat = false;
for (POSITION ps = arKMSG.GetHeadPosition(); ps != NULL;)
{
sCmn = arKMSG.GetNext(ps);
if (sSys1.Find(sCmn) != -1)
bThis = true;
if (sSysD.Find(sCmn) != -1)
bThat = true;
}
if (bThis && bThat)
return true;
return false;
}
static bool IsSameAsSysUse(const CableData &data, AecHvac::DuctParam &param)
{
/*
#define HIGH_V _T("高压")
#define LOW_V _T("低压")
#define KVV _T("控制")
#define MSGV _T("通讯")
#define MSGV2 _T("信号")
#define MSGV3 _T("仪表")
*/
CStringList arSHv, arSLv;
CStringList arKMSG;
arSHv.AddTail(HIGH_V);
arSLv.AddTail(LOW_V);
arKMSG.AddTail(KVV); arKMSG.AddTail(MSGV); arKMSG.AddTail(MSGV2); arKMSG.AddTail(MSGV3);
CString sSysD = data.szSys;
CString sSys1, sSys2 = _T("-"), sSyss;
if (param.m_bSpart)//分层
{
sSyss = param.szSys;
int nPos = sSyss.Find(_T('|'), 0);
if (nPos != -1)
{
sSys1 = sSyss.Mid(0, nPos);
if (nPos < sSyss.GetLength() - 1)
sSys2 = sSyss.Mid(nPos + 1);
}
else
{
sSys1 = sSyss;
}
}
else
{
sSys1 = param.szSys;
}
//高压是否相同
CString sCmn;
bool bThis = false, bThat = false;
for (POSITION ps = arSHv.GetHeadPosition(); ps != NULL;)
{
sCmn = arSHv.GetNext(ps);
if (sSys1.Find(sCmn) != -1)
bThis = true;
if (sSys2.Find(sCmn) != -1)
bThis = true;
if (sSysD.Find(sCmn) != -1)
bThat = true;
}
if (bThis && bThat)
return true;
//低压是否相同
bThis = false, bThat = false;
for (POSITION ps = arSLv.GetHeadPosition(); ps != NULL;)
{
sCmn = arSLv.GetNext(ps);
if (sSys1.Find(sCmn) != -1)
bThis = true;
if (sSys2.Find(sCmn) != -1)
bThat = true;
if (sSysD.Find(sCmn) != -1)
bThat = true;
}
if (bThis && bThat)
return true;
//控制通讯
bThis = false, bThat = false;
for (POSITION ps = arKMSG.GetHeadPosition(); ps != NULL;)
{
sCmn = arKMSG.GetNext(ps);
if (sSys1.Find(sCmn) != -1)
bThis = true;
if (sSys2.Find(sCmn) != -1)
bThis = true;
if (sSysD.Find(sCmn) != -1)
bThat = true;
}
if (bThis && bThat)
return true;
return false;
}
Acad::ErrorStatus CableRoutePath::SetFillUsed(AecDbObjXDataMap *pDataMap, AecHvac::DuctParam& param, const CableData &data) const
{
double dFillUsed = 0.0, dThisUsed = 0;
CString sSys, sSys2, sSysData = data.szSys;
double dSCab = 0.25 * PI * m_cabData.dD * m_cabData.dD;
struct resbuf rb;
acedGetVar(_T("INSUNITS"), &rb);
if (rb.resval.rint == AcDb::kUnitsMeters)
{
dSCab *= 1.e-6;
}
if (param.m_bSpart)//有隔板
{
//隔板系统分类
//param.m_nSysSplit;
//判断
CString sSyss = param.szSys;
sSyss.TrimRight();
int nPos = sSyss.Find(_T('|'), 0);
if (nPos != -1)
{
sSys = sSyss.Mid(0, nPos);
if (nPos < sSyss.GetLength() - 1)
{
sSys2 = sSyss.Mid(nPos + 1);
}
if (IsSameAsSysUse(sSys, sSysData) )
//if (sSysData.Find(sSys) != -1)//走左侧层
{
//...
dFillUsed = 0.0;
pDataMap->GetAt(KEY_FILLUSED, dFillUsed);//0.65
//面积 / 总面积 = 0.15
dThisUsed = dSCab;
dThisUsed /= ( param.dSize[4] * param.dSize[1] );
//ext.累加 0.45 + 0.15
dFillUsed += dThisUsed;
pDataMap->SetAt(KEY_FILLUSED, dFillUsed);
}
//else if (sSysData.Find(sSys2) != -1)//走右侧层
else if (IsSameAsSysUse(sSys2, sSysData))
{
//...
dFillUsed = 0.0;
pDataMap->GetAt(KEY_FILLUSED2, dFillUsed);
//ext.面积 / 总面积 = 0.15
dThisUsed = dSCab;
dThisUsed /= (( param.dSize[0] - param.dSize[4]) * param.dSize[1]);
//ext.累加 0.45 + 0.15
dFillUsed += dThisUsed;
pDataMap->SetAt(KEY_FILLUSED2, dFillUsed);
}
else//都没有找到,走单层
{
//...
dFillUsed = 0.0;
pDataMap->GetAt(KEY_FILLUSED, dFillUsed);
//ext.面积 / 总面积 = 0.15
dThisUsed = dSCab;
dThisUsed /= ( param.dSize[0] * param.dSize[1] );
//ext.累加 0.45 + 0.15
dFillUsed += dThisUsed;
pDataMap->SetAt(KEY_FILLUSED, dFillUsed);
}
}
else//有隔板,没有分层系统,走单层
{
dFillUsed = 0.0;
pDataMap->GetAt(KEY_FILLUSED, dFillUsed);
//ext.面积 / 总面积 = 0.15
dThisUsed = dSCab;
dThisUsed /= ( param.dSize[0] * param.dSize[1] );
//ext.面积 / 总面积 = 0.15
dFillUsed += dThisUsed;
pDataMap->SetAt(KEY_FILLUSED, dFillUsed);
}
}
else
{
dFillUsed = 0.0;
pDataMap->GetAt(KEY_FILLUSED, dFillUsed);
//ext.面积 / 总面积 = 0.15
dThisUsed = dSCab;
dThisUsed /= ( param.dSize[0] * param.dSize[1] );
//ext.面积 / 总面积 = 0.15
dFillUsed += dThisUsed;
pDataMap->SetAt(KEY_FILLUSED, dFillUsed);
}
return Acad::eOk;
}
Acad::ErrorStatus CableRoutePath::CalSetFillUsed(const CableData& data) const
{
Adesk::UInt16 nColor = colorIndex();
DlgData dlgData;
AecHvac::DuctParam param;
double dFillUsed = 0.0,dThisUsed = 0;
CString sSys, sSys2,sSysData = data.szSys;
AcDbEntity *pEnt = NULL;
for (int i = 0; i < m_arPathSegs.length(); i++)
{
const idPathSeg &ips = m_arPathSegs.at(i);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, ips.id, AcDb::kForWrite))
{
AecDbECableTray *pTray = AecDbECableTray::cast(pEnt);
if (pTray != NULL)
{
if (!pTray->GetDlgData(dlgData))
{
memset(&param, 0, sizeof(AecHvac::DuctParam));
pTray->GetDuctParam(param);
AecDbObjXDataMap *pDataMap = pTray->GetSpecialtyData(AcDb::kForWrite);
//if (nColor == kRed)//红色才考虑容积率
{
SetFillUsed(pDataMap, param, data);
}
}
}
AecDbEcFitting *pEFit = AecDbEcFitting::cast(pEnt);
if (pEFit != NULL)
{
if (!pEFit->GetDlgData(dlgData))
{
memset(&param, 0, sizeof(AecHvac::DuctParam));
pEFit->GetDuctParam(param);
AecDbObjXDataMap *pDataMap = pTray->GetSpecialtyData(AcDb::kForWrite);
//if (nColor == kRed)//红色才考虑容积率
{
SetFillUsed(pDataMap, param, data);
}
}
}
pEnt->close();
}
}
//保存路径的桥架缆沟等ID,删除时递增填充率
if (m_idRd.isValid() && nColor == kRed)
{
AcDbEntity *pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, m_idRd, AcDb::kForWrite))
{
AecDb3dRoadAxisLine *pRd = AecDb3dRoadAxisLine::cast(pEnt);
if (pRd != NULL)
{
TCHAR szHd[17];
for (int i = 0; i < m_arPathSegs.length(); i++)
{
const idPathSeg &idPs = m_arPathSegs.at(i);
if (idPs.id.isValid())
{
idPs.id.handle().getIntoAsciiBuffer(szHd);
pRd->AddPathHd(szHd);
}
}
}
pEnt->close();
}
}
return Acad::eOk;
}
//CCableRouting
CCableRouting::CCableRouting()
{
int nUnit = 1;//默认毫米
struct resbuf rb;
acedGetVar(_T("INSUNITS"), &rb);
if (rb.resval.rint == AcDb::kUnitsMeters)
{
nUnit = 1000;
}
m_dBypassDis = 1000.0 / nUnit;//
m_dSpaceTol = 100.0 / nUnit;//100mm
m_dPathOnPoint = 100.0 / nUnit;
m_dMaxextDis = 1000.0 / nUnit;
m_dEquFindDis = 5000.0 / nUnit;
m_bIgoreFillUsed = false;
m_nAssocNoorName = 0;
}
CCableRouting::~CCableRouting()
{
}
void CCableRouting::SetBypassDis(double dBypassDis)
{
m_dBypassDis = dBypassDis;
}
void CCableRouting::SetPathOnPoint(double dPathOnPoint)
{
m_dPathOnPoint = dPathOnPoint;
}
void CCableRouting::SetEquFindDis(double dEquFindDis)
{
m_dEquFindDis = dEquFindDis;
}
void CCableRouting::SetIgoreFillUsed(bool bIgore)
{
m_bIgoreFillUsed = bIgore;
}
void CCableRouting::SetAssocNoorName(int nAssocNoorName)
{
m_nAssocNoorName = nAssocNoorName;
}
bool CCableRouting::FindEquCableEntryPoint(const AcDbObjectId &idEqu, AcGePoint3d& ptFrom, AcDbExtents &ext,AcDbObjectId &idEntryFr,AcGePoint3d& ptEntry)
{
struct resbuf* pRb1 = acutBuildList(RTDXF0, DXF_TRAY_FPIPE, 0);
double dDs1 = 0, dDs2 = 0,dDsMax = 999999.0;
AcGePoint3d ptS, ptE;
AcDbObjectId id,idT;
ads_name ss, ent;
int nRes = acedSSGet(_T("X"), NULL, NULL, pRb1, ss);
if (nRes == RTNORM)
{
Adesk::Int32 nLen = 0;
acedSSLength(ss, &nLen);
AcDbEntity *pEnt = NULL;
for (int i = 0;i < nLen;i++)
{
acedSSName(ss, i, ent);
acdbGetObjectId(id, ent);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead))
{
AecDbECableTray *pTray = AecDbECableTray::cast(pEnt);
if (pTray != NULL)
{
pTray->getStartPoint(ptS);
pTray->getEndPoint(ptE);
}
AecDbEwFlexiblePipe *pFPipe = AecDbEwFlexiblePipe::cast(pEnt);
if (pFPipe != NULL)
{
pFPipe->getStartPoint(ptS);
pFPipe->getEndPoint(ptE);
}
AecDb3dRoadAxisLine *pRd = AecDb3dRoadAxisLine::cast(pEnt);
if (pRd != NULL)
{
pRd->getStartPoint(ptS);
pRd->getEndPoint(ptE);
}
dDs1 = ptS.distanceTo(ptFrom);
dDs2 = ptE.distanceTo(ptFrom);
if (__min(dDs1, dDs2) < dDsMax)
{
dDsMax = __min(dDs1, dDs2);
idT = id;
ptEntry = fabs(dDsMax - dDs1) < 1.e-3 ? ptS : ptE;
}
pEnt->close();
}
}
acedSSFree(ss);
//距离设备范围ext 小于 m_dEquFindDis 即可
// ...
//
//acutPrintf(_T("\n设备距离最近的桥架套管距离=%.1f"),dDsMax);
if (dDsMax < m_dEquFindDis)
{
idEntryFr = idT;
return true;
}
//没有找到,则查看最近的引出线口
for (int i = 0;i < m_arRaceWayExit.length();i++)
{
idLeadPort &idlp = m_arRaceWayExit.at(i);
dDs1 = idlp.m_ptPos.distanceTo(ptFrom);
if (dDs1 < m_dEquFindDis)
{
idEntryFr = idT;
ptEntry = idlp.m_ptPos;
return true;
}
}
}
return false;
}
void CCableRouting::CopyNRoadAxline(idPathStep &idps, int nSkip, CableRoutePath *pRd, AcArray<CableRoutePath *>& arNewRd)
{
if (pRd == NULL) return;
AcGePoint3d ptEnd;
pRd->getEndPoint(ptEnd);
CableRoutePath *pRdNew = NULL;
for (int i = 0;i < idps.nPoints;i++)
{
if (i != nSkip)
{
pRdNew = new CableRoutePath;
pRdNew->setColorIndex(kWhite);
pRdNew->copyFrom(pRd);
AcDbLine *pLn = new AcDbLine(ptEnd, idps.ptGe[i]);
pRdNew->AppendCurveSeg(pLn, idps.id,idps.dSize);
arNewRd.append(pRdNew);
}
}
}
bool CCableRouting::IsNearToEndEntry(CableRoutePath *pRd, const AcGePoint3d &ptToEntry)
{
if (pRd == NULL)
return false;
AcGePoint3d ptE;
pRd->getEndPoint(ptE);
double dSize[3];
memset(dSize, 0, sizeof(double) * 3);
if (ptE.distanceTo(ptToEntry) < m_dMaxextDis)//5米范围内
{
//L形折线连接
AcDbLine *pLn = NULL;
//先Z
AcGePoint3d ptToEntry2 = ptE;
ptToEntry2.z = ptToEntry.z;
pLn = new AcDbLine(ptToEntry2, ptE);
pRd->AppendCurveSeg(pLn, AcDbObjectId::kNull,dSize);
//然后水平
pLn = new AcDbLine(ptToEntry2, ptToEntry);
pRd->AppendCurveSeg(pLn, AcDbObjectId::kNull,dSize);
//设为有效路径
pRd->setColorIndex(kRed);
return true;
}
return false;
}
//是否接近锁定路径连接
bool CCableRouting::GoOnLockPath(CableRoutePath *pRd)
{
AcGePoint3d ptE;
pRd->getEndPoint(ptE);
bool bOnLockPath = false;
AcDbLine *pLn = NULL;
AcArray< idPathStep> arSteps;
arSteps.append(m_arIdPathBy);
for (int i = 0;i < arSteps.length();i++)
{
idPathStep &ips = arSteps.at(i);
//if ( ptE.distanceTo(ips.ptGe[0]) < m_dSpaceTol)
if (IsPointDockPathStep(pRd,ptE,ips,0))
{
//判断是否回溯
if (pRd->HasLineSeg(ips))
{
continue;
}
if (!pRd->HasLineSeg(ptE, ips.ptGe[1]))
{
pLn = new AcDbLine(ptE, ips.ptGe[1]);
pRd->AppendCurveSeg(pLn, ips.id, ips.dSize, ips.szPathNo);
//进入下次锁定路径连接
pRd->getEndPoint(ptE);
bOnLockPath = true;
arSteps.removeAt(i);
i = -1;//从头开始
continue;
}
}
//else if (ptE.distanceTo(ips.ptGe[1]) < m_dSpaceTol)
else if (IsPointDockPathStep(pRd, ptE, ips, 1))
{
//判断是否回溯
if (pRd->HasLineSeg(ips))
{
continue;
}
if (!pRd->HasLineSeg(ptE, ips.ptGe[0]))
{
pLn = new AcDbLine(ptE, ips.ptGe[0]);
pRd->AppendCurveSeg(pLn, ips.id, ips.dSize, ips.szPathNo);
//进入下次锁定路径连接
pRd->getEndPoint(ptE);
bOnLockPath = true;
arSteps.removeAt(i);
i = -1;//从头开始
continue;
}
}
}
return bOnLockPath;
}
bool CCableRouting::IsPointDockPathStep(CableRoutePath *pRd, const AcGePoint3d &ptEnd, idPathStep &idps, int nPtPos)
{
if (ptEnd.distanceTo(idps.ptGe[nPtPos]) < m_dSpaceTol)
return true;
AcGePoint2d ptS2d, ptE2d;
ptS2d.set(idps.ptGe[nPtPos].x, idps.ptGe[nPtPos].y);
ptE2d.set(ptEnd.x, ptEnd.y);
//水平投影在误差范围内
if (ptS2d.distanceTo(ptE2d) > m_dSpaceTol)
{
return false;
}
double dTolMax = __max(idps.dSize[0], idps.dSize[1]);
dTolMax = __max(dTolMax, m_dSpaceTol);
double dTolMaxL = dTolMax;
idPathSeg idpsL;
if (pRd->GetEndIdPathSeg(idpsL))
{
dTolMaxL = __max(idpsL.dSize[0], idpsL.dSize[1]);
dTolMax = __max(dTolMax, dTolMaxL);
}
//空间标高在尺寸范围内
if (fabs(ptEnd.z - idps.ptGe[nPtPos].z) < dTolMax)
{
return true;
}
return false;
}
/*
* 注:上高速时,如果遇到引线接口,算一条连接设备的路径!!!
*/
bool CCableRouting::IsGoRacewayExit(const AcGePoint3d &ptEnd, idPathStep &idps, AcGePoint3d &ptExit, const AcGePoint3d &ptToEntry)
{
TCHAR szHd[17];
AcGePoint3d ptOn, ptOn2 = ptToEntry;
ptOn2.z = 0.0;
AcGePoint3d pt1, pt2;
double dDis = 0, dP = 0;
//自 点, X=55868.6186 Y=126211.5881 Z=3175.0000
//到 点, X=60740.5504 Y=126211.5881 Z=3175.0000
pt1.set(55868.6186, 126211.5881, 3175.0);
pt2.set(60740.5504, 126211.5881, 3175.0);
if (idps.ptGe[0].distanceTo(pt1) < 10.0 &&
idps.ptGe[1].distanceTo(pt2) < 10.0)
{
int nnnn = 1000;
}
for (int i = 0;i < m_arRaceWayExit.length();i++)
{
idLeadPort &idlp = m_arRaceWayExit.at(i);
if (idps.id.isValid())
{
idps.id.handle().getIntoAsciiBuffer(szHd);
if (_tcscmp(szHd, idlp.szHd) == 0)//本段上的出口
{
//判断本段出口是否有线管,预埋路径直通设备
//m_arIdPathBy
AcDbLine ln;
ln.setStartPoint(idps.ptGe[0]);
ln.setEndPoint(idps.ptGe[1]);
//idLeadPort 落在 idps 上
if (Acad::eOk == ln.getClosestPointTo(idlp.m_ptPos, ptOn, Adesk::kTrue))
{
if (Acad::eOk == ln.getParamAtPoint(ptOn, dP))
{
if (ptOn.distanceTo(idlp.m_ptPos) <= 1000.0)//1米
{
//5米范围内,并且同系统
ptOn.z = 0.0;
dDis = ptOn.distanceTo(ptOn2);
if ( dDis < m_dEquFindDis &&
IsSameAsSysUse(idlp.szSys,idps.szSys) || _tcslen(idps.szSys) == 0)
{
ptExit = idlp.m_ptPos;
return true;
}
}
}
}
}
}
}
return false;
}
void CCableRouting::AddLPath(CableRoutePath *pRd, const AcGePoint3d &ptEnd, const AcGePoint3d &ptTo,int nOut/* = 1*/, LPCTSTR pszPathNo)
{
if (ptEnd.distanceTo(ptTo) > m_dMaxextDis)
{
double dSize[3];
memset(dSize, 0, sizeof(double) * 3);
if (nOut == 1)//出
{
//创建 L形 电缆路径
AcDbLine* pLn = new AcDbLine(ptEnd, AcGePoint3d(ptEnd.x, ptEnd.y, ptTo.z));
pRd->AppendCurveSeg(pLn, AcDbObjectId::kNull, dSize, pszPathNo);
pLn = new AcDbLine(AcGePoint3d(ptEnd.x, ptEnd.y, ptTo.z), ptTo);
pRd->AppendCurveSeg(pLn, AcDbObjectId::kNull, dSize,pszPathNo);
}
else//进
{
//创建 L形 电缆路径
AcDbLine *pLn = new AcDbLine(ptEnd, AcGePoint3d(ptTo.x, ptTo.y, ptEnd.z));
pRd->AppendCurveSeg(pLn, AcDbObjectId::kNull, dSize, pszPathNo);
pLn = new AcDbLine(AcGePoint3d(ptTo.x, ptTo.y, ptEnd.z), ptTo);
pRd->AppendCurveSeg(pLn, AcDbObjectId::kNull, dSize, pszPathNo);
}
}
}
bool CCableRouting::Has2Way(const AcGePoint3d &ptEnd)
{
int nPt = 0;
for (int i = 0; i < m_arIdPthSteps.length(); i++)
{
idPathStep &idps = m_arIdPthSteps.at(i);
if (idps.ptGe[0].distanceTo(ptEnd) < m_dSpaceTol ||
idps.ptGe[1].distanceTo(ptEnd) < m_dSpaceTol )
{
nPt += 1;
continue;
}
}
if (nPt > 2) return true;
return false;
}
bool CCableRouting::GoOnRaceWay(CableRoutePath *pRd,const AcGePoint3d& ptToEntry, const AcGePoint3d& ptTo,const CableData &data, AcArray<CableRoutePath *>& arRoadAxLnPtrs)
{
if (pRd == NULL) return false;
//0.是一条成功路径,不继续
Adesk::UInt16 nColorIndex = pRd->colorIndex();
if (nColorIndex == kRed)
return false;
AcGePoint3d ptEnd, ptExit;
pRd->getEndPoint(ptEnd);
//1.是否接近出口,下高速
if (IsNearToEndEntry(pRd, ptToEntry) )
{
AddLPath(pRd, ptToEntry, ptTo);
pRd->setColorIndex(kRed);
return true;
}
//2.是否接近中间的预埋路径
if (GoOnLockPath(pRd))
{
pRd->getEndPoint(ptEnd);
//2.1是否接近出口,下高速
if (IsNearToEndEntry(pRd, ptToEntry))
{
AddLPath(pRd, ptToEntry, ptTo);
pRd->setColorIndex(kRed);
return true;
}
}
//3.高速公路继续前进...
bool bFindPos = false;
AcArray<CableRoutePath *> arNewRd;
AcDbLine *pLn = NULL;
//TEST
CableRoutePath *pRdNew = NULL;
CableRoutePath *pRdGet = NULL;
for (int i = 0; i < m_arIdPthSteps.length(); i++)
{
idPathStep& idps = m_arIdPthSteps.at(i);
//禁止回溯
if (idps.bSteped || pRd->HasLineSeg(idps))
{
continue;
}
//if (idps.ptGe[0].distanceTo(ptEnd) < m_dSpaceTol)
if (IsPointDockPathStep(pRd,ptEnd,idps,0 ) )//起点相接
{
//如果有高速引出口满足到设备距离
if (IsGoRacewayExit(ptEnd,idps,ptExit,ptToEntry))
{
pRdGet = new CableRoutePath;
pRdGet->copyFrom(pRd);
arRoadAxLnPtrs.append(pRdGet);
AcDbLine *pLn = new AcDbLine(ptEnd, ptExit);
pRdGet->AppendCurveSeg(pLn, idps.id,idps.dSize,idps.szPathNo);
AddLPath(pRdGet, ptExit, ptTo, 1,idps.szPathNo);
//确认一条路径,不再找下一个出口 ?
pRdGet->setColorIndex(kRed);
//原来的路径继续找
idps.bSteped = true;
//pRd 继续
i = -1;
continue;
}
//产生分支点
if (Has2Way(ptEnd))
{
idps.bSteped = true;//避开此段
pRdNew = new CableRoutePath;
pRdNew->copyFrom(pRd);
arRoadAxLnPtrs.append(pRdNew);
GoOnRaceWay(pRdNew, ptToEntry, ptTo, data, arRoadAxLnPtrs);
}
//步行一段
idps.bSteped = true;//避开此段
pLn = new AcDbLine(ptEnd, idps.ptGe[1]);//End点
pRd->AppendCurveSeg(pLn, idps.id, idps.dSize,idps.szPathNo);
pRd->getEndPoint(ptEnd);
//找桥架间预埋路径
GoOnLockPath(pRd);
if (IsNearToEndEntry(pRd, ptToEntry))
{
pRdGet = new CableRoutePath;
pRdGet->copyFrom(pRd);
pRdGet->setColorIndex(kRed);//一条路径
arRoadAxLnPtrs.append(pRdGet);
AddLPath(pRdGet, ptToEntry, ptTo,1, idps.szPathNo);
//原来的路径继续找
idps.bSteped = true;
return GoOnRaceWay(pRd, ptToEntry, ptTo, data, arRoadAxLnPtrs);
break;
}
else
{
return GoOnRaceWay(pRd, ptToEntry, ptTo, data, arRoadAxLnPtrs);
break;
}
}
//if (idps.ptGe[1].distanceTo(ptEnd) < m_dSpaceTol)
if (IsPointDockPathStep(pRd,ptEnd,idps, 1) )
{
//如果有高速引出口满足到设备距离
if (IsGoRacewayExit(ptEnd, idps, ptExit, ptToEntry))
{
pRdGet = new CableRoutePath;
pRdGet->copyFrom(pRd);
arRoadAxLnPtrs.append(pRdGet);
AcDbLine *pLn = new AcDbLine(ptEnd, ptExit);
pRdGet->AppendCurveSeg(pLn, idps.id, idps.dSize, idps.szPathNo);
AddLPath(pRdGet, ptExit, ptTo,1, idps.szPathNo);
//确认一条路径,不再找下一个出口 ?
pRdGet->setColorIndex(kRed);
//idps.bSteped = true;
idps.bSteped = true;
return GoOnRaceWay(pRd, ptToEntry, ptTo, data, arRoadAxLnPtrs);
break;
}
//产生分支点
if (Has2Way(ptEnd))
{
idps.bSteped = true;//避开此段
pRdNew = new CableRoutePath;
pRdNew->copyFrom(pRd);
arRoadAxLnPtrs.append(pRdNew);
GoOnRaceWay(pRdNew, ptToEntry, ptTo, data, arRoadAxLnPtrs);
}
//步行一段
idps.bSteped = true;//避开此段
pLn = new AcDbLine(ptEnd, idps.ptGe[0]);//Sta点
pRd->AppendCurveSeg(pLn, idps.id, idps.dSize, idps.szPathNo);
pRd->getEndPoint(ptEnd);
//找桥架间预埋路径
GoOnLockPath(pRd);
if (IsNearToEndEntry(pRd, ptToEntry))
{
double dSize[3];
memset(dSize, 0, sizeof(double) * 3);
pRdGet = new CableRoutePath;
pRdGet->copyFrom(pRd);
pRdGet->setColorIndex(kRed);//一条路径
arRoadAxLnPtrs.append(pRdGet);
AddLPath(pRdGet, ptToEntry, ptTo,1, idps.szPathNo);
idps.bSteped = true;
return GoOnRaceWay(pRd, ptToEntry, ptTo, data, arRoadAxLnPtrs);
break;
}
else
{
return GoOnRaceWay(pRd, ptToEntry, ptTo, data, arRoadAxLnPtrs);
break;
}
}
}
nColorIndex = pRd->colorIndex();
if (nColorIndex == kRed)
return true;
return false;
}
// 1. 强电优先路径 通过清册顺序!
// 2. 强电 弱电避开 通过桥架设置避开
// 3. 桥架填充率 + 已用路径 填埋电缆属性 !
// 4. 所有路径以颜色 和 属性 显示 可选路径
// 5. 敷设设置界面!电缆等级 避让 填充率 等
// 6. 锁定电缆经过的 路径!
bool CCableRouting::GetEntryPath(const AcGePoint3d& ptFrEntry, const CableData &data, AcArray<CableRoutePath *>& arRoadAxLnPtrs)
{
//1.从桥架和电缆沟找到最近的 head
double dMinDis = m_dMaxextDis;
CPoint ptFind;
ptFind.x = -1; ptFind.y = -1;
bool bFindHead = false;
AcDbLine *pLn = NULL;
if (!bFindHead)
{
bool bFindHeadFrSta = false;
bool bFindHeadFrEnd = false;
ptFind.x = -1; ptFind.y = -1;
double dMinDisSta = m_dMaxextDis;
double dMinDisEnd = m_dMaxextDis;
for (int i = 0; i < m_arIdPathBy.length(); i++)
{
idPathStep &ips = m_arIdPathBy.at(i);
if (ips.ptGe[0].distanceTo(ptFrEntry) < dMinDisSta)
{
dMinDisSta = ips.ptGe[0].distanceTo(ptFrEntry);
ptFind.x = i;
bFindHeadFrSta = true;
break;
}
if (ips.ptGe[ips.nPoints - 1].distanceTo(ptFrEntry) < dMinDisEnd)
{
dMinDisEnd = ips.ptGe[ips.nPoints - 1].distanceTo(ptFrEntry);
ptFind.y = i;
bFindHeadFrEnd = true;
break;
}
}
if (bFindHeadFrSta)//3.1 sta 接入
{
CableRoutePath *pRd = new CableRoutePath;
pRd->SetCableData(data);
pRd->setColorIndex(kWhite);
arRoadAxLnPtrs.append(pRd);
idPathStep ips = m_arIdPathBy.at(ptFind.x);
pLn = new AcDbLine(ptFrEntry, ips.ptGe[1]);
pRd->AppendCurveSeg(pLn, ips.id,ips.dSize);
//m_arIdPathBy.removeAt(ptFind.x);
for (int j = 0;j < m_arIdPathBy.length();j++)
{
idPathStep ips2 = m_arIdPathBy.at(j);
pRd->getEndPoint(ips.ptGe[0]);
//if (pRd->HasLineSeg(ips2))
//{
// continue;
//}
if (ips2.ptGe[0].distanceTo(ips.ptGe[0]) < 1.e-1)
{
if (!pRd->HasLineSeg(ips.ptGe[0], ips2.ptGe[1]))
{
pLn = new AcDbLine(ips.ptGe[0], ips2.ptGe[1]);
pRd->AppendCurveSeg(pLn, ips.id,ips.dSize);
}
//m_arIdPathBy.removeAt(j);
//j = -1;
}
if (ips2.ptGe[1].distanceTo(ips.ptGe[0]) < 1.e-1)
{
if (!pRd->HasLineSeg(ips.ptGe[0], ips2.ptGe[0]))
{
pLn = new AcDbLine(ips.ptGe[0], ips2.ptGe[0]);
pRd->AppendCurveSeg(pLn, ips.id,ips.dSize);
}
//m_arIdPathBy.removeAt(j);
//j = -1;
}
}
bFindHead = true;
}
else if (bFindHeadFrEnd) //3.2 end接入
{
CableRoutePath *pRd = new CableRoutePath;
pRd->SetCableData(data);
pRd->setColorIndex(kWhite);
arRoadAxLnPtrs.append(pRd);
idPathStep ips = m_arIdPathBy.at(ptFind.y);
pLn = new AcDbLine(ptFrEntry, ips.ptGe[0]);
pRd->AppendCurveSeg(pLn, ips.id,ips.dSize);
//m_arIdPathBy.removeAt(ptFind.y);
for (int j = 0; j < m_arIdPathBy.length(); j++)
{
idPathStep ips2 = m_arIdPathBy.at(j);
////if (pRd->HasLineSeg(ips2))
//{
// continue;
//}
pRd->getEndPoint(ips.ptGe[0]);
if (ips2.ptGe[0].distanceTo(ips.ptGe[0]) < 1.e-1)
{
if (!pRd->HasLineSeg(ips.ptGe[0], ips2.ptGe[1]))
{
pLn = new AcDbLine(ips.ptGe[0], ips2.ptGe[1]);
pRd->AppendCurveSeg(pLn, ips.id,ips.dSize);
//m_arIdPathBy.removeAt(j);
//j = -1;
j = -1;//从头开始
}
}
if (ips2.ptGe[1].distanceTo(ips.ptGe[0]) < 1.e-1)
{
if (!pRd->HasLineSeg(ips.ptGe[0], ips2.ptGe[0]))
{
pLn = new AcDbLine(ips.ptGe[0], ips2.ptGe[0]);
pRd->AppendCurveSeg(pLn, ips.id,ips.dSize);
//m_arIdPathBy.removeAt(j);
//j = -1;
j = -1;//从头开始
}
}
}
bFindHead = true;
}
}
//3 从桥架路径找入口
if (!bFindHead)
{
for (int i = 0; i < m_arIdPthSteps.length(); i++)
{
idPathStep &idps = m_arIdPthSteps.at(i);
for (int j = 0; j < idps.nPoints; j++)
{
if (idps.ptGe[j].distanceTo(ptFrEntry) < dMinDis)//最大5米范围
{
bFindHead = true;
ptFind.x = i; ptFind.y = j;
dMinDis = idps.ptGe[j].distanceTo(ptFrEntry);
}
}
}
//找到桥架或电缆沟或套管的入口
if (bFindHead)
{
CableRoutePath *pRd = new CableRoutePath;
pRd->SetCableData(data);
pRd->setColorIndex(kWhite);
arRoadAxLnPtrs.append(pRd);
idPathStep &idps = m_arIdPthSteps.at(ptFind.x);
if (ptFind.y == 0)
{
AcGePoint3d ptFr = ptFrEntry;
for (int i = 1; i < idps.nPoints; i++)
{
if (!pRd->HasLineSeg(ptFr, idps.ptGe[i]))
{
pLn = new AcDbLine(ptFr, idps.ptGe[i]);
pRd->AppendCurveSeg(pLn, idps.id,idps.dSize);
ptFr = idps.ptGe[i];
}
}
}
else if (ptFind.y == idps.nPoints - 1)
{
AcGePoint3d ptFr = ptFrEntry;
for (int i = idps.nPoints - 2; i > 0; i--)
{
if (!pRd->HasLineSeg(ptFr, idps.ptGe[i]))
{
pLn = new AcDbLine(ptFr, idps.ptGe[i]);
pRd->AppendCurveSeg(pLn, idps.id,idps.dSize);
ptFr = idps.ptGe[i];
}
}
}
//m_arIdPthSteps.removeAt(ptFind.x);
}
}
return bFindHead;
}
bool CCableRouting::CalRoutingPath(const AcGePoint3d& ptFrEntry, const AcGePoint3d& ptToEntry, const AcGePoint3d &ptFr, const AcGePoint3d & ptTo, const CableData &data, AcArray<CableRoutePath *>& arRoadAxLnPtrs)
{
//找引线 或 最近 入口
bool bFindHead = GetEntryPath(ptFrEntry,data, arRoadAxLnPtrs);
if ( arRoadAxLnPtrs.isEmpty())
{
CableRoutePath *pRd = new CableRoutePath;
pRd->SetCableData(data);
pRd->setColorIndex(kWhite);
AddLPath(pRd, ptFr, ptFrEntry);
arRoadAxLnPtrs.append(pRd);
bFindHead = true;
}
else
{
//加入 L 路径
CableRoutePath *pRd = arRoadAxLnPtrs.first();
if (pRd->isEmpty())
{
pRd->SetCableData(data);
pRd->setColorIndex(kWhite);
AddLPath(pRd, ptFr, ptFrEntry,0);
bFindHead = true;
}
}
//从head开始
if (bFindHead)
{
//上高速-找出口路径
GoOnRaceWay(arRoadAxLnPtrs.first(),ptToEntry,ptTo, data, arRoadAxLnPtrs);
}
return !arRoadAxLnPtrs.isEmpty();
}
bool CCableRouting::SearchRouting(const AcDbObjectId &idFrom, const AcDbObjectId &idTo, CableData &data, int nPathUserPick, AcDbObjectId &idPath,CString& sPathSteps)
{
//...
// 1. 强电优先路径 通过清册顺序!
// 2. 弱电避开
// 3. 桥架填充率 + 已用路径 填埋电缆属性 !
// 4. 所有路径以颜色 和 属性 显示 可选路径
// 5. 敷设设置界面!电缆等级 避让 填充率 等
// 6. 锁定电缆经过的 路径!
//总算法思路
//设备附近->找到上高速的入口---高速----下高速出口---设备
PreGetAllLeadPorts();
AcGePoint3d ptFr, ptTo;
AcDbExtents extFr, extTo;
GetEquPowerPoint(idFrom, ptFr,extFr, data);
GetEquPowerPoint(idTo, ptTo,extTo, data);
//pt点附近找桥架,电缆套管,电缆沟的接入点
AcDbObjectId idEntryFr;
AcGePoint3d ptFrEntry;
if ( !FindEquCableEntryPoint(idFrom, ptFr, extFr,idEntryFr,ptFrEntry))
{
acutPrintf(_T("\n起点设备附近5米范围内没有找到接入设施(桥架、套管、电缆沟、路径)!"));
return false;
}
AcDbObjectId idEntryTo;
AcGePoint3d ptToEntry;
if (!FindEquCableEntryPoint(idTo, ptTo, extTo,idEntryTo, ptToEntry))
{
acutPrintf(_T("\n终点设备附近5米范围内没有找到接入设施(桥架、套管、电缆沟、路径)!"));
return false;
}
//获取绑定到设备的必经路径
PrepareLockPathData(idFrom, idTo,data);
//预埋路径
PreparePolyPathData(idFrom, idTo, data, false);
//考虑填充率,考虑填充率
PrepareSetPathStepData(data,false);
//TEST StepData
//TestPathStepData();
//搜索路径 ptFrEntry - ptToEntry;
//获取所有的ptFrEntry的分支路径,包括填充率 必经过的路径 必经过的点
AcArray<CableRoutePath *> ar3dRdAxLines;
CalRoutingPath(ptFrEntry, ptToEntry,ptFr,ptTo,data,ar3dRdAxLines);
//然后计算一条不考虑填充率的最短路径
AcArray<CableRoutePath *> ar3dRdAxLinesAll;
CableRoutePath *pMinLenRdBlue = NULL;
if (m_bIgoreFillUsed )
{
//预埋路径
m_arIdPathBy.removeAll();
PreparePolyPathData(idFrom, idTo, data, true);
//考虑填充率,考虑填充率
m_arIdPthSteps.removeAll();
PrepareSetPathStepData(data, true);
CalRoutingPath(ptFrEntry, ptToEntry, ptFr, ptTo, data, ar3dRdAxLinesAll);
pMinLenRdBlue = GetMinLenRdAxLine(ar3dRdAxLinesAll, ptFrEntry, ptToEntry, true);
if (pMinLenRdBlue != NULL)
{
pMinLenRdBlue->setColorIndex(kBlue);
}
}
//记录起点终点
TCHAR szFrEqu[33], szToEqu[33];
idFrom.handle().getIntoAsciiBuffer(szFrEqu);
idTo.handle().getIntoAsciiBuffer(szToEqu);
//测试所有路径
struct resbuf rb;
rb.resval.rint = 0;
acedGetVar(_T("useri3"), &rb);
if (rb.resval.rint == 1394)
{
TestPaths(ar3dRdAxLines,szFrEqu,szToEqu);
return idPath.isValid();
}
//测试最短两种路径 [容积率和非容积率]
if (nPathUserPick)// 用户选择 包括不考虑容积率的问题
{
RemoveInValidatePath(ar3dRdAxLines);
if (m_bIgoreFillUsed && pMinLenRdBlue != NULL)
{
ar3dRdAxLines.append(pMinLenRdBlue);
}
//弹出界面,用户查看所有路径 ar3dRdAxLinesAll
CAcModuleResourceOverride myResources;
CLJCKDlg dlg;
dlg.SetFrAndTo(szFrEqu, szToEqu);
dlg.SetarAllPath(ar3dRdAxLines);
dlg.DoModal();
CableRoutePath *pMinLenRdRed = dlg.m_pPathSel;
if (pMinLenRdRed != NULL)
{
idPath = pMinLenRdRed->GetRoadAxLineId();
if (idPath.isValid())
{
data.dLen = pMinLenRdRed->length();
pMinLenRdRed->GetPathSteps(sPathSteps);
pMinLenRdRed->CalSetFillUsed(data);
}
}
else
{
//考虑容积率 的最短
CableRoutePath *pMinLenRdRed = GetMinLenRdAxLine(ar3dRdAxLines, ptFrEntry, ptToEntry, true);
if (pMinLenRdRed != NULL)
{
pMinLenRdRed->Add2ModelSpace(szFrEqu,szToEqu);
idPath = pMinLenRdRed->GetRoadAxLineId();
if (idPath.isValid())
{
data.dLen = pMinLenRdRed->length();
pMinLenRdRed->GetPathSteps(sPathSteps);
pMinLenRdRed->CalSetFillUsed(data);
}
delete pMinLenRdRed;
}
}
}
else
{
CableRoutePath *pMinLenRdRed = GetMinLenRdAxLine(ar3dRdAxLines, ptFrEntry, ptToEntry, true);
if (pMinLenRdRed != NULL)
{
pMinLenRdRed->Add2ModelSpace(szFrEqu, szToEqu);
idPath = pMinLenRdRed->GetRoadAxLineId();
if (idPath.isValid())
{
data.dLen = pMinLenRdRed->length();
pMinLenRdRed->GetPathSteps(sPathSteps);
pMinLenRdRed->CalSetFillUsed(data);
}
delete pMinLenRdRed;
}
}
return idPath.isValid();
}
void CCableRouting::TestPaths(AcArray<CableRoutePath *> & ar3dRdAxLines,LPCTSTR pszFr,LPCTSTR pszTo)
{
AecDb3dRoadAxisLine *pARd = NULL;
CableRoutePath *pRd = NULL;
for (int i = 0; i < ar3dRdAxLines.length(); i++)
{
pRd = (CableRoutePath *)ar3dRdAxLines.at(i);
pRd->Add2ModelSpace(pszFr, pszTo);
}
}
typedef struct RoadAxLineLen
{
CableRoutePath *pRd;
double dLen;
}ROADAXLINELEN;
static bool SortRdAxLnLens(const RoadAxLineLen &rd1, const RoadAxLineLen &rd2)
{
return (rd1.dLen < rd2.dLen) ? true : false;
}
//取最短路径,同时清理无效路径,然后有效路径排序
CableRoutePath * CCableRouting::GetMinLenRdAxLine(AcArray<CableRoutePath *> & ar3dRdAxLines, AcGePoint3d& ptFrEntry, AcGePoint3d & ptToEntry,bool bDelete)
{
double dLen = 0.0, dMinLen = 1.e10;
RoadAxLineLen rdlen;
std::vector<RoadAxLineLen> vtRdAxLns;
Adesk::UInt16 nColorIndex = 0;
CableRoutePath *pMinRd = NULL;
CableRoutePath *pRd = NULL;
AcGePoint3d ptS, ptE;
for (int i = 0;i < ar3dRdAxLines.length();i++)
{
pRd = ar3dRdAxLines.at(i);
dLen = pRd->length();
if (dLen < 1.e-1)
{
ar3dRdAxLines.removeAt(i);
i -= 1;
delete pRd;
continue;
}
pRd->getStartPoint(ptS);
pRd->getEndPoint(ptE);
//起始端连上 起始设备 判断速度慢
/*if (ptS.distanceTo(ptFrEntry) < 1.0 && ptE.distanceTo(ptToEntry) < 1.0)
{
//如果有锁定路径
if (!pRd->IsPassByLockPath(m_arIdsPassBy))
{
continue;
}
pRd->setColorIndex(kRed);
if (!bDelete)
{
rdlen.dLen = dLen;
rdlen.pRd = pRd;
vtRdAxLns.push_back(rdlen);
}
if (dLen < dMinLen)
{
dMinLen = dLen;
pMinRd = pRd;
}
}
else
{
//
ar3dRdAxLines.removeAt(i);
i -= 1;
delete pRd;
}*/
nColorIndex = pRd->colorIndex();
if (nColorIndex == kRed )
{
//如果有锁定路径
if (!pRd->IsPassByLockPath(m_arIdsPassBy))
{
continue;
}
if (!bDelete)
{
rdlen.dLen = dLen;
rdlen.pRd = pRd;
vtRdAxLns.push_back(rdlen);
}
if (dLen < dMinLen)
{
dMinLen = dLen;
pMinRd = pRd;
}
}
else
{
//
ar3dRdAxLines.removeAt(i);
i -= 1;
delete pRd;
}
}
if (bDelete)
{
//清空
for (int i = 0; i < ar3dRdAxLines.length(); i++)
{
pRd = (CableRoutePath *)ar3dRdAxLines.at(i);
if (pMinRd != pRd)
delete pRd;
}
}
else
{
//排序
std::sort(vtRdAxLns.begin(), vtRdAxLns.end(), SortRdAxLnLens);
}
return pMinRd;
}
void CCableRouting::RemoveInValidatePath(AcArray<CableRoutePath *> &ar3dRdAxLines)
{
Adesk::UInt16 nColorIndex = 0;
CableRoutePath *pRd = NULL;
for (int i = 0; i < ar3dRdAxLines.length(); i++)
{
pRd = ar3dRdAxLines.at(i);
nColorIndex = pRd->colorIndex();
if (nColorIndex != kRed)
{
ar3dRdAxLines.removeAt(i);
i -= 1;
delete pRd;
}
}
}
//0,1 第一层 2 第二层
int CCableRouting::GetCableLayPos(const CableData &data, AecHvac::DuctParam &param)
{
if (!param.m_bSpart)
return 0;
CString sSysD = data.szSys;
CString sSys1, sSys2 = _T("-"), sSyss;
sSyss = param.szSys;
int nPos = sSyss.Find(_T('|'), 0);
if (nPos != -1)
{
sSys1 = sSyss.Mid(0, nPos);
if (nPos < sSyss.GetLength() - 1)
sSys2 = sSyss.Mid(nPos + 1);
}
else
{
sSys1 = sSyss;
}
AecHvac::DuctParam param2;
_tcscpy(param2.szSys, sSys1);
if (IsSameAsSysUse(data, param2))
{
_tcscpy(param.szSys, sSys1);
return 1;
}
_tcscpy(param2.szSys, sSys2);
if (IsSameAsSysUse(data, param2))
{
_tcscpy(param.szSys, sSys2);
return 2;
}
return -1;
}
static void AddCirTrace(const AcGePoint3d& ptS)
{
struct resbuf rb;
rb.resval.rint = 0;
acedGetVar(_T("useri3"), &rb);
if (rb.resval.rint == 1395)
{
AcDbCircle *pCir = new AcDbCircle;
pCir->setCenter(ptS);
pCir->setRadius(100.0);
pCir->setNormal(AcGeVector3d::kZAxis);
pCir->setColorIndex(1);
CoreTools::AddToModelSpace(pCir);
}
}
void CCableRouting::AddCableTrayStps(const CableData &data,const AcGePoint3d& ptS, const AcGePoint3d &ptE,AecHvac::DuctParam& param,AcDbObjectId& id, bool bIgoreFillUsed)
{
CString sType;
double dSCab = PI * 0.25 * data.dD * data.dD;
struct resbuf rb;
acedGetVar(_T("INSUNITS"), &rb);
if (rb.resval.rint == AcDb::kUnitsMeters)
{
dSCab *= 1.e-6;
}
TCHAR szHd[17];
_tcscpy(szHd, _T(""));
//id.handle().getIntoAsciiBuffer(szHd);
idPathStep idp;
memset(&idp, 0, sizeof(idPathStep));
if (bIgoreFillUsed)//不考虑填充率
{
idp.bUseFillUsed = false;
idp.nPoints = 2;
idp.dSize[0] = param.dSize[0];
idp.dSize[1] = param.dSize[1];
idp.id = id;
idp.ptGe[0] = ptS;
idp.ptGe[1] = ptE;
_tcscpy(idp.szSys, param.szSys);
_tcscpy(idp.szPathNo, szHd);
_tcscpy(idp.szNo, param.szNo);
idp.bSteped = false;
m_arIdPthSteps.append(idp);
}
else
{
if (param.m_bSpart) //分层
{
//获取电缆铺设的位置
int nLayUD = GetCableLayPos(data, param);
if (nLayUD == 0 || nLayUD == 1)
{
param.dSize[0] = param.dSize[4];//LeftW
idp.dFillUsed = param.m_dFillUsed;
if (idp.dFillUsed < param.m_dFullPer * 0.01)//在桥架的填充率要求内 100
{
double dS = param.dSize[0] * param.dSize[1];
double dS2 = dSCab + idp.dFillUsed * dS;
dS2 /= dS;
if (dS2 < param.m_dFullPer * 0.01)//在加入之后的填充率要求内
{
idp.bUseFillUsed = true;
idp.nPoints = 2;
idp.dSize[0] = param.dSize[0];
idp.dSize[1] = param.dSize[1];
idp.id = id;
idp.ptGe[0] = ptS;
idp.ptGe[1] = ptE;
_tcscpy(idp.szSys, param.szSys);
_tcscpy(idp.szPathNo, szHd);
_tcscpy(idp.szNo, param.szNo);
idp.bSteped = false;
m_arIdPthSteps.append(idp);
}
else
{
id.handle().getIntoAsciiBuffer(szHd);
acutPrintf(_T("\n发现桥架填充率已经用满!句柄 = %s id=%I64u"), szHd, id.asOldId());
AddCirTrace(ptS);
}
}
}
if (nLayUD == 2)
{
param.dSize[0] -= param.dSize[4];//dLeft
idp.dFillUsed = param.m_dFillUsed2;
if (idp.dFillUsed < param.m_dFullPer2 * 0.01)//在桥架的填充率要求内
{
double dS = param.dSize[0] * param.dSize[1];
double dS2 = dSCab + idp.dFillUsed * dS;
dS2 /= dS;
if (dS2 < param.m_dFullPer2 * 0.01)//在加入之后的填充率要求内
{
idp.bUseFillUsed = true;
idp.nPoints = 2;
idp.dSize[0] = param.dSize[0];
idp.dSize[1] = param.dSize[1];
idp.id = id;
idp.ptGe[0] = ptS;
idp.ptGe[1] = ptE;
_tcscpy(idp.szSys, param.szSys);
_tcscpy(idp.szPathNo, szHd);
_tcscpy(idp.szNo, param.szNo);
idp.bSteped = false;
m_arIdPthSteps.append(idp);
}
else
{
id.handle().getIntoAsciiBuffer(szHd);
acutPrintf(_T("\n发现桥架填充率已经用满!句柄 = %s id=%I64u"), szHd,id.asOldId());
AddCirTrace(ptS);
}
}
}
}
else //不分层
{
//idp.dFillUsed 即将的填充率
idp.dFillUsed = param.m_dFillUsed;
if (data.dD < param.dSize[0] &&
data.dD < param.dSize[1]) //保证桥架WxH能放下本电缆
{
//sType = param.szType;
//槽式;托盘式;梯架式 是否容积率计算一样
if (idp.dFillUsed < param.m_dFullPer * 0.01)//在桥架的填充率要求内
{
double dS = param.dSize[0] * param.dSize[1];
double dS2 = dSCab + idp.dFillUsed * dS;
dS2 /= dS;
if (dS2 < param.m_dFullPer * 0.01)//在加入之后的填充率要求内
{
idp.bUseFillUsed = true;
idp.nPoints = 2;
idp.dSize[0] = param.dSize[0];
idp.dSize[1] = param.dSize[1];
idp.id = id;
idp.ptGe[0] = ptS;
idp.ptGe[1] = ptE;
_tcscpy(idp.szSys, param.szSys);
_tcscpy(idp.szPathNo, szHd);
_tcscpy(idp.szNo, param.szNo);
idp.bSteped = false;
m_arIdPthSteps.append(idp);
}
else
{
id.handle().getIntoAsciiBuffer(szHd);
acutPrintf(_T("\n发现桥架填充率已经用满!句柄 = %s id=%I64u"), szHd,id.asOldId());
AddCirTrace(ptS);
}
}
}
}
}
}
static bool SortInfuPoint(AecUserInterface& fr, AecUserInterface& la)
{
if (fr.ptGe[fr.nPoints].z < la.ptGe[la.nPoints].z)
return true;//升序
return false;//降序
}
static void SortUserInterface(std::vector< AecUserInterface>& arInfus, const AcGePoint3d& pt1, const AcGePoint3d& pt2)
{
AcDbLine ln(pt1, pt2);
for (int i = 0;i < arInfus.size();i++)
{
AecUserInterface &infu = arInfus.at(i);
//infu.nPoints < 16 !!! 用户接口只支持矩形和圆行,所以 infu.nPoints 最多4个点
//预留的空间足够
infu.ptGe[infu.nPoints].z = 0;
ln.getClosestPointTo(infu.ptGe[0], infu.ptGe[infu.nPoints], Adesk::kTrue);
ln.getParamAtPoint(infu.ptGe[infu.nPoints], infu.ptGe[infu.nPoints].z);
}
std::sort(arInfus.begin(),arInfus.end(), SortInfuPoint);
}
static AcGePoint3d GetInfuPoint(AecUserInterface& infu)
{
if (infu.nPoints == 2)
{
return infu.ptGe[0];
}
else
{
return MidPoint(infu.ptGe[0], infu.ptGe[2]);
}
}
static AcGePoint3d GetInfuPointTo(AecUserInterface& infu)
{
AcGePoint3d ptTo = GetInfuPoint(infu);
ptTo += infu.vtDir;
return ptTo;
}
static void GetInfuParam(AecHvac::DuctParam& param, AecUserInterface & infu)
{
if (infu.nPoints == 2)
{
param.dSize[0] = 2.0 * infu.ptGe[0].distanceTo(infu.ptGe[1]);
param.eType = eCircle;
}
else
{
param.dSize[0] = infu.ptGe[0].distanceTo(infu.ptGe[1]);
param.dSize[1] = infu.ptGe[1].distanceTo(infu.ptGe[2]);
param.eType = eRect;
}
_tcscpy(param.szSys, infu.szSys);
_tcscpy(param.szNo, infu.szNo);
}
void CCableRouting::PreGetAllLeadPorts()
{
m_arIdEquTerminal.removeAll();
m_arRaceWayExit.removeAll();
//3.接线点
ads_name ss, ent;
struct resbuf* pRb1 = acutBuildList(RTDXF0, DXF_DIRPS, 0);
int nRes = acedSSGet(_T("A"), NULL, NULL, pRb1, ss);
acutRelRb(pRb1);
Adesk::Int32 nLen = 0;
AcDbObjectId id;
AcDbEntity *pEnt = NULL;
bool bIsEqu = false;
idLeadPort lpt;
memset(&lpt, 0, sizeof(idLeadPort));
if (nRes == RTNORM)
{
CString sSys = _T(""), sEqu = _T("");
acedSSLength(ss, &nLen);
for (int i = 0; i < nLen; i++)
{
acedSSName(ss, i, ent);
acdbGetObjectId(id, ent);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead))
{
AecDbDirPosition *pDirPos = AecDbDirPosition::cast(pEnt);
if (pDirPos != NULL)
{
sSys = _T(""), sEqu = _T("");
lpt.m_ptPos = pDirPos->GetPosition();
pDirPos->GetSys(sSys);
pDirPos->GetOnEqu(sEqu);
bIsEqu = pDirPos->IsEqu();
_tcscpy(lpt.szSys, (LPCTSTR)sSys);
_tcscpy(lpt.szEquOn, (LPCTSTR)sEqu);
_tcscpy(lpt.szHd, pDirPos->GetAssocEnt());
if (bIsEqu)//设备引出口
{
m_arIdEquTerminal.append(lpt);
}
else//桥架引出口
{
m_arRaceWayExit.append(lpt);
}
}
pEnt->close();
}
}
acedSSFree(ss);
}
}
static void ReadLockPath(const AcDbObjectId &id, CStringList& lstHds)
{
AcDbEntity *pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead))
{
AecDbObjXDataMap xData;
xData.Read(pEnt, KEY_LOCKPATH);
AecDbObjXDataMap::It it = xData.Begin();
AecDbObjXDataMap::It end = xData.End();
CString sKey;
AecXData cVal;
memset(&cVal, 0, sizeof(AecXData));
for (; it != end; )
{
if (!xData.GetNext(it, sKey, cVal))
break;
if (lstHds.Find(sKey) == NULL)
lstHds.AddTail(sKey);
}
pEnt->close();
}
}
void CCableRouting::PrepareLockPathData(const AcDbObjectId &idFrom, const AcDbObjectId &idTo, const CableData &data)
{
CStringList lstHds1, lstHds2;
ReadLockPath(idFrom, lstHds1);
ReadLockPath(idTo, lstHds2);
m_arIdsPassBy.removeAll();
AcDbObjectId id;
AcDbDatabase *pDb = acdbCurDwg();
//共有
CString sVal;
for (POSITION ps = lstHds1.GetHeadPosition();ps != NULL;)
{
sVal = lstHds1.GetNext(ps);
if (lstHds2.Find(sVal) != NULL)
{
AcDbHandle hd(sVal);
if (Acad::eOk == pDb->getAcDbObjectId(id, false, hd) )
{
m_arIdsPassBy.append(id);
}
}
}
}
void CCableRouting::PreparePolyPathData(const AcDbObjectId &idFrom, const AcDbObjectId &idTo, const CableData &data, bool bIgoreFillUsed /*= false*/)
{
m_arIdPathBy.removeAll();
Adesk::Int32 nLen = 0;
ads_name ss, ent;
AcDbObjectId id;
AcDbEntity *pEnt = NULL;
idPathStep idp;
idp.bIsPtPassby = false;
//2.预埋地下的路径线
idp.bIsLockPath = true;
idp.bUseFillUsed = false;
idp.bIsPtPassby = false;
idp.nPoints = 2;
idp.dFillUsed = 0;
idp.dSize[0] = 0;
idp.dSize[1] = 0;
_tcscpy(idp.szNo, _T(""));
_tcscpy(idp.szPathNo, _T(""));
_tcscpy(idp.szSys, _T(""));
TCHAR szFrEqu[17], szToEqu[17];
memset(szFrEqu, 0, sizeof(TCHAR) * 17);
memset(szToEqu, 0, sizeof(TCHAR) * 17);
idFrom.handle().getIntoAsciiBuffer(szFrEqu);
idTo.handle().getIntoAsciiBuffer(szToEqu);
CString sKey;
sKey.Format(_T("%s-%s"), szFrEqu, szToEqu);
struct resbuf* pRb1 = acutBuildList(RTDXF0, DXF_PATH, 0);
int nRes = acedSSGet(_T("A"), NULL, NULL, pRb1, ss);
acutRelRb(pRb1);
AcDbObjectId idLayCable = KTSetting::InitLayer(_T("LAY_CABLE"), true);
if (nRes == RTNORM)
{
acedSSLength(ss, &nLen);
for (int i = 0; i < nLen; i++)
{
acedSSName(ss, i, ent);
acdbGetObjectId(id, ent);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead))
{
AecDbObjXDataMap xMap;
if (xMap.Read(pEnt, KEY_POLYPATH))
{
if (xMap.HasKey(sKey, nRes))
{
id.handle().getIntoAsciiBuffer(idp.szPathNo);
AcDbLine *pLn = AcDbLine::cast(pEnt);
if (pLn != NULL)
{
idp.id = id;
idp.ptGe[0] = pLn->startPoint();
idp.ptGe[1] = pLn->endPoint();
m_arIdPathBy.append(idp);
}
AcDbPolyline *pPl = AcDbPolyline::cast(pEnt);
if (pPl != NULL)
{
idp.id = id;
for (int j = 0; j < pPl->numVerts() - 1; j++)
{
pPl->getPointAt(j, idp.ptGe[0]);
pPl->getPointAt(j + 1, idp.ptGe[1]);
m_arIdPathBy.append(idp);
}
}
}
}
AecDb3dRoadAxisLine *pRdAxLn = AecDb3dRoadAxisLine::cast(pEnt);
if (pRdAxLn != NULL)
{
if (idLayCable != pRdAxLn->layerId())//不是电缆
{
id.handle().getIntoAsciiBuffer(idp.szPathNo);
AcGePoint3dArray arPts;
pRdAxLn->ConvertTo3dPline(arPts);
idp.id = id;
//一段 --- 一段 记录
for (int j = 0; j < arPts.length() - 1; j++)
{
idp.ptGe[0] = arPts.at(j);
idp.ptGe[1] = arPts.at(j + 1);
m_arIdPathBy.append(idp);
}
}
}
AecDbEwFlexiblePipe *pFPipe = AecDbEwFlexiblePipe::cast(pEnt);
if (pFPipe != NULL)
{
if (idLayCable != pFPipe->layerId())//不是电缆
{
id.handle().getIntoAsciiBuffer(idp.szPathNo);
AcDbCurve * pBaseCr = pFPipe->GetNativeCurve();
if (pBaseCr != NULL)
{
pRdAxLn = AecDb3dRoadAxisLine::cast(pBaseCr);
if (pRdAxLn != NULL)
{
AcGePoint3dArray arPts;
pRdAxLn->ConvertTo3dPline(arPts);
idp.id = id;
//一段 --- 一段 记录
for (int j = 0; j < arPts.length() - 1; j++)
{
idp.ptGe[0] = arPts.at(j);
idp.ptGe[1] = arPts.at(j + 1);
m_arIdPathBy.append(idp);
}
}
AcDbPolyline *pPl = AcDbPolyline::cast(pBaseCr);
if (pPl != NULL)
{
idp.id = id;
for (int j = 0; j < pPl->numVerts() - 1; j++)
{
pPl->getPointAt(j, idp.ptGe[0]);
pPl->getPointAt(j + 1, idp.ptGe[1]);
m_arIdPathBy.append(idp);
}
}
}
}
}
pEnt->close();
}
}
acedSSFree(ss);
}
}
void CCableRouting::PrepareSetPathStepData(const CableData &data, bool bIgoreFillUsed /*= false*/)
{
m_arIdPthSteps.removeAll();
//准备所有的路径数据,便于后面迭代用到
//1.选择所有的桥架、线套管
struct resbuf *pRb1 = acutBuildList(RTDXF0, _T("AEC_DBCABTRY,AEC_DBECFIT,AEC_EWFPIPE"), 0);
Adesk::Int32 nLen = 0;
ads_name ss, ent;
AcDbObjectId id;
AcDbEntity *pEnt = NULL;
idPathStep idp;
_tcscpy(idp.szSys, _T(""));
_tcscpy(idp.szPathNo, _T(""));
_tcscpy(idp.szNo, _T(""));
idp.bIsPtPassby = false;
double dSCab = PI * 0.25 * data.dD * data.dD;
struct resbuf rb;
acedGetVar(_T("INSUNITS"), &rb);
if (rb.resval.rint == AcDb::kUnitsMeters)
{
dSCab *= 1.e-6;
}
double dS = 0.0,dS2 = 0.0;
int nRes = acedSSGet(_T("X"), NULL, NULL, pRb1, ss);
acutRelRb(pRb1);
if (nRes == RTNORM)
{
acedSSLength(ss, &nLen);
AecHvac::DuctParam param,param2;
DlgData dlgDat;
double dOD = 0.0, dt = 0.0;
int nLayUD = -1;
AecMInterfaces *pInf = NULL;
AecInterface inf;
AcGePoint3d ptMid;
idp.bIsLockPath = false;
TCHAR szHd[17];
CString sTmp;
for (int i = 0; i < nLen; i++)
{
acedSSName(ss, i, ent);
acdbGetObjectId(id, ent);
id.handle().getIntoAsciiBuffer(szHd);
_tcscpy(idp.szPathNo, szHd);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead))
{
pInf = NULL;
AecDbECableTray *pTray = AecDbECableTray::cast(pEnt);
if (pTray != NULL)
{
pInf = static_cast<AecMInterfaces *>(pTray);
memset(&dlgDat, 0, sizeof(DlgData));
if (pTray->GetDlgData(dlgDat))//电缆沟
{
idp.bUseFillUsed = false;
idp.nPoints = 2;
idp.dFillUsed = 0;
idp.dSize[0] = dlgDat.m_dW;
idp.dSize[1] = dlgDat.m_dH;
idp.id = id;
idp.ptGe[0] = pTray->StartPoint();
idp.ptGe[1] = pTray->EndPoint();
_tcscpy(idp.szSys, _T(""));
_tcscpy(idp.szPathNo, szHd);
_tcscpy(idp.szNo, dlgDat.m_szNo);
idp.bSteped = false;
m_arIdPthSteps.append(idp);
}
else
{
//确认桥架可以走此data系统
//判断字符串有共同的字符串
memset(&param, 0, sizeof(AecHvac::DuctParam));
pTray->GetDuctParam(param);
if (!IsSameAsSysUse(data, param))
{
//不同系统分类
pEnt->close();
continue;
}
//排序
int nUInfs = pTray->GetUserInterfaceCount();
if (nUInfs == 0)
{
AddCableTrayStps(data, pTray->StartPoint(), pTray->EndPoint(), param, id, bIgoreFillUsed);
}
else
{
AecUserInterface infu, infu0;
std::vector< AecUserInterface> arInfus;
for (int n = 0; n < nUInfs; n++)
{
pTray->GetUserInterface(n, infu);
arInfus.push_back(infu);
}
SortUserInterface(arInfus, pTray->StartPoint(), pTray->EndPoint());
for (int n = 0; n < arInfus.size(); n++)
{
infu = arInfus.at(n);
if (n == 0)
{
AddCableTrayStps(data, pTray->StartPoint(), GetInfuPoint(infu) , param, id, bIgoreFillUsed);
memcpy(&param2, &param, sizeof(AecHvac::DuctParam));
param2.m_bSpart = 0;
GetInfuParam(param2, infu);
AddCableTrayStps(data, GetInfuPoint(infu), GetInfuPointTo(infu), param2, id, bIgoreFillUsed);
}
else if (n == arInfus.size() - 1)
{
memcpy(&param2, &param, sizeof(AecHvac::DuctParam));
param2.m_bSpart = 0;
GetInfuParam(param2, infu);
AddCableTrayStps(data, GetInfuPoint(infu), GetInfuPointTo(infu), param2, id, bIgoreFillUsed);
AddCableTrayStps(data, GetInfuPoint(infu), pTray->EndPoint(), param, id, bIgoreFillUsed);
}
else
{
infu0 = arInfus.at(n-1);
memcpy(&param2, &param, sizeof(AecHvac::DuctParam));
param2.m_bSpart = 0;
GetInfuParam(param2, infu);
AddCableTrayStps(data, GetInfuPoint(infu0), GetInfuPoint(infu), param, id, bIgoreFillUsed);
AddCableTrayStps(data, GetInfuPoint(infu), GetInfuPointTo(infu), param2, id, bIgoreFillUsed);
}
}
}
}
}
AecDbEcFitting *pEcFit = AecDbEcFitting::cast(pEnt);
if (pEcFit != NULL)
{
pInf = static_cast<AecMInterfaces *>(pEcFit);
memset(&dlgDat, 0, sizeof(DlgData));
if (pEcFit->GetDlgData(dlgDat))//电缆沟
{
idp.bUseFillUsed = false;
idp.dFillUsed = 0;
idp.dSize[0] = dlgDat.m_dW;
idp.dSize[1] = dlgDat.m_dH;
idp.id = id;
idp.nPoints = 2;
_tcscpy(idp.szNo, dlgDat.m_szNo);
pEcFit->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_MID, ptMid);
if (pInf != NULL)
{
idp.nPoints = 2;
for (int j = 0; j < pInf->GetInterfaceCount(); j++)
{
pInf->GetInterface(j, inf);
idp.ptGe[0] = inf.ptPos;
idp.ptGe[1] = ptMid;
sTmp.Format(_T("%s-%d"),szHd,j+1);
_tcscpy(idp.szPathNo, sTmp);
idp.bSteped = false;
m_arIdPthSteps.append(idp);
}
}
}
else
{
//确认桥架可以走此data系统
//判断字符串有共同的字符串
memset(&param, 0, sizeof(AecHvac::DuctParam));
pEcFit->GetDuctParam(param);
if (!IsSameAsSysUse(data, param))
{
//不同系统分类
pEnt->close();
continue;
}
//弯头,三通,四通 如何处理?
//由桥架确定
//fitt 直接通过,由桥架决定
//从Mid点为起点到各个分支
pEcFit->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_MID, ptMid);
if (pInf != NULL)
{
idp.dFillUsed = 0;
idp.nPoints = 2;
idp.bUseFillUsed = true;
idp.dSize[0] = param.dSize[0];
idp.dSize[1] = param.dSize[1];
idp.id = id;
_tcscpy(idp.szSys, param.szSys);
_tcscpy(idp.szNo, param.szNo);
idp.nPoints = 2;
for (int j = 0; j < pInf->GetInterfaceCount(); j++)
{
pInf->GetInterface(j, inf);
idp.ptGe[0] = inf.ptPos;
idp.ptGe[1] = ptMid;
sTmp.Format(_T("%s-%d"), szHd, j + 1);
_tcscpy(idp.szPathNo, sTmp);
idp.bSteped = false;
m_arIdPthSteps.append(idp);
}
int nInfs = pInf->GetInterfaceCount();
int nUInfs = pEcFit->GetUserInterfaceCount();
AecUserInterface infu;
for (int n = 0; n < nUInfs; n++)
{
pEcFit->GetUserInterface(n, infu);
sTmp.Format(_T("%s-%d"), szHd, nInfs + n + 1);
_tcscpy(idp.szPathNo, sTmp);
idp.ptGe[0] = ptMid;
if (infu.nPoints == 2)
{
idp.ptGe[1] = GetInfuPointTo(infu);
idp.bSteped = false;
m_arIdPthSteps.append(idp);
idp.dSize[0] = infu.ptGe[0].distanceTo(infu.ptGe[1]);
idp.dSize[1] = infu.ptGe[0].distanceTo(infu.ptGe[1]);
}
else if (infu.nPoints == 4)
{
idp.dSize[0] = infu.ptGe[0].distanceTo(infu.ptGe[1]);
idp.dSize[1] = infu.ptGe[1].distanceTo(infu.ptGe[2]);
idp.ptGe[1] = GetInfuPointTo(infu);
idp.bSteped = false;
m_arIdPthSteps.append(idp);
}
}
}
}
}
//电力套管
AecDbEwFlexiblePipe *pFPipe = AecDbEwFlexiblePipe::cast(pEnt);
if (pFPipe != NULL)
{
AecDb3dRoadAxisLine *pRDAxln = AecDb3dRoadAxisLine::cast(pFPipe->GetBaseCurve());
if (pRDAxln != NULL)
{
//判断是电缆套管用...
pFPipe->GetSpecialtyData(AcDb::kForRead)->GetAt(PIPE_D, dOD);
pFPipe->GetSpecialtyData(AcDb::kForRead)->GetAt(PIPE_THICK, dt);
TCHAR szNo[33];
_tcscpy(szNo, _T(""));
pFPipe->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SN, szNo);
if (data.dD < (dOD - 2.0 * dt))//套管能装下本电缆
{
//判断套管使用情况
idp.dFillUsed = 0.0;
pFPipe->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_FILLUSED, idp.dFillUsed);
//计算能否能装入该电缆...
AcGePoint3dArray arPts;
pRDAxln->ConvertTo3dPline(arPts);
idp.bUseFillUsed = false;
idp.dFillUsed = 0;
idp.dSize[0] = dOD - dt;
idp.dSize[1] = 0;
idp.nPoints = 2;
_tcscpy(idp.szPathNo, szHd);
_tcscpy(idp.szNo, szNo);
//一段 --- 一段 记录
for (int j = 0; j < arPts.length() - 1; j++)
{
idp.ptGe[0] = arPts.at(j);
idp.ptGe[1] = arPts.at(j + 1);
idp.bSteped = false;
m_arIdPthSteps.append(idp);
}
}
}
}
pEnt->close();
}
}
}
acedSSFree(ss);
}
void CCableRouting::GetEquPowerPoint(const AcDbObjectId &id, AcGePoint3d& pt, AcDbExtents& ext, const CableData &data)
{
AcDbEntity *pEnt = NULL;
CString sNo, sName;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead))
{
bool bGetInfPt = false;
AecInterface inf;
AecDbXEquipment *pXEqu = AecDbXEquipment::cast(pEnt);
if (pXEqu != NULL)
{
pXEqu->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_NO, sNo);
pXEqu->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_NAME, sName);
if (pXEqu->GetInterfaceCount() > 0)
{
pXEqu->GetInterface(0, inf);
pt = inf.ptPos;
bGetInfPt = true;
}
}
AecDbEwEquipment *pEqu = AecDbEwEquipment::cast(pEnt);
if (pEqu != NULL)
{
pEqu->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_NO, sNo);
pEqu->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_NAME, sName);
if (pEqu->GetInterfaceCount() > 0)
{
pEqu->GetInterface(0, inf);
pt = inf.ptPos;
bGetInfPt = true;
}
}
AcDbBlockReference *pRef = AcDbBlockReference::cast(pEnt);
if (pRef != NULL)
{
AecDbObjXDataMap xData;
if (xData.Read(pRef, KEY_ASSOIC))
{
xData.GetAt(KEY_NO, sNo);
xData.GetAt(KEY_NAME, sName);
}
bGetInfPt = false;
}
//其他块的情况
pEnt->getGeomExtents(ext);
if (!bGetInfPt)
{
Midpoint(ext.maxPoint(), ext.minPoint(),pt);
}
pEnt->close();
}
//再从接线点精确
bool bFindSysPort = false;
CString sEqu2,sTip;
for (int i = 0;i < m_arIdEquTerminal.length();i++)
{
idLeadPort &lpt = m_arIdEquTerminal.at(i);
sEqu2 = lpt.szEquOn;
if (IsSameAsSysUse(lpt.szSys, data.szSys))
{
if (m_nAssocNoorName == 0)//关联编码
{
if (sEqu2.Find(sNo) != -1)
{
pt = lpt.m_ptPos;
m_arIdEquTerminal.removeAt(i);
bFindSysPort = true;
break;
}
}
else
{
if (sEqu2.Find(sName) != -1)
{
pt = lpt.m_ptPos;
m_arIdEquTerminal.removeAt(i);
bFindSysPort = true;
break;
}
}
if (m_nAssocNoorName == 0)//关联编码
{
if (sNo.Find(sEqu2) != -1)
{
pt = lpt.m_ptPos;
m_arIdEquTerminal.removeAt(i);
bFindSysPort = true;
break;
}
}
else
{
if (sName.Find(sEqu2) != -1)
{
pt = lpt.m_ptPos;
m_arIdEquTerminal.removeAt(i);
bFindSysPort = true;
break;
}
}
}
else
{
sTip.Format(_T("\n排除设备上属性为[ %s ]的接线点"), lpt.szSys);
acutPrintf(sTip);
}
}
if (!bFindSysPort)
{
acutPrintf(_T("\n----------------------------"));
sTip.Format(_T("\n设备上没有属性匹配[ %s ]的接线点!"), data.szSys);
acutPrintf(sTip);
}
}
void CCableRouting::TestPathStepData()
{
AcDbLine *pLn = NULL;
for (int i = 0;i < m_arIdPthSteps.length();i++)
{
idPathStep &idPs = m_arIdPthSteps.at(i);
pLn = new AcDbLine;
pLn->setStartPoint(idPs.ptGe[0]);
pLn->setEndPoint(idPs.ptGe[1]);
pLn->setColorIndex(kBlue);
CoreTools::AddToModelSpace(pLn);
}
}