613 lines
14 KiB
C++
613 lines
14 KiB
C++
#include "StdAfx.h"
|
|
#include "DrawDrainChamfer.h"
|
|
|
|
// 返回值表示次管道是否修改
|
|
bool CDrawDrainChamfer::GetChamferInfo(const AcDbObjectId &IdPipeM, const AcDbObjectId &idPipeBra, std::map<AcDbObjectId,AcGePoint3dArray> &dataMap, double dChamferLen)
|
|
{
|
|
// 打开次管道获得起点终点
|
|
TDbPipe *pPipe1 = NULL, *pPipe2 = NULL;
|
|
AcGePoint3d ptS1, ptS2, ptE1, ptE2;
|
|
acdbOpenObject(pPipe2, idPipeBra, AcDb::kForRead);
|
|
if (pPipe2 != NULL)
|
|
{
|
|
if (pPipe2->GetFlowDir() == TPipeSys::kFromStart)
|
|
{
|
|
pPipe2->getStartPoint(ptS2);
|
|
pPipe2->getEndPoint(ptE2);
|
|
}
|
|
else
|
|
{
|
|
pPipe2->getStartPoint(ptE2);
|
|
pPipe2->getEndPoint(ptS2);
|
|
}
|
|
pPipe2->close();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 获得主管道起点终点
|
|
std::map<AcDbObjectId,AcGePoint3dArray>::iterator it;
|
|
it = dataMap.find(IdPipeM);
|
|
if (it != dataMap.end())
|
|
{
|
|
ptS1 = (*it).second[0];
|
|
ptE1 = (*it).second[1];
|
|
}
|
|
else
|
|
{
|
|
acdbOpenObject(pPipe1, IdPipeM, AcDb::kForRead);
|
|
if (pPipe1 != NULL)
|
|
{
|
|
if (pPipe1->GetFlowDir() == TPipeSys::kFromStart)
|
|
{
|
|
pPipe1->getStartPoint(ptS1);
|
|
pPipe1->getEndPoint(ptE1);
|
|
}
|
|
else
|
|
{
|
|
pPipe1->getStartPoint(ptE1);
|
|
pPipe1->getEndPoint(ptS1);
|
|
}
|
|
pPipe1->close();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
AcGeVector3d vt1 = ptE1 - ptS1, vt2 = ptE2 - ptS2 ;
|
|
AcGeTol tol;
|
|
tol.setEqualVector(1e-3);
|
|
if (vt1.isParallelTo(vt2, tol)) // 共线
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 获得倒角值
|
|
double dLen = ptS1.distanceTo(ptE1);
|
|
if (dLen < 1e-3)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (dLen < dChamferLen)
|
|
{
|
|
dChamferLen = dLen;
|
|
}
|
|
|
|
vt1.normalize();
|
|
vt2.normalize();
|
|
ptS1 += vt1 * dChamferLen;
|
|
ptE2 -= vt2 * dChamferLen;
|
|
AcGePoint3dArray arPt;
|
|
arPt.append(ptS2); // 按流向依次存入
|
|
arPt.append(ptE2);
|
|
arPt.append(ptS1);
|
|
it = dataMap.find(idPipeBra);
|
|
if (it == dataMap.end())
|
|
{
|
|
dataMap.insert(std::make_pair(idPipeBra, arPt));
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CDrawDrainChamfer::IsVerticalPipe(const AcDbObjectId &id)
|
|
{
|
|
bool bRet = false;
|
|
TDbPipe *pPipe = NULL;
|
|
acdbOpenObject(pPipe, id, AcDb::kForRead);
|
|
if (pPipe != NULL)
|
|
{
|
|
if (pPipe->IsVertical())
|
|
{
|
|
bRet = true;
|
|
}
|
|
pPipe->close();
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
// 判断管线是否在选择集中
|
|
bool CDrawDrainChamfer::IsValidPipe(PickSet &ssAll, AcDbObjectId &id)
|
|
{
|
|
ads_name sname;
|
|
acdbGetAdsName(sname, id);
|
|
Entity ent(sname);
|
|
return ssAll.IsInclude(ent);
|
|
}
|
|
|
|
// 节点上所有的次管道是否在选择集内
|
|
bool CDrawDrainChamfer::IsAllVaildPipe(PickSet &ssAll, SSearchPipeList *pLst)
|
|
{
|
|
if (pLst == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
int nNum = pLst->m_lstNode.Length();
|
|
for(int i = 0; i < nNum; i++)
|
|
{
|
|
ads_name sname;
|
|
acdbGetAdsName(sname, pLst->m_lstNode[i]->m_ID);
|
|
Entity ent(sname);
|
|
if (!ssAll.IsInclude(ent))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// 是否有次管道与主管道共线
|
|
bool CDrawDrainChamfer::IsExistOnLine(AcDbObjectId &id, SSearchPipeList *pLst, SSearchPipeList *&pLstOut)
|
|
{
|
|
if (pLst != NULL)
|
|
{
|
|
TDbPipe *pPipe = NULL;
|
|
AcGePoint3d ptS, ptE;
|
|
acdbOpenObject(pPipe, id, AcDb::kForRead);
|
|
if (pPipe != NULL)
|
|
{
|
|
pPipe->getStartPoint(ptS);
|
|
pPipe->getEndPoint(ptE);
|
|
pPipe->close();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
AcGeVector3d vt = ptS - ptE;
|
|
int nNum = pLst->m_lstNode.Length();
|
|
AcGePoint3d pt1, pt2;
|
|
AcGeTol tol;
|
|
tol.setEqualVector(1e-3);
|
|
for(int i = 0; i < nNum; i++)
|
|
{
|
|
pPipe = NULL;
|
|
acdbOpenObject(pPipe, pLst->m_lstNode[i]->m_ID, AcDb::kForRead);
|
|
if (pPipe != NULL)
|
|
{
|
|
pPipe->getStartPoint(pt1);
|
|
pPipe->getEndPoint(pt2);
|
|
pPipe->close();
|
|
|
|
AcGeVector3d vt1 = pt2 - pt1;
|
|
if (vt.isParallelTo(vt1, tol))
|
|
{
|
|
pLstOut = pLst->m_lstNode[i];
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// 两管是否共线
|
|
bool CDrawDrainChamfer::IsOnSameLine(const AcDbObjectId &id1, const AcDbObjectId &id2)
|
|
{
|
|
TDbPipe *pPipe1 = NULL, *pPipe2 = NULL;
|
|
AcGePoint3d ptS1, ptS2, ptE1, ptE2;
|
|
Acad::ErrorStatus st = acdbOpenObject(pPipe1, id1, AcDb::kForRead);
|
|
if (pPipe1 != NULL)
|
|
{
|
|
pPipe1->getStartPoint(ptS1);
|
|
pPipe1->getEndPoint(ptE1);
|
|
pPipe1->close();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
st = acdbOpenObject(pPipe2, id2, AcDb::kForRead);
|
|
if (pPipe2 != NULL)
|
|
{
|
|
pPipe2->getStartPoint(ptS2);
|
|
pPipe2->getEndPoint(ptE2);
|
|
pPipe2->close();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
AcGeVector3d vt1 = ptE1 - ptS1, vt2 = ptE2 - ptS2;
|
|
vt1.normalize();
|
|
vt2.normalize();
|
|
AcGeTol tol;
|
|
tol.setEqualVector(1e-3);
|
|
if (vt1.isParallelTo(vt2, tol)) // 共线
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// 管道长度是否大于倒角长度
|
|
bool CDrawDrainChamfer::IsOverChamferLen(AcDbObjectId &id, double dChamferLen)
|
|
{
|
|
TDbPipe *pPipe = NULL;
|
|
acdbOpenObject(pPipe, id, AcDb::kForRead);
|
|
if (pPipe != NULL)
|
|
{
|
|
AcGePoint3d ptS, ptE;
|
|
pPipe->getStartPoint(ptS);
|
|
pPipe->getEndPoint(ptE);
|
|
pPipe->close();
|
|
|
|
if (ptS.distanceTo(ptE) > dChamferLen)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// 根据管道流向确定需要修改的管道id和修改后管道的起点终点以及倒角的起点终点
|
|
// 如果map中点数组的长度为2,则直接使用两点设置对应管道起始点即可
|
|
// 长度为3,则1和2点用途同上,2和3两点用于生成一段新管道(倒角)
|
|
void CDrawDrainChamfer::GetPipeMap(SSearchPipeList *pListAll, std::map<AcDbObjectId,AcGePoint3dArray> &dataMap, double dChamferLen, PickSet &ssAll, std::vector<AcDbObjectId> &vecId)
|
|
{
|
|
if (pListAll->m_iType == 0)
|
|
{
|
|
TDbPipe *pPipe = NULL;
|
|
acdbOpenObject(pPipe, pListAll->m_ID, AcDb::kForRead);
|
|
if (pPipe != NULL)
|
|
{
|
|
AcGePoint3d pt;
|
|
BOOL bVPipe = pPipe->IsVertical();
|
|
if (pPipe->GetFlowDir() == TPipeSys::kFromStart)
|
|
{
|
|
pPipe->getStartPoint(pt);
|
|
}
|
|
else
|
|
{
|
|
pPipe->getEndPoint(pt);
|
|
}
|
|
pPipe->close();
|
|
|
|
if (bVPipe) // 立管
|
|
{
|
|
int nLen = pListAll->m_lstNode.Length();
|
|
for(int i = 0; i < nLen; i++)
|
|
{
|
|
GetPipeMap(pListAll->m_lstNode[i], dataMap, dChamferLen, ssAll, vecId);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SSearchPipeList *pLst = NULL;
|
|
GetFristPipeNode(pListAll, pLst);
|
|
if (pLst != NULL)
|
|
{
|
|
int nNum = pLst->m_lstNode.Length();
|
|
bool bVertical = false; // 次管道是否有立管
|
|
|
|
//节点处是否有立管
|
|
for(int j = 0; j < nNum; j++)
|
|
{
|
|
SSearchPipeList *pLstTmp = pLst->m_lstNode[j];
|
|
if (IsVerticalPipe(pLstTmp->m_ID))
|
|
{
|
|
bVertical = true;
|
|
}
|
|
}
|
|
|
|
bool bValidM = IsValidPipe(ssAll, pListAll->m_ID); // 主管道是否在集合内
|
|
SSearchPipeList *pLstOut = NULL; // 与主管道共线的次管道分支
|
|
bool bOnLine = IsExistOnLine(pListAll->m_ID, pLst, pLstOut); // 是否有次管道与主管道共线
|
|
bool bAllValid = IsAllVaildPipe(ssAll, pLst); // 是否所有次管道都在选择集内
|
|
int nPipe = 0; // 修改的次管道个数
|
|
double dMin = dChamferLen; // 被修改的次管道最小长度(长度小于倒角长度)
|
|
|
|
// 获得需要修改的次管道的最小长度
|
|
if (!bVertical)
|
|
{
|
|
GetMinPipeLen(pLst, ssAll, pListAll->m_ID, dMin);
|
|
if (dMin > dChamferLen)
|
|
{
|
|
dMin = dChamferLen;
|
|
}
|
|
}
|
|
|
|
if (bValidM)
|
|
{
|
|
for (int i = 0; i < nNum; i++)
|
|
{
|
|
SSearchPipeList *pLstTmp = pLst->m_lstNode[i];
|
|
if (!bVertical && IsValidPipe(ssAll, pLstTmp->m_ID))
|
|
{
|
|
if (GetChamferInfo(pListAll->m_ID, pLstTmp->m_ID, dataMap, dMin))
|
|
{
|
|
nPipe++;
|
|
}
|
|
}
|
|
GetPipeMap(pLstTmp, dataMap, dChamferLen, ssAll, vecId);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < nNum; i++)
|
|
{
|
|
SSearchPipeList *pLstTmp = pLst->m_lstNode[i];
|
|
if (!bVertical && IsValidPipe(ssAll, pLstTmp->m_ID))
|
|
{
|
|
if (bAllValid && bOnLine || !bAllValid)
|
|
{
|
|
if (GetChamferInfo(pListAll->m_ID, pLstTmp->m_ID, dataMap, dMin))
|
|
{
|
|
nPipe++;
|
|
}
|
|
}
|
|
}
|
|
GetPipeMap(pLstTmp, dataMap, dChamferLen, ssAll, vecId);
|
|
}
|
|
}
|
|
|
|
// 处理多余管道(与主管道共线的次管道)
|
|
bool bDel = false;
|
|
if (!bVertical && bValidM && bAllValid && bOnLine && pLstOut != NULL && nPipe == nNum - 1) // 存在与主管道共线次管道
|
|
{
|
|
if (pLstOut->m_lstNode.Length() == 1 && pLstOut->m_lstNode[0]->m_lstNode.Length() == 0)
|
|
{
|
|
if (!IsOverChamferLen(pLstOut->m_ID, dChamferLen))
|
|
{
|
|
vecId.push_back(pLstOut->m_ID);
|
|
bDel = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bOnLine && nNum != 0 && nPipe == nNum &&
|
|
!bVertical && bValidM && bAllValid|| bDel) //处理主管道
|
|
{
|
|
|
|
std::map<AcDbObjectId, AcGePoint3dArray>::iterator it;
|
|
it = dataMap.find(pListAll->m_ID);
|
|
if (it == dataMap.end()) // 管道没有被处理过
|
|
{
|
|
TDbPipe *pPipe = NULL;
|
|
AcGePoint3d ptS, ptE;
|
|
acdbOpenObject(pPipe, pListAll->m_ID, AcDb::kForRead);
|
|
if (pPipe != NULL)
|
|
{
|
|
if (pPipe->GetFlowDir() == TPipeSys::kFromStart)
|
|
{
|
|
pPipe->getStartPoint(ptS);
|
|
pPipe->getEndPoint(ptE);
|
|
}
|
|
else
|
|
{
|
|
pPipe->getStartPoint(ptE);
|
|
pPipe->getEndPoint(ptS);
|
|
}
|
|
pPipe->close();
|
|
}
|
|
|
|
AcGeVector3d vt = ptE - ptS;
|
|
vt.normalize();
|
|
|
|
// 取得修改的次管道和主管道的长度最小值
|
|
double dLen = ptS.distanceTo(ptE);
|
|
if (dLen > dChamferLen)
|
|
{
|
|
dLen = dChamferLen;
|
|
}
|
|
|
|
if (dMin < dLen)
|
|
{
|
|
dLen = dMin;
|
|
}
|
|
|
|
AcGePoint3d pt = ptS + vt * dLen;
|
|
AcGePoint3dArray arPt;
|
|
arPt.append(pt);
|
|
arPt.append(ptE);
|
|
dataMap.insert(std::make_pair(pListAll->m_ID, arPt));
|
|
}
|
|
else // 管道已被处理过
|
|
{
|
|
AcGePoint3d pt1, pt2;
|
|
pt1 = (*it).second[0];
|
|
pt2 = (*it).second[1];
|
|
|
|
AcGeVector3d vt = pt2 - pt1;
|
|
vt.normalize();
|
|
double dLen = pt1.distanceTo(pt2);
|
|
if(dLen > dChamferLen)
|
|
{
|
|
dLen = dChamferLen;
|
|
}
|
|
|
|
if (dMin < dLen)
|
|
{
|
|
dLen = dMin;
|
|
}
|
|
|
|
pt = pt1 + vt * dLen;
|
|
(*it).second[0] = pt;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int nLen = pListAll->m_lstNode.Length();
|
|
for(int i = 0; i < nLen; i++)
|
|
{
|
|
GetPipeMap(pListAll->m_lstNode[i], dataMap, dChamferLen, ssAll, vecId);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CDrawDrainChamfer::ModifyPipe(std::map<AcDbObjectId, AcGePoint3dArray> &dataMap, std::vector<AcDbObjectId> &vecId)
|
|
{
|
|
// 修改原管道和生成倒角
|
|
std::map<AcDbObjectId, AcGePoint3dArray>::iterator it;
|
|
AcGePoint3dArray arPt;
|
|
for(it = dataMap.begin(); it != dataMap.end(); it++)
|
|
{
|
|
AcDbObjectId id = (*it).first;
|
|
arPt.setLogicalLength(0);
|
|
arPt = (*it).second;
|
|
int nLen = arPt.length();
|
|
if (nLen == 2 || nLen == 3)
|
|
{
|
|
TDbPipe *pPipe = NULL;
|
|
acdbOpenObject(pPipe, id, AcDb::kForWrite);
|
|
if (pPipe != NULL)
|
|
{
|
|
if (nLen == 3) // 生成倒角
|
|
{
|
|
TDbPipe *pPipe1 = new TDbPipe;
|
|
// zxl 2013.05.30 modify
|
|
// pPipe1->CopyPropertiesFrom(pPipe, 0);
|
|
pPipe1 = (TDbPipe*)pPipe->clone();
|
|
pPipe1->SetStartPoint(arPt[1]);
|
|
pPipe1->SetEndPoint(arPt[2]);
|
|
pPipe1->SetFlowDir(TPipeSys::kFromStart);
|
|
pPipe1->setLayer(pPipe->layer());
|
|
// zxl 2013.05.29 add
|
|
if (pPipe1->IsLabelValid())
|
|
{
|
|
pPipe1->EnableDrawLabel(FALSE);
|
|
}
|
|
|
|
AddToCurrentSpace(pPipe1, Adesk::kTrue);
|
|
}
|
|
|
|
if (arPt[0].distanceTo(arPt[1]) > 1e-3) // 原管道修改后的长度
|
|
{
|
|
XPoint ptLoc = pPipe->GetLabelLocation();// zxl 2013.05.29 add
|
|
pPipe->SetStartPoint(arPt[0]);
|
|
pPipe->SetEndPoint(arPt[1]);
|
|
pPipe->SetFlowDir(TPipeSys::kFromStart);
|
|
pPipe->SetLabelLocation(ptLoc);// zxl 2013.05.29 add
|
|
}
|
|
else
|
|
{
|
|
pPipe->erase();
|
|
}
|
|
pPipe->close();
|
|
}
|
|
}
|
|
}
|
|
|
|
// 删除多余管道(与主管道共线的长度不大于倒角长度的末端管道)
|
|
std::vector<AcDbObjectId>::iterator it1;
|
|
for (it1 = vecId.begin(); it1 != vecId.end(); it1++)
|
|
{
|
|
TDbPipe *pPipe = NULL;
|
|
acdbOpenObject(pPipe, *it1, AcDb::kForWrite);
|
|
if (pPipe != NULL)
|
|
{
|
|
pPipe->erase();
|
|
pPipe->close();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CDrawDrainChamfer::GetFristPipeNode(SSearchPipeList *pLstIn, SSearchPipeList *&pLstOut)
|
|
{
|
|
if (pLstIn != NULL)
|
|
{
|
|
int nLen = pLstIn->m_lstNode.Length();
|
|
if (nLen == 1)
|
|
{
|
|
pLstOut = pLstIn->m_lstNode[0];
|
|
}
|
|
else if (nLen == 2)
|
|
{
|
|
SSearchPipeList *pLst1 = pLstIn->m_lstNode[0];
|
|
SSearchPipeList *pLst2 = pLstIn->m_lstNode[1];
|
|
int nLen1 = pLst1->m_lstNode.Length();
|
|
int nLen2 = pLst2->m_lstNode.Length();
|
|
|
|
if ((nLen1 > 0 && nLen2 == 0) || (nLen2 > 0 && nLen1 == 0))
|
|
{
|
|
if (nLen1 > 0)
|
|
{
|
|
pLstOut = pLst1;
|
|
}
|
|
else
|
|
{
|
|
pLstOut = pLst2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CDrawDrainChamfer::GetMinPipeLen(SSearchPipeList *pLst, PickSet &ssAll, const AcDbObjectId &idM, double &dMin)
|
|
{
|
|
if (pLst != NULL)
|
|
{
|
|
TDbPipe *pPipe1 = NULL, *pPipe2 = NULL;
|
|
AcGePoint3d ptS1, ptS2, ptE1, ptE2;
|
|
acdbOpenObject(pPipe2, idM, AcDb::kForRead);
|
|
if (pPipe2 != NULL)
|
|
{
|
|
pPipe2->getStartPoint(ptS2);
|
|
pPipe2->getEndPoint(ptE2);
|
|
pPipe2->close();
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcGeVector3d vt2 = ptS2 - ptE2, vt1;
|
|
AcGeTol tol;
|
|
tol.setEqualVector(1e-3);
|
|
|
|
int nNum = pLst->m_lstNode.Length();
|
|
for (int i = 0; i < nNum; i++)
|
|
{
|
|
SSearchPipeList *pLstTmp = pLst->m_lstNode[i];
|
|
if (IsValidPipe(ssAll, pLstTmp->m_ID))
|
|
{
|
|
acdbOpenObject(pPipe1, pLstTmp->m_ID, AcDb::kForRead);
|
|
if (pPipe1 != NULL)
|
|
{
|
|
pPipe1->getStartPoint(ptS1);
|
|
pPipe1->getEndPoint(ptE1);
|
|
pPipe1->close();
|
|
|
|
vt1 = ptS1 - ptE1;
|
|
if (!vt1.isParallelTo(vt2, tol)) // 不共线,次管道需要修改
|
|
{
|
|
if (i == 0)
|
|
{
|
|
dMin = ptS1.distanceTo(ptE1);
|
|
}
|
|
else if (dMin > ptS1.distanceTo(ptE1))
|
|
{
|
|
dMin = ptS1.distanceTo(ptE1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CDrawDrainChamfer::MakeChamfer(SSearchPipeList *pListAll, PickSet &ssAll, double dChamferLen)
|
|
{
|
|
std::map<AcDbObjectId, AcGePoint3dArray> dataMap;
|
|
std::vector<AcDbObjectId> vecId; // 需处理的的末端管道
|
|
GetPipeMap(pListAll, dataMap, dChamferLen, ssAll, vecId); // 得到需要修改的管道的信息并存入Map中
|
|
ModifyPipe(dataMap, vecId);
|
|
} |