diff --git a/src/Mod/Raytracing/App/AppRaytracing.cpp b/src/Mod/Raytracing/App/AppRaytracing.cpp index 24d9ca6ee..db669ec9a 100644 --- a/src/Mod/Raytracing/App/AppRaytracing.cpp +++ b/src/Mod/Raytracing/App/AppRaytracing.cpp @@ -35,11 +35,12 @@ #include "LuxFeature.h" #include "LuxProject.h" -extern struct PyMethodDef Raytracing_methods[]; +namespace Raytracing { + extern PyObject* initModule(); +} -extern "C" { -void AppRaytracingExport initRaytracing() +PyMODINIT_FUNC initRaytracing() { // load dependent module try { @@ -50,16 +51,13 @@ void AppRaytracingExport initRaytracing() return; } - Raytracing::RaySegment ::init(); - Raytracing::RayFeature ::init(); - Raytracing::RayProject ::init(); + Raytracing::RaySegment ::init(); + Raytracing::RayFeature ::init(); + Raytracing::RayProject ::init(); Raytracing::LuxFeature ::init(); Raytracing::LuxProject ::init(); - (void) Py_InitModule("Raytracing", Raytracing_methods); /* mod name, table ptr */ + (void) Raytracing::initModule(); Base::Console().Log("Loading Raytracing module... done\n"); - } - -} // extern "C" { diff --git a/src/Mod/Raytracing/App/AppRaytracingPy.cpp b/src/Mod/Raytracing/App/AppRaytracingPy.cpp index e043300d2..cd702a034 100644 --- a/src/Mod/Raytracing/App/AppRaytracingPy.cpp +++ b/src/Mod/Raytracing/App/AppRaytracingPy.cpp @@ -27,6 +27,9 @@ #include +#include +#include + #include #include "PovTools.h" #include "LuxTools.h" @@ -37,217 +40,211 @@ #include #include -using namespace Raytracing; - -/// write empty project file -static PyObject * -writeProjectFile(PyObject *self, PyObject *args) +namespace Raytracing { +class Module : public Py::ExtensionModule { - char *fromPython; - if (! PyArg_ParseTuple(args, "(s)", &fromPython)) - return NULL; - - std::ofstream fout; - if(fromPython) - fout.open(fromPython); - else - fout.open("FreeCAD.pov"); - - fout << FreeCAD ; - fout.close(); - - Py_Return; -} - -/// write project file -static PyObject * -getProjectFile(PyObject *self, PyObject *args) -{ - return Py_BuildValue("s", FreeCAD); -} - -/// get part file as string -static PyObject * -getPartAsPovray(PyObject *self, PyObject *args) -{ - float r=0.5,g=0.5,b=0.5; - PyObject *ShapeObject; - const char *PartName; - if (! PyArg_ParseTuple(args, "sO!|fff",&PartName, - &(Part::TopoShapePy::Type), &ShapeObject,&r,&g,&b)) - return NULL; - - std::stringstream out; - TopoDS_Shape &aShape = static_cast(ShapeObject)->getTopoShapePtr()->_Shape; - - PovTools::writeShape(out,PartName,aShape,(float)0.1); - // This must not be done in PovTools::writeShape! - out << "// instance to render" << endl - << "object {" << PartName << endl - << " texture {" << endl - << " pigment {color rgb <"<}" << endl - << " finish {StdFinish } //definition on top of the project" << endl - << " }" << endl - << "}" << endl ; - return Py::new_reference_to(Py::String(out.str())); -} - -/// get part as lux string -static PyObject * -getPartAsLux(PyObject *self, PyObject *args) -{ - float r=0.5,g=0.5,b=0.5; - PyObject *ShapeObject; - const char *PartName; - if (! PyArg_ParseTuple(args, "sO!|fff",&PartName, - &(Part::TopoShapePy::Type), &ShapeObject,&r,&g,&b)) - return NULL; - - std::stringstream out; - TopoDS_Shape &aShape = static_cast(ShapeObject)->getTopoShapePtr()->_Shape; - - // write a material entry - // This must not be done in PovTools::writeShape! - out << "MakeNamedMaterial \"FreeCADMaterial_" << PartName << "\"" << endl; - out << " \"color Kd\" [" << r << " " << g << " " << b << "]" << endl; - out << " \"float sigma\" [0.000000000000000]" << endl; - out << " \"string type\" [\"matte\"]" << endl << endl; - - LuxTools::writeShape(out,PartName,aShape,(float)0.1); - - return Py::new_reference_to(Py::String(out.str())); -} - -/// write part file -static PyObject * -writePartFile(PyObject *self, PyObject *args) -{ - PyObject *ShapeObject; - const char *FileName,*PartName; - if (! PyArg_ParseTuple(args, "ssO!",&FileName,&PartName, - &(Part::TopoShapePy::Type), &ShapeObject)) - return NULL; - - TopoDS_Shape &aShape = static_cast(ShapeObject)->getTopoShapePtr()->_Shape; - - PovTools::writeShape(FileName,PartName,aShape,(float)0.1); - - Py_Return; -} - -/// write part file -static PyObject * -writeDataFile(PyObject *self, PyObject *args) -{ - PyObject *dataObject; - const char *FileName,*PartName; - if (! PyArg_ParseTuple(args, "ssO!",&FileName,&PartName, - &(Data::ComplexGeoDataPy::Type), &dataObject)) - return 0; - - const Data::ComplexGeoData* aData = static_cast - (dataObject)->getComplexGeoDataPtr(); - - PovTools::writeData(FileName,PartName,aData,0.1f); - - Py_Return; -} - -/// write part file as CSV -static PyObject * -writePartFileCSV(PyObject *self, PyObject *args) -{ - PyObject *ShapeObject; - const char *FileName; - float Acur,Length; - if (! PyArg_ParseTuple(args, "O!sff",&(Part::TopoShapePy::Type), - &ShapeObject,&FileName,&Acur,&Length)) - return NULL; - - TopoDS_Shape aShape = static_cast(ShapeObject)->getTopoShapePtr()->_Shape; - PovTools::writeShapeCSV(FileName,aShape,Acur,Length); - Py_Return; -} - -/// write project file -static PyObject * -writeCameraFile(PyObject *self, PyObject *args) -{ - PyObject *Arg[4]; - const char *FileName; - double vecs[4][3]; - if (! PyArg_ParseTuple(args, "sO!O!O!O!",&FileName,&PyTuple_Type, - &Arg[0],&PyTuple_Type, &Arg[1],&PyTuple_Type, &Arg[2],&PyTuple_Type, &Arg[3])) - return NULL; - - // go throug the Tuple of Tupls - for(int i=0;i<4;i++) { - // check the right size of the Tuple of floats - if(PyTuple_GET_SIZE(Arg[i]) != 3) - Py_Error(Base::BaseExceptionFreeCADError,"Wrong parameter format, four Tuple of three floats needed!"); - - // go through the Tuple of floats - for(int l=0;l<3;l++) { - PyObject* temp = PyTuple_GetItem(Arg[i],l); - // check Type - if (PyFloat_Check(temp)) - vecs[i][l] = PyFloat_AsDouble(temp); - else if (PyLong_Check(temp)) - vecs[i][l] = (double) PyLong_AsLong(temp); - else if (PyInt_Check(temp)) - vecs[i][l] = (double) PyInt_AsLong(temp); - else - Py_Error(Base::BaseExceptionFreeCADError,"Wrong parameter format, four Tuple of three floats needed!"); - } +public: + Module() : Py::ExtensionModule("Raytracing") + { + add_varargs_method("writeProjectFile",&Module::writeProjectFile + ); + add_varargs_method("getProjectFile",&Module::getProjectFile + ); + add_varargs_method("getPartAsPovray",&Module::getPartAsPovray + ); + add_varargs_method("getPartAsLux",&Module::getPartAsLux + ); + add_varargs_method("writePartFile",&Module::writePartFile + ); + add_varargs_method("writeDataFile",&Module::writeDataFile + ); + add_varargs_method("writePartFileCSV",&Module::writePartFileCSV + ); + add_varargs_method("writeCameraFile",&Module::writeCameraFile + ); + add_varargs_method("copyResource",&Module::copyResource + ); + initialize("This module is the Raytracing module."); // register with Python } - // call the write method of PovTools.... - PovTools::writeCamera(FileName,CamDef(gp_Vec(vecs[0][0],vecs[0][1],vecs[0][2]), - gp_Vec(vecs[1][0],vecs[1][1],vecs[1][2]), - gp_Vec(vecs[2][0],vecs[2][1],vecs[2][2]), - gp_Vec(vecs[3][0],vecs[3][1],vecs[3][2]))); + virtual ~Module() {} - Py_Return; -} +private: + Py::Object writeProjectFile(const Py::Tuple& args) + { + char *fromPython; + if (! PyArg_ParseTuple(args.ptr(), "(s)", &fromPython)) + throw Py::Exception(); -/// write project file -static PyObject * -copyResource(PyObject *self, PyObject *args) -{ - const char *FileName,*DestDir; - if (! PyArg_ParseTuple(args, "ss",&FileName,&DestDir)) - return NULL; + std::ofstream fout; + if (fromPython) + fout.open(fromPython); + else + fout.open("FreeCAD.pov"); - std::string resName = App::GetApplication().getHomePath(); - resName += "Mod"; - resName += PATHSEP ; - resName += "Raytracing"; - resName += PATHSEP ; - resName += "resources"; - resName += PATHSEP; - resName += FileName; + fout << FreeCAD ; + fout.close(); + return Py::None(); + } + Py::Object getProjectFile(const Py::Tuple& /*args*/) + { + return Py::String(FreeCAD); + } + Py::Object getPartAsPovray(const Py::Tuple& args) + { + float r=0.5,g=0.5,b=0.5; + PyObject *ShapeObject; + const char *PartName; + if (! PyArg_ParseTuple(args.ptr(), "sO!|fff",&PartName, + &(Part::TopoShapePy::Type), &ShapeObject,&r,&g,&b)) + throw Py::Exception(); - Base::Console().Warning("Using fileName = %s\nRaytracer scene file not generated " - "because function is not implemented yet.\nYou can copy " - "the standard scene file FreeCAD.pov to your raytracing " - "directory to render the scene.\n",resName.c_str()); + std::stringstream out; + TopoDS_Shape &aShape = static_cast(ShapeObject)->getTopoShapePtr()->_Shape; + + PovTools::writeShape(out,PartName,aShape,(float)0.1); + // This must not be done in PovTools::writeShape! + out << "// instance to render" << endl + << "object {" << PartName << endl + << " texture {" << endl + << " pigment {color rgb <"<}" << endl + << " finish {StdFinish } //definition on top of the project" << endl + << " }" << endl + << "}" << endl ; + return Py::String(out.str()); + } + Py::Object getPartAsLux(const Py::Tuple& args) + { + float r=0.5,g=0.5,b=0.5; + PyObject *ShapeObject; + const char *PartName; + if (! PyArg_ParseTuple(args.ptr(), "sO!|fff",&PartName, + &(Part::TopoShapePy::Type), &ShapeObject,&r,&g,&b)) + throw Py::Exception(); + + std::stringstream out; + TopoDS_Shape &aShape = static_cast(ShapeObject)->getTopoShapePtr()->_Shape; + + // write a material entry + // This must not be done in PovTools::writeShape! + out << "MakeNamedMaterial \"FreeCADMaterial_" << PartName << "\"" << endl; + out << " \"color Kd\" [" << r << " " << g << " " << b << "]" << endl; + out << " \"float sigma\" [0.000000000000000]" << endl; + out << " \"string type\" [\"matte\"]" << endl << endl; + + LuxTools::writeShape(out,PartName,aShape,(float)0.1); + return Py::String(out.str()); + } + Py::Object writePartFile(const Py::Tuple& args) + { + PyObject *ShapeObject; + const char *FileName,*PartName; + if (! PyArg_ParseTuple(args.ptr(), "ssO!",&FileName,&PartName, + &(Part::TopoShapePy::Type), &ShapeObject)) + throw Py::Exception(); + + TopoDS_Shape &aShape = static_cast(ShapeObject)->getTopoShapePtr()->_Shape; + + PovTools::writeShape(FileName,PartName,aShape,(float)0.1); + + return Py::None(); + } + Py::Object writeDataFile(const Py::Tuple& args) + { + PyObject *dataObject; + const char *FileName,*PartName; + if (! PyArg_ParseTuple(args.ptr(), "ssO!",&FileName,&PartName, + &(Data::ComplexGeoDataPy::Type), &dataObject)) + throw Py::Exception(); + + const Data::ComplexGeoData* aData = static_cast + (dataObject)->getComplexGeoDataPtr(); + + PovTools::writeData(FileName,PartName,aData,0.1f); + + return Py::None(); + } + Py::Object writePartFileCSV(const Py::Tuple& args) + { + PyObject *ShapeObject; + const char *FileName; + float Acur,Length; + if (!PyArg_ParseTuple(args.ptr(), "O!sff",&(Part::TopoShapePy::Type), + &ShapeObject,&FileName,&Acur,&Length)) + throw Py::Exception(); + + TopoDS_Shape aShape = static_cast(ShapeObject)->getTopoShapePtr()->_Shape; + PovTools::writeShapeCSV(FileName,aShape,Acur,Length); + return Py::None(); + } + Py::Object writeCameraFile(const Py::Tuple& args) + { + PyObject *Arg[4]; + const char *FileName; + double vecs[4][3]; + if (!PyArg_ParseTuple(args.ptr(), "sO!O!O!O!",&FileName,&PyTuple_Type, + &Arg[0],&PyTuple_Type, &Arg[1],&PyTuple_Type, &Arg[2],&PyTuple_Type, &Arg[3])) + throw Py::Exception(); + + // go throug the Tuple of Tuples + for (int i=0;i<4;i++) { + // check the right size of the Tuple of floats + if (PyTuple_GET_SIZE(Arg[i]) != 3) + throw Py::ValueError("Wrong parameter format, four Tuple of three floats needed!"); + + // go through the Tuple of floats + for (int l=0;l<3;l++) { + PyObject* temp = PyTuple_GetItem(Arg[i],l); + // check Type + if (PyFloat_Check(temp)) + vecs[i][l] = PyFloat_AsDouble(temp); + else if (PyLong_Check(temp)) + vecs[i][l] = (double) PyLong_AsLong(temp); + else if (PyInt_Check(temp)) + vecs[i][l] = (double) PyInt_AsLong(temp); + else + throw Py::ValueError("Wrong parameter format, four Tuple of three floats needed!"); + } + } + + // call the write method of PovTools.... + PovTools::writeCamera(FileName,CamDef(gp_Vec(vecs[0][0],vecs[0][1],vecs[0][2]), + gp_Vec(vecs[1][0],vecs[1][1],vecs[1][2]), + gp_Vec(vecs[2][0],vecs[2][1],vecs[2][2]), + gp_Vec(vecs[3][0],vecs[3][1],vecs[3][2]))); + + return Py::None(); + } + Py::Object copyResource(const Py::Tuple& args) + { + const char *FileName,*DestDir; + if (! PyArg_ParseTuple(args.ptr(), "ss",&FileName,&DestDir)) + throw Py::Exception(); + + std::string resName = App::GetApplication().getHomePath(); + resName += "Mod"; + resName += PATHSEP ; + resName += "Raytracing"; + resName += PATHSEP ; + resName += "resources"; + resName += PATHSEP; + resName += FileName; + + Base::Console().Warning("Using fileName = %s\nRaytracer scene file not generated " + "because function is not implemented yet.\nYou can copy " + "the standard scene file FreeCAD.pov to your raytracing " + "directory to render the scene.\n",resName.c_str()); // This command should create the povray scene file, but does currently do nothing. - Py_Return; + return Py::None(); + } +}; + +PyObject* initModule() +{ + return (new Module)->module().ptr(); } -/* registration table */ -struct PyMethodDef Raytracing_methods[] = { - {"writeProjectFile", writeProjectFile, 1}, - {"getProjectFile", getProjectFile , 1}, - {"writePartFile", writePartFile , 1}, - {"writePartFileCSV", writePartFileCSV, 1}, - {"getPartAsPovray", getPartAsPovray , 1}, - {"getPartAsLux", getPartAsLux , 1}, - {"writeDataFile", writeDataFile , 1}, - {"writeCameraFile", writeCameraFile , 1}, - {"copyResource", copyResource , 1}, - {NULL, NULL} -}; +} // namespace Raytracing diff --git a/src/Mod/Raytracing/Gui/AppRaytracingGui.cpp b/src/Mod/Raytracing/Gui/AppRaytracingGui.cpp index 296d6b9ff..5254dc73d 100644 --- a/src/Mod/Raytracing/Gui/AppRaytracingGui.cpp +++ b/src/Mod/Raytracing/Gui/AppRaytracingGui.cpp @@ -46,11 +46,12 @@ void loadRaytracingResource() Gui::Translator::instance()->refresh(); } -extern struct PyMethodDef RaytracingGui_methods[]; +namespace RaytracingGui { + PyObject* initModule(); +} -extern "C" { -void AppRaytracingGuiExport initRaytracingGui() +PyMODINIT_FUNC initRaytracingGui() { if (!Gui::Application::Instance) { PyErr_SetString(PyExc_ImportError, "Cannot load Gui module in console application."); @@ -64,7 +65,7 @@ void AppRaytracingGuiExport initRaytracingGui() PyErr_SetString(PyExc_ImportError, e.what()); return; } - (void) Py_InitModule("RaytracingGui", RaytracingGui_methods); /* mod name, table ptr */ + (void) RaytracingGui::initModule(); Base::Console().Log("Loading GUI of Raytracing module... done\n"); // instantiating the commands @@ -79,5 +80,3 @@ void AppRaytracingGuiExport initRaytracingGui() // add resources and reloads the translators loadRaytracingResource(); } - -} // extern "C" { diff --git a/src/Mod/Raytracing/Gui/AppRaytracingGuiPy.cpp b/src/Mod/Raytracing/Gui/AppRaytracingGuiPy.cpp index abeabcdac..68bb26329 100644 --- a/src/Mod/Raytracing/Gui/AppRaytracingGuiPy.cpp +++ b/src/Mod/Raytracing/Gui/AppRaytracingGuiPy.cpp @@ -32,6 +32,9 @@ # include #endif +#include +#include + #include #include #include @@ -45,196 +48,208 @@ #include #include "PovrayHighlighter.h" -using namespace RaytracingGui; -using namespace Raytracing; - -/// open pov file -static PyObject * -open(PyObject *self, PyObject *args) +namespace RaytracingGui { +class Module : public Py::ExtensionModule { - // only used to open Povray files - char* Name; - const char* DocName; - if (!PyArg_ParseTuple(args, "et|s","utf-8",&Name,&DocName)) - return NULL; - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - PY_TRY { - QString fileName = QString::fromUtf8(EncodedName.c_str()); - QFileInfo fi; - fi.setFile(fileName); - QString ext = fi.completeSuffix().toLower(); - QList views = Gui::getMainWindow()->findChildren(); - for (QList::Iterator it = views.begin(); it != views.end(); ++it) { - if ((*it)->fileName() == fileName) { - (*it)->setFocus(); - Py_Return; +public: + Module() : Py::ExtensionModule("RaytracingGui") + { + add_varargs_method("open",&Module::open, + "open(string) -- Create a new text document and load the file into the document." + ); + add_varargs_method("insert",&Module::open, + "insert(string,string) -- Create a new text document and load the file into the document." + ); + add_varargs_method("povViewCamera",&Module::povViewCamera, + "string povViewCamera() -- returns the povray camera definition of the active 3D view." + ); + add_varargs_method("luxViewCamera",&Module::luxViewCamera, + "string luxViewCamera() -- returns the luxrender camera definition of the active 3D view." + ); + initialize("This module is the RaytracingGui module."); // register with Python + } + + virtual ~Module() {} + +private: + Py::Object open(const Py::Tuple& args) + { + // only used to open Povray files + char* Name; + const char* DocName; + if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName)) + throw Py::Exception(); + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + try { + QString fileName = QString::fromUtf8(EncodedName.c_str()); + QFileInfo fi; + fi.setFile(fileName); + QString ext = fi.completeSuffix().toLower(); + QList views = Gui::getMainWindow()->findChildren(); + for (QList::Iterator it = views.begin(); it != views.end(); ++it) { + if ((*it)->fileName() == fileName) { + (*it)->setFocus(); + return Py::None(); + } + } + + if (ext == QLatin1String("pov") || ext == QLatin1String("inc")) { + Gui::TextEditor* editor = new Gui::TextEditor(); + editor->setSyntaxHighlighter(new PovrayHighlighter(editor)); + Gui::EditorView* edit = new Gui::EditorView(editor, Gui::getMainWindow()); + edit->open(fileName); + edit->resize(400, 300); + Gui::getMainWindow()->addWindow(edit); } } - - if (ext == QLatin1String("pov") || ext == QLatin1String("inc")) { - Gui::TextEditor* editor = new Gui::TextEditor(); - editor->setSyntaxHighlighter(new PovrayHighlighter(editor)); - Gui::EditorView* edit = new Gui::EditorView(editor, Gui::getMainWindow()); - edit->open(fileName); - edit->resize(400, 300); - Gui::getMainWindow()->addWindow(edit); + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); } - } PY_CATCH; + return Py::None(); + } - Py_Return; -} + Py::Object povViewCamera(const Py::Tuple& args) + { + // no arguments + if (!PyArg_ParseTuple(args.ptr(), "")) + throw Py::Exception(); + try { + std::string out; + const char* ppReturn=0; -/// return the camera definition of the active view -static PyObject * -povViewCamera(PyObject *self, PyObject *args) -{ - // no arguments - if (!PyArg_ParseTuple(args, "")) - return NULL; - PY_TRY { - std::string out; - const char* ppReturn=0; + Gui::Document* doc = Gui::Application::Instance->activeDocument(); + if (doc) { + doc->sendMsgToFirstView(Gui::MDIView::getClassTypeId(), "GetCamera", &ppReturn); + } + else { + throw Py::RuntimeError("No active document found"); + } - Gui::Document* doc = Gui::Application::Instance->activeDocument(); - if (doc) { - doc->sendMsgToFirstView(Gui::MDIView::getClassTypeId(), "GetCamera", &ppReturn); + if (!ppReturn) { + throw Py::RuntimeError("Could not read camera information from active view"); + } + + SoNode* rootNode; + SoInput in; + in.setBuffer((void*)ppReturn,std::strlen(ppReturn)); + SoDB::read(&in,rootNode); + + if (!rootNode || !rootNode->getTypeId().isDerivedFrom(SoCamera::getClassTypeId())) { + throw Py::RuntimeError("Could not read camera information from ASCII stream"); + } + + // root-node returned from SoDB::readAll() has initial zero + // ref-count, so reference it before we start using it to + // avoid premature destruction. + SoCamera * Cam = static_cast(rootNode); + Cam->ref(); + + SbRotation camrot = Cam->orientation.getValue(); + + SbVec3f upvec(0, 1, 0); // init to default up vector + camrot.multVec(upvec, upvec); + + SbVec3f lookat(0, 0, -1); // init to default view direction vector + camrot.multVec(lookat, lookat); + + SbVec3f pos = Cam->position.getValue(); + float Dist = Cam->focalDistance.getValue(); + Cam->unref(); // free memory + + // making gp out of the Coin stuff + gp_Vec gpPos(pos.getValue()[0],pos.getValue()[1],pos.getValue()[2]); + gp_Vec gpDir(lookat.getValue()[0],lookat.getValue()[1],lookat.getValue()[2]); + lookat *= Dist; + lookat += pos; + gp_Vec gpLookAt(lookat.getValue()[0],lookat.getValue()[1],lookat.getValue()[2]); + gp_Vec gpUp(upvec.getValue()[0],upvec.getValue()[1],upvec.getValue()[2]); + + // getting image format + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Raytracing"); + int width = hGrp->GetInt("OutputWidth", 800); + int height = hGrp->GetInt("OutputHeight", 600); + + // call the write method of PovTools.... + out = Raytracing::PovTools::getCamera(Raytracing::CamDef(gpPos,gpDir,gpLookAt,gpUp),width,height); + + return Py::String(out); } - else { - PyErr_SetString(PyExc_RuntimeError, "No active document found"); - return 0; + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); } + } - if (!ppReturn) { - PyErr_SetString(PyExc_RuntimeError, "Could not read camera information from active view"); - return 0; + Py::Object luxViewCamera(const Py::Tuple& args) + { + // no arguments + if (!PyArg_ParseTuple(args.ptr(), "")) + throw Py::Exception(); + try { + std::string out; + const char* ppReturn=0; + + Gui::Document* doc = Gui::Application::Instance->activeDocument(); + if (doc) { + doc->sendMsgToFirstView(Gui::MDIView::getClassTypeId(), "GetCamera", &ppReturn); + } + else { + throw Py::RuntimeError("No active document found"); + } + + if (!ppReturn) { + throw Py::RuntimeError("Could not read camera information from active view"); + } + + SoNode* rootNode; + SoInput in; + in.setBuffer((void*)ppReturn,std::strlen(ppReturn)); + SoDB::read(&in,rootNode); + + if (!rootNode || !rootNode->getTypeId().isDerivedFrom(SoCamera::getClassTypeId())) { + throw Py::RuntimeError("Could not read camera information from ASCII stream"); + } + + // root-node returned from SoDB::readAll() has initial zero + // ref-count, so reference it before we start using it to + // avoid premature destruction. + SoCamera * Cam = static_cast(rootNode); + Cam->ref(); + + SbRotation camrot = Cam->orientation.getValue(); + + SbVec3f upvec(0, 1, 0); // init to default up vector + camrot.multVec(upvec, upvec); + + SbVec3f lookat(0, 0, -1); // init to default view direction vector + camrot.multVec(lookat, lookat); + + SbVec3f pos = Cam->position.getValue(); + float Dist = Cam->focalDistance.getValue(); + Cam->unref(); // free memory + + // making gp out of the Coin stuff + gp_Vec gpPos(pos.getValue()[0],pos.getValue()[1],pos.getValue()[2]); + gp_Vec gpDir(lookat.getValue()[0],lookat.getValue()[1],lookat.getValue()[2]); + lookat *= Dist; + lookat += pos; + gp_Vec gpLookAt(lookat.getValue()[0],lookat.getValue()[1],lookat.getValue()[2]); + gp_Vec gpUp(upvec.getValue()[0],upvec.getValue()[1],upvec.getValue()[2]); + + // call the write method of PovTools.... + out = Raytracing::LuxTools::getCamera(Raytracing::CamDef(gpPos,gpDir,gpLookAt,gpUp)); + + return Py::String(out); } - - SoNode* rootNode; - SoInput in; - in.setBuffer((void*)ppReturn,std::strlen(ppReturn)); - SoDB::read(&in,rootNode); - - if (!rootNode || !rootNode->getTypeId().isDerivedFrom(SoCamera::getClassTypeId())) { - PyErr_SetString(PyExc_RuntimeError, "Could not read camera information from ASCII stream"); - return 0; + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); } - - // root-node returned from SoDB::readAll() has initial zero - // ref-count, so reference it before we start using it to - // avoid premature destruction. - SoCamera * Cam = static_cast(rootNode); - Cam->ref(); - - SbRotation camrot = Cam->orientation.getValue(); - - SbVec3f upvec(0, 1, 0); // init to default up vector - camrot.multVec(upvec, upvec); - - SbVec3f lookat(0, 0, -1); // init to default view direction vector - camrot.multVec(lookat, lookat); - - SbVec3f pos = Cam->position.getValue(); - float Dist = Cam->focalDistance.getValue(); - Cam->unref(); // free memory - - // making gp out of the Coin stuff - gp_Vec gpPos(pos.getValue()[0],pos.getValue()[1],pos.getValue()[2]); - gp_Vec gpDir(lookat.getValue()[0],lookat.getValue()[1],lookat.getValue()[2]); - lookat *= Dist; - lookat += pos; - gp_Vec gpLookAt(lookat.getValue()[0],lookat.getValue()[1],lookat.getValue()[2]); - gp_Vec gpUp(upvec.getValue()[0],upvec.getValue()[1],upvec.getValue()[2]); - - // getting image format - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Raytracing"); - int width = hGrp->GetInt("OutputWidth", 800); - int height = hGrp->GetInt("OutputHeight", 600); - - // call the write method of PovTools.... - out = PovTools::getCamera(CamDef(gpPos,gpDir,gpLookAt,gpUp),width,height); - - return Py::new_reference_to(Py::String(out)); - } PY_CATCH; -} - -/// return a luxrender camera definition of the active view -static PyObject * -luxViewCamera(PyObject *self, PyObject *args) -{ - // no arguments - if (!PyArg_ParseTuple(args, "")) - return NULL; - PY_TRY { - std::string out; - const char* ppReturn=0; - - Gui::Document* doc = Gui::Application::Instance->activeDocument(); - if (doc) { - doc->sendMsgToFirstView(Gui::MDIView::getClassTypeId(), "GetCamera", &ppReturn); - } - else { - PyErr_SetString(PyExc_RuntimeError, "No active document found"); - return 0; - } - - if (!ppReturn) { - PyErr_SetString(PyExc_RuntimeError, "Could not read camera information from active view"); - return 0; - } - - SoNode* rootNode; - SoInput in; - in.setBuffer((void*)ppReturn,std::strlen(ppReturn)); - SoDB::read(&in,rootNode); - - if (!rootNode || !rootNode->getTypeId().isDerivedFrom(SoCamera::getClassTypeId())) { - PyErr_SetString(PyExc_RuntimeError, "Could not read camera information from ASCII stream"); - return 0; - } - - // root-node returned from SoDB::readAll() has initial zero - // ref-count, so reference it before we start using it to - // avoid premature destruction. - SoCamera * Cam = static_cast(rootNode); - Cam->ref(); - - SbRotation camrot = Cam->orientation.getValue(); - - SbVec3f upvec(0, 1, 0); // init to default up vector - camrot.multVec(upvec, upvec); - - SbVec3f lookat(0, 0, -1); // init to default view direction vector - camrot.multVec(lookat, lookat); - - SbVec3f pos = Cam->position.getValue(); - float Dist = Cam->focalDistance.getValue(); - Cam->unref(); // free memory - - // making gp out of the Coin stuff - gp_Vec gpPos(pos.getValue()[0],pos.getValue()[1],pos.getValue()[2]); - gp_Vec gpDir(lookat.getValue()[0],lookat.getValue()[1],lookat.getValue()[2]); - lookat *= Dist; - lookat += pos; - gp_Vec gpLookAt(lookat.getValue()[0],lookat.getValue()[1],lookat.getValue()[2]); - gp_Vec gpUp(upvec.getValue()[0],upvec.getValue()[1],upvec.getValue()[2]); - - // call the write method of PovTools.... - out = LuxTools::getCamera(CamDef(gpPos,gpDir,gpLookAt,gpUp)); - - return Py::new_reference_to(Py::String(out)); - } PY_CATCH; -} - -/* registration table */ -struct PyMethodDef RaytracingGui_methods[] = { - {"open" ,open ,METH_VARARGS, - "open(string) -- Create a new text document and load the file into the document."}, - {"insert" ,open ,METH_VARARGS, - "insert(string,string) -- Create a new text document and load the file into the document."}, - {"povViewCamera" ,povViewCamera ,METH_VARARGS, - "string povViewCamera() -- returns the povray camera definition of the active 3D view."}, - {"luxViewCamera" ,luxViewCamera ,METH_VARARGS, - "string luxViewCamera() -- returns the luxrender camera definition of the active 3D view."}, - {NULL, NULL} + } }; + +PyObject* initModule() +{ + return (new Module)->module().ptr(); +} + +} // namespace RaytracingGui