diff options
Diffstat (limited to 'src/3rdparty/assimp/code/BlenderDNA.h')
-rw-r--r-- | src/3rdparty/assimp/code/BlenderDNA.h | 933 |
1 files changed, 469 insertions, 464 deletions
diff --git a/src/3rdparty/assimp/code/BlenderDNA.h b/src/3rdparty/assimp/code/BlenderDNA.h index c52eb28a3..801d68fce 100644 --- a/src/3rdparty/assimp/code/BlenderDNA.h +++ b/src/3rdparty/assimp/code/BlenderDNA.h @@ -2,11 +2,11 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2012, assimp team +Copyright (c) 2006-2016, assimp team All rights reserved. -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above @@ -23,23 +23,23 @@ following conditions are met: derived from this software without specific prior written permission of the assimp team. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ /** @file BlenderDNA.h - * @brief Blender `DNA` (file format specification embedded in + * @brief Blender `DNA` (file format specification embedded in * blend file itself) loader. */ #ifndef INCLUDED_AI_BLEND_DNA_H @@ -47,24 +47,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "BaseImporter.h" #include "TinyFormatter.h" +#include "StreamReader.h" +#include <assimp/DefaultLogger.hpp> +#include <stdint.h> +#include <memory> + // enable verbose log output. really verbose, so be careful. #ifdef ASSIMP_BUILD_DEBUG -# define ASSIMP_BUILD_BLENDER_DEBUG +# define ASSIMP_BUILD_BLENDER_DEBUG #endif // #define ASSIMP_BUILD_BLENDER_NO_STATS -namespace Assimp { - template <bool,bool> class StreamReader; - typedef StreamReader<true,true> StreamReaderAny; +namespace Assimp { + template <bool,bool> class StreamReader; + typedef StreamReader<true,true> StreamReaderAny; - namespace Blender { - class FileDatabase; - struct FileBlockHead; + namespace Blender { + class FileDatabase; + struct FileBlockHead; - template <template <typename> class TOUT> - class ObjectCache; + template <template <typename> class TOUT> + class ObjectCache; // ------------------------------------------------------------------------------- /** Exception class used by the blender loader to selectively catch exceptions @@ -75,40 +80,40 @@ namespace Assimp { // ------------------------------------------------------------------------------- struct Error : DeadlyImportError { - Error (const std::string& s) - : DeadlyImportError(s) - {} + Error (const std::string& s) + : DeadlyImportError(s) + {} }; // ------------------------------------------------------------------------------- /** The only purpose of this structure is to feed a virtual dtor into its * descendents. It serves as base class for all data structure fields. */ // ------------------------------------------------------------------------------- -struct ElemBase +struct ElemBase { - virtual ~ElemBase() {} - - /** Type name of the element. The type - * string points is the `c_str` of the `name` attribute of the - * corresponding `Structure`, that is, it is only valid as long - * as the DNA is not modified. The dna_type is only set if the - * data type is not static, i.e. a boost::shared_ptr<ElemBase> - * in the scene description would have its type resolved - * at runtime, so this member is always set. */ - const char* dna_type; + virtual ~ElemBase() {} + + /** Type name of the element. The type + * string points is the `c_str` of the `name` attribute of the + * corresponding `Structure`, that is, it is only valid as long + * as the DNA is not modified. The dna_type is only set if the + * data type is not static, i.e. a std::shared_ptr<ElemBase> + * in the scene description would have its type resolved + * at runtime, so this member is always set. */ + const char* dna_type; }; // ------------------------------------------------------------------------------- /** Represents a generic pointer to a memory location, which can be either 32 * or 64 bits. These pointers are loaded from the BLEND file and finally - * fixed to point to the real, converted representation of the objects + * fixed to point to the real, converted representation of the objects * they used to point to.*/ // ------------------------------------------------------------------------------- struct Pointer { - Pointer() : val() {} - uint64_t val; + Pointer() : val() {} + uint64_t val; }; // ------------------------------------------------------------------------------- @@ -116,13 +121,13 @@ struct Pointer // ------------------------------------------------------------------------------- struct FileOffset { - FileOffset() : val() {} - uint64_t val; + FileOffset() : val() {} + uint64_t val; }; // ------------------------------------------------------------------------------- /** Dummy derivate of std::vector to be able to use it in templates simultaenously - * with boost::shared_ptr, which takes only one template argument + * with std::shared_ptr, which takes only one template argument * while std::vector takes three. Also we need to provide some special member * functions of shared_ptr */ // ------------------------------------------------------------------------------- @@ -130,44 +135,44 @@ template <typename T> class vector : public std::vector<T> { public: - using std::vector<T>::resize; - using std::vector<T>::empty; + using std::vector<T>::resize; + using std::vector<T>::empty; - void reset() { - resize(0); - } + void reset() { + resize(0); + } - operator bool () const { - return !empty(); - } + operator bool () const { + return !empty(); + } }; // ------------------------------------------------------------------------------- /** Mixed flags for use in #Field */ // ------------------------------------------------------------------------------- -enum FieldFlags +enum FieldFlags { - FieldFlag_Pointer = 0x1, - FieldFlag_Array = 0x2 + FieldFlag_Pointer = 0x1, + FieldFlag_Array = 0x2 }; // ------------------------------------------------------------------------------- /** Represents a single member of a data structure in a BLEND file */ // ------------------------------------------------------------------------------- -struct Field -{ - std::string name; - std::string type; +struct Field +{ + std::string name; + std::string type; - size_t size; - size_t offset; + size_t size; + size_t offset; - /** Size of each array dimension. For flat arrays, - * the second dimension is set to 1. */ - size_t array_sizes[2]; + /** Size of each array dimension. For flat arrays, + * the second dimension is set to 1. */ + size_t array_sizes[2]; - /** Any of the #FieldFlags enumerated values */ - unsigned int flags; + /** Any of the #FieldFlags enumerated values */ + unsigned int flags; }; // ------------------------------------------------------------------------------- @@ -175,18 +180,18 @@ struct Field * mission critical so we need them, while others can silently be default * initialized and no animations are harmed. */ // ------------------------------------------------------------------------------- -enum ErrorPolicy +enum ErrorPolicy { - /** Substitute default value and ignore */ - ErrorPolicy_Igno, - /** Substitute default value and write to log */ - ErrorPolicy_Warn, - /** Substitute a massive error message and crash the whole matrix. Its time for another zion */ - ErrorPolicy_Fail + /** Substitute default value and ignore */ + ErrorPolicy_Igno, + /** Substitute default value and write to log */ + ErrorPolicy_Warn, + /** Substitute a massive error message and crash the whole matrix. Its time for another zion */ + ErrorPolicy_Fail }; #ifdef ASSIMP_BUILD_BLENDER_DEBUG -# define ErrorPolicy_Igno ErrorPolicy_Warn +# define ErrorPolicy_Igno ErrorPolicy_Warn #endif // ------------------------------------------------------------------------------- @@ -197,395 +202,395 @@ enum ErrorPolicy * binary `blob` read from the file to such a structure instance with * meaningful contents. */ // ------------------------------------------------------------------------------- -class Structure +class Structure { - template <template <typename> class> friend class ObjectCache; + template <template <typename> class> friend class ObjectCache; public: - Structure() - : cache_idx(-1) - {} + Structure() + : cache_idx(static_cast<size_t>(-1) ) + {} public: - // publicly accessible members - std::string name; - vector< Field > fields; - std::map<std::string, size_t> indices; + // publicly accessible members + std::string name; + vector< Field > fields; + std::map<std::string, size_t> indices; - size_t size; + size_t size; public: - // -------------------------------------------------------- - /** Access a field of the structure by its canonical name. The pointer version - * returns NULL on failure while the reference version raises an import error. */ - inline const Field& operator [] (const std::string& ss) const; - inline const Field* Get (const std::string& ss) const; + // -------------------------------------------------------- + /** Access a field of the structure by its canonical name. The pointer version + * returns NULL on failure while the reference version raises an import error. */ + inline const Field& operator [] (const std::string& ss) const; + inline const Field* Get (const std::string& ss) const; - // -------------------------------------------------------- - /** Access a field of the structure by its index */ - inline const Field& operator [] (const size_t i) const; + // -------------------------------------------------------- + /** Access a field of the structure by its index */ + inline const Field& operator [] (const size_t i) const; - // -------------------------------------------------------- - inline bool operator== (const Structure& other) const { - return name == other.name; // name is meant to be an unique identifier - } + // -------------------------------------------------------- + inline bool operator== (const Structure& other) const { + return name == other.name; // name is meant to be an unique identifier + } - // -------------------------------------------------------- - inline bool operator!= (const Structure& other) const { - return name != other.name; - } + // -------------------------------------------------------- + inline bool operator!= (const Structure& other) const { + return name != other.name; + } public: - // -------------------------------------------------------- - /** Try to read an instance of the structure from the stream - * and attempt to convert to `T`. This is done by - * an appropriate specialization. If none is available, - * a compiler complain is the result. - * @param dest Destination value to be written - * @param db File database, including input stream. */ - template <typename T> inline void Convert (T& dest, - const FileDatabase& db) const; - - - - // -------------------------------------------------------- - // generic converter - template <typename T> - void Convert(boost::shared_ptr<ElemBase> in,const FileDatabase& db) const; - - // -------------------------------------------------------- - // generic allocator - template <typename T> boost::shared_ptr<ElemBase> Allocate() const; - - - - // -------------------------------------------------------- - // field parsing for 1d arrays - template <int error_policy, typename T, size_t M> - void ReadFieldArray(T (& out)[M], const char* name, - const FileDatabase& db) const; - - // -------------------------------------------------------- - // field parsing for 2d arrays - template <int error_policy, typename T, size_t M, size_t N> - void ReadFieldArray2(T (& out)[M][N], const char* name, - const FileDatabase& db) const; - - // -------------------------------------------------------- - // field parsing for pointer or dynamic array types - // (boost::shared_ptr or boost::shared_array) - // The return value indicates whether the data was already cached. - template <int error_policy, template <typename> class TOUT, typename T> - bool ReadFieldPtr(TOUT<T>& out, const char* name, - const FileDatabase& db, - bool non_recursive = false) const; - - // -------------------------------------------------------- - // field parsing for static arrays of pointer or dynamic - // array types (boost::shared_ptr[] or boost::shared_array[]) - // The return value indicates whether the data was already cached. - template <int error_policy, template <typename> class TOUT, typename T, size_t N> - bool ReadFieldPtr(TOUT<T> (&out)[N], const char* name, - const FileDatabase& db) const; - - // -------------------------------------------------------- - // field parsing for `normal` values - // The return value indicates whether the data was already cached. - template <int error_policy, typename T> - void ReadField(T& out, const char* name, - const FileDatabase& db) const; + // -------------------------------------------------------- + /** Try to read an instance of the structure from the stream + * and attempt to convert to `T`. This is done by + * an appropriate specialization. If none is available, + * a compiler complain is the result. + * @param dest Destination value to be written + * @param db File database, including input stream. */ + template <typename T> inline void Convert (T& dest, + const FileDatabase& db) const; + + + + // -------------------------------------------------------- + // generic converter + template <typename T> + void Convert(std::shared_ptr<ElemBase> in,const FileDatabase& db) const; + + // -------------------------------------------------------- + // generic allocator + template <typename T> std::shared_ptr<ElemBase> Allocate() const; + + + + // -------------------------------------------------------- + // field parsing for 1d arrays + template <int error_policy, typename T, size_t M> + void ReadFieldArray(T (& out)[M], const char* name, + const FileDatabase& db) const; + + // -------------------------------------------------------- + // field parsing for 2d arrays + template <int error_policy, typename T, size_t M, size_t N> + void ReadFieldArray2(T (& out)[M][N], const char* name, + const FileDatabase& db) const; + + // -------------------------------------------------------- + // field parsing for pointer or dynamic array types + // (std::shared_ptr) + // The return value indicates whether the data was already cached. + template <int error_policy, template <typename> class TOUT, typename T> + bool ReadFieldPtr(TOUT<T>& out, const char* name, + const FileDatabase& db, + bool non_recursive = false) const; + + // -------------------------------------------------------- + // field parsing for static arrays of pointer or dynamic + // array types (std::shared_ptr[]) + // The return value indicates whether the data was already cached. + template <int error_policy, template <typename> class TOUT, typename T, size_t N> + bool ReadFieldPtr(TOUT<T> (&out)[N], const char* name, + const FileDatabase& db) const; + + // -------------------------------------------------------- + // field parsing for `normal` values + // The return value indicates whether the data was already cached. + template <int error_policy, typename T> + void ReadField(T& out, const char* name, + const FileDatabase& db) const; private: - // -------------------------------------------------------- - template <template <typename> class TOUT, typename T> - bool ResolvePointer(TOUT<T>& out, const Pointer & ptrval, - const FileDatabase& db, const Field& f, - bool non_recursive = false) const; + // -------------------------------------------------------- + template <template <typename> class TOUT, typename T> + bool ResolvePointer(TOUT<T>& out, const Pointer & ptrval, + const FileDatabase& db, const Field& f, + bool non_recursive = false) const; - // -------------------------------------------------------- - template <template <typename> class TOUT, typename T> - bool ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, - const FileDatabase& db, const Field& f, bool) const; + // -------------------------------------------------------- + template <template <typename> class TOUT, typename T> + bool ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, + const FileDatabase& db, const Field& f, bool) const; - // -------------------------------------------------------- - bool ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval, - const FileDatabase& db, const Field& f, bool) const; + // -------------------------------------------------------- + bool ResolvePointer( std::shared_ptr< FileOffset >& out, const Pointer & ptrval, + const FileDatabase& db, const Field& f, bool) const; - // -------------------------------------------------------- - inline const FileBlockHead* LocateFileBlockForAddress( - const Pointer & ptrval, - const FileDatabase& db) const; + // -------------------------------------------------------- + inline const FileBlockHead* LocateFileBlockForAddress( + const Pointer & ptrval, + const FileDatabase& db) const; private: - // ------------------------------------------------------------------------------ - template <typename T> T* _allocate(boost::shared_ptr<T>& out, size_t& s) const { - out = boost::shared_ptr<T>(new T()); - s = 1; - return out.get(); - } - - template <typename T> T* _allocate(vector<T>& out, size_t& s) const { - out.resize(s); - return s ? &out.front() : NULL; - } - - // -------------------------------------------------------- - template <int error_policy> - struct _defaultInitializer { - - template <typename T, unsigned int N> - void operator ()(T (& out)[N], const char* = NULL) { - for (unsigned int i = 0; i < N; ++i) { - out[i] = T(); - } - } - - template <typename T, unsigned int N, unsigned int M> - void operator ()(T (& out)[N][M], const char* = NULL) { - for (unsigned int i = 0; i < N; ++i) { - for (unsigned int j = 0; j < M; ++j) { - out[i][j] = T(); - } - } - } - - template <typename T> - void operator ()(T& out, const char* = NULL) { - out = T(); - } - }; + // ------------------------------------------------------------------------------ + template <typename T> T* _allocate(std::shared_ptr<T>& out, size_t& s) const { + out = std::shared_ptr<T>(new T()); + s = 1; + return out.get(); + } + + template <typename T> T* _allocate(vector<T>& out, size_t& s) const { + out.resize(s); + return s ? &out.front() : NULL; + } + + // -------------------------------------------------------- + template <int error_policy> + struct _defaultInitializer { + + template <typename T, unsigned int N> + void operator ()(T (& out)[N], const char* = NULL) { + for (unsigned int i = 0; i < N; ++i) { + out[i] = T(); + } + } + + template <typename T, unsigned int N, unsigned int M> + void operator ()(T (& out)[N][M], const char* = NULL) { + for (unsigned int i = 0; i < N; ++i) { + for (unsigned int j = 0; j < M; ++j) { + out[i][j] = T(); + } + } + } + + template <typename T> + void operator ()(T& out, const char* = NULL) { + out = T(); + } + }; private: - mutable size_t cache_idx; + mutable size_t cache_idx; }; // -------------------------------------------------------- template <> struct Structure :: _defaultInitializer<ErrorPolicy_Warn> { - template <typename T> - void operator ()(T& out, const char* reason = "<add reason>") { - DefaultLogger::get()->warn(reason); + template <typename T> + void operator ()(T& out, const char* reason = "<add reason>") { + DefaultLogger::get()->warn(reason); - // ... and let the show go on - _defaultInitializer<0 /*ErrorPolicy_Igno*/>()(out); - } + // ... and let the show go on + _defaultInitializer<0 /*ErrorPolicy_Igno*/>()(out); + } }; template <> struct Structure :: _defaultInitializer<ErrorPolicy_Fail> { - template <typename T> - void operator ()(T& /*out*/,const char* = "") { - // obviously, it is crucial that _DefaultInitializer is used - // only from within a catch clause. - throw; - } + template <typename T> + void operator ()(T& /*out*/,const char* = "") { + // obviously, it is crucial that _DefaultInitializer is used + // only from within a catch clause. + throw; + } }; // ------------------------------------------------------------------------------------------------------- -template <> inline bool Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out, - const Pointer & ptrval, - const FileDatabase& db, - const Field& f, - bool - ) const; +template <> inline bool Structure :: ResolvePointer<std::shared_ptr,ElemBase>(std::shared_ptr<ElemBase>& out, + const Pointer & ptrval, + const FileDatabase& db, + const Field& f, + bool + ) const; // ------------------------------------------------------------------------------- /** Represents the full data structure information for a single BLEND file. * This data is extracted from the DNA1 chunk in the file. - * #DNAParser does the reading and represents currently the only place where + * #DNAParser does the reading and represents currently the only place where * DNA is altered.*/ // ------------------------------------------------------------------------------- class DNA { public: - typedef void (Structure::*ConvertProcPtr) ( - boost::shared_ptr<ElemBase> in, - const FileDatabase& - ) const; + typedef void (Structure::*ConvertProcPtr) ( + std::shared_ptr<ElemBase> in, + const FileDatabase& + ) const; + + typedef std::shared_ptr<ElemBase> ( + Structure::*AllocProcPtr) () const; - typedef boost::shared_ptr<ElemBase> ( - Structure::*AllocProcPtr) () const; - - typedef std::pair< AllocProcPtr, ConvertProcPtr > FactoryPair; + typedef std::pair< AllocProcPtr, ConvertProcPtr > FactoryPair; public: - std::map<std::string, FactoryPair > converters; - vector<Structure > structures; - std::map<std::string, size_t> indices; + std::map<std::string, FactoryPair > converters; + vector<Structure > structures; + std::map<std::string, size_t> indices; public: - // -------------------------------------------------------- - /** Access a structure by its canonical name, the pointer version returns NULL on failure - * while the reference version raises an error. */ - inline const Structure& operator [] (const std::string& ss) const; - inline const Structure* Get (const std::string& ss) const; + // -------------------------------------------------------- + /** Access a structure by its canonical name, the pointer version returns NULL on failure + * while the reference version raises an error. */ + inline const Structure& operator [] (const std::string& ss) const; + inline const Structure* Get (const std::string& ss) const; - // -------------------------------------------------------- - /** Access a structure by its index */ - inline const Structure& operator [] (const size_t i) const; + // -------------------------------------------------------- + /** Access a structure by its index */ + inline const Structure& operator [] (const size_t i) const; public: - // -------------------------------------------------------- - /** Add structure definitions for all the primitive types, - * i.e. integer, short, char, float */ - void AddPrimitiveStructures(); - - // -------------------------------------------------------- - /** Fill the @c converters member with converters for all - * known data types. The implementation of this method is - * in BlenderScene.cpp and is machine-generated. - * Converters are used to quickly handle objects whose - * exact data type is a runtime-property and not yet - * known at compile time (consier Object::data).*/ - void RegisterConverters(); - - - // -------------------------------------------------------- - /** Take an input blob from the stream, interpret it according to - * a its structure name and convert it to the intermediate - * representation. - * @param structure Destination structure definition - * @param db File database. - * @return A null pointer if no appropriate converter is available.*/ - boost::shared_ptr< ElemBase > ConvertBlobToStructure( - const Structure& structure, - const FileDatabase& db - ) const; - - // -------------------------------------------------------- - /** Find a suitable conversion function for a given Structure. - * Such a converter function takes a blob from the input - * stream, reads as much as it needs, and builds up a - * complete object in intermediate representation. - * @param structure Destination structure definition - * @param db File database. - * @return A null pointer in .first if no appropriate converter is available.*/ - FactoryPair GetBlobToStructureConverter( - const Structure& structure, - const FileDatabase& db - ) const; + // -------------------------------------------------------- + /** Add structure definitions for all the primitive types, + * i.e. integer, short, char, float */ + void AddPrimitiveStructures(); + + // -------------------------------------------------------- + /** Fill the @c converters member with converters for all + * known data types. The implementation of this method is + * in BlenderScene.cpp and is machine-generated. + * Converters are used to quickly handle objects whose + * exact data type is a runtime-property and not yet + * known at compile time (consier Object::data).*/ + void RegisterConverters(); + + + // -------------------------------------------------------- + /** Take an input blob from the stream, interpret it according to + * a its structure name and convert it to the intermediate + * representation. + * @param structure Destination structure definition + * @param db File database. + * @return A null pointer if no appropriate converter is available.*/ + std::shared_ptr< ElemBase > ConvertBlobToStructure( + const Structure& structure, + const FileDatabase& db + ) const; + + // -------------------------------------------------------- + /** Find a suitable conversion function for a given Structure. + * Such a converter function takes a blob from the input + * stream, reads as much as it needs, and builds up a + * complete object in intermediate representation. + * @param structure Destination structure definition + * @param db File database. + * @return A null pointer in .first if no appropriate converter is available.*/ + FactoryPair GetBlobToStructureConverter( + const Structure& structure, + const FileDatabase& db + ) const; #ifdef ASSIMP_BUILD_BLENDER_DEBUG - // -------------------------------------------------------- - /** Dump the DNA to a text file. This is for debugging purposes. - * The output file is `dna.txt` in the current working folder*/ - void DumpToFile(); + // -------------------------------------------------------- + /** Dump the DNA to a text file. This is for debugging purposes. + * The output file is `dna.txt` in the current working folder*/ + void DumpToFile(); #endif - // -------------------------------------------------------- - /** Extract array dimensions from a C array declaration, such - * as `...[4][6]`. Returned string would be `...[][]`. - * @param out - * @param array_sizes Receive maximally two array dimensions, - * the second element is set to 1 if the array is flat. - * Both are set to 1 if the input is not an array. - * @throw DeadlyImportError if more than 2 dimensions are - * encountered. */ - static void ExtractArraySize( - const std::string& out, - size_t array_sizes[2] - ); + // -------------------------------------------------------- + /** Extract array dimensions from a C array declaration, such + * as `...[4][6]`. Returned string would be `...[][]`. + * @param out + * @param array_sizes Receive maximally two array dimensions, + * the second element is set to 1 if the array is flat. + * Both are set to 1 if the input is not an array. + * @throw DeadlyImportError if more than 2 dimensions are + * encountered. */ + static void ExtractArraySize( + const std::string& out, + size_t array_sizes[2] + ); }; // special converters for primitive types -template <> inline void Structure :: Convert<int> (int& dest,const FileDatabase& db) const; -template <> inline void Structure :: Convert<short> (short& dest,const FileDatabase& db) const; -template <> inline void Structure :: Convert<char> (char& dest,const FileDatabase& db) const; -template <> inline void Structure :: Convert<float> (float& dest,const FileDatabase& db) const; -template <> inline void Structure :: Convert<double> (double& dest,const FileDatabase& db) const; -template <> inline void Structure :: Convert<Pointer> (Pointer& dest,const FileDatabase& db) const; +template <> inline void Structure :: Convert<int> (int& dest,const FileDatabase& db) const; +template <> inline void Structure :: Convert<short> (short& dest,const FileDatabase& db) const; +template <> inline void Structure :: Convert<char> (char& dest,const FileDatabase& db) const; +template <> inline void Structure :: Convert<float> (float& dest,const FileDatabase& db) const; +template <> inline void Structure :: Convert<double> (double& dest,const FileDatabase& db) const; +template <> inline void Structure :: Convert<Pointer> (Pointer& dest,const FileDatabase& db) const; // ------------------------------------------------------------------------------- /** Describes a master file block header. Each master file sections holds n * elements of a certain SDNA structure (or otherwise unspecified data). */ // ------------------------------------------------------------------------------- -struct FileBlockHead +struct FileBlockHead { - // points right after the header of the file block - StreamReaderAny::pos start; + // points right after the header of the file block + StreamReaderAny::pos start; - std::string id; - size_t size; + std::string id; + size_t size; - // original memory address of the data - Pointer address; + // original memory address of the data + Pointer address; - // index into DNA - unsigned int dna_index; + // index into DNA + unsigned int dna_index; - // number of structure instances to follow - size_t num; + // number of structure instances to follow + size_t num; - // file blocks are sorted by address to quickly locate specific memory addresses - bool operator < (const FileBlockHead& o) const { - return address.val < o.address.val; - } + // file blocks are sorted by address to quickly locate specific memory addresses + bool operator < (const FileBlockHead& o) const { + return address.val < o.address.val; + } - // for std::upper_bound - operator const Pointer& () const { - return address; - } + // for std::upper_bound + operator const Pointer& () const { + return address; + } }; // for std::upper_bound inline bool operator< (const Pointer& a, const Pointer& b) { - return a.val < b.val; + return a.val < b.val; } // ------------------------------------------------------------------------------- /** Utility to read all master file blocks in turn. */ // ------------------------------------------------------------------------------- -class SectionParser +class SectionParser { public: - // -------------------------------------------------------- - /** @param stream Inout stream, must point to the - * first section in the file. Call Next() once - * to have it read. - * @param ptr64 Pointer size in file is 64 bits? */ - SectionParser(StreamReaderAny& stream,bool ptr64) - : stream(stream) - , ptr64(ptr64) - { - current.size = current.start = 0; - } + // -------------------------------------------------------- + /** @param stream Inout stream, must point to the + * first section in the file. Call Next() once + * to have it read. + * @param ptr64 Pointer size in file is 64 bits? */ + SectionParser(StreamReaderAny& stream,bool ptr64) + : stream(stream) + , ptr64(ptr64) + { + current.size = current.start = 0; + } public: - // -------------------------------------------------------- - const FileBlockHead& GetCurrent() const { - return current; - } - + // -------------------------------------------------------- + const FileBlockHead& GetCurrent() const { + return current; + } + public: - // -------------------------------------------------------- - /** Advance to the next section. - * @throw DeadlyImportError if the last chunk was passed. */ - void Next(); + // -------------------------------------------------------- + /** Advance to the next section. + * @throw DeadlyImportError if the last chunk was passed. */ + void Next(); public: - FileBlockHead current; - StreamReaderAny& stream; - bool ptr64; + FileBlockHead current; + StreamReaderAny& stream; + bool ptr64; }; @@ -597,31 +602,31 @@ class Statistics { public: - Statistics () - : fields_read () - , pointers_resolved () - , cache_hits () -// , blocks_read () - , cached_objects () - {} + Statistics () + : fields_read () + , pointers_resolved () + , cache_hits () +// , blocks_read () + , cached_objects () + {} public: - /** total number of fields we read */ - unsigned int fields_read; + /** total number of fields we read */ + unsigned int fields_read; - /** total number of resolved pointers */ - unsigned int pointers_resolved; + /** total number of resolved pointers */ + unsigned int pointers_resolved; - /** number of pointers resolved from the cache */ - unsigned int cache_hits; + /** number of pointers resolved from the cache */ + unsigned int cache_hits; - /** number of blocks (from FileDatabase::entries) - we did actually read from. */ - // unsigned int blocks_read; + /** number of blocks (from FileDatabase::entries) + we did actually read from. */ + // unsigned int blocks_read; - /** objects in FileData::cache */ - unsigned int cached_objects; + /** objects in FileData::cache */ + unsigned int cached_objects; }; #endif @@ -630,173 +635,173 @@ public: * avoids circular references and avoids object duplication. */ // ------------------------------------------------------------------------------- template <template <typename> class TOUT> -class ObjectCache +class ObjectCache { public: - typedef std::map< Pointer, TOUT<ElemBase> > StructureCache; + typedef std::map< Pointer, TOUT<ElemBase> > StructureCache; public: - ObjectCache(const FileDatabase& db) - : db(db) - { - // currently there are only ~400 structure records per blend file. - // we read only a small part of them and don't cache objects - // which we don't need, so this should suffice. - caches.reserve(64); - } + ObjectCache(const FileDatabase& db) + : db(db) + { + // currently there are only ~400 structure records per blend file. + // we read only a small part of them and don't cache objects + // which we don't need, so this should suffice. + caches.reserve(64); + } public: - // -------------------------------------------------------- - /** Check whether a specific item is in the cache. - * @param s Data type of the item - * @param out Output pointer. Unchanged if the - * cache doens't know the item yet. - * @param ptr Item address to look for. */ - template <typename T> void get ( - const Structure& s, - TOUT<T>& out, - const Pointer& ptr) const; - - // -------------------------------------------------------- - /** Add an item to the cache after the item has - * been fully read. Do not insert anything that - * may be faulty or might cause the loading - * to abort. - * @param s Data type of the item - * @param out Item to insert into the cache - * @param ptr address (cache key) of the item. */ - template <typename T> void set - (const Structure& s, - const TOUT<T>& out, - const Pointer& ptr); + // -------------------------------------------------------- + /** Check whether a specific item is in the cache. + * @param s Data type of the item + * @param out Output pointer. Unchanged if the + * cache doens't know the item yet. + * @param ptr Item address to look for. */ + template <typename T> void get ( + const Structure& s, + TOUT<T>& out, + const Pointer& ptr) const; + + // -------------------------------------------------------- + /** Add an item to the cache after the item has + * been fully read. Do not insert anything that + * may be faulty or might cause the loading + * to abort. + * @param s Data type of the item + * @param out Item to insert into the cache + * @param ptr address (cache key) of the item. */ + template <typename T> void set + (const Structure& s, + const TOUT<T>& out, + const Pointer& ptr); private: - mutable vector<StructureCache> caches; - const FileDatabase& db; + mutable vector<StructureCache> caches; + const FileDatabase& db; }; // ------------------------------------------------------------------------------- // ------------------------------------------------------------------------------- -template <> class ObjectCache<Blender::vector> +template <> class ObjectCache<Blender::vector> { public: - ObjectCache(const FileDatabase&) {} + ObjectCache(const FileDatabase&) {} - template <typename T> void get(const Structure&, vector<T>&, const Pointer&) {} - template <typename T> void set(const Structure&, const vector<T>&, const Pointer&) {} + template <typename T> void get(const Structure&, vector<T>&, const Pointer&) {} + template <typename T> void set(const Structure&, const vector<T>&, const Pointer&) {} }; #ifdef _MSC_VER -# pragma warning(disable:4355) +# pragma warning(disable:4355) #endif // ------------------------------------------------------------------------------- /** Memory representation of a full BLEND file and all its dependencies. The * output aiScene is constructed from an instance of this data structure. */ // ------------------------------------------------------------------------------- -class FileDatabase +class FileDatabase { - template <template <typename> class TOUT> friend class ObjectCache; + template <template <typename> class TOUT> friend class ObjectCache; public: - FileDatabase() - : _cacheArrays(*this) - , _cache(*this) - , next_cache_idx() - {} + FileDatabase() + : _cacheArrays(*this) + , _cache(*this) + , next_cache_idx() + {} public: - // publicly accessible fields - bool i64bit; - bool little; + // publicly accessible fields + bool i64bit; + bool little; - DNA dna; - boost::shared_ptr< StreamReaderAny > reader; - vector< FileBlockHead > entries; + DNA dna; + std::shared_ptr< StreamReaderAny > reader; + vector< FileBlockHead > entries; public: - Statistics& stats() const { - return _stats; - } + Statistics& stats() const { + return _stats; + } - // For all our templates to work on both shared_ptr's and vector's - // using the same code, a dummy cache for arrays is provided. Actually, - // arrays of objects are never cached because we can't easily - // ensure their proper destruction. - template <typename T> - ObjectCache<boost::shared_ptr>& cache(boost::shared_ptr<T>& /*in*/) const { - return _cache; - } + // For all our templates to work on both shared_ptr's and vector's + // using the same code, a dummy cache for arrays is provided. Actually, + // arrays of objects are never cached because we can't easily + // ensure their proper destruction. + template <typename T> + ObjectCache<std::shared_ptr>& cache(std::shared_ptr<T>& /*in*/) const { + return _cache; + } - template <typename T> - ObjectCache<vector>& cache(vector<T>& /*in*/) const { - return _cacheArrays; - } + template <typename T> + ObjectCache<vector>& cache(vector<T>& /*in*/) const { + return _cacheArrays; + } private: - + #ifndef ASSIMP_BUILD_BLENDER_NO_STATS - mutable Statistics _stats; + mutable Statistics _stats; #endif - mutable ObjectCache<vector> _cacheArrays; - mutable ObjectCache<boost::shared_ptr> _cache; + mutable ObjectCache<vector> _cacheArrays; + mutable ObjectCache<std::shared_ptr> _cache; - mutable size_t next_cache_idx; + mutable size_t next_cache_idx; }; #ifdef _MSC_VER -# pragma warning(default:4355) +# pragma warning(default:4355) #endif // ------------------------------------------------------------------------------- /** Factory to extract a #DNA from the DNA1 file block in a BLEND file. */ // ------------------------------------------------------------------------------- -class DNAParser +class DNAParser { public: - /** Bind the parser to a empty DNA and an input stream */ - DNAParser(FileDatabase& db) - : db(db) - {} + /** Bind the parser to a empty DNA and an input stream */ + DNAParser(FileDatabase& db) + : db(db) + {} public: - // -------------------------------------------------------- - /** Locate the DNA in the file and parse it. The input - * stream is expected to point to the beginning of the DN1 - * chunk at the time this method is called and is - * undefined afterwards. - * @throw DeadlyImportError if the DNA cannot be read. - * @note The position of the stream pointer is undefined - * afterwards.*/ - void Parse (); + // -------------------------------------------------------- + /** Locate the DNA in the file and parse it. The input + * stream is expected to point to the beginning of the DN1 + * chunk at the time this method is called and is + * undefined afterwards. + * @throw DeadlyImportError if the DNA cannot be read. + * @note The position of the stream pointer is undefined + * afterwards.*/ + void Parse (); public: - /** Obtain a reference to the extracted DNA information */ - const Blender::DNA& GetDNA() const { - return db.dna; - } + /** Obtain a reference to the extracted DNA information */ + const Blender::DNA& GetDNA() const { + return db.dna; + } private: - FileDatabase& db; + FileDatabase& db; }; - } // end Blend + } // end Blend } // end Assimp #include "BlenderDNA.inl" |