/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2024, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2024 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "DbArcMultiModesGripPE.h" //---------------------------------------------------------------------------------------- #include "DbArc.h" #include "DbCommandContext.h" #include "Gs/Gs.h" #include "Ge/GeCircArc3d.h" //######################################################################################## //############### OdDbArcMultiModesGripPE ############## //######################################################################################## ODRX_NO_CONS_DEFINE_MEMBERS(OdGripArcMultiModeAppData, OdRxObject); bool OdDbArcMultiModesGripPE::getGripModes(const OdDbEntity* pEnt, OdDbGripData* pGripData, OdArray& modes, unsigned int& curMode) const { if (!pEnt || !pGripData) return false; OdGripArcMultiModeAppDataPtr appData = static_cast(pGripData->appData()); if (!appData) return false; appData->getGripModes(modes); curMode = appData->mode(); return true; } unsigned int OdDbArcMultiModesGripPE::mode(OdDbEntity*, OdDbGripData* pGripData) const { OdGripArcMultiModeAppDataPtr appData = static_cast(pGripData->appData()); return appData->mode(); } OdDbMultiModesGripPE::GripMode OdDbArcMultiModesGripPE::modeEx(OdDbEntity*, OdDbGripData* pGripData) const { OdGripArcMultiModeAppDataPtr appData = static_cast(pGripData->appData()); return appData->gripMode(); } namespace Trackers { class StretchGripTracker : public OdStaticRxObject { public: StretchGripTracker() = delete; StretchGripTracker(const OdDbArcPtr& org, OdGripArcMultiModeAppData::ArcGripType type) : m_pArc(org->clone()), m_gripType(type) { m_pArc->getStartPoint(m_orgStart); m_pArc->getEndPoint(m_orgEnd); double start = 0., end = 0.; m_pArc->getStartParam(start); m_pArc->getEndParam(end); m_pArc->getPointAtParam((start + end) / 2, m_orgMiddle); } virtual void setValue(const OdGePoint3d& value) { OdGeCircArc3d circArc; OdGePoint3d start = m_orgStart; OdGePoint3d middle = m_orgMiddle; OdGePoint3d end = m_orgEnd; if (m_gripType == OdGripArcMultiModeAppData::ArcGripType::START) start = value; else if (m_gripType == OdGripArcMultiModeAppData::ArcGripType::END) end = value; else if (m_gripType == OdGripArcMultiModeAppData::ArcGripType::MIDDLE) middle = value; OdGeError err; circArc.set(start, middle, end, err); if (err != OdGeError::kOk) circArc.set(m_orgStart, m_orgMiddle, m_orgEnd); m_pArc->setFromOdGeCurve(circArc); } virtual int addDrawables(OdGsView* pView) { pView->add(m_pArc, 0); return 1; } virtual void removeDrawables(OdGsView* pView) { pView->erase(m_pArc); } private: OdDbArcPtr m_pArc; OdGePoint3d m_orgStart; OdGePoint3d m_orgMiddle; OdGePoint3d m_orgEnd; OdGripArcMultiModeAppData::ArcGripType m_gripType; }; class ArcRadiusTracker : public OdStaticRxObject { public: ArcRadiusTracker() = delete; ArcRadiusTracker(const OdDbArcPtr& org) : m_pArc(org->clone()) { } virtual void setValue(const OdGePoint3d& value) { m_pArc->setRadius(value.distanceTo(m_pArc->center())); } virtual int addDrawables(OdGsView* pView) { pView->add(m_pArc, 0); return 1; } virtual void removeDrawables(OdGsView* pView) { pView->erase(m_pArc); } private: OdDbArcPtr m_pArc; }; class ArcLengthenTracker : public OdStaticRxObject { public: ArcLengthenTracker() = delete; ArcLengthenTracker(const OdDbArcPtr& org, OdGripArcMultiModeAppData::ArcGripType type) : m_pArc(org->clone()), m_gripType(type) { } virtual void setValue(const OdGePoint3d& value) { OdGeVector3d v = value - m_pArc->center(); v.normalize(); double ang = 0.; m_pArc->getParamAtPoint(m_pArc->center() + v * m_pArc->radius(), ang); if (m_gripType == OdGripArcMultiModeAppData::ArcGripType::START) m_pArc->setStartAngle(ang); else if (m_gripType == OdGripArcMultiModeAppData::ArcGripType::END) m_pArc->setEndAngle(ang); } virtual int addDrawables(OdGsView* pView) { pView->add(m_pArc, 0); return 1; } virtual void removeDrawables(OdGsView* pView) { pView->erase(m_pArc); } void modifyArc(OdDbArcPtr& org) { org->copyFrom(m_pArc); } private: OdDbArcPtr m_pArc; OdGripArcMultiModeAppData::ArcGripType m_gripType; }; } bool OdDbArcMultiModesGripPE::setMode(OdDbEntity* pEnt, OdDbGripData* pGripData, unsigned int newMode) { OdDbArcPtr pArc = pEnt; OdDbDatabase* pDb = pArc->database(); OdDbCommandContextPtr pCmdCtx = OdDbCommandContext::registredCommandContext(pDb); OdDbUserIO* pIO = pCmdCtx->dbUserIO(); if (!pGripData) return false; OdGripArcMultiModeAppDataPtr appData = static_cast(pGripData->appData()); if (!appData) return false; appData->setMode(newMode); const OdDbMultiModesGripPE::GripMode curMode = appData->gripMode(); try { switch (newMode) { case 101: { int nKeyword = 0; bool bKeyword = false; OdIntArray indices; if (!appData->getIndices(indices)) return false; try { Trackers::StretchGripTracker tracker(pArc, appData->arcGripType()); OdGePoint3d pnt = pIO->getPoint(curMode.CLIPromptString, OdEd::kGptRubberBand, &pGripData->gripPoint(), curMode.CLIKeywordList, &tracker); pArc->moveGripPointsAt(indices, pnt - pGripData->gripPoint()); } catch (const OdEdKeyword& kwd) { bKeyword = true; nKeyword = kwd.keywordIndex(); } catch (...) { throw; } if (bKeyword && nKeyword == 0) return false; break; } case 102: { Trackers::ArcRadiusTracker tracker(pArc); OdGePoint3d pnt = pIO->getPoint(curMode.CLIPromptString, OdEd::kGptRubberBand, &pGripData->gripPoint(), curMode.CLIKeywordList, &tracker); pArc->setRadius(pnt.distanceTo(pArc->center())); break; } case 103: { Trackers::ArcLengthenTracker tracker(pArc, appData->arcGripType()); pIO->getPoint(curMode.CLIPromptString, OdEd::kGptRubberBand, &pGripData->gripPoint(), curMode.CLIKeywordList, &tracker); tracker.modifyArc(pArc); break; } default: return false; } } catch (const OdEdCancel&) { return false; } return true; } OdDbMultiModesGripPE::GripType OdDbArcMultiModesGripPE::gripType(OdDbEntity*, OdDbGripData* pGripData) const { if (pGripData) { OdGripArcMultiModeAppDataPtr appData = static_cast(pGripData->appData()); if (appData) { return appData->gripType(); } } return OdDbMultiModesGripPE::kPrimary; } void OdDbArcMultiModesGripPE::reset(OdDbEntity*) { } void OdGripArcMultiModeAppData::initGripModes() { if (!m_modes.empty() || (m_arcGripType != MIDDLE && m_arcGripType != START && m_arcGripType != END)) return; { OdDbMultiModesGripPE::GripMode mode; mode.Mode = 101; mode.DisplayString = "Stretch"; mode.ActionType = OdDbMultiModesGripPE::GripActionType::kImmediate; mode.CLIDisplayString = "** STRETCH **"; mode.CLIPromptString = "Specify stretch point or [eXit]:"; mode.CLIKeywordList = "eXit"; m_modes[mode.Mode] = mode; } if (m_arcGripType == MIDDLE) { OdDbMultiModesGripPE::GripMode mode; mode.Mode = 102; mode.DisplayString = "Radius"; mode.ActionType = OdDbMultiModesGripPE::GripActionType::kImmediate; mode.CLIDisplayString = "** RADIUS **"; mode.CLIPromptString = "Specify radius:"; m_modes[mode.Mode] = mode; } else if (m_arcGripType == START || m_arcGripType == END) { OdDbMultiModesGripPE::GripMode mode; mode.Mode = 103; mode.DisplayString = "Lengthen"; mode.ActionType = OdDbMultiModesGripPE::GripActionType::kImmediate; mode.CLIDisplayString = "** LENGTHEN **"; mode.CLIPromptString = "Specify end point of arc:"; m_modes[mode.Mode] = mode; } } void OdGripArcMultiModeAppData::getGripModes(OdArray& modes) { for (const auto& mode : m_modes) modes.append(mode.second); } bool OdGripArcMultiModeAppData::getIndices(OdIntArray& indices) const { if (m_arcGripType == START || m_arcGripType == END || m_arcGripType == MIDDLE || m_arcGripType == CENTER) indices.append(m_arcGripType); else return false; return true; }