#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 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::iterator it; for (it = points2.begin(); it < points2.end(); it++) { points.append((*it).ptOn); } } static AcDbObjectId GetConnectObject(const AecInterface &intf, const CArray &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(¶mTmp,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(¶mTmp); double dL = GetElbowL(¶mTmp); //如果上段不是管子 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(¶m,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,¶m,¶m); 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,¶m,¶m); 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(¶mT,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,¶mT,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(¶mTmp,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(¶mTmp); double dX = GetElbowL(¶mTmp); 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(¶m,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,¶m,¶m); 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,¶m,¶m); 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 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::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(¶mB,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(¶mM,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,¶mM,¶mB,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,¶m1,¶m2,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(¶m,0,sizeof(AecHvac::DuctParam)); pDbFit->GetDuctParam(param); double dL = 0.0,dS = 0.0; dL = GetElbowL(¶m); dS = dL; double dLx = GetElbowLx(¶m); AecInterface intf1,intf2; pDbFit->GetInterface(0,intf1); pDbFit->GetInterface(1,intf2); vtMaj.normalize(); vtMin.normalize(); //创建三通 if (m_pPipeParam != NULL) { memcpy(m_pPipeParam,¶m,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(¶m,0,sizeof(AecHvac::DuctParam)); pDbFit->GetDuctParam(param); double dL = 0.0,dB = 0.0; dL = GetElbowL(¶m); dB = dL; double dLx = GetElbowLx(¶m); 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,¶m,¶m); 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; } } }