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

Revision 13850, 19.0 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            OSG_NOTICE<<"Calling get"<<std::endl;
376            return serializer->get(*object, valuePtr);
377        }
378        else
379        {
380            OSG_NOTICE<<"PropertyInterface::copyPropertyObjectFromObject() Types are not compatible, valueType = "<<valueType<<", destinationType="<<sourceType<<std::endl;
381            return false;
382        }
383    }
384    else
385    {
386        OSG_NOTICE<<"PropertyInterface::copyPropertyObjectFromObject() no serializer available."<<std::endl;
387        return false;
388    }
389}
390
391bool PropertyInterface::copyPropertyObjectToObject(osg::Object* object, const std::string& propertyName, const void* valuePtr, unsigned int valueSize, osgDB::BaseSerializer::Type valueType)
392{
393    osgDB::BaseSerializer::Type destinationType;
394    osgDB::BaseSerializer* serializer = getSerializer(object, propertyName, destinationType);
395    if (serializer)
396    {
397        if (areTypesCompatible(valueType, destinationType))
398        {
399            OSG_NOTICE<<"Calling set"<<std::endl;
400            return serializer->set(*object, const_cast<void*>(valuePtr));
401        }
402        else
403        {
404            OSG_NOTICE<<"PropertyInterface::copyPropertyObjectToObject() Types are not compatible, valueType = "<<valueType<<", destinationType="<<destinationType<<std::endl;
405            return false;
406        }
407    }
408    else
409    {
410        OSG_NOTICE<<"PropertyInterface::copyPropertyObjectToObject() no serializer available."<<std::endl;
411        return false;
412    }
413}
414
415
416class GetPropertyType : public osg::ValueObject::GetValueVisitor
417{
418public:
419
420    GetPropertyType(): type(osgDB::BaseSerializer::RW_UNDEFINED) {}
421
422    osgDB::BaseSerializer::Type type;
423
424    virtual void apply(bool /*value*/) { type = osgDB::BaseSerializer::RW_BOOL; }
425    virtual void apply(char /*value*/) { type = osgDB::BaseSerializer::RW_CHAR; }
426    virtual void apply(unsigned char /*value*/) { type = osgDB::BaseSerializer::RW_UCHAR; }
427    virtual void apply(short /*value*/) { type = osgDB::BaseSerializer::RW_SHORT; }
428    virtual void apply(unsigned short /*value*/) { type = osgDB::BaseSerializer::RW_USHORT; }
429    virtual void apply(int /*value*/) { type = osgDB::BaseSerializer::RW_INT; }
430    virtual void apply(unsigned int /*value*/) { type = osgDB::BaseSerializer::RW_UINT; }
431    virtual void apply(float /*value*/) { type = osgDB::BaseSerializer::RW_FLOAT; }
432    virtual void apply(double /*value*/) { type = osgDB::BaseSerializer::RW_DOUBLE; }
433    virtual void apply(const std::string& /*value*/) { type = osgDB::BaseSerializer::RW_STRING; }
434    virtual void apply(const osg::Vec2f& /*value*/) { type = osgDB::BaseSerializer::RW_VEC2F; }
435    virtual void apply(const osg::Vec3f& /*value*/) { type = osgDB::BaseSerializer::RW_VEC3F; }
436    virtual void apply(const osg::Vec4f& /*value*/) { type = osgDB::BaseSerializer::RW_VEC4F; }
437    virtual void apply(const osg::Vec2d& /*value*/) { type = osgDB::BaseSerializer::RW_VEC2D; }
438    virtual void apply(const osg::Vec3d& /*value*/) { type = osgDB::BaseSerializer::RW_VEC3D; }
439    virtual void apply(const osg::Vec4d& /*value*/) { type = osgDB::BaseSerializer::RW_VEC4D; }
440    virtual void apply(const osg::Quat& /*value*/) { type = osgDB::BaseSerializer::RW_QUAT; }
441    virtual void apply(const osg::Plane& /*value*/) { type = osgDB::BaseSerializer::RW_PLANE; }
442    virtual void apply(const osg::Matrixf& /*value*/) { type = osgDB::BaseSerializer::RW_MATRIXF; }
443    virtual void apply(const osg::Matrixd& /*value*/) { type = osgDB::BaseSerializer::RW_MATRIXD; }
444};
445
446bool PropertyInterface::getPropertyType(const osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type& type) const
447{
448    if (getSerializer(object, propertyName, type)!=0) return true;
449
450    const osg::UserDataContainer* udc = object->getUserDataContainer();
451    const osg::Object* userObject = udc ? udc->getUserObject(propertyName) : 0;
452    if (userObject)
453    {
454        const osg::ValueObject* valueObject = dynamic_cast<const osg::ValueObject*>(userObject);
455        if (valueObject)
456        {
457            GetPropertyType gpt;
458            valueObject->get(gpt);
459            type = gpt.type;
460            return gpt.type!=osgDB::BaseSerializer::RW_UNDEFINED;
461        }
462    }
463    return false;
464}
465
466
467bool PropertyInterface::getSupportedProperties(const osg::Object* object, PropertyMap& properties, bool searchAssociates) const
468{
469    osgDB::ObjectWrapper* ow = getObjectWrapper(object);
470    if (!ow)
471    {
472        return false;
473    }
474
475    std::string compoundClassName = object->getCompoundClassName();
476    ObjectPropertyMap::const_iterator wl_itr = _whiteList.find(compoundClassName);
477    if (wl_itr != _whiteList.end())
478    {
479        properties = wl_itr->second;
480    }
481
482    ObjectPropertyMap::const_iterator bl_itr = _blackList.find(compoundClassName);
483
484    if (searchAssociates)
485    {
486        const osgDB::StringList& associates = ow->getAssociates();
487        for(osgDB::StringList::const_iterator aitr = associates.begin();
488            aitr != associates.end();
489            ++aitr)
490        {
491            osgDB::ObjectWrapper* associate_wrapper = osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(*aitr);
492            if (associate_wrapper)
493            {
494                const osgDB::ObjectWrapper::SerializerList& associate_serializers = associate_wrapper->getSerializerList();
495                unsigned int i=0;
496                for(osgDB::ObjectWrapper::SerializerList::const_iterator sitr = associate_serializers.begin();
497                    sitr != associate_serializers.end();
498                    ++sitr, ++i)
499                {
500                    const std::string& propertyName = (*sitr)->getName();
501                    bool notBlackListed = (bl_itr == _blackList.end()) || (bl_itr->second.count(propertyName)==0);
502                    if (notBlackListed) properties[propertyName] = associate_wrapper->getTypeList()[i];
503                }
504            }
505        }
506    }
507    else
508    {
509        const osgDB::ObjectWrapper::SerializerList& serializers = ow->getSerializerList();
510        unsigned int i=0;
511        for(osgDB::ObjectWrapper::SerializerList::const_iterator itr = serializers.begin();
512            itr != serializers.end();
513            ++itr)
514        {
515            const std::string& propertyName = (*itr)->getName();
516            bool notBlackListed = (bl_itr == _blackList.end()) || (bl_itr->second.count(propertyName)==0);
517            if (notBlackListed) properties[propertyName] = ow->getTypeList()[i];
518        }
519    }
520
521
522    return true;
523}
524
525
526} // end of osgDB namespace
527
Note: See TracBrowser for help on using the browser.