#include "stdafx.h" #include "AecDbRoadLine.h" #include "AecDb3dRoad.h" #include "AecDb3dRoadFitting.h" #include "AecAngleWatch.h" #include "AecDbRoadJig.h" #include "AECStatusRecord.h" #include "KTSetting.h" #include "CoreTools.h" extern AcGePoint3d MidPoint(const AcGePoint3d& pt1,const AcGePoint3d& pt2); extern DLLIMPEXP AcDbArc* FormatArc(const AcGePoint3d& ptGe1,const AcGePoint3d& ptGe2,const AcGePoint3d& ptGe3); double GetElbowL(WPipe::RoadParam* pParam) { double dRatio = pParam->dRRatio; double dLx = (int)(dRatio * pParam->dSize[0] / 3.0 + 0.5);//默认50 if (dLx > 50.0) dLx = 50.0; double dL = dRatio * pParam->dSize[0] + dLx; return dL; } double GetElbowLx(WPipe::RoadParam* pParam) { double dRatio = pParam->dRRatio; double dLx = (int)(dRatio * pParam->dSize[0] / 3.0 + 0.5);//默认50 if (dLx > 50.0) dLx = 50.0; return dLx; } static AcDbObjectId GetConnectObject(const AecInterface &intf, const CArray &arr) { for (int i = 0; i < arr.GetSize(); ++i) { const AecInterface &ff(arr[i]); if (intf.ptPos == ff.ptPos && intf.idOwner != ff.idOwner) return ff.idOwner; } return AcDbObjectId::kNull; } typedef struct PointParam { AcGePoint3d ptOn; double dParam; }POINTPARAM; static bool ComparePtparam(PointParam ptParam1,PointParam ptParam2) { if (ptParam1.dParam - ptParam2.dParam < 1.e-10) { return true; } return false; } void SortPoints(AcGePoint3dArray& points,AcDbCurve* pLine) { PointParam ptParam; std::vector points2; for (int i = 0;i < points.length();i++) { ptParam.ptOn = points.at(i); pLine->getParamAtPoint(points.at(i),ptParam.dParam); points2.push_back(ptParam); } std::sort(points2.begin(),points2.end(),ComparePtparam); points.setLogicalLength(0); std::vector::iterator it; for (it = points2.begin(); it < points2.end(); it++) { points.append((*it).ptOn); } } AecDbRoadLine::AecDbRoadLine() { m_pAngleWatch = NULL; m_pPipeJig = NULL; m_pPipeParam = NULL; m_pCurPipeLine[0] = NULL; m_pCurPipeLine[1] = NULL; m_bStopCommand = FALSE; m_idStartDragFrom = AcDbObjectId::kNull; } AecDbRoadLine::AecDbRoadLine(AecDbRoadJig* pJig) { m_pAngleWatch = new AecAngleWatch; m_pAngleWatch->m_dSnapAngle *= 0.25;//2.5度 m_pPipeJig = pJig; m_pPipeParam = NULL; m_pCurPipeLine[0] = NULL; m_pCurPipeLine[1] = NULL; m_bStopCommand = FALSE; m_idStartDragFrom = AcDbObjectId::kNull; } AecDbRoadLine::~AecDbRoadLine(void) { if ( m_pAngleWatch != NULL) DELETE_PTR(m_pAngleWatch); } Acad::ErrorStatus AecDbRoadLine::Draw2d(AcGiDraw &mode) const { if (m_pCurPipeLine[0] != NULL ) { ((AecDbRoadLine*)(m_pCurPipeLine[0]))->Draw2d(mode); } if (m_pAngleWatch != NULL && m_pCurPipeLine[0] != NULL) { m_pAngleWatch->Draw2d(mode); } return Acad::eOk; } void AecDbRoadLine::SetPipeParam(WPipe::RoadParam* pPipePar) { m_pPipeParam = pPipePar; } WPipe::RoadParam* AecDbRoadLine::GetPipeParam() { return m_pPipeParam; } int AecDbRoadLine::GetLastInfCount() const { return m_arHistoryIntfs.GetCount(); } AecInterface* AecDbRoadLine::GetLastInterface() { int nLen = m_arHistoryIntfs.GetSize(); if (nLen > 0) { AecInterface& intf = m_arHistoryIntfs[nLen - 1]; return &intf; } return NULL; } AecInterface* AecDbRoadLine::GetLastLastInterface() { int nLen = m_arHistoryIntfs.GetSize(); if (nLen > 1) { AecInterface& intf = m_arHistoryIntfs[nLen - 2]; return &intf; } return NULL; } double AecDbRoadLine::GetEndElevation() const { return m_pPipeParam->m_dEl; } BOOL AecDbRoadLine::MakeArc(WPipe::PipeDraw ePipe) { if (m_arHistoryIntfs.IsEmpty()) return FALSE; if (m_arHistoryIntfs.GetCount() >= 1) { AECStatusRecord* pRecLast = m_pPipeJig->GetTailStatusRec(); AcGePoint3d ptLast = pRecLast->GetAcquirePoint(); AcGePoint3d ptThis = m_pPipeJig->GetCurStatusRec()->GetAcquirePoint(); AecInterface* pLast = GetLastInterface(); AcGeVector3d vtLast = pLast->vtDir; vtLast.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); AcGeVector3d vtThis = ptThis - ptLast; AcGePoint3d ptMid = MidPoint(ptLast,ptThis); if (vtThis.isParallelTo(vtLast))//180.0度的弧 { AcGeVector3d vtCen2Mid = pLast->vtDir; vtCen2Mid.normalize(); double dR = 0.5 * ptLast.distanceTo(ptThis); ptMid += dR * vtCen2Mid; } else { vtThis.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); AcGeLine3d ln1(ptLast,vtLast); AcGeLine3d ln2(ptMid,vtThis); AcGePoint3d ptCen; ln1.intersectWith(ln2,ptCen); double dR = ptCen.distanceTo(ptLast); vtThis = ptMid - ptCen; vtThis.normalize(); ptMid = ptCen + dR * vtThis; } AcDbArc* pArc = FormatArc(ptLast,ptMid,ptThis); if (pArc != NULL) { if (ePipe == WPipe::eToCreate) { AecDb3dRoad* pWpipe = new AecDb3dRoad; AecDbObjXDataMap* pXDataMap = pWpipe->GetSpecialtyData(); //设置图层 AcDbObjectId idLay = KTSetting::InitLayer(LAY_ROAD); pWpipe->setLayer(idLay); pWpipe->SetRoadParam(m_pPipeParam); AecEqui::AecCurveElement el; AecComplexCurve::MakeElement(el,pArc); pWpipe->SetCurveSeg(el); pXDataMap->SetAt(KEY_NORMAL,m_pPipeParam->m_vtNrom); AcDbObjectId id = CoreTools::AddToModelSpace(pWpipe); AcGeVector3d vtDir; pArc->getFirstDeriv(ptThis,vtDir); AcGePoint3d ptS; pArc->getStartPoint(ptS); if (ptS.distanceTo(ptThis) < 1e-2) vtDir.negate();//向外 //记录接口到历史记录 AecInterface intf; intf.ptPos = ptThis; intf.vtDir = vtDir; intf.idOwner = id; PushInterface(intf); } else { if (m_pCurPipeLine[0] == NULL) m_pCurPipeLine[0] = new AecDb3dRoad; AecDb3dRoad* pWpipe = (AecDb3dRoad*)m_pCurPipeLine[0]; AecDbObjXDataMap* pXDataMap = pWpipe->GetSpecialtyData(); pWpipe->SetRoadParam(m_pPipeParam); AecEqui::AecCurveElement el; AecComplexCurve::MakeElement(el,pArc); pWpipe->SetCurveSeg(el); pXDataMap->SetAt(KEY_NORMAL,m_pPipeParam->m_vtNrom); } delete pArc; //TEST return TRUE; } } return FALSE; } BOOL AecDbRoadLine::AddPipeNode(AECStatusRecord* pRec ,WPipe::PipeDraw ePipe ) { switch(ePipe) { case WPipe::eToPreView: { if (m_pPipeJig->GetCurStatusRec()->GetPlanPosition() > 1) { MakeArc(ePipe); } else { //预览 if (m_pCurPipeLine[0] == NULL) m_pCurPipeLine[0] = new AecDb3dRoad; AecDb3dRoad* pWpipe = (AecDb3dRoad*)m_pCurPipeLine[0]; AecDbObjXDataMap* pXDataMap = pWpipe->GetSpecialtyData(); pWpipe->SetRoadParam(m_pPipeParam); AcGePoint3d ptGe,ptGe1,ptGe2; ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint(); ptGe1 = pRec->GetAcquirePoint(); //第一次对齐即可 BOOL bAdjust3d = FALSE; AcGeVector3d vtAg(0,0,0); if (m_arHistoryIntfs.GetSize() == 0) { bAdjust3d = TRUE; vtAg = ptGe1 - ptGe; vtAg.normalize(); switch(m_pPipeParam->m_nAlign) { case 0://底部左 { vtAg.rotateBy(-PI / 2.0,AcGeVector3d::kZAxis); vtAg *= 0.5 * m_pPipeParam->dSize[0]; break; } case 1://底部中 { vtAg.set(0,0,0); break; } case 2://底部右 { vtAg.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtAg *= 0.5 * m_pPipeParam->dSize[0]; break; } default: break; } ptGe += vtAg; ptGe1 += vtAg; } pWpipe->SetCurveSeg(ptGe,ptGe1); if (bAdjust3d) { ptGe1 -= vtAg; } //水平桥架 AcGeVector3d vtDir = AcGeVector3d::kXAxis; vtDir = m_pAngleWatch->m_vtDir; AcGeVector3d vtWDir = vtDir; vtWDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); AcGeVector3d vtNorm = vtDir.crossProduct(vtWDir); pWpipe->GetSpecialtyData()->SetAt(KEY_NORMAL,vtNorm); m_pAngleWatch->m_bFallInSnap = FALSE; m_pAngleWatch->snapWatch(ptGe,ptGe1,vtDir); pRec->SetAcquirePoint(ptGe1); m_pAngleWatch->m_bFallInSnap = TRUE; } break; } case WPipe::eToCreate: { if (m_pPipeJig->GetCurStatusRec()->GetPlanPosition() > 1) { MakeArc(ePipe); } else { AcGePoint3d ptGe,ptGe1; ptGe1 = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint(); ptGe = pRec->GetAcquirePoint(); //判断方向是否一致 int nLen = m_arHistoryIntfs.GetSize(); if (nLen == 0) { //第一次创建 CreateWPipe(pRec,TRUE); //考虑首尾三通 } else { AecInterface tInf = m_arHistoryIntfs[nLen - 1]; AcGeVector3d vtDir1 = tInf.vtDir; AcGeVector3d vtDir2 = ptGe - ptGe1; if (vtDir2.isParallelTo(vtDir1)) //平行,和上次同向,连续画 { if ( !ExtendLastWPipe(pRec) ) { CreateWPipe(pRec,FALSE); } } else //添加弯头过渡 { EFittingType type(eElbow); CreateElbowAndPipe(pRec, type); m_pPipeParam->m_dEl = pRec->GetAcquirePoint().z;//4-24 } } AcGeVector3d vtDir = AcGeVector3d::kXAxis; vtDir = m_pAngleWatch->m_vtDir; ptGe1.z = m_pPipeParam->m_dEl; ptGe.z = m_pPipeParam->m_dEl; m_pAngleWatch->m_bFallInSnap = FALSE; m_pAngleWatch->snapWatch(ptGe1,ptGe,vtDir); m_pAngleWatch->m_bFallInSnap = TRUE; } break; } default: break; } return TRUE; } BOOL AecDbRoadLine::AddReducer(AECStatusRecord* pCurStaRec,WPipe::RoadParam* pParam) { AecDb3dRoadFitting* pFit = new AecDb3dRoadFitting; AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData(); AcGeVector3d vtDir = AcGeVector3d::kXAxis; AecInterface* pIntf = GetLastInterface(); if (pIntf != NULL) { vtDir = pIntf->vtDir; } vtDir.normalize(); AcGePoint3d ptSta = pIntf->ptPos; AcGePoint3d ptEnd = ptSta + vtDir * pParam->m_dL; AcGeVector3d vtNorm = AcGeVector3d::kZAxis; pFit->SetRoadParam(pParam); pFit->GetSpecialtyData()->SetAt(KEY_RUNTIME,(int)eReduce); pFit->GetSpecialtyData()->SetAt(KEY_MAJBR, vtDir); pFit->GetSpecialtyData()->SetAt(KEY_NORMAL, vtNorm); pFit->GetSpecialtyData()->SetAt(KEY_START, ptSta); pFit->GetSpecialtyData()->SetAt(KEY_END, ptEnd); pFit->GetSpecialtyData()->SetAt(PIPE_DN, pParam->dSize[0]); pFit->GetSpecialtyData()->SetAt(PIPE_OD, pParam->dSize[0]); pFit->GetSpecialtyData()->SetAt(PIPE_EDN, pParam->dSize[1]); pFit->GetSpecialtyData()->SetAt(PIPE_EOD, pParam->dSize[1]); pFit->GetSpecialtyData()->SetAt(PIPE_THICK, pParam->dSize[2]); pFit->Create(); //设置图层 AcDbObjectId idLay = KTSetting::InitLayer(LAY_ROAD); int nColor = KTSetting::GetLayerColor(LAY_ROAD); pFit->setLayer(idLay); AcDbObjectId id = CoreTools::AddToModelSpace(pFit); AecInterface intf; intf.ptPos = ptEnd; intf.vtDir = vtDir; intf.idOwner = id; PushInterface(intf); //覆盖当前的param PushPipeParam(); memcpy(m_pPipeParam,pParam,sizeof(WPipe::RoadParam));//回退 //创建余下管子,并插入虚拟状态记录 AECStatusRecord* pRecMid = new AECStatusRecord; pRecMid->CopyFrom(pCurStaRec); pRecMid->SetAcquirePoint(ptEnd); m_pPipeJig->PushBackStatusRec(pRecMid); pCurStaRec->SetAcquirePoint(ptEnd); return TRUE; } AcDbObjectId AecDbRoadLine::CreateElbow(AcGeVector3d vtMaj ,AcGePoint3d ptMid ,AcGeVector3d vtMin ,WPipe::RoadParam* pparam ,BOOL bInsertBeforLast/* = FALSE*/) { AecDb3dRoadFitting* pFit = new AecDb3dRoadFitting; AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData(); //图层 //设置图层 AcDbObjectId idLay = KTSetting::InitLayer(LAY_ROAD); int nColor = KTSetting::GetLayerColor(LAY_ROAD); pFit->setLayer(idLay); pFit->SetRoadParam(pparam); pFit->GetSpecialtyData()->SetAt(KEY_RUNTIME,(int)eElbow); pFit->GetSpecialtyData()->SetAt(KEY_MAJBR, vtMaj); pFit->GetSpecialtyData()->SetAt(KEY_MINBR, vtMin); pFit->GetSpecialtyData()->SetAt(KEY_MID, ptMid); pFit->GetSpecialtyData()->SetAt(PIPE_DN, pparam->dSize[0]); AcGeVector3d vtNorm = vtMin.crossProduct(vtMaj); double dAngle = vtMin.angleTo(vtMaj,vtNorm); pFit->GetSpecialtyData()->SetAt(PIPE_RATIO, pparam->dRRatio); pFit->GetSpecialtyData()->SetAt(PIPE_ELBOWANG,dAngle); pFit->GetSpecialtyData()->SetAt(PIPE_THICK, pparam->dSize[2]); pFit->Create(); AecInterface intf0,intf1; pFit->GetInterface(0,intf0); pFit->GetInterface(1,intf1); m_intf0 = intf0; m_intf1 = intf1; //添加本次到数据库 AcDbObjectId id = CoreTools::AddToModelSpace(pFit); m_intf0.idOwner = id; m_intf1.idOwner = id; //记录接口到历史记录 intf1.idOwner = id; if (m_pPipeJig != NULL) intf1.nType = m_pPipeJig->GetUndoGroupID(); if (bInsertBeforLast) { if (m_arHistoryIntfs.GetSize() > 0) { AecInterface inf = m_arHistoryIntfs[m_arHistoryIntfs.GetSize() - 1]; m_arHistoryIntfs.RemoveAt(m_arHistoryIntfs.GetSize() - 1); PushInterface(intf0); PushInterface(inf); } else { PushInterface(intf0); } } else { PushInterface(intf0); } return id; } AcDbObjectId AecDbRoadLine::CreateElbowEx(AcGeVector3d vtMaj ,AcGePoint3d ptMid ,AcGeVector3d vtMin ,WPipe::RoadParam* pparam1 ,WPipe::RoadParam* pparam2 ,BOOL bInsertBeforLast/* = FALSE*/) { AecDb3dRoadFitting* pFit = new AecDb3dRoadFitting; AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData(); //图层 //设置图层 AcDbObjectId idLay = KTSetting::InitLayer(LAY_ROAD); int nColor = KTSetting::GetLayerColor(LAY_ROAD); pFit->setLayer(idLay); pFit->SetRoadParam(pparam1); pFit->GetSpecialtyData()->SetAt(KEY_RUNTIME,(int)eReduceElbow); pFit->GetSpecialtyData()->SetAt(KEY_MAJBR, vtMaj); pFit->GetSpecialtyData()->SetAt(KEY_MINBR, vtMin); pFit->GetSpecialtyData()->SetAt(KEY_MID, ptMid); pFit->GetSpecialtyData()->SetAt(PIPE_DN, pparam1->dSize[0]); pFit->GetSpecialtyData()->SetAt(PIPE_TDN, pparam2->dSize[0]); AcGeVector3d vtNorm = vtMin.crossProduct(vtMaj); double dAngle = vtMin.angleTo(vtMaj,vtNorm); pFit->GetSpecialtyData()->SetAt(PIPE_RATIO, pparam1->dRRatio); pFit->GetSpecialtyData()->SetAt(PIPE_ELBOWANG,dAngle); pFit->GetSpecialtyData()->SetAt(PIPE_THICK, pparam1->dSize[2]); pFit->Create(); AecInterface intf0,intf1; pFit->GetInterface(0,intf0); pFit->GetInterface(1,intf1); m_intf0 = intf0; m_intf1 = intf1; //添加本次到数据库 AcDbObjectId id = CoreTools::AddToModelSpace(pFit); m_intf0.idOwner = id; m_intf1.idOwner = id; //记录接口到历史记录 intf1.idOwner = id; if (m_pPipeJig != NULL) intf1.nType = m_pPipeJig->GetUndoGroupID(); if (bInsertBeforLast) { if (m_arHistoryIntfs.GetSize() > 0) { AecInterface inf = m_arHistoryIntfs[m_arHistoryIntfs.GetSize() - 1]; m_arHistoryIntfs.RemoveAt(m_arHistoryIntfs.GetSize() - 1); PushInterface(intf0); PushInterface(inf); } else { PushInterface(intf0); } } else { PushInterface(intf0); } return id; } void AecDbRoadLine::SetAngleWath(AcGePoint3d& ptCen,const AcGePoint3d& ptGeTo,const AcGeVector3d& vtDir/* = AcGeVector3d::kXAxis*/) { if (m_pAngleWatch != NULL) { m_pAngleWatch->SetAngleWath(ptCen,ptGeTo,vtDir); } } void AecDbRoadLine::MoveAngWatchPosition() { //导航表盘 if (m_pPipeJig->GetTailStatusRec() != NULL && m_pPipeJig->GetTailStatusRec()->GetStatusType() >= AECStatusRecord::kAngle && m_pPipeJig->GetTailStatusRec()->GetStatusType() <= AECStatusRecord::kPoint) { AcGePoint3d ptGe,ptGe1; ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint(); ptGe1 = m_pPipeJig->m_pCurStaRec->GetAcquirePoint(); AcGeVector3d vtDir; vtDir = m_pAngleWatch->m_vtDir; AecInterface* pLast = GetLastInterface(); if (pLast != NULL) { vtDir = pLast->vtDir; } m_pAngleWatch->SetAngleWath(ptGe,ptGe1,vtDir); } } //画管线停止 BOOL AecDbRoadLine::PipeFinished() { return m_bStopCommand; } void AecDbRoadLine::PopUpInterface(int nGroupID) { while(m_arHistoryIntfs.GetSize() > 0) { if (m_arHistoryIntfs[m_arHistoryIntfs.GetSize() - 1].nType == nGroupID) { m_arHistoryIntfs.RemoveAt(m_arHistoryIntfs.GetSize() - 1); } else { break; } } //回退上次参数 while (m_lstLastPipeParam.GetCount() > 0) { //回上次管道参数 WPipe::RoadParam* pLast = (WPipe::RoadParam*)m_lstLastPipeParam.GetTail(); if (pLast->m_nGroupID == nGroupID) { m_lstLastPipeParam.RemoveTail(); DELETE_PTR(pLast); } else { memcpy(m_pPipeParam,pLast,sizeof(WPipe::RoadParam)); break; } } } void AecDbRoadLine::PushPipeParam() { WPipe::RoadParam* pParam = new WPipe::RoadParam; memcpy(pParam,m_pPipeParam,sizeof(WPipe::RoadParam)); pParam->m_nGroupID = m_pPipeJig->GetUndoGroupID(); m_lstLastPipeParam.AddTail(pParam); } void AecDbRoadLine::PushInterface(AecInterface& intf,BOOL bStartDragFromIt/* = FALSE*/) { m_arHistoryIntfs.Add(intf); if (bStartDragFromIt)//拖出的源对象 { m_idStartDragFrom = intf.idOwner; } } BOOL AecDbRoadLine::CreateWPipe(AECStatusRecord* pRec,BOOL bMaybeAddTee/* = FALSE*/) { AcGePoint3d ptGe,ptGe1; AecDb3dRoad* pWpipe = new AecDb3dRoad; AecDbObjXDataMap* pXDataMap = pWpipe->GetSpecialtyData(); pWpipe->SetRoadParam(m_pPipeParam); //设置图层 AcDbObjectId idLay = KTSetting::InitLayer(LAY_ROAD); int nColor = KTSetting::GetLayerColor(LAY_ROAD); pWpipe->setLayer(idLay); ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint(); ptGe1 = pRec->GetAcquirePoint(); #ifndef _DEBUG_WAS_DEFINED acutPrintf(_T("\n%.3f-%.3f"), ptGe.x, ptGe.y); acutPrintf(_T("\n%.3f-%.3f"), ptGe1.x, ptGe1.y); #endif //第一次对齐即可 AcGeVector3d vtAg(0,0,0); if (m_arHistoryIntfs.GetSize() == 0) { vtAg = ptGe1 - ptGe; vtAg.normalize(); switch(m_pPipeParam->m_nAlign) { case 0://底部左 { vtAg.rotateBy(-PI / 2.0,AcGeVector3d::kZAxis); vtAg *= 0.5 * m_pPipeParam->dSize[0]; break; } case 1://底部中 { vtAg.set(0,0,0); break; } case 2://底部右 { vtAg.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtAg *= 0.5 * m_pPipeParam->dSize[0]; break; } default: break; } ptGe += vtAg; m_pPipeJig->GetTailStatusRec()->SetAcquirePoint(ptGe); } pWpipe->SetCurveSeg( ptGe,ptGe1); AcGeVector3d vtDir = ptGe1 - ptGe; vtDir.normalize(); //法向量,水平桥架 AcGeVector3d vtWDir = vtDir; vtWDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); AcGeVector3d vtNorm = vtDir.crossProduct(vtWDir); pWpipe->GetSpecialtyData()->SetAt(KEY_NORMAL,vtNorm); m_pPipeParam->m_vtNrom = vtNorm; //pWpipe->ReCreateByXDataMap(); AcDbObjectId id = CoreTools::AddToModelSpace(pWpipe); //记录接口到历史记录 AecInterface intf; intf.ptPos = ptGe1; intf.vtDir = vtDir; intf.idOwner = id; PushInterface(intf); if (bMaybeAddTee) //开始端或末端考虑添加三通的可能性 { //1. 可能的与其他管子在开始端合成三通 MaybeAddTeeConnectToThis(ptGe,vtDir,id,0); //2. 可能的与其他管子在末端合成三通,从而结束命令 if ( MaybeAddTeeConnectToThis(ptGe1,vtDir,id,1) ) { //结束命令 m_bStopCommand = TRUE; } //1.可能与其他的管子在中间端合成四通的可能性 MaybeAddCrossConnectToThis(ptGe,ptGe1,id); } else //末端或中间部分添加三通或四通的可能性 { //1.可能与其他的管子在中间端合成四通的可能性 MaybeAddCrossConnectToThis(ptGe,ptGe1,id); //2. 可能的与其他管子在末端合成三通,从而结束命令 if ( MaybeAddTeeConnectToThis(ptGe1,vtDir,id,1) ) { //结束命令 m_bStopCommand = TRUE; } } return TRUE; } BOOL AecDbRoadLine::CreatePipe(AcDbArc* pArc,const AcGePoint3d& ptEnd) { AecDb3dRoad* pWpipe = new AecDb3dRoad; AecDbObjXDataMap* pXDataMap = pWpipe->GetSpecialtyData(); //设置图层 AcDbObjectId idLay = KTSetting::InitLayer(LAY_ROAD); pWpipe->setLayer(idLay); pWpipe->SetRoadParam(m_pPipeParam); AecEqui::AecCurveElement el; AecComplexCurve::MakeElement(el,pArc); pWpipe->SetCurveSeg(el); pXDataMap->SetAt(KEY_NORMAL,m_pPipeParam->m_vtNrom); AcDbObjectId id = CoreTools::AddToModelSpace(pWpipe); AcGeVector3d vtDir; pArc->getFirstDeriv(ptEnd,vtDir); AcGePoint3d ptS; pArc->getStartPoint(ptS); if (ptS.distanceTo(ptEnd) < 1e-2) vtDir.negate();//向外 //记录接口到历史记录 AecInterface intf; intf.ptPos = ptEnd; intf.vtDir = vtDir; intf.idOwner = id; PushInterface(intf); return TRUE; } BOOL AecDbRoadLine::CreatePipe(AcGePoint3d ptSta,AcGePoint3d ptEnd,WPipe::RoadParam* pPipeParam) { AecDb3dRoad* pWpipe = new AecDb3dRoad; AecDbObjXDataMap* pXDataMap = pWpipe->GetSpecialtyData(); //设置图层 AcDbObjectId idLay = KTSetting::InitLayer(LAY_ROAD); pWpipe->setLayer(idLay); pWpipe->SetRoadParam(pPipeParam); pWpipe->SetCurveSeg(ptSta,ptEnd); pXDataMap->SetAt(KEY_NORMAL,pPipeParam->m_vtNrom); if ( fabs(ptSta.z - ptEnd.z) > 1.e-6) { pWpipe->GetSpecialtyData()->SetAt(KEY_DRAWGRAD,TRUE); } AcDbObjectId id = CoreTools::AddToModelSpace(pWpipe); AcGeVector3d vtDir = ptEnd - ptSta; //记录接口到历史记录 AecInterface intf; intf.ptPos = ptEnd; intf.vtDir = vtDir; intf.idOwner = id; PushInterface(intf); return TRUE; } BOOL AecDbRoadLine::ExtendLastWPipe(AECStatusRecord* pRec) { int nLen = m_arHistoryIntfs.GetSize(); if (nLen == 0) return FALSE; AecInterface& intf = m_arHistoryIntfs[nLen - 1]; AcDbObjectId id = intf.idOwner; AcDbEntity* pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite)) { AecDb3dRoad* pDbWpipe = AecDb3dRoad::cast(pEnt); if (pDbWpipe != NULL) { if ( pDbWpipe->GetCurveSegType() != (int)AecEqui::eLine) { pEnt->close(); return FALSE; } AcGePoint3d ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint(); AcGePoint3d ptGe1 = pRec->GetAcquirePoint(); AcGeVector3d vtThis = ptGe1 - ptGe; AcGePoint3d ptGeT; int nPos = 0; AcGeVector3d vt = pDbWpipe->EndPoint() - pDbWpipe->StartPoint(); if (vtThis.isCodirectionalTo(vt)) { ptGeT = pDbWpipe->EndPoint(); pDbWpipe->SetEndPoint(pRec->GetAcquirePoint()); nPos = 1; } else { ptGeT = pDbWpipe->StartPoint(); pDbWpipe->SetStartPoint(pRec->GetAcquirePoint()); } //先关闭 pEnt->close(); //1.可能与其他的管子在中间端合成四通的可能性 MaybeAddCrossConnectToThis(ptGe,ptGe1,id); //2. 可能的与其他管子在末端合成三通,从而结束命令 AcGeVector3d vtDir = ptGe1 - ptGe; if ( MaybeAddTeeConnectToThis(ptGe1,vtDir,id,nPos) ) { //结束命令 m_bStopCommand = TRUE; } intf.ptPos = pRec->GetAcquirePoint(); PushInterface(intf,FALSE); return TRUE; } AecDb3dRoadFitting* pDbFit = AecDb3dRoadFitting::cast(pEnt); if (pDbFit != NULL) //上次是管件,本次创建管子 { AecDbObjXDataMap* pXDataMap = pDbFit->GetSpecialtyData(); int nVal = 0; pXDataMap->GetAt(KEY_RUNTIME,nVal); EFittingType eKind = (EFittingType)nVal; //可能的改上次弯头为三通,当方向不一致 if (nVal == eElbow) { AcGeVector3d vtIntf = intf.vtDir; AcGePoint3d ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint(); AcGePoint3d ptGe1 = pRec->GetAcquirePoint(); AcGeVector3d vtThis = ptGe1 - ptGe; if (vtThis.isParallelTo(vtIntf)) { if (!vtThis.isCodirectionalTo(vtIntf)) // 反向,改弯头为三通 { //判断弯头是否是90度弯头 double dAng = 0.0; pXDataMap->GetAt(PIPE_ELBOWANG,dAng); if ( fabs( dAng - 90.0 ) < 1.e-6) //是90 度 { WPipe::RoadParam data; memset(&data,0,sizeof(WPipe::RoadParam)); pDbFit->GetRoadParam(data); //获取另一方向 double dDn = data.dSize[0]; AcGeVector3d vt1,vt2; pXDataMap->GetAt(KEY_MAJBR,vt1); pXDataMap->GetAt(KEY_MINBR,vt2); AcGeVector3d vtMin; if (vt1.isParallelTo(vtIntf)) // 本位置 { vtMin = vt2; } else { vtMin = vt1; vtMin.negate(); } AcGePoint3d ptGeM; pXDataMap->GetAt(KEY_MID,ptGeM); ChangeElbowToTree(pDbFit,vtThis,ptGeM,vtMin,dDn,pRec); } } } } else if(nVal == eTee) { AcGeVector3d vtIntf = intf.vtDir; AcGePoint3d ptGe = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint(); AcGePoint3d ptGe1 = pRec->GetAcquirePoint(); AcGeVector3d vtThis = ptGe1 - ptGe; AecInterface inf2,inf0; pDbFit->GetInterface(2,inf2); pDbFit->GetInterface(0,inf0); AcGeVector3d vtInf2 = inf2.vtDir; AcGeVector3d vtInf0 = inf0.vtDir; if (vtInf0.isPerpendicularTo(vtInf2)) //正十字三通 { //如果是支管拉,才可能创建四通; if (vtThis.isParallelTo(vtIntf) && vtIntf.isParallelTo(vtInf2) ) { if (!vtThis.isCodirectionalTo(vtIntf)) // 反向,改三通为四通 { //直接改三通为四通 ChangeTeeToCross(pDbFit,vtInf0,vtInf2,pRec); } } } } pEnt->close(); return CreateWPipe(pRec); } pEnt->close(); intf.ptPos = pRec->GetAcquirePoint(); return TRUE; } return FALSE; } BOOL AecDbRoadLine::CreateElbowAndPipe(AECStatusRecord* pRec, const EFittingType &type/* = eElbow*/) { int nLen = m_arHistoryIntfs.GetSize(); if (nLen == 0) return FALSE; AecInterface intf; intf = m_arHistoryIntfs[nLen - 1]; AcDbObjectId id = intf.idOwner; AecDb3dRoadFitting* pFit = new AecDb3dRoadFitting; AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData(); AcGePoint3d ptCur = pRec->GetAcquirePoint(); AcGePoint3d ptGeM = m_pPipeJig->GetTailStatusRec()->GetAcquirePoint(); AcGeVector3d vtMaj,vtMin,vtPipe; vtMaj = intf.vtDir; vtMaj.normalize(); vtMin = ptCur - ptGeM; vtMin.normalize(); AcGeVector3d vtNom = vtMin.crossProduct(vtMaj); double dAngle = vtMin.angleTo(vtMaj,vtNom); //设置图层 AcDbObjectId idLay = KTSetting::InitLayer(LAY_ROAD); int nColor = KTSetting::GetLayerColor(LAY_ROAD); pFit->setLayer(idLay); pFit->SetRoadParam(m_pPipeParam); pFit->GetSpecialtyData()->SetAt(KEY_RUNTIME,(int)eElbow); pFit->GetSpecialtyData()->SetAt(KEY_MAJBR, vtMaj); pFit->GetSpecialtyData()->SetAt(KEY_MINBR, vtMin); pFit->GetSpecialtyData()->SetAt(PIPE_DN, m_pPipeParam->dSize[0]); pFit->GetSpecialtyData()->SetAt(PIPE_RATIO, m_pPipeParam->dRRatio); pFit->GetSpecialtyData()->SetAt(PIPE_ELBOWANG, dAngle); pFit->GetSpecialtyData()->SetAt(PIPE_THICK, m_pPipeParam->dSize[2]); pFit->GetSpecialtyData()->SetAt(KEY_MID, ptGeM); pFit->Create(); //改变上次intf 的末端点 AecInterface intf0,intf1; pFit->GetInterface(0,intf0); pFit->GetInterface(1,intf1); AcGeVector3d vtMove = vtMaj; vtMove.normalize(); AcGePoint3d ptGeT; //判断id 是管件 AcDbEntity* pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead)) { AecDb3dRoadFitting* pFitLast = AecDb3dRoadFitting::cast(pEnt); if (pFitLast != NULL) { double dMove = 0.0; if (intf.vtDir.isParallelTo(intf0.vtDir)) { dMove = intf.ptPos.distanceTo(intf0.ptPos); vtMove = intf.vtDir; vtMove.normalize(); vtMove *= dMove; ptGeM += vtMove; } else { dMove = intf.ptPos.distanceTo(intf1.ptPos); vtMove = intf.vtDir; vtMove.normalize(); vtMove *= dMove; ptGeM += vtMove; } AcGeMatrix3d xformMove; xformMove.setToTranslation(vtMove); pFit->transformBy(xformMove); pFit->GetInterface(0,intf0); pFit->GetInterface(1,intf1); vtMove = vtMaj; vtMove.normalize(); } pEnt->close(); } if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite)) { // 如果上次是管子,则改变上次管子的终点 AecDb3dRoad* pWPipe = AecDb3dRoad::cast(pEnt); if (pWPipe != NULL) { AcGeVector3d vtPipe = pWPipe->EndPoint() - pWPipe->StartPoint(); if (intf0.vtDir.isParallelTo(vtPipe)) { //距离那个点近, 则修改哪个点 double dDis1 = ptGeM.distanceTo(pWPipe->StartPoint()); double dDis2 = ptGeM.distanceTo(pWPipe->EndPoint()); if (dDis1 < dDis2) { ptGeT = pWPipe->StartPoint(); pWPipe->SetStartPoint(intf0.ptPos); } else { ptGeT = pWPipe->EndPoint(); pWPipe->SetEndPoint(intf0.ptPos); } } if (intf1.vtDir.isParallelTo(vtPipe)) { //距离那个点近, 则修改哪个点 double dDis1 = ptGeM.distanceTo(pWPipe->StartPoint()); double dDis2 = ptGeM.distanceTo(pWPipe->EndPoint()); if (dDis1 < dDis2) { ptGeT = pWPipe->StartPoint(); pWPipe->SetStartPoint(intf1.ptPos); } else { ptGeT = pWPipe->EndPoint(); pWPipe->SetEndPoint(intf1.ptPos); } } } AecDb3dRoadFitting* pDbFit = AecDb3dRoadFitting::cast(pEnt); if (pDbFit != NULL ) { AcGeVector3d vtPipe = intf.vtDir; if (intf0.vtDir.isParallelTo(vtPipe)) { vtMove = intf.ptPos - intf0.ptPos; } if (intf1.vtDir.isParallelTo(vtPipe)) { vtMove = intf.ptPos - intf1.ptPos; } ptGeM += vtMove; pXDataMap->SetAt(KEY_MID,ptGeM); pFit->GetInterface(0,intf0); pFit->GetInterface(1,intf1); } pEnt->close(); } //添加本次到数据库 id = CoreTools::AddToModelSpace(pFit); //创建余下的管子 AcGePoint3d ptSta,ptEnd; if (intf0.vtDir.isParallelTo(vtMin)) { ptSta = intf1.ptPos; ptEnd = intf0.ptPos; } if (intf1.vtDir.isParallelTo(vtMin)) { ptSta = intf0.ptPos; ptEnd = intf1.ptPos; } //记录弯头末接口到历史记录 intf.ptPos = ptEnd; intf.vtDir = vtMin; intf.idOwner = id; PushInterface(intf); ptGeT = pRec->GetAcquirePoint(); ptGeT += vtMove; pRec->SetAcquirePoint(ptGeT); //校正 AcGePoint3d ptTemp; AcDbLine ln; ln.setStartPoint(ptEnd); ptTemp = ptEnd + 1000.0 * vtMin; ln.setEndPoint(ptTemp); ln.getClosestPointTo(ptGeT,ptGeT,Adesk::kTrue); pRec->SetAcquirePoint(ptGeT); //创建余下管子,并插入虚拟状态记录 AECStatusRecord* pRecMid = new AECStatusRecord; pRecMid->CopyFrom(pRec); pRecMid->SetAcquirePoint(ptEnd); m_pPipeJig->PushBackStatusRec(pRecMid); CreateWPipe(pRec); return TRUE; } BOOL AecDbRoadLine::MaybeAddTeeConnectToThis(AcGePoint3d& ptGe,AcGeVector3d& vtDir,AcDbObjectId id,int nPos) { AcDbObjectId idLay1,idLay2; AcDbEntity* pEnt1 = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id,AcDb::kForRead)) { idLay1 = pEnt1->layerId(); pEnt1->close(); } else { return FALSE; } //以ptGe的,以管子公称直径为搜索 ads_point pt[5]; vtDir.normalize(); AcGeVector3d vtV = vtDir; vtV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); AcGePoint3d ptGeT = ptGe; ptGeT = ptGe + m_pPipeParam->dSize[0] * 0.5 * vtDir; ptGeT += m_pPipeParam->dSize[0] * 0.5 * vtV; AcGePoint3d ptGeX[5]; ptGeX[0] = ptGeT; ptGeX[1] = ptGeX[0] - m_pPipeParam->dSize[0] * vtDir; ptGeX[2] = ptGeX[1] - m_pPipeParam->dSize[0] * vtV; ptGeX[3] = ptGeX[0] - m_pPipeParam->dSize[0] * vtV; ptGeX[4] = ptGeX[0]; for (int i = 0;i < 5;i++) { acdbWcs2Ucs(asDblArray(ptGeX[i]),pt[i],false); } TCHAR szBuf[64]; memset(szBuf,0,sizeof(szBuf)); _tcscpy(szBuf, _T("AEC_3DROAD")); struct resbuf rb; rb.restype = 0; rb.resval.rstring = szBuf; rb.rbnext = NULL; struct resbuf* pointlist; pointlist = acutBuildList(RTPOINT, pt[0], RTPOINT, pt[1], RTPOINT, pt[2], RTPOINT, pt[3], 0); ads_name ss,ent; acedSSGet(_T("CP"),pointlist,NULL,&rb,ss); acutRelRb(pointlist); Adesk::Int32 lLen = 0; acedSSLength(ss,&lLen); int nType = 0; double dTemp = 0.0; CString sSQL,sTemp; AcDbObjectId idT; AcDbEntity* pEnt = NULL; AcGeVector3d vtPipe; AcGePoint3d ptMid,ptTemp1,ptTemp2; BOOL bModified = FALSE; for (long i = 0;i < lLen;i++) { acedSSName(ss,i,ent); acdbGetObjectId(idT,ent); if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idT,AcDb::kForWrite)) { AecDb3dRoad* pWPipe = AecDb3dRoad::cast(pEnt); if (pWPipe != NULL) { //判断是否同系统 idLay2 = pWPipe->layerId(); if (idLay1 != idLay2) { pEnt->close(); continue; } nType = pWPipe->GetCurveSegType(); if (nType == AecEqui::eArc) { acutPrintf(_T("\n弧形道路暂不支持三通道路!")); pEnt->close(); continue; } vtPipe = pWPipe->EndPoint() - pWPipe->StartPoint(); vtPipe.normalize(); if (!vtPipe.isParallelTo(vtDir)) { //且两管子中心线能相交 AcGeLine3d ln1(pWPipe->EndPoint(),vtPipe); AcGeLine3d ln2(ptGe,vtDir); double dDn = m_pPipeParam->dSize[0]; pWPipe->GetSpecialtyData()->GetAt(KEY_SIZE1,dDn); if (ln1.intersectWith(ln2,ptMid)) { double dL = 1.0 * GetElbowL(m_pPipeParam); double dS = dL; //也可能加弯头,ptMid的两头有一在管子外 ptTemp1 = ptMid + vtPipe * dL; ptTemp2 = ptMid - vtPipe * dL; AcGeLineSeg3d lineGe(pWPipe->StartPoint(),pWPipe->EndPoint()); BOOL bAddTee = TRUE; if ( !lineGe.isOn(ptTemp1) || !lineGe.isOn(ptTemp2) ) { if ( fabs(dDn - m_pPipeParam->dSize[0]) < 1.e-3) //==DN { pEnt->close(); bAddTee = FALSE; if ( AddElbow(idT,ptMid,id)) { bModified = TRUE; } return bModified; } else// 只能加三通 { bAddTee = TRUE; } } if (bAddTee) { //对方断为两个管子 SplitWPipe(ptMid,dL,pWPipe); if (nPos == 1) vtDir.negate(); //改变this管子的位置 ptGe = ptMid + dS * vtDir; ModifyWPipe(ptGe,id,nPos); //添加三通,继承pWPipe属性 AddTee(pWPipe,dL,ptMid,dS,vtDir); } bModified = TRUE; acedSSFree(ss); pEnt->close(); return bModified; } } else //平行,是否可以融合 { //规格相同, 且不是从夹点拖出的命令 if (m_idStartDragFrom != id) { double dDn = 0.0; pWPipe->GetSpecialtyData()->GetAt(KEY_SIZE1,dDn); if (fabs(dDn - m_pPipeParam->dSize[0]) < 1.e-3)//公称相同 { if ( fabs(pWPipe->EndPoint().z - m_pPipeParam->m_dEl) < 1.e-3)//等标高 { AcGePoint3d ptEnd = pWPipe->EndPoint(); AcGePoint3d ptSta = pWPipe->StartPoint(); if (!vtPipe.isCodirectionalTo(vtDir)) { AcGePoint3d ptTemp = ptSta; ptSta = ptEnd; ptEnd = ptTemp; } //删除原来的管子 pEnt->erase(); //改变this管子的位置 ModifyWPipe( nPos == 0 ? ptSta : ptEnd,id,nPos); bModified = TRUE; } } } } } pEnt->close(); } } acedSSFree(ss); return bModified; } typedef struct Point_ID { AcDbObjectId id; AcGePoint3d ptInt; AcDbCurve* pCurve; }POINT_ID; static bool ComparePointID(Point_ID& pt1,Point_ID& pt2) { double dP1 = 0.0,dP2 = 0.0; pt1.pCurve->getParamAtPoint(pt1.ptInt,dP1); pt1.pCurve->getParamAtPoint(pt2.ptInt,dP2); if (dP1 - dP2 < 1.e-6) { return true;//up sort } return false;//down sort } BOOL AecDbRoadLine::MaybeAddCrossConnectToThis(AcGePoint3d ptFr,AcGePoint3d ptTo,AcDbObjectId id) { int nType = 0; AcDbObjectId idLay1,idLay2; AcDbEntity* pEnt1 = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id,AcDb::kForRead)) { idLay1 = pEnt1->layerId(); AecDb3dRoad* pWPipe = AecDb3dRoad::cast(pEnt1); if (pWPipe != NULL) { nType = pWPipe->GetCurveSegType(); if (nType == AecEqui::eArc) { acutPrintf(_T("\n弧形道路暂不支持四通道路!")); pEnt1->close(); return FALSE; } } pEnt1->close(); } else { return FALSE; } //等标高的情况下 if (fabs(ptFr.z - ptTo.z) > 1.0) { return FALSE; } //id 的范围内选择实体,只考虑XY 面,其他三维单加四通 AcGePoint3d ptGe[4]; AcGeVector3d vtDir = ptTo - ptFr; AcGeVector3d vtV = vtDir; vtV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtV.normalize(); vtDir.normalize(); //四通的主支 DN 相同 double dM = 0.0,dB = 0.0; double dL = 1.0 * GetElbowL(m_pPipeParam); dM = dL; dB = dL; //选择范围缩小, 至少长度超过四通的长度 ptFr += m_pPipeParam->dSize[0] * 2.0 * vtDir; ptTo -= m_pPipeParam->dSize[0] * 2.0 * vtDir; ptGe[0] = ptFr; ptGe[0] += vtV * m_pPipeParam->dSize[0] * 0.8; ptGe[1] = ptTo; ptGe[1] += vtV * m_pPipeParam->dSize[0] * 0.8; ptGe[2] = ptGe[1] - vtV * 1.6 * m_pPipeParam->dSize[0]; ptGe[3] = ptGe[0] - vtV * 1.6 * m_pPipeParam->dSize[0]; ads_point pt[4]; for (int i = 0;i < 4;i++) { acdbWcs2Ucs(asDblArray(ptGe[i]),pt[i],false); } TCHAR szBuf[64]; memset(szBuf,0,sizeof(szBuf)); _tcscpy(szBuf, _T("AEC_3DROAD")); struct resbuf rb; rb.restype = 0; rb.resval.rstring = szBuf; rb.rbnext = NULL; struct resbuf* pointlist = NULL; pointlist = acutBuildList(RTPOINT, pt[0], RTPOINT, pt[1], RTPOINT, pt[2], RTPOINT, pt[3], 0); ads_name ss,ent; acedSSGet(_T("CP"),pointlist,NULL,&rb,ss); acutRelRb(pointlist); Adesk::Int32 lLen = 0; acedSSLength(ss,&lLen); AcDbObjectId idT; AcDbEntity* pEnt = NULL; AcGeVector3d vtDir2; AcDbLine line; line.setStartPoint(ptFr); line.setEndPoint(ptTo); AcGeLineSeg3d line1; line1.set(ptFr,ptTo); AcGeLineSeg3d line2; double dDN = 0.0; std::vector vtPtids; for ( i = 0;i < lLen;i++) { acedSSName(ss,i,ent); acdbGetObjectId(idT,ent); if (Acad::eOk == acdbOpenAcDbEntity(pEnt,idT,AcDb::kForRead)) { idLay2 = pEnt->layerId(); if (idLay1 != idLay2) { pEnt->close(); continue; } AecDb3dRoad* pWPipe = AecDb3dRoad::cast(pEnt); if (pWPipe != NULL) { nType = pWPipe->GetCurveSegType(); if (nType == AecEqui::eArc) { acutPrintf(_T("\n弧形道路暂不支持四通道路!")); pEnt->close(); continue; } WPipe::RoadParam data; memset(&data,0,sizeof(WPipe::RoadParam)); pWPipe->GetRoadParam(data); //判断标高是否一致,方向是否垂直,且 公称直径一致?? if ( fabs(pWPipe->EndPoint().z - ptTo.z) < 1.e-6 /*&& fabs(m_pPipeParam->dSize[0] - data.dSize[0]) < 1.e-6*/) { vtDir2 = pWPipe->EndPoint() - pWPipe->StartPoint(); if (vtDir2.isPerpendicularTo(vtDir)) { line2.set(pWPipe->StartPoint(),pWPipe->EndPoint()); Point_ID ptid; ptid.id = idT; ptid.pCurve = &line; if ( line1.intersectWith(line2,ptid.ptInt)) { vtPtids.push_back(ptid); } } } } pEnt->close(); } } //排序 if (!vtPtids.empty()) { std::sort(vtPtids.begin(),vtPtids.end(),ComparePointID); typedef std::vector::iterator PIDIT; for (PIDIT it = vtPtids.begin();it != vtPtids.end();it++) { AddCross( (*it).id,(*it).ptInt,id); } } acedSSFree(ss); return FALSE; return FALSE; } BOOL AecDbRoadLine::SplitWPipe(AcGePoint3d& ptMid,double dL,AecDb3dRoad* pWPipe,BOOL bEraseWhiletooShort/* = TRUE*/) { AcGePoint3d ptSta = pWPipe->StartPoint(); AcGePoint3d ptEnd = pWPipe->EndPoint(); AcGeVector3d vtDir = ptEnd - ptSta; vtDir.normalize(); AecDbObjXDataMap* pXDataMapt = pWPipe->GetSpecialtyData(); AcGePoint3d ptTemp = ptMid - dL * vtDir; AcGeVector3d vtDir1 = ptTemp - ptSta; if (vtDir.isCodirectionalTo(vtDir1)) //同向,说明放得下L的 Tee { //新建管子 //放得下L的 Tee 的情况,新建vtDir 方向的end端 AecDb3dRoad* pWPipe1 = new AecDb3dRoad; AecDbObjXDataMap* pXDataMap = pWPipe1->GetSpecialtyData(); //设置图层 AcDbObjectId idLay = KTSetting::InitLayer(LAY_ROAD); int nColor = KTSetting::GetLayerColor(LAY_ROAD); pWPipe1->setLayer(idLay); WPipe::RoadParam data; pWPipe->GetRoadParam(data); pWPipe1->SetRoadParam(&data); ptTemp = ptMid - dL * vtDir; pWPipe1->SetCurveSeg(ptSta,ptTemp); pWPipe1->setLayer(pWPipe->layerId()); CoreTools::AddToModelSpace(pWPipe1); //改变现有的管子的起点 ptTemp = ptMid + dL * vtDir; pWPipe->SetStartPoint(ptTemp); return TRUE; } else //放不下,直接更改 start 或 end 腾出L位置 { double dDis1 = ptMid.distanceTo(ptSta); double dDis2 = ptMid.distanceTo(ptEnd); if (dDis1 < dDis2 )//靠近sta { ptTemp = ptMid + dL * vtDir; vtDir1 = ptEnd - ptTemp; if (vtDir1.isCodirectionalTo(vtDir)) { pWPipe->SetStartPoint(ptTemp); return TRUE; } } else//靠近 end { ptTemp = ptMid - dL * vtDir; vtDir1 = ptTemp - ptSta; if (vtDir1.isCodirectionalTo(vtDir)) { pWPipe->SetEndPoint(ptTemp); return TRUE; } } } return FALSE; } BOOL AecDbRoadLine::ModifyWPipe(AcGePoint3d& ptGe,AcDbObjectId id,int nPos) { AcDbEntity* pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite)) { AecDb3dRoad* pWPipe = AecDb3dRoad::cast(pEnt); if (pWPipe != NULL) { if (nPos == 0) { pWPipe->SetStartPoint(ptGe); } if (nPos == 1) { pWPipe->SetEndPoint(ptGe); } } pEnt->close(); } return TRUE; } BOOL AecDbRoadLine::AddTee(AecDb3dRoad* pWPipe,double dL,AcGePoint3d ptMid,double dB,AcGeVector3d vtMin) { AecDb3dRoadFitting* pFit = new AecDb3dRoadFitting; AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData(); AcGeVector3d vtMaj = pWPipe->EndPoint() - pWPipe->StartPoint(); vtMaj.normalize(); WPipe::RoadParam rp; memcpy(&rp,m_pPipeParam,sizeof(WPipe::RoadParam)); pWPipe->GetRoadParam(rp); double dRatio = m_pPipeParam->dRRatio; //double dL = 1.0 * GetElbowL(m_pPipeParam); pFit->SetRoadParam(m_pPipeParam); pFit->GetSpecialtyData()->SetAt(KEY_RUNTIME,(int)eTee); pFit->GetSpecialtyData()->SetAt(KEY_MID, ptMid); pFit->GetSpecialtyData()->SetAt(KEY_MAJBR, vtMaj); pFit->GetSpecialtyData()->SetAt(KEY_MINBR, vtMin); pFit->GetSpecialtyData()->SetAt(PIPE_DN, rp.dSize[0]); pFit->GetSpecialtyData()->SetAt(PIPE_TDN, m_pPipeParam->dSize[0]); pFit->GetSpecialtyData()->SetAt(PIPE_THICK, m_pPipeParam->dSize[2]); pFit->GetSpecialtyData()->SetAt(PIPE_RATIO, m_pPipeParam->dRRatio); pFit->GetSpecialtyData()->SetAt(KEY_L, dL); pFit->GetSpecialtyData()->SetAt(KEY_T, dL); pFit->Create(); //设置图层 //设置图层 AcDbObjectId idLay = KTSetting::InitLayer(LAY_ROAD); int nColor = KTSetting::GetLayerColor(LAY_ROAD); pFit->setLayer(idLay); CoreTools::AddToModelSpace(pFit); return TRUE; } BOOL AecDbRoadLine::AddCross(AcDbObjectId id1,AcGePoint3d& ptInt,AcDbObjectId idThis) { AecDb3dRoad* pWPipe = NULL; double dL = 0.0,dB = 0.0; AcGeVector3d vtMaj,vtMin; double dRatio = m_pPipeParam->dRRatio; double dLx = GetElbowLx(m_pPipeParam); dL = 1.0 * GetElbowL(m_pPipeParam); dB = dL; AcDbObjectId idLay; AcGeLine3d ln1; WPipe::RoadParam rp; memcpy(&rp,m_pPipeParam,sizeof(WPipe::RoadParam)); AcDbEntity* pEnt1 = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForRead)) { pWPipe = AecDb3dRoad::cast(pEnt1); if (pWPipe != NULL) { pWPipe->GetRoadParam(rp); ln1.set(pWPipe->StartPoint(),pWPipe->EndPoint()); } pEnt1->close(); } WPipe::RoadParam rpMax; if (rp.dSize[0] > m_pPipeParam->dSize[0]) memcpy(&rpMax,&rp,sizeof(WPipe::RoadParam)); else memcpy(&rpMax,m_pPipeParam,sizeof(WPipe::RoadParam)); dLx = GetElbowLx(&rpMax); dL = 1.0 * GetElbowL(&rpMax); dB = dL; //idThis 管分割为两部分 AcDbEntity* pEnt2 = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt2,idThis,AcDb::kForWrite)) { idLay = pEnt2->layerId(); pWPipe = AecDb3dRoad::cast(pEnt2); if (pWPipe != NULL) { pWPipe->GetRoadParam(rp); vtMin = pWPipe->EndPoint() - pWPipe->StartPoint(); vtMin.normalize(); //矫正 AcGeLineSeg3d ln(pWPipe->StartPoint(),pWPipe->EndPoint()); ln.intersectWith(ln1,ptInt); if (ln.isOn(ptInt)) //落在管子上,两管线相交 { if ( !SplitWPipe(ptInt,dB,pWPipe,FALSE) ) { //太短,放不下四通 pEnt2->close(); return FALSE; } } else //不落在管子上,两管线延长相交, 外部加四通命令调用 { vtMin.normalize(); double dDis1 = ptInt.distanceTo(pWPipe->StartPoint()); double dDis2 = ptInt.distanceTo(pWPipe->EndPoint()); if (dDis1 < dDis2)//距离sta近 { pWPipe->SetStartPoint(ptInt + vtMin * dL); } else { pWPipe->SetEndPoint(ptInt - vtMin * dL); } } } pEnt2->close(); } // id1 管分割为两部分 if ( Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForWrite)) { pWPipe = AecDb3dRoad::cast(pEnt1); if (pWPipe != NULL) { vtMaj = pWPipe->EndPoint() - pWPipe->StartPoint(); vtMaj.normalize(); AcGeLineSeg3d ln(pWPipe->StartPoint(),pWPipe->EndPoint()); if (ln.isOn(ptInt)) //落在管子上,两管线相交 { SplitWPipe(ptInt,dL,pWPipe,TRUE); } else //不落在管子上,两管线延长相交, 外部加四通命令调用 { vtMaj.normalize(); double dDis1 = ptInt.distanceTo(pWPipe->StartPoint()); double dDis2 = ptInt.distanceTo(pWPipe->EndPoint()); if (dDis1 < dDis2)//距离sta近 { pWPipe->SetStartPoint(ptInt + vtMaj * dL); } else { pWPipe->SetEndPoint(ptInt - vtMaj * dL); } } } pEnt1->close(); } //加入四通 AcGeVector3d vtNro = vtMin.crossProduct(vtMaj); AecDb3dRoadFitting* pFit = new AecDb3dRoadFitting; AecDbObjXDataMap* pXDataMap = pFit->GetSpecialtyData(); //设置图层 int nColor = KTSetting::GetLayerColor(LAY_ROAD); pFit->setLayer(idLay); pFit->SetRoadParam(m_pPipeParam); pFit->GetSpecialtyData()->SetAt(KEY_RUNTIME,(int)eCross); pFit->GetSpecialtyData()->SetAt(KEY_MAJBR, vtMaj); pFit->GetSpecialtyData()->SetAt(KEY_MINBR, vtMin); pFit->GetSpecialtyData()->SetAt(KEY_MID, ptInt); pFit->GetSpecialtyData()->SetAt(PIPE_DN, rpMax.dSize[0]); pFit->GetSpecialtyData()->SetAt(PIPE_TDN, m_pPipeParam->dSize[0]); pFit->GetSpecialtyData()->SetAt(PIPE_THICK, m_pPipeParam->dSize[2]); pFit->GetSpecialtyData()->SetAt(KEY_L, dB); pFit->GetSpecialtyData()->SetAt(KEY_T, dL); pFit->GetSpecialtyData()->SetAt(PIPE_RATIO, m_pPipeParam->dRRatio); pFit->Create(); CoreTools::AddToModelSpace(pFit); return TRUE; } BOOL AecDbRoadLine::AddElbow(AcDbObjectId id1,AcGePoint3d& ptGe,AcDbObjectId idThis) { AecDb3dRoad* pWPipe1 = NULL; AecDb3dRoad* pWPipe2 = NULL; AcDbEntity* pEnt1 = NULL; AcDbEntity* pEnt2 = NULL; BOOL bSuccess = FALSE; if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForWrite)) { if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,idThis,AcDb::kForWrite)) { pWPipe1 = AecDb3dRoad::cast(pEnt1); pWPipe2 = AecDb3dRoad::cast(pEnt2); if (pWPipe1 != NULL && pWPipe2 != NULL) { AcGeLine3d ln1(pWPipe1->StartPoint(),pWPipe1->EndPoint()); AcGeLine3d ln2(pWPipe2->StartPoint(),pWPipe2->EndPoint()); AcGePoint3d ptMid = ptGe; ln1.intersectWith(ln2,ptMid); ptGe = ptMid;//?? WPipe::RoadParam param1,param2; pWPipe1->GetRoadParam(param1); pWPipe2->GetRoadParam(param2); int npos1 = 1,npos2 = 1; AcGeVector3d vtMaj,vtMin; double dDis1 = ptMid.distanceTo(pWPipe1->EndPoint()); double dDis2 = ptMid.distanceTo(pWPipe1->StartPoint()); vtMaj = pWPipe1->EndPoint() - pWPipe1->StartPoint();//默认靠近 end if (dDis1 > dDis2) { vtMaj = pWPipe1->StartPoint() - pWPipe1->EndPoint();//靠近 sta npos1 = 0; } vtMaj.normalize(); //vtMaj.negate(); dDis1 = ptMid.distanceTo(pWPipe2->EndPoint()); dDis2 = ptMid.distanceTo(pWPipe2->StartPoint()); vtMin = pWPipe2->EndPoint() - pWPipe2->StartPoint();//默认靠近 end if (dDis1 > dDis2) { vtMin = pWPipe2->StartPoint() - pWPipe2->EndPoint();//靠近 sta npos2 = 0; } vtMin.normalize(); vtMin.negate(); if ( fabs(param1.dSize[0] - param2.dSize[0]) < 1.e-3) { //创建弯头,是插入到当前管子的接口记录的前面 AcDbObjectId id = CreateElbow(vtMaj,ptMid,vtMin,¶m1,TRUE); //获取万头接口,改变边的管子 AcDbEntity* pEnt3 = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt3,id,AcDb::kForRead)) { AecDb3dRoadFitting* pFit = AecDb3dRoadFitting::cast(pEnt3); if (pFit != NULL) { AecInterface inf1,inf2; pFit->GetInterface(0,inf1); pFit->GetInterface(1,inf2); AcGeVector3d vtPipe = pWPipe1->EndPoint() - pWPipe1->StartPoint(); if (vtPipe.isParallelTo(inf1.vtDir)) { if (npos1 == 0)//改sta pWPipe1->SetStartPoint(inf1.ptPos); else pWPipe1->SetEndPoint(inf1.ptPos); if (npos2 == 0) pWPipe2->SetStartPoint(inf2.ptPos); else pWPipe2->SetEndPoint(inf2.ptPos); } else { if (npos1 == 0)//改sta pWPipe1->SetStartPoint(inf2.ptPos); else pWPipe1->SetEndPoint(inf2.ptPos); if (npos2 == 0) pWPipe2->SetStartPoint(inf1.ptPos); else pWPipe2->SetEndPoint(inf1.ptPos); } } pEnt3->close(); } } bSuccess = TRUE; } pEnt2->close(); } pEnt1->close(); } return bSuccess; } BOOL AecDbRoadLine::AddElbowEx(AcDbObjectId id1,AcGePoint3d& ptGe,AcDbObjectId idThis) { AecDb3dRoad* pWPipe1 = NULL; AecDb3dRoad* pWPipe2 = NULL; AcDbEntity* pEnt1 = NULL; AcDbEntity* pEnt2 = NULL; BOOL bSuccess = FALSE; if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForWrite)) { if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,idThis,AcDb::kForWrite)) { pWPipe1 = AecDb3dRoad::cast(pEnt1); pWPipe2 = AecDb3dRoad::cast(pEnt2); if (pWPipe1 != NULL && pWPipe2 != NULL) { AcGeLine3d ln1(pWPipe1->StartPoint(),pWPipe1->EndPoint()); AcGeLine3d ln2(pWPipe2->StartPoint(),pWPipe2->EndPoint()); AcGePoint3d ptMid = ptGe; ln1.intersectWith(ln2,ptMid); ptGe = ptMid;//?? WPipe::RoadParam param1,param2; pWPipe1->GetRoadParam(param1); pWPipe2->GetRoadParam(param2); int npos1 = 1,npos2 = 1; AcGeVector3d vtMaj,vtMin; double dDis1 = ptMid.distanceTo(pWPipe1->EndPoint()); double dDis2 = ptMid.distanceTo(pWPipe1->StartPoint()); vtMaj = pWPipe1->EndPoint() - pWPipe1->StartPoint();//默认靠近 end if (dDis1 > dDis2) { vtMaj = pWPipe1->StartPoint() - pWPipe1->EndPoint();//靠近 sta npos1 = 0; } vtMaj.normalize(); //vtMaj.negate(); dDis1 = ptMid.distanceTo(pWPipe2->EndPoint()); dDis2 = ptMid.distanceTo(pWPipe2->StartPoint()); vtMin = pWPipe2->EndPoint() - pWPipe2->StartPoint();//默认靠近 end if (dDis1 > dDis2) { vtMin = pWPipe2->StartPoint() - pWPipe2->EndPoint();//靠近 sta npos2 = 0; } vtMin.normalize(); vtMin.negate(); //if ( fabs(param1.dSize[0] - param2.dSize[0]) < 1.e-3) { //创建弯头,是插入到当前管子的接口记录的前面 AcDbObjectId id = CreateElbowEx(vtMaj,ptMid,vtMin,¶m1,¶m2,TRUE); //获取万头接口,改变边的管子 AcDbEntity* pEnt3 = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt3,id,AcDb::kForRead)) { AecDb3dRoadFitting* pFit = AecDb3dRoadFitting::cast(pEnt3); if (pFit != NULL) { AecInterface inf1,inf2; pFit->GetInterface(0,inf1); pFit->GetInterface(1,inf2); AcGeVector3d vtPipe = pWPipe1->EndPoint() - pWPipe1->StartPoint(); if (vtPipe.isParallelTo(inf1.vtDir)) { if (npos1 == 0)//改sta pWPipe1->SetStartPoint(inf1.ptPos); else pWPipe1->SetEndPoint(inf1.ptPos); if (npos2 == 0) pWPipe2->SetStartPoint(inf2.ptPos); else pWPipe2->SetEndPoint(inf2.ptPos); } else { if (npos1 == 0)//改sta pWPipe1->SetStartPoint(inf2.ptPos); else pWPipe1->SetEndPoint(inf2.ptPos); if (npos2 == 0) pWPipe2->SetStartPoint(inf1.ptPos); else pWPipe2->SetEndPoint(inf1.ptPos); } } pEnt3->close(); } } bSuccess = TRUE; } pEnt2->close(); } pEnt1->close(); } return bSuccess; } BOOL AecDbRoadLine::ChangeElbowToTree(AecDb3dRoadFitting* pDbFit,AcGeVector3d vtMaj,AcGePoint3d ptGeM,AcGeVector3d vtMin,double dDn,AECStatusRecord* pCurRec) { //查询 Tee 数据 WPipe::RoadParam param; memset(¶m,0,sizeof(WPipe::RoadParam)); pDbFit->GetRoadParam(param); double dL = 0.0,dS = 0.0; dL = 1.0 * GetElbowL(¶m); dS = dL; double dLx = GetElbowLx(¶m); AecInterface intf1,intf2; pDbFit->GetInterface(0,intf1); pDbFit->GetInterface(1,intf2); vtMaj.normalize(); vtMin.normalize(); //创建三通 AecDb3dRoadFitting* pFitting = new AecDb3dRoadFitting; AecDbObjXDataMap* pXDataMap = pFitting->GetSpecialtyData(); pFitting->SetRoadParam(¶m); pFitting->GetSpecialtyData()->SetAt(KEY_RUNTIME,(int)eTee); pFitting->GetSpecialtyData()->SetAt(KEY_MAJBR, vtMaj); pFitting->GetSpecialtyData()->SetAt(KEY_MINBR, vtMin); pFitting->GetSpecialtyData()->SetAt(KEY_MID, ptGeM); pFitting->GetSpecialtyData()->SetAt(PIPE_DN, m_pPipeParam->dSize[0]); pFitting->GetSpecialtyData()->SetAt(PIPE_TDN, m_pPipeParam->dSize[0]); pFitting->GetSpecialtyData()->SetAt(PIPE_THICK, m_pPipeParam->dSize[2]); pFitting->GetSpecialtyData()->SetAt(PIPE_RATIO, m_pPipeParam->dRRatio); pFitting->GetSpecialtyData()->SetAt(KEY_L, dL); pFitting->GetSpecialtyData()->SetAt(KEY_T, dL); pFitting->Create(); AcGeVector3d vtNro = vtMin.crossProduct(vtMaj); pXDataMap->SetAt(KEY_NORMAL,vtNro); //设置图层 AcDbObjectId idLay = KTSetting::InitLayer(LAY_ROAD); pFitting->setLayer(idLay); //可能的几种修改,更改弯头两头的管子的位置 AcGePoint3d ptGe; if (intf1.vtDir.isParallelTo(vtMin)) { ptGe = ptGeM + dS * vtMin; ModifyPipeOfElbow(GetConnectObject(intf1, m_arHistoryIntfs),intf1.ptPos,ptGe); } if (intf2.vtDir.isParallelTo(vtMin)) { ptGe = ptGeM + dS * vtMin; ModifyPipeOfElbow(GetConnectObject(intf2, m_arHistoryIntfs),intf2.ptPos,ptGe); } if (intf1.vtDir.isParallelTo(vtMaj)) { ptGe = ptGeM - dL * vtMaj; ModifyPipeOfElbow(GetConnectObject(intf1, m_arHistoryIntfs),intf1.ptPos,ptGe); } if (intf2.vtDir.isParallelTo(vtMaj)) { ptGe = ptGeM - dL * vtMaj;//反向 ModifyPipeOfElbow(GetConnectObject(intf2, m_arHistoryIntfs),intf2.ptPos,ptGe); } //替换pdbfit pDbFit->erase(); CoreTools::AddToModelSpace(pFitting); AECStatusRecord* pRecMid = new AECStatusRecord; pRecMid->CopyFrom(pCurRec); ptGe = ptGeM + vtMaj * dL; pRecMid->SetAcquirePoint(ptGe); m_pPipeJig->PushBackStatusRec(pRecMid); return TRUE; } BOOL AecDbRoadLine::ChangeTeeToCross(AecDb3dRoadFitting* pDbFit,AcGeVector3d& vtMaj,AcGeVector3d& vtMin,AECStatusRecord* pCurRec) { WPipe::RoadParam param; memset(¶m,0,sizeof(WPipe::RoadParam)); pDbFit->GetRoadParam(param); double dL = 0.0,dB = 0.0; dL = 1.0 * GetElbowL(¶m); dB = dL; double dLx = GetElbowLx(¶m); AecDbObjXDataMap* pXDataMap = pDbFit->GetSpecialtyData(); pXDataMap->SetAt(KEY_RUNTIME, eCross); pXDataMap->SetAt(KEY_MAJBR,vtMaj); pXDataMap->SetAt(KEY_MINBR,vtMin);// AcGeVector3d vtNro = vtMaj.crossProduct(vtMin);// pXDataMap->SetAt(KEY_NORMAL,vtNro); pXDataMap->SetAt(KEY_L,dL); pXDataMap->SetAt(KEY_T,dB); AcGePoint3d ptMid; pXDataMap->GetAt(KEY_MID,ptMid); pDbFit->GetSpecialtyData()->SetAt(KEY_RUNTIME,(int)eCross); pDbFit->GetSpecialtyData()->SetAt(KEY_MAJBR, vtMaj); pDbFit->GetSpecialtyData()->SetAt(KEY_MINBR, vtMin); pDbFit->GetSpecialtyData()->SetAt(KEY_MID, ptMid); pDbFit->GetSpecialtyData()->SetAt(PIPE_DN, m_pPipeParam->dSize[0]); pDbFit->GetSpecialtyData()->SetAt(PIPE_TDN, m_pPipeParam->dSize[0]); pDbFit->GetSpecialtyData()->SetAt(PIPE_THICK, m_pPipeParam->dSize[2]); pDbFit->GetSpecialtyData()->SetAt(PIPE_RATIO, m_pPipeParam->dRRatio); pDbFit->GetSpecialtyData()->SetAt(KEY_L, dL); pDbFit->GetSpecialtyData()->SetAt(KEY_T, dL); vtMin.normalize(); AcGePoint3d ptGe = ptMid - vtMin * dB; AECStatusRecord* pRecMid = new AECStatusRecord; pRecMid->CopyFrom(pCurRec); pRecMid->SetAcquirePoint(ptGe); m_pPipeJig->PushBackStatusRec(pRecMid); return TRUE; } void AecDbRoadLine::ModifyPipeOfElbow(AcDbObjectId id,AcGePoint3d ptOld,AcGePoint3d ptNew) { AcDbEntity* pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite)) { AecDb3dRoad* pPipe = AecDb3dRoad::cast(pEnt); if (pPipe != NULL) { AcGePoint3d ptGeT; AcGeVector3d vtPipe = pPipe->EndPoint() - pPipe->StartPoint(); if ( pPipe->EndPoint().distanceTo(ptOld) < 1.e-3) { ptGeT = pPipe->EndPoint(); pPipe->SetEndPoint(ptNew); } if (pPipe->StartPoint().distanceTo(ptOld) < 1.e-3) { ptGeT = pPipe->StartPoint(); pPipe->SetStartPoint(ptNew); } } pEnt->close(); } } double AecDbRoadLine::PixelToWcs(int nPixel) { ads_point ptScreenSize; double nViewSize; struct resbuf rb1,rb2; acedGetVar(_T("ScreenSize"), &rb1); acedGetVar(_T("ViewSize"), &rb2); nViewSize = rb2.resval.rreal; ads_point_set(rb1.resval.rpoint,ptScreenSize); if (ptScreenSize[1] < 1.0E-6 || nViewSize < 1.0E-6) return 0.0; double hight = (nViewSize / ptScreenSize[Y]) * nPixel; return hight; }