#include "StdAfx.h" #include "StdArx.h" #include "resource.h" #include "KTPIDPipeParamDlg.h" #include "KTPIDPipeOper.h" #include "DLGArribtEdit.h" #include "KTPIDInstLineDlg.h" #include "LineNumDlg.h" #include "coretools.h" #include #define LAYER_MAJOR1 _T("LAY_MAJOR1") #define LAYER_MAJOR2 _T("LAY_MAJOR2") #define LAYER_MINOR1 _T("LAY_MINOR1") #define LAYER_MINOR2 _T("LAY_MINOR2") #define LAYER_INST_1 _T("LAY_INSTRUMENT") #define LAYER_INSULA _T("LAY_INSULATION") #define LAYER_JACKET _T("LAY_JACKET") #define PID_LINETYPE_DEF _T("AcadIso.lin") #define PID_LINETYPE_FILE _T("KTPID.lin") #define DEBUG_INFO(format, ...) acutPrintf(_T("\nFile:%s, Line:%d, Function:%s, %s"),\ CString(__FILE__), __LINE__ , CString(__FUNCTION__), ##__VA_ARGS__); namespace { void drawCircle(const AcGePoint3d &pt, const double &r = 10, const int &clr = 2) { AcDbCircle *pC = new AcDbCircle(pt, AcGeVector3d::kZAxis, r); pC->setColorIndex(clr); CKTCadUtility::AddToCurrentSpace(pC); pC->close(); } void ResetXDataMap(AecDbObjXDataMap &xDataMap) { xDataMap.SetAt(DOC_PIDTRADE, WPipe::ePetro); //应用行业,石油 xDataMap.SetAt(DOC_PIDSCRIPTT, _T("{0}{-}{1}{-}{2}{-}{3}"));//上标脚本 xDataMap.SetAt(DOC_PIDSCRIPTB, _T("{4}{-}{5}"));//下标脚本 xDataMap.SetAt(DOC_PIDBSPACE, 3.0); //交叉断线间距 xDataMap.SetAt(DOC_PIDEWITHDIM, TRUE); //设备插入标注 xDataMap.SetAt(DOC_PIDVWITHDIM, TRUE); //阀门插入标注 xDataMap.SetAt(DOC_PIDINSRDN, 12); //仪表泡直径 xDataMap.SetAt(DOC_CONSIGN, 30.0); //续接符号 xDataMap.SetAt(DOC_PIDBARROW, 6.0); //大箭头 xDataMap.SetAt(DOC_PIDEQPTXTH, 3.5); //设备标注文字高度 xDataMap.SetAt(DOC_PIDEQPTXTF, 1.0); //设备文字宽度系数 xDataMap.SetAt(DOC_PIDMARROW, 3.0); //中箭头 xDataMap.SetAt(DOC_PIDSARROW, 1.5); //小箭头 xDataMap.SetAt(DOC_PIDVALVTXTH, 3.5); //阀门文字高度 xDataMap.SetAt(DOC_PIDVALVTXTF, 1.0); //阀门文字宽度系数 xDataMap.SetAt(DOC_PIDDIMTXTH, 3.5); //标注文字高度 xDataMap.SetAt(DOC_PIDDIMTXTF, 1.0); //标注文字宽度系数 xDataMap.SetAt(DOC_EQUSCALE, 6.0); //设备比例 xDataMap.SetAt(DOC_LINEARSCALE, 10.0); //线性比例 xDataMap.SetAt(DOC_PIDMPIPE1W, 1.0); //主管道线宽1 xDataMap.SetAt(DOC_PIDMPIPE2W, 0.5); //主管道线宽2 xDataMap.SetAt(DOC_NODESCALE, 6.0); //管嘴比例 xDataMap.SetAt(DOC_PIDSPIPE1W, 0.25); //次管道线宽1 xDataMap.SetAt(DOC_PIDSPIPE2W, 0.125); //次管道线宽2 xDataMap.SetAt(DOC_VALVESCALE, 100.0); //阀门比例 xDataMap.SetAt(DOC_PIDUNIT, 0); //单位 xDataMap.SetAt(DOC_PIDDIMTERM, 0); //标注端符 } void DefaultPIDParam(PID::PIDPipeParam * pPidparam) { if (pPidparam != NULL) { pPidparam->m_dDN = 100.0; _tcscpy(pPidparam->m_pszInchDN, _T("4\"")); _tcscpy(pPidparam->m_pszZone, _T("1")); _tcscpy(pPidparam->m_pszNo, _T("1000")); _tcscpy(pPidparam->m_pszDesc, _T("工艺空气")); _tcscpy(pPidparam->m_pszMedia, _T("PA")); _tcscpy(pPidparam->m_pszLevel, _T("1.6A1")); _tcscpy(pPidparam->m_pszLineNo, _T("PA-1000")); _tcscpy(pPidparam->m_pszInsTag, _T("ST1")); _tcscpy(pPidparam->m_pszInsTagDim, _T("S")); pPidparam->m_nTraType = 0; pPidparam->m_dCoverSpace = 0.0; pPidparam->m_dHeatThick = 0.0; } } void GetLastPIDParam(PID::PIDPipeParam * pPidparam) { if (pPidparam != NULL) { KTPIDPipeOper::ReadPIDParamFromModel(pPidparam); } } int BreakParamCompare(const void *pParam1, const void *pParam2) { return ((((PID::CBreakParam*)pParam1)->dParam < ((PID::CBreakParam*)pParam2)->dParam) ? -1 : ((((PID::CBreakParam*)pParam2)->dParam < ((PID::CBreakParam*)pParam1)->dParam) ? 1 : 0)); } int ConnectParamCompare(const void *pParam1, const void *pParam2) { return ((((PID::CConnectData*)pParam1)->dParam < ((PID::CConnectData*)pParam2)->dParam) ? -1 : 1); } BOOL FindPipePlines(const AcDbObjectId& idPline , AcDbObjectIdArray& arid , double& dLeftWidth , double& dRightWidth) { arid.append(idPline); dLeftWidth = dRightWidth = 0.0; AcDbPolyline* pPline = NULL; acdbOpenObject(pPline, idPline, AcDb::kForRead); if (NULL == pPline) return FALSE; if (2 > pPline->numVerts()) { pPline->close(); return FALSE; } AcGePoint3d pt1, pt2; pPline->getPointAt(0, pt1); pPline->getPointAt(1, pt2); AcGeLine3d line(pt1, pt2); AcGeVector3d vt1(pt2 - pt1); AcGeVector3d vt2 = pPline->normal(); pPline->close(); AcDbObjectIdArray aridGroup; if (0 < CKTCadUtility::GetItemGroups(idPline, aridGroup)) CKTCadUtility::GetGroupItems(aridGroup[0], arid); double dAngle, dDist; AcGePoint3d pt3, pt4; int iPos = arid.length(); while ((--iPos) >= 1) { if (arid[iPos] == idPline) { arid.removeAt(iPos); continue; } if (Acad::eOk != acdbOpenObject(pPline, arid[iPos], AcDb::kForRead)) { arid.removeAt(iPos); continue; } pPline->getPointAt(0, pt3); pPline->close(); pt4 = line.closestPointTo(pt3); dAngle = vt1.angleTo(pt3 - pt4, vt2); if (dAngle < PI) { dDist = pt3.distanceTo(pt4); if (dLeftWidth < dDist) dLeftWidth = dDist; } else { dDist = -pt3.distanceTo(pt4); if (dRightWidth > dDist) dRightWidth = dDist; } } return TRUE; } BOOL CreatePolyline(AcDbObjectIdArray& arid , LPCTSTR pszLayer , LPCTSTR pszLType = NULL , int iColor = PID::kColorByLayer , double dWidth = 0 , PID::CPlineDataArray* parPlineData = NULL) { ads_point ptAdsBase; int iRet = acedGetPoint(NULL, _T("\n请选择起点:"), ptAdsBase); if (RTNORM != iRet) return FALSE; AcGePoint3d ptBase; acdbUcs2Wcs(ptAdsBase, asDblArray(ptBase), false); AcDbObjectId idLayer = KTSetting::InitLayer(pszLayer); AcGeVector3d vtNormal(UcsZAxis); AcGePlane plane(AcGePoint3d::kOrigin, vtNormal); AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase(); ASSERT(NULL != pDb); // 主管 AcDbPolyline* pPline = new AcDbPolyline; ASSERT(NULL != pPline); double dElev = plane.distanceTo(UcsOrigin); pPline->setNormal(vtNormal); pPline->setElevation(dElev); pPline->setConstantWidth(dWidth); pPline->setLayer(idLayer); pPline->setColorIndex(iColor); if (NULL != pszLType) { // 分解"线型路径及文件\线型"格式 TCHAR szPathName[MAX_PATH]; LPCTSTR pszType = _tcsrchr(pszLType, _T('\\')); if (NULL == pszType) { _tcscpy(szPathName, PID_LINETYPE_DEF); pszType = pszLType; } else { iRet = pszType - pszLType; _tcsncpy(szPathName, pszLType, iRet); szPathName[iRet] = 0; pszType++; } CString strLinFile(FilePath::GetSysDir() + _T("\\")); strLinFile += szPathName; pDb->loadLineTypeFile(pszType, strLinFile); pPline->setLinetype(pszType); } AcGePoint2d pt2d(ptBase.convert2d(plane)); pPline->addVertexAt(0, pt2d); AcDbObjectId idPline; if (Acad::eOk != CKTCadUtility::AddToCurrentSpace(pPline, idPline)) { delete pPline; return FALSE; } pPline->close(); pPline = NULL; // 伴管 int iPos; PID::CPLineData* pData; if (NULL != parPlineData) { iPos = parPlineData->length(); while ((--iPos) >= 0) { pData = &((PID::CPLineData&)parPlineData->operator [](iPos)); ASSERT(NULL != pData); ASSERT(NULL == pData->pPline); pData->pPline = new AcDbPolyline; ASSERT(NULL != pData->pPline); pData->pPline->setNormal(vtNormal); pData->pPline->setElevation(dElev); pData->pPline->setConstantWidth(pData->dWidth); pData->pPline->setLayer(KTSetting::InitLayer(pData->pszLayer)); pData->pPline->setColorIndex(pData->iColor); if (NULL != pData->pszLType) { // 分解"线型路径及文件\线型"格式 TCHAR szPathName[MAX_PATH]; LPCTSTR pszType = _tcsrchr(pData->pszLType, _T('\\')); if (NULL == pszType) { _tcscpy(szPathName, PID_LINETYPE_DEF); pszType = pData->pszLType; } else { iRet = pszType - pData->pszLType; _tcsncpy(szPathName, pData->pszLType, iRet); szPathName[iRet] = 0; pszType++; } CString strLinFile(FilePath::GetSysDir() + _T("\\")); strLinFile += szPathName; pDb->loadLineTypeFile(pszType, szPathName); pData->pPline->setLinetype(pszType); } pData->pPline->addVertexAt(0, pt2d); if (Acad::eOk != CKTCadUtility::AddToCurrentSpace(pData->pPline, pData->id)) { delete pData->pPline; parPlineData->removeAt(iPos); } else { pData->pPline->close(); pData->pPline = NULL; } } } AcGeVector3d vtOff1, vtOff2; AcGeLine3d line1, line2; AcGePoint3d pt1, pt2, ptPrev, ptFar; int iIndex; BOOL bExtend; ads_point ptAdsNext; while (TRUE) { acedInitGet(0, _T("Undo")); iRet = acedGetPoint(ptAdsBase, _T("\n请选择下一点或 [放弃(U)]:"), ptAdsNext); if (Acad::eOk != acdbOpenObject(pPline, idPline, AcDb::kForWrite)) break; iIndex = pPline->numVerts(); if (RTNONE == iRet) { if (iIndex >= 2) { pPline->close(); break; } else { pPline->erase(); pPline->close(); if (NULL != parPlineData) { iPos = parPlineData->length(); while ((--iPos) >= 0) { pData = &((PID::CPLineData&)parPlineData->operator [](iPos)); ASSERT(NULL != pData); if (Acad::eOk != acdbOpenObject(pData->pPline, pData->id, AcDb::kForWrite)) continue; pData->pPline->erase(); pData->pPline->close(); } } } break; } if (RTKWORD == iRet) { iIndex--; if (iIndex > 0) { pPline->removeVertexAt(iIndex); pPline->getPointAt(iIndex - 1, ptBase); acdbWcs2Ucs(asDblArray(ptBase), ptAdsBase, false); pPline->getPointAt(iIndex - 2, ptPrev); vtOff1 = vtNormal.crossProduct(ptBase - ptPrev); vtOff1.normalize(); pPline->close(); if (NULL != parPlineData) { iPos = parPlineData->length(); while ((--iPos) >= 0) { pData = &((PID::CPLineData&)parPlineData->operator [](iPos)); ASSERT(NULL != pData); if (Acad::eOk != acdbOpenObject(pData->pPline, pData->id, AcDb::kForWrite)) continue; pData->pPline->removeVertexAt(iIndex); if (iIndex > 0) { pt1 = ptBase + vtOff1 * pData->dOffset; pData->pPline->setPointAt(iIndex - 1, pt1.convert2d(plane)); } pData->pPline->close(); } } } else { pPline->close(); acutPrintf(_T("\n已经撤销了所有线段。")); } continue; } if (RTNORM != iRet) { pPline->erase(); pPline->close(); if (NULL != parPlineData) { iPos = parPlineData->length(); while ((--iPos) >= 0) { pData = &((PID::CPLineData&)parPlineData->operator [](iPos)); ASSERT(NULL != pData); if (Acad::eOk != acdbOpenObject(pData->pPline, pData->id, AcDb::kForWrite)) continue; pData->pPline->erase(); pData->pPline->close(); } } return FALSE; } acdbUcs2Wcs(ptAdsNext, asDblArray(ptBase), false); pPline->getPointAt(iIndex - 1, ptPrev); vtOff1 = vtNormal.crossProduct(ptBase - ptPrev); vtOff1.normalize(); if (iIndex == 1) { pPline->addVertexAt(iIndex, ptBase.convert2d(plane)); } else { pPline->getPointAt(iIndex - 2, ptFar); bExtend = (ptBase - ptPrev).isParallelTo(ptBase - ptFar); if (bExtend) { pPline->setPointAt(iIndex - 1, ptBase.convert2d(plane)); } else { vtOff2 = vtNormal.crossProduct(ptPrev - ptFar); vtOff2.normalize(); pPline->addVertexAt(iIndex, ptBase.convert2d(plane)); } } pPline->close(); if (NULL != parPlineData) { iPos = parPlineData->length(); while ((--iPos) >= 0) { pData = &((PID::CPLineData&)parPlineData->operator [](iPos)); ASSERT(NULL != pData); if (Acad::eOk != acdbOpenObject(pData->pPline, pData->id, AcDb::kForWrite)) continue; if (iIndex == 1) { pt2 = ptBase + vtOff1 * pData->dOffset; pData->pPline->addVertexAt(iIndex, pt2.convert2d(plane)); pt1 = ptPrev + vtOff1 * pData->dOffset; pData->pPline->setPointAt(iIndex - 1, pt1.convert2d(plane)); } else { if (bExtend) { pt1 = ptBase + vtOff1 * pData->dOffset; pData->pPline->setPointAt(iIndex - 1, pt1.convert2d(plane)); } else { pt2 = ptBase + vtOff1 * pData->dOffset; pData->pPline->addVertexAt(iIndex, pt2.convert2d(plane)); line1.set(pt2, ptPrev + vtOff1 * pData->dOffset); line2.set(ptPrev + vtOff2 * pData->dOffset, ptFar + vtOff2 * pData->dOffset); line1.intersectWith(line2, pt1); pData->pPline->setPointAt(iIndex - 1, pt1.convert2d(plane)); } } pData->pPline->close(); } } ptAdsBase[X] = ptAdsNext[X]; ptAdsBase[Y] = ptAdsNext[Y]; ptAdsBase[Z] = ptAdsNext[Z]; } arid.append(idPline); if (NULL != parPlineData) { iPos = parPlineData->length(); while ((--iPos) >= 0) { pData = &((PID::CPLineData&)parPlineData->operator [](iPos)); ASSERT(NULL != pData); pData->pPline = NULL; arid.append(pData->id); } } return TRUE; } BOOL OnBreakPline(AcDbPolyline* pPline , const AcDbObjectIdArray& aridPline , double dLeftWidth , double dRightWidth , double dBreakSpace , PID::AcBreakParamArray& arParam , const int &brkStyle) { ASSERT(NULL != pPline && 0 < arParam.length() && 1 < pPline->numVerts()); // 将arParam在曲线上按参数值从小到大排序 int iPos = arParam.length(); if (2 > pPline->numVerts() || Acad::eOk != pPline->upgradeOpen()) return FALSE; qsort(arParam.asArrayPtr(), iPos, sizeof(PID::CBreakParam), BreakParamCompare); // 打开所有的裁减实体 AcArray arpPline; arpPline.append(pPline); AcDbPolyline* pPoly; int iIndex = aridPline.length(); while ((--iIndex) >= 1) // 第0个即为pPline { if (Acad::eOk != acdbOpenObject(pPoly, aridPline[iIndex], AcDb::kForWrite)) continue; arpPline.append(pPoly); } // 取得参数 AcGeVector3d vtNormal = pPline->normal(); AcGePlane plane(AcGePoint3d::kOrigin, vtNormal); // 从曲线的末尾开始裁减,末尾裁减出来的曲线为新曲线,前面的修改保留曲线继续裁减 AcGeVector3d vt; int iParam, iVert; PID::CBreakParam* pItem; AcDbPolyline* pNew; struct resbuf* pRb; AcDbObjectId idEnt; AcDbObjectIdArray arid; double dAngle, dWidth; AcGePoint3d pt1, pt2, pt3; while ((--iPos) >= 0) { pItem = &arParam[iPos]; ASSERT(NULL != pItem); // 判断在该点处曲线是否可以裁减(看是否裁超过拐点, 包括多线时) iParam = int(pItem->dParam); pPline->getPointAtParam(iParam, pt1); pPline->getPointAtParam(iParam + 1, pt2); vt = (pt2 - pt1).normal(); // 去除多线拐弯宽度 if (Acad::eOk == pPline->getPointAtParam(iParam - 1, pt3)) { dAngle = vt.angleTo(pt1 - pt3, vtNormal); pt1 += vt * fabs(dAngle > PI ? fabs(dLeftWidth) : fabs(dRightWidth)); } // 去除多线拐弯宽度 if (Acad::eOk == pPline->getPointAtParam(iParam + 2, pt3)) { dAngle = vt.angleTo(pt3 - pt2, vtNormal); pt2 -= vt * fabs(dAngle < PI ? fabs(dLeftWidth) : fabs(dRightWidth)); } // 判断是否够裁减, 并将pt1, pt2定位到断开位置 dAngle = vt.angleTo(pItem->vt, vtNormal); if (dAngle < PI) { if (pt1.distanceTo(pItem->pt) < max(fabs(pItem->dLeft), pItem->dWidth) + dBreakSpace || pt2.distanceTo(pItem->pt) < max(fabs(pItem->dRight), pItem->dWidth) + dBreakSpace) continue; pt1 = pItem->pt - vt * (max(fabs(pItem->dLeft), pItem->dWidth) + dBreakSpace); pt2 = pItem->pt + vt * (max(fabs(pItem->dRight), pItem->dWidth) + dBreakSpace); } else { if (pt1.distanceTo(pItem->pt) < max(fabs(pItem->dRight), pItem->dWidth) + dBreakSpace || pt2.distanceTo(pItem->pt) < max(fabs(pItem->dLeft), pItem->dWidth) + dBreakSpace) continue; pt1 = pItem->pt - vt * (max(fabs(pItem->dRight), pItem->dWidth) + dBreakSpace); pt2 = pItem->pt + vt * (max(fabs(pItem->dLeft), pItem->dWidth) + dBreakSpace); } // 裁减出曲线, 修改保留旧曲线 arid.setLogicalLength(0); iIndex = arpPline.length(); while ((--iIndex) >= 0) { pPoly = arpPline[iIndex]; ASSERT(NULL != pPoly); pPoly->getConstantWidth(dWidth); pRb = pPoly->xData(); if (brkStyle == 1) { AcDbPolyline *pArc = new AcDbPolyline; pArc->setNormal(pPoly->normal()); pArc->setElevation(pPoly->elevation()); pArc->setPropertiesFrom(pPoly); pArc->setConstantWidth(dWidth); if (pRb) pArc->setXData(pRb); pArc->addVertexAt(0, pt1.convert2d(plane), 1); pArc->addVertexAt(1, pt2.convert2d(plane)); CKTCadUtility::AddToCurrentSpace(pArc); pArc->close(); } pNew = new AcDbPolyline; ASSERT(NULL != pPoly); pNew->setNormal(pPoly->normal()); pNew->setElevation(pPoly->elevation()); pNew->setConstantWidth(dWidth); // 复制属新和扩展数据 pNew->setPropertiesFrom(pPoly); if (NULL != pRb) { pNew->setXData(pRb); CKTCadUtility::FreeRbList(pRb); } // iVert = 0; pPoly->getClosestPointTo(pt2, pt3); pNew->addVertexAt(iVert, pt3.convert2d(plane)); ++iVert; // pPoly->getPointAt(iParam + 1, pt3); pNew->addVertexAt(iVert, pt3.convert2d(plane)); ++iVert; pPoly->getClosestPointTo(pt1, pt3); pPoly->setPointAt(iParam + 1, pt3.convert2d(plane)); // while (Acad::eOk == pPoly->getPointAt(iParam + 2, pt3)) { pNew->addVertexAt(iVert, pt3.convert2d(plane)); ++iVert; pPoly->removeVertexAt(iParam + 2); } // 加入数据库 CKTCadUtility::AddToCurrentSpace(pNew, idEnt); pNew->close(); // 保存id arid.append(idEnt); } // 创建组 if (arid.length() > 1) CKTCadUtility::CreateAcDbGroup(arid); } VERIFY(Acad::eOk == pPline->downgradeOpen()); iIndex = aridPline.length(); while ((--iIndex) >= 1) // 第0个即为pPline { pPoly = arpPline[iIndex]; ASSERT(NULL != pPoly); pPoly->close(); } return TRUE; } BOOL OnBreakPline(const AcDbObjectIdArray& aridPline , double dLeftWidth , double dRightWidth , double dBreakSpace , LPCTSTR pszMeBrkLayer , LPCTSTR pszVerBrkLayer , LPCTSTR pszAllBrkLayer , const int &brkStyle ) { AcDbPolylinePtr pPline(aridPline[0], AcDb::kForRead); if (NULL == pPline) return FALSE; // 关闭组选 KTCADSysVar tempPickStyle(_T("PICKSTYLE"), 0); struct resbuf rbTemp = { NULL, RT3DPOINT, 0 }; struct resbuf rbFence = { &rbTemp, RT3DPOINT, 0 }; struct resbuf rbMeBrk = { NULL, 8, 0 }; rbMeBrk.resval.rstring = (LPTSTR)pszMeBrkLayer; struct resbuf rbVerBrk = { NULL, 8, 0 }; rbVerBrk.resval.rstring = (LPTSTR)pszVerBrkLayer; struct resbuf rbAllBrk = { NULL, 8, 0 }; rbAllBrk.resval.rstring = (LPTSTR)pszAllBrkLayer; CKTAdsPickSet ssMeBrk, ssVerBrk, ssAllBrk; AcDbObjectIdArray arid; AcGeTol tol; tol.setEqualVector(0.7654); AcGeVector3d vtXDir = UcsXAxis; BOOL bHorz; PID::CBreakParam cVert; PID::AcBreakParamArray arThisParam, arOtherParam; int iIdx; AcGeVector3d vt; double dLeft, dRight; AcGePoint3d pt1, pt2; AcGePoint3dArray arpt; AcDbLine dbLine; AcDbPolyline* pPoly; int iPos = pPline->numVerts() - 1; while ((--iPos) >= 0) { pPline->getPointAt(iPos, pt1); pPline->getPointAt(iPos + 1, pt2); dbLine.setStartPoint(pt1); dbLine.setEndPoint(pt2); vt = pt2 - pt1; bHorz = vt.isParallelTo(vtXDir, tol); acdbWcs2Ucs(asDblArray(pt1), rbFence.resval.rpoint, false); acdbWcs2Ucs(asDblArray(pt2), rbTemp.resval.rpoint, false); arThisParam.setLogicalLength(0); // 我断他不断 if (NULL != pszMeBrkLayer && 0 < _tcslen(pszMeBrkLayer)) { acedSSGet(_T("F"), &rbFence, NULL, &rbMeBrk, ssMeBrk); ssMeBrk -= aridPline; // while (!ssMeBrk.IsEmpty()) { arid.setLogicalLength(0); FindPipePlines(ssMeBrk[0], arid, dLeft, dRight); ssMeBrk -= arid[0]; if (Acad::eOk != acdbOpenObject(pPoly, arid[0], AcDb::kForRead)) continue; arpt.setLogicalLength(0); dbLine.intersectWith(pPoly, AcDb::kOnBothOperands, arpt); iIdx = arpt.length(); while ((--iIdx) >= 0) { cVert.pt = arpt[iIdx]; pPoly->getFirstDeriv(cVert.pt, cVert.vt); pPoly->getConstantWidth(cVert.dWidth); cVert.dWidth /= 2; cVert.dLeft = dLeft; cVert.dRight = dRight; pPline->getParamAtPoint(cVert.pt, cVert.dParam); arThisParam.append(cVert); } pPoly->close(); } acedSSFree(ssMeBrk); } // 竖断横不断 acedSSGet(_T("F"), &rbFence, NULL, &rbVerBrk, ssVerBrk); ssVerBrk -= aridPline; // while (!ssVerBrk.IsEmpty()) { arid.setLogicalLength(0); FindPipePlines(ssVerBrk[0], arid, dLeft, dRight); ssVerBrk -= arid[0]; if (Acad::eOk != acdbOpenObject(pPoly, arid[0], AcDb::kForRead)) continue; arpt.setLogicalLength(0); dbLine.intersectWith(pPoly, AcDb::kOnBothOperands, arpt); arOtherParam.setLogicalLength(0); iIdx = arpt.length(); while ((--iIdx) >= 0) { if (bHorz) { cVert.pt = arpt[iIdx]; cVert.vt = vt; pPline->getConstantWidth(cVert.dWidth); cVert.dWidth /= 2; cVert.dLeft = dLeftWidth; cVert.dRight = dRightWidth; pPoly->getParamAtPoint(cVert.pt, cVert.dParam); arOtherParam.append(cVert); } else { cVert.pt = arpt[iIdx]; pPoly->getFirstDeriv(cVert.pt, cVert.vt); pPoly->getConstantWidth(cVert.dWidth); cVert.dWidth /= 2; cVert.dLeft = dLeft; cVert.dRight = dRight; pPline->getParamAtPoint(cVert.pt, cVert.dParam); arThisParam.append(cVert); } } acedSSFree(ssVerBrk); // 断相交的线 if (0 < arOtherParam.length()) OnBreakPline(pPoly, arid, dLeft, dRight, dBreakSpace, arOtherParam, brkStyle); pPoly->close(); } // 断自己 if (0 < arThisParam.length()) OnBreakPline(pPline, aridPline, dLeftWidth, dRightWidth, dBreakSpace, arThisParam, brkStyle); // 横竖都要断 if (NULL != pszAllBrkLayer && 0 < _tcslen(pszAllBrkLayer)) { acedSSGet(_T("F"), &rbFence, NULL, &rbAllBrk, ssAllBrk); ssAllBrk -= aridPline; // while (!ssAllBrk.IsEmpty()) { arid.setLogicalLength(0); FindPipePlines(ssAllBrk[0], arid, dLeft, dRight); ssAllBrk -= arid[0]; if (Acad::eOk != acdbOpenObject(pPoly, arid[0], AcDb::kForRead)) continue; arpt.setLogicalLength(0); dbLine.intersectWith(pPoly, AcDb::kOnBothOperands, arpt); arOtherParam.setLogicalLength(0); iIdx = arpt.length(); while ((--iIdx) >= 0) { cVert.pt = arpt[iIdx]; cVert.vt = vt; pPline->getConstantWidth(cVert.dWidth); cVert.dWidth /= 2; cVert.dLeft = dLeftWidth; cVert.dRight = dRightWidth; pPoly->getParamAtPoint(cVert.pt, cVert.dParam); arOtherParam.append(cVert); } acedSSFree(ssAllBrk); // 段相交的线 if (0 < arOtherParam.length()) OnBreakPline(pPoly, arid, dLeft, dRight, dBreakSpace, arOtherParam, brkStyle); pPoly->close(); } } } return TRUE; } BOOL OnPIDPipe(LPCTSTR pszLayer, double dPipeWidth, double dBreakSpace, const int &clr) { CAcModuleResourceOverride resOverride; if (NULL == pszLayer || _tcslen(pszLayer) <= 0) return FALSE; KTSetting::InitLayer(pszLayer); KTCADSysVar varTemp(_T("ORTHOMODE"), 1); //获取初始化数据 AecDbObjXDataMap xDataMap; ResetXDataMap(xDataMap); if (!KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap)) { acedAlert(_T("\n系统没有初始化!")); return FALSE; } PID::PIDPipeParam pidparam; memset(&pidparam, 0, sizeof(PID::PIDPipeParam)); pidparam.m_nPipeColor = PID::kColorByLayer; DefaultPIDParam(&pidparam); GetLastPIDParam(&pidparam); CString dbPath = FilePath::GetSysDir(); dbPath += _T("\\Plumbing.db"); CUIISQLiteServer sqlDb; if (!sqlDb.InitADOServer(dbPath)) { AfxMessageBox(IDS_LOADADOSERVERFAILED); return FALSE; } KTPIDPipeParamDlg paramDlg; pidparam.m_nPipeColor = clr; paramDlg.SetPIDParam(&pidparam); int nRes = paramDlg.DoModal(); if (nRes == IDOK) { // KTPIDPipeOper::WritePIDParam2Model(&pidparam); CString sProj; xDataMap.GetAt(DOC_PIDPROJECT, sProj); int nBrkStyle(1); xDataMap.GetAt(DOC_PIDBRKSTYLE, nBrkStyle); CString sSQL; sSQL.Format(_T("select * from [AecSpecPipe] where [项目名称]='%s' and ") _T("[等级名称]='%s' and [公称直径]=%d"), sProj, pidparam.m_pszLevel, (int)pidparam.m_dDN); CString sInfo; CStringArray arValues; sqlDb.GetSelData(sSQL, arValues); std::stringstream ss; ss << arValues.GetSize(); if (arValues.GetSize() >= 13) { for (int i = 1; i <= 11; i++)//最后一个为描述 { if (i == 1) { sInfo = arValues.GetAt(i); } else { sInfo += _T("^") + arValues.GetAt(i); } } pidparam.m_dOD = _ttof(arValues.GetAt(9)); //外径 _tcscpy(pidparam.m_pszDesc, arValues.GetAt(12)); _tcscpy(pidparam.m_pszMtoInfo, sInfo); double dLeft = 0.0; double dRight = 0.0; PID::CPlineDataArray arData; if (pidparam.m_nTraType > 0) { PID::CPLineData data; // 伴热 if (pidparam.m_nTraType & 1) { data.pszLayer = LAYER_INSULA; data.pszLType = NULL; data.iColor = PID::kColorByLayer; data.dWidth = 0; data.pPline = NULL; data.dOffset = -pidparam.m_dHeatThick; arData.append(data); if (pidparam.m_dHeatThick < 0) { if (dLeft < -pidparam.m_dHeatThick) dLeft = -pidparam.m_dHeatThick; } else { if (dRight > -pidparam.m_dHeatThick) dRight = -pidparam.m_dHeatThick; } } // 加套管 if (pidparam.m_nTraType & 2) { data.pszLayer = LAYER_JACKET; data.pszLType = NULL; data.iColor = PID::kColorByLayer; data.dWidth = 0; data.pPline = NULL; data.dOffset = pidparam.m_dCoverSpace; arData.append(data); data.dOffset = -pidparam.m_dCoverSpace; arData.append(data); if (dLeft < fabs(pidparam.m_dCoverSpace)) dLeft = fabs(pidparam.m_dCoverSpace); if (dRight > -fabs(pidparam.m_dCoverSpace)) dRight = -fabs(pidparam.m_dCoverSpace); } } AcDbObjectIdArray arid; if (!CreatePolyline(arid, pszLayer, NULL, pidparam.m_nPipeColor, dPipeWidth, &arData)) return FALSE; if (arid.length() > 1) CKTCadUtility::CreateAcDbGroup(arid); KTPIDPipeOper::WriteXData(arid[0], &pidparam); CString sMeBrkLayers, sLayer, sAllBrkLayers; LPCTSTR pszLayers[] = { LAYER_MAJOR1, LAYER_MAJOR2, LAYER_MINOR1, LAYER_MINOR2, LAYER_INST_1 }; for (i = 0; i < sizeof(pszLayers) / sizeof(pszLayers[0]) && (0 != _tcsicmp(pszLayers[i], pszLayer)); i++) { if (KTSetting::GetLayerName(pszLayers[i], sLayer)) { sMeBrkLayers += _T(","); sMeBrkLayers += sLayer; } } sMeBrkLayers.Delete(0); for (i++; i < sizeof(pszLayers) / sizeof(pszLayers[0]); i++) { if (KTSetting::GetLayerName(pszLayers[i], sLayer)) { sAllBrkLayers += _T(","); sAllBrkLayers += sLayer; } } sAllBrkLayers.Delete(0); KTSetting::GetLayerName(pszLayer, sLayer); OnBreakPline(arid, dLeft, dRight, dBreakSpace, sMeBrkLayers, sLayer, sAllBrkLayers, nBrkStyle); return TRUE; } } return FALSE; } AcDbObjectId GetGroupId(AcDbObjectId objId) { AcDbObjectId persObjId; AcDbObject *pEnt; if (Acad::eOk != acdbOpenObject(pEnt, objId, AcDb::kForRead)) { acutPrintf(_T("\nCannot open entity.")); return AcDbObjectId::kNull; } AcDbDictionary *pGroup; const AcDbVoidPtrArray *pReactors; pReactors = pEnt->reactors(); if (pReactors == NULL) { acutPrintf(_T("\nEntity does not belong to a group.")); pEnt->close(); return AcDbObjectId::kNull; } pEnt->close(); int length = pReactors->length(); void *pSomething; for (int i = 0; i < length; ++i) { pSomething = (AcDbObject*)pReactors->at(i); if (acdbIsPersistentReactor(pSomething)) { // Every group reactor is a persistent reactor. // Is this a reactor from a group? persObjId = acdbPersistentReactorObjectId(pSomething); AcDbObject *pReactor; if (Acad::eOk != acdbOpenObject(pReactor, persObjId, AcDb::kForRead)) { acutPrintf(_T("\nCannot get reactor.")); continue; } if (pReactor->isKindOf(AcDbGroup::desc())) { // This is a group reactor. Get the group name. AcDbObjectId groupId = pReactor->ownerId(); if (Acad::eOk != acdbOpenObject(pGroup, groupId, AcDb::kForRead)) { acutPrintf(_T("\nCannot open group.")); pReactor->close(); continue; } LPTSTR groupName; if (Acad::eOk != (pGroup->nameAt(persObjId, groupName))) { acutPrintf(_T("\nCannot get group name.")); pReactor->close(); pGroup->close(); continue; } pGroup->close(); } pReactor->close(); } } return persObjId; } BOOL OnConnectPolyline(AcDbPolyline* pPline1, BOOL bStart1, AcDbPolyline* pPline2, BOOL bStart2) { AcGePoint2d pt; int iPos = (bStart2 ? 1 : pPline2->numVerts() - 2); if (Acad::eOk != pPline2->getPointAt(iPos, pt)) return FALSE; (bStart2 ? ++iPos : --iPos); pPline1->setPointAt((bStart1 ? 0 : pPline1->numVerts() - 1), pt); while (Acad::eOk == pPline2->getPointAt(iPos, pt)) { (bStart2 ? ++iPos : --iPos); pPline1->addVertexAt((bStart1 ? 0 : pPline1->numVerts()), pt); } pPline2->erase(); return TRUE; } BOOL OnConnectPolylines(const AcDbObjectId& idEnt1, const AcDbObjectId& idEnt2, const AcGePoint3d ptNear) { double dLeft1, dRight1; AcDbObjectIdArray arid1; FindPipePlines(idEnt1, arid1, dLeft1, dRight1); double dLeft2, dRight2; AcDbObjectIdArray arid2; FindPipePlines(idEnt2, arid2, dLeft2, dRight2); int iLen1 = arid1.length(); int iLen2 = arid2.length(); // 没有找到曲线或数目不同,返回 if (iLen1 <= 0 || iLen1 != iLen2) return FALSE; // 取得排序方向 PID::CConnectData data; AcGePoint3d pt1, pt2; if (Acad::eOk != acdbOpenObject(data.pPline, arid1[0], AcDb::kForRead)) return FALSE; data.pPline->getStartPoint(pt1); data.pPline->getEndPoint(pt2); if (ptNear.distanceTo(pt1) < ptNear.distanceTo(pt2)) data.pPline->getPointAt(1, pt2); else data.pPline->getPointAt(data.pPline->numVerts() - 2, pt1); AcGeVector3d vtDir((pt2 - pt1).normal()); vtDir.rotateBy(PI / 2.0, data.pPline->normal()); data.pPline->close(); AcDbXline cXLine; cXLine.setBasePoint(ptNear); cXLine.setUnitDir(vtDir); int iPos = iLen1; PID::CConnectDataArray arData1, arData2; while ((--iPos) >= 0) { if (Acad::eOk != acdbOpenObject(data.pPline, arid1[iPos], AcDb::kForWrite)) break; data.pPline->getStartPoint(pt1); data.pPline->getEndPoint(pt2); pt1 = ((data.bStart = (ptNear.distanceTo(pt1) < ptNear.distanceTo(pt2))) ? pt1 : pt2); cXLine.getClosestPointTo(pt1, pt2); cXLine.getParamAtPoint(pt2, data.dParam); arData1.append(data); if (Acad::eOk != acdbOpenObject(data.pPline, arid2[iPos], AcDb::kForWrite)) break; data.pPline->getStartPoint(pt1); data.pPline->getEndPoint(pt2); pt1 = ((data.bStart = (ptNear.distanceTo(pt1) < ptNear.distanceTo(pt2))) ? pt1 : pt2); cXLine.getClosestPointTo(pt1, pt2); cXLine.getParamAtPoint(pt2, data.dParam); arData2.append(data); } BOOL bCanLink = TRUE; iLen1 = arData1.length(); iLen2 = arData2.length(); if (iLen1 > 0 && iLen1 == iLen2) { // 在同一方向上排序 iPos = iLen1; qsort(arData1.asArrayPtr(), iPos, sizeof(PID::CConnectData), ConnectParamCompare); qsort(arData2.asArrayPtr(), iPos, sizeof(PID::CConnectData), ConnectParamCompare); // 判断图层线型是否一致 while ((--iPos) >= 0 && bCanLink) { bCanLink = (arData1[iPos].pPline->layerId() == arData2[iPos].pPline->layerId() && arData1[iPos].pPline->linetypeId() == arData2[iPos].pPline->linetypeId()); } // 连接曲线 iPos = iLen1; while ((--iPos) >= 0 && bCanLink) { OnConnectPolyline(arData1[iPos].pPline, arData1[iPos].bStart, arData2[iPos].pPline, arData2[iPos].bStart); } } while ((--iLen1) >= 0) arData1[iLen1].pPline->close(); while ((--iLen2) >= 0) arData2[iLen2].pPline->close(); return bCanLink; } } // pid-pipe void PL_KTPIDMajor1() { if (!CoreTools::hasCSSZ(true)) return; AecDbObjXDataMap xDataMap; ResetXDataMap(xDataMap); KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap); double dWidth = 0.0; xDataMap.GetAt(DOC_PIDMPIPE1W, dWidth); double dBreak = 0.0; xDataMap.GetAt(DOC_PIDBSPACE, dBreak); OnPIDPipe(LAYER_MAJOR1, dWidth, dBreak, 1); return; } void PL_KTPIDMajor2() { if (!CoreTools::hasCSSZ(true)) return; AecDbObjXDataMap xDataMap; ResetXDataMap(xDataMap); KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap); double dWidth = 0.0; xDataMap.GetAt(DOC_PIDMPIPE2W, dWidth); double dBreak = 0.0; xDataMap.GetAt(DOC_PIDBSPACE, dBreak); OnPIDPipe(LAYER_MAJOR2, dWidth, dBreak, 1); return; } void PL_KTPIDMinor1() { if (!CoreTools::hasCSSZ(true)) return; AecDbObjXDataMap xDataMap; ResetXDataMap(xDataMap); KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap); double dWidth = 0.0; xDataMap.GetAt(DOC_PIDSPIPE1W, dWidth); double dBreak = 0.0; xDataMap.GetAt(DOC_PIDBSPACE, dBreak); OnPIDPipe(LAYER_MINOR1, dWidth, dBreak, 4); return; } void PL_KTPIDMinor2() { if (!CoreTools::hasCSSZ(true)) return; AecDbObjXDataMap xDataMap; ResetXDataMap(xDataMap); KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap); double dWidth = 0.0; xDataMap.GetAt(DOC_PIDSPIPE2W, dWidth); double dBreak = 0.0; xDataMap.GetAt(DOC_PIDBSPACE, dBreak); OnPIDPipe(LAYER_MINOR2, dWidth, dBreak, 4); return; } void PL_KTPIDINSTLINE() { if (!CoreTools::hasCSSZ(true)) return; CAcModuleResourceOverride resOverride; KTPIDInstLineDlg dlg; if (IDOK != dlg.DoModal()) return; CString sLType; sLType.Format(_T("%s\\%s"), PID_LINETYPE_FILE, dlg.GetLineType()); KTCADSysVar varTemp(_T("ORTHOMODE"), 1); AcDbObjectIdArray arid; if (!CreatePolyline(arid, LAYER_INST_1, sLType)) return; AecDbObjXDataMap xDataMap; ResetXDataMap(xDataMap); KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap); double dBreak = 0.0; xDataMap.GetAt(DOC_PIDBSPACE, dBreak); int nBrkStyle(1); xDataMap.GetAt(DOC_PIDBRKSTYLE, nBrkStyle); CString sMeBrkLayers, sLayer; LPCTSTR pszLayers[] = { LAYER_MAJOR1, LAYER_MAJOR2, LAYER_MINOR1, LAYER_MINOR2 }; for (int i = 0; i < sizeof(pszLayers) / sizeof(pszLayers[0]); i++) { if (KTSetting::GetLayerName(pszLayers[i], sLayer)) { sMeBrkLayers += _T(","); sMeBrkLayers += sLayer; } } sMeBrkLayers.Delete(0); KTSetting::GetLayerName(LAYER_INST_1, sLayer); OnBreakPline(arid, 0, 0, dBreak, sMeBrkLayers, sLayer, NULL, nBrkStyle); return; } void PL_KTAttribEdit() { ads_point pt; ads_name ent; int iRet = acedEntSel(_T("\n选择图形元件:"), ent, pt); if (RTNORM != iRet) return; AcDbObjectId idEnt; acdbGetObjectId(idEnt, ent); if (idEnt.isNull()) return; int nKind = -1; CString sAppName(PIDPIPE_APP); AecDbObjXDataMap objXData; BOOL bFind = objXData.Read(idEnt, sAppName); if (!bFind) { AcDbObjectId idGroup = GetGroupId(idEnt); AcDbGroup* pGroup = NULL; acdbOpenObject(pGroup, idGroup, AcDb::kForRead); if (NULL == pGroup) return; CString sValue; sAppName = _T("KTParamPart"); AcDbGroupIterator* pIT = pGroup->newIterator(); if (NULL != pIT) { for (; !pIT->done(); pIT->next()) { idEnt = pIT->objectId(); if (objXData.Read(idEnt, sAppName) && objXData.GetAt(_T("点类型"), sValue) && 0 == sValue.CompareNoCase(_T("材料点"))) { bFind = TRUE; break; } } } delete pIT; pGroup->close(); } if (!bFind) return; CAcModuleResourceOverride theResources; CDLGArribtEdit dlg(&objXData); if (IDOK == dlg.DoModal()) { objXData.Write(idEnt, sAppName, FALSE); } return; } void PL_KTPIPEWMO() { ads_name ss; struct resbuf* pRb = acutBuildList(RTDXF0, _T("LWPOLYLINE"), NULL); int nRes = acedSSGet(NULL, NULL, NULL, pRb, ss); if (RTNORM != nRes) return; Adesk::Int32 lLen = 0; acedSSLength(ss, &lLen); ads_name ent; AcDbObjectIdArray arid; while ((--lLen) >= 0) { acedSSName(ss, lLen, ent); AcDbPolylinePtr pPLine(ent, AcDb::kForRead); if (NULL == pPLine) continue; struct resbuf* pRbXdata = pPLine->xData(PIDPIPE_APP); if (NULL == pRbXdata) continue; arid.append(pPLine->objectId()); acutRelRb(pRbXdata); } acedSSFree(ss); int iPos = arid.length(); if (0 >= iPos) return; double dWidth = 0.0; while (TRUE) { nRes = acedGetReal(_T("\n请输入新的管线打印线宽:"), &dWidth); if (RTNORM != nRes) return; if (_IsZero_(dWidth)) { acutPrintf(_T("\n打印线宽必须大于0!请重新输入!")); continue; } break; } while ((--iPos) >= 0) { AcDbPolylinePtr pPline(arid[iPos], AcDb::kForWrite); if (NULL == pPline) continue; pPline->setConstantWidth(dWidth); } return; } void PL_KTPIPECONNECT() { struct resbuf rbFilter = { NULL, RTDXF0, 0 }; rbFilter.resval.rstring = _tcsdup(_T("LWPOLYLINE")); ads_name ent1; ads_point pt1; int iRet = CKTCadUtility::SelectEntity(_T("\n请选择第一根管线"), ent1, &rbFilter, pt1); if (RTNORM != iRet) return; ads_name ent2; ads_point pt2; iRet = CKTCadUtility::SelectEntity(_T("\n请选择第二根管线"), ent2, &rbFilter, pt2); if (RTNORM != iRet) return; //如果平行,共线 AcDbObjectId idEnt1, idEnt2; acdbGetObjectId(idEnt1, ent1); acdbGetObjectId(idEnt2, ent2); acdbUcs2Wcs(pt1, pt1, false); acdbUcs2Wcs(pt2, pt2, false); AcGePoint3d pt = CKTCadUtility::GetMiddlePoint(asPnt3d(pt1), asPnt3d(pt2)); OnConnectPolylines(idEnt1, idEnt2, pt); return; } void PI_OnPIDReport() { CAcModuleResourceOverride myResources; CLineNumDlg Dlg; //获取初始化数据 AecDbObjXDataMap xDataMap; ResetXDataMap(xDataMap); if (!KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap)) { acedAlert(_T("\n系统没有初始化!")); return; } CString dbPath = FilePath::GetSysDir(); dbPath += _T("\\Plumbing.db"); CUIISQLiteServer sqlDb; if (!sqlDb.InitADOServer(dbPath)) { AfxMessageBox(IDS_LOADADOSERVERFAILED); return; } Dlg.SetADOServer(&sqlDb); int nRet = Dlg.DoModal(); }