diff options
Diffstat (limited to 'src/3rdparty/assimp/code/BlenderDNA.cpp')
-rw-r--r-- | src/3rdparty/assimp/code/BlenderDNA.cpp | 519 |
1 files changed, 260 insertions, 259 deletions
diff --git a/src/3rdparty/assimp/code/BlenderDNA.cpp b/src/3rdparty/assimp/code/BlenderDNA.cpp index b380fbe8d..18ec9f2b4 100644 --- a/src/3rdparty/assimp/code/BlenderDNA.cpp +++ b/src/3rdparty/assimp/code/BlenderDNA.cpp @@ -2,11 +2,11 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2012, assimp team +Copyright (c) 2006-2016, assimp team All rights reserved. -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above @@ -23,16 +23,16 @@ following conditions are met: derived from this software without specific prior written permission of the assimp team. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- @@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * @brief Implementation of the Blender `DNA`, that is its own * serialized set of data structures. */ -#include "AssimpPCH.h" + #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER #include "BlenderDNA.h" @@ -53,170 +53,169 @@ using namespace Assimp; using namespace Assimp::Blender; using namespace Assimp::Formatter; -#define for_each BOOST_FOREACH bool match4(StreamReaderAny& stream, const char* string) { - char tmp[] = { - (stream).GetI1(), - (stream).GetI1(), - (stream).GetI1(), - (stream).GetI1() - }; - return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]); + char tmp[] = { + (stream).GetI1(), + (stream).GetI1(), + (stream).GetI1(), + (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; + size_t size; + std::string name; }; // ------------------------------------------------------------------------------------------------ -void DNAParser :: Parse () +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_each(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_each(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_each(Type& s, types) { - s.size = stream.GetI2(); - } - - // structures dictionary - for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); - if(!match4(stream,"STRC")) { - throw DeadlyImportError("BlenderDNA: Expected STRC field"); - } - - size_t end = stream.GetI4(), fields = 0; - - dna.structures.reserve(end); - for(size_t i = 0; i != end; ++i) { - - uint16_t n = stream.GetI2(); - if (n >= types.size()) { - throw DeadlyImportError((format(), - "BlenderDNA: Invalid type index in structure name" ,n, - " (there are only ", types.size(), " entries)" - )); - } - - // maintain separate indexes - dna.indices[types[n].name] = dna.structures.size(); - - dna.structures.push_back(Structure()); - Structure& s = dna.structures.back(); - s.name = types[n].name; - //s.index = dna.structures.size()-1; - - n = stream.GetI2(); - s.fields.reserve(n); - - size_t offset = 0; - for (size_t m = 0; m < n; ++m, ++fields) { - - uint16_t j = stream.GetI2(); - if (j >= types.size()) { - throw DeadlyImportError((format(), - "BlenderDNA: Invalid type index in structure field ", j, - " (there are only ", types.size(), " entries)" - )); - } - s.fields.push_back(Field()); - Field& f = s.fields.back(); - f.offset = offset; - - f.type = types[j].name; - f.size = types[j].size; - - j = stream.GetI2(); - if (j >= names.size()) { - throw DeadlyImportError((format(), - "BlenderDNA: Invalid name index in structure field ", j, - " (there are only ", names.size(), " entries)" - )); - } - - f.name = names[j]; - f.flags = 0u; - - // pointers always specify the size of the pointee instead of their own. - // The pointer asterisk remains a property of the lookup name. - if (f.name[0] == '*') { - f.size = db.i64bit ? 8 : 4; - f.flags |= FieldFlag_Pointer; - } - - // arrays, however, specify the size of a single element so we - // need to parse the (possibly multi-dimensional) array declaration - // in order to obtain the actual size of the array in the file. - // Also we need to alter the lookup name to include no array - // brackets anymore or size fixup won't work (if our size does - // not match the size read from the DNA). - if (*f.name.rbegin() == ']') { - const std::string::size_type rb = f.name.find('['); - if (rb == std::string::npos) { - throw DeadlyImportError((format(), - "BlenderDNA: Encountered invalid array declaration ", - f.name - )); - } - - f.flags |= FieldFlag_Array; - DNA::ExtractArraySize(f.name,f.array_sizes); - f.name = f.name.substr(0,rb); - - f.size *= f.array_sizes[0] * f.array_sizes[1]; - } - - // maintain separate indexes - s.indices[f.name] = s.fields.size()-1; - offset += f.size; - } - s.size = offset; - } - - DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(), - " structures with totally ",fields," fields")); + StreamReaderAny& stream = *db.reader.get(); + DNA& dna = db.dna; + + if(!match4(stream,"SDNA")) { + throw DeadlyImportError("BlenderDNA: Expected SDNA chunk"); + } + + // name dictionary + if(!match4(stream,"NAME")) { + throw DeadlyImportError("BlenderDNA: Expected NAME field"); + } + + std::vector<std::string> names (stream.GetI4()); + for(std::string& s : names) { + while (char c = stream.GetI1()) { + s += c; + } + } + + // type dictionary + for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); + if(!match4(stream,"TYPE")) { + throw DeadlyImportError("BlenderDNA: Expected TYPE field"); + } + + std::vector<Type> types (stream.GetI4()); + for(Type& s : types) { + while (char c = stream.GetI1()) { + s.name += c; + } + } + + // type length dictionary + for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); + if(!match4(stream,"TLEN")) { + throw DeadlyImportError("BlenderDNA: Expected TLEN field"); + } + + for(Type& s : types) { + s.size = stream.GetI2(); + } + + // structures dictionary + for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); + if(!match4(stream,"STRC")) { + throw DeadlyImportError("BlenderDNA: Expected STRC field"); + } + + size_t end = stream.GetI4(), fields = 0; + + dna.structures.reserve(end); + for(size_t i = 0; i != end; ++i) { + + uint16_t n = stream.GetI2(); + if (n >= types.size()) { + throw DeadlyImportError((format(), + "BlenderDNA: Invalid type index in structure name" ,n, + " (there are only ", types.size(), " entries)" + )); + } + + // maintain separate indexes + dna.indices[types[n].name] = dna.structures.size(); + + dna.structures.push_back(Structure()); + Structure& s = dna.structures.back(); + s.name = types[n].name; + //s.index = dna.structures.size()-1; + + n = stream.GetI2(); + s.fields.reserve(n); + + size_t offset = 0; + for (size_t m = 0; m < n; ++m, ++fields) { + + uint16_t j = stream.GetI2(); + if (j >= types.size()) { + throw DeadlyImportError((format(), + "BlenderDNA: Invalid type index in structure field ", j, + " (there are only ", types.size(), " entries)" + )); + } + s.fields.push_back(Field()); + Field& f = s.fields.back(); + f.offset = offset; + + f.type = types[j].name; + f.size = types[j].size; + + j = stream.GetI2(); + if (j >= names.size()) { + throw DeadlyImportError((format(), + "BlenderDNA: Invalid name index in structure field ", j, + " (there are only ", names.size(), " entries)" + )); + } + + f.name = names[j]; + f.flags = 0u; + + // pointers always specify the size of the pointee instead of their own. + // The pointer asterisk remains a property of the lookup name. + if (f.name[0] == '*') { + f.size = db.i64bit ? 8 : 4; + f.flags |= FieldFlag_Pointer; + } + + // arrays, however, specify the size of a single element so we + // need to parse the (possibly multi-dimensional) array declaration + // in order to obtain the actual size of the array in the file. + // Also we need to alter the lookup name to include no array + // brackets anymore or size fixup won't work (if our size does + // not match the size read from the DNA). + if (*f.name.rbegin() == ']') { + const std::string::size_type rb = f.name.find('['); + if (rb == std::string::npos) { + throw DeadlyImportError((format(), + "BlenderDNA: Encountered invalid array declaration ", + f.name + )); + } + + f.flags |= FieldFlag_Array; + DNA::ExtractArraySize(f.name,f.array_sizes); + f.name = f.name.substr(0,rb); + + f.size *= f.array_sizes[0] * f.array_sizes[1]; + } + + // maintain separate indexes + s.indices[f.name] = s.fields.size()-1; + offset += f.size; + } + s.size = offset; + } + + DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(), + " structures with totally ",fields," fields")); #ifdef ASSIMP_BUILD_BLENDER_DEBUG - dna.DumpToFile(); + dna.DumpToFile(); #endif - dna.AddPrimitiveStructures(); - dna.RegisterConverters(); + dna.AddPrimitiveStructures(); + dna.RegisterConverters(); } @@ -226,144 +225,146 @@ void DNAParser :: Parse () // ------------------------------------------------------------------------------------------------ void DNA :: DumpToFile() { - // we dont'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()) { - DefaultLogger::get()->error("Could not dump dna to dna.txt"); - return; - } - f << "Field format: type name offset size" << "\n"; - f << "Structure format: name size" << "\n"; - - for_each(const Structure& s, structures) { - f << s.name << " " << s.size << "\n\n"; - for_each(const Field& ff, s.fields) { - f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << std::endl; - } - f << std::endl; - } - DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt"); + // we dont'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()) { + DefaultLogger::get()->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; + + DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt"); } #endif // ------------------------------------------------------------------------------------------------ /*static*/ void DNA :: ExtractArraySize( - const std::string& out, - size_t array_sizes[2] + 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]); + 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]); } // ------------------------------------------------------------------------------------------------ -boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure( - const Structure& structure, - const FileDatabase& db -) const +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 boost::shared_ptr< ElemBase >(); - } - - boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))(); - (structure.*((*it).second.second))(ret,db); - - return ret; + 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 + 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; + 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. + // 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["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["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["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["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; + indices["double"] = structures.size(); + structures.push_back( Structure() ); + structures.back().name = "double"; + structures.back().size = 8; - // no long, seemingly. + // no long, seemingly. } // ------------------------------------------------------------------------------------------------ void SectionParser :: Next() { - stream.SetCurrentPos(current.start + current.size); + stream.SetCurrentPos(current.start + current.size); - const char tmp[] = { - stream.GetI1(), - stream.GetI1(), - stream.GetI1(), - stream.GetI1() - }; - current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1); + const char tmp[] = { + stream.GetI1(), + stream.GetI1(), + stream.GetI1(), + 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.size = stream.GetI4(); + current.address.val = ptr64 ? stream.GetU8() : stream.GetU4(); - current.dna_index = stream.GetI4(); - current.num = stream.GetI4(); + 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"); - } + current.start = stream.GetCurrentPos(); + if (stream.GetRemainingSizeToLimit() < current.size) { + throw DeadlyImportError("BLEND: invalid size of file block"); + } #ifdef ASSIMP_BUILD_BLENDER_DEBUG - DefaultLogger::get()->debug(current.id); + DefaultLogger::get()->debug(current.id); #endif } |