Path Tracer
metadata.h
Go to the documentation of this file.
1 /*
2 ---------------------------------------------------------------------------
3 Open Asset Import Library (assimp)
4 ---------------------------------------------------------------------------
5 
6 Copyright (c) 2006-2020, assimp team
7 
8 All rights reserved.
9 
10 Redistribution and use of this software in source and binary forms,
11 with or without modification, are permitted provided that the following
12 conditions are met:
13 
14 * Redistributions of source code must retain the above
15  copyright notice, this list of conditions and the
16  following disclaimer.
17 
18 * Redistributions in binary form must reproduce the above
19  copyright notice, this list of conditions and the
20  following disclaimer in the documentation and/or other
21  materials provided with the distribution.
22 
23 * Neither the name of the assimp team, nor the names of its
24  contributors may be used to endorse or promote products
25  derived from this software without specific prior
26  written permission of the assimp team.
27 
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 ---------------------------------------------------------------------------
40 */
41 
45 #pragma once
46 #ifndef AI_METADATA_H_INC
47 #define AI_METADATA_H_INC
48 
49 #ifdef __GNUC__
50 #pragma GCC system_header
51 #endif
52 
53 #if defined(_MSC_VER) && (_MSC_VER <= 1500)
54 #include "Compiler/pstdint.h"
55 #else
56 #include <stdint.h>
57 #endif
58 
59 // -------------------------------------------------------------------------------
63 // -------------------------------------------------------------------------------
64 typedef enum aiMetadataType {
65  AI_BOOL = 0,
66  AI_INT32 = 1,
67  AI_UINT64 = 2,
68  AI_FLOAT = 3,
69  AI_DOUBLE = 4,
70  AI_AISTRING = 5,
71  AI_AIVECTOR3D = 6,
72  AI_AIMETADATA = 7,
73  AI_META_MAX = 8,
74 
75 #ifndef SWIG
76  FORCE_32BIT = INT_MAX
77 #endif
79 
80 // -------------------------------------------------------------------------------
86 // -------------------------------------------------------------------------------
88  aiMetadataType mType;
89  void *mData;
90 
91 #ifdef __cplusplus
92  aiMetadataEntry() :
93  mType(AI_META_MAX),
94  mData( nullptr ) {
95  // empty
96  }
97 #endif
98 };
99 
100 #ifdef __cplusplus
101 
102 #include <string>
103 
104 struct aiMetadata;
105 
106 // -------------------------------------------------------------------------------
110 // -------------------------------------------------------------------------------
111 
112 inline aiMetadataType GetAiType(bool) {
113  return AI_BOOL;
114 }
115 inline aiMetadataType GetAiType(int32_t) {
116  return AI_INT32;
117 }
118 inline aiMetadataType GetAiType(uint64_t) {
119  return AI_UINT64;
120 }
121 inline aiMetadataType GetAiType(float) {
122  return AI_FLOAT;
123 }
124 inline aiMetadataType GetAiType(double) {
125  return AI_DOUBLE;
126 }
127 inline aiMetadataType GetAiType(const aiString &) {
128  return AI_AISTRING;
129 }
130 inline aiMetadataType GetAiType(const aiVector3D &) {
131  return AI_AIVECTOR3D;
132 }
133 inline aiMetadataType GetAiType(const aiMetadata &) {
134  return AI_AIMETADATA;
135 }
136 
137 #endif // __cplusplus
138 
139 // -------------------------------------------------------------------------------
145 // -------------------------------------------------------------------------------
146 struct aiMetadata {
148  unsigned int mNumProperties;
149 
151  C_STRUCT aiString *mKeys;
152 
156 
157 #ifdef __cplusplus
158 
162  aiMetadata() AI_NO_EXCEPT
163  : mNumProperties(0),
164  mKeys(nullptr),
165  mValues(nullptr) {
166  // empty
167  }
168 
169  aiMetadata(const aiMetadata &rhs) :
170  mNumProperties(rhs.mNumProperties), mKeys(nullptr), mValues(nullptr) {
172  for (size_t i = 0; i < static_cast<size_t>(mNumProperties); ++i) {
173  mKeys[i] = rhs.mKeys[i];
174  }
176  for (size_t i = 0; i < static_cast<size_t>(mNumProperties); ++i) {
177  mValues[i].mType = rhs.mValues[i].mType;
178  switch (rhs.mValues[i].mType) {
179  case AI_BOOL:
180  mValues[i].mData = new bool;
181  ::memcpy(mValues[i].mData, rhs.mValues[i].mData, sizeof(bool));
182  break;
183  case AI_INT32: {
184  int32_t v;
185  ::memcpy(&v, rhs.mValues[i].mData, sizeof(int32_t));
186  mValues[i].mData = new int32_t(v);
187  } break;
188  case AI_UINT64: {
189  uint64_t v;
190  ::memcpy(&v, rhs.mValues[i].mData, sizeof(uint64_t));
191  mValues[i].mData = new uint64_t(v);
192  } break;
193  case AI_FLOAT: {
194  float v;
195  ::memcpy(&v, rhs.mValues[i].mData, sizeof(float));
196  mValues[i].mData = new float(v);
197  } break;
198  case AI_DOUBLE: {
199  double v;
200  ::memcpy(&v, rhs.mValues[i].mData, sizeof(double));
201  mValues[i].mData = new double(v);
202  } break;
203  case AI_AISTRING: {
204  aiString v;
205  rhs.Get<aiString>(mKeys[i], v);
206  mValues[i].mData = new aiString(v);
207  } break;
208  case AI_AIVECTOR3D: {
209  aiVector3D v;
210  rhs.Get<aiVector3D>(mKeys[i], v);
211  mValues[i].mData = new aiVector3D(v);
212  } break;
213  case AI_AIMETADATA: {
214  aiMetadata v;
215  rhs.Get<aiMetadata>(mKeys[i], v);
216  mValues[i].mData = new aiMetadata(v);
217  } break;
218 #ifndef SWIG
219  case FORCE_32BIT:
220 #endif
221  default:
222  break;
223  }
224  }
225  }
226 
227  aiMetadata &operator=(aiMetadata rhs) {
228  using std::swap;
229  swap(mNumProperties, rhs.mNumProperties);
230  swap(mKeys, rhs.mKeys);
231  swap(mValues, rhs.mValues);
232  return *this;
233  }
234 
238  ~aiMetadata() {
239  delete[] mKeys;
240  mKeys = nullptr;
241  if (mValues) {
242  // Delete each metadata entry
243  for (unsigned i = 0; i < mNumProperties; ++i) {
244  void *data = mValues[i].mData;
245  switch (mValues[i].mType) {
246  case AI_BOOL:
247  delete static_cast<bool *>(data);
248  break;
249  case AI_INT32:
250  delete static_cast<int32_t *>(data);
251  break;
252  case AI_UINT64:
253  delete static_cast<uint64_t *>(data);
254  break;
255  case AI_FLOAT:
256  delete static_cast<float *>(data);
257  break;
258  case AI_DOUBLE:
259  delete static_cast<double *>(data);
260  break;
261  case AI_AISTRING:
262  delete static_cast<aiString *>(data);
263  break;
264  case AI_AIVECTOR3D:
265  delete static_cast<aiVector3D *>(data);
266  break;
267  case AI_AIMETADATA:
268  delete static_cast<aiMetadata *>(data);
269  break;
270 #ifndef SWIG
271  case FORCE_32BIT:
272 #endif
273  default:
274  break;
275  }
276  }
277 
278  // Delete the metadata array
279  delete[] mValues;
280  mValues = nullptr;
281  }
282  }
283 
288  static inline aiMetadata *Alloc(unsigned int numProperties) {
289  if (0 == numProperties) {
290  return nullptr;
291  }
292 
293  aiMetadata *data = new aiMetadata;
294  data->mNumProperties = numProperties;
295  data->mKeys = new aiString[data->mNumProperties]();
296  data->mValues = new aiMetadataEntry[data->mNumProperties]();
297 
298  return data;
299  }
300 
304  static inline void Dealloc(aiMetadata *metadata) {
305  delete metadata;
306  }
307 
308  template <typename T>
309  inline void Add(const std::string &key, const T &value) {
310  aiString *new_keys = new aiString[mNumProperties + 1];
311  aiMetadataEntry *new_values = new aiMetadataEntry[mNumProperties + 1];
312 
313  for (unsigned int i = 0; i < mNumProperties; ++i) {
314  new_keys[i] = mKeys[i];
315  new_values[i] = mValues[i];
316  }
317 
318  delete[] mKeys;
319  delete[] mValues;
320 
321  mKeys = new_keys;
322  mValues = new_values;
323 
324  mNumProperties++;
325 
326  Set(mNumProperties - 1, key, value);
327  }
328 
329  template <typename T>
330  inline bool Set(unsigned index, const std::string &key, const T &value) {
331  // In range assertion
332  if (index >= mNumProperties) {
333  return false;
334  }
335 
336  // Ensure that we have a valid key.
337  if (key.empty()) {
338  return false;
339  }
340 
341  // Set metadata key
342  mKeys[index] = key;
343 
344  // Set metadata type
345  mValues[index].mType = GetAiType(value);
346 
347  // Copy the given value to the dynamic storage
348  if (nullptr != mValues[index].mData && AI_AIMETADATA != mValues[index].mType) {
349  ::memcpy(mValues[index].mData, &value, sizeof(T));
350  } else if (nullptr != mValues[index].mData && AI_AIMETADATA == mValues[index].mType) {
351  *static_cast<T *>(mValues[index].mData) = value;
352  } else {
353  mValues[index].mData = new T(value);
354  }
355 
356  return true;
357  }
358 
359  template <typename T>
360  inline bool Set(const std::string &key, const T &value) {
361  if (key.empty()) {
362  return false;
363  }
364 
365  bool result = false;
366  for (unsigned int i = 0; i < mNumProperties; ++i) {
367  if (key == mKeys[i].C_Str()) {
368  Set(i, key, value);
369  result = true;
370  break;
371  }
372  }
373 
374  return result;
375  }
376 
377  template <typename T>
378  inline bool Get(unsigned index, T &value) const {
379  // In range assertion
380  if (index >= mNumProperties) {
381  return false;
382  }
383 
384  // Return false if the output data type does
385  // not match the found value's data type
386  if (GetAiType(value) != mValues[index].mType) {
387  return false;
388  }
389 
390  // Otherwise, output the found value and
391  // return true
392  value = *static_cast<T *>(mValues[index].mData);
393 
394  return true;
395  }
396 
397  template <typename T>
398  inline bool Get(const aiString &key, T &value) const {
399  // Search for the given key
400  for (unsigned int i = 0; i < mNumProperties; ++i) {
401  if (mKeys[i] == key) {
402  return Get(i, value);
403  }
404  }
405  return false;
406  }
407 
408  template <typename T>
409  inline bool Get(const std::string &key, T &value) const {
410  return Get(aiString(key), value);
411  }
412 
418  inline bool Get(size_t index, const aiString *&key, const aiMetadataEntry *&entry) const {
419  if (index >= mNumProperties) {
420  return false;
421  }
422 
423  key = &mKeys[index];
424  entry = &mValues[index];
425 
426  return true;
427  }
428 
431  inline bool HasKey(const char *key) {
432  if (nullptr == key) {
433  return false;
434  }
435 
436  // Search for the given key
437  for (unsigned int i = 0; i < mNumProperties; ++i) {
438  if (0 == strncmp(mKeys[i].C_Str(), key, mKeys[i].length)) {
439  return true;
440  }
441  }
442  return false;
443  }
444 
445  friend bool CompareKeys(const aiMetadata &lhs, const aiMetadata &rhs) {
446  if (lhs.mNumProperties != rhs.mNumProperties) {
447  return false;
448  }
449 
450  for (unsigned int i = 0; i < lhs.mNumProperties; ++i) {
451  if (lhs.mKeys[i] != rhs.mKeys[i]) {
452  return false;
453  }
454  }
455  return true;
456  }
457 
458  friend bool CompareValues(const aiMetadata &lhs, const aiMetadata &rhs) {
459  if (lhs.mNumProperties != rhs.mNumProperties) {
460  return false;
461  }
462 
463  for (unsigned int i = 0; i < lhs.mNumProperties; ++i) {
464  if (lhs.mValues[i].mType != rhs.mValues[i].mType) {
465  return false;
466  }
467 
468  switch (lhs.mValues[i].mType) {
469  case AI_BOOL: {
470  if (*static_cast<bool *>(lhs.mValues[i].mData) != *static_cast<bool *>(rhs.mValues[i].mData)) {
471  return false;
472  }
473  } break;
474  case AI_INT32: {
475  if (*static_cast<int32_t *>(lhs.mValues[i].mData) != *static_cast<int32_t *>(rhs.mValues[i].mData)) {
476  return false;
477  }
478  } break;
479  case AI_UINT64: {
480  if (*static_cast<uint64_t *>(lhs.mValues[i].mData) != *static_cast<uint64_t *>(rhs.mValues[i].mData)) {
481  return false;
482  }
483  } break;
484  case AI_FLOAT: {
485  if (*static_cast<float *>(lhs.mValues[i].mData) != *static_cast<float *>(rhs.mValues[i].mData)) {
486  return false;
487  }
488  } break;
489  case AI_DOUBLE: {
490  if (*static_cast<double *>(lhs.mValues[i].mData) != *static_cast<double *>(rhs.mValues[i].mData)) {
491  return false;
492  }
493  } break;
494  case AI_AISTRING: {
495  if (*static_cast<aiString *>(lhs.mValues[i].mData) != *static_cast<aiString *>(rhs.mValues[i].mData)) {
496  return false;
497  }
498  } break;
499  case AI_AIVECTOR3D: {
500  if (*static_cast<aiVector3D *>(lhs.mValues[i].mData) != *static_cast<aiVector3D *>(rhs.mValues[i].mData)) {
501  return false;
502  }
503  } break;
504  case AI_AIMETADATA: {
505  if (*static_cast<aiMetadata *>(lhs.mValues[i].mData) != *static_cast<aiMetadata *>(rhs.mValues[i].mData)) {
506  return false;
507  }
508  } break;
509 #ifndef SWIG
510  case FORCE_32BIT:
511 #endif
512  default:
513  break;
514  }
515  }
516 
517  return true;
518  }
519 
520  friend bool operator==(const aiMetadata &lhs, const aiMetadata &rhs) {
521  return CompareKeys(lhs, rhs) && CompareValues(lhs, rhs);
522  }
523 
524  friend bool operator!=(const aiMetadata &lhs, const aiMetadata &rhs) {
525  return !(lhs == rhs);
526  }
527 
528 #endif // __cplusplus
529 };
530 
531 #endif // AI_METADATA_H_INC
aiMetadataType
aiMetadataType
Definition: metadata.h:64
aiVector3D
Definition: vector3.h:136
aiMetadata::mValues
C_STRUCT aiMetadataEntry * mValues
Definition: metadata.h:155
aiMetadataEntry
Definition: metadata.h:87
aiString
Definition: types.h:266
nlohmann::detail::parse_event_t::object_start
@ object_start
the parser read { and started to process a JSON object
aiMetadata::mKeys
C_STRUCT aiString * mKeys
Definition: metadata.h:151
aiMetadata
Definition: metadata.h:146
aiMetadata::mNumProperties
unsigned int mNumProperties
Definition: metadata.h:148