From b7791d0068dc0cb0ece4b08c477f0d3da2ab70d4 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Fri, 27 Oct 2023 14:08:14 -0400 Subject: [PATCH] [Meas]fix crash on active view not 3d view --- .../Measure/Gui/ViewProviderMeasureBase.cpp | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/Mod/Measure/Gui/ViewProviderMeasureBase.cpp b/src/Mod/Measure/Gui/ViewProviderMeasureBase.cpp index e004b59d3e99..40bf12638981 100644 --- a/src/Mod/Measure/Gui/ViewProviderMeasureBase.cpp +++ b/src/Mod/Measure/Gui/ViewProviderMeasureBase.cpp @@ -216,7 +216,7 @@ void ViewProviderMeasureBase::redrawAnnotation() // Base::Console().Message("VPMB::redrawAnnotation()\n"); } -//! connect to the subject to receive visibility updates +//! connect to the subject to receive visibility updates void ViewProviderMeasureBase::connectToSubject(App::DocumentObject* subject) { if (!subject) { @@ -228,8 +228,8 @@ void ViewProviderMeasureBase::connectToSubject(App::DocumentObject* subject) //NOLINTEND subject->signalChanged.connect(bndVisibility); } - -//! connect to the subject to receive visibility updates + +//! connect to the subject to receive visibility updates void ViewProviderMeasureBase::connectToSubject(std::vector subject) { if (subject.empty()) { @@ -238,8 +238,8 @@ void ViewProviderMeasureBase::connectToSubject(std::vector //NOLINTBEGIN auto bndVisibility = boost::bind(&ViewProviderMeasureBase::onSubjectVisibilityChanged, this, bp::_1, bp::_2); - //NOLINTEND - + //NOLINTEND + // TODO: should we connect to all the subject objects when there is >1? auto proxy = subject.front(); proxy->signalChanged.connect(bndVisibility); @@ -264,24 +264,33 @@ Measure::MeasureBase* ViewProviderMeasureBase::getMeasureObject() //! an example of an elementDirection would be the vector from the start of a line to the end. Base::Vector3d ViewProviderMeasureBase::getTextDirection(Base::Vector3d elementDirection, double tolerance) { + // TODO: this can fail if the active view is not a 3d view (spreadsheet, techdraw page) and something causes a measure to try to update + // we need to search throught the mdi views for a 3d view and take the direction from it (or decide that if the active view is not 3d, + // assume we are looking from the front). + Base::Vector3d viewDirection; + Base::Vector3d upDirection; auto view = dynamic_cast(Gui::Application::Instance->activeDocument()->getActiveView()); - // if (!view) { - // // Measure doesn't work with this kind of active view. Might be dependency graph, might be TechDraw, or ???? - // // i don't know if this can even happen. - // throw Base::RuntimeError("Measure doesn't work with this kind of active view."); - // } - Gui::View3DInventorViewer* viewer = view->getViewer(); - Base::Vector3d viewDirection = toVector3d(viewer->getViewDirection()).Normalize(); + if (view) { + Gui::View3DInventorViewer* viewer = view->getViewer(); + viewDirection = toVector3d(viewer->getViewDirection()).Normalize(); + upDirection = toVector3d(viewer->getUpDirection()).Normalize(); + // Measure doesn't work with this kind of active view. Might be dependency graph, might be TechDraw, or ???? + //throw Base::RuntimeError("Measure doesn't work with this kind of active view."); + } else { + viewDirection = Base::Vector3d(0.0, 1.0, 0.0); + upDirection = Base::Vector3d(0.0, 0.0, 1.0); + } + Base::Vector3d textDirection = elementDirection.Cross(viewDirection); if (textDirection.Length() < tolerance) { // either elementDirection and viewDirection are parallel or one of them is null. - viewDirection = toVector3d(viewer->getUpDirection()).Normalize(); - textDirection = elementDirection.Cross(viewDirection); + textDirection = elementDirection.Cross(upDirection); } return textDirection.Normalize(); } + //! true if the subject of this measurement is visible. For Measures that have multiple object subject, //! all of the subjects must be visible. bool ViewProviderMeasureBase::isSubjectVisible()