/////////////////////////////////////////////////////////////////////////////// // 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 "DbLineMultiModesGripPE.h" //---------------------------------------------------------------------------------------- #include "DbLine.h" #include "DbCommandContext.h" #include "Gs/Gs.h" //######################################################################################## //############### OdDbLineMultiModesGripPE ############## //######################################################################################## ODRX_NO_CONS_DEFINE_MEMBERS(OdGripLineMultiModeAppData, OdRxObject); bool OdDbLineMultiModesGripPE::getGripModes(const OdDbEntity* pEnt, OdDbGripData* pGripData, OdArray& modes, unsigned int& curMode) const { if (!pEnt || !pGripData) return false; OdGripLineMultiModeAppDataPtr appData = static_cast(pGripData->appData()); if (!appData) return false; appData->getGripModes(modes); curMode = appData->mode(); return true; } unsigned int OdDbLineMultiModesGripPE::mode(OdDbEntity*, OdDbGripData* pGripData) const { OdGripLineMultiModeAppDataPtr appData = static_cast(pGripData->appData()); return appData->mode(); } OdDbMultiModesGripPE::GripMode OdDbLineMultiModesGripPE::modeEx(OdDbEntity*, OdDbGripData* pGripData) const { OdGripLineMultiModeAppDataPtr appData = static_cast(pGripData->appData()); return appData->gripMode(); } namespace Trackers { class MoveGripTracker : public OdStaticRxObject { public: MoveGripTracker() = delete; MoveGripTracker(const OdDbLinePtr& org, const OdIntArray& indices, const OdGePoint3d& pnt) : m_pLine(org->clone()), m_indices(indices), m_pnt(pnt) { } virtual void setValue(const OdGePoint3d& value) { OdGeVector3d vec = value - m_pnt; if (eOk == m_pLine->moveGripPointsAt(m_indices, value - m_pnt)) m_pnt = value; } virtual int addDrawables(OdGsView* pView) { pView->add(m_pLine, 0); return 1; } virtual void removeDrawables(OdGsView* pView) { pView->erase(m_pLine); } private: OdDbLinePtr m_pLine; const OdIntArray m_indices; OdGePoint3d m_pnt; }; class LengthenTracker : public OdStaticRxObject { public: LengthenTracker() = delete; LengthenTracker(const OdDbLinePtr& org, OdGripLineMultiModeAppData::LineGripType type) : m_pLine(org->clone()), m_gripType(type) {} virtual void setValue(const OdGePoint3d& value) { if (m_gripType == OdGripLineMultiModeAppData::LineGripType::START) m_pLine->setStartPoint(calculatePntProjections(value, m_pLine->startPoint())); else if (m_gripType == OdGripLineMultiModeAppData::LineGripType::END) m_pLine->setEndPoint(calculatePntProjections(value, m_pLine->endPoint())); } virtual int addDrawables(OdGsView* pView) { pView->add(m_pLine, 0); return 1; } virtual void removeDrawables(OdGsView* pView) { pView->erase(m_pLine); } void modifyLine(OdDbLinePtr& org) { if (m_gripType == OdGripLineMultiModeAppData::LineGripType::START) org->setStartPoint(m_pLine->startPoint()); else if (m_gripType == OdGripLineMultiModeAppData::LineGripType::END) org->setEndPoint(m_pLine->endPoint()); } private: OdGePoint3d calculatePntProjections(const OdGePoint3d& pnt, const OdGePoint3d& sidePnt) const { const OdGeVector3d v = m_pLine->endPoint() - m_pLine->startPoint(); const double len = v.lengthSqrd(); const OdGeVector3d vec = pnt - sidePnt; const double scalar = vec.dotProduct(v); const OdGeVector3d vecProj = (scalar / len) * v; return sidePnt + vecProj; } OdDbLinePtr m_pLine; OdGripLineMultiModeAppData::LineGripType m_gripType; }; } bool OdDbLineMultiModesGripPE::setMode(OdDbEntity* pEnt, OdDbGripData* pGripData, unsigned int newMode) { OdDbLinePtr pLine = pEnt; OdDbDatabase* pDb = pLine->database(); OdDbCommandContextPtr pCmdCtx = OdDbCommandContext::registredCommandContext(pDb); OdDbUserIO* pIO = pCmdCtx->dbUserIO(); if (!pGripData) return false; OdGripLineMultiModeAppDataPtr 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::MoveGripTracker tracker(pLine, indices, pGripData->gripPoint()); OdGePoint3d pnt = pIO->getPoint(curMode.CLIPromptString, OdEd::kGptRubberBand, &pGripData->gripPoint(), curMode.CLIKeywordList, &tracker); pLine->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::LengthenTracker tracker(pLine, appData->lineGripType()); pIO->getPoint(curMode.CLIPromptString, OdEd::kGptRubberBand, &pGripData->gripPoint(), curMode.CLIKeywordList, &tracker); tracker.modifyLine(pLine); break; } default: return false; } } catch (const OdEdCancel&) { return false; } return true; } OdDbMultiModesGripPE::GripType OdDbLineMultiModesGripPE::gripType(OdDbEntity*, OdDbGripData* pGripData) const { if (pGripData) { OdGripLineMultiModeAppDataPtr appData = static_cast(pGripData->appData()); if (appData) return appData->gripType(); } return OdDbMultiModesGripPE::kPrimary; } void OdDbLineMultiModesGripPE::reset(OdDbEntity*) { } void OdGripLineMultiModeAppData::initGripModes() { if (!m_modes.empty() || (m_lineGripType != START && m_lineGripType != 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; } { OdDbMultiModesGripPE::GripMode mode; mode.Mode = 102; mode.DisplayString = "Lengthen"; mode.ActionType = OdDbMultiModesGripPE::GripActionType::kImmediate; mode.CLIDisplayString = "** LENGTHEN **"; mode.CLIPromptString = "Specify end point:"; m_modes[mode.Mode] = mode; } } void OdGripLineMultiModeAppData::getGripModes(OdArray& modes) { for (const auto& mode : m_modes) modes.append(mode.second); } bool OdGripLineMultiModeAppData::getIndices(OdIntArray& indices) const { if (m_lineGripType == START || m_lineGripType == END || m_lineGripType == MIDDLE) indices.append(m_lineGripType); else return false; return true; }