#include "stdafx.h" #include "KTPIDUtility.h" #include "KTObjSmartPtr.h" #include "EarThwormDef.h" int KTPIDUtility::CreatePolyLine(AcDbObjectId idLineType,AcDbObjectId idLayer) { AcDbObjectId idPolyLine; AcGePoint3d pt1,pt2; ads_point adsPt; acedInitGet(RSG_NOZERO,NULL); CString sTip = _T("请选择起始点:"); int nResult = acedGetPoint(NULL, sTip, adsPt); if (nResult == RTNORM) { pt1= asPnt3d(adsPt); pt2= asPnt3d(adsPt); } else { return 1; } AcDbPolyline * pLine; while (TRUE) { pLine = new AcDbPolyline(); pt1=pt2; sTip = _T("\n请选择下一点:"); nResult = acedGetPoint(adsPt, sTip, adsPt); if(nResult == RTNORM) { pt2 = asPnt3d(adsPt); pLine->addVertexAt(0,pt1.convert2d(AcGePlane::kXYPlane)); pLine->addVertexAt(1,pt2.convert2d(AcGePlane::kXYPlane)); pLine->setLinetype(idLineType); pLine->setLayer(idLayer); CKTCadUtility::AddToBlockTableRecord(idPolyLine,pLine); pLine->close(); } if (nResult == RTNONE ) { break; } if (nResult == RTCAN) { return 1; } } return 0; } int KTPIDUtility::CreatePolyLineALL(AcDbObjectId idLineType,AcDbObjectId idLayer,AcGePoint3d &ptInsert,AcGeVector3d &vDir,AcDbObjectId &idPolyLine) { AcGePoint3d ptBack; ads_point adsPt; acedInitGet(RSG_NOZERO,NULL); CString sTip = _T("请选择起始点:"); int nResult = acedGetPoint(NULL, sTip, adsPt); if (nResult == RTNORM) { ptInsert= asPnt3d(adsPt); ptBack=ptInsert; } else { return 1; } AcDbPolyline * pLine; pLine = new AcDbPolyline(); int iNode=0; pLine->addVertexAt(0,ptInsert.convert2d(AcGePlane::kXYPlane)); while (TRUE) { iNode = iNode +1; sTip = _T("\n请选择下一点:"); nResult = acedGetPoint(adsPt, sTip, adsPt); if(nResult == RTNORM) { ptInsert = asPnt3d(adsPt); if (idPolyLine.isValid()) { if (acdbOpenObject(pLine,idPolyLine,AcDb::kForWrite) != Acad::eOk) { return 1; } else { pLine->addVertexAt(iNode,ptInsert.convert2d(AcGePlane::kXYPlane)); pLine->setLinetype(idLineType); pLine->setLayer(idLayer); CKTCadUtility::AddToBlockTableRecord(idPolyLine,pLine); pLine->close(); } } else { pLine->addVertexAt(iNode,ptInsert.convert2d(AcGePlane::kXYPlane)); pLine->setLinetype(idLineType); pLine->setLayer(idLayer); CKTCadUtility::AddToBlockTableRecord(idPolyLine,pLine); pLine->close(); } vDir=ptInsert-ptBack; ptBack = ptInsert; } if (nResult == RTNONE) { if (iNode==1) { pLine->close(); } break; } if (nResult == RTCAN) { if (iNode==1) { pLine->close(); } else { if (acdbOpenObject(pLine,idPolyLine,AcDb::kForWrite) == Acad::eOk) { pLine->erase(true); pLine->close(); } } return 1; } } return 0; } int KTPIDUtility::GetLinetypeId(LPCTSTR pStr, AcDbObjectId& idLineType) { // Get the table of currently loaded linetypes. // AcDbLinetypeTable* pLinetypeTable; Acad::ErrorStatus err = acdbCurDwg()->getLinetypeTable( pLinetypeTable, AcDb::kForRead); if (err != Acad::eOk) return err; // Get the ID of the linetype with the name in 'pStr' // (even if it's erased) and place it in 'id'. // err = pLinetypeTable->getAt(pStr, idLineType, Adesk::kTrue); pLinetypeTable->close(); return err; } void KTPIDUtility::Break(AcDbObjectId id,AcGePoint3d pt1,AcGePoint3d pt2) { ads_name ss; acdbGetAdsName(ss,id); Break(ss, pt1, pt2); } void KTPIDUtility::Break(ads_name ss,AcGePoint3d pt1,AcGePoint3d pt2) { struct resbuf *result = NULL, *list,Var; acedGetVar(_T("OSMODE"),&Var); acedSetVar(_T("OSMODE"),acutBuildList(RTSHORT,0,RTNONE)); //把组打开 struct resbuf rb; rb.restype = RTSHORT; rb.resval.rint = 0; acedSetVar(_T("PICKSTYLE"), &rb); list = acutBuildList(RTSTR, _T("break"),RTENAME,ss,RTSTR,_T("F"),RT3DPOINT,asDblArray(pt1),RT3DPOINT,asDblArray(pt2),RTNONE); if (SHacedCmd(list) != RTNORM) { acedAlert(_T("Break is defeat!")); } acutRelRb(list); acedSetVar(_T("OSMODE"),&Var); rb.restype = RTSHORT; rb.resval.rint = 1; acedSetVar(_T("PICKSTYLE"), &rb); } BOOL KTPIDUtility::FindPipeCen(AcGePoint3d& ptGeIn,AcDbObjectId& idCen,int & npipe,double dPipeW,AcGePoint3d& pts,AcGePoint3d& pte,CString & sLineno,CString & sDn,CString & sSpec) { //该点附近有管线,根据管线确定中线 ads_point pt1,pt2; pt1[X] = ptGeIn.x;pt1[Y] = ptGeIn.y;pt1[Z] = ptGeIn.z; pt2[X] = ptGeIn.x;pt2[Y] = ptGeIn.y;pt2[Z] = ptGeIn.z; //范围为一个普捉框的大小 pt1[X] -= dPipeW/2;pt1[Y] += dPipeW/2; pt2[X] += dPipeW/2;pt2[Y] -= dPipeW/2; acdbWcs2Ucs(pt1,pt1,false); acdbWcs2Ucs(pt2,pt2,false); // struct resbuf* pRb = NULL; // pRb = acutBuildList(RTDXF0,_T("LINE,POLYLINE"),NULL); actrTransactionManager->flushGraphics();//这样就可以选择刚建立的pline了. ads_name ssname,ent; acedSSGet(_T("C"),pt1,pt2,NULL,ssname); Adesk::Int32 lLen = 0; acedSSLength(ssname,&lLen); AcDbEntity* pEnt = NULL; AcDbObjectId id; for(int i = 0;i < lLen;i++) { acedSSName(ssname,i,ent); if (Acad::eOk == acdbGetObjectId(id,ent)) { if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead) ) { AecDbObjXDataMap objXData; if (objXData.Read(pEnt,PIDPIPE_APP)) { objXData.GetAt(PID_PIPE_DN,sDn); objXData.GetAt(PID_PIPE_LEVEL,sSpec); objXData.GetAt(PID_PIPE_LINENO,sLineno); AcDbPolyline * pPline = AcDbPolyline::cast(pEnt); if (pPline!=NULL) //如果是PL则管道为单线 { AcGePoint3d pt; pPline->getClosestPointTo(ptGeIn, pt); // 去点所在处参数值 double dParam; pPline->getParamAtPoint(pt, dParam); // 取前后节点 int iParam = int(dParam); pPline->getPointAtParam(iParam, pts); pPline->getPointAtParam(iParam + 1, pte); pPline->close(); idCen = id; pEnt->close(); acedSSFree(ssname); return TRUE; } } else { pEnt->close(); continue; } //是管线 } } } acedSSFree(ssname); // acutRelRb(pRb); return FALSE; } BOOL KTPIDUtility::BreakPIDPipe(const AcDbObjectId& idBreak, const AcGePoint3d& ptBreak, double dLength) { // 找到管线组 double dLeft, dRight; AcDbObjectIdArray aridPoly; FindPipePlines(idBreak, aridPoly, dLeft, dRight); // 打开主管线 AcDbPolylinePtr pPline(aridPoly[0], AcDb::kForRead); if (NULL == pPline) return FALSE; // 判断在该点处曲线是否可以裁减(看是否裁超过拐点, 包括多线时) // 确保是曲线上的点 AcGePoint3d pt, pt1, pt2, pt3; pPline->getClosestPointTo(ptBreak, pt); // 去点所在处参数值 double dParam, dAngle; pPline->getParamAtPoint(pt, dParam); // 取前后节点 int iParam = int(dParam); pPline->getPointAtParam(iParam, pt1); pPline->getPointAtParam(iParam + 1, pt2); // 该点所在线段方向 AcGeVector3d vt = (pt2 - pt1).normal(); AcGeVector3d vtNormal = pPline->normal(); // 去除多线拐弯宽度 if (Acad::eOk == pPline->getPointAtParam(iParam - 1, pt3)) { dAngle = vt.angleTo(pt1 - pt3, vtNormal); pt1 += vt * fabs(dAngle > PI ? fabs(dLeft) : fabs(dRight)); } // 去除多线拐弯宽度 if (Acad::eOk == pPline->getPointAtParam(iParam + 2, pt3)) { dAngle = vt.angleTo(pt3 - pt2, vtNormal); pt2 -= vt * fabs(dAngle < PI ? fabs(dLeft) : fabs(dRight)); } // 判断是否够裁减 if (pt1.distanceTo(pt) < dLength / 2.0 || pt2.distanceTo(pt) < dLength / 2.0) return FALSE; // 将pt1, pt2定位到断开位置 pt1 = pt - vt * dLength / 2.0; pt2 = pt + vt * dLength / 2.0; // 关闭主管线 pPline->close(); // 裁减出曲线, 修改保留旧曲线 AcGePlane plane(AcGePoint3d::kOrigin, vtNormal); // AcDbObjectId idEnt; AcDbPolyline* pNew; AcDbObjectIdArray arid; // int iVert; double dWidth; struct resbuf* pRb; int iPos = aridPoly.length(); while ((--iPos) >= 0) { // 打开每根多段线 pPline.Open(aridPoly[iPos], AcDb::kForWrite); if (NULL == pPline) continue; // 创建裁剪的新对象 pNew = new AcDbPolyline; ASSERT(NULL != pNew); // 复制属新和扩展数据 pNew->setNormal(pPline->normal()); pNew->setElevation(pPline->elevation()); pPline->getConstantWidth(dWidth); pNew->setConstantWidth(dWidth); pNew->setPropertiesFrom(pPline); pRb = pPline->xData(); if (NULL != pRb) { pNew->setXData(pRb); CKTCadUtility::FreeRbList(pRb); } // iVert = 0; pPline->getClosestPointTo(pt2, pt3); pNew->addVertexAt(iVert, pt3.convert2d(plane)); ++iVert; // pPline->getPointAt(iParam + 1, pt3); pNew->addVertexAt(iVert, pt3.convert2d(plane)); ++iVert; pPline->getClosestPointTo(pt1, pt3); pPline->setPointAt(iParam + 1, pt3.convert2d(plane)); // while (Acad::eOk == pPline->getPointAt(iParam + 2, pt3)) { pNew->addVertexAt(iVert, pt3.convert2d(plane)); ++iVert; pPline->removeVertexAt(iParam + 2); } // 加入数据库 CKTCadUtility::AddToCurrentSpace(pNew, idEnt); pNew->close(); pPline->close(); // 保存id arid.append(idEnt); } // 创建组 if (arid.length() > 1) CKTCadUtility::CreateAcDbGroup(arid); return TRUE; } BOOL KTPIDUtility::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 KTPIDUtility::GetPipeID(AcGePoint3d ptBase,AcDbObjectId& id) { int npipe=-1; AcGePoint3d pts,pte; CString sLineno=_T(""); CString sDn=_T(""); CString sSpec=_T(""); //获取初始化数据 AecDbObjXDataMap xDataMap; PIDLineTools::ReSetPID(xDataMap); if (!KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap)) { acedAlert(_T("\n系统没有初始化!")); return FALSE; } CString sPipeW; xDataMap.GetAt(DOC_PIDMPIPE1W,sPipeW); double dPipeW=_ttof(sPipeW); BOOL nB = KTPIDUtility::FindPipeCen(ptBase,id,npipe,dPipeW,pts,pte,sLineno,sDn,sSpec); //是管子dPipeW是线宽,npipe是单双线属性等 if (nB == FALSE) { acutPrintf(_T("未获得管道信息!")); return FALSE; } return TRUE; }