From db81b925d776103326128bf629cbdda576a223e7 Mon Sep 17 00:00:00 2001 From: sanine Date: Sat, 16 Apr 2022 11:55:09 -0500 Subject: move 3rd-party librarys into libs/ and add built-in honeysuckle --- libs/assimp/code/AssetLib/Blender/BlenderDNA.inl | 845 +++++++++++++++++++++++ 1 file changed, 845 insertions(+) create mode 100644 libs/assimp/code/AssetLib/Blender/BlenderDNA.inl (limited to 'libs/assimp/code/AssetLib/Blender/BlenderDNA.inl') diff --git a/libs/assimp/code/AssetLib/Blender/BlenderDNA.inl b/libs/assimp/code/AssetLib/Blender/BlenderDNA.inl new file mode 100644 index 0000000..4f64987 --- /dev/null +++ b/libs/assimp/code/AssetLib/Blender/BlenderDNA.inl @@ -0,0 +1,845 @@ +/* +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 +#include + +namespace Assimp { +namespace Blender { + +//-------------------------------------------------------------------------------- +const Field& Structure :: operator [] (const std::string& ss) const +{ + std::map::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::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 std::shared_ptr Structure :: Allocate() const +{ + return std::shared_ptr(new T()); +} + +//-------------------------------------------------------------------------------- +template void Structure :: Convert( + std::shared_ptr in, + const FileDatabase& db) const +{ + Convert (*static_cast ( in.get() ),db); +} + +//-------------------------------------------------------------------------------- +template +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()(out[i]); + } + } + catch (const Error& e) { + _defaultInitializer()(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 +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()(out[i][j]); + } + } + for(; i < M; ++i) { + _defaultInitializer()(out[i]); + } + } + catch (const Error& e) { + _defaultInitializer()(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 class TOUT, typename T> +bool Structure :: ReadFieldPtr(TOUT& 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()(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 class TOUT, typename T, size_t N> +bool Structure :: ReadFieldPtr(TOUT (&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()(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()(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 +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()(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 +bool Structure::ReadCustomDataPtr(std::shared_ptr&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()(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((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 class TOUT, typename T> +bool Structure::ReadFieldPtrVector(vector>&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()(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((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 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