937 lines
25 KiB
C++
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);
|
|
|
|
} |