From 19702dcb214251c6230fa8cf036753dc4ffbe122 Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Tue, 26 Nov 2024 10:16:03 +0100 Subject: [PATCH] Core: Add App::LocalCoordinateSystem. Most of App::Origin is moved into this sub class of App::Origin. Add App::Point. Change graphics of the planes/axis. Remove scale-by-content behavior and make it fixed size on screen. --- src/App/Application.cpp | 2 + src/App/Datums.cpp | 312 +++++++++++++++++- src/App/Datums.h | 194 ++++++++++- src/App/Graphviz.cpp | 5 +- src/App/Origin.cpp | 227 +------------ src/App/Origin.h | 115 +------ src/App/OriginGroupExtension.cpp | 30 +- src/Gui/Application.cpp | 2 + src/Gui/CMakeLists.txt | 2 + src/Gui/ViewProviderDatum.cpp | 93 ++---- src/Gui/ViewProviderDatum.h | 19 +- src/Gui/ViewProviderLine.cpp | 46 ++- src/Gui/ViewProviderOrigin.cpp | 91 ++--- src/Gui/ViewProviderOrigin.h | 9 +- src/Gui/ViewProviderOriginGroupExtension.cpp | 122 ------- src/Gui/ViewProviderOriginGroupExtension.h | 12 - src/Gui/ViewProviderPlane.cpp | 89 +++-- src/Gui/ViewProviderPoint.cpp | 70 ++++ src/Gui/ViewProviderPoint.h | 46 +++ src/Mod/Part/App/PartFeature.cpp | 9 + .../Part/parttests/ColorTransparencyTest.py | 4 +- src/Mod/PartDesign/Gui/ViewProviderBody.cpp | 134 -------- src/Mod/PartDesign/Gui/ViewProviderBody.h | 9 - 23 files changed, 823 insertions(+), 819 deletions(-) create mode 100644 src/Gui/ViewProviderPoint.cpp create mode 100644 src/Gui/ViewProviderPoint.h diff --git a/src/App/Application.cpp b/src/App/Application.cpp index a62f55bd53..a4587d5001 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -2150,6 +2150,8 @@ void Application::initTypes() App::DatumElement ::init(); App::Plane ::init(); App::Line ::init(); + App::Point ::init(); + App::LocalCoordinateSystem ::init(); App::Part ::init(); App::Origin ::init(); App::Link ::init(); diff --git a/src/App/Datums.cpp b/src/App/Datums.cpp index 68511613dc..75a6b06e2b 100644 --- a/src/App/Datums.cpp +++ b/src/App/Datums.cpp @@ -1,5 +1,7 @@ /*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * * Copyright (c) 2015 Alexander Golubev (Fat-Zer) * + * Copyright (c) 2024 Ondsel (PL Boyer) * * * * This file is part of the FreeCAD CAx development system. * * * @@ -21,42 +23,318 @@ ***************************************************************************/ #include "PreCompiled.h" +#ifndef _PreComp_ +#include +#endif + +#include +#include +#include #include "Datums.h" -#include "Document.h" -#include "Origin.h" +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif using namespace App; PROPERTY_SOURCE(App::DatumElement, App::GeoFeature) PROPERTY_SOURCE(App::Plane, App::DatumElement) PROPERTY_SOURCE(App::Line, App::DatumElement) +PROPERTY_SOURCE(App::Point, App::DatumElement) +PROPERTY_SOURCE(App::LocalCoordinateSystem, App::GeoFeature) -DatumElement::DatumElement() +DatumElement::DatumElement(bool hideRole) { - ADD_PROPERTY_TYPE(Role, (""), 0, App::Prop_ReadOnly, "Role of the feature in the Origin"); + ADD_PROPERTY_TYPE(Role, + (""), + 0, + App::Prop_ReadOnly, + "Role of the datum in the local coordinate system."); - // Set placement to read-only - Placement.setStatus(Property::Hidden, true); + // The role is hidden by default. It is visible only when the datum is in a LCS + if (hideRole) { + Role.setStatus(Property::Hidden, true); + } } DatumElement::~DatumElement() = default; -Origin* DatumElement::getOrigin() +bool DatumElement::getCameraAlignmentDirection(Base::Vector3d& direction, const char* subname) const +{ + Q_UNUSED(subname); + Placement.getValue().getRotation().multVec(Base::Vector3d(0., 0., 1.), direction); + + return true; +} + +App::LocalCoordinateSystem* DatumElement::getLCS() +{ + auto inList = getInList(); + for (auto* obj : inList) { + auto* lcs = dynamic_cast(obj); + if (lcs) { + return lcs; + } + } + + return nullptr; +} + +bool DatumElement::isOriginFeature() +{ + auto lcs = getLCS(); + return lcs ? lcs->isOrigin() : false; +} + +// ---------------------------------------------------------------------------- + +LocalCoordinateSystem::LocalCoordinateSystem() + : extension(this) +{ + ADD_PROPERTY_TYPE(OriginFeatures, + (nullptr), + 0, + App::Prop_Hidden, + "Axis and baseplanes controlled by the LCS"); + + setStatus(App::NoAutoExpand, true); + extension.initExtension(this); +} + + +LocalCoordinateSystem::~LocalCoordinateSystem() = default; + +bool LocalCoordinateSystem::getCameraAlignmentDirection(Base::Vector3d& direction, + const char* subname) const +{ + Q_UNUSED(subname); + Placement.getValue().getRotation().multVec(Base::Vector3d(0., 0., 1.), direction); + + return true; +} + +App::DatumElement* LocalCoordinateSystem::getDatumElement(const char* role) const +{ + const auto& features = OriginFeatures.getValues(); + auto featIt = std::find_if(features.begin(), features.end(), [role](App::DocumentObject* obj) { + return obj->isDerivedFrom(App::DatumElement::getClassTypeId()) + && strcmp(static_cast(obj)->Role.getValue(), role) == 0; + }); + if (featIt != features.end()) { + return static_cast(*featIt); + } + std::stringstream err; + err << "LocalCoordinateSystem \"" << getFullName() << "\" doesn't contain feature with role \"" + << role << '"'; + throw Base::RuntimeError(err.str().c_str()); +} + +App::Line* LocalCoordinateSystem::getAxis(const char* role) const +{ + App::DatumElement* feat = getDatumElement(role); + if (feat->isDerivedFrom(App::Line::getClassTypeId())) { + return static_cast(feat); + } + std::stringstream err; + err << "LocalCoordinateSystem \"" << getFullName() << "\" contains bad Axis object for role \"" + << role << '"'; + throw Base::RuntimeError(err.str().c_str()); +} + +App::Plane* LocalCoordinateSystem::getPlane(const char* role) const +{ + App::DatumElement* feat = getDatumElement(role); + if (feat->isDerivedFrom(App::Plane::getClassTypeId())) { + return static_cast(feat); + } + std::stringstream err; + err << "LocalCoordinateSystem \"" << getFullName() << "\" contains bad Plane object for role \"" + << role << '"'; + throw Base::RuntimeError(err.str().c_str()); +} + +App::Point* LocalCoordinateSystem::getPoint(const char* role) const +{ + App::DatumElement* feat = getDatumElement(role); + if (feat->isDerivedFrom(App::Point::getClassTypeId())) { + return static_cast(feat); + } + std::stringstream err; + err << "LocalCoordinateSystem \"" << getFullName() << "\" contains bad Point object for role \"" + << role << '"'; + throw Base::RuntimeError(err.str().c_str()); +} + +bool LocalCoordinateSystem::hasObject(const DocumentObject* obj) const +{ + const auto& features = OriginFeatures.getValues(); + return std::find(features.begin(), features.end(), obj) != features.end(); +} + +short LocalCoordinateSystem::mustExecute() const +{ + if (OriginFeatures.isTouched()) { + return 1; + } + return DocumentObject::mustExecute(); +} + +App::DocumentObjectExecReturn* LocalCoordinateSystem::execute() +{ + try { // try to find all base axis and planes in the origin + for (const char* role : AxisRoles) { + App::Line* axis = getAxis(role); + assert(axis); + (void)axis; + } + for (const char* role : PlaneRoles) { + App::Plane* plane = getPlane(role); + assert(plane); + (void)plane; + } + } + catch (const Base::Exception& ex) { + setError(); + return new App::DocumentObjectExecReturn(ex.what()); + } + + return DocumentObject::execute(); +} + +const std::vector& LocalCoordinateSystem::getSetupData() +{ + static const std::vector setupData = { + // clang-format off + {App::Line::getClassTypeId(), AxisRoles[0], tr("X-axis"), Base::Rotation()}, + {App::Line::getClassTypeId(), AxisRoles[1], tr("Y-axis"), Base::Rotation(Base::Vector3d(1, 1, 1), M_PI * 2 / 3)}, + {App::Line::getClassTypeId(), AxisRoles[2], tr("Z-axis"), Base::Rotation(Base::Vector3d(1,-1, 1), M_PI * 2 / 3)}, + {App::Plane::getClassTypeId(), PlaneRoles[0], tr("XY-plane"), Base::Rotation()}, + {App::Plane::getClassTypeId(), PlaneRoles[1], tr("XZ-plane"), Base::Rotation(1.0, 0.0, 0.0, 1.0)}, + {App::Plane::getClassTypeId(), PlaneRoles[2], tr("YZ-plane"), Base::Rotation(Base::Vector3d(1, 1, 1), M_PI * 2 / 3)}, + {App::Point::getClassTypeId(), PointRoles[0], tr("Origin"), Base::Rotation()} + // clang-format on + }; + return setupData; +} + +DatumElement* LocalCoordinateSystem::createDatum(SetupData& data) { App::Document* doc = getDocument(); - auto origins = doc->getObjectsOfType(App::Origin::getClassTypeId()); + std::string objName = doc->getUniqueObjectName(data.role); + App::DocumentObject* featureObj = doc->addObject(data.type.getName(), objName.c_str()); - auto originIt = std::find_if(origins.begin(), origins.end(), [this](DocumentObject* origin) { - assert(origin->isDerivedFrom(App::Origin::getClassTypeId())); - return static_cast(origin)->hasObject(this); - }); - if (originIt == origins.end()) { - return nullptr; + assert(featureObj && featureObj->isDerivedFrom(App::DatumElement::getClassTypeId())); + + QByteArray byteArray = data.label.toUtf8(); + featureObj->Label.setValue(byteArray.constData()); + + auto* feature = static_cast(featureObj); + feature->Placement.setValue(Base::Placement(Base::Vector3d(), data.rot)); + feature->Role.setValue(data.role); + + feature->Placement.setStatus(Property::Hidden, true); + return feature; +} + +LocalCoordinateSystem::SetupData LocalCoordinateSystem::getData(const char* role) +{ + const auto& setupData = getSetupData(); + for (auto data : setupData) { + if (std::strcmp(role, data.role) == 0) { + return data; + } } - else { - assert((*originIt)->isDerivedFrom(App::Origin::getClassTypeId())); - return static_cast(*originIt); + return LocalCoordinateSystem::SetupData(); +} + +void LocalCoordinateSystem::setupObject() +{ + std::vector links; + const auto& setupData = getSetupData(); + for (auto data : setupData) { + links.push_back(createDatum(data)); + } + + OriginFeatures.setValues(links); +} + +void LocalCoordinateSystem::unsetupObject() +{ + const auto& objsLnk = OriginFeatures.getValues(); + // Copy to set to assert we won't call method more then one time for each object + std::set objs(objsLnk.begin(), objsLnk.end()); + // Remove all controlled objects + for (auto obj : objs) { + // Check that previous deletes didn't indirectly remove one of our objects + const auto& objsLnk = OriginFeatures.getValues(); + if (std::find(objsLnk.begin(), objsLnk.end(), obj) != objsLnk.end()) { + if (!obj->isRemoving()) { + obj->getDocument()->removeObject(obj->getNameInDocument()); + } + } + } +} + +// ---------------------------------------------------------------------------- + +LocalCoordinateSystem::LCSExtension::LCSExtension(LocalCoordinateSystem* obj) + : obj(obj) +{ + Group.setStatus(Property::Transient, true); +} + +void LocalCoordinateSystem::LCSExtension::initExtension(ExtensionContainer* obj) +{ + App::GroupExtension::initExtension(obj); +} + +bool LocalCoordinateSystem::LCSExtension::extensionGetSubObject(DocumentObject*& ret, + const char* subname, + PyObject** pyobj, + Base::Matrix4D* mat, + bool, + int depth) const +{ + if (!subname || subname[0] == '\0') { + return false; + } + + // mapping of object name to role name + std::string name(subname); + for (int i = 0; i < 3; i++) { + if (name.rfind(LocalCoordinateSystem::AxisRoles[i], 0) == 0) { + name = LocalCoordinateSystem::AxisRoles[i]; + break; + } + if (name.rfind(LocalCoordinateSystem::PlaneRoles[i], 0) == 0) { + name = LocalCoordinateSystem::PlaneRoles[i]; + break; + } + } + + if (name.rfind(LocalCoordinateSystem::PointRoles[0], 0) == 0) { + name = LocalCoordinateSystem::PointRoles[0]; + } + + try { + ret = obj->getDatumElement(name.c_str()); + if (!ret) { + return false; + } + const char* dot = strchr(subname, '.'); + if (dot) { + subname = dot + 1; + } + else { + subname = ""; + } + ret = ret->getSubObject(subname, pyobj, mat, true, depth + 1); + return true; + } + catch (const Base::Exception& e) { + e.ReportException(); + return false; } } diff --git a/src/App/Datums.h b/src/App/Datums.h index 5da3ffd8e6..ec10f26222 100644 --- a/src/App/Datums.h +++ b/src/App/Datums.h @@ -1,5 +1,7 @@ /*************************************************************************** - * Copyright (c) 2012 Jürgen Riegel * + * Copyright (c) 2015 Stefan Tröger * + * Copyright (c) 2015 Alexander Golubev (Fat-Zer) * + * Copyright (c) 2024 Ondsel (PL Boyer) * * * * This file is part of the FreeCAD CAx development system. * * * @@ -24,29 +26,37 @@ #define DATUMS_H #include "GeoFeature.h" +#include "GeoFeatureGroupExtension.h" +#include "QCoreApplication" + +namespace Base +{ +class Rotation; +} namespace App { +class LocalCoordinateSystem; -class Origin; - -/** Plane Object - * Used to define planar support for all kind of operations in the document space - */ class AppExport DatumElement: public App::GeoFeature { PROPERTY_HEADER_WITH_OVERRIDE(App::DatumElement); public: - /// additional information about the feature usage (e.g. "BasePlane-XY" or "Axis-X" in a Origin) + /// additional information about the feature usage (e.g. "BasePlane-XY" or "Axis-X") PropertyString Role; /// Constructor - DatumElement(); + DatumElement(bool hideRole = true); ~DatumElement() override; /// Finds the origin object this plane belongs to - App::Origin* getOrigin(); + App::LocalCoordinateSystem* getLCS(); + + bool getCameraAlignmentDirection(Base::Vector3d& direction, const char* subname) const override; + + /// Returns true if this DatumElement is part of a App::Origin. + bool isOriginFeature(); }; class AppExport Plane: public App::DatumElement @@ -71,6 +81,172 @@ public: } }; +class AppExport Point: public App::DatumElement +{ + PROPERTY_HEADER_WITH_OVERRIDE(App::DatumElement); + +public: + const char* getViewProviderName() const override + { + return "Gui::ViewProviderPoint"; + } +}; + + +class AppExport LocalCoordinateSystem: public App::GeoFeature +{ + PROPERTY_HEADER_WITH_OVERRIDE(App::LocalCoordinateSystem); + Q_DECLARE_TR_FUNCTIONS(App::LocalCoordinateSystem) + +public: + /// Constructor + LocalCoordinateSystem(); + ~LocalCoordinateSystem() override; + + /// returns the type name of the ViewProvider + const char* getViewProviderName() const override + { + return "Gui::ViewProviderOrigin"; + } + + bool getCameraAlignmentDirection(Base::Vector3d& direction, const char* subname) const override; + + /** @name Axis and plane access + * This functions returns casted axis and planes objects and asserts they are set correctly + * otherwise Base::Exception is thrown. + */ + ///@{ + // returns origin point + App::Point* getOrigin() const + { + return getPoint(PointRoles[0]); + } + + // returns X axis + App::Line* getX() const + { + return getAxis(AxisRoles[0]); + } + // returns Y axis + App::Line* getY() const + { + return getAxis(AxisRoles[1]); + } + // returns Z axis + App::Line* getZ() const + { + return getAxis(AxisRoles[2]); + } + + // returns XY plane + App::Plane* getXY() const + { + return getPlane(PlaneRoles[0]); + } + // returns XZ plane + App::Plane* getXZ() const + { + return getPlane(PlaneRoles[1]); + } + // returns YZ plane + App::Plane* getYZ() const + { + return getPlane(PlaneRoles[2]); + } + + /// Returns all axis objects to iterate on them + std::vector axes() const + { + return {getX(), getY(), getZ()}; + } + + /// Returns all base planes objects to iterate on them + std::vector planes() const + { + return {getXY(), getXZ(), getYZ()}; + } + + /// Returns all controlled objects (both planes and axis) to iterate on them + std::vector baseObjects() const + { + return {getX(), getY(), getZ(), getXY(), getXZ(), getYZ(), getOrigin()}; + } + + /// Returns an axis by it's name + App::DatumElement* getDatumElement(const char* role) const; + + /// Returns an axis by it's name + App::Line* getAxis(const char* role) const; + + /// Returns an axis by it's name + App::Plane* getPlane(const char* role) const; + + /// Returns a point by it's name + App::Point* getPoint(const char* role) const; + ///@} + + /// Returns true if the given object is part of the origin + bool hasObject(const DocumentObject* obj) const; + + /// Returns true on changing DatumElement set + short mustExecute() const override; + + /// Axis types + static constexpr const char* AxisRoles[3] = {"X_Axis", "Y_Axis", "Z_Axis"}; + /// Baseplane types + static constexpr const char* PlaneRoles[3] = {"XY_Plane", "XZ_Plane", "YZ_Plane"}; + /// Points types + static constexpr const char* PointRoles[1] = {"Origin"}; + + virtual bool isOrigin() + { + return false; + }; + + // Axis links + PropertyLinkList OriginFeatures; + +protected: + /// Checks integrity of the LCS + App::DocumentObjectExecReturn* execute() override; + /// Creates all corresponding Axes and Planes objects for the LCS if they aren't linked yet + void setupObject() override; + /// Removes all planes and axis if they are still linked to the document + void unsetupObject() override; + +private: + struct SetupData; + void setupDatumElement(App::PropertyLink& featProp, const SetupData& data); + + class LCSExtension: public GeoFeatureGroupExtension + { + LocalCoordinateSystem* obj; + + public: + explicit LCSExtension(LocalCoordinateSystem* obj); + void initExtension(ExtensionContainer* obj) override; + bool extensionGetSubObject(DocumentObject*& ret, + const char* subname, + PyObject**, + Base::Matrix4D*, + bool, + int) const override; + }; + LCSExtension extension; + + struct SetupData + { + Base::Type type; + const char* role = nullptr; + QString label; + Base::Rotation rot; + }; + static const std::vector& getSetupData(); + + DatumElement* createDatum(SetupData& data); + SetupData getData(const char* role); +}; + } // namespace App #endif /* end of include guard: DATUMS_H */ diff --git a/src/App/Graphviz.cpp b/src/App/Graphviz.cpp index 176339d168..5a09a9e3ee 100644 --- a/src/App/Graphviz.cpp +++ b/src/App/Graphviz.cpp @@ -312,7 +312,10 @@ void Document::exportGraphviz(std::ostream& out) const } if (!sgraph) { if (docObj->isDerivedFrom(DatumElement::getClassTypeId())) { - sgraph = GraphList[static_cast(docObj)->getOrigin()]; + auto* lcs = static_cast(docObj)->getLCS(); + if (lcs) { + sgraph = GraphList[lcs]; + } } } } diff --git a/src/App/Origin.cpp b/src/App/Origin.cpp index fe8254bd92..4f5cbf3c65 100644 --- a/src/App/Origin.cpp +++ b/src/App/Origin.cpp @@ -23,240 +23,19 @@ #include "PreCompiled.h" -#ifndef _PreComp_ -#include -#endif - #include -#include #include #include "Origin.h" -#include "Datums.h" - - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif using namespace App; - -PROPERTY_SOURCE(App::Origin, App::DocumentObject) +PROPERTY_SOURCE(App::Origin, App::LocalCoordinateSystem) Origin::Origin() - : extension(this) { - ADD_PROPERTY_TYPE(OriginFeatures, - (nullptr), - 0, - App::Prop_Hidden, - "Axis and baseplanes controlled by the origin"); - - setStatus(App::NoAutoExpand, true); - extension.initExtension(this); + // App::Origin is a LCS for which placement is fixed to identity. + Placement.setStatus(Property::Hidden, true); } - Origin::~Origin() = default; - -App::DatumElement* Origin::getOriginFeature(const char* role) const -{ - const auto& features = OriginFeatures.getValues(); - auto featIt = std::find_if(features.begin(), features.end(), [role](App::DocumentObject* obj) { - return obj->isDerivedFrom(App::DatumElement::getClassTypeId()) - && strcmp(static_cast(obj)->Role.getValue(), role) == 0; - }); - if (featIt != features.end()) { - return static_cast(*featIt); - } - else { - - std::stringstream err; - err << "Origin \"" << getFullName() << "\" doesn't contain feature with role \"" << role - << '"'; - throw Base::RuntimeError(err.str().c_str()); - } -} - -App::Line* Origin::getAxis(const char* role) const -{ - App::DatumElement* feat = getOriginFeature(role); - if (feat->isDerivedFrom(App::Line::getClassTypeId())) { - return static_cast(feat); - } - else { - std::stringstream err; - err << "Origin \"" << getFullName() << "\" contains bad Axis object for role \"" << role - << '"'; - throw Base::RuntimeError(err.str().c_str()); - } -} - -App::Plane* Origin::getPlane(const char* role) const -{ - App::DatumElement* feat = getOriginFeature(role); - if (feat->isDerivedFrom(App::Plane::getClassTypeId())) { - return static_cast(feat); - } - else { - std::stringstream err; - err << "Origin \"" << getFullName() << "\" contains bad Plane object for role \"" << role - << '"'; - throw Base::RuntimeError(err.str().c_str()); - } -} - -bool Origin::hasObject(const DocumentObject* obj) const -{ - const auto& features = OriginFeatures.getValues(); - return std::find(features.begin(), features.end(), obj) != features.end(); -} - -short Origin::mustExecute() const -{ - if (OriginFeatures.isTouched()) { - return 1; - } - else { - return DocumentObject::mustExecute(); - } -} - -App::DocumentObjectExecReturn* Origin::execute() -{ - try { // try to find all base axis and planes in the origin - for (const char* role : AxisRoles) { - App::Line* axis = getAxis(role); - assert(axis); - (void)axis; - } - for (const char* role : PlaneRoles) { - App::Plane* plane = getPlane(role); - assert(plane); - (void)plane; - } - } - catch (const Base::Exception& ex) { - setError(); - return new App::DocumentObjectExecReturn(ex.what()); - } - - return DocumentObject::execute(); -} - -void Origin::setupObject() -{ - const static struct - { - const Base::Type type; - const char* role; - const QString label; - Base::Rotation rot; - } setupData[] = { - // clang-format off - {App::Line::getClassTypeId(), AxisRoles[0], tr("X-axis"), Base::Rotation()}, - {App::Line::getClassTypeId(), AxisRoles[1], tr("Y-axis"), Base::Rotation(Base::Vector3d(1,1,1), M_PI*2/3)}, - {App::Line::getClassTypeId(), AxisRoles[2], tr("Z-axis"), Base::Rotation(Base::Vector3d(1,-1,1), M_PI*2/3)}, - {App::Plane::getClassTypeId(), PlaneRoles[0], tr("XY-plane"), Base::Rotation()}, - {App::Plane::getClassTypeId(), PlaneRoles[1], tr("XZ-plane"), Base::Rotation(1.0, 0.0, 0.0, 1.0 )}, - {App::Plane::getClassTypeId(), PlaneRoles[2], tr("YZ-plane"), Base::Rotation(Base::Vector3d(1,1,1), M_PI*2/3)} - // clang-format on - }; - - App::Document* doc = getDocument(); - - std::vector links; - for (auto data : setupData) { - std::string objName = doc->getUniqueObjectName(data.role); - App::DocumentObject* featureObj = doc->addObject(data.type.getName(), objName.c_str()); - - assert(featureObj && featureObj->isDerivedFrom(App::DatumElement::getClassTypeId())); - - QByteArray byteArray = data.label.toUtf8(); - featureObj->Label.setValue(byteArray.constData()); - - App::DatumElement* feature = static_cast(featureObj); - feature->Placement.setValue(Base::Placement(Base::Vector3d(), data.rot)); - feature->Role.setValue(data.role); - - links.push_back(feature); - } - - OriginFeatures.setValues(links); -} - -void Origin::unsetupObject() -{ - const auto& objsLnk = OriginFeatures.getValues(); - // Copy to set to assert we won't call methode more then one time for each object - std::set objs(objsLnk.begin(), objsLnk.end()); - // Remove all controlled objects - for (auto obj : objs) { - // Check that previous deletes wasn't inderectly removed one of our objects - const auto& objsLnk = OriginFeatures.getValues(); - if (std::find(objsLnk.begin(), objsLnk.end(), obj) != objsLnk.end()) { - if (!obj->isRemoving()) { - obj->getDocument()->removeObject(obj->getNameInDocument()); - } - } - } -} - -// ---------------------------------------------------------------------------- - -Origin::OriginExtension::OriginExtension(Origin* obj) - : obj(obj) -{ - Group.setStatus(Property::Transient, true); -} - -void Origin::OriginExtension::initExtension(ExtensionContainer* obj) -{ - App::GroupExtension::initExtension(obj); -} - -bool Origin::OriginExtension::extensionGetSubObject(DocumentObject*& ret, - const char* subname, - PyObject** pyobj, - Base::Matrix4D* mat, - bool, - int depth) const -{ - if (!subname || subname[0] == '\0') { - return false; - } - - // mapping of object name to role name - std::string name(subname); - for (int i = 0; i < 3; i++) { - if (name.rfind(Origin::AxisRoles[i], 0) == 0) { - name = Origin::AxisRoles[i]; - break; - } - if (name.rfind(Origin::PlaneRoles[i], 0) == 0) { - name = Origin::PlaneRoles[i]; - break; - } - } - - try { - ret = obj->getOriginFeature(name.c_str()); - if (!ret) { - return false; - } - const char* dot = strchr(subname, '.'); - if (dot) { - subname = dot + 1; - } - else { - subname = ""; - } - ret = ret->getSubObject(subname, pyobj, mat, true, depth + 1); - return true; - } - catch (const Base::Exception& e) { - e.ReportException(); - return false; - } -} diff --git a/src/App/Origin.h b/src/App/Origin.h index 68aeca6a4c..86bb46172f 100644 --- a/src/App/Origin.h +++ b/src/App/Origin.h @@ -26,16 +26,13 @@ #define APP_Origin_H #include "Datums.h" -#include "GeoFeatureGroupExtension.h" - -#include "QCoreApplication" namespace App { /** Base class of all geometric document objects. */ -class AppExport Origin: public App::DocumentObject +class AppExport Origin: public App::LocalCoordinateSystem { PROPERTY_HEADER_WITH_OVERRIDE(App::Origin); Q_DECLARE_TR_FUNCTIONS(App::Origin) @@ -51,116 +48,10 @@ public: return "Gui::ViewProviderOrigin"; } - /** @name Axis and plane access - * This functions returns casted axis and planes objects and asserts they are set correctly - * otherwise Base::Exception is thrown. - */ - ///@{ - // returns X axis - App::Line* getX() const + bool isOrigin() override { - return getAxis(AxisRoles[0]); - } - // returns Y axis - App::Line* getY() const - { - return getAxis(AxisRoles[1]); - } - // returns Z axis - App::Line* getZ() const - { - return getAxis(AxisRoles[2]); - } - - // returns XY plane - App::Plane* getXY() const - { - return getPlane(PlaneRoles[0]); - } - // returns XZ plane - App::Plane* getXZ() const - { - return getPlane(PlaneRoles[1]); - } - // returns YZ plane - App::Plane* getYZ() const - { - return getPlane(PlaneRoles[2]); - } - - /// Returns all axis objects to iterate on them - std::vector axes() const - { - return {getX(), getY(), getZ()}; - } - - /// Returns all base planes objects to iterate on them - std::vector planes() const - { - return {getXY(), getXZ(), getYZ()}; - } - - /// Returns all controlled objects (both planes and axis) to iterate on them - std::vector baseObjects() const - { - return {getX(), getY(), getZ(), getXY(), getXZ(), getYZ()}; - } - - /// Returns an axis by it's name - App::DatumElement* getOriginFeature(const char* role) const; - - /// Returns an axis by it's name - App::Line* getAxis(const char* role) const; - - /// Returns an axis by it's name - App::Plane* getPlane(const char* role) const; - ///@} - - /// Returns true if the given object is part of the origin - bool hasObject(const DocumentObject* obj) const; - - /// Returns the default bounding box of the origin (use this if you confused what should be s ) - // TODO Delete me if not really needed (2015-09-01, Fat-Zer) - static Base::BoundBox3d defaultBoundBox(); - - /// Returns true on changing OriginFeature set - short mustExecute() const override; - - /// Axis types - static constexpr const char* AxisRoles[3] = {"X_Axis", "Y_Axis", "Z_Axis"}; - /// Baseplane types - static constexpr const char* PlaneRoles[3] = {"XY_Plane", "XZ_Plane", "YZ_Plane"}; - - // Axis links - PropertyLinkList OriginFeatures; - -protected: - /// Checks integrity of the Origin - App::DocumentObjectExecReturn* execute() override; - /// Creates all corresponding Axes and Planes objects for the origin if they aren't linked yet - void setupObject() override; - /// Removes all planes and axis if they are still linked to the document - void unsetupObject() override; - -private: - struct SetupData; - void setupOriginFeature(App::PropertyLink& featProp, const SetupData& data); - - class OriginExtension: public GeoFeatureGroupExtension - { - Origin* obj; - - public: - explicit OriginExtension(Origin* obj); - void initExtension(ExtensionContainer* obj) override; - bool extensionGetSubObject(DocumentObject*& ret, - const char* subname, - PyObject**, - Base::Matrix4D*, - bool, - int) const override; + return true; }; - OriginExtension extension; }; } // namespace App diff --git a/src/App/OriginGroupExtension.cpp b/src/App/OriginGroupExtension.cpp index 9dabd2475e..369db51bad 100644 --- a/src/App/OriginGroupExtension.cpp +++ b/src/App/OriginGroupExtension.cpp @@ -121,7 +121,8 @@ App::DocumentObject* OriginGroupExtension::getGroupOfObject(const DocumentObject if (o->hasExtension(App::OriginGroupExtension::getExtensionClassTypeId())) { return o; } - else if (isOriginFeature && o->isDerivedFrom(App::Origin::getClassTypeId())) { + else if (isOriginFeature + && o->isDerivedFrom(App::LocalCoordinateSystem::getClassTypeId())) { auto result = getGroupOfObject(o); if (result) { return result; @@ -221,16 +222,24 @@ void OriginGroupExtension::relinkToOrigin(App::DocumentObject* obj) std::vector result; std::vector list; obj->getPropertyList(list); + auto isOriginFeature = [](App::DocumentObject* obj) -> bool { + // Check if the object is a DatumElement + if (auto* datumElement = dynamic_cast(obj)) { + // Check if the DatumElement is an origin + return datumElement->isOriginFeature(); + } + return false; + }; + for (App::Property* prop : list) { if (prop->isDerivedFrom()) { auto p = static_cast(prop); - if (!p->getValue() - || !p->getValue()->isDerivedFrom(App::DatumElement::getClassTypeId())) { + if (!p->getValue() || !isOriginFeature(p->getValue())) { continue; } - p->setValue(getOrigin()->getOriginFeature( + p->setValue(getOrigin()->getDatumElement( static_cast(p->getValue())->Role.getValue())); } else if (prop->isDerivedFrom()) { @@ -239,11 +248,11 @@ void OriginGroupExtension::relinkToOrigin(App::DocumentObject* obj) std::vector result; bool changed = false; for (App::DocumentObject* o : vec) { - if (!o || !o->isDerivedFrom(App::DatumElement::getClassTypeId())) { + if (!isOriginFeature(o)) { result.push_back(o); } else { - result.push_back(getOrigin()->getOriginFeature( + result.push_back(getOrigin()->getDatumElement( static_cast(o)->Role.getValue())); changed = true; } @@ -254,13 +263,12 @@ void OriginGroupExtension::relinkToOrigin(App::DocumentObject* obj) } else if (prop->isDerivedFrom()) { auto p = static_cast(prop); - if (!p->getValue() - || !p->getValue()->isDerivedFrom(App::DatumElement::getClassTypeId())) { + if (!p->getValue() || !isOriginFeature(p->getValue())) { continue; } std::vector subValues = p->getSubValues(); - p->setValue(getOrigin()->getOriginFeature( + p->setValue(getOrigin()->getDatumElement( static_cast(p->getValue())->Role.getValue()), subValues); } @@ -269,8 +277,8 @@ void OriginGroupExtension::relinkToOrigin(App::DocumentObject* obj) auto vec = p->getSubListValues(); bool changed = false; for (auto& v : vec) { - if (v.first && v.first->isDerivedFrom(App::DatumElement::getClassTypeId())) { - v.first = getOrigin()->getOriginFeature( + if (isOriginFeature(v.first)) { + v.first = getOrigin()->getDatumElement( static_cast(v.first)->Role.getValue()); changed = true; } diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 90934ca6b2..6492e2b839 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -120,6 +120,7 @@ #include "ViewProviderOriginGroup.h" #include "ViewProviderPlacement.h" #include "ViewProviderPlane.h" +#include "ViewProviderPoint.h" #include "ViewProviderPart.h" #include "ViewProviderFeaturePython.h" #include "ViewProviderTextDocument.h" @@ -2070,6 +2071,7 @@ void Application::initTypes() Gui::ViewProviderPlacementPython ::init(); Gui::ViewProviderDatum ::init(); Gui::ViewProviderPlane ::init(); + Gui::ViewProviderPoint ::init(); Gui::ViewProviderLine ::init(); Gui::ViewProviderGeoFeatureGroup ::init(); Gui::ViewProviderGeoFeatureGroupPython ::init(); diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index dda0c341c0..a62637ee30 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -963,6 +963,7 @@ SET(Viewprovider_CPP_SRCS ViewProviderPlacement.cpp ViewProviderDatum.cpp ViewProviderPlane.cpp + ViewProviderPoint.cpp ViewProviderLine.cpp ViewProviderGeoFeatureGroup.cpp ViewProviderOriginGroup.cpp @@ -1000,6 +1001,7 @@ SET(Viewprovider_SRCS ViewProviderPlacement.h ViewProviderDatum.h ViewProviderPlane.h + ViewProviderPoint.h ViewProviderLine.h ViewProviderGeoFeatureGroup.h ViewProviderOriginGroup.h diff --git a/src/Gui/ViewProviderDatum.cpp b/src/Gui/ViewProviderDatum.cpp index ee968e64d9..3112ddab45 100644 --- a/src/Gui/ViewProviderDatum.cpp +++ b/src/Gui/ViewProviderDatum.cpp @@ -23,7 +23,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include +# include # include # include # include @@ -38,6 +38,7 @@ #include #include "ViewProviderDatum.h" +#include "Inventor/SoAxisCrossKit.h" #include "SoFCSelection.h" #include "ViewProviderOrigin.h" @@ -47,32 +48,28 @@ using namespace Gui; PROPERTY_SOURCE(Gui::ViewProviderDatum, Gui::ViewProviderGeometryObject) ViewProviderDatum::ViewProviderDatum() { - ADD_PROPERTY_TYPE(Size, (ViewProviderOrigin::defaultSize()), 0, App::Prop_ReadOnly, - QT_TRANSLATE_NOOP("App::Property", "Visual size of the feature")); - - ShapeAppearance.setDiffuseColor( - ViewProviderOrigin::defaultColor); // Set default color for origin (light-blue) + // Set default color for origin (light-blue) + ShapeAppearance.setDiffuseColor(ViewProviderOrigin::defaultColor); Transparency.setValue(0); BoundingBox.setStatus(App::Property::Hidden, true); // Hide Boundingbox from the user due to it doesn't make sense // Create node for scaling the origin - pScale = new SoScale(); - pScale->ref(); + soScale = new SoShapeScale(); // Create the separator filled by inherited classes - pOriginFeatureRoot = new SoSeparator(); - pOriginFeatureRoot->ref(); + pRoot = new SoSeparator(); + pRoot->ref(); // Create the Label node - pLabel = new SoAsciiText(); + pLabel = new SoText2(); pLabel->ref(); - pLabel->width.setValue(-1); + + lineThickness = 2.0; } ViewProviderDatum::~ViewProviderDatum() { - pScale->unref(); - pOriginFeatureRoot->unref(); + pRoot->unref(); pLabel->unref(); } @@ -82,7 +79,6 @@ void ViewProviderDatum::attach(App::DocumentObject* pcObject) ViewProviderGeometryObject::attach(pcObject); float defaultSz = ViewProviderOrigin::defaultSize(); - float sz = Size.getValue() / defaultSz; // Create an external separator auto sep = new SoSeparator(); @@ -95,31 +91,9 @@ void ViewProviderDatum::attach(App::DocumentObject* pcObject) matBinding->value = SoMaterialBinding::OVERALL; sep->addChild(matBinding); - // Scale feature to the given size - pScale->scaleFactor = SbVec3f(sz, sz, sz); - sep->addChild(pScale); - // Setup font size auto font = new SoFont(); - float fontRatio = 10.0f; - if (pcObject->is()) { - // keep font size on axes equal to font size on planes - fontRatio *= ViewProviderOrigin::axesScaling; - const char* axisName = pcObject->getNameInDocument(); - auto axisRoles = App::Origin::AxisRoles; - if (strncmp(axisName, axisRoles[0], strlen(axisRoles[0])) == 0) { - // X-axis: red - ShapeAppearance.setDiffuseColor(0xFF0000FF); - } - else if (strncmp(axisName, axisRoles[1], strlen(axisRoles[1])) == 0) { - // Y-axis: green - ShapeAppearance.setDiffuseColor(0x00FF00FF); - } - else if (strncmp(axisName, axisRoles[2], strlen(axisRoles[2])) == 0) { - // Z-axis: blue - ShapeAppearance.setDiffuseColor(0x0000FFFF); - } - } + float fontRatio = 4.0f; font->size.setValue(defaultSz / fontRatio); sep->addChild(font); @@ -135,46 +109,42 @@ void ViewProviderDatum::attach(App::DocumentObject* pcObject) // Style for normal (visible) lines auto style = new SoDrawStyle(); - style->lineWidth = 2.0f; + style->lineWidth = lineThickness; highlight->addChild(style); // Visible lines - highlight->addChild(pOriginFeatureRoot); + highlight->addChild(pRoot); // Hidden features auto hidden = new SoAnnotation(); // Style for hidden lines style = new SoDrawStyle(); - style->lineWidth = 2.0f; - style->linePattern.setValue(0xF000); // (dash-skip-skip-skip) + style->lineWidth = lineThickness; + style->linePattern.setValue(0xFF00); // (dash-skip) hidden->addChild(style); // Hidden lines - hidden->addChild(pOriginFeatureRoot); + hidden->addChild(pRoot); highlight->addChild(hidden); sep->addChild(highlight); - // Setup the object label as it's text - pLabel->string.setValue(SbString(pcObject->Label.getValue())); - addDisplayMaskMode(sep, "Base"); + // Scale feature to the given size + float sz = App::GetApplication() + .GetParameterGroupByPath("User parameter:BaseApp/Preferences/View") + ->GetFloat("LocalCoordinateSystemSize", 2.0); // NOLINT + + soScale->setPart("shape", sep); + soScale->scaleFactor = sz; + + addDisplayMaskMode(soScale, "Base"); } -void ViewProviderDatum::updateData(const App::Property* prop) { - if (prop == &getObject()->Label) { - pLabel->string.setValue(SbString(getObject()->Label.getValue())); - } - ViewProviderGeometryObject::updateData(prop); -} void ViewProviderDatum::onChanged(const App::Property* prop) { - if (prop == &Size) { - float sz = Size.getValue() / ViewProviderOrigin::defaultSize(); - pScale->scaleFactor = SbVec3f(sz, sz, sz); - } ViewProviderGeometryObject::onChanged(prop); } @@ -188,19 +158,14 @@ std::vector ViewProviderDatum::getDisplayModes() const void ViewProviderDatum::setDisplayMode(const char* ModeName) { - if (strcmp(ModeName, "Base") == 0) + if (strcmp(ModeName, "Base") == 0) { setDisplayMaskMode("Base"); + } ViewProviderGeometryObject::setDisplayMode(ModeName); } bool ViewProviderDatum::onDelete(const std::vector&) { auto feat = static_cast (getObject()); // Forbid deletion if there is an origin this feature belongs to - - if (feat->getOrigin()) { - return false; - } - else { - return true; - } + return !feat->getLCS(); } diff --git a/src/Gui/ViewProviderDatum.h b/src/Gui/ViewProviderDatum.h index 8da935262f..857037ae28 100644 --- a/src/Gui/ViewProviderDatum.h +++ b/src/Gui/ViewProviderDatum.h @@ -25,12 +25,14 @@ #include "ViewProviderGeometryObject.h" -class SoAsciiText; +class SoText2; class SoScale; namespace Gui { + class SoShapeScale; + /** * View provider associated with an App::DatumElement. */ @@ -38,20 +40,16 @@ namespace Gui PROPERTY_HEADER_WITH_OVERRIDE(Gui::ViewProviderDatum); public: - /// The display size of the feature - App::PropertyFloat Size; - ViewProviderDatum(); ~ViewProviderDatum() override; /// Get point derived classes will add their specific stuff - SoSeparator* getOriginFeatureRoot() { return pOriginFeatureRoot; } + SoSeparator* getRoot() { return pRoot; } /// Get pointer to the text label associated with the feature - SoAsciiText* getLabel() { return pLabel; } + SoText2* getLabel() { return pLabel; } void attach(App::DocumentObject*) override; - void updateData(const App::Property*) override; std::vector getDisplayModes() const override; void setDisplayMode(const char* ModeName) override; @@ -69,9 +67,10 @@ namespace Gui void onChanged(const App::Property* prop) override; bool onDelete(const std::vector&) override; protected: - SoSeparator* pOriginFeatureRoot; - SoScale* pScale; - SoAsciiText* pLabel; + SoSeparator* pRoot; + SoShapeScale* soScale; + SoText2* pLabel; + double lineThickness; }; } /* Gui */ diff --git a/src/Gui/ViewProviderLine.cpp b/src/Gui/ViewProviderLine.cpp index 7b13c44908..042bff7f38 100644 --- a/src/Gui/ViewProviderLine.cpp +++ b/src/Gui/ViewProviderLine.cpp @@ -24,6 +24,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include # include # include # include @@ -32,6 +33,9 @@ # include #endif +#include +#include + #include "ViewProviderLine.h" #include "ViewProviderOrigin.h" @@ -51,14 +55,46 @@ ViewProviderLine::~ViewProviderLine() = default; void ViewProviderLine::attach(App::DocumentObject *obj) { ViewProviderDatum::attach(obj); - static const float size = ViewProviderOrigin::defaultSize (); + // Setup label text and line colors + const char* name = pcObject->getNameInDocument(); - static const SbVec3f verts[2] = { SbVec3f(size, 0, 0), SbVec3f ( -size, 0, 0 ) }; + bool noRole = false; + auto axisRoles = App::LocalCoordinateSystem::AxisRoles; + if (strncmp(name, axisRoles[0], strlen(axisRoles[0])) == 0) { + // X-axis: red + ShapeAppearance.setDiffuseColor(ViewParams::instance()->getAxisXColor()); + pLabel->string.setValue(SbString("X")); + } + else if (strncmp(name, axisRoles[1], strlen(axisRoles[1])) == 0) { + // Y-axis: green + ShapeAppearance.setDiffuseColor(ViewParams::instance()->getAxisYColor()); + pLabel->string.setValue(SbString("Y")); + } + else if (strncmp(name, axisRoles[2], strlen(axisRoles[2])) == 0) { + // Z-axis: blue + ShapeAppearance.setDiffuseColor(ViewParams::instance()->getAxisZColor()); + pLabel->string.setValue(SbString("Z")); + } + else { + noRole = true; + } + + static const float size = ViewProviderOrigin::defaultSize(); + + SbVec3f verts[2]; + if (noRole) { + verts[0] = SbVec3f(2 * size, 0, 0); + verts[1] = SbVec3f(0, 0, 0); + } + else { + verts[0] = SbVec3f(size, 0, 0); + verts[1] = SbVec3f(0.2 * size, 0, 0); + } // indexes used to create the edges static const int32_t lines[4] = { 0, 1, -1 }; - SoSeparator *sep = getOriginFeatureRoot (); + SoSeparator *sep = getRoot(); auto pCoords = new SoCoordinate3 (); pCoords->point.setNum (2); @@ -71,11 +107,11 @@ void ViewProviderLine::attach(App::DocumentObject *obj) { sep->addChild ( pLines ); auto textTranslation = new SoTranslation (); - textTranslation->translation.setValue ( SbVec3f ( -size * 49. / 50., size / 30., 0 ) ); + textTranslation->translation.setValue ( SbVec3f ( size * 1.1, 0, 0 ) ); sep->addChild ( textTranslation ); auto ps = new SoPickStyle(); - ps->style.setValue(SoPickStyle::BOUNDING_BOX); + ps->style.setValue(SoPickStyle::SHAPE_ON_TOP); sep->addChild(ps); sep->addChild ( getLabel () ); diff --git a/src/Gui/ViewProviderOrigin.cpp b/src/Gui/ViewProviderOrigin.cpp index 5282836c1f..647bd52b79 100644 --- a/src/Gui/ViewProviderOrigin.cpp +++ b/src/Gui/ViewProviderOrigin.cpp @@ -39,22 +39,19 @@ #include "Document.h" #include "ViewProviderLine.h" #include "ViewProviderPlane.h" +#include "ViewProviderPoint.h" using namespace Gui; -PROPERTY_SOURCE(Gui::ViewProviderOrigin, Gui::ViewProviderDocumentObject) +PROPERTY_SOURCE(Gui::ViewProviderOrigin, Gui::ViewProviderGeoFeatureGroup) /** * Creates the view provider for an object group. */ ViewProviderOrigin::ViewProviderOrigin() { - ADD_PROPERTY_TYPE ( Size, (Base::Vector3d(10,10,10)), 0, App::Prop_None, - QT_TRANSLATE_NOOP("App::Property", "The displayed size of the origin")); - Size.setStatus(App::Property::ReadOnly, true); - sPixmap = "Std_CoordinateSystem"; Visibility.setValue(false); @@ -71,8 +68,9 @@ ViewProviderOrigin::~ViewProviderOrigin() { pcGroupChildren = nullptr; } -std::vector ViewProviderOrigin::claimChildren() const { - return static_cast( getObject() )->OriginFeatures.getValues (); +std::vector ViewProviderOrigin::claimChildren() const +{ + return static_cast( getObject() )->OriginFeatures.getValues(); } std::vector ViewProviderOrigin::claimChildren3D() const { @@ -128,7 +126,22 @@ void ViewProviderOrigin::setTemporaryVisibility(bool axis, bool plane) { } } } - } catch (const Base::Exception &ex) { + + // Remember & Set origin point visibility + App::DocumentObject* obj = origin->getOrigin(); + if (obj) { + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(obj); + if (vp) { + if (saveState) { + tempVisMap[vp] = vp->isVisible(); + } + vp->setVisible(plane); + } + } + + + } + catch (const Base::Exception &ex) { Base::Console().Error ("%s\n", ex.what() ); } @@ -148,70 +161,34 @@ void ViewProviderOrigin::resetTemporaryVisibility() { double ViewProviderOrigin::defaultSize() { ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); - return 0.25 * hGrp->GetFloat("NewDocumentCameraScale",100.0); + return hGrp->GetFloat("DatumsSize", 25); } bool ViewProviderOrigin::isTemporaryVisibility() { return !tempVisMap.empty(); } -void ViewProviderOrigin::onChanged(const App::Property* prop) { - if (prop == &Size) { - try { - Gui::Application *app = Gui::Application::Instance; - Base::Vector3d sz = Size.getValue (); - auto origin = static_cast ( getObject() ); - - // Calculate axes and planes sizes - double szXY = std::max ( sz.x, sz.y ); - double szXZ = std::max ( sz.x, sz.z ); - double szYZ = std::max ( sz.y, sz.z ); - - double szX = std::min ( szXY, szXZ ); - double szY = std::min ( szXY, szYZ ); - double szZ = std::min ( szXZ, szYZ ); - - // Find view providers - Gui::ViewProviderPlane* vpPlaneXY, *vpPlaneXZ, *vpPlaneYZ; - Gui::ViewProviderLine* vpLineX, *vpLineY, *vpLineZ; - // Planes - vpPlaneXY = static_cast ( app->getViewProvider ( origin->getXY () ) ); - vpPlaneXZ = static_cast ( app->getViewProvider ( origin->getXZ () ) ); - vpPlaneYZ = static_cast ( app->getViewProvider ( origin->getYZ () ) ); - // Axes - vpLineX = static_cast ( app->getViewProvider ( origin->getX () ) ); - vpLineY = static_cast ( app->getViewProvider ( origin->getY () ) ); - vpLineZ = static_cast ( app->getViewProvider ( origin->getZ () ) ); - - // set their sizes - if (vpPlaneXY) { vpPlaneXY->Size.setValue ( szXY ); } - if (vpPlaneXZ) { vpPlaneXZ->Size.setValue ( szXZ ); } - if (vpPlaneYZ) { vpPlaneYZ->Size.setValue ( szYZ ); } - if (vpLineX) { vpLineX->Size.setValue ( szX * axesScaling ); } - if (vpLineY) { vpLineY->Size.setValue ( szY * axesScaling ); } - if (vpLineZ) { vpLineZ->Size.setValue ( szZ * axesScaling ); } - - } catch (const Base::Exception &ex) { - // While restoring a document don't report errors if one of the lines or planes - // cannot be found. - App::Document* doc = getObject()->getDocument(); - if (!doc->testStatus(App::Document::Restoring)) - Base::Console().Error ("%s\n", ex.what() ); +void ViewProviderOrigin::updateData(const App::Property* prop) { + auto* jcs = dynamic_cast(getObject()); + if(jcs) { + if (prop == &jcs->Placement) { + // Update position } } - - ViewProviderDocumentObject::onChanged ( prop ); + ViewProviderDocumentObject::updateData(prop); } bool ViewProviderOrigin::onDelete(const std::vector &) { - auto origin = static_cast( getObject() ); + auto lcs = static_cast(getObject()); - if ( !origin->getInList().empty() ) { + auto origin = dynamic_cast(lcs); + if (origin && !origin->getInList().empty()) { + // Do not allow deletion of origin objects that are not lost. return false; } - auto objs = origin->OriginFeatures.getValues(); - origin->OriginFeatures.setValues({}); + auto objs = lcs->OriginFeatures.getValues(); + lcs->OriginFeatures.setValues({}); for (auto obj: objs ) { Gui::Command::doCommand( Gui::Command::Doc, "App.getDocument(\"%s\").removeObject(\"%s\")", diff --git a/src/Gui/ViewProviderOrigin.h b/src/Gui/ViewProviderOrigin.h index 4a7640951d..7145c2b842 100644 --- a/src/Gui/ViewProviderOrigin.h +++ b/src/Gui/ViewProviderOrigin.h @@ -26,21 +26,18 @@ #include -#include "ViewProviderDocumentObject.h" +#include "ViewProviderGeoFeatureGroup.h" namespace Gui { class Document; -class GuiExport ViewProviderOrigin : public ViewProviderDocumentObject +class GuiExport ViewProviderOrigin : public ViewProviderGeoFeatureGroup { PROPERTY_HEADER_WITH_OVERRIDE(Gui::ViewProviderOrigin); public: - /// Size of the origin as set by the part. - App::PropertyVector Size; - /// constructor. ViewProviderOrigin(); /// destructor. @@ -83,7 +80,7 @@ public: // default color for origini: light-blue (50, 150, 250, 255 stored as 0xRRGGBBAA) static const uint32_t defaultColor = 0x3296faff; protected: - void onChanged(const App::Property* prop) override; + void updateData(const App::Property*) override; bool onDelete(const std::vector &) override; private: diff --git a/src/Gui/ViewProviderOriginGroupExtension.cpp b/src/Gui/ViewProviderOriginGroupExtension.cpp index 522f74a8ab..9fbe4d4504 100644 --- a/src/Gui/ViewProviderOriginGroupExtension.cpp +++ b/src/Gui/ViewProviderOriginGroupExtension.cpp @@ -55,8 +55,6 @@ ViewProviderOriginGroupExtension::ViewProviderOriginGroupExtension() ViewProviderOriginGroupExtension::~ViewProviderOriginGroupExtension() { - connectChangedObjectApp.disconnect(); - connectChangedObjectGui.disconnect(); } std::vector ViewProviderOriginGroupExtension::constructChildren ( @@ -89,126 +87,6 @@ std::vector ViewProviderOriginGroupExtension::extensionCla return constructChildren ( ViewProviderGeoFeatureGroupExtension::extensionClaimChildren3D () ); } -void ViewProviderOriginGroupExtension::extensionAttach(App::DocumentObject *pcObject) { - ViewProviderGeoFeatureGroupExtension::extensionAttach ( pcObject ); - - App::Document *adoc = pcObject->getDocument (); - Gui::Document *gdoc = Gui::Application::Instance->getDocument ( adoc ) ; - - assert ( adoc ); - assert ( gdoc ); - - //NOLINTBEGIN - connectChangedObjectApp = adoc->signalChangedObject.connect ( - std::bind ( &ViewProviderOriginGroupExtension::slotChangedObjectApp, this, sp::_1) ); - - connectChangedObjectGui = gdoc->signalChangedObject.connect ( - std::bind ( &ViewProviderOriginGroupExtension::slotChangedObjectGui, this, sp::_1) ); - //NOLINTEND -} - -void ViewProviderOriginGroupExtension::extensionUpdateData( const App::Property* prop ) { - - auto* obj = getExtendedViewProvider()->getObject(); - auto* group = obj ? obj->getExtensionByType() : nullptr; - if ( group && prop == &group->Group ) { - updateOriginSize(); - } - - ViewProviderGeoFeatureGroupExtension::extensionUpdateData ( prop ); -} - -void ViewProviderOriginGroupExtension::slotChangedObjectApp ( const App::DocumentObject& obj) { - auto* ext = getExtendedViewProvider()->getObject(); - auto* group = ext ? ext->getExtensionByType() : nullptr; - if ( group && group->hasObject (&obj, /*recursive=*/ true ) ) { - updateOriginSize (); - } -} - -void ViewProviderOriginGroupExtension::slotChangedObjectGui ( const Gui::ViewProviderDocumentObject& vp) { - if ( !vp.isDerivedFrom ( Gui::ViewProviderDatum::getClassTypeId () )) { - // Ignore origins to avoid infinite recursion (not likely in a well-formed document, - // but may happen in documents designed in old versions of assembly branch ) - auto* ext = getExtendedViewProvider()->getObject(); - auto* group = ext ? ext->getExtensionByType() : nullptr; - App::DocumentObject *obj = vp.getObject (); - - if ( group && obj && group->hasObject (obj, /*recursive=*/ true ) ) { - updateOriginSize (); - } - } -} - -void ViewProviderOriginGroupExtension::updateOriginSize () { - auto owner = getExtendedViewProvider()->getObject(); - - if(!owner->isAttachedToDocument() || - owner->isRemoving() || - owner->getDocument()->testStatus(App::Document::Restoring)) - return; - - auto* group = owner->getExtensionByType(); - if(!group) - return; - - // obtain an Origin and it's ViewProvider - App::Origin* origin = nullptr; - Gui::ViewProviderOrigin* vpOrigin = nullptr; - try { - origin = group->getOrigin (); - assert (origin); - - Gui::ViewProvider *vp = Gui::Application::Instance->getViewProvider(origin); - if (!vp) { - Base::Console().Error ("No view provider linked to the Origin\n"); - return; - } - assert ( vp->isDerivedFrom ( Gui::ViewProviderOrigin::getClassTypeId () ) ); - vpOrigin = static_cast ( vp ); - } catch (const Base::Exception &ex) { - Base::Console().Error ("%s\n", ex.what() ); - return; - } - - Gui::Document* gdoc = getExtendedViewProvider()->getDocument(); - if(!gdoc) - return; - - Gui::MDIView* view = gdoc->getViewOfViewProvider(getExtendedViewProvider()); - if(!view) - return; - - Gui::View3DInventorViewer* viewer = static_cast(view)->getViewer(); - SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion()); - - // calculate the bounding box for out content - SbBox3f bbox(0,0,0, 0,0,0); - for(App::DocumentObject* obj : group->Group.getValues()) { - ViewProvider *vp = Gui::Application::Instance->getViewProvider(obj); - if (!vp) { - continue; - } - - bboxAction.apply ( vp->getRoot () ); - bbox.extendBy ( bboxAction.getBoundingBox () ); - }; - - // get the bounding box values - SbVec3f max = bbox.getMax(); - SbVec3f min = bbox.getMin(); - - Base::Vector3d size; - - for (uint_fast8_t i=0; i<3; i++) { - size[i] = std::max ( fabs ( max[i] ), fabs ( min[i] ) ); - if (size[i] < 1e-7) { // TODO replace the magic values (2015-08-31, Fat-Zer) - size[i] = ViewProviderOrigin::defaultSize(); - } - } - - vpOrigin->Size.setValue ( size * 1.3 ); -} namespace Gui { EXTENSION_PROPERTY_SOURCE_TEMPLATE(Gui::ViewProviderOriginGroupExtensionPython, Gui::ViewProviderOriginGroupExtension) diff --git a/src/Gui/ViewProviderOriginGroupExtension.h b/src/Gui/ViewProviderOriginGroupExtension.h index 00332627ff..09571ad323 100644 --- a/src/Gui/ViewProviderOriginGroupExtension.h +++ b/src/Gui/ViewProviderOriginGroupExtension.h @@ -42,21 +42,9 @@ public: std::vector extensionClaimChildren()const override; std::vector extensionClaimChildren3D()const override; - void extensionAttach(App::DocumentObject *pcObject) override; - void extensionUpdateData(const App::Property* prop) override; - - void updateOriginSize(); - -protected: - void slotChangedObjectApp ( const App::DocumentObject& obj ); - void slotChangedObjectGui ( const Gui::ViewProviderDocumentObject& obj ); - private: std::vector constructChildren ( const std::vector &children ) const; - - boost::signals2::connection connectChangedObjectApp; - boost::signals2::connection connectChangedObjectGui; }; using ViewProviderOriginGroupExtensionPython = ViewProviderExtensionPythonT; diff --git a/src/Gui/ViewProviderPlane.cpp b/src/Gui/ViewProviderPlane.cpp index d845ae9e1d..df92e14a93 100644 --- a/src/Gui/ViewProviderPlane.cpp +++ b/src/Gui/ViewProviderPlane.cpp @@ -24,6 +24,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include # include # include # include @@ -36,6 +37,9 @@ # include #endif +#include +#include + #include "ViewProviderPlane.h" #include "ViewProviderOrigin.h" @@ -48,43 +52,85 @@ PROPERTY_SOURCE(Gui::ViewProviderPlane, Gui::ViewProviderDatum) ViewProviderPlane::ViewProviderPlane() { sPixmap = "Std_Plane"; + lineThickness = 1.0; } ViewProviderPlane::~ViewProviderPlane() = default; void ViewProviderPlane::attach(App::DocumentObject * obj) { ViewProviderDatum::attach(obj); - static const float size = ViewProviderOrigin::defaultSize (); - static const SbVec3f verts[4] = { - SbVec3f(size,size,0), SbVec3f(size,-size,0), - SbVec3f(-size,-size,0), SbVec3f(-size,size,0), - }; + const char* name = pcObject->getNameInDocument(); + + // Setup colors + auto material = new SoMaterial(); + SbColor color; + material->transparency.setValue(0.95f); + float alpha = 0.0f; + float lineTransparency = 0.5; + bool noRole = false; + auto planesRoles = App::LocalCoordinateSystem::PlaneRoles; + if (strncmp(name, planesRoles[0], strlen(planesRoles[0])) == 0) { + // XY-axis: blue + ShapeAppearance.setDiffuseColor(ViewParams::instance()->getAxisZColor()); + ShapeAppearance.setTransparency(lineTransparency); + color.setPackedValue(ViewParams::instance()->getAxisZColor(), alpha); + } + else if (strncmp(name, planesRoles[1], strlen(planesRoles[1])) == 0) { + // XZ-axis: green + ShapeAppearance.setDiffuseColor(ViewParams::instance()->getAxisYColor()); + ShapeAppearance.setTransparency(lineTransparency); + color.setPackedValue(ViewParams::instance()->getAxisYColor(), alpha); + } + else if (strncmp(name, planesRoles[2], strlen(planesRoles[2])) == 0) { + // YZ-axis: red + ShapeAppearance.setDiffuseColor(ViewParams::instance()->getAxisXColor()); + ShapeAppearance.setTransparency(lineTransparency); + color.setPackedValue(ViewParams::instance()->getAxisXColor(), alpha); + } + else { + noRole = true; + } + + static const float size = ViewProviderOrigin::defaultSize() * 0.6; //NOLINT + static const float startSize = 0.25 * size; //NOLINT + + + SbVec3f verts[4]; + if (noRole) { + verts[0] = SbVec3f(size, size, 0); + verts[1] = SbVec3f(size, -size, 0); + verts[2] = SbVec3f(-size, -size, 0); + verts[3] = SbVec3f(-size, size, 0); + } + else { + verts[0] = SbVec3f(size, size, 0); + verts[1] = SbVec3f(size, startSize, 0); + verts[2] = SbVec3f(startSize, startSize, 0); + verts[3] = SbVec3f(startSize, size, 0); + } + // indexes used to create the edges static const int32_t lines[6] = { 0, 1, 2, 3, 0, -1 }; - SoSeparator *sep = getOriginFeatureRoot (); + SoSeparator* sep = getRoot(); - auto pCoords = new SoCoordinate3 (); - pCoords->point.setNum (4); - pCoords->point.setValues ( 0, 4, verts ); - sep->addChild ( pCoords ); + auto pCoords = new SoCoordinate3(); + pCoords->point.setNum(4); + pCoords->point.setValues(0, 4, verts); + sep->addChild(pCoords); - auto pLines = new SoIndexedLineSet (); + auto pLines = new SoIndexedLineSet(); pLines->coordIndex.setNum(6); pLines->coordIndex.setValues(0, 6, lines); - sep->addChild ( pLines ); + sep->addChild(pLines); // add semi transparent face auto faceSeparator = new SoSeparator(); sep->addChild(faceSeparator); - auto material = new SoMaterial(); - material->transparency.setValue(0.95f); - SbColor color; - float alpha = 0.0f; - color.setPackedValue(ViewProviderOrigin::defaultColor, alpha); + material->ambientColor.setValue(color); material->diffuseColor.setValue(color); faceSeparator->addChild(material); @@ -95,9 +141,8 @@ void ViewProviderPlane::attach(App::DocumentObject * obj) { shapeHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE; faceSeparator->addChild(shapeHints); - // disable picking auto pickStyle = new SoPickStyle(); - pickStyle->style = SoPickStyle::UNPICKABLE; + pickStyle->style = SoPickStyle::SHAPE_ON_TOP; faceSeparator->addChild(pickStyle); auto faceSet = new SoFaceSet(); @@ -106,13 +151,9 @@ void ViewProviderPlane::attach(App::DocumentObject * obj) { faceSet->vertexProperty.setValue(vertexProperty); faceSeparator->addChild(faceSet); - auto textTranslation = new SoTranslation (); - textTranslation->translation.setValue ( SbVec3f ( -size * 49. / 50., size * 9./10., 0 ) ); - sep->addChild ( textTranslation ); - auto ps = new SoPickStyle(); ps->style.setValue(SoPickStyle::BOUNDING_BOX); sep->addChild(ps); - sep->addChild ( getLabel () ); + sep->addChild(getLabel()); } diff --git a/src/Gui/ViewProviderPoint.cpp b/src/Gui/ViewProviderPoint.cpp new file mode 100644 index 0000000000..c8646495fd --- /dev/null +++ b/src/Gui/ViewProviderPoint.cpp @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/**************************************************************************** + * * + * Copyright (c) 2024 Ondsel (PL Boyer) * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * 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 Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +#endif + +#include "ViewProviderPoint.h" +#include "ViewProviderOrigin.h" + +using namespace Gui; + +PROPERTY_SOURCE(Gui::ViewProviderPoint, Gui::ViewProviderDatum) + +ViewProviderPoint::ViewProviderPoint() +{ + sPixmap = "Std_Point"; // Set the icon for the point +} + +ViewProviderPoint::~ViewProviderPoint() = default; + +void ViewProviderPoint::attach(App::DocumentObject * obj) { + ViewProviderDatum::attach(obj); + + // The coordinates for the point (single vertex at the origin) + static const SbVec3f point = SbVec3f(0, 0, 0); + + SoSeparator* sep = getRoot(); + + auto pCoords = new SoCoordinate3(); + pCoords->point.setNum(1); + pCoords->point.setValue(point); + sep->addChild(pCoords); + + auto sphere = new SoSphere(); + sphere->radius.setValue(1.0); + sep->addChild(sphere); + + // Add pick style to define how the point can be selected + auto ps = new SoPickStyle(); + ps->style.setValue(SoPickStyle::BOUNDING_BOX); + sep->addChild(ps); +} diff --git a/src/Gui/ViewProviderPoint.h b/src/Gui/ViewProviderPoint.h new file mode 100644 index 0000000000..cbb8be9cd2 --- /dev/null +++ b/src/Gui/ViewProviderPoint.h @@ -0,0 +1,46 @@ + // SPDX-License-Identifier: LGPL-2.1-or-later +/**************************************************************************** + * * + * Copyright (c) 2024 Ondsel (PL Boyer) * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * 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 Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + + +#ifndef GUI_ViewProviderPoint_H +#define GUI_ViewProviderPoint_H + +#include "ViewProviderDatum.h" + +namespace Gui +{ + +class GuiExport ViewProviderPoint : public ViewProviderDatum { + PROPERTY_HEADER_WITH_OVERRIDE(Gui::ViewProviderPoint); +public: + /// Constructor + ViewProviderPoint(); + ~ViewProviderPoint() override; + + void attach ( App::DocumentObject * ) override; +}; + +} //namespace Gui + + +#endif // GUI_ViewProviderPoint_H diff --git a/src/Mod/Part/App/PartFeature.cpp b/src/Mod/Part/App/PartFeature.cpp index ad07da1d89..2105701f75 100644 --- a/src/Mod/Part/App/PartFeature.cpp +++ b/src/Mod/Part/App/PartFeature.cpp @@ -31,6 +31,7 @@ # include # include # include +# include # include # include # include @@ -1020,6 +1021,14 @@ static TopoShape _getTopoShape(const App::DocumentObject* obj, } shape = TopoShape(tag, hasher, _shape); } + else if (linked->isDerivedFrom(App::Point::getClassTypeId())) { + static TopoDS_Shape _shape; + if (_shape.IsNull()) { + BRepBuilderAPI_MakeVertex builder(gp_Pnt(0, 0, 0)); + _shape = builder.Shape(); + } + shape = TopoShape(tag, hasher, _shape); + } else if (linked->isDerivedFrom(App::Placement::getClassTypeId())) { auto element = Data::findElementName(subname); if (element) { diff --git a/src/Mod/Part/parttests/ColorTransparencyTest.py b/src/Mod/Part/parttests/ColorTransparencyTest.py index 9def11d7b7..273220ef83 100644 --- a/src/Mod/Part/parttests/ColorTransparencyTest.py +++ b/src/Mod/Part/parttests/ColorTransparencyTest.py @@ -64,6 +64,6 @@ class ColorTransparencyTest(unittest.TestCase): obj = self._doc.addObject('App::Origin') t = self._doc.findObjects('App::Plane')[0].ViewObject.Transparency - self.assertEqual(t, 0, - 'transparency of App::Plane object is {} instead of 0'.format(t)) + self.assertEqual(t, 50, + 'transparency of App::Plane object is {} instead of 50'.format(t)) diff --git a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp index 5056247c75..392a8748b5 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp @@ -74,8 +74,6 @@ ViewProviderBody::ViewProviderBody() ViewProviderBody::~ViewProviderBody() { - connectChangedObjectApp.disconnect(); - connectChangedObjectGui.disconnect(); } void ViewProviderBody::attach(App::DocumentObject *pcFeat) @@ -85,20 +83,6 @@ void ViewProviderBody::attach(App::DocumentObject *pcFeat) //set default display mode onChanged(&DisplayModeBody); - - App::Document *adoc = pcObject->getDocument (); - Gui::Document *gdoc = Gui::Application::Instance->getDocument ( adoc ) ; - - assert ( adoc ); - assert ( gdoc ); - - //NOLINTBEGIN - connectChangedObjectApp = adoc->signalChangedObject.connect ( - std::bind ( &ViewProviderBody::slotChangedObjectApp, this, sp::_1, sp::_2) ); - - connectChangedObjectGui = gdoc->signalChangedObject.connect ( - std::bind ( &ViewProviderBody::slotChangedObjectGui, this, sp::_1, sp::_2) ); - //NOLINTEND } // TODO on activating the body switch to the "Through" mode (2015-09-05, Fat-Zer) @@ -228,8 +212,6 @@ void ViewProviderBody::updateData(const App::Property* prop) PartDesign::Body* body = static_cast(getObject()); if (prop == &body->Group || prop == &body->BaseFeature) { - // update sizes of origins and datums - updateOriginDatumSize (); //ensure all model features are in visual body mode setVisualBodyMode(true); } @@ -252,122 +234,6 @@ void ViewProviderBody::updateData(const App::Property* prop) PartGui::ViewProviderPart::updateData(prop); } -void ViewProviderBody::slotChangedObjectApp ( const App::DocumentObject& obj, const App::Property& prop ) { - - if(App::GetApplication().isRestoring()) - return; - - if (!obj.isDerivedFrom ( Part::Feature::getClassTypeId () ) || - obj.isDerivedFrom ( Part::BodyBase::getClassTypeId () ) ) { // we are interested only in Part::Features, not in bodies - return; - } - - const Part::Feature *feat = static_cast (&obj); - - if ( &feat->Shape != &prop && &feat->Placement != &prop) { // react only on changes in shapes and placement - return; - } - - PartDesign::Body *body = static_cast ( getObject() ); - if ( body && body->hasObject (&obj ) ) { - updateOriginDatumSize (); - } -} - -void ViewProviderBody::slotChangedObjectGui ( - const Gui::ViewProviderDocumentObject& vp, const App::Property& prop ) -{ - if (&vp.Visibility != &prop) { // react only on visibility changes - return; - } - - if ( !vp.isDerivedFrom ( Gui::ViewProviderOrigin::getClassTypeId () ) && - !vp.isDerivedFrom ( Gui::ViewProviderDatum::getClassTypeId () ) ) { - // Ignore origins to avoid infinite recursion (not likely in a well-formed document, - // but may happen in documents designed in old versions of assembly branch ) - return; - } - - PartDesign::Body *body = static_cast ( getObject() ); - App::DocumentObject *obj = vp.getObject (); - - if ( body && obj && body->hasObject ( obj ) ) { - updateOriginDatumSize (); - } -} - -void ViewProviderBody::updateOriginDatumSize () { - PartDesign::Body *body = static_cast ( getObject() ); - - // Use different bounding boxes for datums and for origins: - Gui::Document* gdoc = Gui::Application::Instance->getDocument(getObject()->getDocument()); - if(!gdoc) - return; - - Gui::MDIView* view = gdoc->getViewOfViewProvider(this); - if(!view) - return; - - Gui::View3DInventorViewer* viewer = static_cast(view)->getViewer(); - SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion()); - - const auto & model = body->getFullModel (); - - // BBox for Datums is calculated from all visible objects but treating datums as their basepoints only - SbBox3f bboxDatums = ViewProviderDatum::getRelevantBoundBox ( bboxAction, model ); - // BBox for origin should take into account datums size also - SbBox3f bboxOrigins = bboxDatums; - - for(App::DocumentObject* obj : model) { - if ( obj->isDerivedFrom ( Part::Datum::getClassTypeId () ) ) { - ViewProvider *vp = Gui::Application::Instance->getViewProvider(obj); - if (!vp) { continue; } - - ViewProviderDatum *vpDatum = static_cast (vp) ; - - vpDatum->setExtents ( bboxDatums ); - - bboxAction.apply ( vp->getRoot () ); - bboxOrigins.extendBy ( bboxAction.getBoundingBox () ); - } - } - - // get the bounding box values - SbVec3f max = bboxOrigins.getMax(); - SbVec3f min = bboxOrigins.getMin(); - - // obtain an Origin and it's ViewProvider - App::Origin* origin = nullptr; - Gui::ViewProviderOrigin* vpOrigin = nullptr; - try { - origin = body->getOrigin (); - assert (origin); - - Gui::ViewProvider *vp = Gui::Application::Instance->getViewProvider(origin); - if (!vp) { - throw Base::ValueError ("No view provider linked to the Origin"); - } - assert ( vp->isDerivedFrom ( Gui::ViewProviderOrigin::getClassTypeId () ) ); - vpOrigin = static_cast ( vp ); - } catch (const Base::Exception &ex) { - if(!getExtendedViewProvider()->getDocument()->getDocument()->testStatus(App::Document::Restoring)) - Base::Console().Error ("%s\n", ex.what() ); - return; - } - - // calculate the desired origin size - Base::Vector3d size; - - for (uint_fast8_t i=0; i<3; i++) { - size[i] = std::max ( fabs ( max[i] ), fabs ( min[i] ) ); - if (size[i] < Precision::Confusion() ) { - size[i] = Gui::ViewProviderOrigin::defaultSize(); - } - } - - vpOrigin->Size.setValue ( size*1.2 ); -} - void ViewProviderBody::onChanged(const App::Property* prop) { if(prop == &DisplayModeBody) { diff --git a/src/Mod/PartDesign/Gui/ViewProviderBody.h b/src/Mod/PartDesign/Gui/ViewProviderBody.h index 394d6975f6..3e4d331a08 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderBody.h +++ b/src/Mod/PartDesign/Gui/ViewProviderBody.h @@ -72,9 +72,6 @@ public: ///unify children visuals void onChanged(const App::Property* prop) override; - /// Update the sizes of origin and datums - void updateOriginDatumSize (); - /** * Return the bounding box of visible features * @note datums are counted as their base point only @@ -89,9 +86,6 @@ public: void dropObject(App::DocumentObject*) override; protected: - void slotChangedObjectApp ( const App::DocumentObject& obj, const App::Property& prop ); - void slotChangedObjectGui ( const Gui::ViewProviderDocumentObject& obj, const App::Property& prop ); - /// Copy over all visual properties to the child features void unifyVisualProperty(const App::Property* prop); /// Set Feature viewprovider into visual body mode @@ -99,9 +93,6 @@ protected: private: static const char* BodyModeEnum[]; - - boost::signals2::connection connectChangedObjectApp; - boost::signals2::connection connectChangedObjectGui; };