Refactored the setup of the reading of the wrl file by allow reading from istreams, as well as nesting of filepaths using a local osgDB::Options to prevent threading issues.

Also fixed crash in parsing of the vrml data structures that occurred when no vrml material was assigned.
This commit is contained in:
Robert Osfield
2009-07-14 10:37:31 +00:00
parent c690dfec50
commit f9517fde6a
2 changed files with 30 additions and 35 deletions

View File

@@ -170,33 +170,28 @@ class resource_fetcher: public openvrml::resource_fetcher
// Register with Registry to instantiate the above reader/writer.
REGISTER_OSGPLUGIN(vrml, ReaderWriterVRML2)
osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(const std::string &fname, const Options* opt) const
osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(const std::string& fname, const osgDB::Options* opt) const
{
std::string fileName = osgDB::findDataFile(fname, opt);
if (fileName.empty())
return ReadResult::FILE_NOT_FOUND;
// convert possible Windows backslashes to Unix slashes
// OpenVRML doesn't like backslashes, even on Windows
std::string unixFileName = osgDB::convertFileNameToUnixStyle(fileName);
#ifdef WIN32
if(unixFileName[1] == ':') // absolute path
fileName = "file:///" + unixFileName;
#else
if (unixFileName[0] == '/') // absolute path
fileName = "file://" + unixFileName;
#endif
else
// relative path
fileName = unixFileName;
std::fstream null;
resource_fetcher fetcher;
openvrml::browser *b = new openvrml::browser(fetcher, null, null);
// code for setting up the database path so that internally referenced file are searched for on relative paths.
osg::ref_ptr<osgDB::Options> local_opt = opt ? static_cast<osgDB::Options*>(opt->clone(osg::CopyOp::SHALLOW_COPY)) : new osgDB::Options;
local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
std::ifstream vrml_stream(fileName.c_str());
return readNode(vrml_stream, local_opt.get());
}
osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(std::istream& vrml_stream, const osgDB::Options* opt) const
{
std::fstream null;
resource_fetcher fetcher;
std::auto_ptr<openvrml::browser> b(new openvrml::browser(fetcher, null, null));
try
{
const std::vector< boost::intrusive_ptr< openvrml::node > > & mfn = b->create_vrml_from_stream(vrml_stream);
@@ -210,22 +205,24 @@ osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(const std::string &f
0, -1, 0, 0,
0, 0, 0, 1));
osgDB::getDataFilePathList().push_front(osgDB::getFilePath(unixFileName));
for (unsigned i = 0; i < mfn.size(); i++)
{
openvrml::node *vrml_node = mfn[i].get();
osg_root->addChild(convertFromVRML(vrml_node));
osg_root->addChild(convertFromVRML(vrml_node, opt));
}
osgDB::getDataFilePathList().pop_front();
return osg_root.get();
}
}
catch (openvrml::invalid_vrml) { return ReadResult::FILE_NOT_HANDLED; }
catch (std::invalid_argument) { return ReadResult::FILE_NOT_HANDLED; }
return ReadResult::FILE_NOT_HANDLED;
}
osg::Node* ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) const
osg::Node* ReaderWriterVRML2::convertFromVRML(openvrml::node *obj, const osgDB::Options* opt) const
{
//static int osgLightNum = 0; //light
@@ -250,7 +247,7 @@ osg::Node* ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) const
for (it_npv = node_ptr_vector.begin(); it_npv != node_ptr_vector.end(); it_npv++)
{
openvrml::node *node = (*(it_npv)).get();
osg_group->addChild(convertFromVRML(node));
osg_group->addChild(convertFromVRML(node, opt));
}
}
}
@@ -259,7 +256,7 @@ osg::Node* ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) const
// no children
}
return osg_group.get();
return osg_group.release();
}
@@ -285,7 +282,7 @@ osg::Node* ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) const
for (it_npv = node_ptr_vector.begin(); it_npv != node_ptr_vector.end(); it_npv++)
{
openvrml::node *node = (*(it_npv)).get();
osg_m->addChild(convertFromVRML(node));
osg_m->addChild(convertFromVRML(node, opt));
}
}
}
@@ -352,8 +349,8 @@ osg::Node* ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) const
const openvrml::sfnode *sfn = dynamic_cast<const openvrml::sfnode *>(fv.get());
openvrml::appearance_node *vrml_app = dynamic_cast<openvrml::appearance_node *>(sfn->value().get());
const boost::intrusive_ptr<openvrml::node> vrml_material_node = vrml_app->material();
const boost::intrusive_ptr<openvrml::node> vrml_texture_node = vrml_app->texture();
const boost::intrusive_ptr<openvrml::node> vrml_material_node = vrml_app ? vrml_app->material() : 0;
const boost::intrusive_ptr<openvrml::node> vrml_texture_node = vrml_app ? vrml_app->texture() : 0;
const openvrml::material_node *vrml_material = dynamic_cast<const openvrml::material_node *>(vrml_material_node.get());
if (vrml_material != NULL)
@@ -406,7 +403,7 @@ osg::Node* ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) const
const openvrml::mfstring *mfs = dynamic_cast<const openvrml::mfstring *>(texture_url_fv.get());
const std::string &url = mfs->value()[0];
osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile(url);
osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile(url, opt);
if (image != 0)
{

View File

@@ -69,13 +69,11 @@ public:
supportsExtension("wrl","VRML format");
}
virtual const char* className()
{
return "VRML2 Reader/Writer";
}
virtual const char* className() const { return "VRML2 Reader/Writer"; }
virtual ReadResult readNode(const std::string&, const osgDB::ReaderWriter::Options *options = NULL) const;
virtual ReadResult readNode(const std::string&, const osgDB::Options *options) const;
virtual ReadResult readNode(std::istream& fin, const osgDB::Options* options) const;
private:
typedef std::map<float, osg::ref_ptr<osg::Geometry> > SphereLibrary;
@@ -83,7 +81,7 @@ private:
typedef std::map<QuadricKey, osg::ref_ptr<osg::Geometry> > ConeLibrary;
typedef std::map<QuadricKey, osg::ref_ptr<osg::Geometry> > CylinderLibrary;
osg::Node* convertFromVRML(openvrml::node *obj) const;
osg::Node* convertFromVRML(openvrml::node *obj, const osgDB::Options* opt) const;
osg::ref_ptr<osg::Geometry> convertVRML97IndexedFaceSet(openvrml::node *vrml_ifs) const;