#include "StdAfx.h" #include "SanitarySys.h" void SanitarySys::AutoLinkSanitary(const SanitarySysData &data) { } SanitarySys::~SanitarySys() { std::vector::iterator it; std::vector::iterator itP; for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++) { std::vector &data = (*it).data; for (itP = data.begin(); itP != data.end(); itP++) { delete (*itP).pLine; (*itP).pLine = NULL; } } } void SanitarySys::Sort(std::vector &data, const AcGePoint3d &pt) { std::multimap mapData; std::vector::iterator it; AcGePoint3d ptFeed = pt, ptSan; ptFeed.z = 0; ptFeed = Wcs2Ucs(ptFeed); for (it = data.begin(); it != data.end(); it++) { ptSan = (*it).pt; ptSan = Wcs2Ucs(ptSan); double dDist = fabs(ptFeed.x - ptSan.x) + fabs(ptFeed.y - ptSan.y); // 沿x轴和y轴距离之和 mapData.insert(std::make_pair(dDist, *it)); } data.clear(); std::multimap::reverse_iterator itM; for (itM = mapData.rbegin(); itM != mapData.rend(); itM++) { data.push_back((*itM).second); } } bool SanitarySys::IsVertivalPipe(const AcDbObjectId &id) { bool bVertival = false; TDbPipe *pPipe = NULL; acdbOpenObject(pPipe, id, AcDb::kForRead); if (pPipe != NULL) { bVertival = pPipe->IsVertical() ? true : false; pPipe->close(); } return bVertival; } double SanitarySys::GetPipeDn(const AcDbObjectId &id) { double dDn = 0.0; TDbPipe *pPipe = NULL; acdbOpenObject(pPipe, id, AcDb::kForRead); if (pPipe != NULL) { dDn = pPipe->GetDnDiameter(); pPipe->close(); } return dDn; } bool SanitarySys::GetPipePoint(const AcDbObjectId &id, AcGePoint3d &ptS, AcGePoint3d &ptE) { bool bRet = false; TDbPipe *pPipe = NULL; acdbOpenObject(pPipe, id, AcDb::kForRead); if (pPipe != NULL) { bRet = true; ptS = pPipe->StartPoint(); ptE = pPipe->EndPoint(); pPipe->close(); } return bRet; } SanitarySys::PipeDir SanitarySys::GetPipeDirection(const AcDbObjectId &id) { PipeDir Ret = eNone; AcGePoint3d ptS, ptE; if (!GetPipePoint(id, ptS, ptE)) { return Ret; } if (IsVertivalPipe(id)) { return eOther; } AcGeVector3d vtX = AcGeVector3d::kXAxis; AcGeVector3d vtY = AcGeVector3d::kYAxis; // vtX.rotateBy(Wcs2Ucs(0.0), AcGeVector3d::kZAxis); // vtY.rotateBy(Wcs2Ucs(0.0), AcGeVector3d::kZAxis); AcGeVector3d vtDir = ptE - ptS; vtDir.z = 0.0; vtDir.rotateBy(Wcs2Ucs(0.0), AcGeVector3d::kZAxis); vtDir.normalize(); AcGeTol tol; tol.setEqualVector(0.001); if (vtDir.isParallelTo(vtX, tol)) { Ret = eParallelX; } else if (vtDir.isParallelTo(vtY, tol)) { Ret = eParallelY; } else { Ret = eOther; } return Ret; } SanitarySys::PipeDir SanitarySys::GetPipeDirection(TPipeSys::SysType sys, int nId) { PipeDir Dir = eNone; std::vector::iterator it; std::vector::iterator itP; for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++) { if ((*it).sys != sys) { continue; } for(itP = ((*it).data).begin(); itP != ((*it).data).end(); itP++) { if ((*itP).nId == nId) { Dir = (*itP).drection; break; } } break; } return Dir; } SanitarySys::PipeType SanitarySys::GetDataType(TPipeSys::SysType sys, int nId) { PipeType type = eError; std::vector::iterator it; std::vector::iterator itP; for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++) { if ((*it).sys != sys) { continue; } for(itP = ((*it).data).begin(); itP != ((*it).data).end(); itP++) { if ((*itP).nId == nId) { type = (*itP).type; break; } } break; } return type; } //获取支管可供连接洁具点的给水点或排水点 void SanitarySys::GetLinkablePt(const AcDbObjectId &id, AcGePoint3d &ptLinkable, AcGePoint3d &ptS, AcGePoint3d &ptE) { TDbPipe *pPipe = NULL; acdbOpenObject(pPipe, id, AcDb::kForRead); if (pPipe != NULL) { ptS = pPipe->GetStartPoint(); ptE = pPipe->GetEndPoint(); if (pPipe->GetFlowDir() == TPipeSys::kFromStart) { pPipe->getStartPoint(ptLinkable); if (pPipe->GetSysType() == TPipeSys::kDirtWater || pPipe->GetSysType() == TPipeSys::kUselessWater) { pPipe->getEndPoint(ptLinkable); } } else { pPipe->getEndPoint(ptLinkable); if (pPipe->GetSysType() == TPipeSys::kDirtWater || pPipe->GetSysType() == TPipeSys::kUselessWater) { pPipe->getStartPoint(ptLinkable); } } pPipe->close(); } } bool SanitarySys::AddSanitarySys(TPipeSys::SysType sys, double dDn) { bool bRet = false; std::vector::iterator it; for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++) { if ((*it).sys == sys) { bRet = true; break; } } if (it == m_vecPipe.end()) { bRet = true; Node node; node.sys = sys; node.dPipeDn = dDn; m_vecPipe.push_back(node); } return bRet; } void SanitarySys::CreatePipe() { std::vector::iterator it; std::vector::iterator itP; CString sLayer; for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++) { sLayer = GetPipeLayer((*it).sys); InitLayer(sLayer); int iPipeIdx = GetPipeLayerIdxByName(sLayer); CString sLineType = GetPipeWireLayLineType(sLayer); CString sMaterial = GetPipeMaterialByIdx(g_iPipeMaterial[iPipeIdx]); CString sDnType = GetDnByMat(sMaterial); std::vector &vec = (*it).data; for (itP = vec.begin(); itP != vec.end(); itP++) { AcDbLine *&line = (*itP).pLine; TDbPipe *pPipe = new TDbPipe(); pPipe->SetRadius(g_nPipeRadius[iPipeIdx]); if (itP->type == eVertival)//设置立管显示半径 { if(g_bPipeDouble[iPipeIdx]) { pPipe->SetRadiusIn(g_nPipeRadius[iPipeIdx] / 2); } else { if(!g_bStandPipeArc)//传统扣弯 pPipe->SetRadiusIn(-2); } } pPipe->SetStartPoint(line->startPoint()); pPipe->SetEndPoint(line->endPoint()); pPipe->SetFlowDir(TPipeSys::kFromStart); CString sLineType2 = GetLayerLineType(sLayer); if(sLineType2.Find(_T("TG")) > -1) { XLine lineTemp(asDblArray(line->startPoint()), asDblArray(line->endPoint())); double nAng = lineTemp.Direction(); if(nAng > PI/2 && nAng < (PI/2*3 + 0.001)) { pPipe->SetStartPoint(line->endPoint()); pPipe->SetEndPoint(line->startPoint()); pPipe->SetFlowDir(TPipeSys::kFromEnd); } } pPipe->SetDnDiameter((*it).dPipeDn); pPipe->setLayer(sLayer); pPipe->SetSysType(GetPipeSysByLayer(sLayer)); pPipe->setColor(AcCmColor()); //随层 pPipe->SetPipeWeight(g_nPipeWidth[iPipeIdx]); pPipe->setLinetype(sLineType); pPipe->setLineWeight(AcDb::kLnWtByLayer); pPipe->SetMaterial(g_iPipeMaterial[iPipeIdx]); pPipe->SetLabel(sDnType); AddToCurrentSpace(pPipe, Adesk::kTrue); } } } CString SanitarySys::GetPipeLayer(TPipeSys::SysType sys) { CString sLayer; if(sys == TPipeSys::kFeedWater) sLayer = LAY_PIPE_FEED; else if (sys == TPipeSys::kFeedWater2) sLayer = LAY_PIPE_FEED2; else if (sys == TPipeSys::kFeedWater3) sLayer = LAY_PIPE_FEED3; else if(sys == TPipeSys::kHeatFeedWater) sLayer = LAY_PIPE_HEADFEED; else if(sys == TPipeSys::kHeatFeedWater2) sLayer = LAY_PIPE_HEADFEED2; else if(sys == TPipeSys::kHeatFeedWater3) sLayer = LAY_PIPE_HEADFEED3; else if(sys == TPipeSys::kHeatBackWater) sLayer = LAY_PIPE_HEADBACK; else if(sys == TPipeSys::kHeatBackWater2) sLayer = LAY_PIPE_HEADBACK2; else if(sys == TPipeSys::kHeatBackWater3) sLayer = LAY_PIPE_HEADBACK3; else if(sys == TPipeSys::kDirtWater) sLayer = LAY_PIPE_DIRT; else if(sys == TPipeSys::kUselessWater) sLayer = LAY_PIPE_USELESS; else if(sys == TPipeSys::kRainWater) sLayer = LAY_PIPE_RAIN; else if(sys == TPipeSys::kUsedWater) sLayer = LAY_PIPE_USED; else if(sys == TPipeSys::kUsedWater2) sLayer = LAY_PIPE_USED2; else if(sys == TPipeSys::kUsedWater3) sLayer = LAY_PIPE_USED3; else if(sys == TPipeSys::kFireFighting) sLayer = LAY_PIPE_FIRE; else if(sys == TPipeSys::kFireFighting2) sLayer = LAY_PIPE_FIRE2; else if(sys == TPipeSys::kFireFighting3) sLayer = LAY_PIPE_FIRE3; else if(sys == TPipeSys::kSprinkle) sLayer = LAY_PIPE_SPRINKLE; else if(sys == TPipeSys::kSprinkle2) sLayer = LAY_PIPE_SPRINKLE2; else if(sys == TPipeSys::kSprinkle3) sLayer = LAY_PIPE_SPRINKLE3; else if(sys == TPipeSys::kCoagulate) sLayer = LAY_PIPE_COAGULATE; else if(sys == TPipeSys::kDrink) sLayer = LAY_PIPE_DRINK; else if(sys == TPipeSys::kPressDirt) sLayer = LAY_PIPE_PRESSDIRT; else if(sys == TPipeSys::kPressUseless) sLayer = LAY_PIPE_PRESSUSELESS; else if(sys == TPipeSys::kPressRain) sLayer = LAY_PIPE_PRESSRAIN; else if(sys == TPipeSys::kCivilFeed) sLayer = LAY_PIPE_USER1; else if(sys == TPipeSys::kCycleFeed) sLayer = LAY_PIPE_USER2; else if(sys == TPipeSys::kOther) sLayer = LAY_PIPE_OTHER; else if (sys == TPipeSys::kUser3) sLayer = LAY_PIPE_USER3; else if (sys == TPipeSys::kUser4) sLayer = LAY_PIPE_USER4; else if (sys == TPipeSys::kUser5) sLayer = LAY_PIPE_USER5; else if (sys == TPipeSys::kUser6) sLayer = LAY_PIPE_USER6; else if (sys == TPipeSys::kUser7) sLayer = LAY_PIPE_USER7; else if (sys == TPipeSys::kUser8) sLayer = LAY_PIPE_USER8; return sLayer; } CString SanitarySys::GetVPipeLayer(TPipeSys::SysType sys) { CString sLayer; if(sys == TPipeSys::kFeedWater) sLayer = LAY_VPIPE_FEED; else if (sys == TPipeSys::kFeedWater2) sLayer = LAY_VPIPE_FEED2; else if (sys == TPipeSys::kFeedWater3) sLayer = LAY_VPIPE_FEED3; else if(sys == TPipeSys::kHeatFeedWater) sLayer = LAY_VPIPE_HEADFEED; else if(sys == TPipeSys::kHeatFeedWater2) sLayer = LAY_VPIPE_HEADFEED2; else if(sys == TPipeSys::kHeatFeedWater3) sLayer = LAY_VPIPE_HEADFEED3; else if(sys == TPipeSys::kHeatBackWater) sLayer = LAY_VPIPE_HEADBACK; else if(sys == TPipeSys::kHeatBackWater2) sLayer = LAY_VPIPE_HEADBACK2; else if(sys == TPipeSys::kHeatBackWater3) sLayer = LAY_VPIPE_HEADBACK3; else if(sys == TPipeSys::kDirtWater) sLayer = LAY_VPIPE_DIRT; else if(sys == TPipeSys::kUselessWater) sLayer = LAY_VPIPE_USELESS; else if(sys == TPipeSys::kRainWater) sLayer = LAY_VPIPE_RAIN; else if(sys == TPipeSys::kUsedWater) sLayer = LAY_VPIPE_USED; else if(sys == TPipeSys::kUsedWater2) sLayer = LAY_VPIPE_USED2; else if(sys == TPipeSys::kUsedWater3) sLayer = LAY_VPIPE_USED3; else if(sys == TPipeSys::kFireFighting) sLayer = LAY_VPIPE_FIRE; else if(sys == TPipeSys::kFireFighting2) sLayer = LAY_VPIPE_FIRE2; else if(sys == TPipeSys::kFireFighting3) sLayer = LAY_VPIPE_FIRE3; else if(sys == TPipeSys::kSprinkle) sLayer = LAY_VPIPE_SPRINKLE; else if(sys == TPipeSys::kSprinkle2) sLayer = LAY_VPIPE_SPRINKLE2; else if(sys == TPipeSys::kSprinkle3) sLayer = LAY_VPIPE_SPRINKLE3; else if(sys == TPipeSys::kCoagulate) sLayer = LAY_VPIPE_COAGULATE; else if(sys == TPipeSys::kDrink) sLayer = LAY_VPIPE_DRINK; else if(sys == TPipeSys::kPressDirt) sLayer = LAY_VPIPE_PRESSDIRT; else if(sys == TPipeSys::kPressUseless) sLayer = LAY_VPIPE_PRESSUSELESS; else if(sys == TPipeSys::kPressRain) sLayer = LAY_VPIPE_PRESSRAIN; else if(sys == TPipeSys::kCivilFeed) sLayer = LAY_VPIPE_USER1; else if(sys == TPipeSys::kCycleFeed) sLayer = LAY_VPIPE_USER2; else if(sys == TPipeSys::kOther) sLayer = LAY_VPIPE_OTHER; else if (sys == TPipeSys::kUser3) sLayer = LAY_VPIPE_USER3; else if (sys == TPipeSys::kUser4) sLayer = LAY_VPIPE_USER4; else if (sys == TPipeSys::kUser5) sLayer = LAY_VPIPE_USER5; else if (sys == TPipeSys::kUser6) sLayer = LAY_VPIPE_USER6; else if (sys == TPipeSys::kUser7) sLayer = LAY_VPIPE_USER7; else if (sys == TPipeSys::kUser8) sLayer = LAY_VPIPE_USER8; return sLayer; } void SanitarySys::SetVertivalPipeAndDoor(PickSet &ss) { Entity ent; for (long l = 0; l < ss.Length(); l++ ) { ent = ss[l]; if (ent.Is(_T("ATS_PIPE")))//管线或立管 { AcDbObjectId id; acdbGetObjectId(id, ent); if (IsVertivalPipe(id)) { m_ssPipe += ent; } } else//门窗 { m_ssDoorWall += ent; } } } int SanitarySys::PassWallNumByLine(const AcGePoint3d &ptXOY, const AcGePoint3d &ptSanitary, double &dWidth) { int nNum = 0; Entity ent; AcGePoint3d ptS = ptXOY, ptE = ptSanitary; ptS.z = 0; ptE.z = 0; PickSet ssTGWall(SS_FREE), ssLineWall(SS_FREE); AcDbLine line(ptS, ptE); AcGePoint3dArray arryPt1, arryPt2; for (long l = 0; l < m_ssDoorWall.Length(); l++) { arryPt1.setLogicalLength(0); arryPt2.setLogicalLength(0); ent = m_ssDoorWall[l]; OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbWall, pWall);// 上华墙体 if (pWall != NULL) { pWall->intersectWith(&line, AcDb::kOnBothOperands, arryPt1); } OPENOBJ_END(); if (arryPt1.length() > 0) { ssTGWall += ent; nNum++; } OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbLine, pLine);// 图层为WALL的线段 if (pLine != NULL) { CString sLayer; sLayer = pLine->layer(); if (sLayer.Compare(_T("WALL")) == 0) { ptS = pLine->startPoint(); ptE = pLine->endPoint(); ptS.z = 0; ptE.z = 0; AcDbLine line2(ptS, ptE); line2.intersectWith(&line, AcDb::kOnBothOperands, arryPt2); } } OPENOBJ_END(); if (arryPt2.length() > 0) { ssLineWall += ent;// 其他线性墙体 nNum ++; } } GetNearestWallWidth(ptSanitary, ptXOY, ssTGWall, ssLineWall, dWidth); return nNum; } void SanitarySys::GetNearestWallWidth(const AcGePoint3d &ptSanitary, const AcGePoint3d &ptDir, PickSet &ssTGWall, PickSet &ssLineWall, double &dWidth) { bool bTGWall = false, bLineWall = false; double dDist1 = 0.0, dDist2 = 0.0; double dWidth1 = 0.0, dWidth2 = 0.0; if (ssTGWall.Length() > 0) { bTGWall = true; GetTGWallWidth(ptSanitary, ptDir, ssTGWall, dDist1, dWidth1); } if (ssLineWall.Length() > 1) { bLineWall = true; GetLineWallWidth(ptSanitary, ptDir, ssLineWall, dDist2, dWidth2); } if (bTGWall && bLineWall) { if (dDist1 - dDist2 > 0.001) { dWidth = dWidth2; } else { dWidth = dWidth1; } } else if (bTGWall) { dWidth = dWidth1; } else { dWidth = dWidth2; } } void SanitarySys::GetLineWallWidth(const AcGePoint3d &ptSanitary, const AcGePoint3d &ptDir, PickSet &ssLineWall, double &dDist, double &dWidth) { double dTmp = 0.0; Entity ent; AcGePoint3d ptWall; AcGePoint3d ptS, ptE; AcGePoint3d ptPipeStart = ptSanitary, ptPipeEnd = ptDir; ptPipeStart.z = 0; ptPipeEnd.z = 0; AcDbLine linePipe(ptPipeStart, ptPipeEnd); std::multimap mapWallInfo; AcGePoint3dArray arrayPts; for (long l = 0; l < ssLineWall.Length(); l++) { ent = ssLineWall[l]; arrayPts.setLogicalLength(0); OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbLine, pLine);// 图层为WALL的线段 if (pLine != NULL) { CString sLayer; sLayer = pLine->layer(); if (sLayer.Compare(_T("WALL")) == 0) { ptS = pLine->startPoint(); ptE = pLine->endPoint(); ptS.z = 0; ptE.z = 0; AcDbLine line(ptS, ptE); Acad::ErrorStatus es = line.intersectWith(&linePipe, AcDb::kOnBothOperands, arrayPts); if (es == Acad::eOk) { if (arrayPts.length() > 0) { ptWall = arrayPts[0]; dTmp = ptWall.distanceTo(ptSanitary); mapWallInfo.insert(std::make_pair(dTmp, ptWall)); } } } } OPENOBJ_END(); } AcGePoint3d ptFirst, ptNext; std::multimap::iterator itM; int i = 0; for (itM = mapWallInfo.begin(); itM != mapWallInfo.end(); itM++, i++) { if (i == 0) { ptFirst = (*itM).second; } if (i == 1) { ptNext = (*itM).second; break; } } if (mapWallInfo.size() < 2) { ptNext = ptSanitary; } dWidth = ptFirst.distanceTo(ptNext); } void SanitarySys::GetTGWallWidth(const AcGePoint3d &ptSanitary, const AcGePoint3d &ptDir, PickSet &ssTGWall, double &dDist, double &dWidth) { double dTmp = 0.0; Entity ent; AcGePoint3d ptWall; AcGePoint3dArray arrayPts; AcGePoint3d ptPipeStart = ptSanitary, ptPipeEnd = ptDir; ptPipeStart.z = 0; ptPipeEnd.z = 0; AcDbLine linePipe(ptPipeStart, ptPipeEnd); for (long l = 0; l < ssTGWall.Length(); l++) { ent = ssTGWall[l]; arrayPts.setLogicalLength(0); OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbWall, pWall);// 上华墙体 if (pWall != NULL) { pWall->intersectWith(&linePipe, AcDb::kOnBothOperands, arrayPts); if (arrayPts.length() > 0) { ptWall = arrayPts[0]; dTmp = ptWall.distanceTo(ptSanitary); if (dDist - dTmp > 0.001 || l == 0) { dDist = dTmp; dWidth = pWall->GetWidth(); } } } OPENOBJ_END(); } } int SanitarySys::PassSanitaryNumByLine(const std::vector &data, const AcGePoint3d &pt1, const AcGePoint3d &pt2) { int nNum = 0; AcGePoint3d ptTemp, ptData, PtLine = pt1, ptSan = pt2; PtLine.z = 0; ptSan.z = 0; std::vector::const_iterator it; AcDbLine line(PtLine, ptSan); for (it = data.begin(); it != data.end(); it++) { ptData = (*it).pt; ptData.z = 0; if (line.getClosestPointTo(ptData, AcGeVector3d::kZAxis, ptTemp) == Acad::eOk) { if ((ptData).distanceTo(ptTemp) - 0.01 < 0.0) { ++nNum; } } } return nNum; } int SanitarySys::PassVertivalPipeNumByLine(const AcGePoint3d &pt1, const AcGePoint3d &pt2) { long len = 0; int nNum = 0; XPoint ptS = pt1, ptE = pt2, ptTemp; AcDbLine line(ptS, ptE); Entity ent; for (; len < m_ssPipe.Length(); len++) { ent = m_ssPipe[len]; OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbPipe, pPipe); if (pPipe) { line.getClosestPointTo(pPipe->GetStartPoint(), AcGeVector3d::kZAxis, ptTemp); const double dScale = DocGetMeterUnitDim() ? 1 : 100; double dDn = pPipe->GetRadius() * dScale;//立管半径 double dDist = ptTemp.Distance2d(pPipe->GetStartPoint()); if (dDist - dDn < 0.001) { nNum++; } } OPENOBJ_END(); } if (nNum > 0)//删除立管自身和直线的交点 { --nNum; } return nNum; } int SanitarySys::IsNextToDoor(double dDist, const AcGePoint3d &pt1, const AcGePoint3d &pt2) { int nNum = 0; Entity ent; AcGePoint3d ptS = pt1, ptE = pt2; ptS.z = 0; ptE.z = 0; AcDbLine line(ptS, ptE); XPoint ptOnLine, ptDoor; AcGePoint3dArray arryPts; for (long l = 0; l < m_ssDoorWall.Length(); l++) { ent = m_ssDoorWall[l]; arryPts.setLogicalLength(0); OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbOpening, pDoor);//上华门窗实体 if (pDoor != NULL) { ptDoor = pDoor->GetLocation(); double dWidth = pDoor->GetWallThickness(); pDoor->GetWallId(); TDbWall *pWall = NULL; acdbOpenObject(pWall, pDoor->GetWallId(), AcDb::kForRead); if (pWall != NULL) { pWall->intersectWith(&line, AcDb::kOnBothOperands,arryPts); pWall->close(); if (arryPts.length() > 0)//管线和墙体相交时 { double dLength = ptDoor.Distance2d(arryPts[0]); if (dLength - pDoor->GetWidth() / 2 < 0.001) { nNum++; } } else // 管线和墙体平行时 { line.getClosestPointTo(ptDoor, AcGeVector3d::kZAxis, ptOnLine); if (ptDoor.Distance2d(ptOnLine) - dDist - dWidth / 2 < 0.001) { nNum++; } } } } OPENOBJ_END(); } return nNum; }