From 1757f70cdf0aa84df291cc42a7882613d2ea8492 Mon Sep 17 00:00:00 2001 From: DeepSOIC Date: Sun, 25 Sep 2016 18:34:58 +0300 Subject: [PATCH] Part: Py API: add methods to use FaceMakers * new Part.Shape.Face() constructor footprints with facemaker class supplied as string mane of C++ class. * add Part.makeFace method that uses facemaker. --- src/Mod/Part/App/AppPartPy.cpp | 66 +++++++++++++++++++++++++ src/Mod/Part/App/TopoShapeFacePyImp.cpp | 60 +++++++++++++++++++++- 2 files changed, 125 insertions(+), 1 deletion(-) diff --git a/src/Mod/Part/App/AppPartPy.cpp b/src/Mod/Part/App/AppPartPy.cpp index 070087e79..3863796ed 100644 --- a/src/Mod/Part/App/AppPartPy.cpp +++ b/src/Mod/Part/App/AppPartPy.cpp @@ -124,6 +124,7 @@ #include "ImportIges.h" #include "ImportStep.h" #include "edgecluster.h" +#include "FaceMaker.h" #ifdef FCUseFreeType # include "FT2FC.h" @@ -252,6 +253,10 @@ public: add_varargs_method("makeShell",&Module::makeShell, "makeShell(list) -- Create a shell out of a list of faces." ); + add_varargs_method("makeFace",&Module::makeFace, + "makeFace(list_of_shapes_or_compound, maker_class_name) -- Create a face (faces) using facemaker class.\n" + "maker_class_name is a string like 'Part::FaceMakerSimple'." + ); add_varargs_method("makeFilledFace",&Module::makeFilledFace, "makeFilledFace(list) -- Create a face out of a list of edges." ); @@ -626,6 +631,67 @@ private: return Py::asObject(new TopoShapeShellPy(new TopoShape(shape))); } + Py::Object makeFace(const Py::Tuple& args) + { + try{ + + char* className = 0; + PyObject* pcPyShapeOrList = nullptr; + PyErr_Clear(); + if (PyArg_ParseTuple(args.ptr(), "Os", &pcPyShapeOrList, &className)) { + std::unique_ptr fm_instance = Part::FaceMaker::ConstructFromType(className); + FaceMaker* fm = &(*fm_instance); + + //dump all supplied shapes to facemaker, no matter what type (let facemaker decide). + if (PySequence_Check(pcPyShapeOrList)){ + Py::Sequence list(pcPyShapeOrList); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + PyObject* item = (*it).ptr(); + if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) { + const TopoDS_Shape& sh = static_cast(item)->getTopoShapePtr()->getShape(); + fm->addShape(sh); + } else { + throw Py::Exception(PyExc_TypeError, "Object is not a shape."); + } + } + } else if (PyObject_TypeCheck(pcPyShapeOrList, &(Part::TopoShapePy::Type))) { + const TopoDS_Shape& sh = static_cast(pcPyShapeOrList)->getTopoShapePtr()->getShape(); + if (sh.IsNull()) + throw Base::Exception("Shape is null!"); + if (sh.ShapeType() == TopAbs_COMPOUND) + fm->useCompound(TopoDS::Compound(sh)); + else + fm->addShape(sh); + } else { + throw Py::Exception(PyExc_TypeError, "First argument is neither a shape nor list of shapes."); + } + + fm->Build(); + + if(fm->Shape().IsNull()) + return Py::asObject(new TopoShapePy(new TopoShape(fm->Shape()))); + + switch(fm->Shape().ShapeType()){ + case TopAbs_FACE: + return Py::asObject(new TopoShapeFacePy(new TopoShape(fm->Shape()))); + break; + case TopAbs_COMPOUND: + return Py::asObject(new TopoShapeCompoundPy(new TopoShape(fm->Shape()))); + break; + default: + return Py::asObject(new TopoShapePy(new TopoShape(fm->Shape()))); + } + } ; + + throw Py::Exception(Base::BaseExceptionFreeCADError, std::string("Argument type signature not recognized. Should be either (list, string), or (shape, string)")); + + } catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + throw Py::Exception(PartExceptionOCCError, e->GetMessageString()); + } catch (Base::Exception &e){ + throw Py::Exception(Base::BaseExceptionFreeCADError, e.what()); + } + } Py::Object makeFilledFace(const Py::Tuple& args) { // TODO: BRepFeat_SplitShape diff --git a/src/Mod/Part/App/TopoShapeFacePyImp.cpp b/src/Mod/Part/App/TopoShapeFacePyImp.cpp index a742507f1..2b2198d4c 100644 --- a/src/Mod/Part/App/TopoShapeFacePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeFacePyImp.cpp @@ -75,6 +75,7 @@ #include "TopoShapeWirePy.h" #include "TopoShapeFacePy.h" #include "TopoShapeFacePy.cpp" +#include "TopoShapeCompoundPy.h" #include "BezierSurfacePy.h" #include "BSplineSurfacePy.h" @@ -88,6 +89,7 @@ #include "ToroidPy.h" #include "OCCError.h" #include "Tools.h" +#include "FaceMaker.h" using namespace Part; @@ -245,7 +247,63 @@ int TopoShapeFacePy::PyInit(PyObject* args, PyObject* /*kwd*/) } } - PyErr_SetString(PartExceptionOCCError, "wire or list of wires expected"); + char* className = 0; + PyObject* pcPyShapeOrList = nullptr; + PyErr_Clear(); + if (PyArg_ParseTuple(args, "Os", &pcPyShapeOrList, &className)) { + try{ + std::unique_ptr fm_instance = Part::FaceMaker::ConstructFromType(className); + FaceMaker* fm = &(*fm_instance); + + //dump all supplied shapes to facemaker, no matter what type (let facemaker decide). + if (PySequence_Check(pcPyShapeOrList)){ + Py::Sequence list(pcPyShapeOrList); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + PyObject* item = (*it).ptr(); + if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) { + const TopoDS_Shape& sh = static_cast(item)->getTopoShapePtr()->getShape(); + fm->addShape(sh); + } else { + PyErr_SetString(PyExc_TypeError, "Object is not a shape."); + return -1; + } + } + } else if (PyObject_TypeCheck(pcPyShapeOrList, &(Part::TopoShapePy::Type))) { + const TopoDS_Shape& sh = static_cast(pcPyShapeOrList)->getTopoShapePtr()->getShape(); + if (sh.IsNull()) + throw Base::Exception("Shape is null!"); + if (sh.ShapeType() == TopAbs_COMPOUND) + fm->useCompound(TopoDS::Compound(sh)); + else + fm->addShape(sh); + } else { + PyErr_SetString(PyExc_TypeError, "First argument is neither a shape nor list of shapes."); + return -1; + } + + fm->Build(); + + getTopoShapePtr()->setShape(fm->Face()); + return 0; + } catch (Base::Exception &e){ + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return -1; + } catch (Standard_Failure){ + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PartExceptionOCCError, e->GetMessageString()); + return -1; + } + } ; + + PyErr_SetString(PartExceptionOCCError, + "Argument list signature is incorrect.\n\nSupported signatures:\n" + "(face)\n" + "(wire)\n" + "(list_of_wires)\n" + "(wire, facemaker_class_name)\n" + "(list_of_wires, facemaker_class_name)\n" + "(surface, list_of_wires)\n" + ); return -1; }