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.
This commit is contained in:
DeepSOIC 2016-09-25 18:34:58 +03:00
parent 320763d78a
commit 1757f70cdf
2 changed files with 125 additions and 1 deletions

View File

@ -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<FaceMaker> 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<Part::TopoShapePy*>(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<Part::TopoShapePy*>(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

View File

@ -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<FaceMaker> 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<Part::TopoShapePy*>(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<Part::TopoShapePy*>(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;
}