Measure: Fix quick measure

* Create QuickMeasure in C++ instead of Python to avoid that it will be garbage collected
* Handle exceptions in case of invalid selections
* Refactor QuickMeasure class
* Fix linter warnings
This commit is contained in:
wmayer
2024-05-10 21:38:41 +02:00
committed by Chris Hennes
parent c05111cb59
commit c16a4e034d
4 changed files with 54 additions and 27 deletions

View File

@@ -20,7 +20,9 @@
**************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QApplication>
#endif
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <Base/PyObjectBase.h>
@@ -71,7 +73,7 @@ PyMOD_INIT_FUNC(MeasureGui)
PyErr_SetString(PyExc_ImportError, "Cannot load Gui module in console application.");
PyMOD_Return(nullptr);
}
// load dependent module
try {
Base::Interpreter().loadModule("Measure");
@@ -97,7 +99,11 @@ PyMOD_INIT_FUNC(MeasureGui)
// Q_INIT_RESOURCE(Measure);
Base::Interpreter().addType(&MeasureGui::QuickMeasurePy::Type, mod, "QuickMeasure");
Base::Interpreter().addType(&MeasureGui::QuickMeasurePy::Type, mod, "QuickMeasure");
// Create a QuickMeasure instance
auto measure = new MeasureGui::QuickMeasure(QApplication::instance());
Q_UNUSED(measure)
PyMOD_Return(mod);
}

View File

@@ -23,11 +23,6 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <cmath>
#include <vector>
#endif
@@ -51,9 +46,10 @@
using namespace Measure;
using namespace MeasureGui;
QuickMeasure::QuickMeasure(QObject* parent) : QObject(parent)
QuickMeasure::QuickMeasure(QObject* parent)
: QObject(parent)
, measurement{new Measure::Measurement()}
{
measurement = new Measure::Measurement();
}
QuickMeasure::~QuickMeasure()
@@ -61,21 +57,42 @@ QuickMeasure::~QuickMeasure()
delete measurement;
}
void QuickMeasure::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (msg.Type == Gui::SelectionChanges::SetPreselect || msg.Type == Gui::SelectionChanges::RmvPreselect) {
return;
try {
tryMeasureSelection(msg);
}
catch (const Base::IndexError&) {
// ignore this exception because it can be caused by trying to access a non-existing
// sub-element e.g. when selecting a construction geometry in sketcher
}
catch (const Base::Exception& e) {
e.ReportException();
}
}
void QuickMeasure::tryMeasureSelection(const Gui::SelectionChanges& msg)
{
if (canMeasureSelection(msg)) {
measurement->clear();
addSelectionToMeasurement();
printResult();
}
}
bool QuickMeasure::canMeasureSelection(const Gui::SelectionChanges& msg) const
{
if (msg.Type == Gui::SelectionChanges::SetPreselect ||
msg.Type == Gui::SelectionChanges::RmvPreselect) {
return false;
}
Gui::Document* doc = Gui::Application::Instance->activeDocument();
if (!doc) { return; }
return doc != nullptr;
}
measurement->clear();
std::vector<Part::TopoShape> subShapes;
std::vector<App::DocumentObject*> docsToMove;
void QuickMeasure::addSelectionToMeasurement()
{
for (auto& selObj : Gui::Selection().getSelectionEx()) {
App::DocumentObject* obj = selObj.getObject();
const std::vector<std::string> subNames = selObj.getSubNames();
@@ -88,7 +105,10 @@ void QuickMeasure::onSelectionChanged(const Gui::SelectionChanges& msg)
}
}
}
}
void QuickMeasure::printResult()
{
MeasureType mtype = measurement->getType();
if (mtype == MeasureType::Surfaces) {
Base::Quantity area(measurement->area(), Base::Unit::Area);
@@ -112,7 +132,7 @@ void QuickMeasure::onSelectionChanged(const Gui::SelectionChanges& msg)
else if (mtype == MeasureType::Cylinder || mtype == MeasureType::Sphere || mtype == MeasureType::Torus) {
Base::Quantity area(measurement->area(), Base::Unit::Area);
Base::Quantity rad(measurement->radius(), Base::Unit::Length);
print(tr("Area: %1, Radius: %2").arg(area.getSafeUserString()).arg(rad.getSafeUserString()));
print(tr("Area: %1, Radius: %2").arg(area.getSafeUserString(), rad.getSafeUserString()));
}
else if (mtype == MeasureType::Edges) {
Base::Quantity dist(measurement->length(), Base::Unit::Length);
@@ -125,7 +145,7 @@ void QuickMeasure::onSelectionChanged(const Gui::SelectionChanges& msg)
else if (mtype == MeasureType::TwoLines) {
Base::Quantity angle(measurement->angle(), Base::Unit::Length);
Base::Quantity dist(measurement->length(), Base::Unit::Length);
print(tr("Angle: %1, Total length: %2").arg(angle.getSafeUserString()).arg(dist.getSafeUserString()));
print(tr("Angle: %1, Total length: %2").arg(angle.getSafeUserString(), dist.getSafeUserString()));
}
else if (mtype == MeasureType::Line) {
Base::Quantity dist(measurement->length(), Base::Unit::Length);
@@ -146,7 +166,6 @@ void QuickMeasure::onSelectionChanged(const Gui::SelectionChanges& msg)
else {
print(QString::fromLatin1(""));
}
}
void QuickMeasure::print(const QString& message)
@@ -155,4 +174,4 @@ void QuickMeasure::print(const QString& message)
}
#include "moc_QuickMeasure.cpp"
#include "moc_QuickMeasure.cpp"

View File

@@ -45,7 +45,11 @@ public:
private:
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
void tryMeasureSelection(const Gui::SelectionChanges& msg);
bool canMeasureSelection(const Gui::SelectionChanges& msg) const;
void addSelectionToMeasurement();
void printResult();
void print(const QString& message);
Measure::Measurement* measurement;

View File

@@ -26,6 +26,7 @@
# python which could complicate things further.
import Measure
import MeasureGui
from MeasureCOM import makeMeasureCOM, MeasureCOM
@@ -40,6 +41,3 @@ FreeCAD.MeasureManager.addMeasureType(
"Center of Mass",
MeasureCOM,
)
import MeasureGui
MeasureGui.QuickMeasure()