1384 lines
36 KiB
C++
1384 lines
36 KiB
C++
#include "stdafx.h"
|
|
#include "SanitarySysForDrain.h"
|
|
#include "PartitionSanitarySys.h"
|
|
#include "AutoLinkSanitaraySettingDlg.h"
|
|
#include "ConcealInstallSanitarySys.h"
|
|
#include "PipeWireMonitor.h"
|
|
#include "UnfoldInstallSanitarySys.h"
|
|
#include "NewSanitaryDefineDlg.h"
|
|
|
|
extern bool GetSanitaryInfo(Entity ent, XPoint &ptRet, CString &csBlk, CString &csSysBlk, double &nRadius, double &nDang, double &nBigQ, double &dEle, int iType, CString &sDwbName, CString &sFeedElev, CString &sHotElev);
|
|
extern bool GetSanitaryDriection(Entity ent, double &dSanitaryDriec);
|
|
extern double GetEntDriection(const XPoint &ptStart, const XPoint &ptEnd);
|
|
extern int GetSanitaryDataSourceType(Entity ent);
|
|
extern bool GetLocSanitaryData(Entity ent, CSanitaryInfo &data, AcGePoint3d &ptFeed,
|
|
AcGePoint3d &ptHeatFeed, AcGePoint3d &ptDrain, AcGePoint3d &ptDir);
|
|
|
|
// 用户选择安装方式
|
|
bool SetInstallTypeByCustom(bool &bType, int iType = 1)
|
|
{
|
|
CString sTmp;
|
|
if (iType == 1)// 默认暗装
|
|
{
|
|
bType = true;
|
|
sTmp = _T("\n请选择安装方式 [暗装(A)/明装(D)]<A>:");
|
|
}
|
|
else// 默认明装
|
|
{
|
|
bType = false;
|
|
sTmp = _T("\n请选择安装方式 [暗装(A)/明装(D)]<D>:");
|
|
}
|
|
|
|
TCHAR szTmp[10];
|
|
INITGET_BEG(0, _T("A D"));
|
|
int iRet = acedGetKword(sTmp, szTmp);
|
|
if (iRet == RTNORM)
|
|
{
|
|
if (szTmp[0] == 'd' || szTmp[0] == 'D')
|
|
{
|
|
bType = false;
|
|
}
|
|
else
|
|
{
|
|
bType = true;
|
|
}
|
|
}
|
|
else if(iRet == RTCAN)
|
|
{
|
|
return false;
|
|
}
|
|
INITGET_END();
|
|
return true;
|
|
}
|
|
|
|
// 根据管线类型设定安装方式
|
|
bool SetInstallType(std::vector<SanitarySysData> &vecdata, bool &bInstallType)
|
|
{
|
|
std::vector<SanitarySysData>::const_iterator it;
|
|
|
|
for (it = vecdata.begin(); it != vecdata.end(); it++)
|
|
{
|
|
if ((*it).type == TPipeSys::kDirtWater || (*it).type == TPipeSys::kUselessWater)// 排水系统
|
|
{
|
|
continue;
|
|
}
|
|
const double dMinEle = DocGetMeterUnitDim() ? 0.12 : 120;
|
|
const double dMaxEle = DocGetMeterUnitDim() ? 2.5 : 2500;
|
|
AcDbObjectId id = (*it).id;
|
|
TDbPipe *pPipe = NULL;
|
|
acdbOpenObject(pPipe, id, AcDb::kForRead);
|
|
if (pPipe != NULL)
|
|
{
|
|
BOOL bIsVertical = pPipe->IsVertical();
|
|
XPoint ptTmp = pPipe->StartPoint();
|
|
pPipe->close();
|
|
if(bIsVertical)//立管
|
|
{
|
|
if (SetInstallTypeByCustom(bInstallType))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
double dEle = ptTmp.z;
|
|
if (dEle - dMinEle <= 0.0 || dEle - dMaxEle >= 0.0)
|
|
{
|
|
if (SetInstallTypeByCustom(bInstallType))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (SetInstallTypeByCustom(bInstallType, 0))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// 自动管连洁具主函数
|
|
void AutoPipeLinkSanitary()
|
|
{
|
|
// 命令行提示操作部分
|
|
PickSet ss(SS_FREE); // 选择的管线和洁具
|
|
static double dChamferLen = 150.0; // 排水倒角
|
|
static int nType = 0; // 安装方式,0 垂直连接 1 水平连接
|
|
static double dDistPipe2Wall = 120;
|
|
|
|
RBList rbMask = ads_buildlist( -4, _T("<or"),
|
|
-4, _T("<and"), RTDXF0, _T("ATS_PIPE"), 8, _T("*"), -4, _T("and>"),
|
|
-4, _T("<and"), RTDXF0, _T("LINE"), 8, LAY_WALL, -4, _T("and>"),
|
|
-4, _T("<and"), RTDXF0, _T("ATS_WALL"), -4, _T("and>"),
|
|
-4, _T("<and"), RTDXF0, _T("INSERT"), 8, _T("*"), -4, _T("and>"),
|
|
-4, _T("<and"), RTDXF0, _T("AEC_BLOCK_INSERT"), 8, LAY_SANIWARE, -4, _T("and>"),
|
|
-4, _T("<and"), RTDXF0, _T("ATS_EQUIPMENT"), 8, _T("*"), -4, _T("and>"),
|
|
-4, _T("<and"), RTDXF0, _T("ATS_OPENING"), 8, _T("*"), -4, _T("and>"),
|
|
-4, _T("or>"), NULL);
|
|
|
|
static double dVPipeEle = 2.6; // 暗装时给水管为立管时的立管标高
|
|
TCHAR cRet;
|
|
int ret(0);
|
|
while (true)
|
|
{
|
|
PickSet ss1(SS_FREE);
|
|
INITGET_BEG(0, _T("S"));
|
|
ret = SelectEntities(_T("\n请框选立管或靠近立管的管线及需要连接的洁具{连接设置(S)}<退出>:"), ss1, rbMask, _T("S"), cRet);
|
|
INITGET_END();
|
|
if (ret == RTKWORD)
|
|
{
|
|
if (cRet == _T('S'))
|
|
{
|
|
CAutoLinkSanitaraySettingDlg dlg;
|
|
if (dlg.DoModal() == IDOK)
|
|
{
|
|
dVPipeEle = dlg.GetVPipeEle();
|
|
dChamferLen = dlg.GetChamferLen();
|
|
nType = dlg.GetLinkType();
|
|
dDistPipe2Wall = dlg.GetDistPipe2Wall();
|
|
if (!dlg.IsCreateChamfer())
|
|
{
|
|
dChamferLen = 0.0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (ret == RTNORM)
|
|
{
|
|
ss += ss1;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 根据连接规则划分洁具系统
|
|
PartitionSanitarySys sanitarySys;
|
|
std::vector<SanitarySysData> sanitarySysData; // 划分结果
|
|
if (!sanitarySys.PartitionSanitary(ss, sanitarySysData))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 将洁具系统按污水-废水-给水-热水-中水顺序排序依次连接
|
|
sanitarySys.Sort(sanitarySysData);
|
|
|
|
// 按照规则连接管线
|
|
std::vector<AcDbLine* > vecPipeLine;
|
|
std::vector<AcGePoint3d> vecPt;
|
|
if (!sanitarySysData.empty())
|
|
{
|
|
bool bConcealInstall = true;// 暗装
|
|
if (!SetInstallType(sanitarySysData, bConcealInstall))
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool bErrorTime = false;
|
|
std::vector<SanitarySysData>::const_iterator it;
|
|
for (it = sanitarySysData.begin(); it != sanitarySysData.end(); it++)
|
|
{
|
|
if ((*it).type == TPipeSys::kDirtWater || (*it).type == TPipeSys::kUselessWater)// 排水系统
|
|
{
|
|
SanitarySysForDrain linkSanitaryForDrain;
|
|
linkSanitaryForDrain.SetVertivalPipeAndDoor(ss);
|
|
linkSanitaryForDrain.SetChamferLen(dChamferLen);
|
|
linkSanitaryForDrain.AutoLinkSanitary(*it);
|
|
linkSanitaryForDrain.GetLinkedPipe(vecPipeLine);
|
|
}
|
|
else// 给水系统
|
|
{
|
|
// 获得其他系统洁具点
|
|
vecPt.clear();
|
|
sanitarySys.GetOtherSanitaryPt((*it).type, sanitarySysData, vecPt);
|
|
|
|
if (bConcealInstall)// 暗装
|
|
{
|
|
ConcealInstallSanitarySys sanSys;
|
|
sanSys.SetDistPipe2Wall(dDistPipe2Wall);
|
|
sanSys.SetVertivalPipeAndDoor(ss);
|
|
sanSys.SetCollidePipe(vecPipeLine);
|
|
sanSys.SetFeedPointEle(dVPipeEle);
|
|
sanSys.SetOtherSanitaryPoint(vecPt);
|
|
sanSys.AutoLinkSanitary(*it);
|
|
sanSys.GetLinkedPipe(vecPipeLine);
|
|
}
|
|
else
|
|
{
|
|
UnfoldInstallSanitarySys sanSys;
|
|
sanSys.SetDistPipe2Wall(dDistPipe2Wall);
|
|
sanSys.IsCreatPipe(false);
|
|
sanSys.SetInstallType(nType);
|
|
sanSys.SetErrorNote(bErrorTime);
|
|
sanSys.SetVertivalPipeAndDoor(ss);
|
|
sanSys.SetCollidePipe(vecPipeLine);
|
|
sanSys.SetOtherSanitaryPoint(vecPt);
|
|
sanSys.AutoLinkSanitary(*it);
|
|
sanSys.GetLinkedPipe(vecPipeLine);
|
|
bErrorTime = sanSys.GetErrorNote();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
std::vector<AcDbLine* >::iterator itLine;
|
|
for (itLine = vecPipeLine.begin(); itLine != vecPipeLine.end(); itLine++)
|
|
{
|
|
if ((*itLine) != NULL)
|
|
{
|
|
delete *itLine;
|
|
*itLine = NULL;
|
|
}
|
|
}
|
|
|
|
// 更新管线系统
|
|
TPipePerDocData *pData = GetCurPipeDocData();
|
|
if (pData != NULL)
|
|
{
|
|
pData->ApplyUpdates();
|
|
}
|
|
}
|
|
|
|
SanitarySysForDrain::SanitarySysForDrain()
|
|
{
|
|
m_nId = 1;
|
|
}
|
|
|
|
void SanitarySysForDrain::SetChamferLen(double dChamferLen)
|
|
{
|
|
m_dChamferLen = dChamferLen;
|
|
}
|
|
|
|
void SanitarySysForDrain::AutoLinkSanitary(const SanitarySysData &data)
|
|
{
|
|
std::vector<PipeData> vecPipeData;
|
|
// 如果只有一个洁具,排水点直接与洁具点相连
|
|
if (data.vecSanitaryNode.size() == 1)
|
|
{
|
|
LinkSingleSanitary(data);
|
|
return;
|
|
}
|
|
else if (!IsVertivalPipe(data.id))// 多洁具系统且主干是直管时,判断主干是否平行于X 或 Y 轴
|
|
{
|
|
PipeDir dir = GetPipeDirection(data.id);
|
|
if (dir != eParallelX && dir != eParallelY)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 按距排水点的远近对洁具点排序(计算距离时,按当前坐标系x轴,y轴方向连接两点)
|
|
std::vector<SanitaryNode> vecSanitary(data.vecSanitaryNode);
|
|
AcGePoint3d ptFrom = data.pt; // 排水点或给水点、
|
|
Sort(vecSanitary, ptFrom);
|
|
|
|
// 首次找出最远洁具点设置主干管
|
|
AcGePoint3d ptTo = (*vecSanitary.begin()).pt; // 最远洁具点
|
|
ptTo.z = ptFrom.z;
|
|
m_idPipe = data.id;
|
|
SelectMianPipe(vecSanitary, data.type, data.id, ptFrom, ptTo); // 设置主干管
|
|
|
|
// 按距离远近连接所有未连接的洁具点(为简化操作排水倒角在生成管线时产生)
|
|
LinkPipe(vecSanitary, data.type, ptFrom);
|
|
// 绘制管线
|
|
CreatePipe();
|
|
}
|
|
|
|
void SanitarySysForDrain::LinkSingleSanitary(const SanitarySysData &data)
|
|
{
|
|
AcGePoint3d ptS, ptE;
|
|
if (IsVertivalPipe(data.id)) // 立管
|
|
{
|
|
const double dDist = DocGetMeterUnitDim() ? -0.45 : -450;
|
|
AcGePoint3d ptTmp;
|
|
ptS = data.vecSanitaryNode[0].pt;
|
|
ptE = data.pt;
|
|
ptE.z = dDist;
|
|
ptS.z = dDist;
|
|
AddSanitarySys(data.type, GetPipeDn(data.id));
|
|
AddPipeLine(data.type, ptS, ptE, eBranch, GetPipeDirection(data.id));
|
|
GetPipePoint(data.id, ptS, ptE);
|
|
|
|
ptTmp = ptS;
|
|
ptTmp.z = dDist;
|
|
double dDist1 = ptTmp.distanceTo(ptS);
|
|
double dDist2 = ptTmp.distanceTo(ptE);
|
|
double dLen = ptS.distanceTo(ptE);
|
|
if (fabs(dLen - dDist1 - dDist2) > 0.001)//延长立管到标高 -450处
|
|
{
|
|
if (dDist1 > dDist2)
|
|
{
|
|
AddPipeLine(data.type, ptE, ptTmp, eVertival, eOther);
|
|
}
|
|
else
|
|
{
|
|
AddPipeLine(data.type, ptTmp, ptS, eVertival, eOther);
|
|
}
|
|
}
|
|
ptS.z = dDist;
|
|
}
|
|
else
|
|
{
|
|
AcGePoint3d ptPipeS, ptPipeE;
|
|
AcGePoint3d ptSan, ptOnLine;
|
|
ptSan = data.vecSanitaryNode[0].pt;
|
|
GetPipePoint(data.id, ptS, ptE);
|
|
AcDbLine line(ptS, ptE);
|
|
line.getClosestPointTo(ptSan, AcGeVector3d::kZAxis, ptOnLine, Adesk::kTrue);
|
|
if (ptSan.distanceTo(ptOnLine) < 0.001)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcGePoint3d ptChamferEnd, ptChamferStart;
|
|
AcDbLine lineMain(ptOnLine, ptE);
|
|
lineMain.getPointAtDist(m_dChamferLen, ptChamferEnd);
|
|
|
|
double dLen = ptS.distanceTo(ptE);
|
|
double dDist1 = ptS.distanceTo(ptOnLine);
|
|
double dDist2 = ptE.distanceTo(ptOnLine);
|
|
if (fabs(dLen - dDist1 - dDist2) > m_dChamferLen) // 投影点不在线上,延长主干
|
|
{
|
|
TDbPipe *pPipe = NULL;
|
|
acdbOpenObject(pPipe, data.id, AcDb::kForWrite);
|
|
if (pPipe != NULL)
|
|
{
|
|
// 调整主干流向
|
|
if (dDist1 - dDist2 > 0.001) // 投影点在管线终点方向
|
|
{
|
|
pPipe->SetEndPoint(ptChamferEnd);
|
|
ptPipeS = pPipe->StartPoint();
|
|
ptPipeE = pPipe->EndPoint();
|
|
pPipe->SetEndPoint(ptPipeS);
|
|
pPipe->SetStartPoint(ptPipeE);
|
|
}
|
|
else
|
|
{
|
|
pPipe->SetStartPoint(ptChamferEnd);
|
|
}
|
|
pPipe->close();
|
|
}
|
|
}
|
|
|
|
ptS = ptSan;
|
|
ptE = ptOnLine;
|
|
ptS.z = ptE.z;
|
|
|
|
AcDbLine lineBranch(ptS, ptE);
|
|
lineBranch.getPointAtDist(ptS.distanceTo(ptE) - m_dChamferLen, ptChamferStart);
|
|
|
|
AddSanitarySys(data.type, GetPipeDn(data.id));
|
|
AddPipeLine(data.type, ptS, ptChamferStart, eBranch, GetPipeDirection(data.id));
|
|
AddPipeLine(data.type, ptChamferStart, ptChamferEnd, eBranch, eOther);
|
|
}
|
|
DrawDirtEquip(data.type, data.vecSanitaryNode[0], ptS);
|
|
CreatePipe();
|
|
}
|
|
|
|
void SanitarySysForDrain::SetVector3dByXOY(AcGeVector3d &vtX, AcGeVector3d &vtY)
|
|
{
|
|
vtX = AcGeVector3d::kXAxis;
|
|
vtY = AcGeVector3d::kYAxis;
|
|
}
|
|
|
|
// 主干管连接排水点
|
|
void SanitarySysForDrain::SelectMianPipe(std::vector<SanitaryNode> &vec, TPipeSys::SysType sys, const AcDbObjectId &idPipe, AcGePoint3d &ptFrom, AcGePoint3d &ptTo)
|
|
{
|
|
AddSanitarySys(sys, GetPipeDn(idPipe));
|
|
// 设定立管排水点标高
|
|
const double dDist = DocGetMeterUnitDim() ? -0.45 : -450;
|
|
if (IsVertivalPipe(idPipe))
|
|
{
|
|
ptFrom.z = dDist;
|
|
ptTo.z = dDist;
|
|
AcGePoint3d ptS, ptE;
|
|
GetPipePoint(idPipe, ptS, ptE);
|
|
// ptS = Wcs2Ucs(ptS);
|
|
// ptE = Wcs2Ucs(ptE);
|
|
|
|
AcGePoint3d ptTmp = ptS;
|
|
ptTmp.z = dDist;
|
|
double dDist1 = ptTmp.distanceTo(ptS);
|
|
double dDist2 = ptTmp.distanceTo(ptE);
|
|
double dLen = ptS.distanceTo(ptE);
|
|
if (fabs(dLen - dDist1 - dDist2) > 0.001)//延长立管到标高 -450处
|
|
{
|
|
if (dDist1 > dDist2)
|
|
{
|
|
AddPipeLine(sys, ptE, ptTmp, eVertival, eOther);
|
|
}
|
|
else
|
|
{
|
|
AddPipeLine(sys, ptTmp, ptS, eVertival, eOther);
|
|
}
|
|
}
|
|
}
|
|
//设定排水附件
|
|
DrawDirtEquip(sys, vec[0], ptFrom);
|
|
vec.erase(vec.begin());//删除最远洁具点(主干在UCS下设定,分支在WCS下设定)
|
|
ptFrom = Wcs2Ucs(ptFrom);
|
|
ptTo = Wcs2Ucs(ptTo);
|
|
|
|
AcGeVector3d vt = ptFrom - ptTo;
|
|
vt.z = 0.0;
|
|
AcGeVector3d vtX, vtY;
|
|
SetVector3dByXOY(vtX, vtY);
|
|
AcGePoint3d pt = ptTo;
|
|
|
|
PipeDir Dir = GetPipeDirection(idPipe); // 排水管或给水管方向
|
|
if (vtX.isParallelTo(vt)) // 平行x轴, 直接连接即可
|
|
{
|
|
AddPipeLine(vec, sys, pt, ptFrom, eMainPipe, eParallelX);
|
|
}
|
|
else if (vtY.isParallelTo(vt)) // 平行y轴, 直接连接即可
|
|
{
|
|
AddPipeLine(vec, sys, pt, ptFrom, eMainPipe, eParallelY);
|
|
}
|
|
else
|
|
{
|
|
AcGePoint3d ptX, ptY; // 沿x轴或y轴连接洁具点时转折点、
|
|
ptX = ptFrom + vtX * (ptTo.x - ptFrom.x);
|
|
ptY = ptFrom + vtY * (ptTo.y - ptFrom.y);
|
|
if (IsVertivalPipe(idPipe)) // 排水管或给水管是立管
|
|
{
|
|
int nPipeX = PassVertivalPipeNumByLine(ptX, ptFrom) + PassVertivalPipeNumByLine(ptX, ptTo);
|
|
int nPipeY = PassVertivalPipeNumByLine(ptY, ptFrom) + PassVertivalPipeNumByLine(ptY, ptTo);
|
|
if ((nPipeX > 0 && nPipeY > 0) || (nPipeX == 0 && nPipeY == 0)) // 沿x轴和y轴方向均穿过立管或均不穿过立管
|
|
{
|
|
const double dDist = DocGetMeterUnitDim() ? 0.1 : 100;
|
|
int nNextToDoor1 = IsNextToDoor(dDist, ptX, ptFrom) + IsNextToDoor(dDist, ptX, ptTo); // 是否挨着门
|
|
int nNextToDoor2 = IsNextToDoor(dDist, ptY, ptFrom) + IsNextToDoor(dDist, ptY, ptTo); // 是否挨着门
|
|
if (nNextToDoor1 <= nNextToDoor2) // 沿X轴设置主干管
|
|
{
|
|
SetMainPipeForXOY(vec, sys, idPipe, pt, ptFrom, ptX, eParallelX);
|
|
}
|
|
else
|
|
{
|
|
SetMainPipeForXOY(vec, sys, idPipe, pt, ptFrom, ptY, eParallelY);
|
|
}
|
|
}
|
|
else if (nPipeX == 0) // 沿y轴穿过立管, 则沿x轴布置主干管
|
|
{
|
|
SetMainPipeForXOY(vec, sys, idPipe, pt, ptFrom, ptX, eParallelX);
|
|
}
|
|
else if (nPipeY == 0) // 沿x轴穿过立管,则沿y轴布置主干管
|
|
{
|
|
SetMainPipeForXOY(vec, sys, idPipe, pt, ptFrom, ptY, eParallelY);
|
|
}
|
|
}
|
|
else // 支管
|
|
{
|
|
XPoint ptLinkable, ptS, ptE;
|
|
GetLinkablePt(idPipe, ptLinkable, ptS, ptE);// 获取支管末端可用的给水点或排水点
|
|
|
|
ptS = Wcs2Ucs(ptS);
|
|
ptE = Wcs2Ucs(ptE);
|
|
ptLinkable = Wcs2Ucs(ptLinkable);
|
|
AcGeVector3d vtPipe = ptE - ptS;
|
|
vtPipe.normalize();
|
|
AcGeVector3d vtXOY;
|
|
|
|
// 排水管为支管时,需要生成一段管线以便连接洁具时使用
|
|
ads_name name;
|
|
acdbGetAdsName(name, idPipe);
|
|
Entity ent = name;
|
|
ent.Erase();
|
|
|
|
if (Dir == eParallelX)
|
|
{
|
|
vtXOY = ptE - ptX;
|
|
vtXOY.normalize();
|
|
if (vtPipe != vtXOY)
|
|
{
|
|
ptLinkable = ptS;
|
|
}
|
|
SetMainPipeForXOY(vec, sys, idPipe, pt, ptLinkable, ptX, eParallelX);
|
|
}
|
|
else if (Dir == eParallelY)
|
|
{
|
|
vtXOY = ptE - ptY;
|
|
vtXOY.normalize();
|
|
if (vtPipe != vtXOY)
|
|
{
|
|
ptLinkable = ptS;
|
|
}
|
|
SetMainPipeForXOY(vec, sys, idPipe, pt, ptLinkable, ptY, eParallelY);
|
|
}
|
|
else//管线不在水平或垂直方向时 返回
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 按文档规则连接洁具点和管线
|
|
void SanitarySysForDrain::LinkPipe(std::vector<SanitaryNode> &data, TPipeSys::SysType sys, const AcGePoint3d &ptFrom)
|
|
{
|
|
AcGePoint3d pt, ptX, ptY;
|
|
while(!data.empty())
|
|
{
|
|
//设定排水附件
|
|
DrawDirtEquip(sys, data[0], ptFrom);
|
|
|
|
pt = data[0].pt;
|
|
pt.z = ptFrom.z;
|
|
data.erase(data.begin());
|
|
// x轴方向和y轴方向距离洁具点pt
|
|
int nIdX = GetNearestPipeForX(sys, pt);
|
|
int nIdY = GetNearestPipeForY(sys, pt);
|
|
if (nIdX > -1 && nIdY > -1) // x轴和y轴方向都存在可连接洁具的管线
|
|
{
|
|
// 获得洁具点沿X轴或y轴在nIdX和nIdY上的投影点
|
|
GetProjectPoint(sys, nIdX, pt, ptX);
|
|
GetProjectPoint(sys, nIdY, pt, ptY);
|
|
// 向nIdX和nIdY连接洁具点 查看连接线经过的立管个数
|
|
int nPipeX = PassVertivalPipeNumByLine(ptX, pt);
|
|
int nPipeY = PassVertivalPipeNumByLine(ptY, pt);
|
|
if (nPipeX == 0 && nPipeY == 0) // 均不经过立管
|
|
{
|
|
// 获得连接线穿过墙数,以不穿墙者为准,都穿墙以经过的洁具点数为准
|
|
double dWeithX = 0.0, dWeithY = 0.0;
|
|
int nWallX = PassWallNumByLine(ptX, pt, dWeithX);
|
|
int nWallY = PassWallNumByLine(ptY, pt, dWeithY);
|
|
if ((nWallX > 0 && nWallY > 0) || ((nWallX == 0 && nWallY == 0))) // 都穿过墙体或都不穿过墙体
|
|
{
|
|
// 连接线经过的洁具点数, 以经过的洁具点数多者为准,相同时以连接线长度短者为准
|
|
int nSanitaryX = PassSanitaryNumByLine(data, ptX, pt);
|
|
int nSanitaryY = PassSanitaryNumByLine(data, ptY, pt);
|
|
if (nSanitaryX > nSanitaryY)
|
|
{
|
|
LinkSanitary(data, sys, nIdX, pt, ptX);
|
|
}
|
|
else if (nSanitaryX < nSanitaryY)
|
|
{
|
|
LinkSanitary(data, sys, nIdY, pt, ptY);
|
|
}
|
|
else // 都未经过洁具点或经过的洁具点相同
|
|
{
|
|
// 以穿墙 墙体厚度为准
|
|
if (dWeithX - dWeithY > 0.001)
|
|
{
|
|
LinkSanitary(data, sys, nIdY, pt, ptY);
|
|
}
|
|
else if (dWeithX - dWeithY < -0.001)
|
|
{
|
|
LinkSanitary(data, sys, nIdX, pt, ptX);
|
|
}
|
|
else// 墙体厚度相同 以距离为准
|
|
{
|
|
XPoint pt1 = pt, pt2 = ptX, pt3 = ptY;
|
|
double dDistX = pt1.Distance2d(pt2);
|
|
double dDistY = pt1.Distance2d(pt3);
|
|
if (dDistX > dDistY)
|
|
{
|
|
LinkSanitary(data, sys, nIdY, pt, ptY);
|
|
}
|
|
else
|
|
{
|
|
LinkSanitary(data, sys, nIdX, pt, ptX);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (nWallX > 0) // y轴方向穿过墙体
|
|
{
|
|
LinkSanitary(data, sys, nIdY, pt, ptY);
|
|
}
|
|
else if (nWallY > 0) // x轴方向穿过墙体
|
|
{
|
|
LinkSanitary(data, sys, nIdX, pt, ptX);
|
|
}
|
|
}
|
|
else if (nPipeY > 0) // 均经过立管或只有Y轴方向经过立管,以X轴方向投影为准
|
|
{
|
|
LinkSanitary(data, sys, nIdX, pt, ptX);
|
|
}
|
|
else if (nPipeX > 0) // 以不经过立管的Y轴方向投影为准
|
|
{
|
|
LinkSanitary(data, sys, nIdY, pt, ptY);
|
|
}
|
|
}
|
|
else if (nIdX == -1) // 只在y轴方向存在可连接洁具的管线
|
|
{
|
|
// 获得洁具点沿y轴在nIdX上的投影点
|
|
GetProjectPoint(sys, nIdY, pt, ptY);
|
|
LinkSanitary(data, sys, nIdY, pt, ptY);
|
|
}
|
|
else if (nIdY == -1) // 只在x轴方向存在可连接洁具的管线
|
|
{
|
|
// 获得洁具点沿X轴在nIdY上的投影点
|
|
GetProjectPoint(sys, nIdX, pt, ptX);
|
|
LinkSanitary(data, sys, nIdX, pt, ptX);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 按规则连接洁具
|
|
void SanitarySysForDrain::LinkSanitary(std::vector<SanitaryNode> &vec, TPipeSys::SysType sys, int nId, AcGePoint3d &ptSanitary, AcGePoint3d &ptPrj)
|
|
{
|
|
AcGePoint3d pt, ptElv;
|
|
PipeType type = eError;
|
|
type = GetDataType(sys, nId);
|
|
|
|
bool bMovePipe = false;
|
|
AcGePoint3d ptChamferEnd = ptPrj, ptChamferStart = ptPrj;//倒角点
|
|
PipeDir Dir = GetPipeDirection(sys, nId);
|
|
AcDbLine* pLine = GetPipeLine(sys, nId);
|
|
|
|
AcGePoint3d ptS ,ptE;
|
|
bool bCreatBranch = true;
|
|
//延长投影管 到投影点
|
|
if (pLine != NULL)
|
|
{
|
|
ptS = pLine->startPoint();
|
|
ptE = pLine->endPoint();
|
|
|
|
// 获取投影线上的倒角点
|
|
AcDbLine lineMain(ptPrj, ptE);
|
|
if (lineMain.getPointAtDist(m_dChamferLen, ptChamferEnd) != Acad::eOk) //投影点与排水点距离小于排水倒角长度
|
|
{
|
|
if (type == eMainPipe && IsVertivalPipe(m_idPipe)) // 投影点在主干时, 移动管线
|
|
{
|
|
bMovePipe = true;
|
|
lineMain.setStartPoint(ptE);
|
|
lineMain.setEndPoint(ptS);
|
|
lineMain.getPointAtDist(m_dChamferLen, ptChamferEnd);
|
|
}
|
|
else
|
|
{
|
|
ptChamferEnd = ptE;
|
|
}
|
|
}
|
|
if (ptPrj.distanceTo(ptSanitary) - m_dChamferLen < 0.001)// 投影点与洁具点距离小于倒角长度时 重设倒角点
|
|
{
|
|
lineMain.getPointAtDist(ptPrj.distanceTo(ptSanitary), ptChamferEnd);
|
|
}
|
|
|
|
double dLen = ptS.distanceTo(ptE);
|
|
double dDist1 = ptS.distanceTo(ptPrj);
|
|
double dDist2 = ptE.distanceTo(ptPrj);
|
|
if (fabs(dLen - dDist1 - dDist2) > m_dChamferLen && !bMovePipe) // 投影点不在线上, 延长管线
|
|
{
|
|
bool bFromStart = false;
|
|
if (dDist1 - dDist2 < 0.001)
|
|
{
|
|
bFromStart = true;
|
|
}
|
|
|
|
if (ptPrj.distanceTo(ptSanitary) < 0.001 )//投影点和洁具点重合
|
|
{
|
|
ptChamferEnd = ptSanitary;
|
|
bCreatBranch = false;
|
|
}
|
|
|
|
if (m_dChamferLen - 0.001 < 0.0)
|
|
{
|
|
ptChamferEnd = ptPrj;
|
|
}
|
|
ExtendPipeLine(sys, ptS, ptE, eBranch, Dir, ptChamferEnd, bFromStart);
|
|
}
|
|
}
|
|
|
|
if (!bCreatBranch)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (Dir == eParallelX)
|
|
{
|
|
Dir = eParallelY;
|
|
}
|
|
else if (Dir == eParallelY)
|
|
{
|
|
Dir = eParallelX;
|
|
}
|
|
|
|
//生成支管
|
|
AcGePoint3d ptStart, ptEnd;
|
|
ptStart = ptSanitary;
|
|
ptEnd = ptPrj;
|
|
|
|
// 支管上的倒角点
|
|
AcDbLine lineBranch(ptStart, ptEnd);
|
|
if (lineBranch.getPointAtDist(ptStart.distanceTo(ptEnd) - m_dChamferLen, ptChamferStart) != Acad::eOk)
|
|
{
|
|
ptChamferStart = ptStart;
|
|
}
|
|
|
|
if (bMovePipe)
|
|
{
|
|
SetBranchPipePt(sys, ptSanitary, ptPrj, ptS, ptE, ptChamferStart, ptStart);
|
|
}
|
|
|
|
if (ptChamferStart.distanceTo(ptChamferEnd) - 0.001 > 0.0 && m_dChamferLen - 0.001 > 0.0)
|
|
{
|
|
// 生成倒角
|
|
AddPipeLine(sys, ptChamferStart, ptChamferEnd, eChamfer, eOther);
|
|
}
|
|
|
|
// 生成支管
|
|
if (ptStart.distanceTo(ptChamferStart) > 0.0)
|
|
{
|
|
AddPipeLine(vec, sys, ptStart, ptChamferStart, eBranch, Dir);
|
|
}
|
|
}
|
|
|
|
// 获取排水倒角的倒角点
|
|
void SanitarySysForDrain::SetBranchPipePt(TPipeSys::SysType sys, const AcGePoint3d &ptSanitary, const AcGePoint3d &ptProj, const AcGePoint3d &ptStart, const AcGePoint3d &ptEnd, AcGePoint3d &ptChamferStart, AcGePoint3d &ptBranchStart)
|
|
{
|
|
AcGePoint3d ptSanitaryClone = ptSanitary;
|
|
ptSanitaryClone.z = ptProj.z;
|
|
AcGeVector3d vtMain = ptProj - ptStart;
|
|
vtMain.normalize();
|
|
AcGeVector3d vtBranch = ptProj - ptSanitaryClone;
|
|
vtBranch.normalize();
|
|
AcGePoint3d ptChamferStart2;
|
|
|
|
ptChamferStart = ptEnd - 2 * m_dChamferLen * vtMain;
|
|
ptChamferStart = ptChamferStart - m_dChamferLen * vtBranch;
|
|
ptBranchStart = ptChamferStart - (ptProj.distanceTo(ptSanitaryClone) - 2 * m_dChamferLen) * vtBranch;
|
|
ptChamferStart2 = ptBranchStart + vtMain * m_dChamferLen;
|
|
ptChamferStart2 = ptChamferStart2 - vtBranch * m_dChamferLen;
|
|
|
|
PipeDir dir = eNone;
|
|
if (vtMain.isParallelTo(AcGeVector3d::kXAxis))
|
|
{
|
|
dir = eParallelX;
|
|
}
|
|
else
|
|
{
|
|
dir = eParallelY;
|
|
}
|
|
|
|
if (m_dChamferLen - 0.001 > 0.0)
|
|
{
|
|
AddPipeLine(sys, ptChamferStart2, ptBranchStart, eChamfer, eOther);
|
|
}
|
|
AddPipeLine(sys, ptSanitaryClone, ptChamferStart2, eBranch, dir);
|
|
}
|
|
|
|
// 按照系统类型和管线方向 设置 XOY平面的主干管
|
|
void SanitarySysForDrain::SetMainPipeForXOY(std::vector<SanitaryNode> &vec, TPipeSys::SysType sys, const AcDbObjectId &idPipe,
|
|
AcGePoint3d &pt, AcGePoint3d &ptFrom, AcGePoint3d &ptXoY, PipeDir Dir)
|
|
{
|
|
|
|
PipeDir DirXoY = eParallelY;
|
|
if (Dir == eParallelY)//Y轴方向
|
|
{
|
|
DirXoY = eParallelX;
|
|
}
|
|
|
|
// 生成排水倒角 管
|
|
XPoint ptChamferEnd, ptChamferStart;
|
|
AcDbLine lineMain(ptXoY, ptFrom);
|
|
lineMain.getPointAtDist(m_dChamferLen, ptChamferEnd);
|
|
AcDbLine lineBranch(ptXoY, pt);
|
|
lineBranch.getPointAtDist(m_dChamferLen, ptChamferStart);
|
|
if (ptChamferStart.Distance2d(ptChamferEnd) - 0.001 > 0.0 && !!ptChamferStart && !!ptChamferEnd)
|
|
{
|
|
AddPipeLine(sys, ptChamferStart, ptChamferEnd, eMainPipe, eOther);
|
|
}
|
|
else // 不生成倒角
|
|
{
|
|
ptChamferStart = ptXoY;
|
|
ptChamferEnd = ptXoY;
|
|
}
|
|
|
|
//生成XOY两条管线
|
|
AddPipeLine(vec, sys, pt, ptChamferStart, eMainPipe, DirXoY);
|
|
AddPipeLine(vec, sys, ptChamferEnd, ptFrom, eMainPipe, Dir);
|
|
}
|
|
|
|
// 根据 管线延长方向 添加延长线
|
|
void SanitarySysForDrain::ExtendPipeLine(TPipeSys::SysType sys, AcGePoint3d &ptS, AcGePoint3d &ptE, PipeType type, PipeDir Dir, AcGePoint3d &ptTmp, bool bFromStart)
|
|
{
|
|
|
|
if (!bFromStart)
|
|
{
|
|
if (CheckIntersectPipe(ptTmp, ptE, sys))
|
|
{
|
|
AddPipeLine(sys, ptTmp, ptE, type, Dir);
|
|
}
|
|
else if (ExtendPipeLineFromEnd(sys, ptTmp, ptE))
|
|
{
|
|
AddPipeLine(sys, ptTmp, ptE, type, Dir);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CheckIntersectPipe(ptTmp, ptS, sys);
|
|
if (ptTmp.distanceTo(ptS) - 0.001 > 0.0)
|
|
{
|
|
AddPipeLine(sys, ptTmp, ptS, type, Dir);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 从管线排出端延长
|
|
bool SanitarySysForDrain::ExtendPipeLineFromEnd(TPipeSys::SysType sys, AcGePoint3d &ptS, AcGePoint3d &ptE)
|
|
{
|
|
if (m_dChamferLen - 0.001 < 0.0)
|
|
{
|
|
return true;
|
|
}
|
|
AcDbLine line(ptE, ptS);
|
|
AcGePoint3d ptDrain, ptIntersect;
|
|
if (line.getPointAtDist(m_dChamferLen, ptIntersect) != Acad::eOk)
|
|
{
|
|
return false;
|
|
}
|
|
ptDrain = ptIntersect;
|
|
|
|
GetDrainPtByPipe(sys, ptDrain);
|
|
|
|
if (line.getPointAtDist( 2 * m_dChamferLen, ptE) == Acad::eOk)
|
|
{
|
|
AddPipeLine(sys, ptE, ptDrain, eChamfer, eOther);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
AcGePoint3d ptMiddle;
|
|
AcDbLine lineBranch(ptIntersect, ptDrain);
|
|
if (lineBranch.getPointAtDist(ptIntersect.distanceTo(ptS), ptMiddle) == Acad::eOk)
|
|
{
|
|
AddPipeLine(sys, ptMiddle, ptDrain, eBranch, eOther);
|
|
AddPipeLine(sys, ptS, ptMiddle, eChamfer, eOther);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// 获取上级管线连接点
|
|
void SanitarySysForDrain::GetDrainPtByPipe(TPipeSys::SysType sys, AcGePoint3d &pt)
|
|
{
|
|
double dDist = 0.0;
|
|
std::vector<Node>::iterator it;
|
|
std::vector<PipeData>::iterator itP;
|
|
for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++)
|
|
{
|
|
if ((*it).sys != sys)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(itP = ((*it).data).begin(); itP != ((*it).data).end(); itP++)
|
|
{
|
|
if (((*itP).drection != eParallelX && (*itP).drection != eParallelY))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dDist = (*itP).pLine->startPoint().distanceTo(pt);
|
|
if ( fabs(dDist - m_dChamferLen) < 0.001)
|
|
{
|
|
pt = (*itP).pLine->startPoint();
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 检查到管线相交时重新设定管线
|
|
bool SanitarySysForDrain::CheckIntersectPipe(AcGePoint3d &ptS, AcGePoint3d &ptE, TPipeSys::SysType sys)
|
|
{
|
|
AcGePoint3dArray ptArray, ptIntersectArray;
|
|
AcGePoint3d ptPrj, ptChamfer;
|
|
AcDbLine lineNew(ptS, ptE), lineMain;
|
|
AcDbLine *pLine = NULL;
|
|
std::vector<Node>::iterator it;
|
|
std::vector<PipeData>::iterator itP;
|
|
for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++)
|
|
{
|
|
if ((*it).sys != sys)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(itP = ((*it).data).begin(); itP != ((*it).data).end(); itP++)
|
|
{
|
|
if (((*itP).drection != eParallelX && (*itP).drection != eParallelY))
|
|
{
|
|
continue;
|
|
}
|
|
ptArray.setLogicalLength(0);
|
|
pLine = (*itP).pLine;
|
|
lineNew.intersectWith(pLine, AcDb::kOnBothOperands, ptArray);
|
|
if (ptArray.length() > 0)
|
|
{
|
|
ptPrj = ptArray[0];
|
|
lineMain.setStartPoint(ptPrj);
|
|
lineMain.setEndPoint(pLine->endPoint());
|
|
if (ptPrj.distanceTo(ptS) - m_dChamferLen > 0.001)
|
|
{
|
|
AcDbLine lineBranch(ptPrj, ptS);
|
|
lineBranch.getPointAtDist(m_dChamferLen, ptE);
|
|
Acad::ErrorStatus es = lineMain.getPointAtDist(m_dChamferLen, ptChamfer);
|
|
if (ptE.distanceTo(ptChamfer) - 0.001 > 0.0 && m_dChamferLen - 0.001 > 0.0)
|
|
{
|
|
if (es == Acad::eOk)
|
|
{
|
|
AddPipeLine(sys, ptE, ptChamfer, eChamfer, eOther);
|
|
}
|
|
else
|
|
{
|
|
AddPipeLine(sys, ptE, ptPrj, eChamfer, eOther);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
ptE = ptS;
|
|
lineMain.getPointAtDist(ptE.distanceTo(ptPrj), ptChamfer);
|
|
if (ptE.distanceTo(ptChamfer) - 0.001 > 0.0 && m_dChamferLen - 0.001 > 0.0)
|
|
{
|
|
AddPipeLine(sys, ptE, ptChamfer, eChamfer, eOther);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 添加支管 若该支管上有洁具 则连接该洁具
|
|
void SanitarySysForDrain::AddPipeLine(std::vector<SanitaryNode> &vec, TPipeSys::SysType sys, AcGePoint3d &ptS, AcGePoint3d &ptE, PipeType type, PipeDir Dir)
|
|
{
|
|
if (ptS.distanceTo(ptE) < 0.001)
|
|
{
|
|
return;
|
|
}
|
|
XPoint pt1 = ptS, pt2 = ptE, ptTmp;
|
|
AcDbLine line(pt1, pt2);
|
|
XPoint ptOnLine, ptSan;
|
|
std::vector<SanitaryNode>::iterator itPt = vec.begin();
|
|
for (; itPt != vec.end(); )//遍历洁具点
|
|
{
|
|
ptSan = (*itPt).pt;
|
|
line.getClosestPointTo(ptSan, ptOnLine);
|
|
if (ptOnLine.Distance2d(ptSan) - 0.001 < 0.0)//洁具点在该管线上
|
|
{
|
|
DrawDirtEquip(sys, *itPt, ptS);
|
|
itPt = vec.erase(itPt);
|
|
}
|
|
else
|
|
{
|
|
itPt++;
|
|
}
|
|
}
|
|
AddPipeLine(sys, ptS, ptE, type, Dir);
|
|
}
|
|
|
|
void SanitarySysForDrain::AddPipeLine(TPipeSys::SysType sys, const AcGePoint3d &ptS, const AcGePoint3d &ptE, PipeType type, PipeDir Dir)
|
|
{
|
|
if (ptS.distanceTo(ptE) < 0.001)
|
|
{
|
|
return;
|
|
}
|
|
std::vector<Node>::iterator it;
|
|
AcGePoint3d pt1 = ptS, pt2 = ptE;
|
|
for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++)
|
|
{
|
|
if ((*it).sys == sys)
|
|
{
|
|
AcDbLine *pNewLine = new AcDbLine();
|
|
if (type == eMainPipe)// 多洁具连接管线时,转换UCS为WCS下生成主干
|
|
{
|
|
pt1 = Ucs2Wcs(pt1);
|
|
pt2 = Ucs2Wcs(pt2);
|
|
}
|
|
|
|
pNewLine->setStartPoint(pt1);
|
|
pNewLine->setEndPoint(pt2);
|
|
|
|
PipeData node;
|
|
node.pLine = pNewLine;
|
|
if (Dir == eParallelX || Dir == eParallelY)
|
|
{
|
|
node.nId = m_nId++;
|
|
}
|
|
else // 其他方向的管线 不编号
|
|
{
|
|
node.nId = 0;
|
|
}
|
|
node.drection = Dir;
|
|
node.type = type;
|
|
((*it).data).push_back(node);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
AcDbLine* SanitarySysForDrain::GetPipeLine(TPipeSys::SysType sys, int nId)
|
|
{
|
|
AcDbLine *pLine = NULL;
|
|
std::vector<Node>::iterator it;
|
|
std::vector<PipeData>::iterator itP;
|
|
for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++)
|
|
{
|
|
if ((*it).sys != sys)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(itP = ((*it).data).begin(); itP != ((*it).data).end(); itP++)
|
|
{
|
|
if ((*itP).nId == nId)
|
|
{
|
|
pLine = (*itP).pLine;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return pLine;
|
|
}
|
|
|
|
void SanitarySysForDrain::GetPipeLine(TPipeSys::SysType sys, PipeDir Dir, std::map<int, AcDbLine*> &mapLine)
|
|
{
|
|
std::vector<Node>::iterator it;
|
|
std::vector<PipeData>::iterator itP;
|
|
for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++)
|
|
{
|
|
if ((*it).sys != sys)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(itP = ((*it).data).begin(); itP != ((*it).data).end(); itP++)
|
|
{
|
|
if ((*itP).drection == Dir && (*itP).nId > 0)
|
|
{
|
|
mapLine.insert(std::make_pair((*itP).nId, (*itP).pLine));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
int SanitarySysForDrain::GetNearestPipeForX(TPipeSys::SysType sys, const AcGePoint3d &pt)
|
|
{
|
|
// 所有x轴方向的管线
|
|
int nRet = -1;
|
|
PipeDir Dir = eParallelX;
|
|
std::map<int,AcDbLine*> mapLine;
|
|
GetPipeLine(sys, Dir, mapLine);
|
|
|
|
// 找到在XOY平面沿y轴方向距pt点最近的管线
|
|
std::map<int,AcDbLine*>::iterator it;
|
|
AcGePoint3d ptS, ptE, ptOnLine;
|
|
AcDbLine line;
|
|
AcGeVector3d vtDir = AcGeVector3d::kYAxis;
|
|
vtDir.rotateBy(Ucs2Wcs(0.0), AcGeVector3d::kZAxis);
|
|
double dDist = 0.0, dTemp = 0.0;
|
|
AcGePoint3d ptTemp = pt;
|
|
ptTemp.z = 0.0;
|
|
PipeType type = eError;
|
|
double dLen1 = 0.0, dLen2 = 0.0, dLen3 = 0.0;
|
|
bool bFirst = true;
|
|
for (it = mapLine.begin(); it != mapLine.end(); it++)
|
|
{
|
|
ptS = (*it).second->startPoint();
|
|
ptE = (*it).second->endPoint();
|
|
ptS.z = 0.0;
|
|
ptE.z = 0.0;
|
|
line.setStartPoint(ptS);
|
|
line.setEndPoint(ptE);
|
|
type = GetDataType(sys, (*it).first);
|
|
if ((ptS.distanceTo(ptE) + m_dChamferLen - 300 < -0.001) && type != eMainPipe)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
line.getClosestPointTo(ptTemp, vtDir, ptOnLine, Adesk::kTrue);
|
|
if (type == eMainPipe)
|
|
{
|
|
dLen1 = ptE.distanceTo(ptOnLine);
|
|
dLen2 = ptS.distanceTo(ptOnLine);
|
|
dLen3 = ptS.distanceTo(ptE);
|
|
|
|
if (dLen1 - dLen2 < 0.001 && dLen1 + dLen2 - dLen3 > 0.001 && (*it).first == 2) //投影点 在排水点方向
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
dTemp = ptTemp.distanceTo(ptOnLine);
|
|
if (bFirst || dDist - dTemp > 0.001)
|
|
{
|
|
bFirst = false;
|
|
dDist = dTemp;
|
|
nRet = (*it).first;
|
|
}
|
|
}
|
|
return nRet;
|
|
}
|
|
|
|
int SanitarySysForDrain::GetNearestPipeForY(TPipeSys::SysType sys, const AcGePoint3d &pt)
|
|
{
|
|
// 所有y轴方向的管线
|
|
int nRet = -1;
|
|
PipeDir Dir = eParallelY;
|
|
std::map<int,AcDbLine*> mapLine;
|
|
GetPipeLine(sys, Dir, mapLine);
|
|
|
|
// 找到在XOY平面上沿x轴方向距pt点最近的管线
|
|
std::map<int,AcDbLine*>::iterator it;
|
|
AcGePoint3d ptS, ptE, ptOnLine;
|
|
AcDbLine line;
|
|
AcGeVector3d vtDir = AcGeVector3d::kXAxis;
|
|
vtDir.rotateBy(Ucs2Wcs(0.0), AcGeVector3d::kZAxis);
|
|
double dDist = 0.0, dTemp = 0.0;
|
|
AcGePoint3d ptTemp = pt;
|
|
ptTemp.z = 0.0;
|
|
PipeType type = eError;
|
|
double dLen1 = 0.0, dLen2 = 0.0, dLen3 = 0.0;
|
|
bool bFirst = true;
|
|
for (it = mapLine.begin(); it != mapLine.end(); it++)
|
|
{
|
|
ptS = (*it).second->startPoint();
|
|
ptE = (*it).second->endPoint();
|
|
ptS.z = 0.0;
|
|
ptE.z = 0.0;
|
|
line.setStartPoint(ptS);
|
|
line.setEndPoint(ptE);
|
|
type = GetDataType(sys, (*it).first);
|
|
if ((ptS.distanceTo(ptE) + m_dChamferLen - 300 < -0.001) && type != eMainPipe)
|
|
{
|
|
continue;
|
|
}
|
|
line.getClosestPointTo(ptTemp, vtDir, ptOnLine, Adesk::kTrue);
|
|
if (type == eMainPipe)
|
|
{
|
|
dLen1 = ptE.distanceTo(ptOnLine);
|
|
dLen2 = ptS.distanceTo(ptOnLine);
|
|
dLen3 = ptS.distanceTo(ptE);
|
|
|
|
if (dLen1 - dLen2 < 0.001 && dLen1 + dLen2 - dLen3 > 0.001 && (*it).first == 2) //投影点 在排水点方向时,排除该管线
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
dTemp = ptTemp.distanceTo(ptOnLine);
|
|
if (bFirst || dDist - dTemp > 0.001)
|
|
{
|
|
bFirst = false;
|
|
dDist = dTemp;
|
|
nRet = (*it).first;
|
|
}
|
|
}
|
|
return nRet;
|
|
}
|
|
|
|
// 获取洁具点在管线上的投影点
|
|
bool SanitarySysForDrain::GetProjectPoint(TPipeSys::SysType sys, int nId, const AcGePoint3d &pt, AcGePoint3d &pt1)
|
|
{
|
|
std::vector<Node>::iterator it;
|
|
std::vector<PipeData>::iterator itP;
|
|
AcDbLine *pLine = NULL;
|
|
PipeDir Dir = eNone;
|
|
for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++)
|
|
{
|
|
if ((*it).sys == sys)
|
|
{
|
|
for(itP = ((*it).data).begin(); itP != ((*it).data).end(); itP++)
|
|
{
|
|
if ((*itP).nId == nId)
|
|
{
|
|
pLine = (*itP).pLine;
|
|
Dir = (*itP).drection;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (pLine == NULL || Dir == eOther || Dir == eNone)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
AcGePoint3d ptS = pLine->startPoint(), ptE = pLine->endPoint();
|
|
ptS.z = 0.0;
|
|
ptE.z = 0.0;
|
|
AcDbLine line(ptS, ptE);
|
|
AcGeVector3d vtDir = (Dir == eParallelX ? AcGeVector3d::kXAxis : AcGeVector3d::kYAxis);
|
|
vtDir.rotateBy(Ucs2Wcs(0.0), AcGeVector3d::kZAxis);
|
|
AcGePoint3d ptTemp = pt;
|
|
ptTemp.z = 0.0;
|
|
line.getClosestPointTo(ptTemp, pt1, Adesk::kTrue);
|
|
pLine->getClosestPointTo(pt1, AcGeVector3d::kZAxis, pt1, Adesk::kTrue);
|
|
return true;
|
|
}
|
|
|
|
void SanitarySysForDrain::GetSanitaryDrainPtInfo(Entity &ent, CString &csBlk, CString &csSysBlk, double &dRadius, double &dDang, double &dBigQ, double &dAngle, XPoint &ptDrain)
|
|
{
|
|
CString sDwbName, sHotElev, sFeedElev;
|
|
double dEle(0);
|
|
// zxl 2012.12.11 modify 获取洁具数据源
|
|
int nDataSourceType = GetSanitaryDataSourceType(ent);
|
|
if (nDataSourceType == 1 || nDataSourceType == 0)
|
|
{
|
|
GetSanitaryInfo(ent, ptDrain, csBlk, csSysBlk, dRadius, dDang, dBigQ, dEle, 2,
|
|
sDwbName, sFeedElev, sHotElev);//排水点信息
|
|
GetSanitaryDriection(ent, dAngle);
|
|
}
|
|
else
|
|
{
|
|
CSanitaryInfo sanInfo;
|
|
XPoint ptFeed, ptHeatFeed, ptDir, ptBlk;
|
|
GetLocSanitaryData(ent, sanInfo, ptFeed, ptHeatFeed, ptDrain, ptDir);
|
|
CString csDwb = g_csDwbPath + _T("TwtSys");
|
|
XString xsTmp;
|
|
LoadDwbBlock(csDwb, _T("00000147"), xsTmp);//排水点
|
|
csBlk = (const TCHAR*)xsTmp;
|
|
|
|
csSysBlk = sanInfo.sSysBlk2;
|
|
dDang = sanInfo.dNg;
|
|
dBigQ = sanInfo.dBigQ;
|
|
AcDbObjectId Id = NULL;
|
|
acdbGetObjectId(Id, ent);
|
|
AcDbBlockReference *pBlkRef = NULL;
|
|
acdbOpenObject(pBlkRef, Id, AcDb::kForRead);
|
|
if(!pBlkRef)
|
|
return;
|
|
ptBlk = pBlkRef->position();
|
|
pBlkRef->close();
|
|
dAngle = GetEntDriection(ptBlk, ptDir);
|
|
}
|
|
|
|
}
|
|
|
|
//设定排水附件
|
|
extern double GetEquipmentAdjustAngle(Entity &ent, double dEquipmentAngle, double dDrainAngle = 0.0, bool bDrain = false);
|
|
void SanitarySysForDrain::DrawDirtEquip(TPipeSys::SysType sys, SanitaryNode sanData, const AcGePoint3d &ptFrom)
|
|
{
|
|
AcDbObjectId id = sanData.idSanitary;
|
|
ads_name name;
|
|
acdbGetAdsName(name, id);
|
|
Entity ent = name;
|
|
|
|
CString csBlk, csSysBlk;
|
|
double dRadius(-1), dEle(0), dAngle(0), dDang(0), dBigQ(0);
|
|
XPoint ptDrain;
|
|
GetSanitaryDrainPtInfo(ent, csBlk, csSysBlk, dRadius, dDang, dBigQ, dAngle, ptDrain);//排水点信息
|
|
|
|
if (!ptDrain)
|
|
{
|
|
TCHAR szEqLay[256];
|
|
ent.GetData(8, szEqLay);
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbEquipment, pEquip);
|
|
if(pEquip)
|
|
{
|
|
if (_tcsicmp(szEqLay, LAY_EQ_DIRT) == 0 || _tcsicmp(szEqLay, LAY_EQ_USELESS) == 0 || _tcsicmp(szEqLay, LAY_EQUIP_LEAK) == 0)
|
|
{//地漏
|
|
AcGePoint3d ptIns = pEquip->GetLocation();
|
|
ptIns.z = ptFrom.z;
|
|
pEquip->SetLocation(ptIns);
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
// 镜像处理 zxl 2012.05.15 add
|
|
double dTmp = 0.0;
|
|
ent.GetData(50, &dTmp);
|
|
double xscale, yscale;
|
|
ent.GetData(41, &xscale);
|
|
ent.GetData(42, &yscale);
|
|
bool bMirror = false;
|
|
if(ent.Is(_T("INSERT")))
|
|
{
|
|
if(xscale < 0)
|
|
bMirror = true;
|
|
}
|
|
else if(ent.Is(_T("AEC_BLOCK_INSERT")))
|
|
{
|
|
if(yscale < 0)
|
|
bMirror = true;
|
|
}
|
|
if (bMirror)
|
|
{
|
|
dTmp += PI * 0.5;
|
|
}
|
|
dAngle = GetEquipmentAdjustAngle(ent, dTmp, dAngle, true);
|
|
|
|
ptDrain.z = ptFrom.z;
|
|
LoadTkBlock(csBlk);
|
|
LoadTkBlock(csSysBlk);
|
|
TDbEquipment *pEquip = new TDbEquipment;
|
|
pEquip->SetBlock2d(GetBlkIdByName(csBlk));
|
|
pEquip->SetLocation(ptDrain);
|
|
pEquip->SetDang(dDang);
|
|
pEquip->SetSpare(dBigQ);
|
|
pEquip->SetHidePipe(TRUE);
|
|
pEquip->SetAngle(dAngle);
|
|
if(dRadius < 0)
|
|
pEquip->SetScale(g_nDrainPtRadius);
|
|
else
|
|
pEquip->SetScale(dRadius);
|
|
|
|
pEquip->SetSysBlock((const TCHAR*)csSysBlk);
|
|
if(g_bBlk3D && (_tcsicmp(csSysBlk, _T("TWTSYS(00000101)")) == 0 || _tcsicmp(csSysBlk, _T("TWTSYS(00000102)")) == 0 || _tcsicmp(csSysBlk, _T("TWTSYS(00000103)")) == 0))
|
|
{
|
|
CString csDwb = g_csDwbPath + _T("TwtSys");
|
|
XString xsTmp;
|
|
if(_tcsicmp(csSysBlk, _T("TWTSYS(00000103)")) == 0)
|
|
{
|
|
if(LoadDwbBlock(csDwb, _T("00000363"), xsTmp) != RTNORM)//3dP存水弯
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
if(LoadDwbBlock(csDwb, _T("00000362"), xsTmp) != RTNORM)//3dS存水弯
|
|
return;
|
|
}
|
|
pEquip->SetBlock3d(GetBlockIdFromString(xsTmp));
|
|
}
|
|
pEquip->SetNumber(_T("CIRCLE-1"));
|
|
|
|
pEquip->setLayer(InitLayer(LAY_EQ_DIRT));
|
|
pEquip->setColor(AcCmColor()); //随层
|
|
AddToCurrentSpace(pEquip, Adesk::kTrue);
|
|
}
|
|
|
|
// 连接洁具产生的管线
|
|
void SanitarySysForDrain::GetLinkedPipe(std::vector<AcDbLine*> &vecPipe)
|
|
{
|
|
std::vector<Node>::iterator it;
|
|
std::vector<PipeData>::iterator itP;
|
|
for (it = m_vecPipe.begin(); it != m_vecPipe.end(); it++)
|
|
{
|
|
for(itP = ((*it).data).begin(); itP != ((*it).data).end(); itP++)
|
|
{
|
|
if ((*itP).drection == eParallelX || (*itP).drection == eParallelY)
|
|
{
|
|
vecPipe.push_back(new AcDbLine((*itP).pLine->startPoint(), ((*itP).pLine->endPoint())));
|
|
}
|
|
}
|
|
}
|
|
}
|