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

3731 lines
98 KiB
C++

#include "stdafx.h"
#include "AecDbDuctLine.h"
#include "AecDbHvacDuct.h"
#include "AecDbHvacFitting.h"
#include "AecAngleWatch.h"
#include "AecDbDuctJig.h"
#include "AECStatusRecord.h"
#include "KTSetting.h"
#include "CoreTools.h"
#include "AecDbEwEquipment.h"
#include "DuctlineTools.h"
#include "AcGiExplodeDraw.h"
#include "AecDbX3dPartEntity.h"
#ifndef DXF_PIPE
#define DXF_PIPE _T("AEC_DBDUCT")
#endif
CMapStringToString *g_pMapData = NULL;
extern AcGePoint3d MidPoint(AcGePoint3d& pt1,AcGePoint3d& pt2);
extern CString IDCreate();
typedef struct PointParam
{
AcGePoint3d ptOn;
double dParam;
}POINTPARAM;
static bool ComparePtparam(PointParam ptParam1,PointParam ptParam2)
{
if (ptParam1.dParam - ptParam2.dParam < 1.e-10)
{
return true;
}
return false;
}
void SortPoints(AcGePoint3dArray& points,AcDbCurve* pLine)
{
PointParam ptParam;
std::vector<PointParam> points2;
for (int i = 0;i < points.length();i++)
{
ptParam.ptOn = points.at(i);
pLine->getParamAtPoint(points.at(i),ptParam.dParam);
points2.push_back(ptParam);
}
std::sort(points2.begin(),points2.end(),ComparePtparam);
points.setLogicalLength(0);
std::vector<PointParam>::iterator it;
for (it = points2.begin(); it < points2.end(); it++)
{
points.append((*it).ptOn);
}
}
static AcDbObjectId GetConnectObject(const AecInterface &intf, const CArray<AecInterface> &arr)
{
for (int i = 0; i < arr.GetSize(); ++i)
{
const AecInterface &ff(arr[i]);
if (intf.ptPos == ff.ptPos && intf.idOwner != ff.idOwner) return ff.idOwner;
}
return AcDbObjectId::kNull;
}
double MayAsMUnit(double dVal)
{
struct resbuf rb;
acedGetVar(_T("INSUNITS"), &rb);
if (rb.resval.rint == AcDb::kUnitsMeters)
{
dVal *= 0.001;
}
return dVal;
}
double GetElbowL(AecHvac::DuctParam* pParam)
{
double dL = 0.0;
if (pParam->eType == eCircle)
dL = pParam->dSize[0];
double dRatio = pParam->m_dRatio;
if (dRatio < 1.e-2)
dRatio = 1.0;
double dLx = dRatio * pParam->dSize[0] / 3.0;//默认50
if (dLx > MayAsMUnit(50.0))
dLx = MayAsMUnit(50.0);
dL = dRatio * pParam->dSize[0] + dLx;
dL += pParam->m_dPlusEdge;//卷边
return dL;
}
double GetElbowLx(AecHvac::DuctParam* pParam)
{
double dRatio = pParam->m_dRatio;
if (dRatio < 1.e-2)
dRatio = 1.0;
double dLx = dRatio * pParam->dSize[0] / 3.0;//默认50
if (dLx > MayAsMUnit(50.0))
dLx = MayAsMUnit(50.0);
if (pParam->eType == eCircle)
dLx = MayAsMUnit(50.0);
return dLx;
}
void GetFreeStyleTeeParam(const AecHvac::HvacTeeType& eTeeType, ESection eSectType,
AcGePoint3d& ptStart, AcGeVector3d& vtToEnd, AcGeVector3d& vtZAxis,
double dStartWidth, double dEndWidth, double dBranchWidth, double dFlange, double dRatio,
double dAng, AcGePoint3d& ptEnd, AcGePoint3d& ptBranch, AcGeVector3d& vtStart,
AcGeVector3d& vtEnd, AcGeVector3d& vtBranch)
{
vtStart = -vtToEnd;
vtStart.normalize();
vtEnd = vtToEnd;
vtEnd.normalize();
vtBranch = vtEnd;
vtBranch.rotateBy(PI / 2.0, vtZAxis);
double dDis = 0.0;
switch(eTeeType)
{
case AecHvac::eOrthoBranch:
{
dDis = dBranchWidth * dRatio;
ptEnd = ptStart + vtEnd * dDis * 2;
ptBranch = ptStart + vtEnd * dDis;
double dMaxWidth = dStartWidth > dEndWidth ? dStartWidth : dEndWidth;
if (dDis <= dMaxWidth / 2.0)
{
dDis = dMaxWidth / 2.0 + dBranchWidth / 2.0;
}
else if (dDis <= dMaxWidth / 2.0 + MayAsMUnit(100.0))
{
dDis = dMaxWidth / 2.0 + MayAsMUnit(100.0);
}
ptBranch += vtBranch * dDis;
break;
}
case AecHvac::eInsertBranch:
case AecHvac::eInsertIntubBranch:
if(AecHvac::eRectangular == eSectType)
{
ptEnd = ptStart + vtEnd * (dFlange + MayAsMUnit(100.0) + dBranchWidth + MayAsMUnit(50.0) + dFlange);
ptBranch = ptStart + vtEnd * (dFlange + MayAsMUnit(100.0) + dBranchWidth / 2.0);
ptBranch += vtBranch * (dStartWidth / 2.0 + MayAsMUnit(150.0) + dFlange);
}
else if (AecHvac::eCircular == eSectType)
{
if (fabs(dAng - PI / 4.0) < 1e-2)
{
dDis = dFlange + 0.65 * (dEndWidth + dBranchWidth) + 1.21 * MayAsMUnit(70);//25+25+20
ptEnd = ptStart + vtEnd * dDis;
vtBranch = vtEnd;
vtBranch.rotateBy(PI / 4.0, vtZAxis);
ptBranch = ptStart + vtEnd * dFlange;
ptBranch = ptStart + vtBranch * (dDis -dFlange);
}
else if (fabs(dAng - PI / 6.0) < 1e-2)
{
dDis = dFlange + dEndWidth + dBranchWidth + 1.866 * MayAsMUnit(25 + 25 + 20);
ptEnd = ptStart + vtEnd * dDis;
vtBranch = vtEnd;
vtBranch.rotateBy(PI / 6.0, vtZAxis);
ptBranch = ptStart + vtEnd * dFlange;
ptBranch = ptStart + vtBranch * (dDis - dFlange);
}
}
break;
case AecHvac::eInclineBranch:
if (AecHvac::eRectangular == eSectType)
{
ptEnd = ptStart + vtEnd * (dFlange + MayAsMUnit(100.0) + dBranchWidth + MayAsMUnit(50.0) + dFlange);
ptBranch = ptStart + vtEnd * (dFlange + MayAsMUnit(100.0) + dBranchWidth / 2.0);
ptBranch += vtBranch * (dStartWidth / 2.0 + MayAsMUnit(150.0) + dFlange);
}
else if (AecHvac::eCircular == eSectType)
{
dDis = (dEndWidth + dBranchWidth * cos(dAng)) * 0.5 / sin(dAng) * 1.4;
dDis /= 50;
if (dDis - int(dDis) > 0.0)
{
dDis = int(dDis) + 1;
}
else
{
dDis = int(dDis);
}
dDis *= MayAsMUnit(50.0);
dDis += dFlange * 2.0;
ptEnd = ptStart + vtEnd * dDis;
vtBranch = vtEnd;
vtBranch.rotateBy(dAng, vtZAxis);
ptBranch = ptStart + vtEnd * dFlange;
ptBranch = ptStart + vtBranch * (dDis - dFlange);
}
break;
case AecHvac::eYShapeBranch:
dDis = dBranchWidth * dRatio + dFlange;
ptEnd = ptStart + vtEnd * dDis * 2.0;
ptBranch = ptStart + vtEnd * dDis;
ptBranch += vtBranch * (dDis - dBranchWidth / 2.0 + dStartWidth / 2.0);
break;
case AecHvac::eVShapeBranch:
if (AecHvac::eRectangular == eSectType)
{
// dDis = dStartWidth + dEndWidth +dFlange;
// ptEnd = ptStart + vtEnd * dDis * 2.0;
// ptBranch = ptStart + vtEnd * dDis;
// ptBranch += vtBranch * dDis;
// vtStart = - vtBranch;
// vtEnd = vtStart;
dDis = dStartWidth + dEndWidth +dFlange;
dDis /= sin(dAng / 2.0);
ptEnd = ptStart + vtEnd * dDis * sin(dAng / 2.0) * 2.0;
ptBranch = ptStart + vtEnd * dDis * sin(dAng / 2.0);
ptBranch += vtBranch * dDis * cos(dAng / 2.0);
vtStart = -vtBranch;
vtEnd = vtStart;
}
else if (AecHvac::eCircular == eSectType)
{
vtStart.rotateBy(PI / 3.0, vtZAxis);
vtEnd.rotateBy(-PI / 3.0, vtZAxis);
ptBranch = ptStart - vtStart * (0.37 * dStartWidth + 0.50 * dEndWidth + dFlange + MayAsMUnit(50.0));
ptEnd = ptBranch + vtEnd * (0.62 * dStartWidth + 0.25 * dEndWidth + dFlange + MayAsMUnit(50.0));
ptBranch += dFlange * vtBranch;
}
break;
case AecHvac::eTShapeBranch:
dDis = dBranchWidth * dRatio + dFlange;
ptEnd = ptStart + vtEnd * dDis * 2.0;
ptBranch = ptStart + vtEnd * dDis;
ptBranch += vtBranch * (dDis - dBranchWidth / 2.0 + dStartWidth / 2.0);
break;
case AecHvac::eArcuateBranch:
case AecHvac::eArcuateIntubBranch:
{
dDis = min(dStartWidth, dBranchWidth) * (dRatio - 0.5) + dBranchWidth / 2.0 + dFlange;
ptEnd = ptStart + vtEnd * (dDis + dBranchWidth / 2.0 + MayAsMUnit(50.0) + dFlange);
ptBranch = ptStart + vtEnd * dDis;
dDis += dStartWidth / 2.0 - dBranchWidth / 2.0;
double dDis1 = min(dEndWidth, dBranchWidth) * (dRatio - 0.5) + dEndWidth / 2.0 + dFlange;
double dMaxDis = max(dDis, dDis1);
ptBranch += vtBranch * dMaxDis;
break;
}
default:
break;
}
}
bool GetThreePts(const AcGePoint3d& ptCenter,
const AcGeVector3d& vtRectVShapeNormal,
const AcGeVector3d& vtStart,
const AcGeVector3d& vtEnd,
const AcGeVector3d& vtBranch,
const double dStartWidth,
const double dEndWidth,
const double dBranchWidth,
const double dFlange,
const double dRatio,
const double dAng,
const double dSToBInH,
const double dEToBInH,
const AecHvac::HvacTeeType eTeeType,
const ESection eTeeSectType,
AcGePoint3d& ptStart,
AcGePoint3d& ptEnd,
AcGePoint3d& ptBranch,
const AcGeLine3d* pEndLine = NULL)
{
AcGeVector3d vtNormal = vtStart.crossProduct(vtBranch);
if (!(AecHvac::eVShapeBranch == eTeeType &&
eRect == eTeeSectType))
{
if (vtNormal.length() < 1e-6)
{
return false;
}
}
vtNormal.normalize();
double dFLen = dFlange;
if (eRect == eTeeSectType)
{
switch(eTeeType)
{
case AecHvac::eOrthoBranch:
{
double dDis = dBranchWidth * dRatio;
ptStart = ptCenter + vtStart * dDis;
ptEnd = ptCenter + vtEnd * dDis;
double dMaxWidth = dStartWidth > dEndWidth ? dStartWidth : dEndWidth;
if (dDis <= dMaxWidth / 2.0 + MayAsMUnit(100.0))
{
dDis = dMaxWidth / 2.0 + MayAsMUnit(100.0);
}
ptBranch = ptCenter + vtBranch * dDis;
break;
}
case AecHvac::eInsertBranch:
{
AcGePlane planeStd(ptBranch, vtNormal);
AcGePoint3d ptCenterForBranch = ptCenter.orthoProject(planeStd);
double dDis = dFlange + MayAsMUnit(100.0) + dBranchWidth / 2.0;
ptStart = ptCenter + vtStart * dDis;
dDis = dBranchWidth / 2.0 + MayAsMUnit(50.0) + dFlange;
ptEnd = ptCenter + vtEnd * dDis;
dDis = dStartWidth / 2.0 + MayAsMUnit(150) + dFlange;
if (Adesk::kFalse == ptBranch.isEqualTo(AcGePoint3d::kOrigin))
{
ptBranch = ptCenterForBranch + vtBranch * dDis;
}
else
{
ptBranch = ptCenter + vtBranch * dDis; //ptCenter
}
break;
}
case AecHvac::eInsertIntubBranch:
{
AcGePlane planeStd(ptBranch, vtNormal);
AcGePoint3d ptCenterForBranch = ptCenter.orthoProject(planeStd);
double dDis = MayAsMUnit(100.0) + dBranchWidth / 2.0;
ptStart = ptCenter + vtStart * dDis;
dDis = dBranchWidth / 2.0 + MayAsMUnit(50.0);
ptEnd = ptCenter + vtEnd * dDis;
dDis = dStartWidth / 2.0 + MayAsMUnit(150) + dFlange;
if (Adesk::kFalse == ptBranch.isEqualTo(AcGePoint3d::kOrigin))
{
ptBranch = ptCenterForBranch + vtBranch * dDis;
}
else
{
ptBranch = ptCenter + vtBranch * dDis;
}
break;
}
case AecHvac::eInclineBranch:
{
double dDis = dFlange + MayAsMUnit(100.0) + dBranchWidth / 2.0;
ptStart = ptCenter + vtStart * dDis;
dDis = dBranchWidth / 2.0 + MayAsMUnit(50.0) + dFlange;
ptEnd = ptCenter + vtEnd * dDis;
dDis = dStartWidth / 2.0 + MayAsMUnit(150) + dFlange;
ptBranch = ptCenter + vtBranch * dDis;
break;
}
case AecHvac::eYShapeBranch:
{
double dSBRadius = min(dStartWidth, dBranchWidth) * (dRatio - 0.5);
double dAngS2B = vtStart.angleTo(vtBranch, vtNormal);
double dLengthPartS = dSBRadius / tan(dAngS2B / 2.0);
double dAngB2E = vtBranch.angleTo(vtEnd, vtNormal);
double dLengthFixS = dBranchWidth / sin(dAngB2E) / 2.0 - dStartWidth / tan(dAngB2E) / 2.0;
double dDisS = dLengthPartS + dLengthFixS + dFlange;
ptStart = ptCenter + vtStart * dDisS;
double dEBRadius = min(dEndWidth, dBranchWidth) * (dRatio - 0.5);
double dLengthPartE = dEBRadius / tan(dAngB2E / 2.0);
double dLengthFixE = dBranchWidth / sin(dAngB2E) / 2.0 + dEndWidth / tan(dAngB2E) / 2.0;
double dDisE = dLengthPartE + dLengthFixE + dFlange;
ptEnd = ptCenter + vtEnd * dDisE;
double dDisB = max(dLengthPartS + dStartWidth / sin(dAngB2E) / 2.0, dLengthPartE + dEndWidth / sin(dAngB2E) / 2.0) + dFlange;
ptBranch = ptCenter + vtBranch * dDisB;
break;
}
case AecHvac::eVShapeBranch:
{
double dRadius = (dSToBInH + dEToBInH) / sin(dAng) / 2.0;
double dPart = fabs((dSToBInH + dEToBInH) / 2.0 - dSToBInH);
double dHalf = sqrt(dRadius * dRadius - dPart * dPart);
dPart = (dSToBInH + dEToBInH) / 2.0;
double dLeft = sqrt(dRadius * dRadius - dPart * dPart);
double dDis = 0.0;
if (dAng < PI / 2.0)
{
dDis = dHalf + dLeft;
}
else
{
dDis = dHalf - dLeft;
}
ptStart = ptCenter - vtBranch * dDis;
ptEnd = ptStart;
AcGeVector3d vtDir = vtStart;
vtDir.normalize();
vtDir.rotateBy(PI / 2.0, vtRectVShapeNormal);
ptStart += vtDir * dSToBInH;
vtDir = vtEnd;
vtDir.normalize();
vtDir.rotateBy(-PI / 2.0, vtRectVShapeNormal);
ptEnd += vtDir* dEToBInH;
ptBranch = ptCenter + vtBranch * dFlange;
break;
}
case AecHvac::eTShapeBranch:
{
double dDis = dBranchWidth * dRatio + dFlange;
ptStart = ptCenter + vtStart * dDis;
ptEnd = ptCenter + vtEnd * dDis;
dDis = dDis - dBranchWidth / 2.0 + dStartWidth / 2.0;
ptBranch = ptCenter + vtBranch * dDis;
break;
}
case AecHvac::eArcuateBranch:
case AecHvac::eArcuateIntubBranch:
{
const double dStartDis = min(dStartWidth, dBranchWidth) * (dRatio - 0.5) + dBranchWidth / 2.0 + dFlange;
ptStart = ptCenter + vtStart * dStartDis;
double dAngB2E = vtBranch.angleTo(vtEnd, vtNormal);
const double dBranchDis = (min(dStartWidth, dBranchWidth) * (dRatio - 0.5) + dStartWidth / 2.0) / tan(dAngB2E / 2.0) + dFlange;
const double dBranchDis1 = (min(dEndWidth, dBranchWidth) * (dRatio - 0.5) + dEndWidth / 2.0) / tan(dAngB2E / 2.0) + dFlange;
const double dMaxBranchDis = max(dBranchDis, dBranchDis1);
AcGePlane planeStd(ptBranch, vtNormal);
AcGePoint3d ptCenterForBranch = ptCenter.orthoProject(planeStd);
if (Adesk::kFalse == ptBranch.isEqualTo(AcGePoint3d::kOrigin))
{
ptBranch = ptCenterForBranch + vtBranch * dMaxBranchDis;
}
else
{
ptBranch = ptCenter + vtBranch * dMaxBranchDis;
}
double dEndDis = dBranchWidth / 2.0 / sin(dAngB2E) + dStartWidth / 2.0 / tan(dAngB2E) + MayAsMUnit(50.0) + dFlange;
ptEnd = ptCenter + vtEnd * dEndDis;
// 为获得正确的内弧线修正起始点和支管点
double dAngS2B = vtStart.angleTo(vtBranch, vtNormal);
double dRadius = (dRatio - 0.5) * min(dStartWidth, dBranchWidth);
double dNewStartDis = dBranchWidth / 2.0 / sin(dAngS2B) + dStartWidth / 2.0 / tan(dAngS2B) + dRadius / tan(dAngS2B / 2.0) + dFlange;
if (dNewStartDis > dStartDis)
{
ptStart = ptCenter + vtStart * dNewStartDis;
}
double dNewBranchDis = dStartWidth / 2.0 / sin(dAngS2B) + dBranchWidth / 2.0 / tan(dAngS2B) + dRadius / tan(dAngS2B / 2.0) + dFlange;
if (dNewBranchDis > dBranchDis)
{
if (ptCenterForBranch.z == ptBranch.z)
{
ptBranch = ptCenterForBranch + vtBranch * dNewBranchDis;
}
else
{
ptBranch = ptCenter + vtBranch * dNewBranchDis;
}
}
// 防止支管端口沉入起始管或结束管
AcGeVector3d vtBranchOff = vtBranch;
vtBranchOff.normalize();
vtBranchOff.rotateBy(PI / 2.0, vtNormal);
AcGePoint3d ptBranchOff = ptBranch + vtBranchOff * dBranchWidth / 2.0;
AcGeLine3d lineSE(ptStart, ptEnd);
double dRes = dStartWidth / 2.0 - lineSE.distanceTo(ptBranchOff);
if (dRes > 0.0)
{
double dDisFix = dRes / sin(dAngB2E);
ptBranch += vtBranch * dDisFix;
}
break;
}
default:
break;
}
}
else if (eCircle == eTeeSectType)
{
switch(eTeeType)
{
case AecHvac::eOrthoBranch:
{
double dDis = dBranchWidth * dRatio;
ptStart = ptCenter + vtStart * dDis;
ptEnd = ptCenter + vtEnd * dDis;
double dMaxWidth = dStartWidth > dEndWidth ? dStartWidth : dEndWidth;
if (dDis <= dMaxWidth / 2.0 + MayAsMUnit(100.0))
{
dDis = dMaxWidth / 2.0 + MayAsMUnit(100.0);
}
ptBranch = ptCenter + vtBranch * dDis;
break;
}
case AecHvac::eInsertBranch:
{
double dBranAng = PI - vtBranch.angleTo(vtStart);
if (fabs(dAng - PI / 6.0) < 1e-6)
{
double dDis = dBranchWidth + dEndWidth + MayAsMUnit((25 + 25 + 20)) * 1.886;
AcGePoint3d ptCenterFixed;
if (fabs(vtBranch.angleTo(vtEnd, vtNormal) - PI / 6.0) < 1e-6)
{
ptCenterFixed = ptCenter;
}
else
{
// 三通支管长度+法兰长度+弯头长度
double dBranLen = dDis + dFLen + (dBranchWidth * dRatio / tan((PI / 2 + dAng) / 2) + MayAsMUnit(50));
if(fabs(dBranAng - dAng) > 1e-6)
{
// 计算三通起点(正弦定理)
ptCenterFixed = ptCenter + vtStart * (sin(dBranAng - dAng) * dBranLen / sin(PI - dBranAng));
}
else
{
ptCenterFixed = ptCenter;
}
}
ptStart = ptCenterFixed + vtStart * dFlange;
ptEnd = ptCenterFixed + vtEnd * dDis;
AcGeVector3d vtBranchFixed = vtEnd;
vtBranchFixed.rotateBy(-PI / 6.0, vtNormal);
ptBranch = ptCenterFixed + vtBranchFixed * dDis;
}
else if (fabs(dAng - PI / 4.0) < 1e-6)
{
double dDis = (dEndWidth + dBranchWidth) * 0.65 + MayAsMUnit((25 + 25 + 20)) * 1.21;
AcGePoint3d ptCenterFixed;
if (fabs(vtBranch.angleTo(vtEnd, vtNormal) - PI / 4.0) < 1e-6)
{
ptCenterFixed = ptCenter;
}
else
{
// 三通支管长度+法兰长度+弯头长度
double dBranLen = dDis + dFLen + (dBranchWidth * dRatio / tan((PI / 2 + dAng) / 2) + MayAsMUnit(50));
if(fabs(dBranAng - dAng) > 1e-6)
{
// 计算三通起点(正弦定理)
ptCenterFixed = ptCenter + vtStart * (sin(dBranAng - dAng) * dBranLen / sin(PI - dBranAng));
}
else
{
ptCenterFixed = ptCenter;
}
}
ptStart = ptCenterFixed + vtStart * dFlange;
ptEnd = ptCenterFixed + vtEnd * dDis;
AcGeVector3d vtBranchFixed = vtEnd;
vtBranchFixed.rotateBy(-PI / 4.0, vtNormal);
ptBranch = ptCenterFixed + vtBranchFixed * dDis;
}
break;
}
case AecHvac::eInclineBranch:
{
double dFlangeTemp = /*dFlange*/0.1;
double dDis = (dEndWidth + dBranchWidth * cos(dAng)) * 0.5 / sin(dAng) * 1.4;
dDis /= MayAsMUnit(50);
if (dDis - int(dDis) > 0.0)
{
dDis = int(dDis) + 1;
}
else
{
dDis = int(dDis);
}
dDis *= MayAsMUnit(50.0);
dDis += dFlangeTemp * 2.0;
AcGePoint3d ptCenterFixed;
if (fabs(vtBranch.angleTo(vtEnd, vtNormal) - dAng) < 1e-6)
{
ptStart = ptCenter + vtStart * dFlangeTemp;
ptCenterFixed = ptCenter;
}
else
{
// 支管与主管的角度
double dBranAng = PI - vtBranch.angleTo(vtStart);
// 三通支管长度+法兰长度+弯头长度
double dBranLen = dDis + dFLen + (dBranchWidth * dRatio / tan((PI / 2 + dAng) / 2) + MayAsMUnit(50));
if(fabs(dBranAng - dAng) > 1e-6)
{
// 计算三通起点(正弦定理)
ptStart = ptCenter + vtStart * (sin(dBranAng - dAng) * dBranLen / sin(PI - dBranAng));
ptCenterFixed = ptStart - vtStart * dFLen;
}
else
{
ptStart = ptCenter;
ptCenterFixed = ptCenter;
}
}
ptEnd = ptStart + vtEnd * dDis;
AcGeVector3d vtBranchFixed = vtEnd;
vtBranchFixed.rotateBy(-dAng, vtNormal);
ptBranch = ptCenterFixed + vtBranchFixed * dDis;
break;
}
case AecHvac::eYShapeBranch:
{
double dSBRadius = min(dStartWidth, dBranchWidth) * (dRatio - 0.5);
double dAngS2B = vtStart.angleTo(vtBranch, vtNormal);
double dLengthPartS = dSBRadius / tan(dAngS2B / 2.0);
double dAngB2E = vtBranch.angleTo(vtEnd, vtNormal);
double dLengthFixS = dBranchWidth / sin(dAngB2E) / 2.0 - dStartWidth / tan(dAngB2E) / 2.0;
double dDisS = dLengthPartS + dLengthFixS + dFlange;
ptStart = ptCenter + vtStart * dDisS;
double dEBRadius = min(dEndWidth, dBranchWidth) * (dRatio - 0.5);
double dLengthPartE = dEBRadius / tan(dAngB2E / 2.0);
double dLengthFixE = dBranchWidth / sin(dAngB2E) / 2.0 + dEndWidth / tan(dAngB2E) / 2.0;
double dDisE = dLengthPartE + dLengthFixE + dFlange;
ptEnd = ptCenter + vtEnd * dDisE;
double dDisB = max(dLengthPartS + dStartWidth / sin(dAngB2E) / 2.0, dLengthPartE + dEndWidth / sin(dAngB2E) / 2.0) + dFlange;
ptBranch = ptCenter + vtBranch * dDisB;
// 根据尾管管线修正端口点
if (NULL != pEndLine)
{
// 根据尾管管线修正尾端口点
ptEnd = pEndLine->closestPointTo(ptEnd);
// 重新调整三通端口点
double dHalfStaWidth = dStartWidth * 0.5;
double dHalfEndWidth = dEndWidth * 0.5;
double dHalfBranWidth = dBranchWidth * 0.5;
AcGeVector3d vtBranV = vtBranch;
AcGeVector3d vtStrV = vtStart;
AcGeVector3d vtEndV = vtEnd;
vtBranV.rotateBy(PI * 0.5, vtNormal);
vtStrV.rotateBy(PI * 0.5, vtNormal);
vtEndV.rotateBy(PI * 0.5, vtNormal);
vtStrV.normalize();
vtEndV.normalize();
vtBranV.normalize();
AcGePoint3d pt1, pt2, pt4, pt5, pt6, pt7, pt9, pt10;
pt1 = ptStart + vtStrV * dHalfStaWidth;
pt5 = ptBranch - vtBranV * dHalfBranWidth;
pt6 = ptBranch + vtBranV * dHalfBranWidth;
pt10 = ptEnd - vtEndV * dHalfEndWidth;
double dADis = MayAsMUnit(50.0);
pt2 = pt1 - vtStart * dADis;
pt4 = pt5 - vtBranch * dADis;
pt7 = pt6 - vtBranch * dADis;
pt9 = pt10 - vtEnd * dADis;
AcGeLine3d line1, line2;
line1.set(pt1, pt2);
line2.set(pt4, pt5);
AcGePoint3d ptCor1;
line1.intersectWith(line2, ptCor1);
line1.set(pt6, pt7);
line2.set(pt9, pt10);
AcGePoint3d ptCor2;
line1.intersectWith(line2, ptCor2);
double dminEbr = dHalfBranWidth;
if (dHalfBranWidth > dHalfEndWidth)
{
dminEbr = dHalfEndWidth;
}
double dminSbr = dHalfBranWidth;
if (dHalfBranWidth > dHalfStaWidth)
{
dminSbr = dHalfStaWidth;
}
double dAngleS(0.0),dAngleE(0.0);
dAngleS = vtBranch.angleTo(vtStart);
dAngleS *= 0.5;
dAngleE = vtBranch.angleTo(vtEnd);
dAngleE *= 0.5;
double dLengthS = dRatio * dminSbr / tan(dAngleS) + dFlange;
double dLengthE = dRatio * dminEbr / tan(dAngleE) + dFlange;
AcGePoint3d ptDis = ptBranch + vtBranch * MayAsMUnit(10000);
double dis1 = ptDis.distanceTo(ptCor1 + vtBranch * dLengthS);
double dis2 = ptDis.distanceTo(ptCor2 + vtBranch * dLengthE);
if (dis1 < dis2)
{
ptBranch = ptCor1 + vtBranch * dLengthS;
ptBranch += vtBranV * dHalfBranWidth;
}
else
{
ptBranch = ptCor2 + vtBranch * dLengthE;
ptBranch -= vtBranV * dHalfBranWidth;
}
ptStart = ptCor1 + vtStart * dLengthS;
ptStart -= vtStrV * dHalfStaWidth;
ptEnd = ptCor2 + vtEnd * dLengthE;
ptEnd += vtEndV * dHalfEndWidth;
}
break;
}
case AecHvac::eVShapeBranch:
{
double dLenS = dStartWidth * 0.37 + dEndWidth * 0.50 + dFlange + MayAsMUnit(50.0);
AcGePoint3d ptCenterFixed;
if (fabs(vtBranch.angleTo(vtEnd, vtNormal) - PI * 5.0 / 6.0) < 1e-6
|| fabs(vtStart.angleTo(vtBranch, vtNormal) - PI * 5.0 / 6.0) < 1e-6)
{
ptCenterFixed = ptCenter;
}
else
{
double dMinEdge = PI / 3.0;
double dMaxEdge = 2.0 * PI / 3.0;
double dAngB2E = vtBranch.angleTo(vtEnd, vtNormal);
if (dAngB2E < dMinEdge)
{
dAngB2E = dMinEdge;
}
if (dAngB2E > dMaxEdge)
{
dAngB2E = dMaxEdge;
}
if (dAngB2E > PI / 2.0)
{
dAngB2E = PI - dAngB2E;
}
// 此项为了修复法兰长度造成的尺寸误差
double dFix = 0.5 + 0.5 * (dAngB2E - dMinEdge) / (PI / 6.0);
ptCenterFixed = ptCenter + vtBranch * (dStartWidth * dRatio * 0.5 + dLenS * sqrt(3.0) * 0.5
+ dFLen * 2.0 / sqrt(3.0)) / dFix;
}
AcGeVector3d vtStartFixed = vtBranch;
vtStartFixed.rotateBy(-PI * 5.0 / 6.0, vtNormal);
ptStart = ptCenterFixed + vtStartFixed * dLenS;
double dLenE = dStartWidth * 0.62 + dEndWidth * 0.25 + dFlange + MayAsMUnit(50.0);
AcGeVector3d vtEndFixed = vtBranch;
vtEndFixed.rotateBy(PI * 5.0 / 6.0, vtNormal);
ptEnd = ptCenterFixed + vtEndFixed * dLenE;
ptBranch = ptCenterFixed + vtBranch * dFlange;
break;
}
default:
break;
}
}
return true;
}
AcGePoint2d GetTeeBL(AecHvac::DuctParam* pParamM,AecHvac::DuctParam* pParamB,const AcGeVector3d& vtStart,
const AcGeVector3d& vtBranch,AecHvac::HvacTeeType eTeeType)
{
AcGePoint2d ptBL;
/*double dBranchWidth = pParamB->dSize[0];
double dStartWidth = pParamM->dSize[0];
double dEndWidth = pParamM->dSize[0];
double dRatio = pParamM->m_dRatio;
double dDis = 0.0,dMaxWidth = 0.0;
double dFlange = 50.0;
AcGeVector3d vtEnd = -vtStart;
ESection eSectType = pParamM->eType;
double dSToBInH = 0.0;
double dEToBInH = 0.0;
double dAngle = 0;
AcGeVector3d vtNormal = vtBranch.crossProduct(vtEnd);
AcGePoint3d ptCen(0,0,0);
AcGePoint3d ptSta,ptEnd,ptBra;
GetThreePts(ptCen,vtNormal,vtStart,vtEnd,vtBranch,dStartWidth,dEndWidth,dBranchWidth,
dFlange,dRatio,dAngle,dSToBInH,dEToBInH,eTeeType,eSectType,ptSta,ptEnd,ptBra);
//放大,经验系数 0.8 1.2
ptBL.x = (int)( 0.8 * ptSta.distanceTo(ptEnd) );
ptBL.y = (int)(1.2 * ptBra.distanceTo(ptCen) );
if (ptBL.x < 1.e-2 || ptBL.y < 1.e-2)
{
ptBL.x = GetElbowL(pParamB);
ptBL.y = GetElbowL(pParamB);
}*/
//简易算法
ptBL.x = __max(pParamM->dSize[0],pParamM->dSize[1]) + GetElbowLx(pParamM);
ptBL.y = __max(pParamB->dSize[0],pParamB->dSize[1]) + GetElbowLx(pParamB);
if (vtStart.isParallelTo(AcGeVector3d::kZAxis) ||
vtBranch.isParallelTo(AcGeVector3d::kZAxis))
{
if (pParamM->eType == eRect)
{
ptBL.x = __min(pParamM->dSize[0], pParamM->dSize[1]) + GetElbowLx(pParamM);
ptBL.y = __min(pParamB->dSize[0], pParamB->dSize[1]) + GetElbowLx(pParamB);
}
}
//取平均
double dAv = (ptBL.x + ptBL.y) / 2.0;
ptBL.x = dAv; ptBL.y = dAv;
return ptBL;
}
AecDbDuctLine::AecDbDuctLine(AecDbDuctJig* pJig)
{
m_pAngleWatch = new AecAngleWatch;
m_pPipeJig = pJig;
m_pPipeParam = NULL;
m_pCurPipeLine[0] = NULL;
m_pCurPipeLine[1] = NULL;
m_bStopCommand = FALSE;
m_idStartDragFrom = AcDbObjectId::kNull;
}
AecDbDuctLine::~AecDbDuctLine(void)
{
if ( m_pAngleWatch != NULL)
DELETE_PTR(m_pAngleWatch);
if (m_pPipeParam != NULL)
delete m_pPipeParam;
}
Acad::ErrorStatus AecDbDuctLine::Draw2d(AcGiDraw &mode) const
{
if (m_pCurPipeLine[0] != NULL )
{
((AecDbDuctLine*)(m_pCurPipeLine[0]))->Draw2d(mode);
}
if (m_pAngleWatch != NULL && m_pCurPipeLine[0] != NULL)
{
m_pAngleWatch->Draw2d(mode);
}
return Acad::eOk;
}
void AecDbDuctLine::SetPipeParam(AecHvac::DuctParam* pPipePar)
{
if (m_pPipeParam == NULL)
m_pPipeParam = new AecHvac::DuctParam;
memcpy(m_pPipeParam,pPipePar,sizeof(AecHvac::DuctParam));
}
AecHvac::DuctParam* AecDbDuctLine::GetPipeParam()
{
return m_pPipeParam;
}
AecInterface* AecDbDuctLine::GetLastInterface()
{
int nLen = m_arHistoryIntfs.GetSize();
if (nLen > 0)
{
AecInterface& intf = m_arHistoryIntfs[nLen - 1];
return &intf;
}
return NULL;
}
int AecDbDuctLine::GetLastInfCount() const
{
return m_arHistoryIntfs.GetSize();
}
double AecDbDuctLine::GetEndElevation() const
{
return m_pPipeParam->m_dEl;
}
BOOL AecDbDuctLine::AddPipeNode(AECStatusRecord* pRec ,WPipe::PipeDraw ePipe )
{
switch(ePipe)
{
case WPipe::eToPreView:
{
if (m_pCurPipeLine[0] == NULL)
m_pCurPipeLine[0] = new AecDbHvacDuct;
AecDbHvacDuct* pWpipe = (AecDbHvacDuct*)m_pCurPipeLine[0];
AecDbObjXDataMap* pXDataMap = pWpipe->GetSpecialtyData();
pWpipe->SetDuctParam(m_pPipeParam);
pWpipe->GetSpecialtyData()->SetAt(KEY_2DSTYLE,2);
pWpipe->GetSpecialtyData()->SetAt(KEY_SINGLEW,0);
AcGePoint3d ptGe,ptGe1,ptGe2;
ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint();
ptGe1 = pRec->GetAcquirePoint();
//第一次对齐即可
BOOL bAdjust3d = FALSE;
AcGeVector3d vtAg(0,0,0);
if (m_arHistoryIntfs.GetSize() == 0)
{
bAdjust3d = TRUE;
vtAg = ptGe1 - ptGe;
vtAg.normalize();
switch(m_pPipeParam->m_nAlign)
{
case 0://底部左
{
vtAg.rotateBy(-PI / 2.0,AcGeVector3d::kZAxis);
vtAg *= 0.5 * m_pPipeParam->dSize[0];
break;
}
case 1://底部中
{
vtAg.set(0,0,0);
break;
}
case 2://底部右
{
vtAg.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
vtAg *= 0.5 * m_pPipeParam->dSize[0];
break;
}
default:
break;
}
ptGe += vtAg;
ptGe1 += vtAg;
}
pWpipe->SetStartPoint( ptGe );
pWpipe->SetEndPoint( ptGe1 );
if (bAdjust3d)
{
ptGe1 -= vtAg;
}
//水平风管
AcGeVector3d vtDir = AcGeVector3d::kXAxis;
vtDir = m_pAngleWatch->m_vtDir;
AcGeVector3d vtWDir = vtDir;
vtWDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
AcGeVector3d vtNorm = vtDir.crossProduct(vtWDir);
pWpipe->GetSpecialtyData()->SetAt(KEY_NORMAL,vtNorm);
m_pAngleWatch->m_bFallInSnap = FALSE;
m_pAngleWatch->snapWatch(ptGe,ptGe1,vtDir);
pRec->SetAcquirePoint(ptGe1);
m_pAngleWatch->m_bFallInSnap = TRUE;
break;
}
case WPipe::eToCreate:
{
AcGePoint3d ptGe,ptGe1;
ptGe1 = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint();
ptGe = pRec->GetAcquirePoint();
//判断方向是否一致
int nLen = m_arHistoryIntfs.GetSize();
if (nLen == 0)
{
CreateWPipe(pRec,TRUE); //考虑首尾三通
}
else
{
AecInterface tInf = m_arHistoryIntfs[nLen - 1];
AcGeVector3d vtDir1 = tInf.vtDir;
AcGeVector3d vtDir2 = ptGe - ptGe1;
if (vtDir2.isParallelTo(vtDir1)) //平行,和上次同向,连续画
{
if ( !ExtendLastWPipe(pRec) )
{
CreateWPipe(pRec,FALSE);
}
}
else //添加弯头过渡
{
EFittingType type(eElbow);
CreateElbowAndPipe(pRec, type);
m_pPipeParam->m_dEl = pRec->GetAcquirePoint().z;//4-24
}
}
AcGeVector3d vtDir = AcGeVector3d::kXAxis;
vtDir = m_pAngleWatch->m_vtDir;
ptGe1.z = m_pPipeParam->m_dEl;
ptGe.z = m_pPipeParam->m_dEl;
m_pAngleWatch->m_bFallInSnap = FALSE;
m_pAngleWatch->snapWatch(ptGe1,ptGe,vtDir);
m_pAngleWatch->m_bFallInSnap = TRUE;
break;
}
default:
break;
}
return TRUE;
}
BOOL AecDbDuctLine::AddReducer(AECStatusRecord* pCurStaRec,AecHvac::DuctParam* pParam)
{
AcGeVector3d vtDir = AcGeVector3d::kXAxis;
AecInterface* pIntf = GetLastInterface();
if (pIntf != NULL)
{
vtDir = pIntf->vtDir;
}
vtDir.normalize();
AcGePoint3d ptSta = pIntf->ptPos;
AcGePoint3d ptEnd = ptSta + vtDir * pParam->m_dL;
AcGeVector3d vtNorm = pParam->m_vtNrom;
AecDbHvacFitting* pFit = new AecDbHvacFitting;
AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData();
pXDataMap->SetAt(KEY_FITSRV, KEY_FITHVAC);
pXDataMap->SetAt(KEY_RUNTIME, (int)eReduce);
pXDataMap->SetAt(HRED_StartSectType, pParam->eType);
pXDataMap->SetAt(HRED_EndSectType, pParam->eType);
//pXDataMap->SetAt(KEY_SECSHAPE, pParam->eType);
pXDataMap->SetAt(HRED_StartWidth, pParam->dSize[0]);
pXDataMap->SetAt(HRED_StartThick, pParam->dSize[1]);
pXDataMap->SetAt(HRED_EndWidth, pParam->dSize[3]);
pXDataMap->SetAt(HRED_EndThick, pParam->dSize[4]);
pXDataMap->SetAt(HVAC_IsSingleLine, 0);
pXDataMap->SetAt(HVAC_HasBaseLine, 1);
pXDataMap->SetAt(HRED_StartPoint, ptSta);
pXDataMap->SetAt(HRED_EndPoint, ptEnd);
pXDataMap->SetAt(HRED_StartDir,-vtDir);
pXDataMap->SetAt(HVAC_Normal, vtNorm);
pXDataMap->SetAt(HVAC_PlusEdge, pParam->m_dPlusEdge);//咬口法兰翻边余量
pXDataMap->SetAt(HRED_ComputeType, AecHvac::eLength);
int nDir = 1,nZDir = 1;
AcGeVector3d vtOff(0,0,0);//可以偏心
if (pParam->m_nEcCen == 0)
{
//标准居中
}
else if (pParam->m_nEcCen == 1)//偏心上对齐
{
if (vtDir.dotProduct(AcGeVector3d::kXAxis) > 1.e-10)
{
nDir = -1;
}
else if (vtDir.dotProduct(-AcGeVector3d::kXAxis) > 1.e-10)
{
nDir = 1;
}
vtOff = vtDir;
vtOff.rotateBy(nDir * PI / 2.0,AcGeVector3d::kZAxis);
vtOff.normalize();
vtOff *= 0.5 * (pParam->dSize[3] - pParam->dSize[0]);
ptEnd += vtOff;
pXDataMap->SetAt(HRED_EndPoint, ptEnd);
}
else if (pParam->m_nEcCen == 2)//偏心下对齐
{
if (vtDir.dotProduct(AcGeVector3d::kXAxis) > 1.e-10)
{
nDir = 1;
}
else if (vtDir.dotProduct(-AcGeVector3d::kXAxis) > 1.e-10)
{
nDir = -1;
}
vtOff = vtDir;
vtOff.rotateBy(nDir * PI / 2.0,AcGeVector3d::kZAxis);
vtOff.normalize();
vtOff *= 0.5 * (pParam->dSize[3] - pParam->dSize[0]);
ptEnd += vtOff;
pXDataMap->SetAt(HRED_EndPoint, ptEnd);
}
vtOff.set(0,0,0);
if (pParam->m_nZEcCen == 0)
{
}
else if (pParam->m_nZEcCen == 1)
{
vtOff.set(0,0,-0.5 * (pParam->dSize[4] - pParam->dSize[1]));
}
else if (pParam->m_nZEcCen == 2)
{
vtOff.set(0,0,0.5 * (pParam->dSize[4] - pParam->dSize[1]));
}
ptEnd += vtOff;
pXDataMap->SetAt(HRED_EndPoint, ptEnd);
pXDataMap->SetAt(HRED_Offset, vtOff);
pXDataMap->SetAt(KEY_ECCEN,pParam->m_nEcCen);
pXDataMap->SetAt(KEY_ECZCEN,pParam->m_nZEcCen);
pXDataMap->SetAt(HRED_Angle, PI / 3.0);//60
pXDataMap->SetAt(HRED_Length, pParam->m_dL);
//设置图层
//AcDbObjectId idLay = KTSetting::InitLayer(LAY_HVAC_OUT);
//pFit->setLayer(idLay);
AcDbObjectId idCenLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_CEN,pParam->szSys,4,_T("center2"),NULL);
AcDbObjectId idOutLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_OUT,pParam->szSys,7,_T("Continuous"),NULL);
AcDbObjectId idSingle = DuctlineTools::AecInitLayerEx(LAY_HVAC_SIG,pParam->szSys,7,_T("Continuous"),NULL);
pFit->setLayer(idOutLay);
pFit->SetDoubleLayer(idOutLay);
pFit->SetCenterLayer(idCenLay);
pFit->SetCenterLayer(idCenLay);
AcDbObjectId id = CoreTools::AddToModelSpace(pFit);
AddUserData(id,pXDataMap,5);
AecInterface intf;
intf.ptPos = ptEnd;
intf.vtDir = vtDir;
intf.idOwner = id;
PushInterface(intf);
//覆盖当前的param
PushPipeParam();
memcpy(m_pPipeParam,pParam,sizeof(AecHvac::DuctParam));//回退
m_pPipeParam->dSize[0] = pParam->dSize[3];
//创建余下管子,并插入虚拟状态记录
AECStatusRecord* pRecMid = new AECStatusRecord;
pRecMid->CopyFrom(pCurStaRec);
pRecMid->SetAcquirePoint(ptEnd);
m_pPipeJig->PushBackStatusRec(pRecMid);
pCurStaRec->SetAcquirePoint(ptEnd);
return TRUE;
}
AcDbObjectId AecDbDuctLine::CreateElbow( AcGeVector3d vtMaj
,AcGePoint3d ptMid
,AcGeVector3d vtMin
,AecHvac::DuctParam* pparamM
,AecHvac::DuctParam* pparamB
,BOOL bInsertBeforLast/* = FALSE*/)
{
AecDbHvacFitting* pFit = ImpNewElbow(vtMaj,ptMid,vtMin,pparamM,pparamB);
AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData();
//图层
//AcDbObjectId idLay = KTSetting::InitLayer(LAY_HVAC_OUT);
//pFit->setLayer(idLay);
AecInterface intf0,intf1;
pFit->GetInterface(0,intf0);
pFit->GetInterface(1,intf1);
m_intf0 = intf0;
m_intf1 = intf1;
//添加本次到数据库
AcDbObjectId id = CoreTools::AddToModelSpace(pFit);
m_intf0.idOwner = id;
m_intf1.idOwner = id;
AddUserData(id,pXDataMap,1);
//记录接口到历史记录
intf1.idOwner = id;
if (m_pPipeJig != NULL) intf1.nType = m_pPipeJig->GetUndoGroupID();
if (bInsertBeforLast)
{
if (m_arHistoryIntfs.GetSize() > 0)
{
AecInterface inf = m_arHistoryIntfs[m_arHistoryIntfs.GetSize() - 1];
m_arHistoryIntfs.RemoveAt(m_arHistoryIntfs.GetSize() - 1);
PushInterface(intf0);
PushInterface(inf);
}
else
{
PushInterface(intf0);
}
}
else
{
PushInterface(intf0);
}
AddUserData(id,pXDataMap,1);
return id;
}
AecDbHvacFitting* AecDbDuctLine::ImpNewElbow( AcGeVector3d& vtMaj
,AcGePoint3d& ptMid
,AcGeVector3d& vtMin
,AecHvac::DuctParam* pparamM
,AecHvac::DuctParam* pparamB)
{
AecDbHvacFitting* pFit = new AecDbHvacFitting;
AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData();
//设置图层
//AcDbObjectId idLay = KTSetting::InitLayer(LAY_HVAC_OUT);
AcDbObjectId idCenLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_CEN,m_pPipeParam->szSys,4,_T("center2"),NULL);
AcDbObjectId idOutLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_OUT,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
AcDbObjectId idSingle = DuctlineTools::AecInitLayerEx(LAY_HVAC_SIG,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
pFit->setLayer(idOutLay);
pFit->SetDoubleLayer(idOutLay);
pFit->SetCenterLayer(idCenLay);
pFit->SetCenterLayer(idCenLay);
//按主管最大计算
AecHvac::DuctParam* pParamMax = (pparamM->dSize[0] > pparamB->dSize[0]) ? pparamM : pparamB;
double dRatio = pParamMax->m_dRatio;
double dLx = GetElbowLx(pParamMax);
double dL = GetElbowL(pParamMax);
AcGePoint3d ptStart,ptEnd;
vtMaj.normalize();
vtMin.normalize();
ptStart = ptMid + vtMaj * dL;
ptEnd = ptMid + vtMin * dL;
pXDataMap->SetAt(KEY_FITSRV,KEY_FITHVAC);
pXDataMap->SetAt(KEY_RUNTIME, (int)eElbow);
pXDataMap->SetAt(HVAC_SectType, pparamM->eType);
pXDataMap->SetAt(HELB_Type, (pparamM->eType == eRect) ? AecHvac::eIncline : AecHvac::eSegmental);
pXDataMap->SetAt(HVAC_PlusEdge, pparamM->m_dPlusEdge);//咬口法兰翻边余量
pXDataMap->SetAt(HELB_Thick, pparamM->dSize[1]);
pXDataMap->SetAt(HELB_EndThick, pparamB->dSize[1]);
pXDataMap->SetAt(HELB_StartWidth, pparamM->dSize[0]);
pXDataMap->SetAt(HELB_EndWidth, pparamB->dSize[0]);
pXDataMap->SetAt(HELB_Diameter, pparamM->dSize[0]);
pXDataMap->SetAt(HELB_EndDiameter, pparamB->dSize[0]);
pXDataMap->SetAt(HELB_StartPoint, ptStart);
pXDataMap->SetAt(HELB_CornerPoint, ptMid);
pXDataMap->SetAt(HELB_AssisCornerPoint, ptMid);
pXDataMap->SetAt(HELB_EndPoint, ptEnd);
pXDataMap->SetAt(HVAC_IsSingleLine, 0);
pXDataMap->SetAt(HVAC_HasBaseLine, 1);
pXDataMap->SetAt(HELB_Segments, 3);
pXDataMap->SetAt(HELB_RadRatio, pparamM->m_dRatio);
pXDataMap->SetAt(HELB_VertDrawStyle, 0);
pFit->SetDuctParam(*pparamM);
return pFit;
}
BOOL AecDbDuctLine::ChangeEl(AECStatusRecord* pRec,double dNewEl,BOOL bCheckRec,double dRedElPos,AecHvac::DuctParam* pParamred)
{
AcGeVector3d vtMaj,vtMin;
if (GetLastInterface() != NULL)
{
vtMaj = GetLastInterface()->vtDir;
vtMaj.normalize();
vtMin = AcGeVector3d::kZAxis;
if (dNewEl - m_pPipeParam->m_dEl < 1.e-3)
{
vtMin = -AcGeVector3d::kZAxis;
}
AcGePoint3d ptMid,ptSta,ptEnd,ptGeT,ptLast;
double dRatio = m_pPipeParam->m_dRatio;
AecHvac::DuctParam paramTmp;
memcpy(&paramTmp,m_pPipeParam,sizeof(AecHvac::DuctParam));
double dTmp = paramTmp.dSize[0];
if (paramTmp.eType == eRect)
{
paramTmp.dSize[0] = paramTmp.dSize[1];
paramTmp.dSize[1] = dTmp;
}
double dLx = GetElbowLx(&paramTmp);
double dL = GetElbowL(&paramTmp);
//如果上段不是管子
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,GetLastInterface()->idOwner,AcDb::kForWrite))
{
AecDbHvacDuct* pPipe = AecDbHvacDuct::cast(pEnt);
if (pPipe == NULL)//不是管子
{
ptMid = GetLastInterface()->ptPos;
ptMid += vtMaj * dL;
ptLast = ptMid;
}
else//改短上次管子
{
ptLast = GetLastInterface()->ptPos;
if (ptLast.distanceTo(pPipe->EndPoint()) < 1.e-3)
{
ptEnd = pPipe->EndPoint();
ptMid = ptEnd;
ptEnd -= vtMaj * dL;
ptGeT = pPipe->EndPoint();
pPipe->SetEndPoint(ptEnd);
ptLast = ptEnd;
}
else
{
vtMaj = pPipe->StartPoint() - pPipe->EndPoint();
vtMaj.normalize();
ptSta = pPipe->StartPoint();
ptMid = ptSta;
ptSta -= vtMaj * dL;
ptGeT = pPipe->StartPoint();
pPipe->SetStartPoint(ptSta);
ptLast = ptSta;
}
}
pEnt->close();
}
//压入当前param
PushPipeParam();
//1. 如果方向不同创建弯头
if (!vtMaj.isParallelTo(vtMin))
{
//底部弯头
AecHvac::DuctParam param;
memcpy(&param,m_pPipeParam,sizeof(AecHvac::DuctParam));
double dTmp = param.dSize[0];
if (param.eType == eRect)
{
param.dSize[0] = param.dSize[1];
param.dSize[1] = dTmp;
}
vtMaj.negate();
CreateElbow(vtMaj,ptMid,vtMin,&param,&param);
if (m_intf0.vtDir.isParallelTo(vtMin) )
{
ptSta = m_intf0.ptPos;
}
else
{
ptSta = m_intf1.ptPos;
}
//顶部弯头
ptMid.z = dNewEl;
vtMin = vtMaj;
vtMin.negate();
vtMaj = -AcGeVector3d::kZAxis;
if (dNewEl < m_pPipeParam->m_dEl)
vtMaj.negate();
//顶部不需要创建 2023-11-22
//CreateElbow(vtMaj,ptMid,vtMin,&param,&param);
if (m_intf0.vtDir.isParallelTo(vtMaj))
{
ptEnd = m_intf0.ptPos;
ptLast = m_intf1.ptPos;
}
else
{
ptEnd = m_intf1.ptPos;
ptLast = m_intf0.ptPos;
}
AcGeVector3d vtDirXY = vtMaj.isParallelTo(AcGeVector3d::kZAxis) ? vtMin : vtMaj;
double dAng = AcGeVector3d::kXAxis.angleTo(vtDirXY,AcGeVector3d::kZAxis);
if (vtMaj.isParallelTo(AcGeVector3d::kZAxis) ||
vtMin.isParallelTo(AcGeVector3d::kZAxis))
dAng += PI / 2.0;
//2. 创建立管
AecHvac::DuctParam paramT;
memcpy(&paramT,m_pPipeParam,sizeof(AecHvac::DuctParam));
paramT.m_vtNrom = vtMin;
/*dTmp = paramT.dSize[0];
if (paramT.eType == eRect)
{
paramT.dSize[0] = paramT.dSize[1];
paramT.dSize[1] = dTmp;
}*/
ptEnd.z = dNewEl;
CreatePipe(ptSta,ptEnd,&paramT,dAng);
m_pPipeParam->m_dEl = dNewEl;
//重新调整历史记录
// //CreatePipe 已经加入最后管嘴 2023-11-22 去掉
//AecInterface inf = m_intf0;
//inf.vtDir = vtMin;
//inf.ptPos = ptLast;
//PushInterface(inf);
//pRec->SetAcquirePoint(ptLast);
//调整本次状态点
pRec->SetAcquirePoint(ptEnd);
}
}
return TRUE;
}
BOOL AecDbDuctLine::ChangeEl2(AECStatusRecord* pRec,AECStatusRecord* pRecLast,double dNewEl,
BOOL bCheckRec,double dRedElPos,AecHvac::DuctParam* pParamred)
{
ads_point pt[5];
AcGePoint3d ptGe = pRecLast->GetAcquirePoint();
double dSize = PixelToWcs(5);//5
AcGePoint3d ptGeX[5];
ptGeX[0] = ptGe;
ptGeX[0] -= dSize * AcGeVector3d::kYAxis;
ptGeX[0] -= dSize * AcGeVector3d::kXAxis;
ptGeX[1] = ptGeX[0] + 2 * dSize * AcGeVector3d::kYAxis;
ptGeX[2] = ptGeX[1] + 2 * dSize * AcGeVector3d::kXAxis;
ptGeX[3] = ptGeX[0] + 2 * dSize * AcGeVector3d::kXAxis;
ptGeX[4] = ptGeX[0];
for (int i = 0;i < 5;i++)
{
acdbWcs2Ucs(asDblArray(ptGeX[i]),pt[i],false);
}
TCHAR szBuf[64];
memset(szBuf,0,sizeof(szBuf));
_tcscpy(szBuf, DXF_PIPE);
struct resbuf rb;
rb.restype = 0;
rb.resval.rstring = szBuf;
rb.rbnext = NULL;
struct resbuf* pointlist = NULL;
pointlist = acutBuildList(RTPOINT, pt[0], RTPOINT, pt[1],
RTPOINT, pt[2], RTPOINT, pt[3], 0);
ads_name ss,ent;
acedSSGet(_T("CP"),pointlist,NULL,&rb,ss);
acutRelRb(pointlist);
Adesk::Int32 lLen = 0;
acedSSLength(ss,&lLen);
AecHvac::DuctParam wparamMain;
memcpy(&wparamMain,m_pPipeParam,sizeof(AecHvac::DuctParam));
AcGeVector3d vtSta;
AcDbObjectId id;
AcGePoint3d ptOn;
if (lLen > 0)
{
acedSSName(ss,0,ent);
acdbGetObjectId(id,ent);
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead) )
{
AecDbHvacDuct* pWPipe = AecDbHvacDuct::cast(pEnt);
if (pWPipe != NULL)
{
pWPipe->GetDuctParam(wparamMain);
AcGePoint3d ptOn1 = pRec->GetAcquirePoint();
AcDbLine ln(pWPipe->StartPoint(),pWPipe->EndPoint());
ln.getClosestPointTo(ptOn1,ptOn);
pRec->SetAcquirePoint(ptOn);
vtSta = pWPipe->StartPoint() - pWPipe->EndPoint();
}
pEnt->close();
}
}
acedSSFree(ss);
bool bCreateTee = false;
if ( ( wparamMain.dSize[0] - m_pPipeParam->dSize[0] ) > -1.e-6) //可能的创建三通,否则只创建立管
{
bCreateTee = true;
}
//创建立管
AcGePoint3d ptSta,ptEnd;
ptSta = pRec->GetAcquirePoint();
if (bCreateTee)
{
AcGeVector3d vtMin = AcGeVector3d::kZAxis;
if (dNewEl - ptSta.z < 1.e-3)
{
vtMin = -AcGeVector3d::kZAxis;
}
AcGePoint3d ptMid = pRec->GetAcquirePoint();
double dL = 0.0,dB = 0.0;
double dLx = GetElbowLx(&wparamMain);
AcGePoint2d ptBL = GetTeeBL(&wparamMain,m_pPipeParam,vtSta,vtMin,AecHvac::eArcuateBranch);
dL = ptBL.x;//GetElbowL(&wparamMain);
dB = ptBL.y;//GetElbowL(m_pPipeParam);
//创建三通
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite) )
{
AecDbHvacDuct* pWPipe = AecDbHvacDuct::cast(pEnt);
if (pWPipe != NULL)
{
//对方断为两个管子
SplitWPipe(ptMid,dL,pWPipe);
AddTee(pWPipe,dL,ptMid,dB,vtMin);
ptSta += vtMin * dB;
}
pEnt->close();
}
}
//3.创建立管
ptEnd = ptSta;
{
ptEnd.z = dNewEl;
CreatePipe(ptSta,ptEnd,m_pPipeParam);
m_pPipeParam->m_dEl = dNewEl;
//调整本次状态点
pRec->SetAcquirePoint(ptEnd);
}
return TRUE;
}
BOOL AecDbDuctLine::ChangeEl3(AECStatusRecord* pRec,AcGePoint3d& ptThis)
{
double dNewEl = ptThis.z;
AcGeVector3d vtMaj,vtMin;
if (GetLastInterface() != NULL)
{
vtMaj = GetLastInterface()->vtDir;
vtMaj.normalize();
vtMin = ptThis - GetLastInterface()->ptPos;
vtMaj.normalize();
vtMin.normalize();
AecHvac::DuctParam paramTmp;
memcpy(&paramTmp,m_pPipeParam,sizeof(AecHvac::DuctParam));
double dTmp = paramTmp.dSize[0];
if (paramTmp.eType == eRect)
{
paramTmp.dSize[0] = paramTmp.dSize[1];
paramTmp.dSize[1] = dTmp;
}
double dLx = GetElbowLx(&paramTmp);
double dX = GetElbowL(&paramTmp);
AcGePoint3d ptMid,ptSta,ptEnd,ptGeT,ptLast;
//如果上段不是管子
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,GetLastInterface()->idOwner,AcDb::kForWrite))
{
AecDbHvacDuct* pPipe = AecDbHvacDuct::cast(pEnt);
if (pPipe == NULL)//不是管子
{
ptMid = GetLastInterface()->ptPos;
ptMid += vtMaj * dX;
}
else//改短上次管子
{
ptLast = GetLastInterface()->ptPos;
if (ptLast.distanceTo(pPipe->EndPoint()) < 1.e-3)
{
ptEnd = pPipe->EndPoint();
ptMid = ptEnd;
ptEnd -= vtMaj * dX;
ptGeT = pPipe->EndPoint();
pPipe->SetEndPoint(ptEnd);
}
else
{
vtMaj = pPipe->StartPoint() - pPipe->EndPoint();
vtMaj.normalize();
ptSta = pPipe->StartPoint();
ptMid = ptSta;
ptSta -= vtMaj * dX;
ptGeT = pPipe->StartPoint();
pPipe->SetStartPoint(ptSta);
}
}
pEnt->close();
}
//压入当前param
PushPipeParam();
//1. 如果方向不同创建弯头->乙字弯结构
if (!vtMaj.isParallelTo(vtMin))
{
vtMaj.negate();
AecHvac::DuctParam param;
memcpy(&param,m_pPipeParam,sizeof(AecHvac::DuctParam));
double dTmp = param.dSize[0];
if (param.eType == eRect)
{
param.dSize[0] = param.dSize[1];
param.dSize[1] = dTmp;
}
CreateElbow(vtMaj,ptMid,vtMin,&param,&param);
AcGeVector3d vtPipe = vtMaj;
if (m_intf0.vtDir.isParallelTo(vtMin) )
{
ptSta = m_intf0.ptPos;
vtPipe = m_intf0.vtDir;
}
else
{
ptSta = m_intf1.ptPos;
vtPipe = m_intf1.vtDir;
}
//2. 创建斜管
vtPipe.normalize();
ptEnd = ptThis;
ptEnd -= vtPipe * dX;
CreatePipe(ptSta,ptEnd,m_pPipeParam);
//在创建弯头
vtMin = vtMaj;
vtMin.negate();
ptMid = ptThis;
vtMaj = vtPipe;
vtMaj.negate();
CreateElbow(vtMaj,ptMid,vtMin,&param,&param);
if (m_intf0.vtDir.isParallelTo(vtMin) )
{
ptEnd = m_intf0.ptPos;
PushInterface(m_intf0);
}
else
{
ptEnd = m_intf1.ptPos;
PushInterface(m_intf1);
}
}
m_pPipeParam->m_dEl = dNewEl;
//调整本次状态点
pRec->SetAcquirePoint(ptEnd);
return TRUE;
}
return FALSE;
}
void AecDbDuctLine::SetAngleWath(AcGePoint3d& ptCen,const AcGePoint3d& ptGeTo,const AcGeVector3d& vtDir/* = AcGeVector3d::kXAxis*/)
{
if (m_pAngleWatch != NULL)
{
m_pAngleWatch->SetAngleWath(ptCen,ptGeTo,vtDir);
}
}
void AecDbDuctLine::AngWatchTo(const AcGePoint3d& ptGeTo)
{
if (m_pAngleWatch != NULL)
{
m_pAngleWatch->m_ptGeTo = ptGeTo;
}
}
void AecDbDuctLine::SwitchAutoSnapOrF8()
{
if (m_pAngleWatch != NULL)
{
m_pAngleWatch->SwitchAutoSnapOrF8();
}
}
void AecDbDuctLine::MoveAngWatchPosition()
{
//导航表盘
if (m_pPipeJig->GetTailStatusRec() != NULL &&
m_pPipeJig->GetTailStatusRec()->GetStatusType() >= AECStatusRecord::kAngle &&
m_pPipeJig->GetTailStatusRec()->GetStatusType() <= AECStatusRecord::kPoint)
{
AcGePoint3d ptGe,ptGe1;
ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint();
ptGe1 = m_pPipeJig->m_pCurStaRec->GetAcquirePoint();
AcGeVector3d vtDir;
vtDir = m_pAngleWatch->m_vtDir;
AecInterface* pLast = GetLastInterface();
if (pLast != NULL)
{
vtDir = pLast->vtDir;
}
m_pAngleWatch->SetAngleWath(ptGe,ptGe1,vtDir);
}
}
//画管线停止
BOOL AecDbDuctLine::PipeFinished()
{
return m_bStopCommand;
}
void AecDbDuctLine::PopUpInterface(int nGroupID)
{
while(m_arHistoryIntfs.GetSize() > 0)
{
if (m_arHistoryIntfs[m_arHistoryIntfs.GetSize() - 1].nType == nGroupID)
{
m_arHistoryIntfs.RemoveAt(m_arHistoryIntfs.GetSize() - 1);
}
else
{
break;
}
}
//回退上次参数
while (m_lstLastPipeParam.GetCount() > 0)
{
//回上次管道参数
AecHvac::DuctParam* pLast = (AecHvac::DuctParam*)m_lstLastPipeParam.GetTail();
if (pLast->m_nGroupID == nGroupID)
{
m_lstLastPipeParam.RemoveTail();
DELETE_PTR(pLast);
}
else
{
memcpy(m_pPipeParam,pLast,sizeof(AecHvac::DuctParam));
break;
}
}
}
void AecDbDuctLine::PushPipeParam()
{
AecHvac::DuctParam* pParam = new AecHvac::DuctParam;
memcpy(pParam,m_pPipeParam,sizeof(AecHvac::DuctParam));
pParam->m_nGroupID = m_pPipeJig->GetUndoGroupID();
m_lstLastPipeParam.AddTail(pParam);
}
void AecDbDuctLine::PushInterface(AecInterface& intf,BOOL bStartDragFromIt/* = FALSE*/)
{
m_arHistoryIntfs.Add(intf);
if (bStartDragFromIt)//拖出的源对象
{
m_idStartDragFrom = intf.idOwner;
}
}
void AecDbDuctLine::SetFittingLayer(AecDbHvacFitting *pFitting, LPCTSTR pszSys)
{
AcDbObjectId idCenLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_CEN, pszSys, 4, _T("center2"), NULL);
AcDbObjectId idOutLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_OUT, pszSys, 7, _T("Continuous"), NULL);
AcDbObjectId idSingle = DuctlineTools::AecInitLayerEx(LAY_HVAC_SIG, pszSys, 7, _T("Continuous"), NULL);
AecDbObjXDataMap *pXDataMap = pFitting->GetSpecialtyData();
pXDataMap->SetAt(PIPE_CENTLAY, idCenLay);
pXDataMap->SetAt(PIPE_OUTDLAY, idOutLay);
pXDataMap->SetAt(PIPE_SINGLAY, idSingle);
pFitting->SetDoubleLayer(idOutLay);
pFitting->SetSingleLayer(idSingle);
pFitting->SetCenterLayer(idCenLay);
//设置图层
pFitting->setLayer(idOutLay);
}
void AecDbDuctLine::SetPipeLayer(AecDbHvacDuct *pPipe, LPCTSTR pszSys)
{
AcDbObjectId idCenLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_CEN, pszSys, 4, _T("center2"), NULL);
AcDbObjectId idOutLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_OUT, pszSys, 7, _T("Continuous"), NULL);
AcDbObjectId idSingle = DuctlineTools::AecInitLayerEx(LAY_HVAC_SIG, pszSys, 7, _T("Continuous"), NULL);
AecDbObjXDataMap *pXDataMap = pPipe->GetSpecialtyData();
pXDataMap->SetAt(PIPE_CENTLAY, idCenLay);
pXDataMap->SetAt(PIPE_OUTDLAY, idOutLay);
pXDataMap->SetAt(PIPE_SINGLAY, idSingle);
pPipe->SetDoubleLayer(idOutLay);
pPipe->SetSingleLayer(idSingle);
pPipe->SetCenterLayer(idCenLay);
//设置图层
pPipe->setLayer(idOutLay);
}
BOOL AecDbDuctLine::CreateWPipe(AECStatusRecord* pRec,BOOL bMaybeAddTee/* = FALSE*/)
{
AcGePoint3d ptGe,ptGe1;
ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint();
ptGe1 = pRec->GetAcquirePoint();
AecDbHvacDuct* pWpipe = ImpNewDuct(m_pPipeParam,ptGe,ptGe1);
AecDbObjXDataMap* pXDataMap = pWpipe->GetSpecialtyData();
pWpipe->SetDuctParam(m_pPipeParam);
pWpipe->GetSpecialtyData()->SetAt(KEY_2DSTYLE,2);
pWpipe->GetSpecialtyData()->SetAt(KEY_SINGLEW,0);
AcDbObjectId idCenLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_CEN,m_pPipeParam->szSys,4,_T("center2"),NULL);
AcDbObjectId idOutLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_OUT,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
AcDbObjectId idSingle = DuctlineTools::AecInitLayerEx(LAY_HVAC_SIG,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
pXDataMap->SetAt(PIPE_CENTLAY,idCenLay);
pXDataMap->SetAt(PIPE_OUTDLAY,idOutLay);
pXDataMap->SetAt(PIPE_SINGLAY,idSingle);
pWpipe->SetDoubleLayer(idOutLay);
pWpipe->SetSingleLayer(idSingle);
pWpipe->SetCenterLayer(idCenLay);
//设置图层
//pWpipe->setLayer(idCenLay);
pWpipe->setLayer(idOutLay);
#ifndef _DEBUG_WAS_DEFINED
acutPrintf(_T("\n%.3f-%.3f"), ptGe.x, ptGe.y);
acutPrintf(_T("\n%.3f-%.3f"), ptGe1.x, ptGe1.y);
#endif
//第一次对齐即可
AcGeVector3d vtAg(0,0,0);
if (m_arHistoryIntfs.GetSize() == 0)
{
vtAg = ptGe1 - ptGe;
vtAg.normalize();
switch(m_pPipeParam->m_nAlign)
{
case 0://底部左
{
vtAg.rotateBy(-PI / 2.0,AcGeVector3d::kZAxis);
vtAg *= 0.5 * m_pPipeParam->dSize[0];
break;
}
case 1://底部中
{
vtAg.set(0,0,0);
break;
}
case 2://底部右
{
vtAg.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
vtAg *= 0.5 * m_pPipeParam->dSize[0];
break;
}
default:
break;
}
ptGe += vtAg;
m_pPipeJig->GetTailStatusRec()->SetAcquirePoint(ptGe);
}
pWpipe->SetStartPoint( ptGe );
pWpipe->SetEndPoint( ptGe1 );
AcGeVector3d vtDir = ptGe1 - ptGe;
vtDir.normalize();
//法向量,水平风管
AcGeVector3d vtWDir = vtDir;
vtWDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
AcGeVector3d vtNorm = vtDir.crossProduct(vtWDir);
pWpipe->GetSpecialtyData()->SetAt(KEY_NORMAL,vtNorm);
m_pPipeParam->m_vtNrom = vtNorm;
//pWpipe->ReCreateByXDataMap();
AcDbObjectId id = CoreTools::AddToModelSpace(pWpipe);
AddUserData(id,pXDataMap,0);
//记录接口到历史记录
AecInterface intf;
intf.ptPos = ptGe1;
intf.vtDir = vtDir;
intf.idOwner = id;
PushInterface(intf);
if (bMaybeAddTee) //开始端或末端考虑添加三通的可能性
{
//1. 可能的与其他管子在开始端合成三通
MaybeAddTeeConnectToThis(ptGe,vtDir,id,0);
//2. 可能的与其他管子在末端合成三通,从而结束命令
if ( MaybeAddTeeConnectToThis(ptGe1,vtDir,id,1) )
{
//结束命令
m_bStopCommand = TRUE;
}
//1.可能与其他的管子在中间端合成四通的可能性
MaybeAddCrossConnectToThis(ptGe,ptGe1,id);
}
else //末端或中间部分添加三通或四通的可能性
{
//1.可能与其他的管子在中间端合成四通的可能性
MaybeAddCrossConnectToThis(ptGe,ptGe1,id);
//2. 可能的与其他管子在末端合成三通,从而结束命令
if ( MaybeAddTeeConnectToThis(ptGe1,vtDir,id,1) )
{
//结束命令
m_bStopCommand = TRUE;
}
}
return TRUE;
}
BOOL AecDbDuctLine::CreatePipe(const AcGePoint3d& ptSta,const AcGePoint3d& ptEnd,AecHvac::DuctParam* pPipeParam,double dSectRot)
{
AecDbHvacDuct* pWpipe = ImpNewDuct(pPipeParam,ptSta,ptEnd);
AecDbObjXDataMap* pXDataMap = pWpipe->GetSpecialtyData();
// 增加参数 [10/24/2016 Rex]
if(g_pMapData != NULL)
{
CMapStringToString mapData;
CString sKey,sVal;
for (POSITION ps = g_pMapData->GetStartPosition();ps != NULL;)
{
g_pMapData->GetNextAssoc(ps,sKey,sVal);
pXDataMap->SetAt(sKey,sVal);
}
}
if (fabs(dSectRot) > 1.e-3)
pWpipe->SetSectionRotation(dSectRot);
pWpipe->SetDuctParam(pPipeParam);
pWpipe->GetSpecialtyData()->SetAt(KEY_2DSTYLE,2);
pWpipe->GetSpecialtyData()->SetAt(KEY_SINGLEW,0);
pWpipe->SetStartPoint( ptSta );
pWpipe->SetEndPoint( ptEnd );
pXDataMap->SetAt(KEY_NORMAL,pPipeParam->m_vtNrom);
if ( fabs(ptSta.z - ptEnd.z) > 1.e-6)
{
pWpipe->GetSpecialtyData()->SetAt(KEY_DRAWGRAD,TRUE);
}
AcDbObjectId id = CoreTools::AddToModelSpace(pWpipe);
AddUserData(id,pXDataMap,0);
AcGeVector3d vtDir = ptEnd - ptSta;
//记录接口到历史记录
AecInterface intf;
intf.ptPos = ptEnd;
intf.vtDir = vtDir;
intf.idOwner = id;
PushInterface(intf);
return TRUE;
}
BOOL AecDbDuctLine::ExtendLastWPipe(AECStatusRecord* pRec)
{
int nLen = m_arHistoryIntfs.GetSize();
if (nLen == 0)
return FALSE;
AecInterface& intf = m_arHistoryIntfs[nLen - 1];
AcDbObjectId id = intf.idOwner;
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite))
{
AecDbHvacDuct* pDbWpipe = AecDbHvacDuct::cast(pEnt);
if (pDbWpipe != NULL)
{
AcGePoint3d ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint();
AcGePoint3d ptGe1 = pRec->GetAcquirePoint();
AcGeVector3d vtThis = ptGe1 - ptGe;
AcGePoint3d ptGeT;
int nPos = 0;
AcGeVector3d vt = pDbWpipe->EndPoint() - pDbWpipe->StartPoint();
if (vtThis.isCodirectionalTo(vt))
{
ptGeT = pDbWpipe->EndPoint();
pDbWpipe->SetEndPoint(pRec->GetAcquirePoint());
nPos = 1;
}
else
{
ptGeT = pDbWpipe->StartPoint();
pDbWpipe->SetStartPoint(pRec->GetAcquirePoint());
}
//pDbWpipe->UpdateInterfaceRec(ptGeT,pRec->GetAcquirePoint());
//先关闭
pEnt->close();
//1.可能与其他的管子在中间端合成四通的可能性
MaybeAddCrossConnectToThis(ptGe,ptGe1,id);
//2. 可能的与其他管子在末端合成三通,从而结束命令
AcGeVector3d vtDir = ptGe1 - ptGe;
if ( MaybeAddTeeConnectToThis(ptGe1,vtDir,id,nPos) )
{
//结束命令
m_bStopCommand = TRUE;
}
intf.ptPos = pRec->GetAcquirePoint();
PushInterface(intf,FALSE);
return TRUE;
}
AecDbHvacFitting* pDbFit = AecDbHvacFitting::cast(pEnt);
if (pDbFit != NULL) //上次是管件,本次创建管子
{
AecDbObjXDataMap* pXDataMap = pDbFit->GetSpecialtyData();
int nVal = 0;
pXDataMap->GetAt(KEY_RUNTIME,nVal);
EFittingType eKind = (EFittingType)nVal;
//可能的改上次弯头为三通,当方向不一致
if (nVal == eElbow)
{
AcGeVector3d vtIntf = intf.vtDir;
AcGePoint3d ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint();
AcGePoint3d ptGe1 = pRec->GetAcquirePoint();
AcGeVector3d vtThis = ptGe1 - ptGe;
if (vtThis.isParallelTo(vtIntf))
{
if (!vtThis.isCodirectionalTo(vtIntf)) // 反向,改弯头为三通
{
//判断弯头是否是90度弯头
double dAng = 0.0;
pXDataMap->GetAt(PIPE_ELBOWANG,dAng);
if ( fabs( dAng - 90.0 ) < 1.e-6) //是90 度
{
AecHvac::DuctParam data;
memset(&data,0,sizeof(AecHvac::DuctParam));
pDbFit->GetDuctParam(data);
//获取另一方向
double dDn = data.dSize[0];
AcGeVector3d vt1,vt2;
pXDataMap->GetAt(KEY_MAJBR,vt1);
pXDataMap->GetAt(KEY_MINBR,vt2);
AcGeVector3d vtMin;
if (vt1.isParallelTo(vtIntf)) // 本位置
{
vtMin = vt2;
}
else
{
vtMin = vt1;
vtMin.negate();
}
AcGePoint3d ptGeM;
pXDataMap->GetAt(KEY_MID,ptGeM);
ChangeElbowToTree(pDbFit,vtThis,ptGeM,vtMin,dDn,pRec);
}
}
}
}
else if(nVal == eTee)
{
AcGeVector3d vtIntf = intf.vtDir;
AcGePoint3d ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint();
AcGePoint3d ptGe1 = pRec->GetAcquirePoint();
AcGeVector3d vtThis = ptGe1 - ptGe;
AecInterface inf2,inf0;
pDbFit->GetInterface(2,inf2);
pDbFit->GetInterface(0,inf0);
AcGeVector3d vtInf2 = inf2.vtDir;
AcGeVector3d vtInf0 = inf0.vtDir;
if (vtInf0.isPerpendicularTo(vtInf2)) //正十字三通
{
//如果是支管拉,才可能创建四通;
if (vtThis.isParallelTo(vtIntf) && vtIntf.isParallelTo(vtInf2) )
{
if (!vtThis.isCodirectionalTo(vtIntf)) // 反向,改三通为四通
{
//直接改三通为四通
ChangeTeeToCross(pDbFit,vtInf0,vtInf2,pRec);
}
}
}
}
pEnt->close();
return CreateWPipe(pRec);
}
AecDbEwEquipment* pWEqu = AecDbEwEquipment::cast(pEnt);
if (pWEqu != NULL)
{
pEnt->close();
return CreateWPipe(pRec);
}
pEnt->close();
intf.ptPos = pRec->GetAcquirePoint();
return TRUE;
}
return FALSE;
}
BOOL AecDbDuctLine::CreateElbowAndPipe(AECStatusRecord* pRec, const EFittingType &type/* = eElbow*/)
{
int nLen = m_arHistoryIntfs.GetSize();
if (nLen == 0)
return FALSE;
AecInterface intf;
intf = m_arHistoryIntfs[nLen - 1];
AcDbObjectId id = intf.idOwner;
AcGePoint3d ptCur = pRec->GetAcquirePoint();
AcGePoint3d ptGeM = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint();
AcGeVector3d vtMaj,vtMin,vtPipe;
vtMaj = intf.vtDir;
vtMaj.normalize();
vtMaj.negate();
vtMin = ptCur - ptGeM;
vtMin.normalize();
//如果上端仅仅为一个接口,且为立管,则需要上段绕Z轴旋转
bool bSwitchSize = false;
if ( GetLastInfCount() >= 1)
{
AecInterface* pLast = GetLastInterface();
if (pLast != NULL)
{
if (pLast->vtDir.isParallelTo(AcGeVector3d::kZAxis))
{
if (m_pPipeParam->eType == eRect)
{
bSwitchSize = true;
}
}
}
}
double dTmp = 0.0;
if (bSwitchSize)
{
dTmp = m_pPipeParam->dSize[0];
if (m_pPipeParam->eType == eRect)
{
m_pPipeParam->dSize[0] = m_pPipeParam->dSize[1];
m_pPipeParam->dSize[1] = dTmp;
}
}
AecDbHvacFitting* pFit = ImpNewElbow(vtMaj,ptGeM,vtMin,m_pPipeParam,m_pPipeParam);
if (bSwitchSize)
{
dTmp = m_pPipeParam->dSize[0];
if (m_pPipeParam->eType == eRect)
{
m_pPipeParam->dSize[0] = m_pPipeParam->dSize[1];
m_pPipeParam->dSize[1] = dTmp;
}
}
//改变上次intf 的末端点
AecInterface intf0,intf1;
pFit->GetInterface(0,intf0);
pFit->GetInterface(1,intf1);
AcGeVector3d vtMove = vtMaj;
vtMove.normalize();
AcGePoint3d ptGeT;
//判断id 是管件
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead))
{
AecDbHvacFitting* pFitLast = AecDbHvacFitting::cast(pEnt);
if (pFitLast != NULL)
{
double dMove = 0.0;
if (intf.vtDir.isParallelTo(intf0.vtDir))
{
dMove = intf.ptPos.distanceTo(intf0.ptPos);
vtMove = intf.vtDir;
vtMove.normalize();
vtMove *= dMove;
ptGeM += vtMove;
}
else
{
dMove = intf.ptPos.distanceTo(intf1.ptPos);
vtMove = intf.vtDir;
vtMove.normalize();
vtMove *= dMove;
ptGeM += vtMove;
}
AcGeMatrix3d xformMove;
xformMove.setToTranslation(vtMove);
pFit->transformBy(xformMove);
pFit->GetInterface(0,intf0);
pFit->GetInterface(1,intf1);
vtMove = vtMaj;
vtMove.normalize();
}
pEnt->close();
}
AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData();
//AcDbObjectId idLay = KTSetting::InitLayer(LAY_HVAC_OUT);
//pFit->setLayer(idLay);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite))
{
// 如果上次是管子,则改变上次管子的终点
AecDbHvacDuct* pWPipe = AecDbHvacDuct::cast(pEnt);
if (pWPipe != NULL)
{
AcGeVector3d vtPipe = pWPipe->EndPoint() - pWPipe->StartPoint();
if (intf0.vtDir.isParallelTo(vtPipe))
{
//距离那个点近, 则修改哪个点
double dDis1 = ptGeM.distanceTo(pWPipe->StartPoint());
double dDis2 = ptGeM.distanceTo(pWPipe->EndPoint());
if (dDis1 < dDis2)
{
ptGeT = pWPipe->StartPoint();
pWPipe->SetStartPoint(intf0.ptPos);
}
else
{
ptGeT = pWPipe->EndPoint();
pWPipe->SetEndPoint(intf0.ptPos);
}
}
if (intf1.vtDir.isParallelTo(vtPipe))
{
//距离那个点近, 则修改哪个点
double dDis1 = ptGeM.distanceTo(pWPipe->StartPoint());
double dDis2 = ptGeM.distanceTo(pWPipe->EndPoint());
if (dDis1 < dDis2)
{
ptGeT = pWPipe->StartPoint();
pWPipe->SetStartPoint(intf1.ptPos);
}
else
{
ptGeT = pWPipe->EndPoint();
pWPipe->SetEndPoint(intf1.ptPos);
}
}
//如果上次是立管子,本次水平,则上次旋转
vtPipe = pWPipe->GetTailDir();
if (vtPipe.isParallelTo(AcGeVector3d::kZAxis))
{
AcGeLine3d ln3d(AcGePoint3d::kOrigin,vtMin);
if (ln3d.isParallelTo(AcGePlane::kXYPlane))
{
//旋转上次
double dAng = AcGeVector3d::kXAxis.angleTo(vtMin,AcGeVector3d::kZAxis);
if (vtMaj.isParallelTo(AcGeVector3d::kZAxis) ||
vtMin.isParallelTo(AcGeVector3d::kZAxis))
dAng += PI / 2.0;
pWPipe->SetSectionRotation(dAng);
}
}
}
AecDbHvacFitting* pDbFit = AecDbHvacFitting::cast(pEnt);
AecDbEwEquipment* pDbWEqu = AecDbEwEquipment::cast(pEnt);
if (pDbFit != NULL || pDbWEqu != NULL) //如果是管件或设备元件,则加入的弯头需要调整M点,因为上次对象不可更改接口点
{
AcGeVector3d vtPipe = intf.vtDir;
if (intf0.vtDir.isParallelTo(vtPipe))
{
vtMove = intf.ptPos - intf0.ptPos;
}
if (intf1.vtDir.isParallelTo(vtPipe))
{
vtMove = intf.ptPos - intf1.ptPos;
}
ptGeM += vtMove;
pXDataMap->SetAt(KEY_MID,ptGeM);
pFit->GetInterface(0,intf0);
pFit->GetInterface(1,intf1);
}
pEnt->close();
}
//添加本次到数据库
id = CoreTools::AddToModelSpace(pFit);
AddUserData(id,pXDataMap,1);
//创建余下的管子
AcGePoint3d ptSta,ptEnd;
if (intf0.vtDir.isParallelTo(vtMin))
{
ptSta = intf1.ptPos;
ptEnd = intf0.ptPos;
}
if (intf1.vtDir.isParallelTo(vtMin))
{
ptSta = intf0.ptPos;
ptEnd = intf1.ptPos;
}
//记录弯头末接口到历史记录
intf.ptPos = ptEnd;
intf.vtDir = vtMin;
intf.idOwner = id;
PushInterface(intf);
ptGeT = pRec->GetAcquirePoint();
ptGeT += vtMove;
pRec->SetAcquirePoint(ptGeT);
//校正
AcGePoint3d ptTemp;
AcDbLine ln;
ln.setStartPoint(ptEnd);
ptTemp = ptEnd + 1000.0 * vtMin;
ln.setEndPoint(ptTemp);
ln.getClosestPointTo(ptGeT,ptGeT,Adesk::kTrue);
pRec->SetAcquirePoint(ptGeT);
//创建余下管子,并插入虚拟状态记录
AECStatusRecord* pRecMid = new AECStatusRecord;
pRecMid->CopyFrom(pRec);
pRecMid->SetAcquirePoint(ptEnd);
m_pPipeJig->PushBackStatusRec(pRecMid);
CreateWPipe(pRec);
return TRUE;
}
BOOL AecDbDuctLine::MaybeAddTeeConnectToThis(AcGePoint3d& ptGe,AcGeVector3d& vtDir,AcDbObjectId id,int nPos)
{
AcDbObjectId idLay1,idLay2;
AcDbEntity* pEnt1 = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id,AcDb::kForRead))
{
idLay1 = pEnt1->layerId();
pEnt1->close();
}
else
{
return FALSE;
}
//以ptGe的,以管子公称直径为搜索
ads_point pt[5];
vtDir.normalize();
AcGeVector3d vtV = vtDir;
vtV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
AcGePoint3d ptGeT = ptGe;
ptGeT = ptGe + m_pPipeParam->dSize[0] * 0.5 * vtDir;
ptGeT += m_pPipeParam->dSize[0] * 0.5 * vtV;
AcGePoint3d ptGeX[5];
ptGeX[0] = ptGeT;
ptGeX[1] = ptGeX[0] - m_pPipeParam->dSize[0] * vtDir;
ptGeX[2] = ptGeX[1] - m_pPipeParam->dSize[0] * vtV;
ptGeX[3] = ptGeX[0] - m_pPipeParam->dSize[0] * vtV;
ptGeX[4] = ptGeX[0];
for (int i = 0;i < 5;i++)
{
acdbWcs2Ucs(asDblArray(ptGeX[i]),pt[i],false);
}
TCHAR szBuf[64];
memset(szBuf,0,sizeof(szBuf));
_tcscpy(szBuf, DXF_PIPE);
struct resbuf rb;
rb.restype = 0;
rb.resval.rstring = szBuf;
rb.rbnext = NULL;
struct resbuf* pointlist = NULL;
pointlist = acutBuildList(RTPOINT, pt[0], RTPOINT, pt[1],
RTPOINT, pt[2], RTPOINT, pt[3], 0);
ads_name ss,ent;
acedSSGet(_T("CP"),pointlist,NULL,&rb,ss);
acutRelRb(pointlist);
Adesk::Int32 lLen = 0;
acedSSLength(ss,&lLen);
double dTemp = 0.0;
CString sSQL,sTemp;
AcDbObjectId idT;
AcDbEntity* pEnt = NULL;
AcGeVector3d vtPipe;
AcGePoint3d ptMid,ptTemp1,ptTemp2;
BOOL bModified = FALSE;
for (long i = 0;i < lLen;i++)
{
acedSSName(ss,i,ent);
acdbGetObjectId(idT,ent);
if (idT == id) continue;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idT,AcDb::kForWrite))
{
AecDbHvacDuct* pWPipe = AecDbHvacDuct::cast(pEnt);
if (pWPipe != NULL)
{
//判断是否同系统
idLay2 = pWPipe->layerId();
if (idLay1 != idLay2)
{
pEnt->close();
continue;
}
vtPipe = pWPipe->EndPoint() - pWPipe->StartPoint();
vtPipe.normalize();
if (!vtPipe.isParallelTo(vtDir))
{
//且两管子中心线能相交
AcGeLine3d ln1(pWPipe->EndPoint(),vtPipe);
AcGeLine3d ln2(ptGe,vtDir);
double dDn = m_pPipeParam->dSize[0];
pWPipe->GetSpecialtyData()->GetAt(KEY_SIZE1,dDn);
if (ln1.intersectWith(ln2,ptMid))
{
double dL = GetElbowL(m_pPipeParam);
double dS = dL;
//也可能加弯头,ptMid的两头有一在管子外
ptTemp1 = ptMid + vtPipe * dL;
ptTemp2 = ptMid - vtPipe * dL;
AcGeLineSeg3d lineGe(pWPipe->StartPoint(),pWPipe->EndPoint());
BOOL bAddTee = TRUE;
if ( !lineGe.isOn(ptTemp1) || !lineGe.isOn(ptTemp2) )
{
if ( fabs(dDn - m_pPipeParam->dSize[0]) < 1.e-3) //==DN
{
pEnt->close();
bAddTee = FALSE;
if ( AddElbow(idT,ptMid,id))
{
bModified = TRUE;
}
return bModified;
}
else// 只能加三通
{
bAddTee = TRUE;
}
}
if (bAddTee)
{
AecHvac::DuctParam wparamMain;
memcpy(&wparamMain,m_pPipeParam,sizeof(AecHvac::DuctParam));
pWPipe->GetDuctParam(wparamMain);
AcGeVector3d vtBra = -vtPipe;
vtBra.normalize();
AcGePoint2d ptBL = GetTeeBL(&wparamMain,m_pPipeParam,vtDir,vtBra,AecHvac::eArcuateBranch);
dL = ptBL.x;//GetElbowL(&wparamMain);
dS = ptBL.y;//GetElbowL(m_pPipeParam);
//对方断为两个管子
SplitWPipe(ptMid,dL,pWPipe);
if (nPos == 1)
vtDir.negate();
//改变this管子的位置
ptGe = ptMid + dS * vtDir;
ModifyWPipe(ptGe,id,nPos);
//添加三通,继承pWPipe属性
AddTee(pWPipe,dL,ptMid,dS,vtDir);
}
bModified = TRUE;
acedSSFree(ss);
pEnt->close();
return bModified;
}
}
else //平行,是否可以融合
{
//规格相同, 且不是从夹点拖出的命令
if (m_idStartDragFrom != id)
{
double dDn = 0.0;
pWPipe->GetSpecialtyData()->GetAt(KEY_SIZE1,dDn);
if (fabs(dDn - m_pPipeParam->dSize[0]) < 1.e-3)//公称相同
{
if ( fabs(pWPipe->EndPoint().z - m_pPipeParam->m_dEl) < 1.e-3)//等标高
{
AcGePoint3d ptEnd = pWPipe->EndPoint();
AcGePoint3d ptSta = pWPipe->StartPoint();
if (!vtPipe.isCodirectionalTo(vtDir))
{
AcGePoint3d ptTemp = ptSta;
ptSta = ptEnd;
ptEnd = ptTemp;
}
//删除原来的管子
pEnt->erase();
//改变this管子的位置
ModifyWPipe( nPos == 0 ? ptSta : ptEnd,id,nPos);
bModified = TRUE;
}
}
}
}
}
pEnt->close();
}
}
acedSSFree(ss);
return bModified;
}
typedef struct Point_ID
{
AcDbObjectId id;
AcGePoint3d ptInt;
AcDbCurve* pCurve;
}POINT_ID;
static bool ComparePointID(Point_ID& pt1,Point_ID& pt2)
{
double dP1 = 0.0,dP2 = 0.0;
pt1.pCurve->getParamAtPoint(pt1.ptInt,dP1);
pt1.pCurve->getParamAtPoint(pt2.ptInt,dP2);
if (dP1 - dP2 < 1.e-6)
{
return true;//up sort
}
return false;//down sort
}
BOOL AecDbDuctLine::MaybeAddCrossConnectToThis(AcGePoint3d ptFr,AcGePoint3d ptTo,AcDbObjectId id)
{
AcDbObjectId idLay1,idLay2;
AcDbEntity* pEnt1 = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id,AcDb::kForRead))
{
idLay1 = pEnt1->layerId();
pEnt1->close();
}
else
{
return FALSE;
}
//等标高的情况下
if (fabs(ptFr.z - ptTo.z) > 1.0)
{
return FALSE;
}
//id 的范围内选择实体,只考虑XY 面,其他三维单加四通
AcGePoint3d ptGe[4];
AcGeVector3d vtDir = ptTo - ptFr;
AcGeVector3d vtV = vtDir;
vtV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
vtV.normalize();
vtDir.normalize();
//四通的主支 DN 相同
double dM = 0.0,dB = 0.0;
double dL = GetElbowL(m_pPipeParam);
dM = dL;
dB = dL;
//选择范围缩小, 至少长度超过四通的长度
ptFr += m_pPipeParam->dSize[0] * 2.0 * vtDir;
ptTo -= m_pPipeParam->dSize[0] * 2.0 * vtDir;
ptGe[0] = ptFr;
ptGe[0] += vtV * m_pPipeParam->dSize[0] * 0.8;
ptGe[1] = ptTo;
ptGe[1] += vtV * m_pPipeParam->dSize[0] * 0.8;
ptGe[2] = ptGe[1] - vtV * 1.6 * m_pPipeParam->dSize[0];
ptGe[3] = ptGe[0] - vtV * 1.6 * m_pPipeParam->dSize[0];
ads_point pt[4];
for (int i = 0;i < 4;i++)
{
acdbWcs2Ucs(asDblArray(ptGe[i]),pt[i],false);
}
TCHAR szBuf[64];
memset(szBuf,0,sizeof(szBuf));
_tcscpy(szBuf, DXF_PIPE);
struct resbuf rb;
rb.restype = 0;
rb.resval.rstring = szBuf;
rb.rbnext = NULL;
struct resbuf* pointlist = NULL;
pointlist = acutBuildList(RTPOINT, pt[0], RTPOINT, pt[1],
RTPOINT, pt[2], RTPOINT, pt[3], 0);
ads_name ss,ent;
acedSSGet(_T("CP"),pointlist,NULL,&rb,ss);
acutRelRb(pointlist);
Adesk::Int32 lLen = 0;
acedSSLength(ss,&lLen);
AcDbObjectId idT;
AcDbEntity* pEnt = NULL;
AcGeVector3d vtDir2;
AcDbLine line;
line.setStartPoint(ptFr);
line.setEndPoint(ptTo);
AcGeLineSeg3d line1;
line1.set(ptFr,ptTo);
AcGeLineSeg3d line2;
double dDN = 0.0;
std::vector<Point_ID> vtPtids;
for ( i = 0;i < lLen;i++)
{
acedSSName(ss,i,ent);
acdbGetObjectId(idT,ent);
if (idT == id) continue;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idT,AcDb::kForRead))
{
idLay2 = pEnt->layerId();
if (idLay1 != idLay2)
{
pEnt->close();
continue;
}
AecDbHvacDuct* pWPipe = AecDbHvacDuct::cast(pEnt);
if (pWPipe != NULL)
{
AecHvac::DuctParam data;
memset(&data,0,sizeof(AecHvac::DuctParam));
pWPipe->GetDuctParam(data);
//判断标高是否一致,方向是否垂直,且 公称直径一致??
if ( fabs(pWPipe->EndPoint().z - ptTo.z) < 1.e-6 &&
fabs(m_pPipeParam->dSize[0] - data.dSize[0]) < 1.e-6)
{
vtDir2 = pWPipe->EndPoint() - pWPipe->StartPoint();
if (vtDir2.isPerpendicularTo(vtDir))
{
line2.set(pWPipe->StartPoint(),pWPipe->EndPoint());
Point_ID ptid;
ptid.id = idT;
ptid.pCurve = &line;
if ( line1.intersectWith(line2,ptid.ptInt))
{
vtPtids.push_back(ptid);
}
}
}
}
pEnt->close();
}
}
//排序
if (!vtPtids.empty())
{
std::sort(vtPtids.begin(),vtPtids.end(),ComparePointID);
typedef std::vector<Point_ID>::iterator PIDIT;
for (PIDIT it = vtPtids.begin();it != vtPtids.end();it++)
{
AddCross( (*it).id,(*it).ptInt,id);
}
}
acedSSFree(ss);
return FALSE;
return FALSE;
}
BOOL AecDbDuctLine::SplitWPipe(AcGePoint3d& ptMid,double dL,AecDbHvacDuct* pWPipe,BOOL bEraseWhiletooShort/* = TRUE*/)
{
AcGePoint3d ptSta = pWPipe->StartPoint();
AcGePoint3d ptEnd = pWPipe->EndPoint();
AcGeVector3d vtDir = ptEnd - ptSta;
vtDir.normalize();
AecDbObjXDataMap* pXDataMapt = pWPipe->GetSpecialtyData();
AcGePoint3d ptTemp = ptMid - dL * vtDir;
AcGeVector3d vtDir1 = ptTemp - ptSta;
if (vtDir.isCodirectionalTo(vtDir1)) //同向,说明放得下L的 Tee
{
//新建管子
//放得下L的 Tee 的情况,新建vtDir 方向的end端
AecDbHvacDuct* pWPipe1 = new AecDbHvacDuct;
AecDbObjXDataMap* pXDataMap = pWPipe1->GetSpecialtyData();
pXDataMap->CopyFrom(pWPipe->GetSpecialtyData());
CString sGUID = IDCreate();
pXDataMap->SetAt(KEY_NO,sGUID);
AcDbObjectId idCenLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_CEN,m_pPipeParam->szSys,4,_T("center2"),NULL);
AcDbObjectId idOutLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_OUT,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
AcDbObjectId idSingle = DuctlineTools::AecInitLayerEx(LAY_HVAC_SIG,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
pXDataMap->SetAt(PIPE_CENTLAY,idCenLay);
pXDataMap->SetAt(PIPE_OUTDLAY,idOutLay);
pXDataMap->SetAt(PIPE_SINGLAY,idSingle);
pWPipe1->SetDoubleLayer(idOutLay);
pWPipe1->SetSingleLayer(idSingle);
pWPipe1->SetCenterLayer(idCenLay);
AecHvac::DuctParam data;
pWPipe->GetDuctParam(data);
pWPipe1->SetDuctParam(&data);
pWPipe1->GetSpecialtyData()->SetAt(KEY_2DSTYLE,2);
pWPipe1->GetSpecialtyData()->SetAt(KEY_SINGLEW,0);
ptTemp = ptMid - dL * vtDir;
pWPipe1->SetStartPoint(ptSta);
pWPipe1->SetEndPoint(ptTemp);
pWPipe1->setLayer(pWPipe->layerId());
//套管,洞口
//移除内部关联的套管,如果位置在其中
RemoveHolePipe(pWPipe1);
AcDbObjectId id = CoreTools::AddToModelSpace(pWPipe1);
AddUserData(id,pXDataMap,0);
//改变现有的管子的起点
ptTemp = ptMid + dL * vtDir;
pWPipe->SetStartPoint(ptTemp);
//套管,洞口
//移除内部关联的套管,如果位置在其中
RemoveHolePipe(pWPipe);
return TRUE;
}
else //放不下,直接更改 start 或 end 腾出L位置
{
double dDis1 = ptMid.distanceTo(ptSta);
double dDis2 = ptMid.distanceTo(ptEnd);
if (dDis1 < dDis2 )//靠近sta
{
ptTemp = ptMid + dL * vtDir;
vtDir1 = ptEnd - ptTemp;
if (vtDir1.isCodirectionalTo(vtDir))
{
pWPipe->SetStartPoint(ptTemp);
return TRUE;
}
}
else//靠近 end
{
ptTemp = ptMid - dL * vtDir;
vtDir1 = ptTemp - ptSta;
if (vtDir1.isCodirectionalTo(vtDir))
{
pWPipe->SetEndPoint(ptTemp);
return TRUE;
}
}
//套管,洞口
//移除内部关联的套管,如果位置在其中
RemoveHolePipe(pWPipe);
}
return FALSE;
}
void AecDbDuctLine::RemoveHolePipe(AecDbHvacDuct* pWPipe)
{
AcGePoint3d ptS = pWPipe->StartPoint();
AcGePoint3d ptE = pWPipe->EndPoint();
AcGePoint3d ptOn;
AcGeVector3d vt1,vt2;
AecDbObjXDataMap* pXDatMap = pWPipe->GetSpecialtyData();
if (pXDatMap == NULL)
return;
//关联的洞口和套管联动
AecDbObjXDataMap::It it = pXDatMap->Begin();
AecDbObjXDataMap::It end = pXDatMap->End();
CString sKey;
AecXData cVal;
memset(&cVal,0,sizeof(AecXData));
CStringArray arKeysRemove;
AcDbObjectId idSrc,idCloned;
for (; it != end;)
{
if (!pXDatMap->GetNext(it, sKey, cVal)) break;
if (sKey.Find(_T("$H")) != -1 && cVal.nVt == VT_BSTR)//可能的实体句柄
{
AcDbHandle handle(cVal.pszVal);
AcDbObjectId idHole;
acdbCurDwg()->getAcDbObjectId(idHole,false,handle);
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idHole,AcDb::kForRead))
{
AecDbX3dPartEntity* pX3dPartEnt = AecDbX3dPartEntity::cast(pEnt);
if (pX3dPartEnt != NULL)
{
ptOn = pX3dPartEnt->GetOrgPoint(true);
vt1 = ptOn - ptS;
vt2 = ptOn - ptE;
//TEST
//AcDbCircle* pCir = new AcDbCircle;
//pCir->setCenter(ptOn);
//pCir->setRadius(100.0);
//CoreTools::AddToModelSpace(pCir);
if (vt1.dotProduct(vt2) > 1.e-10)//同向
{
}
else
{
arKeysRemove.Add(sKey);
}
}
pEnt->close();
}
}
}
for (int i = 0;i < arKeysRemove.GetSize();i++)
{
pXDatMap->RemoveAt(arKeysRemove.GetAt(i));
//acutPrintf(_T("\nRemove key %s"),arKeysRemove.GetAt(i));
}
}
BOOL AecDbDuctLine::ModifyWPipe(AcGePoint3d& ptGe,AcDbObjectId id,int nPos)
{
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite))
{
AecDbHvacDuct* pWPipe = AecDbHvacDuct::cast(pEnt);
if (pWPipe != NULL)
{
if (nPos == 0)
{
AcGePoint3d ptGeT;
ptGeT = pWPipe->StartPoint();
pWPipe->SetStartPoint(ptGe);
}
if (nPos == 1)
{
AcGePoint3d ptGeT;
ptGeT = pWPipe->EndPoint();
pWPipe->SetEndPoint(ptGe);
}
}
pEnt->close();
}
return TRUE;
}
BOOL AecDbDuctLine::AddTee(AecDbHvacDuct* pWPipe,double dL,AcGePoint3d ptMid,double dB,AcGeVector3d& vtMin,AecHvac::HvacTeeType eTeeType /*= AecHvac::eArcuateBranch*/)
{
AcGeVector3d vtMaj = pWPipe->GetTailDir();
vtMaj.normalize();
AecHvac::DuctParam wparamMain;
memcpy(&wparamMain,m_pPipeParam,sizeof(AecHvac::DuctParam));
pWPipe->GetDuctParam(wparamMain);
AecDbHvacFitting* pFit = ImpNewTee(dL,ptMid,dB,vtMaj,vtMin,&wparamMain,eTeeType);
AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData();
//设置图层
//AcDbObjectId idLay = KTSetting::InitLayer(LAY_HVAC_OUT);
//pFit->setLayer(idLay);
AcDbObjectId id = CoreTools::AddToModelSpace(pFit);
AddUserData(id,pXDataMap,2);
return TRUE;
}
AecDbHvacFitting* AecDbDuctLine::ImpNewTee(double dL,AcGePoint3d& ptMid,double dB,AcGeVector3d& vtMaj,AcGeVector3d& vtMin,AecHvac::DuctParam* pMainParam,AecHvac::HvacTeeType eTeeType/* = AecHvac::eArcuateBranch*/)
{
if (pMainParam == NULL)
pMainParam = m_pPipeParam;
AecDbHvacFitting* pFit = new AecDbHvacFitting;
AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData();
//设置图层
//AcDbObjectId idLay = KTSetting::InitLayer(LAY_HVAC_OUT);
AcDbObjectId idCenLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_CEN,m_pPipeParam->szSys,4,_T("center2"),NULL);
AcDbObjectId idOutLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_OUT,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
AcDbObjectId idSingle = DuctlineTools::AecInitLayerEx(LAY_HVAC_SIG,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
pFit->setLayer(idOutLay);
pFit->SetDoubleLayer(idOutLay);
pFit->SetCenterLayer(idCenLay);
pFit->SetCenterLayer(idCenLay);
vtMaj.normalize();
double dRatio = m_pPipeParam->m_dRatio;
double dLx = GetElbowLx(pMainParam);
//AecHvac::HvacTeeType eTeeType = AecHvac::eArcuateBranch;
pXDataMap->SetAt(HVAC_SectType, m_pPipeParam->eType);
pXDataMap->SetAt(KEY_FITSRV,KEY_FITHVAC);
pXDataMap->SetAt(KEY_RUNTIME, (int)eTee);
pXDataMap->SetAt(HVAC_PlusEdge,m_pPipeParam->m_dPlusEdge);//咬口法兰翻边余量
pXDataMap->SetAt(HTEE_Type, eTeeType);
AcGePoint3d ptStart,ptEnd,ptBra;
ptStart = ptMid - vtMaj * dL;
ptEnd = ptMid + vtMaj * dL;
ptBra = ptMid + vtMin * dB;
pXDataMap->SetAt(HTEE_StartPoint, ptStart);
pXDataMap->SetAt(HTEE_EndPoint, ptEnd);
pXDataMap->SetAt(HTEE_BranchPoint, ptBra);
pXDataMap->SetAt(HTEE_StartDir, -vtMaj);
pXDataMap->SetAt(HTEE_EndDir, vtMaj);
pXDataMap->SetAt(HTEE_BranchDir, vtMin);
if (vtMin.isParallelTo(AcGeVector3d::kZAxis) ||
vtMaj.isParallelTo(AcGeVector3d::kZAxis) )
{
//如果是矩形
if (m_pPipeParam->eType == eRect)
{
pXDataMap->SetAt(HTEE_StartWidth, pMainParam->dSize[1]);
pXDataMap->SetAt(HTEE_EndWidth, pMainParam->dSize[1]);
pXDataMap->SetAt(HTEE_BranchWidth, m_pPipeParam->dSize[1]);
pXDataMap->SetAt(HTEE_Thick, m_pPipeParam->dSize[0]);
pXDataMap->SetAt(HTEE_EndThick, m_pPipeParam->dSize[0]);
pXDataMap->SetAt(HTEE_BranchThick, m_pPipeParam->dSize[0]);
}
else
{
pXDataMap->SetAt(HTEE_StartWidth, pMainParam->dSize[0]);
pXDataMap->SetAt(HTEE_EndWidth, pMainParam->dSize[0]);
pXDataMap->SetAt(HTEE_BranchWidth, m_pPipeParam->dSize[0]);
pXDataMap->SetAt(HTEE_Thick, m_pPipeParam->dSize[1]);
pXDataMap->SetAt(HTEE_EndThick, m_pPipeParam->dSize[1]);
pXDataMap->SetAt(HTEE_BranchThick, m_pPipeParam->dSize[1]);
}
}
else
{
pXDataMap->SetAt(HTEE_StartWidth, pMainParam->dSize[0]);
pXDataMap->SetAt(HTEE_EndWidth, pMainParam->dSize[0]);
pXDataMap->SetAt(HTEE_BranchWidth, m_pPipeParam->dSize[0]);
pXDataMap->SetAt(HTEE_Thick, m_pPipeParam->dSize[1]);
pXDataMap->SetAt(HTEE_EndThick, m_pPipeParam->dSize[1]);
pXDataMap->SetAt(HTEE_BranchThick, m_pPipeParam->dSize[1]);
}
pXDataMap->SetAt(HVAC_HasBaseLine, 1);
pXDataMap->SetAt(HVAC_IsSingleLine, 0);
pXDataMap->SetAt(HTEE_RadRatio, m_pPipeParam->m_dRatio);
pXDataMap->SetAt(HVAC_PlusEdge, m_pPipeParam->m_dPlusEdge);
pXDataMap->SetAt(HVAC_EndLayer, idOutLay);
pXDataMap->SetAt(HVAC_System, m_pPipeParam->szSys);
pXDataMap->SetAt(HVAC_Material, m_pPipeParam->szMat);
pXDataMap->SetAt(HVAC_EdgeWeight, TRUE);
pXDataMap->SetAt(HVAC_EdgeWidth, 0.35);
pXDataMap->SetAt(HVAC_CentWeight, TRUE);
pXDataMap->SetAt(HVAC_CentWidth, 0.35);
pXDataMap->SetAt(HVAC_EndWidth, 0.35);
pFit->SetDuctParam(*pMainParam);
return pFit;
}
AecDbHvacDuct * AecDbDuctLine::ImpNewDuct(AecHvac::DuctParam* pparam,const AcGePoint3d& ptSta,const AcGePoint3d& ptEnd)
{
if (pparam == NULL)
return NULL;
//新建一个风管
AecDbHvacDuct *pNewDuct = new AecDbHvacDuct;
pNewDuct->SetStartPoint(ptSta);
pNewDuct->SetEndPoint(ptEnd);
AecDbObjXDataMap *pNewMap = pNewDuct->GetSpecialtyData();
//设置图层
//AcDbObjectId idLay = KTSetting::InitLayer(LAY_HVAC_OUT);
AcDbObjectId idCenLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_CEN,m_pPipeParam->szSys,4,_T("center2"),NULL);
AcDbObjectId idOutLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_OUT,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
AcDbObjectId idSingle = DuctlineTools::AecInitLayerEx(LAY_HVAC_SIG,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
pNewMap->SetAt(PIPE_CENTLAY,idCenLay);
pNewMap->SetAt(PIPE_OUTDLAY,idOutLay);
pNewMap->SetAt(PIPE_SINGLAY,idSingle);
pNewDuct->SetDoubleLayer(idOutLay);
pNewDuct->SetSingleLayer(idSingle);
pNewDuct->SetCenterLayer(idCenLay);
pNewDuct->setLayer(idOutLay);
pNewMap->SetAt(KEY_FITSRV, KEY_FITHVAC);
pNewMap->SetAt(KEY_RUNTIME, ePipe);
pNewMap->SetAt(HVAC_SectType, pparam->eType);
pNewMap->SetAt(HVAC_Material, pparam->szMat);
pNewMap->SetAt(HDCT_Width, pparam->dSize[0]);
pNewMap->SetAt(HDCT_Thick, pparam->dSize[1]);
pNewMap->SetAt(HDCT_Bulge, 0.0);
AecHvac::HvacDuctType eType = AecHvac::eStraight;
pNewMap->SetAt(HDCT_Type, eType);
pNewMap->SetAt(HVAC_HasBaseLine, TRUE);
pNewMap->SetAt(HVAC_IsSingleLine, 0);
pNewMap->SetAt(HVAC_System, pparam->szSys);
//保存风量单位
pNewMap->SetAt(HVAC_AirLoadUnit, pparam->iALUnit);
//风口风量
double dAirload = 0.0;
pNewMap->SetAt(HVAC_AirLoad, pparam->dAirload);
// add end
//pNewMap->SetAt(HVAC_EndLayer, idOutLay, FALSE);
pNewMap->SetAt(HVAC_EdgeWeight, TRUE);
pNewMap->SetAt(HVAC_CentWeight, TRUE);
pNewMap->SetAt(HVAC_EdgeWidth, 0.15);
pNewMap->SetAt(HVAC_CentWidth, 0.15);
pNewDuct->setNormal(pparam->m_vtNrom);
return pNewDuct;
}
BOOL AecDbDuctLine::AddCross(AcDbObjectId id1,AcGePoint3d& ptInt,AcDbObjectId idThis,AecHvac::HvacCrossType eCrossType/* = AecHvac::eArcuateCross*/)
{
AecDbHvacDuct* pWPipe = NULL;
double dL = 0.0,dB = 0.0;
AcGeVector3d vtMaj,vtMin;
double dRatio = m_pPipeParam->m_dRatio;
double dLx = GetElbowLx(m_pPipeParam);
dL = GetElbowL(m_pPipeParam);
dB = dL;
AcDbObjectId idLay;
AecHvac::DuctParam paramB;
memcpy(&paramB,m_pPipeParam,sizeof(AecHvac::DuctParam));
//idThis 管分割为两部分
AcDbEntity* pEnt2 = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt2,idThis,AcDb::kForWrite))
{
idLay = pEnt2->layerId();
pWPipe = AecDbHvacDuct::cast(pEnt2);
if (pWPipe != NULL)
{
pWPipe->GetDuctParam(paramB);
vtMin = pWPipe->EndPoint() - pWPipe->StartPoint();
vtMin.normalize();
AcGeLineSeg3d ln(pWPipe->StartPoint(),pWPipe->EndPoint());
if (ln.isOn(ptInt)) //落在管子上,两管线相交
{
if ( !SplitWPipe(ptInt,dB,pWPipe,FALSE) )
{
//太短,放不下四通
pEnt2->close();
return FALSE;
}
}
else //不落在管子上,两管线延长相交, 外部加四通命令调用
{
vtMin.normalize();
double dDis1 = ptInt.distanceTo(pWPipe->StartPoint());
double dDis2 = ptInt.distanceTo(pWPipe->EndPoint());
if (dDis1 < dDis2)//距离sta近
{
pWPipe->SetStartPoint(ptInt + vtMin * dL);
}
else
{
pWPipe->SetEndPoint(ptInt - vtMin * dL);
}
}
}
pEnt2->close();
}
AecHvac::DuctParam paramM;
memcpy(&paramM,m_pPipeParam,sizeof(AecHvac::DuctParam));
// id1 管分割为两部分
AcDbEntity* pEnt1 = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForWrite))
{
pWPipe = AecDbHvacDuct::cast(pEnt1);
if (pWPipe != NULL)
{
pWPipe->GetDuctParam(paramM);
vtMaj = pWPipe->EndPoint() - pWPipe->StartPoint();
vtMaj.normalize();
AcGeLineSeg3d ln(pWPipe->StartPoint(),pWPipe->EndPoint());
if (ln.isOn(ptInt)) //落在管子上,两管线相交
{
SplitWPipe(ptInt,dL,pWPipe,TRUE);
}
else //不落在管子上,两管线延长相交, 外部加四通命令调用
{
vtMaj.normalize();
double dDis1 = ptInt.distanceTo(pWPipe->StartPoint());
double dDis2 = ptInt.distanceTo(pWPipe->EndPoint());
if (dDis1 < dDis2)//距离sta近
{
pWPipe->SetStartPoint(ptInt + vtMaj * dL);
}
else
{
pWPipe->SetEndPoint(ptInt - vtMaj * dL);
}
}
}
pEnt1->close();
}
//加入四通
AcGeVector3d vtStart = vtMaj;
vtStart.negate();
AcGeVector3d vtEnd = vtMaj;
AcGeVector3d vtBra1 = vtMin;
vtBra1.negate();
AcGeVector3d vtBr2 = vtMin;
vtStart.normalize();
vtEnd.normalize();
vtBra1.normalize();
vtBr2.normalize();
AcGePoint3d ptEnd = ptInt + vtEnd * dL;
AcGePoint3d ptStart = ptInt + vtStart * dL;
AcGePoint3d ptBra1 = ptInt + vtBra1 * dB;
AcGePoint3d ptBra2 = ptInt + vtBr2 * dB;
AecDbHvacFitting* pFit = ImpNewCross(NULL,ptInt,vtStart,ptStart,vtEnd,ptEnd,vtBra1,ptBra1,vtBr2,ptBra2,&paramM,&paramB,eCrossType);
AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData();
//设置图层
//pFit->setLayer(idLay);
AcDbObjectId id = CoreTools::AddToModelSpace(pFit);
AddUserData(id,pXDataMap,2);
return TRUE;
}
AecDbHvacFitting* AecDbDuctLine::ImpNewCross(AecDbHvacFitting* pFitMod,AcGePoint3d& ptInt,AcGeVector3d& vtStart,AcGePoint3d& ptStart,
AcGeVector3d& vtEnd,AcGePoint3d& ptEnd,AcGeVector3d& vtBra1,
AcGePoint3d& ptBra1,AcGeVector3d& vtBr2,AcGePoint3d& ptBra2,
AecHvac::DuctParam* pParamM,
AecHvac::DuctParam* pParamB,
AecHvac::HvacCrossType eCrossType/* = AecHvac::eArcuateCross*/)
{
AecDbHvacFitting* pFit = NULL;
if (pFitMod != NULL)
{
pFit = pFitMod;
}
else
{
pFit = new AecDbHvacFitting;
}
AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData();
//设置图层
//AcDbObjectId idLay = KTSetting::InitLayer(LAY_HVAC_OUT);
AcDbObjectId idCenLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_CEN,m_pPipeParam->szSys,4,_T("center2"),NULL);
AcDbObjectId idOutLay = DuctlineTools::AecInitLayerEx(LAY_HVAC_OUT,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
AcDbObjectId idSingle = DuctlineTools::AecInitLayerEx(LAY_HVAC_SIG,m_pPipeParam->szSys,7,_T("Continuous"),NULL);
pFit->setLayer(idOutLay);
pFit->SetDoubleLayer(idOutLay);
pFit->SetCenterLayer(idCenLay);
pFit->SetCenterLayer(idCenLay);
pXDataMap->SetAt(KEY_FITSRV,KEY_FITHVAC);
pXDataMap->SetAt(KEY_RUNTIME, (int)eCross);
//AecHvac::HvacTeeType eCrossType = AecHvac::eArcuateBranch;
pXDataMap->SetAt(HVAC_SectType, pParamM->eType);
pXDataMap->SetAt(HCRS_Type, pParamM->eType== eRect ? eCrossType : AecHvac::eOrthoBranch);
pXDataMap->SetAt(HCRS_StartPoint, ptStart);
pXDataMap->SetAt(HCRS_StartDir, vtStart);
pXDataMap->SetAt(HCRS_EndPoint, ptEnd);
pXDataMap->SetAt(HCRS_EndDir, vtEnd);
pXDataMap->SetAt(HCRS_BranchPoint1, ptBra1);
pXDataMap->SetAt(HCRS_BranchDir1, vtBra1);
pXDataMap->SetAt(HCRS_BranchPoint2, ptBra2);
pXDataMap->SetAt(HCRS_BranchDir2, vtBr2);
if (vtBra1.isParallelTo(AcGeVector3d::kZAxis) ||
vtStart.isParallelTo(AcGeVector3d::kZAxis))
{
//如果是矩形
if (m_pPipeParam->eType == eRect)
{
pXDataMap->SetAt(HCRS_StartWidth, pParamM->dSize[1]);
pXDataMap->SetAt(HCRS_EndWidth, pParamM->dSize[1]);
pXDataMap->SetAt(HCRS_Thick, pParamM->dSize[0]);
pXDataMap->SetAt(HCRS_Branch1Width, pParamB->dSize[1]);
pXDataMap->SetAt(HCRS_Branch1Thick, pParamB->dSize[0]);
pXDataMap->SetAt(HCRS_Branch2Width, pParamB->dSize[1]);
pXDataMap->SetAt(HCRS_Branch2Thick, pParamB->dSize[0]);
}
else
{
pXDataMap->SetAt(HCRS_StartWidth, pParamM->dSize[0]);
pXDataMap->SetAt(HCRS_Thick, pParamM->dSize[1]);
pXDataMap->SetAt(HCRS_EndWidth, pParamM->dSize[0]);
pXDataMap->SetAt(HCRS_Branch1Width, pParamB->dSize[0]);
pXDataMap->SetAt(HCRS_Branch1Thick, pParamB->dSize[1]);
pXDataMap->SetAt(HCRS_Branch2Width, pParamB->dSize[0]);
pXDataMap->SetAt(HCRS_Branch2Thick, pParamB->dSize[1]);
}
}
else
{
pXDataMap->SetAt(HCRS_StartWidth, pParamM->dSize[0]);
pXDataMap->SetAt(HCRS_Thick, pParamM->dSize[1]);
pXDataMap->SetAt(HCRS_EndWidth, pParamM->dSize[0]);
pXDataMap->SetAt(HCRS_Branch1Width, pParamB->dSize[0]);
pXDataMap->SetAt(HCRS_Branch1Thick, pParamB->dSize[1]);
pXDataMap->SetAt(HCRS_Branch2Width, pParamB->dSize[0]);
pXDataMap->SetAt(HCRS_Branch2Thick, pParamB->dSize[1]);
}
pXDataMap->SetAt(HVAC_IsSingleLine, 0);
pXDataMap->SetAt(HVAC_HasBaseLine,1);
pXDataMap->SetAt(HCRS_RadRatio, pParamM->m_dRatio);
pFit->SetDuctParam(*pParamM);
return pFit;
}
BOOL AecDbDuctLine::AddElbow(AcDbObjectId id1,AcGePoint3d& ptGe,AcDbObjectId idThis)
{
AecDbHvacDuct* pWPipe1 = NULL;
AecDbHvacDuct* pWPipe2 = NULL;
AcDbEntity* pEnt1 = NULL;
AcDbEntity* pEnt2 = NULL;
BOOL bSuccess = FALSE;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForWrite))
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,idThis,AcDb::kForWrite))
{
pWPipe1 = AecDbHvacDuct::cast(pEnt1);
pWPipe2 = AecDbHvacDuct::cast(pEnt2);
if (pWPipe1 != NULL && pWPipe2 != NULL)
{
AcGeLine3d ln1(pWPipe1->StartPoint(),pWPipe1->EndPoint());
AcGeLine3d ln2(pWPipe2->StartPoint(),pWPipe2->EndPoint());
AcGePoint3d ptMid = ptGe;
ln1.intersectWith(ln2,ptMid);
ptGe = ptMid;//??
AecHvac::DuctParam param1,param2;
pWPipe1->GetDuctParam(param1);
pWPipe2->GetDuctParam(param2);
int npos1 = 1,npos2 = 1;
AcGeVector3d vtMaj,vtMin;
double dDis1 = ptMid.distanceTo(pWPipe1->EndPoint());
double dDis2 = ptMid.distanceTo(pWPipe1->StartPoint());
vtMaj = pWPipe1->EndPoint() - pWPipe1->StartPoint();//默认靠近 end
if (dDis1 > dDis2)
{
vtMaj = pWPipe1->StartPoint() - pWPipe1->EndPoint();//靠近 sta
npos1 = 0;
}
vtMaj.normalize();
vtMaj.negate();
dDis1 = ptMid.distanceTo(pWPipe2->EndPoint());
dDis2 = ptMid.distanceTo(pWPipe2->StartPoint());
vtMin = pWPipe2->EndPoint() - pWPipe2->StartPoint();//默认靠近 end
if (dDis1 > dDis2)
{
vtMin = pWPipe2->StartPoint() - pWPipe2->EndPoint();//靠近 sta
npos2 = 0;
}
vtMin.normalize();
vtMin.negate();
//if ( fabs(param1.dSize[0] - param2.dSize[0]) < 1.e-3)
{
//创建弯头,是插入到当前管子的接口记录的前面
AcDbObjectId id = CreateElbow(vtMaj,ptMid,vtMin,&param1,&param2,TRUE);
//获取万头接口,改变边的管子
AcDbEntity* pEnt3 = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt3,id,AcDb::kForRead))
{
AecDbHvacFitting* pFit = AecDbHvacFitting::cast(pEnt3);
if (pFit != NULL)
{
AecInterface inf1,inf2;
pFit->GetInterface(0,inf1);
pFit->GetInterface(1,inf2);
AcGeVector3d vtPipe = pWPipe1->EndPoint() - pWPipe1->StartPoint();
if (vtPipe.isParallelTo(inf1.vtDir))
{
if (npos1 == 0)//改sta
pWPipe1->SetStartPoint(inf1.ptPos);
else
pWPipe1->SetEndPoint(inf1.ptPos);
if (npos2 == 0)
pWPipe2->SetStartPoint(inf2.ptPos);
else
pWPipe2->SetEndPoint(inf2.ptPos);
}
else
{
if (npos1 == 0)//改sta
pWPipe1->SetStartPoint(inf2.ptPos);
else
pWPipe1->SetEndPoint(inf2.ptPos);
if (npos2 == 0)
pWPipe2->SetStartPoint(inf1.ptPos);
else
pWPipe2->SetEndPoint(inf1.ptPos);
}
}
pEnt3->close();
}
}
bSuccess = TRUE;
}
pEnt2->close();
}
pEnt1->close();
}
return bSuccess;
}
BOOL AecDbDuctLine::ChangeElbowToTree(AecDbHvacFitting* pDbFit,AcGeVector3d vtMaj,AcGePoint3d ptGeM,AcGeVector3d vtMin,double dDn,AECStatusRecord* pCurRec)
{
//查询 Tee 数据
AecHvac::DuctParam param;
memset(&param,0,sizeof(AecHvac::DuctParam));
pDbFit->GetDuctParam(param);
double dL = 0.0,dS = 0.0;
dL = GetElbowL(&param);
dS = dL;
double dLx = GetElbowLx(&param);
AecInterface intf1,intf2;
pDbFit->GetInterface(0,intf1);
pDbFit->GetInterface(1,intf2);
vtMaj.normalize();
vtMin.normalize();
//创建三通
if (m_pPipeParam != NULL)
{
memcpy(m_pPipeParam,&param,sizeof(AecHvac::DuctParam));
}
AecDbHvacFitting* pFitting = ImpNewTee(dL,ptGeM,dS,vtMaj,vtMin,m_pPipeParam);
AecDbObjXDataMap* pXDataMap = pFitting->GetSpecialtyData();
//设置图层
AcDbObjectId idLay = pDbFit->layerId();
pFitting->setLayer(idLay);
//可能的几种修改,更改弯头两头的管子的位置
AcGePoint3d ptGe;
if (intf1.vtDir.isParallelTo(vtMin))
{
ptGe = ptGeM + dS * vtMin;
ModifyPipeOfElbow(GetConnectObject(intf1, m_arHistoryIntfs),intf1.ptPos,ptGe);
}
if (intf2.vtDir.isParallelTo(vtMin))
{
ptGe = ptGeM + dS * vtMin;
ModifyPipeOfElbow(GetConnectObject(intf2, m_arHistoryIntfs),intf2.ptPos,ptGe);
}
if (intf1.vtDir.isParallelTo(vtMaj))
{
ptGe = ptGeM - dL * vtMaj;
ModifyPipeOfElbow(GetConnectObject(intf1, m_arHistoryIntfs),intf1.ptPos,ptGe);
}
if (intf2.vtDir.isParallelTo(vtMaj))
{
ptGe = ptGeM - dL * vtMaj;//反向
ModifyPipeOfElbow(GetConnectObject(intf2, m_arHistoryIntfs),intf2.ptPos,ptGe);
}
//替换pdbfit
pDbFit->erase();
AcDbObjectId id = CoreTools::AddToModelSpace(pFitting);
AddUserData(id,pXDataMap,2);
//
AECStatusRecord* pRecMid = new AECStatusRecord;
pRecMid->CopyFrom(pCurRec);
ptGe = ptGeM + vtMaj * dL;
pRecMid->SetAcquirePoint(ptGe);
m_pPipeJig->PushBackStatusRec(pRecMid);
return TRUE;
}
BOOL AecDbDuctLine::ChangeTeeToCross(AecDbHvacFitting* pDbFit,AcGeVector3d& vtMaj,AcGeVector3d& vtMin,AECStatusRecord* pCurRec)
{
AecHvac::DuctParam param;
memset(&param,0,sizeof(AecHvac::DuctParam));
pDbFit->GetDuctParam(param);
double dL = 0.0,dB = 0.0;
dL = GetElbowL(&param);
dB = dL;
double dLx = GetElbowLx(&param);
AecDbObjXDataMap* pXDataMap = pDbFit->GetSpecialtyData();
AcGePoint3d ptMid;
pXDataMap->GetAt(KEY_MID,ptMid);
AcGePoint3d ptStart,ptEnd,ptBra1,ptBra2;
AcGeVector3d vtStart,vtEnd,vtBra1,vtBra2;
vtMin.normalize();
vtMaj.normalize();
vtStart = vtMaj;
vtStart.negate();
vtEnd = vtMaj;
vtBra1 = vtMin;
vtBra1.negate();
vtBra2 = vtMin;
ptStart = ptMid + vtStart * dL;
ptEnd = ptMid + vtEnd * dL;
ptBra1 = ptMid + vtBra1 * dB;
ptBra2 = ptMid + vtBra2 * dB;
ImpNewCross(pDbFit,ptMid,vtStart,ptStart,vtEnd,ptEnd,vtBra1,ptBra1,vtBra2,ptBra2,&param,&param);
vtMin.normalize();
AcGePoint3d ptGe = ptMid - vtMin * dB;
AECStatusRecord* pRecMid = new AECStatusRecord;
pRecMid->CopyFrom(pCurRec);
pRecMid->SetAcquirePoint(ptGe);
m_pPipeJig->PushBackStatusRec(pRecMid);
return TRUE;
}
void AecDbDuctLine::ModifyPipeOfElbow(AcDbObjectId id,AcGePoint3d ptOld,AcGePoint3d ptNew)
{
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite))
{
AecDbHvacDuct* pPipe = AecDbHvacDuct::cast(pEnt);
if (pPipe != NULL)
{
AcGePoint3d ptGeT;
AcGeVector3d vtPipe = pPipe->EndPoint() - pPipe->StartPoint();
if ( pPipe->EndPoint().distanceTo(ptOld) < 1.e-3)
{
ptGeT = pPipe->EndPoint();
pPipe->SetEndPoint(ptNew);
}
if (pPipe->StartPoint().distanceTo(ptOld) < 1.e-3)
{
ptGeT = pPipe->StartPoint();
pPipe->SetStartPoint(ptNew);
}
}
pEnt->close();
}
}
double AecDbDuctLine::PixelToWcs(int nPixel)
{
ads_point ptScreenSize;
double nViewSize;
struct resbuf rb1,rb2;
acedGetVar(_T("ScreenSize"), &rb1);
acedGetVar(_T("ViewSize"), &rb2);
nViewSize = rb2.resval.rreal;
ads_point_set(rb1.resval.rpoint,ptScreenSize);
if (ptScreenSize[1] < 1.0E-6 || nViewSize < 1.0E-6)
return 0.0;
double hight = (nViewSize / ptScreenSize[Y]) * nPixel;
return hight;
}
void AecDbDuctLine::AddUserData(AcDbObjectId id,AecDbObjXDataMap* pXDataMap,int nType)
{
// 增加参数 [10/24/2016 Rex]
if(g_pMapData != NULL && !id.isNull())
{
AecDbObjXDataMap* pXTempDataMap = new AecDbObjXDataMap();
CMapStringToString mapData;
if(pXTempDataMap->Read(id,_T("BIMEQUIP"),TRUE))
{
//用户数据USER0~999
CString sKey,sVal;
for (int i = 0;i < MAX_BIM_DATA_LEN;i++)
{
sKey.Format(_T("user%d"),i) ;
if (pXDataMap->GetAt(sKey,sVal))
{
mapData.SetAt(sKey,sVal);
}
else
{
break;
}
}
}
mapData.RemoveAll();
CString sKey;
CString sVal;
for (POSITION ps = g_pMapData->GetStartPosition();ps != NULL;)
{
g_pMapData->GetNextAssoc(ps,sKey,sVal);
mapData.SetAt(sKey,sVal);
}
for (int i = 0;i < MAX_BIM_DATA_LEN;i++)
{
sKey.Format(_T("user%d"),i) ;
pXTempDataMap->RemoveAt(sKey);
}
for (POSITION ps = mapData.GetStartPosition();ps != NULL;)
{
mapData.GetNextAssoc(ps,sKey,sVal);
if(sVal.Find(_T("物料描述")) != -1)
{
//nType == 0 Pipe,1 Elbow,2 Tee,3 Cross,4 Flange
CString szTempKey = _T("");
switch (nType)
{
case 1:
case 2:
case 3:
case 4:
case 5:
{
if(nType == 1)
szTempKey = _T("弯头");
else if(nType == 2)
szTempKey = _T("三通");
else if(nType == 3)
szTempKey = _T("四通");
else if(nType == 4)
szTempKey = _T("法兰");
else if(nType == 5)
szTempKey = _T("变径");
else
szTempKey = _T("");
CString szTemp;
szTemp = sVal;
int nIndex = szTemp.Find(_T("("));
if(nIndex >= 0)
{
szTemp = szTemp.Mid(nIndex);
szTempKey = _T("物料描述:") + szTempKey;
szTemp = szTempKey + szTemp;
sVal = szTemp;
}
}
break;
default:
break;
}
}
pXTempDataMap->SetAt(sKey,sVal);
}
//pXTempDataMap->SetAt(_T("user0"),_T("test:test"));
if(pXTempDataMap->Write(id,_T("BIMEQUIP"),TRUE))
{
DELETE_PTR(pXTempDataMap);
pXTempDataMap = NULL;
}
}
}