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

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);
}