diff --git a/.gitignore b/.gitignore index 2a3b68a50..60884061d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ build bin/ lib/ +# QtCreator +CMakeLists.txt.user # Generated assimp.pc @@ -38,6 +40,7 @@ tools/assimp_cmd/Makefile # Tests test/results +test/readlinetest* # Python __pycache__ diff --git a/CHANGES b/CHANGES index d5faab2e0..c0c73b98c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,264 @@ ---------------------------------------------------------------------- CHANGELOG ---------------------------------------------------------------------- +4.1.0 (2017-12): +- FEATURES: + - Export 3MF ( experimental ) + - Import / Export glTF 2 + - Introduce new zib-lib to eb able to export zip-archives +- FIXES/HOUSEKEEPING: + - Added missing include to stdlib.h and remove load library call + - Fix install for builds with MSVC compiler and NMake. + - Update list of supported file formats. + - Add TriLib to the official list of supported ports. + - Re-enabling PACK_STRUCT for MDL files. + - Use std.::unique_ptr + - Update D3MFExporter.h + - Update MD3Loader.cpp, using index + - Fix all warnings on MSVC14 + - Copy assimp dll to unit folder on windows + - Update jvm port supported formats + - Add support for building Mac OS X Framework bundles + - Check for nullptr dereferencing before copying scene data + - Update ValidateDataStructure.h, typo + - Enable data structure validation in cases where it doesn't cause failures + - Remove some dead assignments + - fast_atof: Silence some uninitialized variable warnings + - Check for area test if the face is a triangle. + - Set mNumUVComponents to 0 when deleting texture coordinate sets + - Only scale the root node because this will rescale all children nodes as well. + - Issue 1514: Fix frame pointer arithmetic + - Prevent failing stringstream to crash the export process + - powf -> pow + - add Defines.h to include folder for install. + - Android: + - Fix android build + - Fix assimp for cross compile for android + - Use define for D_FILE_OFFSET_BITS only for not-android systems. + - FBX: + - Fix handling with embedded textures + - FBX 7500 Binary reading + - Remove dead assignment + - Fix export of deleted meshes; Add LazyDict::Remove method + - Log an error instead of letting the fbx-importer crash. ( issue 213 ) + - Replace bad pointer casting with memcpy + - Remove useless const qualifier from return value + - Add explicit instantiation of log_prefix so other FBX source files can see it + - add missing inversion of postrotation matrix for fbx. + - FIReader: Silence uninitialized variable warning + - Update version check in FBX reader to check for version >= 7500 + - Use actual min/max of anim keys when start/stop time is missing +- GLTF1: + - Fix output of glTF 1 version string + - Fix delete / delete[] mismatch in glTFAsset + - Don’t ignore rgba(1,1,1,1) color properties + - glTF2 primitives fixes + - Don’t ignore rgba(1,1,1,1) color properties + - Fix delete / delete[] mismatch in glTFAsset + - Remove KHR_binary_glTF code + - glTF nodes can only hold one mesh. this simply assigns to and check’s a Node’s Mesh + - version in glb header is stored as uint32_t +- GLTF2: + - node name conflict fix + - Fix transform matrices multiplication order + - Preserve node names when importing + - Add support for tangents in import + - Fix typo on gltf2 camera parameters + - Moved byteStride from accessor to bufferView + - Implemented reading binary glTF2 (glb) files + - Fix signed/unsigned warning + - Add postprocess step for scaling + - Fix shininess to roughness conversion + - Prefer “BLEND” over “MASK” as an alphaMode default + - Approximate specularity / glossiness in metallicRoughness materials + - Diffuse color and diffuse texture import and export improvements + - Addressed some mismatched news/deletes caused by the new glTF2 sources. + - Fix delete / delete[] mismatches in glTF2 importer + - use correct name of exporter to gltf2 + - Fix possible infinite loop when exporting to gltf2 + - Fix glTF2::Asset::FindUniqueID() when the input string is >= 256 chars + - Fix glTF2 alphaMode storage and reading + - Fix glTF 2.0 multi-primitive support + - Load gltf .bin files from correct directory + - Add support for importing both glTF and glTF2 files + - ampler improvements; Add new LazyDict method + - Changes to GLTF2 materials + - Remove Light, Technique references + - Start removing materials common, and adding pbrSpecularGlossiness + - Use !ObjectEmpty() vs. MemberCount() > 0 + - Working read, import, export, and write of gltf2 (pbr) material + - Check in gltf2 models to test directory + - Remove un-needed test models + - Start managing and importing gltf2 pbr materials + - Update glTF2 Asset to use indexes + - Duplicate gltfImporter as gltf2Importer; Include glTF2 importer in CMake List + - glTF2: Fix animation export + - use opacity for diffuse alpha + alphaMode +- STL: + - Restore import of multi mesh binary STLs +- Blender: + - Silence warning about uninitialized member +- MDLImporter: + - Don't take address of packed struct member +- assimp_cmd: + - Fix strict-aliasing warnings +- Open3DGC: + - Fix strict-aliasing warnings + - Add assertions to silence static analyzer warnings + - Remove redundant const qualifiers from return types + - Fix some uninitialized variable warnings + - Remove OPEN3DGC and compression references +- unzip: + - Remove dead assignment + - Bail on bad compression method + - Fix possibly uninitialized variables +- clipper: + - Add assertion to silence a static analyzer warning +- OpenDDLExport: + - Reduce scope of a variable + - Remove dead variable + - Remove dead assignment + - Fix another potential memory leak +- X3DImporter: + - Add assertions to silence static analyzer warnings + - Add missing unittest + - Workaround for buggy Android NDK (issue #1361) +- TerragenLoader: + - Remove unused variable +- SIBImporter: + - Add assertions to silence static analyzer warnings +- IFC: + - Remove dead code + - Add explicit instantiation of log_prefix so IFCMaterial.cpp can see it +- PLY: + - Remove dead assignment and reduce scope of a variable + - fix vertex attribute lookup. +- OpenGEX: + - Add assertion to silence a static analyzer warning + - Fix for TextureFile with number in file name + - Return early when element is TextureFile +- NFF: + - Add assertions to silence static analyzer warnings + - Split up some complicated assignments +- Raw: Fix misleading indentation warning + - Reduce scope of a variable +- LWO + - Reduce scope of a variable +- IRRLoader: + - Fix confusing boolean casting +- AssbinExporter: + - Add assertion to silence a static analyzer warning +- ASE: + - Add assertion to silence a static analyzer warning +- AMFImporter: + - Add assertion to silence a static analyzer warning + - Add a block +- OptimizeGraph: + - Fix possible null pointer dereference + - RemoveRedundantMaterials: + - Add assertion to silence a static analyzer warning +- ImproveCacheLocality: + - Add assertion to silence a static analyzer warning +- RemoveRedundantMaterials: + - Set pointer to nullptr after deleting it +- Travis: + - Disable unit tests in scan-build config + - Move slower builds earlier to improve parallelization + - Add static analysis to build + - Remove unused branch rule for travis. + - Add Clang UBSan build configuration + - Treat warnings as errors, without typos this time +- Unittests: + - Add VS-based source groups for the unittests. +- Collada: + - export tag + - Update ColladaExporter.cpp + - Silence uninitialized variable warning + - Add support for line strip primitives +- Obj Wavefront: + - check in exporting against out-of-bounds-access . + - Issue 1351: use correct name for obj-meshname export for groups. + - fix mem-lead: face will be not released in case of an error. + - Anatoscope obj exporter nomtl + - Raise exception when obj file contains invalid face indices + - Added alternative displacement texture token in OBJ MTL material. + - Obj: rename attribute from exporter. + - Fix OBJ discarding all material names if the material library is missing +- Step: + - use correct lookup for utf32 +- MD2: + - Fix MD2 frames containing garbage +- STL + - add missing const. + - Fix memory-alignment bug. + - Fix issue 104: deal with more solids in one STL file. +- CMake + - Fix issue 213: use correct include folder for assimp +- Doxygen + - Fix issue 1513: put irrXML onto exclucde list for doxygen run +- PyAssimp: + - Search for libassimp.so in LD_LIBRARY_PATH if available. + - Fix operator precedence issue in header check + - Split setup.py into multiple lines + - Detect if Anaconda and fixed 3d_viewer for Python 3 + - created a python3 version of the 3dviewer and fixed the / = float in py3 +- Blender: + - Fix invalid access to mesh array when the array is empty. + - Fix short overflow. + - Silence warning about inline function which is declared but not defined +- JAssimp + - Changed license header for IHMC contributions from Apache 2.0 to BSD + - Add Node metadata to the Jassmip Java API + - Added supported for custom IO Systems in Java. Implemented ClassLoader IO System + - Added a link to pure jvm assimp port +- Clang sanitizer: + - Undefined Behavior sanitizer + - Fixed a divide by zero error in IFCBoolean that was latent, but nevertheless a bug +- B3DImporter: + - Replace bad pointer casting with memcpy +- AppVeyor: + - Cleanup and Addition of VS 2017 and running Tests + - Fixed File Size reported as 0 in tests that use temporary files + - x86 isn't a valid VS platform. Win32 it is, then. + - Replaced the worker image name, which doesn't work as generator name, with a manually created generator name. + - Cleaned up appveyor setup, added VS 2017 to the build matrix and attempted to add running of tests. + - Treat warnings as errors on Appveyor + - Disable warning 4351 on MSVC 2013 +- OpenGEXImporter: + - Copy materials to scene + - Store RefInfo in unique_ptr so they get automatically cleaned up + - Fix IOStream leak + - Store ChildInfo in unique_ptr so they get automatically cleaned up + - improve logging to be able to detect error-prone situations. +- AMFImporter: + - Fix memory leak +- UnrealLoader: + - Fix IOStream leak +- Upgrade RapidJSON to get rid of a clang warning +- zlib: + - Update zlib contribution + - Removed unnecessary files from zlib contribution + - Replaced unsigned long for the crc table to z_crc_t, to match what is returned by get-crc_table +- MakeVerboseFormat: + - Fix delete / delete[] mismatches in MakeVerboseFormat +- MaterialSystem: + - Fix out-of-bounds read in MaterialSystem unit test +- SIB: + - Added support for SIB models from Silo 2.5 +- AssbinExporter: + - Fix strict aliasing violation + - Add Write specialization for aiColor3D +- DefaultLogger: + - Whitespace cleanup to fix GCC misleading indentation warning +- MDP: + - Fix encoding issues. + - PreTransformVertices: + - fix name lost in mesh and nodes when load with flag +- C4D: + - Fixes for C4D importer +- Unzip: + - Latest greatest. + 4.0.1 (2017-07-28) - FIXES/HOUSEKEEPING: - fix version test. diff --git a/CMakeLists.txt b/CMakeLists.txt index cb407c4b1..9d13db57a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,7 @@ EXECUTE_PROCESS( # Get the latest abbreviated commit hash of the working branch EXECUTE_PROCESS( - COMMAND git log -1 --format=%h + COMMAND git log -1 --format=%h --no-show-signature WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE GIT_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE @@ -412,32 +412,7 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS ) ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY ) ADD_SUBDIRECTORY( tools/assimp_cmd/ ) - - # Check dependencies for assimp_qt_viewer. - # Why here? Maybe user do not want Qt viewer and have no Qt. - # Why assimp_qt_viewer/CMakeLists.txt still contain similar check? - # Because viewer can be build independently of Assimp. - FIND_PACKAGE(Qt5Widgets QUIET) - FIND_PACKAGE(DevIL QUIET) - FIND_PACKAGE(OpenGL QUIET) - IF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND) - ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ ) - ELSE() - SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "") - IF (NOT Qt5_FOUND) - SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5") - ENDIF (NOT Qt5_FOUND) - - IF (NOT IL_FOUND) - SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} DevIL") - ENDIF (NOT IL_FOUND) - - IF (NOT OPENGL_FOUND) - SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL") - ENDIF (NOT OPENGL_FOUND) - - MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}") - ENDIF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND) + ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ ) ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS ) IF ( ASSIMP_BUILD_SAMPLES) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..82ef07a65 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,10 @@ +# How to contribute + +If you want to contribute, follow these steps: + +- First, create your own clone of assimp. +- When you want to fix a bug or add a new feature, create a branch on your own fork following [these instructions](https://help.github.com/articles/creating-a-pull-request-from-a-fork/). +- Push it to your fork of the repository and open a pull request. +- A pull request will start our continuous integration service, which checks if the build works for Linux and Windows. + It will check for memory leaks, compiler warnings and memory alignment issues. If any of these tests fail, fix it and the tests will be restarted automatically. + - At the end, we will perform a code review and merge your branch to the master branch. diff --git a/INSTALL b/INSTALL index 3baaddc4a..357918d6b 100644 --- a/INSTALL +++ b/INSTALL @@ -42,3 +42,6 @@ For Windows: 1. Open a command prompt 2. cmake CMakeLists.txt 2. Open your default IDE and build it + +For iOS: +Just check the following project, which deploys a compiler toolchain for different iOS-versions: https://github.com/assimp/assimp/tree/master/port/iOS diff --git a/Readme.md b/Readme.md index c78a0c1c8..449efc547 100644 --- a/Readme.md +++ b/Readme.md @@ -140,8 +140,6 @@ Open Asset Import Library is implemented in C++. The directory structure is: /tools Tools (old assimp viewer, command line `assimp`) /samples A small number of samples to illustrate possible use cases for Assimp - /workspaces Build environments for vc,xcode,... (deprecated, - CMake has superseeded all legacy build options!) ### Where to get help ### diff --git a/appveyor.yml b/appveyor.yml index 1b87286f6..2b5f212f9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -32,6 +32,9 @@ install: - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017 - if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64 - cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%" + - set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5" + - ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/5/7/b/57b2947c-7221-4f33-b35e-2fc78cb10df4/vc_redist.x64.exe -OutFile .\packaging\windows-innosetup\vc_redist.x64.exe + - ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/1/d/8/1d8137db-b5bb-4925-8c5d-927424a2e4de/vc_redist.x86.exe -OutFile .\packaging\windows-innosetup\vc_redist.x86.exe cache: - code\assimp.dir\%CONFIGURATION% @@ -50,6 +53,7 @@ build: project: Assimp.sln after_build: + - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" iscc packaging\windows-innosetup\script.iss - 7z a assimp.7z bin\%CONFIGURATION%\* lib\%CONFIGURATION%\* test_script: diff --git a/code/3DSConverter.cpp b/code/3DSConverter.cpp index 081da1bcf..7ec79ba64 100644 --- a/code/3DSConverter.cpp +++ b/code/3DSConverter.cpp @@ -120,7 +120,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() else if ( (*a) >= mScene->mMaterials.size()) { (*a) = idx; - DefaultLogger::get()->warn("Material index overflow in 3DS file. Using default material"); + ASSIMP_LOG_WARN("Material index overflow in 3DS file. Using default material"); ++cnt; } } @@ -132,7 +132,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f); mScene->mMaterials.push_back(sMat); - DefaultLogger::get()->info("3DS: Generating default material"); + ASSIMP_LOG_INFO("3DS: Generating default material"); } } @@ -147,12 +147,12 @@ void Discreet3DSImporter::CheckIndices(D3DS::Mesh& sMesh) { if ((*i).mIndices[a] >= sMesh.mPositions.size()) { - DefaultLogger::get()->warn("3DS: Vertex index overflow)"); + ASSIMP_LOG_WARN("3DS: Vertex index overflow)"); (*i).mIndices[a] = (uint32_t)sMesh.mPositions.size()-1; } if ( !sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size()) { - DefaultLogger::get()->warn("3DS: Texture coordinate index overflow)"); + ASSIMP_LOG_WARN("3DS: Texture coordinate index overflow)"); (*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size()-1; } } @@ -204,8 +204,9 @@ void CopyTexture(aiMaterial& mat, D3DS::Texture& texture, aiTextureType type) mat.AddProperty( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0)); // Setup the texture mapping mode - mat.AddProperty((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0)); - mat.AddProperty((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0)); + int mapMode = static_cast(texture.mMapMode); + mat.AddProperty(&mapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0)); + mat.AddProperty(&mapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0)); // Mirroring - double the scaling values // FIXME: this is not really correct ... @@ -313,7 +314,8 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat, case D3DS::Discreet3DS::Blinn : eShading = aiShadingMode_Blinn; break; } - mat.AddProperty( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL); + int eShading_ = static_cast(eShading); + mat.AddProperty(&eShading_, 1, AI_MATKEY_SHADING_MODEL); // DIFFUSE texture if( oldMat.sTexDiffuse.mMapName.length() > 0) @@ -497,7 +499,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, pvCurrent->x *= -1.f; t2->x *= -1.f; } - DefaultLogger::get()->info("3DS: Flipping mesh X-Axis"); + ASSIMP_LOG_INFO("3DS: Flipping mesh X-Axis"); } // Handle pivot point @@ -573,11 +575,11 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, pcIn->aTargetPositionKeys.size() > 1) { aiAnimation* anim = pcSOut->mAnimations[0]; - ai_assert(NULL != anim); + ai_assert(nullptr != anim); if (pcIn->aCameraRollKeys.size() > 1) { - DefaultLogger::get()->debug("3DS: Converting camera roll track ..."); + ASSIMP_LOG_DEBUG("3DS: Converting camera roll track ..."); // Camera roll keys - in fact they're just rotations // around the camera's z axis. The angles are given @@ -597,7 +599,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, #if 0 if (pcIn->aTargetPositionKeys.size() > 1) { - DefaultLogger::get()->debug("3DS: Converting target track ..."); + ASSIMP_LOG_DEBUG("3DS: Converting target track ..."); // Camera or spot light - need to convert the separate // target position channel to our representation @@ -743,7 +745,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut) // | | | | | // MESH_0 MESH_1 MESH_2 ... MESH_N CAMERA_0 .... // - DefaultLogger::get()->warn("No hierarchy information has been found in the file. "); + ASSIMP_LOG_WARN("No hierarchy information has been found in the file. "); pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes + static_cast(mScene->mCameras.size() + mScene->mLights.size()); diff --git a/code/3DSExporter.cpp b/code/3DSExporter.cpp index fcd24d8aa..53976b16f 100644 --- a/code/3DSExporter.cpp +++ b/code/3DSExporter.cpp @@ -381,7 +381,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type // TODO: handle embedded textures properly if (path.data[0] == '*') { - DefaultLogger::get()->error("Ignoring embedded texture for export: " + std::string(path.C_Str())); + ASSIMP_LOG_ERROR("Ignoring embedded texture for export: " + std::string(path.C_Str())); return; } diff --git a/code/3DSLoader.cpp b/code/3DSLoader.cpp index bfe2bf6e5..cd79b0a6d 100644 --- a/code/3DSLoader.cpp +++ b/code/3DSLoader.cpp @@ -71,7 +71,7 @@ static const aiImporterDesc desc = { 0, 0, 0, - "3ds prj 3DS PRJ" + "3ds prj" }; @@ -127,7 +127,7 @@ Discreet3DSImporter::~Discreet3DSImporter() { // Returns whether the class can handle the format of the given file. bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { std::string extension = GetExtension(pFile); - if(extension == "3ds" || extension == "3DS" || extension == "prj"|| extension == "PRJ" ) { + if(extension == "3ds" || extension == "prj") { return true; } @@ -258,8 +258,9 @@ void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk* pcOut) if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSize()) throw DeadlyImportError("Chunk is too large"); - if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit()) - DefaultLogger::get()->error("3DS: Chunk overflow"); + if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit()) { + ASSIMP_LOG_ERROR("3DS: Chunk overflow"); + } } // ------------------------------------------------------------------------------------------------ @@ -320,7 +321,7 @@ void Discreet3DSImporter::ParseEditorChunk() // print the version number char buff[10]; ASSIMP_itoa10(buff,stream->GetI2()); - DefaultLogger::get()->info(std::string("3DS file format version: ") + buff); + ASSIMP_LOG_INFO_F(std::string("3DS file format version: "), buff); } break; }; @@ -361,7 +362,7 @@ void Discreet3DSImporter::ParseObjectChunk() if (is_qnan(mClrAmbient.r)) { // We failed to read the ambient base color. - DefaultLogger::get()->error("3DS: Failed to read ambient base color"); + ASSIMP_LOG_ERROR("3DS: Failed to read ambient base color"); mClrAmbient.r = mClrAmbient.g = mClrAmbient.b = 0.0f; } break; @@ -463,7 +464,7 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num) if (len < 1e-5) { // There are some files with lookat == position. Don't know why or whether it's ok or not. - DefaultLogger::get()->error("3DS: Unable to read proper camera look-at vector"); + ASSIMP_LOG_ERROR("3DS: Unable to read proper camera look-at vector"); camera->mLookAt = aiVector3D(0.0,1.0,0.0); } @@ -629,9 +630,9 @@ void Discreet3DSImporter::SkipTCBInfo() if (!flags) { // Currently we can't do anything with these values. They occur // quite rare, so it wouldn't be worth the effort implementing - // them. 3DS ist not really suitable for complex animations, + // them. 3DS is not really suitable for complex animations, // so full support is not required. - DefaultLogger::get()->warn("3DS: Skipping TCB animation info"); + ASSIMP_LOG_WARN("3DS: Skipping TCB animation info"); } if (flags & Discreet3DS::KEY_USE_TENS) { @@ -732,7 +733,6 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) // If object name is DUMMY, take this one instead if (mCurrentNode->mName == "$$$DUMMY") { - //DefaultLogger::get()->warn("3DS: Skipping dummy object name for non-dummy object"); mCurrentNode->mName = std::string(sz); break; } @@ -743,7 +743,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) if ( Discreet3DS::CHUNK_TRACKINFO != parent) { - DefaultLogger::get()->warn("3DS: Skipping pivot subchunk for non usual object"); + ASSIMP_LOG_WARN("3DS: Skipping pivot subchunk for non usual object"); break; } @@ -805,7 +805,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) { // roll keys are accepted for cameras only if (parent != Discreet3DS::CHUNK_TRACKCAMERA) { - DefaultLogger::get()->warn("3DS: Ignoring roll track for non-camera object"); + ASSIMP_LOG_WARN("3DS: Ignoring roll track for non-camera object"); break; } bool sortKeys = false; @@ -845,7 +845,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) // CAMERA FOV KEYFRAME case Discreet3DS::CHUNK_TRACKFOV: { - DefaultLogger::get()->error("3DS: Skipping FOV animation track. " + ASSIMP_LOG_ERROR("3DS: Skipping FOV animation track. " "This is not supported"); } break; @@ -985,7 +985,7 @@ void Discreet3DSImporter::ParseFaceChunk() } } if (0xcdcdcdcd == idx) { - DefaultLogger::get()->error(std::string("3DS: Unknown material: ") + sz); + ASSIMP_LOG_ERROR_F( "3DS: Unknown material: ", sz); } // Now continue and read all material indices @@ -995,7 +995,7 @@ void Discreet3DSImporter::ParseFaceChunk() // check range if (fidx >= mMesh.mFaceMaterials.size()) { - DefaultLogger::get()->error("3DS: Invalid face index in face material list"); + ASSIMP_LOG_ERROR("3DS: Invalid face index in face material list"); } else mMesh.mFaceMaterials[fidx] = idx; }} @@ -1110,7 +1110,7 @@ void Discreet3DSImporter::ParseMaterialChunk() if (!cnt) { // This may not be, we use the default name instead - DefaultLogger::get()->error("3DS: Empty material name"); + ASSIMP_LOG_ERROR("3DS: Empty material name"); } else mScene->mMaterials.back().mName = std::string(sz,cnt); } @@ -1123,7 +1123,7 @@ void Discreet3DSImporter::ParseMaterialChunk() ParseColorChunk(pc); if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it - DefaultLogger::get()->error("3DS: Unable to read DIFFUSE chunk"); + ASSIMP_LOG_ERROR("3DS: Unable to read DIFFUSE chunk"); pc->r = pc->g = pc->b = 1.0f; }} break; @@ -1135,7 +1135,7 @@ void Discreet3DSImporter::ParseMaterialChunk() ParseColorChunk(pc); if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it - DefaultLogger::get()->error("3DS: Unable to read SPECULAR chunk"); + ASSIMP_LOG_ERROR("3DS: Unable to read SPECULAR chunk"); pc->r = pc->g = pc->b = 1.0f; }} break; @@ -1147,7 +1147,7 @@ void Discreet3DSImporter::ParseMaterialChunk() ParseColorChunk(pc); if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it - DefaultLogger::get()->error("3DS: Unable to read AMBIENT chunk"); + ASSIMP_LOG_ERROR("3DS: Unable to read AMBIENT chunk"); pc->r = pc->g = pc->b = 0.0f; }} break; @@ -1159,7 +1159,7 @@ void Discreet3DSImporter::ParseMaterialChunk() ParseColorChunk(pc); if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it - DefaultLogger::get()->error("3DS: Unable to read EMISSIVE chunk"); + ASSIMP_LOG_ERROR("3DS: Unable to read EMISSIVE chunk"); pc->r = pc->g = pc->b = 0.0f; }} break; @@ -1293,7 +1293,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut) pcOut->mScaleU = stream->GetF4(); if (0.0f == pcOut->mScaleU) { - DefaultLogger::get()->warn("Texture coordinate scaling in the x direction is zero. Assuming 1."); + ASSIMP_LOG_WARN("Texture coordinate scaling in the x direction is zero. Assuming 1."); pcOut->mScaleU = 1.0f; } break; @@ -1302,7 +1302,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut) pcOut->mScaleV = stream->GetF4(); if (0.0f == pcOut->mScaleV) { - DefaultLogger::get()->warn("Texture coordinate scaling in the y direction is zero. Assuming 1."); + ASSIMP_LOG_WARN("Texture coordinate scaling in the y direction is zero. Assuming 1."); pcOut->mScaleV = 1.0f; } break; diff --git a/code/ACLoader.cpp b/code/ACLoader.cpp index 3f8653d5d..7b8afbe9b 100644 --- a/code/ACLoader.cpp +++ b/code/ACLoader.cpp @@ -85,7 +85,7 @@ static const aiImporterDesc desc = { #define AI_AC_SKIP_TO_NEXT_TOKEN() \ if (!SkipSpaces(&buffer)) \ { \ - DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL"); \ + ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL"); \ continue; \ } @@ -101,7 +101,7 @@ static const aiImporterDesc desc = { { \ if (IsLineEnd( *buffer )) \ { \ - DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL in string"); \ + ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string"); \ out = "ERROR"; \ break; \ } \ @@ -120,7 +120,7 @@ static const aiImporterDesc desc = { { \ if (strncmp(buffer,name,name_length) || !IsSpace(buffer[name_length])) \ { \ - DefaultLogger::get()->error("AC3D: Unexpexted token. " name " was expected."); \ + ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " name " was expected."); \ continue; \ } \ buffer += name_length+1; \ @@ -217,7 +217,7 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i",static_cast(mLights->size())-1); obj.name = std::string( light->mName.data ); - DefaultLogger::get()->debug("AC3D: Light source encountered"); + ASSIMP_LOG_DEBUG("AC3D: Light source encountered"); obj.type = Object::Light; } else if (!ASSIMP_strincmp(buffer,"group",5)) @@ -307,12 +307,12 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) { if (!GetNextLine()) { - DefaultLogger::get()->error("AC3D: Unexpected EOF: not all vertices have been parsed yet"); + ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet"); break; } else if (!IsNumeric(*buffer)) { - DefaultLogger::get()->error("AC3D: Unexpected token: not all vertices have been parsed yet"); + ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet"); --buffer; // make sure the line is processed a second time break; } @@ -338,8 +338,8 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) // example writes no surf chunks if (!Q3DWorkAround) { - DefaultLogger::get()->warn("AC3D: SURF token was expected"); - DefaultLogger::get()->debug("Continuing with Quick3D Workaround enabled"); + ASSIMP_LOG_WARN("AC3D: SURF token was expected"); + ASSIMP_LOG_DEBUG("Continuing with Quick3D Workaround enabled"); } --buffer; // make sure the line is processed a second time // break; --- see fix notes above @@ -384,7 +384,7 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) { if(!GetNextLine()) { - DefaultLogger::get()->error("AC3D: Unexpected EOF: surface references are incomplete"); + ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: surface references are incomplete"); break; } surf.entries.push_back(Surface::SurfaceEntry()); @@ -405,7 +405,7 @@ void AC3DImporter::LoadObjectSection(std::vector& objects) } } } - DefaultLogger::get()->error("AC3D: Unexpected EOF: \'kids\' line was expected"); + ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: \'kids\' line was expected"); } // ------------------------------------------------------------------------------------------------ @@ -478,7 +478,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, therefore: if no surfaces are defined return point data only */ - DefaultLogger::get()->info("AC3D: No surfaces defined in object definition, " + ASSIMP_LOG_INFO("AC3D: No surfaces defined in object definition, " "a point list is returned"); meshes.push_back(new aiMesh()); @@ -519,12 +519,12 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, unsigned int idx = (*it).mat; if (idx >= needMat.size()) { - DefaultLogger::get()->error("AC3D: material index is out of range"); + ASSIMP_LOG_ERROR("AC3D: material index is out of range"); idx = 0; } if ((*it).entries.empty()) { - DefaultLogger::get()->warn("AC3D: surface her zero vertex references"); + ASSIMP_LOG_WARN("AC3D: surface her zero vertex references"); } // validate all vertex indices to make sure we won't crash here @@ -533,7 +533,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, { if ((*it2).first >= object.vertices.size()) { - DefaultLogger::get()->warn("AC3D: Invalid vertex reference"); + ASSIMP_LOG_WARN("AC3D: Invalid vertex reference"); (*it2).first = 0; } } @@ -561,7 +561,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, if ((*it).flags & 0xf) { - DefaultLogger::get()->warn("AC3D: The type flag of a surface is unknown"); + ASSIMP_LOG_WARN("AC3D: The type flag of a surface is unknown"); (*it).flags &= ~(0xf); } @@ -712,7 +712,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, if (object.subDiv) { if (configEvalSubdivision) { std::unique_ptr div(Subdivider::Create(Subdivider::CATMULL_CLARKE)); - DefaultLogger::get()->info("AC3D: Evaluating subdivision surface: "+object.name); + ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: "+object.name); std::vector cpy(meshes.size()-oldm,NULL); div->Subdivide(&meshes[oldm],cpy.size(),&cpy.front(),object.subDiv,true); @@ -721,7 +721,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object, // previous meshes are deleted vy Subdivide(). } else { - DefaultLogger::get()->info("AC3D: Letting the subdivision surface untouched due to my configuration: " + ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: " +object.name); } } @@ -813,7 +813,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile, unsigned int version = HexDigitToDecimal( buffer[4] ); char msg[3]; ASSIMP_itoa10(msg,3,version); - DefaultLogger::get()->info(std::string("AC3D file format version: ") + msg); + ASSIMP_LOG_INFO_F("AC3D file format version: ", msg); std::vector materials; materials.reserve(5); @@ -857,7 +857,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile, } if (materials.empty()) { - DefaultLogger::get()->warn("AC3D: No material has been found"); + ASSIMP_LOG_WARN("AC3D: No material has been found"); materials.push_back(Material()); } diff --git a/code/AMFImporter.cpp b/code/AMFImporter.cpp index d20be6b9f..e5b41b3ad 100644 --- a/code/AMFImporter.cpp +++ b/code/AMFImporter.cpp @@ -230,7 +230,7 @@ casu_cres: if(!skipped_before[sk_idx]) { skipped_before[sk_idx] = true; - LogWarning("Skipping node \"" + nn + "\" in " + pParentNodeName + "."); + ASSIMP_LOG_WARN_F("Skipping node \"", nn, "\" in ", pParentNodeName, "."); } } diff --git a/code/AMFImporter.hpp b/code/AMFImporter.hpp index 060cbf10a..3c60caeab 100644 --- a/code/AMFImporter.hpp +++ b/code/AMFImporter.hpp @@ -358,18 +358,6 @@ private: /************** Functions: LOG set *************/ /***********************************************/ - /// \fn void LogInfo(const std::string& pMessage) - /// Short variant for calling \ref DefaultLogger::get()->info() - void LogInfo(const std::string& pMessage) { DefaultLogger::get()->info(pMessage); } - - /// \fn void LogWarning(const std::string& pMessage) - /// Short variant for calling \ref DefaultLogger::get()->warn() - void LogWarning(const std::string& pMessage) { DefaultLogger::get()->warn(pMessage); } - - /// \fn void LogError(const std::string& pMessage) - /// Short variant for calling \ref DefaultLogger::get()->error() - void LogError(const std::string& pMessage) { DefaultLogger::get()->error(pMessage); } - /***********************************************/ /************** Functions: XML set *************/ /***********************************************/ diff --git a/code/AMFImporter_Macro.hpp b/code/AMFImporter_Macro.hpp index afa120028..ea8c17850 100644 --- a/code/AMFImporter_Macro.hpp +++ b/code/AMFImporter_Macro.hpp @@ -71,7 +71,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } /// \def MACRO_ATTRREAD_CHECK_REF -/// Check curent attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then +/// Check current attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then /// "continue" will called. /// \param [in] pAttrName - attribute name. /// \param [out] pVarName - output variable name. @@ -84,7 +84,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } /// \def MACRO_ATTRREAD_CHECK_RET -/// Check curent attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction. +/// Check current attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction. /// If result was read then "continue" will called. /// \param [in] pAttrName - attribute name. /// \param [out] pVarName - output variable name. @@ -130,7 +130,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } while(false) /// \def MACRO_NODECHECK_READCOMP_F -/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "float". +/// Check current node name and if it equal to requested then read value. Result write to output variable of type "float". /// If result was read then "continue" will called. Also check if node data already read then raise exception. /// \param [in] pNodeName - node name. /// \param [in, out] pReadFlag - read flag. @@ -147,7 +147,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } /// \def MACRO_NODECHECK_READCOMP_U32 -/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "uint32_t". +/// Check current node name and if it equal to requested then read value. Result write to output variable of type "uint32_t". /// If result was read then "continue" will called. Also check if node data already read then raise exception. /// \param [in] pNodeName - node name. /// \param [in, out] pReadFlag - read flag. diff --git a/code/AMFImporter_Material.cpp b/code/AMFImporter_Material.cpp index 77f49d39e..2f65ad833 100644 --- a/code/AMFImporter_Material.cpp +++ b/code/AMFImporter_Material.cpp @@ -99,7 +99,7 @@ CAMFImporter_NodeElement* ne; ParseHelper_Node_Exit(); // check that all components was defined if(!(read_flag[0] && read_flag[1] && read_flag[2])) throw DeadlyImportError("Not all color components are defined."); - // check if is absent. Then manualy add "a == 1". + // check if is absent. Then manually add "a == 1". if(!read_flag[3]) als.Color.a = 1; }// if(!mReader->isEmptyElement()) diff --git a/code/AMFImporter_Postprocess.cpp b/code/AMFImporter_Postprocess.cpp index 192544fcb..a6ee8fa2f 100644 --- a/code/AMFImporter_Postprocess.cpp +++ b/code/AMFImporter_Postprocess.cpp @@ -770,7 +770,7 @@ std::list ch_node; // find referenced object if(!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID); - // create node for apllying transformation + // create node for applying transformation t_node = new aiNode; t_node->mParent = con_node; // apply transformation diff --git a/code/ASELoader.cpp b/code/ASELoader.cpp index 32b0eae2d..1808f25e2 100644 --- a/code/ASELoader.cpp +++ b/code/ASELoader.cpp @@ -200,7 +200,7 @@ void ASEImporter::InternReadFile( const std::string& pFile, ConvertMeshes(*i,avOutMeshes); } if (tookNormals) { - DefaultLogger::get()->debug("ASE: Taking normals from the file. Use " + ASSIMP_LOG_DEBUG("ASE: Taking normals from the file. Use " "the AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS setting if you " "experience problems"); } @@ -297,15 +297,15 @@ void ASEImporter::BuildAnimations(const std::vector& nodes) // TODO: Implement Bezier & TCB support if ((*i)->mAnim.mPositionType != ASE::Animation::TRACK) { - DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. " + ASSIMP_LOG_WARN("ASE: Position controller uses Bezier/TCB keys. " "This is not supported."); } if ((*i)->mAnim.mRotationType != ASE::Animation::TRACK) { - DefaultLogger::get()->warn("ASE: Rotation controller uses Bezier/TCB keys. " + ASSIMP_LOG_WARN("ASE: Rotation controller uses Bezier/TCB keys. " "This is not supported."); } if ((*i)->mAnim.mScalingType != ASE::Animation::TRACK) { - DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. " + ASSIMP_LOG_WARN("ASE: Position controller uses Bezier/TCB keys. " "This is not supported."); } @@ -624,7 +624,7 @@ void ASEImporter::AddNodes (const std::vector& nodes, node->mNumChildren++; // What we did is so great, it is at least worth a debug message - DefaultLogger::get()->debug("ASE: Generating separate target node ("+snode->mName+")"); + ASSIMP_LOG_DEBUG("ASE: Generating separate target node ("+snode->mName+")"); } } @@ -947,7 +947,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh // validate the material index of the mesh if (mesh.iMaterialIndex >= mParser->m_vMaterials.size()) { mesh.iMaterialIndex = (unsigned int)mParser->m_vMaterials.size()-1; - DefaultLogger::get()->warn("Material index is out of range"); + ASSIMP_LOG_WARN("Material index is out of range"); } // If the material the mesh is assigned to is consisting of submeshes, split it @@ -957,11 +957,11 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMesh std::vector* aiSplit = new std::vector[vSubMaterials.size()]; - // build a list of all faces per submaterial + // build a list of all faces per sub-material for (unsigned int i = 0; i < mesh.mFaces.size();++i) { // check range if (mesh.mFaces[i].iMaterial >= vSubMaterials.size()) { - DefaultLogger::get()->warn("Submaterial index is out of range"); + ASSIMP_LOG_WARN("Submaterial index is out of range"); // use the last material instead aiSplit[vSubMaterials.size()-1].push_back(i); diff --git a/code/ASEParser.cpp b/code/ASEParser.cpp index b953f8d96..298c6fe61 100644 --- a/code/ASEParser.cpp +++ b/code/ASEParser.cpp @@ -151,7 +151,7 @@ void Parser::LogWarning(const char* szWarn) #endif // output the warning to the logger ... - DefaultLogger::get()->warn(szTemp); + ASSIMP_LOG_WARN(szTemp); } // ------------------------------------------------------------------------------------------------ @@ -167,7 +167,7 @@ void Parser::LogInfo(const char* szWarn) #endif // output the information to the logger ... - DefaultLogger::get()->info(szTemp); + ASSIMP_LOG_INFO(szTemp); } // ------------------------------------------------------------------------------------------------ @@ -758,7 +758,7 @@ void Parser::ParseLV3MapBlock(Texture& map) SkipToNextToken(); if (temp != "Bitmap" && temp != "Normal Bump") { - DefaultLogger::get()->warn("ASE: Skipping unknown map type: " + temp); + ASSIMP_LOG_WARN_F("ASE: Skipping unknown map type: ", temp); parsePath = false; } continue; @@ -773,7 +773,7 @@ void Parser::ParseLV3MapBlock(Texture& map) { // Files with 'None' as map name are produced by // an Maja to ASE exporter which name I forgot .. - DefaultLogger::get()->warn("ASE: Skipping invalid map entry"); + ASSIMP_LOG_WARN("ASE: Skipping invalid map entry"); map.mMapName = ""; } @@ -1072,7 +1072,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh) ( mesh.mType != BaseNode::Light || ((ASE::Light&)mesh).mLightType != ASE::Light::TARGET)) { - DefaultLogger::get()->error("ASE: Found target animation channel " + ASSIMP_LOG_ERROR("ASE: Found target animation channel " "but the node is neither a camera nor a spot light"); anim = NULL; } @@ -1098,7 +1098,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh) if (!anim || anim == &mesh.mTargetAnim) { // Target animation channels may have no rotation channels - DefaultLogger::get()->error("ASE: Ignoring scaling channel in target animation"); + ASSIMP_LOG_ERROR("ASE: Ignoring scaling channel in target animation"); SkipSection(); } else ParseLV3ScaleAnimationBlock(*anim); @@ -1112,7 +1112,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh) if (!anim || anim == &mesh.mTargetAnim) { // Target animation channels may have no rotation channels - DefaultLogger::get()->error("ASE: Ignoring rotation channel in target animation"); + ASSIMP_LOG_ERROR("ASE: Ignoring rotation channel in target animation"); SkipSection(); } else ParseLV3RotAnimationBlock(*anim); @@ -1295,12 +1295,14 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode& mesh) { mode = 2; } - else DefaultLogger::get()->error("ASE: Ignoring target transform, " - "this is no spot light or target camera"); + else { + ASSIMP_LOG_ERROR("ASE: Ignoring target transform, " + "this is no spot light or target camera"); + } } else { - DefaultLogger::get()->error("ASE: Unknown node transformation: " + temp); + ASSIMP_LOG_ERROR("ASE: Unknown node transformation: " + temp); // mode = 0 } continue; @@ -1916,7 +1918,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh) else if (index == face.mIndices[2]) index = 2; else { - DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_VERTEXNORMAL section"); + ASSIMP_LOG_ERROR("ASE: Invalid vertex index in MESH_VERTEXNORMAL section"); continue; } // We'll renormalize later @@ -1928,7 +1930,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh) ParseLV4MeshFloatTriple(&vNormal.x,faceIdx); if (faceIdx >= sMesh.mFaces.size()) { - DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_FACENORMAL section"); + ASSIMP_LOG_ERROR("ASE: Invalid vertex index in MESH_FACENORMAL section"); continue; } diff --git a/code/ASEParser.h b/code/ASEParser.h index 8715fdfab..70eb3de66 100644 --- a/code/ASEParser.h +++ b/code/ASEParser.h @@ -427,7 +427,7 @@ public: // ------------------------------------------------------------------- //! Construct a parser from a given input file which is - //! guaranted to be terminated with zero. + //! guaranteed to be terminated with zero. //! @param szFile Input file //! @param fileFormatDefault Assumed file format version. If the //! file format is specified in the file the new value replaces diff --git a/code/Assimp.cpp b/code/Assimp.cpp index 44e3ed563..b682d257b 100644 --- a/code/Assimp.cpp +++ b/code/Assimp.cpp @@ -146,7 +146,7 @@ private: // ------------------------------------------------------------------------------------------------ void ReportSceneNotFoundError() { - DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. " + ASSIMP_LOG_ERROR("Unable to find the Assimp::Importer for this aiScene. " "The C-API does not accept scenes produced by the C++ API and vice versa"); ai_assert(false); diff --git a/code/B3DImporter.cpp b/code/B3DImporter.cpp index e4572f8eb..ce8bd5159 100644 --- a/code/B3DImporter.cpp +++ b/code/B3DImporter.cpp @@ -614,7 +614,7 @@ void B3DImporter::ReadBB3D( aiScene *scene ){ if (!DefaultLogger::isNullLogger()) { char dmp[128]; ai_snprintf(dmp, 128, "B3D file format version: %i",version); - DefaultLogger::get()->info(dmp); + ASSIMP_LOG_INFO(dmp); } while( ChunkSize() ){ diff --git a/code/BaseImporter.cpp b/code/BaseImporter.cpp index 4782e9e2d..c7d10865e 100644 --- a/code/BaseImporter.cpp +++ b/code/BaseImporter.cpp @@ -64,23 +64,24 @@ using namespace Assimp; // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer BaseImporter::BaseImporter() -: m_progress() -{ +: m_progress() { // nothing to do here } // ------------------------------------------------------------------------------------------------ // Destructor, private as well -BaseImporter::~BaseImporter() -{ +BaseImporter::~BaseImporter() { // nothing to do here } // ------------------------------------------------------------------------------------------------ // Imports the given file and returns the imported data. -aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) -{ +aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) { m_progress = pImp->GetProgressHandler(); + if (nullptr == m_progress) { + return nullptr; + } + ai_assert(m_progress); // Gather configuration properties for this run @@ -100,8 +101,8 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, } catch( const std::exception& err ) { // extract error description m_ErrorText = err.what(); - DefaultLogger::get()->error(m_ErrorText); - return NULL; + ASSIMP_LOG_ERROR(m_ErrorText); + return nullptr; } // return what we gathered from the import. @@ -142,7 +143,8 @@ void BaseImporter::GetExtensionList(std::set& extensions) { const char** tokens, unsigned int numTokens, unsigned int searchBytes /* = 200 */, - bool tokensSol /* false */) + bool tokensSol /* false */, + bool noAlphaBeforeTokens /* false */) { ai_assert( nullptr != tokens ); ai_assert( 0 != numTokens ); @@ -192,10 +194,15 @@ void BaseImporter::GetExtensionList(std::set& extensions) { if( !r ) { continue; } + // 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]))) { + continue; + } // 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') { - DefaultLogger::get()->debug(std::string("Found positive match for header keyword: ") + tokens[i]); + ASSIMP_LOG_DEBUG_F( "Found positive match for header keyword: ", tokens[i] ); return true; } } @@ -322,7 +329,7 @@ void BaseImporter::ConvertToUTF8(std::vector& data) // UTF 8 with BOM if((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) { - DefaultLogger::get()->debug("Found UTF-8 BOM ..."); + ASSIMP_LOG_DEBUG("Found UTF-8 BOM ..."); std::copy(data.begin()+3,data.end(),data.begin()); data.resize(data.size()-3); @@ -341,7 +348,7 @@ void BaseImporter::ConvertToUTF8(std::vector& data) // UTF 32 LE with BOM if(*((uint32_t*)&data.front()) == 0x0000FFFE) { - DefaultLogger::get()->debug("Found UTF-32 BOM ..."); + ASSIMP_LOG_DEBUG("Found UTF-32 BOM ..."); std::vector output; int *ptr = (int*)&data[ 0 ]; @@ -361,7 +368,7 @@ void BaseImporter::ConvertToUTF8(std::vector& data) // UTF 16 LE with BOM if(*((uint16_t*)&data.front()) == 0xFEFF) { - DefaultLogger::get()->debug("Found UTF-16 BOM ..."); + ASSIMP_LOG_DEBUG("Found UTF-16 BOM ..."); std::vector output; utf8::utf16to8(data.begin(), data.end(), back_inserter(output)); @@ -386,16 +393,14 @@ void BaseImporter::ConvertUTF8toISO8859_1(std::string& data) data[j] = ((unsigned char) data[++i] + 0x40); } else { std::stringstream stream; - stream << "UTF8 code " << std::hex << data[i] << data[i + 1] << " can not be converted into ISA-8859-1."; - - DefaultLogger::get()->error(stream.str()); + ASSIMP_LOG_ERROR( stream.str() ); data[j++] = data[i++]; data[j] = data[i]; } } else { - DefaultLogger::get()->error("UTF8 code but only one character remaining"); + ASSIMP_LOG_ERROR("UTF8 code but only one character remaining"); data[j] = data[i]; } @@ -411,7 +416,7 @@ void BaseImporter::TextFileToBuffer(IOStream* stream, std::vector& data, TextFileMode mode) { - ai_assert(NULL != stream); + ai_assert(nullptr != stream); const size_t fileSize = stream->FileSize(); if (mode == FORBID_EMPTY) { @@ -472,14 +477,14 @@ struct Assimp::BatchData { , pImporter( nullptr ) , next_id(0xffff) , validate( validate ) { - ai_assert( NULL != pIO ); + ai_assert( nullptr != pIO ); pImporter = new Importer(); pImporter->SetIOHandler( pIO ); } ~BatchData() { - pImporter->SetIOHandler( NULL ); /* get pointer back into our possession */ + pImporter->SetIOHandler( nullptr ); /* get pointer back into our possession */ delete pImporter; } @@ -505,9 +510,8 @@ struct Assimp::BatchData { typedef std::list::iterator LoadReqIt; // ------------------------------------------------------------------------------------------------ -BatchLoader::BatchLoader(IOSystem* pIO, bool validate ) -{ - ai_assert(NULL != pIO); +BatchLoader::BatchLoader(IOSystem* pIO, bool validate ) { + ai_assert(nullptr != pIO); m_data = new BatchData( pIO, validate ); } @@ -573,7 +577,7 @@ aiScene* BatchLoader::GetImport( unsigned int which ) return sc; } } - return NULL; + return nullptr; } // ------------------------------------------------------------------------------------------------ @@ -596,13 +600,13 @@ void BatchLoader::LoadAll() if (!DefaultLogger::isNullLogger()) { - DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%"); - DefaultLogger::get()->info("File: " + (*it).file); + ASSIMP_LOG_INFO("%%% BEGIN EXTERNAL FILE %%%"); + ASSIMP_LOG_INFO_F("File: ", (*it).file); } m_data->pImporter->ReadFile((*it).file,pp); (*it).scene = m_data->pImporter->GetOrphanedScene(); (*it).loaded = true; - DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%"); + ASSIMP_LOG_INFO("%%% END EXTERNAL FILE %%%"); } } diff --git a/code/BaseProcess.cpp b/code/BaseProcess.cpp index 8508f59e4..ba968a819 100644 --- a/code/BaseProcess.cpp +++ b/code/BaseProcess.cpp @@ -85,7 +85,7 @@ void BaseProcess::ExecuteOnScene( Importer* pImp) // extract error description pImp->Pimpl()->mErrorString = err.what(); - DefaultLogger::get()->error(pImp->Pimpl()->mErrorString); + ASSIMP_LOG_ERROR(pImp->Pimpl()->mErrorString); // and kill the partially imported data delete pImp->Pimpl()->mScene; diff --git a/code/BlenderCustomData.cpp b/code/BlenderCustomData.cpp new file mode 100644 index 000000000..682186618 --- /dev/null +++ b/code/BlenderCustomData.cpp @@ -0,0 +1,185 @@ +#include "BlenderCustomData.h" +#include "BlenderDNA.h" +#include +#include + +namespace Assimp { + namespace Blender { + /** + * @brief read/convert of Structure array to memory + */ + template + bool read(const Structure &s, T *p, const size_t cnt, const FileDatabase &db) { + for (size_t i = 0; i < cnt; ++i) { + T read; + s.Convert(read, db); + *p = read; + p++; + } + return true; + } + + /** + * @brief pointer to function read memory for n CustomData types + */ + typedef bool (*PRead)(ElemBase *pOut, const size_t cnt, const FileDatabase &db); + typedef ElemBase * (*PCreate)(const size_t cnt); + typedef void(*PDestroy)(ElemBase *); + +#define IMPL_STRUCT_READ(ty) \ + bool read##ty(ElemBase *v, const size_t cnt, const FileDatabase &db) { \ + return read(db.dna[#ty], dynamic_cast(v), cnt, db); \ + } + +#define IMPL_STRUCT_CREATE(ty) \ + ElemBase *create##ty(const size_t cnt) { \ + return new ty[cnt]; \ + } + +#define IMPL_STRUCT_DESTROY(ty) \ + void destroy##ty(ElemBase *pE) { \ + ty *p = dynamic_cast(pE); \ + delete[]p; \ + } + + /** + * @brief helper macro to define Structure functions + */ +#define IMPL_STRUCT(ty) \ + IMPL_STRUCT_READ(ty) \ + IMPL_STRUCT_CREATE(ty) \ + IMPL_STRUCT_DESTROY(ty) + + // supported structures for CustomData + IMPL_STRUCT(MVert) + IMPL_STRUCT(MEdge) + IMPL_STRUCT(MFace) + IMPL_STRUCT(MTFace) + IMPL_STRUCT(MTexPoly) + IMPL_STRUCT(MLoopUV) + IMPL_STRUCT(MLoopCol) + IMPL_STRUCT(MPoly) + IMPL_STRUCT(MLoop) + + /** + * @brief describes the size of data and the read function to be used for single CustomerData.type + */ + struct CustomDataTypeDescription { + PRead Read; ///< function to read one CustomData type element + PCreate Create; ///< function to allocate n type elements + PDestroy Destroy; + + CustomDataTypeDescription(PRead read, PCreate create, PDestroy destroy) + : Read(read) + , Create(create) + , Destroy(destroy) + {} + }; + + + /** + * @brief helper macro to define Structure type specific CustomDataTypeDescription + * @note IMPL_STRUCT_READ for same ty must be used earlier to implement the typespecific read function + */ +#define DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(ty) \ + CustomDataTypeDescription{&read##ty, &create##ty, &destroy##ty} + + /** + * @brief helper macro to define CustomDataTypeDescription for UNSUPPORTED type + */ +#define DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION \ + CustomDataTypeDescription{nullptr, nullptr, nullptr} + + /** + * @brief descriptors for data pointed to from CustomDataLayer.data + * @note some of the CustomData uses already well defined Structures + * other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures + * use a special readfunction for that cases + */ + std::array customDataTypeDescriptions = { { + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert), + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge), + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MFace), + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTFace), + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTexPoly), + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopUV), + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopCol), + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MPoly), + DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoop), + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION, + DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION + }}; + + + bool isValidCustomDataType(const int cdtype) { + return cdtype >= 0 && cdtype < CD_NUMTYPES; + } + + bool readCustomData(std::shared_ptr &out, const int cdtype, const size_t cnt, const FileDatabase &db) { + if (!isValidCustomDataType(cdtype)) { + throw Error((Formatter::format(), "CustomData.type ", cdtype, " out of index")); + } + + const CustomDataTypeDescription cdtd = customDataTypeDescriptions[cdtype]; + if (cdtd.Read && cdtd.Create && cdtd.Destroy && cnt > 0) { + // allocate cnt elements and parse them from file + out.reset(cdtd.Create(cnt), cdtd.Destroy); + return cdtd.Read(out.get(), cnt, db); + } + return false; + } + + std::shared_ptr getCustomDataLayer(const CustomData &customdata, const CustomDataType cdtype, const std::string &name) { + for (auto it = customdata.layers.begin(); it != customdata.layers.end(); ++it) { + if (it->get()->type == cdtype && name == it->get()->name) { + return *it; + } + } + return nullptr; + } + + const ElemBase * getCustomDataLayerData(const CustomData &customdata, const CustomDataType cdtype, const std::string &name) + { + const std::shared_ptr pLayer = getCustomDataLayer(customdata, cdtype, name); + if (pLayer && pLayer->data) { + return pLayer->data.get(); + } + return nullptr; + } + } +} diff --git a/code/BlenderCustomData.h b/code/BlenderCustomData.h new file mode 100644 index 000000000..f61d79a26 --- /dev/null +++ b/code/BlenderCustomData.h @@ -0,0 +1,89 @@ +#pragma once + +#include "BlenderDNA.h" +#include "BlenderScene.h" +#include + +namespace Assimp { + namespace Blender { + /* CustomData.type from Blender (2.79b) */ + enum CustomDataType { + CD_AUTO_FROM_NAME = -1, + CD_MVERT = 0, +#ifdef DNA_DEPRECATED + CD_MSTICKY = 1, /* DEPRECATED */ +#endif + CD_MDEFORMVERT = 2, + CD_MEDGE = 3, + CD_MFACE = 4, + CD_MTFACE = 5, + CD_MCOL = 6, + CD_ORIGINDEX = 7, + CD_NORMAL = 8, + /* CD_POLYINDEX = 9, */ + CD_PROP_FLT = 10, + CD_PROP_INT = 11, + CD_PROP_STR = 12, + CD_ORIGSPACE = 13, /* for modifier stack face location mapping */ + CD_ORCO = 14, + CD_MTEXPOLY = 15, + CD_MLOOPUV = 16, + CD_MLOOPCOL = 17, + CD_TANGENT = 18, + CD_MDISPS = 19, + CD_PREVIEW_MCOL = 20, /* for displaying weightpaint colors */ + /* CD_ID_MCOL = 21, */ + CD_TEXTURE_MLOOPCOL = 22, + CD_CLOTH_ORCO = 23, + CD_RECAST = 24, + + /* BMESH ONLY START */ + CD_MPOLY = 25, + CD_MLOOP = 26, + CD_SHAPE_KEYINDEX = 27, + CD_SHAPEKEY = 28, + CD_BWEIGHT = 29, + CD_CREASE = 30, + CD_ORIGSPACE_MLOOP = 31, + CD_PREVIEW_MLOOPCOL = 32, + CD_BM_ELEM_PYPTR = 33, + /* BMESH ONLY END */ + + CD_PAINT_MASK = 34, + CD_GRID_PAINT_MASK = 35, + CD_MVERT_SKIN = 36, + CD_FREESTYLE_EDGE = 37, + CD_FREESTYLE_FACE = 38, + CD_MLOOPTANGENT = 39, + CD_TESSLOOPNORMAL = 40, + CD_CUSTOMLOOPNORMAL = 41, + + CD_NUMTYPES = 42 + }; + + /** + * @brief check if given cdtype is valid (ie >= 0 and < CD_NUMTYPES) + * @param[in] cdtype to check + * @return true when valid + */ + bool isValidCustomDataType(const int cdtype); + + /** + * @brief returns CustomDataLayer ptr for given cdtype and name + * @param[in] customdata CustomData to search for wanted layer + * @param[in] cdtype to search for + * @param[in] name to search for + * @return CustomDataLayer * or nullptr if not found + */ + std::shared_ptr getCustomDataLayer(const CustomData &customdata, CustomDataType cdtype, const std::string &name); + + /** + * @brief returns CustomDataLayer data ptr for given cdtype and name + * @param[in] customdata CustomData to search for wanted layer + * @param[in] cdtype to search for + * @param[in] name to search for + * @return * to struct data or nullptr if not found + */ + const ElemBase * getCustomDataLayerData(const CustomData &customdata, CustomDataType cdtype, const std::string &name); + } +} diff --git a/code/BlenderDNA.cpp b/code/BlenderDNA.cpp index 1d88f8fa6..f84c45601 100644 --- a/code/BlenderDNA.cpp +++ b/code/BlenderDNA.cpp @@ -210,8 +210,7 @@ void DNAParser::Parse () s.size = offset; } - DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(), - " structures with totally ",fields," fields")); + ASSIMP_LOG_DEBUG_F( "BlenderDNA: Got ", dna.structures.size()," structures with totally ",fields," fields"); #ifdef ASSIMP_BUILD_BLENDER_DEBUG dna.DumpToFile(); @@ -228,12 +227,12 @@ void DNAParser::Parse () // ------------------------------------------------------------------------------------------------ void DNA :: DumpToFile() { - // we dont't bother using the VFS here for this is only for debugging. + // we don't bother using the VFS here for this is only for debugging. // (and all your bases are belong to us). std::ofstream f("dna.txt"); if (f.fail()) { - DefaultLogger::get()->error("Could not dump dna to dna.txt"); + ASSIMP_LOG_ERROR("Could not dump dna to dna.txt"); return; } f << "Field format: type name offset size" << "\n"; @@ -248,7 +247,7 @@ void DNA :: DumpToFile() } f << std::flush; - DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt"); + ASSIMP_LOG_INFO("BlenderDNA: Dumped dna to dna.txt"); } #endif @@ -367,7 +366,7 @@ void SectionParser :: Next() } #ifdef ASSIMP_BUILD_BLENDER_DEBUG - DefaultLogger::get()->debug(current.id); + ASSIMP_LOG_DEBUG(current.id); #endif } diff --git a/code/BlenderDNA.h b/code/BlenderDNA.h index 3a2455275..ecf606a3b 100644 --- a/code/BlenderDNA.h +++ b/code/BlenderDNA.h @@ -309,6 +309,28 @@ public: void ReadField(T& out, const char* name, const FileDatabase& db) const; + // -------------------------------------------------------- + /** + * @brief field parsing for dynamic vectors + * @param[in] out vector of struct to be filled + * @param[in] name of field + * @param[in] db to access the file, dna, ... + * @return true when read was successful + */ + template class TOUT, typename T> + bool ReadFieldPtrVector(vector>&out, const char* name, const FileDatabase& db) const; + + /** + * @brief parses raw customdata + * @param[in] out shared_ptr to be filled + * @param[in] cdtype customdata type to read + * @param[in] name of field ptr + * @param[in] db to access the file, dna, ... + * @return true when read was successful + */ + template + bool ReadCustomDataPtr(std::shared_ptr&out, int cdtype, const char* name, const FileDatabase& db) const; + private: // -------------------------------------------------------- @@ -381,7 +403,7 @@ template <> struct Structure :: _defaultInitializer { template void operator ()(T& out, const char* reason = "") { - DefaultLogger::get()->warn(reason); + ASSIMP_LOG_WARN(reason); // ... and let the show go on _defaultInitializer<0 /*ErrorPolicy_Igno*/>()(out); @@ -663,7 +685,7 @@ public: /** Check whether a specific item is in the cache. * @param s Data type of the item * @param out Output pointer. Unchanged if the - * cache doens't know the item yet. + * cache doesn't know the item yet. * @param ptr Item address to look for. */ template void get ( const Structure& s, @@ -803,6 +825,17 @@ private: FileDatabase& db; }; +/** +* @brief read CustomData's data to ptr to mem +* @param[out] out memory ptr to set +* @param[in] cdtype to read +* @param[in] cnt cnt of elements to read +* @param[in] db to read elements from +* @return true when ok +*/ +bool readCustomData(std::shared_ptr &out, int cdtype, size_t cnt, const FileDatabase &db); + + } // end Blend } // end Assimp diff --git a/code/BlenderDNA.inl b/code/BlenderDNA.inl index 163798a40..5065aa118 100644 --- a/code/BlenderDNA.inl +++ b/code/BlenderDNA.inl @@ -307,6 +307,108 @@ void Structure :: ReadField(T& out, const char* name, const FileDatabase& db) co } +//-------------------------------------------------------------------------------- +// field parsing for raw untyped data (like CustomDataLayer.data) +template +bool Structure::ReadCustomDataPtr(std::shared_ptr&out, int cdtype, const char* name, const FileDatabase& db) const { + + const StreamReaderAny::pos old = db.reader->GetCurrentPos(); + + Pointer ptrval; + const Field* f; + try { + f = &(*this)[name]; + + // sanity check, should never happen if the genblenddna script is right + if (!(f->flags & FieldFlag_Pointer)) { + throw Error((Formatter::format(), "Field `", name, "` of structure `", + this->name, "` ought to be a pointer")); + } + + db.reader->IncPtr(f->offset); + Convert(ptrval, db); + // actually it is meaningless on which Structure the Convert is called + // because the `Pointer` argument triggers a special implementation. + } + catch (const Error& e) { + _defaultInitializer()(out, e.what()); + out.reset(); + } + + bool readOk = true; + if (ptrval.val) { + // get block for ptr + const FileBlockHead* block = LocateFileBlockForAddress(ptrval, db); + db.reader->SetCurrentPos(block->start + static_cast((ptrval.val - block->address.val))); + // read block->num instances of given type to out + readOk = readCustomData(out, cdtype, block->num, db); + } + + // and recover the previous stream position + db.reader->SetCurrentPos(old); + +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS + ++db.stats().fields_read; +#endif + + return readOk; +} + +//-------------------------------------------------------------------------------- +template class TOUT, typename T> +bool Structure::ReadFieldPtrVector(vector>&out, const char* name, const FileDatabase& db) const { + out.clear(); + + const StreamReaderAny::pos old = db.reader->GetCurrentPos(); + + Pointer ptrval; + const Field* f; + try { + f = &(*this)[name]; + + // sanity check, should never happen if the genblenddna script is right + if (!(f->flags & FieldFlag_Pointer)) { + throw Error((Formatter::format(), "Field `", name, "` of structure `", + this->name, "` ought to be a pointer")); + } + + db.reader->IncPtr(f->offset); + Convert(ptrval, db); + // actually it is meaningless on which Structure the Convert is called + // because the `Pointer` argument triggers a special implementation. + } + catch (const Error& e) { + _defaultInitializer()(out, e.what()); + out.clear(); + return false; + } + + + if (ptrval.val) { + // find the file block the pointer is pointing to + const FileBlockHead* block = LocateFileBlockForAddress(ptrval, db); + db.reader->SetCurrentPos(block->start + static_cast((ptrval.val - block->address.val))); + // FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems. + // I really ought to improve StreamReader to work with 64 bit indices exclusively. + + const Structure& s = db.dna[f->type]; + for (size_t i = 0; i < block->num; ++i) { + TOUT p(new T); + s.Convert(*p, db); + out.push_back(p); + } + } + + db.reader->SetCurrentPos(old); + +#ifndef ASSIMP_BUILD_BLENDER_NO_STATS + ++db.stats().fields_read; +#endif + + return false; +} + + //-------------------------------------------------------------------------------- template