#include "stdafx.h" #include "AECStatusRecord.h" #include "AecDbRoadJig.h" #include "HZDLDlg.h" #include "AecDbRoadLine.h" #include "CoreTools.h" #include "AecDb3dRoad.h" #include "ReducerDlg.h" static double FormatZero(double dVal) { if ( fabs(dVal) < 1.e-6 ) return 0.0; int nVal = (int)(dVal * 1000.0); return nVal / 1000.0; } AcGePoint3d MidPoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2) { return AcGePoint3d((pt1.x + pt2.x) / 2.0, (pt1.y + pt2.y) / 2.0, (pt1.z + pt2.z) / 2.0); } extern DLLIMPEXP AcDbArc* FormatArc(const AcGePoint3d& ptGe1,const AcGePoint3d& ptGe2,const AcGePoint3d& ptGe3); AecDbRoadJig::AecDbRoadJig(void) { m_pPipeLine = new AecDbRoadLine(this); m_tStartIntf.vtDir = AcGeVector3d::kIdentity; m_tStartIntf.ptPos = AcGePoint3d::kOrigin; m_vtStaDir.set(0.0,0.0,0.0); m_nUndoGoupid = 0; InitStatusRecs(); } AecDbRoadJig::AecDbRoadJig(WPipe::RoadParam* pParam) { m_pPipeLine = new AecDbRoadLine(this); m_pPipeLine->SetPipeParam(pParam); m_tStartIntf.vtDir = AcGeVector3d::kIdentity; m_tStartIntf.ptPos = AcGePoint3d::kOrigin; m_vtStaDir.set(0.0,0.0,0.0); m_nUndoGoupid = 0; } AecDbRoadJig::~AecDbRoadJig(void) { if (m_pPipeLine != NULL) delete m_pPipeLine; } void AecDbRoadJig::InitStatusRecs() { FreeStatusRecs(); //1.起端为管子的状态 AECStatusRecord* pRec1 = NULL; pRec1 = new AECStatusRecord; m_arStaPtrs.Add(pRec1); pRec1->SetPrompt(_T("\n指定起点<退出>:")); pRec1->SetStatusType(AECStatusRecord::kPoint); pRec1->SetPlanPosition(0); AECStatusRecord* pRec2 = NULL; pRec2 = new AECStatusRecord; m_arStaPtrs.Add(pRec2); pRec2->SetPrompt(_T("\n指定下一点或 [变窄(R)/圆弧(A)/回退(U)<退出>:")); pRec2->SetStatusType(AECStatusRecord::kPoint); pRec2->SetKeywordList(_T("R A X U")); pRec1->SetNextStatus(pRec2); pRec2->SetPlanPosition(1); pRec2->SetNextStatus(pRec2,1); m_pCurStaRec = pRec1; //分支状态 AECStatusRecord* pRec3 = NULL; pRec3 = new AECStatusRecord; pRec3->SetPrompt(_T("\n指定下一个点或 [圆弧设置(A)]:")); pRec3->SetStatusType(AECStatusRecord::kPoint); pRec3->SetKeywordList(_T("A")); pRec2->SetKeyStatus(_T("A"),pRec3); pRec3->SetPlanPosition(2); pRec3->SetNextStatus(pRec2); m_arStaPtrs.Add(pRec3); } void AecDbRoadJig::SetAngleWath(AcGePoint3d& ptCen,const AcGePoint3d& ptGeTo,const AcGeVector3d& vtDir) { ((AecDbRoadLine *)m_pPipeLine)->SetAngleWath(ptCen,ptGeTo,vtDir); } void AecDbRoadJig::CalReferencePoint() { AcGePoint3d ptWcs; ads_point ptBase,pt22,pt33; acedInitGet(RSG_NONULL,_T("R")); int nRes = acedGetPoint(NULL,_T("\n指定起点或[参考点(R)]<退出>:"),ptBase); switch(nRes) { case RTNORM: { acdbUcs2Wcs(ptBase,pt22,false); ptWcs = asPnt3d(pt22); ptWcs.z = ((AecDbRoadLine*)m_pPipeLine)->GetEndElevation(); m_pCurStaRec->SetAcquirePoint(ptWcs); //压入本次状态,起点 m_pCurStaRec->SetAcquirePoint(ptWcs); AECStatusRecord * pRec = new AECStatusRecord; pRec->CopyFrom(m_pCurStaRec); pRec->SetUndoGroupId(0); PushBackStatusRec(pRec); ((AecDbRoadLine *)m_pPipeLine)->MoveAngWatchPosition(); m_pCurStaRec = m_pCurStaRec->GetNextStatus(m_pCurStaRec->GetPos()); m_pCurStaRec->SetAcquirePoint(ptWcs); break; } case RTKWORD: { TCHAR szKey[2]; szKey[0] = '0'; acedGetInput(szKey); switch(szKey[0]) { case _T('R'): case _T('r'): { //参考点<退出>: nRes = acedGetPoint(NULL,_T("\n参考点<退出>:"),ptBase); if (nRes == RTNORM) { //起点<退出>: nRes = acedGetPoint(ptBase,_T("\n指定起点<退出>:"),pt22); if (nRes == RTNORM) { acdbUcs2Wcs(pt22,pt33,false); ptWcs = asPnt3d(pt33); ptWcs.z = ((AecDbRoadLine*)m_pPipeLine)->GetEndElevation(); m_pCurStaRec->SetAcquirePoint(ptWcs); //压入本次状态,起点 m_pCurStaRec->SetAcquirePoint(ptWcs); AECStatusRecord * pRec = new AECStatusRecord; pRec->CopyFrom(m_pCurStaRec); pRec->SetUndoGroupId(0); PushBackStatusRec(pRec); ((AecDbRoadLine *)m_pPipeLine)->MoveAngWatchPosition(); m_pCurStaRec = m_pCurStaRec->GetNextStatus(m_pCurStaRec->GetPos()); m_pCurStaRec->SetAcquirePoint(ptWcs); } } break; } default: break; } } default: { break; } } } BOOL AecDbRoadJig::DoIt(WPipe::EApp app, BOOL bParamDlg/* = TRUE*/,BOOL bCalRefPoint/* = TRUE*/) { CAcModuleResourceOverride myResources; if (bParamDlg) { CHZDLDlg drawCnfgDLg; drawCnfgDLg.EnableLoadLast(TRUE); int nRes = drawCnfgDLg.DoModal(); if (nRes != IDOK) { return FALSE; } WPipe::RoadParam param; memset(¶m,0,sizeof(WPipe::RoadParam)); drawCnfgDLg.GetPipeParam(param); ((AecDbRoadLine*)m_pPipeLine)->SetPipeParam(¶m); } //参考 if (bCalRefPoint) { CalReferencePoint(); } AcEdJig::DragStatus eStat; int nPlanPos = 0,nRes = 0; while(TRUE) { CString sPrompt = m_pCurStaRec->Prompt(); SetDispPromptWithEleTip(sPrompt); setDispPrompt(sPrompt); if (((AecDbRoadLine*)m_pPipeLine)->PipeFinished()) { break; } eStat = drag(); nPlanPos = m_pCurStaRec->GetPlanPosition(); switch(eStat) { case AcEdJig::kNormal: { if (nPlanPos == 1 || nPlanPos == 2) //Create Pipe { if ( -1 != (nRes = AfterDrag())) { return nRes; } } break; } case AcEdJig::kCancel: case AcEdJig::kNull:// 退出 { acutPrintf(_T("\n")); return FALSE; } case AcEdJig::kKW1://R 变径 { //至少创建了一个管段 if (((AecDbRoadLine*)m_pPipeLine)->GetLastInterface() == NULL) { acutPrintf(_T("\n之前没有创建管段,无法变径!")); continue; } AcGeVector3d vtDir; AecInterface* pIntf = ((AecDbRoadLine*)m_pPipeLine)->GetLastInterface(); if (pIntf == NULL) vtDir = AcGeVector3d::kXAxis; else vtDir = pIntf->vtDir; CReducerDlg redDLg; WPipe::RoadParam param; memset(¶m,0,sizeof(WPipe::RoadParam)); memcpy(¶m,((AecDbRoadLine*)m_pPipeLine)->GetPipeParam(),sizeof(WPipe::RoadParam)); param.dSize[3] = param.dSize[0]; redDLg.SetCurWidth(param.dSize[0],param.dRRatio * param.dSize[0]); int nRes = redDLg.DoModal(); if (nRes == IDOK) { AcGePoint3d ptSize; int nEcCen = redDLg.GetReducer(ptSize); param.dSize[1] = ptSize.y; param.m_dL = ptSize.z; //param.m_nEcCen = 0; //设置回退记录 SHacedCommand(RTSTR,_T("_undo"),RTSTR,_T("BE"),RTNONE); SetUndoGroupBegin(); if ( ( (AecDbRoadLine *)m_pPipeLine)->AddReducer(m_pCurStaRec,¶m) ) { AECStatusRecord* pRec = new AECStatusRecord; pRec->CopyFrom(m_pCurStaRec); PushBackStatusRec(pRec); ((AecDbRoadLine*)m_pPipeLine)->GetPipeParam()->dSize[0] = ptSize.y; ((AecDbRoadLine *)m_pPipeLine)->MoveAngWatchPosition(); } SHacedCommand(RTSTR,_T("_undo"),RTSTR,_T("E"),RTNONE); SetUndoGroupEnd(); } break; } case AcEdJig::kKW2://A 圆弧设置 { //指定下一个点或 [圆弧设置(S)] if (m_pCurStaRec->GetPlanPosition() == 1)//A { if (m_lstStaPtrsBack.GetCount() == 1)//第一个点历史记录,开始绘制圆弧 { AECStatusRecord* pLast = (AECStatusRecord*)m_lstStaPtrsBack.GetTail(); ads_point ptLast; acdbWcs2Ucs(asDblArray(pLast->GetAcquirePoint()),ptLast,false); ads_point pt2,pt22; int nRes = acedGetPoint(ptLast,_T("\n定圆弧上的第中间一点:"),pt2); if (nRes == RTNORM) { ads_point pt3,pt33; nRes = acedGetPoint(pt2,_T("\n指定圆弧的端点:"),pt3); if (nRes == RTNORM) { AcGePoint3d ptMid; acdbUcs2Wcs(pt2,pt22,false); ptMid = asPnt3d(pt22); acdbUcs2Wcs(pt3,pt33,false); AcDbArc* pArc = FormatArc(pLast->GetAcquirePoint(),ptMid,asPnt3d(pt33)); if (pArc != NULL) { m_pPipeLine->CreatePipe(pArc,asPnt3d(pt33)); delete pArc; } m_pCurStaRec->SetAcquirePoint(asPnt3d(pt33)); AECStatusRecord* pRec = new AECStatusRecord; pRec->CopyFrom(m_pCurStaRec); pRec->SetAcquirePoint(asPnt3d(pt33)); PushBackStatusRec(pRec); ((AecDbRoadLine *)m_pPipeLine)->MoveAngWatchPosition(); } } } else { AECStatusRecord* pRec = m_pCurStaRec->GetKeyStatus(_T("A")); m_pCurStaRec = pRec; } continue; } else { double dAngle(.0), dR(.0); //圆弧设置 R,ANGLE if (acedGetReal(_T("\n请输入圆心角(负值时顺时针绘制):"), &dAngle) == RTNORM) { if (acedGetReal(_T("\n请输入半径:"), &dR) == RTNORM) { AcGePoint3d ptSta, ptEnd; if (AddRoadNode(dAngle * PI / 180.0, dR,ptSta,ptEnd)) { //设置回退记录 SHacedCommand(RTSTR, _T("_undo"), RTSTR, _T("BE"), RTNONE); SetUndoGroupBegin(); AECStatusRecord* pRec = new AECStatusRecord; pRec->CopyFrom(m_pCurStaRec); if (!m_lstStaPtrsBack.IsEmpty()) { //根据R,Angle 转为 模拟去点动作保存缓存 AECStatusRecord* pLast = (AECStatusRecord*)m_lstStaPtrsBack.GetTail(); if (ptSta.distanceTo(pLast->GetAcquirePoint()) < 1.e-3) pRec->SetAcquirePoint(ptEnd); if (ptEnd.distanceTo(pLast->GetAcquirePoint()) < 1.e-3) pRec->SetAcquirePoint(ptSta); } PushBackStatusRec(pRec); SHacedCommand(RTSTR, _T("_undo"), RTSTR, _T("E"), RTNONE); SetUndoGroupEnd(); } } } } break; } case AcEdJig::kKW3://U 回退 X 斜管 { break; } case AcEdJig::kKW4://U 回退 { if (m_lstStaPtrsBack.GetCount() > 1) { SHacedCommand(RTSTR,_T("u"),RTNONE); PopUpStatusRec(); } else { continue; } break; } default: break; } EndDragRecord(); } acutPrintf(_T("\n")); return TRUE; } BOOL AecDbRoadJig::AddRoadNode(double dAngle,double dR,AcGePoint3d& ptS,AcGePoint3d& ptE) { if (m_pPipeLine->GetLastInfCount() < 2) return FALSE; BOOL bSuccess = FALSE; if (m_lstStaPtrsBack.GetCount() > 1) { AECStatusRecord* pRecLast = (AECStatusRecord* )m_lstStaPtrsBack.GetTail(); AcGePoint3d ptLast = pRecLast->GetAcquirePoint(); AecInterface* pInfLast = m_pPipeLine->GetLastInterface(); AecInterface* pInfLastLast = m_pPipeLine->GetLastLastInterface(); if (pInfLast != NULL && pInfLastLast != NULL) { double dB = 0.5 * dAngle; AcGePoint3d ptSta,ptEnd; ptSta = pInfLastLast->ptPos; ptEnd = pInfLast->ptPos; AcGePoint3d ptMid = MidPoint(ptSta,ptEnd); AcGeVector3d vtLast = ptLast - ptMid; AcGeVector3d vtLast2 = pInfLast->vtDir; if (vtLast2.dotProduct(vtLast) < 1.e-10)//反向 vtLast.negate(); AcGeVector3d vtThis = vtLast; vtThis.rotateBy(dB,AcGeVector3d::kZAxis); vtThis.normalize(); double dL = 2 * dR * fabs(sin(dB)); AcGePoint3d ptThis = ptLast + vtThis * dL; if (dB < 1.e-10) {vtThis.rotateBy(-PI / 2.0 - dB,AcGeVector3d::kZAxis);} else {vtThis.rotateBy(PI / 2.0 - dB,AcGeVector3d::kZAxis);} AcGePoint3d ptCen = ptLast + vtThis * dR; ptMid = MidPoint(ptLast,ptThis); AcGeVector3d vtMid = ptMid - ptCen; vtMid.normalize(); ptMid = ptCen + vtMid * dR; AcDbArc* pArc = FormatArc(ptLast,ptMid,ptThis); if (pArc != NULL) { m_pPipeLine->CreatePipe(pArc,ptThis); delete pArc; bSuccess = TRUE; ptS = ptLast; ptE = ptThis; } } } return bSuccess; } int AecDbRoadJig::AfterDrag() { int nPlanPos = m_pCurStaRec->GetPlanPosition(); if (nPlanPos < 1) return -1; //设置回退记录 SHacedCommand(RTSTR,_T("_undo"),RTSTR,_T("BE"),RTNONE); SetUndoGroupBegin(); if ( ((AecDbRoadLine *)m_pPipeLine)->AddPipeNode(m_pCurStaRec,WPipe::eToCreate) ) { AECStatusRecord* pRec = new AECStatusRecord; pRec->CopyFrom(m_pCurStaRec); PushBackStatusRec(pRec); ((AecDbRoadLine *)m_pPipeLine)->MoveAngWatchPosition(); if (m_pCurStaRec->IsCommand2Stop()) { return TRUE; } } else { ((AecDbRoadLine *)m_pPipeLine)->PipeFinished(); return FALSE; } m_vtStaDir.set(0,0,0);//reset SHacedCommand(RTSTR,_T("_undo"),RTSTR,_T("E"),RTNONE); SetUndoGroupEnd(); return -1; } void AecDbRoadJig::EndDragRecord() { //获取下个状态,plane判断是? if (m_pCurStaRec->GetPlanPosition() == 0 || m_pCurStaRec->GetPlanPosition() == 2 ) { AECStatusRecord * pRec = new AECStatusRecord; pRec->CopyFrom(m_pCurStaRec); pRec->SetUndoGroupId(0); PushBackStatusRec(pRec); ((AecDbRoadLine *)m_pPipeLine)->MoveAngWatchPosition(); m_pCurStaRec = m_pCurStaRec->GetNextStatus(m_pCurStaRec->GetPos()); } } BOOL AecDbRoadJig::DoIt(AecInterface* pIntf,WPipe::RoadParam* pParam) { if (pIntf == NULL) return FALSE; if (pParam == NULL) //用户确定壁厚和外径 etc. { CAcModuleResourceOverride myResources; CHZDLDlg drawCnfgDLg; double dSize(pIntf->dSize1),dSize1(pIntf->dSize2); drawCnfgDLg.SetEleReadOnly(TRUE,FormatZero(pIntf->ptPos.z));//圆整 int nRes = drawCnfgDLg.DoModal(); if (nRes == IDOK) { WPipe::RoadParam param; memset(¶m,0,sizeof(WPipe::RoadParam)); drawCnfgDLg.GetPipeParam(param); param.m_dEl = pIntf->ptPos.z;//标高确定不变 ((AecDbRoadLine*)m_pPipeLine)->SetPipeParam(¶m); } else { return FALSE; } } else { // ((AecDbRoadLine*)m_pPipeLine)->SetPipeParam(pParam); } //压入本次接口 if ( /*pParam != NULL &&*/ pIntf->idOwner.isValid()) { ((AecDbRoadLine*)m_pPipeLine)->PushInterface(*pIntf,TRUE); } //压入本次状态,起点 m_pCurStaRec->SetAcquirePoint(pIntf->ptPos); AECStatusRecord * pRec = new AECStatusRecord; pRec->CopyFrom(m_pCurStaRec); pRec->SetUndoGroupId(0); PushBackStatusRec(pRec); ((AecDbRoadLine *)m_pPipeLine)->SetAngleWath(pIntf->ptPos,pRec->GetAcquirePoint(),pIntf->vtDir); m_pCurStaRec = m_pCurStaRec->GetNextStatus(m_pCurStaRec->GetPos()); return DoIt(WPipe::eBridge, FALSE,FALSE); } AcEdJig::DragStatus AecDbRoadJig::sampler() { setUserInputControls( ( UserInputControls) ( AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted ) ); CString sKeywordsList; sKeywordsList = m_pCurStaRec->KeywordList(); if (!sKeywordsList.IsEmpty()) { setKeywordList(sKeywordsList); } AcEdJig::DragStatus eStat; AcGePoint3d ptGe,ptGeBase,ptGe2; ptGeBase = AcGePoint3d::kOrigin; AECStatusRecord::EAcquire eAcquire = m_pCurStaRec->GetStatusType(); switch(eAcquire) { case AECStatusRecord::kPoint: { //开始状态 int nPos = m_pCurStaRec->GetPlanPosition(); if (nPos == 0) { eStat = acquirePoint(ptGe); //动态获取的点的标高始终和上次一致 ptGe.z = ((AecDbRoadLine*)m_pPipeLine)->GetEndElevation(); } else { //管线的末端点 GetLastStatusAquire(ptGeBase); eStat = acquirePoint(ptGe,ptGeBase); ptGe.z = ((AecDbRoadLine*)m_pPipeLine)->GetEndElevation(); double dDist = ptGeBase.distanceTo(ptGe); if (!m_vtStaDir.isZeroLength()) { m_vtStaDir.normalize(); ptGe = ptGeBase + dDist * m_vtStaDir; } } if (eStat == AcEdJig::kNormal) { if (m_pCurStaRec->IsValSeted()) { ptGe2 = m_pCurStaRec->GetAcquirePoint(); double dDis = ptGe2.distanceTo(ptGe); if (dDis < 1.e-6) { //鼠标原地不动 return AcEdJig::kNoChange; } } return SetPickPoint(ptGe); } break; } default: break; } return eStat; } AcEdJig::DragStatus AecDbRoadJig::SetPickPoint(const AcGePoint3d& ptGe) { //上次点 AcGePoint3d ptGe2 = m_pCurStaRec->GetAcquirePoint(); //本次点 m_pCurStaRec->SetAcquirePoint(ptGe); if (m_pCurStaRec->GetPlanPosition() > 0 && m_lstStaPtrsBack.GetCount() > 0) { ((AecDbRoadLine *)m_pPipeLine)->AddPipeNode(m_pCurStaRec,WPipe::eToPreView); //if (AecAngleWatch::m_bFallInSnap ) //{ //ptGe = m_pCurStaRec->GetAcquirePoint(); if (ptGe.distanceTo(ptGe2) < 1.e-6) { return AcEdJig::kNoChange; } //} return AcEdJig::kNormal; } return AcEdJig::kNormal; } AcDbEntity* AecDbRoadJig::entity() const { return m_pPipeLine; } Adesk::Boolean AecDbRoadJig::update() { return Adesk::kTrue; } void AecDbRoadJig::FreeStatusRecs() { AECStatusRecord* pRecord = NULL; int nSize = m_arStaPtrs.GetSize(); for(int i = 0;i < nSize;i++) { pRecord = (AECStatusRecord*)m_arStaPtrs.GetAt(i); if (pRecord != NULL) DELETE_PTR(pRecord); } m_arStaPtrs.RemoveAll(); for(POSITION ps = m_lstStaPtrsBack.GetHeadPosition();ps != NULL;) { pRecord = (AECStatusRecord*)m_lstStaPtrsBack.GetNext(ps); if (pRecord != NULL) DELETE_PTR(pRecord); } m_lstStaPtrsBack.RemoveAll(); } BOOL AecDbRoadJig::GetLastStatusAquire(AcGePoint3d& ptGe) { int nSize = m_lstStaPtrsBack.GetCount(); if (nSize > 0) { AECStatusRecord* pRec = (AECStatusRecord*)m_lstStaPtrsBack.GetTail(); if (pRec != NULL) ptGe = pRec->GetAcquirePoint(); return TRUE; } return FALSE; } AECStatusRecord* AecDbRoadJig::GetTailStatusRec() const { int nSize = m_lstStaPtrsBack.GetCount(); if (nSize > 0) { return (AECStatusRecord*)m_lstStaPtrsBack.GetTail(); } return NULL; } AECStatusRecord* AecDbRoadJig::GetCurStatusRec() const { return m_pCurStaRec; } void AecDbRoadJig::PushBackStatusRec(AECStatusRecord* pRec) { pRec->SetUndoGroupId(m_nUndoGoupid); m_lstStaPtrsBack.AddTail(pRec); } void AecDbRoadJig::SetUndoGroupBegin() { m_nUndoGoupid += 1; } void AecDbRoadJig::SetUndoGroupEnd() { ((AecDbRoadLine *)m_pPipeLine)->PushPipeParam(); } int AecDbRoadJig::GetUndoGroupID() { return m_nUndoGoupid; } void AecDbRoadJig::PopUpStatusRec() { //按 id 回退一次,调整当前状态 if (m_lstStaPtrsBack.GetCount() > 0) { AECStatusRecord* pLast = (AECStatusRecord*)m_lstStaPtrsBack.GetTail(); int nID = pLast->GetUndoGroupId(); while(m_lstStaPtrsBack.GetCount() > 0) { m_lstStaPtrsBack.RemoveTail(); DELETE_PTR(pLast); pLast = NULL; if (m_lstStaPtrsBack.GetCount() == 0) { break; } pLast = (AECStatusRecord*)m_lstStaPtrsBack.GetTail(); if (nID != pLast->GetUndoGroupId()) { break; } } //pipeline 回退一次,调整接口记录 ((AecDbRoadLine *)m_pPipeLine)->PopUpInterface(nID); ((AecDbRoadLine *)m_pPipeLine)->MoveAngWatchPosition(); } } void AecDbRoadJig::SetDispPromptWithEleTip(CString& sPrompt) { CString sEl; if (m_pCurStaRec != NULL) { sEl.Format(_T("(当前标高:%g)"),m_pCurStaRec->GetAcquirePoint().z); int nIndex = sPrompt.ReverseFind(_T(':')); if (nIndex != -1) { sPrompt.Insert(nIndex,sEl); } } } double AecDbRoadJig::PickWPipehereEl(AcGePoint3d& ptGe) { double dEl = ptGe.z; ads_point pt[5]; double dSize = CoreTools::PixelToWcs(5);//5 AcGePoint3d ptGeX[5]; ptGeX[0] = ptGe; ptGeX[0] -= dSize * AcGeVector3d::kYAxis; ptGeX[0] -= dSize * AcGeVector3d::kXAxis; ptGeX[1] = ptGeX[0] + 2 * dSize * AcGeVector3d::kYAxis; ptGeX[2] = ptGeX[1] + 2 * dSize * AcGeVector3d::kXAxis; ptGeX[3] = ptGeX[0] + 2 * dSize * AcGeVector3d::kXAxis; 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); AcDbObjectId id; AcGePoint3d ptOn; if (lLen > 0) { acedSSName(ss,0,ent); acdbGetObjectId(id,ent); AcDbEntity* pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead) ) { AecDb3dRoad* pWPipe = AecDb3dRoad::cast(pEnt); if (pWPipe != NULL) { dEl = pWPipe->EndPoint().z; } pEnt->close(); } } acedSSFree(ss); return dEl; }