#include "stdafx.h" #include "KTPipeOper.h" #include "KTTempTol.h" #include "KTGeUtility.h" #include "KTFitting.h" #include "KTCADSysVar.h" #include "AecDbEwPipe.h" #include #include #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 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::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 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; }