rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 ---------------------------------------------------------------------------
|
nuclear@0
|
3 Open Asset Import Library (assimp)
|
nuclear@0
|
4 ---------------------------------------------------------------------------
|
nuclear@0
|
5
|
nuclear@0
|
6 Copyright (c) 2006-2018, assimp team
|
nuclear@0
|
7
|
nuclear@0
|
8
|
nuclear@0
|
9
|
nuclear@0
|
10 All rights reserved.
|
nuclear@0
|
11
|
nuclear@0
|
12 Redistribution and use of this software in source and binary forms,
|
nuclear@0
|
13 with or without modification, are permitted provided that the following
|
nuclear@0
|
14 conditions are met:
|
nuclear@0
|
15
|
nuclear@0
|
16 * Redistributions of source code must retain the above
|
nuclear@0
|
17 copyright notice, this list of conditions and the
|
nuclear@0
|
18 following disclaimer.
|
nuclear@0
|
19
|
nuclear@0
|
20 * Redistributions in binary form must reproduce the above
|
nuclear@0
|
21 copyright notice, this list of conditions and the
|
nuclear@0
|
22 following disclaimer in the documentation and/or other
|
nuclear@0
|
23 materials provided with the distribution.
|
nuclear@0
|
24
|
nuclear@0
|
25 * Neither the name of the assimp team, nor the names of its
|
nuclear@0
|
26 contributors may be used to endorse or promote products
|
nuclear@0
|
27 derived from this software without specific prior
|
nuclear@0
|
28 written permission of the assimp team.
|
nuclear@0
|
29
|
nuclear@0
|
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
nuclear@0
|
31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
nuclear@0
|
32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
nuclear@0
|
33 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
nuclear@0
|
34 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
nuclear@0
|
35 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
nuclear@0
|
36 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
nuclear@0
|
37 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
nuclear@0
|
38 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
nuclear@0
|
39 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
nuclear@0
|
40 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
nuclear@0
|
41 ---------------------------------------------------------------------------
|
nuclear@0
|
42 */
|
nuclear@0
|
43
|
nuclear@0
|
44 /** @file metadata.h
|
nuclear@0
|
45 * @brief Defines the data structures for holding node meta information.
|
nuclear@0
|
46 */
|
nuclear@0
|
47 #pragma once
|
nuclear@0
|
48 #ifndef AI_METADATA_H_INC
|
nuclear@0
|
49 #define AI_METADATA_H_INC
|
nuclear@0
|
50
|
nuclear@0
|
51 #if defined(_MSC_VER) && (_MSC_VER <= 1500)
|
nuclear@0
|
52 # include "Compiler/pstdint.h"
|
nuclear@0
|
53 #else
|
nuclear@0
|
54 # include <inttypes.h>
|
nuclear@0
|
55 #endif
|
nuclear@0
|
56
|
nuclear@0
|
57 // -------------------------------------------------------------------------------
|
nuclear@0
|
58 /**
|
nuclear@0
|
59 * Enum used to distinguish data types
|
nuclear@0
|
60 */
|
nuclear@0
|
61 // -------------------------------------------------------------------------------
|
nuclear@0
|
62 typedef enum aiMetadataType {
|
nuclear@0
|
63 AI_BOOL = 0,
|
nuclear@0
|
64 AI_INT32 = 1,
|
nuclear@0
|
65 AI_UINT64 = 2,
|
nuclear@0
|
66 AI_FLOAT = 3,
|
nuclear@0
|
67 AI_DOUBLE = 4,
|
nuclear@0
|
68 AI_AISTRING = 5,
|
nuclear@0
|
69 AI_AIVECTOR3D = 6,
|
nuclear@0
|
70 AI_META_MAX = 7,
|
nuclear@0
|
71
|
nuclear@0
|
72 #ifndef SWIG
|
nuclear@0
|
73 FORCE_32BIT = INT_MAX
|
nuclear@0
|
74 #endif
|
nuclear@0
|
75 } aiMetadataType;
|
nuclear@0
|
76
|
nuclear@0
|
77 // -------------------------------------------------------------------------------
|
nuclear@0
|
78 /**
|
nuclear@0
|
79 * Metadata entry
|
nuclear@0
|
80 *
|
nuclear@0
|
81 * The type field uniquely identifies the underlying type of the data field
|
nuclear@0
|
82 */
|
nuclear@0
|
83 // -------------------------------------------------------------------------------
|
nuclear@0
|
84 struct aiMetadataEntry {
|
nuclear@0
|
85 aiMetadataType mType;
|
nuclear@0
|
86 void* mData;
|
nuclear@0
|
87 };
|
nuclear@0
|
88
|
nuclear@0
|
89 #ifdef __cplusplus
|
nuclear@0
|
90
|
nuclear@0
|
91 #include <string>
|
nuclear@0
|
92
|
nuclear@0
|
93 // -------------------------------------------------------------------------------
|
nuclear@0
|
94 /**
|
nuclear@0
|
95 * Helper functions to get the aiType enum entry for a type
|
nuclear@0
|
96 */
|
nuclear@0
|
97 // -------------------------------------------------------------------------------
|
nuclear@0
|
98
|
nuclear@0
|
99 inline aiMetadataType GetAiType( bool ) { return AI_BOOL; }
|
nuclear@0
|
100 inline aiMetadataType GetAiType( int32_t ) { return AI_INT32; }
|
nuclear@0
|
101 inline aiMetadataType GetAiType( uint64_t ) { return AI_UINT64; }
|
nuclear@0
|
102 inline aiMetadataType GetAiType( float ) { return AI_FLOAT; }
|
nuclear@0
|
103 inline aiMetadataType GetAiType( double ) { return AI_DOUBLE; }
|
nuclear@0
|
104 inline aiMetadataType GetAiType( const aiString & ) { return AI_AISTRING; }
|
nuclear@0
|
105 inline aiMetadataType GetAiType( const aiVector3D & ) { return AI_AIVECTOR3D; }
|
nuclear@0
|
106
|
nuclear@0
|
107 #endif // __cplusplus
|
nuclear@0
|
108
|
nuclear@0
|
109 // -------------------------------------------------------------------------------
|
nuclear@0
|
110 /**
|
nuclear@0
|
111 * Container for holding metadata.
|
nuclear@0
|
112 *
|
nuclear@0
|
113 * Metadata is a key-value store using string keys and values.
|
nuclear@0
|
114 */
|
nuclear@0
|
115 // -------------------------------------------------------------------------------
|
nuclear@0
|
116 struct aiMetadata {
|
nuclear@0
|
117 /** Length of the mKeys and mValues arrays, respectively */
|
nuclear@0
|
118 unsigned int mNumProperties;
|
nuclear@0
|
119
|
nuclear@0
|
120 /** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */
|
nuclear@0
|
121 C_STRUCT aiString* mKeys;
|
nuclear@0
|
122
|
nuclear@0
|
123 /** Arrays of values, may not be NULL. Entries in this array may be NULL if the
|
nuclear@0
|
124 * corresponding property key has no assigned value. */
|
nuclear@0
|
125 C_STRUCT aiMetadataEntry* mValues;
|
nuclear@0
|
126
|
nuclear@0
|
127 #ifdef __cplusplus
|
nuclear@0
|
128
|
nuclear@0
|
129 /**
|
nuclear@0
|
130 * @brief The default constructor, set all members to zero by default.
|
nuclear@0
|
131 */
|
nuclear@0
|
132 aiMetadata() AI_NO_EXCEPT
|
nuclear@0
|
133 : mNumProperties(0)
|
nuclear@0
|
134 , mKeys(0)
|
nuclear@0
|
135 , mValues(0) {
|
nuclear@0
|
136 // empty
|
nuclear@0
|
137 }
|
nuclear@0
|
138
|
nuclear@0
|
139 aiMetadata( const aiMetadata &rhs )
|
nuclear@0
|
140 : mNumProperties( rhs.mNumProperties )
|
nuclear@0
|
141 , mKeys( 0 )
|
nuclear@0
|
142 , mValues( 0 ) {
|
nuclear@0
|
143 mKeys = new aiString[ mNumProperties ];
|
nuclear@0
|
144 for ( size_t i = 0; i < static_cast<size_t>( mNumProperties ); ++i ) {
|
nuclear@0
|
145 mKeys[ i ] = rhs.mKeys[ i ];
|
nuclear@0
|
146 }
|
nuclear@0
|
147 mValues = new aiMetadataEntry[ mNumProperties ];
|
nuclear@0
|
148 for ( size_t i = 0; i < static_cast<size_t>(mNumProperties); ++i ) {
|
nuclear@0
|
149 mValues[ i ].mType = rhs.mValues[ i ].mType;
|
nuclear@0
|
150 switch ( rhs.mValues[ i ].mType ) {
|
nuclear@0
|
151 case AI_BOOL:
|
nuclear@0
|
152 mValues[ i ].mData = new bool;
|
nuclear@0
|
153 ::memcpy( mValues[ i ].mData, rhs.mValues[ i ].mData, sizeof(bool) );
|
nuclear@0
|
154 break;
|
nuclear@0
|
155 case AI_INT32: {
|
nuclear@0
|
156 int32_t v;
|
nuclear@0
|
157 ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( int32_t ) );
|
nuclear@0
|
158 mValues[ i ].mData = new int32_t( v );
|
nuclear@0
|
159 }
|
nuclear@0
|
160 break;
|
nuclear@0
|
161 case AI_UINT64: {
|
nuclear@0
|
162 uint64_t v;
|
nuclear@0
|
163 ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( uint64_t ) );
|
nuclear@0
|
164 mValues[ i ].mData = new uint64_t( v );
|
nuclear@0
|
165 }
|
nuclear@0
|
166 break;
|
nuclear@0
|
167 case AI_FLOAT: {
|
nuclear@0
|
168 float v;
|
nuclear@0
|
169 ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( float ) );
|
nuclear@0
|
170 mValues[ i ].mData = new float( v );
|
nuclear@0
|
171 }
|
nuclear@0
|
172 break;
|
nuclear@0
|
173 case AI_DOUBLE: {
|
nuclear@0
|
174 double v;
|
nuclear@0
|
175 ::memcpy( &v, rhs.mValues[ i ].mData, sizeof( double ) );
|
nuclear@0
|
176 mValues[ i ].mData = new double( v );
|
nuclear@0
|
177 }
|
nuclear@0
|
178 break;
|
nuclear@0
|
179 case AI_AISTRING: {
|
nuclear@0
|
180 aiString v;
|
nuclear@0
|
181 rhs.Get<aiString>( mKeys[ i ], v );
|
nuclear@0
|
182 mValues[ i ].mData = new aiString( v );
|
nuclear@0
|
183 }
|
nuclear@0
|
184 break;
|
nuclear@0
|
185 case AI_AIVECTOR3D: {
|
nuclear@0
|
186 aiVector3D v;
|
nuclear@0
|
187 rhs.Get<aiVector3D>( mKeys[ i ], v );
|
nuclear@0
|
188 mValues[ i ].mData = new aiVector3D( v );
|
nuclear@0
|
189 }
|
nuclear@0
|
190 break;
|
nuclear@0
|
191 #ifndef SWIG
|
nuclear@0
|
192 case FORCE_32BIT:
|
nuclear@0
|
193 #endif
|
nuclear@0
|
194 default:
|
nuclear@0
|
195 break;
|
nuclear@0
|
196 }
|
nuclear@0
|
197
|
nuclear@0
|
198 }
|
nuclear@0
|
199 }
|
nuclear@0
|
200
|
nuclear@0
|
201 /**
|
nuclear@0
|
202 * @brief The destructor.
|
nuclear@0
|
203 */
|
nuclear@0
|
204 ~aiMetadata() {
|
nuclear@0
|
205 delete [] mKeys;
|
nuclear@0
|
206 mKeys = 0;
|
nuclear@0
|
207 if (mValues) {
|
nuclear@0
|
208 // Delete each metadata entry
|
nuclear@0
|
209 for (unsigned i=0; i<mNumProperties; ++i) {
|
nuclear@0
|
210 void* data = mValues[i].mData;
|
nuclear@0
|
211 switch (mValues[i].mType) {
|
nuclear@0
|
212 case AI_BOOL:
|
nuclear@0
|
213 delete static_cast< bool* >( data );
|
nuclear@0
|
214 break;
|
nuclear@0
|
215 case AI_INT32:
|
nuclear@0
|
216 delete static_cast< int32_t* >( data );
|
nuclear@0
|
217 break;
|
nuclear@0
|
218 case AI_UINT64:
|
nuclear@0
|
219 delete static_cast< uint64_t* >( data );
|
nuclear@0
|
220 break;
|
nuclear@0
|
221 case AI_FLOAT:
|
nuclear@0
|
222 delete static_cast< float* >( data );
|
nuclear@0
|
223 break;
|
nuclear@0
|
224 case AI_DOUBLE:
|
nuclear@0
|
225 delete static_cast< double* >( data );
|
nuclear@0
|
226 break;
|
nuclear@0
|
227 case AI_AISTRING:
|
nuclear@0
|
228 delete static_cast< aiString* >( data );
|
nuclear@0
|
229 break;
|
nuclear@0
|
230 case AI_AIVECTOR3D:
|
nuclear@0
|
231 delete static_cast< aiVector3D* >( data );
|
nuclear@0
|
232 break;
|
nuclear@0
|
233 #ifndef SWIG
|
nuclear@0
|
234 case FORCE_32BIT:
|
nuclear@0
|
235 #endif
|
nuclear@0
|
236 default:
|
nuclear@0
|
237 break;
|
nuclear@0
|
238 }
|
nuclear@0
|
239 }
|
nuclear@0
|
240
|
nuclear@0
|
241 // Delete the metadata array
|
nuclear@0
|
242 delete [] mValues;
|
nuclear@0
|
243 mValues = 0;
|
nuclear@0
|
244 }
|
nuclear@0
|
245 }
|
nuclear@0
|
246
|
nuclear@0
|
247 /**
|
nuclear@0
|
248 * @brief Allocates property fields + keys.
|
nuclear@0
|
249 * @param numProperties Number of requested properties.
|
nuclear@0
|
250 */
|
nuclear@0
|
251 static inline
|
nuclear@0
|
252 aiMetadata *Alloc( unsigned int numProperties ) {
|
nuclear@0
|
253 if ( 0 == numProperties ) {
|
nuclear@0
|
254 return 0;
|
nuclear@0
|
255 }
|
nuclear@0
|
256
|
nuclear@0
|
257 aiMetadata *data = new aiMetadata;
|
nuclear@0
|
258 data->mNumProperties = numProperties;
|
nuclear@0
|
259 data->mKeys = new aiString[ data->mNumProperties ]();
|
nuclear@0
|
260 data->mValues = new aiMetadataEntry[ data->mNumProperties ]();
|
nuclear@0
|
261
|
nuclear@0
|
262 return data;
|
nuclear@0
|
263 }
|
nuclear@0
|
264
|
nuclear@0
|
265 /**
|
nuclear@0
|
266 * @brief Deallocates property fields + keys.
|
nuclear@0
|
267 */
|
nuclear@0
|
268 static inline
|
nuclear@0
|
269 void Dealloc( aiMetadata *metadata ) {
|
nuclear@0
|
270 delete metadata;
|
nuclear@0
|
271 }
|
nuclear@0
|
272
|
nuclear@0
|
273 template<typename T>
|
nuclear@0
|
274 inline
|
nuclear@0
|
275 void Add(const std::string& key, const T& value) {
|
nuclear@0
|
276 aiString* new_keys = new aiString[mNumProperties + 1];
|
nuclear@0
|
277 aiMetadataEntry* new_values = new aiMetadataEntry[mNumProperties + 1];
|
nuclear@0
|
278
|
nuclear@0
|
279 for(unsigned int i = 0; i < mNumProperties; ++i)
|
nuclear@0
|
280 {
|
nuclear@0
|
281 new_keys[i] = mKeys[i];
|
nuclear@0
|
282 new_values[i] = mValues[i];
|
nuclear@0
|
283 }
|
nuclear@0
|
284
|
nuclear@0
|
285 delete mKeys;
|
nuclear@0
|
286 delete mValues;
|
nuclear@0
|
287
|
nuclear@0
|
288 mKeys = new_keys;
|
nuclear@0
|
289 mValues = new_values;
|
nuclear@0
|
290
|
nuclear@0
|
291 mNumProperties++;
|
nuclear@0
|
292
|
nuclear@0
|
293 Set(mNumProperties - 1, key, value);
|
nuclear@0
|
294 }
|
nuclear@0
|
295
|
nuclear@0
|
296 template<typename T>
|
nuclear@0
|
297 inline
|
nuclear@0
|
298 bool Set( unsigned index, const std::string& key, const T& value ) {
|
nuclear@0
|
299 // In range assertion
|
nuclear@0
|
300 if ( index >= mNumProperties ) {
|
nuclear@0
|
301 return false;
|
nuclear@0
|
302 }
|
nuclear@0
|
303
|
nuclear@0
|
304 // Ensure that we have a valid key.
|
nuclear@0
|
305 if ( key.empty() ) {
|
nuclear@0
|
306 return false;
|
nuclear@0
|
307 }
|
nuclear@0
|
308
|
nuclear@0
|
309 // Set metadata key
|
nuclear@0
|
310 mKeys[index] = key;
|
nuclear@0
|
311
|
nuclear@0
|
312 // Set metadata type
|
nuclear@0
|
313 mValues[index].mType = GetAiType(value);
|
nuclear@0
|
314 // Copy the given value to the dynamic storage
|
nuclear@0
|
315 mValues[index].mData = new T(value);
|
nuclear@0
|
316
|
nuclear@0
|
317 return true;
|
nuclear@0
|
318 }
|
nuclear@0
|
319
|
nuclear@0
|
320 template<typename T>
|
nuclear@0
|
321 inline
|
nuclear@0
|
322 bool Get( unsigned index, T& value ) const {
|
nuclear@0
|
323 // In range assertion
|
nuclear@0
|
324 if ( index >= mNumProperties ) {
|
nuclear@0
|
325 return false;
|
nuclear@0
|
326 }
|
nuclear@0
|
327
|
nuclear@0
|
328 // Return false if the output data type does
|
nuclear@0
|
329 // not match the found value's data type
|
nuclear@0
|
330 if ( GetAiType( value ) != mValues[ index ].mType ) {
|
nuclear@0
|
331 return false;
|
nuclear@0
|
332 }
|
nuclear@0
|
333
|
nuclear@0
|
334 // Otherwise, output the found value and
|
nuclear@0
|
335 // return true
|
nuclear@0
|
336 value = *static_cast<T*>(mValues[index].mData);
|
nuclear@0
|
337
|
nuclear@0
|
338 return true;
|
nuclear@0
|
339 }
|
nuclear@0
|
340
|
nuclear@0
|
341 template<typename T>
|
nuclear@0
|
342 inline
|
nuclear@0
|
343 bool Get( const aiString& key, T& value ) const {
|
nuclear@0
|
344 // Search for the given key
|
nuclear@0
|
345 for ( unsigned int i = 0; i < mNumProperties; ++i ) {
|
nuclear@0
|
346 if ( mKeys[ i ] == key ) {
|
nuclear@0
|
347 return Get( i, value );
|
nuclear@0
|
348 }
|
nuclear@0
|
349 }
|
nuclear@0
|
350 return false;
|
nuclear@0
|
351 }
|
nuclear@0
|
352
|
nuclear@0
|
353 template<typename T>
|
nuclear@0
|
354 inline
|
nuclear@0
|
355 bool Get( const std::string& key, T& value ) const {
|
nuclear@0
|
356 return Get(aiString(key), value);
|
nuclear@0
|
357 }
|
nuclear@0
|
358
|
nuclear@0
|
359 /// Return metadata entry for analyzing it by user.
|
nuclear@0
|
360 /// \param [in] pIndex - index of the entry.
|
nuclear@0
|
361 /// \param [out] pKey - pointer to the key value.
|
nuclear@0
|
362 /// \param [out] pEntry - pointer to the entry: type and value.
|
nuclear@0
|
363 /// \return false - if pIndex is out of range, else - true.
|
nuclear@0
|
364 inline
|
nuclear@0
|
365 bool Get(size_t index, const aiString*& key, const aiMetadataEntry*& entry) const {
|
nuclear@0
|
366 if ( index >= mNumProperties ) {
|
nuclear@0
|
367 return false;
|
nuclear@0
|
368 }
|
nuclear@0
|
369
|
nuclear@0
|
370 key = &mKeys[index];
|
nuclear@0
|
371 entry = &mValues[index];
|
nuclear@0
|
372
|
nuclear@0
|
373 return true;
|
nuclear@0
|
374 }
|
nuclear@0
|
375
|
nuclear@0
|
376 #endif // __cplusplus
|
nuclear@0
|
377
|
nuclear@0
|
378 };
|
nuclear@0
|
379
|
nuclear@0
|
380 #endif // AI_METADATA_H_INC
|