From f948a39bdb5390b846f42287f0aae65916e2e6f3 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 29 Jun 2020 11:54:38 +0200 Subject: [PATCH] Gui: export scene graph to file or buffer --- src/Gui/Application.cpp | 48 +++++++++++++++++++++-------------------- src/Gui/SoFCDB.cpp | 10 +++++++-- src/Gui/SoFCDB.h | 1 + 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 1ba99e4382b5..a514b1bf3dfb 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -231,39 +231,40 @@ FreeCADGui_subgraphFromObject(PyObject * /*self*/, PyObject *args) } static PyObject * -FreeCADGui_replaceSwitchNodes(PyObject * /*self*/, PyObject *args) +FreeCADGui_exportSubgraph(PyObject * /*self*/, PyObject *args) { + const char* format = "VRML"; PyObject* proxy; - if (!PyArg_ParseTuple(args, "O", &proxy)) + PyObject* output; + if (!PyArg_ParseTuple(args, "OO|s", &proxy, &output, &format)) return nullptr; void* ptr = 0; try { Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoNode *", proxy, &ptr, 0); SoNode* node = reinterpret_cast(ptr); - SoNode* replace = SoFCDB::replaceSwitches(node); - if (replace) { - replace->ref(); + if (node) { + std::string formatStr(format); + std::string buffer; - std::string prefix = "So"; - std::string type = replace->getTypeId().getName().getString(); - // doesn't start with the prefix 'So' - if (type.rfind("So", 0) != 0) { - type = prefix + type; + if (formatStr == "VRML") { + SoFCDB::writeToVRML(node, buffer); } - else if (type == "SoFCSelectionRoot") { - type = "SoSeparator"; + else if (formatStr == "IV") { + buffer = SoFCDB::writeNodesToString(node); + } + else { + throw Base::ValueError("Unsupported format"); } - type += " *"; - PyObject* proxy = 0; - proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", type.c_str(), (void*)replace, 1); - return Py::new_reference_to(Py::Object(proxy, true)); - } - else { - Py_INCREF(Py_None); - return Py_None; + Base::PyStreambuf buf(output); + std::ostream str(0); + str.rdbuf(&buf); + str << buffer; } + + Py_INCREF(Py_None); + return Py_None; } catch (const Base::Exception& e) { PyErr_SetString(PyExc_RuntimeError, e.what()); @@ -334,9 +335,10 @@ struct PyMethodDef FreeCADGui_methods[] = { {"subgraphFromObject",FreeCADGui_subgraphFromObject,METH_VARARGS, "subgraphFromObject(object) -> Node\n\n" "Return the Inventor subgraph to an object"}, - {"replaceSwitchNodes",FreeCADGui_replaceSwitchNodes,METH_VARARGS, - "replaceSwitchNodes(Node) -> Node\n\n" - "Replace Switch nodes with Separators"}, + {"exportSubgraph",FreeCADGui_exportSubgraph,METH_VARARGS, + "exportSubgraph(Node, File or Buffer, [Format='VRML']) -> None\n\n" + "Exports the sub-graph in the requested format" + "The format string can be VRML or IV"}, {"getSoDBVersion",FreeCADGui_getSoDBVersion,METH_VARARGS, "getSoDBVersion() -> String\n\n" "Return a text string containing the name\n" diff --git a/src/Gui/SoFCDB.cpp b/src/Gui/SoFCDB.cpp index 340f3ceae10e..d66b3c269a33 100644 --- a/src/Gui/SoFCDB.cpp +++ b/src/Gui/SoFCDB.cpp @@ -301,7 +301,7 @@ SoNode* Gui::SoFCDB::replaceSwitches(SoNode* node) return replaceSwitchesInSceneGraph(node); } -bool Gui::SoFCDB::writeToVRML(SoNode* node, const char* filename, bool binary) +void Gui::SoFCDB::writeToVRML(SoNode* node, std::string& buffer) { SoNode* noSwitches = replaceSwitchesInSceneGraph(node); noSwitches->ref(); @@ -313,13 +313,19 @@ bool Gui::SoFCDB::writeToVRML(SoNode* node, const char* filename, bool binary) SoVRMLGroup* vrmlRoot = tovrml2.getVRML2SceneGraph(); vrmlRoot->setInstancePrefix(SbString("o")); vrmlRoot->ref(); - std::string buffer = SoFCDB::writeNodesToString(vrmlRoot); + buffer = SoFCDB::writeNodesToString(vrmlRoot); vrmlRoot->unref(); // release the memory as soon as possible // restore old settings vrml2.setOverrideMode(false); vrml2.apply(noSwitches); noSwitches->unref(); +} + +bool Gui::SoFCDB::writeToVRML(SoNode* node, const char* filename, bool binary) +{ + std::string buffer; + writeToVRML(node, buffer); Base::FileInfo fi(filename); if (binary) { diff --git a/src/Gui/SoFCDB.h b/src/Gui/SoFCDB.h index 932eab05721d..ebfaefc0d9f3 100644 --- a/src/Gui/SoFCDB.h +++ b/src/Gui/SoFCDB.h @@ -44,6 +44,7 @@ class GuiExport SoFCDB /// helper to apply a SoWriteAction to a node and write it to a string static const std::string& writeNodesToString(SoNode * root); static bool writeToVRML(SoNode* node, const char* filename, bool binary); + static void writeToVRML(SoNode* node, std::string& buffer); // Write to VRML or Inventor file static bool writeToFile(SoNode* node, const char* filename, bool binary); /*! container for app lifetime storage. See SoFCCSysDragger for details