// MovePipe.cpp: implementation of the MovePipe class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MovePipe.h" extern void SearchOneselfPipe(AcDbObjectId idPipe, TPipeGraph &PipeGraph); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// // 检查所选管线是否是直管 bool CheckPipe(Entity entPipe) { OPENOBJ_BEGIN(entPipe, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe != NULL) { if (pPipe->IsVertical() || pPipe->GetBulge() != 0) { return false; } } OPENOBJ_END(); return true; } void MovePipes() { g_ssPickFirst.Free(); RBList rbMask(RTDXF0, _T("ATS_PIPE"), 8, GetLayerNames(_T("管")), NULL); Entity entSel; XPoint ptPick; while (SelectEntity(_T("\n请选择需要移动的管段:<退出>"), entSel, ptPick, rbMask) == RTNORM) { if (!CheckPipe(entSel)) { ads_printf(_T("\n选择管段有误,请重新选择!")); continue; } MovePipe moveAct; moveAct.InitPipeSys(entSel); moveAct.Move(); // 更新管线系统 TPipePerDocData *pData = GetCurPipeDocData(); if (pData != NULL) { pData->ApplyUpdates(); } break; } } MovePipe::MovePipe() { m_typeSys = TPipeSys::SysType::kUnknownSys; } MovePipe::~MovePipe() { m_ssMove.Free(); m_ssLink.Free(); } void MovePipe::InitPipeSys(Entity entPipe) { acdbGetObjectId(m_idPipeMove, entPipe); m_typeSys = GetPipeSys(entPipe); SearchOneselfPipe(m_idPipeMove, m_graphPipe); SearchMovePipe(); SearchLinkedPipe(); } void MovePipe::SearchMovePipe() { // 搜索移动管线 int len = m_graphPipe.m_lstEdge.Length(); for(int i = 0; i < len; i++) { AcDbObjectId idTmp = m_graphPipe.m_lstEdge[i]->m_idPipe; if(idTmp != NULL) { PickSet ssVist(SS_FREE); if (IsParallelToPipe(idTmp, m_idPipeMove, ssVist)) { ads_name name; acdbGetAdsName(name, idTmp); Entity entPipe = name; if (IsPipeVertical(entPipe)) { XPoint pt1, pt2; GetPipePoint(entPipe, pt1, pt2); AcDbObjectId idDim = GetVPipeDimByPt(pt1); if (idDim != NULL) { m_ssMove += idDim; m_vecPipeMove.push_back(idDim); } } m_ssMove += idTmp; m_vecPipeMove.push_back(idTmp); m_ssMove += m_graphPipe.m_lstEdge[i]->m_pNode1->m_idNode; m_ssMove += m_graphPipe.m_lstEdge[i]->m_pNode2->m_idNode; // 获取管线附件 OPENOBJ_BEGIN(idTmp, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe != NULL) { DList lstAtt; pPipe->GetAttachments(lstAtt); for (int j = 0; j < lstAtt.Length(); j++) { m_ssMove += *lstAtt.GetAt(j); } } OPENOBJ_END(); } } } } void MovePipe::SearchLinkedPipe() { // 搜索联动管线 int len = m_graphPipe.m_lstEdge.Length(); for(int i = 0; i < len; i++) { AcDbObjectId idTmp = m_graphPipe.m_lstEdge[i]->m_idPipe; if(idTmp != NULL) { ads_name name; acdbGetAdsName(name, idTmp); Entity entNow = name; if (entNow.In(&m_ssMove)) { continue; } PickSet ssVist(SS_FREE); XPoint pt1, pt2, ptOnPipe; GetPipePoint(entNow, pt1, pt2); AcGeVector3d vt = pt1 - pt2; if (IsLinkedWithPipe(m_ssMove, idTmp, ssVist, vt, ptOnPipe)) { ads_name name; acdbGetAdsName(name, idTmp); Entity entPipe = name; AcDbObjectId idDim; if (IsPipeVertical(entPipe)) { XPoint pt1, pt2; GetPipePoint(entPipe, pt1, pt2); idDim = GetVPipeDimByPt(pt1); if (idDim != NULL) { m_ssLink += idDim; } } m_ssLink += idTmp; std::vector::iterator it; AcGeTol tol; tol.setEqualVector(1e-3); for (it = m_vecPipeLink.begin(); it != m_vecPipeLink.end(); it++) { if (it->ptOnPipe.Distance2d(ptOnPipe) < MINDIST && vt.isParallelTo(it->vtPipe, tol)) { it->vecPipeLink.push_back(idTmp); if (idDim != NULL) { it->vecPipeLink.push_back(idDim); } break; } } if (it == m_vecPipeLink.end()) { PipeLinkedInfo info; info.bSideOnPipe = false; info.ptOnPipe = ptOnPipe; info.vtPipe = vt; info.vecPipeLink.push_back(idTmp); if (idDim != NULL) { info.vecPipeLink.push_back(idDim); } m_vecPipeLink.push_back(info); } } } } } void MovePipe::InitPipeLinkSys() { std::vector::iterator it; for (it = m_vecPipeLink.begin(); it != m_vecPipeLink.end(); it++) { std::vector::iterator itPipe; int nPtOnPipeNum = 0; for (itPipe = it->vecPipeLink.begin(); itPipe != it->vecPipeLink.end(); itPipe++) { OPENOBJ_BEGIN(*itPipe, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { XPoint pt; pPipe->getClosestPointTo(it->ptOnPipe, pt); if (pt.Distance2d(it->ptOnPipe) < MINDIST) { nPtOnPipeNum++; } } OPENOBJ_END(); } if (nPtOnPipeNum > 1) { it->bSideOnPipe = false; } else { it->bSideOnPipe = true; } } } void MovePipe::Move() { bool bMoveLinked = true; if (m_ssLink.Length() > 0) { TCHAR szTmp[10]; INITGET_BEG(0, _T("Y N")); int nStatus = acedGetKword(_T("\n与其相交管段是否联动:[Y/N]:"), szTmp); if (nStatus == RTNORM) { if (szTmp[0] == 'N' || szTmp[0] == 'n') { bMoveLinked = false; } } else if (nStatus == RTCAN) { return; } INITGET_END(); } else { bMoveLinked = false; } // 移动主干管 if (!MoveMainPipe()) { return; } if (bMoveLinked)// 联动管线联动 { InitPipeLinkSys(); MovePipeByPerpendicularVt();// 沿移动管线垂直方向移动管网 } else// 联动管线不联动 { LinkPipeByVPipe(); } // 更新管线系统 TPipePerDocData *pData = GetCurPipeDocData(); if (pData != NULL) { pData->ApplyUpdates(); } DeleteUselessVPipe(bMoveLinked); } bool MovePipe::MoveMainPipe() { xg_setvar(_T("CMDECHO"), 0); int nOsMode=0; xg_getvar(_T("OSMODE"), &nOsMode); if(g_bTgOsnap) { nOsMode &= ~0x4000; nOsMode |= OS_INT|OS_NEA|OS_PER|OS_END|OS_CEN; } XPushVar vOsMode(_T("OSMODE"), nOsMode); double dCeltScale = 1; xg_getvar(_T("CELTSCALE"), &dCeltScale); XPoint ptS, ptE, ptMid, ptOld; ads_name name; acdbGetAdsName(name, m_idPipeMove); Entity entPipe = name; GetPipePoint(entPipe, ptS, ptE, ptOld); Midpoint(ptS, ptE, ptOld); AcDbLine line(ptS, ptE); SHads_command(RTSTR, _T(".UNDO"), RTSTR, _T("MARK"), RTNONE); // Make a undo mark ModifyMovedVPipe(); ads_printf(_T("\n请点取位置点:<退出>")); TADSGePoint3d __pt(Wcs2Ucs(ptOld)); int nRet = SHads_command(RTSTR, _T("MOVE"), RTPICKS, (TLong_ptr *)m_ssMove, RTSTR, _T(""), RT3DPOINT, &__pt, RTSTR, PAUSE, 0); XPoint pt; pt.z = ptOld.z; AcGeVector3d vtOld = ptOld - pt; GetPipePoint(entPipe, ptS, ptE, ptMid); Midpoint(ptS, ptE, ptMid); AcGeVector3d vtNow = ptMid - ptOld; AcGeTol tol; tol.setEqualVector(vtNow.length() / 10000); if (nRet != RTNORM || vtOld.isEqualTo(vtNow, tol)) { SHads_command(RTSTR, _T("UNDO"), RTSTR, _T("BACK"), RTNONE); SHads_command(RTNONE); return false; } return true; } void MovePipe::ModifyMovedVPipe() { PickSet ss(SS_FREE); for (long l = 0l; l < m_ssMove.Length(); l++) { Entity ent = m_ssMove[l]; OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL && pPipe->IsVertical()) { XPoint pt = pPipe->MidPoint(); std::vector::iterator it; for (it = m_vecPipeLink.begin(); it != m_vecPipeLink.end(); it++) { XPoint ptOnPipe = it->ptOnPipe; if (pt.Distance2d(ptOnPipe) < MINDIST) { ss += ent; } } } OPENOBJ_END(); } m_ssMove -= ss; ss.Erase(); } void MovePipe::DeleteUselessVPipe(bool bMoveLinked) { // 删除无用立管 int len = m_graphPipe.m_lstEdge.Length(); for(int i = 0; i < len; i++) { AcDbObjectId idTmp = m_graphPipe.m_lstEdge[i]->m_idPipe; OPENOBJ_BEGIN(idTmp, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe != NULL && pPipe->IsVertical()) { XPoint ptS = pPipe->MidPoint(); std::vector::iterator it; for (it = m_vecPipeLink.begin(); it != m_vecPipeLink.end(); it++) { if (ptS.Distance2d(it->ptOnPipe) < MINDIST) { bool bErase = false; for (int i = 0; i < 2; i++) { AcDbObjectId nodeId(NULL); nodeId = pPipe->GetNode(i); OPENOBJ_BEGIN(nodeId, AcDb::kForRead, TDbPipeNode, pNode); if(pNode != NULL) { int num = pNode->GetInterfaceNum(); if (num == 1) { bErase = true; break; } } OPENOBJ_END(); } if (bErase) { pPipe->erase(); if (!bMoveLinked) { AcDbObjectId idDim = GetVPipeDimByPt(ptS); if (idDim != NULL) { PickSet ss(SS_FREE); ss += idDim; ss.Erase(); } } break; } } } } OPENOBJ_END(); } } // 管线不联动时交点处生成立管 void MovePipe::LinkPipeByVPipe() { XPoint ptS, ptE; ads_name name; acdbGetAdsName(name, m_idPipeMove); Entity entPipe = name; GetPipePoint(entPipe, ptS, ptE); ptS.z = 0; ptE.z = 0; AcDbLine line(ptS, ptE); std::vector::iterator it; std::vector::iterator itPipe; for (it = m_vecPipeLink.begin(); it != m_vecPipeLink.end(); it++) { for (itPipe = it->vecPipeLink.begin(); itPipe != it->vecPipeLink.end(); itPipe++) { OPENOBJ_BEGIN(*itPipe, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { ptS = pPipe->GetStartPoint(); ptE = pPipe->GetEndPoint(); double dElePipe = ptS.z; ptS.z = 0; ptE.z = 0; AcDbLine linePipe(ptS, ptE); AcGePoint3dArray arrys; arrys.setLogicalLength(0); line.intersectWith(&linePipe, AcDb::kExtendThis, arrys); if (arrys.length() == 1) { XPoint ptInt = arrys[0]; double dEleMain = 0.0; bool bFindPipe = false; std::vector::iterator itPipe; for (itPipe = m_vecPipeMove.begin(); itPipe != m_vecPipeMove.end(); itPipe++) { OPENOBJ_BEGIN(*itPipe, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { XPoint ptOnPipe; pPipe->getClosestPointTo(ptInt, ptOnPipe); if (ptInt.Distance2d(ptOnPipe) < MINDIST) { dEleMain = ptOnPipe.z; bFindPipe = true; break; } } OPENOBJ_END(); } if (fabs(dEleMain - dElePipe) > MINDIST && bFindPipe) { TDbPipe *pPipeNew = (TDbPipe *)pPipe->clone(); if (pPipeNew != NULL) { ptInt.z = dEleMain; pPipeNew->SetStartPoint(ptInt); ptInt.z = dElePipe; pPipeNew->SetEndPoint(ptInt); AddToCurrentSpace(pPipeNew, Adesk::kTrue); } } } } OPENOBJ_END(); } } } void MovePipe::ModifyPipeBy1Side(std::vector &vecPipe, XPoint ptNew, XPoint ptOld) { bool bOnPipe = false;// 交点是否在联动管线上 AcDbObjectId idNeatestPipe; bool bExtendThis = true; // 是否从近端延长管线 ptOld.z = 0; std::vector::iterator itPipe; for (itPipe = vecPipe.begin(); itPipe != vecPipe.end(); itPipe++) { OPENOBJ_BEGIN(*itPipe, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { XPoint ptOnPipe; pPipe->getClosestPointTo(ptNew, ptOnPipe); if (ptNew.Distance2d(ptOnPipe) < MINDIST) { bOnPipe = true; ptNew.z = ptOnPipe.z; } pPipe->getClosestPointTo(ptOld, ptOnPipe); if (ptOld.Distance2d(ptOnPipe) < MINDIST) { idNeatestPipe = pPipe->id(); ptNew.z = ptOnPipe.z; AcGeVector3d vt; if (pPipe->GetStartPoint().Distance2d(ptOld) < MINDIST) { vt = ptOld - pPipe->GetEndPoint(); } else { vt = ptOld - pPipe->GetStartPoint(); } vt.z = 0; vt.normalize(); AcGeVector3d vtMove = ptOld - ptNew; vtMove.z = 0; vtMove.normalize(); AcGeTol tol; tol.setEqualVector(1e-3); if (vtMove.isEqualTo(vt, tol)) { bExtendThis = false; } } } OPENOBJ_END(); } if (!bOnPipe)// 交点不在联动管线上 { AcDbObjectId idVPipe; AcDbObjectId idDim = GetVPipeDimByPt(ptOld); ExtendPipe2Pt(idNeatestPipe, ptNew, bExtendThis); idVPipe = CreateVPipe(ptNew, GetVPipeByPt(ptOld)); if (idDim != NULL && idVPipe != NULL) { ResetDimPos(idDim, ptNew, idVPipe); } } else { ModifyPipeByPt(vecPipe, ptNew, ptOld); } } void MovePipe::ModifyPipeByPt(std::vector &vecPipe, XPoint ptNew, XPoint ptOld) { XPoint ptNewOne = ptNew; XPoint ptOldOne = ptOld; ptNewOne.z = 0; ptOldOne.z = 0; AcGeVector3d vtMove = ptNewOne - ptOldOne; vtMove.normalize(); PickSet ssErase(SS_FREE); std::vector::iterator itPipe; DList lstAttachs;// 附件 std::vector vecNewPipe;// 新生成的管线 std::map mapEq;// 设备 AcDbObjectId idCur; for (itPipe = vecPipe.begin(); itPipe != vecPipe.end();) { AcDbObjectId idVPipe; bool bErase = false;//是否删除当前管线 OPENOBJ_BEGIN(*itPipe, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe != NULL) { XPoint ptS, ptE; ptS = pPipe->GetStartPoint(); ptE = pPipe->GetEndPoint(); ptS.z = 0; ptE.z = 0; AcGeVector3d vtS = ptNewOne - ptS; vtS.normalize(); AcGeVector3d vtE = ptNewOne - ptE; vtE.normalize(); AcGeTol tol; tol.setEqualVector(1e-3); if (vtS.isEqualTo(vtMove, tol) && vtE.isEqualTo(vtMove, tol) || vtS.isEqualTo(vtMove, tol) && vtE.isZeroLength(tol) || vtS.isZeroLength(tol) && vtE.isEqualTo(vtMove, tol)) { DList lstAttach; pPipe->GetAttachments(lstAttach); lstAttachs<RemoveAttachment(id); } for (i = 0; i < 2; i++) { AcDbObjectId id = pPipe->GetNode(i); OPENOBJ_BEGIN(id, AcDb::kForRead, TDbEquipment, pEq); if(pEq != NULL) { XPoint ptLoc = pEq->GetLocation(); mapEq.insert(std::make_pair(ptLoc.Distance2d(ptNewOne), id)); } OPENOBJ_END(); } itPipe = vecPipe.erase(itPipe); bErase = true; ssErase += pPipe->id(); } else if ((!vtS.isZeroLength(tol) || !vtE.isZeroLength(tol)) && (vtS.isEqualTo(vtMove, tol) && !vtE.isEqualTo(vtMove, tol) || !vtS.isEqualTo(vtMove, tol) && vtE.isEqualTo(vtMove, tol) || !vtS.isEqualTo(vtMove, tol) && vtE.isZeroLength(tol) || vtS.isZeroLength(tol) && !vtE.isEqualTo(vtMove, tol))) { idCur = pPipe->id(); // 移动端点不在管线端点 if (!(!vtS.isEqualTo(vtMove, tol) && vtE.isZeroLength(tol) || vtS.isZeroLength(tol) && !vtE.isEqualTo(vtMove, tol))) { if (vtS.isEqualTo(vtMove, tol) && !vtE.isEqualTo(vtMove, tol)) { ptNew.z = pPipe->GetStartPoint().z; pPipe->SetStartPoint(ptNew); } else { ptNew.z = pPipe->GetEndPoint().z; pPipe->SetEndPoint(ptNew); } pPipe->downgradeOpen(); idVPipe = CreateVPipe(ptNew, GetVPipeByPt(ptOld)); pPipe->upgradeOpen(); } } } OPENOBJ_END(); if (idVPipe != NULL) { vecNewPipe.push_back(idVPipe); AcDbObjectId idDim = GetVPipeDimByPt(ptOld); if (idDim != NULL) { ResetDimPos(idDim, ptNew, idVPipe); } } if (!bErase) { itPipe++; } } ssErase.Erase(); if (idCur == NULL) { for (int i = 0; i < lstAttachs.Length(); i++) { AcDbObjectId id = *lstAttachs[i]; OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbPipeValve, pValve); if(pValve != NULL) { pValve->SetLocation(ptNewOne); } OPENOBJ_END(); } } else { ResetAttachmentsPos(idCur, lstAttachs); } ReLinkEquipment(mapEq, idCur, vecNewPipe); for (itPipe = vecNewPipe.begin(); itPipe != vecNewPipe.end(); itPipe++) { vecPipe.push_back(*itPipe); } } void MovePipe::ReLinkEquipment(std::map mapEq, AcDbObjectId idPipe, std::vector &vec) { std::map::reverse_iterator it; bool bCreatPipe2Pt = true; double dElev = 0.0; for (it = mapEq.rbegin(); it != mapEq.rend(); it++) { OPENOBJ_BEGIN(it->second, AcDb::kForRead, TDbEquipment, pEq); if(pEq != NULL) { XPoint ptLoc = pEq->GetLocation(); OPENOBJ_BEGIN(idPipe, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL) { XPoint pt = pPipe->GetStartPoint(); if (bCreatPipe2Pt) { bCreatPipe2Pt = false; dElev = ptLoc.z; double d1 = pPipe->GetStartPoint().Distance(ptLoc); double d2 = pPipe->GetEndPoint().Distance(ptLoc); XPoint pt; if (d1 > d2) { pt = pPipe->GetEndPoint(); } else { pt = pPipe->GetStartPoint(); } TDbPipe *pPipeNew = (TDbPipe *)pPipe->clone(); XPoint ptS = pt; ptS.z = dElev; pPipeNew->SetStartPoint(ptS); pPipeNew->SetEndPoint(ptLoc); vec.push_back(AddToCurrentSpace(pPipeNew, Adesk::kTrue)); if (pt.Distance(ptS) > MINDIST) { TDbPipe *pPipeNew1 = (TDbPipe *)pPipe->clone(); pPipeNew1->SetStartPoint(pt); pPipeNew1->SetEndPoint(ptS); vec.push_back(AddToCurrentSpace(pPipeNew1, Adesk::kTrue)); } } if (fabs(dElev - ptLoc.z) > MINDIST) { TDbPipe *pPipeNew = (TDbPipe *)pPipe->clone(); XPoint pt = ptLoc; pt.z = dElev; pPipeNew->SetStartPoint(pt); pPipeNew->SetEndPoint(ptLoc); vec.push_back(AddToCurrentSpace(pPipeNew, Adesk::kTrue)); } } OPENOBJ_END(); } OPENOBJ_END(); } } void MovePipe::ResetAttachmentsPos(const AcDbObjectId idPipe, DList &lstAttachs) { OPENOBJ_BEGIN(idPipe, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe != NULL) { DList lstAttach; pPipe->GetAttachments(lstAttach); lstAttachs<AddAttachments(lstAttachs); XPoint ptMid; ptMid = pPipe->MidPoint(); XPoint ptS = pPipe->GetStartPoint(); ptS.z = 0; XPoint ptE = pPipe->GetEndPoint(); ptE.z = 0; for (int i = 0; i < lstAttachs.Length(); i++) { AcDbObjectId id = *lstAttachs[i]; OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbPipeValve, pValve); if(pValve != NULL) { XPoint ptLoc = pValve->GetLocation(); XPoint ptLow, ptUp; pValve->GetExtents2d(ptLow, ptUp); XPoly2D poly; poly.AppendNode(ptLow); XPoint pt; pt.x = ptUp.x; pt.y = ptLow.y; poly.AppendNode(pt); poly.AppendNode(ptUp); pt.x = ptLow.x; pt.y = ptUp.y; poly.AppendNode(pt); poly.SetClosed(); XPoint ptOnPipe; pPipe->getClosestPointTo(ptLoc, ptOnPipe); ptOnPipe.z = 0; if (ptLoc.Distance2d(ptOnPipe) > MINDIST || ((ptS & poly) == PR_INSIDE)|| ((ptE & poly) == PR_INSIDE))// 附件不在管线上 { pValve->SetLocation(ptMid); } } OPENOBJ_END(); OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbPipeText, pText); if(pText != NULL) { XPoint ptLoc = pText->GetLocation(); XPoint ptOnPipe; pPipe->getClosestPointTo(ptLoc, ptOnPipe); if (ptLoc.Distance2d(ptOnPipe) > MINDIST) { pPipe->RemoveAttachment(id); pText->erase(); } } OPENOBJ_END(); } } OPENOBJ_END(); } AcDbObjectId MovePipe::CreateVPipe(const XPoint ptNew, const AcDbObjectId idOldVPipe) { // 生成立管 AcDbObjectId id; XPoint pt = ptNew; pt.z = 0; std::vector::iterator itPipe; for (itPipe = m_vecPipeMove.begin(); itPipe != m_vecPipeMove.end(); itPipe++) { OPENOBJ_BEGIN(*itPipe, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { XPoint ptOnPipe; pPipe->getClosestPointTo(pt, ptOnPipe); XPoint ptOnLine = ptOnPipe; ptOnLine.z = 0; if (pt.Distance2d(ptOnLine) < MINDIST) { if (ptNew.Distance(ptOnPipe) > MINDIST) { TDbPipe *pPipeNew = NULL; if (idOldVPipe != NULL) { OPENOBJ_BEGIN(idOldVPipe, AcDb::kForRead, TDbPipe, pOldVPipe); pPipeNew = (TDbPipe *)pOldVPipe->clone(); OPENOBJ_END(); } else { pPipeNew = (TDbPipe *)pPipe->clone(); } if (pPipeNew != NULL) { ptOnLine.z = ptNew.z; pPipeNew->SetStartPoint(ptOnLine); pPipeNew->SetEndPoint(ptOnPipe); id= AddToCurrentSpace(pPipeNew, Adesk::kTrue); m_ssMove += id; } } break; } } OPENOBJ_END(); } return id; } void MovePipe::ExtendPipe2Pt(const AcDbObjectId idPipe, XPoint &ptNew, bool bExtendNearPt) { XPoint ptS, ptE; OPENOBJ_BEGIN(idPipe, AcDb::kForWrite, TDbPipe, pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { ptS = pPipe->GetStartPoint(); ptE = pPipe->GetEndPoint(); XPoint ptNear; if ((ptS.Distance2d(ptNew) < ptE.Distance2d(ptNew) && bExtendNearPt) || (ptS.Distance2d(ptNew) > ptE.Distance2d(ptNew) && !bExtendNearPt)) { ptNew.z = ptS.z; pPipe->SetStartPoint(ptNew); ptNear = pPipe->GetEndPoint(); } else { ptNew.z = ptE.z; pPipe->SetEndPoint(ptNew); ptNear = pPipe->GetStartPoint(); } if (!bExtendNearPt)// 管线从远端延长时,重设附件位置 { XPoint ptMid = pPipe->MidPoint(); double dPipeLen = ptNew.Distance2d(ptNear); DList lstAtt; pPipe->GetAttachments(lstAtt); for (int i = 0; i < lstAtt.Length(); i++) { AcDbObjectId id = *lstAtt[i]; OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbPipeValve, pValve); if(pValve != NULL) { XPoint ptLoc = pValve->GetLocation(); AcGeVector3d vt = ptNear - ptLoc; if (dPipeLen > vt.length()) { ptLoc += (vt * 2); pValve->SetLocation(ptLoc); } else { pValve->SetLocation(ptMid); } } OPENOBJ_END(); OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbPipeText, pText); if(pText != NULL) { XPoint ptLoc = pText->GetLocation(); AcGeVector3d vt = ptNear - ptLoc; if (dPipeLen > vt.length()) { ptLoc += (vt * 2); pText->SetLocation(ptLoc); } else { pText->SetLocation(ptMid); } } OPENOBJ_END(); } } } OPENOBJ_END(); } AcDbObjectId MovePipe::GetNearestMovePipe(const AcDbLine &line) { std::vector::iterator itPipe; for (itPipe = m_vecPipeMove.begin(); itPipe != m_vecPipeMove.end(); itPipe++) { OPENOBJ_BEGIN(*itPipe, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { AcGePoint3dArray arry; arry.setLogicalLength(0); XPoint ptS, ptE; ptS = pPipe->GetStartPoint(); ptE = pPipe->GetEndPoint(); ptS.z = 0; ptE.z = 0; AcGeVector3d vtPipe = ptS - ptE; vtPipe.normalize(); ptS += vtPipe * 10; ptE -= vtPipe * 10; AcDbLine linePipe(ptS, ptE); line.intersectWith(&linePipe, AcDb::kExtendThis, arry); if (arry.length() > 0) { return pPipe->id(); } } OPENOBJ_END(); } return NULL; } void MovePipe::MovePipeByPerpendicularVt() { std::vector::iterator it; for (it = m_vecPipeLink.begin(); it != m_vecPipeLink.end(); it++) { XPoint ptS, ptE, pt1, pt2; pt1 = it->ptOnPipe; pt1.z = 0; pt2 = pt1 + it->vtPipe; AcDbLine line(pt1, pt2); AcDbObjectId id = GetNearestMovePipe(line); if (id == NULL) { continue; } ads_name name; acdbGetAdsName(name, id); Entity ent = name; GetPipePoint(ent, ptS, ptE); ptS.z = 0; ptE.z = 0; AcGeVector3d vtPipe = ptS - ptE; vtPipe.normalize(); ptS += vtPipe * 10; ptE -= vtPipe * 10; AcDbLine lineMain(ptS, ptE); AcGePoint3dArray arrys; arrys.setLogicalLength(0); line.intersectWith(&lineMain, AcDb::kExtendThis, arrys); if (arrys.length() < 1) { continue; } pt2 = arrys[0]; if (it->bSideOnPipe) { ModifyPipeBy1Side(it->vecPipeLink, pt2, it->ptOnPipe);// T型管线移动 } else { ModifyPipeBy2Side(it->vecPipeLink, pt2, it->ptOnPipe);// +型管线移动 } } } void MovePipe::ModifyPipeBy2Side(std::vector vecPipe, XPoint ptNew, XPoint ptOld) { bool bOnPipe = false;// 交点是否在联动管线上 AcDbObjectId idNeatestPipe; double dDist = 0.0, dMinDst = 0.0; std::vector::iterator itPipe; for (itPipe = vecPipe.begin(); itPipe != vecPipe.end(); itPipe++) { OPENOBJ_BEGIN(*itPipe, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { XPoint ptOnPipe; pPipe->getClosestPointTo(ptNew, ptOnPipe); dDist = ptNew.Distance2d(ptOnPipe); if (dDist < MINDIST) { bOnPipe = true; idNeatestPipe = pPipe->id(); ptNew.z = ptOnPipe.z; break; } if (idNeatestPipe == NULL || dDist < dMinDst) { idNeatestPipe = pPipe->id(); dMinDst = dDist; ptNew.z = ptOnPipe.z; } } OPENOBJ_END(); } AcDbObjectId idVPipe; AcDbObjectId idDim = GetVPipeDimByPt(ptOld); if (!bOnPipe)// 交点不在联动管线上 { ExtendPipe2Pt(idNeatestPipe, ptNew); } idVPipe = CreateVPipe(ptNew, GetVPipeByPt(ptOld)); if (idDim != NULL && idVPipe != NULL) { ResetDimPos(idDim, ptNew, idVPipe); } } void MovePipe::ResetDimPos(const AcDbObjectId idDim, const XPoint pt, const AcDbObjectId idVPipe) { XPoint ptDim = pt; ptDim.z = 0; OPENOBJ_BEGIN(idDim, AcDb::kForWrite, TDbVPipeDim , pDim); if (pDim != NULL) { XPoint ptTurn = pDim->GetTurnPt(); AcGeVector3d vt = ptTurn - pDim->GetStartPt(); ptTurn = ptDim + vt; pDim->SetTurnPt(ptTurn); pDim->SetStartPt(ptDim); pDim->SetVPipeId(idVPipe); } OPENOBJ_END(); } AcDbObjectId MovePipe::GetVPipeByPt(const XPoint pt) { AcDbObjectId id; XPoint ptPipe = pt; ptPipe.z = 0; RBList rbMask(RTDXF0, _T("ATS_PIPE"), NULL); XPoint pt1, pt2, pt3, pt4; AcGeVector3d vecX = AcGeVector3d::kXAxis; vecX.normalize(); AcGeVector3d vecY = AcGeVector3d::kYAxis; vecY.normalize(); pt1 = ptPipe + vecX * 50; pt1 = pt1 + vecY * 50; pt2 = pt1 - vecX * 100; pt3 = pt2 - vecY * 100; pt4 = pt3 + vecX * 100; PickSet ss(SS_FREE); struct resbuf *pointlist; TADSGePoint3d _pt1 = Wcs2Ucs(pt1) , _pt2 = Wcs2Ucs(pt2) , _pt3 = Wcs2Ucs(pt3) , _pt4 = Wcs2Ucs(pt4); RBList rbPt = acutBuildList(RTPOINT,&_pt1,RTPOINT,&_pt2,RTPOINT,&_pt3, RTPOINT,&_pt4, RTPOINT, &_pt1,NULL); ss.Get(_T("CP"), pointlist, NULL, rbMask); ads_relrb(pointlist); if (ss.Length() == 0) { return NULL; } else { long lLen = ss.Length(); for (long i = 0; i < lLen; ++i) { OPENOBJ_BEGIN(ss[i], AcDb::kForRead, TDbPipe, pPipe); if (pPipe != NULL && pPipe->IsVertical()) { int nIndex = GetPipeLayerIdxBySys(m_typeSys); if (nIndex == GetPipeLayerIdxByName(pPipe->GetLayer())) { return pPipe->id(); } } OPENOBJ_END(); } } return id; } AcDbObjectId MovePipe::GetVPipeDimByPt(const XPoint pt) { AcDbObjectId id; XPoint ptPipe = pt; ptPipe.z = 0; RBList rbMask(RTDXF0, _T("ATS_VPIPEDIM"), NULL); XPoint pt1, pt2, pt3, pt4; AcGeVector3d vecX = AcGeVector3d::kXAxis; vecX.normalize(); AcGeVector3d vecY = AcGeVector3d::kYAxis; vecY.normalize(); pt1 = ptPipe + vecX * 5; pt1 = pt1 + vecY * 5; pt2 = pt1 - vecX * 10; pt3 = pt2 - vecY * 10; pt4 = pt3 + vecX * 10; PickSet ss(SS_FREE); struct resbuf *pointlist; TADSGePoint3d _pt1 = Wcs2Ucs(pt1) , _pt2 = Wcs2Ucs(pt2) , _pt3 = Wcs2Ucs(pt3) , _pt4 = Wcs2Ucs(pt4); RBList rbPt = acutBuildList(RTPOINT,&_pt1,RTPOINT,&_pt2,RTPOINT,&_pt3, RTPOINT,&_pt4, RTPOINT, &_pt1,NULL); ss.Get(_T("CP"), pointlist, NULL, rbMask); ads_relrb(pointlist); if (ss.Length() == 0) { return NULL; } else { long lLen = ss.Length(); for (long i = 0; i < lLen; ++i) { OPENOBJ_BEGIN(ss[i], AcDb::kForRead, TDbVPipeDim, pDim); if (pDim != NULL) { CString csLayer = GetDimLayBySys(m_typeSys); if (csLayer.Compare(pDim->layer()) == 0) { return pDim->id(); } } OPENOBJ_END(); } } return id; } bool MovePipe::IsParallelToPipe(const AcDbObjectId idPipe, const AcDbObjectId idPipeDes, PickSet &ssVist) { if (idPipe == idPipeDes) { return true; } OPENOBJ_BEGIN(idPipe, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL) { AcGeVector3d vtPipe = pPipe->GetStartPoint() - pPipe->GetEndPoint(); XPoint pt1, pt2; ads_name name; acdbGetAdsName(name, idPipeDes); Entity ent = name; GetPipePoint(ent, pt1, pt2); AcGeVector3d vtPipeDes = pt1 - pt2; AcGeTol tol; tol.setEqualVector(1e-3); if (!vtPipe.isParallelTo(vtPipeDes, tol) && !pPipe->IsVertical()) { return false; } else if (pPipe->IsVertical()) { for (int i = 0; i < 2; i++) { AcDbObjectId nodeId(NULL); nodeId = pPipe->GetNode(i); OPENOBJ_BEGIN(nodeId, AcDb::kForRead, TDbPipeNode, pNode); if(pNode != NULL) { int num = pNode->GetInterfaceNum(); for(int j = 0; j < num; j++) { TPipeInterface face; pNode->GetInterface(j, face); AcDbObjectId nextPipeId = face.m_idPipe; OPENOBJ_BEGIN(nextPipeId, AcDb::kForRead, TDbPipe, pPipeNext); if(pPipeNext != NULL) { AcGeVector3d vtPipe = pPipeNext->GetStartPoint() - pPipeNext->GetEndPoint(); tol.setEqualVector(1e-3); if (!vtPipe.isParallelTo(vtPipeDes, tol) && !pPipeNext->IsVertical()) { return false; } } OPENOBJ_END(); } } OPENOBJ_END(); } } ssVist += idPipe; for (int i = 0; i < 2; i++) { AcDbObjectId nodeId(NULL); nodeId = pPipe->GetNode(i); OPENOBJ_BEGIN(nodeId, AcDb::kForRead, TDbPipeNode, pNode); if(pNode != NULL) { int num = pNode->GetInterfaceNum(); for(int j = 0; j < num; j++) { TPipeInterface face; pNode->GetInterface(j, face); AcDbObjectId nextPipeId = face.m_idPipe; ads_name name; acdbGetAdsName(name, nextPipeId); Entity entNow = name; if (nextPipeId == idPipe || entNow.In(&ssVist)) { continue; } if (IsParallelToPipe(nextPipeId, idPipeDes, ssVist)) { return true; } } } OPENOBJ_END(); } } OPENOBJ_END(); return false; } bool MovePipe::IsLinkedWithPipe(const PickSet ssLine, const AcDbObjectId idPipeLinked, PickSet &ssVist, AcGeVector3d &vtPipeLinked, AcGePoint3d &ptOnPipe) { ssVist += idPipeLinked; OPENOBJ_BEGIN(idPipeLinked, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL) { for (int i = 0; i < 2; i++) { AcDbObjectId nodeId(NULL); nodeId = pPipe->GetNode(i); OPENOBJ_BEGIN(nodeId, AcDb::kForRead, TDbPipeNode, pNode); if(pNode != NULL) { int num = pNode->GetInterfaceNum(); for(int j = 0; j < num; j++) { TPipeInterface face; pNode->GetInterface(j, face); AcDbObjectId nextPipeId = face.m_idPipe; ads_name name; acdbGetAdsName(name, nextPipeId); Entity entNow = name; if (entNow.In(&ssLine)) { ptOnPipe = face.m_ptLocation; return true; } if (nextPipeId == idPipeLinked || entNow.In(&ssVist)) { continue; } OPENOBJ_BEGIN(nextPipeId, AcDb::kForRead, TDbPipe, pPipeNow); if(pPipeNow != NULL) { AcGeVector3d vtPipeNow = pPipeNow->GetStartPoint() - pPipeNow->GetEndPoint(); if (vtPipeLinked.x == 0.0 && vtPipeLinked.y == 0.0) { vtPipeLinked = vtPipeNow; } AcGeTol tol; tol.setEqualVector(1e-3); if (!vtPipeLinked.isParallelTo(vtPipeNow, tol) && !pPipeNow->IsVertical()) { continue; } if (IsLinkedWithPipe(ssLine, nextPipeId, ssVist, vtPipeLinked, ptOnPipe)) { return true; } } OPENOBJ_END(); } } OPENOBJ_END(); } } OPENOBJ_END(); return false; }