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 5d8972b1d..d5a7bc278 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,7 +110,6 @@ if (WIN32) endif() IF(MSVC) - SET (CMAKE_PREFIX_PATH "D:\\libs\\devil") OPTION( ASSIMP_INSTALL_PDB "Install MSVC debug files." ON @@ -139,8 +138,7 @@ SET (PROJECT_VERSION "${ASSIMP_VERSION}") SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" ) -# Needed for openddl_parser config, no use of c++11 at this moment -ADD_DEFINITIONS( -DOPENDDL_NO_USE_CPP11 ) +# Enable C++1 globally set_property( GLOBAL PROPERTY CXX_STANDARD 11 ) # Get the current working branch @@ -162,7 +160,7 @@ EXECUTE_PROCESS( ) IF(NOT GIT_COMMIT_HASH) - SET(GIT_COMMIT_HASH 0) + SET(GIT_COMMIT_HASH 0) ENDIF(NOT GIT_COMMIT_HASH) IF(ASSIMP_DOUBLE_PRECISION) @@ -180,10 +178,10 @@ CONFIGURE_FILE( ) INCLUDE_DIRECTORIES( - ./ - include - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/include + ./ + include + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/include ) LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules" ) @@ -193,14 +191,6 @@ SET(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPO SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names") IF( UNIX ) - # Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux - IF( ${OPERATING_SYSTEM} MATCHES "Android") - ELSE() - IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux - #ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 ) - ENDIF() - ENDIF() - # Use GNUInstallDirs for Unix predefined directories INCLUDE(GNUInstallDirs) ENDIF( UNIX ) @@ -213,13 +203,13 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW) SET(LIBSTDC++_LIBRARIES -lstdc++) ELSEIF(MSVC) # enable multi-core compilation with MSVC - add_compile_options(/MP) - if("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)") - add_compile_options( /bigobj ) - endif() + ADD_COMPILE_OPTIONS(/MP) + IF("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)") + ADD_COMPILE_OPTIONS( /bigobj ) + ENDIF() # disable "elements of array '' will be default initialized" warning on MSVC2013 IF(MSVC12) - add_compile_options(/wd4351) + ADD_COMPILE_OPTIONS(/wd4351) ENDIF() ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" ) @@ -230,34 +220,39 @@ ELSEIF( CMAKE_COMPILER_IS_MINGW ) ADD_DEFINITIONS( -U__STRICT_ANSI__ ) ENDIF() -if (ASSIMP_COVERALLS) - MESSAGE(STATUS "Coveralls enabled") - INCLUDE(Coveralls) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") -endif() +IF (IOS) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3") +ENDIF() -if (ASSIMP_WERROR) +IF (ASSIMP_COVERALLS) + MESSAGE(STATUS "Coveralls enabled") + INCLUDE(Coveralls) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") +ENDIF() + +IF (ASSIMP_WERROR) MESSAGE(STATUS "Treating warnings as errors") IF (MSVC) - add_compile_options(/WX) + ADD_COMPILE_OPTIONS(/WX) ELSE() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") ENDIF() -endif() +ENDIF() -if (ASSIMP_ASAN) - MESSAGE(STATUS "AddressSanitizer enabled") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") -endif() +IF (ASSIMP_ASAN) + MESSAGE(STATUS "AddressSanitizer enabled") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") +ENDIF() -if (ASSIMP_UBSAN) - MESSAGE(STATUS "Undefined Behavior sanitizer enabled") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") -endif() +IF (ASSIMP_UBSAN) + MESSAGE(STATUS "Undefined Behavior sanitizer enabled") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") +ENDIF() INCLUDE (FindPkgMacros) INCLUDE (PrecompiledHeader) @@ -290,42 +285,42 @@ ENDIF() IF (NOT TARGET uninstall) # add make uninstall capability CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) - add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") + ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") ENDIF() # cmake configuration files CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE) CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE) -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT}) +INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT}) FIND_PACKAGE( DirectX ) IF( BUILD_DOCS ) - add_subdirectory(doc) + ADD_SUBDIRECTORY(doc) ENDIF( BUILD_DOCS ) # Look for system installed irrXML IF ( SYSTEM_IRRXML ) - find_package( IrrXML REQUIRED ) + FIND_PACKAGE( IrrXML REQUIRED ) ENDIF( SYSTEM_IRRXML ) # Search for external dependencies, and build them from source if not found # Search for zlib IF ( NOT ASSIMP_BUILD_ZLIB ) - find_package(ZLIB) + FIND_PACKAGE(ZLIB) ENDIF( NOT ASSIMP_BUILD_ZLIB ) IF( NOT ZLIB_FOUND ) - message(STATUS "compiling zlib from souces") + MESSAGE(STATUS "compiling zlib from sources") INCLUDE(CheckIncludeFile) INCLUDE(CheckTypeSize) INCLUDE(CheckFunctionExists) # compile from sources - add_subdirectory(contrib/zlib) + ADD_SUBDIRECTORY(contrib/zlib) SET(ZLIB_FOUND 1) SET(ZLIB_LIBRARIES zlibstatic) SET(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib) -else(NOT ZLIB_FOUND) +ELSE(NOT ZLIB_FOUND) ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB) SET(ZLIB_LIBRARIES_LINKED -lz) ENDIF(NOT ZLIB_FOUND) @@ -367,7 +362,9 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER) SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/includes") # pick the correct prebuilt library - IF(MSVC14) + IF(MSVC15) + SET(C4D_LIB_POSTFIX "_2017") + ELSEIF(MSVC14) SET(C4D_LIB_POSTFIX "_2015") ELSEIF(MSVC12) SET(C4D_LIB_POSTFIX "_2013") @@ -408,39 +405,14 @@ ADD_SUBDIRECTORY(contrib) ADD_SUBDIRECTORY( code/ ) IF ( ASSIMP_BUILD_ASSIMP_TOOLS ) IF ( WIN32 AND DirectX_D3DX9_LIBRARY ) - option ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" ${DirectX_FOUND} ) + OPTION ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" ${DirectX_FOUND} ) IF ( ASSIMP_BUILD_ASSIMP_VIEW ) ADD_SUBDIRECTORY( tools/assimp_view/ ) ENDIF ( ASSIMP_BUILD_ASSIMP_VIEW ) 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) @@ -460,7 +432,7 @@ INSTALL( FILES "${PROJECT_BINARY_DIR}/assimp.pc" DESTINATION ${ASSIMP_LIB_INSTAL IF(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES) # Packing information - SET(CPACK_PACKAGE_NAME "assimp{ASSIMP_VERSION_MAJOR}") + SET(CPACK_PACKAGE_NAME "assimp{ASSIMP_VERSION_MAJOR}.{ASSIMP_VERSION_MINOR}") SET(CPACK_PACKAGE_CONTACT "" CACHE STRING "Package maintainer and PGP signer.") SET(CPACK_PACKAGE_VENDOR "https://github.com/assimp") SET(CPACK_PACKAGE_DISPLAY_NAME "Assimp ${ASSIMP_VERSION}") @@ -472,8 +444,8 @@ IF(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES) SET(CPACK_PACKAGE_INSTALL_DIRECTORY "assimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}") SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") - string(TOUPPER ${LIBASSIMP_COMPONENT} "LIBASSIMP_COMPONENT_UPPER") - string(TOUPPER ${LIBASSIMP-DEV_COMPONENT} "LIBASSIMP-DEV_COMPONENT_UPPER") + STRING(TOUPPER ${LIBASSIMP_COMPONENT} "LIBASSIMP_COMPONENT_UPPER") + STRING(TOUPPER ${LIBASSIMP-DEV_COMPONENT} "LIBASSIMP-DEV_COMPONENT_UPPER") SET(CPACK_COMPONENT_ASSIMP-BIN_DISPLAY_NAME "tools") SET(CPACK_COMPONENT_ASSIMP-BIN_DEPENDS "${LIBASSIMP_COMPONENT}" ) @@ -490,8 +462,8 @@ IF(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES) SET(CPACK_DEBIAN_PACKAGE_SECTION "libs" ) SET(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}") SET(CPACK_DEBIAN_PACKAGE_SUGGESTS) - SET(CPACK_DEBIAN_PACKAGE_NAME "assimp") - SET(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/cppunit-1.12.1 contrib/cppunit_note.txt contrib/zlib workspaces test doc obj samples packaging) + set(cPACK_DEBIAN_PACKAGE_NAME "assimp") + SET(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/gtest contrib/zlib workspaces test doc obj samples packaging) SET(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force) SET(CPACK_DEBIAN_CHANGELOG) execute_process(COMMAND lsb_release -is @@ -503,8 +475,8 @@ IF(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES) SET(CPACK_DEBIAN_DISTRIBUTION_RELEASES lucid maverick natty oneiric precise CACHE STRING "Release code-names of the distrubiton release") ENDIF() SET(DPUT_HOST "" CACHE STRING "PPA repository to upload the debian sources") - include(CPack) - include(DebSourcePPA) + INCLUDE(CPack) + INCLUDE(DebSourcePPA) ENDIF() if(WIN32) @@ -516,14 +488,16 @@ if(WIN32) SET(LIB_DIR "${PROJECT_SOURCE_DIR}/lib32/") ENDIF() - if(MSVC12) + IF(MSVC12) SET(ASSIMP_MSVC_VERSION "vc120") - elseif(MSVC14) + ELSEIF(MSVC14) SET(ASSIMP_MSVC_VERSION "vc140") + ELSEIF(MSVC15) + SET(ASSIMP_MSVC_VERSION "vc141") ENDIF(MSVC12) - if(MSVC12 OR MSVC14) - add_custom_target(UpdateAssimpLibsDebugSymbolsAndDLLs COMMENT "Copying Assimp Libraries ..." VERBATIM) + IF(MSVC12 OR MSVC14 OR MSVC15 ) + ADD_CUSTOM_TARGET(UpdateAssimpLibsDebugSymbolsAndDLLs COMMENT "Copying Assimp Libraries ..." VERBATIM) IF(CMAKE_GENERATOR MATCHES "^Visual Studio") ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.dll VERBATIM) ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.exp VERBATIM) @@ -544,5 +518,5 @@ if(WIN32) ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM) ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM) ENDIF() - ENDIF(MSVC12 OR MSVC14) + ENDIF(MSVC12 OR MSVC14 OR MSVC15 ) ENDIF (WIN32) 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/CREDITS b/CREDITS index df41c482d..26e21d2f4 100644 --- a/CREDITS +++ b/CREDITS @@ -157,12 +157,27 @@ Contributed ExportProperties interface Contributed X File exporter Contributed Step (stp) exporter +- Thomas Iorns (mesilliac) +Initial FBX Export support + For a more detailed list just check: https://github.com/assimp/assimp/network/members -Patreons: + +======== +Patreons +======== + +Huge thanks to our Patreons! + - migenius - Marcus - Cort - elect - Steffen + +=================== +Commercial Sponsors +=================== + +- MyDidimo (mydidimo.com): Sponsored development of FBX Export support diff --git a/Readme.md b/Readme.md index a6f2e3d3d..449efc547 100644 --- a/Readme.md +++ b/Readme.md @@ -32,32 +32,32 @@ Please check our Wiki as well: https://github.com/assimp/assimp/wiki #### Supported file formats #### -A full list [is here](http://assimp.org/main_features_formats.html). __Importers__: + - 3D -- 3DS -- 3MF +- [3DS](https://en.wikipedia.org/wiki/.3ds) +- [3MF](https://en.wikipedia.org/wiki/3D_Manufacturing_Format) - AC -- AC3D +- [AC3D](https://en.wikipedia.org/wiki/AC3D) - ACC - AMJ - ASE - ASK - B3D -- BLEND (Blender) -- BVH -- COB +- [BLEND](https://en.wikipedia.org/wiki/.blend_(file_format)) +- [BVH](https://en.wikipedia.org/wiki/Biovision_Hierarchy) - CMS -- DAE/Collada -- DXF +- COB +- [DAE/Collada](https://en.wikipedia.org/wiki/COLLADA) +- [DXF](https://en.wikipedia.org/wiki/AutoCAD_DXF) - ENFF -- FBX -- glTF 1.0 + GLB -- glTF 2.0 +- [FBX](https://en.wikipedia.org/wiki/FBX) +- [glTF 1.0](https://en.wikipedia.org/wiki/GlTF#glTF_1.0) + GLB +- [glTF 2.0](https://en.wikipedia.org/wiki/GlTF#glTF_2.0) - HMB - IFC-STEP - IRR / IRRMESH -- LWO +- [LWO](https://en.wikipedia.org/wiki/LightWave_3D) - LWS - LXO - MD2 @@ -70,10 +70,10 @@ __Importers__: - MS3D - NDO - NFF -- OBJ -- OFF -- OGEX -- PLY +- [OBJ](https://en.wikipedia.org/wiki/Wavefront_.obj_file) +- [OFF](https://en.wikipedia.org/wiki/OFF_(file_format)) +- [OGEX](https://en.wikipedia.org/wiki/Open_Game_Engine_Exchange) +- [PLY](https://en.wikipedia.org/wiki/PLY_(file_format)) - PMX - PRJ - Q3O @@ -82,19 +82,19 @@ __Importers__: - SCN - SIB - SMD -- STL -- STP +- [STP](https://en.wikipedia.org/wiki/ISO_10303-21) +- [STL](https://en.wikipedia.org/wiki/STL_(file_format)) - TER - UC - VTA - X -- X3D +- [X3D](https://en.wikipedia.org/wiki/X3D) - XGL - ZGL Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default): -- C4D (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange) +- [C4D](https://en.wikipedia.org/wiki/Cinema_4D) (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange) __Exporters__: @@ -109,6 +109,8 @@ __Exporters__: - STEP - glTF 1.0 (partial) - glTF 2.0 (partial) +- 3MF ( experimental ) +- FBX ( experimental ) ### Building ### Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do. @@ -138,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/assimp-config.cmake.in b/assimp-config.cmake.in index e06cc10ee..1710cac5d 100644 --- a/assimp-config.cmake.in +++ b/assimp-config.cmake.in @@ -10,10 +10,7 @@ # ASSIMP_LIBRARY_DIRS - link directories # ASSIMP_LIBRARIES - libraries to link plugins with # ASSIMP_Boost_VERSION - the boost version assimp was compiled with -get_filename_component(_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) -get_filename_component(_PREFIX "${_PREFIX}" PATH) -get_filename_component(_PREFIX "${_PREFIX}" PATH) -get_filename_component(ASSIMP_ROOT_DIR "${_PREFIX}" PATH) +get_filename_component(ASSIMP_ROOT_DIR "@CMAKE_INSTALL_PREFIX@" REALPATH) if( MSVC ) # in order to prevent DLL hell, each of the DLLs have to be suffixed with the major version and msvc prefix @@ -34,36 +31,18 @@ if( MSVC ) else() set(MSVC_PREFIX "vc150") endif() - set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" FORCE) + set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" ) else() - set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the openrave libraries" FORCE) + set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the openrave libraries" ) endif() set( ASSIMP_CXX_FLAGS ) # dynamically linked library -if( WIN32 ) - # for visual studio linking, most of the time boost dlls will be used - set( ASSIMP_CXX_FLAGS " -DBOOST_ALL_DYN_LINK -DBOOST_ALL_NO_LIB") -endif() set( ASSIMP_LINK_FLAGS "" ) set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@") set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@") set( ASSIMP_LIBRARIES assimp${ASSIMP_LIBRARY_SUFFIX}) set( ASSIMP_LIBRARIES ${ASSIMP_LIBRARIES}@CMAKE_DEBUG_POSTFIX@) -# search for the boost version assimp was compiled with -#set(Boost_USE_MULTITHREAD ON) -#set(Boost_USE_STATIC_LIBS OFF) -#set(Boost_USE_STATIC_RUNTIME OFF) -#find_package(Boost ${ASSIMP_Boost_VERSION} EXACT COMPONENTS thread date_time) -#if(Boost_VERSION AND NOT "${Boost_VERSION}" STREQUAL "0") -# set( ASSIMP_INCLUDE_DIRS "${ASSIMP_INCLUDE_DIRS}" ${Boost_INCLUDE_DIRS}) -#else(Boost_VERSION AND NOT "${Boost_VERSION}" STREQUAL "0") -# message(WARNING "Failed to find Boost ${ASSIMP_Boost_VERSION} necessary for assimp") -#endif(Boost_VERSION AND NOT "${Boost_VERSION}" STREQUAL "0") - -# the boost version assimp was compiled with -set( ASSIMP_Boost_VERSION "@Boost_MAJOR_VERSION@.@Boost_MINOR_VERSION@") - # for compatibility with pkg-config set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}") set(ASSIMP_LDFLAGS_OTHER "${ASSIMP_LINK_FLAGS}") @@ -74,7 +53,6 @@ MARK_AS_ADVANCED( ASSIMP_LINK_FLAGS ASSIMP_INCLUDE_DIRS ASSIMP_LIBRARIES - ASSIMP_Boost_VERSION ASSIMP_CFLAGS_OTHER ASSIMP_LDFLAGS_OTHER ASSIMP_LIBRARY_SUFFIX diff --git a/code/3DSConverter.cpp b/code/3DSConverter.cpp index cbc6d31d2..7ec79ba64 100644 --- a/code/3DSConverter.cpp +++ b/code/3DSConverter.cpp @@ -72,7 +72,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() unsigned int idx( NotSet ); for (unsigned int i = 0; i < mScene->mMaterials.size();++i) { - std::string s = mScene->mMaterials[i].mName; + std::string &s = mScene->mMaterials[i].mName; for ( std::string::iterator it = s.begin(); it != s.end(); ++it ) { *it = static_cast< char >( ::tolower( *it ) ); } @@ -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 65f4bf8d8..53976b16f 100644 --- a/code/3DSExporter.cpp +++ b/code/3DSExporter.cpp @@ -184,7 +184,7 @@ void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScen } // end of namespace Assimp // ------------------------------------------------------------------------------------------------ -Discreet3DSExporter:: Discreet3DSExporter(std::shared_ptr outfile, const aiScene* scene) +Discreet3DSExporter:: Discreet3DSExporter(std::shared_ptr &outfile, const aiScene* scene) : scene(scene) , writer(outfile) { @@ -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/3DSExporter.h b/code/3DSExporter.h index 5e138e92d..5db58a4cb 100644 --- a/code/3DSExporter.h +++ b/code/3DSExporter.h @@ -67,7 +67,7 @@ namespace Assimp // ------------------------------------------------------------------------------------------------ class Discreet3DSExporter { public: - Discreet3DSExporter(std::shared_ptr outfile, const aiScene* pScene); + Discreet3DSExporter(std::shared_ptr &outfile, const aiScene* pScene); ~Discreet3DSExporter(); private: diff --git a/code/3DSLoader.cpp b/code/3DSLoader.cpp index 9d61e125c..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" }; @@ -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 == "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; }; @@ -349,7 +350,7 @@ void Discreet3DSImporter::ParseObjectChunk() case Discreet3DS::CHUNK_MAT_MATERIAL: // Add a new material to the list - mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + std::to_string(mScene->mMaterials.size())))); + mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + to_string(mScene->mMaterials.size())))); ParseMaterialChunk(); 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/3MFXmlTags.h b/code/3MFXmlTags.h index 30aed0e95..e869c33c1 100644 --- a/code/3MFXmlTags.h +++ b/code/3MFXmlTags.h @@ -45,6 +45,11 @@ namespace Assimp { namespace D3MF { namespace XmlTag { + // Meta-data + static const std::string meta = "metadata"; + static const std::string meta_name = "name"; + + // Model-data specific tags static const std::string model = "model"; static const std::string model_unit = "unit"; static const std::string metadata = "metadata"; @@ -62,6 +67,8 @@ namespace XmlTag { static const std::string v2 = "v2"; static const std::string v3 = "v3"; static const std::string id = "id"; + static const std::string pid = "pid"; + static const std::string p1 = "p1"; static const std::string name = "name"; static const std::string type = "type"; static const std::string build = "build"; @@ -69,6 +76,14 @@ namespace XmlTag { static const std::string objectid = "objectid"; static const std::string transform = "transform"; + // Material definitions + static const std::string basematerials = "basematerials"; + static const std::string basematerials_id = "id"; + static const std::string basematerials_base = "base"; + static const std::string basematerials_name = "name"; + static const std::string basematerials_displaycolor = "displaycolor"; + + // Meta info tags static const std::string CONTENT_TYPES_ARCHIVE = "[Content_Types].xml"; static const std::string ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels"; static const std::string SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types"; @@ -83,7 +98,6 @@ namespace XmlTag { static const std::string PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture"; static const std::string PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"; static const std::string PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"; - } } // Namespace D3MF 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 f048e1178..a6ee8fa2f 100644 --- a/code/AMFImporter_Postprocess.cpp +++ b/code/AMFImporter_Postprocess.cpp @@ -156,10 +156,11 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string& TextureConverted_Index = 0; for(const SPP_Texture& tex_convd: mTexture_Converted) { - if(tex_convd.ID == TextureConverted_ID) - return TextureConverted_Index; - else - TextureConverted_Index++; + if ( tex_convd.ID == TextureConverted_ID ) { + return TextureConverted_Index; + } else { + ++TextureConverted_Index; + } } // @@ -769,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 122b226f4..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."); } @@ -583,7 +583,7 @@ void ASEImporter::AddNodes (const std::vector& nodes, node->mTransformation = mParentAdjust*snode->mTransform; // Add sub nodes - prevent stack overflow due to recursive parenting - if (node->mName != node->mParent->mName) { + if (node->mName != node->mParent->mName && node->mName != node->mParent->mParent->mName ) { AddNodes(nodes,node,node->mName.data,snode->mTransform); } @@ -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 59af24a10..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); } // ------------------------------------------------------------------------------------------------ @@ -267,7 +267,9 @@ void Parser::Parse() // at the file extension (ASE, ASK, ASC) // ************************************************************* - if (fmt)iFileFormat = fmt; + if ( fmt ) { + iFileFormat = fmt; + } continue; } // main scene information @@ -427,28 +429,25 @@ void Parser::ParseLV1SoftSkinBlock() // Reserve enough storage vert.mBoneWeights.reserve(numWeights); - for (unsigned int w = 0; w < numWeights;++w) - { - std::string bone; + std::string bone; + for (unsigned int w = 0; w < numWeights;++w) { + bone.clear(); ParseString(bone,"*MESH_SOFTSKINVERTS.Bone"); // Find the bone in the mesh's list std::pair me; me.first = -1; - for (unsigned int n = 0; n < curMesh->mBones.size();++n) - { - if (curMesh->mBones[n].mName == bone) - { + for (unsigned int n = 0; n < curMesh->mBones.size();++n) { + if (curMesh->mBones[n].mName == bone) { me.first = n; break; } } - if (-1 == me.first) - { + if (-1 == me.first) { // We don't have this bone yet, so add it to the list - me.first = (int)curMesh->mBones.size(); - curMesh->mBones.push_back(ASE::Bone(bone)); + me.first = static_cast( curMesh->mBones.size() ); + curMesh->mBones.push_back( ASE::Bone( bone ) ); } ParseLV4MeshFloat( me.second ); @@ -745,6 +744,7 @@ void Parser::ParseLV3MapBlock(Texture& map) // empty the texture won't be used later. // *********************************************************** bool parsePath = true; + std::string temp; while (true) { if ('*' == *filePtr) @@ -753,12 +753,12 @@ void Parser::ParseLV3MapBlock(Texture& map) // type of map if (TokenMatch(filePtr,"MAP_CLASS" ,9)) { - std::string temp; + temp.clear(); if(!ParseString(temp,"*MAP_CLASS")) 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/BVHLoader.cpp b/code/BVHLoader.cpp index dfeeb60ac..0b2a818ae 100644 --- a/code/BVHLoader.cpp +++ b/code/BVHLoader.cpp @@ -199,6 +199,7 @@ aiNode* BVHLoader::ReadNode() Node& internNode = mNodes.back(); // now read the node's contents + std::string siteToken; while( 1) { std::string token = GetNextToken(); @@ -218,7 +219,8 @@ aiNode* BVHLoader::ReadNode() else if( token == "End") { // The real symbol is "End Site". Second part comes in a separate token - std::string siteToken = GetNextToken(); + siteToken.clear(); + siteToken = GetNextToken(); if( siteToken != "Site") ThrowException( format() << "Expected \"End Site\" keyword, but found \"" << token << " " << siteToken << "\"." ); @@ -262,21 +264,18 @@ aiNode* BVHLoader::ReadEndSite( const std::string& pParentName) aiNode* node = new aiNode( "EndSite_" + pParentName); // now read the node's contents. Only possible entry is "OFFSET" - while( 1) - { - std::string token = GetNextToken(); + std::string token; + while( 1) { + token.clear(); + token = GetNextToken(); // end node's offset - if( token == "OFFSET") - { + if( token == "OFFSET") { ReadNodeOffset( node); - } - else if( token == "}") - { + } else if( token == "}") { // we're done with the end node break; - } else - { + } else { // everything else is a parse error ThrowException( format() << "Unknown keyword \"" << token << "\"." ); } @@ -296,8 +295,10 @@ void BVHLoader::ReadNodeOffset( aiNode* pNode) offset.z = GetNextTokenAsFloat(); // build a transformation matrix from it - pNode->mTransformation = aiMatrix4x4( 1.0f, 0.0f, 0.0f, offset.x, 0.0f, 1.0f, 0.0f, offset.y, - 0.0f, 0.0f, 1.0f, offset.z, 0.0f, 0.0f, 0.0f, 1.0f); + pNode->mTransformation = aiMatrix4x4( 1.0f, 0.0f, 0.0f, offset.x, + 0.0f, 1.0f, 0.0f, offset.y, + 0.0f, 0.0f, 1.0f, offset.z, + 0.0f, 0.0f, 0.0f, 1.0f); } // ------------------------------------------------------------------------------------------------ diff --git a/code/BaseImporter.cpp b/code/BaseImporter.cpp index 0892efd9f..78979d078 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. @@ -115,13 +116,12 @@ void BaseImporter::SetupProperties(const Importer* /*pImp*/) } // ------------------------------------------------------------------------------------------------ -void BaseImporter::GetExtensionList(std::set& extensions) -{ +void BaseImporter::GetExtensionList(std::set& extensions) { const aiImporterDesc* desc = GetInfo(); - ai_assert(desc != NULL); + ai_assert(desc != nullptr); const char* ext = desc->mFileExtensions; - ai_assert(ext != NULL); + ai_assert(ext != nullptr ); const char* last = ext; do { @@ -145,12 +145,13 @@ void BaseImporter::GetExtensionList(std::set& extensions) unsigned int searchBytes /* = 200 */, bool tokensSol /* false */) { - ai_assert( NULL != tokens ); + ai_assert( nullptr != tokens ); ai_assert( 0 != numTokens ); ai_assert( 0 != searchBytes); - if (!pIOHandler) + if ( nullptr == pIOHandler ) { return false; + } std::unique_ptr pStream (pIOHandler->Open(pFile)); if (pStream.get() ) { @@ -178,16 +179,24 @@ void BaseImporter::GetExtensionList(std::set& extensions) } *cur2 = '\0'; - for (unsigned int i = 0; i < numTokens;++i) { - ai_assert(NULL != tokens[i]); - const char* r = strstr(buffer,tokens[i]); + std::string token; + for (unsigned int i = 0; i < numTokens; ++i ) { + ai_assert( nullptr != tokens[i] ); + const size_t len( strlen( tokens[ i ] ) ); + token.clear(); + const char *ptr( tokens[ i ] ); + for ( size_t tokIdx = 0; tokIdx < len; ++tokIdx ) { + token.push_back( tolower( *ptr ) ); + ++ptr; + } + const char* r = strstr( buffer, token.c_str() ); if( !r ) { 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; } } @@ -243,7 +252,8 @@ void BaseImporter::GetExtensionList(std::set& extensions) /* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile, const void* _magic, unsigned int num, unsigned int offset, unsigned int size) { - ai_assert(size <= 16 && _magic); + ai_assert( size <= 16 ); + ai_assert( _magic ); if (!pIOHandler) { return false; @@ -313,7 +323,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); @@ -332,7 +342,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 ]; @@ -352,7 +362,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)); @@ -377,16 +387,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]; } @@ -402,7 +410,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) { @@ -463,14 +471,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; } @@ -496,9 +504,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 ); } @@ -564,7 +571,7 @@ aiScene* BatchLoader::GetImport( unsigned int which ) return sc; } } - return NULL; + return nullptr; } // ------------------------------------------------------------------------------------------------ @@ -587,13 +594,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 285cb05b8..f84c45601 100644 --- a/code/BlenderDNA.cpp +++ b/code/BlenderDNA.cpp @@ -58,12 +58,11 @@ using namespace Assimp::Formatter; static bool match4(StreamReaderAny& stream, const char* string) { ai_assert( nullptr != string ); - char tmp[] = { - (const char)(stream).GetI1(), - (const char)(stream).GetI1(), - (const char)(stream).GetI1(), - (const char)(stream).GetI1() - }; + char tmp[4]; + tmp[ 0 ] = ( stream ).GetI1(); + tmp[ 1 ] = ( stream ).GetI1(); + tmp[ 2 ] = ( stream ).GetI1(); + tmp[ 3 ] = ( stream ).GetI1(); return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]); } @@ -211,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(); @@ -229,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"; @@ -249,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 @@ -368,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 6f4c69c04..ecf606a3b 100644 --- a/code/BlenderDNA.h +++ b/code/BlenderDNA.h @@ -205,7 +205,7 @@ enum ErrorPolicy { // ------------------------------------------------------------------------------- /** Represents a data structure in a BLEND file. A Structure defines n fields - * and their locatios and encodings the input stream. Usually, every + * and their locations and encodings the input stream. Usually, every * Structure instance pertains to one equally-named data structure in the * BlenderScene.h header. This class defines various utilities to map a * binary `blob` read from the file to such a structure instance with @@ -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 185531d1a..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