diff --git a/src/osgPlugins/ive/DataOutputStream.cpp b/src/osgPlugins/ive/DataOutputStream.cpp index 1324e3d91..cb7379f0d 100644 --- a/src/osgPlugins/ive/DataOutputStream.cpp +++ b/src/osgPlugins/ive/DataOutputStream.cpp @@ -123,7 +123,9 @@ #include #include #include +#include #include +#include #include #include @@ -142,10 +144,23 @@ DataOutputStream::DataOutputStream(std::ostream * ostream, const osgDB::ReaderWr _useOriginalExternalReferences = true; _maximumErrorToSizeRatio = 0.001; + _outputTextureFiles = false; + _textureFileNameNumber = 0; + _options = options; _compressionLevel = 0; + if (options) _filename = options->getPluginStringData("filename"); + + if (_filename.empty()) + { + // initialize _filename to a unique identifier in case a real filename is not supplied + std::ostringstream filenameBuilder; + filenameBuilder << "file" << ostream; // use address of ostream to formulate unique filename + _filename = filenameBuilder.str(); + } + if (_options.get()) { std::string optionsString = _options->getOptionString(); @@ -157,19 +172,22 @@ DataOutputStream::DataOutputStream(std::ostream * ostream, const osgDB::ReaderWr } else if(optionsString.find("compressImageData")!=std::string::npos) { setIncludeImageMode(IMAGE_COMPRESS_DATA); } - osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setIncludeImageMode()=" << getIncludeImageMode() << std::endl; + osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream.setIncludeImageMode()=" << getIncludeImageMode() << std::endl; setIncludeExternalReferences(optionsString.find("inlineExternalReferencesInIVEFile")!=std::string::npos); - osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setIncludeExternalReferences()=" << getIncludeExternalReferences() << std::endl; + osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream.setIncludeExternalReferences()=" << getIncludeExternalReferences() << std::endl; setWriteExternalReferenceFiles(optionsString.find("noWriteExternalReferenceFiles")==std::string::npos); - osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setWriteExternalReferenceFiles()=" << getWriteExternalReferenceFiles() << std::endl; + osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream.setWriteExternalReferenceFiles()=" << getWriteExternalReferenceFiles() << std::endl; setUseOriginalExternalReferences(optionsString.find("useOriginalExternalReferences")!=std::string::npos); - osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setUseOriginalExternalReferences()=" << getUseOriginalExternalReferences() << std::endl; + osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream.setUseOriginalExternalReferences()=" << getUseOriginalExternalReferences() << std::endl; + + setOutputTextureFiles(optionsString.find("OutputTextureFiles")!=std::string::npos); + osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream.setOutputTextureFiles()=" << getOutputTextureFiles() << std::endl; _compressionLevel = (optionsString.find("compressed")!=std::string::npos) ? 1 : 0; - osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream._compressionLevel=" << _compressionLevel << std::endl; + osg::notify(osg::DEBUG_INFO) << "ive::DataOutputStream._compressionLevel=" << _compressionLevel << std::endl; std::string::size_type terrainErrorPos = optionsString.find("TerrainMaximumErrorToSizeRatio="); if (terrainErrorPos!=std::string::npos) @@ -1439,14 +1457,28 @@ void DataOutputStream::writeImage(IncludeImageMode mode, osg::Image *image) ((ive::Image*)image)->write(this); break; case IMAGE_REFERENCE_FILE: - // Only include image name in stream - if (image && !(image->getFileName().empty())){ - writeString(image->getFileName()); + { + if (image) + { + // Only include image name in stream + std::string fileName = image->getFileName(); + // Export an image, if requested + if (getOutputTextureFiles()) + { + if (fileName.empty()) + { // synthesize a new faux filename + fileName = getTextureFileNameForOutput(); + } + osgDB::writeImageFile(*image, fileName); + } + writeString(fileName); } - else{ + else + { writeString(""); } break; + } case IMAGE_INCLUDE_FILE: // Include image file in stream if(image && !(image->getFileName().empty())) { @@ -1839,6 +1871,24 @@ void DataOutputStream::writeObject(const osg::Object* object) writeInt(-1); } +std::string DataOutputStream::getTextureFileNameForOutput() +{ + std::string fileName = osgDB::getNameLessExtension(_filename); + if (_textureFileNameNumber>0) + { + std::ostringstream o; + o << '_' << _textureFileNameNumber; + fileName += o.str(); + } + + fileName += ".dds"; + ++_textureFileNameNumber; + + return fileName; +} + + + void DataOutputStream::setExternalFileWritten(const std::string& filename, bool hasBeenWritten) { _externalFileWritten[filename] = hasBeenWritten; diff --git a/src/osgPlugins/ive/DataOutputStream.h b/src/osgPlugins/ive/DataOutputStream.h index 01ee43a5c..fe03dd9fa 100644 --- a/src/osgPlugins/ive/DataOutputStream.h +++ b/src/osgPlugins/ive/DataOutputStream.h @@ -130,6 +130,15 @@ public: void setUseOriginalExternalReferences(bool b) {_useOriginalExternalReferences=b;}; bool getUseOriginalExternalReferences() const {return _useOriginalExternalReferences;}; + // Set and get if export texture files during write + void setOutputTextureFiles(bool flag) { _outputTextureFiles = flag; } + bool getOutputTextureFiles() const { return _outputTextureFiles; } + + // support code for OutputTextureFiles + virtual std::string getTextureFileNameForOutput(); + void setFileName(std::string newFileName) {_filename = newFileName;} + std::string getFileName(void) const {return(_filename);} + void setTerrainMaximumErrorToSizeRatio(double ratio) { _maximumErrorToSizeRatio = ratio; } double getTerrainMaximumErrorToSizeRatio() const { return _maximumErrorToSizeRatio; } @@ -150,6 +159,7 @@ public: std::ostream* _ostream; std::ostream* _output_ostream; + std::string _filename; // not necessary, but optional for use in texture export std::stringstream _compressionStream; int _compressionLevel; @@ -188,7 +198,10 @@ public: double _maximumErrorToSizeRatio; IncludeImageMode _includeImageMode; - + + bool _outputTextureFiles; + unsigned int _textureFileNameNumber; + osg::ref_ptr _options; typedef std::map ExternalFileWrittenMap; diff --git a/src/osgPlugins/ive/ReaderWriterIVE.cpp b/src/osgPlugins/ive/ReaderWriterIVE.cpp index 3d534aa90..389dc6766 100644 --- a/src/osgPlugins/ive/ReaderWriterIVE.cpp +++ b/src/osgPlugins/ive/ReaderWriterIVE.cpp @@ -28,6 +28,7 @@ class ReaderWriterIVE : public ReaderWriter supportsOption("useOriginalExternalReferences","Export option"); supportsOption("TerrainMaximumErrorToSizeRatio=value","Export option that controls error matric used to determine terrain HieghtField storage precision."); supportsOption("noLoadExternalReferenceFiles","Import option"); + supportsOption("OutputTextureFiles","Write out the texture images to file"); } virtual const char* className() const { return "IVE Reader/Writer"; } @@ -68,7 +69,7 @@ class ReaderWriterIVE : public ReaderWriter // code for setting up the database path so that internally referenced file are searched for on relative paths. osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName)); - + osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); return readNode(istream,local_opt.get()); } @@ -118,6 +119,9 @@ class ReaderWriterIVE : public ReaderWriter osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; if(local_opt->getDatabasePathList().empty()) local_opt->setDatabasePath(osgDB::getFilePath(fileName)); + + local_opt->setPluginStringData("filename",fileName); + osgDB::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary); if (!fout) return WriteResult::ERROR_IN_WRITING_FILE; WriteResult result = writeImage(image, fout, local_opt.get()); @@ -135,6 +139,8 @@ class ReaderWriterIVE : public ReaderWriter if(local_opt->getDatabasePathList().empty()) local_opt->setDatabasePath(osgDB::getFilePath(fileName)); + local_opt->setPluginStringData("filename",fileName); + osgDB::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary); if (!fout) return WriteResult::ERROR_IN_WRITING_FILE; diff --git a/src/osgPlugins/osgTerrain/ImageLayer.cpp b/src/osgPlugins/osgTerrain/ImageLayer.cpp index 07b481e4c..40d60212f 100644 --- a/src/osgPlugins/osgTerrain/ImageLayer.cpp +++ b/src/osgPlugins/osgTerrain/ImageLayer.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -64,10 +65,20 @@ bool ImageLayer_readLocalData(osg::Object& obj, osgDB::Input &fr) bool ImageLayer_writeLocalData(const osg::Object& obj, osgDB::Output& fw) { const osgTerrain::ImageLayer& layer = static_cast(obj); + + std::string fileName = layer.getFileName(); - if (!layer.getFileName().empty()) + if (fw.getOutputTextureFiles()) { - fw.indent()<<"file "<< layer.getFileName() << std::endl; + if (fileName.empty()) + { + fileName = fw.getTextureFileNameForOutput(); + } + osgDB::writeImageFile(*layer.getImage(), fileName); + } + if (!fileName.empty()) + { + fw.indent()<<"file "<< fw.wrapString(fileName) << std::endl; } return true;