root/OpenSceneGraph/trunk/src/osgDB/PropertyInterface.cpp @ 13890

Revision 13890, 18.9 kB (checked in by robert, 13 days ago)

Moved widgets from VolumeEditorWidget? to TransferFunctionWidget?, and widget utilities into WidgetUtils?.

Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2013 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
14
15#include <osgDB/PropertyInterface>
16
17namespace osgDB  // start of osgDB namespace
18{
19
20osgDB::BaseSerializer::Type getTypeEnumFromPtr(const osg::Object*) { return osgDB::BaseSerializer::RW_OBJECT; }
21const char* getTypeStringFromPtr(const osg::Object*) { return "OBJECT"; }
22
23osgDB::BaseSerializer::Type getTypeEnumFromPtr(const osg::Image*) { return osgDB::BaseSerializer::RW_IMAGE; }
24const char* getTypeStringFromPtr(const osg::Image*) { return "IMAGE"; }
25
26///////////////////////////////////////////////////////////////////
27//
28// PropertyOutputIterator enables the get of class properties
29//
30class PropertyOutputIterator : public osgDB::OutputIterator
31{
32public:
33
34    PropertyOutputIterator()
35    {
36    }
37
38    virtual ~PropertyOutputIterator() {}
39
40    virtual bool isBinary() const { return true; }
41
42
43    template<typename T>
44    inline void write(T t)
45    {
46        char* ptr = reinterpret_cast<char*>(&t);
47        _str.insert(_str.size(), ptr, sizeof(T));
48    }
49
50    virtual void writeBool( bool b ) { _str.push_back(b?0:1); }
51    virtual void writeChar( char c ) { _str.push_back(c); }
52    virtual void writeUChar( unsigned char c ) { _str.push_back(static_cast<char>(c)); }
53    virtual void writeShort( short s ) { write(s); }
54    virtual void writeUShort( unsigned short s ) { write(s); }
55    virtual void writeInt( int i ) { write(i); }
56    virtual void writeUInt( unsigned int i ) { write(i);  }
57    virtual void writeLong( long l ) { write(l); }
58    virtual void writeULong( unsigned long l ) { write(l); }
59    virtual void writeFloat( float f ) { write(f); }
60    virtual void writeDouble( double d ) { write(d); }
61    virtual void writeString( const std::string& s ) { _str.insert(_str.end(), s.begin(), s.end()); }
62    virtual void writeStream( std::ostream& (*fn)(std::ostream&) ) {}
63    virtual void writeBase( std::ios_base& (*fn)(std::ios_base&) ) {}
64    virtual void writeGLenum( const osgDB::ObjectGLenum& value ) { writeInt(value.get()); }
65    virtual void writeProperty( const osgDB::ObjectProperty& prop ) { _propertyName = prop._name; }
66    virtual void writeMark( const osgDB::ObjectMark& mark ) { _markName = mark._name; }
67    virtual void writeCharArray( const char* s, unsigned int size) { _str.insert(std::string::npos, s, size); }
68    virtual void writeWrappedString( const std::string& str ) { _str.insert(_str.end(), str.begin(), str.end()); }
69
70    virtual void flush()
71    {
72        _str.clear();
73        _propertyName.clear();
74        _markName.clear();
75    }
76
77    std::string         _str;
78    std::string         _propertyName;
79    std::string         _markName;
80};
81
82///////////////////////////////////////////////////////////////////
83//
84// PropertyInputIterator enables the set of class properties
85//
86class OSGDB_EXPORT PropertyInputIterator : public osgDB::InputIterator
87{
88public:
89    PropertyInputIterator():
90        _sstream(std::stringstream::binary),
91        _bufferData(0),
92        _currentPtr(0),
93        _bufferSize(0)
94    {
95        setStream(&_sstream);
96    }
97    virtual ~PropertyInputIterator()
98    {
99        if (_bufferData) delete [] _bufferData;
100        setStream(0);
101    }
102
103    virtual bool isBinary() const { return true; }
104
105    template<typename T>
106    void read(T& value)
107    {
108        memcpy(reinterpret_cast<char*>(&value), _currentPtr, sizeof(T));
109        _currentPtr += sizeof(T);
110    }
111
112    virtual void readBool( bool& b ) { char c; read(c); b = (c==1);}
113    virtual void readChar( char& c ) { read(c); }
114    virtual void readSChar( signed char& c ) { read(c); }
115    virtual void readUChar( unsigned char& c ) { read(c); }
116    virtual void readShort( short& s ) { read(s); }
117    virtual void readUShort( unsigned short& s ) { read(s); }
118    virtual void readInt( int& i ) { read(i); }
119    virtual void readUInt( unsigned int& i ) { read(i);}
120    virtual void readLong( long& l ) { read(l); }
121    virtual void readULong( unsigned long& l ) { read(l); }
122    virtual void readFloat( float& f ) { read(f); }
123    virtual void readDouble( double& d ) { read(d); }
124    virtual void readString( std::string& s ) { s = std::string(_bufferData, _bufferSize); }
125
126    virtual void readStream( std::istream& (*fn)(std::istream&) ) {}
127    virtual void readBase( std::ios_base& (*fn)(std::ios_base&) ) {}
128
129    virtual void readGLenum( ObjectGLenum& value ) { readUInt(value._value); }
130    virtual void readProperty( ObjectProperty& prop ) {}
131    virtual void readMark( ObjectMark& mark ) {}
132    virtual void readCharArray( char* s, unsigned int size ) { if ( size>0 ) _in->read( s, size ); }
133    virtual void readWrappedString( std::string& str ) { readString(str); }
134
135    virtual bool matchString( const std::string& /*str*/ ) { return false; }
136
137    template<typename T>
138    void set(const T& value)
139    {
140        if (_bufferData) delete [] _bufferData;
141        _bufferData = new char[sizeof(T)];
142        _bufferSize = sizeof(T);
143        _currentPtr = _bufferData;
144        memcpy(_bufferData, reinterpret_cast<const char*>(&value), sizeof(T));
145    }
146
147    void set(const void* ptr, unsigned int valueSize)
148    {
149        if (_bufferData) delete [] _bufferData;
150        _bufferData = new char[valueSize];
151        _currentPtr = _bufferData;
152        _bufferSize = valueSize;
153        memcpy(_bufferData, reinterpret_cast<const char*>(ptr), valueSize);
154    }
155
156    std::stringstream _sstream;
157    char* _bufferData;
158    char* _currentPtr;
159    unsigned int _bufferSize;
160};
161
162
163////////////////////////////////////////////////////////////////////////////////////////////////////////////
164//
165// PropertyInterface class provides a generic mechanism for get/setting class properties using the osgDB serializers
166//
167PropertyInterface::PropertyInterface():
168    _outputStream(0),
169    _inputStream(0)
170{
171    _poi = new PropertyOutputIterator;
172    _outputStream.setOutputIterator(_poi);
173
174    _pii = new PropertyInputIterator;
175    _inputStream.setInputIterator(_pii);
176
177
178    // initialize the type maps
179    #define TYPENAME(A) \
180        _typeToTypeNameMap[osgDB::BaseSerializer::RW_##A] = #A; \
181        _typeNameToTypeMap[#A] = osgDB::BaseSerializer::RW_##A;
182
183    TYPENAME(UNDEFINED)
184    TYPENAME(USER)
185    TYPENAME(OBJECT)
186    TYPENAME(IMAGE)
187    TYPENAME(LIST)
188
189    TYPENAME(BOOL)
190    TYPENAME(CHAR)
191    TYPENAME(UCHAR)
192    TYPENAME(SHORT)
193    TYPENAME(USHORT)
194    TYPENAME(INT)
195    TYPENAME(UINT)
196    TYPENAME(FLOAT)
197    TYPENAME(DOUBLE)
198
199    TYPENAME(VEC2F)
200    TYPENAME(VEC2D)
201    TYPENAME(VEC3F)
202    TYPENAME(VEC3D)
203    TYPENAME(VEC4F)
204    TYPENAME(VEC4D)
205    TYPENAME(QUAT)
206    TYPENAME(PLANE)
207
208    TYPENAME(MATRIXF)
209    TYPENAME(MATRIXD)
210    TYPENAME(MATRIX)
211    TYPENAME(GLENUM)
212    TYPENAME(STRING)
213    TYPENAME(ENUM)
214
215    TYPENAME(VEC2B)
216    TYPENAME(VEC2UB)
217    TYPENAME(VEC2S)
218    TYPENAME(VEC2US)
219    TYPENAME(VEC2I)
220    TYPENAME(VEC2UI)
221
222    TYPENAME(VEC3B)
223    TYPENAME(VEC3UB)
224    TYPENAME(VEC3S)
225    TYPENAME(VEC3US)
226    TYPENAME(VEC3I)
227    TYPENAME(VEC3UI)
228
229    TYPENAME(VEC4B)
230    TYPENAME(VEC4UB)
231    TYPENAME(VEC4S)
232    TYPENAME(VEC4US)
233    TYPENAME(VEC4I)
234    TYPENAME(VEC4UI)
235}
236
237
238bool PropertyInterface::areTypesCompatible(osgDB::BaseSerializer::Type lhs, osgDB::BaseSerializer::Type rhs) const
239{
240    if (lhs==rhs) return true;
241
242#ifdef OSG_USE_FLOAT_MATRIX
243    if (lhs==osgDB::BaseSerializer::RW_MATRIX) lhs = osgDB::BaseSerializer::RW_MATRIXF;
244    if (rhs==osgDB::BaseSerializer::RW_MATRIX) rhs = osgDB::BaseSerializer::RW_MATRIXF;
245#else
246    if (lhs==osgDB::BaseSerializer::RW_MATRIX) lhs = osgDB::BaseSerializer::RW_MATRIXD;
247    if (rhs==osgDB::BaseSerializer::RW_MATRIX) rhs = osgDB::BaseSerializer::RW_MATRIXD;
248#endif
249
250    if (lhs==osgDB::BaseSerializer::RW_GLENUM) lhs = osgDB::BaseSerializer::RW_UINT;
251    if (rhs==osgDB::BaseSerializer::RW_GLENUM) rhs = osgDB::BaseSerializer::RW_UINT;
252
253    if (lhs==osgDB::BaseSerializer::RW_ENUM) lhs = osgDB::BaseSerializer::RW_INT;
254    if (rhs==osgDB::BaseSerializer::RW_ENUM) rhs = osgDB::BaseSerializer::RW_INT;
255
256    return lhs==rhs;
257}
258
259std::string PropertyInterface::getTypeName(osgDB::BaseSerializer::Type type) const
260{
261    TypeToTypeNameMap::const_iterator itr = _typeToTypeNameMap.find(type);
262    if (itr != _typeToTypeNameMap.end()) return itr->second;
263    else return std::string();
264}
265
266osgDB::BaseSerializer::Type PropertyInterface::getType(const std::string& typeName) const
267{
268    TypeNameToTypeMap::const_iterator itr = _typeNameToTypeMap.find(typeName);
269    if (itr != _typeNameToTypeMap.end()) return itr->second;
270    else return osgDB::BaseSerializer::RW_UNDEFINED;
271}
272
273
274osgDB::ObjectWrapper* PropertyInterface::getObjectWrapper(const osg::Object* object) const
275{
276    return osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(object->getCompoundClassName());
277}
278
279osgDB::BaseSerializer* PropertyInterface::getSerializer(const osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type& type) const
280{
281    osgDB::ObjectWrapper* ow = getObjectWrapper(object);
282    return ow ? ow->getSerializer(propertyName, type) : 0;
283}
284
285osg::Object* PropertyInterface::createObject(const std::string& compoundClassName) const
286{
287    osgDB::ObjectWrapper* ow = osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(compoundClassName);
288    return (ow!=0) ? ow->createInstance() : 0;
289}
290
291bool PropertyInterface::copyPropertyDataFromObject(const osg::Object* object, const std::string& propertyName, void* valuePtr, unsigned int valueSize, osgDB::BaseSerializer::Type valueType)
292{
293    _poi->flush();
294
295    osgDB::BaseSerializer::Type sourceType;
296    osgDB::BaseSerializer* serializer = getSerializer(object, propertyName, sourceType);
297    if (!serializer) return false;
298
299    if (!areTypesCompatible(sourceType, valueType))
300    {
301        OSG_NOTICE<<"PropertyInterface::copyPropertyDataFromObject() Types are not compatible, valueType = "<<valueType<<", sourceType="<<sourceType<<std::endl;
302        return false;
303    }
304
305    if (serializer->write(_outputStream, *object))
306    {
307        unsigned int sourceSize = _poi->_str.size();
308
309        if (valueType==osgDB::BaseSerializer::RW_STRING)
310        {
311            std::string* string_ptr = reinterpret_cast<std::string*>(valuePtr);
312            (*string_ptr) = _poi->_str;
313            return true;
314        }
315        else if (sourceSize==valueSize)
316        {
317            memcpy(valuePtr, &(_poi->_str[0]), valueSize);
318            return true;
319        }
320        else
321        {
322            OSG_NOTICE<<"PropertyInterface::copyPropertyDataFromObject() Sizes not compatible, sourceSize = "<<sourceSize<<" valueSize = "<<valueSize<<std::endl;
323            return false;
324        }
325    }
326    else
327    {
328        OSG_NOTICE<<"PropertyInterface::copyPropertyDataFromObject() serializer write failed."<<std::endl;
329        return false;
330    }
331}
332
333bool PropertyInterface::copyPropertyDataToObject(osg::Object* object, const std::string& propertyName, const void* valuePtr, unsigned int valueSize, osgDB::BaseSerializer::Type valueType)
334{
335    // copy data to PropertyInputIterator
336    if (valueType==osgDB::BaseSerializer::RW_STRING)
337    {
338        const std::string* string_ptr = reinterpret_cast<const std::string*>(valuePtr);
339        _pii->set(&((*string_ptr)[0]), string_ptr->size());
340    }
341    else
342    {
343        _pii->set(valuePtr, valueSize);
344    }
345
346    osgDB::BaseSerializer::Type destinationType;
347    osgDB::BaseSerializer* serializer = getSerializer(object, propertyName, destinationType);
348    if (serializer)
349    {
350        if (areTypesCompatible(valueType, destinationType))
351        {
352            return serializer->read(_inputStream, *object);
353        }
354        else
355        {
356            OSG_NOTICE<<"PropertyInterface::copyPropertyDataToObject() Types are not compatible, valueType = "<<valueType<<", destinationType="<<destinationType<<std::endl;
357            return false;
358        }
359    }
360    else
361    {
362        OSG_NOTICE<<"PropertyInterface::copyPropertyDataFromObject() no serializer available."<<std::endl;
363        return false;
364    }
365}
366
367bool PropertyInterface::copyPropertyObjectFromObject(const osg::Object* object, const std::string& propertyName, void* valuePtr, unsigned int valueSize, osgDB::BaseSerializer::Type valueType)
368{
369    osgDB::BaseSerializer::Type sourceType;
370    osgDB::BaseSerializer* serializer = getSerializer(object, propertyName, sourceType);
371    if (serializer)
372    {
373        if (areTypesCompatible(valueType, sourceType))
374        {
375            return serializer->get(*object, valuePtr);
376        }
377        else
378        {
379            OSG_NOTICE<<"PropertyInterface::copyPropertyObjectFromObject() Types are not compatible, valueType = "<<valueType<<", destinationType="<<sourceType<<std::endl;
380            return false;
381        }
382    }
383    else
384    {
385        OSG_NOTICE<<"PropertyInterface::copyPropertyObjectFromObject() no serializer available."<<std::endl;
386        return false;
387    }
388}
389
390bool PropertyInterface::copyPropertyObjectToObject(osg::Object* object, const std::string& propertyName, const void* valuePtr, unsigned int valueSize, osgDB::BaseSerializer::Type valueType)
391{
392    osgDB::BaseSerializer::Type destinationType;
393    osgDB::BaseSerializer* serializer = getSerializer(object, propertyName, destinationType);
394    if (serializer)
395    {
396        if (areTypesCompatible(valueType, destinationType))
397        {
398            return serializer->set(*object, const_cast<void*>(valuePtr));
399        }
400        else
401        {
402            OSG_NOTICE<<"PropertyInterface::copyPropertyObjectToObject() Types are not compatible, valueType = "<<valueType<<", destinationType="<<destinationType<<std::endl;
403            return false;
404        }
405    }
406    else
407    {
408        OSG_NOTICE<<"PropertyInterface::copyPropertyObjectToObject() no serializer available."<<std::endl;
409        return false;
410    }
411}
412
413
414class GetPropertyType : public osg::ValueObject::GetValueVisitor
415{
416public:
417
418    GetPropertyType(): type(osgDB::BaseSerializer::RW_UNDEFINED) {}
419
420    osgDB::BaseSerializer::Type type;
421
422    virtual void apply(bool /*value*/) { type = osgDB::BaseSerializer::RW_BOOL; }
423    virtual void apply(char /*value*/) { type = osgDB::BaseSerializer::RW_CHAR; }
424    virtual void apply(unsigned char /*value*/) { type = osgDB::BaseSerializer::RW_UCHAR; }
425    virtual void apply(short /*value*/) { type = osgDB::BaseSerializer::RW_SHORT; }
426    virtual void apply(unsigned short /*value*/) { type = osgDB::BaseSerializer::RW_USHORT; }
427    virtual void apply(int /*value*/) { type = osgDB::BaseSerializer::RW_INT; }
428    virtual void apply(unsigned int /*value*/) { type = osgDB::BaseSerializer::RW_UINT; }
429    virtual void apply(float /*value*/) { type = osgDB::BaseSerializer::RW_FLOAT; }
430    virtual void apply(double /*value*/) { type = osgDB::BaseSerializer::RW_DOUBLE; }
431    virtual void apply(const std::string& /*value*/) { type = osgDB::BaseSerializer::RW_STRING; }
432    virtual void apply(const osg::Vec2f& /*value*/) { type = osgDB::BaseSerializer::RW_VEC2F; }
433    virtual void apply(const osg::Vec3f& /*value*/) { type = osgDB::BaseSerializer::RW_VEC3F; }
434    virtual void apply(const osg::Vec4f& /*value*/) { type = osgDB::BaseSerializer::RW_VEC4F; }
435    virtual void apply(const osg::Vec2d& /*value*/) { type = osgDB::BaseSerializer::RW_VEC2D; }
436    virtual void apply(const osg::Vec3d& /*value*/) { type = osgDB::BaseSerializer::RW_VEC3D; }
437    virtual void apply(const osg::Vec4d& /*value*/) { type = osgDB::BaseSerializer::RW_VEC4D; }
438    virtual void apply(const osg::Quat& /*value*/) { type = osgDB::BaseSerializer::RW_QUAT; }
439    virtual void apply(const osg::Plane& /*value*/) { type = osgDB::BaseSerializer::RW_PLANE; }
440    virtual void apply(const osg::Matrixf& /*value*/) { type = osgDB::BaseSerializer::RW_MATRIXF; }
441    virtual void apply(const osg::Matrixd& /*value*/) { type = osgDB::BaseSerializer::RW_MATRIXD; }
442};
443
444bool PropertyInterface::getPropertyType(const osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type& type) const
445{
446    if (getSerializer(object, propertyName, type)!=0) return true;
447
448    const osg::UserDataContainer* udc = object->getUserDataContainer();
449    const osg::Object* userObject = udc ? udc->getUserObject(propertyName) : 0;
450    if (userObject)
451    {
452        const osg::ValueObject* valueObject = dynamic_cast<const osg::ValueObject*>(userObject);
453        if (valueObject)
454        {
455            GetPropertyType gpt;
456            valueObject->get(gpt);
457            type = gpt.type;
458            return gpt.type!=osgDB::BaseSerializer::RW_UNDEFINED;
459        }
460    }
461    return false;
462}
463
464
465bool PropertyInterface::getSupportedProperties(const osg::Object* object, PropertyMap& properties, bool searchAssociates) const
466{
467    osgDB::ObjectWrapper* ow = getObjectWrapper(object);
468    if (!ow)
469    {
470        return false;
471    }
472
473    std::string compoundClassName = object->getCompoundClassName();
474    ObjectPropertyMap::const_iterator wl_itr = _whiteList.find(compoundClassName);
475    if (wl_itr != _whiteList.end())
476    {
477        properties = wl_itr->second;
478    }
479
480    ObjectPropertyMap::const_iterator bl_itr = _blackList.find(compoundClassName);
481
482    if (searchAssociates)
483    {
484        const osgDB::StringList& associates = ow->getAssociates();
485        for(osgDB::StringList::const_iterator aitr = associates.begin();
486            aitr != associates.end();
487            ++aitr)
488        {
489            osgDB::ObjectWrapper* associate_wrapper = osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(*aitr);
490            if (associate_wrapper)
491            {
492                const osgDB::ObjectWrapper::SerializerList& associate_serializers = associate_wrapper->getSerializerList();
493                unsigned int i=0;
494                for(osgDB::ObjectWrapper::SerializerList::const_iterator sitr = associate_serializers.begin();
495                    sitr != associate_serializers.end();
496                    ++sitr, ++i)
497                {
498                    const std::string& propertyName = (*sitr)->getName();
499                    bool notBlackListed = (bl_itr == _blackList.end()) || (bl_itr->second.count(propertyName)==0);
500                    if (notBlackListed) properties[propertyName] = associate_wrapper->getTypeList()[i];
501                }
502            }
503        }
504    }
505    else
506    {
507        const osgDB::ObjectWrapper::SerializerList& serializers = ow->getSerializerList();
508        unsigned int i=0;
509        for(osgDB::ObjectWrapper::SerializerList::const_iterator itr = serializers.begin();
510            itr != serializers.end();
511            ++itr)
512        {
513            const std::string& propertyName = (*itr)->getName();
514            bool notBlackListed = (bl_itr == _blackList.end()) || (bl_itr->second.count(propertyName)==0);
515            if (notBlackListed) properties[propertyName] = ow->getTypeList()[i];
516        }
517    }
518
519
520    return true;
521}
522
523
524} // end of osgDB namespace
525
Note: See TracBrowser for help on using the browser.