diff --git a/src/Mod/MeshPart/App/AppMeshPart.cpp b/src/Mod/MeshPart/App/AppMeshPart.cpp index bf505f9d6..d29b517ff 100644 --- a/src/Mod/MeshPart/App/AppMeshPart.cpp +++ b/src/Mod/MeshPart/App/AppMeshPart.cpp @@ -30,15 +30,16 @@ #include -extern struct PyMethodDef MeshPart_methods[]; +namespace MeshPart { +extern PyObject* initModule(); +} PyDoc_STRVAR(module_MeshPart_doc, "This module is the MeshPart module."); /* Python entry */ -extern "C" { -void MeshPartExport initMeshPart() +PyMODINIT_FUNC initMeshPart() { // load dependent module try { @@ -49,15 +50,6 @@ void MeshPartExport initMeshPart() PyErr_SetString(PyExc_ImportError, e.what()); return; } - Py_InitModule3("MeshPart", MeshPart_methods, module_MeshPart_doc); /* mod name, table ptr */ + (void)MeshPart::initModule(); Base::Console().Log("Loading MeshPart module... done\n"); - - - // NOTE: To finish the initialization of our own type objects we must - // call PyType_Ready, otherwise we run into a segmentation fault, later on. - // This function is responsible for adding inherited slots from a type's base class. - - //MeshPart::FeatureViewPart ::init(); } - -} // extern "C" diff --git a/src/Mod/MeshPart/App/AppMeshPartPy.cpp b/src/Mod/MeshPart/App/AppMeshPartPy.cpp index 3395884a7..30c601659 100644 --- a/src/Mod/MeshPart/App/AppMeshPartPy.cpp +++ b/src/Mod/MeshPart/App/AppMeshPartPy.cpp @@ -26,6 +26,9 @@ # include #endif +#include +#include + #include #include #include @@ -38,82 +41,125 @@ #include "MeshAlgos.h" #include "Mesher.h" -static PyObject * -loftOnCurve(PyObject *self, PyObject *args) +namespace MeshPart { +class Module : public Py::ExtensionModule { - Part::TopoShapePy *pcObject; - PyObject *pcTopoObj,*pcListObj; - float x=0.0f,y=0.0f,z=1.0f,size = 0.1f; - - if (!PyArg_ParseTuple(args, "O!O(fff)f", &(Part::TopoShapePy::Type), &pcTopoObj,&pcListObj,&x,&y,&z,&size)) // convert args: Python->C -// if (!PyArg_ParseTuple(args, "O!O!", &(App::TopoShapePy::Type), &pcTopoObj,&PyList_Type,&pcListObj,x,y,z,size)) // convert args: Python->C - return NULL; // NULL triggers exception - - pcObject = (Part::TopoShapePy*)pcTopoObj; - MeshCore::MeshKernel M; - - std::vector poly; - - if (!PyList_Check(pcListObj)) - Py_Error(Base::BaseExceptionFreeCADError,"List of Tuble of three or two floats needed as second parameter!"); - - int nSize = PyList_Size(pcListObj); - for (int i=0; i("MeshPart") { - PyObject* item = PyList_GetItem(pcListObj, i); - if (!PyTuple_Check(item)) - Py_Error(Base::BaseExceptionFreeCADError,"List of Tuble of three or two floats needed as second parameter!"); - int nTSize = PyTuple_Size(item); - if(nTSize != 2 && nTSize != 3) - Py_Error(Base::BaseExceptionFreeCADError,"List of Tuble of three or two floats needed as second parameter!"); - - Base::Vector3f vec(0,0,0); - - for(int l = 0; l < nTSize;l++) - { - PyObject* item2 = PyTuple_GetItem(item, l); - if (!PyFloat_Check(item2)) - Py_Error(Base::BaseExceptionFreeCADError,"List of Tuble of three or two floats needed as second parameter!"); - vec[l] = (float)PyFloat_AS_DOUBLE(item2); - } - poly.push_back(vec); + add_varargs_method("loftOnCurve",&Module::loftOnCurve, + "Loft on curve." + ); + add_varargs_method("wireFromSegment",&Module::wireFromSegment, + "Create wire(s) from boundary of segment" + ); + add_keyword_method("meshFromShape",&Module::meshFromShape, + "Create mesh from shape" + ); + initialize("This module is the MeshPart module."); // register with Python } - - PY_TRY { + + virtual ~Module() {} + +private: + virtual Py::Object invoke_method_varargs(void *method_def, const Py::Tuple &args) + { + try { + return Py::ExtensionModule::invoke_method_varargs(method_def, args); + } + catch (const Standard_Failure &e) { + std::string str; + Standard_CString msg = e.GetMessageString(); + str += typeid(e).name(); + str += " "; + if (msg) {str += msg;} + else {str += "No OCCT Exception Message";} + Base::Console().Error("%s\n", str.c_str()); + throw Py::Exception(Base::BaseExceptionFreeCADError, str); + } + catch (const Base::Exception &e) { + std::string str; + str += "FreeCAD exception thrown ("; + str += e.what(); + str += ")"; + e.ReportException(); + throw Py::RuntimeError(str); + } + catch (const std::exception &e) { + std::string str; + str += "C++ exception thrown ("; + str += e.what(); + str += ")"; + Base::Console().Error("%s\n", str.c_str()); + throw Py::RuntimeError(str); + } + } + + Py::Object loftOnCurve(const Py::Tuple& args) + { + Part::TopoShapePy *pcObject; + PyObject *pcTopoObj,*pcListObj; + float x=0.0f,y=0.0f,z=1.0f,size = 0.1f; + + if (!PyArg_ParseTuple(args.ptr(), "O!O(fff)f", &(Part::TopoShapePy::Type), &pcTopoObj,&pcListObj,&x,&y,&z,&size)) +// if (!PyArg_ParseTuple(args, "O!O!", &(App::TopoShapePy::Type), &pcTopoObj,&PyList_Type,&pcListObj,x,y,z,size)) + throw Py::Exception(); + + pcObject = static_cast(pcTopoObj); + MeshCore::MeshKernel M; + + std::vector poly; + + if (!PyList_Check(pcListObj)) + throw Py::Exception(Base::BaseExceptionFreeCADError,"List of Tuble of three or two floats needed as second parameter!"); + + int nSize = PyList_Size(pcListObj); + for (int i=0; igetTopoShapePtr()->_Shape; // use the MeshAlgos MeshPart::MeshAlgos::LoftOnCurve(M,aShape,poly,Base::Vector3f(x,y,z),size); - - } PY_CATCH; - - return new Mesh::MeshPy(new Mesh::MeshObject(M)); -} - -PyDoc_STRVAR(loft_doc, -"Loft on curve."); - -static PyObject * -wireFromSegment(PyObject *self, PyObject *args) -{ - PyObject *o, *m; - if (!PyArg_ParseTuple(args, "O!O!", &(Mesh::MeshPy::Type), &m,&PyList_Type,&o)) - return 0; - Py::List list(o); - Mesh::MeshObject* mesh = static_cast(m)->getMeshObjectPtr(); - std::vector segm; - segm.reserve(list.size()); - for (unsigned int i=0; i > bounds; - MeshCore::MeshAlgorithm algo(mesh->getKernel()); - algo.GetFacetBorders(segm, bounds); + Py::List list(o); + Mesh::MeshObject* mesh = static_cast(m)->getMeshObjectPtr(); + std::vector segm; + segm.reserve(list.size()); + for (unsigned int i=0; i >::iterator bt; + std::list > bounds; + MeshCore::MeshAlgorithm algo(mesh->getKernel()); + algo.GetFacetBorders(segm, bounds); + + Py::List wires; + std::list >::iterator bt; - try { for (bt = bounds.begin(); bt != bounds.end(); ++bt) { BRepBuilderAPI_MakePolygon mkPoly; for (std::vector::reverse_iterator it = bt->rbegin(); it != bt->rend(); ++it) { @@ -124,87 +170,78 @@ wireFromSegment(PyObject *self, PyObject *args) wires.append(Py::Object(wire, true)); } } - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } - return Py::new_reference_to(wires); -} - -static PyObject * -meshFromShape(PyObject *self, PyObject *args, PyObject* kwds) -{ - try { + return wires; + } + Py::Object meshFromShape(const Py::Tuple& args, const Py::Dict& kwds) + { PyObject *shape; static char* kwds_maxLength[] = {"Shape", "MaxLength",NULL}; PyErr_Clear(); double maxLength=0; - if (PyArg_ParseTupleAndKeywords(args, kwds, "O!d", kwds_maxLength, + if (PyArg_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!d", kwds_maxLength, &(Part::TopoShapePy::Type), &shape, &maxLength)) { MeshPart::Mesher mesher(static_cast(shape)->getTopoShapePtr()->_Shape); mesher.setMethod(MeshPart::Mesher::Mefisto); mesher.setMaxLength(maxLength); mesher.setRegular(true); - return new Mesh::MeshPy(mesher.createMesh()); + return Py::asObject(new Mesh::MeshPy(mesher.createMesh())); } static char* kwds_maxArea[] = {"Shape", "MaxArea",NULL}; PyErr_Clear(); double maxArea=0; - if (PyArg_ParseTupleAndKeywords(args, kwds, "O!d", kwds_maxArea, + if (PyArg_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!d", kwds_maxArea, &(Part::TopoShapePy::Type), &shape, &maxArea)) { MeshPart::Mesher mesher(static_cast(shape)->getTopoShapePtr()->_Shape); mesher.setMethod(MeshPart::Mesher::Mefisto); mesher.setMaxArea(maxArea); mesher.setRegular(true); - return new Mesh::MeshPy(mesher.createMesh()); + return Py::asObject(new Mesh::MeshPy(mesher.createMesh())); } static char* kwds_localLen[] = {"Shape", "LocalLength",NULL}; PyErr_Clear(); double localLen=0; - if (PyArg_ParseTupleAndKeywords(args, kwds, "O!d", kwds_localLen, + if (PyArg_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!d", kwds_localLen, &(Part::TopoShapePy::Type), &shape, &localLen)) { MeshPart::Mesher mesher(static_cast(shape)->getTopoShapePtr()->_Shape); mesher.setMethod(MeshPart::Mesher::Mefisto); mesher.setLocalLength(localLen); mesher.setRegular(true); - return new Mesh::MeshPy(mesher.createMesh()); + return Py::asObject(new Mesh::MeshPy(mesher.createMesh())); } static char* kwds_deflection[] = {"Shape", "Deflection",NULL}; PyErr_Clear(); double deflection=0; - if (PyArg_ParseTupleAndKeywords(args, kwds, "O!d", kwds_deflection, + if (PyArg_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!d", kwds_deflection, &(Part::TopoShapePy::Type), &shape, &deflection)) { MeshPart::Mesher mesher(static_cast(shape)->getTopoShapePtr()->_Shape); mesher.setMethod(MeshPart::Mesher::Mefisto); mesher.setDeflection(deflection); mesher.setRegular(true); - return new Mesh::MeshPy(mesher.createMesh()); + return Py::asObject(new Mesh::MeshPy(mesher.createMesh())); } static char* kwds_minmaxLen[] = {"Shape", "MinLength","MaxLength",NULL}; PyErr_Clear(); double minLen=0, maxLen=0; - if (PyArg_ParseTupleAndKeywords(args, kwds, "O!dd", kwds_minmaxLen, + if (PyArg_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!dd", kwds_minmaxLen, &(Part::TopoShapePy::Type), &shape, &minLen, &maxLen)) { MeshPart::Mesher mesher(static_cast(shape)->getTopoShapePtr()->_Shape); mesher.setMethod(MeshPart::Mesher::Mefisto); mesher.setMinMaxLengths(minLen, maxLen); mesher.setRegular(true); - return new Mesh::MeshPy(mesher.createMesh()); + return Py::asObject(new Mesh::MeshPy(mesher.createMesh())); } #if defined (HAVE_NETGEN) static char* kwds_fineness[] = {"Shape", "Fineness", "SecondOrder", "Optimize", "AllowQuad",NULL}; PyErr_Clear(); int fineness=0, secondOrder=0, optimize=1, allowquad=0; - if (PyArg_ParseTupleAndKeywords(args, kwds, "O!i|iii", kwds_fineness, + if (PyArg_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!i|iii", kwds_fineness, &(Part::TopoShapePy::Type), &shape, &fineness, &secondOrder, &optimize, &allowquad)) { MeshPart::Mesher mesher(static_cast(shape)->getTopoShapePtr()->_Shape); @@ -213,13 +250,13 @@ meshFromShape(PyObject *self, PyObject *args, PyObject* kwds) mesher.setSecondOrder(secondOrder > 0); mesher.setOptimize(optimize > 0); mesher.setQuadAllowed(allowquad > 0); - return new Mesh::MeshPy(mesher.createMesh()); + return Py::asObject(new Mesh::MeshPy(mesher.createMesh())); } static char* kwds_user[] = {"Shape", "GrowthRate", "SegPerEdge", "SegPerRadius", "SecondOrder", "Optimize", "AllowQuad",NULL}; PyErr_Clear(); double growthRate=0, nbSegPerEdge=0, nbSegPerRadius=0; - if (PyArg_ParseTupleAndKeywords(args, kwds, "O!|dddiii", kwds_user, + if (PyArg_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O!|dddiii", kwds_user, &(Part::TopoShapePy::Type), &shape, &growthRate, &nbSegPerEdge, &nbSegPerRadius, &secondOrder, &optimize, &allowquad)) { @@ -231,12 +268,12 @@ meshFromShape(PyObject *self, PyObject *args, PyObject* kwds) mesher.setSecondOrder(secondOrder > 0); mesher.setOptimize(optimize > 0); mesher.setQuadAllowed(allowquad > 0); - return new Mesh::MeshPy(mesher.createMesh()); + return Py::asObject(new Mesh::MeshPy(mesher.createMesh())); } #endif PyErr_Clear(); - if (PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &shape)) { + if (PyArg_ParseTuple(args.ptr(), "O!", &(Part::TopoShapePy::Type), &shape)) { MeshPart::Mesher mesher(static_cast(shape)->getTopoShapePtr()->_Shape); #if defined (HAVE_NETGEN) mesher.setMethod(MeshPart::Mesher::Netgen); @@ -244,24 +281,16 @@ meshFromShape(PyObject *self, PyObject *args, PyObject* kwds) mesher.setMethod(MeshPart::Mesher::Mefisto); mesher.setRegular(true); #endif - return new Mesh::MeshPy(mesher.createMesh()); + return Py::asObject(new Mesh::MeshPy(mesher.createMesh())); } - } - catch (const Base::Exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - PyErr_SetString(Base::BaseExceptionFreeCADError,"Wrong arguments"); - return 0; + throw Py::Exception(Base::BaseExceptionFreeCADError,"Wrong arguments"); + } +}; + +PyObject* initModule() +{ + return (new Module)->module().ptr(); } -/* registration table */ -struct PyMethodDef MeshPart_methods[] = { - {"loftOnCurve",loftOnCurve, METH_VARARGS, loft_doc}, - {"wireFromSegment",wireFromSegment, METH_VARARGS, - "Create wire(s) from boundary of segment"}, - {"meshFromShape",(PyCFunction)meshFromShape, METH_VARARGS|METH_KEYWORDS, - "Create mesh from shape"}, - {NULL, NULL} /* end of table marker */ -}; +} // namespace MeshPart diff --git a/src/Mod/MeshPart/Gui/AppMeshPartGui.cpp b/src/Mod/MeshPart/Gui/AppMeshPartGui.cpp index 62cca702a..5af3c42ab 100644 --- a/src/Mod/MeshPart/Gui/AppMeshPartGui.cpp +++ b/src/Mod/MeshPart/Gui/AppMeshPartGui.cpp @@ -26,6 +26,9 @@ # include #endif +#include +#include + #include #include #include @@ -41,20 +44,37 @@ void loadMeshPartResource() Gui::Translator::instance()->refresh(); } -/* registration table */ -extern struct PyMethodDef MeshPartGui_Import_methods[]; +namespace MeshPartGui { +class Module : public Py::ExtensionModule +{ +public: + Module() : Py::ExtensionModule("MeshPartGui") + { + initialize("This module is the MeshPartGui module."); // register with Python + } + + virtual ~Module() {} + +private: +}; + +PyObject* initModule() +{ + return (new Module)->module().ptr(); +} + +} // namespace MeshPartGui /* Python entry */ -extern "C" { -void MeshPartGuiExport initMeshPartGui() +PyMODINIT_FUNC initMeshPartGui() { if (!Gui::Application::Instance) { PyErr_SetString(PyExc_ImportError, "Cannot load Gui module in console application."); return; } - (void) Py_InitModule("MeshPartGui", MeshPartGui_Import_methods); /* mod name, table ptr */ + (void)MeshPartGui::initModule(); Base::Console().Log("Loading GUI of MeshPart module... done\n"); // instantiating the commands @@ -64,5 +84,3 @@ void MeshPartGuiExport initMeshPartGui() // add resources and reloads the translators loadMeshPartResource(); } - -} // extern "C" { diff --git a/src/Mod/MeshPart/Gui/AppMeshPartGuiPy.cpp b/src/Mod/MeshPart/Gui/AppMeshPartGuiPy.cpp deleted file mode 100644 index 034c13a5b..000000000 --- a/src/Mod/MeshPart/Gui/AppMeshPartGuiPy.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2008 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 - - -/* registration table */ -struct PyMethodDef MeshPartGui_Import_methods[] = { - {NULL, NULL} /* end of table marker */ -}; diff --git a/src/Mod/MeshPart/Gui/CMakeLists.txt b/src/Mod/MeshPart/Gui/CMakeLists.txt index 77b4e8970..8b49d9725 100644 --- a/src/Mod/MeshPart/Gui/CMakeLists.txt +++ b/src/Mod/MeshPart/Gui/CMakeLists.txt @@ -48,7 +48,6 @@ SET(MeshPartGui_SRCS ${MeshPartGui_QRC_SRCS} ${MeshPartGui_UIC_HDRS} AppMeshPartGui.cpp - AppMeshPartGuiPy.cpp Command.cpp Resources/MeshPart.qrc PreCompiled.cpp