Merge pull request #16045 from wwmayer/format_measure
Measure: Prepare for clang-format
This commit is contained in:
@@ -17,6 +17,7 @@ files: |
|
||||
src/Mod/Import|
|
||||
src/Mod/Inspection|
|
||||
src/Mod/JtReader|
|
||||
src/Mod/Measure|
|
||||
src/Mod/Mesh|
|
||||
src/Mod/MeshPart|
|
||||
src/Mod/Plot|
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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()};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 ¶m = 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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -46,4 +46,4 @@
|
||||
|
||||
#endif //_PreComp_
|
||||
|
||||
#endif // MEASUREGUI_PRECOMPILED_H
|
||||
#endif // MEASUREGUI_PRECOMPILED_H
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
Module()
|
||||
: Py::ExtensionModule<Module>("MeasureGui")
|
||||
{
|
||||
initialize("This module is the MeasureGui module.");// register with Python
|
||||
initialize("This module is the MeasureGui module."); // register with Python
|
||||
}
|
||||
|
||||
~Module() override = default;
|
||||
@@ -65,7 +65,7 @@ PyObject* initModule()
|
||||
return Base::Interpreter().addModule(new Module);
|
||||
}
|
||||
|
||||
}// namespace MeasureGui
|
||||
} // namespace MeasureGui
|
||||
|
||||
/* Python entry */
|
||||
PyMOD_INIT_FUNC(MeasureGui)
|
||||
@@ -79,7 +79,7 @@ PyMOD_INIT_FUNC(MeasureGui)
|
||||
try {
|
||||
Base::Interpreter().loadModule("Measure");
|
||||
}
|
||||
catch(const Base::Exception& e) {
|
||||
catch (const Base::Exception& e) {
|
||||
PyErr_SetString(PyExc_ImportError, e.what());
|
||||
PyMOD_Return(nullptr);
|
||||
}
|
||||
@@ -93,6 +93,7 @@ PyMOD_INIT_FUNC(MeasureGui)
|
||||
// instantiating the commands
|
||||
CreateMeasureCommands();
|
||||
|
||||
// clang-format off
|
||||
MeasureGui::DimensionLinear::initClass();
|
||||
|
||||
MeasureGui::ViewProviderMeasureGroup ::init();
|
||||
@@ -105,11 +106,13 @@ PyMOD_INIT_FUNC(MeasureGui)
|
||||
MeasureGui::ViewProviderMeasureLength ::init();
|
||||
MeasureGui::ViewProviderMeasurePosition ::init();
|
||||
MeasureGui::ViewProviderMeasureRadius ::init();
|
||||
// clang-format on
|
||||
|
||||
// register preferences pages
|
||||
new Gui::PrefPageProducer<MeasureGui::DlgPrefsMeasureAppearanceImp>(QT_TRANSLATE_NOOP("QObject", "Measure"));
|
||||
new Gui::PrefPageProducer<MeasureGui::DlgPrefsMeasureAppearanceImp>(
|
||||
QT_TRANSLATE_NOOP("QObject", "Measure"));
|
||||
|
||||
// Q_INIT_RESOURCE(Measure);
|
||||
// Q_INIT_RESOURCE(Measure);
|
||||
|
||||
Base::Interpreter().addType(&MeasureGui::QuickMeasurePy::Type, mod, "QuickMeasure");
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user