ExternalFileWriter 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSGDB_PLUGIN_IMAGE_WRITER
  14. #define OSGDB_PLUGIN_IMAGE_WRITER 1
  15. #include <osgDB/Export>
  16. #include <string>
  17. #include <map>
  18. namespace osg
  19. {
  20. class Object;
  21. }
  22. namespace osgDB
  23. {
  24. class Options;
  25. /// Helper allowing 'intelligent' writing of external files (images, shaders, etc.), regarding to a main file (a scene), especially in plugins.
  26. /// Goals are:
  27. /// - Enable writing out objects only once (even if referenced multiple times)
  28. /// - Handle duplicates (avoid writing two different objects at the same place, renaming files as needed)
  29. /// - Handle directory creation when paths don't just exist
  30. /// - Generate writing paths which may keep original directory structure (depending on user wishes). Ex:
  31. /// Reading: model.osg and images/img1.jpg
  32. /// Writing with 'keepRelativePaths': /somePath/newmodel.osg and /somePath/images/img1.jpg
  33. /// Writing without 'keepRelativePaths': /somePath/newmodel.osg and /somePath/img1.jpg
  34. ///\author Sukender
  35. class OSGDB_EXPORT ExternalFileWriter
  36. {
  37. public:
  38. /// Builds the helper class with all options.
  39. ///\param srcDirectory Directory of the initial main file (if any), used as a base when relativising objects names. Not used if keepRelativePaths==false.
  40. ///\param destDirectory Directory where to write the main file.
  41. ///\param keepRelativePaths If true, then relative paths of source objects are kept if possible (ex: If an image is initially "imageDir/image.jpg" relatively to the source dir, then we'd like to get "destDir/imageDir/image.jpg"). If false, then only the simple file name is used to write the object file.
  42. ///\param allowUpDirs When relativising objects paths, sets the maximum number of directories the objects can be written "up" the destination directory. Not used if keepRelativePaths==false. Examples: If an image is initially "../image.jpg" relatively to the source dir *AND* if we allow one dir level up, then we'd like to get "destDirParent/destDir/../image.jpg" (= "destDirParent/image.jpg"). If we *DO NOT* allow one dir level up, then we'd like to get "destDir/image.jpg".
  43. ExternalFileWriter(const std::string & srcDirectory, const std::string & destDirectory, bool keepRelativePaths, unsigned int allowUpDirs=0);
  44. /// Short constructor used when not relativising objects paths, or when having no initial model file (which is pretty the same here).
  45. ExternalFileWriter(const std::string & destDirectory);
  46. /// Writes the current object if not already done.
  47. ///\param obj Object to write, using corresponding osgDB::write method.
  48. ///\param options Writing options to pass to corresponding osgDB::write method.
  49. ///\param [out] out_absolutePath Pointer to a string to be filled with absolute writing path, or NULL.
  50. ///\param [out] out_relativePath Pointer to a string to be filled with write path relative to the destination directory if possible (absolute path if not), or NULL.
  51. ///\return true on success, false otherwise.
  52. bool write(const osg::Object & obj, const osgDB::Options * options, std::string * out_absolutePath=NULL, std::string * out_relativePath=NULL);
  53. struct ObjectData
  54. {
  55. ObjectData() : written(false) {}
  56. ObjectData(const std::string & in_absolutePath, const std::string & in_relativePath, bool in_written) : absolutePath(in_absolutePath), relativePath(in_relativePath), written(in_written) {}
  57. std::string absolutePath;
  58. std::string relativePath;
  59. bool written; ///< Says if write succeeded or not.
  60. };
  61. /// Set of written objects, with their absolute writing path.
  62. /// Objects being passed to the write() method but which have failed to be effectively written are also included.
  63. typedef std::map<const osg::Object*, ObjectData> ObjectsSet;
  64. /// Returns the written objects.
  65. const ObjectsSet & getObjects() const { return _objects; }
  66. protected:
  67. // Dev note:
  68. // A multi-indexed structure would be more efficient for ObjectsSet (such as boost::multi_index, indexed on object pointer (unique), and hashed indexed on absolute path (unique)).
  69. // In order to get a correct search time, SearchMap "replaces" the multi-index structure for hashed indexes on absolute paths.
  70. typedef std::multimap<unsigned int, const osg::Object*> SearchMap;
  71. typedef unsigned int ObjectIndex; ///< Integer type used for indices of unnamed objects
  72. ObjectsSet _objects;
  73. SearchMap _searchMap; ///< Map used to search by absolute file path.
  74. ObjectIndex _lastGeneratedObjectIndex;
  75. const std::string _srcDirectory;
  76. const std::string _destDirectory;
  77. bool _keepRelativePaths;
  78. const unsigned int _allowUpDirs;
  79. /// Generates a unique name for an object to be written on disk.
  80. /// Side effect: updates _lastGeneratedObjectIndex to the index associated with the returned name.
  81. void generateObjectName(std::string & out_relativePath, std::string & out_absolutePath, int type);
  82. bool absoluteObjectPathExists(const std::string & path);
  83. private:
  84. // Prevent copy
  85. ExternalFileWriter & operator=(const ExternalFileWriter &);
  86. ExternalFileWriter(const ExternalFileWriter &);
  87. };
  88. }
  89. #endif // OSGDB_PLUGIN_IMAGE_WRITER