[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
This commit is contained in:
pre-commit-ci[bot]
2024-08-25 11:42:33 +00:00
parent 7cf6c4f5df
commit 7c6b8cc9ab
45 changed files with 1378 additions and 1040 deletions

View File

@@ -43,7 +43,8 @@
#include "MeasureArea.h"
#include "MeasureRadius.h"
namespace Measure {
namespace Measure
{
// explicit template instantiations
template class MeasureExport MeasureBaseExtendable<Part::MeasureAngleInfo>;
@@ -54,12 +55,13 @@ template class MeasureExport MeasureBaseExtendable<Part::MeasurePositionInfo>;
template class MeasureExport MeasureBaseExtendable<Part::MeasureRadiusInfo>;
class Module : public Py::ExtensionModule<Module>
class Module: public Py::ExtensionModule<Module>
{
public:
Module() : Py::ExtensionModule<Module>("Measure")
Module()
: Py::ExtensionModule<Module>("Measure")
{
initialize("This module is the Measure module."); // register with Python
initialize("This module is the Measure module."); // register with Python
}
private:
@@ -70,7 +72,7 @@ PyObject* initModule()
return Base::Interpreter().addModule(new Module);
}
} // namespace Measure
} // namespace Measure
using namespace Measure;
@@ -81,7 +83,7 @@ PyMOD_INIT_FUNC(Measure)
try {
Base::Interpreter().runString("import Part");
}
catch(const Base::Exception& e) {
catch (const Base::Exception& e) {
PyErr_SetString(PyExc_ImportError, e.what());
PyMOD_Return(nullptr);
}
@@ -90,100 +92,94 @@ PyMOD_INIT_FUNC(Measure)
Base::Interpreter().addType(&Measure::MeasurementPy::Type, mod, "Measurement");
Base::Interpreter().addType(&Measure::MeasureBasePy::Type, mod, "MeasureBase");
Measure::Measurement ::init();
Measure::Measurement ::init();
// umf classes
Measure::MeasureDistanceType ::init();
Measure::MeasureBase ::init();
Measure::MeasurePython ::init();
Measure::MeasureAngle ::init();
Measure::MeasureDistance ::init();
Measure::MeasureDistanceType ::init();
Measure::MeasureBase ::init();
Measure::MeasurePython ::init();
Measure::MeasureAngle ::init();
Measure::MeasureDistance ::init();
Measure::MeasureDistanceDetached::init();
Measure::MeasurePosition ::init();
Measure::MeasureLength ::init();
Measure::MeasureArea ::init();
Measure::MeasureRadius ::init();
Measure::MeasurePosition ::init();
Measure::MeasureLength ::init();
Measure::MeasureArea ::init();
Measure::MeasureRadius ::init();
// Add fundamental umf Measure Types
App::MeasureManager::addMeasureType("DISTANCE",
"Distance",
"Measure::MeasureDistance",
MeasureDistance::isValidSelection,
MeasureDistance::isPrioritizedSelection
);
"Distance",
"Measure::MeasureDistance",
MeasureDistance::isValidSelection,
MeasureDistance::isPrioritizedSelection);
App::MeasureManager::addMeasureType("DISTANCEFREE",
"Distance Free",
"Measure::MeasureDistanceDetached",
MeasureDistanceDetached::isValidSelection,
nullptr
);
"Distance Free",
"Measure::MeasureDistanceDetached",
MeasureDistanceDetached::isValidSelection,
nullptr);
App::MeasureManager::addMeasureType(
"ANGLE",
"Angle",
"Measure::MeasureAngle",
MeasureAngle::isValidSelection,
MeasureAngle::isPrioritizedSelection
);
App::MeasureManager::addMeasureType(
"LENGTH",
"Length",
"Measure::MeasureLength",
MeasureLength::isValidSelection,
nullptr
);
App::MeasureManager::addMeasureType("ANGLE",
"Angle",
"Measure::MeasureAngle",
MeasureAngle::isValidSelection,
MeasureAngle::isPrioritizedSelection);
App::MeasureManager::addMeasureType(
"POSITION",
"Position",
"Measure::MeasurePosition",
MeasurePosition::isValidSelection,
nullptr
);
App::MeasureManager::addMeasureType("LENGTH",
"Length",
"Measure::MeasureLength",
MeasureLength::isValidSelection,
nullptr);
App::MeasureManager::addMeasureType(
"AREA",
"Area",
"Measure::MeasureArea",
MeasureArea::isValidSelection,
nullptr
);
App::MeasureManager::addMeasureType(
"RADIUS",
"Radius",
"Measure::MeasureRadius",
MeasureRadius::isValidSelection,
MeasureRadius::isPrioritizedSelection
);
App::MeasureManager::addMeasureType("POSITION",
"Position",
"Measure::MeasurePosition",
MeasurePosition::isValidSelection,
nullptr);
App::MeasureManager::addMeasureType("AREA",
"Area",
"Measure::MeasureArea",
MeasureArea::isValidSelection,
nullptr);
App::MeasureManager::addMeasureType("RADIUS",
"Radius",
"Measure::MeasureRadius",
MeasureRadius::isValidSelection,
MeasureRadius::isPrioritizedSelection);
// load measure callbacks from Part module
auto lengthList = Part::MeasureClient::reportLengthCB();
for (auto& entry : lengthList) {
MeasureBaseExtendable<Part::MeasureLengthInfo>::addGeometryHandler(entry.m_module, entry.m_callback);
MeasureBaseExtendable<Part::MeasureLengthInfo>::addGeometryHandler(entry.m_module,
entry.m_callback);
}
auto angleList = Part::MeasureClient::reportAngleCB();
for (auto& entry : angleList) {
MeasureBaseExtendable<Part::MeasureAngleInfo>::addGeometryHandler(entry.m_module, entry.m_callback);
MeasureBaseExtendable<Part::MeasureAngleInfo>::addGeometryHandler(entry.m_module,
entry.m_callback);
}
auto areaList = Part::MeasureClient::reportAreaCB();
auto areaList = Part::MeasureClient::reportAreaCB();
for (auto& entry : areaList) {
MeasureBaseExtendable<Part::MeasureAreaInfo>::addGeometryHandler(entry.m_module, entry.m_callback);
MeasureBaseExtendable<Part::MeasureAreaInfo>::addGeometryHandler(entry.m_module,
entry.m_callback);
}
auto distanceList = Part::MeasureClient::reportDistanceCB();
for (auto& entry : distanceList) {
MeasureBaseExtendable<Part::MeasureDistanceInfo>::addGeometryHandler(entry.m_module, entry.m_callback);
MeasureBaseExtendable<Part::MeasureDistanceInfo>::addGeometryHandler(entry.m_module,
entry.m_callback);
}
auto positionList = Part::MeasureClient::reportPositionCB();
for (auto& entry : positionList) {
MeasureBaseExtendable<Part::MeasurePositionInfo>::addGeometryHandler(entry.m_module, entry.m_callback);
MeasureBaseExtendable<Part::MeasurePositionInfo>::addGeometryHandler(entry.m_module,
entry.m_callback);
}
auto radiusList = Part::MeasureClient::reportRadiusCB();
for (auto& entry : radiusList) {
MeasureBaseExtendable<Part::MeasureRadiusInfo>::addGeometryHandler(entry.m_module, entry.m_callback);
for (auto& entry : radiusList) {
MeasureBaseExtendable<Part::MeasureRadiusInfo>::addGeometryHandler(entry.m_module,
entry.m_callback);
}
@@ -191,7 +187,7 @@ PyMOD_INIT_FUNC(Measure)
PyMOD_Return(mod);
}
// debug print for sketchsolv
// debug print for sketchsolv
void debugprint(const std::string& text)
{
Base::Console().Log("%s", text.c_str());

View File

@@ -38,16 +38,27 @@ PROPERTY_SOURCE(Measure::MeasureAngle, Measure::MeasureBase)
MeasureAngle::MeasureAngle()
{
ADD_PROPERTY_TYPE(Element1,(nullptr), "Measurement", App::Prop_None, "First element of the measurement");
ADD_PROPERTY_TYPE(Element1,
(nullptr),
"Measurement",
App::Prop_None,
"First element of the measurement");
Element1.setScope(App::LinkScope::Global);
Element1.setAllowExternal(true);
ADD_PROPERTY_TYPE(Element2,(nullptr), "Measurement", App::Prop_None, "Second element of the measurement");
ADD_PROPERTY_TYPE(Element2,
(nullptr),
"Measurement",
App::Prop_None,
"Second element of the measurement");
Element2.setScope(App::LinkScope::Global);
Element2.setAllowExternal(true);
ADD_PROPERTY_TYPE(Angle,(0.0) ,"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Angle between the two elements");
ADD_PROPERTY_TYPE(Angle,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Angle between the two elements");
Angle.setUnit(Base::Unit::Angle);
}
@@ -67,9 +78,8 @@ bool MeasureAngle::isValidSelection(const App::MeasureSelection& selection)
return false;
}
if (!(type == App::MeasureElementType::LINE ||
type == App::MeasureElementType::PLANE ||
type == App::MeasureElementType::LINESEGMENT)) {
if (!(type == App::MeasureElementType::LINE || type == App::MeasureElementType::PLANE
|| type == App::MeasureElementType::LINESEGMENT)) {
return false;
}
}
@@ -81,7 +91,7 @@ bool MeasureAngle::isPrioritizedSelection(const App::MeasureSelection& selection
if (selection.size() != 2) {
return false;
}
// Check if the two elements are parallel
auto element1 = selection.at(0);
auto objT1 = element1.object;
@@ -97,13 +107,14 @@ bool MeasureAngle::isPrioritizedSelection(const App::MeasureSelection& selection
Base::Vector3d vec2;
getVec(*ob2, sub2, vec2);
double angle = std::fmod(vec1.GetAngle(vec2), D_PI);
return angle > Base::Precision::Angular();
}
void MeasureAngle::parseSelection(const App::MeasureSelection& selection) {
void MeasureAngle::parseSelection(const App::MeasureSelection& selection)
{
assert(selection.size() >= 2);
@@ -121,8 +132,9 @@ void MeasureAngle::parseSelection(const App::MeasureSelection& selection) {
}
bool MeasureAngle::getVec(App::DocumentObject& ob, std::string& subName, Base::Vector3d& vecOut) {
App::SubObjectT subject{&ob, subName.c_str()};
bool MeasureAngle::getVec(App::DocumentObject& ob, std::string& subName, Base::Vector3d& vecOut)
{
App::SubObjectT subject {&ob, subName.c_str()};
auto info = getMeasureInfo(subject);
if (!info || !info->valid) {
return false;
@@ -135,22 +147,23 @@ bool MeasureAngle::getVec(App::DocumentObject& ob, std::string& subName, Base::V
Base::Vector3d MeasureAngle::getLoc(App::DocumentObject& ob, std::string& subName)
{
App::SubObjectT subject{&ob, subName.c_str()};
App::SubObjectT subject {&ob, subName.c_str()};
auto info = getMeasureInfo(subject);
if (!info || !info->valid) {
return Base::Vector3d();
}
if (!info || !info->valid) {
return Base::Vector3d();
}
auto angleInfo = std::dynamic_pointer_cast<Part::MeasureAngleInfo>(info);
return angleInfo->position;
}
gp_Vec MeasureAngle::vector1() {
gp_Vec MeasureAngle::vector1()
{
App::DocumentObject* ob = Element1.getValue();
std::vector<std::string> subs = Element1.getSubValues();
if (!ob || !ob->isValid() || subs.empty() ) {
if (!ob || !ob->isValid() || subs.empty()) {
return {};
}
@@ -159,11 +172,12 @@ gp_Vec MeasureAngle::vector1() {
return gp_Vec(vec.x, vec.y, vec.z);
}
gp_Vec MeasureAngle::vector2() {
gp_Vec MeasureAngle::vector2()
{
App::DocumentObject* ob = Element2.getValue();
std::vector<std::string> subs = Element2.getSubValues();
if (!ob || !ob->isValid() || subs.empty() ) {
if (!ob || !ob->isValid() || subs.empty()) {
return gp_Vec();
}
@@ -172,22 +186,24 @@ gp_Vec MeasureAngle::vector2() {
return gp_Vec(vec.x, vec.y, vec.z);
}
gp_Vec MeasureAngle::location1() {
gp_Vec MeasureAngle::location1()
{
App::DocumentObject* ob = Element1.getValue();
std::vector<std::string> subs = Element1.getSubValues();
if (!ob || !ob->isValid() || subs.empty() ) {
if (!ob || !ob->isValid() || subs.empty()) {
return {};
}
auto temp = getLoc(*ob, subs.at(0));
return {temp.x, temp.y, temp.z};
}
gp_Vec MeasureAngle::location2() {
gp_Vec MeasureAngle::location2()
{
App::DocumentObject* ob = Element2.getValue();
std::vector<std::string> subs = Element2.getSubValues();
if (!ob || !ob->isValid() || subs.empty() ) {
if (!ob || !ob->isValid() || subs.empty()) {
return {};
}
@@ -195,7 +211,7 @@ gp_Vec MeasureAngle::location2() {
return {temp.x, temp.y, temp.z};
}
App::DocumentObjectExecReturn *MeasureAngle::execute()
App::DocumentObjectExecReturn* MeasureAngle::execute()
{
App::DocumentObject* ob1 = Element1.getValue();
std::vector<std::string> subs1 = Element1.getSubValues();
@@ -227,7 +243,7 @@ void MeasureAngle::onChanged(const App::Property* prop)
if (prop == &Element1 || prop == &Element2) {
if (!isRestoring()) {
App::DocumentObjectExecReturn *ret = recompute();
App::DocumentObjectExecReturn* ret = recompute();
delete ret;
}
}
@@ -240,4 +256,3 @@ std::vector<App::DocumentObject*> MeasureAngle::getSubject() const
{
return {Element1.getValue()};
}

View File

@@ -41,7 +41,7 @@ namespace Measure
{
class MeasureExport MeasureAngle : public Measure::MeasureBaseExtendable<Part::MeasureAngleInfo>
class MeasureExport MeasureAngle: public Measure::MeasureBaseExtendable<Part::MeasureAngleInfo>
{
PROPERTY_HEADER_WITH_OVERRIDE(Measure::MeasureAngle);
@@ -54,9 +54,10 @@ public:
App::PropertyLinkSub Element2;
App::PropertyAngle Angle;
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
const char* getViewProviderName() const override {
const char* getViewProviderName() const override
{
return "MeasureGui::ViewProviderMeasureAngle";
}
@@ -64,10 +65,16 @@ public:
static bool isPrioritizedSelection(const App::MeasureSelection& selection);
void parseSelection(const App::MeasureSelection& selection) override;
std::vector<std::string> getInputProps() override {return {"Element1", "Element2"};}
App::Property* getResultProp() override {return &this->Angle;}
std::vector<std::string> getInputProps() override
{
return {"Element1", "Element2"};
}
App::Property* getResultProp() override
{
return &this->Angle;
}
// Return the object we are measuring
// Return the object we are measuring
std::vector<App::DocumentObject*> getSubject() const override;
@@ -81,13 +88,12 @@ public:
// Location Vectors
gp_Vec location1();
gp_Vec location2();
private:
private:
void onChanged(const App::Property* prop) override;
};
} //namespace Measure
} // namespace Measure
#endif // APP_MEASUREANGLE_H
#endif // APP_MEASUREANGLE_H

View File

@@ -34,22 +34,28 @@ using namespace Measure;
PROPERTY_SOURCE(Measure::MeasureArea, Measure::MeasureBase)
MeasureArea::MeasureArea()
{
ADD_PROPERTY_TYPE(Elements,(nullptr), "Measurement", App::Prop_None, "Element to get the area from");
ADD_PROPERTY_TYPE(Elements,
(nullptr),
"Measurement",
App::Prop_None,
"Element to get the area from");
Elements.setScope(App::LinkScope::Global);
Elements.setAllowExternal(true);
ADD_PROPERTY_TYPE(Area,(0.0), "Measurement", App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Area of element");
ADD_PROPERTY_TYPE(Area,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Area of element");
}
MeasureArea::~MeasureArea() = default;
bool MeasureArea::isValidSelection(const App::MeasureSelection& selection){
bool MeasureArea::isValidSelection(const App::MeasureSelection& selection)
{
if (selection.empty()) {
return false;
@@ -70,7 +76,8 @@ bool MeasureArea::isValidSelection(const App::MeasureSelection& selection){
return true;
}
void MeasureArea::parseSelection(const App::MeasureSelection& selection) {
void MeasureArea::parseSelection(const App::MeasureSelection& selection)
{
// Set properties from selection, method is only invoked when isValid Selection returns true
std::vector<App::DocumentObject*> objects;
@@ -87,7 +94,7 @@ void MeasureArea::parseSelection(const App::MeasureSelection& selection) {
}
App::DocumentObjectExecReturn *MeasureArea::execute()
App::DocumentObjectExecReturn* MeasureArea::execute()
{
recalculateArea();
return DocumentObject::StdReturn;
@@ -101,8 +108,8 @@ void MeasureArea::recalculateArea()
double result(0.0);
// Loop through Elements and call the valid geometry handler
for (std::vector<App::DocumentObject*>::size_type i=0; i<objects.size(); i++) {
App::SubObjectT subject{objects.at(i), subElements.at(i).c_str()};
for (std::vector<App::DocumentObject*>::size_type i = 0; i < objects.size(); i++) {
App::SubObjectT subject {objects.at(i), subElements.at(i).c_str()};
auto info = getMeasureInfo(subject);
if (!info || !info->valid) {
@@ -129,7 +136,8 @@ void MeasureArea::onChanged(const App::Property* prop)
}
Base::Placement MeasureArea::getPlacement() {
Base::Placement MeasureArea::getPlacement()
{
const std::vector<App::DocumentObject*>& objects = Elements.getValues();
const std::vector<std::string>& subElements = Elements.getSubValues();
@@ -137,7 +145,7 @@ Base::Placement MeasureArea::getPlacement() {
return Base::Placement();
}
App::SubObjectT subject{objects.front(), subElements.front().c_str()};
App::SubObjectT subject {objects.front(), subElements.front().c_str()};
auto info = getMeasureInfo(subject);
if (!info) {

View File

@@ -40,9 +40,7 @@ namespace Measure
{
class MeasureExport MeasureArea : public Measure::MeasureBaseExtendable<Part::MeasureAreaInfo>
class MeasureExport MeasureArea: public Measure::MeasureBaseExtendable<Part::MeasureAreaInfo>
{
PROPERTY_HEADER_WITH_OVERRIDE(Measure::MeasureArea);
@@ -54,18 +52,25 @@ public:
App::PropertyLinkSubList Elements;
App::PropertyArea Area;
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
void recalculateArea();
const char* getViewProviderName() const override {
const char* getViewProviderName() const override
{
return "MeasureGui::ViewProviderMeasureArea";
}
static bool isValidSelection(const App::MeasureSelection& selection);
void parseSelection(const App::MeasureSelection& selection) override;
std::vector<std::string> getInputProps() override {return {"Elements"};}
App::Property* getResultProp() override {return &this->Area;}
std::vector<std::string> getInputProps() override
{
return {"Elements"};
}
App::Property* getResultProp() override
{
return &this->Area;
}
// Return a placement for the viewprovider, just use the first element for now
Base::Placement getPlacement() override;
@@ -76,11 +81,9 @@ public:
private:
void onChanged(const App::Property* prop) override;
};
} //namespace Measure
} // namespace Measure
#endif // MEASURE_MEASUREAREA_H
#endif // MEASURE_MEASUREAREA_H

View File

@@ -35,13 +35,18 @@ using namespace Measure;
PROPERTY_SOURCE(Measure::MeasureBase, App::DocumentObject)
MeasureBase::MeasureBase() {
ADD_PROPERTY_TYPE(Placement, (Base::Placement()), nullptr, App::PropertyType(App::Prop_ReadOnly|App::Prop_Output|App::Prop_NoRecompute), "Visual placement of the measurement");
MeasureBase::MeasureBase()
{
ADD_PROPERTY_TYPE(
Placement,
(Base::Placement()),
nullptr,
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output | App::Prop_NoRecompute),
"Visual placement of the measurement");
}
PyObject *MeasureBase::getPyObject(void)
PyObject* MeasureBase::getPyObject(void)
{
if (PythonObject.is(Py::_None())) {
// ref counter is set to 1
@@ -50,7 +55,8 @@ PyObject *MeasureBase::getPyObject(void)
return Py::new_reference_to(PythonObject);
}
Py::Object MeasureBase::getProxyObject() const {
Py::Object MeasureBase::getProxyObject() const
{
Base::PyGILStateLocker lock;
App::Property* prop = this->getPropertyByName("Proxy");
if (!prop) {
@@ -59,7 +65,8 @@ Py::Object MeasureBase::getProxyObject() const {
return dynamic_cast<App::PropertyPythonObject*>(prop)->getValue();
};
std::vector<App::DocumentObject*> MeasureBase::getSubject() const {
std::vector<App::DocumentObject*> MeasureBase::getSubject() const
{
Base::PyGILStateLocker lock;
Py::Object proxy = getProxyObject();
@@ -67,11 +74,12 @@ std::vector<App::DocumentObject*> MeasureBase::getSubject() const {
// Pass the feature object to the proxy
Py::Tuple args(1);
args.setItem(0, Py::Object(const_cast<MeasureBase*>(this)->getPyObject()));
Py::Object ret;
try {
ret = proxy.callMemberFunction("getSubject", args);
} catch (Py::Exception&) {
}
catch (Py::Exception&) {
Base::PyException e;
e.ReportException();
return {};
@@ -84,14 +92,13 @@ std::vector<App::DocumentObject*> MeasureBase::getSubject() const {
}
return retVec;
};
};
void MeasureBase::parseSelection(const App::MeasureSelection& selection) {
void MeasureBase::parseSelection(const App::MeasureSelection& selection)
{
Base::PyGILStateLocker lock;
Py::Object proxy = getProxyObject();
// Convert selection to python list
@@ -106,15 +113,16 @@ void MeasureBase::parseSelection(const App::MeasureSelection& selection) {
// Call the parseSelection method of the proxy object
try {
proxy.callMemberFunction("parseSelection", args);
} catch (Py::Exception&) {
}
catch (Py::Exception&) {
Base::PyException e;
e.ReportException();
}
}
std::vector<std::string> MeasureBase::getInputProps() {
std::vector<std::string> MeasureBase::getInputProps()
{
Base::PyGILStateLocker lock;
Py::Object proxy = getProxyObject();
@@ -125,7 +133,8 @@ std::vector<std::string> MeasureBase::getInputProps() {
Py::Object ret;
try {
ret = proxy.callMemberFunction("getInputProps");
} catch (Py::Exception&) {
}
catch (Py::Exception&) {
Base::PyException e;
e.ReportException();
return {};
@@ -142,11 +151,11 @@ std::vector<std::string> MeasureBase::getInputProps() {
}
QString MeasureBase::getResultString() {
QString MeasureBase::getResultString()
{
Py::Object proxy = getProxyObject();
Base::PyGILStateLocker lock;
if (!proxy.isNone()) {
// Pass the feature object to the proxy
@@ -156,7 +165,8 @@ QString MeasureBase::getResultString() {
Py::Object ret;
try {
ret = proxy.callMemberFunction("getResultString", args);
} catch (Py::Exception&) {
}
catch (Py::Exception&) {
Base::PyException e;
e.ReportException();
return QString();
@@ -165,9 +175,9 @@ QString MeasureBase::getResultString() {
}
App::Property* prop = getResultProp();
if (prop == nullptr) {
return QString();
}
if (prop == nullptr) {
return QString();
}
if (prop->isDerivedFrom(App::PropertyQuantity::getClassTypeId())) {
return static_cast<App::PropertyQuantity*>(prop)->getQuantityValue().getUserString();
@@ -177,28 +187,35 @@ QString MeasureBase::getResultString() {
return QString();
}
void MeasureBase::onDocumentRestored() {
void MeasureBase::onDocumentRestored()
{
// Force recompute the measurement
recompute();
}
Base::Placement MeasureBase::getPlacement() {
Base::Placement MeasureBase::getPlacement()
{
return this->Placement.getValue();
}
// Python Drawing feature ---------------------------------------------------------
namespace App {
namespace App
{
/// @cond DOXERR
PROPERTY_SOURCE_TEMPLATE(Measure::MeasurePython, Measure::MeasureBase)
template<> const char* Measure::MeasurePython::getViewProviderName(void) const {
template<>
const char* Measure::MeasurePython::getViewProviderName(void) const
{
return "MeasureGui::ViewProviderMeasure";
}
template<> PyObject* Measure::MeasurePython::getPyObject() {
template<>
PyObject* Measure::MeasurePython::getPyObject()
{
if (PythonObject.is(Py::_None())) {
// ref counter is set to 1
PythonObject = Py::Object(new FeaturePythonPyT<Measure::MeasureBasePy>(this),true);
PythonObject = Py::Object(new FeaturePythonPyT<Measure::MeasureBasePy>(this), true);
}
return Py::new_reference_to(PythonObject);
}
@@ -206,6 +223,4 @@ template<> PyObject* Measure::MeasurePython::getPyObject() {
// explicit template instantiation
template class MeasureExport FeaturePythonT<Measure::MeasureBase>;
}
} // namespace App

View File

@@ -46,7 +46,7 @@
namespace Measure
{
class MeasureExport MeasureBase : public App::DocumentObject
class MeasureExport MeasureBase: public App::DocumentObject
{
PROPERTY_HEADER_WITH_OVERRIDE(Measure::MeasureBase);
@@ -58,8 +58,8 @@ public:
// boost::signals2::signal<void (const MeasureBase*)> signalGuiInit;
//return PyObject as MeasureBasePy
PyObject *getPyObject() override;
// return PyObject as MeasureBasePy
PyObject* getPyObject() override;
// Initialize measurement properties from selection
virtual void parseSelection(const App::MeasureSelection& selection);
@@ -68,7 +68,10 @@ public:
virtual QString getResultString();
virtual std::vector<std::string> getInputProps();
virtual App::Property* getResultProp() {return {};}
virtual App::Property* getResultProp()
{
return {};
}
virtual Base::Placement getPlacement();
// Return the objects that are measured
@@ -84,21 +87,22 @@ protected:
// Create a scriptable object based on MeasureBase
using MeasurePython = App::FeaturePythonT<MeasureBase>;
template <typename T>
class MeasureExport MeasureBaseExtendable : public MeasureBase
template<typename T>
class MeasureExport MeasureBaseExtendable: public MeasureBase
{
using GeometryHandler = std::function<Part::MeasureInfoPtr (const App::SubObjectT&)>;
using GeometryHandler = std::function<Part::MeasureInfoPtr(const App::SubObjectT&)>;
using HandlerMap = std::map<std::string, GeometryHandler>;
public:
static void addGeometryHandler(const std::string& module, GeometryHandler callback) {
public:
static void addGeometryHandler(const std::string& module, GeometryHandler callback)
{
_mGeometryHandlers[module] = callback;
}
static GeometryHandler getGeometryHandler(const std::string& module) {
static GeometryHandler getGeometryHandler(const std::string& module)
{
if (!hasGeometryHandler(module)) {
return {};
@@ -107,7 +111,8 @@ public:
return _mGeometryHandlers[module];
}
static Part::MeasureInfoPtr getMeasureInfo(App::SubObjectT& subObjT) {
static Part::MeasureInfoPtr getMeasureInfo(App::SubObjectT& subObjT)
{
// Resolve App::Link
App::DocumentObject* sub = subObjT.getSubObject();
@@ -119,26 +124,30 @@ public:
// Get the Geometry handler based on the module
const char* className = sub->getTypeId().getName();
std::string mod = Base::Type::getModuleName(className);
auto handler = getGeometryHandler(mod);
if (!handler) {
Base::Console().Log("MeasureBaseExtendable::getMeasureInfo: No geometry handler available for submitted element type");
Base::Console().Log("MeasureBaseExtendable::getMeasureInfo: No geometry handler "
"available for submitted element type");
return nullptr;
}
return handler(subObjT);
}
static void addGeometryHandlers(const std::vector<std::string>& modules, GeometryHandler callback){
// TODO: this will replace a callback with a later one. Should we check that there isn't already a
// handler defined for this module?
static void addGeometryHandlers(const std::vector<std::string>& modules,
GeometryHandler callback)
{
// TODO: this will replace a callback with a later one. Should we check that there isn't
// already a handler defined for this module?
for (auto& mod : modules) {
_mGeometryHandlers[mod] = callback;
}
}
static bool hasGeometryHandler(const std::string& module) {
static bool hasGeometryHandler(const std::string& module)
{
return (_mGeometryHandlers.count(module) > 0);
}
@@ -147,8 +156,7 @@ private:
};
} //namespace Measure
} // namespace Measure
#endif // MEASURE_MEASUREBASE_H
#endif // MEASURE_MEASUREBASE_H

View File

@@ -16,7 +16,7 @@ std::string MeasureBasePy::representation() const
return "<Measure::MeasureBase>";
}
PyObject *MeasureBasePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
PyObject* MeasureBasePy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
{
// create a new instance of MeasureBasePy and the Twin object
return new MeasureBasePy(new MeasureBase);
@@ -26,10 +26,10 @@ PyObject *MeasureBasePy::PyMake(struct _typeobject *, PyObject *, PyObject *) /
// constructor method
int MeasureBasePy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
{
return 0;
return 0;
}
PyObject *MeasureBasePy::getCustomAttributes(const char* /*attr*/) const
PyObject* MeasureBasePy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;
}

View File

@@ -39,37 +39,65 @@ PROPERTY_SOURCE(Measure::MeasureDistance, Measure::MeasureBase)
MeasureDistance::MeasureDistance()
{
ADD_PROPERTY_TYPE(Element1,(nullptr), "Measurement", App::Prop_None, "First element of the measurement");
ADD_PROPERTY_TYPE(Element1,
(nullptr),
"Measurement",
App::Prop_None,
"First element of the measurement");
Element1.setScope(App::LinkScope::Global);
Element1.setAllowExternal(true);
ADD_PROPERTY_TYPE(Element2,(nullptr), "Measurement", App::Prop_None, "Second element of the measurement");
ADD_PROPERTY_TYPE(Element2,
(nullptr),
"Measurement",
App::Prop_None,
"Second element of the measurement");
Element2.setScope(App::LinkScope::Global);
Element2.setAllowExternal(true);
ADD_PROPERTY_TYPE(Distance,(0.0) ,"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Distance between the two elements");
ADD_PROPERTY_TYPE(Distance,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Distance between the two elements");
Distance.setUnit(Base::Unit::Length);
ADD_PROPERTY_TYPE(DistanceX,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Distance in X direction");
ADD_PROPERTY_TYPE(DistanceX,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Distance in X direction");
DistanceX.setUnit(Base::Unit::Length);
ADD_PROPERTY_TYPE(DistanceY,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Distance in Y direction");
ADD_PROPERTY_TYPE(DistanceY,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Distance in Y direction");
DistanceY.setUnit(Base::Unit::Length);
ADD_PROPERTY_TYPE(DistanceZ,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Distance in Z direction");
ADD_PROPERTY_TYPE(DistanceZ,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Distance in Z direction");
DistanceZ.setUnit(Base::Unit::Length);
ADD_PROPERTY_TYPE(Position1,(Base::Vector3d(0.0,0.0,0.0)),"Measurement", App::Prop_Hidden, "Position1");
ADD_PROPERTY_TYPE(Position2,(Base::Vector3d(0.0,1.0,0.0)),"Measurement", App::Prop_Hidden, "Position2");
ADD_PROPERTY_TYPE(Position1,
(Base::Vector3d(0.0, 0.0, 0.0)),
"Measurement",
App::Prop_Hidden,
"Position1");
ADD_PROPERTY_TYPE(Position2,
(Base::Vector3d(0.0, 1.0, 0.0)),
"Measurement",
App::Prop_Hidden,
"Position2");
}
MeasureDistance::~MeasureDistance() = default;
bool MeasureDistance::isValidSelection(const App::MeasureSelection& selection){
bool MeasureDistance::isValidSelection(const App::MeasureSelection& selection)
{
if (selection.size() != 2) {
return false;
@@ -82,23 +110,19 @@ bool MeasureDistance::isValidSelection(const App::MeasureSelection& selection){
return false;
}
if (
type != App::MeasureElementType::POINT &&
type != App::MeasureElementType::LINE &&
type != App::MeasureElementType::LINESEGMENT &&
type != App::MeasureElementType::CIRCLE &&
type != App::MeasureElementType::ARC &&
type != App::MeasureElementType::CURVE &&
type != App::MeasureElementType::PLANE &&
type != App::MeasureElementType::CYLINDER
) {
if (type != App::MeasureElementType::POINT && type != App::MeasureElementType::LINE
&& type != App::MeasureElementType::LINESEGMENT
&& type != App::MeasureElementType::CIRCLE && type != App::MeasureElementType::ARC
&& type != App::MeasureElementType::CURVE && type != App::MeasureElementType::PLANE
&& type != App::MeasureElementType::CYLINDER) {
return false;
}
}
return true;
}
bool MeasureDistance::isPrioritizedSelection(const App::MeasureSelection& selection) {
bool MeasureDistance::isPrioritizedSelection(const App::MeasureSelection& selection)
{
(void)selection;
@@ -111,7 +135,8 @@ bool MeasureDistance::isPrioritizedSelection(const App::MeasureSelection& select
}
void MeasureDistance::parseSelection(const App::MeasureSelection& selection) {
void MeasureDistance::parseSelection(const App::MeasureSelection& selection)
{
assert(selection.size() >= 2);
@@ -129,17 +154,18 @@ void MeasureDistance::parseSelection(const App::MeasureSelection& selection) {
}
bool MeasureDistance::getShape(App::PropertyLinkSub* prop, TopoDS_Shape& rShape) {
bool MeasureDistance::getShape(App::PropertyLinkSub* prop, TopoDS_Shape& rShape)
{
App::DocumentObject* ob = prop->getValue();
std::vector<std::string> subs = prop->getSubValues();
if (!ob || !ob->isValid() || subs.empty() ) {
if (!ob || !ob->isValid() || subs.empty()) {
return false;
}
std::string subName = subs.at(0);
App::SubObjectT subject{ob, subName.c_str()};
App::SubObjectT subject {ob, subName.c_str()};
auto info = getMeasureInfo(subject);
@@ -153,7 +179,7 @@ bool MeasureDistance::getShape(App::PropertyLinkSub* prop, TopoDS_Shape& rShape)
}
App::DocumentObjectExecReturn *MeasureDistance::execute()
App::DocumentObjectExecReturn* MeasureDistance::execute()
{
App::DocumentObject* ob1 = Element1.getValue();
@@ -207,7 +233,7 @@ void MeasureDistance::onChanged(const App::Property* prop)
if (prop == &Element1 || prop == &Element2) {
if (!isRestoring()) {
App::DocumentObjectExecReturn *ret = recompute();
App::DocumentObjectExecReturn* ret = recompute();
delete ret;
}
}
@@ -223,37 +249,58 @@ std::vector<App::DocumentObject*> MeasureDistance::getSubject() const
}
PROPERTY_SOURCE(Measure::MeasureDistanceDetached, Measure::MeasureBase)
MeasureDistanceDetached::MeasureDistanceDetached()
{
ADD_PROPERTY_TYPE(Distance,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Distance between the two elements");
ADD_PROPERTY_TYPE(Distance,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Distance between the two elements");
Distance.setUnit(Base::Unit::Length);
ADD_PROPERTY_TYPE(DistanceX,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Distance in X direction");
ADD_PROPERTY_TYPE(DistanceX,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Distance in X direction");
DistanceX.setUnit(Base::Unit::Length);
ADD_PROPERTY_TYPE(DistanceY,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Distance in Y direction");
ADD_PROPERTY_TYPE(DistanceY,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Distance in Y direction");
DistanceY.setUnit(Base::Unit::Length);
ADD_PROPERTY_TYPE(DistanceZ,(0.0),"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Distance in Z direction");
ADD_PROPERTY_TYPE(DistanceZ,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Distance in Z direction");
DistanceZ.setUnit(Base::Unit::Length);
ADD_PROPERTY_TYPE(Position1,(Base::Vector3d(0.0,0.0,0.0)),"Measurement", App::Prop_None, "Position1");
ADD_PROPERTY_TYPE(Position2,(Base::Vector3d(0.0,1.0,0.0)),"Measurement", App::Prop_None, "Position2");
ADD_PROPERTY_TYPE(Position1,
(Base::Vector3d(0.0, 0.0, 0.0)),
"Measurement",
App::Prop_None,
"Position1");
ADD_PROPERTY_TYPE(Position2,
(Base::Vector3d(0.0, 1.0, 0.0)),
"Measurement",
App::Prop_None,
"Position2");
}
MeasureDistanceDetached::~MeasureDistanceDetached() = default;
bool MeasureDistanceDetached::isValidSelection(const App::MeasureSelection& selection){
bool MeasureDistanceDetached::isValidSelection(const App::MeasureSelection& selection)
{
return selection.size() == 2;
}
void MeasureDistanceDetached::parseSelection(const App::MeasureSelection& selection) {
void MeasureDistanceDetached::parseSelection(const App::MeasureSelection& selection)
{
auto sel1 = selection.at(0);
auto sel2 = selection.at(1);
@@ -262,7 +309,7 @@ void MeasureDistanceDetached::parseSelection(const App::MeasureSelection& select
}
App::DocumentObjectExecReturn *MeasureDistanceDetached::execute()
App::DocumentObjectExecReturn* MeasureDistanceDetached::execute()
{
recalculateDistance();
return DocumentObject::StdReturn;
@@ -297,7 +344,6 @@ std::vector<App::DocumentObject*> MeasureDistanceDetached::getSubject() const
}
Base::Type MeasureDistanceType::getClassTypeId()
{
return Base::Type::badType();
@@ -324,11 +370,10 @@ void* MeasureDistanceType::create()
Base::Type MeasureDistanceType::classTypeId = Base::Type::badType();
// Migrate old MeasureDistance Type
void MeasureDistanceDetached::handleChangedPropertyName(Base::XMLReader &reader,
const char * TypeName,
const char *PropName)
void MeasureDistanceDetached::handleChangedPropertyName(Base::XMLReader& reader,
const char* TypeName,
const char* PropName)
{
if (strcmp(PropName, "P1") == 0 && strcmp(TypeName, "App::PropertyVector") == 0) {
Position1.Restore(reader);

View File

@@ -51,7 +51,8 @@ private:
};
class MeasureExport MeasureDistance : public Measure::MeasureBaseExtendable<Part::MeasureDistanceInfo>
class MeasureExport MeasureDistance
: public Measure::MeasureBaseExtendable<Part::MeasureDistanceInfo>
{
PROPERTY_HEADER_WITH_OVERRIDE(Measure::MeasureDistance);
@@ -71,9 +72,10 @@ public:
App::PropertyVector Position1;
App::PropertyVector Position2;
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
const char* getViewProviderName() const override {
const char* getViewProviderName() const override
{
return "MeasureGui::ViewProviderMeasureDistance";
}
@@ -81,8 +83,14 @@ public:
static bool isPrioritizedSelection(const App::MeasureSelection& selection);
void parseSelection(const App::MeasureSelection& selection) override;
std::vector<std::string> getInputProps() override {return {"Element1", "Element2"};}
App::Property* getResultProp() override {return &this->Distance;}
std::vector<std::string> getInputProps() override
{
return {"Element1", "Element2"};
}
App::Property* getResultProp() override
{
return &this->Distance;
}
bool getShape(App::PropertyLinkSub* prop, TopoDS_Shape& rShape);
@@ -91,15 +99,11 @@ public:
private:
void onChanged(const App::Property* prop) override;
};
class MeasureExport MeasureDistanceDetached : public Measure::MeasureBase
class MeasureExport MeasureDistanceDetached: public Measure::MeasureBase
{
PROPERTY_HEADER_WITH_OVERRIDE(Measure::MeasureDistanceDetached);
@@ -116,33 +120,39 @@ public:
App::PropertyVector Position1;
App::PropertyVector Position2;
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
void recalculateDistance();
const char* getViewProviderName() const override {
const char* getViewProviderName() const override
{
return "MeasureGui::ViewProviderMeasureDistance";
}
static bool isValidSelection(const App::MeasureSelection& selection);
void parseSelection(const App::MeasureSelection& selection) override;
std::vector<std::string> getInputProps() override {return {"Position1", "Position2"};}
App::Property* getResultProp() override {return &this->Distance;}
std::vector<std::string> getInputProps() override
{
return {"Position1", "Position2"};
}
App::Property* getResultProp() override
{
return &this->Distance;
}
// Return the object we are measuring
std::vector<App::DocumentObject*> getSubject() const override;
void handleChangedPropertyName(Base::XMLReader &reader,
const char * TypeName,
const char *PropName) override;
void handleChangedPropertyName(Base::XMLReader& reader,
const char* TypeName,
const char* PropName) override;
private:
void onChanged(const App::Property* prop) override;
};
} //namespace Measure
} // namespace Measure
#endif // MEASUREAPP_MEASUREDISTANCE_H
#endif // MEASUREAPP_MEASUREDISTANCE_H

View File

@@ -36,22 +36,28 @@ using namespace Measure;
PROPERTY_SOURCE(Measure::MeasureLength, Measure::MeasureBase)
MeasureLength::MeasureLength()
{
ADD_PROPERTY_TYPE(Elements,(nullptr), "Measurement", App::Prop_None, "Elements to get the length from");
ADD_PROPERTY_TYPE(Elements,
(nullptr),
"Measurement",
App::Prop_None,
"Elements to get the length from");
Elements.setScope(App::LinkScope::Global);
Elements.setAllowExternal(true);
ADD_PROPERTY_TYPE(Length,(0.0) ,"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Length of selection");
ADD_PROPERTY_TYPE(Length,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Length of selection");
}
MeasureLength::~MeasureLength() = default;
bool MeasureLength::isValidSelection(const App::MeasureSelection& selection){
bool MeasureLength::isValidSelection(const App::MeasureSelection& selection)
{
if (selection.empty()) {
return false;
@@ -65,14 +71,15 @@ bool MeasureLength::isValidSelection(const App::MeasureSelection& selection){
}
if ((type != App::MeasureElementType::LINESEGMENT && type != App::MeasureElementType::CIRCLE
&& type != App::MeasureElementType::ARC && type != App::MeasureElementType::CURVE)) {
&& type != App::MeasureElementType::ARC && type != App::MeasureElementType::CURVE)) {
return false;
}
}
return true;
}
void MeasureLength::parseSelection(const App::MeasureSelection& selection) {
void MeasureLength::parseSelection(const App::MeasureSelection& selection)
{
// Set properties from selection, method is only invoked when isValid Selection returns true
std::vector<App::DocumentObject*> objects;
@@ -89,7 +96,7 @@ void MeasureLength::parseSelection(const App::MeasureSelection& selection) {
}
App::DocumentObjectExecReturn *MeasureLength::execute()
App::DocumentObjectExecReturn* MeasureLength::execute()
{
recalculateLength();
return DocumentObject::StdReturn;
@@ -103,9 +110,9 @@ void MeasureLength::recalculateLength()
double result(0.0);
// Loop through Elements and call the valid geometry handler
for (std::vector<App::DocumentObject*>::size_type i=0; i<objects.size(); i++) {
for (std::vector<App::DocumentObject*>::size_type i = 0; i < objects.size(); i++) {
App::SubObjectT subject{objects.at(i), subElements.at(i).c_str()};
App::SubObjectT subject {objects.at(i), subElements.at(i).c_str()};
auto info = getMeasureInfo(subject);
if (!info || !info->valid) {
continue;
@@ -132,7 +139,8 @@ void MeasureLength::onChanged(const App::Property* prop)
}
Base::Placement MeasureLength::getPlacement() {
Base::Placement MeasureLength::getPlacement()
{
const std::vector<App::DocumentObject*>& objects = Elements.getValues();
const std::vector<std::string>& subElements = Elements.getSubValues();
@@ -140,7 +148,7 @@ Base::Placement MeasureLength::getPlacement() {
return Base::Placement();
}
App::SubObjectT subject{objects.front(), subElements.front().c_str()};
App::SubObjectT subject {objects.front(), subElements.front().c_str()};
auto info = getMeasureInfo(subject);
if (!info || !info->valid) {
@@ -157,4 +165,3 @@ std::vector<App::DocumentObject*> MeasureLength::getSubject() const
{
return Elements.getValues();
}

View File

@@ -37,7 +37,7 @@
namespace Measure
{
class MeasureExport MeasureLength : public Measure::MeasureBaseExtendable<Part::MeasureLengthInfo>
class MeasureExport MeasureLength: public Measure::MeasureBaseExtendable<Part::MeasureLengthInfo>
{
PROPERTY_HEADER_WITH_OVERRIDE(Measure::MeasureLength);
@@ -49,18 +49,25 @@ public:
App::PropertyLinkSubList Elements;
App::PropertyDistance Length;
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
void recalculateLength();
const char* getViewProviderName() const override {
const char* getViewProviderName() const override
{
return "MeasureGui::ViewProviderMeasureLength";
}
static bool isValidSelection(const App::MeasureSelection& selection);
void parseSelection(const App::MeasureSelection& selection) override;
std::vector<std::string> getInputProps() override {return {"Elements"};}
App::Property* getResultProp() override {return &this->Length;}
std::vector<std::string> getInputProps() override
{
return {"Elements"};
}
App::Property* getResultProp() override
{
return &this->Length;
}
// Return a placement for the viewprovider, just use the first element for now
Base::Placement getPlacement() override;
@@ -71,11 +78,9 @@ public:
private:
void onChanged(const App::Property* prop) override;
};
} //namespace Measure
} // namespace Measure
#endif // MEASURE_MEASURELENGTH_H
#endif // MEASURE_MEASURELENGTH_H

View File

@@ -35,23 +35,29 @@ using namespace Measure;
PROPERTY_SOURCE(Measure::MeasurePosition, Measure::MeasureBase)
MeasurePosition::MeasurePosition()
{
ADD_PROPERTY_TYPE(Element,(nullptr), "Measurement", App::Prop_None, "Element to get the position from");
ADD_PROPERTY_TYPE(Element,
(nullptr),
"Measurement",
App::Prop_None,
"Element to get the position from");
Element.setScope(App::LinkScope::Global);
Element.setAllowExternal(true);
ADD_PROPERTY_TYPE(Position,(0.0, 0.0, 0.0), "Measurement", App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"The absolute position");
ADD_PROPERTY_TYPE(Position,
(0.0, 0.0, 0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"The absolute position");
}
MeasurePosition::~MeasurePosition() = default;
bool MeasurePosition::isValidSelection(const App::MeasureSelection& selection){
bool MeasurePosition::isValidSelection(const App::MeasureSelection& selection)
{
if (selection.empty() || selection.size() > 1) {
return false;
@@ -71,7 +77,8 @@ bool MeasurePosition::isValidSelection(const App::MeasureSelection& selection){
return true;
}
void MeasurePosition::parseSelection(const App::MeasureSelection& selection) {
void MeasurePosition::parseSelection(const App::MeasureSelection& selection)
{
// Set properties from selection, method is only invoked when isValid Selection returns true
for (auto element : selection) {
@@ -84,7 +91,7 @@ void MeasurePosition::parseSelection(const App::MeasureSelection& selection) {
}
App::DocumentObjectExecReturn *MeasurePosition::execute()
App::DocumentObjectExecReturn* MeasurePosition::execute()
{
recalculatePosition();
return DocumentObject::StdReturn;
@@ -95,9 +102,9 @@ void MeasurePosition::recalculatePosition()
const App::DocumentObject* object = Element.getValue();
const std::vector<std::string>& subElements = Element.getSubValues();
App::SubObjectT subject{object, subElements.front().c_str()};
App::SubObjectT subject {object, subElements.front().c_str()};
auto info = getMeasureInfo(subject);
if (!info || !info->valid) {
return;
}
@@ -119,7 +126,8 @@ void MeasurePosition::onChanged(const App::Property* prop)
}
QString MeasurePosition::getResultString() {
QString MeasurePosition::getResultString()
{
App::Property* prop = this->getResultProp();
if (prop == nullptr) {
return {};
@@ -129,22 +137,23 @@ QString MeasurePosition::getResultString() {
QString unit = Position.getUnit().getString();
int precision = 2;
QString text;
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QTextStream(&text)
<< "X: " << QString::number(value.x, 'f', precision) << " " << unit << endl
<< "Y: " << QString::number(value.y, 'f', precision) << " " << unit << endl
<< "Z: " << QString::number(value.z, 'f', precision) << " " << unit;
#else
QTextStream(&text)
<< "X: " << QString::number(value.x, 'f', precision) << " " << unit << Qt::endl
<< "Y: " << QString::number(value.y, 'f', precision) << " " << unit << Qt::endl
<< "Z: " << QString::number(value.z, 'f', precision) << " " << unit;
#endif
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QTextStream(&text) << "X: " << QString::number(value.x, 'f', precision) << " " << unit << endl
<< "Y: " << QString::number(value.y, 'f', precision) << " " << unit << endl
<< "Z: " << QString::number(value.z, 'f', precision) << " " << unit;
#else
QTextStream(&text) << "X: " << QString::number(value.x, 'f', precision) << " " << unit
<< Qt::endl
<< "Y: " << QString::number(value.y, 'f', precision) << " " << unit
<< Qt::endl
<< "Z: " << QString::number(value.z, 'f', precision) << " " << unit;
#endif
return text;
}
Base::Placement MeasurePosition::getPlacement() {
Base::Placement MeasurePosition::getPlacement()
{
Base::Placement placement;
placement.setPosition(Position.getValue());
return placement;

View File

@@ -40,7 +40,8 @@ namespace Measure
{
class MeasureExport MeasurePosition : public Measure::MeasureBaseExtendable<Part::MeasurePositionInfo>
class MeasureExport MeasurePosition
: public Measure::MeasureBaseExtendable<Part::MeasurePositionInfo>
{
PROPERTY_HEADER_WITH_OVERRIDE(Measure::MeasurePosition);
@@ -52,18 +53,25 @@ public:
App::PropertyLinkSub Element;
App::PropertyPosition Position;
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
void recalculatePosition();
const char* getViewProviderName() const override {
const char* getViewProviderName() const override
{
return "MeasureGui::ViewProviderMeasurePosition";
}
static bool isValidSelection(const App::MeasureSelection& selection);
void parseSelection(const App::MeasureSelection& selection) override;
std::vector<std::string> getInputProps() override {return {"Element"};}
App::Property* getResultProp() override {return &this->Position;}
std::vector<std::string> getInputProps() override
{
return {"Element"};
}
App::Property* getResultProp() override
{
return &this->Position;
}
QString getResultString() override;
Base::Placement getPlacement() override;
@@ -72,11 +80,10 @@ public:
std::vector<App::DocumentObject*> getSubject() const override;
private:
void onChanged(const App::Property* prop) override;
};
} //namespace Measure
} // namespace Measure
#endif // APP_MEASUREPOSITION_H
#endif // APP_MEASUREPOSITION_H

View File

@@ -43,16 +43,21 @@ using namespace Measure;
PROPERTY_SOURCE(Measure::MeasureRadius, Measure::MeasureBase)
MeasureRadius::MeasureRadius()
{
ADD_PROPERTY_TYPE(Element,(nullptr), "Measurement", App::Prop_None, "Element to get the radius from");
ADD_PROPERTY_TYPE(Element,
(nullptr),
"Measurement",
App::Prop_None,
"Element to get the radius from");
Element.setScope(App::LinkScope::Global);
Element.setAllowExternal(true);
ADD_PROPERTY_TYPE(Radius,(0.0) ,"Measurement",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Radius of selection");
ADD_PROPERTY_TYPE(Radius,
(0.0),
"Measurement",
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
"Radius of selection");
}
MeasureRadius::~MeasureRadius() = default;
@@ -60,7 +65,8 @@ MeasureRadius::~MeasureRadius() = default;
//! validate all the object+subelement pairs in the selection. Must be circle or arc
//! and have a geometry handler available. We only calculate radius if there is a
//! single valid item in the selection
bool MeasureRadius::isValidSelection(const App::MeasureSelection& selection){
bool MeasureRadius::isValidSelection(const App::MeasureSelection& selection)
{
if (selection.empty() || selection.size() > 1) {
// too few or too many selections
@@ -74,8 +80,7 @@ bool MeasureRadius::isValidSelection(const App::MeasureSelection& selection){
return false;
}
if (type != App::MeasureElementType::CIRCLE
&& type != App::MeasureElementType::ARC) {
if (type != App::MeasureElementType::CIRCLE && type != App::MeasureElementType::ARC) {
return false;
}
@@ -84,7 +89,8 @@ bool MeasureRadius::isValidSelection(const App::MeasureSelection& selection){
//! return true if the selection is particularly interesting to MeasureRadius.
//! In this case we claim circles and arcs.
bool MeasureRadius::isPrioritizedSelection(const App::MeasureSelection& selection) {
bool MeasureRadius::isPrioritizedSelection(const App::MeasureSelection& selection)
{
if (selection.size() != 1) {
return false;
}
@@ -92,8 +98,7 @@ bool MeasureRadius::isPrioritizedSelection(const App::MeasureSelection& selectio
auto element = selection.front();
auto type = App::MeasureManager::getMeasureElementType(element);
if (type == App::MeasureElementType::CIRCLE
|| type == App::MeasureElementType::ARC) {
if (type == App::MeasureElementType::CIRCLE || type == App::MeasureElementType::ARC) {
return true;
}
@@ -102,16 +107,17 @@ bool MeasureRadius::isPrioritizedSelection(const App::MeasureSelection& selectio
//! Set properties from first item in selection. assumes a valid selection.
void MeasureRadius::parseSelection(const App::MeasureSelection& selection) {
void MeasureRadius::parseSelection(const App::MeasureSelection& selection)
{
auto element = selection.front();
auto objT = element.object;
std::vector<std::string> subElementList { objT.getSubName() };
std::vector<std::string> subElementList {objT.getSubName()};
Element.setValue(objT.getObject(), subElementList);
}
App::DocumentObjectExecReturn *MeasureRadius::execute()
App::DocumentObjectExecReturn* MeasureRadius::execute()
{
recalculateRadius();
return DocumentObject::StdReturn;
@@ -138,7 +144,8 @@ void MeasureRadius::onChanged(const App::Property* prop)
//! return a placement (location + orientation) for the first element
Base::Placement MeasureRadius::getPlacement() {
Base::Placement MeasureRadius::getPlacement()
{
auto loc = getMeasureInfoFirst()->pointOnCurve;
auto p = Base::Placement();
p.setPosition(loc);
@@ -159,14 +166,14 @@ Part::MeasureRadiusInfoPtr MeasureRadius::getMeasureInfoFirst() const
const std::vector<std::string>& subElements = Element.getSubValues();
if (!object || subElements.empty()) {
// NOLINTNEXTLINE(modernize-return-braced-init-list)
// NOLINTNEXTLINE(modernize-return-braced-init-list)
return std::make_shared<Part::MeasureRadiusInfo>();
}
App::SubObjectT subject{object, subElements.front().c_str()};
App::SubObjectT subject {object, subElements.front().c_str()};
auto info = getMeasureInfo(subject);
if (!info || !info->valid) {
// NOLINTNEXTLINE(modernize-return-braced-init-list)
// NOLINTNEXTLINE(modernize-return-braced-init-list)
return std::make_shared<Part::MeasureRadiusInfo>();
}

View File

@@ -40,7 +40,7 @@ namespace Measure
{
class MeasureExport MeasureRadius : public Measure::MeasureBaseExtendable<Part::MeasureRadiusInfo>
class MeasureExport MeasureRadius: public Measure::MeasureBaseExtendable<Part::MeasureRadiusInfo>
{
PROPERTY_HEADER_WITH_OVERRIDE(Measure::MeasureRadius);
@@ -52,8 +52,9 @@ public:
App::PropertyLinkSub Element;
App::PropertyDistance Radius;
App::DocumentObjectExecReturn *execute() override;
const char* getViewProviderName() const override {
App::DocumentObjectExecReturn* execute() override;
const char* getViewProviderName() const override
{
return "MeasureGui::ViewProviderMeasureRadius";
}
@@ -63,8 +64,14 @@ public:
static bool isPrioritizedSelection(const App::MeasureSelection& selection);
void parseSelection(const App::MeasureSelection& selection) override;
std::vector<std::string> getInputProps() override {return {"Element"};}
App::Property* getResultProp() override {return &this->Radius;}
std::vector<std::string> getInputProps() override
{
return {"Element"};
}
App::Property* getResultProp() override
{
return &this->Radius;
}
// Return a placement for the viewprovider, just use the first element for now
Base::Placement getPlacement() override;
@@ -78,13 +85,9 @@ public:
private:
void onChanged(const App::Property* prop) override;
Part::MeasureRadiusInfoPtr getMeasureInfoFirst() const;
};
} //namespace Measure
#endif // MEASURE_MEASURERADIUS_H
} // namespace Measure
#endif // MEASURE_MEASURERADIUS_H

View File

@@ -22,21 +22,21 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRep_Tool.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <BRepExtrema_DistShapeShape.hxx>
# include <BRepGProp.hxx>
# include <GCPnts_AbscissaPoint.hxx>
# include <gp_Pln.hxx>
# include <gp_Circ.hxx>
# include <gp_Torus.hxx>
# include <gp_Cylinder.hxx>
# include <gp_Sphere.hxx>
# include <gp_Lin.hxx>
# include <GProp_GProps.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Shape.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <BRepGProp.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <gp_Pln.hxx>
#include <gp_Circ.hxx>
#include <gp_Torus.hxx>
#include <gp_Cylinder.hxx>
#include <gp_Sphere.hxx>
#include <gp_Lin.hxx>
#include <GProp_GProps.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#endif
@@ -50,7 +50,7 @@
#ifndef M_PI
# define M_PI 3.14159265358979323846
#define M_PI 3.14159265358979323846
#endif
using namespace Measure;
@@ -80,31 +80,31 @@ bool Measurement::has3DReferences()
return (References3D.getSize() > 0);
}
//add a 3D reference (obj+sub) to end of list
int Measurement::addReference3D(App::DocumentObject *obj, const std::string& subName)
// add a 3D reference (obj+sub) to end of list
int Measurement::addReference3D(App::DocumentObject* obj, const std::string& subName)
{
return addReference3D(obj,subName.c_str());
return addReference3D(obj, subName.c_str());
}
///add a 3D reference (obj+sub) to end of list
int Measurement::addReference3D(App::DocumentObject *obj, const char* subName)
/// add a 3D reference (obj+sub) to end of list
int Measurement::addReference3D(App::DocumentObject* obj, const char* subName)
{
std::vector<App::DocumentObject*> objects = References3D.getValues();
std::vector<std::string> subElements = References3D.getSubValues();
std::vector<App::DocumentObject*> objects = References3D.getValues();
std::vector<std::string> subElements = References3D.getSubValues();
objects.push_back(obj);
subElements.emplace_back(subName);
objects.push_back(obj);
subElements.emplace_back(subName);
References3D.setValues(objects, subElements);
References3D.setValues(objects, subElements);
measureType = findType();
return References3D.getSize();
measureType = findType();
return References3D.getSize();
}
MeasureType Measurement::findType()
{
const std::vector<App::DocumentObject*> &objects = References3D.getValues();
const std::vector<std::string> &subElements = References3D.getSubValues();
const std::vector<App::DocumentObject*>& objects = References3D.getValues();
const std::vector<std::string>& subElements = References3D.getSubValues();
std::vector<App::DocumentObject*>::const_iterator obj = objects.begin();
std::vector<std::string>::const_iterator subEl = subElements.begin();
@@ -123,18 +123,18 @@ MeasureType Measurement::findType()
int spheres = 0;
int vols = 0;
for (;obj != objects.end(); ++obj, ++subEl) {
for (; obj != objects.end(); ++obj, ++subEl) {
// Check if solid object
if(strcmp((*subEl).c_str(), "") == 0) {
if (strcmp((*subEl).c_str(), "") == 0) {
vols++;
}
else {
TopoDS_Shape refSubShape;
try {
refSubShape = Part::Feature::getShape(*obj,(*subEl).c_str(),true);
if(refSubShape.IsNull()){
refSubShape = Part::Feature::getShape(*obj, (*subEl).c_str(), true);
if (refSubShape.IsNull()) {
return MeasureType::Invalid;
}
}
@@ -146,13 +146,10 @@ MeasureType Measurement::findType()
}
switch (refSubShape.ShapeType()) {
case TopAbs_VERTEX:
{
case TopAbs_VERTEX: {
verts++;
}
break;
case TopAbs_EDGE:
{
} break;
case TopAbs_EDGE: {
edges++;
TopoDS_Edge edge = TopoDS::Edge(refSubShape);
BRepAdaptor_Curve sf(edge);
@@ -163,10 +160,8 @@ MeasureType Measurement::findType()
else if (sf.GetType() == GeomAbs_Circle) {
circles++;
}
}
break;
case TopAbs_FACE:
{
} break;
case TopAbs_FACE: {
faces++;
TopoDS_Face face = TopoDS::Face(refSubShape);
BRepAdaptor_Surface sf(face);
@@ -186,24 +181,23 @@ MeasureType Measurement::findType()
else if (sf.GetType() == GeomAbs_Torus) {
torus++;
}
}
break;
default:
break;
} break;
default:
break;
}
}
}
if(vols > 0) {
if(verts > 0 || edges > 0 || faces > 0) {
if (vols > 0) {
if (verts > 0 || edges > 0 || faces > 0) {
mode = MeasureType::Invalid;
}
else {
mode = MeasureType::Volumes;
}
}
else if(faces > 0) {
if(verts > 0 || edges > 0) {
else if (faces > 0) {
if (verts > 0 || edges > 0) {
if (faces == 1 && verts == 1) {
mode = MeasureType::PointToSurface;
}
@@ -240,9 +234,9 @@ MeasureType Measurement::findType()
}
}
}
else if(edges > 0) {
if(verts > 0) {
if(verts > 1 && edges > 0) {
else if (edges > 0) {
if (verts > 0) {
if (verts > 1 && edges > 0) {
mode = MeasureType::Invalid;
}
else {
@@ -287,11 +281,11 @@ MeasureType Measurement::getType()
return measureType;
}
TopoDS_Shape Measurement::getShape(App::DocumentObject *obj , const char *subName) const
TopoDS_Shape Measurement::getShape(App::DocumentObject* obj, const char* subName) const
{
//temporary fix to get "Vertex7" from "Body003.Pocket020.Vertex7"
//when selected, Body features are provided as featureName and subNameAndIndex
//other sources provide the full extended name with index
// temporary fix to get "Vertex7" from "Body003.Pocket020.Vertex7"
// when selected, Body features are provided as featureName and subNameAndIndex
// other sources provide the full extended name with index
if (strcmp(subName, "") == 0) {
return Part::Feature::getShape(obj);
}
@@ -303,12 +297,12 @@ TopoDS_Shape Measurement::getShape(App::DocumentObject *obj , const char *subNam
try {
Part::TopoShape partShape = Part::Feature::getTopoShape(obj);
App::GeoFeature* geoFeat = dynamic_cast<App::GeoFeature*>(obj);
App::GeoFeature* geoFeat = dynamic_cast<App::GeoFeature*>(obj);
if (geoFeat) {
partShape.setPlacement(geoFeat->globalPlacement());
}
TopoDS_Shape shape = partShape.getSubShape(workingSubName.c_str());
if(shape.IsNull()) {
if (shape.IsNull()) {
throw Part::NullShapeException("null shape in measurement");
}
return shape;
@@ -323,64 +317,63 @@ TopoDS_Shape Measurement::getShape(App::DocumentObject *obj , const char *subNam
catch (...) {
throw Base::RuntimeError("Measurement: Unknown error retrieving shape");
}
}
//TODO:: add lengthX, lengthY (and lengthZ??) support
// Methods for distances (edge length, two points, edge and a point
// TODO:: add lengthX, lengthY (and lengthZ??) support
// Methods for distances (edge length, two points, edge and a point
double Measurement::length() const
{
double result = 0.0;
int numRefs = References3D.getSize();
if(numRefs == 0) {
if (numRefs == 0) {
Base::Console().Error("Measurement::length - No 3D references available\n");
}
else if (measureType == MeasureType::Invalid) {
Base::Console().Error("Measurement::length - measureType is Invalid\n");
}
else {
const std::vector<App::DocumentObject*> &objects = References3D.getValues();
const std::vector<std::string> &subElements = References3D.getSubValues();
const std::vector<App::DocumentObject*>& objects = References3D.getValues();
const std::vector<std::string>& subElements = References3D.getSubValues();
if(measureType == MeasureType::Points ||
measureType == MeasureType::PointToPoint ||
measureType == MeasureType::PointToEdge ||
measureType == MeasureType::PointToSurface) {
if (measureType == MeasureType::Points || measureType == MeasureType::PointToPoint
|| measureType == MeasureType::PointToEdge
|| measureType == MeasureType::PointToSurface) {
Base::Vector3d diff = this->delta();
result = diff.Length();
}
else if(measureType == MeasureType::Edges || measureType == MeasureType::Line
|| measureType == MeasureType::TwoLines || measureType == MeasureType::Circle) {
else if (measureType == MeasureType::Edges || measureType == MeasureType::Line
|| measureType == MeasureType::TwoLines || measureType == MeasureType::Circle) {
// Iterate through edges and calculate each length
std::vector<App::DocumentObject*>::const_iterator obj = objects.begin();
std::vector<std::string>::const_iterator subEl = subElements.begin();
for (;obj != objects.end(); ++obj, ++subEl) {
//const Part::Feature *refObj = static_cast<const Part::Feature*>((*obj));
//const Part::TopoShape& refShape = refObj->Shape.getShape();
// Get the length of one edge
for (; obj != objects.end(); ++obj, ++subEl) {
// const Part::Feature *refObj = static_cast<const Part::Feature*>((*obj));
// const Part::TopoShape& refShape = refObj->Shape.getShape();
// Get the length of one edge
TopoDS_Shape shape = getShape(*obj, (*subEl).c_str());
const TopoDS_Edge& edge = TopoDS::Edge(shape);
BRepAdaptor_Curve curve(edge);
switch(curve.GetType()) {
case GeomAbs_Line : {
switch (curve.GetType()) {
case GeomAbs_Line: {
gp_Pnt P1 = curve.Value(curve.FirstParameter());
gp_Pnt P2 = curve.Value(curve.LastParameter());
gp_XYZ diff = P2.XYZ() - P1.XYZ();
result += diff.Modulus();
break;
}
case GeomAbs_Circle : {
case GeomAbs_Circle: {
double u = curve.FirstParameter();
double v = curve.LastParameter();
double radius = curve.Circle().Radius();
if (u > v) // if arc is reversed
if (u > v) { // if arc is reversed
std::swap(u, v);
}
double range = v-u;
double range = v - u;
result += radius * range;
break;
}
@@ -392,10 +385,11 @@ double Measurement::length() const
break;
}
default: {
throw Base::RuntimeError("Measurement - length - Curve type not currently handled");
throw Base::RuntimeError(
"Measurement - length - Curve type not currently handled");
}
} //end switch
} //end for
} // end switch
} // end for
}
}
return result;
@@ -403,8 +397,8 @@ double Measurement::length() const
double Measurement::lineLineDistance() const
{
// We don't use delta() because BRepExtrema_DistShapeShape return minimum length between line segment.
// Here we get the nominal distance between the infinite lines.
// We don't use delta() because BRepExtrema_DistShapeShape return minimum length between line
// segment. Here we get the nominal distance between the infinite lines.
double distance = 0.0;
if (measureType != MeasureType::TwoParallelLines || References3D.getSize() != 2) {
@@ -452,7 +446,8 @@ double Measurement::lineLineDistance() const
return distance;
}
double Measurement::planePlaneDistance() const {
double Measurement::planePlaneDistance() const
{
if (measureType != MeasureType::TwoPlanes || References3D.getSize() != 2) {
return 0.0;
}
@@ -489,45 +484,44 @@ double Measurement::planePlaneDistance() const {
return distance;
}
double Measurement::angle(const Base::Vector3d & /*param*/) const
double Measurement::angle(const Base::Vector3d& /*param*/) const
{
//TODO: do these references arrive as obj+sub pairs or as a struct of obj + [subs]?
const std::vector<App::DocumentObject*> &objects = References3D.getValues();
const std::vector<std::string> &subElements = References3D.getSubValues();
// TODO: do these references arrive as obj+sub pairs or as a struct of obj + [subs]?
const std::vector<App::DocumentObject*>& objects = References3D.getValues();
const std::vector<std::string>& subElements = References3D.getSubValues();
int numRefs = objects.size();
if(numRefs == 0) {
if (numRefs == 0) {
throw Base::RuntimeError("No references available for angle measurement");
}
else if (measureType == MeasureType::Invalid) {
throw Base::RuntimeError("MeasureType is Invalid for angle measurement");
}
else if(measureType == MeasureType::TwoLines) {
//Only case that is supported is edge to edge
//The angle between two skew lines is measured by the angle between one line (A)
//and a line (B) with the direction of the second through a point on the first line.
//Since we don't know if the directions of the lines point in the same general direction
//we could get the angle we want or the supplementary angle.
if(numRefs == 2) {
else if (measureType == MeasureType::TwoLines) {
// Only case that is supported is edge to edge
// The angle between two skew lines is measured by the angle between one line (A)
// and a line (B) with the direction of the second through a point on the first line.
// Since we don't know if the directions of the lines point in the same general direction
// we could get the angle we want or the supplementary angle.
if (numRefs == 2) {
TopoDS_Shape shape1 = getShape(objects.at(0), subElements.at(0).c_str());
TopoDS_Shape shape2 = getShape(objects.at(1), subElements.at(1).c_str());
BRepAdaptor_Curve curve1(TopoDS::Edge(shape1));
BRepAdaptor_Curve curve2(TopoDS::Edge(shape2));
if(curve1.GetType() == GeomAbs_Line &&
curve2.GetType() == GeomAbs_Line) {
if (curve1.GetType() == GeomAbs_Line && curve2.GetType() == GeomAbs_Line) {
gp_Pnt pnt1First = curve1.Value(curve1.FirstParameter());
gp_Dir dir1 = curve1.Line().Direction();
gp_Dir dir2 = curve2.Line().Direction();
gp_Dir dir2r = curve2.Line().Direction().Reversed();
gp_Lin l1 = gp_Lin(pnt1First, dir1); // (A)
gp_Lin l2 = gp_Lin(pnt1First, dir2); // (B)
gp_Lin l1 = gp_Lin(pnt1First, dir1); // (A)
gp_Lin l2 = gp_Lin(pnt1First, dir2); // (B)
gp_Lin l2r = gp_Lin(pnt1First, dir2r); // (B')
Standard_Real aRad = l1.Angle(l2);
double aRadr = l1.Angle(l2r);
return std::min(aRad, aRadr) * 180 / M_PI;
return std::min(aRad, aRadr) * 180 / M_PI;
}
else {
throw Base::RuntimeError("Measurement references must both be lines");
@@ -538,15 +532,14 @@ double Measurement::angle(const Base::Vector3d & /*param*/) const
}
}
else if (measureType == MeasureType::Points) {
//NOTE: we are calculating the 3d angle here, not the projected angle
//ASSUMPTION: the references are in end-apex-end order
if(numRefs == 3) {
// NOTE: we are calculating the 3d angle here, not the projected angle
// ASSUMPTION: the references are in end-apex-end order
if (numRefs == 3) {
TopoDS_Shape shape0 = getShape(objects.at(0), subElements.at(0).c_str());
TopoDS_Shape shape1 = getShape(objects.at(1), subElements.at(1).c_str());
TopoDS_Shape shape2 = getShape(objects.at(1), subElements.at(2).c_str());
if (shape0.ShapeType() != TopAbs_VERTEX ||
shape1.ShapeType() != TopAbs_VERTEX ||
shape2.ShapeType() != TopAbs_VERTEX) {
if (shape0.ShapeType() != TopAbs_VERTEX || shape1.ShapeType() != TopAbs_VERTEX
|| shape2.ShapeType() != TopAbs_VERTEX) {
throw Base::RuntimeError("Measurement references for 3 point angle are not Vertex");
}
gp_Pnt gEnd0 = BRep_Tool::Pnt(TopoDS::Vertex(shape0));
@@ -557,7 +550,7 @@ double Measurement::angle(const Base::Vector3d & /*param*/) const
gp_Lin line0 = gp_Lin(gEnd0, gDir0);
gp_Lin line1 = gp_Lin(gEnd1, gDir1);
double radians = line0.Angle(line1);
return radians * 180 / M_PI;
return radians * 180 / M_PI;
}
}
throw Base::RuntimeError("Unexpected error for angle measurement");
@@ -569,7 +562,7 @@ double Measurement::radius() const
const std::vector<std::string>& subElements = References3D.getSubValues();
int numRefs = References3D.getSize();
if(numRefs == 0) {
if (numRefs == 0) {
Base::Console().Error("Measurement::radius - No 3D references available\n");
}
else if (measureType == MeasureType::Circle) {
@@ -577,11 +570,12 @@ double Measurement::radius() const
const TopoDS_Edge& edge = TopoDS::Edge(shape);
BRepAdaptor_Curve curve(edge);
if(curve.GetType() == GeomAbs_Circle) {
return (double) curve.Circle().Radius();
if (curve.GetType() == GeomAbs_Circle) {
return (double)curve.Circle().Radius();
}
}
else if (measureType == MeasureType::Cylinder || measureType == MeasureType::Sphere || measureType == MeasureType::Torus) {
else if (measureType == MeasureType::Cylinder || measureType == MeasureType::Sphere
|| measureType == MeasureType::Torus) {
TopoDS_Shape shape = getShape(objects.at(0), subElements.at(0).c_str());
TopoDS_Face face = TopoDS::Face(shape);
@@ -603,7 +597,7 @@ double Measurement::radius() const
Base::Vector3d Measurement::delta() const
{
Base::Vector3d result;
int numRefs = References3D.getSize();
int numRefs = References3D.getSize();
if (numRefs == 0) {
Base::Console().Error("Measurement::delta - No 3D references available\n");
}
@@ -611,11 +605,11 @@ Base::Vector3d Measurement::delta() const
Base::Console().Error("Measurement::delta - measureType is Invalid\n");
}
else {
const std::vector<App::DocumentObject*> &objects = References3D.getValues();
const std::vector<std::string> &subElements = References3D.getSubValues();
const std::vector<App::DocumentObject*>& objects = References3D.getValues();
const std::vector<std::string>& subElements = References3D.getSubValues();
if(measureType == MeasureType::PointToPoint) {
if(numRefs == 2) {
if (measureType == MeasureType::PointToPoint) {
if (numRefs == 2) {
// Keep separate case for two points to reduce need for complex algorithm
TopoDS_Shape shape1 = getShape(objects.at(0), subElements.at(0).c_str());
TopoDS_Shape shape2 = getShape(objects.at(1), subElements.at(1).c_str());
@@ -629,17 +623,19 @@ Base::Vector3d Measurement::delta() const
return Base::Vector3d(diff.X(), diff.Y(), diff.Z());
}
}
else if(measureType == MeasureType::PointToEdge || measureType == MeasureType::PointToSurface) {
else if (measureType == MeasureType::PointToEdge
|| measureType == MeasureType::PointToSurface) {
// BrepExtema can calculate minimum distance between any set of topology sets.
if(numRefs == 2) {
if (numRefs == 2) {
TopoDS_Shape shape1 = getShape(objects.at(0), subElements.at(0).c_str());
TopoDS_Shape shape2 = getShape(objects.at(1), subElements.at(1).c_str());
BRepExtrema_DistShapeShape extrema(shape1, shape2);
if(extrema.IsDone()) {
if (extrema.IsDone()) {
// Found the nearest point between point and curve
// NOTE we will assume there is only 1 solution (cyclic topology will create multiple solutions.
// NOTE we will assume there is only 1 solution (cyclic topology will create
// multiple solutions.
gp_Pnt P1 = extrema.PointOnShape1(1);
gp_Pnt P2 = extrema.PointOnShape2(1);
gp_XYZ diff = P2.XYZ() - P1.XYZ();
@@ -647,21 +643,21 @@ Base::Vector3d Measurement::delta() const
}
}
}
else if(measureType == MeasureType::Edges) {
else if (measureType == MeasureType::Edges) {
// Only case that is supported is straight line edge
if(numRefs == 1) {
if (numRefs == 1) {
TopoDS_Shape shape = getShape(objects.at(0), subElements.at(0).c_str());
const TopoDS_Edge& edge = TopoDS::Edge(shape);
BRepAdaptor_Curve curve(edge);
if(curve.GetType() == GeomAbs_Line) {
gp_Pnt P1 = curve.Value(curve.FirstParameter());
gp_Pnt P2 = curve.Value(curve.LastParameter());
gp_XYZ diff = P2.XYZ() - P1.XYZ();
result = Base::Vector3d(diff.X(), diff.Y(), diff.Z());
if (curve.GetType() == GeomAbs_Line) {
gp_Pnt P1 = curve.Value(curve.FirstParameter());
gp_Pnt P2 = curve.Value(curve.LastParameter());
gp_XYZ diff = P2.XYZ() - P1.XYZ();
result = Base::Vector3d(diff.X(), diff.Y(), diff.Z());
}
}
else if(numRefs == 2) {
else if (numRefs == 2) {
TopoDS_Shape shape1 = getShape(objects.at(0), subElements.at(0).c_str());
TopoDS_Shape shape2 = getShape(objects.at(1), subElements.at(1).c_str());
@@ -669,13 +665,13 @@ Base::Vector3d Measurement::delta() const
BRepAdaptor_Curve curve2(TopoDS::Edge(shape2));
// Only permit line to line distance
if(curve1.GetType() == GeomAbs_Line &&
curve2.GetType() == GeomAbs_Line) {
if (curve1.GetType() == GeomAbs_Line && curve2.GetType() == GeomAbs_Line) {
BRepExtrema_DistShapeShape extrema(shape1, shape2);
if(extrema.IsDone()) {
if (extrema.IsDone()) {
// Found the nearest point between point and curve
// NOTE we will assume there is only 1 solution (cyclic topology will create multiple solutions.
// NOTE we will assume there is only 1 solution (cyclic topology will create
// multiple solutions.
gp_Pnt P1 = extrema.PointOnShape1(1);
gp_Pnt P2 = extrema.PointOnShape2(1);
gp_XYZ diff = P2.XYZ() - P1.XYZ();
@@ -720,9 +716,9 @@ double Measurement::area() const
Base::Console().Error("Measurement::area - No 3D references available\n");
}
else if (measureType == MeasureType::Volumes || measureType == MeasureType::Surfaces
|| measureType == MeasureType::Cylinder || measureType == MeasureType::Cone
|| measureType == MeasureType::Sphere || measureType == MeasureType::Torus
|| measureType == MeasureType::Plane) {
|| measureType == MeasureType::Cylinder || measureType == MeasureType::Cone
|| measureType == MeasureType::Sphere || measureType == MeasureType::Torus
|| measureType == MeasureType::Plane) {
const std::vector<App::DocumentObject*>& objects = References3D.getValues();
const std::vector<std::string>& subElements = References3D.getSubValues();
@@ -742,7 +738,7 @@ double Measurement::area() const
Base::Vector3d Measurement::massCenter() const
{
Base::Vector3d result;
int numRefs = References3D.getSize();
int numRefs = References3D.getSize();
if (numRefs == 0) {
Base::Console().Error("Measurement::massCenter - No 3D references available\n");
}
@@ -750,18 +746,18 @@ Base::Vector3d Measurement::massCenter() const
Base::Console().Error("Measurement::massCenter - measureType is Invalid\n");
}
else {
const std::vector<App::DocumentObject*> &objects = References3D.getValues();
const std::vector<std::string> &subElements = References3D.getSubValues();
const std::vector<App::DocumentObject*>& objects = References3D.getValues();
const std::vector<std::string>& subElements = References3D.getSubValues();
GProp_GProps gprops = GProp_GProps();
if(measureType == MeasureType::Volumes) {
if (measureType == MeasureType::Volumes) {
// Iterate through edges and calculate each length
std::vector<App::DocumentObject*>::const_iterator obj = objects.begin();
std::vector<std::string>::const_iterator subEl = subElements.begin();
for (;obj != objects.end(); ++obj, ++subEl) {
//const Part::Feature *refObj = static_cast<const Part::Feature*>((*obj));
//const Part::TopoShape& refShape = refObj->Shape.getShape();
for (; obj != objects.end(); ++obj, ++subEl) {
// const Part::Feature *refObj = static_cast<const Part::Feature*>((*obj));
// const Part::TopoShape& refShape = refObj->Shape.getShape();
// Compute inertia properties
@@ -771,20 +767,22 @@ Base::Vector3d Measurement::massCenter() const
// Get inertia properties
}
//double mass = gprops.Mass();
// double mass = gprops.Mass();
gp_Pnt cog = gprops.CentreOfMass();
return Base::Vector3d(cog.X(), cog.Y(), cog.Z());
}
else {
Base::Console().Error("Measurement::massCenter - measureType is not recognized\n");
// throw Base::ValueError("Measurement - massCenter - Invalid References3D Provided");
// throw Base::ValueError("Measurement - massCenter - Invalid References3D
// Provided");
}
}
return result;
}
bool Measurement::planesAreParallel() const {
bool Measurement::planesAreParallel() const
{
const std::vector<App::DocumentObject*>& objects = References3D.getValues();
const std::vector<std::string>& subElements = References3D.getSubValues();
@@ -827,7 +825,8 @@ bool Measurement::planesAreParallel() const {
return normal1.IsParallel(normal2, Precision::Angular());
}
bool Measurement::linesAreParallel() const {
bool Measurement::linesAreParallel() const
{
const std::vector<App::DocumentObject*>& objects = References3D.getValues();
const std::vector<std::string>& subElements = References3D.getSubValues();
@@ -866,11 +865,11 @@ unsigned int Measurement::getMemSize() const
return 0;
}
PyObject *Measurement::getPyObject()
PyObject* Measurement::getPyObject()
{
if (PythonObject.is(Py::_None())) {
// ref counter is set to 1
PythonObject = Py::Object(new MeasurementPy(this),true);
PythonObject = Py::Object(new MeasurementPy(this), true);
}
return Py::new_reference_to(PythonObject);
}

View File

@@ -36,32 +36,34 @@
class TopoDS_Shape;
namespace Measure
{
enum class MeasureType {
Volumes, // Measure the Volume(s)
Edges, // Measure the Edge(s)
Line, // One Line
TwoLines, // Two lines
TwoParallelLines, // Two parallel lines
Circle, // One circle
Surfaces, // Measure the surface(s)
Cylinder, // One Cylinder
Cone, // One Cone
Sphere, // One Sphere
Torus, // One Torus
Plane, // One Plane
TwoPlanes, // One Plane
Points,
PointToPoint, // Measure between TWO points
PointToEdge, // Measure between ONE point and ONE edge
PointToSurface, // Measure between ONE point and ONE surface
EdgeToEdge, // Measure between TWO edges
Invalid
};
enum class MeasureType
{
Volumes, // Measure the Volume(s)
Edges, // Measure the Edge(s)
Line, // One Line
TwoLines, // Two lines
TwoParallelLines, // Two parallel lines
Circle, // One circle
Surfaces, // Measure the surface(s)
Cylinder, // One Cylinder
Cone, // One Cone
Sphere, // One Sphere
Torus, // One Torus
Plane, // One Plane
TwoPlanes, // One Plane
Points,
PointToPoint, // Measure between TWO points
PointToEdge, // Measure between ONE point and ONE edge
PointToSurface, // Measure between ONE point and ONE surface
EdgeToEdge, // Measure between TWO edges
Invalid
};
class MeasureExport Measurement: public Base::BaseClass
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
class MeasureExport Measurement : public Base::BaseClass {
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
App::PropertyLinkSubList References3D;
public:
@@ -73,51 +75,55 @@ public:
/// Add a reference
int addReference3D(App::DocumentObject* obj, const std::string& subName);
int addReference3D(App::DocumentObject* obj, const char *subName);
int addReference3D(App::DocumentObject* obj, const char* subName);
MeasureType getType();
MeasureType findType();
// from base class
PyObject *getPyObject() override;
// from base class
PyObject* getPyObject() override;
virtual unsigned int getMemSize() const;
// Methods for distances (edge length, two points, edge and a point
double length() const;
Base::Vector3d delta() const; //when would client use delta??
double lineLineDistance() const;
double planePlaneDistance() const;
// Methods for distances (edge length, two points, edge and a point
double length() const;
Base::Vector3d delta() const; // when would client use delta??
double lineLineDistance() const;
double planePlaneDistance() const;
// Calculates the radius for an arc or circular edge
double radius() const;
// Calculates the radius for an arc or circular edge
double radius() const;
// Calculates the angle between two edges
double angle(const Base::Vector3d &param = Base::Vector3d(0,0,0)) const; //param is never used???
// Calculates the angle between two edges
double
angle(const Base::Vector3d& param = Base::Vector3d(0, 0, 0)) const; // param is never used???
// Calculate the center of mass
Base::Vector3d massCenter() const;
// Calculate the center of mass
Base::Vector3d massCenter() const;
// Calculate the volume of selected volumes
double volume() const;
// Calculate the volume of selected volumes
double volume() const;
// Calculate the area of selection
double area() const;
// Calculate the area of selection
double area() const;
static Base::Vector3d toVector3d(const gp_Pnt gp) { return Base::Vector3d(gp.X(), gp.Y(), gp.Z()); }
static Base::Vector3d toVector3d(const gp_Pnt gp)
{
return Base::Vector3d(gp.X(), gp.Y(), gp.Z());
}
bool planesAreParallel() const;
bool linesAreParallel() const;
bool planesAreParallel() const;
bool linesAreParallel() const;
protected:
TopoDS_Shape getShape(App::DocumentObject *obj , const char *subName) const;
TopoDS_Shape getShape(App::DocumentObject* obj, const char* subName) const;
private:
MeasureType measureType;
Py::SmartPtr PythonObject;
MeasureType measureType;
Py::SmartPtr PythonObject;
};
} //namespace measure
} // namespace Measure
#endif // MEASURE_MEASUREMENT_H
#endif // MEASURE_MEASUREMENT_H

View File

@@ -22,7 +22,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
#include <sstream>
#endif
#include <App/Application.h>
@@ -42,7 +42,7 @@ std::string MeasurementPy::representation() const
return "<Measure::Measurement>";
}
PyObject *MeasurementPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
PyObject* MeasurementPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
{
// create a new instance of BoundBoxPy and the Twin object
return new MeasurementPy(new Measurement);
@@ -51,18 +51,19 @@ PyObject *MeasurementPy::PyMake(struct _typeobject *, PyObject *, PyObject *) /
// constructor method
int MeasurementPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
{
return 0;
return 0;
}
PyObject* MeasurementPy::addReference3D(PyObject *args)
PyObject* MeasurementPy::addReference3D(PyObject* args)
{
char *ObjectName;
char *SubName;
if (!PyArg_ParseTuple(args, "ss:Give an object and subelement name", &ObjectName,&SubName))
char* ObjectName;
char* SubName;
if (!PyArg_ParseTuple(args, "ss:Give an object and subelement name", &ObjectName, &SubName)) {
return nullptr;
}
// get the target object for the external link
App::DocumentObject * Obj = App::GetApplication().getActiveDocument()->getObject(ObjectName);
App::DocumentObject* Obj = App::GetApplication().getActiveDocument()->getObject(ObjectName);
if (!Obj) {
std::stringstream str;
str << ObjectName << "does not exist in the document";
@@ -71,7 +72,7 @@ PyObject* MeasurementPy::addReference3D(PyObject *args)
}
// add the external
if (this->getMeasurementPtr()->addReference3D(Obj,SubName) < 0) {
if (this->getMeasurementPtr()->addReference3D(Obj, SubName) < 0) {
std::stringstream str;
str << "Not able to add reference";
PyErr_SetString(PyExc_ValueError, str.str().c_str());
@@ -81,11 +82,12 @@ PyObject* MeasurementPy::addReference3D(PyObject *args)
Py_Return;
}
PyObject* MeasurementPy::has3DReferences(PyObject *args)
PyObject* MeasurementPy::has3DReferences(PyObject* args)
{
PyObject *result=Py_False;
if (!PyArg_ParseTuple(args, ""))
PyObject* result = Py_False;
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
if (getMeasurementPtr()->has3DReferences()) {
result = Py_True;
@@ -95,30 +97,33 @@ PyObject* MeasurementPy::has3DReferences(PyObject *args)
return result;
}
PyObject* MeasurementPy::clear(PyObject *args)
PyObject* MeasurementPy::clear(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
this->getMeasurementPtr()->clear();
Py_Return;
}
PyObject* MeasurementPy::delta(PyObject *args)
PyObject* MeasurementPy::delta(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
Py::Vector delta(this->getMeasurementPtr()->delta());
return Py::new_reference_to(delta);
}
PyObject* MeasurementPy::length(PyObject *args)
PyObject* MeasurementPy::length(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
Py::Float length;
length = this->getMeasurementPtr()->length();
@@ -126,10 +131,11 @@ PyObject* MeasurementPy::length(PyObject *args)
return Py::new_reference_to(length);
}
PyObject* MeasurementPy::lineLineDistance(PyObject *args)
PyObject* MeasurementPy::lineLineDistance(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
Py::Float length;
length = this->getMeasurementPtr()->lineLineDistance();
@@ -137,10 +143,11 @@ PyObject* MeasurementPy::lineLineDistance(PyObject *args)
return Py::new_reference_to(length);
}
PyObject* MeasurementPy::planePlaneDistance(PyObject *args)
PyObject* MeasurementPy::planePlaneDistance(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
Py::Float length;
length = this->getMeasurementPtr()->planePlaneDistance();
@@ -148,10 +155,11 @@ PyObject* MeasurementPy::planePlaneDistance(PyObject *args)
return Py::new_reference_to(length);
}
PyObject* MeasurementPy::volume(PyObject *args)
PyObject* MeasurementPy::volume(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
Py::Float length;
length = this->getMeasurementPtr()->volume();
@@ -159,10 +167,11 @@ PyObject* MeasurementPy::volume(PyObject *args)
return Py::new_reference_to(length);
}
PyObject* MeasurementPy::area(PyObject *args)
PyObject* MeasurementPy::area(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
Py::Float length;
length = this->getMeasurementPtr()->area();
@@ -170,10 +179,11 @@ PyObject* MeasurementPy::area(PyObject *args)
return Py::new_reference_to(length);
}
PyObject* MeasurementPy::radius(PyObject *args)
PyObject* MeasurementPy::radius(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
Py::Float radius;
radius = this->getMeasurementPtr()->radius();
@@ -181,10 +191,11 @@ PyObject* MeasurementPy::radius(PyObject *args)
return Py::new_reference_to(radius);
}
PyObject* MeasurementPy::angle(PyObject *args)
PyObject* MeasurementPy::angle(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
Py::Float angle;
angle = this->getMeasurementPtr()->angle();
@@ -192,17 +203,18 @@ PyObject* MeasurementPy::angle(PyObject *args)
return Py::new_reference_to(angle);
}
PyObject* MeasurementPy::com(PyObject *args)
PyObject* MeasurementPy::com(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
Py::Vector com(this->getMeasurementPtr()->massCenter());
return Py::new_reference_to(com);
}
PyObject *MeasurementPy::getCustomAttributes(const char* /*attr*/) const
PyObject* MeasurementPy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;
}

View File

@@ -46,4 +46,4 @@
#endif //_PreComp_
#endif // MEASUREGUI_PRECOMPILED_H
#endif // MEASUREGUI_PRECOMPILED_H

View File

@@ -21,7 +21,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <string>
#include <string>
#endif
#include <App/Application.h>
@@ -32,35 +32,41 @@
#include "Preferences.h"
//getters for parameters used in multiple places.
//ensure this is in sync with parameter names and default values on preference pages
// getters for parameters used in multiple places.
// ensure this is in sync with parameter names and default values on preference pages
using namespace Measure;
//! Returns the Measure preference group
Base::Reference<ParameterGrp> Preferences::getPreferenceGroup(const char* Name)
{
return App::GetApplication().GetUserParameter().GetGroup("BaseApp/Preferences/Mod/Measure")->GetGroup(Name);
return App::GetApplication()
.GetUserParameter()
.GetGroup("BaseApp/Preferences/Mod/Measure")
->GetGroup(Name);
}
App::Color Preferences::defaultLineColor()
{
App::Color fcColor;
fcColor.setPackedValue(getPreferenceGroup("Appearance")->GetUnsigned("DefaultLineColor", 0x3CF00000));
fcColor.setPackedValue(
getPreferenceGroup("Appearance")->GetUnsigned("DefaultLineColor", 0x3CF00000));
return fcColor;
}
App::Color Preferences::defaultTextColor()
{
App::Color fcColor;
fcColor.setPackedValue(getPreferenceGroup("Appearance")->GetUnsigned("DefaultTextColor", 0x00000000));
fcColor.setPackedValue(
getPreferenceGroup("Appearance")->GetUnsigned("DefaultTextColor", 0x00000000));
return fcColor;
}
App::Color Preferences::defaultTextBackgroundColor()
{
App::Color fcColor;
fcColor.setPackedValue(getPreferenceGroup("Appearance")->GetUnsigned("DefaultTextBackgroundColor", 0x3CF00000));
fcColor.setPackedValue(
getPreferenceGroup("Appearance")->GetUnsigned("DefaultTextBackgroundColor", 0x3CF00000));
return fcColor;
}

View File

@@ -37,7 +37,7 @@ class Color;
namespace Measure
{
//getters for parameters used in multiple places.
// getters for parameters used in multiple places.
class MeasureExport Preferences
{
@@ -51,6 +51,5 @@ public:
};
}//end namespace Measure
} // end namespace Measure
#endif

View File

@@ -99,4 +99,3 @@ fc_copy_sources(MeasureGui "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Mea
INSTALL(TARGETS MeasureGui DESTINATION ${CMAKE_INSTALL_LIBDIR})
INSTALL(FILES ${MeasureGuiIcon_SVG} DESTINATION "${CMAKE_INSTALL_DATADIR}/Mod/Measure/Resources/icons")

View File

@@ -60,26 +60,26 @@ void StdCmdMeasure::activated(int iMsg)
Gui::Control().showDialog(task);
}
bool StdCmdMeasure::isActive() {
bool StdCmdMeasure::isActive()
{
App::Document* doc = App::GetApplication().getActiveDocument();
if (!doc || doc->countObjectsOfType(App::GeoFeature::getClassTypeId()) == 0) {
return false;
}
Gui::MDIView *view = Gui::getMainWindow()->activeWindow();
Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
Gui::View3DInventorViewer *viewer =
dynamic_cast<Gui::View3DInventor *>(view)->getViewer();
Gui::View3DInventorViewer* viewer = dynamic_cast<Gui::View3DInventor*>(view)->getViewer();
return !viewer->isEditing();
}
return false;
}
void CreateMeasureCommands() {
void CreateMeasureCommands()
{
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
auto cmd = new StdCmdMeasure();
cmd->initAction();
rcCmdMgr.addCommand(cmd);
}

View File

@@ -1,4 +1,4 @@
/**************************************************************************
/**************************************************************************
* Copyright (c) 2023 Wanderer Fan <wandererfan@gmail.com> *
* *
* This file is part of FreeCAD. *
@@ -26,9 +26,9 @@
using namespace MeasureGui;
DlgPrefsMeasureAppearanceImp::DlgPrefsMeasureAppearanceImp( QWidget* parent )
: PreferencePage( parent )
, ui(new Ui_DlgPrefsMeasureAppearanceImp)
DlgPrefsMeasureAppearanceImp::DlgPrefsMeasureAppearanceImp(QWidget* parent)
: PreferencePage(parent)
, ui(new Ui_DlgPrefsMeasureAppearanceImp)
{
ui->setupUi(this);
}
@@ -57,7 +57,7 @@ void DlgPrefsMeasureAppearanceImp::loadSettings()
/**
* Sets the strings of the subwidgets using the current language.
*/
void DlgPrefsMeasureAppearanceImp::changeEvent(QEvent *e)
void DlgPrefsMeasureAppearanceImp::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
@@ -68,4 +68,3 @@ void DlgPrefsMeasureAppearanceImp::changeEvent(QEvent *e)
}
#include <Mod/Measure/Gui/moc_DlgPrefsMeasureAppearanceImp.cpp>

View File

@@ -1,4 +1,4 @@
/**************************************************************************
/**************************************************************************
* Copyright (c) 2023 Wanderer Fan <wandererfan@gmail.com> *
* *
* This file is part of FreeCAD. *
@@ -28,28 +28,28 @@
#include <Mod/Measure/MeasureGlobal.h>
namespace MeasureGui {
namespace MeasureGui
{
class Ui_DlgPrefsMeasureAppearanceImp;
class DlgPrefsMeasureAppearanceImp : public Gui::Dialog::PreferencePage
class DlgPrefsMeasureAppearanceImp: public Gui::Dialog::PreferencePage
{
Q_OBJECT
public:
explicit DlgPrefsMeasureAppearanceImp( QWidget* parent = nullptr );
explicit DlgPrefsMeasureAppearanceImp(QWidget* parent = nullptr);
~DlgPrefsMeasureAppearanceImp() override;
protected:
void saveSettings() override;
void loadSettings() override;
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
private:
std::unique_ptr<Ui_DlgPrefsMeasureAppearanceImp> ui;
};
} // namespace MeasureGui
#endif // MeasureGui_DlgPrefsAppearanceImp_H
} // namespace MeasureGui
#endif // MeasureGui_DlgPrefsAppearanceImp_H

View File

@@ -28,17 +28,17 @@
// point at which warnings of overly long specifiers disabled (needed for VC6)
#ifdef _MSC_VER
# pragma warning( disable : 4251 )
# pragma warning( disable : 4503 )
# pragma warning( disable : 4786 ) // specifier longer then 255 chars
# pragma warning( disable : 4273 )
#pragma warning(disable : 4251)
#pragma warning(disable : 4503)
#pragma warning(disable : 4786) // specifier longer then 255 chars
#pragma warning(disable : 4273)
#endif
#ifdef FC_OS_WIN32
# ifndef NOMINMAX
# define NOMINMAX
# endif
# include <windows.h>
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#endif
#ifdef _PreComp_
@@ -64,34 +64,33 @@
// GL
// Include glext before QtAll/InventorAll
#ifdef FC_OS_WIN32
# include <GL/gl.h>
# include <GL/glext.h>
#include <GL/gl.h>
#include <GL/glext.h>
#else
# ifdef FC_OS_MACOSX
# include <OpenGL/gl.h>
# include <OpenGL/glext.h>
# else
# ifndef GL_GLEXT_PROTOTYPES
# define GL_GLEXT_PROTOTYPES 1
# endif
# include <GL/gl.h>
# include <GL/glext.h>
# endif //FC_OS_MACOSX
#endif //FC_OS_WIN32
#ifdef FC_OS_MACOSX
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#else
#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES 1
#endif
#include <GL/gl.h>
#include <GL/glext.h>
#endif // FC_OS_MACOSX
#endif // FC_OS_WIN32
// Should come after glext.h to avoid warnings
#include <Inventor/C/glue/gl.h>
// Qt Toolkit
#ifndef __QtAll__
# include <Gui/QtAll.h>
#include <Gui/QtAll.h>
#endif
// Inventor includes OpenGL
#ifndef __InventorAll__
# include <Gui/InventorAll.h>
#include <Gui/InventorAll.h>
#endif
#endif //_PreComp_
#endif //_PreComp_
#endif

View File

@@ -50,7 +50,7 @@ using namespace MeasureGui;
QuickMeasure::QuickMeasure(QObject* parent)
: QObject(parent)
, measurement{new Measure::Measurement()}
, measurement {new Measure::Measurement()}
{
selectionTimer = new QTimer(this);
pendingProcessing = false;
@@ -103,8 +103,8 @@ void QuickMeasure::tryMeasureSelection()
bool QuickMeasure::canMeasureSelection(const Gui::SelectionChanges& msg) const
{
if (msg.Type == Gui::SelectionChanges::SetPreselect ||
msg.Type == Gui::SelectionChanges::RmvPreselect) {
if (msg.Type == Gui::SelectionChanges::SetPreselect
|| msg.Type == Gui::SelectionChanges::RmvPreselect) {
return false;
}
@@ -158,7 +158,8 @@ void QuickMeasure::printResult()
else if (mtype == MeasureType::Volumes) {
Base::Quantity area(measurement->area(), Base::Unit::Area);
Base::Quantity vol(measurement->volume(), Base::Unit::Volume);
print(tr("Volume: %1, Area: %2").arg(vol.getSafeUserString()).arg(area.getSafeUserString()));
print(tr("Volume: %1, Area:
%2").arg(vol.getSafeUserString()).arg(area.getSafeUserString()));
}*/
else if (mtype == MeasureType::TwoPlanes) {
Base::Quantity dist(measurement->planePlaneDistance(), Base::Unit::Length);
@@ -168,7 +169,8 @@ void QuickMeasure::printResult()
Base::Quantity area(measurement->area(), Base::Unit::Area);
print(tr("Area: %1").arg(area.getUserString()));
}
else if (mtype == MeasureType::Cylinder || mtype == MeasureType::Sphere || mtype == MeasureType::Torus) {
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(), rad.getSafeUserString()));
@@ -184,7 +186,8 @@ void QuickMeasure::printResult()
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(), 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);

View File

@@ -32,13 +32,15 @@
class QTimer;
namespace Measure {
class Measurement;
namespace Measure
{
class Measurement;
}
namespace MeasureGui {
namespace MeasureGui
{
class QuickMeasure : public QObject, Gui::SelectionObserver
class QuickMeasure: public QObject, Gui::SelectionObserver
{
Q_OBJECT
@@ -63,6 +65,6 @@ private:
bool pendingProcessing;
};
} //namespace MeasureGui
} // namespace MeasureGui
#endif // MEASUREGUI_QUICKMEASURE_H
#endif // MEASUREGUI_QUICKMEASURE_H

View File

@@ -41,7 +41,7 @@ std::string QuickMeasurePy::representation() const
return "<MeasureGui::QuickMeasure>";
}
PyObject *QuickMeasurePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
PyObject* QuickMeasurePy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
{
// create a new instance of BoundBoxPy and the Twin object
return new QuickMeasurePy(new QuickMeasure);
@@ -50,10 +50,10 @@ PyObject *QuickMeasurePy::PyMake(struct _typeobject *, PyObject *, PyObject *)
// constructor method
int QuickMeasurePy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
{
return 0;
return 0;
}
PyObject *QuickMeasurePy::getCustomAttributes(const char* /*attr*/) const
PyObject* QuickMeasurePy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;
}

View File

@@ -23,8 +23,8 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QApplication>
# include <QKeyEvent>
#include <QApplication>
#include <QKeyEvent>
#endif
@@ -49,7 +49,10 @@ TaskMeasure::TaskMeasure()
qApp->installEventFilter(this);
this->setButtonPosition(TaskMeasure::South);
auto taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("umf-measurement"), tr("Measurement"), true, nullptr);
auto taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("umf-measurement"),
tr("Measurement"),
true,
nullptr);
// Create mode dropdown and add all registered measuretypes
modeSwitch = new QComboBox();
@@ -60,14 +63,17 @@ TaskMeasure::TaskMeasure()
}
// Connect dropdown's change signal to our onModeChange slot
connect(modeSwitch, qOverload<int>(&QComboBox::currentIndexChanged), this, &TaskMeasure::onModeChanged);
connect(modeSwitch,
qOverload<int>(&QComboBox::currentIndexChanged),
this,
&TaskMeasure::onModeChanged);
// Result widget
valueResult = new QLineEdit();
valueResult->setReadOnly(true);
// Main layout
QBoxLayout *layout = taskbox->groupLayout();
QBoxLayout* layout = taskbox->groupLayout();
QFormLayout* formLayout = new QFormLayout();
formLayout->setHorizontalSpacing(10);
@@ -87,22 +93,25 @@ TaskMeasure::TaskMeasure()
// Set selection style
Gui::Selection().setSelectionStyle(Gui::SelectionSingleton::SelectionStyle::GreedySelection);
if(!App::GetApplication().getActiveTransaction())
if (!App::GetApplication().getActiveTransaction()) {
App::GetApplication().setActiveTransaction("Add Measurement");
}
// Call invoke method delayed, otherwise the dialog might not be fully initialized
QTimer::singleShot(0, this, &TaskMeasure::invoke);
}
TaskMeasure::~TaskMeasure() {
TaskMeasure::~TaskMeasure()
{
Gui::Selection().setSelectionStyle(Gui::SelectionSingleton::SelectionStyle::NormalSelection);
detachSelection();
qApp->removeEventFilter(this);
}
void TaskMeasure::modifyStandardButtons(QDialogButtonBox* box) {
void TaskMeasure::modifyStandardButtons(QDialogButtonBox* box)
{
QPushButton* btn = box->button(QDialogButtonBox::Apply);
btn->setText(tr("Save"));
@@ -120,7 +129,8 @@ void TaskMeasure::modifyStandardButtons(QDialogButtonBox* box) {
connect(btn, &QPushButton::released, this, &TaskMeasure::reset);
}
bool canAnnotate(Measure::MeasureBase* obj) {
bool canAnnotate(Measure::MeasureBase* obj)
{
if (obj == nullptr) {
// null object, can't annotate this
return false;
@@ -135,7 +145,8 @@ bool canAnnotate(Measure::MeasureBase* obj) {
return true;
}
void TaskMeasure::enableAnnotateButton(bool state) {
void TaskMeasure::enableAnnotateButton(bool state)
{
// if the task ui is not init yet we don't have a button box.
if (!this->buttonBox) {
return;
@@ -145,16 +156,18 @@ void TaskMeasure::enableAnnotateButton(bool state) {
btn->setEnabled(state);
}
void TaskMeasure::setMeasureObject(Measure::MeasureBase* obj) {
void TaskMeasure::setMeasureObject(Measure::MeasureBase* obj)
{
_mMeasureObject = obj;
}
void TaskMeasure::update() {
App::Document *doc = App::GetApplication().getActiveDocument();
void TaskMeasure::update()
{
App::Document* doc = App::GetApplication().getActiveDocument();
// Reset selection if the selected object is not valid
for(auto sel : Gui::Selection().getSelection()) {
for (auto sel : Gui::Selection().getSelection()) {
App::DocumentObject* ob = sel.pObject;
App::DocumentObject* sub = ob->getSubObject(sel.SubName);
@@ -166,7 +179,8 @@ void TaskMeasure::update() {
std::string mod = Base::Type::getModuleName(sub->getTypeId().getName());
if (!App::MeasureManager::hasMeasureHandler(mod.c_str())) {
Base::Console().Message("No measure handler available for geometry of module: %s\n", mod);
Base::Console().Message("No measure handler available for geometry of module: %s\n",
mod);
clearSelection();
return;
}
@@ -175,7 +189,7 @@ void TaskMeasure::update() {
valueResult->setText(QString::asprintf("-"));
// Get valid measure type
App::MeasureType *measureType(nullptr);
App::MeasureType* measureType(nullptr);
std::string mode = explicitMode ? modeSwitch->currentText().toStdString() : "";
@@ -184,7 +198,7 @@ void TaskMeasure::update() {
for (auto s : Gui::Selection().getSelection(doc->getName(), ResolveMode::NoResolve)) {
App::SubObjectT sub(s.pObject, s.SubName);
App::MeasureSelectionItem item = { sub, Base::Vector3d(s.x, s.y, s.z) };
App::MeasureSelectionItem item = {sub, Base::Vector3d(s.x, s.y, s.z)};
selection.push_back(item);
}
@@ -223,10 +237,12 @@ void TaskMeasure::update() {
auto pyMeasureClass = measureType->pythonClass;
// Create a MeasurePython instance
auto featurePython = doc->addObject("Measure::MeasurePython", measureType->label.c_str());
auto featurePython =
doc->addObject("Measure::MeasurePython", measureType->label.c_str());
setMeasureObject((Measure::MeasureBase*)featurePython);
// Create an instance of the pyMeasureClass, the classe's initializer sets the object as proxy
// Create an instance of the pyMeasureClass, the classe's initializer sets the object as
// proxy
Py::Tuple args(1);
args.setItem(0, Py::asObject(featurePython->getPyObject()));
PyObject* result = PyObject_CallObject(pyMeasureClass, args.ptr());
@@ -235,8 +251,8 @@ void TaskMeasure::update() {
else {
// Create measure object
setMeasureObject(
(Measure::MeasureBase*)doc->addObject(measureType->measureObject.c_str(), measureType->label.c_str())
);
(Measure::MeasureBase*)doc->addObject(measureType->measureObject.c_str(),
measureType->label.c_str()));
}
}
@@ -254,15 +270,16 @@ void TaskMeasure::update() {
// Get result
valueResult->setText(_mMeasureObject->getResultString());
}
void TaskMeasure::close() {
void TaskMeasure::close()
{
Control().closeDialog();
}
void ensureGroup(Measure::MeasureBase* measurement) {
void ensureGroup(Measure::MeasureBase* measurement)
{
// Ensure measurement object is part of the measurements group
const char* measurementGroupName = "Measurements";
@@ -273,7 +290,10 @@ void ensureGroup(Measure::MeasureBase* measurement) {
App::Document* doc = App::GetApplication().getActiveDocument();
App::DocumentObject* obj = doc->getObject(measurementGroupName);
if (!obj || !obj->isValid()) {
obj = doc->addObject("App::DocumentObjectGroup", measurementGroupName, true, "MeasureGui::ViewProviderMeasureGroup");
obj = doc->addObject("App::DocumentObjectGroup",
measurementGroupName,
true,
"MeasureGui::ViewProviderMeasureGroup");
}
auto group = static_cast<App::DocumentObjectGroup*>(obj);
@@ -282,11 +302,13 @@ void ensureGroup(Measure::MeasureBase* measurement) {
// Runs after the dialog is created
void TaskMeasure::invoke() {
void TaskMeasure::invoke()
{
update();
}
bool TaskMeasure::apply() {
bool TaskMeasure::apply()
{
ensureGroup(_mMeasureObject);
_mMeasureObject = nullptr;
reset();
@@ -297,7 +319,8 @@ bool TaskMeasure::apply() {
return false;
}
bool TaskMeasure::reject() {
bool TaskMeasure::reject()
{
removeObject();
close();
@@ -306,7 +329,8 @@ bool TaskMeasure::reject() {
return false;
}
void TaskMeasure::reset() {
void TaskMeasure::reset()
{
// Reset tool state
this->clearSelection();
@@ -318,22 +342,25 @@ void TaskMeasure::reset() {
}
void TaskMeasure::removeObject() {
void TaskMeasure::removeObject()
{
if (_mMeasureObject == nullptr) {
return;
}
if (_mMeasureObject->isRemoving() ) {
if (_mMeasureObject->isRemoving()) {
return;
}
_mMeasureObject->getDocument()->removeObject (_mMeasureObject->getNameInDocument());
_mMeasureObject->getDocument()->removeObject(_mMeasureObject->getNameInDocument());
setMeasureObject(nullptr);
}
bool TaskMeasure::hasSelection() {
bool TaskMeasure::hasSelection()
{
return !Gui::Selection().getSelection().empty();
}
void TaskMeasure::clearSelection() {
void TaskMeasure::clearSelection()
{
Gui::Selection().clearSelection();
}
@@ -341,15 +368,17 @@ void TaskMeasure::onSelectionChanged(const Gui::SelectionChanges& msg)
{
// Skip non-relevant events
if (msg.Type != SelectionChanges::AddSelection && msg.Type != SelectionChanges::RmvSelection
&& msg.Type != SelectionChanges::SetSelection && msg.Type != SelectionChanges::ClrSelection) {
&& msg.Type != SelectionChanges::SetSelection
&& msg.Type != SelectionChanges::ClrSelection) {
return;
}
}
update();
}
bool TaskMeasure::eventFilter(QObject* obj, QEvent* event) {
bool TaskMeasure::eventFilter(QObject* obj, QEvent* event)
{
if (event->type() == QEvent::KeyPress) {
auto keyEvent = static_cast<QKeyEvent*>(event);
@@ -358,7 +387,8 @@ bool TaskMeasure::eventFilter(QObject* obj, QEvent* event) {
if (this->hasSelection()) {
this->reset();
} else {
}
else {
this->reject();
}
@@ -374,12 +404,14 @@ bool TaskMeasure::eventFilter(QObject* obj, QEvent* event) {
return TaskDialog::eventFilter(obj, event);
}
void TaskMeasure::onModeChanged(int index) {
void TaskMeasure::onModeChanged(int index)
{
explicitMode = (index != 0);
this->update();
}
void TaskMeasure::setModeSilent(App::MeasureType* mode) {
void TaskMeasure::setModeSilent(App::MeasureType* mode)
{
modeSwitch->blockSignals(true);
if (mode == nullptr) {
@@ -392,7 +424,8 @@ void TaskMeasure::setModeSilent(App::MeasureType* mode) {
}
// Get explicitly set measure type from the mode switch
App::MeasureType* TaskMeasure::getMeasureType() {
App::MeasureType* TaskMeasure::getMeasureType()
{
for (App::MeasureType* mType : App::MeasureManager::getMeasureTypes()) {
if (mType->label.c_str() == modeSwitch->currentText().toLatin1()) {
return mType;

View File

@@ -36,16 +36,19 @@
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
namespace Gui {
namespace Gui
{
class TaskMeasure : public TaskView::TaskDialog, public Gui::SelectionObserver {
class TaskMeasure: public TaskView::TaskDialog, public Gui::SelectionObserver
{
public:
TaskMeasure();
~TaskMeasure() override;
void modifyStandardButtons(QDialogButtonBox* box) override;
QDialogButtonBox::StandardButtons getStandardButtons() const override {
QDialogButtonBox::StandardButtons getStandardButtons() const override
{
return QDialogButtonBox::Apply | QDialogButtonBox::Abort | QDialogButtonBox::Reset;
}
@@ -64,10 +67,10 @@ public:
private:
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
Measure::MeasureBase *_mMeasureObject = nullptr;
Measure::MeasureBase* _mMeasureObject = nullptr;
QLineEdit* valueResult{nullptr};
QComboBox* modeSwitch{nullptr};
QLineEdit* valueResult {nullptr};
QComboBox* modeSwitch {nullptr};
void removeObject();
void onModeChanged(int index);
@@ -80,7 +83,6 @@ private:
// Stores if the mode is explicitly set by the user or implicitly through the selection
bool explicitMode = false;
};
} // namespace Gui
} // namespace Gui

View File

@@ -23,34 +23,34 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
# include <QApplication>
# include <Inventor/draggers/SoTranslate2Dragger.h>
# include <Inventor/nodes/SoAnnotation.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/nodes/SoFontStyle.h>
# include <Inventor/nodes/SoIndexedLineSet.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoText2.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/engines/SoCalculator.h>
# include <Inventor/engines/SoComposeVec3f.h>
# include <Inventor/engines/SoConcatenate.h>
# include <Inventor/engines/SoComposeMatrix.h>
# include <Inventor/engines/SoComposeRotation.h>
# include <Inventor/engines/SoComposeRotationFromTo.h>
# include <Inventor/engines/SoDecomposeRotation.h>
# include <Inventor/engines/SoTransformVec3f.h>
# include <Inventor/nodekits/SoShapeKit.h>
# include <Inventor/nodes/SoFont.h>
# include <Inventor/nodes/SoLineSet.h>
# include <Inventor/nodes/SoMatrixTransform.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoTransform.h>
# include <Inventor/nodes/SoVertexProperty.h>
# include <Inventor/nodekits/SoBaseKit.h>
#include <sstream>
#include <QApplication>
#include <Inventor/draggers/SoTranslate2Dragger.h>
#include <Inventor/nodes/SoAnnotation.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoFontStyle.h>
#include <Inventor/nodes/SoIndexedLineSet.h>
#include <Inventor/nodes/SoPickStyle.h>
#include <Inventor/nodes/SoText2.h>
#include <Inventor/nodes/SoTranslation.h>
#include <Inventor/engines/SoCalculator.h>
#include <Inventor/engines/SoComposeVec3f.h>
#include <Inventor/engines/SoConcatenate.h>
#include <Inventor/engines/SoComposeMatrix.h>
#include <Inventor/engines/SoComposeRotation.h>
#include <Inventor/engines/SoComposeRotationFromTo.h>
#include <Inventor/engines/SoDecomposeRotation.h>
#include <Inventor/engines/SoTransformVec3f.h>
#include <Inventor/nodekits/SoShapeKit.h>
#include <Inventor/nodes/SoFont.h>
#include <Inventor/nodes/SoLineSet.h>
#include <Inventor/nodes/SoMatrixTransform.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoVertexProperty.h>
#include <Inventor/nodekits/SoBaseKit.h>
#endif
#include <Precision.hxx>
@@ -59,8 +59,8 @@
#include <gp_Vec.hxx>
#include <gp_Lin.hxx>
#include <gp_Pnt.hxx>
# include <GeomAPI_ExtremaCurveCurve.hxx>
# include <GeomAPI_ProjectPointOnCurve.hxx>
#include <GeomAPI_ExtremaCurveCurve.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <App/Application.h>
#include <App/Document.h>
@@ -80,13 +80,15 @@
using namespace MeasureGui;
using namespace Measure;
gp_Lin getLine(gp_Vec& vec, gp_Vec& origin) {
gp_Lin getLine(gp_Vec& vec, gp_Vec& origin)
{
gp_Pnt tempOrigin;
tempOrigin.SetXYZ(origin.XYZ());
return gp_Lin(tempOrigin, gp_Dir(vec));
}
SbMatrix ViewProviderMeasureAngle::getMatrix() {
SbMatrix ViewProviderMeasureAngle::getMatrix()
{
// Code ported from src/Mod/Part/Gui/TaskDimension.cpp
if (pcObject == nullptr) {
@@ -95,10 +97,10 @@ SbMatrix ViewProviderMeasureAngle::getMatrix() {
Measure::MeasureAngle* measurement = static_cast<Measure::MeasureAngle*>(pcObject);
if (!measurement->Element1.getValue() || measurement->Element1.getSubValues().empty()){
if (!measurement->Element1.getValue() || measurement->Element1.getSubValues().empty()) {
return SbMatrix();
}
if (!measurement->Element2.getValue() || measurement->Element2.getSubValues().empty()){
if (!measurement->Element2.getValue() || measurement->Element2.getSubValues().empty()) {
return SbMatrix();
}
@@ -120,24 +122,24 @@ SbMatrix ViewProviderMeasureAngle::getMatrix() {
double radius;
if (vector1.IsParallel(vector2, Precision::Angular())) {
//take first point project it onto second vector.
// take first point project it onto second vector.
Handle(Geom_Curve) heapLine2 = new Geom_Line(lin2);
gp_Pnt tempPoint(loc1.XYZ());
GeomAPI_ProjectPointOnCurve projection(tempPoint, heapLine2);
if (projection.NbPoints() < 1)
{
if (projection.NbPoints() < 1) {
throw Base::RuntimeError("parallel vectors: couldn't project onto line");
}
gp_Vec newPoint2;
newPoint2.SetXYZ(projection.Point(1).XYZ());
//if points are colinear, projection doesn't work and returns the same point.
//In this case we just use the original point.
if ((newPoint2 - loc1).Magnitude() < Precision::Confusion())
// if points are colinear, projection doesn't work and returns the same point.
// In this case we just use the original point.
if ((newPoint2 - loc1).Magnitude() < Precision::Confusion()) {
newPoint2 = loc2;
}
//now get midpoint between for dim origin.
// now get midpoint between for dim origin.
gp_Vec point1 = loc1;
gp_Vec midPointProjection = newPoint2 - point1;
double distance = midPointProjection.Magnitude();
@@ -146,53 +148,65 @@ SbMatrix ViewProviderMeasureAngle::getMatrix() {
gp_Vec origin = point1 + midPointProjection;
//yaxis should be the same as vector1, but doing this to eliminate any potential slop from
//using precision::angular. If lines are colinear and we have no plane, we can't establish zAxis from crossing.
//we just the absolute axis.
// yaxis should be the same as vector1, but doing this to eliminate any potential slop from
// using precision::angular. If lines are colinear and we have no plane, we can't establish
// zAxis from crossing. we just the absolute axis.
gp_Vec xAxis = (point1 - origin).Normalized();
gp_Vec zAxis;
if (xAxis.IsParallel(vector1, Precision::Angular())) {
if (!xAxis.IsParallel(gp_Vec(0.0, 0.0, 1.0), Precision::Angular()))
zAxis = gp_Vec(0.0, 0.0, 1.0);
else
zAxis = gp_Vec(0.0, 1.0, 0.0);
if (!xAxis.IsParallel(gp_Vec(0.0, 0.0, 1.0), Precision::Angular())) {
zAxis = gp_Vec(0.0, 0.0, 1.0);
}
else {
zAxis = gp_Vec(0.0, 1.0, 0.0);
}
}
else
else {
zAxis = xAxis.Crossed(vector1).Normalized();
}
gp_Vec yAxis = zAxis.Crossed(xAxis).Normalized();
zAxis = xAxis.Crossed(yAxis).Normalized();
dimSys = SbMatrix
(
xAxis.X(), yAxis.X(), zAxis.X(), origin.X(),
xAxis.Y(), yAxis.Y(), zAxis.Y(), origin.Y(),
xAxis.Z(), yAxis.Z(), zAxis.Z(), origin.Z(),
0.0, 0.0, 0.0, 1.0
);
dimSys = SbMatrix(xAxis.X(),
yAxis.X(),
zAxis.X(),
origin.X(),
xAxis.Y(),
yAxis.Y(),
zAxis.Y(),
origin.Y(),
xAxis.Z(),
yAxis.Z(),
zAxis.Z(),
origin.Z(),
0.0,
0.0,
0.0,
1.0);
dimSys = dimSys.transpose();
radius = midPointProjection.Magnitude();
} else {
}
else {
Handle(Geom_Curve) heapLine1 = new Geom_Line(lin1);
Handle(Geom_Curve) heapLine2 = new Geom_Line(lin2);
GeomAPI_ExtremaCurveCurve extrema(heapLine1, heapLine2);
if (extrema.NbExtrema() < 1)
{
if (extrema.NbExtrema() < 1) {
throw Base::RuntimeError("couldn't get extrema");
}
gp_Pnt extremaPoint1, extremaPoint2, dimensionOriginPoint;
extrema.Points(1, extremaPoint1, extremaPoint2);
if (extremaPoint1.Distance(extremaPoint2) < Precision::Confusion())
if (extremaPoint1.Distance(extremaPoint2) < Precision::Confusion()) {
dimensionOriginPoint = extremaPoint1;
else
{
//find halfway point in between extrema points for dimension origin.
}
else {
// find halfway point in between extrema points for dimension origin.
gp_Vec vec1(extremaPoint1.XYZ());
gp_Vec vec2(extremaPoint2.XYZ());
gp_Vec connection(vec2-vec1);
gp_Vec connection(vec2 - vec1);
Standard_Real distance = connection.Magnitude();
connection.Normalize();
connection *= (distance / 2.0);
@@ -204,8 +218,7 @@ SbMatrix ViewProviderMeasureAngle::getMatrix() {
gp_Vec extrema2Vector(extremaPoint2.XYZ());
radius = (loc1 - originVector).Magnitude();
double legOne = (extrema2Vector - originVector).Magnitude();
if (legOne > Precision::Confusion())
{
if (legOne > Precision::Confusion()) {
double legTwo = sqrt(pow(radius, 2) - pow(legOne, 2));
gp_Vec projectionVector(vector2);
projectionVector.Normalize();
@@ -222,13 +235,22 @@ SbMatrix ViewProviderMeasureAngle::getMatrix() {
gp_Vec zAxis = (xAxis.Crossed(fakeYAxis)).Normalized();
gp_Vec yAxis = zAxis.Crossed(xAxis).Normalized();
dimSys = SbMatrix
(
xAxis.X(), yAxis.X(), zAxis.X(), dimensionOriginPoint.X(),
xAxis.Y(), yAxis.Y(), zAxis.Y(), dimensionOriginPoint.Y(),
xAxis.Z(), yAxis.Z(), zAxis.Z(), dimensionOriginPoint.Z(),
0.0, 0.0, 0.0, 1.0
);
dimSys = SbMatrix(xAxis.X(),
yAxis.X(),
zAxis.X(),
dimensionOriginPoint.X(),
xAxis.Y(),
yAxis.Y(),
zAxis.Y(),
dimensionOriginPoint.Y(),
xAxis.Z(),
yAxis.Z(),
zAxis.Z(),
dimensionOriginPoint.Z(),
0.0,
0.0,
0.0,
1.0);
dimSys = dimSys.transpose();
}
@@ -237,7 +259,6 @@ SbMatrix ViewProviderMeasureAngle::getMatrix() {
}
PROPERTY_SOURCE(MeasureGui::ViewProviderMeasureAngle, MeasureGui::ViewProviderMeasureBase)
@@ -246,7 +267,7 @@ ViewProviderMeasureAngle::ViewProviderMeasureAngle()
sPixmap = "Measurement-Angle";
// Primary Arc
Gui::ArcEngine *arcEngine = new Gui::ArcEngine();
Gui::ArcEngine* arcEngine = new Gui::ArcEngine();
arcEngine->angle.connectFrom(&fieldAngle);
auto calculatorRadius = new SoCalculator();
@@ -255,10 +276,10 @@ ViewProviderMeasureAngle::ViewProviderMeasureAngle()
arcEngine->radius.connectFrom(&calculatorRadius->oa);
arcEngine->deviation.setValue(0.1f);
SoCoordinate3 *coordinates = new SoCoordinate3();
SoCoordinate3* coordinates = new SoCoordinate3();
coordinates->point.connectFrom(&arcEngine->points);
SoLineSet *lineSet = new SoLineSet();
SoLineSet* lineSet = new SoLineSet();
lineSet->vertexProperty.setValue(coordinates);
lineSet->numVertices.connectFrom(&arcEngine->pointCount);
lineSet->startIndex.setValue(0);
@@ -269,16 +290,17 @@ ViewProviderMeasureAngle::ViewProviderMeasureAngle()
auto engineAngle = new SoCalculator();
engineAngle->A.connectFrom(&arcEngine->midpoint);
engineAngle->B.connectFrom(&pLabelTranslation->translation);
engineAngle->expression.setValue("tA=normalize(A); tB=normalize(B); oa=atan2(tB[1], tB[0])-atan2(tA[1], tA[0])");
engineAngle->expression.setValue(
"tA=normalize(A); tB=normalize(B); oa=atan2(tB[1], tB[0])-atan2(tA[1], tA[0])");
Gui::ArcEngine *arcEngineSecondary = new Gui::ArcEngine();
Gui::ArcEngine* arcEngineSecondary = new Gui::ArcEngine();
arcEngineSecondary->radius.connectFrom(&calculatorRadius->oa);
arcEngineSecondary->deviation.setValue(0.1f);
arcEngineSecondary->angle.connectFrom(&engineAngle->oa);
// Rotate arc
auto engineRotMidpoint = new SoComposeRotationFromTo(); // absolute angle to midpoint
engineRotMidpoint->from.setValue(SbVec3f(1.0, 0.0, 0.0));
auto engineRotMidpoint = new SoComposeRotationFromTo(); // absolute angle to midpoint
engineRotMidpoint->from.setValue(SbVec3f(1.0, 0.0, 0.0));
engineRotMidpoint->to.connectFrom(&arcEngine->midpoint);
auto matrixEngine = new SoComposeMatrix();
@@ -287,10 +309,10 @@ ViewProviderMeasureAngle::ViewProviderMeasureAngle()
transformEngine->matrix.connectFrom(&matrixEngine->matrix);
transformEngine->vector.connectFrom(&arcEngineSecondary->points);
SoCoordinate3 *coordinatesSecondary = new SoCoordinate3();
SoCoordinate3* coordinatesSecondary = new SoCoordinate3();
coordinatesSecondary->point.connectFrom(&transformEngine->point);
SoLineSet *lineSetSecondary = new SoLineSet();
SoLineSet* lineSetSecondary = new SoLineSet();
lineSetSecondary->vertexProperty.setValue(coordinatesSecondary);
lineSetSecondary->numVertices.connectFrom(&arcEngineSecondary->pointCount);
lineSetSecondary->startIndex.setValue(0);
@@ -304,15 +326,16 @@ void ViewProviderMeasureAngle::redrawAnnotation()
auto obj = dynamic_cast<Measure::MeasureAngle*>(getMeasureObject());
double angleDeg = obj->Angle.getValue();
constexpr double radiansPerDegree = M_PI / 180.0;
this->fieldAngle = angleDeg * radiansPerDegree;
this->fieldAngle = angleDeg * radiansPerDegree;
// Set matrix
try {
SbMatrix matrix = getMatrix();
pcTransform->setMatrix(matrix);
} catch (const Base::Exception& e) {
Base::Console().Error("Error in ViewProviderMeasureAngle::redrawAnnotation: %s\n", e.what());
}
catch (const Base::Exception& e) {
Base::Console().Error("Error in ViewProviderMeasureAngle::redrawAnnotation: %s\n",
e.what());
return;
}
@@ -332,8 +355,8 @@ Measure::MeasureAngle* ViewProviderMeasureAngle::getMeasureAngle()
}
void ViewProviderMeasureAngle::positionAnno(const Measure::MeasureBase* measureObject) {
void ViewProviderMeasureAngle::positionAnno(const Measure::MeasureBase* measureObject)
{
(void)measureObject;
setLabelTranslation(SbVec3f(0, 0.1 * getViewScale(), 0));
}

View File

@@ -35,18 +35,18 @@
#include "ViewProviderMeasureBase.h"
//NOLINTBEGIN
// NOLINTBEGIN
class SoText2;
class SoTranslation;
class SoCoordinate3;
class SoIndexedLineSet;
class SoTransform;
//NOLINTEND
// NOLINTEND
namespace MeasureGui
{
class MeasureGuiExport ViewProviderMeasureAngle : public MeasureGui::ViewProviderMeasureBase
class MeasureGuiExport ViewProviderMeasureAngle: public MeasureGui::ViewProviderMeasureBase
{
PROPERTY_HEADER_WITH_OVERRIDE(MeasureGui::ViewProviderMeasureAngle);
@@ -60,14 +60,13 @@ public:
private:
// Fields
SoSFFloat fieldAngle; //radians.
SoSFFloat fieldAngle; // radians.
SbMatrix getMatrix();
};
} //namespace MeasureGui
} // namespace MeasureGui
#endif // GUI_VIEWPROVIDERMEASUREANGLE_H
#endif // GUI_VIEWPROVIDERMEASUREANGLE_H

View File

@@ -24,20 +24,20 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/actions/SoGetMatrixAction.h>
# include <Inventor/nodes/SoAnnotation.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoCamera.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/nodes/SoIndexedLineSet.h>
# include <Inventor/nodes/SoMarkerSet.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/draggers/SoTranslate2Dragger.h>
# include <Inventor/engines/SoComposeMatrix.h>
# include <Inventor/engines/SoTransformVec3f.h>
# include <Inventor/engines/SoConcatenate.h>
# include <Inventor/SbViewportRegion.h>
#include <Inventor/actions/SoGetMatrixAction.h>
#include <Inventor/nodes/SoAnnotation.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoCamera.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoIndexedLineSet.h>
#include <Inventor/nodes/SoMarkerSet.h>
#include <Inventor/nodes/SoPickStyle.h>
#include <Inventor/draggers/SoTranslate2Dragger.h>
#include <Inventor/engines/SoComposeMatrix.h>
#include <Inventor/engines/SoTransformVec3f.h>
#include <Inventor/engines/SoConcatenate.h>
#include <Inventor/SbViewportRegion.h>
#endif
#include <App/DocumentObject.h>
@@ -69,20 +69,35 @@ QIcon ViewProviderMeasureGroup::getIcon() const
}
//NOLINTBEGIN
// NOLINTBEGIN
PROPERTY_SOURCE(MeasureGui::ViewProviderMeasureBase, Gui::ViewProviderDocumentObject)
//NOLINTEND
// NOLINTEND
ViewProviderMeasureBase::ViewProviderMeasureBase()
{
static const char *agroup = "Appearance";
//NOLINTBEGIN
ADD_PROPERTY_TYPE(TextColor, (Preferences::defaultTextColor()), agroup, App::Prop_None, "Color for the measurement text");
ADD_PROPERTY_TYPE(TextBackgroundColor, (Preferences::defaultTextBackgroundColor()), agroup, App::Prop_None, "Color for the measurement text background");
ADD_PROPERTY_TYPE(LineColor, (Preferences::defaultLineColor()), agroup, App::Prop_None, "Color for the measurement lines");
ADD_PROPERTY_TYPE(FontSize, (Preferences::defaultFontSize()), agroup, App::Prop_None, "Size of measurement text");
//NOLINTEND
static const char* agroup = "Appearance";
// NOLINTBEGIN
ADD_PROPERTY_TYPE(TextColor,
(Preferences::defaultTextColor()),
agroup,
App::Prop_None,
"Color for the measurement text");
ADD_PROPERTY_TYPE(TextBackgroundColor,
(Preferences::defaultTextBackgroundColor()),
agroup,
App::Prop_None,
"Color for the measurement text background");
ADD_PROPERTY_TYPE(LineColor,
(Preferences::defaultLineColor()),
agroup,
App::Prop_None,
"Color for the measurement lines");
ADD_PROPERTY_TYPE(FontSize,
(Preferences::defaultFontSize()),
agroup,
App::Prop_None,
"Size of measurement text");
// NOLINTEND
pGlobalSeparator = new SoSeparator();
pGlobalSeparator->ref();
@@ -158,7 +173,7 @@ ViewProviderMeasureBase::ViewProviderMeasureBase()
sa.setSearchingAll(true);
sa.setNode(pLabel);
sa.apply(pcRoot);
SoPath * labelPath = sa.getPath();
SoPath* labelPath = sa.getPath();
assert(labelPath);
dragger->setPartAsPath("translator", labelPath);
@@ -168,12 +183,12 @@ ViewProviderMeasureBase::ViewProviderMeasureBase()
dragger->setPart("yAxisFeedback", NULL);
// end setupSceneGraph
// these touches cause onChanged to run which then updates pLabel and pColor with the initial values
// these touches cause onChanged to run which then updates pLabel and pColor with the initial
// values
TextColor.touch();
TextBackgroundColor.touch();
FontSize.touch();
LineColor.touch();
}
ViewProviderMeasureBase::~ViewProviderMeasureBase()
@@ -207,7 +222,8 @@ void ViewProviderMeasureBase::setDisplayMode(const char* ModeName)
}
void ViewProviderMeasureBase::finishRestoring() {
void ViewProviderMeasureBase::finishRestoring()
{
// Force measurement visibility when loading a document
show();
}
@@ -234,16 +250,19 @@ void ViewProviderMeasureBase::onChanged(const App::Property* prop)
ViewProviderDocumentObject::onChanged(prop);
}
void ViewProviderMeasureBase::draggerChangedCallback(void *data, SoDragger *) {
void ViewProviderMeasureBase::draggerChangedCallback(void* data, SoDragger*)
{
auto me = static_cast<ViewProviderMeasureBase*>(data);
me->onLabelMoved();
}
void ViewProviderMeasureBase::setLabelValue(const Base::Quantity& value) {
void ViewProviderMeasureBase::setLabelValue(const Base::Quantity& value)
{
pLabel->string.setValue(value.getUserString().toUtf8().constData());
}
void ViewProviderMeasureBase::setLabelValue(const QString& value) {
void ViewProviderMeasureBase::setLabelValue(const QString& value)
{
auto lines = value.split(QString::fromLatin1("\n"));
int i = 0;
@@ -253,51 +272,58 @@ void ViewProviderMeasureBase::setLabelValue(const QString& value) {
}
}
void ViewProviderMeasureBase::setLabelTranslation(const SbVec3f& position) {
void ViewProviderMeasureBase::setLabelTranslation(const SbVec3f& position)
{
// Set the dragger translation to keep it in sync with pLabelTranslation
pDragger->translation.setValue(position);
}
SoPickStyle* ViewProviderMeasureBase::getSoPickStyle() {
SoPickStyle* ViewProviderMeasureBase::getSoPickStyle()
{
auto ps = new SoPickStyle();
ps->style = SoPickStyle::UNPICKABLE;
return ps;
}
SoDrawStyle* ViewProviderMeasureBase::getSoLineStylePrimary() {
SoDrawStyle* ViewProviderMeasureBase::getSoLineStylePrimary()
{
auto style = new SoDrawStyle();
style->lineWidth = 2.0f;
return style;
}
SoDrawStyle* ViewProviderMeasureBase::getSoLineStyleSecondary() {
SoDrawStyle* ViewProviderMeasureBase::getSoLineStyleSecondary()
{
auto style = new SoDrawStyle();
style->lineWidth = 1.0f;
return style;
}
SoSeparator* ViewProviderMeasureBase::getSoSeparatorText() {
SoSeparator* ViewProviderMeasureBase::getSoSeparatorText()
{
return pTextSeparator;
}
void ViewProviderMeasureBase::positionAnno(const Measure::MeasureBase* measureObject) {
void ViewProviderMeasureBase::positionAnno(const Measure::MeasureBase* measureObject)
{
(void)measureObject;
}
void ViewProviderMeasureBase::updateIcon() {
void ViewProviderMeasureBase::updateIcon()
{
// This assumes the icons main color is black
Gui::ColorMap colorMap {
{ 0x000000, TextColor.getValue().getPackedRGB() >> 8 },
{0x000000, TextColor.getValue().getPackedRGB() >> 8},
};
pLabel->setIcon(Gui::BitmapFactory().pixmapFromSvg(sPixmap, QSize(20, 20), colorMap));
}
void ViewProviderMeasureBase::attach(App::DocumentObject *pcObj)
void ViewProviderMeasureBase::attach(App::DocumentObject* pcObj)
{
ViewProviderDocumentObject::attach(pcObj);
updateIcon();
@@ -320,7 +346,8 @@ void ViewProviderMeasureBase::updateData(const App::Property* prop)
// Check if one of the input properties has been changed
auto inputProps = obj->getInputProps();
if (std::find(inputProps.begin(), inputProps.end(), std::string(prop->getName())) != inputProps.end()) {
if (std::find(inputProps.begin(), inputProps.end(), std::string(prop->getName()))
!= inputProps.end()) {
doUpdate = true;
// Add connections to be notified when the measured objects are changed
@@ -329,7 +356,7 @@ void ViewProviderMeasureBase::updateData(const App::Property* prop)
// Check if the result prop has been changed
auto resultProp = obj->getResultProp();
if (resultProp && prop == resultProp){
if (resultProp && prop == resultProp) {
doUpdate = true;
}
@@ -349,7 +376,7 @@ void ViewProviderMeasureBase::updateData(const App::Property* prop)
// TODO: should this be pure virtual?
void ViewProviderMeasureBase::redrawAnnotation()
{
// Base::Console().Message("VPMB::redrawAnnotation()\n");
// Base::Console().Message("VPMB::redrawAnnotation()\n");
}
//! connect to the subject to receive visibility updates
@@ -364,9 +391,12 @@ void ViewProviderMeasureBase::connectToSubject(App::DocumentObject* subject)
_mVisibilityChangedConnection.disconnect();
}
//NOLINTBEGIN
auto bndVisibility = std::bind(&ViewProviderMeasureBase::onSubjectVisibilityChanged, this, std::placeholders::_1, std::placeholders::_2);
//NOLINTEND
// NOLINTBEGIN
auto bndVisibility = std::bind(&ViewProviderMeasureBase::onSubjectVisibilityChanged,
this,
std::placeholders::_1,
std::placeholders::_2);
// NOLINTEND
_mVisibilityChangedConnection = subject->signalChanged.connect(bndVisibility);
}
@@ -386,7 +416,8 @@ void ViewProviderMeasureBase::connectToSubject(std::vector<App::DocumentObject*>
//! retrieve the feature
Measure::MeasureBase* ViewProviderMeasureBase::getMeasureObject()
{
// Note: Cast to MeasurePropertyBase once we use it to provide the needed values e.g. basePosition textPosition etc.
// Note: Cast to MeasurePropertyBase once we use it to provide the needed values e.g.
// basePosition textPosition etc.
auto feature = dynamic_cast<Measure::MeasureBase*>(pcObject);
if (!feature) {
throw Base::RuntimeError("Feature not found for ViewProviderMeasureBase");
@@ -395,38 +426,44 @@ Measure::MeasureBase* ViewProviderMeasureBase::getMeasureObject()
}
//! calculate a good direction from the elements being measured to the annotation text based on the layout
//! of the elements and relationship with the cardinal axes and the view direction. elementDirection
//! is expected to be a normalized vector.
//! 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)
//! calculate a good direction from the elements being measured to the annotation text based on the
//! layout of the elements and relationship with the cardinal axes and the view direction.
//! elementDirection is expected to be a normalized vector. 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 through 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).
// 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 through 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;
Gui::View3DInventor* view = nullptr;
Gui::View3DInventor* view = nullptr;
try {
view = dynamic_cast<Gui::View3DInventor*>(this->getActiveView());
} catch (const Base::RuntimeError&) {
Base::Console().Log("ViewProviderMeasureBase::getTextDirection: Could not get active view\n");
}
catch (const Base::RuntimeError&) {
Base::Console().Log(
"ViewProviderMeasureBase::getTextDirection: Could not get active view\n");
}
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 {
// 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) {
if (textDirection.Length() < tolerance) {
// either elementDirection and viewDirection are parallel or one of them is null.
textDirection = elementDirection.Cross(upDirection);
}
@@ -435,20 +472,21 @@ Gui::View3DInventor* view = nullptr;
}
//! true if the subject of this measurement is visible. For Measures that have multiple object subject,
//! all of the subjects must be visible.
//! 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()
{
Gui::Document* guiDoc = nullptr;
try {
guiDoc = this->getDocument();
} catch (const Base::RuntimeError&) {
}
catch (const Base::RuntimeError&) {
Base::Console().Log("ViewProviderMeasureBase::isSubjectVisible: Could not get document\n");
return false;
}
// we need these things to proceed
if (!getMeasureObject() || !guiDoc ) {
if (!getMeasureObject() || !guiDoc) {
return false;
}
@@ -457,7 +495,7 @@ bool ViewProviderMeasureBase::isSubjectVisible()
return true;
}
for (auto & obj : getMeasureObject()->getSubject()) {
for (auto& obj : getMeasureObject()->getSubject()) {
Gui::ViewProvider* vp = guiDoc->getViewProvider(obj);
if (!vp || !vp->isVisible()) {
return false;
@@ -469,9 +507,10 @@ bool ViewProviderMeasureBase::isSubjectVisible()
}
//! gets called when the subject object issues a signalChanged (ie a property change). We are only interested in the subject's
//! Visibility property
void ViewProviderMeasureBase::onSubjectVisibilityChanged(const App::DocumentObject& docObj, const App::Property& prop)
//! gets called when the subject object issues a signalChanged (ie a property change). We are only
//! interested in the subject's Visibility property
void ViewProviderMeasureBase::onSubjectVisibilityChanged(const App::DocumentObject& docObj,
const App::Property& prop)
{
if (docObj.isRemoving()) {
return;
@@ -482,15 +521,18 @@ void ViewProviderMeasureBase::onSubjectVisibilityChanged(const App::DocumentObje
if (!docObj.Visibility.getValue()) {
// show ourselves only if subject is visible
setVisible(false);
} else {
// here, we don't know if we should be visible or not, so we have to check the whole subject
}
else {
// here, we don't know if we should be visible or not, so we have to check the whole
// subject
setVisible(isSubjectVisible());
}
}
}
float ViewProviderMeasureBase::getViewScale() {
float ViewProviderMeasureBase::getViewScale()
{
float scale = 1.0;
Gui::View3DInventor* view = dynamic_cast<Gui::View3DInventor*>(this->getActiveView());
@@ -500,9 +542,10 @@ float ViewProviderMeasureBase::getViewScale() {
}
Gui::View3DInventorViewer* viewer = view->getViewer();
SoCamera * const camera = viewer->getSoRenderManager()->getCamera();
if (!camera)
SoCamera* const camera = viewer->getSoRenderManager()->getCamera();
if (!camera) {
return false;
}
SbViewVolume volume(camera->getViewVolume());
SbVec3f center(volume.getSightPoint(camera->focalDistance.getValue()));
@@ -511,12 +554,12 @@ float ViewProviderMeasureBase::getViewScale() {
}
//NOLINTBEGIN
// NOLINTBEGIN
PROPERTY_SOURCE(MeasureGui::ViewProviderMeasure, MeasureGui::ViewProviderMeasureBase)
//NOLINTEND
// NOLINTEND
//! the general purpose view provider. handles area, length, etc - any measure without a specialized VP
//! the general purpose view provider. handles area, length, etc - any measure without a
//! specialized VP
ViewProviderMeasure::ViewProviderMeasure()
{
sPixmap = "umf-measurement";
@@ -527,10 +570,7 @@ ViewProviderMeasure::ViewProviderMeasure()
// indexes used to create the edges
// this makes a line from verts[0] to verts[1]
static const int32_t lines[lineCount] =
{
0,1,-1
};
static const int32_t lines[lineCount] = {0, 1, -1};
pCoords = new SoCoordinate3();
pCoords->ref();
@@ -538,13 +578,13 @@ ViewProviderMeasure::ViewProviderMeasure()
// Combine coordinates from baseTranslation and labelTranslation
auto engineCat = new SoConcatenate(SoMFVec3f::getClassTypeId());
auto origin = new SoSFVec3f();
origin->setValue(0,0,0);
origin->setValue(0, 0, 0);
engineCat->input[0]->connectFrom(origin);
engineCat->input[1]->connectFrom(&pLabelTranslation->translation);
pCoords->point.setNum(engineCat->output->getNumConnections());
pCoords->point.connectFrom(engineCat->output);
pLines = new SoIndexedLineSet();
pLines = new SoIndexedLineSet();
pLines->ref();
pLines->coordIndex.setNum(lineCount);
pLines->coordIndex.setValues(0, lineCount, lines);
@@ -553,17 +593,20 @@ ViewProviderMeasure::ViewProviderMeasure()
lineSep->addChild(pCoords);
lineSep->addChild(pLines);
auto points = new SoMarkerSet();
points->markerIndex = Gui::Inventor::MarkerBitmaps::getMarkerIndex("CROSS",
Gui::ViewParams::instance()->getMarkerSize());
points->numPoints=1;
points->markerIndex =
Gui::Inventor::MarkerBitmaps::getMarkerIndex("CROSS",
Gui::ViewParams::instance()->getMarkerSize());
points->numPoints = 1;
lineSep->addChild(points);
// Connect dragger local orientation to view orientation
Gui::View3DInventor* view = nullptr;
try {
view = dynamic_cast<Gui::View3DInventor*>(this->getActiveView());
} catch (const Base::RuntimeError& ) {
Base::Console().Log("ViewProviderMeasure::ViewProviderMeasure: Could not get active view\n");
}
catch (const Base::RuntimeError&) {
Base::Console().Log(
"ViewProviderMeasure::ViewProviderMeasure: Could not get active view\n");
}
if (view) {
@@ -572,8 +615,6 @@ ViewProviderMeasure::ViewProviderMeasure()
auto cam = renderManager->getCamera();
pDraggerOrientation->rotation.connectFrom(&cam->orientation);
}
}
ViewProviderMeasure::~ViewProviderMeasure()
@@ -582,7 +623,8 @@ ViewProviderMeasure::~ViewProviderMeasure()
pLines->unref();
}
void ViewProviderMeasure::positionAnno(const Measure::MeasureBase* measureObject) {
void ViewProviderMeasure::positionAnno(const Measure::MeasureBase* measureObject)
{
(void)measureObject;
// Initialize the text position
@@ -593,11 +635,12 @@ void ViewProviderMeasure::positionAnno(const Measure::MeasureBase* measureObject
Gui::View3DInventor* view = nullptr;
try {
view = dynamic_cast<Gui::View3DInventor*>(this->getActiveView());
} catch (const Base::RuntimeError&) {
}
catch (const Base::RuntimeError&) {
Base::Console().Log("ViewProviderMeasure::positionAnno: Could not get active view\n");
}
if(!view){
if (!view) {
return;
}
@@ -636,27 +679,30 @@ void ViewProviderMeasure::redrawAnnotation()
}
Base::Vector3d ViewProviderMeasure::getBasePosition(){
Base::Vector3d ViewProviderMeasure::getBasePosition()
{
auto measureObject = getMeasureObject();
Base::Placement placement = measureObject->getPlacement();
return placement.getPosition();
}
Base::Vector3d ViewProviderMeasure::getTextPosition(){
Base::Vector3d ViewProviderMeasure::getTextPosition()
{
// Return the initial position relative to the base position
auto basePoint = getBasePosition();
Gui::View3DInventor* view = dynamic_cast<Gui::View3DInventor*>(this->getActiveView());
if (!view) {
Base::Console().Log("ViewProviderMeasureBase::getTextPosition: Could not get active view\n");
Base::Console().Log(
"ViewProviderMeasureBase::getTextPosition: Could not get active view\n");
return Base::Vector3d();
}
Gui::View3DInventorViewer* viewer = view->getViewer();
// Convert to screenspace, offset and convert back to world space
SbVec2s screenPos = viewer->getPointOnViewport(SbVec3f(basePoint.x, basePoint.y, basePoint.z));
SbVec3f vec = viewer->getPointOnFocalPlane(screenPos + SbVec2s(30.0, 30.0));
SbVec3f vec = viewer->getPointOnFocalPlane(screenPos + SbVec2s(30.0, 30.0));
Base::Vector3d textPos(vec[0], vec[1], vec[2]);
return textPos - basePoint;
@@ -676,4 +722,4 @@ void ViewProviderMeasureBase::show()
PROPERTY_SOURCE(MeasureGui::ViewProviderMeasureArea, MeasureGui::ViewProviderMeasure)
PROPERTY_SOURCE(MeasureGui::ViewProviderMeasureLength, MeasureGui::ViewProviderMeasure)
PROPERTY_SOURCE(MeasureGui::ViewProviderMeasurePosition, MeasureGui::ViewProviderMeasure)
PROPERTY_SOURCE(MeasureGui::ViewProviderMeasureRadius, MeasureGui::ViewProviderMeasure)
PROPERTY_SOURCE(MeasureGui::ViewProviderMeasureRadius, MeasureGui::ViewProviderMeasure)

View File

@@ -35,7 +35,7 @@
#include <Mod/Measure/App/MeasureBase.h>
//NOLINTBEGIN
// NOLINTBEGIN
class SbVec2s;
class SoFontStyle;
class SoBaseColor;
@@ -45,13 +45,14 @@ class SoPickStyle;
class SoCoordinate3;
class SoIndexedLineSet;
class SoTranslate2Dragger;
//NOLINTEND
// NOLINTEND
namespace MeasureGui {
namespace MeasureGui
{
class MeasureGuiExport ViewProviderMeasureGroup : public Gui::ViewProviderDocumentObjectGroup
class MeasureGuiExport ViewProviderMeasureGroup: public Gui::ViewProviderDocumentObjectGroup
{
PROPERTY_HEADER_WITH_OVERRIDE(MeasureGui::ViewProviderMeasureGroup);
@@ -59,7 +60,8 @@ public:
ViewProviderMeasureGroup();
~ViewProviderMeasureGroup() override;
bool allowOverride(const App::DocumentObject &) const override {
bool allowOverride(const App::DocumentObject&) const override
{
return true;
}
@@ -67,9 +69,8 @@ public:
};
//NOLINTBEGIN
class MeasureGuiExport ViewProviderMeasureBase :public Gui::ViewProviderDocumentObject
// NOLINTBEGIN
class MeasureGuiExport ViewProviderMeasureBase: public Gui::ViewProviderDocumentObject
{
PROPERTY_HEADER_WITH_OVERRIDE(ViewProviderMeasureBase);
@@ -81,22 +82,28 @@ public:
~ViewProviderMeasureBase() override;
// Display properties
App::PropertyColor TextColor;
App::PropertyColor TextBackgroundColor;
App::PropertyColor LineColor;
App::PropertyInteger FontSize;
//NOLINTEND
App::PropertyColor TextColor;
App::PropertyColor TextBackgroundColor;
App::PropertyColor LineColor;
App::PropertyInteger FontSize;
// NOLINTEND
/**
* Attaches the document object to this view provider.
*/
bool isPartOfPhysicalObject() const override {return false;};
void attach(App::DocumentObject *pcObj) override;
bool isPartOfPhysicalObject() const override
{
return false;
};
void attach(App::DocumentObject* pcObj) override;
void updateData(const App::Property* prop) override;
virtual void positionAnno(const Measure::MeasureBase* measureObject);
void finishRestoring() override;
bool useNewSelectionModel() const override {return true;}
bool useNewSelectionModel() const override
{
return true;
}
std::vector<std::string> getDisplayModes() const override;
void setDisplayMode(const char* ModeName) override;
/// Show the annotation in the 3d window
@@ -107,8 +114,14 @@ public:
virtual bool isSubjectVisible();
static Base::Vector3d toVector3d(SbVec3f svec) { return Base::Vector3d(svec[0], svec[1], svec[2]); }
static SbVec3f toSbVec3f(Base::Vector3d vec3) { return SbVec3f(vec3.x, vec3.y, vec3.z); }
static Base::Vector3d toVector3d(SbVec3f svec)
{
return Base::Vector3d(svec[0], svec[1], svec[2]);
}
static SbVec3f toSbVec3f(Base::Vector3d vec3)
{
return SbVec3f(vec3.x, vec3.y, vec3.z);
}
void onSubjectVisibilityChanged(const App::DocumentObject& docObj, const App::Property& prop);
void connectToSubject(App::DocumentObject* subject);
@@ -129,32 +142,34 @@ protected:
SoSeparator* getSoSeparatorText();
static constexpr double defaultTolerance = 10e-6;
virtual Base::Vector3d getTextDirection(Base::Vector3d elementDirection, double tolerance = defaultTolerance);
virtual Base::Vector3d getTextDirection(Base::Vector3d elementDirection,
double tolerance = defaultTolerance);
float getViewScale();
// TODO: getters & setters and move variables to private?
bool _mShowTree = true;
SoSeparator* pGlobalSeparator; // Separator in the global coordinate space
Gui::SoFrameLabel * pLabel;
SoSeparator* pGlobalSeparator; // Separator in the global coordinate space
Gui::SoFrameLabel* pLabel;
SoTranslate2Dragger* pDragger;
SoTransform* pDraggerOrientation;
SoTransform * pLabelTranslation;
SoBaseColor * pColor;
SoTransform* pLabelTranslation;
SoBaseColor* pColor;
SoSeparator* pRootSeparator;
SoSeparator* pTextSeparator;
SoSeparator* pLineSeparator;
SoSeparator* pLineSeparatorSecondary;
private:
boost::signals2::connection _mVisibilityChangedConnection;
};
//NOLINTBEGIN
class MeasureGuiExport ViewProviderMeasure : public MeasureGui::ViewProviderMeasureBase
// NOLINTBEGIN
class MeasureGuiExport ViewProviderMeasure: public MeasureGui::ViewProviderMeasureBase
{
PROPERTY_HEADER_WITH_OVERRIDE(MeasureGui::ViewProviderMeasure);
//NOLINTEND
// NOLINTEND
public:
/// Constructor
@@ -171,56 +186,59 @@ protected:
virtual Base::Vector3d getTextPosition();
private:
SoCoordinate3 * pCoords;
SoIndexedLineSet * pLines;
SoCoordinate3* pCoords;
SoIndexedLineSet* pLines;
};
class ViewProviderMeasureArea : public ViewProviderMeasure
class ViewProviderMeasureArea: public ViewProviderMeasure
{
PROPERTY_HEADER(MeasureGui::ViewProviderMeasureArea);
public:
ViewProviderMeasureArea() {
ViewProviderMeasureArea()
{
sPixmap = "Measurement-Area";
}
};
class ViewProviderMeasureLength : public ViewProviderMeasure
class ViewProviderMeasureLength: public ViewProviderMeasure
{
PROPERTY_HEADER(MeasureGui::ViewProviderMeasureLength);
public:
ViewProviderMeasureLength() {
ViewProviderMeasureLength()
{
sPixmap = "Measurement-Distance";
}
};
class ViewProviderMeasurePosition : public ViewProviderMeasure
class ViewProviderMeasurePosition: public ViewProviderMeasure
{
PROPERTY_HEADER(MeasureGui::ViewProviderMeasurePosition);
public:
ViewProviderMeasurePosition() {
ViewProviderMeasurePosition()
{
sPixmap = "Measurement-Position";
}
};
class ViewProviderMeasureRadius : public ViewProviderMeasure
class ViewProviderMeasureRadius: public ViewProviderMeasure
{
PROPERTY_HEADER(MeasureGui::ViewProviderMeasureRadius);
public:
ViewProviderMeasureRadius() {
ViewProviderMeasureRadius()
{
sPixmap = "Measurement-Radius";
}
};
} // namespace Gui
#endif // GUI_VIEWPROVIDER_MEASUREMENTBASE_H
} // namespace MeasureGui
#endif // GUI_VIEWPROVIDER_MEASUREMENTBASE_H

View File

@@ -96,8 +96,8 @@ MeasureGui::DimensionLinear::DimensionLinear()
SO_NODE_ADD_FIELD(text, ("test")); // dimension text
SO_NODE_ADD_FIELD(dColor, (1.0, 0.0, 0.0)); // dimension color.
SO_NODE_ADD_FIELD(backgroundColor, (1.0, 1.0, 1.0));
SO_NODE_ADD_FIELD(showArrows, (false)); // display dimension arrows
SO_NODE_ADD_FIELD(fontSize, (12.0)); // size of the dimension font
SO_NODE_ADD_FIELD(showArrows, (false)); // display dimension arrows
SO_NODE_ADD_FIELD(fontSize, (12.0)); // size of the dimension font
}
MeasureGui::DimensionLinear::~DimensionLinear()
@@ -231,13 +231,16 @@ void MeasureGui::DimensionLinear::setupDimension()
}
SbMatrix ViewProviderMeasureDistance::getMatrix() {
SbMatrix ViewProviderMeasureDistance::getMatrix()
{
if (!pcObject) {
return {};
}
auto prop1 = Base::freecad_dynamic_cast<App::PropertyVector>(pcObject->getPropertyByName("Position1"));
auto prop2 = Base::freecad_dynamic_cast<App::PropertyVector>(pcObject->getPropertyByName("Position2"));
auto prop1 =
Base::freecad_dynamic_cast<App::PropertyVector>(pcObject->getPropertyByName("Position1"));
auto prop2 =
Base::freecad_dynamic_cast<App::PropertyVector>(pcObject->getPropertyByName("Position2"));
if (!prop1 || !prop2) {
return {};
@@ -255,23 +258,34 @@ SbMatrix ViewProviderMeasureDistance::getMatrix() {
assert(fabs(localYAxis.Dot(localXAxis)) < tolerance);
Base::Vector3d localZAxis = localYAxis.Cross(localXAxis).Normalize();
SbMatrix matrix = SbMatrix(
localXAxis.x, localXAxis.y, localXAxis.z, 0,
localYAxis.x, localYAxis.y, localYAxis.z ,0,
localZAxis.x, localZAxis.y, localZAxis.z, 0,
// 0,0,0,1
origin[0], origin[1], origin[2], 1
);
SbMatrix matrix = SbMatrix(localXAxis.x,
localXAxis.y,
localXAxis.z,
0,
localYAxis.x,
localYAxis.y,
localYAxis.z,
0,
localZAxis.x,
localZAxis.y,
localZAxis.z,
0,
// 0,0,0,1
origin[0],
origin[1],
origin[2],
1);
return matrix;
}
//! calculate a good direction from the elements being measured to the annotation text based on the layout
//! of the elements and its relationship with the cardinal axes and the view direction. elementDirection
//! is expected to be a normalized vector.
//! an example of an elementDirection would be the vector from the start of a line to the end.
Base::Vector3d ViewProviderMeasureDistance::getTextDirection(Base::Vector3d elementDirection, double tolerance)
//! calculate a good direction from the elements being measured to the annotation text based on the
//! layout of the elements and its relationship with the cardinal axes and the view direction.
//! elementDirection is expected to be a normalized vector. an example of an elementDirection would
//! be the vector from the start of a line to the end.
Base::Vector3d ViewProviderMeasureDistance::getTextDirection(Base::Vector3d elementDirection,
double tolerance)
{
const Base::Vector3d stdX(1.0, 0.0, 0.0);
const Base::Vector3d stdY(0.0, 1.0, 0.0);
@@ -297,20 +311,31 @@ ViewProviderMeasureDistance::ViewProviderMeasureDistance()
{
sPixmap = "Measurement-Distance";
ADD_PROPERTY_TYPE(ShowDelta, (false), "Appearance", App::Prop_None, "Display the X, Y and Z components of the distance");
ADD_PROPERTY_TYPE(ShowDelta,
(false),
"Appearance",
App::Prop_None,
"Display the X, Y and Z components of the distance");
// vert indexes used to create the annotation lines
const size_t lineCount(3);
static const int32_t lines[lineCount] =
{
2,3,-1 // dimension line
static const int32_t lines[lineCount] = {
2,
3,
-1 // dimension line
};
const size_t lineCountSecondary(9);
static const int32_t linesSecondary[lineCountSecondary] = {
0,2,-1, // extension line 1
1,3,-1, // extension line 2
2,4,-1 // label helper line
0,
2,
-1, // extension line 1
1,
3,
-1, // extension line 2
2,
4,
-1 // label helper line
};
// Line Coordinates
@@ -354,9 +379,10 @@ ViewProviderMeasureDistance::ViewProviderMeasureDistance()
pLineSeparatorSecondary->addChild(lineSetSecondary);
auto points = new SoMarkerSet();
points->markerIndex = Gui::Inventor::MarkerBitmaps::getMarkerIndex("CROSS",
ViewParams::instance()->getMarkerSize());
points->numPoints=2;
points->markerIndex =
Gui::Inventor::MarkerBitmaps::getMarkerIndex("CROSS",
ViewParams::instance()->getMarkerSize());
points->numPoints = 2;
pLineSeparator->addChild(points);
@@ -431,9 +457,11 @@ void ViewProviderMeasureDistance::redrawAnnotation()
if (!pcObject) {
return;
}
auto prop1 = Base::freecad_dynamic_cast<App::PropertyVector>(pcObject->getPropertyByName("Position1"));
auto prop2 = Base::freecad_dynamic_cast<App::PropertyVector>(pcObject->getPropertyByName("Position2"));
auto prop1 =
Base::freecad_dynamic_cast<App::PropertyVector>(pcObject->getPropertyByName("Position1"));
auto prop2 =
Base::freecad_dynamic_cast<App::PropertyVector>(pcObject->getPropertyByName("Position2"));
if (!prop1 || !prop2) {
return;
@@ -448,19 +476,23 @@ void ViewProviderMeasureDistance::redrawAnnotation()
// Set the distance
fieldDistance = (vec2 - vec1).Length();
auto propDistance = dynamic_cast<App::PropertyDistance*>(pcObject->getPropertyByName("Distance"));
auto propDistance =
dynamic_cast<App::PropertyDistance*>(pcObject->getPropertyByName("Distance"));
setLabelValue(propDistance->getQuantityValue().getUserString());
// Set delta distance
auto propDistanceX = static_cast<App::PropertyDistance*>(getMeasureObject()->getPropertyByName("DistanceX"));
auto propDistanceX =
static_cast<App::PropertyDistance*>(getMeasureObject()->getPropertyByName("DistanceX"));
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(0))
->text.setValue("Δx: " + propDistanceX->getQuantityValue().getUserString().toUtf8());
auto propDistanceY = static_cast<App::PropertyDistance*>(getMeasureObject()->getPropertyByName("DistanceY"));
auto propDistanceY =
static_cast<App::PropertyDistance*>(getMeasureObject()->getPropertyByName("DistanceY"));
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(1))
->text.setValue("Δy: " + propDistanceY->getQuantityValue().getUserString().toUtf8());
auto propDistanceZ = static_cast<App::PropertyDistance*>(getMeasureObject()->getPropertyByName("DistanceZ"));
auto propDistanceZ =
static_cast<App::PropertyDistance*>(getMeasureObject()->getPropertyByName("DistanceZ"));
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(2))
->text.setValue("Δz: " + propDistanceZ->getQuantityValue().getUserString().toUtf8());
@@ -472,27 +504,38 @@ void ViewProviderMeasureDistance::redrawAnnotation()
updateView();
}
void ViewProviderMeasureDistance::onChanged(const App::Property* prop) {
void ViewProviderMeasureDistance::onChanged(const App::Property* prop)
{
if (prop == &ShowDelta) {
pDeltaDimensionSwitch->whichChild.setValue(ShowDelta.getValue() ? SO_SWITCH_ALL : SO_SWITCH_NONE);
} else if (prop == &FontSize) {
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(0))->fontSize.setValue(FontSize.getValue());
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(1))->fontSize.setValue(FontSize.getValue());
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(2))->fontSize.setValue(FontSize.getValue());
} else if (prop == &TextBackgroundColor) {
auto bColor = TextBackgroundColor.getValue();
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(0))->backgroundColor.setValue(bColor.r, bColor.g, bColor.g);
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(1))->backgroundColor.setValue(bColor.r, bColor.g, bColor.g);
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(2))->backgroundColor.setValue(bColor.r, bColor.g, bColor.g);
pDeltaDimensionSwitch->whichChild.setValue(ShowDelta.getValue() ? SO_SWITCH_ALL
: SO_SWITCH_NONE);
}
else if (prop == &FontSize) {
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(0))
->fontSize.setValue(FontSize.getValue());
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(1))
->fontSize.setValue(FontSize.getValue());
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(2))
->fontSize.setValue(FontSize.getValue());
}
else if (prop == &TextBackgroundColor) {
auto bColor = TextBackgroundColor.getValue();
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(0))
->backgroundColor.setValue(bColor.r, bColor.g, bColor.g);
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(1))
->backgroundColor.setValue(bColor.r, bColor.g, bColor.g);
static_cast<DimensionLinear*>(pDeltaDimensionSwitch->getChild(2))
->backgroundColor.setValue(bColor.r, bColor.g, bColor.g);
}
ViewProviderMeasureBase::onChanged(prop);
}
void ViewProviderMeasureDistance::positionAnno(const Measure::MeasureBase* measureObject) {
void ViewProviderMeasureDistance::positionAnno(const Measure::MeasureBase* measureObject)
{
(void)measureObject;
setLabelTranslation(SbVec3f(0, 0.1 * getViewScale(), 0));
}

View File

@@ -82,8 +82,7 @@ private:
};
class MeasureGuiExport ViewProviderMeasureDistance : public MeasureGui::ViewProviderMeasureBase
class MeasureGuiExport ViewProviderMeasureDistance: public MeasureGui::ViewProviderMeasureBase
{
PROPERTY_HEADER_WITH_OVERRIDE(MeasureGui::ViewProviderMeasureDistance);
@@ -98,7 +97,8 @@ public:
void positionAnno(const Measure::MeasureBase* measureObject) override;
protected:
Base::Vector3d getTextDirection(Base::Vector3d elementDirection, double tolerance = defaultTolerance) override;
Base::Vector3d getTextDirection(Base::Vector3d elementDirection,
double tolerance = defaultTolerance) override;
void onChanged(const App::Property* prop) override;
private:
@@ -115,7 +115,7 @@ private:
SbMatrix getMatrix();
};
} //namespace MeasureGui
} // namespace MeasureGui
#endif // MEASUREGUI_VIEWPROVIDERMEASUREDISTANCE_H
#endif // MEASUREGUI_VIEWPROVIDERMEASUREDISTANCE_H

View File

@@ -38,7 +38,8 @@ void WorkbenchManipulator::modifyMenuBar([[maybe_unused]] Gui::MenuItem* menuBar
menuTools->appendItem(itemMeasure);
}
void WorkbenchManipulator::modifyToolBars(Gui::ToolBarItem* toolBar) {
void WorkbenchManipulator::modifyToolBars(Gui::ToolBarItem* toolBar)
{
auto tbView = toolBar->findItem("View");
if (!tbView) {
return;

View File

@@ -25,7 +25,8 @@
#include <Gui/WorkbenchManipulator.h>
namespace MeasureGui {
namespace MeasureGui
{
class WorkbenchManipulator: public Gui::WorkbenchManipulator
{
@@ -34,7 +35,7 @@ protected:
void modifyToolBars(Gui::ToolBarItem* toolBar) override;
};
} // namespace MeasureGui
} // namespace MeasureGui
#endif // MEASUREGUI_WORKBENCHMANIPULATOR_H
#endif // MEASUREGUI_WORKBENCHMANIPULATOR_H

View File

@@ -1,22 +1,22 @@
#***************************************************************************
#* Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
#* *
#* This file is part of the FreeCAD CAx development system. *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* FreeCAD is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Lesser General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with FreeCAD; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************/
# ***************************************************************************
# * Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * FreeCAD is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Lesser General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with FreeCAD; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************/

View File

@@ -36,8 +36,9 @@ Measure.makeMeasureCOM = makeMeasureCOM
# Register python measure types
import FreeCAD
FreeCAD.MeasureManager.addMeasureType(
"CENTEROFMASS",
"Center of Mass",
MeasureCOM,
"CENTEROFMASS",
"Center of Mass",
MeasureCOM,
)

View File

@@ -25,26 +25,23 @@ from UtilsMeasure import MeasureBasePython
from PySide.QtCore import QT_TRANSLATE_NOOP
__title__="Measure Center of Mass Object"
__title__ = "Measure Center of Mass Object"
__author__ = "David Friedli"
__url__ = "http://www.freecad.org"
"""
"""
The Measure cpp object defines a result and a placement property. The Python measure type
adds it's own specific properties. Once the object is recomputed the parent properties are updated
based on the specific python properties.
based on the specific python properties.
We'll need some kind of interface for the measure command which exposes "parseSelection", "isValidSelection" etc.
"""
def makeMeasureCOM(name="CenterOfMass"):
'''makeMeasureCOM(name): make a CenterofMass measurement'''
"""makeMeasureCOM(name): make a CenterofMass measurement"""
obj = FreeCAD.ActiveDocument.addObject("Measure::MeasurePython", name)
MeasureCOM(obj)
return obj
@@ -52,12 +49,22 @@ def makeMeasureCOM(name="CenterOfMass"):
class MeasureCOM(MeasureBasePython):
"The MeasureCOM object"
def __init__(self, obj):
obj.Proxy = self
obj.addProperty("App::PropertyLinkSubGlobal", "Element", "", QT_TRANSLATE_NOOP("App::Property", "Element to measure"))
obj.addProperty("App::PropertyPosition", "Result", "", QT_TRANSLATE_NOOP("App::PropertyVector", "The result location"))
obj.addProperty(
"App::PropertyLinkSubGlobal",
"Element",
"",
QT_TRANSLATE_NOOP("App::Property", "Element to measure"),
)
obj.addProperty(
"App::PropertyPosition",
"Result",
"",
QT_TRANSLATE_NOOP("App::PropertyVector", "The result location"),
)
@classmethod
def isValidSelection(cls, selection):
@@ -70,7 +77,7 @@ class MeasureCOM(MeasureBasePython):
if not ob:
return
sub = ob.getSubObject(subName)
if not sub:
return
@@ -101,13 +108,11 @@ class MeasureCOM(MeasureBasePython):
return ()
return (ob,)
def parseSelection(self, obj, selection):
item = selection[0]
o = item["object"]
obj.Element = (o, item["subName"])
def getResultString(self, obj):
values = [Units.Quantity(v, Units.Length).getUserPreferred()[0] for v in obj.Result]
return "COM\nX: {}\nY: {}\nZ: {}".format(*values)
@@ -144,9 +149,8 @@ class MeasureCOM(MeasureBasePython):
placement.Base = com
obj.Placement = placement
def onChanged(self, obj, prop):
'''Do something when a property has changed'''
"""Do something when a property has changed"""
if prop == "Element":
self.execute(obj)

View File

@@ -38,10 +38,10 @@
// MeasureGui
#ifndef MeasureGuiExport
#ifdef MeasureGui_EXPORTS
# define MeasureGuiExport FREECAD_DECL_EXPORT
#define MeasureGuiExport FREECAD_DECL_EXPORT
#else
# define MeasureGuiExport FREECAD_DECL_IMPORT
#define MeasureGuiExport FREECAD_DECL_IMPORT
#endif
#endif
#endif //MEASURE_GLOBAL_H
#endif // MEASURE_GLOBAL_H

View File

@@ -22,6 +22,7 @@
from abc import ABC, abstractmethod, abstractclassmethod
from typing import List, Tuple
class MeasureBasePython(ABC):
@abstractclassmethod
@@ -48,5 +49,3 @@ class MeasureBasePython(ABC):
def parseSelection(self, obj, selection):
"""Sets the measurements properties from the given selection"""
pass