Externalize Assimp
This commit is contained in:
		
							
								
								
									
										206
									
								
								thirdparty/assimp/code/Blender/BlenderBMesh.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										206
									
								
								thirdparty/assimp/code/Blender/BlenderBMesh.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,206 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2013, 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  BlenderBMesh.cpp
 | 
			
		||||
 *  @brief Conversion of Blender's new BMesh stuff
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
 | 
			
		||||
 | 
			
		||||
#include "BlenderDNA.h"
 | 
			
		||||
#include "BlenderScene.h"
 | 
			
		||||
#include "BlenderBMesh.h"
 | 
			
		||||
#include "BlenderTessellator.h"
 | 
			
		||||
 | 
			
		||||
namespace Assimp
 | 
			
		||||
{
 | 
			
		||||
    template< > const char* LogFunctions< BlenderBMeshConverter >::Prefix()
 | 
			
		||||
    {
 | 
			
		||||
        static auto prefix = "BLEND_BMESH: ";
 | 
			
		||||
        return prefix;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
using namespace Assimp;
 | 
			
		||||
using namespace Assimp::Blender;
 | 
			
		||||
using namespace Assimp::Formatter;
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
BlenderBMeshConverter::BlenderBMeshConverter( const Mesh* mesh ):
 | 
			
		||||
    BMesh( mesh ),
 | 
			
		||||
    triMesh( NULL )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
BlenderBMeshConverter::~BlenderBMeshConverter( )
 | 
			
		||||
{
 | 
			
		||||
    DestroyTriMesh( );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
bool BlenderBMeshConverter::ContainsBMesh( ) const
 | 
			
		||||
{
 | 
			
		||||
    // TODO - Should probably do some additional verification here
 | 
			
		||||
    return BMesh->totpoly && BMesh->totloop && BMesh->totvert;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
const Mesh* BlenderBMeshConverter::TriangulateBMesh( )
 | 
			
		||||
{
 | 
			
		||||
    AssertValidMesh( );
 | 
			
		||||
    AssertValidSizes( );
 | 
			
		||||
    PrepareTriMesh( );
 | 
			
		||||
 | 
			
		||||
    for ( int i = 0; i < BMesh->totpoly; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        const MPoly& poly = BMesh->mpoly[ i ];
 | 
			
		||||
        ConvertPolyToFaces( poly );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return triMesh;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderBMeshConverter::AssertValidMesh( )
 | 
			
		||||
{
 | 
			
		||||
    if ( !ContainsBMesh( ) )
 | 
			
		||||
    {
 | 
			
		||||
        ThrowException( "BlenderBMeshConverter requires a BMesh with \"polygons\" - please call BlenderBMeshConverter::ContainsBMesh to check this first" );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderBMeshConverter::AssertValidSizes( )
 | 
			
		||||
{
 | 
			
		||||
    if ( BMesh->totpoly != static_cast<int>( BMesh->mpoly.size( ) ) )
 | 
			
		||||
    {
 | 
			
		||||
        ThrowException( "BMesh poly array has incorrect size" );
 | 
			
		||||
    }
 | 
			
		||||
    if ( BMesh->totloop != static_cast<int>( BMesh->mloop.size( ) ) )
 | 
			
		||||
    {
 | 
			
		||||
        ThrowException( "BMesh loop array has incorrect size" );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderBMeshConverter::PrepareTriMesh( )
 | 
			
		||||
{
 | 
			
		||||
    if ( triMesh )
 | 
			
		||||
    {
 | 
			
		||||
        DestroyTriMesh( );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    triMesh = new Mesh( *BMesh );
 | 
			
		||||
    triMesh->totface = 0;
 | 
			
		||||
    triMesh->mface.clear( );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderBMeshConverter::DestroyTriMesh( )
 | 
			
		||||
{
 | 
			
		||||
    delete triMesh;
 | 
			
		||||
    triMesh = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderBMeshConverter::ConvertPolyToFaces( const MPoly& poly )
 | 
			
		||||
{
 | 
			
		||||
    const MLoop* polyLoop = &BMesh->mloop[ poly.loopstart ];
 | 
			
		||||
 | 
			
		||||
    if ( poly.totloop == 3 || poly.totloop == 4 )
 | 
			
		||||
    {
 | 
			
		||||
        AddFace( polyLoop[ 0 ].v, polyLoop[ 1 ].v, polyLoop[ 2 ].v, poly.totloop == 4 ? polyLoop[ 3 ].v : 0 );
 | 
			
		||||
 | 
			
		||||
        // UVs are optional, so only convert when present.
 | 
			
		||||
        if ( BMesh->mloopuv.size() )
 | 
			
		||||
        {
 | 
			
		||||
            if ( (poly.loopstart + poly.totloop ) > static_cast<int>( BMesh->mloopuv.size() ) )
 | 
			
		||||
            {
 | 
			
		||||
                ThrowException( "BMesh uv loop array has incorrect size" );
 | 
			
		||||
            }
 | 
			
		||||
            const MLoopUV* loopUV = &BMesh->mloopuv[ poly.loopstart ];
 | 
			
		||||
            AddTFace( loopUV[ 0 ].uv, loopUV[ 1 ].uv, loopUV[ 2 ].uv, poly.totloop == 4 ? loopUV[ 3 ].uv : 0 );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if ( poly.totloop > 4 )
 | 
			
		||||
    {
 | 
			
		||||
#if ASSIMP_BLEND_WITH_GLU_TESSELLATE
 | 
			
		||||
        BlenderTessellatorGL tessGL( *this );
 | 
			
		||||
        tessGL.Tessellate( polyLoop, poly.totloop, triMesh->mvert );
 | 
			
		||||
#elif ASSIMP_BLEND_WITH_POLY_2_TRI
 | 
			
		||||
        BlenderTessellatorP2T tessP2T( *this );
 | 
			
		||||
        tessP2T.Tessellate( polyLoop, poly.totloop, triMesh->mvert );
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderBMeshConverter::AddFace( int v1, int v2, int v3, int v4 )
 | 
			
		||||
{
 | 
			
		||||
    MFace face;
 | 
			
		||||
    face.v1 = v1;
 | 
			
		||||
    face.v2 = v2;
 | 
			
		||||
    face.v3 = v3;
 | 
			
		||||
    face.v4 = v4;
 | 
			
		||||
    // TODO - Work out how materials work
 | 
			
		||||
    face.mat_nr = 0;
 | 
			
		||||
    triMesh->mface.push_back( face );
 | 
			
		||||
    triMesh->totface = static_cast<int>(triMesh->mface.size( ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderBMeshConverter::AddTFace( const float* uv1, const float *uv2, const float *uv3, const float* uv4 )
 | 
			
		||||
{
 | 
			
		||||
    MTFace mtface;
 | 
			
		||||
    memcpy( &mtface.uv[ 0 ], uv1, sizeof(float) * 2 );
 | 
			
		||||
    memcpy( &mtface.uv[ 1 ], uv2, sizeof(float) * 2 );
 | 
			
		||||
    memcpy( &mtface.uv[ 2 ], uv3, sizeof(float) * 2 );
 | 
			
		||||
 | 
			
		||||
    if ( uv4 )
 | 
			
		||||
    {
 | 
			
		||||
        memcpy( &mtface.uv[ 3 ], uv4, sizeof(float) * 2 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    triMesh->mtface.push_back( mtface );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
 | 
			
		||||
							
								
								
									
										94
									
								
								thirdparty/assimp/code/Blender/BlenderBMesh.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										94
									
								
								thirdparty/assimp/code/Blender/BlenderBMesh.h
									
									
									
									
										vendored
									
									
								
							@@ -1,94 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2013, 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  BlenderBMesh.h
 | 
			
		||||
 *  @brief Conversion of Blender's new BMesh stuff
 | 
			
		||||
 */
 | 
			
		||||
#ifndef INCLUDED_AI_BLEND_BMESH_H
 | 
			
		||||
#define INCLUDED_AI_BLEND_BMESH_H
 | 
			
		||||
 | 
			
		||||
#include <assimp/LogAux.h>
 | 
			
		||||
 | 
			
		||||
namespace Assimp
 | 
			
		||||
{
 | 
			
		||||
    // TinyFormatter.h
 | 
			
		||||
    namespace Formatter
 | 
			
		||||
    {
 | 
			
		||||
        template < typename T,typename TR, typename A > class basic_formatter;
 | 
			
		||||
        typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // BlenderScene.h
 | 
			
		||||
    namespace Blender
 | 
			
		||||
    {
 | 
			
		||||
        struct Mesh;
 | 
			
		||||
        struct MPoly;
 | 
			
		||||
        struct MLoop;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class BlenderBMeshConverter: public LogFunctions< BlenderBMeshConverter >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        BlenderBMeshConverter( const Blender::Mesh* mesh );
 | 
			
		||||
        ~BlenderBMeshConverter( );
 | 
			
		||||
 | 
			
		||||
        bool ContainsBMesh( ) const;
 | 
			
		||||
 | 
			
		||||
        const Blender::Mesh* TriangulateBMesh( );
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        void AssertValidMesh( );
 | 
			
		||||
        void AssertValidSizes( );
 | 
			
		||||
        void PrepareTriMesh( );
 | 
			
		||||
        void DestroyTriMesh( );
 | 
			
		||||
        void ConvertPolyToFaces( const Blender::MPoly& poly );
 | 
			
		||||
        void AddFace( int v1, int v2, int v3, int v4 = 0 );
 | 
			
		||||
        void AddTFace( const float* uv1, const float* uv2, const float *uv3, const float* uv4 = 0 );
 | 
			
		||||
 | 
			
		||||
        const Blender::Mesh* BMesh;
 | 
			
		||||
        Blender::Mesh* triMesh;
 | 
			
		||||
 | 
			
		||||
        friend class BlenderTessellatorGL;
 | 
			
		||||
        friend class BlenderTessellatorP2T;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
} // end of namespace Assimp
 | 
			
		||||
 | 
			
		||||
#endif // INCLUDED_AI_BLEND_BMESH_H
 | 
			
		||||
							
								
								
									
										189
									
								
								thirdparty/assimp/code/Blender/BlenderCustomData.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										189
									
								
								thirdparty/assimp/code/Blender/BlenderCustomData.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,189 +0,0 @@
 | 
			
		||||
#include "BlenderCustomData.h"
 | 
			
		||||
#include "BlenderDNA.h"
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
namespace Assimp {
 | 
			
		||||
    namespace Blender {
 | 
			
		||||
        /**
 | 
			
		||||
        *   @brief  read/convert of Structure array to memory
 | 
			
		||||
        */
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        bool read(const Structure &s, T *p, const size_t cnt, const FileDatabase &db) {
 | 
			
		||||
            for (size_t i = 0; i < cnt; ++i) {
 | 
			
		||||
                T read;
 | 
			
		||||
                s.Convert(read, db);
 | 
			
		||||
                *p = read;
 | 
			
		||||
                p++;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
        *   @brief  pointer to function read memory for n CustomData types
 | 
			
		||||
        */
 | 
			
		||||
        typedef bool        (*PRead)(ElemBase *pOut, const size_t cnt, const FileDatabase &db);
 | 
			
		||||
        typedef ElemBase *  (*PCreate)(const size_t cnt);
 | 
			
		||||
        typedef void(*PDestroy)(ElemBase *);
 | 
			
		||||
 | 
			
		||||
#define IMPL_STRUCT_READ(ty)                                                    \
 | 
			
		||||
        bool read##ty(ElemBase *v, const size_t cnt, const FileDatabase &db) {  \
 | 
			
		||||
        ty *ptr = dynamic_cast<ty*>(v);                                         \
 | 
			
		||||
        if (nullptr == ptr) {                                                   \
 | 
			
		||||
            return false;                                                       \
 | 
			
		||||
        }                                                                       \
 | 
			
		||||
        return read<ty>(db.dna[#ty], ptr, cnt, db);                             \
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#define IMPL_STRUCT_CREATE(ty)                                                  \
 | 
			
		||||
        ElemBase *create##ty(const size_t cnt) {                                \
 | 
			
		||||
            return new ty[cnt];                                                 \
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#define IMPL_STRUCT_DESTROY(ty)                                                 \
 | 
			
		||||
        void destroy##ty(ElemBase *pE) {                                        \
 | 
			
		||||
            ty *p = dynamic_cast<ty *>(pE);                                     \
 | 
			
		||||
            delete[]p;                                                          \
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
        *   @brief  helper macro to define Structure functions
 | 
			
		||||
        */
 | 
			
		||||
#define IMPL_STRUCT(ty)                                                         \
 | 
			
		||||
        IMPL_STRUCT_READ(ty)                                                    \
 | 
			
		||||
        IMPL_STRUCT_CREATE(ty)                                                  \
 | 
			
		||||
        IMPL_STRUCT_DESTROY(ty)
 | 
			
		||||
 | 
			
		||||
        // supported structures for CustomData
 | 
			
		||||
        IMPL_STRUCT(MVert)
 | 
			
		||||
        IMPL_STRUCT(MEdge)
 | 
			
		||||
        IMPL_STRUCT(MFace)
 | 
			
		||||
        IMPL_STRUCT(MTFace)
 | 
			
		||||
        IMPL_STRUCT(MTexPoly)
 | 
			
		||||
        IMPL_STRUCT(MLoopUV)
 | 
			
		||||
        IMPL_STRUCT(MLoopCol)
 | 
			
		||||
        IMPL_STRUCT(MPoly)
 | 
			
		||||
        IMPL_STRUCT(MLoop)
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
        *   @brief  describes the size of data and the read function to be used for single CustomerData.type
 | 
			
		||||
        */
 | 
			
		||||
        struct CustomDataTypeDescription {
 | 
			
		||||
            PRead Read;                         ///< function to read one CustomData type element
 | 
			
		||||
            PCreate Create;                       ///< function to allocate n type elements
 | 
			
		||||
            PDestroy Destroy;
 | 
			
		||||
 | 
			
		||||
            CustomDataTypeDescription(PRead read, PCreate create, PDestroy destroy)
 | 
			
		||||
                : Read(read)
 | 
			
		||||
                , Create(create)
 | 
			
		||||
                , Destroy(destroy)
 | 
			
		||||
            {}
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
        *   @brief  helper macro to define Structure type specific CustomDataTypeDescription
 | 
			
		||||
        *   @note   IMPL_STRUCT_READ for same ty must be used earlier to implement the typespecific read function
 | 
			
		||||
        */
 | 
			
		||||
#define DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(ty)           \
 | 
			
		||||
        CustomDataTypeDescription{&read##ty, &create##ty, &destroy##ty}
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
        *   @brief  helper macro to define CustomDataTypeDescription for UNSUPPORTED type
 | 
			
		||||
        */
 | 
			
		||||
#define DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION          \
 | 
			
		||||
        CustomDataTypeDescription{nullptr, nullptr, nullptr}
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
        *   @brief  descriptors for data pointed to from CustomDataLayer.data
 | 
			
		||||
        *   @note   some of the CustomData uses already well defined Structures
 | 
			
		||||
        *           other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
 | 
			
		||||
        *           use a special readfunction for that cases
 | 
			
		||||
        */
 | 
			
		||||
        std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
 | 
			
		||||
            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
 | 
			
		||||
            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MFace),
 | 
			
		||||
            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTFace),
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTexPoly),
 | 
			
		||||
            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopUV),
 | 
			
		||||
            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopCol),
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MPoly),
 | 
			
		||||
            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoop),
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
 | 
			
		||||
            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION
 | 
			
		||||
        }};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        bool isValidCustomDataType(const int cdtype) {
 | 
			
		||||
            return cdtype >= 0 && cdtype < CD_NUMTYPES;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool readCustomData(std::shared_ptr<ElemBase> &out, const int cdtype, const size_t cnt, const FileDatabase &db) {
 | 
			
		||||
            if (!isValidCustomDataType(cdtype)) {
 | 
			
		||||
                throw Error((Formatter::format(), "CustomData.type ", cdtype, " out of index"));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const CustomDataTypeDescription cdtd = customDataTypeDescriptions[cdtype];
 | 
			
		||||
            if (cdtd.Read && cdtd.Create && cdtd.Destroy && cnt > 0) {
 | 
			
		||||
                // allocate cnt elements and parse them from file
 | 
			
		||||
                out.reset(cdtd.Create(cnt), cdtd.Destroy);
 | 
			
		||||
                return cdtd.Read(out.get(), cnt, db);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::shared_ptr<CustomDataLayer> getCustomDataLayer(const CustomData &customdata, const CustomDataType cdtype, const std::string &name) {
 | 
			
		||||
            for (auto it = customdata.layers.begin(); it != customdata.layers.end(); ++it) {
 | 
			
		||||
                if (it->get()->type == cdtype && name == it->get()->name) {
 | 
			
		||||
                    return *it;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return nullptr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const ElemBase * getCustomDataLayerData(const CustomData &customdata, const CustomDataType cdtype, const std::string &name)
 | 
			
		||||
        {
 | 
			
		||||
            const std::shared_ptr<CustomDataLayer> pLayer = getCustomDataLayer(customdata, cdtype, name);
 | 
			
		||||
            if (pLayer && pLayer->data) {
 | 
			
		||||
                return pLayer->data.get();
 | 
			
		||||
            }
 | 
			
		||||
            return nullptr;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,89 +0,0 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "BlenderDNA.h"
 | 
			
		||||
#include "BlenderScene.h"
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
namespace Assimp {
 | 
			
		||||
    namespace Blender {
 | 
			
		||||
        /* CustomData.type from Blender (2.79b) */
 | 
			
		||||
        enum CustomDataType {
 | 
			
		||||
            CD_AUTO_FROM_NAME = -1,
 | 
			
		||||
            CD_MVERT = 0,
 | 
			
		||||
#ifdef DNA_DEPRECATED
 | 
			
		||||
            CD_MSTICKY = 1,  /* DEPRECATED */
 | 
			
		||||
#endif
 | 
			
		||||
            CD_MDEFORMVERT = 2,
 | 
			
		||||
            CD_MEDGE = 3,
 | 
			
		||||
            CD_MFACE = 4,
 | 
			
		||||
            CD_MTFACE = 5,
 | 
			
		||||
            CD_MCOL = 6,
 | 
			
		||||
            CD_ORIGINDEX = 7,
 | 
			
		||||
            CD_NORMAL = 8,
 | 
			
		||||
            /*	CD_POLYINDEX        = 9, */
 | 
			
		||||
            CD_PROP_FLT = 10,
 | 
			
		||||
            CD_PROP_INT = 11,
 | 
			
		||||
            CD_PROP_STR = 12,
 | 
			
		||||
            CD_ORIGSPACE = 13,  /* for modifier stack face location mapping */
 | 
			
		||||
            CD_ORCO = 14,
 | 
			
		||||
            CD_MTEXPOLY = 15,
 | 
			
		||||
            CD_MLOOPUV = 16,
 | 
			
		||||
            CD_MLOOPCOL = 17,
 | 
			
		||||
            CD_TANGENT = 18,
 | 
			
		||||
            CD_MDISPS = 19,
 | 
			
		||||
            CD_PREVIEW_MCOL = 20,  /* for displaying weightpaint colors */
 | 
			
		||||
            /*	CD_ID_MCOL          = 21, */
 | 
			
		||||
            CD_TEXTURE_MLOOPCOL = 22,
 | 
			
		||||
            CD_CLOTH_ORCO = 23,
 | 
			
		||||
            CD_RECAST = 24,
 | 
			
		||||
 | 
			
		||||
            /* BMESH ONLY START */
 | 
			
		||||
            CD_MPOLY = 25,
 | 
			
		||||
            CD_MLOOP = 26,
 | 
			
		||||
            CD_SHAPE_KEYINDEX = 27,
 | 
			
		||||
            CD_SHAPEKEY = 28,
 | 
			
		||||
            CD_BWEIGHT = 29,
 | 
			
		||||
            CD_CREASE = 30,
 | 
			
		||||
            CD_ORIGSPACE_MLOOP = 31,
 | 
			
		||||
            CD_PREVIEW_MLOOPCOL = 32,
 | 
			
		||||
            CD_BM_ELEM_PYPTR = 33,
 | 
			
		||||
            /* BMESH ONLY END */
 | 
			
		||||
 | 
			
		||||
            CD_PAINT_MASK = 34,
 | 
			
		||||
            CD_GRID_PAINT_MASK = 35,
 | 
			
		||||
            CD_MVERT_SKIN = 36,
 | 
			
		||||
            CD_FREESTYLE_EDGE = 37,
 | 
			
		||||
            CD_FREESTYLE_FACE = 38,
 | 
			
		||||
            CD_MLOOPTANGENT = 39,
 | 
			
		||||
            CD_TESSLOOPNORMAL = 40,
 | 
			
		||||
            CD_CUSTOMLOOPNORMAL = 41,
 | 
			
		||||
 | 
			
		||||
            CD_NUMTYPES = 42
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
        *   @brief  check if given cdtype is valid (ie >= 0 and < CD_NUMTYPES)
 | 
			
		||||
        *   @param[in]  cdtype to check
 | 
			
		||||
        *   @return true when valid
 | 
			
		||||
        */
 | 
			
		||||
        bool isValidCustomDataType(const int cdtype);
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
        *   @brief  returns CustomDataLayer ptr for given cdtype and name
 | 
			
		||||
        *   @param[in]  customdata CustomData to search for wanted layer
 | 
			
		||||
        *   @param[in]  cdtype to search for
 | 
			
		||||
        *   @param[in]  name to search for
 | 
			
		||||
        *   @return CustomDataLayer * or nullptr if not found
 | 
			
		||||
        */
 | 
			
		||||
        std::shared_ptr<CustomDataLayer> getCustomDataLayer(const CustomData &customdata, CustomDataType cdtype, const std::string &name);
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
        *   @brief  returns CustomDataLayer data ptr for given cdtype and name
 | 
			
		||||
        *   @param[in]  customdata CustomData to search for wanted layer
 | 
			
		||||
        *   @param[in]  cdtype to search for
 | 
			
		||||
        *   @param[in]  name to search for
 | 
			
		||||
        *   @return * to struct data or nullptr if not found
 | 
			
		||||
        */
 | 
			
		||||
        const ElemBase * getCustomDataLayerData(const CustomData &customdata, CustomDataType cdtype, const std::string &name);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										375
									
								
								thirdparty/assimp/code/Blender/BlenderDNA.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										375
									
								
								thirdparty/assimp/code/Blender/BlenderDNA.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,375 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2019, 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.cpp
 | 
			
		||||
 *  @brief Implementation of the Blender `DNA`, that is its own
 | 
			
		||||
 *    serialized set of data structures.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
 | 
			
		||||
#include "BlenderDNA.h"
 | 
			
		||||
#include <assimp/StreamReader.h>
 | 
			
		||||
#include <assimp/fast_atof.h>
 | 
			
		||||
#include <assimp/TinyFormatter.h>
 | 
			
		||||
 | 
			
		||||
using namespace Assimp;
 | 
			
		||||
using namespace Assimp::Blender;
 | 
			
		||||
using namespace Assimp::Formatter;
 | 
			
		||||
 | 
			
		||||
static bool match4(StreamReaderAny& stream, const char* string) {
 | 
			
		||||
    ai_assert( nullptr != string );
 | 
			
		||||
    char tmp[4];
 | 
			
		||||
    tmp[ 0 ] = ( stream ).GetI1();
 | 
			
		||||
    tmp[ 1 ] = ( stream ).GetI1();
 | 
			
		||||
    tmp[ 2 ] = ( stream ).GetI1();
 | 
			
		||||
    tmp[ 3 ] = ( stream ).GetI1();
 | 
			
		||||
    return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct Type {
 | 
			
		||||
    size_t size;
 | 
			
		||||
    std::string name;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void DNAParser::Parse ()
 | 
			
		||||
{
 | 
			
		||||
    StreamReaderAny& stream = *db.reader.get();
 | 
			
		||||
    DNA& dna = db.dna;
 | 
			
		||||
 | 
			
		||||
    if(!match4(stream,"SDNA")) {
 | 
			
		||||
        throw DeadlyImportError("BlenderDNA: Expected SDNA chunk");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // name dictionary
 | 
			
		||||
    if(!match4(stream,"NAME")) {
 | 
			
		||||
        throw DeadlyImportError("BlenderDNA: Expected NAME field");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::vector<std::string> names (stream.GetI4());
 | 
			
		||||
    for(std::string& s : names) {
 | 
			
		||||
        while (char c = stream.GetI1()) {
 | 
			
		||||
            s += c;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // type dictionary
 | 
			
		||||
    for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
 | 
			
		||||
    if(!match4(stream,"TYPE")) {
 | 
			
		||||
        throw DeadlyImportError("BlenderDNA: Expected TYPE field");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::vector<Type> types (stream.GetI4());
 | 
			
		||||
    for(Type& s : types) {
 | 
			
		||||
        while (char c = stream.GetI1()) {
 | 
			
		||||
            s.name += c;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // type length dictionary
 | 
			
		||||
    for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
 | 
			
		||||
    if(!match4(stream,"TLEN")) {
 | 
			
		||||
        throw DeadlyImportError("BlenderDNA: Expected TLEN field");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(Type& s : types) {
 | 
			
		||||
        s.size = stream.GetI2();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // structures dictionary
 | 
			
		||||
    for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
 | 
			
		||||
    if(!match4(stream,"STRC")) {
 | 
			
		||||
        throw DeadlyImportError("BlenderDNA: Expected STRC field");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    size_t end = stream.GetI4(), fields = 0;
 | 
			
		||||
 | 
			
		||||
    dna.structures.reserve(end);
 | 
			
		||||
    for(size_t i = 0; i != end; ++i) {
 | 
			
		||||
 | 
			
		||||
        uint16_t n = stream.GetI2();
 | 
			
		||||
        if (n >= types.size()) {
 | 
			
		||||
            throw DeadlyImportError((format(),
 | 
			
		||||
                "BlenderDNA: Invalid type index in structure name" ,n,
 | 
			
		||||
                " (there are only ", types.size(), " entries)"
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // maintain separate indexes
 | 
			
		||||
        dna.indices[types[n].name] = dna.structures.size();
 | 
			
		||||
 | 
			
		||||
        dna.structures.push_back(Structure());
 | 
			
		||||
        Structure& s = dna.structures.back();
 | 
			
		||||
        s.name  = types[n].name;
 | 
			
		||||
        //s.index = dna.structures.size()-1;
 | 
			
		||||
 | 
			
		||||
        n = stream.GetI2();
 | 
			
		||||
        s.fields.reserve(n);
 | 
			
		||||
 | 
			
		||||
        size_t offset = 0;
 | 
			
		||||
        for (size_t m = 0; m < n; ++m, ++fields) {
 | 
			
		||||
 | 
			
		||||
            uint16_t j = stream.GetI2();
 | 
			
		||||
            if (j >= types.size()) {
 | 
			
		||||
                throw DeadlyImportError((format(),
 | 
			
		||||
                    "BlenderDNA: Invalid type index in structure field ", j,
 | 
			
		||||
                    " (there are only ", types.size(), " entries)"
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
            s.fields.push_back(Field());
 | 
			
		||||
            Field& f = s.fields.back();
 | 
			
		||||
            f.offset = offset;
 | 
			
		||||
 | 
			
		||||
            f.type = types[j].name;
 | 
			
		||||
            f.size = types[j].size;
 | 
			
		||||
 | 
			
		||||
            j = stream.GetI2();
 | 
			
		||||
            if (j >= names.size()) {
 | 
			
		||||
                throw DeadlyImportError((format(),
 | 
			
		||||
                    "BlenderDNA: Invalid name index in structure field ", j,
 | 
			
		||||
                    " (there are only ", names.size(), " entries)"
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            f.name = names[j];
 | 
			
		||||
            f.flags = 0u;
 | 
			
		||||
 | 
			
		||||
            // pointers always specify the size of the pointee instead of their own.
 | 
			
		||||
            // The pointer asterisk remains a property of the lookup name.
 | 
			
		||||
            if (f.name[0] == '*') {
 | 
			
		||||
                f.size = db.i64bit ? 8 : 4;
 | 
			
		||||
                f.flags |= FieldFlag_Pointer;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // arrays, however, specify the size of a single element so we
 | 
			
		||||
            // need to parse the (possibly multi-dimensional) array declaration
 | 
			
		||||
            // in order to obtain the actual size of the array in the file.
 | 
			
		||||
            // Also we need to alter the lookup name to include no array
 | 
			
		||||
            // brackets anymore or size fixup won't work (if our size does
 | 
			
		||||
            // not match the size read from the DNA).
 | 
			
		||||
            if (*f.name.rbegin() == ']') {
 | 
			
		||||
                const std::string::size_type rb = f.name.find('[');
 | 
			
		||||
                if (rb == std::string::npos) {
 | 
			
		||||
                    throw DeadlyImportError((format(),
 | 
			
		||||
                        "BlenderDNA: Encountered invalid array declaration ",
 | 
			
		||||
                        f.name
 | 
			
		||||
                    ));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                f.flags |= FieldFlag_Array;
 | 
			
		||||
                DNA::ExtractArraySize(f.name,f.array_sizes);
 | 
			
		||||
                f.name = f.name.substr(0,rb);
 | 
			
		||||
 | 
			
		||||
                f.size *= f.array_sizes[0] * f.array_sizes[1];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // maintain separate indexes
 | 
			
		||||
            s.indices[f.name] = s.fields.size()-1;
 | 
			
		||||
            offset += f.size;
 | 
			
		||||
        }
 | 
			
		||||
        s.size = offset;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ASSIMP_LOG_DEBUG_F( "BlenderDNA: Got ", dna.structures.size()," structures with totally ",fields," fields");
 | 
			
		||||
 | 
			
		||||
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
 | 
			
		||||
    dna.DumpToFile();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    dna.AddPrimitiveStructures();
 | 
			
		||||
    dna.RegisterConverters();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
 | 
			
		||||
 | 
			
		||||
#include <fstream>
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void DNA :: DumpToFile()
 | 
			
		||||
{
 | 
			
		||||
    // we don't bother using the VFS here for this is only for debugging.
 | 
			
		||||
    // (and all your bases are belong to us).
 | 
			
		||||
 | 
			
		||||
    std::ofstream f("dna.txt");
 | 
			
		||||
    if (f.fail()) {
 | 
			
		||||
        ASSIMP_LOG_ERROR("Could not dump dna to dna.txt");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    f << "Field format: type name offset size" << "\n";
 | 
			
		||||
    f << "Structure format: name size" << "\n";
 | 
			
		||||
 | 
			
		||||
    for(const Structure& s : structures) {
 | 
			
		||||
        f << s.name << " " << s.size << "\n\n";
 | 
			
		||||
        for(const Field& ff : s.fields) {
 | 
			
		||||
            f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << "\n";
 | 
			
		||||
        }
 | 
			
		||||
        f << "\n";
 | 
			
		||||
    }
 | 
			
		||||
    f << std::flush;
 | 
			
		||||
 | 
			
		||||
    ASSIMP_LOG_INFO("BlenderDNA: Dumped dna to dna.txt");
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
/*static*/ void  DNA :: ExtractArraySize(
 | 
			
		||||
    const std::string& out,
 | 
			
		||||
    size_t array_sizes[2]
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    array_sizes[0] = array_sizes[1] = 1;
 | 
			
		||||
    std::string::size_type pos = out.find('[');
 | 
			
		||||
    if (pos++ == std::string::npos) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    array_sizes[0] = strtoul10(&out[pos]);
 | 
			
		||||
 | 
			
		||||
    pos = out.find('[',pos);
 | 
			
		||||
    if (pos++ == std::string::npos) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    array_sizes[1] = strtoul10(&out[pos]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
std::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure(
 | 
			
		||||
    const Structure& structure,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
) const
 | 
			
		||||
{
 | 
			
		||||
    std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name);
 | 
			
		||||
    if (it == converters.end()) {
 | 
			
		||||
        return std::shared_ptr< ElemBase >();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
 | 
			
		||||
    (structure.*((*it).second.second))(ret,db);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
DNA::FactoryPair DNA :: GetBlobToStructureConverter(
 | 
			
		||||
    const Structure& structure,
 | 
			
		||||
    const FileDatabase& /*db*/
 | 
			
		||||
) const
 | 
			
		||||
{
 | 
			
		||||
    std::map<std::string,  FactoryPair>::const_iterator it = converters.find(structure.name);
 | 
			
		||||
    return it == converters.end() ? FactoryPair() : (*it).second;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// basing on http://www.blender.org/development/architecture/notes-on-sdna/
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void DNA :: AddPrimitiveStructures()
 | 
			
		||||
{
 | 
			
		||||
    // NOTE: these are just dummies. Their presence enforces
 | 
			
		||||
    // Structure::Convert<target_type> to be called on these
 | 
			
		||||
    // empty structures. These converters are special
 | 
			
		||||
    // overloads which scan the name of the structure and
 | 
			
		||||
    // perform the required data type conversion if one
 | 
			
		||||
    // of these special names is found in the structure
 | 
			
		||||
    // in question.
 | 
			
		||||
 | 
			
		||||
    indices["int"] = structures.size();
 | 
			
		||||
    structures.push_back( Structure() );
 | 
			
		||||
    structures.back().name = "int";
 | 
			
		||||
    structures.back().size = 4;
 | 
			
		||||
 | 
			
		||||
    indices["short"] = structures.size();
 | 
			
		||||
    structures.push_back( Structure() );
 | 
			
		||||
    structures.back().name = "short";
 | 
			
		||||
    structures.back().size = 2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    indices["char"] = structures.size();
 | 
			
		||||
    structures.push_back( Structure() );
 | 
			
		||||
    structures.back().name = "char";
 | 
			
		||||
    structures.back().size = 1;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    indices["float"] = structures.size();
 | 
			
		||||
    structures.push_back( Structure() );
 | 
			
		||||
    structures.back().name = "float";
 | 
			
		||||
    structures.back().size = 4;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    indices["double"] = structures.size();
 | 
			
		||||
    structures.push_back( Structure() );
 | 
			
		||||
    structures.back().name = "double";
 | 
			
		||||
    structures.back().size = 8;
 | 
			
		||||
 | 
			
		||||
    // no long, seemingly.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void SectionParser :: Next()
 | 
			
		||||
{
 | 
			
		||||
    stream.SetCurrentPos(current.start + current.size);
 | 
			
		||||
 | 
			
		||||
    const char tmp[] = {
 | 
			
		||||
        (const char)stream.GetI1(),
 | 
			
		||||
        (const char)stream.GetI1(),
 | 
			
		||||
        (const char)stream.GetI1(),
 | 
			
		||||
        (const char)stream.GetI1()
 | 
			
		||||
    };
 | 
			
		||||
    current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
 | 
			
		||||
 | 
			
		||||
    current.size = stream.GetI4();
 | 
			
		||||
    current.address.val = ptr64 ? stream.GetU8() : stream.GetU4();
 | 
			
		||||
 | 
			
		||||
    current.dna_index = stream.GetI4();
 | 
			
		||||
    current.num = stream.GetI4();
 | 
			
		||||
 | 
			
		||||
    current.start = stream.GetCurrentPos();
 | 
			
		||||
    if (stream.GetRemainingSizeToLimit() < current.size) {
 | 
			
		||||
        throw DeadlyImportError("BLEND: invalid size of file block");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
 | 
			
		||||
    ASSIMP_LOG_DEBUG(current.id);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										844
									
								
								thirdparty/assimp/code/Blender/BlenderDNA.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										844
									
								
								thirdparty/assimp/code/Blender/BlenderDNA.h
									
									
									
									
										vendored
									
									
								
							@@ -1,844 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2019, 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 <assimp/BaseImporter.h>
 | 
			
		||||
#include <assimp/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 locations 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;
 | 
			
		||||
 | 
			
		||||
    // --------------------------------------------------------
 | 
			
		||||
    /**
 | 
			
		||||
    *   @brief  field parsing for dynamic vectors
 | 
			
		||||
    *   @param[in]  out vector of struct to be filled
 | 
			
		||||
    *   @param[in]  name of field
 | 
			
		||||
    *   @param[in]  db to access the file, dna, ...
 | 
			
		||||
    *   @return true when read was successful
 | 
			
		||||
    */
 | 
			
		||||
    template <int error_policy, template <typename> class TOUT, typename T>
 | 
			
		||||
    bool ReadFieldPtrVector(vector<TOUT<T>>&out, const char* name, const FileDatabase& db) const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    *   @brief  parses raw customdata
 | 
			
		||||
    *   @param[in]  out shared_ptr to be filled
 | 
			
		||||
    *   @param[in]  cdtype customdata type to read
 | 
			
		||||
    *   @param[in]  name of field ptr
 | 
			
		||||
    *   @param[in]  db to access the file, dna, ...
 | 
			
		||||
    *   @return true when read was successful
 | 
			
		||||
    */
 | 
			
		||||
    template <int error_policy>
 | 
			
		||||
    bool ReadCustomDataPtr(std::shared_ptr<ElemBase>&out, int cdtype, 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>") {
 | 
			
		||||
        ASSIMP_LOG_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 DeadlyImportError("Constructing BlenderDNA Structure encountered an error");
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------------------------------
 | 
			
		||||
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 doesn'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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
*   @brief  read CustomData's data to ptr to mem
 | 
			
		||||
*   @param[out] out memory ptr to set
 | 
			
		||||
*   @param[in]  cdtype  to read
 | 
			
		||||
*   @param[in]  cnt cnt of elements to read
 | 
			
		||||
*   @param[in]  db to read elements from
 | 
			
		||||
*   @return true when ok
 | 
			
		||||
*/
 | 
			
		||||
bool readCustomData(std::shared_ptr<ElemBase> &out, int cdtype, size_t cnt, const FileDatabase &db);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    } // end Blend
 | 
			
		||||
} // end Assimp
 | 
			
		||||
 | 
			
		||||
#include "BlenderDNA.inl"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										856
									
								
								thirdparty/assimp/code/Blender/BlenderDNA.inl
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										856
									
								
								thirdparty/assimp/code/Blender/BlenderDNA.inl
									
									
									
									
										vendored
									
									
								
							@@ -1,856 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2019, 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.inl
 | 
			
		||||
 *  @brief Blender `DNA` (file format specification embedded in
 | 
			
		||||
 *    blend file itself) loader.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef INCLUDED_AI_BLEND_DNA_INL
 | 
			
		||||
#define INCLUDED_AI_BLEND_DNA_INL
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <assimp/TinyFormatter.h>
 | 
			
		||||
 | 
			
		||||
namespace Assimp {
 | 
			
		||||
namespace Blender {
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
const Field& Structure :: operator [] (const std::string& ss) const
 | 
			
		||||
{
 | 
			
		||||
    std::map<std::string, size_t>::const_iterator it = indices.find(ss);
 | 
			
		||||
    if (it == indices.end()) {
 | 
			
		||||
        throw Error((Formatter::format(),
 | 
			
		||||
            "BlendDNA: Did not find a field named `",ss,"` in structure `",name,"`"
 | 
			
		||||
            ));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return fields[(*it).second];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
const Field* Structure :: Get (const std::string& ss) const
 | 
			
		||||
{
 | 
			
		||||
    std::map<std::string, size_t>::const_iterator it = indices.find(ss);
 | 
			
		||||
    return it == indices.end() ? NULL : &fields[(*it).second];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
const Field& Structure :: operator [] (const size_t i) const
 | 
			
		||||
{
 | 
			
		||||
    if (i >= fields.size()) {
 | 
			
		||||
        throw Error((Formatter::format(),
 | 
			
		||||
            "BlendDNA: There is no field with index `",i,"` in structure `",name,"`"
 | 
			
		||||
            ));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return fields[i];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <typename T> std::shared_ptr<ElemBase> Structure :: Allocate() const
 | 
			
		||||
{
 | 
			
		||||
    return std::shared_ptr<T>(new T());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <typename T> void Structure :: Convert(
 | 
			
		||||
    std::shared_ptr<ElemBase> in,
 | 
			
		||||
    const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    Convert<T> (*static_cast<T*> ( in.get() ),db);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <int error_policy, typename T, size_t M>
 | 
			
		||||
void Structure :: ReadFieldArray(T (& out)[M], const char* name, const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    const StreamReaderAny::pos old = db.reader->GetCurrentPos();
 | 
			
		||||
    try {
 | 
			
		||||
        const Field& f = (*this)[name];
 | 
			
		||||
        const Structure& s = db.dna[f.type];
 | 
			
		||||
 | 
			
		||||
        // is the input actually an array?
 | 
			
		||||
        if (!(f.flags & FieldFlag_Array)) {
 | 
			
		||||
            throw Error((Formatter::format(),"Field `",name,"` of structure `",
 | 
			
		||||
                this->name,"` ought to be an array of size ",M
 | 
			
		||||
                ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        db.reader->IncPtr(f.offset);
 | 
			
		||||
 | 
			
		||||
        // size conversions are always allowed, regardless of error_policy
 | 
			
		||||
        unsigned int i = 0;
 | 
			
		||||
        for(; i < std::min(f.array_sizes[0],M); ++i) {
 | 
			
		||||
            s.Convert(out[i],db);
 | 
			
		||||
        }
 | 
			
		||||
        for(; i < M; ++i) {
 | 
			
		||||
            _defaultInitializer<ErrorPolicy_Igno>()(out[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    catch (const Error& e) {
 | 
			
		||||
        _defaultInitializer<error_policy>()(out,e.what());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // and recover the previous stream position
 | 
			
		||||
    db.reader->SetCurrentPos(old);
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
 | 
			
		||||
    ++db.stats().fields_read;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <int error_policy, typename T, size_t M, size_t N>
 | 
			
		||||
void Structure :: ReadFieldArray2(T (& out)[M][N], const char* name, const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    const StreamReaderAny::pos old = db.reader->GetCurrentPos();
 | 
			
		||||
    try {
 | 
			
		||||
        const Field& f = (*this)[name];
 | 
			
		||||
        const Structure& s = db.dna[f.type];
 | 
			
		||||
 | 
			
		||||
        // is the input actually an array?
 | 
			
		||||
        if (!(f.flags & FieldFlag_Array)) {
 | 
			
		||||
            throw Error((Formatter::format(),"Field `",name,"` of structure `",
 | 
			
		||||
                this->name,"` ought to be an array of size ",M,"*",N
 | 
			
		||||
                ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        db.reader->IncPtr(f.offset);
 | 
			
		||||
 | 
			
		||||
        // size conversions are always allowed, regardless of error_policy
 | 
			
		||||
        unsigned int i = 0;
 | 
			
		||||
        for(; i < std::min(f.array_sizes[0],M); ++i) {
 | 
			
		||||
            unsigned int j = 0;
 | 
			
		||||
            for(; j < std::min(f.array_sizes[1],N); ++j) {
 | 
			
		||||
                s.Convert(out[i][j],db);
 | 
			
		||||
            }
 | 
			
		||||
            for(; j < N; ++j) {
 | 
			
		||||
                _defaultInitializer<ErrorPolicy_Igno>()(out[i][j]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        for(; i < M; ++i) {
 | 
			
		||||
            _defaultInitializer<ErrorPolicy_Igno>()(out[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    catch (const Error& e) {
 | 
			
		||||
        _defaultInitializer<error_policy>()(out,e.what());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // and recover the previous stream position
 | 
			
		||||
    db.reader->SetCurrentPos(old);
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
 | 
			
		||||
    ++db.stats().fields_read;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <int error_policy, template <typename> class TOUT, typename T>
 | 
			
		||||
bool Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabase& db,
 | 
			
		||||
    bool non_recursive /*= false*/) const
 | 
			
		||||
{
 | 
			
		||||
    const StreamReaderAny::pos old = db.reader->GetCurrentPos();
 | 
			
		||||
    Pointer ptrval;
 | 
			
		||||
    const Field* f;
 | 
			
		||||
    try {
 | 
			
		||||
        f = &(*this)[name];
 | 
			
		||||
 | 
			
		||||
        // sanity check, should never happen if the genblenddna script is right
 | 
			
		||||
        if (!(f->flags & FieldFlag_Pointer)) {
 | 
			
		||||
            throw Error((Formatter::format(),"Field `",name,"` of structure `",
 | 
			
		||||
                this->name,"` ought to be a pointer"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        db.reader->IncPtr(f->offset);
 | 
			
		||||
        Convert(ptrval,db);
 | 
			
		||||
        // actually it is meaningless on which Structure the Convert is called
 | 
			
		||||
        // because the `Pointer` argument triggers a special implementation.
 | 
			
		||||
    }
 | 
			
		||||
    catch (const Error& e) {
 | 
			
		||||
        _defaultInitializer<error_policy>()(out,e.what());
 | 
			
		||||
 | 
			
		||||
        out.reset();
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // resolve the pointer and load the corresponding structure
 | 
			
		||||
    const bool res = ResolvePointer(out,ptrval,db,*f, non_recursive);
 | 
			
		||||
 | 
			
		||||
    if(!non_recursive) {
 | 
			
		||||
        // and recover the previous stream position
 | 
			
		||||
        db.reader->SetCurrentPos(old);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
 | 
			
		||||
    ++db.stats().fields_read;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <int error_policy, template <typename> class TOUT, typename T, size_t N>
 | 
			
		||||
bool Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
 | 
			
		||||
    const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    // XXX see if we can reduce this to call to the 'normal' ReadFieldPtr
 | 
			
		||||
    const StreamReaderAny::pos old = db.reader->GetCurrentPos();
 | 
			
		||||
    Pointer ptrval[N];
 | 
			
		||||
    const Field* f;
 | 
			
		||||
    try {
 | 
			
		||||
        f = &(*this)[name];
 | 
			
		||||
 | 
			
		||||
        // sanity check, should never happen if the genblenddna script is right
 | 
			
		||||
        if ((FieldFlag_Pointer|FieldFlag_Pointer) != (f->flags & (FieldFlag_Pointer|FieldFlag_Pointer))) {
 | 
			
		||||
            throw Error((Formatter::format(),"Field `",name,"` of structure `",
 | 
			
		||||
                this->name,"` ought to be a pointer AND an array"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        db.reader->IncPtr(f->offset);
 | 
			
		||||
 | 
			
		||||
        size_t i = 0;
 | 
			
		||||
        for(; i < std::min(f->array_sizes[0],N); ++i) {
 | 
			
		||||
            Convert(ptrval[i],db);
 | 
			
		||||
        }
 | 
			
		||||
        for(; i < N; ++i) {
 | 
			
		||||
            _defaultInitializer<ErrorPolicy_Igno>()(ptrval[i]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // actually it is meaningless on which Structure the Convert is called
 | 
			
		||||
        // because the `Pointer` argument triggers a special implementation.
 | 
			
		||||
    }
 | 
			
		||||
    catch (const Error& e) {
 | 
			
		||||
        _defaultInitializer<error_policy>()(out,e.what());
 | 
			
		||||
        for(size_t i = 0; i < N; ++i) {
 | 
			
		||||
            out[i].reset();
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool res = true;
 | 
			
		||||
    for(size_t i = 0; i < N; ++i) {
 | 
			
		||||
        // resolve the pointer and load the corresponding structure
 | 
			
		||||
        res = ResolvePointer(out[i],ptrval[i],db,*f) && res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // and recover the previous stream position
 | 
			
		||||
    db.reader->SetCurrentPos(old);
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
 | 
			
		||||
    ++db.stats().fields_read;
 | 
			
		||||
#endif
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <int error_policy, typename T>
 | 
			
		||||
void Structure :: ReadField(T& out, const char* name, const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    const StreamReaderAny::pos old = db.reader->GetCurrentPos();
 | 
			
		||||
    try {
 | 
			
		||||
        const Field& f = (*this)[name];
 | 
			
		||||
        // find the structure definition pertaining to this field
 | 
			
		||||
        const Structure& s = db.dna[f.type];
 | 
			
		||||
 | 
			
		||||
        db.reader->IncPtr(f.offset);
 | 
			
		||||
        s.Convert(out,db);
 | 
			
		||||
    }
 | 
			
		||||
    catch (const Error& e) {
 | 
			
		||||
        _defaultInitializer<error_policy>()(out,e.what());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // and recover the previous stream position
 | 
			
		||||
    db.reader->SetCurrentPos(old);
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
 | 
			
		||||
    ++db.stats().fields_read;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
// field parsing for raw untyped data (like CustomDataLayer.data)
 | 
			
		||||
template <int error_policy>
 | 
			
		||||
bool Structure::ReadCustomDataPtr(std::shared_ptr<ElemBase>&out, int cdtype, const char* name, const FileDatabase& db) const {
 | 
			
		||||
 | 
			
		||||
	const StreamReaderAny::pos old = db.reader->GetCurrentPos();
 | 
			
		||||
 | 
			
		||||
	Pointer ptrval;
 | 
			
		||||
	const Field* f;
 | 
			
		||||
	try	{
 | 
			
		||||
		f = &(*this)[name];
 | 
			
		||||
 | 
			
		||||
		// sanity check, should never happen if the genblenddna script is right
 | 
			
		||||
		if (!(f->flags & FieldFlag_Pointer)) {
 | 
			
		||||
			throw Error((Formatter::format(), "Field `", name, "` of structure `",
 | 
			
		||||
				this->name, "` ought to be a pointer"));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		db.reader->IncPtr(f->offset);
 | 
			
		||||
		Convert(ptrval, db);
 | 
			
		||||
		// actually it is meaningless on which Structure the Convert is called
 | 
			
		||||
		// because the `Pointer` argument triggers a special implementation.
 | 
			
		||||
	}
 | 
			
		||||
	catch (const Error& e) {
 | 
			
		||||
		_defaultInitializer<error_policy>()(out, e.what());
 | 
			
		||||
		out.reset();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool readOk = true;
 | 
			
		||||
	if (ptrval.val)	{
 | 
			
		||||
		// get block for ptr
 | 
			
		||||
		const FileBlockHead* block = LocateFileBlockForAddress(ptrval, db);
 | 
			
		||||
		db.reader->SetCurrentPos(block->start + static_cast<size_t>((ptrval.val - block->address.val)));
 | 
			
		||||
		// read block->num instances of given type to out
 | 
			
		||||
		readOk = readCustomData(out, cdtype, block->num, db);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// and recover the previous stream position
 | 
			
		||||
	db.reader->SetCurrentPos(old);
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
 | 
			
		||||
	++db.stats().fields_read;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return readOk;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <int error_policy, template <typename> class TOUT, typename T>
 | 
			
		||||
bool Structure::ReadFieldPtrVector(vector<TOUT<T>>&out, const char* name, const FileDatabase& db) const {
 | 
			
		||||
	out.clear();
 | 
			
		||||
 | 
			
		||||
	const StreamReaderAny::pos old = db.reader->GetCurrentPos();
 | 
			
		||||
 | 
			
		||||
	Pointer ptrval;
 | 
			
		||||
	const Field* f;
 | 
			
		||||
	try	{
 | 
			
		||||
		f = &(*this)[name];
 | 
			
		||||
 | 
			
		||||
		// sanity check, should never happen if the genblenddna script is right
 | 
			
		||||
		if (!(f->flags & FieldFlag_Pointer)) {
 | 
			
		||||
			throw Error((Formatter::format(), "Field `", name, "` of structure `",
 | 
			
		||||
				this->name, "` ought to be a pointer"));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		db.reader->IncPtr(f->offset);
 | 
			
		||||
		Convert(ptrval, db);
 | 
			
		||||
		// actually it is meaningless on which Structure the Convert is called
 | 
			
		||||
		// because the `Pointer` argument triggers a special implementation.
 | 
			
		||||
	}
 | 
			
		||||
	catch (const Error& e) {
 | 
			
		||||
		_defaultInitializer<error_policy>()(out, e.what());
 | 
			
		||||
		out.clear();
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (ptrval.val)	{
 | 
			
		||||
		// find the file block the pointer is pointing to
 | 
			
		||||
		const FileBlockHead* block = LocateFileBlockForAddress(ptrval, db);
 | 
			
		||||
		db.reader->SetCurrentPos(block->start + static_cast<size_t>((ptrval.val - block->address.val)));
 | 
			
		||||
		// FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
 | 
			
		||||
		// I really ought to improve StreamReader to work with 64 bit indices exclusively.
 | 
			
		||||
 | 
			
		||||
		const Structure& s = db.dna[f->type];
 | 
			
		||||
		for (size_t i = 0; i < block->num; ++i)	{
 | 
			
		||||
			TOUT<T> p(new T);
 | 
			
		||||
			s.Convert(*p, db);
 | 
			
		||||
			out.push_back(p);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	db.reader->SetCurrentPos(old);
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
 | 
			
		||||
	++db.stats().fields_read;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <template <typename> class TOUT, typename T>
 | 
			
		||||
bool Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db,
 | 
			
		||||
    const Field& f,
 | 
			
		||||
    bool non_recursive /*= false*/) const
 | 
			
		||||
{
 | 
			
		||||
    out.reset(); // ensure null pointers work
 | 
			
		||||
    if (!ptrval.val) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    const Structure& s = db.dna[f.type];
 | 
			
		||||
    // find the file block the pointer is pointing to
 | 
			
		||||
    const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
 | 
			
		||||
 | 
			
		||||
    // also determine the target type from the block header
 | 
			
		||||
    // and check if it matches the type which we expect.
 | 
			
		||||
    const Structure& ss = db.dna[block->dna_index];
 | 
			
		||||
    if (ss != s) {
 | 
			
		||||
        throw Error((Formatter::format(),"Expected target to be of type `",s.name,
 | 
			
		||||
            "` but seemingly it is a `",ss.name,"` instead"
 | 
			
		||||
            ));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // try to retrieve the object from the cache
 | 
			
		||||
    db.cache(out).get(s,out,ptrval);
 | 
			
		||||
    if (out) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // seek to this location, but save the previous stream pointer.
 | 
			
		||||
    const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
 | 
			
		||||
    db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
 | 
			
		||||
    // FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
 | 
			
		||||
    // I really ought to improve StreamReader to work with 64 bit indices exclusively.
 | 
			
		||||
 | 
			
		||||
    // continue conversion after allocating the required storage
 | 
			
		||||
    size_t num = block->size / ss.size;
 | 
			
		||||
    T* o = _allocate(out,num);
 | 
			
		||||
 | 
			
		||||
    // cache the object before we convert it to avoid cyclic recursion.
 | 
			
		||||
    db.cache(out).set(s,out,ptrval);
 | 
			
		||||
 | 
			
		||||
    // if the non_recursive flag is set, we don't do anything but leave
 | 
			
		||||
    // the cursor at the correct position to resolve the object.
 | 
			
		||||
    if (!non_recursive) {
 | 
			
		||||
        for (size_t i = 0; i < num; ++i,++o) {
 | 
			
		||||
            s.Convert(*o,db);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        db.reader->SetCurrentPos(pold);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
 | 
			
		||||
    if(out) {
 | 
			
		||||
        ++db.stats().pointers_resolved;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
inline bool Structure :: ResolvePointer( std::shared_ptr< FileOffset >& out, const Pointer & ptrval,
 | 
			
		||||
    const FileDatabase& db,
 | 
			
		||||
    const Field&,
 | 
			
		||||
    bool) const
 | 
			
		||||
{
 | 
			
		||||
    // Currently used exclusively by PackedFile::data to represent
 | 
			
		||||
    // a simple offset into the mapped BLEND file.
 | 
			
		||||
    out.reset();
 | 
			
		||||
    if (!ptrval.val) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // find the file block the pointer is pointing to
 | 
			
		||||
    const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
 | 
			
		||||
 | 
			
		||||
    out =  std::shared_ptr< FileOffset > (new FileOffset());
 | 
			
		||||
    out->val = block->start+ static_cast<size_t>((ptrval.val - block->address.val) );
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <template <typename> class TOUT, typename T>
 | 
			
		||||
bool Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
 | 
			
		||||
    const FileDatabase& db,
 | 
			
		||||
    const Field& f,
 | 
			
		||||
    bool) const
 | 
			
		||||
{
 | 
			
		||||
    // This is a function overload, not a template specialization. According to
 | 
			
		||||
    // the partial ordering rules, it should be selected by the compiler
 | 
			
		||||
    // for array-of-pointer inputs, i.e. Object::mats.
 | 
			
		||||
 | 
			
		||||
    out.reset();
 | 
			
		||||
    if (!ptrval.val) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // find the file block the pointer is pointing to
 | 
			
		||||
    const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
 | 
			
		||||
    const size_t num = block->size / (db.i64bit?8:4);
 | 
			
		||||
 | 
			
		||||
    // keep the old stream position
 | 
			
		||||
    const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
 | 
			
		||||
    db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
 | 
			
		||||
 | 
			
		||||
    bool res = false;
 | 
			
		||||
    // allocate raw storage for the array
 | 
			
		||||
    out.resize(num);
 | 
			
		||||
    for (size_t i = 0; i< num; ++i) {
 | 
			
		||||
        Pointer val;
 | 
			
		||||
        Convert(val,db);
 | 
			
		||||
 | 
			
		||||
        // and resolve the pointees
 | 
			
		||||
        res = ResolvePointer(out[i],val,db,f) && res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    db.reader->SetCurrentPos(pold);
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> bool Structure :: ResolvePointer<std::shared_ptr,ElemBase>(std::shared_ptr<ElemBase>& out,
 | 
			
		||||
    const Pointer & ptrval,
 | 
			
		||||
    const FileDatabase& db,
 | 
			
		||||
    const Field&,
 | 
			
		||||
    bool
 | 
			
		||||
) const
 | 
			
		||||
{
 | 
			
		||||
    // Special case when the data type needs to be determined at runtime.
 | 
			
		||||
    // Less secure than in the `strongly-typed` case.
 | 
			
		||||
 | 
			
		||||
    out.reset();
 | 
			
		||||
    if (!ptrval.val) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // find the file block the pointer is pointing to
 | 
			
		||||
    const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
 | 
			
		||||
 | 
			
		||||
    // determine the target type from the block header
 | 
			
		||||
    const Structure& s = db.dna[block->dna_index];
 | 
			
		||||
 | 
			
		||||
    // try to retrieve the object from the cache
 | 
			
		||||
    db.cache(out).get(s,out,ptrval);
 | 
			
		||||
    if (out) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // seek to this location, but save the previous stream pointer.
 | 
			
		||||
    const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
 | 
			
		||||
    db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
 | 
			
		||||
    // FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
 | 
			
		||||
    // I really ought to improve StreamReader to work with 64 bit indices exclusively.
 | 
			
		||||
 | 
			
		||||
    // continue conversion after allocating the required storage
 | 
			
		||||
    DNA::FactoryPair builders = db.dna.GetBlobToStructureConverter(s,db);
 | 
			
		||||
    if (!builders.first) {
 | 
			
		||||
        // this might happen if DNA::RegisterConverters hasn't been called so far
 | 
			
		||||
        // or if the target type is not contained in `our` DNA.
 | 
			
		||||
        out.reset();
 | 
			
		||||
        ASSIMP_LOG_WARN_F( "Failed to find a converter for the `",s.name,"` structure" );
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // allocate the object hull
 | 
			
		||||
    out = (s.*builders.first)();
 | 
			
		||||
 | 
			
		||||
    // cache the object immediately to prevent infinite recursion in a
 | 
			
		||||
    // circular list with a single element (i.e. a self-referencing element).
 | 
			
		||||
    db.cache(out).set(s,out,ptrval);
 | 
			
		||||
 | 
			
		||||
    // and do the actual conversion
 | 
			
		||||
    (s.*builders.second)(out,db);
 | 
			
		||||
    db.reader->SetCurrentPos(pold);
 | 
			
		||||
 | 
			
		||||
    // store a pointer to the name string of the actual type
 | 
			
		||||
    // in the object itself. This allows the conversion code
 | 
			
		||||
    // to perform additional type checking.
 | 
			
		||||
    out->dna_type = s.name.c_str();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
 | 
			
		||||
    ++db.stats().pointers_resolved;
 | 
			
		||||
#endif
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
const FileBlockHead* Structure :: LocateFileBlockForAddress(const Pointer & ptrval, const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    // the file blocks appear in list sorted by
 | 
			
		||||
    // with ascending base addresses so we can run a
 | 
			
		||||
    // binary search to locate the pointer quickly.
 | 
			
		||||
 | 
			
		||||
    // NOTE: Blender seems to distinguish between side-by-side
 | 
			
		||||
    // data (stored in the same data block) and far pointers,
 | 
			
		||||
    // which are only used for structures starting with an ID.
 | 
			
		||||
    // We don't need to make this distinction, our algorithm
 | 
			
		||||
    // works regardless where the data is stored.
 | 
			
		||||
    vector<FileBlockHead>::const_iterator it = std::lower_bound(db.entries.begin(),db.entries.end(),ptrval);
 | 
			
		||||
    if (it == db.entries.end()) {
 | 
			
		||||
        // this is crucial, pointers may not be invalid.
 | 
			
		||||
        // this is either a corrupted file or an attempted attack.
 | 
			
		||||
        throw DeadlyImportError((Formatter::format(),"Failure resolving pointer 0x",
 | 
			
		||||
            std::hex,ptrval.val,", no file block falls into this address range"
 | 
			
		||||
            ));
 | 
			
		||||
    }
 | 
			
		||||
    if (ptrval.val >= (*it).address.val + (*it).size) {
 | 
			
		||||
        throw DeadlyImportError((Formatter::format(),"Failure resolving pointer 0x",
 | 
			
		||||
            std::hex,ptrval.val,", nearest file block starting at 0x",
 | 
			
		||||
            (*it).address.val," ends at 0x",
 | 
			
		||||
            (*it).address.val + (*it).size
 | 
			
		||||
            ));
 | 
			
		||||
    }
 | 
			
		||||
    return &*it;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
// NOTE: The MSVC debugger keeps showing up this annoying `a cast to a smaller data type has
 | 
			
		||||
// caused a loss of data`-warning. Avoid this warning by a masking with an appropriate bitmask.
 | 
			
		||||
 | 
			
		||||
template <typename T> struct signless;
 | 
			
		||||
template <> struct signless<char> {typedef unsigned char type;};
 | 
			
		||||
template <> struct signless<short> {typedef unsigned short type;};
 | 
			
		||||
template <> struct signless<int> {typedef unsigned int type;};
 | 
			
		||||
template <> struct signless<unsigned char> { typedef unsigned char type; };
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct static_cast_silent {
 | 
			
		||||
    template <typename V>
 | 
			
		||||
    T operator()(V in) {
 | 
			
		||||
        return static_cast<T>(in & static_cast<typename signless<T>::type>(-1));
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <> struct static_cast_silent<float> {
 | 
			
		||||
    template <typename V> float  operator()(V in) {
 | 
			
		||||
        return static_cast<float> (in);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <> struct static_cast_silent<double> {
 | 
			
		||||
    template <typename V> double operator()(V in) {
 | 
			
		||||
        return static_cast<double>(in);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
template <typename T> inline void ConvertDispatcher(T& out, const Structure& in,const FileDatabase& db)
 | 
			
		||||
{
 | 
			
		||||
    if (in.name == "int") {
 | 
			
		||||
        out = static_cast_silent<T>()(db.reader->GetU4());
 | 
			
		||||
    }
 | 
			
		||||
    else if (in.name == "short") {
 | 
			
		||||
        out = static_cast_silent<T>()(db.reader->GetU2());
 | 
			
		||||
    }
 | 
			
		||||
    else if (in.name == "char") {
 | 
			
		||||
        out = static_cast_silent<T>()(db.reader->GetU1());
 | 
			
		||||
    }
 | 
			
		||||
    else if (in.name == "float") {
 | 
			
		||||
        out = static_cast<T>(db.reader->GetF4());
 | 
			
		||||
    }
 | 
			
		||||
    else if (in.name == "double") {
 | 
			
		||||
        out = static_cast<T>(db.reader->GetF8());
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        throw DeadlyImportError("Unknown source for conversion to primitive data type: "+in.name);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
template <> inline void Structure :: Convert<int>    (int& dest,const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    ConvertDispatcher(dest,*this,db);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
template<> inline void Structure :: Convert<short>  (short& dest,const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    // automatic rescaling from short to float and vice versa (seems to be used by normals)
 | 
			
		||||
    if (name == "float") {
 | 
			
		||||
        float f = db.reader->GetF4();
 | 
			
		||||
        if ( f > 1.0f )
 | 
			
		||||
            f = 1.0f;
 | 
			
		||||
        dest = static_cast<short>( f * 32767.f);
 | 
			
		||||
        //db.reader->IncPtr(-4);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    else if (name == "double") {
 | 
			
		||||
        dest = static_cast<short>(db.reader->GetF8() * 32767.);
 | 
			
		||||
        //db.reader->IncPtr(-8);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    ConvertDispatcher(dest,*this,db);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
template <> inline void Structure :: Convert<char>   (char& dest,const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    // automatic rescaling from char to float and vice versa (seems useful for RGB colors)
 | 
			
		||||
    if (name == "float") {
 | 
			
		||||
        dest = static_cast<char>(db.reader->GetF4() * 255.f);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    else if (name == "double") {
 | 
			
		||||
        dest = static_cast<char>(db.reader->GetF8() * 255.f);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    ConvertDispatcher(dest,*this,db);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
template <> inline void Structure::Convert<unsigned char>(unsigned char& dest, const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
	// automatic rescaling from char to float and vice versa (seems useful for RGB colors)
 | 
			
		||||
	if (name == "float") {
 | 
			
		||||
		dest = static_cast<unsigned char>(db.reader->GetF4() * 255.f);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	else if (name == "double") {
 | 
			
		||||
		dest = static_cast<unsigned char>(db.reader->GetF8() * 255.f);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	ConvertDispatcher(dest, *this, db);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
template <> inline void Structure :: Convert<float>  (float& dest,const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    // automatic rescaling from char to float and vice versa (seems useful for RGB colors)
 | 
			
		||||
    if (name == "char") {
 | 
			
		||||
        dest = db.reader->GetI1() / 255.f;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // automatic rescaling from short to float and vice versa (used by normals)
 | 
			
		||||
    else if (name == "short") {
 | 
			
		||||
        dest = db.reader->GetI2() / 32767.f;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    ConvertDispatcher(dest,*this,db);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
template <> inline void Structure :: Convert<double> (double& dest,const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    if (name == "char") {
 | 
			
		||||
        dest = db.reader->GetI1() / 255.;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    else if (name == "short") {
 | 
			
		||||
        dest = db.reader->GetI2() / 32767.;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    ConvertDispatcher(dest,*this,db);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
template <> inline void Structure :: Convert<Pointer> (Pointer& dest,const FileDatabase& db) const
 | 
			
		||||
{
 | 
			
		||||
    if (db.i64bit) {
 | 
			
		||||
        dest.val = db.reader->GetU8();
 | 
			
		||||
        //db.reader->IncPtr(-8);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    dest.val = db.reader->GetU4();
 | 
			
		||||
    //db.reader->IncPtr(-4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
const Structure& DNA :: operator [] (const std::string& ss) const
 | 
			
		||||
{
 | 
			
		||||
    std::map<std::string, size_t>::const_iterator it = indices.find(ss);
 | 
			
		||||
    if (it == indices.end()) {
 | 
			
		||||
        throw Error((Formatter::format(),
 | 
			
		||||
            "BlendDNA: Did not find a structure named `",ss,"`"
 | 
			
		||||
            ));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return structures[(*it).second];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
const Structure* DNA :: Get (const std::string& ss) const
 | 
			
		||||
{
 | 
			
		||||
    std::map<std::string, size_t>::const_iterator it = indices.find(ss);
 | 
			
		||||
    return it == indices.end() ? NULL : &structures[(*it).second];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
const Structure& DNA :: operator [] (const size_t i) const
 | 
			
		||||
{
 | 
			
		||||
    if (i >= structures.size()) {
 | 
			
		||||
        throw Error((Formatter::format(),
 | 
			
		||||
            "BlendDNA: There is no structure with index `",i,"`"
 | 
			
		||||
            ));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return structures[i];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <template <typename> class TOUT> template <typename T> void ObjectCache<TOUT> :: get (
 | 
			
		||||
    const Structure& s,
 | 
			
		||||
    TOUT<T>& out,
 | 
			
		||||
    const Pointer& ptr
 | 
			
		||||
) const {
 | 
			
		||||
 | 
			
		||||
    if(s.cache_idx == static_cast<size_t>(-1)) {
 | 
			
		||||
        s.cache_idx = db.next_cache_idx++;
 | 
			
		||||
        caches.resize(db.next_cache_idx);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    typename StructureCache::const_iterator it = caches[s.cache_idx].find(ptr);
 | 
			
		||||
    if (it != caches[s.cache_idx].end()) {
 | 
			
		||||
        out = std::static_pointer_cast<T>( (*it).second );
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
 | 
			
		||||
        ++db.stats().cache_hits;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    // otherwise, out remains untouched
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <template <typename> class TOUT> template <typename T> void ObjectCache<TOUT> :: set (
 | 
			
		||||
    const Structure& s,
 | 
			
		||||
    const TOUT<T>& out,
 | 
			
		||||
    const Pointer& ptr
 | 
			
		||||
) {
 | 
			
		||||
    if(s.cache_idx == static_cast<size_t>(-1)) {
 | 
			
		||||
        s.cache_idx = db.next_cache_idx++;
 | 
			
		||||
        caches.resize(db.next_cache_idx);
 | 
			
		||||
    }
 | 
			
		||||
    caches[s.cache_idx][ptr] = std::static_pointer_cast<ElemBase>( out );
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
 | 
			
		||||
    ++db.stats().cached_objects;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										206
									
								
								thirdparty/assimp/code/Blender/BlenderIntermediate.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										206
									
								
								thirdparty/assimp/code/Blender/BlenderIntermediate.h
									
									
									
									
										vendored
									
									
								
							@@ -1,206 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2019, 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  BlenderIntermediate.h
 | 
			
		||||
 *  @brief Internal utility structures for the BlenderLoader. It also serves
 | 
			
		||||
 *    as master include file for the whole (internal) Blender subsystem.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef INCLUDED_AI_BLEND_INTERMEDIATE_H
 | 
			
		||||
#define INCLUDED_AI_BLEND_INTERMEDIATE_H
 | 
			
		||||
 | 
			
		||||
#include "BlenderLoader.h"
 | 
			
		||||
#include "BlenderDNA.h"
 | 
			
		||||
#include "BlenderScene.h"
 | 
			
		||||
#include <deque>
 | 
			
		||||
#include <assimp/material.h>
 | 
			
		||||
 | 
			
		||||
struct aiTexture;
 | 
			
		||||
 | 
			
		||||
namespace Assimp {
 | 
			
		||||
namespace Blender {
 | 
			
		||||
 | 
			
		||||
    // --------------------------------------------------------------------
 | 
			
		||||
    /** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
 | 
			
		||||
    // --------------------------------------------------------------------
 | 
			
		||||
    template <template <typename,typename> class TCLASS, typename T>
 | 
			
		||||
    struct TempArray    {
 | 
			
		||||
        typedef TCLASS< T*,std::allocator<T*> > mywrap;
 | 
			
		||||
 | 
			
		||||
        TempArray() {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~TempArray () {
 | 
			
		||||
            for(T* elem : arr) {
 | 
			
		||||
                delete elem;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void dismiss() {
 | 
			
		||||
            arr.clear();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mywrap* operator -> () {
 | 
			
		||||
            return &arr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        operator mywrap& () {
 | 
			
		||||
            return arr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        operator const mywrap& () const {
 | 
			
		||||
            return arr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mywrap& get () {
 | 
			
		||||
            return arr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const mywrap& get () const {
 | 
			
		||||
            return arr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        T* operator[] (size_t idx) const {
 | 
			
		||||
            return arr[idx];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        T*& operator[] (size_t idx) {
 | 
			
		||||
            return arr[idx];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        // no copy semantics
 | 
			
		||||
        void operator= (const TempArray&)  {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        TempArray(const TempArray& /*arr*/) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        mywrap arr;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#   pragma warning(disable:4351)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // As counter-intuitive as it may seem, a comparator must return false for equal values.
 | 
			
		||||
    // The C++ standard defines and expects this behavior: true if lhs < rhs, false otherwise.
 | 
			
		||||
    struct ObjectCompare {
 | 
			
		||||
        bool operator() (const Object* left, const Object* right) const {
 | 
			
		||||
            return ::strncmp(left->id.name, right->id.name, strlen( left->id.name ) ) < 0;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // When keeping objects in sets, sort them by their name.
 | 
			
		||||
    typedef std::set<const Object*, ObjectCompare> ObjectSet;
 | 
			
		||||
 | 
			
		||||
    // --------------------------------------------------------------------
 | 
			
		||||
    /** ConversionData acts as intermediate storage location for
 | 
			
		||||
     *  the various ConvertXXX routines in BlenderImporter.*/
 | 
			
		||||
    // --------------------------------------------------------------------
 | 
			
		||||
    struct ConversionData
 | 
			
		||||
    {
 | 
			
		||||
        ConversionData(const FileDatabase& db)
 | 
			
		||||
            : sentinel_cnt()
 | 
			
		||||
            , next_texture()
 | 
			
		||||
            , db(db)
 | 
			
		||||
        {}
 | 
			
		||||
 | 
			
		||||
        // As counter-intuitive as it may seem, a comparator must return false for equal values.
 | 
			
		||||
        // The C++ standard defines and expects this behavior: true if lhs < rhs, false otherwise.
 | 
			
		||||
        struct ObjectCompare {
 | 
			
		||||
            bool operator() (const Object* left, const Object* right) const {
 | 
			
		||||
                return ::strncmp( left->id.name, right->id.name, strlen( left->id.name ) ) < 0;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        ObjectSet objects;
 | 
			
		||||
 | 
			
		||||
        TempArray <std::vector, aiMesh> meshes;
 | 
			
		||||
        TempArray <std::vector, aiCamera> cameras;
 | 
			
		||||
        TempArray <std::vector, aiLight> lights;
 | 
			
		||||
        TempArray <std::vector, aiMaterial> materials;
 | 
			
		||||
        TempArray <std::vector, aiTexture> textures;
 | 
			
		||||
 | 
			
		||||
        // set of all materials referenced by at least one mesh in the scene
 | 
			
		||||
        std::deque< std::shared_ptr< Material > > materials_raw;
 | 
			
		||||
 | 
			
		||||
        // counter to name sentinel textures inserted as substitutes for procedural textures.
 | 
			
		||||
        unsigned int sentinel_cnt;
 | 
			
		||||
 | 
			
		||||
        // next texture ID for each texture type, respectively
 | 
			
		||||
        unsigned int next_texture[aiTextureType_UNKNOWN+1];
 | 
			
		||||
 | 
			
		||||
        // original file data
 | 
			
		||||
        const FileDatabase& db;
 | 
			
		||||
    };
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#   pragma warning(default:4351)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
inline const char* GetTextureTypeDisplayString(Tex::Type t)
 | 
			
		||||
{
 | 
			
		||||
    switch (t)  {
 | 
			
		||||
    case Tex::Type_CLOUDS       :  return  "Clouds";
 | 
			
		||||
    case Tex::Type_WOOD         :  return  "Wood";
 | 
			
		||||
    case Tex::Type_MARBLE       :  return  "Marble";
 | 
			
		||||
    case Tex::Type_MAGIC        :  return  "Magic";
 | 
			
		||||
    case Tex::Type_BLEND        :  return  "Blend";
 | 
			
		||||
    case Tex::Type_STUCCI       :  return  "Stucci";
 | 
			
		||||
    case Tex::Type_NOISE        :  return  "Noise";
 | 
			
		||||
    case Tex::Type_PLUGIN       :  return  "Plugin";
 | 
			
		||||
    case Tex::Type_MUSGRAVE     :  return  "Musgrave";
 | 
			
		||||
    case Tex::Type_VORONOI      :  return  "Voronoi";
 | 
			
		||||
    case Tex::Type_DISTNOISE    :  return  "DistortedNoise";
 | 
			
		||||
    case Tex::Type_ENVMAP       :  return  "EnvMap";
 | 
			
		||||
    case Tex::Type_IMAGE        :  return  "Image";
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    return "<Unknown>";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // ! Blender
 | 
			
		||||
} // ! Assimp
 | 
			
		||||
 | 
			
		||||
#endif // ! INCLUDED_AI_BLEND_INTERMEDIATE_H
 | 
			
		||||
							
								
								
									
										1397
									
								
								thirdparty/assimp/code/Blender/BlenderLoader.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1397
									
								
								thirdparty/assimp/code/Blender/BlenderLoader.cpp
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										240
									
								
								thirdparty/assimp/code/Blender/BlenderLoader.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										240
									
								
								thirdparty/assimp/code/Blender/BlenderLoader.h
									
									
									
									
										vendored
									
									
								
							@@ -1,240 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2019, 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  BlenderLoader.h
 | 
			
		||||
 *  @brief Declaration of the Blender 3D (*.blend) importer class.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef INCLUDED_AI_BLEND_LOADER_H
 | 
			
		||||
#define INCLUDED_AI_BLEND_LOADER_H
 | 
			
		||||
 | 
			
		||||
#include <assimp/BaseImporter.h>
 | 
			
		||||
#include <assimp/LogAux.h>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
struct aiNode;
 | 
			
		||||
struct aiMesh;
 | 
			
		||||
struct aiLight;
 | 
			
		||||
struct aiCamera;
 | 
			
		||||
struct aiMaterial;
 | 
			
		||||
 | 
			
		||||
namespace Assimp    {
 | 
			
		||||
 | 
			
		||||
    // TinyFormatter.h
 | 
			
		||||
    namespace Formatter {
 | 
			
		||||
        template <typename T,typename TR, typename A> class basic_formatter;
 | 
			
		||||
        typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // BlenderDNA.h
 | 
			
		||||
    namespace Blender {
 | 
			
		||||
        class  FileDatabase;
 | 
			
		||||
        struct ElemBase;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // BlenderScene.h
 | 
			
		||||
    namespace Blender {
 | 
			
		||||
        struct Scene;
 | 
			
		||||
        struct Object;
 | 
			
		||||
        struct Mesh;
 | 
			
		||||
        struct Camera;
 | 
			
		||||
        struct Lamp;
 | 
			
		||||
        struct MTex;
 | 
			
		||||
        struct Image;
 | 
			
		||||
        struct Material;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // BlenderIntermediate.h
 | 
			
		||||
    namespace Blender {
 | 
			
		||||
        struct ConversionData;
 | 
			
		||||
        template <template <typename,typename> class TCLASS, typename T> struct TempArray;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // BlenderModifier.h
 | 
			
		||||
    namespace Blender {
 | 
			
		||||
        class BlenderModifierShowcase;
 | 
			
		||||
        class BlenderModifier;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------------------
 | 
			
		||||
/** Load blenders official binary format. The actual file structure (the `DNA` how they
 | 
			
		||||
 *  call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
 | 
			
		||||
 *  conversion from intermediate format to aiScene. */
 | 
			
		||||
// -------------------------------------------------------------------------------------------
 | 
			
		||||
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    BlenderImporter();
 | 
			
		||||
    ~BlenderImporter();
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    bool CanRead( const std::string& pFile,
 | 
			
		||||
        IOSystem* pIOHandler,
 | 
			
		||||
        bool checkSig
 | 
			
		||||
    ) const;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    const aiImporterDesc* GetInfo () const;
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    void GetExtensionList(std::set<std::string>& app);
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    void SetupProperties(const Importer* pImp);
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    void InternReadFile( const std::string& pFile,
 | 
			
		||||
        aiScene* pScene,
 | 
			
		||||
        IOSystem* pIOHandler
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    void ParseBlendFile(Blender::FileDatabase& out,
 | 
			
		||||
        std::shared_ptr<IOStream> stream
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    void ExtractScene(Blender::Scene& out,
 | 
			
		||||
        const Blender::FileDatabase& file
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    void ConvertBlendFile(aiScene* out,
 | 
			
		||||
        const Blender::Scene& in,
 | 
			
		||||
        const Blender::FileDatabase& file
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    aiNode* ConvertNode(const Blender::Scene& in,
 | 
			
		||||
        const Blender::Object* obj,
 | 
			
		||||
        Blender::ConversionData& conv_info,
 | 
			
		||||
        const aiMatrix4x4& parentTransform
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    void ConvertMesh(const Blender::Scene& in,
 | 
			
		||||
        const Blender::Object* obj,
 | 
			
		||||
        const Blender::Mesh* mesh,
 | 
			
		||||
        Blender::ConversionData& conv_data,
 | 
			
		||||
        Blender::TempArray<std::vector,aiMesh>& temp
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    aiLight* ConvertLight(const Blender::Scene& in,
 | 
			
		||||
        const Blender::Object* obj,
 | 
			
		||||
        const Blender::Lamp* mesh,
 | 
			
		||||
        Blender::ConversionData& conv_data
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    aiCamera* ConvertCamera(const Blender::Scene& in,
 | 
			
		||||
        const Blender::Object* obj,
 | 
			
		||||
        const Blender::Camera* mesh,
 | 
			
		||||
        Blender::ConversionData& conv_data
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    void BuildDefaultMaterial(
 | 
			
		||||
        Blender::ConversionData& conv_data
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    void AddBlendParams(
 | 
			
		||||
        aiMaterial* result,
 | 
			
		||||
        const Blender::Material* source
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    void BuildMaterials(
 | 
			
		||||
        Blender::ConversionData& conv_data
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    void ResolveTexture(
 | 
			
		||||
        aiMaterial* out,
 | 
			
		||||
        const Blender::Material* mat,
 | 
			
		||||
        const Blender::MTex* tex,
 | 
			
		||||
        Blender::ConversionData& conv_data
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    void ResolveImage(
 | 
			
		||||
        aiMaterial* out,
 | 
			
		||||
        const Blender::Material* mat,
 | 
			
		||||
        const Blender::MTex* tex,
 | 
			
		||||
        const Blender::Image* img,
 | 
			
		||||
        Blender::ConversionData& conv_data
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    void AddSentinelTexture(
 | 
			
		||||
        aiMaterial* out,
 | 
			
		||||
        const Blender::Material* mat,
 | 
			
		||||
        const Blender::MTex* tex,
 | 
			
		||||
        Blender::ConversionData& conv_data
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
private: // static stuff, mostly logging and error reporting.
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    static void CheckActualType(const Blender::ElemBase* dt,
 | 
			
		||||
        const char* check
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    static void NotSupportedObjectType(const Blender::Object* obj,
 | 
			
		||||
        const char* type
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    Blender::BlenderModifierShowcase* modifier_cache;
 | 
			
		||||
 | 
			
		||||
}; // !class BlenderImporter
 | 
			
		||||
 | 
			
		||||
} // end of namespace Assimp
 | 
			
		||||
#endif // AI_UNREALIMPORTER_H_INC
 | 
			
		||||
							
								
								
									
										299
									
								
								thirdparty/assimp/code/Blender/BlenderModifier.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										299
									
								
								thirdparty/assimp/code/Blender/BlenderModifier.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,299 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2019, 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  BlenderModifier.cpp
 | 
			
		||||
 *  @brief Implementation of some blender modifiers (i.e subdivision, mirror).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
 | 
			
		||||
 | 
			
		||||
#include "BlenderModifier.h"
 | 
			
		||||
#include <assimp/SceneCombiner.h>
 | 
			
		||||
#include <assimp/Subdivision.h>
 | 
			
		||||
#include <assimp/scene.h>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
using namespace Assimp;
 | 
			
		||||
using namespace Assimp::Blender;
 | 
			
		||||
 | 
			
		||||
template <typename T> BlenderModifier* god() {
 | 
			
		||||
    return new T();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// add all available modifiers here
 | 
			
		||||
typedef BlenderModifier* (*fpCreateModifier)();
 | 
			
		||||
static const fpCreateModifier creators[] = {
 | 
			
		||||
        &god<BlenderModifier_Mirror>,
 | 
			
		||||
        &god<BlenderModifier_Subdivision>,
 | 
			
		||||
 | 
			
		||||
        NULL // sentinel
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
struct SharedModifierData : ElemBase
 | 
			
		||||
{
 | 
			
		||||
    ModifierData modifier;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object )
 | 
			
		||||
{
 | 
			
		||||
    size_t cnt = 0u, ful = 0u;
 | 
			
		||||
 | 
			
		||||
    // NOTE: this cast is potentially unsafe by design, so we need to perform type checks before
 | 
			
		||||
    // we're allowed to dereference the pointers without risking to crash. We might still be
 | 
			
		||||
    // invoking UB btw - we're assuming that the ModifierData member of the respective modifier
 | 
			
		||||
    // structures is at offset sizeof(vftable) with no padding.
 | 
			
		||||
    const SharedModifierData* cur = static_cast<const SharedModifierData *> ( orig_object.modifiers.first.get() );
 | 
			
		||||
    for (; cur; cur =  static_cast<const SharedModifierData *> ( cur->modifier.next.get() ), ++ful) {
 | 
			
		||||
        ai_assert(cur->dna_type);
 | 
			
		||||
 | 
			
		||||
        const Structure* s = conv_data.db.dna.Get( cur->dna_type );
 | 
			
		||||
        if (!s) {
 | 
			
		||||
            ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // this is a common trait of all XXXMirrorData structures in BlenderDNA
 | 
			
		||||
        const Field* f = s->Get("modifier");
 | 
			
		||||
        if (!f || f->offset != 0) {
 | 
			
		||||
            ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0");
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        s = conv_data.db.dna.Get( f->type );
 | 
			
		||||
        if (!s || s->name != "ModifierData") {
 | 
			
		||||
            ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member");
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // now, we can be sure that we should be fine to dereference *cur* as
 | 
			
		||||
        // ModifierData (with the above note).
 | 
			
		||||
        const ModifierData& dat = cur->modifier;
 | 
			
		||||
 | 
			
		||||
        const fpCreateModifier* curgod = creators;
 | 
			
		||||
        std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end();
 | 
			
		||||
 | 
			
		||||
        for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly
 | 
			
		||||
            if (curmod == endmod) {
 | 
			
		||||
                cached_modifiers->push_back((*curgod)());
 | 
			
		||||
 | 
			
		||||
                endmod = cached_modifiers->end();
 | 
			
		||||
                curmod = endmod-1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            BlenderModifier* const modifier = *curmod;
 | 
			
		||||
            if(modifier->IsActive(dat)) {
 | 
			
		||||
                modifier->DoIt(out,conv_data,*static_cast<const ElemBase *>(cur),in,orig_object);
 | 
			
		||||
                cnt++;
 | 
			
		||||
 | 
			
		||||
                curgod = NULL;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (curgod) {
 | 
			
		||||
            ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ",dat.name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Even though we managed to resolve some or all of the modifiers on this
 | 
			
		||||
    // object, we still can't say whether our modifier implementations were
 | 
			
		||||
    // able to fully do their job.
 | 
			
		||||
    if (ful) {
 | 
			
		||||
        ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name,
 | 
			
		||||
            "`, check log messages above for errors");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
 | 
			
		||||
{
 | 
			
		||||
    return modin.type == ModifierData::eModifierType_Mirror;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void  BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data,  const ElemBase& orig_modifier,
 | 
			
		||||
    const Scene& /*in*/,
 | 
			
		||||
    const Object& orig_object )
 | 
			
		||||
{
 | 
			
		||||
    // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
 | 
			
		||||
    const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier);
 | 
			
		||||
    ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
 | 
			
		||||
 | 
			
		||||
    conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes);
 | 
			
		||||
 | 
			
		||||
    // XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ...
 | 
			
		||||
 | 
			
		||||
    // take all input meshes and clone them
 | 
			
		||||
    for (unsigned int i = 0; i < out.mNumMeshes; ++i) {
 | 
			
		||||
        aiMesh* mesh;
 | 
			
		||||
        SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]);
 | 
			
		||||
 | 
			
		||||
        const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f;
 | 
			
		||||
        const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f;
 | 
			
		||||
        const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f;
 | 
			
		||||
 | 
			
		||||
        if (mir.mirror_ob) {
 | 
			
		||||
            const aiVector3D center( mir.mirror_ob->obmat[3][0],mir.mirror_ob->obmat[3][1],mir.mirror_ob->obmat[3][2] );
 | 
			
		||||
            for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
 | 
			
		||||
                aiVector3D& v = mesh->mVertices[i];
 | 
			
		||||
 | 
			
		||||
                v.x = center.x + xs*(center.x - v.x);
 | 
			
		||||
                v.y = center.y + ys*(center.y - v.y);
 | 
			
		||||
                v.z = center.z + zs*(center.z - v.z);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
 | 
			
		||||
                aiVector3D& v = mesh->mVertices[i];
 | 
			
		||||
                v.x *= xs;v.y *= ys;v.z *= zs;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mesh->mNormals) {
 | 
			
		||||
            for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
 | 
			
		||||
                aiVector3D& v = mesh->mNormals[i];
 | 
			
		||||
                v.x *= xs;v.y *= ys;v.z *= zs;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mesh->mTangents) {
 | 
			
		||||
            for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
 | 
			
		||||
                aiVector3D& v = mesh->mTangents[i];
 | 
			
		||||
                v.x *= xs;v.y *= ys;v.z *= zs;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mesh->mBitangents) {
 | 
			
		||||
            for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
 | 
			
		||||
                aiVector3D& v = mesh->mBitangents[i];
 | 
			
		||||
                v.x *= xs;v.y *= ys;v.z *= zs;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const float us = mir.flag & MirrorModifierData::Flags_MIRROR_U ? -1.f : 1.f;
 | 
			
		||||
        const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f;
 | 
			
		||||
 | 
			
		||||
        for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) {
 | 
			
		||||
            for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
 | 
			
		||||
                aiVector3D& v = mesh->mTextureCoords[n][i];
 | 
			
		||||
                v.x *= us;v.y *= vs;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Only reverse the winding order if an odd number of axes were mirrored.
 | 
			
		||||
        if (xs * ys * zs < 0) {
 | 
			
		||||
            for( unsigned int i = 0; i < mesh->mNumFaces; i++) {
 | 
			
		||||
                aiFace& face = mesh->mFaces[i];
 | 
			
		||||
                for( unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi)
 | 
			
		||||
                    std::swap( face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        conv_data.meshes->push_back(mesh);
 | 
			
		||||
    }
 | 
			
		||||
    unsigned int* nind = new unsigned int[out.mNumMeshes*2];
 | 
			
		||||
 | 
			
		||||
    std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind);
 | 
			
		||||
    std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes,
 | 
			
		||||
        [&out](unsigned int n) { return out.mNumMeshes + n; });
 | 
			
		||||
 | 
			
		||||
    delete[] out.mMeshes;
 | 
			
		||||
    out.mMeshes = nind;
 | 
			
		||||
    out.mNumMeshes *= 2;
 | 
			
		||||
 | 
			
		||||
    ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `",
 | 
			
		||||
        orig_object.id.name,"`");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
 | 
			
		||||
{
 | 
			
		||||
    return modin.type == ModifierData::eModifierType_Subsurf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void  BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data,  const ElemBase& orig_modifier,
 | 
			
		||||
    const Scene& /*in*/,
 | 
			
		||||
    const Object& orig_object )
 | 
			
		||||
{
 | 
			
		||||
    // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
 | 
			
		||||
    const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier);
 | 
			
		||||
    ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
 | 
			
		||||
 | 
			
		||||
    Subdivider::Algorithm algo;
 | 
			
		||||
    switch (mir.subdivType)
 | 
			
		||||
    {
 | 
			
		||||
    case SubsurfModifierData::TYPE_CatmullClarke:
 | 
			
		||||
        algo = Subdivider::CATMULL_CLARKE;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case SubsurfModifierData::TYPE_Simple:
 | 
			
		||||
        ASSIMP_LOG_WARN("BlendModifier: The `SIMPLE` subdivision algorithm is not currently implemented, using Catmull-Clarke");
 | 
			
		||||
        algo = Subdivider::CATMULL_CLARKE;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType);
 | 
			
		||||
        return;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<Subdivider> subd(Subdivider::Create(algo));
 | 
			
		||||
    ai_assert(subd);
 | 
			
		||||
    if ( conv_data.meshes->empty() ) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
 | 
			
		||||
    std::unique_ptr<aiMesh*[]> tempmeshes(new aiMesh*[out.mNumMeshes]());
 | 
			
		||||
 | 
			
		||||
    subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
 | 
			
		||||
    std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes);
 | 
			
		||||
 | 
			
		||||
    ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `",
 | 
			
		||||
        orig_object.id.name,"`");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
 | 
			
		||||
							
								
								
									
										155
									
								
								thirdparty/assimp/code/Blender/BlenderModifier.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										155
									
								
								thirdparty/assimp/code/Blender/BlenderModifier.h
									
									
									
									
										vendored
									
									
								
							@@ -1,155 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2019, 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  BlenderModifier.h
 | 
			
		||||
 *  @brief Declare dedicated helper classes to simulate some blender modifiers (i.e. mirror)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef INCLUDED_AI_BLEND_MODIFIER_H
 | 
			
		||||
#define INCLUDED_AI_BLEND_MODIFIER_H
 | 
			
		||||
 | 
			
		||||
#include "BlenderIntermediate.h"
 | 
			
		||||
 | 
			
		||||
namespace Assimp {
 | 
			
		||||
namespace Blender {
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------------------
 | 
			
		||||
/** 
 | 
			
		||||
 *  Dummy base class for all blender modifiers. Modifiers are reused between imports, so
 | 
			
		||||
 *  they should be stateless and not try to cache model data. 
 | 
			
		||||
 */
 | 
			
		||||
// -------------------------------------------------------------------------------------------
 | 
			
		||||
class BlenderModifier {
 | 
			
		||||
public:
 | 
			
		||||
    /**
 | 
			
		||||
     *  The class destructor, virtual.
 | 
			
		||||
     */
 | 
			
		||||
    virtual ~BlenderModifier() {
 | 
			
		||||
        // empty
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    /** 
 | 
			
		||||
     *  Check if *this* modifier is active, given a ModifierData& block.
 | 
			
		||||
     */
 | 
			
		||||
    virtual bool IsActive( const ModifierData& /*modin*/) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    /** 
 | 
			
		||||
     *  Apply the modifier to a given output node. The original data used
 | 
			
		||||
     *  to construct the node is given as well. Not called unless IsActive()
 | 
			
		||||
     *  was called and gave positive response. 
 | 
			
		||||
     */
 | 
			
		||||
    virtual void DoIt(aiNode& /*out*/,
 | 
			
		||||
        ConversionData& /*conv_data*/,
 | 
			
		||||
        const ElemBase& orig_modifier,
 | 
			
		||||
        const Scene& /*in*/,
 | 
			
		||||
        const Object& /*orig_object*/
 | 
			
		||||
    ) {
 | 
			
		||||
        ASSIMP_LOG_INFO_F("This modifier is not supported, skipping: ",orig_modifier.dna_type );
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------------------
 | 
			
		||||
/** 
 | 
			
		||||
 *  Manage all known modifiers and instance and apply them if necessary 
 | 
			
		||||
 */
 | 
			
		||||
// -------------------------------------------------------------------------------------------
 | 
			
		||||
class BlenderModifierShowcase {
 | 
			
		||||
public:
 | 
			
		||||
    // --------------------
 | 
			
		||||
    /** Apply all requested modifiers provided we support them. */
 | 
			
		||||
    void ApplyModifiers(aiNode& out,
 | 
			
		||||
        ConversionData& conv_data,
 | 
			
		||||
        const Scene& in,
 | 
			
		||||
        const Object& orig_object
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    TempArray< std::vector,BlenderModifier > cached_modifiers;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// MODIFIERS /////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------------------
 | 
			
		||||
/** 
 | 
			
		||||
 *  Mirror modifier. Status: implemented. 
 | 
			
		||||
 */
 | 
			
		||||
// -------------------------------------------------------------------------------------------
 | 
			
		||||
class BlenderModifier_Mirror : public BlenderModifier {
 | 
			
		||||
public:
 | 
			
		||||
    // --------------------
 | 
			
		||||
    virtual bool IsActive( const ModifierData& modin);
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    virtual void DoIt(aiNode& out,
 | 
			
		||||
        ConversionData& conv_data,
 | 
			
		||||
        const ElemBase& orig_modifier,
 | 
			
		||||
        const Scene& in,
 | 
			
		||||
        const Object& orig_object
 | 
			
		||||
    ) ;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------------------
 | 
			
		||||
/** Subdivision modifier. Status: dummy. */
 | 
			
		||||
// -------------------------------------------------------------------------------------------
 | 
			
		||||
class BlenderModifier_Subdivision : public BlenderModifier {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    virtual bool IsActive( const ModifierData& modin);
 | 
			
		||||
 | 
			
		||||
    // --------------------
 | 
			
		||||
    virtual void DoIt(aiNode& out,
 | 
			
		||||
        ConversionData& conv_data,
 | 
			
		||||
        const ElemBase& orig_modifier,
 | 
			
		||||
        const Scene& in,
 | 
			
		||||
        const Object& orig_object
 | 
			
		||||
    ) ;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // !INCLUDED_AI_BLEND_MODIFIER_H
 | 
			
		||||
							
								
								
									
										875
									
								
								thirdparty/assimp/code/Blender/BlenderScene.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										875
									
								
								thirdparty/assimp/code/Blender/BlenderScene.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,875 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (ASSIMP)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2016, ASSIMP Development 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 Development 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  BlenderScene.cpp
 | 
			
		||||
 *  @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
 | 
			
		||||
 | 
			
		||||
#include "BlenderScene.h"
 | 
			
		||||
#include "BlenderSceneGen.h"
 | 
			
		||||
#include "BlenderDNA.h"
 | 
			
		||||
#include "BlenderCustomData.h"
 | 
			
		||||
 | 
			
		||||
using namespace Assimp;
 | 
			
		||||
using namespace Assimp::Blender;
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<Object> (
 | 
			
		||||
    Object& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
 | 
			
		||||
    int temp = 0;
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(temp,"type",db);
 | 
			
		||||
    dest.type = static_cast<Assimp::Blender::Object::Type>(temp);
 | 
			
		||||
    ReadFieldArray2<ErrorPolicy_Warn>(dest.obmat,"obmat",db);
 | 
			
		||||
    ReadFieldArray2<ErrorPolicy_Warn>(dest.parentinv,"parentinv",db);
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Warn>(dest.parsubstr,"parsubstr",db);
 | 
			
		||||
    {
 | 
			
		||||
        std::shared_ptr<Object> parent;
 | 
			
		||||
        ReadFieldPtr<ErrorPolicy_Warn>(parent,"*parent",db);
 | 
			
		||||
        dest.parent = parent.get();
 | 
			
		||||
    }
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.track,"*track",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy,"*proxy",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy_from,"*proxy_from",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy_group,"*proxy_group",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.dup_group,"*dup_group",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Fail>(dest.data,"*data",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.modifiers,"modifiers",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<Group> (
 | 
			
		||||
    Group& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.layer,"layer",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.gobject,"*gobject",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MTex> (
 | 
			
		||||
    MTex& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    int temp_short = 0;
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(temp_short,"mapto",db);
 | 
			
		||||
    dest.mapto = static_cast<Assimp::Blender::MTex::MapType>(temp_short);
 | 
			
		||||
    int temp = 0;
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(temp,"blendtype",db);
 | 
			
		||||
    dest.blendtype = static_cast<Assimp::Blender::MTex::BlendType>(temp);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.object,"*object",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.tex,"*tex",db);
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Igno>(dest.uvname,"uvname",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(temp,"projx",db);
 | 
			
		||||
    dest.projx = static_cast<Assimp::Blender::MTex::Projection>(temp);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(temp,"projy",db);
 | 
			
		||||
    dest.projy = static_cast<Assimp::Blender::MTex::Projection>(temp);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(temp,"projz",db);
 | 
			
		||||
    dest.projz = static_cast<Assimp::Blender::MTex::Projection>(temp);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mapping,"mapping",db);
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Igno>(dest.ofs,"ofs",db);
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Igno>(dest.size,"size",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.rot,"rot",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.texflag,"texflag",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.pmapto,"pmapto",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.pmaptoneg,"pmaptoneg",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.colspecfac,"colspecfac",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mirrfac,"mirrfac",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.alphafac,"alphafac",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.difffac,"difffac",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.specfac,"specfac",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.emitfac,"emitfac",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.hardfac,"hardfac",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.norfac,"norfac",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<TFace> (
 | 
			
		||||
    TFace& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadFieldArray2<ErrorPolicy_Fail>(dest.uv,"uv",db);
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Fail>(dest.col,"col",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<SubsurfModifierData> (
 | 
			
		||||
    SubsurfModifierData& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.modifier,"modifier",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.subdivType,"subdivType",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.levels,"levels",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.renderLevels,"renderLevels",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MFace> (
 | 
			
		||||
    MFace& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.v1,"v1",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.v2,"v2",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.v3,"v3",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.v4,"v4",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.mat_nr,"mat_nr",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<Lamp> (
 | 
			
		||||
    Lamp& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
 | 
			
		||||
    int temp = 0;
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(temp,"type",db);
 | 
			
		||||
    dest.type = static_cast<Assimp::Blender::Lamp::Type>(temp);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flags,"flag",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.energy,"energy",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.dist,"dist",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.spotsize,"spotsize",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.constant_coefficient, "coeff_const", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.linear_coefficient, "coeff_lin", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.quadratic_coefficient, "coeff_quad", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(temp,"falloff_type",db);
 | 
			
		||||
    dest.falloff_type = static_cast<Assimp::Blender::Lamp::FalloffType>(temp);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.area_size,"area_size",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.area_sizey,"area_sizey",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.area_sizez,"area_sizez",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.area_shape,"area_shape",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MDeformWeight> (
 | 
			
		||||
    MDeformWeight& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.def_nr,"def_nr",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.weight,"weight",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<PackedFile> (
 | 
			
		||||
    PackedFile& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.size,"size",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.seek,"seek",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.data,"*data",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<Base> (
 | 
			
		||||
    Base& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
    // note: as per https://github.com/assimp/assimp/issues/128,
 | 
			
		||||
    // reading the Object linked list recursively is prone to stack overflow.
 | 
			
		||||
    // This structure converter is therefore an hand-written exception that
 | 
			
		||||
    // does it iteratively.
 | 
			
		||||
 | 
			
		||||
    const int initial_pos = db.reader->GetCurrentPos();
 | 
			
		||||
 | 
			
		||||
    std::pair<Base*, int> todo = std::make_pair(&dest, initial_pos);
 | 
			
		||||
    for ( ;; ) {
 | 
			
		||||
 | 
			
		||||
        Base& cur_dest = *todo.first;
 | 
			
		||||
        db.reader->SetCurrentPos(todo.second);
 | 
			
		||||
 | 
			
		||||
        // we know that this is a double-linked, circular list which we never
 | 
			
		||||
        // traverse backwards, so don't bother resolving the back links.
 | 
			
		||||
        cur_dest.prev = NULL;
 | 
			
		||||
 | 
			
		||||
        ReadFieldPtr<ErrorPolicy_Warn>(cur_dest.object,"*object",db);
 | 
			
		||||
 | 
			
		||||
        // the return value of ReadFieldPtr indicates whether the object
 | 
			
		||||
        // was already cached. In this case, we don't need to resolve
 | 
			
		||||
        // it again.
 | 
			
		||||
        if(!ReadFieldPtr<ErrorPolicy_Warn>(cur_dest.next,"*next",db, true) && cur_dest.next) {
 | 
			
		||||
            todo = std::make_pair(&*cur_dest.next, db.reader->GetCurrentPos());
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    db.reader->SetCurrentPos(initial_pos + size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MTFace> (
 | 
			
		||||
    MTFace& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadFieldArray2<ErrorPolicy_Fail>(dest.uv,"uv",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<Material> (
 | 
			
		||||
    Material& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.specr,"specr",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.specg,"specg",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.specb,"specb",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.har,"har",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.ambr,"ambr",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.ambg,"ambg",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.ambb,"ambb",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mirr,"mirr",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mirg,"mirg",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mirb,"mirb",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.emit,"emit",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.ray_mirror,"ray_mirror",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.alpha,"alpha",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.ref,"ref",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.translucency,"translucency",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.roughness,"roughness",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.darkness,"darkness",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.refrac,"refrac",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.group,"*group",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.diff_shader,"diff_shader",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.spec_shader,"spec_shader",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.mtex,"*mtex",db);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.amb, "amb", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.ang, "ang", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.spectra, "spectra", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.spec, "spec", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.zoffs, "zoffs", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.add, "add", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.fresnel_mir, "fresnel_mir", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.fresnel_mir_i, "fresnel_mir_i", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.fresnel_tra, "fresnel_tra", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.fresnel_tra_i, "fresnel_tra_i", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.filter, "filter", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.tx_limit, "tx_limit", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.tx_falloff, "tx_falloff", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.gloss_mir, "gloss_mir", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.gloss_tra, "gloss_tra", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.adapt_thresh_mir, "adapt_thresh_mir", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.adapt_thresh_tra, "adapt_thresh_tra", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.aniso_gloss_mir, "aniso_gloss_mir", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.dist_mir, "dist_mir", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.hasize, "hasize", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flaresize, "flaresize", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.subsize, "subsize", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flareboost, "flareboost", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.strand_sta, "strand_sta", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.strand_end, "strand_end", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.strand_ease, "strand_ease", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.strand_surfnor, "strand_surfnor", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.strand_min, "strand_min", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.strand_widthfade, "strand_widthfade", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sbias, "sbias", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.lbias, "lbias", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.shad_alpha, "shad_alpha", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.param, "param", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.rms, "rms", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.rampfac_col, "rampfac_col", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.rampfac_spec, "rampfac_spec", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.friction, "friction", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.fh, "fh", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.reflect, "reflect", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.fhdist, "fhdist", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.xyfrict, "xyfrict", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sss_radius, "sss_radius", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sss_col, "sss_col", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sss_error, "sss_error", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sss_scale, "sss_scale", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sss_ior, "sss_ior", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sss_colfac, "sss_colfac", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sss_texfac, "sss_texfac", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sss_front, "sss_front", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sss_back, "sss_back", db);
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.material_type, "material_type", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.ray_depth, "ray_depth", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.ray_depth_tra, "ray_depth_tra", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.samp_gloss_mir, "samp_gloss_mir", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.samp_gloss_tra, "samp_gloss_tra", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.fadeto_mir, "fadeto_mir", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.shade_flag, "shade_flag", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flarec, "flarec", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.starc, "starc", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.linec, "linec", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.ringc, "ringc", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.pr_lamp, "pr_lamp", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.pr_texture, "pr_texture", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.ml_flag, "ml_flag", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.diff_shader, "diff_shader", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.spec_shader, "spec_shader", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.texco, "texco", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mapto, "mapto", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.ramp_show, "ramp_show", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.pad3, "pad3", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.dynamode, "dynamode", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.pad2, "pad2", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sss_flag, "sss_flag", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.sss_preset, "sss_preset", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.shadowonly_flag, "shadowonly_flag", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.index, "index", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.vcol_alpha, "vcol_alpha", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.pad4, "pad4", db);
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.seed1, "seed1", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.seed2, "seed2", db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MTexPoly> (
 | 
			
		||||
    MTexPoly& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        std::shared_ptr<Image> tpage;
 | 
			
		||||
        ReadFieldPtr<ErrorPolicy_Igno>(tpage,"*tpage",db);
 | 
			
		||||
        dest.tpage = tpage.get();
 | 
			
		||||
    }
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.transp,"transp",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.pad,"pad",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<Mesh> (
 | 
			
		||||
    Mesh& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.totface,"totface",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.totedge,"totedge",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.totvert,"totvert",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.totloop,"totloop",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.totpoly,"totpoly",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.subdiv,"subdiv",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.subdivr,"subdivr",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.subsurftype,"subsurftype",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.smoothresh,"smoothresh",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Fail>(dest.mface,"*mface",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.mtface,"*mtface",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.tface,"*tface",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Fail>(dest.mvert,"*mvert",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.medge,"*medge",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.mloop,"*mloop",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.mloopuv,"*mloopuv",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.mloopcol,"*mloopcol",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.mpoly,"*mpoly",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.mtpoly,"*mtpoly",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.dvert,"*dvert",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.mcol,"*mcol",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Fail>(dest.mat,"**mat",db);
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.vdata, "vdata", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.edata, "edata", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.fdata, "fdata", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.pdata, "pdata", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.ldata, "ldata", db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MDeformVert> (
 | 
			
		||||
    MDeformVert& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.dw,"*dw",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.totweight,"totweight",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<World> (
 | 
			
		||||
    World& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MLoopCol> (
 | 
			
		||||
    MLoopCol& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.r,"r",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.g,"g",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.b,"b",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.a,"a",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MVert> (
 | 
			
		||||
    MVert& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Fail>(dest.co,"co",db);
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Fail>(dest.no,"no",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
 | 
			
		||||
    //ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MEdge> (
 | 
			
		||||
    MEdge& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.v1,"v1",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.v2,"v2",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.crease,"crease",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MLoopUV> (
 | 
			
		||||
    MLoopUV& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Igno>(dest.uv,"uv",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<GroupObject> (
 | 
			
		||||
    GroupObject& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Fail>(dest.prev,"*prev",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Fail>(dest.next,"*next",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.ob,"*ob",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<ListBase> (
 | 
			
		||||
    ListBase& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.first,"*first",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.last,"*last",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MLoop> (
 | 
			
		||||
    MLoop& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.v,"v",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.e,"e",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<ModifierData> (
 | 
			
		||||
    ModifierData& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.next,"*next",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.prev,"*prev",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.type,"type",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Igno>(dest.name,"name",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<ID> (
 | 
			
		||||
    ID& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MCol> (
 | 
			
		||||
    MCol& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.r,"r",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.g,"g",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.b,"b",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.a,"a",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MPoly> (
 | 
			
		||||
    MPoly& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.loopstart,"loopstart",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.totloop,"totloop",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.mat_nr,"mat_nr",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<Scene> (
 | 
			
		||||
    Scene& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.camera,"*camera",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.world,"*world",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.basact,"*basact",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.base,"base",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<Library> (
 | 
			
		||||
    Library& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Fail>(dest.filename,"filename",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.parent,"*parent",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<Tex> (
 | 
			
		||||
    Tex& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
    short temp_short = 0;
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(temp_short,"imaflag",db);
 | 
			
		||||
    dest.imaflag = static_cast<Assimp::Blender::Tex::ImageFlags>(temp_short);
 | 
			
		||||
    int temp = 0;
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(temp,"type",db);
 | 
			
		||||
    dest.type = static_cast<Assimp::Blender::Tex::Type>(temp);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<Camera> (
 | 
			
		||||
    Camera& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
 | 
			
		||||
    int temp = 0;
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(temp,"type",db);
 | 
			
		||||
    dest.type = static_cast<Assimp::Blender::Camera::Type>(temp);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(temp,"flag",db);
 | 
			
		||||
    dest.flag = static_cast<Assimp::Blender::Camera::Type>(temp);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.lens,"lens",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.sensor_x,"sensor_x",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.clipsta,"clipsta",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.clipend,"clipend",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<MirrorModifierData> (
 | 
			
		||||
    MirrorModifierData& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.modifier,"modifier",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.axis,"axis",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.tolerance,"tolerance",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.mirror_ob,"*mirror_ob",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure :: Convert<Image> (
 | 
			
		||||
    Image& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.ok,"ok",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.source,"source",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.type,"type",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.pad,"pad",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.pad1,"pad1",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.lastframe,"lastframe",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.tpageflag,"tpageflag",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.totbind,"totbind",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.xrep,"xrep",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.yrep,"yrep",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.twsta,"twsta",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.twend,"twend",db);
 | 
			
		||||
    ReadFieldPtr<ErrorPolicy_Igno>(dest.packedfile,"*packedfile",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.lastupdate,"lastupdate",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.lastused,"lastused",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.animspeed,"animspeed",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.gen_x,"gen_x",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.gen_y,"gen_y",db);
 | 
			
		||||
    ReadField<ErrorPolicy_Igno>(dest.gen_type,"gen_type",db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure::Convert<CustomData>(
 | 
			
		||||
    CustomData& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Warn>(dest.typemap, "typemap", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.totlayer, "totlayer", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.maxlayer, "maxlayer", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Warn>(dest.totsize, "totsize", db);
 | 
			
		||||
    ReadFieldPtrVector<ErrorPolicy_Warn>(dest.layers, "*layers", db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
template <> void Structure::Convert<CustomDataLayer>(
 | 
			
		||||
    CustomDataLayer& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
{
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.type, "type", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.offset, "offset", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.flag, "flag", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.active, "active", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.active_rnd, "active_rnd", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.active_clone, "active_clone", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.active_mask, "active_mask", db);
 | 
			
		||||
    ReadField<ErrorPolicy_Fail>(dest.uid, "uid", db);
 | 
			
		||||
    ReadFieldArray<ErrorPolicy_Warn>(dest.name, "name", db);
 | 
			
		||||
    ReadCustomDataPtr<ErrorPolicy_Fail>(dest.data, dest.type, "*data", db);
 | 
			
		||||
 | 
			
		||||
    db.reader->IncPtr(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------------
 | 
			
		||||
void DNA::RegisterConverters() {
 | 
			
		||||
 | 
			
		||||
    converters["Object"] = DNA::FactoryPair( &Structure::Allocate<Object>, &Structure::Convert<Object> );
 | 
			
		||||
    converters["Group"] = DNA::FactoryPair( &Structure::Allocate<Group>, &Structure::Convert<Group> );
 | 
			
		||||
    converters["MTex"] = DNA::FactoryPair( &Structure::Allocate<MTex>, &Structure::Convert<MTex> );
 | 
			
		||||
    converters["TFace"] = DNA::FactoryPair( &Structure::Allocate<TFace>, &Structure::Convert<TFace> );
 | 
			
		||||
    converters["SubsurfModifierData"] = DNA::FactoryPair( &Structure::Allocate<SubsurfModifierData>, &Structure::Convert<SubsurfModifierData> );
 | 
			
		||||
    converters["MFace"] = DNA::FactoryPair( &Structure::Allocate<MFace>, &Structure::Convert<MFace> );
 | 
			
		||||
    converters["Lamp"] = DNA::FactoryPair( &Structure::Allocate<Lamp>, &Structure::Convert<Lamp> );
 | 
			
		||||
    converters["MDeformWeight"] = DNA::FactoryPair( &Structure::Allocate<MDeformWeight>, &Structure::Convert<MDeformWeight> );
 | 
			
		||||
    converters["PackedFile"] = DNA::FactoryPair( &Structure::Allocate<PackedFile>, &Structure::Convert<PackedFile> );
 | 
			
		||||
    converters["Base"] = DNA::FactoryPair( &Structure::Allocate<Base>, &Structure::Convert<Base> );
 | 
			
		||||
    converters["MTFace"] = DNA::FactoryPair( &Structure::Allocate<MTFace>, &Structure::Convert<MTFace> );
 | 
			
		||||
    converters["Material"] = DNA::FactoryPair( &Structure::Allocate<Material>, &Structure::Convert<Material> );
 | 
			
		||||
    converters["MTexPoly"] = DNA::FactoryPair( &Structure::Allocate<MTexPoly>, &Structure::Convert<MTexPoly> );
 | 
			
		||||
    converters["Mesh"] = DNA::FactoryPair( &Structure::Allocate<Mesh>, &Structure::Convert<Mesh> );
 | 
			
		||||
    converters["MDeformVert"] = DNA::FactoryPair( &Structure::Allocate<MDeformVert>, &Structure::Convert<MDeformVert> );
 | 
			
		||||
    converters["World"] = DNA::FactoryPair( &Structure::Allocate<World>, &Structure::Convert<World> );
 | 
			
		||||
    converters["MLoopCol"] = DNA::FactoryPair( &Structure::Allocate<MLoopCol>, &Structure::Convert<MLoopCol> );
 | 
			
		||||
    converters["MVert"] = DNA::FactoryPair( &Structure::Allocate<MVert>, &Structure::Convert<MVert> );
 | 
			
		||||
    converters["MEdge"] = DNA::FactoryPair( &Structure::Allocate<MEdge>, &Structure::Convert<MEdge> );
 | 
			
		||||
    converters["MLoopUV"] = DNA::FactoryPair( &Structure::Allocate<MLoopUV>, &Structure::Convert<MLoopUV> );
 | 
			
		||||
    converters["GroupObject"] = DNA::FactoryPair( &Structure::Allocate<GroupObject>, &Structure::Convert<GroupObject> );
 | 
			
		||||
    converters["ListBase"] = DNA::FactoryPair( &Structure::Allocate<ListBase>, &Structure::Convert<ListBase> );
 | 
			
		||||
    converters["MLoop"] = DNA::FactoryPair( &Structure::Allocate<MLoop>, &Structure::Convert<MLoop> );
 | 
			
		||||
    converters["ModifierData"] = DNA::FactoryPair( &Structure::Allocate<ModifierData>, &Structure::Convert<ModifierData> );
 | 
			
		||||
    converters["ID"] = DNA::FactoryPair( &Structure::Allocate<ID>, &Structure::Convert<ID> );
 | 
			
		||||
    converters["MCol"] = DNA::FactoryPair( &Structure::Allocate<MCol>, &Structure::Convert<MCol> );
 | 
			
		||||
    converters["MPoly"] = DNA::FactoryPair( &Structure::Allocate<MPoly>, &Structure::Convert<MPoly> );
 | 
			
		||||
    converters["Scene"] = DNA::FactoryPair( &Structure::Allocate<Scene>, &Structure::Convert<Scene> );
 | 
			
		||||
    converters["Library"] = DNA::FactoryPair( &Structure::Allocate<Library>, &Structure::Convert<Library> );
 | 
			
		||||
    converters["Tex"] = DNA::FactoryPair( &Structure::Allocate<Tex>, &Structure::Convert<Tex> );
 | 
			
		||||
    converters["Camera"] = DNA::FactoryPair( &Structure::Allocate<Camera>, &Structure::Convert<Camera> );
 | 
			
		||||
    converters["MirrorModifierData"] = DNA::FactoryPair( &Structure::Allocate<MirrorModifierData>, &Structure::Convert<MirrorModifierData> );
 | 
			
		||||
    converters["Image"] = DNA::FactoryPair( &Structure::Allocate<Image>, &Structure::Convert<Image> );
 | 
			
		||||
    converters["CustomData"] = DNA::FactoryPair(&Structure::Allocate<CustomData>, &Structure::Convert<CustomData>);
 | 
			
		||||
    converters["CustomDataLayer"] = DNA::FactoryPair(&Structure::Allocate<CustomDataLayer>, &Structure::Convert<CustomDataLayer>);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										983
									
								
								thirdparty/assimp/code/Blender/BlenderScene.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										983
									
								
								thirdparty/assimp/code/Blender/BlenderScene.h
									
									
									
									
										vendored
									
									
								
							@@ -1,983 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2019, 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  BlenderScene.h
 | 
			
		||||
 *  @brief Intermediate representation of a BLEND scene.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef INCLUDED_AI_BLEND_SCENE_H
 | 
			
		||||
#define INCLUDED_AI_BLEND_SCENE_H
 | 
			
		||||
 | 
			
		||||
#include "BlenderDNA.h"
 | 
			
		||||
 | 
			
		||||
namespace Assimp    {
 | 
			
		||||
namespace Blender {
 | 
			
		||||
 | 
			
		||||
// Minor parts of this file are extracts from blender data structures,
 | 
			
		||||
// declared in the ./source/blender/makesdna directory.
 | 
			
		||||
// Stuff that is not used by Assimp is commented.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// NOTE
 | 
			
		||||
// this file serves as input data to the `./scripts/genblenddna.py`
 | 
			
		||||
// script. This script generates the actual binding code to read a
 | 
			
		||||
// blender file with a possibly different DNA into our structures.
 | 
			
		||||
// Only `struct` declarations are considered and the following
 | 
			
		||||
// rules must be obeyed in order for the script to work properly:
 | 
			
		||||
//
 | 
			
		||||
// * C++ style comments only
 | 
			
		||||
//
 | 
			
		||||
// * Structures may include the primitive types char, int, short,
 | 
			
		||||
//   float, double. Signed specifiers are not allowed on
 | 
			
		||||
//   integers. Enum types are allowed, but they must have been
 | 
			
		||||
//   defined in this header.
 | 
			
		||||
//
 | 
			
		||||
// * Structures may aggregate other structures, unless not defined
 | 
			
		||||
//   in this header.
 | 
			
		||||
//
 | 
			
		||||
// * Pointers to other structures or primitive types are allowed.
 | 
			
		||||
//   No references or double pointers or arrays of pointers.
 | 
			
		||||
//   A pointer to a T is normally written as std::shared_ptr, while a
 | 
			
		||||
//   pointer to an array of elements is written as boost::
 | 
			
		||||
//   shared_array. To avoid cyclic pointers, use raw pointers in
 | 
			
		||||
//   one direction.
 | 
			
		||||
//
 | 
			
		||||
// * Arrays can have maximally two-dimensions. Any non-pointer
 | 
			
		||||
//   type can form them.
 | 
			
		||||
//
 | 
			
		||||
// * Multiple fields can be declare in a single line (i.e `int a,b;`)
 | 
			
		||||
//   provided they are neither pointers nor arrays.
 | 
			
		||||
//
 | 
			
		||||
// * One of WARN, FAIL can be appended to the declaration (
 | 
			
		||||
//   prior to the semicolon to specify the error handling policy if
 | 
			
		||||
//   this field is missing in the input DNA). If none of those
 | 
			
		||||
//   is specified the default policy is to substitute a default
 | 
			
		||||
//   value for the field.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// warn if field is missing, substitute default value
 | 
			
		||||
#ifdef WARN
 | 
			
		||||
#  undef WARN
 | 
			
		||||
#endif
 | 
			
		||||
#define WARN 
 | 
			
		||||
 | 
			
		||||
// fail the import if the field does not exist
 | 
			
		||||
#ifdef FAIL
 | 
			
		||||
#  undef FAIL
 | 
			
		||||
#endif
 | 
			
		||||
#define FAIL 
 | 
			
		||||
 | 
			
		||||
struct Object;
 | 
			
		||||
struct MTex;
 | 
			
		||||
struct Image;
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
#define AI_BLEND_MESH_MAX_VERTS 2000000000L
 | 
			
		||||
 | 
			
		||||
static const size_t MaxNameLen = 1024;
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct ID : ElemBase {
 | 
			
		||||
    char name[ MaxNameLen ] WARN;
 | 
			
		||||
    short flag;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct ListBase : ElemBase {
 | 
			
		||||
    std::shared_ptr<ElemBase> first;
 | 
			
		||||
    std::shared_ptr<ElemBase> last;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct PackedFile : ElemBase {
 | 
			
		||||
     int size WARN;
 | 
			
		||||
     int seek WARN;
 | 
			
		||||
     std::shared_ptr< FileOffset > data WARN;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct GroupObject : ElemBase {
 | 
			
		||||
    std::shared_ptr<GroupObject> prev,next FAIL;
 | 
			
		||||
    std::shared_ptr<Object> ob;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct Group : ElemBase {
 | 
			
		||||
    ID id FAIL;
 | 
			
		||||
    int layer;
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<GroupObject> gobject;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct World : ElemBase {
 | 
			
		||||
    ID id FAIL;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MVert : ElemBase {
 | 
			
		||||
    float co[3] FAIL;
 | 
			
		||||
    float no[3] FAIL;       // readed as short and divided through / 32767.f
 | 
			
		||||
    char flag;
 | 
			
		||||
    int mat_nr WARN;
 | 
			
		||||
    int bweight;
 | 
			
		||||
 | 
			
		||||
    MVert() : ElemBase()
 | 
			
		||||
        , flag(0)
 | 
			
		||||
        , mat_nr(0)
 | 
			
		||||
        , bweight(0)
 | 
			
		||||
    {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MEdge : ElemBase {
 | 
			
		||||
      int v1, v2 FAIL;
 | 
			
		||||
      char crease, bweight;
 | 
			
		||||
      short flag;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MLoop : ElemBase {
 | 
			
		||||
    int v, e;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MLoopUV : ElemBase {
 | 
			
		||||
    float uv[2];
 | 
			
		||||
    int flag;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
// Note that red and blue are not swapped, as with MCol
 | 
			
		||||
struct MLoopCol : ElemBase {
 | 
			
		||||
	unsigned char r, g, b, a;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MPoly : ElemBase {
 | 
			
		||||
    int loopstart;
 | 
			
		||||
    int totloop;
 | 
			
		||||
    short mat_nr;
 | 
			
		||||
    char flag;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MTexPoly : ElemBase {
 | 
			
		||||
    Image* tpage;
 | 
			
		||||
    char flag, transp;
 | 
			
		||||
    short mode, tile, pad;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MCol : ElemBase {
 | 
			
		||||
    char r,g,b,a FAIL;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MFace : ElemBase {
 | 
			
		||||
    int v1,v2,v3,v4 FAIL;
 | 
			
		||||
    int mat_nr FAIL;
 | 
			
		||||
    char flag;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct TFace : ElemBase {
 | 
			
		||||
    float uv[4][2] FAIL;
 | 
			
		||||
    int col[4] FAIL;
 | 
			
		||||
    char flag;
 | 
			
		||||
    short mode;
 | 
			
		||||
    short tile;
 | 
			
		||||
    short unwrap;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MTFace : ElemBase {
 | 
			
		||||
	MTFace()
 | 
			
		||||
	: flag(0)
 | 
			
		||||
	, mode(0)
 | 
			
		||||
	, tile(0)
 | 
			
		||||
	, unwrap(0)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    float uv[4][2] FAIL;
 | 
			
		||||
    char flag;
 | 
			
		||||
    short mode;
 | 
			
		||||
    short tile;
 | 
			
		||||
    short unwrap;
 | 
			
		||||
 | 
			
		||||
    // std::shared_ptr<Image> tpage;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MDeformWeight : ElemBase  {
 | 
			
		||||
      int    def_nr FAIL;
 | 
			
		||||
      float  weight FAIL;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MDeformVert : ElemBase  {
 | 
			
		||||
    vector<MDeformWeight> dw WARN;
 | 
			
		||||
    int totweight;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
#define MA_RAYMIRROR    0x40000
 | 
			
		||||
#define MA_TRANSPARENCY 0x10000
 | 
			
		||||
#define MA_RAYTRANSP    0x20000
 | 
			
		||||
#define MA_ZTRANSP      0x00040
 | 
			
		||||
 | 
			
		||||
struct Material : ElemBase {
 | 
			
		||||
    ID id FAIL;
 | 
			
		||||
 | 
			
		||||
    float r,g,b WARN;
 | 
			
		||||
    float specr,specg,specb WARN;
 | 
			
		||||
    short har;
 | 
			
		||||
    float ambr,ambg,ambb WARN;
 | 
			
		||||
    float mirr,mirg,mirb;
 | 
			
		||||
    float emit WARN;
 | 
			
		||||
    float ray_mirror;
 | 
			
		||||
    float alpha WARN;
 | 
			
		||||
    float ref;
 | 
			
		||||
    float translucency;
 | 
			
		||||
    int mode;
 | 
			
		||||
    float roughness;
 | 
			
		||||
    float darkness;
 | 
			
		||||
    float refrac;
 | 
			
		||||
 | 
			
		||||
    float amb;
 | 
			
		||||
    float ang;
 | 
			
		||||
    float spectra;
 | 
			
		||||
    float spec;
 | 
			
		||||
    float zoffs;
 | 
			
		||||
    float add;
 | 
			
		||||
    float fresnel_mir;
 | 
			
		||||
    float fresnel_mir_i;
 | 
			
		||||
    float fresnel_tra;
 | 
			
		||||
    float fresnel_tra_i;
 | 
			
		||||
    float filter;
 | 
			
		||||
    float tx_limit;
 | 
			
		||||
    float tx_falloff;
 | 
			
		||||
    float gloss_mir;
 | 
			
		||||
    float gloss_tra;
 | 
			
		||||
    float adapt_thresh_mir;
 | 
			
		||||
    float adapt_thresh_tra;
 | 
			
		||||
    float aniso_gloss_mir;
 | 
			
		||||
    float dist_mir;
 | 
			
		||||
    float hasize;
 | 
			
		||||
    float flaresize;
 | 
			
		||||
    float subsize;
 | 
			
		||||
    float flareboost;
 | 
			
		||||
    float strand_sta;
 | 
			
		||||
    float strand_end;
 | 
			
		||||
    float strand_ease;
 | 
			
		||||
    float strand_surfnor;
 | 
			
		||||
    float strand_min;
 | 
			
		||||
    float strand_widthfade;
 | 
			
		||||
    float sbias;
 | 
			
		||||
    float lbias;
 | 
			
		||||
    float shad_alpha;
 | 
			
		||||
    float param;
 | 
			
		||||
    float rms;
 | 
			
		||||
    float rampfac_col;
 | 
			
		||||
    float rampfac_spec;
 | 
			
		||||
    float friction;
 | 
			
		||||
    float fh;
 | 
			
		||||
    float reflect;
 | 
			
		||||
    float fhdist;
 | 
			
		||||
    float xyfrict;
 | 
			
		||||
    float sss_radius;
 | 
			
		||||
    float sss_col;
 | 
			
		||||
    float sss_error;
 | 
			
		||||
    float sss_scale;
 | 
			
		||||
    float sss_ior;
 | 
			
		||||
    float sss_colfac;
 | 
			
		||||
    float sss_texfac;
 | 
			
		||||
    float sss_front;
 | 
			
		||||
    float sss_back;
 | 
			
		||||
 | 
			
		||||
    short material_type;
 | 
			
		||||
    short flag;
 | 
			
		||||
    short ray_depth;
 | 
			
		||||
    short ray_depth_tra;
 | 
			
		||||
    short samp_gloss_mir;
 | 
			
		||||
    short samp_gloss_tra;
 | 
			
		||||
    short fadeto_mir;
 | 
			
		||||
    short shade_flag;
 | 
			
		||||
    short flarec;
 | 
			
		||||
    short starc;
 | 
			
		||||
    short linec;
 | 
			
		||||
    short ringc;
 | 
			
		||||
    short pr_lamp;
 | 
			
		||||
    short pr_texture;
 | 
			
		||||
    short ml_flag;
 | 
			
		||||
    short texco;
 | 
			
		||||
    short mapto;
 | 
			
		||||
    short ramp_show;
 | 
			
		||||
    short pad3;
 | 
			
		||||
    short dynamode;
 | 
			
		||||
    short pad2;
 | 
			
		||||
    short sss_flag;
 | 
			
		||||
    short sss_preset;
 | 
			
		||||
    short shadowonly_flag;
 | 
			
		||||
    short index;
 | 
			
		||||
    short vcol_alpha;
 | 
			
		||||
    short pad4;
 | 
			
		||||
 | 
			
		||||
    char seed1;
 | 
			
		||||
    char seed2;
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<Group> group;
 | 
			
		||||
 | 
			
		||||
    short diff_shader WARN;
 | 
			
		||||
    short spec_shader WARN;
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<MTex> mtex[18];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
CustomDataLayer 104
 | 
			
		||||
 | 
			
		||||
    int type 0 4
 | 
			
		||||
    int offset 4 4
 | 
			
		||||
    int flag 8 4
 | 
			
		||||
    int active 12 4
 | 
			
		||||
    int active_rnd 16 4
 | 
			
		||||
    int active_clone 20 4
 | 
			
		||||
    int active_mask 24 4
 | 
			
		||||
    int uid 28 4
 | 
			
		||||
    char name 32 64
 | 
			
		||||
    void *data 96 8
 | 
			
		||||
*/
 | 
			
		||||
struct CustomDataLayer : ElemBase {
 | 
			
		||||
    int type;
 | 
			
		||||
    int offset;
 | 
			
		||||
    int flag;
 | 
			
		||||
    int active;
 | 
			
		||||
    int active_rnd;
 | 
			
		||||
    int active_clone;
 | 
			
		||||
    int active_mask;
 | 
			
		||||
    int uid;
 | 
			
		||||
    char name[64];
 | 
			
		||||
    std::shared_ptr<ElemBase> data;     // must be converted to real type according type member
 | 
			
		||||
 | 
			
		||||
    CustomDataLayer()
 | 
			
		||||
        : ElemBase()
 | 
			
		||||
        , type(0)
 | 
			
		||||
        , offset(0)
 | 
			
		||||
        , flag(0)
 | 
			
		||||
        , active(0)
 | 
			
		||||
        , active_rnd(0)
 | 
			
		||||
        , active_clone(0)
 | 
			
		||||
        , active_mask(0)
 | 
			
		||||
        , uid(0)
 | 
			
		||||
        , data(nullptr)
 | 
			
		||||
    {
 | 
			
		||||
        memset(name, 0, sizeof name);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
CustomData 208
 | 
			
		||||
 | 
			
		||||
    CustomDataLayer *layers 0 8
 | 
			
		||||
    int typemap 8 168
 | 
			
		||||
    int pad_i1 176 4
 | 
			
		||||
    int totlayer 180 4
 | 
			
		||||
    int maxlayer 184 4
 | 
			
		||||
    int totsize 188 4
 | 
			
		||||
    BLI_mempool *pool 192 8
 | 
			
		||||
    CustomDataExternal *external 200 8
 | 
			
		||||
*/
 | 
			
		||||
struct CustomData : ElemBase {
 | 
			
		||||
    vector<std::shared_ptr<struct CustomDataLayer> > layers;
 | 
			
		||||
    int typemap[42];    // CD_NUMTYPES
 | 
			
		||||
    int totlayer;
 | 
			
		||||
    int maxlayer;
 | 
			
		||||
    int totsize;
 | 
			
		||||
    /*
 | 
			
		||||
    std::shared_ptr<BLI_mempool> pool;
 | 
			
		||||
    std::shared_ptr<CustomDataExternal> external;
 | 
			
		||||
    */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct Mesh : ElemBase {
 | 
			
		||||
    ID id FAIL;
 | 
			
		||||
 | 
			
		||||
    int totface FAIL;
 | 
			
		||||
    int totedge FAIL;
 | 
			
		||||
    int totvert FAIL;
 | 
			
		||||
    int totloop;
 | 
			
		||||
    int totpoly;
 | 
			
		||||
 | 
			
		||||
    short subdiv;
 | 
			
		||||
    short subdivr;
 | 
			
		||||
    short subsurftype;
 | 
			
		||||
    short smoothresh;
 | 
			
		||||
 | 
			
		||||
    vector<MFace> mface FAIL;
 | 
			
		||||
    vector<MTFace> mtface;
 | 
			
		||||
    vector<TFace> tface;
 | 
			
		||||
    vector<MVert> mvert FAIL;
 | 
			
		||||
    vector<MEdge> medge WARN;
 | 
			
		||||
    vector<MLoop> mloop;
 | 
			
		||||
    vector<MLoopUV> mloopuv;
 | 
			
		||||
    vector<MLoopCol> mloopcol;
 | 
			
		||||
    vector<MPoly> mpoly;
 | 
			
		||||
    vector<MTexPoly> mtpoly;
 | 
			
		||||
    vector<MDeformVert> dvert;
 | 
			
		||||
    vector<MCol> mcol;
 | 
			
		||||
 | 
			
		||||
    vector< std::shared_ptr<Material> > mat FAIL;
 | 
			
		||||
 | 
			
		||||
    struct CustomData vdata;
 | 
			
		||||
    struct CustomData edata;
 | 
			
		||||
    struct CustomData fdata;
 | 
			
		||||
    struct CustomData pdata;
 | 
			
		||||
    struct CustomData ldata;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct Library : ElemBase {
 | 
			
		||||
    ID id FAIL;
 | 
			
		||||
 | 
			
		||||
    char name[240] WARN;
 | 
			
		||||
    char filename[240] FAIL;
 | 
			
		||||
    std::shared_ptr<Library> parent WARN;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct Camera : ElemBase {
 | 
			
		||||
    enum Type {
 | 
			
		||||
          Type_PERSP    =   0
 | 
			
		||||
         ,Type_ORTHO    =   1
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ID id FAIL;
 | 
			
		||||
 | 
			
		||||
    Type type,flag WARN;
 | 
			
		||||
    float lens WARN;
 | 
			
		||||
    float sensor_x WARN;
 | 
			
		||||
    float clipsta, clipend;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct Lamp : ElemBase {
 | 
			
		||||
 | 
			
		||||
    enum FalloffType {
 | 
			
		||||
         FalloffType_Constant   = 0x0
 | 
			
		||||
        ,FalloffType_InvLinear  = 0x1
 | 
			
		||||
        ,FalloffType_InvSquare  = 0x2
 | 
			
		||||
        //,FalloffType_Curve    = 0x3
 | 
			
		||||
        //,FalloffType_Sliders  = 0x4
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum Type {
 | 
			
		||||
         Type_Local         = 0x0
 | 
			
		||||
        ,Type_Sun           = 0x1
 | 
			
		||||
        ,Type_Spot          = 0x2
 | 
			
		||||
        ,Type_Hemi          = 0x3
 | 
			
		||||
        ,Type_Area          = 0x4
 | 
			
		||||
        //,Type_YFPhoton    = 0x5
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
      ID id FAIL;
 | 
			
		||||
      //AnimData *adt;
 | 
			
		||||
 | 
			
		||||
      Type type FAIL;
 | 
			
		||||
      short flags;
 | 
			
		||||
 | 
			
		||||
      //int mode;
 | 
			
		||||
 | 
			
		||||
      short colormodel, totex;
 | 
			
		||||
      float r,g,b,k WARN;
 | 
			
		||||
      //float shdwr, shdwg, shdwb;
 | 
			
		||||
 | 
			
		||||
      float energy, dist, spotsize, spotblend;
 | 
			
		||||
      //float haint;
 | 
			
		||||
 | 
			
		||||
      float constant_coefficient;
 | 
			
		||||
      float linear_coefficient;
 | 
			
		||||
      float quadratic_coefficient;
 | 
			
		||||
 | 
			
		||||
      float att1, att2;
 | 
			
		||||
      //struct CurveMapping *curfalloff;
 | 
			
		||||
      FalloffType falloff_type;
 | 
			
		||||
 | 
			
		||||
      //float clipsta, clipend, shadspotsize;
 | 
			
		||||
      //float bias, soft, compressthresh;
 | 
			
		||||
      //short bufsize, samp, buffers, filtertype;
 | 
			
		||||
      //char bufflag, buftype;
 | 
			
		||||
 | 
			
		||||
      //short ray_samp, ray_sampy, ray_sampz;
 | 
			
		||||
      //short ray_samp_type;
 | 
			
		||||
      short area_shape;
 | 
			
		||||
      float area_size, area_sizey, area_sizez;
 | 
			
		||||
      //float adapt_thresh;
 | 
			
		||||
      //short ray_samp_method;
 | 
			
		||||
 | 
			
		||||
      //short texact, shadhalostep;
 | 
			
		||||
 | 
			
		||||
      //short sun_effect_type;
 | 
			
		||||
      //short skyblendtype;
 | 
			
		||||
      //float horizon_brightness;
 | 
			
		||||
      //float spread;
 | 
			
		||||
      float sun_brightness;
 | 
			
		||||
      //float sun_size;
 | 
			
		||||
      //float backscattered_light;
 | 
			
		||||
      //float sun_intensity;
 | 
			
		||||
      //float atm_turbidity;
 | 
			
		||||
      //float atm_inscattering_factor;
 | 
			
		||||
      //float atm_extinction_factor;
 | 
			
		||||
      //float atm_distance_factor;
 | 
			
		||||
      //float skyblendfac;
 | 
			
		||||
      //float sky_exposure;
 | 
			
		||||
      //short sky_colorspace;
 | 
			
		||||
 | 
			
		||||
      // int YF_numphotons, YF_numsearch;
 | 
			
		||||
      // short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad;
 | 
			
		||||
      // float YF_causticblur, YF_ltradius;
 | 
			
		||||
 | 
			
		||||
      // float YF_glowint, YF_glowofs;
 | 
			
		||||
      // short YF_glowtype, YF_pad2;
 | 
			
		||||
 | 
			
		||||
      //struct Ipo *ipo;
 | 
			
		||||
      //struct MTex *mtex[18];
 | 
			
		||||
      // short pr_texture;
 | 
			
		||||
 | 
			
		||||
      //struct PreviewImage *preview;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct ModifierData : ElemBase  {
 | 
			
		||||
    enum ModifierType {
 | 
			
		||||
      eModifierType_None = 0,
 | 
			
		||||
      eModifierType_Subsurf,
 | 
			
		||||
      eModifierType_Lattice,
 | 
			
		||||
      eModifierType_Curve,
 | 
			
		||||
      eModifierType_Build,
 | 
			
		||||
      eModifierType_Mirror,
 | 
			
		||||
      eModifierType_Decimate,
 | 
			
		||||
      eModifierType_Wave,
 | 
			
		||||
      eModifierType_Armature,
 | 
			
		||||
      eModifierType_Hook,
 | 
			
		||||
      eModifierType_Softbody,
 | 
			
		||||
      eModifierType_Boolean,
 | 
			
		||||
      eModifierType_Array,
 | 
			
		||||
      eModifierType_EdgeSplit,
 | 
			
		||||
      eModifierType_Displace,
 | 
			
		||||
      eModifierType_UVProject,
 | 
			
		||||
      eModifierType_Smooth,
 | 
			
		||||
      eModifierType_Cast,
 | 
			
		||||
      eModifierType_MeshDeform,
 | 
			
		||||
      eModifierType_ParticleSystem,
 | 
			
		||||
      eModifierType_ParticleInstance,
 | 
			
		||||
      eModifierType_Explode,
 | 
			
		||||
      eModifierType_Cloth,
 | 
			
		||||
      eModifierType_Collision,
 | 
			
		||||
      eModifierType_Bevel,
 | 
			
		||||
      eModifierType_Shrinkwrap,
 | 
			
		||||
      eModifierType_Fluidsim,
 | 
			
		||||
      eModifierType_Mask,
 | 
			
		||||
      eModifierType_SimpleDeform,
 | 
			
		||||
      eModifierType_Multires,
 | 
			
		||||
      eModifierType_Surface,
 | 
			
		||||
      eModifierType_Smoke,
 | 
			
		||||
      eModifierType_ShapeKey
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<ElemBase> next WARN;
 | 
			
		||||
    std::shared_ptr<ElemBase> prev WARN;
 | 
			
		||||
 | 
			
		||||
    int type, mode;
 | 
			
		||||
    char name[32];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct SubsurfModifierData : ElemBase  {
 | 
			
		||||
 | 
			
		||||
    enum Type {
 | 
			
		||||
 | 
			
		||||
        TYPE_CatmullClarke = 0x0,
 | 
			
		||||
        TYPE_Simple = 0x1
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum Flags {
 | 
			
		||||
        // some omitted
 | 
			
		||||
        FLAGS_SubsurfUV     =1<<3
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ModifierData modifier FAIL;
 | 
			
		||||
    short subdivType WARN;
 | 
			
		||||
    short levels FAIL;
 | 
			
		||||
    short renderLevels ;
 | 
			
		||||
    short flags;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MirrorModifierData : ElemBase {
 | 
			
		||||
 | 
			
		||||
    enum Flags {
 | 
			
		||||
        Flags_CLIPPING      =1<<0,
 | 
			
		||||
        Flags_MIRROR_U      =1<<1,
 | 
			
		||||
        Flags_MIRROR_V      =1<<2,
 | 
			
		||||
        Flags_AXIS_X        =1<<3,
 | 
			
		||||
        Flags_AXIS_Y        =1<<4,
 | 
			
		||||
        Flags_AXIS_Z        =1<<5,
 | 
			
		||||
        Flags_VGROUP        =1<<6
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ModifierData modifier FAIL;
 | 
			
		||||
 | 
			
		||||
    short axis, flag;
 | 
			
		||||
    float tolerance;
 | 
			
		||||
    std::shared_ptr<Object> mirror_ob;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct Object : ElemBase  {
 | 
			
		||||
    ID id FAIL;
 | 
			
		||||
 | 
			
		||||
    enum Type {
 | 
			
		||||
         Type_EMPTY     =   0
 | 
			
		||||
        ,Type_MESH      =   1
 | 
			
		||||
        ,Type_CURVE     =   2
 | 
			
		||||
        ,Type_SURF      =   3
 | 
			
		||||
        ,Type_FONT      =   4
 | 
			
		||||
        ,Type_MBALL     =   5
 | 
			
		||||
 | 
			
		||||
        ,Type_LAMP      =   10
 | 
			
		||||
        ,Type_CAMERA    =   11
 | 
			
		||||
 | 
			
		||||
        ,Type_WAVE      =   21
 | 
			
		||||
        ,Type_LATTICE   =   22
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Type type FAIL;
 | 
			
		||||
    float obmat[4][4] WARN;
 | 
			
		||||
    float parentinv[4][4] WARN;
 | 
			
		||||
    char parsubstr[32] WARN;
 | 
			
		||||
 | 
			
		||||
    Object* parent WARN;
 | 
			
		||||
    std::shared_ptr<Object> track WARN;
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<Object> proxy,proxy_from,proxy_group WARN;
 | 
			
		||||
    std::shared_ptr<Group> dup_group WARN;
 | 
			
		||||
    std::shared_ptr<ElemBase> data FAIL;
 | 
			
		||||
 | 
			
		||||
    ListBase modifiers;
 | 
			
		||||
 | 
			
		||||
    Object()
 | 
			
		||||
    : ElemBase()
 | 
			
		||||
    , type( Type_EMPTY )
 | 
			
		||||
    , parent( nullptr )
 | 
			
		||||
    , track()
 | 
			
		||||
    , proxy()
 | 
			
		||||
    , proxy_from()
 | 
			
		||||
    , data() {
 | 
			
		||||
        // empty
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct Base : ElemBase {
 | 
			
		||||
    Base* prev WARN;
 | 
			
		||||
    std::shared_ptr<Base> next WARN;
 | 
			
		||||
    std::shared_ptr<Object> object WARN;
 | 
			
		||||
 | 
			
		||||
    Base() 
 | 
			
		||||
    : ElemBase()
 | 
			
		||||
    , prev( nullptr )
 | 
			
		||||
    , next()
 | 
			
		||||
    , object() {
 | 
			
		||||
        // empty
 | 
			
		||||
        // empty
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct Scene : ElemBase {
 | 
			
		||||
    ID id FAIL;
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<Object> camera WARN;
 | 
			
		||||
    std::shared_ptr<World> world WARN;
 | 
			
		||||
    std::shared_ptr<Base> basact WARN;
 | 
			
		||||
 | 
			
		||||
    ListBase base;
 | 
			
		||||
 | 
			
		||||
    Scene()
 | 
			
		||||
    : ElemBase()
 | 
			
		||||
    , camera()
 | 
			
		||||
    , world()
 | 
			
		||||
    , basact() {
 | 
			
		||||
        // empty
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct Image : ElemBase {
 | 
			
		||||
    ID id FAIL;
 | 
			
		||||
 | 
			
		||||
    char name[240] WARN;
 | 
			
		||||
 | 
			
		||||
    //struct anim *anim;
 | 
			
		||||
 | 
			
		||||
    short ok, flag;
 | 
			
		||||
    short source, type, pad, pad1;
 | 
			
		||||
    int lastframe;
 | 
			
		||||
 | 
			
		||||
    short tpageflag, totbind;
 | 
			
		||||
    short xrep, yrep;
 | 
			
		||||
    short twsta, twend;
 | 
			
		||||
    //unsigned int bindcode;
 | 
			
		||||
    //unsigned int *repbind;
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<PackedFile> packedfile;
 | 
			
		||||
    //struct PreviewImage * preview;
 | 
			
		||||
 | 
			
		||||
    float lastupdate;
 | 
			
		||||
    int lastused;
 | 
			
		||||
    short animspeed;
 | 
			
		||||
 | 
			
		||||
    short gen_x, gen_y, gen_type;
 | 
			
		||||
    
 | 
			
		||||
    Image()
 | 
			
		||||
    : ElemBase() {
 | 
			
		||||
        // empty
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct Tex : ElemBase {
 | 
			
		||||
 | 
			
		||||
    // actually, the only texture type we support is Type_IMAGE
 | 
			
		||||
    enum Type {
 | 
			
		||||
         Type_CLOUDS        = 1
 | 
			
		||||
        ,Type_WOOD          = 2
 | 
			
		||||
        ,Type_MARBLE        = 3
 | 
			
		||||
        ,Type_MAGIC         = 4
 | 
			
		||||
        ,Type_BLEND         = 5
 | 
			
		||||
        ,Type_STUCCI        = 6
 | 
			
		||||
        ,Type_NOISE         = 7
 | 
			
		||||
        ,Type_IMAGE         = 8
 | 
			
		||||
        ,Type_PLUGIN        = 9
 | 
			
		||||
        ,Type_ENVMAP        = 10
 | 
			
		||||
        ,Type_MUSGRAVE      = 11
 | 
			
		||||
        ,Type_VORONOI       = 12
 | 
			
		||||
        ,Type_DISTNOISE     = 13
 | 
			
		||||
        ,Type_POINTDENSITY  = 14
 | 
			
		||||
        ,Type_VOXELDATA     = 15
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum ImageFlags {
 | 
			
		||||
         ImageFlags_INTERPOL         = 1
 | 
			
		||||
        ,ImageFlags_USEALPHA         = 2
 | 
			
		||||
        ,ImageFlags_MIPMAP           = 4
 | 
			
		||||
        ,ImageFlags_IMAROT           = 16
 | 
			
		||||
        ,ImageFlags_CALCALPHA        = 32
 | 
			
		||||
        ,ImageFlags_NORMALMAP        = 2048
 | 
			
		||||
        ,ImageFlags_GAUSS_MIP        = 4096
 | 
			
		||||
        ,ImageFlags_FILTER_MIN       = 8192
 | 
			
		||||
        ,ImageFlags_DERIVATIVEMAP   = 16384
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ID id FAIL;
 | 
			
		||||
    // AnimData *adt;
 | 
			
		||||
 | 
			
		||||
    //float noisesize, turbul;
 | 
			
		||||
    //float bright, contrast, rfac, gfac, bfac;
 | 
			
		||||
    //float filtersize;
 | 
			
		||||
 | 
			
		||||
    //float mg_H, mg_lacunarity, mg_octaves, mg_offset, mg_gain;
 | 
			
		||||
    //float dist_amount, ns_outscale;
 | 
			
		||||
 | 
			
		||||
    //float vn_w1;
 | 
			
		||||
    //float vn_w2;
 | 
			
		||||
    //float vn_w3;
 | 
			
		||||
    //float vn_w4;
 | 
			
		||||
    //float vn_mexp;
 | 
			
		||||
    //short vn_distm, vn_coltype;
 | 
			
		||||
 | 
			
		||||
    //short noisedepth, noisetype;
 | 
			
		||||
    //short noisebasis, noisebasis2;
 | 
			
		||||
 | 
			
		||||
    //short flag;
 | 
			
		||||
    ImageFlags imaflag;
 | 
			
		||||
    Type type FAIL;
 | 
			
		||||
    //short stype;
 | 
			
		||||
 | 
			
		||||
    //float cropxmin, cropymin, cropxmax, cropymax;
 | 
			
		||||
    //int texfilter;
 | 
			
		||||
    //int afmax;
 | 
			
		||||
    //short xrepeat, yrepeat;
 | 
			
		||||
    //short extend;
 | 
			
		||||
 | 
			
		||||
    //short fie_ima;
 | 
			
		||||
    //int len;
 | 
			
		||||
    //int frames, offset, sfra;
 | 
			
		||||
 | 
			
		||||
    //float checkerdist, nabla;
 | 
			
		||||
    //float norfac;
 | 
			
		||||
 | 
			
		||||
    //ImageUser iuser;
 | 
			
		||||
 | 
			
		||||
    //bNodeTree *nodetree;
 | 
			
		||||
    //Ipo *ipo;
 | 
			
		||||
    std::shared_ptr<Image> ima WARN;
 | 
			
		||||
    //PluginTex *plugin;
 | 
			
		||||
    //ColorBand *coba;
 | 
			
		||||
    //EnvMap *env;
 | 
			
		||||
    //PreviewImage * preview;
 | 
			
		||||
    //PointDensity *pd;
 | 
			
		||||
    //VoxelData *vd;
 | 
			
		||||
 | 
			
		||||
    //char use_nodes;
 | 
			
		||||
 | 
			
		||||
    Tex()
 | 
			
		||||
    : ElemBase()
 | 
			
		||||
    , imaflag( ImageFlags_INTERPOL )
 | 
			
		||||
    , type( Type_CLOUDS )
 | 
			
		||||
    , ima() {
 | 
			
		||||
        // empty
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------
 | 
			
		||||
struct MTex : ElemBase {
 | 
			
		||||
 | 
			
		||||
    enum Projection {
 | 
			
		||||
         Proj_N = 0
 | 
			
		||||
        ,Proj_X = 1
 | 
			
		||||
        ,Proj_Y = 2
 | 
			
		||||
        ,Proj_Z = 3
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum Flag {
 | 
			
		||||
         Flag_RGBTOINT      = 0x1
 | 
			
		||||
        ,Flag_STENCIL       = 0x2
 | 
			
		||||
        ,Flag_NEGATIVE      = 0x4
 | 
			
		||||
        ,Flag_ALPHAMIX      = 0x8
 | 
			
		||||
        ,Flag_VIEWSPACE     = 0x10
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum BlendType {
 | 
			
		||||
         BlendType_BLEND            = 0
 | 
			
		||||
        ,BlendType_MUL              = 1
 | 
			
		||||
        ,BlendType_ADD              = 2
 | 
			
		||||
        ,BlendType_SUB              = 3
 | 
			
		||||
        ,BlendType_DIV              = 4
 | 
			
		||||
        ,BlendType_DARK             = 5
 | 
			
		||||
        ,BlendType_DIFF             = 6
 | 
			
		||||
        ,BlendType_LIGHT            = 7
 | 
			
		||||
        ,BlendType_SCREEN           = 8
 | 
			
		||||
        ,BlendType_OVERLAY          = 9
 | 
			
		||||
        ,BlendType_BLEND_HUE        = 10
 | 
			
		||||
        ,BlendType_BLEND_SAT        = 11
 | 
			
		||||
        ,BlendType_BLEND_VAL        = 12
 | 
			
		||||
        ,BlendType_BLEND_COLOR      = 13
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum MapType {
 | 
			
		||||
         MapType_COL         = 1
 | 
			
		||||
        ,MapType_NORM        = 2
 | 
			
		||||
        ,MapType_COLSPEC     = 4
 | 
			
		||||
        ,MapType_COLMIR      = 8
 | 
			
		||||
        ,MapType_REF         = 16
 | 
			
		||||
        ,MapType_SPEC        = 32
 | 
			
		||||
        ,MapType_EMIT        = 64
 | 
			
		||||
        ,MapType_ALPHA       = 128
 | 
			
		||||
        ,MapType_HAR         = 256
 | 
			
		||||
        ,MapType_RAYMIRR     = 512
 | 
			
		||||
        ,MapType_TRANSLU     = 1024
 | 
			
		||||
        ,MapType_AMB         = 2048
 | 
			
		||||
        ,MapType_DISPLACE    = 4096
 | 
			
		||||
        ,MapType_WARP        = 8192
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // short texco, maptoneg;
 | 
			
		||||
    MapType mapto;
 | 
			
		||||
 | 
			
		||||
    BlendType blendtype;
 | 
			
		||||
    std::shared_ptr<Object> object;
 | 
			
		||||
    std::shared_ptr<Tex> tex;
 | 
			
		||||
    char uvname[32];
 | 
			
		||||
 | 
			
		||||
    Projection projx,projy,projz;
 | 
			
		||||
    char mapping;
 | 
			
		||||
    float ofs[3], size[3], rot;
 | 
			
		||||
 | 
			
		||||
    int texflag;
 | 
			
		||||
    short colormodel, pmapto, pmaptoneg;
 | 
			
		||||
    //short normapspace, which_output;
 | 
			
		||||
    //char brush_map_mode;
 | 
			
		||||
    float r,g,b,k WARN;
 | 
			
		||||
    //float def_var, rt;
 | 
			
		||||
 | 
			
		||||
    //float colfac, varfac;
 | 
			
		||||
 | 
			
		||||
    float norfac;
 | 
			
		||||
    //float dispfac, warpfac;
 | 
			
		||||
    float colspecfac, mirrfac, alphafac;
 | 
			
		||||
    float difffac, specfac, emitfac, hardfac;
 | 
			
		||||
    //float raymirrfac, translfac, ambfac;
 | 
			
		||||
    //float colemitfac, colreflfac, coltransfac;
 | 
			
		||||
    //float densfac, scatterfac, reflfac;
 | 
			
		||||
 | 
			
		||||
    //float timefac, lengthfac, clumpfac;
 | 
			
		||||
    //float kinkfac, roughfac, padensfac;
 | 
			
		||||
    //float lifefac, sizefac, ivelfac, pvelfac;
 | 
			
		||||
    //float shadowfac;
 | 
			
		||||
    //float zenupfac, zendownfac, blendfac;
 | 
			
		||||
 | 
			
		||||
    MTex()
 | 
			
		||||
    : ElemBase() {
 | 
			
		||||
        // empty
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										266
									
								
								thirdparty/assimp/code/Blender/BlenderSceneGen.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										266
									
								
								thirdparty/assimp/code/Blender/BlenderSceneGen.h
									
									
									
									
										vendored
									
									
								
							@@ -1,266 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (ASSIMP)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2016, ASSIMP Development 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 Development 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  BlenderSceneGen.h
 | 
			
		||||
 *  @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
 | 
			
		||||
 */
 | 
			
		||||
#ifndef INCLUDED_AI_BLEND_SCENEGEN_H
 | 
			
		||||
#define INCLUDED_AI_BLEND_SCENEGEN_H
 | 
			
		||||
 | 
			
		||||
#include "BlenderDNA.h"
 | 
			
		||||
#include "BlenderScene.h"
 | 
			
		||||
 | 
			
		||||
namespace Assimp    {
 | 
			
		||||
namespace Blender {
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<Object> (
 | 
			
		||||
    Object& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<Group> (
 | 
			
		||||
    Group& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MTex> (
 | 
			
		||||
    MTex& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<TFace> (
 | 
			
		||||
    TFace& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<SubsurfModifierData> (
 | 
			
		||||
    SubsurfModifierData& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MFace> (
 | 
			
		||||
    MFace& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<Lamp> (
 | 
			
		||||
    Lamp& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MDeformWeight> (
 | 
			
		||||
    MDeformWeight& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<PackedFile> (
 | 
			
		||||
    PackedFile& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<Base> (
 | 
			
		||||
    Base& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MTFace> (
 | 
			
		||||
    MTFace& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<Material> (
 | 
			
		||||
    Material& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MTexPoly> (
 | 
			
		||||
    MTexPoly& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<Mesh> (
 | 
			
		||||
    Mesh& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MDeformVert> (
 | 
			
		||||
    MDeformVert& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<World> (
 | 
			
		||||
    World& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MLoopCol> (
 | 
			
		||||
    MLoopCol& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MVert> (
 | 
			
		||||
    MVert& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MEdge> (
 | 
			
		||||
    MEdge& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MLoopUV> (
 | 
			
		||||
    MLoopUV& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<GroupObject> (
 | 
			
		||||
    GroupObject& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<ListBase> (
 | 
			
		||||
    ListBase& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MLoop> (
 | 
			
		||||
    MLoop& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<ModifierData> (
 | 
			
		||||
    ModifierData& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<ID> (
 | 
			
		||||
    ID& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MCol> (
 | 
			
		||||
    MCol& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MPoly> (
 | 
			
		||||
    MPoly& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<Scene> (
 | 
			
		||||
    Scene& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<Library> (
 | 
			
		||||
    Library& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<Tex> (
 | 
			
		||||
    Tex& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<Camera> (
 | 
			
		||||
    Camera& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<MirrorModifierData> (
 | 
			
		||||
    MirrorModifierData& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure :: Convert<Image> (
 | 
			
		||||
    Image& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
template <> void Structure::Convert<CustomData>(
 | 
			
		||||
    CustomData& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
template <> void Structure::Convert<CustomDataLayer>(
 | 
			
		||||
    CustomDataLayer& dest,
 | 
			
		||||
    const FileDatabase& db
 | 
			
		||||
    ) const
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,526 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2019, 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  BlenderTessellator.cpp
 | 
			
		||||
 *  @brief A simple tessellation wrapper
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
 | 
			
		||||
 | 
			
		||||
#include "BlenderDNA.h"
 | 
			
		||||
#include "BlenderScene.h"
 | 
			
		||||
#include "BlenderBMesh.h"
 | 
			
		||||
#include "BlenderTessellator.h"
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
static const unsigned int BLEND_TESS_MAGIC = 0x83ed9ac3;
 | 
			
		||||
 | 
			
		||||
#if ASSIMP_BLEND_WITH_GLU_TESSELLATE
 | 
			
		||||
 | 
			
		||||
namspace Assimp
 | 
			
		||||
{
 | 
			
		||||
    template< > const char* LogFunctions< BlenderTessellatorGL >::Prefix()
 | 
			
		||||
    {
 | 
			
		||||
        static auto prefix = "BLEND_TESS_GL: ";
 | 
			
		||||
        return prefix;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
using namespace Assimp;
 | 
			
		||||
using namespace Assimp::Blender;
 | 
			
		||||
 | 
			
		||||
#ifndef CALLBACK
 | 
			
		||||
#define CALLBACK
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
BlenderTessellatorGL::BlenderTessellatorGL( BlenderBMeshConverter& converter ):
 | 
			
		||||
    converter( &converter )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
BlenderTessellatorGL::~BlenderTessellatorGL( )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
 | 
			
		||||
{
 | 
			
		||||
    AssertVertexCount( vertexCount );
 | 
			
		||||
 | 
			
		||||
    std::vector< VertexGL > polyLoopGL;
 | 
			
		||||
    GenerateLoopVerts( polyLoopGL, polyLoop, vertexCount, vertices );
 | 
			
		||||
 | 
			
		||||
    TessDataGL tessData;
 | 
			
		||||
    Tesssellate( polyLoopGL, tessData );
 | 
			
		||||
 | 
			
		||||
    TriangulateDrawCalls( tessData );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::AssertVertexCount( int vertexCount )
 | 
			
		||||
{
 | 
			
		||||
    if ( vertexCount <= 4 )
 | 
			
		||||
    {
 | 
			
		||||
        ThrowException( "Expected more than 4 vertices for tessellation" );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::GenerateLoopVerts( std::vector< VertexGL >& polyLoopGL, const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
 | 
			
		||||
{
 | 
			
		||||
    for ( int i = 0; i < vertexCount; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        const MLoop& loopItem = polyLoop[ i ];
 | 
			
		||||
        const MVert& vertex = vertices[ loopItem.v ];
 | 
			
		||||
        polyLoopGL.push_back( VertexGL( vertex.co[ 0 ], vertex.co[ 1 ], vertex.co[ 2 ], loopItem.v, BLEND_TESS_MAGIC ) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::Tesssellate( std::vector< VertexGL >& polyLoopGL, TessDataGL& tessData )
 | 
			
		||||
{
 | 
			
		||||
    GLUtesselator* tessellator = gluNewTess( );
 | 
			
		||||
    gluTessCallback( tessellator, GLU_TESS_BEGIN_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateBegin ) );
 | 
			
		||||
    gluTessCallback( tessellator, GLU_TESS_END_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEnd ) );
 | 
			
		||||
    gluTessCallback( tessellator, GLU_TESS_VERTEX_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateVertex ) );
 | 
			
		||||
    gluTessCallback( tessellator, GLU_TESS_COMBINE_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateCombine ) );
 | 
			
		||||
    gluTessCallback( tessellator, GLU_TESS_EDGE_FLAG_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEdgeFlag ) );
 | 
			
		||||
    gluTessCallback( tessellator, GLU_TESS_ERROR_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateError ) );
 | 
			
		||||
    gluTessProperty( tessellator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO );
 | 
			
		||||
 | 
			
		||||
    gluTessBeginPolygon( tessellator, &tessData );
 | 
			
		||||
    gluTessBeginContour( tessellator );
 | 
			
		||||
 | 
			
		||||
    for ( unsigned int i = 0; i < polyLoopGL.size( ); ++i )
 | 
			
		||||
    {
 | 
			
		||||
        gluTessVertex( tessellator, reinterpret_cast< GLdouble* >( &polyLoopGL[ i ] ), &polyLoopGL[ i ] );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gluTessEndContour( tessellator );
 | 
			
		||||
    gluTessEndPolygon( tessellator );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::TriangulateDrawCalls( const TessDataGL& tessData )
 | 
			
		||||
{
 | 
			
		||||
    // NOTE - Because we are supplying a callback to GLU_TESS_EDGE_FLAG_DATA we don't technically
 | 
			
		||||
    //        need support for GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN but we'll keep it here in case
 | 
			
		||||
    //        GLU tessellate changes or tri-strips and fans are wanted.
 | 
			
		||||
    //        See: http://www.opengl.org/sdk/docs/man2/xhtml/gluTessCallback.xml
 | 
			
		||||
    for ( unsigned int i = 0; i < tessData.drawCalls.size( ); ++i )
 | 
			
		||||
    {
 | 
			
		||||
        const DrawCallGL& drawCallGL = tessData.drawCalls[ i ];
 | 
			
		||||
        const VertexGL* vertices = &tessData.vertices[ drawCallGL.baseVertex ];
 | 
			
		||||
        if ( drawCallGL.drawMode == GL_TRIANGLES )
 | 
			
		||||
        {
 | 
			
		||||
            MakeFacesFromTris( vertices, drawCallGL.vertexCount );
 | 
			
		||||
        }
 | 
			
		||||
        else if ( drawCallGL.drawMode == GL_TRIANGLE_STRIP )
 | 
			
		||||
        {
 | 
			
		||||
            MakeFacesFromTriStrip( vertices, drawCallGL.vertexCount );
 | 
			
		||||
        }
 | 
			
		||||
        else if ( drawCallGL.drawMode == GL_TRIANGLE_FAN )
 | 
			
		||||
        {
 | 
			
		||||
            MakeFacesFromTriFan( vertices, drawCallGL.vertexCount );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::MakeFacesFromTris( const VertexGL* vertices, int vertexCount )
 | 
			
		||||
{
 | 
			
		||||
    const int triangleCount = vertexCount / 3;
 | 
			
		||||
    for ( int i = 0; i < triangleCount; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        int vertexBase = i * 3;
 | 
			
		||||
        converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::MakeFacesFromTriStrip( const VertexGL* vertices, int vertexCount )
 | 
			
		||||
{
 | 
			
		||||
    const int triangleCount = vertexCount - 2;
 | 
			
		||||
    for ( int i = 0; i < triangleCount; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        int vertexBase = i;
 | 
			
		||||
        converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::MakeFacesFromTriFan( const VertexGL* vertices, int vertexCount )
 | 
			
		||||
{
 | 
			
		||||
    const int triangleCount = vertexCount - 2;
 | 
			
		||||
    for ( int i = 0; i < triangleCount; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        int vertexBase = i;
 | 
			
		||||
        converter->AddFace( vertices[ 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::TessellateBegin( GLenum drawModeGL, void* userData )
 | 
			
		||||
{
 | 
			
		||||
    TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData );
 | 
			
		||||
    tessData.drawCalls.push_back( DrawCallGL( drawModeGL, tessData.vertices.size( ) ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::TessellateEnd( void* )
 | 
			
		||||
{
 | 
			
		||||
    // Do nothing
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::TessellateVertex( const void* vtxData, void* userData )
 | 
			
		||||
{
 | 
			
		||||
    TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData );
 | 
			
		||||
 | 
			
		||||
    const VertexGL& vertex = *reinterpret_cast< const VertexGL* >( vtxData );
 | 
			
		||||
    if ( vertex.magic != BLEND_TESS_MAGIC )
 | 
			
		||||
    {
 | 
			
		||||
        ThrowException( "Point returned by GLU Tessellate was probably not one of ours. This indicates we need a new way to store vertex information" );
 | 
			
		||||
    }
 | 
			
		||||
    tessData.vertices.push_back( vertex );
 | 
			
		||||
    if ( tessData.drawCalls.size( ) == 0 )
 | 
			
		||||
    {
 | 
			
		||||
        ThrowException( "\"Vertex\" callback received before \"Begin\"" );
 | 
			
		||||
    }
 | 
			
		||||
    ++( tessData.drawCalls.back( ).vertexCount );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData )
 | 
			
		||||
{
 | 
			
		||||
    ThrowException( "Intersected polygon loops are not yet supported" );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::TessellateEdgeFlag( GLboolean, void* )
 | 
			
		||||
{
 | 
			
		||||
    // Do nothing
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* )
 | 
			
		||||
{
 | 
			
		||||
    ThrowException( reinterpret_cast< const char* >( gluErrorString( errorCode ) ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE
 | 
			
		||||
 | 
			
		||||
#if ASSIMP_BLEND_WITH_POLY_2_TRI
 | 
			
		||||
 | 
			
		||||
namespace Assimp
 | 
			
		||||
{
 | 
			
		||||
    template< > const char* LogFunctions< BlenderTessellatorP2T >::Prefix()
 | 
			
		||||
    {
 | 
			
		||||
        static auto prefix = "BLEND_TESS_P2T: ";
 | 
			
		||||
        return prefix;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
using namespace Assimp;
 | 
			
		||||
using namespace Assimp::Blender;
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
BlenderTessellatorP2T::BlenderTessellatorP2T( BlenderBMeshConverter& converter ):
 | 
			
		||||
    converter( &converter )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
BlenderTessellatorP2T::~BlenderTessellatorP2T( )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorP2T::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
 | 
			
		||||
{
 | 
			
		||||
    AssertVertexCount( vertexCount );
 | 
			
		||||
 | 
			
		||||
    // NOTE - We have to hope that points in a Blender polygon are roughly on the same plane.
 | 
			
		||||
    //        There may be some triangulation artifacts if they are wildly different.
 | 
			
		||||
 | 
			
		||||
    std::vector< PointP2T > points;
 | 
			
		||||
    Copy3DVertices( polyLoop, vertexCount, vertices, points );
 | 
			
		||||
 | 
			
		||||
    PlaneP2T plane = FindLLSQPlane( points );
 | 
			
		||||
 | 
			
		||||
    aiMatrix4x4 transform = GeneratePointTransformMatrix( plane );
 | 
			
		||||
 | 
			
		||||
    TransformAndFlattenVectices( transform, points );
 | 
			
		||||
 | 
			
		||||
    std::vector< p2t::Point* > pointRefs;
 | 
			
		||||
    ReferencePoints( points, pointRefs );
 | 
			
		||||
 | 
			
		||||
    p2t::CDT cdt( pointRefs );
 | 
			
		||||
 | 
			
		||||
    cdt.Triangulate( );
 | 
			
		||||
    std::vector< p2t::Triangle* > triangles = cdt.GetTriangles( );
 | 
			
		||||
 | 
			
		||||
    MakeFacesFromTriangles( triangles );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorP2T::AssertVertexCount( int vertexCount )
 | 
			
		||||
{
 | 
			
		||||
    if ( vertexCount <= 4 )
 | 
			
		||||
    {
 | 
			
		||||
        ThrowException( "Expected more than 4 vertices for tessellation" );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorP2T::Copy3DVertices( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices, std::vector< PointP2T >& points ) const
 | 
			
		||||
{
 | 
			
		||||
    points.resize( vertexCount );
 | 
			
		||||
    for ( int i = 0; i < vertexCount; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        const MLoop& loop = polyLoop[ i ];
 | 
			
		||||
        const MVert& vert = vertices[ loop.v ];
 | 
			
		||||
 | 
			
		||||
        PointP2T& point = points[ i ];
 | 
			
		||||
        point.point3D.Set( vert.co[ 0 ], vert.co[ 1 ], vert.co[ 2 ] );
 | 
			
		||||
        point.index = loop.v;
 | 
			
		||||
        point.magic = BLEND_TESS_MAGIC;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
aiMatrix4x4 BlenderTessellatorP2T::GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const
 | 
			
		||||
{
 | 
			
		||||
    aiVector3D sideA( 1.0f, 0.0f, 0.0f );
 | 
			
		||||
    if ( std::fabs( plane.normal * sideA ) > 0.999f )
 | 
			
		||||
    {
 | 
			
		||||
        sideA = aiVector3D( 0.0f, 1.0f, 0.0f );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aiVector3D sideB( plane.normal ^ sideA );
 | 
			
		||||
    sideB.Normalize( );
 | 
			
		||||
    sideA = sideB ^ plane.normal;
 | 
			
		||||
 | 
			
		||||
    aiMatrix4x4 result;
 | 
			
		||||
    result.a1 = sideA.x;
 | 
			
		||||
    result.a2 = sideA.y;
 | 
			
		||||
    result.a3 = sideA.z;
 | 
			
		||||
    result.b1 = sideB.x;
 | 
			
		||||
    result.b2 = sideB.y;
 | 
			
		||||
    result.b3 = sideB.z;
 | 
			
		||||
    result.c1 = plane.normal.x;
 | 
			
		||||
    result.c2 = plane.normal.y;
 | 
			
		||||
    result.c3 = plane.normal.z;
 | 
			
		||||
    result.a4 = plane.centre.x;
 | 
			
		||||
    result.b4 = plane.centre.y;
 | 
			
		||||
    result.c4 = plane.centre.z;
 | 
			
		||||
    result.Inverse( );
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorP2T::TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const
 | 
			
		||||
{
 | 
			
		||||
    for ( size_t i = 0; i < vertices.size( ); ++i )
 | 
			
		||||
    {
 | 
			
		||||
        PointP2T& point = vertices[ i ];
 | 
			
		||||
        point.point3D = transform * point.point3D;
 | 
			
		||||
        point.point2D.set( point.point3D.y, point.point3D.z );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorP2T::ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const
 | 
			
		||||
{
 | 
			
		||||
    pointRefs.resize( points.size( ) );
 | 
			
		||||
    for ( size_t i = 0; i < points.size( ); ++i )
 | 
			
		||||
    {
 | 
			
		||||
        pointRefs[ i ] = &points[ i ].point2D;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& point ) const
 | 
			
		||||
{
 | 
			
		||||
    unsigned int pointOffset = offsetof( PointP2T, point2D );
 | 
			
		||||
    PointP2T& pointStruct = *reinterpret_cast< PointP2T* >( reinterpret_cast< char* >( &point ) - pointOffset );
 | 
			
		||||
    if ( pointStruct.magic != static_cast<int>( BLEND_TESS_MAGIC ) )
 | 
			
		||||
    {
 | 
			
		||||
        ThrowException( "Point returned by poly2tri was probably not one of ours. This indicates we need a new way to store vertex information" );
 | 
			
		||||
    }
 | 
			
		||||
    return pointStruct;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
void BlenderTessellatorP2T::MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const
 | 
			
		||||
{
 | 
			
		||||
    for ( size_t i = 0; i < triangles.size( ); ++i )
 | 
			
		||||
    {
 | 
			
		||||
        p2t::Triangle& Triangle = *triangles[ i ];
 | 
			
		||||
 | 
			
		||||
        PointP2T& pointA = GetActualPointStructure( *Triangle.GetPoint( 0 ) );
 | 
			
		||||
        PointP2T& pointB = GetActualPointStructure( *Triangle.GetPoint( 1 ) );
 | 
			
		||||
        PointP2T& pointC = GetActualPointStructure( *Triangle.GetPoint( 2 ) );
 | 
			
		||||
 | 
			
		||||
        converter->AddFace( pointA.index, pointB.index, pointC.index );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
inline float p2tMax( float a, float b )
 | 
			
		||||
{
 | 
			
		||||
    return a > b ? a : b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
 | 
			
		||||
float BlenderTessellatorP2T::FindLargestMatrixElem( const aiMatrix3x3& mtx ) const
 | 
			
		||||
{
 | 
			
		||||
    float result = 0.0f;
 | 
			
		||||
 | 
			
		||||
    for ( unsigned int x = 0; x < 3; ++x )
 | 
			
		||||
    {
 | 
			
		||||
        for ( unsigned int y = 0; y < 3; ++y )
 | 
			
		||||
        {
 | 
			
		||||
            result = p2tMax( std::fabs( mtx[ x ][ y ] ), result );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
// Apparently Assimp doesn't have matrix scaling
 | 
			
		||||
aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const
 | 
			
		||||
{
 | 
			
		||||
    aiMatrix3x3 result;
 | 
			
		||||
 | 
			
		||||
    for ( unsigned int x = 0; x < 3; ++x )
 | 
			
		||||
    {
 | 
			
		||||
        for ( unsigned int y = 0; y < 3; ++y )
 | 
			
		||||
        {
 | 
			
		||||
            result[ x ][ y ] = mtx[ x ][ y ] * scale;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
 | 
			
		||||
aiVector3D BlenderTessellatorP2T::GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const
 | 
			
		||||
{
 | 
			
		||||
    const float scale = FindLargestMatrixElem( mtx );
 | 
			
		||||
    aiMatrix3x3 mc = ScaleMatrix( mtx, 1.0f / scale );
 | 
			
		||||
    mc = mc * mc * mc;
 | 
			
		||||
 | 
			
		||||
    aiVector3D v( 1.0f );
 | 
			
		||||
    aiVector3D lastV = v;
 | 
			
		||||
    for ( int i = 0; i < 100; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        v = mc * v;
 | 
			
		||||
        v.Normalize( );
 | 
			
		||||
        if ( ( v - lastV ).SquareLength( ) < 1e-16f )
 | 
			
		||||
        {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        lastV = v;
 | 
			
		||||
    }
 | 
			
		||||
    return v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------------------------------
 | 
			
		||||
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
 | 
			
		||||
PlaneP2T BlenderTessellatorP2T::FindLLSQPlane( const std::vector< PointP2T >& points ) const
 | 
			
		||||
{
 | 
			
		||||
    PlaneP2T result;
 | 
			
		||||
 | 
			
		||||
    aiVector3D sum( 0.0 );
 | 
			
		||||
    for ( size_t i = 0; i < points.size( ); ++i )
 | 
			
		||||
    {
 | 
			
		||||
        sum += points[ i ].point3D;
 | 
			
		||||
    }
 | 
			
		||||
    result.centre = sum * (ai_real)( 1.0 / points.size( ) );
 | 
			
		||||
 | 
			
		||||
    ai_real sumXX = 0.0;
 | 
			
		||||
    ai_real sumXY = 0.0;
 | 
			
		||||
    ai_real sumXZ = 0.0;
 | 
			
		||||
    ai_real sumYY = 0.0;
 | 
			
		||||
    ai_real sumYZ = 0.0;
 | 
			
		||||
    ai_real sumZZ = 0.0;
 | 
			
		||||
    for ( size_t i = 0; i < points.size( ); ++i )
 | 
			
		||||
    {
 | 
			
		||||
        aiVector3D offset = points[ i ].point3D - result.centre;
 | 
			
		||||
        sumXX += offset.x * offset.x;
 | 
			
		||||
        sumXY += offset.x * offset.y;
 | 
			
		||||
        sumXZ += offset.x * offset.z;
 | 
			
		||||
        sumYY += offset.y * offset.y;
 | 
			
		||||
        sumYZ += offset.y * offset.z;
 | 
			
		||||
        sumZZ += offset.z * offset.z;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aiMatrix3x3 mtx( sumXX, sumXY, sumXZ, sumXY, sumYY, sumYZ, sumXZ, sumYZ, sumZZ );
 | 
			
		||||
 | 
			
		||||
    const ai_real det = mtx.Determinant( );
 | 
			
		||||
    if ( det == 0.0f )
 | 
			
		||||
    {
 | 
			
		||||
        result.normal = aiVector3D( 0.0f );
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        aiMatrix3x3 invMtx = mtx;
 | 
			
		||||
        invMtx.Inverse( );
 | 
			
		||||
        result.normal = GetEigenVectorFromLargestEigenValue( invMtx );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ASSIMP_BLEND_WITH_POLY_2_TRI
 | 
			
		||||
 | 
			
		||||
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
 | 
			
		||||
							
								
								
									
										214
									
								
								thirdparty/assimp/code/Blender/BlenderTessellator.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										214
									
								
								thirdparty/assimp/code/Blender/BlenderTessellator.h
									
									
									
									
										vendored
									
									
								
							@@ -1,214 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
Open Asset Import Library (assimp)
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2006-2019, 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  BlenderTessellator.h
 | 
			
		||||
 *  @brief A simple tessellation wrapper
 | 
			
		||||
 */
 | 
			
		||||
#ifndef INCLUDED_AI_BLEND_TESSELLATOR_H
 | 
			
		||||
#define INCLUDED_AI_BLEND_TESSELLATOR_H
 | 
			
		||||
 | 
			
		||||
// Use these to toggle between GLU Tessellate or poly2tri
 | 
			
		||||
// Note (acg) keep GLU Tessellate disabled by default - if it is turned on,
 | 
			
		||||
// assimp needs to be linked against GLU, which is currently not yet
 | 
			
		||||
// made configurable in CMake and potentially not wanted by most users
 | 
			
		||||
// as it requires a Gl environment.
 | 
			
		||||
#ifndef ASSIMP_BLEND_WITH_GLU_TESSELLATE
 | 
			
		||||
#   define ASSIMP_BLEND_WITH_GLU_TESSELLATE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef ASSIMP_BLEND_WITH_POLY_2_TRI
 | 
			
		||||
#   define ASSIMP_BLEND_WITH_POLY_2_TRI 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <assimp/LogAux.h>
 | 
			
		||||
 | 
			
		||||
#if ASSIMP_BLEND_WITH_GLU_TESSELLATE
 | 
			
		||||
 | 
			
		||||
#if defined( WIN32 ) || defined( _WIN32 ) || defined( _MSC_VER )
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <GL/glu.h>
 | 
			
		||||
 | 
			
		||||
namespace Assimp
 | 
			
		||||
{
 | 
			
		||||
    class BlenderBMeshConverter;
 | 
			
		||||
 | 
			
		||||
    // TinyFormatter.h
 | 
			
		||||
    namespace Formatter
 | 
			
		||||
    {
 | 
			
		||||
        template < typename T,typename TR, typename A > class basic_formatter;
 | 
			
		||||
        typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // BlenderScene.h
 | 
			
		||||
    namespace Blender
 | 
			
		||||
    {
 | 
			
		||||
        struct MLoop;
 | 
			
		||||
        struct MVert;
 | 
			
		||||
 | 
			
		||||
        struct VertexGL
 | 
			
		||||
        {
 | 
			
		||||
            GLdouble X;
 | 
			
		||||
            GLdouble Y;
 | 
			
		||||
            GLdouble Z;
 | 
			
		||||
            int index;
 | 
			
		||||
            int magic;
 | 
			
		||||
 | 
			
		||||
            VertexGL( GLdouble X, GLdouble Y, GLdouble Z, int index, int magic ): X( X ), Y( Y ), Z( Z ), index( index ), magic( magic ) { }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct DrawCallGL
 | 
			
		||||
        {
 | 
			
		||||
            GLenum drawMode;
 | 
			
		||||
            int baseVertex;
 | 
			
		||||
            int vertexCount;
 | 
			
		||||
 | 
			
		||||
            DrawCallGL( GLenum drawMode, int baseVertex ): drawMode( drawMode ), baseVertex( baseVertex ), vertexCount( 0 ) { }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct TessDataGL
 | 
			
		||||
        {
 | 
			
		||||
            std::vector< DrawCallGL > drawCalls;
 | 
			
		||||
            std::vector< VertexGL > vertices;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class BlenderTessellatorGL: public LogFunctions< BlenderTessellatorGL >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        BlenderTessellatorGL( BlenderBMeshConverter& converter );
 | 
			
		||||
        ~BlenderTessellatorGL( );
 | 
			
		||||
 | 
			
		||||
        void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        void AssertVertexCount( int vertexCount );
 | 
			
		||||
        void GenerateLoopVerts( std::vector< Blender::VertexGL >& polyLoopGL, const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
 | 
			
		||||
        void Tesssellate( std::vector< Blender::VertexGL >& polyLoopGL, Blender::TessDataGL& tessData );
 | 
			
		||||
        void TriangulateDrawCalls( const Blender::TessDataGL& tessData );
 | 
			
		||||
        void MakeFacesFromTris( const Blender::VertexGL* vertices, int vertexCount );
 | 
			
		||||
        void MakeFacesFromTriStrip( const Blender::VertexGL* vertices, int vertexCount );
 | 
			
		||||
        void MakeFacesFromTriFan( const Blender::VertexGL* vertices, int vertexCount );
 | 
			
		||||
 | 
			
		||||
        static void TessellateBegin( GLenum drawModeGL, void* userData );
 | 
			
		||||
        static void TessellateEnd( void* userData );
 | 
			
		||||
        static void TessellateVertex( const void* vtxData, void* userData );
 | 
			
		||||
        static void TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData );
 | 
			
		||||
        static void TessellateEdgeFlag( GLboolean edgeFlag, void* userData );
 | 
			
		||||
        static void TessellateError( GLenum errorCode, void* userData );
 | 
			
		||||
 | 
			
		||||
        BlenderBMeshConverter* converter;
 | 
			
		||||
    };
 | 
			
		||||
} // end of namespace Assimp
 | 
			
		||||
 | 
			
		||||
#endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE
 | 
			
		||||
 | 
			
		||||
#if ASSIMP_BLEND_WITH_POLY_2_TRI
 | 
			
		||||
 | 
			
		||||
#ifdef ASSIMP_USE_HUNTER
 | 
			
		||||
#  include <poly2tri/poly2tri.h>
 | 
			
		||||
#else
 | 
			
		||||
#  include "../contrib/poly2tri/poly2tri/poly2tri.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace Assimp
 | 
			
		||||
{
 | 
			
		||||
    class BlenderBMeshConverter;
 | 
			
		||||
 | 
			
		||||
    // TinyFormatter.h
 | 
			
		||||
    namespace Formatter
 | 
			
		||||
    {
 | 
			
		||||
        template < typename T,typename TR, typename A > class basic_formatter;
 | 
			
		||||
        typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // BlenderScene.h
 | 
			
		||||
    namespace Blender
 | 
			
		||||
    {
 | 
			
		||||
        struct MLoop;
 | 
			
		||||
        struct MVert;
 | 
			
		||||
 | 
			
		||||
        struct PointP2T
 | 
			
		||||
        {
 | 
			
		||||
            aiVector3D point3D;
 | 
			
		||||
            p2t::Point point2D;
 | 
			
		||||
            int magic;
 | 
			
		||||
            int index;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct PlaneP2T
 | 
			
		||||
        {
 | 
			
		||||
            aiVector3D centre;
 | 
			
		||||
            aiVector3D normal;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class BlenderTessellatorP2T: public LogFunctions< BlenderTessellatorP2T >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        BlenderTessellatorP2T( BlenderBMeshConverter& converter );
 | 
			
		||||
        ~BlenderTessellatorP2T( );
 | 
			
		||||
 | 
			
		||||
        void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        void AssertVertexCount( int vertexCount );
 | 
			
		||||
        void Copy3DVertices( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices, std::vector< Blender::PointP2T >& targetVertices ) const;
 | 
			
		||||
        aiMatrix4x4 GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const;
 | 
			
		||||
        void TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const;
 | 
			
		||||
        void ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const;
 | 
			
		||||
        inline Blender::PointP2T& GetActualPointStructure( p2t::Point& point ) const;
 | 
			
		||||
        void MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const;
 | 
			
		||||
 | 
			
		||||
        // Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
 | 
			
		||||
        float FindLargestMatrixElem( const aiMatrix3x3& mtx ) const;
 | 
			
		||||
        aiMatrix3x3 ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const;
 | 
			
		||||
        aiVector3D GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const;
 | 
			
		||||
        Blender::PlaneP2T FindLLSQPlane( const std::vector< Blender::PointP2T >& points ) const;
 | 
			
		||||
 | 
			
		||||
        BlenderBMeshConverter* converter;
 | 
			
		||||
    };
 | 
			
		||||
} // end of namespace Assimp
 | 
			
		||||
 | 
			
		||||
#endif // ASSIMP_BLEND_WITH_POLY_2_TRI
 | 
			
		||||
 | 
			
		||||
#endif // INCLUDED_AI_BLEND_TESSELLATOR_H
 | 
			
		||||
		Reference in New Issue
	
	Block a user