#include "stdafx.h" #include #include "commonRoad.h" #include "TDbRoadEntity.h" #include "TRoadDragJig.h" using namespace RoadDrag; void Point3DTo2D(AcGePoint3d &ptOri, AcGePoint2d &ptDest) { ptDest.set(ptOri.x, ptOri.y); } inline bool KeyRet(AcEdJig::DragStatus ret) { return ret >= AcEdJig::kKW1 && ret <= AcEdJig::kKW9; } CString CStateData::m_arSzPrompt[] = { _T("\n请点取道路起点<退出>: "), _T("\n请点取道路的下一点或[弧道路(A)] <退出>: "), _T("\n请点取道路的下一点或[弧道路(A) /回退(U)] <退出>: "), _T("\n请点取道路的下一点或[弧道路(A) /回退(U) /闭合(C)] <退出>: "), _T("\n请点取弧道路的下一点或[直道路(L)] <退出>: "), _T("\n请点取弧道路的下一点或[直道路(L)/回退(U)] <退出>: "), _T("\n圆弧道路的中间点<退出>: ") }; CString CStateData::m_szKeyListLine = _T("A"); CString CStateData::m_szKeyListNextLine = _T("A U C"); CString CStateData::m_szKeyListArc = _T("L"); CString CStateData::m_szKeyListNextArc = _T("L U"); TRoadDragJig::TRoadDragJig(CDrawRoadDlg *pDlg) : m_pDrawDlg(pDlg) { m_pState = NULL; m_pLineRoad = new TDbLineRoadEntity(); m_pArcRoad = new TDbArcRoadEntity(); m_pRoad = new CMixRoadForJig(m_pLineRoad, m_pArcRoad); NullShow(); // 初始不绘制。 } TRoadDragJig::~TRoadDragJig(void) { // 当然,如果该实体被添加到了CAD中,该实体不需要删除, // 因此,实体被绘制之后,需要取消针对该实体的引用(置空) ASSERT(m_pLineRoad != NULL); ASSERT(m_pArcRoad != NULL); ASSERT(m_pRoad != NULL); delete m_pRoad; m_pRoad = NULL; delete m_pLineRoad; m_pLineRoad = NULL; delete m_pArcRoad; m_pArcRoad = NULL; m_pDrawDlg->SetCmdNum(1); } // 读取对话框的内容,构造圆弧道路 Adesk::Boolean TRoadDragJig::ConArcRoad() { ASSERT(m_pDrawDlg != NULL); if (m_ptFirst.distanceTo(m_ptNext) < 1.0 || m_ptFirst.distanceTo(m_ptThird) < 1.0 || m_ptThird.distanceTo(m_ptNext) < 1.0 ) { return Adesk::kFalse; } m_pArcRoad->SetArcRoad(m_ptFirst, m_ptThird, m_ptNext, m_pDrawDlg); m_pRoad->SetState(CMixRoadForJig::eArc); return Adesk::kTrue; } // 读取对话框的内容,构造直线道路。 Adesk::Boolean TRoadDragJig::ConLineRoad() { if (m_ptFirst.distanceTo(m_ptNext) < 1.0) { return Adesk::kFalse; } m_pLineRoad->SetLineRoad(m_ptFirst, m_ptNext, m_pDrawDlg); m_pRoad->SetState(CMixRoadForJig::eLine); return Adesk::kTrue; } Adesk::Boolean TRoadDragJig::NullShow() { m_pRoad->SetState(CMixRoadForJig::eNone); return Adesk::kTrue; } void TRoadDragJig::NextPoint() { m_ptFirst = m_ptNext; } void TRoadDragJig::DoIt() { ASSERT(m_pState != NULL); m_pState->Drag(); } // overide of parent cls AcEdJig::DragStatus TRoadDragJig::sampler() { m_pDrawDlg->SetCmdNum(2); setUserInputControls((UserInputControls) (AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted | AcEdJig::kNoNegativeResponseAccepted | AcEdJig::kNoZeroResponseAccepted)); ASSERT(m_pState != NULL); return m_pState->sampler(); } Adesk::Boolean TRoadDragJig::update() { ASSERT(m_pState != NULL); return m_pState->update(); } AcDbEntity* TRoadDragJig::entity() const { return m_pRoad;// 这个road中集成几种道路类型 } ////////////////////////////////////////////////////////////////////////// // state fun!! CStateData::CStateData (TRoadDragJig *jig, TRoadDragContext *pContext) : m_pRoadJig(jig), m_pContext(pContext) { } CStateData::~CStateData() { } AcEdJig::DragStatus CStateData::LineSamplerFun(CString &m_szKeyList) { ASSERT(m_pRoadJig != NULL); m_pRoadJig->setKeywordList(m_szKeyList); AcGePoint3d ptDump; AcEdJig::DragStatus ret = m_pRoadJig->acquirePoint(ptDump, POINT_2D_TO_3D(PtFirst())); if (ret == AcEdJig::kNormal) { AcGePoint2d ptDump2d; Point3DTo2D(ptDump, ptDump2d); m_pRoadJig->m_ptNext = ptDump2d; if (m_pRoadJig->m_ptFirst.distanceTo(ptDump2d) < 1.0) return AcEdJig::kNoChange; if (m_pRoadJig->m_ptCheck.distanceTo(ptDump2d) < 1.0) return AcEdJig::kNoChange; else m_pRoadJig->m_ptCheck = ptDump2d; } return ret; // 需要处理,然后生成实体 } AcEdJig::DragStatus CStateData::ArcSamplerFun(CString &m_szKeyList) { ASSERT(m_pRoadJig != NULL); m_pRoadJig->setKeywordList(m_szKeyList); AcGePoint3d ptDump; AcEdJig::DragStatus ret = m_pRoadJig->acquirePoint(ptDump, POINT_2D_TO_3D(PtFirst())); if (ret == AcEdJig::kNormal) { AcGePoint2d ptDump2d; Point3DTo2D(ptDump, ptDump2d); m_pRoadJig->m_ptNext = ptDump2d; if (PtFirst().distanceTo(ptDump2d) < 1.0) return AcEdJig::kNoChange; } return ret; } // First in AcEdJig::DragStatus CFirstInState::Drag() { m_pRoadJig->setDispPrompt(m_arSzPrompt[TRoadDragContext::eFirstIn]); AcEdJig::DragStatus ret = m_pRoadJig->drag(); // 需要判断的返回类型: // 1、正常选中一个点, // 2、其他 if (ret == AcEdJig::kNormal) { // 应该是进入下一个状态了。 m_pContext->SetSequenceState(m_pContext->SequenceAfterFirstIn()); } else { m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } return ret; } // 取点 AcEdJig::DragStatus CFirstInState::sampler() { AcGePoint3d ptDump; AcEdJig::DragStatus ret = m_pRoadJig->acquirePoint(ptDump); // 这个决定了drag的返回值 if (ret == AcEdJig::kNormal) { Point3DTo2D(ptDump, PtFirst()); m_pContext->RecordFirstPoint(PtFirst()); m_pRoadJig->NullShow(); return AcEdJig::kNoChange; } return ret; // 需要处理,然后生成实体 } Adesk::Boolean CFirstInState::update() { return m_pRoadJig->NullShow(); } // LineRoad AcEdJig::DragStatus CLineRoadState::Drag() { ASSERT(m_pRoadJig != NULL); m_pRoadJig->setDispPrompt(m_arSzPrompt[TRoadDragContext::eLineRoad]); AcEdJig::DragStatus ret; INITGET_BEG(-1, m_szKeyListLine) ret = m_pRoadJig->drag(); INITGET_END() if (ret == AcEdJig::kNull) { m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } else if (ret == AcEdJig::kNormal) { // 下一个道路了 m_pContext->PushPoint(PtFirst()); m_pContext->SetSequenceState(TRoadDragContext::eNextLineRoad); m_pRoadJig->NextPoint(); m_pContext->AddLineRoad(m_pRoadJig->m_pLineRoad); } else if (ret == AcEdJig::kKW1) { // 关键字1,切换到圆弧 m_pContext->SetSequenceState(TRoadDragContext::eArcRoad); } else { // 其他的情况! // do Nothing!! m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } return ret; } AcEdJig::DragStatus CLineRoadState::sampler() { return LineSamplerFun(m_szKeyListLine); } Adesk::Boolean CLineRoadState::update() { ASSERT(m_pRoadJig != NULL); // 这时候,需要处理实体 return m_pRoadJig->ConLineRoad(); } // NextLineRoad AcEdJig::DragStatus CNextLineRoadState::Drag() { ASSERT(m_pRoadJig != NULL); m_pRoadJig->setDispPrompt(m_arSzPrompt[TRoadDragContext::eNextLineRoad]); AcEdJig::DragStatus ret; INITGET_BEG(-1, m_szKeyListNextLine) ret = m_pRoadJig->drag(); INITGET_END() if (ret == AcEdJig::kNull) { m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } else if (ret == AcEdJig::kNormal) { // still this state m_pContext->PushPoint(PtFirst()); m_pContext->SetSequenceState(TRoadDragContext::eThirdLineRoad); m_pRoadJig->NextPoint(); m_pContext->AddLineRoad(m_pRoadJig->m_pLineRoad); } else if (ret == AcEdJig::kKW1) { // 关键字_T("A U C"); m_pContext->SetSequenceState(TRoadDragContext::eNextArcRoad); } else if (ret == AcEdJig::kKW2) {// 关键字_T("A U C"); PtFirst() = m_pContext->RoolBack(); } else { // 其他的情况! m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } return ret; } AcEdJig::DragStatus CNextLineRoadState::sampler() { return LineSamplerFun(m_szKeyListNextLine); } Adesk::Boolean CNextLineRoadState::update() { ASSERT(m_pRoadJig != NULL); // 这时候,需要处理实体 return m_pRoadJig->ConLineRoad(); } // NextLineRoad AcEdJig::DragStatus CThirdLineRoadState::Drag() { ASSERT(m_pRoadJig != NULL); m_pRoadJig->setDispPrompt(m_arSzPrompt[TRoadDragContext::eThirdLineRoad]); AcEdJig::DragStatus ret; INITGET_BEG(-1, m_szKeyListNextLine) ret = m_pRoadJig->drag(); INITGET_END() if (ret == AcEdJig::kNull) { m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } else if (ret == AcEdJig::kNormal) { // still this state m_pContext->PushPoint(PtFirst()); m_pContext->SetSequenceState(TRoadDragContext::eThirdLineRoad); m_pRoadJig->NextPoint(); m_pContext->AddLineRoad(m_pRoadJig->m_pLineRoad); } else if (ret == AcEdJig::kKW1) { // 关键字_T("A U C"); m_pContext->SetSequenceState(TRoadDragContext::eNextArcRoad); } else if (ret == AcEdJig::kKW2) {// 关键字_T("A U C"); PtFirst() = m_pContext->RoolBack(); } else if (ret == AcEdJig::kKW3) {// 关键字_T("A U C"); m_pRoadJig->MakeClosed(m_pContext->GetFirstPoint()); if (m_pRoadJig->ConLineRoad()) m_pContext->AddLineRoad(m_pRoadJig->m_pLineRoad); m_pContext->ClearStep(); m_pContext->SetSequenceState(TRoadDragContext::eFirstIn); m_pContext->SetStateAfterFirstIn(TRUE); } else { // 其他的情况! m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } return ret; } AcEdJig::DragStatus CThirdLineRoadState::sampler() { return LineSamplerFun(m_szKeyListNextLine); } Adesk::Boolean CThirdLineRoadState::update() { ASSERT(m_pRoadJig != NULL); // 这时候,需要处理实体 return m_pRoadJig->ConLineRoad(); } // ArcRoad AcEdJig::DragStatus CArcRoadState::Drag() { ASSERT(m_pRoadJig != NULL); m_pRoadJig->setDispPrompt(m_arSzPrompt[TRoadDragContext::eArcRoad]); AcEdJig::DragStatus ret; INITGET_BEG(-1, m_szKeyListArc) ret = m_pRoadJig->drag(); INITGET_END() if (ret == AcEdJig::kNull) { m_pContext->SetSequenceState(TRoadDragContext::eFirstIn); m_pContext->SetStateAfterFirstIn(FALSE); m_pContext->ClearStep(); } else if (ret == AcEdJig::kNormal) { m_pContext->SetSequenceState(TRoadDragContext::eArcMidRoad); } else if (ret == AcEdJig::kKW1) { // 关键字1,切换到线段 m_pContext->SetSequenceState(TRoadDragContext::eLineRoad); } else { // 其他的情况! m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } return ret; } AcEdJig::DragStatus CArcRoadState::sampler() { return ArcSamplerFun(m_szKeyListArc); } Adesk::Boolean CArcRoadState::update() { return m_pRoadJig->NullShow(); } // NextArcRoad AcEdJig::DragStatus CNextArcRoadState::Drag() { ASSERT(m_pRoadJig != NULL); m_pRoadJig->setDispPrompt(m_arSzPrompt[TRoadDragContext::eNextArcRoad]); AcEdJig::DragStatus ret; INITGET_BEG(-1, m_szKeyListNextArc) ret = m_pRoadJig->drag(); INITGET_END() // 需要判断的返回类型: // 1、选中了一个点,(组成了一个线段回路) // 2、取消 // 3、关键字选中 // 3、其他,比如:右键,空格,回车等 if (ret == AcEdJig::kNull) { m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } else if (ret == AcEdJig::kNormal) { m_pContext->SetSequenceState(TRoadDragContext::eArcMidRoad); } else if (ret == AcEdJig::kKW1) { // 关键字,切换到LineRoad,_T("L U"); if (m_pContext->PushPointNum() >= 2) m_pContext->SetSequenceState(TRoadDragContext::eThirdLineRoad); else m_pContext->SetSequenceState(TRoadDragContext::eNextLineRoad); } else if (ret == AcEdJig::kKW2) { // Undo; PtFirst() = m_pContext->RoolBack(); } else { // 其他的情况! // do Nothing!! m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } return ret; } AcEdJig::DragStatus CNextArcRoadState::sampler() { return ArcSamplerFun(m_szKeyListNextArc); } Adesk::Boolean CNextArcRoadState::update() { return m_pRoadJig->NullShow(); } // MidArcRoad AcEdJig::DragStatus CMidArcRoadState::Drag() { ASSERT(m_pRoadJig != NULL); m_pRoadJig->setDispPrompt(m_arSzPrompt[TRoadDragContext::eArcMidRoad]); AcEdJig::DragStatus ret; ret = m_pRoadJig->drag(); // 需要判断的返回类型: // 1、选中了一个点,(组成了一个线段回路) // 2、取消 // 3、关键字选中 // 3、其他,比如:右键,空格,回车等 if (ret == AcEdJig::kCancel) { m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } else if (ret == AcEdJig::kNull) { m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } else if (ret == AcEdJig::kNormal) { m_pContext->PushPoint(PtFirst()); m_pContext->SetSequenceState(TRoadDragContext::eNextArcRoad); m_pRoadJig->NextPoint(); m_pContext->AddArcRoad(m_pRoadJig->m_pArcRoad); } else if (ret == AcEdJig::kNoChange) { // do nothing; } else { // 其他的情况! m_pContext->SetSequenceState(TRoadDragContext::eSequenceCancel); } return ret; } AcEdJig::DragStatus CMidArcRoadState::sampler() { ASSERT(m_pRoadJig != NULL); AcGePoint3d ptDump; AcEdJig::DragStatus ret = m_pRoadJig->acquirePoint(ptDump); if (ret == AcEdJig::kNormal) { AcGePoint2d ptDump2d; Point3DTo2D(ptDump, ptDump2d); if (PtFirst().distanceTo(ptDump2d) < 1.0) return AcEdJig::kNoChange; else if (m_pRoadJig->m_ptNext.distanceTo(ptDump2d) < 1.0) return AcEdJig::kNoChange; m_pRoadJig->m_ptThird = ptDump2d; if (m_pRoadJig->m_ptCheck.distanceTo(ptDump2d) < 1.0) return AcEdJig::kNoChange; else m_pRoadJig->m_ptCheck = ptDump2d; } return ret; // 需要处理,然后生成实体 } Adesk::Boolean CMidArcRoadState::update() { ASSERT(m_pRoadJig != NULL); return m_pRoadJig->ConArcRoad(); } ACRX_DXF_DEFINE_MEMBERS(CMixRoadForJig, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_MIX_ROAD, "ATS_MIX_ROAD缺乏解释器图形看不见, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(CMixRoadForJig); Acad::ErrorStatus CMixRoadForJig::dwgInFields (AcDbDwgFiler *pFiler) { assertWriteEnabled(); Acad::ErrorStatus errorStatus = TDbEntity::dwgInFields(pFiler); if (Acad::eOk != errorStatus) { return errorStatus; } AcGePoint2d ptStart, ptEnd; pFiler->readAddress((void**)(&m_pLineRoad)); pFiler->readAddress((void**)(&m_pArcRoad)); return pFiler->filerStatus(); } Acad::ErrorStatus CMixRoadForJig::dwgOutFields(AcDbDwgFiler*pFiler) const { assertReadEnabled(); Acad::ErrorStatus errorStatus = TDbEntity::dwgOutFields(pFiler); if (Acad::eOk != errorStatus) { return errorStatus; } pFiler->writeAddress(m_pLineRoad); pFiler->writeAddress(m_pArcRoad); return pFiler->filerStatus(); } Acad::ErrorStatus CMixRoadForJig::ExplodeOrDraw2d(XExplodeDraw &dc) const { ASSERT(m_pLineRoad != NULL); ASSERT(m_pArcRoad != NULL); assertReadEnabled(); if (m_eDrawState == eNone) { // 不绘制 } else if (m_eDrawState == eLine) { m_pLineRoad->ExplodeOrDraw2d(dc); } else if (m_eDrawState == eArc) { m_pArcRoad->ExplodeOrDraw2d(dc); } return Acad::eOk; } ////////////////////////////////////////////////////////////////////////// // TRoadDragContext TRoadDragContext::TRoadDragContext(CDrawRoadDlg *pDrawDlg) : m_pDrawDlg(pDrawDlg), m_bLineAfterFirstrIn(TRUE), m_eSequence(eFirstIn) { } TRoadDragContext::~TRoadDragContext() { ClearStep(); } void TRoadDragContext::AddArcRoad(TDbArcRoadEntity *pArcRoadEnt) { ASSERT(pArcRoadEnt != NULL); CArcRoad *pArcRoad = pArcRoadEnt->CreateArcRoad(m_pDrawDlg); m_datas.AddArcRoad(*pArcRoad); delete pArcRoad; pArcRoad = NULL; } void TRoadDragContext::AddLineRoad(TDbLineRoadEntity *pLineRoadEnt) { ASSERT(pLineRoadEnt != NULL); CLineRoad *pLineRoad = pLineRoadEnt->CreateLineRoad(m_pDrawDlg); m_datas.AddLineRoad(*pLineRoad); delete pLineRoad; pLineRoad = NULL; } void TRoadDragContext::PushPoint(const AcGePoint2d &ptPush) { m_arPushPoint.append(ptPush); } AcGePoint2d TRoadDragContext::PopPoint() { if (PushPointNum() > 0) { PopSequence();// 调整状态 AcGePoint2d ptPop = m_arPushPoint[m_arPushPoint.length() - 1]; m_arPushPoint.removeLast(); return ptPop; } else { ASSERT(0); return AcGePoint2d(); } } AcGePoint2d TRoadDragContext::RoolBack() { m_datas.RoolBack(); return PopPoint(); } TRoadDragContext::ESequence TRoadDragContext::SequenceAfterFirstIn() { return m_bLineAfterFirstrIn ? eLineRoad : eArcRoad; } void TRoadDragContext::PopSequence() { ASSERT(PushPointNum() > 0); if (m_eSequence == eNextLineRoad) { m_eSequence = eLineRoad; } else if (m_eSequence == eThirdLineRoad) { if (PushPointNum() > 2) m_eSequence = eThirdLineRoad; else m_eSequence = eNextLineRoad; } else if (m_eSequence == eNextArcRoad) { if (PushPointNum() > 1) m_eSequence = eNextArcRoad; else m_eSequence = eArcRoad; } else { ASSERT(0); } } void TRoadDragContext ::ClearStep() { ClearAcaryAll(m_arPushPoint); m_datas.ClearStep(); }