From 279346cbf2dfb59ad415d9f07db579687e3580db Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Thu, 3 Dec 2020 14:13:39 +0100 Subject: [PATCH] Sketcher: GeometryTypedFacade and GeometryFacade convenience functions ====================================================================== GeometryFacade is added the ability to get the construction status via static function, for convenience in situations where only the construction status is necessary and a geometry facade would not be otherwise necessary. A new type GeometryTypedFacade is added, for situations in which the specific Part::Geometry derived type is known (or is to be created). This Typed version enables to directly access the Geometry derived class without the need for casting, as well as the SketchGeometryExtension information. For example, this is possible: auto HLineF = GeometryTypedFacade::getTypedFacade(HLine); HLine->getTypedGeometry()->setPoints(Base::Vector3d(0,0,0),Base::Vector3d(1,0,0)); If a facade is requested without passing an Part::Geometry derived object, the constructor of the indicated geometry type is called with any parameter passed as argument (emplace style): auto HLine = GeometryTypedFacade::getTypedFacade(); HLine->getTypedGeometry()->setPoints(Base::Vector3d(0,0,0),Base::Vector3d(1,0,0)); HLine->setConstruction(true); ExternalGeo.push_back(HLine->getGeometry()); Using either GeometryFacade or GeometryTypedFacade is probably a matter of style and of the specific situation. --- src/Mod/Sketcher/App/GeometryFacade.cpp | 12 ++++ src/Mod/Sketcher/App/GeometryFacade.h | 85 ++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/src/Mod/Sketcher/App/GeometryFacade.cpp b/src/Mod/Sketcher/App/GeometryFacade.cpp index 8a13bc1e4c..bd5443bacf 100644 --- a/src/Mod/Sketcher/App/GeometryFacade.cpp +++ b/src/Mod/Sketcher/App/GeometryFacade.cpp @@ -113,6 +113,18 @@ void GeometryFacade::copyId(const Part::Geometry * src, Part::Geometry * dst) gfdst->setId(gfsrc->getId()); } +bool GeometryFacade::getConstruction(const Part::Geometry * geometry) +{ + auto gf = GeometryFacade::getFacade(geometry); + return gf->getConstruction(); +} + +void GeometryFacade::setConstruction(Part::Geometry * geometry, bool construction) +{ + auto gf = GeometryFacade::getFacade(geometry); + return gf->setConstruction(construction); +} + PyObject * GeometryFacade::getPyObject(void) { return new GeometryFacadePy(new GeometryFacade(this->Geo)); diff --git a/src/Mod/Sketcher/App/GeometryFacade.h b/src/Mod/Sketcher/App/GeometryFacade.h index 6e491b3978..bd3567966f 100644 --- a/src/Mod/Sketcher/App/GeometryFacade.h +++ b/src/Mod/Sketcher/App/GeometryFacade.h @@ -70,6 +70,27 @@ class GeometryFacadePy; // Part::GeomBSplineCurve * gbsc = bspline.release(); // GeometryFacade::copyId(geo, gbsc); // +// Examples getting and setting the construction stations without creating a Facade: +// +// if ((*geo) && GeometryFacade::getConstruction(*geo) && +// (*geo)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) +// count++; +// +// Part::Geometry* copy = v->copy(); +// +// if(construction && copy->getTypeId() != Part::GeomPoint::getClassTypeId()) { +// GeometryFacade::setConstruction(copy, construction); +// } +// +// +// Note: The standard GeometryFacade stores Part::Geometry derived clases as a Part::Geometry *, while +// it has the ability to return a dynamic_cast-ed version to a provided type as follows: +// +// HLine->getGeometry(); +// +// If for seamless operation it is convenient to have a given derived class of Part::Geometry, it is possible +// to use GeometryTypedFacade (see below). +// // Summary Remarks: // It is intended to have a separate type (not being a Geometry type). // it is intended to have the relevant interface in full for the sketcher extension only @@ -78,7 +99,7 @@ class SketcherExport GeometryFacade : public Base::BaseClass, private ISketchGeo { TYPESYSTEM_HEADER_WITH_OVERRIDE(); -private: +protected: GeometryFacade(const Part::Geometry * geometry); GeometryFacade(); // As TYPESYSTEM requirement @@ -91,6 +112,8 @@ public: // Factory methods public: // Utility methods static void ensureSketchGeometryExtension(Part::Geometry * geometry); static void copyId(const Part::Geometry * src, Part::Geometry * dst); + static bool getConstruction(const Part::Geometry * geometry); + static void setConstruction(Part::Geometry * geometry, bool construction); public: void setGeometry(Part::Geometry *geometry); @@ -108,7 +131,7 @@ public: std::is_base_of::type>::value >::type > - GeometryT * getGeometry() {return dynamic_cast(const_cast(Geo));} + GeometryT * getGeometry() {return dynamic_cast(const_cast(Geo));} // Geometry Element template < typename GeometryT = Part::Geometry, @@ -145,6 +168,9 @@ public: void transform(Base::Matrix4D mat) {return getGeo()->transform(mat);}; void translate(Base::Vector3d vec) {return getGeo()->translate(vec);}; + // convenience GeometryFunctions + bool isGeoType(const Base::Type &type) const { return getGeo()->getTypeId() == type;} + private: void initExtension(void); void initExtension(void) const; @@ -162,6 +188,61 @@ private: +/////////////////////////////////////////////////////////////////////////////////////// +// +// GeometryTypedFacade +// +// It provides all the funcionality of GeometryFacade (derives from it), but in addition +// allows to indicate the type of a Part::Geometry derived class. +// +// auto HLineF = GeometryTypedFacade::getTypedFacade(HLine); +// +// Then it is possible to get the typed geometry directly via: +// +// HLine->getTypedGeometry()->setPoints(Base::Vector3d(0,0,0),Base::Vector3d(1,0,0)); +// +// If a facade is requested without passing an Part::Geometry derived object, the constructor +// of the indicated geometry type is called with any parameter passed as argument (emplace style) +// +// Example of seamless operation with a GeomLineSegment: +// +// auto HLine = GeometryTypedFacade::getTypedFacade(); +// HLine->getTypedGeometry()->setPoints(Base::Vector3d(0,0,0),Base::Vector3d(1,0,0)); +// HLine->setConstruction(true); +// ExternalGeo.push_back(HLine->getGeometry()); + +template < typename GeometryT > +class SketcherExport GeometryTypedFacade : public GeometryFacade +{ + static_assert( std::is_base_of::type>::value && + !std::is_same::type>::value, "Only for classes derived from Geometry!"); + private: + GeometryTypedFacade(const Part::Geometry * geometry):GeometryFacade(geometry) {}; + GeometryTypedFacade():GeometryFacade() {}; + +public: // Factory methods + static std::unique_ptr> getTypedFacade(GeometryT * geometry) { + return std::unique_ptr>(new GeometryTypedFacade(geometry)); + } + static std::unique_ptr> getTypedFacade(const GeometryT * geometry) { + return std::unique_ptr>(new GeometryTypedFacade(geometry)); + } + + template < typename... Args > + static std::unique_ptr> getTypedFacade(Args&&... args) { + return GeometryTypedFacade::getTypedFacade(new GeometryT(std::forward(args)...)); + } + + // Geometry Element + GeometryT * getTypedGeometry() {return GeometryFacade::getGeometry();} + + // Geometry Element + GeometryT * getTypedGeometry() const {return GeometryFacade::getGeometry();} +}; + + + + } //namespace Sketcher