1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
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.
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.
14#ifndef OSGDB_PLUGIN_IMAGE_WRITER
15#define OSGDB_PLUGIN_IMAGE_WRITER 1
17#include <osgDB/Export>
31 /// Helper allowing 'intelligent' writing of external files (images, shaders, etc.), regarding to a main file (a scene), especially in plugins.
33 /// - Enable writing out objects only once (even if referenced multiple times)
34 /// - Handle duplicates (avoid writing two different objects at the same place, renaming files as needed)
35 /// - Handle directory creation when paths don't just exist
36 /// - Generate writing paths which may keep original directory structure (depending on user wishes). Ex:
37 /// Reading: model.osg and images/img1.jpg
38 /// Writing with 'keepRelativePaths': /somePath/newmodel.osg and /somePath/images/img1.jpg
39 /// Writing without 'keepRelativePaths': /somePath/newmodel.osg and /somePath/img1.jpg
41 class OSGDB_EXPORT ExternalFileWriter
44 /// Builds the helper class with all options.
45 ///\param srcDirectory Directory of the initial main file (if any), used as a base when relativising objects names. Not used if keepRelativePaths==false.
46 ///\param destDirectory Directory where to write the main file.
47 ///\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.
48 ///\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".
49 ExternalFileWriter(const std::string & srcDirectory, const std::string & destDirectory, bool keepRelativePaths, unsigned int allowUpDirs=0);
51 /// Short constructor used when not relativising objects paths, or when having no initial model file (which is pretty the same here).
52 ExternalFileWriter(const std::string & destDirectory);
54 /// Writes the current object if not already done.
55 ///\param obj Object to write, using corresponding osgDB::write method.
56 ///\param options Writing options to pass to corresponding osgDB::write method.
57 ///\param [out] out_absolutePath Pointer to a string to be filled with absolute writing path, or NULL.
58 ///\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.
59 ///\return true on success, false otherwise.
60 bool write(const osg::Object & obj, const osgDB::Options * options, std::string * out_absolutePath=NULL, std::string * out_relativePath=NULL);
64 ObjectData() : written(false) {}
65 ObjectData(const std::string & in_absolutePath, const std::string & in_relativePath, bool in_written) : absolutePath(in_absolutePath), relativePath(in_relativePath), written(in_written) {}
66 std::string absolutePath;
67 std::string relativePath;
68 bool written; ///< Says if write succeeded or not.
71 /// Set of written objects, with their absolute writing path.
72 /// Objects being passed to the write() method but which have failed to be effectively written are also included.
73 typedef std::map<const osg::Object*, ObjectData> ObjectsSet;
75 /// Returns the written objects.
76 const ObjectsSet & getObjects() const { return _objects; }
80 // 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)).
81 // In order to get a correct search time, SearchMap "replaces" the multi-index structure for hashed indexes on absolute paths.
82 typedef std::multimap<unsigned int, const osg::Object*> SearchMap;
83 typedef unsigned int ObjectIndex; ///< Integer type used for indices of unnamed objects
85 SearchMap _searchMap; ///< Map used to search by absolute file path.
86 ObjectIndex _lastGeneratedObjectIndex;
87 const std::string _srcDirectory;
88 const std::string _destDirectory;
89 bool _keepRelativePaths;
90 const unsigned int _allowUpDirs;
92 /// Generates a unique name for an object to be written on disk.
93 /// Side effect: updates _lastGeneratedObjectIndex to the index associated with the returned name.
94 void generateObjectName(std::string & out_relativePath, std::string & out_absolutePath, int type);
96 bool absoluteObjectPathExists(const std::string & path);
100 ExternalFileWriter & operator=(const ExternalFileWriter &);
101 ExternalFileWriter(const ExternalFileWriter &);
105#endif // OSGDB_PLUGIN_IMAGE_WRITER