#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 #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 ¶m) { /* #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(¶m, 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(¶m, 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& 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& 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 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& 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& 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 ar3dRdAxLines; CalRoutingPath(ptFrEntry, ptToEntry,ptFr,ptTo,data,ar3dRdAxLines); //然后计算一条不考虑填充率的最短路径 AcArray 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 & 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 & ar3dRdAxLines, AcGePoint3d& ptFrEntry, AcGePoint3d & ptToEntry,bool bDelete) { double dLen = 0.0, dMinLen = 1.e10; RoadAxLineLen rdlen; std::vector 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 &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 ¶m) { 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(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(¶m, 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(¶m2, ¶m, 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(¶m2, ¶m, 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(¶m2, ¶m, 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(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(¶m, 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); } }