From 80c88ffc73a176de44b641d166057e68780d4cdc Mon Sep 17 00:00:00 2001 From: xiaozhuai <798047000@qq.com> Date: Mon, 18 May 2020 15:40:12 +0800 Subject: [PATCH 01/21] optimize CMakeLists.txt --- CMakeLists.txt | 2 +- code/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b350f6e3..495e161c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -351,7 +351,7 @@ ELSE() ENDIF() # Only generate this target if no higher-level project already has -IF (NOT TARGET uninstall) +IF (NOT TARGET uninstall AND ASSIMP_INSTALL) # add make uninstall capability CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 000ebad6c..d390e525c 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1036,7 +1036,7 @@ ENDIF() # Check dependencies for glTF importer with Open3DGC-compression. # RT-extensions is used in "contrib/Open3DGC/o3dgcTimer.h" for collecting statistics. Pointed file # has implementation for different platforms: WIN32, __MACH__ and other ("else" block). -FIND_PACKAGE(RT QUIET) +FIND_PACKAGE(rt QUIET) IF (NOT ASSIMP_HUNTER_ENABLED AND (RT_FOUND OR MSVC)) SET( ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC 1 ) ADD_DEFINITIONS( -DASSIMP_IMPORTER_GLTF_USE_OPEN3DGC=1 ) From 6b9c47776394d9d92c3ab1db35e0a53f62d377ba Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Fri, 2 Oct 2020 13:58:55 +0100 Subject: [PATCH 02/21] The floar parsing routines are now DeadlyErrors. --- code/AssetLib/Collada/ColladaExporter.cpp | 2 +- include/assimp/fast_atof.h | 28 ++++++++++++++--------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/code/AssetLib/Collada/ColladaExporter.cpp b/code/AssetLib/Collada/ColladaExporter.cpp index 567f7c8e7..251cbee3e 100644 --- a/code/AssetLib/Collada/ColladaExporter.cpp +++ b/code/AssetLib/Collada/ColladaExporter.cpp @@ -573,7 +573,7 @@ bool ColladaExporter::ReadMaterialSurface(Surface &poSurface, const aiMaterial & index_str = index_str.substr(1, std::string::npos); try { - index = (unsigned int)strtoul10_64(index_str.c_str()); + index = (unsigned int)strtoul10_64(index_str.c_str()); } catch (std::exception &error) { throw DeadlyExportError(error.what()); } diff --git a/include/assimp/fast_atof.h b/include/assimp/fast_atof.h index 6e9a1bba7..79740a1e8 100644 --- a/include/assimp/fast_atof.h +++ b/include/assimp/fast_atof.h @@ -29,6 +29,7 @@ #include "StringComparison.h" #include +#include #ifdef _MSC_VER # include @@ -185,13 +186,14 @@ unsigned int strtoul_cppstyle( const char* in, const char** out=0) { // Special version of the function, providing higher accuracy and safety // It is mainly used by fast_atof to prevent ugly and unwanted integer overflows. // ------------------------------------------------------------------------------------ +template inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_inout=0) { unsigned int cur = 0; uint64_t value = 0; if ( *in < '0' || *in > '9' ) { - throw std::invalid_argument( std::string( "The string \"" ) + in + "\" cannot be converted into a value." ); + throw DeadlyImportError("The string \"", in, "\" cannot be converted into a value." ); } for ( ;; ) { @@ -237,6 +239,7 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino // ------------------------------------------------------------------------------------ // signed variant of strtoul10_64 // ------------------------------------------------------------------------------------ +template inline int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inout = 0) { bool inv = (*in == '-'); @@ -244,7 +247,7 @@ int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inou ++in; } - int64_t value = strtoul10_64(in, out, max_inout); + int64_t value = strtoul10_64(in, out, max_inout); if (inv) { value = -value; } @@ -259,7 +262,7 @@ int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inou //! about 6 times faster than atof in win32. // If you find any bugs, please send them to me, niko (at) irrlicht3d.org. // ------------------------------------------------------------------------------------ -template +template inline const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) { Real f = 0; @@ -289,13 +292,13 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) if (!(c[0] >= '0' && c[0] <= '9') && !((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')) { - throw std::invalid_argument("Cannot parse string " - "as real number: does not start with digit " + throw ExceptionType("Cannot parse string \"", c, + "\" as a real number: does not start with digit " "or decimal point followed by digit."); } if (*c != '.' && (! check_comma || c[0] != ',')) { - f = static_cast( strtoul10_64 ( c, &c) ); + f = static_cast( strtoul10_64 ( c, &c) ); } if ((*c == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9') { @@ -310,7 +313,7 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) // number of digits to be read. AI_FAST_ATOF_RELAVANT_DECIMALS can be a value between // 1 and 15. unsigned int diff = AI_FAST_ATOF_RELAVANT_DECIMALS; - double pl = static_cast( strtoul10_64 ( c, &c, &diff )); + double pl = static_cast( strtoul10_64 ( c, &c, &diff )); pl *= fast_atof_table[diff]; f += static_cast( pl ); @@ -332,7 +335,7 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) // The reason float constants are used here is that we've seen cases where compilers // would perform such casts on compile-time constants at runtime, which would be // bad considering how frequently fast_atoreal_move is called in Assimp. - Real exp = static_cast( strtoul10_64(c, &c) ); + Real exp = static_cast( strtoul10_64(c, &c) ); if (einv) { exp = -exp; } @@ -348,26 +351,29 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) // ------------------------------------------------------------------------------------ // The same but more human. +template inline ai_real fast_atof(const char* c) { ai_real ret(0.0); - fast_atoreal_move(c, ret); + fast_atoreal_move(c, ret); return ret; } +template inline ai_real fast_atof( const char* c, const char** cout) { ai_real ret(0.0); - *cout = fast_atoreal_move(c, ret); + *cout = fast_atoreal_move(c, ret); return ret; } +template inline ai_real fast_atof( const char** inout) { ai_real ret(0.0); - *inout = fast_atoreal_move(*inout, ret); + *inout = fast_atoreal_move(*inout, ret); return ret; } From 17702605cfd4ff697e7bbf2ba50ad87db451de77 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Fri, 2 Oct 2020 14:41:36 +0100 Subject: [PATCH 03/21] Limit the number of characters printed. --- include/assimp/fast_atof.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/assimp/fast_atof.h b/include/assimp/fast_atof.h index 79740a1e8..a27863760 100644 --- a/include/assimp/fast_atof.h +++ b/include/assimp/fast_atof.h @@ -193,7 +193,8 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino uint64_t value = 0; if ( *in < '0' || *in > '9' ) { - throw DeadlyImportError("The string \"", in, "\" cannot be converted into a value." ); + // The string is known to be bad, so don't risk printing the whole thing. + throw ExceptionType("The string \"", std::substr(in, 0, 100), "\" cannot be converted into a value." ); } for ( ;; ) { @@ -292,7 +293,8 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) if (!(c[0] >= '0' && c[0] <= '9') && !((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')) { - throw ExceptionType("Cannot parse string \"", c, + // The string is known to be bad, so don't risk printing the whole thing. + throw ExceptionType("Cannot parse string \"", std::substr(c, 0, 100), "\" as a real number: does not start with digit " "or decimal point followed by digit."); } From 57756750f66196e9dfba680d3ea51dcc711c4b29 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Fri, 2 Oct 2020 15:20:50 +0100 Subject: [PATCH 04/21] Limit the output --- include/assimp/fast_atof.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/assimp/fast_atof.h b/include/assimp/fast_atof.h index a27863760..9ea49c85c 100644 --- a/include/assimp/fast_atof.h +++ b/include/assimp/fast_atof.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "StringComparison.h" @@ -194,7 +193,7 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino if ( *in < '0' || *in > '9' ) { // The string is known to be bad, so don't risk printing the whole thing. - throw ExceptionType("The string \"", std::substr(in, 0, 100), "\" cannot be converted into a value." ); + throw ExceptionType("The string \"", std::string(in).substr(0, 100), "\" cannot be converted into a value." ); } for ( ;; ) { @@ -294,7 +293,7 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) if (!(c[0] >= '0' && c[0] <= '9') && !((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')) { // The string is known to be bad, so don't risk printing the whole thing. - throw ExceptionType("Cannot parse string \"", std::substr(c, 0, 100), + throw ExceptionType("Cannot parse string \"", std::string(c).substr(0, 100), "\" as a real number: does not start with digit " "or decimal point followed by digit."); } From 585fb89154da1dd79cedaa1ba0a2342571a7b0f4 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Fri, 2 Oct 2020 15:25:16 +0100 Subject: [PATCH 05/21] Make an assert a DeadlyImportError. --- code/AssetLib/FBX/FBXImporter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/AssetLib/FBX/FBXImporter.cpp b/code/AssetLib/FBX/FBXImporter.cpp index f80b65cd4..fc3b85ef5 100644 --- a/code/AssetLib/FBX/FBXImporter.cpp +++ b/code/AssetLib/FBX/FBXImporter.cpp @@ -187,6 +187,10 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // size relative to cm float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor(); + if (size_relative_to_cm == 0.0) + { + ThrowException("The UnitScaleFactor must be non-zero"); + } // Set FBX file scale is relative to CM must be converted to M for // assimp universal format (M) From 4bdaf20b708337f21317822cb5fb3b5dac4603a2 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Mon, 5 Oct 2020 14:23:42 +0100 Subject: [PATCH 06/21] Add comment. --- code/AssetLib/FBX/FBXImporter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/AssetLib/FBX/FBXImporter.cpp b/code/AssetLib/FBX/FBXImporter.cpp index fc3b85ef5..4c473510e 100644 --- a/code/AssetLib/FBX/FBXImporter.cpp +++ b/code/AssetLib/FBX/FBXImporter.cpp @@ -189,6 +189,7 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor(); if (size_relative_to_cm == 0.0) { + // BaseImporter later asserts that fileScale is non-zero. ThrowException("The UnitScaleFactor must be non-zero"); } From 22ea239049f732ccdf45d467125e45003bcab738 Mon Sep 17 00:00:00 2001 From: xantares Date: Mon, 12 Oct 2020 10:42:41 +0200 Subject: [PATCH 07/21] CMake: Fix FindRT warning This fixes the following warning: The package name passed to `find_package_handle_standard_args` (rt) does not match the name of the calling package (RT). --- cmake-modules/FindRT.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake-modules/FindRT.cmake b/cmake-modules/FindRT.cmake index 17d5df81d..c397acabd 100644 --- a/cmake-modules/FindRT.cmake +++ b/cmake-modules/FindRT.cmake @@ -16,5 +16,5 @@ set(RT_LIBRARIES ${RT_LIBRARY}) # handle the QUIETLY and REQUIRED arguments and set # RT_FOUND to TRUE if all listed variables are TRUE include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(rt DEFAULT_MSG RT_LIBRARY) +find_package_handle_standard_args(RT DEFAULT_MSG RT_LIBRARY) mark_as_advanced(RT_LIBRARY) From 9f880e221478f3b76d44abd2c84602701dd7030e Mon Sep 17 00:00:00 2001 From: Inho Lee Date: Fri, 16 Oct 2020 08:45:17 +0200 Subject: [PATCH 08/21] Fix glTF1 orthographic camera --- code/AssetLib/glTF/glTFAsset.inl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/AssetLib/glTF/glTFAsset.inl b/code/AssetLib/glTF/glTFAsset.inl index 41bdc508a..acda572c3 100644 --- a/code/AssetLib/glTF/glTFAsset.inl +++ b/code/AssetLib/glTF/glTFAsset.inl @@ -1060,7 +1060,7 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG inline void Camera::Read(Value &obj, Asset & /*r*/) { type = MemberOrDefault(obj, "type", Camera::Perspective); - const char *subobjId = (type == Camera::Orthographic) ? "ortographic" : "perspective"; + const char *subobjId = (type == Camera::Orthographic) ? "orthographic" : "perspective"; Value *it = FindObject(obj, subobjId); if (!it) throw DeadlyImportError("GLTF: Camera missing its parameters"); @@ -1071,10 +1071,10 @@ inline void Camera::Read(Value &obj, Asset & /*r*/) { perspective.zfar = MemberOrDefault(*it, "zfar", 100.f); perspective.znear = MemberOrDefault(*it, "znear", 0.01f); } else { - ortographic.xmag = MemberOrDefault(obj, "xmag", 1.f); - ortographic.ymag = MemberOrDefault(obj, "ymag", 1.f); - ortographic.zfar = MemberOrDefault(obj, "zfar", 100.f); - ortographic.znear = MemberOrDefault(obj, "znear", 0.01f); + ortographic.xmag = MemberOrDefault(*it, "xmag", 1.f); + ortographic.ymag = MemberOrDefault(*it, "ymag", 1.f); + ortographic.zfar = MemberOrDefault(*it, "zfar", 100.f); + ortographic.znear = MemberOrDefault(*it, "znear", 0.01f); } } From ad7f8910e96cd936b3de52a4dfd855caa636422e Mon Sep 17 00:00:00 2001 From: Inho Lee Date: Fri, 16 Oct 2020 17:09:17 +0200 Subject: [PATCH 09/21] Rollback the method to handle empty bones for GLTF2 A patch made the assimp to ignore empty bones. However, some assets can have bones which don't have weights but are connected to other bones. --- code/AssetLib/glTF2/glTF2Importer.cpp | 2047 ++++++++++++------------- 1 file changed, 1023 insertions(+), 1024 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index 972154b5f..b1ba5b67b 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -69,8 +69,8 @@ using namespace glTFCommon; namespace { // generate bi-tangents from normals and tangents according to spec struct Tangent { - aiVector3D xyz; - ai_real w; + aiVector3D xyz; + ai_real w; }; } // namespace @@ -79,1283 +79,1282 @@ struct Tangent { // static const aiImporterDesc desc = { - "glTF2 Importer", - "", - "", - "", - aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental, - 0, - 0, - 0, - 0, - "gltf glb" + "glTF2 Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental, + 0, + 0, + 0, + 0, + "gltf glb" }; glTF2Importer::glTF2Importer() : - BaseImporter(), - meshOffsets(), - embeddedTexIdxs(), - mScene(nullptr) { - // empty + BaseImporter(), + meshOffsets(), + embeddedTexIdxs(), + mScene(nullptr) { + // empty } glTF2Importer::~glTF2Importer() { - // empty + // empty } const aiImporterDesc *glTF2Importer::GetInfo() const { - return &desc; + return &desc; } bool glTF2Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /* checkSig */) const { - const std::string &extension = GetExtension(pFile); + const std::string &extension = GetExtension(pFile); - if (extension != "gltf" && extension != "glb") { + if (extension != "gltf" && extension != "glb") { return false; - } + } - if (pIOHandler) { - glTF2::Asset asset(pIOHandler); - asset.Load(pFile, extension == "glb"); - std::string version = asset.asset.version; - return !version.empty() && version[0] == '2'; - } + if (pIOHandler) { + glTF2::Asset asset(pIOHandler); + asset.Load(pFile, extension == "glb"); + std::string version = asset.asset.version; + return !version.empty() && version[0] == '2'; + } - return false; + return false; } static aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode) { - switch (gltfWrapMode) { - case SamplerWrap::Mirrored_Repeat: - return aiTextureMapMode_Mirror; + switch (gltfWrapMode) { + case SamplerWrap::Mirrored_Repeat: + return aiTextureMapMode_Mirror; - case SamplerWrap::Clamp_To_Edge: - return aiTextureMapMode_Clamp; + case SamplerWrap::Clamp_To_Edge: + return aiTextureMapMode_Clamp; - case SamplerWrap::UNSET: - case SamplerWrap::Repeat: - default: - return aiTextureMapMode_Wrap; - } + case SamplerWrap::UNSET: + case SamplerWrap::Repeat: + default: + return aiTextureMapMode_Wrap; + } } inline void SetMaterialColorProperty(Asset & /*r*/, vec4 &prop, aiMaterial *mat, const char *pKey, unsigned int type, unsigned int idx) { - aiColor4D col; - CopyValue(prop, col); - mat->AddProperty(&col, 1, pKey, type, idx); + aiColor4D col; + CopyValue(prop, col); + mat->AddProperty(&col, 1, pKey, type, idx); } inline void SetMaterialColorProperty(Asset & /*r*/, vec3 &prop, aiMaterial *mat, const char *pKey, unsigned int type, unsigned int idx) { - aiColor4D col; - glTFCommon::CopyValue(prop, col); - mat->AddProperty(&col, 1, pKey, type, idx); + aiColor4D col; + glTFCommon::CopyValue(prop, col); + mat->AddProperty(&col, 1, pKey, type, idx); } inline void SetMaterialTextureProperty(std::vector &embeddedTexIdxs, Asset & /*r*/, glTF2::TextureInfo prop, aiMaterial *mat, aiTextureType texType, unsigned int texSlot = 0) { - if (prop.texture && prop.texture->source) { - aiString uri(prop.texture->source->uri); + if (prop.texture && prop.texture->source) { + aiString uri(prop.texture->source->uri); - int texIdx = embeddedTexIdxs[prop.texture->source.GetIndex()]; - if (texIdx != -1) { // embedded - // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture) - uri.data[0] = '*'; - uri.length = 1 + ASSIMP_itoa10(uri.data + 1, MAXLEN - 1, texIdx); - } + int texIdx = embeddedTexIdxs[prop.texture->source.GetIndex()]; + if (texIdx != -1) { // embedded + // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture) + uri.data[0] = '*'; + uri.length = 1 + ASSIMP_itoa10(uri.data + 1, MAXLEN - 1, texIdx); + } mat->AddProperty(&uri, AI_MATKEY_TEXTURE(texType, texSlot)); mat->AddProperty(&prop.texCoord, 1, AI_MATKEY_GLTF_TEXTURE_TEXCOORD(texType, texSlot)); - if (prop.textureTransformSupported) { - aiUVTransform transform; - transform.mScaling.x = prop.TextureTransformExt_t.scale[0]; - transform.mScaling.y = prop.TextureTransformExt_t.scale[1]; - transform.mRotation = -prop.TextureTransformExt_t.rotation; // must be negated + if (prop.textureTransformSupported) { + aiUVTransform transform; + transform.mScaling.x = prop.TextureTransformExt_t.scale[0]; + transform.mScaling.y = prop.TextureTransformExt_t.scale[1]; + transform.mRotation = -prop.TextureTransformExt_t.rotation; // must be negated - // A change of coordinates is required to map glTF UV transformations into the space used by - // Assimp. In glTF all UV origins are at 0,1 (top left of texture) in Assimp space. In Assimp - // rotation occurs around the image center (0.5,0.5) where as in glTF rotation is around the - // texture origin. All three can be corrected for solely by a change of the translation since - // the transformations available are shape preserving. Note the importer already flips the V - // coordinate of the actual meshes during import. - const ai_real rcos(cos(-transform.mRotation)); - const ai_real rsin(sin(-transform.mRotation)); - transform.mTranslation.x = (static_cast( 0.5 ) * transform.mScaling.x) * (-rcos + rsin + 1) + prop.TextureTransformExt_t.offset[0]; - transform.mTranslation.y = ((static_cast( 0.5 ) * transform.mScaling.y) * (rsin + rcos - 1)) + 1 - transform.mScaling.y - prop.TextureTransformExt_t.offset[1];; + // A change of coordinates is required to map glTF UV transformations into the space used by + // Assimp. In glTF all UV origins are at 0,1 (top left of texture) in Assimp space. In Assimp + // rotation occurs around the image center (0.5,0.5) where as in glTF rotation is around the + // texture origin. All three can be corrected for solely by a change of the translation since + // the transformations available are shape preserving. Note the importer already flips the V + // coordinate of the actual meshes during import. + const ai_real rcos(cos(-transform.mRotation)); + const ai_real rsin(sin(-transform.mRotation)); + transform.mTranslation.x = (static_cast( 0.5 ) * transform.mScaling.x) * (-rcos + rsin + 1) + prop.TextureTransformExt_t.offset[0]; + transform.mTranslation.y = ((static_cast( 0.5 ) * transform.mScaling.y) * (rsin + rcos - 1)) + 1 - transform.mScaling.y - prop.TextureTransformExt_t.offset[1];; - mat->AddProperty(&transform, 1, _AI_MATKEY_UVTRANSFORM_BASE, texType, texSlot); - } + mat->AddProperty(&transform, 1, _AI_MATKEY_UVTRANSFORM_BASE, texType, texSlot); + } - if (prop.texture->sampler) { - Ref sampler = prop.texture->sampler; + if (prop.texture->sampler) { + Ref sampler = prop.texture->sampler; - aiString name(sampler->name); - aiString id(sampler->id); + aiString name(sampler->name); + aiString id(sampler->id); - mat->AddProperty(&name, AI_MATKEY_GLTF_MAPPINGNAME(texType, texSlot)); - mat->AddProperty(&id, AI_MATKEY_GLTF_MAPPINGID(texType, texSlot)); + mat->AddProperty(&name, AI_MATKEY_GLTF_MAPPINGNAME(texType, texSlot)); + mat->AddProperty(&id, AI_MATKEY_GLTF_MAPPINGID(texType, texSlot)); - aiTextureMapMode wrapS = ConvertWrappingMode(sampler->wrapS); - aiTextureMapMode wrapT = ConvertWrappingMode(sampler->wrapT); - mat->AddProperty(&wrapS, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot)); - mat->AddProperty(&wrapT, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot)); + aiTextureMapMode wrapS = ConvertWrappingMode(sampler->wrapS); + aiTextureMapMode wrapT = ConvertWrappingMode(sampler->wrapT); + mat->AddProperty(&wrapS, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot)); + mat->AddProperty(&wrapT, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot)); - if (sampler->magFilter != SamplerMagFilter::UNSET) { - mat->AddProperty(&sampler->magFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(texType, texSlot)); - } + if (sampler->magFilter != SamplerMagFilter::UNSET) { + mat->AddProperty(&sampler->magFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(texType, texSlot)); + } - if (sampler->minFilter != SamplerMinFilter::UNSET) { - mat->AddProperty(&sampler->minFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(texType, texSlot)); - } - } - } + if (sampler->minFilter != SamplerMinFilter::UNSET) { + mat->AddProperty(&sampler->minFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(texType, texSlot)); + } + } + } } inline void SetMaterialTextureProperty(std::vector &embeddedTexIdxs, Asset &r, glTF2::NormalTextureInfo &prop, aiMaterial *mat, aiTextureType texType, unsigned int texSlot = 0) { - SetMaterialTextureProperty(embeddedTexIdxs, r, (glTF2::TextureInfo)prop, mat, texType, texSlot); + SetMaterialTextureProperty(embeddedTexIdxs, r, (glTF2::TextureInfo)prop, mat, texType, texSlot); - if (prop.texture && prop.texture->source) { - mat->AddProperty(&prop.scale, 1, AI_MATKEY_GLTF_TEXTURE_SCALE(texType, texSlot)); - } + if (prop.texture && prop.texture->source) { + mat->AddProperty(&prop.scale, 1, AI_MATKEY_GLTF_TEXTURE_SCALE(texType, texSlot)); + } } inline void SetMaterialTextureProperty(std::vector &embeddedTexIdxs, Asset &r, glTF2::OcclusionTextureInfo &prop, aiMaterial *mat, aiTextureType texType, unsigned int texSlot = 0) { - SetMaterialTextureProperty(embeddedTexIdxs, r, (glTF2::TextureInfo)prop, mat, texType, texSlot); + SetMaterialTextureProperty(embeddedTexIdxs, r, (glTF2::TextureInfo)prop, mat, texType, texSlot); - if (prop.texture && prop.texture->source) { - mat->AddProperty(&prop.strength, 1, AI_MATKEY_GLTF_TEXTURE_STRENGTH(texType, texSlot)); - } + if (prop.texture && prop.texture->source) { + mat->AddProperty(&prop.strength, 1, AI_MATKEY_GLTF_TEXTURE_STRENGTH(texType, texSlot)); + } } static aiMaterial *ImportMaterial(std::vector &embeddedTexIdxs, Asset &r, Material &mat) { - aiMaterial *aimat = new aiMaterial(); + aiMaterial *aimat = new aiMaterial(); - if (!mat.name.empty()) { - aiString str(mat.name); + if (!mat.name.empty()) { + aiString str(mat.name); - aimat->AddProperty(&str, AI_MATKEY_NAME); - } + aimat->AddProperty(&str, AI_MATKEY_NAME); + } - SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); - SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR); + SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); + SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE); - aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR); - aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR); + aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR); + aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR); - float roughnessAsShininess = 1 - mat.pbrMetallicRoughness.roughnessFactor; - roughnessAsShininess *= roughnessAsShininess * 1000; - aimat->AddProperty(&roughnessAsShininess, 1, AI_MATKEY_SHININESS); + float roughnessAsShininess = 1 - mat.pbrMetallicRoughness.roughnessFactor; + roughnessAsShininess *= roughnessAsShininess * 1000; + aimat->AddProperty(&roughnessAsShininess, 1, AI_MATKEY_SHININESS); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.normalTexture, aimat, aiTextureType_NORMALS); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.occlusionTexture, aimat, aiTextureType_LIGHTMAP); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.emissiveTexture, aimat, aiTextureType_EMISSIVE); - SetMaterialColorProperty(r, mat.emissiveFactor, aimat, AI_MATKEY_COLOR_EMISSIVE); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.normalTexture, aimat, aiTextureType_NORMALS); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.occlusionTexture, aimat, aiTextureType_LIGHTMAP); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.emissiveTexture, aimat, aiTextureType_EMISSIVE); + SetMaterialColorProperty(r, mat.emissiveFactor, aimat, AI_MATKEY_COLOR_EMISSIVE); - aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED); + aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED); - aiString alphaMode(mat.alphaMode); - aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE); - aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF); + aiString alphaMode(mat.alphaMode); + aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE); + aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF); - //pbrSpecularGlossiness - if (mat.pbrSpecularGlossiness.isPresent) { - PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value; + //pbrSpecularGlossiness + if (mat.pbrSpecularGlossiness.isPresent) { + PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value; - aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS); - SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); - SetMaterialColorProperty(r, pbrSG.specularFactor, aimat, AI_MATKEY_COLOR_SPECULAR); + aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS); + SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); + SetMaterialColorProperty(r, pbrSG.specularFactor, aimat, AI_MATKEY_COLOR_SPECULAR); - float glossinessAsShininess = pbrSG.glossinessFactor * 1000.0f; - aimat->AddProperty(&glossinessAsShininess, 1, AI_MATKEY_SHININESS); - aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR); + float glossinessAsShininess = pbrSG.glossinessFactor * 1000.0f; + aimat->AddProperty(&glossinessAsShininess, 1, AI_MATKEY_SHININESS); + aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR); - SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.diffuseTexture, aimat, aiTextureType_DIFFUSE); + SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.diffuseTexture, aimat, aiTextureType_DIFFUSE); - SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, aiTextureType_SPECULAR); - } - if (mat.unlit) { - aimat->AddProperty(&mat.unlit, 1, AI_MATKEY_GLTF_UNLIT); - } + SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, aiTextureType_SPECULAR); + } + if (mat.unlit) { + aimat->AddProperty(&mat.unlit, 1, AI_MATKEY_GLTF_UNLIT); + } - return aimat; + return aimat; } void glTF2Importer::ImportMaterials(glTF2::Asset &r) { - const unsigned int numImportedMaterials = unsigned(r.materials.Size()); - ASSIMP_LOG_DEBUG_F("Importing ", numImportedMaterials, " materials"); - Material defaultMaterial; + const unsigned int numImportedMaterials = unsigned(r.materials.Size()); + ASSIMP_LOG_DEBUG_F("Importing ", numImportedMaterials, " materials"); + Material defaultMaterial; - mScene->mNumMaterials = numImportedMaterials + 1; - mScene->mMaterials = new aiMaterial *[mScene->mNumMaterials]; - mScene->mMaterials[numImportedMaterials] = ImportMaterial(embeddedTexIdxs, r, defaultMaterial); + mScene->mNumMaterials = numImportedMaterials + 1; + mScene->mMaterials = new aiMaterial *[mScene->mNumMaterials]; + mScene->mMaterials[numImportedMaterials] = ImportMaterial(embeddedTexIdxs, r, defaultMaterial); - for (unsigned int i = 0; i < numImportedMaterials; ++i) { - mScene->mMaterials[i] = ImportMaterial(embeddedTexIdxs, r, r.materials[i]); - } + for (unsigned int i = 0; i < numImportedMaterials; ++i) { + mScene->mMaterials[i] = ImportMaterial(embeddedTexIdxs, r, r.materials[i]); + } } static inline void SetFaceAndAdvance1(aiFace*& face, unsigned int numVertices, unsigned int a) { - if (a >= numVertices) { - return; - } - face->mNumIndices = 1; - face->mIndices = new unsigned int[1]; - face->mIndices[0] = a; - ++face; + if (a >= numVertices) { + return; + } + face->mNumIndices = 1; + face->mIndices = new unsigned int[1]; + face->mIndices[0] = a; + ++face; } static inline void SetFaceAndAdvance2(aiFace*& face, unsigned int numVertices, unsigned int a, unsigned int b) { - if ((a >= numVertices) || (b >= numVertices)) { - return; - } - face->mNumIndices = 2; - face->mIndices = new unsigned int[2]; - face->mIndices[0] = a; - face->mIndices[1] = b; - ++face; + if ((a >= numVertices) || (b >= numVertices)) { + return; + } + face->mNumIndices = 2; + face->mIndices = new unsigned int[2]; + face->mIndices[0] = a; + face->mIndices[1] = b; + ++face; } static inline void SetFaceAndAdvance3(aiFace*& face, unsigned int numVertices, unsigned int a, unsigned int b, unsigned int c) { - if ((a >= numVertices) || (b >= numVertices) || (c >= numVertices)) { - return; - } - face->mNumIndices = 3; - face->mIndices = new unsigned int[3]; - face->mIndices[0] = a; - face->mIndices[1] = b; - face->mIndices[2] = c; - ++face; + if ((a >= numVertices) || (b >= numVertices) || (c >= numVertices)) { + return; + } + face->mNumIndices = 3; + face->mIndices = new unsigned int[3]; + face->mIndices[0] = a; + face->mIndices[1] = b; + face->mIndices[2] = c; + ++face; } #ifdef ASSIMP_BUILD_DEBUG static inline bool CheckValidFacesIndices(aiFace *faces, unsigned nFaces, unsigned nVerts) { - for (unsigned i = 0; i < nFaces; ++i) { - for (unsigned j = 0; j < faces[i].mNumIndices; ++j) { - unsigned idx = faces[i].mIndices[j]; - if (idx >= nVerts) { - return false; - } - } - } - return true; + for (unsigned i = 0; i < nFaces; ++i) { + for (unsigned j = 0; j < faces[i].mNumIndices; ++j) { + unsigned idx = faces[i].mIndices[j]; + if (idx >= nVerts) { + return false; + } + } + } + return true; } #endif // ASSIMP_BUILD_DEBUG void glTF2Importer::ImportMeshes(glTF2::Asset &r) { - ASSIMP_LOG_DEBUG_F("Importing ", r.meshes.Size(), " meshes"); - std::vector> meshes; + ASSIMP_LOG_DEBUG_F("Importing ", r.meshes.Size(), " meshes"); + std::vector> meshes; - unsigned int k = 0; + unsigned int k = 0; meshOffsets.clear(); - for (unsigned int m = 0; m < r.meshes.Size(); ++m) { - Mesh &mesh = r.meshes[m]; + for (unsigned int m = 0; m < r.meshes.Size(); ++m) { + Mesh &mesh = r.meshes[m]; - meshOffsets.push_back(k); - k += unsigned(mesh.primitives.size()); + meshOffsets.push_back(k); + k += unsigned(mesh.primitives.size()); - for (unsigned int p = 0; p < mesh.primitives.size(); ++p) { - Mesh::Primitive &prim = mesh.primitives[p]; + for (unsigned int p = 0; p < mesh.primitives.size(); ++p) { + Mesh::Primitive &prim = mesh.primitives[p]; - aiMesh *aim = new aiMesh(); - meshes.push_back(std::unique_ptr(aim)); + aiMesh *aim = new aiMesh(); + meshes.push_back(std::unique_ptr(aim)); - aim->mName = mesh.name.empty() ? mesh.id : mesh.name; + aim->mName = mesh.name.empty() ? mesh.id : mesh.name; - if (mesh.primitives.size() > 1) { - ai_uint32 &len = aim->mName.length; - aim->mName.data[len] = '-'; - len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p); - } + if (mesh.primitives.size() > 1) { + ai_uint32 &len = aim->mName.length; + aim->mName.data[len] = '-'; + len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p); + } - switch (prim.mode) { - case PrimitiveMode_POINTS: - aim->mPrimitiveTypes |= aiPrimitiveType_POINT; - break; + switch (prim.mode) { + case PrimitiveMode_POINTS: + aim->mPrimitiveTypes |= aiPrimitiveType_POINT; + break; - case PrimitiveMode_LINES: - case PrimitiveMode_LINE_LOOP: - case PrimitiveMode_LINE_STRIP: - aim->mPrimitiveTypes |= aiPrimitiveType_LINE; - break; + case PrimitiveMode_LINES: + case PrimitiveMode_LINE_LOOP: + case PrimitiveMode_LINE_STRIP: + aim->mPrimitiveTypes |= aiPrimitiveType_LINE; + break; - case PrimitiveMode_TRIANGLES: - case PrimitiveMode_TRIANGLE_STRIP: - case PrimitiveMode_TRIANGLE_FAN: - aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - break; - } + case PrimitiveMode_TRIANGLES: + case PrimitiveMode_TRIANGLE_STRIP: + case PrimitiveMode_TRIANGLE_FAN: + aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; + break; + } - Mesh::Primitive::Attributes &attr = prim.attributes; + Mesh::Primitive::Attributes &attr = prim.attributes; - if (attr.position.size() > 0 && attr.position[0]) { - aim->mNumVertices = static_cast(attr.position[0]->count); - attr.position[0]->ExtractData(aim->mVertices); - } + if (attr.position.size() > 0 && attr.position[0]) { + aim->mNumVertices = static_cast(attr.position[0]->count); + attr.position[0]->ExtractData(aim->mVertices); + } - if (attr.normal.size() > 0 && attr.normal[0]) { - attr.normal[0]->ExtractData(aim->mNormals); + if (attr.normal.size() > 0 && attr.normal[0]) { + attr.normal[0]->ExtractData(aim->mNormals); - // only extract tangents if normals are present - if (attr.tangent.size() > 0 && attr.tangent[0]) { - // generate bitangents from normals and tangents according to spec - Tangent *tangents = nullptr; + // only extract tangents if normals are present + if (attr.tangent.size() > 0 && attr.tangent[0]) { + // generate bitangents from normals and tangents according to spec + Tangent *tangents = nullptr; - attr.tangent[0]->ExtractData(tangents); + attr.tangent[0]->ExtractData(tangents); - aim->mTangents = new aiVector3D[aim->mNumVertices]; - aim->mBitangents = new aiVector3D[aim->mNumVertices]; + aim->mTangents = new aiVector3D[aim->mNumVertices]; + aim->mBitangents = new aiVector3D[aim->mNumVertices]; - for (unsigned int i = 0; i < aim->mNumVertices; ++i) { - aim->mTangents[i] = tangents[i].xyz; - aim->mBitangents[i] = (aim->mNormals[i] ^ tangents[i].xyz) * tangents[i].w; - } + for (unsigned int i = 0; i < aim->mNumVertices; ++i) { + aim->mTangents[i] = tangents[i].xyz; + aim->mBitangents[i] = (aim->mNormals[i] ^ tangents[i].xyz) * tangents[i].w; + } - delete[] tangents; - } - } + delete[] tangents; + } + } - for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) { - if (attr.color[c]->count != aim->mNumVertices) { - DefaultLogger::get()->warn("Color stream size in mesh \"" + mesh.name + - "\" does not match the vertex count"); - continue; - } - attr.color[c]->ExtractData(aim->mColors[c]); - } - for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) { + for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) { + if (attr.color[c]->count != aim->mNumVertices) { + DefaultLogger::get()->warn("Color stream size in mesh \"" + mesh.name + + "\" does not match the vertex count"); + continue; + } + attr.color[c]->ExtractData(aim->mColors[c]); + } + for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) { if (!attr.texcoord[tc]) { DefaultLogger::get()->warn("Texture coordinate accessor not found or non-contiguous texture coordinate sets."); continue; } - if (attr.texcoord[tc]->count != aim->mNumVertices) { - DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name + - "\" does not match the vertex count"); - continue; - } + if (attr.texcoord[tc]->count != aim->mNumVertices) { + DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name + + "\" does not match the vertex count"); + continue; + } - attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]); - aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents(); + attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]); + aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents(); - aiVector3D *values = aim->mTextureCoords[tc]; - for (unsigned int i = 0; i < aim->mNumVertices; ++i) { - values[i].y = 1 - values[i].y; // Flip Y coords - } - } + aiVector3D *values = aim->mTextureCoords[tc]; + for (unsigned int i = 0; i < aim->mNumVertices; ++i) { + values[i].y = 1 - values[i].y; // Flip Y coords + } + } - std::vector &targets = prim.targets; - if (targets.size() > 0) { - aim->mNumAnimMeshes = (unsigned int)targets.size(); - aim->mAnimMeshes = new aiAnimMesh *[aim->mNumAnimMeshes]; - for (size_t i = 0; i < targets.size(); i++) { - aim->mAnimMeshes[i] = aiCreateAnimMesh(aim); - aiAnimMesh &aiAnimMesh = *(aim->mAnimMeshes[i]); - Mesh::Primitive::Target &target = targets[i]; + std::vector &targets = prim.targets; + if (targets.size() > 0) { + aim->mNumAnimMeshes = (unsigned int)targets.size(); + aim->mAnimMeshes = new aiAnimMesh *[aim->mNumAnimMeshes]; + for (size_t i = 0; i < targets.size(); i++) { + aim->mAnimMeshes[i] = aiCreateAnimMesh(aim); + aiAnimMesh &aiAnimMesh = *(aim->mAnimMeshes[i]); + Mesh::Primitive::Target &target = targets[i]; - if (target.position.size() > 0) { - aiVector3D *positionDiff = nullptr; - target.position[0]->ExtractData(positionDiff); - for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) { - aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId]; - } - delete[] positionDiff; - } - if (target.normal.size() > 0) { - aiVector3D *normalDiff = nullptr; - target.normal[0]->ExtractData(normalDiff); - for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) { - aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId]; - } - delete[] normalDiff; - } - if (target.tangent.size() > 0) { - Tangent *tangent = nullptr; - attr.tangent[0]->ExtractData(tangent); + if (target.position.size() > 0) { + aiVector3D *positionDiff = nullptr; + target.position[0]->ExtractData(positionDiff); + for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) { + aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId]; + } + delete[] positionDiff; + } + if (target.normal.size() > 0) { + aiVector3D *normalDiff = nullptr; + target.normal[0]->ExtractData(normalDiff); + for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) { + aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId]; + } + delete[] normalDiff; + } + if (target.tangent.size() > 0) { + Tangent *tangent = nullptr; + attr.tangent[0]->ExtractData(tangent); - aiVector3D *tangentDiff = nullptr; - target.tangent[0]->ExtractData(tangentDiff); + aiVector3D *tangentDiff = nullptr; + target.tangent[0]->ExtractData(tangentDiff); - for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) { - tangent[vertexId].xyz += tangentDiff[vertexId]; - aiAnimMesh.mTangents[vertexId] = tangent[vertexId].xyz; - aiAnimMesh.mBitangents[vertexId] = (aiAnimMesh.mNormals[vertexId] ^ tangent[vertexId].xyz) * tangent[vertexId].w; - } - delete[] tangent; - delete[] tangentDiff; - } - if (mesh.weights.size() > i) { - aiAnimMesh.mWeight = mesh.weights[i]; - } - if (mesh.targetNames.size() > i) { - aiAnimMesh.mName = mesh.targetNames[i]; - } - } - } + for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) { + tangent[vertexId].xyz += tangentDiff[vertexId]; + aiAnimMesh.mTangents[vertexId] = tangent[vertexId].xyz; + aiAnimMesh.mBitangents[vertexId] = (aiAnimMesh.mNormals[vertexId] ^ tangent[vertexId].xyz) * tangent[vertexId].w; + } + delete[] tangent; + delete[] tangentDiff; + } + if (mesh.weights.size() > i) { + aiAnimMesh.mWeight = mesh.weights[i]; + } + if (mesh.targetNames.size() > i) { + aiAnimMesh.mName = mesh.targetNames[i]; + } + } + } - aiFace *faces = nullptr; - aiFace *facePtr = nullptr; - size_t nFaces = 0; + aiFace *faces = nullptr; + aiFace *facePtr = nullptr; + size_t nFaces = 0; - if (prim.indices) { - size_t count = prim.indices->count; + if (prim.indices) { + size_t count = prim.indices->count; - Accessor::Indexer data = prim.indices->GetIndexer(); - ai_assert(data.IsValid()); + Accessor::Indexer data = prim.indices->GetIndexer(); + ai_assert(data.IsValid()); - switch (prim.mode) { - case PrimitiveMode_POINTS: { - nFaces = count; - facePtr = faces = new aiFace[nFaces]; - for (unsigned int i = 0; i < count; ++i) { - SetFaceAndAdvance1(facePtr, aim->mNumVertices, data.GetUInt(i)); - } - break; - } + switch (prim.mode) { + case PrimitiveMode_POINTS: { + nFaces = count; + facePtr = faces = new aiFace[nFaces]; + for (unsigned int i = 0; i < count; ++i) { + SetFaceAndAdvance1(facePtr, aim->mNumVertices, data.GetUInt(i)); + } + break; + } - case PrimitiveMode_LINES: { - nFaces = count / 2; - if (nFaces * 2 != count) { - ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped."); - count = nFaces * 2; - } - facePtr = faces = new aiFace[nFaces]; - for (unsigned int i = 0; i < count; i += 2) { - SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1)); - } - break; - } + case PrimitiveMode_LINES: { + nFaces = count / 2; + if (nFaces * 2 != count) { + ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped."); + count = nFaces * 2; + } + facePtr = faces = new aiFace[nFaces]; + for (unsigned int i = 0; i < count; i += 2) { + SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1)); + } + break; + } - case PrimitiveMode_LINE_LOOP: - case PrimitiveMode_LINE_STRIP: { - nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0); - facePtr = faces = new aiFace[nFaces]; - SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1)); - for (unsigned int i = 2; i < count; ++i) { - SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i - 1), data.GetUInt(i)); - } - if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop - SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(static_cast(count) - 1), faces[0].mIndices[0]); - } - break; - } + case PrimitiveMode_LINE_LOOP: + case PrimitiveMode_LINE_STRIP: { + nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0); + facePtr = faces = new aiFace[nFaces]; + SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1)); + for (unsigned int i = 2; i < count; ++i) { + SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i - 1), data.GetUInt(i)); + } + if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop + SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(static_cast(count) - 1), faces[0].mIndices[0]); + } + break; + } - case PrimitiveMode_TRIANGLES: { - nFaces = count / 3; - if (nFaces * 3 != count) { - ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped."); - count = nFaces * 3; - } - facePtr = faces = new aiFace[nFaces]; - for (unsigned int i = 0; i < count; i += 3) { - SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2)); - } - break; - } - case PrimitiveMode_TRIANGLE_STRIP: { - nFaces = count - 2; - facePtr = faces = new aiFace[nFaces]; - for (unsigned int i = 0; i < nFaces; ++i) { - //The ordering is to ensure that the triangles are all drawn with the same orientation - if ((i + 1) % 2 == 0) { - //For even n, vertices n + 1, n, and n + 2 define triangle n - SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2)); - } else { - //For odd n, vertices n, n+1, and n+2 define triangle n - SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2)); - } - } - break; - } - case PrimitiveMode_TRIANGLE_FAN: - nFaces = count - 2; - facePtr = faces = new aiFace[nFaces]; - SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1), data.GetUInt(2)); - for (unsigned int i = 1; i < nFaces; ++i) { - SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(i + 1), data.GetUInt(i + 2)); - } - break; - } - } else { // no indices provided so directly generate from counts + case PrimitiveMode_TRIANGLES: { + nFaces = count / 3; + if (nFaces * 3 != count) { + ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped."); + count = nFaces * 3; + } + facePtr = faces = new aiFace[nFaces]; + for (unsigned int i = 0; i < count; i += 3) { + SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2)); + } + break; + } + case PrimitiveMode_TRIANGLE_STRIP: { + nFaces = count - 2; + facePtr = faces = new aiFace[nFaces]; + for (unsigned int i = 0; i < nFaces; ++i) { + //The ordering is to ensure that the triangles are all drawn with the same orientation + if ((i + 1) % 2 == 0) { + //For even n, vertices n + 1, n, and n + 2 define triangle n + SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2)); + } else { + //For odd n, vertices n, n+1, and n+2 define triangle n + SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2)); + } + } + break; + } + case PrimitiveMode_TRIANGLE_FAN: + nFaces = count - 2; + facePtr = faces = new aiFace[nFaces]; + SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1), data.GetUInt(2)); + for (unsigned int i = 1; i < nFaces; ++i) { + SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(i + 1), data.GetUInt(i + 2)); + } + break; + } + } else { // no indices provided so directly generate from counts - // use the already determined count as it includes checks - unsigned int count = aim->mNumVertices; + // use the already determined count as it includes checks + unsigned int count = aim->mNumVertices; - switch (prim.mode) { - case PrimitiveMode_POINTS: { - nFaces = count; - facePtr = faces = new aiFace[nFaces]; - for (unsigned int i = 0; i < count; ++i) { - SetFaceAndAdvance1(facePtr, aim->mNumVertices, i); - } - break; - } + switch (prim.mode) { + case PrimitiveMode_POINTS: { + nFaces = count; + facePtr = faces = new aiFace[nFaces]; + for (unsigned int i = 0; i < count; ++i) { + SetFaceAndAdvance1(facePtr, aim->mNumVertices, i); + } + break; + } - case PrimitiveMode_LINES: { - nFaces = count / 2; - if (nFaces * 2 != count) { - ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped."); - count = (unsigned int)nFaces * 2; - } - facePtr = faces = new aiFace[nFaces]; - for (unsigned int i = 0; i < count; i += 2) { - SetFaceAndAdvance2(facePtr, aim->mNumVertices, i, i + 1); - } - break; - } + case PrimitiveMode_LINES: { + nFaces = count / 2; + if (nFaces * 2 != count) { + ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped."); + count = (unsigned int)nFaces * 2; + } + facePtr = faces = new aiFace[nFaces]; + for (unsigned int i = 0; i < count; i += 2) { + SetFaceAndAdvance2(facePtr, aim->mNumVertices, i, i + 1); + } + break; + } - case PrimitiveMode_LINE_LOOP: - case PrimitiveMode_LINE_STRIP: { - nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0); - facePtr = faces = new aiFace[nFaces]; - SetFaceAndAdvance2(facePtr, aim->mNumVertices, 0, 1); - for (unsigned int i = 2; i < count; ++i) { - SetFaceAndAdvance2(facePtr, aim->mNumVertices, i - 1, i); - } - if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop - SetFaceAndAdvance2(facePtr, aim->mNumVertices, count - 1, 0); - } - break; - } + case PrimitiveMode_LINE_LOOP: + case PrimitiveMode_LINE_STRIP: { + nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0); + facePtr = faces = new aiFace[nFaces]; + SetFaceAndAdvance2(facePtr, aim->mNumVertices, 0, 1); + for (unsigned int i = 2; i < count; ++i) { + SetFaceAndAdvance2(facePtr, aim->mNumVertices, i - 1, i); + } + if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop + SetFaceAndAdvance2(facePtr, aim->mNumVertices, count - 1, 0); + } + break; + } - case PrimitiveMode_TRIANGLES: { - nFaces = count / 3; - if (nFaces * 3 != count) { - ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped."); - count = (unsigned int)nFaces * 3; - } - facePtr = faces = new aiFace[nFaces]; - for (unsigned int i = 0; i < count; i += 3) { - SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2); - } - break; - } - case PrimitiveMode_TRIANGLE_STRIP: { - nFaces = count - 2; - facePtr = faces = new aiFace[nFaces]; - for (unsigned int i = 0; i < nFaces; ++i) { - //The ordering is to ensure that the triangles are all drawn with the same orientation - if ((i + 1) % 2 == 0) { - //For even n, vertices n + 1, n, and n + 2 define triangle n - SetFaceAndAdvance3(facePtr, aim->mNumVertices, i + 1, i, i + 2); - } else { - //For odd n, vertices n, n+1, and n+2 define triangle n - SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2); - } - } - break; - } - case PrimitiveMode_TRIANGLE_FAN: - nFaces = count - 2; - facePtr = faces = new aiFace[nFaces]; - SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, 1, 2); - for (unsigned int i = 1; i < nFaces; ++i) { - SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, i + 1, i + 2); - } - break; - } - } + case PrimitiveMode_TRIANGLES: { + nFaces = count / 3; + if (nFaces * 3 != count) { + ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped."); + count = (unsigned int)nFaces * 3; + } + facePtr = faces = new aiFace[nFaces]; + for (unsigned int i = 0; i < count; i += 3) { + SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2); + } + break; + } + case PrimitiveMode_TRIANGLE_STRIP: { + nFaces = count - 2; + facePtr = faces = new aiFace[nFaces]; + for (unsigned int i = 0; i < nFaces; ++i) { + //The ordering is to ensure that the triangles are all drawn with the same orientation + if ((i + 1) % 2 == 0) { + //For even n, vertices n + 1, n, and n + 2 define triangle n + SetFaceAndAdvance3(facePtr, aim->mNumVertices, i + 1, i, i + 2); + } else { + //For odd n, vertices n, n+1, and n+2 define triangle n + SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2); + } + } + break; + } + case PrimitiveMode_TRIANGLE_FAN: + nFaces = count - 2; + facePtr = faces = new aiFace[nFaces]; + SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, 1, 2); + for (unsigned int i = 1; i < nFaces; ++i) { + SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, i + 1, i + 2); + } + break; + } + } - if (faces) { - aim->mFaces = faces; + if (faces) { + aim->mFaces = faces; const unsigned int actualNumFaces = static_cast(facePtr - faces); - if (actualNumFaces < nFaces) { - ASSIMP_LOG_WARN("Some faces had out-of-range indices. Those faces were dropped."); - } - if (actualNumFaces == 0) - { - throw DeadlyImportError("Mesh \"", aim->mName.C_Str(), "\" has no faces"); - } - aim->mNumFaces = actualNumFaces; - ai_assert(CheckValidFacesIndices(faces, actualNumFaces, aim->mNumVertices)); - } + if (actualNumFaces < nFaces) { + ASSIMP_LOG_WARN("Some faces had out-of-range indices. Those faces were dropped."); + } + if (actualNumFaces == 0) + { + throw DeadlyImportError("Mesh \"", aim->mName.C_Str(), "\" has no faces"); + } + aim->mNumFaces = actualNumFaces; + ai_assert(CheckValidFacesIndices(faces, actualNumFaces, aim->mNumVertices)); + } - if (prim.material) { - aim->mMaterialIndex = prim.material.GetIndex(); - } else { - aim->mMaterialIndex = mScene->mNumMaterials - 1; - } - } - } + if (prim.material) { + aim->mMaterialIndex = prim.material.GetIndex(); + } else { + aim->mMaterialIndex = mScene->mNumMaterials - 1; + } + } + } - meshOffsets.push_back(k); + meshOffsets.push_back(k); - CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes); + CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes); } void glTF2Importer::ImportCameras(glTF2::Asset &r) { - if (!r.cameras.Size()) return; + if (!r.cameras.Size()) return; const unsigned int numCameras = r.cameras.Size(); - ASSIMP_LOG_DEBUG_F("Importing ", numCameras, " cameras"); - mScene->mNumCameras = numCameras; - mScene->mCameras = new aiCamera *[numCameras]; + ASSIMP_LOG_DEBUG_F("Importing ", numCameras, " cameras"); + mScene->mNumCameras = numCameras; + mScene->mCameras = new aiCamera *[numCameras]; - for (size_t i = 0; i < numCameras; ++i) { - Camera &cam = r.cameras[i]; + for (size_t i = 0; i < numCameras; ++i) { + Camera &cam = r.cameras[i]; - aiCamera *aicam = mScene->mCameras[i] = new aiCamera(); + aiCamera *aicam = mScene->mCameras[i] = new aiCamera(); - // cameras point in -Z by default, rest is specified in node transform - aicam->mLookAt = aiVector3D(0.f, 0.f, -1.f); + // cameras point in -Z by default, rest is specified in node transform + aicam->mLookAt = aiVector3D(0.f, 0.f, -1.f); - if (cam.type == Camera::Perspective) { + if (cam.type == Camera::Perspective) { - aicam->mAspect = cam.cameraProperties.perspective.aspectRatio; - aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect); - aicam->mClipPlaneFar = cam.cameraProperties.perspective.zfar; - aicam->mClipPlaneNear = cam.cameraProperties.perspective.znear; - } else { - aicam->mClipPlaneFar = cam.cameraProperties.ortographic.zfar; - aicam->mClipPlaneNear = cam.cameraProperties.ortographic.znear; - aicam->mHorizontalFOV = 0.0; - aicam->mOrthographicWidth = cam.cameraProperties.ortographic.xmag; - aicam->mAspect = 1.0f; - if (0.f != cam.cameraProperties.ortographic.ymag) { - aicam->mAspect = cam.cameraProperties.ortographic.xmag / cam.cameraProperties.ortographic.ymag; - } - } - } + aicam->mAspect = cam.cameraProperties.perspective.aspectRatio; + aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect); + aicam->mClipPlaneFar = cam.cameraProperties.perspective.zfar; + aicam->mClipPlaneNear = cam.cameraProperties.perspective.znear; + } else { + aicam->mClipPlaneFar = cam.cameraProperties.ortographic.zfar; + aicam->mClipPlaneNear = cam.cameraProperties.ortographic.znear; + aicam->mHorizontalFOV = 0.0; + aicam->mOrthographicWidth = cam.cameraProperties.ortographic.xmag; + aicam->mAspect = 1.0f; + if (0.f != cam.cameraProperties.ortographic.ymag) { + aicam->mAspect = cam.cameraProperties.ortographic.xmag / cam.cameraProperties.ortographic.ymag; + } + } + } } void glTF2Importer::ImportLights(glTF2::Asset &r) { - if (!r.lights.Size()) - return; + if (!r.lights.Size()) + return; const unsigned int numLights = r.lights.Size(); - ASSIMP_LOG_DEBUG_F("Importing ", numLights, " lights"); - mScene->mNumLights = numLights; - mScene->mLights = new aiLight *[numLights]; + ASSIMP_LOG_DEBUG_F("Importing ", numLights, " lights"); + mScene->mNumLights = numLights; + mScene->mLights = new aiLight *[numLights]; - for (size_t i = 0; i < numLights; ++i) { - Light &light = r.lights[i]; + for (size_t i = 0; i < numLights; ++i) { + Light &light = r.lights[i]; - aiLight *ail = mScene->mLights[i] = new aiLight(); + aiLight *ail = mScene->mLights[i] = new aiLight(); - switch (light.type) { - case Light::Directional: - ail->mType = aiLightSource_DIRECTIONAL; - break; - case Light::Point: - ail->mType = aiLightSource_POINT; - break; - case Light::Spot: - ail->mType = aiLightSource_SPOT; - break; - } + switch (light.type) { + case Light::Directional: + ail->mType = aiLightSource_DIRECTIONAL; + break; + case Light::Point: + ail->mType = aiLightSource_POINT; + break; + case Light::Spot: + ail->mType = aiLightSource_SPOT; + break; + } - if (ail->mType != aiLightSource_POINT) { - ail->mDirection = aiVector3D(0.0f, 0.0f, -1.0f); - ail->mUp = aiVector3D(0.0f, 1.0f, 0.0f); - } + if (ail->mType != aiLightSource_POINT) { + ail->mDirection = aiVector3D(0.0f, 0.0f, -1.0f); + ail->mUp = aiVector3D(0.0f, 1.0f, 0.0f); + } - vec3 colorWithIntensity = { light.color[0] * light.intensity, light.color[1] * light.intensity, light.color[2] * light.intensity }; - CopyValue(colorWithIntensity, ail->mColorAmbient); - CopyValue(colorWithIntensity, ail->mColorDiffuse); - CopyValue(colorWithIntensity, ail->mColorSpecular); + vec3 colorWithIntensity = { light.color[0] * light.intensity, light.color[1] * light.intensity, light.color[2] * light.intensity }; + CopyValue(colorWithIntensity, ail->mColorAmbient); + CopyValue(colorWithIntensity, ail->mColorDiffuse); + CopyValue(colorWithIntensity, ail->mColorSpecular); - if (ail->mType == aiLightSource_DIRECTIONAL) { - ail->mAttenuationConstant = 1.0; - ail->mAttenuationLinear = 0.0; - ail->mAttenuationQuadratic = 0.0; - } else { - //in PBR attenuation is calculated using inverse square law which can be expressed - //using assimps equation: 1/(att0 + att1 * d + att2 * d*d) with the following parameters - //this is correct equation for the case when range (see - //https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual) - //is not present. When range is not present it is assumed that it is infinite and so numerator is 1. - //When range is present then numerator might be any value in range [0,1] and then assimps equation - //will not suffice. In this case range is added into metadata in ImportNode function - //and its up to implementation to read it when it wants to - ail->mAttenuationConstant = 0.0; - ail->mAttenuationLinear = 0.0; - ail->mAttenuationQuadratic = 1.0; - } + if (ail->mType == aiLightSource_DIRECTIONAL) { + ail->mAttenuationConstant = 1.0; + ail->mAttenuationLinear = 0.0; + ail->mAttenuationQuadratic = 0.0; + } else { + //in PBR attenuation is calculated using inverse square law which can be expressed + //using assimps equation: 1/(att0 + att1 * d + att2 * d*d) with the following parameters + //this is correct equation for the case when range (see + //https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual) + //is not present. When range is not present it is assumed that it is infinite and so numerator is 1. + //When range is present then numerator might be any value in range [0,1] and then assimps equation + //will not suffice. In this case range is added into metadata in ImportNode function + //and its up to implementation to read it when it wants to + ail->mAttenuationConstant = 0.0; + ail->mAttenuationLinear = 0.0; + ail->mAttenuationQuadratic = 1.0; + } - if (ail->mType == aiLightSource_SPOT) { - ail->mAngleInnerCone = light.innerConeAngle; - ail->mAngleOuterCone = light.outerConeAngle; - } - } + if (ail->mType == aiLightSource_SPOT) { + ail->mAngleInnerCone = light.innerConeAngle; + ail->mAngleOuterCone = light.outerConeAngle; + } + } } static void GetNodeTransform(aiMatrix4x4 &matrix, const glTF2::Node &node) { - if (node.matrix.isPresent) { - CopyValue(node.matrix.value, matrix); - } else { - if (node.translation.isPresent) { - aiVector3D trans; - CopyValue(node.translation.value, trans); - aiMatrix4x4 t; - aiMatrix4x4::Translation(trans, t); - matrix = matrix * t; - } + if (node.matrix.isPresent) { + CopyValue(node.matrix.value, matrix); + } else { + if (node.translation.isPresent) { + aiVector3D trans; + CopyValue(node.translation.value, trans); + aiMatrix4x4 t; + aiMatrix4x4::Translation(trans, t); + matrix = matrix * t; + } - if (node.rotation.isPresent) { - aiQuaternion rot; - CopyValue(node.rotation.value, rot); - matrix = matrix * aiMatrix4x4(rot.GetMatrix()); - } + if (node.rotation.isPresent) { + aiQuaternion rot; + CopyValue(node.rotation.value, rot); + matrix = matrix * aiMatrix4x4(rot.GetMatrix()); + } - if (node.scale.isPresent) { - aiVector3D scal(1.f); - CopyValue(node.scale.value, scal); - aiMatrix4x4 s; - aiMatrix4x4::Scaling(scal, s); - matrix = matrix * s; - } - } + if (node.scale.isPresent) { + aiVector3D scal(1.f); + CopyValue(node.scale.value, scal); + aiMatrix4x4 s; + aiMatrix4x4::Scaling(scal, s); + matrix = matrix * s; + } + } } static void BuildVertexWeightMapping(Mesh::Primitive &primitive, std::vector> &map) { - Mesh::Primitive::Attributes &attr = primitive.attributes; - if (attr.weight.empty() || attr.joint.empty()) { - return; - } - if (attr.weight[0]->count != attr.joint[0]->count) { - return; - } + Mesh::Primitive::Attributes &attr = primitive.attributes; + if (attr.weight.empty() || attr.joint.empty()) { + return; + } + if (attr.weight[0]->count != attr.joint[0]->count) { + return; + } - size_t num_vertices = attr.weight[0]->count; + size_t num_vertices = attr.weight[0]->count; - struct Weights { - float values[4]; - }; - Weights *weights = nullptr; - attr.weight[0]->ExtractData(weights); + struct Weights { + float values[4]; + }; + Weights *weights = nullptr; + attr.weight[0]->ExtractData(weights); - struct Indices8 { - uint8_t values[4]; - }; - struct Indices16 { - uint16_t values[4]; - }; - Indices8 *indices8 = nullptr; - Indices16 *indices16 = nullptr; - if (attr.joint[0]->GetElementSize() == 4) { - attr.joint[0]->ExtractData(indices8); - } else { - attr.joint[0]->ExtractData(indices16); - } - // - if (nullptr == indices8 && nullptr == indices16) { - // Something went completely wrong! - ai_assert(false); - return; - } + struct Indices8 { + uint8_t values[4]; + }; + struct Indices16 { + uint16_t values[4]; + }; + Indices8 *indices8 = nullptr; + Indices16 *indices16 = nullptr; + if (attr.joint[0]->GetElementSize() == 4) { + attr.joint[0]->ExtractData(indices8); + } else { + attr.joint[0]->ExtractData(indices16); + } + // + if (nullptr == indices8 && nullptr == indices16) { + // Something went completely wrong! + ai_assert(false); + return; + } - for (size_t i = 0; i < num_vertices; ++i) { - for (int j = 0; j < 4; ++j) { - const unsigned int bone = (indices8 != nullptr) ? indices8[i].values[j] : indices16[i].values[j]; - const float weight = weights[i].values[j]; - if (weight > 0 && bone < map.size()) { - map[bone].reserve(8); - map[bone].emplace_back(static_cast(i), weight); - } - } - } + for (size_t i = 0; i < num_vertices; ++i) { + for (int j = 0; j < 4; ++j) { + const unsigned int bone = (indices8 != nullptr) ? indices8[i].values[j] : indices16[i].values[j]; + const float weight = weights[i].values[j]; + if (weight > 0 && bone < map.size()) { + map[bone].reserve(8); + map[bone].emplace_back(static_cast(i), weight); + } + } + } - delete[] weights; - delete[] indices8; - delete[] indices16; + delete[] weights; + delete[] indices8; + delete[] indices16; } static std::string GetNodeName(const Node &node) { - return node.name.empty() ? node.id : node.name; + return node.name.empty() ? node.id : node.name; } void ParseExtensions(aiMetadata *metadata, const CustomExtension &extension) { - if (extension.mStringValue.isPresent) { - metadata->Add(extension.name.c_str(), aiString(extension.mStringValue.value)); - } else if (extension.mDoubleValue.isPresent) { - metadata->Add(extension.name.c_str(), extension.mDoubleValue.value); - } else if (extension.mUint64Value.isPresent) { - metadata->Add(extension.name.c_str(), extension.mUint64Value.value); - } else if (extension.mInt64Value.isPresent) { - metadata->Add(extension.name.c_str(), static_cast(extension.mInt64Value.value)); - } else if (extension.mBoolValue.isPresent) { - metadata->Add(extension.name.c_str(), extension.mBoolValue.value); - } else if (extension.mValues.isPresent) { - aiMetadata val; - for (size_t i = 0; i < extension.mValues.value.size(); ++i) { - ParseExtensions(&val, extension.mValues.value[i]); - } - metadata->Add(extension.name.c_str(), val); - } + if (extension.mStringValue.isPresent) { + metadata->Add(extension.name.c_str(), aiString(extension.mStringValue.value)); + } else if (extension.mDoubleValue.isPresent) { + metadata->Add(extension.name.c_str(), extension.mDoubleValue.value); + } else if (extension.mUint64Value.isPresent) { + metadata->Add(extension.name.c_str(), extension.mUint64Value.value); + } else if (extension.mInt64Value.isPresent) { + metadata->Add(extension.name.c_str(), static_cast(extension.mInt64Value.value)); + } else if (extension.mBoolValue.isPresent) { + metadata->Add(extension.name.c_str(), extension.mBoolValue.value); + } else if (extension.mValues.isPresent) { + aiMetadata val; + for (size_t i = 0; i < extension.mValues.value.size(); ++i) { + ParseExtensions(&val, extension.mValues.value[i]); + } + metadata->Add(extension.name.c_str(), val); + } } aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector &meshOffsets, glTF2::Ref &ptr) { - Node &node = *ptr; + Node &node = *ptr; - aiNode *ainode = new aiNode(GetNodeName(node)); + aiNode *ainode = new aiNode(GetNodeName(node)); - if (!node.children.empty()) { - ainode->mNumChildren = unsigned(node.children.size()); - ainode->mChildren = new aiNode *[ainode->mNumChildren]; + if (!node.children.empty()) { + ainode->mNumChildren = unsigned(node.children.size()); + ainode->mChildren = new aiNode *[ainode->mNumChildren]; - for (unsigned int i = 0; i < ainode->mNumChildren; ++i) { - aiNode *child = ImportNode(pScene, r, meshOffsets, node.children[i]); - child->mParent = ainode; - ainode->mChildren[i] = child; - } - } + for (unsigned int i = 0; i < ainode->mNumChildren; ++i) { + aiNode *child = ImportNode(pScene, r, meshOffsets, node.children[i]); + child->mParent = ainode; + ainode->mChildren[i] = child; + } + } - if (node.extensions) { - ainode->mMetaData = new aiMetadata; - ParseExtensions(ainode->mMetaData, node.extensions); - } + if (node.extensions) { + ainode->mMetaData = new aiMetadata; + ParseExtensions(ainode->mMetaData, node.extensions); + } - GetNodeTransform(ainode->mTransformation, node); + GetNodeTransform(ainode->mTransformation, node); - if (!node.meshes.empty()) { - // GLTF files contain at most 1 mesh per node. - assert(node.meshes.size() == 1); - int mesh_idx = node.meshes[0].GetIndex(); - int count = meshOffsets[mesh_idx + 1] - meshOffsets[mesh_idx]; + if (!node.meshes.empty()) { + // GLTF files contain at most 1 mesh per node. + assert(node.meshes.size() == 1); + int mesh_idx = node.meshes[0].GetIndex(); + int count = meshOffsets[mesh_idx + 1] - meshOffsets[mesh_idx]; - ainode->mNumMeshes = count; - ainode->mMeshes = new unsigned int[count]; + ainode->mNumMeshes = count; + ainode->mMeshes = new unsigned int[count]; - if (node.skin) { - for (int primitiveNo = 0; primitiveNo < count; ++primitiveNo) { - aiMesh *mesh = pScene->mMeshes[meshOffsets[mesh_idx] + primitiveNo]; - unsigned int numBones =static_cast(node.skin->jointNames.size()); + if (node.skin) { + for (int primitiveNo = 0; primitiveNo < count; ++primitiveNo) { + aiMesh *mesh = pScene->mMeshes[meshOffsets[mesh_idx] + primitiveNo]; + unsigned int numBones =static_cast(node.skin->jointNames.size()); - std::vector> weighting(numBones); - BuildVertexWeightMapping(node.meshes[0]->primitives[primitiveNo], weighting); + std::vector> weighting(numBones); + BuildVertexWeightMapping(node.meshes[0]->primitives[primitiveNo], weighting); - unsigned int realNumBones = 0; - for (uint32_t i = 0; i < numBones; ++i) { - if (weighting[i].size() > 0) { - realNumBones++; - } - } + mesh->mNumBones = static_cast(numBones); + mesh->mBones = new aiBone *[mesh->mNumBones]; - mesh->mNumBones = static_cast(realNumBones); - mesh->mBones = new aiBone *[mesh->mNumBones]; + // GLTF and Assimp choose to store bone weights differently. + // GLTF has each vertex specify which bones influence the vertex. + // Assimp has each bone specify which vertices it has influence over. + // To convert this data, we first read over the vertex data and pull + // out the bone-to-vertex mapping. Then, when creating the aiBones, + // we copy the bone-to-vertex mapping into the bone. This is unfortunate + // both because it's somewhat slow and because, for many applications, + // we then need to reconvert the data back into the vertex-to-bone + // mapping which makes things doubly-slow. - // GLTF and Assimp choose to store bone weights differently. - // GLTF has each vertex specify which bones influence the vertex. - // Assimp has each bone specify which vertices it has influence over. - // To convert this data, we first read over the vertex data and pull - // out the bone-to-vertex mapping. Then, when creating the aiBones, - // we copy the bone-to-vertex mapping into the bone. This is unfortunate - // both because it's somewhat slow and because, for many applications, - // we then need to reconvert the data back into the vertex-to-bone - // mapping which makes things doubly-slow. + mat4 *pbindMatrices = nullptr; + node.skin->inverseBindMatrices->ExtractData(pbindMatrices); - mat4 *pbindMatrices = nullptr; - node.skin->inverseBindMatrices->ExtractData(pbindMatrices); + for (uint32_t i = 0; i < numBones; ++i) { + const std::vector &weights = weighting[i]; + aiBone *bone = new aiBone(); - int cb = 0; - for (uint32_t i = 0; i < numBones; ++i) { - const std::vector &weights = weighting[i]; - if (weights.size() > 0) { - aiBone *bone = new aiBone(); + Ref joint = node.skin->jointNames[i]; + if (!joint->name.empty()) { + bone->mName = joint->name; + } else { + // Assimp expects each bone to have a unique name. + static const std::string kDefaultName = "bone_"; + char postfix[10] = { 0 }; + ASSIMP_itoa10(postfix, i); + bone->mName = (kDefaultName + postfix); + } + GetNodeTransform(bone->mOffsetMatrix, *joint); + CopyValue(pbindMatrices[i], bone->mOffsetMatrix); + bone->mNumWeights = static_cast(weights.size()); - Ref joint = node.skin->jointNames[i]; - if (!joint->name.empty()) { - bone->mName = joint->name; - } else { - // Assimp expects each bone to have a unique name. - static const std::string kDefaultName = "bone_"; - char postfix[10] = { 0 }; - ASSIMP_itoa10(postfix, i); - bone->mName = (kDefaultName + postfix); - } - GetNodeTransform(bone->mOffsetMatrix, *joint); - CopyValue(pbindMatrices[i], bone->mOffsetMatrix); - bone->mNumWeights = static_cast(weights.size()); - bone->mWeights = new aiVertexWeight[bone->mNumWeights]; - memcpy(bone->mWeights, weights.data(), bone->mNumWeights * sizeof(aiVertexWeight)); - mesh->mBones[cb++] = bone; - } - } + if (bone->mNumWeights > 0) { + bone->mWeights = new aiVertexWeight[bone->mNumWeights]; + memcpy(bone->mWeights, weights.data(), bone->mNumWeights * sizeof(aiVertexWeight)); + } else { + // Assimp expects all bones to have at least 1 weight. + bone->mWeights = new aiVertexWeight[1]; + bone->mNumWeights = 1; + bone->mWeights->mVertexId = 0; + bone->mWeights->mWeight = 0.f; + } + mesh->mBones[i] = bone; + } - if (pbindMatrices) { - delete[] pbindMatrices; - } - } - } + if (pbindMatrices) { + delete[] pbindMatrices; + } + } + } - int k = 0; - for (unsigned int j = meshOffsets[mesh_idx]; j < meshOffsets[mesh_idx + 1]; ++j, ++k) { - ainode->mMeshes[k] = j; - } - } + int k = 0; + for (unsigned int j = meshOffsets[mesh_idx]; j < meshOffsets[mesh_idx + 1]; ++j, ++k) { + ainode->mMeshes[k] = j; + } + } - if (node.camera) { - pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName; - if (node.translation.isPresent) { - aiVector3D trans; - CopyValue(node.translation.value, trans); - pScene->mCameras[node.camera.GetIndex()]->mPosition = trans; - } - } + if (node.camera) { + pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName; + if (node.translation.isPresent) { + aiVector3D trans; + CopyValue(node.translation.value, trans); + pScene->mCameras[node.camera.GetIndex()]->mPosition = trans; + } + } - if (node.light) { - pScene->mLights[node.light.GetIndex()]->mName = ainode->mName; + if (node.light) { + pScene->mLights[node.light.GetIndex()]->mName = ainode->mName; - //range is optional - see https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual - //it is added to meta data of parent node, because there is no other place to put it - if (node.light->range.isPresent) { - if (!ainode->mMetaData) { - ainode->mMetaData = aiMetadata::Alloc(1); - ainode->mMetaData->Set(0, "PBR_LightRange", node.light->range.value); - } - else { - ainode->mMetaData->Add("PBR_LightRange", node.light->range.value); - } - } - } + //range is optional - see https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual + //it is added to meta data of parent node, because there is no other place to put it + if (node.light->range.isPresent) { + if (!ainode->mMetaData) { + ainode->mMetaData = aiMetadata::Alloc(1); + ainode->mMetaData->Set(0, "PBR_LightRange", node.light->range.value); + } + else { + ainode->mMetaData->Add("PBR_LightRange", node.light->range.value); + } + } + } - return ainode; + return ainode; } void glTF2Importer::ImportNodes(glTF2::Asset &r) { - if (!r.scene) { - throw DeadlyImportError("GLTF: No scene"); - } - ASSIMP_LOG_DEBUG("Importing nodes"); + if (!r.scene) { + throw DeadlyImportError("GLTF: No scene"); + } + ASSIMP_LOG_DEBUG("Importing nodes"); - std::vector> rootNodes = r.scene->nodes; + std::vector> rootNodes = r.scene->nodes; - // The root nodes - unsigned int numRootNodes = unsigned(rootNodes.size()); - if (numRootNodes == 1) { // a single root node: use it - mScene->mRootNode = ImportNode(mScene, r, meshOffsets, rootNodes[0]); - } else if (numRootNodes > 1) { // more than one root node: create a fake root - aiNode *root = new aiNode("ROOT"); - root->mChildren = new aiNode *[numRootNodes]; - for (unsigned int i = 0; i < numRootNodes; ++i) { - aiNode *node = ImportNode(mScene, r, meshOffsets, rootNodes[i]); - node->mParent = root; - root->mChildren[root->mNumChildren++] = node; - } - mScene->mRootNode = root; - } else { - mScene->mRootNode = new aiNode("ROOT"); - } + // The root nodes + unsigned int numRootNodes = unsigned(rootNodes.size()); + if (numRootNodes == 1) { // a single root node: use it + mScene->mRootNode = ImportNode(mScene, r, meshOffsets, rootNodes[0]); + } else if (numRootNodes > 1) { // more than one root node: create a fake root + aiNode *root = new aiNode("ROOT"); + root->mChildren = new aiNode *[numRootNodes]; + for (unsigned int i = 0; i < numRootNodes; ++i) { + aiNode *node = ImportNode(mScene, r, meshOffsets, rootNodes[i]); + node->mParent = root; + root->mChildren[root->mNumChildren++] = node; + } + mScene->mRootNode = root; + } else { + mScene->mRootNode = new aiNode("ROOT"); + } } struct AnimationSamplers { - AnimationSamplers() : - translation(nullptr), - rotation(nullptr), - scale(nullptr), - weight(nullptr) { - // empty - } + AnimationSamplers() : + translation(nullptr), + rotation(nullptr), + scale(nullptr), + weight(nullptr) { + // empty + } - Animation::Sampler *translation; - Animation::Sampler *rotation; - Animation::Sampler *scale; - Animation::Sampler *weight; + Animation::Sampler *translation; + Animation::Sampler *rotation; + Animation::Sampler *scale; + Animation::Sampler *weight; }; aiNodeAnim *CreateNodeAnim(glTF2::Asset&, Node &node, AnimationSamplers &samplers) { - aiNodeAnim *anim = new aiNodeAnim(); - anim->mNodeName = GetNodeName(node); + aiNodeAnim *anim = new aiNodeAnim(); + anim->mNodeName = GetNodeName(node); - static const float kMillisecondsFromSeconds = 1000.f; + static const float kMillisecondsFromSeconds = 1000.f; - if (samplers.translation) { - float *times = nullptr; - samplers.translation->input->ExtractData(times); - aiVector3D *values = nullptr; - samplers.translation->output->ExtractData(values); - anim->mNumPositionKeys = static_cast(samplers.translation->input->count); - anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys]; - for (unsigned int i = 0; i < anim->mNumPositionKeys; ++i) { - anim->mPositionKeys[i].mTime = times[i] * kMillisecondsFromSeconds; - anim->mPositionKeys[i].mValue = values[i]; - } - delete[] times; - delete[] values; - } else if (node.translation.isPresent) { - anim->mNumPositionKeys = 1; - anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys]; - anim->mPositionKeys->mTime = 0.f; - anim->mPositionKeys->mValue.x = node.translation.value[0]; - anim->mPositionKeys->mValue.y = node.translation.value[1]; - anim->mPositionKeys->mValue.z = node.translation.value[2]; - } + if (samplers.translation) { + float *times = nullptr; + samplers.translation->input->ExtractData(times); + aiVector3D *values = nullptr; + samplers.translation->output->ExtractData(values); + anim->mNumPositionKeys = static_cast(samplers.translation->input->count); + anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys]; + for (unsigned int i = 0; i < anim->mNumPositionKeys; ++i) { + anim->mPositionKeys[i].mTime = times[i] * kMillisecondsFromSeconds; + anim->mPositionKeys[i].mValue = values[i]; + } + delete[] times; + delete[] values; + } else if (node.translation.isPresent) { + anim->mNumPositionKeys = 1; + anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys]; + anim->mPositionKeys->mTime = 0.f; + anim->mPositionKeys->mValue.x = node.translation.value[0]; + anim->mPositionKeys->mValue.y = node.translation.value[1]; + anim->mPositionKeys->mValue.z = node.translation.value[2]; + } - if (samplers.rotation) { - float *times = nullptr; - samplers.rotation->input->ExtractData(times); - aiQuaternion *values = nullptr; - samplers.rotation->output->ExtractData(values); - anim->mNumRotationKeys = static_cast(samplers.rotation->input->count); - anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys]; - for (unsigned int i = 0; i < anim->mNumRotationKeys; ++i) { - anim->mRotationKeys[i].mTime = times[i] * kMillisecondsFromSeconds; - anim->mRotationKeys[i].mValue.x = values[i].w; - anim->mRotationKeys[i].mValue.y = values[i].x; - anim->mRotationKeys[i].mValue.z = values[i].y; - anim->mRotationKeys[i].mValue.w = values[i].z; - } - delete[] times; - delete[] values; - } else if (node.rotation.isPresent) { - anim->mNumRotationKeys = 1; - anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys]; - anim->mRotationKeys->mTime = 0.f; - anim->mRotationKeys->mValue.x = node.rotation.value[0]; - anim->mRotationKeys->mValue.y = node.rotation.value[1]; - anim->mRotationKeys->mValue.z = node.rotation.value[2]; - anim->mRotationKeys->mValue.w = node.rotation.value[3]; - } + if (samplers.rotation) { + float *times = nullptr; + samplers.rotation->input->ExtractData(times); + aiQuaternion *values = nullptr; + samplers.rotation->output->ExtractData(values); + anim->mNumRotationKeys = static_cast(samplers.rotation->input->count); + anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys]; + for (unsigned int i = 0; i < anim->mNumRotationKeys; ++i) { + anim->mRotationKeys[i].mTime = times[i] * kMillisecondsFromSeconds; + anim->mRotationKeys[i].mValue.x = values[i].w; + anim->mRotationKeys[i].mValue.y = values[i].x; + anim->mRotationKeys[i].mValue.z = values[i].y; + anim->mRotationKeys[i].mValue.w = values[i].z; + } + delete[] times; + delete[] values; + } else if (node.rotation.isPresent) { + anim->mNumRotationKeys = 1; + anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys]; + anim->mRotationKeys->mTime = 0.f; + anim->mRotationKeys->mValue.x = node.rotation.value[0]; + anim->mRotationKeys->mValue.y = node.rotation.value[1]; + anim->mRotationKeys->mValue.z = node.rotation.value[2]; + anim->mRotationKeys->mValue.w = node.rotation.value[3]; + } - if (samplers.scale) { - float *times = nullptr; - samplers.scale->input->ExtractData(times); - aiVector3D *values = nullptr; - samplers.scale->output->ExtractData(values); - anim->mNumScalingKeys = static_cast(samplers.scale->input->count); - anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys]; - for (unsigned int i = 0; i < anim->mNumScalingKeys; ++i) { - anim->mScalingKeys[i].mTime = times[i] * kMillisecondsFromSeconds; - anim->mScalingKeys[i].mValue = values[i]; - } - delete[] times; - delete[] values; - } else if (node.scale.isPresent) { - anim->mNumScalingKeys = 1; - anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys]; - anim->mScalingKeys->mTime = 0.f; - anim->mScalingKeys->mValue.x = node.scale.value[0]; - anim->mScalingKeys->mValue.y = node.scale.value[1]; - anim->mScalingKeys->mValue.z = node.scale.value[2]; - } + if (samplers.scale) { + float *times = nullptr; + samplers.scale->input->ExtractData(times); + aiVector3D *values = nullptr; + samplers.scale->output->ExtractData(values); + anim->mNumScalingKeys = static_cast(samplers.scale->input->count); + anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys]; + for (unsigned int i = 0; i < anim->mNumScalingKeys; ++i) { + anim->mScalingKeys[i].mTime = times[i] * kMillisecondsFromSeconds; + anim->mScalingKeys[i].mValue = values[i]; + } + delete[] times; + delete[] values; + } else if (node.scale.isPresent) { + anim->mNumScalingKeys = 1; + anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys]; + anim->mScalingKeys->mTime = 0.f; + anim->mScalingKeys->mValue.x = node.scale.value[0]; + anim->mScalingKeys->mValue.y = node.scale.value[1]; + anim->mScalingKeys->mValue.z = node.scale.value[2]; + } - return anim; + return anim; } aiMeshMorphAnim *CreateMeshMorphAnim(glTF2::Asset&, Node &node, AnimationSamplers &samplers) { - aiMeshMorphAnim *anim = new aiMeshMorphAnim(); - anim->mName = GetNodeName(node); + aiMeshMorphAnim *anim = new aiMeshMorphAnim(); + anim->mName = GetNodeName(node); - static const float kMillisecondsFromSeconds = 1000.f; + static const float kMillisecondsFromSeconds = 1000.f; - if (nullptr != samplers.weight) { - float *times = nullptr; - samplers.weight->input->ExtractData(times); - float *values = nullptr; - samplers.weight->output->ExtractData(values); - anim->mNumKeys = static_cast(samplers.weight->input->count); + if (nullptr != samplers.weight) { + float *times = nullptr; + samplers.weight->input->ExtractData(times); + float *values = nullptr; + samplers.weight->output->ExtractData(values); + anim->mNumKeys = static_cast(samplers.weight->input->count); - const unsigned int numMorphs = (unsigned int)samplers.weight->output->count / anim->mNumKeys; + const unsigned int numMorphs = (unsigned int)samplers.weight->output->count / anim->mNumKeys; - anim->mKeys = new aiMeshMorphKey[anim->mNumKeys]; - unsigned int k = 0u; - for (unsigned int i = 0u; i < anim->mNumKeys; ++i) { - anim->mKeys[i].mTime = times[i] * kMillisecondsFromSeconds; - anim->mKeys[i].mNumValuesAndWeights = numMorphs; - anim->mKeys[i].mValues = new unsigned int[numMorphs]; - anim->mKeys[i].mWeights = new double[numMorphs]; + anim->mKeys = new aiMeshMorphKey[anim->mNumKeys]; + unsigned int k = 0u; + for (unsigned int i = 0u; i < anim->mNumKeys; ++i) { + anim->mKeys[i].mTime = times[i] * kMillisecondsFromSeconds; + anim->mKeys[i].mNumValuesAndWeights = numMorphs; + anim->mKeys[i].mValues = new unsigned int[numMorphs]; + anim->mKeys[i].mWeights = new double[numMorphs]; - for (unsigned int j = 0u; j < numMorphs; ++j, ++k) { - anim->mKeys[i].mValues[j] = j; - anim->mKeys[i].mWeights[j] = (0.f > values[k]) ? 0.f : values[k]; - } - } + for (unsigned int j = 0u; j < numMorphs; ++j, ++k) { + anim->mKeys[i].mValues[j] = j; + anim->mKeys[i].mWeights[j] = (0.f > values[k]) ? 0.f : values[k]; + } + } - delete[] times; - delete[] values; - } + delete[] times; + delete[] values; + } - return anim; + return anim; } std::unordered_map GatherSamplers(Animation &anim) { - std::unordered_map samplers; - for (unsigned int c = 0; c < anim.channels.size(); ++c) { - Animation::Channel &channel = anim.channels[c]; - if (channel.sampler >= static_cast(anim.samplers.size())) { - continue; - } + std::unordered_map samplers; + for (unsigned int c = 0; c < anim.channels.size(); ++c) { + Animation::Channel &channel = anim.channels[c]; + if (channel.sampler >= static_cast(anim.samplers.size())) { + continue; + } - const unsigned int node_index = channel.target.node.GetIndex(); + const unsigned int node_index = channel.target.node.GetIndex(); - AnimationSamplers &sampler = samplers[node_index]; - if (channel.target.path == AnimationPath_TRANSLATION) { - sampler.translation = &anim.samplers[channel.sampler]; - } else if (channel.target.path == AnimationPath_ROTATION) { - sampler.rotation = &anim.samplers[channel.sampler]; - } else if (channel.target.path == AnimationPath_SCALE) { - sampler.scale = &anim.samplers[channel.sampler]; - } else if (channel.target.path == AnimationPath_WEIGHTS) { - sampler.weight = &anim.samplers[channel.sampler]; - } - } + AnimationSamplers &sampler = samplers[node_index]; + if (channel.target.path == AnimationPath_TRANSLATION) { + sampler.translation = &anim.samplers[channel.sampler]; + } else if (channel.target.path == AnimationPath_ROTATION) { + sampler.rotation = &anim.samplers[channel.sampler]; + } else if (channel.target.path == AnimationPath_SCALE) { + sampler.scale = &anim.samplers[channel.sampler]; + } else if (channel.target.path == AnimationPath_WEIGHTS) { + sampler.weight = &anim.samplers[channel.sampler]; + } + } - return samplers; + return samplers; } void glTF2Importer::ImportAnimations(glTF2::Asset &r) { - if (!r.scene) return; + if (!r.scene) return; const unsigned numAnimations = r.animations.Size(); - ASSIMP_LOG_DEBUG_F("Importing ", numAnimations, " animations"); - mScene->mNumAnimations = numAnimations; - if (mScene->mNumAnimations == 0) { - return; - } + ASSIMP_LOG_DEBUG_F("Importing ", numAnimations, " animations"); + mScene->mNumAnimations = numAnimations; + if (mScene->mNumAnimations == 0) { + return; + } mScene->mAnimations = new aiAnimation *[numAnimations]; - for (unsigned int i = 0; i < numAnimations; ++i) { - Animation &anim = r.animations[i]; + for (unsigned int i = 0; i < numAnimations; ++i) { + Animation &anim = r.animations[i]; - aiAnimation *ai_anim = new aiAnimation(); - ai_anim->mName = anim.name; - ai_anim->mDuration = 0; - ai_anim->mTicksPerSecond = 0; + aiAnimation *ai_anim = new aiAnimation(); + ai_anim->mName = anim.name; + ai_anim->mDuration = 0; + ai_anim->mTicksPerSecond = 0; - std::unordered_map samplers = GatherSamplers(anim); + std::unordered_map samplers = GatherSamplers(anim); - uint32_t numChannels = 0u; - uint32_t numMorphMeshChannels = 0u; + uint32_t numChannels = 0u; + uint32_t numMorphMeshChannels = 0u; - for (auto &iter : samplers) { - if ((nullptr != iter.second.rotation) || (nullptr != iter.second.scale) || (nullptr != iter.second.translation)) { - ++numChannels; - } - if (nullptr != iter.second.weight) { - ++numMorphMeshChannels; - } - } + for (auto &iter : samplers) { + if ((nullptr != iter.second.rotation) || (nullptr != iter.second.scale) || (nullptr != iter.second.translation)) { + ++numChannels; + } + if (nullptr != iter.second.weight) { + ++numMorphMeshChannels; + } + } - ai_anim->mNumChannels = numChannels; - if (ai_anim->mNumChannels > 0) { - ai_anim->mChannels = new aiNodeAnim *[ai_anim->mNumChannels]; - int j = 0; - for (auto &iter : samplers) { - if ((nullptr != iter.second.rotation) || (nullptr != iter.second.scale) || (nullptr != iter.second.translation)) { - ai_anim->mChannels[j] = CreateNodeAnim(r, r.nodes[iter.first], iter.second); - ++j; - } - } - } + ai_anim->mNumChannels = numChannels; + if (ai_anim->mNumChannels > 0) { + ai_anim->mChannels = new aiNodeAnim *[ai_anim->mNumChannels]; + int j = 0; + for (auto &iter : samplers) { + if ((nullptr != iter.second.rotation) || (nullptr != iter.second.scale) || (nullptr != iter.second.translation)) { + ai_anim->mChannels[j] = CreateNodeAnim(r, r.nodes[iter.first], iter.second); + ++j; + } + } + } - ai_anim->mNumMorphMeshChannels = numMorphMeshChannels; - if (ai_anim->mNumMorphMeshChannels > 0) { - ai_anim->mMorphMeshChannels = new aiMeshMorphAnim *[ai_anim->mNumMorphMeshChannels]; - int j = 0; - for (auto &iter : samplers) { - if (nullptr != iter.second.weight) { - ai_anim->mMorphMeshChannels[j] = CreateMeshMorphAnim(r, r.nodes[iter.first], iter.second); - ++j; - } - } - } + ai_anim->mNumMorphMeshChannels = numMorphMeshChannels; + if (ai_anim->mNumMorphMeshChannels > 0) { + ai_anim->mMorphMeshChannels = new aiMeshMorphAnim *[ai_anim->mNumMorphMeshChannels]; + int j = 0; + for (auto &iter : samplers) { + if (nullptr != iter.second.weight) { + ai_anim->mMorphMeshChannels[j] = CreateMeshMorphAnim(r, r.nodes[iter.first], iter.second); + ++j; + } + } + } - // Use the latest keyframe for the duration of the animation - double maxDuration = 0; - unsigned int maxNumberOfKeys = 0; - for (unsigned int j = 0; j < ai_anim->mNumChannels; ++j) { - auto chan = ai_anim->mChannels[j]; - if (chan->mNumPositionKeys) { - auto lastPosKey = chan->mPositionKeys[chan->mNumPositionKeys - 1]; - if (lastPosKey.mTime > maxDuration) { - maxDuration = lastPosKey.mTime; - } - maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumPositionKeys); - } - if (chan->mNumRotationKeys) { - auto lastRotKey = chan->mRotationKeys[chan->mNumRotationKeys - 1]; - if (lastRotKey.mTime > maxDuration) { - maxDuration = lastRotKey.mTime; - } - maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumRotationKeys); - } - if (chan->mNumScalingKeys) { - auto lastScaleKey = chan->mScalingKeys[chan->mNumScalingKeys - 1]; - if (lastScaleKey.mTime > maxDuration) { - maxDuration = lastScaleKey.mTime; - } - maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumScalingKeys); - } - } + // Use the latest keyframe for the duration of the animation + double maxDuration = 0; + unsigned int maxNumberOfKeys = 0; + for (unsigned int j = 0; j < ai_anim->mNumChannels; ++j) { + auto chan = ai_anim->mChannels[j]; + if (chan->mNumPositionKeys) { + auto lastPosKey = chan->mPositionKeys[chan->mNumPositionKeys - 1]; + if (lastPosKey.mTime > maxDuration) { + maxDuration = lastPosKey.mTime; + } + maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumPositionKeys); + } + if (chan->mNumRotationKeys) { + auto lastRotKey = chan->mRotationKeys[chan->mNumRotationKeys - 1]; + if (lastRotKey.mTime > maxDuration) { + maxDuration = lastRotKey.mTime; + } + maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumRotationKeys); + } + if (chan->mNumScalingKeys) { + auto lastScaleKey = chan->mScalingKeys[chan->mNumScalingKeys - 1]; + if (lastScaleKey.mTime > maxDuration) { + maxDuration = lastScaleKey.mTime; + } + maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumScalingKeys); + } + } - for (unsigned int j = 0; j < ai_anim->mNumMorphMeshChannels; ++j) { - const auto *const chan = ai_anim->mMorphMeshChannels[j]; + for (unsigned int j = 0; j < ai_anim->mNumMorphMeshChannels; ++j) { + const auto *const chan = ai_anim->mMorphMeshChannels[j]; - if (0u != chan->mNumKeys) { - const auto &lastKey = chan->mKeys[chan->mNumKeys - 1u]; - if (lastKey.mTime > maxDuration) { - maxDuration = lastKey.mTime; - } - maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumKeys); - } - } + if (0u != chan->mNumKeys) { + const auto &lastKey = chan->mKeys[chan->mNumKeys - 1u]; + if (lastKey.mTime > maxDuration) { + maxDuration = lastKey.mTime; + } + maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumKeys); + } + } - ai_anim->mDuration = maxDuration; - ai_anim->mTicksPerSecond = 1000.0; + ai_anim->mDuration = maxDuration; + ai_anim->mTicksPerSecond = 1000.0; - mScene->mAnimations[i] = ai_anim; - } + mScene->mAnimations[i] = ai_anim; + } } void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset &r) { - embeddedTexIdxs.resize(r.images.Size(), -1); + embeddedTexIdxs.resize(r.images.Size(), -1); - int numEmbeddedTexs = 0; - for (size_t i = 0; i < r.images.Size(); ++i) { - if (r.images[i].HasData()) { - numEmbeddedTexs += 1; - } - } + int numEmbeddedTexs = 0; + for (size_t i = 0; i < r.images.Size(); ++i) { + if (r.images[i].HasData()) { + numEmbeddedTexs += 1; + } + } - if (numEmbeddedTexs == 0) - return; + if (numEmbeddedTexs == 0) + return; - ASSIMP_LOG_DEBUG_F("Importing ", numEmbeddedTexs, " embedded textures"); + ASSIMP_LOG_DEBUG_F("Importing ", numEmbeddedTexs, " embedded textures"); - mScene->mTextures = new aiTexture *[numEmbeddedTexs]; + mScene->mTextures = new aiTexture *[numEmbeddedTexs]; - // Add the embedded textures - for (size_t i = 0; i < r.images.Size(); ++i) { - Image &img = r.images[i]; - if (!img.HasData()) { - continue; - } + // Add the embedded textures + for (size_t i = 0; i < r.images.Size(); ++i) { + Image &img = r.images[i]; + if (!img.HasData()) { + continue; + } - int idx = mScene->mNumTextures++; - embeddedTexIdxs[i] = idx; + int idx = mScene->mNumTextures++; + embeddedTexIdxs[i] = idx; - aiTexture *tex = mScene->mTextures[idx] = new aiTexture(); + aiTexture *tex = mScene->mTextures[idx] = new aiTexture(); - size_t length = img.GetDataLength(); - void *data = img.StealData(); + size_t length = img.GetDataLength(); + void *data = img.StealData(); - tex->mFilename = img.name; - tex->mWidth = static_cast(length); - tex->mHeight = 0; - tex->pcData = reinterpret_cast(data); + tex->mFilename = img.name; + tex->mWidth = static_cast(length); + tex->mHeight = 0; + tex->pcData = reinterpret_cast(data); - if (!img.mimeType.empty()) { - const char *ext = strchr(img.mimeType.c_str(), '/') + 1; - if (ext) { - if (strcmp(ext, "jpeg") == 0) { + if (!img.mimeType.empty()) { + const char *ext = strchr(img.mimeType.c_str(), '/') + 1; + if (ext) { + if (strcmp(ext, "jpeg") == 0) { ext = "jpg"; } - size_t len = strlen(ext); - if (len <= 3) { - strcpy(tex->achFormatHint, ext); - } - } - } - } + size_t len = strlen(ext); + if (len <= 3) { + strcpy(tex->achFormatHint, ext); + } + } + } + } } void glTF2Importer::ImportCommonMetadata(glTF2::Asset& a) { - ASSIMP_LOG_DEBUG("Importing metadata"); + ASSIMP_LOG_DEBUG("Importing metadata"); ai_assert(mScene->mMetaData == nullptr); const bool hasVersion = !a.asset.version.empty(); const bool hasGenerator = !a.asset.generator.empty(); @@ -1378,37 +1377,37 @@ void glTF2Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IO ASSIMP_LOG_DEBUG("Reading GLTF2 file"); - // clean all member arrays - meshOffsets.clear(); - embeddedTexIdxs.clear(); + // clean all member arrays + meshOffsets.clear(); + embeddedTexIdxs.clear(); - this->mScene = pScene; + this->mScene = pScene; - // read the asset file - glTF2::Asset asset(pIOHandler); - asset.Load(pFile, GetExtension(pFile) == "glb"); + // read the asset file + glTF2::Asset asset(pIOHandler); + asset.Load(pFile, GetExtension(pFile) == "glb"); - // - // Copy the data out - // + // + // Copy the data out + // - ImportEmbeddedTextures(asset); - ImportMaterials(asset); + ImportEmbeddedTextures(asset); + ImportMaterials(asset); - ImportMeshes(asset); + ImportMeshes(asset); - ImportCameras(asset); - ImportLights(asset); + ImportCameras(asset); + ImportLights(asset); - ImportNodes(asset); + ImportNodes(asset); - ImportAnimations(asset); + ImportAnimations(asset); ImportCommonMetadata(asset); - if (pScene->mNumMeshes == 0) { - pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; - } + if (pScene->mNumMeshes == 0) { + pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; + } } #endif // ASSIMP_BUILD_NO_GLTF_IMPORTER From 37c09ecb69f7d6acd8c0ddd089e5159450ac8ff7 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 17 Oct 2020 10:58:06 +0200 Subject: [PATCH 10/21] Update CMakeLists.txt --- code/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 7d9b03ce1..5a4e2dafd 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1014,7 +1014,7 @@ ENDIF() # Check dependencies for glTF importer with Open3DGC-compression. # RT-extensions is used in "contrib/Open3DGC/o3dgcTimer.h" for collecting statistics. Pointed file # has implementation for different platforms: WIN32, __MACH__ and other ("else" block). -FIND_PACKAGE(rt QUIET) +FIND_PACKAGE(RT QUIET) IF (NOT ASSIMP_HUNTER_ENABLED AND (RT_FOUND OR MSVC)) SET( ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC 1 ) ADD_DEFINITIONS( -DASSIMP_IMPORTER_GLTF_USE_OPEN3DGC=1 ) From 080322b9e2aa96f4258ecbf4efc58564b7721feb Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 19 Oct 2020 19:06:11 +0200 Subject: [PATCH 11/21] cleanup collada xml migration. --- code/AssetLib/Collada/ColladaHelper.cpp | 3 +- code/AssetLib/Collada/ColladaHelper.h | 228 +++++++++++------------- code/AssetLib/Collada/ColladaLoader.cpp | 19 +- code/AssetLib/Collada/ColladaParser.cpp | 133 +++++++------- code/AssetLib/Collada/ColladaParser.h | 34 ++-- include/assimp/StringUtils.h | 101 ++++++----- include/assimp/XmlParser.h | 12 +- 7 files changed, 256 insertions(+), 274 deletions(-) diff --git a/code/AssetLib/Collada/ColladaHelper.cpp b/code/AssetLib/Collada/ColladaHelper.cpp index 50d70e640..0a779e04e 100644 --- a/code/AssetLib/Collada/ColladaHelper.cpp +++ b/code/AssetLib/Collada/ColladaHelper.cpp @@ -1,5 +1,3 @@ -/** Helper structures for the Collada loader */ - /* Open Asset Import Library (assimp) ---------------------------------------------------------------------- @@ -40,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ +/** Helper structures for the Collada loader */ #include "ColladaHelper.h" diff --git a/code/AssetLib/Collada/ColladaHelper.h b/code/AssetLib/Collada/ColladaHelper.h index bc93203aa..bfd57918e 100644 --- a/code/AssetLib/Collada/ColladaHelper.h +++ b/code/AssetLib/Collada/ColladaHelper.h @@ -1,12 +1,9 @@ -/** Helper structures for the Collada loader */ - /* Open Asset Import Library (assimp) ---------------------------------------------------------------------- Copyright (c) 2006-2020, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -42,12 +39,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ +/** Helper structures for the Collada loader */ + #ifndef AI_COLLADAHELPER_H_INC #define AI_COLLADAHELPER_H_INC #include #include #include + #include #include #include @@ -58,14 +58,14 @@ struct aiMaterial; namespace Assimp { namespace Collada { -/** Collada file versions which evolved during the years ... */ +/// Collada file versions which evolved during the years ... enum FormatVersion { FV_1_5_n, FV_1_4_n, FV_1_3_n }; -/** Transformation types that can be applied to a node */ +/// Transformation types that can be applied to a node enum TransformType { TF_LOOKAT, TF_ROTATE, @@ -75,7 +75,7 @@ enum TransformType { TF_MATRIX }; -/** Different types of input data to a vertex or face */ +/// Different types of input data to a vertex or face enum InputType { IT_Invalid, IT_Vertex, // special type for per-index data referring to the element carrying the per-vertex data. @@ -87,38 +87,39 @@ enum InputType { IT_Bitangent }; -/** Supported controller types */ +/// Supported controller types enum ControllerType { Skin, Morph }; -/** Supported morph methods */ +/// Supported morph methods enum MorphMethod { Normalized, Relative }; -/** Common metadata keys as */ -typedef std::pair MetaKeyPair; -typedef std::vector MetaKeyPairVector; +/// Common metadata keys as +using MetaKeyPair = std::pair; +using MetaKeyPairVector = std::vector; -// Collada as lower_case (native) +/// Collada as lower_case (native) const MetaKeyPairVector &GetColladaAssimpMetaKeys(); + // Collada as CamelCase (used by Assimp for consistency) const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase(); -/** Convert underscore_separated to CamelCase "authoring_tool" becomes "AuthoringTool" */ +/// Convert underscore_separated to CamelCase "authoring_tool" becomes "AuthoringTool" void ToCamelCase(std::string &text); -/** Contains all data for one of the different transformation types */ +/// Contains all data for one of the different transformation types struct Transform { std::string mID; ///< SID of the transform step, by which anim channels address their target node TransformType mType; ai_real f[16]; ///< Interpretation of data depends on the type of the transformation }; -/** A collada camera. */ +/// A collada camera. struct Camera { Camera() : mOrtho(false), @@ -128,22 +129,22 @@ struct Camera { mZNear(0.1f), mZFar(1000.f) {} - // Name of camera + /// Name of camera std::string mName; - // True if it is an orthografic camera + /// True if it is an orthographic camera bool mOrtho; - //! Horizontal field of view in degrees + /// Horizontal field of view in degrees ai_real mHorFov; - //! Vertical field of view in degrees + /// Vertical field of view in degrees ai_real mVerFov; - //! Screen aspect + /// Screen aspect ai_real mAspect; - //! Near& far z + /// Near& far z ai_real mZNear, mZFar; }; @@ -162,27 +163,27 @@ struct Light { mOuterAngle(ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET), mIntensity(1.f) {} - //! Type of the light source aiLightSourceType + ambient + /// Type of the light source aiLightSourceType + ambient unsigned int mType; - //! Color of the light + /// Color of the light aiColor3D mColor; - //! Light attenuation + /// Light attenuation ai_real mAttConstant, mAttLinear, mAttQuadratic; - //! Spot light falloff + /// Spot light falloff ai_real mFalloffAngle; ai_real mFalloffExponent; // ----------------------------------------------------- // FCOLLADA extension from here - //! ... related stuff from maja and max extensions + /// ... related stuff from maja and max extensions ai_real mPenumbraAngle; ai_real mOuterAngle; - //! Common light intensity + /// Common light intensity ai_real mIntensity; }; @@ -192,30 +193,29 @@ struct InputSemanticMapEntry { mSet(0), mType(IT_Invalid) {} - //! Index of set, optional + /// Index of set, optional unsigned int mSet; - //! Type of referenced vertex input + /// Type of referenced vertex input InputType mType; }; -/** Table to map from effect to vertex input semantics */ +/// Table to map from effect to vertex input semantics struct SemanticMappingTable { - //! Name of material + /// Name of material std::string mMatName; - //! List of semantic map commands, grouped by effect semantic name + /// List of semantic map commands, grouped by effect semantic name std::map mMap; - //! For std::find + /// For std::find bool operator==(const std::string &s) const { return s == mMatName; } }; -/** A reference to a mesh inside a node, including materials assigned to the various subgroups. - * The ID refers to either a mesh or a controller which specifies the mesh - */ +/// A reference to a mesh inside a node, including materials assigned to the various subgroups. +/// The ID refers to either a mesh or a controller which specifies the mesh struct MeshInstance { ///< ID of the mesh or controller to be instanced std::string mMeshOrController; @@ -224,25 +224,25 @@ struct MeshInstance { std::map mMaterials; }; -/** A reference to a camera inside a node*/ +/// A reference to a camera inside a node struct CameraInstance { ///< ID of the camera std::string mCamera; }; -/** A reference to a light inside a node*/ +/// A reference to a light inside a node struct LightInstance { ///< ID of the camera std::string mLight; }; -/** A reference to a node inside a node*/ +/// A reference to a node inside a node struct NodeInstance { ///< ID of the node std::string mNode; }; -/** A node in a scene hierarchy */ +/// A node in a scene hierarchy struct Node { std::string mName; std::string mID; @@ -250,52 +250,53 @@ struct Node { Node *mParent; std::vector mChildren; - /** Operations in order to calculate the resulting transformation to parent. */ + /// Operations in order to calculate the resulting transformation to parent. std::vector mTransforms; - /** Meshes at this node */ + /// Meshes at this node std::vector mMeshes; - /** Lights at this node */ + /// Lights at this node std::vector mLights; - /** Cameras at this node */ + /// Cameras at this node std::vector mCameras; - /** Node instances at this node */ + /// Node instances at this node std::vector mNodeInstances; - /** Root-nodes: Name of primary camera, if any */ + /// Root-nodes: Name of primary camera, if any std::string mPrimaryCamera; - //! Constructor. Begin with a zero parent + /// Constructor. Begin with a zero parent Node() : mParent(nullptr) { // empty } - //! Destructor: delete all children subsequently + /// Destructor: delete all children subsequently ~Node() { - for (std::vector::iterator it = mChildren.begin(); it != mChildren.end(); ++it) + for (std::vector::iterator it = mChildren.begin(); it != mChildren.end(); ++it) { delete *it; + } } }; -/** Data source array: either floats or strings */ +/// Data source array: either floats or strings struct Data { bool mIsStringArray; std::vector mValues; std::vector mStrings; }; -/** Accessor to a data array */ +/// Accessor to a data array struct Accessor { size_t mCount; // in number of objects size_t mSize; // size of an object, in elements (floats or strings, mostly 1) size_t mOffset; // in number of values size_t mStride; // Stride in number of values std::vector mParams; // names of the data streams in the accessors. Empty string tells to ignore. - size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on. + size_t mSubOffset[4]; // Sub-offset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on. // For example, SubOffset[0] denotes which of the values inside the object is the vector X component. std::string mSource; // URL of the source array mutable const Data *mData; // Pointer to the source array, if resolved. nullptr else @@ -310,12 +311,12 @@ struct Accessor { } }; -/** A single face in a mesh */ +/// A single face in a mesh struct Face { std::vector mIndices; }; -/** An input channel for mesh data, referring to a single accessor */ +/// An input channel for mesh data, referring to a single accessor struct InputChannel { InputType mType; // Type of the data size_t mIndex; // Optional index, if multiple sets of the same data type are given @@ -331,18 +332,19 @@ struct InputChannel { } }; -/** Subset of a mesh with a certain material */ +/// Subset of a mesh with a certain material struct SubMesh { std::string mMaterial; ///< subgroup identifier - size_t mNumFaces; ///< number of faces in this submesh + size_t mNumFaces; ///< number of faces in this sub-mesh }; -/** Contains data for a single mesh */ +/// Contains data for a single mesh struct Mesh { Mesh(const std::string &id) : mId(id) { - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) + for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { mNumUVComponents[i] = 2; + } } const std::string mId; @@ -373,11 +375,11 @@ struct Mesh { // necessary for bone weight assignment std::vector mFacePosIndices; - // Submeshes in this mesh, each with a given material + // Sub-meshes in this mesh, each with a given material std::vector mSubMeshes; }; -/** Which type of primitives the ReadPrimitives() function is going to read */ +/// Which type of primitives the ReadPrimitives() function is going to read enum PrimitiveType { Prim_Invalid, Prim_Lines, @@ -389,7 +391,7 @@ enum PrimitiveType { Prim_Polygon }; -/** A skeleton controller to deform a mesh with the use of joints */ +/// A skeleton controller to deform a mesh with the use of joints struct Controller { // controller type ControllerType mType; @@ -424,25 +426,25 @@ struct Controller { std::string mMorphWeight; }; -/** A collada material. Pretty much the only member is a reference to an effect. */ +/// A collada material. Pretty much the only member is a reference to an effect. struct Material { std::string mName; std::string mEffect; }; -/** Type of the effect param */ +/// Type of the effect param enum ParamType { Param_Sampler, Param_Surface }; -/** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */ +/// A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them struct EffectParam { ParamType mType; std::string mReference; // to which other thing the param is referring to. }; -/** Shading type supported by the standard effect spec of Collada */ +/// Shading type supported by the standard effect spec of Collada enum ShadeType { Shade_Invalid, Shade_Constant, @@ -451,7 +453,7 @@ enum ShadeType { Shade_Blinn }; -/** Represents a texture sampler in collada */ +/// Represents a texture sampler in collada struct Sampler { Sampler() : mWrapU(true), @@ -463,77 +465,66 @@ struct Sampler { mWeighting(1.f), mMixWithPrevious(1.f) {} - /** Name of image reference - */ + /// Name of image reference std::string mName; - /** Wrap U? - */ + /// Wrap U? bool mWrapU; - /** Wrap V? - */ + /// Wrap V? bool mWrapV; - /** Mirror U? - */ + /// Mirror U? bool mMirrorU; - /** Mirror V? - */ + /// Mirror V? bool mMirrorV; - /** Blend mode - */ + /// Blend mode aiTextureOp mOp; - /** UV transformation - */ + /// UV transformation aiUVTransform mTransform; - /** Name of source UV channel - */ + /// Name of source UV channel std::string mUVChannel; - /** Resolved UV channel index or UINT_MAX if not known - */ + /// Resolved UV channel index or UINT_MAX if not known unsigned int mUVId; // OKINO/MAX3D extensions from here // ------------------------------------------------------- - /** Weighting factor - */ + /// Weighting factor ai_real mWeighting; - /** Mixing factor from OKINO - */ + /// Mixing factor from OKINO ai_real mMixWithPrevious; }; -/** A collada effect. Can contain about anything according to the Collada spec, - but we limit our version to a reasonable subset. */ +/// A collada effect. Can contain about anything according to the Collada spec, +/// but we limit our version to a reasonable subset. struct Effect { - // Shading mode + /// Shading mode ShadeType mShadeType; - // Colors + /// Colors aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular, mTransparent, mReflective; - // Textures + /// Textures Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular, mTexTransparent, mTexBump, mTexReflective; - // Scalar factory + /// Scalar factory ai_real mShininess, mRefractIndex, mReflectivity; ai_real mTransparency; bool mHasTransparency; bool mRGBTransparency; bool mInvertTransparency; - // local params referring to each other by their SID - typedef std::map ParamLibrary; + /// local params referring to each other by their SID + using ParamLibrary = std::map; ParamLibrary mParams; // MAX3D extensions @@ -561,65 +552,64 @@ struct Effect { } }; -/** An image, meaning texture */ +/// An image, meaning texture struct Image { std::string mFileName; - /** Embedded image data */ + /// Embedded image data std::vector mImageData; - /** File format hint of embedded image data */ + /// File format hint of embedded image data std::string mEmbeddedFormat; }; -/** An animation channel. */ +/// An animation channel. struct AnimationChannel { - /** URL of the data to animate. Could be about anything, but we support only the - * "NodeID/TransformID.SubElement" notation - */ + /// URL of the data to animate. Could be about anything, but we support only the + /// "NodeID/TransformID.SubElement" notation std::string mTarget; - /** Source URL of the time values. Collada calls them "input". Meh. */ + /// Source URL of the time values. Collada calls them "input". Meh. std::string mSourceTimes; - /** Source URL of the value values. Collada calls them "output". */ + /// Source URL of the value values. Collada calls them "output". std::string mSourceValues; - /** Source URL of the IN_TANGENT semantic values. */ + /// Source URL of the IN_TANGENT semantic values. std::string mInTanValues; - /** Source URL of the OUT_TANGENT semantic values. */ + /// Source URL of the OUT_TANGENT semantic values. std::string mOutTanValues; - /** Source URL of the INTERPOLATION semantic values. */ + /// Source URL of the INTERPOLATION semantic values. std::string mInterpolationValues; }; -/** An animation. Container for 0-x animation channels or 0-x animations */ +/// An animation. Container for 0-x animation channels or 0-x animations struct Animation { - /** Anim name */ + /// Anim name std::string mName; - /** the animation channels, if any */ + /// the animation channels, if any std::vector mChannels; - /** the sub-animations, if any */ + /// the sub-animations, if any std::vector mSubAnims; - /** Destructor */ + /// Destructor ~Animation() { - for (std::vector::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) + for (std::vector::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) { delete *it; + } } - /** Collect all channels in the animation hierarchy into a single channel list. */ + /// Collect all channels in the animation hierarchy into a single channel list. void CollectChannelsRecursively(std::vector &channels) { channels.insert(channels.end(), mChannels.begin(), mChannels.end()); for (std::vector::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) { Animation *pAnim = (*it); - pAnim->CollectChannelsRecursively(channels); } } - /** Combine all single-channel animations' channel into the same (parent) animation channel list. */ + /// Combine all single-channel animations' channel into the same (parent) animation channel list. void CombineSingleChannelAnimations() { CombineSingleChannelAnimationsRecursively(this); } @@ -658,9 +648,9 @@ struct Animation { } }; -/** Description of a collada animation channel which has been determined to affect the current node */ +/// Description of a collada animation channel which has been determined to affect the current node struct ChannelEntry { - const Collada::AnimationChannel *mChannel; ///> the source channel + const Collada::AnimationChannel *mChannel; ///< the source channel std::string mTargetId; std::string mTransformId; // the ID of the transformation step of the node which is influenced size_t mTransformIndex; // Index into the node's transform chain to apply the channel to diff --git a/code/AssetLib/Collada/ColladaLoader.cpp b/code/AssetLib/Collada/ColladaLoader.cpp index 4beaf8431..99cb8c305 100644 --- a/code/AssetLib/Collada/ColladaLoader.cpp +++ b/code/AssetLib/Collada/ColladaLoader.cpp @@ -55,12 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include -#include -#include #include #include -#include + #include namespace Assimp { @@ -331,13 +328,15 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Col // Resolve UV channels void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler, const Collada::SemanticMappingTable &table) { std::map::const_iterator it = table.mMap.find(sampler.mUVChannel); - if (it != table.mMap.end()) { - if (it->second.mType != Collada::IT_Texcoord) { - ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping"); - } - - sampler.mUVId = it->second.mSet; + if (it == table.mMap.end()) { + return; } + + if (it->second.mType != Collada::IT_Texcoord) { + ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping"); + } + + sampler.mUVId = it->second.mSet; } // ------------------------------------------------------------------------------------------------ diff --git a/code/AssetLib/Collada/ColladaParser.cpp b/code/AssetLib/Collada/ColladaParser.cpp index c5ca97b89..70f1f80f7 100644 --- a/code/AssetLib/Collada/ColladaParser.cpp +++ b/code/AssetLib/Collada/ColladaParser.cpp @@ -48,7 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ColladaParser.h" #include #include -#include #include #include #include @@ -56,14 +55,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#include -#include -#include - using namespace Assimp; using namespace Assimp::Collada; using namespace Assimp::Formatter; +static void ReportWarning(const char *msg, ...) { + ai_assert(nullptr != msg); + + va_list args; + va_start(args, msg); + + char szBuffer[3000]; + const int iLen = vsprintf(szBuffer, msg, args); + ai_assert(iLen > 0); + + va_end(args); + ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer, iLen)); +} + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) : @@ -301,11 +310,8 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) { for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { const std::string name = currentNode.name(); if (name == "unit") { - pugi::xml_attribute attr = currentNode.attribute("meter"); mUnitSize = 1.f; - if (attr) { - mUnitSize = static_cast(attr.as_double()); - } + XmlParser::getFloatAttribute(node, "meter", mUnitSize); } else if (name == "up_axis") { std::string v; XmlParser::getValueAsString(currentNode, v); @@ -349,20 +355,22 @@ void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) { } std::string v; - if (XmlParser::getValueAsString(node, v)) { - trim(v); - aiString aistr; - aistr.Set(v); + if (!XmlParser::getValueAsString(node, v)) { + return; + } - std::string camel_key_str(name); - ToCamelCase(camel_key_str); + trim(v); + aiString aistr; + aistr.Set(v); - size_t found_index; - if (FindCommonKey(camel_key_str, key_renaming, found_index)) { - metadata.emplace(key_renaming[found_index].second, aistr); - } else { - metadata.emplace(camel_key_str, aistr); - } + std::string camel_key_str(name); + ToCamelCase(camel_key_str); + + size_t found_index; + if (FindCommonKey(camel_key_str, key_renaming, found_index)) { + metadata.emplace(key_renaming[found_index].second, aistr); + } else { + metadata.emplace(camel_key_str, aistr); } } @@ -469,7 +477,7 @@ void ColladaParser::ReadAnimationLibrary(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string currentName = currentNode.name(); if (currentName == "animation") { ReadAnimation(currentNode, &mAnims); @@ -506,7 +514,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) { animID = idAttr.as_string(); } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string currentName = currentNode.name(); if (currentName == "animation") { if (!anim) { @@ -563,7 +571,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) { // ------------------------------------------------------------------------------------------------ // Reads an animation sampler into the given anim channel void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) { - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string currentName = currentNode.name(); if (currentName == "input") { if (XmlParser::hasAttribute(currentNode, "semantic")) { @@ -618,7 +626,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll // initial values pController.mType = Skin; pController.mMethod = Normalized; - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "morph") { pController.mType = Morph; @@ -670,7 +678,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll // ------------------------------------------------------------------------------------------------ // Reads the joint definitions for the given controller void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pController) { - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string currentName = currentNode.name(); if (currentName == "input") { const char *attrSemantic = currentNode.attribute("semantic").as_string(); @@ -698,7 +706,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC int vertexCount=0; XmlParser::getIntAttribute(node, "count", vertexCount); - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { std::string currentName = currentNode.name(); if (currentName == "input") { InputChannel channel; @@ -763,9 +771,9 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string name = currentNode.name(); - if (name == "image") { + for (XmlNode currentNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == "image") { std::string id = currentNode.attribute("id").as_string(); mImageLibrary[id] = Image(); @@ -778,7 +786,7 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) { // ------------------------------------------------------------------------------------------------ // Reads an image entry into the given image void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) { - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string currentName = currentNode.name(); if (currentName == "image") { // Ignore @@ -861,8 +869,7 @@ void ColladaParser::ReadMaterialLibrary(XmlNode &node) { } std::map names; - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string currentName = currentNode.name(); + for (XmlNode currentNode : node.children()) { std::string id = currentNode.attribute("id").as_string(); std::string name = currentNode.attribute("name").as_string(); mMaterialLibrary[id] = Material(); @@ -891,7 +898,7 @@ void ColladaParser::ReadLightLibrary(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "light") { std::string id = currentNode.attribute("id").as_string(); @@ -907,7 +914,7 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "camera") { std::string id = currentNode.attribute("id").as_string(); @@ -1032,7 +1039,7 @@ void ColladaParser::ReadEffectLibrary(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "effect") { // read ID. Do I have to repeat my ranting about "optional" attributes? @@ -1051,7 +1058,7 @@ void ColladaParser::ReadEffectLibrary(XmlNode &node) { // ------------------------------------------------------------------------------------------------ // Reads an effect entry into the given effect void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) { - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "profile_COMMON") { ReadEffectProfileCommon(currentNode, pEffect); @@ -1330,7 +1337,7 @@ void ColladaParser::ReadGeometryLibrary(XmlNode &node) { if (node.empty()) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "geometry") { // read ID. Another entry which is "optional" by design but obligatory in reality @@ -1359,7 +1366,7 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) { if (node.empty()) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "mesh") { ReadMesh(currentNode, pMesh); @@ -1383,7 +1390,9 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) { ReadSource(currentNode); } else if (currentName == "vertices") { ReadVertexData(currentNode, pMesh); - } else if (currentName == "triangles" || currentName == "lines" || currentName == "linestrips" || currentName == "polygons" || currentName == "polylist" || currentName == "trifans" || currentName == "tristrips") { + } else if (currentName == "triangles" || currentName == "lines" || currentName == "linestrips" || + currentName == "polygons" || currentName == "polylist" || currentName == "trifans" || + currentName == "tristrips") { ReadIndexData(currentNode, pMesh); } } @@ -1575,7 +1584,7 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) { void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) { // extract the ID of the element. Not that we care, but to catch strange referencing schemes we should warn about XmlParser::getStdStrAttribute(node, "id", pMesh.mVertexID); - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "input") { ReadInputChannel(currentNode, pMesh.mPerVertexData); @@ -1733,20 +1742,20 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector 0); - - va_end(args); - ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer, iLen)); -} - // ------------------------------------------------------------------------------------------------ // Calculates the resulting transformation from all the given transform steps aiMatrix4x4 ColladaParser::CalculateResultTransform(const std::vector &pTransforms) const { diff --git a/code/AssetLib/Collada/ColladaParser.h b/code/AssetLib/Collada/ColladaParser.h index 4b26b179c..5b8526b47 100644 --- a/code/AssetLib/Collada/ColladaParser.h +++ b/code/AssetLib/Collada/ColladaParser.h @@ -243,8 +243,6 @@ protected: void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive); protected: - void ReportWarning(const char *msg, ...); - /** Calculates the resulting transformation from all the given transform steps */ aiMatrix4x4 CalculateResultTransform(const std::vector &pTransforms) const; @@ -260,56 +258,55 @@ protected: std::string mFileName; // XML reader, member for everyday use - //irr::io::IrrXMLReader *mReader; XmlParser mXmlParser; /** All data arrays found in the file by ID. Might be referred to by actually everyone. Collada, you are a steaming pile of indirection. */ - typedef std::map DataLibrary; + using DataLibrary = std::map ; DataLibrary mDataLibrary; /** Same for accessors which define how the data in a data array is accessed. */ - typedef std::map AccessorLibrary; + using AccessorLibrary = std::map ; AccessorLibrary mAccessorLibrary; /** Mesh library: mesh by ID */ - typedef std::map MeshLibrary; + using MeshLibrary = std::map; MeshLibrary mMeshLibrary; /** node library: root node of the hierarchy part by ID */ - typedef std::map NodeLibrary; + using NodeLibrary = std::map; NodeLibrary mNodeLibrary; /** Image library: stores texture properties by ID */ - typedef std::map ImageLibrary; + using ImageLibrary = std::map ; ImageLibrary mImageLibrary; /** Effect library: surface attributes by ID */ - typedef std::map EffectLibrary; + using EffectLibrary = std::map ; EffectLibrary mEffectLibrary; /** Material library: surface material by ID */ - typedef std::map MaterialLibrary; + using MaterialLibrary = std::map ; MaterialLibrary mMaterialLibrary; /** Light library: surface light by ID */ - typedef std::map LightLibrary; + using LightLibrary = std::map ; LightLibrary mLightLibrary; /** Camera library: surface material by ID */ - typedef std::map CameraLibrary; + using CameraLibrary = std::map ; CameraLibrary mCameraLibrary; /** Controller library: joint controllers by ID */ - typedef std::map ControllerLibrary; + using ControllerLibrary = std::map ; ControllerLibrary mControllerLibrary; /** Animation library: animation references by ID */ - typedef std::map AnimationLibrary; + using AnimationLibrary = std::map ; AnimationLibrary mAnimationLibrary; /** Animation clip library: clip animation references by ID */ - typedef std::vector>> AnimationClipLibrary; + using AnimationClipLibrary = std::vector>> ; AnimationClipLibrary mAnimationClipLibrary; /** Pointer to the root node. Don't delete, it just points to one of @@ -334,13 +331,6 @@ protected: Collada::FormatVersion mFormat; }; -// ------------------------------------------------------------------------------------------------ -// Check for element match -/*inline bool ColladaParser::IsElement(const char *pName) const { - ai_assert(mReader->getNodeType() == irr::io::EXN_ELEMENT); - return ::strcmp(mReader->getNodeName(), pName) == 0; -}*/ - // ------------------------------------------------------------------------------------------------ // Finds the item in the given library by its reference, throws if not found template diff --git a/include/assimp/StringUtils.h b/include/assimp/StringUtils.h index 3abf4ca20..21942eed4 100644 --- a/include/assimp/StringUtils.h +++ b/include/assimp/StringUtils.h @@ -44,22 +44,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define INCLUDED_AI_STRINGUTILS_H #ifdef __GNUC__ -# pragma GCC system_header +#pragma GCC system_header #endif #include -#include #include -#include -#include +#include #include +#include #include +#include #ifdef _MSC_VER -# define AI_SIZEFMT "%Iu" +#define AI_SIZEFMT "%Iu" #else -# define AI_SIZEFMT "%zu" +#define AI_SIZEFMT "%zu" #endif /// @fn ai_snprintf @@ -71,35 +71,35 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /// @return The number of written characters if the buffer size was big enough. If an encoding error occurs, a negative number is returned. #if defined(_MSC_VER) && _MSC_VER < 1900 - AI_FORCE_INLINE - int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) { - int count(-1); - if (0 != size) { - count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); - } - if (count == -1) { - count = _vscprintf(format, ap); - } +AI_FORCE_INLINE +int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) { + int count(-1); + if (0 != size) { + count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); + } + if (count == -1) { + count = _vscprintf(format, ap); + } - return count; - } + return count; +} - AI_FORCE_INLINE - int ai_snprintf(char *outBuf, size_t size, const char *format, ...) { - int count; - va_list ap; +AI_FORCE_INLINE +int ai_snprintf(char *outBuf, size_t size, const char *format, ...) { + int count; + va_list ap; - va_start(ap, format); - count = c99_ai_vsnprintf(outBuf, size, format, ap); - va_end(ap); + va_start(ap, format); + count = c99_ai_vsnprintf(outBuf, size, format, ap); + va_end(ap); - return count; - } + return count; +} #elif defined(__MINGW32__) -# define ai_snprintf __mingw_snprintf +#define ai_snprintf __mingw_snprintf #else -# define ai_snprintf snprintf +#define ai_snprintf snprintf #endif /// @fn to_string @@ -107,8 +107,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /// @param value The value to write into the std::string. /// @return The value as a std::string template -AI_FORCE_INLINE -std::string to_string( T value ) { +AI_FORCE_INLINE std::string to_string(T value) { std::ostringstream os; os << value; @@ -121,17 +120,17 @@ std::string to_string( T value ) { /// @param end The last character /// @return The float value, 0.0f in cas of an error. AI_FORCE_INLINE -float ai_strtof( const char *begin, const char *end ) { - if ( nullptr == begin ) { +float ai_strtof(const char *begin, const char *end) { + if (nullptr == begin) { return 0.0f; } - float val( 0.0f ); - if ( nullptr == end ) { - val = static_cast< float >( ::atof( begin ) ); + float val(0.0f); + if (nullptr == end) { + val = static_cast(::atof(begin)); } else { - std::string::size_type len( end - begin ); - std::string token( begin, len ); - val = static_cast< float >( ::atof( token.c_str() ) ); + std::string::size_type len(end - begin); + std::string token(begin, len); + val = static_cast(::atof(token.c_str())); } return val; @@ -141,16 +140,15 @@ float ai_strtof( const char *begin, const char *end ) { /// @brief The portable to convert a decimal value into a hexadecimal string. /// @param toConvert Value to convert /// @return The hexadecimal string, is empty in case of an error. -template -AI_FORCE_INLINE -std::string DecimalToHexa( T toConvert ) { +template +AI_FORCE_INLINE std::string DecimalToHexa(T toConvert) { std::string result; std::stringstream ss; ss << std::hex << toConvert; ss >> result; - for ( size_t i = 0; i < result.size(); ++i ) { - result[ i ] = (char) toupper( result[ i ] ); + for (size_t i = 0; i < result.size(); ++i) { + result[i] = (char)toupper(result[i]); } return result; @@ -164,31 +162,32 @@ std::string DecimalToHexa( T toConvert ) { /// @param with_head # /// @return The hexadecimal string, is empty in case of an error. AI_FORCE_INLINE std::string Rgba2Hex(int r, int g, int b, int a, bool with_head) { - std::stringstream ss; - if (with_head) { - ss << "#"; + std::stringstream ss; + if (with_head) { + ss << "#"; } - ss << std::hex << (r << 24 | g << 16 | b << 8 | a); + ss << std::hex << (r << 24 | g << 16 | b << 8 | a); return ss.str(); } // trim from start (in place) -inline void ltrim(std::string &s) { +AI_FORCE_INLINE void ltrim(std::string &s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); })); } // trim from end (in place) -inline void rtrim(std::string &s) { +AI_FORCE_INLINE void rtrim(std::string &s) { s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); - }).base(), s.end()); + }).base(), + s.end()); } // trim from both ends (in place) -inline void trim(std::string &s) { +AI_FORCE_INLINE void trim(std::string &s) { ltrim(s); rtrim(s); } diff --git a/include/assimp/XmlParser.h b/include/assimp/XmlParser.h index 9dca314de..3d430a278 100644 --- a/include/assimp/XmlParser.h +++ b/include/assimp/XmlParser.h @@ -179,7 +179,7 @@ public: return true; } - static inline bool getFloatAttribute( XmlNode &xmlNode, const char *name, float &val ) { + static inline bool getFloatAttribute(XmlNode &xmlNode, const char *name, float &val ) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { return false; @@ -190,6 +190,16 @@ public: } + static inline bool getDoubleAttribute( XmlNode &xmlNode, const char *name, double &val ) { + pugi::xml_attribute attr = xmlNode.attribute(name); + if (attr.empty()) { + return false; + } + + val = attr.as_double(); + return true; + } + static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { From 69143ed14939b1345b798dd95bf15d9dc02277f4 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 19 Oct 2020 23:53:27 +0200 Subject: [PATCH 12/21] fix unittests. --- code/AssetLib/Collada/ColladaParser.cpp | 252 +++++++++++------------- 1 file changed, 113 insertions(+), 139 deletions(-) diff --git a/code/AssetLib/Collada/ColladaParser.cpp b/code/AssetLib/Collada/ColladaParser.cpp index 70f1f80f7..d84f76340 100644 --- a/code/AssetLib/Collada/ColladaParser.cpp +++ b/code/AssetLib/Collada/ColladaParser.cpp @@ -73,6 +73,29 @@ static void ReportWarning(const char *msg, ...) { ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer, iLen)); } +static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) { + for (size_t i = 0; i < key_renaming.size(); ++i) { + if (key_renaming[i].first == collada_key) { + found_index = i; + return true; + } + } + found_index = std::numeric_limits::max(); + + return false; +} + +static void readUrlAttribute(XmlNode &node, std::string &url) { + url.clear(); + if (!XmlParser::getStdStrAttribute(node, "url", url)) { + return; + } + if (url[0] != '#') { + throw DeadlyImportError("Unknown reference format"); + } + url = url.c_str() + 1; +} + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) : @@ -265,35 +288,35 @@ void ColladaParser::ReadContents(XmlNode &node) { // ------------------------------------------------------------------------------------------------ // Reads the structure of the file void ColladaParser::ReadStructure(XmlNode &node) { - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string name = std::string(currentNode.name()); - ASSIMP_LOG_DEBUG("last name" + name); - if (name == "asset") + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = std::string(currentNode.name()); + if (currentName == "asset") { ReadAssetInfo(currentNode); - else if (name == "library_animations") + } else if (currentName == "library_animations") { ReadAnimationLibrary(currentNode); - else if (name == "library_animation_clips") + } else if (currentName == "library_animation_clips") { ReadAnimationClipLibrary(currentNode); - else if (name == "library_controllers") + } else if (currentName == "library_controllers") { ReadControllerLibrary(currentNode); - else if (name == "library_images") + } else if (currentName == "library_images") { ReadImageLibrary(currentNode); - else if (name == "library_materials") + } else if (currentName == "library_materials") { ReadMaterialLibrary(currentNode); - else if (name == "library_effects") + } else if (currentName == "library_effects") { ReadEffectLibrary(currentNode); - else if (name == "library_geometries") + } else if (currentName == "library_geometries") { ReadGeometryLibrary(currentNode); - else if (name == "library_visual_scenes") + } else if (currentName == "library_visual_scenes") { ReadSceneLibrary(currentNode); - else if (name == "library_lights") + } else if (currentName == "library_lights") { ReadLightLibrary(currentNode); - else if (name == "library_cameras") + } else if (currentName == "library_cameras") { ReadCameraLibrary(currentNode); - else if (name == "library_nodes") + } else if (currentName == "library_nodes") { ReadSceneNode(currentNode, nullptr); /* some hacking to reuse this piece of code */ - else if (name == "scene") + } else if (currentName == "scene") { ReadScene(currentNode); + } } PostProcessRootAnimations(); @@ -307,14 +330,16 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string name = currentNode.name(); - if (name == "unit") { + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == "unit") { mUnitSize = 1.f; XmlParser::getFloatAttribute(node, "meter", mUnitSize); - } else if (name == "up_axis") { + } else if (currentName == "up_axis") { std::string v; - XmlParser::getValueAsString(currentNode, v); + if (!XmlParser::getValueAsString(currentNode, v)) { + continue; + } if (v == "X_UP") { mUpDirection = UP_X; } else if (v == "Z_UP") { @@ -322,9 +347,9 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) { } else { mUpDirection = UP_Y; } - } else if (name == "contributor") { - for (XmlNode currentChldNode : currentNode.children()) { - ReadMetaDataItem(currentChldNode, mAssetMetaData); + } else if (currentName == "contributor") { + for (XmlNode currentChildNode : currentNode.children()) { + ReadMetaDataItem(currentChildNode, mAssetMetaData); } } else { ReadMetaDataItem(currentNode, mAssetMetaData); @@ -332,23 +357,10 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) { } } -static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) { - for (size_t i = 0; i < key_renaming.size(); ++i) { - if (key_renaming[i].first == collada_key) { - found_index = i; - return true; - } - } - found_index = std::numeric_limits::max(); - - return false; -} - // ------------------------------------------------------------------------------------------------ // Reads a single string metadata item void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) { const Collada::MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase(); - const std::string name = node.name(); if (name.empty()) { return; @@ -382,14 +394,8 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) { } std::string animName; - pugi::xml_attribute nameAttr = node.attribute("name"); - if (nameAttr) { - animName = nameAttr.as_string(); - } else { - pugi::xml_attribute idAttr = node.attribute("id"); - if (idAttr) { - animName = idAttr.as_string(); - } else { + if (!XmlParser::getStdStrAttribute(node, "name", animName)) { + if (!XmlParser::getStdStrAttribute( node, "id", animName )) { animName = std::string("animation_") + to_string(mAnimationClipLibrary.size()); } } @@ -397,17 +403,12 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) { std::pair> clip; clip.first = animName; - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string currentName = currentNode.name(); + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); if (currentName == "instance_animation") { - pugi::xml_attribute url = currentNode.attribute("url"); - if (url) { - const std::string urlName = url.as_string(); - if (urlName[0] != '#') { - throw DeadlyImportError("Unknown reference format"); - } - clip.second.push_back(url.as_string()); - } + std::string url; + readUrlAttribute(node, url); + clip.second.push_back(url); } if (clip.second.size() > 0) { @@ -477,8 +478,8 @@ void ColladaParser::ReadAnimationLibrary(XmlNode &node) { return; } - for (XmlNode currentNode : node.children()) { - const std::string currentName = currentNode.name(); + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); if (currentName == "animation") { ReadAnimation(currentNode, &mAnims); } @@ -494,17 +495,14 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) { // an element may be a container for grouping sub-elements or an animation channel // this is the channel collection by ID, in case it has channels - typedef std::map ChannelMap; + using ChannelMap = std::map ; ChannelMap channels; // this is the anim container in case we're a container Animation *anim = nullptr; // optional name given as an attribute std::string animName; - pugi::xml_attribute nameAttr = node.attribute("name"); - if (nameAttr) { - animName = nameAttr.as_string(); - } else { + if (!XmlParser::getStdStrAttribute(node, "name", animName)) { animName = "animation"; } @@ -514,8 +512,8 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) { animID = idAttr.as_string(); } - for (XmlNode currentNode : node.children()) { - const std::string currentName = currentNode.name(); + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); if (currentName == "animation") { if (!anim) { anim = new Animation; @@ -528,23 +526,21 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) { } else if (currentName == "source") { ReadSource(currentNode); } else if (currentName == "sampler") { - pugi::xml_attribute sampler_id = currentNode.attribute("id"); - if (sampler_id) { - std::string id = sampler_id.as_string(); - ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first; - + std::string id; + if (XmlParser::getStdStrAttribute(currentNode, "id", id)) { // have it read into a channel + ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first; ReadAnimationSampler(currentNode, newChannel->second); } else if (currentName == "channel") { - pugi::xml_attribute target = currentNode.attribute("target"); - pugi::xml_attribute source = currentNode.attribute("source"); - std::string source_name = source.as_string(); + std::string source_name, target; + XmlParser::getStdStrAttribute(currentNode, "source", source_name); + XmlParser::getStdStrAttribute(currentNode, "target", target); if (source_name[0] == '#') { source_name = source_name.substr(1, source_name.size() - 1); } ChannelMap::iterator cit = channels.find(source_name); if (cit != channels.end()) { - cit->second.mTarget = target.as_string(); + cit->second.mTarget = target; } } } @@ -571,8 +567,8 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) { // ------------------------------------------------------------------------------------------------ // Reads an animation sampler into the given anim channel void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) { - for (XmlNode currentNode : node.children()) { - const std::string currentName = currentNode.name(); + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); if (currentName == "input") { if (XmlParser::hasAttribute(currentNode, "semantic")) { std::string semantic, sourceAttr; @@ -585,16 +581,17 @@ void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChanne } source++; - if (semantic == "INPUT") + if (semantic == "INPUT") { pChannel.mSourceTimes = source; - else if (semantic == "OUTPUT") + } else if (semantic == "OUTPUT") { pChannel.mSourceValues = source; - else if (semantic == "IN_TANGENT") + } else if (semantic == "IN_TANGENT") { pChannel.mInTanValues = source; - else if (semantic == "OUT_TANGENT") + } else if (semantic == "OUT_TANGENT") { pChannel.mOutTanValues = source; - else if (semantic == "INTERPOLATION") + } else if (semantic == "INTERPOLATION") { pChannel.mInterpolationValues = source; + } } } } @@ -612,7 +609,6 @@ void ColladaParser::ReadControllerLibrary(XmlNode &node) { const std::string ¤tName = currentNode.name(); if (currentName != "controller") { continue; - ; } std::string id = node.attribute("id").as_string(); mControllerLibrary[id] = Controller(); @@ -626,7 +622,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll // initial values pController.mType = Skin; pController.mMethod = Normalized; - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "morph") { pController.mType = Morph; @@ -678,8 +674,8 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll // ------------------------------------------------------------------------------------------------ // Reads the joint definitions for the given controller void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pController) { - for (XmlNode currentNode : node.children()) { - const std::string currentName = currentNode.name(); + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); if (currentName == "input") { const char *attrSemantic = currentNode.attribute("semantic").as_string(); const char *attrSource = currentNode.attribute("source").as_string(); @@ -706,8 +702,8 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC int vertexCount=0; XmlParser::getIntAttribute(node, "count", vertexCount); - for (XmlNode currentNode : node.children()) { - std::string currentName = currentNode.name(); + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); if (currentName == "input") { InputChannel channel; @@ -771,7 +767,7 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) { return; } - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "image") { std::string id = currentNode.attribute("id").as_string(); @@ -786,7 +782,7 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) { // ------------------------------------------------------------------------------------------------ // Reads an image entry into the given image void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) { - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string currentName = currentNode.name(); if (currentName == "image") { // Ignore @@ -806,23 +802,6 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) { if (!pImage.mFileName.length()) { pImage.mFileName = "unknown_texture"; } - } else if (mFormat == FV_1_5_n) { - // make sure we skip over mip and array initializations, which - // we don't support, but which could confuse the loader if - // they're not skipped. - //int v = currentNode.attribute("ref").as_int(); - /* if (v y) { - ASSIMP_LOG_WARN("Collada: Ignoring texture array index"); - continue; - }*/ - - //v = currentNode.attribute("mip_index").as_int(); - /*if (attrib != -1 && v > 0) { - ASSIMP_LOG_WARN("Collada: Ignoring MIP map layer"); - continue; - }*/ - - // TODO: correctly jump over cube and volume maps? } } else if (mFormat == FV_1_5_n) { std::string value; @@ -869,7 +848,7 @@ void ColladaParser::ReadMaterialLibrary(XmlNode &node) { } std::map names; - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { std::string id = currentNode.attribute("id").as_string(); std::string name = currentNode.attribute("name").as_string(); mMaterialLibrary[id] = Material(); @@ -898,11 +877,13 @@ void ColladaParser::ReadLightLibrary(XmlNode &node) { return; } - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "light") { - std::string id = currentNode.attribute("id").as_string(); - ReadLight(currentNode, mLightLibrary[id] = Light()); + std::string id; + if (XmlParser::getStdStrAttribute(currentNode, "id", id)) { + ReadLight(currentNode, mLightLibrary[id] = Light()); + } } } } @@ -914,18 +895,24 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) { return; } - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "camera") { - std::string id = currentNode.attribute("id").as_string(); + std::string id; + if (!XmlParser::getStdStrAttribute(currentNode, "id", id)) { + continue; + } // create an entry and store it in the library under its ID Camera &cam = mCameraLibrary[id]; - std::string name = currentNode.attribute("name").as_string(); + std::string name; + if (!XmlParser::getStdStrAttribute(currentNode, "name", name)) { + continue; + } if (!name.empty()) { cam.mName = name; } - ReadCamera(currentNode, cam); + ReadCamera(currentNode, cam); } } } @@ -933,14 +920,12 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) { // ------------------------------------------------------------------------------------------------ // Reads a material entry into the given material void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) { - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "instance_effect") { - const char *url = currentNode.attribute("url").as_string(); - if (url[0] != '#') { - throw DeadlyImportError("Unknown reference format"); - } - pMaterial.mEffect = url + 1; + std::string url; + readUrlAttribute(currentNode, url); + pMaterial.mEffect = url.c_str(); } } } @@ -1039,7 +1024,7 @@ void ColladaParser::ReadEffectLibrary(XmlNode &node) { return; } - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "effect") { // read ID. Do I have to repeat my ranting about "optional" attributes? @@ -1058,7 +1043,7 @@ void ColladaParser::ReadEffectLibrary(XmlNode &node) { // ------------------------------------------------------------------------------------------------ // Reads an effect entry into the given effect void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) { - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "profile_COMMON") { ReadEffectProfileCommon(currentNode, pEffect); @@ -1263,8 +1248,6 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p } else if (currentName == "technique") { std::string profile; XmlParser::getStdStrAttribute(currentNode, "profile", profile); - //const int _profile = GetAttribute("profile"); - //const char *profile = mReader->getAttributeValue(_profile); // Some extensions are quite useful ... ReadSamplerProperties processes // several extensions in MAYA, OKINO and MAX3D profiles. @@ -1337,7 +1320,7 @@ void ColladaParser::ReadGeometryLibrary(XmlNode &node) { if (node.empty()) { return; } - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "geometry") { // read ID. Another entry which is "optional" by design but obligatory in reality @@ -1366,7 +1349,7 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) { if (node.empty()) { return; } - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "mesh") { ReadMesh(currentNode, pMesh); @@ -1550,16 +1533,11 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) { acc.mSubOffset[1] = acc.mParams.size(); else if (name == "P") acc.mSubOffset[2] = acc.mParams.size(); - // else if( name == "Q") acc.mSubOffset[3] = acc.mParams.size(); - /* 4D uv coordinates are not supported in Assimp */ - /* Generic extra data, interpreted as UV data, too*/ else if (name == "U") acc.mSubOffset[0] = acc.mParams.size(); else if (name == "V") acc.mSubOffset[1] = acc.mParams.size(); - //else - // DefaultLogger::get()->warn( format() << "Unknown accessor parameter \"" << name << "\". Ignoring data channel." ); } if (XmlParser::hasAttribute(currentNode, "type")) { // read data type @@ -1584,7 +1562,7 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) { void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) { // extract the ID of the element. Not that we care, but to catch strange referencing schemes we should warn about XmlParser::getStdStrAttribute(node, "id", pMesh.mVertexID); - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "input") { ReadInputChannel(currentNode, pMesh.mPerVertexData); @@ -1787,7 +1765,6 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector element."); } - } else if (expectedPointCount == 0 && (indices.size() % numOffsets) != 0) { throw DeadlyImportError("Expected different index count in

element."); } @@ -2039,7 +2016,7 @@ void ColladaParser::ReadSceneLibrary(XmlNode &node) { return; } - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "visual_scene") { // read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then? @@ -2206,11 +2183,8 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform // ------------------------------------------------------------------------------------------------ // Processes bind_vertex_input and bind elements void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl) { - //XmlNodeIterator xmlIt(node); - //xmlIt.collectChildrenPreOrder(node); - //XmlNode currentNode; std::string name = node.name(); - for (XmlNode currentNode : node.children()) { + for (XmlNode ¤tNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "bind_vertex_input") { Collada::InputSemanticMapEntry vn; @@ -2305,8 +2279,8 @@ void ColladaParser::ReadScene(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string currentName = currentNode.name(); + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); if (currentName == "instance_visual_scene") { // should be the first and only occurrence if (mRootNode) { From f96698a6d25525bbc6ccb343c42af65787e7392a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 21 Oct 2020 16:39:19 +0200 Subject: [PATCH 13/21] Update FUNDING.yml --- .github/FUNDING.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 84e3123fe..e0c2bec9e 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,2 @@ patreon: assimp custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4 -open_collective: assimp From 7781fe5781dd8de2632192df17c7d31898bf8947 Mon Sep 17 00:00:00 2001 From: #Momo <40578274+MomoDeve@users.noreply.github.com> Date: Wed, 21 Oct 2020 23:21:50 +0300 Subject: [PATCH 14/21] MSVC crash workaround I do not know why, but the following line causes crash if assimp was compiled using MSVC with RelWithDebInfo configuration: `std::transform(shading.begin(), shading.end(), shading.begin(), Assimp::ToLower);` replacing `shading.begin()` with `shading.data()` fixes this issue. --- code/AssetLib/FBX/FBXMaterial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/FBX/FBXMaterial.cpp b/code/AssetLib/FBX/FBXMaterial.cpp index 9679e62a5..6296b2a56 100644 --- a/code/AssetLib/FBX/FBXMaterial.cpp +++ b/code/AssetLib/FBX/FBXMaterial.cpp @@ -86,7 +86,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con std::string templateName; // lower-case shading because Blender (for example) writes "Phong" - std::transform(shading.begin(), shading.end(), shading.begin(), Assimp::ToLower); + std::transform(shading.data(), shading.data() + shading.size(), shading.data(), Assimp::ToLower); if(shading == "phong") { templateName = "Material.FbxSurfacePhong"; } From b168d8f441e71e110f0e2c00202ccaf76851a1d9 Mon Sep 17 00:00:00 2001 From: #Momo <40578274+MomoDeve@users.noreply.github.com> Date: Wed, 21 Oct 2020 23:41:33 +0300 Subject: [PATCH 15/21] replaced data with taking address of first element oops, seems like `data()` returns `char*` only since C++17. Replaced with taking address of first string element --- code/AssetLib/FBX/FBXMaterial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/FBX/FBXMaterial.cpp b/code/AssetLib/FBX/FBXMaterial.cpp index 6296b2a56..9fe4ce5be 100644 --- a/code/AssetLib/FBX/FBXMaterial.cpp +++ b/code/AssetLib/FBX/FBXMaterial.cpp @@ -86,7 +86,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con std::string templateName; // lower-case shading because Blender (for example) writes "Phong" - std::transform(shading.data(), shading.data() + shading.size(), shading.data(), Assimp::ToLower); + std::transform(shading.data(), shading.data() + shading.size(), std::addressof(shading[0]), Assimp::ToLower); if(shading == "phong") { templateName = "Material.FbxSurfacePhong"; } From 4006bb71f4b37cbaaddb02bae95de6607a7cee15 Mon Sep 17 00:00:00 2001 From: Max Vollmer Date: Fri, 23 Oct 2020 12:01:43 +0100 Subject: [PATCH 16/21] Fixes for crashes in GLTF2 Importer --- code/AssetLib/glTF2/glTF2Asset.inl | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl index 67f33d74a..badf60f5c 100644 --- a/code/AssetLib/glTF2/glTF2Asset.inl +++ b/code/AssetLib/glTF2/glTF2Asset.inl @@ -554,6 +554,16 @@ inline void BufferView::Read(Value &obj, Asset &r) { byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0)); byteLength = MemberOrDefault(obj, "byteLength", size_t(0)); byteStride = MemberOrDefault(obj, "byteStride", 0u); + + // Check length + if ((byteOffset + byteLength) > buffer->byteLength) { + const uint8_t val_size = 64; + + char val[val_size]; + + ai_snprintf(val, val_size, "%llu, %llu", (unsigned long long)byteOffset, (unsigned long long)byteLength); + throw DeadlyImportError("GLTF: Buffer view with offset/length (", val, ") is out of range."); + } } inline uint8_t *BufferView::GetPointer(size_t accOffset) { @@ -627,6 +637,17 @@ inline void Accessor::Read(Value &obj, Asset &r) { const char *typestr; type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR; + // Check length + unsigned long long byteLength = (unsigned long long)GetBytesPerComponent() * (unsigned long long)count; + if ((byteOffset + byteLength) > bufferView->byteLength || (bufferView->byteOffset + byteOffset + byteLength) > bufferView->buffer->byteLength) { + const uint8_t val_size = 64; + + char val[val_size]; + + ai_snprintf(val, val_size, "%llu, %llu", (unsigned long long)byteOffset, (unsigned long long)byteLength); + throw DeadlyImportError("GLTF: Accessor with offset/length (", val, ") is out of range."); + } + if (Value *sparseValue = FindObject(obj, "sparse")) { sparse.reset(new Sparse); // count @@ -1115,7 +1136,10 @@ inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) { Mesh::AccessorList *vec = 0; if (GetAttribVector(prim, attr, vec, undPos)) { size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0; - if ((*vec).size() <= idx) (*vec).resize(idx + 1); + if ((*vec).size() != idx) { + throw DeadlyImportError("GLTF: Invalid attribute: ", attr, ". All indices for indexed attribute semantics must start with 0 and be continuous positive integers: TEXCOORD_0, TEXCOORD_1, etc."); + } + (*vec).resize(idx + 1); (*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint()); } } From 57e691e28eb773467ccaa0ffdb4c73261cea4d23 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 25 Oct 2020 10:34:43 +0100 Subject: [PATCH 17/21] openddl: latest greatest. --- code/AssetLib/Blender/BlenderDNA.cpp | 1 - code/AssetLib/Blender/BlenderDNA.h | 13 +- code/AssetLib/Blender/BlenderLoader.h | 43 +- code/AssetLib/Blender/BlenderScene.h | 7 +- code/Common/Version.cpp | 6 +- contrib/CMakeLists.txt | 169 +++ contrib/openddlparser/CMakeLists.txt | 24 +- contrib/openddlparser/code/DDLNode.cpp | 144 +-- contrib/openddlparser/code/OpenDDLCommon.cpp | 144 ++- contrib/openddlparser/code/OpenDDLExport.cpp | 340 +++--- contrib/openddlparser/code/OpenDDLParser.cpp | 986 +++++++++--------- contrib/openddlparser/code/OpenDDLStream.cpp | 30 +- contrib/openddlparser/code/Value.cpp | 390 ++++--- .../include/openddlparser/DDLNode.h | 38 +- .../include/openddlparser/OpenDDLCommon.h | 149 ++- .../include/openddlparser/OpenDDLExport.h | 26 +- .../include/openddlparser/OpenDDLParser.h | 106 +- .../openddlparser/OpenDDLParserUtils.h | 450 ++++++-- .../include/openddlparser/OpenDDLStream.h | 8 +- .../include/openddlparser/TPoolAllocator.h | 226 ++++ .../include/openddlparser/Value.h | 4 +- 21 files changed, 1940 insertions(+), 1364 deletions(-) create mode 100644 contrib/openddlparser/include/openddlparser/TPoolAllocator.h diff --git a/code/AssetLib/Blender/BlenderDNA.cpp b/code/AssetLib/Blender/BlenderDNA.cpp index ad0760914..cd9bce66f 100644 --- a/code/AssetLib/Blender/BlenderDNA.cpp +++ b/code/AssetLib/Blender/BlenderDNA.cpp @@ -139,7 +139,6 @@ void DNAParser::Parse() { 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); diff --git a/code/AssetLib/Blender/BlenderDNA.h b/code/AssetLib/Blender/BlenderDNA.h index a084dbdbd..25322a374 100644 --- a/code/AssetLib/Blender/BlenderDNA.h +++ b/code/AssetLib/Blender/BlenderDNA.h @@ -83,10 +83,9 @@ class ObjectCache; * ancestry. */ // ------------------------------------------------------------------------------- struct Error : DeadlyImportError { - template - explicit Error(T&&... args) - : DeadlyImportError(args...) - { + template + explicit Error(T &&...args) : + DeadlyImportError(args...) { } }; @@ -187,7 +186,7 @@ struct Field { }; // ------------------------------------------------------------------------------- -/** Range of possible behaviours for fields absend in the input file. Some are +/** 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. */ // ------------------------------------------------------------------------------- @@ -395,7 +394,7 @@ private: // -------------------------------------------------------- template <> -struct Structure ::_defaultInitializer { +struct Structure::_defaultInitializer { template void operator()(T &out, const char *reason = "") { @@ -407,7 +406,7 @@ struct Structure ::_defaultInitializer { }; template <> -struct Structure ::_defaultInitializer { +struct Structure::_defaultInitializer { template void operator()(T & /*out*/, const char * = "") { diff --git a/code/AssetLib/Blender/BlenderLoader.h b/code/AssetLib/Blender/BlenderLoader.h index 8110ac946..15a7ea6f0 100644 --- a/code/AssetLib/Blender/BlenderLoader.h +++ b/code/AssetLib/Blender/BlenderLoader.h @@ -106,51 +106,18 @@ class BlenderImporter : public BaseImporter, public LogFunctions& app); - - // -------------------- void SetupProperties(const Importer* pImp); - - // -------------------- - void InternReadFile( const std::string& pFile, - aiScene* pScene, - IOSystem* pIOHandler - ); - - // -------------------- - void ParseBlendFile(Blender::FileDatabase& out, - std::shared_ptr stream - ); - - // -------------------- - void ExtractScene(Blender::Scene& out, - const Blender::FileDatabase& file - ); - - // -------------------- - void ConvertBlendFile(aiScene* out, - const Blender::Scene& in, - const Blender::FileDatabase& file - ); + void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); + void ParseBlendFile(Blender::FileDatabase& out, std::shared_ptr stream); + void ExtractScene(Blender::Scene& out, const Blender::FileDatabase& file); + void ConvertBlendFile(aiScene* out, const Blender::Scene& in, const Blender::FileDatabase& file); private: - - // -------------------- aiNode* ConvertNode(const Blender::Scene& in, const Blender::Object* obj, Blender::ConversionData& conv_info, diff --git a/code/AssetLib/Blender/BlenderScene.h b/code/AssetLib/Blender/BlenderScene.h index 980dde6e0..19d19ed01 100644 --- a/code/AssetLib/Blender/BlenderScene.h +++ b/code/AssetLib/Blender/BlenderScene.h @@ -155,7 +155,7 @@ struct World : ElemBase { // ------------------------------------------------------------------------------- struct MVert : ElemBase { float co[3] FAIL; - float no[3] FAIL; // readed as short and divided through / 32767.f + float no[3] FAIL; // read as short and divided through / 32767.f char flag; int mat_nr WARN; int bweight; @@ -228,7 +228,10 @@ struct TFace : ElemBase { // ------------------------------------------------------------------------------- struct MTFace : ElemBase { MTFace() : - flag(0), mode(0), tile(0), unwrap(0) { + flag(0), + mode(0), + tile(0), + unwrap(0) { } float uv[4][2] FAIL; diff --git a/code/Common/Version.cpp b/code/Common/Version.cpp index b040ab729..439e9aac7 100644 --- a/code/Common/Version.cpp +++ b/code/Common/Version.cpp @@ -40,7 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- */ -// Actually just a dummy, used by the compiler to build the precompiled header. +// Actually just a dummy, used by the compiler to build the pre-compiled header. #include "ScenePrivate.h" #include @@ -51,13 +51,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -------------------------------------------------------------------------------- // Legal information string - don't remove this. static const char *LEGAL_INFORMATION = - "Open Asset Import Library (Assimp).\n" "A free C/C++ library to import various 3D file formats into applications\n\n" - "(c) 2006-2020, assimp team\n" "License under the terms and conditions of the 3-clause BSD license\n" - "http://assimp.org\n"; + "https://www.assimp.org\n"; // ------------------------------------------------------------------------------------------------ // Get legal string diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 8b1378917..6a38acf5f 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -1 +1,170 @@ +CMAKE_MINIMUM_REQUIRED( VERSION 2.6 ) +PROJECT( OpenDDL-Parser ) +SET ( OPENDDL_PARSER_VERSION_MAJOR 0 ) +SET ( OPENDDL_PARSER_VERSION_MINOR 1 ) +SET ( OPENDDL_PARSER_VERSION_PATCH 0 ) +SET ( OPENDDL_PARSER_VERSION ${OPENDDL_PARSER_VERSION_MAJOR}.${OPENDDL_PARSER_VERSION_MINOR}.${OPENDDL_PARSER_VERSION_PATCH} ) +SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" ) +option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF ) +option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON ) +option( COVERALLS "Generate coveralls data" OFF ) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) + find_package(Threads) +else() + add_definitions( -D_CRT_SECURE_NO_WARNINGS ) +endif() + +if ( DDL_STATIC_LIBRARY ) + add_definitions( -DOPENDDL_STATIC_LIBARY ) +endif() + +if (MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING") + add_definitions(-DGTEST_HAS_TR1_TUPLE=0) +endif() + +add_definitions( -DOPENDDLPARSER_BUILD ) +add_definitions( -D_VARIADIC_MAX=10 ) +add_definitions( -DGTEST_HAS_PTHREAD=0 ) +if ( DDL_DEBUG_OUTPUT ) + add_definitions( -DDDL_DEBUG_HEADER_NAME) +endif() + +INCLUDE_DIRECTORIES( + ./ + include/ + contrib/gtest-1.7.0/include + contrib/gtest-1.7.0/ +) + +link_directories( + ${CMAKE_HOME_DIRECTORY}/lib +) + +SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake ) +SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) +SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) +SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin ) + +if( WIN32 AND NOT CYGWIN ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc" ) # Force to always compile with W4 + if( CMAKE_CXX_FLAGS MATCHES "/W[0-4]" ) + string( REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" ) + else() + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4" ) + endif() +elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) + # Update if necessary + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS}") +elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS} -Wwrite-strings") +endif() + +if (COVERALLS) + include(Coveralls) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") +endif() + +# Include the doc component. +FIND_PACKAGE( doxygen ) +IF ( DOXYGEN_FOUND ) + CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY ) + ADD_CUSTOM_TARGET( doc ALL ${DOXYGEN_EXECUTABLE} doc/doxygenfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen" VERBATIM ) +ENDIF ( DOXYGEN_FOUND ) + +SET ( openddl_parser_src + code/OpenDDLCommon.cpp + code/OpenDDLExport.cpp + code/OpenDDLParser.cpp + code/OpenDDLStream.cpp + code/DDLNode.cpp + code/Value.cpp + include/openddlparser/OpenDDLCommon.h + include/openddlparser/OpenDDLExport.h + include/openddlparser/OpenDDLParser.h + include/openddlparser/OpenDDLParserUtils.h + include/openddlparser/OpenDDLStream.h + include/openddlparser/DDLNode.h + include/openddlparser/Value.h + include/openddlparser/TPoolAllocator.h + README.md +) + +SOURCE_GROUP( code FILES ${openddl_parser_src} ) + +if ( DDL_STATIC_LIBRARY ) + ADD_LIBRARY( openddl_parser STATIC + ${openddl_parser_src} + ) +else() + ADD_LIBRARY( openddl_parser SHARED + ${openddl_parser_src} + ) +endif() + +SET ( GTEST_PATH contrib/gtest-1.7.0 ) + +SET ( gtest_src + ${GTEST_PATH}/src/gtest-death-test.cc + ${GTEST_PATH}/src/gtest-filepath.cc + ${GTEST_PATH}/src/gtest-internal-inl.h + ${GTEST_PATH}/src/gtest-port.cc + ${GTEST_PATH}/src/gtest-printers.cc + ${GTEST_PATH}/src/gtest-test-part.cc + ${GTEST_PATH}/src/gtest-typed-test.cc + ${GTEST_PATH}/src/gtest.cc +) + +SET( openddl_parser_unittest_src + test/UnitTestCommon.h + test/DDLNodeTest.cpp + test/OpenDDLCommonTest.cpp + test/OpenDDLExportTest.cpp + test/OpenDDLParserTest.cpp + test/OpenDDLParserUtilsTest.cpp + test/OpenDDLStreamTest.cpp + test/OpenDDLIntegrationTest.cpp + test/ValueTest.cpp + test/OpenDDLDefectsTest.cpp + test/OssFuzzTest.cpp + test/main.cpp +) +add_definitions(-DOPENDDL_TEST_DATA="${CMAKE_CURRENT_LIST_DIR}/test/TestData") + +SOURCE_GROUP( code FILES ${openddl_parser_unittest_src} ) +SOURCE_GROUP( gtest FILES ${gtest_src} ) + +ADD_EXECUTABLE( openddl_parser_unittest + ${gtest_src} + ${openddl_parser_unittest_src} +) + +target_link_libraries( openddl_parser_unittest openddl_parser ${CMAKE_THREAD_LIBS_INIT} ) + +SET( openddl_parser_demo_src + demo/main.cpp +) + +if (COVERALLS) + set(COVERAGE_SRCS ${gtest_src} ${openddl_parser_unittest_src} ) + + # Create the coveralls target. + coveralls_setup( + "${COVERAGE_SRCS}" # The source files. + ON # If we should upload. + "${PROJECT_SOURCE_DIR}/cmake/") # (Optional) Alternate project cmake module path. +endif() + +ADD_EXECUTABLE( openddl_parser_demo + ${openddl_parser_demo_src} +) + +target_link_libraries( openddl_parser_demo openddl_parser ) diff --git a/contrib/openddlparser/CMakeLists.txt b/contrib/openddlparser/CMakeLists.txt index 9e903ca3f..6a38acf5f 100644 --- a/contrib/openddlparser/CMakeLists.txt +++ b/contrib/openddlparser/CMakeLists.txt @@ -6,20 +6,12 @@ SET ( OPENDDL_PARSER_VERSION_PATCH 0 ) SET ( OPENDDL_PARSER_VERSION ${OPENDDL_PARSER_VERSION_MAJOR}.${OPENDDL_PARSER_VERSION_MINOR}.${OPENDDL_PARSER_VERSION_PATCH} ) SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" ) -option( DDL_USE_CPP11 "Set to ON to use C++11 features ( always on on windows )." ON ) option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF ) option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON ) option( COVERALLS "Generate coveralls data" OFF ) -if ( DDL_USE_CPP11 ) - if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) - set( OPENDDL_CXXFLAGS -std=c++0x ) - elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set( OPENDDL_CXXFLAGS --std=c++11 ) - endif() -else( DDL_USE_CPP11 ) - add_definitions( -DOPENDDL_NO_USE_CPP11 ) -endif( DDL_USE_CPP11) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) find_package(Threads) @@ -31,6 +23,11 @@ if ( DDL_STATIC_LIBRARY ) add_definitions( -DOPENDDL_STATIC_LIBARY ) endif() +if (MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING") + add_definitions(-DGTEST_HAS_TR1_TUPLE=0) +endif() + add_definitions( -DOPENDDLPARSER_BUILD ) add_definitions( -D_VARIADIC_MAX=10 ) add_definitions( -DGTEST_HAS_PTHREAD=0 ) @@ -49,7 +46,7 @@ link_directories( ${CMAKE_HOME_DIRECTORY}/lib ) -set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake ) +SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake ) SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin ) @@ -97,6 +94,7 @@ SET ( openddl_parser_src include/openddlparser/OpenDDLStream.h include/openddlparser/DDLNode.h include/openddlparser/Value.h + include/openddlparser/TPoolAllocator.h README.md ) @@ -123,7 +121,6 @@ SET ( gtest_src ${GTEST_PATH}/src/gtest-test-part.cc ${GTEST_PATH}/src/gtest-typed-test.cc ${GTEST_PATH}/src/gtest.cc - ${GTEST_PATH}/src/gtest_main.cc ) SET( openddl_parser_unittest_src @@ -137,7 +134,10 @@ SET( openddl_parser_unittest_src test/OpenDDLIntegrationTest.cpp test/ValueTest.cpp test/OpenDDLDefectsTest.cpp + test/OssFuzzTest.cpp + test/main.cpp ) +add_definitions(-DOPENDDL_TEST_DATA="${CMAKE_CURRENT_LIST_DIR}/test/TestData") SOURCE_GROUP( code FILES ${openddl_parser_unittest_src} ) SOURCE_GROUP( gtest FILES ${gtest_src} ) diff --git a/contrib/openddlparser/code/DDLNode.cpp b/contrib/openddlparser/code/DDLNode.cpp index a7c557fc5..724c5d67b 100644 --- a/contrib/openddlparser/code/DDLNode.cpp +++ b/contrib/openddlparser/code/DDLNode.cpp @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -----------------------------------------------------------------------------------------------*/ #include #include +#include #include @@ -29,77 +30,76 @@ BEGIN_ODDLPARSER_NS DDLNode::DllNodeList DDLNode::s_allocatedNodes; -template -inline -static void releaseDataType( T *ptr ) { - if( ddl_nullptr == ptr ) { +template +inline static void releaseDataType(T *ptr) { + if (nullptr == ptr) { return; } - T *current( ddl_nullptr ); - while( ptr ) { + T *current(nullptr); + while (ptr) { current = ptr; ptr = ptr->m_next; delete current; } } -static void releaseReferencedNames( Reference *ref ) { - if( ddl_nullptr == ref ) { +static void releaseReferencedNames(Reference *ref) { + if (nullptr == ref) { return; } delete ref; } -DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent ) -: m_type( type ) -, m_name( name ) -, m_parent( parent ) -, m_children() -, m_properties( ddl_nullptr ) -, m_value( ddl_nullptr ) -, m_dtArrayList( ddl_nullptr ) -, m_references( ddl_nullptr ) -, m_idx( idx ) { - if( m_parent ) { - m_parent->m_children.push_back( this ); +DDLNode::DDLNode(const std::string &type, const std::string &name, size_t idx, DDLNode *parent) : + m_type(type), + m_name(name), + m_parent(parent), + m_children(), + m_properties(nullptr), + m_value(nullptr), + m_dtArrayList(nullptr), + m_references(nullptr), + m_idx(idx) { + if (m_parent) { + m_parent->m_children.push_back(this); } } DDLNode::~DDLNode() { delete m_properties; delete m_value; - releaseReferencedNames( m_references ); + releaseReferencedNames(m_references); delete m_dtArrayList; - m_dtArrayList = ddl_nullptr; - if( s_allocatedNodes[ m_idx ] == this ) { - s_allocatedNodes[ m_idx ] = ddl_nullptr; + m_dtArrayList = nullptr; + if (s_allocatedNodes[m_idx] == this) { + s_allocatedNodes[m_idx] = nullptr; } - for ( size_t i = 0; im_children.push_back( this ); + if (nullptr != m_parent) { + m_parent->m_children.push_back(this); } } void DDLNode::detachParent() { - if( ddl_nullptr != m_parent ) { - DDLNodeIt it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this ); - if( m_parent->m_children.end() != it ) { - m_parent->m_children.erase( it ); + if (nullptr != m_parent) { + DDLNodeIt it = std::find(m_parent->m_children.begin(), m_parent->m_children.end(), this); + if (m_parent->m_children.end() != it) { + m_parent->m_children.erase(it); } - m_parent = ddl_nullptr; + m_parent = nullptr; } } @@ -111,7 +111,7 @@ const DDLNode::DllNodeList &DDLNode::getChildNodeList() const { return m_children; } -void DDLNode::setType( const std::string &type ) { +void DDLNode::setType(const std::string &type) { m_type = type; } @@ -119,7 +119,7 @@ const std::string &DDLNode::getType() const { return m_type; } -void DDLNode::setName( const std::string &name ) { +void DDLNode::setName(const std::string &name) { m_name = name; } @@ -127,8 +127,8 @@ const std::string &DDLNode::getName() const { return m_name; } -void DDLNode::setProperties( Property *prop ) { - if(m_properties!=ddl_nullptr) +void DDLNode::setProperties(Property *prop) { + if (m_properties != nullptr) delete m_properties; m_properties = prop; } @@ -137,37 +137,37 @@ Property *DDLNode::getProperties() const { return m_properties; } -bool DDLNode::hasProperty( const std::string &name ) { - const Property *prop( findPropertyByName( name ) ); - return ( ddl_nullptr != prop ); +bool DDLNode::hasProperty(const std::string &name) { + const Property *prop(findPropertyByName(name)); + return (nullptr != prop); } bool DDLNode::hasProperties() const { - return( ddl_nullptr != m_properties ); + return (nullptr != m_properties); } -Property *DDLNode::findPropertyByName( const std::string &name ) { - if( name.empty() ) { - return ddl_nullptr; +Property *DDLNode::findPropertyByName(const std::string &name) { + if (name.empty()) { + return nullptr; } - if( ddl_nullptr == m_properties ) { - return ddl_nullptr; + if (nullptr == m_properties) { + return nullptr; } - Property *current( m_properties ); - while( ddl_nullptr != current ) { - int res = strncmp( current->m_key->m_buffer, name.c_str(), name.size() ); - if( 0 == res ) { + Property *current(m_properties); + while (nullptr != current) { + int res = strncmp(current->m_key->m_buffer, name.c_str(), name.size()); + if (0 == res) { return current; } current = current->m_next; } - return ddl_nullptr; + return nullptr; } -void DDLNode::setValue( Value *val ) { +void DDLNode::setValue(Value *val) { m_value = val; } @@ -175,7 +175,7 @@ Value *DDLNode::getValue() const { return m_value; } -void DDLNode::setDataArrayList( DataArrayList *dtArrayList ) { +void DDLNode::setDataArrayList(DataArrayList *dtArrayList) { m_dtArrayList = dtArrayList; } @@ -183,7 +183,7 @@ DataArrayList *DDLNode::getDataArrayList() const { return m_dtArrayList; } -void DDLNode::setReferences( Reference *refs ) { +void DDLNode::setReferences(Reference *refs) { m_references = refs; } @@ -191,22 +191,32 @@ Reference *DDLNode::getReferences() const { return m_references; } -void DDLNode::dump(IOStreamBase &/*stream*/) { - // Todo! +void DDLNode::dump(IOStreamBase &stream) { + if (!stream.isOpen()) { + return; + } + + const std::string &type = this->getType(); + stream.write("type = " + type); + Value::Iterator it(getValue()); + while (it.hasNext()) { + Value *v = it.getNext(); + v->dump(stream); + } } -DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) { - const size_t idx( s_allocatedNodes.size() ); - DDLNode *node = new DDLNode( type, name, idx, parent ); - s_allocatedNodes.push_back( node ); - +DDLNode *DDLNode::create(const std::string &type, const std::string &name, DDLNode *parent) { + const size_t idx(s_allocatedNodes.size()); + DDLNode *node = new DDLNode(type, name, idx, parent); + s_allocatedNodes.push_back(node); + return node; } void DDLNode::releaseNodes() { - if( s_allocatedNodes.size() > 0 ) { - for( DDLNodeIt it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) { - if( *it ) { + if (s_allocatedNodes.size() > 0) { + for (DDLNodeIt it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++) { + if (*it) { delete *it; } } diff --git a/contrib/openddlparser/code/OpenDDLCommon.cpp b/contrib/openddlparser/code/OpenDDLCommon.cpp index 5c341a780..d853efae8 100644 --- a/contrib/openddlparser/code/OpenDDLCommon.cpp +++ b/contrib/openddlparser/code/OpenDDLCommon.cpp @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -20,17 +20,17 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -----------------------------------------------------------------------------------------------*/ -#include #include +#include #include BEGIN_ODDLPARSER_NS -Text::Text( const char *buffer, size_t numChars ) -: m_capacity( 0 ) -, m_len( 0 ) -, m_buffer( ddl_nullptr ) { - set( buffer, numChars ); +Text::Text(const char *buffer, size_t numChars) : + m_capacity(0), + m_len(0), + m_buffer(nullptr) { + set(buffer, numChars); } Text::~Text() { @@ -39,103 +39,98 @@ Text::~Text() { void Text::clear() { delete[] m_buffer; - m_buffer = ddl_nullptr; + m_buffer = nullptr; m_capacity = 0; m_len = 0; } -void Text::set( const char *buffer, size_t numChars ) { +void Text::set(const char *buffer, size_t numChars) { clear(); - if( numChars > 0 ) { + if (numChars > 0) { m_len = numChars; m_capacity = m_len + 1; - m_buffer = new char[ m_capacity ]; - strncpy( m_buffer, buffer, numChars ); - m_buffer[ numChars ] = '\0'; + m_buffer = new char[m_capacity]; + strncpy(m_buffer, buffer, numChars); + m_buffer[numChars] = '\0'; } } -bool Text::operator == ( const std::string &name ) const { - if( m_len != name.size() ) { +bool Text::operator==(const std::string &name) const { + if (m_len != name.size()) { return false; } - const int res( strncmp( m_buffer, name.c_str(), name.size() ) ); + const int res(strncmp(m_buffer, name.c_str(), name.size())); - return ( 0 == res ); + return (0 == res); } -bool Text::operator == ( const Text &rhs ) const { - if( m_len != rhs.m_len ) { +bool Text::operator==(const Text &rhs) const { + if (m_len != rhs.m_len) { return false; } - const int res( strncmp( m_buffer, rhs.m_buffer, m_len ) ); + const int res(strncmp(m_buffer, rhs.m_buffer, m_len)); - return ( 0 == res ); + return (0 == res); } -Name::Name( NameType type, Text *id ) -: m_type( type ) -, m_id( id ) { +Name::Name(NameType type, Text *id) : + m_type(type), m_id(id) { // empty } Name::~Name() { delete m_id; - m_id = ddl_nullptr; + m_id = nullptr; } -Name::Name( const Name &name ){ - m_type=name.m_type; - m_id=new Text(name.m_id->m_buffer,name.m_id->m_len); +Name::Name(const Name &name) { + m_type = name.m_type; + m_id = new Text(name.m_id->m_buffer, name.m_id->m_len); } - - - Reference::Reference() -: m_numRefs( 0 ) -, m_referencedName( ddl_nullptr ) { +Reference::Reference() : + m_numRefs(0), m_referencedName(nullptr) { // empty } -Reference::Reference( size_t numrefs, Name **names ) -: m_numRefs( numrefs ) -, m_referencedName( ddl_nullptr ) { - if ( numrefs > 0 ) { - m_referencedName = new Name *[ numrefs ]; - for ( size_t i = 0; i < numrefs; i++ ) { - m_referencedName[ i ] = names[i]; +Reference::Reference(size_t numrefs, Name **names) : + m_numRefs(numrefs), m_referencedName(nullptr) { + if (numrefs > 0) { + m_referencedName = new Name *[numrefs]; + for (size_t i = 0; i < numrefs; i++) { + m_referencedName[i] = names[i]; } } } Reference::Reference(const Reference &ref) { - m_numRefs=ref.m_numRefs; - if(m_numRefs!=0){ - m_referencedName = new Name*[m_numRefs]; - for ( size_t i = 0; i < m_numRefs; i++ ) { + m_numRefs = ref.m_numRefs; + if (m_numRefs != 0) { + m_referencedName = new Name *[m_numRefs]; + for (size_t i = 0; i < m_numRefs; i++) { m_referencedName[i] = new Name(*ref.m_referencedName[i]); } } } Reference::~Reference() { - for( size_t i = 0; i < m_numRefs; i++ ) { - delete m_referencedName[ i ]; + for (size_t i = 0; i < m_numRefs; i++) { + delete m_referencedName[i]; } m_numRefs = 0; - delete [] m_referencedName; - m_referencedName = ddl_nullptr; + delete[] m_referencedName; + m_referencedName = nullptr; } size_t Reference::sizeInBytes() { - if ( 0 == m_numRefs ) { + if (0 == m_numRefs) { return 0; } - size_t size( 0 ); - for ( size_t i = 0; i < m_numRefs; i++ ) { - Name *name( m_referencedName[ i ] ); - if ( ddl_nullptr != name ) { + size_t size(0); + for (size_t i = 0; i < m_numRefs; i++) { + Name *name(m_referencedName[i]); + if (nullptr != name) { size += name->m_id->m_len; } } @@ -143,60 +138,53 @@ size_t Reference::sizeInBytes() { return size; } -Property::Property( Text *id ) -: m_key( id ) -, m_value( ddl_nullptr ) -, m_ref( ddl_nullptr ) -, m_next( ddl_nullptr ) { +Property::Property(Text *id) : + m_key(id), m_value(nullptr), m_ref(nullptr), m_next(nullptr) { // empty } Property::~Property() { delete m_key; - if(m_value!=ddl_nullptr) + if (m_value != nullptr) delete m_value; - if(m_ref!=ddl_nullptr) - delete(m_ref); - if(m_next!=ddl_nullptr) + if (m_ref != nullptr) + delete (m_ref); + if (m_next != nullptr) delete m_next; } -DataArrayList::DataArrayList() -: m_numItems( 0 ) -, m_dataList( ddl_nullptr ) -, m_next( ddl_nullptr ) -, m_refs(ddl_nullptr) -, m_numRefs(0){ +DataArrayList::DataArrayList() : + m_numItems(0), m_dataList(nullptr), m_next(nullptr), m_refs(nullptr), m_numRefs(0) { // empty } DataArrayList::~DataArrayList() { delete m_dataList; - if(m_next!=ddl_nullptr) + if (m_next != nullptr) delete m_next; - if(m_refs!=ddl_nullptr) + if (m_refs != nullptr) delete m_refs; } size_t DataArrayList::size() { - size_t result( 0 ); - if ( ddl_nullptr == m_next ) { - if ( m_dataList != ddl_nullptr ) { + size_t result(0); + if (nullptr == m_next) { + if (m_dataList != nullptr) { result = 1; } return result; } - DataArrayList *n( m_next ); - while( ddl_nullptr != n ) { + DataArrayList *n(m_next); + while (nullptr != n) { result++; n = n->m_next; } return result; } -Context::Context() -: m_root( ddl_nullptr ) { +Context::Context() : + m_root(nullptr) { // empty } @@ -206,7 +194,7 @@ Context::~Context() { void Context::clear() { delete m_root; - m_root = ddl_nullptr; + m_root = nullptr; } END_ODDLPARSER_NS diff --git a/contrib/openddlparser/code/OpenDDLExport.cpp b/contrib/openddlparser/code/OpenDDLExport.cpp index e45fb041a..6d6f2458d 100644 --- a/contrib/openddlparser/code/OpenDDLExport.cpp +++ b/contrib/openddlparser/code/OpenDDLExport.cpp @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -20,10 +20,10 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -----------------------------------------------------------------------------------------------*/ -#include #include -#include +#include #include +#include #include @@ -33,9 +33,8 @@ struct DDLNodeIterator { const DDLNode::DllNodeList &m_childs; size_t m_idx; - DDLNodeIterator( const DDLNode::DllNodeList &childs ) - : m_childs( childs ) - , m_idx( 0 ) { + DDLNodeIterator(const DDLNode::DllNodeList &childs) : + m_childs(childs), m_idx(0) { // empty } @@ -43,10 +42,10 @@ struct DDLNodeIterator { // empty } - bool getNext( DDLNode **node ) { - if( m_childs.size() > (m_idx+1) ) { + bool getNext(DDLNode **node) { + if (m_childs.size() > (m_idx + 1)) { m_idx++; - *node = m_childs[ m_idx ]; + *node = m_childs[m_idx]; return true; } @@ -55,65 +54,65 @@ struct DDLNodeIterator { private: DDLNodeIterator() ddl_no_copy; - DDLNodeIterator &operator = ( const DDLNodeIterator & ) ddl_no_copy; + DDLNodeIterator &operator=(const DDLNodeIterator &) ddl_no_copy; }; -static void writeLineEnd( std::string &statement ) { +static void writeLineEnd(std::string &statement) { statement += "\n"; } -OpenDDLExport::OpenDDLExport( IOStreamBase *stream ) -: m_stream( stream ) { - if (ddl_nullptr == m_stream) { +OpenDDLExport::OpenDDLExport(IOStreamBase *stream) : + m_stream(stream) { + if (nullptr == m_stream) { m_stream = new IOStreamBase(); } } OpenDDLExport::~OpenDDLExport() { - if (ddl_nullptr != m_stream) { + if (nullptr != m_stream) { m_stream->close(); } delete m_stream; } -bool OpenDDLExport::exportContext( Context *ctx, const std::string &filename ) { - if( ddl_nullptr == ctx ) { +bool OpenDDLExport::exportContext(Context *ctx, const std::string &filename) { + if (nullptr == ctx) { return false; } - DDLNode *root( ctx->m_root ); - if ( ddl_nullptr == root ) { + DDLNode *root(ctx->m_root); + if (nullptr == root) { return true; } if (!filename.empty()) { - if (!m_stream->open( filename )) { + if (!m_stream->open(filename)) { return false; } } - const bool retValue( handleNode( root ) ); - + const bool retValue(handleNode(root)); + return retValue; } -bool OpenDDLExport::handleNode( DDLNode *node ) { - if( ddl_nullptr == node ) { +bool OpenDDLExport::handleNode(DDLNode *node) { + if (nullptr == node) { return true; } const DDLNode::DllNodeList &childs = node->getChildNodeList(); - if( childs.empty() ) { + if (childs.empty()) { return true; } - DDLNode *current( ddl_nullptr ); - DDLNodeIterator it( childs ); + DDLNode *current(nullptr); + DDLNodeIterator it(childs); std::string statement; - bool success( true ); - while( it.getNext( ¤t ) ) { - if( ddl_nullptr != current ) { - success |= writeNode( current, statement ); - if( !handleNode( current ) ) { + bool success(true); + while (it.getNext(¤t)) { + if (nullptr != current) { + success |= writeNode(current, statement); + if (!handleNode(current)) { success = false; } } @@ -122,56 +121,57 @@ bool OpenDDLExport::handleNode( DDLNode *node ) { return success; } -bool OpenDDLExport::writeToStream( const std::string &statement ) { - if (ddl_nullptr == m_stream ) { +bool OpenDDLExport::writeToStream(const std::string &statement) { + if (nullptr == m_stream) { return false; } - if ( !statement.empty()) { - m_stream->write( statement ); + if (!statement.empty()) { + m_stream->write(statement); } return true; } -bool OpenDDLExport::writeNode( DDLNode *node, std::string &statement ) { - writeNodeHeader( node, statement ); +bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) { + bool success(true); + writeNodeHeader(node, statement); if (node->hasProperties()) { - writeProperties( node, statement ); + success |= writeProperties(node, statement); } - writeLineEnd( statement ); + writeLineEnd(statement); statement = "}"; - DataArrayList *al( node->getDataArrayList() ); - if ( ddl_nullptr != al ) { - writeValueType( al->m_dataList->m_type, al->m_numItems, statement ); - writeValueArray( al, statement ); + DataArrayList *al(node->getDataArrayList()); + if (nullptr != al) { + writeValueType(al->m_dataList->m_type, al->m_numItems, statement); + writeValueArray(al, statement); } - Value *v( node->getValue() ); - if (ddl_nullptr != v ) { - writeValueType( v->m_type, 1, statement ); + Value *v(node->getValue()); + if (nullptr != v) { + writeValueType(v->m_type, 1, statement); statement = "{"; - writeLineEnd( statement ); - writeValue( v, statement ); + writeLineEnd(statement); + writeValue(v, statement); statement = "}"; - writeLineEnd( statement ); + writeLineEnd(statement); } statement = "}"; - writeLineEnd( statement ); + writeLineEnd(statement); - writeToStream( statement ); + writeToStream(statement); return true; } -bool OpenDDLExport::writeNodeHeader( DDLNode *node, std::string &statement ) { - if (ddl_nullptr == node) { +bool OpenDDLExport::writeNodeHeader(DDLNode *node, std::string &statement) { + if (nullptr == node) { return false; } statement += node->getType(); - const std::string &name( node->getName() ); - if ( !name.empty() ) { + const std::string &name(node->getName()); + if (!name.empty()) { statement += " "; statement += "$"; statement += name; @@ -180,30 +180,30 @@ bool OpenDDLExport::writeNodeHeader( DDLNode *node, std::string &statement ) { return true; } -bool OpenDDLExport::writeProperties( DDLNode *node, std::string &statement ) { - if ( ddl_nullptr == node ) { +bool OpenDDLExport::writeProperties(DDLNode *node, std::string &statement) { + if (nullptr == node) { return false; } - Property *prop( node->getProperties() ); + Property *prop(node->getProperties()); // if no properties are there, return - if ( ddl_nullptr == prop ) { + if (nullptr == prop) { return true; } - if ( ddl_nullptr != prop ) { + if (nullptr != prop) { // for instance (attrib = "position", bla=2) statement += "("; - bool first( true ); - while ( ddl_nullptr != prop ) { + bool first(true); + while (nullptr != prop) { if (!first) { statement += ", "; } else { first = false; } - statement += std::string( prop->m_key->m_buffer ); + statement += std::string(prop->m_key->m_buffer); statement += " = "; - writeValue( prop->m_value, statement ); + writeValue(prop->m_value, statement); prop = prop->m_next; } @@ -213,19 +213,19 @@ bool OpenDDLExport::writeProperties( DDLNode *node, std::string &statement ) { return true; } -bool OpenDDLExport::writeValueType( Value::ValueType type, size_t numItems, std::string &statement ) { - if ( Value::ddl_types_max == type) { +bool OpenDDLExport::writeValueType(Value::ValueType type, size_t numItems, std::string &statement) { + if (Value::ValueType::ddl_types_max == type) { return false; } - const std::string typeStr( getTypeToken( type ) ); + const std::string typeStr(getTypeToken(type)); statement += typeStr; // if we have an array to write - if ( numItems > 1 ) { + if (numItems > 1) { statement += "["; - char buffer[ 256 ]; - ::memset( buffer, '\0', 256 * sizeof( char ) ); - sprintf( buffer, "%d", static_cast( numItems ) ); + char buffer[256]; + ::memset(buffer, '\0', 256 * sizeof(char)); + sprintf(buffer, "%d", static_cast(numItems)); statement += buffer; statement += "]"; } @@ -233,115 +233,93 @@ bool OpenDDLExport::writeValueType( Value::ValueType type, size_t numItems, std: return true; } -bool OpenDDLExport::writeValue( Value *val, std::string &statement ) { - if (ddl_nullptr == val) { +bool OpenDDLExport::writeValue(Value *val, std::string &statement) { + if (nullptr == val) { return false; } - switch ( val->m_type ) { - case Value::ddl_bool: - if ( true == val->getBool() ) { + switch (val->m_type) { + case Value::ValueType::ddl_bool: + if (true == val->getBool()) { statement += "true"; } else { statement += "false"; } break; - case Value::ddl_int8: - { - std::stringstream stream; - const int i = static_cast( val->getInt8() ); - stream << i; - statement += stream.str(); - } + case Value::ValueType::ddl_int8 : { + std::stringstream stream; + const int i = static_cast(val->getInt8()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_int16: { + std::stringstream stream; + char buffer[256]; + ::memset(buffer, '\0', 256 * sizeof(char)); + sprintf(buffer, "%d", val->getInt16()); + statement += buffer; + } break; + case Value::ValueType::ddl_int32: { + std::stringstream stream; + char buffer[256]; + ::memset(buffer, '\0', 256 * sizeof(char)); + const int i = static_cast(val->getInt32()); + sprintf(buffer, "%d", i); + statement += buffer; + } break; + case Value::ValueType::ddl_int64: { + std::stringstream stream; + const int i = static_cast(val->getInt64()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_unsigned_int8: { + std::stringstream stream; + const int i = static_cast(val->getUnsignedInt8()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_unsigned_int16: { + std::stringstream stream; + const int i = static_cast(val->getUnsignedInt16()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_unsigned_int32: { + std::stringstream stream; + const int i = static_cast(val->getUnsignedInt32()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_unsigned_int64: { + std::stringstream stream; + const int i = static_cast(val->getUnsignedInt64()); + stream << i; + statement += stream.str(); + } break; + case Value::ValueType::ddl_half: break; - case Value::ddl_int16: - { - std::stringstream stream; - char buffer[ 256 ]; - ::memset( buffer, '\0', 256 * sizeof( char ) ); - sprintf( buffer, "%d", val->getInt16() ); - statement += buffer; - } + case Value::ValueType::ddl_float: { + std::stringstream stream; + stream << val->getFloat(); + statement += stream.str(); + } break; + case Value::ValueType::ddl_double: { + std::stringstream stream; + stream << val->getDouble(); + statement += stream.str(); + } break; + case Value::ValueType::ddl_string: { + std::stringstream stream; + stream << val->getString(); + statement += "\""; + statement += stream.str(); + statement += "\""; + } break; + case Value::ValueType::ddl_ref: break; - case Value::ddl_int32: - { - std::stringstream stream; - char buffer[ 256 ]; - ::memset( buffer, '\0', 256 * sizeof( char ) ); - const int i = static_cast< int >( val->getInt32() ); - sprintf( buffer, "%d", i ); - statement += buffer; - } - break; - case Value::ddl_int64: - { - std::stringstream stream; - const int i = static_cast< int >( val->getInt64() ); - stream << i; - statement += stream.str(); - } - break; - case Value::ddl_unsigned_int8: - { - std::stringstream stream; - const int i = static_cast< unsigned int >( val->getUnsignedInt8() ); - stream << i; - statement += stream.str(); - } - break; - case Value::ddl_unsigned_int16: - { - std::stringstream stream; - const int i = static_cast< unsigned int >( val->getUnsignedInt16() ); - stream << i; - statement += stream.str(); - } - break; - case Value::ddl_unsigned_int32: - { - std::stringstream stream; - const int i = static_cast< unsigned int >( val->getUnsignedInt32() ); - stream << i; - statement += stream.str(); - } - break; - case Value::ddl_unsigned_int64: - { - std::stringstream stream; - const int i = static_cast< unsigned int >( val->getUnsignedInt64() ); - stream << i; - statement += stream.str(); - } - break; - case Value::ddl_half: - break; - case Value::ddl_float: - { - std::stringstream stream; - stream << val->getFloat(); - statement += stream.str(); - } - break; - case Value::ddl_double: - { - std::stringstream stream; - stream << val->getDouble(); - statement += stream.str(); - } - break; - case Value::ddl_string: - { - std::stringstream stream; - stream << val->getString(); - statement += "\""; - statement += stream.str(); - statement += "\""; - } - break; - case Value::ddl_ref: - break; - case Value::ddl_none: - case Value::ddl_types_max: + case Value::ValueType::ddl_none: + case Value::ValueType::ddl_types_max: default: break; } @@ -349,8 +327,8 @@ bool OpenDDLExport::writeValue( Value *val, std::string &statement ) { return true; } -bool OpenDDLExport::writeValueArray( DataArrayList *al, std::string &statement ) { - if (ddl_nullptr == al) { +bool OpenDDLExport::writeValueArray(DataArrayList *al, std::string &statement) { + if (nullptr == al) { return false; } @@ -358,17 +336,18 @@ bool OpenDDLExport::writeValueArray( DataArrayList *al, std::string &statement ) return true; } - DataArrayList *nextDataArrayList = al ; - while (ddl_nullptr != nextDataArrayList) { - if (ddl_nullptr != nextDataArrayList) { + DataArrayList *nextDataArrayList = al; + Value *nextValue(nextDataArrayList->m_dataList); + while (nullptr != nextDataArrayList) { + if (nullptr != nextDataArrayList) { statement += "{ "; - Value *nextValue( nextDataArrayList->m_dataList ); - size_t idx( 0 ); - while (ddl_nullptr != nextValue) { + nextValue = nextDataArrayList->m_dataList; + size_t idx(0); + while (nullptr != nextValue) { if (idx > 0) { statement += ", "; } - writeValue( nextValue, statement ); + writeValue(nextValue, statement); nextValue = nextValue->m_next; idx++; } @@ -381,4 +360,3 @@ bool OpenDDLExport::writeValueArray( DataArrayList *al, std::string &statement ) } END_ODDLPARSER_NS - diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 91831ba27..e6f4d7f39 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -20,112 +20,106 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -----------------------------------------------------------------------------------------------*/ -#include #include +#include +#include +#include #include #include #include -#include -#include -#include #ifdef _WIN32 -# include +#include #endif // _WIN32 - BEGIN_ODDLPARSER_NS static const char *Version = "0.4.0"; namespace Grammar { - static const char *OpenBracketToken = "{"; - static const char *CloseBracketToken = "}"; - static const char *OpenPropertyToken = "("; - static const char *ClosePropertyToken = ")"; - static const char *OpenArrayToken = "["; - static const char *CloseArrayToken = "]"; - static const char *BoolTrue = "true"; - static const char *BoolFalse = "false"; - static const char *CommaSeparator = ","; - static const char *PrimitiveTypeToken[ Value::ddl_types_max ] = { - "bool", - "int8", - "int16", - "int32", - "int64", - "unsigned_int8", - "unsigned_int16", - "unsigned_int32", - "unsigned_int64", - "half", - "float", - "double", - "string", - "ref" - }; +static const char *OpenBracketToken = "{"; +static const char *CloseBracketToken = "}"; +static const char *OpenPropertyToken = "("; +static const char *ClosePropertyToken = ")"; +static const char *OpenArrayToken = "["; +static const char *CloseArrayToken = "]"; +static const char *BoolTrue = "true"; +static const char *BoolFalse = "false"; +static const char *CommaSeparator = ","; + +static const char *PrimitiveTypeToken[(size_t)Value::ValueType::ddl_types_max] = { + "bool", + "int8", + "int16", + "int32", + "int64", + "unsigned_int8", + "unsigned_int16", + "unsigned_int32", + "unsigned_int64", + "half", + "float", + "double", + "string", + "ref" +}; } // Namespace Grammar -const char *getTypeToken( Value::ValueType type ) { - return Grammar::PrimitiveTypeToken[ type ]; +const char *getTypeToken(Value::ValueType type) { + return Grammar::PrimitiveTypeToken[(size_t)type]; } -static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) { +static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) { std::stringstream stream; - stream << "Invalid token \"" << *in << "\"" << " expected \"" << exp << "\"" << std::endl; - std::string full( in ); - std::string part( full.substr( 0, 50 ) ); + stream << "Invalid token \"" << *in << "\"" + << " expected \"" << exp << "\"" << std::endl; + std::string full(in); + std::string part(full.substr(0, 50)); stream << part; - callback( ddl_error_msg, stream.str() ); + callback(ddl_error_msg, stream.str()); } -static bool isIntegerType( Value::ValueType integerType ) { - if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 && - integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) { - return false; - } - - return true; -} - -static bool isUnsignedIntegerType( Value::ValueType integerType ) { - if( integerType != Value::ddl_unsigned_int8 && integerType != Value::ddl_unsigned_int16 && - integerType != Value::ddl_unsigned_int32 && integerType != Value::ddl_unsigned_int64 ) { +static bool isIntegerType(Value::ValueType integerType) { + if (integerType != Value::ValueType::ddl_int8 && integerType != Value::ValueType::ddl_int16 && + integerType != Value::ValueType::ddl_int32 && integerType != Value::ValueType::ddl_int64) { return false; } return true; } -static DDLNode *createDDLNode( Text *id, OpenDDLParser *parser ) { - // Basic checks - if( ddl_nullptr == id || ddl_nullptr == parser ) { - return ddl_nullptr; - } - - // If the buffer is empty ( an empty node ) return nullptr - if ( ddl_nullptr == id->m_buffer ) { - return ddl_nullptr; +static bool isUnsignedIntegerType(Value::ValueType integerType) { + if (integerType != Value::ValueType::ddl_unsigned_int8 && integerType != Value::ValueType::ddl_unsigned_int16 && + integerType != Value::ValueType::ddl_unsigned_int32 && integerType != Value::ValueType::ddl_unsigned_int64) { + return false; } - const std::string type( id->m_buffer ); - DDLNode *parent( parser->top() ); - DDLNode *node = DDLNode::create( type, "", parent ); - + return true; +} + +static DDLNode *createDDLNode(Text *id, OpenDDLParser *parser) { + if (nullptr == id || nullptr == parser) { + return nullptr; + } + + const std::string type(id->m_buffer); + DDLNode *parent(parser->top()); + DDLNode *node = DDLNode::create(type, "", parent); + return node; } -static void logMessage( LogSeverity severity, const std::string &msg ) { +static void logMessage(LogSeverity severity, const std::string &msg) { std::string log; - if( ddl_debug_msg == severity ) { + if (ddl_debug_msg == severity) { log += "Debug:"; - } else if( ddl_info_msg == severity ) { + } else if (ddl_info_msg == severity) { log += "Info :"; - } else if( ddl_warn_msg == severity ) { + } else if (ddl_warn_msg == severity) { log += "Warn :"; - } else if( ddl_error_msg == severity ) { + } else if (ddl_error_msg == severity) { log += "Error:"; } else { log += "None :"; @@ -135,20 +129,18 @@ static void logMessage( LogSeverity severity, const std::string &msg ) { std::cout << log; } -OpenDDLParser::OpenDDLParser() -: m_logCallback( logMessage ) -, m_buffer() -, m_stack() -, m_context( ddl_nullptr ) { +OpenDDLParser::OpenDDLParser() : + m_logCallback(logMessage), + m_buffer(), + m_stack(), + m_context(nullptr) { // empty } -OpenDDLParser::OpenDDLParser( const char *buffer, size_t len ) -: m_logCallback( &logMessage ) -, m_buffer() -, m_context( ddl_nullptr ) { - if( 0 != len ) { - setBuffer( buffer, len ); +OpenDDLParser::OpenDDLParser(const char *buffer, size_t len) : + m_logCallback(&logMessage), m_buffer(), m_context(nullptr) { + if (0 != len) { + setBuffer(buffer, len); } } @@ -156,8 +148,8 @@ OpenDDLParser::~OpenDDLParser() { clear(); } -void OpenDDLParser::setLogCallback( logCallback callback ) { - if( ddl_nullptr != callback ) { +void OpenDDLParser::setLogCallback(logCallback callback) { + if (nullptr != callback) { // install user-specific log callback m_logCallback = callback; } else { @@ -170,28 +162,28 @@ OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const { return m_logCallback; } -void OpenDDLParser::setBuffer( const char *buffer, size_t len ) { +void OpenDDLParser::setBuffer(const char *buffer, size_t len) { clear(); - if( 0 == len ) { + if (0 == len) { return; } - m_buffer.resize( len ); - ::memcpy(&m_buffer[ 0 ], buffer, len ); + m_buffer.resize(len); + ::memcpy(&m_buffer[0], buffer, len); } -void OpenDDLParser::setBuffer( const std::vector &buffer ) { +void OpenDDLParser::setBuffer(const std::vector &buffer) { clear(); - m_buffer.resize( buffer.size() ); - std::copy( buffer.begin(), buffer.end(), m_buffer.begin() ); + m_buffer.resize(buffer.size()); + std::copy(buffer.begin(), buffer.end(), m_buffer.begin()); } const char *OpenDDLParser::getBuffer() const { - if( m_buffer.empty() ) { - return ddl_nullptr; + if (m_buffer.empty()) { + return nullptr; } - return &m_buffer[ 0 ]; + return &m_buffer[0]; } size_t OpenDDLParser::getBufferSize() const { @@ -199,266 +191,279 @@ size_t OpenDDLParser::getBufferSize() const { } void OpenDDLParser::clear() { - m_buffer.resize( 0 ); - if( ddl_nullptr != m_context ) { + m_buffer.resize(0); + if (nullptr != m_context) { delete m_context; - m_context=ddl_nullptr; + m_context = nullptr; } -// DDLNode::releaseNodes(); + // DDLNode::releaseNodes(); } -bool OpenDDLParser::parse() { - if( m_buffer.empty() ) { +bool OpenDDLParser::validate() { + if (m_buffer.empty()) { + return true; + } + + if (!isCharacter(m_buffer[0]) && !isNumeric(m_buffer[0])) { return false; } - normalizeBuffer( m_buffer ); + return true; +} + +bool OpenDDLParser::parse() { + if (m_buffer.empty()) { + return false; + } + + normalizeBuffer(m_buffer); + if (!validate()) { + return false; + } m_context = new Context; - m_context->m_root = DDLNode::create( "root", "", ddl_nullptr ); - pushNode( m_context->m_root ); + m_context->m_root = DDLNode::create("root", "", nullptr); + pushNode(m_context->m_root); // do the main parsing - char *current( &m_buffer[ 0 ] ); - char *end( &m_buffer[m_buffer.size() - 1 ] + 1 ); - size_t pos( current - &m_buffer[ 0 ] ); - while( pos < m_buffer.size() ) { - current = parseNextNode( current, end ); - if ( current == ddl_nullptr ) { + char *current(&m_buffer[0]); + char *end(&m_buffer[m_buffer.size() - 1] + 1); + size_t pos(current - &m_buffer[0]); + while (pos < m_buffer.size()) { + current = parseNextNode(current, end); + if (current == nullptr) { return false; } - pos = current - &m_buffer[ 0 ]; + pos = current - &m_buffer[0]; } return true; } -bool OpenDDLParser::exportContext( Context *ctx, const std::string &filename ) { - if( ddl_nullptr == ctx ) { +bool OpenDDLParser::exportContext(Context *ctx, const std::string &filename) { + if (nullptr == ctx) { return false; } OpenDDLExport myExporter; - return myExporter.exportContext( ctx, filename ); + return myExporter.exportContext(ctx, filename); } -char *OpenDDLParser::parseNextNode( char *in, char *end ) { - in = parseHeader( in, end ); - in = parseStructure( in, end ); +char *OpenDDLParser::parseNextNode(char *in, char *end) { + in = parseHeader(in, end); + in = parseStructure(in, end); return in; } #ifdef DEBUG_HEADER_NAME -static void dumpId( Identifier *id ) { - if( ddl_nullptr != id ) { - if ( ddl_nullptr != id->m_text.m_buffer ) { +static void dumpId(Identifier *id) { + if (nullptr != id) { + if (nullptr != id->m_text.m_buffer) { std::cout << id->m_text.m_buffer << std::endl; - } + } } } #endif -char *OpenDDLParser::parseHeader( char *in, char *end ) { - if( ddl_nullptr == in || in == end ) { +char *OpenDDLParser::parseHeader(char *in, char *end) { + if (nullptr == in || in == end) { return in; } - Text *id( ddl_nullptr ); - in = OpenDDLParser::parseIdentifier( in, end, &id ); + Text *id(nullptr); + in = OpenDDLParser::parseIdentifier(in, end, &id); #ifdef DEBUG_HEADER_NAME - dumpId( id ); + dumpId(id); #endif // DEBUG_HEADER_NAME - in = lookForNextToken( in, end ); - if( ddl_nullptr != id ) { + in = lookForNextToken(in, end); + if (nullptr != id) { // store the node - DDLNode *node( createDDLNode( id, this ) ); - if( ddl_nullptr != node ) { - pushNode( node ); + DDLNode *node(createDDLNode(id, this)); + if (nullptr != node) { + pushNode(node); } else { std::cerr << "nullptr returned by creating DDLNode." << std::endl; } delete id; - Name *name_(ddl_nullptr); - in = OpenDDLParser::parseName(in, end, &name_); - std::unique_ptr name(name_); - if( ddl_nullptr != name && ddl_nullptr != node ) { - const std::string nodeName( name->m_id->m_buffer ); - node->setName( nodeName ); + Name *name(nullptr); + in = OpenDDLParser::parseName(in, end, &name); + if (nullptr != name && nullptr != node && nullptr != name->m_id->m_buffer) { + const std::string nodeName(name->m_id->m_buffer); + node->setName(nodeName); + delete name; } + Property *first(nullptr); + in = lookForNextToken(in, end); + if (*in == Grammar::OpenPropertyToken[0]) { + in++; + Property *prop(nullptr), *prev(nullptr); + while (*in != Grammar::ClosePropertyToken[0] && in != end) { + in = OpenDDLParser::parseProperty(in, end, &prop); + in = lookForNextToken(in, end); - std::unique_ptr first; - in = lookForNextToken(in, end); - if (*in == Grammar::OpenPropertyToken[0]) { - in++; - std::unique_ptr prop, prev; - while (*in != Grammar::ClosePropertyToken[0] && in != end) { - Property *prop_(ddl_nullptr); - in = OpenDDLParser::parseProperty(in, end, &prop_); - prop.reset(prop_); - in = lookForNextToken(in, end); + if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) { + logInvalidTokenError(in, Grammar::ClosePropertyToken, m_logCallback); + return nullptr; + } - if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) { - logInvalidTokenError(in, Grammar::ClosePropertyToken, m_logCallback); - return ddl_nullptr; - } + if (nullptr != prop && *in != Grammar::CommaSeparator[0]) { + if (nullptr == first) { + first = prop; + } + if (nullptr != prev) { + prev->m_next = prop; + } + prev = prop; + } + } + ++in; + } - if (ddl_nullptr != prop && *in != Grammar::CommaSeparator[0]) { - if (ddl_nullptr == first) { - first = std::move(prop); - } - if (ddl_nullptr != prev) { - prev->m_next = prop.release(); - } - prev = std::move(prop); - } - } - ++in; - } - - // set the properties - if (first && ddl_nullptr != node) { - node->setProperties(first.release()); - } + // set the properties + if (nullptr != first && nullptr != node) { + node->setProperties(first); + } } return in; } -char *OpenDDLParser::parseStructure( char *in, char *end ) { - if( ddl_nullptr == in || in == end ) { +char *OpenDDLParser::parseStructure(char *in, char *end) { + if (nullptr == in || in == end) { return in; } - bool error( false ); - in = lookForNextToken( in, end ); - if( *in == *Grammar::OpenBracketToken) { + bool error(false); + in = lookForNextToken(in, end); + if (*in == *Grammar::OpenBracketToken) { // loop over all children ( data and nodes ) do { - in = parseStructureBody( in, end, error ); - if(in == ddl_nullptr){ - return ddl_nullptr; + in = parseStructureBody(in, end, error); + if (in == nullptr) { + return nullptr; } - } while ( *in != *Grammar::CloseBracketToken); + } while (*in != *Grammar::CloseBracketToken); ++in; } else { ++in; - logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback ); - return ddl_nullptr; + logInvalidTokenError(in, std::string(Grammar::OpenBracketToken), m_logCallback); + error = true; + return nullptr; } - in = lookForNextToken( in, end ); + in = lookForNextToken(in, end); // pop node from stack after successful parsing - if( !error ) { + if (!error) { popNode(); } return in; } -static void setNodeValues( DDLNode *currentNode, Value *values ) { - if( ddl_nullptr != values ){ - if( ddl_nullptr != currentNode ) { - currentNode->setValue( values ); +static void setNodeValues(DDLNode *currentNode, Value *values) { + if (nullptr != values) { + if (nullptr != currentNode) { + currentNode->setValue(values); } } } -static void setNodeReferences( DDLNode *currentNode, Reference *refs ) { - if( ddl_nullptr != refs ) { - if( ddl_nullptr != currentNode ) { - currentNode->setReferences( refs ); +static void setNodeReferences(DDLNode *currentNode, Reference *refs) { + if (nullptr != refs) { + if (nullptr != currentNode) { + currentNode->setReferences(refs); } } } -static void setNodeDataArrayList( DDLNode *currentNode, DataArrayList *dtArrayList ) { - if( ddl_nullptr != dtArrayList ) { - if( ddl_nullptr != currentNode ) { - currentNode->setDataArrayList( dtArrayList ); +static void setNodeDataArrayList(DDLNode *currentNode, DataArrayList *dtArrayList) { + if (nullptr != dtArrayList) { + if (nullptr != currentNode) { + currentNode->setDataArrayList(dtArrayList); } } } -char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) { - if( !isNumeric( *in ) && !isCharacter( *in ) ) { +char *OpenDDLParser::parseStructureBody(char *in, char *end, bool &error) { + if (!isNumeric(*in) && !isCharacter(*in)) { ++in; } - in = lookForNextToken( in, end ); - Value::ValueType type( Value::ddl_none ); - size_t arrayLen( 0 ); - in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen ); - if( Value::ddl_none != type ) { + in = lookForNextToken(in, end); + Value::ValueType type(Value::ValueType::ddl_none); + size_t arrayLen(0); + in = OpenDDLParser::parsePrimitiveDataType(in, end, type, arrayLen); + if (Value::ValueType::ddl_none != type) { // parse a primitive data type - in = lookForNextToken( in, end ); - if( *in == Grammar::OpenBracketToken[ 0 ] ) { - Reference *refs( ddl_nullptr ); - DataArrayList *dtArrayList( ddl_nullptr ); - Value *values( ddl_nullptr ); - if( 1 == arrayLen ) { - size_t numRefs( 0 ), numValues( 0 ); - in = parseDataList( in, end, type, &values, numValues, &refs, numRefs ); - setNodeValues( top(), values ); - setNodeReferences( top(), refs ); - } else if( arrayLen > 1 ) { - in = parseDataArrayList( in, end, type, &dtArrayList ); - setNodeDataArrayList( top(), dtArrayList ); + in = lookForNextToken(in, end); + if (*in == Grammar::OpenBracketToken[0]) { + Reference *refs(nullptr); + DataArrayList *dtArrayList(nullptr); + Value *values(nullptr); + if (1 == arrayLen) { + size_t numRefs(0), numValues(0); + in = parseDataList(in, end, type, &values, numValues, &refs, numRefs); + setNodeValues(top(), values); + setNodeReferences(top(), refs); + } else if (arrayLen > 1) { + in = parseDataArrayList(in, end, type, &dtArrayList); + setNodeDataArrayList(top(), dtArrayList); } else { std::cerr << "0 for array is invalid." << std::endl; error = true; } } - in = lookForNextToken( in, end ); - if( *in != '}' ) { - logInvalidTokenError( in, std::string( Grammar::CloseBracketToken ), m_logCallback ); - return ddl_nullptr; + in = lookForNextToken(in, end); + if (*in != '}') { + logInvalidTokenError(in, std::string(Grammar::CloseBracketToken), m_logCallback); + return nullptr; } else { //in++; } } else { // parse a complex data type - in = parseNextNode( in, end ); + in = parseNextNode(in, end); } return in; } -void OpenDDLParser::pushNode( DDLNode *node ) { - if( ddl_nullptr == node ) { +void OpenDDLParser::pushNode(DDLNode *node) { + if (nullptr == node) { return; } - m_stack.push_back( node ); + m_stack.push_back(node); } DDLNode *OpenDDLParser::popNode() { - if( m_stack.empty() ) { - return ddl_nullptr; + if (m_stack.empty()) { + return nullptr; } - DDLNode *topNode( top() ); + DDLNode *topNode(top()); m_stack.pop_back(); return topNode; } DDLNode *OpenDDLParser::top() { - if( m_stack.empty() ) { - return ddl_nullptr; + if (m_stack.empty()) { + return nullptr; } - DDLNode *top( m_stack.back() ); + DDLNode *top(m_stack.back()); return top; } DDLNode *OpenDDLParser::getRoot() const { - if( ddl_nullptr == m_context ) { - return ddl_nullptr; + if (nullptr == m_context) { + return nullptr; } return m_context->m_root; @@ -468,16 +473,16 @@ Context *OpenDDLParser::getContext() const { return m_context; } -void OpenDDLParser::normalizeBuffer( std::vector &buffer) { - if( buffer.empty() ) { +void OpenDDLParser::normalizeBuffer(std::vector &buffer) { + if (buffer.empty()) { return; } std::vector newBuffer; - const size_t len( buffer.size() ); - char *end( &buffer[ len-1 ] + 1 ); - for( size_t readIdx = 0; readIdx &buffer) { ++readIdx; } ++readIdx; - ++readIdx; - } else if( !isComment( c, end ) && !isNewLine( *c ) ) { - newBuffer.push_back( buffer[ readIdx ] ); + } else if (!isComment(c, end) && !isNewLine(*c)) { + newBuffer.push_back(buffer[readIdx]); } else { - if( isComment( c, end ) ) { + if (isComment(c, end)) { ++readIdx; // skip the comment and the rest of the line - while( !isEndofLine( buffer[ readIdx ] ) ) { + while (!isEndofLine(buffer[readIdx])) { ++readIdx; } } @@ -501,29 +505,29 @@ void OpenDDLParser::normalizeBuffer( std::vector &buffer) { buffer = newBuffer; } -char *OpenDDLParser::parseName( char *in, char *end, Name **name ) { - *name = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { +char *OpenDDLParser::parseName(char *in, char *end, Name **name) { + *name = nullptr; + if (nullptr == in || in == end) { return in; } // ignore blanks - in = lookForNextToken( in, end ); - if( *in != '$' && *in != '%' ) { + in = lookForNextToken(in, end); + if (*in != '$' && *in != '%') { return in; } - NameType ntype( GlobalName ); - if( *in == '%' ) { + NameType ntype(GlobalName); + if (*in == '%') { ntype = LocalName; } in++; - Name *currentName( ddl_nullptr ); - Text *id( ddl_nullptr ); - in = parseIdentifier( in, end, &id ); - if( id ) { - currentName = new Name( ntype, id ); - if( currentName ) { + Name *currentName(nullptr); + Text *id(nullptr); + in = parseIdentifier(in, end, &id); + if (id) { + currentName = new Name(ntype, id); + if (currentName) { *name = currentName; } } @@ -531,70 +535,70 @@ char *OpenDDLParser::parseName( char *in, char *end, Name **name ) { return in; } -char *OpenDDLParser::parseIdentifier( char *in, char *end, Text **id ) { - *id = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { +char *OpenDDLParser::parseIdentifier(char *in, char *end, Text **id) { + *id = nullptr; + if (nullptr == in || in == end) { return in; } // ignore blanks - in = lookForNextToken( in, end ); + in = lookForNextToken(in, end); // staring with a number is forbidden - if( isNumeric( *in ) ) { + if (isNumeric(*in)) { return in; } // get size of id - size_t idLen( 0 ); - char *start( in ); - while( !isSeparator( *in ) && - !isNewLine( *in ) && ( in != end ) && - *in != Grammar::OpenPropertyToken[ 0 ] && - *in != Grammar::ClosePropertyToken[ 0 ] && - *in != '$' ) { + size_t idLen(0); + char *start(in); + while (!isSeparator(*in) && + !isNewLine(*in) && (in != end) && + *in != Grammar::OpenPropertyToken[0] && + *in != Grammar::ClosePropertyToken[0] && + *in != '$') { ++in; ++idLen; } - const size_t len( idLen ); - *id = new Text( start, len ); + const size_t len(idLen); + *id = new Text(start, len); return in; } -char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ) { - type = Value::ddl_none; +char *OpenDDLParser::parsePrimitiveDataType(char *in, char *end, Value::ValueType &type, size_t &len) { + type = Value::ValueType::ddl_none; len = 0; - if( ddl_nullptr == in || in == end ) { + if (nullptr == in || in == end) { return in; } - size_t prim_len( 0 ); - for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) { - prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] ); - if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) { - type = static_cast( i ); + size_t prim_len(0); + for (size_t i = 0; i < (size_t) Value::ValueType::ddl_types_max; i++) { + prim_len = strlen(Grammar::PrimitiveTypeToken[i]); + if (0 == strncmp(in, Grammar::PrimitiveTypeToken[i], prim_len)) { + type = static_cast(i); break; } } - if( Value::ddl_none == type ) { - in = lookForNextToken( in, end ); + if (Value::ValueType::ddl_none == type) { + in = lookForNextToken(in, end); return in; } else { in += prim_len; } - bool ok( true ); - if( *in == Grammar::OpenArrayToken[ 0 ] ) { + bool ok(true); + if (*in == Grammar::OpenArrayToken[0]) { ok = false; ++in; - char *start( in ); - while ( in != end ) { + char *start(in); + while (in != end) { ++in; - if( *in == Grammar::CloseArrayToken[ 0 ] ) { - len = ::atoi( start ); + if (*in == Grammar::CloseArrayToken[0]) { + len = ::atoi(start); ok = true; ++in; break; @@ -603,29 +607,29 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy } else { len = 1; } - if( !ok ) { - type = Value::ddl_none; + if (!ok) { + type = Value::ValueType::ddl_none; } return in; } -char *OpenDDLParser::parseReference( char *in, char *end, std::vector &names ) { - if( ddl_nullptr == in || in == end ) { +char *OpenDDLParser::parseReference(char *in, char *end, std::vector &names) { + if (nullptr == in || in == end) { return in; } - Name *nextName( ddl_nullptr ); - in = parseName( in, end, &nextName ); - if( nextName ) { - names.push_back( nextName ); + Name *nextName(nullptr); + in = parseName(in, end, &nextName); + if (nextName) { + names.push_back(nextName); } - while( Grammar::CommaSeparator[ 0 ] == *in ) { - in = getNextSeparator( in, end ); - if( Grammar::CommaSeparator[ 0 ] == *in ) { - in = parseName( in, end, &nextName ); - if( nextName ) { - names.push_back( nextName ); + while (Grammar::CommaSeparator[0] == *in) { + in = getNextSeparator(in, end); + if (Grammar::CommaSeparator[0] == *in) { + in = parseName(in, end, &nextName); + if (nextName) { + names.push_back(nextName); } } else { break; @@ -635,86 +639,86 @@ char *OpenDDLParser::parseReference( char *in, char *end, std::vector &na return in; } -char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) { - *boolean = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { +char *OpenDDLParser::parseBooleanLiteral(char *in, char *end, Value **boolean) { + *boolean = nullptr; + if (nullptr == in || in == end) { return in; } - in = lookForNextToken( in, end ); - char *start( in ); - size_t len( 0 ); - while( !isSeparator( *in ) && in != end ) { + in = lookForNextToken(in, end); + char *start(in); + size_t len(0); + while (!isSeparator(*in) && in != end) { ++in; ++len; } ++len; - int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) ); - if( 0 != res ) { - res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) ); - if( 0 != res ) { - *boolean = ddl_nullptr; + int res = ::strncmp(Grammar::BoolTrue, start, strlen(Grammar::BoolTrue)); + if (0 != res) { + res = ::strncmp(Grammar::BoolFalse, start, strlen(Grammar::BoolFalse)); + if (0 != res) { + *boolean = nullptr; return in; } - *boolean = ValueAllocator::allocPrimData( Value::ddl_bool ); - (*boolean)->setBool( false ); + *boolean = ValueAllocator::allocPrimData(Value::ValueType::ddl_bool); + (*boolean)->setBool(false); } else { - *boolean = ValueAllocator::allocPrimData( Value::ddl_bool ); - (*boolean)->setBool( true ); + *boolean = ValueAllocator::allocPrimData(Value::ValueType::ddl_bool); + (*boolean)->setBool(true); } return in; } -char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType ) { - *integer = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { +char *OpenDDLParser::parseIntegerLiteral(char *in, char *end, Value **integer, Value::ValueType integerType) { + *integer = nullptr; + if (nullptr == in || in == end) { return in; } - if( !(isIntegerType( integerType ) || isUnsignedIntegerType(integerType)) ) { + if (!(isIntegerType(integerType) || isUnsignedIntegerType(integerType))) { return in; } - in = lookForNextToken( in, end ); - char *start( in ); - while( !isSeparator( *in ) && in != end ) { + in = lookForNextToken(in, end); + char *start(in); + while (!isSeparator(*in) && in != end) { ++in; } - if( isNumeric( *start ) ) { + if (isNumeric(*start)) { #ifdef OPENDDL_NO_USE_CPP11 - const int64 value( atol( start ) ); // maybe not really 64bit as atoll is but exists without c++11 - const uint64 uvalue( strtoul( start,ddl_nullptr,10 ) ); + const int64 value(atol(start)); // maybe not really 64bit as atoll is but exists without c++11 + const uint64 uvalue(strtoul(start, nullptr, 10)); #else - const int64 value( atoll( start ) ); - const uint64 uvalue( strtoull( start,ddl_nullptr,10 ) ); + const int64 value(atoll(start)); + const uint64 uvalue(strtoull(start, nullptr, 10)); #endif - *integer = ValueAllocator::allocPrimData( integerType ); - switch( integerType ) { - case Value::ddl_int8: - ( *integer )->setInt8( (int8) value ); + *integer = ValueAllocator::allocPrimData(integerType); + switch (integerType) { + case Value::ValueType::ddl_int8: + (*integer)->setInt8((int8)value); break; - case Value::ddl_int16: - ( *integer )->setInt16( ( int16 ) value ); + case Value::ValueType::ddl_int16: + (*integer)->setInt16((int16)value); break; - case Value::ddl_int32: - ( *integer )->setInt32( ( int32 ) value ); + case Value::ValueType::ddl_int32: + (*integer)->setInt32((int32)value); break; - case Value::ddl_int64: - ( *integer )->setInt64( ( int64 ) value ); + case Value::ValueType::ddl_int64: + (*integer)->setInt64((int64)value); break; - case Value::ddl_unsigned_int8: - ( *integer )->setUnsignedInt8( (uint8) uvalue ); + case Value::ValueType::ddl_unsigned_int8: + (*integer)->setUnsignedInt8((uint8)uvalue); break; - case Value::ddl_unsigned_int16: - ( *integer )->setUnsignedInt16( ( uint16 ) uvalue ); + case Value::ValueType::ddl_unsigned_int16: + (*integer)->setUnsignedInt16((uint16)uvalue); break; - case Value::ddl_unsigned_int32: - ( *integer )->setUnsignedInt32( ( uint32 ) uvalue ); + case Value::ValueType::ddl_unsigned_int32: + (*integer)->setUnsignedInt32((uint32)uvalue); break; - case Value::ddl_unsigned_int64: - ( *integer )->setUnsignedInt64( ( uint64 ) uvalue ); + case Value::ValueType::ddl_unsigned_int64: + (*integer)->setUnsignedInt64((uint64)uvalue); break; default: break; @@ -724,105 +728,105 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, return in; } -char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating, Value::ValueType floatType) { - *floating = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { +char *OpenDDLParser::parseFloatingLiteral(char *in, char *end, Value **floating, Value::ValueType floatType) { + *floating = nullptr; + if (nullptr == in || in == end) { return in; } - in = lookForNextToken( in, end ); - char *start( in ); - while( !isSeparator( *in ) && in != end ) { + in = lookForNextToken(in, end); + char *start(in); + while (!isSeparator(*in) && in != end) { ++in; } // parse the float value - bool ok( false ); - if ( isHexLiteral( start, end ) ) { - parseHexaLiteral( start, end, floating ); + bool ok(false); + if (isHexLiteral(start, end)) { + parseHexaLiteral(start, end, floating); return in; } - if( isNumeric( *start ) ) { + if (isNumeric(*start)) { ok = true; } else { - if( *start == '-' ) { - if( isNumeric( *(start+1) ) ) { + if (*start == '-') { + if (isNumeric(*(start + 1))) { ok = true; } } } - if( ok ) { - if ( floatType == Value::ddl_double ) { - const double value( atof( start ) ); - *floating = ValueAllocator::allocPrimData( Value::ddl_double ); - ( *floating )->setDouble( value ); + if (ok) { + if (floatType == Value::ValueType::ddl_double) { + const double value(atof(start)); + *floating = ValueAllocator::allocPrimData(Value::ValueType::ddl_double); + (*floating)->setDouble(value); } else { - const float value( ( float ) atof( start ) ); - *floating = ValueAllocator::allocPrimData( Value::ddl_float ); - ( *floating )->setFloat( value ); + const float value((float)atof(start)); + *floating = ValueAllocator::allocPrimData(Value::ValueType::ddl_float); + (*floating)->setFloat(value); } } return in; } -char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData ) { - *stringData = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { +char *OpenDDLParser::parseStringLiteral(char *in, char *end, Value **stringData) { + *stringData = nullptr; + if (nullptr == in || in == end) { return in; } - in = lookForNextToken( in, end ); - size_t len( 0 ); - char *start( in ); - if( *start == '\"' ) { + in = lookForNextToken(in, end); + size_t len(0); + char *start(in); + if (*start == '\"') { ++start; ++in; - while( *in != '\"' && in != end ) { + while (*in != '\"' && in != end) { ++in; ++len; } - *stringData = ValueAllocator::allocPrimData( Value::ddl_string, len ); - ::strncpy( ( char* ) ( *stringData )->m_data, start, len ); - ( *stringData )->m_data[len] = '\0'; + *stringData = ValueAllocator::allocPrimData(Value::ValueType::ddl_string, len); + ::strncpy((char *)(*stringData)->m_data, start, len); + (*stringData)->m_data[len] = '\0'; ++in; } return in; } -static void createPropertyWithData( Text *id, Value *primData, Property **prop ) { - if( ddl_nullptr != primData ) { - ( *prop ) = new Property( id ); - ( *prop )->m_value = primData; +static void createPropertyWithData(Text *id, Value *primData, Property **prop) { + if (nullptr != primData) { + (*prop) = new Property(id); + (*prop)->m_value = primData; } } -char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) { - *data = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { +char *OpenDDLParser::parseHexaLiteral(char *in, char *end, Value **data) { + *data = nullptr; + if (nullptr == in || in == end) { return in; } - in = lookForNextToken( in, end ); - if( *in != '0' ) { + in = lookForNextToken(in, end); + if (*in != '0') { return in; } ++in; - if( *in != 'x' && *in != 'X' ) { + if (*in != 'x' && *in != 'X') { return in; } ++in; - bool ok( true ); - char *start( in ); - int pos( 0 ); - while( !isSeparator( *in ) && in != end ) { - if( ( *in < '0' && *in > '9' ) || ( *in < 'a' && *in > 'f' ) || ( *in < 'A' && *in > 'F' ) ) { + bool ok(true); + char *start(in); + int pos(0); + while (!isSeparator(*in) && in != end) { + if ((*in < '0' && *in > '9') || (*in < 'a' && *in > 'f') || (*in < 'A' && *in > 'F')) { ok = false; break; } @@ -830,57 +834,57 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) { ++in; } - if( !ok ) { + if (!ok) { return in; } - int value( 0 ); - while( pos > 0 ) { - int v = hex2Decimal( *start ); + int value(0); + while (pos > 0) { + int v = hex2Decimal(*start); --pos; - value = ( value << 4 ) | v; + value = (value << 4) | v; ++start; } - *data = ValueAllocator::allocPrimData( Value::ddl_unsigned_int64 ); - if( ddl_nullptr != *data ) { - ( *data )->setUnsignedInt64( value ); + *data = ValueAllocator::allocPrimData(Value::ValueType::ddl_unsigned_int64); + if (nullptr != *data) { + (*data)->setUnsignedInt64(value); } return in; } -char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) { - *prop = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { +char *OpenDDLParser::parseProperty(char *in, char *end, Property **prop) { + *prop = nullptr; + if (nullptr == in || in == end) { return in; } - in = lookForNextToken( in, end ); - Text *id( ddl_nullptr ); - in = parseIdentifier( in, end, &id ); - if( ddl_nullptr != id ) { - in = lookForNextToken( in, end ); - if( *in == '=' ) { + in = lookForNextToken(in, end); + Text *id(nullptr); + in = parseIdentifier(in, end, &id); + if (nullptr != id) { + in = lookForNextToken(in, end); + if (*in == '=') { ++in; - in = getNextToken( in, end ); - Value *primData( ddl_nullptr ); - if( isInteger( in, end ) ) { - in = parseIntegerLiteral( in, end, &primData ); - createPropertyWithData( id, primData, prop ); - } else if( isFloat( in, end ) ) { - in = parseFloatingLiteral( in, end, &primData ); - createPropertyWithData( id, primData, prop ); - } else if( isStringLiteral( *in ) ) { // string data - in = parseStringLiteral( in, end, &primData ); - createPropertyWithData( id, primData, prop ); - } else { // reference data - std::vector names; - in = parseReference( in, end, names ); - if( !names.empty() ) { - Reference *ref = new Reference( names.size(), &names[ 0 ] ); - ( *prop ) = new Property( id ); - ( *prop )->m_ref = ref; + in = getNextToken(in, end); + Value *primData(nullptr); + if (isInteger(in, end)) { + in = parseIntegerLiteral(in, end, &primData); + createPropertyWithData(id, primData, prop); + } else if (isFloat(in, end)) { + in = parseFloatingLiteral(in, end, &primData); + createPropertyWithData(id, primData, prop); + } else if (isStringLiteral(*in)) { // string data + in = parseStringLiteral(in, end, &primData); + createPropertyWithData(id, primData, prop); + } else { // reference data + std::vector names; + in = parseReference(in, end, names); + if (!names.empty()) { + Reference *ref = new Reference(names.size(), &names[0]); + (*prop) = new Property(id); + (*prop)->m_ref = ref; } } } else { @@ -891,77 +895,77 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) { return in; } -char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type, Value **data, - size_t &numValues, Reference **refs, size_t &numRefs ) { - *data = ddl_nullptr; +char *OpenDDLParser::parseDataList(char *in, char *end, Value::ValueType type, Value **data, + size_t &numValues, Reference **refs, size_t &numRefs) { + *data = nullptr; numValues = numRefs = 0; - if( ddl_nullptr == in || in == end ) { + if (nullptr == in || in == end) { return in; } - in = lookForNextToken( in, end ); - if( *in == '{' ) { + in = lookForNextToken(in, end); + if (*in == '{') { ++in; - Value *current( ddl_nullptr ), *prev( ddl_nullptr ); - while( '}' != *in ) { - current = ddl_nullptr; - in = lookForNextToken( in, end ); - if ( Value::ddl_ref == type ) { - std::vector names; - in = parseReference( in, end, names ); - if ( !names.empty() ) { - Reference *ref = new Reference( names.size(), &names[ 0 ] ); + Value *current(nullptr), *prev(nullptr); + while ('}' != *in) { + current = nullptr; + in = lookForNextToken(in, end); + if (Value::ValueType::ddl_ref == type) { + std::vector names; + in = parseReference(in, end, names); + if (!names.empty()) { + Reference *ref = new Reference(names.size(), &names[0]); *refs = ref; numRefs = names.size(); } - } else if ( Value::ddl_none == type ) { - if (isInteger( in, end )) { - in = parseIntegerLiteral( in, end, ¤t ); - } else if (isFloat( in, end )) { - in = parseFloatingLiteral( in, end, ¤t ); - } else if (isStringLiteral( *in )) { - in = parseStringLiteral( in, end, ¤t ); - } else if (isHexLiteral( in, end )) { - in = parseHexaLiteral( in, end, ¤t ); + } else if (Value::ValueType::ddl_none == type) { + if (isInteger(in, end)) { + in = parseIntegerLiteral(in, end, ¤t); + } else if (isFloat(in, end)) { + in = parseFloatingLiteral(in, end, ¤t); + } else if (isStringLiteral(*in)) { + in = parseStringLiteral(in, end, ¤t); + } else if (isHexLiteral(in, end)) { + in = parseHexaLiteral(in, end, ¤t); } } else { - switch(type){ - case Value::ddl_int8: - case Value::ddl_int16: - case Value::ddl_int32: - case Value::ddl_int64: - case Value::ddl_unsigned_int8: - case Value::ddl_unsigned_int16: - case Value::ddl_unsigned_int32: - case Value::ddl_unsigned_int64: - in = parseIntegerLiteral( in, end, ¤t, type); + switch (type) { + case Value::ValueType::ddl_int8: + case Value::ValueType::ddl_int16: + case Value::ValueType::ddl_int32: + case Value::ValueType::ddl_int64: + case Value::ValueType::ddl_unsigned_int8: + case Value::ValueType::ddl_unsigned_int16: + case Value::ValueType::ddl_unsigned_int32: + case Value::ValueType::ddl_unsigned_int64: + in = parseIntegerLiteral(in, end, ¤t, type); break; - case Value::ddl_half: - case Value::ddl_float: - case Value::ddl_double: - in = parseFloatingLiteral( in, end, ¤t, type); + case Value::ValueType::ddl_half: + case Value::ValueType::ddl_float: + case Value::ValueType::ddl_double: + in = parseFloatingLiteral(in, end, ¤t, type); break; - case Value::ddl_string: - in = parseStringLiteral( in, end, ¤t ); + case Value::ValueType::ddl_string: + in = parseStringLiteral(in, end, ¤t); break; default: break; } } - if( ddl_nullptr != current ) { - if( ddl_nullptr == *data ) { + if (nullptr != current) { + if (nullptr == *data) { *data = current; prev = current; } else { - prev->setNext( current ); + prev->setNext(current); prev = current; } ++numValues; } - in = getNextSeparator( in, end ); - if( ',' != *in && Grammar::CloseBracketToken[ 0 ] != *in && !isSpace( *in ) ) { + in = getNextSeparator(in, end); + if (',' != *in && Grammar::CloseBracketToken[0] != *in && !isSpace(*in)) { break; } } @@ -971,53 +975,53 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type, return in; } -static DataArrayList *createDataArrayList( Value *currentValue, size_t numValues, - Reference *refs, size_t numRefs ) { - DataArrayList *dataList( new DataArrayList ); +static DataArrayList *createDataArrayList(Value *currentValue, size_t numValues, + Reference *refs, size_t numRefs) { + DataArrayList *dataList(new DataArrayList); dataList->m_dataList = currentValue; dataList->m_numItems = numValues; - dataList->m_refs = refs; - dataList->m_numRefs = numRefs; + dataList->m_refs = refs; + dataList->m_numRefs = numRefs; return dataList; } -char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType type, - DataArrayList **dataArrayList ) { - if ( ddl_nullptr == dataArrayList ) { +char *OpenDDLParser::parseDataArrayList(char *in, char *end, Value::ValueType type, + DataArrayList **dataArrayList) { + if (nullptr == dataArrayList) { return in; } - *dataArrayList = ddl_nullptr; - if( ddl_nullptr == in || in == end ) { + *dataArrayList = nullptr; + if (nullptr == in || in == end) { return in; } - in = lookForNextToken( in, end ); - if( *in == Grammar::OpenBracketToken[ 0 ] ) { + in = lookForNextToken(in, end); + if (*in == Grammar::OpenBracketToken[0]) { ++in; - Value *currentValue( ddl_nullptr ); - Reference *refs( ddl_nullptr ); - DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr ); + Value *currentValue(nullptr); + Reference *refs(nullptr); + DataArrayList *prev(nullptr), *currentDataList(nullptr); do { - size_t numRefs( 0 ), numValues( 0 ); - currentValue = ddl_nullptr; + size_t numRefs(0), numValues(0); + currentValue = nullptr; - in = parseDataList( in, end, type, ¤tValue, numValues, &refs, numRefs ); - if( ddl_nullptr != currentValue || 0 != numRefs ) { - if( ddl_nullptr == prev ) { - *dataArrayList = createDataArrayList( currentValue, numValues, refs, numRefs ); + in = parseDataList(in, end, type, ¤tValue, numValues, &refs, numRefs); + if (nullptr != currentValue || 0 != numRefs) { + if (nullptr == prev) { + *dataArrayList = createDataArrayList(currentValue, numValues, refs, numRefs); prev = *dataArrayList; } else { - currentDataList = createDataArrayList( currentValue, numValues, refs, numRefs ); - if( ddl_nullptr != prev ) { + currentDataList = createDataArrayList(currentValue, numValues, refs, numRefs); + if (nullptr != prev) { prev->m_next = currentDataList; prev = currentDataList; } } } - } while( Grammar::CommaSeparator[ 0 ] == *in && in != end ); - in = lookForNextToken( in, end ); + } while (Grammar::CommaSeparator[0] == *in && in != end); + in = lookForNextToken(in, end); ++in; } diff --git a/contrib/openddlparser/code/OpenDDLStream.cpp b/contrib/openddlparser/code/OpenDDLStream.cpp index 7ea8331bd..1a38dfa27 100644 --- a/contrib/openddlparser/code/OpenDDLStream.cpp +++ b/contrib/openddlparser/code/OpenDDLStream.cpp @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -37,22 +37,22 @@ std::string StreamFormatterBase::format(const std::string &statement) { return tmp; } -IOStreamBase::IOStreamBase(StreamFormatterBase *formatter) - : m_formatter(formatter) - , m_file(ddl_nullptr) { - if (ddl_nullptr == m_formatter) { +IOStreamBase::IOStreamBase(StreamFormatterBase *formatter) : + m_formatter(formatter), + m_file(nullptr) { + if (nullptr == m_formatter) { m_formatter = new StreamFormatterBase; } } IOStreamBase::~IOStreamBase() { delete m_formatter; - m_formatter = ddl_nullptr; + m_formatter = nullptr; } bool IOStreamBase::open(const std::string &name) { m_file = ::fopen(name.c_str(), "a"); - if (m_file == ddl_nullptr) { + if (m_file == nullptr) { return false; } @@ -60,33 +60,33 @@ bool IOStreamBase::open(const std::string &name) { } bool IOStreamBase::close() { - if (ddl_nullptr == m_file) { + if (nullptr == m_file) { return false; } ::fclose(m_file); - m_file = ddl_nullptr; + m_file = nullptr; return true; } bool IOStreamBase::isOpen() const { - return ( ddl_nullptr != m_file ); + return (nullptr != m_file); } -size_t IOStreamBase::read( size_t sizeToRead, std::string &statement ) { - if (ddl_nullptr == m_file) { +size_t IOStreamBase::read(size_t sizeToRead, std::string &statement) { + if (nullptr == m_file) { return 0; } - + statement.resize(sizeToRead); - const size_t readBytes = ::fread( &statement[0], 1, sizeToRead, m_file ); + const size_t readBytes = ::fread(&statement[0], 1, sizeToRead, m_file); return readBytes; } size_t IOStreamBase::write(const std::string &statement) { - if (ddl_nullptr == m_file) { + if (nullptr == m_file) { return 0; } std::string formatStatement = m_formatter->format(statement); diff --git a/contrib/openddlparser/code/Value.cpp b/contrib/openddlparser/code/Value.cpp index b5a35e722..708a6878f 100644 --- a/contrib/openddlparser/code/Value.cpp +++ b/contrib/openddlparser/code/Value.cpp @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -20,30 +20,30 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -----------------------------------------------------------------------------------------------*/ +#include #include -#include #include BEGIN_ODDLPARSER_NS -static Value::Iterator end( ddl_nullptr ); +static Value::Iterator end(nullptr); -Value::Iterator::Iterator() -: m_start( ddl_nullptr ) -, m_current( ddl_nullptr ) { +Value::Iterator::Iterator() : + m_start(nullptr), + m_current(nullptr) { // empty } -Value::Iterator::Iterator( Value *start ) -: m_start( start ) -, m_current( start ) { +Value::Iterator::Iterator(Value *start) : + m_start(start), + m_current(start) { // empty } -Value::Iterator::Iterator( const Iterator &rhs ) -: m_start( rhs.m_start ) -, m_current( rhs.m_current ) { +Value::Iterator::Iterator(const Iterator &rhs) : + m_start(rhs.m_start), + m_current(rhs.m_current) { // empty } @@ -52,36 +52,36 @@ Value::Iterator::~Iterator() { } bool Value::Iterator::hasNext() const { - if( ddl_nullptr == m_current ) { + if (nullptr == m_current) { return false; } - return ( ddl_nullptr != m_current->getNext() ); + return (nullptr != m_current->getNext()); } Value *Value::Iterator::getNext() { - if( !hasNext() ) { - return ddl_nullptr; + if (!hasNext()) { + return nullptr; } - Value *v( m_current->getNext() ); + Value *v(m_current->getNext()); m_current = v; return v; } -const Value::Iterator Value::Iterator::operator++( int ) { - if( ddl_nullptr == m_current ) { +const Value::Iterator Value::Iterator::operator++(int) { + if (nullptr == m_current) { return end; } m_current = m_current->getNext(); - Iterator inst( m_current ); + Iterator inst(m_current); return inst; } -Value::Iterator &Value::Iterator::operator++( ) { - if( ddl_nullptr == m_current ) { +Value::Iterator &Value::Iterator::operator++() { + if (nullptr == m_current) { return end; } @@ -90,263 +90,261 @@ Value::Iterator &Value::Iterator::operator++( ) { return *this; } -bool Value::Iterator::operator == ( const Iterator &rhs ) const { - return ( m_current == rhs.m_current ); +bool Value::Iterator::operator==(const Iterator &rhs) const { + return (m_current == rhs.m_current); } -Value *Value::Iterator::operator->( ) const { - if(ddl_nullptr == m_current ) { - return ddl_nullptr; +Value *Value::Iterator::operator->() const { + if (nullptr == m_current) { + return nullptr; } return m_current; } -Value::Value( ValueType type ) -: m_type( type ) -, m_size( 0 ) -, m_data( ddl_nullptr ) -, m_next( ddl_nullptr ) { +Value::Value(ValueType type) : + m_type(type), + m_size(0), + m_data(nullptr), + m_next(nullptr) { // empty } Value::~Value() { - if(m_data!=ddl_nullptr) { - if (m_type == ddl_ref ) { - Reference *tmp = (Reference *) m_data; - if (tmp != ddl_nullptr) + if (m_data != nullptr) { + if (m_type == ValueType::ddl_ref) { + Reference *tmp = (Reference *)m_data; + if (tmp != nullptr) delete tmp; - }else + } else delete[] m_data; - } - if(m_next!=ddl_nullptr) + if (m_next != nullptr) delete m_next; } -void Value::setBool( bool value ) { - assert( ddl_bool == m_type ); - ::memcpy( m_data, &value, m_size ); +void Value::setBool(bool value) { + assert(ValueType::ddl_bool == m_type); + ::memcpy(m_data, &value, m_size); } bool Value::getBool() { - assert( ddl_bool == m_type ); - return ( *m_data == 1 ); + assert(ValueType::ddl_bool == m_type); + return (*m_data == 1); } -void Value::setInt8( int8 value ) { - assert( ddl_int8 == m_type ); - ::memcpy( m_data, &value, m_size ); +void Value::setInt8(int8 value) { + assert(ValueType::ddl_int8 == m_type); + ::memcpy(m_data, &value, m_size); } int8 Value::getInt8() { - assert( ddl_int8 == m_type ); - return ( int8 ) ( *m_data ); + assert(ValueType::ddl_int8 == m_type); + return (int8)(*m_data); } -void Value::setInt16( int16 value ) { - assert( ddl_int16 == m_type ); - ::memcpy( m_data, &value, m_size ); +void Value::setInt16(int16 value) { + assert(ValueType::ddl_int16 == m_type); + ::memcpy(m_data, &value, m_size); } int16 Value::getInt16() { - assert( ddl_int16 == m_type ); + assert(ValueType::ddl_int16 == m_type); int16 i; - ::memcpy( &i, m_data, m_size ); + ::memcpy(&i, m_data, m_size); return i; } -void Value::setInt32( int32 value ) { - assert( ddl_int32 == m_type ); - ::memcpy( m_data, &value, m_size ); +void Value::setInt32(int32 value) { + assert(ValueType::ddl_int32 == m_type); + ::memcpy(m_data, &value, m_size); } int32 Value::getInt32() { - assert( ddl_int32 == m_type ); + assert(ValueType::ddl_int32 == m_type); int32 i; - ::memcpy( &i, m_data, m_size ); + ::memcpy(&i, m_data, m_size); return i; } -void Value::setInt64( int64 value ) { - assert( ddl_int64 == m_type ); - ::memcpy( m_data, &value, m_size ); +void Value::setInt64(int64 value) { + assert(ValueType::ddl_int64 == m_type); + ::memcpy(m_data, &value, m_size); } int64 Value::getInt64() { - assert( ddl_int64 == m_type ); + assert(ValueType::ddl_int64 == m_type); int64 i; - ::memcpy( &i, m_data, m_size ); + ::memcpy(&i, m_data, m_size); return i; } -void Value::setUnsignedInt8( uint8 value ) { - assert( ddl_unsigned_int8 == m_type ); - ::memcpy( m_data, &value, m_size ); +void Value::setUnsignedInt8(uint8 value) { + assert(ValueType::ddl_unsigned_int8 == m_type); + ::memcpy(m_data, &value, m_size); } uint8 Value::getUnsignedInt8() const { - assert( ddl_unsigned_int8 == m_type ); + assert(ValueType::ddl_unsigned_int8 == m_type); uint8 i; - ::memcpy( &i, m_data, m_size ); + ::memcpy(&i, m_data, m_size); return i; } -void Value::setUnsignedInt16( uint16 value ) { - assert( ddl_unsigned_int16 == m_type ); - ::memcpy( m_data, &value, m_size ); +void Value::setUnsignedInt16(uint16 value) { + assert(ValueType::ddl_unsigned_int16 == m_type); + ::memcpy(m_data, &value, m_size); } uint16 Value::getUnsignedInt16() const { - assert( ddl_unsigned_int16 == m_type ); + assert(ValueType::ddl_unsigned_int16 == m_type); uint16 i; - ::memcpy( &i, m_data, m_size ); + ::memcpy(&i, m_data, m_size); return i; } -void Value::setUnsignedInt32( uint32 value ) { - assert( ddl_unsigned_int32 == m_type ); - ::memcpy( m_data, &value, m_size ); +void Value::setUnsignedInt32(uint32 value) { + assert(ValueType::ddl_unsigned_int32 == m_type); + ::memcpy(m_data, &value, m_size); } uint32 Value::getUnsignedInt32() const { - assert( ddl_unsigned_int32 == m_type ); + assert(ValueType::ddl_unsigned_int32 == m_type); uint32 i; - ::memcpy( &i, m_data, m_size ); + ::memcpy(&i, m_data, m_size); return i; } -void Value::setUnsignedInt64( uint64 value ) { - assert( ddl_unsigned_int64 == m_type ); - ::memcpy( m_data, &value, m_size ); +void Value::setUnsignedInt64(uint64 value) { + assert(ValueType::ddl_unsigned_int64 == m_type); + ::memcpy(m_data, &value, m_size); } uint64 Value::getUnsignedInt64() const { - assert( ddl_unsigned_int64 == m_type ); + assert(ValueType::ddl_unsigned_int64 == m_type); uint64 i; - ::memcpy( &i, m_data, m_size ); + ::memcpy(&i, m_data, m_size); return i; } -void Value::setFloat( float value ) { - assert( ddl_float == m_type ); - ::memcpy( m_data, &value, m_size ); +void Value::setFloat(float value) { + assert(ValueType::ddl_float == m_type); + ::memcpy(m_data, &value, m_size); } float Value::getFloat() const { - if( m_type == ddl_float ) { + if (m_type == ValueType::ddl_float) { float v; - ::memcpy( &v, m_data, m_size ); - return ( float ) v; + ::memcpy(&v, m_data, m_size); + return (float)v; } else { float tmp; - ::memcpy( &tmp, m_data, 4 ); - return ( float ) tmp; + ::memcpy(&tmp, m_data, 4); + return (float)tmp; } } -void Value::setDouble( double value ) { - assert( ddl_double == m_type ); - ::memcpy( m_data, &value, m_size ); +void Value::setDouble(double value) { + assert(ValueType::ddl_double == m_type); + ::memcpy(m_data, &value, m_size); } double Value::getDouble() const { - if ( m_type == ddl_double ) { + if (m_type == ValueType::ddl_double) { double v; - ::memcpy( &v, m_data, m_size ); - return ( float ) v; - } - else { + ::memcpy(&v, m_data, m_size); + return (float)v; + } else { double tmp; - ::memcpy( &tmp, m_data, 4 ); - return ( double ) tmp; + ::memcpy(&tmp, m_data, 4); + return (double)tmp; } } -void Value::setString( const std::string &str ) { - assert( ddl_string == m_type ); - ::memcpy( m_data, str.c_str(), str.size() ); - m_data[ str.size() ] = '\0'; +void Value::setString(const std::string &str) { + assert(ValueType::ddl_string == m_type); + ::memcpy(m_data, str.c_str(), str.size()); + m_data[str.size()] = '\0'; } const char *Value::getString() const { - assert( ddl_string == m_type ); - return (const char*) m_data; + assert(ValueType::ddl_string == m_type); + return (const char *)m_data; } -void Value::setRef( Reference *ref ) { - assert( ddl_ref == m_type ); +void Value::setRef(Reference *ref) { + assert(ValueType::ddl_ref == m_type); - if ( ddl_nullptr != ref ) { - const size_t sizeInBytes( ref->sizeInBytes() ); - if ( sizeInBytes > 0 ) { - if ( ddl_nullptr != m_data ) { - delete [] m_data; + if (nullptr != ref) { + const size_t sizeInBytes(ref->sizeInBytes()); + if (sizeInBytes > 0) { + if (nullptr != m_data) { + delete[] m_data; } - m_data = (unsigned char*) new Reference(*ref); + m_data = (unsigned char *)new Reference(*ref); } } } Reference *Value::getRef() const { - assert( ddl_ref == m_type ); + assert(ValueType::ddl_ref == m_type); - return (Reference*) m_data; + return (Reference *)m_data; } -void Value::dump( IOStreamBase &/*stream*/ ) { - switch( m_type ) { - case ddl_none: - std::cout << "None" << std::endl; +void Value::dump(IOStreamBase &stream) { + switch (m_type) { + case ValueType::ddl_none: + stream.write("None\n"); break; - case ddl_bool: - std::cout << getBool() << std::endl; + case ValueType::ddl_bool: + stream.write(std::to_string(getBool()) + "\n"); break; - case ddl_int8: - std::cout << getInt8() << std::endl; + case ValueType::ddl_int8: + stream.write(std::to_string(getInt8()) + "\n"); break; - case ddl_int16: - std::cout << getInt16() << std::endl; + case ValueType::ddl_int16: + stream.write(std::to_string(getInt16()) + "\n"); break; - case ddl_int32: - std::cout << getInt32() << std::endl; + case ValueType::ddl_int32: + stream.write(std::to_string(getInt32()) + "\n"); break; - case ddl_int64: - std::cout << getInt64() << std::endl; + case ValueType::ddl_int64: + stream.write(std::to_string(getInt64()) + "\n"); break; - case ddl_unsigned_int8: - std::cout << "Not supported" << std::endl; + case ValueType::ddl_unsigned_int8: + stream.write("Not supported\n"); break; - case ddl_unsigned_int16: - std::cout << "Not supported" << std::endl; + case ValueType::ddl_unsigned_int16: + stream.write("Not supported\n"); break; - case ddl_unsigned_int32: - std::cout << "Not supported" << std::endl; + case ValueType::ddl_unsigned_int32: + stream.write("Not supported\n"); break; - case ddl_unsigned_int64: - std::cout << "Not supported" << std::endl; + case ValueType::ddl_unsigned_int64: + stream.write("Not supported\n"); break; - case ddl_half: - std::cout << "Not supported" << std::endl; + case ValueType::ddl_half: + stream.write("Not supported\n"); break; - case ddl_float: - std::cout << getFloat() << std::endl; + case ValueType::ddl_float: + stream.write(std::to_string(getFloat()) + "\n"); break; - case ddl_double: - std::cout << getDouble() << std::endl; + case ValueType::ddl_double: + stream.write(std::to_string(getDouble()) + "\n"); break; - case ddl_string: - std::cout << getString() << std::endl; + case ValueType::ddl_string: + stream.write(std::string(getString()) + "\n"); break; - case ddl_ref: - std::cout << "Not supported" << std::endl; + case ValueType::ddl_ref: + stream.write("Not supported\n"); break; default: break; } } -void Value::setNext( Value *next ) { +void Value::setNext(Value *next) { m_next = next; } @@ -354,86 +352,86 @@ Value *Value::getNext() const { return m_next; } -size_t Value::size() const{ - size_t result=1; - Value *n=m_next; - while( n!=ddl_nullptr) { +size_t Value::size() const { + size_t result = 1; + Value *n = m_next; + while (n != nullptr) { result++; - n=n->m_next; + n = n->m_next; } return result; } -Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) { - if( type == Value::ddl_none || Value::ddl_types_max == type ) { - return ddl_nullptr; +Value *ValueAllocator::allocPrimData(Value::ValueType type, size_t len) { + if (type == Value::ValueType::ddl_none || Value::ValueType::ddl_types_max == type) { + return nullptr; } - Value *data = new Value( type ); - switch( type ) { - case Value::ddl_bool: - data->m_size = sizeof( bool ); + Value *data = new Value(type); + switch (type) { + case Value::ValueType::ddl_bool: + data->m_size = sizeof(bool); break; - case Value::ddl_int8: - data->m_size = sizeof( int8 ); + case Value::ValueType::ddl_int8: + data->m_size = sizeof(int8); break; - case Value::ddl_int16: - data->m_size = sizeof( int16 ); + case Value::ValueType::ddl_int16: + data->m_size = sizeof(int16); break; - case Value::ddl_int32: - data->m_size = sizeof( int32 ); + case Value::ValueType::ddl_int32: + data->m_size = sizeof(int32); break; - case Value::ddl_int64: - data->m_size = sizeof( int64 ); + case Value::ValueType::ddl_int64: + data->m_size = sizeof(int64); break; - case Value::ddl_unsigned_int8: - data->m_size = sizeof( uint8 ); + case Value::ValueType::ddl_unsigned_int8: + data->m_size = sizeof(uint8); break; - case Value::ddl_unsigned_int16: - data->m_size = sizeof( uint16 ); + case Value::ValueType::ddl_unsigned_int16: + data->m_size = sizeof(uint16); break; - case Value::ddl_unsigned_int32: - data->m_size = sizeof( uint32 ); + case Value::ValueType::ddl_unsigned_int32: + data->m_size = sizeof(uint32); break; - case Value::ddl_unsigned_int64: - data->m_size = sizeof( uint64 ); + case Value::ValueType::ddl_unsigned_int64: + data->m_size = sizeof(uint64); break; - case Value::ddl_half: - data->m_size = sizeof( short ); + case Value::ValueType::ddl_half: + data->m_size = sizeof(short); break; - case Value::ddl_float: - data->m_size = sizeof( float ); + case Value::ValueType::ddl_float: + data->m_size = sizeof(float); break; - case Value::ddl_double: - data->m_size = sizeof( double ); + case Value::ValueType::ddl_double: + data->m_size = sizeof(double); break; - case Value::ddl_string: - data->m_size = sizeof( char )*(len+1); + case Value::ValueType::ddl_string: + data->m_size = sizeof(char) * (len + 1); break; - case Value::ddl_ref: + case Value::ValueType::ddl_ref: data->m_size = 0; break; - case Value::ddl_none: - case Value::ddl_types_max: + case Value::ValueType::ddl_none: + case Value::ValueType::ddl_types_max: default: break; } - if( data->m_size ) { - data->m_data = new unsigned char[ data->m_size ]; - ::memset(data->m_data,0,data->m_size); + if (data->m_size) { + data->m_data = new unsigned char[data->m_size]; + ::memset(data->m_data, 0, data->m_size); } return data; } -void ValueAllocator::releasePrimData( Value **data ) { - if( !data ) { +void ValueAllocator::releasePrimData(Value **data) { + if (!data) { return; } delete *data; - *data = ddl_nullptr; + *data = nullptr; } END_ODDLPARSER_NS diff --git a/contrib/openddlparser/include/openddlparser/DDLNode.h b/contrib/openddlparser/include/openddlparser/DDLNode.h index 915bd3041..593a5f145 100644 --- a/contrib/openddlparser/include/openddlparser/DDLNode.h +++ b/contrib/openddlparser/include/openddlparser/DDLNode.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -24,8 +24,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include -#include #include +#include BEGIN_ODDLPARSER_NS @@ -53,10 +53,10 @@ public: friend class OpenDDLParser; /// @brief The child-node-list type. - typedef std::vector DllNodeList; + typedef std::vector DllNodeList; /// @brief The child-node-list iterator. - typedef std::vector::iterator DDLNodeIt; + typedef std::vector::iterator DDLNodeIt; public: /// @brief The class destructor. @@ -64,7 +64,7 @@ public: /// @brief Will attach a parent node instance, an older one will be released. /// @param parent [in] The parent node instance. - void attachParent( DDLNode *parent ); + void attachParent(DDLNode *parent); /// @brief Will try to detach a parent node instance, if there is any. void detachParent(); @@ -79,7 +79,7 @@ public: /// Set the type of the DDLNode instance. /// @param type [in] The type. - void setType( const std::string &type ); + void setType(const std::string &type); /// @brief Returns the type of the DDLNode instance. /// @return The type of the DDLNode instance. @@ -87,7 +87,7 @@ public: /// Set the name of the DDLNode instance. /// @param name [in] The name. - void setName( const std::string &name ); + void setName(const std::string &name); /// @brief Returns the name of the DDLNode instance. /// @return The name of the DDLNode instance. @@ -95,7 +95,7 @@ public: /// @brief Set a new property set. /// @param prop [in] The first element of the property set. - void setProperties( Property *prop ); + void setProperties(Property *prop); /// @brief Returns the first element of the assigned property set. /// @return The first property of the assigned property set. @@ -104,7 +104,7 @@ public: /// @brief Looks for a given property. /// @param name [in] The name for the property to look for. /// @return true, if a corresponding property is assigned to the node, false if not. - bool hasProperty( const std::string &name ); + bool hasProperty(const std::string &name); /// @brief Will return true, if any properties are assigned to the node instance. /// @return True, if properties are assigned. @@ -113,11 +113,11 @@ public: /// @brief Search for a given property and returns it. Will return ddl_nullptr if no property was found. /// @param name [in] The name for the property to look for. /// @return The property or ddl_nullptr if no property was found. - Property *findPropertyByName( const std::string &name ); - + Property *findPropertyByName(const std::string &name); + /// @brief Set a new value set. /// @param val [in] The first value instance of the value set. - void setValue( Value *val ); + void setValue(Value *val); /// @brief Returns the first element of the assigned value set. /// @return The first property of the assigned value set. @@ -125,7 +125,7 @@ public: /// @brief Set a new DataArrayList. /// @param dtArrayList [in] The DataArrayList instance. - void setDataArrayList( DataArrayList *dtArrayList ); + void setDataArrayList(DataArrayList *dtArrayList); /// @brief Returns the DataArrayList. /// @return The DataArrayList. @@ -133,7 +133,7 @@ public: /// @brief Set a new Reference set. /// @param refs [in] The first value instance of the Reference set. - void setReferences( Reference *refs ); + void setReferences(Reference *refs); /// @brief Returns the first element of the assigned Reference set. /// @return The first property of the assigned Reference set. @@ -148,20 +148,20 @@ public: /// @param name [in] The name for the new DDLNode instance. /// @param parent [in] The parent node instance or ddl_nullptr if no parent node is there. /// @return The new created node instance. - static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr ); + static DDLNode *create(const std::string &type, const std::string &name, DDLNode *parent = nullptr); private: - DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = ddl_nullptr ); + DDLNode(const std::string &type, const std::string &name, size_t idx, DDLNode *parent = nullptr); DDLNode(); - DDLNode( const DDLNode & ) ddl_no_copy; - DDLNode &operator = ( const DDLNode & ) ddl_no_copy; + DDLNode(const DDLNode &) ddl_no_copy; + DDLNode &operator=(const DDLNode &) ddl_no_copy; static void releaseNodes(); private: std::string m_type; std::string m_name; DDLNode *m_parent; - std::vector m_children; + std::vector m_children; Property *m_properties; Value *m_value; DataArrayList *m_dtArrayList; diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h index bec62cc9d..6ccc83b88 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -23,49 +23,49 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #pragma once #include -#include #include +#include #include #include #ifndef _WIN32 -# include +#include #endif -#if defined(_MSC_VER) && !defined( OPENDDL_STATIC_LIBARY ) +#if defined(_MSC_VER) && !defined(OPENDDL_STATIC_LIBARY) -# define TAG_DLL_EXPORT __declspec(dllexport) -# define TAG_DLL_IMPORT __declspec(dllimport ) -# ifdef OPENDDLPARSER_BUILD -# define DLL_ODDLPARSER_EXPORT TAG_DLL_EXPORT -# else -# define DLL_ODDLPARSER_EXPORT TAG_DLL_IMPORT -# endif // OPENDDLPARSER_BUILD -# pragma warning( disable : 4251 ) +#define TAG_DLL_EXPORT __declspec(dllexport) +#define TAG_DLL_IMPORT __declspec(dllimport) +#ifdef OPENDDLPARSER_BUILD +#define DLL_ODDLPARSER_EXPORT TAG_DLL_EXPORT #else -# define DLL_ODDLPARSER_EXPORT +#define DLL_ODDLPARSER_EXPORT TAG_DLL_IMPORT +#endif // OPENDDLPARSER_BUILD +#pragma warning(disable : 4251) +#else +#define DLL_ODDLPARSER_EXPORT #endif // _WIN32 // Namespace declarations, override this to avoid any conflicts #define BEGIN_ODDLPARSER_NS namespace ODDLParser { -#define END_ODDLPARSER_NS } // namespace ODDLParser -#define USE_ODDLPARSER_NS using namespace ODDLParser; +#define END_ODDLPARSER_NS } // namespace ODDLParser +#define USE_ODDLPARSER_NS using namespace ODDLParser; BEGIN_ODDLPARSER_NS // We will use C++11 optional #ifndef OPENDDL_NO_USE_CPP11 - // All C++11 constructs -# define ddl_nullptr nullptr -# define ddl_override override -# define ddl_final final -# define ddl_no_copy = delete +// All C++11 constructs +#define nullptr nullptr +#define ddl_override override +#define ddl_final final +#define ddl_no_copy = delete #else - // Fall-back for older compilers -# define ddl_nullptr NULL -# define ddl_override -# define ddl_final -# define ddl_no_copy +// Fall-back for older compilers +#define nullptr NULL +#define ddl_override +#define ddl_final +#define ddl_no_copy #endif // OPENDDL_NO_USE_CPP11 // Forward declarations @@ -80,36 +80,36 @@ struct DataArrayList; // Platform-specific typedefs #ifdef _WIN32 -typedef signed __int64 int64_impl; -typedef unsigned __int64 uint64_impl; +typedef signed __int64 int64_impl; +typedef unsigned __int64 uint64_impl; #else -typedef int64_t int64_impl; -typedef uint64_t uint64_impl; +typedef int64_t int64_impl; +typedef uint64_t uint64_impl; #endif // OpenDDL-specific data typedefs -typedef signed char int8; ///< Signed integer, 1 byte -typedef signed short int16; ///< Signed integer, 2 byte -typedef signed int int32; ///< Signed integer, 4 byte -typedef int64_impl int64; ///< Signed integer, 8 byte -typedef unsigned char uint8; ///< Unsigned integer, 1 byte -typedef unsigned short uint16; ///< Unsigned integer, 2 byte -typedef unsigned int uint32; ///< Unsigned integer, 4 byte -typedef uint64_impl uint64; ///< Unsigned integer, 8 byte +using int8 = signed char; ///< Signed integer, 1 byte +using int16 = signed short; ///< Signed integer, 2 byte +using int32 = signed int; ///< Signed integer, 4 byte +using int64 = int64_impl; ///< Signed integer, 8 byte +using uint8 = unsigned char; ///< Unsigned integer, 1 byte +using uint16 = unsigned short ; ///< Unsigned integer, 2 byte +using uint32 = unsigned int; ///< Unsigned integer, 4 byte +using uint64 = uint64_impl ; ///< Unsigned integer, 8 byte /// @brief Stores a text. /// /// A text is stored in a simple character buffer. Texts buffer can be /// greater than the number of stored characters in them. struct DLL_ODDLPARSER_EXPORT Text { - size_t m_capacity; ///< The capacity of the text. - size_t m_len; ///< The length of the text. - char *m_buffer; ///< The buffer with the text. + size_t m_capacity; ///< The capacity of the text. + size_t m_len; ///< The length of the text. + char *m_buffer; ///< The buffer with the text. /// @brief The constructor with a given text buffer. /// @param buffer [in] The buffer. /// @param numChars [in] The number of characters in the buffer. - Text( const char *buffer, size_t numChars ); + Text(const char *buffer, size_t numChars); /// @brief The destructor. ~Text(); @@ -120,55 +120,54 @@ struct DLL_ODDLPARSER_EXPORT Text { /// @brief Set a new text. /// @param buffer [in] The buffer. /// @param numChars [in] The number of characters in the buffer. - void set( const char *buffer, size_t numChars ); + void set(const char *buffer, size_t numChars); /// @brief The compare operator for std::strings. - bool operator == ( const std::string &name ) const; + bool operator==(const std::string &name) const; /// @brief The compare operator for Texts. - bool operator == ( const Text &rhs ) const; + bool operator==(const Text &rhs) const; private: - Text( const Text & ) ddl_no_copy; - Text &operator = ( const Text & ) ddl_no_copy; + Text(const Text &) ddl_no_copy; + Text &operator=(const Text &) ddl_no_copy; }; /// @brief Description of the type of a name. enum NameType { GlobalName, ///< Name is global. - LocalName ///< Name is local. + LocalName ///< Name is local. }; /// @brief Stores an OpenDDL-specific name struct DLL_ODDLPARSER_EXPORT Name { - NameType m_type; ///< The type of the name ( @see NameType ). - Text *m_id; ///< The id. + NameType m_type; ///< The type of the name ( @see NameType ). + Text *m_id; ///< The id. /// @brief The constructor with the type and the id. /// @param type [in] The name type. /// @param id [in] The id. - Name( NameType type, Text *id ); - Name( const Name &name ); + Name(NameType type, Text *id); + Name(const Name &name); /// @brief The destructor. ~Name(); private: - - Name &operator = ( const Name& ) ddl_no_copy; + Name &operator=(const Name &) ddl_no_copy; }; /// @brief Stores a bundle of references. struct DLL_ODDLPARSER_EXPORT Reference { - size_t m_numRefs; ///< The number of stored references. - Name **m_referencedName; ///< The reference names. + size_t m_numRefs; ///< The number of stored references. + Name **m_referencedName; ///< The reference names. /// @brief The default constructor. Reference(); - Reference( const Reference &ref ); + Reference(const Reference &ref); /// @brief The constructor with an array of ref names. /// @param numrefs [in] The number of ref names. /// @param names [in] The ref names. - Reference( size_t numrefs, Name **names ); + Reference(size_t numrefs, Name **names); /// @brief The destructor. ~Reference(); @@ -178,38 +177,38 @@ struct DLL_ODDLPARSER_EXPORT Reference { size_t sizeInBytes(); private: - Reference &operator = ( const Reference & ) ddl_no_copy; + Reference &operator=(const Reference &) ddl_no_copy; }; /// @brief Stores a property list. struct DLL_ODDLPARSER_EXPORT Property { - Text *m_key; ///< The identifier / key of the property. - Value *m_value; ///< The value assigned to its key / id ( ddl_nullptr if none ). - Reference *m_ref; ///< References assigned to its key / id ( ddl_nullptr if none ). - Property *m_next; ///< The next property ( ddl_nullptr if none ). + Text *m_key; ///< The identifier / key of the property. + Value *m_value; ///< The value assigned to its key / id ( ddl_nullptr if none ). + Reference *m_ref; ///< References assigned to its key / id ( ddl_nullptr if none ). + Property *m_next; ///< The next property ( ddl_nullptr if none ). /// @brief The default constructor. Property(); /// @brief The constructor for initialization. /// @param id [in] The identifier - Property( Text *id ); + Property(Text *id); /// @brief The destructor. ~Property(); private: - Property( const Property & ) ddl_no_copy; - Property &operator = ( const Property & ) ddl_no_copy; + Property(const Property &) ddl_no_copy; + Property &operator=(const Property &) ddl_no_copy; }; /// @brief Stores a data array list. struct DLL_ODDLPARSER_EXPORT DataArrayList { - size_t m_numItems; ///< The number of items in the list. - Value *m_dataList; ///< The data list ( a Value ). - DataArrayList *m_next; ///< The next data array list ( ddl_nullptr if last ). - Reference *m_refs; - size_t m_numRefs; + size_t m_numItems; ///< The number of items in the list. + Value *m_dataList; ///< The data list ( a Value ). + DataArrayList *m_next; ///< The next data array list ( ddl_nullptr if last ). + Reference *m_refs; + size_t m_numRefs; /// @brief The default constructor for initialization. DataArrayList(); @@ -221,13 +220,13 @@ struct DLL_ODDLPARSER_EXPORT DataArrayList { size_t size(); private: - DataArrayList( const DataArrayList & ) ddl_no_copy; - DataArrayList &operator = ( const DataArrayList & ) ddl_no_copy; + DataArrayList(const DataArrayList &) ddl_no_copy; + DataArrayList &operator=(const DataArrayList &) ddl_no_copy; }; /// @brief Stores the context of a parsed OpenDDL declaration. struct DLL_ODDLPARSER_EXPORT Context { - DDLNode *m_root; ///< The root node of the OpenDDL node tree. + DDLNode *m_root; ///< The root node of the OpenDDL node tree. /// @brief Constructor for initialization. Context(); @@ -239,8 +238,8 @@ struct DLL_ODDLPARSER_EXPORT Context { void clear(); private: - Context( const Context & ) ddl_no_copy; - Context &operator = ( const Context & ) ddl_no_copy; + Context(const Context &) ddl_no_copy; + Context &operator=(const Context &) ddl_no_copy; }; END_ODDLPARSER_NS diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLExport.h b/contrib/openddlparser/include/openddlparser/OpenDDLExport.h index 020d662a0..945253594 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLExport.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLExport.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -40,7 +40,7 @@ class IOStreamBase; class DLL_ODDLPARSER_EXPORT OpenDDLExport { public: /// @brief The class constructor - OpenDDLExport( IOStreamBase *stream = ddl_nullptr ); + OpenDDLExport(IOStreamBase *stream = nullptr); /// @brief The class destructor. ~OpenDDLExport(); @@ -49,29 +49,29 @@ public: /// @param ctx [in] Pointer to the context. /// @param filename [in] The filename for the export. /// @return True in case of success, false in case of an error. - bool exportContext( Context *ctx, const std::string &filename ); + bool exportContext(Context *ctx, const std::string &filename); /// @brief Handles a node export. /// @param node [in] The node to handle with. /// @return True in case of success, false in case of an error. - bool handleNode( DDLNode *node ); + bool handleNode(DDLNode *node); /// @brief Writes the statement to the stream. /// @param statement [in] The content to write. /// @return True in case of success, false in case of an error. - bool writeToStream( const std::string &statement ); + bool writeToStream(const std::string &statement); protected: - bool writeNode( DDLNode *node, std::string &statement ); - bool writeNodeHeader( DDLNode *node, std::string &statement ); - bool writeProperties( DDLNode *node, std::string &statement ); - bool writeValueType( Value::ValueType type, size_t numItems, std::string &statement ); - bool writeValue( Value *val, std::string &statement ); - bool writeValueArray( DataArrayList *al, std::string &statement ); + bool writeNode(DDLNode *node, std::string &statement); + bool writeNodeHeader(DDLNode *node, std::string &statement); + bool writeProperties(DDLNode *node, std::string &statement); + bool writeValueType(Value::ValueType type, size_t numItems, std::string &statement); + bool writeValue(Value *val, std::string &statement); + bool writeValueArray(DataArrayList *al, std::string &statement); private: - OpenDDLExport( const OpenDDLExport & ) ddl_no_copy; - OpenDDLExport &operator = ( const OpenDDLExport & ) ddl_no_copy; + OpenDDLExport(const OpenDDLExport &) ddl_no_copy; + OpenDDLExport &operator=(const OpenDDLExport &) ddl_no_copy; private: IOStreamBase *m_stream; diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParser.h b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h index ef7f3a72e..5794add90 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParser.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -22,13 +22,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -----------------------------------------------------------------------------------------------*/ #pragma once -#include #include +#include #include #include -#include #include +#include BEGIN_ODDLPARSER_NS @@ -39,14 +39,9 @@ struct Identifier; struct Reference; struct Property; -template -inline -bool isEmbeddedCommentOpenTag( T *in, T *end ) { - if ( in == end ) { - return false; - } - - if ( in == '/' && in+1 == '*' ) { +template +inline bool isEmbeddedCommentOpenTag(T *in, T *end) { + if (in == '/' && in + 1 == '*') { return true; } @@ -58,11 +53,10 @@ bool isEmbeddedCommentOpenTag( T *in, T *end ) { /// @param end [in] The end position in the buffer. /// @return Pointer showing to the next token or the end of the buffer. /// @detail Will not increase buffer when already a valid buffer was found. -template -inline -T *lookForNextToken( T *in, T *end ) { - while( ( in != end ) && ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) ) { - in++; +template +inline T *lookForNextToken(T *in, T *end) { + while ((in != end) && (isSpace(*in) || isNewLine(*in) || ',' == *in)) { + ++in; } return in; } @@ -72,26 +66,25 @@ T *lookForNextToken( T *in, T *end ) { /// @param end [in] The end position in the buffer. /// @return Pointer showing to the next token or the end of the buffer. /// @detail Will increase buffer by a minimum of one. -template -inline -T *getNextToken( T *in, T *end ) { - T *tmp( in ); - in = lookForNextToken( in, end ); - if( tmp == in ) { - in++; +template +inline T *getNextToken(T *in, T *end) { + T *tmp(in); + in = lookForNextToken(in, end); + if (tmp == in) { + ++in; } return in; } /// @brief Defines the log severity. enum LogSeverity { - ddl_debug_msg = 0, ///< Debug message, for debugging - ddl_info_msg, ///< Info messages, normal mode - ddl_warn_msg, ///< Parser warnings - ddl_error_msg ///< Parser errors + ddl_debug_msg = 0, ///< Debug message, for debugging + ddl_info_msg, ///< Info messages, normal mode + ddl_warn_msg, ///< Parser warnings + ddl_error_msg ///< Parser errors }; -DLL_ODDLPARSER_EXPORT const char *getTypeToken( Value::ValueType type ); +DLL_ODDLPARSER_EXPORT const char *getTypeToken(Value::ValueType type); //------------------------------------------------------------------------------------------------- /// @class OpenDDLParser @@ -105,7 +98,7 @@ DLL_ODDLPARSER_EXPORT const char *getTypeToken( Value::ValueType type ); class DLL_ODDLPARSER_EXPORT OpenDDLParser { public: /// @brief The log callback function pointer. - typedef void( *logCallback )( LogSeverity severity, const std::string &msg ); + typedef void (*logCallback)(LogSeverity severity, const std::string &msg); public: /// @brief The default class constructor. @@ -114,14 +107,14 @@ public: /// @brief The class constructor. /// @param buffer [in] The buffer /// @param len [in] Size of the buffer - OpenDDLParser( const char *buffer, size_t len ); + OpenDDLParser(const char *buffer, size_t len); /// @brief The class destructor. ~OpenDDLParser(); /// @brief Setter for an own log callback function. /// @param callback [in] The own callback. - void setLogCallback( logCallback callback ); + void setLogCallback(logCallback callback); /// @brief Getter for the log callback. /// @return The current log callback. @@ -130,11 +123,11 @@ public: /// @brief Assigns a new buffer to parse. /// @param buffer [in] The buffer /// @param len [in] Size of the buffer - void setBuffer( const char *buffer, size_t len ); + void setBuffer(const char *buffer, size_t len); /// @brief Assigns a new buffer to parse. /// @param buffer [in] The buffer as a std::vector. - void setBuffer( const std::vector &buffer ); + void setBuffer(const std::vector &buffer); /// @brief Returns the buffer pointer. /// @return The buffer pointer. @@ -147,12 +140,15 @@ public: /// @brief Clears all parser data, including buffer and active context. void clear(); + bool validate(); + /// @brief Starts the parsing of the OpenDDL-file. /// @return True in case of success, false in case of an error. /// @remark In case of errors check log. bool parse(); - bool exportContext( Context *ctx, const std::string &filename ); + + bool exportContext(Context *ctx, const std::string &filename); /// @brief Returns the root node. /// @return The root node. @@ -163,37 +159,37 @@ public: Context *getContext() const; public: // parser helpers - char *parseNextNode( char *current, char *end ); - char *parseHeader( char *in, char *end ); - char *parseStructure( char *in, char *end ); - char *parseStructureBody( char *in, char *end, bool &error ); - void pushNode( DDLNode *node ); + char *parseNextNode(char *current, char *end); + char *parseHeader(char *in, char *end); + char *parseStructure(char *in, char *end); + char *parseStructureBody(char *in, char *end, bool &error); + void pushNode(DDLNode *node); DDLNode *popNode(); DDLNode *top(); - static void normalizeBuffer( std::vector &buffer ); - static char *parseName( char *in, char *end, Name **name ); - static char *parseIdentifier( char *in, char *end, Text **id ); - static char *parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ); - static char *parseReference( char *in, char *end, std::vector &names ); - static char *parseBooleanLiteral( char *in, char *end, Value **boolean ); - static char *parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType = Value::ddl_int32 ); - static char *parseFloatingLiteral( char *in, char *end, Value **floating, Value::ValueType floatType= Value::ddl_float ); - static char *parseStringLiteral( char *in, char *end, Value **stringData ); - static char *parseHexaLiteral( char *in, char *end, Value **data ); - static char *parseProperty( char *in, char *end, Property **prop ); - static char *parseDataList( char *in, char *end, Value::ValueType type, Value **data, size_t &numValues, Reference **refs, size_t &numRefs ); - static char *parseDataArrayList( char *in, char *end, Value::ValueType type, DataArrayList **dataList ); + static void normalizeBuffer(std::vector &buffer); + static char *parseName(char *in, char *end, Name **name); + static char *parseIdentifier(char *in, char *end, Text **id); + static char *parsePrimitiveDataType(char *in, char *end, Value::ValueType &type, size_t &len); + static char *parseReference(char *in, char *end, std::vector &names); + static char *parseBooleanLiteral(char *in, char *end, Value **boolean); + static char *parseIntegerLiteral(char *in, char *end, Value **integer, Value::ValueType integerType = Value::ValueType::ddl_int32); + static char *parseFloatingLiteral(char *in, char *end, Value **floating, Value::ValueType floatType = Value::ValueType::ddl_float); + static char *parseStringLiteral(char *in, char *end, Value **stringData); + static char *parseHexaLiteral(char *in, char *end, Value **data); + static char *parseProperty(char *in, char *end, Property **prop); + static char *parseDataList(char *in, char *end, Value::ValueType type, Value **data, size_t &numValues, Reference **refs, size_t &numRefs); + static char *parseDataArrayList(char *in, char *end, Value::ValueType type, DataArrayList **dataList); static const char *getVersion(); private: - OpenDDLParser( const OpenDDLParser & ) ddl_no_copy; - OpenDDLParser &operator = ( const OpenDDLParser & ) ddl_no_copy; + OpenDDLParser(const OpenDDLParser &) ddl_no_copy; + OpenDDLParser &operator=(const OpenDDLParser &) ddl_no_copy; private: logCallback m_logCallback; std::vector m_buffer; - typedef std::vector DDLNodeStack; + typedef std::vector DDLNodeStack; DDLNodeStack m_stack; Context *m_context; }; diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h index f0762ac67..5f177f252 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -26,64 +26,318 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. BEGIN_ODDLPARSER_NS -template -inline -bool isUpperCase( T in ) { - return ( in >= 'A' && in <= 'Z' ); +template +inline bool isUpperCase(T in) { + return (in >= 'A' && in <= 'Z'); } -template -inline -bool isLowerCase( T in ) { - return ( in >= 'a' && in <= 'z' ); +template +inline bool isLowerCase(T in) { + return (in >= 'a' && in <= 'z'); } -template -inline -bool isSpace( const T in ) { - return ( ' ' == in || '\t' == in ); +template +inline bool isSpace(const T in) { + return (' ' == in || '\t' == in); } -template -inline -bool isNewLine( const T in ) { - return ( '\n' == in || ( '\r' == in ) ); +template +inline bool isNewLine(const T in) { + return ('\n' == in || ('\r' == in)); } -template -inline -bool isSeparator( T in ) { - if( isSpace( in ) || ',' == in || '{' == in || '}' == in || '[' == in || '(' == in || ')' == in ) { +template +inline bool isSeparator(T in) { + if (isSpace(in) || ',' == in || '{' == in || '}' == in || '[' == in || '(' == in || ')' == in) { return true; } return false; } -template -inline -bool isNumeric( const T in ) { - return ( in >= '0' && in <= '9' ); +static const unsigned char chartype_table[256] = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // 0-15 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // 16-31 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // 32-47 + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, // 48-63 + + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // 64-79 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // 80-95 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // 96-111 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // 112-127 + + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // > 127 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +template +inline bool isNumeric(const T in) { + return (chartype_table[static_cast(in)] == 1); } -template -inline -bool isNotEndOfToken( T *in, T *end ) { - return ( '}' != *in && ',' != *in && !isSpace( *in ) && ')' != *in && in != end ); +template +inline bool isNotEndOfToken(T *in, T *end) { + return ('}' != *in && ',' != *in && !isSpace(*in) && ')' != *in && in != end); } -template -inline -bool isInteger( T *in, T *end ) { - if( in != end ) { - if( *in == '-' ) { +template +inline bool isInteger(T *in, T *end) { + if (in != end) { + if (*in == '-') { ++in; } } - bool result( false ); - while( isNotEndOfToken( in, end ) ) { - result = isNumeric( *in ); - if( !result ) { + bool result(false); + while (isNotEndOfToken(in, end)) { + result = isNumeric(*in); + if (!result) { break; } ++in; @@ -92,40 +346,39 @@ bool isInteger( T *in, T *end ) { return result; } -template -inline -bool isFloat( T *in, T *end ) { - if( in != end ) { - if( *in == '-' ) { +template +inline bool isFloat(T *in, T *end) { + if (in != end) { + if (*in == '-') { ++in; } } // check for <1>.0f - bool result( false ); - while( isNotEndOfToken( in, end ) ) { - if( *in == '.' ) { + bool result(false); + while (isNotEndOfToken(in, end)) { + if (*in == '.') { result = true; break; } - result = isNumeric( *in ); - if( !result ) { + result = isNumeric(*in); + if (!result) { return false; } ++in; } // check for 1<.>0f - if( *in == '.' ) { + if (*in == '.') { ++in; } else { return false; } // check for 1.<0>f - while( isNotEndOfToken( in, end ) ) { - result = isNumeric( *in ); - if( !result ) { + while (isNotEndOfToken(in, end)) { + result = isNumeric(*in); + if (!result) { return false; } ++in; @@ -134,24 +387,21 @@ bool isFloat( T *in, T *end ) { return result; } -template -inline -bool isCharacter( const T in ) { - return ( ( in >= 'a' && in <= 'z' ) || ( in >= 'A' && in <= 'Z' ) ); +template +inline bool isCharacter(const T in) { + return ((in >= 'a' && in <= 'z') || (in >= 'A' && in <= 'Z')); } -template -inline -bool isStringLiteral( const T in ) { - return ( in == '\"' ); +template +inline bool isStringLiteral(const T in) { + return (in == '\"'); } -template -inline -bool isHexLiteral( T *in, T *end ) { - if( *in == '0' ) { - if( in + 1 != end ) { - if( *( in + 1 ) == 'x' || *( in + 1 ) == 'X' ) { +template +inline bool isHexLiteral(T *in, T *end) { + if (*in == '0') { + if (in + 1 != end) { + if (*(in + 1) == 'x' || *(in + 1) == 'X') { return true; } } @@ -160,13 +410,12 @@ bool isHexLiteral( T *in, T *end ) { return false; } -template -inline -bool isReference( T *in, T *end ) { - if( *in == 'r' ) { - if( *(in+1) == 'e' ) { - if( *(in+2) == 'f' ) { - if( ( in + 2 ) != end ) { +template +inline bool isReference(T *in, T *end) { + if (*in == 'r') { + if (*(in + 1) == 'e') { + if (*(in + 2) == 'f') { + if ((in + 2) != end) { return true; } } @@ -176,16 +425,14 @@ bool isReference( T *in, T *end ) { return false; } -template -inline -bool isEndofLine( const T in ) { - return ( '\n' == in ); +template +inline bool isEndofLine(const T in) { + return ('\n' == in); } -template -inline -static T *getNextSeparator( T *in, T *end ) { - while( !isSeparator( *in ) || in == end ) { +template +inline static T *getNextSeparator(T *in, T *end) { + while (!isSeparator(*in) || in == end) { ++in; } return in; @@ -193,30 +440,28 @@ static T *getNextSeparator( T *in, T *end ) { static const int ErrorHex2Decimal = 9999999; -inline -int hex2Decimal( char in ) { - if( isNumeric( in ) ) { - return ( in - 48 ); +inline int hex2Decimal(char in) { + if (isNumeric(in)) { + return (in - 48); } - char hexCodeLower( 'a' ), hexCodeUpper( 'A' ); - for( int i = 0; i<16; i++ ) { - if( in == hexCodeLower + i || in == hexCodeUpper + i ) { - return ( i+10 ); + char hexCodeLower('a'), hexCodeUpper('A'); + for (int i = 0; i < 16; i++) { + if (in == hexCodeLower + i || in == hexCodeUpper + i) { + return (i + 10); } } return ErrorHex2Decimal; } -template -inline -bool isComment( T *in, T *end ) { - if ( *in=='/' ) { - if ( in+1!=end ) { - if ( *( in+1 )=='/' ) { - char *drive( ( in+2 ) ); - if ( (isUpperCase( *drive )||isLowerCase( *drive ))&&*( drive+1 )=='/' ) { +template +inline bool isComment(T *in, T *end) { + if (*in == '/') { + if (in + 1 != end) { + if (*(in + 1) == '/') { + char *drive((in + 2)); + if ((isUpperCase(*drive) || isLowerCase(*drive)) && *(drive + 1) == '/') { return false; } else { return true; @@ -228,9 +473,8 @@ bool isComment( T *in, T *end ) { return false; } -template -inline -bool isCommentOpenTag(T *in, T *end ) { +template +inline bool isCommentOpenTag(T *in, T *end) { if (*in == '/') { if (in + 1 != end) { if (*(in + 1) == '*') { @@ -242,9 +486,8 @@ bool isCommentOpenTag(T *in, T *end ) { return false; } -template -inline -bool isCommentCloseTag(T *in, T *end) { +template +inline bool isCommentCloseTag(T *in, T *end) { if (*in == '*') { if (in + 1 != end) { if (*(in + 1) == '/') { @@ -257,4 +500,3 @@ bool isCommentCloseTag(T *in, T *end) { } END_ODDLPARSER_NS - diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLStream.h b/contrib/openddlparser/include/openddlparser/OpenDDLStream.h index 93370da03..93bde5f7c 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLStream.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLStream.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -38,7 +38,7 @@ public: /// @brief The class destructor, virtual. virtual ~StreamFormatterBase(); - /// @brief Will format the sring and return the new formatted result. + /// @brief Will format the string and return the new formatted result. /// @param statement [in] The string to reformat. /// @return The reformatted result. virtual std::string format(const std::string &statement); @@ -52,7 +52,7 @@ class DLL_ODDLPARSER_EXPORT IOStreamBase { public: /// @brief The class constructor with the formatter. /// @param formatter [in] The formatter to use. - explicit IOStreamBase(StreamFormatterBase *formatter = ddl_nullptr); + explicit IOStreamBase(StreamFormatterBase *formatter = nullptr); /// @brief The class destructor, virtual. virtual ~IOStreamBase(); @@ -74,7 +74,7 @@ public: /// @param sizeToRead [in] The size to read in bytes. /// @param statement [out] The read statements. /// @return The bytes read from the stream. - virtual size_t read( size_t sizeToRead, std::string &statement ); + virtual size_t read(size_t sizeToRead, std::string &statement); /// @brief Will write a string into the stream. /// @param statement [in] The string to write. diff --git a/contrib/openddlparser/include/openddlparser/TPoolAllocator.h b/contrib/openddlparser/include/openddlparser/TPoolAllocator.h new file mode 100644 index 000000000..6076c7324 --- /dev/null +++ b/contrib/openddlparser/include/openddlparser/TPoolAllocator.h @@ -0,0 +1,226 @@ +/*----------------------------------------------------------------------------------------------- +The MIT License (MIT) + +Copyright (c) 2014-2019 Kim Kulling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-----------------------------------------------------------------------------------------------*/ +#pragma once + +#include +#include + +BEGIN_ODDLPARSER_NS + +//------------------------------------------------------------------------------------------------- +/// @class TPoolAllocator +/// @ingroup CPPCore +/// +/// @brief This class implements a simple pool-based allocation scheme. +/// Initially you have to define its size. Each allocation will be done from this initially created +/// pool. You have to release all pooled instances after the usage. +/// This allocation scheme is fast and does no call any new-calls during the lifetime of the +/// allocator. +//------------------------------------------------------------------------------------------------- +template +class TPoolAllocator { +public: + TPoolAllocator(); + TPoolAllocator(size_t numItems); + ~TPoolAllocator(); + T *alloc(); + void release(); + void reserve(size_t size); + void clear(); + size_t capacity() const; + size_t reservedMem() const; + size_t freeMem() const; + void dumpAllocations(std::string &allocs); + void resize(size_t growSize); + + CPPCORE_NONE_COPYING(TPoolAllocator) + +private: + struct Pool { + size_t m_poolsize; + T *m_pool; + size_t m_currentIdx; + Pool *m_next; + + Pool() : + m_poolsize(0u), m_pool(nullptr), m_currentIdx(0u), m_next(nullptr) { + // empty + } + + Pool(size_t numItems, Pool *prev) : + m_poolsize(numItems), m_pool(nullptr), m_currentIdx(0u), m_next(prev) { + m_pool = new T[m_poolsize]; + } + + ~Pool() { + delete[] m_pool; + m_pool = nullptr; + } + + CPPCORE_NONE_COPYING(Pool) + }; + + Pool *getFreePool() { + Pool *current(m_freeList); + if (nullptr != m_freeList) { + m_freeList = m_freeList->m_next; + } + return current; + } + + Pool *m_first; + Pool *m_current; + Pool *m_freeList; + size_t m_capacity; +}; + +template +inline TPoolAllocator::TPoolAllocator() : + m_first(nullptr), m_current(nullptr), m_freeList(nullptr), m_capacity(0L) { + // empty +} + +template +inline TPoolAllocator::TPoolAllocator(size_t numItems) : + m_first(nullptr), m_current(nullptr), m_freeList(nullptr), m_capacity(0L) { + m_first = new Pool(numItems); + m_capacity += numItems; + m_current = m_first; +} + +template +inline TPoolAllocator::~TPoolAllocator() { + clear(); +} + +template +inline T *TPoolAllocator::alloc() { + if (nullptr == m_current) { + return nullptr; + } + + if (m_current->m_currentIdx == m_current->m_poolsize) { + resize(m_current->m_poolsize); + } + + T *ptr(&m_current->m_pool[m_current->m_currentIdx]); + m_current->m_currentIdx++; + + return ptr; +} + +template +inline void TPoolAllocator::release() { + if (nullptr == m_current) { + return; + } + + Pool *current(m_first); + while (nullptr != current) { + current->m_currentIdx = 0; + current = current->m_next; + } + m_freeList = m_first->m_next; + m_current = m_first; +} + +template +inline void TPoolAllocator::reserve(size_t size) { + clear(); + + m_first = new Pool(size, nullptr); + m_current = m_first; + + m_current->m_pool = new T[size]; + m_current->m_poolsize = size; + + m_capacity = size; +} + +template +inline void TPoolAllocator::clear() { + if (nullptr == m_current) { + return; + } + + Pool *next(m_first); + while (nullptr != next) { + Pool *current = next; + next = current->m_next; + delete current; + } + m_current = nullptr; + m_freeList = nullptr; +} + +template +inline size_t TPoolAllocator::capacity() const { + return m_capacity; +} + +template +inline size_t TPoolAllocator::reservedMem() const { + return m_capacity * sizeof(T); +} + +template +inline size_t TPoolAllocator::freeMem() const { + if (nullptr == m_current) { + return 0L; + } + + return (m_current->m_poolsize - m_current->m_currentIdx); +} + +template +inline void TPoolAllocator::dumpAllocations(std::string &allocs) { + allocs.clear(); + allocs += "Number allocations = "; + allocs += std::to_string(m_current->m_currentIdx); + allocs += "\n"; +} + +template +inline void TPoolAllocator::resize(size_t growSize) { + if (nullptr != m_current) { + if (growSize < m_current->m_poolsize) { + return; + } + } + + if (nullptr == m_first) { + m_first = new Pool(growSize, nullptr); + m_current = m_first; + m_capacity += m_current->m_poolsize; + } else { + Pool *pool = getFreePool(); + if (nullptr == pool) { + pool = new Pool(growSize, nullptr); + m_capacity += growSize; + } + m_current->m_next = pool; + m_current = m_current->m_next; + } +} + +END_ODDLPARSER_NS \ No newline at end of file diff --git a/contrib/openddlparser/include/openddlparser/Value.h b/contrib/openddlparser/include/openddlparser/Value.h index 77c6da06b..75af7816b 100644 --- a/contrib/openddlparser/include/openddlparser/Value.h +++ b/contrib/openddlparser/include/openddlparser/Value.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014-2015 Kim Kulling +Copyright (c) 2014-2020 Kim Kulling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -101,7 +101,7 @@ public: }; /// @brief This enum describes the data type stored in the value. - enum ValueType { + enum class ValueType { ddl_none = -1, ///< Nothing specified ddl_bool = 0, ///< A boolean type ddl_int8, ///< Integer type, 8 bytes From 7e1a8f09c5860ffd100e06a8eb44017985afb95c Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 26 Oct 2020 21:35:44 +0100 Subject: [PATCH 18/21] more openddl-fixes --- code/AssetLib/OpenGEX/OpenGEXImporter.cpp | 1235 +++++++++--------- contrib/openddlparser/code/OpenDDLParser.cpp | 7 +- test/unit/utOpenGEXImportExport.cpp | 2 +- 3 files changed, 621 insertions(+), 623 deletions(-) diff --git a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp index ff6af63f6..a49dbed4e 100644 --- a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp +++ b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -45,13 +44,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "PostProcessing/MakeVerboseFormat.h" #include -#include #include +#include -#include -#include #include #include +#include +#include #include @@ -69,135 +68,135 @@ static const aiImporterDesc desc = { }; namespace Grammar { - static const std::string MetricType = "Metric"; - static const std::string Metric_DistanceType = "distance"; - static const std::string Metric_AngleType = "angle"; - static const std::string Metric_TimeType = "time"; - static const std::string Metric_UpType = "up"; - static const std::string NameType = "Name"; - static const std::string ObjectRefType = "ObjectRef"; - static const std::string MaterialRefType = "MaterialRef"; - static const std::string MetricKeyType = "key"; - static const std::string GeometryNodeType = "GeometryNode"; - static const std::string CameraNodeType = "CameraNode"; - static const std::string LightNodeType = "LightNode"; - static const std::string GeometryObjectType = "GeometryObject"; - static const std::string CameraObjectType = "CameraObject"; - static const std::string LightObjectType = "LightObject"; - static const std::string TransformType = "Transform"; - static const std::string MeshType = "Mesh"; - static const std::string VertexArrayType = "VertexArray"; - static const std::string IndexArrayType = "IndexArray"; - static const std::string MaterialType = "Material"; - static const std::string ColorType = "Color"; - static const std::string ParamType = "Param"; - static const std::string TextureType = "Texture"; - static const std::string AttenType = "Atten"; +static const std::string MetricType = "Metric"; +static const std::string Metric_DistanceType = "distance"; +static const std::string Metric_AngleType = "angle"; +static const std::string Metric_TimeType = "time"; +static const std::string Metric_UpType = "up"; +static const std::string NameType = "Name"; +static const std::string ObjectRefType = "ObjectRef"; +static const std::string MaterialRefType = "MaterialRef"; +static const std::string MetricKeyType = "key"; +static const std::string GeometryNodeType = "GeometryNode"; +static const std::string CameraNodeType = "CameraNode"; +static const std::string LightNodeType = "LightNode"; +static const std::string GeometryObjectType = "GeometryObject"; +static const std::string CameraObjectType = "CameraObject"; +static const std::string LightObjectType = "LightObject"; +static const std::string TransformType = "Transform"; +static const std::string MeshType = "Mesh"; +static const std::string VertexArrayType = "VertexArray"; +static const std::string IndexArrayType = "IndexArray"; +static const std::string MaterialType = "Material"; +static const std::string ColorType = "Color"; +static const std::string ParamType = "Param"; +static const std::string TextureType = "Texture"; +static const std::string AttenType = "Atten"; - static const std::string DiffuseColorToken = "diffuse"; - static const std::string SpecularColorToken = "specular"; - static const std::string EmissionColorToken = "emission"; +static const std::string DiffuseColorToken = "diffuse"; +static const std::string SpecularColorToken = "specular"; +static const std::string EmissionColorToken = "emission"; - static const std::string DiffuseTextureToken = "diffuse"; - static const std::string DiffuseSpecularTextureToken = "specular"; - static const std::string SpecularPowerTextureToken = "specular_power"; - static const std::string EmissionTextureToken = "emission"; - static const std::string OpacyTextureToken = "opacity"; - static const std::string TransparencyTextureToken = "transparency"; - static const std::string NormalTextureToken = "normal"; +static const std::string DiffuseTextureToken = "diffuse"; +static const std::string DiffuseSpecularTextureToken = "specular"; +static const std::string SpecularPowerTextureToken = "specular_power"; +static const std::string EmissionTextureToken = "emission"; +static const std::string OpacyTextureToken = "opacity"; +static const std::string TransparencyTextureToken = "transparency"; +static const std::string NormalTextureToken = "normal"; - enum TokenType { - NoneType = -1, - MetricToken, - NameToken, - ObjectRefToken, - MaterialRefToken, - MetricKeyToken, - GeometryNodeToken, - CameraNodeToken, - LightNodeToken, - GeometryObjectToken, - CameraObjectToken, - LightObjectToken, - TransformToken, - MeshToken, - VertexArrayToken, - IndexArrayToken, - MaterialToken, - ColorToken, - ParamToken, - TextureToken, - AttenToken - }; +enum TokenType { + NoneType = -1, + MetricToken, + NameToken, + ObjectRefToken, + MaterialRefToken, + MetricKeyToken, + GeometryNodeToken, + CameraNodeToken, + LightNodeToken, + GeometryObjectToken, + CameraObjectToken, + LightObjectToken, + TransformToken, + MeshToken, + VertexArrayToken, + IndexArrayToken, + MaterialToken, + ColorToken, + ParamToken, + TextureToken, + AttenToken +}; - static const std::string ValidMetricToken[ 4 ] = { - Metric_DistanceType, - Metric_AngleType, - Metric_TimeType, - Metric_UpType - }; +static const std::string ValidMetricToken[4] = { + Metric_DistanceType, + Metric_AngleType, + Metric_TimeType, + Metric_UpType +}; - static int isValidMetricType( const char *token ) { - if( nullptr == token ) { - return false; - } - - int idx( -1 ); - for( size_t i = 0; i < 4; i++ ) { - if( ValidMetricToken[ i ] == token ) { - idx = (int) i; - break; - } - } - - return idx; +static int isValidMetricType(const char *token) { + if (nullptr == token) { + return false; } - static TokenType matchTokenType( const char *tokenType ) { - if( MetricType == tokenType ) { - return MetricToken; - } else if( NameType == tokenType ) { - return NameToken; - } else if( ObjectRefType == tokenType ) { - return ObjectRefToken; - } else if( MaterialRefType == tokenType ) { - return MaterialRefToken; - } else if( MetricKeyType == tokenType ) { - return MetricKeyToken; - } else if ( GeometryNodeType == tokenType ) { - return GeometryNodeToken; - } else if ( CameraNodeType == tokenType ) { - return CameraNodeToken; - } else if ( LightNodeType == tokenType ) { - return LightNodeToken; - } else if ( GeometryObjectType == tokenType ) { - return GeometryObjectToken; - } else if ( CameraObjectType == tokenType ) { - return CameraObjectToken; - } else if ( LightObjectType == tokenType ) { - return LightObjectToken; - } else if( TransformType == tokenType ) { - return TransformToken; - } else if( MeshType == tokenType ) { - return MeshToken; - } else if( VertexArrayType == tokenType ) { - return VertexArrayToken; - } else if( IndexArrayType == tokenType ) { - return IndexArrayToken; - } else if( MaterialType == tokenType ) { - return MaterialToken; - } else if ( ColorType == tokenType ) { - return ColorToken; - } else if ( ParamType == tokenType ) { - return ParamToken; - } else if( TextureType == tokenType ) { - return TextureToken; - } else if ( AttenType == tokenType ) { - return AttenToken; + int idx(-1); + for (size_t i = 0; i < 4; i++) { + if (ValidMetricToken[i] == token) { + idx = (int)i; + break; } - - return NoneType; } + + return idx; +} + +static TokenType matchTokenType(const char *tokenType) { + if (MetricType == tokenType) { + return MetricToken; + } else if (NameType == tokenType) { + return NameToken; + } else if (ObjectRefType == tokenType) { + return ObjectRefToken; + } else if (MaterialRefType == tokenType) { + return MaterialRefToken; + } else if (MetricKeyType == tokenType) { + return MetricKeyToken; + } else if (GeometryNodeType == tokenType) { + return GeometryNodeToken; + } else if (CameraNodeType == tokenType) { + return CameraNodeToken; + } else if (LightNodeType == tokenType) { + return LightNodeToken; + } else if (GeometryObjectType == tokenType) { + return GeometryObjectToken; + } else if (CameraObjectType == tokenType) { + return CameraObjectToken; + } else if (LightObjectType == tokenType) { + return LightObjectToken; + } else if (TransformType == tokenType) { + return TransformToken; + } else if (MeshType == tokenType) { + return MeshToken; + } else if (VertexArrayType == tokenType) { + return VertexArrayToken; + } else if (IndexArrayType == tokenType) { + return IndexArrayToken; + } else if (MaterialType == tokenType) { + return MaterialToken; + } else if (ColorType == tokenType) { + return ColorToken; + } else if (ParamType == tokenType) { + return ParamToken; + } else if (TextureType == tokenType) { + return TextureToken; + } else if (AttenType == tokenType) { + return AttenToken; + } + + return NoneType; +} } // Namespace Grammar namespace Assimp { @@ -206,30 +205,27 @@ namespace OpenGEX { USE_ODDLPARSER_NS //------------------------------------------------------------------------------------------------ -static void propId2StdString( Property *prop, std::string &name, std::string &key ) { +static void propId2StdString(Property *prop, std::string &name, std::string &key) { name = key = ""; - if ( nullptr == prop ) { + if (nullptr == prop) { return; } - if ( nullptr != prop->m_key ) { + if (nullptr != prop->m_key) { #ifdef ASSIMP_USE_HUNTER name = prop->m_key->m_text.m_buffer; #else name = prop->m_key->m_buffer; #endif - if ( Value::ddl_string == prop->m_value->m_type ) { + if (Value::ValueType::ddl_string == prop->m_value->m_type) { key = prop->m_value->getString(); } } } //------------------------------------------------------------------------------------------------ -OpenGEXImporter::VertexContainer::VertexContainer() -: m_numColors( 0 ) -, m_colors( nullptr ) -, m_numUVComps() -, m_textureCoords() { +OpenGEXImporter::VertexContainer::VertexContainer() : + m_numColors(0), m_colors(nullptr), m_numUVComps(), m_textureCoords() { // empty } @@ -237,16 +233,16 @@ OpenGEXImporter::VertexContainer::VertexContainer() OpenGEXImporter::VertexContainer::~VertexContainer() { delete[] m_colors; - for(auto &texcoords : m_textureCoords) { - delete [] texcoords; + for (auto &texcoords : m_textureCoords) { + delete[] texcoords; } } //------------------------------------------------------------------------------------------------ -OpenGEXImporter::RefInfo::RefInfo( aiNode *node, Type type, std::vector &names ) -: m_node( node ) -, m_type( type ) -, m_Names( names ) { +OpenGEXImporter::RefInfo::RefInfo(aiNode *node, Type type, std::vector &names) : + m_node(node), + m_type(type), + m_Names(names) { // empty } @@ -256,26 +252,26 @@ OpenGEXImporter::RefInfo::~RefInfo() { } //------------------------------------------------------------------------------------------------ -OpenGEXImporter::OpenGEXImporter() -: m_root( nullptr ) -, m_nodeChildMap() -, m_meshCache() -, m_mesh2refMap() -, m_material2refMap() -, m_ctx( nullptr ) -, m_metrics() -, m_currentNode( nullptr ) -, m_currentVertices() -, m_currentMesh( nullptr ) -, m_currentMaterial( nullptr ) -, m_currentLight( nullptr ) -, m_currentCamera( nullptr ) -, m_tokenType( Grammar::NoneType ) -, m_materialCache() -, m_cameraCache() -, m_lightCache() -, m_nodeStack() -, m_unresolvedRefStack() { +OpenGEXImporter::OpenGEXImporter() : + m_root(nullptr), + m_nodeChildMap(), + m_meshCache(), + m_mesh2refMap(), + m_material2refMap(), + m_ctx(nullptr), + m_metrics(), + m_currentNode(nullptr), + m_currentVertices(), + m_currentMesh(nullptr), + m_currentMaterial(nullptr), + m_currentLight(nullptr), + m_currentCamera(nullptr), + m_tokenType(Grammar::NoneType), + m_materialCache(), + m_cameraCache(), + m_lightCache(), + m_nodeStack(), + m_unresolvedRefStack() { // empty } @@ -285,46 +281,46 @@ OpenGEXImporter::~OpenGEXImporter() { } //------------------------------------------------------------------------------------------------ -bool OpenGEXImporter::CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const { - bool canRead( false ); - if( !checkSig ) { - canRead = SimpleExtensionCheck( file, "ogex" ); +bool OpenGEXImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool checkSig) const { + bool canRead(false); + if (!checkSig) { + canRead = SimpleExtensionCheck(file, "ogex"); } else { static const char *token[] = { "Metric", "GeometryNode", "VertexArray (attrib", "IndexArray" }; - canRead = BaseImporter::SearchFileHeaderForToken( pIOHandler, file, token, 4 ); + canRead = BaseImporter::SearchFileHeaderForToken(pIOHandler, file, token, 4); } return canRead; } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pScene, IOSystem *pIOHandler ) { +void OpenGEXImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) { // open source file - IOStream *file = pIOHandler->Open( filename, "rb" ); - if( !file ) { - throw DeadlyImportError( "Failed to open file ", filename ); + IOStream *file = pIOHandler->Open(filename, "rb"); + if (!file) { + throw DeadlyImportError("Failed to open file ", filename); } std::vector buffer; - TextFileToBuffer( file, buffer ); - pIOHandler->Close( file ); + TextFileToBuffer(file, buffer); + pIOHandler->Close(file); OpenDDLParser myParser; - myParser.setBuffer( &buffer[ 0 ], buffer.size() ); - bool success( myParser.parse() ); - if( success ) { + myParser.setBuffer(&buffer[0], buffer.size()); + bool success(myParser.parse()); + if (success) { m_ctx = myParser.getContext(); pScene->mRootNode = new aiNode; - pScene->mRootNode->mName.Set( filename ); - handleNodes( m_ctx->m_root, pScene ); + pScene->mRootNode->mName.Set(filename); + handleNodes(m_ctx->m_root, pScene); } - copyMeshes( pScene ); - copyCameras( pScene ); - copyLights( pScene ); - copyMaterials( pScene ); + copyMeshes(pScene); + copyCameras(pScene); + copyLights(pScene); + copyMaterials(pScene); resolveReferences(); - createNodeTree( pScene ); + createNodeTree(pScene); } //------------------------------------------------------------------------------------------------ @@ -333,130 +329,130 @@ const aiImporterDesc *OpenGEXImporter::GetInfo() const { } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::SetupProperties( const Importer *pImp ) { - if( nullptr == pImp ) { +void OpenGEXImporter::SetupProperties(const Importer *pImp) { + if (nullptr == pImp) { return; } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) { - if( nullptr == node ) { +void OpenGEXImporter::handleNodes(DDLNode *node, aiScene *pScene) { + if (nullptr == node) { return; } DDLNode::DllNodeList childs = node->getChildNodeList(); - for( DDLNode::DllNodeList::iterator it = childs.begin(); it != childs.end(); ++it ) { - Grammar::TokenType tokenType( Grammar::matchTokenType( ( *it )->getType().c_str() ) ); - switch( tokenType ) { - case Grammar::MetricToken: - handleMetricNode( *it, pScene ); - break; + for (DDLNode::DllNodeList::iterator it = childs.begin(); it != childs.end(); ++it) { + Grammar::TokenType tokenType(Grammar::matchTokenType((*it)->getType().c_str())); + switch (tokenType) { + case Grammar::MetricToken: + handleMetricNode(*it, pScene); + break; - case Grammar::NameToken: - handleNameNode( *it, pScene ); - break; + case Grammar::NameToken: + handleNameNode(*it, pScene); + break; - case Grammar::ObjectRefToken: - handleObjectRefNode( *it, pScene ); - break; + case Grammar::ObjectRefToken: + handleObjectRefNode(*it, pScene); + break; - case Grammar::MaterialRefToken: - handleMaterialRefNode( *it, pScene ); - break; + case Grammar::MaterialRefToken: + handleMaterialRefNode(*it, pScene); + break; - case Grammar::MetricKeyToken: - break; + case Grammar::MetricKeyToken: + break; - case Grammar::GeometryNodeToken: - handleGeometryNode( *it, pScene ); - break; + case Grammar::GeometryNodeToken: + handleGeometryNode(*it, pScene); + break; - case Grammar::CameraNodeToken: - handleCameraNode( *it, pScene ); - break; + case Grammar::CameraNodeToken: + handleCameraNode(*it, pScene); + break; - case Grammar::LightNodeToken: - handleLightNode( *it, pScene ); - break; + case Grammar::LightNodeToken: + handleLightNode(*it, pScene); + break; - case Grammar::GeometryObjectToken: - handleGeometryObject( *it, pScene ); - break; + case Grammar::GeometryObjectToken: + handleGeometryObject(*it, pScene); + break; - case Grammar::CameraObjectToken: - handleCameraObject( *it, pScene ); - break; + case Grammar::CameraObjectToken: + handleCameraObject(*it, pScene); + break; - case Grammar::LightObjectToken: - handleLightObject( *it, pScene ); - break; + case Grammar::LightObjectToken: + handleLightObject(*it, pScene); + break; - case Grammar::TransformToken: - handleTransformNode( *it, pScene ); - break; + case Grammar::TransformToken: + handleTransformNode(*it, pScene); + break; - case Grammar::MeshToken: - handleMeshNode( *it, pScene ); - break; + case Grammar::MeshToken: + handleMeshNode(*it, pScene); + break; - case Grammar::VertexArrayToken: - handleVertexArrayNode( *it, pScene ); - break; + case Grammar::VertexArrayToken: + handleVertexArrayNode(*it, pScene); + break; - case Grammar::IndexArrayToken: - handleIndexArrayNode( *it, pScene ); - break; + case Grammar::IndexArrayToken: + handleIndexArrayNode(*it, pScene); + break; - case Grammar::MaterialToken: - handleMaterialNode( *it, pScene ); - break; + case Grammar::MaterialToken: + handleMaterialNode(*it, pScene); + break; - case Grammar::ColorToken: - handleColorNode( *it, pScene ); - break; + case Grammar::ColorToken: + handleColorNode(*it, pScene); + break; - case Grammar::ParamToken: - handleParamNode( *it, pScene ); - break; + case Grammar::ParamToken: + handleParamNode(*it, pScene); + break; - case Grammar::TextureToken: - handleTextureNode( *it, pScene ); - break; + case Grammar::TextureToken: + handleTextureNode(*it, pScene); + break; - default: - break; + default: + break; } } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene * /*pScene*/ ) { - if( nullptr == node || nullptr == m_ctx ) { +void OpenGEXImporter::handleMetricNode(DDLNode *node, aiScene * /*pScene*/) { + if (nullptr == node || nullptr == m_ctx) { return; } - if( m_ctx->m_root != node->getParent() ) { + if (m_ctx->m_root != node->getParent()) { return; } - Property *prop( node->getProperties() ); - while( nullptr != prop ) { - if( nullptr != prop->m_key ) { - if( Value::ddl_string == prop->m_value->m_type ) { - std::string valName( ( char* ) prop->m_value->m_data ); - int type( Grammar::isValidMetricType( valName.c_str() ) ); - if( Grammar::NoneType != type ) { - Value *val( node->getValue() ); - if( nullptr != val ) { - if( Value::ddl_float == val->m_type ) { - m_metrics[ type ].m_floatValue = val->getFloat(); - } else if( Value::ddl_int32 == val->m_type ) { - m_metrics[ type ].m_intValue = val->getInt32(); - } else if( Value::ddl_string == val->m_type ) { - m_metrics[type].m_stringValue = std::string( val->getString() ); + Property *prop(node->getProperties()); + while (nullptr != prop) { + if (nullptr != prop->m_key) { + if (Value::ValueType::ddl_string == prop->m_value->m_type) { + std::string valName((char *)prop->m_value->m_data); + int type(Grammar::isValidMetricType(valName.c_str())); + if (Grammar::NoneType != type) { + Value *val(node->getValue()); + if (nullptr != val) { + if (Value::ValueType::ddl_float == val->m_type) { + m_metrics[type].m_floatValue = val->getFloat(); + } else if (Value::ValueType::ddl_int32 == val->m_type) { + m_metrics[type].m_intValue = val->getInt32(); + } else if (Value::ValueType::ddl_string == val->m_type) { + m_metrics[type].m_stringValue = std::string(val->getString()); } else { - throw DeadlyImportError( "OpenGEX: invalid data type for Metric node." ); + throw DeadlyImportError("OpenGEX: invalid data type for Metric node."); } } } @@ -467,48 +463,47 @@ void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene * /*pScene*/ ) { } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene * /*pScene*/ ) { - if( nullptr == m_currentNode ) { - throw DeadlyImportError( "No current node for name." ); +void OpenGEXImporter::handleNameNode(DDLNode *node, aiScene * /*pScene*/) { + if (nullptr == m_currentNode) { + throw DeadlyImportError("No current node for name."); return; } - Value *val( node->getValue() ); - if( nullptr != val ) { - if( Value::ddl_string != val->m_type ) { - throw DeadlyImportError( "OpenGEX: invalid data type for value in node name." ); + Value *val(node->getValue()); + if (nullptr != val) { + if (Value::ValueType::ddl_string != val->m_type) { + throw DeadlyImportError("OpenGEX: invalid data type for value in node name."); return; } - const std::string name( val->getString() ); - if( m_tokenType == Grammar::GeometryNodeToken || m_tokenType == Grammar::LightNodeToken - || m_tokenType == Grammar::CameraNodeToken ) { - m_currentNode->mName.Set( name.c_str() ); - } else if( m_tokenType == Grammar::MaterialToken ) { + const std::string name(val->getString()); + if (m_tokenType == Grammar::GeometryNodeToken || m_tokenType == Grammar::LightNodeToken || m_tokenType == Grammar::CameraNodeToken) { + m_currentNode->mName.Set(name.c_str()); + } else if (m_tokenType == Grammar::MaterialToken) { aiString aiName; - aiName.Set( name ); - m_currentMaterial->AddProperty( &aiName, AI_MATKEY_NAME ); - m_material2refMap[ name ] = m_materialCache.size() - 1; + aiName.Set(name); + m_currentMaterial->AddProperty(&aiName, AI_MATKEY_NAME); + m_material2refMap[name] = m_materialCache.size() - 1; } } } //------------------------------------------------------------------------------------------------ -static void getRefNames( DDLNode *node, std::vector &names ) { - ai_assert( nullptr != node ); +static void getRefNames(DDLNode *node, std::vector &names) { + ai_assert(nullptr != node); Reference *ref = node->getReferences(); - if( nullptr != ref ) { - for( size_t i = 0; i < ref->m_numRefs; i++ ) { - Name *currentName( ref->m_referencedName[ i ] ); - if( nullptr != currentName && nullptr != currentName->m_id ) { + if (nullptr != ref) { + for (size_t i = 0; i < ref->m_numRefs; i++) { + Name *currentName(ref->m_referencedName[i]); + if (nullptr != currentName && nullptr != currentName->m_id) { #ifdef ASSIMP_USE_HUNTER - const std::string name( currentName->m_id->m_text.m_buffer ); + const std::string name(currentName->m_id->m_text.m_buffer); #else - const std::string name( currentName->m_id->m_buffer ); + const std::string name(currentName->m_id->m_buffer); #endif - if( !name.empty() ) { - names.push_back( name ); + if (!name.empty()) { + names.push_back(name); } } } @@ -516,218 +511,218 @@ static void getRefNames( DDLNode *node, std::vector &names ) { } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene * /*pScene*/ ) { - if( nullptr == m_currentNode ) { - throw DeadlyImportError( "No parent node for name." ); +void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) { + if (nullptr == m_currentNode) { + throw DeadlyImportError("No parent node for name."); return; } std::vector objRefNames; - getRefNames( node, objRefNames ); + getRefNames(node, objRefNames); // when we are dealing with a geometry node prepare the mesh cache - if ( m_tokenType == Grammar::GeometryNodeToken ) { + if (m_tokenType == Grammar::GeometryNodeToken) { m_currentNode->mNumMeshes = static_cast(objRefNames.size()); - m_currentNode->mMeshes = new unsigned int[ objRefNames.size() ]; - if ( !objRefNames.empty() ) { - m_unresolvedRefStack.push_back( std::unique_ptr( new RefInfo( m_currentNode, RefInfo::MeshRef, objRefNames ) ) ); + m_currentNode->mMeshes = new unsigned int[objRefNames.size()]; + if (!objRefNames.empty()) { + m_unresolvedRefStack.push_back(std::unique_ptr(new RefInfo(m_currentNode, RefInfo::MeshRef, objRefNames))); } - } else if ( m_tokenType == Grammar::LightNodeToken ) { + } else if (m_tokenType == Grammar::LightNodeToken) { // TODO! - } else if ( m_tokenType == Grammar::CameraNodeToken ) { + } else if (m_tokenType == Grammar::CameraNodeToken) { // TODO! } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) { - if( nullptr == m_currentNode ) { - throw DeadlyImportError( "No parent node for name." ); +void OpenGEXImporter::handleMaterialRefNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { + if (nullptr == m_currentNode) { + throw DeadlyImportError("No parent node for name."); return; } std::vector matRefNames; - getRefNames( node, matRefNames ); - if( !matRefNames.empty() ) { - m_unresolvedRefStack.push_back( std::unique_ptr( new RefInfo( m_currentNode, RefInfo::MaterialRef, matRefNames ) ) ); + getRefNames(node, matRefNames); + if (!matRefNames.empty()) { + m_unresolvedRefStack.push_back(std::unique_ptr(new RefInfo(m_currentNode, RefInfo::MaterialRef, matRefNames))); } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleGeometryNode( DDLNode *node, aiScene *pScene ) { +void OpenGEXImporter::handleGeometryNode(DDLNode *node, aiScene *pScene) { aiNode *newNode = new aiNode; - pushNode( newNode, pScene ); + pushNode(newNode, pScene); m_tokenType = Grammar::GeometryNodeToken; m_currentNode = newNode; - handleNodes( node, pScene ); + handleNodes(node, pScene); popNode(); } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleCameraNode( DDLNode *node, aiScene *pScene ) { - aiCamera *camera( new aiCamera ); - m_cameraCache.push_back( camera ); +void OpenGEXImporter::handleCameraNode(DDLNode *node, aiScene *pScene) { + aiCamera *camera(new aiCamera); + m_cameraCache.push_back(camera); m_currentCamera = camera; aiNode *newNode = new aiNode; - pushNode( newNode, pScene ); + pushNode(newNode, pScene); m_tokenType = Grammar::CameraNodeToken; m_currentNode = newNode; - handleNodes( node, pScene ); + handleNodes(node, pScene); popNode(); - m_currentCamera->mName.Set( newNode->mName.C_Str() ); + m_currentCamera->mName.Set(newNode->mName.C_Str()); } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleLightNode( ODDLParser::DDLNode *node, aiScene *pScene ) { - aiLight *light( new aiLight ); - m_lightCache.push_back( light ); +void OpenGEXImporter::handleLightNode(ODDLParser::DDLNode *node, aiScene *pScene) { + aiLight *light(new aiLight); + m_lightCache.push_back(light); m_currentLight = light; aiNode *newNode = new aiNode; m_tokenType = Grammar::LightNodeToken; m_currentNode = newNode; - pushNode( newNode, pScene ); + pushNode(newNode, pScene); - handleNodes( node, pScene ); + handleNodes(node, pScene); popNode(); - m_currentLight->mName.Set( newNode->mName.C_Str() ); + m_currentLight->mName.Set(newNode->mName.C_Str()); } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleGeometryObject( DDLNode *node, aiScene *pScene ) { +void OpenGEXImporter::handleGeometryObject(DDLNode *node, aiScene *pScene) { // parameters will be parsed normally in the tree, so just go for it - handleNodes( node, pScene ); + handleNodes(node, pScene); } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleCameraObject( ODDLParser::DDLNode *node, aiScene *pScene ) { +void OpenGEXImporter::handleCameraObject(ODDLParser::DDLNode *node, aiScene *pScene) { // parameters will be parsed normally in the tree, so just go for it - handleNodes( node, pScene ); + handleNodes(node, pScene); } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleLightObject( ODDLParser::DDLNode *node, aiScene *pScene ) { - aiLight *light( new aiLight ); - m_lightCache.push_back( light ); +void OpenGEXImporter::handleLightObject(ODDLParser::DDLNode *node, aiScene *pScene) { + aiLight *light(new aiLight); + m_lightCache.push_back(light); std::string objName = node->getName(); - if ( !objName.empty() ) { - light->mName.Set( objName ); + if (!objName.empty()) { + light->mName.Set(objName); } m_currentLight = light; - Property *prop( node->findPropertyByName( "type" ) ); - if ( nullptr != prop ) { - if ( nullptr != prop->m_value ) { - std::string typeStr( prop->m_value->getString() ); - if ( "point" == typeStr ) { + Property *prop(node->findPropertyByName("type")); + if (nullptr != prop) { + if (nullptr != prop->m_value) { + std::string typeStr(prop->m_value->getString()); + if ("point" == typeStr) { m_currentLight->mType = aiLightSource_POINT; - } else if ( "spot" == typeStr ) { + } else if ("spot" == typeStr) { m_currentLight->mType = aiLightSource_SPOT; - } else if ( "infinite" == typeStr ) { + } else if ("infinite" == typeStr) { m_currentLight->mType = aiLightSource_DIRECTIONAL; } } } // parameters will be parsed normally in the tree, so just go for it - handleNodes( node, pScene ); + handleNodes(node, pScene); } //------------------------------------------------------------------------------------------------ -static void setMatrix( aiNode *node, DataArrayList *transformData ) { - ai_assert( nullptr != node ); - ai_assert( nullptr != transformData ); +static void setMatrix(aiNode *node, DataArrayList *transformData) { + ai_assert(nullptr != node); + ai_assert(nullptr != transformData); - float m[ 16 ]; - size_t i( 1 ); - Value *next( transformData->m_dataList->m_next ); - m[ 0 ] = transformData->m_dataList->getFloat(); - while( next != nullptr ) { - m[ i ] = next->getFloat(); + float m[16]; + size_t i(1); + Value *next(transformData->m_dataList->m_next); + m[0] = transformData->m_dataList->getFloat(); + while (next != nullptr) { + m[i] = next->getFloat(); next = next->m_next; i++; } ai_assert(i == 16); - node->mTransformation.a1 = m[ 0 ]; - node->mTransformation.a2 = m[ 4 ]; - node->mTransformation.a3 = m[ 8 ]; - node->mTransformation.a4 = m[ 12 ]; + node->mTransformation.a1 = m[0]; + node->mTransformation.a2 = m[4]; + node->mTransformation.a3 = m[8]; + node->mTransformation.a4 = m[12]; - node->mTransformation.b1 = m[ 1 ]; - node->mTransformation.b2 = m[ 5 ]; - node->mTransformation.b3 = m[ 9 ]; - node->mTransformation.b4 = m[ 13 ]; + node->mTransformation.b1 = m[1]; + node->mTransformation.b2 = m[5]; + node->mTransformation.b3 = m[9]; + node->mTransformation.b4 = m[13]; - node->mTransformation.c1 = m[ 2 ]; - node->mTransformation.c2 = m[ 6 ]; - node->mTransformation.c3 = m[ 10 ]; - node->mTransformation.c4 = m[ 14 ]; + node->mTransformation.c1 = m[2]; + node->mTransformation.c2 = m[6]; + node->mTransformation.c3 = m[10]; + node->mTransformation.c4 = m[14]; - node->mTransformation.d1 = m[ 3 ]; - node->mTransformation.d2 = m[ 7 ]; - node->mTransformation.d3 = m[ 11 ]; - node->mTransformation.d4 = m[ 15 ]; + node->mTransformation.d1 = m[3]; + node->mTransformation.d2 = m[7]; + node->mTransformation.d3 = m[11]; + node->mTransformation.d4 = m[15]; } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleTransformNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) { - if( nullptr == m_currentNode ) { - throw DeadlyImportError( "No parent node for name." ); +void OpenGEXImporter::handleTransformNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { + if (nullptr == m_currentNode) { + throw DeadlyImportError("No parent node for name."); return; } - DataArrayList *transformData( node->getDataArrayList() ); - if( nullptr != transformData ) { - if( transformData->m_numItems != 16 ) { - throw DeadlyImportError( "Invalid number of data for transform matrix." ); + DataArrayList *transformData(node->getDataArrayList()); + if (nullptr != transformData) { + if (transformData->m_numItems != 16) { + throw DeadlyImportError("Invalid number of data for transform matrix."); return; } - setMatrix( m_currentNode, transformData ); + setMatrix(m_currentNode, transformData); } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene ) { +void OpenGEXImporter::handleMeshNode(ODDLParser::DDLNode *node, aiScene *pScene) { m_currentMesh = new aiMesh; - const size_t meshidx( m_meshCache.size() ); + const size_t meshidx(m_meshCache.size()); // ownership is transferred but a reference remains in m_currentMesh - m_meshCache.emplace_back( m_currentMesh ); + m_meshCache.emplace_back(m_currentMesh); Property *prop = node->getProperties(); - if( nullptr != prop ) { + if (nullptr != prop) { std::string propName, propKey; - propId2StdString( prop, propName, propKey ); - if( "primitive" == propName ) { - if ( "points" == propKey ) { + propId2StdString(prop, propName, propKey); + if ("primitive" == propName) { + if ("points" == propKey) { m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; - } else if ( "lines" == propKey ) { + } else if ("lines" == propKey) { m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_LINE; - } else if( "triangles" == propKey ) { + } else if ("triangles" == propKey) { m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; - } else if ( "quads" == propKey ) { + } else if ("quads" == propKey) { m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; } else { - ASSIMP_LOG_WARN_F( propKey, " is not supported primitive type." ); + ASSIMP_LOG_WARN_F(propKey, " is not supported primitive type."); } } } - handleNodes( node, pScene ); + handleNodes(node, pScene); - DDLNode *parent( node->getParent() ); - if( nullptr != parent ) { + DDLNode *parent(node->getParent()); + if (nullptr != parent) { const std::string &name = parent->getName(); - m_mesh2refMap[ name ] = meshidx; + m_mesh2refMap[name] = meshidx; } } @@ -746,16 +741,16 @@ static const std::string NormalToken = "normal"; static const std::string TexCoordToken = "texcoord"; //------------------------------------------------------------------------------------------------ -static MeshAttribute getAttributeByName( const char *attribName ) { - ai_assert( nullptr != attribName ); +static MeshAttribute getAttributeByName(const char *attribName) { + ai_assert(nullptr != attribName); - if ( 0 == strncmp( PosToken.c_str(), attribName, PosToken.size() ) ) { + if (0 == strncmp(PosToken.c_str(), attribName, PosToken.size())) { return Position; - } else if ( 0 == strncmp( ColToken.c_str(), attribName, ColToken.size() ) ) { + } else if (0 == strncmp(ColToken.c_str(), attribName, ColToken.size())) { return Color; - } else if( 0 == strncmp( NormalToken.c_str(), attribName, NormalToken.size() ) ) { + } else if (0 == strncmp(NormalToken.c_str(), attribName, NormalToken.size())) { return Normal; - } else if( 0 == strncmp( TexCoordToken.c_str(), attribName, TexCoordToken.size() ) ) { + } else if (0 == strncmp(TexCoordToken.c_str(), attribName, TexCoordToken.size())) { return TexCoord; } @@ -763,60 +758,60 @@ static MeshAttribute getAttributeByName( const char *attribName ) { } //------------------------------------------------------------------------------------------------ -static void fillVector3( aiVector3D *vec3, Value *vals ) { - ai_assert( nullptr != vec3 ); - ai_assert( nullptr != vals ); +static void fillVector3(aiVector3D *vec3, Value *vals) { + ai_assert(nullptr != vec3); + ai_assert(nullptr != vals); - float x( 0.0f ), y( 0.0f ), z( 0.0f ); - Value *next( vals ); + float x(0.0f), y(0.0f), z(0.0f); + Value *next(vals); x = next->getFloat(); next = next->m_next; y = next->getFloat(); next = next->m_next; - if( nullptr != next ) { + if (nullptr != next) { z = next->getFloat(); } - vec3->Set( x, y, z ); + vec3->Set(x, y, z); } //------------------------------------------------------------------------------------------------ -static void fillColor4( aiColor4D *col4, Value *vals ) { - ai_assert( nullptr != col4 ); - ai_assert( nullptr != vals ); +static void fillColor4(aiColor4D *col4, Value *vals) { + ai_assert(nullptr != col4); + ai_assert(nullptr != vals); - Value *next( vals ); + Value *next(vals); col4->r = next->getFloat(); next = next->m_next; if (!next) { - throw DeadlyImportError( "OpenGEX: Not enough values to fill 4-element color, only 1" ); + throw DeadlyImportError("OpenGEX: Not enough values to fill 4-element color, only 1"); } col4->g = next->getFloat(); next = next->m_next; if (!next) { - throw DeadlyImportError( "OpenGEX: Not enough values to fill 4-element color, only 2" ); + throw DeadlyImportError("OpenGEX: Not enough values to fill 4-element color, only 2"); } col4->b = next->getFloat(); next = next->m_next; if (!next) { - throw DeadlyImportError( "OpenGEX: Not enough values to fill 4-element color, only 3" ); + throw DeadlyImportError("OpenGEX: Not enough values to fill 4-element color, only 3"); } col4->a = next->getFloat(); } //------------------------------------------------------------------------------------------------ -static size_t countDataArrayListItems( DataArrayList *vaList ) { - size_t numItems( 0 ); - if( nullptr == vaList ) { +static size_t countDataArrayListItems(DataArrayList *vaList) { + size_t numItems(0); + if (nullptr == vaList) { return numItems; } - DataArrayList *next( vaList ); - while( nullptr != next ) { - if( nullptr != vaList->m_dataList ) { + DataArrayList *next(vaList); + while (nullptr != next) { + if (nullptr != vaList->m_dataList) { numItems++; } next = next->m_next; @@ -826,126 +821,126 @@ static size_t countDataArrayListItems( DataArrayList *vaList ) { } //------------------------------------------------------------------------------------------------ -static void copyVectorArray( size_t numItems, DataArrayList *vaList, aiVector3D *vectorArray ) { - for( size_t i = 0; i < numItems; i++ ) { - Value *next( vaList->m_dataList ); - fillVector3( &vectorArray[ i ], next ); +static void copyVectorArray(size_t numItems, DataArrayList *vaList, aiVector3D *vectorArray) { + for (size_t i = 0; i < numItems; i++) { + Value *next(vaList->m_dataList); + fillVector3(&vectorArray[i], next); vaList = vaList->m_next; } } //------------------------------------------------------------------------------------------------ -static void copyColor4DArray( size_t numItems, DataArrayList *vaList, aiColor4D *colArray ) { - for ( size_t i = 0; i < numItems; i++ ) { - Value *next( vaList->m_dataList ); - fillColor4( &colArray[ i ], next ); +static void copyColor4DArray(size_t numItems, DataArrayList *vaList, aiColor4D *colArray) { + for (size_t i = 0; i < numItems; i++) { + Value *next(vaList->m_dataList); + fillColor4(&colArray[i], next); } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) { - if( nullptr == node ) { - throw DeadlyImportError( "No parent node for name." ); +void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { + if (nullptr == node) { + throw DeadlyImportError("No parent node for name."); return; } - Property *prop( node->getProperties() ); - if( nullptr != prop ) { + Property *prop(node->getProperties()); + if (nullptr != prop) { std::string propName, propKey; - propId2StdString( prop, propName, propKey ); - MeshAttribute attribType( getAttributeByName( propKey.c_str() ) ); - if( None == attribType ) { + propId2StdString(prop, propName, propKey); + MeshAttribute attribType(getAttributeByName(propKey.c_str())); + if (None == attribType) { return; } DataArrayList *vaList = node->getDataArrayList(); - if( nullptr == vaList ) { + if (nullptr == vaList) { return; } - const size_t numItems( countDataArrayListItems( vaList ) ); + const size_t numItems(countDataArrayListItems(vaList)); - if( Position == attribType ) { - m_currentVertices.m_vertices.resize( numItems ); - copyVectorArray( numItems, vaList, m_currentVertices.m_vertices.data() ); - } else if ( Color == attribType ) { + if (Position == attribType) { + m_currentVertices.m_vertices.resize(numItems); + copyVectorArray(numItems, vaList, m_currentVertices.m_vertices.data()); + } else if (Color == attribType) { m_currentVertices.m_numColors = numItems; - m_currentVertices.m_colors = new aiColor4D[ numItems ]; - copyColor4DArray( numItems, vaList, m_currentVertices.m_colors ); - } else if( Normal == attribType ) { - m_currentVertices.m_normals.resize( numItems ); - copyVectorArray( numItems, vaList, m_currentVertices.m_normals.data() ); - } else if( TexCoord == attribType ) { - m_currentVertices.m_numUVComps[ 0 ] = numItems; - m_currentVertices.m_textureCoords[ 0 ] = new aiVector3D[ numItems ]; - copyVectorArray( numItems, vaList, m_currentVertices.m_textureCoords[ 0 ] ); + m_currentVertices.m_colors = new aiColor4D[numItems]; + copyColor4DArray(numItems, vaList, m_currentVertices.m_colors); + } else if (Normal == attribType) { + m_currentVertices.m_normals.resize(numItems); + copyVectorArray(numItems, vaList, m_currentVertices.m_normals.data()); + } else if (TexCoord == attribType) { + m_currentVertices.m_numUVComps[0] = numItems; + m_currentVertices.m_textureCoords[0] = new aiVector3D[numItems]; + copyVectorArray(numItems, vaList, m_currentVertices.m_textureCoords[0]); } } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) { - if( nullptr == node ) { - throw DeadlyImportError( "No parent node for name." ); +void OpenGEXImporter::handleIndexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { + if (nullptr == node) { + throw DeadlyImportError("No parent node for name."); return; } - if( nullptr == m_currentMesh ) { - throw DeadlyImportError( "No current mesh for index data found." ); + if (nullptr == m_currentMesh) { + throw DeadlyImportError("No current mesh for index data found."); return; } DataArrayList *vaList = node->getDataArrayList(); - if( nullptr == vaList ) { + if (nullptr == vaList) { return; } - const size_t numItems( countDataArrayListItems( vaList ) ); + const size_t numItems(countDataArrayListItems(vaList)); m_currentMesh->mNumFaces = static_cast(numItems); - m_currentMesh->mFaces = new aiFace[ numItems ]; + m_currentMesh->mFaces = new aiFace[numItems]; m_currentMesh->mNumVertices = static_cast(numItems * 3); - m_currentMesh->mVertices = new aiVector3D[ m_currentMesh->mNumVertices ]; - bool hasColors( false ); - if ( m_currentVertices.m_numColors > 0 ) { - m_currentMesh->mColors[0] = new aiColor4D[ m_currentVertices.m_numColors ]; + m_currentMesh->mVertices = new aiVector3D[m_currentMesh->mNumVertices]; + bool hasColors(false); + if (m_currentVertices.m_numColors > 0) { + m_currentMesh->mColors[0] = new aiColor4D[m_currentVertices.m_numColors]; hasColors = true; } - bool hasNormalCoords( false ); - if ( !m_currentVertices.m_normals.empty() ) { - m_currentMesh->mNormals = new aiVector3D[ m_currentMesh->mNumVertices ]; + bool hasNormalCoords(false); + if (!m_currentVertices.m_normals.empty()) { + m_currentMesh->mNormals = new aiVector3D[m_currentMesh->mNumVertices]; hasNormalCoords = true; } - bool hasTexCoords( false ); - if ( m_currentVertices.m_numUVComps[ 0 ] > 0 ) { - m_currentMesh->mTextureCoords[ 0 ] = new aiVector3D[ m_currentMesh->mNumVertices ]; + bool hasTexCoords(false); + if (m_currentVertices.m_numUVComps[0] > 0) { + m_currentMesh->mTextureCoords[0] = new aiVector3D[m_currentMesh->mNumVertices]; hasTexCoords = true; } - unsigned int index( 0 ); - for( size_t i = 0; i < m_currentMesh->mNumFaces; i++ ) { - aiFace ¤t( m_currentMesh->mFaces[ i ] ); + unsigned int index(0); + for (size_t i = 0; i < m_currentMesh->mNumFaces; i++) { + aiFace ¤t(m_currentMesh->mFaces[i]); current.mNumIndices = 3; - current.mIndices = new unsigned int[ current.mNumIndices ]; - Value *next( vaList->m_dataList ); - for( size_t indices = 0; indices < current.mNumIndices; indices++ ) { - const int idx( next->getUnsignedInt32() ); - ai_assert( static_cast( idx ) <= m_currentVertices.m_vertices.size() ); - ai_assert( index < m_currentMesh->mNumVertices ); - aiVector3D &pos = ( m_currentVertices.m_vertices[ idx ] ); - m_currentMesh->mVertices[ index ].Set( pos.x, pos.y, pos.z ); - if ( hasColors ) { - aiColor4D &col = m_currentVertices.m_colors[ idx ]; - m_currentMesh->mColors[ 0 ][ index ] = col; + current.mIndices = new unsigned int[current.mNumIndices]; + Value *next(vaList->m_dataList); + for (size_t indices = 0; indices < current.mNumIndices; indices++) { + const int idx(next->getUnsignedInt32()); + ai_assert(static_cast(idx) <= m_currentVertices.m_vertices.size()); + ai_assert(index < m_currentMesh->mNumVertices); + aiVector3D &pos = (m_currentVertices.m_vertices[idx]); + m_currentMesh->mVertices[index].Set(pos.x, pos.y, pos.z); + if (hasColors) { + aiColor4D &col = m_currentVertices.m_colors[idx]; + m_currentMesh->mColors[0][index] = col; } - if ( hasNormalCoords ) { - aiVector3D &normal = ( m_currentVertices.m_normals[ idx ] ); - m_currentMesh->mNormals[ index ].Set( normal.x, normal.y, normal.z ); + if (hasNormalCoords) { + aiVector3D &normal = (m_currentVertices.m_normals[idx]); + m_currentMesh->mNormals[index].Set(normal.x, normal.y, normal.z); } - if ( hasTexCoords ) { - aiVector3D &tex = ( m_currentVertices.m_textureCoords[ 0 ][ idx ] ); - m_currentMesh->mTextureCoords[ 0 ][ index ].Set( tex.x, tex.y, tex.z ); + if (hasTexCoords) { + aiVector3D &tex = (m_currentVertices.m_textureCoords[0][idx]); + m_currentMesh->mTextureCoords[0][index].Set(tex.x, tex.y, tex.z); } - current.mIndices[ indices ] = index; + current.mIndices[indices] = index; index++; next = next->m_next; @@ -955,13 +950,13 @@ void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene * } //------------------------------------------------------------------------------------------------ -static void getColorRGB3( aiColor3D *pColor, DataArrayList *colList ) { - if( nullptr == pColor || nullptr == colList ) { +static void getColorRGB3(aiColor3D *pColor, DataArrayList *colList) { + if (nullptr == pColor || nullptr == colList) { return; } - ai_assert( 3 == colList->m_numItems ); - Value *val( colList->m_dataList ); + ai_assert(3 == colList->m_numItems); + Value *val(colList->m_dataList); pColor->r = val->getFloat(); val = val->getNext(); pColor->g = val->getFloat(); @@ -970,13 +965,13 @@ static void getColorRGB3( aiColor3D *pColor, DataArrayList *colList ) { } //------------------------------------------------------------------------------------------------ -static void getColorRGB4( aiColor4D *pColor, DataArrayList *colList ) { - if ( nullptr == pColor || nullptr == colList ) { +static void getColorRGB4(aiColor4D *pColor, DataArrayList *colList) { + if (nullptr == pColor || nullptr == colList) { return; } - ai_assert( 4 == colList->m_numItems ); - Value *val( colList->m_dataList ); + ai_assert(4 == colList->m_numItems); + Value *val(colList->m_dataList); pColor->r = val->getFloat(); val = val->getNext(); pColor->g = val->getFloat(); @@ -996,18 +991,18 @@ enum ColorType { }; //------------------------------------------------------------------------------------------------ -static ColorType getColorType( Text *id ) { - if ( nullptr == id ) { +static ColorType getColorType(Text *id) { + if (nullptr == id) { return NoneColor; } - if( *id == Grammar::DiffuseColorToken ) { + if (*id == Grammar::DiffuseColorToken) { return DiffuseColor; - } else if( *id == Grammar::SpecularColorToken ) { + } else if (*id == Grammar::SpecularColorToken) { return SpecularColor; - } else if( *id == Grammar::EmissionColorToken ) { + } else if (*id == Grammar::EmissionColorToken) { return EmissionColor; - } else if ( *id == "light" ) { + } else if (*id == "light") { return LightColor; } @@ -1015,50 +1010,50 @@ static ColorType getColorType( Text *id ) { } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleMaterialNode( ODDLParser::DDLNode *node, aiScene *pScene ) { +void OpenGEXImporter::handleMaterialNode(ODDLParser::DDLNode *node, aiScene *pScene) { m_currentMaterial = new aiMaterial; - m_materialCache.push_back( m_currentMaterial ); + m_materialCache.push_back(m_currentMaterial); m_tokenType = Grammar::MaterialToken; - handleNodes( node, pScene ); + handleNodes(node, pScene); } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleColorNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) { - if( nullptr == node ) { +void OpenGEXImporter::handleColorNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { + if (nullptr == node) { return; } - Property *prop = node->findPropertyByName( "attrib" ); - if( nullptr != prop ) { - if( nullptr != prop->m_value ) { - DataArrayList *colList( node->getDataArrayList() ); - if( nullptr == colList ) { + Property *prop = node->findPropertyByName("attrib"); + if (nullptr != prop) { + if (nullptr != prop->m_value) { + DataArrayList *colList(node->getDataArrayList()); + if (nullptr == colList) { return; } aiColor3D col; - if ( 3 == colList->m_numItems ) { + if (3 == colList->m_numItems) { aiColor3D col3; - getColorRGB3( &col3, colList ); + getColorRGB3(&col3, colList); col = col3; } else { aiColor4D col4; - getColorRGB4( &col4, colList ); + getColorRGB4(&col4, colList); col.r = col4.r; col.g = col4.g; col.b = col4.b; } #ifdef ASSIMP_USE_HUNTER - const ColorType colType( getColorType( &prop->m_key->m_text ) ); + const ColorType colType(getColorType(&prop->m_key->m_text)); #else - const ColorType colType( getColorType( prop->m_key ) ); + const ColorType colType(getColorType(prop->m_key)); #endif - if( DiffuseColor == colType ) { - m_currentMaterial->AddProperty( &col, 1, AI_MATKEY_COLOR_DIFFUSE ); - } else if( SpecularColor == colType ) { - m_currentMaterial->AddProperty( &col, 1, AI_MATKEY_COLOR_SPECULAR ); - } else if( EmissionColor == colType ) { - m_currentMaterial->AddProperty( &col, 1, AI_MATKEY_COLOR_EMISSIVE ); - } else if ( LightColor == colType ) { + if (DiffuseColor == colType) { + m_currentMaterial->AddProperty(&col, 1, AI_MATKEY_COLOR_DIFFUSE); + } else if (SpecularColor == colType) { + m_currentMaterial->AddProperty(&col, 1, AI_MATKEY_COLOR_SPECULAR); + } else if (EmissionColor == colType) { + m_currentMaterial->AddProperty(&col, 1, AI_MATKEY_COLOR_EMISSIVE); + } else if (LightColor == colType) { m_currentLight->mColorDiffuse = col; } } @@ -1066,33 +1061,33 @@ void OpenGEXImporter::handleColorNode( ODDLParser::DDLNode *node, aiScene * /*pS } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) { - if( nullptr == node ) { +void OpenGEXImporter::handleTextureNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { + if (nullptr == node) { return; } - Property *prop = node->findPropertyByName( "attrib" ); - if( nullptr != prop ) { - if( nullptr != prop->m_value ) { - Value *val( node->getValue() ); - if( nullptr != val ) { + Property *prop = node->findPropertyByName("attrib"); + if (nullptr != prop) { + if (nullptr != prop->m_value) { + Value *val(node->getValue()); + if (nullptr != val) { aiString tex; - tex.Set( val->getString() ); - if( prop->m_value->getString() == Grammar::DiffuseTextureToken ) { - m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) ); - } else if( prop->m_value->getString() == Grammar::SpecularPowerTextureToken ) { - m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR( 0 ) ); - } else if( prop->m_value->getString() == Grammar::EmissionTextureToken ) { - m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE( 0 ) ); - } else if( prop->m_value->getString() == Grammar::OpacyTextureToken ) { - m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_OPACITY( 0 ) ); - } else if( prop->m_value->getString() == Grammar::TransparencyTextureToken ) { + tex.Set(val->getString()); + if (prop->m_value->getString() == Grammar::DiffuseTextureToken) { + m_currentMaterial->AddProperty(&tex, AI_MATKEY_TEXTURE_DIFFUSE(0)); + } else if (prop->m_value->getString() == Grammar::SpecularPowerTextureToken) { + m_currentMaterial->AddProperty(&tex, AI_MATKEY_TEXTURE_SPECULAR(0)); + } else if (prop->m_value->getString() == Grammar::EmissionTextureToken) { + m_currentMaterial->AddProperty(&tex, AI_MATKEY_TEXTURE_EMISSIVE(0)); + } else if (prop->m_value->getString() == Grammar::OpacyTextureToken) { + m_currentMaterial->AddProperty(&tex, AI_MATKEY_TEXTURE_OPACITY(0)); + } else if (prop->m_value->getString() == Grammar::TransparencyTextureToken) { // ToDo! // m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) ); - } else if( prop->m_value->getString() == Grammar::NormalTextureToken ) { - m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS( 0 ) ); + } else if (prop->m_value->getString() == Grammar::NormalTextureToken) { + m_currentMaterial->AddProperty(&tex, AI_MATKEY_TEXTURE_NORMALS(0)); } else { - ai_assert( false ); + ai_assert(false); } } } @@ -1100,44 +1095,44 @@ void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene * /* } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleParamNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) { - if ( nullptr == node ) { +void OpenGEXImporter::handleParamNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { + if (nullptr == node) { return; } - Property *prop = node->findPropertyByName( "attrib" ); - if ( nullptr == prop ) { + Property *prop = node->findPropertyByName("attrib"); + if (nullptr == prop) { return; } - if ( nullptr != prop->m_value ) { - Value *val( node->getValue() ); - if ( nullptr == val ) { + if (nullptr != prop->m_value) { + Value *val(node->getValue()); + if (nullptr == val) { return; } - const float floatVal( val->getFloat() ); - if ( 0 == ASSIMP_strincmp( "fov", prop->m_value->getString(), 3 ) ) { + const float floatVal(val->getFloat()); + if (0 == ASSIMP_strincmp("fov", prop->m_value->getString(), 3)) { m_currentCamera->mHorizontalFOV = floatVal; - } else if ( 0 == ASSIMP_strincmp( "near", prop->m_value->getString(), 4 ) ) { + } else if (0 == ASSIMP_strincmp("near", prop->m_value->getString(), 4)) { m_currentCamera->mClipPlaneNear = floatVal; - } else if ( 0 == ASSIMP_strincmp( "far", prop->m_value->getString(), 3 ) ) { + } else if (0 == ASSIMP_strincmp("far", prop->m_value->getString(), 3)) { m_currentCamera->mClipPlaneFar = floatVal; } } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::handleAttenNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) { - if ( nullptr == node ) { +void OpenGEXImporter::handleAttenNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) { + if (nullptr == node) { return; } - Property *prop = node->findPropertyByName( "curve" ); - if ( nullptr != prop ) { - if ( nullptr != prop->m_value ) { - Value *val( node->getValue() ); - const float floatVal( val->getFloat() ); - if ( 0 == strncmp( "scale", prop->m_value->getString(), strlen( "scale" ) ) ) { + Property *prop = node->findPropertyByName("curve"); + if (nullptr != prop) { + if (nullptr != prop->m_value) { + Value *val(node->getValue()); + const float floatVal(val->getFloat()); + if (0 == strncmp("scale", prop->m_value->getString(), strlen("scale"))) { m_currentLight->mAttenuationQuadratic = floatVal; } } @@ -1145,160 +1140,160 @@ void OpenGEXImporter::handleAttenNode( ODDLParser::DDLNode *node, aiScene * /*pS } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::copyMeshes( aiScene *pScene ) { - ai_assert( nullptr != pScene ); +void OpenGEXImporter::copyMeshes(aiScene *pScene) { + ai_assert(nullptr != pScene); - if( m_meshCache.empty() ) { + if (m_meshCache.empty()) { return; } pScene->mNumMeshes = static_cast(m_meshCache.size()); - pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ]; + pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; for (unsigned int i = 0; i < pScene->mNumMeshes; i++) { pScene->mMeshes[i] = m_meshCache[i].release(); } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::copyCameras( aiScene *pScene ) { - ai_assert( nullptr != pScene ); +void OpenGEXImporter::copyCameras(aiScene *pScene) { + ai_assert(nullptr != pScene); - if ( m_cameraCache.empty() ) { + if (m_cameraCache.empty()) { return; } pScene->mNumCameras = static_cast(m_cameraCache.size()); - pScene->mCameras = new aiCamera*[ pScene->mNumCameras ]; - std::copy( m_cameraCache.begin(), m_cameraCache.end(), pScene->mCameras ); + pScene->mCameras = new aiCamera *[pScene->mNumCameras]; + std::copy(m_cameraCache.begin(), m_cameraCache.end(), pScene->mCameras); } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::copyLights( aiScene *pScene ) { - ai_assert( nullptr != pScene ); +void OpenGEXImporter::copyLights(aiScene *pScene) { + ai_assert(nullptr != pScene); - if ( m_lightCache.empty() ) { + if (m_lightCache.empty()) { return; } pScene->mNumLights = static_cast(m_lightCache.size()); - pScene->mLights = new aiLight*[ pScene->mNumLights ]; - std::copy( m_lightCache.begin(), m_lightCache.end(), pScene->mLights ); + pScene->mLights = new aiLight *[pScene->mNumLights]; + std::copy(m_lightCache.begin(), m_lightCache.end(), pScene->mLights); } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::copyMaterials( aiScene *pScene ) { - ai_assert( nullptr != pScene ); +void OpenGEXImporter::copyMaterials(aiScene *pScene) { + ai_assert(nullptr != pScene); - if ( m_materialCache.empty() ) { + if (m_materialCache.empty()) { return; } pScene->mNumMaterials = static_cast(m_materialCache.size()); - pScene->mMaterials = new aiMaterial*[ pScene->mNumMaterials ]; - std::copy( m_materialCache.begin(), m_materialCache.end(), pScene->mMaterials ); + pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials]; + std::copy(m_materialCache.begin(), m_materialCache.end(), pScene->mMaterials); } //------------------------------------------------------------------------------------------------ void OpenGEXImporter::resolveReferences() { - if( m_unresolvedRefStack.empty() ) { + if (m_unresolvedRefStack.empty()) { return; } - RefInfo *currentRefInfo( nullptr ); - for( auto it = m_unresolvedRefStack.begin(); it != m_unresolvedRefStack.end(); ++it ) { + RefInfo *currentRefInfo(nullptr); + for (auto it = m_unresolvedRefStack.begin(); it != m_unresolvedRefStack.end(); ++it) { currentRefInfo = it->get(); - if( nullptr != currentRefInfo ) { - aiNode *node( currentRefInfo->m_node ); - if( RefInfo::MeshRef == currentRefInfo->m_type ) { - for( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) { - const std::string &name( currentRefInfo->m_Names[ i ] ); - ReferenceMap::const_iterator curIt( m_mesh2refMap.find( name ) ); + if (nullptr != currentRefInfo) { + aiNode *node(currentRefInfo->m_node); + if (RefInfo::MeshRef == currentRefInfo->m_type) { + for (size_t i = 0; i < currentRefInfo->m_Names.size(); ++i) { + const std::string &name(currentRefInfo->m_Names[i]); + ReferenceMap::const_iterator curIt(m_mesh2refMap.find(name)); if (m_mesh2refMap.end() != curIt) { - unsigned int meshIdx = static_cast(m_mesh2refMap[ name ]); - node->mMeshes[ i ] = meshIdx; + unsigned int meshIdx = static_cast(m_mesh2refMap[name]); + node->mMeshes[i] = meshIdx; } } - } else if( RefInfo::MaterialRef == currentRefInfo->m_type ) { - for ( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) { - const std::string name( currentRefInfo->m_Names[ i ] ); + } else if (RefInfo::MaterialRef == currentRefInfo->m_type) { + for (size_t i = 0; i < currentRefInfo->m_Names.size(); ++i) { + const std::string name(currentRefInfo->m_Names[i]); ReferenceMap::const_iterator curIt(m_material2refMap.find(name)); if (m_material2refMap.end() != curIt) { - if ( nullptr != m_currentMesh ) { - unsigned int matIdx = static_cast< unsigned int >( m_material2refMap[ name ] ); - if ( m_currentMesh->mMaterialIndex != 0 ) { - ASSIMP_LOG_WARN( "Override of material reference in current mesh by material reference." ); + if (nullptr != m_currentMesh) { + unsigned int matIdx = static_cast(m_material2refMap[name]); + if (m_currentMesh->mMaterialIndex != 0) { + ASSIMP_LOG_WARN("Override of material reference in current mesh by material reference."); } m_currentMesh->mMaterialIndex = matIdx; - } else { - ASSIMP_LOG_WARN( "Cannot resolve material reference, because no current mesh is there." ); + } else { + ASSIMP_LOG_WARN("Cannot resolve material reference, because no current mesh is there."); } } } } else { - throw DeadlyImportError( "Unknown reference info to resolve." ); + throw DeadlyImportError("Unknown reference info to resolve."); } } } } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::createNodeTree( aiScene *pScene ) { - if( nullptr == m_root ) { +void OpenGEXImporter::createNodeTree(aiScene *pScene) { + if (nullptr == m_root) { return; } - if( m_root->m_children.empty() ) { + if (m_root->m_children.empty()) { return; } pScene->mRootNode->mNumChildren = static_cast(m_root->m_children.size()); - pScene->mRootNode->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren ]; - std::copy( m_root->m_children.begin(), m_root->m_children.end(), pScene->mRootNode->mChildren ); + pScene->mRootNode->mChildren = new aiNode *[pScene->mRootNode->mNumChildren]; + std::copy(m_root->m_children.begin(), m_root->m_children.end(), pScene->mRootNode->mChildren); } //------------------------------------------------------------------------------------------------ -void OpenGEXImporter::pushNode( aiNode *node, aiScene *pScene ) { - ai_assert( nullptr != pScene ); +void OpenGEXImporter::pushNode(aiNode *node, aiScene *pScene) { + ai_assert(nullptr != pScene); - if ( nullptr == node ) { + if (nullptr == node) { return; } - ChildInfo *info( nullptr ); - if( m_nodeStack.empty() ) { + ChildInfo *info(nullptr); + if (m_nodeStack.empty()) { node->mParent = pScene->mRootNode; - NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) ); - if( m_nodeChildMap.end() == it ) { + NodeChildMap::iterator it(m_nodeChildMap.find(node->mParent)); + if (m_nodeChildMap.end() == it) { info = new ChildInfo; m_root = info; - m_nodeChildMap[ node->mParent ] = std::unique_ptr(info); + m_nodeChildMap[node->mParent] = std::unique_ptr(info); } else { info = it->second.get(); } - info->m_children.push_back( node ); + info->m_children.push_back(node); } else { - aiNode *parent( m_nodeStack.back() ); - ai_assert( nullptr != parent ); + aiNode *parent(m_nodeStack.back()); + ai_assert(nullptr != parent); node->mParent = parent; - NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) ); - if( m_nodeChildMap.end() == it ) { + NodeChildMap::iterator it(m_nodeChildMap.find(node->mParent)); + if (m_nodeChildMap.end() == it) { info = new ChildInfo; - m_nodeChildMap[ node->mParent ] = std::unique_ptr(info); + m_nodeChildMap[node->mParent] = std::unique_ptr(info); } else { info = it->second.get(); } - info->m_children.push_back( node ); + info->m_children.push_back(node); } - m_nodeStack.push_back( node ); + m_nodeStack.push_back(node); } //------------------------------------------------------------------------------------------------ aiNode *OpenGEXImporter::popNode() { - if( m_nodeStack.empty() ) { + if (m_nodeStack.empty()) { return nullptr; } - aiNode *node( top() ); + aiNode *node(top()); m_nodeStack.pop_back(); return node; @@ -1306,7 +1301,7 @@ aiNode *OpenGEXImporter::popNode() { //------------------------------------------------------------------------------------------------ aiNode *OpenGEXImporter::top() const { - if( m_nodeStack.empty() ) { + if (m_nodeStack.empty()) { return nullptr; } diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index e6f4d7f39..ca535a780 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -100,7 +100,7 @@ static bool isUnsignedIntegerType(Value::ValueType integerType) { } static DDLNode *createDDLNode(Text *id, OpenDDLParser *parser) { - if (nullptr == id || nullptr == parser) { + if (nullptr == id || nullptr == parser || id->m_buffer == nullptr) { return nullptr; } @@ -543,6 +543,9 @@ char *OpenDDLParser::parseIdentifier(char *in, char *end, Text **id) { // ignore blanks in = lookForNextToken(in, end); + if (in == end) { + return in; + } // staring with a number is forbidden if (isNumeric(*in)) { @@ -861,7 +864,7 @@ char *OpenDDLParser::parseProperty(char *in, char *end, Property **prop) { } in = lookForNextToken(in, end); - Text *id(nullptr); + Text *id = nullptr; in = parseIdentifier(in, end, &id); if (nullptr != id) { in = lookForNextToken(in, end); diff --git a/test/unit/utOpenGEXImportExport.cpp b/test/unit/utOpenGEXImportExport.cpp index 86836bfea..9362dc2a3 100644 --- a/test/unit/utOpenGEXImportExport.cpp +++ b/test/unit/utOpenGEXImportExport.cpp @@ -48,7 +48,7 @@ using namespace Assimp; class utOpenGEXImportExport : public AbstractImportExportBase { public: - virtual bool importerTest() { + bool importerTest() override { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OpenGEX/Example.ogex", 0); return nullptr != scene; From 4bba338d92823f4180fe02d54da7d39ce713cfaf Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 27 Oct 2020 09:23:20 +0100 Subject: [PATCH 19/21] Update CMakeLists.txt --- contrib/CMakeLists.txt | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 6a38acf5f..619b1e5b4 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -6,12 +6,20 @@ SET ( OPENDDL_PARSER_VERSION_PATCH 0 ) SET ( OPENDDL_PARSER_VERSION ${OPENDDL_PARSER_VERSION_MAJOR}.${OPENDDL_PARSER_VERSION_MINOR}.${OPENDDL_PARSER_VERSION_PATCH} ) SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" ) -option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF ) -option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON ) -option( COVERALLS "Generate coveralls data" OFF ) +option( DDL_USE_CPP11 "Set to ON to use C++11 features ( always on on windows )." ON ) +option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF ) +option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON ) +option( COVERALLS "Generate coveralls data" OFF ) -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) +if ( DDL_USE_CPP11 ) + if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) + set( OPENDDL_CXXFLAGS -std=c++0x ) + elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set( OPENDDL_CXXFLAGS --std=c++11 ) + endif() +else( DDL_USE_CPP11 ) + add_definitions( -DOPENDDL_NO_USE_CPP11 ) +endif( DDL_USE_CPP11) if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) find_package(Threads) @@ -23,11 +31,6 @@ if ( DDL_STATIC_LIBRARY ) add_definitions( -DOPENDDL_STATIC_LIBARY ) endif() -if (MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING") - add_definitions(-DGTEST_HAS_TR1_TUPLE=0) -endif() - add_definitions( -DOPENDDLPARSER_BUILD ) add_definitions( -D_VARIADIC_MAX=10 ) add_definitions( -DGTEST_HAS_PTHREAD=0 ) @@ -46,7 +49,7 @@ link_directories( ${CMAKE_HOME_DIRECTORY}/lib ) -SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake ) +set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake ) SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin ) @@ -94,20 +97,15 @@ SET ( openddl_parser_src include/openddlparser/OpenDDLStream.h include/openddlparser/DDLNode.h include/openddlparser/Value.h - include/openddlparser/TPoolAllocator.h README.md ) SOURCE_GROUP( code FILES ${openddl_parser_src} ) if ( DDL_STATIC_LIBRARY ) - ADD_LIBRARY( openddl_parser STATIC - ${openddl_parser_src} - ) + ADD_LIBRARY( openddl_parser STATIC ${openddl_parser_src} ) else() - ADD_LIBRARY( openddl_parser SHARED - ${openddl_parser_src} - ) + ADD_LIBRARY( openddl_parser SHARED ${openddl_parser_src} ) endif() SET ( GTEST_PATH contrib/gtest-1.7.0 ) @@ -121,6 +119,7 @@ SET ( gtest_src ${GTEST_PATH}/src/gtest-test-part.cc ${GTEST_PATH}/src/gtest-typed-test.cc ${GTEST_PATH}/src/gtest.cc + ${GTEST_PATH}/src/gtest_main.cc ) SET( openddl_parser_unittest_src @@ -134,10 +133,7 @@ SET( openddl_parser_unittest_src test/OpenDDLIntegrationTest.cpp test/ValueTest.cpp test/OpenDDLDefectsTest.cpp - test/OssFuzzTest.cpp - test/main.cpp ) -add_definitions(-DOPENDDL_TEST_DATA="${CMAKE_CURRENT_LIST_DIR}/test/TestData") SOURCE_GROUP( code FILES ${openddl_parser_unittest_src} ) SOURCE_GROUP( gtest FILES ${gtest_src} ) From 22ad7028f008a44ad74696c07bfc0c09ba530df1 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 27 Oct 2020 09:42:46 +0100 Subject: [PATCH 20/21] Delete CMakeLists.txt --- contrib/CMakeLists.txt | 166 ----------------------------------------- 1 file changed, 166 deletions(-) delete mode 100644 contrib/CMakeLists.txt diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt deleted file mode 100644 index 619b1e5b4..000000000 --- a/contrib/CMakeLists.txt +++ /dev/null @@ -1,166 +0,0 @@ -CMAKE_MINIMUM_REQUIRED( VERSION 2.6 ) -PROJECT( OpenDDL-Parser ) -SET ( OPENDDL_PARSER_VERSION_MAJOR 0 ) -SET ( OPENDDL_PARSER_VERSION_MINOR 1 ) -SET ( OPENDDL_PARSER_VERSION_PATCH 0 ) -SET ( OPENDDL_PARSER_VERSION ${OPENDDL_PARSER_VERSION_MAJOR}.${OPENDDL_PARSER_VERSION_MINOR}.${OPENDDL_PARSER_VERSION_PATCH} ) -SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" ) - -option( DDL_USE_CPP11 "Set to ON to use C++11 features ( always on on windows )." ON ) -option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF ) -option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON ) -option( COVERALLS "Generate coveralls data" OFF ) - -if ( DDL_USE_CPP11 ) - if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) - set( OPENDDL_CXXFLAGS -std=c++0x ) - elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set( OPENDDL_CXXFLAGS --std=c++11 ) - endif() -else( DDL_USE_CPP11 ) - add_definitions( -DOPENDDL_NO_USE_CPP11 ) -endif( DDL_USE_CPP11) - -if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) - find_package(Threads) -else() - add_definitions( -D_CRT_SECURE_NO_WARNINGS ) -endif() - -if ( DDL_STATIC_LIBRARY ) - add_definitions( -DOPENDDL_STATIC_LIBARY ) -endif() - -add_definitions( -DOPENDDLPARSER_BUILD ) -add_definitions( -D_VARIADIC_MAX=10 ) -add_definitions( -DGTEST_HAS_PTHREAD=0 ) -if ( DDL_DEBUG_OUTPUT ) - add_definitions( -DDDL_DEBUG_HEADER_NAME) -endif() - -INCLUDE_DIRECTORIES( - ./ - include/ - contrib/gtest-1.7.0/include - contrib/gtest-1.7.0/ -) - -link_directories( - ${CMAKE_HOME_DIRECTORY}/lib -) - -set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake ) -SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) -SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) -SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin ) - -if( WIN32 AND NOT CYGWIN ) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc" ) # Force to always compile with W4 - if( CMAKE_CXX_FLAGS MATCHES "/W[0-4]" ) - string( REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" ) - else() - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4" ) - endif() -elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) - # Update if necessary - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS}") -elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS} -Wwrite-strings") -endif() - -if (COVERALLS) - include(Coveralls) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") -endif() - -# Include the doc component. -FIND_PACKAGE( doxygen ) -IF ( DOXYGEN_FOUND ) - CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY ) - ADD_CUSTOM_TARGET( doc ALL ${DOXYGEN_EXECUTABLE} doc/doxygenfile - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Generating API documentation with Doxygen" VERBATIM ) -ENDIF ( DOXYGEN_FOUND ) - -SET ( openddl_parser_src - code/OpenDDLCommon.cpp - code/OpenDDLExport.cpp - code/OpenDDLParser.cpp - code/OpenDDLStream.cpp - code/DDLNode.cpp - code/Value.cpp - include/openddlparser/OpenDDLCommon.h - include/openddlparser/OpenDDLExport.h - include/openddlparser/OpenDDLParser.h - include/openddlparser/OpenDDLParserUtils.h - include/openddlparser/OpenDDLStream.h - include/openddlparser/DDLNode.h - include/openddlparser/Value.h - README.md -) - -SOURCE_GROUP( code FILES ${openddl_parser_src} ) - -if ( DDL_STATIC_LIBRARY ) - ADD_LIBRARY( openddl_parser STATIC ${openddl_parser_src} ) -else() - ADD_LIBRARY( openddl_parser SHARED ${openddl_parser_src} ) -endif() - -SET ( GTEST_PATH contrib/gtest-1.7.0 ) - -SET ( gtest_src - ${GTEST_PATH}/src/gtest-death-test.cc - ${GTEST_PATH}/src/gtest-filepath.cc - ${GTEST_PATH}/src/gtest-internal-inl.h - ${GTEST_PATH}/src/gtest-port.cc - ${GTEST_PATH}/src/gtest-printers.cc - ${GTEST_PATH}/src/gtest-test-part.cc - ${GTEST_PATH}/src/gtest-typed-test.cc - ${GTEST_PATH}/src/gtest.cc - ${GTEST_PATH}/src/gtest_main.cc -) - -SET( openddl_parser_unittest_src - test/UnitTestCommon.h - test/DDLNodeTest.cpp - test/OpenDDLCommonTest.cpp - test/OpenDDLExportTest.cpp - test/OpenDDLParserTest.cpp - test/OpenDDLParserUtilsTest.cpp - test/OpenDDLStreamTest.cpp - test/OpenDDLIntegrationTest.cpp - test/ValueTest.cpp - test/OpenDDLDefectsTest.cpp -) - -SOURCE_GROUP( code FILES ${openddl_parser_unittest_src} ) -SOURCE_GROUP( gtest FILES ${gtest_src} ) - -ADD_EXECUTABLE( openddl_parser_unittest - ${gtest_src} - ${openddl_parser_unittest_src} -) - -target_link_libraries( openddl_parser_unittest openddl_parser ${CMAKE_THREAD_LIBS_INIT} ) - -SET( openddl_parser_demo_src - demo/main.cpp -) - -if (COVERALLS) - set(COVERAGE_SRCS ${gtest_src} ${openddl_parser_unittest_src} ) - - # Create the coveralls target. - coveralls_setup( - "${COVERAGE_SRCS}" # The source files. - ON # If we should upload. - "${PROJECT_SOURCE_DIR}/cmake/") # (Optional) Alternate project cmake module path. -endif() - -ADD_EXECUTABLE( openddl_parser_demo - ${openddl_parser_demo_src} -) - -target_link_libraries( openddl_parser_demo openddl_parser ) From 43f7224d0caba5e0d9f1000103c0d33b12d3e18a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 27 Oct 2020 09:46:31 +0100 Subject: [PATCH 21/21] Update CMakeLists.txt --- CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9da3735ef..fb6ef422a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -578,10 +578,6 @@ ELSE () ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER ) ENDIF () -#IF(NOT ASSIMP_HUNTER_ENABLED) - ADD_SUBDIRECTORY(contrib) -#ENDIF() - ADD_SUBDIRECTORY( code/ ) IF ( ASSIMP_BUILD_ASSIMP_TOOLS ) # The viewer for windows only