Files
envi-code/SourceCode/Code2026/tg_shs/shs_TwtKernal/ConcealInstallSanitarySys.cpp
T
2026-09-28 15:28:50 +08:00

1620 lines
39 KiB
C++

#include "StdAfx.h"
#include "ConcealInstallSanitarySys.h"
#define OFFSET_TIME 4 // 管线偏移次数
ConcealInstallSanitarySys::ConcealInstallSanitarySys()
{
m_dVPipeEle = DocGetMeterUnitDraw() ? 2.6 : 2600;
}
void ConcealInstallSanitarySys::AutoLinkSanitary( const SanitarySysData &data )
{
m_dPipeDn = GetPipeDn(data.id);
m_sysPipe = data.type;
m_idPipe = data.id;
InitWallEnt();
// 独立洁具
if (IsSingleSanitary(data))
{
LinkSingleSanitary(data);
return;
}
// 将洁具按距离给水点远近排序
SanitarySysData sanData = data;
std::vector<SanitaryNode> &vecSanNode = sanData.vecSanitaryNode;
Sort(vecSanNode, sanData.pt);
// 按洁具点距给水点远近连接洁具
LinkSanitary(sanData);
}
bool ConcealInstallSanitarySys::IsSingleSanitary( const SanitarySysData &data )
{
return false;
}
void ConcealInstallSanitarySys::LinkSingleSanitary( const SanitarySysData &data )
{
}
void ConcealInstallSanitarySys::LinkSanitary(const SanitarySysData &data)
{
// 获得最远洁具给水点 洁具id
std::vector<SanitaryNode> vecNode = data.vecSanitaryNode;
std::vector<SanitaryNode>::iterator it = vecNode.begin();
AcGePoint3d ptSan = it->pt;
AcDbObjectId idSan = it->idSanitary;
vecNode.erase(it);
// 确定X轴Y轴
ComfirmXAxisYAxis(data.id);
bool bSuccess = true;
if (IsVertivalPipe(data.id)) // 给水管是立管
{
// 给水管为立管时,设置给水点高度
m_ptFeed = data.pt;
m_ptFeed.z = m_dVPipeEle;
bSuccess = SelectMainPipeFromVPipe(m_ptFeed, ptSan, data.id, idSan);
}
else // 给水管是非立管
{
m_ptFeed = data.pt;
bSuccess = SelectMainPipeFromPipe(data.pt, ptSan, data.id, idSan);
}
if (!bSuccess)
{
return;
}
// 按距离远近依次连接洁具
it = vecNode.begin();
while(it != vecNode.end())
{
LinkSanitary(it->pt, it->idSanitary);
it++;
}
// 生成管线
CreatePipe();
// 添加附件
InsertFeedEquip();
}
void ConcealInstallSanitarySys::LinkSanitary( const AcGePoint3d &pt, const AcDbObjectId &idSan )
{
// 通过延长管线直接连接洁具
if (LinkSanitaryByExtendedPipe(pt, idSan))
{
return;
}
// 洁具直接连接最近的管线
LinkDate data;
data.ptSan = pt;
data.idSan = idSan;
data.nTransformTime = 0;
data.bInWall = false;
ModifyLinkSanPt(data);
if (GetLinkData(data))
{
LinkDate data1;
data1.ptSan = pt;
data1.idSan = idSan;
data1.nTransformTime = 1;
data1.bInWall = false;
ModifyLinkSanPt(data1);
if (GetLinkData(data1))
{
// 通过比较直接连接和一次变换连接的管线长度取近者连接
if (data.dLinkLen < data1.dLinkLen)
{
LinkSanitary2Pipe(data);
}
else
{
LinkSanitary2Pipe(data1);
}
}
else // 直接连接洁具与管线
{
LinkSanitary2Pipe(data);
}
return;
}
// 变换一次连接洁具
LinkDate data1;
data1.ptSan = pt;
data1.idSan = idSan;
data1.nTransformTime = 1;
data1.bInWall = false;
ModifyLinkSanPt(data1);
if (GetLinkData(data1))
{
LinkSanitary2Pipe(data1);
return;
}
// 变换两次连接洁具
LinkDate data2;
data2.ptSan = pt;
data2.idSan = idSan;
data2.nTransformTime = 2;
data2.bInWall = false;
ModifyLinkSanPt(data2);
if (GetLinkData(data2))
{
LinkSanitary2Pipe(data2);
return;
}
acutPrintf(_T("\n洁具不能连接!"));
}
void ConcealInstallSanitarySys::LinkSanitary( const AcGePoint3d &ptSan, const AcGePoint3d &ptFeed, const AcDbObjectId &idSan, PipeType type, bool bInSanPtWall, const AcGePoint3d &ptWall )
{
if (IsSanitaryPtEleSamePipe(idSan)) // 洁具给水点标高随支管标高
{
if (bInSanPtWall)
{
AcGePoint3d ptPrj = ptWall;
if (ptPrj.distanceTo(ptSan) > 0.001) // 洁具点在墙外
{
// 转换为真正的洁具点和墙体投影点
AcGePoint3d ptSanTemp = ptWall;
ptSanTemp.z = ptFeed.z;
CreateVirtualPipe(ptFeed, ptSanTemp, type);
m_mapSan.insert(std::make_pair(idSan, ptSanTemp));
}
else // 洁具点在墙内
{
AcGePoint3d ptTemp = ptSan;
ptTemp.z = ptFeed.z;
CreateVirtualPipe(ptFeed, ptTemp, type);
m_mapSan.insert(std::make_pair(idSan, ptTemp));
}
}
else
{
AcGePoint3d ptTemp = ptSan;
ptTemp.z = ptFeed.z;
CreateVirtualPipe(ptFeed, ptTemp, type);
m_mapSan.insert(std::make_pair(idSan, ptTemp));
}
}
else // 指定给水点标高
{
// 暗装时,得到给水点到最近墙上的投影点
if (bInSanPtWall)
{
AcGePoint3d ptPrj = ptWall;
// 转换为真正的洁具点和墙体投影点
ptPrj = ptSan;
AcGePoint3d ptSanTemp = ptWall;
ptPrj.z = ptFeed.z;
CreateVirtualPipe(ptFeed, ptPrj, type);
// 扣弯
AcGePoint3d pt = ptPrj;
pt.z = GetSanitaryPtEle(idSan); // 给水点标高
CreateVirtualPipe(ptPrj, pt, eVertival);
// 连接洁具
ptSanTemp.z = pt.z;
ptPrj.z = pt.z;
CreateVirtualPipe(ptPrj, ptSanTemp, eSmallPipe);
m_mapSan.insert(std::make_pair(idSan, ptSanTemp));
}
else // 找不到墙体时直接连接
{
AcGePoint3d ptSanTemp = ptSan;
ptSanTemp.z = ptFeed.z;
CreateVirtualPipe(ptFeed, ptSanTemp, type);
AcGePoint3d ptTemp = ptSan;
ptTemp.z = GetSanitaryPtEle(idSan);
CreateVirtualPipe(ptSanTemp, ptTemp, eVertival);
m_mapSan.insert(std::make_pair(idSan, ptTemp));
}
}
}
bool ConcealInstallSanitarySys::LinkSanitaryByExtendedPipe( const AcGePoint3d &ptSan, const AcDbObjectId &idSan )
{
// 获得所有可被延长的管线
std::vector<PipeData>::iterator it;
AcGePoint3d ptTemp = ptSan, ptPrj;
AcDbLine *pLine = NULL;
PipeType type;
for(it = m_vecPipeData.begin(); it != m_vecPipeData.end(); it++)
{
pLine = it->pLine;
if (pLine == NULL)
{
continue;
}
type = it->type;
if (type != eMainPipe && type != eBranch
&& type != eSmallPipe && type != eBranch2)
{
continue;
}
ptTemp.z = pLine->startPoint().z;
if (pLine->getClosestPointTo(ptTemp, ptPrj, Adesk::kTrue) == Acad::eOk)
{
if (ptTemp.distanceTo(ptPrj) > 0.001) // 不在直线内或其延长线上
{
continue;
}
// 洁具点标高
double dSanEle = 0.0;
if (IsSanitaryPtEleSamePipe(idSan)) // 随支管
{
dSanEle = pLine->startPoint().z;
}
else // 指定标高
{
dSanEle = GetSanitaryPtEle(idSan);
}
// 延长小支管连接洁具时,扣弯需要产生在墙体内
if (type == eSmallPipe)
{
//当洁具点在墙外时,需安装洁具
AcGePoint3d ptWall;
AcGeVector3d vtDir;
if (GetSanitaryDir(vtDir, idSan) && GetPtInWall(ptWall, ptTemp, vtDir) && ptWall.distanceTo(ptTemp) > 0.001)
{
ptWall.z = pLine->startPoint().z;
AcGePoint3d ptWallPrj;
if (pLine->getClosestPointTo(ptWall, ptWallPrj, Adesk::kTrue) == Acad::eOk
&& ptWall.distanceTo(ptWallPrj) < 0.001)
{
// 修改管线使之延伸到洁具点
ExtendLine(pLine, ptWallPrj);
// 连接洁具
ptWall.z = dSanEle;
CreateVirtualPipe(ptWallPrj, ptWall, eVertival);
ptTemp = ptSan;
ptTemp.z = dSanEle;
CreateVirtualPipe(ptWall, ptTemp, eSmallPipe);
m_mapSan.insert(std::make_pair(idSan, ptTemp));
return true;
}
}
}
// 修改管线使之延伸到洁具点
ExtendLine(pLine, ptPrj);
// 连接洁具
ptTemp = ptSan;
ptTemp.z = dSanEle;
LinkSanitary(ptTemp, ptPrj, idSan, eSmallPipe, false, AcGePoint3d());
return true;
}
}
return false;
}
bool ConcealInstallSanitarySys::PipeParallelXorYAxis( const AcDbObjectId &idPipe )
{
AcGeVector3d vtDir;
TDbPipe *pPipe = NULL;
acdbOpenObject(pPipe, idPipe, AcDb::kForRead);
if (pPipe != NULL)
{
vtDir = pPipe->StartPoint() - pPipe->EndPoint();
vtDir.z = 0.0;
pPipe->close();
}
else
{
return false;
}
if (vtDir.isParallelTo(m_vtXAxis) || vtDir.isParallelTo(m_vtYAxis))
{
return true;
}
return false;
}
void ConcealInstallSanitarySys::Sort( std::vector<SanitaryNode> &data, const AcGePoint3d &pt )
{
// 计算洁具点与给水点在XOY平面内的距离
std::map<double, SanitaryNode> mapDist;
std::vector<SanitaryNode>::iterator it;
AcGePoint3d pt1 = pt, pt2;
pt1.z = 0.0;
for (it = data.begin(); it != data.end(); it++)
{
pt2 = it->pt;
pt2.z = 0.0;
mapDist.insert(std::make_pair(pt1.distanceTo(pt2), *it));
}
// 按由大到小排序
data.clear();
std::map<double,SanitaryNode>::reverse_iterator itR;
for (itR = mapDist.rbegin(); itR != mapDist.rend(); itR++)
{
data.push_back(itR->second);
}
}
void ConcealInstallSanitarySys::SetFeedPointEle( double dEle )
{
m_dVPipeEle = dEle;
if (!DocGetCurMeterUnitDraw())
{
m_dVPipeEle *= 1000;
}
}
bool ConcealInstallSanitarySys::SelectMainPipeFromVPipe( const AcGePoint3d &ptWater, const AcGePoint3d &ptSan, const AcDbObjectId &idPipe, const AcDbObjectId &idSan )
{
// 确定主干管位置
LinkDate data;
data.ptLink = ptWater;
data.ptSan = ptSan;
data.idSan = idSan;
data.bInWall = false;
ModifyLinkSanPt(data);
if (!ConfirmMianPipePosFromVPipe(data, idPipe))
{
return false;
}
// 连接主干管
return LinkMainPipe(data);
}
bool ConcealInstallSanitarySys::SelectMainPipeFromPipe( const AcGePoint3d &ptWater, const AcGePoint3d &ptSan, const AcDbObjectId &idPipe, const AcDbObjectId &idSan )
{
// 给水管方向
AcGeVector3d vtPipeDir = m_vtXAxis;
TDbPipe *pPipe = NULL;
acdbOpenObject(pPipe, m_idPipe, AcDb::kForRead);
if (pPipe != NULL)
{
vtPipeDir = pPipe->StartPoint() - pPipe->EndPoint();
vtPipeDir.z = 0.0;
vtPipeDir.normalize();
pPipe->close();
}
LinkDate data;
data.ptLink = ptWater;
data.ptSan = ptSan;
data.idSan = idSan;
data.bInWall = false;
ModifyLinkSanPt(data);
if (!ConfirmMianPipePosFromPipe(data, vtPipeDir))
{
return false;
}
// 根据主干管铺设点调整给水点位置使之在给水管流入点
AcGePoint3d ptWaterNew = ptWater;
pPipe = NULL;
acdbOpenObject(pPipe, idPipe, AcDb::kForRead);
if (pPipe != NULL)
{
AcGeVector3d vtPipeDir = pPipe->StartPoint() - pPipe->EndPoint();
vtPipeDir.z = 0.0;
AcGeVector3d vtDir = data.vecPts[0] - ptWater;
vtDir.z = 0;
if (vtDir.isCodirectionalTo(vtPipeDir, m_tolVec))
{
ptWaterNew = pPipe->EndPoint();
}
else
{
ptWaterNew = pPipe->StartPoint();
}
pPipe->close();
}
// 连接主干管
data.ptLink = ptWaterNew;
return LinkMainPipe(data);
}
bool ConcealInstallSanitarySys::GetPipe( AcGePoint3d &ptS, AcGePoint3d &ptE, const AcGeVector3d &vtDir )
{
// 获得最近的墙体
AcGePoint3d pt1 = ptS, pt2 = ptE;
AcGeVector3d vtWall = pt1 - pt2;
vtWall.z = 0.0;
AcDbLine line;
double dWallThick = 0.0;
if (!GetNearestWall(pt2, vtWall, line, dWallThick))
{
line.setStartPoint(ptS);
line.setEndPoint(ptE);
dWallThick = 0.0;
}
for(int i = 0; i < OFFSET_TIME; i++)
{
// 检查是否与其他系统碰撞
if (!IsConflicting(pt1, pt2, m_dDistPipe2Pipe))
{
ptS = pt1;
ptE = pt2;
break;
}
// 将点移动到距墙m_dDistPipe2Wall * (i + 1)处
MovePipe(pt1, line, vtDir, dWallThick * 0.5 + m_dDistPipe2Wall * (i + 1));
MovePipe(pt2, line, vtDir, dWallThick * 0.5 + m_dDistPipe2Wall * (i + 1));
}
return true;
}
bool ConcealInstallSanitarySys::GetPtInWall( AcGePoint3d &ptWall, const AcGePoint3d &ptSan, const AcGeVector3d &vtDir )
{
// 找到与vtDir垂直的墙
AcGeVector3d vt = vtDir;
vt.z = 0.0;
vt.normalize();
AcGeVector3d vtWall;
std::vector<std::pair<XCurveSegment, XCurveSegment> > vecWall;
std::vector<std::pair<XCurveSegment, XCurveSegment> >::iterator it;
for (it = m_vecWallSide.begin(); it != m_vecWallSide.end(); it++)
{
if (it->first.GetCurveType() == CURVE_LINE)
{
vtWall = it->first.StartPoint() - it->first.EndPoint();
vtWall.z = 0.0;
if (vt.isPerpendicularTo(vtWall, m_tolVec))
{
vecWall.push_back(*it);
}
}
}
// 找到距离ptSan最近的墙体
XCurveSegment segNear, segFar;
if (!GetWallSide(ptSan, vecWall, segNear, segFar))
{
acutPrintf(_T("\n未找到墙体!"));
return false;
}
XPoly2D poly;
GetWallOutLine(poly, segNear, segFar);
poly.SetElevation(0.0);
AcGePoint3d pt = ptSan;
pt.z = 0.0;
if (((pt & poly) == PR_EDGE)
|| ((pt & poly) == PR_INSIDE)) // 点在墙内
{
ptWall = ptSan;
return true;
}
else // 点在墙外
{
AcGePoint3d ptS, ptE;
ptS = segNear.StartPoint();
ptE = segNear.EndPoint();
ptS.z = 0.0;
ptE.z = 0.0;
AcDbLine lineNear(ptS, ptE);
ptS = segFar.StartPoint();
ptE = segFar.EndPoint();
ptS.z = 0.0;
ptE.z = 0.0;
AcDbLine lineFar(ptS, ptE);
AcGePoint3d pt = ptSan, ptPrj;
pt.z = 0.0;
if ((lineNear.getClosestPointTo(pt, ptPrj, Adesk::kTrue) == Acad::eOk))
{
AcGeVector3d vt = ptPrj - pt;
vt.z = 0.0;
vt.normalize();
double dVPipeRadius = GetVPipeDrawRadius();
ptPrj += vt * dVPipeRadius;
ptWall = ptPrj;
return true;
}
}
return false;
}
void ConcealInstallSanitarySys::CreateVirtualPipe( const AcGePoint3d &ptS, const AcGePoint3d &ptE, const PipeType &type)
{
// 点重合直接返回
if (ptS.distanceTo(ptE) < 0.001)
{
return;
}
AcGeVector3d vtDir = ptS - ptE;
vtDir.z = 0.0;
PipeDir dir = GetPipeDir(vtDir);
AcDbLine *pNewLine = new AcDbLine();
pNewLine->setStartPoint(ptS);
pNewLine->setEndPoint(ptE);
PipeData node;
node.pLine = pNewLine;
node.nId = m_nId++;
node.drection = dir;
node.type = type;
m_vecPipeData.push_back(node);
}
bool ConcealInstallSanitarySys::ConfirmMianPipePosFromVPipe( LinkDate &data, const AcDbObjectId &idPipe )
{
// 从给水点沿m_vtXAxis后m_vtYAxis方向铺设管线
LinkDate dataX = data;
bool bXAxis = ConfirmMianPipePosFromPipe(dataX, m_vtXAxis);
// 从给水点沿m_vtYAxis后m_vtXAxis方向铺设管线
LinkDate dataY = data;
bool bYAxis = ConfirmMianPipePosFromPipe(dataY, m_vtYAxis);
if (bXAxis && bYAxis) // 两方向均可
{
AcGePoint3d ptWater = dataX.ptLink, ptSanX, ptX, ptSanY, ptY;
if (dataX.nTransformTime == 0)
{
ptX = dataX.vecPts[0];
ptSanX = dataX.ptSan;
}
else
{
ptX = dataX.vecPts[0];
ptSanX = dataX.vecPts[1];
}
if (dataY.nTransformTime == 0)
{
ptY = dataY.vecPts[0];
ptSanY = dataY.ptSan;
}
else
{
ptY = dataY.vecPts[0];
ptSanY = dataY.vecPts[1];
}
int nNumVPipeX = PassVertivalPipeNumByLine(ptWater, ptX); // 穿过立管个数
int nNumVPipeY = PassVertivalPipeNumByLine(ptWater, ptY);
if ((nNumVPipeX == 0 && nNumVPipeY == 0) || (nNumVPipeX > 0 && nNumVPipeY > 0)) // 都穿过立管或都不穿过立管
{
// 以经过门窗少为准
double dWidth = 0.0;
int nNumDoorX = PassWallNumByLine(ptX, ptSanX, dWidth); // 挨门窗个数
int nNumDoorY = PassWallNumByLine(ptY, ptSanY, dWidth);
if (nNumDoorX <= nNumDoorY) // 以穿过门窗少为准
{
data = dataX;
}
else
{
data = dataY;
}
}
else if (nNumVPipeX == 0)// 以不穿过立管为准
{
data = dataX;
}
else if (nNumVPipeY == 0)// 以不穿过立管为准
{
data = dataY;
}
}
else if (bXAxis && !bYAxis)
{
data = dataX;
}
else if (!bXAxis && bYAxis)
{
data = dataY;
}
else
{
return false;
}
return true;
}
bool ConcealInstallSanitarySys::ConfirmMianPipePosFromPipe( LinkDate &data, const AcGeVector3d &vtPipeDir)
{
AcGePoint3d ptSan = data.ptSan; // 洁具点
AcGePoint3d ptFeed = data.ptLink; // 供水点
AcDbObjectId idSan = data.idSan;
// 根据水管方向确定连接方向
AcGeVector3d vtLinkDir1, vtLinkDir2;
if (vtPipeDir.isParallelTo(m_vtXAxis, m_tolVec))
{
vtLinkDir1 = m_vtXAxis;
vtLinkDir2 = m_vtYAxis;
}
else if (vtPipeDir.isParallelTo(m_vtYAxis, m_tolVec))
{
vtLinkDir1 = m_vtYAxis;
vtLinkDir2 = m_vtXAxis;
}
else
{
return false;
}
// 先按m_vtXAxis后m_vtYAxis方向铺设管线时,管线交点
AcDbLine lineX(ptFeed, ptFeed + vtLinkDir1);
AcDbLine lineY(ptSan, ptSan + vtLinkDir2);
AcGePoint3dArray ptArr;
lineX.intersectWith(&lineY, AcDb::kExtendBoth, AcGePlane::kXYPlane, ptArr);
if (ptArr.length() != 1)
{
return false;
}
AcGePoint3d ptX = ptArr[0];
ptX.z = ptFeed.z;
// if (!IsPipe(idSan)) // 洁具 zxl 2013.11.11 del
{
if (!LayMainPipe(ptSan, ptX, m_dDistPipe2Pipe)) // 直接连接洁具连接线发生碰撞
{
// 偏移连接线
AcGeVector3d vtDir;
if (!GetSanitaryDir(vtDir, idSan))
{
acutPrintf(_T("\n无法获取洁具方向!"));
return false;
}
AcGeVector3d vtOffset;
if (vtDir.isParallelTo(vtLinkDir1, m_tolVec))
{
vtOffset = vtDir;
}
else if (vtDir.isPerpendicularTo(vtLinkDir1, m_tolVec))
{
if (!GetSanitaryOffsetDir(vtOffset, ptSan, idSan))
{
vtOffset = ptFeed - ptX;
vtOffset.z = 0.0;
vtOffset.normalize();
}
}
else // 偏移方向需要与m_vtXAxis或m_vtYAxis平行
{
return false;
}
// 转换一次
AcGePoint3d ptSan1 = ptSan;
if (OffsetMainPipe(ptSan1, ptX, m_dDistPipe2Pipe, m_dDistPipe2Wall, vtOffset, OFFSET_TIME))
{
if (LayMainPipe(ptSan, ptSan1, m_dDistPipe2Pipe)) // 无碰撞
{
data.nTransformTime = 1;
data.vecPts.push_back(ptX);
ptSan1.z = ptFeed.z;
data.vecPts.push_back(ptSan1);
}
else
{
// 转换两次
AcGeVector3d vtOffset2 = ptX - ptSan1;
vtOffset2.z = 0.0;
vtOffset2.normalize();
if (vtOffset2.isParallelTo(vtDir, m_tolVec))
{
vtOffset2 = vtDir;
}
AcGePoint3d ptSan2 = ptSan;
if (OffsetMainPipe(ptSan2, ptSan1, m_dDistPipe2Pipe, m_dDistPipe2Wall, vtOffset2, OFFSET_TIME))
{
if (LayMainPipe(ptSan, ptSan2, m_dDistPipe2Pipe))
{
data.nTransformTime = 2;
data.vecPts.push_back(ptX);
ptSan1.z = ptFeed.z;
data.vecPts.push_back(ptSan1);
ptSan2.z = ptFeed.z;
data.vecPts.push_back(ptSan2);
}
else // 找不到合适位置连接洁具
{
return false;
}
}
else // 找不到合适位置连接洁具
{
return false;
}
}
}
else // 找不到合适位置连接洁具
{
return false;
}
}
else // 直接连接洁具
{
data.nTransformTime = 0; // 无需转换
data.vecPts.push_back(ptX);
}
}
return true;
}
bool ConcealInstallSanitarySys::LayMainPipe( const AcGePoint3d &ptS, const AcGePoint3d &ptE, double dDist )
{
AcDbLine line(ptS, ptE);
if ((!PassParallelWall(ptS, ptE)) // 没有穿过平行墙体
&& !IsPassOtherSanitarySysPt(ptS, ptE) // 没有穿过其他系统洁具点
&& !IsCollidePipe(&line, dDist)) // 没有与其他系统平行管线发生碰撞
{
return true;
}
return false;
}
bool ConcealInstallSanitarySys::LinkMainPipe( LinkDate &data )
{
// 洁具实际上是管线 zxl 2013.11.11 del
// if (IsPipe(data.idSan))
// {
// // return LinkPipe(ptWater, ptS, ptE);
// return false;
// }
int nTransformTime = data.nTransformTime;
PipeType type;
AcGePoint3d ptFeed;
switch(nTransformTime)
{
case 0:
{
AcGePoint3d ptTemp = data.ptSan;
ptTemp.z = data.ptLink.z;
AcGePoint3d pt1 = data.ptLink, pt2 = data.vecPts[0];
ModifyMainPipePt(pt1, pt2);
CreateVirtualPipe(pt1, pt2, eMainPipe);
type = eMainPipe;
ptFeed = data.vecPts[0];
break;
}
case 1:
{
AcGePoint3d ptTemp = data.ptSan;
ptTemp.z = data.ptLink.z;
AcGePoint3d pt1 = data.ptLink, pt2 = data.vecPts[0];
ModifyMainPipePt(pt1, pt2);
CreateVirtualPipe(pt1, pt2, eMainPipe);
CreateVirtualPipe(data.vecPts[0], data.vecPts[1], eMainPipe);
type = eSmallPipe;
ptFeed = data.vecPts[1];
break;
}
case 2:
{
AcGePoint3d ptTemp = data.ptSan;
ptTemp.z = data.ptLink.z;
AcGePoint3d pt1 = data.ptLink, pt2 = data.vecPts[0];
ModifyMainPipePt(pt1, pt2);
CreateVirtualPipe(pt1, pt2, eMainPipe);
CreateVirtualPipe(data.vecPts[0], data.vecPts[1], eMainPipe);
CreateVirtualPipe(data.vecPts[1], data.vecPts[2], eBranch);
type = eSmallPipe;
ptFeed = data.vecPts[2];
break;
}
default:
return false;
}
// 连接洁具
AcGePoint3d ptSan = data.ptSan;
AcDbObjectId idSan = data.idSan;
LinkSanitary(ptSan, ptFeed, idSan, type, data.bInWall, data.ptInWall);
return true;
}
bool ConcealInstallSanitarySys::OffsetMainPipe( AcGePoint3d &ptS, AcGePoint3d &ptE, double dCollideDist, double dOffsetDist, const AcGeVector3d &vtOffset, int nOffsetTime )
{
AcDbLine line;
double dWallThick = 0.0;
AcGeVector3d vtWall = ptS - ptE;
vtWall.z = 0.0;
if (!GetNearestWall(ptS, vtWall, line, dWallThick))
{
line.setStartPoint(ptS);
line.setEndPoint(ptE);
dWallThick = 0.0;
}
bool bRet = false;
AcGePoint3d pt1 = ptS, pt2 = ptE;
for (int j = 0; j < nOffsetTime; j++)
{
MovePipe(pt1, line, vtOffset, dWallThick * 0.5 + dOffsetDist * (j + 1));
MovePipe(pt2, line, vtOffset, dWallThick * 0.5 + dOffsetDist * (j + 1));
if (LayMainPipe(pt1, pt2, dCollideDist))
{
ptS = pt1;
ptE = pt2;
bRet = true;
break;
}
}
return bRet;
}
void ConcealInstallSanitarySys::ComfirmXAxisYAxis( const AcDbObjectId &idPipe )
{
// 给水管为立管时,连接洁具时方向
m_vtXAxis = AcGeVector3d::kXAxis;
m_vtYAxis = AcGeVector3d::kYAxis;
m_vtXAxis.rotateBy(Ucs2Wcs(0.0), AcGeVector3d::kZAxis);
m_vtYAxis.rotateBy(Ucs2Wcs(0.0), AcGeVector3d::kZAxis);
// 非立管时,以管线方向和其垂涎方向为x轴y轴
if (!IsVertivalPipe(idPipe))
{
return;
AcGeVector3d vt = AcGeVector3d::kIdentity;
TDbPipe *pPipe = NULL;
acdbOpenObject(pPipe, idPipe, AcDb::kForRead);
if (pPipe != NULL)
{
vt = pPipe->StartPoint() - pPipe->EndPoint();
vt.z = 0.0;
pPipe->close();
}
// 管线垂直方向
AcGeVector3d vt2 = vt;
vt2.rotateBy(PI / 2, AcGeVector3d::kZAxis);
// 以与世界坐标系x轴夹角小的胃X轴方向
if (vt != AcGeVector3d::kIdentity)
{
AcGeVector3d vtX = AcGeVector3d::kXAxis;
double dAngle1 = vtX.angleTo(vt);
double dAngle2 = vtX.angleTo(vt2);
if (dAngle2 > dAngle1)
{
m_vtXAxis = vt;
m_vtYAxis = vt2;
}
else
{
m_vtXAxis = vt2;
m_vtYAxis = vt;
}
}
}
}
void ConcealInstallSanitarySys::CreatePipe()
{
// 获得给水点
AcGePoint3d ptFeed;
TDbPipe *pPipe = NULL;
acdbOpenObject(pPipe, m_idPipe, AcDb::kForRead);
if (pPipe != NULL)
{
if (pPipe->IsVertical())
{
ptFeed = pPipe->StartPoint();
}
else
{
if (pPipe->GetFlowDir() == TPipeSys::kFromStart)
{
ptFeed = pPipe->StartPoint();
}
else
{
ptFeed = pPipe->EndPoint();
}
}
pPipe->close();
}
std::vector<PipeData>::iterator it;
CString sLayer = GetPipeLayer(m_sysPipe);
CString sVPipeLayer = GetVPipeLayer(m_sysPipe);
InitPipeLayer(sLayer);
InitPipeLayer(sVPipeLayer);
int iPipeIdx = GetPipeLayerIdxByName(sLayer);
CString sLineType = GetPipeWireLayLineType(sLayer);
CString sMaterial = GetPipeMaterialByIdx(g_iPipeMaterial[iPipeIdx]);
CString sDnType = GetDnByMat(sMaterial);
CString sLineType2 = GetLayerLineType(sLayer);
for (it = m_vecPipeData.begin(); it != m_vecPipeData.end(); it++)
{
AcDbLine *pline = (*it).pLine;
// 供水点在管线中间的管线序切断分别设置流向
if (PipePassFeedPt(pline, ptFeed, sLayer))
{
continue;
}
TDbPipe *pPipe = new TDbPipe();
pPipe->SetRadius(g_nPipeRadius[iPipeIdx]);
if (it->type == eVertival)//设置立管显示半径
{
if(g_bPipeDouble[iPipeIdx])
{
pPipe->SetRadiusIn(g_nPipeRadius[iPipeIdx] / 2);
}
else
{
if(!g_bStandPipeArc)//传统扣弯
pPipe->SetRadiusIn(-2);
}
}
pPipe->SetStartPoint(pline->startPoint());
pPipe->SetEndPoint(pline->endPoint());
pPipe->SetFlowDir(TPipeSys::kFromStart);
if(sLineType2.Find(_T("TG")) > -1)
{
XLine lineTemp(asDblArray(pline->startPoint()), asDblArray(pline->endPoint()));
double nAng = lineTemp.Direction();
if(nAng > PI/2 && nAng < (PI/2*3 + 0.001))
{
pPipe->SetStartPoint(pline->endPoint());
pPipe->SetEndPoint(pline->startPoint());
pPipe->SetFlowDir(TPipeSys::kFromEnd);
}
}
pPipe->SetDnDiameter(m_dPipeDn);
pPipe->setLayer(sLayer);
pPipe->SetSysType(GetPipeSysByLayer(sLayer));
pPipe->setColor(AcCmColor()); //随层
pPipe->SetPipeWeight(g_nPipeWidth[iPipeIdx]);
pPipe->setLinetype(sLineType);
pPipe->setLineWeight(AcDb::kLnWtByLayer);
pPipe->SetMaterial(g_iPipeMaterial[iPipeIdx]);
pPipe->SetLabel(sDnType);
AddToCurrentSpace(pPipe, Adesk::kTrue);
}
// 更新给水管
ModifyFeedPipe();
}
SanitarySys::PipeDir ConcealInstallSanitarySys::GetPipeDir( const AcGeVector3d &vtDir )
{
PipeDir dir = eNone;
if (vtDir.isParallelTo(m_vtXAxis))
{
dir = eParallelX;
}
else if (vtDir.isParallelTo(m_vtYAxis))
{
dir = eParallelY;
}
else
{
dir = eOther;
}
return dir;
}
void ConcealInstallSanitarySys::ModifyFeedPipe()
{
TDbPipe *pPipe = NULL;
acdbOpenObject(pPipe, m_idPipe, AcDb::kForWrite);
if (pPipe != NULL)
{
if (pPipe->IsVertical())
{
AcDbLine line(pPipe->StartPoint(), pPipe->EndPoint());
AcGePoint3d pt;
if (line.getClosestPointTo(m_ptFeed, pt, Adesk::kTrue) == Acad::eOk)
{
AcGePoint3d ptS = pPipe->StartPoint();
AcGePoint3d ptE = pPipe->EndPoint();
double dDistS = ptS.distanceTo(pt);
double dDistE = ptE.distanceTo(pt);
double dDist = ptS.distanceTo(ptE);
if (fabs(dDist - dDistE - dDistS) > 0.001) // 点在管线延长线上
{
if (dDistS < dDistE)
{
pPipe->SetStartPoint(pt);
}
else
{
pPipe->SetEndPoint(pt);
}
}
}
}
else
{
pPipe->erase();
}
pPipe->close();
}
}
bool ConcealInstallSanitarySys::IsPipe( const AcDbObjectId idEnt )
{
ads_name name;
acdbGetAdsName(name, idEnt);
Entity ent(name);
if (ent.Is(_T("ATS_PIPE")))
{
return true;
}
return false;
}
bool ConcealInstallSanitarySys::LinkPipe( const AcGePoint3d &ptWater, const AcGePoint3d &ptS, const AcGePoint3d &ptE )
{
CreateVirtualPipe(ptWater, ptS, eMainPipe);
CreateVirtualPipe(ptS, ptE, eMainPipe);
return true;
}
double ConcealInstallSanitarySys::GetVPipeDrawRadius()
{
double dRadius = 0.5 * DocGetPScale();
TDbPipe *pPipe = NULL;
acdbOpenObject(pPipe, m_idPipe, AcDb::kForRead);
if (pPipe != NULL)
{
dRadius = pPipe->GetRadius() * DocGetPScale();
pPipe->close();
}
return dRadius;
}
void ConcealInstallSanitarySys::GetPtToLineDist( std::multimap<double, std::pair<AcDbLine*, AcGePoint3d> > &mapDist, const AcGePoint3d &pt, const AcGeVector3d &vtDir, PipeType type )
{
std::vector<PipeData>::iterator it;
AcGeVector3d vtTemp;
AcGePoint3d ptPrj, ptTemp = pt, ptS, ptE;
AcDbLine *pLine = NULL;
AcDbLine line;
for (it = m_vecPipeData.begin(); it != m_vecPipeData.end(); it++)
{
pLine = it->pLine;
if (pLine == NULL || it->type != type)
{
continue;
}
vtTemp = pLine->startPoint() - pLine->endPoint();
vtTemp.z = 0.0;
if (vtTemp.isParallelTo(vtDir, m_tolVec))
{
ptS = pLine->startPoint();
ptE = pLine->endPoint();
ptS.z = 0.0;
ptE.z = 0.0;
line.setStartPoint(ptS);
line.setEndPoint(ptE);
if (line.getClosestPointTo(ptTemp, ptPrj, Adesk::kTrue) == Acad::eOk)
{
double dDist = ptTemp.distanceTo(ptPrj);
ptPrj.z = pLine->startPoint().z;
mapDist.insert(std::make_pair(dDist, std::make_pair(pLine, ptPrj)));
}
}
}
}
void ConcealInstallSanitarySys::ExtendLine( AcDbLine *pLine, const AcGePoint3d &pt )
{
ASSERT(pLine != NULL);
AcGePoint3d ptS = pLine->startPoint();
AcGePoint3d ptE = pLine->endPoint();
double dDistS = ptS.distanceTo(pt);
double dDistE = ptE.distanceTo(pt);
double dDist = ptS.distanceTo(ptE);
double dLen = dDistS + dDistE;
if (fabs(dLen - dDist) > 0.001 && dLen > dDist) // 在延长线上
{
if (dDistS < dDistE)
{
pLine->setStartPoint(pt);
}
else
{
pLine->setEndPoint(pt);
}
}
}
bool ConcealInstallSanitarySys::OffsetLine( AcGePoint3d &ptS, AcGePoint3d &ptE, double dCollideDist, const AcGeVector3d &vtOffset, int nOffsetTime)
{
AcDbLine line;
double dWallThick = 0.0;
AcGeVector3d vtWall = ptS - ptE;
vtWall.z = 0.0;
if (!GetNearestWall(ptS, vtWall, line, dWallThick))
{
line.setStartPoint(ptS);
line.setEndPoint(ptE);
dWallThick = 0.0;
}
bool bRet = false;
AcGePoint3d pt1 = ptS, pt2 = ptE;
for (int j = 0; j < nOffsetTime; j++)
{
MovePipe(pt1, line, vtOffset, dWallThick * 0.5 + m_dDistPipe2Wall * (j + 1));
MovePipe(pt2, line, vtOffset, dWallThick * 0.5 + m_dDistPipe2Wall * (j + 1));
if (!IsConflicting(pt1, pt2, dCollideDist))
{
ptS = pt1;
ptE = pt2;
bRet = true;
break;
}
}
return bRet;
}
void ConcealInstallSanitarySys::GetOffsetDir( AcGeVector3d &vtOffset, const AcGePoint3d &ptSan, const AcGeVector3d &vtSanitaryDir, const AcGeVector3d &vtLinkedPipe, const AcDbObjectId &idSan )
{
if (vtSanitaryDir.isParallelTo(vtLinkedPipe, m_tolVec)) // 洁具方向与洁具连接的管线方向平行
{
if (!GetSanitaryOffsetDir(vtOffset, ptSan, idSan)) // 给水点相对另一个给水点的方向
{
vtOffset = vtLinkedPipe;
vtOffset.rotateBy(PI / 2, AcGeVector3d::kZAxis);
}
}
else if (vtSanitaryDir.isPerpendicularTo(vtLinkedPipe, m_tolVec))
{
vtOffset = vtSanitaryDir;
}
else
{
vtOffset = vtLinkedPipe;
vtOffset.rotateBy(PI / 2, AcGeVector3d::kZAxis);
}
vtOffset.z = 0.0;
vtOffset.normalize();
// 偏移方向有可能需与m_vtXAxis或m_vtYAxis平行
std::map<double, AcGeVector3d> mapDir;
double dAngle = vtOffset.angleTo(m_vtYAxis);
mapDir.insert(std::make_pair(dAngle, m_vtYAxis));
dAngle = vtOffset.angleTo(-m_vtYAxis);
mapDir.insert(std::make_pair(dAngle, -m_vtYAxis));
dAngle = vtOffset.angleTo(m_vtXAxis);
mapDir.insert(std::make_pair(dAngle, m_vtXAxis));
dAngle = vtOffset.angleTo(-m_vtXAxis);
mapDir.insert(std::make_pair(dAngle, -m_vtXAxis));
vtOffset = mapDir.begin()->second;
}
//////////////////////////////////////////////////////////////////////////
void ConcealInstallSanitarySys::DrawSanitaryDir( const AcGePoint3d &pt, const AcGeVector3d &vtDir )
{
AcGeVector3d vt = vtDir;
vt.normalize();
XPoint ptE = pt + vt * 500;
AcGeVector3d vt1 = vt;
vt1.rotateBy(PI/2, AcGeVector3d::kZAxis);
XPoint pt1 = ptE - vt * 50 + vt1 * 50;
XPoint pt2 = ptE - vt * 50 - vt1 * 50;
XLine line1(asDblArray(pt), ptE);
line1.Make();
XLine line2(ptE, pt1);
line2.Make();
XLine line3(ptE, pt2);
line3.Make();
}
bool ConcealInstallSanitarySys::GetLinkData( LinkDate &data )
{
// 连接洁具时可参考的四个方向的管线
AcGeVector3d vtLinkDir1 = m_vtXAxis;
AcGeVector3d vtLinkDir2 = m_vtXAxis;
AcGeVector3d vtLinkDir3 = m_vtXAxis;
AcGeVector3d vtLinkDir4 = m_vtXAxis;
vtLinkDir2.rotateBy(PI * 0.5, AcGeVector3d::kZAxis);
vtLinkDir3.rotateBy(PI, AcGeVector3d::kZAxis);
vtLinkDir4.rotateBy(PI * 1.5, AcGeVector3d::kZAxis);
AcDbObjectId idSan = data.idSan;
AcGePoint3d ptSan = data.ptSan;
// 洁具方向
AcGeVector3d vtSanitaryDir;
GetSanitaryDir(vtSanitaryDir, idSan);
// 在四个方向连接洁具
AcDbLine *pLineTemp = NULL;
double dDist = 0.0;
AcGePoint3d ptLinkTemp, ptCornerTemp;
std::multimap<double, LinkDate> mapLinkDist;
AcGeVector3d vtOffset; // 偏移方向
GetOffsetDir(vtOffset, ptSan, vtSanitaryDir, vtLinkDir1, idSan);
LinkDate DataTemp1 = data;
if (GetLinkData(DataTemp1, vtLinkDir1, m_vtYAxis, vtOffset))
{
mapLinkDist.insert(std::make_pair(DataTemp1.dLinkLen, DataTemp1));
}
LinkDate DataTemp2 = data;
GetOffsetDir(vtOffset, ptSan, vtSanitaryDir, vtLinkDir2, idSan);
if (GetLinkData(DataTemp2, vtLinkDir2, m_vtXAxis, vtOffset))
{
mapLinkDist.insert(std::make_pair(DataTemp2.dLinkLen, DataTemp2));
}
LinkDate DataTemp3 = data;
GetOffsetDir(vtOffset, ptSan, vtSanitaryDir, vtLinkDir3, idSan);
if (GetLinkData(DataTemp3, vtLinkDir3, m_vtYAxis, vtOffset))
{
mapLinkDist.insert(std::make_pair(DataTemp3.dLinkLen, DataTemp3));
}
LinkDate DataTemp4 = data;
GetOffsetDir(vtOffset, ptSan, vtSanitaryDir, vtLinkDir4, idSan);
if (GetLinkData(DataTemp4, vtLinkDir4, m_vtXAxis, vtOffset))
{
mapLinkDist.insert(std::make_pair(DataTemp4.dLinkLen, DataTemp4));
}
// 找到连接线最短的路径
std::multimap<double, LinkDate>::iterator it;
it = mapLinkDist.begin();
if (it != mapLinkDist.end())
{
data = (*it).second;
return true;
}
return false;
}
bool ConcealInstallSanitarySys::GetLinkData( LinkDate &data, const AcGeVector3d &vtLink, const AcGeVector3d &vtPipe, const AcGeVector3d &vtOffset )
{
// 获得点pt到所有与vtLine平行的直线的距离
AcGePoint3d ptSan = data.ptSan;
std::multimap<double, std::pair<AcDbLine*, AcGePoint3d> > mapData;
GetPtToLineDist(mapData, ptSan, vtPipe, eMainPipe);
GetPtToLineDist(mapData, ptSan, vtPipe, eBranch);
GetPtToLineDist(mapData, ptSan, vtPipe, eBranch2);
// 找出与vtDir同向的直线
std::multimap<double, std::pair<AcDbLine*, AcGePoint3d> > mapNew;
std::multimap<double, std::pair<AcDbLine*, AcGePoint3d> >::iterator it;
AcGeVector3d vtTemp;
for (it = mapData.begin(); it != mapData.end(); it++)
{
vtTemp = ((*it).second).second - ptSan;
vtTemp.z = 0.0;
vtTemp.normalize();
if (vtTemp.isCodirectionalTo(vtLink, m_tolVec)) // 与连接方向同向
{
mapNew.insert(*it);
}
}
// 获得同向最近的直线
bool bRet = false;
it = mapNew.begin();
if (it != mapNew.end())
{
ptSan.z = (*it).second.second.z;
int nTransfromTime = data.nTransformTime;
switch(nTransfromTime)
{
case 0:
{
/*
*
*
ptSan*********************** ptLink
*
*
洁具连接管线示意图,ptSan为洁具点
*/
if (!IsConflicting(ptSan, ((*it).second).second, m_dDistPipe2Pipe))
{
data.pLine = ((*it).second).first;
data.ptLink = ((*it).second).second;
if (!data.bInWall) // 洁具点在墙内
{
data.dLinkLen = (*it).first;
}
else // 在墙外
{
data.dLinkLen = (data.ptInWall).distanceTo(((*it).second).second);
}
bRet = true;
}
break;
}
case 1:
{
/*
*
*
ptConer*********************** ptLink
* *
* *
*
ptSan
洁具连接管线示意图,ptSan为洁具点
*/
AcGePoint3d pt1 = (*it).second.second, pt2 = ptSan;
AcGeVector3d vtMove = vtOffset;
if (OffsetLine(pt1, pt2, m_dDistPipe2Wall, vtMove, OFFSET_TIME))
{
if (!IsConflicting(pt2, ptSan, m_dDistPipe2Pipe))
{
data.pLine = ((*it).second).first;
data.ptLink = pt1;
data.vecPts.push_back(pt2);
if (!data.bInWall)
{
data.dLinkLen = (*it).first + GetDist(ptSan, pt2);
}
else
{
data.dLinkLen = (*it).first + GetDist(data.ptInWall, pt2);
}
bRet = true;
}
}
break;
}
case 2:
{
/*
*
*
ptCorner1*********************** ptLink
* *
* *
*
ptSan*******ptCorner2
洁具连接管线示意图,ptSan为洁具点
*/
AcGePoint3d pt1 = (*it).second.second, pt2 = ptSan;
AcGeVector3d vtMove = vtOffset;
if (OffsetLine(pt1, pt2, m_dDistPipe2Wall, vtMove, OFFSET_TIME))
{
AcGeVector3d vtMove2 = pt1 - pt2;
vtMove2.z = 0.0;
vtMove2.normalize();
AcGePoint3d pt3 = ptSan, pt4 = pt2;
if (IsConflicting(pt3, pt4, m_dDistPipe2Pipe))
{
if (OffsetLine(pt3, pt4, m_dDistPipe2Wall, vtMove2, OFFSET_TIME) && !IsConflicting(ptSan, pt3, m_dDistPipe2Pipe))
{
data.pLine = ((*it).second).first;
data.ptLink = pt1;
data.dLinkLen = (*it).first + GetDist(pt3, pt4);
data.vecPts.push_back(pt4);
data.vecPts.push_back(pt3);
bRet = true;
}
}
}
break;
}
}
}
return bRet;
}
void ConcealInstallSanitarySys::LinkSanitary2Pipe( const LinkDate &data )
{
AcGePoint3d ptFeed;
PipeType type;
switch(data.nTransformTime)
{
case 0:
{
ExtendLine(data.pLine, data.ptLink);
ptFeed = data.ptLink;
type = eSmallPipe;
break;
}
case 1:
{
if (data.vecPts.size() == 1)
{
ExtendLine(data.pLine, data.ptLink);
CreateVirtualPipe(data.ptLink, data.vecPts[0], eBranch);
ptFeed = data.vecPts[0];
type = eSmallPipe;
}
break;
}
case 2:
{
if (data.vecPts.size() == 2)
{
ExtendLine(data.pLine, data.ptLink);
CreateVirtualPipe(data.ptLink, data.vecPts[0], eBranch);
CreateVirtualPipe(data.vecPts[0], data.vecPts[1], eBranch);
ptFeed = data.vecPts[1];
type = eSmallPipe;
}
break;
}
default:
return;
}
if (IsPipe(data.idSan))
{
AcGePoint3d ptSan = data.ptSan;
ptSan.z = ptFeed.z;
CreateVirtualPipe(ptFeed, ptSan, eMainPipe);
}
else
{
LinkSanitary(data.ptSan, ptFeed, data.idSan, type, data.bInWall, data.ptInWall);
}
}
double ConcealInstallSanitarySys::GetDist( const AcGePoint3d &pt1, const AcGePoint3d &pt2 )
{
AcGePoint3d ptS = pt1, ptE = pt2;
ptS.z = 0.0;
ptE.z = 0.0;
return ptS.distanceTo(ptE);
}
void ConcealInstallSanitarySys::ModifyLinkSanPt(LinkDate &data)
{
// 当洁具点在墙外时,以洁具点暗装时到墙体的投影点为虚拟洁具点进行连接
AcGeVector3d vtDir;
GetSanitaryDir(vtDir, data.idSan);
AcGePoint3d ptSan = data.ptSan, ptWall;
if (GetPtInWall(ptWall, ptSan, vtDir) && ptSan.distanceTo(ptWall) > 0.001)
{
data.ptSan = ptWall; // 将洁具点到墙体的投影点当做待连接洁具点
data.ptInWall = ptSan;
data.bInWall = true;
}
}
bool ConcealInstallSanitarySys::PipePassFeedPt( AcDbLine *pLine, const AcGePoint3d &ptFeed, const CString &sLayer)
{
AcGePoint3d ptTemp = ptFeed;
AcGePoint3d ptS = pLine->startPoint();
AcGePoint3d ptE = pLine->endPoint();
ptTemp.z = ptS.z;
// 供水点在线的端点处
if (ptS.distanceTo(ptTemp) < 0.001 || ptE.distanceTo(ptTemp) < 0.001)
{
return false;
}
// 供水点在线内
double dLen = ptS.distanceTo(ptE);
double dDist = ptS.distanceTo(ptTemp) + ptE.distanceTo(ptTemp);
if (fabs(dDist - dLen) < 0.001)
{
int iPipeIdx = GetPipeLayerIdxByName(sLayer);
CString sLineType = GetPipeWireLayLineType(sLayer);
CString sMaterial = GetPipeMaterialByIdx(g_iPipeMaterial[iPipeIdx]);
CString sDnType = GetDnByMat(sMaterial);
CString sLineType2 = GetLayerLineType(sLayer);
TDbPipe *pPipe = new TDbPipe();
pPipe->SetStartPoint(ptTemp);
pPipe->SetEndPoint(ptS);
pPipe->SetFlowDir(TPipeSys::kFromStart);
if(sLineType2.Find(_T("TG")) > -1)
{
XLine line(asDblArray(ptTemp), asDblArray(ptS));
double nAng = line.Direction();
if(nAng > PI/2 && nAng < (PI/2*3 + 0.001))
{
pPipe->SetStartPoint(ptS);
pPipe->SetEndPoint(ptTemp);
pPipe->SetFlowDir(TPipeSys::kFromEnd);
}
}
pPipe->SetDnDiameter(m_dPipeDn);
pPipe->setLayer(sLayer);
pPipe->SetSysType(GetPipeSysByLayer(sLayer));
pPipe->setColor(AcCmColor()); //随层
pPipe->SetPipeWeight(g_nPipeWidth[iPipeIdx]);
pPipe->setLinetype(sLineType);
pPipe->setLineWeight(AcDb::kLnWtByLayer);
pPipe->SetMaterial(g_iPipeMaterial[iPipeIdx]);
pPipe->SetLabel(sDnType);
AddToCurrentSpace(pPipe, Adesk::kTrue);
TDbPipe *pPipe2 = new TDbPipe();
pPipe2->SetStartPoint(ptTemp);
pPipe2->SetEndPoint(ptE);
pPipe2->SetFlowDir(TPipeSys::kFromStart);
if(sLineType2.Find(_T("TG")) > -1)
{
XLine line(asDblArray(ptTemp), asDblArray(ptE));
double nAng = line.Direction();
if(nAng > PI/2 && nAng < (PI/2*3 + 0.001))
{
pPipe2->SetStartPoint(ptE);
pPipe2->SetEndPoint(ptTemp);
pPipe2->SetFlowDir(TPipeSys::kFromEnd);
}
}
pPipe2->SetDnDiameter(m_dPipeDn);
pPipe2->setLayer(sLayer);
pPipe2->SetSysType(GetPipeSysByLayer(sLayer));
pPipe2->setColor(AcCmColor()); //随层
pPipe2->SetPipeWeight(g_nPipeWidth[iPipeIdx]);
pPipe2->setLinetype(sLineType);
pPipe2->setLineWeight(AcDb::kLnWtByLayer);
pPipe2->SetMaterial(g_iPipeMaterial[iPipeIdx]);
pPipe2->SetLabel(sDnType);
AddToCurrentSpace(pPipe2, Adesk::kTrue);
return true;
}
// 供水点不在线上
return false;
}
void ConcealInstallSanitarySys::ModifyMainPipePt( AcGePoint3d &ptS, AcGePoint3d &ptE )
{
TDbPipe *pPipe = NULL;
acdbOpenObject(pPipe, m_idPipe, AcDb::kForRead);
if (pPipe != NULL)
{
if (!pPipe->IsVertical())
{
AcGePoint3d pt1 = pPipe->StartPoint();
AcGePoint3d pt2 = pPipe->EndPoint();
AcGeVector3d vt1 = pt1 - pt2;
AcGeVector3d vt2 = ptS - ptE;
AcGeTol tol;
tol.setEqualVector(0.001);
if (vt2.isParallelTo(vt1, tol))
{
if (ptS.distanceTo(pt1) < 0.001)
{
if (ptS.distanceTo(ptE) < pt1.distanceTo(pt2))
{
ptE = pt2;
}
}
else if (ptS.distanceTo(pt2) < 0.001)
{
if (ptS.distanceTo(ptE) < pt1.distanceTo(pt2))
{
ptE = pt1;
}
}
}
}
pPipe->close();
}
}
void ConcealInstallSanitarySys::InsertFeedEquip()
{
std::map<AcDbObjectId,AcGePoint3d>::iterator it;
for (it = m_mapSan.begin(); it != m_mapSan.end(); it++)
{
DrawFeedEquip(it->first, it->second);
}
}