Files
envi-code/SourceCode/Code2026/PIDLineCmd/KTPIDUtility.cpp
T
2026-09-28 15:28:50 +08:00

477 lines
11 KiB
C++

#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;
}