From db142da571d99a3a44a0eed52a819bc7c4a85617 Mon Sep 17 00:00:00 2001 From: Garux Date: Thu, 29 Apr 2021 19:44:06 +0300 Subject: [PATCH 01/93] orient mdc correctly --- code/AssetLib/MDC/MDCLoader.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/code/AssetLib/MDC/MDCLoader.cpp b/code/AssetLib/MDC/MDCLoader.cpp index 17a349768..c53c31b77 100644 --- a/code/AssetLib/MDC/MDCLoader.cpp +++ b/code/AssetLib/MDC/MDCLoader.cpp @@ -465,6 +465,13 @@ void MDCImporter::InternReadFile( pcMat->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0)); } } + + // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system + pScene->mRootNode->mTransformation = aiMatrix4x4( + 1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, -1.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f); } #endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER From ebf5ef9a4be21f1f8c5a5f311aad342f41878291 Mon Sep 17 00:00:00 2001 From: Garux Date: Thu, 29 Apr 2021 20:02:20 +0300 Subject: [PATCH 02/93] consider pScene->mRootNode->mTransformation set by some importers while using AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION --- code/PostProcessing/PretransformVertices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/PostProcessing/PretransformVertices.cpp b/code/PostProcessing/PretransformVertices.cpp index d1740f30b..2691ed488 100644 --- a/code/PostProcessing/PretransformVertices.cpp +++ b/code/PostProcessing/PretransformVertices.cpp @@ -429,7 +429,7 @@ void PretransformVertices::Execute(aiScene *pScene) { const unsigned int iOldNodes = CountNodes(pScene->mRootNode); if (configTransform) { - pScene->mRootNode->mTransformation = configTransformation; + pScene->mRootNode->mTransformation = configTransformation * pScene->mRootNode->mTransformation; } // first compute absolute transformation matrices for all nodes From 4798ff3882bac60e89d2015783d2966ffc8e620c Mon Sep 17 00:00:00 2001 From: Garux Date: Thu, 29 Apr 2021 19:51:03 +0300 Subject: [PATCH 03/93] fix hl1 mdl orientation, tex coords, face windings order --- code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp | 6 +++--- code/AssetLib/MDL/MDLLoader.cpp | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp b/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp index 4df0d0d1d..e9020637b 100644 --- a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp @@ -868,7 +868,7 @@ void HL1MDLLoader::read_meshes() { scene_mesh->mNormals[v] = bind_pose_normals[pTrivert->normindex]; scene_mesh->mTextureCoords[0][v] = aiVector3D( pTrivert->s * texcoords_s_scale, - pTrivert->t * texcoords_t_scale, 0); + pTrivert->t * -texcoords_t_scale, 0); } // Add face and indices. @@ -879,9 +879,9 @@ void HL1MDLLoader::read_meshes() { aiFace *face = &scene_mesh->mFaces[f]; face->mNumIndices = 3; face->mIndices = new unsigned int[3]; - face->mIndices[0] = mesh_faces[f].v0; + face->mIndices[0] = mesh_faces[f].v2; face->mIndices[1] = mesh_faces[f].v1; - face->mIndices[2] = mesh_faces[f].v2; + face->mIndices[2] = mesh_faces[f].v0; } // Add mesh bones. diff --git a/code/AssetLib/MDL/MDLLoader.cpp b/code/AssetLib/MDL/MDLLoader.cpp index a4286a716..0d694a2cc 100644 --- a/code/AssetLib/MDL/MDLLoader.cpp +++ b/code/AssetLib/MDL/MDLLoader.cpp @@ -199,6 +199,7 @@ void MDLImporter::InternReadFile(const std::string &pFile, const uint32_t iMagicWord = *((uint32_t *)mBuffer); // Determine the file subtype and call the appropriate member function + bool is_half_life = false; // Original Quake1 format if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) { @@ -240,6 +241,7 @@ void MDLImporter::InternReadFile(const std::string &pFile, else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord) { iGSFileVersion = 0; + is_half_life = true; HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer; if (pHeader->version == AI_MDL_HL1_VERSION) { @@ -255,9 +257,19 @@ void MDLImporter::InternReadFile(const std::string &pFile, ". Magic word (", std::string((char *)&iMagicWord, 4), ") is not known"); } - // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system - pScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); + if (is_half_life){ + // Now rotate the whole scene 90 degrees around the z and x axes to convert to internal coordinate system + pScene->mRootNode->mTransformation = aiMatrix4x4( + 0.f, -1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + -1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f); + } + else { + // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system + pScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); + } DeleteBufferAndCleanup(); } catch (...) { From edf12bd3571a0297d5a2784704b206df69655bbf Mon Sep 17 00:00:00 2001 From: Garux Date: Thu, 29 Apr 2021 20:14:57 +0300 Subject: [PATCH 04/93] fix md2 orientation --- code/AssetLib/MD2/MD2Loader.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/code/AssetLib/MD2/MD2Loader.cpp b/code/AssetLib/MD2/MD2Loader.cpp index 9ccbcdfca..41cec5ab6 100644 --- a/code/AssetLib/MD2/MD2Loader.cpp +++ b/code/AssetLib/MD2/MD2Loader.cpp @@ -433,10 +433,6 @@ void MD2Importer::InternReadFile( const std::string& pFile, aiVector3D& vNormal = pcMesh->mNormals[iCurrent]; LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal); - // flip z and y to become right-handed - std::swap((float&)vNormal.z,(float&)vNormal.y); - std::swap((float&)vec.z,(float&)vec.y); - if (m_pcHeader->numTexCoords) { // validate texture coordinates iIndex = pcTriangles[i].textureIndices[c]; @@ -454,7 +450,15 @@ void MD2Importer::InternReadFile( const std::string& pFile, } pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent; } + // flip the face order + std::swap( pScene->mMeshes[0]->mFaces[i].mIndices[0], pScene->mMeshes[0]->mFaces[i].mIndices[2] ); } + // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system + pScene->mRootNode->mTransformation = aiMatrix4x4( + 1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, -1.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f); } #endif // !! ASSIMP_BUILD_NO_MD2_IMPORTER From 149224091f2967badf71d074b1839a45afa1695e Mon Sep 17 00:00:00 2001 From: Garux Date: Fri, 30 Apr 2021 10:37:06 +0300 Subject: [PATCH 05/93] support missing closing brace in material list after Ascii Scene Exporter v2.51 --- code/AssetLib/ASE/ASEParser.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/AssetLib/ASE/ASEParser.cpp b/code/AssetLib/ASE/ASEParser.cpp index 21ec26593..958e3b9a8 100644 --- a/code/AssetLib/ASE/ASEParser.cpp +++ b/code/AssetLib/ASE/ASEParser.cpp @@ -498,6 +498,12 @@ void Parser::ParseLV1MaterialListBlock() { ParseLV2MaterialBlock(sMat); continue; } + if( iDepth == 1 ){ + // CRUDE HACK: support missing brace after "Ascii Scene Exporter v2.51" + LogWarning("Missing closing brace in material list"); + --filePtr; + return; + } } AI_ASE_HANDLE_TOP_LEVEL_SECTION(); } From 0b7ebef497f0bde699e85c8935f7201cf638470d Mon Sep 17 00:00:00 2001 From: Garux Date: Fri, 30 Apr 2021 22:51:21 +0300 Subject: [PATCH 06/93] fix path separator in md3 shader loading --- code/AssetLib/MD3/MD3Loader.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/AssetLib/MD3/MD3Loader.cpp b/code/AssetLib/MD3/MD3Loader.cpp index e27079766..fc8bd9037 100644 --- a/code/AssetLib/MD3/MD3Loader.cpp +++ b/code/AssetLib/MD3/MD3Loader.cpp @@ -483,8 +483,9 @@ void MD3Importer::ReadShader(Q3Shader::ShaderData &fill) const { // If no specific dir or file is given, use our default search behaviour if (!configShaderFile.length()) { - if (!Q3Shader::LoadShader(fill, path + "..\\..\\..\\scripts\\" + model_file + ".shader", mIOHandler)) { - Q3Shader::LoadShader(fill, path + "..\\..\\..\\scripts\\" + filename + ".shader", mIOHandler); + const char sep = mIOHandler->getOsSeparator(); + if (!Q3Shader::LoadShader(fill, path + ".." + sep + ".." + sep + ".." + sep + "scripts" + sep + model_file + ".shader", mIOHandler)) { + Q3Shader::LoadShader(fill, path + ".." + sep + ".." + sep + ".." + sep + "scripts" + sep + filename + ".shader", mIOHandler); } } else { // If the given string specifies a file, load this file. From 55abc49d6de53bfdbc66937932f63019a3aad5c5 Mon Sep 17 00:00:00 2001 From: Garux Date: Fri, 30 Apr 2021 22:59:05 +0300 Subject: [PATCH 07/93] improve md3::Q3 shader::cull keyword support only use nonstandard winding order with `cull back`; might be excess too, since engine doesn't support this --- code/AssetLib/MD3/MD3Loader.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/AssetLib/MD3/MD3Loader.cpp b/code/AssetLib/MD3/MD3Loader.cpp index fc8bd9037..87fe2509c 100644 --- a/code/AssetLib/MD3/MD3Loader.cpp +++ b/code/AssetLib/MD3/MD3Loader.cpp @@ -196,11 +196,11 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem * // 'cull' specifies culling behaviour for the model else if (TokenMatchI(buff, "cull", 4)) { SkipSpaces(&buff); - if (!ASSIMP_strincmp(buff, "back", 4)) { + if (!ASSIMP_strincmp(buff, "back", 4)) { // render face's backside, does not function in Q3 engine (bug) curData->cull = Q3Shader::CULL_CCW; - } else if (!ASSIMP_strincmp(buff, "front", 5)) { + } else if (!ASSIMP_strincmp(buff, "front", 5)) { // is not valid keyword in Q3, but occurs in shaders curData->cull = Q3Shader::CULL_CW; - } else if (!ASSIMP_strincmp(buff, "none", 4) || !ASSIMP_strincmp(buff, "disable", 7)) { + } else if (!ASSIMP_strincmp(buff, "none", 4) || !ASSIMP_strincmp(buff, "twosided", 8) || !ASSIMP_strincmp(buff, "disable", 7)) { curData->cull = Q3Shader::CULL_NONE; } else { ASSIMP_LOG_ERROR("Q3Shader: Unrecognized cull mode"); @@ -986,8 +986,8 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[index].U; pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - pcUVs[index].V; } - // Flip face order if necessary - if (!shader || shader->cull == Q3Shader::CULL_CW) { + // Flip face order normally, unless shader is backfacing + if (!(shader && shader->cull == Q3Shader::CULL_CCW)) { std::swap(pcMesh->mFaces[i].mIndices[2], pcMesh->mFaces[i].mIndices[1]); } ++pcTriangles; From af0aca796ebab7663bba2778f7f30dd424f324ca Mon Sep 17 00:00:00 2001 From: contriteobserver Date: Fri, 30 Apr 2021 21:07:01 -0700 Subject: [PATCH 08/93] now compiling M3D ASCII support by default addresses issue #3777 --- code/AssetLib/M3D/M3DExporter.cpp | 12 ++++------ code/AssetLib/M3D/M3DImporter.cpp | 10 -------- code/AssetLib/M3D/M3DWrapper.h | 1 - code/AssetLib/M3D/m3d.h | 38 +++---------------------------- 4 files changed, 7 insertions(+), 54 deletions(-) diff --git a/code/AssetLib/M3D/M3DExporter.cpp b/code/AssetLib/M3D/M3DExporter.cpp index 856932947..bcac1d98a 100644 --- a/code/AssetLib/M3D/M3DExporter.cpp +++ b/code/AssetLib/M3D/M3DExporter.cpp @@ -294,21 +294,17 @@ void ExportSceneM3D( // Worker function for exporting a scene to ASCII A3D. // Prototyped and registered in Exporter.cpp void ExportSceneM3DA( - const char *, - IOSystem *, - const aiScene *, - const ExportProperties * + const char *pFile, + IOSystem *pIOSystem, + const aiScene *pScene, + const ExportProperties *pProperties ) { -#ifdef M3D_ASCII // initialize the exporter M3DExporter exporter(pScene, pProperties); // perform ascii export exporter.doExport(pFile, pIOSystem, true); -#else - throw DeadlyExportError("Assimp configured without M3D_ASCII support"); -#endif } // ------------------------------------------------------------------------------------------------ diff --git a/code/AssetLib/M3D/M3DImporter.cpp b/code/AssetLib/M3D/M3DImporter.cpp index 8cbda23cb..56c272be8 100644 --- a/code/AssetLib/M3D/M3DImporter.cpp +++ b/code/AssetLib/M3D/M3DImporter.cpp @@ -95,11 +95,7 @@ static const aiImporterDesc desc = { 0, 0, 0, -#ifdef M3D_ASCII "m3d a3d" -#else - "m3d" -#endif }; namespace Assimp { @@ -119,9 +115,7 @@ bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c const std::string extension = GetExtension(pFile); if (extension == "m3d" -#ifdef M3D_ASCII || extension == "a3d" -#endif ) return true; else if (!extension.length() || checkSig) { @@ -141,9 +135,7 @@ bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c return false; } return !memcmp(data, "3DMO", 4) /* bin */ -#ifdef M3D_ASCII || !memcmp(data, "3dmo", 4) /* ASCII */ -#endif ; } return false; @@ -176,12 +168,10 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys if (!memcmp(buffer.data(), "3DMO", 4) && memcmp(buffer.data() + 4, &fileSize, 4)) { throw DeadlyImportError("Bad binary header in file ", file, "."); } -#ifdef M3D_ASCII // make sure there's a terminator zero character, as input must be ASCIIZ if (!memcmp(buffer.data(), "3dmo", 4)) { buffer.push_back(0); } -#endif // Get the path for external assets std::string folderName("./"); diff --git a/code/AssetLib/M3D/M3DWrapper.h b/code/AssetLib/M3D/M3DWrapper.h index 5c370e607..782e908d2 100644 --- a/code/AssetLib/M3D/M3DWrapper.h +++ b/code/AssetLib/M3D/M3DWrapper.h @@ -54,7 +54,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Assimp specific M3D configuration. Comment out these defines to remove functionality //#define ASSIMP_USE_M3D_READFILECB -//#define M3D_ASCII #include "m3d.h" diff --git a/code/AssetLib/M3D/m3d.h b/code/AssetLib/M3D/m3d.h index dfc30aec3..11398cfab 100644 --- a/code/AssetLib/M3D/m3d.h +++ b/code/AssetLib/M3D/m3d.h @@ -231,14 +231,9 @@ enum { typedef struct { uint8_t format; uint8_t id; -#ifdef M3D_ASCII #define M3D_PROPERTYDEF(f, i, n) \ { (f), (i), (char *)(n) } char *key; -#else -#define M3D_PROPERTYDEF(f, i, n) \ - { (f), (i) } -#endif } m3dpd_t; /* material property types */ @@ -376,18 +371,11 @@ enum { #define M3D_CMDMAXARG 8 /* if you increase this, add more arguments to the macro below */ typedef struct { -#ifdef M3D_ASCII #define M3D_CMDDEF(t, n, p, a, b, c, d, e, f, g, h) \ { \ (char *)(n), (p), { (a), (b), (c), (d), (e), (f), (g), (h) } \ } char *key; -#else -#define M3D_CMDDEF(t, n, p, a, b, c, d, e, f, g, h) \ - { \ - (p), { (a), (b), (c), (d), (e), (f), (g), (h) } \ - } -#endif uint8_t p; uint8_t a[M3D_CMDMAXARG]; } m3dcd_t; @@ -2059,15 +2047,13 @@ unsigned char *_m3dstbi_zlib_compress(unsigned char *data, int data_len, int *ou #define M3D_CHUNKMAGIC(m, a, b, c, d) ((m)[0] == (a) && (m)[1] == (b) && (m)[2] == (c) && (m)[3] == (d)) -#ifdef M3D_ASCII #include /* sprintf and strtod cares about number locale */ #include /* get sprintf */ -#endif #ifdef M3D_PROFILING #include #endif -#if !defined(M3D_NOIMPORTER) && defined(M3D_ASCII) +#if !defined(M3D_NOIMPORTER) /* helper functions for the ASCII parser */ static char *_m3d_findarg(char *s) { while (s && *s && *s != ' ' && *s != '\t' && *s != '\r' && *s != '\n') @@ -2118,7 +2104,7 @@ static char *_m3d_getfloat(char *s, M3D_FLOAT *ret) { return _m3d_findarg(e); } #endif -#if !defined(M3D_NODUP) && (!defined(M3D_NOIMPORTER) || defined(M3D_ASCII) || defined(M3D_EXPORTER)) +#if !defined(M3D_NODUP) && (!defined(M3D_NOIMPORTER) || defined(M3D_EXPORTER)) /* helper function to create safe strings */ char *_m3d_safestr(char *in, int morelines) { char *out, *o, *i = in; @@ -2426,21 +2412,17 @@ m3d_t *m3d_load(unsigned char *data, m3dread_t readfilecb, m3dfree_t freecb, m3d #ifndef M3D_NOWEIGHTS m3ds_t *sk; #endif -#ifdef M3D_ASCII m3ds_t s; M3D_INDEX bi[M3D_BONEMAXLEVEL + 1], level; const char *ol; char *ptr, *pe, *fn; -#endif #ifdef M3D_PROFILING struct timeval tv0, tv1, tvd; gettimeofday(&tv0, NULL); #endif if (!data || (!M3D_CHUNKMAGIC(data, '3', 'D', 'M', 'O') -#ifdef M3D_ASCII && !M3D_CHUNKMAGIC(data, '3', 'd', 'm', 'o') -#endif )) return NULL; model = (m3d_t *)M3D_MALLOC(sizeof(m3d_t)); @@ -2457,7 +2439,6 @@ m3d_t *m3d_load(unsigned char *data, m3dread_t readfilecb, m3dfree_t freecb, m3d model->texture = mtllib->texture; model->flags |= M3D_FLG_MTLLIB; } -#ifdef M3D_ASCII /* ASCII variant? */ if (M3D_CHUNKMAGIC(data, '3', 'd', 'm', 'o')) { model->errcode = M3D_ERR_BADFILE; @@ -3034,7 +3015,6 @@ m3d_t *m3d_load(unsigned char *data, m3dread_t readfilecb, m3dfree_t freecb, m3d setlocale(LC_NUMERIC, ol); goto postprocess; } -#endif /* Binary variant */ if (!M3D_CHUNKMAGIC(data + 8, 'H', 'E', 'A', 'D')) { buff = (unsigned char *)stbi_zlib_decode_malloc_guesssize_headerflag((const char *)data + 8, ((m3dchunk_t *)data)->length - 8, @@ -3698,9 +3678,7 @@ m3d_t *m3d_load(unsigned char *data, m3dread_t readfilecb, m3dfree_t freecb, m3d } } /* calculate normals, normalize skin weights, create bone/vertex cross-references and calculate transform matrices */ -#ifdef M3D_ASCII postprocess: -#endif if (model) { M3D_LOG("Post-process"); #ifdef M3D_PROFILING @@ -3989,7 +3967,6 @@ void m3d_free(m3d_t *model) { unsigned int i, j; if (!model) return; -#ifdef M3D_ASCII /* if model imported from ASCII, we have to free all strings as well */ if (model->flags & M3D_FLG_FREESTR) { if (model->name) M3D_FREE(model->name); @@ -4047,7 +4024,6 @@ void m3d_free(m3d_t *model) { if (model->preview.data) M3D_FREE(model->preview.data); } -#endif if (model->flags & M3D_FLG_FREERAW) M3D_FREE(model->raw); if (model->tmap) M3D_FREE(model->tmap); @@ -4315,7 +4291,6 @@ static void _m3d_round(int quality, m3dv_t *src, m3dv_t *dst) { if (dst->w == (M3D_FLOAT)-0.0) dst->w = (M3D_FLOAT)0.0; } -#ifdef M3D_ASCII /* add a bone to ascii output */ static char *_m3d_prtbone(char *ptr, m3db_t *bone, M3D_INDEX numbone, M3D_INDEX parent, uint32_t level, M3D_INDEX *vrtxidx) { uint32_t i, j; @@ -4334,16 +4309,13 @@ static char *_m3d_prtbone(char *ptr, m3db_t *bone, M3D_INDEX numbone, M3D_INDEX } return ptr; } -#endif /** * Function to encode an in-memory model into on storage Model 3D format */ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size) { -#ifdef M3D_ASCII const char *ol; char *ptr; -#endif char vc_s, vi_s, si_s, ci_s, ti_s, bi_s, nb_s, sk_s, fc_s, hi_s, fi_s; char *sn = NULL, *sl = NULL, *sa = NULL, *sd = NULL; unsigned char *out = NULL, *z = NULL, weights[M3D_NUMBONE], *norm = NULL; @@ -4369,9 +4341,7 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size return NULL; } model->errcode = M3D_SUCCESS; -#ifdef M3D_ASCII if (flags & M3D_EXP_ASCII) quality = M3D_EXP_DOUBLE; -#endif vrtxidx = (M3D_INDEX *)M3D_MALLOC(model->numvertex * sizeof(M3D_INDEX)); if (!vrtxidx) goto memerr; memset(vrtxidx, 255, model->numvertex * sizeof(M3D_INDEX)); @@ -4800,7 +4770,6 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size } M3D_LOG("Serializing model"); -#ifdef M3D_ASCII if (flags & M3D_EXP_ASCII) { /* use CRLF to make model creators on Win happy... */ sd = _m3d_safestr(model->desc, 1); @@ -5073,7 +5042,7 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size ptr += sprintf(ptr, "\r\n"); } /* mathematical shapes face */ - if (model->numshape !(flags & M3D_EXP_NOFACE)) { + if (model->numshape != (flags & M3D_EXP_NOFACE)) { for (j = 0; j < model->numshape; j++) { sn = _m3d_safestr(model->shape[j].name, 0); if (!sn) { @@ -5287,7 +5256,6 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size if (!out) goto memerr; out[len] = 0; } else -#endif { /* stricly only use LF (newline) in binary */ sd = _m3d_safestr(model->desc, 3); From e51bb1e77e5d26aaaa40ef9bcffb196aa3049dfb Mon Sep 17 00:00:00 2001 From: contriteobserver Date: Fri, 30 Apr 2021 21:26:57 -0700 Subject: [PATCH 09/93] fixed signed/unsigned mismatch warning --- code/AssetLib/M3D/m3d.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/M3D/m3d.h b/code/AssetLib/M3D/m3d.h index 11398cfab..7dcb29593 100644 --- a/code/AssetLib/M3D/m3d.h +++ b/code/AssetLib/M3D/m3d.h @@ -5042,7 +5042,7 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size ptr += sprintf(ptr, "\r\n"); } /* mathematical shapes face */ - if (model->numshape != (flags & M3D_EXP_NOFACE)) { + if (model->numshape != (M3D_INDEX)(flags & M3D_EXP_NOFACE)) { for (j = 0; j < model->numshape; j++) { sn = _m3d_safestr(model->shape[j].name, 0); if (!sn) { From 813b64ef520a8b35548684e0bc42362bdb386e01 Mon Sep 17 00:00:00 2001 From: contriteobserver Date: Fri, 30 Apr 2021 21:51:02 -0700 Subject: [PATCH 10/93] corrected M3D_EXP_NOFACE test --- code/AssetLib/M3D/m3d.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/M3D/m3d.h b/code/AssetLib/M3D/m3d.h index 7dcb29593..68265959e 100644 --- a/code/AssetLib/M3D/m3d.h +++ b/code/AssetLib/M3D/m3d.h @@ -5042,7 +5042,7 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size ptr += sprintf(ptr, "\r\n"); } /* mathematical shapes face */ - if (model->numshape != (M3D_INDEX)(flags & M3D_EXP_NOFACE)) { + if (model->numshape && (!(flags & M3D_EXP_NOFACE))) { for (j = 0; j < model->numshape; j++) { sn = _m3d_safestr(model->shape[j].name, 0); if (!sn) { From eab1c9c3c04bb8e9244f485684f7d3ed5b79a15a Mon Sep 17 00:00:00 2001 From: Garux Date: Sat, 1 May 2021 00:27:28 +0300 Subject: [PATCH 11/93] add `AI_CONFIG_IMPORT_MD3_LOAD_SHADERS` bool option the purpose is use of this loader with idtech3 FS this requires full original material name, which euqals to Q3 shader path result of deduction is not usable inside Q3 FS at all option in general is "do not tinker with the path" --- code/AssetLib/MD3/MD3Loader.cpp | 14 ++++++++++++-- code/AssetLib/MD3/MD3Loader.h | 3 +++ include/assimp/config.h.in | 13 +++++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/code/AssetLib/MD3/MD3Loader.cpp b/code/AssetLib/MD3/MD3Loader.cpp index 87fe2509c..53a0eea41 100644 --- a/code/AssetLib/MD3/MD3Loader.cpp +++ b/code/AssetLib/MD3/MD3Loader.cpp @@ -450,6 +450,9 @@ void MD3Importer::SetupProperties(const Importer *pImp) { // AI_CONFIG_IMPORT_MD3_SKIN_NAME configSkinFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SKIN_NAME, "default")); + // AI_CONFIG_IMPORT_MD3_LOAD_SHADERS + configLoadShaders = (pImp->GetPropertyBool(AI_CONFIG_IMPORT_MD3_LOAD_SHADERS, true)); + // AI_CONFIG_IMPORT_MD3_SHADER_SRC configShaderFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SHADER_SRC, "")); @@ -781,7 +784,9 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // And check whether we can locate a shader file for this model Q3Shader::ShaderData shaders; - ReadShader(shaders); + if (configLoadShaders){ + ReadShader(shaders); + } // Adjust all texture paths in the shader const char *header_name = pcHeader->NAME; @@ -863,7 +868,12 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy std::string convertedPath; if (texture_name) { - ConvertPath(texture_name, header_name, convertedPath); + if (configLoadShaders){ + ConvertPath(texture_name, header_name, convertedPath); + } + else{ + convertedPath = texture_name; + } } const Q3Shader::ShaderDataBlock *shader = nullptr; diff --git a/code/AssetLib/MD3/MD3Loader.h b/code/AssetLib/MD3/MD3Loader.h index d34df2d77..1a4e5982c 100644 --- a/code/AssetLib/MD3/MD3Loader.h +++ b/code/AssetLib/MD3/MD3Loader.h @@ -297,6 +297,9 @@ protected: /** Configuration option: name of skin file to be read */ std::string configSkinFile; + /** Configuration option: whether to load shaders */ + bool configLoadShaders; + /** Configuration option: name or path of shader */ std::string configShaderFile; diff --git a/include/assimp/config.h.in b/include/assimp/config.h.in index d78568da7..016cabbad 100644 --- a/include/assimp/config.h.in +++ b/include/assimp/config.h.in @@ -669,7 +669,7 @@ enum aiComponent // --------------------------------------------------------------------------- /** @brief Set wether the importer shall not remove empty bones. - * + * * Empty bone are often used to define connections for other models. */ #define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \ @@ -854,6 +854,15 @@ enum aiComponent #define AI_CONFIG_IMPORT_MD3_SKIN_NAME \ "IMPORT_MD3_SKIN_NAME" +// --------------------------------------------------------------------------- +/** @brief Specify if to try load Quake 3 shader files. This also controls + * original surface name handling: when disabled it will be used unchanged. + * + * Property type: bool. Default value: true. + */ +#define AI_CONFIG_IMPORT_MD3_LOAD_SHADERS \ + "IMPORT_MD3_LOAD_SHADERS" + // --------------------------------------------------------------------------- /** @brief Specify the Quake 3 shader file to be used for a particular * MD3 file. This can also be a search path. @@ -1058,7 +1067,7 @@ enum aiComponent #define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT" /** @brief Specifies whether the assimp export shall be able to export point clouds - * + * * When this flag is not defined the render data has to contain valid faces. * Point clouds are only a collection of vertices which have nor spatial organization * by a face and the validation process will remove them. Enabling this feature will From c2d3d22271cb81aacce318df85a1cf8be1ad8122 Mon Sep 17 00:00:00 2001 From: Jason C Date: Sat, 1 May 2021 10:58:29 -0400 Subject: [PATCH 12/93] Fix crash in CanRead when file can not be opened. Addresses #3849 --- code/AssetLib/M3D/M3DImporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/M3D/M3DImporter.cpp b/code/AssetLib/M3D/M3DImporter.cpp index 8cbda23cb..91fa54b75 100644 --- a/code/AssetLib/M3D/M3DImporter.cpp +++ b/code/AssetLib/M3D/M3DImporter.cpp @@ -137,7 +137,7 @@ bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c */ std::unique_ptr pStream(pIOHandler->Open(pFile, "rb")); unsigned char data[4]; - if (4 != pStream->Read(data, 1, 4)) { + if (!pStream || 4 != pStream->Read(data, 1, 4)) { return false; } return !memcmp(data, "3DMO", 4) /* bin */ From 65a2b98b867a3dece8b2428c0defe8acb7f4fafd Mon Sep 17 00:00:00 2001 From: Krishty Date: Sat, 1 May 2021 18:46:12 +0200 Subject: [PATCH 13/93] updated C4D importer to use the Cineware SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maxon’s Melange SDK has been renamed Cineware SDK as of 21.004, and with it all namespaces and types. This commit - makes CMake use contrib/Cineware instead of contrib/Melange; - renames Assimp’s namespace melange to namespace cineware; - removes useless functions and formatter references from class C4DImporter; - removes duplicate conversion of cineware::String to aiString in the importer; - updates comments accordingly; - updates copyright info. --- CMakeLists.txt | 15 ++++---- code/AssetLib/C4D/C4DImporter.cpp | 64 +++++++++++-------------------- code/AssetLib/C4D/C4DImporter.h | 39 ++++++++----------- 3 files changed, 46 insertions(+), 72 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97a3641f5..7027e3300 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -527,12 +527,12 @@ ENDIF() MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER ) SET ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL - "Build the C4D importer, which relies on the non-free Melange SDK." + "Build the C4D importer, which relies on the non-free Cineware SDK." ) IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER) IF ( MSVC ) - SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/includes") + SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/includes") # pick the correct prebuilt library IF(MSVC15) @@ -551,22 +551,23 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER) ) ENDIF() - SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/libraries/win") + SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/libraries/win") SET(C4D_DEBUG_LIBRARIES - "${C4D_LIB_BASE_PATH}/melangelib${C4D_LIB_POSTFIX}/melangelib_debug.lib" + "${C4D_LIB_BASE_PATH}/cinewarelib${C4D_LIB_POSTFIX}/cinewarelib_debug.lib" "${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_debug.lib" ) SET(C4D_RELEASE_LIBRARIES - "${C4D_LIB_BASE_PATH}/melangelib${C4D_LIB_POSTFIX}/melangelib_release.lib" + "${C4D_LIB_BASE_PATH}/cinewarelib${C4D_LIB_POSTFIX}/cinewarelib_release.lib" "${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_release.lib" ) - # winsock and winmm are necessary dependencies of melange (this is undocumented, but true.) + # winsock and winmm are necessary (and undocumented) dependencies of Cineware SDK because + # it can be used to communicate with a running Cinema 4D instance SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib) ELSE () MESSAGE( FATAL_ERROR - "C4D is currently only available on Windows with melange SDK installed in contrib/Melange" + "C4D is currently only available on Windows with Cineware SDK installed in contrib/Cineware" ) ENDIF () ELSE () diff --git a/code/AssetLib/C4D/C4DImporter.cpp b/code/AssetLib/C4D/C4DImporter.cpp index 24fd6f622..594bcfddd 100644 --- a/code/AssetLib/C4D/C4DImporter.cpp +++ b/code/AssetLib/C4D/C4DImporter.cpp @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2020, assimp team +Copyright (c) 2006-2021, assimp team All rights reserved. Redistribution and use of this software in source and binary forms, @@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif #include "C4DImporter.h" -#include #include #include #include @@ -65,7 +64,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "c4d_file.h" #include "default_alien_overloads.h" -using namespace melange; +namespace { + +aiString aiStringFrom(cineware::String const & cinestring) { + aiString result; + cinestring.GetCString(result.data, MAXLEN-1); + result.length = static_cast(cinestring.GetLength()); + return result; +} + +} + +using namespace Assimp; +using namespace cineware; // overload this function and fill in your own unique data void GetWriterInfo(int &id, String &appname) { @@ -73,9 +84,6 @@ void GetWriterInfo(int &id, String &appname) { appname = "Open Asset Import Library"; } -using namespace Assimp; -using namespace Assimp::Formatter; - namespace Assimp { template<> const char* LogFunctions::Prefix() { static auto prefix = "C4D: "; @@ -97,17 +105,6 @@ static const aiImporterDesc desc = { }; -// ------------------------------------------------------------------------------------------------ -C4DImporter::C4DImporter() -: BaseImporter() { - // empty -} - -// ------------------------------------------------------------------------------------------------ -C4DImporter::~C4DImporter() { - // empty -} - // ------------------------------------------------------------------------------------------------ bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { const std::string& extension = GetExtension(pFile); @@ -125,11 +122,6 @@ const aiImporterDesc* C4DImporter::GetInfo () const { return &desc; } -// ------------------------------------------------------------------------------------------------ -void C4DImporter::SetupProperties(const Importer* /*pImp*/) { - // nothing to be done for the moment -} - // ------------------------------------------------------------------------------------------------ // Imports the given file into the given scene structure. @@ -199,8 +191,8 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS // ------------------------------------------------------------------------------------------------ -bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) { - // based on Melange sample code (C4DImportExport.cpp) +bool C4DImporter::ReadShader(aiMaterial* out, BaseShader* shader) { + // based on Cineware sample code (C4DImportExport.cpp) while(shader) { if(shader->GetType() == Xlayer) { BaseContainer* container = shader->GetDataInstance(); @@ -242,9 +234,7 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) { lsl = lsl->GetNext(); } } else if ( shader->GetType() == Xbitmap ) { - aiString path; - shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1); - path.length = ::strlen(path.data); + auto const path = aiStringFrom(shader->GetFileName().GetString()); out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0)); return true; } else { @@ -257,18 +247,15 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) { } // ------------------------------------------------------------------------------------------------ -void C4DImporter::ReadMaterials(melange::BaseMaterial* mat) { - // based on Melange sample code +void C4DImporter::ReadMaterials(BaseMaterial* mat) { + // based on Cineware sample code while (mat) { - const String& name = mat->GetName(); if (mat->GetType() == Mmaterial) { aiMaterial* out = new aiMaterial(); material_mapping[mat] = static_cast(materials.size()); materials.push_back(out); - aiString ai_name; - name.GetCString(ai_name.data, MAXLEN-1); - ai_name.length = ::strlen(ai_name.data); + auto const ai_name = aiStringFrom(mat->GetName()); out->AddProperty(&ai_name, AI_MATKEY_NAME); Material& m = dynamic_cast(*mat); @@ -305,19 +292,15 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) { ai_assert(parent != nullptr ); std::vector nodes; - // based on Melange sample code + // based on Cineware sample code while (object) { - const String& name = object->GetName(); const LONG type = object->GetType(); const Matrix& ml = object->GetMl(); - aiString string; - name.GetCString(string.data, MAXLEN-1); - string.length = ::strlen(string.data); aiNode* const nd = new aiNode(); nd->mParent = parent; - nd->mName = string; + nd->mName = aiStringFrom(object->GetName()); nd->mTransformation.a1 = ml.v1.x; nd->mTransformation.b1 = ml.v1.y; @@ -370,7 +353,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) { ai_assert(object != nullptr); ai_assert( object->GetType() == Opolygon ); - // based on Melange sample code + // based on Cineware sample code PolygonObject* const polyObject = dynamic_cast(object); ai_assert(polyObject != nullptr); @@ -618,4 +601,3 @@ unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj) { } #endif // ASSIMP_BUILD_NO_C4D_IMPORTER - diff --git a/code/AssetLib/C4D/C4DImporter.h b/code/AssetLib/C4D/C4DImporter.h index f9406c3e0..c44cf5e37 100644 --- a/code/AssetLib/C4D/C4DImporter.h +++ b/code/AssetLib/C4D/C4DImporter.h @@ -2,7 +2,7 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2020, assimp team +Copyright (c) 2006-2021, assimp team All rights reserved. Redistribution and use of this software in source and binary forms, @@ -56,8 +56,8 @@ struct aiMaterial; struct aiImporterDesc; -namespace melange { - class BaseObject; // c4d_file.h +namespace cineware { + class BaseObject; class PolygonObject; class BaseMaterial; class BaseShader; @@ -71,43 +71,34 @@ namespace Assimp { } // ------------------------------------------------------------------------------------------- -/** Importer class to load Cinema4D files using the Melange library to be obtained from - * www.plugincafe.com +/** Importer class to load Cinema4D files using the Cineware library to be obtained from + * https://developers.maxon.net * - * Note that Melange is not free software. */ + * Note that Cineware is not free software. */ // ------------------------------------------------------------------------------------------- class C4DImporter : public BaseImporter, public LogFunctions { public: - C4DImporter(); - ~C4DImporter(); - bool CanRead( const std::string& pFile, IOSystem* pIOHandler, - bool checkSig) const; + bool CanRead( const std::string& pFile, IOSystem*, bool checkSig) const override; protected: - // -------------------- - const aiImporterDesc* GetInfo () const; + const aiImporterDesc* GetInfo () const override; - // -------------------- - void SetupProperties(const Importer* pImp); - - // -------------------- - void InternReadFile( const std::string& pFile, aiScene* pScene, - IOSystem* pIOHandler); + void InternReadFile( const std::string& pFile, aiScene*, IOSystem* ) override; private: - void ReadMaterials(melange::BaseMaterial* mat); - void RecurseHierarchy(melange::BaseObject* object, aiNode* parent); - aiMesh* ReadMesh(melange::BaseObject* object); - unsigned int ResolveMaterial(melange::PolygonObject* obj); + void ReadMaterials(cineware::BaseMaterial* mat); + void RecurseHierarchy(cineware::BaseObject* object, aiNode* parent); + aiMesh* ReadMesh(cineware::BaseObject* object); + unsigned int ResolveMaterial(cineware::PolygonObject* obj); - bool ReadShader(aiMaterial* out, melange::BaseShader* shader); + bool ReadShader(aiMaterial* out, cineware::BaseShader* shader); std::vector meshes; std::vector materials; - typedef std::map MaterialMap; + typedef std::map MaterialMap; MaterialMap material_mapping; }; // !class C4DImporter From fe5a23e1101d6c36596040878d333328a09ab026 Mon Sep 17 00:00:00 2001 From: Krishty Date: Mon, 3 May 2021 17:01:59 +0200 Subject: [PATCH 14/93] fixed bloat in SIB importer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SIB importer, upon needing an empty aiString, did not create a new one but rather copied a predefined global empty string. Since aiStrings contain large buffers, Assimp copied 1028 B of zeros instead of setting five bytes (at least when compiled with Visual C++). Since aiString is a user-defined type without a constexpr constructor, Visual C++ had to generate a thread-safe run-time initializer as well. Now it’s just two instructions. --- code/AssetLib/SIB/SIBImporter.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/AssetLib/SIB/SIBImporter.cpp b/code/AssetLib/SIB/SIBImporter.cpp index 6898fb65c..f73301c21 100644 --- a/code/AssetLib/SIB/SIBImporter.cpp +++ b/code/AssetLib/SIB/SIBImporter.cpp @@ -179,8 +179,7 @@ static void UnknownChunk(StreamReaderLE * /*stream*/, const SIBChunk &chunk) { // Reads a UTF-16LE string and returns it at UTF-8. static aiString ReadString(StreamReaderLE *stream, uint32_t numWChars) { if (nullptr == stream || 0 == numWChars) { - static const aiString empty; - return empty; + return aiString(); } // Allocate buffers (max expansion is 1 byte -> 4 bytes for UTF-8) From e7211790fb6307ae0e73a44a5529b709877d2f89 Mon Sep 17 00:00:00 2001 From: Tom spot Callaway Date: Mon, 3 May 2021 13:27:52 -0400 Subject: [PATCH 15/93] PBR material support --- code/AssetLib/FBX/FBXConverter.cpp | 53 ++++++++++++++++++++++++++++- code/AssetLib/FBX/FBXProperties.cpp | 2 +- include/assimp/material.h | 12 +++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index cb033a651..177fa636c 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -2126,7 +2126,12 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert const aiColor3D &Emissive = GetColorPropertyFromMaterial(props, "Emissive", ok); if (ok) { out_mat->AddProperty(&Emissive, 1, AI_MATKEY_COLOR_EMISSIVE); - } + } else { + const aiColor3D &emissiveColor = GetColorPropertyFromMaterial(props, "Maya|emissive", ok); + if (ok) { + out_mat->AddProperty(&emissiveColor, 1, AI_MATKEY_COLOR_EMISSIVE); + } + } const aiColor3D &Ambient = GetColorPropertyFromMaterial(props, "Ambient", ok); if (ok) { @@ -2207,6 +2212,52 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert if (ok) { out_mat->AddProperty(&DispFactor, 1, "$mat.displacementscaling", 0, 0); } + + // PBR material information + const aiColor3D &baseColor = GetColorPropertyFromMaterial(props, "Maya|base_color", ok); + if (ok) { + out_mat->AddProperty(&baseColor, 1, AI_MATKEY_BASE_COLOR); + } + + const float useColorMap = PropertyGet(props, "Maya|use_color_map", ok); + if (ok) { + out_mat->AddProperty(&useColorMap, 1, AI_MATKEY_USE_COLOR_MAP); + } + + const float useMetallicMap = PropertyGet(props, "Maya|use_metallic_map", ok); + if (ok) { + out_mat->AddProperty(&useMetallicMap, 1, AI_MATKEY_USE_METALLIC_MAP); + } + + const float metallicFactor = PropertyGet(props, "Maya|metallic", ok); + if (ok) { + out_mat->AddProperty(&metallicFactor, 1, AI_MATKEY_METALLIC_FACTOR); + } + + const float useRoughnessMap = PropertyGet(props, "Maya|use_roughness_map", ok); + if (ok) { + out_mat->AddProperty(&useRoughnessMap, 1, AI_MATKEY_USE_ROUGHNESS_MAP); + } + + const float roughnessFactor = PropertyGet(props, "Maya|roughness", ok); + if (ok) { + out_mat->AddProperty(&roughnessFactor, 1, AI_MATKEY_ROUGHNESS_FACTOR); + } + + const float useEmissiveMap = PropertyGet(props, "Maya|use_emissive_map", ok); + if (ok) { + out_mat->AddProperty(&useEmissiveMap, 1, AI_MATKEY_USE_EMISSIVE_MAP); + } + + const float emissiveIntensity = PropertyGet(props, "Maya|emissive_intensity", ok); + if (ok) { + out_mat->AddProperty(&emissiveIntensity, 1, AI_MATKEY_EMISSIVE_INTENSITY); + } + + const float useAOMap = PropertyGet(props, "Maya|use_ao_map", ok); + if (ok) { + out_mat->AddProperty(&useAOMap, 1, AI_MATKEY_USE_AO_MAP); + } } void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTable &props, const TextureMap &_textures, const MeshGeometry *const mesh) { diff --git a/code/AssetLib/FBX/FBXProperties.cpp b/code/AssetLib/FBX/FBXProperties.cpp index 1e4cd0ead..1a5ebffd1 100644 --- a/code/AssetLib/FBX/FBXProperties.cpp +++ b/code/AssetLib/FBX/FBXProperties.cpp @@ -131,7 +131,7 @@ Property* ReadTypedProperty(const Element& element) ParseTokenAsFloat(*tok[6])) ); } - else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView") || !strcmp( cs, "UnitScaleFactor" ) ) { + else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"float") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView") || !strcmp( cs, "UnitScaleFactor" ) ) { checkTokenCount(tok, 5); return new TypedProperty(ParseTokenAsFloat(*tok[4])); } diff --git a/include/assimp/material.h b/include/assimp/material.h index f3daa62dc..08c0491c0 100644 --- a/include/assimp/material.h +++ b/include/assimp/material.h @@ -920,6 +920,18 @@ extern "C" { #define AI_MATKEY_SHADER_PRIMITIVE "?sh.ps", 0, 0 #define AI_MATKEY_SHADER_COMPUTE "?sh.cs", 0, 0 +// --------------------------------------------------------------------------- +// PBR material support +#define AI_MATKEY_USE_COLOR_MAP "$mat.useColorMap", 0, 0 +#define AI_MATKEY_BASE_COLOR "$clr.base", 0, 0 +#define AI_MATKEY_USE_METALLIC_MAP "$mat.useMetallicMap", 0, 0 +#define AI_MATKEY_METALLIC_FACTOR "$mat.metallicFactor", 0, 0 +#define AI_MATKEY_USE_ROUGHNESS_MAP "$mat.useRoughnessMap", 0, 0 +#define AI_MATKEY_ROUGHNESS_FACTOR "$mat.roughnessFactor", 0, 0 +#define AI_MATKEY_USE_EMISSIVE_MAP "$mat.useEmissiveMap", 0, 0 +#define AI_MATKEY_EMISSIVE_INTENSITY "$mat.emissiveIntensity", 0, 0 +#define AI_MATKEY_USE_AO_MAP "$mat.useAOMap", 0, 0 + // --------------------------------------------------------------------------- // Pure key names for all texture-related properties //! @cond MATS_DOC_FULL From f91b439f79cc106f08678a265562191c67b184cf Mon Sep 17 00:00:00 2001 From: Tom spot Callaway Date: Mon, 3 May 2021 13:40:31 -0400 Subject: [PATCH 16/93] preserve UV Stream names in FBX files --- code/AssetLib/Assxml/AssxmlFileWriter.cpp | 7 +++++-- code/AssetLib/FBX/FBXConverter.cpp | 2 ++ include/assimp/mesh.h | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/code/AssetLib/Assxml/AssxmlFileWriter.cpp b/code/AssetLib/Assxml/AssxmlFileWriter.cpp index 6d876b3aa..24fda5955 100644 --- a/code/AssetLib/Assxml/AssxmlFileWriter.cpp +++ b/code/AssetLib/Assxml/AssxmlFileWriter.cpp @@ -598,8 +598,11 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene, if (!mesh->mTextureCoords[a]) break; - ioprintf(io, "\t\t \n", mesh->mNumVertices, - a, mesh->mNumUVComponents[a]); + ioprintf(io, "\t\t \n", + mesh->mNumVertices, + a, + mesh->mTextureCoordsNames[a].C_Str(), + mesh->mNumUVComponents[a]); if (!shortened) { if (mesh->mNumUVComponents[a] == 3) { diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index cb033a651..4778f9b07 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -1126,6 +1126,8 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c *out_uv++ = aiVector3D(v.x, v.y, 0.0f); } + out_mesh->mTextureCoordsNames[i] = mesh.GetTextureCoordChannelName(i); + out_mesh->mNumUVComponents[i] = 2; } diff --git a/include/assimp/mesh.h b/include/assimp/mesh.h index 427dba008..989ed3800 100644 --- a/include/assimp/mesh.h +++ b/include/assimp/mesh.h @@ -674,6 +674,10 @@ struct aiMesh { */ C_STRUCT aiVector3D *mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; + /** Vertex stream names. + */ + C_STRUCT aiString mTextureCoordsNames[AI_MAX_NUMBER_OF_TEXTURECOORDS]; + /** Specifies the number of components for a given UV channel. * Up to three channels are supported (UVW, for accessing volume * or cube maps). If the value is 2 for a given channel n, the From 2a126f9f62a8174448a5ac31d94a3534eefd909f Mon Sep 17 00:00:00 2001 From: Krishty Date: Mon, 3 May 2021 21:46:53 +0200 Subject: [PATCH 17/93] reduced Ogre string bloat The Ogre importer used std::string where a string literal would have been sufficient. Saves another 600 B of code and data. --- code/AssetLib/Ogre/OgreBinarySerializer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/AssetLib/Ogre/OgreBinarySerializer.cpp b/code/AssetLib/Ogre/OgreBinarySerializer.cpp index 0fc18feb9..68b1cf1ed 100644 --- a/code/AssetLib/Ogre/OgreBinarySerializer.cpp +++ b/code/AssetLib/Ogre/OgreBinarySerializer.cpp @@ -55,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { namespace Ogre { -const std::string MESH_VERSION_1_8 = "[MeshSerializer_v1.8]"; -const std::string SKELETON_VERSION_1_8 = "[Serializer_v1.80]"; -const std::string SKELETON_VERSION_1_1 = "[Serializer_v1.10]"; +static constexpr auto MESH_VERSION_1_8 = "[MeshSerializer_v1.8]"; +static constexpr auto SKELETON_VERSION_1_8 = "[Serializer_v1.80]"; +static constexpr auto SKELETON_VERSION_1_1 = "[Serializer_v1.10]"; const unsigned short HEADER_CHUNK_ID = 0x1000; From 7b6dab5e209257a17b4ca3bcc7834e2c8cc402b1 Mon Sep 17 00:00:00 2001 From: Krishty Date: Mon, 3 May 2021 21:52:48 +0200 Subject: [PATCH 18/93] reduced DXF string bloat The DXF importer defined a global std::string constant, only to convert it back to a C string on use. This commit defines the constant as a C string right away, thus saving 340 B of code and data. --- code/AssetLib/DXF/DXFLoader.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/AssetLib/DXF/DXFLoader.cpp b/code/AssetLib/DXF/DXFLoader.cpp index d4a6be4ad..b42d497f4 100644 --- a/code/AssetLib/DXF/DXFLoader.cpp +++ b/code/AssetLib/DXF/DXFLoader.cpp @@ -63,11 +63,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; // AutoCAD Binary DXF -const std::string AI_DXF_BINARY_IDENT = std::string("AutoCAD Binary DXF\r\n\x1a\0"); -const size_t AI_DXF_BINARY_IDENT_LEN = 24u; +static constexpr char AI_DXF_BINARY_IDENT[] = "AutoCAD Binary DXF\r\n\x1a"; +static constexpr size_t AI_DXF_BINARY_IDENT_LEN = sizeof AI_DXF_BINARY_IDENT; // default vertex color that all uncolored vertices will receive -const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f)); +static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f)); // color indices for DXF - 16 are supported, the table is // taken directly from the DXF spec. @@ -156,10 +156,10 @@ void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene, } // Check whether this is a binary DXF file - we can't read binary DXF files :-( - char buff[AI_DXF_BINARY_IDENT_LEN+1] = {0}; + char buff[AI_DXF_BINARY_IDENT_LEN] = {0}; file->Read(buff,AI_DXF_BINARY_IDENT_LEN,1); - if (0 == strncmp(AI_DXF_BINARY_IDENT.c_str(),buff,AI_DXF_BINARY_IDENT_LEN)) { + if (0 == memcmp(AI_DXF_BINARY_IDENT,buff,AI_DXF_BINARY_IDENT_LEN)) { throw DeadlyImportError("DXF: Binary files are not supported at the moment"); } @@ -549,7 +549,7 @@ void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output) ++reader; } - ASSIMP_LOG_VERBOSE_DEBUG_F( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(), + ASSIMP_LOG_VERBOSE_DEBUG_F( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(), " inserted blocks in ENTITIES" ); } From f3c18556d1331e43ac5828fa82bf10fee966df96 Mon Sep 17 00:00:00 2001 From: Krishty Date: Tue, 4 May 2021 22:03:44 +0200 Subject: [PATCH 19/93] reduced OpenGEX string bloat The OpenGEX importer defined a few global std::string constants, only to convert them back to C strings on use. This commit defines them as C strings from the beginning. strncmp() was used to compare these strings to other strings, but the length limit was set to string length, which made it equivalent to strcmp(), just slower. Fixed that as well. --- code/AssetLib/OpenGEX/OpenGEXImporter.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp index b29aeeeb1..7ee278521 100644 --- a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp +++ b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp @@ -735,22 +735,22 @@ enum MeshAttribute { TexCoord }; -static const std::string PosToken = "position"; -static const std::string ColToken = "color"; -static const std::string NormalToken = "normal"; -static const std::string TexCoordToken = "texcoord"; +constexpr auto PosToken = "position"; +constexpr auto ColToken = "color"; +constexpr auto NormalToken = "normal"; +constexpr auto TexCoordToken = "texcoord"; //------------------------------------------------------------------------------------------------ static MeshAttribute getAttributeByName(const char *attribName) { ai_assert(nullptr != attribName); - if (0 == strncmp(PosToken.c_str(), attribName, PosToken.size())) { + if (0 == strcmp(PosToken, attribName)) { return Position; - } else if (0 == strncmp(ColToken.c_str(), attribName, ColToken.size())) { + } else if (0 == strcmp(ColToken, attribName)) { return Color; - } else if (0 == strncmp(NormalToken.c_str(), attribName, NormalToken.size())) { + } else if (0 == strcmp(NormalToken, attribName)) { return Normal; - } else if (0 == strncmp(TexCoordToken.c_str(), attribName, TexCoordToken.size())) { + } else if (0 == strcmp(TexCoordToken, attribName)) { return TexCoord; } From b57ce004f805f133cf731311c3c8a6f08b0d7db9 Mon Sep 17 00:00:00 2001 From: Krishty Date: Tue, 4 May 2021 09:45:26 +0200 Subject: [PATCH 20/93] reduced FBX string bloat The FBX importer used two std::strings where string literals would have been sufficient. --- code/AssetLib/FBX/FBXMeshGeometry.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/AssetLib/FBX/FBXMeshGeometry.cpp b/code/AssetLib/FBX/FBXMeshGeometry.cpp index 2bca8dff2..4f87c5a2c 100644 --- a/code/AssetLib/FBX/FBXMeshGeometry.cpp +++ b/code/AssetLib/FBX/FBXMeshGeometry.cpp @@ -604,15 +604,15 @@ void MeshGeometry::ReadVertexDataTangents(std::vector& tangents_out, } // ------------------------------------------------------------------------------------------------ -static const std::string BinormalIndexToken = "BinormalIndex"; -static const std::string BinormalsIndexToken = "BinormalsIndex"; +static const char * BinormalIndexToken = "BinormalIndex"; +static const char * BinormalsIndexToken = "BinormalsIndex"; void MeshGeometry::ReadVertexDataBinormals(std::vector& binormals_out, const Scope& source, const std::string& MappingInformationType, const std::string& ReferenceInformationType) { const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal"; - const char * strIdx = source.Elements().count( "Binormals" ) > 0 ? BinormalsIndexToken.c_str() : BinormalIndexToken.c_str(); + const char * strIdx = source.Elements().count( "Binormals" ) > 0 ? BinormalsIndexToken : BinormalIndexToken; ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType, str, strIdx, From 2925592c640132e2b34d9aa52d7e36d675b18092 Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 04:55:08 -0400 Subject: [PATCH 21/93] [assimp] Make sure ctype calls use unsigned char. Cast to unsigned char as required by C++ (see C++ **[cctype.cyn]** -> ISO C99 section 7.4, [see also](https://en.cppreference.com/w/cpp/string/byte/isspace)). Addresses https://github.com/assimp/assimp/issues/3867 and then some. --- code/AssetLib/3DS/3DSConverter.cpp | 2 +- code/AssetLib/AMF/AMFImporter.cpp | 2 +- code/AssetLib/BVH/BVHLoader.cpp | 4 ++-- code/AssetLib/Blender/BlenderLoader.cpp | 6 +++--- code/AssetLib/Collada/ColladaParser.cpp | 2 +- code/AssetLib/FBX/FBXMaterial.cpp | 2 +- code/AssetLib/MD3/MD3Loader.cpp | 2 +- code/AssetLib/X/XFileImporter.cpp | 4 ++-- code/AssetLib/X/XFileParser.cpp | 4 ++-- code/Common/BaseImporter.cpp | 6 +++--- include/assimp/ParsingUtils.h | 2 +- include/assimp/StringComparison.h | 8 ++++---- include/assimp/StringUtils.h | 2 +- 13 files changed, 23 insertions(+), 23 deletions(-) diff --git a/code/AssetLib/3DS/3DSConverter.cpp b/code/AssetLib/3DS/3DSConverter.cpp index c977867c0..aca16b0d6 100644 --- a/code/AssetLib/3DS/3DSConverter.cpp +++ b/code/AssetLib/3DS/3DSConverter.cpp @@ -69,7 +69,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() { for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) { std::string s = mScene->mMaterials[i].mName; for (std::string::iterator it = s.begin(); it != s.end(); ++it) { - *it = static_cast(::tolower(*it)); + *it = static_cast(::tolower(static_cast(*it))); } if (std::string::npos == s.find("default")) continue; diff --git a/code/AssetLib/AMF/AMFImporter.cpp b/code/AssetLib/AMF/AMFImporter.cpp index 1a3efba9a..e77b65f77 100644 --- a/code/AssetLib/AMF/AMFImporter.cpp +++ b/code/AssetLib/AMF/AMFImporter.cpp @@ -205,7 +205,7 @@ void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::s } static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) { - return (isalnum(pChar) || (pChar == '+') || (pChar == '/')); + return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/')); } void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector &pOutputData) const { diff --git a/code/AssetLib/BVH/BVHLoader.cpp b/code/AssetLib/BVH/BVHLoader.cpp index 8ae99033c..cf78fb6c6 100644 --- a/code/AssetLib/BVH/BVHLoader.cpp +++ b/code/AssetLib/BVH/BVHLoader.cpp @@ -359,7 +359,7 @@ void BVHLoader::ReadMotion(aiScene * /*pScene*/) { std::string BVHLoader::GetNextToken() { // skip any preceding whitespace while (mReader != mBuffer.end()) { - if (!isspace(*mReader)) + if (!isspace((unsigned char)*mReader)) break; // count lines @@ -372,7 +372,7 @@ std::string BVHLoader::GetNextToken() { // collect all chars till the next whitespace. BVH is easy in respect to that. std::string token; while (mReader != mBuffer.end()) { - if (isspace(*mReader)) + if (isspace((unsigned char)*mReader)) break; token.push_back(*mReader); diff --git a/code/AssetLib/Blender/BlenderLoader.cpp b/code/AssetLib/Blender/BlenderLoader.cpp index 3722b9c73..56f4e985f 100644 --- a/code/AssetLib/Blender/BlenderLoader.cpp +++ b/code/AssetLib/Blender/BlenderLoader.cpp @@ -420,9 +420,9 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M --s; } - curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower(s[1]); - curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower(s[2]); - curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower(s[3]); + curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower((unsigned char)s[1]); + curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower((unsigned char)s[2]); + curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower((unsigned char)s[3]); curTex->achFormatHint[3] = '\0'; // tex->mHeight = 0; diff --git a/code/AssetLib/Collada/ColladaParser.cpp b/code/AssetLib/Collada/ColladaParser.cpp index 42166fdd4..1ef109f11 100644 --- a/code/AssetLib/Collada/ColladaParser.cpp +++ b/code/AssetLib/Collada/ColladaParser.cpp @@ -234,7 +234,7 @@ void ColladaParser::UriDecodePath(aiString &ss) { #if defined(_MSC_VER) if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') { #else - if (ss.data[0] == '/' && isalpha(ss.data[1]) && ss.data[2] == ':') { + if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') { #endif --ss.length; ::memmove(ss.data, ss.data + 1, ss.length); diff --git a/code/AssetLib/FBX/FBXMaterial.cpp b/code/AssetLib/FBX/FBXMaterial.cpp index 3af014bc3..409d7304a 100644 --- a/code/AssetLib/FBX/FBXMaterial.cpp +++ b/code/AssetLib/FBX/FBXMaterial.cpp @@ -82,7 +82,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con // lower-case shading because Blender (for example) writes "Phong" for (size_t i = 0; i < shading.length(); ++i) { - shading[i] = static_cast(tolower(shading[i])); + shading[i] = static_cast(tolower(static_cast(shading[i]))); } std::string templateName; if(shading == "phong") { diff --git a/code/AssetLib/MD3/MD3Loader.cpp b/code/AssetLib/MD3/MD3Loader.cpp index e27079766..3002aff67 100644 --- a/code/AssetLib/MD3/MD3Loader.cpp +++ b/code/AssetLib/MD3/MD3Loader.cpp @@ -702,7 +702,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy } filename = mFile.substr(s), path = mFile.substr(0, s); for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) { - *it = static_cast(tolower(*it)); + *it = static_cast(tolower(static_cast(*it))); } // Load multi-part model file, if necessary diff --git a/code/AssetLib/X/XFileImporter.cpp b/code/AssetLib/X/XFileImporter.cpp index cb245ed74..1fcd6b3db 100644 --- a/code/AssetLib/X/XFileImporter.cpp +++ b/code/AssetLib/X/XFileImporter.cpp @@ -667,8 +667,8 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector &extensions) { } for (size_t i = 0; i < read; ++i) { - buffer[i] = static_cast(::tolower(buffer[i])); + buffer[i] = static_cast(::tolower((unsigned char)buffer[i])); } // It is not a proper handling of unicode files here ... @@ -214,7 +214,7 @@ void BaseImporter::GetExtensionList(std::set &extensions) { token.clear(); const char *ptr(tokens[i]); for (size_t tokIdx = 0; tokIdx < len; ++tokIdx) { - token.push_back(static_cast(tolower(*ptr))); + token.push_back(static_cast(tolower(static_cast(*ptr)))); ++ptr; } const char *r = strstr(buffer, token.c_str()); @@ -223,7 +223,7 @@ void BaseImporter::GetExtensionList(std::set &extensions) { } // We need to make sure that we didn't accidentially identify the end of another token as our token, // e.g. in a previous version the "gltf " present in some gltf files was detected as "f " - if (noAlphaBeforeTokens && (r != buffer && isalpha(r[-1]))) { + if (noAlphaBeforeTokens && (r != buffer && isalpha(static_cast(r[-1])))) { continue; } // We got a match, either we don't care where it is, or it happens to diff --git a/include/assimp/ParsingUtils.h b/include/assimp/ParsingUtils.h index b52b0610e..b5074869e 100644 --- a/include/assimp/ParsingUtils.h +++ b/include/assimp/ParsingUtils.h @@ -262,7 +262,7 @@ AI_FORCE_INLINE unsigned int tokenize(const string_type &str, std::vector= n) return 0; - c1 = tolower(*s1++); - c2 = tolower(*s2++); + c1 = tolower((unsigned char)*(s1++)); + c2 = tolower((unsigned char)*(s2++)); } while (c1 && (c1 == c2)); return c1 - c2; diff --git a/include/assimp/StringUtils.h b/include/assimp/StringUtils.h index 4afd717cf..93b7c3f0b 100644 --- a/include/assimp/StringUtils.h +++ b/include/assimp/StringUtils.h @@ -157,7 +157,7 @@ AI_FORCE_INLINE std::string ai_decimal_to_hexa(T toConvert) { ss >> result; for (size_t i = 0; i < result.size(); ++i) { - result[i] = (char)toupper(result[i]); + result[i] = (char)toupper((unsigned char)result[i]); } return result; From 1ec8d4b6cf15c8a14e8cc33834b9164c85cd79d7 Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 17:22:44 -0400 Subject: [PATCH 22/93] [draco] Make sure ctype calls use unsigned char. Addresses https://github.com/assimp/assimp/issues/3867 and then some. --- contrib/draco/src/draco/io/parser_utils.cc | 2 +- contrib/draco/src/draco/io/ply_reader.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/draco/src/draco/io/parser_utils.cc b/contrib/draco/src/draco/io/parser_utils.cc index 753a1b314..4f95f6f84 100644 --- a/contrib/draco/src/draco/io/parser_utils.cc +++ b/contrib/draco/src/draco/io/parser_utils.cc @@ -252,7 +252,7 @@ DecoderBuffer ParseLineIntoDecoderBuffer(DecoderBuffer *buffer) { std::string ToLower(const std::string &str) { std::string out; - std::transform(str.begin(), str.end(), std::back_inserter(out), tolower); + std::transform(str.begin(), str.end(), std::back_inserter(out), [](unsigned char c){return tolower(c);}); return out; } diff --git a/contrib/draco/src/draco/io/ply_reader.cc b/contrib/draco/src/draco/io/ply_reader.cc index ea7f2689a..cb32df225 100644 --- a/contrib/draco/src/draco/io/ply_reader.cc +++ b/contrib/draco/src/draco/io/ply_reader.cc @@ -268,14 +268,14 @@ std::vector PlyReader::SplitWords(const std::string &line) { while ((end = line.find_first_of(" \t\n\v\f\r", start)) != std::string::npos) { const std::string word(line.substr(start, end - start)); - if (!std::all_of(word.begin(), word.end(), isspace)) { + if (!std::all_of(word.begin(), word.end(), [](unsigned char c){return isspace(c);})) { output.push_back(word); } start = end + 1; } const std::string last_word(line.substr(start)); - if (!std::all_of(last_word.begin(), last_word.end(), isspace)) { + if (!std::all_of(last_word.begin(), last_word.end(), [](unsigned char c){return isspace(c);})) { output.push_back(last_word); } return output; From 7dd7a053a91322fad88cdf958c6d0b3b7b91cb90 Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 17:25:45 -0400 Subject: [PATCH 23/93] [gtest] Fixed a rogue std::isalnum Use IsAlNum instead (gtest-port.h), which deals with char signedness correctly. This was the only spot in gtest where a cctype function was called instead of its gtest-port.h equivalent. Addresses https://github.com/assimp/assimp/issues/3867 and then some. --- contrib/gtest/include/gtest/internal/gtest-param-util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/gtest/include/gtest/internal/gtest-param-util.h b/contrib/gtest/include/gtest/internal/gtest-param-util.h index 82cab9b02..9d725a433 100644 --- a/contrib/gtest/include/gtest/internal/gtest-param-util.h +++ b/contrib/gtest/include/gtest/internal/gtest-param-util.h @@ -644,7 +644,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { // Check for invalid characters for (std::string::size_type index = 0; index < name.size(); ++index) { - if (!isalnum(name[index]) && name[index] != '_') + if (!IsAlNum(name[index]) && name[index] != '_') return false; } From 200086c4c5ea18593dace1f3800d1213b8b3588c Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 17:26:17 -0400 Subject: [PATCH 24/93] [assimp_view] Make sure ctype calls use unsigned char. Addresses https://github.com/assimp/assimp/issues/3867 and then some. --- tools/assimp_view/Material.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/assimp_view/Material.cpp b/tools/assimp_view/Material.cpp index 8141fb58c..bcc93011e 100644 --- a/tools/assimp_view/Material.cpp +++ b/tools/assimp_view/Material.cpp @@ -272,7 +272,7 @@ bool CMaterialManager::TryLongerPath(char* szTemp,aiString* p_szString) szExtFound - 1 - info.cFileName); for (unsigned int i = 0; i < iSizeFound;++i) - info.cFileName[i] = (CHAR)tolower(info.cFileName[i]); + info.cFileName[i] = (CHAR)tolower((unsigned char)info.cFileName[i]); if (0 == memcmp(info.cFileName,szFile2, std::min(iSizeFound,iSize))) { @@ -354,7 +354,7 @@ int CMaterialManager::FindValidPath(aiString* p_szString) for (unsigned int i = 0;;++i) { if ('\0' == szTemp[i])break; - szTemp[i] = (char)tolower(szTemp[i]); + szTemp[i] = (char)tolower((unsigned char)szTemp[i]); } if(TryLongerPath(szTemp,p_szString))return 1; From c8ad8c6017c78534d54a8478d3aa0b1203cc515b Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 04:15:17 -0400 Subject: [PATCH 25/93] [mmd] Remove stderr spam. Removed stderr spam and cleaned up exception text. Addresses #3865. --- code/AssetLib/MMD/MMDPmxParser.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/code/AssetLib/MMD/MMDPmxParser.cpp b/code/AssetLib/MMD/MMDPmxParser.cpp index cb4787efd..d57dc169a 100644 --- a/code/AssetLib/MMD/MMDPmxParser.cpp +++ b/code/AssetLib/MMD/MMDPmxParser.cpp @@ -478,8 +478,7 @@ namespace pmx void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/) { - std::cerr << "Not Implemented Exception" << std::endl; - throw DeadlyImportError("MMD: Not Implemented Exception"); + throw DeadlyImportError("MMD: Soft Body support is not implemented."); } void PmxModel::Init() @@ -516,15 +515,13 @@ namespace pmx char magic[4]; stream->read((char*) magic, sizeof(char) * 4); if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20) - { - std::cerr << "invalid magic number." << std::endl; - throw DeadlyImportError("MMD: invalid magic number."); + { + throw DeadlyImportError("MMD: Invalid magic number."); } stream->read((char*) &version, sizeof(float)); if (version != 2.0f && version != 2.1f) { - std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl; - throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but ", ai_to_string(version)); + throw DeadlyImportError("MMD: Unsupported version (must be 2.0 or 2.1): ", ai_to_string(version)); } this->setting.Read(stream); From a9fb1e56ae1504001b3848c2019fb622fd6b72e3 Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 19:16:23 -0400 Subject: [PATCH 26/93] Add ai_str_toprintable; fixed garbage messages in HMP, MDL, Q3D loaders. - ai_str_toprintable: See docs in StringUtils.h. - HMP, MDL, Q3D: In particular, newlines in binary data were complicating logging. --- code/AssetLib/HMP/HMPLoader.cpp | 8 ++------ code/AssetLib/MDL/MDLLoader.cpp | 2 +- code/AssetLib/Q3D/Q3DLoader.cpp | 3 ++- include/assimp/StringUtils.h | 27 +++++++++++++++++++++++++++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/code/AssetLib/HMP/HMPLoader.cpp b/code/AssetLib/HMP/HMPLoader.cpp index 56401f5c9..cd14cb9c3 100644 --- a/code/AssetLib/HMP/HMPLoader.cpp +++ b/code/AssetLib/HMP/HMPLoader.cpp @@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssetLib/HMP/HMPLoader.h" #include "AssetLib/MD2/MD2FileData.h" +#include #include #include #include @@ -151,12 +152,7 @@ void HMPImporter::InternReadFile(const std::string &pFile, InternReadFile_HMP7(); } else { // Print the magic word to the logger - char szBuffer[5]; - szBuffer[0] = ((char *)&iMagic)[0]; - szBuffer[1] = ((char *)&iMagic)[1]; - szBuffer[2] = ((char *)&iMagic)[2]; - szBuffer[3] = ((char *)&iMagic)[3]; - szBuffer[4] = '\0'; + std::string szBuffer = ai_str_toprintable((const char *)&iMagic, sizeof(iMagic)); delete[] mBuffer; mBuffer = nullptr; diff --git a/code/AssetLib/MDL/MDLLoader.cpp b/code/AssetLib/MDL/MDLLoader.cpp index a4286a716..4c0fcd339 100644 --- a/code/AssetLib/MDL/MDLLoader.cpp +++ b/code/AssetLib/MDL/MDLLoader.cpp @@ -252,7 +252,7 @@ void MDLImporter::InternReadFile(const std::string &pFile, } else { // print the magic word to the log file throw DeadlyImportError("Unknown MDL subformat ", pFile, - ". Magic word (", std::string((char *)&iMagicWord, 4), ") is not known"); + ". Magic word (", ai_str_toprintable((const char *)&iMagicWord, sizeof(iMagicWord)), ") is not known"); } // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system diff --git a/code/AssetLib/Q3D/Q3DLoader.cpp b/code/AssetLib/Q3D/Q3DLoader.cpp index b52f86672..b6684d1b8 100644 --- a/code/AssetLib/Q3D/Q3DLoader.cpp +++ b/code/AssetLib/Q3D/Q3DLoader.cpp @@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // internal headers #include "Q3DLoader.h" +#include #include #include #include @@ -115,7 +116,7 @@ void Q3DImporter::InternReadFile(const std::string &pFile, // Check the file's signature if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) && ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) { - throw DeadlyImportError("Not a Quick3D file. Signature string is: ", std::string((const char *)stream.GetPtr(), 8)); + throw DeadlyImportError("Not a Quick3D file. Signature string is: ", ai_str_toprintable((const char *)stream.GetPtr(), 8)); } // Print the file format version diff --git a/include/assimp/StringUtils.h b/include/assimp/StringUtils.h index 4afd717cf..5ee1f48d8 100644 --- a/include/assimp/StringUtils.h +++ b/include/assimp/StringUtils.h @@ -249,4 +249,31 @@ AI_FORCE_INLINE std::string ai_str_toupper(const std::string &in) { return out; } +// --------------------------------------------------------------------------------- +/// @brief Make a string printable by replacing all non-printable characters with +/// the specified placeholder character. +/// @param in The incoming string. +/// @param placeholder Placeholder character, default is a question mark. +/// @return The string, with all non-printable characters replaced. +AI_FORCE_INLINE std::string ai_str_toprintable(const std::string &in, char placeholder = '?') { + std::string out(in); + std::transform(out.begin(), out.end(), out.begin(), [placeholder] (unsigned char c) { + return isprint(c) ? (char)c : placeholder; + }); + return out; +} + +// --------------------------------------------------------------------------------- +/// @brief Make a string printable by replacing all non-printable characters with +/// the specified placeholder character. +/// @param in The incoming string. +/// @param len The length of the incoming string. +/// @param placeholder Placeholder character, default is a question mark. +/// @return The string, with all non-printable characters replaced. Will return an +/// empty string if in is null or len is <= 0. +AI_FORCE_INLINE std::string ai_str_toprintable(const char *in, int len, char placeholder = '?') { + return (in && len > 0) ? ai_str_toprintable(std::string(in, len), placeholder) : std::string(); +} + + #endif From 9a04f5d4b0ea3cafba84dfcdc3f8746cc3eaac0a Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 21:24:44 -0400 Subject: [PATCH 27/93] Fix garbage messages in SIB, MD2, and MDC loaders. --- code/AssetLib/MD2/MD2Loader.cpp | 32 +++++++++++++------------------ code/AssetLib/MDC/MDCLoader.cpp | 13 +++---------- code/AssetLib/SIB/SIBImporter.cpp | 7 ++++--- 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/code/AssetLib/MD2/MD2Loader.cpp b/code/AssetLib/MD2/MD2Loader.cpp index 9ccbcdfca..5308ac89c 100644 --- a/code/AssetLib/MD2/MD2Loader.cpp +++ b/code/AssetLib/MD2/MD2Loader.cpp @@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include @@ -148,46 +149,39 @@ void MD2Importer::ValidateHeader( ) if (m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE && m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE) { - char szBuffer[5]; - szBuffer[0] = ((char*)&m_pcHeader->magic)[0]; - szBuffer[1] = ((char*)&m_pcHeader->magic)[1]; - szBuffer[2] = ((char*)&m_pcHeader->magic)[2]; - szBuffer[3] = ((char*)&m_pcHeader->magic)[3]; - szBuffer[4] = '\0'; - - throw DeadlyImportError("Invalid MD2 magic word: should be IDP2, the " - "magic word found is " + std::string(szBuffer)); + throw DeadlyImportError("Invalid MD2 magic word: expected IDP2, found ", + ai_str_toprintable((char *)&m_pcHeader->magic, 4)); } // check file format version if (m_pcHeader->version != 8) - ASSIMP_LOG_WARN( "Unsupported md2 file version. Continuing happily ..."); + ASSIMP_LOG_WARN( "Unsupported MD2 file version. Continuing happily ..."); // check some values whether they are valid if (0 == m_pcHeader->numFrames) - throw DeadlyImportError( "Invalid md2 file: NUM_FRAMES is 0"); + throw DeadlyImportError( "Invalid MD2 file: NUM_FRAMES is 0"); if (m_pcHeader->offsetEnd > (uint32_t)fileSize) - throw DeadlyImportError( "Invalid md2 file: File is too small"); + throw DeadlyImportError( "Invalid MD2 file: File is too small"); if (m_pcHeader->numSkins > AI_MAX_ALLOC(MD2::Skin)) { - throw DeadlyImportError("Invalid MD2 header: too many skins, would overflow"); + throw DeadlyImportError("Invalid MD2 header: Too many skins, would overflow"); } if (m_pcHeader->numVertices > AI_MAX_ALLOC(MD2::Vertex)) { - throw DeadlyImportError("Invalid MD2 header: too many vertices, would overflow"); + throw DeadlyImportError("Invalid MD2 header: Too many vertices, would overflow"); } if (m_pcHeader->numTexCoords > AI_MAX_ALLOC(MD2::TexCoord)) { - throw DeadlyImportError("Invalid MD2 header: too many texcoords, would overflow"); + throw DeadlyImportError("Invalid MD2 header: Too many texcoords, would overflow"); } if (m_pcHeader->numTriangles > AI_MAX_ALLOC(MD2::Triangle)) { - throw DeadlyImportError("Invalid MD2 header: too many triangles, would overflow"); + throw DeadlyImportError("Invalid MD2 header: Too many triangles, would overflow"); } if (m_pcHeader->numFrames > AI_MAX_ALLOC(MD2::Frame)) { - throw DeadlyImportError("Invalid MD2 header: too many frames, would overflow"); + throw DeadlyImportError("Invalid MD2 header: Too many frames, would overflow"); } // -1 because Frame already contains one @@ -199,7 +193,7 @@ void MD2Importer::ValidateHeader( ) m_pcHeader->offsetFrames + m_pcHeader->numFrames * frameSize >= fileSize || m_pcHeader->offsetEnd > fileSize) { - throw DeadlyImportError("Invalid MD2 header: some offsets are outside the file"); + throw DeadlyImportError("Invalid MD2 header: Some offsets are outside the file"); } if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS) @@ -210,7 +204,7 @@ void MD2Importer::ValidateHeader( ) ASSIMP_LOG_WARN("The model contains more vertices than Quake 2 supports"); if (m_pcHeader->numFrames <= configFrameID ) - throw DeadlyImportError("The requested frame is not existing the file"); + throw DeadlyImportError("MD2: The requested frame (", configFrameID, ") does not exist in the file"); } // ------------------------------------------------------------------------------------------------ diff --git a/code/AssetLib/MDC/MDCLoader.cpp b/code/AssetLib/MDC/MDCLoader.cpp index 17a349768..ef5fdbfcd 100644 --- a/code/AssetLib/MDC/MDCLoader.cpp +++ b/code/AssetLib/MDC/MDCLoader.cpp @@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include @@ -143,16 +144,8 @@ void MDCImporter::ValidateHeader() { if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE && pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE) { - char szBuffer[5]; - szBuffer[0] = ((char *)&pcHeader->ulIdent)[0]; - szBuffer[1] = ((char *)&pcHeader->ulIdent)[1]; - szBuffer[2] = ((char *)&pcHeader->ulIdent)[2]; - szBuffer[3] = ((char *)&pcHeader->ulIdent)[3]; - szBuffer[4] = '\0'; - - throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the " - "magic word found is " + - std::string(szBuffer)); + throw DeadlyImportError("Invalid MDC magic word: expected IDPC, found ", + ai_str_toprintable((char *)&pcHeader->ulIdent, 4)); } if (pcHeader->ulVersion != AI_MDC_VERSION) { diff --git a/code/AssetLib/SIB/SIBImporter.cpp b/code/AssetLib/SIB/SIBImporter.cpp index 6898fb65c..5c43c8587 100644 --- a/code/AssetLib/SIB/SIBImporter.cpp +++ b/code/AssetLib/SIB/SIBImporter.cpp @@ -68,6 +68,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include @@ -166,14 +167,14 @@ static aiColor3D ReadColor(StreamReaderLE *stream) { } static void UnknownChunk(StreamReaderLE * /*stream*/, const SIBChunk &chunk) { - char temp[5] = { + char temp[4] = { static_cast((chunk.Tag >> 24) & 0xff), static_cast((chunk.Tag >> 16) & 0xff), static_cast((chunk.Tag >> 8) & 0xff), - static_cast(chunk.Tag & 0xff), '\0' + static_cast(chunk.Tag & 0xff) }; - ASSIMP_LOG_WARN((Formatter::format(), "SIB: Skipping unknown '", temp, "' chunk.")); + ASSIMP_LOG_WARN((Formatter::format(), "SIB: Skipping unknown '", ai_str_toprintable(temp, 4), "' chunk.")); } // Reads a UTF-16LE string and returns it at UTF-8. From 558457e5bf2711ab845239fe4b98c872f4b05d33 Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 03:04:12 -0400 Subject: [PATCH 28/93] [openddlparser] Remove default log handler and unsolicited output. This addresses part of #3862. - Remove default log handler. - Log callback can now be set to nullptr, which just makes logging a no-op. - Initial log callback is nullptr. - Also tweaked format of token error log message and removed newline. Assimp code that uses this may regain logging output by installing a callback and directing the output through appropriate logging facilities. --- contrib/openddlparser/code/OpenDDLParser.cpp | 47 ++++++-------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index 024c26f41..6a9f802ec 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -72,13 +72,15 @@ const char *getTypeToken(Value::ValueType type) { } 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 << part; - callback(ddl_error_msg, stream.str()); + if (callback) { + std::string full(in); + std::string part(full.substr(0, 50)); + std::stringstream stream; + stream << "Invalid token \"" << *in << "\" " + << "(expected \"" << exp << "\") " + << "in: \"" << part << "\""; + callback(ddl_error_msg, stream.str()); + } } static bool isIntegerType(Value::ValueType integerType) { @@ -111,26 +113,8 @@ static DDLNode *createDDLNode(Text *id, OpenDDLParser *parser) { return node; } -static void logMessage(LogSeverity severity, const std::string &msg) { - std::string log; - if (ddl_debug_msg == severity) { - log += "Debug:"; - } else if (ddl_info_msg == severity) { - log += "Info :"; - } else if (ddl_warn_msg == severity) { - log += "Warn :"; - } else if (ddl_error_msg == severity) { - log += "Error:"; - } else { - log += "None :"; - } - - log += msg; - std::cout << log; -} - OpenDDLParser::OpenDDLParser() : - m_logCallback(logMessage), + m_logCallback(nullptr), m_buffer(), m_stack(), m_context(nullptr) { @@ -138,7 +122,7 @@ OpenDDLParser::OpenDDLParser() : } OpenDDLParser::OpenDDLParser(const char *buffer, size_t len) : - m_logCallback(&logMessage), m_buffer(), m_context(nullptr) { + m_logCallback(nullptr), m_buffer(), m_context(nullptr) { if (0 != len) { setBuffer(buffer, len); } @@ -149,13 +133,8 @@ OpenDDLParser::~OpenDDLParser() { } void OpenDDLParser::setLogCallback(logCallback callback) { - if (nullptr != callback) { - // install user-specific log callback - m_logCallback = callback; - } else { - // install default log callback - m_logCallback = &logMessage; - } + // install user-specific log callback; null = no log callback + m_logCallback = callback; } OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const { From f8609c2c2dc65d40a13c6e542f0cf0058821444b Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 03:32:49 -0400 Subject: [PATCH 29/93] [opengex] Direct OpenDDLParser log messages to assimp logger Also filter unprintable characters. Addresses second part of #3862. --- code/AssetLib/OpenGEX/OpenGEXImporter.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp index b29aeeeb1..44b0bbf7b 100644 --- a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp +++ b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp @@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include @@ -223,6 +224,18 @@ static void propId2StdString(Property *prop, std::string &name, std::string &key } } +//------------------------------------------------------------------------------------------------ +static void logDDLParserMessage (LogSeverity severity, const std::string &rawmsg) { + std::string msg = ai_str_toprintable(rawmsg); + switch (severity) { + case ddl_debug_msg: ASSIMP_LOG_DEBUG(msg); break; + case ddl_info_msg: ASSIMP_LOG_INFO(msg); break; + case ddl_warn_msg: ASSIMP_LOG_WARN(msg); break; + case ddl_error_msg: ASSIMP_LOG_ERROR(msg); break; + default: ASSIMP_LOG_VERBOSE_DEBUG(msg); break; + } +} + //------------------------------------------------------------------------------------------------ OpenGEXImporter::VertexContainer::VertexContainer() : m_numColors(0), m_colors(nullptr), m_numUVComps(), m_textureCoords() { @@ -306,6 +319,7 @@ void OpenGEXImporter::InternReadFile(const std::string &filename, aiScene *pScen pIOHandler->Close(file); OpenDDLParser myParser; + myParser.setLogCallback(&logDDLParserMessage); myParser.setBuffer(&buffer[0], buffer.size()); bool success(myParser.parse()); if (success) { From a03dc4edaa05731e81c5ac9edef78f9ac90097fa Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 20:45:08 -0400 Subject: [PATCH 30/93] [amf] Fix minor typo in error message. Added missing space to detail string on parse failure. --- code/AssetLib/AMF/AMFImporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/AMF/AMFImporter.cpp b/code/AssetLib/AMF/AMFImporter.cpp index 1a3efba9a..07b033b38 100644 --- a/code/AssetLib/AMF/AMFImporter.cpp +++ b/code/AssetLib/AMF/AMFImporter.cpp @@ -268,7 +268,7 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) { mXmlParser = new XmlParser(); if (!mXmlParser->parse(file.get())) { delete mXmlParser; - throw DeadlyImportError("Failed to create XML reader for file" + pFile + "."); + throw DeadlyImportError("Failed to create XML reader for file ", pFile, "."); } // Start reading, search for root tag From ccd1a4455e3f5611e32cc5f933ec7f3f60316b70 Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 21:14:39 -0400 Subject: [PATCH 31/93] [ply] Fix minor typo in error message. --- code/AssetLib/Ply/PlyLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/Ply/PlyLoader.cpp b/code/AssetLib/Ply/PlyLoader.cpp index ce52636dd..93d48bcbf 100644 --- a/code/AssetLib/Ply/PlyLoader.cpp +++ b/code/AssetLib/Ply/PlyLoader.cpp @@ -172,7 +172,7 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy (headerCheck[1] != 'L' && headerCheck[1] != 'l') || (headerCheck[2] != 'Y' && headerCheck[2] != 'y')) { streamedBuffer.close(); - throw DeadlyImportError("Invalid .ply file: Magic number \'ply\' is no there"); + throw DeadlyImportError("Invalid .ply file: Incorrect magic number (expected 'ply' or 'PLY')."); } std::vector mBuffer2; From 6e65115253dbb8806308c8efd399516fcfbd6ba9 Mon Sep 17 00:00:00 2001 From: Jason C Date: Tue, 4 May 2021 21:10:02 -0400 Subject: [PATCH 32/93] [assimp/xml] Improved XML parse error message. Fixed typo, added detail. --- include/assimp/XmlParser.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/assimp/XmlParser.h b/include/assimp/XmlParser.h index f525d3549..bd5281049 100644 --- a/include/assimp/XmlParser.h +++ b/include/assimp/XmlParser.h @@ -136,7 +136,9 @@ public: if (parse_result.status == pugi::status_ok) { return true; } else { - ASSIMP_LOG_DEBUG("Error while parse xml."); + std::ostringstream oss; + oss << "Error while parsing XML: " << parse_result.description() << " @ " << parse_result.offset; + ASSIMP_LOG_DEBUG(oss.str()); return false; } } From 153b890b02efaea35f5a73d3bb10f7576bce57a1 Mon Sep 17 00:00:00 2001 From: "Max Vollmer (Microsoft Havok)" <60260460+ms-maxvollmer@users.noreply.github.com> Date: Wed, 5 May 2021 14:09:43 +0100 Subject: [PATCH 33/93] Prevent accessing nullpointers --- code/AssetLib/glTF2/glTF2Importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index f34b1b451..e6265946b 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -1263,7 +1263,7 @@ aiMeshMorphAnim *CreateMeshMorphAnim(glTF2::Asset&, Node &node, AnimationSampler static const float kMillisecondsFromSeconds = 1000.f; - if (nullptr != samplers.weight) { + if (samplers.weight && samplers.weight->input && samplers.weight->output) { float *times = nullptr; samplers.weight->input->ExtractData(times); float *values = nullptr; From 785cca1bb43f9e6047cb566a910fcd0e3d49951f Mon Sep 17 00:00:00 2001 From: Jason C Date: Wed, 5 May 2021 17:13:10 -0400 Subject: [PATCH 34/93] [amf] Fix crash when file could not be parsed. Fix double free of mXmlParser (deleted but not reset in ParseFile, then deleted again in ~AMFImporter). Should probably use a smart pointer instead, though. Partially addresses https://github.com/assimp/assimp/issues/3888. --- code/AssetLib/AMF/AMFImporter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/AssetLib/AMF/AMFImporter.cpp b/code/AssetLib/AMF/AMFImporter.cpp index 1a3efba9a..add1cdb57 100644 --- a/code/AssetLib/AMF/AMFImporter.cpp +++ b/code/AssetLib/AMF/AMFImporter.cpp @@ -268,6 +268,7 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) { mXmlParser = new XmlParser(); if (!mXmlParser->parse(file.get())) { delete mXmlParser; + mXmlParser = nullptr; throw DeadlyImportError("Failed to create XML reader for file" + pFile + "."); } From 116ebf6e10c39fdb2c88b31445b68d51fdfb5c5a Mon Sep 17 00:00:00 2001 From: Jason C Date: Wed, 5 May 2021 17:30:05 -0400 Subject: [PATCH 35/93] [3ds] Fix assertion failure when file could not be opened Check result of IOSystem::Open before constructing stream. Partially addresses #3888. --- code/AssetLib/3DS/3DSLoader.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/3DS/3DSLoader.cpp b/code/AssetLib/3DS/3DSLoader.cpp index a25355ccc..92fe72bbf 100644 --- a/code/AssetLib/3DS/3DSLoader.cpp +++ b/code/AssetLib/3DS/3DSLoader.cpp @@ -143,7 +143,13 @@ void Discreet3DSImporter::SetupProperties(const Importer * /*pImp*/) { // Imports the given file into the given scene structure. void Discreet3DSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { - StreamReaderLE theStream(pIOHandler->Open(pFile, "rb")); + + auto theFile = pIOHandler->Open(pFile, "rb"); + if (!theFile) { + throw DeadlyImportError("3DS: Could not open ", pFile); + } + + StreamReaderLE theStream(theFile); // We should have at least one chunk if (theStream.GetRemainingSize() < 16) { From 7f13387487d9650f4212489b86e9a8be4beb2a0f Mon Sep 17 00:00:00 2001 From: Jason C Date: Wed, 5 May 2021 17:30:29 -0400 Subject: [PATCH 36/93] [cob] Fix assertion failure when file could not be opened. Check result of IOSystem::Open before constructing stream. Partially addresses #3888. --- code/AssetLib/COB/COBLoader.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/COB/COBLoader.cpp b/code/AssetLib/COB/COBLoader.cpp index efe7fc446..a6e9d4218 100644 --- a/code/AssetLib/COB/COBLoader.cpp +++ b/code/AssetLib/COB/COBLoader.cpp @@ -137,7 +137,13 @@ void COBImporter::SetupProperties(const Importer * /*pImp*/) { // Imports the given file into the given scene structure. void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { COB::Scene scene; - std::unique_ptr stream(new StreamReaderLE(pIOHandler->Open(pFile, "rb"))); + + auto file = pIOHandler->Open(pFile, "rb"); + if (!file) { + ThrowException("Could not open " + pFile); + } + + std::unique_ptr stream(new StreamReaderLE(file)); // check header char head[32]; From 1cd3752ec6b64d584ebce84c0a6d0ae437a6e5c4 Mon Sep 17 00:00:00 2001 From: Jason C Date: Wed, 5 May 2021 17:31:06 -0400 Subject: [PATCH 37/93] [ms3d] Fix assertion failure when file could not be opened. Check result of IOSystem::Open before constructing stream. Partially addresses #3888. --- code/AssetLib/MS3D/MS3DLoader.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/MS3D/MS3DLoader.cpp b/code/AssetLib/MS3D/MS3DLoader.cpp index 192bcbe41..31cbca83b 100644 --- a/code/AssetLib/MS3D/MS3DLoader.cpp +++ b/code/AssetLib/MS3D/MS3DLoader.cpp @@ -215,7 +215,12 @@ void MS3DImporter :: CollectChildJoints(const std::vector& joints, ai void MS3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) { - StreamReaderLE stream(pIOHandler->Open(pFile,"rb")); + + auto file = pIOHandler->Open(pFile, "rb"); + if (!file) + throw DeadlyImportError("MS3D: Could not open ", pFile); + + StreamReaderLE stream(file); // CanRead() should have done this already char head[10]; From e52c2972841afc1806d0f0a7a528cbe4af4fbbf3 Mon Sep 17 00:00:00 2001 From: Jason C Date: Wed, 5 May 2021 17:31:24 -0400 Subject: [PATCH 38/93] [nendo] Fix assertion failure when file could not be opened. Check result of IOSystem::Open before constructing stream. Partially addresses #3888. --- code/AssetLib/NDO/NDOLoader.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/NDO/NDOLoader.cpp b/code/AssetLib/NDO/NDOLoader.cpp index 77fe3e36c..df3a9b15d 100644 --- a/code/AssetLib/NDO/NDOLoader.cpp +++ b/code/AssetLib/NDO/NDOLoader.cpp @@ -116,7 +116,13 @@ void NDOImporter::SetupProperties(const Importer* /*pImp*/) void NDOImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) { - StreamReaderBE reader(pIOHandler->Open( pFile, "rb")); + + auto file = pIOHandler->Open( pFile, "rb"); + if (!file) { + throw DeadlyImportError("Nendo: Could not open ", pFile); + } + + StreamReaderBE reader(file); // first 9 bytes are nendo file format ("nendo 1.n") const char* head = (const char*)reader.GetPtr(); From a80b3b25ebba38a04afc8a72ad46c66759b4a640 Mon Sep 17 00:00:00 2001 From: Jason C Date: Wed, 5 May 2021 17:31:50 -0400 Subject: [PATCH 39/93] [quick3d] Fix assertion failure when file could not be opened. Check result of IOSystem::Open before constructing stream. Partially addresses #3888. --- code/AssetLib/Q3D/Q3DLoader.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/Q3D/Q3DLoader.cpp b/code/AssetLib/Q3D/Q3DLoader.cpp index b52f86672..710dd52ac 100644 --- a/code/AssetLib/Q3D/Q3DLoader.cpp +++ b/code/AssetLib/Q3D/Q3DLoader.cpp @@ -106,7 +106,12 @@ const aiImporterDesc *Q3DImporter::GetInfo() const { // Imports the given file into the given scene structure. void Q3DImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { - StreamReaderLE stream(pIOHandler->Open(pFile, "rb")); + + auto file = pIOHandler->Open(pFile, "rb"); + if (!file) + throw DeadlyImportError("Quick3D: Could not open ", pFile); + + StreamReaderLE stream(file); // The header is 22 bytes large if (stream.GetRemainingSize() < 22) From 0d3e8b52be6f6c1465fc1ff885fa16f7b221b7d2 Mon Sep 17 00:00:00 2001 From: Jason C Date: Wed, 5 May 2021 17:32:10 -0400 Subject: [PATCH 40/93] [sib] Fix assertion failure when file could not be opened. Check result of IOSystem::Open before constructing stream. Partially addresses #3888. --- code/AssetLib/SIB/SIBImporter.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/SIB/SIBImporter.cpp b/code/AssetLib/SIB/SIBImporter.cpp index 6898fb65c..825f20ee2 100644 --- a/code/AssetLib/SIB/SIBImporter.cpp +++ b/code/AssetLib/SIB/SIBImporter.cpp @@ -804,7 +804,12 @@ static void ReadScene(SIB *sib, StreamReaderLE *stream) { // Imports the given file into the given scene structure. void SIBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { - StreamReaderLE stream(pIOHandler->Open(pFile, "rb")); + + auto file = pIOHandler->Open(pFile, "rb"); + if (!file) + throw DeadlyImportError("SIB: Could not open ", pFile); + + StreamReaderLE stream(file); // We should have at least one chunk if (stream.GetRemainingSize() < 16) From 470913bf27e74a6fa6f6ef0f0d0fccd4ebd675de Mon Sep 17 00:00:00 2001 From: Jason C Date: Wed, 5 May 2021 17:46:24 -0400 Subject: [PATCH 41/93] [assbin] Fail if file could not be opened Fail instead of returning empty scene. Partially addresses #3888. --- code/AssetLib/Assbin/AssbinLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/Assbin/AssbinLoader.cpp b/code/AssetLib/Assbin/AssbinLoader.cpp index d94a9ed7d..d94407e03 100644 --- a/code/AssetLib/Assbin/AssbinLoader.cpp +++ b/code/AssetLib/Assbin/AssbinLoader.cpp @@ -671,7 +671,7 @@ void AssbinImporter::ReadBinaryScene(IOStream *stream, aiScene *scene) { void AssbinImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { IOStream *stream = pIOHandler->Open(pFile, "rb"); if (nullptr == stream) { - return; + throw DeadlyImportError("ASSBIN: Could not open ", pFile); } // signature From 98f586c8d443d46b14aa551baa00fbb03188903f Mon Sep 17 00:00:00 2001 From: Jason C Date: Wed, 5 May 2021 17:48:44 -0400 Subject: [PATCH 42/93] [irr] Fail if file could not be parsed. Fail instead of returning empty scene. Partially addresses #3888. TODO: Propagate XML error detail through exception (depends on #3881). --- code/AssetLib/Irr/IRRLoader.cpp | 4 ++-- code/AssetLib/Irr/IRRMeshLoader.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/AssetLib/Irr/IRRLoader.cpp b/code/AssetLib/Irr/IRRLoader.cpp index ed92c93bb..9ec0a9244 100644 --- a/code/AssetLib/Irr/IRRLoader.cpp +++ b/code/AssetLib/Irr/IRRLoader.cpp @@ -859,13 +859,13 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // Check whether we can read from the file if (file.get() == nullptr) { - throw DeadlyImportError("Failed to open IRR file " + pFile); + throw DeadlyImportError("Failed to open IRR file ", pFile); } // Construct the irrXML parser XmlParser st; if (!st.parse( file.get() )) { - return; + throw DeadlyImportError("XML parse error while loading IRR file ", pFile); } pugi::xml_node rootElement = st.getRootNode(); diff --git a/code/AssetLib/Irr/IRRMeshLoader.cpp b/code/AssetLib/Irr/IRRMeshLoader.cpp index edcff6c83..9350e07b8 100644 --- a/code/AssetLib/Irr/IRRMeshLoader.cpp +++ b/code/AssetLib/Irr/IRRMeshLoader.cpp @@ -135,12 +135,12 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile, // Check whether we can read from the file if (file.get() == NULL) - throw DeadlyImportError("Failed to open IRRMESH file " + pFile); + throw DeadlyImportError("Failed to open IRRMESH file ", pFile); // Construct the irrXML parser XmlParser parser; if (!parser.parse( file.get() )) { - return; + throw DeadlyImportError("XML parse error while loading IRRMESH file ", pFile); } XmlNode root = parser.getRootNode(); From de5c8ece6f53f5d22ac1c872780cd7518bbb2bb8 Mon Sep 17 00:00:00 2001 From: Jason C Date: Wed, 5 May 2021 17:49:10 -0400 Subject: [PATCH 43/93] [xgl] Fail if file could not be parsed. Fail instead of returning empty scene. Partially addresses #3888. TODO: Propagate XML error detail through exception (depends on #3881). --- code/AssetLib/XGL/XGLLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/XGL/XGLLoader.cpp b/code/AssetLib/XGL/XGLLoader.cpp index 00e8bafb2..3b84d7ba9 100644 --- a/code/AssetLib/XGL/XGLLoader.cpp +++ b/code/AssetLib/XGL/XGLLoader.cpp @@ -200,7 +200,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // parse the XML file mXmlParser = new XmlParser; if (!mXmlParser->parse(stream.get())) { - return; + throw DeadlyImportError("XML parse error while loading XGL file ", pFile); } TempScope scope; From 7da9c42c81d9a15664c47e2281a84931bc36eb72 Mon Sep 17 00:00:00 2001 From: Jason C Date: Wed, 5 May 2021 19:30:29 -0400 Subject: [PATCH 44/93] [blender] Disable creation of "dna.txt" Developers who want to enable it can either: - *Temporarily* set ASSIMP_BUILD_BLENDER_DEBUG_DNA=1 in BlenderDNA.h, or - *Temporarily* define ASSIMP_BUILD_BLENDER_DEBUG_DNA=1 on the build command line. Addresses #3886. --- code/AssetLib/Blender/BlenderDNA.cpp | 6 +++--- code/AssetLib/Blender/BlenderDNA.h | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/code/AssetLib/Blender/BlenderDNA.cpp b/code/AssetLib/Blender/BlenderDNA.cpp index 4dcb3d654..c58041771 100644 --- a/code/AssetLib/Blender/BlenderDNA.cpp +++ b/code/AssetLib/Blender/BlenderDNA.cpp @@ -200,7 +200,7 @@ void DNAParser::Parse() { ASSIMP_LOG_DEBUG_F("BlenderDNA: Got ", dna.structures.size(), " structures with totally ", fields, " fields"); -#ifdef ASSIMP_BUILD_BLENDER_DEBUG +#if ASSIMP_BUILD_BLENDER_DEBUG_DNA dna.DumpToFile(); #endif @@ -208,7 +208,7 @@ void DNAParser::Parse() { dna.RegisterConverters(); } -#ifdef ASSIMP_BUILD_BLENDER_DEBUG +#if ASSIMP_BUILD_BLENDER_DEBUG_DNA #include // ------------------------------------------------------------------------------------------------ @@ -237,7 +237,7 @@ void DNA ::DumpToFile() { ASSIMP_LOG_INFO("BlenderDNA: Dumped dna to dna.txt"); } -#endif +#endif // ASSIMP_BUILD_BLENDER_DEBUG_DNA // ------------------------------------------------------------------------------------------------ /*static*/ void DNA ::ExtractArraySize( diff --git a/code/AssetLib/Blender/BlenderDNA.h b/code/AssetLib/Blender/BlenderDNA.h index 090d1be04..f566554b8 100644 --- a/code/AssetLib/Blender/BlenderDNA.h +++ b/code/AssetLib/Blender/BlenderDNA.h @@ -59,6 +59,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define ASSIMP_BUILD_BLENDER_DEBUG #endif +// set this to non-zero to dump BlenderDNA stuff to dna.txt. +// you could set it on the assimp build command line too without touching it here. +// !!! please make sure this is set to 0 in the repo !!! +#ifndef ASSIMP_BUILD_BLENDER_DEBUG_DNA +#define ASSIMP_BUILD_BLENDER_DEBUG_DNA 0 +#endif + // #define ASSIMP_BUILD_BLENDER_NO_STATS namespace Assimp { @@ -495,7 +502,7 @@ public: const Structure &structure, const FileDatabase &db) const; -#ifdef ASSIMP_BUILD_BLENDER_DEBUG +#if ASSIMP_BUILD_BLENDER_DEBUG_DNA // -------------------------------------------------------- /** Dump the DNA to a text file. This is for debugging purposes. * The output file is `dna.txt` in the current working folder*/ From 2b9d88c9434b13a3c0824bb5b402eb2e83857b0b Mon Sep 17 00:00:00 2001 From: ywang Date: Thu, 6 May 2021 15:10:06 -0700 Subject: [PATCH 45/93] support basis universal --- code/AssetLib/glTF2/glTF2Asset.h | 2 ++ code/AssetLib/glTF2/glTF2Asset.inl | 2 ++ code/AssetLib/glTF2/glTF2AssetWriter.inl | 13 +++++++++ code/AssetLib/glTF2/glTF2Exporter.cpp | 36 ++++++++++++++++++++---- code/AssetLib/glTF2/glTF2Importer.cpp | 6 ++++ 5 files changed, 53 insertions(+), 6 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index fad5cba83..f2c0369d6 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -1118,11 +1118,13 @@ public: bool KHR_materials_transmission; bool KHR_draco_mesh_compression; bool FB_ngon_encoding; + bool KHR_texture_basisu; } extensionsUsed; //! Keeps info about the required extensions struct RequiredExtensions { bool KHR_draco_mesh_compression; + bool KHR_texture_basisu; } extensionsRequired; AssetMetadata asset; diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl index 77537028f..42d3f060e 100644 --- a/code/AssetLib/glTF2/glTF2Asset.inl +++ b/code/AssetLib/glTF2/glTF2Asset.inl @@ -1121,6 +1121,7 @@ inline Image::Image() : } inline void Image::Read(Value &obj, Asset &r) { + //basisu: no need to handle .ktx2, .basis, load as is if (!mDataLength) { Value *curUri = FindString(obj, "uri"); if (nullptr != curUri) { @@ -2101,6 +2102,7 @@ inline void Asset::ReadExtensionsUsed(Document &doc) { CHECK_EXT(KHR_materials_clearcoat); CHECK_EXT(KHR_materials_transmission); CHECK_EXT(KHR_draco_mesh_compression); + CHECK_EXT(KHR_texture_basisu); #undef CHECK_EXT } diff --git a/code/AssetLib/glTF2/glTF2AssetWriter.inl b/code/AssetLib/glTF2/glTF2AssetWriter.inl index 01a28d4b7..bf7dbbb2e 100644 --- a/code/AssetLib/glTF2/glTF2AssetWriter.inl +++ b/code/AssetLib/glTF2/glTF2AssetWriter.inl @@ -250,6 +250,7 @@ namespace glTF2 { inline void Write(Value& obj, Image& img, AssetWriter& w) { + //basisu: no need to handle .ktx2, .basis, write as is if (img.bufferView) { obj.AddMember("bufferView", img.bufferView->index, w.mAl); obj.AddMember("mimeType", Value(img.mimeType, w.mAl).Move(), w.mAl); @@ -892,10 +893,22 @@ namespace glTF2 { if (this->mAsset.extensionsUsed.FB_ngon_encoding) { exts.PushBack(StringRef("FB_ngon_encoding"), mAl); } + + if (this->mAsset.extensionsUsed.KHR_texture_basisu) { + exts.PushBack(StringRef("KHR_texture_basisu"), mAl); + } } if (!exts.Empty()) mDoc.AddMember("extensionsUsed", exts, mAl); + + //basisu extensionRequired + Value extsReq; + extsReq.SetArray(); + if (this->mAsset.extensionsUsed.KHR_texture_basisu) { + extsReq.PushBack(StringRef("KHR_texture_basisu"), mAl); + mDoc.AddMember("extensionsRequired", extsReq, mAl); + } } template diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index 51aef013d..e039bf88a 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -494,7 +494,6 @@ void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, float& prop, const char void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTextureType tt, unsigned int slot = 0) { - if (mat->GetTextureCount(tt) > 0) { aiString tex; @@ -507,6 +506,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTe texture = mAsset->textures.Get(it->second); } + bool useBasisUniversal = false; if (!texture) { std::string texId = mAsset->FindUniqueID("", "texture"); texture = mAsset->textures.Create(texId); @@ -519,18 +519,42 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTe aiTexture* curTex = mScene->mTextures[atoi(&path[1])]; texture->source->name = curTex->mFilename.C_Str(); - - // The asset has its own buffer, see Image::SetData - texture->source->SetData(reinterpret_cast(curTex->pcData), curTex->mWidth, *mAsset); - + + //basisu: embedded ktx2, bu if (curTex->achFormatHint[0]) { std::string mimeType = "image/"; - mimeType += (memcmp(curTex->achFormatHint, "jpg", 3) == 0) ? "jpeg" : curTex->achFormatHint; + if(memcmp(curTex->achFormatHint, "jpg", 3) == 0) + mimeType += "jpeg"; + else if(memcmp(curTex->achFormatHint, "ktx", 3) == 0) { + useBasisUniversal = true; + mimeType += "ktx2"; + } + else if(memcmp(curTex->achFormatHint, "bu", 3) == 0) { + useBasisUniversal = true; + mimeType += "basis"; + } + else + mimeType += curTex->achFormatHint; texture->source->mimeType = mimeType; } + + // The asset has its own buffer, see Image::SetData + //basisu: "image/ktx2", "image/basis" as is + texture->source->SetData(reinterpret_cast(curTex->pcData), curTex->mWidth, *mAsset); } else { texture->source->uri = path; + if(texture->source->uri.find(".ktx2")!=std::string::npos || + texture->source->uri.find(".basis")!=std::string::npos) + { + useBasisUniversal = true; + } + } + + //basisu + if(useBasisUniversal) { + mAsset->extensionsUsed.KHR_texture_basisu = true; + mAsset->extensionsRequired.KHR_texture_basisu = true; } GetTexSampler(mat, texture, tt, slot); diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index ab1f01bf8..b109891cb 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -1476,6 +1476,12 @@ void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset &r) { if (strcmp(ext, "jpeg") == 0) { ext = "jpg"; } + else if(strcmp(ext, "ktx2") == 0) { //basisu + ext = "ktx"; + } + else if(strcmp(ext, "basis") == 0) { //basisu + ext = "bu"; + } size_t len = strlen(ext); if (len <= 3) { From 964778cac1a98fd333d00ab18f43577ff69ce39b Mon Sep 17 00:00:00 2001 From: Carsten Rudolph <18394207+crud89@users.noreply.github.com> Date: Fri, 7 May 2021 17:30:26 +0200 Subject: [PATCH 46/93] Add AI_CONFIG_EXPORT_BLOB_NAME export property. --- include/assimp/config.h.in | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/assimp/config.h.in b/include/assimp/config.h.in index d78568da7..8ea82482f 100644 --- a/include/assimp/config.h.in +++ b/include/assimp/config.h.in @@ -1066,6 +1066,23 @@ enum aiComponent */ #define AI_CONFIG_EXPORT_POINT_CLOUDS "EXPORT_POINT_CLOUDS" +/** + * @brief Specifies the blob name, assimp uses for exporting. + * + * Some formats require auxiliary files to be written, that need to be linked back into + * the original file. For example, OBJ files export materials to a separate MTL file and + * use the `mtllib` keyword to reference this file. + * + * When exporting blobs using #ExportToBlob, assimp does not know the name of the blob + * file and thus outputs `mtllib $blobfile.mtl`, which might not be desired, since the + * MTL file might be called differently. + * + * This property can be used to give the exporter a hint on how to use the magic + * `$blobfile` keyword. If the exporter detects the keyword and is provided with a name + * for the blob, it instead uses this name. + */ +#define AI_CONFIG_EXPORT_BLOB_NAME "EXPORT_BLOB_NAME" + /** * @brief Specifies a gobal key factor for scale, float value */ From be85f238f4dd96f1182678d23e997b2e675484a7 Mon Sep 17 00:00:00 2001 From: Carsten Rudolph <18394207+crud89@users.noreply.github.com> Date: Fri, 7 May 2021 17:30:58 +0200 Subject: [PATCH 47/93] Add optional blob base name to blob IO system. --- include/assimp/BlobIOSystem.h | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/include/assimp/BlobIOSystem.h b/include/assimp/BlobIOSystem.h index 4e3d5c2a3..081ccf32a 100644 --- a/include/assimp/BlobIOSystem.h +++ b/include/assimp/BlobIOSystem.h @@ -194,8 +194,14 @@ class BlobIOSystem : public IOSystem { friend class BlobIOStream; typedef std::pair BlobEntry; + public: - BlobIOSystem() { + BlobIOSystem() : + baseName{} { + } + + BlobIOSystem(const std::string &baseName) : + baseName(baseName) { } virtual ~BlobIOSystem() { @@ -207,27 +213,32 @@ public: public: // ------------------------------------------------------------------- const char *GetMagicFileName() const { - return AI_BLOBIO_MAGIC; + return baseName.empty() ? AI_BLOBIO_MAGIC : baseName.c_str(); } // ------------------------------------------------------------------- aiExportDataBlob *GetBlobChain() { + const auto magicName = std::string(this->GetMagicFileName()); + const bool hasBaseName = baseName.empty(); + // one must be the master aiExportDataBlob *master = nullptr, *cur; + for (const BlobEntry &blobby : blobs) { - if (blobby.first == AI_BLOBIO_MAGIC) { + if (blobby.first == magicName) { master = blobby.second; + master->name.Set(hasBaseName ? blobby.first : ""); break; } } + if (!master) { ASSIMP_LOG_ERROR("BlobIOSystem: no data written or master file was not closed properly."); return nullptr; } - master->name.Set(""); - cur = master; + for (const BlobEntry &blobby : blobs) { if (blobby.second == master) { continue; @@ -236,9 +247,14 @@ public: cur->next = blobby.second; cur = cur->next; - // extract the file extension from the file written - const std::string::size_type s = blobby.first.find_first_of('.'); - cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s + 1)); + if (hasBaseName) { + cur->name.Set(blobby.first); + } + else { + // extract the file extension from the file written + const std::string::size_type s = blobby.first.find_first_of('.'); + cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s + 1)); + } } // give up blob ownership @@ -283,6 +299,7 @@ private: } private: + std::string baseName; std::set created; std::vector blobs; }; From 8ff52c0f89fe52d52b6fc0ac6f111c9355616139 Mon Sep 17 00:00:00 2001 From: Carsten Rudolph <18394207+crud89@users.noreply.github.com> Date: Fri, 7 May 2021 17:31:30 +0200 Subject: [PATCH 48/93] Pass base name from export properties to the IO system. --- code/Common/Exporter.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/Common/Exporter.cpp b/code/Common/Exporter.cpp index 20cbb05d6..ebcc955df 100644 --- a/code/Common/Exporter.cpp +++ b/code/Common/Exporter.cpp @@ -343,9 +343,11 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha delete pimpl->blob; pimpl->blob = nullptr; } + + auto baseName = pProperties ? pProperties->GetPropertyString(AI_CONFIG_EXPORT_BLOB_NAME, AI_BLOBIO_MAGIC) : AI_BLOBIO_MAGIC; std::shared_ptr old = pimpl->mIOSystem; - BlobIOSystem* blobio = new BlobIOSystem(); + BlobIOSystem *blobio = new BlobIOSystem(baseName); pimpl->mIOSystem = std::shared_ptr( blobio ); if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName(), pPreprocessing, pProperties)) { From 1b33dd1965dd0a58b20fa4e270d1809abb920c58 Mon Sep 17 00:00:00 2001 From: Carsten Rudolph <18394207+crud89@users.noreply.github.com> Date: Fri, 7 May 2021 17:31:38 +0200 Subject: [PATCH 49/93] Document AI_CONFIG_EXPORT_BLOB_NAME. --- include/assimp/cexport.h | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/include/assimp/cexport.h b/include/assimp/cexport.h index 2e84b1f30..44843af0e 100644 --- a/include/assimp/cexport.h +++ b/include/assimp/cexport.h @@ -205,16 +205,22 @@ struct aiExportDataBlob { void *data; /** Name of the blob. An empty string always - indicates the first (and primary) blob, - which contains the actual file data. - Any other blobs are auxiliary files produced - by exporters (i.e. material files). Existence - of such files depends on the file format. Most - formats don't split assets across multiple files. - - If used, blob names usually contain the file - extension that should be used when writing - the data to disc. + * indicates the first (and primary) blob, + * which contains the actual file data. + * Any other blobs are auxiliary files produced + * by exporters (i.e. material files). Existence + * of such files depends on the file format. Most + * formats don't split assets across multiple files. + * + * If used, blob names usually contain the file + * extension that should be used when writing + * the data to disc. + * + * The blob names generated can be influenced by + * setting the #AI_CONFIG_EXPORT_BLOB_NAME export + * property to the name that is used for the master + * blob. All other names are typically derived from + * the base name, by the file format exporter. */ C_STRUCT aiString name; From a19b708144b91d6936339b40f93ab7540ee25689 Mon Sep 17 00:00:00 2001 From: ywang Date: Fri, 7 May 2021 16:27:23 -0700 Subject: [PATCH 50/93] support both ktx and ktx2 --- code/AssetLib/glTF2/glTF2Exporter.cpp | 8 ++++++-- code/AssetLib/glTF2/glTF2Importer.cpp | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index e039bf88a..751508225 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -526,10 +526,14 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTe if(memcmp(curTex->achFormatHint, "jpg", 3) == 0) mimeType += "jpeg"; else if(memcmp(curTex->achFormatHint, "ktx", 3) == 0) { + useBasisUniversal = true; + mimeType += "ktx"; + } + else if(memcmp(curTex->achFormatHint, "kx2", 3) == 0) { useBasisUniversal = true; mimeType += "ktx2"; } - else if(memcmp(curTex->achFormatHint, "bu", 3) == 0) { + else if(memcmp(curTex->achFormatHint, "bu", 2) == 0) { useBasisUniversal = true; mimeType += "basis"; } @@ -544,7 +548,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTe } else { texture->source->uri = path; - if(texture->source->uri.find(".ktx2")!=std::string::npos || + if(texture->source->uri.find(".ktx")!=std::string::npos || texture->source->uri.find(".basis")!=std::string::npos) { useBasisUniversal = true; diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index b109891cb..db5da8813 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -1476,8 +1476,8 @@ void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset &r) { if (strcmp(ext, "jpeg") == 0) { ext = "jpg"; } - else if(strcmp(ext, "ktx2") == 0) { //basisu - ext = "ktx"; + else if(strcmp(ext, "ktx2") == 0) { //basisu: ktx remains + ext = "kx2"; } else if(strcmp(ext, "basis") == 0) { //basisu ext = "bu"; From e37e00c51fa48d459165ef57caf033e9fe73c3e6 Mon Sep 17 00:00:00 2001 From: Jason C Date: Fri, 7 May 2021 20:21:56 -0400 Subject: [PATCH 51/93] [assimp/fast_atof] Fixed garbage in exception messages. Also reduced 100 byte context output to 30 (which is still probably excessive, but not *as* excessive). --- include/assimp/fast_atof.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/assimp/fast_atof.h b/include/assimp/fast_atof.h index 9ea49c85c..441fe5652 100644 --- a/include/assimp/fast_atof.h +++ b/include/assimp/fast_atof.h @@ -29,6 +29,7 @@ #include "StringComparison.h" #include #include +#include #ifdef _MSC_VER # include @@ -193,7 +194,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::string(in).substr(0, 100), "\" cannot be converted into a value." ); + throw ExceptionType("The string \"", ai_str_toprintable(in, 30), "\" cannot be converted into a value." ); } for ( ;; ) { @@ -293,7 +294,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::string(c).substr(0, 100), + throw ExceptionType("Cannot parse string \"", ai_str_toprintable(c, 30), "\" as a real number: does not start with digit " "or decimal point followed by digit."); } From 859b32c04581644a9f54c6f18860dd7927a1d127 Mon Sep 17 00:00:00 2001 From: Jason C Date: Fri, 7 May 2021 22:32:32 -0400 Subject: [PATCH 52/93] [Logger] Log a notification instead of silently dropping long log messages. Logs a notification instead of silently dropping long log messages, which can complicate debugging. This way, if you don't see a message you expect to see, you'll immediately know why. The *correct* approach would be to eliminate length filtering here entirely and use `snprintf` appropriately (also there's a tiny -- probably negligible -- performance hit here in calling `strlen` regardless of whether or not the verbosity level matches). Failing that, the second best option is to copy and truncate messages here. However, for now, this should be OK. --- code/Common/DefaultLogger.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/Common/DefaultLogger.cpp b/code/Common/DefaultLogger.cpp index aa13ca5ce..3f6d2d7ed 100644 --- a/code/Common/DefaultLogger.cpp +++ b/code/Common/DefaultLogger.cpp @@ -169,7 +169,7 @@ void Logger::debug(const char *message) { // sometimes importers will include data from the input file // (i.e. node names) in their messages. if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { - return; + return OnDebug(""); } return OnDebug(message); } @@ -181,7 +181,7 @@ void Logger::verboseDebug(const char *message) { // sometimes importers will include data from the input file // (i.e. node names) in their messages. if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { - return; + return OnVerboseDebug(""); } return OnVerboseDebug(message); } @@ -191,7 +191,7 @@ void Logger::info(const char *message) { // SECURITY FIX: see above if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { - return; + return OnInfo(""); } return OnInfo(message); } @@ -201,7 +201,7 @@ void Logger::warn(const char *message) { // SECURITY FIX: see above if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { - return; + return OnWarn(""); } return OnWarn(message); } @@ -210,7 +210,7 @@ void Logger::warn(const char *message) { void Logger::error(const char *message) { // SECURITY FIX: see above if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { - return; + return OnError(""); } return OnError(message); } From 00b625a2ae75f344bafc85baf03a1b2ea73f8462 Mon Sep 17 00:00:00 2001 From: Jason C Date: Mon, 10 May 2021 19:01:15 -0400 Subject: [PATCH 53/93] [amf] Fix crash when file could not be parsed. Fix double free of mXmlParser (deleted but not reset in ParseFile, then deleted again in ~AMFImporter). Should probably use a smart pointer instead, though. --- This change was previously made in 785cca1bb43f9e6047cb566a910fcd0e3d49951f, as part of PR #3890, but was lost in a merge. --- code/AssetLib/AMF/AMFImporter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/AMF/AMFImporter.cpp b/code/AssetLib/AMF/AMFImporter.cpp index e77b65f77..615882b6a 100644 --- a/code/AssetLib/AMF/AMFImporter.cpp +++ b/code/AssetLib/AMF/AMFImporter.cpp @@ -268,7 +268,8 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) { mXmlParser = new XmlParser(); if (!mXmlParser->parse(file.get())) { delete mXmlParser; - throw DeadlyImportError("Failed to create XML reader for file" + pFile + "."); + mXmlParser = nullptr; + throw DeadlyImportError("Failed to create XML reader for file ", pFile, "."); } // Start reading, search for root tag From 632e4a20a989d2e2849b81d828ab22fba3b8d6da Mon Sep 17 00:00:00 2001 From: Salvage <29021710+Saalvage@users.noreply.github.com> Date: Tue, 11 May 2021 05:29:51 +0200 Subject: [PATCH 54/93] Utilize decltype for slightly improved syntax --- include/assimp/Bitmap.h | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/include/assimp/Bitmap.h b/include/assimp/Bitmap.h index d56bb4c73..a455e2ecf 100644 --- a/include/assimp/Bitmap.h +++ b/include/assimp/Bitmap.h @@ -75,13 +75,12 @@ protected: uint32_t offset; // We define the struct size because sizeof(Header) might return a wrong result because of structure padding. - // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). - static const std::size_t header_size = - sizeof(uint16_t) + // type - sizeof(uint32_t) + // size - sizeof(uint16_t) + // reserved1 - sizeof(uint16_t) + // reserved2 - sizeof(uint32_t); // offset + static constexpr std::size_t header_size = + sizeof(decltype(type)) + + sizeof(decltype(size)) + + sizeof(decltype(reserved1)) + + sizeof(decltype(reserved2)) + + sizeof(decltype(offset)); }; struct DIB { @@ -98,22 +97,21 @@ protected: uint32_t nb_important_colors; // We define the struct size because sizeof(DIB) might return a wrong result because of structure padding. - // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). - static const std::size_t dib_size = - sizeof(uint32_t) + // size - sizeof(int32_t) + // width - sizeof(int32_t) + // height - sizeof(uint16_t) + // planes - sizeof(uint16_t) + // bits_per_pixel - sizeof(uint32_t) + // compression - sizeof(uint32_t) + // image_size - sizeof(int32_t) + // x_resolution - sizeof(int32_t) + // y_resolution - sizeof(uint32_t) + // nb_colors - sizeof(uint32_t); // nb_important_colors + static constexpr std::size_t dib_size = + sizeof(decltype(size)) + + sizeof(decltype(width)) + + sizeof(decltype(height)) + + sizeof(decltype(planes)) + + sizeof(decltype(bits_per_pixel)) + + sizeof(decltype(compression)) + + sizeof(decltype(image_size)) + + sizeof(decltype(x_resolution)) + + sizeof(decltype(y_resolution)) + + sizeof(decltype(nb_colors)) + + sizeof(decltype(nb_important_colors)); }; - static const std::size_t mBytesPerPixel = 4; + static constexpr std::size_t mBytesPerPixel = 4; public: static void Save(aiTexture* texture, IOStream* file); From 8d20460ae43728b31d390a49a81b655cfe856ad9 Mon Sep 17 00:00:00 2001 From: Salvage <29021710+Saalvage@users.noreply.github.com> Date: Tue, 11 May 2021 19:06:21 +0200 Subject: [PATCH 55/93] Ditch decltype --- include/assimp/Bitmap.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/include/assimp/Bitmap.h b/include/assimp/Bitmap.h index a455e2ecf..e4ce194d9 100644 --- a/include/assimp/Bitmap.h +++ b/include/assimp/Bitmap.h @@ -76,11 +76,11 @@ protected: // We define the struct size because sizeof(Header) might return a wrong result because of structure padding. static constexpr std::size_t header_size = - sizeof(decltype(type)) + - sizeof(decltype(size)) + - sizeof(decltype(reserved1)) + - sizeof(decltype(reserved2)) + - sizeof(decltype(offset)); + sizeof(type) + + sizeof(size) + + sizeof(reserved1) + + sizeof(reserved2) + + sizeof(offset); }; struct DIB { @@ -98,17 +98,17 @@ protected: // We define the struct size because sizeof(DIB) might return a wrong result because of structure padding. static constexpr std::size_t dib_size = - sizeof(decltype(size)) + - sizeof(decltype(width)) + - sizeof(decltype(height)) + - sizeof(decltype(planes)) + - sizeof(decltype(bits_per_pixel)) + - sizeof(decltype(compression)) + - sizeof(decltype(image_size)) + - sizeof(decltype(x_resolution)) + - sizeof(decltype(y_resolution)) + - sizeof(decltype(nb_colors)) + - sizeof(decltype(nb_important_colors)); + sizeof(size) + + sizeof(width) + + sizeof(height) + + sizeof(planes) + + sizeof(bits_per_pixel) + + sizeof(compression) + + sizeof(image_size) + + sizeof(x_resolution) + + sizeof(y_resolution) + + sizeof(nb_colors) + + sizeof(nb_important_colors); }; static constexpr std::size_t mBytesPerPixel = 4; From 813d0aecdda2627d3bdd612332ce5efc2f5f0afa Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Wed, 12 May 2021 12:43:24 +0100 Subject: [PATCH 56/93] Adjust warn --- code/AssetLib/Ogre/OgreStructs.cpp | 4 ++-- code/AssetLib/SIB/SIBImporter.cpp | 2 +- code/Common/DefaultLogger.cpp | 9 +++++---- include/assimp/Logger.hpp | 22 +++++++++++++--------- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/code/AssetLib/Ogre/OgreStructs.cpp b/code/AssetLib/Ogre/OgreStructs.cpp index 90e2d4465..ce289c79c 100644 --- a/code/AssetLib/Ogre/OgreStructs.cpp +++ b/code/AssetLib/Ogre/OgreStructs.cpp @@ -545,7 +545,7 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent) { dest->mNumUVComponents[0] = static_cast(uv1Element->ComponentCount()); dest->mTextureCoords[0] = new aiVector3D[dest->mNumVertices]; } else { - ASSIMP_LOG_WARN(Formatter::format() << "Ogre imported UV0 type " << uv1Element->TypeToString() << " is not compatible with Assimp. Ignoring UV."); + ASSIMP_LOG_WARN_F("Ogre imported UV0 type ", uv1Element->TypeToString(), " is not compatible with Assimp. Ignoring UV."); uv1 = 0; } } @@ -554,7 +554,7 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent) { dest->mNumUVComponents[1] = static_cast(uv2Element->ComponentCount()); dest->mTextureCoords[1] = new aiVector3D[dest->mNumVertices]; } else { - ASSIMP_LOG_WARN(Formatter::format() << "Ogre imported UV0 type " << uv2Element->TypeToString() << " is not compatible with Assimp. Ignoring UV."); + ASSIMP_LOG_WARN_F("Ogre imported UV0 type ", uv2Element->TypeToString(), " is not compatible with Assimp. Ignoring UV."); uv2 = 0; } } diff --git a/code/AssetLib/SIB/SIBImporter.cpp b/code/AssetLib/SIB/SIBImporter.cpp index 6c1e5950b..1426fb73c 100644 --- a/code/AssetLib/SIB/SIBImporter.cpp +++ b/code/AssetLib/SIB/SIBImporter.cpp @@ -174,7 +174,7 @@ static void UnknownChunk(StreamReaderLE * /*stream*/, const SIBChunk &chunk) { static_cast(chunk.Tag & 0xff) }; - ASSIMP_LOG_WARN((Formatter::format(), "SIB: Skipping unknown '", ai_str_toprintable(temp, 4), "' chunk.")); + ASSIMP_LOG_WARN_F("SIB: Skipping unknown '", ai_str_toprintable(temp, 4), "' chunk."); } // Reads a UTF-16LE string and returns it at UTF-8. diff --git a/code/Common/DefaultLogger.cpp b/code/Common/DefaultLogger.cpp index aa13ca5ce..d2e9a2caf 100644 --- a/code/Common/DefaultLogger.cpp +++ b/code/Common/DefaultLogger.cpp @@ -197,13 +197,14 @@ void Logger::info(const char *message) { } // ---------------------------------------------------------------------------------- -void Logger::warn(const char *message) { - +void Logger::warnInternal(Assimp::Formatter::format f) { + std::string message = f; + // TODO: Should limit sizes in the formatter. // SECURITY FIX: see above - if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { + if (message.length() > MAX_LOG_MESSAGE_LENGTH) { return; } - return OnWarn(message); + return OnWarn(message.c_str()); } // ---------------------------------------------------------------------------------- diff --git a/include/assimp/Logger.hpp b/include/assimp/Logger.hpp index ee6eab507..f68c951fd 100644 --- a/include/assimp/Logger.hpp +++ b/include/assimp/Logger.hpp @@ -119,8 +119,10 @@ public: // ---------------------------------------------------------------------- /** @brief Writes a warning message * @param message Warn message*/ - void warn(const char* message); - void warn(const std::string &message); + template + void warn(T&&... args) { + warnInternal(Assimp::Formatter::format(), std::forward(args)...); + } // ---------------------------------------------------------------------- /** @brief Writes an error message @@ -225,6 +227,14 @@ protected: */ virtual void OnError(const char* message) = 0; +protected: + void warnInternal(Assimp::Formatter::format f); + + template + void warnInternal(Assimp::Formatter::format f, U&& u, T&&... args) { + warnInternal(std::move(f << std::forward(u)), std::forward(args)...); + } + protected: LogSeverity m_Severity; }; @@ -283,12 +293,6 @@ void Logger::error(const std::string &message) { return error(message.c_str()); } -// ---------------------------------------------------------------------------------- -inline -void Logger::warn(const std::string &message) { - return warn(message.c_str()); -} - // ---------------------------------------------------------------------------------- inline void Logger::info(const std::string &message) { @@ -299,7 +303,7 @@ void Logger::info(const std::string &message) { // ------------------------------------------------------------------------------------------------ #define ASSIMP_LOG_WARN_F(string, ...) \ - Assimp::DefaultLogger::get()->warn((Assimp::Formatter::format(string), __VA_ARGS__)) + Assimp::DefaultLogger::get()->warn((string, __VA_ARGS__)) #define ASSIMP_LOG_ERROR_F(string, ...) \ Assimp::DefaultLogger::get()->error((Assimp::Formatter::format(string), __VA_ARGS__)) From 58bc4bcb63924ae10bd9c5a8a8f6639c681f5eea Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Wed, 12 May 2021 12:55:21 +0100 Subject: [PATCH 57/93] log info --- code/AssetLib/3DS/3DSLoader.cpp | 2 +- code/AssetLib/AC/ACLoader.cpp | 4 ++-- code/Common/DefaultLogger.cpp | 9 +++++---- include/assimp/Logger.hpp | 21 ++++++++++++--------- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/code/AssetLib/3DS/3DSLoader.cpp b/code/AssetLib/3DS/3DSLoader.cpp index 92fe72bbf..2d77e0f66 100644 --- a/code/AssetLib/3DS/3DSLoader.cpp +++ b/code/AssetLib/3DS/3DSLoader.cpp @@ -305,7 +305,7 @@ void Discreet3DSImporter::ParseEditorChunk() { // print the version number char buff[10]; ASSIMP_itoa10(buff, stream->GetI2()); - ASSIMP_LOG_INFO_F(std::string("3DS file format version: "), buff); + ASSIMP_LOG_INFO_F("3DS file format version: ", buff); } break; }; ASSIMP_3DS_END_CHUNK(); diff --git a/code/AssetLib/AC/ACLoader.cpp b/code/AssetLib/AC/ACLoader.cpp index cba84e8b0..59cfc30dd 100644 --- a/code/AssetLib/AC/ACLoader.cpp +++ b/code/AssetLib/AC/ACLoader.cpp @@ -690,7 +690,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object, if (object.subDiv) { if (configEvalSubdivision) { std::unique_ptr div(Subdivider::Create(Subdivider::CATMULL_CLARKE)); - ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: " + object.name); + ASSIMP_LOG_INFO_F("AC3D: Evaluating subdivision surface: ", object.name); std::vector cpy(meshes.size() - oldm, nullptr); div->Subdivide(&meshes[oldm], cpy.size(), &cpy.front(), object.subDiv, true); @@ -698,7 +698,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object, // previous meshes are deleted vy Subdivide(). } else { - ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: " + object.name); + ASSIMP_LOG_INFO_F("AC3D: Letting the subdivision surface untouched due to my configuration: ", object.name); } } } diff --git a/code/Common/DefaultLogger.cpp b/code/Common/DefaultLogger.cpp index d2e9a2caf..a5c378e03 100644 --- a/code/Common/DefaultLogger.cpp +++ b/code/Common/DefaultLogger.cpp @@ -187,13 +187,14 @@ void Logger::verboseDebug(const char *message) { } // ---------------------------------------------------------------------------------- -void Logger::info(const char *message) { - +void Logger::infoInternal(Assimp::Formatter::format f) { + std::string message = f; + // TODO: Should limit sizes in the formatter. // SECURITY FIX: see above - if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { + if (message.length() > MAX_LOG_MESSAGE_LENGTH) { return; } - return OnInfo(message); + return OnInfo(message.c_str()); } // ---------------------------------------------------------------------------------- diff --git a/include/assimp/Logger.hpp b/include/assimp/Logger.hpp index f68c951fd..2c3ee1085 100644 --- a/include/assimp/Logger.hpp +++ b/include/assimp/Logger.hpp @@ -113,8 +113,10 @@ public: // ---------------------------------------------------------------------- /** @brief Writes a info message * @param message Info message*/ - void info(const char* message); - void info(const std::string &message); + template + void info(T&&... args) { + infoInternal(Assimp::Formatter::format(), std::forward(args)...); + } // ---------------------------------------------------------------------- /** @brief Writes a warning message @@ -235,6 +237,13 @@ protected: warnInternal(std::move(f << std::forward(u)), std::forward(args)...); } + void infoInternal(Assimp::Formatter::format f); + + template + void infoInternal(Assimp::Formatter::format f, U&& u, T&&... args) { + infoInternal(std::move(f << std::forward(u)), std::forward(args)...); + } + protected: LogSeverity m_Severity; }; @@ -293,12 +302,6 @@ void Logger::error(const std::string &message) { return error(message.c_str()); } -// ---------------------------------------------------------------------------------- -inline -void Logger::info(const std::string &message) { - return info(message.c_str()); -} - } // Namespace Assimp // ------------------------------------------------------------------------------------------------ @@ -315,7 +318,7 @@ void Logger::info(const std::string &message) { Assimp::DefaultLogger::get()->verboseDebug((Assimp::Formatter::format(string), __VA_ARGS__)) #define ASSIMP_LOG_INFO_F(string, ...) \ - Assimp::DefaultLogger::get()->info((Assimp::Formatter::format(string), __VA_ARGS__)) + Assimp::DefaultLogger::get()->info((string, __VA_ARGS__)) #define ASSIMP_LOG_WARN(string) \ Assimp::DefaultLogger::get()->warn(string) From 18beae988cb12cbc9db15d3fdce35b18187047af Mon Sep 17 00:00:00 2001 From: Chuck Claunch Date: Wed, 12 May 2021 21:57:24 +0000 Subject: [PATCH 58/93] Add support for arm 64 bit --- port/PyAssimp/pyassimp/helper.py | 1 + 1 file changed, 1 insertion(+) diff --git a/port/PyAssimp/pyassimp/helper.py b/port/PyAssimp/pyassimp/helper.py index 5c1aca827..7a4b2bdcb 100644 --- a/port/PyAssimp/pyassimp/helper.py +++ b/port/PyAssimp/pyassimp/helper.py @@ -27,6 +27,7 @@ if os.name=='posix': additional_dirs.append('./') additional_dirs.append('/usr/lib/') additional_dirs.append('/usr/lib/x86_64-linux-gnu/') + additional_dirs.append('/usr/lib/aarch64-linux-gnu/') additional_dirs.append('/usr/local/lib/') if 'LD_LIBRARY_PATH' in os.environ: From ca698c3e491a5681c1959a61e944a1a267158373 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Thu, 13 May 2021 09:36:42 +0100 Subject: [PATCH 59/93] Log error --- code/Common/DefaultLogger.cpp | 9 ++++---- code/PostProcessing/CalcTangentsProcess.cpp | 2 +- include/assimp/Logger.hpp | 23 ++++++++++++--------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/code/Common/DefaultLogger.cpp b/code/Common/DefaultLogger.cpp index a5c378e03..e468d72ca 100644 --- a/code/Common/DefaultLogger.cpp +++ b/code/Common/DefaultLogger.cpp @@ -176,7 +176,6 @@ void Logger::debug(const char *message) { // ---------------------------------------------------------------------------------- void Logger::verboseDebug(const char *message) { - // SECURITY FIX: otherwise it's easy to produce overruns since // sometimes importers will include data from the input file // (i.e. node names) in their messages. @@ -209,12 +208,14 @@ void Logger::warnInternal(Assimp::Formatter::format f) { } // ---------------------------------------------------------------------------------- -void Logger::error(const char *message) { +void Logger::errorInternal(Assimp::Formatter::format f) { + std::string message = f; + // TODO: Should limit sizes in the formatter. // SECURITY FIX: see above - if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { + if (message.length() > MAX_LOG_MESSAGE_LENGTH) { return; } - return OnError(message); + return OnError(message.c_str()); } // ---------------------------------------------------------------------------------- diff --git a/code/PostProcessing/CalcTangentsProcess.cpp b/code/PostProcessing/CalcTangentsProcess.cpp index cdafda3b6..721567857 100644 --- a/code/PostProcessing/CalcTangentsProcess.cpp +++ b/code/PostProcessing/CalcTangentsProcess.cpp @@ -129,7 +129,7 @@ bool CalcTangentsProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshIndex) { return false; } if (configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV]) { - ASSIMP_LOG_ERROR((Formatter::format("Failed to compute tangents; need UV data in channel"), configSourceUV)); + ASSIMP_LOG_ERROR_F("Failed to compute tangents; need UV data in channel", configSourceUV); return false; } diff --git a/include/assimp/Logger.hpp b/include/assimp/Logger.hpp index 2c3ee1085..07a26c053 100644 --- a/include/assimp/Logger.hpp +++ b/include/assimp/Logger.hpp @@ -128,9 +128,11 @@ public: // ---------------------------------------------------------------------- /** @brief Writes an error message - * @param message Error message*/ - void error(const char* message); - void error(const std::string &message); + * @param message Info message*/ + template + void error(T&&... args) { + errorInternal(Assimp::Formatter::format(), std::forward(args)...); + } // ---------------------------------------------------------------------- /** @brief Set a new log severity. @@ -244,6 +246,13 @@ protected: infoInternal(std::move(f << std::forward(u)), std::forward(args)...); } + void errorInternal(Assimp::Formatter::format f); + + template + void errorInternal(Assimp::Formatter::format f, U&& u, T&&... args) { + errorInternal(std::move(f << std::forward(u)), std::forward(args)...); + } + protected: LogSeverity m_Severity; }; @@ -296,12 +305,6 @@ inline void Logger::verboseDebug(const std::string &message) { return verboseDebug(message.c_str()); } -// ---------------------------------------------------------------------------------- -inline -void Logger::error(const std::string &message) { - return error(message.c_str()); -} - } // Namespace Assimp // ------------------------------------------------------------------------------------------------ @@ -309,7 +312,7 @@ void Logger::error(const std::string &message) { Assimp::DefaultLogger::get()->warn((string, __VA_ARGS__)) #define ASSIMP_LOG_ERROR_F(string, ...) \ - Assimp::DefaultLogger::get()->error((Assimp::Formatter::format(string), __VA_ARGS__)) + Assimp::DefaultLogger::get()->error((string, __VA_ARGS__)) #define ASSIMP_LOG_DEBUG_F(string, ...) \ Assimp::DefaultLogger::get()->debug((Assimp::Formatter::format(string), __VA_ARGS__)) From 89584c167aaf341a6d717083bb9a52a4c1b0ace1 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Thu, 13 May 2021 09:56:42 +0100 Subject: [PATCH 60/93] Log debug --- code/AssetLib/STEPParser/STEPFileReader.cpp | 4 +-- code/Common/DefaultLogger.cpp | 13 ++++---- .../SplitByBoneCountProcess.cpp | 4 +-- include/assimp/Logger.hpp | 31 ++++++++++--------- include/assimp/Profiler.h | 4 +-- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/code/AssetLib/STEPParser/STEPFileReader.cpp b/code/AssetLib/STEPParser/STEPFileReader.cpp index cbf8c07c2..1ed5ab7d2 100644 --- a/code/AssetLib/STEPParser/STEPFileReader.cpp +++ b/code/AssetLib/STEPParser/STEPFileReader.cpp @@ -297,8 +297,8 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, } if ( !DefaultLogger::isNullLogger()){ - ASSIMP_LOG_DEBUG((Formatter::format(),"STEP: got ",map.size()," object records with ", - db.GetRefs().size()," inverse index entries")); + ASSIMP_LOG_DEBUG_F("STEP: got ",map.size()," object records with ", + db.GetRefs().size()," inverse index entries"); } } diff --git a/code/Common/DefaultLogger.cpp b/code/Common/DefaultLogger.cpp index e468d72ca..03a0a80de 100644 --- a/code/Common/DefaultLogger.cpp +++ b/code/Common/DefaultLogger.cpp @@ -163,15 +163,14 @@ Logger *DefaultLogger::create(const char *name /*= "AssimpLog.txt"*/, } // ---------------------------------------------------------------------------------- -void Logger::debug(const char *message) { - - // SECURITY FIX: otherwise it's easy to produce overruns since - // sometimes importers will include data from the input file - // (i.e. node names) in their messages. - if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { +void Logger::debugInternal(Assimp::Formatter::format f) { + std::string message = f; + // TODO: Should limit sizes in the formatter. + // SECURITY FIX: see above + if (message.length() > MAX_LOG_MESSAGE_LENGTH) { return; } - return OnDebug(message); + return OnDebug(message.c_str()); } // ---------------------------------------------------------------------------------- diff --git a/code/PostProcessing/SplitByBoneCountProcess.cpp b/code/PostProcessing/SplitByBoneCountProcess.cpp index 1f4170a6a..f7dffb8f2 100644 --- a/code/PostProcessing/SplitByBoneCountProcess.cpp +++ b/code/PostProcessing/SplitByBoneCountProcess.cpp @@ -103,7 +103,7 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene) if( !isNecessary ) { - ASSIMP_LOG_DEBUG( format() << "SplitByBoneCountProcess early-out: no meshes with more than " << mMaxBoneCount << " bones." ); + ASSIMP_LOG_DEBUG_F("SplitByBoneCountProcess early-out: no meshes with more than ", mMaxBoneCount, " bones." ); return; } @@ -151,7 +151,7 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene) // recurse through all nodes and translate the node's mesh indices to fit the new mesh array UpdateNode( pScene->mRootNode); - ASSIMP_LOG_DEBUG( format() << "SplitByBoneCountProcess end: split " << mSubMeshIndices.size() << " meshes into " << meshes.size() << " submeshes." ); + ASSIMP_LOG_DEBUG_F( "SplitByBoneCountProcess end: split ", mSubMeshIndices.size(), " meshes into ", meshes.size(), " submeshes." ); } // ------------------------------------------------------------------------------------------------ diff --git a/include/assimp/Logger.hpp b/include/assimp/Logger.hpp index 07a26c053..475b19aa6 100644 --- a/include/assimp/Logger.hpp +++ b/include/assimp/Logger.hpp @@ -99,10 +99,12 @@ public: virtual ~Logger(); // ---------------------------------------------------------------------- - /** @brief Writes a debug message - * @param message Debug message*/ - void debug(const char* message); - void debug(const std::string &message); + /** @brief Writes a info message + * @param message Info message*/ + template + void debug(T&&... args) { + debugInternal(Assimp::Formatter::format(), std::forward(args)...); + } // ---------------------------------------------------------------------- /** @brief Writes a debug message @@ -232,22 +234,27 @@ protected: virtual void OnError(const char* message) = 0; protected: + + void debugInternal(Assimp::Formatter::format f); void warnInternal(Assimp::Formatter::format f); + void infoInternal(Assimp::Formatter::format f); + void errorInternal(Assimp::Formatter::format f); + + template + void debugInternal(Assimp::Formatter::format f, U&& u, T&&... args) { + warnInternal(std::move(f << std::forward(u)), std::forward(args)...); + } template void warnInternal(Assimp::Formatter::format f, U&& u, T&&... args) { warnInternal(std::move(f << std::forward(u)), std::forward(args)...); } - void infoInternal(Assimp::Formatter::format f); - template void infoInternal(Assimp::Formatter::format f, U&& u, T&&... args) { infoInternal(std::move(f << std::forward(u)), std::forward(args)...); } - void errorInternal(Assimp::Formatter::format f); - template void errorInternal(Assimp::Formatter::format f, U&& u, T&&... args) { errorInternal(std::move(f << std::forward(u)), std::forward(args)...); @@ -294,12 +301,6 @@ Logger::LogSeverity Logger::getLogSeverity() const { return m_Severity; } -// ---------------------------------------------------------------------------------- -inline -void Logger::debug(const std::string &message) { - return debug(message.c_str()); -} - // ---------------------------------------------------------------------------------- inline void Logger::verboseDebug(const std::string &message) { return verboseDebug(message.c_str()); @@ -315,7 +316,7 @@ inline void Logger::verboseDebug(const std::string &message) { Assimp::DefaultLogger::get()->error((string, __VA_ARGS__)) #define ASSIMP_LOG_DEBUG_F(string, ...) \ - Assimp::DefaultLogger::get()->debug((Assimp::Formatter::format(string), __VA_ARGS__)) + Assimp::DefaultLogger::get()->debug((string, __VA_ARGS__)) #define ASSIMP_LOG_VERBOSE_DEBUG_F(string, ...) \ Assimp::DefaultLogger::get()->verboseDebug((Assimp::Formatter::format(string), __VA_ARGS__)) diff --git a/include/assimp/Profiler.h b/include/assimp/Profiler.h index 5f9fa52aa..566ea84e1 100644 --- a/include/assimp/Profiler.h +++ b/include/assimp/Profiler.h @@ -76,7 +76,7 @@ public: /** Start a named timer */ void BeginRegion(const std::string& region) { regions[region] = std::chrono::system_clock::now(); - ASSIMP_LOG_DEBUG((format("START `"),region,"`")); + ASSIMP_LOG_DEBUG_F("START `",region,"`"); } @@ -88,7 +88,7 @@ public: } std::chrono::duration elapsedSeconds = std::chrono::system_clock::now() - regions[region]; - ASSIMP_LOG_DEBUG((format("END `"),region,"`, dt= ", elapsedSeconds.count()," s")); + ASSIMP_LOG_DEBUG_F("END `",region,"`, dt= ", elapsedSeconds.count()," s"); } private: From 78145f1425b0ad81f39c1a2c5c26e70fb9174749 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Thu, 13 May 2021 10:08:59 +0100 Subject: [PATCH 61/93] log verboseDebug --- code/AssetLib/ASE/ASELoader.cpp | 2 +- code/AssetLib/COB/COBLoader.cpp | 3 +-- code/AssetLib/DXF/DXFHelper.h | 2 +- code/Common/DefaultLogger.cpp | 12 ++++++------ include/assimp/Logger.hpp | 21 ++++++++++++--------- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/code/AssetLib/ASE/ASELoader.cpp b/code/AssetLib/ASE/ASELoader.cpp index e1b9c5b83..a05c3c5e9 100644 --- a/code/AssetLib/ASE/ASELoader.cpp +++ b/code/AssetLib/ASE/ASELoader.cpp @@ -614,7 +614,7 @@ void ASEImporter::AddNodes(const std::vector &nodes, node->mNumChildren++; // What we did is so great, it is at least worth a debug message - ASSIMP_LOG_VERBOSE_DEBUG("ASE: Generating separate target node (" + snode->mName + ")"); + ASSIMP_LOG_VERBOSE_DEBUG_F("ASE: Generating separate target node (", snode->mName, ")"); } } diff --git a/code/AssetLib/COB/COBLoader.cpp b/code/AssetLib/COB/COBLoader.cpp index a6e9d4218..29e8e9de1 100644 --- a/code/AssetLib/COB/COBLoader.cpp +++ b/code/AssetLib/COB/COBLoader.cpp @@ -301,8 +301,7 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi } std::unique_ptr defmat; if (!min) { - ASSIMP_LOG_VERBOSE_DEBUG(format() << "Could not resolve material index " - << reflist.first << " - creating default material for this slot"); + ASSIMP_LOG_VERBOSE_DEBUG_F("Could not resolve material index ", reflist.first, " - creating default material for this slot"); defmat.reset(min = new Material()); } diff --git a/code/AssetLib/DXF/DXFHelper.h b/code/AssetLib/DXF/DXFHelper.h index f7fc470e8..5099b43ee 100644 --- a/code/AssetLib/DXF/DXFHelper.h +++ b/code/AssetLib/DXF/DXFHelper.h @@ -135,7 +135,7 @@ public: for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++); splitter++; - ASSIMP_LOG_VERBOSE_DEBUG((Formatter::format("DXF: skipped over control group ("),cnt," lines)")); + ASSIMP_LOG_VERBOSE_DEBUG_F("DXF: skipped over control group (",cnt," lines)"); } } catch(std::logic_error&) { ai_assert(!splitter); diff --git a/code/Common/DefaultLogger.cpp b/code/Common/DefaultLogger.cpp index 03a0a80de..e12276ea9 100644 --- a/code/Common/DefaultLogger.cpp +++ b/code/Common/DefaultLogger.cpp @@ -174,14 +174,14 @@ void Logger::debugInternal(Assimp::Formatter::format f) { } // ---------------------------------------------------------------------------------- -void Logger::verboseDebug(const char *message) { - // SECURITY FIX: otherwise it's easy to produce overruns since - // sometimes importers will include data from the input file - // (i.e. node names) in their messages. - if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { +void Logger::verboseDebugInternal(Assimp::Formatter::format f) { + std::string message = f; + // TODO: Should limit sizes in the formatter. + // SECURITY FIX: see above + if (message.length() > MAX_LOG_MESSAGE_LENGTH) { return; } - return OnVerboseDebug(message); + return OnVerboseDebug(message.c_str()); } // ---------------------------------------------------------------------------------- diff --git a/include/assimp/Logger.hpp b/include/assimp/Logger.hpp index 475b19aa6..3d1588f61 100644 --- a/include/assimp/Logger.hpp +++ b/include/assimp/Logger.hpp @@ -109,8 +109,10 @@ public: // ---------------------------------------------------------------------- /** @brief Writes a debug message * @param message Debug message*/ - void verboseDebug(const char *message); - void verboseDebug(const std::string &message); + template + void verboseDebug(T&&... args) { + verboseDebugInternal(Assimp::Formatter::format(), std::forward(args)...); + } // ---------------------------------------------------------------------- /** @brief Writes a info message @@ -236,13 +238,19 @@ protected: protected: void debugInternal(Assimp::Formatter::format f); + void verboseDebugInternal(Assimp::Formatter::format f); void warnInternal(Assimp::Formatter::format f); void infoInternal(Assimp::Formatter::format f); void errorInternal(Assimp::Formatter::format f); template void debugInternal(Assimp::Formatter::format f, U&& u, T&&... args) { - warnInternal(std::move(f << std::forward(u)), std::forward(args)...); + debugInternal(std::move(f << std::forward(u)), std::forward(args)...); + } + + template + void verboseDebugInternal(Assimp::Formatter::format f, U&& u, T&&... args) { + verboseDebugInternal(std::move(f << std::forward(u)), std::forward(args)...); } template @@ -301,11 +309,6 @@ Logger::LogSeverity Logger::getLogSeverity() const { return m_Severity; } -// ---------------------------------------------------------------------------------- -inline void Logger::verboseDebug(const std::string &message) { - return verboseDebug(message.c_str()); -} - } // Namespace Assimp // ------------------------------------------------------------------------------------------------ @@ -319,7 +322,7 @@ inline void Logger::verboseDebug(const std::string &message) { Assimp::DefaultLogger::get()->debug((string, __VA_ARGS__)) #define ASSIMP_LOG_VERBOSE_DEBUG_F(string, ...) \ - Assimp::DefaultLogger::get()->verboseDebug((Assimp::Formatter::format(string), __VA_ARGS__)) + Assimp::DefaultLogger::get()->verboseDebug((string, __VA_ARGS__)) #define ASSIMP_LOG_INFO_F(string, ...) \ Assimp::DefaultLogger::get()->info((string, __VA_ARGS__)) From 6957d3473396c9f94f6fd7456a8718293da89831 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Thu, 13 May 2021 10:14:24 +0100 Subject: [PATCH 62/93] Simplify the macros. --- include/assimp/Logger.hpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/assimp/Logger.hpp b/include/assimp/Logger.hpp index 3d1588f61..71f458731 100644 --- a/include/assimp/Logger.hpp +++ b/include/assimp/Logger.hpp @@ -312,20 +312,20 @@ Logger::LogSeverity Logger::getLogSeverity() const { } // Namespace Assimp // ------------------------------------------------------------------------------------------------ -#define ASSIMP_LOG_WARN_F(string, ...) \ - Assimp::DefaultLogger::get()->warn((string, __VA_ARGS__)) +#define ASSIMP_LOG_WARN_F(...) \ + Assimp::DefaultLogger::get()->warn(__VA_ARGS__) -#define ASSIMP_LOG_ERROR_F(string, ...) \ - Assimp::DefaultLogger::get()->error((string, __VA_ARGS__)) +#define ASSIMP_LOG_ERROR_F(...) \ + Assimp::DefaultLogger::get()->error(__VA_ARGS__) -#define ASSIMP_LOG_DEBUG_F(string, ...) \ - Assimp::DefaultLogger::get()->debug((string, __VA_ARGS__)) +#define ASSIMP_LOG_DEBUG_F(...) \ + Assimp::DefaultLogger::get()->debug(__VA_ARGS__) -#define ASSIMP_LOG_VERBOSE_DEBUG_F(string, ...) \ - Assimp::DefaultLogger::get()->verboseDebug((string, __VA_ARGS__)) +#define ASSIMP_LOG_VERBOSE_DEBUG_F(...) \ + Assimp::DefaultLogger::get()->verboseDebug(__VA_ARGS__) -#define ASSIMP_LOG_INFO_F(string, ...) \ - Assimp::DefaultLogger::get()->info((string, __VA_ARGS__)) +#define ASSIMP_LOG_INFO_F(...) \ + Assimp::DefaultLogger::get()->info(__VA_ARGS__) #define ASSIMP_LOG_WARN(string) \ Assimp::DefaultLogger::get()->warn(string) From 5cd3bdd5c22c1695174cd92639333ef5e5d30291 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Thu, 13 May 2021 10:25:27 +0100 Subject: [PATCH 63/93] No need to distinguish formatting log functions. --- code/AssetLib/3DS/3DSLoader.cpp | 4 +-- code/AssetLib/3MF/D3MFOpcPackage.cpp | 4 +-- code/AssetLib/AC/ACLoader.cpp | 8 ++--- code/AssetLib/ASE/ASELoader.cpp | 2 +- code/AssetLib/ASE/ASEParser.cpp | 2 +- code/AssetLib/B3D/B3DImporter.cpp | 8 ++--- code/AssetLib/Blender/BlenderDNA.cpp | 2 +- code/AssetLib/Blender/BlenderDNA.inl | 2 +- code/AssetLib/Blender/BlenderLoader.cpp | 2 +- code/AssetLib/Blender/BlenderModifier.cpp | 12 +++---- code/AssetLib/Blender/BlenderModifier.h | 2 +- code/AssetLib/COB/COBLoader.cpp | 36 +++++++++---------- code/AssetLib/Collada/ColladaLoader.cpp | 16 ++++----- code/AssetLib/Collada/ColladaParser.cpp | 4 +-- code/AssetLib/DXF/DXFHelper.h | 2 +- code/AssetLib/DXF/DXFLoader.cpp | 14 ++++---- code/AssetLib/FBX/FBXBinaryTokenizer.cpp | 2 +- code/AssetLib/FBX/FBXConverter.cpp | 6 ++-- code/AssetLib/FBX/FBXDocument.cpp | 2 +- code/AssetLib/FBX/FBXDocumentUtil.cpp | 2 +- code/AssetLib/FBX/FBXMaterial.cpp | 2 +- code/AssetLib/LWO/LWOBLoader.cpp | 2 +- code/AssetLib/LWO/LWOLoader.cpp | 8 ++--- code/AssetLib/LWO/LWOMaterial.cpp | 2 +- code/AssetLib/M3D/M3DImporter.cpp | 14 ++++---- code/AssetLib/MD3/MD3Loader.cpp | 6 ++-- code/AssetLib/MS3D/MS3DLoader.cpp | 2 +- code/AssetLib/NDO/NDOLoader.cpp | 2 +- code/AssetLib/NFF/NFFLoader.cpp | 8 ++--- code/AssetLib/Ogre/OgreBinarySerializer.cpp | 28 +++++++-------- code/AssetLib/Ogre/OgreMaterial.cpp | 30 ++++++++-------- code/AssetLib/Ogre/OgreStructs.cpp | 4 +-- code/AssetLib/Ogre/OgreXmlSerializer.cpp | 22 ++++++------ code/AssetLib/OpenGEX/OpenGEXImporter.cpp | 2 +- code/AssetLib/Q3D/Q3DLoader.cpp | 2 +- code/AssetLib/SIB/SIBImporter.cpp | 2 +- code/AssetLib/STEPParser/STEPFileReader.cpp | 2 +- code/AssetLib/Unreal/UnrealLoader.cpp | 6 ++-- code/AssetLib/X/XFileImporter.cpp | 2 +- code/AssetLib/glTF/glTFExporter.cpp | 2 +- code/AssetLib/glTF2/glTF2Importer.cpp | 18 +++++----- code/Common/BaseImporter.cpp | 6 ++-- code/Common/DefaultIOSystem.cpp | 2 +- code/Common/Importer.cpp | 6 ++-- code/Common/SceneCombiner.cpp | 2 +- code/Common/Subdivision.cpp | 2 +- code/PostProcessing/ArmaturePopulate.cpp | 12 +++---- code/PostProcessing/CalcTangentsProcess.cpp | 2 +- code/PostProcessing/DeboneProcess.cpp | 2 +- code/PostProcessing/EmbedTexturesProcess.cpp | 6 ++-- code/PostProcessing/FindDegenerates.cpp | 2 +- code/PostProcessing/FindInstancesProcess.cpp | 2 +- .../PostProcessing/FindInvalidDataProcess.cpp | 2 +- code/PostProcessing/FixNormalsStep.cpp | 2 +- code/PostProcessing/ImproveCacheLocality.cpp | 4 +-- code/PostProcessing/JoinVerticesProcess.cpp | 4 +-- .../LimitBoneWeightsProcess.cpp | 2 +- code/PostProcessing/OptimizeGraph.cpp | 2 +- code/PostProcessing/OptimizeMeshes.cpp | 2 +- code/PostProcessing/PretransformVertices.cpp | 6 ++-- .../RemoveRedundantMaterials.cpp | 4 +-- .../SplitByBoneCountProcess.cpp | 4 +-- code/PostProcessing/TextureTransform.cpp | 6 ++-- include/assimp/LineSplitter.h | 2 +- include/assimp/Logger.hpp | 25 +++---------- include/assimp/Profiler.h | 4 +-- include/assimp/fast_atof.h | 2 +- 67 files changed, 199 insertions(+), 214 deletions(-) diff --git a/code/AssetLib/3DS/3DSLoader.cpp b/code/AssetLib/3DS/3DSLoader.cpp index 2d77e0f66..b5e6f749b 100644 --- a/code/AssetLib/3DS/3DSLoader.cpp +++ b/code/AssetLib/3DS/3DSLoader.cpp @@ -305,7 +305,7 @@ void Discreet3DSImporter::ParseEditorChunk() { // print the version number char buff[10]; ASSIMP_itoa10(buff, stream->GetI2()); - ASSIMP_LOG_INFO_F("3DS file format version: ", buff); + ASSIMP_LOG_INFO("3DS file format version: ", buff); } break; }; ASSIMP_3DS_END_CHUNK(); @@ -934,7 +934,7 @@ void Discreet3DSImporter::ParseFaceChunk() { } } if (0xcdcdcdcd == idx) { - ASSIMP_LOG_ERROR_F("3DS: Unknown material: ", sz); + ASSIMP_LOG_ERROR("3DS: Unknown material: ", sz); } // Now continue and read all material indices diff --git a/code/AssetLib/3MF/D3MFOpcPackage.cpp b/code/AssetLib/3MF/D3MFOpcPackage.cpp index d5bbcd618..dbf4f2e10 100644 --- a/code/AssetLib/3MF/D3MFOpcPackage.cpp +++ b/code/AssetLib/3MF/D3MFOpcPackage.cpp @@ -160,9 +160,9 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) : } } else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) { - ASSIMP_LOG_WARN_F("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file); + ASSIMP_LOG_WARN("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file); } else { - ASSIMP_LOG_WARN_F("Ignored file of unknown type: ", file); + ASSIMP_LOG_WARN("Ignored file of unknown type: ", file); } } } diff --git a/code/AssetLib/AC/ACLoader.cpp b/code/AssetLib/AC/ACLoader.cpp index 59cfc30dd..974e77825 100644 --- a/code/AssetLib/AC/ACLoader.cpp +++ b/code/AssetLib/AC/ACLoader.cpp @@ -492,7 +492,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object, default: // Coerce unknowns to a polygon and warn - ASSIMP_LOG_WARN_F("AC3D: The type flag of a surface is unknown: ", (*it).flags); + ASSIMP_LOG_WARN("AC3D: The type flag of a surface is unknown: ", (*it).flags); (*it).flags &= ~(Surface::Mask); // fallthrough @@ -690,7 +690,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object, if (object.subDiv) { if (configEvalSubdivision) { std::unique_ptr div(Subdivider::Create(Subdivider::CATMULL_CLARKE)); - ASSIMP_LOG_INFO_F("AC3D: Evaluating subdivision surface: ", object.name); + ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: ", object.name); std::vector cpy(meshes.size() - oldm, nullptr); div->Subdivide(&meshes[oldm], cpy.size(), &cpy.front(), object.subDiv, true); @@ -698,7 +698,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object, // previous meshes are deleted vy Subdivide(). } else { - ASSIMP_LOG_INFO_F("AC3D: Letting the subdivision surface untouched due to my configuration: ", object.name); + ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: ", object.name); } } } @@ -782,7 +782,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile, unsigned int version = HexDigitToDecimal(buffer[4]); char msg[3]; ASSIMP_itoa10(msg, 3, version); - ASSIMP_LOG_INFO_F("AC3D file format version: ", msg); + ASSIMP_LOG_INFO("AC3D file format version: ", msg); std::vector materials; materials.reserve(5); diff --git a/code/AssetLib/ASE/ASELoader.cpp b/code/AssetLib/ASE/ASELoader.cpp index a05c3c5e9..1a42c2f52 100644 --- a/code/AssetLib/ASE/ASELoader.cpp +++ b/code/AssetLib/ASE/ASELoader.cpp @@ -614,7 +614,7 @@ void ASEImporter::AddNodes(const std::vector &nodes, node->mNumChildren++; // What we did is so great, it is at least worth a debug message - ASSIMP_LOG_VERBOSE_DEBUG_F("ASE: Generating separate target node (", snode->mName, ")"); + ASSIMP_LOG_VERBOSE_DEBUG("ASE: Generating separate target node (", snode->mName, ")"); } } diff --git a/code/AssetLib/ASE/ASEParser.cpp b/code/AssetLib/ASE/ASEParser.cpp index 00155805f..4e4af8ed8 100644 --- a/code/AssetLib/ASE/ASEParser.cpp +++ b/code/AssetLib/ASE/ASEParser.cpp @@ -677,7 +677,7 @@ void Parser::ParseLV3MapBlock(Texture &map) { if (!ParseString(temp, "*MAP_CLASS")) SkipToNextToken(); if (temp != "Bitmap" && temp != "Normal Bump") { - ASSIMP_LOG_WARN_F("ASE: Skipping unknown map type: ", temp); + ASSIMP_LOG_WARN("ASE: Skipping unknown map type: ", temp); parsePath = false; } continue; diff --git a/code/AssetLib/B3D/B3DImporter.cpp b/code/AssetLib/B3D/B3DImporter.cpp index bcdb286be..3d9a5075a 100644 --- a/code/AssetLib/B3D/B3DImporter.cpp +++ b/code/AssetLib/B3D/B3DImporter.cpp @@ -145,7 +145,7 @@ AI_WONT_RETURN void B3DImporter::Oops() { // ------------------------------------------------------------------------------------------------ AI_WONT_RETURN void B3DImporter::Fail(string str) { #ifdef DEBUG_B3D - ASSIMP_LOG_ERROR_F("Error in B3D file data: ", str); + ASSIMP_LOG_ERROR("Error in B3D file data: ", str); #endif throw DeadlyImportError("B3D Importer - error in B3D file data: ", str); } @@ -233,7 +233,7 @@ string B3DImporter::ReadChunk() { tag += char(ReadByte()); } #ifdef DEBUG_B3D - ASSIMP_LOG_DEBUG_F("ReadChunk: ", tag); + ASSIMP_LOG_DEBUG("ReadChunk: ", tag); #endif unsigned sz = (unsigned)ReadInt(); _stack.push_back(_pos + sz); @@ -397,7 +397,7 @@ void B3DImporter::ReadTRIS(int v0) { matid = 0; } else if (matid < 0 || matid >= (int)_materials.size()) { #ifdef DEBUG_B3D - ASSIMP_LOG_ERROR_F("material id=", matid); + ASSIMP_LOG_ERROR("material id=", matid); #endif Fail("Bad material id"); } @@ -417,7 +417,7 @@ void B3DImporter::ReadTRIS(int v0) { int i2 = ReadInt() + v0; if (i0 < 0 || i0 >= (int)_vertices.size() || i1 < 0 || i1 >= (int)_vertices.size() || i2 < 0 || i2 >= (int)_vertices.size()) { #ifdef DEBUG_B3D - ASSIMP_LOG_ERROR_F("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2); + ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2); #endif Fail("Bad triangle index"); continue; diff --git a/code/AssetLib/Blender/BlenderDNA.cpp b/code/AssetLib/Blender/BlenderDNA.cpp index 4dcb3d654..99e9173aa 100644 --- a/code/AssetLib/Blender/BlenderDNA.cpp +++ b/code/AssetLib/Blender/BlenderDNA.cpp @@ -198,7 +198,7 @@ void DNAParser::Parse() { s.size = offset; } - ASSIMP_LOG_DEBUG_F("BlenderDNA: Got ", dna.structures.size(), " structures with totally ", fields, " fields"); + ASSIMP_LOG_DEBUG("BlenderDNA: Got ", dna.structures.size(), " structures with totally ", fields, " fields"); #ifdef ASSIMP_BUILD_BLENDER_DEBUG dna.DumpToFile(); diff --git a/code/AssetLib/Blender/BlenderDNA.inl b/code/AssetLib/Blender/BlenderDNA.inl index aebcefa84..a46532057 100644 --- a/code/AssetLib/Blender/BlenderDNA.inl +++ b/code/AssetLib/Blender/BlenderDNA.inl @@ -565,7 +565,7 @@ template <> bool Structure :: ResolvePointer(std::shar // this might happen if DNA::RegisterConverters hasn't been called so far // or if the target type is not contained in `our` DNA. out.reset(); - ASSIMP_LOG_WARN_F( "Failed to find a converter for the `",s.name,"` structure" ); + ASSIMP_LOG_WARN( "Failed to find a converter for the `",s.name,"` structure" ); return false; } diff --git a/code/AssetLib/Blender/BlenderLoader.cpp b/code/AssetLib/Blender/BlenderLoader.cpp index 56f4e985f..8cc0162f5 100644 --- a/code/AssetLib/Blender/BlenderLoader.cpp +++ b/code/AssetLib/Blender/BlenderLoader.cpp @@ -310,7 +310,7 @@ void BlenderImporter::ExtractScene(Scene &out, const FileDatabase &file) { ss.Convert(out, file); #ifndef ASSIMP_BUILD_BLENDER_NO_STATS - ASSIMP_LOG_INFO_F( + ASSIMP_LOG_INFO( "(Stats) Fields read: ", file.stats().fields_read, ", pointers resolved: ", file.stats().pointers_resolved, ", cache hits: ", file.stats().cache_hits, diff --git a/code/AssetLib/Blender/BlenderModifier.cpp b/code/AssetLib/Blender/BlenderModifier.cpp index 995e20b1c..bc5c8c2d9 100644 --- a/code/AssetLib/Blender/BlenderModifier.cpp +++ b/code/AssetLib/Blender/BlenderModifier.cpp @@ -90,7 +90,7 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_d const Structure *s = conv_data.db.dna.Get(cur->dna_type); if (!s) { - ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ", cur->dna_type); + ASSIMP_LOG_WARN("BlendModifier: could not resolve DNA name: ", cur->dna_type); continue; } @@ -132,7 +132,7 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_d } } if (curgod) { - ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ", dat.name); + ASSIMP_LOG_WARN("Couldn't find a handler for modifier: ", dat.name); } } @@ -140,7 +140,7 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_d // object, we still can't say whether our modifier implementations were // able to fully do their job. if (ful) { - ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ", cnt, " of ", ful, " modifiers on `", orig_object.id.name, + ASSIMP_LOG_DEBUG("BlendModifier: found handlers for ", cnt, " of ", ful, " modifiers on `", orig_object.id.name, "`, check log messages above for errors"); } } @@ -248,7 +248,7 @@ void BlenderModifier_Mirror ::DoIt(aiNode &out, ConversionData &conv_data, const out.mMeshes = nind; out.mNumMeshes *= 2; - ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `", + ASSIMP_LOG_INFO("BlendModifier: Applied the `Mirror` modifier to `", orig_object.id.name, "`"); } @@ -277,7 +277,7 @@ void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data, break; default: - ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ", mir.subdivType); + ASSIMP_LOG_WARN("BlendModifier: Unrecognized subdivision algorithm: ", mir.subdivType); return; }; @@ -292,7 +292,7 @@ void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data, subd->Subdivide(meshes, out.mNumMeshes, tempmeshes.get(), std::max(mir.renderLevels, mir.levels), true); std::copy(tempmeshes.get(), tempmeshes.get() + out.mNumMeshes, meshes); - ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `", + ASSIMP_LOG_INFO("BlendModifier: Applied the `Subdivision` modifier to `", orig_object.id.name, "`"); } diff --git a/code/AssetLib/Blender/BlenderModifier.h b/code/AssetLib/Blender/BlenderModifier.h index 7d4096cde..daf120087 100644 --- a/code/AssetLib/Blender/BlenderModifier.h +++ b/code/AssetLib/Blender/BlenderModifier.h @@ -86,7 +86,7 @@ public: const Scene& /*in*/, const Object& /*orig_object*/ ) { - ASSIMP_LOG_INFO_F("This modifier is not supported, skipping: ",orig_modifier.dna_type ); + ASSIMP_LOG_INFO("This modifier is not supported, skipping: ",orig_modifier.dna_type ); return; } }; diff --git a/code/AssetLib/COB/COBLoader.cpp b/code/AssetLib/COB/COBLoader.cpp index 29e8e9de1..94327c683 100644 --- a/code/AssetLib/COB/COBLoader.cpp +++ b/code/AssetLib/COB/COBLoader.cpp @@ -152,7 +152,7 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy ThrowException("Could not found magic id: `Caligari`"); } - ASSIMP_LOG_INFO_F("File format tag: ", std::string(head + 9, 6)); + ASSIMP_LOG_INFO("File format tag: ", std::string(head + 9, 6)); if (head[16] != 'L') { ThrowException("File is big-endian, which is not supported"); } @@ -301,7 +301,7 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi } std::unique_ptr defmat; if (!min) { - ASSIMP_LOG_VERBOSE_DEBUG_F("Could not resolve material index ", reflist.first, " - creating default material for this slot"); + ASSIMP_LOG_VERBOSE_DEBUG("Could not resolve material index ", reflist.first, " - creating default material for this slot"); defmat.reset(min = new Material()); } @@ -526,7 +526,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk ++splitter; if (!splitter.match_start("mat# ")) { - ASSIMP_LOG_WARN_F("Expected `mat#` line in `Mat1` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `mat#` line in `Mat1` chunk ", nfo.id); return; } @@ -538,7 +538,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk ++splitter; if (!splitter.match_start("shader: ")) { - ASSIMP_LOG_WARN_F("Expected `mat#` line in `Mat1` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `mat#` line in `Mat1` chunk ", nfo.id); return; } std::string shader = std::string(splitter[1]); @@ -549,12 +549,12 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk } else if (shader == "phong") { mat.shader = Material::PHONG; } else if (shader != "flat") { - ASSIMP_LOG_WARN_F("Unknown value for `shader` in `Mat1` chunk ", nfo.id); + ASSIMP_LOG_WARN("Unknown value for `shader` in `Mat1` chunk ", nfo.id); } ++splitter; if (!splitter.match_start("rgb ")) { - ASSIMP_LOG_WARN_F("Expected `rgb` line in `Mat1` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `rgb` line in `Mat1` chunk ", nfo.id); } const char *rgb = splitter[1]; @@ -562,7 +562,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk ++splitter; if (!splitter.match_start("alpha ")) { - ASSIMP_LOG_WARN_F("Expected `alpha` line in `Mat1` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `alpha` line in `Mat1` chunk ", nfo.id); } const char *tokens[10]; @@ -582,7 +582,7 @@ void COBImporter::ReadUnit_Ascii(Scene &out, LineSplitter &splitter, const Chunk } ++splitter; if (!splitter.match_start("Units ")) { - ASSIMP_LOG_WARN_F("Expected `Units` line in `Unit` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `Units` line in `Unit` chunk ", nfo.id); return; } @@ -593,12 +593,12 @@ void COBImporter::ReadUnit_Ascii(Scene &out, LineSplitter &splitter, const Chunk const unsigned int t = strtoul10(splitter[1]); nd->unit_scale = t >= sizeof(units) / sizeof(units[0]) ? ( - ASSIMP_LOG_WARN_F(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) : + ASSIMP_LOG_WARN(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) : units[t]; return; } } - ASSIMP_LOG_WARN_F("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist"); + ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist"); } // ------------------------------------------------------------------------------------------------ @@ -627,13 +627,13 @@ void COBImporter::ReadLght_Ascii(Scene &out, LineSplitter &splitter, const Chunk } else if (splitter.match_start("Spot ")) { msh.ltype = Light::SPOT; } else { - ASSIMP_LOG_WARN_F("Unknown kind of light source in `Lght` chunk ", nfo.id, " : ", *splitter); + ASSIMP_LOG_WARN("Unknown kind of light source in `Lght` chunk ", nfo.id, " : ", *splitter); msh.ltype = Light::SPOT; } ++splitter; if (!splitter.match_start("color ")) { - ASSIMP_LOG_WARN_F("Expected `color` line in `Lght` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `color` line in `Lght` chunk ", nfo.id); } const char *rgb = splitter[1]; @@ -641,14 +641,14 @@ void COBImporter::ReadLght_Ascii(Scene &out, LineSplitter &splitter, const Chunk SkipSpaces(&rgb); if (strncmp(rgb, "cone angle", 10) != 0) { - ASSIMP_LOG_WARN_F("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id); } SkipSpaces(rgb + 10, &rgb); msh.angle = fast_atof(&rgb); SkipSpaces(&rgb); if (strncmp(rgb, "inner angle", 11) != 0) { - ASSIMP_LOG_WARN_F("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id); + ASSIMP_LOG_WARN("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id); } SkipSpaces(rgb + 11, &rgb); msh.inner_angle = fast_atof(&rgb); @@ -1032,7 +1032,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene &out, StreamReaderLE &reader, const mat.type = Material::METAL; break; default: - ASSIMP_LOG_ERROR_F("Unrecognized shader type in `Mat1` chunk with id ", nfo.id); + ASSIMP_LOG_ERROR("Unrecognized shader type in `Mat1` chunk with id ", nfo.id); mat.type = Material::FLAT; } @@ -1047,7 +1047,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene &out, StreamReaderLE &reader, const mat.autofacet = Material::SMOOTH; break; default: - ASSIMP_LOG_ERROR_F("Unrecognized faceting mode in `Mat1` chunk with id ", nfo.id); + ASSIMP_LOG_ERROR("Unrecognized faceting mode in `Mat1` chunk with id ", nfo.id); mat.autofacet = Material::FACETED; } mat.autofacet_angle = static_cast(reader.GetI1()); @@ -1175,13 +1175,13 @@ void COBImporter::ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const if (nd->id == nfo.parent_id) { const unsigned int t = reader.GetI2(); nd->unit_scale = t >= sizeof(units) / sizeof(units[0]) ? ( - ASSIMP_LOG_WARN_F(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) : + ASSIMP_LOG_WARN(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) : units[t]; return; } } - ASSIMP_LOG_WARN_F("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist"); + ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist"); } #endif // ASSIMP_BUILD_NO_COB_IMPORTER diff --git a/code/AssetLib/Collada/ColladaLoader.cpp b/code/AssetLib/Collada/ColladaLoader.cpp index 736d20ce5..492e6971f 100644 --- a/code/AssetLib/Collada/ColladaLoader.cpp +++ b/code/AssetLib/Collada/ColladaLoader.cpp @@ -317,7 +317,7 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Nod nd = FindNode(pParser.mRootNode, nodeInst.mNode); } if (nullptr == nd) { - ASSIMP_LOG_ERROR_F("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode); + ASSIMP_LOG_ERROR("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode); } else { // attach this node to the list of children resolved.push_back(nd); @@ -347,7 +347,7 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node // find the referred light ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find(lid.mLight); if (srcLightIt == pParser.mLightLibrary.end()) { - ASSIMP_LOG_WARN_F("Collada: Unable to find light for ID \"", lid.mLight, "\". Skipping."); + ASSIMP_LOG_WARN("Collada: Unable to find light for ID \"", lid.mLight, "\". Skipping."); continue; } const Collada::Light *srcLight = &srcLightIt->second; @@ -412,7 +412,7 @@ void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Node // find the referred light ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find(cid.mCamera); if (srcCameraIt == pParser.mCameraLibrary.end()) { - ASSIMP_LOG_WARN_F("Collada: Unable to find camera for ID \"", cid.mCamera, "\". Skipping."); + ASSIMP_LOG_WARN("Collada: Unable to find camera for ID \"", cid.mCamera, "\". Skipping."); continue; } const Collada::Camera *srcCamera = &srcCameraIt->second; @@ -486,7 +486,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node } if (nullptr == srcMesh) { - ASSIMP_LOG_WARN_F("Collada: Unable to find geometry for ID \"", mid.mMeshOrController, "\". Skipping."); + ASSIMP_LOG_WARN("Collada: Unable to find geometry for ID \"", mid.mMeshOrController, "\". Skipping."); continue; } } else { @@ -511,7 +511,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node table = &meshMatIt->second; meshMaterial = table->mMatName; } else { - ASSIMP_LOG_WARN_F("Collada: No material specified for subgroup <", submesh.mMaterial, "> in geometry <", + ASSIMP_LOG_WARN("Collada: No material specified for subgroup <", submesh.mMaterial, "> in geometry <", mid.mMeshOrController, ">."); if (!mid.mMaterials.empty()) { meshMaterial = mid.mMaterials.begin()->second.mMatName; @@ -883,7 +883,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc if (nullptr != bnode) { bone->mName.Set(FindNameForNode(bnode)); } else { - ASSIMP_LOG_WARN_F("ColladaLoader::CreateMesh(): could not find corresponding node for joint \"", bone->mName.data, "\"."); + ASSIMP_LOG_WARN("ColladaLoader::CreateMesh(): could not find corresponding node for joint \"", bone->mName.data, "\"."); } // and insert bone @@ -1184,7 +1184,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse else if (subElement == "Z") entry.mSubElement = 2; else - ASSIMP_LOG_WARN_F("Unknown anim subelement <", subElement, ">. Ignoring"); + ASSIMP_LOG_WARN("Unknown anim subelement <", subElement, ">. Ignoring"); } else { // no sub-element following, transformId is remaining string entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1); @@ -1711,7 +1711,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse // find the image referred by this name in the image library of the scene ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find(name); if (imIt == pParser.mImageLibrary.end()) { - ASSIMP_LOG_WARN_F("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\"."); + ASSIMP_LOG_WARN("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\"."); //set default texture file name result.Set(name + ".jpg"); diff --git a/code/AssetLib/Collada/ColladaParser.cpp b/code/AssetLib/Collada/ColladaParser.cpp index 1ef109f11..fc9a45802 100644 --- a/code/AssetLib/Collada/ColladaParser.cpp +++ b/code/AssetLib/Collada/ColladaParser.cpp @@ -71,7 +71,7 @@ static void ReportWarning(const char *msg, ...) { ai_assert(iLen > 0); va_end(args); - ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer, iLen)); + ASSIMP_LOG_WARN("Validation warning: ", std::string(szBuffer, iLen)); } static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) { @@ -2400,7 +2400,7 @@ Collada::InputType ColladaParser::GetTypeForSemantic(const std::string &semantic else if (semantic == "TANGENT" || semantic == "TEXTANGENT") return IT_Tangent; - ASSIMP_LOG_WARN_F("Unknown vertex input type \"", semantic, "\". Ignoring."); + ASSIMP_LOG_WARN("Unknown vertex input type \"", semantic, "\". Ignoring."); return IT_Invalid; } diff --git a/code/AssetLib/DXF/DXFHelper.h b/code/AssetLib/DXF/DXFHelper.h index 5099b43ee..c7e75c3b1 100644 --- a/code/AssetLib/DXF/DXFHelper.h +++ b/code/AssetLib/DXF/DXFHelper.h @@ -135,7 +135,7 @@ public: for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++); splitter++; - ASSIMP_LOG_VERBOSE_DEBUG_F("DXF: skipped over control group (",cnt," lines)"); + ASSIMP_LOG_VERBOSE_DEBUG("DXF: skipped over control group (",cnt," lines)"); } } catch(std::logic_error&) { ai_assert(!splitter); diff --git a/code/AssetLib/DXF/DXFLoader.cpp b/code/AssetLib/DXF/DXFLoader.cpp index d4a6be4ad..09c229265 100644 --- a/code/AssetLib/DXF/DXFLoader.cpp +++ b/code/AssetLib/DXF/DXFLoader.cpp @@ -202,7 +202,7 @@ void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene, // comments else if (reader.Is(999)) { - ASSIMP_LOG_INFO_F("DXF Comment: ", reader.Value()); + ASSIMP_LOG_INFO("DXF Comment: ", reader.Value()); } // don't read past the official EOF sign @@ -241,7 +241,7 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) { } } - ASSIMP_LOG_VERBOSE_DEBUG_F("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount); + ASSIMP_LOG_VERBOSE_DEBUG("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount); } if (! output.blocks.size() ) { @@ -372,7 +372,7 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc // first check if the referenced blocks exists ... const DXF::BlockMap::const_iterator it = blocks_by_name.find(insert.name); if (it == blocks_by_name.end()) { - ASSIMP_LOG_ERROR_F("DXF: Failed to resolve block reference: ", insert.name,"; skipping" ); + ASSIMP_LOG_ERROR("DXF: Failed to resolve block reference: ", insert.name,"; skipping" ); continue; } @@ -473,7 +473,7 @@ void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output) { ++reader; } - ASSIMP_LOG_VERBOSE_DEBUG_F("DXF: got ", output.blocks.size()," entries in BLOCKS" ); + ASSIMP_LOG_VERBOSE_DEBUG("DXF: got ", output.blocks.size()," entries in BLOCKS" ); } // ------------------------------------------------------------------------------------------------ @@ -549,7 +549,7 @@ void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output) ++reader; } - ASSIMP_LOG_VERBOSE_DEBUG_F( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(), + ASSIMP_LOG_VERBOSE_DEBUG( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(), " inserted blocks in ENTITIES" ); } @@ -654,7 +654,7 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) //} if (vguess && line.positions.size() != vguess) { - ASSIMP_LOG_WARN_F("DXF: unexpected vertex count in polymesh: ", + ASSIMP_LOG_WARN("DXF: unexpected vertex count in polymesh: ", line.positions.size(),", expected ", vguess ); } @@ -670,7 +670,7 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) // to set the 71 and 72 fields, respectively, to valid values. // So just fire a warning. if (iguess && line.counts.size() != iguess) { - ASSIMP_LOG_WARN_F( "DXF: unexpected face count in polymesh: ", line.counts.size(),", expected ", iguess ); + ASSIMP_LOG_WARN( "DXF: unexpected face count in polymesh: ", line.counts.size(),", expected ", iguess ); } } else if (!line.indices.size() && !line.counts.size()) { diff --git a/code/AssetLib/FBX/FBXBinaryTokenizer.cpp b/code/AssetLib/FBX/FBXBinaryTokenizer.cpp index 800d0014d..348812054 100644 --- a/code/AssetLib/FBX/FBXBinaryTokenizer.cpp +++ b/code/AssetLib/FBX/FBXBinaryTokenizer.cpp @@ -459,7 +459,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length) /*Result ignored*/ ReadByte(input, cursor, input + length); /*Result ignored*/ ReadByte(input, cursor, input + length); const uint32_t version = ReadWord(input, cursor, input + length); - ASSIMP_LOG_DEBUG_F("FBX version: ", version); + ASSIMP_LOG_DEBUG("FBX version: ", version); const bool is64bits = version >= 7500; const char *end = input + length; try diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index cb033a651..88d7ad626 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -1542,10 +1542,10 @@ void FBXConverter::ConvertCluster(std::vector &local_mesh_bones, const aiBone *bone = nullptr; if (bone_map.count(deformer_name)) { - ASSIMP_LOG_VERBOSE_DEBUG_F("retrieved bone from lookup ", bone_name.C_Str(), ". Deformer:", deformer_name); + ASSIMP_LOG_VERBOSE_DEBUG("retrieved bone from lookup ", bone_name.C_Str(), ". Deformer:", deformer_name); bone = bone_map[deformer_name]; } else { - ASSIMP_LOG_VERBOSE_DEBUG_F("created new bone ", bone_name.C_Str(), ". Deformer: ", deformer_name); + ASSIMP_LOG_VERBOSE_DEBUG("created new bone ", bone_name.C_Str(), ". Deformer: ", deformer_name); bone = new aiBone(); bone->mName = bone_name; @@ -1591,7 +1591,7 @@ void FBXConverter::ConvertCluster(std::vector &local_mesh_bones, const bone_map.insert(std::pair(deformer_name, bone)); } - ASSIMP_LOG_DEBUG_F("bone research: Indicies size: ", out_indices.size()); + ASSIMP_LOG_DEBUG("bone research: Indicies size: ", out_indices.size()); // lookup must be populated in case something goes wrong // this also allocates bones to mesh instance outside diff --git a/code/AssetLib/FBX/FBXDocument.cpp b/code/AssetLib/FBX/FBXDocument.cpp index a9eb3ad15..7adaadf6c 100644 --- a/code/AssetLib/FBX/FBXDocument.cpp +++ b/code/AssetLib/FBX/FBXDocument.cpp @@ -312,7 +312,7 @@ void Document::ReadHeader() { const Scope& shead = *ehead->Compound(); fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0)); - ASSIMP_LOG_DEBUG_F("FBX Version: ", fbxVersion); + ASSIMP_LOG_DEBUG("FBX Version: ", fbxVersion); // While we may have some success with newer files, we don't support // the older 6.n fbx format diff --git a/code/AssetLib/FBX/FBXDocumentUtil.cpp b/code/AssetLib/FBX/FBXDocumentUtil.cpp index 6ba01aa47..77455198f 100644 --- a/code/AssetLib/FBX/FBXDocumentUtil.cpp +++ b/code/AssetLib/FBX/FBXDocumentUtil.cpp @@ -79,7 +79,7 @@ void DOMError(const std::string& message, const Element* element /*= nullptr*/) void DOMWarning(const std::string& message, const Token& token) { if(DefaultLogger::get()) { - ASSIMP_LOG_WARN_F("FBX-DOM", Util::GetTokenText(&token), message); + ASSIMP_LOG_WARN("FBX-DOM", Util::GetTokenText(&token), message); } } diff --git a/code/AssetLib/FBX/FBXMaterial.cpp b/code/AssetLib/FBX/FBXMaterial.cpp index 409d7304a..6ada9630b 100644 --- a/code/AssetLib/FBX/FBXMaterial.cpp +++ b/code/AssetLib/FBX/FBXMaterial.cpp @@ -352,7 +352,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std } } catch (const runtime_error& runtimeError) { //we don't need the content data for contents that has already been loaded - ASSIMP_LOG_VERBOSE_DEBUG_F("Caught exception in FBXMaterial (likely because content was already loaded): ", + ASSIMP_LOG_VERBOSE_DEBUG("Caught exception in FBXMaterial (likely because content was already loaded): ", runtimeError.what()); } } diff --git a/code/AssetLib/LWO/LWOBLoader.cpp b/code/AssetLib/LWO/LWOBLoader.cpp index 2654eccf4..8ef40fc21 100644 --- a/code/AssetLib/LWO/LWOBLoader.cpp +++ b/code/AssetLib/LWO/LWOBLoader.cpp @@ -242,7 +242,7 @@ LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned i else { // procedural or gradient, not supported - ASSIMP_LOG_ERROR_F("LWOB: Unsupported legacy texture: ", type); + ASSIMP_LOG_ERROR("LWOB: Unsupported legacy texture: ", type); } return tex; diff --git a/code/AssetLib/LWO/LWOLoader.cpp b/code/AssetLib/LWO/LWOLoader.cpp index a9fa08f11..7a2916424 100644 --- a/code/AssetLib/LWO/LWOLoader.cpp +++ b/code/AssetLib/LWO/LWOLoader.cpp @@ -1006,7 +1006,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { if (name == "APS.Level") { // XXX handle this (seems to be subdivision-related). } - ASSIMP_LOG_WARN_F("LWO2: Skipping unknown VMAP/VMAD channel \'", name, "\'"); + ASSIMP_LOG_WARN("LWO2: Skipping unknown VMAP/VMAD channel \'", name, "\'"); return; }; base->Allocate((unsigned int)mCurLayer->mTempPoints.size()); @@ -1026,7 +1026,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs; if (idx >= numPoints) { - ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAP/VMAD entry \'", name, "\', vertex index is out of range"); + ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAP/VMAD entry \'", name, "\', vertex index is out of range"); mFileBuffer += base->dims << 2u; continue; } @@ -1036,7 +1036,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { // we have already a VMAP entry for this vertex - thus // we need to duplicate the corresponding polygon. if (polyIdx >= numFaces) { - ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAD entry \'", name, "\', polygon index is out of range"); + ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAD entry \'", name, "\', polygon index is out of range"); mFileBuffer += base->dims << 2u; continue; } @@ -1076,7 +1076,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { CreateNewEntry(mCurLayer->mNormals, srcIdx); } if (!had) { - ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAD entry \'", name, "\', vertex index wasn't found in that polygon"); + ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAD entry \'", name, "\', vertex index wasn't found in that polygon"); ai_assert(had); } } diff --git a/code/AssetLib/LWO/LWOMaterial.cpp b/code/AssetLib/LWO/LWOMaterial.cpp index 9d51438d7..186aa8a42 100644 --- a/code/AssetLib/LWO/LWOMaterial.cpp +++ b/code/AssetLib/LWO/LWOMaterial.cpp @@ -335,7 +335,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) { m = aiShadingMode_Fresnel; break; } else { - ASSIMP_LOG_WARN_F("LWO2: Unknown surface shader: ", shader.functionName); + ASSIMP_LOG_WARN("LWO2: Unknown surface shader: ", shader.functionName); } } if (surf.mMaximumSmoothAngle <= 0.0) diff --git a/code/AssetLib/M3D/M3DImporter.cpp b/code/AssetLib/M3D/M3DImporter.cpp index 1fb21d73e..5485b1bff 100644 --- a/code/AssetLib/M3D/M3DImporter.cpp +++ b/code/AssetLib/M3D/M3DImporter.cpp @@ -193,7 +193,7 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys } //DefaultLogger::create("/dev/stderr", Logger::VERBOSE); - ASSIMP_LOG_DEBUG_F("M3D: loading ", file); + ASSIMP_LOG_DEBUG("M3D: loading ", file); // let the C SDK do the hard work for us M3DWrapper m3d(pIOHandler, buffer); @@ -239,7 +239,7 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) { mScene->mNumMaterials = m3d->nummaterial + 1; mScene->mMaterials = new aiMaterial *[mScene->mNumMaterials]; - ASSIMP_LOG_DEBUG_F("M3D: importMaterials ", mScene->mNumMaterials); + ASSIMP_LOG_DEBUG("M3D: importMaterials ", mScene->mNumMaterials); // add a default material as first aiMaterial *mat = new aiMaterial; @@ -334,7 +334,7 @@ void M3DImporter::importTextures(const M3DWrapper &m3d) { ai_assert(m3d); mScene->mNumTextures = m3d->numtexture; - ASSIMP_LOG_DEBUG_F("M3D: importTextures ", mScene->mNumTextures); + ASSIMP_LOG_DEBUG("M3D: importTextures ", mScene->mNumTextures); if (!m3d->numtexture || !m3d->texture) { return; @@ -389,7 +389,7 @@ void M3DImporter::importTextures(const M3DWrapper &m3d) { // individually. In assimp there're per mesh vertex and UV lists, and they must be // indexed simultaneously. void M3DImporter::importMeshes(const M3DWrapper &m3d) { - ASSIMP_LOG_DEBUG_F("M3D: importMeshes ", m3d->numface); + ASSIMP_LOG_DEBUG("M3D: importMeshes ", m3d->numface); if (!m3d->numface || !m3d->face || !m3d->numvertex || !m3d->vertex) { return; @@ -508,7 +508,7 @@ void M3DImporter::importBones(const M3DWrapper &m3d, unsigned int parentid, aiNo ai_assert(mScene != nullptr); ai_assert(m3d); - ASSIMP_LOG_DEBUG_F("M3D: importBones ", m3d->numbone, " parentid ", (int)parentid); + ASSIMP_LOG_DEBUG("M3D: importBones ", m3d->numbone, " parentid ", (int)parentid); if (!m3d->numbone || !m3d->bone) { return; @@ -549,7 +549,7 @@ void M3DImporter::importAnimations(const M3DWrapper &m3d) { mScene->mNumAnimations = m3d->numaction; - ASSIMP_LOG_DEBUG_F("M3D: importAnimations ", mScene->mNumAnimations); + ASSIMP_LOG_DEBUG("M3D: importAnimations ", mScene->mNumAnimations); if (!m3d->numaction || !m3d->action || !m3d->numbone || !m3d->bone || !m3d->vertex) { return; @@ -712,7 +712,7 @@ void M3DImporter::populateMesh(const M3DWrapper &m3d, aiMesh *pMesh, std::vector ai_assert(vertexids != nullptr); ai_assert(m3d); - ASSIMP_LOG_DEBUG_F("M3D: populateMesh numvertices ", vertices->size(), " numfaces ", faces->size(), + ASSIMP_LOG_DEBUG("M3D: populateMesh numvertices ", vertices->size(), " numfaces ", faces->size(), " numnormals ", normals->size(), " numtexcoord ", texcoords->size(), " numbones ", m3d->numbone); if (vertices->size() && faces->size()) { diff --git a/code/AssetLib/MD3/MD3Loader.cpp b/code/AssetLib/MD3/MD3Loader.cpp index 3002aff67..18c3d4228 100644 --- a/code/AssetLib/MD3/MD3Loader.cpp +++ b/code/AssetLib/MD3/MD3Loader.cpp @@ -112,7 +112,7 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem * if (!file.get()) return false; // if we can't access the file, don't worry and return - ASSIMP_LOG_INFO_F("Loading Quake3 shader file ", pFile); + ASSIMP_LOG_INFO("Loading Quake3 shader file ", pFile); // read file in memory const size_t s = file->FileSize(); @@ -851,7 +851,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy if (it != skins.textures.end()) { texture_name = &*(_texture_name = (*it).second).begin(); - ASSIMP_LOG_VERBOSE_DEBUG_F("MD3: Assigning skin texture ", (*it).second, " to surface ", pcSurfaces->NAME); + ASSIMP_LOG_VERBOSE_DEBUG("MD3: Assigning skin texture ", (*it).second, " to surface ", pcSurfaces->NAME); (*it).resolved = true; // mark entry as resolved } @@ -1000,7 +1000,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy if (!DefaultLogger::isNullLogger()) { for (std::list::const_iterator it = skins.textures.begin(); it != skins.textures.end(); ++it) { if (!(*it).resolved) { - ASSIMP_LOG_ERROR_F("MD3: Failed to match skin ", (*it).first, " to surface ", (*it).second); + ASSIMP_LOG_ERROR("MD3: Failed to match skin ", (*it).first, " to surface ", (*it).second); } } } diff --git a/code/AssetLib/MS3D/MS3DLoader.cpp b/code/AssetLib/MS3D/MS3DLoader.cpp index 31cbca83b..e4057a43a 100644 --- a/code/AssetLib/MS3D/MS3DLoader.cpp +++ b/code/AssetLib/MS3D/MS3DLoader.cpp @@ -387,7 +387,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile, } const std::string& s = std::string(reinterpret_cast(stream.GetPtr()),len); - ASSIMP_LOG_DEBUG_F("MS3D: Model comment: ", s); + ASSIMP_LOG_DEBUG("MS3D: Model comment: ", s); } if(stream.GetRemainingSize() > 4 && inrange((stream >> subversion,subversion),1u,3u)) { diff --git a/code/AssetLib/NDO/NDOLoader.cpp b/code/AssetLib/NDO/NDOLoader.cpp index df3a9b15d..0abc09dc8 100644 --- a/code/AssetLib/NDO/NDOLoader.cpp +++ b/code/AssetLib/NDO/NDOLoader.cpp @@ -147,7 +147,7 @@ void NDOImporter::InternReadFile( const std::string& pFile, ASSIMP_LOG_INFO("NDO file format is 1.2"); } else { - ASSIMP_LOG_WARN_F( "Unrecognized nendo file format version, continuing happily ... :", (head+6)); + ASSIMP_LOG_WARN( "Unrecognized nendo file format version, continuing happily ... :", (head+6)); } reader.IncPtr(2); /* skip flags */ diff --git a/code/AssetLib/NFF/NFFLoader.cpp b/code/AssetLib/NFF/NFFLoader.cpp index 11cce0990..65f2dc069 100644 --- a/code/AssetLib/NFF/NFFLoader.cpp +++ b/code/AssetLib/NFF/NFFLoader.cpp @@ -150,7 +150,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector &output, // The file should start with the magic sequence "mat" if (!TokenMatch(buffer, "mat", 3)) { - ASSIMP_LOG_ERROR_F("NFF2: Not a valid material library ", path, "."); + ASSIMP_LOG_ERROR("NFF2: Not a valid material library ", path, "."); return; } @@ -164,7 +164,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector &output, // 'version' defines the version of the file format if (TokenMatch(sz, "version", 7)) { - ASSIMP_LOG_INFO_F("NFF (Sense8) material library file format: ", std::string(sz)); + ASSIMP_LOG_INFO("NFF (Sense8) material library file format: ", std::string(sz)); } // 'matdef' starts a new material in the file else if (TokenMatch(sz, "matdef", 6)) { @@ -177,7 +177,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector &output, // check whether we have an active material at the moment if (!IsLineEnd(*sz)) { if (!curShader) { - ASSIMP_LOG_ERROR_F("NFF2 material library: Found element ", sz, "but there is no active material"); + ASSIMP_LOG_ERROR("NFF2 material library: Found element ", sz, "but there is no active material"); continue; } } else @@ -277,7 +277,7 @@ void NFFImporter::InternReadFile(const std::string &pFile, while (GetNextLine(buffer, line)) { SkipSpaces(line, &sz); if (TokenMatch(sz, "version", 7)) { - ASSIMP_LOG_INFO_F("NFF (Sense8) file format: ", sz); + ASSIMP_LOG_INFO("NFF (Sense8) file format: ", sz); } else if (TokenMatch(sz, "viewpos", 7)) { AI_NFF_PARSE_TRIPLE(camPos); hasCam = true; diff --git a/code/AssetLib/Ogre/OgreBinarySerializer.cpp b/code/AssetLib/Ogre/OgreBinarySerializer.cpp index 0fc18feb9..b54316514 100644 --- a/code/AssetLib/Ogre/OgreBinarySerializer.cpp +++ b/code/AssetLib/Ogre/OgreBinarySerializer.cpp @@ -168,7 +168,7 @@ void OgreBinarySerializer::RollbackHeader() { void OgreBinarySerializer::SkipBytes(size_t numBytes) { #if (OGRE_BINARY_SERIALIZER_DEBUG == 1) - ASSIMP_LOG_VERBOSE_DEBUG_F("Skipping ", numBytes, " bytes"); + ASSIMP_LOG_VERBOSE_DEBUG("Skipping ", numBytes, " bytes"); #endif m_reader->IncPtr(numBytes); @@ -208,7 +208,7 @@ void OgreBinarySerializer::ReadMesh(Mesh *mesh) { mesh->hasSkeletalAnimations = Read(); ASSIMP_LOG_VERBOSE_DEBUG("Reading Mesh"); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Skeletal animations: ", mesh->hasSkeletalAnimations ? "true" : "false"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Skeletal animations: ", mesh->hasSkeletalAnimations ? "true" : "false"); if (!AtEnd()) { uint16_t id = ReadHeader(); @@ -364,9 +364,9 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh) { submesh->indexData->faceCount = static_cast(submesh->indexData->count / 3); submesh->indexData->is32bit = Read(); - ASSIMP_LOG_VERBOSE_DEBUG_F("Reading SubMesh ", mesh->subMeshes.size()); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Material: '", submesh->materialRef, "'"); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Uses shared geometry: ", submesh->usesSharedVertexData ? "true" : "false"); + ASSIMP_LOG_VERBOSE_DEBUG("Reading SubMesh ", mesh->subMeshes.size()); + ASSIMP_LOG_VERBOSE_DEBUG(" - Material: '", submesh->materialRef, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Uses shared geometry: ", submesh->usesSharedVertexData ? "true" : "false"); // Index buffer if (submesh->indexData->count > 0) { @@ -374,7 +374,7 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh) { uint8_t *indexBuffer = ReadBytes(numBytes); submesh->indexData->buffer = MemoryStreamPtr(new Assimp::MemoryIOStream(indexBuffer, numBytes, true)); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - ", submesh->indexData->faceCount, + ASSIMP_LOG_VERBOSE_DEBUG(" - ", submesh->indexData->faceCount, " faces from ", submesh->indexData->count, (submesh->indexData->is32bit ? " 32bit" : " 16bit"), " indexes of ", numBytes, " bytes"); } @@ -475,7 +475,7 @@ void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh) { } submesh->name = ReadLine(); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - SubMesh ", submesh->index, " name '", submesh->name, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" - SubMesh ", submesh->index, " name '", submesh->name, "'"); if (!AtEnd()) id = ReadHeader(); @@ -488,7 +488,7 @@ void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh) { void OgreBinarySerializer::ReadGeometry(VertexData *dest) { dest->count = Read(); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Reading geometry of ", dest->count, " vertices"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Reading geometry of ", dest->count, " vertices"); if (!AtEnd()) { uint16_t id = ReadHeader(); @@ -536,7 +536,7 @@ void OgreBinarySerializer::ReadGeometryVertexElement(VertexData *dest) { element.offset = Read(); element.index = Read(); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Vertex element ", element.SemanticToString(), " of type ", + ASSIMP_LOG_VERBOSE_DEBUG(" - Vertex element ", element.SemanticToString(), " of type ", element.TypeToString(), " index=", element.index, " source=", element.source); dest->vertexElements.push_back(element); @@ -557,7 +557,7 @@ void OgreBinarySerializer::ReadGeometryVertexBuffer(VertexData *dest) { uint8_t *vertexBuffer = ReadBytes(numBytes); dest->vertexBindings[bindIndex] = MemoryStreamPtr(new Assimp::MemoryIOStream(vertexBuffer, numBytes, true)); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Read vertex buffer for source ", bindIndex, " of ", numBytes, " bytes"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Read vertex buffer for source ", bindIndex, " of ", numBytes, " bytes"); } void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/) { @@ -777,12 +777,12 @@ bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename) { if (!EndsWith(filename, ".skeleton", false)) { - ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file."); + ASSIMP_LOG_ERROR("Imported Mesh is referencing to unsupported '", filename, "' skeleton file."); return MemoryStreamReaderPtr(); } if (!pIOHandler->Exists(filename)) { - ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh."); + ASSIMP_LOG_ERROR("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh."); return MemoryStreamReaderPtr(); } @@ -874,7 +874,7 @@ void OgreBinarySerializer::ReadBone(Skeleton *skeleton) { throw DeadlyImportError("Ogre Skeleton bone indexes not contiguous. Error at bone index ", bone->id); } - ASSIMP_LOG_VERBOSE_DEBUG_F(" ", bone->id, " ", bone->name); + ASSIMP_LOG_VERBOSE_DEBUG(" ", bone->id, " ", bone->name); skeleton->bones.push_back(bone); } @@ -919,7 +919,7 @@ void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton) { skeleton->animations.push_back(anim); - ASSIMP_LOG_VERBOSE_DEBUG_F(" ", anim->name, " (", anim->length, " sec, ", anim->tracks.size(), " tracks)"); + ASSIMP_LOG_VERBOSE_DEBUG(" ", anim->name, " (", anim->length, " sec, ", anim->tracks.size(), " tracks)"); } void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, Animation *dest) { diff --git a/code/AssetLib/Ogre/OgreMaterial.cpp b/code/AssetLib/Ogre/OgreMaterial.cpp index eced651f6..cafdda795 100644 --- a/code/AssetLib/Ogre/OgreMaterial.cpp +++ b/code/AssetLib/Ogre/OgreMaterial.cpp @@ -160,16 +160,16 @@ aiMaterial *OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste if (materialFile) { break; } - ASSIMP_LOG_VERBOSE_DEBUG_F("Source file for material '", materialName, "' ", potentialFiles[i], " does not exist"); + ASSIMP_LOG_VERBOSE_DEBUG("Source file for material '", materialName, "' ", potentialFiles[i], " does not exist"); } if (!materialFile) { - ASSIMP_LOG_ERROR_F("Failed to find source file for material '", materialName, "'"); + ASSIMP_LOG_ERROR("Failed to find source file for material '", materialName, "'"); return 0; } std::unique_ptr stream(materialFile); if (stream->FileSize() == 0) { - ASSIMP_LOG_WARN_F("Source file for material '", materialName, "' is empty (size is 0 bytes)"); + ASSIMP_LOG_WARN("Source file for material '", materialName, "' is empty (size is 0 bytes)"); return 0; } @@ -184,7 +184,7 @@ aiMaterial *OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste ss << &data[0]; } - ASSIMP_LOG_VERBOSE_DEBUG_F("Reading material '", materialName, "'"); + ASSIMP_LOG_VERBOSE_DEBUG("Reading material '", materialName, "'"); aiMaterial *material = new aiMaterial(); m_textures.clear(); @@ -219,11 +219,11 @@ aiMaterial *OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste NextAfterNewLine(ss, linePart); if (linePart != partBlockStart) { - ASSIMP_LOG_ERROR_F("Invalid material: block start missing near index ", ss.tellg()); + ASSIMP_LOG_ERROR("Invalid material: block start missing near index ", ss.tellg()); return material; } - ASSIMP_LOG_VERBOSE_DEBUG_F("material '", materialName, "'"); + ASSIMP_LOG_VERBOSE_DEBUG("material '", materialName, "'"); while (linePart != partBlockEnd) { // Proceed to the first technique @@ -303,11 +303,11 @@ bool OgreImporter::ReadTechnique(const std::string &techniqueName, stringstream ss >> linePart; if (linePart != partBlockStart) { - ASSIMP_LOG_ERROR_F("Invalid material: Technique block start missing near index ", ss.tellg()); + ASSIMP_LOG_ERROR("Invalid material: Technique block start missing near index ", ss.tellg()); return false; } - ASSIMP_LOG_VERBOSE_DEBUG_F(" technique '", techniqueName, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" technique '", techniqueName, "'"); const string partPass = "pass"; @@ -334,11 +334,11 @@ bool OgreImporter::ReadPass(const std::string &passName, stringstream &ss, aiMat ss >> linePart; if (linePart != partBlockStart) { - ASSIMP_LOG_ERROR_F("Invalid material: Pass block start missing near index ", ss.tellg()); + ASSIMP_LOG_ERROR("Invalid material: Pass block start missing near index ", ss.tellg()); return false; } - ASSIMP_LOG_VERBOSE_DEBUG_F(" pass '", passName, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" pass '", passName, "'"); const string partAmbient = "ambient"; const string partDiffuse = "diffuse"; @@ -362,7 +362,7 @@ bool OgreImporter::ReadPass(const std::string &passName, stringstream &ss, aiMat ss >> r >> g >> b; const aiColor3D color(r, g, b); - ASSIMP_LOG_VERBOSE_DEBUG_F(" ", linePart, " ", r, " ", g, " ", b); + ASSIMP_LOG_VERBOSE_DEBUG(" ", linePart, " ", r, " ", g, " ", b); if (linePart == partAmbient) { material->AddProperty(&color, 1, AI_MATKEY_COLOR_AMBIENT); @@ -386,11 +386,11 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr ss >> linePart; if (linePart != partBlockStart) { - ASSIMP_LOG_ERROR_F("Invalid material: Texture unit block start missing near index ", ss.tellg()); + ASSIMP_LOG_ERROR("Invalid material: Texture unit block start missing near index ", ss.tellg()); return false; } - ASSIMP_LOG_VERBOSE_DEBUG_F(" texture_unit '", textureUnitName, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" texture_unit '", textureUnitName, "'"); const string partTexture = "texture"; const string partTextCoordSet = "tex_coord_set"; @@ -420,7 +420,7 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) { string identifier = ai_tolower(textureRef.substr(posUnderscore, posSuffix - posUnderscore)); - ASSIMP_LOG_VERBOSE_DEBUG_F("Detecting texture type from filename postfix '", identifier, "'"); + ASSIMP_LOG_VERBOSE_DEBUG("Detecting texture type from filename postfix '", identifier, "'"); if (identifier == "_n" || identifier == "_nrm" || identifier == "_nrml" || identifier == "_normal" || identifier == "_normals" || identifier == "_normalmap") { textureType = aiTextureType_NORMALS; @@ -484,7 +484,7 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr unsigned int textureTypeIndex = m_textures[textureType]; m_textures[textureType]++; - ASSIMP_LOG_VERBOSE_DEBUG_F(" texture '", textureRef, "' type ", textureType, + ASSIMP_LOG_VERBOSE_DEBUG(" texture '", textureRef, "' type ", textureType, " index ", textureTypeIndex, " UV ", uvCoord); aiString assimpTextureRef(textureRef); diff --git a/code/AssetLib/Ogre/OgreStructs.cpp b/code/AssetLib/Ogre/OgreStructs.cpp index ce289c79c..a2d861172 100644 --- a/code/AssetLib/Ogre/OgreStructs.cpp +++ b/code/AssetLib/Ogre/OgreStructs.cpp @@ -545,7 +545,7 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent) { dest->mNumUVComponents[0] = static_cast(uv1Element->ComponentCount()); dest->mTextureCoords[0] = new aiVector3D[dest->mNumVertices]; } else { - ASSIMP_LOG_WARN_F("Ogre imported UV0 type ", uv1Element->TypeToString(), " is not compatible with Assimp. Ignoring UV."); + ASSIMP_LOG_WARN("Ogre imported UV0 type ", uv1Element->TypeToString(), " is not compatible with Assimp. Ignoring UV."); uv1 = 0; } } @@ -554,7 +554,7 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent) { dest->mNumUVComponents[1] = static_cast(uv2Element->ComponentCount()); dest->mTextureCoords[1] = new aiVector3D[dest->mNumVertices]; } else { - ASSIMP_LOG_WARN_F("Ogre imported UV0 type ", uv2Element->TypeToString(), " is not compatible with Assimp. Ignoring UV."); + ASSIMP_LOG_WARN("Ogre imported UV0 type ", uv2Element->TypeToString(), " is not compatible with Assimp. Ignoring UV."); uv2 = 0; } } diff --git a/code/AssetLib/Ogre/OgreXmlSerializer.cpp b/code/AssetLib/Ogre/OgreXmlSerializer.cpp index 938ae48f3..70671f251 100644 --- a/code/AssetLib/Ogre/OgreXmlSerializer.cpp +++ b/code/AssetLib/Ogre/OgreXmlSerializer.cpp @@ -256,7 +256,7 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) { void OgreXmlSerializer::ReadGeometry(XmlNode &node, VertexDataXml *dest) { dest->count = ReadAttribute(node, "vertexcount"); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Reading geometry of ", dest->count, " vertices"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Reading geometry of ", dest->count, " vertices"); for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); @@ -290,7 +290,7 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(XmlNode &node, VertexDataXml *d dest->tangents.reserve(dest->count); } if (uvs > 0) { - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Contains ", uvs, " texture coords"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Contains ", uvs, " texture coords"); dest->uvs.resize(uvs); for (size_t i = 0, len = dest->uvs.size(); i < len; ++i) { dest->uvs[i].reserve(dest->count); @@ -365,9 +365,9 @@ void OgreXmlSerializer::ReadSubMesh(XmlNode &node, MeshXml *mesh) { submesh->usesSharedVertexData = ReadAttribute(node, anUseSharedVertices); } - ASSIMP_LOG_VERBOSE_DEBUG_F("Reading SubMesh ", mesh->subMeshes.size()); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Material: '", submesh->materialRef, "'"); - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Uses shared geometry: ", (submesh->usesSharedVertexData ? "true" : "false")); + ASSIMP_LOG_VERBOSE_DEBUG("Reading SubMesh ", mesh->subMeshes.size()); + ASSIMP_LOG_VERBOSE_DEBUG(" - Material: '", submesh->materialRef, "'"); + ASSIMP_LOG_VERBOSE_DEBUG(" - Uses shared geometry: ", (submesh->usesSharedVertexData ? "true" : "false")); // TODO: maybe we have always just 1 faces and 1 geometry and always in this order. this loop will only work correct, when the order // of faces and geometry changed, and not if we have more than one of one @@ -398,7 +398,7 @@ void OgreXmlSerializer::ReadSubMesh(XmlNode &node, MeshXml *mesh) { } } if (submesh->indexData->faces.size() == submesh->indexData->faceCount) { - ASSIMP_LOG_VERBOSE_DEBUG_F(" - Faces ", submesh->indexData->faceCount); + ASSIMP_LOG_VERBOSE_DEBUG(" - Faces ", submesh->indexData->faceCount); } else { throw DeadlyImportError("Read only ", submesh->indexData->faces.size(), " faces when should have read ", submesh->indexData->faceCount); } @@ -459,7 +459,7 @@ void OgreXmlSerializer::ReadBoneAssignments(XmlNode &node, VertexDataXml *dest) } } - ASSIMP_LOG_VERBOSE_DEBUG_F(" - ", dest->boneAssignments.size(), " bone assignments"); + ASSIMP_LOG_VERBOSE_DEBUG(" - ", dest->boneAssignments.size(), " bone assignments"); } // Skeleton @@ -515,12 +515,12 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh) XmlParserPtr OgreXmlSerializer::OpenXmlParser(Assimp::IOSystem *pIOHandler, const std::string &filename) { if (!EndsWith(filename, ".skeleton.xml", false)) { - ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file."); + ASSIMP_LOG_ERROR("Imported Mesh is referencing to unsupported '", filename, "' skeleton file."); return XmlParserPtr(); } if (!pIOHandler->Exists(filename)) { - ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh."); + ASSIMP_LOG_ERROR("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh."); return XmlParserPtr(); } @@ -631,7 +631,7 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(XmlNode &node, Animation *anim, V if (axis.Equal(zeroVec)) { axis.x = 1.0f; if (angle != 0) { - ASSIMP_LOG_WARN_F("Found invalid a key frame with a zero rotation axis in animation: ", anim->name); + ASSIMP_LOG_WARN("Found invalid a key frame with a zero rotation axis in animation: ", anim->name); } } keyframe.rotation = aiQuaternion(axis, angle); @@ -741,7 +741,7 @@ void OgreXmlSerializer::ReadBones(XmlNode &node, Skeleton *skeleton) { as per the Ogre skeleton spec. It might be more that other (later) code in this imported does not break. */ for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) { Bone *b = skeleton->bones[i]; - ASSIMP_LOG_VERBOSE_DEBUG_F(" ", b->id, " ", b->name); + ASSIMP_LOG_VERBOSE_DEBUG(" ", b->id, " ", b->name); if (b->id != static_cast(i)) { throw DeadlyImportError("Bone ids are not in sequence starting from 0. Missing index ", i); diff --git a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp index 44b0bbf7b..9baaa4a12 100644 --- a/code/AssetLib/OpenGEX/OpenGEXImporter.cpp +++ b/code/AssetLib/OpenGEX/OpenGEXImporter.cpp @@ -726,7 +726,7 @@ void OpenGEXImporter::handleMeshNode(ODDLParser::DDLNode *node, aiScene *pScene) } else if ("quads" == propKey) { m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; } else { - ASSIMP_LOG_WARN_F(propKey, " is not supported primitive type."); + ASSIMP_LOG_WARN(propKey, " is not supported primitive type."); } } } diff --git a/code/AssetLib/Q3D/Q3DLoader.cpp b/code/AssetLib/Q3D/Q3DLoader.cpp index e96ec0f82..f81026547 100644 --- a/code/AssetLib/Q3D/Q3DLoader.cpp +++ b/code/AssetLib/Q3D/Q3DLoader.cpp @@ -125,7 +125,7 @@ void Q3DImporter::InternReadFile(const std::string &pFile, } // Print the file format version - ASSIMP_LOG_INFO_F("Quick3D File format version: ", + ASSIMP_LOG_INFO("Quick3D File format version: ", std::string(&((const char *)stream.GetPtr())[8], 2)); // ... an store it diff --git a/code/AssetLib/SIB/SIBImporter.cpp b/code/AssetLib/SIB/SIBImporter.cpp index 1426fb73c..c62730cdd 100644 --- a/code/AssetLib/SIB/SIBImporter.cpp +++ b/code/AssetLib/SIB/SIBImporter.cpp @@ -174,7 +174,7 @@ static void UnknownChunk(StreamReaderLE * /*stream*/, const SIBChunk &chunk) { static_cast(chunk.Tag & 0xff) }; - ASSIMP_LOG_WARN_F("SIB: Skipping unknown '", ai_str_toprintable(temp, 4), "' chunk."); + ASSIMP_LOG_WARN("SIB: Skipping unknown '", ai_str_toprintable(temp, 4), "' chunk."); } // Reads a UTF-16LE string and returns it at UTF-8. diff --git a/code/AssetLib/STEPParser/STEPFileReader.cpp b/code/AssetLib/STEPParser/STEPFileReader.cpp index 1ed5ab7d2..e97ea1e28 100644 --- a/code/AssetLib/STEPParser/STEPFileReader.cpp +++ b/code/AssetLib/STEPParser/STEPFileReader.cpp @@ -297,7 +297,7 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, } if ( !DefaultLogger::isNullLogger()){ - ASSIMP_LOG_DEBUG_F("STEP: got ",map.size()," object records with ", + ASSIMP_LOG_DEBUG("STEP: got ",map.size()," object records with ", db.GetRefs().size()," inverse index entries"); } } diff --git a/code/AssetLib/Unreal/UnrealLoader.cpp b/code/AssetLib/Unreal/UnrealLoader.cpp index 499b49c05..e3ebc05c3 100644 --- a/code/AssetLib/Unreal/UnrealLoader.cpp +++ b/code/AssetLib/Unreal/UnrealLoader.cpp @@ -228,9 +228,9 @@ void UnrealImporter::InternReadFile(const std::string &pFile, a_path = extension + "_a.3d"; uc_path = extension + ".uc"; - ASSIMP_LOG_DEBUG_F("UNREAL: data file is ", d_path); - ASSIMP_LOG_DEBUG_F("UNREAL: aniv file is ", a_path); - ASSIMP_LOG_DEBUG_F("UNREAL: uc file is ", uc_path); + ASSIMP_LOG_DEBUG("UNREAL: data file is ", d_path); + ASSIMP_LOG_DEBUG("UNREAL: aniv file is ", a_path); + ASSIMP_LOG_DEBUG("UNREAL: uc file is ", uc_path); // and open the files ... we can't live without them std::unique_ptr p(pIOHandler->Open(d_path)); diff --git a/code/AssetLib/X/XFileImporter.cpp b/code/AssetLib/X/XFileImporter.cpp index 1fcd6b3db..df1aba331 100644 --- a/code/AssetLib/X/XFileImporter.cpp +++ b/code/AssetLib/X/XFileImporter.cpp @@ -602,7 +602,7 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector &embeddedTexIdxs, Asset &r, M void glTF2Importer::ImportMaterials(glTF2::Asset &r) { const unsigned int numImportedMaterials = unsigned(r.materials.Size()); - ASSIMP_LOG_DEBUG_F("Importing ", numImportedMaterials, " materials"); + ASSIMP_LOG_DEBUG("Importing ", numImportedMaterials, " materials"); Material defaultMaterial; mScene->mNumMaterials = numImportedMaterials + 1; @@ -402,7 +402,7 @@ aiColor4D* GetVertexColorsForType(glTF2::Ref input) { } void glTF2Importer::ImportMeshes(glTF2::Asset &r) { - ASSIMP_LOG_DEBUG_F("Importing ", r.meshes.Size(), " meshes"); + ASSIMP_LOG_DEBUG("Importing ", r.meshes.Size(), " meshes"); std::vector> meshes; unsigned int k = 0; @@ -539,7 +539,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { if (needPositions) { if (target.position[0]->count != aim->mNumVertices) { - ASSIMP_LOG_WARN_F("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); + ASSIMP_LOG_WARN("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { aiVector3D *positionDiff = nullptr; target.position[0]->ExtractData(positionDiff); @@ -551,7 +551,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { } if (needNormals) { if (target.normal[0]->count != aim->mNumVertices) { - ASSIMP_LOG_WARN_F("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); + ASSIMP_LOG_WARN("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { aiVector3D *normalDiff = nullptr; target.normal[0]->ExtractData(normalDiff); @@ -563,7 +563,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { } if (needTangents) { if (target.tangent[0]->count != aim->mNumVertices) { - ASSIMP_LOG_WARN_F("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); + ASSIMP_LOG_WARN("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count"); } else { Tangent *tangent = nullptr; attr.tangent[0]->ExtractData(tangent); @@ -785,7 +785,7 @@ void glTF2Importer::ImportCameras(glTF2::Asset &r) { if (!r.cameras.Size()) return; const unsigned int numCameras = r.cameras.Size(); - ASSIMP_LOG_DEBUG_F("Importing ", numCameras, " cameras"); + ASSIMP_LOG_DEBUG("Importing ", numCameras, " cameras"); mScene->mNumCameras = numCameras; mScene->mCameras = new aiCamera *[numCameras]; std::fill(mScene->mCameras, mScene->mCameras + numCameras, nullptr); @@ -822,7 +822,7 @@ void glTF2Importer::ImportLights(glTF2::Asset &r) { return; const unsigned int numLights = r.lights.Size(); - ASSIMP_LOG_DEBUG_F("Importing ", numLights, " lights"); + ASSIMP_LOG_DEBUG("Importing ", numLights, " lights"); mScene->mNumLights = numLights; mScene->mLights = new aiLight *[numLights]; std::fill(mScene->mLights, mScene->mLights + numLights, nullptr); @@ -1329,7 +1329,7 @@ void glTF2Importer::ImportAnimations(glTF2::Asset &r) { if (!r.scene) return; const unsigned numAnimations = r.animations.Size(); - ASSIMP_LOG_DEBUG_F("Importing ", numAnimations, " animations"); + ASSIMP_LOG_DEBUG("Importing ", numAnimations, " animations"); mScene->mNumAnimations = numAnimations; if (mScene->mNumAnimations == 0) { return; @@ -1445,7 +1445,7 @@ void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset &r) { if (numEmbeddedTexs == 0) return; - ASSIMP_LOG_DEBUG_F("Importing ", numEmbeddedTexs, " embedded textures"); + ASSIMP_LOG_DEBUG("Importing ", numEmbeddedTexs, " embedded textures"); mScene->mTextures = new aiTexture *[numEmbeddedTexs]; std::fill(mScene->mTextures, mScene->mTextures + numEmbeddedTexs, nullptr); diff --git a/code/Common/BaseImporter.cpp b/code/Common/BaseImporter.cpp index 02aa47326..0f41e9e65 100644 --- a/code/Common/BaseImporter.cpp +++ b/code/Common/BaseImporter.cpp @@ -83,7 +83,7 @@ void BaseImporter::UpdateImporterScale(Importer *pImp) { // Set active scaling pImp->SetPropertyFloat(AI_CONFIG_APP_SCALE_KEY, static_cast(activeScale)); - ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: ", activeScale); + ASSIMP_LOG_DEBUG("UpdateImporterScale scale set: ", activeScale); } // ------------------------------------------------------------------------------------------------ @@ -215,7 +215,7 @@ void BaseImporter::GetExtensionList(std::set &extensions) { // We got a match, either we don't care where it is, or it happens to // be in the beginning of the file / line if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') { - ASSIMP_LOG_DEBUG_F("Found positive match for header keyword: ", tokens[i]); + ASSIMP_LOG_DEBUG("Found positive match for header keyword: ", tokens[i]); return true; } } @@ -604,7 +604,7 @@ void BatchLoader::LoadAll() { if (!DefaultLogger::isNullLogger()) { ASSIMP_LOG_INFO("%%% BEGIN EXTERNAL FILE %%%"); - ASSIMP_LOG_INFO_F("File: ", (*it).file); + ASSIMP_LOG_INFO("File: ", (*it).file); } m_data->pImporter->ReadFile((*it).file, pp); (*it).scene = m_data->pImporter->GetOrphanedScene(); diff --git a/code/Common/DefaultIOSystem.cpp b/code/Common/DefaultIOSystem.cpp index ec7a311cf..98d51a17d 100644 --- a/code/Common/DefaultIOSystem.cpp +++ b/code/Common/DefaultIOSystem.cpp @@ -176,7 +176,7 @@ inline static std::string MakeAbsolutePath(const char *in) { if (!ret) { // preserve the input path, maybe someone else is able to fix // the path before it is accessed (e.g. our file system filter) - ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in)); + ASSIMP_LOG_WARN("Invalid path: ", std::string(in)); out = in; } return out; diff --git a/code/Common/Importer.cpp b/code/Common/Importer.cpp index 8cea2cd09..61e5938f6 100644 --- a/code/Common/Importer.cpp +++ b/code/Common/Importer.cpp @@ -232,7 +232,7 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp) { #ifdef ASSIMP_BUILD_DEBUG if (IsExtensionSupported(*it)) { - ASSIMP_LOG_WARN_F("The file extension ", *it, " is already in use"); + ASSIMP_LOG_WARN("The file extension ", *it, " is already in use"); } #endif baked += *it; @@ -240,7 +240,7 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp) { // add the loader pimpl->mImporter.push_back(pImp); - ASSIMP_LOG_INFO_F("Registering custom importer for these file extensions: ", baked); + ASSIMP_LOG_INFO("Registering custom importer for these file extensions: ", baked); ASSIMP_END_EXCEPTION_REGION(aiReturn); return AI_SUCCESS; @@ -519,7 +519,7 @@ const aiScene* Importer::ReadFileFromMemory( const void* pBuffer, // ------------------------------------------------------------------------------------------------ void WriteLogOpening(const std::string& file) { - ASSIMP_LOG_INFO_F("Load ", file); + ASSIMP_LOG_INFO("Load ", file); // print a full version dump. This is nice because we don't // need to ask the authors of incoming bug reports for diff --git a/code/Common/SceneCombiner.cpp b/code/Common/SceneCombiner.cpp index fe00dfe1f..555d46b6a 100644 --- a/code/Common/SceneCombiner.cpp +++ b/code/Common/SceneCombiner.cpp @@ -612,7 +612,7 @@ void SceneCombiner::MergeScenes(aiScene **_dest, aiScene *master, std::vectormName.data, + ASSIMP_LOG_ERROR("SceneCombiner: Failed to resolve attachment ", (*it).node->mName.data, " ", (*it).attachToNode->mName.data); } } diff --git a/code/Common/Subdivision.cpp b/code/Common/Subdivision.cpp index 76fc83404..9e7577a04 100644 --- a/code/Common/Subdivision.cpp +++ b/code/Common/Subdivision.cpp @@ -336,7 +336,7 @@ void CatmullClarkSubdivider::InternSubdivide( // Report the number of bad edges. bad edges are referenced by less than two // faces in the mesh. They occur at outer model boundaries in non-closed // shapes. - ASSIMP_LOG_VERBOSE_DEBUG_F("Catmull-Clark Subdivider: got ", bad_cnt, " bad edges touching only one face (totally ", + ASSIMP_LOG_VERBOSE_DEBUG("Catmull-Clark Subdivider: got ", bad_cnt, " bad edges touching only one face (totally ", static_cast(edges.size()), " edges). "); } } diff --git a/code/PostProcessing/ArmaturePopulate.cpp b/code/PostProcessing/ArmaturePopulate.cpp index 88b0b2d7c..fdf7508d0 100644 --- a/code/PostProcessing/ArmaturePopulate.cpp +++ b/code/PostProcessing/ArmaturePopulate.cpp @@ -77,12 +77,12 @@ void ArmaturePopulate::Execute(aiScene *out) { BuildBoneStack(out->mRootNode, out->mRootNode, out, bones, bone_stack, nodes); - ASSIMP_LOG_DEBUG_F("Bone stack size: ", bone_stack.size()); + ASSIMP_LOG_DEBUG("Bone stack size: ", bone_stack.size()); for (std::pair kvp : bone_stack) { aiBone *bone = kvp.first; aiNode *bone_node = kvp.second; - ASSIMP_LOG_VERBOSE_DEBUG_F("active node lookup: ", bone->mName.C_Str()); + ASSIMP_LOG_VERBOSE_DEBUG("active node lookup: ", bone->mName.C_Str()); // lcl transform grab - done in generate_nodes :) // bone->mOffsetMatrix = bone_node->mTransformation; @@ -179,7 +179,7 @@ void ArmaturePopulate::BuildBoneStack(aiNode *, if (node == nullptr) { node_stack.clear(); BuildNodeList(root_node, node_stack); - ASSIMP_LOG_VERBOSE_DEBUG_F("Resetting bone stack: nullptr element ", bone->mName.C_Str()); + ASSIMP_LOG_VERBOSE_DEBUG("Resetting bone stack: nullptr element ", bone->mName.C_Str()); node = GetNodeFromStack(bone->mName, node_stack); @@ -189,7 +189,7 @@ void ArmaturePopulate::BuildBoneStack(aiNode *, } } - ASSIMP_LOG_VERBOSE_DEBUG_F("Successfully added bone[", bone->mName.C_Str(), "] to stack and bone node is: ", node->mName.C_Str()); + ASSIMP_LOG_VERBOSE_DEBUG("Successfully added bone[", bone->mName.C_Str(), "] to stack and bone node is: ", node->mName.C_Str()); bone_stack.insert(std::pair(bone, node)); } @@ -203,7 +203,7 @@ aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node, std::vector &bone_list) { while (nullptr != bone_node) { if (!IsBoneNode(bone_node->mName, bone_list)) { - ASSIMP_LOG_VERBOSE_DEBUG_F("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str()); + ASSIMP_LOG_VERBOSE_DEBUG("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str()); return bone_node; } @@ -247,7 +247,7 @@ aiNode *ArmaturePopulate::GetNodeFromStack(const aiString &node_name, } if (found != nullptr) { - ASSIMP_LOG_INFO_F("Removed node from stack: ", found->mName.C_Str()); + ASSIMP_LOG_INFO("Removed node from stack: ", found->mName.C_Str()); // now pop the element from the node list nodes.erase(iter); diff --git a/code/PostProcessing/CalcTangentsProcess.cpp b/code/PostProcessing/CalcTangentsProcess.cpp index 721567857..46feff4a1 100644 --- a/code/PostProcessing/CalcTangentsProcess.cpp +++ b/code/PostProcessing/CalcTangentsProcess.cpp @@ -129,7 +129,7 @@ bool CalcTangentsProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshIndex) { return false; } if (configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV]) { - ASSIMP_LOG_ERROR_F("Failed to compute tangents; need UV data in channel", configSourceUV); + ASSIMP_LOG_ERROR("Failed to compute tangents; need UV data in channel", configSourceUV); return false; } diff --git a/code/PostProcessing/DeboneProcess.cpp b/code/PostProcessing/DeboneProcess.cpp index b5ed66268..3783bb65c 100644 --- a/code/PostProcessing/DeboneProcess.cpp +++ b/code/PostProcessing/DeboneProcess.cpp @@ -148,7 +148,7 @@ void DeboneProcess::Execute( aiScene* pScene) } if(!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F("Removed %u bones. Input bones:", in - out, ". Output bones: ", out); + ASSIMP_LOG_INFO("Removed %u bones. Input bones:", in - out, ". Output bones: ", out); } // and destroy the source mesh. It should be completely contained inside the new submeshes diff --git a/code/PostProcessing/EmbedTexturesProcess.cpp b/code/PostProcessing/EmbedTexturesProcess.cpp index dc304ff9c..7e435e556 100644 --- a/code/PostProcessing/EmbedTexturesProcess.cpp +++ b/code/PostProcessing/EmbedTexturesProcess.cpp @@ -93,7 +93,7 @@ void EmbedTexturesProcess::Execute(aiScene* pScene) { } } - ASSIMP_LOG_INFO_F("EmbedTexturesProcess finished. Embedded ", embeddedTexturesCount, " textures." ); + ASSIMP_LOG_INFO("EmbedTexturesProcess finished. Embedded ", embeddedTexturesCount, " textures." ); } bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const { @@ -103,7 +103,7 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const { // Test path directly std::ifstream file(imagePath, std::ios::binary | std::ios::ate); if ((imageSize = file.tellg()) == std::streampos(-1)) { - ASSIMP_LOG_WARN_F("EmbedTexturesProcess: Cannot find image: ", imagePath, ". Will try to find it in root folder."); + ASSIMP_LOG_WARN("EmbedTexturesProcess: Cannot find image: ", imagePath, ". Will try to find it in root folder."); // Test path in root path imagePath = mRootPath + path; @@ -113,7 +113,7 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const { imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u); file.open(imagePath, std::ios::binary | std::ios::ate); if ((imageSize = file.tellg()) == std::streampos(-1)) { - ASSIMP_LOG_ERROR_F("EmbedTexturesProcess: Unable to embed texture: ", path, "."); + ASSIMP_LOG_ERROR("EmbedTexturesProcess: Unable to embed texture: ", path, "."); return false; } } diff --git a/code/PostProcessing/FindDegenerates.cpp b/code/PostProcessing/FindDegenerates.cpp index 1fc58cf59..eae91ff02 100644 --- a/code/PostProcessing/FindDegenerates.cpp +++ b/code/PostProcessing/FindDegenerates.cpp @@ -291,7 +291,7 @@ evil_jump_outside: } if (deg && !DefaultLogger::isNullLogger()) { - ASSIMP_LOG_WARN_F( "Found ", deg, " degenerated primitives"); + ASSIMP_LOG_WARN( "Found ", deg, " degenerated primitives"); } return false; } diff --git a/code/PostProcessing/FindInstancesProcess.cpp b/code/PostProcessing/FindInstancesProcess.cpp index 98527e531..ab5f52b78 100644 --- a/code/PostProcessing/FindInstancesProcess.cpp +++ b/code/PostProcessing/FindInstancesProcess.cpp @@ -267,7 +267,7 @@ void FindInstancesProcess::Execute( aiScene* pScene) // write to log if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F( "FindInstancesProcess finished. Found ", (pScene->mNumMeshes - numMeshesOut), " instances" ); + ASSIMP_LOG_INFO( "FindInstancesProcess finished. Found ", (pScene->mNumMeshes - numMeshesOut), " instances" ); } pScene->mNumMeshes = numMeshesOut; } else { diff --git a/code/PostProcessing/FindInvalidDataProcess.cpp b/code/PostProcessing/FindInvalidDataProcess.cpp index 9c19c606a..ea7d99094 100644 --- a/code/PostProcessing/FindInvalidDataProcess.cpp +++ b/code/PostProcessing/FindInvalidDataProcess.cpp @@ -200,7 +200,7 @@ inline bool ProcessArray(T *&in, unsigned int num, const char *name, const std::vector &dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true) { const char *err = ValidateArrayContents(in, num, dirtyMask, mayBeIdentical, mayBeZero); if (err) { - ASSIMP_LOG_ERROR_F("FindInvalidDataProcess fails on mesh ", name, ": ", err); + ASSIMP_LOG_ERROR("FindInvalidDataProcess fails on mesh ", name, ": ", err); delete[] in; in = nullptr; return true; diff --git a/code/PostProcessing/FixNormalsStep.cpp b/code/PostProcessing/FixNormalsStep.cpp index 850da5e25..09b1f1908 100644 --- a/code/PostProcessing/FixNormalsStep.cpp +++ b/code/PostProcessing/FixNormalsStep.cpp @@ -164,7 +164,7 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index) // now compare the volumes of the bounding boxes if (std::fabs(fDelta0_x * fDelta0_y * fDelta0_z) < std::fabs(fDelta1_x * fDelta1_yz)) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F("Mesh ", index, ": Normals are facing inwards (or the mesh is planar)", index); + ASSIMP_LOG_INFO("Mesh ", index, ": Normals are facing inwards (or the mesh is planar)", index); } // Invert normals diff --git a/code/PostProcessing/ImproveCacheLocality.cpp b/code/PostProcessing/ImproveCacheLocality.cpp index 38d5c5a5b..3243c40b4 100644 --- a/code/PostProcessing/ImproveCacheLocality.cpp +++ b/code/PostProcessing/ImproveCacheLocality.cpp @@ -109,7 +109,7 @@ void ImproveCacheLocalityProcess::Execute( aiScene* pScene) { } if (!DefaultLogger::isNullLogger()) { if (numf > 0) { - ASSIMP_LOG_INFO_F("Cache relevant are ", numm, " meshes (", numf, " faces). Average output ACMR is ", out / numf); + ASSIMP_LOG_INFO("Cache relevant are ", numm, " meshes (", numf, " faces). Average output ACMR is ", out / numf); } ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess finished. "); } @@ -355,7 +355,7 @@ ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int me // very intense verbose logging ... prepare for much text if there are many meshes if ( DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) { - ASSIMP_LOG_VERBOSE_DEBUG_F("Mesh %u | ACMR in: ", meshNum, " out: ", fACMR, " | ~", fACMR2, ((fACMR - fACMR2) / fACMR) * 100.f); + ASSIMP_LOG_VERBOSE_DEBUG("Mesh %u | ACMR in: ", meshNum, " out: ", fACMR, " | ~", fACMR2, ((fACMR - fACMR2) / fACMR) * 100.f); } fACMR2 *= pMesh->mNumFaces; diff --git a/code/PostProcessing/JoinVerticesProcess.cpp b/code/PostProcessing/JoinVerticesProcess.cpp index 22b399471..60c64f3bf 100644 --- a/code/PostProcessing/JoinVerticesProcess.cpp +++ b/code/PostProcessing/JoinVerticesProcess.cpp @@ -100,7 +100,7 @@ void JoinVerticesProcess::Execute( aiScene* pScene) if (iNumOldVertices == iNumVertices) { ASSIMP_LOG_DEBUG("JoinVerticesProcess finished "); } else { - ASSIMP_LOG_INFO_F("JoinVerticesProcess finished | Verts in: ", iNumOldVertices, + ASSIMP_LOG_INFO("JoinVerticesProcess finished | Verts in: ", iNumOldVertices, " out: ", iNumVertices, " | ~", ((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f ); } @@ -373,7 +373,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) } if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) { - ASSIMP_LOG_VERBOSE_DEBUG_F( + ASSIMP_LOG_VERBOSE_DEBUG( "Mesh ",meshIndex, " (", (pMesh->mName.length ? pMesh->mName.data : "unnamed"), diff --git a/code/PostProcessing/LimitBoneWeightsProcess.cpp b/code/PostProcessing/LimitBoneWeightsProcess.cpp index c7ecf1b00..fb8b49b91 100644 --- a/code/PostProcessing/LimitBoneWeightsProcess.cpp +++ b/code/PostProcessing/LimitBoneWeightsProcess.cpp @@ -191,6 +191,6 @@ void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh) pMesh->mNumBones = writeBone; if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO_F("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones); + ASSIMP_LOG_INFO("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones); } } diff --git a/code/PostProcessing/OptimizeGraph.cpp b/code/PostProcessing/OptimizeGraph.cpp index ad49b635a..e33c2ab18 100644 --- a/code/PostProcessing/OptimizeGraph.cpp +++ b/code/PostProcessing/OptimizeGraph.cpp @@ -335,7 +335,7 @@ void OptimizeGraphProcess::Execute(aiScene *pScene) { pScene->mRootNode->mParent = nullptr; if (!DefaultLogger::isNullLogger()) { if (nodes_in != nodes_out) { - ASSIMP_LOG_INFO_F("OptimizeGraphProcess finished; Input nodes: ", nodes_in, ", Output nodes: ", nodes_out); + ASSIMP_LOG_INFO("OptimizeGraphProcess finished; Input nodes: ", nodes_in, ", Output nodes: ", nodes_out); } else { ASSIMP_LOG_DEBUG("OptimizeGraphProcess finished"); } diff --git a/code/PostProcessing/OptimizeMeshes.cpp b/code/PostProcessing/OptimizeMeshes.cpp index dd81644de..939284ee4 100644 --- a/code/PostProcessing/OptimizeMeshes.cpp +++ b/code/PostProcessing/OptimizeMeshes.cpp @@ -151,7 +151,7 @@ void OptimizeMeshesProcess::Execute( aiScene* pScene) std::copy(output.begin(),output.end(),mScene->mMeshes); if (output.size() != num_old) { - ASSIMP_LOG_DEBUG_F("OptimizeMeshesProcess finished. Input meshes: ", num_old, ", Output meshes: ", pScene->mNumMeshes); + ASSIMP_LOG_DEBUG("OptimizeMeshesProcess finished. Input meshes: ", num_old, ", Output meshes: ", pScene->mNumMeshes); } else { ASSIMP_LOG_DEBUG( "OptimizeMeshesProcess finished" ); } diff --git a/code/PostProcessing/PretransformVertices.cpp b/code/PostProcessing/PretransformVertices.cpp index 2691ed488..e9a3af0d2 100644 --- a/code/PostProcessing/PretransformVertices.cpp +++ b/code/PostProcessing/PretransformVertices.cpp @@ -680,9 +680,9 @@ void PretransformVertices::Execute(aiScene *pScene) { if (!DefaultLogger::isNullLogger()) { ASSIMP_LOG_DEBUG("PretransformVerticesProcess finished"); - ASSIMP_LOG_INFO_F("Removed ", iOldNodes, " nodes and ", iOldAnimationChannels, " animation channels (", + ASSIMP_LOG_INFO("Removed ", iOldNodes, " nodes and ", iOldAnimationChannels, " animation channels (", CountNodes(pScene->mRootNode), " output nodes)"); - ASSIMP_LOG_INFO_F("Kept ", pScene->mNumLights, " lights and ", pScene->mNumCameras, " cameras."); - ASSIMP_LOG_INFO_F("Moved ", iOldMeshes, " meshes to WCS (number of output meshes: ", pScene->mNumMeshes, ")"); + ASSIMP_LOG_INFO("Kept ", pScene->mNumLights, " lights and ", pScene->mNumCameras, " cameras."); + ASSIMP_LOG_INFO("Moved ", iOldMeshes, " meshes to WCS (number of output meshes: ", pScene->mNumMeshes, ")"); } } diff --git a/code/PostProcessing/RemoveRedundantMaterials.cpp b/code/PostProcessing/RemoveRedundantMaterials.cpp index 5264d3608..c252f37a5 100644 --- a/code/PostProcessing/RemoveRedundantMaterials.cpp +++ b/code/PostProcessing/RemoveRedundantMaterials.cpp @@ -122,7 +122,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) // Keep this material even if no mesh references it abReferenced[i] = true; - ASSIMP_LOG_VERBOSE_DEBUG_F( "Found positive match in exclusion list: \'", name.data, "\'"); + ASSIMP_LOG_VERBOSE_DEBUG( "Found positive match in exclusion list: \'", name.data, "\'"); } } } @@ -215,7 +215,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) } else { - ASSIMP_LOG_INFO_F("RemoveRedundantMatsProcess finished. Removed ", redundantRemoved, " redundant and ", + ASSIMP_LOG_INFO("RemoveRedundantMatsProcess finished. Removed ", redundantRemoved, " redundant and ", unreferencedRemoved, " unused materials."); } } diff --git a/code/PostProcessing/SplitByBoneCountProcess.cpp b/code/PostProcessing/SplitByBoneCountProcess.cpp index f7dffb8f2..2613d8561 100644 --- a/code/PostProcessing/SplitByBoneCountProcess.cpp +++ b/code/PostProcessing/SplitByBoneCountProcess.cpp @@ -103,7 +103,7 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene) if( !isNecessary ) { - ASSIMP_LOG_DEBUG_F("SplitByBoneCountProcess early-out: no meshes with more than ", mMaxBoneCount, " bones." ); + ASSIMP_LOG_DEBUG("SplitByBoneCountProcess early-out: no meshes with more than ", mMaxBoneCount, " bones." ); return; } @@ -151,7 +151,7 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene) // recurse through all nodes and translate the node's mesh indices to fit the new mesh array UpdateNode( pScene->mRootNode); - ASSIMP_LOG_DEBUG_F( "SplitByBoneCountProcess end: split ", mSubMeshIndices.size(), " meshes into ", meshes.size(), " submeshes." ); + ASSIMP_LOG_DEBUG( "SplitByBoneCountProcess end: split ", mSubMeshIndices.size(), " meshes into ", meshes.size(), " submeshes." ); } // ------------------------------------------------------------------------------------------------ diff --git a/code/PostProcessing/TextureTransform.cpp b/code/PostProcessing/TextureTransform.cpp index a2f20a082..681b047c0 100644 --- a/code/PostProcessing/TextureTransform.cpp +++ b/code/PostProcessing/TextureTransform.cpp @@ -108,7 +108,7 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info) if (rounded) { out -= rounded * static_cast(AI_MATH_PI); - ASSIMP_LOG_INFO_F("Texture coordinate rotation ", info.mRotation, " can be simplified to ", out); + ASSIMP_LOG_INFO("Texture coordinate rotation ", info.mRotation, " can be simplified to ", out); } // Next step - convert negative rotation angles to positives @@ -448,7 +448,7 @@ void TextureTransformStep::Execute( aiScene* pScene) if (size > AI_MAX_NUMBER_OF_TEXTURECOORDS) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_ERROR_F(static_cast(trafo.size()), " UV channels required but just ", + ASSIMP_LOG_ERROR(static_cast(trafo.size()), " UV channels required but just ", AI_MAX_NUMBER_OF_TEXTURECOORDS, " available"); } size = AI_MAX_NUMBER_OF_TEXTURECOORDS; @@ -557,7 +557,7 @@ void TextureTransformStep::Execute( aiScene* pScene) if (!DefaultLogger::isNullLogger()) { if (transformedChannels) { - ASSIMP_LOG_INFO_F("TransformUVCoordsProcess end: ", outChannels, " output channels (in: ", inChannels, ", modified: ", transformedChannels,")"); + ASSIMP_LOG_INFO("TransformUVCoordsProcess end: ", outChannels, " output channels (in: ", inChannels, ", modified: ", transformedChannels,")"); } else { ASSIMP_LOG_DEBUG("TransformUVCoordsProcess finished"); } diff --git a/include/assimp/LineSplitter.h b/include/assimp/LineSplitter.h index 7cb71476c..44e6f0f1e 100644 --- a/include/assimp/LineSplitter.h +++ b/include/assimp/LineSplitter.h @@ -72,7 +72,7 @@ for(LineSplitter splitter(stream);splitter;++splitter) { if (strtol(splitter[2]) > 5) { .. } } - ASSIMP_LOG_VERBOSE_DEBUG_F("Current line is: ", splitter.get_index()); + ASSIMP_LOG_VERBOSE_DEBUG("Current line is: ", splitter.get_index()); } @endcode */ diff --git a/include/assimp/Logger.hpp b/include/assimp/Logger.hpp index 71f458731..ecbd9df9b 100644 --- a/include/assimp/Logger.hpp +++ b/include/assimp/Logger.hpp @@ -312,34 +312,19 @@ Logger::LogSeverity Logger::getLogSeverity() const { } // Namespace Assimp // ------------------------------------------------------------------------------------------------ -#define ASSIMP_LOG_WARN_F(...) \ +#define ASSIMP_LOG_WARN(...) \ Assimp::DefaultLogger::get()->warn(__VA_ARGS__) -#define ASSIMP_LOG_ERROR_F(...) \ +#define ASSIMP_LOG_ERROR(...) \ Assimp::DefaultLogger::get()->error(__VA_ARGS__) -#define ASSIMP_LOG_DEBUG_F(...) \ +#define ASSIMP_LOG_DEBUG(...) \ Assimp::DefaultLogger::get()->debug(__VA_ARGS__) -#define ASSIMP_LOG_VERBOSE_DEBUG_F(...) \ +#define ASSIMP_LOG_VERBOSE_DEBUG(...) \ Assimp::DefaultLogger::get()->verboseDebug(__VA_ARGS__) -#define ASSIMP_LOG_INFO_F(...) \ +#define ASSIMP_LOG_INFO(...) \ Assimp::DefaultLogger::get()->info(__VA_ARGS__) -#define ASSIMP_LOG_WARN(string) \ - Assimp::DefaultLogger::get()->warn(string) - -#define ASSIMP_LOG_ERROR(string) \ - Assimp::DefaultLogger::get()->error(string) - -#define ASSIMP_LOG_DEBUG(string) \ - Assimp::DefaultLogger::get()->debug(string) - -#define ASSIMP_LOG_VERBOSE_DEBUG(string) \ - Assimp::DefaultLogger::get()->verboseDebug(string) - -#define ASSIMP_LOG_INFO(string) \ - Assimp::DefaultLogger::get()->info(string) - #endif // !! INCLUDED_AI_LOGGER_H diff --git a/include/assimp/Profiler.h b/include/assimp/Profiler.h index 566ea84e1..2f2c72bf2 100644 --- a/include/assimp/Profiler.h +++ b/include/assimp/Profiler.h @@ -76,7 +76,7 @@ public: /** Start a named timer */ void BeginRegion(const std::string& region) { regions[region] = std::chrono::system_clock::now(); - ASSIMP_LOG_DEBUG_F("START `",region,"`"); + ASSIMP_LOG_DEBUG("START `",region,"`"); } @@ -88,7 +88,7 @@ public: } std::chrono::duration elapsedSeconds = std::chrono::system_clock::now() - regions[region]; - ASSIMP_LOG_DEBUG_F("END `",region,"`, dt= ", elapsedSeconds.count()," s"); + ASSIMP_LOG_DEBUG("END `",region,"`, dt= ", elapsedSeconds.count()," s"); } private: diff --git a/include/assimp/fast_atof.h b/include/assimp/fast_atof.h index 441fe5652..aea793f35 100644 --- a/include/assimp/fast_atof.h +++ b/include/assimp/fast_atof.h @@ -206,7 +206,7 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino // numeric overflow, we rely on you if ( new_value < value ) { - ASSIMP_LOG_WARN_F( "Converting the string \"", in, "\" into a value resulted in overflow." ); + ASSIMP_LOG_WARN( "Converting the string \"", in, "\" into a value resulted in overflow." ); return 0; } From 7abfd134b60eeed6d7f775eea2e6509051fdd079 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Thu, 13 May 2021 10:33:16 +0100 Subject: [PATCH 64/93] LogAux warn --- code/AssetLib/Blender/BlenderLoader.cpp | 4 ++-- code/AssetLib/FBX/FBXMeshGeometry.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/AssetLib/Blender/BlenderLoader.cpp b/code/AssetLib/Blender/BlenderLoader.cpp index 8cc0162f5..f38831567 100644 --- a/code/AssetLib/Blender/BlenderLoader.cpp +++ b/code/AssetLib/Blender/BlenderLoader.cpp @@ -516,7 +516,7 @@ void BlenderImporter::ResolveTexture(aiMaterial *out, const Material *mat, const case Tex::Type_POINTDENSITY: case Tex::Type_VOXELDATA: - LogWarn(std::string("Encountered a texture with an unsupported type: ") + dispnam); + LogWarn("Encountered a texture with an unsupported type: ", dispnam); AddSentinelTexture(out, mat, tex, conv_data); break; @@ -752,7 +752,7 @@ void BlenderImporter::CheckActualType(const ElemBase *dt, const char *check) { // ------------------------------------------------------------------------------------------------ void BlenderImporter::NotSupportedObjectType(const Object *obj, const char *type) { - LogWarn((format(), "Object `", obj->id.name, "` - type is unsupported: `", type, "`, skipping")); + LogWarn("Object `", obj->id.name, "` - type is unsupported: `", type, "`, skipping"); } // ------------------------------------------------------------------------------------------------ diff --git a/code/AssetLib/FBX/FBXMeshGeometry.cpp b/code/AssetLib/FBX/FBXMeshGeometry.cpp index 2bca8dff2..a88045210 100644 --- a/code/AssetLib/FBX/FBXMeshGeometry.cpp +++ b/code/AssetLib/FBX/FBXMeshGeometry.cpp @@ -509,8 +509,8 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName)); if (uvIndices.size() > vertex_count) { - FBXImporter::LogWarn(Formatter::format("trimming length of input array for ByPolygonVertex mapping: ") - << uvIndices.size() << ", expected " << vertex_count); + FBXImporter::LogWarn("trimming length of input array for ByPolygonVertex mapping: ", + uvIndices.size(), ", expected ", vertex_count); uvIndices.resize(vertex_count); } @@ -645,7 +645,7 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector& materials_out, cons FBXImporter::LogError(Formatter::format("expected material index, ignoring")); return; } else if (materials_out.size() > 1) { - FBXImporter::LogWarn(Formatter::format("expected only a single material index, ignoring all except the first one")); + FBXImporter::LogWarn("expected only a single material index, ignoring all except the first one"); materials_out.clear(); } From c5f22269a8ae5ea491f36d9fc5a92ddb495433bc Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Thu, 13 May 2021 10:33:25 +0100 Subject: [PATCH 65/93] LogAux --- include/assimp/LogAux.h | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/include/assimp/LogAux.h b/include/assimp/LogAux.h index b0a1f9ddd..6ca1912d3 100644 --- a/include/assimp/LogAux.h +++ b/include/assimp/LogAux.h @@ -64,13 +64,14 @@ public: template static void ThrowException(T&&... args) { - throw DeadlyImportError(Prefix(), args...); + throw DeadlyImportError(Prefix(), std::forward(args)...); } // ------------------------------------------------------------------------------------------------ - static void LogWarn(const Formatter::format& message) { + template + static void LogWarn(T&&... args) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_WARN(Prefix()+(std::string)message); + ASSIMP_LOG_WARN(Prefix(), std::forward(args)...); } } @@ -104,13 +105,6 @@ public: // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462 #if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) - // ------------------------------------------------------------------------------------------------ - static void LogWarn (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogWarn(Formatter::format(message)); - } - } - // ------------------------------------------------------------------------------------------------ static void LogError (const char* message) { if (!DefaultLogger::isNullLogger()) { From ad6f300b1dbfefdd67097b0ed8ba8eeab1725a1e Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Thu, 13 May 2021 10:43:28 +0100 Subject: [PATCH 66/93] Other LogAux functions --- code/AssetLib/Blender/BlenderLoader.cpp | 6 +-- code/AssetLib/FBX/FBXMeshGeometry.cpp | 42 ++++++++++---------- code/AssetLib/IFC/IFCLoader.cpp | 6 +-- include/assimp/LogAux.h | 51 ++++++------------------- 4 files changed, 39 insertions(+), 66 deletions(-) diff --git a/code/AssetLib/Blender/BlenderLoader.cpp b/code/AssetLib/Blender/BlenderLoader.cpp index f38831567..7cf4e070e 100644 --- a/code/AssetLib/Blender/BlenderLoader.cpp +++ b/code/AssetLib/Blender/BlenderLoader.cpp @@ -235,9 +235,9 @@ void BlenderImporter::InternReadFile(const std::string &pFile, stream->Read(magic, 3, 1); magic[3] = '\0'; - LogInfo((format(), "Blender version is ", magic[0], ".", magic + 1, + LogInfo("Blender version is ", magic[0], ".", magic + 1, " (64bit: ", file.i64bit ? "true" : "false", - ", little endian: ", file.little ? "true" : "false", ")")); + ", little endian: ", file.little ? "true" : "false", ")"); ParseBlendFile(file, stream); @@ -434,7 +434,7 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M curTex->pcData = reinterpret_cast(ch); - LogInfo("Reading embedded texture, original file was " + std::string(img->name)); + LogInfo("Reading embedded texture, original file was ", img->name); } else { name = aiString(img->name); } diff --git a/code/AssetLib/FBX/FBXMeshGeometry.cpp b/code/AssetLib/FBX/FBXMeshGeometry.cpp index a88045210..9bafcbd2a 100644 --- a/code/AssetLib/FBX/FBXMeshGeometry.cpp +++ b/code/AssetLib/FBX/FBXMeshGeometry.cpp @@ -307,8 +307,8 @@ void MeshGeometry::ReadLayerElement(const Scope& layerElement) } } - FBXImporter::LogError(Formatter::format("failed to resolve vertex layer element: ") - << type << ", index: " << typedIndex); + FBXImporter::LogError("failed to resolve vertex layer element: ", + type, ", index: ", typedIndex); } // ------------------------------------------------------------------------------------------------ @@ -324,8 +324,8 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop if (type == "LayerElementUV") { if(index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { - FBXImporter::LogError(Formatter::format("ignoring UV layer, maximum number of UV channels exceeded: ") - << index << " (limit is " << AI_MAX_NUMBER_OF_TEXTURECOORDS << ")" ); + FBXImporter::LogError("ignoring UV layer, maximum number of UV channels exceeded: ", + index, " (limit is ", AI_MAX_NUMBER_OF_TEXTURECOORDS, ")" ); return; } @@ -402,8 +402,8 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop } else if (type == "LayerElementColor") { if(index >= AI_MAX_NUMBER_OF_COLOR_SETS) { - FBXImporter::LogError(Formatter::format("ignoring vertex color layer, maximum number of color sets exceeded: ") - << index << " (limit is " << AI_MAX_NUMBER_OF_COLOR_SETS << ")" ); + FBXImporter::LogError("ignoring vertex color layer, maximum number of color sets exceeded: ", + index, " (limit is ", AI_MAX_NUMBER_OF_COLOR_SETS, ")" ); return; } @@ -449,8 +449,8 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); if (tempData.size() != mapping_offsets.size()) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByVertice mapping: ") - << tempData.size() << ", expected " << mapping_offsets.size()); + FBXImporter::LogError("length of input data unexpected for ByVertice mapping: ", + tempData.size(), ", expected ", mapping_offsets.size()); return; } @@ -470,8 +470,8 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName)); if (uvIndices.size() != vertex_count) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByVertice mapping: ") - << uvIndices.size() << ", expected " << vertex_count); + FBXImporter::LogError("length of input data unexpected for ByVertice mapping: ", + uvIndices.size(), ", expected ", vertex_count); return; } @@ -493,8 +493,8 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); if (tempData.size() != vertex_count) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") - << tempData.size() << ", expected " << vertex_count + FBXImporter::LogError("length of input data unexpected for ByPolygon mapping: ", + tempData.size(), ", expected ", vertex_count ); return; } @@ -515,8 +515,8 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, } if (uvIndices.size() != vertex_count) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygonVertex mapping: ") - << uvIndices.size() << ", expected " << vertex_count); + FBXImporter::LogError("length of input data unexpected for ByPolygonVertex mapping: ", + uvIndices.size(), ", expected ", vertex_count); return; } @@ -537,8 +537,8 @@ void ResolveVertexDataArray(std::vector& data_out, const Scope& source, } } else { - FBXImporter::LogError(Formatter::format("ignoring vertex data channel, access type not implemented: ") - << MappingInformationType << "," << ReferenceInformationType); + FBXImporter::LogError("ignoring vertex data channel, access type not implemented: ", + MappingInformationType, ",", ReferenceInformationType); } } @@ -642,7 +642,7 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector& materials_out, cons if (MappingInformationType == "AllSame") { // easy - same material for all faces if (materials_out.empty()) { - FBXImporter::LogError(Formatter::format("expected material index, ignoring")); + FBXImporter::LogError("expected material index, ignoring"); return; } else if (materials_out.size() > 1) { FBXImporter::LogWarn("expected only a single material index, ignoring all except the first one"); @@ -655,14 +655,14 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector& materials_out, cons materials_out.resize(face_count); if(materials_out.size() != face_count) { - FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") - << materials_out.size() << ", expected " << face_count + FBXImporter::LogError("length of input data unexpected for ByPolygon mapping: ", + materials_out.size(), ", expected ", face_count ); return; } } else { - FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ") - << MappingInformationType << "," << ReferenceInformationType); + FBXImporter::LogError("ignoring material assignments, access type not implemented: ", + MappingInformationType, ",", ReferenceInformationType); } } // ------------------------------------------------------------------------------------------------ diff --git a/code/AssetLib/IFC/IFCLoader.cpp b/code/AssetLib/IFC/IFCLoader.cpp index bdac1801a..46b36bd51 100644 --- a/code/AssetLib/IFC/IFCLoader.cpp +++ b/code/AssetLib/IFC/IFCLoader.cpp @@ -315,7 +315,7 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // this must be last because objects are evaluated lazily as we process them if (!DefaultLogger::isNullLogger()) { - LogDebug((Formatter::format(), "STEP: evaluated ", db->GetEvaluatedObjectCount(), " object records")); + LogDebug("STEP: evaluated ", db->GetEvaluatedObjectCount(), " object records"); } } @@ -438,7 +438,7 @@ bool ProcessMappedItem(const Schema_2x3::IfcMappedItem &mapped, aiNode *nd_src, bool got = false; for (const Schema_2x3::IfcRepresentationItem &item : repr.Items) { if (!ProcessRepresentationItem(item, localmatid, meshes, conv)) { - IFCImporter::LogWarn("skipping mapped entity of type " + item.GetClassName() + ", no representations could be generated"); + IFCImporter::LogWarn("skipping mapped entity of type ", item.GetClassName(), ", no representations could be generated"); } else got = true; } @@ -856,7 +856,7 @@ void ProcessSpatialStructures(ConversionData &conv) { if (!prod) { continue; } - IFCImporter::LogVerboseDebug("looking at spatial structure `" + (prod->Name ? prod->Name.Get() : "unnamed") + "`" + (prod->ObjectType ? " which is of type " + prod->ObjectType.Get() : "")); + IFCImporter::LogVerboseDebug("looking at spatial structure `", (prod->Name ? prod->Name.Get() : "unnamed"), "`", (prod->ObjectType ? " which is of type " + prod->ObjectType.Get() : "")); // the primary sites are referenced by an IFCRELAGGREGATES element which assigns them to the IFCPRODUCT const STEP::DB::RefMap &refs = conv.db.GetRefs(); diff --git a/include/assimp/LogAux.h b/include/assimp/LogAux.h index 6ca1912d3..065433648 100644 --- a/include/assimp/LogAux.h +++ b/include/assimp/LogAux.h @@ -76,64 +76,37 @@ public: } // ------------------------------------------------------------------------------------------------ - static void LogError(const Formatter::format& message) { + template + static void LogError(T&&... args) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_ERROR(Prefix()+(std::string)message); + ASSIMP_LOG_ERROR(Prefix(), std::forward(args)...); } } // ------------------------------------------------------------------------------------------------ - static void LogInfo(const Formatter::format& message) { + template + static void LogInfo(T&&... args) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_INFO(Prefix()+(std::string)message); + ASSIMP_LOG_INFO(Prefix(), std::forward(args)...); } } // ------------------------------------------------------------------------------------------------ - static void LogDebug(const Formatter::format& message) { + template + static void LogDebug(T&&... args) { if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_DEBUG(Prefix()+(std::string)message); - } - } - - static void LogVerboseDebug(const Formatter::format& message) { - if (!DefaultLogger::isNullLogger()) { - ASSIMP_LOG_VERBOSE_DEBUG(Prefix()+(std::string)message); - } - } - - // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462 -#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) - - // ------------------------------------------------------------------------------------------------ - static void LogError (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogError(Formatter::format(message)); + ASSIMP_LOG_DEBUG(Prefix(), std::forward(args)...); } } // ------------------------------------------------------------------------------------------------ - static void LogInfo (const char* message) { + template + static void LogVerboseDebug(T&&... args) { if (!DefaultLogger::isNullLogger()) { - LogInfo(Formatter::format(message)); + ASSIMP_LOG_VERBOSE_DEBUG(Prefix(), std::forward(args)...); } } - // ------------------------------------------------------------------------------------------------ - static void LogDebug (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogDebug(Formatter::format(message)); - } - } - - // ------------------------------------------------------------------------------------------------ - static void LogVerboseDebug (const char* message) { - if (!DefaultLogger::isNullLogger()) { - LogVerboseDebug(Formatter::format(message)); - } - } -#endif - private: static const char* Prefix(); From 4ec01cfdcdb6f0e917e98e09c64e721d26eebc89 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Thu, 13 May 2021 12:05:31 +0100 Subject: [PATCH 67/93] Improve use of logging --- code/AssetLib/3DS/3DSExporter.cpp | 2 +- code/AssetLib/ASE/ASEParser.cpp | 2 +- code/AssetLib/C4D/C4DImporter.cpp | 6 +-- code/AssetLib/FBX/FBXConverter.cpp | 40 +++++++++---------- code/AssetLib/FBX/FBXDocumentUtil.cpp | 2 +- code/AssetLib/IFC/IFCBoolean.cpp | 4 +- code/AssetLib/IFC/IFCGeometry.cpp | 6 +-- code/AssetLib/IFC/IFCLoader.cpp | 8 ++-- code/AssetLib/IFC/IFCMaterial.cpp | 4 +- code/AssetLib/IFC/IFCProfile.cpp | 8 ++-- code/AssetLib/IFC/IFCUtil.cpp | 2 +- code/AssetLib/Irr/IRRLoader.cpp | 8 ++-- code/AssetLib/Irr/IRRShared.cpp | 2 +- code/AssetLib/LWO/LWOLoader.cpp | 6 +-- code/AssetLib/LWO/LWOMaterial.cpp | 2 +- code/AssetLib/LWS/LWSLoader.cpp | 4 +- code/AssetLib/M3D/M3DImporter.cpp | 2 +- code/AssetLib/MD3/MD3Loader.cpp | 8 ++-- code/AssetLib/MD5/MD5Loader.cpp | 4 +- code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp | 2 +- code/AssetLib/NFF/NFFLoader.cpp | 2 +- code/AssetLib/Obj/ObjFileParser.cpp | 10 ++--- code/AssetLib/Ogre/OgreBinarySerializer.cpp | 2 +- code/AssetLib/Ogre/OgreMaterial.cpp | 2 +- code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp | 2 +- code/AssetLib/glTF2/glTF2Importer.cpp | 8 ++-- code/Common/FileSystemFilter.h | 2 +- code/Common/Importer.cpp | 2 +- code/Material/MaterialSystem.cpp | 7 ++-- code/PostProcessing/ValidateDataStructure.cpp | 2 +- 30 files changed, 80 insertions(+), 81 deletions(-) diff --git a/code/AssetLib/3DS/3DSExporter.cpp b/code/AssetLib/3DS/3DSExporter.cpp index 07e9ccfc7..92a6d5aa7 100644 --- a/code/AssetLib/3DS/3DSExporter.cpp +++ b/code/AssetLib/3DS/3DSExporter.cpp @@ -379,7 +379,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type // TODO: handle embedded textures properly if (path.data[0] == '*') { - ASSIMP_LOG_ERROR("Ignoring embedded texture for export: " + std::string(path.C_Str())); + ASSIMP_LOG_ERROR("Ignoring embedded texture for export: ", path.C_Str()); return; } diff --git a/code/AssetLib/ASE/ASEParser.cpp b/code/AssetLib/ASE/ASEParser.cpp index 4e4af8ed8..1f7018b11 100644 --- a/code/AssetLib/ASE/ASEParser.cpp +++ b/code/AssetLib/ASE/ASEParser.cpp @@ -1125,7 +1125,7 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode &mesh) { "this is no spot light or target camera"); } } else { - ASSIMP_LOG_ERROR("ASE: Unknown node transformation: " + temp); + ASSIMP_LOG_ERROR("ASE: Unknown node transformation: ", temp); // mode = 0 } continue; diff --git a/code/AssetLib/C4D/C4DImporter.cpp b/code/AssetLib/C4D/C4DImporter.cpp index 594bcfddd..434d1429e 100644 --- a/code/AssetLib/C4D/C4DImporter.cpp +++ b/code/AssetLib/C4D/C4DImporter.cpp @@ -238,7 +238,7 @@ bool C4DImporter::ReadShader(aiMaterial* out, BaseShader* shader) { out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0)); return true; } else { - LogWarn("ignoring shader type: " + std::string(GetObjectTypeName(shader->GetType()))); + LogWarn("ignoring shader type: ", GetObjectTypeName(shader->GetType())); } shader = shader->GetNext(); } @@ -281,7 +281,7 @@ void C4DImporter::ReadMaterials(BaseMaterial* mat) { ReadShader(out, shader); } } else { - LogWarn("ignoring plugin material: " + std::string(GetObjectTypeName(mat->GetType()))); + LogWarn("ignoring plugin material: ", GetObjectTypeName(mat->GetType())); } mat = mat->GetNext(); } @@ -335,7 +335,7 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) { meshes.push_back(mesh); } } else { - LogWarn("ignoring object: " + std::string(GetObjectTypeName(type))); + LogWarn("ignoring object: ", GetObjectTypeName(type)); } RecurseHierarchy(object->GetDown(), nd); diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index 88d7ad626..8d37d3790 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -811,7 +811,7 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std // we need to generate a full node chain to accommodate for assimp's // lack to express pivots and offsets. if ((chainBits & chainMaskComplex) && doc.Settings().preservePivots) { - FBXImporter::LogInfo("generating full transformation chain for node: " + name); + FBXImporter::LogInfo("generating full transformation chain for node: ", name); // query the anim_chain_bits dictionary to find out which chain elements // have associated node animation channels. These can not be dropped @@ -918,7 +918,7 @@ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root const std::vector &indices = ConvertLine(*line, root_node); std::copy(indices.begin(), indices.end(), std::back_inserter(meshes)); } else { - FBXImporter::LogWarn("ignoring unrecognized geometry: " + geo->Name()); + FBXImporter::LogWarn("ignoring unrecognized geometry: ", geo->Name()); } } @@ -944,7 +944,7 @@ FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode * const std::vector &vertices = mesh.GetVertices(); const std::vector &faces = mesh.GetFaceIndexCounts(); if (vertices.empty() || faces.empty()) { - FBXImporter::LogWarn("ignoring empty geometry: " + mesh.Name()); + FBXImporter::LogWarn("ignoring empty geometry: ", mesh.Name()); return temp; } @@ -971,7 +971,7 @@ std::vector FBXConverter::ConvertLine(const LineGeometry &line, ai const std::vector &vertices = line.GetVertices(); const std::vector &indices = line.GetIndices(); if (vertices.empty() || indices.empty()) { - FBXImporter::LogWarn("ignoring empty line: " + line.Name()); + FBXImporter::LogWarn("ignoring empty line: ", line.Name()); return temp; } @@ -1815,14 +1815,14 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); continue; } if (uvIndex == -1) { uvIndex = index; } else { - FBXImporter::LogWarn("the UV channel named " + uvSet + + FBXImporter::LogWarn("the UV channel named ", uvSet, " appears at different positions in meshes, results will be wrong"); } } @@ -1839,7 +1839,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); } if (uvIndex == -1) { @@ -1848,7 +1848,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap } if (uvIndex == -1) { - FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel"); + FBXImporter::LogWarn("failed to resolve UV channel ", uvSet, ", using first UV channel"); uvIndex = 0; } } @@ -1934,14 +1934,14 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); continue; } if (uvIndex == -1) { uvIndex = index; } else { - FBXImporter::LogWarn("the UV channel named " + uvSet + + FBXImporter::LogWarn("the UV channel named ", uvSet, " appears at different positions in meshes, results will be wrong"); } } @@ -1958,7 +1958,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); } if (uvIndex == -1) { @@ -1967,7 +1967,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex } if (uvIndex == -1) { - FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel"); + FBXImporter::LogWarn("failed to resolve UV channel ", uvSet, ", using first UV channel"); uvIndex = 0; } } @@ -2319,14 +2319,14 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); continue; } if (uvIndex == -1) { uvIndex = index; } else { - FBXImporter::LogWarn("the UV channel named " + uvSet + " appears at different positions in meshes, results will be wrong"); + FBXImporter::LogWarn("the UV channel named ", uvSet, " appears at different positions in meshes, results will be wrong"); } } } else { @@ -2342,7 +2342,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa } } if (index == -1) { - FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material"); } if (uvIndex == -1) { @@ -2351,7 +2351,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa } if (uvIndex == -1) { - FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel"); + FBXImporter::LogWarn("failed to resolve UV channel ", uvSet, ", using first UV channel"); uvIndex = 0; } } @@ -2574,7 +2574,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) { // empty animations would fail validation, so drop them delete anim; animations.pop_back(); - FBXImporter::LogInfo("ignoring empty AnimationStack (using IK?): " + name); + FBXImporter::LogInfo("ignoring empty AnimationStack (using IK?): ", name); return; } @@ -2707,13 +2707,13 @@ void FBXConverter::GenerateNodeAnimations(std::vector &node_anims, ai_assert(node); if (node->TargetProperty().empty()) { - FBXImporter::LogWarn("target property for animation curve not set: " + node->Name()); + FBXImporter::LogWarn("target property for animation curve not set: ", node->Name()); continue; } curve_node = node; if (node->Curves().empty()) { - FBXImporter::LogWarn("no animation curves assigned to AnimationCurveNode: " + node->Name()); + FBXImporter::LogWarn("no animation curves assigned to AnimationCurveNode: ", node->Name()); continue; } @@ -2748,7 +2748,7 @@ void FBXConverter::GenerateNodeAnimations(std::vector &node_anims, if (doc.Settings().optimizeEmptyAnimationCurves && IsRedundantAnimationData(target, comp, (chain[i]->second))) { - FBXImporter::LogVerboseDebug("dropping redundant animation channel for node " + target.Name()); + FBXImporter::LogVerboseDebug("dropping redundant animation channel for node ", target.Name()); continue; } diff --git a/code/AssetLib/FBX/FBXDocumentUtil.cpp b/code/AssetLib/FBX/FBXDocumentUtil.cpp index 77455198f..ab15298a8 100644 --- a/code/AssetLib/FBX/FBXDocumentUtil.cpp +++ b/code/AssetLib/FBX/FBXDocumentUtil.cpp @@ -91,7 +91,7 @@ void DOMWarning(const std::string& message, const Element* element /*= nullptr*/ return; } if(DefaultLogger::get()) { - ASSIMP_LOG_WARN("FBX-DOM: " + message); + ASSIMP_LOG_WARN("FBX-DOM: ", message); } } diff --git a/code/AssetLib/IFC/IFCBoolean.cpp b/code/AssetLib/IFC/IFCBoolean.cpp index 6015920c1..86cac7f46 100644 --- a/code/AssetLib/IFC/IFCBoolean.cpp +++ b/code/AssetLib/IFC/IFCBoolean.cpp @@ -715,7 +715,7 @@ void ProcessBoolean(const Schema_2x3::IfcBooleanResult &boolean, TempMesh &resul // DIFFERENCE if (const Schema_2x3::IfcBooleanResult *const clip = boolean.ToPtr()) { if (clip->Operator != "DIFFERENCE") { - IFCImporter::LogWarn("encountered unsupported boolean operator: " + (std::string)clip->Operator); + IFCImporter::LogWarn("encountered unsupported boolean operator: ", (std::string)clip->Operator); return; } @@ -756,7 +756,7 @@ void ProcessBoolean(const Schema_2x3::IfcBooleanResult &boolean, TempMesh &resul ProcessBooleanExtrudedAreaSolidDifference(as, result, first_operand, conv); } } else { - IFCImporter::LogWarn("skipping unknown IfcBooleanResult entity, type is " + boolean.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcBooleanResult entity, type is ", boolean.GetClassName()); } } diff --git a/code/AssetLib/IFC/IFCGeometry.cpp b/code/AssetLib/IFC/IFCGeometry.cpp index 664444443..6e645f1ae 100644 --- a/code/AssetLib/IFC/IFCGeometry.cpp +++ b/code/AssetLib/IFC/IFCGeometry.cpp @@ -216,7 +216,7 @@ void ProcessConnectedFaceSet(const Schema_2x3::IfcConnectedFaceSet& fset, TempMe } } else { - IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is " + bound.Bound->GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is ", bound.Bound->GetClassName()); continue; } @@ -729,7 +729,7 @@ void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept, TempMesh& ProcessRevolvedAreaSolid(*rev,meshout,conv); } else { - IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is " + swept.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is ", swept.GetClassName()); } } @@ -781,7 +781,7 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned return false; } else { - IFCImporter::LogWarn("skipping unknown IfcGeometricRepresentationItem entity, type is " + geo.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcGeometricRepresentationItem entity, type is ", geo.GetClassName()); return false; } diff --git a/code/AssetLib/IFC/IFCLoader.cpp b/code/AssetLib/IFC/IFCLoader.cpp index 46b36bd51..daf2cc946 100644 --- a/code/AssetLib/IFC/IFCLoader.cpp +++ b/code/AssetLib/IFC/IFCLoader.cpp @@ -243,12 +243,12 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy } if (!DefaultLogger::isNullLogger()) { - LogDebug("File schema is \'" + head.fileSchema + '\''); + LogDebug("File schema is \'", head.fileSchema, '\''); if (head.timestamp.length()) { - LogDebug("Timestamp \'" + head.timestamp + '\''); + LogDebug("Timestamp \'", head.timestamp, '\''); } if (head.app.length()) { - LogDebug("Application/Exporter identline is \'" + head.app + '\''); + LogDebug("Application/Exporter identline is \'", head.app, '\''); } } @@ -403,7 +403,7 @@ void ResolveObjectPlacement(aiMatrix4x4 &m, const Schema_2x3::IfcObjectPlacement m = tmpM * m; } } else { - IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is " + place.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is ", place.GetClassName()); } } diff --git a/code/AssetLib/IFC/IFCMaterial.cpp b/code/AssetLib/IFC/IFCMaterial.cpp index e0146b887..2a79f0754 100644 --- a/code/AssetLib/IFC/IFCMaterial.cpp +++ b/code/AssetLib/IFC/IFCMaterial.cpp @@ -64,7 +64,7 @@ static int ConvertShadingMode(const std::string& name) { else if (name == "PHONG") { return aiShadingMode_Phong; } - IFCImporter::LogWarn("shading mode "+name+" not recognized by Assimp, using Phong instead"); + IFCImporter::LogWarn("shading mode ", name, " not recognized by Assimp, using Phong instead"); return aiShadingMode_Phong; } @@ -145,7 +145,7 @@ unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionDat // not found, create new material const std::string side = static_cast(surf->Side); if( side != "BOTH" ) { - IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: " + side); + IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: ", side); } std::unique_ptr mat(new aiMaterial()); diff --git a/code/AssetLib/IFC/IFCProfile.cpp b/code/AssetLib/IFC/IFCProfile.cpp index f33f8cdbe..4235be181 100644 --- a/code/AssetLib/IFC/IFCProfile.cpp +++ b/code/AssetLib/IFC/IFCProfile.cpp @@ -68,7 +68,7 @@ bool ProcessCurve(const Schema_2x3::IfcCurve& curve, TempMesh& meshout, Convers { std::unique_ptr cv(Curve::Convert(curve,conv)); if (!cv) { - IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is " + curve.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is ", curve.GetClassName()); return false; } @@ -78,7 +78,7 @@ bool ProcessCurve(const Schema_2x3::IfcCurve& curve, TempMesh& meshout, Convers bc->SampleDiscrete(meshout); } catch(const CurveError& cv) { - IFCImporter::LogError(cv.mStr + " (error occurred while processing curve)"); + IFCImporter::LogError(cv.mStr, " (error occurred while processing curve)"); return false; } meshout.mVertcnt.push_back(static_cast(meshout.mVerts.size())); @@ -152,7 +152,7 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de meshout.mVertcnt.push_back(12); } else { - IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is " + def.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is ", def.GetClassName()); return; } @@ -174,7 +174,7 @@ bool ProcessProfile(const Schema_2x3::IfcProfileDef& prof, TempMesh& meshout, Co ProcessParametrizedProfile(*cparam,meshout,conv); } else { - IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is " + prof.GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is ", prof.GetClassName()); return false; } meshout.RemoveAdjacentDuplicates(); diff --git a/code/AssetLib/IFC/IFCUtil.cpp b/code/AssetLib/IFC/IFCUtil.cpp index b451262e9..8c37cebed 100644 --- a/code/AssetLib/IFC/IFCUtil.cpp +++ b/code/AssetLib/IFC/IFCUtil.cpp @@ -506,7 +506,7 @@ IfcFloat ConvertSIPrefix(const std::string& prefix) return 1e-18f; } else { - IFCImporter::LogError("Unrecognized SI prefix: " + prefix); + IFCImporter::LogError("Unrecognized SI prefix: ", prefix); return 1; } } diff --git a/code/AssetLib/Irr/IRRLoader.cpp b/code/AssetLib/Irr/IRRLoader.cpp index 9ec0a9244..cb383e936 100644 --- a/code/AssetLib/Irr/IRRLoader.cpp +++ b/code/AssetLib/Irr/IRRLoader.cpp @@ -639,7 +639,7 @@ void IRRImporter::GenerateGraph(Node *root, aiNode *rootOut, aiScene *scene, // graph we're currently building aiScene *localScene = batch.GetImport(root->id); if (!localScene) { - ASSIMP_LOG_ERROR("IRR: Unable to load external file: " + root->meshPath); + ASSIMP_LOG_ERROR("IRR: Unable to load external file: ", root->meshPath); break; } attach.push_back(AttachmentInfo(localScene, rootOut)); @@ -963,7 +963,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy ASSIMP_LOG_ERROR("IRR: Billboards are not supported by Assimp"); nd = new Node(Node::DUMMY); } else { - ASSIMP_LOG_WARN("IRR: Found unknown node: " + std::string(attrib.name())); + ASSIMP_LOG_WARN("IRR: Found unknown node: ", attrib.name()); /* We skip the contents of nodes we don't know. * We parse the transformation and all animators @@ -1181,7 +1181,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy lights.pop_back(); curNode->type = Node::DUMMY; - ASSIMP_LOG_ERROR("Ignoring light of unknown type: " + prop.value); + ASSIMP_LOG_ERROR("Ignoring light of unknown type: ", prop.value); } } else if ((prop.name == "Mesh" && Node::MESH == curNode->type) || Node::ANIMMESH == curNode->type) { @@ -1225,7 +1225,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy } else if (prop.value == "followSpline") { curAnim->type = Animator::FOLLOW_SPLINE; } else { - ASSIMP_LOG_WARN("IRR: Ignoring unknown animator: " + prop.value); + ASSIMP_LOG_WARN("IRR: Ignoring unknown animator: ", prop.value); curAnim->type = Animator::UNKNOWN; } diff --git a/code/AssetLib/Irr/IRRShared.cpp b/code/AssetLib/Irr/IRRShared.cpp index b119b063a..b42f34b65 100644 --- a/code/AssetLib/Irr/IRRShared.cpp +++ b/code/AssetLib/Irr/IRRShared.cpp @@ -260,7 +260,7 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) { prop.value == "parallaxmap_trans_add") { matFlags = AI_IRRMESH_MAT_normalmap_ta; } else { - ASSIMP_LOG_WARN("IRRMat: Unrecognized material type: " + prop.value); + ASSIMP_LOG_WARN("IRRMat: Unrecognized material type: ", prop.value); } } diff --git a/code/AssetLib/LWO/LWOLoader.cpp b/code/AssetLib/LWO/LWOLoader.cpp index 7a2916424..bc62152c5 100644 --- a/code/AssetLib/LWO/LWOLoader.cpp +++ b/code/AssetLib/LWO/LWOLoader.cpp @@ -961,7 +961,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { switch (type) { case AI_LWO_TXUV: if (dims != 2) { - ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'" + name + "\' with !2 components"); + ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'", name, "\' with !2 components"); return; } base = FindEntry(mCurLayer->mUVChannels, name, perPoly); @@ -969,7 +969,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { case AI_LWO_WGHT: case AI_LWO_MNVW: if (dims != 1) { - ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'" + name + "\' with !1 components"); + ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'", name, "\' with !1 components"); return; } base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels : mCurLayer->mSWeightChannels), name, perPoly); @@ -977,7 +977,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) { case AI_LWO_RGB: case AI_LWO_RGBA: if (dims != 3 && dims != 4) { - ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'" + name + "\' with a dimension > 4 or < 3"); + ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'", name, "\' with a dimension > 4 or < 3"); return; } base = FindEntry(mCurLayer->mVColorChannels, name, perPoly); diff --git a/code/AssetLib/LWO/LWOMaterial.cpp b/code/AssetLib/LWO/LWOMaterial.cpp index 186aa8a42..178f24265 100644 --- a/code/AssetLib/LWO/LWOMaterial.cpp +++ b/code/AssetLib/LWO/LWOMaterial.cpp @@ -711,7 +711,7 @@ void LWOImporter::LoadLWO2Surface(unsigned int size) { } } if (derived.size()) { - ASSIMP_LOG_WARN("LWO2: Unable to find source surface: " + derived); + ASSIMP_LOG_WARN("LWO2: Unable to find source surface: ", derived); } } diff --git a/code/AssetLib/LWS/LWSLoader.cpp b/code/AssetLib/LWS/LWSLoader.cpp index a75b90ef9..d469a1064 100644 --- a/code/AssetLib/LWS/LWSLoader.cpp +++ b/code/AssetLib/LWS/LWSLoader.cpp @@ -346,7 +346,7 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vectormRootNode->mNumChildren == 1) { @@ -538,7 +538,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // get file format version and print to log ++it; unsigned int version = strtoul10((*it).tokens[0].c_str()); - ASSIMP_LOG_INFO("LWS file format version is " + (*it).tokens[0]); + ASSIMP_LOG_INFO("LWS file format version is ", (*it).tokens[0]); first = 0.; last = 60.; fps = 25.; // seems to be a good default frame rate diff --git a/code/AssetLib/M3D/M3DImporter.cpp b/code/AssetLib/M3D/M3DImporter.cpp index 5485b1bff..380e92c4f 100644 --- a/code/AssetLib/M3D/M3DImporter.cpp +++ b/code/AssetLib/M3D/M3DImporter.cpp @@ -209,7 +209,7 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys pScene->mRootNode->mNumChildren = 0; mScene = pScene; - ASSIMP_LOG_DEBUG("M3D: root node " + m3d.Name()); + ASSIMP_LOG_DEBUG("M3D: root node ", m3d.Name()); // now we just have to fill up the Assimp structures in pScene importMaterials(m3d); diff --git a/code/AssetLib/MD3/MD3Loader.cpp b/code/AssetLib/MD3/MD3Loader.cpp index 18c3d4228..a3d36f00d 100644 --- a/code/AssetLib/MD3/MD3Loader.cpp +++ b/code/AssetLib/MD3/MD3Loader.cpp @@ -101,7 +101,7 @@ Q3Shader::BlendFunc StringToBlendFunc(const std::string &m) { if (m == "GL_ONE_MINUS_DST_COLOR") { return Q3Shader::BLEND_GL_ONE_MINUS_DST_COLOR; } - ASSIMP_LOG_ERROR("Q3Shader: Unknown blend function: " + m); + ASSIMP_LOG_ERROR("Q3Shader: Unknown blend function: ", m); return Q3Shader::BLEND_NONE; } @@ -226,7 +226,7 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io) if (!file.get()) return false; // if we can't access the file, don't worry and return - ASSIMP_LOG_INFO("Loading Quake3 skin file " + pFile); + ASSIMP_LOG_INFO("Loading Quake3 skin file ", pFile); // read file in memory const size_t s = file->FileSize(); @@ -880,9 +880,9 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy if (dit != shaders.blocks.end()) { // We made it! shader = &*dit; - ASSIMP_LOG_INFO("Found shader record for " + without_ext); + ASSIMP_LOG_INFO("Found shader record for ", without_ext); } else { - ASSIMP_LOG_WARN("Unable to find shader record for " + without_ext); + ASSIMP_LOG_WARN("Unable to find shader record for ", without_ext); } } diff --git a/code/AssetLib/MD5/MD5Loader.cpp b/code/AssetLib/MD5/MD5Loader.cpp index b99638cd2..0d9c77b71 100644 --- a/code/AssetLib/MD5/MD5Loader.cpp +++ b/code/AssetLib/MD5/MD5Loader.cpp @@ -345,7 +345,7 @@ void MD5Importer::LoadMD5MeshFile() { // Check whether we can read from the file if (file.get() == nullptr || !file->FileSize()) { - ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + filename); + ASSIMP_LOG_WARN("Failed to access MD5MESH file: ", filename); return; } mHadMD5Mesh = true; @@ -567,7 +567,7 @@ void MD5Importer::LoadMD5AnimFile() { // Check whether we can read from the file if (!file.get() || !file->FileSize()) { - ASSIMP_LOG_WARN("Failed to read MD5ANIM file: " + pFile); + ASSIMP_LOG_WARN("Failed to read MD5ANIM file: ", pFile); return; } diff --git a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp b/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp index 2d2fd7427..e6576b344 100644 --- a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp @@ -1343,7 +1343,7 @@ bool HL1MDLLoader::get_num_blend_controllers(const int num_blend_animations, int return true; default: num_blend_controllers = 0; - ASSIMP_LOG_WARN(MDL_HALFLIFE_LOG_HEADER "Unsupported number of blend animations (" + std::to_string(num_blend_animations) + ")"); + ASSIMP_LOG_WARN(MDL_HALFLIFE_LOG_HEADER "Unsupported number of blend animations (", num_blend_animations, ")"); return false; } } diff --git a/code/AssetLib/NFF/NFFLoader.cpp b/code/AssetLib/NFF/NFFLoader.cpp index 65f2dc069..15f46b5e6 100644 --- a/code/AssetLib/NFF/NFFLoader.cpp +++ b/code/AssetLib/NFF/NFFLoader.cpp @@ -132,7 +132,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector &output, // Check whether we can read from the file if (!file.get()) { - ASSIMP_LOG_ERROR("NFF2: Unable to open material library " + path + "."); + ASSIMP_LOG_ERROR("NFF2: Unable to open material library ", path, "."); return; } diff --git a/code/AssetLib/Obj/ObjFileParser.cpp b/code/AssetLib/Obj/ObjFileParser.cpp index a8039ae23..767805c10 100644 --- a/code/AssetLib/Obj/ObjFileParser.cpp +++ b/code/AssetLib/Obj/ObjFileParser.cpp @@ -556,7 +556,7 @@ void ObjFileParser::getMaterialDesc() { // This may be the case if the material library is missing. We don't want to lose all // materials if that happens, so create a new named material instead of discarding it // completely. - ASSIMP_LOG_ERROR("OBJ: failed to locate material " + strName + ", creating new material"); + ASSIMP_LOG_ERROR("OBJ: failed to locate material ", strName, ", creating new material"); m_pModel->m_pCurrentMaterial = new ObjFile::Material(); m_pModel->m_pCurrentMaterial->MaterialName.Set(strName); m_pModel->m_MaterialLib.push_back(strName); @@ -620,12 +620,12 @@ void ObjFileParser::getMaterialLib() { IOStream *pFile = m_pIO->Open(absName); if (nullptr == pFile) { - ASSIMP_LOG_ERROR("OBJ: Unable to locate material file " + strMatName); + ASSIMP_LOG_ERROR("OBJ: Unable to locate material file ", strMatName); std::string strMatFallbackName = m_originalObjFileName.substr(0, m_originalObjFileName.length() - 3) + "mtl"; - ASSIMP_LOG_INFO("OBJ: Opening fallback material file " + strMatFallbackName); + ASSIMP_LOG_INFO("OBJ: Opening fallback material file ", strMatFallbackName); pFile = m_pIO->Open(strMatFallbackName); if (!pFile) { - ASSIMP_LOG_ERROR("OBJ: Unable to locate fallback material file " + strMatFallbackName); + ASSIMP_LOG_ERROR("OBJ: Unable to locate fallback material file ", strMatFallbackName); m_DataIt = skipLine(m_DataIt, m_DataItEnd, m_uiLine); return; } @@ -660,7 +660,7 @@ void ObjFileParser::getNewMaterial() { std::map::iterator it = m_pModel->m_MaterialMap.find(strMat); if (it == m_pModel->m_MaterialMap.end()) { // Show a warning, if material was not found - ASSIMP_LOG_WARN("OBJ: Unsupported material requested: " + strMat); + ASSIMP_LOG_WARN("OBJ: Unsupported material requested: ", strMat); m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; } else { // Set new material diff --git a/code/AssetLib/Ogre/OgreBinarySerializer.cpp b/code/AssetLib/Ogre/OgreBinarySerializer.cpp index b54316514..1d20799a1 100644 --- a/code/AssetLib/Ogre/OgreBinarySerializer.cpp +++ b/code/AssetLib/Ogre/OgreBinarySerializer.cpp @@ -155,7 +155,7 @@ uint16_t OgreBinarySerializer::ReadHeader(bool readLen) { #if (OGRE_BINARY_SERIALIZER_DEBUG == 1) if (id != HEADER_CHUNK_ID) { - ASSIMP_LOG_DEBUG(Formatter::format() << (assetMode == AM_Mesh ? MeshHeaderToString(static_cast(id)) : SkeletonHeaderToString(static_cast(id)))); + ASSIMP_LOG_DEBUG((assetMode == AM_Mesh ? MeshHeaderToString(static_cast(id)) : SkeletonHeaderToString(static_cast(id)))); } #endif diff --git a/code/AssetLib/Ogre/OgreMaterial.cpp b/code/AssetLib/Ogre/OgreMaterial.cpp index cafdda795..295dedde6 100644 --- a/code/AssetLib/Ogre/OgreMaterial.cpp +++ b/code/AssetLib/Ogre/OgreMaterial.cpp @@ -477,7 +477,7 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr return false; } if (textureType == aiTextureType_NONE) { - ASSIMP_LOG_WARN("Failed to detect texture type for '" + textureRef + "', ignoring texture_unit."); + ASSIMP_LOG_WARN("Failed to detect texture type for '", textureRef, "', ignoring texture_unit."); return false; } diff --git a/code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp b/code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp index 7d9e1f6eb..becfa41fc 100644 --- a/code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp +++ b/code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp @@ -446,7 +446,7 @@ void Q3BSPFileImporter::createMaterials(const Q3BSP::Q3BSPModel *pModel, aiScene normalizePathName(tmp, texName); if (!importTextureFromArchive(pModel, pArchive, pScene, pMatHelper, textureId)) { - ASSIMP_LOG_ERROR("Cannot import texture from archive " + texName); + ASSIMP_LOG_ERROR("Cannot import texture from archive ", texName); } } } diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp index 1edfc602b..dbc8267d3 100644 --- a/code/AssetLib/glTF2/glTF2Importer.cpp +++ b/code/AssetLib/glTF2/glTF2Importer.cpp @@ -455,14 +455,14 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { if (attr.normal.size() > 0 && attr.normal[0]) { if (attr.normal[0]->count != aim->mNumVertices) { - DefaultLogger::get()->warn("Normal count in mesh \"" + mesh.name + "\" does not match the vertex count, normals ignored."); + DefaultLogger::get()->warn("Normal count in mesh \"", mesh.name, "\" does not match the vertex count, normals ignored."); } else { attr.normal[0]->ExtractData(aim->mNormals); // only extract tangents if normals are present if (attr.tangent.size() > 0 && attr.tangent[0]) { if (attr.tangent[0]->count != aim->mNumVertices) { - DefaultLogger::get()->warn("Tangent count in mesh \"" + mesh.name + "\" does not match the vertex count, tangents ignored."); + DefaultLogger::get()->warn("Tangent count in mesh \"", mesh.name, "\" does not match the vertex count, tangents ignored."); } else { // generate bitangents from normals and tangents according to spec Tangent *tangents = nullptr; @@ -485,7 +485,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { 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 + + DefaultLogger::get()->warn("Color stream size in mesh \"", mesh.name, "\" does not match the vertex count"); continue; } @@ -508,7 +508,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) { } if (attr.texcoord[tc]->count != aim->mNumVertices) { - DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name + + DefaultLogger::get()->warn("Texcoord stream size in mesh \"", mesh.name, "\" does not match the vertex count"); continue; } diff --git a/code/Common/FileSystemFilter.h b/code/Common/FileSystemFilter.h index 92f199870..6585f9df6 100644 --- a/code/Common/FileSystemFilter.h +++ b/code/Common/FileSystemFilter.h @@ -89,7 +89,7 @@ public: mBase += getOsSeparator(); } - DefaultLogger::get()->info("Import root directory is \'" + mBase + "\'"); + DefaultLogger::get()->info("Import root directory is \'", mBase, "\'"); } /** Destructor. */ diff --git a/code/Common/Importer.cpp b/code/Common/Importer.cpp index 61e5938f6..a2ad041fb 100644 --- a/code/Common/Importer.cpp +++ b/code/Common/Importer.cpp @@ -665,7 +665,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { if ( nullptr != desc ) { ext = desc->mName; } - ASSIMP_LOG_INFO("Found a matching importer for this file format: " + ext + "." ); + ASSIMP_LOG_INFO("Found a matching importer for this file format: ", ext, "." ); pimpl->mProgressHandler->UpdateFileRead( 0, fileSize ); if (profiler) { diff --git a/code/Material/MaterialSystem.cpp b/code/Material/MaterialSystem.cpp index 310dea29d..c35a1aa93 100644 --- a/code/Material/MaterialSystem.cpp +++ b/code/Material/MaterialSystem.cpp @@ -160,7 +160,7 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial *pMat, break; } if (!IsSpace(*cur)) { - ASSIMP_LOG_ERROR("Material property" + std::string(pKey) + + ASSIMP_LOG_ERROR("Material property", pKey, " is a string; failed to parse a float array out of it."); return AI_FAILURE; } @@ -238,7 +238,7 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial *pMat, break; } if (!IsSpace(*cur)) { - ASSIMP_LOG_ERROR("Material property" + std::string(pKey) + + ASSIMP_LOG_ERROR("Material property", pKey, " is a string; failed to parse an integer array out of it."); return AI_FAILURE; } @@ -306,8 +306,7 @@ aiReturn aiGetMaterialString(const aiMaterial *pMat, memcpy(pOut->data, prop->mData + 4, pOut->length + 1); } else { // TODO - implement lexical cast as well - ASSIMP_LOG_ERROR("Material property" + std::string(pKey) + - " was found, but is no string"); + ASSIMP_LOG_ERROR("Material property", pKey, " was found, but is no string"); return AI_FAILURE; } return AI_SUCCESS; diff --git a/code/PostProcessing/ValidateDataStructure.cpp b/code/PostProcessing/ValidateDataStructure.cpp index 3058ca6ce..6a872ef11 100644 --- a/code/PostProcessing/ValidateDataStructure.cpp +++ b/code/PostProcessing/ValidateDataStructure.cpp @@ -99,7 +99,7 @@ void ValidateDSProcess::ReportWarning(const char *msg, ...) { ai_assert(iLen > 0); va_end(args); - ASSIMP_LOG_WARN("Validation warning: " + std::string(szBuffer, iLen)); + ASSIMP_LOG_WARN("Validation warning: ", std::string(szBuffer, iLen)); } // ------------------------------------------------------------------------------------------------ From 8ab2e466f52c46afdf2740e787cbdc1648966a61 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 13 May 2021 18:51:12 +0200 Subject: [PATCH 68/93] Update Readme.md - Add folder AssetLib to readme in structure --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 81fd9fd9d..680f7e446 100644 --- a/Readme.md +++ b/Readme.md @@ -68,7 +68,7 @@ The source code is organized in the following way: code/Common The base implementation for importers and the infrastructure code/PostProcessing The post-processing steps - code/ Implementation for import and export for the format + code/AssetLib/ Implementation for import and export for the format ### Where to get help ### For more information, visit [our website](http://assimp.org/). Or check out the `./doc`- folder, which contains the official documentation in HTML format. From 348ae42212d9b0f6263e286054502ae6505d1048 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 13 May 2021 18:54:21 +0200 Subject: [PATCH 69/93] Update Readme.md --- Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 680f7e446..f2ea4b094 100644 --- a/Readme.md +++ b/Readme.md @@ -66,8 +66,8 @@ Open Asset Import Library is implemented in C++. The directory structure looks l The source code is organized in the following way: - code/Common The base implementation for importers and the infrastructure - code/PostProcessing The post-processing steps + code/Common The base implementation for importers and the infrastructure + code/PostProcessing The post-processing steps code/AssetLib/ Implementation for import and export for the format ### Where to get help ### From 27135bd3e7ec444bb7000a2d8be179a52f77a5cf Mon Sep 17 00:00:00 2001 From: ogjamesfranco Date: Sat, 15 May 2021 15:27:24 -0400 Subject: [PATCH 70/93] changed the assimp output directory vars to cached vars --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7027e3300..7b9d6fc55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -334,9 +334,9 @@ INCLUDE (FindPkgMacros) INCLUDE (PrecompiledHeader) # Set Assimp project output directory variables. -SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") -SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") -SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib") +SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for runtime output files") +SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for library output files") +SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib" CACHE STRING "Path for archive output files") # Macro used to set the output directories of a target to the # respective Assimp output directories. From 6e4b9d267bbf69f3e9f054f5d1f4b237ced578cf Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Mon, 17 May 2021 10:29:06 +0100 Subject: [PATCH 71/93] Remove TODO. Typo fix. --- code/AssetLib/AC/ACLoader.cpp | 2 +- code/Common/DefaultLogger.cpp | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/code/AssetLib/AC/ACLoader.cpp b/code/AssetLib/AC/ACLoader.cpp index 974e77825..078c96e32 100644 --- a/code/AssetLib/AC/ACLoader.cpp +++ b/code/AssetLib/AC/ACLoader.cpp @@ -116,7 +116,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name buffer = AcSkipToNextToken(buffer); if (0 != name_length) { if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) { - ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " + std::string(name) + " was expected."); + ASSIMP_LOG_ERROR("AC3D: Unexpected token. ", name, " was expected."); return buffer; } buffer += name_length + 1; diff --git a/code/Common/DefaultLogger.cpp b/code/Common/DefaultLogger.cpp index e12276ea9..253cae47b 100644 --- a/code/Common/DefaultLogger.cpp +++ b/code/Common/DefaultLogger.cpp @@ -165,7 +165,6 @@ Logger *DefaultLogger::create(const char *name /*= "AssimpLog.txt"*/, // ---------------------------------------------------------------------------------- void Logger::debugInternal(Assimp::Formatter::format f) { std::string message = f; - // TODO: Should limit sizes in the formatter. // SECURITY FIX: see above if (message.length() > MAX_LOG_MESSAGE_LENGTH) { return; @@ -176,7 +175,6 @@ void Logger::debugInternal(Assimp::Formatter::format f) { // ---------------------------------------------------------------------------------- void Logger::verboseDebugInternal(Assimp::Formatter::format f) { std::string message = f; - // TODO: Should limit sizes in the formatter. // SECURITY FIX: see above if (message.length() > MAX_LOG_MESSAGE_LENGTH) { return; @@ -187,7 +185,6 @@ void Logger::verboseDebugInternal(Assimp::Formatter::format f) { // ---------------------------------------------------------------------------------- void Logger::infoInternal(Assimp::Formatter::format f) { std::string message = f; - // TODO: Should limit sizes in the formatter. // SECURITY FIX: see above if (message.length() > MAX_LOG_MESSAGE_LENGTH) { return; @@ -198,7 +195,6 @@ void Logger::infoInternal(Assimp::Formatter::format f) { // ---------------------------------------------------------------------------------- void Logger::warnInternal(Assimp::Formatter::format f) { std::string message = f; - // TODO: Should limit sizes in the formatter. // SECURITY FIX: see above if (message.length() > MAX_LOG_MESSAGE_LENGTH) { return; @@ -209,7 +205,6 @@ void Logger::warnInternal(Assimp::Formatter::format f) { // ---------------------------------------------------------------------------------- void Logger::errorInternal(Assimp::Formatter::format f) { std::string message = f; - // TODO: Should limit sizes in the formatter. // SECURITY FIX: see above if (message.length() > MAX_LOG_MESSAGE_LENGTH) { return; From fd5d1211f9aa4012127d6a92370fa00f4c49ffe2 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Mon, 17 May 2021 10:33:00 +0100 Subject: [PATCH 72/93] Recover comment which got dropped --- code/Common/DefaultLogger.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/Common/DefaultLogger.cpp b/code/Common/DefaultLogger.cpp index 253cae47b..913857f85 100644 --- a/code/Common/DefaultLogger.cpp +++ b/code/Common/DefaultLogger.cpp @@ -165,7 +165,9 @@ Logger *DefaultLogger::create(const char *name /*= "AssimpLog.txt"*/, // ---------------------------------------------------------------------------------- void Logger::debugInternal(Assimp::Formatter::format f) { std::string message = f; - // SECURITY FIX: see above + // SECURITY FIX: otherwise it's easy to produce overruns since + // sometimes importers will include data from the input file + // (i.e. node names) in their messages. if (message.length() > MAX_LOG_MESSAGE_LENGTH) { return; } From 084dc73b91c65e84db83b4bd94e79b1437c88834 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Mon, 17 May 2021 11:27:21 +0100 Subject: [PATCH 73/93] Fast path for unformatted calls. --- code/Common/DefaultLogger.cpp | 39 ++++++++++---------- include/assimp/Logger.hpp | 69 +++++++++++++++++++++++------------ 2 files changed, 65 insertions(+), 43 deletions(-) diff --git a/code/Common/DefaultLogger.cpp b/code/Common/DefaultLogger.cpp index 913857f85..4fa9c865b 100644 --- a/code/Common/DefaultLogger.cpp +++ b/code/Common/DefaultLogger.cpp @@ -163,55 +163,54 @@ Logger *DefaultLogger::create(const char *name /*= "AssimpLog.txt"*/, } // ---------------------------------------------------------------------------------- -void Logger::debugInternal(Assimp::Formatter::format f) { - std::string message = f; +void Logger::debug(const char *message) { + // SECURITY FIX: otherwise it's easy to produce overruns since // sometimes importers will include data from the input file // (i.e. node names) in their messages. - if (message.length() > MAX_LOG_MESSAGE_LENGTH) { + if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { return; } - return OnDebug(message.c_str()); + return OnDebug(message); } // ---------------------------------------------------------------------------------- -void Logger::verboseDebugInternal(Assimp::Formatter::format f) { - std::string message = f; +void Logger::verboseDebug(const char *message) { + // SECURITY FIX: see above - if (message.length() > MAX_LOG_MESSAGE_LENGTH) { + if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { return; } - return OnVerboseDebug(message.c_str()); + return OnVerboseDebug(message); } // ---------------------------------------------------------------------------------- -void Logger::infoInternal(Assimp::Formatter::format f) { - std::string message = f; +void Logger::info(const char *message) { + // SECURITY FIX: see above - if (message.length() > MAX_LOG_MESSAGE_LENGTH) { + if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { return; } - return OnInfo(message.c_str()); + return OnInfo(message); } // ---------------------------------------------------------------------------------- -void Logger::warnInternal(Assimp::Formatter::format f) { - std::string message = f; +void Logger::warn(const char *message) { + // SECURITY FIX: see above - if (message.length() > MAX_LOG_MESSAGE_LENGTH) { + if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { return; } - return OnWarn(message.c_str()); + return OnWarn(message); } // ---------------------------------------------------------------------------------- -void Logger::errorInternal(Assimp::Formatter::format f) { - std::string message = f; +void Logger::error(const char *message) { // SECURITY FIX: see above - if (message.length() > MAX_LOG_MESSAGE_LENGTH) { + if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) { return; } - return OnError(message.c_str()); + return OnError(message); } // ---------------------------------------------------------------------------------- diff --git a/include/assimp/Logger.hpp b/include/assimp/Logger.hpp index ecbd9df9b..cb9ef3770 100644 --- a/include/assimp/Logger.hpp +++ b/include/assimp/Logger.hpp @@ -101,41 +101,51 @@ public: // ---------------------------------------------------------------------- /** @brief Writes a info message * @param message Info message*/ + void debug(const char* message); + template void debug(T&&... args) { - debugInternal(Assimp::Formatter::format(), std::forward(args)...); + debugFormat(Assimp::Formatter::format(), std::forward(args)...); } // ---------------------------------------------------------------------- /** @brief Writes a debug message * @param message Debug message*/ + void verboseDebug(const char* message); + template void verboseDebug(T&&... args) { - verboseDebugInternal(Assimp::Formatter::format(), std::forward(args)...); + verboseDebugFormat(Assimp::Formatter::format(), std::forward(args)...); } // ---------------------------------------------------------------------- /** @brief Writes a info message * @param message Info message*/ + void info(const char* message); + template void info(T&&... args) { - infoInternal(Assimp::Formatter::format(), std::forward(args)...); + infoFormat(Assimp::Formatter::format(), std::forward(args)...); } // ---------------------------------------------------------------------- /** @brief Writes a warning message * @param message Warn message*/ + void warn(const char* message); + template void warn(T&&... args) { - warnInternal(Assimp::Formatter::format(), std::forward(args)...); + warnFormat(Assimp::Formatter::format(), std::forward(args)...); } // ---------------------------------------------------------------------- /** @brief Writes an error message * @param message Info message*/ + void error(const char* message); + template void error(T&&... args) { - errorInternal(Assimp::Formatter::format(), std::forward(args)...); + errorFormat(Assimp::Formatter::format(), std::forward(args)...); } // ---------------------------------------------------------------------- @@ -236,36 +246,49 @@ protected: virtual void OnError(const char* message) = 0; protected: - - void debugInternal(Assimp::Formatter::format f); - void verboseDebugInternal(Assimp::Formatter::format f); - void warnInternal(Assimp::Formatter::format f); - void infoInternal(Assimp::Formatter::format f); - void errorInternal(Assimp::Formatter::format f); - - template - void debugInternal(Assimp::Formatter::format f, U&& u, T&&... args) { - debugInternal(std::move(f << std::forward(u)), std::forward(args)...); + void debugFormat(Assimp::Formatter::format f) { + debug(std::string(f).c_str()); } template - void verboseDebugInternal(Assimp::Formatter::format f, U&& u, T&&... args) { - verboseDebugInternal(std::move(f << std::forward(u)), std::forward(args)...); + void debugFormat(Assimp::Formatter::format f, U&& u, T&&... args) { + debugFormat(std::move(f << std::forward(u)), std::forward(args)...); + } + + void verboseDebugFormat(Assimp::Formatter::format f) { + verboseDebug(std::string(f).c_str()); } template - void warnInternal(Assimp::Formatter::format f, U&& u, T&&... args) { - warnInternal(std::move(f << std::forward(u)), std::forward(args)...); + void verboseDebugFormat(Assimp::Formatter::format f, U&& u, T&&... args) { + verboseDebugFormat(std::move(f << std::forward(u)), std::forward(args)...); + } + + void warnFormat(Assimp::Formatter::format f) { + warn(std::string(f).c_str()); } template - void infoInternal(Assimp::Formatter::format f, U&& u, T&&... args) { - infoInternal(std::move(f << std::forward(u)), std::forward(args)...); + void warnFormat(Assimp::Formatter::format f, U&& u, T&&... args) { + warnFormat(std::move(f << std::forward(u)), std::forward(args)...); + } + + void infoFormat(Assimp::Formatter::format f) { + info(std::string(f).c_str()); } template - void errorInternal(Assimp::Formatter::format f, U&& u, T&&... args) { - errorInternal(std::move(f << std::forward(u)), std::forward(args)...); + void infoFormat(Assimp::Formatter::format f, U&& u, T&&... args) { + infoFormat(std::move(f << std::forward(u)), std::forward(args)...); + } + + void errorFormat(Assimp::Formatter::format f) { + error(std::string(f).c_str()); + } + + template + void errorFormat(Assimp::Formatter::format f, U&& u, T&&... args) { + errorFormat(std::move(f << std::forward(u)), std::forward(args)...); } protected: From 3d3462a621bae404d9704de4523bec9e39da53e1 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Mon, 17 May 2021 11:54:43 +0100 Subject: [PATCH 74/93] Simplify formatting templates. --- include/assimp/Logger.hpp | 55 +++++++-------------------------------- 1 file changed, 9 insertions(+), 46 deletions(-) diff --git a/include/assimp/Logger.hpp b/include/assimp/Logger.hpp index cb9ef3770..3ca4a6cb2 100644 --- a/include/assimp/Logger.hpp +++ b/include/assimp/Logger.hpp @@ -105,7 +105,7 @@ public: template void debug(T&&... args) { - debugFormat(Assimp::Formatter::format(), std::forward(args)...); + debug(formatMessage(std::forward(args)...).c_str()); } // ---------------------------------------------------------------------- @@ -115,7 +115,7 @@ public: template void verboseDebug(T&&... args) { - verboseDebugFormat(Assimp::Formatter::format(), std::forward(args)...); + verboseDebug(formatMessage(std::forward(args)...).c_str()); } // ---------------------------------------------------------------------- @@ -125,7 +125,7 @@ public: template void info(T&&... args) { - infoFormat(Assimp::Formatter::format(), std::forward(args)...); + info(formatMessage(std::forward(args)...).c_str()); } // ---------------------------------------------------------------------- @@ -135,7 +135,7 @@ public: template void warn(T&&... args) { - warnFormat(Assimp::Formatter::format(), std::forward(args)...); + warn(formatMessage(std::forward(args)...).c_str()); } // ---------------------------------------------------------------------- @@ -145,7 +145,7 @@ public: template void error(T&&... args) { - errorFormat(Assimp::Formatter::format(), std::forward(args)...); + error(formatMessage(std::forward(args)...).c_str()); } // ---------------------------------------------------------------------- @@ -244,51 +244,14 @@ protected: * the function is left. */ virtual void OnError(const char* message) = 0; - protected: - void debugFormat(Assimp::Formatter::format f) { - debug(std::string(f).c_str()); + std::string formatMessage(Assimp::Formatter::format f) { + return f; } template - void debugFormat(Assimp::Formatter::format f, U&& u, T&&... args) { - debugFormat(std::move(f << std::forward(u)), std::forward(args)...); - } - - void verboseDebugFormat(Assimp::Formatter::format f) { - verboseDebug(std::string(f).c_str()); - } - - template - void verboseDebugFormat(Assimp::Formatter::format f, U&& u, T&&... args) { - verboseDebugFormat(std::move(f << std::forward(u)), std::forward(args)...); - } - - void warnFormat(Assimp::Formatter::format f) { - warn(std::string(f).c_str()); - } - - template - void warnFormat(Assimp::Formatter::format f, U&& u, T&&... args) { - warnFormat(std::move(f << std::forward(u)), std::forward(args)...); - } - - void infoFormat(Assimp::Formatter::format f) { - info(std::string(f).c_str()); - } - - template - void infoFormat(Assimp::Formatter::format f, U&& u, T&&... args) { - infoFormat(std::move(f << std::forward(u)), std::forward(args)...); - } - - void errorFormat(Assimp::Formatter::format f) { - error(std::string(f).c_str()); - } - - template - void errorFormat(Assimp::Formatter::format f, U&& u, T&&... args) { - errorFormat(std::move(f << std::forward(u)), std::forward(args)...); + std::string formatMessage(Assimp::Formatter::format f, U&& u, T&&... args) { + return formatMessage(std::move(f << std::forward(u)), std::forward(args)...); } protected: From e01a6b427648f30144957c1add05baac21273d17 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 18 May 2021 21:15:48 +0200 Subject: [PATCH 75/93] Add xml doc. --- code/AssetLib/Collada/ColladaParser.cpp | 40 +++----- include/assimp/Exceptional.h | 3 + include/assimp/XmlParser.h | 131 ++++++++++++++++++++++-- test/unit/Common/utXmlParser.cpp | 4 +- test/unit/utImporter.cpp | 116 +++++++++------------ 5 files changed, 189 insertions(+), 105 deletions(-) diff --git a/code/AssetLib/Collada/ColladaParser.cpp b/code/AssetLib/Collada/ColladaParser.cpp index 42166fdd4..8e2cb3f9f 100644 --- a/code/AssetLib/Collada/ColladaParser.cpp +++ b/code/AssetLib/Collada/ColladaParser.cpp @@ -623,8 +623,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle controller.mType = Skin; controller.mMethod = Normalized; - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { @@ -929,8 +928,7 @@ void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) { // ------------------------------------------------------------------------------------------------ // Reads a light entry into the given light void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) { - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); @@ -991,10 +989,8 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) { // ------------------------------------------------------------------------------------------------ // Reads a camera entry into the given light void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) { - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; - while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); if (currentName == "orthographic") { @@ -1050,11 +1046,10 @@ void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) { // ------------------------------------------------------------------------------------------------ // Reads an COMMON effect profile void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect) { - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { - const std::string ¤tName = currentNode.name(); + const std::string currentName = currentNode.name(); if (currentName == "newparam") { // save ID std::string sid = currentNode.attribute("sid").as_string(); @@ -1145,10 +1140,9 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) { if (node.empty()) { return; } - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); - XmlNode currentNode; + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); + XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); // MAYA extensions @@ -1208,10 +1202,9 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p if (node.empty()) { return; } - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); - XmlNode currentNode; + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); + XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); if (currentName == "color") { @@ -1273,8 +1266,7 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam) return; } - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); @@ -1360,8 +1352,7 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) { return; } - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); @@ -1386,8 +1377,7 @@ void ColladaParser::ReadSource(XmlNode &node) { std::string sourceID; XmlParser::getStdStrAttribute(node, "id", sourceID); - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); @@ -1490,8 +1480,7 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) { acc.mSource = source.c_str() + 1; // ignore the leading '#' acc.mSize = 0; // gets incremented with every param - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); @@ -1608,8 +1597,7 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) { ai_assert(primType != Prim_Invalid); // also a number of elements, but in addition a

primitive collection and probably index counts for all primitives - XmlNodeIterator xmlIt(node); - xmlIt.collectChildrenPreOrder(node); + XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { const std::string ¤tName = currentNode.name(); diff --git a/include/assimp/Exceptional.h b/include/assimp/Exceptional.h index 36d60d63a..98e2a3321 100644 --- a/include/assimp/Exceptional.h +++ b/include/assimp/Exceptional.h @@ -71,6 +71,9 @@ protected: * nullptr instead of a valid aiScene then. */ class ASSIMP_API DeadlyImportError : public DeadlyErrorBase { public: + DeadlyImportError(const char *message) : + DeadlyErrorBase(Assimp::Formatter::format(), std::forward(message)) {} + /** Constructor with arguments */ template explicit DeadlyImportError(T&&... args) : diff --git a/include/assimp/XmlParser.h b/include/assimp/XmlParser.h index 91fb9907f..5e63a4e79 100644 --- a/include/assimp/XmlParser.h +++ b/include/assimp/XmlParser.h @@ -66,6 +66,8 @@ struct find_node_by_name_predicate { } }; +/// @brief Will convert an attribute to its int value. +/// @tparam TNodeType The node type. template struct NodeConverter { public: @@ -78,19 +80,37 @@ public: using XmlNode = pugi::xml_node; using XmlAttribute = pugi::xml_attribute; +/// @brief The Xml-Parser class. +/// +/// Use this parser if you have to import any kind of xml-format. +/// +/// An example: +/// @code +/// TXmlParser theParser; +/// if (theParser.parse(fileStream)) { +/// auto node = theParser.getRootNode(); +/// for ( auto currentNode : node.children()) { +/// // Will loop over all children +/// } +/// } +/// @endcode +/// @tparam TNodeType template class TXmlParser { public: + /// @brief The default class constructor. TXmlParser() : mDoc(nullptr), mData() { // empty } + /// @brief The class destructor. ~TXmlParser() { clear(); } + /// @brief Will clear the parsed xml-file. void clear() { if(mData.empty()) { mDoc = nullptr; @@ -101,6 +121,9 @@ public: mDoc = nullptr; } + /// @brief Will search for a child-node by its name + /// @param name [in] The name of the child-node. + /// @return The node instance or nullptr, if nothing was found. TNodeType *findNode(const std::string &name) { if (name.empty()) { return nullptr; @@ -119,10 +142,16 @@ public: return &mCurrent; } + /// @brief Will return true, if the node is a child-node. + /// @param name [in] The name of the child node to look for. + /// @return true, if the node is a child-node or false if not. bool hasNode(const std::string &name) { return nullptr != findNode(name); } + /// @brief Will parse an xml-file from a given stream. + /// @param stream The input stream. + /// @return true, if the parsing was successful, false if not. bool parse(IOStream *stream) { if (nullptr == stream) { ASSIMP_LOG_DEBUG("Stream is nullptr."); @@ -138,34 +167,53 @@ public: pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full); if (parse_result.status == pugi::status_ok) { return true; - } else { - ASSIMP_LOG_DEBUG("Error while parse xml."); - return false; - } + } + + ASSIMP_LOG_DEBUG("Error while parse xml."); + return false; } + /// @brief Will return the document pointer, is nullptr if no xml-file was parsed. + /// @return The pointer showing to the document. pugi::xml_document *getDocument() const { return mDoc; } + /// @brief Will return the root node, const version. + /// @return The root node. const TNodeType getRootNode() const { return mDoc->root(); } + /// @brief Will return the root node, non-const version. + /// @return The root node. TNodeType getRootNode() { return mDoc->root(); } + /// @brief Will check if a node with the given name is in. + /// @param node [in] The node to look in. + /// @param name [in] The name of the child-node. + /// @return true, if node was found, false if not. static inline bool hasNode(XmlNode &node, const char *name) { pugi::xml_node child = node.find_child(find_node_by_name_predicate(name)); return !child.empty(); } + /// @brief Will check if an attribute is part of the XmlNode. + /// @param xmlNode [in] The node to search in. + /// @param name [in} The attribute name to look for. + /// @return true, if the was found, false if not. static inline bool hasAttribute(XmlNode &xmlNode, const char *name) { pugi::xml_attribute attr = xmlNode.attribute(name); return !attr.empty(); } + /// @brief Will try to get an unsigned int attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The unsigned int value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is an unsigned int. static inline bool getUIntAttribute(XmlNode &xmlNode, const char *name, unsigned int &val) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { @@ -176,6 +224,11 @@ public: return true; } + /// @brief Will try to get an int attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The int value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is an int. static inline bool getIntAttribute(XmlNode &xmlNode, const char *name, int &val ) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { @@ -186,6 +239,11 @@ public: return true; } + /// @brief Will try to get a real attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The real value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is a real. static inline bool getRealAttribute( XmlNode &xmlNode, const char *name, ai_real &val ) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { @@ -199,7 +257,12 @@ public: return true; } - static inline bool getFloatAttribute(XmlNode &xmlNode, const char *name, float &val ) { + /// @brief Will try to get a float attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The float value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is a float. + static inline bool getFloatAttribute(XmlNode &xmlNode, const char *name, float &val) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { return false; @@ -210,7 +273,12 @@ public: } - static inline bool getDoubleAttribute( XmlNode &xmlNode, const char *name, double &val ) { + /// @brief Will try to get a double attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The double value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is a double. + static inline bool getDoubleAttribute(XmlNode &xmlNode, const char *name, double &val) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { return false; @@ -220,6 +288,11 @@ public: return true; } + /// @brief Will try to get a std::string attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The std::string value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is a std::string. static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { @@ -230,6 +303,11 @@ public: return true; } + /// @brief Will try to get a bool attribute value. + /// @param xmlNode [in] The node to search in. + /// @param name [in] The attribute name to look for. + /// @param val [out] The bool value from the attribute. + /// @return true, if the node contains an attribute with the given name and if the value is a bool. static inline bool getBoolAttribute( XmlNode &xmlNode, const char *name, bool &val ) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { @@ -241,6 +319,10 @@ public: } + /// @brief Will try to get the value of the node as a string. + /// @param node [in] The node to search in. + /// @param text [out] The value as a text. + /// @return true, if the value can be read out. static inline bool getValueAsString( XmlNode &node, std::string &text ) { text = std::string(); if (node.empty()) { @@ -252,6 +334,10 @@ public: return true; } + /// @brief Will try to get the value of the node as a float. + /// @param node [in] The node to search in. + /// @param text [out] The value as a float. + /// @return true, if the value can be read out. static inline bool getValueAsFloat( XmlNode &node, ai_real &v ) { if (node.empty()) { return false; @@ -271,17 +357,36 @@ public: using XmlParser = TXmlParser; +/// @brief This class declares an iterator to loop through all children of the root node. class XmlNodeIterator { public: - XmlNodeIterator(XmlNode &parent) : + /// @brief The iteration mode. + enum IterationMode { + PreOrderMode, ///< Pre-ordering, get the values, continue the iteration. + PostOrderMode ///< Post-ordering, continue the iteration, get the values. + }; + /// @brief The class constructor + /// @param parent [in] The xml parent to to iterate through. + /// @param mode [in] The iteration mode. + explicit XmlNodeIterator(XmlNode &parent, IterationMode mode) : mParent(parent), mNodes(), mIndex(0) { + if (mode == PreOrderMode) { + collectChildrenPreOrder(parent); + } else { + collectChildrenPostOrder(parent); + } + } + + /// @brief The class destructor. + ~XmlNodeIterator() { // empty } + /// @brief Will iterate through all children in pre-order iteration. + /// @param node [in] The nod to iterate through. void collectChildrenPreOrder( XmlNode &node ) { - if (node != mParent && node.type() == pugi::node_element) { mNodes.push_back(node); } @@ -290,6 +395,8 @@ public: } } + /// @brief Will iterate through all children in post-order iteration. + /// @param node [in] The nod to iterate through. void collectChildrenPostOrder(XmlNode &node) { for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { collectChildrenPostOrder(currentNode); @@ -299,6 +406,9 @@ public: } } + /// @brief Will iterate through all collected nodes. + /// @param next The next node, if there is any. + /// @return true, if there is a node left. bool getNext(XmlNode &next) { if (mIndex == mNodes.size()) { return false; @@ -310,14 +420,19 @@ public: return true; } + /// @brief Will return the number of collected nodes. + /// @return The number of collected nodes. size_t size() const { return mNodes.size(); } + /// @brief Returns true, if the node is empty. + /// @return true, if the node is empty, false if not. bool isEmpty() const { return mNodes.empty(); } + /// @brief Will clear all collected nodes. void clear() { if (mNodes.empty()) { return; diff --git a/test/unit/Common/utXmlParser.cpp b/test/unit/Common/utXmlParser.cpp index c27669dd1..7e992f9df 100644 --- a/test/unit/Common/utXmlParser.cpp +++ b/test/unit/Common/utXmlParser.cpp @@ -73,9 +73,7 @@ TEST_F(utXmlParser, parse_xml_and_traverse_test) { EXPECT_TRUE(result); XmlNode root = parser.getRootNode(); - XmlNodeIterator nodeIt(root); - EXPECT_TRUE(nodeIt.isEmpty()); - nodeIt.collectChildrenPreOrder(root); + XmlNodeIterator nodeIt(root, XmlNodeIterator::PreOrderMode); const size_t numNodes = nodeIt.size(); bool empty = nodeIt.isEmpty(); EXPECT_FALSE(empty); diff --git a/test/unit/utImporter.cpp b/test/unit/utImporter.cpp index 65b7f99ee..9d3b971a3 100644 --- a/test/unit/utImporter.cpp +++ b/test/unit/utImporter.cpp @@ -280,104 +280,84 @@ TEST_F(ImporterTest, SearchFileHeaderForTokenTest) { // BaseImporter::SearchFileHeaderForToken( &ioSystem, assetPath, Token, 2 ) } +namespace { +// Description for an importer which fails in specific ways. +aiImporterDesc s_failingImporterDescription = { + "Failing importer", + "assimp team", + "", + "", + 0, + 1, + 0, + 1, + 0, + "fail" +}; -namespace -{ - // Description for an importer which fails in specific ways. - aiImporterDesc s_failingImporterDescription = { - "Failing importer", - "assimp team", - "", - "", - 0, - 1, - 0, - 1, - 0, - "fail" - }; +// This importer fails in specific ways. +class FailingImporter : public Assimp::BaseImporter { +public: + virtual ~FailingImporter() = default; + virtual bool CanRead(const std::string &, Assimp::IOSystem *, bool) const override { + return true; + } - // This importer fails in specific ways. - class FailingImporter : public Assimp::BaseImporter { - public: - virtual ~FailingImporter() = default; - virtual bool CanRead( const std::string&, Assimp::IOSystem*, bool ) const override - { - return true; +protected: + const aiImporterDesc *GetInfo() const override { + return &s_failingImporterDescription; + } + + void InternReadFile(const std::string &pFile, aiScene *, Assimp::IOSystem *) override { + if (pFile == "deadlyImportError.fail") { + throw DeadlyImportError("Deadly import error test. Details: ", 42, " More Details: ", "Failure"); + } else if (pFile == "stdException.fail") { + throw std::runtime_error("std::exception test"); + } else if (pFile == "unexpectedException.fail") { + throw 5; } + } +}; +} // namespace - protected: - virtual const aiImporterDesc* GetInfo() const override { return &s_failingImporterDescription; } - - virtual void InternReadFile( const std::string& pFile, aiScene*, Assimp::IOSystem* ) override - { - if (pFile == "deadlyImportError.fail") - { - throw DeadlyImportError("Deadly import error test. Details: ", 42, " More Details: ", "Failure"); - } - else if (pFile == "stdException.fail") - { - throw std::runtime_error("std::exception test"); - } - else if (pFile == "unexpectedException.fail") - { - throw 5; - } - } - }; -} - -TEST_F(ImporterTest, deadlyImportError) -{ +TEST_F(ImporterTest, deadlyImportError) { pImp->RegisterLoader(new FailingImporter); pImp->SetIOHandler(new TestIOSystem); - const aiScene* scene = pImp->ReadFile("deadlyImportError.fail", 0); + const aiScene *scene = pImp->ReadFile("deadlyImportError.fail", 0); EXPECT_EQ(scene, nullptr); EXPECT_STREQ(pImp->GetErrorString(), "Deadly import error test. Details: 42 More Details: Failure"); EXPECT_NE(pImp->GetException(), std::exception_ptr()); } -TEST_F(ImporterTest, stdException) -{ +TEST_F(ImporterTest, stdException) { pImp->RegisterLoader(new FailingImporter); pImp->SetIOHandler(new TestIOSystem); - const aiScene* scene = pImp->ReadFile("stdException.fail", 0); + const aiScene *scene = pImp->ReadFile("stdException.fail", 0); EXPECT_EQ(scene, nullptr); EXPECT_STREQ(pImp->GetErrorString(), "std::exception test"); EXPECT_NE(pImp->GetException(), std::exception_ptr()); - try - { + try { std::rethrow_exception(pImp->GetException()); - } - catch(const std::exception& e) - { + } catch (const std::exception &e) { EXPECT_STREQ(e.what(), "std::exception test"); - } - catch(...) - { + } catch (...) { EXPECT_TRUE(false); } } -TEST_F(ImporterTest, unexpectedException) -{ +TEST_F(ImporterTest, unexpectedException) { pImp->RegisterLoader(new FailingImporter); pImp->SetIOHandler(new TestIOSystem); - const aiScene* scene = pImp->ReadFile("unexpectedException.fail", 0); + const aiScene *scene = pImp->ReadFile("unexpectedException.fail", 0); EXPECT_EQ(scene, nullptr); EXPECT_STREQ(pImp->GetErrorString(), "Unknown exception"); ASSERT_NE(pImp->GetException(), std::exception_ptr()); - try - { + try { std::rethrow_exception(pImp->GetException()); - } - catch(int x) - { + } catch (int x) { EXPECT_EQ(x, 5); - } - catch(...) - { + } catch (...) { EXPECT_TRUE(false); } } From 3726b2eef462f2941d1479e16fc7eea424e3f11e Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 18 May 2021 21:21:43 +0200 Subject: [PATCH 76/93] fix the build --- include/assimp/XmlParser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/assimp/XmlParser.h b/include/assimp/XmlParser.h index 11f937b56..35ab0471e 100644 --- a/include/assimp/XmlParser.h +++ b/include/assimp/XmlParser.h @@ -169,7 +169,7 @@ public: return true; } - ASSIMP_LOG_DEBUG("Error while parse xml.", parse_result.description() << " @ ", parse_result.offset); + ASSIMP_LOG_DEBUG("Error while parse xml.", std::string(parse_result.description()), " @ ", parse_result.offset); return false; } From 88ccfedd10d9fb3f90502b4ffed94657ac16d134 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 19 May 2021 00:16:15 +0200 Subject: [PATCH 77/93] Fix possible nullptr dereferences. --- include/assimp/XmlParser.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/assimp/XmlParser.h b/include/assimp/XmlParser.h index 35ab0471e..7578eff59 100644 --- a/include/assimp/XmlParser.h +++ b/include/assimp/XmlParser.h @@ -183,12 +183,18 @@ public: /// @brief Will return the root node, const version. /// @return The root node. const TNodeType getRootNode() const { + if (nullptr == mDoc) { + return nullptr; + } return mDoc->root(); } /// @brief Will return the root node, non-const version. /// @return The root node. TNodeType getRootNode() { + if (nullptr == mDoc) { + return nullptr; + } return mDoc->root(); } From 20ade095eaeac898d7ce0bc1c6a9d8a120e8e8d1 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 20 May 2021 13:40:44 +0200 Subject: [PATCH 78/93] Return null-type in case of an empty document --- include/assimp/XmlParser.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/include/assimp/XmlParser.h b/include/assimp/XmlParser.h index 7578eff59..18d48f337 100644 --- a/include/assimp/XmlParser.h +++ b/include/assimp/XmlParser.h @@ -174,6 +174,11 @@ public: return false; } + /// @brief Will return truem if a root node is there. + /// @return true in case of an existing root. + bool hasRoot() const { + return nullptr != mDoc; + } /// @brief Will return the document pointer, is nullptr if no xml-file was parsed. /// @return The pointer showing to the document. pugi::xml_document *getDocument() const { @@ -183,8 +188,9 @@ public: /// @brief Will return the root node, const version. /// @return The root node. const TNodeType getRootNode() const { + static pugi::xml_node none; if (nullptr == mDoc) { - return nullptr; + return none; } return mDoc->root(); } @@ -192,8 +198,9 @@ public: /// @brief Will return the root node, non-const version. /// @return The root node. TNodeType getRootNode() { + static pugi::xml_node none; if (nullptr == mDoc) { - return nullptr; + return none; } return mDoc->root(); } From 1f32743f8b455082432adb249426f17c39dfa756 Mon Sep 17 00:00:00 2001 From: dlyr Date: Sat, 22 May 2021 00:56:01 +0200 Subject: [PATCH 79/93] Fix camera fov comment since full fov is stored --- include/assimp/camera.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/assimp/camera.h b/include/assimp/camera.h index d7324d10d..6a7acadbb 100644 --- a/include/assimp/camera.h +++ b/include/assimp/camera.h @@ -137,7 +137,7 @@ struct aiCamera */ C_STRUCT aiVector3D mLookAt; - /** Half horizontal field of view angle, in radians. + /** Horizontal field of view angle, in radians. * * The field of view angle is the angle between the center * line of the screen and the left or right border. From b7b3c6db7e3ba84814dcec1394787e40d3ff7e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Verdon?= Date: Sat, 22 May 2021 16:57:07 +0200 Subject: [PATCH 80/93] Fixing GCC 4.9 compilation issues --- code/AssetLib/glTF2/glTF2Asset.inl | 2 ++ include/assimp/TinyFormatter.h | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl index 8a793c144..256fc8931 100644 --- a/code/AssetLib/glTF2/glTF2Asset.inl +++ b/code/AssetLib/glTF2/glTF2Asset.inl @@ -58,7 +58,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma clang diagnostic ignored "-Wsign-compare" #elif defined(__GNUC__) #pragma GCC diagnostic push +#if (__GNUC__ > 4) #pragma GCC diagnostic ignored "-Wbool-compare" +#endif #pragma GCC diagnostic ignored "-Wsign-compare" #endif diff --git a/include/assimp/TinyFormatter.h b/include/assimp/TinyFormatter.h index ace20be5c..112f19013 100644 --- a/include/assimp/TinyFormatter.h +++ b/include/assimp/TinyFormatter.h @@ -88,9 +88,17 @@ public: underlying << sin; } + // Same problem as the copy constructor below, but with root cause is that stream move + // is not permitted on older GCC versions. Small performance impact on those platforms. +#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 9) + basic_formatter(basic_formatter&& other) { + underlying << (string)other; + } +#else basic_formatter(basic_formatter&& other) : underlying(std::move(other.underlying)) { } +#endif // The problem described here: // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462 From 799384f2b85b8d3ee9c5b9e18bbe532b4dc7c63c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Verdon?= Date: Sat, 22 May 2021 17:36:39 +0200 Subject: [PATCH 81/93] Adding the required c flag to compile zip files using gcc 4.9 --- code/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index ebc3e0116..d3cb6e923 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1137,6 +1137,9 @@ ELSE() TARGET_COMPILE_OPTIONS(assimp PRIVATE -Werror) ENDIF() +# adds C_FLAGS required to compile zip.c on old GCC 4.x compiler +TARGET_COMPILE_FEATURES(assimp PUBLIC c_std_99) + TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC $ $ From 5468dd667e41069da6f6ca97141c953838107eef Mon Sep 17 00:00:00 2001 From: Evangel Date: Wed, 26 May 2021 18:36:56 +1000 Subject: [PATCH 82/93] Fix bug in aiMetadata constructor that overwrites an array of one of aiString, aiVector3D, or aiMetadata with the first entry aiMetadata copy constructor calls aiMetadata::Get on the copied from aiMetadata using the const aiString &key version. When this is called on the metadata of an array type, this overwrites all entries with the first entry. This is due to the key of all entries in an array being the name of the array. ie, in a glTF2 file with an extension: "Extension" : [ "Value1", "Value2", "Value3" ] the aiMetadata struct for the "Extension" entry will have 3 entries with key/value pairs as: "Extension"/"Value1" "Extension"/"Value2" "Extension"/"Value3" So when the copy constructor calls the key based aiMetadata::Get, it will find "Value1" for all three entries. This change simply replaces the key based aiMetadata::Get with the index based aiMetadata::Get --- include/assimp/metadata.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/assimp/metadata.h b/include/assimp/metadata.h index fdc88be56..39ac386e4 100644 --- a/include/assimp/metadata.h +++ b/include/assimp/metadata.h @@ -202,17 +202,17 @@ struct aiMetadata { } break; case AI_AISTRING: { aiString v; - rhs.Get(mKeys[i], v); + rhs.Get(i, v); mValues[i].mData = new aiString(v); } break; case AI_AIVECTOR3D: { aiVector3D v; - rhs.Get(mKeys[i], v); + rhs.Get(i, v); mValues[i].mData = new aiVector3D(v); } break; case AI_AIMETADATA: { aiMetadata v; - rhs.Get(mKeys[i], v); + rhs.Get(i, v); mValues[i].mData = new aiMetadata(v); } break; #ifndef SWIG From 2f4fba070364ec3ceb34104e884ee9bddcbd8acf Mon Sep 17 00:00:00 2001 From: Evangel Date: Wed, 26 May 2021 19:11:19 +1000 Subject: [PATCH 83/93] Static cast i back to unsigned int because MSVC complains otherwise. i will never be bigger than an unsigned int since that's what mNumProperties is to begin with. --- include/assimp/metadata.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/assimp/metadata.h b/include/assimp/metadata.h index 39ac386e4..551a9aba4 100644 --- a/include/assimp/metadata.h +++ b/include/assimp/metadata.h @@ -156,7 +156,7 @@ struct aiMetadata { #ifdef __cplusplus - /** + /** * @brief The default constructor, set all members to zero by default. */ aiMetadata() AI_NO_EXCEPT @@ -202,17 +202,17 @@ struct aiMetadata { } break; case AI_AISTRING: { aiString v; - rhs.Get(i, v); + rhs.Get(static_cast(i), v); mValues[i].mData = new aiString(v); } break; case AI_AIVECTOR3D: { aiVector3D v; - rhs.Get(i, v); + rhs.Get(static_cast(i), v); mValues[i].mData = new aiVector3D(v); } break; case AI_AIMETADATA: { aiMetadata v; - rhs.Get(i, v); + rhs.Get(static_cast(i), v); mValues[i].mData = new aiMetadata(v); } break; #ifndef SWIG From c33a4b26346fd1cdaf7133dad06fcc29f47990aa Mon Sep 17 00:00:00 2001 From: Carsten Rudolph <18394207+crud89@users.noreply.github.com> Date: Thu, 27 May 2021 10:10:55 +0200 Subject: [PATCH 84/93] Fixed base name check. --- include/assimp/BlobIOSystem.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/assimp/BlobIOSystem.h b/include/assimp/BlobIOSystem.h index 081ccf32a..0abf166bc 100644 --- a/include/assimp/BlobIOSystem.h +++ b/include/assimp/BlobIOSystem.h @@ -197,7 +197,7 @@ class BlobIOSystem : public IOSystem { public: BlobIOSystem() : - baseName{} { + baseName{AI_BLOBIO_MAGIC} { } BlobIOSystem(const std::string &baseName) : @@ -213,13 +213,13 @@ public: public: // ------------------------------------------------------------------- const char *GetMagicFileName() const { - return baseName.empty() ? AI_BLOBIO_MAGIC : baseName.c_str(); + return baseName.c_str(); } // ------------------------------------------------------------------- aiExportDataBlob *GetBlobChain() { const auto magicName = std::string(this->GetMagicFileName()); - const bool hasBaseName = baseName.empty(); + const bool hasBaseName = baseName != AI_BLOBIO_MAGIC; // one must be the master aiExportDataBlob *master = nullptr, *cur; @@ -249,8 +249,7 @@ public: if (hasBaseName) { cur->name.Set(blobby.first); - } - else { + } else { // extract the file extension from the file written const std::string::size_type s = blobby.first.find_first_of('.'); cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s + 1)); From 59467b204a6f099ed13ab7234bee08c1d89d24e6 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 27 May 2021 15:50:28 +0200 Subject: [PATCH 85/93] Create tech_debt.md --- .github/ISSUE_TEMPLATE/tech_debt.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/tech_debt.md diff --git a/.github/ISSUE_TEMPLATE/tech_debt.md b/.github/ISSUE_TEMPLATE/tech_debt.md new file mode 100644 index 000000000..2cd84d975 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/tech_debt.md @@ -0,0 +1,25 @@ +--- +name: Technical debt +about: Create a report to help us to fix and detect tech debts +title: '' +labels: '' +assignees: '' + +--- + +**Describe the technical debt** +A clear and concise description of what the tech debt is about. + +**Better solution** +A clear and concise description of what you would expect. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. From 919ae69fe8208524301689371e43a5581b8889c6 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 28 May 2021 08:44:40 +0200 Subject: [PATCH 86/93] Update tech_debt.md --- .github/ISSUE_TEMPLATE/tech_debt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/tech_debt.md b/.github/ISSUE_TEMPLATE/tech_debt.md index 2cd84d975..a1172d932 100644 --- a/.github/ISSUE_TEMPLATE/tech_debt.md +++ b/.github/ISSUE_TEMPLATE/tech_debt.md @@ -2,7 +2,7 @@ name: Technical debt about: Create a report to help us to fix and detect tech debts title: '' -labels: '' +labels: 'Techdebt' assignees: '' --- From 3c51ff771cfa001e96b78382e299788250647ef8 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 28 May 2021 09:34:03 +0200 Subject: [PATCH 87/93] Update bug_report.md - Add the bug label - Make platform config more easy --- .github/ISSUE_TEMPLATE/bug_report.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea782..0f9a5f105 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,8 +1,8 @@ --- name: Bug report about: Create a report to help us improve -title: '' -labels: '' +title: 'Bug:' +labels: 'Bug' assignees: '' --- @@ -23,16 +23,10 @@ A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. -**Desktop (please complete the following information):** +**Platform (please complete the following information):** - OS: [e.g. iOS] - Browser [e.g. chrome, safari] - Version [e.g. 22] -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] - **Additional context** Add any other context about the problem here. From 2559befaca621a94f6e911493519730d42f17775 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 28 May 2021 10:26:03 +0200 Subject: [PATCH 88/93] Update feature_request.md - Add label Feature-Request --- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d6..87302a0f0 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request about: Suggest an idea for this project title: '' -labels: '' +labels: 'Feature-Request' assignees: '' --- From 7534b149cff5ef287fce50da4f17cebf4c5a3608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20M=C3=B6ller?= Date: Fri, 28 May 2021 11:55:46 +0200 Subject: [PATCH 89/93] fix non skipped CR in header parsing --- code/AssetLib/Ply/PlyParser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/Ply/PlyParser.cpp b/code/AssetLib/Ply/PlyParser.cpp index 4b416d1a1..59cb6b976 100644 --- a/code/AssetLib/Ply/PlyParser.cpp +++ b/code/AssetLib/Ply/PlyParser.cpp @@ -419,7 +419,8 @@ bool PLY::DOM::ParseHeader(IOStreamBuffer &streamBuffer, std::vector if (PLY::Element::ParseElement(streamBuffer, buffer, &out)) { // add the element to the list of elements alElements.push_back(out); - } else if (TokenMatch(buffer, "end_header", 10)) { + } else if ( TokenMatch(buffer, "end_header\r", 11) || //checks for header end with /r/n ending + TokenMatch(buffer, "end_header", 10)) { //checks for /n ending, if it doesn't end with /r/n // we have reached the end of the header break; } else { From 84a2e1fc922542c3c60dff94c5db682f7ab95711 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 3 Jun 2021 20:43:37 +0200 Subject: [PATCH 90/93] Update unity plugin to trilib2 - closes https://github.com/assimp/assimp/issues/3872 --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index f2ea4b094..949d60966 100644 --- a/Readme.md +++ b/Readme.md @@ -42,7 +42,7 @@ Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. * [.NET](https://bitbucket.org/Starnick/assimpnet/src/master/) * [Pascal](port/AssimpPascal/Readme.md) * [Javascript (Alpha)](https://github.com/makc/assimp2json) -* [Unity 3d Plugin](https://www.assetstore.unity3d.com/en/#!/content/91777) +* [Unity 3d Plugin](https://ricardoreis.net/trilib-2/) * [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status)) * [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port. * [Rust](https://github.com/jkvargas/russimp) From b4fc41bc094574400b0a688ec1381888e40ee99c Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 3 Jun 2021 22:52:10 +0200 Subject: [PATCH 91/93] Use corret attribute name - closes https://github.com/assimp/assimp/issues/3887 --- port/PyAssimp/pyassimp/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port/PyAssimp/pyassimp/core.py b/port/PyAssimp/pyassimp/core.py index 37beac886..35ad882b3 100644 --- a/port/PyAssimp/pyassimp/core.py +++ b/port/PyAssimp/pyassimp/core.py @@ -211,7 +211,7 @@ def _init(self, target = None, parent = None): else: # starts with 'm' but not iterable - setattr(target, name, obj) + setattr(target, m, obj) logger.debug("Added " + name + " as self." + name + " (type: " + str(type(obj)) + ")") if _is_init_type(obj): From cc912f09f7cf1d0d7cbdff5d6d6617d5af904c3a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 3 Jun 2021 23:16:20 +0200 Subject: [PATCH 92/93] update pugi_xml to 1.11 --- contrib/pugixml/readme.txt | 10 +- contrib/pugixml/src/pugiconfig.hpp | 21 +- contrib/pugixml/src/pugixml.cpp | 638 +++++++++++++++++++---------- contrib/pugixml/src/pugixml.hpp | 69 +++- 4 files changed, 496 insertions(+), 242 deletions(-) diff --git a/contrib/pugixml/readme.txt b/contrib/pugixml/readme.txt index 5beb08a90..bfb1875cb 100644 --- a/contrib/pugixml/readme.txt +++ b/contrib/pugixml/readme.txt @@ -1,7 +1,7 @@ -pugixml 1.9 - an XML processing library +pugixml 1.11 - an XML processing library -Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) -Report bugs and download new versions at http://pugixml.org/ +Copyright (C) 2006-2020, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +Report bugs and download new versions at https://pugixml.org/ This is the distribution of pugixml, which is a C++ XML processing library, which consists of a DOM-like interface with rich traversal/modification @@ -13,8 +13,6 @@ automatically during parsing/saving). The distribution contains the following folders: - contrib/ - various contributions to pugixml - docs/ - documentation docs/samples - pugixml usage examples docs/quickstart.html - quick start guide @@ -28,7 +26,7 @@ The distribution contains the following folders: This library is distributed under the MIT License: -Copyright (c) 2006-2018 Arseny Kapoulkine +Copyright (c) 2006-2019 Arseny Kapoulkine Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/contrib/pugixml/src/pugiconfig.hpp b/contrib/pugixml/src/pugiconfig.hpp index 065b3c8bb..405a66b65 100644 --- a/contrib/pugixml/src/pugiconfig.hpp +++ b/contrib/pugixml/src/pugiconfig.hpp @@ -1,8 +1,8 @@ /** - * pugixml parser - version 1.9 + * pugixml parser - version 1.11 * -------------------------------------------------------- - * Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) - * Report bugs and download new versions at http://pugixml.org/ + * Copyright (C) 2006-2020, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Report bugs and download new versions at https://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end * of this file. @@ -30,10 +30,8 @@ // #define PUGIXML_NO_EXCEPTIONS // Set this to control attributes for public classes/functions, i.e.: -//#ifdef _WIN32 -//#define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL -//#define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL -//#endif +// #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL +// #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL // #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall // In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead @@ -42,16 +40,19 @@ // #define PUGIXML_MEMORY_OUTPUT_STACK 10240 // #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096 +// Tune this constant to adjust max nesting for XPath queries +// #define PUGIXML_XPATH_DEPTH_LIMIT 1024 + // Uncomment this to switch to header-only version -#define PUGIXML_HEADER_ONLY +// #define PUGIXML_HEADER_ONLY // Uncomment this to enable long long support -//#define PUGIXML_HAS_LONG_LONG +// #define PUGIXML_HAS_LONG_LONG #endif /** - * Copyright (c) 2006-2018 Arseny Kapoulkine + * Copyright (c) 2006-2020 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/contrib/pugixml/src/pugixml.cpp b/contrib/pugixml/src/pugixml.cpp index 2afff09dd..efdcdf699 100644 --- a/contrib/pugixml/src/pugixml.cpp +++ b/contrib/pugixml/src/pugixml.cpp @@ -1,8 +1,8 @@ /** - * pugixml parser - version 1.9 + * pugixml parser - version 1.11 * -------------------------------------------------------- - * Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) - * Report bugs and download new versions at http://pugixml.org/ + * Copyright (C) 2006-2020, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Report bugs and download new versions at https://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end * of this file. @@ -378,7 +378,7 @@ PUGI__NS_BEGIN static PUGI__UNSIGNED_OVERFLOW unsigned int hash(const void* key) { - unsigned int h = static_cast(reinterpret_cast(key)); + unsigned int h = static_cast(reinterpret_cast(key) & 0xffffffff); // MurmurHash3 32-bit finalizer h ^= h >> 16; @@ -1861,7 +1861,7 @@ PUGI__NS_BEGIN enum chartypex_t { ctx_special_pcdata = 1, // Any symbol >= 0 and < 32 (except \t, \r, \n), &, <, > - ctx_special_attr = 2, // Any symbol >= 0 and < 32 (except \t), &, <, >, " + ctx_special_attr = 2, // Any symbol >= 0 and < 32, &, <, ", ' ctx_start_symbol = 4, // Any symbol > 127, a-z, A-Z, _ ctx_digit = 8, // 0-9 ctx_symbol = 16 // Any symbol > 127, a-z, A-Z, 0-9, _, -, . @@ -1869,10 +1869,10 @@ PUGI__NS_BEGIN static const unsigned char chartypex_table[256] = { - 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 2, 3, 3, // 0-15 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 3, 3, // 0-15 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 16-31 - 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 16, 16, 0, // 32-47 - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 3, 0, 3, 0, // 48-63 + 0, 0, 2, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 16, 16, 0, // 32-47 + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 3, 0, 1, 0, // 48-63 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 64-79 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 20, // 80-95 @@ -2709,7 +2709,7 @@ PUGI__NS_BEGIN { PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_trim_pcdata == 0x0800); - switch (((optmask >> 4) & 3) | ((optmask >> 9) & 4)) // get bitmask for flags (eol escapes trim) + switch (((optmask >> 4) & 3) | ((optmask >> 9) & 4)) // get bitmask for flags (trim eol escapes); this simultaneously checks 3 options from assertion above { case 0: return strconv_pcdata_impl::parse; case 1: return strconv_pcdata_impl::parse; @@ -2878,7 +2878,7 @@ PUGI__NS_BEGIN { PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wconv_attribute == 0x40 && parse_wnorm_attribute == 0x80); - switch ((optmask >> 4) & 15) // get bitmask for flags (wconv wnorm eol escapes) + switch ((optmask >> 4) & 15) // get bitmask for flags (wnorm wconv eol escapes); this simultaneously checks 4 options from assertion above { case 0: return strconv_attribute_impl::parse_simple; case 1: return strconv_attribute_impl::parse_simple; @@ -3903,7 +3903,7 @@ PUGI__NS_BEGIN xml_encoding encoding; }; - PUGI__FN void text_output_escaped(xml_buffered_writer& writer, const char_t* s, chartypex_t type) + PUGI__FN void text_output_escaped(xml_buffered_writer& writer, const char_t* s, chartypex_t type, unsigned int flags) { while (*s) { @@ -3930,7 +3930,17 @@ PUGI__NS_BEGIN ++s; break; case '"': - writer.write('&', 'q', 'u', 'o', 't', ';'); + if (flags & format_attribute_single_quote) + writer.write('"'); + else + writer.write('&', 'q', 'u', 'o', 't', ';'); + ++s; + break; + case '\'': + if (flags & format_attribute_single_quote) + writer.write('&', 'a', 'p', 'o', 's', ';'); + else + writer.write('\''); ++s; break; default: // s is not a usual symbol @@ -3938,7 +3948,8 @@ PUGI__NS_BEGIN unsigned int ch = static_cast(*s++); assert(ch < 32); - writer.write('&', '#', static_cast((ch / 10) + '0'), static_cast((ch % 10) + '0'), ';'); + if (!(flags & format_skip_control_chars)) + writer.write('&', '#', static_cast((ch / 10) + '0'), static_cast((ch % 10) + '0'), ';'); } } } @@ -3949,7 +3960,7 @@ PUGI__NS_BEGIN if (flags & format_no_escapes) writer.write_string(s); else - text_output_escaped(writer, s, type); + text_output_escaped(writer, s, type, flags); } PUGI__FN void text_output_cdata(xml_buffered_writer& writer, const char_t* s) @@ -4063,6 +4074,7 @@ PUGI__NS_BEGIN PUGI__FN void node_output_attributes(xml_buffered_writer& writer, xml_node_struct* node, const char_t* indent, size_t indent_length, unsigned int flags, unsigned int depth) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); + const char_t enquotation_char = (flags & format_attribute_single_quote) ? '\'' : '"'; for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute) { @@ -4078,12 +4090,12 @@ PUGI__NS_BEGIN } writer.write_string(a->name ? a->name + 0 : default_name); - writer.write('=', '"'); + writer.write('=', enquotation_char); if (a->value) text_output(writer, a->value, ctx_special_attr, flags); - writer.write('"'); + writer.write(enquotation_char); } } @@ -4423,6 +4435,9 @@ PUGI__NS_BEGIN while (sit && sit != sn) { + // loop invariant: dit is inside the subtree rooted at dn + assert(dit); + // when a tree is copied into one of the descendants, we need to skip that subtree to avoid an infinite loop if (sit != dn) { @@ -4452,9 +4467,14 @@ PUGI__NS_BEGIN sit = sit->parent; dit = dit->parent; + + // loop invariant: dit is inside the subtree rooted at dn while sit is inside sn + assert(sit == sn || dit); } while (sit != sn); } + + assert(!sit || dit == dn->parent); } PUGI__FN void node_copy_attribute(xml_attribute_struct* da, xml_attribute_struct* sa) @@ -4653,19 +4673,19 @@ PUGI__NS_BEGIN } template - PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, float value) + PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, float value, int precision) { char buf[128]; - PUGI__SNPRINTF(buf, "%.9g", value); + PUGI__SNPRINTF(buf, "%.*g", precision, double(value)); return set_value_ascii(dest, header, header_mask, buf); } template - PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, double value) + PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, double value, int precision) { char buf[128]; - PUGI__SNPRINTF(buf, "%.17g", value); + PUGI__SNPRINTF(buf, "%.*g", precision, value); return set_value_ascii(dest, header, header_mask, buf); } @@ -4688,6 +4708,7 @@ PUGI__NS_BEGIN char_t* buffer = 0; size_t length = 0; + // coverity[var_deref_model] if (!impl::convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable)) return impl::make_parse_result(status_out_of_memory); // delete original buffer if we performed a conversion @@ -4960,7 +4981,12 @@ PUGI__NS_BEGIN #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR))) PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) { +#if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 + FILE* file = 0; + return _wfopen_s(&file, path, mode) == 0 ? file : 0; +#else return _wfopen(path, mode); +#endif } #else PUGI__FN char* convert_path_heap(const wchar_t* str) @@ -5004,6 +5030,16 @@ PUGI__NS_BEGIN } #endif + PUGI__FN FILE* open_file(const char* path, const char* mode) + { +#if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 + FILE* file = 0; + return fopen_s(&file, path, mode) == 0 ? file : 0; +#else + return fopen(path, mode); +#endif + } + PUGI__FN bool save_file_impl(const xml_document& doc, FILE* file, const char_t* indent, unsigned int flags, xml_encoding encoding) { if (!file) return false; @@ -5329,14 +5365,28 @@ namespace pugi { if (!_attr) return false; - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, default_double_precision); + } + + PUGI__FN bool xml_attribute::set_value(double rhs, int precision) + { + if (!_attr) return false; + + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, precision); } PUGI__FN bool xml_attribute::set_value(float rhs) { if (!_attr) return false; - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, default_float_precision); + } + + PUGI__FN bool xml_attribute::set_value(float rhs, int precision) + { + if (!_attr) return false; + + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, precision); } PUGI__FN bool xml_attribute::set_value(bool rhs) @@ -6046,6 +6096,27 @@ namespace pugi return true; } + PUGI__FN bool xml_node::remove_attributes() + { + if (!_root) return false; + + impl::xml_allocator& alloc = impl::get_allocator(_root); + if (!alloc.reserve()) return false; + + for (xml_attribute_struct* attr = _root->first_attribute; attr; ) + { + xml_attribute_struct* next = attr->next_attribute; + + impl::destroy_attribute(attr, alloc); + + attr = next; + } + + _root->first_attribute = 0; + + return true; + } + PUGI__FN bool xml_node::remove_child(const char_t* name_) { return remove_child(child(name_)); @@ -6064,6 +6135,27 @@ namespace pugi return true; } + PUGI__FN bool xml_node::remove_children() + { + if (!_root) return false; + + impl::xml_allocator& alloc = impl::get_allocator(_root); + if (!alloc.reserve()) return false; + + for (xml_node_struct* cur = _root->first_child; cur; ) + { + xml_node_struct* next = cur->next_sibling; + + impl::destroy_node(cur, alloc); + + cur = next; + } + + _root->first_child = 0; + + return true; + } + PUGI__FN xml_parse_result xml_node::append_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) { // append_buffer is only valid for elements/documents @@ -6164,16 +6256,9 @@ namespace pugi PUGI__FN xml_node xml_node::first_element_by_path(const char_t* path_, char_t delimiter) const { - xml_node found = *this; // Current search context. + xml_node context = path_[0] == delimiter ? root() : *this; - if (!_root || !path_[0]) return found; - - if (path_[0] == delimiter) - { - // Absolute path; e.g. '/foo/bar' - found = found.root(); - ++path_; - } + if (!context._root) return xml_node(); const char_t* path_segment = path_; @@ -6183,19 +6268,19 @@ namespace pugi while (*path_segment_end && *path_segment_end != delimiter) ++path_segment_end; - if (path_segment == path_segment_end) return found; + if (path_segment == path_segment_end) return context; const char_t* next_segment = path_segment_end; while (*next_segment == delimiter) ++next_segment; if (*path_segment == '.' && path_segment + 1 == path_segment_end) - return found.first_element_by_path(next_segment, delimiter); + return context.first_element_by_path(next_segment, delimiter); else if (*path_segment == '.' && *(path_segment+1) == '.' && path_segment + 2 == path_segment_end) - return found.parent().first_element_by_path(next_segment, delimiter); + return context.parent().first_element_by_path(next_segment, delimiter); else { - for (xml_node_struct* j = found._root->first_child; j; j = j->next_sibling) + for (xml_node_struct* j = context._root->first_child; j; j = j->next_sibling) { if (j->name && impl::strequalrange(j->name, path_segment, static_cast(path_segment_end - path_segment))) { @@ -6490,14 +6575,28 @@ namespace pugi { xml_node_struct* dn = _data_new(); - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, default_float_precision) : false; + } + + PUGI__FN bool xml_text::set(float rhs, int precision) + { + xml_node_struct* dn = _data_new(); + + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, precision) : false; } PUGI__FN bool xml_text::set(double rhs) { xml_node_struct* dn = _data_new(); - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, default_double_precision) : false; + } + + PUGI__FN bool xml_text::set(double rhs, int precision) + { + xml_node_struct* dn = _data_new(); + + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, precision) : false; } PUGI__FN bool xml_text::set(bool rhs) @@ -6873,8 +6972,7 @@ namespace pugi { reset(); - for (xml_node cur = proto.first_child(); cur; cur = cur.next_sibling()) - append_copy(cur); + impl::node_copy_tree(_root, proto._root); } PUGI__FN void xml_document::_create() @@ -7104,7 +7202,7 @@ namespace pugi reset(); using impl::auto_deleter; // MSVC7 workaround - auto_deleter file(fopen(path_, "rb"), impl::close_file); + auto_deleter file(impl::open_file(path_, "rb"), impl::close_file); return impl::load_file_impl(static_cast(_root), file.data, options, encoding, &_buffer); } @@ -7187,7 +7285,7 @@ namespace pugi PUGI__FN bool xml_document::save_file(const char* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const { using impl::auto_deleter; // MSVC7 workaround - auto_deleter file(fopen(path_, (flags & format_save_file_text) ? "w" : "wb"), impl::close_file); + auto_deleter file(impl::open_file(path_, (flags & format_save_file_text) ? "w" : "wb"), impl::close_file); return impl::save_file_impl(*this, file.data, indent, flags, encoding); } @@ -7331,14 +7429,14 @@ PUGI__NS_BEGIN } }; - template void swap(T& lhs, T& rhs) + template inline void swap(T& lhs, T& rhs) { T temp = lhs; lhs = rhs; rhs = temp; } - template I min_element(I begin, I end, const Pred& pred) + template PUGI__FN I min_element(I begin, I end, const Pred& pred) { I result = begin; @@ -7349,17 +7447,20 @@ PUGI__NS_BEGIN return result; } - template void reverse(I begin, I end) + template PUGI__FN void reverse(I begin, I end) { - while (end - begin > 1) swap(*begin++, *--end); + while (end - begin > 1) + swap(*begin++, *--end); } - template I unique(I begin, I end) + template PUGI__FN I unique(I begin, I end) { // fast skip head - while (end - begin > 1 && *begin != *(begin + 1)) begin++; + while (end - begin > 1 && *begin != *(begin + 1)) + begin++; - if (begin == end) return begin; + if (begin == end) + return begin; // last written element I write = begin++; @@ -7377,7 +7478,7 @@ PUGI__NS_BEGIN return write + 1; } - template void insertion_sort(T* begin, T* end, const Pred& pred) + template PUGI__FN void insertion_sort(T* begin, T* end, const Pred& pred) { if (begin == end) return; @@ -7399,16 +7500,19 @@ PUGI__NS_BEGIN } } - template I median3(I first, I middle, I last, const Pred& pred) + template inline I median3(I first, I middle, I last, const Pred& pred) { - if (pred(*middle, *first)) swap(middle, first); - if (pred(*last, *middle)) swap(last, middle); - if (pred(*middle, *first)) swap(middle, first); + if (pred(*middle, *first)) + swap(middle, first); + if (pred(*last, *middle)) + swap(last, middle); + if (pred(*middle, *first)) + swap(middle, first); return middle; } - template void partition3(T* begin, T* end, T pivot, const Pred& pred, T** out_eqbeg, T** out_eqend) + template PUGI__FN void partition3(T* begin, T* end, T pivot, const Pred& pred, T** out_eqbeg, T** out_eqend) { // invariant: array is split into 4 groups: = < ? > (each variable denotes the boundary between the groups) T* eq = begin; @@ -7435,7 +7539,7 @@ PUGI__NS_BEGIN *out_eqend = gt; } - template void sort(I begin, I end, const Pred& pred) + template PUGI__FN void sort(I begin, I end, const Pred& pred) { // sort large chunks while (end - begin > 16) @@ -7464,6 +7568,41 @@ PUGI__NS_BEGIN // insertion sort small chunk insertion_sort(begin, end, pred); } + + PUGI__FN bool hash_insert(const void** table, size_t size, const void* key) + { + assert(key); + + unsigned int h = static_cast(reinterpret_cast(key)); + + // MurmurHash3 32-bit finalizer + h ^= h >> 16; + h *= 0x85ebca6bu; + h ^= h >> 13; + h *= 0xc2b2ae35u; + h ^= h >> 16; + + size_t hashmod = size - 1; + size_t bucket = h & hashmod; + + for (size_t probe = 0; probe <= hashmod; ++probe) + { + if (table[bucket] == 0) + { + table[bucket] = key; + return true; + } + + if (table[bucket] == key) + return false; + + // hash collision, quadratic probing + bucket = (bucket + probe + 1) & hashmod; + } + + assert(false && "Hash table is full"); // unreachable + return false; + } PUGI__NS_END // Allocator used for AST and evaluation stacks @@ -8053,15 +8192,6 @@ PUGI__NS_BEGIN } }; - struct duplicate_comparator - { - bool operator()(const xpath_node& lhs, const xpath_node& rhs) const - { - if (lhs.attribute()) return rhs.attribute() ? lhs.attribute() < rhs.attribute() : true; - else return rhs.attribute() ? false : lhs.node() < rhs.node(); - } - }; - PUGI__FN double gen_nan() { #if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24)) @@ -8069,7 +8199,7 @@ PUGI__NS_BEGIN typedef uint32_t UI; // BCC5 workaround union { float f; UI i; } u; u.i = 0x7fc00000; - return u.f; + return double(u.f); #else // fallback const volatile double zero = 0.0; @@ -8849,12 +8979,42 @@ PUGI__NS_BEGIN _end = pos; } - void remove_duplicates() + void remove_duplicates(xpath_allocator* alloc) { - if (_type == xpath_node_set::type_unsorted) - sort(_begin, _end, duplicate_comparator()); + if (_type == xpath_node_set::type_unsorted && _end - _begin > 2) + { + xpath_allocator_capture cr(alloc); - _end = unique(_begin, _end); + size_t size_ = static_cast(_end - _begin); + + size_t hash_size = 1; + while (hash_size < size_ + size_ / 2) hash_size *= 2; + + const void** hash_data = static_cast(alloc->allocate(hash_size * sizeof(void**))); + if (!hash_data) return; + + memset(hash_data, 0, hash_size * sizeof(const void**)); + + xpath_node* write = _begin; + + for (xpath_node* it = _begin; it != _end; ++it) + { + const void* attr = it->attribute().internal_object(); + const void* node = it->node().internal_object(); + const void* key = attr ? attr : node; + + if (key && hash_insert(hash_data, hash_size, key)) + { + *write++ = *it; + } + } + + _end = write; + } + else + { + _end = unique(_begin, _end); + } } xpath_node_set::type_t type() const @@ -9611,7 +9771,7 @@ PUGI__NS_BEGIN { xpath_context c(*it, i, size); - if (expr->eval_number(c, stack) == i) + if (expr->eval_number(c, stack) == static_cast(i)) { *last++ = *it; @@ -9635,11 +9795,11 @@ PUGI__NS_BEGIN double er = expr->eval_number(c, stack); - if (er >= 1.0 && er <= size) + if (er >= 1.0 && er <= static_cast(size)) { size_t eri = static_cast(er); - if (er == eri) + if (er == static_cast(eri)) { xpath_node r = last[eri - 1]; @@ -10083,6 +10243,7 @@ PUGI__NS_BEGIN bool once = (axis == axis_attribute && _test == nodetest_name) || (!_right && eval_once(axis_type, eval)) || + // coverity[mixed_enums] (_right && !_right->_next && _right->_test == predicate_constant_one); xpath_node_set_raw ns; @@ -10115,7 +10276,7 @@ PUGI__NS_BEGIN // child, attribute and self axes always generate unique set of nodes // for other axis, if the set stayed sorted, it stayed unique because the traversal algorithms do not visit the same node twice if (axis != axis_child && axis != axis_attribute && axis != axis_self && ns.type() == xpath_node_set::type_unsorted) - ns.remove_duplicates(); + ns.remove_duplicates(stack.temp); return ns; } @@ -10275,35 +10436,38 @@ PUGI__NS_BEGIN if (_rettype == xpath_type_boolean) return _data.variable->get_boolean(); + + // variable needs to be converted to the correct type, this is handled by the fallthrough block below + break; } - // fallthrough default: - { - switch (_rettype) - { - case xpath_type_number: - return convert_number_to_boolean(eval_number(c, stack)); - - case xpath_type_string: - { - xpath_allocator_capture cr(stack.result); - - return !eval_string(c, stack).empty(); - } - - case xpath_type_node_set: - { - xpath_allocator_capture cr(stack.result); - - return !eval_node_set(c, stack, nodeset_eval_any).empty(); - } - - default: - assert(false && "Wrong expression for return type boolean"); // unreachable - return false; - } + ; } + + // none of the ast types that return the value directly matched, we need to perform type conversion + switch (_rettype) + { + case xpath_type_number: + return convert_number_to_boolean(eval_number(c, stack)); + + case xpath_type_string: + { + xpath_allocator_capture cr(stack.result); + + return !eval_string(c, stack).empty(); + } + + case xpath_type_node_set: + { + xpath_allocator_capture cr(stack.result); + + return !eval_node_set(c, stack, nodeset_eval_any).empty(); + } + + default: + assert(false && "Wrong expression for return type boolean"); // unreachable + return false; } } @@ -10410,36 +10574,38 @@ PUGI__NS_BEGIN if (_rettype == xpath_type_number) return _data.variable->get_number(); + + // variable needs to be converted to the correct type, this is handled by the fallthrough block below + break; } - // fallthrough default: - { - switch (_rettype) - { - case xpath_type_boolean: - return eval_boolean(c, stack) ? 1 : 0; - - case xpath_type_string: - { - xpath_allocator_capture cr(stack.result); - - return convert_string_to_number(eval_string(c, stack).c_str()); - } - - case xpath_type_node_set: - { - xpath_allocator_capture cr(stack.result); - - return convert_string_to_number(eval_string(c, stack).c_str()); - } - - default: - assert(false && "Wrong expression for return type number"); // unreachable - return 0; - } - + ; } + + // none of the ast types that return the value directly matched, we need to perform type conversion + switch (_rettype) + { + case xpath_type_boolean: + return eval_boolean(c, stack) ? 1 : 0; + + case xpath_type_string: + { + xpath_allocator_capture cr(stack.result); + + return convert_string_to_number(eval_string(c, stack).c_str()); + } + + case xpath_type_node_set: + { + xpath_allocator_capture cr(stack.result); + + return convert_string_to_number(eval_string(c, stack).c_str()); + } + + default: + assert(false && "Wrong expression for return type number"); // unreachable + return 0; } } @@ -10596,7 +10762,7 @@ PUGI__NS_BEGIN double first = round_nearest(_right->eval_number(c, stack)); if (is_nan(first)) return xpath_string(); // NaN - else if (first >= s_length + 1) return xpath_string(); + else if (first >= static_cast(s_length + 1)) return xpath_string(); size_t pos = first < 1 ? 1 : static_cast(first); assert(1 <= pos && pos <= s_length + 1); @@ -10620,12 +10786,12 @@ PUGI__NS_BEGIN double last = first + round_nearest(_right->_next->eval_number(c, stack)); if (is_nan(first) || is_nan(last)) return xpath_string(); - else if (first >= s_length + 1) return xpath_string(); + else if (first >= static_cast(s_length + 1)) return xpath_string(); else if (first >= last) return xpath_string(); else if (last < 1) return xpath_string(); size_t pos = first < 1 ? 1 : static_cast(first); - size_t end = last >= s_length + 1 ? s_length + 1 : static_cast(last); + size_t end = last >= static_cast(s_length + 1) ? s_length + 1 : static_cast(last); assert(1 <= pos && pos <= end && end <= s_length + 1); const char_t* rbegin = s.c_str() + (pos - 1); @@ -10694,34 +10860,37 @@ PUGI__NS_BEGIN if (_rettype == xpath_type_string) return xpath_string::from_const(_data.variable->get_string()); + + // variable needs to be converted to the correct type, this is handled by the fallthrough block below + break; } - // fallthrough default: - { - switch (_rettype) - { - case xpath_type_boolean: - return xpath_string::from_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); - - case xpath_type_number: - return convert_number_to_string(eval_number(c, stack), stack.result); - - case xpath_type_node_set: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_node_set_raw ns = eval_node_set(c, swapped_stack, nodeset_eval_first); - return ns.empty() ? xpath_string() : string_value(ns.first(), stack.result); - } - - default: - assert(false && "Wrong expression for return type string"); // unreachable - return xpath_string(); - } + ; } + + // none of the ast types that return the value directly matched, we need to perform type conversion + switch (_rettype) + { + case xpath_type_boolean: + return xpath_string::from_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); + + case xpath_type_number: + return convert_number_to_string(eval_number(c, stack), stack.result); + + case xpath_type_node_set: + { + xpath_allocator_capture cr(stack.temp); + + xpath_stack swapped_stack = {stack.temp, stack.result}; + + xpath_node_set_raw ns = eval_node_set(c, swapped_stack, nodeset_eval_first); + return ns.empty() ? xpath_string() : string_value(ns.first(), stack.result); + } + + default: + assert(false && "Wrong expression for return type string"); // unreachable + return xpath_string(); } } @@ -10735,16 +10904,16 @@ PUGI__NS_BEGIN xpath_stack swapped_stack = {stack.temp, stack.result}; - xpath_node_set_raw ls = _left->eval_node_set(c, swapped_stack, eval); - xpath_node_set_raw rs = _right->eval_node_set(c, stack, eval); + xpath_node_set_raw ls = _left->eval_node_set(c, stack, eval); + xpath_node_set_raw rs = _right->eval_node_set(c, swapped_stack, eval); // we can optimize merging two sorted sets, but this is a very rare operation, so don't bother - rs.set_type(xpath_node_set::type_unsorted); + ls.set_type(xpath_node_set::type_unsorted); - rs.append(ls.begin(), ls.end(), stack.result); - rs.remove_duplicates(); + ls.append(rs.begin(), rs.end(), stack.result); + ls.remove_duplicates(stack.temp); - return rs; + return ls; } case ast_filter: @@ -10843,13 +11012,18 @@ PUGI__NS_BEGIN return ns; } + + // variable needs to be converted to the correct type, this is handled by the fallthrough block below + break; } - // fallthrough default: - assert(false && "Wrong expression for return type node set"); // unreachable - return xpath_node_set_raw(); + ; } + + // none of the ast types that return the value directly matched, but conversions to node set are invalid + assert(false && "Wrong expression for return type node set"); // unreachable + return xpath_node_set_raw(); } void optimize(xpath_allocator* alloc) @@ -10863,6 +11037,7 @@ PUGI__NS_BEGIN if (_next) _next->optimize(alloc); + // coverity[var_deref_model] optimize_self(alloc); } @@ -10871,13 +11046,14 @@ PUGI__NS_BEGIN // Rewrite [position()=expr] with [expr] // Note that this step has to go before classification to recognize [position()=1] if ((_type == ast_filter || _type == ast_predicate) && + _right && // workaround for clang static analyzer (_right is never null for ast_filter/ast_predicate) _right->_type == ast_op_equal && _right->_left->_type == ast_func_position && _right->_right->_rettype == xpath_type_number) { _right = _right->_right; } // Classify filter/predicate ops to perform various optimizations during evaluation - if (_type == ast_filter || _type == ast_predicate) + if ((_type == ast_filter || _type == ast_predicate) && _right) // workaround for clang static analyzer (_right is never null for ast_filter/ast_predicate) { assert(_test == predicate_default); @@ -10893,8 +11069,8 @@ PUGI__NS_BEGIN // The former is a full form of //foo, the latter is much faster since it executes the node test immediately // Do a similar kind of rewrite for self/descendant/descendant-or-self axes // Note that we only rewrite positionally invariant steps (//foo[1] != /descendant::foo[1]) - if (_type == ast_step && (_axis == axis_child || _axis == axis_self || _axis == axis_descendant || _axis == axis_descendant_or_self) && _left && - _left->_type == ast_step && _left->_axis == axis_descendant_or_self && _left->_test == nodetest_type_node && !_left->_right && + if (_type == ast_step && (_axis == axis_child || _axis == axis_self || _axis == axis_descendant || _axis == axis_descendant_or_self) && + _left && _left->_type == ast_step && _left->_axis == axis_descendant_or_self && _left->_test == nodetest_type_node && !_left->_right && is_posinv_step()) { if (_axis == axis_child || _axis == axis_descendant) @@ -10906,7 +11082,9 @@ PUGI__NS_BEGIN } // Use optimized lookup table implementation for translate() with constant arguments - if (_type == ast_func_translate && _right->_type == ast_string_constant && _right->_next->_type == ast_string_constant) + if (_type == ast_func_translate && + _right && // workaround for clang static analyzer (_right is never null for ast_func_translate) + _right->_type == ast_string_constant && _right->_next->_type == ast_string_constant) { unsigned char* table = translate_table_generate(alloc, _right->_data.string, _right->_next->_data.string); @@ -10919,6 +11097,8 @@ PUGI__NS_BEGIN // Use optimized path for @attr = 'value' or @attr = $value if (_type == ast_op_equal && + _left && _right && // workaround for clang static analyzer and Coverity (_left and _right are never null for ast_op_equal) + // coverity[mixed_enums] _left->_type == ast_step && _left->_axis == axis_attribute && _left->_test == nodetest_name && !_left->_left && !_left->_right && (_right->_type == ast_string_constant || (_right->_type == ast_variable && _right->_rettype == xpath_type_string))) { @@ -10978,6 +11158,14 @@ PUGI__NS_BEGIN } }; + static const size_t xpath_ast_depth_limit = + #ifdef PUGIXML_XPATH_DEPTH_LIMIT + PUGIXML_XPATH_DEPTH_LIMIT + #else + 1024 + #endif + ; + struct xpath_parser { xpath_allocator* _alloc; @@ -10990,6 +11178,8 @@ PUGI__NS_BEGIN char_t _scratch[32]; + size_t _depth; + xpath_ast_node* error(const char* message) { _result->error = message; @@ -11006,6 +11196,11 @@ PUGI__NS_BEGIN return 0; } + xpath_ast_node* error_rec() + { + return error("Exceeded maximum allowed query depth"); + } + void* alloc_node() { return _alloc->allocate(sizeof(xpath_ast_node)); @@ -11361,6 +11556,8 @@ PUGI__NS_BEGIN return error("Unrecognized function call"); _lexer.next(); + size_t old_depth = _depth; + while (_lexer.current() != lex_close_brace) { if (argc > 0) @@ -11370,6 +11567,9 @@ PUGI__NS_BEGIN _lexer.next(); } + if (++_depth > xpath_ast_depth_limit) + return error_rec(); + xpath_ast_node* n = parse_expression(); if (!n) return 0; @@ -11382,6 +11582,8 @@ PUGI__NS_BEGIN _lexer.next(); + _depth = old_depth; + return parse_function(function, argc, args); } @@ -11398,10 +11600,15 @@ PUGI__NS_BEGIN xpath_ast_node* n = parse_primary_expression(); if (!n) return 0; + size_t old_depth = _depth; + while (_lexer.current() == lex_open_square_brace) { _lexer.next(); + if (++_depth > xpath_ast_depth_limit) + return error_rec(); + if (n->rettype() != xpath_type_node_set) return error("Predicate has to be applied to node set"); @@ -11417,6 +11624,8 @@ PUGI__NS_BEGIN _lexer.next(); } + _depth = old_depth; + return n; } @@ -11568,12 +11777,17 @@ PUGI__NS_BEGIN xpath_ast_node* n = alloc_node(ast_step, set, axis, nt_type, nt_name_copy); if (!n) return 0; + size_t old_depth = _depth; + xpath_ast_node* last = 0; while (_lexer.current() == lex_open_square_brace) { _lexer.next(); + if (++_depth > xpath_ast_depth_limit) + return error_rec(); + xpath_ast_node* expr = parse_expression(); if (!expr) return 0; @@ -11590,6 +11804,8 @@ PUGI__NS_BEGIN last = pred; } + _depth = old_depth; + return n; } @@ -11599,11 +11815,16 @@ PUGI__NS_BEGIN xpath_ast_node* n = parse_step(set); if (!n) return 0; + size_t old_depth = _depth; + while (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) { lexeme_t l = _lexer.current(); _lexer.next(); + if (++_depth > xpath_ast_depth_limit) + return error_rec(); + if (l == lex_double_slash) { n = alloc_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); @@ -11614,6 +11835,8 @@ PUGI__NS_BEGIN if (!n) return 0; } + _depth = old_depth; + return n; } @@ -11799,6 +12022,9 @@ PUGI__NS_BEGIN { _lexer.next(); + if (++_depth > xpath_ast_depth_limit) + return error_rec(); + xpath_ast_node* rhs = parse_path_or_unary_expression(); if (!rhs) return 0; @@ -11844,13 +12070,22 @@ PUGI__NS_BEGIN // | MultiplicativeExpr 'mod' UnaryExpr xpath_ast_node* parse_expression(int limit = 0) { + size_t old_depth = _depth; + + if (++_depth > xpath_ast_depth_limit) + return error_rec(); + xpath_ast_node* n = parse_path_or_unary_expression(); if (!n) return 0; - return parse_expression_rec(n, limit); + n = parse_expression_rec(n, limit); + + _depth = old_depth; + + return n; } - xpath_parser(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result): _alloc(alloc), _lexer(query), _query(query), _variables(variables), _result(result) + xpath_parser(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result): _alloc(alloc), _lexer(query), _query(query), _variables(variables), _result(result), _depth(0) { } @@ -11859,6 +12094,8 @@ PUGI__NS_BEGIN xpath_ast_node* n = parse_expression(); if (!n) return 0; + assert(_depth == 0); + // check if there are unparsed tokens left if (_lexer.current() != lex_eof) return error("Incorrect query"); @@ -12013,74 +12250,61 @@ namespace pugi size_t size_ = static_cast(end_ - begin_); - if (size_ <= 1) + // use internal buffer for 0 or 1 elements, heap buffer otherwise + xpath_node* storage = (size_ <= 1) ? _storage : static_cast(impl::xml_memory::allocate(size_ * sizeof(xpath_node))); + + if (!storage) { - // deallocate old buffer - if (_begin != &_storage) impl::xml_memory::deallocate(_begin); - - // use internal buffer - if (begin_ != end_) _storage = *begin_; - - _begin = &_storage; - _end = &_storage + size_; - _type = type_; + #ifdef PUGIXML_NO_EXCEPTIONS + return; + #else + throw std::bad_alloc(); + #endif } - else - { - // make heap copy - xpath_node* storage = static_cast(impl::xml_memory::allocate(size_ * sizeof(xpath_node))); - if (!storage) - { - #ifdef PUGIXML_NO_EXCEPTIONS - return; - #else - throw std::bad_alloc(); - #endif - } + // deallocate old buffer + if (_begin != _storage) + impl::xml_memory::deallocate(_begin); + // size check is necessary because for begin_ = end_ = nullptr, memcpy is UB + if (size_) memcpy(storage, begin_, size_ * sizeof(xpath_node)); - // deallocate old buffer - if (_begin != &_storage) impl::xml_memory::deallocate(_begin); - - // finalize - _begin = storage; - _end = storage + size_; - _type = type_; - } + _begin = storage; + _end = storage + size_; + _type = type_; } #ifdef PUGIXML_HAS_MOVE PUGI__FN void xpath_node_set::_move(xpath_node_set& rhs) PUGIXML_NOEXCEPT { _type = rhs._type; - _storage = rhs._storage; - _begin = (rhs._begin == &rhs._storage) ? &_storage : rhs._begin; + _storage[0] = rhs._storage[0]; + _begin = (rhs._begin == rhs._storage) ? _storage : rhs._begin; _end = _begin + (rhs._end - rhs._begin); rhs._type = type_unsorted; - rhs._begin = &rhs._storage; - rhs._end = rhs._begin; + rhs._begin = rhs._storage; + rhs._end = rhs._storage; } #endif - PUGI__FN xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(&_storage), _end(&_storage) + PUGI__FN xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(_storage), _end(_storage) { } - PUGI__FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_unsorted), _begin(&_storage), _end(&_storage) + PUGI__FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_unsorted), _begin(_storage), _end(_storage) { _assign(begin_, end_, type_); } PUGI__FN xpath_node_set::~xpath_node_set() { - if (_begin != &_storage) + if (_begin != _storage) impl::xml_memory::deallocate(_begin); } - PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(type_unsorted), _begin(&_storage), _end(&_storage) + PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(type_unsorted), _begin(_storage), _end(_storage) { _assign(ns._begin, ns._end, ns._type); } @@ -12095,7 +12319,7 @@ namespace pugi } #ifdef PUGIXML_HAS_MOVE - PUGI__FN xpath_node_set::xpath_node_set(xpath_node_set&& rhs) PUGIXML_NOEXCEPT: _type(type_unsorted), _begin(&_storage), _end(&_storage) + PUGI__FN xpath_node_set::xpath_node_set(xpath_node_set&& rhs) PUGIXML_NOEXCEPT: _type(type_unsorted), _begin(_storage), _end(_storage) { _move(rhs); } @@ -12104,7 +12328,7 @@ namespace pugi { if (this == &rhs) return *this; - if (_begin != &_storage) + if (_begin != _storage) impl::xml_memory::deallocate(_begin); _move(rhs); @@ -12771,7 +12995,7 @@ namespace pugi #endif /** - * Copyright (c) 2006-2018 Arseny Kapoulkine + * Copyright (c) 2006-2020 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/contrib/pugixml/src/pugixml.hpp b/contrib/pugixml/src/pugixml.hpp index 1775600f1..7e2ce7776 100644 --- a/contrib/pugixml/src/pugixml.hpp +++ b/contrib/pugixml/src/pugixml.hpp @@ -1,8 +1,8 @@ /** - * pugixml parser - version 1.9 + * pugixml parser - version 1.11 * -------------------------------------------------------- - * Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) - * Report bugs and download new versions at http://pugixml.org/ + * Copyright (C) 2006-2020, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Report bugs and download new versions at https://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end * of this file. @@ -12,8 +12,9 @@ */ #ifndef PUGIXML_VERSION -// Define version macro; evaluates to major * 100 + minor so that it's safe to use in less-than comparisons -# define PUGIXML_VERSION 190 +// Define version macro; evaluates to major * 1000 + minor * 10 + patch so that it's safe to use in less-than comparisons +// Note: pugixml used major * 100 + minor * 10 + patch format up until 1.9 (which had version identifier 190); starting from pugixml 1.10, the minor version number is two digits +# define PUGIXML_VERSION 1110 #endif // Include user configuration file (this can define various configuration macros) @@ -110,6 +111,15 @@ # endif #endif +// If C++ is 2011 or higher, use 'nullptr' +#ifndef PUGIXML_NULL +# if __cplusplus >= 201103 +# define PUGIXML_NULL nullptr +# else +# define PUGIXML_NULL 0 +# endif +#endif + // Character interface macros #ifdef PUGIXML_WCHAR_MODE # define PUGIXML_TEXT(t) L ## t @@ -252,10 +262,19 @@ namespace pugi // Don't output empty element tags, instead writing an explicit start and end tag even if there are no children. This flag is off by default. const unsigned int format_no_empty_element_tags = 0x80; + // Skip characters belonging to range [0; 32) instead of "&#xNN;" encoding. This flag is off by default. + const unsigned int format_skip_control_chars = 0x100; + + // Use single quotes ' instead of double quotes " for enclosing attribute values. This flag is off by default. + const unsigned int format_attribute_single_quote = 0x200; + // The default set of formatting flags. // Nodes are indented depending on their depth in DOM tree, a default declaration is output if document has none. const unsigned int format_default = format_indent; + const int default_double_precision = 17; + const int default_float_precision = 9; + // Forward declarations struct xml_attribute_struct; struct xml_node_struct; @@ -403,7 +422,9 @@ namespace pugi bool set_value(long rhs); bool set_value(unsigned long rhs); bool set_value(double rhs); + bool set_value(double rhs, int precision); bool set_value(float rhs); + bool set_value(float rhs, int precision); bool set_value(bool rhs); #ifdef PUGIXML_HAS_LONG_LONG @@ -569,10 +590,16 @@ namespace pugi bool remove_attribute(const xml_attribute& a); bool remove_attribute(const char_t* name); + // Remove all attributes + bool remove_attributes(); + // Remove specified child bool remove_child(const xml_node& n); bool remove_child(const char_t* name); + // Remove all children + bool remove_children(); + // Parses buffer as an XML document fragment and appends all nodes as children of the current node. // Copies/converts the buffer, so it may be deleted or changed after the function returns. // Note: append_buffer allocates memory that has the lifetime of the owning document; removing the appended nodes does not immediately reclaim that memory. @@ -643,15 +670,15 @@ namespace pugi #ifndef PUGIXML_NO_XPATH // Select single node by evaluating XPath query. Returns first node from the resulting node set. - xpath_node select_node(const char_t* query, xpath_variable_set* variables = 0) const; + xpath_node select_node(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const; xpath_node select_node(const xpath_query& query) const; // Select node set by evaluating XPath query - xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = 0) const; + xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const; xpath_node_set select_nodes(const xpath_query& query) const; // (deprecated: use select_node instead) Select single node by evaluating XPath query. - PUGIXML_DEPRECATED xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = 0) const; + PUGIXML_DEPRECATED xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const; PUGIXML_DEPRECATED xpath_node select_single_node(const xpath_query& query) const; #endif @@ -754,7 +781,9 @@ namespace pugi bool set(long rhs); bool set(unsigned long rhs); bool set(double rhs); + bool set(double rhs, int precision); bool set(float rhs); + bool set(float rhs, int precision); bool set(bool rhs); #ifdef PUGIXML_HAS_LONG_LONG @@ -1192,7 +1221,7 @@ namespace pugi public: // Construct a compiled object from XPath expression. // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors. - explicit xpath_query(const char_t* query, xpath_variable_set* variables = 0); + explicit xpath_query(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL); // Constructor xpath_query(); @@ -1251,11 +1280,12 @@ namespace pugi }; #ifndef PUGIXML_NO_EXCEPTIONS - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning( disable: 4275 ) -#endif + #if defined(_MSC_VER) + // C4275 can be ignored in Visual C++ if you are deriving + // from a type in the Standard C++ Library + #pragma warning(push) + #pragma warning(disable: 4275) + #endif // XPath exception class class PUGIXML_CLASS xpath_exception: public std::exception { @@ -1272,10 +1302,11 @@ namespace pugi // Get parse result const xpath_parse_result& result() const; }; + #if defined(_MSC_VER) + #pragma warning(pop) + #endif #endif -#ifdef _MSC_VER -# pragma warning(pop) -#endif + // XPath node class (either xml_node or xml_attribute) class PUGIXML_CLASS xpath_node { @@ -1379,7 +1410,7 @@ namespace pugi private: type_t _type; - xpath_node _storage; + xpath_node _storage[1]; xpath_node* _begin; xpath_node* _end; @@ -1443,7 +1474,7 @@ namespace std #endif /** - * Copyright (c) 2006-2018 Arseny Kapoulkine + * Copyright (c) 2006-2020 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation From bf0f8d4c1b2f53a457b4e1834abf7f841ef30300 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 3 Jun 2021 23:29:53 +0200 Subject: [PATCH 93/93] Update pugiconfig.hpp --- contrib/pugixml/src/pugiconfig.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/pugixml/src/pugiconfig.hpp b/contrib/pugixml/src/pugiconfig.hpp index 405a66b65..03f854bf1 100644 --- a/contrib/pugixml/src/pugiconfig.hpp +++ b/contrib/pugixml/src/pugiconfig.hpp @@ -44,7 +44,7 @@ // #define PUGIXML_XPATH_DEPTH_LIMIT 1024 // Uncomment this to switch to header-only version -// #define PUGIXML_HEADER_ONLY +#define PUGIXML_HEADER_ONLY // Uncomment this to enable long long support // #define PUGIXML_HAS_LONG_LONG