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