1925 lines
45 KiB
C++
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(¶m1,&xData1, NULL);
|
|
|
|
//1.管子中线
|
|
KTPipeOper::SplitPipe(pEnt1,¶m1,&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,¶m1,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,¶m1,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(¶m1,&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(¶m1,&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(¶m1,&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;
|
|
}
|