From cb92240458cf4b22e9e7315a8f47c606f54df425 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 20 Jan 2016 00:00:41 +0100 Subject: [PATCH] + simplify porting of Points module to Python3 --- src/Mod/Points/App/AppPoints.cpp | 18 +- src/Mod/Points/App/AppPointsPy.cpp | 372 +++++++++++++++------------- src/Mod/Points/Gui/AppPointsGui.cpp | 27 +- 3 files changed, 223 insertions(+), 194 deletions(-) diff --git a/src/Mod/Points/App/AppPoints.cpp b/src/Mod/Points/App/AppPoints.cpp index 7f353f2c3..fa7905546 100644 --- a/src/Mod/Points/App/AppPoints.cpp +++ b/src/Mod/Points/App/AppPoints.cpp @@ -35,22 +35,18 @@ #include "PropertyPointKernel.h" #include "ViewFeature.h" - -/* registration table */ - -extern struct PyMethodDef Points_Import_methods[]; - - +namespace Points { + extern PyObject* initModule(); +} /* Python entry */ -extern "C" { -void PointsExport initPoints() +PyMODINIT_FUNC initPoints() { - PyObject* pointsModule = Py_InitModule("Points", Points_Import_methods); /* mod name, table ptr */ + PyObject* pointsModule = Points::initModule(); Base::Console().Log("Loading Points module... done\n"); // add python types - Base::Interpreter().addType(&Points::PointsPy ::Type,pointsModule,"Points"); + Base::Interpreter().addType(&Points::PointsPy::Type, pointsModule, "Points"); // add properties Points::PropertyGreyValue ::init(); @@ -65,5 +61,3 @@ void PointsExport initPoints() Points::FeaturePython ::init(); Points::ViewFeature ::init(); } - -} // extern "C" diff --git a/src/Mod/Points/App/AppPointsPy.cpp b/src/Mod/Points/App/AppPointsPy.cpp index d79aca74b..5a1ef28eb 100644 --- a/src/Mod/Points/App/AppPointsPy.cpp +++ b/src/Mod/Points/App/AppPointsPy.cpp @@ -32,6 +32,9 @@ # include #endif +#include +#include + #include #include #include @@ -47,203 +50,224 @@ #include "PointsFeature.h" #include "Properties.h" -using namespace Points; - -/* module functions */ -static PyObject * -open(PyObject *self, PyObject *args) +namespace Points { +class Module : public Py::ExtensionModule { - char* Name; - if (!PyArg_ParseTuple(args, "et","utf-8",&Name)) - return NULL; - std::string EncodedName = std::string(Name); - PyMem_Free(Name); +public: + Module() : Py::ExtensionModule("Points") + { + add_varargs_method("open",&Module::open + ); + add_varargs_method("insert",&Module::insert + ); + add_varargs_method("show",&Module::show + ); + initialize("This module is the Points module."); // register with Python + } - PY_TRY { - Base::Console().Log("Open in Points with %s",EncodedName.c_str()); - Base::FileInfo file(EncodedName.c_str()); + virtual ~Module() {} - // extract ending - if (file.extension() == "") - Py_Error(Base::BaseExceptionFreeCADError,"no file ending"); +private: + Py::Object open(const Py::Tuple& args) + { + char* Name; + if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name)) + throw Py::Exception(); + std::string EncodedName = std::string(Name); + PyMem_Free(Name); - if (file.hasExtension("asc")) { - // create new document and add Import feature - App::Document *pcDoc = App::GetApplication().newDocument("Unnamed"); - Points::Feature *pcFeature = (Points::Feature *)pcDoc->addObject("Points::Feature", file.fileNamePure().c_str()); - Points::PointKernel pkTemp; - pkTemp.load(EncodedName.c_str()); - pcFeature->Points.setValue( pkTemp ); + try { + Base::Console().Log("Open in Points with %s",EncodedName.c_str()); + Base::FileInfo file(EncodedName.c_str()); - } + // extract ending + if (file.extension().empty()) + throw Py::RuntimeError("No file extension"); + + if (file.hasExtension("asc")) { + // create new document and add Import feature + App::Document *pcDoc = App::GetApplication().newDocument("Unnamed"); + Points::Feature *pcFeature = (Points::Feature *)pcDoc->addObject("Points::Feature", file.fileNamePure().c_str()); + Points::PointKernel pkTemp; + pkTemp.load(EncodedName.c_str()); + pcFeature->Points.setValue( pkTemp ); + + } #ifdef HAVE_PCL_IO - else if (file.hasExtension("ply")) { - PlyReader reader; - reader.read(EncodedName); + else if (file.hasExtension("ply")) { + PlyReader reader; + reader.read(EncodedName); - App::Document *pcDoc = App::GetApplication().newDocument("Unnamed"); - if (reader.hasProperties()) { - Points::FeatureCustom *pcFeature = new Points::FeatureCustom(); - pcFeature->Points.setValue(reader.getPoints()); - // add gray values - if (reader.hasIntensities()) { - Points::PropertyGreyValueList* prop = static_cast - (pcFeature->addDynamicProperty("Points::PropertyGreyValueList", "Intensity")); - if (prop) { - prop->setValues(reader.getIntensities()); + App::Document *pcDoc = App::GetApplication().newDocument("Unnamed"); + if (reader.hasProperties()) { + Points::FeatureCustom *pcFeature = new Points::FeatureCustom(); + pcFeature->Points.setValue(reader.getPoints()); + // add gray values + if (reader.hasIntensities()) { + Points::PropertyGreyValueList* prop = static_cast + (pcFeature->addDynamicProperty("Points::PropertyGreyValueList", "Intensity")); + if (prop) { + prop->setValues(reader.getIntensities()); + } } - } - // add colors - if (reader.hasColors()) { - App::PropertyColorList* prop = static_cast - (pcFeature->addDynamicProperty("App::PropertyColorList", "Color")); - if (prop) { - prop->setValues(reader.getColors()); + // add colors + if (reader.hasColors()) { + App::PropertyColorList* prop = static_cast + (pcFeature->addDynamicProperty("App::PropertyColorList", "Color")); + if (prop) { + prop->setValues(reader.getColors()); + } } - } - // add normals - if (reader.hasNormals()) { - Points::PropertyNormalList* prop = static_cast - (pcFeature->addDynamicProperty("Points::PropertyNormalList", "Normal")); - if (prop) { - prop->setValues(reader.getNormals()); + // add normals + if (reader.hasNormals()) { + Points::PropertyNormalList* prop = static_cast + (pcFeature->addDynamicProperty("Points::PropertyNormalList", "Normal")); + if (prop) { + prop->setValues(reader.getNormals()); + } } - } - // delayed adding of the points feature - pcDoc->addObject(pcFeature, file.fileNamePure().c_str()); - pcDoc->recomputeFeature(pcFeature); + // delayed adding of the points feature + pcDoc->addObject(pcFeature, file.fileNamePure().c_str()); + pcDoc->recomputeFeature(pcFeature); + } + else { + Points::Feature *pcFeature = static_cast + (pcDoc->addObject("Points::Feature", file.fileNamePure().c_str())); + pcFeature->Points.setValue(reader.getPoints()); + pcDoc->recomputeFeature(pcFeature); + } } - else { - Points::Feature *pcFeature = static_cast - (pcDoc->addObject("Points::Feature", file.fileNamePure().c_str())); - pcFeature->Points.setValue(reader.getPoints()); - pcDoc->recomputeFeature(pcFeature); - } - } #endif - else { - Py_Error(Base::BaseExceptionFreeCADError,"unknown file ending"); - } - } PY_CATCH; - - Py_Return; -} - -static PyObject * -insert(PyObject *self, PyObject *args) -{ - char* Name; - const char* DocName; - if (!PyArg_ParseTuple(args, "ets","utf-8",&Name,&DocName)) - return NULL; - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - - PY_TRY { - Base::Console().Log("Import in Points with %s",EncodedName.c_str()); - Base::FileInfo file(EncodedName.c_str()); - - // extract ending - if (file.extension() == "") - Py_Error(Base::BaseExceptionFreeCADError,"no file ending"); - - if (file.hasExtension("asc")) { - // add Import feature - App::Document *pcDoc = App::GetApplication().getDocument(DocName); - if (!pcDoc) { - pcDoc = App::GetApplication().newDocument(DocName); + else { + throw Py::RuntimeError("Unsupported file extension"); } - - Points::Feature *pcFeature = (Points::Feature *)pcDoc->addObject("Points::Feature", file.fileNamePure().c_str()); - Points::PointKernel pkTemp; - pkTemp.load(EncodedName.c_str()); - pcFeature->Points.setValue( pkTemp ); } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + + return Py::None(); + } + + Py::Object insert(const Py::Tuple& args) + { + char* Name; + const char* DocName; + if (!PyArg_ParseTuple(args.ptr(), "ets","utf-8",&Name,&DocName)) + throw Py::Exception(); + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + + try { + Base::Console().Log("Import in Points with %s",EncodedName.c_str()); + Base::FileInfo file(EncodedName.c_str()); + + // extract ending + if (file.extension().empty()) + throw Py::RuntimeError("No file extension"); + + if (file.hasExtension("asc")) { + // add Import feature + App::Document *pcDoc = App::GetApplication().getDocument(DocName); + if (!pcDoc) { + pcDoc = App::GetApplication().newDocument(DocName); + } + + Points::Feature *pcFeature = (Points::Feature *)pcDoc->addObject("Points::Feature", file.fileNamePure().c_str()); + Points::PointKernel pkTemp; + pkTemp.load(EncodedName.c_str()); + pcFeature->Points.setValue( pkTemp ); + } #ifdef HAVE_PCL_IO - else if (file.hasExtension("ply")) { - App::Document *pcDoc = App::GetApplication().getDocument(DocName); - if (!pcDoc) { - pcDoc = App::GetApplication().newDocument(DocName); - } - - PlyReader reader; - reader.read(EncodedName); - - if (reader.hasProperties()) { - Points::FeatureCustom *pcFeature = new Points::FeatureCustom(); - pcFeature->Points.setValue(reader.getPoints()); - // add gray values - if (reader.hasIntensities()) { - Points::PropertyGreyValueList* prop = static_cast - (pcFeature->addDynamicProperty("Points::PropertyGreyValueList", "Intensity")); - if (prop) { - prop->setValues(reader.getIntensities()); - } - } - // add colors - if (reader.hasColors()) { - App::PropertyColorList* prop = static_cast - (pcFeature->addDynamicProperty("App::PropertyColorList", "Color")); - if (prop) { - prop->setValues(reader.getColors()); - } - } - // add normals - if (reader.hasNormals()) { - Points::PropertyNormalList* prop = static_cast - (pcFeature->addDynamicProperty("Points::PropertyNormalList", "Normal")); - if (prop) { - prop->setValues(reader.getNormals()); - } + else if (file.hasExtension("ply")) { + App::Document *pcDoc = App::GetApplication().getDocument(DocName); + if (!pcDoc) { + pcDoc = App::GetApplication().newDocument(DocName); } - // delayed adding of the points feature - pcDoc->addObject(pcFeature, file.fileNamePure().c_str()); - pcDoc->recomputeFeature(pcFeature); + PlyReader reader; + reader.read(EncodedName); + + if (reader.hasProperties()) { + Points::FeatureCustom *pcFeature = new Points::FeatureCustom(); + pcFeature->Points.setValue(reader.getPoints()); + // add gray values + if (reader.hasIntensities()) { + Points::PropertyGreyValueList* prop = static_cast + (pcFeature->addDynamicProperty("Points::PropertyGreyValueList", "Intensity")); + if (prop) { + prop->setValues(reader.getIntensities()); + } + } + // add colors + if (reader.hasColors()) { + App::PropertyColorList* prop = static_cast + (pcFeature->addDynamicProperty("App::PropertyColorList", "Color")); + if (prop) { + prop->setValues(reader.getColors()); + } + } + // add normals + if (reader.hasNormals()) { + Points::PropertyNormalList* prop = static_cast + (pcFeature->addDynamicProperty("Points::PropertyNormalList", "Normal")); + if (prop) { + prop->setValues(reader.getNormals()); + } + } + + // delayed adding of the points feature + pcDoc->addObject(pcFeature, file.fileNamePure().c_str()); + pcDoc->recomputeFeature(pcFeature); + } + else { + Points::Feature *pcFeature = static_cast + (pcDoc->addObject("Points::Feature", file.fileNamePure().c_str())); + pcFeature->Points.setValue(reader.getPoints()); + pcDoc->recomputeFeature(pcFeature); + } } - else { - Points::Feature *pcFeature = static_cast - (pcDoc->addObject("Points::Feature", file.fileNamePure().c_str())); - pcFeature->Points.setValue(reader.getPoints()); - pcDoc->recomputeFeature(pcFeature); - } - } #endif - else { - Py_Error(Base::BaseExceptionFreeCADError,"unknown file ending"); + else { + throw Py::RuntimeError("Unsupported file extension"); + } + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); } - } PY_CATCH; - Py_Return; -} + return Py::None(); + } -static PyObject * -show(PyObject *self, PyObject *args) -{ - PyObject *pcObj; - if (!PyArg_ParseTuple(args, "O!", &(PointsPy::Type), &pcObj)) // convert args: Python->C - return NULL; // NULL triggers exception + Py::Object show(const Py::Tuple& args) + { + PyObject *pcObj; + if (!PyArg_ParseTuple(args.ptr(), "O!", &(PointsPy::Type), &pcObj)) + throw Py::Exception(); - PY_TRY { - App::Document *pcDoc = App::GetApplication().getActiveDocument(); - if (!pcDoc) - pcDoc = App::GetApplication().newDocument(); - PointsPy* pPoints = static_cast(pcObj); - Points::Feature *pcFeature = (Points::Feature *)pcDoc->addObject("Points::Feature", "Points"); - // copy the data - //TopoShape* shape = new MeshObject(*pShape->getTopoShapeObjectPtr()); - pcFeature->Points.setValue(*(pPoints->getPointKernelPtr())); - //pcDoc->recompute(); - } PY_CATCH; + try { + App::Document *pcDoc = App::GetApplication().getActiveDocument(); + if (!pcDoc) + pcDoc = App::GetApplication().newDocument(); + PointsPy* pPoints = static_cast(pcObj); + Points::Feature *pcFeature = (Points::Feature *)pcDoc->addObject("Points::Feature", "Points"); + // copy the data + //TopoShape* shape = new MeshObject(*pShape->getTopoShapeObjectPtr()); + pcFeature->Points.setValue(*(pPoints->getPointKernelPtr())); + //pcDoc->recompute(); + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } - Py_Return; -} - -// registration table -struct PyMethodDef Points_Import_methods[] = { - {"open", open, 1}, /* method name, C func ptr, always-tuple */ - {"insert",insert, 1}, - {"show",show, 1}, - {NULL, NULL} /* end of table marker */ + return Py::None(); + } }; + +PyObject* initModule() +{ + return (new Module())->module().ptr(); +} + +} // namespace Points diff --git a/src/Mod/Points/Gui/AppPointsGui.cpp b/src/Mod/Points/Gui/AppPointsGui.cpp index b54d6f26c..ed79d26f0 100644 --- a/src/Mod/Points/Gui/AppPointsGui.cpp +++ b/src/Mod/Points/Gui/AppPointsGui.cpp @@ -25,6 +25,9 @@ #ifndef _PreComp_ #endif +#include +#include + #include "ViewProvider.h" #include "Workbench.h" @@ -44,15 +47,25 @@ void loadPointsResource() Gui::Translator::instance()->refresh(); } +namespace PointsGui { +class Module : public Py::ExtensionModule +{ +public: + Module() : Py::ExtensionModule("PointsGui") + { + initialize("This module is the PointsGui module."); // register with Python + } -/* registration table */ -static struct PyMethodDef PointsGui_methods[] = { - {NULL, NULL} /* end of table marker */ + virtual ~Module() {} + +private: }; +} // namespace PointsGui + + /* Python entry */ -extern "C" { -void PointsGuiExport initPointsGui() +PyMODINIT_FUNC initPointsGui() { if (!Gui::Application::Instance) { PyErr_SetString(PyExc_ImportError, "Cannot load Gui module in console application."); @@ -69,7 +82,7 @@ void PointsGuiExport initPointsGui() } Base::Console().Log("Loading GUI of Points module... done\n"); - (void) Py_InitModule("PointsGui", PointsGui_methods); /* mod name, table ptr */ + (void)new PointsGui::Module(); // instantiating the commands CreatePointsCommands(); @@ -84,5 +97,3 @@ void PointsGuiExport initPointsGui() // add resources and reloads the translators loadPointsResource(); } - -} // extern "C"