From 564869487a56784676b14fae843cbbbc7aa58745 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 9 Nov 2004 14:18:29 +0000 Subject: [PATCH] Added support of archiving into osgTerrain::DataSet and osgdem. --- examples/osgarchive/osgarchive.cpp | 11 ++- examples/osgdem/osgdem.cpp | 3 + include/osgDB/Archive | 31 +++++- include/osgTerrain/DataSet | 20 ++++ src/osgDB/Archive.cpp | 151 +++++++++++++++++++++-------- src/osgTerrain/DataSet.cpp | 39 ++++++-- 6 files changed, 199 insertions(+), 56 deletions(-) diff --git a/examples/osgarchive/osgarchive.cpp b/examples/osgarchive/osgarchive.cpp index 82f387c91..230281923 100644 --- a/examples/osgarchive/osgarchive.cpp +++ b/examples/osgarchive/osgarchive.cpp @@ -99,7 +99,8 @@ int main( int argc, char **argv ) { if (insert) { - osgDB::FileType fileType = osgDB::fileType(arguments[pos]); + std::string filePath = osgDB::findDataFile(arguments[pos]); + osgDB::FileType fileType = osgDB::fileType(filePath); if (fileType==osgDB::REGULAR_FILE) { files.push_back(arguments[pos]); @@ -110,10 +111,6 @@ int main( int argc, char **argv ) files.insert(files.end(),directory.begin(),directory.end()); } } - else - { - files.push_back(arguments[pos]); - } } } @@ -152,13 +149,17 @@ int main( int argc, char **argv ) osgDB::Archive archive; archive.open(archiveFilename, osgDB::Archive::WRITE); + std::cout<<"Going through files"< obj = osgDB::readObjectFile(*itr); if (obj.valid()) { + std::cout<<" Have read"<<*itr<addCommandLineOption("-d ","Specify the digital elevation map input file to process"); arguments.getApplicationUsage()->addCommandLineOption("-t ","Specify the texture map input file to process"); arguments.getApplicationUsage()->addCommandLineOption("-m ","Specify the 3D database model input file to process"); + arguments.getApplicationUsage()->addCommandLineOption("-a ","Specify the archive to place the generated database"); arguments.getApplicationUsage()->addCommandLineOption("-o ","Specify the output master file to generate"); arguments.getApplicationUsage()->addCommandLineOption("-l ","Specify the number of PagedLOD levels to generate"); arguments.getApplicationUsage()->addCommandLineOption("-e ","Extents of the model to generate"); @@ -263,6 +264,8 @@ int main( int argc, char **argv ) std::string comment; while (arguments.read("--comment",comment)) { dataset->setCommentString(comment); } + std::string archiveName; + while (arguments.read("-a",archiveName)) { dataset->setArchiveName(archiveName); } dataset->setDestinationTileBaseName("output"); dataset->setDestinationTileExtension(".ive"); diff --git a/include/osgDB/Archive b/include/osgDB/Archive index 49d7db5fb..800654e3f 100644 --- a/include/osgDB/Archive +++ b/include/osgDB/Archive @@ -62,6 +62,34 @@ class OSGDB_EXPORT Archive : public ReaderWriter virtual WriteResult writeHeightField(const osg::HeightField& heightField,const std::string& fileName,const Options* options=NULL); virtual WriteResult writeNode(const osg::Node& node,const std::string& fileName,const Options* options=NULL); + /** Functor used in internal implementations.*/ + struct ReadFunctor + { + ReadFunctor(const std::string& filename, const ReaderWriter::Options* options): + _filename(filename), + _options(options) {} + + virtual ~ReadFunctor() {} + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const = 0; + + std::string _filename; + const ReaderWriter::Options* _options; + }; + + /** Functor used in internal implementations.*/ + struct WriteFunctor + { + WriteFunctor(const std::string& filename, const ReaderWriter::Options* options): + _filename(filename), + _options(options) {} + + virtual ~WriteFunctor() {} + virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const = 0; + + std::string _filename; + const ReaderWriter::Options* _options; + }; + protected: @@ -114,7 +142,8 @@ class OSGDB_EXPORT Archive : public ReaderWriter char* _data; }; - + ReaderWriter::ReadResult read(const ReadFunctor& readFunctor); + ReaderWriter::WriteResult write(const WriteFunctor& writeFunctor); typedef std::list< osg::ref_ptr > IndexBlockList; diff --git a/include/osgTerrain/DataSet b/include/osgTerrain/DataSet index af0bba068..af524729c 100644 --- a/include/osgTerrain/DataSet +++ b/include/osgTerrain/DataSet @@ -32,6 +32,8 @@ #include #include +#include + #include #include @@ -927,6 +929,18 @@ class OSGTERRAIN_EXPORT DataSet : public osg::Referenced void setDestinationGeoTransform(const osg::Matrixd& geoTransform) { _geoTransform = geoTransform; } + /** Set the Archive name if one is to be used.*/ + void setArchiveName(const std::string& filename) { _archiveName = filename; } + + /** Get the Archive name.*/ + const std::string& getArchiveName() const { return _archiveName; } + + /** Set the Archive.*/ + void setArchive(osgDB::Archive* archive) { _archive = archive; } + + /** Get the Archive if one is to being used.*/ + osgDB::Archive* getArchive() { return _archive.get(); } + /** Set the DestinationTileBaseName and DestinationTileExtension from the passed in filename.*/ void setDestinationName(const std::string& filename); @@ -1020,12 +1034,16 @@ class OSGTERRAIN_EXPORT DataSet : public osg::Referenced osg::Node* getDestinationRootNode() { return _rootNode.get(); } + // helper functions for handling optional archive + void _writeNodeFile(const osg::Node& node,const std::string& filename); + void _writeImageFile(const osg::Image& image,const std::string& filename); protected: virtual ~DataSet() {} + void _readRow(Row& row); void _equalizeRow(Row& row); void _writeRow(Row& row); @@ -1059,6 +1077,8 @@ class OSGTERRAIN_EXPORT DataSet : public osg::Referenced osg::Matrixd _geoTransform; osg::BoundingBox _extents; + std::string _archiveName; + osg::ref_ptr _archive; std::string _tileBasename; std::string _tileExtension; osg::Vec4 _defaultColor; diff --git a/src/osgDB/Archive.cpp b/src/osgDB/Archive.cpp index 6bb6fcda9..c508437ba 100644 --- a/src/osgDB/Archive.cpp +++ b/src/osgDB/Archive.cpp @@ -434,29 +434,53 @@ class proxy_streambuf : public std::streambuf } }; -ReaderWriter::ReadResult Archive::readObject(const std::string& fileName,const Options* options) +struct ArchiveReadObjectFunctor : public Archive::ReadFunctor +{ + ArchiveReadObjectFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readObject(input, _options); } +}; + +struct ArchiveReadImageFunctor : public Archive::ReadFunctor +{ + ArchiveReadImageFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input)const { return rw.readImage(input, _options); } +}; + +struct ArchiveReadHeightFieldFunctor : public Archive::ReadFunctor +{ + ArchiveReadHeightFieldFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readHeightField(input, _options); } +}; + +struct ArchiveReadNodeFunctor : public Archive::ReadFunctor +{ + ArchiveReadNodeFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readNode(input, _options); } +}; + +ReaderWriter::ReadResult Archive::read(const ReadFunctor& readFunctor) { if (_status!=READ) { - osg::notify(osg::INFO)<<"Archive::readObject(obj, "<getReaderWriterForExtension(getLowerCaseFileExtension(fileName)); + ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension(getLowerCaseFileExtension(readFunctor._filename)); if (!rw) { - osg::notify(osg::INFO)<<"Archive::readObject(obj, "<second.first); @@ -465,82 +489,127 @@ ReaderWriter::ReadResult Archive::readObject(const std::string& fileName,const O proxy_streambuf mystreambuf(ins.rdbuf(),itr->second.second); ins.rdbuf(&mystreambuf); - ReaderWriter::ReadResult result = rw->readObject(_input, options); + ReaderWriter::ReadResult result = readFunctor.doRead(*rw, _input); ins.rdbuf(mystreambuf._streambuf); return result; } -ReaderWriter::ReadResult Archive::readImage(const std::string& /*fileName*/,const Options*) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } -ReaderWriter::ReadResult Archive::readHeightField(const std::string& /*fileName*/,const Options*) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } -ReaderWriter::ReadResult Archive::readNode(const std::string& /*fileName*/,const Options*) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } +ReaderWriter::ReadResult Archive::readObject(const std::string& fileName,const Options* options) +{ + return read(ArchiveReadObjectFunctor(fileName, options)); +} + +ReaderWriter::ReadResult Archive::readImage(const std::string& fileName,const Options* options) +{ + return read(ArchiveReadImageFunctor(fileName, options)); +} + +ReaderWriter::ReadResult Archive::readHeightField(const std::string& fileName,const Options* options) +{ + return read(ArchiveReadHeightFieldFunctor(fileName, options)); +} + +ReaderWriter::ReadResult Archive::readNode(const std::string& fileName,const Options* options) +{ + return read(ArchiveReadNodeFunctor(fileName, options)); +} +struct WriteObjectFunctor : public Archive::WriteFunctor +{ + WriteObjectFunctor(const osg::Object& object, const std::string& filename, const ReaderWriter::Options* options): + WriteFunctor(filename,options), + _object(object) {} + const osg::Object& _object; + + virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.writeObject(_object, output, _options); } +}; -ReaderWriter::WriteResult Archive::writeObject(const osg::Object& obj,const std::string& fileName,const Options* options) +struct WriteImageFunctor : public Archive::WriteFunctor +{ + WriteImageFunctor(const osg::Image& object, const std::string& filename, const ReaderWriter::Options* options): + WriteFunctor(filename,options), + _object(object) {} + const osg::Image& _object; + + virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output)const { return rw.writeImage(_object, output, _options); } +}; + +struct WriteHeightFieldFunctor : public Archive::WriteFunctor +{ + WriteHeightFieldFunctor(const osg::HeightField& object, const std::string& filename, const ReaderWriter::Options* options): + WriteFunctor(filename,options), + _object(object) {} + const osg::HeightField& _object; + + virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.writeHeightField(_object, output, _options); } +}; + +struct WriteNodeFunctor : public Archive::WriteFunctor +{ + WriteNodeFunctor(const osg::Node& object, const std::string& filename, const ReaderWriter::Options* options): + WriteFunctor(filename,options), + _object(object) {} + const osg::Node& _object; + + virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.writeNode(_object, output, _options); } +}; + +ReaderWriter::WriteResult Archive::write(const WriteFunctor& writeFunctor) { if (_status!=WRITE) { - osg::notify(osg::NOTICE)<<"Archive::writeObject(obj, "<getReaderWriterForExtension(getLowerCaseFileExtension(fileName)); + ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension(getLowerCaseFileExtension(writeFunctor._filename)); if (!rw) { - osg::notify(osg::NOTICE)<<"Archive::writeObject(obj, "<writeObject(obj, _output, options); + WriteResult result = writeFunctor.doWrite(*rw,_output); pos_type final_position = _output.tellp(); size_type size = size_type(final_position-position); - if (result.success()) addFileReference(position, size, fileName); + if (result.success()) addFileReference(position, size, writeFunctor._filename); return result; } -ReaderWriter::WriteResult Archive::writeImage(const osg::Image& /*image*/,const std::string& fileName,const Options* /*options*/) + +ReaderWriter::WriteResult Archive::writeObject(const osg::Object& obj,const std::string& fileName,const Options* options) { - if (_status==READ) - { - osg::notify(osg::NOTICE)<<"Archive::writeImage(obj, "<writeNode(node,filename); + else osgDB::writeNodeFile(node, filename); +} + +void DataSet::_writeImageFile(const osg::Image& image,const std::string& filename) +{ + if (_archive.valid()) _archive->writeImage(image,filename); + else osgDB::writeImageFile(image, filename); +} + class WriteImageFilesVisitor : public osg::NodeVisitor { public: - WriteImageFilesVisitor(): - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + WriteImageFilesVisitor(osgTerrain::DataSet* dataSet): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _dataSet(dataSet) {} + osgTerrain::DataSet* _dataSet; virtual void apply(osg::Node& node) { @@ -3762,7 +3776,7 @@ public: if (image) { - osgDB::writeImageFile(*image,image->getFileName().c_str()); + _dataSet->_writeImageFile(*image,image->getFileName().c_str()); } } } @@ -3787,11 +3801,11 @@ void DataSet::_writeRow(Row& row) if (node.valid()) { my_notify(osg::NOTICE)<<" writeSubTile filename="<accept(wifv); } @@ -3825,11 +3839,11 @@ void DataSet::_writeRow(Row& row) if (node.valid()) { my_notify(osg::NOTICE)<<" writeNodeFile = "<_level<<" X="<_tileX<<" Y="<_tileY<<" filename="<accept(wifv); } } @@ -3879,6 +3893,12 @@ osg::Node* DataSet::decorateWithCoordinateSystemNode(osg::Node* subgraph) void DataSet::_buildDestination(bool writeToDisk) { + if (!_archive && !_archiveName.empty()) + { + _archive = new osgDB::Archive; + _archive->open(_archiveName, osgDB::Archive::WRITE); + } + if (_destinationGraph.valid()) { std::string filename = _tileBasename+_tileExtension; @@ -3901,10 +3921,10 @@ void DataSet::_buildDestination(bool writeToDisk) if (writeToDisk) { - osgDB::writeNodeFile(*_rootNode,filename); + _writeNodeFile(*_rootNode,filename); if (_tileExtension==".osg") { - WriteImageFilesVisitor wifv; + WriteImageFilesVisitor wifv(this); _rootNode->accept(wifv); } } @@ -3954,5 +3974,6 @@ void DataSet::_buildDestination(bool writeToDisk) my_notify(osg::WARN)<<"Error: no scene graph to output, no file written."<close(); }