diff options
author | sanine <sanine.not@pm.me> | 2023-02-12 23:53:22 -0600 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2023-02-12 23:53:22 -0600 |
commit | f1fe73d1909a2448a004a88362a1a532d0d4f7c3 (patch) | |
tree | ab37ae3837e2f858de2932bcee9f26e69fab3db1 /libs/assimp/code/AssetLib/Blender | |
parent | f567ea1e2798fd3156a416e61f083ea3e6b95719 (diff) |
switch to tinyobj and nanovg from assimp and cairo
Diffstat (limited to 'libs/assimp/code/AssetLib/Blender')
17 files changed, 0 insertions, 7642 deletions
diff --git a/libs/assimp/code/AssetLib/Blender/BlenderBMesh.cpp b/libs/assimp/code/AssetLib/Blender/BlenderBMesh.cpp deleted file mode 100644 index be536eb..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderBMesh.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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 "BlenderBMesh.h" -#include "BlenderDNA.h" -#include "BlenderScene.h" -#include "BlenderTessellator.h" - -namespace Assimp { -template <> -const char *LogFunctions<BlenderBMeshConverter>::Prefix() { - static auto prefix = "BLEND_BMESH: "; - return prefix; -} -} // namespace Assimp - -using namespace Assimp; -using namespace Assimp::Blender; -using namespace Assimp::Formatter; - -// ------------------------------------------------------------------------------------------------ -BlenderBMeshConverter::BlenderBMeshConverter(const Mesh *mesh) : - BMesh(mesh), - triMesh(nullptr) { - ai_assert(nullptr != mesh); -} - -// ------------------------------------------------------------------------------------------------ -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 = nullptr; -} - -// ------------------------------------------------------------------------------------------------ -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; - face.flag = 0; - // 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 diff --git a/libs/assimp/code/AssetLib/Blender/BlenderBMesh.h b/libs/assimp/code/AssetLib/Blender/BlenderBMesh.h deleted file mode 100644 index 45ca2c8..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderBMesh.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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 diff --git a/libs/assimp/code/AssetLib/Blender/BlenderCustomData.cpp b/libs/assimp/code/AssetLib/Blender/BlenderCustomData.cpp deleted file mode 100644 index c74a6bb..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderCustomData.cpp +++ /dev/null @@ -1,181 +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("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; -} -} // namespace Blender -} // namespace Assimp diff --git a/libs/assimp/code/AssetLib/Blender/BlenderCustomData.h b/libs/assimp/code/AssetLib/Blender/BlenderCustomData.h deleted file mode 100644 index f61d79a..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderCustomData.h +++ /dev/null @@ -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); - } -} diff --git a/libs/assimp/code/AssetLib/Blender/BlenderDNA.cpp b/libs/assimp/code/AssetLib/Blender/BlenderDNA.cpp deleted file mode 100644 index 2910904..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderDNA.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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/TinyFormatter.h> -#include <assimp/fast_atof.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("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; - - 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("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("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("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("BlenderDNA: Got ", dna.structures.size(), " structures with totally ", fields, " fields"); - -#if ASSIMP_BUILD_BLENDER_DEBUG_DNA - dna.DumpToFile(); -#endif - - dna.AddPrimitiveStructures(); - dna.RegisterConverters(); -} - -#if ASSIMP_BUILD_BLENDER_DEBUG_DNA - -#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 // ASSIMP_BUILD_BLENDER_DEBUG_DNA - -// ------------------------------------------------------------------------------------------------ -/*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_VERBOSE_DEBUG(current.id); -#endif -} - -#endif diff --git a/libs/assimp/code/AssetLib/Blender/BlenderDNA.h b/libs/assimp/code/AssetLib/Blender/BlenderDNA.h deleted file mode 100644 index b2158f2..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderDNA.h +++ /dev/null @@ -1,808 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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 <stdint.h> -#include <assimp/DefaultLogger.hpp> -#include <map> -#include <memory> - -// enable verbose log output. really verbose, so be careful. -#ifdef ASSIMP_BUILD_DEBUG -#define ASSIMP_BUILD_BLENDER_DEBUG -#endif - -// set this to non-zero to dump BlenderDNA stuff to dna.txt. -// you could set it on the assimp build command line too without touching it here. -// !!! please make sure this is set to 0 in the repo !!! -#ifndef ASSIMP_BUILD_BLENDER_DEBUG_DNA -#define ASSIMP_BUILD_BLENDER_DEBUG_DNA 0 -#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 { - template <typename... T> - explicit Error(T &&...args) : - DeadlyImportError(args...) { - } -}; - -// ------------------------------------------------------------------------------- -/** 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 behaviors for fields absence 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 - } - - // publicly accessible members - std::string name; - vector<Field> fields; - std::map<std::string, size_t> indices; - - size_t size; - - // -------------------------------------------------------- - /** Access a field of the structure by its canonical name. The pointer version - * returns nullptr 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; - } - - // -------------------------------------------------------- - /** 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() : nullptr; - } - - // -------------------------------------------------------- - template <int error_policy> - struct _defaultInitializer { - - template <typename T, unsigned int N> - void operator()(T (&out)[N], const char * = nullptr) { - 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 * = nullptr) { - 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 * = nullptr) { - 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 nullptr 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 (consider 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; - -#if ASSIMP_BUILD_BLENDER_DEBUG_DNA - // -------------------------------------------------------- - /** 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); - -} // namespace Blender -} // namespace Assimp - -#include "BlenderDNA.inl" - -#endif diff --git a/libs/assimp/code/AssetLib/Blender/BlenderDNA.inl b/libs/assimp/code/AssetLib/Blender/BlenderDNA.inl deleted file mode 100644 index 4f64987..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderDNA.inl +++ /dev/null @@ -1,845 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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("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() ? nullptr : &fields[(*it).second]; -} - -//-------------------------------------------------------------------------------- -const Field& Structure :: operator [] (const size_t i) const -{ - if (i >= fields.size()) { - throw Error("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("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("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("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]; - -#ifdef _DEBUG - // sanity check, should never happen if the genblenddna script is right - if ((FieldFlag_Pointer|FieldFlag_Pointer) != (f->flags & (FieldFlag_Pointer|FieldFlag_Pointer))) { - throw Error("Field `",name,"` of structure `", - this->name,"` ought to be a pointer AND an array"); - } -#endif // _DEBUG - - 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("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("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("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( "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("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("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("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() ? nullptr : &structures[(*it).second]; -} - -//-------------------------------------------------------------------------------- -const Structure& DNA :: operator [] (const size_t i) const -{ - if (i >= structures.size()) { - throw Error("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 diff --git a/libs/assimp/code/AssetLib/Blender/BlenderIntermediate.h b/libs/assimp/code/AssetLib/Blender/BlenderIntermediate.h deleted file mode 100644 index 0651f71..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderIntermediate.h +++ /dev/null @@ -1,206 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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 diff --git a/libs/assimp/code/AssetLib/Blender/BlenderLoader.cpp b/libs/assimp/code/AssetLib/Blender/BlenderLoader.cpp deleted file mode 100644 index b3591b4..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderLoader.cpp +++ /dev/null @@ -1,1340 +0,0 @@ - -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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.cpp - * @brief Implementation of the Blender3D importer class. - */ - -//#define ASSIMP_BUILD_NO_COMPRESSED_BLEND -// Uncomment this to disable support for (gzip)compressed .BLEND files - -#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER - -#include "BlenderBMesh.h" -#include "BlenderCustomData.h" -#include "BlenderIntermediate.h" -#include "BlenderModifier.h" -#include <assimp/StringUtils.h> -#include <assimp/importerdesc.h> -#include <assimp/scene.h> - -#include <assimp/MemoryIOWrapper.h> -#include <assimp/StreamReader.h> -#include <assimp/StringComparison.h> - -#include <cctype> - -// zlib is needed for compressed blend files -#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND -#include "Common/Compression.h" -/* #ifdef ASSIMP_BUILD_NO_OWN_ZLIB -# include <zlib.h> -# else -# include "../contrib/zlib/zlib.h" -# endif*/ -#endif - -namespace Assimp { - -template <> -const char *LogFunctions<BlenderImporter>::Prefix() { - static auto prefix = "BLEND: "; - return prefix; -} - -} // namespace Assimp - -using namespace Assimp; -using namespace Assimp::Blender; -using namespace Assimp::Formatter; - -static const aiImporterDesc blenderDesc = { - "Blender 3D Importer (http://www.blender3d.org)", - "", - "", - "No animation support yet", - aiImporterFlags_SupportBinaryFlavour, - 0, - 0, - 2, - 50, - "blend" -}; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -BlenderImporter::BlenderImporter() : - modifier_cache(new BlenderModifierShowcase()) { - // empty -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -BlenderImporter::~BlenderImporter() { - delete modifier_cache; -} - -static const char * const Tokens[] = { "BLENDER" }; - -// ------------------------------------------------------------------------------------------------ -// Returns whether the class can handle the format of the given file. -bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { - // note: this won't catch compressed files - static const char *tokens[] = { "<BLENDER", "blender" }; - - return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); -} - -// ------------------------------------------------------------------------------------------------ -// Loader registry entry -const aiImporterDesc *BlenderImporter::GetInfo() const { - return &blenderDesc; -} - -// ------------------------------------------------------------------------------------------------ -// Setup configuration properties for the loader -void BlenderImporter::SetupProperties(const Importer * /*pImp*/) { - // nothing to be done for the moment -} - -// ------------------------------------------------------------------------------------------------ -// Imports the given file into the given scene structure. -void BlenderImporter::InternReadFile(const std::string &pFile, - aiScene *pScene, IOSystem *pIOHandler) { -#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND - std::vector<char> uncompressed; -#endif - - FileDatabase file; - std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb")); - if (!stream) { - ThrowException("Could not open file for reading"); - } - - char magic[8] = { 0 }; - stream->Read(magic, 7, 1); - if (strcmp(magic, Tokens[0])) { - // Check for presence of the gzip header. If yes, assume it is a - // compressed blend file and try uncompressing it, else fail. This is to - // avoid uncompressing random files which our loader might end up with. -#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND - ThrowException("BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?"); -#else - if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) { - ThrowException("BLENDER magic bytes are missing, couldn't find GZIP header either"); - } - - LogDebug("Found no BLENDER magic word but a GZIP header, might be a compressed file"); - if (magic[2] != 8) { - ThrowException("Unsupported GZIP compression method"); - } - - // http://www.gzip.org/zlib/rfc-gzip.html#header-trailer - stream->Seek(0L, aiOrigin_SET); - std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream)); - - size_t total = 0; - Compression compression; - if (compression.open(Compression::Format::Binary, Compression::FlushMode::NoFlush, 16 + Compression::MaxWBits)) { - total = compression.decompress((unsigned char *)reader->GetPtr(), reader->GetRemainingSize(), uncompressed); - compression.close(); - } - - // replace the input stream with a memory stream - stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t *>(uncompressed.data()), total)); - - // .. and retry - stream->Read(magic, 7, 1); - if (strcmp(magic, "BLENDER")) { - ThrowException("Found no BLENDER magic word in decompressed GZIP file"); - } -#endif - } - - file.i64bit = (stream->Read(magic, 1, 1), magic[0] == '-'); - file.little = (stream->Read(magic, 1, 1), magic[0] == 'v'); - - stream->Read(magic, 3, 1); - magic[3] = '\0'; - - LogInfo("Blender version is ", magic[0], ".", magic + 1, - " (64bit: ", file.i64bit ? "true" : "false", - ", little endian: ", file.little ? "true" : "false", ")"); - - ParseBlendFile(file, stream); - - Scene scene; - ExtractScene(scene, file); - - ConvertBlendFile(pScene, scene, file); -} - -// ------------------------------------------------------------------------------------------------ -void BlenderImporter::ParseBlendFile(FileDatabase &out, std::shared_ptr<IOStream> stream) { - out.reader = std::make_shared<StreamReaderAny>(stream, out.little); - - DNAParser dna_reader(out); - const DNA *dna = nullptr; - - out.entries.reserve(128); - { // even small BLEND files tend to consist of many file blocks - SectionParser parser(*out.reader.get(), out.i64bit); - - // first parse the file in search for the DNA and insert all other sections into the database - while ((parser.Next(), 1)) { - const FileBlockHead &head = parser.GetCurrent(); - - if (head.id == "ENDB") { - break; // only valid end of the file - } else if (head.id == "DNA1") { - dna_reader.Parse(); - dna = &dna_reader.GetDNA(); - continue; - } - - out.entries.push_back(head); - } - } - if (!dna) { - ThrowException("SDNA not found"); - } - - std::sort(out.entries.begin(), out.entries.end()); -} - -// ------------------------------------------------------------------------------------------------ -void BlenderImporter::ExtractScene(Scene &out, const FileDatabase &file) { - const FileBlockHead *block = nullptr; - std::map<std::string, size_t>::const_iterator it = file.dna.indices.find("Scene"); - if (it == file.dna.indices.end()) { - ThrowException("There is no `Scene` structure record"); - } - - const Structure &ss = file.dna.structures[(*it).second]; - - // we need a scene somewhere to start with. - for (const FileBlockHead &bl : file.entries) { - - // Fix: using the DNA index is more reliable to locate scenes - //if (bl.id == "SC") { - - if (bl.dna_index == (*it).second) { - block = &bl; - break; - } - } - - if (!block) { - ThrowException("There is not a single `Scene` record to load"); - } - - file.reader->SetCurrentPos(block->start); - ss.Convert(out, file); - -#ifndef ASSIMP_BUILD_BLENDER_NO_STATS - ASSIMP_LOG_INFO( - "(Stats) Fields read: ", file.stats().fields_read, - ", pointers resolved: ", file.stats().pointers_resolved, - ", cache hits: ", file.stats().cache_hits, - ", cached objects: ", file.stats().cached_objects); -#endif -} - -// ------------------------------------------------------------------------------------------------ -void BlenderImporter::ParseSubCollection(const Blender::Scene &in, aiNode *root, std::shared_ptr<Collection> collection, ConversionData &conv_data) { - - std::deque<Object *> root_objects; - // Count number of objects - for (std::shared_ptr<CollectionObject> cur = std::static_pointer_cast<CollectionObject>(collection->gobject.first); cur; cur = cur->next) { - if (cur->ob) { - root_objects.push_back(cur->ob); - } - } - std::deque<Collection *> root_children; - // Count number of child nodes - for (std::shared_ptr<CollectionChild> cur = std::static_pointer_cast<CollectionChild>(collection->children.first); cur; cur = cur->next) { - if (cur->collection) { - root_children.push_back(cur->collection.get()); - } - } - root->mNumChildren = static_cast<unsigned int>(root_objects.size() + root_children.size()); - root->mChildren = new aiNode *[root->mNumChildren](); - - for (unsigned int i = 0; i < static_cast<unsigned int>(root_objects.size()); ++i) { - root->mChildren[i] = ConvertNode(in, root_objects[i], conv_data, aiMatrix4x4()); - root->mChildren[i]->mParent = root; - } - - // For each subcollection create a new node to represent it - unsigned int iterator = static_cast<unsigned int>(root_objects.size()); - for (std::shared_ptr<CollectionChild> cur = std::static_pointer_cast<CollectionChild>(collection->children.first); cur; cur = cur->next) { - if (cur->collection) { - root->mChildren[iterator] = new aiNode(cur->collection->id.name + 2); // skip over the name prefix 'OB' - root->mChildren[iterator]->mParent = root; - ParseSubCollection(in, root->mChildren[iterator], cur->collection, conv_data); - } - iterator += 1; - } -} - -// ------------------------------------------------------------------------------------------------ -void BlenderImporter::ConvertBlendFile(aiScene *out, const Scene &in, const FileDatabase &file) { - ConversionData conv(file); - - aiNode *root = out->mRootNode = new aiNode("<BlenderRoot>"); - // Iterate over all objects directly under master_collection, - // If in.master_collection == null, then we're parsing something older. - if (in.master_collection) { - ParseSubCollection(in, root, in.master_collection, conv); - } else { - std::deque<const Object *> no_parents; - for (std::shared_ptr<Base> cur = std::static_pointer_cast<Base>(in.base.first); cur; cur = cur->next) { - if (cur->object) { - if (!cur->object->parent) { - no_parents.push_back(cur->object.get()); - } else { - conv.objects.insert(cur->object.get()); - } - } - } - for (std::shared_ptr<Base> cur = in.basact; cur; cur = cur->next) { - if (cur->object) { - if (cur->object->parent) { - conv.objects.insert(cur->object.get()); - } - } - } - - if (no_parents.empty()) { - ThrowException("Expected at least one object with no parent"); - } - - root->mNumChildren = static_cast<unsigned int>(no_parents.size()); - root->mChildren = new aiNode *[root->mNumChildren](); - for (unsigned int i = 0; i < root->mNumChildren; ++i) { - root->mChildren[i] = ConvertNode(in, no_parents[i], conv, aiMatrix4x4()); - root->mChildren[i]->mParent = root; - } - } - - BuildMaterials(conv); - - if (conv.meshes->size()) { - out->mMeshes = new aiMesh *[out->mNumMeshes = static_cast<unsigned int>(conv.meshes->size())]; - std::copy(conv.meshes->begin(), conv.meshes->end(), out->mMeshes); - conv.meshes.dismiss(); - } - - if (conv.lights->size()) { - out->mLights = new aiLight *[out->mNumLights = static_cast<unsigned int>(conv.lights->size())]; - std::copy(conv.lights->begin(), conv.lights->end(), out->mLights); - conv.lights.dismiss(); - } - - if (conv.cameras->size()) { - out->mCameras = new aiCamera *[out->mNumCameras = static_cast<unsigned int>(conv.cameras->size())]; - std::copy(conv.cameras->begin(), conv.cameras->end(), out->mCameras); - conv.cameras.dismiss(); - } - - if (conv.materials->size()) { - out->mMaterials = new aiMaterial *[out->mNumMaterials = static_cast<unsigned int>(conv.materials->size())]; - std::copy(conv.materials->begin(), conv.materials->end(), out->mMaterials); - conv.materials.dismiss(); - } - - if (conv.textures->size()) { - out->mTextures = new aiTexture *[out->mNumTextures = static_cast<unsigned int>(conv.textures->size())]; - std::copy(conv.textures->begin(), conv.textures->end(), out->mTextures); - conv.textures.dismiss(); - } - - // acknowledge that the scene might come out incomplete - // by Assimp's definition of `complete`: blender scenes - // can consist of thousands of cameras or lights with - // not a single mesh between them. - if (!out->mNumMeshes) { - out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; - } -} - -// ------------------------------------------------------------------------------------------------ -void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const MTex *tex, const Image *img, ConversionData &conv_data) { - (void)mat; - (void)tex; - (void)conv_data; - aiString name; - - // check if the file contents are bundled with the BLEND file - if (img->packedfile) { - name.data[0] = '*'; - name.length = 1 + ASSIMP_itoa10(name.data + 1, static_cast<unsigned int>(MAXLEN - 1), static_cast<int32_t>(conv_data.textures->size())); - - conv_data.textures->push_back(new aiTexture()); - aiTexture *curTex = conv_data.textures->back(); - - // usually 'img->name' will be the original file name of the embedded textures, - // so we can extract the file extension from it. - const size_t nlen = strlen(img->name); - const char *s = img->name + nlen, *e = s; - while (s >= img->name && *s != '.') { - --s; - } - - curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower((unsigned char)s[1]); - curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower((unsigned char)s[2]); - curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower((unsigned char)s[3]); - curTex->achFormatHint[3] = '\0'; - - // tex->mHeight = 0; - curTex->mWidth = img->packedfile->size; - uint8_t *ch = new uint8_t[curTex->mWidth]; - - conv_data.db.reader->SetCurrentPos(static_cast<size_t>(img->packedfile->data->val)); - conv_data.db.reader->CopyAndAdvance(ch, curTex->mWidth); - - curTex->pcData = reinterpret_cast<aiTexel *>(ch); - - LogInfo("Reading embedded texture, original file was ", img->name); - } else { - name = aiString(img->name); - } - - aiTextureType texture_type = aiTextureType_UNKNOWN; - MTex::MapType map_type = tex->mapto; - - if (map_type & MTex::MapType_COL) - texture_type = aiTextureType_DIFFUSE; - else if (map_type & MTex::MapType_NORM) { - if (tex->tex->imaflag & Tex::ImageFlags_NORMALMAP) { - texture_type = aiTextureType_NORMALS; - } else { - texture_type = aiTextureType_HEIGHT; - } - out->AddProperty(&tex->norfac, 1, AI_MATKEY_BUMPSCALING); - } else if (map_type & MTex::MapType_COLSPEC) - texture_type = aiTextureType_SPECULAR; - else if (map_type & MTex::MapType_COLMIR) - texture_type = aiTextureType_REFLECTION; - //else if (map_type & MTex::MapType_REF) - else if (map_type & MTex::MapType_SPEC) - texture_type = aiTextureType_SHININESS; - else if (map_type & MTex::MapType_EMIT) - texture_type = aiTextureType_EMISSIVE; - //else if (map_type & MTex::MapType_ALPHA) - //else if (map_type & MTex::MapType_HAR) - //else if (map_type & MTex::MapType_RAYMIRR) - //else if (map_type & MTex::MapType_TRANSLU) - else if (map_type & MTex::MapType_AMB) - texture_type = aiTextureType_AMBIENT; - else if (map_type & MTex::MapType_DISPLACE) - texture_type = aiTextureType_DISPLACEMENT; - //else if (map_type & MTex::MapType_WARP) - - out->AddProperty(&name, AI_MATKEY_TEXTURE(texture_type, - conv_data.next_texture[texture_type]++)); -} - -// ------------------------------------------------------------------------------------------------ -void BlenderImporter::AddSentinelTexture(aiMaterial *out, const Material *mat, const MTex *tex, ConversionData &conv_data) { - (void)mat; - (void)tex; - (void)conv_data; - - aiString name; - name.length = ai_snprintf(name.data, MAXLEN, "Procedural,num=%i,type=%s", conv_data.sentinel_cnt++, - GetTextureTypeDisplayString(tex->tex->type)); - out->AddProperty(&name, AI_MATKEY_TEXTURE_DIFFUSE( - conv_data.next_texture[aiTextureType_DIFFUSE]++)); -} - -// ------------------------------------------------------------------------------------------------ -void BlenderImporter::ResolveTexture(aiMaterial *out, const Material *mat, const MTex *tex, ConversionData &conv_data) { - const Tex *rtex = tex->tex.get(); - if (!rtex || !rtex->type) { - return; - } - - // We can't support most of the texture types because they're mostly procedural. - // These are substituted by a dummy texture. - const char *dispnam = ""; - switch (rtex->type) { - // these are listed in blender's UI - case Tex::Type_CLOUDS: - case Tex::Type_WOOD: - case Tex::Type_MARBLE: - case Tex::Type_MAGIC: - case Tex::Type_BLEND: - case Tex::Type_STUCCI: - case Tex::Type_NOISE: - case Tex::Type_PLUGIN: - case Tex::Type_MUSGRAVE: - case Tex::Type_VORONOI: - case Tex::Type_DISTNOISE: - case Tex::Type_ENVMAP: - - // these do no appear in the UI, why? - case Tex::Type_POINTDENSITY: - case Tex::Type_VOXELDATA: - - LogWarn("Encountered a texture with an unsupported type: ", dispnam); - AddSentinelTexture(out, mat, tex, conv_data); - break; - - case Tex::Type_IMAGE: - if (!rtex->ima) { - LogError("A texture claims to be an Image, but no image reference is given"); - break; - } - ResolveImage(out, mat, tex, rtex->ima.get(), conv_data); - break; - - default: - ai_assert(false); - }; -} - -// ------------------------------------------------------------------------------------------------ -void BlenderImporter::BuildDefaultMaterial(Blender::ConversionData &conv_data) { - // add a default material if necessary - unsigned int index = static_cast<unsigned int>(-1); - for (aiMesh *mesh : conv_data.meshes.get()) { - if (mesh->mMaterialIndex == static_cast<unsigned int>(-1)) { - - if (index == static_cast<unsigned int>(-1)) { - // Setup a default material. - std::shared_ptr<Material> p(new Material()); - ai_assert(::strlen(AI_DEFAULT_MATERIAL_NAME) < sizeof(p->id.name) - 2); - strcpy(p->id.name + 2, AI_DEFAULT_MATERIAL_NAME); - - // Note: MSVC11 does not zero-initialize Material here, although it should. - // Thus all relevant fields should be explicitly initialized. We cannot add - // a default constructor to Material since the DNA codegen does not support - // parsing it. - p->r = p->g = p->b = 0.6f; - p->specr = p->specg = p->specb = 0.6f; - p->ambr = p->ambg = p->ambb = 0.0f; - p->mirr = p->mirg = p->mirb = 0.0f; - p->emit = 0.f; - p->alpha = 0.f; - p->har = 0; - - index = static_cast<unsigned int>(conv_data.materials_raw.size()); - conv_data.materials_raw.push_back(p); - LogInfo("Adding default material"); - } - mesh->mMaterialIndex = index; - } - } -} - -void BlenderImporter::AddBlendParams(aiMaterial *result, const Material *source) { - aiColor3D diffuseColor(source->r, source->g, source->b); - result->AddProperty(&diffuseColor, 1, "$mat.blend.diffuse.color", 0, 0); - - float diffuseIntensity = source->ref; - result->AddProperty(&diffuseIntensity, 1, "$mat.blend.diffuse.intensity", 0, 0); - - int diffuseShader = source->diff_shader; - result->AddProperty(&diffuseShader, 1, "$mat.blend.diffuse.shader", 0, 0); - - int diffuseRamp = 0; - result->AddProperty(&diffuseRamp, 1, "$mat.blend.diffuse.ramp", 0, 0); - - aiColor3D specularColor(source->specr, source->specg, source->specb); - result->AddProperty(&specularColor, 1, "$mat.blend.specular.color", 0, 0); - - float specularIntensity = source->spec; - result->AddProperty(&specularIntensity, 1, "$mat.blend.specular.intensity", 0, 0); - - int specularShader = source->spec_shader; - result->AddProperty(&specularShader, 1, "$mat.blend.specular.shader", 0, 0); - - int specularRamp = 0; - result->AddProperty(&specularRamp, 1, "$mat.blend.specular.ramp", 0, 0); - - int specularHardness = source->har; - result->AddProperty(&specularHardness, 1, "$mat.blend.specular.hardness", 0, 0); - - int transparencyUse = source->mode & MA_TRANSPARENCY ? 1 : 0; - result->AddProperty(&transparencyUse, 1, "$mat.blend.transparency.use", 0, 0); - - int transparencyMethod = source->mode & MA_RAYTRANSP ? 2 : (source->mode & MA_ZTRANSP ? 1 : 0); - result->AddProperty(&transparencyMethod, 1, "$mat.blend.transparency.method", 0, 0); - - float transparencyAlpha = source->alpha; - result->AddProperty(&transparencyAlpha, 1, "$mat.blend.transparency.alpha", 0, 0); - - float transparencySpecular = source->spectra; - result->AddProperty(&transparencySpecular, 1, "$mat.blend.transparency.specular", 0, 0); - - float transparencyFresnel = source->fresnel_tra; - result->AddProperty(&transparencyFresnel, 1, "$mat.blend.transparency.fresnel", 0, 0); - - float transparencyBlend = source->fresnel_tra_i; - result->AddProperty(&transparencyBlend, 1, "$mat.blend.transparency.blend", 0, 0); - - float transparencyIor = source->ang; - result->AddProperty(&transparencyIor, 1, "$mat.blend.transparency.ior", 0, 0); - - float transparencyFilter = source->filter; - result->AddProperty(&transparencyFilter, 1, "$mat.blend.transparency.filter", 0, 0); - - float transparencyFalloff = source->tx_falloff; - result->AddProperty(&transparencyFalloff, 1, "$mat.blend.transparency.falloff", 0, 0); - - float transparencyLimit = source->tx_limit; - result->AddProperty(&transparencyLimit, 1, "$mat.blend.transparency.limit", 0, 0); - - int transparencyDepth = source->ray_depth_tra; - result->AddProperty(&transparencyDepth, 1, "$mat.blend.transparency.depth", 0, 0); - - float transparencyGlossAmount = source->gloss_tra; - result->AddProperty(&transparencyGlossAmount, 1, "$mat.blend.transparency.glossAmount", 0, 0); - - float transparencyGlossThreshold = source->adapt_thresh_tra; - result->AddProperty(&transparencyGlossThreshold, 1, "$mat.blend.transparency.glossThreshold", 0, 0); - - int transparencyGlossSamples = source->samp_gloss_tra; - result->AddProperty(&transparencyGlossSamples, 1, "$mat.blend.transparency.glossSamples", 0, 0); - - int mirrorUse = source->mode & MA_RAYMIRROR ? 1 : 0; - result->AddProperty(&mirrorUse, 1, "$mat.blend.mirror.use", 0, 0); - - float mirrorReflectivity = source->ray_mirror; - result->AddProperty(&mirrorReflectivity, 1, "$mat.blend.mirror.reflectivity", 0, 0); - - aiColor3D mirrorColor(source->mirr, source->mirg, source->mirb); - result->AddProperty(&mirrorColor, 1, "$mat.blend.mirror.color", 0, 0); - - float mirrorFresnel = source->fresnel_mir; - result->AddProperty(&mirrorFresnel, 1, "$mat.blend.mirror.fresnel", 0, 0); - - float mirrorBlend = source->fresnel_mir_i; - result->AddProperty(&mirrorBlend, 1, "$mat.blend.mirror.blend", 0, 0); - - int mirrorDepth = source->ray_depth; - result->AddProperty(&mirrorDepth, 1, "$mat.blend.mirror.depth", 0, 0); - - float mirrorMaxDist = source->dist_mir; - result->AddProperty(&mirrorMaxDist, 1, "$mat.blend.mirror.maxDist", 0, 0); - - int mirrorFadeTo = source->fadeto_mir; - result->AddProperty(&mirrorFadeTo, 1, "$mat.blend.mirror.fadeTo", 0, 0); - - float mirrorGlossAmount = source->gloss_mir; - result->AddProperty(&mirrorGlossAmount, 1, "$mat.blend.mirror.glossAmount", 0, 0); - - float mirrorGlossThreshold = source->adapt_thresh_mir; - result->AddProperty(&mirrorGlossThreshold, 1, "$mat.blend.mirror.glossThreshold", 0, 0); - - int mirrorGlossSamples = source->samp_gloss_mir; - result->AddProperty(&mirrorGlossSamples, 1, "$mat.blend.mirror.glossSamples", 0, 0); - - float mirrorGlossAnisotropic = source->aniso_gloss_mir; - result->AddProperty(&mirrorGlossAnisotropic, 1, "$mat.blend.mirror.glossAnisotropic", 0, 0); -} - -void BlenderImporter::BuildMaterials(ConversionData &conv_data) { - conv_data.materials->reserve(conv_data.materials_raw.size()); - - BuildDefaultMaterial(conv_data); - - for (const std::shared_ptr<Material> &mat : conv_data.materials_raw) { - - // reset per material global counters - for (size_t i = 0; i < sizeof(conv_data.next_texture) / sizeof(conv_data.next_texture[0]); ++i) { - conv_data.next_texture[i] = 0; - } - - aiMaterial *mout = new aiMaterial(); - conv_data.materials->push_back(mout); - // For any new material field handled here, the default material above must be updated with an appropriate default value. - - // set material name - aiString name = aiString(mat->id.name + 2); // skip over the name prefix 'MA' - mout->AddProperty(&name, AI_MATKEY_NAME); - - // basic material colors - aiColor3D col(mat->r, mat->g, mat->b); - if (mat->r || mat->g || mat->b) { - - // Usually, zero diffuse color means no diffuse color at all in the equation. - // So we omit this member to express this intent. - mout->AddProperty(&col, 1, AI_MATKEY_COLOR_DIFFUSE); - - if (mat->emit) { - aiColor3D emit_col(mat->emit * mat->r, mat->emit * mat->g, mat->emit * mat->b); - mout->AddProperty(&emit_col, 1, AI_MATKEY_COLOR_EMISSIVE); - } - } - - col = aiColor3D(mat->specr, mat->specg, mat->specb); - mout->AddProperty(&col, 1, AI_MATKEY_COLOR_SPECULAR); - - // is hardness/shininess set? - if (mat->har) { - const float har = mat->har; - mout->AddProperty(&har, 1, AI_MATKEY_SHININESS); - } - - col = aiColor3D(mat->ambr, mat->ambg, mat->ambb); - mout->AddProperty(&col, 1, AI_MATKEY_COLOR_AMBIENT); - - // is mirror enabled? - if (mat->mode & MA_RAYMIRROR) { - const float ray_mirror = mat->ray_mirror; - mout->AddProperty(&ray_mirror, 1, AI_MATKEY_REFLECTIVITY); - } - - col = aiColor3D(mat->mirr, mat->mirg, mat->mirb); - mout->AddProperty(&col, 1, AI_MATKEY_COLOR_REFLECTIVE); - - for (size_t i = 0; i < sizeof(mat->mtex) / sizeof(mat->mtex[0]); ++i) { - if (!mat->mtex[i]) { - continue; - } - - ResolveTexture(mout, mat.get(), mat->mtex[i].get(), conv_data); - } - - AddBlendParams(mout, mat.get()); - } -} - -// ------------------------------------------------------------------------------------------------ -void BlenderImporter::CheckActualType(const ElemBase *dt, const char *check) { - ai_assert(dt); - if (strcmp(dt->dna_type, check)) { - ThrowException("Expected object at ", std::hex, dt, " to be of type `", check, - "`, but it claims to be a `", dt->dna_type, "`instead"); - } -} - -// ------------------------------------------------------------------------------------------------ -void BlenderImporter::NotSupportedObjectType(const Object *obj, const char *type) { - LogWarn("Object `", obj->id.name, "` - type is unsupported: `", type, "`, skipping"); -} - -// ------------------------------------------------------------------------------------------------ -void BlenderImporter::ConvertMesh(const Scene & /*in*/, const Object * /*obj*/, const Mesh *mesh, - ConversionData &conv_data, TempArray<std::vector, aiMesh> &temp) { - // TODO: Resolve various problems with BMesh triangulation before re-enabling. - // See issues #400, #373, #318 #315 and #132. -#if defined(TODO_FIX_BMESH_CONVERSION) - BlenderBMeshConverter BMeshConverter(mesh); - if (BMeshConverter.ContainsBMesh()) { - mesh = BMeshConverter.TriangulateBMesh(); - } -#endif - - typedef std::pair<const int, size_t> MyPair; - if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) { - return; - } - - // some sanity checks - if (static_cast<size_t>(mesh->totface) > mesh->mface.size()) { - ThrowException("Number of faces is larger than the corresponding array"); - } - - if (static_cast<size_t>(mesh->totvert) > mesh->mvert.size()) { - ThrowException("Number of vertices is larger than the corresponding array"); - } - - if (static_cast<size_t>(mesh->totloop) > mesh->mloop.size()) { - ThrowException("Number of vertices is larger than the corresponding array"); - } - - // collect per-submesh numbers - std::map<int, size_t> per_mat; - std::map<int, size_t> per_mat_verts; - for (int i = 0; i < mesh->totface; ++i) { - - const MFace &mf = mesh->mface[i]; - per_mat[mf.mat_nr]++; - per_mat_verts[mf.mat_nr] += mf.v4 ? 4 : 3; - } - - for (int i = 0; i < mesh->totpoly; ++i) { - const MPoly &mp = mesh->mpoly[i]; - per_mat[mp.mat_nr]++; - per_mat_verts[mp.mat_nr] += mp.totloop; - } - - // ... and allocate the corresponding meshes - const size_t old = temp->size(); - temp->reserve(temp->size() + per_mat.size()); - - std::map<size_t, size_t> mat_num_to_mesh_idx; - for (MyPair &it : per_mat) { - - mat_num_to_mesh_idx[it.first] = temp->size(); - temp->push_back(new aiMesh()); - - aiMesh *out = temp->back(); - out->mVertices = new aiVector3D[per_mat_verts[it.first]]; - out->mNormals = new aiVector3D[per_mat_verts[it.first]]; - - //out->mNumFaces = 0 - //out->mNumVertices = 0 - out->mFaces = new aiFace[it.second](); - - // all sub-meshes created from this mesh are named equally. this allows - // curious users to recover the original adjacency. - out->mName = aiString(mesh->id.name + 2); - // skip over the name prefix 'ME' - - // resolve the material reference and add this material to the set of - // output materials. The (temporary) material index is the index - // of the material entry within the list of resolved materials. - if (mesh->mat) { - - if (static_cast<size_t>(it.first) >= mesh->mat.size()) { - ThrowException("Material index is out of range"); - } - - std::shared_ptr<Material> mat = mesh->mat[it.first]; - const std::deque<std::shared_ptr<Material>>::iterator has = std::find( - conv_data.materials_raw.begin(), - conv_data.materials_raw.end(), mat); - - if (has != conv_data.materials_raw.end()) { - out->mMaterialIndex = static_cast<unsigned int>(std::distance(conv_data.materials_raw.begin(), has)); - } else { - out->mMaterialIndex = static_cast<unsigned int>(conv_data.materials_raw.size()); - conv_data.materials_raw.push_back(mat); - } - } else - out->mMaterialIndex = static_cast<unsigned int>(-1); - } - - for (int i = 0; i < mesh->totface; ++i) { - - const MFace &mf = mesh->mface[i]; - - aiMesh *const out = temp[mat_num_to_mesh_idx[mf.mat_nr]]; - aiFace &f = out->mFaces[out->mNumFaces++]; - - f.mIndices = new unsigned int[f.mNumIndices = mf.v4 ? 4 : 3]; - aiVector3D *vo = out->mVertices + out->mNumVertices; - aiVector3D *vn = out->mNormals + out->mNumVertices; - - // XXX we can't fold this easily, because we are restricted - // to the member names from the BLEND file (v1,v2,v3,v4) - // which are assigned by the genblenddna.py script and - // cannot be changed without breaking the entire - // import process. - - if (mf.v1 >= mesh->totvert) { - ThrowException("Vertex index v1 out of range"); - } - const MVert *v = &mesh->mvert[mf.v1]; - vo->x = v->co[0]; - vo->y = v->co[1]; - vo->z = v->co[2]; - vn->x = v->no[0]; - vn->y = v->no[1]; - vn->z = v->no[2]; - f.mIndices[0] = out->mNumVertices++; - ++vo; - ++vn; - - // if (f.mNumIndices >= 2) { - if (mf.v2 >= mesh->totvert) { - ThrowException("Vertex index v2 out of range"); - } - v = &mesh->mvert[mf.v2]; - vo->x = v->co[0]; - vo->y = v->co[1]; - vo->z = v->co[2]; - vn->x = v->no[0]; - vn->y = v->no[1]; - vn->z = v->no[2]; - f.mIndices[1] = out->mNumVertices++; - ++vo; - ++vn; - - if (mf.v3 >= mesh->totvert) { - ThrowException("Vertex index v3 out of range"); - } - // if (f.mNumIndices >= 3) { - v = &mesh->mvert[mf.v3]; - vo->x = v->co[0]; - vo->y = v->co[1]; - vo->z = v->co[2]; - vn->x = v->no[0]; - vn->y = v->no[1]; - vn->z = v->no[2]; - f.mIndices[2] = out->mNumVertices++; - ++vo; - ++vn; - - if (mf.v4 >= mesh->totvert) { - ThrowException("Vertex index v4 out of range"); - } - // if (f.mNumIndices >= 4) { - if (mf.v4) { - v = &mesh->mvert[mf.v4]; - vo->x = v->co[0]; - vo->y = v->co[1]; - vo->z = v->co[2]; - vn->x = v->no[0]; - vn->y = v->no[1]; - vn->z = v->no[2]; - f.mIndices[3] = out->mNumVertices++; - ++vo; - ++vn; - - out->mPrimitiveTypes |= aiPrimitiveType_POLYGON; - } else - out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - - // } - // } - // } - } - - for (int i = 0; i < mesh->totpoly; ++i) { - - const MPoly &mf = mesh->mpoly[i]; - - aiMesh *const out = temp[mat_num_to_mesh_idx[mf.mat_nr]]; - aiFace &f = out->mFaces[out->mNumFaces++]; - - f.mIndices = new unsigned int[f.mNumIndices = mf.totloop]; - aiVector3D *vo = out->mVertices + out->mNumVertices; - aiVector3D *vn = out->mNormals + out->mNumVertices; - - // XXX we can't fold this easily, because we are restricted - // to the member names from the BLEND file (v1,v2,v3,v4) - // which are assigned by the genblenddna.py script and - // cannot be changed without breaking the entire - // import process. - for (int j = 0; j < mf.totloop; ++j) { - const MLoop &loop = mesh->mloop[mf.loopstart + j]; - - if (loop.v >= mesh->totvert) { - ThrowException("Vertex index out of range"); - } - - const MVert &v = mesh->mvert[loop.v]; - - vo->x = v.co[0]; - vo->y = v.co[1]; - vo->z = v.co[2]; - vn->x = v.no[0]; - vn->y = v.no[1]; - vn->z = v.no[2]; - f.mIndices[j] = out->mNumVertices++; - - ++vo; - ++vn; - } - if (mf.totloop == 3) { - out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - } else { - out->mPrimitiveTypes |= aiPrimitiveType_POLYGON; - } - } - - // TODO should we create the TextureUVMapping map in Convert<Material> to prevent redundant processing? - - // create texture <-> uvname mapping for all materials - // key is texture number, value is data * - typedef std::map<uint32_t, const MLoopUV *> TextureUVMapping; - // key is material number, value is the TextureUVMapping for the material - typedef std::map<uint32_t, TextureUVMapping> MaterialTextureUVMappings; - MaterialTextureUVMappings matTexUvMappings; - const uint32_t maxMat = static_cast<const uint32_t>(mesh->mat.size()); - for (uint32_t m = 0; m < maxMat; ++m) { - // get material by index - const std::shared_ptr<Material> pMat = mesh->mat[m]; - TextureUVMapping texuv; - const uint32_t maxTex = sizeof(pMat->mtex) / sizeof(pMat->mtex[0]); - for (uint32_t t = 0; t < maxTex; ++t) { - if (pMat->mtex[t] && pMat->mtex[t]->uvname[0]) { - // get the CustomData layer for given uvname and correct type - const ElemBase *pLoop = getCustomDataLayerData(mesh->ldata, CD_MLOOPUV, pMat->mtex[t]->uvname); - if (pLoop) { - texuv.insert(std::make_pair(t, dynamic_cast<const MLoopUV *>(pLoop))); - } - } - } - if (texuv.size()) { - matTexUvMappings.insert(std::make_pair(m, texuv)); - } - } - - // collect texture coordinates, they're stored in a separate per-face buffer - if (mesh->mtface || mesh->mloopuv) { - if (mesh->totface > static_cast<int>(mesh->mtface.size())) { - ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)"); - } - for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) { - ai_assert(0 != (*it)->mNumVertices); - ai_assert(0 != (*it)->mNumFaces); - const auto itMatTexUvMapping = matTexUvMappings.find((*it)->mMaterialIndex); - if (itMatTexUvMapping == matTexUvMappings.end()) { - // default behaviour like before - (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices]; - } else { - // create texture coords for every mapped tex - for (uint32_t i = 0; i < itMatTexUvMapping->second.size(); ++i) { - (*it)->mTextureCoords[i] = new aiVector3D[(*it)->mNumVertices]; - } - } - (*it)->mNumFaces = (*it)->mNumVertices = 0; - } - - for (int i = 0; i < mesh->totface; ++i) { - const MTFace *v = &mesh->mtface[i]; - - aiMesh *const out = temp[mat_num_to_mesh_idx[mesh->mface[i].mat_nr]]; - const aiFace &f = out->mFaces[out->mNumFaces++]; - - aiVector3D *vo = &out->mTextureCoords[0][out->mNumVertices]; - for (unsigned int j = 0; j < f.mNumIndices; ++j, ++vo, ++out->mNumVertices) { - vo->x = v->uv[j][0]; - vo->y = v->uv[j][1]; - } - } - - for (int i = 0; i < mesh->totpoly; ++i) { - const MPoly &v = mesh->mpoly[i]; - aiMesh *const out = temp[mat_num_to_mesh_idx[v.mat_nr]]; - const aiFace &f = out->mFaces[out->mNumFaces++]; - - const auto itMatTexUvMapping = matTexUvMappings.find(v.mat_nr); - if (itMatTexUvMapping == matTexUvMappings.end()) { - // old behavior - aiVector3D *vo = &out->mTextureCoords[0][out->mNumVertices]; - for (unsigned int j = 0; j < f.mNumIndices; ++j, ++vo, ++out->mNumVertices) { - const MLoopUV &uv = mesh->mloopuv[v.loopstart + j]; - vo->x = uv.uv[0]; - vo->y = uv.uv[1]; - } - } else { - // create textureCoords for every mapped tex - for (uint32_t m = 0; m < itMatTexUvMapping->second.size(); ++m) { - const MLoopUV *tm = itMatTexUvMapping->second[m]; - aiVector3D *vo = &out->mTextureCoords[m][out->mNumVertices]; - uint32_t j = 0; - for (; j < f.mNumIndices; ++j, ++vo) { - const MLoopUV &uv = tm[v.loopstart + j]; - vo->x = uv.uv[0]; - vo->y = uv.uv[1]; - } - // only update written mNumVertices in last loop - // TODO why must the numVertices be incremented here? - if (m == itMatTexUvMapping->second.size() - 1) { - out->mNumVertices += j; - } - } - } - } - } - - // collect texture coordinates, old-style (marked as deprecated in current blender sources) - if (mesh->tface) { - if (mesh->totface > static_cast<int>(mesh->tface.size())) { - ThrowException("Number of faces is larger than the corresponding UV face array (#2)"); - } - for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) { - ai_assert(0 != (*it)->mNumVertices); - ai_assert(0 != (*it)->mNumFaces); - - (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices]; - (*it)->mNumFaces = (*it)->mNumVertices = 0; - } - - for (int i = 0; i < mesh->totface; ++i) { - const TFace *v = &mesh->tface[i]; - - aiMesh *const out = temp[mat_num_to_mesh_idx[mesh->mface[i].mat_nr]]; - const aiFace &f = out->mFaces[out->mNumFaces++]; - - aiVector3D *vo = &out->mTextureCoords[0][out->mNumVertices]; - for (unsigned int j = 0; j < f.mNumIndices; ++j, ++vo, ++out->mNumVertices) { - vo->x = v->uv[j][0]; - vo->y = v->uv[j][1]; - } - } - } - - // collect vertex colors, stored separately as well - if (mesh->mcol || mesh->mloopcol) { - if (mesh->totface > static_cast<int>((mesh->mcol.size() / 4))) { - ThrowException("Number of faces is larger than the corresponding color face array"); - } - for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) { - ai_assert(0 != (*it)->mNumVertices); - ai_assert(0 != (*it)->mNumFaces); - - (*it)->mColors[0] = new aiColor4D[(*it)->mNumVertices]; - (*it)->mNumFaces = (*it)->mNumVertices = 0; - } - - for (int i = 0; i < mesh->totface; ++i) { - - aiMesh *const out = temp[mat_num_to_mesh_idx[mesh->mface[i].mat_nr]]; - const aiFace &f = out->mFaces[out->mNumFaces++]; - - aiColor4D *vo = &out->mColors[0][out->mNumVertices]; - for (unsigned int n = 0; n < f.mNumIndices; ++n, ++vo, ++out->mNumVertices) { - const MCol *col = &mesh->mcol[(i << 2) + n]; - - vo->r = col->r; - vo->g = col->g; - vo->b = col->b; - vo->a = col->a; - } - for (unsigned int n = f.mNumIndices; n < 4; ++n) - ; - } - - for (int i = 0; i < mesh->totpoly; ++i) { - const MPoly &v = mesh->mpoly[i]; - aiMesh *const out = temp[mat_num_to_mesh_idx[v.mat_nr]]; - const aiFace &f = out->mFaces[out->mNumFaces++]; - - aiColor4D *vo = &out->mColors[0][out->mNumVertices]; - const ai_real scaleZeroToOne = 1.f / 255.f; - for (unsigned int j = 0; j < f.mNumIndices; ++j, ++vo, ++out->mNumVertices) { - const MLoopCol &col = mesh->mloopcol[v.loopstart + j]; - vo->r = ai_real(col.r) * scaleZeroToOne; - vo->g = ai_real(col.g) * scaleZeroToOne; - vo->b = ai_real(col.b) * scaleZeroToOne; - vo->a = ai_real(col.a) * scaleZeroToOne; - } - } - } - - return; -} - -// ------------------------------------------------------------------------------------------------ -aiCamera *BlenderImporter::ConvertCamera(const Scene & /*in*/, const Object *obj, const Camera *cam, ConversionData & /*conv_data*/) { - std::unique_ptr<aiCamera> out(new aiCamera()); - out->mName = obj->id.name + 2; - out->mPosition = aiVector3D(0.f, 0.f, 0.f); - out->mUp = aiVector3D(0.f, 1.f, 0.f); - out->mLookAt = aiVector3D(0.f, 0.f, -1.f); - if (cam->sensor_x && cam->lens) { - out->mHorizontalFOV = 2.f * std::atan2(cam->sensor_x, 2.f * cam->lens); - } - out->mClipPlaneNear = cam->clipsta; - out->mClipPlaneFar = cam->clipend; - - return out.release(); -} - -// ------------------------------------------------------------------------------------------------ -aiLight *BlenderImporter::ConvertLight(const Scene & /*in*/, const Object *obj, const Lamp *lamp, ConversionData & /*conv_data*/) { - std::unique_ptr<aiLight> out(new aiLight()); - out->mName = obj->id.name + 2; - - switch (lamp->type) { - case Lamp::Type_Local: - out->mType = aiLightSource_POINT; - break; - case Lamp::Type_Spot: - out->mType = aiLightSource_SPOT; - - // blender orients directional lights as facing toward -z - out->mDirection = aiVector3D(0.f, 0.f, -1.f); - out->mUp = aiVector3D(0.f, 1.f, 0.f); - - out->mAngleInnerCone = lamp->spotsize * (1.0f - lamp->spotblend); - out->mAngleOuterCone = lamp->spotsize; - break; - case Lamp::Type_Sun: - out->mType = aiLightSource_DIRECTIONAL; - - // blender orients directional lights as facing toward -z - out->mDirection = aiVector3D(0.f, 0.f, -1.f); - out->mUp = aiVector3D(0.f, 1.f, 0.f); - break; - - case Lamp::Type_Area: - out->mType = aiLightSource_AREA; - - if (lamp->area_shape == 0) { - out->mSize = aiVector2D(lamp->area_size, lamp->area_size); - } else { - out->mSize = aiVector2D(lamp->area_size, lamp->area_sizey); - } - - // blender orients directional lights as facing toward -z - out->mDirection = aiVector3D(0.f, 0.f, -1.f); - out->mUp = aiVector3D(0.f, 1.f, 0.f); - break; - - default: - break; - } - - out->mColorAmbient = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy; - out->mColorSpecular = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy; - out->mColorDiffuse = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy; - - // If default values are supplied, compute the coefficients from light's max distance - // Read this: https://imdoingitwrong.wordpress.com/2011/01/31/light-attenuation/ - // - if (lamp->constant_coefficient == 1.0f && lamp->linear_coefficient == 0.0f && lamp->quadratic_coefficient == 0.0f && lamp->dist > 0.0f) { - out->mAttenuationConstant = 1.0f; - out->mAttenuationLinear = 2.0f / lamp->dist; - out->mAttenuationQuadratic = 1.0f / (lamp->dist * lamp->dist); - } else { - out->mAttenuationConstant = lamp->constant_coefficient; - out->mAttenuationLinear = lamp->linear_coefficient; - out->mAttenuationQuadratic = lamp->quadratic_coefficient; - } - - return out.release(); -} - -// ------------------------------------------------------------------------------------------------ -aiNode *BlenderImporter::ConvertNode(const Scene &in, const Object *obj, ConversionData &conv_data, const aiMatrix4x4 &parentTransform) { - std::deque<const Object *> children; - for (ObjectSet::iterator it = conv_data.objects.begin(); it != conv_data.objects.end();) { - const Object *object = *it; - if (object->parent == obj) { - children.push_back(object); - - conv_data.objects.erase(it++); - continue; - } - ++it; - } - - std::unique_ptr<aiNode> node(new aiNode(obj->id.name + 2)); // skip over the name prefix 'OB' - if (obj->data) { - switch (obj->type) { - case Object ::Type_EMPTY: - break; // do nothing - - // supported object types - case Object ::Type_MESH: { - const size_t old = conv_data.meshes->size(); - - CheckActualType(obj->data.get(), "Mesh"); - ConvertMesh(in, obj, static_cast<const Mesh *>(obj->data.get()), conv_data, conv_data.meshes); - - if (conv_data.meshes->size() > old) { - node->mMeshes = new unsigned int[node->mNumMeshes = static_cast<unsigned int>(conv_data.meshes->size() - old)]; - for (unsigned int i = 0; i < node->mNumMeshes; ++i) { - node->mMeshes[i] = static_cast<unsigned int>(i + old); - } - } - } break; - case Object ::Type_LAMP: { - CheckActualType(obj->data.get(), "Lamp"); - aiLight *mesh = ConvertLight(in, obj, static_cast<const Lamp *>(obj->data.get()), conv_data); - - if (mesh) { - conv_data.lights->push_back(mesh); - } - } break; - case Object ::Type_CAMERA: { - CheckActualType(obj->data.get(), "Camera"); - aiCamera *mesh = ConvertCamera(in, obj, static_cast<const Camera *>(obj->data.get()), conv_data); - - if (mesh) { - conv_data.cameras->push_back(mesh); - } - } break; - - // unsupported object types / log, but do not break - case Object ::Type_CURVE: - NotSupportedObjectType(obj, "Curve"); - break; - case Object ::Type_SURF: - NotSupportedObjectType(obj, "Surface"); - break; - case Object ::Type_FONT: - NotSupportedObjectType(obj, "Font"); - break; - case Object ::Type_MBALL: - NotSupportedObjectType(obj, "MetaBall"); - break; - case Object ::Type_WAVE: - NotSupportedObjectType(obj, "Wave"); - break; - case Object ::Type_LATTICE: - NotSupportedObjectType(obj, "Lattice"); - break; - - // invalid or unknown type - default: - break; - } - } - - for (unsigned int x = 0; x < 4; ++x) { - for (unsigned int y = 0; y < 4; ++y) { - node->mTransformation[y][x] = obj->obmat[x][y]; - } - } - - aiMatrix4x4 m = parentTransform; - m = m.Inverse(); - - node->mTransformation = m * node->mTransformation; - - if (children.size()) { - node->mNumChildren = static_cast<unsigned int>(children.size()); - aiNode **nd = node->mChildren = new aiNode *[node->mNumChildren](); - for (const Object *nobj : children) { - *nd = ConvertNode(in, nobj, conv_data, node->mTransformation * parentTransform); - (*nd++)->mParent = node.get(); - } - } - - // apply modifiers - modifier_cache->ApplyModifiers(*node, conv_data, in, *obj); - - return node.release(); -} - -#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER diff --git a/libs/assimp/code/AssetLib/Blender/BlenderLoader.h b/libs/assimp/code/AssetLib/Blender/BlenderLoader.h deleted file mode 100644 index 0299ae3..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderLoader.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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. - */ -#pragma once -#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; - -} // namespace Formatter - -// BlenderDNA.h -namespace Blender { -class FileDatabase; -struct ElemBase; -} // namespace Blender - -// BlenderScene.h -namespace Blender { -struct Scene; -struct Object; -struct Collection; -struct Mesh; -struct Camera; -struct Lamp; -struct MTex; -struct Image; -struct Material; -} // namespace Blender - -// BlenderIntermediate.h -namespace Blender { -struct ConversionData; -template <template <typename, typename> class TCLASS, typename T> -struct TempArray; -} // namespace Blender - -// BlenderModifier.h -namespace Blender { -class BlenderModifierShowcase; -class BlenderModifier; -} // namespace Blender - -// ------------------------------------------------------------------------------------------- -/** 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() override; - bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override; - -protected: - const aiImporterDesc *GetInfo() const override; - void SetupProperties(const Importer *pImp) override; - void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override; - void ParseBlendFile(Blender::FileDatabase &out, std::shared_ptr<IOStream> stream); - void ExtractScene(Blender::Scene &out, const Blender::FileDatabase &file); - void ParseSubCollection(const Blender::Scene &in, aiNode *root, std::shared_ptr<Blender::Collection> collection, Blender::ConversionData &conv_data); - 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 diff --git a/libs/assimp/code/AssetLib/Blender/BlenderModifier.cpp b/libs/assimp/code/AssetLib/Blender/BlenderModifier.cpp deleted file mode 100644 index d2b393d..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderModifier.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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>, - - nullptr // 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("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 = nullptr; - break; - } - } - if (curgod) { - ASSIMP_LOG_WARN("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("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 j = 0; j < mesh->mNumVertices; ++j) { - aiVector3D &v = mesh->mVertices[j]; - - 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 j = 0; j < mesh->mNumVertices; ++j) { - aiVector3D &v = mesh->mVertices[j]; - v.x *= xs; - v.y *= ys; - v.z *= zs; - } - } - - if (mesh->mNormals) { - for (unsigned int j = 0; j < mesh->mNumVertices; ++j) { - aiVector3D &v = mesh->mNormals[j]; - v.x *= xs; - v.y *= ys; - v.z *= zs; - } - } - - if (mesh->mTangents) { - for (unsigned int j = 0; j < mesh->mNumVertices; ++j) { - aiVector3D &v = mesh->mTangents[j]; - v.x *= xs; - v.y *= ys; - v.z *= zs; - } - } - - if (mesh->mBitangents) { - for (unsigned int j = 0; j < mesh->mNumVertices; ++j) { - aiVector3D &v = mesh->mBitangents[j]; - 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 j = 0; j < mesh->mNumVertices; ++j) { - aiVector3D &v = mesh->mTextureCoords[n][j]; - 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 j = 0; j < mesh->mNumFaces; ++j) { - aiFace &face = mesh->mFaces[j]; - 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("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("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("BlendModifier: Applied the `Subdivision` modifier to `", - orig_object.id.name, "`"); -} - -#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER diff --git a/libs/assimp/code/AssetLib/Blender/BlenderModifier.h b/libs/assimp/code/AssetLib/Blender/BlenderModifier.h deleted file mode 100644 index 5af560c..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderModifier.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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("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 diff --git a/libs/assimp/code/AssetLib/Blender/BlenderScene.cpp b/libs/assimp/code/AssetLib/Blender/BlenderScene.cpp deleted file mode 100644 index 9ad086f..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderScene.cpp +++ /dev/null @@ -1,891 +0,0 @@ -/* -Open Asset Import Library (ASSIMP) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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 "BlenderCustomData.h" -#include "BlenderDNA.h" -#include "BlenderSceneGen.h" - -namespace Assimp { -namespace 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<CollectionObject>( - CollectionObject &dest, - const FileDatabase &db) const { - - ReadFieldPtr<ErrorPolicy_Fail>(dest.next, "*next", db); - { - //std::shared_ptr<CollectionObject> prev; - //ReadFieldPtr<ErrorPolicy_Fail>(prev, "*prev", db); - //dest.prev = prev.get(); - - std::shared_ptr<Object> ob; - ReadFieldPtr<ErrorPolicy_Igno>(ob, "*ob", db); - dest.ob = ob.get(); - } - - db.reader->IncPtr(size); -} - -//-------------------------------------------------------------------------------- -template <> -void Structure::Convert<CollectionChild>( - CollectionChild &dest, - const FileDatabase &db) const { - - ReadFieldPtr<ErrorPolicy_Fail>(dest.prev, "*prev", db); - ReadFieldPtr<ErrorPolicy_Fail>(dest.next, "*next", db); - ReadFieldPtr<ErrorPolicy_Igno>(dest.collection, "*collection", db); - - db.reader->IncPtr(size); -} - -//-------------------------------------------------------------------------------- -template <> -void Structure::Convert<Collection>( - Collection &dest, - const FileDatabase &db) const { - - ReadField<ErrorPolicy_Fail>(dest.id, "id", db); - ReadField<ErrorPolicy_Fail>(dest.gobject, "gobject", db); - ReadField<ErrorPolicy_Fail>(dest.children, "children", 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 = nullptr; - - 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); - ReadFieldPtr<ErrorPolicy_Warn>(dest.master_collection, "*master_collection", 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>); - converters["Collection"] = DNA::FactoryPair(&Structure::Allocate<Collection>, &Structure::Convert<Collection>); - converters["CollectionChild"] = DNA::FactoryPair(&Structure::Allocate<CollectionChild>, &Structure::Convert<CollectionChild>); - converters["CollectionObject"] = DNA::FactoryPair(&Structure::Allocate<CollectionObject>, &Structure::Convert<CollectionObject>); -} - -} // namespace Blender -} //namespace Assimp - -#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER diff --git a/libs/assimp/code/AssetLib/Blender/BlenderScene.h b/libs/assimp/code/AssetLib/Blender/BlenderScene.h deleted file mode 100644 index c153d3c..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderScene.h +++ /dev/null @@ -1,983 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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; -struct Collection; - -#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 CollectionObject : ElemBase { - //CollectionObject* prev; - std::shared_ptr<CollectionObject> next; - Object *ob; -}; - -// ------------------------------------------------------------------------------- -struct CollectionChild : ElemBase { - std::shared_ptr<CollectionChild> next, prev; - std::shared_ptr<Collection> collection; -}; - -// ------------------------------------------------------------------------------- -struct Collection : ElemBase { - ID id FAIL; - ListBase gobject; // CollectionObject - ListBase children; // CollectionChild -}; - -// ------------------------------------------------------------------------------- -struct World : ElemBase { - ID id FAIL; -}; - -// ------------------------------------------------------------------------------- -struct MVert : ElemBase { - float co[3] FAIL; - float no[3] FAIL; // read 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; - std::shared_ptr<Collection> master_collection WARN; - - ListBase base; - - Scene() : - ElemBase(), camera(), world(), basact(), master_collection() { - // 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 - } -}; - -} // namespace Blender -} // namespace Assimp -#endif diff --git a/libs/assimp/code/AssetLib/Blender/BlenderSceneGen.h b/libs/assimp/code/AssetLib/Blender/BlenderSceneGen.h deleted file mode 100644 index 762fdd3..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderSceneGen.h +++ /dev/null @@ -1,272 +0,0 @@ -/* -Open Asset Import Library (ASSIMP) ----------------------------------------------------------------------- - -Copyright (c) 2006-2020, 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<Collection>( - Collection& 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 diff --git a/libs/assimp/code/AssetLib/Blender/BlenderTessellator.cpp b/libs/assimp/code/AssetLib/Blender/BlenderTessellator.cpp deleted file mode 100644 index d3d463e..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderTessellator.cpp +++ /dev/null @@ -1,532 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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 -{ -#if defined __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Winvalid-offsetof" -#endif // __clang__ - unsigned int pointOffset = offsetof( PointP2T, point2D ); -#if defined __clang__ -# pragma clang diagnostic pop -#endif - 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 diff --git a/libs/assimp/code/AssetLib/Blender/BlenderTessellator.h b/libs/assimp/code/AssetLib/Blender/BlenderTessellator.h deleted file mode 100644 index 0d0ba32..0000000 --- a/libs/assimp/code/AssetLib/Blender/BlenderTessellator.h +++ /dev/null @@ -1,214 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, 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 |