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

1085 lines
29 KiB
C++

#include "stdafx.h"
#include "SearchPipeSys.h"
//#include "DbObject.h"
#include "DbPool.h"
#include "DbPipe.h"
#include "PipeSystemProcessor.h"
#include "DbPipeFitting.h"
namespace
{
// cet 2015.7.3 add 管线系统索引
int GetPipeSysIndex(const AcDbObjectId &idPipe)
{
return PipeSystemProcessor::GetSysIndex(idPipe);
}
// cet 2015.7.3 add 按系统索引区分管线系统
void PartitionPipes(DList<TPsSide> &lstAllSide, std::map<int, std::vector<TPsSide*> > &mapPipes)
{
int nLen = lstAllSide.Length();
std::vector<TPsSide*> vecId;
for (int i = 0; i < nLen; ++i)
{
if (!lstAllSide[i]->m_pipe.id.isValid() || lstAllSide[i]->m_pipe.id.isErased())
{
continue;
}
int nIndex = GetPipeSysIndex(lstAllSide[i]->m_pipe.id);
if (mapPipes.find(nIndex) != mapPipes.end())
{
mapPipes[nIndex].push_back(lstAllSide[i]);
}
else
{
vecId.clear();
vecId.push_back(lstAllSide[i]);
mapPipes.insert(std::make_pair(nIndex, vecId));
}
}
}
// cet 2015.7.3 add 按系统索引区分管线系统
void PartitionPipes(TPsNode &node, std::map<int, std::vector<AcDbObjectId> > &mapPipes, bool bSplitSys = true)
{
int nLen = node.Length();
std::vector<AcDbObjectId> vecId;
for (int i = 0; i < nLen; ++i)
{
if (!node[i]->m_pipe.id.isValid() || node[i]->m_pipe.id.isErased())
{
continue;
}
int nIndex = GetPipeSysIndex(node[i]->m_pipe.id);
// 不区分系统
if (!bSplitSys)
{
nIndex = 1000;
}
if (mapPipes.find(nIndex) != mapPipes.end())
{
mapPipes[nIndex].push_back(node[i]->m_pipe.id);
}
else
{
vecId.clear();
vecId.push_back(node[i]->m_pipe.id);
mapPipes.insert(std::make_pair(nIndex, vecId));
}
}
}
}
static int ComparePoint(const XPoint *p1, const void *p2)
{
if(*p1==*(const XPoint *)p2)
return 0;
return 1;
}
//////////////////////////////////////////////////////////////////
// TPsNode
// 判断节点是否可以连接边的端点. nPos: 0--start; 1--end
BOOL TPsNode::CanLinkSide(const TPsSide &rSide, int nPos) const
{
BOOL bRet=FALSE;
if(!m_bAutoLiving && IsDbObject() && rSide.IsDbObject()) {
OPENOBJ_BEGIN(m_node.id, AcDb::kForRead, TDbPipeNode, pNode);
if(pNode) {
bRet=pNode->CanLinkSide(rSide.m_pipe.id, nPos);
}
OPENOBJ_END();
} else {
const XPoint &ptRef=nPos? rSide.EndPoint() : rSide.StartPoint();
bRet= m_node.EqualLocation(ptRef);
}
return bRet;
}
void TPsNode::RemovePipeFromDb(const AcDbObjectId &idSide)
{
OPENOBJ_BEGIN(m_node.id,AcDb::kForWrite,TDbPipeNode,pNode);
if(pNode!=NULL) {
pNode->RemoveInterface(idSide);
}
OPENOBJ_END();
}
void TPsNode::ReplacePipeFromDb(const AcDbObjectId &idOld,const AcDbObjectId &idNew)
{
OPENOBJ_BEGIN(m_node.id,AcDb::kForWrite,TDbPipeNode,pNode);
if(pNode!=NULL) {
pNode->ReplaceInterface(idOld,idNew);
}
OPENOBJ_END();
}
// 根据节点对st类型管段的连接
void TPsNode::UpdateLinkage(TPipeSys::SysType st)
{
DList<AcDbObjectId> lstId;
for(int i=0; i<Length(); i++) {
lstId.Append(new AcDbObjectId((*this)[i]->m_pipe.id));
}
OPENOBJ_BEGIN(m_node.id, AcDb::kForWrite, TDbPipeNode, pNode);
if(pNode) {
pNode->UpdateLinkage(m_node.ptLocation,st,lstId);
}
OPENOBJ_END();
}
// TPsNode
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// TPsSide
TPsSide::TPsSide(const AcDbObjectId &id):
m_pStartNode(NULL),m_pEndNode(NULL),m_pipe(id,XPoint(),XPoint())
{
OPENOBJ_BEGIN(m_pipe.id,AcDb::kForRead,TDbPipePrototype,pPipe);
if(pPipe) {
(XDirectionCurve &)(*this)=(XDirectionCurve &)(*pPipe);
XPoint ptMin,ptMax;
pPipe->GetExtend(ptMin,ptMax);
m_pipe.rect.lowLeft=ptMin;
m_pipe.rect.upRight=ptMax;
}
OPENOBJ_END();
}
TPsSide::TPsSide(const TEntRect &pipe):
m_pStartNode(NULL),m_pEndNode(NULL),m_pipe(pipe)
{
OPENOBJ_BEGIN(m_pipe.id, AcDb::kForRead, TDbPipePrototype, pPipe);
if(pPipe) {
(XDirectionCurve &)(*this)=(XDirectionCurve &)(*pPipe);
}
OPENOBJ_END();
}
BOOL TPsSide::IsFullDupSide(const TPsSide &side) const
{
if(m_pipe.id!=side.m_pipe.id) {
if((XDirectionCurve &)side == (XDirectionCurve &)*this)
return TRUE;
}
return FALSE;
}
// 对数据库对象进行合并
BOOL TPsSide::MergeWith(TPsSide &pipeOther, const TPsNode &nodeMerge)
{
if(!IsDbObject() || !pipeOther.IsDbObject())
return FALSE;
ASSERT(m_pStartNode==&nodeMerge || m_pEndNode==&nodeMerge);
ASSERT(pipeOther.m_pStartNode==&nodeMerge || pipeOther.m_pEndNode==&nodeMerge);
BOOL bRet=FALSE;
OPENOBJ_BEGIN(m_pipe.id, AcDb::kForWrite, TDbPipePrototype, pPipeThis);
if(pPipeThis) {
OPENOBJ_BEGIN(pipeOther.m_pipe.id, AcDb::kForWrite, TDbPipePrototype, pPipeOther);
if(pPipeOther) {
if(pPipeThis->MergeWith(*pPipeOther)) {
(XDirectionCurve &)*this = *pPipeThis;
TPsNode *pNode2 = pipeOther.m_pStartNode==&nodeMerge?
pipeOther.m_pEndNode : pipeOther.m_pStartNode;
if(m_pStartNode==&nodeMerge) {
m_pStartNode=pNode2;
} else {
m_pEndNode=pNode2;
}
// 对pipeOther的引用改为对this的引用
TPsNode &rNode=*pNode2;
for(int n=0; n<rNode.Length(); n++) {
if(rNode[n]==&pipeOther) {
// cet 2015.3.31 modify 需要添加索引,否则替换失败
// rNode.Replace(this); //替换
rNode.Replace(this, n);
OPENOBJ_BEGIN(rNode.m_node.id,AcDb::kForWrite,TDbPipeNode,pNode);
if(pNode!=NULL) {
pNode->ReplaceInterface(pipeOther.m_pipe.id,m_pipe.id);
}
OPENOBJ_END();
}
}
bRet=TRUE;
}
}
OPENOBJ_END();
}
OPENOBJ_END();
return bRet;
}
// 更新管线对节点的连接: 位标志0x01-起点;0x02-终点
void TPsSide::UpdateLinkage(int nFlag)
{
if(!IsDbObject())
return;
OPENOBJ_BEGIN(m_pipe.id, AcDb::kForWrite, TDbPipePrototype, pPipe);
if(pPipe) {
if(nFlag&0x01) {
ASSERT(m_pStartNode || m_pStartNode->IsDbObject());
pPipe->SetNode(0, m_pStartNode->m_node.id);
}
if(nFlag&0x02) {
ASSERT(m_pEndNode || m_pEndNode->IsDbObject());
pPipe->SetNode(1, m_pEndNode->m_node.id);
}
}
OPENOBJ_END();
}
// TPsSide
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// TSearchPipeSys
// 初始化系统
void TSearchPipeSys::
InitStart(TPipeSys::SysType st,const DList<TEntRect>& lstPipe,
const DList<TNodeLocation>& lstNode,const XPointList& lstBreak)
{
// 构造节点
int nCount = lstNode.Length();
for(int i=0; i<nCount; i++) {
const TNodeLocation &node=lstNode[i];
OPENOBJ_BEGIN(node.id,AcDb::kForRead,TDbPipeNode,pNode);
if(pNode!=NULL) {
if(pNode->IsAutoLiving()) {
if(IsDupNode(node)) {
m_lstDupNode.Append(new AcDbObjectId(node.id));
} else {
TPsNode *pNode=new TPsNode(node,TRUE);
m_lstAllNode.Append(pNode);
}
} else {
TPsNode *pNode=new TPsNode(node,FALSE);
if(!m_lstAllNode) {
m_lstAllNode.Append(pNode);
} else {
m_lstAllNode[0];
m_lstAllNode.Insert(pNode);
}
}
}
OPENOBJ_END();
}
// 构造管段
nCount=lstPipe.Length();
acedSetStatusBarProgressMeter(_T("管线关系处理中..."), 0, nCount);
for(i=0; i<nCount; i++) {
acedSetStatusBarProgressMeterPos(i);
AddPipe(lstPipe[i],st);
}
acedRestoreStatusBar();
// 添加打断节点
nCount=lstBreak.Length();
for(i=0; i<nCount; i++) {
const XPoint &ptBreak=lstBreak[i];
if(!IsDupNode(ptBreak)) {
TPsNode *pNode=new TPsNode(ptBreak);
m_lstAllNode.Append(pNode);
}
}
}
BOOL TSearchPipeSys::IsFullDupPipe(const XCurveSegment *pSeg) const
{
for(int i=0; i<m_lstAllSide.Length(); i++) {
if(m_lstAllSide[i].IsFullDupSide(pSeg))
return TRUE;
}
return FALSE;
}
BOOL TSearchPipeSys::IsFullDupPipe(const TPsSide &side) const
{
for(int i=0; i<m_lstAllSide.Length(); i++) {
if(m_lstAllSide[i].IsFullDupSide(side))
return TRUE;
}
return FALSE;
}
//从AllNode判断是否为重复节点
BOOL TSearchPipeSys::IsDupNode(const TNodeLocation &node) const
{
for(int i=0; i<m_lstAllNode.Length(); i++) {
if(m_lstAllNode[i].IsDupLocation(node)) //只对隐式节点
return TRUE;
}
return FALSE;
}
BOOL TSearchPipeSys::IsDupNode(const XPoint& pt) const
{
for(int i=0; i<m_lstAllNode.Length(); i++) {
if(m_lstAllNode[i].IsDupLocation(pt))
return TRUE;
}
return FALSE;
}
// 根据pSide提供的id所引用的节点或端点,查找Ps节点。nPos: 0--start; 1--end
TPsNode *TSearchPipeSys::FindPsNodeAt(const TPsSide &rSide, int nPos)
{
TPsNode *pFind=NULL;
for(int i=0; i<m_lstAllNode.Length(); i++) {
TPsNode *node=m_lstAllNode[i];
if(node->CanLinkSide(rSide, nPos)) {
pFind=node;
break;
}
}
return pFind;
}
// 加入管段
void TSearchPipeSys::AddPipe(const TEntRect &pipe,TPipeSys::SysType st)
{
OPENOBJ_BEGIN(pipe.id,AcDb::kForRead,TDbPipePrototype,pPipe);
if(pPipe!=NULL /*&& pPipe->GetSysType()==st*/ && pPipe->GetLength()>_distSnap) { // cet 2015.7.3 modify 不需要比较是否为同一个系统管线,节点处的管线统一处理
if(!m_bOptimize && IsFullDupPipe(pPipe)) {
m_lstDupPipe.Append(new AcDbObjectId(pipe.id));
return;
}
TPsSide *pSide=new TPsSide(pipe);
m_lstAllSide.Append(pSide);
for(int n=0; n<2; n++) {
TPsNode *pNode=FindPsNodeAt(*pSide, n);
if(!pNode) {
pNode=new TPsNode(n? pSide->EndPoint() : pSide->StartPoint());
m_lstAllNode.Append(pNode);
// 非更新区域内的节点
AcDbObjectId idNode=pPipe->GetNode(n);
OPENOBJ_BEGIN(idNode,AcDb::kForRead,TDbPipeNode,pDbNode);
if(pDbNode!=NULL) {
if(pDbNode->GetLocation()==pNode->m_node.ptLocation) {
pNode->m_node.id=idNode;
}
}
OPENOBJ_END();
}
pNode->Append(pSide);
if(n)
pSide->m_pEndNode=pNode;
else
pSide->m_pStartNode=pNode;
}
}
OPENOBJ_END();
}
// 合并管段
void TSearchPipeSys::MergePipes(XPointList &lstCorners, PickSet &ssDel, bool bDelTPsSide)
{
// cet 2015.7.3 modiify 节点处管线先区分系统,再按系统合并管线
// int nLen=m_lstAllNode.Length();
// for(int i=0; i<nLen; i++) {
// if(MergePipeAt(i, lstCorners, ssDel)) {
// i--;
// nLen--;
// }
// }
std::map<int, std::vector<TPsSide*> > mapPipes; // 按系统索引划分管线
std::map<int, std::vector<TPsSide*> >::iterator it, itEnd = mapPipes.end();
int nLen=m_lstAllNode.Length();
for (int i = 0; i < nLen; ++i)
{
TPsNode &node=*m_lstAllNode[i];
if(node.Length() < 2 || !node.IsAutoLiving())
{
continue;
}
// 按系统划分管线
mapPipes.clear();
PartitionPipes(node, mapPipes);
for (it = mapPipes.begin(); it != itEnd; ++it)
{
std::vector<TPsSide*> &vecSide = it->second;
if (vecSide.size() != 2) // 只能合并两条管线
{
continue;
}
bool bMerge = false;
TPsSide &pipe1 = *vecSide[0], &pipe2 =* vecSide[1];
ASSERT(pipe1.IsDbObject() && pipe2.IsDbObject());
if(pipe1.MergeWith(pipe2, node))
{
bMerge = true;
pipe1.m_pipe += pipe2.m_pipe;
ssDel += pipe2.m_pipe.id; //以后再删除
//sr 2009-4-10 立管合并,解决立管标注绑定问题
m_idMapMergeVPipe.SetAt(pipe2.m_pipe.id.asOldId(), pipe1.m_pipe.id.asOldId());
for(int i=0; i<m_lstAllSide.Length(); i++)
{
if(m_lstAllSide[i]==&pipe2)
{
int nDelFlag = node.GetDelFlag();
node.SetDelFlag(0);
for (int j = 0; j < node.Length(); ++j)
{
if (node[j] == &pipe2)
{
node.Remove();
break;
}
}
node.SetDelFlag(nDelFlag);
m_lstAllSide.Remove();
break;
}
}
}
}
}
// 删除端点不在节点TPsNode上的TPsSide(打断管线后执行此操作,不然会将打断点的TPsSide删除)
// 点相等误差容许范围 cet 2017.12.26
double dTol = EqualPointTol();
for (int i = 0; bDelTPsSide && i < m_lstAllNode.Length(); ++i)
{
TPsNode &node=*m_lstAllNode[i];
if (!node.IsAutoLiving())
{
continue;
}
int nFlag = node.GetDelFlag();
node.SetDelFlag(0);
for (int j = 0; j < node.Length(); ++j)
{
XPoint pt1, pt2;
node[j]->GetPoints(pt1, pt2);
if (pt1.Distance(node.m_node.ptLocation) > dTol && pt2.Distance(node.m_node.ptLocation) > dTol)
{
node.Remove();
--j;
}
}
node.SetDelFlag(nFlag);
}
}
// 在第nPos个位置合并管段
// lstCorners -- 发生变化的位置
// 返回: kTrue--合并进行; kFalse--没有合并
// BOOL TSearchPipeSys::MergePipeAt(int nPos, XPointList &lstCorners, PickSet &ssDel)
// {
// ASSERT(nPos>=0 && nPos<m_lstAllNode.Length());
// TPsNode &node=*m_lstAllNode[nPos];
// if(node.Length()!=2 || !node.IsAutoLiving())
// return FALSE;
//
// int nTotalPipes=m_lstAllSide.Length();
// XPoint ptToBeMerged = node.m_node.ptLocation;
// for(int i=0; i<nTotalPipes; i++) {
// TPsSide &pipe=*m_lstAllSide[i];
// if((ptToBeMerged&pipe)==PR_INSIDE) //在某管段内不能合并
// return FALSE;
// }
//
//
// // 仅仅合并处于lstCorners的管段
// int nCornerPos=-1;
// //没有柱子的时候可以用点相等来比较
// if(lstCorners.FindNode(&node.m_node.ptLocation, ComparePoint))
// nCornerPos=lstCorners.CurPosition();
// else
// return FALSE;
//
// TPsSide &pipe1=*node[0], &pipe2=*node[1];
// ASSERT(pipe1.IsDbObject() && pipe2.IsDbObject());
// if(pipe1.MergeWith(pipe2, node)) {
// pipe1.m_pipe += pipe2.m_pipe;
// ssDel += pipe2.m_pipe.id; //以后再删除
// //sr 2009-4-10 立管合并,解决立管标注绑定问题
// m_idMapMergeVPipe.SetAt(pipe2.m_pipe.id.asOldId(), pipe1.m_pipe.id.asOldId());
//
// for(int i=0; i<m_lstAllSide.Length(); i++) {
// if(m_lstAllSide[i]==&pipe2) {
// m_lstAllSide.Remove();
// break;
// }
// }
// //消除本节点
// m_lstAllNode.Remove(nPos);
// if(node.IsDbObject()) {
// OPENOBJ_BEGIN(node.m_node.id, AcDb::kForWrite, AcDbEntity, pEnt);
// if(pEnt)
// pEnt->erase();
// OPENOBJ_END();
// }
// lstCorners.Remove(nCornerPos); //减变化的位置
// return TRUE;
// }
// return FALSE;
// }
// 在给定位置打断管段
void TSearchPipeSys::BreakPipes(XPointList &lstCorners,BOOL bJudge)
{
// cet 2015.7.3 modify 节点处划分系统打断管线
// int nLen=m_lstAllNode.Length();
// for(int i=0; i<nLen; i++) {
// BreakPipeAt(i, lstCorners, bJudge);
// }
std::map<int, std::vector<TPsSide*> > mapPipes; // 按系统索引划分管线
std::map<int, std::vector<TPsSide*> >::iterator it, itEnd;
std::vector<TPsSide*>::iterator itSide, itSideEnd;
int nLen = m_lstAllNode.Length();
for (int i = 0; i < nLen; ++i)
{
TPsNode &node = *m_lstAllNode[i];
if(m_bOptimize) // 优化,只处理自动生成的管线为一个的节点
{
if(node.Length() < 1 || !node.IsAutoLiving())
{
continue;
}
}
else if(bJudge) // 判断条件为自动和非自动生成的节点
{
if(!((node.Length() > 0 && node.IsAutoLiving()) || !node.IsAutoLiving()))
{
continue;
}
}
if(!lstCorners.FindNode(&node.m_node.ptLocation, ComparePoint))
{
continue;
}
// 按系统划分管线
mapPipes.clear();
PartitionPipes(m_lstAllSide, mapPipes);
for (it = mapPipes.begin(), itEnd = mapPipes.end(); it != itEnd; ++it)
{
std::vector<TPsSide*> &vecSide = it->second;
// 获得穿过该节点的管线
PassPointPipes(node.m_node.ptLocation, vecSide);
// 当该节点为自动生成的节点且同一系统的管线只有一根穿过此节点时不打断
if (vecSide.size() == 1 && node.IsAutoLiving())
{
continue;
}
for (itSide = vecSide.begin(), itSideEnd = vecSide.end(); itSide != itSideEnd; ++itSide)
{
TPsSide *pPipe = *itSide;
if(node.m_node.Intersect(pPipe->m_pipe))
{
if(!pPipe->m_pStartNode || !pPipe->m_pEndNode)
{
adsout << _T("\n严重警告: 管线的位置关系发生错乱! ");
throw pPipe;
continue;
}
ASSERT(pPipe->IsDbObject());
OPENOBJ_BEGIN(pPipe->m_pipe.id,AcDb::kForWrite,TDbPipePrototype,pDbPipe);
if(pDbPipe != NULL)
{
AcDbObjectId idNewPipe=pDbPipe->BreakAt(node.m_node.ptLocation,PS_SNAP);
if(idNewPipe.isValid())
{
UpdateLinkageOnBreak(pDbPipe,*pPipe,node,idNewPipe);
}
}
OPENOBJ_END();
}
}
}
}
}
void TSearchPipeSys::BreakPipeAt(int nPos, XPointList &lstCorners,BOOL bJudge)
{
TPsNode &node=*m_lstAllNode[nPos];
/*if(node.Length()!=1 || !node.IsAutoLiving())
return FALSE;*/
if(m_bOptimize) { //优化,只处理自动生成的管线为一个的节点
if(node.Length()!=1 || !node.IsAutoLiving())
return;
} else if(bJudge) {// 判断条件为自动和非自动生成的节点
if(!((node.Length()>0&&node.IsAutoLiving()) || !node.IsAutoLiving()))
return;
}
if(!lstCorners.FindNode(&node.m_node.ptLocation, ComparePoint))
return;
int nSide=m_lstAllSide.Length();
for(int nIdx=0; nIdx<nSide; nIdx++) {
TPsSide *pPipe = m_lstAllSide[nIdx];
if(node.m_node.Intersect(pPipe->m_pipe)) {
if(!pPipe->m_pStartNode || !pPipe->m_pEndNode) {
adsout << _T("\n严重警告: 管线的位置关系发生错乱! ");
throw pPipe;
continue;
}
ASSERT(pPipe->IsDbObject());
OPENOBJ_BEGIN(pPipe->m_pipe.id,AcDb::kForWrite,TDbPipePrototype,pDbPipe);
if(pDbPipe!=NULL) {
AcDbObjectId idNewPipe=pDbPipe->BreakAt(node.m_node.ptLocation,PS_SNAP);
if(idNewPipe.isValid()) {
UpdateLinkageOnBreak(pDbPipe,*pPipe,node,idNewPipe);
}
}
OPENOBJ_END();
}
}
}
// 更新打断管线的连接,判断新管段是否有重合的管段,
// 若有则删除,同时更新连接关系
// pSide和side是同一管线
void TSearchPipeSys::UpdateLinkageOnBreak(TDbPipePrototype *pSide,TPsSide &side,
TPsNode &node,AcDbObjectId& idNewPipe)
{
(XDirectionCurve &)(side) = (XDirectionCurve &)(*pSide);
TPsNode &updEndNode=*side.m_pEndNode;// 新打断的管段
OPENOBJ_BEGIN(idNewPipe,AcDb::kForRead,TDbPipePrototype,pPipe);
if(pPipe!=NULL) {
if(IsFullDupPipe(pPipe)) { // 是重合管线
if(pPipe->upgradeOpen()==Acad::eOk) {
pPipe->erase();
pPipe->downgradeOpen();
}
for(int n=0; n<updEndNode.Length(); n++) {
if(updEndNode[n]==&side) {
updEndNode.Remove();
updEndNode.RemovePipeFromDb(side.m_pipe.id);
break;
}
}
} else { // 非重合管线
XPoint ptMin,ptMax;
pPipe->GetExtend(ptMin,ptMax);
TEntRect pipeRect(idNewPipe,ptMin,ptMax);
TPsSide *pNewSide = new TPsSide(pipeRect);
m_lstAllSide.Append(pNewSide);
pNewSide->m_pStartNode = &node;
pNewSide->m_pEndNode = side.m_pEndNode;
for(int n=0; n<updEndNode.Length(); n++) {
if(updEndNode[n]==&side) {
// updEndNode.Replace(pNewSide); cet 2015.4.1 modify 需要添加索引,否则替换失败
updEndNode.Replace(pNewSide, n);
updEndNode.ReplacePipeFromDb(side.m_pipe.id,idNewPipe);
break;
}
}
node.Append(pNewSide);
}
}
OPENOBJ_END();
// 被打断的管段
if(IsFullDupPipe(side)) {
TPsNode &updStartNode=*side.m_pStartNode;
for(int n=0; n<updStartNode.Length(); n++) {
if(updStartNode[n]==&side) {
updStartNode.Remove();
updStartNode.RemovePipeFromDb(side.m_pipe.id);
break;
}
}
pSide->erase();
} else {
side.m_pEndNode=&node;
node.Append(&side);
}
}
// 更新节点的连接信息
void TSearchPipeSys::UpdateNodeLinkage(TPipeSys::SysType st, const XRectAngle *box)
{
for(int i=0; i<m_lstAllNode.Length(); i++) {
TPsNode &node=*m_lstAllNode[i];
if(!node.IsDbObject())
continue;
BOOL bInBox=FALSE;
if(box) {
if(node.IsAutoLiving()) {
if(PointInBox02d(node.m_node.ptLocation,*box)) {
bInBox=TRUE;
}
} else {
OPENOBJ_BEGIN(node.m_node.id, AcDb::kForRead, TDbPipeNode, pNode);
if(pNode) {
if(pNode->IsVisible()) {
XPoint ptMin,ptMax;
///////////////////////////////////////////////////SR ADD 考虑化粪池情况 2011-11-10
if(pNode->IsDrawBlock()) {
XPoint ptLocation=pNode->GetLocation();
TDbPool *pPool = TDbPool::cast(pNode);
if (pPool != NULL)
{
double dPoolLen = pPool->GetPoolLength();
double dPoolWidth = pPool->GetPoolWidth();
double dLen = pow(dPoolLen*dPoolLen + dPoolWidth*dPoolWidth,0.5);//double dLen = pow(dPoolLen*dPoolLen + dPoolWidth*dPoolWidth,0.5) + 100;
XPoint ptPool(dLen/2.0, dLen/2.0, 0.0); //sr 范围减半 XPoint ptPool(dLen, dLen, 0.0); 2011-11-10
ptMin=ptLocation-ptPool;
ptMax=ptLocation+ptPool;
}
if(ExtendInBox02d(ptMin, ptMax, *box))
bInBox=TRUE;
}
/////////////////////////////////////////////////
if(!bInBox && pNode->GetExtents(ptMin,ptMax)==Acad::eOk) {
if(ExtendInBox02d(ptMin,ptMax,*box)) {
bInBox=TRUE;
}
}
}
else {//不可见的节点的判断
XPoint ptLocation = pNode->GetLocation();
if(PointInBox02d(ptLocation,*box)) {
bInBox=TRUE;
}
}
}
OPENOBJ_END();
}
} else
bInBox=TRUE;
if(bInBox) {
node.UpdateLinkage(st);
}
}
}
// 更新管线的连接信息
void TSearchPipeSys::UpdatePipeLinkage(const XRectAngle *box)
{
for(int i=0; i<m_lstAllSide.Length(); i++) {
TPsSide &side=*m_lstAllSide[i];
if(!side.IsDbObject())
continue;
if(box) {
XPoint pt1, pt2;
side.GetPoints(pt1, pt2);
pt1.z=pt2.z=0;
int nFlag1=(pt1&(*box));
int nFlag2=(pt2&(*box));
if(nFlag1==PR_INSIDE) {
side.UpdateLinkage(0x01);
}
if(nFlag2==PR_INSIDE) {
side.UpdateLinkage(0x02);
}
} else {
side.UpdateLinkage(0x03);
}
}
}
BOOL TSearchPipeSys::DelNodeFromDb(const AcDbObjectId& id,const XRectAngle& box)
{
OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbPipeNode, pNode);
if(pNode) {
XPoint pt2d=pNode->GetLocation();
pt2d.z=0;
int nFlag=(pt2d&box);
if(nFlag==PR_INSIDE){
pNode->erase();
return TRUE;
}
}
OPENOBJ_END();
return FALSE;
}
BOOL TSearchPipeSys::DelPipeFromDb(const AcDbObjectId& id,const XRectAngle& box)
{
OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbPipePrototype, pPipe);
if(pPipe) {
XPoint ptMin,ptMax;
if(pPipe->GetExtend(ptMin,ptMax)) {
XRectAngle boxPipe(ptMin,ptMax);
int nFlag=(boxPipe&box);
if(nFlag==PR_INSIDE){
pPipe->erase();
return TRUE;
}
}
}
OPENOBJ_END();
return FALSE;
}
void TSearchPipeSys::DelDupNodeFromDb(const XRectAngle& box)
{
for(int i=0; i<m_lstDupNode.Length(); i++) {
if(DelNodeFromDb(*m_lstDupNode[i],box)) {
m_lstDupNode.Remove();
i--;
}
}
}
void TSearchPipeSys::DelDupPipeFromDb(const XRectAngle& box)
{
for(int i=0; i<m_lstDupPipe.Length(); i++) {
if(DelPipeFromDb(*m_lstDupPipe[i],box)) {
m_lstDupPipe.Remove();
i--;
}
}
}
// 移除孤立的节点
void TSearchPipeSys::DelSoleNodeFromDb(TPipeSys::SysType st,const XRectAngle *box)
{
for(int i=0; i<m_lstAllNode.Length(); i++)
{
TPsNode &node=*m_lstAllNode[i];
if(node.IsDbObject() && node.IsAutoLiving())
{
BOOL bDel=TRUE;
if(box)
{
XPoint pt2d=node.m_node.ptLocation;
pt2d.z=0;
int nFlag=(pt2d&(*box));
if(nFlag!=PR_INSIDE)
bDel=FALSE;
}
if(bDel)
{
OPENOBJ_BEGIN(node.m_node.id, AcDb::kForRead, TDbPipeNode, pNode);
if(pNode && pNode->IsAutoLiving())
{
// 本身是否还有有效连接
bool bVaildLink = false;
for (int j = 0; j < pNode->GetInterfaceNum() && !bVaildLink; ++j)
{
const TPipeInterface &face = pNode->GetInterface(j);
OPENOBJ_BEGIN(face.m_idPipe, AcDb::kForRead, TDbPipePrototype, pPipe);
if (pPipe != NULL)
{
double dTol = 0.001;
if (face.m_ptLocation.Distance(pPipe->StartPoint()) < dTol ||
face.m_ptLocation.Distance(pPipe->EndPoint()) < dTol)
{
bVaildLink = true;
break;
}
}
OPENOBJ_END();
}
// 没有连接实体了,删除节点
if (!bVaildLink && pNode->upgradeOpen() == Acad::eOk)
{
pNode->erase();
node.m_node.id = AcDbObjectId::kNull;
pNode->downgradeOpen();
}
}
OPENOBJ_END();
}
}
}
}
void TSearchPipeSys::DelAllNodeFromDb(const XRectAngle *box/*=NULL*/)
{
for(int i = 0; i< m_lstAllNode.Length(); i++)
{
TPsNode &node = *m_lstAllNode[i];
if(node.IsDbObject())
{
BOOL bDel=TRUE;
if(box != NULL)
{
XPoint pt2d=node.m_node.ptLocation;
pt2d.z=0;
int nFlag=(pt2d&(*box));
if(nFlag!=PR_INSIDE)
bDel=FALSE;
}
if(bDel)
{
// 只删除自动生成的对象
OPENOBJ_BEGIN(node.m_node.id, AcDb::kForWrite, TDbPipeFitting, pNode);
if(pNode && pNode->IsAutoLiving())
{
pNode->erase();
node.m_node.id = AcDbObjectId::kNull;
}
OPENOBJ_END();
}
}
}
// 删除重复节点
DelDupNodeFromDb(*box);
}
// 自动节点加入数据库
void TSearchPipeSys::AddAutoNodeToDb(const XRectAngle *box)
{
// cet 2015.7.3 modify 节点处的管线按系统分类生成连接件
// for(int i=0; i<m_lstAllNode.Length(); i++) {
// TPsNode &node=*m_lstAllNode[i];
// if(node.Length() && !node.IsDbObject()) {
// BOOL bAdd=TRUE;
// if(box) {
// XPoint pt2d=node.m_node.ptLocation;
// pt2d.z=0;
// int nFlag=(pt2d&(*box));
// if(nFlag!=PR_INSIDE)
// bAdd=FALSE;
// }
// if(bAdd) {
// DList<AcDbObjectId> lstId;
// for(int n=0; n<node.Length(); n++) {
// TPsSide *pSide=node[n];
// if(pSide->IsDbObject())
// lstId.Append(new AcDbObjectId(pSide->m_pipe.id));
// }
// TPsSide *side=node.Head();
// OPENOBJ_BEGIN(side->m_pipe.id, AcDb::kForRead, TDbPipePrototype, pPipe);
// if(pPipe) {
// AcDbObjectId idNew=pPipe->AddAutoNodeToDb(node.m_node.ptLocation, lstId);
// node.m_node.id = idNew;
// }
// OPENOBJ_END();
// }
// }
// }
std::map<int, std::vector<AcDbObjectId> >::iterator it, itEnd;
std::vector<AcDbObjectId>::iterator itId, itIdEnd;
for(int i = 0; i < m_lstAllNode.Length(); i++)
{
TPsNode &node=*m_lstAllNode[i];
if(node.Length() == 0 || node.IsDbObject())
{
continue;
}
BOOL bAdd=TRUE;
if(box != NULL)
{
XPoint pt2d=node.m_node.ptLocation;
pt2d.z=0;
int nFlag=(pt2d&(*box));
if(nFlag!=PR_INSIDE)
bAdd=FALSE;
}
if(bAdd)
{
// 按系统区分管线
std::map<int, std::vector<AcDbObjectId> > mapPipes;
// cet 2016-07-29 不同系统存在通过连接件相互连接的情况,所以不在区分系统创建连接件
PartitionPipes(node, mapPipes, false);
for (it = mapPipes.begin(), itEnd = mapPipes.end(); it != itEnd; ++it)
{
DList<AcDbObjectId> lstId;
for (itId = it->second.begin(), itIdEnd = it->second.end(); itId != itIdEnd; ++itId)
{
lstId.Append(new AcDbObjectId(*itId));
}
AcDbObjectId idNew = AcDbObjectId::kNull;
TPipeSys::SysType st;
OPENOBJ_BEGIN(*lstId[0], AcDb::kForWrite, TDbPipePrototype, pPipe);
if(pPipe != NULL)
{
idNew = pPipe->AddAutoNodeToDb(node.m_node.ptLocation, lstId);
st = pPipe->GetSysType();
}
OPENOBJ_END();
// 更新节点,利用管线创建节点时,此管线在创建节点时无法更新到节点信息中(管线在此已经打开,在节点中再次打开时失败)
OPENOBJ_BEGIN(idNew, AcDb::kForWrite, TDbPipeNode, pNode);
if (pNode != NULL)
{
pNode->UpdateLinkage(node.m_node.ptLocation, st, lstId);
}
OPENOBJ_END();
// 创建新节点,用于更新管线与节点关联关系
TPsNode *pNewNode = new TPsNode(node.m_node, TRUE);
pNewNode->m_node.id = idNew;
m_lstNewNode.Append(pNewNode);
// 更新管线端点连接件
int nLen = lstId.Length();
for (int i = 0; i < nLen; ++i)
{
OPENOBJ_BEGIN(*lstId[i], AcDb::kForWrite, TDbPipePrototype, pPipe);
if(pPipe != NULL)
{
if(node.m_node.ptLocation.Distance(pPipe->StartPoint()) < 0.001)
{
pPipe->SetNode(0, idNew);
UpdateTPsSideNode(0, pPipe->id(), pNewNode);
}
else
{
pPipe->SetNode(1, idNew);
UpdateTPsSideNode(1, pPipe->id(), pNewNode);
}
}
OPENOBJ_END();
}
}
}
}
}
void TSearchPipeSys::UpdateTPsSideNode(int nPos, const AcDbObjectId &idPipe, TPsNode *pNode)
{
int nLen = m_lstAllSide.Length();
for(int i = 0; i < nLen; ++i)
{
TPsSide &side = *m_lstAllSide[i];
if (side.m_pipe.id != idPipe)
{
continue;
}
if (nPos == 0)
{
side.m_pStartNode = pNode;
}
else
{
side.m_pEndNode = pNode;
}
break;
}
}
void TSearchPipeSys::PassPointPipes(XPoint pt, std::vector<TPsSide*> &vecSide)
{
// 点相等误差容许范围 cet 2017.12.26
double dTol = EqualPointTol();
std::vector<TPsSide*> vtTemp;
std::vector<TPsSide*>::iterator it, itEnd = vecSide.end();
XPoint pt1, pt2;
for (it = vecSide.begin(); it != itEnd; ++it)
{
(*it)->GetPoints(pt1, pt2);
if ((fabs((*it)->GetBulge()) < 0.001) && fabs(pt.Distance(pt1) + pt.Distance(pt2) - pt1.Distance(pt2)) < dTol) // 直线
{
vtTemp.push_back(*it);
}
else if (fabs((*it)->GetBulge()) > 0.001) // 弧线
{
XPoint ptRet;
(*it)->ProjectToMe(pt, ptRet);
if (ptRet.Distance(pt) < dTol)
{
vtTemp.push_back(*it);
}
}
}
vecSide = vtTemp;
}