diff --git a/src/Gui/SoFCDB.cpp b/src/Gui/SoFCDB.cpp index d27d6e051b..ddd7421de7 100644 --- a/src/Gui/SoFCDB.cpp +++ b/src/Gui/SoFCDB.cpp @@ -237,13 +237,66 @@ const std::string& Gui::SoFCDB::writeNodesToString(SoNode * root) return cReturnString; } +SoNode* replaceSwitches(SoNodeList* children, SoGroup* parent) +{ + if (!children) { + return parent; + } + + for (int i=0; igetLength(); i++) { + SoNode* node = (*children)[i]; + if (node->getTypeId().isDerivedFrom(SoGroup::getClassTypeId())) { + if (node->getTypeId().isDerivedFrom(SoSwitch::getClassTypeId())) { + SoSwitch* group = static_cast(node); + int which = group->whichChild.getValue(); + if (which == SO_SWITCH_NONE) + continue; + SoGroup* newParent = new SoGroup(); + SoNodeList c; + if (which >= 0) { + c.append(group->getChild(which)); + } + else { + // SO_SWITCH_INHERIT or SO_SWITCH_ALL + for (int i=0; igetNumChildren(); i++) + c.append(group->getChild(i)); + } + + replaceSwitches(&c, newParent); + parent->addChild(newParent); + } + else { + SoGroup* newParent = static_cast(node->getTypeId().createInstance()); + replaceSwitches(node->getChildren(), newParent); + parent->addChild(newParent); + } + } + else { + parent->addChild(node); + } + } + + return parent; +} + +SoNode* replaceSwitchesInSceneGraph(SoNode* node) +{ + if (node->getTypeId().isDerivedFrom(SoGroup::getClassTypeId())) { + return replaceSwitches(node->getChildren(), new SoSeparator); + } + + return node; +} + bool Gui::SoFCDB::writeToVRML(SoNode* node, const char* filename, bool binary) { + SoNode* noSwitches = replaceSwitchesInSceneGraph(node); + noSwitches->ref(); SoVRMLAction vrml2; vrml2.setOverrideMode(true); - vrml2.apply(node); + vrml2.apply(noSwitches); SoToVRML2Action tovrml2; - tovrml2.apply(node); + tovrml2.apply(noSwitches); SoVRMLGroup* vrmlRoot = tovrml2.getVRML2SceneGraph(); vrmlRoot->setInstancePrefix(SbString("o")); vrmlRoot->ref(); @@ -252,7 +305,8 @@ bool Gui::SoFCDB::writeToVRML(SoNode* node, const char* filename, bool binary) // restore old settings vrml2.setOverrideMode(false); - vrml2.apply(node); + vrml2.apply(noSwitches); + noSwitches->unref(); Base::FileInfo fi(filename); if (binary) {