#include "StdAfx.h" #include "StdArx.h" #include "AecDbDuctJig.h" #include "HFitingStyleDlg.h" #include "KTCadUtility.h" #include "HFitingStyleDlg.h" #include "AecDbDuctLine.h" #include "KTCADSysVar.h" #include "KTCADUtilityEx.h" #include "FGBZDlg.h" #include "KTTempTol.h" #include "KTSetting.h" #include #include "CoreTools.h" #include "AecDbEwPipeDim.h" #include "AecDbEwEquipment.h" #include "AecDbX3dPartEntity.h" #include "AecInfCmdGrip.h" #include "GJXGDlg.h" #include "FITLockedDlg.h" #include "AecPipeLineModify.h" #include "HVACFittingToolkit.h" #include "AecDb3dRoadAxisLine.h" #include "CHFZDDlg.h" #define DXF_PIPE _T("AEC_DBDUCT") #define gLayer_Pipe_Dim _T("LAY_PP3D_DIM") #define gTextStyle_Pipe_Dim _T("Pipe_Dim") #define DXF_PIPE_ONLY _T("AEC_DBDUCT") #ifndef DXF_EQUI #define DXF_EQUI _T("AEC_DBWEQUIPMENT,AEC_DBPARAEQUI") #endif extern bool DLLIMPEXP PickGripMessage(GripMessage& msg); extern void DLLIMPEXP PushGripMessage(GripMessage&); DLLIMPEXP bool GetDoubleClickEnt(LPCTSTR pszCmd,AcDbObjectId& id); extern double GetElbowL(AecHvac::DuctParam* pParam); extern double GetElbowLx(AecHvac::DuctParam* pParam); extern AcGePoint2d GetTeeBL(AecHvac::DuctParam* pParamM,AecHvac::DuctParam* pParamB,const AcGeVector3d& vtStart,const AcGeVector3d& vtBranch,AecHvac::HvacTeeType eTeeType); extern void SortPoints(AcGePoint3dArray& points,AcDbCurve* pLine); extern double MayAsMUnit(double dVal); static AcGePoint3d MidPoint(AcGePoint3d& pt1, AcGePoint3d& pt2) { return AcGePoint3d((pt1.x + pt2.x) / 2.0, (pt1.y + pt2.y) / 2.0, (pt1.z + pt2.z) / 2.0); } void HA_TEST() { //测试函数 //CAcModuleResourceOverride myResources; //CHFitingStyleDlg dlg(2); //dlg.DoModal(); ads_point pt; ads_name ent; int nRes = acedEntSel(_T("\nPick ent:"),ent,pt); if (nRes == RTNORM) { struct resbuf * pRb = acdbEntGet(ent); if (pRb != NULL) { struct resbuf * pTmp = pRb; while(pTmp != NULL) { int nType = pTmp->restype; pTmp = pTmp->rbnext; } acutRelRb(pRb); } } } void HA_HZFGCmdFnc() { AecDbDuctJig jig; jig.DoIt(WPipe::eDuct); CoreTools::refreshGraphics(); } bool GetSamplePoints(AcDbCurve *pCurve, int nDivSegs, AcGePoint3dArray &arPts) { if (pCurve == NULL) return FALSE; double dS = 0, dE = 0; pCurve->getStartParam(dS); pCurve->getEndParam(dE); double dStep = (dE - dS) / nDivSegs; AcGePoint3d pt; for (int i = 0; i <= nDivSegs; i++) { if (Acad::eOk == pCurve->getPointAtParam(dS, pt)) { arPts.append(pt); } dS += dStep; } return true; } void HA_LJFGCmdFnc() { //选择路径 ads_name ent1; struct resbuf *pRb = acutBuildList(RTDXF0, _T("LINE,AEC_ROADAXISLINE,LWPOLYLINE,POLYLINE"), 0); int nRes = CKTCadUtility::SelectEntity(_T("\n选择路径(直线,路径线,多义线):"), ent1, pRb);//圆弧待定 if (nRes == RTNORM) { AcDbObjectId id; acdbGetObjectId(id, ent1); AcGePoint3d pt; AcGePoint3dArray arPts; bool bHasFit = true; AcDbEntity *pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead)) { AcDbLine *pLn = AcDbLine::cast(pEnt); if (pLn != NULL) { arPts.append(pLn->startPoint()); arPts.append(pLn->endPoint()); } AcDbPolyline *pPl = AcDbPolyline::cast(pEnt); if (pPl != NULL) { if (pPl->hasBulges()) { pEnt->close(); acutPrintf(_T("\n选择的PLINE线不可以有圆弧!")); return; } for (int i = 0; i < pPl->numVerts(); i++) { pPl->getPointAt(i, pt); arPts.append(pt); } } AcDb3dPolyline *pPl3d = AcDb3dPolyline::cast(pEnt); if (pPl3d != NULL) { AcGePoint3dArray arPts; AcDbEntity *pVEnt = NULL; AcDbObjectIterator *pIt = pPl3d->vertexIterator(); for (pIt->start(); !pIt->done(); pIt->step()) { pVEnt = pIt->entity(); AcDb3dPolylineVertex *pVtex = AcDb3dPolylineVertex::cast(pVEnt); if (pVtex != NULL) { arPts.append(pVtex->position()); } } } AecDb3dRoadAxisLine *pRoad = AecDb3dRoadAxisLine::cast(pEnt); if (pRoad != NULL) { pRoad->GetReferLineSegPoints(arPts, false); } AcDbArc *pArc = AcDbArc::cast(pEnt); if (pArc != NULL) { AcDbArc *pArc = AcDbArc::cast(pEnt); if (pArc != NULL) { double dLen = (pArc->endAngle() - pArc->startAngle()) * pArc->radius(); CAcModuleResourceOverride myResources; CHFZDDlg dlg; dlg.SetLen(dLen); nRes = dlg.DoModal(); if (nRes == IDOK) { bHasFit = false; GetSamplePoints(pArc, dlg.GetSegCount(), arPts); if (dlg.m_bEraseArc) { pEnt->upgradeOpen(); pEnt->erase(); pEnt->downgradeOpen(); } } } } pEnt->close(); } AecDbDuctJig jig; jig.DoItOnPath(WPipe::eDuct, arPts, bHasFit); } } void HA_FGBRCmdFnc() { //在管子上选择起始位置 ads_name ent1; struct resbuf *pRb = acutBuildList(RTDXF0, DXF_PIPE_ONLY, 0); int nRes = CKTCadUtility::SelectEntity(_T("\n请选择要加U型避让的风管:"), ent1, pRb); acutRelRb(pRb); if (nRes == RTNORM) { AcDbObjectId id1; acdbGetObjectId(id1, ent1); ads_point pt1, pt2; AcGePoint3d ptGe[4], ptT; bool bSet = false; AcGeVector3d vtPipe; AecHvac::DuctParam param; memset(¶m, 0, sizeof(AecHvac::DuctParam)); nRes = acedGetPoint(NULL, _T("\n在风管上选择U型避让的起点:"), pt1); if (nRes == RTNORM) { nRes = acedGetPoint(pt1, _T("\n在风管上选择U型避让的终点:"), pt2); if (nRes == RTNORM) { ads_point pt11, pt22; acdbUcs2Wcs(pt1, pt11, false); acdbUcs2Wcs(pt2, pt22, false); AcDbEntity *pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id1, AcDb::kForRead)) { AecDbHvacDuct *pPipe = AecDbHvacDuct::cast(pEnt); if (pPipe != NULL) { pPipe->GetDuctParam(param); pPipe->getClosestPointTo(asPnt3d(pt11), ptGe[1]); pPipe->getClosestPointTo(asPnt3d(pt22), ptGe[2]); ptGe[0] = pPipe->StartPoint(); ptGe[3] = pPipe->EndPoint(); AcGeVector3d vt1 = ptGe[3] - ptGe[0]; vt1.normalize(); vtPipe = vt1; AcGeVector3d vt2 = ptGe[2] - ptGe[1]; vt2.normalize(); if (vt1.dotProduct(vt2) < 0)//方向相反 { ptT = ptGe[1]; ptGe[1] = ptGe[2]; ptGe[2] = ptT; } bSet = true; } pEnt->close(); } } } if (bSet) { AcGePoint3d ptMid = MidPoint(ptGe[1], ptGe[2]); AcGeLine3d ln; ln.set(ptMid, vtPipe); bool bUpDw = false; //默认 AcGeVector3d vtDir = vtPipe.perpVector(); if (ln.isParallelTo(AcGePlane::kXYPlane)) { vtDir = AcGeVector3d::kZAxis; bUpDw = true; } else { if (vtPipe.isParallelTo(AcGeVector3d::kZAxis)) vtDir = AcGeVector3d::kXAxis; } ads_point ptm, ptmm; acdbWcs2Ucs(asDblArray(ptMid), ptm, false); TCHAR szTip[256]; _tcscpy(szTip, _T("\n请拾取一点指定避让方向:")); if (bUpDw) { //风管一般不考虑上下避让,容易引起风阻,请用乙字弯代替 //acedInitGet(RSG_OTHER, _T("U D")); //_tcscpy(szTip, _T("\n请拾取一点指定避让方向[向上(U)/向下(D):")); } nRes = acedGetPoint(ptm, szTip, ptm); if (nRes == RTNORM) { acdbUcs2Wcs(ptm, ptmm, false); AcGeVector3d vt = asPnt3d(ptmm) - ptMid; vtDir = vt.orthoProject(vtPipe); vtDir.normalize(); if (vtDir.isZeroLength()) { acutPrintf(_T("\n当前避让方向零长度,方向无效!")); return; } } else if (nRes == RTKWORD) { TCHAR szKey[3]; acedGetInput(szKey); if (_tcsicmp(_T("U"), szKey) == 0) { vtDir = AcGeVector3d::kZAxis; } else if (_tcsicmp(_T("D"), szKey) == 0) { vtDir = -AcGeVector3d::kZAxis; } } else { return; } //空间间距 nRes = RTNORM; if (nRes == RTNORM) { double dSpace = 0; nRes = acedGetReal(_T("\n请输入避让以管线中心为基准的空间间距<3000>:"), &dSpace); if (nRes == RTNONE) { dSpace = 1000.0; } else if (nRes == RTCAN) { return; } vtDir *= dSpace; AcGePoint3dArray arPts; arPts.append(ptGe[0]); arPts.append(ptGe[1]); ptGe[1] += vtDir; arPts.append(ptGe[1]); ptGe[2] += vtDir; arPts.append(ptGe[2]); ptGe[2] -= vtDir; arPts.append(ptGe[2]); arPts.append(ptGe[3]); //设置回退记录 SHacedCommand(RTSTR, _T("_undo"), RTSTR, _T("BE"), RTNONE); AcDbEntity *pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id1, AcDb::kForWrite)) { pEnt->erase(); pEnt->close(); } AecDbDuctJig jig(param); jig.DoItOnPath(WPipe::eDuct, arPts, true,false); CoreTools::refreshGraphics(); SHacedCommand(RTSTR, _T("_undo"), RTSTR, _T("E"), RTNONE); } } } } void HA_ductaddCmdFnc() { GripMessage msg; PickGripMessage(msg); if (msg.nType >= eCommand0 && msg.nType <= eCommand20) { AcDbObjectId id = msg.idHost; AcDbEntity* pEnt = NULL; if (Acad::eOk == acdbOpenObject(pEnt, id, AcDb::kForWrite)) { CString sLayer = pEnt->layer(); AecDbHvacDuct* pPipe = AecDbHvacDuct::cast(pEnt); if (pPipe != NULL) //管子拉伸命令 { AecInterface intf; pPipe->AecMInterfaces::GetInterface(msg.ptGrip, intf); if (!pPipe->AecMInterfaces::HasInterface(msg.ptGrip, intf.vtDir)) { //是中间夹点 AcGeVector3d vtDir = pPipe->EndPoint() - pPipe->StartPoint(); //vtDir.rotateBy(PI / 2.0, pPipe->normal()); //? Z vtDir.rotateBy(PI / 2.0, AcGeVector3d::kZAxis); //? Z intf.vtDir = vtDir; intf.ptPos = msg.ptGrip; } //判断是否是管子sta点 AcGePoint3d ptSta = pPipe->StartPoint(); if (ptSta.distanceTo(intf.ptPos) < 1.e-1) { AcGeVector3d vtDir = intf.vtDir; vtDir.negate(); intf.vtDir = vtDir; } AecHvac::DuctParam param; memset(¶m, 0, sizeof(AecHvac::DuctParam)); pPipe->GetDuctParam(param); param.m_dEl = intf.ptPos.z; pEnt->close(); AecDbDuctJig jig; jig.DoIt(&intf, ¶m); return; } AecDbHvacFitting* pWFit = AecDbHvacFitting::cast(pEnt); if (pWFit != NULL) //管件拉伸命令 { AecInterface intf; pWFit->AecMInterfaces::GetInterface(msg.ptGrip, intf); AecHvac::DuctParam param; memset(¶m, 0, sizeof(AecHvac::DuctParam)); pWFit->GetDuctParam(param); param.dSize[0] = intf.dSize1; param.dSize[1] = intf.dSize2; param.m_dEl = intf.ptPos.z; if (intf.nSectType = eCircle) { param.dSize[1] = 0.0; param.eType = eCircle; } pEnt->close(); AecDbDuctJig jig; jig.DoIt(&intf, ¶m); return; } AecDbEwEquipment* pWEqu = AecDbEwEquipment::cast(pEnt); if (pWEqu != NULL) //设备元件拉伸命令 { AecInterface intf; pWEqu->AecMInterfaces::GetInterface(msg.ptGrip, intf); pEnt->close(); AecDbDuctJig jig; jig.DoIt(&intf, NULL); //需要选择管子的外径等规格 return; } AecDbX3dPartEntity* pXPart = AecDbX3dPartEntity::cast(pEnt); if (pXPart != NULL) { AecInterface intf; pXPart->AecMInterfaces::GetInterface(msg.ptGrip, intf); pEnt->close(); AecDbDuctJig jig; jig.DoIt(&intf, NULL); //需要选择管子的外径等规格 return; } //命令夹点拉伸命令 AecInfCmdGrip* pPt = AecInfCmdGrip::cast(pEnt); if (pPt != NULL) { AecInterface intf; pPt->GetInf(intf); AecDbDuctJig jig; jig.DoIt(&intf, NULL); //需要选择管子的外径等规格 return; } pEnt->close(); } } } void HA_TJ3TCmdFnc() { ads_name ent1, ent2; struct resbuf* pRb = acutBuildList(RTDXF0, DXF_PIPE, 0); int nRes = CKTCadUtility::SelectEntity(_T("\n选择主风管:"), ent1, pRb); if (nRes == RTNORM) { nRes = CKTCadUtility::SelectEntity(_T("\n选择支风管:"), ent2, pRb); acutRelRb(pRb); if (nRes == RTNORM) { AcDbObjectId id1; acdbGetObjectId(id1, ent1); AcDbObjectId id2; acdbGetObjectId(id2, ent2); AcDbEntity* pEnt1 = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt1, id1, AcDb::kForWrite)) { AecDbHvacDuct* pPipeMaj = AecDbHvacDuct::cast(pEnt1); if (pPipeMaj != NULL) { AcDbEntity* pEnt2 = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt2, id2, AcDb::kForWrite)) { AecDbHvacDuct* pPipeMin = AecDbHvacDuct::cast(pEnt2); if (pPipeMin != NULL) { AcGePoint3d pt1 = pPipeMaj->StartPoint(); AcGePoint3d pt2 = pPipeMaj->EndPoint(); AcGePoint3d pt3 = pPipeMin->StartPoint(); AcGePoint3d pt4 = pPipeMin->EndPoint(); AcGeLine3d ln1(pt1,pt2); AcGeLine3d ln2(pt3,pt4); KTTempTol tol(1.e-3); AcGePoint3d ptMid, ptTemp1, ptTemp2; Adesk::Boolean bInt = ln1.intersectWith(ln2, ptMid); if (bInt) //相交 { AecHvac::DuctParam param1; memset(¶m1,0,sizeof(AecHvac::DuctParam)); pPipeMaj->GetDuctParam(param1); AecHvac::DuctParam param2; memset(¶m2,0,sizeof(AecHvac::DuctParam)); pPipeMin->GetDuctParam(param2); AcGeVector3d vtMaj = pPipeMaj->EndPoint() - pPipeMaj->StartPoint(); AcGeVector3d vtMin = pPipeMin->EndPoint() - pPipeMin->StartPoint(); vtMaj.normalize(); vtMin.normalize(); CAcModuleResourceOverride myResources; CHFitingStyleDlg dlg(2,param1.eType); if (IDOK != dlg.DoModal() ) { pEnt1->close(); pEnt2->close(); return; } AecHvac::HvacTeeType eTeeType = AecHvac::eArcuateBranch; UINT nTeeCode = dlg.GetFitCode(); eTeeType = (AecHvac::HvacTeeType)nTeeCode; double dRatio = param2.m_dRatio; double dLx = GetElbowLx(¶m2); AcGePoint2d ptLS = GetTeeBL(¶m1,¶m2,vtMaj,vtMin,eTeeType); double dL = ptLS.x; double dS = ptLS.y; AecDbDuctJig jig; AecDbDuctLine pipeLine(&jig); pipeLine.SetPipeParam(¶m2);//支管 //也可能加弯头,ptMid的两头有一在管子外 ptTemp1 = ptMid + vtMaj * dL; ptTemp2 = ptMid - vtMaj * dL; AcGeLineSeg3d lineGe(pPipeMaj->StartPoint(), pPipeMaj->EndPoint()); BOOL bAddTee = TRUE; if (!lineGe.isOn(ptTemp1) || !lineGe.isOn(ptTemp2)) { //可以加不同的管径弯头 //if (fabs(param1.dSize[0] - param2.dSize[0]) < 1.e-3) // { pEnt1->close(); pEnt2->close(); bAddTee = FALSE; if (pipeLine.AddElbow(id1, ptMid, id2)) { } return; } } if (bAddTee) { int nPos = 1;//落在末端附近 double dDis1 = ptMid.distanceTo(pPipeMin->StartPoint()); double dDis2 = ptMid.distanceTo(pPipeMin->EndPoint()); if (dDis1 < dDis2) nPos = 0; //落在开始端 //对方断为两个管子 pipeLine.SplitWPipe(ptMid, dL, pPipeMaj); if (nPos == 1) vtMin.negate(); //改变this管子的位置 pEnt2->close(); AcGePoint3d ptGe = ptMid + dS * vtMin; pipeLine.ModifyWPipe(ptGe, id2, nPos); pipeLine.AddTee(pPipeMaj,dL, ptMid, dS, vtMin,eTeeType); pEnt1->close(); return; } } else { acutPrintf(_T("\n选择的两风管互相延长不相交,请确定中心在同一标高!")); } } pEnt2->close(); } } pEnt1->close(); } } } } //添加四通 void HA_TJ4TCmdFnc() { ads_name ent1, ent2; struct resbuf* pRb = acutBuildList(RTDXF0, DXF_PIPE, 0); int nRes = CKTCadUtility::SelectEntity(_T("\n选择风管1:"), ent1, pRb, NULL); if (nRes == RTNORM) { nRes = CKTCadUtility::SelectEntity(_T("\n选择风管2:"), ent2, pRb, NULL); acutRelRb(pRb); if (nRes == RTNORM) { AcDbObjectId id1; acdbGetObjectId(id1, ent1); AcDbObjectId id2; acdbGetObjectId(id2, ent2); AcDbEntity* pEnt1 = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt1, id1, AcDb::kForWrite)) { AecDbHvacDuct* pPipeMaj = AecDbHvacDuct::cast(pEnt1); if (pPipeMaj != NULL) { AcDbEntity* pEnt2 = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt2, id2, AcDb::kForWrite)) { AecDbHvacDuct* pPipeMin = AecDbHvacDuct::cast(pEnt2); if (pPipeMin != NULL) { AcGeLine3d ln1(pPipeMaj->StartPoint(), pPipeMaj->EndPoint()); AcGeLine3d ln2(pPipeMin->StartPoint(), pPipeMin->EndPoint()); AcGeVector3d vtMaj = pPipeMaj->EndPoint() - pPipeMaj->StartPoint(); AcGeVector3d vtMin = pPipeMin->EndPoint() - pPipeMin->StartPoint(); vtMaj.normalize(); vtMin.normalize(); AcGePoint3d ptMid, ptTemp1, ptTemp2; if (ln1.intersectWith(ln2, ptMid)) //相交 { AecHvac::DuctParam param1, param2; memset(¶m1,0,sizeof(AecHvac::DuctParam)); memset(¶m2,0,sizeof(AecHvac::DuctParam)); pPipeMaj->GetDuctParam(param1); pPipeMin->GetDuctParam(param2); CAcModuleResourceOverride myResources; CHFitingStyleDlg dlg(3,param1.eType); if (IDOK != dlg.DoModal() ) { pEnt1->close(); pEnt2->close(); return; } AecHvac::HvacCrossType eCrossType = AecHvac::eArcuateCross; UINT nCrossType = dlg.GetFitCode(); eCrossType = (AecHvac::HvacCrossType)nCrossType; //if (fabs(param1.dSize[0] - param2.dSize[0]) < 1.e-3) //==DN { AecDbDuctJig jig; AecDbDuctLine pipeLine(&jig); pipeLine.SetPipeParam(¶m1); pEnt1->close(); pEnt2->close(); pipeLine.AddCross(id1, ptMid, id2, eCrossType); return; } } else { acutPrintf(_T("\n选择的两风管互相延长不相交,请确定中心在同一标高!")); } } pEnt2->close(); } } pEnt1->close(); } } } } const double dDeviation = 1.e-6; namespace { AecDbEwEquipment *startForHvacValve(LPCTSTR objType , LPCTSTR objName , const int &nShape // 风管形状 , const double &dDN // nShape = 1,公称,nShape = 0,无效 , const double &dW // nShape = 0,风管长,nShape = 1,无效 , const double &dH // nShape = 0,风管宽,nShape = 1,无效 , const double &dFlT // 法兰厚 , const double &dFlE // 法兰卷边 , bool &bHasFlange // 风管插入阀门带法兰 , const int &idx = 0) { typedef AcDbEntity *(_cdecl *func_startForHvacValve) (LPCTSTR , LPCTSTR , const int & , const double & , const double & , const double & , const double & , const double & , bool & , const int &); #ifndef ZWCAD HINSTANCE hmod = ::LoadLibrary(FilePath::GetArxDir() + _T("\\pool3dcmd.arx")); #else HINSTANCE hmod = ::LoadLibrary(FilePath::GetArxDir() + _T("\\pool3dcmd.zrx")); #endif if (!hmod) return NULL; func_startForHvacValve proc = (func_startForHvacValve)::GetProcAddress(hmod, "startForHvacValve"); if (!proc) { ::FreeLibrary(hmod); return NULL; } AcDbEntity *pEnt = proc(objType, objName, nShape, dDN, dW, dH , dFlT, dFlE, bHasFlange, idx); ::FreeLibrary(hmod); return (AecDbEwEquipment *)pEnt; } bool initParamHvacValveJsonData(LPCTSTR pszType) { return CoreTools::initParamValveJsonData(pszType, _T("Hvac"), _T("HVAC_VALVE")); } void insertHvacValve(LPCTSTR sType, AecEqui::ValveType eVlvType) { //选择风管 ads_name ent; struct resbuf *pRb = acutBuildList(RTDXF0, _T("AEC_DBDUCT"), 0); int nRes = CKTCadUtility::SelectEntity(_T("\n请选择要插入风阀的风管:"), ent, pRb); acutRelRb(pRb); if (nRes != RTNORM) return; ads_point adsPtSelect, adsPtDir; acedInitGet(RSG_OTHER, _T("M")); nRes = acedGetPoint(NULL, _T("\n请在风管上或在接口位置选择参考点[选择管嘴接合的风管或法兰或阀门之间挤入(M)]:"), adsPtSelect); if (nRes != RTNORM) { return; } nRes = acedGetPoint(adsPtSelect, _T("\n输入距离参考点的方向和距离<0.0>:"), adsPtDir); if (nRes != RTNORM) { return; } AecHvac::DuctParam param; ::memset(¶m, 0, sizeof(AecHvac::DuctParam)); OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbHvacDuct, pDuct) if (pDuct) { AcDbCurve *pCurve = pDuct->GetBaseCurve(); if (!pCurve) return; AcGePoint3d pt(asPnt3d(adsPtDir)); CoreTools::UCS2WCS(pt, pt); pCurve->getClosestPointTo(pt, pt); AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin); pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); DELETE_PTR(pCurve); pDuct->GetDuctParam(param); if (param.eType != eRect && param.eType != eCircle) return; bool bFlange(false); AecDbEwEquipment *pEqu = (AecDbEwEquipment *)startForHvacValve(sType , _T("插入暖通阀门") , param.eType == eRect ? 0 : 1 , param.dSize[0] , param.dSize[0] , param.dSize[1] , param.dSize[2] , param.m_dPlusEdge , bFlange); if (pEqu) { pEqu->GetSpecialtyData()->SetAt(KEY_SUBRUNTIME, eValve); pEqu->GetSpecialtyData()->SetAt(PIPE_VALVE, eVlvType); double dist = pEqu->getDistanceByInterface(0, 1); double dDis1 = pt.distanceTo(ptS); double dDis2 = pt.distanceTo(ptE); AcGeVector3d vtDir = ptE - ptS; vtDir.normalize(); AcGePoint3d ptTemp; AcGeVector3d vtDir1; double dL(.0); pEqu->GetSpecialtyData()->GetAt(_T("_param_dFL_"), dL); CString str2d; pEqu->GetSpecialtyData()->GetAt(_T("_hvac_valve_2d_"), str2d); double dDist = ptE.z - ptS.z; if (fabs(dDist) < dDeviation) { if (dDis1 < dDis2)//靠近sta { ptTemp = pt + dist * .5 * vtDir; vtDir1 = ptE - ptTemp; } else//靠近 end { ptTemp = pt - dist * .5 * vtDir; vtDir1 = ptTemp - ptS; } if (vtDir1.isCodirectionalTo(vtDir)) { pEqu->SetInsert(ptTemp, vtDir.normalize()); } CoreTools::AddToModelSpace(pEqu); } else { // 立管 if (dDis1 < dDis2)//靠近sta { ptTemp = pt + dist * .5 * vtDir; vtDir1 = ptE - ptTemp; } else//靠近 end { ptTemp = pt - dist * .5 * vtDir; vtDir1 = ptTemp - ptS; } if (vtDir1.isCodirectionalTo(vtDir)) { pEqu->SetInsert(ptTemp, vtDir.normalize()); } AcGeMatrix3d mat; mat.setToIdentity(); mat.setToRotation(PI * .5, AcGeVector3d::kXAxis, ptTemp); pEqu->transformBy(mat); CoreTools::AddToModelSpace(pEqu); } AecDbDuctJig jig; AecDbDuctLine pipeLine(&jig); pipeLine.SetPipeParam(¶m); pipeLine.SplitWPipe(ptTemp, dist * .5, pDuct); } } OPENOBJ_END() } bool SelectDirInsertEqu(LPCTSTR sType, LPCTSTR sName) { ads_point adsPt; if (acedGetPoint(NULL, _T("\n请选择插入点:"), adsPt) != RTNORM) return NULL; AcGePoint3d ptPos = asPnt3d(adsPt); CoreTools::UCS2WCS(ptPos, ptPos); CEquInsDirJig jig; jig.SetEqu(NULL, ptPos); if (jig.DoIt()) { AcGeVector3d vtDir = AcGeVector3d::kXAxis; vtDir.rotateBy(jig.m_dAngle, AcGeVector3d::kZAxis); bool bFlange(false); AecDbEwEquipment* pEqu = (AecDbEwEquipment*)startForHvacValve(sType, sName , 0, 0., 100., 100. , 5, 30, bFlange); if (pEqu) { pEqu->SetInsert(ptPos, vtDir.normalize()); CoreTools::AddToModelSpace(pEqu); } } else return false; return true; } void insertHvac_SEPt(LPCTSTR sType, LPCTSTR sName) { //选择风管 ads_name ent; ads_point adspt; struct resbuf* pRb = acutBuildList(RTDXF0, _T("AEC_DBDUCT"), 0); int nRes = CKTCadUtility::SelectEntity(_T("\n请选择要插入风管软连接的风管:"), ent, pRb, adspt); acutRelRb(pRb); if (nRes != RTNORM) return; AecHvac::DuctParam param; ::memset(¶m, 0, sizeof(AecHvac::DuctParam)); OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbHvacDuct, pDuct) if (pDuct) { AcDbCurve* pCurve = pDuct->GetBaseCurve(); if (!pCurve) return; AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin); pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); DELETE_PTR(pCurve); pDuct->GetDuctParam(param); AcGeVector3d vt, vtDir, Z(AcGeVector3d::kZAxis); vt = (ptS - ptE).normalize(); vtDir = vt; vtDir.rotateBy(PI / 2.0, Z); vtDir.normalize(); if (param.eType != eRect && param.eType != eCircle) return; bool bFlange(false); AecDbEwEquipment* pEqu = (AecDbEwEquipment*)startForHvacValve(sType , sName , param.eType == eRect ? 0 : 1 , param.dSize[0] , param.dSize[0] , param.dSize[1] , param.dSize[2] , param.m_dPlusEdge , bFlange); if (pEqu) { TCHAR keyWordP[131] = {}; acedInitGet(RSG_OTHER, _T("S E")); nRes = acedGetKword(_T("\n请选择插入点[起点(S)/终点(E)]<起点(S)>:"), keyWordP); if (nRes != RTNORM) return; if (_tcscmp(keyWordP, _T("S")) == 0) { pEqu->SetInsert(ptS, vt); } else if (_tcscmp(keyWordP, _T("E")) == 0) { pEqu->SetInsert(ptE, vt); } CoreTools::AddToModelSpace(pEqu); } } OPENOBJ_END() } void insertHvac_MidPt(LPCTSTR sType, LPCTSTR sName) { //选择风管 ads_name ent; ads_point adspt; struct resbuf* pRb = acutBuildList(RTDXF0, _T("AEC_DBDUCT"), 0); int nRes = CKTCadUtility::SelectEntity(_T("\n请选择要插入设备的风管:"), ent, pRb, adspt); acutRelRb(pRb); if (nRes != RTNORM) return; ads_point adsPtSelect, adsPtDir; acedInitGet(RSG_OTHER, _T("M")); nRes = acedGetPoint(NULL, _T("\n请在风管上或在接口位置选择参考点[选择管嘴接合的风管或法兰或阀门之间挤入(M)]:"), adsPtSelect); if (nRes != RTNORM) { return; } nRes = acedGetPoint(adsPtSelect, _T("\n输入距离参考点的方向和距离<0.0>:"), adsPtDir); if (nRes != RTNORM) { return; } AecHvac::DuctParam param; ::memset(¶m, 0, sizeof(AecHvac::DuctParam)); OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbHvacDuct, pDuct) if (pDuct) { AcDbCurve* pCurve = pDuct->GetBaseCurve(); if (!pCurve) return; AcGePoint3d pt(asPnt3d(adsPtDir)); CoreTools::UCS2WCS(pt, pt); pCurve->getClosestPointTo(pt, pt); AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin); pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); DELETE_PTR(pCurve); pDuct->GetDuctParam(param); if (param.eType != eRect && param.eType != eCircle) return; bool bFlange(false); AecDbEwEquipment* pEqu = (AecDbEwEquipment*)startForHvacValve(sType , sName , param.eType == eRect ? 0 : 1 , param.dSize[0] , param.dSize[0] , param.dSize[1] , param.dSize[2] , param.m_dPlusEdge , bFlange); if (pEqu) { double dL(.0); pEqu->GetSpecialtyData()->GetAt(_T("_param_dL_"), dL); double dist = pEqu->getDistanceByInterface(0, 1); double dDis1 = pt.distanceTo(ptS); double dDis2 = pt.distanceTo(ptE); AcGeVector3d vtDir = ptE - ptS; vtDir.normalize(); AcGePoint3d ptTemp; AcGeVector3d vtDir1; if (dDis1 < dDis2)//靠近sta { ptTemp = pt + dist * .5 * vtDir; vtDir1 = ptE - ptTemp; } else//靠近 end { ptTemp = pt - dist * .5 * vtDir; vtDir1 = ptTemp - ptS; } if (vtDir1.isCodirectionalTo(vtDir)) { pEqu->SetInsert(ptTemp, vtDir.normalize()); } CoreTools::AddToModelSpace(pEqu); AecDbDuctJig jig; AecDbDuctLine pipeLine(&jig); pipeLine.SetPipeParam(¶m); pipeLine.SplitWPipe(ptTemp, dL * .5, pDuct); } } OPENOBJ_END() } void insertHvac_SEPt_Surface(LPCTSTR sType, LPCTSTR sName) { //选择风管 ads_name ent; ads_point adsPt; struct resbuf* pRb = acutBuildList(RTDXF0, _T("AEC_DBDUCT"), 0); int nRes = CKTCadUtility::SelectEntity(_T("\n请选择要插入的暖通风管:"), ent, pRb, adsPt); acutRelRb(pRb); if (nRes != RTNORM) return; AecHvac::DuctParam param; ::memset(¶m, 0, sizeof(AecHvac::DuctParam)); OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbHvacDuct, pDuct) if (!pDuct) { return; } AcDbCurve* pCurve = pDuct->GetBaseCurve(); if (!pCurve) { pDuct->close(); return; } AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin); pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); pDuct->GetDuctParam(param); DELETE_PTR(pCurve); if (param.eType != eRect && param.eType != eCircle) { pDuct->close(); return; } AcGeVector3d vt, vtDir, Z(AcGeVector3d::kZAxis); vt = (ptS - ptE).normalize(); vtDir = vt; vtDir.rotateBy(PI / 2.0, Z); vtDir.normalize(); bool bFlange(false); AecDbEwEquipment* pEqu = (AecDbEwEquipment*)startForHvacValve(sType , sName , param.eType == eRect ? 0 : 1 , param.dSize[0] , param.dSize[0] , param.dSize[1] , param.dSize[2] , param.m_dPlusEdge , bFlange); if (!pEqu) { pDuct->close(); return; } if (param.eType == eRect) { ads_point adsPtSelect, adsPtDir; acedInitGet(RSG_OTHER, _T("M")); nRes = acedGetPoint(NULL, _T("\n请在风管上或在接口位置选择参考点[选择管嘴接合的风管或法兰或阀门之间挤入(M)]:"), adsPtSelect); if (nRes != RTNORM) { DELETE_PTR(pEqu); pDuct->close(); return; } nRes = acedGetPoint(adsPtSelect, _T("\n输入距离参考点的方向和距离<0.0>:"), adsPtDir); if (nRes != RTNORM) { DELETE_PTR(pEqu); pDuct->close(); return; } TCHAR keyWord[131] = {}; acedInitGet(RSG_OTHER, _T("T B")); nRes = acedGetKword(_T("\n请选择插入点所在平面[上表面(T)/下表面(B)]<上表面(T)>:"), keyWord); if (nRes != RTNORM) { DELETE_PTR(pEqu); pDuct->close(); return; } AcGePoint3d pt(asPnt3d(adsPtDir)), ptInsert; CoreTools::UCS2WCS(pt, pt); if (_tcscmp(keyWord, _T("T")) == 0) { ptInsert = pt + Z * param.dSize[1] * .5; } else { ptInsert = pt - Z * param.dSize[1] * .5; } pEqu->SetInsert(ptInsert, vt); CoreTools::AddToModelSpace(pEqu); } else { TCHAR keyWord[131] = {}; acedInitGet(RSG_OTHER, _T("S E")); nRes = acedGetKword(_T("\n请选择插入点[起点(S)/终点(E)]<起点(S)>:"), keyWord); if (nRes != RTNORM) { DELETE_PTR(pEqu); pDuct->close(); return; } if (_tcscmp(keyWord, _T("S")) == 0) { pEqu->SetInsert(ptS, vt); } else { pEqu->SetInsert(ptE, vt); } CoreTools::AddToModelSpace(pEqu); } pDuct->close(); OPENOBJ_END() return; } } // 暖通 调节阀 void HA_CTJF() { if (!initParamHvacValveJsonData(_T("暖通调节阀"))) { AfxMessageBox(_T("初始化数据失败!")); return; } insertHvacValve(_T("暖通调节阀"), AecEqui::eAdjustingVlv); } // 暖通 防火阀 void HA_CFHF() { if (!initParamHvacValveJsonData(_T("暖通防火阀"))) { AfxMessageBox(_T("初始化数据失败!")); return; } insertHvacValve(_T("暖通防火阀"), AecEqui::eGate); } // 暖通 止回阀 void HA_CZHF() { if (!initParamHvacValveJsonData(_T("暖通止回阀"))) { AfxMessageBox(_T("初始化数据失败!")); return; } insertHvacValve(_T("暖通止回阀"), AecEqui::eCheckVlv); } // 暖通 闸板阀 void HA_CZBF() { if (!initParamHvacValveJsonData(_T("暖通闸板阀"))) { AfxMessageBox(_T("初始化数据失败!")); return; } insertHvacValve(_T("暖通闸板阀"), AecEqui::eGate); } // 暖通 蝶阀 void HA_CDF() { if (!initParamHvacValveJsonData(_T("暖通蝶阀"))) { AfxMessageBox(_T("初始化数据失败!")); return; } insertHvacValve(_T("暖通蝶阀"),AecEqui::eButterflyVlv); } // 暖通 定风量阀 void HA_CDFLF() { if (!initParamHvacValveJsonData(_T("暖通定风量阀"))) { AfxMessageBox(_T("初始化数据失败!")); return; } insertHvacValve(_T("暖通定风量阀"), AecEqui::eVentVlv); } // 暖通 吸尘罩 void HA_CXCZ() { //选择风管 ads_name ent; ads_point adsPt; struct resbuf* pRb = acutBuildList(RTDXF0, _T("AEC_DBDUCT"), 0); int nRes = CKTCadUtility::SelectEntity(_T("\n请选择要插入暖通吸尘罩的风管:"), ent, pRb, adsPt); acutRelRb(pRb); if (nRes != RTNORM) return; AcDbObjectId id; acdbGetObjectId(id, ent); if (!id.isValid()) return; AcDbObjectPointer pDuct(id, AcDb::kForRead); if (pDuct.openStatus() != Acad::eOk) return; std::shared_ptr pCurve(pDuct->GetBaseCurve()); if (!pCurve) return; AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin); pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); AecHvac::DuctParam param; ::memset(¶m, 0, sizeof(AecHvac::DuctParam)); pDuct->GetDuctParam(param); if (param.eType != eRect && param.eType != eCircle) return; AcGeVector3d vt, vtDir, X(AcGeVector3d::kXAxis), Y(AcGeVector3d::kYAxis), Z(AcGeVector3d::kZAxis); vt = (ptS - ptE).normalize(); vtDir = vt; vtDir.rotateBy(PI / 2.0, Z); vtDir.normalize(); AcGePoint3d ptIns; AcGeVector3d vtIns; if (param.eType == eRect) { ads_point adsPtSelect, adsPtDir; acedInitGet(RSG_OTHER, _T("M")); nRes = acedGetPoint(NULL, _T("\n请在风管上或在接口位置选择参考点:"), adsPtSelect); if (nRes != RTNORM) return; nRes = acedGetPoint(adsPtSelect, _T("\n输入距离参考点的方向和距离<0.0>:"), adsPtDir); if (nRes != RTNORM) return; AcGePoint3d pt(asPnt3d(adsPtDir)); CoreTools::UCS2WCS(pt, pt); pCurve->getClosestPointTo(pt, pt); TCHAR keyWord[131] = {_T("T")}; acedInitGet(RSG_OTHER, _T("T B")); nRes = acedGetKword(_T("\n请选择插入点所在平面[上表面(T)/下表面(B)]<上表面(T)>:"), keyWord); if (nRes == RTCAN) return; double dDist = ptE.z - ptS.z; if (fabs(dDist) < dDeviation) { if (_tcscmp(keyWord, _T("B")) == 0) { ptIns = pt - Z * param.dSize[1] * .5; } else { ptIns = pt + Z * param.dSize[1] * .5; } vtIns = vt; } else { if (_tcscmp(keyWord, _T("B")) == 0) { ptIns = pt - X * param.dSize[0] * .5; } else { ptIns = pt + X * param.dSize[0] * .5; } vtIns = Y; } } else { TCHAR keyWord[131] = {_T("S")}; acedInitGet(RSG_OTHER, _T("S E")); nRes = acedGetKword(_T("\n请选择插入点[起点(S)/终点(E)]<起点(S)>:"), keyWord); if (nRes == RTCAN) return; vtIns = vt; if (_tcscmp(keyWord, _T("E")) == 0) { ptIns = ptE; } else { ptIns = ptS; } } bool bFlange(false); AecDbEwEquipment *pEqu(startForHvacValve(_T("XICHENZHAO") , _T("插入暖通吸尘罩") , param.eType == eRect ? 0 : 1 , param.dSize[0] , param.dSize[0] , param.dSize[1] , param.dSize[2] , param.m_dPlusEdge , bFlange)); if (!pEqu) return; pEqu->SetInsert(ptIns, vtIns); CoreTools::AddToModelSpace(pEqu); } // 暖通 风口 void HA_CFK() { //选择风管 ads_name ent; ads_point pt; struct resbuf* pRb = acutBuildList(RTDXF0, _T("AEC_DBDUCT"), 0); int nRes = CKTCadUtility::SelectEntity(_T("\n请选择要插入风口的风管:"), ent, pRb, pt); acutRelRb(pRb); if (nRes != RTNORM) { return; } AcDbObjectId id; acdbGetObjectId(id, ent); if (!id.isValid()) return; AcDbObjectPointer pDuct(id, AcDb::kForRead); if (pDuct.openStatus() != Acad::eOk) return; std::shared_ptr pCurve(pDuct->GetBaseCurve()); if (!pCurve) return; AecHvac::DuctParam param; ::memset(¶m, 0, sizeof(AecHvac::DuctParam)); pDuct->GetDuctParam(param); AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin); pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); AcGeVector3d vt, vtDir, X(AcGeVector3d::kXAxis), Y(AcGeVector3d::kYAxis), Z(AcGeVector3d::kZAxis); vt = (ptS - ptE).normalize(); vtDir = vt; vtDir.rotateBy(PI / 2.0, Z); vtDir.normalize(); AcGePoint3d ptIns; AcGeVector3d vtIns; if (param.eType == eRect) { TCHAR keyWordAP[131] = {_T("A")}; acedInitGet(RSG_OTHER, _T("A P")); nRes = acedGetKword(_T("\n请选择插入面/点[表面(A)/点(P)]<表面(A)>:"), keyWordAP); if (nRes == RTCAN) return; if (_tcscmp(keyWordAP, _T("P")) == 0) { TCHAR keyWordP[131] = {_T("S")}; acedInitGet(RSG_OTHER, _T("S E")); nRes = acedGetKword(_T("\n请选择插入点[起点(S)/终点(E)]<起点(S)>:"), keyWordP); if (nRes == RTCAN) return; vtIns = vt; if (_tcscmp(keyWordP, _T("E")) == 0) { ptIns = ptE; } else { ptIns = ptS; } } else { ads_point adsPtSelect, adsPtDir; acedInitGet(RSG_OTHER, _T("M")); nRes = acedGetPoint(NULL, _T("\n请在风管上或在接口位置选择参考点:"), adsPtSelect); if (nRes != RTNORM) return; nRes = acedGetPoint(adsPtSelect, _T("\n输入距离参考点的方向和距离<0.0>:"), adsPtDir); if (nRes != RTNORM) return; AcGePoint3d pt(asPnt3d(adsPtDir)); CoreTools::UCS2WCS(pt, pt); pCurve->getClosestPointTo(pt, pt); double dDist = ptE.z - ptS.z; if (fabs(dDist) < dDeviation) { TCHAR keyWordA[131] = {_T("D")}; acedInitGet(RSG_OTHER, _T("U D F B")); nRes = acedGetKword(_T("\n请选择插入面[上表面(U)/下表面(D)/前侧(F)/后侧(B)]<下表面(D)>:"), keyWordA); if (nRes == RTCAN) return; vtIns = vt; if (_tcscmp(keyWordA, _T("U")) == 0) { ptIns = pt + Z * param.dSize[1] * .5; } else if (_tcscmp(keyWordA, _T("F")) == 0) { ptIns = pt + vtDir * param.dSize[0] * .5; } else if (_tcscmp(keyWordA, _T("B")) == 0) { ptIns = pt - vtDir * param.dSize[0] * .5; } else { ptIns = pt - Z * param.dSize[1] * .5; } } else { TCHAR keyWordA[131] = {_T("L")}; acedInitGet(RSG_OTHER, _T("L R F B")); nRes = acedGetKword(_T("\n请选择插入面[左侧(L)/右侧(R)/前侧(F)/后侧(B)]<下表面(L)>:"), keyWordA); if (nRes == RTCAN) return; vtIns = Z; if (_tcscmp(keyWordA, _T("R")) == 0) { ptIns = pt + X * param.dSize[1] * .5; } else if (_tcscmp(keyWordA, _T("F")) == 0) { ptIns = pt - Y * param.dSize[0] * .5; } else if (_tcscmp(keyWordA, _T("B")) == 0) { ptIns = pt + Y * param.dSize[0] * .5; } else { ptIns = pt - X * param.dSize[1] * .5; } } } } else { TCHAR keyWord[131] = {_T("S")}; acedInitGet(RSG_OTHER, _T("S E")); nRes = acedGetKword(_T("\n请选择插入点[起点(S)/终点(E)]<起点(S)>:"), keyWord); if (nRes == RTCAN) return; vtIns = vt; if (_tcscmp(keyWord, _T("E")) == 0) { ptIns = ptE; } else { ptIns = ptS; } } bool bFlange(false); AecDbEwEquipment* pEqu = (AecDbEwEquipment*)startForHvacValve(_T("FENGKOU") , _T("插入暖通风口") , param.eType == eRect ? 0 : 1 , param.dSize[0] , param.dSize[0] , param.dSize[1] , param.dSize[2] , param.m_dPlusEdge , bFlange); if (!pEqu) return; pEqu->SetInsert(ptIns, vtIns); CoreTools::AddToModelSpace(pEqu); } // 暖通 风帽 void HA_CFM() { //选择风帽 ads_name ent; ads_point adsPt; struct resbuf* pRb = acutBuildList(RTDXF0, _T("AEC_DBDUCT"), 0); int nRes = CKTCadUtility::SelectEntity(_T("\n请选择要插入风帽的风管:"), ent, pRb, adsPt); acutRelRb(pRb); if (nRes != RTNORM) { return; } AcDbObjectId id; acdbGetObjectId(id, ent); AcDbObjectPointer pDuct(id, AcDb::kForRead); if (pDuct.openStatus() != Acad::eOk) return; std::shared_ptr pCurve(pDuct->GetBaseCurve()); if (!pCurve) return; AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin); pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); AecHvac::DuctParam param; ::memset(¶m, 0, sizeof(AecHvac::DuctParam)); pDuct->GetDuctParam(param); if (param.eType != eRect && param.eType != eCircle) return; AcGeVector3d vt, vtDir, X(AcGeVector3d::kXAxis), Y(AcGeVector3d::kYAxis), Z(AcGeVector3d::kZAxis); vt = (ptS - ptE).normalize(); vtDir = vt; vtDir.rotateBy(PI / 2.0, Z); vtDir.normalize(); AcGePoint3d ptIns; AcGeVector3d vtIns; if (param.eType == eRect) { ads_point adsPtSelect, adsPtDir; acedInitGet(RSG_OTHER, _T("M")); nRes = acedGetPoint(NULL, _T("\n请在风管上或在接口位置选择参考点:"), adsPtSelect); if (nRes != RTNORM) return; nRes = acedGetPoint(adsPtSelect, _T("\n输入距离参考点的方向和距离<0.0>:"), adsPtDir); if (nRes != RTNORM) return; AcGePoint3d pt(asPnt3d(adsPtDir)); CoreTools::UCS2WCS(pt, pt); pCurve->getClosestPointTo(pt, pt); TCHAR keyWord[131] = {}; acedInitGet(RSG_OTHER, _T("T B")); nRes = acedGetKword(_T("\n请选择插入点所在平面[上表面(T)/下表面(B)]<上表面(T)>:"), keyWord); if (nRes == RTCAN) return; double dDist = ptE.z - ptS.z; if (fabs(dDist) < dDeviation) { vtIns = vt; if (_tcscmp(keyWord, _T("B")) == 0) { ptIns = pt - Z * param.dSize[1] * .5; } else { ptIns = pt + Z * param.dSize[1] * .5; } } else { vtIns = Y; if (_tcscmp(keyWord, _T("B")) == 0) { ptIns = pt - X * param.dSize[0] * .5; } else { ptIns = pt + X * param.dSize[0] * .5; } } } else { TCHAR keyWord[131] = {}; acedInitGet(RSG_OTHER, _T("S E")); nRes = acedGetKword(_T("\n请选择插入点[起点(S)/终点(E)]<起点(S)>:"), keyWord); if (nRes == RTCAN) return; vtIns = vt; if (_tcscmp(keyWord, _T("B")) == 0) { ptIns = ptE; } else { ptIns = ptS; } } bool bFlange(false); AecDbEwEquipment* pEqu = (AecDbEwEquipment*)startForHvacValve(_T("FENGMAO") , _T("插入风帽") , param.eType == eRect ? 0 : 1 , param.dSize[0] , param.dSize[0] , param.dSize[1] , param.dSize[2] , param.m_dPlusEdge , bFlange); if (!pEqu) return; pEqu->SetInsert(ptIns, vtIns); CoreTools::AddToModelSpace(pEqu); } // 风机 void HA_CFJ() { SelectDirInsertEqu(_T("FENGJI"), _T("插入风机")); } // 水箱 void HA_CSX() { SelectDirInsertEqu(_T("SHUIXIANG"), _T("插入水箱")); } // 风管软连接 void HA_CFGRLJ() { insertHvac_SEPt(_T("FENGGUANRUANLIANJIE"), _T("插入风管软连接")); } // 风管消声器 void HA_CFGXSQ() { insertHvac_MidPt(_T("FENGGUANXIAOSHENGQI"), _T("插入风管消声器")); } // 能量表 void HA_CNLB() { insertHvac_MidPt(_T("NENGLIANGBIAO"), _T("插入能量表")); } // 删除阀门 void HA_DelFM() { ads_name ent; struct resbuf* pRb = acutBuildList(RTDXF0, DXF_EQUI, 0); int nRes = CKTCadUtility::SelectEntity(_T("\n选择要删除的设备:"), ent, pRb); acutRelRb(pRb); if (nRes != RTNORM) { return; } AcDbObjectId id; acdbGetObjectId(id, ent); AcDbEntity* pEnt = NULL; if (Acad::eOk != acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite)) { return; } AecDbEwEquipment* pEqu = AecDbEwEquipment::cast(pEnt); if (!pEqu) { return; } double dFL(.0); pEqu->GetSpecialtyData()->GetAt(_T("_param_dFL_"), dFL); pEqu->erase(); ads_name entFG; struct resbuf* pRbFG = acutBuildList(RTDXF0, _T("AEC_DBDUCT"), 0); nRes = CKTCadUtility::SelectEntity(_T("\n请选择要插入风阀的风管:"), entFG, pRbFG); acutRelRb(pRbFG); if (nRes != RTNORM) { return; } AecHvac::DuctParam param; ::memset(¶m, 0, sizeof(AecHvac::DuctParam)); OPENOBJ_BEGIN(entFG, AcDb::kForWrite, AecDbHvacDuct, pDuct) if (!pDuct) { return; } AcDbCurve* pCurve = pDuct->GetBaseCurve(); if (!pCurve) return; AcGePoint3d ptS, ptE, pt; pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); AcDbCurve* pCurveTest = (AcDbCurve*)pCurve->clone(); pCurveTest->setColorIndex(6); CoreTools::AddToModelSpace(pCurveTest); AcDbCircle* pCirS = new AcDbCircle(ptS, AcGeVector3d::kZAxis, 50); pCirS->setColorIndex(6); CoreTools::AddToModelSpace(pCirS); AcDbCircle* pCirE = new AcDbCircle(ptE, AcGeVector3d::kZAxis, 50); pCirE->setColorIndex(6); CoreTools::AddToModelSpace(pCirE); /*AcDbLine* pLine = AcDbLine::cast(pCurve); if (!pLine) { return; }*/ AcGeVector3d vt = (ptS - ptE).normalize(); pt = ptE - vt * dFL; pDuct->SetStartPoint(ptS); pDuct->SetEndPoint(pt); OPENOBJ_END() } // 报警阀 void HA_CBJF() { SelectDirInsertEqu(_T("BAOJINGFA"), _T("插入报警阀")); } //添加弯头 void HA_TJWTCmdFnc() { //选择管线末点加弯头 ads_name ent; ads_point pt; KTCADSysVar var(_T("orthomode"), 1); int nRes = acedEntSel(_T("\n选择风管末端添加弯头:"), ent, pt); if (nRes == RTNORM) { AcDbObjectId id; acdbGetObjectId(id, ent); AcDbEntity* pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite)) { AecDbHvacDuct* pPipe = AecDbHvacDuct::cast(pEnt); if (pPipe != NULL) { ads_point ptw; acdbUcs2Wcs(pt, ptw, false); AcGePoint3d ptGe = asPnt3d(ptw); double dDis1 = ptGe.distanceTo(pPipe->StartPoint()); double dDis2 = ptGe.distanceTo(pPipe->EndPoint()); AcGeVector3d vtMaj = pPipe->EndPoint() - pPipe->StartPoint(); AcGePoint3d ptFrom = pPipe->EndPoint(); if (dDis1 < dDis2) //靠近start { ptFrom = pPipe->StartPoint(); } else { vtMaj.negate(); } AecHvac::DuctParam param; memset(¶m,0,sizeof(AecHvac::DuctParam)); pPipe->GetDuctParam(param); vtMaj.normalize(); acdbWcs2Ucs(asDblArray(ptFrom), pt, false); ads_point ptRes; AcGePoint3d ptEnd, ptMid; AcGeVector3d vtMin; acedInitGet(RSG_OTHER, _T("U D")); nRes = acedGetPoint(pt, _T("\n选择弯头的出口方向或另外风管末端[向上(U)/向下(D)]:"), ptRes); if (nRes == RTNORM) { //判断是否落在其他管子上,且直径相同 ads_name ss, ent; ads_point pt1, pt2; ads_point_set(ptRes, pt1); ads_point_set(ptRes, pt2); pt1[X] -= CoreTools::PixelToWcs(10); pt1[Y] -= CoreTools::PixelToWcs(10); pt2[X] += CoreTools::PixelToWcs(10); pt2[Y] += CoreTools::PixelToWcs(10); TCHAR szBuf[17]; struct resbuf eb1; eb1.restype = 0; _tcscpy(szBuf, DXF_PIPE); eb1.resval.rstring = szBuf; eb1.rbnext = NULL; acedSSGet(_T("C"), pt1, pt2, &eb1, ss); Adesk::Int32 lLen = 0; acedSSLength(ss, &lLen); BOOL bHitPipeok = FALSE; if (lLen > 0) { acedSSName(ss, 0, ent); acedSSFree(ss); AcDbObjectId id2; acdbGetObjectId(id2, ent); AcDbEntity* pEnt2 = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt2, id2, AcDb::kForWrite)) { AecDbHvacDuct* pWPipe = AecDbHvacDuct::cast(pEnt2); if (pWPipe != NULL) { AecHvac::DuctParam param2; memset(¶m2,0,sizeof(AecHvac::DuctParam)); pWPipe->GetDuctParam(param2); //if ((int)param2.dSize[0] == (int)param.dSize[0]) { AcGeLine3d ln1(pPipe->StartPoint(), pPipe->EndPoint()); AcGeLine3d ln2(pWPipe->StartPoint(), pWPipe->EndPoint()); if (ln2.intersectWith(ln1, ptMid)) { //找距离ptmid最远的 int nDir1 = 1;// vtMaj = ptMid - pPipe->StartPoint(); double dDis1 = ptMid.distanceTo(pPipe->StartPoint()); double dDis2 = ptMid.distanceTo(pPipe->EndPoint()); if (dDis1 - dDis2 < 1.e-10)//距离end远,修改Start { vtMaj = ptMid - pPipe->EndPoint(); nDir1 = 0; } vtMaj.normalize(); vtMaj.negate(); //找距离ptmid最远的 int nDir2 = 1;// vtMin = ptMid - pWPipe->StartPoint(); dDis1 = ptMid.distanceTo(pWPipe->StartPoint()); dDis2 = ptMid.distanceTo(pWPipe->EndPoint()); if (dDis1 - dDis2 < 1.e-10)//距离end远,修改Start { vtMin = ptMid - pWPipe->EndPoint(); nDir2 = 0; } vtMin.normalize(); vtMin.negate(); AecDbDuctJig jig; AecDbDuctLine pipeline(&jig); pipeline.SetPipeParam(¶m); AcDbObjectId idElbow = pipeline.CreateElbow(vtMaj, ptMid, vtMin, ¶m,¶m2,TRUE); //延长两个管子 pPipe->upgradeOpen(); if (nDir1 == 0) pPipe->SetStartPoint(pipeline.m_intf0.ptPos); else pPipe->SetEndPoint(pipeline.m_intf0.ptPos); pPipe->downgradeOpen(); if (nDir2 == 0) pWPipe->SetStartPoint(pipeline.m_intf1.ptPos); else pWPipe->SetEndPoint(pipeline.m_intf1.ptPos); bHitPipeok = TRUE; pEnt->close(); pEnt2->close(); return; } } } pEnt2->close(); } } if (!bHitPipeok) { ads_point ptResw; acdbUcs2Wcs(ptRes, ptResw, false); ptEnd = asPnt3d(ptResw); vtMin = ptEnd - ptFrom; vtMin.normalize(); } } else if (nRes == RTKWORD) { TCHAR szKey[3]; acedGetInput(szKey); if (_tcsicmp(_T("U"), szKey) == 0) { vtMin = AcGeVector3d::kZAxis; } else if (_tcsicmp(_T("D"), szKey) == 0) { vtMin = -AcGeVector3d::kZAxis; } double dTmp = param.dSize[0]; param.dSize[0] = param.dSize[1]; param.dSize[1] = dTmp; } if (vtMin.isParallelTo(vtMaj)) { acutPrintf(_T("\n弯头的出口方向不能和主方向平行!")); pEnt->close(); return; } double dr = GetElbowL(¶m); AcGeVector3d vtToCen = vtMin.orthoProject(vtMaj); vtToCen.normalize(); AcGePoint3d ptCen = ptFrom + dr * vtToCen; double dAng = vtMin.angleTo(vtMaj);//0-180 double dDot = vtMin.dotProduct(vtMaj); if (dDot < -1.e-10 && dAng - PI / 2.0 < 1.e-10) { dAng = PI - dAng; } if (dAng - PI / 2.0 > 1.e-6) { acutPrintf(_T("弯头中心角度必须不大于90度")); pEnt->close(); return; } if (dAng - PI < 1.e-10) dAng = PI - dAng; double dCord = dr * cos((PI - dAng) / 2.0); AcGeVector3d vtCord = vtMaj + vtMin; vtCord.normalize(); ptMid = ptCen - vtCord * dCord; AcGeVector3d vtToM = ptMid - ptCen; vtToM.normalize(); ptMid = ptCen + dr / cos((PI - dAng) / 2.0) * vtToM; AecDbDuctJig jig; AecDbDuctLine pipeline(&jig); pipeline.SetPipeParam(¶m); pipeline.CreateElbow(vtMaj, ptMid, vtMin, ¶m,¶m,TRUE); } else { acutPrintf(_T("\n选择的实体不是管线!")); } pEnt->close(); } } } //弯头连接 void HA_WTLJCmdFnc() { //选择管线末点加弯头 ads_name ent1, ent2; struct resbuf* pRb = acutBuildList(RTDXF0, DXF_PIPE, 0); int nRes = CKTCadUtility::SelectEntity(_T("\n在风管末端选择风管1:"), ent1, pRb); if (nRes == RTNORM) { nRes = CKTCadUtility::SelectEntity(_T("\n在风管末端选择风管2:"), ent2, pRb); acutRelRb(pRb); if (nRes == RTNORM) { AcDbObjectId id1, id2; acdbGetObjectId(id1, ent1); acdbGetObjectId(id2, ent2); AcDbEntity* pEnt1 = NULL; AcDbEntity* pEnt2 = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt1, id1, AcDb::kForWrite)) { if (Acad::eOk == acdbOpenAcDbEntity(pEnt2, id2, AcDb::kForWrite)) { AecDbHvacDuct* pPipe1 = AecDbHvacDuct::cast(pEnt1); AecDbHvacDuct* pPipe2 = AecDbHvacDuct::cast(pEnt2); if (pPipe1 != NULL && pPipe2 != NULL) { AcGeVector3d vtDir1 = pPipe1->EndPoint() - pPipe1->StartPoint(); AcGeVector3d vtDir2 = pPipe2->EndPoint() - pPipe2->StartPoint(); if (vtDir1.isParallelTo(vtDir2)) { pEnt1->close(); pEnt2->close(); acutPrintf(_T("\n选择的两根桥架平行,不能加弯头连接!")); return; } AecHvac::DuctParam param1, param2; memset(¶m1,0,sizeof(AecHvac::DuctParam)); memset(¶m2,0,sizeof(AecHvac::DuctParam)); pPipe1->GetDuctParam(param1); pPipe2->GetDuctParam(param2); //判断点在位置 AcGeLine3d ln1(pPipe1->StartPoint(), pPipe1->EndPoint()); AcGeLine3d ln2(pPipe2->StartPoint(), pPipe2->EndPoint()); AcGePoint3d ptMid; if (ln1.intersectWith(ln2, ptMid) == Adesk::kTrue) { pEnt1->close(); pEnt2->close(); AecDbDuctJig jig; AecDbDuctLine pipeLine(&jig); pipeLine.SetPipeParam(¶m1); pipeLine.AddElbow(id1, ptMid, id2); return; } else { acutPrintf(_T("\n选择的两风管互相延长不相交,请确定中心在同一标高!")); } } pEnt2->close(); } pEnt1->close(); } } } } AcGePoint3d GetEndPtByOffAndAngle( AcGePoint3d ptStart, AcGeVector3d vtStart, double dWidth, AcGeVector3d vtOffSet, double dAngle, double dPluse, int nType ) { // 偏移向量有效化 vtOffSet = vtOffSet.orthoProject(vtStart); double dPerlDist = vtOffSet.length(); // 向下偏移的距离 AcGePoint3d ptEnd; double dHorizLen(0.0); // 水平偏移距离 if (1 == nType) // 双弧Angle:表示弯头角度 dHorizLen = dPerlDist / tan(dAngle * 0.5); // 水平偏移距离 else if (2 == nType) // 角接时,dAngle:表示倾斜角度 dHorizLen = dPerlDist / tan(dAngle); AcGePoint3d ptArcSta = ptStart - dPluse * vtStart; // 弧开始点 ptEnd = ptArcSta + vtOffSet - (dHorizLen + dPluse) * vtStart; return ptEnd; } // 斜接时算末点,dWidth较大端宽度 dAngle角度, dRatio:曲率, dOffSet:偏移。 AcGePoint3d GetInclineEndPt( AcGePoint3d ptStart, AcGeVector3d vtStart, double dWidth1, double dWidth2, AcGeVector3d vtOffSet, double dRatio, double dAngle, double dPluse ) { // 偏移向量有效化 vtOffSet = vtOffSet.orthoProject(vtStart); double dPerlDist = vtOffSet.length(); // 向下偏移的距离 double dRad1 = dWidth1 * dRatio; double dRad2 = dWidth2 * dRatio; double dDistToCor1 = dRad1 * tan(dAngle * 0.5); double dDistToCor2 = dRad2 * tan(dAngle * 0.5); double dIncHoriLen = dPerlDist / tan(dAngle); // 倾斜段管方向上距离 double dAllHoriLen = dIncHoriLen + dDistToCor1 + dDistToCor2 + dPluse * 2; // 管方向上总距离 AcGePoint3d ptEnd = ptStart - dAllHoriLen * vtStart; ptEnd += vtOffSet; return ptEnd; } AcGeVector3d GetUcsZvt() { AcGeVector3d vtZ = AcGeVector3d::kZAxis; AcDbDatabase* pDb = acdbCurDwg(); if (NULL != pDb) vtZ = pDb->ucsxdir().crossProduct(pDb->ucsydir()); return vtZ; } void AdjustDuctLine(const AcGePoint3d& ptCon1, const AcGePoint3d& ptCon2, AecDbHvacDuct* pDuct1) { AcGePoint3d ptSta1 = pDuct1->StartPoint(); AcGePoint3d ptEnd1 = pDuct1->EndPoint(); AcGeVector3d vtDir = ptEnd1 - ptSta1; AcGePoint3d ptMid = MidPoint(ptSta1, ptEnd1); AcGeVector3d vt1 = ptCon1 - ptMid; if (vt1.isParallelTo(vtDir)) //说明 ptCon1 落在 duct 上 { AcGeLine3d ln(ptSta1, ptEnd1); AcGePoint3d ptM2 = MidPoint((AcGePoint3d &)ptCon1, (AcGePoint3d &)ptCon2); ptM2 = ln.closestPointTo(ptM2); if (ptM2.distanceTo(ptSta1) < ptM2.distanceTo(ptEnd1))//ptCon1 距离ptSta1 最近 { pDuct1->SetStartPoint(ptCon1); } else { pDuct1->SetEndPoint(ptCon1); } return; } vt1 = ptCon2 - ptMid; if (vt1.isParallelTo(vtDir)) //说明 ptCon2 落在 duct 上 { AcGeLine3d ln(ptSta1, ptEnd1); AcGePoint3d ptM2 = MidPoint((AcGePoint3d &)ptCon1, (AcGePoint3d &)ptCon2); ptM2 = ln.closestPointTo(ptM2); if (ptM2.distanceTo(ptSta1) < ptM2.distanceTo(ptEnd1))//ptCon1 距离ptSta1 最近 { pDuct1->SetStartPoint(ptCon2); } else { pDuct1->SetEndPoint(ptCon2); } return; } } BOOL GetNewFit( AecDbHvacDuct* pDuct1, AecDbHvacDuct* pDuct2, ads_point pt1Click, AcDbVoidPtrArray &arrFit,CHFitingStyleDlg* pDlg ,AecDbHvacFitting* pOffset = NULL) { AecDbObjXDataMap* pData1 = pDuct1->GetSpecialtyData(AcDb::kForRead); AecDbObjXDataMap* pData2 = pDuct2->GetSpecialtyData(AcDb::kForRead); if (NULL == pData1 || NULL == pData2) return FALSE; CString csComtype; double dOffsetLength = 0.0, dOffsetWidth(0.0); double dAngle(45), dPluse = MayAsMUnit(50),dt = 0.0; double dRealPlusEdge = 0.0; AecHvac::HvacOffsetType eOffsetType = AecHvac::eArcuateLink; AecHvac::HvacOffsetComType eComType = AecHvac::eOffComRatio; //计算方法 if (NULL != pDlg) { CMapFitaram mapOffset; pDlg->GetFitParamMap(mapOffset); UINT nOffsetCode = pDlg->GetFitCode(); eOffsetType = (AecHvac::HvacOffsetType)nOffsetCode; SFitParam eParm; if (mapOffset.Lookup(OFFSET_COMTYPE, eParm)) csComtype = eParm.sDefault; if (csComtype == _T("曲率")) eComType = AecHvac::eOffComRatio; else if (csComtype == _T("偏移")) eComType = AecHvac::eOffComOffset; else if (csComtype == _T("长度")) eComType = AecHvac::eOffComLength; if (mapOffset.Lookup(OFFSET_LENGTH, eParm)) dOffsetLength = _ttof(eParm.sDefault); if (mapOffset.Lookup(OFFSET_ANGLE, eParm)) dAngle = _ttof(eParm.sDefault) * PI / 180; } AcGePoint3d ptSta1 = pDuct1->StartPoint(); AcGePoint3d ptEnd1 = pDuct1->EndPoint(); AcGePoint3d ptSta2 = pDuct2->StartPoint(); AcGePoint3d ptEnd2 = pDuct2->EndPoint(); // 获取原分管通用属性,用于乙子弯 BOOL bSingleLine(FALSE), bBaseLine(TRUE); double dStaWidth(0.0), dEndWidth(0.0), dThick(0.0); double dEdgeWidth(0.0), dCentWidth(0.0), dSideWidth(0.0); BOOL bEdgeWeight(FALSE), bCentWeight(FALSE); ESection eSect = eRect; CString csMatName; pData1->GetAt(HVAC_SectType, (int&)eSect); pData1->GetAt(HVAC_IsSingleLine, bSingleLine); pData1->GetAt(HVAC_Material, csMatName); pData1->GetAt(HVAC_EdgeWeight, bEdgeWeight); pData1->GetAt(HVAC_EdgeWidth, dEdgeWidth); pData1->GetAt(HVAC_CentWeight, bCentWeight); pData1->GetAt(HVAC_CentWidth, dCentWidth); pData1->GetAt(HVAC_EndWidth, dSideWidth); pData1->GetAt(HDCT_Width, dStaWidth); pData2->GetAt(HDCT_Width, dEndWidth); pData2->GetAt(HDCT_Thick, dThick); pData2->GetAt(PIPE_THICK,dt); CString csSysName; pData1->GetAt(HVAC_System, csSysName); AcDbObjectId idMainLayer = pDuct1->layerId(); AcDbObjectId idBaseLayer = pDuct1->GetCenterLayer(); AcDbObjectId idEndLayer; pData1->GetAt(HVAC_EndLayer, idEndLayer); AcDbObjectId idHideLayer = pDuct1->GetDashLayer(); AcGePoint3d ptptSta1Prj; pDuct2->getClosestPointTo(ptSta1, ptptSta1Prj, Adesk::kTrue); AcGeVector3d vt1To2 = ptptSta1Prj - ptSta1; AcGeVector3d vtNormal = pDuct1->GetNormal(); // 矩形管、在法向方向上偏移特殊情况下宽度、高度互换 if (eSect == eRect && vt1To2.isParallelTo(vtNormal)) { dThick = dStaWidth; pData1->GetAt(HDCT_Thick, dStaWidth); pData2->GetAt(HDCT_Thick, dEndWidth); } double dMaxWidth = dStaWidth > dEndWidth ? dStaWidth:dEndWidth; AcGePoint3d ptCon1, ptCon2; // 乙子弯连接点 AcGePoint3d ptOther1, ptOther2; // 管子另一非连接点 double dDistSta = acutDistance(pt1Click,asDblArray(ptSta1)); double dDistEnd = acutDistance(pt1Click,asDblArray(ptEnd1)); if (dDistSta > dDistEnd) { ptCon1 = ptEnd1; ptOther1 = ptSta1; } else { ptCon1 = ptSta1; ptOther1 = ptEnd1; } AcGeVector3d vtSta(ptOther1 - ptCon1); vtSta.normalize(); AcGeVector3d vtEnd = -vtSta; // 求偏移 AcGeLine3d line2(ptSta2, ptEnd2); AcGePoint3d ptRight = line2.closestPointTo(ptSta1); // 管1某点到管2的垂足点 AcGeVector3d vtOffSet = ptRight - ptSta1; dOffsetWidth = vtOffSet.length(); bool bIsAlone = false; AcDbVoidPtrArray arrFitting; if (eOffsetType == 1 || eOffsetType == 2) // 乙子弯实体 { if (eOffsetType == AecHvac::eArcuateLink && csComtype == _T("长度") && bIsAlone)// { dAngle = dAngle * 2; } // 求末点 ptCon2 = GetEndPtByOffAndAngle(ptCon1, vtSta, dMaxWidth, vtOffSet, dAngle, dPluse, eOffsetType); // 改变末端连接的管的首(尾)点位置, 底层原因,要放在添加管件前 AcGePoint3d ptNewDuct = ptCon2; // 取得数据参数容器,加入数据参数 AecDbObjXDataMap* pMapOffset = NULL; if (pOffset == NULL) // 新建乙子弯连接情况 { pOffset = new AecDbHvacFitting; pOffset->setLayer(idMainLayer); pOffset->SetDoubleLayer(idMainLayer); pOffset->SetDashLayer(idHideLayer); pOffset->SetCenterLayer(idBaseLayer); pMapOffset = pOffset->GetSpecialtyData(); if (NULL == pMapOffset) { delete pOffset; return FALSE; } pMapOffset->SetAt(KEY_FITSRV, KEY_FITHVAC); pMapOffset->SetAt(KEY_RUNTIME, eOffset); pMapOffset->SetAt(HVAC_System, csSysName); pMapOffset->SetAt(HVAC_Material, csMatName); pMapOffset->SetAt(HVAC_SectType, eSect); pMapOffset->SetAt(HVAC_PlusEdge, dPluse); pMapOffset->SetAt(HOFF_Thick, dThick); pMapOffset->SetAt(PIPE_THICK,dt); pMapOffset->SetAt(HOFF_StartWidth, dStaWidth); pMapOffset->SetAt(HOFF_EndWidth, dEndWidth); pMapOffset->SetAt(HVAC_IsSingleLine, bSingleLine); pMapOffset->SetAt(HVAC_HasBaseLine, bBaseLine); pMapOffset->SetAt(HVAC_EdgeWeight, bEdgeWeight); pMapOffset->SetAt(HVAC_EdgeWidth, dEdgeWidth); pMapOffset->SetAt(HVAC_CentWeight, bCentWeight); pMapOffset->SetAt(HVAC_CentWidth, dCentWidth); pMapOffset->SetAt(HVAC_EndWidth, dSideWidth); pMapOffset->SetAt(HVAC_EndLayer, idEndLayer, FALSE); pMapOffset->SetAt(HOFF_StartDir, vtSta); pMapOffset->SetAt(HOFF_EndDir, vtEnd); pMapOffset->SetAt(HOFF_Type, eOffsetType); pMapOffset->SetAt(HOFF_StartPoint, ptCon1); pMapOffset->SetAt(HOFF_EndPoint, ptCon2); pMapOffset->SetAt(HOFF_ComputeType, eComType); pMapOffset->SetAt(HOFF_Angle, dAngle); pMapOffset->SetAt(HOFF_VertDrawStyle, 1); pMapOffset->SetAt(HOFF_Length, dOffsetLength); pMapOffset->SetAt(HOFF_Offset, dOffsetWidth); arrFit.append(pOffset); AdjustDuctLine(ptCon1, ptCon2,pDuct1); AdjustDuctLine(ptCon1, ptCon2,pDuct2); } else// 替换情况 { pMapOffset = pOffset->GetSpecialtyData(AcDb::kForWrite); if (NULL != pMapOffset) { // 改变末端连接的管的首(尾)点位置, 更改法兰位置 /*AcGeVector3d vtDuct2End(ptEnd2 - ptSta2); if (vtDuct2End.angleTo(vtEnd) < 1e-3) { pDuct2->SetStartPoint(ptNewDuct); } else { pDuct2->SetEndPoint(ptNewDuct); }*/ AcGePoint3d ptOrigSta, ptOrigEnd; pMapOffset->GetAt(HOFF_StartPoint, ptOrigSta); pMapOffset->GetAt(HOFF_EndPoint, ptOrigEnd); pMapOffset->SetAt(HOFF_Type, eOffsetType); pMapOffset->SetAt(HVAC_SectType, eSect); pMapOffset->SetAt(HOFF_StartPoint, ptCon1); pMapOffset->SetAt(HOFF_EndPoint, ptCon2); pMapOffset->SetAt(HVAC_HasBaseLine, bBaseLine); AdjustDuctLine(ptCon1, ptCon2, pDuct1); AdjustDuctLine(ptCon1, ptCon2, pDuct2); } } } else if (eOffsetType == 3) // 斜接式,有管和弯头组成 { // 斜接式,如果有变径的话,变化端放在大端,否则尺寸不合适,导致绘制出错 double dStaEbwStaWidth(dStaWidth), dStaEbwEndWidth(dEndWidth); double dEndEbwStaWidth(dEndWidth), dEndEbwEndWidth(dEndWidth); if (dEndWidth > dStaWidth) { dStaEbwEndWidth = dStaWidth; dEndEbwEndWidth = dStaWidth; } // 确定中间段风管尺寸 double dNewDuctdWidth(0.0), dNewDuctdThick(0.0); if (eSect == eRect) { double dDtWidth1(0.0), dDtWidth2(0.0); double dDtThick1(0.0), dDtThick2(0.0); pData1->GetAt(HDCT_Width, dDtWidth1); pData1->GetAt(HDCT_Thick, dDtThick1); pData2->GetAt(HDCT_Width, dDtWidth2); pData2->GetAt(HDCT_Thick, dDtThick2); if (vt1To2.isParallelTo(vtNormal)) // 特殊情况,在法向方向上有偏移,要求宽度一致 { dNewDuctdThick = dDtThick1 < dDtThick2 ? dDtThick1:dDtThick2; // 取小厚度 dNewDuctdWidth = dDtWidth1; } else // 常规水平情况,要求厚度一致 { dNewDuctdWidth = dDtWidth1 < dDtWidth2 ? dDtWidth1:dDtWidth2; dNewDuctdThick = dDtThick1; } } double dRatio(1.0); // 曲率 CMapFitaram mapOffset; pDlg->GetFitParamMap(mapOffset); SFitParam eParm; if ( mapOffset.Lookup(OFFSET_RADRATIO, eParm)) dRatio = _ttof(eParm.sDefault); if (csComtype == _T("长度") && bIsAlone) { double dR1 = dStaWidth * dRatio; double dR2 = dEndWidth * dRatio; double dLength = 0.0; double dOffset = vtOffSet.length(); double dTanHalfAlpha = 0.0; if (mapOffset.Lookup(OFFSET_LENGTH, eParm)) dLength = _ttof(eParm.sDefault); dLength = dLength - 2 * dPluse; if (dLength < 1e-3) { acutPrintf(_T("\n长度参数太小,请输入至少输入100毫米!")); return FALSE; } if (fabs(2 * dR1 + 2 * dR2 - dOffset) < 1e-6 || (dLength * dLength + dOffset * dOffset - 2 * dOffset * dR1 - 2 * dOffset * dR2) < 0.0) { acutPrintf(_T("\n请调整乙字弯参数,现有参数无法实现斜接乙字弯的生成!")); return FALSE; } else { dTanHalfAlpha = (dLength - sqrt(dLength * dLength + dOffset * dOffset - 2 * dOffset * dR1 - 2 * dOffset * dR2)) / (2 * dR1 + 2 * dR2 - dOffset); } dAngle = 2 * atan(dTanHalfAlpha); } bBaseLine = FALSE; // 先判断是否能用该方式绘制,否则提示用户改用它方式 double dLimtsLen = (dMaxWidth * dRatio * (1 - cos(dAngle)) + dPluse*sin(dAngle)) * 2; if (vtOffSet.length() - dLimtsLen < 1e-3) { acutPrintf(_T("\n无法连接,请减小曲率或角度,或采用其他方式连接")); return FALSE; } // 求末点 ptCon2 = GetInclineEndPt(ptCon1, vtSta, dStaWidth, dEndWidth, vtOffSet, dRatio, dAngle, dPluse); AcGePoint3d ptNewDuct = ptCon2; double dRad = dStaWidth * dRatio; // 半径 double dDistToCor = dRad * tan(dAngle * 0.5); // corner点到起始点(末点)距离 // 改变末端连接的管的首(尾)点位置, 底层原因,要放在添加管件前 AcGeVector3d vtDuct2End(ptEnd2 - ptSta2); if (vtDuct2End.angleTo(vtEnd) < 1e-3) { pDuct2->SetStartPoint(ptNewDuct); } else { pDuct2->SetEndPoint(ptNewDuct); } // 起始端弯头 AcGePoint3d ptStaCorner, ptStaElbEnd; ptStaCorner = ptCon1 - (dPluse + dDistToCor) * vtSta; AcGeVector3d vtStaRot = vtSta.crossProduct(vtOffSet); AcGeVector3d vtStaEndToCor = -vtSta; // 起始端弯头末端到角点的向量 vtStaEndToCor.rotateBy(-dAngle, vtStaRot); ptStaElbEnd = ptStaCorner + (dDistToCor + dPluse) * vtStaEndToCor; AecDbHvacFitting* pElbow = new AecDbHvacFitting; pElbow->setLayer(idMainLayer); pElbow->SetDoubleLayer(idMainLayer); pElbow->SetCenterLayer(idBaseLayer); pElbow->SetDashLayer(idHideLayer); // 取得数据参数容器,加入数据参数 AecDbObjXDataMap* pMapElbow = pElbow->GetSpecialtyData(); pMapElbow->SetAt(KEY_FITSRV, KEY_FITHVAC); pMapElbow->SetAt(KEY_RUNTIME, eElbow); pMapElbow->SetAt(HVAC_System, csSysName); pMapElbow->SetAt(HVAC_Material, csMatName); pMapElbow->SetAt(HVAC_SectType, eSect); pMapElbow->SetAt(HVAC_PlusEdge, dPluse); pMapElbow->SetAt(HVAC_IsSingleLine, bSingleLine); pMapElbow->SetAt(HVAC_HasBaseLine, bBaseLine); pMapElbow->SetAt(HVAC_EdgeWeight, bEdgeWeight); pMapElbow->SetAt(HVAC_EdgeWidth, dEdgeWidth); pMapElbow->SetAt(HVAC_CentWeight, bCentWeight); pMapElbow->SetAt(HVAC_CentWidth, dCentWidth); pMapElbow->SetAt(HVAC_EndWidth, dSideWidth); pMapElbow->SetAt(HVAC_EndLayer, idEndLayer, FALSE); pMapElbow->SetAt(HELB_Type, AecHvac::eAllArcuate); pMapElbow->SetAt(HELB_StartPoint, ptCon1); pMapElbow->SetAt(HELB_EndPoint, ptStaElbEnd); pMapElbow->SetAt(HELB_CornerPoint, ptStaCorner); double dRadioStart = (ptCon1.distanceTo(ptStaCorner) / fabs(tan(dAngle * 0.5))) / dStaWidth; pMapElbow->SetAt(HELB_RadRatio, dRadioStart); pMapElbow->SetAt(HELB_AssisCornerPoint, ptStaCorner); pMapElbow->SetAt(HELB_StartWidth, dStaEbwStaWidth); pMapElbow->SetAt(HELB_EndWidth, dStaEbwEndWidth); pMapElbow->SetAt(HELB_Diameter, dStaEbwStaWidth); pMapElbow->SetAt(HELB_EndDiameter, dStaEbwEndWidth); pMapElbow->SetAt(HELB_Thick, dThick); pMapElbow->SetAt(HELB_VertDrawStyle, 1); pMapElbow->SetAt(HELB_EndThick, dThick); pMapElbow->SetAt(PIPE_THICK,dt); arrFit.append(pElbow); // 末端弯头 AecDbHvacFitting* pEndElbow = (AecDbHvacFitting*)pElbow->clone(); AcGePoint3d ptEndCorner, ptEndElbEnd; dRad = dEndWidth * dRatio; dDistToCor = dRad * tan(dAngle * 0.5); ptEndCorner = ptCon2 - (dPluse + dDistToCor) * vtEnd; AcGeVector3d vtEndRot = vtEnd.crossProduct(-vtOffSet); AcGeVector3d vtEndEndToCor = (-vtEnd).rotateBy(-dAngle, vtStaRot); ptEndElbEnd = ptEndCorner + (dDistToCor + dPluse) * vtEndEndToCor; // 取得数据参数容器,加入数据参数 pMapElbow = pEndElbow->GetSpecialtyData(); pMapElbow->SetAt(HELB_StartPoint, ptCon2); pMapElbow->SetAt(HELB_EndPoint, ptEndElbEnd); pMapElbow->SetAt(HELB_CornerPoint, ptEndCorner); double dRatioEnd = (ptCon2.distanceTo(ptEndCorner) / fabs(tan(dAngle * 0.5))) / dEndWidth; pMapElbow->SetAt(HELB_RadRatio, dRatioEnd); pMapElbow->SetAt(HELB_AssisCornerPoint, ptEndCorner); pMapElbow->SetAt(HELB_StartWidth, dEndEbwStaWidth); pMapElbow->SetAt(HELB_EndWidth, dEndEbwEndWidth); arrFit.append(pEndElbow); // 中间直管段 AecDbHvacDuct* pDuctAdd = (AecDbHvacDuct*)pDuct2->clone(); if (NULL != pDuctAdd) { AcGePoint3d ptSta = ptStaElbEnd; AcGePoint3d ptEnd = ptEndElbEnd; pDuctAdd->SetStartPoint(ptSta); pDuctAdd->SetEndPoint(ptEnd); AecDbObjXDataMap* pMap = pDuctAdd->GetSpecialtyData(); if (eSect == eRect) // 圆管时,两个管径都一样 { if (NULL != pMap) { pMap->SetAt(HDCT_Width, dNewDuctdWidth); pMap->SetAt(HDCT_Thick, dNewDuctdThick); } } AcGeVector3d vtUcsZ = AcGeVector3d::kZAxis; AcDbDatabase* pDb = acdbCurDwg(); if (NULL != pDb) { vtUcsZ = pDb->ucsxdir().crossProduct(pDb->ucsydir()); } AcGeVector3d vtDirect = ptEndElbEnd - ptStaElbEnd; AcGeVector3d vtDuct = pDuct1->EndPoint() - pDuct1->StartPoint(); if (vtDuct.isParallelTo(GetUcsZvt()) ) { if (!vtDirect.isPerpendicularTo(vtUcsZ)) // 斜管或立管,重设normal记宽高 { AcGeVector3d vtRot = vtSta.crossProduct(vtDirect); AcGeVector3d vtNormal = vtDirect.rotateBy(PI*0.5, vtRot); vtNormal.normalize(); pDuctAdd->setNormal(vtNormal); } else pDuctAdd->setNormal(vtUcsZ); if (eSect == eRect) { AcGeVector3d vtOff = ptStaCorner - ptEndCorner; if (vtOff.isPerpendicularTo(pDuct1->GetNormal())) // 此种情况,宽高比对调下 { double dOrigWidth(0.0), dOrigThick(0.0); AecDbObjXDataMap* pNewDuctMap = pDuctAdd->GetSpecialtyData(); if (NULL != pMap) { pMap->GetAt(HDCT_Width, dOrigWidth); pMap->GetAt(HDCT_Thick, dOrigThick); pMap->SetAt(HDCT_Thick, dOrigWidth); pMap->SetAt(HDCT_Width, dOrigThick); } } } } else { if (!vtDirect.isPerpendicularTo(vtUcsZ)) // 斜管或立管,重设normal记宽高 { AcGeVector3d vtRot = vtSta.crossProduct(vtDirect); AcGeVector3d vtNormal = vtDirect.rotateBy( PI* 0.5, vtRot); vtNormal.normalize(); pDuctAdd->setNormal(vtNormal); } } arrFit.append(pDuctAdd); } } return TRUE; } // 判断风管是能用乙子弯连接 CString CheckDuctValid(AecDbHvacDuct* pDuct1, AecDbHvacDuct* pDuct2) { AecDbObjXDataMap* pData1 = pDuct1->GetSpecialtyData(AcDb::kForRead); AecDbObjXDataMap* pData2 = pDuct2->GetSpecialtyData(AcDb::kForRead); if (NULL == pData1 || NULL == pData2) return _T("\n无法读取风管专业数据"); // 类型判断 AecHvac::HvacDuctType eType1(AecHvac::eStraight), eType2(AecHvac::eStraight); pData1->GetAt(HDCT_Type, (int&)eType1); pData2->GetAt(HDCT_Type, (int&)eType2); if (eType1 != eType2 || eType1 != AecHvac::eStraight) return _T("\n两风管必须都为直风管"); // 截面类型判断 ESection eSect1(eRect), eSect2(eRect); pData1->GetAt(HVAC_SectType, (int&)eSect1); pData2->GetAt(HVAC_SectType, (int&)eSect2); if (eSect1 != eSect2) return _T("\n两风管截面必须相同"); // 点、向量判断 AcGePoint3d ptSta1 = pDuct1->StartPoint(); AcGePoint3d ptEnd1 = pDuct1->EndPoint(); AcGePoint3d ptSta2 = pDuct2->StartPoint(); AcGePoint3d ptEnd2 = pDuct2->EndPoint(); AcGeTol geTol; geTol.setEqualVector(0.001); AcGeVector3d vtDirect1 = ptEnd1 - ptSta1; AcGeVector3d vtDirect2 = ptEnd2 - ptSta2; vtDirect1.normalize(); vtDirect2.normalize(); if (!vtDirect1.isParallelTo(vtDirect2, geTol)) return _T("\n两风管必须平行"); AcGeVector3d vtNormal1 = pDuct1->GetNormal(); AcGeVector3d vtNormal2 = pDuct2->GetNormal(); vtNormal1.normalize(); vtNormal2.normalize(); if (!vtNormal1.isParallelTo(vtNormal2)) return _T("\n两风管法向必须平行"); AcGePoint3d ptptSta1Prj; pDuct2->getClosestPointTo(ptSta1, ptptSta1Prj, Adesk::kTrue); AcGeVector3d vt1To2 = ptptSta1Prj - ptSta1; if (vt1To2.length() < 1e-3 || vtDirect1.isParallelTo(vt1To2)) return _T("\n两风管必须不共线"); if (vt1To2.isPerpendicularTo(vtNormal1)) // 常规情况,在法向垂直方向上偏移 { // 厚度判断 double dThick1(0.0), dThick2(0.0); if (eSect1 == eRect) { pData1->GetAt(HDCT_Thick, dThick1); pData2->GetAt(HDCT_Thick, dThick2); } else if (eSect1 == eCircle) { pData1->GetAt(HDCT_Diameter, dThick1); pData2->GetAt(HDCT_Diameter, dThick2); } if (fabs(dThick1 - dThick2) > 1e-3) return _T("\n水平共面情况下两风管厚度(直径)必须相同"); } else if (vt1To2.isParallelTo(vtNormal1)) // 特殊情况,在法向方向上偏移 { // 宽度判断 double dWidth1(0.0), dWidth2(0.0); if (eSect1 == eRect) { pData1->GetAt(HDCT_Width, dWidth1); pData2->GetAt(HDCT_Width, dWidth2); } else if (eSect1 == eCircle) { pData1->GetAt(HDCT_Diameter, dWidth1); pData2->GetAt(HDCT_Diameter, dWidth2); } if (fabs(dWidth1 - dWidth2) > 1e-3) return _T("\n竖直共面情况下两风管宽度(直径)必须相同"); } else return _T("\n两风管必须水平或竖直共面!"); return _T(""); } //添加乙字弯 void HA_TJZWCmdFnc() { //测试函数 CAcModuleResourceOverride myResources; CHFitingStyleDlg dlg(5,1); if ( IDOK == dlg.DoModal() ) { CMapFitaram mapOffset; SFitParam sParm; dlg.GetFitParamMap(mapOffset); if (mapOffset.Lookup(OFFSET_ANGLE, sParm)) { double dAngle = _tstof(sParm.sDefault); int nKind = dlg.GetFitCode(); if (nKind == 2) { if ( ( dAngle - 83.9 ) > 1.e-10) { acutPrintf(_T("\n角接乙子弯角度过大84度,无法绘制")); return; } } if (nKind == 3) { if ( (dAngle - 89.0 ) > 1e-10) { acutPrintf(_T("\n斜接乙子弯角度不能大于90度")); return; } } } // 风管过滤集 ads_name entDuct1, entDuct2; ads_point ptPick1, ptPick2; struct resbuf* pRb = acutBuildList(RTDXF0, DXF_PIPE, 0); int i = 0; AcDbVoidPtrArray arrFit; AecDbHvacFitting* pFit = NULL; AcDbObjectId id1,id2; // 循环选择风管 while (TRUE) { int nRes = CKTCadUtility::SelectEntity(_T("\n请选取基准风管(选取位置决定连接方向)<退出>:"), entDuct1, pRb,ptPick1); if (RTNORM != nRes) return; acdbGetObjectId(id1,entDuct1); // 第二根风管,根的一根重复时提示重新选 while (1) { nRes= CKTCadUtility::SelectEntity(_T("\n请取第二根风管<退出>:"), entDuct2, pRb,ptPick2); if (nRes != RTNORM) return; acdbGetObjectId(id2,entDuct2); if (id1 == id2) { acutPrintf(_T("\n不能选择同一风管,请重新选择!")); continue; } break; } ads_point ptPick11,ptPick22; acdbUcs2Wcs(ptPick1,ptPick11,false); acdbUcs2Wcs(ptPick2,ptPick22,false); AecDbHvacDuct* pDuct1 = NULL; AecDbHvacDuct* pDuct2 = NULL; if ( Acad::eOk == acdbOpenAcDbEntity((AcDbEntity*&)pDuct1,id1, AcDb::kForWrite) ) { if ( Acad::eOk == acdbOpenAcDbEntity((AcDbEntity*&)pDuct2,id2, AcDb::kForWrite) ) { CString csError = CheckDuctValid(pDuct1, pDuct2); // 连接有效性判断 if (!csError.IsEmpty()) { acutPrintf(csError); } else // 进行连接 { GetNewFit(pDuct1, pDuct2, ptPick1, arrFit,&dlg); } pDuct2->close(); } pDuct1->close(); } for (i = 0; i < arrFit.length(); i++) { pFit = (AecDbHvacFitting*)arrFit.at(i); if (NULL != pFit) { CoreTools::AddToModelSpace(pFit); } } arrFit.removeAll(); } } } typedef struct IDName { AcDbObjectId id; TCHAR szName[65]; }IDNAME; int SortSelectEnts( AcArray& ssEnts ) { if ( _tcscmp( ssEnts[0L].szName,_T("AEC_DBDUCT") ) == 0 ) { if ( _tcscmp( ssEnts[1L].szName,_T("AEC_DBDUCT") ) == 0 ) return 0; else if ( _tcscmp( ssEnts[1L].szName,_T("AEC_DBHVACFIT") ) == 0) { IDName entDuct = ssEnts[1]; IDName entFit = ssEnts[0]; ssEnts.removeAll(); ssEnts.append(entDuct); ssEnts.append(entFit); return 1; } } else if ( _tcscmp( ssEnts[0L].szName,_T("AEC_DBHVACFIT") ) == 0) { if ( _tcscmp( ssEnts[1L].szName,_T("AEC_DBDUCT")) == 0) return 1; } return -1; } CString CheckDuctAddRecValid(AecDbHvacDuct* pDuct1, AecDbHvacDuct* pDuct2) { AecDbObjXDataMap* pData1 = pDuct1->GetSpecialtyData(AcDb::kForRead); AecDbObjXDataMap* pData2 = pDuct2->GetSpecialtyData(AcDb::kForRead); if (NULL == pData1 || NULL == pData2) return _T("\n无法读取风管专业数据"); // 类型判断 AecHvac::HvacDuctType eType1(AecHvac::eStraight), eType2(AecHvac::eStraight); pData1->GetAt(HDCT_Type, (int&)eType1); pData2->GetAt(HDCT_Type, (int&)eType2); if (eType1 != eType2 || eType1 != AecHvac::eStraight) return _T("\n两风管必须都为直风管!"); //点、向量判断 AcGePoint3d ptSta1 = pDuct1->StartPoint(); AcGePoint3d ptEnd1 = pDuct1->EndPoint(); AcGePoint3d ptSta2 = pDuct2->StartPoint(); AcGePoint3d ptEnd2 = pDuct2->EndPoint(); AcGeVector3d vtDirect1 = ptEnd1 - ptSta1; AcGeVector3d vtDirect2 = ptEnd2 - ptSta2; if (!vtDirect1.isParallelTo(vtDirect2)) return _T("\n两风管必须平行!"); if (ptSta1 == ptSta2 || ptSta1 == ptEnd2 || ptEnd1 == ptSta2 || ptEnd1 == ptEnd2) return _T("\n两风管端点不能重合!"); return CString(); } // 获取管件要连接接口数据,pDuct要连接风管, ptCon连接点 BOOL GetFitConData(const AecDbHvacFitting* pFit, const AecDbHvacDuct* pDuct, double &dWidthOrDia, double &dThick, AcGePoint3d &ptCon, AcGeVector3d &vtCon) { AcGePoint3d ptSta = pDuct->StartPoint(); AcGePoint3d ptEnd = pDuct->EndPoint(); AcGePoint3d ptDuct = MidPoint(ptSta, ptEnd); AcGeVector3d vtDirect = ptEnd - ptSta; double dMinDist(0.0); AecInterface tCloseIf; // 离风管最近接口 int i(0); int nCount = pFit->GetInterfaceCount(); for (i = 0; i < nCount; i++) { AecInterface tIf; pFit->GetInterface(i, tIf); double dDistNow = tIf.ptPos.distanceTo(ptDuct); if (i == 0) { dMinDist = dDistNow; tCloseIf = tIf; } else if (dDistNow < dMinDist) { dMinDist = dDistNow; tCloseIf = tIf; } } if (!tCloseIf.vtDir.isParallelTo(vtDirect)) return FALSE; ptCon = tCloseIf.ptPos; vtCon = tCloseIf.vtDir; dWidthOrDia = tCloseIf.dSize1; dThick = 5.0; pDuct->GetSpecialtyData()->GetAt(HDCT_Thick, dThick); return TRUE; } CString CheckFitAndDuctValid(AecDbHvacFitting* pFitting, AecDbHvacDuct* pDuct) { AecDbObjXDataMap* pFitMap = pFitting->GetSpecialtyData(AcDb::kForRead); AecDbObjXDataMap* pDuctMap = pDuct->GetSpecialtyData(AcDb::kForRead); if (NULL == pFitMap || NULL == pDuctMap) return _T("\n无法读取管件或风管专业数据!"); // 类型判断 AecHvac::HvacDuctType eType = AecHvac::eStraight; pDuctMap->GetAt(HDCT_Type, (int&)eType); if (eType != AecHvac::eStraight) return _T("\n风管必须为直风管!"); EFittingType eKind; pFitMap->GetAt(KEY_RUNTIME, (int&)eKind); if (eKind == eReduce) return _T("\n所选管件不能是变径!"); // 同截面等径不处理 ESection eSectFit = eRect; ESection eSectDuct = eRect; pFitMap->GetAt(HVAC_SectType, (int&)eSectFit); pDuctMap->GetAt(HVAC_SectType, (int&)eSectDuct); if (eSectFit == eSectDuct) { double dDuctWidth(0.0), dDuctThick(0.0); double dFitWidth(0.0), dFitThick(0.0); AcGePoint3d ptFitCon; AcGeVector3d vtFitCon; if (!GetFitConData(pFitting, pDuct, dFitWidth, dFitThick, ptFitCon, vtFitCon)) return _T("\n离风管最近的管件接口方向跟风管不平行,无法连接"); if (eSectDuct == eRect) { pDuctMap->GetAt(HDCT_Width, dDuctWidth); pDuctMap->GetAt(HDCT_Thick, dDuctThick); if (fabs(dDuctWidth - dFitWidth) < 1e-3 && fabs(dDuctThick - dFitThick) < 1e-3) return _T("\n管件跟风管管径一致,无需变径连接"); } else if (eSectDuct == eCircle) { pDuctMap->GetAt(HDCT_Diameter, dDuctWidth); if (fabs(dDuctWidth - dFitWidth) < 1e-3) return _T("\n管件跟风管管径一致,无需变径连接"); } } return CString(); } AcGePoint3d GetStartPt( AecDbHvacDuct* pDuct1, AecDbHvacDuct* pDuct2, AcGePoint3d &ptCon2 ) { AcGePoint3d ptStart1, ptEnd1, ptStart2, ptEnd2, ptCon; pDuct1->getStartPoint(ptStart1); pDuct1->getEndPoint(ptEnd1); pDuct2->getStartPoint(ptStart2); pDuct2->getEndPoint(ptEnd2); AcGePoint3dArray ptOrigArr; ptOrigArr.append(ptStart1); ptOrigArr.append(ptEnd1); ptOrigArr.append(ptStart2); ptOrigArr.append(ptEnd2); AcGePoint3d ptStar2Prj, ptEnd2Prj; pDuct1->getClosestPointTo(ptStart2, ptStar2Prj, Adesk::kTrue); pDuct1->getClosestPointTo(ptEnd2, ptEnd2Prj, Adesk::kTrue); double dStaPara1(0.0), dEndPara1(0.0), dStaPara2(0.0), dEndPara2(0.0); pDuct1->getParamAtPoint(ptStart1, dStaPara1); pDuct1->getParamAtPoint(ptEnd1, dEndPara1); pDuct1->getParamAtPoint(ptStart2, dStaPara2); pDuct1->getParamAtPoint(ptEnd2, dEndPara2); AcArray dParaArr; dParaArr.append(dStaPara1); dParaArr.append(dEndPara1); dParaArr.append(dStaPara2); dParaArr.append(dEndPara2); AcGePoint3d ptTemp; double dParaTemp(0.0); int i(0), j(0); for (i = 0; i < 4; i++) { for (j = i + 1; j< 4; j++) { if (dParaArr[i] > dParaArr[j]) { dParaTemp = dParaArr[i]; dParaArr[i] = dParaArr[j]; dParaArr[j] = dParaTemp; ptTemp = ptOrigArr[i]; ptOrigArr[i] = ptOrigArr[j]; ptOrigArr[j] = ptTemp; } } } if (ptOrigArr[1] == ptStart1 || ptOrigArr[1] == ptEnd1) { if (ptOrigArr[2] == ptStart2 || ptOrigArr[2] == ptEnd2) // 两管没有完全重合 { ptCon2 = ptOrigArr[2]; ptCon = ptOrigArr[1]; } else if (ptOrigArr[2] == ptStart1 || ptOrigArr[2] == ptEnd1) // 两管完全重合 { ptCon2 = ptOrigArr[3]; ptCon = ptOrigArr[1]; } } else if (ptOrigArr[1] == ptStart2 || ptOrigArr[1] == ptEnd2) { if (ptOrigArr[2] == ptStart1 || ptOrigArr[2] == ptEnd1) // 两管没有完全重合 { ptCon2 = ptOrigArr[2]; ptCon = ptOrigArr[1]; } else if (ptOrigArr[2] == ptStart2 || ptOrigArr[2] == ptEnd2) // 两管完全重合 { ptCon2 = ptOrigArr[3]; ptCon = ptOrigArr[1]; } } return ptCon; } // 判断两段风管是否重合 BOOL IsSuperposition(AecDbHvacDuct* pDuct1, AecDbHvacDuct* pDuct2) { AcGePoint3d ptStart1, ptEnd1, ptStart2, ptEnd2; pDuct1->getStartPoint(ptStart1); pDuct1->getEndPoint(ptEnd1); pDuct2->getStartPoint(ptStart2); pDuct2->getEndPoint(ptEnd2); ptStart1.z = ptEnd1.z = ptStart2.z = ptEnd2.z = 0; AcDbLine line(ptStart2, ptEnd2); line.getClosestPointTo(ptStart1, ptStart1, Adesk::kTrue); line.getClosestPointTo(ptEnd1, ptEnd1, Adesk::kTrue); double dLen1 = ptStart1.distanceTo(ptEnd1); double dLen2 = ptStart2.distanceTo(ptEnd2); AcGePoint3dArray ptOrigArr; ptOrigArr.append(ptStart1); ptOrigArr.append(ptEnd1); ptOrigArr.append(ptStart2); ptOrigArr.append(ptEnd2); double dStaPara1(0.0), dEndPara1(0.0), dStaPara2(0.0), dEndPara2(0.0); pDuct1->getParamAtPoint(ptStart1, dStaPara1); pDuct1->getParamAtPoint(ptEnd1, dEndPara1); pDuct1->getParamAtPoint(ptStart2, dStaPara2); pDuct1->getParamAtPoint(ptEnd2, dEndPara2); AcArray dParaArr; dParaArr.append(dStaPara1); dParaArr.append(dEndPara1); dParaArr.append(dStaPara2); dParaArr.append(dEndPara2); AcGePoint3d ptTemp; double dParaTemp(0.0); int i(0), j(0); for (i = 0; i < 4; i++) { for (j = i + 1; j< 4; j++) { if (dParaArr[i] > dParaArr[j]) { dParaTemp = dParaArr[i]; dParaArr[i] = dParaArr[j]; dParaArr[j] = dParaTemp; ptTemp = ptOrigArr[i]; ptOrigArr[i] = ptOrigArr[j]; ptOrigArr[j] = ptTemp; } } } double dLength = ptOrigArr[0].distanceTo(ptOrigArr[3]); if(1e-6 > fabs(dLength - dLen1 - dLen2)) return TRUE; return (dLength <= dLen1 + dLen2); } // 得到弧管中心线 AcDbCurve* GetCenterLine(AecDbHvacDuct *pDuct, AecDbObjXDataMap *pMap/* = NULL*/) { if (NULL == pDuct && NULL == pMap) return NULL; if (NULL != pDuct) // 优先使用风管指针,风管指针为空,使用Map指针 { pMap = pDuct->GetSpecialtyData(); } AcDbCurve* pCurve = NULL; if(NULL != pMap) { AcGePoint3d ptStart, ptEnd; double dBulge = 0; pMap->GetAt(HDCT_START, ptStart); pMap->GetAt(HDCT_END, ptEnd); pMap->GetAt(HDCT_Bulge, dBulge); if(EQUAL_ZERO(dBulge)) { pCurve = new AcDbLine(ptStart, ptEnd); } else { AcGeVector3d vtDirect = ptEnd - ptStart; vtDirect.normalize(); AcGeVector3d vtNormal; pMap->GetAt(HVAC_Normal, vtNormal); // 计算弧管中点 AcGeVector3d vtLevel = vtDirect; vtLevel.rotateBy(-PI * 0.5, vtNormal); vtLevel.normalize(); vtLevel *= ptStart.distanceTo(ptEnd) * 0.5 * dBulge; AcGePoint3d ptMid = ptStart + ptStart.distanceTo(ptEnd) * 0.5 * vtDirect; ptMid += vtLevel; AcGeCircArc3d arc(ptStart, ptMid, ptEnd); AcDbCircle circle(arc.center(), vtNormal, arc.radius()); AcGePoint3dArray arVerts; arVerts.append(ptStart); arVerts.append(ptEnd); AcDbVoidPtrArray arEnts; if(Acad::eOk != circle.getSplitCurves(arVerts, arEnts)) return NULL; AcDbObject* pObj = NULL; for(int i = 0; i < arEnts.length(); i++) { pObj = (AcDbObject*)arEnts[i]; if(NULL != pObj && NULL == pCurve) { AcDbArc* pArc = AcDbArc::cast(pObj); if(NULL != pArc) { AcGePoint3d ptS, ptE, ptM; pArc->getStartPoint(ptS); pArc->getEndPoint(ptE); AcGeVector3d vtS = ptS - pArc->center(); AcGeVector3d vtE = ptE - pArc->center(); double dRad = vtS.angleTo(vtE, pArc->normal()) / 2; AcGeVector3d vtM = vtS.rotateBy(dRad, pArc->normal()); vtM.normalize(); ptM = pArc->center() + vtM * pArc->radius(); if(ptM == ptMid){ pCurve = pArc; pObj = NULL; } } } if(NULL != pObj) { delete pObj; pObj = NULL; } } } } return pCurve; } AcGeVector3d GetSoftDirByPt(const AcGePoint3d &pt, AecDbHvacDuct *pDuct, AecDbObjXDataMap *pMap = NULL, AcDbObjectId idSoft = AcDbObjectId::kNull) { if (NULL == pMap) { if (NULL == pDuct) { if (!idSoft.isNull()) { OPENOBJ_BEGIN(idSoft, AcDb::kForRead, AecDbHvacDuct, pTemp); if (NULL == pTemp) return AcGeVector3d::kIdentity; pMap = pTemp->GetSpecialtyData(); OPENOBJ_END(); } else return AcGeVector3d::kIdentity; } else pMap = pDuct->GetSpecialtyData(AcDb::kForRead); } if (NULL == pMap) return AcGeVector3d::kIdentity; AcGeVector3d vtDir = AcGeVector3d::kIdentity; // 人为的设置过方向,使用人为设置的方向 AcGePoint3d ptStart, ptEnd; pMap->GetAt(HDCT_START, ptStart); pMap->GetAt(HDCT_END, ptEnd); if (pt == ptStart) { if ( pMap->GetAt(HDCT_StartDir, vtDir) ) return vtDir.normalize(); } else if (pt == ptEnd) { if ( pMap->GetAt(HDCT_EndDir, vtDir) ) return vtDir.normalize(); } // 否则,重新计算端点方向 AcDbCurve *pCurve = GetCenterLine(NULL, pMap); if (pCurve == NULL) return AcGeVector3d::kIdentity; AcDbArc *pArc = AcDbArc::cast(pCurve); if (pArc == NULL) { delete pCurve; return AcGeVector3d::kIdentity; } AcGePoint3d ptArcS, ptArcE; pArc->getEndPoint(ptArcE); pArc->getStartPoint(ptArcS); vtDir = pt - pArc->center(); // 圆心指向端点的向量,旋转90/-90后,为切线 vtDir.normalize(); if (pt == ptArcS) // 此点为弧线逆时针起点 { vtDir.rotateBy(-PI / 2.0, GetUcsZvt()); } else if (pt == ptArcE) { vtDir.rotateBy(PI / 2.0, GetUcsZvt()); } else { vtDir = AcGeVector3d::kIdentity; } if (pCurve != NULL) { delete pCurve; } return vtDir; } CString CheckSoftDuctValid(AecDbHvacDuct* pDuct1, AecDbHvacDuct* pDuct2, AcGePoint3d& ptInter) { if (NULL == pDuct1 && NULL == pDuct2) return _T("无法得到风管数据."); AecDbHvacDuct* pSoftDuct = NULL; AecDbHvacDuct* pStrDuct = NULL; if (pDuct1->IsArcDuct() && !pDuct2->IsArcDuct()) { pSoftDuct = pDuct1; pStrDuct = pDuct2; } else if (pDuct2->IsArcDuct() && !pDuct1->IsArcDuct()) { pSoftDuct = pDuct2; pStrDuct = pDuct1; } else return _T("ERROE"); // 点、向量判断 AcGePoint3d ptSta1 = pSoftDuct->StartPoint(); AcGePoint3d ptEnd1 = pSoftDuct->EndPoint(); AcGePoint3d ptSta2 = pStrDuct->StartPoint(); AcGePoint3d ptEnd2 = pStrDuct->EndPoint(); // 直管方向与弧管端点方向 AcGeVector3d vt2 = ptEnd2 - ptSta2; vt2.normalize(); AcGeVector3d vtStrDir = GetSoftDirByPt(ptSta1, pSoftDuct); AcGeVector3d vtEndDir = GetSoftDirByPt(ptEnd1, pSoftDuct); AcGeTol tol; tol.setEqualPoint(1e-1); tol.setEqualVector(1e-3); if ( vtStrDir.isParallelTo(vt2, tol) ) { if (vtEndDir.isParallelTo(vt2, tol)) { // 都平行,认为距离直管最近的端点为变径起点 if (ptSta1.distanceTo(ptSta2) + ptSta1.distanceTo(ptEnd2) < ptEnd1.distanceTo(ptSta2) + ptEnd1.distanceTo(ptEnd2)) ptInter = ptSta1; else ptInter = ptEnd1; } else ptInter = ptSta1; } else if ( vtEndDir.isParallelTo(vt2, tol)) { ptInter = ptEnd1; } else { return _T("\n直管方向与弧管端点方向不平行,无法形成变径."); } return _T(""); } double CalReduceLength( ESection eSectS, double dWithS, double dThickS, ESection eSectE, double dWithE, double dThickE, CString csCalType, double dLength, double dAngle ) { double dReduceLen = 0.0; if (eSectS == eCircle) dThickS = dWithS; if (eSectE == eCircle) dThickE = dWithE; double dWidthDif = fabs(dWithS - dWithE); double dThickDif = fabs(dThickS - dThickE); if (csCalType == _T("角度")) { dReduceLen = (dWidthDif > dThickDif ? dWidthDif : dThickDif)*0.5 / tan(dAngle*0.5 * PI / 180.0); } else if (csCalType == _T("长度")) { dReduceLen = dLength; } else { dReduceLen = (dWidthDif > dThickDif ? dWidthDif : dThickDif) * 1.5 + 100.0; } if (dReduceLen < 200.0) dReduceLen = 200.0; return dReduceLen; } void GetSoftFit( AecDbHvacDuct* pSoftDuct, AecDbHvacDuct* pStrDuct, AcDbVoidPtrArray &arrFit, CHFitingStyleDlg* pDlg,AecDbHvacFitting* pReduce /*= NULL*/) { AecDbObjXDataMap* pData1 = pSoftDuct->GetSpecialtyData(); AecDbObjXDataMap* pData2 = pStrDuct->GetSpecialtyData(); if (NULL == pData1 || NULL == pData2) return; // 检查连接的有效性,并将弧管的一个端点作为变径起点 AcGePoint3d ptCon1; CString sError = CheckSoftDuctValid(pSoftDuct, pStrDuct, ptCon1); if ( !sError.IsEmpty() ) return; // 获取界面输入参数 double dAngle(45), dLen(0.0); CString csComType; if (NULL != pDlg) { CMapFitaram mapData; pDlg->GetFitParamMap(mapData); SFitParam eParm; if (mapData.Lookup(REDUCE_ANGLE, eParm)) dAngle = _ttof(eParm.sDefault) * PI / 180; if (mapData.Lookup(REDUCE_LEN, eParm)) dLen = _ttof(eParm.sDefault); if (mapData.Lookup(REDUCE_COMTYPE, eParm)) csComType = eParm.sDefault; } // 获取原分管通用属性,用于变径 AcGePoint3d ptSta1, ptEnd1, ptSta2, ptEnd2; pData1->GetAt(HDCT_START, ptSta1); pData1->GetAt(HDCT_END, ptEnd1); pData2->GetAt(HDCT_START, ptSta2); pData2->GetAt(HDCT_END, ptEnd2); // 直管靠近变径的那一端的端点 AcGePoint3d ptCon2; if (ptCon1.distanceTo(ptSta2) < ptCon1.distanceTo(ptEnd2)) ptCon2 = ptSta2; else ptCon2 = ptEnd2; // 系统图层 CString csSysName, csMatName; pData1->GetAt(HVAC_System, csSysName); pData1->GetAt(HVAC_Material, csMatName); AcDbObjectId idMainLayer = pSoftDuct->layerId(); AcDbObjectId idBaseLayer = pSoftDuct->GetCenterLayer(); AcDbObjectId idHideLayer = pSoftDuct->GetDashLayer(); AcDbObjectId idEndLayer; pData1->GetAt(HVAC_EndLayer, idEndLayer); BOOL bSingleLine(FALSE), bBaseLine(FALSE); double dStaWidth(0.0), dEndWidth(0.0), dStartThick(0.0), dEndThick(0.0); ESection eStartSect(eRect), eEndSect(eRect); BOOL bEdgeWeigh(FALSE), bCentWeigh(FALSE); double dEdgeWidth(0.0), dCentWidth(0.0), dSideWidth(0.0); // 边/中/端线宽 // 变径截面类型,截面尺寸 pData1->GetAt(HVAC_SectType, (int&)eStartSect); pData1->GetAt(HDCT_Width, dStaWidth); pData1->GetAt(HDCT_Thick, dStartThick); pData2->GetAt(HDCT_Width, dEndWidth); pData2->GetAt(HDCT_Thick, dEndThick); pData2->GetAt(HVAC_SectType, (int&)eEndSect); if (eStartSect == eCircle) pData1->GetAt(HDCT_Diameter, dStartThick); else if (eEndSect == eCircle) pData2->GetAt(HDCT_Diameter, dEndThick); pData1->GetAt(HVAC_IsSingleLine, bSingleLine); pData1->GetAt(HVAC_HasBaseLine, bBaseLine); pData1->GetAt(HVAC_EdgeWeight, bEdgeWeigh); pData1->GetAt(HVAC_EdgeWidth, dEdgeWidth); pData1->GetAt(HVAC_CentWeight, bCentWeigh); pData1->GetAt(HVAC_CentWidth, dCentWidth); pData1->GetAt(HVAC_EndWidth, dSideWidth); AcGeVector3d vtNormal = pSoftDuct->GetNormal(); vtNormal.normalize(); // 求偏移 AcGeLine3d line2(ptSta2, ptEnd2); AcGePoint3d ptRight = line2.closestPointTo(ptCon1); // 管1某点到管2的垂足点 AcGeVector3d vtOffSet = ptRight - ptCon1; AcGeVector3d vtOffSetPrj = vtOffSet.orthoProject(vtNormal); double dOffset = vtOffSetPrj.length(); AcGeVector3d vtRedEnd = GetSoftDirByPt(ptCon1, NULL, pData1); vtRedEnd.normalize(); if (!vtRedEnd.crossProduct(vtOffSetPrj).isCodirectionalTo(vtNormal)) dOffset *= -1; AcGeVector3d vtRedStart = -vtRedEnd; // 变径起始点,考虑法兰长度 AcGePoint3d ptRedStart = ptCon1; double dPlusEdge(0.0); // 端部直边段 AecHvac::HvacReduComType eComType = AecHvac::eAuto; if (csComType == _T("角度")) eComType = AecHvac::eAngle; else if (csComType == _T("长度")) eComType = AecHvac::eLength; // 计算变径长度 double dReduceLen = CalReduceLength(eStartSect, dStaWidth, dStartThick, eEndSect, dEndWidth, dEndThick, csComType, dLen, dAngle); AcGePoint3d ptRedEnd = ptRedStart + dReduceLen * vtRedEnd; ptRedEnd += vtOffSet; // 新建变径 AecDbObjXDataMap* pMapReduce = NULL; if (pReduce == NULL) { pReduce = new AecDbHvacFitting; if (NULL == pReduce) return; pReduce->setLayer(idMainLayer); pReduce->SetDashLayer(idHideLayer); pReduce->SetCenterLayer(idBaseLayer); pMapReduce = pReduce->GetSpecialtyData(); if (NULL == pMapReduce) { delete pReduce; pReduce = NULL; return; } pMapReduce->SetAt(KEY_FITSRV, KEY_FITHVAC); pMapReduce->SetAt(KEY_RUNTIME, eReduce); pMapReduce->SetAt(HVAC_System, csSysName); pMapReduce->SetAt(HVAC_Material, csMatName); pMapReduce->SetAt(HRED_StartSectType, (int &)eStartSect); pMapReduce->SetAt(HRED_EndSectType, (int &)eEndSect); //pMapReduce->SetAt(KEY_SECSHAPE, (int &)eStartSect); // 设置数据 pMapReduce->SetAt(HRED_StartPoint, ptRedStart); pMapReduce->SetAt(HRED_EndPoint, ptRedEnd); pMapReduce->SetAt(HVAC_IsSingleLine, bSingleLine); pMapReduce->SetAt(HVAC_HasBaseLine, bBaseLine); pMapReduce->SetAt(HVAC_EdgeWeight, bEdgeWeigh); pMapReduce->SetAt(HVAC_EdgeWidth, dEdgeWidth); pMapReduce->SetAt(HVAC_CentWeight, bCentWeigh); pMapReduce->SetAt(HVAC_CentWidth, dCentWidth); pMapReduce->SetAt(HVAC_EndWidth, dSideWidth); pMapReduce->SetAt(HVAC_EndLayer, idEndLayer, FALSE); pMapReduce->SetAt(HVAC_PlusEdge, dPlusEdge); pMapReduce->SetAt(KEY_NORMAL, vtNormal); pMapReduce->SetAt(HRED_StartWidth, dStaWidth); pMapReduce->SetAt(HRED_EndWidth, dEndWidth); pMapReduce->SetAt(HRED_StartThick, dStartThick); pMapReduce->SetAt(HRED_EndThick, dEndThick); pMapReduce->SetAt(HRED_StartSectType, eStartSect); pMapReduce->SetAt(HRED_EndSectType, eEndSect); pMapReduce->SetAt(HRED_StartDir, vtRedStart); pMapReduce->SetAt(HRED_ComputeType, eComType); pMapReduce->SetAt(HRED_Offset, vtOffSet); pMapReduce->SetAt(HRED_Angle, dAngle); pMapReduce->SetAt(HRED_Length, dLen); arrFit.append(pReduce); // 改变直管的首(尾)点位置 pMapReduce->GetAt(HRED_EndPoint, ptRedEnd); AcGePoint3d pt = ptRedEnd; if (ptCon2 == ptSta2) { pStrDuct->SetStartPoint(pt); } else if ( ptCon2 == ptEnd2 ) { pStrDuct->SetEndPoint(pt); } else {;} } else { } } // 从两风管得到需要添加的构件指针数组 void GetFit( AecDbHvacDuct* pDuct1, AecDbHvacDuct* pDuct2,AcDbVoidPtrArray &arrFit,CHFitingStyleDlg* pDlg, AecDbHvacFitting* pReduce = NULL ) { AecDbObjXDataMap* pData1 = pDuct1->GetSpecialtyData(); AecDbObjXDataMap* pData2 = pDuct2->GetSpecialtyData(); if (NULL == pData1 || NULL == pData2) return; if (pDuct1->IsArcDuct() && !pDuct2->IsArcDuct()) { GetSoftFit(pDuct1, pDuct2, arrFit, pDlg,pReduce); return; } else if ( pDuct2->IsArcDuct() && !pDuct1->IsArcDuct()) { GetSoftFit(pDuct2, pDuct1, arrFit, pDlg,pReduce); return; } // 系统图层 CString csSysName, csMatName; pData1->GetAt(HVAC_System, csSysName); pData1->GetAt(HVAC_Material, csMatName); AcDbObjectId idMainLayer = pDuct1->GetDoubleLayer(); AcDbObjectId idBaseLayer = pDuct1->GetCenterLayer(); AcDbObjectId idEndLayer; AcDbObjectId idHideLayer = pDuct1->GetDashLayer(); // 获取界面输入参数 double dAngle(45), dLen(0.0); CString csComType; if (NULL != pDlg) { CMapFitaram mapData; pDlg->GetFitParamMap(mapData); SFitParam eParm; if (mapData.Lookup(REDUCE_ANGLE, eParm)) dAngle = _ttof(eParm.sDefault) * PI / 180; if (mapData.Lookup(REDUCE_LEN, eParm)) dLen = MayAsMUnit(_ttof(eParm.sDefault)); if (mapData.Lookup(REDUCE_COMTYPE, eParm)) csComType = eParm.sDefault; } // 获取原分管通用属性,用于变径 AcGePoint3d ptSta1 = pDuct1->StartPoint(); AcGePoint3d ptEnd1 = pDuct1->EndPoint(); AcGePoint3d ptSta2 = pDuct2->StartPoint(); AcGePoint3d ptEnd2 = pDuct2->EndPoint(); BOOL bSingleLine(FALSE), bBaseLine(TRUE); double dStaWidth(0.0), dEndWidth(0.0), dStartThick(0.0), dEndThick(0.0); ESection eStartSect(eRect), eEndSect(eRect); BOOL bEdgeWeigh(FALSE), bCentWeigh(FALSE); double dEdgeWidth(0.0), dCentWidth(0.0), dSideWidth(0.0); // 边/中/端线宽 pData1->GetAt(HVAC_SectType, (int&)eStartSect); pData2->GetAt(HVAC_SectType, (int&)eEndSect); pData1->GetAt(HDCT_Width, dStaWidth); pData2->GetAt(HDCT_Width, dEndWidth); pData1->GetAt(HDCT_Thick, dStartThick); pData2->GetAt(HDCT_Thick, dEndThick); pData1->GetAt(HVAC_IsSingleLine, bSingleLine); pData1->GetAt(HVAC_HasBaseLine, bBaseLine); pData1->GetAt(HVAC_EdgeWeight, bEdgeWeigh); pData1->GetAt(HVAC_EdgeWidth, dEdgeWidth); pData1->GetAt(HVAC_CentWeight, bCentWeigh); pData1->GetAt(HVAC_CentWidth, dCentWidth); pData1->GetAt(HVAC_EndWidth, dSideWidth); pData1->GetAt(HVAC_EndLayer, idEndLayer); if (eStartSect == eCircle) pData1->GetAt(HDCT_Diameter, dStartThick); else if (eEndSect == eCircle) pData2->GetAt(HDCT_Diameter, dEndThick); AcGeVector3d vtNormal(0, 0, 1); AcGePoint3d ptTempCon2; // 变径末点,也是某个管的端点 AcGePoint3d ptCon1 = GetStartPt(pDuct1, pDuct2, ptTempCon2); // 得到变径起始点 AcGeVector3d vtSta = ptEnd1 - ptSta1; AcGeLine3d ln(AcGePoint3d::kOrigin, vtSta); if (ln.isParallelTo(AcGePlane::kXYPlane)) vtNormal.set(0, 0, 1); else { if (vtSta.isParallelTo(AcGeVector3d::kZAxis)) { vtNormal = AcGeVector3d::kYAxis; vtNormal.rotateBy(pDuct1->GetSectionRotation(), AcGeVector3d::kZAxis); } else { vtNormal = vtSta; vtNormal.rotateBy(pDuct1->GetSectionRotation(), AcGeVector3d::kZAxis); } } vtNormal.normalize(); AcGeVector3d vtEnd = AcGeVector3d::kXAxis; BOOL bSuper = IsSuperposition(pDuct1, pDuct2); if (ptCon1 == ptSta1) { vtEnd = ptCon1 - ptEnd1; } else if (ptCon1 == ptEnd1) { vtEnd = ptCon1 - ptSta1; } else if (ptCon1 == ptSta2) { vtEnd = ptCon1 - ptEnd2; } else if (ptCon1 == ptEnd2) { vtEnd = ptCon1 - ptSta2; } vtEnd.normalize(); if( (ptCon1 == ptEnd1 && ptEnd1 == ptSta2) || (ptCon1 == ptSta1 && ptCon1 == ptEnd2)) { vtEnd *= -1; } AcGeLine3d line2(ptSta2, ptEnd2); if (ptCon1 == ptSta2 || ptCon1 == ptEnd2) { line2.set(ptSta1, ptEnd1); pData1->GetAt(HDCT_Width, dEndWidth); pData2->GetAt(HDCT_Width, dStaWidth); pData1->GetAt(HDCT_Thick, dEndThick); pData2->GetAt(HDCT_Thick, dStartThick); pData1->GetAt(HVAC_SectType, (int&)eEndSect); pData2->GetAt(HVAC_SectType, (int&)eStartSect); } if (eStartSect == eCircle) dStartThick = dStaWidth; if (eEndSect == eCircle) dEndThick = dEndWidth; // 找出两端尺寸相差较大值 double dWidthSub = fabs(dStaWidth - dEndWidth); double dThickSub = fabs(dStartThick - dEndThick); double dMaxSub = dWidthSub > dThickSub ? dWidthSub:dThickSub; // 求偏移 AcGePoint3d ptRight = line2.closestPointTo(ptCon1); // 管1某点到管2的垂足点 AcGeVector3d vtOffSet = ptRight - ptCon1; AcGeVector3d vtOffSetPrj = vtOffSet.orthoProject(vtNormal); double dOffset = vtOffSetPrj.length(); if (!vtEnd.crossProduct(vtOffSetPrj).isCodirectionalTo(vtNormal)) dOffset *= -1; ptCon1 += 0.0 * vtEnd; double dPlusEdge(0.0); AecHvac::HvacReduComType eComType = AecHvac::eAuto; if (csComType == _T("角度")) eComType = AecHvac::eAngle; else if (csComType == _T("长度")) eComType = AecHvac::eLength; AcGeVector3d vtRedSta = (ptSta1 - ptEnd1); vtRedSta.normalize(); if (pDuct1->IsVertical() && pDuct2->IsVertical()) { vtRedSta = (ptEnd1 - ptSta1); vtRedSta.normalize(); } if(bSuper && !(ptTempCon2 == ptSta1 && ptTempCon2 == ptEnd2)) vtRedSta *= -1; // 取得数据参数容器,加入数据参数 AecDbObjXDataMap* pMapReduce = NULL; if (pReduce == NULL) // 为新建变径连接情况 { pReduce = new AecDbHvacFitting; pReduce->setLayer(idMainLayer); pReduce->SetDoubleLayer(idMainLayer); pReduce->SetDashLayer(idHideLayer); pReduce->SetCenterLayer(idBaseLayer); pMapReduce = pReduce->GetSpecialtyData(); if (NULL == pMapReduce) { delete pReduce; pReduce = NULL; return; } pMapReduce->SetAt(HRED_StartSectType, (int &)eStartSect); pMapReduce->SetAt(HRED_EndSectType, (int &)eEndSect); //pMapReduce->SetAt(KEY_SECSHAPE, (int &)eStartSect); pMapReduce->SetAt(KEY_FITSRV, KEY_FITHVAC); pMapReduce->SetAt(KEY_RUNTIME, eReduce); pMapReduce->SetAt(HVAC_System, csSysName); pMapReduce->SetAt(HVAC_Material, csMatName); // 设置数据 pMapReduce->SetAt(HRED_StartPoint, ptCon1); ptCon1 += vtOffSet; ptCon1 += dLen * vtEnd; pMapReduce->SetAt(HRED_EndPoint, ptCon1); pMapReduce->SetAt(HVAC_IsSingleLine, bSingleLine); pMapReduce->SetAt(HVAC_HasBaseLine, bBaseLine); pMapReduce->SetAt(HVAC_EdgeWeight, bEdgeWeigh); pMapReduce->SetAt(HVAC_EdgeWidth, dEdgeWidth); pMapReduce->SetAt(HVAC_CentWeight, bCentWeigh); pMapReduce->SetAt(HVAC_CentWidth, dCentWidth); pMapReduce->SetAt(HVAC_EndWidth, dSideWidth); pMapReduce->SetAt(HVAC_EndLayer, idEndLayer, FALSE); pMapReduce->SetAt(HVAC_PlusEdge, dPlusEdge); pMapReduce->SetAt(KEY_NORMAL, vtNormal); pMapReduce->SetAt(HRED_StartWidth, dStaWidth); pMapReduce->SetAt(HRED_EndWidth, dEndWidth); pMapReduce->SetAt(HRED_StartThick, dStartThick); pMapReduce->SetAt(HRED_EndThick, dEndThick); pMapReduce->SetAt(HRED_StartSectType, eStartSect); pMapReduce->SetAt(HRED_EndSectType, eEndSect); pMapReduce->SetAt(HRED_StartDir, vtRedSta); pMapReduce->SetAt(HRED_ComputeType, eComType); pMapReduce->SetAt(HRED_Offset, vtOffSet); pMapReduce->SetAt(HRED_Angle, dAngle); pMapReduce->SetAt(HRED_Length, dLen); arrFit.append(pReduce); // 改变末端连接的管的首(尾)点位置 AcGePoint3d ptNewDuct, ptConEnd; pMapReduce->GetAt(HRED_EndPoint, ptConEnd); ptNewDuct = ptConEnd; if (ptTempCon2 == ptSta1) { pDuct1->SetStartPoint(ptNewDuct); } else if (ptTempCon2 == ptEnd1) { pDuct1->SetEndPoint(ptNewDuct); } else if (ptTempCon2 == ptSta2) { pDuct2->SetStartPoint(ptNewDuct); } else if (ptTempCon2 == ptEnd2) { pDuct2->SetEndPoint(ptNewDuct); } } else { } } void GetFit( AecDbHvacFitting* pExistFit, AecDbHvacDuct* pDuct2,CHFitingStyleDlg* pDlg,AcDbVoidPtrArray &arrFit) { AecDbObjXDataMap* pFitMap = pExistFit->GetSpecialtyData(AcDb::kForRead); AecDbObjXDataMap* pDuctMap = pDuct2->GetSpecialtyData(AcDb::kForRead); if (NULL == pFitMap || NULL == pDuctMap) return; double dFitWidth(0.0), dFitThick(0.0); AcGePoint3d ptFitCon; AcGeVector3d vtFitCon; if (!GetFitConData(pExistFit, pDuct2, dFitWidth, dFitThick, ptFitCon, vtFitCon)) { acutPrintf(_T("\n离风管最近的管件接口方向跟风管不平行,无法连接")); return; } // 系统/图层 CString csSysName, csMatName; pFitMap->GetAt(HVAC_System, csSysName); pFitMap->GetAt(HVAC_Material, csMatName); AcDbObjectId idMainLayer = pExistFit->layerId(); AcDbObjectId idBaseLayer = pExistFit->GetCenterLayer(); AcDbObjectId idEndLayer; AcDbObjectId idHideLayer = pExistFit->GetDashLayer(); // 获取界面输入参数 double dAngle(45), dLen(0.0); CString csComType; if (NULL != pDlg) { CMapFitaram mapData; pDlg->GetFitParamMap(mapData); SFitParam eParm; if (mapData.Lookup(REDUCE_ANGLE, eParm)) dAngle = _ttof(eParm.sDefault) * PI / 180; if (mapData.Lookup(REDUCE_LEN, eParm)) dLen = _ttof(eParm.sDefault); if (mapData.Lookup(REDUCE_COMTYPE, eParm)) csComType = eParm.sDefault; } // 获取原分管通用属性,用于变径 AcGePoint3d ptSta2 = pDuct2->StartPoint(); AcGePoint3d ptEnd2 = pDuct2->EndPoint(); BOOL bSingleLine(FALSE), bBaseLine(FALSE); double dStaWidth(0.0), dEndWidth(0.0), dStartThick(0.0), dEndThick(0.0); ESection eStartSect(eRect), eEndSect(eRect); BOOL bEdgeWeigh(FALSE), bCentWeigh(FALSE); double dEdgeWidth(0.0), dCentWidth(0.0), dSideWidth(0.0); // 边/中/端线宽 pFitMap->GetAt(HVAC_SectType, (int&)eStartSect); pDuctMap->GetAt(HVAC_SectType, (int&)eEndSect); pDuctMap->GetAt(HDCT_Width, dEndWidth); pDuctMap->GetAt(HDCT_Thick, dEndThick); pFitMap->GetAt(HVAC_IsSingleLine, bSingleLine); pFitMap->GetAt(HVAC_HasBaseLine, bBaseLine); pFitMap->GetAt(HVAC_EdgeWeight, bEdgeWeigh); pFitMap->GetAt(HVAC_EdgeWidth, dEdgeWidth); pFitMap->GetAt(HVAC_CentWeight, bCentWeigh); pFitMap->GetAt(HVAC_CentWidth, dCentWidth); pFitMap->GetAt(HVAC_EndWidth, dSideWidth); pFitMap->GetAt(HVAC_EndLayer, idEndLayer); EFittingType eKind = (EFittingType)0; pFitMap->GetAt(KEY_RUNTIME, (int &)eKind); if (eElbow == eKind) //管件为弯头的情况 { AcGeVector3d vtFitNormal; AcGeVector3d vtFitStart; AcGeVector3d vtFitEnd; AcGePoint3d ptFitStartPoint; AcGePoint3d ptFitEndPoint; AcGePoint3d ptFitCorner; BOOL bGetFitParam = pFitMap->GetAt(HELB_StartPoint, ptFitStartPoint); bGetFitParam = pFitMap->GetAt(HELB_EndPoint, ptFitEndPoint); bGetFitParam = pFitMap->GetAt(HELB_CornerPoint, ptFitCorner); vtFitStart = ptFitStartPoint - ptFitCorner; vtFitEnd = ptFitEndPoint - ptFitCorner; vtFitNormal = vtFitStart.crossProduct(vtFitEnd); if (vtFitNormal.isParallelTo(GetUcsZvt()) && eStartSect == eRect) //水平放置的管件 { dStaWidth = dFitWidth; dStartThick = dFitThick; } else //立式放置的管件 { dStaWidth = dFitThick; dStartThick = dFitWidth; } if (eStartSect == eCircle) //圆形管件 { dStaWidth = dFitWidth; dStartThick = dFitWidth; } } else { AcDbDatabase* pDb = acdbCurDwg(); AcGeVector3d vtZAxis(pDb->ucsxdir().crossProduct(pDb->ucsydir())); AcGeTol tol; tol.setEqualPoint(1.0); tol.setEqualVector(1.0 / 10.0); if(pExistFit->normal().isParallelTo(vtZAxis, tol)) { dStaWidth = dFitWidth; dStartThick = dFitThick; } else { dStaWidth = dFitThick; dStartThick = dFitWidth; } } if (eStartSect == eCircle) dStartThick = dFitWidth; else if (eEndSect == eCircle) pDuctMap->GetAt(HDCT_Diameter, dEndThick); AcGePoint3d ptCon1 = ptFitCon; // 得到变径起始点 double dStaDist = ptSta2.distanceTo(ptCon1); double dEndDist = ptEnd2.distanceTo(ptCon1); AcGeVector3d vtNormal = pDuct2->GetNormal(); vtNormal.normalize(); AcGeVector3d vtEnd = vtFitCon.normalize(); AcGeVector3d vtRedSta = -vtEnd; AcGePoint3d ptTempCon2 = dStaDist < dEndDist ? ptSta2:ptEnd2;// 变径要末点要根某个管连接的端点 // 找出两端尺寸相差较大值 double dWidthSub = fabs(dStaWidth - dEndWidth); double dThickSub = fabs(dStartThick - dEndThick); double dMaxSub = dWidthSub > dThickSub ? dWidthSub:dThickSub; // 求偏移 AcGeLine3d line2(ptSta2, ptEnd2); AcGePoint3d ptRight = line2.closestPointTo(ptCon1); // 管1某点到管2的垂足点 AcGeVector3d vtOffSet = ptRight - ptCon1; AcGeVector3d vtOffSetPrj = vtOffSet.orthoProject(vtNormal); double dOffset = vtOffSetPrj.length(); if (!vtEnd.crossProduct(vtOffSetPrj).isCodirectionalTo(vtNormal)) dOffset *= -1; double dPlusEdge(0.0); // 端部直边段 AecHvac::HvacReduComType eComType = AecHvac::eAuto; if (csComType == _T("角度")) eComType = AecHvac::eAngle; else if (csComType == _T("长度")) eComType = AecHvac::eLength; AecDbHvacFitting* pReduce = new AecDbHvacFitting; pReduce->setLayer(idMainLayer); pReduce->SetDoubleLayer(idMainLayer); pReduce->SetDashLayer(idHideLayer); pReduce->SetCenterLayer(idBaseLayer); AecDbObjXDataMap* pMapReduce = pReduce->GetSpecialtyData(); if (NULL == pMapReduce) { delete pReduce; pReduce = NULL; return; } pMapReduce->SetAt(HRED_StartSectType, (int &)eStartSect); pMapReduce->SetAt(HRED_EndSectType, (int &)eEndSect); pMapReduce->SetAt(KEY_SECSHAPE, (int &)eStartSect); pMapReduce->SetAt(KEY_FITSRV, KEY_FITHVAC); pMapReduce->SetAt(KEY_RUNTIME, eReduce); pMapReduce->SetAt(HVAC_System, csSysName); pMapReduce->SetAt(HVAC_Material, csMatName); // 设置数据 pMapReduce->SetAt(HRED_StartPoint, ptCon1); ptCon1 += vtOffSet; ptCon1 += dLen * vtEnd; pMapReduce->SetAt(HRED_EndPoint, ptCon1); pMapReduce->SetAt(HVAC_IsSingleLine, bSingleLine); pMapReduce->SetAt(HVAC_HasBaseLine, bBaseLine); pMapReduce->SetAt(HVAC_EdgeWeight, bEdgeWeigh); pMapReduce->SetAt(HVAC_EdgeWidth, dEdgeWidth); pMapReduce->SetAt(HVAC_CentWeight, bCentWeigh); pMapReduce->SetAt(HVAC_CentWidth, dCentWidth); pMapReduce->SetAt(HVAC_EndWidth, dSideWidth); pMapReduce->SetAt(HVAC_EndLayer, idEndLayer, FALSE); pMapReduce->SetAt(HVAC_PlusEdge, dPlusEdge); pMapReduce->SetAt(KEY_NORMAL, vtNormal); pMapReduce->SetAt(HRED_StartWidth, dStaWidth); pMapReduce->SetAt(HRED_EndWidth, dEndWidth); pMapReduce->SetAt(HRED_StartThick, dStartThick); pMapReduce->SetAt(HRED_EndThick, dEndThick); pMapReduce->SetAt(HRED_StartSectType, eStartSect); pMapReduce->SetAt(HRED_EndSectType, eEndSect); pMapReduce->SetAt(HRED_StartDir, vtRedSta); pMapReduce->SetAt(HRED_ComputeType, eComType); pMapReduce->SetAt(HRED_Offset, vtOffSet); pMapReduce->SetAt(HRED_Angle, dAngle); pMapReduce->SetAt(HRED_Length, dLen); arrFit.append(pReduce); // 改变末端连接的管的首尾点位置 AcGePoint3d ptConEnd, ptNewDuct; pMapReduce->GetAt(HRED_EndPoint, ptConEnd); ptNewDuct = ptConEnd; // 取得数据参数容器,加入数据参数 if (ptTempCon2 == ptSta2) { pDuct2->SetStartPoint(ptNewDuct); } else if (ptTempCon2 == ptEnd2) { pDuct2->SetEndPoint(ptNewDuct); } } //添加变径 void HA_TJBJCmdFnc() { ads_name ss,ent; struct resbuf* pRb = acutBuildList(RTDXF0, _T("AEC_DBDUCT,AEC_DBHVACFIT"), 0); int nRes = CKTCadUtility::SelectEntities(_T("\n请框选两个平行的风管或一个风管和一个管件<退出>:"), ss,pRb); acutRelRb(pRb); if ( RTNORM == nRes) { AcDbVoidPtrArray arrFit; AecDbHvacFitting* pFit = NULL; Adesk::Int32 nLen = 0; acedSSLength(ss,&nLen); if (nLen < 2) { acedSSFree(ss); acutPrintf(_T("\n必须选择两个风管实体!")); return; } AecHvac::DuctParam param; memset(¶m,0,sizeof(AecHvac::DuctParam)); AcDbObjectId id; AcArray ssEnts; for (int i = 0;i < nLen;i++) { acedSSName(ss,i,ent); acdbGetObjectId(id,ent); AcDbEntity* pEnt = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead)) { AecDbHvacFitting* pFit = AecDbHvacFitting::cast(pEnt); if (pFit != NULL) { pFit->GetDuctParam(param); AecDbObjXDataMap* pXData = pFit->GetSpecialtyData(AcDb::kForRead); if (pXData != NULL) { EFittingType eKind = ePipe; pXData->GetAt(KEY_RUNTIME, (int&)eKind); if (eKind == eReduce ) { pEnt->close(); continue; } } IDName idName; idName.id = id; _tcscpy(idName.szName,_T("AEC_DBHVACFIT")); ssEnts.append(idName); } AecDbHvacDuct* pDuct = AecDbHvacDuct::cast(pEnt); if (pDuct != NULL) { pDuct->GetDuctParam(param); IDName idName; idName.id = id; _tcscpy(idName.szName,_T("AEC_DBDUCT")); ssEnts.append(idName); } pEnt->close(); } } acedSSFree(ss); if (ssEnts.length() < 2) { acutPrintf(_T("\n必须选择两个风管实体!")); return; } CAcModuleResourceOverride myResources; CHFitingStyleDlg dlg(1,param.eType); if (IDOK != dlg.DoModal() ) { return; } int nSelRet = SortSelectEnts(ssEnts); if (nSelRet == -1) { acutPrintf(_T("\n选择类型不正确!")); return; } else if (nSelRet == 0) // 两风管 { OPENOBJ_BEGIN(ssEnts[0].id, AcDb::kForWrite, AecDbHvacDuct, pDuct1); if (NULL != pDuct1) { OPENOBJ_BEGIN(ssEnts[1].id, AcDb::kForWrite, AecDbHvacDuct, pDuct2); if (NULL != pDuct2) { CString csError = CheckDuctAddRecValid(pDuct1, pDuct2); // 连接有效性判断 if (!csError.IsEmpty()) acutPrintf(csError); else // 进行连接 GetFit(pDuct1, pDuct2,arrFit,&dlg); } OPENOBJ_END(); } OPENOBJ_END(); } else if (nSelRet == 1) // 管件跟风管(不包括变径和法兰) { OPENOBJ_BEGIN(ssEnts[0].id, AcDb::kForRead, AecDbHvacFitting, pFitting); if (NULL != pFitting) { OPENOBJ_BEGIN(ssEnts[1].id, AcDb::kForWrite, AecDbHvacDuct, pDuct); if (NULL != pDuct) { CString csError = CheckFitAndDuctValid(pFitting, pDuct); // 连接有效性判断 if (!csError.IsEmpty()) acutPrintf(csError); else // 进行连接 GetFit(pFitting, pDuct,&dlg,arrFit); } OPENOBJ_END(); } OPENOBJ_END(); } for (int i = 0; i < arrFit.length(); i++) { pFit = (AecDbHvacFitting*)arrFit[i]; if (NULL != pFit) { CoreTools::AddToModelSpace(pFit); } } } } //合并风管 void HA_HBFGCmdFnc() { ads_name ss,ent1,ent2; struct resbuf* pRb = acutBuildList(RTDXF0, DXF_PIPE, 0); int nRes = CKTCadUtility::SelectEntities(_T("\n请框选两个平行共线同属性的风管:"), ss,pRb); acutRelRb(pRb); if ( RTNORM == nRes) { Adesk::Int32 nLen = 0; acedSSLength(ss,&nLen); if (nLen == 2) { AcDbObjectId id1,id2; acedSSName(ss,0,ent1); acdbGetObjectId(id1,ent1); acedSSName(ss,1,ent2); acdbGetObjectId(id2,ent2); AcDbEntity* pEnt1 = NULL; AcDbEntity* pEnt2 = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForWrite)) { if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,id2,AcDb::kForWrite)) { AecDbHvacDuct* pDuct1 = AecDbHvacDuct::cast(pEnt1); AecDbHvacDuct* pDuct2 = AecDbHvacDuct::cast(pEnt2); if (pDuct1 != NULL && pDuct2 != NULL) { AcGeVector3d vt1 = pDuct1->GetTailDir(); AcGeVector3d vt2 = pDuct2->GetTailDir(); AecHvac::DuctParam data1,data2; memset(&data1,0,sizeof(AecHvac::DuctParam)); memset(&data2,0,sizeof(AecHvac::DuctParam)); pDuct1->GetDuctParam(data1); pDuct2->GetDuctParam(data2); if ( vt1.isParallelTo(vt2) && //平行 fabs(data1.m_dEl - data2.m_dEl) < 1.e-3 && //标高 fabs(data1.dSize[0] - data2.dSize[0]) < 1.e-3 && //尺寸 fabs(data1.dSize[1] - data2.dSize[1]) < 1.e-3 ) { AcGePoint3d ptS1 = pDuct1->StartPoint(); AcGePoint3d ptE1 = pDuct1->EndPoint(); AcGePoint3d ptS2 = pDuct2->StartPoint(); AcGePoint3d ptE2 = pDuct2->EndPoint(); AcGePoint3dArray arPts; arPts.append(ptS1); arPts.append(ptE1); if (arPts.find(ptS2) == -1) arPts.append(ptS2); if (arPts.find(ptE2) == -1) arPts.append(ptE2); AcDbLine ln(ptS1,ptE1); SortPoints(arPts,&ln); pDuct1->SetStartPoint(arPts.first()); pDuct1->SetEndPoint(arPts.last()); pDuct2->erase(); } else { acutPrintf(_T("\n选择的两个风管实体几何属性不一致!")); } } pEnt2->close(); } pEnt1->close(); } } else { acutPrintf(_T("\n必须选择两个风管实体!")); } } acedSSFree(ss); } //风管标注 void HA_FBBZCmdFnc() { ads_name ent1; ads_point pt1, pt2; struct resbuf* pRb = acutBuildList(RTDXF0, DXF_PIPE, 0); int nRes = CKTCadUtility::SelectEntity(_T("\n请选择要标注的风管:"), ent1, pRb, pt1); acutRelRb(pRb); if (nRes == RTNORM) { nRes = acedGetPoint(pt1, _T("\n请选择位置:"), pt2); if (nRes == RTNORM) { ads_point pt11, pt22; acdbUcs2Wcs(pt1, pt11, false); acdbUcs2Wcs(pt2, pt22, false); AcGePoint3d ptFr = asPnt3d(pt11); AcGePoint3d ptTo = asPnt3d(pt22); AcDbObjectId id1; acdbGetObjectId(id1, ent1); // AecHvac::DuctParam param; BOOL bGetParam = FALSE; AcDbEntity* pEnt = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,id1,AcDb::kForRead)) { AecDbHvacDuct* pDuct = AecDbHvacDuct::cast(pEnt); if (pDuct != NULL) { pDuct->GetDuctParam(param); bGetParam = TRUE; } /* AecDbHvacFitting* pFit = AecDbHvacFitting::cast(pEnt); if (pFit != NULL) { pFit->GetDuctParam(param); bGetParam = TRUE; }*/ pEnt->close(); } if (bGetParam) { LPCTSTR pszAirload[] = {_T("kg/h"),_T("kg/s"),_T("m^3/h"),_T("m^3/s"),_T("L/h"),_T("L/s"),0}; //Wxh mm V=*m/s Q=*m3 B=*m CString sDimUp; if (param.eType == eRect) { sDimUp.Format(_T("%dx%dmm V=%.2fm/s Q=%.2f%s"),(int)(param.dSize[0]+0.5),(int)(param.dSize[1]+0.5), param.m_dV,param.dAirload,pszAirload[param.iALUnit]); } else if (param.eType == eCircle) { sDimUp.Format(_T("D=%dmm V=%.2fm/s Q=%.2f%s"),(int)(param.dSize[0]+0.5), param.m_dV,param.dAirload,pszAirload[param.iALUnit]); } else { acutPrintf(_T("\n其他类型截面的风管标注待定...")); return; } AcDbObjectId idDimLay = KTSetting::InitLayer(gLayer_Pipe_Dim); AcDbObjectId idTSty = CKTCadUtility::InitTextStyle(gTextStyle_Pipe_Dim); AecDbEwPipeDim* pDim = new AecDbEwPipeDim; pDim->AddAecDbWEntity(id1); pDim->SetDimStyle(0); pDim->SetDimDir(0); pDim->SetDimTextUporDownFlag(1); pDim->SetTextStyleId(idTSty); pDim->SetTextLayerId(idDimLay); pDim->SetPScale(100.0); pDim->SetDimTextUporDownFlag(0); pDim->AddDimText(sDimUp,_T("")); pDim->SetTextHeight(2.5); pDim->SetTextWidthScale(0.75); pDim->AppendPoint(ptFr); pDim->AppendPoint(ptTo); pDim->SetDimupdownSpace(0.0); pDim->SetTextLayerId(idDimLay); CoreTools::AddToModelSpace(pDim); } } } } extern bool DLLIMPEXP GetPipeNetNodes(const AcDbObjectId &id1, AcDbObjectIdArray &arNetIds, const AcDbObjectId &id0, const AcDbObjectId &id2); extern bool DLLIMPEXP GetPipeNetNodes(const AcDbObjectId &id1, AcDbObjectIdArray &arNetIds, BOOL bTeeStop, BOOL bCrossStop,BOOL bReducerStop); void DBL_FGBGCmdFnc() { //弹出对话框 CAcModuleResourceOverride myResources; CGJXGDlg dlg; if (IDOK != dlg.DoModal()) return; //选择管线,管件 struct resbuf *pRb = acutBuildList(RTDXF0, DXF_PIPE_ONLY, 0); ads_name ent1; int nRes = CKTCadUtility::SelectEntity(_T("\n请选择要改尺寸的管线:"), ent1, pRb); if (nRes == RTNORM) { AcDbObjectId id1; acdbGetObjectId(id1, ent1); //获取管网 AcDbObjectIdArray arNetIds; GetPipeNetNodes(id1, arNetIds, dlg.m_bTeeStop, dlg.m_bCrossStop,TRUE); AcDbEntity *pEnt = NULL; for (int i = 0; i < arNetIds.length(); i++) { if (Acad::eOk == acdbOpenAcDbEntity(pEnt, arNetIds.at(i), AcDb::kForWrite)) { pEnt->highlight(); pEnt->close(); } } TCHAR szDummy[133]; nRes = acedGetString(0, _T("\n按 确认修改."), szDummy); if (nRes != RTNORM) { for (int i = 0; i < arNetIds.length(); i++) { if (Acad::eOk == acdbOpenAcDbEntity(pEnt, arNetIds.at(i), AcDb::kForRead)) { pEnt->unhighlight(); pEnt->close(); } } acutRelRb(pRb); //解锁所有的Fit for (int i = 0; i < arNetIds.length(); i++) { if (Acad::eOk == acdbOpenAcDbEntity(pEnt, arNetIds.at(i), AcDb::kForWrite)) { AecDbHvacFitting *pFit = AecDbHvacFitting::cast(pEnt); if (pFit != NULL) { pFit->LockInf(-1); } pEnt->close(); } } return; } AcDbObjectIdArray arFitIds, arPipeIds, arEquIds; bool bFitPosLock = false; AcGePoint3dArray arFitInfPts; //acutPrintf(_T("\n%d:%s"),nRes,szDummy); for (int i = 0; i < arNetIds.length(); i++) { if (Acad::eOk == acdbOpenAcDbEntity(pEnt, arNetIds.at(i), AcDb::kForRead)) { //分出管子和管件 AecDbHvacDuct *pWpipe = AecDbHvacDuct::cast(pEnt); if (pWpipe != NULL) { arPipeIds.append(arNetIds.at(i)); } AecDbHvacFitting *pFit = AecDbHvacFitting::cast(pEnt); if (pFit != NULL) { arFitIds.append(arNetIds.at(i)); int nType = -1; pFit->GetSpecialtyData()->GetAt(KEY_RUNTIME, nType); EFittingType eType = (EFittingType)nType; if (eType == eElbow || eType == eTee || eType == eReduce || eType == eOffset || eType == eCross) { AcArray arInfs; pFit->GetInterface(arInfs); for (int ii = 0; ii < arInfs.length(); ii++) { AecInterface &inf = arInfs.at(ii); if (arFitInfPts.find(inf.ptPos) == -1) { arFitInfPts.append(inf.ptPos); } else { bFitPosLock = true; } } } } AecDbEwEquipment *pEqu = AecDbEwEquipment::cast(pEnt); if (pEqu != NULL) { arEquIds.append(arNetIds.at(i)); } pEnt->unhighlight(); pEnt->close(); } } //判断弯头接弯头的定位位置锁定情况 if (bFitPosLock) { CAcModuleResourceOverride rcTmp; CFITLockedDlg fitDlg; fitDlg.DoModal(); //acedAlert(_T("选择的管线存在弯头三通四通相互连接定位位置锁定!不可管线变更!")); return; } //弹出对话框 AecHvac::DuctParam param; memset(¶m, 0, sizeof(AecHvac::DuctParam)); if (Acad::eOk == acdbOpenAcDbEntity(pEnt, id1, AcDb::kForRead)) { AecDbHvacDuct *pPipe = AecDbHvacDuct::cast(pEnt); if (pPipe != NULL) { pPipe->GetDuctParam(param); } pEnt->close(); } //上一切换 CFGBZDlg drawCnfgDLg; drawCnfgDLg.EnableLoadLast(FALSE); drawCnfgDLg.LockEl(true);//锁定标高 drawCnfgDLg.SetShowParam(param); drawCnfgDLg.SetAlignEnable(FALSE);//锁定对齐 int nRes = drawCnfgDLg.DoModal(); if (nRes == IDOK) { AecHvac::DuctParam paramNew; memset(¶mNew, 0, sizeof(AecHvac::DuctParam)); drawCnfgDLg.GetPipeParam(¶mNew); AecPipeLineModify pipeModify; pipeModify.m_bTeeStop = dlg.m_bTeeStop; pipeModify.m_bCrossStop = dlg.m_bCrossStop; pipeModify.m_bElLock = true; pipeModify.SetPipeParamOld(¶m); pipeModify.SetPipeNetIds(arNetIds); //设置undo标记 SHacedCommand(RTSTR, _T("_undo"), RTSTR, _T("BE"), RTNONE); if (pipeModify.ModifyPipeLineParam(arPipeIds, arFitIds, arEquIds, paramNew, FALSE)) { pipeModify.AddjustTInfAssoc(); SHacedCommand(RTSTR, _T("_undo"), RTSTR, _T("E"), RTNONE); } else { SHacedCommand(RTSTR, _T("_undo"), RTSTR, _T("B"), RTNONE); } } } acutRelRb(pRb); CoreTools::refreshGraphics(); } //管道风机 void HA_GDFJCmdFnc() { } //布置设备 void HA_BZSBCmdFnc() { } //空气机组 void HA_KQJZCmdFnc() { } void DBL_AEC_DBDUCT() { AcDbObjectId id; bool bIsOk = GetDoubleClickEnt(_T("DBL_AEC_DBDUCT"),id); if (bIsOk && id.isValid()) { AcGePoint3d ptS; AcGePoint3d ptE; AcGeVector3d vt; AecHvac::DuctParam param; memset(¶m,0,sizeof(AecHvac::DuctParam)); BOOL bGetParam = FALSE; AcDbEntity* pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead)) { AecDbHvacDuct* pPipe = AecDbHvacDuct::cast(pEnt); if (pPipe != NULL) { pPipe->GetDuctParam(param); //调节为管顶标高 /*if (param.eType == eCircle) param.m_dEl += 0.5 * param.dSize[0]; else param.m_dEl += 0.5 * param.dSize[1]; */ ptS = pPipe->StartPoint(); ptE = pPipe->EndPoint(); vt = ptE - ptS; bGetParam = TRUE; } pEnt->close(); } if (bGetParam) { bool bIsXElPipe = false; double dElOld = param.m_dEl; AcGeLine3d ln(ptS,vt); if (!ln.isParallelTo(AcGePlane::kXYPlane)) { bIsXElPipe = true; } CAcModuleResourceOverride myResources; CFGBZDlg drawCnfgDLg; drawCnfgDLg.EnableLoadLast(FALSE); drawCnfgDLg.SetShowParam(param); drawCnfgDLg.LockEl(bIsXElPipe);//锁定标高 drawCnfgDLg.SetAlignEnable(FALSE);//锁定对齐 int nRes = drawCnfgDLg.DoModal(); if (nRes == IDOK) { memset(¶m,0,sizeof(AecHvac::DuctParam)); drawCnfgDLg.GetPipeParam(¶m); if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite)) { AecDbHvacDuct* pPipe = AecDbHvacDuct::cast(pEnt); if (pPipe != NULL) { pPipe->SetDuctParam(¶m); AecDbObjXDataMap *pNewMap = pPipe->GetSpecialtyData(); pNewMap->SetAt(HDCT_Width, param.dSize[0]); pNewMap->SetAt(HDCT_Thick, param.dSize[1]); } pEnt->close(); if ( fabs( param.m_dEl - dElOld ) > 1.e-2)//标高改动 { //发送管口改动消息 AcGeVector3d vtOffset(0,0,param.m_dEl - dElOld); GripMessage msg; //reset msg.nSegindex = -1; msg.nType = -1; msg.idHost.setNull(); msg.pParam = 0; msg.nData = -1; _tcscpy(msg.szLockId, _T("0"));//锁定id,如果有 msg.fData = 0; msg.nSegindex = 0; msg.nSubSegIndex = 0; msg.vtOffset.set(0,0,0); msg.ptGrip.set(0,0,0); msg.nType = eMid; msg.nData = -1; msg.idHost = id; msg.vtOffset = vtOffset; PushGripMessage(msg); } } } } } } void DBL_AEC_DBHVACFIT() { AcDbObjectId id; bool bIsOk = GetDoubleClickEnt(_T("DBL_AEC_DBHVACFIT"),id); if (bIsOk && id.isValid()) { AecHvac::DuctParam param; memset(¶m,0,sizeof(AecHvac::DuctParam)); int nKind = -1; BOOL bIsHvacFit = FALSE; AcDbEntity* pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead)) { AecDbHvacFitting* pFit = AecDbHvacFitting::cast(pEnt); if (pFit != NULL) { pFit->GetDuctParam(param); bIsHvacFit = TRUE; pFit->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_RUNTIME, nKind); } pEnt->close(); } if (bIsHvacFit) { int nFitType = -1; switch(nKind) { case eElbow: { nFitType = 0; break; } case eReduce: { nFitType = 1; break; } break; case eTee: { nFitType = 2; break; } case eCross: { nFitType = 3; break; } case eOffset: { nFitType = 5; break; } default: break; } if (nFitType != -1) { CAcModuleResourceOverride myResources; CHFitingStyleDlg dlg(nFitType,param.eType,id); if (IDOK == dlg.DoModal() ) { int nFitCode = dlg.GetFitCode(); //不改变接口点,只改变样式 if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite)) { AecDbHvacFitting* pFit = AecDbHvacFitting::cast(pEnt); if (pFit != NULL) { switch(nKind) { case eElbow: { //AecHvac::eAllArcuate pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HELB_Type,nFitCode); break; } case eReduce: { //待定 acutPrintf(_T("\n变径样式不可替换!")); break; } break; case eTee: { AcArray arTInfLast; pFit->GetInterface(arTInfLast); AecHvac::HvacTeeType eTeeTypeLast = AecHvac::eOrthoBranch; pFit->GetSpecialtyData(AcDb::kForRead)->GetAt(HTEE_Type, (int &)eTeeTypeLast); ESection eSect = eRect; pFit->GetSpecialtyData(AcDb::kForWrite)->GetAt(HVAC_SectType, (int &)eSect); //this pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HTEE_Type,nFitCode); if (dlg.m_bFloorDir) { AcGePoint3d ptStart, ptEnd; pFit->GetSpecialtyData(AcDb::kForWrite)->GetAt(HTEE_StartPoint, ptStart); pFit->GetSpecialtyData(AcDb::kForWrite)->GetAt(HTEE_EndPoint, ptEnd); AcGeVector3d vtSta,vtEnd; pFit->GetSpecialtyData(AcDb::kForWrite)->GetAt(HTEE_StartDir, vtSta); pFit->GetSpecialtyData(AcDb::kForWrite)->GetAt(HTEE_EndDir, vtEnd); pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HTEE_StartDir, vtEnd); pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HTEE_EndDir, vtSta); pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HTEE_StartPoint, ptEnd); pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HTEE_EndPoint, ptStart); } AcArray arTInfThis; pFit->GetInterface(arTInfThis); AecHvac::HvacTeeType eTeeTypeThis = (AecHvac::HvacTeeType)nFitCode; if (eSect == eCircle)//首先必须是圆型 { //接口更新 CHVACFittingToolkit::UpdateTeeInfAssoc(pFit, arTInfLast, arTInfThis, eTeeTypeLast, eTeeTypeThis, dlg.m_bFloorDir); } break; } case eCross: { pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HCRS_Type,nFitCode); if (dlg.m_bFloorDir) { AcGePoint3d ptStart, ptEnd; pFit->GetSpecialtyData(AcDb::kForWrite)->GetAt(HCRS_StartPoint, ptStart); pFit->GetSpecialtyData(AcDb::kForWrite)->GetAt(HCRS_EndPoint, ptEnd); AcGeVector3d vtSta, vtEnd; pFit->GetSpecialtyData(AcDb::kForWrite)->GetAt(HCRS_StartDir, vtSta); pFit->GetSpecialtyData(AcDb::kForWrite)->GetAt(HCRS_EndDir, vtEnd); pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HCRS_StartDir, vtEnd); pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HCRS_EndDir, vtSta); pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HCRS_StartPoint, ptEnd); pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HCRS_EndPoint, ptStart); } break; } case eOffset: { pFit->GetSpecialtyData(AcDb::kForWrite)->SetAt(HOFF_Type,nFitCode); break; } default: break; } pFit->ReCreateDraw2d(); pFit->ReCreateDraw3d(); } pEnt->close(); } } } } } }