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

937 lines
25 KiB
C++

#include "StdAfx.h"
#include "SanitarySysForFeedWater.h"
#include "WallIdentify.h"
#include "NewSanitaryDefineDlg.h"
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);
#define WALL_MAX_THICK (DocGetCurMeterUnitDraw() ? 1 : 1000) // 墙体最大厚度
SanitarySysForFeedWater::SanitarySysForFeedWater()
{
m_nId = 0;
BOOL bMeterUnit = DocGetCurMeterUnitDraw();
m_dDistPipe2Wall = (bMeterUnit ? 0.12 : 120);
m_dDistPipe2Pipe = (bMeterUnit ? 0.07 : 70);
m_dDistSearchWall = (bMeterUnit ? 1 : 1000);
m_tolVec.setEqualVector(0.001);
}
double SanitarySysForFeedWater::SetDistPipe2Wall(const double dDist)
{
BOOL bMeterUnit = DocGetCurMeterUnitDraw();
m_dDistPipe2Wall = (bMeterUnit ? dDist / 1000 : dDist);
return m_dDistPipe2Wall;
}
SanitarySysForFeedWater::~SanitarySysForFeedWater()
{
DeleteLine();
}
void SanitarySysForFeedWater::GetLinkedPipe( std::vector<AcDbLine*> &vecPipe )
{
std::vector<PipeData>::iterator it;
for (it = m_vecPipeData.begin(); it != m_vecPipeData.end(); it++)
{
if (it->drection == eParallelX || it->drection == eParallelY)
{
AcDbLine *pLine = it->pLine;
if (pLine == NULL)
{
continue;
}
vecPipe.push_back(new AcDbLine(pLine->startPoint(), pLine->endPoint()));
}
}
}
void SanitarySysForFeedWater::SetCollidePipe( const std::vector<AcDbLine*> &vecLine )
{
DeleteLine();
std::vector<AcDbLine*>::const_iterator it;
for (it = vecLine.begin(); it != vecLine.end(); it++)
{
m_vecCollidePipe.push_back(new AcDbLine((*it)->startPoint(), (*it)->endPoint()));
}
}
bool SanitarySysForFeedWater::GetNearestWall( const AcGePoint3d &pt, const AcGeVector3d &vtDir, AcDbLine &line, double &dWallThick )
{
// 在XOY平面内与vtDir平行的墙体
AcGeVector3d vt = vtDir;
vt.z = 0.0;
std::vector<std::pair<XCurveSegment, XCurveSegment> > vecWall;
std::vector<std::pair<XCurveSegment, XCurveSegment> >::iterator it;
AcGeVector3d vtWall;
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 (vtWall.isParallelTo(vt, m_tolVec))
{
vecWall.push_back(*it);
}
}
}
// 找到距离pt最近的墙体
XCurveSegment segNear, segFar;
if (GetWallSide(pt, vecWall, segNear, segFar))
{
// 是否在规定范围内
AcDbLine lineNear(segNear.StartPoint(), segNear.EndPoint());
if (!IsInBound(pt, lineNear, WALL_MAX_THICK))
{
return false;
}
// 墙体厚度
AcGePoint3d ptS = segFar.StartPoint();
AcGePoint3d ptE = segFar.EndPoint();
ptS.z = 0.0;
ptE.z = 0.0;
AcDbLine lineTemp(ptS, ptE);
AcGePoint3d pt = segNear.StartPoint();
pt.z = 0.0;
AcGePoint3d ptPrj;
if (lineTemp.getClosestPointTo(pt, ptPrj, Adesk::kTrue) == Acad::eOk)
{
dWallThick = pt.distanceTo(ptPrj);
AcGeVector3d vt = pt - ptPrj;
vt.normalize();
line.setStartPoint(segFar.StartPoint() + vt * dWallThick * 0.5);
line.setEndPoint(segFar.EndPoint() + vt * dWallThick * 0.5);
return true;
}
}
return false;
}
bool SanitarySysForFeedWater::GetNearestWall( const AcGePoint3d &pt, double dDist, XCurveSegment &segNear, XCurveSegment &segFar )
{
// 找到距离pt最近的墙体
if (GetWallSide(pt, m_vecWallSide, segNear, segFar))
{
// 是否在规定范围内
AcDbLine lineNear(segNear.StartPoint(), segNear.EndPoint());
if (IsInBound(pt, lineNear, WALL_MAX_THICK))
{
return true;
}
}
return false;
}
double SanitarySysForFeedWater::GetDistLines( const AcDbLine *pLine1, const AcDbLine *pLine2 )
{
ASSERT(pLine1 != NULL && pLine2 != NULL);
// 构造xoy平面上的直线
AcGePoint3d ptS = pLine1->startPoint();
AcGePoint3d ptE = pLine1->endPoint();
ptS.z = 0.0;
ptE.z = 0.0;
AcDbLine line1(ptS, ptE);
ptS = pLine2->startPoint();
ptE = pLine2->endPoint();
ptS.z = 0.0;
ptE.z = 0.0;
AcDbLine line2(ptS, ptE);
// 求两直线间的实际最短距离
ptS = line1.startPoint();
ptE = line1.endPoint();
AcGePoint3d ptSPrj, ptEPrj;
line2.getClosestPointTo(ptS, ptSPrj);
line2.getClosestPointTo(ptE, ptEPrj);
double dDist1 = ptS.distanceTo(ptSPrj);
double dDist2 = ptE.distanceTo(ptEPrj);
double dDist6 = 0.0;
dDist6 = dDist1 > dDist2 ? dDist2 : dDist1;
ptS = line2.startPoint();
ptE = line2.endPoint();
line1.getClosestPointTo(ptS, ptSPrj);
line1.getClosestPointTo(ptE, ptEPrj);
double dDist3 = ptS.distanceTo(ptSPrj);
double dDist4 = ptE.distanceTo(ptEPrj);
double dDist5 = 0.0;
dDist5 = dDist3 > dDist4 ? dDist4 : dDist3;
return (dDist5 > dDist6 ? dDist6 : dDist5);
}
void SanitarySysForFeedWater::CopyLine( const std::vector<AcDbLine*> &vecSrc, std::vector<AcDbLine*> &vecDes )
{
std::vector<AcDbLine*>::const_iterator it;
for (it = vecSrc.begin(); it != vecSrc.end(); it++)
{
AcDbLine *pLine = new AcDbLine((*it)->startPoint(), (*it)->endPoint());
vecDes.push_back(pLine);
}
}
bool SanitarySysForFeedWater::IsCollidePipe( const AcDbLine *pLine, double dDist )
{
ASSERT(pLine != NULL);
AcGeVector3d vtDir = pLine->startPoint() - pLine->endPoint();
vtDir.z = 0.0;
std::vector<AcDbLine*>::iterator it;
AcGeVector3d vtTemp;
for(it = m_vecCollidePipe.begin(); it != m_vecCollidePipe.end(); it++)
{
vtTemp = (*it)->startPoint() - (*it)->endPoint();
vtTemp.z = 0.0;
if (vtTemp.isParallelTo(vtDir, m_tolVec))
{
double dDist = GetDistLines(pLine, *it);
if (dDist < m_dDistPipe2Pipe - 0.001)
{
// XLine line(asDblArray((*it)->startPoint()), asDblArray((*it)->endPoint()));
// line.Make();
// XCircle cir1(asDblArray((*it)->startPoint()), 50);
// cir1.Make();
// XCircle cir2(asDblArray((*it)->endPoint()), 50);
// cir2.Make();
return true;
}
}
}
return false;
}
void SanitarySysForFeedWater::MovePipe( AcGePoint3d &pt, const AcDbLine &line, const AcGeVector3d &vtDir, double dDist )
{
double dZ = pt.z;
AcGePoint3d ptS = line.startPoint();
AcGePoint3d ptE = line.endPoint();
ptS.z = 0.0;
ptE.z = 0.0;
AcDbLine lineTemp(ptS, ptE);
AcGePoint3d ptPrj = pt;
pt.z = 0.0;
if (lineTemp.getClosestPointTo(pt, ptPrj, Adesk::kTrue) == Acad::eOk)
{
pt = ptPrj + vtDir * dDist;
}
pt.z = dZ;
}
void SanitarySysForFeedWater::SetOtherSanitaryPoint( const std::vector<AcGePoint3d> &vecPt )
{
m_vecOtherSanitaryPoint = vecPt;
}
bool SanitarySysForFeedWater::IsPassOtherSanitarySysPt( const AcGePoint3d &ptS, const AcGePoint3d &ptE )
{
AcGePoint3d pt1 = ptS, pt2 = ptE;
pt1.z = 0.0;
pt2.z = 0.0;
AcDbLine line(pt1, pt2);
std::vector<AcGePoint3d>::iterator it;
AcGePoint3d ptPrj, pt;
for (it = m_vecOtherSanitaryPoint.begin(); it != m_vecOtherSanitaryPoint.end(); it++)
{
pt = *it;
pt.z = 0.0;
if (line.getClosestPointTo(pt, ptPrj) == Acad::eOk)
{
ptPrj.z = 0.0;
if (ptPrj.distanceTo(pt) < 0.001)
{
return true;
}
}
}
return false;
}
extern bool GetSanitaryDriection(Entity ent, double &dSanitaryDriec);
bool SanitarySysForFeedWater::GetSanitaryDir( AcGeVector3d &vtDir, const AcDbObjectId &idSan )
{
bool bRet = false;
double dAngle = 0.0;
ads_name name;
acdbGetAdsName(name, idSan);
Entity ent(name);
if (GetSanitaryDriection(ent, dAngle)) // 定义了洁具方向
{
vtDir = AcGeVector3d::kXAxis;
vtDir.rotateBy(/*Ucs2Wcs*/(dAngle), AcGeVector3d::kZAxis);
bRet = true;
}
else // 没有定义洁具方向
{
// 洁具插入点
AcGePoint3d pt;
AcDbBlockReference *pRef = NULL;
Acad::ErrorStatus st = acdbOpenObject(pRef, idSan, AcDb::kForRead);
if (pRef != NULL)
{
pt = pRef->position();
pRef->close();
}
else
{
return false;
}
XCurveSegment segNaer, segFar;
if (GetNearestWall(pt, WALL_MAX_THICK, segNaer, segFar))
{
AcGePoint3d ptPrj;
GetPtProjectToWall(pt, segNaer, segFar, ptPrj);
vtDir = pt - ptPrj;
vtDir.z = 0.0;
vtDir.normalize();
bRet = true;
}
}
return bRet;
}
bool SanitarySysForFeedWater::GetWallSide( Entity &entWall, std::vector<XCurveSegment> &vecSeg )
{
bool bRet = false;
if (entWall.Is(_T("LINE"))) // 老版墙线
{
OPENOBJ_BEGIN(entWall, AcDb::kForRead, AcDbLine, pLine);
if (pLine != NULL)
{
XLine line(asDblArray(pLine->startPoint()), asDblArray(pLine->endPoint()));
XCurveSegment seg;
seg = line;
vecSeg.push_back(seg);
bRet = true;
}
OPENOBJ_END();
}
else
{
OPENOBJ_BEGIN(entWall, AcDb::kForRead, TDbWall, pWall);
if (pWall != NULL)
{
XCurveSegment segL,segR;
pWall->GetSideCurve(segL,segR);
vecSeg.push_back(segL);
vecSeg.push_back(segR);
bRet = true;
}
OPENOBJ_END()
}
return bRet;
}
bool SanitarySysForFeedWater::IsConflicting( const AcGePoint3d &ptS, const AcGePoint3d &ptE, double dDist )
{
AcDbLine *pLine = new AcDbLine(ptS, ptE);
if ((!PassParallelWall(ptS, ptE)) // 没有穿过平行墙体
&& (PassVertivalPipeNumByLine(ptS,ptE) == 0) // 没有穿过立管
&& !IsPassOtherSanitarySysPt(ptS, ptE) // 没有穿过其他系统洁具点
&& !IsCollidePipe(pLine, dDist)) // 没有与其他系统平行管线发生碰撞
{
delete pLine;
return false;
}
delete pLine;
return true;
}
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);
double SanitarySysForFeedWater::GetSanitaryPtEle( const AcDbObjectId &idSan )
{
double dPtFeedEle = 0.0;
ads_name name;
acdbGetAdsName(name, idSan);
XPoint ptFeed;
CString sTmp1, sTmp2, sDwbName, sFeedElev, sHotElev;
double dRadius = 0.0, dDang = 0.0, dRateQ = 0.0;
Entity ent = name;
// zxl 2012.12.11 modify 获取洁具数据源
int nDataSourceType = GetSanitaryDataSourceType(ent);
if (nDataSourceType == 1 || nDataSourceType == 0)
{
GetSanitaryInfo(ent, ptFeed, sTmp1, sTmp2, dRadius, dDang, dRateQ, dPtFeedEle, 0, sDwbName, sFeedElev, sHotElev);
}
else
{
CSanitaryInfo sanInfo;
XPoint ptFeed, ptHeatFeed, ptDir, ptDrain;
GetLocSanitaryData(ent, sanInfo, ptFeed, ptHeatFeed, ptDrain, ptDir);
dPtFeedEle = ptFeed.z;
}
if (!DocGetMeterUnitDraw())
{
dPtFeedEle *= 1000;
}
return dPtFeedEle;
}
bool SanitarySysForFeedWater::IsSanitaryPtEleSamePipe( const AcDbObjectId &idSan )
{
double dPtFeedEle = 0.0;
dPtFeedEle = GetSanitaryPtEle(idSan);
double dRefVal = DocGetMeterUnitDraw() ? 1 : 1000;
if (fabs(dPtFeedEle + dRefVal) < 0.001)
{
return true;
}
return false;
}
int SanitarySysForFeedWater::GetID()
{
return m_nId++;
}
void SanitarySysForFeedWater::DeleteLine()
{
std::vector<AcDbLine*>::iterator it;
for (it = m_vecCollidePipe.begin(); it != m_vecCollidePipe.end(); it++)
{
delete *it;
}
m_vecCollidePipe.clear();
}
bool SanitarySysForFeedWater::GetWallSide( const AcGePoint3d &pt, const std::vector<std::pair<XCurveSegment, XCurveSegment> > &vecWall, XCurveSegment &segNear, XCurveSegment &segFar )
{
// 点距墙距离
std::multimap<double, std::pair<XCurveSegment, XCurveSegment> > mapWallDist;
std::vector<std::pair<XCurveSegment, XCurveSegment> >::const_iterator it;
AcDbLine line;
AcGePoint3d ptS, ptE, ptPrj, pt1 = pt;
pt1.z = 0.0;
XCurveSegment segR, segL;
for (it = vecWall.begin(); it != vecWall.end(); it++)
{
segL = it->first;
segR = it->second;
segL.SetElevation(0.0);
segR.SetElevation(0.0);
// 求点到墙体的最近距离
line.setStartPoint(segL.StartPoint());
line.setEndPoint(segL.EndPoint());
line.getClosestPointTo(pt1, ptS);
line.setStartPoint(segR.StartPoint());
line.setEndPoint(segR.EndPoint());
line.getClosestPointTo(pt1, ptE);
double dDistL = pt1.distanceTo(ptS);
double dDistR = pt1.distanceTo(ptE);
if (dDistL < dDistR)
{
mapWallDist.insert(std::make_pair(dDistL, std::make_pair(segL, segR)));
}
else
{
mapWallDist.insert(std::make_pair(dDistR, std::make_pair(segR, segL)));
}
}
bool bRet = false;
// 最近的墙
if (!mapWallDist.empty())
{
std::multimap<double, std::pair<XCurveSegment, XCurveSegment> >::iterator itM;
itM = mapWallDist.begin();
segNear = (itM->second).first;
segFar = (itM->second).second;
bRet = true;
}
return bRet;
}
void SanitarySysForFeedWater::GetWallSide( PickSet &ss, std::vector<std::pair<XCurveSegment, XCurveSegment> > &vecWall )
{
XCurveSegment segL, segR;
for (long i = 0; i < ss.Length(); i++)
{
OPENOBJ_BEGIN(ss[i], AcDb::kForRead, TDbWall, pWall);
if (pWall != NULL)
{
if (pWall->GetCurveType() == CURVE_LINE)
{
pWall->GetSideCurve(segL, segR);
vecWall.push_back(std::make_pair(segL, segR));
}
}
OPENOBJ_END()
}
}
void SanitarySysForFeedWater::GetPtProjectToWall( const AcGePoint3d &pt, const XCurveSegment &segNear, const XCurveSegment &segFar, AcGePoint3d &ptPrj )
{
AcGePoint3d ptTemp = pt;
ptTemp.z = 0;
XPoint ptMid;
Midpoint(segNear.StartPoint(), segFar.StartPoint(), ptMid);
ptMid.z = 0.0;
AcGePoint3d ptS = ptMid;
Midpoint(segNear.EndPoint(), segFar.EndPoint(), ptMid);
ptMid.z = 0.0;
AcGePoint3d ptE = ptMid;
AcDbLine line(ptS, ptE);
if (line.getClosestPointTo(ptTemp, ptPrj) == Acad::eOk)
{
ptPrj.z = pt.z;
}
}
bool SanitarySysForFeedWater::PassParallelWall( const AcGePoint3d &ptS, const AcGePoint3d &ptE )
{
// 得到与直线平行的墙体
AcGeVector3d vtDir = ptS - ptE;
vtDir.z = 0.0;
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 (vtWall.isParallelTo(vtDir, m_tolVec))
{
vecWall.push_back(*it);
}
}
}
// 检查直线是否在墙体内
XPoint pt1 = ptS, pt2 = ptE;
pt1.z = 0.0;
pt2.z = 0.0;
AcDbLine line(pt1, pt2);
if (PassParallelWall(vecWall, line))
{
return true;
}
return false;
}
bool SanitarySysForFeedWater::PassParallelWall( const std::vector<std::pair<XCurveSegment, XCurveSegment> > &vecWall, const AcDbLine &line )
{
// 直线与墙线构成的墙体是否有交集
XPoly2D poly;
std::vector<std::pair<XCurveSegment, XCurveSegment> >::const_iterator it;
for (it = vecWall.begin(); it != vecWall.end(); it++)
{
if (GetWallOutLine(poly, it->first, it->second) && ExistIntersection(line, poly))
{
//poly.Make();
return true;
}
}
return false;
}
void SanitarySysForFeedWater::GetWall( PickSet &ss, std::vector<std::pair<XCurveSegment, XCurveSegment> > &vecWall )
{
// 墙体边线
std::vector<XCurveSegment> vecSeg;
for (long i = 0; i < ss.Length(); i++)
{
Entity ent(ss[i]);
GetWallSide(ent, vecSeg);
}
DList<XCurveSegment> lstSeg;
std::vector<XCurveSegment>::iterator it;
for (it = vecSeg.begin(); it != vecSeg.end(); it++)
{
lstSeg.Append(new XCurveSegment(*it));
}
//上华3.0墙识别,将所有线两两匹配。
CWallIdentify wallIdentify;
wallIdentify.DoIdentify(lstSeg);
XCurveSegment seg1, seg2;
for (int nPos = wallIdentify.m_arpData.length() - 1; nPos >= 0; nPos--)
{
if(wallIdentify.m_arpData[nPos]->m_cSide1.isLinear() && wallIdentify.m_arpData[nPos]->m_cSide2.isLinear()) //直墙
{
XLine line1(XPoint(wallIdentify.m_arpData[nPos]->m_cSide1.startPoint()), XPoint(wallIdentify.m_arpData[nPos]->m_cSide1.endPoint()));
XLine line2(XPoint(wallIdentify.m_arpData[nPos]->m_cSide2.startPoint()), XPoint(wallIdentify.m_arpData[nPos]->m_cSide2.endPoint()));
seg1 = line1;
seg2 = line2;
vecWall.push_back(std::make_pair(seg1, seg2));
}
}
}
bool SanitarySysForFeedWater::GetWallOutLine( XPoly2D &poly, const XCurveSegment &seg1, const XCurveSegment &seg2 )
{
if (seg1.GetCurveType() != CURVE_LINE || seg2.GetCurveType() != CURVE_LINE)
{
return false;
}
poly.Reset();
// 获取直线的端点
AcGePoint3d ptS1 = seg1.StartPoint(), ptE1 = seg1.EndPoint();
AcGePoint3d ptS2 = seg2.StartPoint(), ptE2 = seg2.EndPoint();
// 墙体两墙线需平行
AcGeVector3d vt1 = ptS1 - ptE1;
AcGeVector3d vt2 = ptS2 - ptE2;
if (vt1.isParallelTo(vt2, m_tolVec)) // 平行
{
poly.AppendNode(ptS1);
poly.AppendNode(ptE1);
if (vt1.isCodirectionalTo(vt2, m_tolVec)) // 同向
{
poly.AppendNode(ptE2);
poly.AppendNode(ptS2);
}
else // 异向
{
poly.AppendNode(ptS2);
poly.AppendNode(ptE2);
}
poly.SetClosed();
return true;
}
return false;
}
bool SanitarySysForFeedWater::ExistIntersection( const AcDbLine &line, const XPoly2D &poly )
{
XPoint pt = line.startPoint();
if (((pt & poly) == PR_EDGE)
|| ((pt & poly) == PR_INSIDE)) // 点在PLine线内或在线上
{
return true;
}
else // 判断直线与PLine是否相交
{
AcDbCurve *pCurve = poly.AsAcDbCurve();
if (pCurve != NULL)
{
AcGePoint3dArray arrPts;
pCurve->intersectWith(&line, AcDb::kOnBothOperands, arrPts);
delete pCurve;
if (arrPts.length() > 0)
{
return true;
}
}
}
return false;
}
void SanitarySysForFeedWater::InitWallEnt()
{
// 搜集墙体
Entity ent;
PickSet ssWall(SS_FREE), ssWallLine(SS_FREE);
for(long i = 0; i < m_ssDoorWall.Length(); i++)
{
ent = m_ssDoorWall[i];
if (ent.Is(_T("TCH_Wall")))
{
ssWall += ent;
}
else if (ent.Is(_T("LINE")))
{
ssWallLine += ent;
}
}
m_vecWallSide.clear();
// 将墙线分组构成墙体
GetWall(ssWallLine, m_vecWallSide);
// 过滤掉无用墙体
FiltrateWall(m_vecWallSide);
// 将墙体拆分成墙线
GetWallSide(ssWall, m_vecWallSide);
}
void SanitarySysForFeedWater::DrawWall()
{
XPoly2D poly;
XLine line1, line2;
XCurveSegment seg1, seg2;
std::vector<std::pair<XCurveSegment, XCurveSegment> >::iterator it;
for (it = m_vecWallSide.begin(); it < m_vecWallSide.end(); it++)
{
line1 = it->first;
line2 = it->second;
seg1 = line1;
seg2 = line2;
if (GetWallOutLine(poly, seg1, seg2))
{
poly.Make();
}
}
}
bool SanitarySysForFeedWater::IsInBound( const AcGePoint3d &pt, const AcDbLine &line, double dDist )
{
AcGePoint3d ptS = line.startPoint();
AcGePoint3d ptE = line.endPoint();
AcGePoint3d ptTemp = pt;
ptS.z = 0.0;
ptE.z = 0.0;
ptTemp.z = 0.0;
AcDbLine lineTemp(ptS, ptE);
AcGePoint3d ptPrj;
if (lineTemp.getClosestPointTo(ptTemp, ptPrj) == Acad::eOk)
{
double dLen = ptTemp.distanceTo(ptPrj);
if ( dLen < dDist + 0.001)
{
return true;
}
}
return false;
}
bool SanitarySysForFeedWater::GetSanitaryOffsetDir(AcGeVector3d &vtDir, const AcGePoint3d &ptSan, const AcDbObjectId &idSan)
{
XPoint ptFeed, ptHotFeed;
CString csTmp1, csTmp2, sDwbName;
double nTmp(0), nDang(0), nBigQ(0), dEle(0), dAngle(0);
ads_name name;
acdbGetAdsName(name, idSan);
Entity ent = name;
CString sHotElev, sFeedElev;
// zxl 2012.12.11 modify 获取洁具数据源
int nDataSourceType = GetSanitaryDataSourceType(ent);
if (nDataSourceType == 1 || nDataSourceType == 0)
{
if (!GetSanitaryInfo(ent, ptFeed, csTmp1, csTmp2, nTmp, nDang, nBigQ, dEle,0, sDwbName, sFeedElev, sHotElev)
|| !GetSanitaryInfo(ent, ptHotFeed, csTmp1, csTmp2, nTmp, nDang, nBigQ, dEle,1, sDwbName, sFeedElev, sHotElev))
{
return false;
}
}
else
{
CSanitaryInfo sanInfo;
XPoint ptDir, ptDrain;
GetLocSanitaryData(ent, sanInfo, ptFeed, ptHotFeed, ptDrain, ptDir);
}
if (ptFeed.Distance2d(ptSan) < 0.001)
{
vtDir = ptFeed - ptHotFeed;
vtDir.z = 0.0;
vtDir.normalize();
return true;
}
else if (ptHotFeed.Distance2d(ptSan) < 0.001 )
{
vtDir = ptHotFeed - ptFeed;
vtDir.z = 0.0;
vtDir.normalize();
return true;
}
return false;
}
void SanitarySysForFeedWater::FiltrateWall( std::vector<std::pair<XCurveSegment, XCurveSegment> > &vecWall )
{
std::vector<std::pair<XCurveSegment, XCurveSegment> > vecData, vecTemp;
std::vector<std::pair<XCurveSegment, XCurveSegment> >::iterator it, itC;
std::multimap<double,std::pair<XCurveSegment, XCurveSegment> > mapData;
std::multimap<double,std::pair<XCurveSegment, XCurveSegment> >::iterator itD;
while(true)
{
for(it = vecWall.begin(); it != vecWall.end(); it++)
{
itC = it;
++itC;
for(; itC != vecWall.end(); itC++)
{
if (it->first == itC->first || it->first == itC->second
|| it->second == itC->first || it->second == itC->second)
{
double dDist = GetParallelDist(itC->first, itC->second);
mapData.insert(std::make_pair(dDist, *itC));
continue;
}
vecTemp.push_back(*itC);
}
if (!mapData.empty()) // 存在边线重合的墙体,取宽度最小的墙体
{
double dDist = GetParallelDist(it->first, it->second);
mapData.insert(std::make_pair(dDist, *it));
dDist = mapData.begin()->first;
for(itD = mapData.begin(); itD != mapData.end(); itD++)
{
if (fabs(itD->first - dDist) < 0.001)
{
vecData.push_back(itD->second);
}
}
break;
}
else
{
vecData.push_back(*it);
}
}
if (!vecWall.empty())
{
vecWall = vecTemp;
vecTemp.clear();
mapData.clear();
continue;
}
break;
}
vecWall = vecData;
}
double SanitarySysForFeedWater::GetParallelDist( const XCurveSegment &seg1, const XCurveSegment &seg2 )
{
XLine line1 = seg1.GetLine();
XLine line2 = seg2.GetLine();
line1.SetElevation(0.0);
line2.SetElevation(0.0);
XPoint ptS = line1.StartPoint();
XPoint ptPrj;
ptS.Project(&line2, ptPrj);
return ptS.Distance(ptPrj);
}
void SanitarySysForFeedWater::DrawFeedEquip(const AcDbObjectId &idSan, const AcGePoint3d &ptSan)
{
ads_name name;
acdbGetAdsName(name, idSan);
Entity ent(name);
CString sDwbName, sHotElev, sFeedElev, sBlk, sSysBlk;
double dEle = 0.0, dRadius = 0.0, dDang = 0.0, dBigQ = 0.0;
XPoint pt = ptSan;
int nType = -1;
if (m_sysPipe == TPipeSys::kHeatFeedWater
|| m_sysPipe == TPipeSys::kHeatFeedWater2
|| m_sysPipe == TPipeSys::kHeatFeedWater3)
{
nType = 1;
}
else if (m_sysPipe == TPipeSys::kFeedWater
|| m_sysPipe == TPipeSys::kFeedWater2
|| m_sysPipe == TPipeSys::kFeedWater3) // 给水
{
nType = 0;
}
else if (m_sysPipe == TPipeSys::kUsedWater
|| m_sysPipe == TPipeSys::kUsedWater2
|| m_sysPipe == TPipeSys::kUsedWater3) // 中水
{
nType = 0;
}
double dAngle = 0.0;
// zxl 2012.12.11 modify 获取洁具数据源
int nDataSourceType = GetSanitaryDataSourceType(ent);
if (nDataSourceType == 1 || nDataSourceType == 0)
{
GetSanitaryInfo(ent, pt, sBlk, sSysBlk, dRadius, dDang, dBigQ, dEle, nType,
sDwbName, sFeedElev, sHotElev);
ent.GetData(50, &dAngle);
if (GetSanitaryDriection(ent, dAngle))
{
dAngle += PI / 2;
}
pt.z *= 1000;
}
else
{
CSanitaryInfo sanInfo;
XPoint ptFeed, ptHeatFeed, ptDir, ptBlk;
GetLocSanitaryData(ent, sanInfo, ptFeed, ptHeatFeed, pt, ptDir);
sBlk = sanInfo.sFeedSys;
sSysBlk = sanInfo.sSysBlk1;
dDang = sanInfo.dDang;
dBigQ = sanInfo.dRateQ;
if (nType == 1 || nType == 0)
{
pt = ptSan;
pt.z = ptFeed.z * 1000;
}
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);
dAngle += PI / 2;
}
// 加载图块
LoadTkBlock(sBlk);
LoadTkBlock(sSysBlk);
TDbEquipment *pEquip = new TDbEquipment;
pEquip->SetBlock2d(GetBlkIdByName(sBlk));
pEquip->SetDang(dDang);
pEquip->SetSpare(dBigQ);
pEquip->SetLocation(pt);
pEquip->SetHidePipe(FALSE);
pEquip->SetAngle(dAngle);
if(_tcsicmp(sSysBlk, _T("twtsys(00000322)")) == 0){
if(g_bBlk3D){
CString csDwb = g_csDwbPath + _T("TwtSys");
XString xsTmp6;
if(LoadDwbBlock(csDwb, _T("00000364"), xsTmp6) != RTNORM)//3d水龙头
return;
pEquip->SetBlock3d(GetBlockIdFromString(xsTmp6));
}
}
else if(_tcsicmp(sSysBlk, _T("twtsys(00000005)")) == 0){
if(g_bBlk3D){
CString csDwb = g_csDwbPath + _T("TwtSys");
XString xsTmp6;
if(LoadDwbBlock(csDwb, _T("00000416"), xsTmp6) != RTNORM)//3d水龙头
return;
pEquip->SetBlock3d(GetBlockIdFromString(xsTmp6));
}
}
else if(_tcsicmp(sSysBlk, _T("twtsys(00000352)")) == 0 || _tcsicmp(sSysBlk, _T("twtsys(00000014)")) == 0){//小便器自闭式冲洗阀
if(g_bBlk3D){
CString csDwb = g_csDwbPath + _T("TwtSys");
XString xsTmp7;
if(LoadDwbBlock(csDwb, _T("00000368"), xsTmp7) != RTNORM)//3d自闭式冲洗阀
return;
pEquip->SetBlock3d(GetBlockIdFromString(xsTmp7));
}
}
else if(g_bBlk3D && _tcsicmp(sSysBlk, _T("twtsys(00000293)")) == 0){ //大便器自闭式冲洗阀
CString csDwb = g_csDwbPath + _T("TwtSys");
XString xsTmp7;
if(LoadDwbBlock(csDwb, _T("00000369"), xsTmp7) != RTNORM)//3d自闭式冲洗阀
return;
pEquip->SetBlock3d(GetBlockIdFromString(xsTmp7));
}
if (_tcsicmp(sBlk, _T("$TWTSYS$00000519")) == 0)// 给水圆比例 zxl 2012.04.16 add
{
pEquip->SetScale(g_nFeedCircleScale);
}
pEquip->SetSysBlock((const TCHAR*)sSysBlk);
pEquip->setLayer(InitLayer(LAY_EQ_FEED));
pEquip->setColor(AcCmColor()); //随层
AddToCurrentSpace(pEquip, Adesk::kTrue);
}