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

1328 lines
31 KiB
C++

// 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<AcDbObjectId> 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<PipeLinkedInfo>::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<PipeLinkedInfo>::iterator it;
for (it = m_vecPipeLink.begin(); it != m_vecPipeLink.end(); it++)
{
std::vector<AcDbObjectId>::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]:<Y>"), 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<int> 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<PipeLinkedInfo>::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<PipeLinkedInfo>::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<PipeLinkedInfo>::iterator it;
std::vector<AcDbObjectId>::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<AcDbObjectId>::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<AcDbObjectId> &vecPipe, XPoint ptNew, XPoint ptOld)
{
bool bOnPipe = false;// 交点是否在联动管线上
AcDbObjectId idNeatestPipe;
bool bExtendThis = true; // 是否从近端延长管线
ptOld.z = 0;
std::vector<AcDbObjectId>::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<AcDbObjectId> &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<AcDbObjectId>::iterator itPipe;
DList<AcDbObjectId> lstAttachs;// 附件
std::vector<AcDbObjectId> vecNewPipe;// 新生成的管线
std::map<double, AcDbObjectId> 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<AcDbObjectId> lstAttach;
pPipe->GetAttachments(lstAttach);
lstAttachs<<lstAttach;
for (int i = 0; i < lstAttachs.Length(); i++)
{
AcDbObjectId id = *lstAttachs[i];
pPipe->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<double, AcDbObjectId> mapEq, AcDbObjectId idPipe, std::vector<AcDbObjectId> &vec)
{
std::map<double, AcDbObjectId>::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<AcDbObjectId> &lstAttachs)
{
OPENOBJ_BEGIN(idPipe, AcDb::kForWrite, TDbPipe, pPipe);
if(pPipe != NULL)
{
DList<AcDbObjectId> lstAttach;
pPipe->GetAttachments(lstAttach);
lstAttachs<<lstAttach;
pPipe->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<AcDbObjectId>::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<AcDbObjectId> 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<AcDbObjectId>::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<PipeLinkedInfo>::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<AcDbObjectId> vecPipe, XPoint ptNew, XPoint ptOld)
{
bool bOnPipe = false;// 交点是否在联动管线上
AcDbObjectId idNeatestPipe;
double dDist = 0.0, dMinDst = 0.0;
std::vector<AcDbObjectId>::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;
}