Merge branch 'master' into ios-build-script

* master: (148 commits)
  Update Importer.cpp
  [-] Trace print removed.
  [F] Get return "like true" when error occured.
  [*] qt_assimp_viewer can be built with Qt4 or Qt5. [F] Working in doule precision.
  [F] List of importers can be empty.
  [F] More correct control by a mouse
  [F] React on mouse pressing ig view only.
  [F] One alignment for labels. [-] Unused checkbox.
  [+] QtCreator temporary file.
  [*] Refactoring of "draw axes" procedure. [-] Removed not working part of code for reloading textures. That do nothing, just show checkbox. As Yoda said: "Do. Or do not. There is no try."
  [-] Function "GetExtension" always return lowercase string. Using uppercase extension in desc is not needed.
  glTF/2.0: Pick scene zero as scene to recursively load if no "scene" property is specified.
  Fix GenVertexNormals
  [F] Wrong type in equation.
  [F] Uninitialized variables.
  Fix #1587 : add validation to LWS unit test
  Fix #1970: stl with empty solid
  Add test for issue 1970: STL with empty solid
  Add mesh name to ValidateDataStructure log
  Read and write the KHR_materials_unlit glTF/2.0 extension.
  ...

# Conflicts:
#	CMakeLists.txt
#	port/iOS/build.sh
pull/2045/head
Doron Adler 2018-05-28 16:27:00 +03:00
commit 27b989fd36
231 changed files with 5477 additions and 3041 deletions

3
.gitignore vendored
View File

@ -12,6 +12,8 @@ build
bin/ bin/
lib/ lib/
# QtCreator
CMakeLists.txt.user
# Generated # Generated
assimp.pc assimp.pc
@ -38,6 +40,7 @@ tools/assimp_cmd/Makefile
# Tests # Tests
test/results test/results
test/readlinetest*
# Python # Python
__pycache__ __pycache__

258
CHANGES
View File

@ -1,6 +1,264 @@
---------------------------------------------------------------------- ----------------------------------------------------------------------
CHANGELOG 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 <library_animations> 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) 4.0.1 (2017-07-28)
- FIXES/HOUSEKEEPING: - FIXES/HOUSEKEEPING:
- fix version test. - fix version test.

View File

@ -116,7 +116,6 @@ if (WIN32)
endif() endif()
IF(MSVC) IF(MSVC)
SET (CMAKE_PREFIX_PATH "D:\\libs\\devil")
OPTION( ASSIMP_INSTALL_PDB OPTION( ASSIMP_INSTALL_PDB
"Install MSVC debug files." "Install MSVC debug files."
ON ON
@ -145,8 +144,7 @@ SET (PROJECT_VERSION "${ASSIMP_VERSION}")
SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" ) 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 # Enable C++1 globally
ADD_DEFINITIONS( -DOPENDDL_NO_USE_CPP11 )
set_property( GLOBAL PROPERTY CXX_STANDARD 11 ) set_property( GLOBAL PROPERTY CXX_STANDARD 11 )
# Get the current working branch # Get the current working branch
@ -199,14 +197,6 @@ SET(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPO
SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names") SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
IF( UNIX ) 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 # Use GNUInstallDirs for Unix predefined directories
INCLUDE(GNUInstallDirs) INCLUDE(GNUInstallDirs)
ENDIF( UNIX ) ENDIF( UNIX )
@ -219,13 +209,13 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
SET(LIBSTDC++_LIBRARIES -lstdc++) SET(LIBSTDC++_LIBRARIES -lstdc++)
ELSEIF(MSVC) ELSEIF(MSVC)
# enable multi-core compilation with MSVC # enable multi-core compilation with MSVC
add_compile_options(/MP) ADD_COMPILE_OPTIONS(/MP)
if("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)") IF("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
add_compile_options( /bigobj ) ADD_COMPILE_OPTIONS( /bigobj )
endif() ENDIF()
# disable "elements of array '' will be default initialized" warning on MSVC2013 # disable "elements of array '' will be default initialized" warning on MSVC2013
IF(MSVC12) IF(MSVC12)
add_compile_options(/wd4351) ADD_COMPILE_OPTIONS(/wd4351)
ENDIF() ENDIF()
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) 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" ) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" )
@ -236,39 +226,39 @@ ELSEIF( CMAKE_COMPILER_IS_MINGW )
ADD_DEFINITIONS( -U__STRICT_ANSI__ ) ADD_DEFINITIONS( -U__STRICT_ANSI__ )
ENDIF() ENDIF()
if (IOS) IF (IOS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
endif() ENDIF()
if (ASSIMP_COVERALLS) IF (ASSIMP_COVERALLS)
MESSAGE(STATUS "Coveralls enabled") MESSAGE(STATUS "Coveralls enabled")
INCLUDE(Coveralls) INCLUDE(Coveralls)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") 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") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
endif() ENDIF()
if (ASSIMP_WERROR) IF (ASSIMP_WERROR)
MESSAGE(STATUS "Treating warnings as errors") MESSAGE(STATUS "Treating warnings as errors")
IF (MSVC) IF (MSVC)
add_compile_options(/WX) ADD_COMPILE_OPTIONS(/WX)
ELSE() ELSE()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
ENDIF() ENDIF()
endif() ENDIF()
if (ASSIMP_ASAN) IF (ASSIMP_ASAN)
MESSAGE(STATUS "AddressSanitizer enabled") MESSAGE(STATUS "AddressSanitizer enabled")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
endif() ENDIF()
if (ASSIMP_UBSAN) IF (ASSIMP_UBSAN)
MESSAGE(STATUS "Undefined Behavior sanitizer enabled") MESSAGE(STATUS "Undefined Behavior sanitizer enabled")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") 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") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
endif() ENDIF()
INCLUDE (FindPkgMacros) INCLUDE (FindPkgMacros)
INCLUDE (PrecompiledHeader) INCLUDE (PrecompiledHeader)
@ -301,42 +291,42 @@ ENDIF()
IF (NOT TARGET uninstall) IF (NOT TARGET uninstall)
# add make uninstall capability # 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) 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() ENDIF()
# cmake configuration files # 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.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) 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 ) FIND_PACKAGE( DirectX )
IF( BUILD_DOCS ) IF( BUILD_DOCS )
add_subdirectory(doc) ADD_SUBDIRECTORY(doc)
ENDIF( BUILD_DOCS ) ENDIF( BUILD_DOCS )
# Look for system installed irrXML # Look for system installed irrXML
IF ( SYSTEM_IRRXML ) IF ( SYSTEM_IRRXML )
find_package( IrrXML REQUIRED ) FIND_PACKAGE( IrrXML REQUIRED )
ENDIF( SYSTEM_IRRXML ) ENDIF( SYSTEM_IRRXML )
# Search for external dependencies, and build them from source if not found # Search for external dependencies, and build them from source if not found
# Search for zlib # Search for zlib
IF ( NOT ASSIMP_BUILD_ZLIB ) IF ( NOT ASSIMP_BUILD_ZLIB )
find_package(ZLIB) FIND_PACKAGE(ZLIB)
ENDIF( NOT ASSIMP_BUILD_ZLIB ) ENDIF( NOT ASSIMP_BUILD_ZLIB )
IF( NOT ZLIB_FOUND ) IF( NOT ZLIB_FOUND )
message(STATUS "compiling zlib from souces") MESSAGE(STATUS "compiling zlib from sources")
INCLUDE(CheckIncludeFile) INCLUDE(CheckIncludeFile)
INCLUDE(CheckTypeSize) INCLUDE(CheckTypeSize)
INCLUDE(CheckFunctionExists) INCLUDE(CheckFunctionExists)
# compile from sources # compile from sources
add_subdirectory(contrib/zlib) ADD_SUBDIRECTORY(contrib/zlib)
SET(ZLIB_FOUND 1) SET(ZLIB_FOUND 1)
SET(ZLIB_LIBRARIES zlibstatic) SET(ZLIB_LIBRARIES zlibstatic)
SET(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib) 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) ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
SET(ZLIB_LIBRARIES_LINKED -lz) SET(ZLIB_LIBRARIES_LINKED -lz)
ENDIF(NOT ZLIB_FOUND) ENDIF(NOT ZLIB_FOUND)
@ -380,7 +370,9 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/includes") SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/includes")
# pick the correct prebuilt library # pick the correct prebuilt library
IF(MSVC14) IF(MSVC15)
SET(C4D_LIB_POSTFIX "_2017")
ELSEIF(MSVC14)
SET(C4D_LIB_POSTFIX "_2015") SET(C4D_LIB_POSTFIX "_2015")
ELSEIF(MSVC12) ELSEIF(MSVC12)
SET(C4D_LIB_POSTFIX "_2013") SET(C4D_LIB_POSTFIX "_2013")
@ -421,41 +413,14 @@ ADD_SUBDIRECTORY(contrib)
ADD_SUBDIRECTORY( code/ ) ADD_SUBDIRECTORY( code/ )
IF ( ASSIMP_BUILD_ASSIMP_TOOLS ) IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
IF ( WIN32 AND DirectX_D3DX9_LIBRARY ) 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 ) IF ( ASSIMP_BUILD_ASSIMP_VIEW )
ADD_SUBDIRECTORY( tools/assimp_view/ ) ADD_SUBDIRECTORY( tools/assimp_view/ )
ENDIF ( ASSIMP_BUILD_ASSIMP_VIEW ) ENDIF ( ASSIMP_BUILD_ASSIMP_VIEW )
ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY ) ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY )
ADD_SUBDIRECTORY( tools/assimp_cmd/ ) 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.
IF (NOT IOS)
FIND_PACKAGE(Qt5Widgets QUIET)
ENDIF (NOT IOS)
FIND_PACKAGE(DevIL QUIET)
FIND_PACKAGE(OpenGL QUIET)
IF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ ) 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)
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS ) ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
IF ( ASSIMP_BUILD_SAMPLES) IF ( ASSIMP_BUILD_SAMPLES)
@ -475,7 +440,7 @@ INSTALL( FILES "${PROJECT_BINARY_DIR}/assimp.pc" DESTINATION ${ASSIMP_LIB_INSTAL
IF(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES) IF(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES)
# Packing information # 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_CONTACT "" CACHE STRING "Package maintainer and PGP signer.")
SET(CPACK_PACKAGE_VENDOR "https://github.com/assimp") SET(CPACK_PACKAGE_VENDOR "https://github.com/assimp")
SET(CPACK_PACKAGE_DISPLAY_NAME "Assimp ${ASSIMP_VERSION}") SET(CPACK_PACKAGE_DISPLAY_NAME "Assimp ${ASSIMP_VERSION}")
@ -487,8 +452,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_PACKAGE_INSTALL_DIRECTORY "assimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
string(TOUPPER ${LIBASSIMP_COMPONENT} "LIBASSIMP_COMPONENT_UPPER") STRING(TOUPPER ${LIBASSIMP_COMPONENT} "LIBASSIMP_COMPONENT_UPPER")
string(TOUPPER ${LIBASSIMP-DEV_COMPONENT} "LIBASSIMP-DEV_COMPONENT_UPPER") STRING(TOUPPER ${LIBASSIMP-DEV_COMPONENT} "LIBASSIMP-DEV_COMPONENT_UPPER")
SET(CPACK_COMPONENT_ASSIMP-BIN_DISPLAY_NAME "tools") SET(CPACK_COMPONENT_ASSIMP-BIN_DISPLAY_NAME "tools")
SET(CPACK_COMPONENT_ASSIMP-BIN_DEPENDS "${LIBASSIMP_COMPONENT}" ) SET(CPACK_COMPONENT_ASSIMP-BIN_DEPENDS "${LIBASSIMP_COMPONENT}" )
@ -505,8 +470,8 @@ IF(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES)
SET(CPACK_DEBIAN_PACKAGE_SECTION "libs" ) SET(CPACK_DEBIAN_PACKAGE_SECTION "libs" )
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}") SET(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}")
SET(CPACK_DEBIAN_PACKAGE_SUGGESTS) SET(CPACK_DEBIAN_PACKAGE_SUGGESTS)
SET(CPACK_DEBIAN_PACKAGE_NAME "assimp") 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_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_PACKAGE_SOURCE_COPY svn export --force)
SET(CPACK_DEBIAN_CHANGELOG) SET(CPACK_DEBIAN_CHANGELOG)
execute_process(COMMAND lsb_release -is execute_process(COMMAND lsb_release -is
@ -518,8 +483,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") SET(CPACK_DEBIAN_DISTRIBUTION_RELEASES lucid maverick natty oneiric precise CACHE STRING "Release code-names of the distrubiton release")
ENDIF() ENDIF()
SET(DPUT_HOST "" CACHE STRING "PPA repository to upload the debian sources") SET(DPUT_HOST "" CACHE STRING "PPA repository to upload the debian sources")
include(CPack) INCLUDE(CPack)
include(DebSourcePPA) INCLUDE(DebSourcePPA)
ENDIF() ENDIF()
if(WIN32) if(WIN32)
@ -531,14 +496,16 @@ if(WIN32)
SET(LIB_DIR "${PROJECT_SOURCE_DIR}/lib32/") SET(LIB_DIR "${PROJECT_SOURCE_DIR}/lib32/")
ENDIF() ENDIF()
if(MSVC12) IF(MSVC12)
SET(ASSIMP_MSVC_VERSION "vc120") SET(ASSIMP_MSVC_VERSION "vc120")
elseif(MSVC14) ELSEIF(MSVC14)
SET(ASSIMP_MSVC_VERSION "vc140") SET(ASSIMP_MSVC_VERSION "vc140")
ELSEIF(MSVC15)
SET(ASSIMP_MSVC_VERSION "vc141")
ENDIF(MSVC12) ENDIF(MSVC12)
if(MSVC12 OR MSVC14) IF(MSVC12 OR MSVC14 OR MSVC15 )
add_custom_target(UpdateAssimpLibsDebugSymbolsAndDLLs COMMENT "Copying Assimp Libraries ..." VERBATIM) ADD_CUSTOM_TARGET(UpdateAssimpLibsDebugSymbolsAndDLLs COMMENT "Copying Assimp Libraries ..." VERBATIM)
IF(CMAKE_GENERATOR MATCHES "^Visual Studio") 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.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) 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)
@ -559,5 +526,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)
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()
ENDIF(MSVC12 OR MSVC14) ENDIF(MSVC12 OR MSVC14 OR MSVC15 )
ENDIF (WIN32) ENDIF (WIN32)

11
CONTRIBUTING.md 100644
View File

@ -0,0 +1,11 @@
#How to contribute
If you want to contribute you can follow these setps:
- Fist 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 ( just follow https://help.github.com/articles/creating-a-pull-request-from-a-fork/ )
- Push it to the repo and open a pull request
- A pull request will start our CI-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 fails: fix it and the tests will be reastarted automatically
- At the end we will perform a code review and merge your branch to the master branch.

View File

@ -32,32 +32,32 @@ Please check our Wiki as well: https://github.com/assimp/assimp/wiki
#### Supported file formats #### #### Supported file formats ####
A full list [is here](http://assimp.org/main_features_formats.html).
__Importers__: __Importers__:
- 3D - 3D
- 3DS - [3DS](https://en.wikipedia.org/wiki/.3ds)
- 3MF - [3MF](https://en.wikipedia.org/wiki/3D_Manufacturing_Format)
- AC - AC
- AC3D - [AC3D](https://en.wikipedia.org/wiki/AC3D)
- ACC - ACC
- AMJ - AMJ
- ASE - ASE
- ASK - ASK
- B3D - B3D
- BLEND (Blender) - [BLEND](https://en.wikipedia.org/wiki/.blend_(file_format))
- BVH - [BVH](https://en.wikipedia.org/wiki/Biovision_Hierarchy)
- COB
- CMS - CMS
- DAE/Collada - COB
- DXF - [DAE/Collada](https://en.wikipedia.org/wiki/COLLADA)
- [DXF](https://en.wikipedia.org/wiki/AutoCAD_DXF)
- ENFF - ENFF
- FBX - [FBX](https://en.wikipedia.org/wiki/FBX)
- glTF 1.0 + GLB - [glTF 1.0](https://en.wikipedia.org/wiki/GlTF#glTF_1.0) + GLB
- glTF 2.0 - [glTF 2.0](https://en.wikipedia.org/wiki/GlTF#glTF_2.0)
- HMB - HMB
- IFC-STEP - IFC-STEP
- IRR / IRRMESH - IRR / IRRMESH
- LWO - [LWO](https://en.wikipedia.org/wiki/LightWave_3D)
- LWS - LWS
- LXO - LXO
- MD2 - MD2
@ -70,10 +70,10 @@ __Importers__:
- MS3D - MS3D
- NDO - NDO
- NFF - NFF
- OBJ - [OBJ](https://en.wikipedia.org/wiki/Wavefront_.obj_file)
- OFF - [OFF](https://en.wikipedia.org/wiki/OFF_(file_format))
- OGEX - [OGEX](https://en.wikipedia.org/wiki/Open_Game_Engine_Exchange)
- PLY - [PLY](https://en.wikipedia.org/wiki/PLY_(file_format))
- PMX - PMX
- PRJ - PRJ
- Q3O - Q3O
@ -82,19 +82,19 @@ __Importers__:
- SCN - SCN
- SIB - SIB
- SMD - SMD
- STL - [STP](https://en.wikipedia.org/wiki/ISO_10303-21)
- STP - [STL](https://en.wikipedia.org/wiki/STL_(file_format))
- TER - TER
- UC - UC
- VTA - VTA
- X - X
- X3D - [X3D](https://en.wikipedia.org/wiki/X3D)
- XGL - XGL
- ZGL - ZGL
Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default): 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__: __Exporters__:
@ -109,6 +109,8 @@ __Exporters__:
- STEP - STEP
- glTF 1.0 (partial) - glTF 1.0 (partial)
- glTF 2.0 (partial) - glTF 2.0 (partial)
- 3MF ( experimental )
- FBX ( experimental )
### Building ### ### 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. 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`) /tools Tools (old assimp viewer, command line `assimp`)
/samples A small number of samples to illustrate possible /samples A small number of samples to illustrate possible
use cases for Assimp use cases for Assimp
/workspaces Build environments for vc,xcode,... (deprecated,
CMake has superseeded all legacy build options!)
### Where to get help ### ### Where to get help ###

View File

@ -10,10 +10,7 @@
# ASSIMP_LIBRARY_DIRS - link directories # ASSIMP_LIBRARY_DIRS - link directories
# ASSIMP_LIBRARIES - libraries to link plugins with # ASSIMP_LIBRARIES - libraries to link plugins with
# ASSIMP_Boost_VERSION - the boost version assimp was compiled with # ASSIMP_Boost_VERSION - the boost version assimp was compiled with
get_filename_component(_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) get_filename_component(ASSIMP_ROOT_DIR "@CMAKE_INSTALL_PREFIX@" REALPATH)
get_filename_component(_PREFIX "${_PREFIX}" PATH)
get_filename_component(_PREFIX "${_PREFIX}" PATH)
get_filename_component(ASSIMP_ROOT_DIR "${_PREFIX}" PATH)
if( MSVC ) if( MSVC )
# in order to prevent DLL hell, each of the DLLs have to be suffixed with the major version and msvc prefix # 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() else()
set(MSVC_PREFIX "vc150") set(MSVC_PREFIX "vc150")
endif() 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() 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() endif()
set( ASSIMP_CXX_FLAGS ) # dynamically linked library 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_LINK_FLAGS "" )
set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@") set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@")
set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@") set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@")
set( ASSIMP_LIBRARIES assimp${ASSIMP_LIBRARY_SUFFIX}) set( ASSIMP_LIBRARIES assimp${ASSIMP_LIBRARY_SUFFIX})
set( ASSIMP_LIBRARIES ${ASSIMP_LIBRARIES}@CMAKE_DEBUG_POSTFIX@) 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 # for compatibility with pkg-config
set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}") set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
set(ASSIMP_LDFLAGS_OTHER "${ASSIMP_LINK_FLAGS}") set(ASSIMP_LDFLAGS_OTHER "${ASSIMP_LINK_FLAGS}")
@ -74,7 +53,6 @@ MARK_AS_ADVANCED(
ASSIMP_LINK_FLAGS ASSIMP_LINK_FLAGS
ASSIMP_INCLUDE_DIRS ASSIMP_INCLUDE_DIRS
ASSIMP_LIBRARIES ASSIMP_LIBRARIES
ASSIMP_Boost_VERSION
ASSIMP_CFLAGS_OTHER ASSIMP_CFLAGS_OTHER
ASSIMP_LDFLAGS_OTHER ASSIMP_LDFLAGS_OTHER
ASSIMP_LIBRARY_SUFFIX ASSIMP_LIBRARY_SUFFIX

View File

@ -72,7 +72,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
unsigned int idx( NotSet ); unsigned int idx( NotSet );
for (unsigned int i = 0; i < mScene->mMaterials.size();++i) 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 ) { for ( std::string::iterator it = s.begin(); it != s.end(); ++it ) {
*it = static_cast< char >( ::tolower( *it ) ); *it = static_cast< char >( ::tolower( *it ) );
} }
@ -120,7 +120,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
else if ( (*a) >= mScene->mMaterials.size()) else if ( (*a) >= mScene->mMaterials.size())
{ {
(*a) = idx; (*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; ++cnt;
} }
} }
@ -132,7 +132,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f); sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f);
mScene->mMaterials.push_back(sMat); 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()) 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; (*i).mIndices[a] = (uint32_t)sMesh.mPositions.size()-1;
} }
if ( !sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size()) 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; (*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size()-1;
} }
} }
@ -497,7 +497,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
pvCurrent->x *= -1.f; pvCurrent->x *= -1.f;
t2->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 // Handle pivot point
@ -573,11 +573,11 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
pcIn->aTargetPositionKeys.size() > 1) pcIn->aTargetPositionKeys.size() > 1)
{ {
aiAnimation* anim = pcSOut->mAnimations[0]; aiAnimation* anim = pcSOut->mAnimations[0];
ai_assert(NULL != anim); ai_assert(nullptr != anim);
if (pcIn->aCameraRollKeys.size() > 1) 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 // Camera roll keys - in fact they're just rotations
// around the camera's z axis. The angles are given // around the camera's z axis. The angles are given
@ -597,7 +597,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
#if 0 #if 0
if (pcIn->aTargetPositionKeys.size() > 1) 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 // Camera or spot light - need to convert the separate
// target position channel to our representation // target position channel to our representation
@ -743,7 +743,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
// | | | | | // | | | | |
// MESH_0 MESH_1 MESH_2 ... MESH_N CAMERA_0 .... // 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 + pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes +
static_cast<unsigned int>(mScene->mCameras.size() + mScene->mLights.size()); static_cast<unsigned int>(mScene->mCameras.size() + mScene->mLights.size());

View File

@ -381,7 +381,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type
// TODO: handle embedded textures properly // TODO: handle embedded textures properly
if (path.data[0] == '*') { 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; return;
} }

View File

@ -258,8 +258,9 @@ void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk* pcOut)
if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSize()) if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSize())
throw DeadlyImportError("Chunk is too large"); throw DeadlyImportError("Chunk is too large");
if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit()) if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit()) {
DefaultLogger::get()->error("3DS: Chunk overflow"); ASSIMP_LOG_ERROR("3DS: Chunk overflow");
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -320,7 +321,7 @@ void Discreet3DSImporter::ParseEditorChunk()
// print the version number // print the version number
char buff[10]; char buff[10];
ASSIMP_itoa10(buff,stream->GetI2()); 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; break;
}; };
@ -361,7 +362,7 @@ void Discreet3DSImporter::ParseObjectChunk()
if (is_qnan(mClrAmbient.r)) if (is_qnan(mClrAmbient.r))
{ {
// We failed to read the ambient base color. // 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; mClrAmbient.r = mClrAmbient.g = mClrAmbient.b = 0.0f;
} }
break; break;
@ -463,7 +464,7 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
if (len < 1e-5) { if (len < 1e-5) {
// There are some files with lookat == position. Don't know why or whether it's ok or not. // 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); camera->mLookAt = aiVector3D(0.0,1.0,0.0);
} }
@ -629,9 +630,9 @@ void Discreet3DSImporter::SkipTCBInfo()
if (!flags) { if (!flags) {
// Currently we can't do anything with these values. They occur // Currently we can't do anything with these values. They occur
// quite rare, so it wouldn't be worth the effort implementing // 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. // 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) { 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 object name is DUMMY, take this one instead
if (mCurrentNode->mName == "$$$DUMMY") { if (mCurrentNode->mName == "$$$DUMMY") {
//DefaultLogger::get()->warn("3DS: Skipping dummy object name for non-dummy object");
mCurrentNode->mName = std::string(sz); mCurrentNode->mName = std::string(sz);
break; break;
} }
@ -743,7 +743,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
if ( Discreet3DS::CHUNK_TRACKINFO != 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; break;
} }
@ -805,7 +805,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
{ {
// roll keys are accepted for cameras only // roll keys are accepted for cameras only
if (parent != Discreet3DS::CHUNK_TRACKCAMERA) { 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; break;
} }
bool sortKeys = false; bool sortKeys = false;
@ -845,7 +845,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
// CAMERA FOV KEYFRAME // CAMERA FOV KEYFRAME
case Discreet3DS::CHUNK_TRACKFOV: case Discreet3DS::CHUNK_TRACKFOV:
{ {
DefaultLogger::get()->error("3DS: Skipping FOV animation track. " ASSIMP_LOG_ERROR("3DS: Skipping FOV animation track. "
"This is not supported"); "This is not supported");
} }
break; break;
@ -985,7 +985,7 @@ void Discreet3DSImporter::ParseFaceChunk()
} }
} }
if (0xcdcdcdcd == idx) { 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 // Now continue and read all material indices
@ -995,7 +995,7 @@ void Discreet3DSImporter::ParseFaceChunk()
// check range // check range
if (fidx >= mMesh.mFaceMaterials.size()) { 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; else mMesh.mFaceMaterials[fidx] = idx;
}} }}
@ -1110,7 +1110,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
if (!cnt) { if (!cnt) {
// This may not be, we use the default name instead // 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); else mScene->mMaterials.back().mName = std::string(sz,cnt);
} }
@ -1123,7 +1123,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
ParseColorChunk(pc); ParseColorChunk(pc);
if (is_qnan(pc->r)) { if (is_qnan(pc->r)) {
// color chunk is invalid. Simply ignore it // 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; pc->r = pc->g = pc->b = 1.0f;
}} }}
break; break;
@ -1135,7 +1135,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
ParseColorChunk(pc); ParseColorChunk(pc);
if (is_qnan(pc->r)) { if (is_qnan(pc->r)) {
// color chunk is invalid. Simply ignore it // 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; pc->r = pc->g = pc->b = 1.0f;
}} }}
break; break;
@ -1147,7 +1147,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
ParseColorChunk(pc); ParseColorChunk(pc);
if (is_qnan(pc->r)) { if (is_qnan(pc->r)) {
// color chunk is invalid. Simply ignore it // 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; pc->r = pc->g = pc->b = 0.0f;
}} }}
break; break;
@ -1159,7 +1159,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
ParseColorChunk(pc); ParseColorChunk(pc);
if (is_qnan(pc->r)) { if (is_qnan(pc->r)) {
// color chunk is invalid. Simply ignore it // 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; pc->r = pc->g = pc->b = 0.0f;
}} }}
break; break;
@ -1293,7 +1293,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
pcOut->mScaleU = stream->GetF4(); pcOut->mScaleU = stream->GetF4();
if (0.0f == pcOut->mScaleU) 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; pcOut->mScaleU = 1.0f;
} }
break; break;
@ -1302,7 +1302,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
pcOut->mScaleV = stream->GetF4(); pcOut->mScaleV = stream->GetF4();
if (0.0f == pcOut->mScaleV) 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; pcOut->mScaleV = 1.0f;
} }
break; break;

View File

@ -85,7 +85,7 @@ static const aiImporterDesc desc = {
#define AI_AC_SKIP_TO_NEXT_TOKEN() \ #define AI_AC_SKIP_TO_NEXT_TOKEN() \
if (!SkipSpaces(&buffer)) \ if (!SkipSpaces(&buffer)) \
{ \ { \
DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL"); \ ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL"); \
continue; \ continue; \
} }
@ -101,7 +101,7 @@ static const aiImporterDesc desc = {
{ \ { \
if (IsLineEnd( *buffer )) \ if (IsLineEnd( *buffer )) \
{ \ { \
DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL in string"); \ ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string"); \
out = "ERROR"; \ out = "ERROR"; \
break; \ break; \
} \ } \
@ -120,7 +120,7 @@ static const aiImporterDesc desc = {
{ \ { \
if (strncmp(buffer,name,name_length) || !IsSpace(buffer[name_length])) \ 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; \ continue; \
} \ } \
buffer += name_length+1; \ buffer += name_length+1; \
@ -217,7 +217,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i",static_cast<unsigned int>(mLights->size())-1); light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i",static_cast<unsigned int>(mLights->size())-1);
obj.name = std::string( light->mName.data ); 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; obj.type = Object::Light;
} }
else if (!ASSIMP_strincmp(buffer,"group",5)) else if (!ASSIMP_strincmp(buffer,"group",5))
@ -307,12 +307,12 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
{ {
if (!GetNextLine()) 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; break;
} }
else if (!IsNumeric(*buffer)) 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 --buffer; // make sure the line is processed a second time
break; break;
} }
@ -338,8 +338,8 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
// example writes no surf chunks // example writes no surf chunks
if (!Q3DWorkAround) if (!Q3DWorkAround)
{ {
DefaultLogger::get()->warn("AC3D: SURF token was expected"); ASSIMP_LOG_WARN("AC3D: SURF token was expected");
DefaultLogger::get()->debug("Continuing with Quick3D Workaround enabled"); ASSIMP_LOG_DEBUG("Continuing with Quick3D Workaround enabled");
} }
--buffer; // make sure the line is processed a second time --buffer; // make sure the line is processed a second time
// break; --- see fix notes above // break; --- see fix notes above
@ -384,7 +384,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
{ {
if(!GetNextLine()) if(!GetNextLine())
{ {
DefaultLogger::get()->error("AC3D: Unexpected EOF: surface references are incomplete"); ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: surface references are incomplete");
break; break;
} }
surf.entries.push_back(Surface::SurfaceEntry()); surf.entries.push_back(Surface::SurfaceEntry());
@ -405,7 +405,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& 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 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"); "a point list is returned");
meshes.push_back(new aiMesh()); meshes.push_back(new aiMesh());
@ -519,12 +519,12 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
unsigned int idx = (*it).mat; unsigned int idx = (*it).mat;
if (idx >= needMat.size()) 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; idx = 0;
} }
if ((*it).entries.empty()) 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 // 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()) if ((*it2).first >= object.vertices.size())
{ {
DefaultLogger::get()->warn("AC3D: Invalid vertex reference"); ASSIMP_LOG_WARN("AC3D: Invalid vertex reference");
(*it2).first = 0; (*it2).first = 0;
} }
} }
@ -561,7 +561,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
if ((*it).flags & 0xf) 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); (*it).flags &= ~(0xf);
} }
@ -712,7 +712,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
if (object.subDiv) { if (object.subDiv) {
if (configEvalSubdivision) { if (configEvalSubdivision) {
std::unique_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE)); std::unique_ptr<Subdivider> 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<aiMesh*> cpy(meshes.size()-oldm,NULL); std::vector<aiMesh*> cpy(meshes.size()-oldm,NULL);
div->Subdivide(&meshes[oldm],cpy.size(),&cpy.front(),object.subDiv,true); 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(). // previous meshes are deleted vy Subdivide().
} }
else { 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); +object.name);
} }
} }
@ -813,7 +813,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
unsigned int version = HexDigitToDecimal( buffer[4] ); unsigned int version = HexDigitToDecimal( buffer[4] );
char msg[3]; char msg[3];
ASSIMP_itoa10(msg,3,version); 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<Material> materials; std::vector<Material> materials;
materials.reserve(5); materials.reserve(5);
@ -857,7 +857,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
} }
if (materials.empty()) 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()); materials.push_back(Material());
} }

View File

@ -230,7 +230,7 @@ casu_cres:
if(!skipped_before[sk_idx]) if(!skipped_before[sk_idx])
{ {
skipped_before[sk_idx] = true; skipped_before[sk_idx] = true;
LogWarning("Skipping node \"" + nn + "\" in " + pParentNodeName + "."); ASSIMP_LOG_WARN_F("Skipping node \"", nn, "\" in ", pParentNodeName, ".");
} }
} }

View File

@ -358,18 +358,6 @@ private:
/************** Functions: LOG set *************/ /************** 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 *************/ /************** Functions: XML set *************/
/***********************************************/ /***********************************************/

View File

@ -71,7 +71,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
} }
/// \def MACRO_ATTRREAD_CHECK_REF /// \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. /// "continue" will called.
/// \param [in] pAttrName - attribute name. /// \param [in] pAttrName - attribute name.
/// \param [out] pVarName - output variable 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 /// \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. /// If result was read then "continue" will called.
/// \param [in] pAttrName - attribute name. /// \param [in] pAttrName - attribute name.
/// \param [out] pVarName - output variable 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) } while(false)
/// \def MACRO_NODECHECK_READCOMP_F /// \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. /// 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] pNodeName - node name.
/// \param [in, out] pReadFlag - read flag. /// \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 /// \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. /// 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] pNodeName - node name.
/// \param [in, out] pReadFlag - read flag. /// \param [in, out] pReadFlag - read flag.

View File

@ -99,7 +99,7 @@ CAMFImporter_NodeElement* ne;
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
// check that all components was defined // check that all components was defined
if(!(read_flag[0] && read_flag[1] && read_flag[2])) throw DeadlyImportError("Not all color components are defined."); if(!(read_flag[0] && read_flag[1] && read_flag[2])) throw DeadlyImportError("Not all color components are defined.");
// check if <a> is absent. Then manualy add "a == 1". // check if <a> is absent. Then manually add "a == 1".
if(!read_flag[3]) als.Color.a = 1; if(!read_flag[3]) als.Color.a = 1;
}// if(!mReader->isEmptyElement()) }// if(!mReader->isEmptyElement())

View File

@ -156,10 +156,11 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string&
TextureConverted_Index = 0; TextureConverted_Index = 0;
for(const SPP_Texture& tex_convd: mTexture_Converted) for(const SPP_Texture& tex_convd: mTexture_Converted)
{ {
if(tex_convd.ID == TextureConverted_ID) if ( tex_convd.ID == TextureConverted_ID ) {
return TextureConverted_Index; return TextureConverted_Index;
else } else {
TextureConverted_Index++; ++TextureConverted_Index;
}
} }
// //
@ -769,7 +770,7 @@ std::list<aiNode*> ch_node;
// find referenced object // find referenced object
if(!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID); 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 = new aiNode;
t_node->mParent = con_node; t_node->mParent = con_node;
// apply transformation // apply transformation

View File

@ -200,7 +200,7 @@ void ASEImporter::InternReadFile( const std::string& pFile,
ConvertMeshes(*i,avOutMeshes); ConvertMeshes(*i,avOutMeshes);
} }
if (tookNormals) { 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 " "the AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS setting if you "
"experience problems"); "experience problems");
} }
@ -297,15 +297,15 @@ void ASEImporter::BuildAnimations(const std::vector<BaseNode*>& nodes)
// TODO: Implement Bezier & TCB support // TODO: Implement Bezier & TCB support
if ((*i)->mAnim.mPositionType != ASE::Animation::TRACK) { 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."); "This is not supported.");
} }
if ((*i)->mAnim.mRotationType != ASE::Animation::TRACK) { 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."); "This is not supported.");
} }
if ((*i)->mAnim.mScalingType != ASE::Animation::TRACK) { 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."); "This is not supported.");
} }
@ -624,7 +624,7 @@ void ASEImporter::AddNodes (const std::vector<BaseNode*>& nodes,
node->mNumChildren++; node->mNumChildren++;
// What we did is so great, it is at least worth a debug message // 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<aiMesh*>& avOutMesh
// validate the material index of the mesh // validate the material index of the mesh
if (mesh.iMaterialIndex >= mParser->m_vMaterials.size()) { if (mesh.iMaterialIndex >= mParser->m_vMaterials.size()) {
mesh.iMaterialIndex = (unsigned int)mParser->m_vMaterials.size()-1; 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 // 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<aiMesh*>& avOutMesh
std::vector<unsigned int>* aiSplit = new std::vector<unsigned int>[vSubMaterials.size()]; std::vector<unsigned int>* aiSplit = new std::vector<unsigned int>[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) { for (unsigned int i = 0; i < mesh.mFaces.size();++i) {
// check range // check range
if (mesh.mFaces[i].iMaterial >= vSubMaterials.size()) { 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 // use the last material instead
aiSplit[vSubMaterials.size()-1].push_back(i); aiSplit[vSubMaterials.size()-1].push_back(i);

View File

@ -151,7 +151,7 @@ void Parser::LogWarning(const char* szWarn)
#endif #endif
// output the warning to the logger ... // 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 #endif
// output the information to the logger ... // 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) // at the file extension (ASE, ASK, ASC)
// ************************************************************* // *************************************************************
if (fmt)iFileFormat = fmt; if ( fmt ) {
iFileFormat = fmt;
}
continue; continue;
} }
// main scene information // main scene information
@ -427,27 +429,24 @@ void Parser::ParseLV1SoftSkinBlock()
// Reserve enough storage // Reserve enough storage
vert.mBoneWeights.reserve(numWeights); 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"); ParseString(bone,"*MESH_SOFTSKINVERTS.Bone");
// Find the bone in the mesh's list // Find the bone in the mesh's list
std::pair<int,ai_real> me; std::pair<int,ai_real> me;
me.first = -1; me.first = -1;
for (unsigned int n = 0; n < curMesh->mBones.size();++n) for (unsigned int n = 0; n < curMesh->mBones.size();++n) {
{ if (curMesh->mBones[n].mName == bone) {
if (curMesh->mBones[n].mName == bone)
{
me.first = n; me.first = n;
break; break;
} }
} }
if (-1 == me.first) if (-1 == me.first) {
{
// We don't have this bone yet, so add it to the list // We don't have this bone yet, so add it to the list
me.first = (int)curMesh->mBones.size(); me.first = static_cast<int>( curMesh->mBones.size() );
curMesh->mBones.push_back( ASE::Bone( bone ) ); curMesh->mBones.push_back( ASE::Bone( bone ) );
} }
ParseLV4MeshFloat( me.second ); ParseLV4MeshFloat( me.second );
@ -745,6 +744,7 @@ void Parser::ParseLV3MapBlock(Texture& map)
// empty the texture won't be used later. // empty the texture won't be used later.
// *********************************************************** // ***********************************************************
bool parsePath = true; bool parsePath = true;
std::string temp;
while (true) while (true)
{ {
if ('*' == *filePtr) if ('*' == *filePtr)
@ -753,12 +753,12 @@ void Parser::ParseLV3MapBlock(Texture& map)
// type of map // type of map
if (TokenMatch(filePtr,"MAP_CLASS" ,9)) if (TokenMatch(filePtr,"MAP_CLASS" ,9))
{ {
std::string temp; temp.clear();
if(!ParseString(temp,"*MAP_CLASS")) if(!ParseString(temp,"*MAP_CLASS"))
SkipToNextToken(); SkipToNextToken();
if (temp != "Bitmap" && temp != "Normal Bump") 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; parsePath = false;
} }
continue; continue;
@ -773,7 +773,7 @@ void Parser::ParseLV3MapBlock(Texture& map)
{ {
// Files with 'None' as map name are produced by // Files with 'None' as map name are produced by
// an Maja to ASE exporter which name I forgot .. // 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 = ""; map.mMapName = "";
} }
@ -1072,7 +1072,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh)
( mesh.mType != BaseNode::Light || ((ASE::Light&)mesh).mLightType != ASE::Light::TARGET)) ( 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"); "but the node is neither a camera nor a spot light");
anim = NULL; anim = NULL;
} }
@ -1098,7 +1098,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh)
if (!anim || anim == &mesh.mTargetAnim) if (!anim || anim == &mesh.mTargetAnim)
{ {
// Target animation channels may have no rotation channels // 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(); SkipSection();
} }
else ParseLV3ScaleAnimationBlock(*anim); else ParseLV3ScaleAnimationBlock(*anim);
@ -1112,7 +1112,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh)
if (!anim || anim == &mesh.mTargetAnim) if (!anim || anim == &mesh.mTargetAnim)
{ {
// Target animation channels may have no rotation channels // 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(); SkipSection();
} }
else ParseLV3RotAnimationBlock(*anim); else ParseLV3RotAnimationBlock(*anim);
@ -1295,12 +1295,14 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode& mesh)
{ {
mode = 2; mode = 2;
} }
else DefaultLogger::get()->error("ASE: Ignoring target transform, " else {
ASSIMP_LOG_ERROR("ASE: Ignoring target transform, "
"this is no spot light or target camera"); "this is no spot light or target camera");
} }
}
else else
{ {
DefaultLogger::get()->error("ASE: Unknown node transformation: " + temp); ASSIMP_LOG_ERROR("ASE: Unknown node transformation: " + temp);
// mode = 0 // mode = 0
} }
continue; continue;
@ -1916,7 +1918,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
else if (index == face.mIndices[2]) else if (index == face.mIndices[2])
index = 2; index = 2;
else { else {
DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_VERTEXNORMAL section"); ASSIMP_LOG_ERROR("ASE: Invalid vertex index in MESH_VERTEXNORMAL section");
continue; continue;
} }
// We'll renormalize later // We'll renormalize later
@ -1928,7 +1930,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
ParseLV4MeshFloatTriple(&vNormal.x,faceIdx); ParseLV4MeshFloatTriple(&vNormal.x,faceIdx);
if (faceIdx >= sMesh.mFaces.size()) { 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; continue;
} }

View File

@ -427,7 +427,7 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Construct a parser from a given input file which is //! 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 szFile Input file
//! @param fileFormatDefault Assumed file format version. If the //! @param fileFormatDefault Assumed file format version. If the
//! file format is specified in the file the new value replaces //! file format is specified in the file the new value replaces

View File

@ -146,7 +146,7 @@ private:
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ReportSceneNotFoundError() { 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"); "The C-API does not accept scenes produced by the C++ API and vice versa");
ai_assert(false); ai_assert(false);

View File

@ -614,7 +614,7 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
if (!DefaultLogger::isNullLogger()) { if (!DefaultLogger::isNullLogger()) {
char dmp[128]; char dmp[128];
ai_snprintf(dmp, 128, "B3D file format version: %i",version); ai_snprintf(dmp, 128, "B3D file format version: %i",version);
DefaultLogger::get()->info(dmp); ASSIMP_LOG_INFO(dmp);
} }
while( ChunkSize() ){ while( ChunkSize() ){

View File

@ -199,6 +199,7 @@ aiNode* BVHLoader::ReadNode()
Node& internNode = mNodes.back(); Node& internNode = mNodes.back();
// now read the node's contents // now read the node's contents
std::string siteToken;
while( 1) while( 1)
{ {
std::string token = GetNextToken(); std::string token = GetNextToken();
@ -218,7 +219,8 @@ aiNode* BVHLoader::ReadNode()
else if( token == "End") else if( token == "End")
{ {
// The real symbol is "End Site". Second part comes in a separate token // The real symbol is "End Site". Second part comes in a separate token
std::string siteToken = GetNextToken(); siteToken.clear();
siteToken = GetNextToken();
if( siteToken != "Site") if( siteToken != "Site")
ThrowException( format() << "Expected \"End Site\" keyword, but found \"" << token << " " << siteToken << "\"." ); 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); aiNode* node = new aiNode( "EndSite_" + pParentName);
// now read the node's contents. Only possible entry is "OFFSET" // now read the node's contents. Only possible entry is "OFFSET"
while( 1) std::string token;
{ while( 1) {
std::string token = GetNextToken(); token.clear();
token = GetNextToken();
// end node's offset // end node's offset
if( token == "OFFSET") if( token == "OFFSET") {
{
ReadNodeOffset( node); ReadNodeOffset( node);
} } else if( token == "}") {
else if( token == "}")
{
// we're done with the end node // we're done with the end node
break; break;
} else } else {
{
// everything else is a parse error // everything else is a parse error
ThrowException( format() << "Unknown keyword \"" << token << "\"." ); ThrowException( format() << "Unknown keyword \"" << token << "\"." );
} }
@ -296,8 +295,10 @@ void BVHLoader::ReadNodeOffset( aiNode* pNode)
offset.z = GetNextTokenAsFloat(); offset.z = GetNextTokenAsFloat();
// build a transformation matrix from it // 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, pNode->mTransformation = aiMatrix4x4( 1.0f, 0.0f, 0.0f, offset.x,
0.0f, 0.0f, 1.0f, offset.z, 0.0f, 0.0f, 0.0f, 1.0f); 0.0f, 1.0f, 0.0f, offset.y,
0.0f, 0.0f, 1.0f, offset.z,
0.0f, 0.0f, 0.0f, 1.0f);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -64,23 +64,24 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
BaseImporter::BaseImporter() BaseImporter::BaseImporter()
: m_progress() : m_progress() {
{
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
BaseImporter::~BaseImporter() BaseImporter::~BaseImporter() {
{
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file and returns the imported data. // 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(); m_progress = pImp->GetProgressHandler();
if (nullptr == m_progress) {
return nullptr;
}
ai_assert(m_progress); ai_assert(m_progress);
// Gather configuration properties for this run // 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 ) { } catch( const std::exception& err ) {
// extract error description // extract error description
m_ErrorText = err.what(); m_ErrorText = err.what();
DefaultLogger::get()->error(m_ErrorText); ASSIMP_LOG_ERROR(m_ErrorText);
return NULL; return nullptr;
} }
// return what we gathered from the import. // return what we gathered from the import.
@ -195,7 +196,7 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
// We got a match, either we don't care where it is, or it happens to // We got a match, either we don't care where it is, or it happens to
// be in the beginning of the file / line // be in the beginning of the file / line
if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') { 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; return true;
} }
} }
@ -251,7 +252,8 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
/* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile, /* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile,
const void* _magic, unsigned int num, unsigned int offset, unsigned int size) 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) { if (!pIOHandler) {
return false; return false;
@ -321,7 +323,7 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
// UTF 8 with BOM // UTF 8 with BOM
if((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) { 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()); std::copy(data.begin()+3,data.end(),data.begin());
data.resize(data.size()-3); data.resize(data.size()-3);
@ -340,7 +342,7 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
// UTF 32 LE with BOM // UTF 32 LE with BOM
if(*((uint32_t*)&data.front()) == 0x0000FFFE) { if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
DefaultLogger::get()->debug("Found UTF-32 BOM ..."); ASSIMP_LOG_DEBUG("Found UTF-32 BOM ...");
std::vector<char> output; std::vector<char> output;
int *ptr = (int*)&data[ 0 ]; int *ptr = (int*)&data[ 0 ];
@ -360,7 +362,7 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
// UTF 16 LE with BOM // UTF 16 LE with BOM
if(*((uint16_t*)&data.front()) == 0xFEFF) { if(*((uint16_t*)&data.front()) == 0xFEFF) {
DefaultLogger::get()->debug("Found UTF-16 BOM ..."); ASSIMP_LOG_DEBUG("Found UTF-16 BOM ...");
std::vector<unsigned char> output; std::vector<unsigned char> output;
utf8::utf16to8(data.begin(), data.end(), back_inserter(output)); utf8::utf16to8(data.begin(), data.end(), back_inserter(output));
@ -385,16 +387,14 @@ void BaseImporter::ConvertUTF8toISO8859_1(std::string& data)
data[j] = ((unsigned char) data[++i] + 0x40); data[j] = ((unsigned char) data[++i] + 0x40);
} else { } else {
std::stringstream stream; std::stringstream stream;
stream << "UTF8 code " << std::hex << data[i] << data[i + 1] << " can not be converted into ISA-8859-1."; stream << "UTF8 code " << std::hex << data[i] << data[i + 1] << " can not be converted into ISA-8859-1.";
ASSIMP_LOG_ERROR( stream.str() );
DefaultLogger::get()->error(stream.str());
data[j++] = data[i++]; data[j++] = data[i++];
data[j] = data[i]; data[j] = data[i];
} }
} else { } 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]; data[j] = data[i];
} }
@ -410,7 +410,7 @@ void BaseImporter::TextFileToBuffer(IOStream* stream,
std::vector<char>& data, std::vector<char>& data,
TextFileMode mode) TextFileMode mode)
{ {
ai_assert(NULL != stream); ai_assert(nullptr != stream);
const size_t fileSize = stream->FileSize(); const size_t fileSize = stream->FileSize();
if (mode == FORBID_EMPTY) { if (mode == FORBID_EMPTY) {
@ -471,14 +471,14 @@ struct Assimp::BatchData {
, pImporter( nullptr ) , pImporter( nullptr )
, next_id(0xffff) , next_id(0xffff)
, validate( validate ) { , validate( validate ) {
ai_assert( NULL != pIO ); ai_assert( nullptr != pIO );
pImporter = new Importer(); pImporter = new Importer();
pImporter->SetIOHandler( pIO ); pImporter->SetIOHandler( pIO );
} }
~BatchData() { ~BatchData() {
pImporter->SetIOHandler( NULL ); /* get pointer back into our possession */ pImporter->SetIOHandler( nullptr ); /* get pointer back into our possession */
delete pImporter; delete pImporter;
} }
@ -504,9 +504,8 @@ struct Assimp::BatchData {
typedef std::list<LoadRequest>::iterator LoadReqIt; typedef std::list<LoadRequest>::iterator LoadReqIt;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
BatchLoader::BatchLoader(IOSystem* pIO, bool validate ) BatchLoader::BatchLoader(IOSystem* pIO, bool validate ) {
{ ai_assert(nullptr != pIO);
ai_assert(NULL != pIO);
m_data = new BatchData( pIO, validate ); m_data = new BatchData( pIO, validate );
} }
@ -572,7 +571,7 @@ aiScene* BatchLoader::GetImport( unsigned int which )
return sc; return sc;
} }
} }
return NULL; return nullptr;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -595,13 +594,13 @@ void BatchLoader::LoadAll()
if (!DefaultLogger::isNullLogger()) if (!DefaultLogger::isNullLogger())
{ {
DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%"); ASSIMP_LOG_INFO("%%% BEGIN EXTERNAL FILE %%%");
DefaultLogger::get()->info("File: " + (*it).file); ASSIMP_LOG_INFO_F("File: ", (*it).file);
} }
m_data->pImporter->ReadFile((*it).file,pp); m_data->pImporter->ReadFile((*it).file,pp);
(*it).scene = m_data->pImporter->GetOrphanedScene(); (*it).scene = m_data->pImporter->GetOrphanedScene();
(*it).loaded = true; (*it).loaded = true;
DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%"); ASSIMP_LOG_INFO("%%% END EXTERNAL FILE %%%");
} }
} }

View File

@ -85,7 +85,7 @@ void BaseProcess::ExecuteOnScene( Importer* pImp)
// extract error description // extract error description
pImp->Pimpl()->mErrorString = err.what(); pImp->Pimpl()->mErrorString = err.what();
DefaultLogger::get()->error(pImp->Pimpl()->mErrorString); ASSIMP_LOG_ERROR(pImp->Pimpl()->mErrorString);
// and kill the partially imported data // and kill the partially imported data
delete pImp->Pimpl()->mScene; delete pImp->Pimpl()->mScene;

View File

@ -210,8 +210,7 @@ void DNAParser::Parse ()
s.size = offset; s.size = offset;
} }
DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(), ASSIMP_LOG_DEBUG_F( "BlenderDNA: Got ", dna.structures.size()," structures with totally ",fields," fields");
" structures with totally ",fields," fields"));
#ifdef ASSIMP_BUILD_BLENDER_DEBUG #ifdef ASSIMP_BUILD_BLENDER_DEBUG
dna.DumpToFile(); dna.DumpToFile();
@ -228,12 +227,12 @@ void DNAParser::Parse ()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DNA :: DumpToFile() 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). // (and all your bases are belong to us).
std::ofstream f("dna.txt"); std::ofstream f("dna.txt");
if (f.fail()) { if (f.fail()) {
DefaultLogger::get()->error("Could not dump dna to dna.txt"); ASSIMP_LOG_ERROR("Could not dump dna to dna.txt");
return; return;
} }
f << "Field format: type name offset size" << "\n"; f << "Field format: type name offset size" << "\n";
@ -248,7 +247,7 @@ void DNA :: DumpToFile()
} }
f << std::flush; f << std::flush;
DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt"); ASSIMP_LOG_INFO("BlenderDNA: Dumped dna to dna.txt");
} }
#endif #endif
@ -367,7 +366,7 @@ void SectionParser :: Next()
} }
#ifdef ASSIMP_BUILD_BLENDER_DEBUG #ifdef ASSIMP_BUILD_BLENDER_DEBUG
DefaultLogger::get()->debug(current.id); ASSIMP_LOG_DEBUG(current.id);
#endif #endif
} }

View File

@ -381,7 +381,7 @@ template <> struct Structure :: _defaultInitializer<ErrorPolicy_Warn> {
template <typename T> template <typename T>
void operator ()(T& out, const char* reason = "<add reason>") { void operator ()(T& out, const char* reason = "<add reason>") {
DefaultLogger::get()->warn(reason); ASSIMP_LOG_WARN(reason);
// ... and let the show go on // ... and let the show go on
_defaultInitializer<0 /*ErrorPolicy_Igno*/>()(out); _defaultInitializer<0 /*ErrorPolicy_Igno*/>()(out);
@ -663,7 +663,7 @@ public:
/** Check whether a specific item is in the cache. /** Check whether a specific item is in the cache.
* @param s Data type of the item * @param s Data type of the item
* @param out Output pointer. Unchanged if the * @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. */ * @param ptr Item address to look for. */
template <typename T> void get ( template <typename T> void get (
const Structure& s, const Structure& s,

View File

@ -468,9 +468,7 @@ template <> bool Structure :: ResolvePointer<std::shared_ptr,ElemBase>(std::shar
// this might happen if DNA::RegisterConverters hasn't been called so far // this might happen if DNA::RegisterConverters hasn't been called so far
// or if the target type is not contained in `our` DNA. // or if the target type is not contained in `our` DNA.
out.reset(); out.reset();
DefaultLogger::get()->warn((Formatter::format(), ASSIMP_LOG_WARN_F( "Failed to find a converter for the `",s.name,"` structure" );
"Failed to find a converter for the `",s.name,"` structure"
));
return false; return false;
} }

View File

@ -327,12 +327,12 @@ void BlenderImporter::ExtractScene(Scene& out, const FileDatabase& file)
ss.Convert(out,file); ss.Convert(out,file);
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS #ifndef ASSIMP_BUILD_BLENDER_NO_STATS
DefaultLogger::get()->info((format(), ASSIMP_LOG_INFO_F(
"(Stats) Fields read: " ,file.stats().fields_read, "(Stats) Fields read: " ,file.stats().fields_read,
", pointers resolved: " ,file.stats().pointers_resolved, ", pointers resolved: " ,file.stats().pointers_resolved,
", cache hits: " ,file.stats().cache_hits, ", cache hits: " ,file.stats().cache_hits,
", cached objects: " ,file.stats().cached_objects ", cached objects: " ,file.stats().cached_objects
)); );
#endif #endif
} }

View File

@ -70,34 +70,6 @@ static const fpCreateModifier creators[] = {
NULL // sentinel NULL // sentinel
}; };
// ------------------------------------------------------------------------------------------------
// just testing out some new macros to simplify logging
#define ASSIMP_LOG_WARN_F(string,...)\
DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_ERROR_F(string,...)\
DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_DEBUG_F(string,...)\
DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_INFO_F(string,...)\
DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_WARN(string)\
DefaultLogger::get()->warn(string)
#define ASSIMP_LOG_ERROR(string)\
DefaultLogger::get()->error(string)
#define ASSIMP_LOG_DEBUG(string)\
DefaultLogger::get()->debug(string)
#define ASSIMP_LOG_INFO(string)\
DefaultLogger::get()->info(string)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct SharedModifierData : ElemBase struct SharedModifierData : ElemBase
{ {

View File

@ -47,53 +47,57 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define INCLUDED_AI_BLEND_MODIFIER_H #define INCLUDED_AI_BLEND_MODIFIER_H
#include "BlenderIntermediate.h" #include "BlenderIntermediate.h"
#include <assimp/TinyFormatter.h>
namespace Assimp { namespace Assimp {
namespace Blender { namespace Blender {
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Dummy base class for all blender modifiers. Modifiers are reused between imports, so /**
* they should be stateless and not try to cache model data. */ * Dummy base class for all blender modifiers. Modifiers are reused between imports, so
* they should be stateless and not try to cache model data.
*/
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifier class BlenderModifier {
{
public: public:
/**
* The class destructor, virtual.
*/
virtual ~BlenderModifier() { virtual ~BlenderModifier() {
// empty // empty
} }
public:
// -------------------- // --------------------
/** Check if *this* modifier is active, given a ModifierData& block.*/ /**
* Check if *this* modifier is active, given a ModifierData& block.
*/
virtual bool IsActive( const ModifierData& /*modin*/) { virtual bool IsActive( const ModifierData& /*modin*/) {
return false; return false;
} }
// -------------------- // --------------------
/** Apply the modifier to a given output node. The original data used /**
* Apply the modifier to a given output node. The original data used
* to construct the node is given as well. Not called unless IsActive() * to construct the node is given as well. Not called unless IsActive()
* was called and gave positive response. */ * was called and gave positive response.
*/
virtual void DoIt(aiNode& /*out*/, virtual void DoIt(aiNode& /*out*/,
ConversionData& /*conv_data*/, ConversionData& /*conv_data*/,
const ElemBase& orig_modifier, const ElemBase& orig_modifier,
const Scene& /*in*/, const Scene& /*in*/,
const Object& /*orig_object*/ const Object& /*orig_object*/
) { ) {
DefaultLogger::get()->warn((Formatter::format("This modifier is not supported, skipping: "),orig_modifier.dna_type)); ASSIMP_LOG_INFO_F("This modifier is not supported, skipping: ",orig_modifier.dna_type );
return; return;
} }
}; };
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Manage all known modifiers and instance and apply them if necessary */ /**
* Manage all known modifiers and instance and apply them if necessary
*/
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifierShowcase class BlenderModifierShowcase {
{
public: public:
// -------------------- // --------------------
/** Apply all requested modifiers provided we support them. */ /** Apply all requested modifiers provided we support them. */
void ApplyModifiers(aiNode& out, void ApplyModifiers(aiNode& out,
@ -103,25 +107,18 @@ public:
); );
private: private:
TempArray< std::vector,BlenderModifier > cached_modifiers; TempArray< std::vector,BlenderModifier > cached_modifiers;
}; };
// MODIFIERS /////////////////////////////////////////////////////////////////////////////////
// MODIFIERS
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Mirror modifier. Status: implemented. */ /**
* Mirror modifier. Status: implemented.
*/
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifier_Mirror : public BlenderModifier class BlenderModifier_Mirror : public BlenderModifier {
{
public: public:
// -------------------- // --------------------
virtual bool IsActive( const ModifierData& modin); virtual bool IsActive( const ModifierData& modin);
@ -137,8 +134,7 @@ public:
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Subdivision modifier. Status: dummy. */ /** Subdivision modifier. Status: dummy. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifier_Subdivision : public BlenderModifier class BlenderModifier_Subdivision : public BlenderModifier {
{
public: public:
// -------------------- // --------------------
@ -153,6 +149,7 @@ public:
) ; ) ;
}; };
}
}
}}
#endif // !INCLUDED_AI_BLEND_MODIFIER_H #endif // !INCLUDED_AI_BLEND_MODIFIER_H

View File

@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define INCLUDED_AI_BLEND_TESSELLATOR_H #define INCLUDED_AI_BLEND_TESSELLATOR_H
// Use these to toggle between GLU Tessellate or poly2tri // Use these to toggle between GLU Tessellate or poly2tri
// Note (acg) keep GLU Tesselate disabled by default - if it is turned on, // Note (acg) keep GLU Tessellate disabled by default - if it is turned on,
// assimp needs to be linked against GLU, which is currently not yet // assimp needs to be linked against GLU, which is currently not yet
// made configurable in CMake and potentially not wanted by most users // made configurable in CMake and potentially not wanted by most users
// as it requires a Gl environment. // as it requires a Gl environment.

View File

@ -177,8 +177,6 @@ SET( Common_SRCS
SkeletonMeshBuilder.cpp SkeletonMeshBuilder.cpp
SplitByBoneCountProcess.cpp SplitByBoneCountProcess.cpp
SplitByBoneCountProcess.h SplitByBoneCountProcess.h
ScaleProcess.cpp
ScaleProcess.h
StandardShapes.cpp StandardShapes.cpp
TargetAnimation.cpp TargetAnimation.cpp
TargetAnimation.h TargetAnimation.h
@ -188,6 +186,8 @@ SET( Common_SRCS
Bitmap.cpp Bitmap.cpp
Version.cpp Version.cpp
CreateAnimMesh.cpp CreateAnimMesh.cpp
simd.h
simd.cpp
) )
SOURCE_GROUP(Common FILES ${Common_SRCS}) SOURCE_GROUP(Common FILES ${Common_SRCS})
@ -208,8 +208,15 @@ OPTION(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT "default value of all ASSIMP_BUILD_
# macro to add the CMake Option ADD_ASSIMP_IMPORTER_<name> which enables compile of loader # macro to add the CMake Option ADD_ASSIMP_IMPORTER_<name> which enables compile of loader
# this way selective loaders can be compiled (reduces filesize + compile time) # this way selective loaders can be compiled (reduces filesize + compile time)
MACRO(ADD_ASSIMP_IMPORTER name) MACRO(ADD_ASSIMP_IMPORTER name)
OPTION(ASSIMP_BUILD_${name}_IMPORTER "build the ${name} importer" ${ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT}) IF (ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT)
IF(ASSIMP_BUILD_${name}_IMPORTER) set(ASSIMP_IMPORTER_ENABLED TRUE)
IF (DEFINED ASSIMP_BUILD_${name}_IMPORTER AND NOT ASSIMP_BUILD_${name}_IMPORTER)
set(ASSIMP_IMPORTER_ENABLED FALSE)
ENDIF ()
ELSE ()
set(ASSIMP_IMPORTER_ENABLED ${ASSIMP_BUILD_${name}_IMPORTER})
ENDIF ()
IF (ASSIMP_IMPORTER_ENABLED)
LIST(APPEND ASSIMP_LOADER_SRCS ${ARGN}) LIST(APPEND ASSIMP_LOADER_SRCS ${ARGN})
SET(ASSIMP_IMPORTERS_ENABLED "${ASSIMP_IMPORTERS_ENABLED} ${name}") SET(ASSIMP_IMPORTERS_ENABLED "${ASSIMP_IMPORTERS_ENABLED} ${name}")
SET(${name}_SRCS ${ARGN}) SET(${name}_SRCS ${ARGN})
@ -485,9 +492,9 @@ ADD_ASSIMP_IMPORTER( IFC
) )
if (ASSIMP_BUILD_IFC_IMPORTER) if (ASSIMP_BUILD_IFC_IMPORTER)
if (MSVC) if (MSVC)
set_source_files_properties(IFCReaderGen1.cpp IFCReaderGen2.cpp PROPERTIES COMPILE_FLAGS "/bigobj") set_source_files_properties(Importer/IFC/IFCReaderGen1_2x3.cpp Importer/IFC/IFCReaderGen2_2x3.cpp PROPERTIES COMPILE_FLAGS "/bigobj")
elseif(CMAKE_COMPILER_IS_MINGW) elseif(CMAKE_COMPILER_IS_MINGW)
set_source_files_properties(IFCReaderGen1.cpp IFCReaderGen2.cpp PROPERTIES COMPILE_FLAGS "-O2 -Wa,-mbig-obj") set_source_files_properties(Importer/IFC/IFCReaderGen1_2x3.cpp Importer/IFC/IFCReaderGen2_2x3.cpp PROPERTIES COMPILE_FLAGS "-O2 -Wa,-mbig-obj")
endif() endif()
endif (ASSIMP_BUILD_IFC_IMPORTER) endif (ASSIMP_BUILD_IFC_IMPORTER)
@ -586,6 +593,8 @@ SET( PostProcessing_SRCS
PolyTools.h PolyTools.h
MakeVerboseFormat.cpp MakeVerboseFormat.cpp
MakeVerboseFormat.h MakeVerboseFormat.h
ScaleProcess.cpp
ScaleProcess.h
) )
SOURCE_GROUP( PostProcessing FILES ${PostProcessing_SRCS}) SOURCE_GROUP( PostProcessing FILES ${PostProcessing_SRCS})

View File

@ -47,11 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_COB_IMPORTER #ifndef ASSIMP_BUILD_NO_COB_IMPORTER
#include "COBLoader.h" #include "COBLoader.h"
#include "COBScene.h" #include "COBScene.h"
#include "ConvertToLHProcess.h"
#include <assimp/StreamReader.h> #include <assimp/StreamReader.h>
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <assimp/LineSplitter.h> #include <assimp/LineSplitter.h>
#include <assimp/TinyFormatter.h> #include <assimp/TinyFormatter.h>
#include <memory> #include <memory>
@ -105,7 +104,7 @@ COBImporter::~COBImporter()
bool COBImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool COBImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{ {
const std::string& extension = GetExtension(pFile); const std::string& extension = GetExtension(pFile);
if (extension == "cob" || extension == "scn") { if (extension == "cob" || extension == "scn" || extension == "COB" || extension == "SCN") {
return true; return true;
} }
@ -151,7 +150,7 @@ void COBImporter::InternReadFile( const std::string& pFile,
ThrowException("Could not found magic id: `Caligari`"); ThrowException("Could not found magic id: `Caligari`");
} }
DefaultLogger::get()->info("File format tag: "+std::string(head+9,6)); ASSIMP_LOG_INFO_F("File format tag: ",std::string(head+9,6));
if (head[16]!='L') { if (head[16]!='L') {
ThrowException("File is big-endian, which is not supported"); ThrowException("File is big-endian, which is not supported");
} }
@ -225,6 +224,9 @@ void COBImporter::InternReadFile( const std::string& pFile,
} }
pScene->mRootNode = BuildNodes(*root.get(),scene,pScene); pScene->mRootNode = BuildNodes(*root.get(),scene,pScene);
//flip normals after import
FlipWindingOrderProcess flip;
flip.Execute( pScene );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -301,7 +303,7 @@ aiNode* COBImporter::BuildNodes(const Node& root,const Scene& scin,aiScene* fill
} }
std::unique_ptr<const Material> defmat; std::unique_ptr<const Material> defmat;
if(!min) { if(!min) {
DefaultLogger::get()->debug(format()<<"Could not resolve material index " ASSIMP_LOG_DEBUG(format()<<"Could not resolve material index "
<<reflist.first<<" - creating default material for this slot"); <<reflist.first<<" - creating default material for this slot");
defmat.reset(min=new Material()); defmat.reset(min=new Material());
@ -473,7 +475,7 @@ void COBImporter::UnsupportedChunk_Ascii(LineSplitter& splitter, const ChunkInfo
// we can recover if the chunk size was specified. // we can recover if the chunk size was specified.
if(nfo.size != static_cast<unsigned int>(-1)) { if(nfo.size != static_cast<unsigned int>(-1)) {
DefaultLogger::get()->error(error); ASSIMP_LOG_ERROR(error);
// (HACK) - our current position in the stream is the beginning of the // (HACK) - our current position in the stream is the beginning of the
// head line of the next chunk. That's fine, but the caller is going // head line of the next chunk. That's fine, but the caller is going
@ -485,46 +487,6 @@ void COBImporter::UnsupportedChunk_Ascii(LineSplitter& splitter, const ChunkInfo
else ThrowException(error); else ThrowException(error);
} }
// ------------------------------------------------------------------------------------------------
void COBImporter::LogWarn_Ascii(const LineSplitter& splitter, const format& message) {
LogWarn_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}
// ------------------------------------------------------------------------------------------------
void COBImporter::LogError_Ascii(const LineSplitter& splitter, const format& message) {
LogError_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}
// ------------------------------------------------------------------------------------------------
void COBImporter::LogInfo_Ascii(const LineSplitter& splitter, const format& message) {
LogInfo_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}
// ------------------------------------------------------------------------------------------------
void COBImporter::LogDebug_Ascii(const LineSplitter& splitter, const format& message) {
LogDebug_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}
// ------------------------------------------------------------------------------------------------
void COBImporter::LogWarn_Ascii(const Formatter::format& message) {
DefaultLogger::get()->warn(std::string("COB: ")+=message);
}
// ------------------------------------------------------------------------------------------------
void COBImporter::LogError_Ascii(const Formatter::format& message) {
DefaultLogger::get()->error(std::string("COB: ")+=message);
}
// ------------------------------------------------------------------------------------------------
void COBImporter::LogInfo_Ascii(const Formatter::format& message) {
DefaultLogger::get()->info(std::string("COB: ")+=message);
}
// ------------------------------------------------------------------------------------------------
void COBImporter::LogDebug_Ascii(const Formatter::format& message) {
DefaultLogger::get()->debug(std::string("COB: ")+=message);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void COBImporter::ReadBasicNodeInfo_Ascii(Node& msh, LineSplitter& splitter, const ChunkInfo& /*nfo*/) void COBImporter::ReadBasicNodeInfo_Ascii(Node& msh, LineSplitter& splitter, const ChunkInfo& /*nfo*/)
{ {
@ -574,8 +536,7 @@ void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const Chunk
++splitter; ++splitter;
if (!splitter.match_start("mat# ")) { if (!splitter.match_start("mat# ")) {
LogWarn_Ascii(splitter,format()<< ASSIMP_LOG_WARN_F( "Expected `mat#` line in `Mat1` chunk ", nfo.id );
"Expected `mat#` line in `Mat1` chunk "<<nfo.id);
return; return;
} }
@ -587,8 +548,7 @@ void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const Chunk
++splitter; ++splitter;
if (!splitter.match_start("shader: ")) { if (!splitter.match_start("shader: ")) {
LogWarn_Ascii(splitter,format()<< ASSIMP_LOG_WARN_F( "Expected `mat#` line in `Mat1` chunk ", nfo.id);
"Expected `mat#` line in `Mat1` chunk "<<nfo.id);
return; return;
} }
std::string shader = std::string(splitter[1]); std::string shader = std::string(splitter[1]);
@ -601,14 +561,12 @@ void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const Chunk
mat.shader = Material::PHONG; mat.shader = Material::PHONG;
} }
else if (shader != "flat") { else if (shader != "flat") {
LogWarn_Ascii(splitter,format()<< ASSIMP_LOG_WARN_F( "Unknown value for `shader` in `Mat1` chunk ", nfo.id );
"Unknown value for `shader` in `Mat1` chunk "<<nfo.id);
} }
++splitter; ++splitter;
if (!splitter.match_start("rgb ")) { if (!splitter.match_start("rgb ")) {
LogWarn_Ascii(splitter,format()<< ASSIMP_LOG_WARN_F( "Expected `rgb` line in `Mat1` chunk ", nfo.id);
"Expected `rgb` line in `Mat1` chunk "<<nfo.id);
} }
const char* rgb = splitter[1]; const char* rgb = splitter[1];
@ -616,8 +574,7 @@ void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const Chunk
++splitter; ++splitter;
if (!splitter.match_start("alpha ")) { if (!splitter.match_start("alpha ")) {
LogWarn_Ascii(splitter,format()<< ASSIMP_LOG_WARN_F( "Expected `alpha` line in `Mat1` chunk ", nfo.id);
"Expected `alpha` line in `Mat1` chunk "<<nfo.id);
} }
const char* tokens[10]; const char* tokens[10];
@ -638,8 +595,7 @@ void COBImporter::ReadUnit_Ascii(Scene& out, LineSplitter& splitter, const Chunk
} }
++splitter; ++splitter;
if (!splitter.match_start("Units ")) { if (!splitter.match_start("Units ")) {
LogWarn_Ascii(splitter,format()<< ASSIMP_LOG_WARN_F( "Expected `Units` line in `Unit` chunk ", nfo.id);
"Expected `Units` line in `Unit` chunk "<<nfo.id);
return; return;
} }
@ -650,13 +606,12 @@ void COBImporter::ReadUnit_Ascii(Scene& out, LineSplitter& splitter, const Chunk
const unsigned int t=strtoul10(splitter[1]); const unsigned int t=strtoul10(splitter[1]);
nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?( nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
LogWarn_Ascii(splitter,format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id) ASSIMP_LOG_WARN_F(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id)
,1.f):units[t]; ,1.f):units[t];
return; return;
} }
} }
LogWarn_Ascii(splitter,format()<<"`Unit` chunk "<<nfo.id<<" is a child of " ASSIMP_LOG_WARN_F( "`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
<<nfo.parent_id<<" which does not exist");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -690,15 +645,13 @@ void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const Chunk
msh.ltype = Light::SPOT; msh.ltype = Light::SPOT;
} }
else { else {
LogWarn_Ascii(splitter,format()<< ASSIMP_LOG_WARN_F( "Unknown kind of light source in `Lght` chunk ", nfo.id, " : ", *splitter );
"Unknown kind of light source in `Lght` chunk "<<nfo.id<<" : "<<*splitter);
msh.ltype = Light::SPOT; msh.ltype = Light::SPOT;
} }
++splitter; ++splitter;
if (!splitter.match_start("color ")) { if (!splitter.match_start("color ")) {
LogWarn_Ascii(splitter,format()<< ASSIMP_LOG_WARN_F( "Expected `color` line in `Lght` chunk ", nfo.id );
"Expected `color` line in `Lght` chunk "<<nfo.id);
} }
const char* rgb = splitter[1]; const char* rgb = splitter[1];
@ -706,16 +659,14 @@ void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const Chunk
SkipSpaces(&rgb); SkipSpaces(&rgb);
if (strncmp(rgb,"cone angle",10)) { if (strncmp(rgb,"cone angle",10)) {
LogWarn_Ascii(splitter,format()<< ASSIMP_LOG_WARN_F( "Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id );
"Expected `cone angle` entity in `color` line in `Lght` chunk "<<nfo.id);
} }
SkipSpaces(rgb+10,&rgb); SkipSpaces(rgb+10,&rgb);
msh.angle = fast_atof(&rgb); msh.angle = fast_atof(&rgb);
SkipSpaces(&rgb); SkipSpaces(&rgb);
if (strncmp(rgb,"inner angle",11)) { if (strncmp(rgb,"inner angle",11)) {
LogWarn_Ascii(splitter,format()<< ASSIMP_LOG_WARN_F( "Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
"Expected `inner angle` entity in `color` line in `Lght` chunk "<<nfo.id);
} }
SkipSpaces(rgb+11,&rgb); SkipSpaces(rgb+11,&rgb);
msh.inner_angle = fast_atof(&rgb); msh.inner_angle = fast_atof(&rgb);
@ -826,7 +777,7 @@ void COBImporter::ReadPolH_Ascii(Scene& out, LineSplitter& splitter, const Chunk
for(unsigned int cur = 0; cur < cnt && ++splitter ;++cur) { for(unsigned int cur = 0; cur < cnt && ++splitter ;++cur) {
if (splitter.match_start("Hole")) { if (splitter.match_start("Hole")) {
LogWarn_Ascii(splitter,"Skipping unsupported `Hole` line"); ASSIMP_LOG_WARN( "Skipping unsupported `Hole` line" );
continue; continue;
} }
@ -886,7 +837,7 @@ void COBImporter::ReadBitM_Ascii(Scene& /*out*/, LineSplitter& splitter, const C
const unsigned int head = strtoul10((++splitter)[1]); const unsigned int head = strtoul10((++splitter)[1]);
if (head != sizeof(Bitmap::BitmapHeader)) { if (head != sizeof(Bitmap::BitmapHeader)) {
LogWarn_Ascii(splitter,"Unexpected ThumbNailHdrSize, skipping this chunk"); ASSIMP_LOG_WARN("Unexpected ThumbNailHdrSize, skipping this chunk");
return; return;
} }
@ -933,7 +884,7 @@ void COBImporter::UnsupportedChunk_Binary( StreamReaderLE& reader, const ChunkIn
// we can recover if the chunk size was specified. // we can recover if the chunk size was specified.
if(nfo.size != static_cast<unsigned int>(-1)) { if(nfo.size != static_cast<unsigned int>(-1)) {
DefaultLogger::get()->error(error); ASSIMP_LOG_ERROR(error);
reader.IncPtr(nfo.size); reader.IncPtr(nfo.size);
} }
else ThrowException(error); else ThrowException(error);
@ -1140,7 +1091,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const
mat.type = Material::METAL; mat.type = Material::METAL;
break; break;
default: default:
LogError_Ascii(format("Unrecognized shader type in `Mat1` chunk with id ")<<nfo.id); ASSIMP_LOG_ERROR_F( "Unrecognized shader type in `Mat1` chunk with id ", nfo.id );
mat.type = Material::FLAT; mat.type = Material::FLAT;
} }
@ -1155,7 +1106,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const
mat.autofacet = Material::SMOOTH; mat.autofacet = Material::SMOOTH;
break; break;
default: default:
LogError_Ascii(format("Unrecognized faceting mode in `Mat1` chunk with id ")<<nfo.id); ASSIMP_LOG_ERROR_F( "Unrecognized faceting mode in `Mat1` chunk with id ", nfo.id );
mat.autofacet = Material::FACETED; mat.autofacet = Material::FACETED;
} }
mat.autofacet_angle = static_cast<float>(reader.GetI1()); mat.autofacet_angle = static_cast<float>(reader.GetI1());
@ -1287,15 +1238,13 @@ void COBImporter::ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const
if (nd->id == nfo.parent_id) { if (nd->id == nfo.parent_id) {
const unsigned int t=reader.GetI2(); const unsigned int t=reader.GetI2();
nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?( nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
LogWarn_Ascii(format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id) ASSIMP_LOG_WARN_F(t," is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id)
,1.f):units[t]; ,1.f):units[t];
return; return;
} }
} }
LogWarn_Ascii(format()<<"`Unit` chunk "<<nfo.id<<" is a child of " ASSIMP_LOG_WARN_F( "`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
<<nfo.parent_id<<" which does not exist");
} }
#endif // ASSIMP_BUILD_NO_COB_IMPORTER
#endif

View File

@ -78,9 +78,6 @@ public:
COBImporter(); COBImporter();
~COBImporter(); ~COBImporter();
public:
// -------------------- // --------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
@ -115,15 +112,11 @@ private:
* @param stream Stream to read from. */ * @param stream Stream to read from. */
void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream); void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream);
private:
// Conversion to Assimp output format // Conversion to Assimp output format
aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill); aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill);
private: private:
// ASCII file support // ASCII file support
void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name); void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name);
@ -142,19 +135,6 @@ private:
void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
// ASCII file logging stuff to add proper line numbers to messages
static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message);
static void LogError_Ascii(const LineSplitter& splitter, const Formatter::format& message);
static void LogInfo_Ascii (const LineSplitter& splitter, const Formatter::format& message);
static void LogDebug_Ascii(const LineSplitter& splitter, const Formatter::format& message);
static void LogWarn_Ascii (const Formatter::format& message);
static void LogError_Ascii (const Formatter::format& message);
static void LogInfo_Ascii (const Formatter::format& message);
static void LogDebug_Ascii (const Formatter::format& message);
// Binary file support // Binary file support
void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name); void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);

View File

@ -233,7 +233,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
if (TokenMatchI(buffer, "DROPOUT", 7)) { if (TokenMatchI(buffer, "DROPOUT", 7)) {
// seems this is invalid marker data; at least the doc says it's possible // seems this is invalid marker data; at least the doc says it's possible
DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)"); ASSIMP_LOG_WARN("CSM: Encountered invalid marker data (DROPOUT)");
} }
else { else {
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys; aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;

View File

@ -95,7 +95,7 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
{ {
ai_assert( NULL != pScene ); ai_assert( NULL != pScene );
DefaultLogger::get()->debug("CalcTangentsProcess begin"); ASSIMP_LOG_DEBUG("CalcTangentsProcess begin");
bool bHas = false; bool bHas = false;
for ( unsigned int a = 0; a < pScene->mNumMeshes; a++ ) { for ( unsigned int a = 0; a < pScene->mNumMeshes; a++ ) {
@ -103,9 +103,9 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
} }
if ( bHas ) { if ( bHas ) {
DefaultLogger::get()->info("CalcTangentsProcess finished. Tangents have been calculated"); ASSIMP_LOG_INFO("CalcTangentsProcess finished. Tangents have been calculated");
} else { } else {
DefaultLogger::get()->debug("CalcTangentsProcess finished"); ASSIMP_LOG_DEBUG("CalcTangentsProcess finished");
} }
} }
@ -126,19 +126,19 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// are undefined. // are undefined.
if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
{ {
DefaultLogger::get()->info("Tangents are undefined for line and point meshes"); ASSIMP_LOG_INFO("Tangents are undefined for line and point meshes");
return false; return false;
} }
// what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement // what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement
if( pMesh->mNormals == NULL) if( pMesh->mNormals == NULL)
{ {
DefaultLogger::get()->error("Failed to compute tangents; need normals"); ASSIMP_LOG_ERROR("Failed to compute tangents; need normals");
return false; return false;
} }
if( configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV] ) if( configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV] )
{ {
DefaultLogger::get()->error((Formatter::format("Failed to compute tangents; need UV data in channel"),configSourceUV)); ASSIMP_LOG_ERROR((Formatter::format("Failed to compute tangents; need UV data in channel"),configSourceUV));
return false; return false;
} }
@ -190,7 +190,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y; float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y;
float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f; float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f;
// when t1, t2, t3 in same position in UV space, just use default UV direction. // when t1, t2, t3 in same position in UV space, just use default UV direction.
if ( 0 == sx && 0 ==sy && 0 == tx && 0 == ty ) { if ( sx * ty == sy * tx ) {
sx = 0.0; sy = 1.0; sx = 0.0; sy = 1.0;
tx = 1.0; ty = 0.0; tx = 1.0; ty = 0.0;
} }

View File

@ -1270,6 +1270,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr; mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
PushTag(); PushTag();
std::string node_idstr;
for (size_t a = 0; a < anim->mNumChannels; ++a) { for (size_t a = 0; a < anim->mNumChannels; ++a) {
const aiNodeAnim * nodeAnim = anim->mChannels[a]; const aiNodeAnim * nodeAnim = anim->mChannels[a];
@ -1277,7 +1278,9 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
if ( nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys || nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys ) continue; if ( nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys || nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys ) continue;
{ {
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-input"); node_idstr.clear();
node_idstr += nodeAnim->mNodeName.data;
node_idstr += std::string( "_matrix-input" );
std::vector<ai_real> frames; std::vector<ai_real> frames;
for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) { for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
@ -1289,12 +1292,14 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
} }
{ {
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-output"); node_idstr.clear();
node_idstr += nodeAnim->mNodeName.data;
node_idstr += std::string("_matrix-output");
std::vector<ai_real> keyframes; std::vector<ai_real> keyframes;
keyframes.reserve(nodeAnim->mNumPositionKeys * 16); keyframes.reserve(nodeAnim->mNumPositionKeys * 16);
for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) { for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
aiVector3D Scaling = nodeAnim->mScalingKeys[i].mValue; aiVector3D Scaling = nodeAnim->mScalingKeys[i].mValue;
aiMatrix4x4 ScalingM; // identity aiMatrix4x4 ScalingM; // identity
ScalingM[0][0] = Scaling.x; ScalingM[1][1] = Scaling.y; ScalingM[2][2] = Scaling.z; ScalingM[0][0] = Scaling.x; ScalingM[1][1] = Scaling.y; ScalingM[2][2] = Scaling.z;
@ -1361,7 +1366,6 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
PopTag(); PopTag();
mOutput << startstr << "</source>" << endstr; mOutput << startstr << "</source>" << endstr;
} }
} }
for (size_t a = 0; a < anim->mNumChannels; ++a) { for (size_t a = 0; a < anim->mNumChannels; ++a) {

View File

@ -189,7 +189,7 @@ protected:
{} {}
}; };
// summarize a material in an convinient way. // summarize a material in an convenient way.
struct Material struct Material
{ {
std::string name; std::string name;

View File

@ -47,13 +47,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER #ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
#include "ColladaLoader.h" #include "ColladaLoader.h"
#include "ColladaParser.h"
#include <assimp/anim.h> #include <assimp/anim.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/Defines.h>
#include "ColladaParser.h"
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <assimp/SkeletonMeshBuilder.h> #include <assimp/SkeletonMeshBuilder.h>
@ -63,7 +65,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "math.h" #include "math.h"
#include <algorithm> #include <algorithm>
#include <numeric> #include <numeric>
#include <assimp/Defines.h>
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
@ -293,7 +294,7 @@ void ColladaLoader::ResolveNodeInstances( const ColladaParser& pParser, const Co
nd = FindNode(pParser.mRootNode, nodeInst.mNode); nd = FindNode(pParser.mRootNode, nodeInst.mNode);
} }
if (!nd) if (!nd)
DefaultLogger::get()->error("Collada: Unable to resolve reference to instanced node " + nodeInst.mNode); ASSIMP_LOG_ERROR_F("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode);
else { else {
// attach this node to the list of children // attach this node to the list of children
@ -310,7 +311,7 @@ void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler
std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel); std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel);
if (it != table.mMap.end()) { if (it != table.mMap.end()) {
if (it->second.mType != Collada::IT_Texcoord) if (it->second.mType != Collada::IT_Texcoord)
DefaultLogger::get()->error("Collada: Unexpected effect input mapping"); ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping");
sampler.mUVId = it->second.mSet; sampler.mUVId = it->second.mSet;
} }
@ -326,7 +327,7 @@ void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Coll
ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find( lid.mLight); ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find( lid.mLight);
if( srcLightIt == pParser.mLightLibrary.end()) if( srcLightIt == pParser.mLightLibrary.end())
{ {
DefaultLogger::get()->warn("Collada: Unable to find light for ID \"" + lid.mLight + "\". Skipping."); ASSIMP_LOG_WARN_F("Collada: Unable to find light for ID \"" , lid.mLight , "\". Skipping.");
continue; continue;
} }
const Collada::Light* srcLight = &srcLightIt->second; const Collada::Light* srcLight = &srcLightIt->second;
@ -394,14 +395,14 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col
ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find( cid.mCamera); ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find( cid.mCamera);
if( srcCameraIt == pParser.mCameraLibrary.end()) if( srcCameraIt == pParser.mCameraLibrary.end())
{ {
DefaultLogger::get()->warn("Collada: Unable to find camera for ID \"" + cid.mCamera + "\". Skipping."); ASSIMP_LOG_WARN_F("Collada: Unable to find camera for ID \"" , cid.mCamera , "\". Skipping.");
continue; continue;
} }
const Collada::Camera* srcCamera = &srcCameraIt->second; const Collada::Camera* srcCamera = &srcCameraIt->second;
// orthographic cameras not yet supported in Assimp // orthographic cameras not yet supported in Assimp
if (srcCamera->mOrtho) { if (srcCamera->mOrtho) {
DefaultLogger::get()->warn("Collada: Orthographic cameras are not supported."); ASSIMP_LOG_WARN("Collada: Orthographic cameras are not supported.");
} }
// now fill our ai data structure // now fill our ai data structure
@ -471,7 +472,7 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
if( !srcMesh) if( !srcMesh)
{ {
DefaultLogger::get()->warn( format() << "Collada: Unable to find geometry for ID \"" << mid.mMeshOrController << "\". Skipping." ); ASSIMP_LOG_WARN_F( "Collada: Unable to find geometry for ID \"", mid.mMeshOrController, "\". Skipping." );
continue; continue;
} }
} else } else
@ -500,7 +501,8 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
} }
else else
{ {
DefaultLogger::get()->warn( format() << "Collada: No material specified for subgroup <" << submesh.mMaterial << "> in geometry <" << mid.mMeshOrController << ">." ); ASSIMP_LOG_WARN_F( "Collada: No material specified for subgroup <", submesh.mMaterial, "> in geometry <",
mid.mMeshOrController, ">." );
if( !mid.mMaterials.empty() ) if( !mid.mMaterials.empty() )
meshMaterial = mid.mMaterials.begin()->second.mMatName; meshMaterial = mid.mMaterials.begin()->second.mMatName;
} }
@ -873,7 +875,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
if( bnode) if( bnode)
bone->mName.Set( FindNameForNode( bnode)); bone->mName.Set( FindNameForNode( bnode));
else else
DefaultLogger::get()->warn( format() << "ColladaLoader::CreateMesh(): could not find corresponding node for joint \"" << bone->mName.data << "\"." ); ASSIMP_LOG_WARN_F( "ColladaLoader::CreateMesh(): could not find corresponding node for joint \"", bone->mName.data, "\"." );
// and insert bone // and insert bone
dstMesh->mBones[boneCount++] = bone; dstMesh->mBones[boneCount++] = bone;
@ -954,7 +956,7 @@ void ColladaLoader::StoreSceneMaterials( aiScene* pScene)
// Stores all animations // Stores all animations
void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser) void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser)
{ {
// recursivly collect all animations from the collada scene // recursively collect all animations from the collada scene
StoreAnimations( pScene, pParser, &pParser.mAnims, ""); StoreAnimations( pScene, pParser, &pParser.mAnims, "");
// catch special case: many animations with the same length, each affecting only a single node. // catch special case: many animations with the same length, each affecting only a single node.
@ -1121,6 +1123,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
continue; continue;
// now check all channels if they affect the current node // now check all channels if they affect the current node
std::string targetID, subElement;
for( std::vector<Collada::AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin(); for( std::vector<Collada::AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin();
cit != pSrcAnim->mChannels.end(); ++cit) cit != pSrcAnim->mChannels.end(); ++cit)
{ {
@ -1147,7 +1150,9 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
} }
if( srcChannel.mTarget.find( '/', slashPos+1) != std::string::npos) if( srcChannel.mTarget.find( '/', slashPos+1) != std::string::npos)
continue; continue;
std::string targetID = srcChannel.mTarget.substr( 0, slashPos);
targetID.clear();
targetID = srcChannel.mTarget.substr( 0, slashPos);
if( targetID != srcNode->mID) if( targetID != srcNode->mID)
continue; continue;
@ -1160,7 +1165,8 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
entry.mTransformId = srcChannel.mTarget.substr( slashPos+1, dotPos - slashPos - 1); entry.mTransformId = srcChannel.mTarget.substr( slashPos+1, dotPos - slashPos - 1);
std::string subElement = srcChannel.mTarget.substr( dotPos+1); subElement.clear();
subElement = srcChannel.mTarget.substr( dotPos+1);
if( subElement == "ANGLE") if( subElement == "ANGLE")
entry.mSubElement = 3; // last number in an Axis-Angle-Transform is the angle entry.mSubElement = 3; // last number in an Axis-Angle-Transform is the angle
else if( subElement == "X") else if( subElement == "X")
@ -1170,9 +1176,8 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
else if( subElement == "Z") else if( subElement == "Z")
entry.mSubElement = 2; entry.mSubElement = 2;
else else
DefaultLogger::get()->warn( format() << "Unknown anim subelement <" << subElement << ">. Ignoring" ); ASSIMP_LOG_WARN_F( "Unknown anim subelement <", subElement, ">. Ignoring" );
} else } else {
{
// no subelement following, transformId is remaining string // no subelement following, transformId is remaining string
entry.mTransformId = srcChannel.mTarget.substr( slashPos+1); entry.mTransformId = srcChannel.mTarget.substr( slashPos+1);
} }
@ -1181,7 +1186,8 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
if (bracketPos != std::string::npos) if (bracketPos != std::string::npos)
{ {
entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1, bracketPos - slashPos - 1); entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1, bracketPos - slashPos - 1);
std::string subElement = srcChannel.mTarget.substr(bracketPos); subElement.clear();
subElement = srcChannel.mTarget.substr(bracketPos);
if (subElement == "(0)(0)") if (subElement == "(0)(0)")
entry.mSubElement = 0; entry.mSubElement = 0;
@ -1215,7 +1221,6 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
entry.mSubElement = 14; entry.mSubElement = 14;
else if (subElement == "(3)(3)") else if (subElement == "(3)(3)")
entry.mSubElement = 15; entry.mSubElement = 15;
} }
// determine which transform step is affected by this channel // determine which transform step is affected by this channel
@ -1401,7 +1406,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
anims.push_back( dstAnim); anims.push_back( dstAnim);
} else } else
{ {
DefaultLogger::get()->warn( "Collada loader: found empty animation channel, ignored. Please check your exporter."); ASSIMP_LOG_WARN( "Collada loader: found empty animation channel, ignored. Please check your exporter.");
} }
if( !entries.empty() && entries.front().mTimeAccessor->mCount > 0 ) if( !entries.empty() && entries.front().mTimeAccessor->mCount > 0 )
@ -1556,7 +1561,7 @@ void ColladaLoader::AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
} }
} }
if (-1 == map) { if (-1 == map) {
DefaultLogger::get()->warn("Collada: unable to determine UV channel for texture"); ASSIMP_LOG_WARN("Collada: unable to determine UV channel for texture");
map = 0; map = 0;
} }
} }
@ -1593,7 +1598,7 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
break; break;
default: default:
DefaultLogger::get()->warn("Collada: Unrecognized shading mode, using gouraud shading"); ASSIMP_LOG_WARN("Collada: Unrecognized shading mode, using gouraud shading");
shadeMode = aiShadingMode_Gouraud; shadeMode = aiShadingMode_Gouraud;
break; break;
} }
@ -1652,9 +1657,10 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
} }
// add textures, if given // add textures, if given
if( !effect.mTexAmbient.mName.empty()) if (!effect.mTexAmbient.mName.empty()) {
/* It is merely a lightmap */ // It is merely a light-map
AddTexture(mat, pParser, effect, effect.mTexAmbient, aiTextureType_LIGHTMAP); AddTexture(mat, pParser, effect, effect.mTexAmbient, aiTextureType_LIGHTMAP);
}
if( !effect.mTexEmissive.mName.empty()) if( !effect.mTexEmissive.mName.empty())
AddTexture( mat, pParser, effect, effect.mTexEmissive, aiTextureType_EMISSIVE); AddTexture( mat, pParser, effect, effect.mTexEmissive, aiTextureType_EMISSIVE);
@ -1682,8 +1688,8 @@ void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
{ {
newMats.reserve(pParser.mMaterialLibrary.size()); newMats.reserve(pParser.mMaterialLibrary.size());
for( ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin(); matIt != pParser.mMaterialLibrary.end(); ++matIt) for( ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin();
{ matIt != pParser.mMaterialLibrary.end(); ++matIt) {
const Collada::Material& material = matIt->second; const Collada::Material& material = matIt->second;
// a material is only a reference to an effect // a material is only a reference to an effect
ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find( material.mEffect); ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find( material.mEffect);
@ -1747,11 +1753,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name); ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name);
if( imIt == pParser.mImageLibrary.end()) if( imIt == pParser.mImageLibrary.end())
{ {
//missing texture should not stop the conversion ASSIMP_LOG_WARN_F("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\".");
//throw DeadlyImportError( format() <<
// "Collada: Unable to resolve effect texture entry \"" << pName << "\", ended up at ID \"" << name << "\"." );
DefaultLogger::get()->warn("Collada: Unable to resolve effect texture entry \"" + pName + "\", ended up at ID \"" + name + "\".");
//set default texture file name //set default texture file name
result.Set(name + ".jpg"); result.Set(name + ".jpg");
@ -1770,7 +1772,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
// setup format hint // setup format hint
if (imIt->second.mEmbeddedFormat.length() > 3) { if (imIt->second.mEmbeddedFormat.length() > 3) {
DefaultLogger::get()->warn("Collada: texture format hint is too long, truncating to 3 characters"); ASSIMP_LOG_WARN("Collada: texture format hint is too long, truncating to 3 characters");
} }
strncpy(tex->achFormatHint,imIt->second.mEmbeddedFormat.c_str(),3); strncpy(tex->achFormatHint,imIt->second.mEmbeddedFormat.c_str(),3);
@ -1782,7 +1784,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING" // TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
// In FBX files textures are now stored internally by Assimp with their filename included // In FBX files textures are now stored internally by Assimp with their filename included
// Now Assimp can lookup thru the loaded textures after all data is processed // Now Assimp can lookup through the loaded textures after all data is processed
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it // We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
// This may occur on this case too, it has to be studied // This may occur on this case too, it has to be studied
// setup texture reference string // setup texture reference string
@ -1806,7 +1808,7 @@ void ColladaLoader::ConvertPath (aiString& ss)
{ {
// TODO: collada spec, p 22. Handle URI correctly. // TODO: collada spec, p 22. Handle URI correctly.
// For the moment we're just stripping the file:// away to make it work. // For the moment we're just stripping the file:// away to make it work.
// Windoes doesn't seem to be able to find stuff like // Windows doesn't seem to be able to find stuff like
// 'file://..\LWO\LWO2\MappingModes\earthSpherical.jpg' // 'file://..\LWO\LWO2\MappingModes\earthSpherical.jpg'
if (0 == strncmp(ss.data,"file://",7)) if (0 == strncmp(ss.data,"file://",7))
{ {
@ -1817,10 +1819,13 @@ void ColladaLoader::ConvertPath (aiString& ss)
// Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes... // Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
// I need to filter it without destroying linux paths starting with "/somewhere" // I need to filter it without destroying linux paths starting with "/somewhere"
if( ss.data[0] == '/' && isalpha( ss.data[1]) && ss.data[2] == ':' ) #if defined( _MSC_VER )
{ if( ss.data[0] == '/' && isalpha( (unsigned char) ss.data[1]) && ss.data[2] == ':' ) {
ss.length--; #else
memmove( ss.data, ss.data+1, ss.length); if (ss.data[ 0 ] == '/' && isalpha( ss.data[ 1 ] ) && ss.data[ 2 ] == ':') {
#endif
--ss.length;
::memmove( ss.data, ss.data+1, ss.length);
ss.data[ss.length] = 0; ss.data[ss.length] = 0;
} }
@ -1870,10 +1875,10 @@ const std::string& ColladaLoader::ReadString( const Collada::Accessor& pAccessor
void ColladaLoader::CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const void ColladaLoader::CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const
{ {
poNodes.push_back( pNode); poNodes.push_back( pNode);
for (size_t a = 0; a < pNode->mNumChildren; ++a) {
for( size_t a = 0; a < pNode->mNumChildren; ++a)
CollectNodes(pNode->mChildren[a], poNodes); CollectNodes(pNode->mChildren[a], poNodes);
} }
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Finds a node in the collada scene by the given name // Finds a node in the collada scene by the given name

View File

@ -152,22 +152,22 @@ void ColladaParser::ReadContents()
if (!::strncmp(version,"1.5",3)) { if (!::strncmp(version,"1.5",3)) {
mFormat = FV_1_5_n; mFormat = FV_1_5_n;
DefaultLogger::get()->debug("Collada schema version is 1.5.n"); ASSIMP_LOG_DEBUG("Collada schema version is 1.5.n");
} }
else if (!::strncmp(version,"1.4",3)) { else if (!::strncmp(version,"1.4",3)) {
mFormat = FV_1_4_n; mFormat = FV_1_4_n;
DefaultLogger::get()->debug("Collada schema version is 1.4.n"); ASSIMP_LOG_DEBUG("Collada schema version is 1.4.n");
} }
else if (!::strncmp(version,"1.3",3)) { else if (!::strncmp(version,"1.3",3)) {
mFormat = FV_1_3_n; mFormat = FV_1_3_n;
DefaultLogger::get()->debug("Collada schema version is 1.3.n"); ASSIMP_LOG_DEBUG("Collada schema version is 1.3.n");
} }
} }
ReadStructure(); ReadStructure();
} else } else
{ {
DefaultLogger::get()->debug( format() << "Ignoring global element <" << mReader->getNodeName() << ">." ); ASSIMP_LOG_DEBUG_F( "Ignoring global element <", mReader->getNodeName(), ">." );
SkipElement(); SkipElement();
} }
} else } else
@ -984,13 +984,13 @@ void ColladaParser::ReadImage( Collada::Image& pImage)
// they're not skipped. // they're not skipped.
int attrib = TestAttribute("array_index"); int attrib = TestAttribute("array_index");
if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) { if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) {
DefaultLogger::get()->warn("Collada: Ignoring texture array index"); ASSIMP_LOG_WARN("Collada: Ignoring texture array index");
continue; continue;
} }
attrib = TestAttribute("mip_index"); attrib = TestAttribute("mip_index");
if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) { if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) {
DefaultLogger::get()->warn("Collada: Ignoring MIP map layer"); ASSIMP_LOG_WARN("Collada: Ignoring MIP map layer");
continue; continue;
} }
@ -1011,7 +1011,7 @@ void ColladaParser::ReadImage( Collada::Image& pImage)
// embedded image. get format // embedded image. get format
const int attrib = TestAttribute("format"); const int attrib = TestAttribute("format");
if (-1 == attrib) if (-1 == attrib)
DefaultLogger::get()->warn("Collada: Unknown image file format"); ASSIMP_LOG_WARN("Collada: Unknown image file format");
else pImage.mEmbeddedFormat = mReader->getAttributeValue(attrib); else pImage.mEmbeddedFormat = mReader->getAttributeValue(attrib);
const char* data = GetTextContent(); const char* data = GetTextContent();
@ -1590,7 +1590,7 @@ void ColladaParser::ReadSamplerProperties( Sampler& out )
out.mOp = aiTextureOp_Multiply; out.mOp = aiTextureOp_Multiply;
else { else {
DefaultLogger::get()->warn("Collada: Unsupported MAYA texture blend mode"); ASSIMP_LOG_WARN("Collada: Unsupported MAYA texture blend mode");
} }
TestClosing( "blend_mode"); TestClosing( "blend_mode");
} }
@ -2541,7 +2541,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
if( pInput.mIndex == 0) if( pInput.mIndex == 0)
pMesh->mPositions.push_back( aiVector3D( obj[0], obj[1], obj[2])); pMesh->mPositions.push_back( aiVector3D( obj[0], obj[1], obj[2]));
else else
DefaultLogger::get()->error("Collada: just one vertex position stream supported"); ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported");
break; break;
case IT_Normal: case IT_Normal:
// pad to current vertex count if necessary // pad to current vertex count if necessary
@ -2552,7 +2552,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
if( pInput.mIndex == 0) if( pInput.mIndex == 0)
pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2])); pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2]));
else else
DefaultLogger::get()->error("Collada: just one vertex normal stream supported"); ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported");
break; break;
case IT_Tangent: case IT_Tangent:
// pad to current vertex count if necessary // pad to current vertex count if necessary
@ -2563,7 +2563,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
if( pInput.mIndex == 0) if( pInput.mIndex == 0)
pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2]));
else else
DefaultLogger::get()->error("Collada: just one vertex tangent stream supported"); ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported");
break; break;
case IT_Bitangent: case IT_Bitangent:
// pad to current vertex count if necessary // pad to current vertex count if necessary
@ -2574,7 +2574,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
if( pInput.mIndex == 0) if( pInput.mIndex == 0)
pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2]));
else else
DefaultLogger::get()->error("Collada: just one vertex bitangent stream supported"); ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported");
break; break;
case IT_Texcoord: case IT_Texcoord:
// up to 4 texture coord sets are fine, ignore the others // up to 4 texture coord sets are fine, ignore the others
@ -2590,7 +2590,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
pMesh->mNumUVComponents[pInput.mIndex]=3; pMesh->mNumUVComponents[pInput.mIndex]=3;
} else } else
{ {
DefaultLogger::get()->error("Collada: too many texture coordinate sets. Skipping."); ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping.");
} }
break; break;
case IT_Color: case IT_Color:
@ -2610,7 +2610,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
pMesh->mColors[pInput.mIndex].push_back(result); pMesh->mColors[pInput.mIndex].push_back(result);
} else } else
{ {
DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping."); ASSIMP_LOG_ERROR("Collada: too many vertex color sets. Skipping.");
} }
break; break;
@ -2739,7 +2739,7 @@ void ColladaParser::ReadSceneNode( Node* pNode)
{ {
const char* s = mReader->getAttributeValue(attrId); const char* s = mReader->getAttributeValue(attrId);
if (s[0] != '#') if (s[0] != '#')
DefaultLogger::get()->error("Collada: Unresolved reference format of camera"); ASSIMP_LOG_ERROR("Collada: Unresolved reference format of camera");
else else
pNode->mPrimaryCamera = s+1; pNode->mPrimaryCamera = s+1;
} }
@ -2752,7 +2752,7 @@ void ColladaParser::ReadSceneNode( Node* pNode)
{ {
const char* s = mReader->getAttributeValue(attrID); const char* s = mReader->getAttributeValue(attrID);
if (s[0] != '#') if (s[0] != '#')
DefaultLogger::get()->error("Collada: Unresolved reference format of node"); ASSIMP_LOG_ERROR("Collada: Unresolved reference format of node");
else else
{ {
pNode->mNodeInstances.push_back(NodeInstance()); pNode->mNodeInstances.push_back(NodeInstance());
@ -2770,7 +2770,7 @@ void ColladaParser::ReadSceneNode( Node* pNode)
// Reference to a light, name given in 'url' attribute // Reference to a light, name given in 'url' attribute
int attrID = TestAttribute("url"); int attrID = TestAttribute("url");
if (-1 == attrID) if (-1 == attrID)
DefaultLogger::get()->warn("Collada: Expected url attribute in <instance_light> element"); ASSIMP_LOG_WARN("Collada: Expected url attribute in <instance_light> element");
else else
{ {
const char* url = mReader->getAttributeValue( attrID); const char* url = mReader->getAttributeValue( attrID);
@ -2786,7 +2786,7 @@ void ColladaParser::ReadSceneNode( Node* pNode)
// Reference to a camera, name given in 'url' attribute // Reference to a camera, name given in 'url' attribute
int attrID = TestAttribute("url"); int attrID = TestAttribute("url");
if (-1 == attrID) if (-1 == attrID)
DefaultLogger::get()->warn("Collada: Expected url attribute in <instance_camera> element"); ASSIMP_LOG_WARN("Collada: Expected url attribute in <instance_camera> element");
else else
{ {
const char* url = mReader->getAttributeValue( attrID); const char* url = mReader->getAttributeValue( attrID);
@ -2873,7 +2873,7 @@ void ColladaParser::ReadMaterialVertexInputBinding( Collada::SemanticMappingTabl
tbl.mMap[s] = vn; tbl.mMap[s] = vn;
} }
else if( IsElement( "bind")) { else if( IsElement( "bind")) {
DefaultLogger::get()->warn("Collada: Found unsupported <bind> element"); ASSIMP_LOG_WARN("Collada: Found unsupported <bind> element");
} }
} }
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
@ -2992,10 +2992,9 @@ void ColladaParser::ReportWarning(const char* msg,...)
ai_assert(iLen > 0); ai_assert(iLen > 0);
va_end(args); va_end(args);
DefaultLogger::get()->warn("Validation warning: " + std::string(szBuffer,iLen)); ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer,iLen));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Skips all data until the end node of the current element // Skips all data until the end node of the current element
void ColladaParser::SkipElement() void ColladaParser::SkipElement()
@ -3106,7 +3105,7 @@ const char* ColladaParser::TestTextContent()
// read contents of the element // read contents of the element
if( !mReader->read() ) if( !mReader->read() )
return NULL; return NULL;
if( mReader->getNodeType() != irr::io::EXN_TEXT) if( mReader->getNodeType() != irr::io::EXN_TEXT && mReader->getNodeType() != irr::io::EXN_CDATA)
return NULL; return NULL;
// skip leading whitespace // skip leading whitespace
@ -3190,7 +3189,7 @@ aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector<Transform
Collada::InputType ColladaParser::GetTypeForSemantic( const std::string& semantic) Collada::InputType ColladaParser::GetTypeForSemantic( const std::string& semantic)
{ {
if ( semantic.empty() ) { if ( semantic.empty() ) {
DefaultLogger::get()->warn( format() << "Vertex input type is empty." ); ASSIMP_LOG_WARN("Vertex input type is empty." );
return IT_Invalid; return IT_Invalid;
} }
@ -3209,7 +3208,7 @@ Collada::InputType ColladaParser::GetTypeForSemantic( const std::string& semanti
else if( semantic == "TANGENT" || semantic == "TEXTANGENT") else if( semantic == "TANGENT" || semantic == "TEXTANGENT")
return IT_Tangent; return IT_Tangent;
DefaultLogger::get()->warn( format() << "Unknown vertex input type \"" << semantic << "\". Ignoring." ); ASSIMP_LOG_WARN_F( "Unknown vertex input type \"", semantic, "\". Ignoring." );
return IT_Invalid; return IT_Invalid;
} }

View File

@ -99,7 +99,7 @@ inline unsigned int FindEmptyUVChannel (aiMesh* mesh)
for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS;++m) for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS;++m)
if (!mesh->mTextureCoords[m])return m; if (!mesh->mTextureCoords[m])return m;
DefaultLogger::get()->error("Unable to compute UV coordinates, no free UV slot found"); ASSIMP_LOG_ERROR("Unable to compute UV coordinates, no free UV slot found");
return UINT_MAX; return UINT_MAX;
} }
@ -384,13 +384,13 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ComputeUVMappingProcess::ComputeBoxMapping( aiMesh*, aiVector3D* ) void ComputeUVMappingProcess::ComputeBoxMapping( aiMesh*, aiVector3D* )
{ {
DefaultLogger::get()->error("Mapping type currently not implemented"); ASSIMP_LOG_ERROR("Mapping type currently not implemented");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ComputeUVMappingProcess::Execute( aiScene* pScene) void ComputeUVMappingProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("GenUVCoordsProcess begin"); ASSIMP_LOG_DEBUG("GenUVCoordsProcess begin");
char buffer[1024]; char buffer[1024];
if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT)
@ -418,7 +418,7 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex, TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
MappingTypeToString(mapping)); MappingTypeToString(mapping));
DefaultLogger::get()->info(buffer); ASSIMP_LOG_INFO(buffer);
} }
if (aiTextureMapping_OTHER == mapping) if (aiTextureMapping_OTHER == mapping)
@ -485,7 +485,7 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
} }
if (m && idx != outIdx) if (m && idx != outIdx)
{ {
DefaultLogger::get()->warn("UV index mismatch. Not all meshes assigned to " ASSIMP_LOG_WARN("UV index mismatch. Not all meshes assigned to "
"this material have equal numbers of UV channels. The UV index stored in " "this material have equal numbers of UV channels. The UV index stored in "
"the material structure does therefore not apply for all meshes. "); "the material structure does therefore not apply for all meshes. ");
} }
@ -502,5 +502,5 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
} }
} }
} }
DefaultLogger::get()->debug("GenUVCoordsProcess finished"); ASSIMP_LOG_DEBUG("GenUVCoordsProcess finished");
} }

View File

@ -85,7 +85,7 @@ void MakeLeftHandedProcess::Execute( aiScene* pScene)
{ {
// Check for an existent root node to proceed // Check for an existent root node to proceed
ai_assert(pScene->mRootNode != NULL); ai_assert(pScene->mRootNode != NULL);
DefaultLogger::get()->debug("MakeLeftHandedProcess begin"); ASSIMP_LOG_DEBUG("MakeLeftHandedProcess begin");
// recursively convert all the nodes // recursively convert all the nodes
ProcessNode( pScene->mRootNode, aiMatrix4x4()); ProcessNode( pScene->mRootNode, aiMatrix4x4());
@ -110,7 +110,7 @@ void MakeLeftHandedProcess::Execute( aiScene* pScene)
ProcessAnimation( nodeAnim); ProcessAnimation( nodeAnim);
} }
} }
DefaultLogger::get()->debug("MakeLeftHandedProcess finished"); ASSIMP_LOG_DEBUG("MakeLeftHandedProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -140,7 +140,7 @@ void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pPare
// Converts a single mesh to left handed coordinates. // Converts a single mesh to left handed coordinates.
void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh) { void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh) {
if ( nullptr == pMesh ) { if ( nullptr == pMesh ) {
DefaultLogger::get()->error( "Nullptr to mesh found." ); ASSIMP_LOG_ERROR( "Nullptr to mesh found." );
return; return;
} }
// mirror positions, normals and stuff along the Z axis // mirror positions, normals and stuff along the Z axis
@ -180,7 +180,7 @@ void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh) {
// Converts a single material to left handed coordinates. // Converts a single material to left handed coordinates.
void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat) { void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat) {
if ( nullptr == _mat ) { if ( nullptr == _mat ) {
DefaultLogger::get()->error( "Nullptr to aiMaterial found." ); ASSIMP_LOG_ERROR( "Nullptr to aiMaterial found." );
return; return;
} }
@ -245,13 +245,13 @@ bool FlipUVsProcess::IsActive( unsigned int pFlags) const
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FlipUVsProcess::Execute( aiScene* pScene) void FlipUVsProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FlipUVsProcess begin"); ASSIMP_LOG_DEBUG("FlipUVsProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
ProcessMesh(pScene->mMeshes[i]); ProcessMesh(pScene->mMeshes[i]);
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
ProcessMaterial(pScene->mMaterials[i]); ProcessMaterial(pScene->mMaterials[i]);
DefaultLogger::get()->debug("FlipUVsProcess finished"); ASSIMP_LOG_DEBUG("FlipUVsProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -262,7 +262,7 @@ void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
for (unsigned int a = 0; a < mat->mNumProperties;++a) { for (unsigned int a = 0; a < mat->mNumProperties;++a) {
aiMaterialProperty* prop = mat->mProperties[a]; aiMaterialProperty* prop = mat->mProperties[a];
if( !prop ) { if( !prop ) {
DefaultLogger::get()->debug( "Property is null" ); ASSIMP_LOG_DEBUG( "Property is null" );
continue; continue;
} }
@ -319,10 +319,10 @@ bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FlipWindingOrderProcess::Execute( aiScene* pScene) void FlipWindingOrderProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FlipWindingOrderProcess begin"); ASSIMP_LOG_DEBUG("FlipWindingOrderProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
ProcessMesh(pScene->mMeshes[i]); ProcessMesh(pScene->mMeshes[i]);
DefaultLogger::get()->debug("FlipWindingOrderProcess finished"); ASSIMP_LOG_DEBUG("FlipWindingOrderProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -117,6 +117,7 @@ bool D3MFExporter::exportArchive( const char *file ) {
if ( nullptr == m_zipArchive ) { if ( nullptr == m_zipArchive ) {
return false; return false;
} }
ok |= exportContentTypes(); ok |= exportContentTypes();
ok |= export3DModel(); ok |= export3DModel();
ok |= exportRelations(); ok |= exportRelations();
@ -181,6 +182,8 @@ bool D3MFExporter::export3DModel() {
mModelOutput << "<" << XmlTag::resources << ">"; mModelOutput << "<" << XmlTag::resources << ">";
mModelOutput << std::endl; mModelOutput << std::endl;
writeMetaData();
writeBaseMaterials(); writeBaseMaterials();
writeObjects(); writeObjects();
@ -209,22 +212,45 @@ void D3MFExporter::writeHeader() {
mModelOutput << std::endl; mModelOutput << std::endl;
} }
void D3MFExporter::writeMetaData() {
if ( nullptr == mScene->mMetaData ) {
return;
}
const unsigned int numMetaEntries( mScene->mMetaData->mNumProperties );
if ( 0 == numMetaEntries ) {
return;
}
const aiString *key = nullptr;
const aiMetadataEntry *entry(nullptr);
for ( size_t i = 0; i < numMetaEntries; ++i ) {
mScene->mMetaData->Get( i, key, entry );
std::string k( key->C_Str() );
aiString value;
mScene->mMetaData->Get( k, value );
mModelOutput << "<" << XmlTag::meta << " " << XmlTag::meta_name << "=\"" << key->C_Str() << "\">";
mModelOutput << value.C_Str();
mModelOutput << "</" << XmlTag::meta << ">" << std::endl;
}
}
void D3MFExporter::writeBaseMaterials() { void D3MFExporter::writeBaseMaterials() {
mModelOutput << "<basematerials id=\"1\">\n"; mModelOutput << "<basematerials id=\"1\">\n";
std::string strName, hexDiffuseColor , tmp;
for ( size_t i = 0; i < mScene->mNumMaterials; ++i ) { for ( size_t i = 0; i < mScene->mNumMaterials; ++i ) {
aiMaterial *mat = mScene->mMaterials[ i ]; aiMaterial *mat = mScene->mMaterials[ i ];
std::string strName;
aiString name; aiString name;
if ( mat->Get( AI_MATKEY_NAME, name ) != aiReturn_SUCCESS ) { if ( mat->Get( AI_MATKEY_NAME, name ) != aiReturn_SUCCESS ) {
strName = "basemat_" + to_string( i ); strName = "basemat_" + to_string( i );
} else { } else {
strName = name.C_Str(); strName = name.C_Str();
} }
std::string hexDiffuseColor;
aiColor4D color; aiColor4D color;
if ( mat->Get( AI_MATKEY_COLOR_DIFFUSE, color ) == aiReturn_SUCCESS ) { if ( mat->Get( AI_MATKEY_COLOR_DIFFUSE, color ) == aiReturn_SUCCESS ) {
hexDiffuseColor.clear();
tmp.clear();
hexDiffuseColor = "#"; hexDiffuseColor = "#";
std::string tmp;
tmp = DecimalToHexa( color.r ); tmp = DecimalToHexa( color.r );
hexDiffuseColor += tmp; hexDiffuseColor += tmp;

View File

@ -76,6 +76,7 @@ public:
protected: protected:
void writeHeader(); void writeHeader();
void writeMetaData();
void writeBaseMaterials(); void writeBaseMaterials();
void writeObjects(); void writeObjects();
void writeMesh( aiMesh *mesh ); void writeMesh( aiMesh *mesh );

View File

@ -94,14 +94,17 @@ public:
scene->mRootNode = new aiNode(); scene->mRootNode = new aiNode();
std::vector<aiNode*> children; std::vector<aiNode*> children;
std::string nodeName;
while(ReadToEndElement(D3MF::XmlTag::model)) { while(ReadToEndElement(D3MF::XmlTag::model)) {
const std::string nodeName( xmlReader->getNodeName() ); nodeName = xmlReader->getNodeName();
if( nodeName == D3MF::XmlTag::object) { if( nodeName == D3MF::XmlTag::object) {
children.push_back(ReadObject(scene)); children.push_back(ReadObject(scene));
} else if( nodeName == D3MF::XmlTag::build) { } else if( nodeName == D3MF::XmlTag::build) {
// //
} else if ( nodeName == D3MF::XmlTag::basematerials ) { } else if ( nodeName == D3MF::XmlTag::basematerials ) {
ReadBaseMaterials(); ReadBaseMaterials();
} else if ( nodeName == D3MF::XmlTag::meta ) {
ReadMetadata();
} }
} }
@ -109,19 +112,31 @@ public:
scene->mRootNode->mName.Set( "3MF" ); scene->mRootNode->mName.Set( "3MF" );
} }
// import the metadata
if ( !mMetaData.empty() ) {
const size_t numMeta( mMetaData.size() );
scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>( numMeta ) );
for ( size_t i = 0; i < numMeta; ++i ) {
aiString val( mMetaData[ i ].value );
scene->mMetaData->Set(static_cast<unsigned int>( i ), mMetaData[ i ].name, val );
}
}
// import the meshes
scene->mNumMeshes = static_cast<unsigned int>( mMeshes.size()); scene->mNumMeshes = static_cast<unsigned int>( mMeshes.size());
scene->mMeshes = new aiMesh*[scene->mNumMeshes](); scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
std::copy( mMeshes.begin(), mMeshes.end(), scene->mMeshes); std::copy( mMeshes.begin(), mMeshes.end(), scene->mMeshes);
// import the materials
scene->mNumMaterials = static_cast<unsigned int>( mMatArray.size() ); scene->mNumMaterials = static_cast<unsigned int>( mMatArray.size() );
if ( 0 != scene->mNumMaterials ) { if ( 0 != scene->mNumMaterials ) {
scene->mMaterials = new aiMaterial*[ scene->mNumMaterials ]; scene->mMaterials = new aiMaterial*[ scene->mNumMaterials ];
std::copy( mMatArray.begin(), mMatArray.end(), scene->mMaterials ); std::copy( mMatArray.begin(), mMatArray.end(), scene->mMaterials );
} }
// create the scenegraph
scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size()); scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size());
scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren](); scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
std::copy(children.begin(), children.end(), scene->mRootNode->mChildren); std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
} }
@ -180,6 +195,21 @@ private:
return mesh; return mesh;
} }
void ReadMetadata() {
const std::string name = xmlReader->getAttributeValue( D3MF::XmlTag::meta_name.c_str() );
xmlReader->read();
const std::string value = xmlReader->getNodeData();
if ( name.empty() ) {
return;
}
MetaEntry entry;
entry.name = name;
entry.value = value;
mMetaData.push_back( entry );
}
void ImportVertices(aiMesh* mesh) { void ImportVertices(aiMesh* mesh) {
std::vector<aiVector3D> vertices; std::vector<aiVector3D> vertices;
while(ReadToEndElement(D3MF::XmlTag::vertices)) { while(ReadToEndElement(D3MF::XmlTag::vertices)) {
@ -253,7 +283,7 @@ private:
MatIdArray = it->second; MatIdArray = it->second;
} }
} }
MatIdArray.push_back( newMatIdx ); MatIdArray.push_back( static_cast<unsigned int>( newMatIdx ) );
mMatId2MatArray[ mActiveMatGroup ] = MatIdArray; mMatId2MatArray[ mActiveMatGroup ] = MatIdArray;
} }
@ -366,13 +396,17 @@ private:
return false; return false;
} }
} }
DefaultLogger::get()->error("unexpected EOF, expected closing <" + closeTag + "> tag"); ASSIMP_LOG_ERROR("unexpected EOF, expected closing <" + closeTag + "> tag");
return false; return false;
} }
private: private:
struct MetaEntry {
std::string name;
std::string value;
};
std::vector<MetaEntry> mMetaData;
std::vector<aiMesh*> mMeshes; std::vector<aiMesh*> mMeshes;
MatArray mMatArray; MatArray mMatArray;
unsigned int mActiveMatGroup; unsigned int mActiveMatGroup;

View File

@ -288,8 +288,8 @@ bool D3MFZipArchive::Exists(const char* pFile) const {
return false; return false;
} }
std::string rFile(pFile); std::string filename(pFile);
std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(rFile); std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(filename);
bool exist( false ); bool exist( false );
if(it != m_ArchiveMap.end()) { if(it != m_ArchiveMap.end()) {
exist = true; exist = true;
@ -465,7 +465,7 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
} }
} }
DefaultLogger::get()->debug(rootFile); ASSIMP_LOG_DEBUG(rootFile);
mRootStream = mZipArchive->Open(rootFile.c_str()); mRootStream = mZipArchive->Open(rootFile.c_str());
ai_assert( mRootStream != nullptr ); ai_assert( mRootStream != nullptr );

View File

@ -146,7 +146,7 @@ public:
for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++); for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++);
splitter++; splitter++;
DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)")); ASSIMP_LOG_DEBUG((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
} }
} catch(std::logic_error&) { } catch(std::logic_error&) {
ai_assert(!splitter); ai_assert(!splitter);
@ -169,7 +169,6 @@ public:
} }
private: private:
LineSplitter splitter; LineSplitter splitter;
int groupcode; int groupcode;
std::string value; std::string value;

View File

@ -119,9 +119,18 @@ DXFImporter::~DXFImporter()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool DXFImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const bool DXFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const {
{ const std::string& extension = GetExtension( pFile );
return SimpleExtensionCheck(pFile,"dxf"); if ( extension == "dxf" ) {
return true;
}
if ( extension.empty() || checkSig ) {
static const char *pTokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" };
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 4, 32 );
}
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -191,7 +200,7 @@ void DXFImporter::InternReadFile( const std::string& pFile,
// comments // comments
else if (reader.Is(999)) { else if (reader.Is(999)) {
DefaultLogger::get()->info("DXF Comment: " + reader.Value()); ASSIMP_LOG_INFO_F("DXF Comment: ", reader.Value());
} }
// don't read past the official EOF sign // don't read past the official EOF sign
@ -203,7 +212,7 @@ void DXFImporter::InternReadFile( const std::string& pFile,
++reader; ++reader;
} }
if (!eof) { if (!eof) {
DefaultLogger::get()->warn("DXF: EOF reached, but did not encounter DXF EOF marker"); ASSIMP_LOG_WARN("DXF: EOF reached, but did not encounter DXF EOF marker");
} }
ConvertMeshes(pScene,output); ConvertMeshes(pScene,output);
@ -220,7 +229,7 @@ void DXFImporter::InternReadFile( const std::string& pFile,
void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output)
{ {
// the process of resolving all the INSERT statements can grow the // the process of resolving all the INSERT statements can grow the
// polycount excessively, so log the original number. // poly-count excessively, so log the original number.
// XXX Option to import blocks as separate nodes? // XXX Option to import blocks as separate nodes?
if (!DefaultLogger::isNullLogger()) { if (!DefaultLogger::isNullLogger()) {
@ -232,16 +241,14 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output)
} }
} }
DefaultLogger::get()->debug((Formatter::format("DXF: Unexpanded polycount is "), ASSIMP_LOG_DEBUG_F("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount);
icount,", vertex count is ",vcount
));
} }
if (! output.blocks.size() ) { if (! output.blocks.size() ) {
throw DeadlyImportError("DXF: no data blocks loaded"); throw DeadlyImportError("DXF: no data blocks loaded");
} }
DXF::Block* entities = 0; DXF::Block* entities( nullptr );
// index blocks by name // index blocks by name
DXF::BlockMap blocks_by_name; DXF::BlockMap blocks_by_name;
@ -366,9 +373,7 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
// first check if the referenced blocks exists ... // first check if the referenced blocks exists ...
const DXF::BlockMap::const_iterator it = blocks_by_name.find(insert.name); const DXF::BlockMap::const_iterator it = blocks_by_name.find(insert.name);
if (it == blocks_by_name.end()) { if (it == blocks_by_name.end()) {
DefaultLogger::get()->error((Formatter::format("DXF: Failed to resolve block reference: "), ASSIMP_LOG_ERROR_F("DXF: Failed to resolve block reference: ", insert.name,"; skipping" );
insert.name,"; skipping"
));
continue; continue;
} }
@ -388,7 +393,7 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
// XXX rotation currently ignored - I didn't find an appropriate sample model. // XXX rotation currently ignored - I didn't find an appropriate sample model.
if (insert.angle != 0.f) { if (insert.angle != 0.f) {
DefaultLogger::get()->warn("DXF: BLOCK rotation not currently implemented"); ASSIMP_LOG_WARN("DXF: BLOCK rotation not currently implemented");
} }
for (aiVector3D& v : pl_out->positions) { for (aiVector3D& v : pl_out->positions) {
@ -401,7 +406,6 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/) void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/)
{ {
@ -428,7 +432,6 @@ void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/)
pScene->mMaterials[0] = pcMat; pScene->mMaterials[0] = pcMat;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/) void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/)
{ {
@ -439,9 +442,7 @@ void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/)
if (1 == pScene->mNumMeshes) { if (1 == pScene->mNumMeshes) {
pScene->mRootNode->mMeshes = new unsigned int[ pScene->mRootNode->mNumMeshes = 1 ]; pScene->mRootNode->mMeshes = new unsigned int[ pScene->mRootNode->mNumMeshes = 1 ];
pScene->mRootNode->mMeshes[0] = 0; pScene->mRootNode->mMeshes[0] = 0;
} } else {
else
{
pScene->mRootNode->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren = pScene->mNumMeshes ]; pScene->mRootNode->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren = pScene->mNumMeshes ];
for (unsigned int m = 0; m < pScene->mRootNode->mNumChildren;++m) { for (unsigned int m = 0; m < pScene->mRootNode->mNumChildren;++m) {
aiNode* p = pScene->mRootNode->mChildren[m] = new aiNode(); aiNode* p = pScene->mRootNode->mChildren[m] = new aiNode();
@ -456,22 +457,17 @@ void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::SkipSection(DXF::LineReader& reader) void DXFImporter::SkipSection(DXF::LineReader& reader) {
{
for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++); for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::ParseHeader(DXF::LineReader& reader, DXF::FileData& /*output*/) void DXFImporter::ParseHeader(DXF::LineReader& reader, DXF::FileData& ) {
{
for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++); for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output) void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output) {
{
while( !reader.End() && !reader.Is(0,"ENDSEC")) { while( !reader.End() && !reader.Is(0,"ENDSEC")) {
if (reader.Is(0,"BLOCK")) { if (reader.Is(0,"BLOCK")) {
ParseBlock(++reader,output); ParseBlock(++reader,output);
@ -480,15 +476,11 @@ void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output)
++reader; ++reader;
} }
DefaultLogger::get()->debug((Formatter::format("DXF: got "), ASSIMP_LOG_DEBUG_F("DXF: got ", output.blocks.size()," entries in BLOCKS" );
output.blocks.size()," entries in BLOCKS"
));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output) void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output) {
{
// push a new block onto the stack. // push a new block onto the stack.
output.blocks.push_back( DXF::Block() ); output.blocks.push_back( DXF::Block() );
DXF::Block& block = output.blocks.back(); DXF::Block& block = output.blocks.back();
@ -518,7 +510,7 @@ void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output)
// XXX is this a valid case? // XXX is this a valid case?
if (reader.Is(0,"INSERT")) { if (reader.Is(0,"INSERT")) {
DefaultLogger::get()->warn("DXF: INSERT within a BLOCK not currently supported; skipping"); ASSIMP_LOG_WARN("DXF: INSERT within a BLOCK not currently supported; skipping");
for( ;!reader.End() && !reader.Is(0,"ENDBLK"); ++reader); for( ;!reader.End() && !reader.Is(0,"ENDBLK"); ++reader);
break; break;
} }
@ -532,7 +524,6 @@ void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output)
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output) void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
{ {
@ -562,19 +553,16 @@ void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
++reader; ++reader;
} }
DefaultLogger::get()->debug((Formatter::format("DXF: got "), ASSIMP_LOG_DEBUG_F( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(),
block.lines.size()," polylines and ", block.insertions.size() ," inserted blocks in ENTITIES" " inserted blocks in ENTITIES" );
));
} }
void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output) void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output)
{ {
output.blocks.back().insertions.push_back( DXF::InsertBlock() ); output.blocks.back().insertions.push_back( DXF::InsertBlock() );
DXF::InsertBlock& bl = output.blocks.back().insertions.back(); DXF::InsertBlock& bl = output.blocks.back().insertions.back();
while( !reader.End() && !reader.Is(0)) { while( !reader.End() && !reader.Is(0)) {
switch(reader.GroupCode()) switch(reader.GroupCode())
{ {
// name of referenced block // name of referenced block
@ -619,8 +607,7 @@ void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output)
#define DXF_POLYLINE_FLAG_POLYFACEMESH 0x40 #define DXF_POLYLINE_FLAG_POLYFACEMESH 0x40
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) {
{
output.blocks.back().lines.push_back( std::shared_ptr<DXF::PolyLine>( new DXF::PolyLine() ) ); output.blocks.back().lines.push_back( std::shared_ptr<DXF::PolyLine>( new DXF::PolyLine() ) );
DXF::PolyLine& line = *output.blocks.back().lines.back(); DXF::PolyLine& line = *output.blocks.back().lines.back();
@ -673,14 +660,13 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
//} //}
if (vguess && line.positions.size() != vguess) { if (vguess && line.positions.size() != vguess) {
DefaultLogger::get()->warn((Formatter::format("DXF: unexpected vertex count in polymesh: "), ASSIMP_LOG_WARN_F("DXF: unexpected vertex count in polymesh: ",
line.positions.size(),", expected ", vguess line.positions.size(),", expected ", vguess );
));
} }
if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH ) { if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH ) {
if (line.positions.size() < 3 || line.indices.size() < 3) { if (line.positions.size() < 3 || line.indices.size() < 3) {
DefaultLogger::get()->warn("DXF: not enough vertices for polymesh; ignoring"); ASSIMP_LOG_WARN("DXF: not enough vertices for polymesh; ignoring");
output.blocks.back().lines.pop_back(); output.blocks.back().lines.pop_back();
return; return;
} }
@ -690,13 +676,11 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
// to set the 71 and 72 fields, respectively, to valid values. // to set the 71 and 72 fields, respectively, to valid values.
// So just fire a warning. // So just fire a warning.
if (iguess && line.counts.size() != iguess) { if (iguess && line.counts.size() != iguess) {
DefaultLogger::get()->warn((Formatter::format("DXF: unexpected face count in polymesh: "), ASSIMP_LOG_WARN_F( "DXF: unexpected face count in polymesh: ", line.counts.size(),", expected ", iguess );
line.counts.size(),", expected ", iguess
));
} }
} }
else if (!line.indices.size() && !line.counts.size()) { else if (!line.indices.size() && !line.counts.size()) {
// a polyline - so there are no indices yet. // a poly-line - so there are no indices yet.
size_t guess = line.positions.size() + (line.flags & DXF_POLYLINE_FLAG_CLOSED ? 1 : 0); size_t guess = line.positions.size() + (line.flags & DXF_POLYLINE_FLAG_CLOSED ? 1 : 0);
line.indices.reserve(guess); line.indices.reserve(guess);
@ -738,10 +722,10 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
{ {
case 8: case 8:
// layer to which the vertex belongs to - assume that // layer to which the vertex belongs to - assume that
// this is always the layer the top-level polyline // this is always the layer the top-level poly-line
// entity resides on as well. // entity resides on as well.
if(reader.Value() != line.layer) { if(reader.Value() != line.layer) {
DefaultLogger::get()->warn("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set"); ASSIMP_LOG_WARN("DXF: expected vertex to be part of a poly-face but the 0x128 flag isn't set");
} }
break; break;
@ -760,7 +744,7 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
case 73: case 73:
case 74: case 74:
if (cnti == 4) { if (cnti == 4) {
DefaultLogger::get()->warn("DXF: more than 4 indices per face not supported; ignoring"); ASSIMP_LOG_WARN("DXF: more than 4 indices per face not supported; ignoring");
break; break;
} }
indices[cnti++] = reader.ValueAsUnsignedInt(); indices[cnti++] = reader.ValueAsUnsignedInt();
@ -776,7 +760,7 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
} }
if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH && !(flags & DXF_VERTEX_FLAG_PART_OF_POLYFACE)) { if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH && !(flags & DXF_VERTEX_FLAG_PART_OF_POLYFACE)) {
DefaultLogger::get()->warn("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set"); ASSIMP_LOG_WARN("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set");
} }
if (cnti) { if (cnti) {
@ -784,14 +768,13 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
for (unsigned int i = 0; i < cnti; ++i) { for (unsigned int i = 0; i < cnti; ++i) {
// IMPORTANT NOTE: POLYMESH indices are ONE-BASED // IMPORTANT NOTE: POLYMESH indices are ONE-BASED
if (indices[i] == 0) { if (indices[i] == 0) {
DefaultLogger::get()->warn("DXF: invalid vertex index, indices are one-based."); ASSIMP_LOG_WARN("DXF: invalid vertex index, indices are one-based.");
--line.counts.back(); --line.counts.back();
continue; continue;
} }
line.indices.push_back(indices[i]-1); line.indices.push_back(indices[i]-1);
} }
} } else {
else {
line.positions.push_back(out); line.positions.push_back(out);
line.colors.push_back(clr); line.colors.push_back(clr);
} }
@ -901,7 +884,7 @@ void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
// sanity checks to see if we got something meaningful // sanity checks to see if we got something meaningful
if ((b[1] && !b[0]) || !b[2] || !b[3]) { if ((b[1] && !b[0]) || !b[2] || !b[3]) {
DefaultLogger::get()->warn("DXF: unexpected vertex setup in 3DFACE/LINE/FACE entity; ignoring"); ASSIMP_LOG_WARN("DXF: unexpected vertex setup in 3DFACE/LINE/FACE entity; ignoring");
output.blocks.back().lines.pop_back(); output.blocks.back().lines.pop_back();
return; return;
} }
@ -917,4 +900,3 @@ void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
} }
#endif // !! ASSIMP_BUILD_NO_DXF_IMPORTER #endif // !! ASSIMP_BUILD_NO_DXF_IMPORTER

View File

@ -91,7 +91,7 @@ void DeboneProcess::SetupProperties(const Importer* pImp)
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void DeboneProcess::Execute( aiScene* pScene) void DeboneProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("DeboneProcess begin"); ASSIMP_LOG_DEBUG("DeboneProcess begin");
if(!pScene->mNumMeshes) { if(!pScene->mNumMeshes) {
return; return;
@ -148,9 +148,7 @@ void DeboneProcess::Execute( aiScene* pScene)
} }
if(!DefaultLogger::isNullLogger()) { if(!DefaultLogger::isNullLogger()) {
char buffer[1024]; ASSIMP_LOG_INFO_F("Removed %u bones. Input bones:", in - out, ". Output bones: ", out);
::ai_snprintf(buffer,1024,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out);
DefaultLogger::get()->info(buffer);
} }
// and destroy the source mesh. It should be completely contained inside the new submeshes // and destroy the source mesh. It should be completely contained inside the new submeshes
@ -173,7 +171,7 @@ void DeboneProcess::Execute( aiScene* pScene)
UpdateNode( pScene->mRootNode); UpdateNode( pScene->mRootNode);
} }
DefaultLogger::get()->debug("DeboneProcess end"); ASSIMP_LOG_DEBUG("DeboneProcess end");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -209,7 +207,7 @@ bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
if(vertexBones[vid]!=cUnowned) { if(vertexBones[vid]!=cUnowned) {
if(vertexBones[vid]==i) //double entry if(vertexBones[vid]==i) //double entry
{ {
DefaultLogger::get()->warn("Encountered double entry in bone weights"); ASSIMP_LOG_WARN("Encountered double entry in bone weights");
} }
else //TODO: track attraction in order to break tie else //TODO: track attraction in order to break tie
{ {
@ -281,7 +279,7 @@ void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMe
if(vertexBones[vid]!=cUnowned) { if(vertexBones[vid]!=cUnowned) {
if(vertexBones[vid]==i) //double entry if(vertexBones[vid]==i) //double entry
{ {
//DefaultLogger::get()->warn("Encountered double entry in bone weights"); ASSIMP_LOG_WARN("Encountered double entry in bone weights");
} }
else //TODO: track attraction in order to break tie else //TODO: track attraction in order to break tie
{ {

View File

@ -76,11 +76,11 @@ bool DefaultIOSystem::Exists( const char* pFile) const
#ifdef _WIN32 #ifdef _WIN32
wchar_t fileName16[PATHLIMIT]; wchar_t fileName16[PATHLIMIT];
bool isUnicode = IsTextUnicode(pFile, strlen(pFile), NULL); bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0;
if (isUnicode) { if (isUnicode) {
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT); MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
struct _stat64 filestat; struct __stat64 filestat;
if (0 != _wstat64(fileName16, &filestat)) { if (0 != _wstat64(fileName16, &filestat)) {
return false; return false;
} }
@ -110,7 +110,7 @@ IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
FILE* file; FILE* file;
#ifdef _WIN32 #ifdef _WIN32
wchar_t fileName16[PATHLIMIT]; wchar_t fileName16[PATHLIMIT];
bool isUnicode = IsTextUnicode(strFile, strlen(strFile), NULL ); bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0;
if (isUnicode) { if (isUnicode) {
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT); MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
std::string mode8(strMode); std::string mode8(strMode);
@ -158,7 +158,7 @@ inline static void MakeAbsolutePath (const char* in, char* _out)
{ {
ai_assert(in && _out); ai_assert(in && _out);
#if defined( _MSC_VER ) || defined( __MINGW32__ ) #if defined( _MSC_VER ) || defined( __MINGW32__ )
bool isUnicode = IsTextUnicode(in, strlen(in), NULL); bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0;
if (isUnicode) { if (isUnicode) {
wchar_t out16[PATHLIMIT]; wchar_t out16[PATHLIMIT];
wchar_t in16[PATHLIMIT]; wchar_t in16[PATHLIMIT];
@ -170,7 +170,7 @@ inline static void MakeAbsolutePath (const char* in, char* _out)
if (!ret) { if (!ret) {
// preserve the input path, maybe someone else is able to fix // preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter) // the path before it is accessed (e.g. our file system filter)
DefaultLogger::get()->warn("Invalid path: " + std::string(in)); ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
strcpy(_out, in); strcpy(_out, in);
} }
@ -179,7 +179,7 @@ inline static void MakeAbsolutePath (const char* in, char* _out)
if (!ret) { if (!ret) {
// preserve the input path, maybe someone else is able to fix // preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter) // the path before it is accessed (e.g. our file system filter)
DefaultLogger::get()->warn("Invalid path: " + std::string(in)); ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
strcpy(_out, in); strcpy(_out, in);
} }
} }
@ -189,7 +189,7 @@ inline static void MakeAbsolutePath (const char* in, char* _out)
if(!ret) { if(!ret) {
// preserve the input path, maybe someone else is able to fix // preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter) // the path before it is accessed (e.g. our file system filter)
DefaultLogger::get()->warn("Invalid path: "+std::string(in)); ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
strcpy(_out,in); strcpy(_out,in);
} }
#endif #endif

View File

@ -93,29 +93,27 @@ void EmbedTexturesProcess::Execute(aiScene* pScene) {
} }
} }
char stringBuffer[128]; ASSIMP_LOG_INFO_F("EmbedTexturesProcess finished. Embedded ", embeddedTexturesCount, " textures." );
::ai_snprintf(stringBuffer, 128, "EmbedTexturesProcess finished. Embedded %u textures.", embeddedTexturesCount);
DefaultLogger::get()->info(stringBuffer);
} }
bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const { bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
uint32_t imageSize = 0; std::streampos imageSize = 0;
std::string imagePath = path; std::string imagePath = path;
// Test path directly // Test path directly
std::ifstream file(imagePath, std::ios::binary | std::ios::ate); std::ifstream file(imagePath, std::ios::binary | std::ios::ate);
if ((imageSize = file.tellg()) == -1u) { if ((imageSize = file.tellg()) == std::streampos(-1)) {
DefaultLogger::get()->warn("EmbedTexturesProcess: Cannot find image: " + imagePath + ". Will try to find it in root folder."); ASSIMP_LOG_WARN_F("EmbedTexturesProcess: Cannot find image: ", imagePath, ". Will try to find it in root folder.");
// Test path in root path // Test path in root path
imagePath = mRootPath + path; imagePath = mRootPath + path;
file.open(imagePath, std::ios::binary | std::ios::ate); file.open(imagePath, std::ios::binary | std::ios::ate);
if ((imageSize = file.tellg()) == -1u) { if ((imageSize = file.tellg()) == std::streampos(-1)) {
// Test path basename in root path // Test path basename in root path
imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u); imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u);
file.open(imagePath, std::ios::binary | std::ios::ate); file.open(imagePath, std::ios::binary | std::ios::ate);
if ((imageSize = file.tellg()) == -1u) { if ((imageSize = file.tellg()) == std::streampos(-1)) {
DefaultLogger::get()->error("EmbedTexturesProcess: Unable to embed texture: " + path + "."); ASSIMP_LOG_ERROR_F("EmbedTexturesProcess: Unable to embed texture: ", path, ".");
return false; return false;
} }
} }
@ -134,7 +132,7 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
// Add the new texture // Add the new texture
auto pTexture = new aiTexture(); auto pTexture = new aiTexture();
pTexture->mHeight = 0; // Means that this is still compressed pTexture->mHeight = 0; // Means that this is still compressed
pTexture->mWidth = imageSize; pTexture->mWidth = static_cast<uint32_t>(imageSize);
pTexture->pcData = imageContent; pTexture->pcData = imageContent;
auto extension = path.substr(path.find_last_of('.') + 1u); auto extension = path.substr(path.find_last_of('.') + 1u);

View File

@ -62,6 +62,7 @@ Here we implement only the C++ interface (Assimp::Exporter).
#include "JoinVerticesProcess.h" #include "JoinVerticesProcess.h"
#include "MakeVerboseFormat.h" #include "MakeVerboseFormat.h"
#include "ConvertToLHProcess.h" #include "ConvertToLHProcess.h"
#include "PretransformVertices.h"
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include "ScenePrivate.h" #include "ScenePrivate.h"
#include <memory> #include <memory>
@ -98,7 +99,7 @@ void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportPrope
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*); void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*); void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*); void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*);
//void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*); void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* ); void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -153,9 +154,9 @@ Exporter::ExportFormatEntry gExporters[] =
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ), aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB, Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ), aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf2", &ExportSceneGLTF2, Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf", &ExportSceneGLTF2,
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ), aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb2", &ExportSceneGLB2, Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb", &ExportSceneGLB2,
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ), aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
#endif #endif
@ -173,7 +174,7 @@ Exporter::ExportFormatEntry gExporters[] =
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER #ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
Exporter::ExportFormatEntry( "fbx", "Autodesk FBX (binary)", "fbx", &ExportSceneFBX, 0 ), Exporter::ExportFormatEntry( "fbx", "Autodesk FBX (binary)", "fbx", &ExportSceneFBX, 0 ),
//Exporter::ExportFormatEntry( "fbxa", "Autodesk FBX (ascii)", "fbx", &ExportSceneFBXA, 0 ), Exporter::ExportFormatEntry( "fbxa", "Autodesk FBX (ascii)", "fbx", &ExportSceneFBXA, 0 ),
#endif #endif
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER #ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
@ -308,7 +309,8 @@ bool IsVerboseFormat(const aiScene* pScene) {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing, const ExportProperties* pProperties) { aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
unsigned int pPreprocessing, const ExportProperties* pProperties) {
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
// when they create scenes from scratch, users will likely create them not in verbose // when they create scenes from scratch, users will likely create them not in verbose
@ -362,7 +364,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
} }
if (verbosify || (exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) { if (verbosify || (exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
DefaultLogger::get()->debug("export: Scene data not in verbose format, applying MakeVerboseFormat step first"); ASSIMP_LOG_DEBUG("export: Scene data not in verbose format, applying MakeVerboseFormat step first");
MakeVerboseFormatProcess proc; MakeVerboseFormatProcess proc;
proc.Execute(scenecopy.get()); proc.Execute(scenecopy.get());
@ -396,6 +398,11 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
} }
} }
bool exportPointCloud(false);
if (nullptr != pProperties) {
exportPointCloud = pProperties->GetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS);
}
// dispatch other processes // dispatch other processes
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
BaseProcess* const p = pimpl->mPostProcessingSteps[a]; BaseProcess* const p = pimpl->mPostProcessingSteps[a];
@ -404,7 +411,9 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
&& !dynamic_cast<FlipUVsProcess*>(p) && !dynamic_cast<FlipUVsProcess*>(p)
&& !dynamic_cast<FlipWindingOrderProcess*>(p) && !dynamic_cast<FlipWindingOrderProcess*>(p)
&& !dynamic_cast<MakeLeftHandedProcess*>(p)) { && !dynamic_cast<MakeLeftHandedProcess*>(p)) {
if (dynamic_cast<PretransformVertices*>(p) && exportPointCloud) {
continue;
}
p->Execute(scenecopy.get()); p->Execute(scenecopy.get());
} }
} }
@ -440,7 +449,6 @@ const char* Exporter::GetErrorString() const {
return pimpl->mError.c_str(); return pimpl->mError.c_str();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Exporter::FreeBlob() { void Exporter::FreeBlob() {
delete pimpl->blob; delete pimpl->blob;
@ -469,7 +477,7 @@ size_t Exporter::GetExportFormatCount() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) const { const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) const {
if (index >= GetExportFormatCount()) { if (index >= GetExportFormatCount()) {
return NULL; return nullptr;
} }
// Return from static storage if the requested index is built-in. // Return from static storage if the requested index is built-in.
@ -494,7 +502,8 @@ aiReturn Exporter::RegisterExporter(const ExportFormatEntry& desc) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Exporter::UnregisterExporter(const char* id) { void Exporter::UnregisterExporter(const char* id) {
for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin(); it != pimpl->mExporters.end(); ++it) { for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin();
it != pimpl->mExporters.end(); ++it) {
if (!strcmp((*it).mDescription.id,id)) { if (!strcmp((*it).mDescription.id,id)) {
pimpl->mExporters.erase(it); pimpl->mExporters.erase(it);
break; break;
@ -530,8 +539,7 @@ bool ExportProperties::SetPropertyFloat(const char* szName, ai_real iValue) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Set a configuration property // Set a configuration property
bool ExportProperties :: SetPropertyString(const char* szName, const std::string& value) bool ExportProperties::SetPropertyString(const char* szName, const std::string& value) {
{
return SetGenericProperty<std::string>(mStringProperties, szName,value); return SetGenericProperty<std::string>(mStringProperties, szName,value);
} }

View File

@ -448,8 +448,8 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
/*Result ignored*/ ReadByte(input, cursor, input + length); /*Result ignored*/ ReadByte(input, cursor, input + length);
const uint32_t version = ReadWord(input, cursor, input + length); const uint32_t version = ReadWord(input, cursor, input + length);
const bool is64bits = version >= 7500; const bool is64bits = version >= 7500;
while (cursor < input + length) const char *end = input + length;
{ while (cursor < end ) {
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) { if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
break; break;
} }

View File

@ -61,6 +61,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory> #include <memory>
#include <iterator> #include <iterator>
#include <vector> #include <vector>
#include <sstream>
#include <iomanip>
namespace Assimp { namespace Assimp {
namespace FBX { namespace FBX {
@ -133,9 +135,7 @@ void Converter::ConvertRootNode() {
ConvertNodes( 0L, *out->mRootNode ); ConvertNodes( 0L, *out->mRootNode );
} }
void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform ) {
void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform )
{
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced( id, "Model" ); const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced( id, "Model" );
std::vector<aiNode*> nodes; std::vector<aiNode*> nodes;
@ -153,14 +153,14 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
} }
const Object* const object = con->SourceObject(); const Object* const object = con->SourceObject();
if ( !object ) { if ( nullptr == object ) {
FBXImporter::LogWarn( "failed to convert source object for Model link" ); FBXImporter::LogWarn( "failed to convert source object for Model link" );
continue; continue;
} }
const Model* const model = dynamic_cast<const Model*>( object ); const Model* const model = dynamic_cast<const Model*>( object );
if ( model ) { if ( nullptr != model ) {
nodes_chain.clear(); nodes_chain.clear();
post_nodes_chain.clear(); post_nodes_chain.clear();
@ -174,7 +174,7 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
ai_assert( nodes_chain.size() ); ai_assert( nodes_chain.size() );
const std::string& original_name = FixNodeName( model->Name() ); std::string original_name = FixNodeName( model->Name() );
// check if any of the nodes in the chain has the name the fbx node // check if any of the nodes in the chain has the name the fbx node
// is supposed to have. If there is none, add another node to // is supposed to have. If there is none, add another node to
@ -189,7 +189,15 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
} }
if ( !name_carrier ) { if ( !name_carrier ) {
NodeNameCache::const_iterator it( std::find( mNodeNames.begin(), mNodeNames.end(), original_name ) );
if ( it != mNodeNames.end() ) {
original_name = original_name + std::string( "001" );
}
mNodeNames.push_back( original_name );
nodes_chain.push_back( new aiNode( original_name ) ); nodes_chain.push_back( new aiNode( original_name ) );
} else {
original_name = nodes_chain.back()->mName.C_Str();
} }
//setup metadata on newest node //setup metadata on newest node
@ -250,11 +258,11 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
ConvertNodes( model->ID(), *last_parent, new_abs_transform ); ConvertNodes( model->ID(), *last_parent, new_abs_transform );
if ( doc.Settings().readLights ) { if ( doc.Settings().readLights ) {
ConvertLights( *model ); ConvertLights( *model, original_name );
} }
if ( doc.Settings().readCameras ) { if ( doc.Settings().readCameras ) {
ConvertCameras( *model ); ConvertCameras( *model, original_name );
} }
nodes.push_back( nodes_chain.front() ); nodes.push_back( nodes_chain.front() );
@ -278,34 +286,31 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
} }
void Converter::ConvertLights( const Model& model ) void Converter::ConvertLights( const Model& model, const std::string &orig_name ) {
{
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
for( const NodeAttribute* attr : node_attrs ) { for( const NodeAttribute* attr : node_attrs ) {
const Light* const light = dynamic_cast<const Light*>( attr ); const Light* const light = dynamic_cast<const Light*>( attr );
if ( light ) { if ( light ) {
ConvertLight( model, *light ); ConvertLight( *light, orig_name );
} }
} }
} }
void Converter::ConvertCameras( const Model& model ) void Converter::ConvertCameras( const Model& model, const std::string &orig_name ) {
{
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
for( const NodeAttribute* attr : node_attrs ) { for( const NodeAttribute* attr : node_attrs ) {
const Camera* const cam = dynamic_cast<const Camera*>( attr ); const Camera* const cam = dynamic_cast<const Camera*>( attr );
if ( cam ) { if ( cam ) {
ConvertCamera( model, *cam ); ConvertCamera( *cam, orig_name );
} }
} }
} }
void Converter::ConvertLight( const Model& model, const Light& light ) void Converter::ConvertLight( const Light& light, const std::string &orig_name ) {
{
lights.push_back( new aiLight() ); lights.push_back( new aiLight() );
aiLight* const out_light = lights.back(); aiLight* const out_light = lights.back();
out_light->mName.Set( FixNodeName( model.Name() ) ); out_light->mName.Set( orig_name );
const float intensity = light.Intensity() / 100.0f; const float intensity = light.Intensity() / 100.0f;
const aiVector3D& col = light.Color(); const aiVector3D& col = light.Color();
@ -378,12 +383,12 @@ void Converter::ConvertLight( const Model& model, const Light& light )
} }
} }
void Converter::ConvertCamera( const Model& model, const Camera& cam ) void Converter::ConvertCamera( const Camera& cam, const std::string &orig_name )
{ {
cameras.push_back( new aiCamera() ); cameras.push_back( new aiCamera() );
aiCamera* const out_camera = cameras.back(); aiCamera* const out_camera = cameras.back();
out_camera->mName.Set( FixNodeName( model.Name() ) ); out_camera->mName.Set( orig_name );
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight(); out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
@ -397,6 +402,31 @@ void Converter::ConvertCamera( const Model& model, const Camera& cam )
out_camera->mClipPlaneFar = cam.FarPlane(); out_camera->mClipPlaneFar = cam.FarPlane();
} }
static bool HasName( NodeNameCache &cache, const std::string &name ) {
NodeNameCache::const_iterator it( std::find( cache.begin(), cache.end(), name ) );
return it != cache.end();
}
void Converter::GetUniqueName( const std::string &name, std::string uniqueName ) {
if ( !HasName( mNodeNames, name ) ) {
uniqueName = name;
return;
}
int i( 0 );
std::string newName;
while ( HasName( mNodeNames, newName ) ) {
++i;
newName.clear();
newName += name;
std::stringstream ext;
ext << std::setfill( '0' ) << std::setw( 3 ) << i;
newName += ext.str();
}
uniqueName = newName;
mNodeNames.push_back( uniqueName );
}
const char* Converter::NameTransformationComp( TransformationComp comp ) const char* Converter::NameTransformationComp( TransformationComp comp )
{ {
@ -704,7 +734,7 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
aiMatrix4x4::Scaling( GeometricScaling, chain[ TransformationComp_GeometricScaling ] ); aiMatrix4x4::Scaling( GeometricScaling, chain[ TransformationComp_GeometricScaling ] );
aiVector3D GeometricScalingInverse = GeometricScaling; aiVector3D GeometricScalingInverse = GeometricScaling;
bool canscale = true; bool canscale = true;
for (size_t i = 0; i < 3; ++i) { for (unsigned int i = 0; i < 3; ++i) {
if ( std::fabs( GeometricScalingInverse[i] ) > zero_epsilon ) { if ( std::fabs( GeometricScalingInverse[i] ) > zero_epsilon ) {
GeometricScalingInverse[i] = 1.0f / GeometricScaling[i]; GeometricScalingInverse[i] = 1.0f / GeometricScaling[i];
} else { } else {
@ -738,7 +768,7 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
// not be guaranteed. // not be guaranteed.
ai_assert( NeedsComplexTransformationChain( model ) == is_complex ); ai_assert( NeedsComplexTransformationChain( model ) == is_complex );
const std::string& name = FixNodeName( model.Name() ); std::string name = FixNodeName( model.Name() );
// now, if we have more than just Translation, Scaling and Rotation, // now, if we have more than just Translation, Scaling and Rotation,
// we need to generate a full node chain to accommodate for assimp's // we need to generate a full node chain to accommodate for assimp's
@ -786,8 +816,10 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
// else, we can just multiply the matrices together // else, we can just multiply the matrices together
aiNode* nd = new aiNode(); aiNode* nd = new aiNode();
output_nodes.push_back( nd ); output_nodes.push_back( nd );
std::string uniqueName;
GetUniqueName( name, uniqueName );
nd->mName.Set( name ); nd->mName.Set( uniqueName );
for (const auto &transform : chain) { for (const auto &transform : chain) {
nd->mTransformation = nd->mTransformation * transform; nd->mTransformation = nd->mTransformation * transform;
@ -842,7 +874,7 @@ void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4&
const MeshGeometry* const mesh = dynamic_cast< const MeshGeometry* >( geo ); const MeshGeometry* const mesh = dynamic_cast< const MeshGeometry* >( geo );
if ( mesh ) { if ( mesh ) {
const std::vector<unsigned int>& indices = ConvertMesh( *mesh, model, node_global_transform ); const std::vector<unsigned int>& indices = ConvertMesh( *mesh, model, node_global_transform, nd);
std::copy( indices.begin(), indices.end(), std::back_inserter( meshes ) ); std::copy( indices.begin(), indices.end(), std::back_inserter( meshes ) );
} }
else { else {
@ -859,7 +891,7 @@ void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4&
} }
std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform ) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
std::vector<unsigned int> temp; std::vector<unsigned int> temp;
@ -883,17 +915,17 @@ std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, cons
const MatIndexArray::value_type base = mindices[ 0 ]; const MatIndexArray::value_type base = mindices[ 0 ];
for( MatIndexArray::value_type index : mindices ) { for( MatIndexArray::value_type index : mindices ) {
if ( index != base ) { if ( index != base ) {
return ConvertMeshMultiMaterial( mesh, model, node_global_transform ); return ConvertMeshMultiMaterial( mesh, model, node_global_transform, nd);
} }
} }
} }
// faster code-path, just copy the data // faster code-path, just copy the data
temp.push_back( ConvertMeshSingleMaterial( mesh, model, node_global_transform ) ); temp.push_back( ConvertMeshSingleMaterial( mesh, model, node_global_transform, nd) );
return temp; return temp;
} }
aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh ) aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
{ {
aiMesh* const out_mesh = new aiMesh(); aiMesh* const out_mesh = new aiMesh();
meshes.push_back( out_mesh ); meshes.push_back( out_mesh );
@ -908,15 +940,19 @@ aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh )
if ( name.length() ) { if ( name.length() ) {
out_mesh->mName.Set( name ); out_mesh->mName.Set( name );
} }
else
{
out_mesh->mName = nd.mName;
}
return out_mesh; return out_mesh;
} }
unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model, unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform ) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
const MatIndexArray& mindices = mesh.GetMaterialIndices(); const MatIndexArray& mindices = mesh.GetMaterialIndices();
aiMesh* const out_mesh = SetupEmptyMesh( mesh ); aiMesh* const out_mesh = SetupEmptyMesh(mesh, nd);
const std::vector<aiVector3D>& vertices = mesh.GetVertices(); const std::vector<aiVector3D>& vertices = mesh.GetVertices();
const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts(); const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
@ -1040,7 +1076,7 @@ unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, con
} }
std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform ) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
const MatIndexArray& mindices = mesh.GetMaterialIndices(); const MatIndexArray& mindices = mesh.GetMaterialIndices();
ai_assert( mindices.size() ); ai_assert( mindices.size() );
@ -1051,7 +1087,7 @@ std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometr
for( MatIndexArray::value_type index : mindices ) { for( MatIndexArray::value_type index : mindices ) {
if ( had.find( index ) == had.end() ) { if ( had.find( index ) == had.end() ) {
indices.push_back( ConvertMeshMultiMaterial( mesh, model, index, node_global_transform ) ); indices.push_back( ConvertMeshMultiMaterial( mesh, model, index, node_global_transform, nd) );
had.insert( index ); had.insert( index );
} }
} }
@ -1061,9 +1097,10 @@ std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometr
unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model, unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
MatIndexArray::value_type index, MatIndexArray::value_type index,
const aiMatrix4x4& node_global_transform ) const aiMatrix4x4& node_global_transform,
aiNode& nd)
{ {
aiMesh* const out_mesh = SetupEmptyMesh( mesh ); aiMesh* const out_mesh = SetupEmptyMesh(mesh, nd);
const MatIndexArray& mindices = mesh.GetMaterialIndices(); const MatIndexArray& mindices = mesh.GetMaterialIndices();
const std::vector<aiVector3D>& vertices = mesh.GetVertices(); const std::vector<aiVector3D>& vertices = mesh.GetVertices();
@ -1527,7 +1564,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
if (textureReady) { if (textureReady) {
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING" // TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
// In FBX files textures are now stored internally by Assimp with their filename included // In FBX files textures are now stored internally by Assimp with their filename included
// Now Assimp can lookup thru the loaded textures after all data is processed // Now Assimp can lookup through the loaded textures after all data is processed
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it // We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
// This may occur on this case too, it has to be studied // This may occur on this case too, it has to be studied
path.data[0] = '*'; path.data[0] = '*';
@ -1643,8 +1680,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
const std::string& propName, const std::string& propName,
aiTextureType target, const MeshGeometry* const mesh ) aiTextureType target, const MeshGeometry* const mesh ) {
{
LayeredTextureMap::const_iterator it = layeredTextures.find( propName ); LayeredTextureMap::const_iterator it = layeredTextures.find( propName );
if ( it == layeredTextures.end() ) { if ( it == layeredTextures.end() ) {
return; return;
@ -1888,11 +1924,11 @@ void Converter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyT
// TransparentColor / TransparencyFactor... gee thanks FBX :rolleyes: // TransparentColor / TransparencyFactor... gee thanks FBX :rolleyes:
const aiColor3D& Transparent = GetColorPropertyFactored( props, "TransparentColor", "TransparencyFactor", ok ); const aiColor3D& Transparent = GetColorPropertyFactored( props, "TransparentColor", "TransparencyFactor", ok );
float CalculatedOpacity = 1.0; float CalculatedOpacity = 1.0f;
if ( ok ) { if ( ok ) {
out_mat->AddProperty( &Transparent, 1, AI_MATKEY_COLOR_TRANSPARENT ); out_mat->AddProperty( &Transparent, 1, AI_MATKEY_COLOR_TRANSPARENT );
// as calculated by FBX SDK 2017: // as calculated by FBX SDK 2017:
CalculatedOpacity = 1.0 - ((Transparent.r + Transparent.g + Transparent.b) / 3.0); CalculatedOpacity = 1.0f - ((Transparent.r + Transparent.g + Transparent.b) / 3.0f);
} }
// use of TransparencyFactor is inconsistent. // use of TransparencyFactor is inconsistent.
@ -2006,81 +2042,17 @@ void Converter::ConvertAnimations()
} }
} }
void Converter::RenameNode( const std::string& fixed_name, const std::string& new_name ) { std::string Converter::FixNodeName( const std::string& name ) {
if ( node_names.find( fixed_name ) == node_names.end() ) {
FBXImporter::LogError( "Cannot rename node " + fixed_name + ", not existing.");
return;
}
if ( node_names.find( new_name ) != node_names.end() ) {
FBXImporter::LogError( "Cannot rename node " + fixed_name + " to " + new_name +", name already existing." );
return;
}
ai_assert( node_names.find( fixed_name ) != node_names.end() );
ai_assert( node_names.find( new_name ) == node_names.end() );
renamed_nodes[ fixed_name ] = new_name;
const aiString fn( fixed_name );
for( aiCamera* cam : cameras ) {
if ( cam->mName == fn ) {
cam->mName.Set( new_name );
break;
}
}
for( aiLight* light : lights ) {
if ( light->mName == fn ) {
light->mName.Set( new_name );
break;
}
}
for( aiAnimation* anim : animations ) {
for ( unsigned int i = 0; i < anim->mNumChannels; ++i ) {
aiNodeAnim* const na = anim->mChannels[ i ];
if ( na->mNodeName == fn ) {
na->mNodeName.Set( new_name );
break;
}
}
}
}
std::string Converter::FixNodeName( const std::string& name )
{
// strip Model:: prefix, avoiding ambiguities (i.e. don't strip if // strip Model:: prefix, avoiding ambiguities (i.e. don't strip if
// this causes ambiguities, well possible between empty identifiers, // this causes ambiguities, well possible between empty identifiers,
// such as "Model::" and ""). Make sure the behaviour is consistent // such as "Model::" and ""). Make sure the behaviour is consistent
// across multiple calls to FixNodeName(). // across multiple calls to FixNodeName().
if ( name.substr( 0, 7 ) == "Model::" ) { if ( name.substr( 0, 7 ) == "Model::" ) {
std::string temp = name.substr( 7 ); std::string temp = name.substr( 7 );
return temp;
const NodeNameMap::const_iterator it = node_names.find( temp );
if ( it != node_names.end() ) {
if ( !( *it ).second ) {
return FixNodeName( name + "_" );
}
}
node_names[ temp ] = true;
const NameNameMap::const_iterator rit = renamed_nodes.find( temp );
return rit == renamed_nodes.end() ? temp : ( *rit ).second;
} }
const NodeNameMap::const_iterator it = node_names.find( name ); return name;
if ( it != node_names.end() ) {
if ( ( *it ).second ) {
return FixNodeName( name + "_" );
}
}
node_names[ name ] = false;
const NameNameMap::const_iterator rit = renamed_nodes.find( name );
return rit == renamed_nodes.end() ? name : ( *rit ).second;
} }
void Converter::ConvertAnimationStack( const AnimationStack& st ) void Converter::ConvertAnimationStack( const AnimationStack& st )

View File

@ -68,6 +68,8 @@ namespace FBX {
class Document; class Document;
using NodeNameCache = std::vector<std::string>;
/** /**
* Convert a FBX #Document to #aiScene * Convert a FBX #Document to #aiScene
* @param out Empty scene to be populated * @param out Empty scene to be populated
@ -117,16 +119,19 @@ private:
void ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4()); void ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4());
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertLights(const Model& model); void ConvertLights(const Model& model, const std::string &orig_name );
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertCameras(const Model& model); void ConvertCameras(const Model& model, const std::string &orig_name );
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertLight(const Model& model, const Light& light); void ConvertLight( const Light& light, const std::string &orig_name );
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertCamera(const Model& model, const Camera& cam); void ConvertCamera( const Camera& cam, const std::string &orig_name );
// ------------------------------------------------------------------------------------------------
void GetUniqueName( const std::string &name, std::string uniqueName );
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// this returns unified names usable within assimp identifiers (i.e. no space characters - // this returns unified names usable within assimp identifiers (i.e. no space characters -
@ -167,23 +172,23 @@ private:
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform); const aiMatrix4x4& node_global_transform, aiNode& nd);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMesh* SetupEmptyMesh(const MeshGeometry& mesh); aiMesh* SetupEmptyMesh(const MeshGeometry& mesh, aiNode& nd);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model, unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform); const aiMatrix4x4& node_global_transform, aiNode& nd);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::vector<unsigned int> ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform); const aiMatrix4x4& node_global_transform, aiNode& nd);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
unsigned int ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model, unsigned int ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
MatIndexArray::value_type index, MatIndexArray::value_type index,
const aiMatrix4x4& node_global_transform); const aiMatrix4x4& node_global_transform, aiNode& nd);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */ static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
@ -258,18 +263,6 @@ private:
// convert animation data to aiAnimation et al // convert animation data to aiAnimation et al
void ConvertAnimations(); void ConvertAnimations();
// ------------------------------------------------------------------------------------------------
// rename a node already partially converted. fixed_name is a string previously returned by
// FixNodeName, new_name specifies the string FixNodeName should return on all further invocations
// which would previously have returned the old value.
//
// this also updates names in node animations, cameras and light sources and is thus slow.
//
// NOTE: the caller is responsible for ensuring that the new name is unique and does
// not collide with any other identifiers. The best way to ensure this is to only
// append to the old name, which is guaranteed to match these requirements.
void RenameNode(const std::string& fixed_name, const std::string& new_name);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// takes a fbx node name and returns the identifier to be used in the assimp output scene. // takes a fbx node name and returns the identifier to be used in the assimp output scene.
// the function is guaranteed to provide consistent results over multiple invocations // the function is guaranteed to provide consistent results over multiple invocations
@ -281,7 +274,6 @@ private:
// XXX: better use multi_map .. // XXX: better use multi_map ..
typedef std::map<std::string, std::vector<const AnimationCurveNode*> > NodeMap; typedef std::map<std::string, std::vector<const AnimationCurveNode*> > NodeMap;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertAnimationStack(const AnimationStack& st); void ConvertAnimationStack(const AnimationStack& st);
@ -432,13 +424,7 @@ private:
typedef std::map<std::string, unsigned int> NodeAnimBitMap; typedef std::map<std::string, unsigned int> NodeAnimBitMap;
NodeAnimBitMap node_anim_chain_bits; NodeAnimBitMap node_anim_chain_bits;
// name -> has had its prefix_stripped? NodeNameCache mNodeNames;
typedef std::map<std::string, bool> NodeNameMap;
NodeNameMap node_names;
typedef std::map<std::string, std::string> NameNameMap;
NameNameMap renamed_nodes;
double anim_fps; double anim_fps;
aiScene* const out; aiScene* const out;

View File

@ -214,7 +214,7 @@ const Object* LazyObject::Get(bool dieOnError)
// note: the error message is already formatted, so raw logging is ok // note: the error message is already formatted, so raw logging is ok
if(!DefaultLogger::isNullLogger()) { if(!DefaultLogger::isNullLogger()) {
DefaultLogger::get()->error(ex.what()); ASSIMP_LOG_ERROR(ex.what());
} }
return NULL; return NULL;
} }
@ -575,11 +575,11 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
ai_assert( count != 0 ); ai_assert( count != 0 );
ai_assert( count <= MAX_CLASSNAMES); ai_assert( count <= MAX_CLASSNAMES);
size_t lenghts[MAX_CLASSNAMES]; size_t lengths[MAX_CLASSNAMES];
const size_t c = count; const size_t c = count;
for (size_t i = 0; i < c; ++i) { for (size_t i = 0; i < c; ++i) {
lenghts[ i ] = strlen(classnames[i]); lengths[ i ] = strlen(classnames[i]);
} }
std::vector<const Connection*> temp; std::vector<const Connection*> temp;
@ -597,7 +597,7 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
for (size_t i = 0; i < c; ++i) { for (size_t i = 0; i < c; ++i) {
ai_assert(classnames[i]); ai_assert(classnames[i]);
if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lenghts[i] && !strncmp(classnames[i],obtype,lenghts[i])) { if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lengths[i] && !strncmp(classnames[i],obtype,lengths[i])) {
obtype = NULL; obtype = NULL;
break; break;
} }

View File

@ -79,7 +79,7 @@ void DOMError(const std::string& message, const Element* element /*= NULL*/)
void DOMWarning(const std::string& message, const Token& token) void DOMWarning(const std::string& message, const Token& token)
{ {
if(DefaultLogger::get()) { if(DefaultLogger::get()) {
DefaultLogger::get()->warn(Util::AddTokenText("FBX-DOM",message,&token)); ASSIMP_LOG_WARN(Util::AddTokenText("FBX-DOM",message,&token));
} }
} }
@ -91,7 +91,7 @@ void DOMWarning(const std::string& message, const Element* element /*= NULL*/)
return; return;
} }
if(DefaultLogger::get()) { if(DefaultLogger::get()) {
DefaultLogger::get()->warn("FBX-DOM: " + message); ASSIMP_LOG_WARN("FBX-DOM: " + message);
} }
} }

View File

@ -45,9 +45,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXCommon.h" #include "FBXCommon.h"
#include <assimp/StreamWriter.h> // StreamWriterLE #include <assimp/StreamWriter.h> // StreamWriterLE
#include <assimp/Exceptional.h> // DeadlyExportError
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/StringUtils.h> // ai_snprintf
#include <string> #include <string>
#include <ostream>
#include <sstream> // ostringstream
#include <memory> // shared_ptr #include <memory> // shared_ptr
// AddP70<type> helpers... there's no usable pattern here, // AddP70<type> helpers... there's no usable pattern here,
@ -145,33 +149,174 @@ void FBX::Node::AddP70time(
} }
// public member functions for writing nodes to stream
void FBX::Node::Dump(
std::shared_ptr<Assimp::IOStream> outfile,
bool binary, int indent
) {
if (binary) {
Assimp::StreamWriterLE outstream(outfile);
DumpBinary(outstream);
} else {
std::ostringstream ss;
DumpAscii(ss, indent);
std::string s = ss.str();
outfile->Write(s.c_str(), s.size(), 1);
}
}
void FBX::Node::Dump(
Assimp::StreamWriterLE &outstream,
bool binary, int indent
) {
if (binary) {
DumpBinary(outstream);
} else {
std::ostringstream ss;
DumpAscii(ss, indent);
outstream.PutString(ss.str());
}
}
// public member functions for low-level writing
void FBX::Node::Begin(
Assimp::StreamWriterLE &s,
bool binary, int indent
) {
if (binary) {
BeginBinary(s);
} else {
// assume we're at the correct place to start already
(void)indent;
std::ostringstream ss;
BeginAscii(ss, indent);
s.PutString(ss.str());
}
}
void FBX::Node::DumpProperties(
Assimp::StreamWriterLE& s,
bool binary, int indent
) {
if (binary) {
DumpPropertiesBinary(s);
} else {
std::ostringstream ss;
DumpPropertiesAscii(ss, indent);
s.PutString(ss.str());
}
}
void FBX::Node::EndProperties(
Assimp::StreamWriterLE &s,
bool binary, int indent
) {
EndProperties(s, binary, indent, properties.size());
}
void FBX::Node::EndProperties(
Assimp::StreamWriterLE &s,
bool binary, int indent,
size_t num_properties
) {
if (binary) {
EndPropertiesBinary(s, num_properties);
} else {
// nothing to do
(void)indent;
}
}
void FBX::Node::BeginChildren(
Assimp::StreamWriterLE &s,
bool binary, int indent
) {
if (binary) {
// nothing to do
} else {
std::ostringstream ss;
BeginChildrenAscii(ss, indent);
s.PutString(ss.str());
}
}
void FBX::Node::DumpChildren(
Assimp::StreamWriterLE& s,
bool binary, int indent
) {
if (binary) {
DumpChildrenBinary(s);
} else {
std::ostringstream ss;
DumpChildrenAscii(ss, indent);
s.PutString(ss.str());
}
}
void FBX::Node::End(
Assimp::StreamWriterLE &s,
bool binary, int indent,
bool has_children
) {
if (binary) {
EndBinary(s, has_children);
} else {
std::ostringstream ss;
EndAscii(ss, indent, has_children);
s.PutString(ss.str());
}
}
// public member functions for writing to binary fbx // public member functions for writing to binary fbx
void FBX::Node::Dump(std::shared_ptr<Assimp::IOStream> outfile) void FBX::Node::DumpBinary(Assimp::StreamWriterLE &s)
{
Assimp::StreamWriterLE outstream(outfile);
Dump(outstream);
}
void FBX::Node::Dump(Assimp::StreamWriterLE &s)
{ {
// write header section (with placeholders for some things) // write header section (with placeholders for some things)
Begin(s); BeginBinary(s);
// write properties // write properties
DumpProperties(s); DumpPropertiesBinary(s);
// go back and fill in property related placeholders // go back and fill in property related placeholders
EndProperties(s, properties.size()); EndPropertiesBinary(s, properties.size());
// write children // write children
DumpChildren(s); DumpChildrenBinary(s);
// finish, filling in end offset placeholder // finish, filling in end offset placeholder
End(s, !children.empty()); EndBinary(s, force_has_children || !children.empty());
} }
void FBX::Node::Begin(Assimp::StreamWriterLE &s)
// public member functions for writing to ascii fbx
void FBX::Node::DumpAscii(std::ostream &s, int indent)
{
// write name
BeginAscii(s, indent);
// write properties
DumpPropertiesAscii(s, indent);
if (force_has_children || !children.empty()) {
// begin children (with a '{')
BeginChildrenAscii(s, indent + 1);
// write children
DumpChildrenAscii(s, indent + 1);
}
// finish (also closing the children bracket '}')
EndAscii(s, indent, force_has_children || !children.empty());
}
// private member functions for low-level writing to fbx
void FBX::Node::BeginBinary(Assimp::StreamWriterLE &s)
{ {
// remember start pos so we can come back and write the end pos // remember start pos so we can come back and write the end pos
this->start_pos = s.Tell(); this->start_pos = s.Tell();
@ -182,33 +327,21 @@ void FBX::Node::Begin(Assimp::StreamWriterLE &s)
s.PutU4(0); // total property section length s.PutU4(0); // total property section length
// node name // node name
s.PutU1(name.size()); // length of node name s.PutU1(uint8_t(name.size())); // length of node name
s.PutString(name); // node name as raw bytes s.PutString(name); // node name as raw bytes
// property data comes after here // property data comes after here
this->property_start = s.Tell(); this->property_start = s.Tell();
} }
void FBX::Node::DumpProperties(Assimp::StreamWriterLE& s) void FBX::Node::DumpPropertiesBinary(Assimp::StreamWriterLE& s)
{ {
for (auto &p : properties) { for (auto &p : properties) {
p.Dump(s); p.DumpBinary(s);
} }
} }
void FBX::Node::DumpChildren(Assimp::StreamWriterLE& s) void FBX::Node::EndPropertiesBinary(
{
for (FBX::Node& child : children) {
child.Dump(s);
}
}
void FBX::Node::EndProperties(Assimp::StreamWriterLE &s)
{
EndProperties(s, properties.size());
}
void FBX::Node::EndProperties(
Assimp::StreamWriterLE &s, Assimp::StreamWriterLE &s,
size_t num_properties size_t num_properties
) { ) {
@ -217,12 +350,19 @@ void FBX::Node::EndProperties(
ai_assert(pos > property_start); ai_assert(pos > property_start);
size_t property_section_size = pos - property_start; size_t property_section_size = pos - property_start;
s.Seek(start_pos + 4); s.Seek(start_pos + 4);
s.PutU4(num_properties); s.PutU4(uint32_t(num_properties));
s.PutU4(property_section_size); s.PutU4(uint32_t(property_section_size));
s.Seek(pos); s.Seek(pos);
} }
void FBX::Node::End( void FBX::Node::DumpChildrenBinary(Assimp::StreamWriterLE& s)
{
for (FBX::Node& child : children) {
child.DumpBinary(s);
}
}
void FBX::Node::EndBinary(
Assimp::StreamWriterLE &s, Assimp::StreamWriterLE &s,
bool has_children bool has_children
) { ) {
@ -232,53 +372,197 @@ void FBX::Node::End(
// now go back and write initial pos // now go back and write initial pos
this->end_pos = s.Tell(); this->end_pos = s.Tell();
s.Seek(start_pos); s.Seek(start_pos);
s.PutU4(end_pos); s.PutU4(uint32_t(end_pos));
s.Seek(end_pos); s.Seek(end_pos);
} }
// static member functions void FBX::Node::BeginAscii(std::ostream& s, int indent)
{
s << '\n';
for (int i = 0; i < indent; ++i) { s << '\t'; }
s << name << ": ";
}
// convenience function to create and write a property node, void FBX::Node::DumpPropertiesAscii(std::ostream &s, int indent)
// holding a single property which is an array of values. {
// does not copy the data, so is efficient for large arrays. for (size_t i = 0; i < properties.size(); ++i) {
if (i > 0) { s << ", "; }
properties[i].DumpAscii(s, indent);
}
}
void FBX::Node::BeginChildrenAscii(std::ostream& s, int indent)
{
// only call this if there are actually children
s << " {";
(void)indent;
}
void FBX::Node::DumpChildrenAscii(std::ostream& s, int indent)
{
// children will need a lot of padding and corralling
if (children.size() || force_has_children) {
for (size_t i = 0; i < children.size(); ++i) {
// no compression in ascii files, so skip this node if it exists
if (children[i].name == "EncryptionType") { continue; }
// the child can dump itself
children[i].DumpAscii(s, indent);
}
}
}
void FBX::Node::EndAscii(std::ostream& s, int indent, bool has_children)
{
if (!has_children) { return; } // nothing to do
s << '\n';
for (int i = 0; i < indent; ++i) { s << '\t'; }
s << "}";
}
// private helpers for static member functions
// ascii property node from vector of doubles
void FBX::Node::WritePropertyNodeAscii(
const std::string& name,
const std::vector<double>& v,
Assimp::StreamWriterLE& s,
int indent
){
char buffer[32];
FBX::Node node(name);
node.Begin(s, false, indent);
std::string vsize = std::to_string(v.size());
// *<size> {
s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n");
// indent + 1
for (int i = 0; i < indent + 1; ++i) { s.PutChar('\t'); }
// a: value,value,value,...
s.PutString("a: ");
int count = 0;
for (size_t i = 0; i < v.size(); ++i) {
if (i > 0) { s.PutChar(','); }
int len = ai_snprintf(buffer, sizeof(buffer), "%f", v[i]);
count += len;
if (count > 2048) { s.PutChar('\n'); count = 0; }
if (len < 0 || len > 31) {
// this should never happen
throw DeadlyExportError("failed to convert double to string");
}
for (int j = 0; j < len; ++j) { s.PutChar(buffer[j]); }
}
// }
s.PutChar('\n');
for (int i = 0; i < indent; ++i) { s.PutChar('\t'); }
s.PutChar('}'); s.PutChar(' ');
node.End(s, false, indent, false);
}
// ascii property node from vector of int32_t
void FBX::Node::WritePropertyNodeAscii(
const std::string& name,
const std::vector<int32_t>& v,
Assimp::StreamWriterLE& s,
int indent
){
char buffer[32];
FBX::Node node(name);
node.Begin(s, false, indent);
std::string vsize = std::to_string(v.size());
// *<size> {
s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n");
// indent + 1
for (int i = 0; i < indent + 1; ++i) { s.PutChar('\t'); }
// a: value,value,value,...
s.PutString("a: ");
int count = 0;
for (size_t i = 0; i < v.size(); ++i) {
if (i > 0) { s.PutChar(','); }
int len = ai_snprintf(buffer, sizeof(buffer), "%d", v[i]);
count += len;
if (count > 2048) { s.PutChar('\n'); count = 0; }
if (len < 0 || len > 31) {
// this should never happen
throw DeadlyExportError("failed to convert double to string");
}
for (int j = 0; j < len; ++j) { s.PutChar(buffer[j]); }
}
// }
s.PutChar('\n');
for (int i = 0; i < indent; ++i) { s.PutChar('\t'); }
s.PutChar('}'); s.PutChar(' ');
node.End(s, false, indent, false);
}
// binary property node from vector of doubles
// TODO: optional zip compression! // TODO: optional zip compression!
void FBX::Node::WritePropertyNode( void FBX::Node::WritePropertyNodeBinary(
const std::string& name, const std::string& name,
const std::vector<double>& v, const std::vector<double>& v,
Assimp::StreamWriterLE& s Assimp::StreamWriterLE& s
){ ){
Node node(name); FBX::Node node(name);
node.Begin(s); node.BeginBinary(s);
s.PutU1('d'); s.PutU1('d');
s.PutU4(v.size()); // number of elements s.PutU4(uint32_t(v.size())); // number of elements
s.PutU4(0); // no encoding (1 would be zip-compressed) s.PutU4(0); // no encoding (1 would be zip-compressed)
s.PutU4(v.size() * 8); // data size s.PutU4(uint32_t(v.size()) * 8); // data size
for (auto it = v.begin(); it != v.end(); ++it) { s.PutF8(*it); } for (auto it = v.begin(); it != v.end(); ++it) { s.PutF8(*it); }
node.EndProperties(s, 1); node.EndPropertiesBinary(s, 1);
node.End(s, false); node.EndBinary(s, false);
}
// binary property node from vector of int32_t
// TODO: optional zip compression!
void FBX::Node::WritePropertyNodeBinary(
const std::string& name,
const std::vector<int32_t>& v,
Assimp::StreamWriterLE& s
){
FBX::Node node(name);
node.BeginBinary(s);
s.PutU1('i');
s.PutU4(uint32_t(v.size())); // number of elements
s.PutU4(0); // no encoding (1 would be zip-compressed)
s.PutU4(uint32_t(v.size()) * 4); // data size
for (auto it = v.begin(); it != v.end(); ++it) { s.PutI4(*it); }
node.EndPropertiesBinary(s, 1);
node.EndBinary(s, false);
}
// public static member functions
// convenience function to create and write a property node,
// holding a single property which is an array of values.
// does not copy the data, so is efficient for large arrays.
void FBX::Node::WritePropertyNode(
const std::string& name,
const std::vector<double>& v,
Assimp::StreamWriterLE& s,
bool binary, int indent
){
if (binary) {
FBX::Node::WritePropertyNodeBinary(name, v, s);
} else {
FBX::Node::WritePropertyNodeAscii(name, v, s, indent);
}
} }
// convenience function to create and write a property node, // convenience function to create and write a property node,
// holding a single property which is an array of values. // holding a single property which is an array of values.
// does not copy the data, so is efficient for large arrays. // does not copy the data, so is efficient for large arrays.
// TODO: optional zip compression!
void FBX::Node::WritePropertyNode( void FBX::Node::WritePropertyNode(
const std::string& name, const std::string& name,
const std::vector<int32_t>& v, const std::vector<int32_t>& v,
Assimp::StreamWriterLE& s Assimp::StreamWriterLE& s,
bool binary, int indent
){ ){
Node node(name); if (binary) {
node.Begin(s); FBX::Node::WritePropertyNodeBinary(name, v, s);
s.PutU1('i'); } else {
s.PutU4(v.size()); // number of elements FBX::Node::WritePropertyNodeAscii(name, v, s, indent);
s.PutU4(0); // no encoding (1 would be zip-compressed) }
s.PutU4(v.size() * 4); // data size
for (auto it = v.begin(); it != v.end(); ++it) { s.PutI4(*it); }
node.EndProperties(s, 1);
node.End(s, false);
} }
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER #endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT #endif // ASSIMP_BUILD_NO_EXPORT

View File

@ -66,14 +66,18 @@ public: // public data members
std::vector<FBX::Property> properties; // node properties std::vector<FBX::Property> properties; // node properties
std::vector<FBX::Node> children; // child nodes std::vector<FBX::Node> children; // child nodes
// some nodes always pretend they have children...
bool force_has_children = false;
public: // constructors public: // constructors
Node() = default; Node() = default;
Node(const std::string& n) : name(n) {} Node(const std::string& n) : name(n) {}
Node(const std::string& n, const FBX::Property &p)
// convenience template to construct with properties directly
template <typename... More>
Node(const std::string& n, const More... more)
: name(n) : name(n)
{ properties.push_back(p); } { AddProperties(more...); }
Node(const std::string& n, const std::vector<FBX::Property> &pv)
: name(n), properties(pv) {}
public: // functions to add properties or children public: // functions to add properties or children
// add a single property to the node // add a single property to the node
@ -138,19 +142,48 @@ public: // support specifically for dealing with Properties70 nodes
public: // member functions for writing data to a file or stream public: // member functions for writing data to a file or stream
// write the full node as binary data to the given file or stream // write the full node to the given file or stream
void Dump(std::shared_ptr<Assimp::IOStream> outfile); void Dump(
void Dump(Assimp::StreamWriterLE &s); std::shared_ptr<Assimp::IOStream> outfile,
bool binary, int indent
);
void Dump(Assimp::StreamWriterLE &s, bool binary, int indent);
// these other functions are for writing data piece by piece. // these other functions are for writing data piece by piece.
// they must be used carefully. // they must be used carefully.
// for usage examples see FBXExporter.cpp. // for usage examples see FBXExporter.cpp.
void Begin(Assimp::StreamWriterLE &s); void Begin(Assimp::StreamWriterLE &s, bool binary, int indent);
void DumpProperties(Assimp::StreamWriterLE& s); void DumpProperties(Assimp::StreamWriterLE& s, bool binary, int indent);
void EndProperties(Assimp::StreamWriterLE &s); void EndProperties(Assimp::StreamWriterLE &s, bool binary, int indent);
void EndProperties(Assimp::StreamWriterLE &s, size_t num_properties); void EndProperties(
void DumpChildren(Assimp::StreamWriterLE& s); Assimp::StreamWriterLE &s, bool binary, int indent,
void End(Assimp::StreamWriterLE &s, bool has_children); size_t num_properties
);
void BeginChildren(Assimp::StreamWriterLE &s, bool binary, int indent);
void DumpChildren(Assimp::StreamWriterLE& s, bool binary, int indent);
void End(
Assimp::StreamWriterLE &s, bool binary, int indent,
bool has_children
);
private: // internal functions used for writing
void DumpBinary(Assimp::StreamWriterLE &s);
void DumpAscii(Assimp::StreamWriterLE &s, int indent);
void DumpAscii(std::ostream &s, int indent);
void BeginBinary(Assimp::StreamWriterLE &s);
void DumpPropertiesBinary(Assimp::StreamWriterLE& s);
void EndPropertiesBinary(Assimp::StreamWriterLE &s);
void EndPropertiesBinary(Assimp::StreamWriterLE &s, size_t num_properties);
void DumpChildrenBinary(Assimp::StreamWriterLE& s);
void EndBinary(Assimp::StreamWriterLE &s, bool has_children);
void BeginAscii(std::ostream &s, int indent);
void DumpPropertiesAscii(std::ostream &s, int indent);
void BeginChildrenAscii(std::ostream &s, int indent);
void DumpChildrenAscii(std::ostream &s, int indent);
void EndAscii(std::ostream &s, int indent, bool has_children);
private: // data used for binary dumps private: // data used for binary dumps
size_t start_pos; // starting position in stream size_t start_pos; // starting position in stream
@ -165,11 +198,12 @@ public: // static member functions
static void WritePropertyNode( static void WritePropertyNode(
const std::string& name, const std::string& name,
const T value, const T value,
Assimp::StreamWriterLE& s Assimp::StreamWriterLE& s,
bool binary, int indent
) { ) {
FBX::Property p(value); FBX::Property p(value);
FBX::Node node(name, p); FBX::Node node(name, p);
node.Dump(s); node.Dump(s, binary, indent);
} }
// convenience function to create and write a property node, // convenience function to create and write a property node,
@ -178,7 +212,8 @@ public: // static member functions
static void WritePropertyNode( static void WritePropertyNode(
const std::string& name, const std::string& name,
const std::vector<double>& v, const std::vector<double>& v,
Assimp::StreamWriterLE& s Assimp::StreamWriterLE& s,
bool binary, int indent
); );
// convenience function to create and write a property node, // convenience function to create and write a property node,
@ -187,8 +222,34 @@ public: // static member functions
static void WritePropertyNode( static void WritePropertyNode(
const std::string& name, const std::string& name,
const std::vector<int32_t>& v, const std::vector<int32_t>& v,
Assimp::StreamWriterLE& s,
bool binary, int indent
);
private: // static helper functions
static void WritePropertyNodeAscii(
const std::string& name,
const std::vector<double>& v,
Assimp::StreamWriterLE& s,
int indent
);
static void WritePropertyNodeAscii(
const std::string& name,
const std::vector<int32_t>& v,
Assimp::StreamWriterLE& s,
int indent
);
static void WritePropertyNodeBinary(
const std::string& name,
const std::vector<double>& v,
Assimp::StreamWriterLE& s Assimp::StreamWriterLE& s
); );
static void WritePropertyNodeBinary(
const std::string& name,
const std::vector<int32_t>& v,
Assimp::StreamWriterLE& s
);
}; };

View File

@ -48,7 +48,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string> #include <string>
#include <vector> #include <vector>
#include <sstream> // stringstream #include <ostream>
#include <locale>
#include <sstream> // ostringstream
// constructors for single element properties // constructors for single element properties
@ -116,6 +118,20 @@ FBX::Property::Property(const std::vector<int32_t>& va)
for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; } for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
} }
FBX::Property::Property(const std::vector<int64_t>& va)
: type('l'), data(8*va.size())
{
int64_t* d = reinterpret_cast<int64_t*>(data.data());
for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
}
FBX::Property::Property(const std::vector<float>& va)
: type('f'), data(4*va.size())
{
float* d = reinterpret_cast<float*>(data.data());
for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
}
FBX::Property::Property(const std::vector<double>& va) FBX::Property::Property(const std::vector<double>& va)
: type('d'), data(8*va.size()) : type('d'), data(8*va.size())
{ {
@ -127,8 +143,8 @@ FBX::Property::Property(const aiMatrix4x4& vm)
: type('d'), data(8*16) : type('d'), data(8*16)
{ {
double* d = reinterpret_cast<double*>(data.data()); double* d = reinterpret_cast<double*>(data.data());
for (size_t c = 0; c < 4; ++c) { for (unsigned int c = 0; c < 4; ++c) {
for (size_t r = 0; r < 4; ++r) { for (unsigned int r = 0; r < 4; ++r) {
d[4*c+r] = vm[r][c]; d[4*c+r] = vm[r][c];
} }
} }
@ -150,52 +166,199 @@ size_t FBX::Property::size()
} }
} }
void FBX::Property::Dump(Assimp::StreamWriterLE &s) void FBX::Property::DumpBinary(Assimp::StreamWriterLE &s)
{ {
s.PutU1(type); s.PutU1(type);
uint8_t* d; uint8_t* d = data.data();
size_t N; size_t N;
switch (type) { switch (type) {
case 'C': s.PutU1(*(reinterpret_cast<uint8_t*>(data.data()))); return; case 'C': s.PutU1(*(reinterpret_cast<uint8_t*>(d))); return;
case 'Y': s.PutI2(*(reinterpret_cast<int16_t*>(data.data()))); return; case 'Y': s.PutI2(*(reinterpret_cast<int16_t*>(d))); return;
case 'I': s.PutI4(*(reinterpret_cast<int32_t*>(data.data()))); return; case 'I': s.PutI4(*(reinterpret_cast<int32_t*>(d))); return;
case 'F': s.PutF4(*(reinterpret_cast<float*>(data.data()))); return; case 'F': s.PutF4(*(reinterpret_cast<float*>(d))); return;
case 'D': s.PutF8(*(reinterpret_cast<double*>(data.data()))); return; case 'D': s.PutF8(*(reinterpret_cast<double*>(d))); return;
case 'L': s.PutI8(*(reinterpret_cast<int64_t*>(data.data()))); return; case 'L': s.PutI8(*(reinterpret_cast<int64_t*>(d))); return;
case 'S': case 'S':
case 'R': case 'R':
s.PutU4(data.size()); s.PutU4(uint32_t(data.size()));
for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); } for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); }
return; return;
case 'i': case 'i':
N = data.size() / 4; N = data.size() / 4;
s.PutU4(N); // number of elements s.PutU4(uint32_t(N)); // number of elements
s.PutU4(0); // no encoding (1 would be zip-compressed) s.PutU4(0); // no encoding (1 would be zip-compressed)
// TODO: compress if large? // TODO: compress if large?
s.PutU4(data.size()); // data size s.PutU4(uint32_t(data.size())); // data size
d = data.data();
for (size_t i = 0; i < N; ++i) { for (size_t i = 0; i < N; ++i) {
s.PutI4((reinterpret_cast<int32_t*>(d))[i]); s.PutI4((reinterpret_cast<int32_t*>(d))[i]);
} }
return; return;
case 'd': case 'l':
N = data.size() / 8; N = data.size() / 8;
s.PutU4(N); // number of elements s.PutU4(uint32_t(N)); // number of elements
s.PutU4(0); // no encoding (1 would be zip-compressed) s.PutU4(0); // no encoding (1 would be zip-compressed)
// TODO: compress if large? // TODO: compress if large?
s.PutU4(data.size()); // data size s.PutU4(uint32_t(data.size())); // data size
d = data.data(); for (size_t i = 0; i < N; ++i) {
s.PutI8((reinterpret_cast<int64_t*>(d))[i]);
}
return;
case 'f':
N = data.size() / 4;
s.PutU4(uint32_t(N)); // number of elements
s.PutU4(0); // no encoding (1 would be zip-compressed)
// TODO: compress if large?
s.PutU4(uint32_t(data.size())); // data size
for (size_t i = 0; i < N; ++i) {
s.PutF4((reinterpret_cast<float*>(d))[i]);
}
return;
case 'd':
N = data.size() / 8;
s.PutU4(uint32_t(N)); // number of elements
s.PutU4(0); // no encoding (1 would be zip-compressed)
// TODO: compress if large?
s.PutU4(uint32_t(data.size())); // data size
for (size_t i = 0; i < N; ++i) { for (size_t i = 0; i < N; ++i) {
s.PutF8((reinterpret_cast<double*>(d))[i]); s.PutF8((reinterpret_cast<double*>(d))[i]);
} }
return; return;
default: default:
std::stringstream err; std::ostringstream err;
err << "Tried to dump property with invalid type '"; err << "Tried to dump property with invalid type '";
err << type << "'!"; err << type << "'!";
throw DeadlyExportError(err.str()); throw DeadlyExportError(err.str());
} }
} }
void FBX::Property::DumpAscii(Assimp::StreamWriterLE &outstream, int indent)
{
std::ostringstream ss;
ss.imbue(std::locale::classic());
ss.precision(15); // this seems to match official FBX SDK exports
DumpAscii(ss, indent);
outstream.PutString(ss.str());
}
void FBX::Property::DumpAscii(std::ostream& s, int indent)
{
// no writing type... or anything. just shove it into the stream.
uint8_t* d = data.data();
size_t N;
size_t swap = data.size();
size_t count = 0;
switch (type) {
case 'C':
if (*(reinterpret_cast<uint8_t*>(d))) { s << 'T'; }
else { s << 'F'; }
return;
case 'Y': s << *(reinterpret_cast<int16_t*>(d)); return;
case 'I': s << *(reinterpret_cast<int32_t*>(d)); return;
case 'F': s << *(reinterpret_cast<float*>(d)); return;
case 'D': s << *(reinterpret_cast<double*>(d)); return;
case 'L': s << *(reinterpret_cast<int64_t*>(d)); return;
case 'S':
// first search to see if it has "\x00\x01" in it -
// which separates fields which are reversed in the ascii version.
// yeah.
// FBX, yeah.
for (size_t i = 0; i < data.size(); ++i) {
if (data[i] == '\0') {
swap = i;
break;
}
}
case 'R':
s << '"';
// we might as well check this now,
// probably it will never happen
for (size_t i = 0; i < data.size(); ++i) {
char c = data[i];
if (c == '"') {
throw runtime_error("can't handle quotes in property string");
}
}
// first write the SWAPPED member (if any)
for (size_t i = swap + 2; i < data.size(); ++i) {
char c = data[i];
s << c;
}
// then a separator
if (swap != data.size()) {
s << "::";
}
// then the initial member
for (size_t i = 0; i < swap; ++i) {
char c = data[i];
s << c;
}
s << '"';
return;
case 'i':
N = data.size() / 4; // number of elements
s << '*' << N << " {\n";
for (int i = 0; i < indent + 1; ++i) { s << '\t'; }
s << "a: ";
for (size_t i = 0; i < N; ++i) {
if (i > 0) { s << ','; }
if (count++ > 120) { s << '\n'; count = 0; }
s << (reinterpret_cast<int32_t*>(d))[i];
}
s << '\n';
for (int i = 0; i < indent; ++i) { s << '\t'; }
s << "} ";
return;
case 'l':
N = data.size() / 8;
s << '*' << N << " {\n";
for (int i = 0; i < indent + 1; ++i) { s << '\t'; }
s << "a: ";
for (size_t i = 0; i < N; ++i) {
if (i > 0) { s << ','; }
if (count++ > 120) { s << '\n'; count = 0; }
s << (reinterpret_cast<int64_t*>(d))[i];
}
s << '\n';
for (int i = 0; i < indent; ++i) { s << '\t'; }
s << "} ";
return;
case 'f':
N = data.size() / 4;
s << '*' << N << " {\n";
for (int i = 0; i < indent + 1; ++i) { s << '\t'; }
s << "a: ";
for (size_t i = 0; i < N; ++i) {
if (i > 0) { s << ','; }
if (count++ > 120) { s << '\n'; count = 0; }
s << (reinterpret_cast<float*>(d))[i];
}
s << '\n';
for (int i = 0; i < indent; ++i) { s << '\t'; }
s << "} ";
return;
case 'd':
N = data.size() / 8;
s << '*' << N << " {\n";
for (int i = 0; i < indent + 1; ++i) { s << '\t'; }
s << "a: ";
// set precision to something that can handle doubles
s.precision(15);
for (size_t i = 0; i < N; ++i) {
if (i > 0) { s << ','; }
if (count++ > 120) { s << '\n'; count = 0; }
s << (reinterpret_cast<double*>(d))[i];
}
s << '\n';
for (int i = 0; i < indent; ++i) { s << '\t'; }
s << "} ";
return;
default:
std::ostringstream err;
err << "Tried to dump property with invalid type '";
err << type << "'!";
throw runtime_error(err.str());
}
}
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER #endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT #endif // ASSIMP_BUILD_NO_EXPORT

View File

@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string> #include <string>
#include <vector> #include <vector>
#include <ostream>
#include <type_traits> // is_void #include <type_traits> // is_void
namespace FBX { namespace FBX {
@ -96,7 +97,9 @@ public:
explicit Property(const std::string& s, bool raw=false); explicit Property(const std::string& s, bool raw=false);
explicit Property(const std::vector<uint8_t>& r); explicit Property(const std::vector<uint8_t>& r);
explicit Property(const std::vector<int32_t>& va); explicit Property(const std::vector<int32_t>& va);
explicit Property(const std::vector<int64_t>& va);
explicit Property(const std::vector<double>& va); explicit Property(const std::vector<double>& va);
explicit Property(const std::vector<float>& va);
explicit Property(const aiMatrix4x4& vm); explicit Property(const aiMatrix4x4& vm);
// this will catch any type not defined above, // this will catch any type not defined above,
@ -111,7 +114,10 @@ public:
size_t size(); size_t size();
// write this property node as binary data to the given stream // write this property node as binary data to the given stream
void Dump(Assimp::StreamWriterLE &s); void DumpBinary(Assimp::StreamWriterLE &s);
void DumpAscii(Assimp::StreamWriterLE &s, int indent=0);
void DumpAscii(std::ostream &s, int indent=0);
// note: make sure the ostream is in classic "C" locale
private: private:
char type; char type;

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER #ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
#include "FBXExportNode.h" // FBX::Node #include "FBXExportNode.h" // FBX::Node
#include "FBXCommon.h" // FBX::TransformInheritance
#include <assimp/types.h> #include <assimp/types.h>
//#include <assimp/material.h> //#include <assimp/material.h>
@ -89,7 +90,7 @@ namespace Assimp
const ExportProperties* mProperties; // currently unused const ExportProperties* mProperties; // currently unused
std::shared_ptr<IOStream> outfile; // file to write to std::shared_ptr<IOStream> outfile; // file to write to
std::vector<FBX::Node> connections; // conection storage std::vector<FBX::Node> connections; // connection storage
std::vector<int64_t> mesh_uids; std::vector<int64_t> mesh_uids;
std::vector<int64_t> material_uids; std::vector<int64_t> material_uids;
@ -104,6 +105,9 @@ namespace Assimp
void WriteBinaryHeader(); void WriteBinaryHeader();
void WriteBinaryFooter(); void WriteBinaryFooter();
// ascii files have a comment at the top
void WriteAsciiHeader();
// WriteAllNodes does the actual export. // WriteAllNodes does the actual export.
// It just calls all the Write<Section> methods below in order. // It just calls all the Write<Section> methods below in order.
void WriteAllNodes(); void WriteAllNodes();
@ -126,6 +130,7 @@ namespace Assimp
// WriteTakes(); // deprecated since at least 2015 (fbx 7.4) // WriteTakes(); // deprecated since at least 2015 (fbx 7.4)
// helpers // helpers
void WriteAsciiSectionHeader(const std::string& title);
void WriteModelNodes( void WriteModelNodes(
Assimp::StreamWriterLE& s, Assimp::StreamWriterLE& s,
const aiNode* node, const aiNode* node,
@ -139,6 +144,32 @@ namespace Assimp
const std::unordered_set<const aiNode*>& limbnodes, const std::unordered_set<const aiNode*>& limbnodes,
std::vector<std::pair<std::string,aiVector3D>>& transform_chain std::vector<std::pair<std::string,aiVector3D>>& transform_chain
); );
void WriteModelNode( // nor this
StreamWriterLE& s,
bool binary,
const aiNode* node,
int64_t node_uid,
const std::string& type,
const std::vector<std::pair<std::string,aiVector3D>>& xfm_chain,
FBX::TransformInheritance ti_type=FBX::TransformInheritance_RSrs
);
void WriteAnimationCurveNode(
StreamWriterLE& outstream,
int64_t uid,
std::string name, // "T", "R", or "S"
aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc
int64_t animation_layer_uid,
int64_t node_uid
);
void WriteAnimationCurve(
StreamWriterLE& outstream,
double default_value,
const std::vector<int64_t>& times,
const std::vector<float>& values,
int64_t curvenode_id,
const std::string& property_link // "d|X", "d|Y", etc
);
}; };
} }

View File

@ -302,7 +302,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
} }
if(Content) { if(Content) {
//this field is ommited when the embedded texture is already loaded, let's ignore if it's not found //this field is omitted when the embedded texture is already loaded, let's ignore if it's not found
try { try {
const Token& token = GetRequiredToken(*Content, 0); const Token& token = GetRequiredToken(*Content, 0);
const char* data = token.begin(); const char* data = token.begin();

View File

@ -79,14 +79,13 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Geometry::~Geometry() Geometry::~Geometry()
{ {
// empty
} }
const Skin* Geometry::DeformerSkin() const { const Skin* Geometry::DeformerSkin() const {
return skin; return skin;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
: Geometry(id, element,name, doc) : Geometry(id, element,name, doc)
@ -186,9 +185,8 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
MeshGeometry::~MeshGeometry() MeshGeometry::~MeshGeometry() {
{ // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -308,7 +306,6 @@ void MeshGeometry::ReadLayerElement(const Scope& layerElement)
<< type << ", index: " << typedIndex); << type << ", index: " << typedIndex);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scope& source) void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scope& source)
{ {
@ -412,7 +409,6 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Lengthy utility function to read and resolve a FBX vertex data array - that is, the // Lengthy utility function to read and resolve a FBX vertex data array - that is, the
// output is in polygon vertex order. This logic is used for reading normals, UVs, colors, // output is in polygon vertex order. This logic is used for reading normals, UVs, colors,
@ -431,7 +427,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
bool isDirect = ReferenceInformationType == "Direct"; bool isDirect = ReferenceInformationType == "Direct";
bool isIndexToDirect = ReferenceInformationType == "IndexToDirect"; bool isIndexToDirect = ReferenceInformationType == "IndexToDirect";
// fallback to direct data if there is no index data element // fall-back to direct data if there is no index data element
if ( isIndexToDirect && !HasElement( source, indexDataElementName ) ) { if ( isIndexToDirect && !HasElement( source, indexDataElementName ) ) {
isDirect = true; isDirect = true;
isIndexToDirect = false; isIndexToDirect = false;
@ -499,8 +495,13 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
return; return;
} }
const T empty;
unsigned int next = 0; unsigned int next = 0;
for(int i : uvIndices) { for(int i : uvIndices) {
if ( -1 == i ) {
data_out[ next++ ] = empty;
continue;
}
if (static_cast<size_t>(i) >= tempData.size()) { if (static_cast<size_t>(i) >= tempData.size()) {
DOMError("index out of range",&GetRequiredElement(source,indexDataElementName)); DOMError("index out of range",&GetRequiredElement(source,indexDataElementName));
} }
@ -528,7 +529,6 @@ void MeshGeometry::ReadVertexDataNormals(std::vector<aiVector3D>& normals_out, c
m_mappings); m_mappings);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadVertexDataUV(std::vector<aiVector2D>& uv_out, const Scope& source, void MeshGeometry::ReadVertexDataUV(std::vector<aiVector2D>& uv_out, const Scope& source,
const std::string& MappingInformationType, const std::string& MappingInformationType,
@ -543,7 +543,6 @@ void MeshGeometry::ReadVertexDataUV(std::vector<aiVector2D>& uv_out, const Scope
m_mappings); m_mappings);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadVertexDataColors(std::vector<aiColor4D>& colors_out, const Scope& source, void MeshGeometry::ReadVertexDataColors(std::vector<aiColor4D>& colors_out, const Scope& source,
const std::string& MappingInformationType, const std::string& MappingInformationType,

View File

@ -68,7 +68,6 @@ private:
const Skin* skin; const Skin* skin;
}; };
typedef std::vector<int> MatIndexArray; typedef std::vector<int> MatIndexArray;
@ -95,8 +94,8 @@ public:
* if no tangents are specified */ * if no tangents are specified */
const std::vector<aiVector3D>& GetTangents() const; const std::vector<aiVector3D>& GetTangents() const;
/** Get a list of all vertex binormals or an empty array /** Get a list of all vertex bi-normals or an empty array
* if no binormals are specified */ * if no bi-normals are specified */
const std::vector<aiVector3D>& GetBinormals() const; const std::vector<aiVector3D>& GetBinormals() const;
/** Return list of faces - each entry denotes a face and specifies /** Return list of faces - each entry denotes a face and specifies

View File

@ -54,6 +54,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
//remove mesh at position 'index' from the scene
static void removeMesh(aiScene* pScene, unsigned const index);
//correct node indices to meshes and remove references to deleted mesh
static void updateSceneGraph(aiNode* pNode, unsigned const index);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
FindDegeneratesProcess::FindDegeneratesProcess() FindDegeneratesProcess::FindDegeneratesProcess()
@ -85,11 +90,50 @@ void FindDegeneratesProcess::SetupProperties(const Importer* pImp) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FindDegeneratesProcess::Execute( aiScene* pScene) { void FindDegeneratesProcess::Execute( aiScene* pScene) {
DefaultLogger::get()->debug("FindDegeneratesProcess begin"); ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){ for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
ExecuteOnMesh( pScene->mMeshes[ i ] ); if (ExecuteOnMesh(pScene->mMeshes[i])) {
removeMesh(pScene, i);
--i; //the current i is removed, do not skip the next one
}
}
ASSIMP_LOG_DEBUG("FindDegeneratesProcess finished");
}
static void removeMesh(aiScene* pScene, unsigned const index) {
//we start at index and copy the pointers one position forward
//save the mesh pointer to delete it later
auto delete_me = pScene->mMeshes[index];
for (unsigned i = index; i < pScene->mNumMeshes - 1; ++i) {
pScene->mMeshes[i] = pScene->mMeshes[i+1];
}
pScene->mMeshes[pScene->mNumMeshes - 1] = nullptr;
--(pScene->mNumMeshes);
delete delete_me;
//removing a mesh also requires updating all references to it in the scene graph
updateSceneGraph(pScene->mRootNode, index);
}
static void updateSceneGraph(aiNode* pNode, unsigned const index) {
for (unsigned i = 0; i < pNode->mNumMeshes; ++i) {
if (pNode->mMeshes[i] > index) {
--(pNode->mMeshes[i]);
continue;
}
if (pNode->mMeshes[i] == index) {
for (unsigned j = i; j < pNode->mNumMeshes -1; ++j) {
pNode->mMeshes[j] = pNode->mMeshes[j+1];
}
--(pNode->mNumMeshes);
--i;
continue;
}
}
//recurse to all children
for (unsigned i = 0; i < pNode->mNumChildren; ++i) {
updateSceneGraph(pNode->mChildren[i], index);
} }
DefaultLogger::get()->debug("FindDegeneratesProcess finished");
} }
static ai_real heron( ai_real a, ai_real b, ai_real c ) { static ai_real heron( ai_real a, ai_real b, ai_real c ) {
@ -125,7 +169,7 @@ static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported mesh // Executes the post processing step on the given imported mesh
void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) { bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
mesh->mPrimitiveTypes = 0; mesh->mPrimitiveTypes = 0;
std::vector<bool> remove_me; std::vector<bool> remove_me;
@ -161,7 +205,7 @@ void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
// NOTE: we set the removed vertex index to an unique value // NOTE: we set the removed vertex index to an unique value
// to make sure the developer gets notified when his // to make sure the developer gets notified when his
// application attemps to access this data. // application attempts to access this data.
face.mIndices[ face.mNumIndices ] = 0xdeadbeef; face.mIndices[ face.mNumIndices ] = 0xdeadbeef;
if(first) { if(first) {
@ -227,33 +271,28 @@ evil_jump_outside:
if (&face_src != &face_dest) { if (&face_src != &face_dest) {
// clear source // clear source
face_src.mNumIndices = 0; face_src.mNumIndices = 0;
face_src.mIndices = NULL; face_src.mIndices = nullptr;
} }
} }
else { else {
// Otherwise delete it if we don't need this face // Otherwise delete it if we don't need this face
delete[] face_src.mIndices; delete[] face_src.mIndices;
face_src.mIndices = NULL; face_src.mIndices = nullptr;
face_src.mNumIndices = 0; face_src.mNumIndices = 0;
} }
} }
// Just leave the rest of the array unreferenced, we don't care for now // Just leave the rest of the array unreferenced, we don't care for now
mesh->mNumFaces = n; mesh->mNumFaces = n;
if (!mesh->mNumFaces) { if (!mesh->mNumFaces) {
// WTF!? //The whole mesh consists of degenerated faces
// OK ... for completeness and because I'm not yet tired, //signal upward, that this mesh should be deleted.
// let's write code that willl hopefully never be called ASSIMP_LOG_DEBUG("FindDegeneratesProcess removed a mesh full of degenerated primitives");
// (famous last words) return true;
// OK ... bad idea.
throw DeadlyImportError("Mesh is empty after removal of degenerated primitives ... WTF!?");
} }
} }
if (deg && !DefaultLogger::isNullLogger()) if (deg && !DefaultLogger::isNullLogger()) {
{ ASSIMP_LOG_WARN_F( "Found ", deg, " degenerated primitives");
char s[64];
ASSIMP_itoa10(s,deg);
DefaultLogger::get()->warn(std::string("Found ") + s + " degenerated primitives");
} }
return false;
} }

View File

@ -74,7 +74,8 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Execute step on a given mesh // Execute step on a given mesh
void ExecuteOnMesh( aiMesh* mesh); ///@returns true if the current mesh should be deleted, false otherwise
bool ExecuteOnMesh( aiMesh* mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// @brief Enable the instant removal of degenerated primitives /// @brief Enable the instant removal of degenerated primitives

View File

@ -119,7 +119,7 @@ void UpdateMeshIndices(aiNode* node, unsigned int* lookup)
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FindInstancesProcess::Execute( aiScene* pScene) void FindInstancesProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FindInstancesProcess begin"); ASSIMP_LOG_DEBUG("FindInstancesProcess begin");
if (pScene->mNumMeshes) { if (pScene->mNumMeshes) {
// use a pseudo hash for all meshes in the scene to quickly find // use a pseudo hash for all meshes in the scene to quickly find
@ -267,13 +267,11 @@ void FindInstancesProcess::Execute( aiScene* pScene)
// write to log // write to log
if (!DefaultLogger::isNullLogger()) { if (!DefaultLogger::isNullLogger()) {
ASSIMP_LOG_INFO_F( "FindInstancesProcess finished. Found ", (pScene->mNumMeshes - numMeshesOut), " instances" );
char buffer[512];
::ai_snprintf(buffer,512,"FindInstancesProcess finished. Found %i instances",pScene->mNumMeshes-numMeshesOut);
DefaultLogger::get()->info(buffer);
} }
pScene->mNumMeshes = numMeshesOut; pScene->mNumMeshes = numMeshesOut;
} } else {
else DefaultLogger::get()->debug("FindInstancesProcess finished. No instanced meshes found"); ASSIMP_LOG_DEBUG("FindInstancesProcess finished. No instanced meshes found");
}
} }
} }

View File

@ -118,7 +118,7 @@ void UpdateMeshReferences(aiNode* node, const std::vector<unsigned int>& meshMap
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FindInvalidDataProcess::Execute( aiScene* pScene) void FindInvalidDataProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FindInvalidDataProcess begin"); ASSIMP_LOG_DEBUG("FindInvalidDataProcess begin");
bool out = false; bool out = false;
std::vector<unsigned int> meshMapping(pScene->mNumMeshes); std::vector<unsigned int> meshMapping(pScene->mNumMeshes);
@ -163,9 +163,10 @@ void FindInvalidDataProcess::Execute( aiScene* pScene)
pScene->mNumMeshes = real; pScene->mNumMeshes = real;
} }
DefaultLogger::get()->info("FindInvalidDataProcess finished. Found issues ..."); ASSIMP_LOG_INFO("FindInvalidDataProcess finished. Found issues ...");
} else {
ASSIMP_LOG_DEBUG("FindInvalidDataProcess finished. Everything seems to be OK.");
} }
else DefaultLogger::get()->debug("FindInvalidDataProcess finished. Everything seems to be OK.");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -212,8 +213,7 @@ inline bool ProcessArray(T*& in, unsigned int num,const char* name,
{ {
const char* err = ValidateArrayContents(in,num,dirtyMask,mayBeIdentical,mayBeZero); const char* err = ValidateArrayContents(in,num,dirtyMask,mayBeIdentical,mayBeZero);
if (err) { if (err) {
DefaultLogger::get()->error(std::string("FindInvalidDataProcess fails on mesh ") + name + ": " + err); ASSIMP_LOG_ERROR_F( "FindInvalidDataProcess fails on mesh ", name, ": ", err);
delete[] in; delete[] in;
in = NULL; in = NULL;
return true; return true;
@ -332,7 +332,7 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
i = 1; i = 1;
} }
if (1 == i) if (1 == i)
DefaultLogger::get()->warn("Simplified dummy tracks with just one key"); ASSIMP_LOG_WARN("Simplified dummy tracks with just one key");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -354,7 +354,7 @@ int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
// Process vertex positions // Process vertex positions
if (pMesh->mVertices && ProcessArray(pMesh->mVertices, pMesh->mNumVertices, "positions", dirtyMask)) { if (pMesh->mVertices && ProcessArray(pMesh->mVertices, pMesh->mNumVertices, "positions", dirtyMask)) {
DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions"); ASSIMP_LOG_ERROR("Deleting mesh: Unable to continue without vertex positions");
return 2; return 2;
} }

View File

@ -82,28 +82,35 @@ bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FixInfacingNormalsProcess::Execute( aiScene* pScene) void FixInfacingNormalsProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FixInfacingNormalsProcess begin"); ASSIMP_LOG_DEBUG("FixInfacingNormalsProcess begin");
bool bHas = false; bool bHas( false );
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
if(ProcessMesh( pScene->mMeshes[a],a))bHas = true; if (ProcessMesh(pScene->mMeshes[a], a)) {
bHas = true;
}
}
if (bHas) if (bHas) {
DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. Found issues."); ASSIMP_LOG_DEBUG("FixInfacingNormalsProcess finished. Found issues.");
else DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. No changes to the scene."); } else {
ASSIMP_LOG_DEBUG("FixInfacingNormalsProcess finished. No changes to the scene.");
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Apply the step to the mesh // Apply the step to the mesh
bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index) bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
{ {
ai_assert(NULL != pcMesh); ai_assert(nullptr != pcMesh);
// Nothing to do if there are no model normals // Nothing to do if there are no model normals
if (!pcMesh->HasNormals())return false; if (!pcMesh->HasNormals()) {
return false;
}
// Compute the bounding box of both the model vertices + normals and // Compute the bounding box of both the model vertices + normals and
// the umodified model vertices. Then check whether the first BB // the unmodified model vertices. Then check whether the first BB
// is smaller than the second. In this case we can assume that the // is smaller than the second. In this case we can assume that the
// normals need to be flipped, although there are a few special cases .. // normals need to be flipped, although there are a few special cases ..
// convex, concave, planar models ... // convex, concave, planar models ...
@ -155,14 +162,9 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
if (fDelta1_z < 0.05f * std::sqrt( fDelta1_y * fDelta1_x ))return false; if (fDelta1_z < 0.05f * std::sqrt( fDelta1_y * fDelta1_x ))return false;
// now compare the volumes of the bounding boxes // now compare the volumes of the bounding boxes
if (std::fabs(fDelta0_x * fDelta0_y * fDelta0_z) < if (std::fabs(fDelta0_x * fDelta0_y * fDelta0_z) < std::fabs(fDelta1_x * fDelta1_yz)) {
std::fabs(fDelta1_x * fDelta1_yz)) if (!DefaultLogger::isNullLogger()) {
{ ASSIMP_LOG_INFO_F("Mesh ", index, ": Normals are facing inwards (or the mesh is planar)", index);
if (!DefaultLogger::isNullLogger())
{
char buffer[128]; // should be sufficiently large
ai_snprintf(buffer,128,"Mesh %u: Normals are facing inwards (or the mesh is planar)",index);
DefaultLogger::get()->info(buffer);
} }
// Invert normals // Invert normals

View File

@ -72,16 +72,14 @@ GenFaceNormalsProcess::~GenFaceNormalsProcess()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool GenFaceNormalsProcess::IsActive( unsigned int pFlags) const bool GenFaceNormalsProcess::IsActive( unsigned int pFlags) const {
{
return (pFlags & aiProcess_GenNormals) != 0; return (pFlags & aiProcess_GenNormals) != 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void GenFaceNormalsProcess::Execute( aiScene* pScene) void GenFaceNormalsProcess::Execute( aiScene* pScene) {
{ ASSIMP_LOG_DEBUG("GenFaceNormalsProcess begin");
DefaultLogger::get()->debug("GenFaceNormalsProcess begin");
if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) { if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here"); throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
@ -94,12 +92,13 @@ void GenFaceNormalsProcess::Execute( aiScene* pScene)
} }
} }
if (bHas) { if (bHas) {
DefaultLogger::get()->info("GenFaceNormalsProcess finished. " ASSIMP_LOG_INFO("GenFaceNormalsProcess finished. "
"Face normals have been calculated"); "Face normals have been calculated");
} } else {
else DefaultLogger::get()->debug("GenFaceNormalsProcess finished. " ASSIMP_LOG_DEBUG("GenFaceNormalsProcess finished. "
"Normals are already there"); "Normals are already there");
} }
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
@ -113,7 +112,7 @@ bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
// triangles or higher-order polygons the normal vectors // triangles or higher-order polygons the normal vectors
// are undefined. // are undefined.
if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) { if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) {
DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes"); ASSIMP_LOG_INFO("Normal vectors are undefined for line and point meshes");
return false; return false;
} }

View File

@ -88,25 +88,26 @@ void GenVertexNormalsProcess::SetupProperties(const Importer* pImp)
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void GenVertexNormalsProcess::Execute( aiScene* pScene) void GenVertexNormalsProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("GenVertexNormalsProcess begin"); ASSIMP_LOG_DEBUG("GenVertexNormalsProcess begin");
if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here"); throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
}
bool bHas = false; bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
{
if(GenMeshVertexNormals( pScene->mMeshes[a],a)) if(GenMeshVertexNormals( pScene->mMeshes[a],a))
bHas = true; bHas = true;
} }
if (bHas) { if (bHas) {
DefaultLogger::get()->info("GenVertexNormalsProcess finished. " ASSIMP_LOG_INFO("GenVertexNormalsProcess finished. "
"Vertex normals have been calculated"); "Vertex normals have been calculated");
} } else {
else DefaultLogger::get()->debug("GenVertexNormalsProcess finished. " ASSIMP_LOG_DEBUG("GenVertexNormalsProcess finished. "
"Normals are already there"); "Normals are already there");
} }
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
@ -120,7 +121,7 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
// are undefined. // are undefined.
if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
{ {
DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes"); ASSIMP_LOG_INFO("Normal vectors are undefined for line and point meshes");
return false; return false;
} }
@ -145,7 +146,7 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]]; const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]]; const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)); const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
for (unsigned int i = 0;i < face.mNumIndices;++i) { for (unsigned int i = 0;i < face.mNumIndices;++i) {
pMesh->mNormals[face.mIndices[i]] = vNor; pMesh->mNormals[face.mIndices[i]] = vNor;
@ -213,17 +214,15 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound); vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound);
aiVector3D vr = pMesh->mNormals[i]; aiVector3D vr = pMesh->mNormals[i];
ai_real vrlen = vr.Length();
aiVector3D pcNor; aiVector3D pcNor;
for (unsigned int a = 0; a < verticesFound.size(); ++a) { for (unsigned int a = 0; a < verticesFound.size(); ++a) {
aiVector3D v = pMesh->mNormals[verticesFound[a]]; aiVector3D v = pMesh->mNormals[verticesFound[a]];
// check whether the angle between the two normals is not too large // Check whether the angle between the two normals is not too large.
// HACK: if v.x is qnan the dot product will become qnan, too // Skip the angle check on our own normal to avoid false negatives
// therefore the comparison against fLimit should be false // (v*v is not guaranteed to be 1.0 for all unit vectors v)
// in every case. if (is_not_qnan(v.x) && (verticesFound[a] == i || (v * vr >= fLimit)))
if (v * vr >= fLimit * vrlen * v.Length())
pcNor += v; pcNor += v;
} }
pcNew[i] = pcNor.NormalizeSafe(); pcNew[i] = pcNor.NormalizeSafe();

View File

@ -141,21 +141,21 @@ void HMPImporter::InternReadFile( const std::string& pFile,
if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic || if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic ||
AI_HMP_MAGIC_NUMBER_BE_4 == iMagic) AI_HMP_MAGIC_NUMBER_BE_4 == iMagic)
{ {
DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A4, magic word is HMP4"); ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A4, magic word is HMP4");
InternReadFile_HMP4(); InternReadFile_HMP4();
} }
// HMP5 format // HMP5 format
else if (AI_HMP_MAGIC_NUMBER_LE_5 == iMagic || else if (AI_HMP_MAGIC_NUMBER_LE_5 == iMagic ||
AI_HMP_MAGIC_NUMBER_BE_5 == iMagic) AI_HMP_MAGIC_NUMBER_BE_5 == iMagic)
{ {
DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A5, magic word is HMP5"); ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A5, magic word is HMP5");
InternReadFile_HMP5(); InternReadFile_HMP5();
} }
// HMP7 format // HMP7 format
else if (AI_HMP_MAGIC_NUMBER_LE_7 == iMagic || else if (AI_HMP_MAGIC_NUMBER_LE_7 == iMagic ||
AI_HMP_MAGIC_NUMBER_BE_7 == iMagic) AI_HMP_MAGIC_NUMBER_BE_7 == iMagic)
{ {
DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A7, magic word is HMP7"); ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A7, magic word is HMP7");
InternReadFile_HMP7(); InternReadFile_HMP7();
} }
else else

View File

@ -131,7 +131,7 @@ void IRRImporter::SetupProperties(const Importer* pImp)
// read the output frame rate of all node animation channels // read the output frame rate of all node animation channels
fps = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_IRR_ANIM_FPS,100); fps = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_IRR_ANIM_FPS,100);
if (fps < 10.) { if (fps < 10.) {
DefaultLogger::get()->error("IRR: Invalid FPS configuration"); ASSIMP_LOG_ERROR("IRR: Invalid FPS configuration");
fps = 100; fps = 100;
} }
@ -281,7 +281,7 @@ void IRRImporter::CopyMaterial(std::vector<aiMaterial*>& materials,
return; return;
} }
else if (inmaterials.size() > 1) { else if (inmaterials.size() > 1) {
DefaultLogger::get()->info("IRR: Skipping additional materials"); ASSIMP_LOG_INFO("IRR: Skipping additional materials");
} }
mesh->mMaterialIndex = (unsigned int)materials.size(); mesh->mMaterialIndex = (unsigned int)materials.size();
@ -319,17 +319,18 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
if (root->animators.empty()) { if (root->animators.empty()) {
return; return;
} }
unsigned int total = 0; unsigned int total( 0 );
for (std::list<Animator>::iterator it = root->animators.begin();it != root->animators.end(); ++it) { for (std::list<Animator>::iterator it = root->animators.begin();it != root->animators.end(); ++it) {
if ((*it).type == Animator::UNKNOWN || (*it).type == Animator::OTHER) { if ((*it).type == Animator::UNKNOWN || (*it).type == Animator::OTHER) {
DefaultLogger::get()->warn("IRR: Skipping unknown or unsupported animator"); ASSIMP_LOG_WARN("IRR: Skipping unknown or unsupported animator");
continue; continue;
} }
++total; ++total;
} }
if (!total)return; if (!total) {
else if (1 == total) { return;
DefaultLogger::get()->warn("IRR: Adding dummy nodes to simulate multiple animators"); } else if (1 == total) {
ASSIMP_LOG_WARN("IRR: Adding dummy nodes to simulate multiple animators");
} }
// NOTE: 1 tick == i millisecond // NOTE: 1 tick == i millisecond
@ -518,9 +519,9 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
const int size = (int)in.splineKeys.size(); const int size = (int)in.splineKeys.size();
if (!size) { if (!size) {
// We have no point in the spline. That's bad. Really bad. // We have no point in the spline. That's bad. Really bad.
DefaultLogger::get()->warn("IRR: Spline animators with no points defined"); ASSIMP_LOG_WARN("IRR: Spline animators with no points defined");
delete anim;anim = NULL; delete anim;anim = nullptr;
break; break;
} }
else if (size == 1) { else if (size == 1) {
@ -672,7 +673,7 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
// graph we're currently building // graph we're currently building
aiScene* scene = batch.GetImport(root->id); aiScene* scene = batch.GetImport(root->id);
if (!scene) { if (!scene) {
DefaultLogger::get()->error("IRR: Unable to load external file: " + root->meshPath); ASSIMP_LOG_ERROR("IRR: Unable to load external file: " + root->meshPath);
break; break;
} }
attach.push_back(AttachmentInfo(scene,rootOut)); attach.push_back(AttachmentInfo(scene,rootOut));
@ -683,7 +684,7 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
// should be equal. If they are not, we can impossibly // should be equal. If they are not, we can impossibly
// do this ... // do this ...
if (root->materials.size() != (unsigned int)scene->mNumMaterials) { if (root->materials.size() != (unsigned int)scene->mNumMaterials) {
DefaultLogger::get()->warn("IRR: Failed to match imported materials " ASSIMP_LOG_WARN("IRR: Failed to match imported materials "
"with the materials found in the IRR scene file"); "with the materials found in the IRR scene file");
break; break;
@ -722,7 +723,7 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
} }
} }
if (bdo) { if (bdo) {
DefaultLogger::get()->info("IRR: Replacing mesh vertex alpha with common opacity"); ASSIMP_LOG_INFO("IRR: Replacing mesh vertex alpha with common opacity");
for (unsigned int a = 0; a < mesh->mNumVertices;++a) for (unsigned int a = 0; a < mesh->mNumVertices;++a)
mesh->mColors[0][a].a = 1.f; mesh->mColors[0][a].a = 1.f;
@ -806,7 +807,7 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
{ {
// A skybox is defined by six materials // A skybox is defined by six materials
if (root->materials.size() < 6) { if (root->materials.size() < 6) {
DefaultLogger::get()->error("IRR: There should be six materials for a skybox"); ASSIMP_LOG_ERROR("IRR: There should be six materials for a skybox");
break; break;
} }
@ -823,7 +824,7 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
// for IRR skyboxes. We add a 'IRR.SkyBox_' prefix to the node. // for IRR skyboxes. We add a 'IRR.SkyBox_' prefix to the node.
// ************************************************************* // *************************************************************
root->name = "IRR.SkyBox_" + root->name; root->name = "IRR.SkyBox_" + root->name;
DefaultLogger::get()->info("IRR: Loading skybox, this will " ASSIMP_LOG_INFO("IRR: Loading skybox, this will "
"require special handling to be displayed correctly"); "require special handling to be displayed correctly");
} }
break; break;
@ -831,7 +832,7 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
case Node::TERRAIN: case Node::TERRAIN:
{ {
// to support terrains, we'd need to have a texture decoder // to support terrains, we'd need to have a texture decoder
DefaultLogger::get()->error("IRR: Unsupported node - TERRAIN"); ASSIMP_LOG_ERROR("IRR: Unsupported node - TERRAIN");
} }
break; break;
default: default:
@ -1010,11 +1011,11 @@ void IRRImporter::InternReadFile( const std::string& pFile,
} }
else if (!ASSIMP_stricmp(sz,"billBoard")) { else if (!ASSIMP_stricmp(sz,"billBoard")) {
// We don't support billboards, so ignore them // We don't support billboards, so ignore them
DefaultLogger::get()->error("IRR: Billboards are not supported by Assimp"); ASSIMP_LOG_ERROR("IRR: Billboards are not supported by Assimp");
nd = new Node(Node::DUMMY); nd = new Node(Node::DUMMY);
} }
else { else {
DefaultLogger::get()->warn("IRR: Found unknown node: " + std::string(sz)); ASSIMP_LOG_WARN("IRR: Found unknown node: " + std::string(sz));
/* We skip the contents of nodes we don't know. /* We skip the contents of nodes we don't know.
* We parse the transformation and all animators * We parse the transformation and all animators
@ -1041,7 +1042,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
*/ */
if (!curNode) { if (!curNode) {
#if 0 #if 0
DefaultLogger::get()->error("IRR: Encountered <attributes> element, but " ASSIMP_LOG_ERROR("IRR: Encountered <attributes> element, but "
"there is no node active"); "there is no node active");
#endif #endif
continue; continue;
@ -1269,7 +1270,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
lights.pop_back(); lights.pop_back();
curNode->type = Node::DUMMY; curNode->type = Node::DUMMY;
DefaultLogger::get()->error("Ignoring light of unknown type: " + prop.value); ASSIMP_LOG_ERROR("Ignoring light of unknown type: " + prop.value);
} }
} }
else if ((prop.name == "Mesh" && Node::MESH == curNode->type) || else if ((prop.name == "Mesh" && Node::MESH == curNode->type) ||
@ -1277,7 +1278,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
{ {
/* This is the file name of the mesh - either /* This is the file name of the mesh - either
* animated or not. We need to make sure we setup * animated or not. We need to make sure we setup
* the correct postprocessing settings here. * the correct post-processing settings here.
*/ */
unsigned int pp = 0; unsigned int pp = 0;
BatchLoader::PropertyMap map; BatchLoader::PropertyMap map;
@ -1299,7 +1300,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
const std::string extension = GetExtension(prop.value); const std::string extension = GetExtension(prop.value);
if ("irr" == extension) { if ("irr" == extension) {
DefaultLogger::get()->error("IRR: Can't load another IRR file recursively"); ASSIMP_LOG_ERROR("IRR: Can't load another IRR file recursively");
} }
else else
{ {
@ -1323,7 +1324,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
curAnim->type = Animator::FOLLOW_SPLINE; curAnim->type = Animator::FOLLOW_SPLINE;
} }
else { else {
DefaultLogger::get()->warn("IRR: Ignoring unknown animator: " ASSIMP_LOG_WARN("IRR: Ignoring unknown animator: "
+ prop.value); + prop.value);
curAnim->type = Animator::UNKNOWN; curAnim->type = Animator::UNKNOWN;
@ -1348,7 +1349,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
// back in the node hierarchy // back in the node hierarchy
if (!curParent) { if (!curParent) {
curParent = root; curParent = root;
DefaultLogger::get()->error("IRR: Too many closing <node> elements"); ASSIMP_LOG_ERROR("IRR: Too many closing <node> elements");
} }
else curParent = curParent->parent; else curParent = curParent->parent;
} }
@ -1369,15 +1370,14 @@ void IRRImporter::InternReadFile( const std::string& pFile,
} }
} }
/* Now iterate through all cameras and compute their final (horizontal) FOV // Now iterate through all cameras and compute their final (horizontal) FOV
*/
for (aiCamera *cam : cameras) { for (aiCamera *cam : cameras) {
// screen aspect could be missing // screen aspect could be missing
if (cam->mAspect) { if (cam->mAspect) {
cam->mHorizontalFOV *= cam->mAspect; cam->mHorizontalFOV *= cam->mAspect;
} else {
ASSIMP_LOG_WARN("IRR: Camera aspect is not given, can't compute horizontal FOV");
} }
else DefaultLogger::get()->warn("IRR: Camera aspect is not given, can't compute horizontal FOV");
} }
batch.LoadAll(); batch.LoadAll();
@ -1472,7 +1472,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
* models from external files * models from external files
*/ */
if (!pScene->mNumMeshes || !pScene->mNumMaterials) { if (!pScene->mNumMeshes || !pScene->mNumMaterials) {
DefaultLogger::get()->warn("IRR: No meshes loaded, setting AI_SCENE_FLAGS_INCOMPLETE"); ASSIMP_LOG_WARN("IRR: No meshes loaded, setting AI_SCENE_FLAGS_INCOMPLETE");
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
} }

View File

@ -175,7 +175,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
if (!ASSIMP_stricmp(reader->getNodeName(),"buffer") && (curMat || curMesh)) { if (!ASSIMP_stricmp(reader->getNodeName(),"buffer") && (curMat || curMesh)) {
// end of previous buffer. A material and a mesh should be there // end of previous buffer. A material and a mesh should be there
if ( !curMat || !curMesh) { if ( !curMat || !curMesh) {
DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material"); ASSIMP_LOG_ERROR("IRRMESH: A buffer must contain a mesh and a material");
releaseMaterial( &curMat ); releaseMaterial( &curMat );
releaseMesh( &curMesh ); releaseMesh( &curMesh );
} else { } else {
@ -197,7 +197,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
if (!ASSIMP_stricmp(reader->getNodeName(),"material")) { if (!ASSIMP_stricmp(reader->getNodeName(),"material")) {
if (curMat) { if (curMat) {
DefaultLogger::get()->warn("IRRMESH: Only one material description per buffer, please"); ASSIMP_LOG_WARN("IRRMESH: Only one material description per buffer, please");
releaseMaterial( &curMat ); releaseMaterial( &curMat );
} }
curMat = ParseMaterial(curMatFlags); curMat = ParseMaterial(curMatFlags);
@ -208,7 +208,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
if (!num) { if (!num) {
// This is possible ... remove the mesh from the list and skip further reading // This is possible ... remove the mesh from the list and skip further reading
DefaultLogger::get()->warn("IRRMESH: Found mesh with zero vertices"); ASSIMP_LOG_WARN("IRRMESH: Found mesh with zero vertices");
releaseMaterial( &curMat ); releaseMaterial( &curMat );
releaseMesh( &curMesh ); releaseMesh( &curMesh );
@ -255,7 +255,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
} }
else if (ASSIMP_stricmp("standard", t)) { else if (ASSIMP_stricmp("standard", t)) {
releaseMaterial( &curMat ); releaseMaterial( &curMat );
DefaultLogger::get()->warn("IRRMESH: Unknown vertex format"); ASSIMP_LOG_WARN("IRRMESH: Unknown vertex format");
} }
else vertexFormat = 0; else vertexFormat = 0;
textMeaning = 1; textMeaning = 1;
@ -275,7 +275,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
curMesh->mNumVertices = reader->getAttributeValueAsInt("indexCount"); curMesh->mNumVertices = reader->getAttributeValueAsInt("indexCount");
if (!curMesh->mNumVertices) { if (!curMesh->mNumVertices) {
// This is possible ... remove the mesh from the list and skip further reading // This is possible ... remove the mesh from the list and skip further reading
DefaultLogger::get()->warn("IRRMESH: Found mesh with zero indices"); ASSIMP_LOG_WARN("IRRMESH: Found mesh with zero indices");
// mesh - away // mesh - away
releaseMesh( &curMesh ); releaseMesh( &curMesh );
@ -288,7 +288,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
} }
if (curMesh->mNumVertices % 3) { if (curMesh->mNumVertices % 3) {
DefaultLogger::get()->warn("IRRMESH: Number if indices isn't divisible by 3"); ASSIMP_LOG_WARN("IRRMESH: Number if indices isn't divisible by 3");
} }
curMesh->mNumFaces = curMesh->mNumVertices / 3; curMesh->mNumFaces = curMesh->mNumVertices / 3;
@ -439,7 +439,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
unsigned int total = 0; unsigned int total = 0;
while(SkipSpacesAndLineEnd(&sz)) { while(SkipSpacesAndLineEnd(&sz)) {
if (curFace >= faceEnd) { if (curFace >= faceEnd) {
DefaultLogger::get()->error("IRRMESH: Too many indices"); ASSIMP_LOG_ERROR("IRRMESH: Too many indices");
break; break;
} }
if (!curIdx) { if (!curIdx) {
@ -449,7 +449,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
unsigned int idx = strtoul10(sz,&sz); unsigned int idx = strtoul10(sz,&sz);
if (idx >= curVertices.size()) { if (idx >= curVertices.size()) {
DefaultLogger::get()->error("IRRMESH: Index out of range"); ASSIMP_LOG_ERROR("IRRMESH: Index out of range");
idx = 0; idx = 0;
} }
@ -470,7 +470,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
} }
if (curFace != faceEnd) if (curFace != faceEnd)
DefaultLogger::get()->error("IRRMESH: Not enough indices"); ASSIMP_LOG_ERROR("IRRMESH: Not enough indices");
// Finish processing the mesh - do some small material workarounds // Finish processing the mesh - do some small material workarounds
if (curMatFlags & AI_IRRMESH_MAT_trans_vertex_alpha && !useColors) { if (curMatFlags & AI_IRRMESH_MAT_trans_vertex_alpha && !useColors) {
@ -492,7 +492,7 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
// End of the last buffer. A material and a mesh should be there // End of the last buffer. A material and a mesh should be there
if (curMat || curMesh) { if (curMat || curMesh) {
if ( !curMat || !curMesh) { if ( !curMat || !curMesh) {
DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material"); ASSIMP_LOG_ERROR("IRRMESH: A buffer must contain a mesh and a material");
releaseMaterial( &curMat ); releaseMaterial( &curMat );
releaseMesh( &curMesh ); releaseMesh( &curMesh );
} }

View File

@ -179,14 +179,14 @@ void IrrlichtBase::ReadVectorProperty (VectorProperty& out)
SkipSpaces(&ptr); SkipSpaces(&ptr);
if (',' != *ptr) if (',' != *ptr)
{ {
DefaultLogger::get()->error("IRR(MESH): Expected comma in vector definition"); ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} }
else SkipSpaces(ptr+1,&ptr); else SkipSpaces(ptr+1,&ptr);
ptr = fast_atoreal_move<float>( ptr,(float&)out.value.y ); ptr = fast_atoreal_move<float>( ptr,(float&)out.value.y );
SkipSpaces(&ptr); SkipSpaces(&ptr);
if (',' != *ptr) if (',' != *ptr)
{ {
DefaultLogger::get()->error("IRR(MESH): Expected comma in vector definition"); ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} }
else SkipSpaces(ptr+1,&ptr); else SkipSpaces(ptr+1,&ptr);
ptr = fast_atoreal_move<float>( ptr,(float&)out.value.z ); ptr = fast_atoreal_move<float>( ptr,(float&)out.value.z );
@ -360,7 +360,7 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
matFlags = AI_IRRMESH_MAT_normalmap_ta; matFlags = AI_IRRMESH_MAT_normalmap_ta;
} }
else { else {
DefaultLogger::get()->warn("IRRMat: Unrecognized material type: " + prop.value); ASSIMP_LOG_WARN("IRRMat: Unrecognized material type: " + prop.value);
} }
} }
@ -391,9 +391,7 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
// set the corresponding material flag // set the corresponding material flag
matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE; matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
} } else if (matFlags & AI_IRRMESH_MAT_solid_2layer) {// or just as second diffuse texture
// or just as second diffuse texture
else if (matFlags & AI_IRRMESH_MAT_solid_2layer) {
++cnt; ++cnt;
s.Set(prop.value); s.Set(prop.value);
mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(1)); mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(1));
@ -401,19 +399,15 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
// set the corresponding material flag // set the corresponding material flag
matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE; matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
} else {
ASSIMP_LOG_WARN("IRRmat: Skipping second texture");
} }
else DefaultLogger::get()->warn("IRRmat: Skipping second texture"); } else if (prop.name == "Texture3" && cnt == 2) {
}
else if (prop.name == "Texture3" && cnt == 2)
{
// Irrlicht does not seem to use these channels. // Irrlicht does not seem to use these channels.
++cnt; ++cnt;
s.Set(prop.value); s.Set(prop.value);
mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(nd+1)); mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(nd+1));
} } else if (prop.name == "Texture4" && cnt == 3) {
else if (prop.name == "Texture4" && cnt == 3)
{
// Irrlicht does not seem to use these channels. // Irrlicht does not seem to use these channels.
++cnt; ++cnt;
s.Set(prop.value); s.Set(prop.value);
@ -499,7 +493,8 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
break; break;
} }
} }
DefaultLogger::get()->error("IRRMESH: Unexpected end of file. Material is not complete"); ASSIMP_LOG_ERROR("IRRMESH: Unexpected end of file. Material is not complete");
return mat; return mat;
} }

View File

@ -91,7 +91,7 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Read a property of the specified type from the current XML element. /** Read a property of the specified type from the current XML element.
* @param out Recives output data * @param out Receives output data
*/ */
void ReadHexProperty (HexProperty& out); void ReadHexProperty (HexProperty& out);
void ReadStringProperty (StringProperty& out); void ReadStringProperty (StringProperty& out);

View File

@ -147,10 +147,7 @@ void AllocateFromAssimpHeap::operator delete[] ( void* data) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Importer constructor. // Importer constructor.
Importer::Importer() Importer::Importer()
: pimpl( NULL ) { : pimpl( new ImporterPimpl ) {
// allocate the pimpl first
pimpl = new ImporterPimpl();
pimpl->mScene = NULL; pimpl->mScene = NULL;
pimpl->mErrorString = ""; pimpl->mErrorString = "";
@ -208,7 +205,7 @@ aiReturn Importer::RegisterPPStep(BaseProcess* pImp)
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
pimpl->mPostProcessingSteps.push_back(pImp); pimpl->mPostProcessingSteps.push_back(pImp);
DefaultLogger::get()->info("Registering custom post-processing step"); ASSIMP_LOG_INFO("Registering custom post-processing step");
ASSIMP_END_EXCEPTION_REGION(aiReturn); ASSIMP_END_EXCEPTION_REGION(aiReturn);
return AI_SUCCESS; return AI_SUCCESS;
@ -235,7 +232,7 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp)
#ifdef ASSIMP_BUILD_DEBUG #ifdef ASSIMP_BUILD_DEBUG
if (IsExtensionSupported(*it)) { if (IsExtensionSupported(*it)) {
DefaultLogger::get()->warn("The file extension " + *it + " is already in use"); ASSIMP_LOG_WARN_F("The file extension ", *it, " is already in use");
} }
#endif #endif
baked += *it; baked += *it;
@ -243,7 +240,7 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp)
// add the loader // add the loader
pimpl->mImporter.push_back(pImp); pimpl->mImporter.push_back(pImp);
DefaultLogger::get()->info("Registering custom importer for these file extensions: " + baked); ASSIMP_LOG_INFO_F("Registering custom importer for these file extensions: ", baked);
ASSIMP_END_EXCEPTION_REGION(aiReturn); ASSIMP_END_EXCEPTION_REGION(aiReturn);
return AI_SUCCESS; return AI_SUCCESS;
} }
@ -263,10 +260,10 @@ aiReturn Importer::UnregisterLoader(BaseImporter* pImp)
if (it != pimpl->mImporter.end()) { if (it != pimpl->mImporter.end()) {
pimpl->mImporter.erase(it); pimpl->mImporter.erase(it);
DefaultLogger::get()->info("Unregistering custom importer: "); ASSIMP_LOG_INFO("Unregistering custom importer: ");
return AI_SUCCESS; return AI_SUCCESS;
} }
DefaultLogger::get()->warn("Unable to remove custom importer: I can't find you ..."); ASSIMP_LOG_WARN("Unable to remove custom importer: I can't find you ...");
ASSIMP_END_EXCEPTION_REGION(aiReturn); ASSIMP_END_EXCEPTION_REGION(aiReturn);
return AI_FAILURE; return AI_FAILURE;
} }
@ -286,10 +283,10 @@ aiReturn Importer::UnregisterPPStep(BaseProcess* pImp)
if (it != pimpl->mPostProcessingSteps.end()) { if (it != pimpl->mPostProcessingSteps.end()) {
pimpl->mPostProcessingSteps.erase(it); pimpl->mPostProcessingSteps.erase(it);
DefaultLogger::get()->info("Unregistering custom post-processing step"); ASSIMP_LOG_INFO("Unregistering custom post-processing step");
return AI_SUCCESS; return AI_SUCCESS;
} }
DefaultLogger::get()->warn("Unable to remove custom post-processing step: I can't find you .."); ASSIMP_LOG_WARN("Unable to remove custom post-processing step: I can't find you ..");
ASSIMP_END_EXCEPTION_REGION(aiReturn); ASSIMP_END_EXCEPTION_REGION(aiReturn);
return AI_FAILURE; return AI_FAILURE;
} }
@ -371,11 +368,11 @@ bool Importer::IsDefaultProgressHandler() const
bool _ValidateFlags(unsigned int pFlags) bool _ValidateFlags(unsigned int pFlags)
{ {
if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals) { if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals) {
DefaultLogger::get()->error("#aiProcess_GenSmoothNormals and #aiProcess_GenNormals are incompatible"); ASSIMP_LOG_ERROR("#aiProcess_GenSmoothNormals and #aiProcess_GenNormals are incompatible");
return false; return false;
} }
if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices) { if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices) {
DefaultLogger::get()->error("#aiProcess_OptimizeGraph and #aiProcess_PreTransformVertices are incompatible"); ASSIMP_LOG_ERROR("#aiProcess_OptimizeGraph and #aiProcess_PreTransformVertices are incompatible");
return false; return false;
} }
return true; return true;
@ -507,26 +504,15 @@ const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void WriteLogOpening(const std::string& file) void WriteLogOpening(const std::string& file)
{ {
Logger* l = DefaultLogger::get(); ASSIMP_LOG_INFO_F("Load ", file);
if (!l) {
return;
}
l->info("Load " + file);
// print a full version dump. This is nice because we don't // print a full version dump. This is nice because we don't
// need to ask the authors of incoming bug reports for // need to ask the authors of incoming bug reports for
// the library version they're using - a log dump is // the library version they're using - a log dump is
// sufficient. // sufficient.
const unsigned int flags = aiGetCompileFlags(); const unsigned int flags( aiGetCompileFlags() );
l->debug(format() std::stringstream stream;
<< "Assimp " stream << "Assimp " << aiGetVersionMajor() << "." << aiGetVersionMinor() << "." << aiGetVersionRevision() << " "
<< aiGetVersionMajor()
<< "."
<< aiGetVersionMinor()
<< "."
<< aiGetVersionRevision()
<< " "
#if defined(ASSIMP_BUILD_ARCHITECTURE) #if defined(ASSIMP_BUILD_ARCHITECTURE)
<< ASSIMP_BUILD_ARCHITECTURE << ASSIMP_BUILD_ARCHITECTURE
#elif defined(_M_IX86) || defined(__x86_32__) || defined(__i386__) #elif defined(_M_IX86) || defined(__x86_32__) || defined(__i386__)
@ -544,10 +530,9 @@ void WriteLogOpening(const std::string& file)
#else #else
<< "<unknown architecture>" << "<unknown architecture>"
#endif #endif
<< " " << " "
#if defined(ASSIMP_BUILD_COMPILER) #if defined(ASSIMP_BUILD_COMPILER)
<< ASSIMP_BUILD_COMPILER << ( ASSIMP_BUILD_COMPILER )
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
<< "msvc" << "msvc"
#elif defined(__GNUC__) #elif defined(__GNUC__)
@ -562,8 +547,9 @@ void WriteLogOpening(const std::string& file)
<< (flags & ASSIMP_CFLAGS_NOBOOST ? " noboost" : "") << (flags & ASSIMP_CFLAGS_NOBOOST ? " noboost" : "")
<< (flags & ASSIMP_CFLAGS_SHARED ? " shared" : "") << (flags & ASSIMP_CFLAGS_SHARED ? " shared" : "")
<< (flags & ASSIMP_CFLAGS_SINGLETHREADED ? " singlethreaded" : "") << (flags & ASSIMP_CFLAGS_SINGLETHREADED ? " singlethreaded" : "");
);
ASSIMP_LOG_DEBUG(stream.str());
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -589,7 +575,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
// a scene. In this case we need to delete the old one // a scene. In this case we need to delete the old one
if (pimpl->mScene) { if (pimpl->mScene) {
DefaultLogger::get()->debug("(Deleting previous scene)"); ASSIMP_LOG_DEBUG("(Deleting previous scene)");
FreeScene(); FreeScene();
} }
@ -597,7 +583,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
if( !pimpl->mIOHandler->Exists( pFile)) { if( !pimpl->mIOHandler->Exists( pFile)) {
pimpl->mErrorString = "Unable to open file \"" + pFile + "\"."; pimpl->mErrorString = "Unable to open file \"" + pFile + "\".";
DefaultLogger::get()->error(pimpl->mErrorString); ASSIMP_LOG_ERROR(pimpl->mErrorString);
return NULL; return NULL;
} }
@ -620,9 +606,8 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
// not so bad yet ... try format auto detection. // not so bad yet ... try format auto detection.
const std::string::size_type s = pFile.find_last_of('.'); const std::string::size_type s = pFile.find_last_of('.');
if (s != std::string::npos) { if (s != std::string::npos) {
DefaultLogger::get()->info("File extension not known, trying signature-based detection"); ASSIMP_LOG_INFO("File extension not known, trying signature-based detection");
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) { if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
imp = pimpl->mImporter[a]; imp = pimpl->mImporter[a];
break; break;
@ -632,7 +617,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
// Put a proper error message if no suitable importer was found // Put a proper error message if no suitable importer was found
if( !imp) { if( !imp) {
pimpl->mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\"."; pimpl->mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\".";
DefaultLogger::get()->error(pimpl->mErrorString); ASSIMP_LOG_ERROR(pimpl->mErrorString);
return NULL; return NULL;
} }
} }
@ -652,7 +637,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
if ( NULL != desc ) { if ( NULL != desc ) {
ext = desc->mName; ext = desc->mName;
} }
DefaultLogger::get()->info("Found a matching importer for this file format: " + ext + "." ); ASSIMP_LOG_INFO("Found a matching importer for this file format: " + ext + "." );
pimpl->mProgressHandler->UpdateFileRead( 0, fileSize ); pimpl->mProgressHandler->UpdateFileRead( 0, fileSize );
if (profiler) { if (profiler) {
@ -720,7 +705,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
pimpl->mErrorString = std::string("std::exception: ") + e.what(); pimpl->mErrorString = std::string("std::exception: ") + e.what();
#endif #endif
DefaultLogger::get()->error(pimpl->mErrorString); ASSIMP_LOG_ERROR(pimpl->mErrorString);
delete pimpl->mScene; pimpl->mScene = NULL; delete pimpl->mScene; pimpl->mScene = NULL;
} }
#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS #endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
@ -748,7 +733,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
// In debug builds: run basic flag validation // In debug builds: run basic flag validation
ai_assert(_ValidateFlags(pFlags)); ai_assert(_ValidateFlags(pFlags));
DefaultLogger::get()->info("Entering post processing pipeline"); ASSIMP_LOG_INFO("Entering post processing pipeline");
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS #ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
// The ValidateDS process plays an exceptional role. It isn't contained in the global // The ValidateDS process plays an exceptional role. It isn't contained in the global
@ -766,13 +751,13 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
if (pimpl->bExtraVerbose) if (pimpl->bExtraVerbose)
{ {
#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS #ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
DefaultLogger::get()->error("Verbose Import is not available due to build settings"); ASSIMP_LOG_ERROR("Verbose Import is not available due to build settings");
#endif // no validation #endif // no validation
pFlags |= aiProcess_ValidateDataStructure; pFlags |= aiProcess_ValidateDataStructure;
} }
#else #else
if (pimpl->bExtraVerbose) { if (pimpl->bExtraVerbose) {
DefaultLogger::get()->warn("Not a debug build, ignoring extra verbose setting"); ASSIMP_LOG_WARN("Not a debug build, ignoring extra verbose setting");
} }
#endif // ! DEBUG #endif // ! DEBUG
@ -804,18 +789,19 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
// If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step
if (pimpl->bExtraVerbose) { if (pimpl->bExtraVerbose) {
DefaultLogger::get()->debug("Verbose Import: revalidating data structures"); ASSIMP_LOG_DEBUG("Verbose Import: re-validating data structures");
ValidateDSProcess ds; ValidateDSProcess ds;
ds.ExecuteOnScene (this); ds.ExecuteOnScene (this);
if( !pimpl->mScene) { if( !pimpl->mScene) {
DefaultLogger::get()->error("Verbose Import: failed to revalidate data structures"); ASSIMP_LOG_ERROR("Verbose Import: failed to re-validate data structures");
break; break;
} }
} }
#endif // ! DEBUG #endif // ! DEBUG
} }
pimpl->mProgressHandler->UpdatePostProcess( static_cast<int>(pimpl->mPostProcessingSteps.size()), static_cast<int>(pimpl->mPostProcessingSteps.size()) ); pimpl->mProgressHandler->UpdatePostProcess( static_cast<int>(pimpl->mPostProcessingSteps.size()),
static_cast<int>(pimpl->mPostProcessingSteps.size()) );
// update private scene flags // update private scene flags
if( pimpl->mScene ) if( pimpl->mScene )
@ -823,7 +809,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
// clear any data allocated by post-process steps // clear any data allocated by post-process steps
pimpl->mPPShared->Clean(); pimpl->mPPShared->Clean();
DefaultLogger::get()->info("Leaving post processing pipeline"); ASSIMP_LOG_INFO("Leaving post processing pipeline");
ASSIMP_END_EXCEPTION_REGION(const aiScene*); ASSIMP_END_EXCEPTION_REGION(const aiScene*);
return pimpl->mScene; return pimpl->mScene;
@ -844,7 +830,7 @@ const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess
} }
// In debug builds: run basic flag validation // In debug builds: run basic flag validation
DefaultLogger::get()->info( "Entering customized post processing pipeline" ); ASSIMP_LOG_INFO( "Entering customized post processing pipeline" );
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS #ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
// The ValidateDS process plays an exceptional role. It isn't contained in the global // The ValidateDS process plays an exceptional role. It isn't contained in the global
@ -862,12 +848,12 @@ const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess
if ( pimpl->bExtraVerbose ) if ( pimpl->bExtraVerbose )
{ {
#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS #ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
DefaultLogger::get()->error( "Verbose Import is not available due to build settings" ); ASSIMP_LOG_ERROR( "Verbose Import is not available due to build settings" );
#endif // no validation #endif // no validation
} }
#else #else
if ( pimpl->bExtraVerbose ) { if ( pimpl->bExtraVerbose ) {
DefaultLogger::get()->warn( "Not a debug build, ignoring extra verbose setting" ); ASSIMP_LOG_WARN( "Not a debug build, ignoring extra verbose setting" );
} }
#endif // ! DEBUG #endif // ! DEBUG
@ -885,18 +871,18 @@ const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess
// If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step
if ( pimpl->bExtraVerbose || requestValidation ) { if ( pimpl->bExtraVerbose || requestValidation ) {
DefaultLogger::get()->debug( "Verbose Import: revalidating data structures" ); ASSIMP_LOG_DEBUG( "Verbose Import: revalidating data structures" );
ValidateDSProcess ds; ValidateDSProcess ds;
ds.ExecuteOnScene( this ); ds.ExecuteOnScene( this );
if ( !pimpl->mScene ) { if ( !pimpl->mScene ) {
DefaultLogger::get()->error( "Verbose Import: failed to revalidate data structures" ); ASSIMP_LOG_ERROR( "Verbose Import: failed to revalidate data structures" );
} }
} }
// clear any data allocated by post-process steps // clear any data allocated by post-process steps
pimpl->mPPShared->Clean(); pimpl->mPPShared->Clean();
DefaultLogger::get()->info( "Leaving customized post processing pipeline" ); ASSIMP_LOG_INFO( "Leaving customized post processing pipeline" );
ASSIMP_END_EXCEPTION_REGION( const aiScene* ); ASSIMP_END_EXCEPTION_REGION( const aiScene* );
@ -907,7 +893,7 @@ const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess
// Helper function to check whether an extension is supported by ASSIMP // Helper function to check whether an extension is supported by ASSIMP
bool Importer::IsExtensionSupported(const char* szExtension) const bool Importer::IsExtensionSupported(const char* szExtension) const
{ {
return NULL != GetImporter(szExtension); return nullptr != GetImporter(szExtension);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -947,6 +933,7 @@ BaseImporter* Importer::GetImporter (const char* szExtension) const
size_t Importer::GetImporterIndex (const char* szExtension) const size_t Importer::GetImporterIndex (const char* szExtension) const
{ {
ai_assert(szExtension); ai_assert(szExtension);
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
// skip over wildcard and dot characters at string head -- // skip over wildcard and dot characters at string head --
@ -983,6 +970,8 @@ void Importer::GetExtensionList(aiString& szOut) const
(*i)->GetExtensionList(str); (*i)->GetExtensionList(str);
} }
// List can be empty
if( !str.empty() ) {
for (std::set<std::string>::const_iterator it = str.begin();; ) { for (std::set<std::string>::const_iterator it = str.begin();; ) {
szOut.Append("*."); szOut.Append("*.");
szOut.Append((*it).c_str()); szOut.Append((*it).c_str());
@ -992,6 +981,7 @@ void Importer::GetExtensionList(aiString& szOut) const
} }
szOut.Append(";"); szOut.Append(";");
} }
}
ASSIMP_END_EXCEPTION_REGION(void); ASSIMP_END_EXCEPTION_REGION(void);
} }
@ -1010,33 +1000,33 @@ bool Importer::SetPropertyInteger(const char* szName, int iValue)
// Set a configuration property // Set a configuration property
bool Importer::SetPropertyFloat(const char* szName, ai_real iValue) bool Importer::SetPropertyFloat(const char* szName, ai_real iValue)
{ {
bool exising; bool existing;
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
exising = SetGenericProperty<ai_real>(pimpl->mFloatProperties, szName,iValue); existing = SetGenericProperty<ai_real>(pimpl->mFloatProperties, szName,iValue);
ASSIMP_END_EXCEPTION_REGION(bool); ASSIMP_END_EXCEPTION_REGION(bool);
return exising; return existing;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Set a configuration property // Set a configuration property
bool Importer::SetPropertyString(const char* szName, const std::string& value) bool Importer::SetPropertyString(const char* szName, const std::string& value)
{ {
bool exising; bool existing;
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
exising = SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value); existing = SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value);
ASSIMP_END_EXCEPTION_REGION(bool); ASSIMP_END_EXCEPTION_REGION(bool);
return exising; return existing;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Set a configuration property // Set a configuration property
bool Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value) bool Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value)
{ {
bool exising; bool existing;
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
exising = SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value); existing = SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value);
ASSIMP_END_EXCEPTION_REGION(bool); ASSIMP_END_EXCEPTION_REGION(bool);
return exising; return existing;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -68,10 +68,8 @@ namespace Assimp {
* std::vector and std::map in the public headers. Furthermore we are dropping * std::vector and std::map in the public headers. Furthermore we are dropping
* any STL interface problems caused by mismatching STL settings. All * any STL interface problems caused by mismatching STL settings. All
* size calculation are now done by us, not the app heap. */ * size calculation are now done by us, not the app heap. */
class ImporterPimpl class ImporterPimpl {
{
public: public:
// Data type to store the key hash // Data type to store the key hash
typedef unsigned int KeyType; typedef unsigned int KeyType;
@ -82,8 +80,6 @@ public:
typedef std::map<KeyType, std::string> StringPropertyMap; typedef std::map<KeyType, std::string> StringPropertyMap;
typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap; typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
public:
/** IO handler to use for all file accesses. */ /** IO handler to use for all file accesses. */
IOSystem* mIOHandler; IOSystem* mIOHandler;
bool mIsDefaultHandler; bool mIsDefaultHandler;
@ -117,12 +113,34 @@ public:
MatrixPropertyMap mMatrixProperties; MatrixPropertyMap mMatrixProperties;
/** Used for testing - extra verbose mode causes the ValidateDataStructure-Step /** Used for testing - extra verbose mode causes the ValidateDataStructure-Step
* to be executed before and after every single postprocess step */ * to be executed before and after every single post-process step */
bool bExtraVerbose; bool bExtraVerbose;
/** Used by post-process steps to share data */ /** Used by post-process steps to share data */
SharedPostProcessInfo* mPPShared; SharedPostProcessInfo* mPPShared;
/// The default class constructor.
ImporterPimpl();
}; };
inline
ImporterPimpl::ImporterPimpl()
: mIOHandler( nullptr )
, mIsDefaultHandler( false )
, mProgressHandler( nullptr )
, mIsDefaultProgressHandler( false )
, mImporter()
, mPostProcessingSteps()
, mScene( nullptr )
, mErrorString()
, mIntProperties()
, mFloatProperties()
, mStringProperties()
, mMatrixProperties()
, bExtraVerbose( false )
, mPPShared( nullptr ) {
// empty
}
//! @endcond //! @endcond

View File

@ -728,7 +728,7 @@ void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept, TempMesh&
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned int matid, std::vector<unsigned int>& mesh_indices, bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned int matid, std::set<unsigned int>& mesh_indices,
ConversionData& conv) ConversionData& conv)
{ {
bool fix_orientation = false; bool fix_orientation = false;
@ -810,7 +810,7 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
aiMesh* const mesh = meshtmp->ToMesh(); aiMesh* const mesh = meshtmp->ToMesh();
if(mesh) { if(mesh) {
mesh->mMaterialIndex = matid; mesh->mMaterialIndex = matid;
mesh_indices.push_back(static_cast<unsigned int>(conv.meshes.size())); mesh_indices.insert(static_cast<unsigned int>(conv.meshes.size()));
conv.meshes.push_back(mesh); conv.meshes.push_back(mesh);
return true; return true;
} }
@ -818,33 +818,31 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd, void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd,
ConversionData& /*conv*/) ConversionData& /*conv*/)
{ {
if (!mesh_indices.empty()) { if (!mesh_indices.empty()) {
std::set<unsigned int>::const_iterator it = mesh_indices.cbegin();
std::set<unsigned int>::const_iterator end = mesh_indices.cend();
// make unique nd->mNumMeshes = static_cast<unsigned int>(mesh_indices.size());
std::sort(mesh_indices.begin(),mesh_indices.end());
std::vector<unsigned int>::iterator it_end = std::unique(mesh_indices.begin(),mesh_indices.end());
nd->mNumMeshes = static_cast<unsigned int>(std::distance(mesh_indices.begin(),it_end));
nd->mMeshes = new unsigned int[nd->mNumMeshes]; nd->mMeshes = new unsigned int[nd->mNumMeshes];
for(unsigned int i = 0; i < nd->mNumMeshes; ++i) { for(unsigned int i = 0; it != end && i < nd->mNumMeshes; ++i, ++it) {
nd->mMeshes[i] = mesh_indices[i]; nd->mMeshes[i] = *it;
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item, bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item,
std::vector<unsigned int>& mesh_indices, unsigned int mat_index, std::set<unsigned int>& mesh_indices, unsigned int mat_index,
ConversionData& conv) ConversionData& conv)
{ {
ConversionData::MeshCacheIndex idx(&item, mat_index); ConversionData::MeshCacheIndex idx(&item, mat_index);
ConversionData::MeshCache::const_iterator it = conv.cached_meshes.find(idx); ConversionData::MeshCache::const_iterator it = conv.cached_meshes.find(idx);
if (it != conv.cached_meshes.end()) { if (it != conv.cached_meshes.end()) {
std::copy((*it).second.begin(),(*it).second.end(),std::back_inserter(mesh_indices)); std::copy((*it).second.begin(),(*it).second.end(),std::inserter(mesh_indices, mesh_indices.end()));
return true; return true;
} }
return false; return false;
@ -852,7 +850,7 @@ bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void PopulateMeshCache(const Schema_2x3::IfcRepresentationItem& item, void PopulateMeshCache(const Schema_2x3::IfcRepresentationItem& item,
const std::vector<unsigned int>& mesh_indices, unsigned int mat_index, const std::set<unsigned int>& mesh_indices, unsigned int mat_index,
ConversionData& conv) ConversionData& conv)
{ {
ConversionData::MeshCacheIndex idx(&item, mat_index); ConversionData::MeshCacheIndex idx(&item, mat_index);
@ -861,7 +859,7 @@ void PopulateMeshCache(const Schema_2x3::IfcRepresentationItem& item,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, unsigned int matid, bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, unsigned int matid,
std::vector<unsigned int>& mesh_indices, std::set<unsigned int>& mesh_indices,
ConversionData& conv) ConversionData& conv)
{ {
// determine material // determine material

View File

@ -435,7 +435,7 @@ bool ProcessMappedItem(const Schema_2x3::IfcMappedItem& mapped, aiNode* nd_src,
msrc = m*msrc; msrc = m*msrc;
std::vector<unsigned int> meshes; std::set<unsigned int> meshes;
const size_t old_openings = conv.collect_openings ? conv.collect_openings->size() : 0; const size_t old_openings = conv.collect_openings ? conv.collect_openings->size() : 0;
if (conv.apply_openings) { if (conv.apply_openings) {
IfcMatrix4 minv = msrc; IfcMatrix4 minv = msrc;
@ -550,7 +550,7 @@ void ProcessProductRepresentation(const Schema_2x3::IfcProduct& el, aiNode* nd,
// extract Color from metadata, if present // extract Color from metadata, if present
unsigned int matid = ProcessMaterials( el.GetID(), std::numeric_limits<uint32_t>::max(), conv, false); unsigned int matid = ProcessMaterials( el.GetID(), std::numeric_limits<uint32_t>::max(), conv, false);
std::vector<unsigned int> meshes; std::set<unsigned int> meshes;
// we want only one representation type, so bring them in a suitable order (i.e try those // we want only one representation type, so bring them in a suitable order (i.e try those
// that look as if we could read them quickly at first). This way of reading // that look as if we could read them quickly at first). This way of reading
@ -584,8 +584,7 @@ typedef std::map<std::string, std::string> Metadata;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessMetadata(const Schema_2x3::ListOf< Schema_2x3::Lazy< Schema_2x3::IfcProperty >, 1, 0 >& set, ConversionData& conv, Metadata& properties, void ProcessMetadata(const Schema_2x3::ListOf< Schema_2x3::Lazy< Schema_2x3::IfcProperty >, 1, 0 >& set, ConversionData& conv, Metadata& properties,
const std::string& prefix = "", const std::string& prefix = "",
unsigned int nest = 0) unsigned int nest = 0) {
{
for(const Schema_2x3::IfcProperty& property : set) { for(const Schema_2x3::IfcProperty& property : set) {
const std::string& key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name; const std::string& key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name;
if (const Schema_2x3::IfcPropertySingleValue* const singleValue = property.ToPtr<Schema_2x3::IfcPropertySingleValue>()) { if (const Schema_2x3::IfcPropertySingleValue* const singleValue = property.ToPtr<Schema_2x3::IfcPropertySingleValue>()) {

View File

@ -317,7 +317,7 @@ void TempMesh::FixupFaceOrientation()
IfcVector3 farthestCenter = std::accumulate(mVerts.begin() + faceStartIndices[farthestIndex], IfcVector3 farthestCenter = std::accumulate(mVerts.begin() + faceStartIndices[farthestIndex],
mVerts.begin() + faceStartIndices[farthestIndex] + mVertcnt[farthestIndex], IfcVector3(0.0)) mVerts.begin() + faceStartIndices[farthestIndex] + mVertcnt[farthestIndex], IfcVector3(0.0))
/ IfcFloat(mVertcnt[farthestIndex]); / IfcFloat(mVertcnt[farthestIndex]);
// We accapt a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in // We accept a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in
// the file. // the file.
if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 ) if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 )
{ {

View File

@ -205,7 +205,7 @@ struct ConversionData
bool operator == (const MeshCacheIndex& o) const { return item == o.item && matindex == o.matindex; } bool operator == (const MeshCacheIndex& o) const { return item == o.item && matindex == o.matindex; }
bool operator < (const MeshCacheIndex& o) const { return item < o.item || (item == o.item && matindex < o.matindex); } bool operator < (const MeshCacheIndex& o) const { return item < o.item || (item == o.item && matindex < o.matindex); }
}; };
typedef std::map<MeshCacheIndex, std::vector<unsigned int> > MeshCache; typedef std::map<MeshCacheIndex, std::set<unsigned int> > MeshCache;
MeshCache cached_meshes; MeshCache cached_meshes;
typedef std::map<const IFC::Schema_2x3::IfcSurfaceStyle*, unsigned int> MaterialCache; typedef std::map<const IFC::Schema_2x3::IfcSurfaceStyle*, unsigned int> MaterialCache;
@ -281,8 +281,8 @@ unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionDat
// IFCGeometry.cpp // IFCGeometry.cpp
IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut); IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut);
bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, unsigned int matid, std::vector<unsigned int>& mesh_indices, ConversionData& conv); bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, unsigned int matid, std::set<unsigned int>& mesh_indices, ConversionData& conv);
void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,ConversionData& /*conv*/); void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd,ConversionData& /*conv*/);
void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept, TempMesh& meshout, void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept, TempMesh& meshout,
ConversionData& conv); ConversionData& conv);

View File

@ -126,7 +126,7 @@ STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream)
// XXX need support for multiple schemas? // XXX need support for multiple schemas?
if (list->GetSize() > 1) { if (list->GetSize() > 1) {
DefaultLogger::get()->warn(AddLineNumber("multiple schemas currently not supported",line)); ASSIMP_LOG_WARN(AddLineNumber("multiple schemas currently not supported",line));
} }
const EXPRESS::STRING* string( nullptr ); const EXPRESS::STRING* string( nullptr );
if (!list->GetSize() || !(string=dynamic_cast<const EXPRESS::STRING*>( (*list)[0].get() ))) { if (!list->GetSize() || !(string=dynamic_cast<const EXPRESS::STRING*>( (*list)[0].get() ))) {
@ -192,7 +192,7 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
// LineSplitter already ignores empty lines // LineSplitter already ignores empty lines
ai_assert(s.length()); ai_assert(s.length());
if (s[0] != '#') { if (s[0] != '#') {
DefaultLogger::get()->warn(AddLineNumber("expected token \'#\'",line)); ASSIMP_LOG_WARN(AddLineNumber("expected token \'#\'",line));
++splitter; ++splitter;
continue; continue;
} }
@ -202,14 +202,14 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
// --- // ---
const std::string::size_type n0 = s.find_first_of('='); const std::string::size_type n0 = s.find_first_of('=');
if (n0 == std::string::npos) { if (n0 == std::string::npos) {
DefaultLogger::get()->warn(AddLineNumber("expected token \'=\'",line)); ASSIMP_LOG_WARN(AddLineNumber("expected token \'=\'",line));
++splitter; ++splitter;
continue; continue;
} }
const uint64_t id = strtoul10_64(s.substr(1,n0-1).c_str()); const uint64_t id = strtoul10_64(s.substr(1,n0-1).c_str());
if (!id) { if (!id) {
DefaultLogger::get()->warn(AddLineNumber("expected positive, numeric entity id",line)); ASSIMP_LOG_WARN(AddLineNumber("expected positive, numeric entity id",line));
++splitter; ++splitter;
continue; continue;
} }
@ -236,7 +236,7 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
} }
if(!ok) { if(!ok) {
DefaultLogger::get()->warn(AddLineNumber("expected token \'(\'",line)); ASSIMP_LOG_WARN(AddLineNumber("expected token \'(\'",line));
continue; continue;
} }
} }
@ -263,13 +263,13 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
} }
} }
if(!ok) { if(!ok) {
DefaultLogger::get()->warn(AddLineNumber("expected token \')\'",line)); ASSIMP_LOG_WARN(AddLineNumber("expected token \')\'",line));
continue; continue;
} }
} }
if (map.find(id) != map.end()) { if (map.find(id) != map.end()) {
DefaultLogger::get()->warn(AddLineNumber((Formatter::format(),"an object with the id #",id," already exists"),line)); ASSIMP_LOG_WARN(AddLineNumber((Formatter::format(),"an object with the id #",id," already exists"),line));
} }
std::string::size_type ns = n0; std::string::size_type ns = n0;
@ -292,11 +292,11 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
} }
if (!splitter) { if (!splitter) {
DefaultLogger::get()->warn("STEP: ignoring unexpected EOF"); ASSIMP_LOG_WARN("STEP: ignoring unexpected EOF");
} }
if ( !DefaultLogger::isNullLogger()){ if ( !DefaultLogger::isNullLogger()){
DefaultLogger::get()->debug((Formatter::format(),"STEP: got ",map.size()," object records with ", ASSIMP_LOG_DEBUG((Formatter::format(),"STEP: got ",map.size()," object records with ",
db.GetRefs().size()," inverse index entries")); db.GetRefs().size()," inverse index entries"));
} }
} }
@ -392,7 +392,7 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
std::string stemp = std::string(start, static_cast<size_t>(cur - start)); std::string stemp = std::string(start, static_cast<size_t>(cur - start));
if(!StringToUTF8(stemp)) { if(!StringToUTF8(stemp)) {
// TODO: route this to a correct logger with line numbers etc., better error messages // TODO: route this to a correct logger with line numbers etc., better error messages
DefaultLogger::get()->error("an error occurred reading escape sequences in ASCII text"); ASSIMP_LOG_ERROR("an error occurred reading escape sequences in ASCII text");
} }
return std::make_shared<EXPRESS::STRING>(stemp); return std::make_shared<EXPRESS::STRING>(stemp);
@ -493,10 +493,17 @@ STEP::LazyObject::LazyObject(DB& db, uint64_t id,uint64_t /*line*/, const char*
} }
if (skip_depth >= 1 && *a=='#') { if (skip_depth >= 1 && *a=='#') {
if (*(a + 1) != '#')
{
const char* tmp; const char* tmp;
const int64_t num = static_cast<int64_t>(strtoul10_64(a + 1, &tmp)); const int64_t num = static_cast<int64_t>(strtoul10_64(a + 1, &tmp));
db.MarkRef(num, id); db.MarkRef(num, id);
} }
else
{
++a;
}
}
++a; ++a;
} }

View File

@ -95,11 +95,11 @@ void ImproveCacheLocalityProcess::SetupProperties(const Importer* pImp)
void ImproveCacheLocalityProcess::Execute( aiScene* pScene) void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
{ {
if (!pScene->mNumMeshes) { if (!pScene->mNumMeshes) {
DefaultLogger::get()->debug("ImproveCacheLocalityProcess skipped; there are no meshes"); ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess skipped; there are no meshes");
return; return;
} }
DefaultLogger::get()->debug("ImproveCacheLocalityProcess begin"); ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess begin");
float out = 0.f; float out = 0.f;
unsigned int numf = 0, numm = 0; unsigned int numf = 0, numm = 0;
@ -112,12 +112,8 @@ void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
} }
} }
if (!DefaultLogger::isNullLogger()) { if (!DefaultLogger::isNullLogger()) {
char szBuff[128]; // should be sufficiently large in every case ASSIMP_LOG_INFO_F("Cache relevant are ", numm, " meshes (", numf," faces). Average output ACMR is ", out / numf );
ai_snprintf(szBuff,128,"Cache relevant are %u meshes (%u faces). Average output ACMR is %f", ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess finished. ");
numm,numf,out/numf);
DefaultLogger::get()->info(szBuff);
DefaultLogger::get()->debug("ImproveCacheLocalityProcess finished. ");
} }
} }
@ -135,7 +131,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
return 0.f; return 0.f;
if (pMesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) { if (pMesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) {
DefaultLogger::get()->error("This algorithm works on triangle meshes only"); ASSIMP_LOG_ERROR("This algorithm works on triangle meshes only");
return 0.f; return 0.f;
} }
@ -186,7 +182,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
// mesh, otherwise this value would normally be at least minimally // mesh, otherwise this value would normally be at least minimally
// smaller than 3.0 ... // smaller than 3.0 ...
ai_snprintf(szBuff,128,"Mesh %u: Not suitable for vcache optimization",meshNum); ai_snprintf(szBuff,128,"Mesh %u: Not suitable for vcache optimization",meshNum);
DefaultLogger::get()->warn(szBuff); ASSIMP_LOG_WARN(szBuff);
return 0.f; return 0.f;
} }
} }
@ -276,8 +272,9 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
// so iterate through all vertices of the current triangle // so iterate through all vertices of the current triangle
const aiFace* pcFace = &pMesh->mFaces[ fidx ]; const aiFace* pcFace = &pMesh->mFaces[ fidx ];
for (unsigned int* p = pcFace->mIndices, *p2 = pcFace->mIndices+3;p != p2;++p) { unsigned nind = pcFace->mNumIndices;
const unsigned int dp = *p; for (unsigned ind = 0; ind < nind; ind++) {
unsigned dp = pcFace->mIndices[ind];
// the current vertex won't have any free triangles after this step // the current vertex won't have any free triangles after this step
if (ivdx != (int)dp) { if (ivdx != (int)dp) {
@ -363,11 +360,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
// very intense verbose logging ... prepare for much text if there are many meshes // very intense verbose logging ... prepare for much text if there are many meshes
if ( DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) { if ( DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
char szBuff[128]; // should be sufficiently large in every case ASSIMP_LOG_DEBUG_F("Mesh %u | ACMR in: ", meshNum, " out: ", fACMR, " | ~", fACMR2, ((fACMR - fACMR2) / fACMR) * 100.f);
ai_snprintf(szBuff,128,"Mesh %u | ACMR in: %f out: %f | ~%.1f%%",meshNum,fACMR,fACMR2,
((fACMR - fACMR2) / fACMR) * 100.f);
DefaultLogger::get()->debug(szBuff);
} }
fACMR2 *= pMesh->mNumFaces; fACMR2 *= pMesh->mNumFaces;
@ -375,9 +368,11 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
// sort the output index buffer back to the input array // sort the output index buffer back to the input array
piCSIter = piIBOutput; piCSIter = piIBOutput;
for (aiFace* pcFace = pMesh->mFaces; pcFace != pcEnd;++pcFace) { for (aiFace* pcFace = pMesh->mFaces; pcFace != pcEnd;++pcFace) {
pcFace->mIndices[0] = *piCSIter++; unsigned nind = pcFace->mNumIndices;
pcFace->mIndices[1] = *piCSIter++; unsigned * ind = pcFace->mIndices;
pcFace->mIndices[2] = *piCSIter++; if (nind > 0) ind[0] = *piCSIter++;
if (nind > 1) ind[1] = *piCSIter++;
if (nind > 2) ind[2] = *piCSIter++;
} }
// delete temporary storage // delete temporary storage

View File

@ -79,7 +79,7 @@ bool JoinVerticesProcess::IsActive( unsigned int pFlags) const
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void JoinVerticesProcess::Execute( aiScene* pScene) void JoinVerticesProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("JoinVerticesProcess begin"); ASSIMP_LOG_DEBUG("JoinVerticesProcess begin");
// get the total number of vertices BEFORE the step is executed // get the total number of vertices BEFORE the step is executed
int iNumOldVertices = 0; int iNumOldVertices = 0;
@ -95,198 +95,71 @@ void JoinVerticesProcess::Execute( aiScene* pScene)
iNumVertices += ProcessMesh( pScene->mMeshes[a],a); iNumVertices += ProcessMesh( pScene->mMeshes[a],a);
// if logging is active, print detailed statistics // if logging is active, print detailed statistics
if (!DefaultLogger::isNullLogger()) if (!DefaultLogger::isNullLogger()) {
{ if (iNumOldVertices == iNumVertices) {
if (iNumOldVertices == iNumVertices) ASSIMP_LOG_DEBUG("JoinVerticesProcess finished ");
{ } else {
DefaultLogger::get()->debug("JoinVerticesProcess finished "); ASSIMP_LOG_INFO_F("JoinVerticesProcess finished | Verts in: ", iNumOldVertices,
} else " out: ", iNumVertices, " | ~",
{
char szBuff[128]; // should be sufficiently large in every case
::ai_snprintf(szBuff,128,"JoinVerticesProcess finished | Verts in: %i out: %i | ~%.1f%%",
iNumOldVertices,
iNumVertices,
((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f ); ((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f );
DefaultLogger::get()->info(szBuff);
} }
} }
pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT; pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
} }
// ------------------------------------------------------------------------------------------------ namespace {
// Unites identical vertices in the given mesh
int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex)
{ {
static_assert( AI_MAX_NUMBER_OF_COLOR_SETS == 8, "AI_MAX_NUMBER_OF_COLOR_SETS == 8");
static_assert( AI_MAX_NUMBER_OF_TEXTURECOORDS == 8, "AI_MAX_NUMBER_OF_TEXTURECOORDS == 8");
// Return early if we don't have any positions
if (!pMesh->HasPositions() || !pMesh->HasFaces()) {
return 0;
}
// We'll never have more vertices afterwards.
std::vector<Vertex> uniqueVertices;
uniqueVertices.reserve( pMesh->mNumVertices);
// For each vertex the index of the vertex it was replaced by.
// Since the maximal number of vertices is 2^31-1, the most significand bit can be used to mark
// whether a new vertex was created for the index (true) or if it was replaced by an existing
// unique vertex (false). This saves an additional std::vector<bool> and greatly enhances
// branching performance.
static_assert(AI_MAX_VERTICES == 0x7fffffff, "AI_MAX_VERTICES == 0x7fffffff");
std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
// A little helper to find locally close vertices faster. // A little helper to find locally close vertices faster.
// Try to reuse the lookup table from the last step. // Try to reuse the lookup table from the last step.
const static float epsilon = 1e-5f; const static float epsilon = 1e-5f;
// float posEpsilonSqr;
SpatialSort* vertexFinder = NULL;
SpatialSort _vertexFinder;
typedef std::pair<SpatialSort,float> SpatPair;
if (shared) {
std::vector<SpatPair >* avf;
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
if (avf) {
SpatPair& blubb = (*avf)[meshIndex];
vertexFinder = &blubb.first;
// posEpsilonSqr = blubb.second;
}
}
if (!vertexFinder) {
// bad, need to compute it.
_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
vertexFinder = &_vertexFinder;
// posEpsilonSqr = ComputePositionEpsilon(pMesh);
}
// Squared because we check against squared length of the vector difference // Squared because we check against squared length of the vector difference
static const float squareEpsilon = epsilon * epsilon; static const float squareEpsilon = epsilon * epsilon;
// Again, better waste some bytes than a realloc ... // Square compare is useful for animeshes vertices compare
std::vector<unsigned int> verticesFound; if ((lhs.position - rhs.position).SquareLength() > squareEpsilon) {
verticesFound.reserve(10); return false;
}
// Run an optimized code path if we don't have multiple UVs or vertex colors.
// This should yield false in more than 99% of all imports ...
const bool complex = ( pMesh->GetNumColorChannels() > 0 || pMesh->GetNumUVChannels() > 1);
// Now check each vertex if it brings something new to the table
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
// collect the vertex data
Vertex v(pMesh,a);
// collect all vertices that are close enough to the given position
vertexFinder->FindIdenticalPositions( v.position, verticesFound);
unsigned int matchIndex = 0xffffffff;
// check all unique vertices close to the position if this vertex is already present among them
for( unsigned int b = 0; b < verticesFound.size(); b++) {
const unsigned int vidx = verticesFound[b];
const unsigned int uidx = replaceIndex[ vidx];
if( uidx & 0x80000000)
continue;
const Vertex& uv = uniqueVertices[ uidx];
// Position mismatch is impossible - the vertex finder already discarded all non-matching positions
// We just test the other attributes even if they're not present in the mesh. // We just test the other attributes even if they're not present in the mesh.
// In this case they're initialized to 0 so the comparison succeeds. // In this case they're initialized to 0 so the comparison succeeds.
// By this method the non-present attributes are effectively ignored in the comparison. // By this method the non-present attributes are effectively ignored in the comparison.
if( (uv.normal - v.normal).SquareLength() > squareEpsilon) if ((lhs.normal - rhs.normal).SquareLength() > squareEpsilon) {
continue; return false;
if( (uv.texcoords[0] - v.texcoords[0]).SquareLength() > squareEpsilon) }
continue;
if( (uv.tangent - v.tangent).SquareLength() > squareEpsilon) if ((lhs.texcoords[0] - rhs.texcoords[0]).SquareLength() > squareEpsilon) {
continue; return false;
if( (uv.bitangent - v.bitangent).SquareLength() > squareEpsilon) }
continue;
if ((lhs.tangent - rhs.tangent).SquareLength() > squareEpsilon) {
return false;
}
if ((lhs.bitangent - rhs.bitangent).SquareLength() > squareEpsilon) {
return false;
}
// Usually we won't have vertex colors or multiple UVs, so we can skip from here // Usually we won't have vertex colors or multiple UVs, so we can skip from here
// Actually this increases runtime performance slightly, at least if branch // Actually this increases runtime performance slightly, at least if branch
// prediction is on our side. // prediction is on our side.
if (complex) { if (complex) {
// manually unrolled because continue wouldn't work as desired in an inner loop, for (int i = 0; i < 8; i++) {
// also because some compilers seem to fail the task. Colors and UV coords if (i > 0 && (lhs.texcoords[i] - rhs.texcoords[i]).SquareLength() > squareEpsilon) {
// are interleaved since the higher entries are most likely to be return false;
// zero and thus useless. By interleaving the arrays, vertices are,
// on average, rejected earlier.
if( (uv.texcoords[1] - v.texcoords[1]).SquareLength() > squareEpsilon)
continue;
if( GetColorDifference( uv.colors[0], v.colors[0]) > squareEpsilon)
continue;
if( (uv.texcoords[2] - v.texcoords[2]).SquareLength() > squareEpsilon)
continue;
if( GetColorDifference( uv.colors[1], v.colors[1]) > squareEpsilon)
continue;
if( (uv.texcoords[3] - v.texcoords[3]).SquareLength() > squareEpsilon)
continue;
if( GetColorDifference( uv.colors[2], v.colors[2]) > squareEpsilon)
continue;
if( (uv.texcoords[4] - v.texcoords[4]).SquareLength() > squareEpsilon)
continue;
if( GetColorDifference( uv.colors[3], v.colors[3]) > squareEpsilon)
continue;
if( (uv.texcoords[5] - v.texcoords[5]).SquareLength() > squareEpsilon)
continue;
if( GetColorDifference( uv.colors[4], v.colors[4]) > squareEpsilon)
continue;
if( (uv.texcoords[6] - v.texcoords[6]).SquareLength() > squareEpsilon)
continue;
if( GetColorDifference( uv.colors[5], v.colors[5]) > squareEpsilon)
continue;
if( (uv.texcoords[7] - v.texcoords[7]).SquareLength() > squareEpsilon)
continue;
if( GetColorDifference( uv.colors[6], v.colors[6]) > squareEpsilon)
continue;
if( GetColorDifference( uv.colors[7], v.colors[7]) > squareEpsilon)
continue;
} }
if (GetColorDifference(lhs.colors[i], rhs.colors[i]) > squareEpsilon) {
// we're still here -> this vertex perfectly matches our given vertex return false;
matchIndex = uidx;
break;
}
// found a replacement vertex among the uniques?
if( matchIndex != 0xffffffff)
{
// store where to found the matching unique vertex
replaceIndex[a] = matchIndex | 0x80000000;
}
else
{
// no unique vertex matches it up to now -> so add it
replaceIndex[a] = (unsigned int)uniqueVertices.size();
uniqueVertices.push_back( v);
} }
} }
}
if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) { return true;
DefaultLogger::get()->debug((Formatter::format(),
"Mesh ",meshIndex,
" (",
(pMesh->mName.length ? pMesh->mName.data : "unnamed"),
") | Verts in: ",pMesh->mNumVertices,
" out: ",
uniqueVertices.size(),
" | ~",
((pMesh->mNumVertices - uniqueVertices.size()) / (float)pMesh->mNumVertices) * 100.f,
"%"
));
} }
template<class XMesh>
void updateXMeshVertices(XMesh *pMesh, std::vector<Vertex> &uniqueVertices) {
// replace vertex data with the unique data sets // replace vertex data with the unique data sets
pMesh->mNumVertices = (unsigned int)uniqueVertices.size(); pMesh->mNumVertices = (unsigned int)uniqueVertices.size();
@ -296,11 +169,15 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// dislikes branches, even if they're easily predictable. // dislikes branches, even if they're easily predictable.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Position // Position, if present (check made for aiAnimMesh)
if (pMesh->mVertices)
{
delete [] pMesh->mVertices; delete [] pMesh->mVertices;
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) for (unsigned int a = 0; a < pMesh->mNumVertices; a++) {
pMesh->mVertices[a] = uniqueVertices[a].position; pMesh->mVertices[a] = uniqueVertices[a].position;
}
}
// Normals, if present // Normals, if present
if (pMesh->mNormals) if (pMesh->mNormals)
@ -347,6 +224,156 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
pMesh->mTextureCoords[a][b] = uniqueVertices[b].texcoords[a]; pMesh->mTextureCoords[a][b] = uniqueVertices[b].texcoords[a];
} }
} }
}
} // namespace
// ------------------------------------------------------------------------------------------------
// Unites identical vertices in the given mesh
int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
{
static_assert( AI_MAX_NUMBER_OF_COLOR_SETS == 8, "AI_MAX_NUMBER_OF_COLOR_SETS == 8");
static_assert( AI_MAX_NUMBER_OF_TEXTURECOORDS == 8, "AI_MAX_NUMBER_OF_TEXTURECOORDS == 8");
// Return early if we don't have any positions
if (!pMesh->HasPositions() || !pMesh->HasFaces()) {
return 0;
}
// We'll never have more vertices afterwards.
std::vector<Vertex> uniqueVertices;
uniqueVertices.reserve( pMesh->mNumVertices);
// For each vertex the index of the vertex it was replaced by.
// Since the maximal number of vertices is 2^31-1, the most significand bit can be used to mark
// whether a new vertex was created for the index (true) or if it was replaced by an existing
// unique vertex (false). This saves an additional std::vector<bool> and greatly enhances
// branching performance.
static_assert(AI_MAX_VERTICES == 0x7fffffff, "AI_MAX_VERTICES == 0x7fffffff");
std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
// float posEpsilonSqr;
SpatialSort* vertexFinder = NULL;
SpatialSort _vertexFinder;
typedef std::pair<SpatialSort,float> SpatPair;
if (shared) {
std::vector<SpatPair >* avf;
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
if (avf) {
SpatPair& blubb = (*avf)[meshIndex];
vertexFinder = &blubb.first;
// posEpsilonSqr = blubb.second;
}
}
if (!vertexFinder) {
// bad, need to compute it.
_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
vertexFinder = &_vertexFinder;
// posEpsilonSqr = ComputePositionEpsilon(pMesh);
}
// Again, better waste some bytes than a realloc ...
std::vector<unsigned int> verticesFound;
verticesFound.reserve(10);
// Run an optimized code path if we don't have multiple UVs or vertex colors.
// This should yield false in more than 99% of all imports ...
const bool complex = ( pMesh->GetNumColorChannels() > 0 || pMesh->GetNumUVChannels() > 1);
const bool hasAnimMeshes = pMesh->mNumAnimMeshes > 0;
// We'll never have more vertices afterwards.
std::vector<std::vector<Vertex>> uniqueAnimatedVertices;
if (hasAnimMeshes) {
uniqueAnimatedVertices.resize(pMesh->mNumAnimMeshes);
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
uniqueAnimatedVertices[animMeshIndex].reserve(pMesh->mNumVertices);
}
}
// Now check each vertex if it brings something new to the table
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
// collect the vertex data
Vertex v(pMesh,a);
// collect all vertices that are close enough to the given position
vertexFinder->FindIdenticalPositions( v.position, verticesFound);
unsigned int matchIndex = 0xffffffff;
// check all unique vertices close to the position if this vertex is already present among them
for( unsigned int b = 0; b < verticesFound.size(); b++) {
const unsigned int vidx = verticesFound[b];
const unsigned int uidx = replaceIndex[ vidx];
if( uidx & 0x80000000)
continue;
const Vertex& uv = uniqueVertices[ uidx];
if (!areVerticesEqual(v, uv, complex)) {
continue;
}
if (hasAnimMeshes) {
// If given vertex is animated, then it has to be preserver 1 to 1 (base mesh and animated mesh require same topology)
// NOTE: not doing this totaly breaks anim meshes as they don't have their own faces (they use pMesh->mFaces)
bool breaksAnimMesh = false;
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
const Vertex& animatedUV = uniqueAnimatedVertices[animMeshIndex][ uidx];
Vertex aniMeshVertex(pMesh->mAnimMeshes[animMeshIndex], a);
if (!areVerticesEqual(aniMeshVertex, animatedUV, complex)) {
breaksAnimMesh = true;
break;
}
}
if (breaksAnimMesh) {
continue;
}
}
// we're still here -> this vertex perfectly matches our given vertex
matchIndex = uidx;
break;
}
// found a replacement vertex among the uniques?
if( matchIndex != 0xffffffff)
{
// store where to found the matching unique vertex
replaceIndex[a] = matchIndex | 0x80000000;
}
else
{
// no unique vertex matches it up to now -> so add it
replaceIndex[a] = (unsigned int)uniqueVertices.size();
uniqueVertices.push_back( v);
if (hasAnimMeshes) {
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
Vertex aniMeshVertex(pMesh->mAnimMeshes[animMeshIndex], a);
uniqueAnimatedVertices[animMeshIndex].push_back(aniMeshVertex);
}
}
}
}
if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
ASSIMP_LOG_DEBUG_F(
"Mesh ",meshIndex,
" (",
(pMesh->mName.length ? pMesh->mName.data : "unnamed"),
") | Verts in: ",pMesh->mNumVertices,
" out: ",
uniqueVertices.size(),
" | ~",
((pMesh->mNumVertices - uniqueVertices.size()) / (float)pMesh->mNumVertices) * 100.f,
"%"
);
}
updateXMeshVertices(pMesh, uniqueVertices);
if (hasAnimMeshes) {
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
updateXMeshVertices(pMesh->mAnimMeshes[animMeshIndex], uniqueAnimatedVertices[animMeshIndex]);
}
}
// adjust the indices in all faces // adjust the indices in all faces
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
@ -375,7 +402,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
} }
} }
} else { } else {
DefaultLogger::get()->error( "X-Export: aiBone shall contain weights, but pointer to them is NULL." ); ASSIMP_LOG_ERROR( "X-Export: aiBone shall contain weights, but pointer to them is NULL." );
} }
if (newWeights.size() > 0) { if (newWeights.size() > 0) {
@ -409,7 +436,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
} }
--a; --a;
DefaultLogger::get()->warn("Removing bone -> no weights remaining"); ASSIMP_LOG_WARN("Removing bone -> no weights remaining");
} }
} }
return pMesh->mNumVertices; return pMesh->mNumVertices;

View File

@ -74,7 +74,7 @@ void LWOImporter::LoadLWOBFile()
case AI_LWO_PNTS: case AI_LWO_PNTS:
{ {
if (!mCurLayer->mTempPoints.empty()) if (!mCurLayer->mTempPoints.empty())
DefaultLogger::get()->warn("LWO: PNTS chunk encountered twice"); ASSIMP_LOG_WARN("LWO: PNTS chunk encountered twice");
else LoadLWOPoints(head.length); else LoadLWOPoints(head.length);
break; break;
} }
@ -83,7 +83,7 @@ void LWOImporter::LoadLWOBFile()
{ {
if (!mCurLayer->mFaces.empty()) if (!mCurLayer->mFaces.empty())
DefaultLogger::get()->warn("LWO: POLS chunk encountered twice"); ASSIMP_LOG_WARN("LWO: POLS chunk encountered twice");
else LoadLWOBPolygons(head.length); else LoadLWOBPolygons(head.length);
break; break;
} }
@ -91,7 +91,7 @@ void LWOImporter::LoadLWOBFile()
case AI_LWO_SRFS: case AI_LWO_SRFS:
{ {
if (!mTags->empty()) if (!mTags->empty())
DefaultLogger::get()->warn("LWO: SRFS chunk encountered twice"); ASSIMP_LOG_WARN("LWO: SRFS chunk encountered twice");
else LoadLWOTags(head.length); else LoadLWOTags(head.length);
break; break;
} }
@ -183,20 +183,20 @@ void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
break; break;
} }
face.mIndices = new unsigned int[face.mNumIndices]; face.mIndices = new unsigned int[face.mNumIndices];
for (unsigned int i = 0; i < face.mNumIndices;++i) for (unsigned int i = 0; i < face.mNumIndices;++i) {
{
unsigned int & mi = face.mIndices[i]; unsigned int & mi = face.mIndices[i];
uint16_t index; uint16_t index;
::memcpy(&index, cursor++, 2); ::memcpy(&index, cursor++, 2);
mi = index; mi = index;
if (mi > mCurLayer->mTempPoints.size()) if (mi > mCurLayer->mTempPoints.size())
{ {
DefaultLogger::get()->warn("LWOB: face index is out of range"); ASSIMP_LOG_WARN("LWOB: face index is out of range");
mi = (unsigned int)mCurLayer->mTempPoints.size()-1; mi = (unsigned int)mCurLayer->mTempPoints.size()-1;
} }
} }
} else {
ASSIMP_LOG_WARN("LWOB: Face has 0 indices");
} }
else DefaultLogger::get()->warn("LWOB: Face has 0 indices");
int16_t surface; int16_t surface;
::memcpy(&surface, cursor++, 2); ::memcpy(&surface, cursor++, 2);
if (surface < 0) if (surface < 0)
@ -242,7 +242,7 @@ LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned i
else else
{ {
// procedural or gradient, not supported // procedural or gradient, not supported
DefaultLogger::get()->error("LWOB: Unsupported legacy texture: " + type); ASSIMP_LOG_ERROR_F("LWOB: Unsupported legacy texture: ", type);
} }
return tex; return tex;
@ -273,7 +273,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
* how much storage is actually left and work with this value from now on. * how much storage is actually left and work with this value from now on.
*/ */
if (mFileBuffer + head.length > end) { if (mFileBuffer + head.length > end) {
DefaultLogger::get()->error("LWOB: Invalid surface chunk length. Trying to continue."); ASSIMP_LOG_ERROR("LWOB: Invalid surface chunk length. Trying to continue.");
head.length = (uint16_t) (end - mFileBuffer); head.length = (uint16_t) (end - mFileBuffer);
} }
@ -381,8 +381,9 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
{ {
if (pTex) { if (pTex) {
GetS0(pTex->mFileName,head.length); GetS0(pTex->mFileName,head.length);
} else {
ASSIMP_LOG_WARN("LWOB: Unexpected TIMG chunk");
} }
else DefaultLogger::get()->warn("LWOB: Unexpected TIMG chunk");
break; break;
} }
// texture strength // texture strength
@ -391,8 +392,9 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TVAL,1); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TVAL,1);
if (pTex) { if (pTex) {
pTex->mStrength = (float)GetU1()/ 255.f; pTex->mStrength = (float)GetU1()/ 255.f;
} else {
ASSIMP_LOG_ERROR("LWOB: Unexpected TVAL chunk");
} }
else DefaultLogger::get()->warn("LWOB: Unexpected TVAL chunk");
break; break;
} }
// texture flags // texture flags
@ -400,8 +402,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
{ {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TFLG,2); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TFLG,2);
if (pTex) if (nullptr != pTex) {
{
const uint16_t s = GetU2(); const uint16_t s = GetU2();
if (s & 1) if (s & 1)
pTex->majorAxis = LWO::Texture::AXIS_X; pTex->majorAxis = LWO::Texture::AXIS_X;
@ -410,10 +411,13 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
else if (s & 4) else if (s & 4)
pTex->majorAxis = LWO::Texture::AXIS_Z; pTex->majorAxis = LWO::Texture::AXIS_Z;
if (s & 16) if (s & 16) {
DefaultLogger::get()->warn("LWOB: Ignoring \'negate\' flag on texture"); ASSIMP_LOG_WARN("LWOB: Ignoring \'negate\' flag on texture");
}
}
else {
ASSIMP_LOG_WARN("LWOB: Unexpected TFLG chunk");
} }
else DefaultLogger::get()->warn("LWOB: Unexpected TFLG chunk");
break; break;
} }
} }

View File

@ -188,7 +188,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// old lightwave file format (prior to v6) // old lightwave file format (prior to v6)
if (AI_LWO_FOURCC_LWOB == fileType) { if (AI_LWO_FOURCC_LWOB == fileType) {
DefaultLogger::get()->info("LWO file format: LWOB (<= LightWave 5.5)"); ASSIMP_LOG_INFO("LWO file format: LWOB (<= LightWave 5.5)");
mIsLWO2 = false; mIsLWO2 = false;
mIsLXOB = false; mIsLXOB = false;
@ -197,12 +197,12 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// New lightwave format // New lightwave format
else if (AI_LWO_FOURCC_LWO2 == fileType) { else if (AI_LWO_FOURCC_LWO2 == fileType) {
mIsLXOB = false; mIsLXOB = false;
DefaultLogger::get()->info("LWO file format: LWO2 (>= LightWave 6)"); ASSIMP_LOG_INFO("LWO file format: LWO2 (>= LightWave 6)");
} }
// MODO file format // MODO file format
else if (AI_LWO_FOURCC_LXOB == fileType) { else if (AI_LWO_FOURCC_LXOB == fileType) {
mIsLXOB = true; mIsLXOB = true;
DefaultLogger::get()->info("LWO file format: LXOB (Modo)"); ASSIMP_LOG_INFO("LWO file format: LXOB (Modo)");
} }
// we don't know this format // we don't know this format
else else
@ -271,7 +271,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
unsigned int idx = (*it).surfaceIndex; unsigned int idx = (*it).surfaceIndex;
if (idx >= mTags->size()) if (idx >= mTags->size())
{ {
DefaultLogger::get()->warn("LWO: Invalid face surface index"); ASSIMP_LOG_WARN("LWO: Invalid face surface index");
idx = UINT_MAX; idx = UINT_MAX;
} }
if(UINT_MAX == idx || UINT_MAX == (idx = _mMapping[idx])) { if(UINT_MAX == idx || UINT_MAX == (idx = _mMapping[idx])) {
@ -423,7 +423,9 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// So we use a separate implementation. // So we use a separate implementation.
ComputeNormals(mesh,smoothingGroups,_mSurfaces[i]); ComputeNormals(mesh,smoothingGroups,_mSurfaces[i]);
} }
else DefaultLogger::get()->debug("LWO2: No need to compute normals, they're already there"); else {
ASSIMP_LOG_DEBUG("LWO2: No need to compute normals, they're already there");
}
++p; ++p;
} }
} }
@ -686,13 +688,13 @@ void LWOImporter::ResolveClips()
if (Clip::REF == clip.type) { if (Clip::REF == clip.type) {
if (clip.clipRef >= mClips.size()) { if (clip.clipRef >= mClips.size()) {
DefaultLogger::get()->error("LWO2: Clip referrer index is out of range"); ASSIMP_LOG_ERROR("LWO2: Clip referrer index is out of range");
clip.clipRef = 0; clip.clipRef = 0;
} }
Clip& dest = mClips[clip.clipRef]; Clip& dest = mClips[clip.clipRef];
if (Clip::REF == dest.type) { if (Clip::REF == dest.type) {
DefaultLogger::get()->error("LWO2: Clip references another clip reference"); ASSIMP_LOG_ERROR("LWO2: Clip references another clip reference");
clip.type = Clip::UNSUPPORTED; clip.type = Clip::UNSUPPORTED;
} }
@ -711,7 +713,7 @@ void LWOImporter::AdjustTexturePath(std::string& out)
if (!mIsLWO2 && ::strstr(out.c_str(), "(sequence)")) { if (!mIsLWO2 && ::strstr(out.c_str(), "(sequence)")) {
// remove the (sequence) and append 000 // remove the (sequence) and append 000
DefaultLogger::get()->info("LWOB: Sequence of animated texture found. It will be ignored"); ASSIMP_LOG_INFO("LWOB: Sequence of animated texture found. It will be ignored");
out = out.substr(0,out.length()-10) + "000"; out = out.substr(0,out.length()-10) + "000";
} }
@ -786,10 +788,10 @@ void LWOImporter::LoadLWO2Polygons(unsigned int length)
{ {
// read unsupported stuff too (although we won't process it) // read unsupported stuff too (although we won't process it)
case AI_LWO_MBAL: case AI_LWO_MBAL:
DefaultLogger::get()->warn("LWO2: Encountered unsupported primitive chunk (METABALL)"); ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (METABALL)");
break; break;
case AI_LWO_CURV: case AI_LWO_CURV:
DefaultLogger::get()->warn("LWO2: Encountered unsupported primitive chunk (SPLINE)");; ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (SPLINE)");;
break; break;
// These are ok with no restrictions // These are ok with no restrictions
@ -801,7 +803,7 @@ void LWOImporter::LoadLWO2Polygons(unsigned int length)
default: default:
// hm!? wtf is this? ok ... // hm!? wtf is this? ok ...
DefaultLogger::get()->error("LWO2: Ignoring unknown polygon type."); ASSIMP_LOG_ERROR("LWO2: Ignoring unknown polygon type.");
break; break;
} }
@ -864,7 +866,7 @@ void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator& it,
face.mIndices[i] = ReadVSizedIntLWO2((uint8_t*&)cursor) + mCurLayer->mPointIDXOfs; face.mIndices[i] = ReadVSizedIntLWO2((uint8_t*&)cursor) + mCurLayer->mPointIDXOfs;
if(face.mIndices[i] > mCurLayer->mTempPoints.size()) if(face.mIndices[i] > mCurLayer->mTempPoints.size())
{ {
DefaultLogger::get()->warn("LWO2: Failure evaluating face record, index is out of range"); ASSIMP_LOG_WARN("LWO2: Failure evaluating face record, index is out of range");
face.mIndices[i] = (unsigned int)mCurLayer->mTempPoints.size()-1; face.mIndices[i] = (unsigned int)mCurLayer->mTempPoints.size()-1;
} }
} }
@ -891,7 +893,7 @@ void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
unsigned int j = GetU2(); unsigned int j = GetU2();
if (i >= mCurLayer->mFaces.size()) { if (i >= mCurLayer->mFaces.size()) {
DefaultLogger::get()->warn("LWO2: face index in PTAG is out of range"); ASSIMP_LOG_WARN("LWO2: face index in PTAG is out of range");
continue; continue;
} }
@ -914,7 +916,7 @@ VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPol
for (auto & elem : list) { for (auto & elem : list) {
if (elem.name == name) { if (elem.name == name) {
if (!perPoly) { if (!perPoly) {
DefaultLogger::get()->warn("LWO2: Found two VMAP sections with equal names"); ASSIMP_LOG_WARN("LWO2: Found two VMAP sections with equal names");
} }
return &elem; return &elem;
} }
@ -999,7 +1001,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
{ {
case AI_LWO_TXUV: case AI_LWO_TXUV:
if (dims != 2) { if (dims != 2) {
DefaultLogger::get()->warn("LWO2: Skipping UV channel \'" ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'"
+ name + "\' with !2 components"); + name + "\' with !2 components");
return; return;
} }
@ -1008,7 +1010,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
case AI_LWO_WGHT: case AI_LWO_WGHT:
case AI_LWO_MNVW: case AI_LWO_MNVW:
if (dims != 1) { if (dims != 1) {
DefaultLogger::get()->warn("LWO2: Skipping Weight Channel \'" ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'"
+ name + "\' with !1 components"); + name + "\' with !1 components");
return; return;
} }
@ -1018,7 +1020,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
case AI_LWO_RGB: case AI_LWO_RGB:
case AI_LWO_RGBA: case AI_LWO_RGBA:
if (dims != 3 && dims != 4) { if (dims != 3 && dims != 4) {
DefaultLogger::get()->warn("LWO2: Skipping Color Map \'" ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'"
+ name + "\' with a dimension > 4 or < 3"); + name + "\' with a dimension > 4 or < 3");
return; return;
} }
@ -1033,7 +1035,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
if (name != "vert_normals" || dims != 3 || mCurLayer->mNormals.name.length()) if (name != "vert_normals" || dims != 3 || mCurLayer->mNormals.name.length())
return; return;
DefaultLogger::get()->info("Processing non-standard extension: MODO VMAP.NORM.vert_normals"); ASSIMP_LOG_INFO("Processing non-standard extension: MODO VMAP.NORM.vert_normals");
mCurLayer->mNormals.name = name; mCurLayer->mNormals.name = name;
base = & mCurLayer->mNormals; base = & mCurLayer->mNormals;
@ -1048,7 +1050,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
if (name == "APS.Level") { if (name == "APS.Level") {
// XXX handle this (seems to be subdivision-related). // XXX handle this (seems to be subdivision-related).
} }
DefaultLogger::get()->warn("LWO2: Skipping unknown VMAP/VMAD channel \'" + name + "\'"); ASSIMP_LOG_WARN_F("LWO2: Skipping unknown VMAP/VMAD channel \'", name, "\'");
return; return;
}; };
base->Allocate((unsigned int)mCurLayer->mTempPoints.size()); base->Allocate((unsigned int)mCurLayer->mTempPoints.size());
@ -1068,7 +1070,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs; unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs;
if (idx >= numPoints) { if (idx >= numPoints) {
DefaultLogger::get()->warn("LWO2: Failure evaluating VMAP/VMAD entry \'" + name + "\', vertex index is out of range"); ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAP/VMAD entry \'", name, "\', vertex index is out of range");
mFileBuffer += base->dims<<2u; mFileBuffer += base->dims<<2u;
continue; continue;
} }
@ -1078,7 +1080,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
// we have already a VMAP entry for this vertex - thus // we have already a VMAP entry for this vertex - thus
// we need to duplicate the corresponding polygon. // we need to duplicate the corresponding polygon.
if (polyIdx >= numFaces) { if (polyIdx >= numFaces) {
DefaultLogger::get()->warn("LWO2: Failure evaluating VMAD entry \'" + name + "\', polygon index is out of range"); ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAD entry \'", name, "\', polygon index is out of range");
mFileBuffer += base->dims<<2u; mFileBuffer += base->dims<<2u;
continue; continue;
} }
@ -1119,7 +1121,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
CreateNewEntry(mCurLayer->mNormals, srcIdx ); CreateNewEntry(mCurLayer->mNormals, srcIdx );
} }
if (!had) { if (!had) {
DefaultLogger::get()->warn("LWO2: Failure evaluating VMAD entry \'" + name + "\', vertex index wasn't found in that polygon"); ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAD entry \'", name, "\', vertex index wasn't found in that polygon");
ai_assert(had); ai_assert(had);
} }
} }
@ -1180,11 +1182,11 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
break; break;
case AI_LWO_STCC: case AI_LWO_STCC:
DefaultLogger::get()->warn("LWO2: Color shifted images are not supported"); ASSIMP_LOG_WARN("LWO2: Color shifted images are not supported");
break; break;
case AI_LWO_ANIM: case AI_LWO_ANIM:
DefaultLogger::get()->warn("LWO2: Animated textures are not supported"); ASSIMP_LOG_WARN("LWO2: Animated textures are not supported");
break; break;
case AI_LWO_XREF: case AI_LWO_XREF:
@ -1201,7 +1203,7 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
break; break;
default: default:
DefaultLogger::get()->warn("LWO2: Encountered unknown CLIP subchunk"); ASSIMP_LOG_WARN("LWO2: Encountered unknown CLIP sub-chunk");
} }
} }
@ -1282,7 +1284,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
{ {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SPAN,4); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SPAN,4);
if (envelope.keys.size()<2) if (envelope.keys.size()<2)
DefaultLogger::get()->warn("LWO2: Unexpected SPAN chunk"); ASSIMP_LOG_WARN("LWO2: Unexpected SPAN chunk");
else { else {
LWO::Key& key = envelope.keys.back(); LWO::Key& key = envelope.keys.back();
switch (GetU4()) switch (GetU4())
@ -1300,7 +1302,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
case AI_LWO_BEZ2: case AI_LWO_BEZ2:
key.inter = LWO::IT_BEZ2;break; key.inter = LWO::IT_BEZ2;break;
default: default:
DefaultLogger::get()->warn("LWO2: Unknown interval interpolation mode"); ASSIMP_LOG_WARN("LWO2: Unknown interval interpolation mode");
}; };
// todo ... read params // todo ... read params
@ -1309,7 +1311,8 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
} }
default: default:
DefaultLogger::get()->warn("LWO2: Encountered unknown ENVL subchunk"); ASSIMP_LOG_WARN("LWO2: Encountered unknown ENVL subchunk");
break;
} }
// regardless how much we did actually read, go to the next chunk // regardless how much we did actually read, go to the next chunk
mFileBuffer = next; mFileBuffer = next;
@ -1408,7 +1411,7 @@ void LWOImporter::LoadLWO2File()
case AI_LWO_VMAD: case AI_LWO_VMAD:
if (mCurLayer->mFaces.empty()) if (mCurLayer->mFaces.empty())
{ {
DefaultLogger::get()->warn("LWO2: Unexpected VMAD chunk"); ASSIMP_LOG_WARN("LWO2: Unexpected VMAD chunk");
break; break;
} }
// --- intentionally no break here // --- intentionally no break here
@ -1418,7 +1421,7 @@ void LWOImporter::LoadLWO2File()
break; break;
if (mCurLayer->mTempPoints.empty()) if (mCurLayer->mTempPoints.empty())
DefaultLogger::get()->warn("LWO2: Unexpected VMAP chunk"); ASSIMP_LOG_WARN("LWO2: Unexpected VMAP chunk");
else LoadLWO2VertexMap(head.length,head.type == AI_LWO_VMAD); else LoadLWO2VertexMap(head.length,head.type == AI_LWO_VMAD);
break; break;
} }
@ -1439,17 +1442,21 @@ void LWOImporter::LoadLWO2File()
if (skip) if (skip)
break; break;
if (mCurLayer->mFaces.empty()) if (mCurLayer->mFaces.empty()) {
DefaultLogger::get()->warn("LWO2: Unexpected PTAG"); ASSIMP_LOG_WARN("LWO2: Unexpected PTAG");
else LoadLWO2PolygonTags(head.length); } else {
LoadLWO2PolygonTags(head.length);
}
break; break;
} }
// list of tags // list of tags
case AI_LWO_TAGS: case AI_LWO_TAGS:
{ {
if (!mTags->empty()) if (!mTags->empty()) {
DefaultLogger::get()->warn("LWO2: SRFS chunk encountered twice"); ASSIMP_LOG_WARN("LWO2: SRFS chunk encountered twice");
else LoadLWOTags(head.length); } else {
LoadLWOTags(head.length);
}
break; break;
} }

View File

@ -473,7 +473,7 @@ inline void LWOImporter::GetS0(std::string& out,unsigned int max)
{ {
if (++iCursor > max) if (++iCursor > max)
{ {
DefaultLogger::get()->warn("LWO: Invalid file, string is is too long"); ASSIMP_LOG_WARN("LWO: Invalid file, string is is too long");
break; break;
} }
++mFileBuffer; ++mFileBuffer;

View File

@ -74,7 +74,7 @@ inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
return aiTextureMapMode_Mirror; return aiTextureMapMode_Mirror;
case LWO::Texture::RESET: case LWO::Texture::RESET:
DefaultLogger::get()->warn("LWO2: Unsupported texture map mode: RESET"); ASSIMP_LOG_WARN("LWO2: Unsupported texture map mode: RESET");
// fall though here // fall though here
case LWO::Texture::EDGE: case LWO::Texture::EDGE:
@ -117,7 +117,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
mapping = aiTextureMapping_BOX; mapping = aiTextureMapping_BOX;
break; break;
case LWO::Texture::FrontProjection: case LWO::Texture::FrontProjection:
DefaultLogger::get()->error("LWO2: Unsupported texture mapping: FrontProjection"); ASSIMP_LOG_ERROR("LWO2: Unsupported texture mapping: FrontProjection");
mapping = aiTextureMapping_OTHER; mapping = aiTextureMapping_OTHER;
break; break;
case LWO::Texture::UV: case LWO::Texture::UV:
@ -164,7 +164,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
static_assert(sizeof(aiUVTransform)/sizeof(ai_real) == 5, "sizeof(aiUVTransform)/sizeof(ai_real) == 5"); static_assert(sizeof(aiUVTransform)/sizeof(ai_real) == 5, "sizeof(aiUVTransform)/sizeof(ai_real) == 5");
pcMat->AddProperty(&trafo,1,AI_MATKEY_UVTRANSFORM(type,cur)); pcMat->AddProperty(&trafo,1,AI_MATKEY_UVTRANSFORM(type,cur));
} }
DefaultLogger::get()->debug("LWO2: Setting up non-UV mapping"); ASSIMP_LOG_DEBUG("LWO2: Setting up non-UV mapping");
} }
// The older LWOB format does not use indirect references to clips. // The older LWOB format does not use indirect references to clips.
@ -181,7 +181,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
} }
if (candidate == end) { if (candidate == end) {
DefaultLogger::get()->error("LWO2: Clip index is out of bounds"); ASSIMP_LOG_ERROR("LWO2: Clip index is out of bounds");
temp = 0; temp = 0;
// fixme: apparently some LWO files shipping with Doom3 don't // fixme: apparently some LWO files shipping with Doom3 don't
@ -194,7 +194,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
} }
else { else {
if (Clip::UNSUPPORTED == (*candidate).type) { if (Clip::UNSUPPORTED == (*candidate).type) {
DefaultLogger::get()->error("LWO2: Clip type is not supported"); ASSIMP_LOG_ERROR("LWO2: Clip type is not supported");
continue; continue;
} }
AdjustTexturePath((*candidate).path); AdjustTexturePath((*candidate).path);
@ -212,7 +212,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
{ {
std::string ss = texture.mFileName; std::string ss = texture.mFileName;
if (!ss.length()) { if (!ss.length()) {
DefaultLogger::get()->error("LWOB: Empty file name"); ASSIMP_LOG_WARN("LWOB: Empty file name");
continue; continue;
} }
AdjustTexturePath(ss); AdjustTexturePath(ss);
@ -246,7 +246,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
default: default:
temp = (unsigned int)aiTextureOp_Multiply; temp = (unsigned int)aiTextureOp_Multiply;
DefaultLogger::get()->warn("LWO2: Unsupported texture blend mode: alpha or displacement"); ASSIMP_LOG_WARN("LWO2: Unsupported texture blend mode: alpha or displacement");
} }
// Setup texture operation // Setup texture operation
@ -347,20 +347,20 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
// the surface and search for a name which we know ... // the surface and search for a name which we know ...
for (const auto &shader : surf.mShaders) { for (const auto &shader : surf.mShaders) {
if (shader.functionName == "LW_SuperCelShader" || shader.functionName == "AH_CelShader") { if (shader.functionName == "LW_SuperCelShader" || shader.functionName == "AH_CelShader") {
DefaultLogger::get()->info("LWO2: Mapping LW_SuperCelShader/AH_CelShader to aiShadingMode_Toon"); ASSIMP_LOG_INFO("LWO2: Mapping LW_SuperCelShader/AH_CelShader to aiShadingMode_Toon");
m = aiShadingMode_Toon; m = aiShadingMode_Toon;
break; break;
} }
else if (shader.functionName == "LW_RealFresnel" || shader.functionName == "LW_FastFresnel") { else if (shader.functionName == "LW_RealFresnel" || shader.functionName == "LW_FastFresnel") {
DefaultLogger::get()->info("LWO2: Mapping LW_RealFresnel/LW_FastFresnel to aiShadingMode_Fresnel"); ASSIMP_LOG_INFO("LWO2: Mapping LW_RealFresnel/LW_FastFresnel to aiShadingMode_Fresnel");
m = aiShadingMode_Fresnel; m = aiShadingMode_Fresnel;
break; break;
} }
else else
{ {
DefaultLogger::get()->warn("LWO2: Unknown surface shader: " + shader.functionName); ASSIMP_LOG_WARN_F("LWO2: Unknown surface shader: ", shader.functionName);
} }
} }
if (surf.mMaximumSmoothAngle <= 0.0) if (surf.mMaximumSmoothAngle <= 0.0)
@ -398,7 +398,7 @@ char LWOImporter::FindUVChannels(LWO::TextureList& list,
} }
else { else {
// channel mismatch. need to duplicate the material. // channel mismatch. need to duplicate the material.
DefaultLogger::get()->warn("LWO: Channel mismatch, would need to duplicate surface [design bug]"); ASSIMP_LOG_WARN("LWO: Channel mismatch, would need to duplicate surface [design bug]");
// TODO // TODO
} }
@ -429,7 +429,7 @@ void LWOImporter::FindUVChannels(LWO::Surface& surf,
if (extra >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { if (extra >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
DefaultLogger::get()->error("LWO: Maximum number of UV channels for " ASSIMP_LOG_ERROR("LWO: Maximum number of UV channels for "
"this mesh reached. Skipping channel \'" + uv.name + "\'"); "this mesh reached. Skipping channel \'" + uv.name + "\'");
} }
@ -502,7 +502,7 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
if (vc.abAssigned[idx] && ((aiColor4D*)&vc.rawData[0])[idx] != aiColor4D(0.0,0.0,0.0,1.0)) { if (vc.abAssigned[idx] && ((aiColor4D*)&vc.rawData[0])[idx] != aiColor4D(0.0,0.0,0.0,1.0)) {
if (next >= AI_MAX_NUMBER_OF_COLOR_SETS) { if (next >= AI_MAX_NUMBER_OF_COLOR_SETS) {
DefaultLogger::get()->error("LWO: Maximum number of vertex color channels for " ASSIMP_LOG_ERROR("LWO: Maximum number of vertex color channels for "
"this mesh reached. Skipping channel \'" + vc.name + "\'"); "this mesh reached. Skipping channel \'" + vc.name + "\'");
} }
@ -567,7 +567,7 @@ void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture& tex ) void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture& tex )
{ {
// --- not supported at the moment // --- not supported at the moment
DefaultLogger::get()->error("LWO2: Found procedural texture, this is not supported"); ASSIMP_LOG_ERROR("LWO2: Found procedural texture, this is not supported");
tex.bCanUse = false; tex.bCanUse = false;
} }
@ -575,7 +575,7 @@ void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture& tex )
void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture& tex ) void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture& tex )
{ {
// --- not supported at the moment // --- not supported at the moment
DefaultLogger::get()->error("LWO2: Found gradient texture, this is not supported"); ASSIMP_LOG_ERROR("LWO2: Found gradient texture, this is not supported");
tex.bCanUse = false; tex.bCanUse = false;
} }
@ -590,7 +590,7 @@ void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
// we could crash later if this is an empty string ... // we could crash later if this is an empty string ...
if (!tex.ordinal.length()) if (!tex.ordinal.length())
{ {
DefaultLogger::get()->error("LWO2: Ill-formed SURF.BLOK ordinal string"); ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string");
tex.ordinal = "\x00"; tex.ordinal = "\x00";
} }
while (true) while (true)
@ -662,7 +662,7 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi
case AI_LWO_REFL: case AI_LWO_REFL:
listRef = &surf.mReflectionTextures;break; listRef = &surf.mReflectionTextures;break;
default: default:
DefaultLogger::get()->warn("LWO2: Encountered unknown texture type"); ASSIMP_LOG_WARN("LWO2: Encountered unknown texture type");
return; return;
} }
@ -691,7 +691,7 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, u
// we could crash later if this is an empty string ... // we could crash later if this is an empty string ...
if (!shader.ordinal.length()) if (!shader.ordinal.length())
{ {
DefaultLogger::get()->error("LWO2: Ill-formed SURF.BLOK ordinal string"); ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string");
shader.ordinal = "\x00"; shader.ordinal = "\x00";
} }
@ -750,7 +750,7 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
} }
} }
if (derived.size()) if (derived.size())
DefaultLogger::get()->warn("LWO2: Unable to find source surface: " + derived); ASSIMP_LOG_WARN("LWO2: Unable to find source surface: " + derived);
} }
while (true) while (true)
@ -886,7 +886,7 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
break; break;
default: default:
DefaultLogger::get()->warn("LWO2: Found an unsupported surface BLOK"); ASSIMP_LOG_WARN("LWO2: Found an unsupported surface BLOK");
}; };
break; break;

View File

@ -105,7 +105,7 @@ void LWS::Element::Parse (const char*& buffer)
if (children.back().tokens[0] == "Plugin") if (children.back().tokens[0] == "Plugin")
{ {
DefaultLogger::get()->debug("LWS: Skipping over plugin-specific data"); ASSIMP_LOG_DEBUG("LWS: Skipping over plugin-specific data");
// strange stuff inside Plugin/Endplugin blocks. Needn't // strange stuff inside Plugin/Endplugin blocks. Needn't
// follow LWS syntax, so we skip over it // follow LWS syntax, so we skip over it
@ -200,7 +200,7 @@ void LWSImporter::SetupProperties(const Importer* pImp)
void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill ) void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
{ {
if (dad.children.empty()) { if (dad.children.empty()) {
DefaultLogger::get()->error("LWS: Envelope descriptions must not be empty"); ASSIMP_LOG_ERROR("LWS: Envelope descriptions must not be empty");
return; return;
} }
@ -248,7 +248,7 @@ void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
num = 4; num = 4;
break; break;
default: default:
DefaultLogger::get()->error("LWS: Unknown span type"); ASSIMP_LOG_ERROR("LWS: Unknown span type");
} }
for (unsigned int i = 0; i < num;++i) { for (unsigned int i = 0; i < num;++i) {
SkipSpaces(&c); SkipSpaces(&c);
@ -305,7 +305,7 @@ void LWSImporter::ReadEnvelope_Old(
return; return;
unexpected_end: unexpected_end:
DefaultLogger::get()->error("LWS: Encountered unexpected end of file while parsing object motion"); ASSIMP_LOG_ERROR("LWS: Encountered unexpected end of file while parsing object motion");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -352,7 +352,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
if (src.path.length() ) { if (src.path.length() ) {
obj = batch.GetImport(src.id); obj = batch.GetImport(src.id);
if (!obj) { if (!obj) {
DefaultLogger::get()->error("LWS: Failed to read external file " + src.path); ASSIMP_LOG_ERROR("LWS: Failed to read external file " + src.path);
} }
else { else {
if (obj->mRootNode->mNumChildren == 1) { if (obj->mRootNode->mNumChildren == 1) {
@ -410,7 +410,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
// name to attach light to node -> unique due to LWs indexing system // name to attach light to node -> unique due to LWs indexing system
lit->mName = nd->mName; lit->mName = nd->mName;
// detemine light type and setup additional members // determine light type and setup additional members
if (src.lightType == 2) { /* spot light */ if (src.lightType == 2) { /* spot light */
lit->mType = aiLightSource_SPOT; lit->mType = aiLightSource_SPOT;
@ -551,7 +551,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// get file format version and print to log // get file format version and print to log
++it; ++it;
unsigned int version = strtoul10((*it).tokens[0].c_str()); unsigned int version = strtoul10((*it).tokens[0].c_str());
DefaultLogger::get()->info("LWS file format version is " + (*it).tokens[0]); ASSIMP_LOG_INFO("LWS file format version is " + (*it).tokens[0]);
first = 0.; first = 0.;
last = 60.; last = 60.;
fps = 25.; /* seems to be a good default frame rate */ fps = 25.; /* seems to be a good default frame rate */
@ -656,7 +656,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
d.number = cur_object++; d.number = cur_object++;
nodes.push_back(d); nodes.push_back(d);
} }
else DefaultLogger::get()->error("LWS: Unexpected keyword: \'Channel\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'Channel\'");
} }
// important: index of channel // important: index of channel
@ -673,7 +673,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// 'Envelope': a single animation channel // 'Envelope': a single animation channel
else if ((*it).tokens[0] == "Envelope") { else if ((*it).tokens[0] == "Envelope") {
if (nodes.empty() || nodes.back().channels.empty()) if (nodes.empty() || nodes.back().channels.empty())
DefaultLogger::get()->error("LWS: Unexpected keyword: \'Envelope\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'Envelope\'");
else { else {
ReadEnvelope((*it),nodes.back().channels.back()); ReadEnvelope((*it),nodes.back().channels.back());
} }
@ -684,7 +684,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
(*it).tokens[0] == "LightMotion")) { (*it).tokens[0] == "LightMotion")) {
if (nodes.empty()) if (nodes.empty())
DefaultLogger::get()->error("LWS: Unexpected keyword: \'<Light|Object|Camera>Motion\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'<Light|Object|Camera>Motion\'");
else { else {
ReadEnvelope_Old(it,root.children.end(),nodes.back(),version); ReadEnvelope_Old(it,root.children.end(),nodes.back(),version);
} }
@ -692,7 +692,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// 'Pre/PostBehavior': pre/post animation behaviour for LWSC 2 // 'Pre/PostBehavior': pre/post animation behaviour for LWSC 2
else if (version == 2 && (*it).tokens[0] == "Pre/PostBehavior") { else if (version == 2 && (*it).tokens[0] == "Pre/PostBehavior") {
if (nodes.empty()) if (nodes.empty())
DefaultLogger::get()->error("LWS: Unexpected keyword: \'Pre/PostBehavior'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'Pre/PostBehavior'");
else { else {
for (std::list<LWO::Envelope>::iterator it = nodes.back().channels.begin(); it != nodes.back().channels.end(); ++it) { for (std::list<LWO::Envelope>::iterator it = nodes.back().channels.begin(); it != nodes.back().channels.end(); ++it) {
// two ints per envelope // two ints per envelope
@ -705,14 +705,14 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// 'ParentItem': specifies the parent of the current element // 'ParentItem': specifies the parent of the current element
else if ((*it).tokens[0] == "ParentItem") { else if ((*it).tokens[0] == "ParentItem") {
if (nodes.empty()) if (nodes.empty())
DefaultLogger::get()->error("LWS: Unexpected keyword: \'ParentItem\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentItem\'");
else nodes.back().parent = strtoul16(c,&c); else nodes.back().parent = strtoul16(c,&c);
} }
// 'ParentObject': deprecated one for older formats // 'ParentObject': deprecated one for older formats
else if (version < 3 && (*it).tokens[0] == "ParentObject") { else if (version < 3 && (*it).tokens[0] == "ParentObject") {
if (nodes.empty()) if (nodes.empty())
DefaultLogger::get()->error("LWS: Unexpected keyword: \'ParentObject\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentObject\'");
else { else {
nodes.back().parent = strtoul10(c,&c) | (1u << 28u); nodes.back().parent = strtoul10(c,&c) | (1u << 28u);
@ -736,7 +736,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// 'CameraName': set name of currently active camera // 'CameraName': set name of currently active camera
else if ((*it).tokens[0] == "CameraName") { else if ((*it).tokens[0] == "CameraName") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA)
DefaultLogger::get()->error("LWS: Unexpected keyword: \'CameraName\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'CameraName\'");
else nodes.back().name = c; else nodes.back().name = c;
} }
@ -758,14 +758,14 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// 'LightName': set name of currently active light // 'LightName': set name of currently active light
else if ((*it).tokens[0] == "LightName") { else if ((*it).tokens[0] == "LightName") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightName\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightName\'");
else nodes.back().name = c; else nodes.back().name = c;
} }
// 'LightIntensity': set intensity of currently active light // 'LightIntensity': set intensity of currently active light
else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity" ) { else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity" ) {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightIntensity\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightIntensity\'");
else fast_atoreal_move<float>(c, nodes.back().lightIntensity ); else fast_atoreal_move<float>(c, nodes.back().lightIntensity );
@ -773,7 +773,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// 'LightType': set type of currently active light // 'LightType': set type of currently active light
else if ((*it).tokens[0] == "LightType") { else if ((*it).tokens[0] == "LightType") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightType\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightType\'");
else nodes.back().lightType = strtoul10(c); else nodes.back().lightType = strtoul10(c);
@ -781,7 +781,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// 'LightFalloffType': set falloff type of currently active light // 'LightFalloffType': set falloff type of currently active light
else if ((*it).tokens[0] == "LightFalloffType") { else if ((*it).tokens[0] == "LightFalloffType") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightFalloffType\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightFalloffType\'");
else nodes.back().lightFalloffType = strtoul10(c); else nodes.back().lightFalloffType = strtoul10(c);
@ -789,7 +789,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// 'LightConeAngle': set cone angle of currently active light // 'LightConeAngle': set cone angle of currently active light
else if ((*it).tokens[0] == "LightConeAngle") { else if ((*it).tokens[0] == "LightConeAngle") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightConeAngle\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightConeAngle\'");
else nodes.back().lightConeAngle = fast_atof(c); else nodes.back().lightConeAngle = fast_atof(c);
@ -797,7 +797,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// 'LightEdgeAngle': set area where we're smoothing from min to max intensity // 'LightEdgeAngle': set area where we're smoothing from min to max intensity
else if ((*it).tokens[0] == "LightEdgeAngle") { else if ((*it).tokens[0] == "LightEdgeAngle") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightEdgeAngle\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightEdgeAngle\'");
else nodes.back().lightEdgeAngle = fast_atof(c); else nodes.back().lightEdgeAngle = fast_atof(c);
@ -805,7 +805,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// 'LightColor': set color of currently active light // 'LightColor': set color of currently active light
else if ((*it).tokens[0] == "LightColor") { else if ((*it).tokens[0] == "LightColor") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightColor\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightColor\'");
else { else {
c = fast_atoreal_move<float>(c, (float&) nodes.back().lightColor.r ); c = fast_atoreal_move<float>(c, (float&) nodes.back().lightColor.r );
@ -819,7 +819,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// 'PivotPosition': position of local transformation origin // 'PivotPosition': position of local transformation origin
else if ((*it).tokens[0] == "PivotPosition" || (*it).tokens[0] == "PivotPoint") { else if ((*it).tokens[0] == "PivotPosition" || (*it).tokens[0] == "PivotPoint") {
if (nodes.empty()) if (nodes.empty())
DefaultLogger::get()->error("LWS: Unexpected keyword: \'PivotPosition\'"); ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'PivotPosition\'");
else { else {
c = fast_atoreal_move<float>(c, (float&) nodes.back().pivotPos.x ); c = fast_atoreal_move<float>(c, (float&) nodes.back().pivotPos.x );
SkipSpaces(&c); SkipSpaces(&c);
@ -840,7 +840,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (dit != it && *it == (*dit).parent) { if (dit != it && *it == (*dit).parent) {
if ((*dit).parent_resolved) { if ((*dit).parent_resolved) {
// fixme: it's still possible to produce an overflow due to cross references .. // fixme: it's still possible to produce an overflow due to cross references ..
DefaultLogger::get()->error("LWS: Found cross reference in scenegraph"); ASSIMP_LOG_ERROR("LWS: Found cross reference in scene-graph");
continue; continue;
} }

View File

@ -76,13 +76,13 @@ bool LimitBoneWeightsProcess::IsActive( unsigned int pFlags) const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void LimitBoneWeightsProcess::Execute( aiScene* pScene) void LimitBoneWeightsProcess::Execute( aiScene* pScene) {
{ ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess begin");
DefaultLogger::get()->debug("LimitBoneWeightsProcess begin"); for (unsigned int a = 0; a < pScene->mNumMeshes; ++a ) {
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
ProcessMesh(pScene->mMeshes[a]); ProcessMesh(pScene->mMeshes[a]);
}
DefaultLogger::get()->debug("LimitBoneWeightsProcess end"); ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess end");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -195,9 +195,7 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
} }
if (!DefaultLogger::isNullLogger()) { if (!DefaultLogger::isNullLogger()) {
char buffer[1024]; ASSIMP_LOG_INFO_F("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones );
ai_snprintf(buffer,1024,"Removed %u weights. Input bones: %u. Output bones: %u",removed,old_bones,pMesh->mNumBones);
DefaultLogger::get()->info(buffer);
} }
} }
} }

View File

@ -83,7 +83,7 @@ void MD2::LookupNormalIndex(uint8_t iNormalIndex,aiVector3D& vOut)
{ {
// make sure the normal index has a valid value // make sure the normal index has a valid value
if (iNormalIndex >= ARRAYSIZE(g_avNormals)) { if (iNormalIndex >= ARRAYSIZE(g_avNormals)) {
DefaultLogger::get()->warn("Index overflow in Quake II normal vector list"); ASSIMP_LOG_WARN("Index overflow in Quake II normal vector list");
iNormalIndex = ARRAYSIZE(g_avNormals) - 1; iNormalIndex = ARRAYSIZE(g_avNormals) - 1;
} }
vOut = *((const aiVector3D*)(&g_avNormals[iNormalIndex])); vOut = *((const aiVector3D*)(&g_avNormals[iNormalIndex]));
@ -161,7 +161,7 @@ void MD2Importer::ValidateHeader( )
// check file format version // check file format version
if (m_pcHeader->version != 8) if (m_pcHeader->version != 8)
DefaultLogger::get()->warn( "Unsupported md2 file version. Continuing happily ..."); ASSIMP_LOG_WARN( "Unsupported md2 file version. Continuing happily ...");
// check some values whether they are valid // check some values whether they are valid
if (0 == m_pcHeader->numFrames) if (0 == m_pcHeader->numFrames)
@ -203,11 +203,11 @@ void MD2Importer::ValidateHeader( )
} }
if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS) if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS)
DefaultLogger::get()->warn("The model contains more skins than Quake 2 supports"); ASSIMP_LOG_WARN("The model contains more skins than Quake 2 supports");
if ( m_pcHeader->numFrames > AI_MD2_MAX_FRAMES) if ( m_pcHeader->numFrames > AI_MD2_MAX_FRAMES)
DefaultLogger::get()->warn("The model contains more frames than Quake 2 supports"); ASSIMP_LOG_WARN("The model contains more frames than Quake 2 supports");
if (m_pcHeader->numVertices > AI_MD2_MAX_VERTS) if (m_pcHeader->numVertices > AI_MD2_MAX_VERTS)
DefaultLogger::get()->warn("The model contains more vertices than Quake 2 supports"); ASSIMP_LOG_WARN("The model contains more vertices than Quake 2 supports");
if (m_pcHeader->numFrames <= configFrameID ) if (m_pcHeader->numFrames <= configFrameID )
throw DeadlyImportError("The requested frame is not existing the file"); throw DeadlyImportError("The requested frame is not existing the file");
@ -352,7 +352,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0)); pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
} }
else{ else{
DefaultLogger::get()->warn("Texture file name has zero length. It will be skipped."); ASSIMP_LOG_WARN("Texture file name has zero length. It will be skipped.");
} }
} }
else { else {
@ -390,11 +390,11 @@ void MD2Importer::InternReadFile( const std::string& pFile,
// check whether the skin width or height are zero (this would // check whether the skin width or height are zero (this would
// cause a division through zero) // cause a division through zero)
if (!m_pcHeader->skinWidth) { if (!m_pcHeader->skinWidth) {
DefaultLogger::get()->error("MD2: No valid skin width given"); ASSIMP_LOG_ERROR("MD2: No valid skin width given");
} }
else fDivisorU = (float)m_pcHeader->skinWidth; else fDivisorU = (float)m_pcHeader->skinWidth;
if (!m_pcHeader->skinHeight){ if (!m_pcHeader->skinHeight){
DefaultLogger::get()->error("MD2: No valid skin height given"); ASSIMP_LOG_ERROR("MD2: No valid skin height given");
} }
else fDivisorV = (float)m_pcHeader->skinHeight; else fDivisorV = (float)m_pcHeader->skinHeight;
} }
@ -412,7 +412,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
// validate vertex indices // validate vertex indices
unsigned int iIndex = (unsigned int)pcTriangles[i].vertexIndices[c]; unsigned int iIndex = (unsigned int)pcTriangles[i].vertexIndices[c];
if (iIndex >= m_pcHeader->numVertices) { if (iIndex >= m_pcHeader->numVertices) {
DefaultLogger::get()->error("MD2: Vertex index is outside the allowed range"); ASSIMP_LOG_ERROR("MD2: Vertex index is outside the allowed range");
iIndex = m_pcHeader->numVertices-1; iIndex = m_pcHeader->numVertices-1;
} }
@ -440,7 +440,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
// validate texture coordinates // validate texture coordinates
iIndex = pcTriangles[i].textureIndices[c]; iIndex = pcTriangles[i].textureIndices[c];
if (iIndex >= m_pcHeader->numTexCoords) { if (iIndex >= m_pcHeader->numTexCoords) {
DefaultLogger::get()->error("MD2: UV index is outside the allowed range"); ASSIMP_LOG_ERROR("MD2: UV index is outside the allowed range");
iIndex = m_pcHeader->numTexCoords-1; iIndex = m_pcHeader->numTexCoords-1;
} }

View File

@ -101,7 +101,7 @@ Q3Shader::BlendFunc StringToBlendFunc(const std::string& m)
if (m == "GL_ONE_MINUS_DST_COLOR") { if (m == "GL_ONE_MINUS_DST_COLOR") {
return Q3Shader::BLEND_GL_ONE_MINUS_DST_COLOR; return Q3Shader::BLEND_GL_ONE_MINUS_DST_COLOR;
} }
DefaultLogger::get()->error("Q3Shader: Unknown blend function: " + m); ASSIMP_LOG_ERROR("Q3Shader: Unknown blend function: " + m);
return Q3Shader::BLEND_NONE; return Q3Shader::BLEND_NONE;
} }
@ -113,7 +113,7 @@ bool Q3Shader::LoadShader(ShaderData& fill, const std::string& pFile,IOSystem* i
if (!file.get()) if (!file.get())
return false; // if we can't access the file, don't worry and return return false; // if we can't access the file, don't worry and return
DefaultLogger::get()->info("Loading Quake3 shader file " + pFile); ASSIMP_LOG_INFO_F("Loading Quake3 shader file ", pFile);
// read file in memory // read file in memory
const size_t s = file->FileSize(); const size_t s = file->FileSize();
@ -136,7 +136,7 @@ bool Q3Shader::LoadShader(ShaderData& fill, const std::string& pFile,IOSystem* i
// append to last section, if any // append to last section, if any
if (!curData) { if (!curData) {
DefaultLogger::get()->error("Q3Shader: Unexpected shader section token \'{\'"); ASSIMP_LOG_ERROR("Q3Shader: Unexpected shader section token \'{\'");
return true; // still no failure, the file is there return true; // still no failure, the file is there
} }
@ -206,19 +206,16 @@ bool Q3Shader::LoadShader(ShaderData& fill, const std::string& pFile,IOSystem* i
SkipSpaces(&buff); SkipSpaces(&buff);
if (!ASSIMP_strincmp(buff,"back",4)) { if (!ASSIMP_strincmp(buff,"back",4)) {
curData->cull = Q3Shader::CULL_CCW; curData->cull = Q3Shader::CULL_CCW;
} } else if (!ASSIMP_strincmp(buff,"front",5)) {
else if (!ASSIMP_strincmp(buff,"front",5)) {
curData->cull = Q3Shader::CULL_CW; curData->cull = Q3Shader::CULL_CW;
} } else if (!ASSIMP_strincmp(buff,"none",4) || !ASSIMP_strincmp(buff,"disable",7)) {
else if (!ASSIMP_strincmp(buff,"none",4) || !ASSIMP_strincmp(buff,"disable",7)) {
curData->cull = Q3Shader::CULL_NONE; curData->cull = Q3Shader::CULL_NONE;
} } else {
else DefaultLogger::get()->error("Q3Shader: Unrecognized cull mode"); ASSIMP_LOG_ERROR("Q3Shader: Unrecognized cull mode");
} }
} }
} }
} else {
else {
// add new section // add new section
fill.blocks.push_back(Q3Shader::ShaderDataBlock()); fill.blocks.push_back(Q3Shader::ShaderDataBlock());
curData = &fill.blocks.back(); curData = &fill.blocks.back();
@ -238,7 +235,7 @@ bool Q3Shader::LoadSkin(SkinData& fill, const std::string& pFile,IOSystem* io)
if (!file.get()) if (!file.get())
return false; // if we can't access the file, don't worry and return return false; // if we can't access the file, don't worry and return
DefaultLogger::get()->info("Loading Quake3 skin file " + pFile); ASSIMP_LOG_INFO("Loading Quake3 skin file " + pFile);
// read file in memory // read file in memory
const size_t s = file->FileSize(); const size_t s = file->FileSize();
@ -397,7 +394,7 @@ void MD3Importer::ValidateHeaderOffsets()
// Check file format version // Check file format version
if (pcHeader->VERSION > 15) if (pcHeader->VERSION > 15)
DefaultLogger::get()->warn( "Unsupported MD3 file version. Continuing happily ..."); ASSIMP_LOG_WARN( "Unsupported MD3 file version. Continuing happily ...");
// Check some offset values whether they are valid // Check some offset values whether they are valid
if (!pcHeader->NUM_SURFACES) if (!pcHeader->NUM_SURFACES)
@ -438,25 +435,24 @@ void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
// Check whether all requirements for Q3 files are met. We don't // Check whether all requirements for Q3 files are met. We don't
// care, but probably someone does. // care, but probably someone does.
if (pcSurf->NUM_TRIANGLES > AI_MD3_MAX_TRIANGLES) { if (pcSurf->NUM_TRIANGLES > AI_MD3_MAX_TRIANGLES) {
DefaultLogger::get()->warn("MD3: Quake III triangle limit exceeded"); ASSIMP_LOG_WARN("MD3: Quake III triangle limit exceeded");
} }
if (pcSurf->NUM_SHADER > AI_MD3_MAX_SHADERS) { if (pcSurf->NUM_SHADER > AI_MD3_MAX_SHADERS) {
DefaultLogger::get()->warn("MD3: Quake III shader limit exceeded"); ASSIMP_LOG_WARN("MD3: Quake III shader limit exceeded");
} }
if (pcSurf->NUM_VERTICES > AI_MD3_MAX_VERTS) { if (pcSurf->NUM_VERTICES > AI_MD3_MAX_VERTS) {
DefaultLogger::get()->warn("MD3: Quake III vertex limit exceeded"); ASSIMP_LOG_WARN("MD3: Quake III vertex limit exceeded");
} }
if (pcSurf->NUM_FRAMES > AI_MD3_MAX_FRAMES) { if (pcSurf->NUM_FRAMES > AI_MD3_MAX_FRAMES) {
DefaultLogger::get()->warn("MD3: Quake III frame limit exceeded"); ASSIMP_LOG_WARN("MD3: Quake III frame limit exceeded");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiImporterDesc* MD3Importer::GetInfo () const const aiImporterDesc* MD3Importer::GetInfo () const {
{
return &desc; return &desc;
} }
@ -579,7 +575,7 @@ bool MD3Importer::ReadMultipartFile()
aiNode* tag_torso, *tag_head; aiNode* tag_torso, *tag_head;
std::vector<AttachmentInfo> attach; std::vector<AttachmentInfo> attach;
DefaultLogger::get()->info("Multi part MD3 player model: lower, upper and head parts are joined"); ASSIMP_LOG_INFO("Multi part MD3 player model: lower, upper and head parts are joined");
// ensure we won't try to load ourselves recursively // ensure we won't try to load ourselves recursively
BatchLoader::PropertyMap props; BatchLoader::PropertyMap props;
@ -600,21 +596,21 @@ bool MD3Importer::ReadMultipartFile()
// ... and get them. We need all of them. // ... and get them. We need all of them.
scene_lower = batch.GetImport(_lower); scene_lower = batch.GetImport(_lower);
if (!scene_lower) { if (!scene_lower) {
DefaultLogger::get()->error("M3D: Failed to read multi part model, lower.md3 fails to load"); ASSIMP_LOG_ERROR("M3D: Failed to read multi part model, lower.md3 fails to load");
failure = "lower"; failure = "lower";
goto error_cleanup; goto error_cleanup;
} }
scene_upper = batch.GetImport(_upper); scene_upper = batch.GetImport(_upper);
if (!scene_upper) { if (!scene_upper) {
DefaultLogger::get()->error("M3D: Failed to read multi part model, upper.md3 fails to load"); ASSIMP_LOG_ERROR("M3D: Failed to read multi part model, upper.md3 fails to load");
failure = "upper"; failure = "upper";
goto error_cleanup; goto error_cleanup;
} }
scene_head = batch.GetImport(_head); scene_head = batch.GetImport(_head);
if (!scene_head) { if (!scene_head) {
DefaultLogger::get()->error("M3D: Failed to read multi part model, head.md3 fails to load"); ASSIMP_LOG_ERROR("M3D: Failed to read multi part model, head.md3 fails to load");
failure = "head"; failure = "head";
goto error_cleanup; goto error_cleanup;
} }
@ -628,7 +624,7 @@ bool MD3Importer::ReadMultipartFile()
// tag_torso // tag_torso
tag_torso = scene_lower->mRootNode->FindNode("tag_torso"); tag_torso = scene_lower->mRootNode->FindNode("tag_torso");
if (!tag_torso) { if (!tag_torso) {
DefaultLogger::get()->error("M3D: Failed to find attachment tag for multi part model: tag_torso expected"); ASSIMP_LOG_ERROR("M3D: Failed to find attachment tag for multi part model: tag_torso expected");
goto error_cleanup; goto error_cleanup;
} }
scene_upper->mRootNode->mName.Set("upper"); scene_upper->mRootNode->mName.Set("upper");
@ -637,7 +633,7 @@ bool MD3Importer::ReadMultipartFile()
// tag_head // tag_head
tag_head = scene_upper->mRootNode->FindNode("tag_head"); tag_head = scene_upper->mRootNode->FindNode("tag_head");
if (!tag_head) { if (!tag_head) {
DefaultLogger::get()->error("M3D: Failed to find attachment tag for multi part model: tag_head expected"); ASSIMP_LOG_ERROR( "M3D: Failed to find attachment tag for multi part model: tag_head expected");
goto error_cleanup; goto error_cleanup;
} }
scene_head->mRootNode->mName.Set("head"); scene_head->mRootNode->mName.Set("head");
@ -890,7 +886,7 @@ void MD3Importer::InternReadFile( const std::string& pFile,
if (it != skins.textures.end()) { if (it != skins.textures.end()) {
texture_name = &*( _texture_name = (*it).second).begin(); texture_name = &*( _texture_name = (*it).second).begin();
DefaultLogger::get()->debug("MD3: Assigning skin texture " + (*it).second + " to surface " + pcSurfaces->NAME); ASSIMP_LOG_DEBUG_F("MD3: Assigning skin texture ", (*it).second, " to surface ", pcSurfaces->NAME);
(*it).resolved = true; // mark entry as resolved (*it).resolved = true; // mark entry as resolved
} }
@ -919,9 +915,10 @@ void MD3Importer::InternReadFile( const std::string& pFile,
if (dit != shaders.blocks.end()) { if (dit != shaders.blocks.end()) {
// Hurra, wir haben einen. Tolle Sache. // Hurra, wir haben einen. Tolle Sache.
shader = &*dit; shader = &*dit;
DefaultLogger::get()->info("Found shader record for " +without_ext ); ASSIMP_LOG_INFO("Found shader record for " +without_ext );
} else {
ASSIMP_LOG_WARN("Unable to find shader record for " + without_ext);
} }
else DefaultLogger::get()->warn("Unable to find shader record for " +without_ext );
} }
aiMaterial* pcHelper = new aiMaterial(); aiMaterial* pcHelper = new aiMaterial();
@ -950,7 +947,7 @@ void MD3Importer::InternReadFile( const std::string& pFile,
szString.Set(convertedPath); szString.Set(convertedPath);
} }
else { else {
DefaultLogger::get()->warn("Texture file name has zero length. Using default name"); ASSIMP_LOG_WARN("Texture file name has zero length. Using default name");
szString.Set("dummy_texture.bmp"); szString.Set("dummy_texture.bmp");
} }
pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0)); pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
@ -1040,7 +1037,7 @@ void MD3Importer::InternReadFile( const std::string& pFile,
if (!DefaultLogger::isNullLogger()) { if (!DefaultLogger::isNullLogger()) {
for (std::list< Q3Shader::SkinData::TextureEntry>::const_iterator it = skins.textures.begin();it != skins.textures.end(); ++it) { for (std::list< Q3Shader::SkinData::TextureEntry>::const_iterator it = skins.textures.begin();it != skins.textures.end(); ++it) {
if (!(*it).resolved) { if (!(*it).resolved) {
DefaultLogger::get()->error("MD3: Failed to match skin " + (*it).first + " to surface " + (*it).second); ASSIMP_LOG_ERROR_F("MD3: Failed to match skin ", (*it).first, " to surface ", (*it).second);
} }
} }
} }

View File

@ -359,7 +359,7 @@ void MD5Importer::LoadMD5MeshFile ()
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL || !file->FileSize()) { if( file.get() == NULL || !file->FileSize()) {
DefaultLogger::get()->warn("Failed to access MD5MESH file: " + pFile); ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + pFile);
return; return;
} }
bHadMD5Mesh = true; bHadMD5Mesh = true;
@ -482,7 +482,7 @@ void MD5Importer::LoadMD5MeshFile ()
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w) for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w)
fSum += meshSrc.mWeights[w].mWeight; fSum += meshSrc.mWeights[w].mWeight;
if (!fSum) { if (!fSum) {
DefaultLogger::get()->error("MD5MESH: The sum of all vertex bone weights is 0"); ASSIMP_LOG_ERROR("MD5MESH: The sum of all vertex bone weights is 0");
continue; continue;
} }
@ -574,7 +574,7 @@ void MD5Importer::LoadMD5AnimFile ()
// Check whether we can read from the file // Check whether we can read from the file
if( !file.get() || !file->FileSize()) { if( !file.get() || !file->FileSize()) {
DefaultLogger::get()->warn("Failed to read MD5ANIM file: " + pFile); ASSIMP_LOG_WARN("Failed to read MD5ANIM file: " + pFile);
return; return;
} }
LoadFileIntoMemory(file.get()); LoadFileIntoMemory(file.get());
@ -588,8 +588,7 @@ void MD5Importer::LoadMD5AnimFile ()
// generate and fill the output animation // generate and fill the output animation
if (animParser.mAnimatedBones.empty() || animParser.mFrames.empty() || if (animParser.mAnimatedBones.empty() || animParser.mFrames.empty() ||
animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) { animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) {
ASSIMP_LOG_ERROR("MD5ANIM: No frames or animated bones loaded");
DefaultLogger::get()->error("MD5ANIM: No frames or animated bones loaded");
} }
else { else {
bHadMD5Anim = true; bHadMD5Anim = true;

View File

@ -70,7 +70,7 @@ MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
fileSize = _fileSize; fileSize = _fileSize;
lineNumber = 0; lineNumber = 0;
DefaultLogger::get()->debug("MD5Parser begin"); ASSIMP_LOG_DEBUG("MD5Parser begin");
// parse the file header // parse the file header
ParseHeader(); ParseHeader();
@ -88,7 +88,7 @@ MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
if ( !DefaultLogger::isNullLogger()) { if ( !DefaultLogger::isNullLogger()) {
char szBuffer[128]; // should be sufficiently large char szBuffer[128]; // should be sufficiently large
::ai_snprintf(szBuffer,128,"MD5Parser end. Parsed %i sections",(int)mSections.size()); ::ai_snprintf(szBuffer,128,"MD5Parser end. Parsed %i sections",(int)mSections.size());
DefaultLogger::get()->debug(szBuffer); ASSIMP_LOG_DEBUG(szBuffer);
} }
} }
@ -107,7 +107,7 @@ MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
{ {
char szBuffer[1024]; char szBuffer[1024];
::sprintf(szBuffer,"[MD5] Line %u: %s",line,warn); ::sprintf(szBuffer,"[MD5] Line %u: %s",line,warn);
DefaultLogger::get()->warn(szBuffer); ASSIMP_LOG_WARN(szBuffer);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -130,7 +130,7 @@ void MD5Parser::ParseHeader()
// FIX: can break the log length limit, so we need to be careful // FIX: can break the log length limit, so we need to be careful
char* sz = buffer; char* sz = buffer;
while (!IsLineEnd( *buffer++)); while (!IsLineEnd( *buffer++));
DefaultLogger::get()->info(std::string(sz,std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer-sz)))); ASSIMP_LOG_INFO(std::string(sz,std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer-sz))));
SkipSpacesAndLineEnd(); SkipSpacesAndLineEnd();
} }
@ -243,7 +243,7 @@ bool MD5Parser::ParseSection(Section& out)
// .MD5MESH parsing function // .MD5MESH parsing function
MD5MeshParser::MD5MeshParser(SectionList& mSections) MD5MeshParser::MD5MeshParser(SectionList& mSections)
{ {
DefaultLogger::get()->debug("MD5MeshParser begin"); ASSIMP_LOG_DEBUG("MD5MeshParser begin");
// now parse all sections // now parse all sections
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter){ for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter){
@ -354,14 +354,14 @@ MD5MeshParser::MD5MeshParser(SectionList& mSections)
} }
} }
} }
DefaultLogger::get()->debug("MD5MeshParser end"); ASSIMP_LOG_DEBUG("MD5MeshParser end");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// .MD5ANIM parsing function // .MD5ANIM parsing function
MD5AnimParser::MD5AnimParser(SectionList& mSections) MD5AnimParser::MD5AnimParser(SectionList& mSections)
{ {
DefaultLogger::get()->debug("MD5AnimParser begin"); ASSIMP_LOG_DEBUG("MD5AnimParser begin");
fFrameRate = 24.0f; fFrameRate = 24.0f;
mNumAnimatedComponents = UINT_MAX; mNumAnimatedComponents = UINT_MAX;
@ -445,14 +445,14 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
fast_atoreal_move<float>((*iter).mGlobalValue.c_str(),fFrameRate); fast_atoreal_move<float>((*iter).mGlobalValue.c_str(),fFrameRate);
} }
} }
DefaultLogger::get()->debug("MD5AnimParser end"); ASSIMP_LOG_DEBUG("MD5AnimParser end");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// .MD5CAMERA parsing function // .MD5CAMERA parsing function
MD5CameraParser::MD5CameraParser(SectionList& mSections) MD5CameraParser::MD5CameraParser(SectionList& mSections)
{ {
DefaultLogger::get()->debug("MD5CameraParser begin"); ASSIMP_LOG_DEBUG("MD5CameraParser begin");
fFrameRate = 24.0f; fFrameRate = 24.0f;
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) { for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) {
@ -483,6 +483,6 @@ MD5CameraParser::MD5CameraParser(SectionList& mSections)
} }
} }
} }
DefaultLogger::get()->debug("MD5CameraParser end"); ASSIMP_LOG_DEBUG("MD5CameraParser end");
} }

View File

@ -159,8 +159,9 @@ void MDCImporter::ValidateHeader()
"magic word found is " + std::string( szBuffer )); "magic word found is " + std::string( szBuffer ));
} }
if (pcHeader->ulVersion != AI_MDC_VERSION) if (pcHeader->ulVersion != AI_MDC_VERSION) {
DefaultLogger::get()->warn("Unsupported MDC file version (2 (AI_MDC_VERSION) was expected)"); ASSIMP_LOG_WARN("Unsupported MDC file version (2 (AI_MDC_VERSION) was expected)");
}
if (pcHeader->ulOffsetBorderFrames + pcHeader->ulNumFrames * sizeof(MDC::Frame) > this->fileSize || if (pcHeader->ulOffsetBorderFrames + pcHeader->ulNumFrames * sizeof(MDC::Frame) > this->fileSize ||
pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize) pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize)
@ -169,9 +170,10 @@ void MDCImporter::ValidateHeader()
"and point to something behind the file."); "and point to something behind the file.");
} }
if (this->configFrameID >= this->pcHeader->ulNumFrames) if (this->configFrameID >= this->pcHeader->ulNumFrames) {
throw DeadlyImportError("The requested frame is not available"); throw DeadlyImportError("The requested frame is not available");
} }
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Validate the header of a given MDC file surface // Validate the header of a given MDC file surface
@ -388,7 +390,7 @@ void MDCImporter::InternReadFile(
uint32_t quak = pcTriangle->aiIndices[iIndex]; uint32_t quak = pcTriangle->aiIndices[iIndex];
if (quak >= pcSurface->ulNumVertices) if (quak >= pcSurface->ulNumVertices)
{ {
DefaultLogger::get()->error("MDC vertex index is out of range"); ASSIMP_LOG_ERROR("MDC vertex index is out of range");
quak = pcSurface->ulNumVertices-1; quak = pcSurface->ulNumVertices-1;
} }

View File

@ -141,7 +141,7 @@ void MDLImporter::SetupProperties(const Importer* pImp)
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0); configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
} }
// AI_CONFIG_IMPORT_MDL_COLORMAP - pallette file // AI_CONFIG_IMPORT_MDL_COLORMAP - palette file
configPalette = pImp->GetPropertyString(AI_CONFIG_IMPORT_MDL_COLORMAP,"colormap.lmp"); configPalette = pImp->GetPropertyString(AI_CONFIG_IMPORT_MDL_COLORMAP,"colormap.lmp");
} }
@ -187,37 +187,37 @@ void MDLImporter::InternReadFile( const std::string& pFile,
// Original Quake1 format // Original Quake1 format
if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) { if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) {
DefaultLogger::get()->debug("MDL subtype: Quake 1, magic word is IDPO"); ASSIMP_LOG_DEBUG("MDL subtype: Quake 1, magic word is IDPO");
iGSFileVersion = 0; iGSFileVersion = 0;
InternReadFile_Quake1(); InternReadFile_Quake1();
} }
// GameStudio A<old> MDL2 format - used by some test models that come with 3DGS // GameStudio A<old> MDL2 format - used by some test models that come with 3DGS
else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord) { else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord) {
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A2, magic word is MDL2"); ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A2, magic word is MDL2");
iGSFileVersion = 2; iGSFileVersion = 2;
InternReadFile_Quake1(); InternReadFile_Quake1();
} }
// GameStudio A4 MDL3 format // GameStudio A4 MDL3 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord) { else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord) {
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL3"); ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A4, magic word is MDL3");
iGSFileVersion = 3; iGSFileVersion = 3;
InternReadFile_3DGS_MDL345(); InternReadFile_3DGS_MDL345();
} }
// GameStudio A5+ MDL4 format // GameStudio A5+ MDL4 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord) { else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord) {
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL4"); ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A4, magic word is MDL4");
iGSFileVersion = 4; iGSFileVersion = 4;
InternReadFile_3DGS_MDL345(); InternReadFile_3DGS_MDL345();
} }
// GameStudio A5+ MDL5 format // GameStudio A5+ MDL5 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord) { else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord) {
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A5, magic word is MDL5"); ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A5, magic word is MDL5");
iGSFileVersion = 5; iGSFileVersion = 5;
InternReadFile_3DGS_MDL345(); InternReadFile_3DGS_MDL345();
} }
// GameStudio A7 MDL7 format // GameStudio A7 MDL7 format
else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord) { else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord) {
DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A7, magic word is MDL7"); ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A7, magic word is MDL7");
iGSFileVersion = 7; iGSFileVersion = 7;
InternReadFile_3DGS_MDL7(); InternReadFile_3DGS_MDL7();
} }
@ -225,7 +225,7 @@ void MDLImporter::InternReadFile( const std::string& pFile,
else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord || else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord) AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
{ {
DefaultLogger::get()->debug("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ"); ASSIMP_LOG_DEBUG("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ");
iGSFileVersion = 0; iGSFileVersion = 0;
InternReadFile_HL2(); InternReadFile_HL2();
} }
@ -258,7 +258,7 @@ void MDLImporter::SizeCheck(const void* szPos)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Just for debgging purposes // Just for debugging purposes
void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int iLine) void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int iLine)
{ {
ai_assert(NULL != szFile); ai_assert(NULL != szFile);
@ -298,20 +298,20 @@ void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader)
if (!this->iGSFileVersion) if (!this->iGSFileVersion)
{ {
if (pcHeader->num_verts > AI_MDL_MAX_VERTS) if (pcHeader->num_verts > AI_MDL_MAX_VERTS)
DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_VERTS vertices"); ASSIMP_LOG_WARN("Quake 1 MDL model has more than AI_MDL_MAX_VERTS vertices");
if (pcHeader->num_tris > AI_MDL_MAX_TRIANGLES) if (pcHeader->num_tris > AI_MDL_MAX_TRIANGLES)
DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_TRIANGLES triangles"); ASSIMP_LOG_WARN("Quake 1 MDL model has more than AI_MDL_MAX_TRIANGLES triangles");
if (pcHeader->num_frames > AI_MDL_MAX_FRAMES) if (pcHeader->num_frames > AI_MDL_MAX_FRAMES)
DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_FRAMES frames"); ASSIMP_LOG_WARN("Quake 1 MDL model has more than AI_MDL_MAX_FRAMES frames");
// (this does not apply for 3DGS MDLs) // (this does not apply for 3DGS MDLs)
if (!this->iGSFileVersion && pcHeader->version != AI_MDL_VERSION) if (!this->iGSFileVersion && pcHeader->version != AI_MDL_VERSION)
DefaultLogger::get()->warn("Quake 1 MDL model has an unknown version: AI_MDL_VERSION (=6) is " ASSIMP_LOG_WARN("Quake 1 MDL model has an unknown version: AI_MDL_VERSION (=6) is "
"the expected file format version"); "the expected file format version");
if(pcHeader->num_skins && (!pcHeader->skinwidth || !pcHeader->skinheight)) if(pcHeader->num_skins && (!pcHeader->skinwidth || !pcHeader->skinheight))
DefaultLogger::get()->warn("Skin width or height are 0"); ASSIMP_LOG_WARN("Skin width or height are 0");
} }
} }
@ -481,7 +481,7 @@ void MDLImporter::InternReadFile_Quake1() {
if (iIndex >= (unsigned int)pcHeader->num_verts) if (iIndex >= (unsigned int)pcHeader->num_verts)
{ {
iIndex = pcHeader->num_verts-1; iIndex = pcHeader->num_verts-1;
DefaultLogger::get()->warn("Index overflow in Q1-MDL vertex list."); ASSIMP_LOG_WARN("Index overflow in Q1-MDL vertex list.");
} }
aiVector3D& vec = pcMesh->mVertices[iCurrent]; aiVector3D& vec = pcMesh->mVertices[iCurrent];
@ -692,7 +692,7 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
unsigned int iIndex = pcTriangles->index_xyz[c]; unsigned int iIndex = pcTriangles->index_xyz[c];
if (iIndex >= (unsigned int)pcHeader->num_verts) { if (iIndex >= (unsigned int)pcHeader->num_verts) {
iIndex = pcHeader->num_verts-1; iIndex = pcHeader->num_verts-1;
DefaultLogger::get()->warn("Index overflow in MDLn vertex list"); ASSIMP_LOG_WARN("Index overflow in MDLn vertex list");
} }
aiVector3D& vec = pcMesh->mVertices[iCurrent]; aiVector3D& vec = pcMesh->mVertices[iCurrent];
@ -747,7 +747,7 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
unsigned int iIndex = pcTriangles->index_xyz[c]; unsigned int iIndex = pcTriangles->index_xyz[c];
if (iIndex >= (unsigned int)pcHeader->num_verts) { if (iIndex >= (unsigned int)pcHeader->num_verts) {
iIndex = pcHeader->num_verts-1; iIndex = pcHeader->num_verts-1;
DefaultLogger::get()->warn("Index overflow in MDLn vertex list"); ASSIMP_LOG_WARN("Index overflow in MDLn vertex list");
} }
aiVector3D& vec = pcMesh->mVertices[iCurrent]; aiVector3D& vec = pcMesh->mVertices[iCurrent];
@ -798,7 +798,7 @@ void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
// validate UV indices // validate UV indices
if (iIndex >= (unsigned int) pcHeader->synctype) { if (iIndex >= (unsigned int) pcHeader->synctype) {
iIndex = pcHeader->synctype-1; iIndex = pcHeader->synctype-1;
DefaultLogger::get()->warn("Index overflow in MDLn UV coord list"); ASSIMP_LOG_WARN("Index overflow in MDLn UV coord list");
} }
float s = (float)pcSrc[iIndex].u; float s = (float)pcSrc[iIndex].u;
@ -835,7 +835,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
iWidth = (unsigned int)*piPtr; iWidth = (unsigned int)*piPtr;
if (!iHeight || !iWidth) if (!iHeight || !iWidth)
{ {
DefaultLogger::get()->warn("Either the width or the height of the " ASSIMP_LOG_WARN("Either the width or the height of the "
"embedded DDS texture is zero. Unable to compute final texture " "embedded DDS texture is zero. Unable to compute final texture "
"coordinates. The texture coordinates remain in their original " "coordinates. The texture coordinates remain in their original "
"0-x/0-y (x,y = texture size) range."); "0-x/0-y (x,y = texture size) range.");
@ -988,7 +988,7 @@ MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size && AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size &&
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size) AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size)
{ {
DefaultLogger::get()->warn("Unknown size of bone data structure"); ASSIMP_LOG_WARN("Unknown size of bone data structure");
return NULL; return NULL;
} }
@ -1026,7 +1026,7 @@ void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
if(iIndex > (unsigned int)groupInfo.pcGroup->numverts) { if(iIndex > (unsigned int)groupInfo.pcGroup->numverts) {
// (we might need to read this section a second time - to process frame vertices correctly) // (we might need to read this section a second time - to process frame vertices correctly)
pcGroupTris->v_index[c] = iIndex = groupInfo.pcGroup->numverts-1; pcGroupTris->v_index[c] = iIndex = groupInfo.pcGroup->numverts-1;
DefaultLogger::get()->warn("Index overflow in MDL7 vertex list"); ASSIMP_LOG_WARN("Index overflow in MDL7 vertex list");
} }
// write the output face index // write the output face index
@ -1071,7 +1071,7 @@ void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
iIndex = pcGroupTris->skinsets[0].st_index[c]; iIndex = pcGroupTris->skinsets[0].st_index[c];
if(iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) { if(iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) {
iIndex = groupInfo.pcGroup->num_stpts-1; iIndex = groupInfo.pcGroup->num_stpts-1;
DefaultLogger::get()->warn("Index overflow in MDL7 UV coordinate list (#1)"); ASSIMP_LOG_WARN("Index overflow in MDL7 UV coordinate list (#1)");
} }
float u = groupInfo.pcGroupUVs[iIndex].u; float u = groupInfo.pcGroupUVs[iIndex].u;
@ -1098,7 +1098,7 @@ void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
iIndex = pcGroupTris->skinsets[1].st_index[c]; iIndex = pcGroupTris->skinsets[1].st_index[c];
if(iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) { if(iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) {
iIndex = groupInfo.pcGroup->num_stpts-1; iIndex = groupInfo.pcGroup->num_stpts-1;
DefaultLogger::get()->warn("Index overflow in MDL7 UV coordinate list (#2)"); ASSIMP_LOG_WARN("Index overflow in MDL7 UV coordinate list (#2)");
} }
float u = groupInfo.pcGroupUVs[ iIndex ].u; float u = groupInfo.pcGroupUVs[ iIndex ].u;
@ -1153,7 +1153,7 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
frame.pcFrame->transmatrix_count * pcHeader->bonetrans_stc_size; frame.pcFrame->transmatrix_count * pcHeader->bonetrans_stc_size;
if (((const char*)szCurrent - (const char*)pcHeader) + iAdd > (unsigned int)pcHeader->data_size) { if (((const char*)szCurrent - (const char*)pcHeader) + iAdd > (unsigned int)pcHeader->data_size) {
DefaultLogger::get()->warn("Index overflow in frame area. " ASSIMP_LOG_WARN("Index overflow in frame area. "
"Ignoring all frames and all further mesh groups, too."); "Ignoring all frames and all further mesh groups, too.");
// don't parse more groups if we can't even read one // don't parse more groups if we can't even read one
@ -1171,7 +1171,7 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
uint16_t iIndex = _AI_MDL7_ACCESS(pcFrameVertices,qq,pcHeader->framevertex_stc_size,MDL::Vertex_MDL7).vertindex; uint16_t iIndex = _AI_MDL7_ACCESS(pcFrameVertices,qq,pcHeader->framevertex_stc_size,MDL::Vertex_MDL7).vertindex;
AI_SWAP2(iIndex); AI_SWAP2(iIndex);
if (iIndex >= groupInfo.pcGroup->numverts) { if (iIndex >= groupInfo.pcGroup->numverts) {
DefaultLogger::get()->warn("Invalid vertex index in frame vertex section"); ASSIMP_LOG_WARN("Invalid vertex index in frame vertex section");
continue; continue;
} }
@ -1257,7 +1257,7 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
// sometimes MED writes -1, but normally only if there is only // sometimes MED writes -1, but normally only if there is only
// one skin assigned. No warning in this case // one skin assigned. No warning in this case
if(0xFFFFFFFF != groupData.pcFaces[iFace].iMatIndex[0]) if(0xFFFFFFFF != groupData.pcFaces[iFace].iMatIndex[0])
DefaultLogger::get()->warn("Index overflow in MDL7 material list [#0]"); ASSIMP_LOG_WARN("Index overflow in MDL7 material list [#0]");
} }
else splitGroupData.aiSplit[groupData.pcFaces[iFace]. else splitGroupData.aiSplit[groupData.pcFaces[iFace].
iMatIndex[0]]->push_back(iFace); iMatIndex[0]]->push_back(iFace);
@ -1282,7 +1282,7 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
// sometimes MED writes -1, but normally only if there is only // sometimes MED writes -1, but normally only if there is only
// one skin assigned. No warning in this case // one skin assigned. No warning in this case
if(UINT_MAX != iMatIndex) if(UINT_MAX != iMatIndex)
DefaultLogger::get()->warn("Index overflow in MDL7 material list [#1]"); ASSIMP_LOG_WARN("Index overflow in MDL7 material list [#1]");
iMatIndex = iNumMaterials-1; iMatIndex = iNumMaterials-1;
} }
unsigned int iMatIndex2 = groupData.pcFaces[iFace].iMatIndex[1]; unsigned int iMatIndex2 = groupData.pcFaces[iFace].iMatIndex[1];
@ -1292,7 +1292,7 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
if (iMatIndex2 >= iNumMaterials) { if (iMatIndex2 >= iNumMaterials) {
// sometimes MED writes -1, but normally only if there is only // sometimes MED writes -1, but normally only if there is only
// one skin assigned. No warning in this case // one skin assigned. No warning in this case
DefaultLogger::get()->warn("Index overflow in MDL7 material list [#2]"); ASSIMP_LOG_WARN("Index overflow in MDL7 material list [#2]");
iMatIndex2 = iNumMaterials-1; iMatIndex2 = iNumMaterials-1;
} }
@ -1414,7 +1414,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
if (1 != groupInfo.pcGroup->typ) { if (1 != groupInfo.pcGroup->typ) {
// Not a triangle-based mesh // Not a triangle-based mesh
DefaultLogger::get()->warn("[3DGS MDL7] Not a triangle mesh group. Continuing happily"); ASSIMP_LOG_WARN("[3DGS MDL7] Not a triangle mesh group. Continuing happily");
} }
// store the name of the group // store the name of the group
@ -1496,7 +1496,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
groupData.vTextureCoords1.resize(iNumVertices,aiVector3D()); groupData.vTextureCoords1.resize(iNumVertices,aiVector3D());
// check whether the triangle data structure is large enough // check whether the triangle data structure is large enough
// to contain a second UV coodinate set // to contain a second UV coordinate set
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) { if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
groupData.vTextureCoords2.resize(iNumVertices,aiVector3D()); groupData.vTextureCoords2.resize(iNumVertices,aiVector3D());
groupData.bNeed2UV = true; groupData.bNeed2UV = true;
@ -1516,7 +1516,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
sharedData.abNeedMaterials[qq] = true; sharedData.abNeedMaterials[qq] = true;
} }
} }
else DefaultLogger::get()->warn("[3DGS MDL7] Mesh group consists of 0 " else ASSIMP_LOG_WARN("[3DGS MDL7] Mesh group consists of 0 "
"vertices or faces. It will be skipped."); "vertices or faces. It will be skipped.");
// process all frames and generate output meshes // process all frames and generate output meshes
@ -1664,7 +1664,7 @@ void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
// read all transformation matrices // read all transformation matrices
for (unsigned int iTrafo = 0; iTrafo < frame.pcFrame->transmatrix_count;++iTrafo) { for (unsigned int iTrafo = 0; iTrafo < frame.pcFrame->transmatrix_count;++iTrafo) {
if(pcBoneTransforms->bone_index >= pcHeader->bones_num) { if(pcBoneTransforms->bone_index >= pcHeader->bones_num) {
DefaultLogger::get()->warn("Index overflow in frame area. " ASSIMP_LOG_WARN("Index overflow in frame area. "
"Unable to parse this bone transformation"); "Unable to parse this bone transformation");
} }
else { else {
@ -1676,7 +1676,7 @@ void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
} }
} }
else { else {
DefaultLogger::get()->warn("Ignoring animation keyframes in groups != 0"); ASSIMP_LOG_WARN("Ignoring animation keyframes in groups != 0");
} }
} }
} }
@ -1894,7 +1894,7 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
unsigned int iBone = groupData.aiBones[ oldFace.mIndices[c] ]; unsigned int iBone = groupData.aiBones[ oldFace.mIndices[c] ];
if (UINT_MAX != iBone) { if (UINT_MAX != iBone) {
if (iBone >= iNumOutBones) { if (iBone >= iNumOutBones) {
DefaultLogger::get()->error("Bone index overflow. " ASSIMP_LOG_ERROR("Bone index overflow. "
"The bone index of a vertex exceeds the allowed range. "); "The bone index of a vertex exceeds the allowed range. ");
iBone = iNumOutBones-1; iBone = iNumOutBones-1;
} }

View File

@ -64,7 +64,7 @@ using namespace Assimp;
static aiTexel* const bad_texel = reinterpret_cast<aiTexel*>(SIZE_MAX); static aiTexel* const bad_texel = reinterpret_cast<aiTexel*>(SIZE_MAX);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Find a suitable pallette file or take the default one // Find a suitable palette file or take the default one
void MDLImporter::SearchPalette(const unsigned char** pszColorMap) void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
{ {
// now try to find the color map in the current directory // now try to find the color map in the current directory
@ -75,10 +75,11 @@ void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
{ {
if (pcStream->FileSize() >= 768) if (pcStream->FileSize() >= 768)
{ {
unsigned char* colorMap = new unsigned char[256*3]; size_t len = 256 * 3;
unsigned char* colorMap = new unsigned char[len];
szColorMap = colorMap; szColorMap = colorMap;
pcStream->Read(colorMap,256*3,1); pcStream->Read(colorMap, len,1);
DefaultLogger::get()->info("Found valid colormap.lmp in directory. " ASSIMP_LOG_INFO("Found valid colormap.lmp in directory. "
"It will be used to decode embedded textures in palletized formats."); "It will be used to decode embedded textures in palletized formats.");
} }
delete pcStream; delete pcStream;
@ -186,7 +187,7 @@ void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
if (iType == 1 || iType > 3) if (iType == 1 || iType > 3)
{ {
DefaultLogger::get()->error("Unsupported texture file format"); ASSIMP_LOG_ERROR("Unsupported texture file format");
return; return;
} }
@ -508,7 +509,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
// ***** EMBEDDED DDS FILE ***** // ***** EMBEDDED DDS FILE *****
if (1 != iHeight) if (1 != iHeight)
{ {
DefaultLogger::get()->warn("Found a reference to an embedded DDS texture, " ASSIMP_LOG_WARN("Found a reference to an embedded DDS texture, "
"but texture height is not equal to 1, which is not supported by MED"); "but texture height is not equal to 1, which is not supported by MED");
} }
@ -531,7 +532,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
// ***** REFERENCE TO EXTERNAL FILE ***** // ***** REFERENCE TO EXTERNAL FILE *****
if (1 != iHeight) if (1 != iHeight)
{ {
DefaultLogger::get()->warn("Found a reference to an external texture, " ASSIMP_LOG_WARN("Found a reference to an external texture, "
"but texture height is not equal to 1, which is not supported by MED"); "but texture height is not equal to 1, which is not supported by MED");
} }
@ -552,7 +553,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
pcNew.reset(new aiTexture()); pcNew.reset(new aiTexture());
if (!iHeight || !iWidth) if (!iHeight || !iWidth)
{ {
DefaultLogger::get()->warn("Found embedded texture, but its width " ASSIMP_LOG_WARN("Found embedded texture, but its width "
"an height are both 0. Is this a joke?"); "an height are both 0. Is this a joke?");
// generate an empty chess pattern // generate an empty chess pattern

View File

@ -217,7 +217,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
pMesh->mNumFaces = indexCount / 3; pMesh->mNumFaces = indexCount / 3;
pMesh->mFaces = new aiFace[pMesh->mNumFaces]; pMesh->mFaces = new aiFace[pMesh->mNumFaces];
const int numIndices = 3; // trianglular face const int numIndices = 3; // triangular face
for (unsigned int index = 0; index < pMesh->mNumFaces; index++) { for (unsigned int index = 0; index < pMesh->mNumFaces; index++) {
pMesh->mFaces[index].mNumIndices = numIndices; pMesh->mFaces[index].mNumIndices = numIndices;
unsigned int *indices = new unsigned int[numIndices]; unsigned int *indices = new unsigned int[numIndices];

Some files were not shown because too many files have changed in this diff Show More