aboutsummaryrefslogtreecommitdiff
path: root/NvCloth/samples/external/assimp-4.1.0/code/BlenderDNA.h
diff options
context:
space:
mode:
Diffstat (limited to 'NvCloth/samples/external/assimp-4.1.0/code/BlenderDNA.h')
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/code/BlenderDNA.h810
1 files changed, 810 insertions, 0 deletions
diff --git a/NvCloth/samples/external/assimp-4.1.0/code/BlenderDNA.h b/NvCloth/samples/external/assimp-4.1.0/code/BlenderDNA.h
new file mode 100644
index 0000000..bac8d78
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/code/BlenderDNA.h
@@ -0,0 +1,810 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2017, 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
+following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+ contributors may be used to endorse or promote products
+ 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
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+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
+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
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+/** @file BlenderDNA.h
+ * @brief Blender `DNA` (file format specification embedded in
+ * blend file itself) loader.
+ */
+#ifndef INCLUDED_AI_BLEND_DNA_H
+#define INCLUDED_AI_BLEND_DNA_H
+
+#include "BaseImporter.h"
+#include "StreamReader.h"
+#include <assimp/DefaultLogger.hpp>
+#include <stdint.h>
+#include <memory>
+#include <map>
+
+// enable verbose log output. really verbose, so be careful.
+#ifdef ASSIMP_BUILD_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 Blender {
+
+class FileDatabase;
+struct FileBlockHead;
+
+template <template <typename> class TOUT>
+class ObjectCache;
+
+// -------------------------------------------------------------------------------
+/** Exception class used by the blender loader to selectively catch exceptions
+ * thrown in its own code (DeadlyImportErrors thrown in general utility
+ * functions are untouched then). If such an exception is not caught by
+ * the loader itself, it will still be caught by Assimp due to its
+ * ancestry. */
+// -------------------------------------------------------------------------------
+struct Error : DeadlyImportError {
+ Error (const std::string& s)
+ : DeadlyImportError(s) {
+ // empty
+ }
+};
+
+// -------------------------------------------------------------------------------
+/** 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 {
+ ElemBase()
+ : dna_type(nullptr)
+ {
+ // empty
+ }
+
+ virtual ~ElemBase() {
+ // empty
+ }
+
+ /** 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
+ * they used to point to.*/
+// -------------------------------------------------------------------------------
+struct Pointer {
+ Pointer()
+ : val() {
+ // empty
+ }
+ uint64_t val;
+};
+
+// -------------------------------------------------------------------------------
+/** Represents a generic offset within a BLEND file */
+// -------------------------------------------------------------------------------
+struct FileOffset {
+ FileOffset()
+ : val() {
+ // empty
+ }
+ uint64_t val;
+};
+
+// -------------------------------------------------------------------------------
+/** Dummy derivate of std::vector to be able to use it in templates simultaenously
+ * 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 */
+// -------------------------------------------------------------------------------
+template <typename T>
+class vector : public std::vector<T> {
+public:
+ using std::vector<T>::resize;
+ using std::vector<T>::empty;
+
+ void reset() {
+ resize(0);
+ }
+
+ operator bool () const {
+ return !empty();
+ }
+};
+
+// -------------------------------------------------------------------------------
+/** Mixed flags for use in #Field */
+// -------------------------------------------------------------------------------
+enum FieldFlags {
+ 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;
+
+ 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];
+
+ /** Any of the #FieldFlags enumerated values */
+ unsigned int flags;
+};
+
+// -------------------------------------------------------------------------------
+/** Range of possible behaviours for fields absend in the input file. Some are
+ * mission critical so we need them, while others can silently be default
+ * initialized and no animations are harmed. */
+// -------------------------------------------------------------------------------
+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
+};
+
+#ifdef ASSIMP_BUILD_BLENDER_DEBUG
+# define ErrorPolicy_Igno ErrorPolicy_Warn
+#endif
+
+// -------------------------------------------------------------------------------
+/** Represents a data structure in a BLEND file. A Structure defines n fields
+ * and their locatios and encodings the input stream. Usually, every
+ * Structure instance pertains to one equally-named data structure in the
+ * BlenderScene.h header. This class defines various utilities to map a
+ * binary `blob` read from the file to such a structure instance with
+ * meaningful contents. */
+// -------------------------------------------------------------------------------
+class Structure {
+ template <template <typename> class> friend class ObjectCache;
+
+public:
+ Structure()
+ : cache_idx(static_cast<size_t>(-1) ){
+ // empty
+ }
+
+public:
+
+ // publicly accessible members
+ std::string name;
+ vector< Field > fields;
+ std::map<std::string, size_t> indices;
+
+ 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 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;
+ }
+
+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> 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(vector< TOUT<T> >& 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;
+
+private:
+
+ // ------------------------------------------------------------------------------
+ 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;
+};
+
+// --------------------------------------------------------
+template <> struct Structure :: _defaultInitializer<ErrorPolicy_Warn> {
+
+ 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);
+ }
+};
+
+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 <> 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
+ * DNA is altered.*/
+// -------------------------------------------------------------------------------
+class DNA
+{
+public:
+
+ typedef void (Structure::*ConvertProcPtr) (
+ std::shared_ptr<ElemBase> in,
+ const FileDatabase&
+ ) const;
+
+ typedef std::shared_ptr<ElemBase> (
+ Structure::*AllocProcPtr) () const;
+
+ typedef std::pair< AllocProcPtr, ConvertProcPtr > FactoryPair;
+
+public:
+
+ 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 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.*/
+ 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();
+#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]
+ );
+};
+
+// 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;
+
+// -------------------------------------------------------------------------------
+/** Describes a master file block header. Each master file sections holds n
+ * elements of a certain SDNA structure (or otherwise unspecified data). */
+// -------------------------------------------------------------------------------
+struct FileBlockHead
+{
+ // points right after the header of the file block
+ StreamReaderAny::pos start;
+
+ std::string id;
+ size_t size;
+
+ // original memory address of the data
+ Pointer address;
+
+ // index into DNA
+ unsigned int dna_index;
+
+ // 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;
+ }
+
+ // 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;
+}
+
+// -------------------------------------------------------------------------------
+/** Utility to read all master file blocks in turn. */
+// -------------------------------------------------------------------------------
+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;
+ }
+
+public:
+
+ // --------------------------------------------------------
+ const FileBlockHead& GetCurrent() const {
+ return current;
+ }
+
+
+public:
+
+ // --------------------------------------------------------
+ /** Advance to the next section.
+ * @throw DeadlyImportError if the last chunk was passed. */
+ void Next();
+
+public:
+
+ FileBlockHead current;
+ StreamReaderAny& stream;
+ bool ptr64;
+};
+
+
+#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
+// -------------------------------------------------------------------------------
+/** Import statistics, i.e. number of file blocks read*/
+// -------------------------------------------------------------------------------
+class Statistics {
+
+public:
+
+ 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 resolved pointers */
+ unsigned int pointers_resolved;
+
+ /** 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;
+
+ /** objects in FileData::cache */
+ unsigned int cached_objects;
+};
+#endif
+
+// -------------------------------------------------------------------------------
+/** The object cache - all objects addressed by pointers are added here. This
+ * avoids circular references and avoids object duplication. */
+// -------------------------------------------------------------------------------
+template <template <typename> class TOUT>
+class ObjectCache
+{
+public:
+
+ 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);
+ }
+
+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);
+
+private:
+
+ mutable vector<StructureCache> caches;
+ const FileDatabase& db;
+};
+
+// -------------------------------------------------------------------------------
+// -------------------------------------------------------------------------------
+template <> class ObjectCache<Blender::vector>
+{
+public:
+
+ 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&) {}
+};
+
+#ifdef _MSC_VER
+# 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
+{
+ template <template <typename> class TOUT> friend class ObjectCache;
+
+public:
+ FileDatabase()
+ : _cacheArrays(*this)
+ , _cache(*this)
+ , next_cache_idx()
+ {}
+
+public:
+ // publicly accessible fields
+ bool i64bit;
+ bool little;
+
+ DNA dna;
+ std::shared_ptr< StreamReaderAny > reader;
+ vector< FileBlockHead > entries;
+
+public:
+
+ 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<std::shared_ptr>& cache(std::shared_ptr<T>& /*in*/) const {
+ return _cache;
+ }
+
+ template <typename T>
+ ObjectCache<vector>& cache(vector<T>& /*in*/) const {
+ return _cacheArrays;
+ }
+
+private:
+
+
+#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
+ mutable Statistics _stats;
+#endif
+
+ mutable ObjectCache<vector> _cacheArrays;
+ mutable ObjectCache<std::shared_ptr> _cache;
+
+ mutable size_t next_cache_idx;
+};
+
+#ifdef _MSC_VER
+# pragma warning(default:4355)
+#endif
+
+// -------------------------------------------------------------------------------
+/** Factory to extract a #DNA from the DNA1 file block in a BLEND file. */
+// -------------------------------------------------------------------------------
+class DNAParser
+{
+
+public:
+
+ /** 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 ();
+
+public:
+
+ /** Obtain a reference to the extracted DNA information */
+ const Blender::DNA& GetDNA() const {
+ return db.dna;
+ }
+
+private:
+
+ FileDatabase& db;
+};
+
+ } // end Blend
+} // end Assimp
+
+#include "BlenderDNA.inl"
+
+#endif