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

1925 lines
45 KiB
C++

#include "stdafx.h"
#include "KTPipeOper.h"
#include "KTTempTol.h"
#include "KTGeUtility.h"
#include "KTFitting.h"
#include "KTCADSysVar.h"
#include "AecDbEwPipe.h"
#include <vector>
#include <algorithm>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define MAXPIPED 1500.0
double KTPipeOper::m_dPickBox = 0.0;
KTPipeOper::KTPipeOper()
{
}
KTPipeOper::~KTPipeOper()
{
}
BOOL KTPipeOper::BreakPipe(AcGePoint3d& ptGeOn,double dHalfWidth,AcDbObjectId idCen)
{
if (idCen == AcDbObjectId::kNull)
{
//找中心线,
if (!FindPipeCen(ptGeOn,idCen))
{
//acutPrintf(_T(""));
return FALSE;
}
}
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idCen,AcDb::kForRead))
{
BreakPipe(ptGeOn,dHalfWidth,pEnt);
pEnt->close();
}
return FALSE;
}
BOOL KTPipeOper::BreakPipe(AcGePoint3d& ptGeOn,double dHalfWidth,AcDbEntity* pEnt)
{
AcDbPolyline* pPl = AcDbPolyline::cast(pEnt);
if (pPl != NULL && pPl->numVerts() == 2)
{
//打断中心线
pEnt->upgradeOpen();
KTGeUtility::BreakLine(pEnt,ptGeOn,dHalfWidth);
pEnt->downgradeOpen();
return TRUE;
}
AcDbLine* pLine = AcDbLine::cast(pEnt);
if (pLine != NULL)
{
//找到管线对,打断它们
AcDbObjectId id1,id2;
if (FindPipePair(pLine,id1,id2))
{
KTGeUtility::BreakLine(id1,ptGeOn,dHalfWidth);
KTGeUtility::BreakLine(id2,ptGeOn,dHalfWidth);
//打断中心线
pEnt->upgradeOpen();
KTGeUtility::BreakLine(pEnt,ptGeOn,dHalfWidth);
pEnt->downgradeOpen();
return TRUE;
}
}
return FALSE;
}
BOOL KTPipeOper::MergePipe(AcDbObjectId& idPipe,AcDbObjectIdArray& arIDs)
{
AcDbObjectIdArray arIDCns;
AcGePoint3d ptGe,ptGeT,ptGe2;
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idPipe,AcDb::kForRead))
{
AecDbObjXDataMap objXData;
AecDbObjXDataMap objXData2;
if (objXData.Read(pEnt,PIDPIPE_APP))
{
CString sDn1,sDn2;
objXData.GetAt(PIPE_DN,sDn1);
AcDbLine* pLine1 = AcDbLine::cast(pEnt);
if (pLine1 != NULL)
{
AcGePoint3d ptGeT;
AcDbEntity* pEnt2 = NULL;
for (int i = 0;i < arIDs.length();i++)
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,arIDs.at(i),AcDb::kForRead))
{
if (objXData2.Read(pEnt2,PIDPIPE_APP))
{
objXData2.GetAt(PIPE_DN,sDn2);
if (sDn1.CompareNoCase(sDn2) == 0)
{
AcDbLine* pLine2 = AcDbLine::cast(pEnt2);
if (pLine2 != NULL)
{
pLine2->getClosestPointTo(pLine1->endPoint(),ptGeT,Adesk::kTrue);
if (ptGeT.distanceTo(pLine1->endPoint()) < 1.e-3) //可重合
{
arIDCns.append(arIDs.at(i));
arIDs.removeAt(i);
i -= 1;
}
}
}
}
pEnt2->close();
}
}
}
AcDbPolyline* pPl1 = AcDbPolyline::cast(pEnt);
if (pPl1 != NULL)
{
AcGePoint3d ptGeT;
AcDbEntity* pEnt2 = NULL;
for (int i = 0;i < arIDs.length();i++)
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,arIDs.at(i),AcDb::kForRead))
{
if (objXData2.Read(pEnt2,PIDPIPE_APP))
{
objXData2.GetAt(PIPE_DN,sDn2);
if (sDn1.CompareNoCase(sDn2) == 0)
{
AcDbPolyline* pPl2 = AcDbPolyline::cast(pEnt2);
if (pPl2 != NULL)
{
pPl1->getStartPoint(ptGe);
pPl1->getEndPoint(ptGe2);
AcDbLine line(ptGe2,ptGe);
pPl2->getEndPoint(ptGe);
line.getClosestPointTo(ptGe,ptGeT,Adesk::kTrue);
if (ptGe.distanceTo(ptGeT) < 1.e-3)
{
arIDCns.append(arIDs.at(i));
arIDs.removeAt(i);
i -= 1;
}
}
}
}
pEnt2->close();
}
}
}
}
pEnt->close();
}
for (int i = 0;i < arIDCns.length();i++)
{
KTPipeOper::MergePipe(idPipe,arIDCns.at(i));
}
return TRUE;
}
static BOOL FindPipe(AcDbObjectIdArray& arIds,AcDbObjectId& id)
{
id.setNull();
AcDbObjectId idT;
AcDbEntity* pEnt = NULL;
for (int i = 0;i < arIds.length();i++)
{
idT = arIds.at(i);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idT,AcDb::kForRead))
{
//验证扩展数据是管子中心线
AecDbObjXDataMap objXData;
if (objXData.Read(pEnt,PIDPIPE_APP))
{
id = idT;
pEnt->close();
break;
}
else
{
arIds.removeAt(i);
i -= 1;
}
pEnt->close();
}
else
{
arIds.removeAt(i);
i -= 1;
}
}
return id.isValid() ? TRUE : FALSE;
}
static BOOL FindPipeOnLine(AcDbObjectIdArray& arIds,const AcDbObjectId& id1,AcDbObjectId& id2)
{
AcDbEntity* pEnt1 = NULL;
AcDbEntity* pEnt2 = NULL;
AcDbObjectIdArray arIdsT;
arIdsT.append(arIds);
AcDbLine* pLine1 = NULL;
AcDbLine* pLine2 = NULL;
AcDbPolyline* pPl1 = NULL;
AcDbPolyline* pPl2 = NULL;
AcGePoint3d ptGeOn;
AcGeVector3d vt1,vt2;
AcGePoint3d ptGeS1,ptGeE1,ptGeS2,ptGeE2;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForRead))
{
while(TRUE)
{
if (arIdsT.isEmpty()) break;
if (FindPipe(arIdsT,id2))
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,id2,AcDb::kForRead))
{
pLine1 = AcDbLine::cast(pEnt1);
pLine2 = AcDbLine::cast(pEnt2);
if (pLine1 != NULL && pLine2 != NULL)
{
pLine2->getClosestPointTo(pLine1->startPoint(),ptGeOn,Adesk::kTrue);
if (pLine1->startPoint().distanceTo(ptGeOn) < 1.e-3) //认为共线
{
vt1 = pLine1->endPoint() - pLine1->startPoint();
vt2 = pLine2->endPoint() - pLine2->startPoint();
if (vt1.isParallelTo(vt2))
{
//是否需要进一步考虑公称直径,待定
pEnt2->close();
pEnt1->close();
return TRUE;
}
}
}
pPl1 = AcDbPolyline::cast(pEnt1);
pPl2 = AcDbPolyline::cast(pEnt2);
if (pPl1 != NULL && pPl2 != NULL)
{
if (pPl1->isOnlyLines() && pPl2->isOnlyLines())
{
pPl1->getStartPoint(ptGeS1);
pPl1->getEndPoint(ptGeE1);
pPl2->getStartPoint(ptGeS2);
pPl2->getEndPoint(ptGeE2);
vt1 = ptGeE1 - ptGeS1;
vt2 = ptGeE2 - ptGeS2;
if (vt1.isParallelTo(vt2))
{
AcDbLine line1(ptGeS1,ptGeE1);
line1.getClosestPointTo(ptGeS2,ptGeOn,Adesk::kTrue);
if (ptGeS2.distanceTo(ptGeOn) < 1.e-3) //认为共线
{
//是否需要进一步考虑公称直径,待定
pEnt2->close();
pEnt1->close();
return TRUE;
}
}
}
else //有弯头处的连接
{
}
}
pEnt2->close();
}
arIdsT.remove(id2);
}
}
pEnt1->close();
}
return FALSE;
}
static BOOL MergeOutLine(AcDbObjectId& idOut11,AcDbObjectId& idOut21,AcDbObjectId& idOut22)
{
AcDbEntity* pEnt11 = NULL,*pEnt21 = NULL,*pEnt22 = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt11,idOut11,AcDb::kForWrite))
{
AcDbLine* pLine11 = AcDbLine::cast(pEnt11);
if (pLine11 != NULL)
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt21,idOut21,AcDb::kForWrite))
{
AcDbLine* pLine21 = AcDbLine::cast(pEnt21);
if (pLine21 != NULL)
{
AcGePoint3d ptGeOn;
pLine21->getClosestPointTo(pLine11->endPoint(),ptGeOn,Adesk::kTrue);
if (pLine11->endPoint().distanceTo(ptGeOn) < 1.e-3) //认为共线
{
AcGePoint3dArray arPts;
arPts.append(pLine11->startPoint());
arPts.append(pLine11->endPoint());
arPts.append(pLine21->startPoint());
arPts.append(pLine21->endPoint());
KTPipeOper::SortPoints(arPts,pLine11);
pLine11->setStartPoint(arPts.first());
pLine11->setEndPoint(arPts.last());
pEnt21->erase();
pEnt21->close();
pEnt11->close();
return TRUE;
}
}
pEnt21->close();
}
if (Acad::eOk == acdbOpenAcDbEntity(pEnt22,idOut22,AcDb::kForWrite))
{
AcDbLine* pLine22 = AcDbLine::cast(pEnt22);
if (pLine22 != NULL)
{
AcGePoint3d ptGeOn;
pLine22->getClosestPointTo(pLine11->endPoint(),ptGeOn,Adesk::kTrue);
if (pLine11->endPoint().distanceTo(ptGeOn) < 1.e-3) //认为共线
{
AcGePoint3dArray arPts;
arPts.append(pLine11->startPoint());
arPts.append(pLine11->endPoint());
arPts.append(pLine22->startPoint());
arPts.append(pLine22->endPoint());
KTPipeOper::SortPoints(arPts,pLine11);
pLine11->setStartPoint(arPts.first());
pLine11->setEndPoint(arPts.last());
pEnt22->erase();
pEnt22->close();
pEnt11->close();
return TRUE;
}
}
pEnt22->close();
}
}
pEnt11->close();
}
return FALSE;
}
typedef struct TagPointOnCurve
{
AcGePoint3d ptGeOn;
AcDbCurve* pCurve;
}TAGPOINTONCURVE;
static bool ComPareFunc(TagPointOnCurve& Item1,TagPointOnCurve& Item2)
{
//ASSERT(pItem2 != NULL && pItem1 != NULL);
double dPar1 = 0.0,dPar2 = 0.0;
Item1.pCurve->getParamAtPoint(Item1.ptGeOn,dPar1);
Item2.pCurve->getParamAtPoint(Item2.ptGeOn,dPar2);
if (dPar1 - dPar2 > 1.e-10)
{
return true;
}
return false;
}
BOOL KTPipeOper::SortPoints(AcGePoint3dArray& arPts,AcDbCurve* pCurve)
{
std::vector<TagPointOnCurve> vtPtsOnCurve;
TagPointOnCurve ptOnCurve;
for (int i = 0;i < arPts.length();i++)
{
ptOnCurve.ptGeOn = arPts.at(i);
ptOnCurve.pCurve = pCurve;
vtPtsOnCurve.push_back(ptOnCurve);
}
std::sort(vtPtsOnCurve.begin(),vtPtsOnCurve.end(),ComPareFunc);
std::vector<TagPointOnCurve>::iterator it;
arPts.setLogicalLength(0);
for (it = vtPtsOnCurve.begin();it != vtPtsOnCurve.end();it++)
{
arPts.append((*it).ptGeOn);
}
return TRUE;
}
BOOL KTPipeOper::MergePipe(AcDbObjectId& id1,AcDbObjectId& id2)
{
AcDbEntity* pEnt1 = NULL;
AcDbEntity* pEnt2 = NULL;
AcDbObjectId idOut11,idOut12;
FindPipePair(id1,idOut11,idOut12);
AcDbObjectId idOut21,idOut22;
FindPipePair(id2,idOut21,idOut22);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForWrite))
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,id2,AcDb::kForWrite))
{
AcDbLine* pLine1 = AcDbLine::cast(pEnt1);
AcDbLine* pLine2 = AcDbLine::cast(pEnt2);
if (pLine1 != NULL && pLine2 != NULL)
{
AcGePoint3d ptGeT;
pLine2->getClosestPointTo(pLine1->endPoint(),ptGeT,Adesk::kTrue);
if (ptGeT.distanceTo(pLine1->endPoint()) < 1.e-3)//重合
{
if (pLine1 != NULL && pLine2 != NULL)
{
AcGeVector3d vt1 = pLine1->endPoint() - pLine1->startPoint();
AcGeVector3d vt2 = pLine2->endPoint() - pLine2->startPoint();
if (vt1.isParallelTo(vt2))
{
//排序
AcGePoint3dArray arPts;
arPts.append(pLine1->startPoint());
arPts.append(pLine1->endPoint());
arPts.append(pLine2->startPoint());
arPts.append(pLine2->endPoint());
SortPoints(arPts,pLine1);
pLine1->setStartPoint(arPts.first());
pLine1->setEndPoint(arPts.last());
pLine2->erase();
//对外轮廓线合并
MergeOutLine(idOut11,idOut21,idOut22);
MergeOutLine(idOut12,idOut21,idOut22);
}
else
{
acutPrintf(_T("\n选择管线不同线,不能合并!"));
}
}
}
}
AcDbPolyline* pPl1 = AcDbPolyline::cast(pEnt1);
AcDbPolyline* pPl2 = AcDbPolyline::cast(pEnt2);
if (pPl1 != NULL && pPl2 != NULL)
{
double dWidth = 0.0,dWidth2 = 0.0;
pPl1->getConstantWidth(dWidth);
pPl2->getConstantWidth(dWidth2);
pPl1->setConstantWidth(0.0);
pPl2->setConstantWidth(0.0);
if (pPl1->isOnlyLines() && pPl2->isOnlyLines())
{
//排序
AcGePoint3dArray arPts;
AcGePoint3d ptGe,ptGeT,ptGe2;
pPl1->getStartPoint(ptGe);
pPl1->getEndPoint(ptGe2);
AcGeVector3d vt1 = ptGe - ptGe2;
AcDbLine line(ptGe2,ptGe);
pPl2->getEndPoint(ptGe);
pPl2->getStartPoint(ptGeT);
AcGeVector3d vt2 = ptGe - ptGeT;
line.getClosestPointTo(ptGe,ptGeT,Adesk::kTrue);
if (ptGe.distanceTo(ptGeT) < 1.e-3)
{
if (vt2.isParallelTo(vt1))
{
pPl1->getStartPoint(ptGe);
arPts.append(ptGe);
pPl1->getEndPoint(ptGe);
arPts.append(ptGe);
pPl2->getStartPoint(ptGe);
arPts.append(ptGe);
pPl2->getEndPoint(ptGe);
arPts.append(ptGe);
AcDbLine line(arPts.first(),arPts.last());
SortPoints(arPts,&line);
AcGePlane plane(AcGePoint3d::kOrigin + pPl1->normal() * pPl1->elevation(), pPl1->normal());
pPl1->setPointAt(0,arPts.first().convert2d(plane));
pPl1->setPointAt(1,arPts.last().convert2d(plane));
pPl1->setConstantWidth(dWidth);
pPl2->erase();
}
else
{
acutPrintf(_T("\n选择管线不同线,不能合并!"));
}
}
}
else
{
}
pPl1->setConstantWidth(dWidth);
pPl2->setConstantWidth(dWidth2);
}
pEnt2->close();
}
pEnt1->close();
}
return TRUE;
}
BOOL KTPipeOper::FindPipePair(AcDbLine* pLineCen,AcDbObjectId& id1,AcDbObjectId& id2)
{
if (pLineCen == NULL) return FALSE;
AcGeVector3d vtCen = pLineCen->endPoint() - pLineCen->startPoint();
AcDbObjectId idCen = pLineCen->objectId();
AcGePoint3d ptGeIn = KTGeUtility::Mid(pLineCen->endPoint(),pLineCen->startPoint());
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] -= MAXPIPED * 0.5;pt1[Y] += MAXPIPED * 0.5;
pt2[X] += MAXPIPED * 0.5;pt2[Y] -= MAXPIPED * 0.5;
acdbWcs2Ucs(pt1,pt1,false);
acdbWcs2Ucs(pt2,pt2,false);
struct resbuf* pRb = NULL;
pRb = acutBuildList(RTDXF0,_T("LINE"),NULL);
ads_name ssname,ent;
acedSSGet(_T("C"),pt1,pt2,pRb,ssname);
acutRelRb(pRb);
Adesk::Int32 lLen = 0l;
acedSSLength(ssname,&lLen);
AcDbObjectIdArray arIds;
AcDbObjectId id;
for(int i = 0;i < lLen;i++)
{
acedSSName(ssname,i,ent);
if (Acad::eOk == acdbGetObjectId(id,ent))
{
arIds.append(id);
}
}
acedSSFree(ssname);
arIds.remove(idCen);
//寻找平行pLineCen的最短的直线
int nFirst = -1,nSecond = -1;
KTGeUtility::FindClosestLineParallelTo(arIds,pLineCen,nFirst);
if (nFirst != -1)
{
id1 = arIds.at(nFirst);
arIds.removeAt(nFirst);
}
KTGeUtility::FindClosestLineParallelTo(arIds,pLineCen,nSecond);
if (nSecond != -1)
{
id2 = arIds.at(nSecond);
arIds.removeAt(nSecond);
}
//找到,返回TRUE
if (nFirst != -1 && nSecond != -1)
{
return TRUE;
}
return FALSE;
}
BOOL KTPipeOper::FindPipePair(const AcDbObjectId& idCen,AcDbObjectId& id1,AcDbObjectId& id2)
{
BOOL bSuccess = FALSE;
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idCen,AcDb::kForRead) )
{
AcDbLine* pLineCen = AcDbLine::cast(pEnt);
if (pLineCen != NULL)
{
bSuccess = KTPipeOper::FindPipePair(pLineCen,id1,id2);
}
pEnt->close();
}
return bSuccess;
}
BOOL KTPipeOper::FindPipeCen(AcGePoint3d& ptGeIn,AcDbObjectId& idCen)
{
//该点附近有管线,根据管线确定中线
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] -= 10.0;pt1[Y] += 10.0;
pt2[X] += 10.0;pt2[Y] -= 10.0;
acdbWcs2Ucs(pt1,pt1,false);
acdbWcs2Ucs(pt2,pt2,false);
struct resbuf* pRb = NULL;
pRb = acutBuildList(RTDXF0,_T("LINE,LWPOLYLINE"),NULL);
ads_name ssname,ent;
acedSSGet(_T("C"),pt1,pt2,pRb,ssname);
Adesk::Int32 lLen = 0l;
acedSSLength(ssname,&lLen);
AcDbEntity* pEnt = NULL;
AcDbObjectId id;
AcDbObjectId idCl = KTSetting::InitLayer(_T("LAY_CL"));
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) )
{
if (idCl == pEnt->layerId()) //是中心线
{
//验证扩展数据是管子中心线
AecDbObjXDataMap objXData;
if (objXData.Read(pEnt,PIDPIPE_APP))
{
int nKind = -1;
objXData.GetAt(PIPE_FITTING,nKind);
if (nKind == 0) //是管子中心线
{
idCen = id;
pEnt->close();
acedSSFree(ssname);
acutRelRb(pRb);
return TRUE;
}
}
}
//是管线
pEnt->close();
}
}
}
acedSSFree(ssname);
acutRelRb(pRb);
return FALSE;
}
BOOL KTPipeOper::FindPipeCen(AcGePoint3d& ptGeIn,AcDbObjectId& idCen,int & npipe,double dPipeW)
{
//该点附近有管线,根据管线确定中线
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;
AcDbObjectId idCl = KTSetting::InitLayer(_T("LAY_CL"));
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))
{
int nKind = -1;
objXData.GetAt(PIPE_FITTING,nKind);
if (nKind == 0) //是管子中心线
{
AcDbPolyline * pPline = AcDbPolyline::cast(pEnt);
if (pPline!=NULL) //如果是PL则管道为单线
{
npipe = 0;
pPline->getClosestPointTo(ptGeIn,ptGeIn);
pPline->close();
}
else
{
AcDbLine * pLine = AcDbLine::cast(pEnt);
if (pLine!=NULL) //如果是PL则管道为单线
{
npipe = 1;
pLine->getClosestPointTo(ptGeIn,ptGeIn);
pLine->close();
}
AecDbEwPipe* pPipe = AecDbEwPipe::cast(pEnt);
if (pPipe != NULL)
{
npipe = 1;
pPipe->getClosestPointTo(ptGeIn,ptGeIn);
pPipe->close();
}
}
idCen = id;
pEnt->close();
acedSSFree(ssname);
return TRUE;
}
}
//是管线
pEnt->close();
}
}
}
acedSSFree(ssname);
// acutRelRb(pRb);
return FALSE;
}
BOOL KTPipeOper::FindPipeCenPt(AcGePoint3d& ptGeIn,AcDbObjectId& idCen,int & npipe,double dPipeW,AcGePoint3d & pts,AcGePoint3d & pte)
{
//该点附近有管线,根据管线确定中线
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;
AcDbObjectId idCl = KTSetting::InitLayer(_T("LAY_CL"));
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))
{
int nKind = -1;
objXData.GetAt(PIPE_FITTING,nKind);
if (nKind == 0) //是管子中心线
{
AcDbPolyline * pPline = AcDbPolyline::cast(pEnt);
if (pPline!=NULL) //如果是PL则管道为单线
{
npipe = 0;
pPline->getStartPoint(pts);
pPline->getEndPoint(pte);
pPline->getClosestPointTo(ptGeIn,ptGeIn);
pPline->close();
}
else
{
AcDbLine * pLine = AcDbLine::cast(pEnt);
if (pLine!=NULL) //如果是PL则管道为单线
{
npipe = 1;
pts=pLine->startPoint();
pte=pLine->endPoint();
pLine->getClosestPointTo(ptGeIn,ptGeIn);
pLine->close();
}
}
idCen = id;
pEnt->close();
acedSSFree(ssname);
return TRUE;
}
}
//是管线
pEnt->close();
}
}
}
acedSSFree(ssname);
return FALSE;
}
BOOL KTPipeOper::SelectPipeCen(LPCTSTR pszTip,AcDbObjectId& idCen,AcGePoint3d& ptGeHit)
{
if (pszTip == NULL) pszTip = _T("\n选择管线的中心线<退出>:");
int nRes = 0;
ads_name ent;
ads_point pt;
AcDbObjectId id;
while(TRUE)
{
nRes = acedEntSel(pszTip,ent,pt);
if (nRes == RTNORM)
{
acdbGetObjectId(id,ent);
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead) )
{
//验证扩展数据是管子中心线
AecDbObjXDataMap objXData;
if (objXData.Read(pEnt,PIDPIPE_APP))
{
int nKind = -1;
objXData.GetAt(PIPE_FITTING,nKind);
if (nKind == 0) //是管子中心线
{
AcDbCurve* pCurve = AcDbCurve::cast(pEnt);
if (pCurve != NULL)
{
ptGeHit = asPnt3d(pt);
pCurve->getClosestPointTo(ptGeHit,ptGeHit,Adesk::kTrue);
idCen = id;
pEnt->close();
return TRUE;
}
}
}
pEnt->close();
}
}
if (nRes == RTNONE ||
nRes == RTCAN)
{
break;
}
}
return FALSE;
}
BOOL KTPipeOper::SplitPipe(AcDbEntity* pEnt1,WPipe::PipeParam* pParam,AecDbObjXDataMap* pxData,
AcGePoint3d& ptGeIns,double dL1)
{
if (pEnt1 == NULL || pParam == NULL) return FALSE;
AcDbLine* pLine = NULL;
AcGeVector3d vtDir,vtNormal;
AcGePoint3d ptGe1,ptGe2,ptGeT;
AcDbPolyline* pPl = AcDbPolyline::cast(pEnt1);
if (pPl != NULL) //认为是只有两点的pline线
{
int nVerts = pPl->numVerts();
if (nVerts != 2)
{
return FALSE;
}
//判断是否是直线的pline线
double dBulge = 0.0;
pPl->getBulgeAt(1,dBulge);
if ( fabs(dBulge) > 1.e-10)
{
return FALSE;
}
AcGePoint3d ptGeSta,ptGeEnd;
pPl->getStartPoint(ptGeSta);
pPl->getEndPoint(ptGeEnd);
AcGePlane plane(AcGePoint3d::kOrigin+pPl->normal()*pPl->elevation(), pPl->normal());
//模板线
AcDbLine lineT(ptGeSta,ptGeEnd);
pLine = &lineT;
vtNormal = pPl->normal();
vtDir = ptGeEnd - ptGeSta;
vtDir.normalize();
ptGe1 = ptGeIns - vtDir * dL1; //sta
ptGe2 = ptGeIns + vtDir * dL1; //end
//1.两个点都在pline 上
double dSta = 0.0,dEnd = 0.0,dDist = 0.0;
pLine->getStartParam(dSta);
pLine->getEndParam(dEnd);
double dParam1 = 0.0,dParam2 = 0.0;
pLine->getParamAtPoint(ptGe1,dParam1);
pLine->getParamAtPoint(ptGe2,dParam2);
if (dParam1 - dSta > 1.e-10 &&
dParam2 - dEnd < 1.e-10) //都在内
{
ptGeT = ptGeEnd;
AcDbObjectId idLay = pPl->layerId();
double dEl = pPl->elevation();
dDist = ptGe2.distanceTo(ptGeSta);
if (dDist - pParam->m_dD * 0.5 > 1.e-6)//最小管长,半径长
{
pPl->setPointAt(1,ptGe1.convert2d(plane));
}
else
{
pPl->erase();//删除
}
dDist = ptGe2.distanceTo(ptGeT);
if (dDist - pParam->m_dD * 0.5 > 1.e-6)//最小管长,半径长
{
AcDbPolyline* pLine2 = new AcDbPolyline;//(ptGe2,ptGeT);
pLine2->addVertexAt(0,ptGe2.convert2d(plane));
pLine2->addVertexAt(1,ptGeT.convert2d(plane));
pLine2->setNormal(vtNormal);
pLine2->setElevation(dEl);
if (pxData != NULL)
pxData->Write(pLine2,PIDPIPE_APP);
pLine2->setLayer(idLay);
CKTCadUtility::AddToBlockTableRecord(pLine2);
pLine2->close();
}
}
else if(dParam1 - dSta < 1.e-10 &&
dParam2 - dEnd < 1.e-10) //超出 sta点
{
dDist = ptGe2.distanceTo(ptGeEnd);
if (dDist - pParam->m_dD * 0.5 > 1.e-10)
{
pPl->setPointAt(0,ptGe2.convert2d(plane));
}
else
{
pPl->erase();
}
}
else if (dParam1 - dSta > 1.e-10 &&
dParam2 - dEnd > 1.e-10) //超出 end点
{
dDist = ptGe2.distanceTo(pLine->startPoint());
if (dDist - pParam->m_dD * 0.5 > 1.e-10)
{
pPl->setPointAt(1,ptGe1.convert2d(plane));
}
else
{
pPl->erase();
}
}
else if (dParam1 - dSta < 1.e-10 &&
dParam2 - dEnd > 1.e-10) //全部超出
{
pPl->erase();
}
/*else
{
}*/
return TRUE;
}
pLine = AcDbLine::cast(pEnt1);
if (pLine != NULL)
{
vtNormal = pLine->normal();
vtDir = pLine->endPoint() - pLine->startPoint();
vtDir.normalize();
ptGe1 = ptGeIns - vtDir * dL1; //sta
ptGe2 = ptGeIns + vtDir * dL1; //end
//1.两个点都在pline 上
double dSta = 0.0,dEnd = 0.0,dDist = 0.0;
pLine->getStartParam(dSta);
pLine->getEndParam(dEnd);
double dParam1 = 0.0,dParam2 = 0.0;
pLine->getParamAtPoint(ptGe1,dParam1);
pLine->getParamAtPoint(ptGe2,dParam2);
if (dParam1 - dSta > 1.e-10 &&
dParam2 - dEnd < 1.e-10) //都在内
{
ptGeT = pLine->endPoint();
AcDbObjectId idLay = pLine->layerId();
dDist = ptGe2.distanceTo(pLine->startPoint());
if (dDist - pParam->m_dD * 0.5 > 1.e-6)//最小管长,半径长
{
pLine->setEndPoint(ptGe1);
}
else
{
pLine->erase();//删除
}
dDist = ptGe2.distanceTo(ptGeT);
if (dDist - pParam->m_dD * 0.5 > 1.e-6)//最小管长,半径长
{
AcDbLine* pLine2 = new AcDbLine(ptGe2,ptGeT);
pLine2->setNormal(vtNormal);
if (pxData != NULL)
pxData->Write(pLine2,PIDPIPE_APP);
pLine2->setLayer(idLay);
CKTCadUtility::AddToBlockTableRecord(pLine2);
pLine2->close();
}
}
else if(dParam1 - dSta < 1.e-10 &&
dParam2 - dEnd < 1.e-10) //超出 sta点
{
dDist = ptGe2.distanceTo(pLine->endPoint());
if (dDist - pParam->m_dD * 0.5 > 1.e-10)
{
pLine->setStartPoint(ptGe2);
}
else
{
pLine->erase();
}
}
else if (dParam1 - dSta > 1.e-10 &&
dParam2 - dEnd > 1.e-10) //超出 end点
{
dDist = ptGe2.distanceTo(pLine->startPoint());
if (dDist - pParam->m_dD * 0.5 > 1.e-10)
{
pLine->setEndPoint(ptGe1);
}
else
{
pLine->erase();
}
}
else if (dParam1 - dSta < 1.e-10 &&
dParam2 - dEnd > 1.e-10) //全部超出
{
pLine->erase();
}
/*else
{
}*/
}
return TRUE;
}
BOOL KTPipeOper::SplitPipe(AcGePoint3d& ptGeIns,double dL1,AcDbEntity* pEnt1,AcDbObjectId& id11,AcDbObjectId& id12)
{
if (pEnt1 == NULL) return FALSE;
AecDbObjXDataMap xData1;
xData1.Read(pEnt1,PIDPIPE_APP);
WPipe::PipeParam param1;
KTFitting::XData2PipeParam(&param1,&xData1, NULL);
//1.管子中线
KTPipeOper::SplitPipe(pEnt1,&param1,&xData1,ptGeIns,dL1);
AcGePoint3d ptGeIns2;
//2.管子轮廓线1
AcDbEntity* pEnt11 = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt11,id11,AcDb::kForWrite) )
{
AcDbCurve* pCurve = AcDbCurve::cast(pEnt11);
if (pCurve != NULL)
{
pCurve->getClosestPointTo(ptGeIns,ptGeIns2);
KTPipeOper::SplitPipe(pEnt11,&param1,NULL,ptGeIns2,dL1);
pEnt11->close();
}
}
//3.管子轮廓线2
AcDbEntity* pEnt12 = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt12,id12,AcDb::kForWrite) )
{
AcDbCurve* pCurve = AcDbCurve::cast(pEnt12);
if (pCurve != NULL)
{
pCurve->getClosestPointTo(ptGeIns,ptGeIns2);
KTPipeOper::SplitPipe(pEnt12,&param1,NULL,ptGeIns2,dL1);
pEnt12->close();
}
}
return FALSE;
}
BOOL KTPipeOper::TrimPipe(AcDbEntity* pEnt2,AcGePoint3d& ptGeIns,AcGePoint3d& ptGeOn,double dL2)
{
if (pEnt2 == NULL) return FALSE;
AcGeVector3d vtCutTo = ptGeOn - ptGeIns;
vtCutTo.normalize();
// ptGeOn
//ptGeIns sta--------+--------------------end
AcDbPolyline* pPl = AcDbPolyline::cast(pEnt2);
if (pPl != NULL && pPl->numVerts() == 2)
{
AcGePoint2d ptGe2D;
AcGePoint3d ptGeSta,ptGeEnd;
pPl->getStartPoint(ptGeSta);
pPl->getEndPoint(ptGeEnd);
AcGePlane plane(AcGePoint3d::kOrigin+pPl->normal()*pPl->elevation(), pPl->normal());
ptGeOn = ptGeIns + dL2 * vtCutTo;
AcGeVector3d vtDir = ptGeEnd - ptGeSta;
if (vtDir.isCodirectionalTo(vtCutTo) )//同LINE方向sta->end
{
vtDir = ptGeOn - ptGeSta;
if (vtDir.isCodirectionalTo(vtCutTo) ) //落在line同向上
{
vtDir = ptGeOn - ptGeEnd;
if (vtDir.isCodirectionalTo(vtCutTo))//落在 end 之外
{
pPl->erase();
}
else
{
ptGe2D = ptGeOn.convert2d(plane);
pPl->setPointAt(0,ptGe2D);
}
}
else //在sta 的延长端,ptGeIns 也在sta的延长端,同向
{
ptGe2D = ptGeOn.convert2d(plane);
pPl->setPointAt(0,ptGe2D);
}
}
else //
{
vtDir = ptGeOn - ptGeEnd;
if (vtDir.isCodirectionalTo(vtCutTo) ) //落在line上
{
vtDir = ptGeOn - ptGeSta;
if (vtDir.isCodirectionalTo(vtCutTo)) //落在sta之外
{
pPl->erase();
}
else
{
ptGe2D = ptGeOn.convert2d(plane);
pPl->setPointAt(1,ptGe2D);
}
}
else //在end 的延长端,ptGeIns 也在end的延长端,同向
{
ptGe2D = ptGeOn.convert2d(plane);
pPl->setPointAt(1,ptGe2D);
}
}
return TRUE;
}
AcDbLine* pLine = AcDbLine::cast(pEnt2);
if (pLine != NULL)
{
ptGeOn = ptGeIns + dL2 * vtCutTo;
AcGeVector3d vtDir = pLine->endPoint() - pLine->startPoint();
if (vtDir.isCodirectionalTo(vtCutTo) )//同LINE方向sta->end
{
vtDir = ptGeOn - pLine->startPoint();
if (vtDir.isCodirectionalTo(vtCutTo) ) //落在line同向上
{
vtDir = ptGeOn - pLine->endPoint();
if (vtDir.isCodirectionalTo(vtCutTo))//落在 end 之外
{
pLine->erase();
}
else
{
pLine->setStartPoint(ptGeOn);
}
}
else //在sta 的延长端,ptGeIns 也在sta的延长端,同向
{
pLine->setStartPoint(ptGeOn);
}
}
else //
{
vtDir = ptGeOn - pLine->endPoint();
if (vtDir.isCodirectionalTo(vtCutTo) ) //落在line上
{
vtDir = ptGeOn - pLine->startPoint();
if (vtDir.isCodirectionalTo(vtCutTo)) //落在sta之外
{
pLine->erase();
}
else
{
pLine->setEndPoint(ptGeOn);
}
}
else //在end 的延长端,ptGeIns 也在end的延长端,同向
{
pLine->setEndPoint(ptGeOn);
}
}
}
return TRUE;
}
BOOL KTPipeOper::TrimPipe(AcGePoint3d& ptGeIns,AcGePoint3d& ptGeOn,double dL2,AcDbEntity* pEnt2,
AcDbObjectId& id21,AcDbObjectId& id22)
{
KTTempTol tol(1.e-6);
KTPipeOper::TrimPipe(pEnt2,ptGeIns,ptGeOn,dL2);
//边线1
AcGePoint3d ptGeT1,ptGeT2;
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id21,AcDb::kForWrite))
{
AcDbCurve* pCurve = AcDbCurve::cast(pEnt);
if (pCurve != NULL)
{
pCurve->getClosestPointTo(ptGeIns,ptGeT1,Adesk::kTrue);
pCurve->getClosestPointTo(ptGeOn,ptGeT2,Adesk::kTrue);
KTPipeOper::TrimPipe(pEnt,ptGeT1,ptGeT2,dL2);
}
pEnt->close();
}
//边线2
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id22,AcDb::kForWrite))
{
AcDbCurve* pCurve = AcDbCurve::cast(pEnt);
if (pCurve != NULL)
{
pCurve->getClosestPointTo(ptGeIns,ptGeT1,Adesk::kTrue);
pCurve->getClosestPointTo(ptGeOn,ptGeT2,Adesk::kTrue);
KTPipeOper::TrimPipe(pEnt,ptGeT1,ptGeT2,dL2);
}
pEnt->close();
}
return TRUE;
}
double KTPipeOper::GetDocScale(AecDbObjXDataMap* pInitData)
{
CString sDocScale = _T("");
pInitData->GetAt(_T("Scale"),sDocScale);
int nIndex = sDocScale.Find(':',0);
double dDocScale = 1.0;
if (nIndex != -1)
{
dDocScale = _ttof(sDocScale.Mid(nIndex + 1)) / _ttof(sDocScale.Mid(0,nIndex));
}
return dDocScale;
}
BOOL KTPipeOper::WeldjointPipe(AcGePoint3d& ptGeIns,AcGeVector3d& vtWeldDir,WPipe::PipeParam* pParamThis,
AcDbObjectId& idCen,BOOL& bCenNeedExtended)
{
BOOL bSuccess = FALSE;
bCenNeedExtended = TRUE;
AcDbObjectId id1,id2;
if (FindPipePair(idCen,id1,id2))
{
//打开侧线
AcDbEntity* pEnt1 = NULL,*pEnt2 = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForRead) )
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,id2,AcDb::kForRead))
{
AcDbLine* pLine1 = AcDbLine::cast(pEnt1);
AcDbLine* pLine2 = AcDbLine::cast(pEnt2);
if (pLine1 != NULL && pLine2 != NULL)
{
AcDbEntity* pEntCen = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEntCen,idCen,AcDb::kForRead))
{
AcDbLine* pLine = AcDbLine::cast(pEntCen);
if (pLine != NULL)
{
AcGePoint3d ptGeOn;
pLine->getClosestPointTo(ptGeIns,ptGeOn,Adesk::kTrue);
ptGeIns = ptGeOn;
WPipe::PipeParam param1;
AecDbObjXDataMap objXData;
if (objXData.Read(pEntCen,PIDPIPE_APP) )
{
KTFitting::XData2PipeParam(&param1,&objXData, NULL);
//获取初始化数据
AecDbObjXDataMap xDataMap;
PIDLineTools::ReSet(xDataMap);
KTModelLayoutXData::ReadModelXData(KT_PIPEINIT,xDataMap);
double dMinDn = 0.0;
xDataMap.GetAt(DOC_PIPEMAXDIA,dMinDn);
//根据两根管子的DN 确定焊接
double dDN1 = pParamThis->m_dDN;
double dDN2 = param1.m_dDN;
if (dDN2 - dDN1 > -1.e-10)//对方直径>= this
{
AcGeVector3d vtPipe = pLine->endPoint() - pLine->startPoint();
vtPipe.normalize();
vtWeldDir.normalize();
double dArch = 0.5 * (dDN2 - sqrt(dDN2 * dDN2 - dDN1 * dDN1));
AcGePoint3d ptGe1,ptGe2,ptGe3,ptGe4,ptGe44;
ptGe2 = ptGeIns + (dDN2 * 0.5 - dArch) * vtWeldDir;
ptGe1 = ptGeIns + dDN2 * 0.5 * vtWeldDir;
ptGe3 = ptGe1 + dDN1 * 0.5 * vtPipe;
ptGe4 = ptGeIns + 0.5 * dDN2 * vtWeldDir;
ptGe1 = ptGe3 - dDN1 * vtPipe;
AcDbEntity* pEntBreak = NULL;
pLine1->getClosestPointTo(ptGe4,ptGe44,Adesk::kTrue);
double dDist1 = ptGe44.distanceTo(ptGe4);
pEntBreak = (dDist1 < 1.e-1) ? pLine1 : pLine2;
if (fabs(dDN1 - dDN2) < 1.e-6) //三角形相贯线
{
//判断当前是否画单线
if (pParamThis->m_dD - dMinDn > -1.e-10)//双线
{
pEntBreak->upgradeOpen();
KTGeUtility::MidBreakLine(pEntBreak,ptGe4,dDN1 * 0.5);
pEntBreak->downgradeOpen();
AcDbLine* pLine11 = new AcDbLine(ptGeIns,ptGe1);
pLine11->setLayer(pLine1->layer());
CKTCadUtility::AddToBlockTableRecord(pLine11);
pLine11->close();
AcDbLine* pLine22 = new AcDbLine(ptGeIns,ptGe3);
pLine22->setLayer(pLine2->layer());
CKTCadUtility::AddToBlockTableRecord(pLine22);
pLine22->close();
bSuccess = TRUE;
ptGeIns = ptGe4;
bCenNeedExtended = FALSE;
}
else
{
double dWeld = 1.0;
xDataMap.GetAt(DOC_WELDDIA,dWeld);
dWeld *= GetDocScale(&xDataMap) * 0.5;
//画个焊点
AcDbPolyline* pDot = new AcDbPolyline;
AcDb::Planarity nType = AcDb::kPlanar;
AcGePlane plane = AcGePlane::kXYPlane;
KTFitting::FormatDot(ptGeIns,dWeld,pDot,plane,pLine1->normal());
pDot->setLayer(pLine1->layer());
CKTCadUtility::AddToBlockTableRecord(pDot);
pDot->close();
bSuccess = TRUE;
}
}
else //圆相贯线
{
//判断当前是否画单线
if (pParamThis->m_dD - dMinDn > -1.e-10)//双线
{
AcGeVector3d vtNormal;
AcDbArc* pArc = new AcDbArc;
if (KTFitting::FormatArc(pArc,ptGe1,ptGe2,ptGe3,vtNormal))
{
pArc->setLayer(pLine1->layer());
pEntBreak->upgradeOpen();
KTGeUtility::MidBreakLine(pEntBreak,ptGe4,dDN1 * 0.5);
pEntBreak->downgradeOpen();
CKTCadUtility::AddToBlockTableRecord(pArc);
pArc->close();
bSuccess = TRUE;
ptGeIns = ptGe4;
}
else
{
delete pArc;
}
}
else //单线
{
double dWeld = 1.0;
xDataMap.GetAt(DOC_WELDDIA,dWeld);
dWeld *= GetDocScale(&xDataMap) * 0.5;
//画个焊点
AcDbPolyline* pDot = new AcDbPolyline;
AcDb::Planarity nType = AcDb::kPlanar;
AcGePlane plane = AcGePlane::kXYPlane;
KTFitting::FormatDot(ptGeIns,dWeld,pDot,plane,pLine1->normal());
pDot->setLayer(pLine1->layer());
CKTCadUtility::AddToBlockTableRecord(pDot);
pDot->close();
bSuccess = TRUE;
}
}
}
else
{
acutPrintf(_T("\n焊接到的管子直径大于本方!"));
}
}
}
pEntCen->close();
}
}
pEnt2->close();
}
pEnt1->close();
}
}
else
{
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idCen,AcDb::kForRead) )
{
AcDbPolyline* pPolyline = AcDbPolyline::cast(pEnt);
if (pPolyline != NULL)
{
//获取初始化数据
AecDbObjXDataMap xDataMap;
PIDLineTools::ReSet(xDataMap);
KTModelLayoutXData::ReadModelXData(KT_PIPEINIT,xDataMap);
double dWeld = 1.0;
xDataMap.GetAt(DOC_WELDDIA,dWeld);
dWeld *= GetDocScale(&xDataMap) * 0.5;
//画个焊点
AcDbPolyline* pDot = new AcDbPolyline;
AcGePlane plane(AcGePoint3d::kOrigin+pPolyline->normal()*pPolyline->elevation(), pPolyline->normal());
KTFitting::FormatDot(ptGeIns,dWeld,pDot,plane,pPolyline->normal());
AcDbObjectId idDot = KTSetting::InitLayer(_T("LAY_DOT"));
pDot->setLayer(idDot);
CKTCadUtility::AddToBlockTableRecord(pDot);
pDot->close();
bSuccess = TRUE;
}
pEnt->close();
}
}
return bSuccess;
}
BOOL KTPipeOper::FindPipeVector(AcGePoint3d& ptGe,AcGeVector3d& vtDir,WPipe::PipeParam& param1,
AcGeVector3d& vtNorm,AcDbObjectId& idPipeCen,BOOL bAndOnOther)
{
AcGePoint3d ptGe1,ptGe2;
ads_point pt,pt1;
BOOL bSuccess = FALSE;
KTCADSysVar<int> cadSysVar(_T("OSMODE"),AcDb::kOsModeEnd);
CString sTip = _T("\n选择管口端点<退出>:");
if (bAndOnOther)
{
cadSysVar.ReSet(AcDb::kOsModeEnd | AcDb::kOsModeMid | AcDb::kOsModeQuad);
sTip = _T("\n选择管口端点或管线上一点<退出>:");
}
int nRes = acedGetPoint(NULL,sTip,pt1);
switch(nRes)
{
case RTNORM:
{
acdbUcs2Wcs(pt1,pt,false);
ptGe1 = asPnt3d(pt);
ptGe = ptGe1;
ptGe1.x -= m_dPickBox * 0.55;
ptGe1.y += m_dPickBox * 0.55;
ptGe2 = ptGe1;
ptGe2.x += m_dPickBox * 1.1;
ptGe2.y -= m_dPickBox * 1.1;
pt[X] = ptGe1.x;pt[Y] = ptGe1.y;pt[Z] = ptGe1.z;
pt1[X] = ptGe2.x;pt1[Y] = ptGe2.y;pt1[Z] = ptGe2.z;
acdbWcs2Ucs(pt,pt,false);
acdbWcs2Ucs(pt1,pt1,false);
ads_name ss;
struct resbuf* pRb = NULL;
pRb = acutBuildList(RTDXF0,_T("LINE,LWPOLYLINE,ARC"),NULL);
acedSSGet(_T("C"),pt,pt1,pRb,ss);
ads_name ent;
AcDbObjectId id;
AcDbEntity* pEnt = NULL;
Adesk::Int32 lLen = 0;
double dSta = 0.0,dEnd = 0.0,dOn = 0.0;
acedSSLength(ss,&lLen);
for (int i = 0;i < lLen;i++)
{
acedSSName(ss,i,ent);
acdbGetObjectId(id,ent);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead))
{
AcDbCurve* pCurve = AcDbCurve::cast(pEnt);
if (pCurve != NULL)
{
AcGePlane plane;
AcDb::Planarity ePlan = AcDb::kPlanar;
pCurve->getPlane(plane,ePlan);
ptGe = ptGe.orthoProject(plane);
pCurve->getClosestPointTo(ptGe,ptGe1);
//落在管线上
double dSpace = ptGe1.distanceTo(ptGe);
if (dSpace - 5.0 > 1.e-10)
{
pEnt->close();
continue;
}
ptGe = ptGe1;
AecDbObjXDataMap objXData;
if (objXData.Read(pEnt,PIDPIPE_APP) )
{
if (!bAndOnOther) //指定落在端点
{
pCurve->getStartParam(dSta);
pCurve->getEndParam(dEnd);
pCurve->getParamAtPoint(ptGe1,dOn);
if (dOn - (dSta + dEnd) / 2.0 > 1.e-10) //靠近end端
{
pCurve->getEndPoint(ptGe);
}
else //靠近sta端
{
pCurve->getStartPoint(ptGe);
}
}
pCurve->getFirstDeriv(ptGe,vtDir);
vtNorm.set(0,0,1);
AcDbLine* pLine = AcDbLine::cast(pCurve);
if (pLine != NULL)
{
vtNorm = pLine->normal();
}
AcDbPolyline* pPl = AcDbPolyline::cast(pCurve);
if (pPl != NULL)
{
vtNorm = pPl->normal();
}
AcDbArc* pArc = AcDbArc::cast(pCurve);
if (pArc != NULL)
{
vtNorm = pArc->normal();
}
AcGePoint3d ptGeMid = KTGeUtility::Mid(pCurve);
AcGeVector3d vtT = ptGe - ptGeMid;
double dDot = vtT.dotProduct(vtDir);
if (dDot < 1.e-10)
vtDir *= -1.0;
bSuccess = KTFitting::XData2PipeParam(&param1,&objXData, NULL);
if (bSuccess)
{
int nKind = -1;
objXData.GetAt(PIPE_FITTING,nKind);
if (nKind == KTFitting::kPipe)
{
idPipeCen = id;
}
}
}
}
pEnt->close();
}
if (bSuccess) break;
}
acedSSFree(ss);
break;
}
case RTNONE:
case RTCAN:
{
break;
}
default:
break;
}
return bSuccess;
}
static BOOL PipeVectorAt(ads_point pt,AcGePoint3d& ptGe,AcGeVector3d& vtDir,WPipe::PipeParam& param1,
AcGeVector3d& vtNorm,AcDbObjectId& idCen,BOOL& bAtEnd,BOOL bAndOnOther)
{
AcGePoint3d ptGe1,ptGe2,ptGeSta,ptGeEnd;
BOOL bSuccess = FALSE;
ads_point pt1;
AecDbObjXDataMap xDataMap;
PIDLineTools::ReSet(xDataMap);
if (!KTModelLayoutXData::ReadModelXData(KT_PIPEINIT,xDataMap))
{
acedAlert(_T("\n系统未初始化!"));
return 0;
}
CString sDocScale = _T("");
xDataMap.GetAt(_T("Scale"),sDocScale);
int nIndex = sDocScale.Find(':',0);
double dDocScale = 1.0;
if (nIndex != -1)
{
dDocScale = _ttof(sDocScale.Mid(nIndex + 1)) / _ttof(sDocScale.Mid(0,nIndex));
}
double dW = 2.0;
xDataMap.GetAt(DOC_PLOTWIDTH,dW);
dW *= dDocScale;
acdbUcs2Wcs(pt,pt,false);
ptGe1 = asPnt3d(pt);
ptGe = ptGe1;
ptGe1.x -= dW * 4.0;
ptGe1.y += dW * 4.0;
ptGe2 = ptGe1;
ptGe2.x += 8.0 * dW;
ptGe2.y -= 8.0 * dW;
pt[X] = ptGe1.x;pt[Y] = ptGe1.y;pt[Z] = ptGe1.z;
pt1[X] = ptGe2.x;pt1[Y] = ptGe2.y;pt1[Z] = ptGe2.z;
acdbWcs2Ucs(pt,pt,false);
acdbWcs2Ucs(pt1,pt1,false);
ads_name ss;
struct resbuf* pRb = NULL;
pRb = acutBuildList(RTDXF0,_T("LINE,LWPOLYLINE,ARC"),NULL);
acedSSGet(_T("C"),pt,pt1,pRb,ss);
ads_name ent;
AcDbObjectId id;
AcDbEntity* pEnt = NULL;
Adesk::Int32 lLen = 0;
double dSta = 0.0,dEnd = 0.0,dOn = 0.0;
acedSSLength(ss,&lLen);
for (int i = 0;i < lLen;i++)
{
acedSSName(ss,i,ent);
acdbGetObjectId(id,ent);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead))
{
AcDbCurve* pCurve = AcDbCurve::cast(pEnt);
if (pCurve != NULL)
{
AcGePlane plane;
AcDb::Planarity ePlan = AcDb::kPlanar;
pCurve->getPlane(plane,ePlan);
ptGe = ptGe.orthoProject(plane);
pCurve->getClosestPointTo(ptGe,ptGe1);
//落在管线上
double dSpace = ptGe1.distanceTo(ptGe);
if (dSpace - dW > 1.e-10)
{
pEnt->close();
continue;
}
AecDbObjXDataMap objXData;
if (objXData.Read(pEnt,PIDPIPE_APP) )
{
if (!bAndOnOther) //指定落在端点
{
pCurve->getStartParam(dSta);
pCurve->getEndParam(dEnd);
pCurve->getParamAtPoint(ptGe1,dOn);
if (dOn - (dSta + dEnd) / 2.0 > 1.e-10) //靠近end端
{
pCurve->getEndPoint(ptGe);
}
else //靠近sta端
{
pCurve->getStartPoint(ptGe);
}
bAtEnd = TRUE;
}
else //指定落在端点时,判断是否落在端点上
{
pCurve->getStartPoint(ptGeSta);
pCurve->getEndPoint(ptGeEnd);
double dDist1 = ptGe1.distanceTo(ptGeSta);
double dDist2 = ptGe1.distanceTo(ptGeEnd);
if (dDist1 - 1.0 < 1.e-6 || dDist2 - 1.0 < 1.e-6)
{
bAtEnd = TRUE;
}
}
ptGe = ptGe1;
pCurve->getFirstDeriv(ptGe1,vtDir);
vtNorm.set(0,0,1);
AcDbLine* pLine = AcDbLine::cast(pCurve);
if (pLine != NULL)
{
vtNorm = pLine->normal();
}
AcDbPolyline* pPl = AcDbPolyline::cast(pCurve);
if (pPl != NULL)
{
vtNorm = pPl->normal();
}
AcDbArc* pArc = AcDbArc::cast(pCurve);
if (pArc != NULL)
{
vtNorm = pArc->normal();
}
AcGePoint3d ptGeMid = KTGeUtility::Mid(pCurve);
AcGeVector3d vtT = ptGe - ptGeMid;
double dDot = vtT.dotProduct(vtDir);
if (dDot < 1.e-10)
vtDir *= -1.0;
idCen = id;
bSuccess = KTFitting::XData2PipeParam(&param1,&objXData, NULL);
}
}
pEnt->close();
}
if (bSuccess) break;
}
acedSSFree(ss);
acutRelRb(pRb);
return bSuccess;
}
BOOL KTPipeOper::FindPipeVector(AcGePoint3d& ptGe,AcGeVector3d& vtDir,WPipe::PipeParam& param1,
AcGeVector3d& vtNorm,AcDbObjectId& idCen,BOOL& bAtEnd,BOOL bAndOnOther)
{
AcGePoint3d ptGe1,ptGe2,ptGeSta,ptGeEnd;
ads_point pt,pt1;
BOOL bSuccess = FALSE;
bAtEnd = FALSE;
CString sKey = _T("");
CString sTip = _T("\n指定管口端点<退出>:");
if (bAndOnOther)
{
sKey = _T("R");
sTip = _T("\n指定管口端点或管线上一点或[相对参考(R)]<退出>:");
}
if (!sKey.IsEmpty())
acedInitGet(RSG_NONULL,sKey);
int nRes = acedGetPoint(NULL,sTip,pt1);
switch(nRes)
{
case RTNORM:
{
bSuccess = PipeVectorAt(pt1,ptGe,vtDir,param1,vtNorm,idCen,bAtEnd,bAndOnOther);
break;
}
case RTKWORD:
{
BOOL bSelectOk = FALSE;
AcDbObjectId id;
AcDbEntity* pEnt = NULL;
AcGePoint3d ptGeBase;
AecDbObjXDataMap objXData;
double dSta = 0.0,dEnd = 0.0,dOn = 0.0;
//1.选择
while (TRUE)
{
ads_name ent;
nRes = acedEntSel(_T("\n指定参考管线靠近端作为参考<退出>:"),ent,pt1);
if (nRes == RTNORM)
{
acdbUcs2Wcs(pt1,pt1,false);
ptGe1 = asPnt3d(pt1);
acdbGetObjectId(id,ent);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead))
{
if (objXData.Read(pEnt,PIDPIPE_APP))
{
AcDbLine* pLine = AcDbLine::cast(pEnt);
if (pLine != NULL)
{
pLine->getClosestPointTo(ptGe1,ptGe1);
double dSta = 0.0,dEnd = 0.0,dOn = 0.0;
pLine->getStartParam(dSta);
pLine->getEndParam(dEnd);
pLine->getParamAtPoint(ptGe1,dOn);
ptGeBase = pLine->startPoint();
if (dOn - (dSta + dEnd) > 1.e-10) //靠近end
{
ptGeBase = pLine->endPoint();
}
bSelectOk = TRUE;
}
AcDbPolyline* pPl = AcDbPolyline::cast(pEnt);
if (pPl != NULL)
{
pLine->getClosestPointTo(ptGe1,ptGe1);
pPl->getStartParam(dSta);
pPl->getEndParam(dEnd);
pPl->getParamAtPoint(ptGe1,dOn);
pPl->getStartPoint(ptGeBase);
if (dOn - (dSta + dEnd) > 1.e-10) //靠近end
{
pPl->getEndPoint(ptGeBase);
}
bSelectOk = TRUE;
}
}
pEnt->close();
if (!bSelectOk)
{
acutPrintf(_T("\n选择的不是管线中线!"));
}
}
}
else if (nRes == RTCAN ||
nRes == RTNONE)
{
return FALSE;
}
if (bSelectOk)
{
pt[X] = ptGeBase.x;pt[Y] = ptGeBase.y;pt[Z] = ptGeBase.z;
acdbWcs2Ucs(pt,pt,false);
sTip = _T("\n指定管线上具体位置<退出>:");
nRes = acedGetPoint(pt,sTip,pt1);
switch(nRes)
{
case RTNORM:
{
bSuccess = PipeVectorAt(pt1,ptGe,vtDir,param1,vtNorm,idCen,bAtEnd,bAndOnOther);
break;
}
default:
break;
}
break;
}
}
break;
}
default:
break;
}
return bSuccess;
}