477 lines
11 KiB
C++
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;
|
|
} |