Thanks Mattias,

I've now merged and checked in all the changes except for the
CMakeLists.txt file change.

The reason for not merging the later is that we shouldn't force all
users to use static linking, rather provide the option to the user to
choose.  There are couple of places where this is done in the CMake
build system - just do a search for OPTION in the root CMakeLists.txt
for an example.

On review of your changes the code that used the auto_ptr to wrap up
string access and conversion to void* to shoe horn it into ne
Options::PluginData filed really felt awkward and makes me wonder if
the PluginData support should not be generalised to handle more
datatypes.  For instance we could use a data type field and union of
object types.

   void setPluginData(name, property);
   bool getPluginData(name, property);

When property could be something along the lines of what I did in
osg::ArgumentParser.  Perhaps this AgumentParser::Property could be
extended (to add void* and Referenced* supprt) and reused directly.

Robert.


On 9/28/07, Mattias Linde <[EMAIL PROTECTED]> wrote:
> Hi Robert,
>
> Nice, this almost gets the job done, one way communication into the plugin is 
> possible.
> I've done some additional small modification regarding constness in 
> ReaderWriter and added
> mutable on _pluginData so passing data back would be possible too.
>
> Have updated the collada plugin (ReaderWriterDAE.cpp) to use the map to 
> handle options and
> have attached the changes.
>
> The stuff in daeReader.h and daeWriter.h are just cosmetic changes to get rid 
> of a warning.
> CMakeLists.txt in src/osgPlugins/dae is changed to link with shared libs in 
> !WIN32
> instead of static libs (have proven to work better for me that way when 
> several libs used by
> the app link with the collada-libs).
>
> /Mattias
>
>
> On Fri, Sep 28, 2007 at 02:07:55PM +0100, Robert Osfield wrote:
> > Hi Mattias,
> >
> > I've checked in your changes and added a const getPluginData() as well
> > as a typedef for the map.
> >
> > Thanks,
> > Robert.
> >
> >
> > On 9/28/07, Mattias Linde <[EMAIL PROTECTED]> wrote:
> > > Hi again,
> > >
> > > I just tested the suggested additions in a small standalone app and a 
> > > thought
> > > struck me during my lunch break..  for the change to work in a plugin 
> > > (which
> > > gets a const options pointer) the 3 suggested methods needs to be const 
> > > and
> > > the _pluginData muteable.
> > >
> > > Sorry for sloppy testing.
> > >
> > > / Mattias
> > >
> > > On Fri, Sep 28, 2007 at 11:53:22AM +0200, Mattias Linde wrote:
> > > > Hi,
> > > >
> > > > Yes, I'm aware of possible threading issues but it's better to mention
> > > > such things once to often than never at all :)
> > > >
> > > > I've attached a modified ReaderWriter header which has some additions
> > > > to osgDB::ReaderWriter::Options to handle PluginData.
> > > >
> > > > I hope something like this could be useful for many plugins. I haven't
> > > > updated the collada plugin yet - and 'll wait with that until I know 
> > > > what
> > > > happens with this suggested change.
> > > >
> > > > / Mattias
> > > >
> > > > On Wed, Sep 26, 2007 at 11:32:22AM -0500, Thrall, Bryan wrote:
> > > > > Robert Osfield wrote on Wednesday, September 26, 2007 11:10 AM:
> > > > > > Hi Bryan,
> > > > > >
> > > > > > The threading issues are rather orthogonal to the general purpose 
> > > > > > API
> > > > > > save perhaps for adding a mutex to getting/setting internal data in 
> > > > > > a
> > > > > > single Options object, these will be a mute point if you simply pass
> > > > > > in a new Options object for each call.
> > > > > >
> > > > > > The main thread problems are related to the plugins themselves and 
> > > > > > if
> > > > > > they aren't thread safe then they need to use a serializer mutex to
> > > > > > marshal access to the plugin.  This side to the threading issues are
> > > > > > very plugin specific so have to be treated on a case by case basis.
> > > > >
> > > > > Right, I just wanted to make sure Mattias was aware of the potential
> > > > > problem, and so it was described in the list archives in case it helps
> > > > > future users of the feature :)
> > > > >
> > > > > > On 9/26/07, Thrall, Bryan <[EMAIL PROTECTED]> wrote:
> > > > > >> Robert Osfield wrote on Wednesday, September 26, 2007 9:19 AM:
> > > > > >>> Hi Mattias,
> > > > > >>>
> > > > > >>> I don't really have any strong suggestions for the name.
> > > > > >>> ExternalData/UserData/ExtraData/PluginData, I don't really know.
> > > > > >>
> > > > > >> I really like this idea; in my own work, paged data needs context
> > > > > >> information about the already loaded scenegraph, and this would 
> > > > > >> help
> > > > > >> out a lot (I'm currently working around the Options limit by
> > > > > >> subclassing and dynamic_casting).
> > > > > >>
> > > > > >> One thing I'm worried about is thread safety, though. If you modify
> > > > > >> the ExternalData/whatever, then you have to worry about the 
> > > > > >> (possibly
> > > > > >> multiple) DatabasePager threads accessing it, and potentially the
> > > > > >> (possibly multiple) render threads too if the data is used there. 
> > > > > >> Not
> > > > > >> that this is an argument against that design, but it's something to
> > > > > >> think about (I don't even know how the Collada plugin works, so 
> > > > > >> this
> > > > > >> problem might not even crop up at all here).
> > > > > >>
> > > > > >>> On 9/26/07, Mattias Linde <[EMAIL PROTECTED]> wrote:
> > > > > >>>> Hi Robert,
> > > > > >>>>
> > > > > >>>> When reading your reply I can agree that putting something like
> > > > > >>>> ColladaOptions into osgDB might not be the best thing to do. My
> > > > > >>>> thoughts when writing the code was to change as little as 
> > > > > >>>> possible
> > > > > >>>> and still be able to get access to plugin internal stuff and to
> > > > > >>>> have the option to pass in another pointer to be used.
> > > > > >>>>
> > > > > >>>> I'd think adding a std::map to ReaderWriter::Options and some
> > > > > >>>> methods to operate on it (set, get, remove - anything else
> > > > > >>>> needed?) would be better than just a userdata object. But I'm not
> > > > > >>>> sure what would be an appropriate name for it. I don't think
> > > > > >>>> ExternalData really describes it since it can be used to pass 
> > > > > >>>> back
> > > > > >>>> data from the plugin.
> > > > > >>>>
> > > > > >>>> / Mattias
> > > > > >>>>
> > > > > >>>> On Wed, Sep 26, 2007 at 11:51:29AM +0100, Robert Osfield wrote:
> > > > > >>>>> Hi Mattias,
> > > > > >>>>>
> > > > > >>>>> Thanks for the changes. I have done a quick review and am not
> > > > > >>>>> happy with placing a plugin specific data structure like
> > > > > >>>>> ColladaOptions into a general purpose library like osgDB.  Once
> > > > > >>>>> one starts going down the road in placing plugin specific data
> > > > > >>>>> structures in osgDB you'll end up on a slippery slope of messy
> > > > > >>>>> and difficult to maintain library.
> > > > > >>>>>
> > > > > >>>>> I don't have a solution to this problem yet.  Perhaps a general
> > > > > >>>>> purpose UserData object for passing in/out void pointers would 
> > > > > >>>>> be
> > > > > >>>>> sufficient.  Or perhaps one could provide a
> > > > > >>>>> std::map<std::string,void*> in ReaderWriter::Options base class
> > > > > >>>>> for passing in and out different types of data, i.e.
> > > > > >>>>>
> > > > > >>>>>    options->setExternalData("DAE",dataPtr);
> > > > > >>>>>
> > > > > >>>>>    DAE* daePtr = (DAE*)options->getExternalData("DAE");
> > > > > >>>>>
> > > > > >>>>>
> > > > > >>>>> The aim must be to keep things with a very loose coupling in
> > > > > >>>>> osgDB, and to make any extensions general purpose.
> > > > > >>>>>
> > > > > >>>>> Robert.
> > > > > >>>>>
> > > > > >>>>>
> > > > > >>>>> On 9/26/07, Mattias Linde <[EMAIL PROTECTED]> wrote:
> > > > > >>>>>> Hi,
> > > > > >>>>>>
> > > > > >>>>>> I've attached some suggested changes to the collada plugin:
> > > > > >>>>>>
> > > > > >>>>>> I've added a ColladaOptions class which can specify which DAE
> > > > > >>>>>> instance should be used. If no options are used when
> > > > > >>>>>> osgDB::readNodeFile is called the plugin will work just as
> > > > > >>>>>> before. (include/osgDB/ColladaOptions and
> > > > > >>>>>> src/osgDB/ColladaOptions.cpp in the tarball)
> > > > > >>>>>>
> > > > > >>>>>> With the colladaoptions one can use an "external" (as in 
> > > > > >>>>>> outside
> > > > > >>>>>> of osg) dae-instance which possibly already holds parsed data 
> > > > > >>>>>> or
> > > > > >>>>>> an internal instance (the plugin creates one unless it has
> > > > > >>>>>> already done so). The options object also makes it possible to
> > > > > >>>>>> get a pointer to the dae instance so it can be used outside of
> > > > > >>>>>> osg.
> > > > > >>>>>>
> > > > > >>>>>> src/osgPlugins/dae/ReaderWriterDAE.cpp have been updated to use
> > > > > >>>>>> ColladaOptions. daeReader.h and daeWriter.h have one minor 
> > > > > >>>>>> change
> > > > > >>>>>> each, a ; was removed after the namespace end } which caused a
> > > > > >>>>>> warning.
> > > > > >>>>>>
> > > > > >>>>>> CMakeLists.txt have also been updated to link with
> > > > > >>>>>> collada_dom_shared and collada_dae_shared (if not under win32)
> > > > > >>>>>> instead of collada_dom and collada_dae. This is because of
> > > > > >>>>>> collada-dom now supports building shared libs under linux (been
> > > > > >>>>>> tested on OS X aswell). Linking with the static libs in the
> > > > > >>>>>> plugin can (and have) cause problems if the application using
> > > > > >>>>>> osg links with collada-dom libraries.
> > > > > >>>>>>
> > > > > >>>>>> / Mattias
> > > > > --
> > > > > Bryan Thrall
> > > > > FlightSafety International
> > > > > [EMAIL PROTECTED]
> > > > > _______________________________________________
> > > > > osg-submissions mailing list
> > > > > [email protected]
> > > > > http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
> > >
> > > > /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
> > > >  *
> > > >  * This library is open source and may be redistributed and/or modified 
> > > > under
> > > >  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
> > > >  * (at your option) any later version.  The full license is in LICENSE 
> > > > file
> > > >  * included with this distribution, and on the openscenegraph.org 
> > > > website.
> > > >  *
> > > >  * This library is distributed in the hope that it will be useful,
> > > >  * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > >  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > >  * OpenSceneGraph Public License for more details.
> > > > */
> > > >
> > > > #ifndef OSGDB_READERWRITER
> > > > #define OSGDB_READERWRITER 1
> > > >
> > > > #include <osg/Referenced>
> > > > #include <osg/Image>
> > > > #include <osg/Shape>
> > > > #include <osg/Node>
> > > >
> > > > #include <osgDB/Export>
> > > >
> > > > #include <deque>
> > > > #include <iosfwd>
> > > >
> > > > namespace osgDB {
> > > >
> > > > class Archive;
> > > >
> > > > /** list of directories to search through which searching for files. */
> > > > typedef std::deque<std::string> FilePathList;
> > > >
> > > > /** pure virtual base class for reading and writing of non native 
> > > > formats. */
> > > > class OSGDB_EXPORT ReaderWriter : public osg::Object
> > > > {
> > > >     public:
> > > >
> > > >
> > > >         ReaderWriter():
> > > >             osg::Object(true) {}
> > > >
> > > >         ReaderWriter(const ReaderWriter& rw,const osg::CopyOp& 
> > > > copyop=osg::CopyOp::SHALLOW_COPY):
> > > >             osg::Object(rw,copyop) {}
> > > >
> > > >         virtual ~ReaderWriter();
> > > >
> > > >         META_Object(osgDB,ReaderWriter);
> > > >
> > > >         virtual bool acceptsExtension(const std::string& /*extension*/) 
> > > > const { return false; }
> > > >
> > > >         /** Options base class used for passing options into plugins to 
> > > > control their operation.*/
> > > >         class Options : public osg::Object
> > > >         {
> > > >             public:
> > > >
> > > >
> > > >                 /// bit mask for setting up which object types get 
> > > > cached by readObject/Image/HeightField/Node(filename) calls
> > > >                 enum CacheHintOptions
> > > >                 {   /// do not cache objects of any type
> > > >                     CACHE_NONE          = 0,
> > > >
> > > >                     /// cache nodes loaded via readNode(filename)
> > > >                     CACHE_NODES         = 1,
> > > >
> > > >                     /// cache images loaded via readImage(filename)
> > > >                     CACHE_IMAGES        = 2,
> > > >
> > > >                     /// cache heightfield loaded via 
> > > > readHeightField(filename)
> > > >                     CACHE_HEIGHTFIELDS  = 4,
> > > >
> > > >                     /// cache heightfield loaded via 
> > > > readHeightField(filename)
> > > >                     CACHE_ARCHIVES      = 8,
> > > >
> > > >                     /// cache objects loaded via readObject(filename)
> > > >                     CACHE_OBJECTS       = 16,
> > > >
> > > >                     /// cache on all read*(filename) calls
> > > >                     CACHE_ALL           = CACHE_NODES |
> > > >                                           CACHE_IMAGES |
> > > >                                           CACHE_HEIGHTFIELDS |
> > > >                                           CACHE_ARCHIVES |
> > > >                                           CACHE_OBJECTS
> > > >                 };
> > > >
> > > >
> > > >                 Options():
> > > >                     osg::Object(true),
> > > >                     _objectCacheHint(CACHE_ARCHIVES) {}
> > > >                 Options(const std::string& str):
> > > >                     osg::Object(true),
> > > >                     _str(str),
> > > >                     _objectCacheHint(CACHE_ARCHIVES) {}
> > > >
> > > >                 Options(const Options& options,const osg::CopyOp& 
> > > > copyop=osg::CopyOp::SHALLOW_COPY):
> > > >                     osg::Object(options,copyop),
> > > >                     _str(options._str),
> > > >                     _databasePaths(options._databasePaths),
> > > >                     _objectCacheHint(options._objectCacheHint) {}
> > > >
> > > >                 META_Object(osgDB,Options);
> > > >
> > > >                 /** Set the general Options string.*/
> > > >                 void setOptionString(const std::string& str) { _str = 
> > > > str; }
> > > >
> > > >                 /** Get the general Options string.*/
> > > >                 const std::string& getOptionString() const { return 
> > > > _str; }
> > > >
> > > >                 /** Set the database path to use a hint of where to 
> > > > look when loading models.*/
> > > >                 void setDatabasePath(const std::string& str) { 
> > > > _databasePaths.clear();  _databasePaths.push_back(str); }
> > > >
> > > >                 /** Get the database path which is used a hint of where 
> > > > to look when loading models.*/
> > > >                 FilePathList& getDatabasePathList() { return 
> > > > _databasePaths; }
> > > >
> > > >                 /** Get the const database path which is used a hint of 
> > > > where to look when loading models.*/
> > > >                 const FilePathList& getDatabasePathList() const { 
> > > > return _databasePaths; }
> > > >
> > > >                 /** Set whether the Registry::ObjectCache should be 
> > > > used by default.*/
> > > >                 void setObjectCacheHint(CacheHintOptions 
> > > > useObjectCache) { _objectCacheHint = useObjectCache; }
> > > >
> > > >                 /** Get whether the Registry::ObjectCache should be 
> > > > used by default.*/
> > > >                 CacheHintOptions getObjectCacheHint() const { return 
> > > > _objectCacheHint; }
> > > >
> > > >                 /** Sets a plugindata value associated with a string */
> > > >                 void setPluginData(const std::string& s, void* v) { 
> > > > _pluginData[s] = v; }
> > > >
> > > >                 /** Get a value from the plugindate */
> > > >                 void* getPluginData(const std::string& s) { return 
> > > > _pluginData[s]; }
> > > >
> > > >                 /** Remove a value from the plugindata */
> > > >                 void removePluginData(const std::string& s) { 
> > > > _pluginData.erase(s); }
> > > >             protected:
> > > >
> > > >                 virtual ~Options() {}
> > > >
> > > >                 std::string         _str;
> > > >                 FilePathList        _databasePaths;
> > > >                 CacheHintOptions    _objectCacheHint;
> > > >
> > > >                 std::map<std::string,void*>  _pluginData;
> > > >         };
> > > >
> > > >
> > > >         class OSGDB_EXPORT ReadResult
> > > >         {
> > > >             public:
> > > >
> > > >                 enum ReadStatus
> > > >                 {
> > > >                     FILE_NOT_HANDLED,
> > > >                     FILE_NOT_FOUND,
> > > >                     FILE_LOADED,
> > > >                     FILE_LOADED_FROM_CACHE,
> > > >                     ERROR_IN_READING_FILE
> > > >                 };
> > > >
> > > >                 ReadResult(ReadStatus 
> > > > status=FILE_NOT_HANDLED):_status(status) {}
> > > >                 ReadResult(const std::string& 
> > > > m):_status(ERROR_IN_READING_FILE),_message(m) {}
> > > >                 ReadResult(osg::Object* obj, ReadStatus 
> > > > status=FILE_LOADED):_status(status),_object(obj) {}
> > > >
> > > >                 ReadResult(const ReadResult& 
> > > > rr):_status(rr._status),_message(rr._message),_object(rr._object) {}
> > > >                 ReadResult& operator = (const ReadResult& rr) { if 
> > > > (this==&rr) return *this; _status=rr._status; 
> > > > _message=rr._message;_object=rr._object; return *this; }
> > > >
> > > >                 osg::Object* getObject();
> > > >                 osg::Image* getImage();
> > > >                 osg::HeightField* getHeightField();
> > > >                 osg::Node* getNode();
> > > >                 osgDB::Archive* getArchive();
> > > >
> > > >                 bool validObject() { return _object.valid(); }
> > > >                 bool validImage() { return getImage()!=0; }
> > > >                 bool validHeightField() { return getHeightField()!=0; }
> > > >                 bool validNode() { return getNode()!=0; }
> > > >                 bool validArchive() { return getArchive()!=0; }
> > > >
> > > >                 osg::Object* takeObject();
> > > >                 osg::Image* takeImage();
> > > >                 osg::HeightField* takeHeightField();
> > > >                 osg::Node* takeNode();
> > > >                 osgDB::Archive* takeArchive();
> > > >
> > > >                 std::string& message() { return _message; }
> > > >                 const std::string& message() const { return _message; }
> > > >
> > > >                 ReadStatus status() const { return _status; }
> > > >                 bool success() const { return _status==FILE_LOADED || 
> > > > _status==FILE_LOADED_FROM_CACHE ; }
> > > >                 bool loadedFromCache() const { return 
> > > > _status==FILE_LOADED_FROM_CACHE; }
> > > >                 bool error() const { return 
> > > > _status==ERROR_IN_READING_FILE; }
> > > >                 bool notHandled() const { return 
> > > > _status==FILE_NOT_HANDLED; }
> > > >                 bool notFound() const { return _status==FILE_NOT_FOUND; 
> > > > }
> > > >
> > > >             protected:
> > > >
> > > >                 ReadStatus                  _status;
> > > >                 std::string                 _message;
> > > >                 osg::ref_ptr<osg::Object>   _object;
> > > >         };
> > > >
> > > >         class WriteResult
> > > >         {
> > > >             public:
> > > >
> > > >                 enum WriteStatus
> > > >                 {
> > > >                     FILE_NOT_HANDLED,
> > > >                     FILE_SAVED,
> > > >                     ERROR_IN_WRITING_FILE
> > > >                 };
> > > >
> > > >                 WriteResult(WriteStatus 
> > > > status=FILE_NOT_HANDLED):_status(status) {}
> > > >                 WriteResult(const std::string& 
> > > > m):_status(ERROR_IN_WRITING_FILE),_message(m) {}
> > > >
> > > >                 WriteResult(const WriteResult& 
> > > > rr):_status(rr._status),_message(rr._message) {}
> > > >                 WriteResult& operator = (const WriteResult& rr) { if 
> > > > (this==&rr) return *this; _status=rr._status; _message=rr._message; 
> > > > return *this; }
> > > >
> > > >                 std::string& message() { return _message; }
> > > >                 const std::string& message() const { return _message; }
> > > >
> > > >                 WriteStatus status() const { return _status; }
> > > >                 bool success() const { return _status==FILE_SAVED; }
> > > >                 bool error() const { return 
> > > > _status==ERROR_IN_WRITING_FILE; }
> > > >                 bool notHandled() const { return 
> > > > _status==FILE_NOT_HANDLED; }
> > > >
> > > >             protected:
> > > >
> > > >                 WriteStatus                 _status;
> > > >                 std::string                 _message;
> > > >         };
> > > >
> > > >         enum ArchiveStatus
> > > >         {
> > > >             READ,
> > > >             WRITE,
> > > >             CREATE
> > > >         };
> > > >
> > > >         /** open an archive for reading, writing, or to create an empty 
> > > > archive for writing to.*/
> > > >         virtual ReadResult openArchive(const std::string& 
> > > > /*fileName*/,ArchiveStatus, unsigned int =4096, const Options* =NULL) 
> > > > const { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
> > > >
> > > >         /** open an archive for reading.*/
> > > >         virtual ReadResult openArchive(std::istream& /*fin*/,const 
> > > > Options* =NULL) const { return 
> > > > ReadResult(ReadResult::FILE_NOT_HANDLED); }
> > > >
> > > >         virtual ReadResult readObject(const std::string& 
> > > > /*fileName*/,const Options* =NULL) const { return 
> > > > ReadResult(ReadResult::FILE_NOT_HANDLED); }
> > > >         virtual ReadResult readImage(const std::string& 
> > > > /*fileName*/,const Options* =NULL) const { return 
> > > > ReadResult(ReadResult::FILE_NOT_HANDLED); }
> > > >         virtual ReadResult readHeightField(const std::string& 
> > > > /*fileName*/,const Options* =NULL) const { return 
> > > > ReadResult(ReadResult::FILE_NOT_HANDLED); }
> > > >         virtual ReadResult readNode(const std::string& 
> > > > /*fileName*/,const Options* =NULL) const { return 
> > > > ReadResult(ReadResult::FILE_NOT_HANDLED); }
> > > >
> > > >         virtual WriteResult writeObject(const osg::Object& 
> > > > /*obj*/,const std::string& /*fileName*/,const Options* =NULL) const 
> > > > {return WriteResult(WriteResult::FILE_NOT_HANDLED); }
> > > >         virtual WriteResult writeImage(const osg::Image& 
> > > > /*image*/,const std::string& /*fileName*/,const Options* =NULL) const 
> > > > {return WriteResult(WriteResult::FILE_NOT_HANDLED); }
> > > >         virtual WriteResult writeHeightField(const osg::HeightField& 
> > > > /*heightField*/,const std::string& /*fileName*/,const Options* =NULL) 
> > > > const {return WriteResult(WriteResult::FILE_NOT_HANDLED); }
> > > >         virtual WriteResult writeNode(const osg::Node& /*node*/,const 
> > > > std::string& /*fileName*/,const Options* =NULL) const { return 
> > > > WriteResult(WriteResult::FILE_NOT_HANDLED); }
> > > >
> > > >         virtual ReadResult readObject(std::istream& /*fin*/,const 
> > > > Options* =NULL) const { return 
> > > > ReadResult(ReadResult::FILE_NOT_HANDLED); }
> > > >         virtual ReadResult readImage(std::istream& /*fin*/,const 
> > > > Options* =NULL) const { return 
> > > > ReadResult(ReadResult::FILE_NOT_HANDLED); }
> > > >         virtual ReadResult readHeightField(std::istream& /*fin*/,const 
> > > > Options* =NULL) const { return 
> > > > ReadResult(ReadResult::FILE_NOT_HANDLED); }
> > > >         virtual ReadResult readNode(std::istream& /*fin*/,const 
> > > > Options* =NULL) const { return 
> > > > ReadResult(ReadResult::FILE_NOT_HANDLED); }
> > > >
> > > >         virtual WriteResult writeObject(const osg::Object& 
> > > > /*obj*/,std::ostream& /*fout*/,const Options* =NULL) const { return 
> > > > WriteResult(WriteResult::FILE_NOT_HANDLED); }
> > > >         virtual WriteResult writeImage(const osg::Image& 
> > > > /*image*/,std::ostream& /*fout*/,const Options* =NULL) const { return 
> > > > WriteResult(WriteResult::FILE_NOT_HANDLED); }
> > > >         virtual WriteResult writeHeightField(const osg::HeightField& 
> > > > /*heightField*/,std::ostream& /*fout*/,const Options* =NULL) const { 
> > > > return WriteResult(WriteResult::FILE_NOT_HANDLED); }
> > > >         virtual WriteResult writeNode(const osg::Node& 
> > > > /*node*/,std::ostream& /*fout*/,const Options* =NULL) const { return 
> > > > WriteResult(WriteResult::FILE_NOT_HANDLED); }
> > > >
> > > > };
> > > >
> > > > }
> > > >
> > > > #endif // OSGDB_READERWRITER
> > >
> > > > _______________________________________________
> > > > osg-submissions mailing list
> > > > [email protected]
> > > > http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
> > >
> > > _______________________________________________
> > > osg-submissions mailing list
> > > [email protected]
> > > http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
> > >
> > _______________________________________________
> > osg-submissions mailing list
> > [email protected]
> > http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
> _______________________________________________
> osg-submissions mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
>
>
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to