From bc5c4f6afbbb604dbb4830d1ab5178b95a3085d4 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Fri, 15 Feb 2019 17:08:48 +0100 Subject: [PATCH] Sketcher: GeometryExtension and ExternalGeometryExtension --- src/Mod/Sketcher/App/AppSketcher.cpp | 11 +- src/Mod/Sketcher/App/CMakeLists.txt | 5 + .../App/ExternalGeometryExtension.cpp | 83 +++++++++ .../Sketcher/App/ExternalGeometryExtension.h | 87 +++++++++ .../App/ExternalGeometryExtensionPy.xml | 37 ++++ .../App/ExternalGeometryExtensionPyImp.cpp | 172 ++++++++++++++++++ .../Sketcher/App/SketchGeometryExtension.cpp | 30 +-- .../Sketcher/App/SketchGeometryExtension.h | 16 +- .../App/SketchGeometryExtensionPyImp.cpp | 16 +- 9 files changed, 436 insertions(+), 21 deletions(-) create mode 100644 src/Mod/Sketcher/App/ExternalGeometryExtension.cpp create mode 100644 src/Mod/Sketcher/App/ExternalGeometryExtension.h create mode 100644 src/Mod/Sketcher/App/ExternalGeometryExtensionPy.xml create mode 100644 src/Mod/Sketcher/App/ExternalGeometryExtensionPyImp.cpp diff --git a/src/Mod/Sketcher/App/AppSketcher.cpp b/src/Mod/Sketcher/App/AppSketcher.cpp index 27721fa053..f56b94717e 100644 --- a/src/Mod/Sketcher/App/AppSketcher.cpp +++ b/src/Mod/Sketcher/App/AppSketcher.cpp @@ -32,13 +32,17 @@ #include "SketchObjectSF.h" #include "SketchObject.h" #include "SketchGeometryExtension.h" +#include "ExternalGeometryExtension.h" #include "Constraint.h" #include "Sketch.h" #include "ConstraintPy.h" #include "SketchPy.h" +#include "SketchGeometryExtensionPy.h" +#include "ExternalGeometryExtensionPy.h" #include "PropertyConstraintList.h" + namespace Sketcher { extern PyObject* initModule(); } @@ -58,8 +62,10 @@ PyMOD_INIT_FUNC(Sketcher) PyObject* sketcherModule = Sketcher::initModule(); // Add Types to module - Base::Interpreter().addType(&Sketcher::ConstraintPy ::Type,sketcherModule,"Constraint"); - Base::Interpreter().addType(&Sketcher::SketchPy ::Type,sketcherModule,"Sketch"); + Base::Interpreter().addType(&Sketcher::ConstraintPy ::Type,sketcherModule,"Constraint"); + Base::Interpreter().addType(&Sketcher::SketchPy ::Type,sketcherModule,"Sketch"); + Base::Interpreter().addType(&Sketcher::ExternalGeometryExtensionPy ::Type,sketcherModule,"ExternalGeometryExtension"); + Base::Interpreter().addType(&Sketcher::SketchGeometryExtensionPy ::Type,sketcherModule,"SketchGeometryExtension"); // NOTE: To finish the initialization of our own type objects we must @@ -67,6 +73,7 @@ PyMOD_INIT_FUNC(Sketcher) // This function is responsible for adding inherited slots from a type's base class. Sketcher::SketchGeometryExtension ::init(); + Sketcher::ExternalGeometryExtension ::init(); Sketcher::SketchObjectSF ::init(); Sketcher::SketchObject ::init(); Sketcher::SketchObjectPython ::init(); diff --git a/src/Mod/Sketcher/App/CMakeLists.txt b/src/Mod/Sketcher/App/CMakeLists.txt index 72682dbd6d..c9413bec43 100644 --- a/src/Mod/Sketcher/App/CMakeLists.txt +++ b/src/Mod/Sketcher/App/CMakeLists.txt @@ -37,6 +37,7 @@ set(Sketcher_LIBS generate_from_xml(SketchObjectSFPy) generate_from_xml(SketchObjectPy) generate_from_xml(SketchGeometryExtensionPy) +generate_from_xml(ExternalGeometryExtensionPy) generate_from_xml(ConstraintPy) generate_from_xml(SketchPy) @@ -53,6 +54,8 @@ SET(Features_SRCS SketchObjectSF.h SketchGeometryExtension.cpp SketchGeometryExtension.h + ExternalGeometryExtension.cpp + ExternalGeometryExtension.h SketchObject.cpp SketchObject.h SketchAnalysis.h @@ -76,6 +79,8 @@ SET(Python_SRCS SketchObjectPyImp.cpp SketchGeometryExtensionPy.xml SketchGeometryExtensionPyImp.cpp + ExternalGeometryExtensionPy.xml + ExternalGeometryExtensionPyImp.cpp ConstraintPyImp.cpp ConstraintPy.xml SketchPy.xml diff --git a/src/Mod/Sketcher/App/ExternalGeometryExtension.cpp b/src/Mod/Sketcher/App/ExternalGeometryExtension.cpp new file mode 100644 index 0000000000..ca0e287f15 --- /dev/null +++ b/src/Mod/Sketcher/App/ExternalGeometryExtension.cpp @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (c) 2019 Abdullah Tahiri * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" + +#include +#include + +#include + +#include "ExternalGeometryExtension.h" + +using namespace Sketcher; + +//---------- Geometry Extension + +constexpr std::array ExternalGeometryExtension::flag2str; + +TYPESYSTEM_SOURCE(Sketcher::ExternalGeometryExtension,Part::GeometryExtension) + +// Persistence implementer +unsigned int ExternalGeometryExtension::getMemSize (void) const +{ + return sizeof(long int); +} + +void ExternalGeometryExtension::Save(Base::Writer &writer) const +{ + writer.Stream() << writer.ind() << "getTypeId().getName(); + + const std::string name = getName(); + + if(name.size() > 0) + writer.Stream() << "\" name=\"" << name; + + writer.Stream() << "\" Ref=\"" << Ref << "\" Flags=\"" << Flags.to_string() << "\"/>" << std::endl; +} + +void ExternalGeometryExtension::Restore(Base::XMLReader &reader) +{ + restoreNameAttribute(reader); + + Ref = reader.getAttribute("Ref"); + Flags = FlagType(reader.getAttribute("Flags")); + +} + +std::unique_ptr ExternalGeometryExtension::copy(void) const +{ + std::unique_ptr cpy = std::make_unique(); + + cpy->Ref = this->Ref; + cpy->Flags = this->Flags; + + cpy->setName(this->getName()); // Base Class + + return std::move(cpy); +} + +PyObject * ExternalGeometryExtension::getPyObject(void) +{ + return new ExternalGeometryExtensionPy(new ExternalGeometryExtension(*this)); +} + diff --git a/src/Mod/Sketcher/App/ExternalGeometryExtension.h b/src/Mod/Sketcher/App/ExternalGeometryExtension.h new file mode 100644 index 0000000000..503c844951 --- /dev/null +++ b/src/Mod/Sketcher/App/ExternalGeometryExtension.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (c) 2019 Abdullah Tahiri * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef SKETCHER_EXTERNALGEOMETRYEXTENSION_H +#define SKETCHER_EXTERNALGEOMETRYEXTENSION_H + +#include + +namespace Sketcher +{ + +class SketcherExport ExternalGeometryExtension : public Part::GeometryExtension +{ + TYPESYSTEM_HEADER(); +public: + // START_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) + enum Flag { + Defining = 0, // allow an external geometry to build shape + Frozen = 1, // freeze an external geometry + Detached = 2, // signal the intentions of detaching the geometry from external reference + Missing = 3, // geometry with missing external reference + Sync = 4, // signal the intension to synchronize a frozen geometry + NumFlags // Must be the last type + }; + // END_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) + + constexpr static std::array flag2str { "Defining", "Frozen", "Detached","Missing", "Sync" }; + + ExternalGeometryExtension() = default; + virtual ~ExternalGeometryExtension() = default; + + // Persistence implementer --------------------- + virtual unsigned int getMemSize(void) const; + virtual void Save(Base::Writer &/*writer*/) const; + virtual void Restore(Base::XMLReader &/*reader*/); + + virtual std::unique_ptr copy(void) const; + + virtual PyObject *getPyObject(void); + + // START_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) + bool testFlag(int flag) const { return Flags.test((size_t)(flag)); } + void setFlag(int flag, bool v=true) { Flags.set((size_t)(flag),v); } + // END_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) + + bool isClear() const {return Flags.none();} + size_t flagSize() const {return Flags.size();} + + const std::string& getRef() const {return Ref;} + void setRef(const std::string & ref) {Ref = ref;} + +private: + ExternalGeometryExtension(const ExternalGeometryExtension&) = default; + +private: + using FlagType = std::bitset<32>; + // START_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) + std::string Ref; + FlagType Flags; + // END_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) + + +}; + +} //namespace Sketcher + + +#endif // SKETCHER_EXTERNALGEOMETRYEXTENSION_H diff --git a/src/Mod/Sketcher/App/ExternalGeometryExtensionPy.xml b/src/Mod/Sketcher/App/ExternalGeometryExtensionPy.xml new file mode 100644 index 0000000000..d8e2ab5b19 --- /dev/null +++ b/src/Mod/Sketcher/App/ExternalGeometryExtensionPy.xml @@ -0,0 +1,37 @@ + + + + + + Describes a ExternalGeometryExtension + + + + returns a boolean indicating whether the given bit is set. + + + + + sets the given bit to true/false. + + + + + + returns the reference string of this external geometry. + + + + + + diff --git a/src/Mod/Sketcher/App/ExternalGeometryExtensionPyImp.cpp b/src/Mod/Sketcher/App/ExternalGeometryExtensionPyImp.cpp new file mode 100644 index 0000000000..bdf010574c --- /dev/null +++ b/src/Mod/Sketcher/App/ExternalGeometryExtensionPyImp.cpp @@ -0,0 +1,172 @@ +/*************************************************************************** + * Copyright (c) 2019 Abdullah Tahiri * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +//#ifndef _PreComp_ +//# include +//#endif + +#include +#include "SketchObject.h" +#include "ExternalGeometryExtensionPy.h" +#include "ExternalGeometryExtensionPy.cpp" + +using namespace Sketcher; + +// returns a string which represents the object e.g. when printed in python +std::string ExternalGeometryExtensionPy::representation(void) const +{ + std::stringstream str; + + std::string ref = getExternalGeometryExtensionPtr()->getRef(); + + + + str << "getName().size()>0) + str << "\'" << getExternalGeometryExtensionPtr()->getName() << "\', "; + + str << "\"" << ref; + + if(!getExternalGeometryExtensionPtr()->isClear()) { + str<< "\",{"; + + bool first=true; + + for(size_t i=0;itestFlag(i)) { + if(first) { + first=false; + } + else { + str << ", "; + } + + str << getExternalGeometryExtensionPtr()->flag2str[i]; + } + } + + str<< "}"; + } + else { + str << "\") >"; + } + + str << ") >"; + + return str.str(); +} + +PyObject *ExternalGeometryExtensionPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +{ + // create a new instance of PointPy and the Twin object + return new ExternalGeometryExtensionPy(new ExternalGeometryExtension); +} + +// constructor method +int ExternalGeometryExtensionPy::PyInit(PyObject* args, PyObject* /*kwd*/) +{ + + if (PyArg_ParseTuple(args, "")) { + // default extension + return 0; + } + + PyErr_SetString(PyExc_TypeError, "ExternalGeometryExtension constructor accepts:\n" + "-- empty parameter list\n"); + return -1; +} + +PyObject* ExternalGeometryExtensionPy::testFlag(PyObject *args) +{ + char* flag; + if (PyArg_ParseTuple(args, "s",&flag)) { + + auto pos = std::find_if(getExternalGeometryExtensionPtr()->flag2str.begin(), + getExternalGeometryExtensionPtr()->flag2str.end(), + [flag](const char * val) { return strcmp(val,flag) == 0;}); + + if( pos != getExternalGeometryExtensionPtr()->flag2str.end()) { + int index = std::distance( getExternalGeometryExtensionPtr()->flag2str.begin(), pos ); + + return new_reference_to(Py::Boolean(this->getExternalGeometryExtensionPtr()->testFlag(index))); + } + + PyErr_SetString(PyExc_TypeError, "Flag string does not exist."); + return NULL; + + } + + PyErr_SetString(PyExc_TypeError, "No flag string provided."); + return NULL; +} + +PyObject* ExternalGeometryExtensionPy::setFlag(PyObject *args) +{ + char * flag; + PyObject * bflag = Py_True; + if (PyArg_ParseTuple(args, "s|O!", &flag, &PyBool_Type, &bflag)) { + + auto pos = std::find_if(getExternalGeometryExtensionPtr()->flag2str.begin(), + getExternalGeometryExtensionPtr()->flag2str.end(), + [flag](const char * val) { + return strcmp(val,flag)==0;} + ); + + if( pos != getExternalGeometryExtensionPtr()->flag2str.end()) { + int index = std::distance( getExternalGeometryExtensionPtr()->flag2str.begin(), pos ); + + this->getExternalGeometryExtensionPtr()->setFlag(index,PyObject_IsTrue(bflag) ? true : false); + Py_Return; + } + + PyErr_SetString(PyExc_TypeError, "Flag string does not exist."); + return NULL; + } + + PyErr_SetString(PyExc_TypeError, "No flag string provided."); + Py_Return; +} + +Py::String ExternalGeometryExtensionPy::getRef(void) const +{ + return Py::String(this->getExternalGeometryExtensionPtr()->getRef()); +} + +void ExternalGeometryExtensionPy::setRef(Py::String value) +{ + this->getExternalGeometryExtensionPtr()->setRef(value.as_std_string()); +} + + +PyObject *ExternalGeometryExtensionPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int ExternalGeometryExtensionPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} diff --git a/src/Mod/Sketcher/App/SketchGeometryExtension.cpp b/src/Mod/Sketcher/App/SketchGeometryExtension.cpp index 8b175689e9..be72c267fa 100644 --- a/src/Mod/Sketcher/App/SketchGeometryExtension.cpp +++ b/src/Mod/Sketcher/App/SketchGeometryExtension.cpp @@ -35,20 +35,19 @@ using namespace Sketcher; TYPESYSTEM_SOURCE(Sketcher::SketchGeometryExtension,Part::GeometryExtension) -SketchGeometryExtension::SketchGeometryExtension():id(0) +// scoped within the class, multithread ready +std::atomic SketchGeometryExtension::_GeometryID; + +SketchGeometryExtension::SketchGeometryExtension():Id(++SketchGeometryExtension::_GeometryID) { } -SketchGeometryExtension::SketchGeometryExtension(long cid):id(cid) +SketchGeometryExtension::SketchGeometryExtension(long cid):Id(cid) { } -SketchGeometryExtension::~SketchGeometryExtension() -{ -} - // Persistence implementer unsigned int SketchGeometryExtension::getMemSize (void) const { @@ -57,27 +56,36 @@ unsigned int SketchGeometryExtension::getMemSize (void) const void SketchGeometryExtension::Save(Base::Writer &writer) const { + writer.Stream() << writer.ind() << "getTypeId().getName(); - writer.Stream() << writer.ind() << "getTypeId().getName() - << "\" id=\"" << id << "\"/>" << endl; + const std::string name = getName(); + + if(name.size() > 0) + writer.Stream() << "\" name=\"" << name; + + writer.Stream() << "\" id=\"" << Id << "\"/>" << std::endl; } void SketchGeometryExtension::Restore(Base::XMLReader &reader) { - id = reader.getAttributeAsInteger("id"); + restoreNameAttribute(reader); + + Id = reader.getAttributeAsInteger("id"); } std::unique_ptr SketchGeometryExtension::copy(void) const { std::unique_ptr cpy = std::make_unique(); - cpy->id = this->id; + cpy->Id = this->Id; + + cpy->setName(this->getName()); // Base Class return std::move(cpy); } PyObject * SketchGeometryExtension::getPyObject(void) { - return new SketchGeometryExtensionPy(new SketchGeometryExtension(this->id)); + return new SketchGeometryExtensionPy(new SketchGeometryExtension(*this)); } diff --git a/src/Mod/Sketcher/App/SketchGeometryExtension.h b/src/Mod/Sketcher/App/SketchGeometryExtension.h index 50f469c722..4a1d5cda66 100644 --- a/src/Mod/Sketcher/App/SketchGeometryExtension.h +++ b/src/Mod/Sketcher/App/SketchGeometryExtension.h @@ -24,6 +24,7 @@ #define SKETCHER_SKETCHGEOMETRYEXTENSION_H #include +#include namespace Sketcher { @@ -34,7 +35,7 @@ class SketcherExport SketchGeometryExtension : public Part::GeometryExtension public: SketchGeometryExtension(); SketchGeometryExtension(long cid); - virtual ~SketchGeometryExtension(); + virtual ~SketchGeometryExtension() = default; // Persistence implementer --------------------- virtual unsigned int getMemSize(void) const; @@ -45,8 +46,17 @@ public: virtual PyObject *getPyObject(void); -public: - long int id; + long getId() const {return Id;} + void setId(long id) {Id = id;} + +private: + SketchGeometryExtension(const SketchGeometryExtension&) = default; + +private: + long Id; + +private: + static std::atomic _GeometryID; }; } //namespace Sketcher diff --git a/src/Mod/Sketcher/App/SketchGeometryExtensionPyImp.cpp b/src/Mod/Sketcher/App/SketchGeometryExtensionPyImp.cpp index 08f7ddda49..9b9832b63f 100644 --- a/src/Mod/Sketcher/App/SketchGeometryExtensionPyImp.cpp +++ b/src/Mod/Sketcher/App/SketchGeometryExtensionPyImp.cpp @@ -38,8 +38,14 @@ using namespace Sketcher; std::string SketchGeometryExtensionPy::representation(void) const { std::stringstream str; - long id = getSketchGeometryExtensionPtr()->id; - str << ""; + str << "getName().size()>0) + str << "\'" << getSketchGeometryExtensionPtr()->getName() << "\', "; + + str << "\""; + + str << getSketchGeometryExtensionPtr()->getId() << "\") >"; return str.str(); } @@ -61,7 +67,7 @@ int SketchGeometryExtensionPy::PyInit(PyObject* args, PyObject* /*kwd*/) PyErr_Clear(); int Id; if (PyArg_ParseTuple(args, "i", &Id)) { - this->getSketchGeometryExtensionPtr()->id=Id; + this->getSketchGeometryExtensionPtr()->setId(Id); return 0; } @@ -75,12 +81,12 @@ int SketchGeometryExtensionPy::PyInit(PyObject* args, PyObject* /*kwd*/) Py::Long SketchGeometryExtensionPy::getId(void) const { - return Py::Long(this->getSketchGeometryExtensionPtr()->id); + return Py::Long(this->getSketchGeometryExtensionPtr()->getId()); } void SketchGeometryExtensionPy::setId(Py::Long Id) { - this->getSketchGeometryExtensionPtr()->id=long(Id); + this->getSketchGeometryExtensionPtr()->setId(long(Id)); }