From d178c2bf91dfdc978ba038ce6c0466be94bbd89a Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 5 Oct 2020 16:57:16 +0200 Subject: [PATCH] Part: [skip ci] expose ShapeUpgrade_UnifySameDomain to Python --- src/Mod/Part/App/AppPart.cpp | 5 + src/Mod/Part/App/AppPartPy.cpp | 13 + src/Mod/Part/App/CMakeLists.txt | 12 + .../App/ShapeUpgrade/UnifySameDomainPy.xml | 71 +++++ .../App/ShapeUpgrade/UnifySameDomainPyImp.cpp | 252 ++++++++++++++++++ 5 files changed, 353 insertions(+) create mode 100644 src/Mod/Part/App/ShapeUpgrade/UnifySameDomainPy.xml create mode 100644 src/Mod/Part/App/ShapeUpgrade/UnifySameDomainPyImp.cpp diff --git a/src/Mod/Part/App/AppPart.cpp b/src/Mod/Part/App/AppPart.cpp index 88a94f7288..d3a0fcfea9 100644 --- a/src/Mod/Part/App/AppPart.cpp +++ b/src/Mod/Part/App/AppPart.cpp @@ -128,6 +128,7 @@ #include #include #include +#include #include "PropertyGeometryList.h" #include "DatumFeature.h" #include "Attacher.h" @@ -427,6 +428,10 @@ PyMOD_INIT_FUNC(Part) Base::Interpreter().addType(&Part::CurveConstraintPy::Type, geomPlate, "CurveConstraint"); Base::Interpreter().addType(&Part::PointConstraintPy::Type, geomPlate, "PointConstraint"); + // ShapeUpgrade sub-module + PyObject* shapeUpgrade(module.getAttr("ShapeUpgrade").ptr()); + Base::Interpreter().addType(&Part::UnifySameDomainPy::Type, shapeUpgrade, "UnifySameDomain"); + Part::TopoShape ::init(); Part::PropertyPartShape ::init(); Part::PropertyGeometryList ::init(); diff --git a/src/Mod/Part/App/AppPartPy.cpp b/src/Mod/Part/App/AppPartPy.cpp index c8242dcdef..2c5fe46e22 100644 --- a/src/Mod/Part/App/AppPartPy.cpp +++ b/src/Mod/Part/App/AppPartPy.cpp @@ -282,9 +282,21 @@ public: virtual ~GeomPlateModule() {} }; +class ShapeUpgradeModule : public Py::ExtensionModule +{ +public: + ShapeUpgradeModule() : Py::ExtensionModule("ShapeUpgrade") + { + initialize("This is a module working with the ShapeUpgrade framework."); // register with Python + } + + virtual ~ShapeUpgradeModule() {} +}; + class Module : public Py::ExtensionModule { GeomPlateModule geomPlate; + ShapeUpgradeModule shapeUpgrade; public: Module() : Py::ExtensionModule("Part") { @@ -502,6 +514,7 @@ public: initialize("This is a module working with shapes."); // register with Python PyModule_AddObject(m_module, "GeomPlate", geomPlate.module().ptr()); + PyModule_AddObject(m_module, "ShapeUpgrade", shapeUpgrade.module().ptr()); } virtual ~Module() {} diff --git a/src/Mod/Part/App/CMakeLists.txt b/src/Mod/Part/App/CMakeLists.txt index d9efe5694e..b6aed42172 100644 --- a/src/Mod/Part/App/CMakeLists.txt +++ b/src/Mod/Part/App/CMakeLists.txt @@ -96,6 +96,7 @@ generate_from_xml(BRepOffsetAPI_MakeFillingPy) # make sure to create the directory at configure time file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Geom2d) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/GeomPlate) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ShapeUpgrade) generate_from_xml(Geom2d/ArcOfCircle2dPy) generate_from_xml(Geom2d/ArcOfConic2dPy) @@ -119,6 +120,8 @@ generate_from_xml(GeomPlate/BuildPlateSurfacePy) generate_from_xml(GeomPlate/CurveConstraintPy) generate_from_xml(GeomPlate/PointConstraintPy) +generate_from_xml(ShapeUpgrade/UnifySameDomainPy) + SET(Features_SRCS FeaturePartBoolean.cpp FeaturePartBoolean.h @@ -361,12 +364,21 @@ SET(GeomPlatePy_SRCS SOURCE_GROUP("GeomPlate" FILES ${GeomPlatePy_SRCS}) +# ShapeUpgrade wrappers +SET(ShapeUpgradePy_SRCS + ShapeUpgrade/UnifySameDomainPy.xml + ShapeUpgrade/UnifySameDomainPyImp.cpp +) + +SOURCE_GROUP("ShapeUpgrade" FILES ${ShapeUpgradePy_SRCS}) + SET(Part_SRCS ${Features_SRCS} ${Properties_SRCS} ${Python_SRCS} ${Geom2dPy_SRCS} ${GeomPlatePy_SRCS} + ${ShapeUpgradePy_SRCS} Attacher.cpp Attacher.h AppPart.cpp diff --git a/src/Mod/Part/App/ShapeUpgrade/UnifySameDomainPy.xml b/src/Mod/Part/App/ShapeUpgrade/UnifySameDomainPy.xml new file mode 100644 index 0000000000..198258a164 --- /dev/null +++ b/src/Mod/Part/App/ShapeUpgrade/UnifySameDomainPy.xml @@ -0,0 +1,71 @@ + + + + + + This tool tries to unify faces and edges of the shape which lie on the same geometry. + + + + Initializes with a shape and necessary flags + + + + + Sets the flag defining whether it is allowed to create +internal edges inside merged faces in the case of non-manifold +topology. Without this flag merging through multi connected edge +is forbidden. Default value is false. + + + + + Sets the shape for avoid merging of the faces/edges. + + + + + Sets the map of shapes for avoid merging of the faces/edges. + + + + + Sets the flag defining the behavior of the algorithm regarding +modification of input shape. +If this flag is equal to True then the input (original) shape can't be +modified during modification process. Default value is true. + + + + + Sets the linear tolerance + + + + + Sets the angular tolerance + + + + + Performs unification and builds the resulting shape + + + + + Gives the resulting shape + + + + diff --git a/src/Mod/Part/App/ShapeUpgrade/UnifySameDomainPyImp.cpp b/src/Mod/Part/App/ShapeUpgrade/UnifySameDomainPyImp.cpp new file mode 100644 index 0000000000..a759180596 --- /dev/null +++ b/src/Mod/Part/App/ShapeUpgrade/UnifySameDomainPyImp.cpp @@ -0,0 +1,252 @@ +/*************************************************************************** + * Copyright (c) 2020 Werner Mayer * + * * + * 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 "ShapeUpgrade/UnifySameDomainPy.h" +#include "ShapeUpgrade/UnifySameDomainPy.cpp" +#include "TopoShapePy.h" +#include "PartPyCXX.h" + +using namespace Part; + +PyObject *UnifySameDomainPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +{ + // create a new instance of UnifySameDomainPy + return new UnifySameDomainPy(nullptr); +} + +// constructor method +int UnifySameDomainPy::PyInit(PyObject* args, PyObject* kwds) +{ + PyObject *shape; + PyObject* unifyEdges = Py_True; + PyObject* unifyFaces = Py_True; + PyObject* concatBSpl = Py_False; + + static char* keywords[] = {"Shape", "UnifyEdges", "UnifyFaces", "ConcatBSplines", nullptr}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|O!O!O!", keywords, + &TopoShapePy::Type, &shape, + &PyBool_Type, &unifyEdges, + &PyBool_Type, &unifyFaces, + &PyBool_Type, &concatBSpl)) + return -1; + + try { + TopoDS_Shape shp = static_cast(shape)->getTopoShapePtr()->getShape(); + std::unique_ptr ptr(new ShapeUpgrade_UnifySameDomain(shp, + PyObject_IsTrue(unifyEdges) ? Standard_True : Standard_False, + PyObject_IsTrue(unifyFaces) ? Standard_True : Standard_False, + PyObject_IsTrue(concatBSpl) ? Standard_True : Standard_False)); + + setTwinPointer(ptr.release()); + return 0; + } + catch (const Standard_Failure& e) { + PyErr_SetString(PyExc_RuntimeError, e.GetMessageString()); + return -1; + } +} + +PyObject* UnifySameDomainPy::initialize(PyObject *args, PyObject* kwds) +{ + PyObject *shape; + PyObject* unifyEdges = Py_True; + PyObject* unifyFaces = Py_True; + PyObject* concatBSpl = Py_False; + + static char* keywords[] = {"Shape", "UnifyEdges", "UnifyFaces", "ConcatBSplines", nullptr}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|O!O!O!", keywords, + &TopoShapePy::Type, &shape, + &PyBool_Type, &unifyEdges, + &PyBool_Type, &unifyFaces, + &PyBool_Type, &concatBSpl)) + return nullptr; + + try { + TopoDS_Shape shp = static_cast(shape)->getTopoShapePtr()->getShape(); + getShapeUpgrade_UnifySameDomainPtr()->Initialize(shp, + PyObject_IsTrue(unifyEdges) ? Standard_True : Standard_False, + PyObject_IsTrue(unifyFaces) ? Standard_True : Standard_False, + PyObject_IsTrue(concatBSpl) ? Standard_True : Standard_False); + + Py_Return; + } + catch (const Standard_Failure& e) { + PyErr_SetString(PyExc_RuntimeError, e.GetMessageString()); + return nullptr; + } +} + +// returns a string which represents the object e.g. when printed in python +std::string UnifySameDomainPy::representation(void) const +{ + return std::string(""); +} + +PyObject* UnifySameDomainPy::allowInternalEdges(PyObject *args) +{ + PyObject* allow; + if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &allow)) + return nullptr; + + try { + getShapeUpgrade_UnifySameDomainPtr()->AllowInternalEdges(PyObject_IsTrue(allow) ? Standard_True : Standard_False); + Py_Return; + } + catch (const Standard_Failure& e) { + PyErr_SetString(PyExc_RuntimeError, e.GetMessageString()); + return nullptr; + } +} + +PyObject* UnifySameDomainPy::keepShape(PyObject *args) +{ + PyObject* shape; + if (!PyArg_ParseTuple(args, "O!", &TopoShapePy::Type, &shape)) + return nullptr; + + try { + TopoDS_Shape shp = static_cast(shape)->getTopoShapePtr()->getShape(); + getShapeUpgrade_UnifySameDomainPtr()->KeepShape(shp); + Py_Return; + } + catch (const Standard_Failure& e) { + PyErr_SetString(PyExc_RuntimeError, e.GetMessageString()); + return nullptr; + } +} + +PyObject* UnifySameDomainPy::keepShapes(PyObject *args) +{ + PyObject* obj; + if (!PyArg_ParseTuple(args, "O", &obj)) + return nullptr; + + try { + TopTools_MapOfShape theShapes; + Py::Sequence list(obj); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + Py::TopoShape shp(*it); + theShapes.Add(shp.extensionObject()->getTopoShapePtr()->getShape()); + } + + getShapeUpgrade_UnifySameDomainPtr()->KeepShapes(theShapes); + Py_Return; + } + catch (const Standard_Failure& e) { + PyErr_SetString(PyExc_RuntimeError, e.GetMessageString()); + return nullptr; + } +} + +PyObject* UnifySameDomainPy::setSafeInputMode(PyObject *args) +{ + PyObject* mode; + if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &mode)) + return nullptr; + + try { + getShapeUpgrade_UnifySameDomainPtr()->SetSafeInputMode(PyObject_IsTrue(mode) ? Standard_True : Standard_False); + Py_Return; + } + catch (const Standard_Failure& e) { + PyErr_SetString(PyExc_RuntimeError, e.GetMessageString()); + return nullptr; + } +} + +PyObject* UnifySameDomainPy::setLinearTolerance(PyObject *args) +{ + double linTol; + if (!PyArg_ParseTuple(args, "d", &linTol)) + return nullptr; + + try { + getShapeUpgrade_UnifySameDomainPtr()->SetLinearTolerance(linTol); + Py_Return; + } + catch (const Standard_Failure& e) { + PyErr_SetString(PyExc_RuntimeError, e.GetMessageString()); + return nullptr; + } +} + +PyObject* UnifySameDomainPy::setAngularTolerance(PyObject *args) +{ + double angTol; + if (!PyArg_ParseTuple(args, "d", &angTol)) + return nullptr; + + try { + getShapeUpgrade_UnifySameDomainPtr()->SetAngularTolerance(angTol); + Py_Return; + } + catch (const Standard_Failure& e) { + PyErr_SetString(PyExc_RuntimeError, e.GetMessageString()); + return nullptr; + } +} + +PyObject* UnifySameDomainPy::build(PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return nullptr; + + try { + getShapeUpgrade_UnifySameDomainPtr()->Build(); + Py_Return; + } + catch (const Standard_Failure& e) { + PyErr_SetString(PyExc_RuntimeError, e.GetMessageString()); + return nullptr; + } +} + +PyObject* UnifySameDomainPy::shape(PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return nullptr; + + try { + TopoDS_Shape shape = getShapeUpgrade_UnifySameDomainPtr()->Shape(); + return new TopoShapePy(new TopoShape(shape)); + } + catch (const Standard_Failure& e) { + PyErr_SetString(PyExc_RuntimeError, e.GetMessageString()); + return nullptr; + } +} + +PyObject *UnifySameDomainPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int UnifySameDomainPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +}