bool Gui::SoFCDB::writeToVRML(SoNode* node, const char* filename, bool binary) { SoVRMLAction vrml2; vrml2.setOverrideMode(true); vrml2.apply(node); SoToVRML2Action tovrml2; tovrml2.apply(node); SoVRMLGroup* vrmlRoot = tovrml2.getVRML2SceneGraph(); vrmlRoot->setInstancePrefix(SbString("o")); vrmlRoot->ref(); std::string buffer = SoFCDB::writeNodesToString(vrmlRoot); vrmlRoot->unref(); // release the memory as soon as possible // restore old settings vrml2.setOverrideMode(false); vrml2.apply(node); Base::FileInfo fi(filename); if (binary) { // We want to write compressed VRML but Coin 2.4.3 doesn't do it even though // SoOutput::getAvailableCompressionMethods() delivers a string list that // contains 'GZIP'. setCompression() was called directly after opening the file, // returned TRUE and no error message appeared but anyway it didn't work. // Strange is that reading GZIPped VRML files works. // So, we do the compression on our own. Base::ofstream str(fi, std::ios::out | std::ios::binary); zipios::GZIPOutputStream gzip(str); if (gzip) { gzip << buffer; gzip.close(); return true; } } else { Base::ofstream str(fi, std::ios::out); if (str) { str << buffer; str.close(); return true; } } return false; }
void Scene::load(const ::std::string& filename, const bool& doBoundingBoxPoints, const bool& doPoints) { ::rl::xml::DomParser parser; ::rl::xml::Document doc = parser.readFile(filename, "", XML_PARSE_NOENT | XML_PARSE_XINCLUDE); doc.substitute(XML_PARSE_NOENT | XML_PARSE_XINCLUDE); ::rl::xml::Path path(doc); ::rl::xml::Object scenes = path.eval("//scene"); for (int i = 0; i < ::std::min(1, scenes.getNodeNr()); ++i) { SoInput input; if (!input.openFile(scenes.getNodeTab(i).getLocalPath(scenes.getNodeTab(i).getAttribute("href").getValue()).c_str() ,true)) { throw Exception("::rl::sg::Scene::load() - failed to open file"); } SoVRMLGroup* root = SoDB::readAllVRML(&input); if (NULL == root) { throw Exception("::rl::sg::Scene::load() - failed to read file"); } SbViewportRegion viewportRegion; root->ref(); // model ::rl::xml::Object models = path.eval("model", scenes.getNodeTab(i)); for (int j = 0; j < models.getNodeNr(); ++j) { SoSearchAction modelSearchAction; modelSearchAction.setName(models.getNodeTab(j).getAttribute("name").getValue().c_str()); modelSearchAction.apply(root); if (NULL == modelSearchAction.getPath()) { continue; } Model* model = this->create(); model->setName(models.getNodeTab(j).getAttribute("name").getValue()); // body ::rl::xml::Object bodies = path.eval("body", models.getNodeTab(j)); for (int k = 0; k < bodies.getNodeNr(); ++k) { SoSearchAction bodySearchAction; bodySearchAction.setName(bodies.getNodeTab(k).getAttribute("name").getValue().c_str()); bodySearchAction.apply(static_cast< SoFullPath* >(modelSearchAction.getPath())->getTail()); if (NULL == bodySearchAction.getPath()) { continue; } Body* body = model->create(); body->setName(bodies.getNodeTab(k).getAttribute("name").getValue()); SoSearchAction pathSearchAction; pathSearchAction.setNode(static_cast< SoFullPath* >(bodySearchAction.getPath())->getTail()); pathSearchAction.apply(root); SoGetMatrixAction bodyGetMatrixAction(viewportRegion); bodyGetMatrixAction.apply(static_cast< SoFullPath* >(pathSearchAction.getPath())); SbMatrix bodyMatrix = bodyGetMatrixAction.getMatrix(); if (!this->isScalingSupported) { SbVec3f bodyTranslation; SbRotation bodyRotation; SbVec3f bodyScaleFactor; SbRotation bodyScaleOrientation; SbVec3f bodyCenter; bodyMatrix.getTransform(bodyTranslation, bodyRotation, bodyScaleFactor, bodyScaleOrientation, bodyCenter); for (int l = 0; l < 3; ++l) { if (::std::abs(bodyScaleFactor[l] - 1.0f) > 1.0e-6f) { throw Exception("::rl::sg::Scene::load() - bodyScaleFactor not supported"); } } } ::rl::math::Transform frame; for (int m = 0; m < 4; ++m) { for (int n = 0; n < 4; ++n) { frame(m, n) = bodyMatrix[n][m]; } } body->setFrame(frame); if (static_cast< SoFullPath* >(bodySearchAction.getPath())->getTail()->isOfType(SoVRMLTransform::getClassTypeId())) { SoVRMLTransform* bodyVrmlTransform = static_cast< SoVRMLTransform* >(static_cast< SoFullPath* >(bodySearchAction.getPath())->getTail()); for (int l = 0; l < 3; ++l) { body->center(l) = bodyVrmlTransform->center.getValue()[l]; } } SoPathList pathList; // shape SoSearchAction shapeSearchAction; shapeSearchAction.setInterest(SoSearchAction::ALL); shapeSearchAction.setType(SoVRMLShape::getClassTypeId()); shapeSearchAction.apply(static_cast< SoFullPath* >(bodySearchAction.getPath())->getTail()); for (int l = 0; l < shapeSearchAction.getPaths().getLength(); ++l) { SoFullPath* path = static_cast< SoFullPath* >(shapeSearchAction.getPaths()[l]); if (path->getLength() > 1) { path = static_cast< SoFullPath* >(shapeSearchAction.getPaths()[l]->copy(1, static_cast< SoFullPath* >(shapeSearchAction.getPaths()[l])->getLength() - 1)); } pathList.append(path); SoGetMatrixAction shapeGetMatrixAction(viewportRegion); shapeGetMatrixAction.apply(path); SbMatrix shapeMatrix = shapeGetMatrixAction.getMatrix(); if (!this->isScalingSupported) { SbVec3f shapeTranslation; SbRotation shapeRotation; SbVec3f shapeScaleFactor; SbRotation shapeScaleOrientation; SbVec3f shapeCenter; shapeMatrix.getTransform(shapeTranslation, shapeRotation, shapeScaleFactor, shapeScaleOrientation, shapeCenter); for (int m = 0; m < 3; ++m) { if (::std::abs(shapeScaleFactor[m] - 1.0f) > 1.0e-6f) { throw Exception("::rl::sg::Scene::load() - shapeScaleFactor not supported"); } } } SoVRMLShape* shapeVrmlShape = static_cast< SoVRMLShape* >(static_cast< SoFullPath* >(shapeSearchAction.getPaths()[l])->getTail()); Shape* shape = body->create(shapeVrmlShape); shape->setName(shapeVrmlShape->getName().getString()); ::rl::math::Transform transform; for (int m = 0; m < 4; ++m) { for (int n = 0; n < 4; ++n) { transform(m, n) = shapeMatrix[n][m]; } } shape->setTransform(transform); } // bounding box if (doBoundingBoxPoints) { SoGetBoundingBoxAction getBoundingBoxAction(viewportRegion); getBoundingBoxAction.apply(pathList); SbBox3f boundingBox = getBoundingBoxAction.getBoundingBox(); for (int l = 0; l < 3; ++l) { body->max(l) = boundingBox.getMax()[l]; body->min(l) = boundingBox.getMin()[l]; } } // convex hull if (doPoints) { SoCallbackAction callbackAction; callbackAction.addTriangleCallback(SoVRMLGeometry::getClassTypeId(), Scene::triangleCallback, &body->points); callbackAction.apply(pathList); } } } root->unref(); } }