root/OpenSceneGraph/trunk/src/osgPlugins/osg/ReaderWriterOSG2.cpp @ 11018

Revision 11018, 11.4 kB (checked in by robert, 4 years ago)

From Wang Rui, "Changes:

1. Rewrite the reading/writing exception handlers to work like the ive
plugin exceptions.
2. Write a header writing/checking function in ReaderWriterOSG2.cpp,
which may help decide if the stream is ascii or binary. The
readInputIterator() function will return null pointer if the input
file is nither osgb nor osgt format, which indicates that the old .osg
format could be used here, in case we've merged the two plugins
together.
3. Add a new ForceReadingImage? option in the InputStream?, which will
allocate an empty image object with the filename if specifed external
image file is missed. It may be useful for format converting in some
cases.
4. Add new osgParticle wrappers, as well as some modification to the
osgParticle headers, for instance, change isEnabled() to getEnabled().
5. Some fixes to the osg serialization wrappers."

Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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// Written by Wang Rui, (C) 2010
14
15#include <osgDB/FileNameUtils>
16#include <osgDB/FileUtils>
17#include <osgDB/Registry>
18#include <osgDB/ObjectWrapper>
19#include "AsciiStreamOperator.h"
20#include "BinaryStreamOperator.h"
21
22using namespace osgDB;
23
24#define CATCH_EXCEPTION(s) \
25    if (s.getException()) return (s.getException()->getError() + " At " + s.getException()->getField());
26
27InputIterator* readInputIterator( std::istream& fin, const Options* options )
28{
29    bool extensionIsAscii = false;
30    if ( options && options->getOptionString().find("Ascii")!=std::string::npos )
31        extensionIsAscii = true;
32   
33    if ( !extensionIsAscii )
34    {
35        unsigned int headerLow = 0, headerHigh = 0;
36        fin.read( (char*)&headerLow, INT_SIZE );
37        fin.read( (char*)&headerHigh, INT_SIZE );
38        if ( headerLow==OSG_HEADER_LOW && headerHigh==OSG_HEADER_HIGH )
39        {
40            return new BinaryInputIterator(&fin);
41        }
42        fin.seekg( 0, std::ios::beg );
43    }
44   
45    std::string header; fin >> header;
46    if ( header=="#Ascii" )
47    {
48        return new AsciiInputIterator(&fin);
49    }
50    return NULL;
51}
52
53OutputIterator* writeInputIterator( std::ostream& fout, const Options* options )
54{
55    if ( options && options->getOptionString().find("Ascii")!=std::string::npos )
56    {
57        fout << std::string("#Ascii") << ' ';
58        return new AsciiOutputIterator(&fout);
59    }
60    else
61    {
62        unsigned int low = OSG_HEADER_LOW, high = OSG_HEADER_HIGH;
63        fout.write( (char*)&low, INT_SIZE );
64        fout.write( (char*)&high, INT_SIZE );
65        return new BinaryOutputIterator(&fout);
66    }
67}
68
69class ReaderWriterOSG2 : public osgDB::ReaderWriter
70{
71public:
72    ReaderWriterOSG2()
73    {
74        supportsExtension( "osg2", "OpenSceneGraph extendable format" );
75        supportsExtension( "osgt", "OpenSceneGraph extendable ascii format" );
76        supportsExtension( "osgb", "OpenSceneGraph extendable binary format" );
77       
78        supportsOption( "Ascii", "Import/Export option: Force reading/writing ascii file" );
79        supportsOption( "ForceReadingImage", "Import option: Load an empty image instead if required file missed" );
80        supportsOption( "SchemaFile=<file>", "Import/Export option: Use/Record a ascii schema file" );
81        supportsOption( "Compressor=<name>", "Export option: Use an inbuilt or user-defined compressor" );
82        supportsOption( "WriteImageHint=<hint>", "Export option: Hint of writing image to stream: "
83                        "<IncludeData> writes Image::data() directly; "
84                        "<IncludeFile> writes the image file itself to stream; "
85                        "<UseExternal> writes only the filename; "
86                        "<WriteOut> writes Image::data() to disk as external file." );
87
88        std::string filename = osgDB::Registry::instance()->createLibraryNameForExtension("serializers_osg");
89        if (osgDB::Registry::instance()->loadLibrary(filename)==osgDB::Registry::LOADED)
90        {
91            osg::notify(osg::NOTICE)<<"Constructor ReaderWriterOSG2 - loaded OK"<<std::endl;
92        }
93        else
94        {
95            osg::notify(osg::NOTICE)<<"Constructor ReaderWriterOSG2 - failed to load"<<std::endl;
96        }
97    }
98   
99    virtual const char* className() const
100    { return "OpenSceneGraph Native Format Reader/Writer"; }
101   
102    virtual ReadResult readObject( const std::string& file, const Options* options ) const
103    { return readNode(file, options); }
104   
105    virtual ReadResult readObject( std::istream& fin, const Options* options ) const
106    { return readNode(fin, options); }
107   
108    virtual ReadResult readImage( const std::string& file, const Options* options ) const
109    {
110        std::string ext = osgDB::getLowerCaseFileExtension( file );
111        if ( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED;
112        std::string fileName = osgDB::findDataFile( file, options );
113        if ( fileName.empty() ) return ReadResult::FILE_NOT_FOUND;
114       
115        osg::ref_ptr<Options> local_opt = options ?
116            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
117        local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
118        if ( ext=="osgt" ) local_opt->setOptionString( local_opt->getOptionString() + " Ascii" );
119       
120        osgDB::ifstream istream( fileName.c_str(), std::ios::out|std::ios::binary );
121        return readImage( istream, local_opt.get() );
122    }
123   
124    virtual ReadResult readImage( std::istream& fin, const Options* options ) const
125    {
126        osg::ref_ptr<InputIterator> ii = readInputIterator(fin, options);
127        if ( !ii ) return ReadResult::FILE_NOT_HANDLED;
128       
129        InputStream is( options );
130        if ( is.start(ii.get())!=InputStream::READ_IMAGE )
131        {
132            CATCH_EXCEPTION(is);
133            return ReadResult::FILE_NOT_HANDLED;
134        }
135        is.decompress(); CATCH_EXCEPTION(is);
136        osg::Image* image = is.readImage(); CATCH_EXCEPTION(is);
137        return image;
138    }
139   
140    virtual ReadResult readNode( const std::string& file, const Options* options ) const
141    {
142        std::string ext = osgDB::getLowerCaseFileExtension( file );
143        if ( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED;
144        std::string fileName = osgDB::findDataFile( file, options );
145        if ( fileName.empty() ) return ReadResult::FILE_NOT_FOUND;
146       
147        osg::ref_ptr<Options> local_opt = options ?
148            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
149        local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
150        if ( ext=="osgt" ) local_opt->setOptionString( local_opt->getOptionString() + " Ascii" );
151       
152        osgDB::ifstream istream( fileName.c_str(), std::ios::out|std::ios::binary );
153        return readNode( istream, local_opt.get() );
154    }
155   
156    virtual ReadResult readNode( std::istream& fin, const Options* options ) const
157    {
158        osg::ref_ptr<InputIterator> ii = readInputIterator(fin, options);
159        if ( !ii ) return ReadResult::FILE_NOT_HANDLED;
160       
161        InputStream is( options );
162        if ( is.start(ii.get())!=InputStream::READ_SCENE )
163        {
164            CATCH_EXCEPTION(is);
165            return ReadResult::FILE_NOT_HANDLED;
166        }
167       
168        is.decompress(); CATCH_EXCEPTION(is);
169        osg::Node* node = dynamic_cast<osg::Node*>(is.readObject()); CATCH_EXCEPTION(is);
170        return node;
171    }
172   
173    virtual WriteResult writeObject( const osg::Object& object, const std::string& fileName, const Options* options ) const
174    {
175        const osg::Node* node = dynamic_cast<const osg::Node*>( &object );
176        if ( node ) return writeNode( *node, fileName, options );
177       
178        const osg::Image* image = dynamic_cast<const osg::Image*>( &object );
179        if ( image ) return writeImage( *image, fileName, options );
180        return WriteResult::FILE_NOT_HANDLED;
181    }
182   
183    virtual WriteResult writeObject( const osg::Object& object, std::ostream& fout, const Options* options ) const
184    {
185        const osg::Node* node = dynamic_cast<const osg::Node*>( &object );
186        if ( node ) return writeNode( *node, fout, options );
187       
188        const osg::Image* image = dynamic_cast<const osg::Image*>( &object );
189        if ( image ) return writeImage( *image, fout, options );
190        return WriteResult::FILE_NOT_HANDLED;
191    }
192   
193    virtual WriteResult writeImage( const osg::Image& image, const std::string& fileName, const Options* options ) const
194    {
195        std::string ext = osgDB::getFileExtension( fileName );
196        if ( !acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED;
197       
198        osg::ref_ptr<Options> local_opt = options ?
199            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
200        if( local_opt->getDatabasePathList().empty() )
201            local_opt->setDatabasePath( osgDB::getFilePath(fileName) );
202        if ( ext=="osgt" ) local_opt->setOptionString( local_opt->getOptionString() + " Ascii" );
203       
204        osgDB::ofstream fout( fileName.c_str(), std::ios::out|std::ios::binary );
205        if ( !fout ) return WriteResult::ERROR_IN_WRITING_FILE;
206       
207        WriteResult result = writeImage( image, fout, local_opt.get() );
208        fout.close();
209        return result;
210    }
211   
212    virtual WriteResult writeImage( const osg::Image& image, std::ostream& fout, const Options* options ) const
213    {
214        osg::ref_ptr<OutputIterator> oi = writeInputIterator(fout, options);
215       
216        OutputStream os( options );
217        os.start( oi.get(), OutputStream::WRITE_IMAGE ); CATCH_EXCEPTION(os);
218        os.writeImage( &image ); CATCH_EXCEPTION(os);
219        os.compress( &fout ); CATCH_EXCEPTION(os);
220       
221        if ( !os.getSchemaName().empty() )
222        {
223            osgDB::ofstream schemaStream( os.getSchemaName().c_str(), std::ios::out );
224            if ( !schemaStream.fail() ) os.writeSchema( schemaStream );
225            schemaStream.close();
226        }
227       
228        if ( fout.fail() ) return WriteResult::ERROR_IN_WRITING_FILE;
229        return WriteResult::FILE_SAVED;
230    }
231   
232    virtual WriteResult writeNode( const osg::Node& node, const std::string& fileName, const Options* options ) const
233    {
234        std::string ext = osgDB::getFileExtension( fileName );
235        if ( !acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED;
236       
237        osg::ref_ptr<Options> local_opt = options ?
238            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
239        if ( local_opt->getDatabasePathList().empty() )
240            local_opt->setDatabasePath( osgDB::getFilePath(fileName) );
241        if ( ext=="osgt" ) local_opt->setOptionString( local_opt->getOptionString() + " Ascii" );
242       
243        osgDB::ofstream fout( fileName.c_str(), std::ios::out|std::ios::binary );
244        if ( !fout ) return WriteResult::ERROR_IN_WRITING_FILE;
245       
246        WriteResult result = writeNode( node, fout, local_opt.get() );
247        fout.close();
248        return result;
249    }
250   
251    virtual WriteResult writeNode( const osg::Node& node, std::ostream& fout, const Options* options ) const
252    {
253        osg::ref_ptr<OutputIterator> oi = writeInputIterator(fout, options);
254       
255        OutputStream os( options );
256        os.start( oi.get(), OutputStream::WRITE_SCENE ); CATCH_EXCEPTION(os);
257        os.writeObject( &node ); CATCH_EXCEPTION(os);
258        os.compress( &fout ); CATCH_EXCEPTION(os);
259       
260        if ( !os.getSchemaName().empty() )
261        {
262            osgDB::ofstream schemaStream( os.getSchemaName().c_str(), std::ios::out );
263            if ( !schemaStream.fail() ) os.writeSchema( schemaStream );
264            schemaStream.close();
265        }
266       
267        if ( fout.fail() ) return WriteResult::ERROR_IN_WRITING_FILE;
268        return WriteResult::FILE_SAVED;
269    }
270};
271
272REGISTER_OSGPLUGIN( osg2, ReaderWriterOSG2 )
Note: See TracBrowser for help on using the browser.