2
0
Эх сурвалжийг харах

Merge pull request #8 from assimp/master

Update from upstream master
ardenpm 5 жил өмнө
parent
commit
8a4c35598e
100 өөрчлөгдсөн 4362 нэмэгдсэн , 1566 устгасан
  1. 2 0
      .github/FUNDING.yml
  2. 8 0
      .gitignore
  3. 2 1
      .travis.sh
  4. 3 10
      .travis.yml
  5. 26 0
      BUILDBINARIES_EXAMPLE.bat
  6. 43 14
      Build.md
  7. 200 90
      CMakeLists.txt
  8. 7 4
      INSTALL
  9. 16 5
      Readme.md
  10. 14 5
      appveyor.yml
  11. 1 1
      assimp.pc.in
  12. 74 34
      assimpTargets-debug.cmake.in
  13. 74 33
      assimpTargets-release.cmake.in
  14. 5 1
      assimpTargets.cmake.in
  15. 7 3
      cmake-modules/Findassimp.cmake
  16. 540 0
      cmake/HunterGate.cmake
  17. 14 0
      cmake/assimp-hunter-config.cmake.in
  18. 2 2
      code/3DS/3DSConverter.cpp
  19. 7 5
      code/3DS/3DSExporter.cpp
  20. 1 1
      code/3DS/3DSExporter.h
  21. 1 1
      code/3DS/3DSHelper.h
  22. 10 10
      code/3DS/3DSLoader.cpp
  23. 1 1
      code/3DS/3DSLoader.h
  24. 1 1
      code/3MF/3MFXmlTags.h
  25. 6 2
      code/3MF/D3MFExporter.cpp
  26. 1 1
      code/3MF/D3MFExporter.h
  27. 3 3
      code/3MF/D3MFImporter.cpp
  28. 1 1
      code/3MF/D3MFImporter.h
  29. 207 0
      code/3MF/D3MFOpcPackage.cpp
  30. 4 5
      code/3MF/D3MFOpcPackage.h
  31. 2 2
      code/AC/ACLoader.cpp
  32. 1 1
      code/AC/ACLoader.h
  33. 2 2
      code/AMF/AMFImporter.cpp
  34. 1 1
      code/AMF/AMFImporter.hpp
  35. 1 1
      code/AMF/AMFImporter_Geometry.cpp
  36. 1 1
      code/AMF/AMFImporter_Macro.hpp
  37. 1 1
      code/AMF/AMFImporter_Material.cpp
  38. 1 1
      code/AMF/AMFImporter_Node.hpp
  39. 14 14
      code/AMF/AMFImporter_Postprocess.cpp
  40. 17 17
      code/ASE/ASELoader.cpp
  41. 1 2
      code/ASE/ASELoader.h
  42. 3 4
      code/ASE/ASEParser.cpp
  43. 7 7
      code/ASE/ASEParser.h
  44. 9 3
      code/Assbin/AssbinExporter.cpp
  45. 1 1
      code/Assbin/AssbinExporter.h
  46. 5 5
      code/Assbin/AssbinLoader.cpp
  47. 1 1
      code/Assbin/AssbinLoader.h
  48. 109 0
      code/Assjson/cencode.c
  49. 31 0
      code/Assjson/cencode.h
  50. 809 0
      code/Assjson/json_exporter.cpp
  51. 320 0
      code/Assjson/mesh_splitter.cpp
  52. 61 0
      code/Assjson/mesh_splitter.h
  53. 12 7
      code/Assxml/AssxmlExporter.cpp
  54. 1 1
      code/Assxml/AssxmlExporter.h
  55. 7 5
      code/B3D/B3DImporter.cpp
  56. 1 1
      code/B3D/B3DImporter.h
  57. 1 1
      code/BVH/BVHLoader.cpp
  58. 1 1
      code/BVH/BVHLoader.h
  59. 0 0
      code/Blender/BlenderBMesh.cpp
  60. 0 0
      code/Blender/BlenderBMesh.h
  61. 5 1
      code/Blender/BlenderCustomData.cpp
  62. 0 0
      code/Blender/BlenderCustomData.h
  63. 1 1
      code/Blender/BlenderDNA.cpp
  64. 2 2
      code/Blender/BlenderDNA.h
  65. 1 1
      code/Blender/BlenderDNA.inl
  66. 1 1
      code/Blender/BlenderIntermediate.h
  67. 28 1
      code/Blender/BlenderLoader.cpp
  68. 1 1
      code/Blender/BlenderLoader.h
  69. 1 1
      code/Blender/BlenderModifier.cpp
  70. 1 1
      code/Blender/BlenderModifier.h
  71. 4 1
      code/Blender/BlenderScene.cpp
  72. 5 1
      code/Blender/BlenderScene.h
  73. 0 0
      code/Blender/BlenderSceneGen.h
  74. 1 1
      code/Blender/BlenderTessellator.cpp
  75. 6 2
      code/Blender/BlenderTessellator.h
  76. 63 92
      code/C4D/C4DImporter.cpp
  77. 6 12
      code/C4D/C4DImporter.h
  78. 2 3
      code/CApi/AssimpCExport.cpp
  79. 1 1
      code/CApi/CInterfaceIOWrapper.cpp
  80. 1 1
      code/CApi/CInterfaceIOWrapper.h
  81. 637 466
      code/CMakeLists.txt
  82. 18 13
      code/COB/COBLoader.cpp
  83. 1 1
      code/COB/COBLoader.h
  84. 1 1
      code/COB/COBScene.h
  85. 1 1
      code/CSM/CSMLoader.cpp
  86. 1 1
      code/CSM/CSMLoader.h
  87. 81 52
      code/Collada/ColladaExporter.cpp
  88. 2 3
      code/Collada/ColladaExporter.h
  89. 3 7
      code/Collada/ColladaHelper.h
  90. 307 298
      code/Collada/ColladaLoader.cpp
  91. 6 6
      code/Collada/ColladaLoader.h
  92. 411 263
      code/Collada/ColladaParser.cpp
  93. 23 1
      code/Collada/ColladaParser.h
  94. 2 2
      code/Common/Assimp.cpp
  95. 31 4
      code/Common/BaseImporter.cpp
  96. 2 2
      code/Common/BaseProcess.cpp
  97. 1 1
      code/Common/BaseProcess.h
  98. 1 1
      code/Common/Bitmap.cpp
  99. 0 4
      code/Common/CreateAnimMesh.cpp
  100. 1 1
      code/Common/DefaultIOStream.cpp

+ 2 - 0
.github/FUNDING.yml

@@ -0,0 +1,2 @@
+patreon: assimp
+ko_fi: kimkulling

+ 8 - 0
.gitignore

@@ -7,6 +7,12 @@ build
 *.sln
 *.sln
 *.ncb
 *.ncb
 *.vcproj
 *.vcproj
+*.vcxproj.user
+*.VC.db
+*.VC.db-shm
+*.VC.db-wal
+*.VC.opendb
+*.ipch
 
 
 # Output
 # Output
 bin/
 bin/
@@ -17,6 +23,7 @@ CMakeLists.txt.user
 
 
 # Generated
 # Generated
 assimp.pc
 assimp.pc
+assimp.aps
 revision.h
 revision.h
 contrib/zlib/zconf.h
 contrib/zlib/zconf.h
 contrib/zlib/zlib.pc
 contrib/zlib/zlib.pc
@@ -31,6 +38,7 @@ cmake_uninstall.cmake
 *.dir/
 *.dir/
 assimp-config.cmake
 assimp-config.cmake
 assimp-config-version.cmake
 assimp-config-version.cmake
+assimpTargets*.cmake
 
 
 # MakeFile
 # MakeFile
 Makefile
 Makefile

+ 2 - 1
.travis.sh

@@ -7,7 +7,8 @@
 #
 #
 function generate() {
 function generate() {
     OPTIONS="-DASSIMP_WERROR=ON"
     OPTIONS="-DASSIMP_WERROR=ON"
-
+    OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=NO"
+    
     if [ "$DISABLE_EXPORTERS" = "YES" ] ; then
     if [ "$DISABLE_EXPORTERS" = "YES" ] ; then
         OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=YES"
         OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=YES"
     else
     else

+ 3 - 10
.travis.yml

@@ -27,16 +27,11 @@ compiler:
 
 
 env:
 env:
   global:
   global:
-  # COVERITY_SCAN_TOKEN
     - secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
     - secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
     - PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
     - PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
 
 
 matrix:
 matrix:
   include:
   include:
-    # disabled until clang 5.0 analyzer issues are fixed
-    # - os: linux
-    #   compiler: clang
-    #   env: ANALYZE=ON
     - os: linux
     - os: linux
       compiler: clang
       compiler: clang
       env: ASAN=ON
       env: ASAN=ON
@@ -51,7 +46,6 @@ matrix:
       env: ANALYZE=ON
       env: ANALYZE=ON
     - os: linux
     - os: linux
       compiler: gcc
       compiler: gcc
-#      env: DISABLE_EXPORTERS=YES ENABLE_COVERALLS=ON
       env: ENABLE_COVERALLS=ON
       env: ENABLE_COVERALLS=ON
     - os: linux
     - os: linux
       compiler: gcc
       compiler: gcc
@@ -61,8 +55,7 @@ install:
   - if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
   - if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
 
 
 before_script:
 before_script:
-  # init coverage to 0 (optional)
-  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && lcov --directory . --zerocounters ; fi
+  cmake . -DASSIMP_ENABLE_BOOST_WORKAROUND=YES
 
 
 script:
 script:
   - export COVERALLS_SERVICE_NAME=travis-ci
   - export COVERALLS_SERVICE_NAME=travis-ci
@@ -77,6 +70,6 @@ addons:
     project:
     project:
       name: "assimp/assimp"
       name: "assimp/assimp"
     notification_email: [email protected]
     notification_email: [email protected]
-    build_command_prepend: "cmake"
-    build_command: "make"
+    build_command_prepend: "cmake ./"
+    build_command: "make -j4"
     branch_pattern: coverity_scan
     branch_pattern: coverity_scan

+ 26 - 0
BUILDBINARIES_EXAMPLE.bat

@@ -0,0 +1,26 @@
+:: This is an example file to generate binaries using Windows Operating System
+:: This script is configured to be executed from the source directory
+
+:: Compiled binaries will be placed in BINARIES_DIR\code\CONFIG
+
+:: NOTE
+:: The build process will generate a config.h file that is placed in BINARIES_DIR\include
+:: This file must be merged with SOURCE_DIR\include
+:: You should write yourself a script that copies the files where you want them.
+:: Also see: https://github.com/assimp/assimp/pull/2646
+
+SET SOURCE_DIR=.
+
+:: For generators see "cmake --help"
+SET GENERATOR=Visual Studio 15 2017
+
+SET BINARIES_DIR="./BINARIES/Win32"
+cmake CMakeLists.txt -G "%GENERATOR%" -S %SOURCE_DIR% -B %BINARIES_DIR%
+cmake --build %BINARIES_DIR% --config release
+
+SET BINARIES_DIR="./BINARIES/x64"
+cmake CMakeLists.txt -G "%GENERATOR% Win64" -S %SOURCE_DIR% -B %BINARIES_DIR%
+cmake --build %BINARIES_DIR% --config debug
+cmake --build %BINARIES_DIR% --config release
+
+PAUSE

+ 43 - 14
Build.md

@@ -1,32 +1,46 @@
-# Install CMake
-Asset-Importer-Lib can be build for a lot of different platforms. We are using cmake to generate the build environment for these via cmake. So you have to make sure that you have a working cmake-installation on your system. You can download it at https://cmake.org/ or for linux install it via
+# Build Instructions
+
+## Build on all platforms using vcpkg
+You can download and install assimp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
+```bash
+    git clone https://github.com/Microsoft/vcpkg.git
+    cd vcpkg
+    ./bootstrap-vcpkg.sh
+    ./vcpkg integrate install
+    vcpkg install assimp
 ```
 ```
+The assimp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
+
+## Manual build instructions
+
+### Install CMake
+Asset-Importer-Lib can be build for a lot of different platforms. We are using cmake to generate the build environment for these via cmake. So you have to make sure that you have a working cmake-installation on your system. You can download it at https://cmake.org/ or for linux install it via
+```bash
 sudo apt-get install cmake
 sudo apt-get install cmake
 ```
 ```
 
 
-# Get the source
+### Get the source
 Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via:
 Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via:
-```
+```bash
 git clone https://github.com/assimp/assimp.git
 git clone https://github.com/assimp/assimp.git
 ```
 ```
 
 
-# Build instructions for Windows with Visual-Studio
+### Build instructions for Windows with Visual-Studio
 
 
 First you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/
 First you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/
 To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
 To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
-```
-> cmake CMakeLists.txt
+```bash
+cmake CMakeLists.txt
 ```
 ```
 This will generate the project files for the visual studio. All dependencies used to build Asset-IMporter-Lib shall be part of the repo. If you want to use you own zlib.installation this is possible as well. Check the options for it.
 This will generate the project files for the visual studio. All dependencies used to build Asset-IMporter-Lib shall be part of the repo. If you want to use you own zlib.installation this is possible as well. Check the options for it.
 
 
-# Build instructions for Windows with UWP
-See https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app
-
+### Build instructions for Windows with UWP
+See <https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app>
 
 
-# Build instrcutions for Linux / Unix
+### Build instructions for Linux / Unix
 Open a terminal and got to your repository. You can generate the makefiles and build the library via:
 Open a terminal and got to your repository. You can generate the makefiles and build the library via:
 
 
-```
+```bash
 cmake CMakeLists.txt
 cmake CMakeLists.txt
 make -j4
 make -j4
 ```
 ```
@@ -34,7 +48,23 @@ The option -j descripes the number of parallel processes for the build. In this
 
 
 If you want to use a IDE for linux you can try QTCreator for instance. 
 If you want to use a IDE for linux you can try QTCreator for instance. 
 
 
-# CMake build options
+### Build instructions for MinGW
+ Older versions of MinGW's compiler (e.g. 5.1.0) do not support the -mbig_obj flag 
+required to compile some of assimp's files, especially for debug builds.
+Version 7.3.0 of g++-mingw-w64 & gcc-mingw-w64 appears to work.
+
+Please see [CMake Cross Compiling](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling) for general information on CMake Toolchains.
+
+Some users have had success building assimp using MinGW on Linux using [polly](https://github.com/ruslo/polly/).
+
+The following toolchain, which is not maintained by assimp, seems to work on Linux: [linux-mingw-w64-gnuxx11.cmake](https://github.com/ruslo/polly/blob/master/linux-mingw-w64-gnuxx11.cmake)
+
+The following toolchain may or may not be helpful for building assimp using MinGW on Windows (untested):
+ [mingw-cxx17.cmake](https://github.com/ruslo/polly/blob/master/mingw-cxx17.cmake)
+
+Besides the toolchain, compilation should be the same as for Linux / Unix.
+
+### CMake build options
 The cmake-build-environment provides options to configure the build. The following options can be used:
 The cmake-build-environment provides options to configure the build. The following options can be used:
 - **BUILD_SHARED_LIBS ( default ON )**: Generation of shared libs ( dll for windows, so for Linux ). Set this to OFF to get a static lib.
 - **BUILD_SHARED_LIBS ( default ON )**: Generation of shared libs ( dll for windows, so for Linux ). Set this to OFF to get a static lib.
 - **BUILD_FRAMEWORK ( default OFF, MacOnly)**: Build package as Mac OS X Framework bundle
 - **BUILD_FRAMEWORK ( default OFF, MacOnly)**: Build package as Mac OS X Framework bundle
@@ -55,4 +85,3 @@ The cmake-build-environment provides options to configure the build. The followi
 - **INJECT_DEBUG_POSTFIX( default ON )**: Inject debug postfix in .a/.so lib names
 - **INJECT_DEBUG_POSTFIX( default ON )**: Inject debug postfix in .a/.so lib names
 - **IGNORE_GIT_HASH ( default OFF )**: Don't call git to get the hash.
 - **IGNORE_GIT_HASH ( default OFF )**: Don't call git to get the hash.
 - **ASSIMP_INSTALL_PDB ( default ON )**: Install MSVC debug files.
 - **ASSIMP_INSTALL_PDB ( default ON )**: Install MSVC debug files.
-

+ 200 - 90
CMakeLists.txt

@@ -1,7 +1,7 @@
 # Open Asset Import Library (assimp)
 # Open Asset Import Library (assimp)
 # ----------------------------------------------------------------------
 # ----------------------------------------------------------------------
-# Copyright (c) 2006-2018, assimp team
-
+# Copyright (c) 2006-2019, assimp team
+#
 # All rights reserved.
 # All rights reserved.
 #
 #
 # Redistribution and use of this software in source and binary forms,
 # Redistribution and use of this software in source and binary forms,
@@ -34,9 +34,24 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #----------------------------------------------------------------------
 #----------------------------------------------------------------------
-SET(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
-CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
-PROJECT( Assimp )
+SET(CMAKE_POLICY_DEFAULT_CMP0074 NEW)
+
+CMAKE_MINIMUM_REQUIRED( VERSION 3.0 )
+
+# Toggles the use of the hunter package manager
+option(HUNTER_ENABLED "Enable Hunter package manager support" OFF)
+
+include("cmake/HunterGate.cmake")
+HunterGate(
+    URL "https://github.com/ruslo/hunter/archive/v0.23.176.tar.gz"
+    SHA1 "2e9ae973d028660b735ac4c6142725ca36a0048a"
+)
+
+IF(HUNTER_ENABLED)
+  add_definitions(-DASSIMP_USE_HUNTER)
+ENDIF(HUNTER_ENABLED)
+
+PROJECT( Assimp VERSION 5.0.0 )
 
 
 # All supported options ###############################################
 # All supported options ###############################################
 
 
@@ -106,7 +121,7 @@ OPTION ( BUILD_DOCS
   OFF
   OFF
 )
 )
 OPTION( INJECT_DEBUG_POSTFIX
 OPTION( INJECT_DEBUG_POSTFIX
-  "Inject debug postfix in .a/.so lib names"
+  "Inject debug postfix in .a/.so/.dll lib names"
   ON
   ON
 )
 )
 
 
@@ -115,11 +130,12 @@ OPTION ( IGNORE_GIT_HASH
    OFF
    OFF
 )
 )
 
 
-IF (IOS)
+IF (IOS AND NOT HUNTER_ENABLED)
   IF (NOT CMAKE_BUILD_TYPE)
   IF (NOT CMAKE_BUILD_TYPE)
     SET(CMAKE_BUILD_TYPE "Release")
     SET(CMAKE_BUILD_TYPE "Release")
   ENDIF (NOT CMAKE_BUILD_TYPE)
   ENDIF (NOT CMAKE_BUILD_TYPE)
-ENDIF (IOS)
+  ADD_DEFINITIONS(-DENABLE_BITCODE)
+ENDIF (IOS AND NOT HUNTER_ENABLED)
 
 
 # Use subset of Windows.h
 # Use subset of Windows.h
 if (WIN32)
 if (WIN32)
@@ -131,6 +147,10 @@ IF(MSVC)
     "Install MSVC debug files."
     "Install MSVC debug files."
     ON
     ON
   )
   )
+  IF(NOT (MSVC_VERSION LESS 1900))
+    # Multibyte character set is deprecated since at least MSVC2015 (possibly earlier)
+    ADD_DEFINITIONS( -DUNICODE -D_UNICODE )
+  ENDIF()
 ENDIF(MSVC)
 ENDIF(MSVC)
 
 
 IF (BUILD_FRAMEWORK)
 IF (BUILD_FRAMEWORK)
@@ -146,17 +166,17 @@ ELSE()
 ENDIF(NOT BUILD_SHARED_LIBS)
 ENDIF(NOT BUILD_SHARED_LIBS)
 
 
 # Define here the needed parameters
 # Define here the needed parameters
-SET (ASSIMP_VERSION_MAJOR 4)
-SET (ASSIMP_VERSION_MINOR 1)
-SET (ASSIMP_VERSION_PATCH 0)
+SET (ASSIMP_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
+SET (ASSIMP_VERSION_MINOR ${PROJECT_VERSION_MINOR})
+SET (ASSIMP_VERSION_PATCH ${PROJECT_VERSION_PATCH})
 SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
 SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
-SET (ASSIMP_SOVERSION 4)
-SET (PROJECT_VERSION "${ASSIMP_VERSION}")
+SET (ASSIMP_SOVERSION 5)
 
 
 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" )
-
-# Enable C++1 globally
-set_property( GLOBAL PROPERTY CXX_STANDARD 11 )
+if(NOT HUNTER_ENABLED)
+  # Enable C++11 support globally
+  set_property( GLOBAL PROPERTY CXX_STANDARD 11 )
+endif()
 
 
 IF(NOT IGNORE_GIT_HASH)
 IF(NOT IGNORE_GIT_HASH)
   # Get the current working branch
   # Get the current working branch
@@ -196,8 +216,9 @@ CONFIGURE_FILE(
   ${CMAKE_CURRENT_BINARY_DIR}/include/assimp/config.h
   ${CMAKE_CURRENT_BINARY_DIR}/include/assimp/config.h
 )
 )
 
 
-INCLUDE_DIRECTORIES(
+INCLUDE_DIRECTORIES( BEFORE
   ./
   ./
+  code/
   include
   include
   ${CMAKE_CURRENT_BINARY_DIR}
   ${CMAKE_CURRENT_BINARY_DIR}
   ${CMAKE_CURRENT_BINARY_DIR}/include
   ${CMAKE_CURRENT_BINARY_DIR}/include
@@ -216,9 +237,13 @@ ENDIF( UNIX )
 
 
 # Grouped compiler settings
 # Grouped compiler settings
 IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
 IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
+  IF(NOT HUNTER_ENABLED)
+    SET(CMAKE_CXX_FLAGS "-fPIC -std=c++0x ${CMAKE_CXX_FLAGS}")
+    SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
+  ENDIF()
   # hide all not-exported symbols
   # hide all not-exported symbols
-  SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fPIC -fno-strict-aliasing -Wall -std=c++0x ${CMAKE_CXX_FLAGS}")
-  SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS}")
+  SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
+  SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
   SET(LIBSTDC++_LIBRARIES -lstdc++)
   SET(LIBSTDC++_LIBRARIES -lstdc++)
 ELSEIF(MSVC)
 ELSEIF(MSVC)
   # enable multi-core compilation with MSVC
   # enable multi-core compilation with MSVC
@@ -228,26 +253,39 @@ ELSEIF(MSVC)
   IF(MSVC12)
   IF(MSVC12)
     ADD_COMPILE_OPTIONS(/wd4351)
     ADD_COMPILE_OPTIONS(/wd4351)
   ENDIF()
   ENDIF()
+  SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2 /DEBUG:FULL /Zi")
 ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
 ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
-  SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fPIC -fno-strict-aliasing -Wall -Wno-long-long -std=c++11 ${CMAKE_CXX_FLAGS}" )
-  SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS}")
+  IF(NOT HUNTER_ENABLED)
+    SET(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}")
+    SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
+  ENDIF()
+  SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
+  SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
 ELSEIF( CMAKE_COMPILER_IS_MINGW )
 ELSEIF( CMAKE_COMPILER_IS_MINGW )
-  SET( CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -std=c++11 -Wa,-mbig-obj ${CMAKE_CXX_FLAGS}" )
-  SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS} ")
+  IF (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
+    message(FATAL_ERROR "MinGW is too old to be supported. Please update MinGW and try again.")
+  ELSEIF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.3)
+    message(WARNING "MinGW is old, if you experience errors, update MinGW.")
+  ENDIF()
+  IF(NOT HUNTER_ENABLED)
+    SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
+    SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
+  ENDIF()
+  SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
+  SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
   ADD_DEFINITIONS( -U__STRICT_ANSI__ )
   ADD_DEFINITIONS( -U__STRICT_ANSI__ )
 ENDIF()
 ENDIF()
 
 
-IF ( IOS )
-
-IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
-  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
-ELSE()
-  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
-ENDIF()
-
-ENDIF( IOS )
+IF ( IOS AND NOT HUNTER_ENABLED)
+  IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
+  ELSE()
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
+    # Experimental for pdb generation
+  ENDIF()
+ENDIF( IOS AND NOT HUNTER_ENABLED)
 
 
 IF (ASSIMP_COVERALLS)
 IF (ASSIMP_COVERALLS)
   MESSAGE(STATUS "Coveralls enabled")
   MESSAGE(STATUS "Coveralls enabled")
@@ -299,7 +337,9 @@ SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE STRING
 SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE STRING
 SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE STRING
   "Path the tool executables are installed to." )
   "Path the tool executables are installed to." )
 
 
-IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
+get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
+
+IF (INJECT_DEBUG_POSTFIX AND (is_multi_config OR CMAKE_BUILD_TYPE STREQUAL "Debug"))
   SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfix for lib, samples and tools")
   SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfix for lib, samples and tools")
 ELSE()
 ELSE()
   SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING "Debug Postfix for lib, samples and tools")
   SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING "Debug Postfix for lib, samples and tools")
@@ -312,20 +352,67 @@ IF (NOT TARGET uninstall)
   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
-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}/assimpTargets.cmake.in"         "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets.cmake" @ONLY IMMEDIATE)
-CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-debug.cmake.in"   "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake" @ONLY IMMEDIATE)
-CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-release.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake" @ONLY IMMEDIATE)
-CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
-#we should generated these scripts after CMake VERSION 3.0.2 using export(EXPORT ...) and write_basic_package_version_file(...)
-INSTALL(FILES 
-  "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake"
-  "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake"
-  "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets.cmake"
-  "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake"
-  "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake"
-  DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
+IF(HUNTER_ENABLED)
+  set(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
+  set(INCLUDE_INSTALL_DIR "include")
+
+  set(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
+
+  # Configuration
+  set(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
+  set(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
+  set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
+  set(NAMESPACE "${PROJECT_NAME}::")
+
+  # Include module with fuction 'write_basic_package_version_file'
+  include(CMakePackageConfigHelpers)
+
+  # Note: PROJECT_VERSION is used as a VERSION
+  write_basic_package_version_file("${VERSION_CONFIG}" COMPATIBILITY SameMajorVersion)
+
+  # Use variables:
+  #   * TARGETS_EXPORT_NAME
+  #   * PROJECT_NAME
+  configure_package_config_file(
+      "cmake/assimp-hunter-config.cmake.in"
+      "${PROJECT_CONFIG}"
+      INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}"
+  )
+
+  install(
+      FILES "${PROJECT_CONFIG}" "${VERSION_CONFIG}"
+      DESTINATION "${CONFIG_INSTALL_DIR}"
+  )
+
+  install(
+      EXPORT "${TARGETS_EXPORT_NAME}"
+      NAMESPACE "${NAMESPACE}"
+      DESTINATION "${CONFIG_INSTALL_DIR}"
+  )
+ELSE(HUNTER_ENABLED)
+  # 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}/assimpTargets.cmake.in"         "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets.cmake" @ONLY IMMEDIATE)
+  IF (is_multi_config)
+    CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-debug.cmake.in"   "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake" @ONLY IMMEDIATE)
+    CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-release.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake" @ONLY IMMEDIATE)
+    SET(PACKAGE_TARGETS_FILE "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake")
+  ELSEIF (CMAKE_BUILD_TYPE STREQUAL Debug)
+    CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-debug.cmake.in"   "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake" @ONLY IMMEDIATE)
+    SET(PACKAGE_TARGETS_FILE "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake")
+  ELSE()
+    CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-release.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake" @ONLY IMMEDIATE)
+    SET(PACKAGE_TARGETS_FILE "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake")
+  ENDIF()
+  CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
+  #we should generated these scripts after CMake VERSION 3.0.2 using export(EXPORT ...) and write_basic_package_version_file(...)
+  INSTALL(FILES
+    "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake"
+    "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake"
+    "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets.cmake"
+    ${PACKAGE_TARGETS_FILE}
+    DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
+ENDIF(HUNTER_ENABLED)
 
 
 FIND_PACKAGE( DirectX )
 FIND_PACKAGE( DirectX )
 
 
@@ -340,39 +427,57 @@ 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 )
-  FIND_PACKAGE(ZLIB)
-ENDIF( NOT ASSIMP_BUILD_ZLIB )
-
-IF( NOT ZLIB_FOUND )
-  MESSAGE(STATUS "compiling zlib from sources")
-  INCLUDE(CheckIncludeFile)
-  INCLUDE(CheckTypeSize)
-  INCLUDE(CheckFunctionExists)
-  # compile from sources
-  ADD_SUBDIRECTORY(contrib/zlib)
-  SET(ZLIB_FOUND 1)
-  SET(ZLIB_LIBRARIES zlibstatic)
-  SET(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
-  # need to ensure we don't link with system zlib or minizip as well.
-  SET(ASSIMP_BUILD_MINIZIP 1)
-ELSE(NOT ZLIB_FOUND)
-  ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
-  SET(ZLIB_LIBRARIES_LINKED -lz)
-ENDIF(NOT ZLIB_FOUND)
-INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
-
-# Search for unzip
-IF ( NOT IOS )
+IF(HUNTER_ENABLED)
+  hunter_add_package(ZLIB)
+  find_package(ZLIB CONFIG REQUIRED)
+
+  add_definitions(-DASSIMP_BUILD_NO_OWN_ZLIB)
+  set(ZLIB_FOUND TRUE)
+  set(ZLIB_LIBRARIES ZLIB::zlib)
+  set(ASSIMP_BUILD_MINIZIP TRUE)
+ELSE(HUNTER_ENABLED)
+  IF ( NOT ASSIMP_BUILD_ZLIB )
+    FIND_PACKAGE(ZLIB)
+  ENDIF( NOT ASSIMP_BUILD_ZLIB )
+
+  IF( NOT ZLIB_FOUND )
+    MESSAGE(STATUS "compiling zlib from sources")
+    INCLUDE(CheckIncludeFile)
+    INCLUDE(CheckTypeSize)
+    INCLUDE(CheckFunctionExists)
+
+    # Explicitly turn off ASM686 and AMD64 cmake options.
+    # The AMD64 option causes a build failure on MSVC and the ASM builds seem to have problems:
+    #		https://github.com/madler/zlib/issues/41#issuecomment-125848075
+    # Also prevents these options from "polluting" the cmake options if assimp is being
+    # included as a submodule.
+    set( ASM686 FALSE CACHE INTERNAL "Override ZLIB flag to turn off assembly" FORCE )
+    set( AMD64 FALSE CACHE INTERNAL "Override ZLIB flag to turn off assembly" FORCE )
+
+    # compile from sources
+    ADD_SUBDIRECTORY(contrib/zlib)
+    SET(ZLIB_FOUND 1)
+    SET(ZLIB_LIBRARIES zlibstatic)
+    SET(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
+    # need to ensure we don't link with system zlib or minizip as well.
+    SET(ASSIMP_BUILD_MINIZIP 1)
+  ELSE(NOT ZLIB_FOUND)
+    ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
+    SET(ZLIB_LIBRARIES_LINKED -lz)
+  ENDIF(NOT ZLIB_FOUND)
+  INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
+ENDIF(HUNTER_ENABLED)
+
+IF( NOT IOS )
   IF( NOT ASSIMP_BUILD_MINIZIP )
   IF( NOT ASSIMP_BUILD_MINIZIP )
-	  use_pkgconfig(UNZIP minizip)
+    use_pkgconfig(UNZIP minizip)
   ENDIF( NOT ASSIMP_BUILD_MINIZIP )
   ENDIF( NOT ASSIMP_BUILD_MINIZIP )
 ELSE ( NOT IOS )
 ELSE ( NOT IOS )
-	IF(NOT BUILD_SHARED_LIBS)
+  IF( NOT BUILD_SHARED_LIBS )
     IF( NOT ASSIMP_BUILD_MINIZIP )
     IF( NOT ASSIMP_BUILD_MINIZIP )
-		  use_pkgconfig(UNZIP minizip)
+      use_pkgconfig(UNZIP minizip)
     ENDIF( NOT ASSIMP_BUILD_MINIZIP )
     ENDIF( NOT ASSIMP_BUILD_MINIZIP )
-	ENDIF (NOT BUILD_SHARED_LIBS)
+  ENDIF ( NOT BUILD_SHARED_LIBS )
 ENDIF ( NOT IOS )
 ENDIF ( NOT IOS )
 
 
 IF ( ASSIMP_NO_EXPORT )
 IF ( ASSIMP_NO_EXPORT )
@@ -446,26 +551,27 @@ ELSE (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
   ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
   ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
 ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
 ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
 
 
-ADD_SUBDIRECTORY(contrib)
+IF(NOT HUNTER_ENABLED)
+  ADD_SUBDIRECTORY(contrib)
+ENDIF(NOT HUNTER_ENABLED)
 
 
 ADD_SUBDIRECTORY( code/ )
 ADD_SUBDIRECTORY( code/ )
 IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
 IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
+  # The viewer for windows only
   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 )
-
+  # Te command line tool
   ADD_SUBDIRECTORY( tools/assimp_cmd/ )
   ADD_SUBDIRECTORY( tools/assimp_cmd/ )
-IF (NOT IOS)
-  ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
-ENDIF (NOT IOS)
 ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
 ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
 
 
 IF ( ASSIMP_BUILD_SAMPLES)
 IF ( ASSIMP_BUILD_SAMPLES)
   IF ( WIN32 )
   IF ( WIN32 )
     ADD_SUBDIRECTORY( samples/SimpleTexturedOpenGL/ )
     ADD_SUBDIRECTORY( samples/SimpleTexturedOpenGL/ )
+    ADD_SUBDIRECTORY( samples/SimpleTexturedDirectx11 )
   ENDIF ( WIN32 )
   ENDIF ( WIN32 )
   ADD_SUBDIRECTORY( samples/SimpleOpenGL/ )
   ADD_SUBDIRECTORY( samples/SimpleOpenGL/ )
 ENDIF ( ASSIMP_BUILD_SAMPLES )
 ENDIF ( ASSIMP_BUILD_SAMPLES )
@@ -531,18 +637,22 @@ if(WIN32)
   if (CMAKE_SIZEOF_VOID_P EQUAL 8)
   if (CMAKE_SIZEOF_VOID_P EQUAL 8)
     SET(BIN_DIR "${PROJECT_SOURCE_DIR}/bin64/")
     SET(BIN_DIR "${PROJECT_SOURCE_DIR}/bin64/")
     SET(LIB_DIR "${PROJECT_SOURCE_DIR}/lib64/")
     SET(LIB_DIR "${PROJECT_SOURCE_DIR}/lib64/")
-  elseif()
+  else()
     SET(BIN_DIR "${PROJECT_SOURCE_DIR}/bin32/")
     SET(BIN_DIR "${PROJECT_SOURCE_DIR}/bin32/")
     SET(LIB_DIR "${PROJECT_SOURCE_DIR}/lib32/")
     SET(LIB_DIR "${PROJECT_SOURCE_DIR}/lib32/")
   ENDIF()
   ENDIF()
 
 
-  IF(MSVC12)
-    SET(ASSIMP_MSVC_VERSION "vc120")
-  ELSEIF(MSVC14)
-    SET(ASSIMP_MSVC_VERSION "vc140")
-  ELSEIF(MSVC15)
-    SET(ASSIMP_MSVC_VERSION "vc141")
-  ENDIF(MSVC12)
+  IF(MSVC_TOOLSET_VERSION)
+    set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
+  ELSE()
+    IF(MSVC12)
+      SET(ASSIMP_MSVC_VERSION "vc120")
+    ELSEIF(MSVC14)
+      SET(ASSIMP_MSVC_VERSION "vc140")
+    ELSEIF(MSVC15)
+      SET(ASSIMP_MSVC_VERSION "vc141")
+    ENDIF(MSVC12)
+  ENDIF()
 
 
   IF(MSVC12 OR MSVC14 OR MSVC15 )
   IF(MSVC12 OR MSVC14 OR MSVC15 )
     ADD_CUSTOM_TARGET(UpdateAssimpLibsDebugSymbolsAndDLLs COMMENT "Copying Assimp Libraries ..." VERBATIM)
     ADD_CUSTOM_TARGET(UpdateAssimpLibsDebugSymbolsAndDLLs COMMENT "Copying Assimp Libraries ..." VERBATIM)

+ 7 - 4
INSTALL

@@ -35,13 +35,16 @@ http://www.cmake.org/.
 
 
 For Unix:
 For Unix:
 
 
-1. cmake CMakeLists.txt -G 'Unix Makefiles'
-2. make
+1. mkdir build && cd build
+2. cmake .. -G 'Unix Makefiles'
+3. make -j4
 
 
 For Windows:
 For Windows:
 1. Open a command prompt
 1. Open a command prompt
-2. cmake CMakeLists.txt
-2. Open your default IDE and build it
+2. mkdir build
+3. cd build
+4. cmake ..
+5. cmake --build .
 
 
 For iOS:
 For iOS:
 Just check the following project, which deploys a compiler toolchain for different iOS-versions: https://github.com/assimp/assimp/tree/master/port/iOS
 Just check the following project, which deploys a compiler toolchain for different iOS-versions: https://github.com/assimp/assimp/tree/master/port/iOS

+ 16 - 5
Readme.md

@@ -1,7 +1,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ==================================
 ==================================
 A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
 A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
-### Current build status ###
+### Current project status ###
 [![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
 [![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
 [![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
 [![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
 <a href="https://scan.coverity.com/projects/5607">
 <a href="https://scan.coverity.com/projects/5607">
@@ -10,10 +10,15 @@ A library to import and export various 3d-model-formats including scene-post-pro
 </a>
 </a>
 [![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
 [![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
 [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
+[![Codacy Badge](https://api.codacy.com/project/badge/Grade/5be56faac64f46fc941ac890fb4febef)](https://www.codacy.com/app/kimkulling/assimp?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
+[![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
 <br>
 <br>
 
 
 APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
 APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
 
 
+[Check the latest doc](https://assimp-docs.readthedocs.io/en/latest/).
+
 Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
 Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
 
 
 This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
 This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
@@ -96,7 +101,7 @@ __Importers__:
 
 
 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://en.wikipedia.org/wiki/Cinema_4D) (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange)
+- [C4D](https://en.wikipedia.org/wiki/Cinema_4D) (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange) IMporting geometry + node hierarchy are currently supported
 
 
 __Exporters__:
 __Exporters__:
 
 
@@ -115,22 +120,23 @@ __Exporters__:
 - FBX ( experimental )
 - FBX ( experimental )
 
 
 ### Building ###
 ### Building ###
-Take a look into the https://github.com/assimp/assimp/blob/master/Build.md 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 https://github.com/assimp/assimp/blob/master/Build.md file. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
 
 
 ### Ports ###
 ### Ports ###
 * [Android](port/AndroidJNI/README.md)
 * [Android](port/AndroidJNI/README.md)
 * [Python](port/PyAssimp/README.md)
 * [Python](port/PyAssimp/README.md)
-* [.NET](port/AssimpNET/Readme.md)
+* [.NET](https://github.com/kebby/assimp-net)
 * [Pascal](port/AssimpPascal/Readme.md)
 * [Pascal](port/AssimpPascal/Readme.md)
 * [Javascript (Alpha)](https://github.com/makc/assimp2json)
 * [Javascript (Alpha)](https://github.com/makc/assimp2json)
 * [Unity 3d Plugin](https://www.assetstore.unity3d.com/en/#!/content/91777)
 * [Unity 3d Plugin](https://www.assetstore.unity3d.com/en/#!/content/91777)
 * [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status))
 * [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status))
+* [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port.
 
 
 ### Other tools ###
 ### Other tools ###
 [open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
 [open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
 
 
 #### Repository structure ####
 #### Repository structure ####
-Open Asset Import Library is implemented in C++. The directory structure is:
+Open Asset Import Library is implemented in C++. The directory structure looks like:
 
 
 	/code		Source code
 	/code		Source code
 	/contrib	Third-party libraries
 	/contrib	Third-party libraries
@@ -143,6 +149,11 @@ Open Asset Import Library is implemented in C++. The directory structure is:
 	/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
 
 
+The source code is organized in the following way:
+
+	code/Common		The base implementation for importers and the infrastructure
+	code/PostProcessing	The post-processing steps
+	code/<FormatName>	Implementation for import and export for the format
 
 
 ### Where to get help ###
 ### Where to get help ###
 For more information, visit [our website](http://assimp.org/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
 For more information, visit [our website](http://assimp.org/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.

+ 14 - 5
appveyor.yml

@@ -14,9 +14,10 @@ matrix:
   fast_finish: true
   fast_finish: true
     
     
 image:
 image:
-  - Visual Studio 2013
   - Visual Studio 2015
   - Visual Studio 2015
   - Visual Studio 2017
   - Visual Studio 2017
+  - Visual Studio 2019
+  - MinGW  
     
     
 platform:
 platform:
   - Win32
   - Win32
@@ -27,11 +28,13 @@ configuration: Release
 install:
 install:
   - set PATH=C:\Ruby24-x64\bin;%PATH%
   - set PATH=C:\Ruby24-x64\bin;%PATH%
   - set CMAKE_DEFINES -DASSIMP_WERROR=ON
   - set CMAKE_DEFINES -DASSIMP_WERROR=ON
-  - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2013" set CMAKE_GENERATOR_NAME=Visual Studio 12 2013
+  - if [%COMPILER%]==[MinGW] set PATH=C:\MinGW\bin;%PATH%
   - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
   - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
   - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017
   - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017
-  - if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64
-  - cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%"
+  - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2019" set CMAKE_GENERATOR_NAME=Visual Studio 16 2019
+  - cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%" -A %platform% .
+  # Rename sh.exe as sh.exe in PATH interferes with MinGW
+  - rename "C:\Program Files\Git\usr\bin\sh.exe" "sh2.exe"
   - set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5"
   - set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5"
   - ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/5/7/b/57b2947c-7221-4f33-b35e-2fc78cb10df4/vc_redist.x64.exe -OutFile .\packaging\windows-innosetup\vc_redist.x64.exe
   - ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/5/7/b/57b2947c-7221-4f33-b35e-2fc78cb10df4/vc_redist.x64.exe -OutFile .\packaging\windows-innosetup\vc_redist.x64.exe
   - ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/1/d/8/1d8137db-b5bb-4925-8c5d-927424a2e4de/vc_redist.x86.exe -OutFile .\packaging\windows-innosetup\vc_redist.x86.exe
   - ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/1/d/8/1d8137db-b5bb-4925-8c5d-927424a2e4de/vc_redist.x86.exe -OutFile .\packaging\windows-innosetup\vc_redist.x86.exe
@@ -53,7 +56,13 @@ build:
   project: Assimp.sln
   project: Assimp.sln
   
   
 after_build:
 after_build:
-  - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" iscc packaging\windows-innosetup\script.iss
+  - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" (
+        if "%platform%"=="x64" (
+            iscc packaging\windows-innosetup\script_x64.iss
+        ) else (
+            iscc packaging\windows-innosetup\script_x86.iss
+        )
+    )
   - 7z a assimp.7z bin\%CONFIGURATION%\* lib\%CONFIGURATION%\*
   - 7z a assimp.7z bin\%CONFIGURATION%\* lib\%CONFIGURATION%\*
 
 
 test_script:
 test_script:

+ 1 - 1
assimp.pc.in

@@ -1,7 +1,7 @@
 prefix=@CMAKE_INSTALL_PREFIX@
 prefix=@CMAKE_INSTALL_PREFIX@
 exec_prefix=@CMAKE_INSTALL_PREFIX@/
 exec_prefix=@CMAKE_INSTALL_PREFIX@/
 libdir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_LIB_INSTALL_DIR@
 libdir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_LIB_INSTALL_DIR@
-includedir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_INCLUDE_INSTALL_DIR@
+includedir=@CMAKE_INSTALL_PREFIX@/../include/@ASSIMP_INCLUDE_INSTALL_DIR@
 
 
 Name: @CMAKE_PROJECT_NAME@
 Name: @CMAKE_PROJECT_NAME@
 Description: Import various well-known 3D model formats in an uniform manner.
 Description: Import various well-known 3D model formats in an uniform manner.

+ 74 - 34
assimpTargets-debug.cmake.in

@@ -5,48 +5,83 @@
 # Commands may need to know the format version.
 # Commands may need to know the format version.
 set(CMAKE_IMPORT_FILE_VERSION 1)
 set(CMAKE_IMPORT_FILE_VERSION 1)
 
 
+set(ASSIMP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
+
 if(MSVC)
 if(MSVC)
-  if( MSVC70 OR MSVC71 )
-    set(MSVC_PREFIX "vc70")
-  elseif( MSVC80 )
-    set(MSVC_PREFIX "vc80")
-  elseif( MSVC90 )
-    set(MSVC_PREFIX "vc90")
-  elseif( MSVC10 )
-    set(MSVC_PREFIX "vc100")
-  elseif( MSVC11 )
-    set(MSVC_PREFIX "vc110")
-  elseif( MSVC12 )
-    set(MSVC_PREFIX "vc120")
-  elseif( MSVC14 )
-    set(MSVC_PREFIX "vc140")
+  if(MSVC_TOOLSET_VERSION)
+    set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
   else()
   else()
-    set(MSVC_PREFIX "vc150")
+    if( MSVC70 OR MSVC71 )
+      set(MSVC_PREFIX "vc70")
+    elseif( MSVC80 )
+      set(MSVC_PREFIX "vc80")
+    elseif( MSVC90 )
+      set(MSVC_PREFIX "vc90")
+    elseif( MSVC10 )
+      set(MSVC_PREFIX "vc100")
+    elseif( MSVC11 )
+      set(MSVC_PREFIX "vc110")
+    elseif( MSVC12 )
+      set(MSVC_PREFIX "vc120")
+    elseif( MSVC_VERSION LESS 1910)
+      set(MSVC_PREFIX "vc140")
+    elseif( MSVC_VERSION LESS 1920)
+      set(MSVC_PREFIX "vc141")
+    elseif( MSVC_VERSION LESS 1930)
+      set(MSVC_PREFIX "vc142")
+    else()
+      set(MSVC_PREFIX "vc150")
+    endif()
   endif()
   endif()
   set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
   set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
 
 
-  set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@")
-  set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_IMPORT_LIBRARY_SUFFIX@")
+  if(ASSIMP_BUILD_SHARED_LIBS)
+    set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@")
+    set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_IMPORT_LIBRARY_SUFFIX@")
+
+    # Import target "assimp::assimp" for configuration "Debug"
+    set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+    set_target_properties(assimp::assimp PROPERTIES
+      IMPORTED_IMPLIB_DEBUG "${_IMPORT_PREFIX}/lib/${importLibraryName}"
+      IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/bin/${sharedLibraryName}"
+    )
+    list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
+    list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${importLibraryName}")
+    list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/bin/${sharedLibraryName}" )
+  else()
+    set(staticLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
 
 
-  # Import target "assimp::assimp" for configuration "Debug"
-  set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
-  set_target_properties(assimp::assimp PROPERTIES
-    IMPORTED_IMPLIB_DEBUG "${_IMPORT_PREFIX}/lib/${importLibraryName}"
-    IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/bin/${sharedLibraryName}"
-    ) 
-  list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
-  list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${importLibraryName}")
-  list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/bin/${sharedLibraryName}" )
+    # Import target "assimp::assimp" for configuration "Debug"
+    set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+    set_target_properties(assimp::assimp PROPERTIES
+      IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/${staticLibraryName}"
+    )
+    list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
+    list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${staticLibraryName}")
+  endif()
 
 
 else()
 else()
-  set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the openrave libraries" )
-  set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
-  set_target_properties(assimp::assimp PROPERTIES
-    IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
-    IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"
+  set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the assimp libraries" )
+  if(ASSIMP_BUILD_SHARED_LIBS)
+    if(APPLE)
+        set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@.@ASSIMP_VERSION_MAJOR@@CMAKE_SHARED_LIBRARY_SUFFIX@")
+    else(APPLE)
+        set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
+    endif()
+    set_target_properties(assimp::assimp PROPERTIES
+      IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
+      IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"
     )
     )
-  list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
-  list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${sharedLibraryName}" )
+    list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
+    list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${sharedLibraryName}" )
+  else()
+    set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
+    set_target_properties(assimp::assimp PROPERTIES
+      IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/${staticLibraryName}"
+    )
+    list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
+    list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${staticLibraryName}" )
+  endif()
 endif()
 endif()
 
 
 
 
@@ -60,7 +95,11 @@ set( ASSIMP_CXX_FLAGS ) # dynamically linked library
 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 ${sharedLibraryName})
+if(ASSIMP_BUILD_SHARED_LIBS)
+  set( ASSIMP_LIBRARIES ${sharedLibraryName})
+else()
+  set( ASSIMP_LIBRARIES ${staticLibraryName})
+endif()
 
 
 # for compatibility with pkg-config
 # for compatibility with pkg-config
 set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
 set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
@@ -75,4 +114,5 @@ MARK_AS_ADVANCED(
   ASSIMP_CFLAGS_OTHER
   ASSIMP_CFLAGS_OTHER
   ASSIMP_LDFLAGS_OTHER
   ASSIMP_LDFLAGS_OTHER
   ASSIMP_LIBRARY_SUFFIX
   ASSIMP_LIBRARY_SUFFIX
+  ASSIMP_BUILD_SHARED_LIBS
 )
 )

+ 74 - 33
assimpTargets-release.cmake.in

@@ -5,59 +5,99 @@
 # Commands may need to know the format version.
 # Commands may need to know the format version.
 set(CMAKE_IMPORT_FILE_VERSION 1)
 set(CMAKE_IMPORT_FILE_VERSION 1)
 
 
+set(ASSIMP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
+
 if(MSVC)
 if(MSVC)
-  if( MSVC70 OR MSVC71 )
-    set(MSVC_PREFIX "vc70")
-  elseif( MSVC80 )
-    set(MSVC_PREFIX "vc80")
-  elseif( MSVC90 )
-    set(MSVC_PREFIX "vc90")
-  elseif( MSVC10 )
-    set(MSVC_PREFIX "vc100")
-  elseif( MSVC11 )
-    set(MSVC_PREFIX "vc110")
-  elseif( MSVC12 )
-    set(MSVC_PREFIX "vc120")
-  elseif( MSVC14 )
-    set(MSVC_PREFIX "vc140")
+  if(MSVC_TOOLSET_VERSION)
+    set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
   else()
   else()
-    set(MSVC_PREFIX "vc150")
+    if( MSVC70 OR MSVC71 )
+      set(MSVC_PREFIX "vc70")
+    elseif( MSVC80 )
+      set(MSVC_PREFIX "vc80")
+    elseif( MSVC90 )
+      set(MSVC_PREFIX "vc90")
+    elseif( MSVC10 )
+      set(MSVC_PREFIX "vc100")
+    elseif( MSVC11 )
+      set(MSVC_PREFIX "vc110")
+    elseif( MSVC12 )
+      set(MSVC_PREFIX "vc120")
+    elseif( MSVC_VERSION LESS 1910)
+      set(MSVC_PREFIX "vc140")
+    elseif( MSVC_VERSION LESS 1920)
+      set(MSVC_PREFIX "vc141")
+    elseif( MSVC_VERSION LESS 1930)
+      set(MSVC_PREFIX "vc142")
+    else()
+      set(MSVC_PREFIX "vc150")
+    endif()
   endif()
   endif()
   set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
   set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
 
 
-  set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@")
-  set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_IMPORT_LIBRARY_SUFFIX@")
+  if(ASSIMP_BUILD_SHARED_LIBS)
+    set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@")
+    set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_IMPORT_LIBRARY_SUFFIX@")
+
+    # Import target "assimp::assimp" for configuration "Release"
+    set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+    set_target_properties(assimp::assimp PROPERTIES
+      IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/${importLibraryName}"
+      IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/${sharedLibraryName}"
+    )
+    list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
+    list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${importLibraryName}")
+    list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/bin/${sharedLibraryName}" )
+  else()
+    set(staticLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
 
 
-  # Import target "assimp::assimp" for configuration "Release"
-  set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
-  set_target_properties(assimp::assimp PROPERTIES
-    IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/${importLibraryName}"
-    IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/${sharedLibraryName}"
+    # Import target "assimp::assimp" for configuration "Release"
+    set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+    set_target_properties(assimp::assimp PROPERTIES
+      IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/${staticLibraryName}"
     )
     )
-  list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
-  list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${importLibraryName}")
-  list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/bin/${sharedLibraryName}" )
+    list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
+    list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${staticLibraryName}")
+  endif()
 
 
 else()
 else()
-  set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the openrave libraries" )
-  set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
-  set_target_properties(assimp::assimp PROPERTIES
-    IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
-    IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"
+  set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the assimp libraries" )
+  if(ASSIMP_BUILD_SHARED_LIBS)
+    if(APPLE)
+        set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}.@ASSIMP_VERSION_MAJOR@@CMAKE_SHARED_LIBRARY_SUFFIX@")
+    else(APPLE)
+        set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
+    endif()
+    set_target_properties(assimp::assimp PROPERTIES
+      IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
+      IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"
     )
     )
-  list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
-  list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${sharedLibraryName}" )
+    list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
+    list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${sharedLibraryName}" )
+  else()
+    set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
+    set_target_properties(assimp::assimp PROPERTIES
+      IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/${staticLibraryName}"
+    )
+    list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
+    list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${staticLibraryName}" )
+  endif()
 endif()
 endif()
 
 
 # Commands beyond this point should not need to know the version.
 # Commands beyond this point should not need to know the version.
 set(CMAKE_IMPORT_FILE_VERSION)
 set(CMAKE_IMPORT_FILE_VERSION)
 
 
 get_filename_component(ASSIMP_ROOT_DIR "@CMAKE_INSTALL_PREFIX@" REALPATH)
 get_filename_component(ASSIMP_ROOT_DIR "@CMAKE_INSTALL_PREFIX@" REALPATH)
+
 set( ASSIMP_CXX_FLAGS ) # dynamically linked library
 set( ASSIMP_CXX_FLAGS ) # dynamically linked library
 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 ${sharedLibraryName})
+if(ASSIMP_BUILD_SHARED_LIBS)
+  set( ASSIMP_LIBRARIES ${sharedLibraryName})
+else()
+  set( ASSIMP_LIBRARIES ${staticLibraryName})
+endif()
 
 
 # for compatibility with pkg-config
 # for compatibility with pkg-config
 set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
 set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
@@ -72,4 +112,5 @@ MARK_AS_ADVANCED(
   ASSIMP_CFLAGS_OTHER
   ASSIMP_CFLAGS_OTHER
   ASSIMP_LDFLAGS_OTHER
   ASSIMP_LDFLAGS_OTHER
   ASSIMP_LIBRARY_SUFFIX
   ASSIMP_LIBRARY_SUFFIX
+  ASSIMP_BUILD_SHARED_LIBS
 )
 )

+ 5 - 1
assimpTargets.cmake.in

@@ -51,7 +51,11 @@ if(_IMPORT_PREFIX STREQUAL "/")
 endif()
 endif()
 
 
 # Create imported target assimp::assimp
 # Create imported target assimp::assimp
-add_library(assimp::assimp SHARED IMPORTED)
+if(@BUILD_SHARED_LIBS@)
+  add_library(assimp::assimp SHARED IMPORTED)
+else()
+  add_library(assimp::assimp STATIC IMPORTED)
+endif()
 
 
 set_target_properties(assimp::assimp PROPERTIES
 set_target_properties(assimp::assimp PROPERTIES
   COMPATIBLE_INTERFACE_STRING "assimp_MAJOR_VERSION"
   COMPATIBLE_INTERFACE_STRING "assimp_MAJOR_VERSION"

+ 7 - 3
cmake-modules/Findassimp.cmake

@@ -54,14 +54,18 @@ else(WIN32)
 
 
 	find_path(
 	find_path(
 	  assimp_INCLUDE_DIRS
 	  assimp_INCLUDE_DIRS
-	  NAMES postprocess.h scene.h version.h config.h cimport.h
-	  PATHS /usr/local/include/
+	  NAMES assimp/postprocess.h assimp/scene.h assimp/version.h assimp/config.h assimp/cimport.h
+	  PATHS /usr/local/include
+	  PATHS /usr/include/
+
 	)
 	)
 
 
 	find_library(
 	find_library(
 	  assimp_LIBRARIES
 	  assimp_LIBRARIES
 	  NAMES assimp
 	  NAMES assimp
 	  PATHS /usr/local/lib/
 	  PATHS /usr/local/lib/
+	  PATHS /usr/lib64/
+	  PATHS /usr/lib/
 	)
 	)
 
 
 	if (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
 	if (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
@@ -78,4 +82,4 @@ else(WIN32)
 	  endif (assimp_FIND_REQUIRED)
 	  endif (assimp_FIND_REQUIRED)
 	endif (assimp_FOUND)
 	endif (assimp_FOUND)
 	
 	
-endif(WIN32)
+endif(WIN32)

+ 540 - 0
cmake/HunterGate.cmake

@@ -0,0 +1,540 @@
+# Copyright (c) 2013-2018, Ruslan Baratov
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This is a gate file to Hunter package manager.
+# Include this file using `include` command and add package you need, example:
+#
+#     cmake_minimum_required(VERSION 3.2)
+#
+#     include("cmake/HunterGate.cmake")
+#     HunterGate(
+#         URL "https://github.com/path/to/hunter/archive.tar.gz"
+#         SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d"
+#     )
+#
+#     project(MyProject)
+#
+#     hunter_add_package(Foo)
+#     hunter_add_package(Boo COMPONENTS Bar Baz)
+#
+# Projects:
+#     * https://github.com/hunter-packages/gate/
+#     * https://github.com/ruslo/hunter
+
+option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
+
+if(HUNTER_ENABLED)
+  if(CMAKE_VERSION VERSION_LESS "3.2")
+    message(
+        FATAL_ERROR
+        "At least CMake version 3.2 required for Hunter dependency management."
+        " Update CMake or set HUNTER_ENABLED to OFF."
+    )
+  endif()
+endif()
+
+include(CMakeParseArguments) # cmake_parse_arguments
+
+option(HUNTER_STATUS_PRINT "Print working status" ON)
+option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
+option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
+
+set(HUNTER_WIKI "https://github.com/ruslo/hunter/wiki")
+
+function(hunter_gate_status_print)
+  if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
+    foreach(print_message ${ARGV})
+      message(STATUS "[hunter] ${print_message}")
+    endforeach()
+  endif()
+endfunction()
+
+function(hunter_gate_status_debug)
+  if(HUNTER_STATUS_DEBUG)
+    foreach(print_message ${ARGV})
+      string(TIMESTAMP timestamp)
+      message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}")
+    endforeach()
+  endif()
+endfunction()
+
+function(hunter_gate_wiki wiki_page)
+  message("------------------------------ WIKI -------------------------------")
+  message("    ${HUNTER_WIKI}/${wiki_page}")
+  message("-------------------------------------------------------------------")
+  message("")
+  message(FATAL_ERROR "")
+endfunction()
+
+function(hunter_gate_internal_error)
+  message("")
+  foreach(print_message ${ARGV})
+    message("[hunter ** INTERNAL **] ${print_message}")
+  endforeach()
+  message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
+  message("")
+  hunter_gate_wiki("error.internal")
+endfunction()
+
+function(hunter_gate_fatal_error)
+  cmake_parse_arguments(hunter "" "WIKI" "" "${ARGV}")
+  string(COMPARE EQUAL "${hunter_WIKI}" "" have_no_wiki)
+  if(have_no_wiki)
+    hunter_gate_internal_error("Expected wiki")
+  endif()
+  message("")
+  foreach(x ${hunter_UNPARSED_ARGUMENTS})
+    message("[hunter ** FATAL ERROR **] ${x}")
+  endforeach()
+  message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
+  message("")
+  hunter_gate_wiki("${hunter_WIKI}")
+endfunction()
+
+function(hunter_gate_user_error)
+  hunter_gate_fatal_error(${ARGV} WIKI "error.incorrect.input.data")
+endfunction()
+
+function(hunter_gate_self root version sha1 result)
+  string(COMPARE EQUAL "${root}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("root is empty")
+  endif()
+
+  string(COMPARE EQUAL "${version}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("version is empty")
+  endif()
+
+  string(COMPARE EQUAL "${sha1}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("sha1 is empty")
+  endif()
+
+  string(SUBSTRING "${sha1}" 0 7 archive_id)
+
+  if(EXISTS "${root}/cmake/Hunter")
+    set(hunter_self "${root}")
+  else()
+    set(
+        hunter_self
+        "${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked"
+    )
+  endif()
+
+  set("${result}" "${hunter_self}" PARENT_SCOPE)
+endfunction()
+
+# Set HUNTER_GATE_ROOT cmake variable to suitable value.
+function(hunter_gate_detect_root)
+  # Check CMake variable
+  string(COMPARE NOTEQUAL "${HUNTER_ROOT}" "" not_empty)
+  if(not_empty)
+    set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE)
+    hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable")
+    return()
+  endif()
+
+  # Check environment variable
+  string(COMPARE NOTEQUAL "$ENV{HUNTER_ROOT}" "" not_empty)
+  if(not_empty)
+    set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE)
+    hunter_gate_status_debug("HUNTER_ROOT detected by environment variable")
+    return()
+  endif()
+
+  # Check HOME environment variable
+  string(COMPARE NOTEQUAL "$ENV{HOME}" "" result)
+  if(result)
+    set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE)
+    hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable")
+    return()
+  endif()
+
+  # Check SYSTEMDRIVE and USERPROFILE environment variable (windows only)
+  if(WIN32)
+    string(COMPARE NOTEQUAL "$ENV{SYSTEMDRIVE}" "" result)
+    if(result)
+      set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE)
+      hunter_gate_status_debug(
+          "HUNTER_ROOT set using SYSTEMDRIVE environment variable"
+      )
+      return()
+    endif()
+
+    string(COMPARE NOTEQUAL "$ENV{USERPROFILE}" "" result)
+    if(result)
+      set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE)
+      hunter_gate_status_debug(
+          "HUNTER_ROOT set using USERPROFILE environment variable"
+      )
+      return()
+    endif()
+  endif()
+
+  hunter_gate_fatal_error(
+      "Can't detect HUNTER_ROOT"
+      WIKI "error.detect.hunter.root"
+  )
+endfunction()
+
+function(hunter_gate_download dir)
+  string(
+      COMPARE
+      NOTEQUAL
+      "$ENV{HUNTER_DISABLE_AUTOINSTALL}"
+      ""
+      disable_autoinstall
+  )
+  if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL)
+    hunter_gate_fatal_error(
+        "Hunter not found in '${dir}'"
+        "Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'"
+        "Settings:"
+        "  HUNTER_ROOT: ${HUNTER_GATE_ROOT}"
+        "  HUNTER_SHA1: ${HUNTER_GATE_SHA1}"
+        WIKI "error.run.install"
+    )
+  endif()
+  string(COMPARE EQUAL "${dir}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("Empty 'dir' argument")
+  endif()
+
+  string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("HUNTER_GATE_SHA1 empty")
+  endif()
+
+  string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad)
+  if(is_bad)
+    hunter_gate_internal_error("HUNTER_GATE_URL empty")
+  endif()
+
+  set(done_location "${dir}/DONE")
+  set(sha1_location "${dir}/SHA1")
+
+  set(build_dir "${dir}/Build")
+  set(cmakelists "${dir}/CMakeLists.txt")
+
+  hunter_gate_status_debug("Locking directory: ${dir}")
+  file(LOCK "${dir}" DIRECTORY GUARD FUNCTION)
+  hunter_gate_status_debug("Lock done")
+
+  if(EXISTS "${done_location}")
+    # while waiting for lock other instance can do all the job
+    hunter_gate_status_debug("File '${done_location}' found, skip install")
+    return()
+  endif()
+
+  file(REMOVE_RECURSE "${build_dir}")
+  file(REMOVE_RECURSE "${cmakelists}")
+
+  file(MAKE_DIRECTORY "${build_dir}") # check directory permissions
+
+  # Disabling languages speeds up a little bit, reduces noise in the output
+  # and avoids path too long windows error
+  file(
+      WRITE
+      "${cmakelists}"
+      "cmake_minimum_required(VERSION 3.2)\n"
+      "project(HunterDownload LANGUAGES NONE)\n"
+      "include(ExternalProject)\n"
+      "ExternalProject_Add(\n"
+      "    Hunter\n"
+      "    URL\n"
+      "    \"${HUNTER_GATE_URL}\"\n"
+      "    URL_HASH\n"
+      "    SHA1=${HUNTER_GATE_SHA1}\n"
+      "    DOWNLOAD_DIR\n"
+      "    \"${dir}\"\n"
+      "    TLS_VERIFY\n"
+      "    ${HUNTER_TLS_VERIFY}\n"
+      "    SOURCE_DIR\n"
+      "    \"${dir}/Unpacked\"\n"
+      "    CONFIGURE_COMMAND\n"
+      "    \"\"\n"
+      "    BUILD_COMMAND\n"
+      "    \"\"\n"
+      "    INSTALL_COMMAND\n"
+      "    \"\"\n"
+      ")\n"
+  )
+
+  if(HUNTER_STATUS_DEBUG)
+    set(logging_params "")
+  else()
+    set(logging_params OUTPUT_QUIET)
+  endif()
+
+  hunter_gate_status_debug("Run generate")
+
+  # Need to add toolchain file too.
+  # Otherwise on Visual Studio + MDD this will fail with error:
+  # "Could not find an appropriate version of the Windows 10 SDK installed on this machine"
+  if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
+    get_filename_component(absolute_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE)
+    set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${absolute_CMAKE_TOOLCHAIN_FILE}")
+  else()
+    # 'toolchain_arg' can't be empty
+    set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=")
+  endif()
+
+  string(COMPARE EQUAL "${CMAKE_MAKE_PROGRAM}" "" no_make)
+  if(no_make)
+    set(make_arg "")
+  else()
+    # Test case: remove Ninja from PATH but set it via CMAKE_MAKE_PROGRAM
+    set(make_arg "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}")
+  endif()
+
+  execute_process(
+      COMMAND
+      "${CMAKE_COMMAND}"
+      "-H${dir}"
+      "-B${build_dir}"
+      "-G${CMAKE_GENERATOR}"
+      "${toolchain_arg}"
+      ${make_arg}
+      WORKING_DIRECTORY "${dir}"
+      RESULT_VARIABLE download_result
+      ${logging_params}
+  )
+
+  if(NOT download_result EQUAL 0)
+    hunter_gate_internal_error(
+        "Configure project failed."
+        "To reproduce the error run: ${CMAKE_COMMAND} -H${dir} -B${build_dir} -G${CMAKE_GENERATOR} ${toolchain_arg} ${make_arg}"
+        "In directory ${dir}"
+    )
+  endif()
+
+  hunter_gate_status_print(
+      "Initializing Hunter workspace (${HUNTER_GATE_SHA1})"
+      "  ${HUNTER_GATE_URL}"
+      "  -> ${dir}"
+  )
+  execute_process(
+      COMMAND "${CMAKE_COMMAND}" --build "${build_dir}"
+      WORKING_DIRECTORY "${dir}"
+      RESULT_VARIABLE download_result
+      ${logging_params}
+  )
+
+  if(NOT download_result EQUAL 0)
+    hunter_gate_internal_error("Build project failed")
+  endif()
+
+  file(REMOVE_RECURSE "${build_dir}")
+  file(REMOVE_RECURSE "${cmakelists}")
+
+  file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}")
+  file(WRITE "${done_location}" "DONE")
+
+  hunter_gate_status_debug("Finished")
+endfunction()
+
+# Must be a macro so master file 'cmake/Hunter' can
+# apply all variables easily just by 'include' command
+# (otherwise PARENT_SCOPE magic needed)
+macro(HunterGate)
+  if(HUNTER_GATE_DONE)
+    # variable HUNTER_GATE_DONE set explicitly for external project
+    # (see `hunter_download`)
+    set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
+  endif()
+
+  # First HunterGate command will init Hunter, others will be ignored
+  get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET)
+
+  if(NOT HUNTER_ENABLED)
+    # Empty function to avoid error "unknown function"
+    function(hunter_add_package)
+    endfunction()
+
+    set(
+        _hunter_gate_disabled_mode_dir
+        "${CMAKE_CURRENT_LIST_DIR}/cmake/Hunter/disabled-mode"
+    )
+    if(EXISTS "${_hunter_gate_disabled_mode_dir}")
+      hunter_gate_status_debug(
+          "Adding \"disabled-mode\" modules: ${_hunter_gate_disabled_mode_dir}"
+      )
+      list(APPEND CMAKE_PREFIX_PATH "${_hunter_gate_disabled_mode_dir}")
+    endif()
+  elseif(_hunter_gate_done)
+    hunter_gate_status_debug("Secondary HunterGate (use old settings)")
+    hunter_gate_self(
+        "${HUNTER_CACHED_ROOT}"
+        "${HUNTER_VERSION}"
+        "${HUNTER_SHA1}"
+        _hunter_self
+    )
+    include("${_hunter_self}/cmake/Hunter")
+  else()
+    set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}")
+
+    string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name)
+    if(_have_project_name)
+      hunter_gate_fatal_error(
+          "Please set HunterGate *before* 'project' command. "
+          "Detected project: ${PROJECT_NAME}"
+          WIKI "error.huntergate.before.project"
+      )
+    endif()
+
+    cmake_parse_arguments(
+        HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV}
+    )
+
+    string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1)
+    string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url)
+    string(
+        COMPARE
+        NOTEQUAL
+        "${HUNTER_GATE_UNPARSED_ARGUMENTS}"
+        ""
+        _have_unparsed
+    )
+    string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global)
+    string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath)
+
+    if(_have_unparsed)
+      hunter_gate_user_error(
+          "HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}"
+      )
+    endif()
+    if(_empty_sha1)
+      hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory")
+    endif()
+    if(_empty_url)
+      hunter_gate_user_error("URL suboption of HunterGate is mandatory")
+    endif()
+    if(_have_global)
+      if(HUNTER_GATE_LOCAL)
+        hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)")
+      endif()
+      if(_have_filepath)
+        hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)")
+      endif()
+    endif()
+    if(HUNTER_GATE_LOCAL)
+      if(_have_global)
+        hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)")
+      endif()
+      if(_have_filepath)
+        hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)")
+      endif()
+    endif()
+    if(_have_filepath)
+      if(_have_global)
+        hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)")
+      endif()
+      if(HUNTER_GATE_LOCAL)
+        hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)")
+      endif()
+    endif()
+
+    hunter_gate_detect_root() # set HUNTER_GATE_ROOT
+
+    # Beautify path, fix probable problems with windows path slashes
+    get_filename_component(
+        HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE
+    )
+    hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}")
+    if(NOT HUNTER_ALLOW_SPACES_IN_PATH)
+      string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces)
+      if(NOT _contain_spaces EQUAL -1)
+        hunter_gate_fatal_error(
+            "HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces."
+            "Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error"
+            "(Use at your own risk!)"
+            WIKI "error.spaces.in.hunter.root"
+        )
+      endif()
+    endif()
+
+    string(
+        REGEX
+        MATCH
+        "[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*"
+        HUNTER_GATE_VERSION
+        "${HUNTER_GATE_URL}"
+    )
+    string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty)
+    if(_is_empty)
+      set(HUNTER_GATE_VERSION "unknown")
+    endif()
+
+    hunter_gate_self(
+        "${HUNTER_GATE_ROOT}"
+        "${HUNTER_GATE_VERSION}"
+        "${HUNTER_GATE_SHA1}"
+        _hunter_self
+    )
+
+    set(_master_location "${_hunter_self}/cmake/Hunter")
+    if(EXISTS "${HUNTER_GATE_ROOT}/cmake/Hunter")
+      # Hunter downloaded manually (e.g. by 'git clone')
+      set(_unused "xxxxxxxxxx")
+      set(HUNTER_GATE_SHA1 "${_unused}")
+      set(HUNTER_GATE_VERSION "${_unused}")
+    else()
+      get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE)
+      set(_done_location "${_archive_id_location}/DONE")
+      set(_sha1_location "${_archive_id_location}/SHA1")
+
+      # Check Hunter already downloaded by HunterGate
+      if(NOT EXISTS "${_done_location}")
+        hunter_gate_download("${_archive_id_location}")
+      endif()
+
+      if(NOT EXISTS "${_done_location}")
+        hunter_gate_internal_error("hunter_gate_download failed")
+      endif()
+
+      if(NOT EXISTS "${_sha1_location}")
+        hunter_gate_internal_error("${_sha1_location} not found")
+      endif()
+      file(READ "${_sha1_location}" _sha1_value)
+      string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal)
+      if(NOT _is_equal)
+        hunter_gate_internal_error(
+            "Short SHA1 collision:"
+            "  ${_sha1_value} (from ${_sha1_location})"
+            "  ${HUNTER_GATE_SHA1} (HunterGate)"
+        )
+      endif()
+      if(NOT EXISTS "${_master_location}")
+        hunter_gate_user_error(
+            "Master file not found:"
+            "  ${_master_location}"
+            "try to update Hunter/HunterGate"
+        )
+      endif()
+    endif()
+    include("${_master_location}")
+    set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
+  endif()
+endmacro()

+ 14 - 0
cmake/assimp-hunter-config.cmake.in

@@ -0,0 +1,14 @@
+@PACKAGE_INIT@
+
+find_package(RapidJSON CONFIG REQUIRED)
+find_package(ZLIB CONFIG REQUIRED)
+find_package(utf8 CONFIG REQUIRED)
+find_package(irrXML CONFIG REQUIRED)
+find_package(minizip CONFIG REQUIRED)
+find_package(openddlparser CONFIG REQUIRED)
+find_package(poly2tri CONFIG REQUIRED)
+find_package(polyclipping CONFIG REQUIRED)
+find_package(zip CONFIG REQUIRED)
+
+include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
+check_required_components("@PROJECT_NAME@")

+ 2 - 2
code/3DSConverter.cpp → code/3DS/3DSConverter.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 // internal headers
 // internal headers
 #include "3DSLoader.h"
 #include "3DSLoader.h"
-#include "TargetAnimation.h"
+#include "Common/TargetAnimation.h"
 #include <assimp/scene.h>
 #include <assimp/scene.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/StringComparison.h>
 #include <assimp/StringComparison.h>

+ 7 - 5
code/3DSExporter.cpp → code/3DS/3DSExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -43,15 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_EXPORT
 #ifndef ASSIMP_BUILD_NO_EXPORT
 #ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
 #ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
 
 
-#include "3DSExporter.h"
-#include "3DSLoader.h"
-#include "3DSHelper.h"
+#include "3DS/3DSExporter.h"
+#include "3DS/3DSLoader.h"
+#include "3DS/3DSHelper.h"
+#include "PostProcessing/SplitLargeMeshes.h"
+
 #include <assimp/SceneCombiner.h>
 #include <assimp/SceneCombiner.h>
-#include "SplitLargeMeshes.h"
 #include <assimp/StringComparison.h>
 #include <assimp/StringComparison.h>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/Exporter.hpp>
 #include <assimp/Exporter.hpp>
+
 #include <memory>
 #include <memory>
 
 
 using namespace Assimp;
 using namespace Assimp;

+ 1 - 1
code/3DSExporter.h → code/3DS/3DSExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 1 - 1
code/3DSHelper.h → code/3DS/3DSHelper.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 10 - 10
code/3DSLoader.cpp → code/3DS/3DSLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -50,9 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
 #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
 
 
-// internal headers
 #include "3DSLoader.h"
 #include "3DSLoader.h"
-#include <assimp/Macros.h>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/scene.h>
 #include <assimp/scene.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
@@ -249,13 +247,14 @@ void Discreet3DSImporter::ApplyMasterScale(aiScene* pScene)
 // Reads a new chunk from the file
 // Reads a new chunk from the file
 void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk* pcOut)
 void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk* pcOut)
 {
 {
-    ai_assert(pcOut != NULL);
+    ai_assert(pcOut != nullptr);
 
 
     pcOut->Flag = stream->GetI2();
     pcOut->Flag = stream->GetI2();
     pcOut->Size = stream->GetI4();
     pcOut->Size = stream->GetI4();
 
 
-    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()) {
         ASSIMP_LOG_ERROR("3DS: Chunk overflow");
         ASSIMP_LOG_ERROR("3DS: Chunk overflow");
@@ -1343,15 +1342,16 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Read a percentage chunk
 // Read a percentage chunk
-ai_real Discreet3DSImporter::ParsePercentageChunk()
-{
+ai_real Discreet3DSImporter::ParsePercentageChunk() {
     Discreet3DS::Chunk chunk;
     Discreet3DS::Chunk chunk;
     ReadChunk(&chunk);
     ReadChunk(&chunk);
 
 
-    if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag)
-        return stream->GetF4();
-    else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag)
+    if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag) {
+        return stream->GetF4() * ai_real(100) / ai_real(0xFFFF);
+    } else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag) {
         return (ai_real)((uint16_t)stream->GetI2()) / (ai_real)0xFFFF;
         return (ai_real)((uint16_t)stream->GetI2()) / (ai_real)0xFFFF;
+    }
+
     return get_qnan();
     return get_qnan();
 }
 }
 
 

+ 1 - 1
code/3DSLoader.h → code/3DS/3DSLoader.h

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 1 - 1
code/3MFXmlTags.h → code/3MF/3MFXmlTags.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 6 - 2
code/D3MFExporter.cpp → code/3MF/D3MFExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -55,7 +55,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "3MFXmlTags.h"
 #include "3MFXmlTags.h"
 #include "D3MFOpcPackage.h"
 #include "D3MFOpcPackage.h"
 
 
-#include <contrib/zip/src/zip.h>
+#ifdef ASSIMP_USE_HUNTER
+#  include <zip/zip.h>
+#else
+#  include <contrib/zip/src/zip.h>
+#endif
 
 
 namespace Assimp {
 namespace Assimp {
 
 

+ 1 - 1
code/D3MFExporter.h → code/3MF/D3MFExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 3 - 3
code/D3MFImporter.cpp → code/3MF/D3MFImporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/importerdesc.h>
 #include <assimp/importerdesc.h>
 #include <assimp/StringComparison.h>
 #include <assimp/StringComparison.h>
 #include <assimp/StringUtils.h>
 #include <assimp/StringUtils.h>
+#include <assimp/ZipArchiveIOSystem.h>
 
 
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
@@ -58,7 +59,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <memory>
 #include <memory>
 
 
 #include "D3MFOpcPackage.h"
 #include "D3MFOpcPackage.h"
-#include <unzip.h>
 #include <assimp/irrXMLWrapper.h>
 #include <assimp/irrXMLWrapper.h>
 #include "3MFXmlTags.h"
 #include "3MFXmlTags.h"
 #include <assimp/fast_atof.h>
 #include <assimp/fast_atof.h>
@@ -449,7 +449,7 @@ bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bo
         if ( nullptr == pIOHandler ) {
         if ( nullptr == pIOHandler ) {
             return false;
             return false;
         }
         }
-        if ( !D3MF::D3MFOpcPackage::isZipArchive( pIOHandler, filename ) ) {
+        if ( !ZipArchiveIOSystem::isZipArchive( pIOHandler, filename ) ) {
             return false;
             return false;
         }
         }
         D3MF::D3MFOpcPackage opcPackage( pIOHandler, filename );
         D3MF::D3MFOpcPackage opcPackage( pIOHandler, filename );

+ 1 - 1
code/D3MFImporter.h → code/3MF/D3MFImporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 207 - 0
code/3MF/D3MFOpcPackage.cpp

@@ -0,0 +1,207 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
+
+#include "D3MFOpcPackage.h"
+#include <assimp/Exceptional.h>
+
+#include <assimp/IOStream.hpp>
+#include <assimp/IOSystem.hpp>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/ai_assert.h>
+#include <assimp/ZipArchiveIOSystem.h>
+
+#include <cstdlib>
+#include <memory>
+#include <vector>
+#include <map>
+#include <algorithm>
+#include <cassert>
+#include "3MFXmlTags.h"
+
+namespace Assimp {
+
+namespace D3MF {
+// ------------------------------------------------------------------------------------------------
+
+typedef std::shared_ptr<OpcPackageRelationship> OpcPackageRelationshipPtr;
+
+class OpcPackageRelationshipReader {
+public:
+    OpcPackageRelationshipReader(XmlReader* xmlReader) {        
+        while(xmlReader->read()) {
+            if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
+               xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER)
+            {
+                ParseRootNode(xmlReader);
+            }
+        }
+    }
+
+    void ParseRootNode(XmlReader* xmlReader)
+    {       
+        ParseAttributes(xmlReader);
+
+        while(xmlReader->read())
+        {
+            if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
+               xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE)
+            {
+                ParseChildNode(xmlReader);
+            }
+        }
+    }
+
+    void ParseAttributes(XmlReader*) {
+        // empty
+    }
+
+    bool validateRels( OpcPackageRelationshipPtr &relPtr ) {
+        if ( relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty() ) {
+            return false;
+        }
+        return true;
+    }
+
+    void ParseChildNode(XmlReader* xmlReader) {        
+        OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
+
+        relPtr->id = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_ID.c_str());
+        relPtr->type = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TYPE.c_str());
+        relPtr->target = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TARGET.c_str());
+        if ( validateRels( relPtr ) ) {
+            m_relationShips.push_back( relPtr );
+        }
+    }
+
+    std::vector<OpcPackageRelationshipPtr> m_relationShips;
+};
+
+// ------------------------------------------------------------------------------------------------
+D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
+: mRootStream(nullptr)
+, mZipArchive() {    
+    mZipArchive.reset( new ZipArchiveIOSystem( pIOHandler, rFile ) );
+    if(!mZipArchive->isOpen()) {
+        throw DeadlyImportError("Failed to open file " + rFile+ ".");
+    }
+
+    std::vector<std::string> fileList;
+    mZipArchive->getFileList(fileList);
+
+    for (auto& file: fileList) {
+        if(file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE) {
+            //PkgRelationshipReader pkgRelReader(file, archive);
+            ai_assert(mZipArchive->Exists(file.c_str()));
+
+            IOStream *fileStream = mZipArchive->Open(file.c_str());
+
+            ai_assert(fileStream != nullptr);
+
+            std::string rootFile = ReadPackageRootRelationship(fileStream);
+            if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) {
+                rootFile = rootFile.substr( 1 );
+                if ( rootFile[ 0 ] == '/' ) {
+                    // deal with zip-bug
+                    rootFile = rootFile.substr( 1 );
+                }
+            }
+
+            ASSIMP_LOG_DEBUG(rootFile);
+
+            mZipArchive->Close(fileStream);
+
+            mRootStream = mZipArchive->Open(rootFile.c_str());
+            ai_assert( mRootStream != nullptr );
+            if ( nullptr == mRootStream ) {
+                throw DeadlyExportError( "Cannot open root-file in archive : " + rootFile );
+            }
+
+        } else if( file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
+            ASSIMP_LOG_WARN_F("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES",file);
+        } else {
+            ASSIMP_LOG_WARN_F("Ignored file of unknown type: ",file);
+        }
+
+    }
+}
+
+D3MFOpcPackage::~D3MFOpcPackage() {
+    mZipArchive->Close(mRootStream);
+}
+
+IOStream* D3MFOpcPackage::RootStream() const {
+    return mRootStream;
+}
+
+static const std::string ModelRef = "3D/3dmodel.model";
+
+bool D3MFOpcPackage::validate() {
+    if ( nullptr == mRootStream || nullptr == mZipArchive ) {
+        return false;
+    }
+
+    return mZipArchive->Exists( ModelRef.c_str() );
+}
+
+std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream) {
+    std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(stream));
+    std::unique_ptr<XmlReader> xml(irr::io::createIrrXMLReader(xmlStream.get()));
+
+    OpcPackageRelationshipReader reader(xml.get());
+
+    auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr& rel){
+        return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
+    });
+
+    if ( itr == reader.m_relationShips.end() ) {
+        throw DeadlyImportError( "Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE );
+    }
+
+    return (*itr)->target;
+}
+
+} // Namespace D3MF
+} // Namespace Assimp
+
+#endif //ASSIMP_BUILD_NO_3MF_IMPORTER

+ 4 - 5
code/D3MFOpcPackage.h → code/3MF/D3MFOpcPackage.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -49,6 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/irrXMLWrapper.h>
 #include <assimp/irrXMLWrapper.h>
 
 
 namespace Assimp {
 namespace Assimp {
+    class ZipArchiveIOSystem;
+
 namespace D3MF {
 namespace D3MF {
 
 
 using XmlReader = irr::io::IrrXMLReader ;
 using XmlReader = irr::io::IrrXMLReader ;
@@ -60,22 +62,19 @@ struct OpcPackageRelationship {
     std::string target;
     std::string target;
 };
 };
 
 
-class D3MFZipArchive;
-
 class D3MFOpcPackage {
 class D3MFOpcPackage {
 public:
 public:
     D3MFOpcPackage( IOSystem* pIOHandler, const std::string& rFile );
     D3MFOpcPackage( IOSystem* pIOHandler, const std::string& rFile );
     ~D3MFOpcPackage();
     ~D3MFOpcPackage();
     IOStream* RootStream() const;
     IOStream* RootStream() const;
     bool validate();
     bool validate();
-    static bool isZipArchive( IOSystem* pIOHandler, const std::string& rFile );
 
 
 protected:
 protected:
     std::string ReadPackageRootRelationship(IOStream* stream);
     std::string ReadPackageRootRelationship(IOStream* stream);
 
 
 private:
 private:
     IOStream* mRootStream;
     IOStream* mRootStream;
-    std::unique_ptr<D3MFZipArchive> mZipArchive;
+    std::unique_ptr<ZipArchiveIOSystem> mZipArchive;
 };
 };
 
 
 } // Namespace D3MF
 } // Namespace D3MF

+ 2 - 2
code/ACLoader.cpp → code/AC/ACLoader.cpp

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/ParsingUtils.h>
 #include <assimp/ParsingUtils.h>
 #include <assimp/fast_atof.h>
 #include <assimp/fast_atof.h>
 #include <assimp/Subdivision.h>
 #include <assimp/Subdivision.h>
-#include "Importer.h"
+#include "Common/Importer.h"
 #include <assimp/BaseImporter.h>
 #include <assimp/BaseImporter.h>
 #include <assimp/Importer.hpp>
 #include <assimp/Importer.hpp>
 #include <assimp/light.h>
 #include <assimp/light.h>

+ 1 - 1
code/ACLoader.h → code/AC/ACLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 2 - 2
code/AMFImporter.cpp → code/AMF/AMFImporter.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -83,7 +83,7 @@ void AMFImporter::Clear()
 	mMaterial_Converted.clear();
 	mMaterial_Converted.clear();
 	mTexture_Converted.clear();
 	mTexture_Converted.clear();
 	// Delete all elements
 	// Delete all elements
-	if(mNodeElement_List.size())
+	if(!mNodeElement_List.empty())
 	{
 	{
 		for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; }
 		for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; }
 
 

+ 1 - 1
code/AMFImporter.hpp → code/AMF/AMFImporter.hpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 

+ 1 - 1
code/AMFImporter_Geometry.cpp → code/AMF/AMFImporter_Geometry.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 

+ 1 - 1
code/AMFImporter_Macro.hpp → code/AMF/AMFImporter_Macro.hpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 

+ 1 - 1
code/AMFImporter_Material.cpp → code/AMF/AMFImporter_Material.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 

+ 1 - 1
code/AMFImporter_Node.hpp → code/AMF/AMFImporter_Node.hpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 

+ 14 - 14
code/AMFImporter_Postprocess.cpp → code/AMF/AMFImporter_Postprocess.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -66,7 +66,7 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
     aiColor4D tcol;
     aiColor4D tcol;
 
 
 	// Check if stored data are supported.
 	// Check if stored data are supported.
-	if(Composition.size() != 0)
+	if(!Composition.empty())
 	{
 	{
 		throw DeadlyImportError("IME. GetColor for composition");
 		throw DeadlyImportError("IME. GetColor for composition");
 	}
 	}
@@ -321,7 +321,7 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
     };
     };
 
 
 	pOutputList_Separated.clear();
 	pOutputList_Separated.clear();
-	if(pInputList.size() == 0) return;
+	if(pInputList.empty()) return;
 
 
 	do
 	do
 	{
 	{
@@ -334,19 +334,19 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
 			{
 			{
 				auto it_old = it;
 				auto it_old = it;
 
 
-				it++;
+				++it;
 				face_list_cur.push_back(*it_old);
 				face_list_cur.push_back(*it_old);
 				pInputList.erase(it_old);
 				pInputList.erase(it_old);
 			}
 			}
 			else
 			else
 			{
 			{
-				it++;
+				++it;
 			}
 			}
 		}
 		}
 
 
-		if(face_list_cur.size() > 0) pOutputList_Separated.push_back(face_list_cur);
+		if(!face_list_cur.empty()) pOutputList_Separated.push_back(face_list_cur);
 
 
-	} while(pInputList.size() > 0);
+	} while(!pInputList.empty());
 }
 }
 
 
 void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const
 void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const
@@ -712,7 +712,7 @@ std::list<unsigned int> mesh_idx;
 	}// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
 	}// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
 
 
 	// if meshes was created then assign new indices with current aiNode
 	// if meshes was created then assign new indices with current aiNode
-	if(mesh_idx.size() > 0)
+	if(!mesh_idx.empty())
 	{
 	{
 		std::list<unsigned int>::const_iterator mit = mesh_idx.begin();
 		std::list<unsigned int>::const_iterator mit = mesh_idx.begin();
 
 
@@ -787,7 +787,7 @@ std::list<aiNode*> ch_node;
 	}// for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
 	}// for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
 
 
 	// copy found aiNode's as children
 	// copy found aiNode's as children
-	if(ch_node.size() == 0) throw DeadlyImportError("<constellation> must have at least one <instance>.");
+	if(ch_node.empty()) throw DeadlyImportError("<constellation> must have at least one <instance>.");
 
 
 	size_t ch_idx = 0;
 	size_t ch_idx = 0;
 
 
@@ -883,13 +883,13 @@ nl_clean_loop:
 	if(node_list.size() > 1)
 	if(node_list.size() > 1)
 	{
 	{
 		// walk through all nodes
 		// walk through all nodes
-		for(std::list<aiNode*>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++)
+		for(std::list<aiNode*>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); ++nl_it)
 		{
 		{
 			// and try to find them in another top nodes.
 			// and try to find them in another top nodes.
 			std::list<aiNode*>::const_iterator next_it = nl_it;
 			std::list<aiNode*>::const_iterator next_it = nl_it;
 
 
-			next_it++;
-			for(; next_it != node_list.end(); next_it++)
+			++next_it;
+			for(; next_it != node_list.end(); ++next_it)
 			{
 			{
 				if((*next_it)->FindNode((*nl_it)->mName) != nullptr)
 				if((*next_it)->FindNode((*nl_it)->mName) != nullptr)
 				{
 				{
@@ -907,7 +907,7 @@ nl_clean_loop:
 	//
 	//
 	//
 	//
 	// Nodes
 	// Nodes
-	if(node_list.size() > 0)
+	if(!node_list.empty())
 	{
 	{
 		std::list<aiNode*>::const_iterator nl_it = node_list.begin();
 		std::list<aiNode*>::const_iterator nl_it = node_list.begin();
 
 
@@ -924,7 +924,7 @@ nl_clean_loop:
 
 
 	//
 	//
 	// Meshes
 	// Meshes
-	if(mesh_list.size() > 0)
+	if(!mesh_list.empty())
 	{
 	{
 		std::list<aiMesh*>::const_iterator ml_it = mesh_list.begin();
 		std::list<aiMesh*>::const_iterator ml_it = mesh_list.begin();
 
 

+ 17 - 17
code/ASELoader.cpp → code/ASE/ASELoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -53,7 +53,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "ASELoader.h"
 #include "ASELoader.h"
 #include <assimp/StringComparison.h>
 #include <assimp/StringComparison.h>
 #include <assimp/SkeletonMeshBuilder.h>
 #include <assimp/SkeletonMeshBuilder.h>
-#include "TargetAnimation.h"
+#include "Common/TargetAnimation.h"
+
 #include <assimp/Importer.hpp>
 #include <assimp/Importer.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
@@ -88,23 +89,25 @@ ASEImporter::ASEImporter()
 , mBuffer()
 , mBuffer()
 , pcScene()
 , pcScene()
 , configRecomputeNormals()
 , configRecomputeNormals()
-, noSkeletonMesh()
-{}
+, noSkeletonMesh() {
+    // empty
+}
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-ASEImporter::~ASEImporter()
-{}
+ASEImporter::~ASEImporter() {
+    // empty
+}
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // 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 ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
-{
+bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const {
     // check file extension
     // check file extension
     const std::string extension = GetExtension(pFile);
     const std::string extension = GetExtension(pFile);
 
 
-    if( extension == "ase" || extension == "ask")
+    if (extension == "ase" || extension == "ask") {
         return true;
         return true;
+    }
 
 
     if ((!extension.length() || cs) && pIOHandler) {
     if ((!extension.length() || cs) && pIOHandler) {
         const char* tokens[] = {"*3dsmax_asciiexport"};
         const char* tokens[] = {"*3dsmax_asciiexport"};
@@ -115,15 +118,13 @@ bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Loader meta information
 // Loader meta information
-const aiImporterDesc* ASEImporter::GetInfo () const
-{
+const aiImporterDesc* ASEImporter::GetInfo () const {
     return &desc;
     return &desc;
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Setup configuration options
 // Setup configuration options
-void ASEImporter::SetupProperties(const Importer* pImp)
-{
+void ASEImporter::SetupProperties(const Importer* pImp) {
     configRecomputeNormals = (pImp->GetPropertyInteger(
     configRecomputeNormals = (pImp->GetPropertyInteger(
         AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS,1) ? true : false);
         AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS,1) ? true : false);
 
 
@@ -133,12 +134,11 @@ void ASEImporter::SetupProperties(const Importer* pImp)
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure.
 // Imports the given file into the given scene structure.
 void ASEImporter::InternReadFile( const std::string& pFile,
 void ASEImporter::InternReadFile( const std::string& pFile,
-    aiScene* pScene, IOSystem* pIOHandler)
-{
+    aiScene* pScene, IOSystem* pIOHandler) {
     std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
     std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 
 
     // Check whether we can read from the file
     // Check whether we can read from the file
-    if( file.get() == NULL) {
+    if( file.get() == nullptr) {
         throw DeadlyImportError( "Failed to open ASE file " + pFile + ".");
         throw DeadlyImportError( "Failed to open ASE file " + pFile + ".");
     }
     }
 
 
@@ -1299,7 +1299,7 @@ void ASEImporter::BuildMaterialIndices()
         }
         }
     }
     }
 
 
-    // Dekete our temporary array
+    // Delete our temporary array
     delete[] pcIntMaterials;
     delete[] pcIntMaterials;
 }
 }
 
 

+ 1 - 2
code/ASELoader.h → code/ASE/ASELoader.h

@@ -2,8 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
-
+Copyright (c) 2006-2019, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 3 - 4
code/ASEParser.cpp → code/ASE/ASEParser.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -45,20 +45,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *  @brief Implementation of the ASE parser class
  *  @brief Implementation of the ASE parser class
  */
  */
 
 
-
 #ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
 #ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
 #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
 #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
 
 
 // internal headers
 // internal headers
-#include "TextureTransform.h"
+#include "PostProcessing/TextureTransform.h"
 #include "ASELoader.h"
 #include "ASELoader.h"
+
 #include <assimp/fast_atof.h>
 #include <assimp/fast_atof.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
 
 
 using namespace Assimp;
 using namespace Assimp;
 using namespace Assimp::ASE;
 using namespace Assimp::ASE;
 
 
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Begin an ASE parsing function
 // Begin an ASE parsing function
 
 

+ 7 - 7
code/ASEParser.h → code/ASE/ASEParser.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -57,7 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/qnan.h>
 #include <assimp/qnan.h>
 
 
 // ASE is quite similar to 3ds. We can reuse some structures
 // ASE is quite similar to 3ds. We can reuse some structures
-#include "3DSLoader.h"
+#include "3DS/3DSLoader.h"
 
 
 namespace Assimp    {
 namespace Assimp    {
 namespace ASE   {
 namespace ASE   {
@@ -188,10 +188,11 @@ struct Animation {
     } mRotationType, mScalingType, mPositionType;
     } mRotationType, mScalingType, mPositionType;
 
 
     Animation() AI_NO_EXCEPT
     Animation() AI_NO_EXCEPT
-        :   mRotationType   (TRACK)
-        ,   mScalingType    (TRACK)
-        ,   mPositionType   (TRACK)
-    {}
+    :   mRotationType   (TRACK)
+    ,   mScalingType    (TRACK)
+    ,   mPositionType   (TRACK) {
+        // empty
+    }
 
 
     //! List of track rotation keyframes
     //! List of track rotation keyframes
     std::vector< aiQuatKey > akeyRotations;
     std::vector< aiQuatKey > akeyRotations;
@@ -243,7 +244,6 @@ struct BaseNode {
         mTargetPosition.x = qnan;
         mTargetPosition.x = qnan;
     }
     }
 
 
-
     //! Name of the mesh
     //! Name of the mesh
     std::string mName;
     std::string mName;
 
 

+ 9 - 3
code/AssbinExporter.cpp → code/Assbin/AssbinExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -46,12 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_EXPORT
 #ifndef ASSIMP_BUILD_NO_EXPORT
 #ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
 #ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
 
 
-#include "assbin_chunks.h"
+#include "Common/assbin_chunks.h"
+#include "PostProcessing/ProcessHelper.h"
+
 #include <assimp/version.h>
 #include <assimp/version.h>
 #include <assimp/IOStream.hpp>
 #include <assimp/IOStream.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/Exporter.hpp>
 #include <assimp/Exporter.hpp>
-#include "ProcessHelper.h"
 #include <assimp/Exceptional.h>
 #include <assimp/Exceptional.h>
 
 
 #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
 #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
@@ -760,7 +761,12 @@ public:
         if (!out) return;
         if (!out) return;
 
 
         time_t tt = time(NULL);
         time_t tt = time(NULL);
+#if _WIN32
         tm* p     = gmtime(&tt);
         tm* p     = gmtime(&tt);
+#else
+        struct tm now;
+        tm* p = gmtime_r(&tt, &now);
+#endif
 
 
         // header
         // header
         char s[64];
         char s[64];

+ 1 - 1
code/AssbinExporter.h → code/Assbin/AssbinExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 5 - 5
code/AssbinLoader.cpp → code/Assbin/AssbinLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -50,8 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
 #ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
 
 
 // internal headers
 // internal headers
-#include "AssbinLoader.h"
-#include "assbin_chunks.h"
+#include "Assbin/AssbinLoader.h"
+#include "Common/assbin_chunks.h"
 #include <assimp/MemoryIOWrapper.h>
 #include <assimp/MemoryIOWrapper.h>
 #include <assimp/mesh.h>
 #include <assimp/mesh.h>
 #include <assimp/anim.h>
 #include <assimp/anim.h>
@@ -68,7 +68,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 using namespace Assimp;
 using namespace Assimp;
 
 
 static const aiImporterDesc desc = {
 static const aiImporterDesc desc = {
-    ".assbin Importer",
+    "Assimp Binary Importer",
     "Gargaj / Conspiracy",
     "Gargaj / Conspiracy",
     "",
     "",
     "",
     "",
@@ -708,7 +708,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
 
 
         unsigned char * uncompressedData = new unsigned char[ uncompressedSize ];
         unsigned char * uncompressedData = new unsigned char[ uncompressedSize ];
 
 
-        int res = uncompress( uncompressedData, &uncompressedSize, compressedData, len );
+        int res = uncompress( uncompressedData, &uncompressedSize, compressedData, (uLong) len );
         if(res != Z_OK)
         if(res != Z_OK)
         {
         {
             delete [] uncompressedData;
             delete [] uncompressedData;

+ 1 - 1
code/AssbinLoader.h → code/Assbin/AssbinLoader.h

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 109 - 0
code/Assjson/cencode.c

@@ -0,0 +1,109 @@
+/*
+cencoder.c - c source to a base64 encoding algorithm implementation
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+#include "cencode.h" // changed from <B64/cencode.h>
+
+const int CHARS_PER_LINE = 72;
+
+void base64_init_encodestate(base64_encodestate* state_in)
+{
+	state_in->step = step_A;
+	state_in->result = 0;
+	state_in->stepcount = 0;
+}
+
+char base64_encode_value(char value_in)
+{
+	static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+	if (value_in > 63) return '=';
+	return encoding[(int)value_in];
+}
+
+int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
+{
+	const char* plainchar = plaintext_in;
+	const char* const plaintextend = plaintext_in + length_in;
+	char* codechar = code_out;
+	char result;
+	char fragment;
+	
+	result = state_in->result;
+	
+	switch (state_in->step)
+	{
+		while (1)
+		{
+	case step_A:
+			if (plainchar == plaintextend)
+			{
+				state_in->result = result;
+				state_in->step = step_A;
+				return codechar - code_out;
+			}
+			fragment = *plainchar++;
+			result = (fragment & 0x0fc) >> 2;
+			*codechar++ = base64_encode_value(result);
+			result = (fragment & 0x003) << 4;
+	case step_B:
+			if (plainchar == plaintextend)
+			{
+				state_in->result = result;
+				state_in->step = step_B;
+				return codechar - code_out;
+			}
+			fragment = *plainchar++;
+			result |= (fragment & 0x0f0) >> 4;
+			*codechar++ = base64_encode_value(result);
+			result = (fragment & 0x00f) << 2;
+	case step_C:
+			if (plainchar == plaintextend)
+			{
+				state_in->result = result;
+				state_in->step = step_C;
+				return codechar - code_out;
+			}
+			fragment = *plainchar++;
+			result |= (fragment & 0x0c0) >> 6;
+			*codechar++ = base64_encode_value(result);
+			result  = (fragment & 0x03f) >> 0;
+			*codechar++ = base64_encode_value(result);
+			
+			++(state_in->stepcount);
+			if (state_in->stepcount == CHARS_PER_LINE/4)
+			{
+				*codechar++ = '\n';
+				state_in->stepcount = 0;
+			}
+		}
+	}
+	/* control should not reach here */
+	return codechar - code_out;
+}
+
+int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
+{
+	char* codechar = code_out;
+	
+	switch (state_in->step)
+	{
+	case step_B:
+		*codechar++ = base64_encode_value(state_in->result);
+		*codechar++ = '=';
+		*codechar++ = '=';
+		break;
+	case step_C:
+		*codechar++ = base64_encode_value(state_in->result);
+		*codechar++ = '=';
+		break;
+	case step_A:
+		break;
+	}
+	*codechar++ = '\n';
+	
+	return codechar - code_out;
+}
+

+ 31 - 0
code/Assjson/cencode.h

@@ -0,0 +1,31 @@
+/*
+cencode.h - c header for a base64 encoding algorithm
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+#ifndef BASE64_CENCODE_H
+#define BASE64_CENCODE_H
+
+typedef enum
+{
+	step_A, step_B, step_C
+} base64_encodestep;
+
+typedef struct
+{
+	base64_encodestep step;
+	char result;
+	int stepcount;
+} base64_encodestate;
+
+void base64_init_encodestate(base64_encodestate* state_in);
+
+char base64_encode_value(char value_in);
+
+int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
+
+int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
+
+#endif /* BASE64_CENCODE_H */

+ 809 - 0
code/Assjson/json_exporter.cpp

@@ -0,0 +1,809 @@
+/*
+Assimp2Json
+Copyright (c) 2011, Alexander C. Gessler
+
+Licensed under a 3-clause BSD license. See the LICENSE file for more information.
+
+*/
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+#ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
+
+#include <assimp/Importer.hpp>
+#include <assimp/Exporter.hpp>
+#include <assimp/IOStream.hpp>
+#include <assimp/IOSystem.hpp>
+#include <assimp/scene.h>
+
+#include <sstream>
+#include <limits>
+#include <cassert>
+#include <memory>
+
+#define CURRENT_FORMAT_VERSION 100
+
+// grab scoped_ptr from assimp to avoid a dependency on boost. 
+//#include <assimp/../../code/BoostWorkaround/boost/scoped_ptr.hpp>
+
+#include "mesh_splitter.h"
+
+extern "C" {
+    #include "cencode.h"
+}
+namespace Assimp {
+
+void ExportAssimp2Json(const char*, Assimp::IOSystem*, const aiScene*, const Assimp::ExportProperties*);
+
+// small utility class to simplify serializing the aiScene to Json
+class JSONWriter {
+public:
+    enum {
+        Flag_DoNotIndent = 0x1,
+        Flag_WriteSpecialFloats = 0x2,
+    };
+
+    JSONWriter(Assimp::IOStream& out, unsigned int flags = 0u)
+    : out(out)
+    , first()
+    , flags(flags) {
+        // make sure that all formatting happens using the standard, C locale and not the user's current locale
+        buff.imbue(std::locale("C"));
+    }
+
+    ~JSONWriter() {
+        Flush();
+    }
+
+    void Flush() {
+        const std::string s = buff.str();
+        out.Write(s.c_str(), s.length(), 1);
+        buff.clear();
+    }
+
+    void PushIndent() {
+        indent += '\t';
+    }
+
+    void PopIndent() {
+        indent.erase(indent.end() - 1);
+    }
+
+    void Key(const std::string& name) {
+        AddIndentation();
+        Delimit();
+        buff << '\"' + name + "\": ";
+    }
+
+    template<typename Literal>
+    void Element(const Literal& name) {
+        AddIndentation();
+        Delimit();
+
+        LiteralToString(buff, name) << '\n';
+    }
+
+    template<typename Literal>
+    void SimpleValue(const Literal& s) {
+        LiteralToString(buff, s) << '\n';
+    }
+
+    void SimpleValue(const void* buffer, size_t len) {
+        base64_encodestate s;
+        base64_init_encodestate(&s);
+
+        char* const out = new char[std::max(len * 2, static_cast<size_t>(16u))];
+        const int n = base64_encode_block(reinterpret_cast<const char*>(buffer), static_cast<int>(len), out, &s);
+        out[n + base64_encode_blockend(out + n, &s)] = '\0';
+
+        // base64 encoding may add newlines, but JSON strings may not contain 'real' newlines
+        // (only escaped ones). Remove any newlines in out.
+        for (char* cur = out; *cur; ++cur) {
+            if (*cur == '\n') {
+                *cur = ' ';
+            }
+        }
+
+        buff << '\"' << out << "\"\n";
+        delete[] out;
+    }
+
+    void StartObj(bool is_element = false) {
+        // if this appears as a plain array element, we need to insert a delimiter and we should also indent it
+        if (is_element) {
+            AddIndentation();
+            if (!first) {
+                buff << ',';
+            }
+        }
+        first = true;
+        buff << "{\n";
+        PushIndent();
+    }
+
+    void EndObj() {
+        PopIndent();
+        AddIndentation();
+        first = false;
+        buff << "}\n";
+    }
+
+    void StartArray(bool is_element = false) {
+        // if this appears as a plain array element, we need to insert a delimiter and we should also indent it
+        if (is_element) {
+            AddIndentation();
+            if (!first) {
+                buff << ',';
+            }
+        }
+        first = true;
+        buff << "[\n";
+        PushIndent();
+    }
+
+    void EndArray() {
+        PopIndent();
+        AddIndentation();
+        buff << "]\n";
+        first = false;
+    }
+
+    void AddIndentation() {
+        if (!(flags & Flag_DoNotIndent)) {
+            buff << indent;
+        }
+    }
+
+    void Delimit() {
+        if (!first) {
+            buff << ',';
+        }
+        else {
+            buff << ' ';
+            first = false;
+        }
+    }
+
+private:
+    template<typename Literal>
+    std::stringstream& LiteralToString(std::stringstream& stream, const Literal& s) {
+        stream << s;
+        return stream;
+    }
+
+    std::stringstream& LiteralToString(std::stringstream& stream, const aiString& s) {
+        std::string t;
+
+        // escape backslashes and single quotes, both would render the JSON invalid if left as is
+        t.reserve(s.length);
+        for (size_t i = 0; i < s.length; ++i) {
+
+            if (s.data[i] == '\\' || s.data[i] == '\'' || s.data[i] == '\"') {
+                t.push_back('\\');
+            }
+
+            t.push_back(s.data[i]);
+        }
+        stream << "\"";
+        stream << t;
+        stream << "\"";
+        return stream;
+    }
+
+    std::stringstream& LiteralToString(std::stringstream& stream, float f) {
+        if (!std::numeric_limits<float>::is_iec559) {
+            // on a non IEEE-754 platform, we make no assumptions about the representation or existence
+            // of special floating-point numbers. 
+            stream << f;
+            return stream;
+        }
+
+        // JSON does not support writing Inf/Nan
+        // [RFC 4672: "Numeric values that cannot be represented as sequences of digits
+        // (such as Infinity and NaN) are not permitted."]
+        // Nevertheless, many parsers will accept the special keywords Infinity, -Infinity and NaN
+        if (std::numeric_limits<float>::infinity() == fabs(f)) {
+            if (flags & Flag_WriteSpecialFloats) {
+                stream << (f < 0 ? "\"-" : "\"") + std::string("Infinity\"");
+                return stream;
+            }
+            //  we should print this warning, but we can't - this is called from within a generic assimp exporter, we cannot use cerr
+            //	std::cerr << "warning: cannot represent infinite number literal, substituting 0 instead (use -i flag to enforce Infinity/NaN)" << std::endl;
+            stream << "0.0";
+            return stream;
+        }
+        // f!=f is the most reliable test for NaNs that I know of
+        else if (f != f) {
+            if (flags & Flag_WriteSpecialFloats) {
+                stream << "\"NaN\"";
+                return stream;
+            }
+            //  we should print this warning, but we can't - this is called from within a generic assimp exporter, we cannot use cerr
+            //	std::cerr << "warning: cannot represent infinite number literal, substituting 0 instead (use -i flag to enforce Infinity/NaN)" << std::endl;
+            stream << "0.0";
+            return stream;
+        }
+
+        stream << f;
+        return stream;
+    }
+
+private:
+    Assimp::IOStream& out;
+    std::string indent, newline;
+    std::stringstream buff;
+    bool first;
+
+    unsigned int flags;
+};
+
+void Write(JSONWriter& out, const aiVector3D& ai, bool is_elem = true) {
+    out.StartArray(is_elem);
+    out.Element(ai.x);
+    out.Element(ai.y);
+    out.Element(ai.z);
+    out.EndArray();
+}
+
+void Write(JSONWriter& out, const aiQuaternion& ai, bool is_elem = true) {
+    out.StartArray(is_elem);
+    out.Element(ai.w);
+    out.Element(ai.x);
+    out.Element(ai.y);
+    out.Element(ai.z);
+    out.EndArray();
+}
+
+void Write(JSONWriter& out, const aiColor3D& ai, bool is_elem = true) {
+    out.StartArray(is_elem);
+    out.Element(ai.r);
+    out.Element(ai.g);
+    out.Element(ai.b);
+    out.EndArray();
+}
+
+void Write(JSONWriter& out, const aiMatrix4x4& ai, bool is_elem = true) {
+    out.StartArray(is_elem);
+    for (unsigned int x = 0; x < 4; ++x) {
+        for (unsigned int y = 0; y < 4; ++y) {
+            out.Element(ai[x][y]);
+        }
+    }
+    out.EndArray();
+}
+
+void Write(JSONWriter& out, const aiBone& ai, bool is_elem = true) {
+    out.StartObj(is_elem);
+
+    out.Key("name");
+    out.SimpleValue(ai.mName);
+
+    out.Key("offsetmatrix");
+    Write(out, ai.mOffsetMatrix, false);
+
+    out.Key("weights");
+    out.StartArray();
+    for (unsigned int i = 0; i < ai.mNumWeights; ++i) {
+        out.StartArray(true);
+        out.Element(ai.mWeights[i].mVertexId);
+        out.Element(ai.mWeights[i].mWeight);
+        out.EndArray();
+    }
+    out.EndArray();
+    out.EndObj();
+}
+
+void Write(JSONWriter& out, const aiFace& ai, bool is_elem = true) {
+    out.StartArray(is_elem);
+    for (unsigned int i = 0; i < ai.mNumIndices; ++i) {
+        out.Element(ai.mIndices[i]);
+    }
+    out.EndArray();
+}
+
+void Write(JSONWriter& out, const aiMesh& ai, bool is_elem = true) {
+    out.StartObj(is_elem);
+
+    out.Key("name");
+    out.SimpleValue(ai.mName);
+
+    out.Key("materialindex");
+    out.SimpleValue(ai.mMaterialIndex);
+
+    out.Key("primitivetypes");
+    out.SimpleValue(ai.mPrimitiveTypes);
+
+    out.Key("vertices");
+    out.StartArray();
+    for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
+        out.Element(ai.mVertices[i].x);
+        out.Element(ai.mVertices[i].y);
+        out.Element(ai.mVertices[i].z);
+    }
+    out.EndArray();
+
+    if (ai.HasNormals()) {
+        out.Key("normals");
+        out.StartArray();
+        for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
+            out.Element(ai.mNormals[i].x);
+            out.Element(ai.mNormals[i].y);
+            out.Element(ai.mNormals[i].z);
+        }
+        out.EndArray();
+    }
+
+    if (ai.HasTangentsAndBitangents()) {
+        out.Key("tangents");
+        out.StartArray();
+        for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
+            out.Element(ai.mTangents[i].x);
+            out.Element(ai.mTangents[i].y);
+            out.Element(ai.mTangents[i].z);
+        }
+        out.EndArray();
+
+        out.Key("bitangents");
+        out.StartArray();
+        for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
+            out.Element(ai.mBitangents[i].x);
+            out.Element(ai.mBitangents[i].y);
+            out.Element(ai.mBitangents[i].z);
+        }
+        out.EndArray();
+    }
+
+    if (ai.GetNumUVChannels()) {
+        out.Key("numuvcomponents");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.GetNumUVChannels(); ++n) {
+            out.Element(ai.mNumUVComponents[n]);
+        }
+        out.EndArray();
+
+        out.Key("texturecoords");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.GetNumUVChannels(); ++n) {
+            const unsigned int numc = ai.mNumUVComponents[n] ? ai.mNumUVComponents[n] : 2;
+
+            out.StartArray(true);
+            for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
+                for (unsigned int c = 0; c < numc; ++c) {
+                    out.Element(ai.mTextureCoords[n][i][c]);
+                }
+            }
+            out.EndArray();
+        }
+        out.EndArray();
+    }
+
+    if (ai.GetNumColorChannels()) {
+        out.Key("colors");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.GetNumColorChannels(); ++n) {
+            out.StartArray(true);
+            for (unsigned int i = 0; i < ai.mNumVertices; ++i) {
+                out.Element(ai.mColors[n][i].r);
+                out.Element(ai.mColors[n][i].g);
+                out.Element(ai.mColors[n][i].b);
+                out.Element(ai.mColors[n][i].a);
+            }
+            out.EndArray();
+        }
+        out.EndArray();
+    }
+
+    if (ai.mNumBones) {
+        out.Key("bones");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumBones; ++n) {
+            Write(out, *ai.mBones[n]);
+        }
+        out.EndArray();
+    }
+
+    out.Key("faces");
+    out.StartArray();
+    for (unsigned int n = 0; n < ai.mNumFaces; ++n) {
+        Write(out, ai.mFaces[n]);
+    }
+    out.EndArray();
+
+    out.EndObj();
+}
+
+void Write(JSONWriter& out, const aiNode& ai, bool is_elem = true) {
+    out.StartObj(is_elem);
+
+    out.Key("name");
+    out.SimpleValue(ai.mName);
+
+    out.Key("transformation");
+    Write(out, ai.mTransformation, false);
+
+    if (ai.mNumMeshes) {
+        out.Key("meshes");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumMeshes; ++n) {
+            out.Element(ai.mMeshes[n]);
+        }
+        out.EndArray();
+    }
+
+    if (ai.mNumChildren) {
+        out.Key("children");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumChildren; ++n) {
+            Write(out, *ai.mChildren[n]);
+        }
+        out.EndArray();
+    }
+
+    out.EndObj();
+}
+
+void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) {
+    out.StartObj(is_elem);
+
+    out.Key("properties");
+    out.StartArray();
+    for (unsigned int i = 0; i < ai.mNumProperties; ++i) {
+        const aiMaterialProperty* const prop = ai.mProperties[i];
+        out.StartObj(true);
+        out.Key("key");
+        out.SimpleValue(prop->mKey);
+        out.Key("semantic");
+        out.SimpleValue(prop->mSemantic);
+        out.Key("index");
+        out.SimpleValue(prop->mIndex);
+
+        out.Key("type");
+        out.SimpleValue(prop->mType);
+
+        out.Key("value");
+        switch (prop->mType) {
+            case aiPTI_Float:
+                if (prop->mDataLength / sizeof(float) > 1) {
+                    out.StartArray();
+                    for (unsigned int i = 0; i < prop->mDataLength / sizeof(float); ++i) {
+                        out.Element(reinterpret_cast<float*>(prop->mData)[i]);
+                    }
+                    out.EndArray();
+                }
+                else {
+                    out.SimpleValue(*reinterpret_cast<float*>(prop->mData));
+                }
+                break;
+
+            case aiPTI_Integer:
+                if (prop->mDataLength / sizeof(int) > 1) {
+                    out.StartArray();
+                    for (unsigned int i = 0; i < prop->mDataLength / sizeof(int); ++i) {
+                        out.Element(reinterpret_cast<int*>(prop->mData)[i]);
+                    }
+                    out.EndArray();
+                } else {
+                    out.SimpleValue(*reinterpret_cast<int*>(prop->mData));
+                }
+                break;
+
+            case aiPTI_String:
+                {
+                    aiString s;
+                    aiGetMaterialString(&ai, prop->mKey.data, prop->mSemantic, prop->mIndex, &s);
+                    out.SimpleValue(s);
+                }
+                break;
+            case aiPTI_Buffer:
+                {
+                    // binary data is written as series of hex-encoded octets
+                    out.SimpleValue(prop->mData, prop->mDataLength);
+                }
+                break;
+            default:
+                assert(false);
+        }
+
+        out.EndObj();
+    }
+
+    out.EndArray();
+    out.EndObj();
+}
+
+void Write(JSONWriter& out, const aiTexture& ai, bool is_elem = true) {
+    out.StartObj(is_elem);
+
+    out.Key("width");
+    out.SimpleValue(ai.mWidth);
+
+    out.Key("height");
+    out.SimpleValue(ai.mHeight);
+
+    out.Key("formathint");
+    out.SimpleValue(aiString(ai.achFormatHint));
+
+    out.Key("data");
+    if (!ai.mHeight) {
+        out.SimpleValue(ai.pcData, ai.mWidth);
+    }
+    else {
+        out.StartArray();
+        for (unsigned int y = 0; y < ai.mHeight; ++y) {
+            out.StartArray(true);
+            for (unsigned int x = 0; x < ai.mWidth; ++x) {
+                const aiTexel& tx = ai.pcData[y*ai.mWidth + x];
+                out.StartArray(true);
+                out.Element(static_cast<unsigned int>(tx.r));
+                out.Element(static_cast<unsigned int>(tx.g));
+                out.Element(static_cast<unsigned int>(tx.b));
+                out.Element(static_cast<unsigned int>(tx.a));
+                out.EndArray();
+            }
+            out.EndArray();
+        }
+        out.EndArray();
+    }
+
+    out.EndObj();
+}
+
+void Write(JSONWriter& out, const aiLight& ai, bool is_elem = true) {
+    out.StartObj(is_elem);
+
+    out.Key("name");
+    out.SimpleValue(ai.mName);
+
+    out.Key("type");
+    out.SimpleValue(ai.mType);
+
+    if (ai.mType == aiLightSource_SPOT || ai.mType == aiLightSource_UNDEFINED) {
+        out.Key("angleinnercone");
+        out.SimpleValue(ai.mAngleInnerCone);
+
+        out.Key("angleoutercone");
+        out.SimpleValue(ai.mAngleOuterCone);
+    }
+
+    out.Key("attenuationconstant");
+    out.SimpleValue(ai.mAttenuationConstant);
+
+    out.Key("attenuationlinear");
+    out.SimpleValue(ai.mAttenuationLinear);
+
+    out.Key("attenuationquadratic");
+    out.SimpleValue(ai.mAttenuationQuadratic);
+
+    out.Key("diffusecolor");
+    Write(out, ai.mColorDiffuse, false);
+
+    out.Key("specularcolor");
+    Write(out, ai.mColorSpecular, false);
+
+    out.Key("ambientcolor");
+    Write(out, ai.mColorAmbient, false);
+
+    if (ai.mType != aiLightSource_POINT) {
+        out.Key("direction");
+        Write(out, ai.mDirection, false);
+
+    }
+
+    if (ai.mType != aiLightSource_DIRECTIONAL) {
+        out.Key("position");
+        Write(out, ai.mPosition, false);
+    }
+
+    out.EndObj();
+}
+
+void Write(JSONWriter& out, const aiNodeAnim& ai, bool is_elem = true) {
+    out.StartObj(is_elem);
+
+    out.Key("name");
+    out.SimpleValue(ai.mNodeName);
+
+    out.Key("prestate");
+    out.SimpleValue(ai.mPreState);
+
+    out.Key("poststate");
+    out.SimpleValue(ai.mPostState);
+
+    if (ai.mNumPositionKeys) {
+        out.Key("positionkeys");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumPositionKeys; ++n) {
+            const aiVectorKey& pos = ai.mPositionKeys[n];
+            out.StartArray(true);
+            out.Element(pos.mTime);
+            Write(out, pos.mValue);
+            out.EndArray();
+        }
+        out.EndArray();
+    }
+
+    if (ai.mNumRotationKeys) {
+        out.Key("rotationkeys");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumRotationKeys; ++n) {
+            const aiQuatKey& rot = ai.mRotationKeys[n];
+            out.StartArray(true);
+            out.Element(rot.mTime);
+            Write(out, rot.mValue);
+            out.EndArray();
+        }
+        out.EndArray();
+    }
+
+    if (ai.mNumScalingKeys) {
+        out.Key("scalingkeys");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumScalingKeys; ++n) {
+            const aiVectorKey& scl = ai.mScalingKeys[n];
+            out.StartArray(true);
+            out.Element(scl.mTime);
+            Write(out, scl.mValue);
+            out.EndArray();
+        }
+        out.EndArray();
+    }
+    out.EndObj();
+}
+
+void Write(JSONWriter& out, const aiAnimation& ai, bool is_elem = true) {
+    out.StartObj(is_elem);
+
+    out.Key("name");
+    out.SimpleValue(ai.mName);
+
+    out.Key("tickspersecond");
+    out.SimpleValue(ai.mTicksPerSecond);
+
+    out.Key("duration");
+    out.SimpleValue(ai.mDuration);
+
+    out.Key("channels");
+    out.StartArray();
+    for (unsigned int n = 0; n < ai.mNumChannels; ++n) {
+        Write(out, *ai.mChannels[n]);
+    }
+    out.EndArray();
+    out.EndObj();
+}
+
+void Write(JSONWriter& out, const aiCamera& ai, bool is_elem = true) {
+    out.StartObj(is_elem);
+
+    out.Key("name");
+    out.SimpleValue(ai.mName);
+
+    out.Key("aspect");
+    out.SimpleValue(ai.mAspect);
+
+    out.Key("clipplanefar");
+    out.SimpleValue(ai.mClipPlaneFar);
+
+    out.Key("clipplanenear");
+    out.SimpleValue(ai.mClipPlaneNear);
+
+    out.Key("horizontalfov");
+    out.SimpleValue(ai.mHorizontalFOV);
+
+    out.Key("up");
+    Write(out, ai.mUp, false);
+
+    out.Key("lookat");
+    Write(out, ai.mLookAt, false);
+
+    out.EndObj();
+}
+
+void WriteFormatInfo(JSONWriter& out) {
+    out.StartObj();
+    out.Key("format");
+    out.SimpleValue("\"assimp2json\"");
+    out.Key("version");
+    out.SimpleValue(CURRENT_FORMAT_VERSION);
+    out.EndObj();
+}
+
+void Write(JSONWriter& out, const aiScene& ai) {
+    out.StartObj();
+
+    out.Key("__metadata__");
+    WriteFormatInfo(out);
+
+    out.Key("rootnode");
+    Write(out, *ai.mRootNode, false);
+
+    out.Key("flags");
+    out.SimpleValue(ai.mFlags);
+
+    if (ai.HasMeshes()) {
+        out.Key("meshes");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumMeshes; ++n) {
+            Write(out, *ai.mMeshes[n]);
+        }
+        out.EndArray();
+    }
+
+    if (ai.HasMaterials()) {
+        out.Key("materials");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumMaterials; ++n) {
+            Write(out, *ai.mMaterials[n]);
+        }
+        out.EndArray();
+    }
+
+    if (ai.HasAnimations()) {
+        out.Key("animations");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumAnimations; ++n) {
+            Write(out, *ai.mAnimations[n]);
+        }
+        out.EndArray();
+    }
+
+    if (ai.HasLights()) {
+        out.Key("lights");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumLights; ++n) {
+            Write(out, *ai.mLights[n]);
+        }
+        out.EndArray();
+    }
+
+    if (ai.HasCameras()) {
+        out.Key("cameras");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumCameras; ++n) {
+            Write(out, *ai.mCameras[n]);
+        }
+        out.EndArray();
+    }
+
+    if (ai.HasTextures()) {
+        out.Key("textures");
+        out.StartArray();
+        for (unsigned int n = 0; n < ai.mNumTextures; ++n) {
+            Write(out, *ai.mTextures[n]);
+        }
+        out.EndArray();
+    }
+    out.EndObj();
+}
+
+
+void ExportAssimp2Json(const char* file, Assimp::IOSystem* io, const aiScene* scene, const Assimp::ExportProperties*) {
+    std::unique_ptr<Assimp::IOStream> str(io->Open(file, "wt"));
+    if (!str) {
+        //throw Assimp::DeadlyExportError("could not open output file");
+    }
+
+    // get a copy of the scene so we can modify it
+    aiScene* scenecopy_tmp;
+    aiCopyScene(scene, &scenecopy_tmp);
+
+    try {
+        // split meshes so they fit into a 16 bit index buffer
+        MeshSplitter splitter;
+        splitter.SetLimit(1 << 16);
+        splitter.Execute(scenecopy_tmp);
+
+        // XXX Flag_WriteSpecialFloats is turned on by default, right now we don't have a configuration interface for exporters
+        JSONWriter s(*str, JSONWriter::Flag_WriteSpecialFloats);
+        Write(s, *scenecopy_tmp);
+
+    }
+    catch (...) {
+        aiFreeScene(scenecopy_tmp);
+        throw;
+    }
+    aiFreeScene(scenecopy_tmp);
+}
+
+}
+
+#endif // ASSIMP_BUILD_NO_ASSJSON_EXPORTER
+#endif // ASSIMP_BUILD_NO_EXPORT

+ 320 - 0
code/Assjson/mesh_splitter.cpp

@@ -0,0 +1,320 @@
+/*
+Assimp2Json
+Copyright (c) 2011, Alexander C. Gessler
+
+Licensed under a 3-clause BSD license. See the LICENSE file for more information.
+
+*/
+
+#include "mesh_splitter.h"
+
+#include <assimp/scene.h>
+
+// ----------------------------------------------------------------------------
+// Note: this is largely based on assimp's SplitLargeMeshes_Vertex process.
+// it is refactored and the coding style is slightly improved, though.
+// ----------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------------------------------
+// Executes the post processing step on the given imported data.
+void MeshSplitter::Execute( aiScene* pScene) {
+	std::vector<std::pair<aiMesh*, unsigned int> > source_mesh_map;
+
+	for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
+		SplitMesh(a, pScene->mMeshes[a],source_mesh_map);
+	}
+
+	const unsigned int size = static_cast<unsigned int>(source_mesh_map.size());
+	if (size != pScene->mNumMeshes) {
+		// it seems something has been split. rebuild the mesh list
+		delete[] pScene->mMeshes;
+		pScene->mNumMeshes = size;
+		pScene->mMeshes = new aiMesh*[size]();
+
+		for (unsigned int i = 0; i < size;++i) {
+			pScene->mMeshes[i] = source_mesh_map[i].first;
+		}
+
+		// now we need to update all nodes
+		UpdateNode(pScene->mRootNode,source_mesh_map);
+	}
+}
+
+
+// ------------------------------------------------------------------------------------------------
+void MeshSplitter::UpdateNode(aiNode* pcNode, const std::vector<std::pair<aiMesh*, unsigned int> >& source_mesh_map) {
+	// TODO: should better use std::(multi)set for source_mesh_map.
+
+	// for every index in out list build a new entry
+	std::vector<unsigned int> aiEntries;
+	aiEntries.reserve(pcNode->mNumMeshes + 1);
+	for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)	{
+		for (unsigned int a = 0, end = static_cast<unsigned int>(source_mesh_map.size()); a < end;++a)	{
+			if (source_mesh_map[a].second == pcNode->mMeshes[i])	{
+				aiEntries.push_back(a);
+			}
+		}
+	}
+
+	// now build the new list
+	delete pcNode->mMeshes;
+	pcNode->mNumMeshes = static_cast<unsigned int>(aiEntries.size());
+	pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
+
+	for (unsigned int b = 0; b < pcNode->mNumMeshes;++b) {
+		pcNode->mMeshes[b] = aiEntries[b];
+	}
+
+	// recursively update children
+	for (unsigned int i = 0, end = pcNode->mNumChildren; i < end;++i)	{
+		UpdateNode ( pcNode->mChildren[i], source_mesh_map );
+	}
+	return;
+}
+
+#define WAS_NOT_COPIED 0xffffffff
+
+typedef std::pair <unsigned int,float> PerVertexWeight;
+typedef std::vector	<PerVertexWeight> VertexWeightTable;
+
+// ------------------------------------------------------------------------------------------------
+VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh) {
+	if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones) {
+		return nullptr;
+	}
+
+	VertexWeightTable* const avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices];
+	for (unsigned int i = 0; i < pMesh->mNumBones;++i)	{
+
+		aiBone* bone = pMesh->mBones[i];
+		for (unsigned int a = 0; a < bone->mNumWeights;++a)	{
+			const aiVertexWeight& weight = bone->mWeights[a];
+			avPerVertexWeights[weight.mVertexId].push_back( std::make_pair(i,weight.mWeight) );
+		}
+	}
+	return avPerVertexWeights;
+}
+
+// ------------------------------------------------------------------------------------------------
+void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std::pair<aiMesh*, unsigned int> >& source_mesh_map) {
+	// TODO: should better use std::(multi)set for source_mesh_map.
+
+	if (in_mesh->mNumVertices <= LIMIT)	{
+		source_mesh_map.push_back(std::make_pair(in_mesh,a));
+		return;
+	}
+
+	// build a per-vertex weight list if necessary
+	VertexWeightTable* avPerVertexWeights = ComputeVertexBoneWeightTable(in_mesh);
+
+	// we need to split this mesh into sub meshes. Estimate submesh size
+	const unsigned int sub_meshes = (in_mesh->mNumVertices / LIMIT) + 1;
+
+	// create a std::vector<unsigned int> to remember which vertices have already 
+	// been copied and to which position (i.e. output index)
+	std::vector<unsigned int> was_copied_to;
+	was_copied_to.resize(in_mesh->mNumVertices,WAS_NOT_COPIED);
+
+	// Try to find a good estimate for the number of output faces
+	// per mesh. Add 12.5% as buffer
+	unsigned int size_estimated = in_mesh->mNumFaces / sub_meshes;
+	size_estimated += size_estimated / 8;
+
+	// now generate all submeshes
+	unsigned int base = 0;
+	while (true) {
+		const unsigned int out_vertex_index = LIMIT;
+
+		aiMesh* out_mesh = new aiMesh();			
+		out_mesh->mNumVertices = 0;
+		out_mesh->mMaterialIndex = in_mesh->mMaterialIndex;
+
+		// the name carries the adjacency information between the meshes
+		out_mesh->mName = in_mesh->mName;
+
+		typedef std::vector<aiVertexWeight> BoneWeightList;
+		if (in_mesh->HasBones())	{
+			out_mesh->mBones = new aiBone*[in_mesh->mNumBones]();
+		}
+
+		// clear the temporary helper array
+		if (base)	{
+			std::fill(was_copied_to.begin(), was_copied_to.end(), WAS_NOT_COPIED);
+		}
+
+		std::vector<aiFace> vFaces;
+
+		// reserve enough storage for most cases
+		if (in_mesh->HasPositions()) {
+			out_mesh->mVertices = new aiVector3D[out_vertex_index];
+		}
+
+		if (in_mesh->HasNormals()) {
+			out_mesh->mNormals = new aiVector3D[out_vertex_index];
+		}
+
+		if (in_mesh->HasTangentsAndBitangents())	{
+			out_mesh->mTangents = new aiVector3D[out_vertex_index];
+			out_mesh->mBitangents = new aiVector3D[out_vertex_index];
+		}
+
+		for (unsigned int c = 0; in_mesh->HasVertexColors(c);++c)	{
+			out_mesh->mColors[c] = new aiColor4D[out_vertex_index];
+		}
+
+		for (unsigned int c = 0; in_mesh->HasTextureCoords(c);++c)	{
+			out_mesh->mNumUVComponents[c] = in_mesh->mNumUVComponents[c];
+			out_mesh->mTextureCoords[c] = new aiVector3D[out_vertex_index];
+		}
+		vFaces.reserve(size_estimated);
+
+		// (we will also need to copy the array of indices)
+		while (base < in_mesh->mNumFaces) {
+			const unsigned int iNumIndices = in_mesh->mFaces[base].mNumIndices;
+
+			// doesn't catch degenerates but is quite fast
+			unsigned int iNeed = 0;
+			for (unsigned int v = 0; v < iNumIndices;++v)	{
+				unsigned int index = in_mesh->mFaces[base].mIndices[v];
+
+				// check whether we do already have this vertex
+				if (WAS_NOT_COPIED == was_copied_to[index])	{
+					iNeed++; 
+				}
+			}
+			if (out_mesh->mNumVertices + iNeed > out_vertex_index)	{
+				// don't use this face
+				break;
+			}
+
+			vFaces.push_back(aiFace());
+			aiFace& rFace = vFaces.back();
+
+			// setup face type and number of indices
+			rFace.mNumIndices = iNumIndices;
+			rFace.mIndices = new unsigned int[iNumIndices];
+
+			// need to update the output primitive types
+			switch (rFace.mNumIndices)
+			{
+			case 1:
+				out_mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
+				break;
+			case 2:
+				out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
+				break;
+			case 3:
+				out_mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
+				break;
+			default:
+				out_mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
+			}
+
+			// and copy the contents of the old array, offset them by current base
+			for (unsigned int v = 0; v < iNumIndices;++v) {
+				const unsigned int index = in_mesh->mFaces[base].mIndices[v];
+
+				// check whether we do already have this vertex
+				if (WAS_NOT_COPIED != was_copied_to[index]) {
+					rFace.mIndices[v] = was_copied_to[index];
+					continue;
+				}
+
+				// copy positions
+				out_mesh->mVertices[out_mesh->mNumVertices] = (in_mesh->mVertices[index]);
+
+				// copy normals
+				if (in_mesh->HasNormals()) {
+					out_mesh->mNormals[out_mesh->mNumVertices] = (in_mesh->mNormals[index]);
+				}
+
+				// copy tangents/bi-tangents
+				if (in_mesh->HasTangentsAndBitangents()) {
+					out_mesh->mTangents[out_mesh->mNumVertices] = (in_mesh->mTangents[index]);
+					out_mesh->mBitangents[out_mesh->mNumVertices] = (in_mesh->mBitangents[index]);
+				}
+
+				// texture coordinates
+				for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
+					if (in_mesh->HasTextureCoords( c)) {
+						out_mesh->mTextureCoords[c][out_mesh->mNumVertices] = in_mesh->mTextureCoords[c][index];
+					}
+				}
+				// vertex colors 
+				for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) {
+					if (in_mesh->HasVertexColors( c)) {
+						out_mesh->mColors[c][out_mesh->mNumVertices] = in_mesh->mColors[c][index];
+					}
+				}
+				// check whether we have bone weights assigned to this vertex
+				rFace.mIndices[v] = out_mesh->mNumVertices;
+				if (avPerVertexWeights) {
+					VertexWeightTable& table = avPerVertexWeights[ out_mesh->mNumVertices ];
+					for (VertexWeightTable::const_iterator iter = table.begin(), end = table.end(); iter != end;++iter) {
+						// allocate the bone weight array if necessary and store it in the mBones field (HACK!)
+						BoneWeightList* weight_list = reinterpret_cast<BoneWeightList*>(out_mesh->mBones[(*iter).first]);
+						if (!weight_list) {
+							weight_list = new BoneWeightList();
+							out_mesh->mBones[(*iter).first] = reinterpret_cast<aiBone*>(weight_list);
+						}
+						weight_list->push_back(aiVertexWeight(out_mesh->mNumVertices,(*iter).second));
+					}
+				}
+
+				was_copied_to[index] = out_mesh->mNumVertices;
+				out_mesh->mNumVertices++;
+			}
+			base++;
+			if(out_mesh->mNumVertices == out_vertex_index) {
+				// break here. The face is only added if it was complete
+				break;
+			}
+		}
+
+		// check which bones we'll need to create for this submesh
+		if (in_mesh->HasBones()) {
+			aiBone** ppCurrent = out_mesh->mBones;
+			for (unsigned int k = 0; k < in_mesh->mNumBones;++k) {
+				// check whether the bone exists
+				BoneWeightList* const weight_list = reinterpret_cast<BoneWeightList*>(out_mesh->mBones[k]);
+
+				if (weight_list) {
+					const aiBone* const bone_in = in_mesh->mBones[k];
+					aiBone* const bone_out = new aiBone();
+					*ppCurrent++ = bone_out;
+					bone_out->mName = aiString(bone_in->mName);
+					bone_out->mOffsetMatrix =bone_in->mOffsetMatrix;
+					bone_out->mNumWeights = (unsigned int)weight_list->size();
+					bone_out->mWeights = new aiVertexWeight[bone_out->mNumWeights];
+
+					// copy the vertex weights
+					::memcpy(bone_out->mWeights, &(*weight_list)[0],bone_out->mNumWeights * sizeof(aiVertexWeight));
+
+					delete weight_list;
+					out_mesh->mNumBones++;
+				}
+			}
+		}
+
+		// copy the face list to the mesh
+		out_mesh->mFaces = new aiFace[vFaces.size()];
+		out_mesh->mNumFaces = (unsigned int)vFaces.size();
+
+		for (unsigned int p = 0; p < out_mesh->mNumFaces;++p) {
+			out_mesh->mFaces[p] = vFaces[p];
+		}
+
+		// add the newly created mesh to the list
+		source_mesh_map.push_back(std::make_pair(out_mesh,a));
+
+		if (base == in_mesh->mNumFaces) {
+			break;
+		}
+	}
+
+	// delete the per-vertex weight list again
+	delete[] avPerVertexWeights;
+
+	// now delete the old mesh data
+	delete in_mesh;
+}

+ 61 - 0
code/Assjson/mesh_splitter.h

@@ -0,0 +1,61 @@
+/*
+Assimp2Json
+Copyright (c) 2011, Alexander C. Gessler
+
+Licensed under a 3-clause BSD license. See the LICENSE file for more information.
+
+*/
+
+#ifndef INCLUDED_MESH_SPLITTER
+#define INCLUDED_MESH_SPLITTER
+
+// ----------------------------------------------------------------------------
+// Note: this is largely based on assimp's SplitLargeMeshes_Vertex process.
+// it is refactored and the coding style is slightly improved, though.
+// ----------------------------------------------------------------------------
+
+#include <vector>
+
+struct aiScene;
+struct aiMesh;
+struct aiNode;
+
+// ---------------------------------------------------------------------------
+/** Splits meshes of unique vertices into meshes with no more vertices than
+ *  a given, configurable threshold value. 
+ */
+class MeshSplitter 
+{
+
+public:
+	
+	void SetLimit(unsigned int l) {
+		LIMIT = l;
+	}
+
+	unsigned int GetLimit() const {
+		return LIMIT;
+	}
+
+public:
+
+	// -------------------------------------------------------------------
+	/** Executes the post processing step on the given imported data.
+	 * At the moment a process is not supposed to fail.
+	 * @param pScene The imported data to work at.
+	 */
+	void Execute( aiScene* pScene);
+
+
+private:
+
+	void UpdateNode(aiNode* pcNode, const std::vector<std::pair<aiMesh*, unsigned int> >& source_mesh_map);
+	void SplitMesh (unsigned int index, aiMesh* mesh, std::vector<std::pair<aiMesh*, unsigned int> >& source_mesh_map);
+
+public:
+
+	unsigned int LIMIT;
+};
+
+#endif // INCLUDED_MESH_SPLITTER
+

+ 12 - 7
code/AssxmlExporter.cpp → code/Assxml/AssxmlExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -46,13 +46,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_EXPORT
 #ifndef ASSIMP_BUILD_NO_EXPORT
 #ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
 #ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
 
 
-#include <stdarg.h>
+#include "PostProcessing/ProcessHelper.h"
+
 #include <assimp/version.h>
 #include <assimp/version.h>
-#include "ProcessHelper.h"
 #include <assimp/IOStream.hpp>
 #include <assimp/IOStream.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/Exporter.hpp>
 #include <assimp/Exporter.hpp>
 
 
+#include <stdarg.h>
+
 #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
 #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
 #   include <zlib.h>
 #   include <zlib.h>
 #else
 #else
@@ -184,8 +186,13 @@ static std::string encodeXML(const std::string& data) {
 static
 static
 void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
 void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
     time_t tt = ::time( NULL );
     time_t tt = ::time( NULL );
-    tm* p     = ::gmtime( &tt );
-    ai_assert( nullptr != p );
+#if _WIN32
+    tm* p = gmtime(&tt);
+#else
+    struct tm now;
+    tm* p = gmtime_r(&tt, &now);
+#endif
+    ai_assert(nullptr != p);
 
 
     // write header
     // write header
     std::string header(
     std::string header(
@@ -550,8 +557,6 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
                             mesh->mNormals[n].z);
                             mesh->mNormals[n].z);
                     }
                     }
                 }
                 }
-                else {
-                }
                 ioprintf(io,"\t\t</Normals>\n");
                 ioprintf(io,"\t\t</Normals>\n");
             }
             }
 
 

+ 1 - 1
code/AssxmlExporter.h → code/Assxml/AssxmlExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 7 - 5
code/B3DImporter.cpp → code/B3D/B3DImporter.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -49,17 +49,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
 #ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
 
 
 // internal headers
 // internal headers
-#include "B3DImporter.h"
-#include "TextureTransform.h"
-#include "ConvertToLHProcess.h"
+#include "B3D/B3DImporter.h"
+#include "PostProcessing/TextureTransform.h"
+#include "PostProcessing/ConvertToLHProcess.h"
+
 #include <assimp/StringUtils.h>
 #include <assimp/StringUtils.h>
-#include <memory>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 #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/importerdesc.h>
 #include <assimp/importerdesc.h>
 
 
+#include <memory>
+
 using namespace Assimp;
 using namespace Assimp;
 using namespace std;
 using namespace std;
 
 

+ 1 - 1
code/B3DImporter.h → code/B3D/B3DImporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 1 - 1
code/BVHLoader.cpp → code/BVH/BVHLoader.cpp

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 

+ 1 - 1
code/BVHLoader.h → code/BVH/BVHLoader.h

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 0 - 0
code/BlenderBMesh.cpp → code/Blender/BlenderBMesh.cpp


+ 0 - 0
code/BlenderBMesh.h → code/Blender/BlenderBMesh.h


+ 5 - 1
code/BlenderCustomData.cpp → code/Blender/BlenderCustomData.cpp

@@ -28,7 +28,11 @@ namespace Assimp {
 
 
 #define IMPL_STRUCT_READ(ty)                                                    \
 #define IMPL_STRUCT_READ(ty)                                                    \
         bool read##ty(ElemBase *v, const size_t cnt, const FileDatabase &db) {  \
         bool read##ty(ElemBase *v, const size_t cnt, const FileDatabase &db) {  \
-            return read<ty>(db.dna[#ty], dynamic_cast<ty *>(v), cnt, db);       \
+        ty *ptr = dynamic_cast<ty*>(v);                                         \
+        if (nullptr == ptr) {                                                   \
+            return false;                                                       \
+        }                                                                       \
+        return read<ty>(db.dna[#ty], ptr, cnt, db);                             \
         }
         }
 
 
 #define IMPL_STRUCT_CREATE(ty)                                                  \
 #define IMPL_STRUCT_CREATE(ty)                                                  \

+ 0 - 0
code/BlenderCustomData.h → code/Blender/BlenderCustomData.h


+ 1 - 1
code/BlenderDNA.cpp → code/Blender/BlenderDNA.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 2 - 2
code/BlenderDNA.h → code/Blender/BlenderDNA.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -416,7 +416,7 @@ template <> struct Structure :: _defaultInitializer<ErrorPolicy_Fail> {
     void operator ()(T& /*out*/,const char* = "") {
     void operator ()(T& /*out*/,const char* = "") {
         // obviously, it is crucial that _DefaultInitializer is used
         // obviously, it is crucial that _DefaultInitializer is used
         // only from within a catch clause.
         // only from within a catch clause.
-        throw;
+        throw DeadlyImportError("Constructing BlenderDNA Structure encountered an error");
     }
     }
 };
 };
 
 

+ 1 - 1
code/BlenderDNA.inl → code/Blender/BlenderDNA.inl

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 1 - 1
code/BlenderIntermediate.h → code/Blender/BlenderIntermediate.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 28 - 1
code/BlenderLoader.cpp → code/Blender/BlenderLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -1225,6 +1225,16 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
         case Lamp::Type_Local:
         case Lamp::Type_Local:
             out->mType = aiLightSource_POINT;
             out->mType = aiLightSource_POINT;
             break;
             break;
+        case Lamp::Type_Spot:
+            out->mType = aiLightSource_SPOT;
+
+            // blender orients directional lights as facing toward -z
+            out->mDirection = aiVector3D(0.f, 0.f, -1.f);
+            out->mUp = aiVector3D(0.f, 1.f, 0.f);
+
+            out->mAngleInnerCone = lamp->spotsize * (1.0f - lamp->spotblend);
+            out->mAngleOuterCone = lamp->spotsize;
+            break;
         case Lamp::Type_Sun:
         case Lamp::Type_Sun:
             out->mType = aiLightSource_DIRECTIONAL;
             out->mType = aiLightSource_DIRECTIONAL;
 
 
@@ -1255,6 +1265,23 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
     out->mColorAmbient = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
     out->mColorAmbient = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
     out->mColorSpecular = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
     out->mColorSpecular = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
     out->mColorDiffuse = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
     out->mColorDiffuse = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
+
+    // If default values are supplied, compute the coefficients from light's max distance
+    // Read this: https://imdoingitwrong.wordpress.com/2011/01/31/light-attenuation/
+    //
+    if (lamp->constant_coefficient == 1.0f && lamp->linear_coefficient == 0.0f && lamp->quadratic_coefficient == 0.0f && lamp->dist > 0.0f)
+    {
+        out->mAttenuationConstant = 1.0f;
+        out->mAttenuationLinear = 2.0f / lamp->dist;
+        out->mAttenuationQuadratic = 1.0f / (lamp->dist * lamp->dist);
+    }
+    else
+    {
+        out->mAttenuationConstant = lamp->constant_coefficient;
+        out->mAttenuationLinear = lamp->linear_coefficient;
+        out->mAttenuationQuadratic = lamp->quadratic_coefficient;
+    }
+
     return out.release();
     return out.release();
 }
 }
 
 

+ 1 - 1
code/BlenderLoader.h → code/Blender/BlenderLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 1 - 1
code/BlenderModifier.cpp → code/Blender/BlenderModifier.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 1 - 1
code/BlenderModifier.h → code/Blender/BlenderModifier.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 4 - 1
code/BlenderScene.cpp → code/Blender/BlenderScene.cpp

@@ -211,9 +211,12 @@ template <> void Structure :: Convert<Lamp> (
     ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
     ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
     ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
     ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
     ReadField<ErrorPolicy_Igno>(dest.energy,"energy",db);
     ReadField<ErrorPolicy_Igno>(dest.energy,"energy",db);
-    ReadField<ErrorPolicy_Igno>(dest.dist,"dist",db);
+    ReadField<ErrorPolicy_Warn>(dest.dist,"dist",db);
     ReadField<ErrorPolicy_Igno>(dest.spotsize,"spotsize",db);
     ReadField<ErrorPolicy_Igno>(dest.spotsize,"spotsize",db);
     ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
     ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
+    ReadField<ErrorPolicy_Warn>(dest.constant_coefficient, "coeff_const", db);
+    ReadField<ErrorPolicy_Warn>(dest.linear_coefficient, "coeff_lin", db);
+    ReadField<ErrorPolicy_Warn>(dest.quadratic_coefficient, "coeff_quad", db);
     ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
     ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
     ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
     ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
     ReadField<ErrorPolicy_Igno>(temp,"falloff_type",db);
     ReadField<ErrorPolicy_Igno>(temp,"falloff_type",db);

+ 5 - 1
code/BlenderScene.h → code/Blender/BlenderScene.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -538,6 +538,10 @@ struct Lamp : ElemBase {
       float energy, dist, spotsize, spotblend;
       float energy, dist, spotsize, spotblend;
       //float haint;
       //float haint;
 
 
+      float constant_coefficient;
+      float linear_coefficient;
+      float quadratic_coefficient;
+
       float att1, att2;
       float att1, att2;
       //struct CurveMapping *curfalloff;
       //struct CurveMapping *curfalloff;
       FalloffType falloff_type;
       FalloffType falloff_type;

+ 0 - 0
code/BlenderSceneGen.h → code/Blender/BlenderSceneGen.h


+ 1 - 1
code/BlenderTessellator.cpp → code/Blender/BlenderTessellator.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 6 - 2
code/BlenderTessellator.h → code/Blender/BlenderTessellator.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -144,7 +144,11 @@ namespace Assimp
 
 
 #if ASSIMP_BLEND_WITH_POLY_2_TRI
 #if ASSIMP_BLEND_WITH_POLY_2_TRI
 
 
-#include "../contrib/poly2tri/poly2tri/poly2tri.h"
+#ifdef ASSIMP_USE_HUNTER
+#  include <poly2tri/poly2tri.h>
+#else
+#  include "../contrib/poly2tri/poly2tri/poly2tri.h"
+#endif
 
 
 namespace Assimp
 namespace Assimp
 {
 {

+ 63 - 92
code/C4DImporter.cpp → code/C4D/C4DImporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2012, assimp team
+Copyright (c) 2006-2019, assimp team
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 Redistribution and use of this software in source and binary forms,
@@ -68,8 +68,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 using namespace melange;
 using namespace melange;
 
 
 // overload this function and fill in your own unique data
 // overload this function and fill in your own unique data
-void GetWriterInfo(int &id, String &appname)
-{
+void GetWriterInfo(int &id, String &appname) {
     id = 2424226;
     id = 2424226;
     appname = "Open Asset Import Library";
     appname = "Open Asset Import Library";
 }
 }
@@ -78,7 +77,10 @@ using namespace Assimp;
 using namespace Assimp::Formatter;
 using namespace Assimp::Formatter;
 
 
 namespace Assimp {
 namespace Assimp {
-    template<> const std::string LogFunctions<C4DImporter>::log_prefix = "C4D: ";
+    template<> const char* LogFunctions<C4DImporter>::Prefix() {
+        static auto prefix = "C4D: ";
+        return prefix;
+    }
 }
 }
 
 
 static const aiImporterDesc desc = {
 static const aiImporterDesc desc = {
@@ -97,47 +99,44 @@ static const aiImporterDesc desc = {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 C4DImporter::C4DImporter()
 C4DImporter::C4DImporter()
-{}
+: BaseImporter() {
+    // empty
+}
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-C4DImporter::~C4DImporter()
-{}
+C4DImporter::~C4DImporter() {
+    // empty
+}
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
+bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
     const std::string& extension = GetExtension(pFile);
     const std::string& extension = GetExtension(pFile);
     if (extension == "c4d") {
     if (extension == "c4d") {
         return true;
         return true;
-    }
-
-    else if ((!extension.length() || checkSig) && pIOHandler)   {
+    } else if ((!extension.length() || checkSig) && pIOHandler)   {
         // TODO
         // TODO
     }
     }
+
     return false;
     return false;
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-const aiImporterDesc* C4DImporter::GetInfo () const
-{
+const aiImporterDesc* C4DImporter::GetInfo () const {
     return &desc;
     return &desc;
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void C4DImporter::SetupProperties(const Importer* /*pImp*/)
-{
+void C4DImporter::SetupProperties(const Importer* /*pImp*/) {
     // nothing to be done for the moment
     // nothing to be done for the moment
 }
 }
 
 
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure.
 // Imports the given file into the given scene structure.
-void C4DImporter::InternReadFile( const std::string& pFile,
-    aiScene* pScene, IOSystem* pIOHandler)
-{
+void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
     std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
     std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
 
 
-    if( file.get() == NULL) {
+    if( file.get() == nullptr ) {
         ThrowException("failed to open file " + pFile);
         ThrowException("failed to open file " + pFile);
     }
     }
 
 
@@ -151,7 +150,7 @@ void C4DImporter::InternReadFile( const std::string& pFile,
 
 
     // open document first
     // open document first
     BaseDocument* doc = LoadDocument(f, SCENEFILTER_OBJECTS | SCENEFILTER_MATERIALS);
     BaseDocument* doc = LoadDocument(f, SCENEFILTER_OBJECTS | SCENEFILTER_MATERIALS);
-    if(doc == NULL) {
+    if(doc == nullptr ) {
         ThrowException("failed to read document " + pFile);
         ThrowException("failed to read document " + pFile);
     }
     }
 
 
@@ -160,11 +159,10 @@ void C4DImporter::InternReadFile( const std::string& pFile,
     // first convert all materials
     // first convert all materials
     ReadMaterials(doc->GetFirstMaterial());
     ReadMaterials(doc->GetFirstMaterial());
 
 
-    // process C4D scenegraph recursively
+    // process C4D scene-graph recursively
     try {
     try {
         RecurseHierarchy(doc->GetFirstObject(), pScene->mRootNode);
         RecurseHierarchy(doc->GetFirstObject(), pScene->mRootNode);
-    }
-    catch(...) {
+    } catch(...) {
         for(aiMesh* mesh : meshes) {
         for(aiMesh* mesh : meshes) {
             delete mesh;
             delete mesh;
         }
         }
@@ -201,8 +199,7 @@ void C4DImporter::InternReadFile( const std::string& pFile,
 
 
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
-{
+bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) {
     // based on Melange sample code (C4DImportExport.cpp)
     // based on Melange sample code (C4DImportExport.cpp)
     while(shader) {
     while(shader) {
         if(shader->GetType() == Xlayer) {
         if(shader->GetType() == Xlayer) {
@@ -220,15 +217,12 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
             // Ignore the actual layer blending - models for real-time rendering should not
             // Ignore the actual layer blending - models for real-time rendering should not
             // use them in a non-trivial way. Just try to find textures that we can apply
             // use them in a non-trivial way. Just try to find textures that we can apply
             // to the model.
             // to the model.
-            while (lsl)
-            {
-                if (lsl->GetType() == TypeFolder)
-                {
+            while (lsl) {
+                if (lsl->GetType() == TypeFolder) {
                     BlendFolder* const folder = dynamic_cast<BlendFolder*>(lsl);
                     BlendFolder* const folder = dynamic_cast<BlendFolder*>(lsl);
                     LayerShaderLayer *subLsl = dynamic_cast<LayerShaderLayer*>(folder->m_Children.GetObject(0));
                     LayerShaderLayer *subLsl = dynamic_cast<LayerShaderLayer*>(folder->m_Children.GetObject(0));
 
 
-                    while (subLsl)
-                    {
+                    while (subLsl) {
                         if (subLsl->GetType() == TypeShader) {
                         if (subLsl->GetType() == TypeShader) {
                             BlendShader* const shader = dynamic_cast<BlendShader*>(subLsl);
                             BlendShader* const shader = dynamic_cast<BlendShader*>(subLsl);
                             if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
                             if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
@@ -238,8 +232,7 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
 
 
                         subLsl = subLsl->GetNext();
                         subLsl = subLsl->GetNext();
                     }
                     }
-                }
-                else if (lsl->GetType() == TypeShader) {
+                } else if (lsl->GetType() == TypeShader) {
                     BlendShader* const shader = dynamic_cast<BlendShader*>(lsl);
                     BlendShader* const shader = dynamic_cast<BlendShader*>(lsl);
                     if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
                     if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
                         return true;
                         return true;
@@ -248,33 +241,27 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
 
 
                 lsl = lsl->GetNext();
                 lsl = lsl->GetNext();
             }
             }
-        }
-        else if ( shader->GetType() == Xbitmap )
-        {
+        } else if ( shader->GetType() == Xbitmap ) {
             aiString path;
             aiString path;
             shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1);
             shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1);
             path.length = ::strlen(path.data);
             path.length = ::strlen(path.data);
             out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
             out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
             return true;
             return true;
-        }
-        else {
+        } else {
             LogWarn("ignoring shader type: " + std::string(GetObjectTypeName(shader->GetType())));
             LogWarn("ignoring shader type: " + std::string(GetObjectTypeName(shader->GetType())));
         }
         }
         shader = shader->GetNext();
         shader = shader->GetNext();
     }
     }
+
     return false;
     return false;
 }
 }
 
 
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
-{
+void C4DImporter::ReadMaterials(melange::BaseMaterial* mat) {
     // based on Melange sample code
     // based on Melange sample code
-    while (mat)
-    {
+    while (mat) {
         const String& name = mat->GetName();
         const String& name = mat->GetName();
-        if (mat->GetType() == Mmaterial)
-        {
+        if (mat->GetType() == Mmaterial) {
             aiMaterial* out = new aiMaterial();
             aiMaterial* out = new aiMaterial();
             material_mapping[mat] = static_cast<unsigned int>(materials.size());
             material_mapping[mat] = static_cast<unsigned int>(materials.size());
             materials.push_back(out);
             materials.push_back(out);
@@ -286,8 +273,7 @@ void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
 
 
             Material& m = dynamic_cast<Material&>(*mat);
             Material& m = dynamic_cast<Material&>(*mat);
 
 
-            if (m.GetChannelState(CHANNEL_COLOR))
-            {
+            if (m.GetChannelState(CHANNEL_COLOR)) {
                 GeData data;
                 GeData data;
                 mat->GetParameter(MATERIAL_COLOR_COLOR, data);
                 mat->GetParameter(MATERIAL_COLOR_COLOR, data);
                 Vector color = data.GetVector();
                 Vector color = data.GetVector();
@@ -307,9 +293,7 @@ void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
             if(shader) {
             if(shader) {
                 ReadShader(out, shader);
                 ReadShader(out, shader);
             }
             }
-        }
-        else
-        {
+        } else {
             LogWarn("ignoring plugin material: " + std::string(GetObjectTypeName(mat->GetType())));
             LogWarn("ignoring plugin material: " + std::string(GetObjectTypeName(mat->GetType())));
         }
         }
         mat = mat->GetNext();
         mat = mat->GetNext();
@@ -317,14 +301,12 @@ void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
-{
-    ai_assert(parent != NULL);
+void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) {
+    ai_assert(parent != nullptr );
     std::vector<aiNode*> nodes;
     std::vector<aiNode*> nodes;
 
 
     // based on Melange sample code
     // based on Melange sample code
-    while (object)
-    {
+    while (object) {
         const String& name = object->GetName();
         const String& name = object->GetName();
         const LONG type = object->GetType();
         const LONG type = object->GetType();
         const Matrix& ml = object->GetMl();
         const Matrix& ml = object->GetMl();
@@ -356,26 +338,20 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
         nodes.push_back(nd);
         nodes.push_back(nd);
 
 
         GeData data;
         GeData data;
-        if (type == Ocamera)
-        {
+        if (type == Ocamera) {
             object->GetParameter(CAMERAOBJECT_FOV, data);
             object->GetParameter(CAMERAOBJECT_FOV, data);
             // TODO: read camera
             // TODO: read camera
-        }
-        else if (type == Olight)
-        {
+        } else if (type == Olight) {
             // TODO: read light
             // TODO: read light
-        }
-        else if (type == Opolygon)
-        {
+        } else if (type == Opolygon) {
             aiMesh* const mesh = ReadMesh(object);
             aiMesh* const mesh = ReadMesh(object);
-            if(mesh != NULL) {
+            if(mesh != nullptr) {
                 nd->mNumMeshes = 1;
                 nd->mNumMeshes = 1;
                 nd->mMeshes = new unsigned int[1];
                 nd->mMeshes = new unsigned int[1];
                 nd->mMeshes[0] = static_cast<unsigned int>(meshes.size());
                 nd->mMeshes[0] = static_cast<unsigned int>(meshes.size());
                 meshes.push_back(mesh);
                 meshes.push_back(mesh);
             }
             }
-        }
-        else {
+        } else {
             LogWarn("ignoring object: " + std::string(GetObjectTypeName(type)));
             LogWarn("ignoring object: " + std::string(GetObjectTypeName(type)));
         }
         }
 
 
@@ -389,28 +365,27 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
     std::copy(nodes.begin(), nodes.end(), parent->mChildren);
     std::copy(nodes.begin(), nodes.end(), parent->mChildren);
 }
 }
 
 
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-aiMesh* C4DImporter::ReadMesh(BaseObject* object)
-{
-    ai_assert(object != NULL && object->GetType() == Opolygon);
+aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
+    ai_assert(object != nullptr);
+    ai_assert( object->GetType() == Opolygon );
 
 
     // based on Melange sample code
     // based on Melange sample code
     PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
     PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
-    ai_assert(polyObject != NULL);
+    ai_assert(polyObject != nullptr);
 
 
     const LONG pointCount = polyObject->GetPointCount();
     const LONG pointCount = polyObject->GetPointCount();
     const LONG polyCount = polyObject->GetPolygonCount();
     const LONG polyCount = polyObject->GetPolygonCount();
     if(!polyObject || !pointCount) {
     if(!polyObject || !pointCount) {
         LogWarn("ignoring mesh with zero vertices or faces");
         LogWarn("ignoring mesh with zero vertices or faces");
-        return NULL;
+        return nullptr;
     }
     }
 
 
     const Vector* points = polyObject->GetPointR();
     const Vector* points = polyObject->GetPointR();
-    ai_assert(points != NULL);
+    ai_assert(points != nullptr);
 
 
     const CPolygon* polys = polyObject->GetPolygonR();
     const CPolygon* polys = polyObject->GetPolygonR();
-    ai_assert(polys != NULL);
+    ai_assert(polys != nullptr);
 
 
     std::unique_ptr<aiMesh> mesh(new aiMesh());
     std::unique_ptr<aiMesh> mesh(new aiMesh());
     mesh->mNumFaces = static_cast<unsigned int>(polyCount);
     mesh->mNumFaces = static_cast<unsigned int>(polyCount);
@@ -443,14 +418,14 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
 
 
     // check if there are normals, tangents or UVW coordinates
     // check if there are normals, tangents or UVW coordinates
     BaseTag* tag = object->GetTag(Tnormal);
     BaseTag* tag = object->GetTag(Tnormal);
-    NormalTag* normals_src = NULL;
+    NormalTag* normals_src = nullptr;
     if(tag) {
     if(tag) {
         normals_src = dynamic_cast<NormalTag*>(tag);
         normals_src = dynamic_cast<NormalTag*>(tag);
         normals = mesh->mNormals = new aiVector3D[mesh->mNumVertices]();
         normals = mesh->mNormals = new aiVector3D[mesh->mNumVertices]();
     }
     }
 
 
     tag = object->GetTag(Ttangent);
     tag = object->GetTag(Ttangent);
-    TangentTag* tangents_src = NULL;
+    TangentTag* tangents_src = nullptr;
     if(tag) {
     if(tag) {
         tangents_src = dynamic_cast<TangentTag*>(tag);
         tangents_src = dynamic_cast<TangentTag*>(tag);
         tangents = mesh->mTangents = new aiVector3D[mesh->mNumVertices]();
         tangents = mesh->mTangents = new aiVector3D[mesh->mNumVertices]();
@@ -458,15 +433,14 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
     }
     }
 
 
     tag = object->GetTag(Tuvw);
     tag = object->GetTag(Tuvw);
-    UVWTag* uvs_src = NULL;
+    UVWTag* uvs_src = nullptr;
     if(tag) {
     if(tag) {
         uvs_src = dynamic_cast<UVWTag*>(tag);
         uvs_src = dynamic_cast<UVWTag*>(tag);
         uvs = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]();
         uvs = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]();
     }
     }
 
 
     // copy vertices and extra channels over and populate faces
     // copy vertices and extra channels over and populate faces
-    for (LONG i = 0; i < polyCount; ++i, ++face)
-    {
+    for (LONG i = 0; i < polyCount; ++i, ++face) {
         ai_assert(polys[i].a < pointCount && polys[i].a >= 0);
         ai_assert(polys[i].a < pointCount && polys[i].a >= 0);
         const Vector& pointA = points[polys[i].a];
         const Vector& pointA = points[polys[i].a];
         verts->x = pointA.x;
         verts->x = pointA.x;
@@ -489,8 +463,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
         ++verts;
         ++verts;
 
 
         // TODO: do we also need to handle lines or points with similar checks?
         // TODO: do we also need to handle lines or points with similar checks?
-        if (polys[i].c != polys[i].d)
-        {
+        if (polys[i].c != polys[i].d) {
             ai_assert(polys[i].d < pointCount && polys[i].d >= 0);
             ai_assert(polys[i].d < pointCount && polys[i].d >= 0);
 
 
             face->mNumIndices = 4;
             face->mNumIndices = 4;
@@ -500,8 +473,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
             verts->y = pointD.y;
             verts->y = pointD.y;
             verts->z = pointD.z;
             verts->z = pointD.z;
             ++verts;
             ++verts;
-        }
-        else {
+        } else {
             face->mNumIndices = 3;
             face->mNumIndices = 3;
         }
         }
         face->mIndices = new unsigned int[face->mNumIndices];
         face->mIndices = new unsigned int[face->mNumIndices];
@@ -513,8 +485,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
         if (normals_src) {
         if (normals_src) {
             if(i >= normals_src->GetDataCount()) {
             if(i >= normals_src->GetDataCount()) {
                 LogError("unexpected number of normals, ignoring");
                 LogError("unexpected number of normals, ignoring");
-            }
-            else {
+            } else {
                 ConstNormalHandle normal_handle = normals_src->GetDataAddressR();
                 ConstNormalHandle normal_handle = normals_src->GetDataAddressR();
                 NormalStruct nor;
                 NormalStruct nor;
                 NormalTag::Get(normal_handle, i, nor);
                 NormalTag::Get(normal_handle, i, nor);
@@ -616,26 +587,25 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
     }
     }
 
 
     mesh->mMaterialIndex = ResolveMaterial(polyObject);
     mesh->mMaterialIndex = ResolveMaterial(polyObject);
+
     return mesh.release();
     return mesh.release();
 }
 }
 
 
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj)
-{
-    ai_assert(obj != NULL);
+unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj) {
+    ai_assert(obj != nullptr);
 
 
     const unsigned int mat_count = static_cast<unsigned int>(materials.size());
     const unsigned int mat_count = static_cast<unsigned int>(materials.size());
 
 
     BaseTag* tag = obj->GetTag(Ttexture);
     BaseTag* tag = obj->GetTag(Ttexture);
-    if(tag == NULL) {
+    if(tag == nullptr) {
         return mat_count;
         return mat_count;
     }
     }
 
 
     TextureTag& ttag = dynamic_cast<TextureTag&>(*tag);
     TextureTag& ttag = dynamic_cast<TextureTag&>(*tag);
 
 
     BaseMaterial* const mat = ttag.GetMaterial();
     BaseMaterial* const mat = ttag.GetMaterial();
-    ai_assert(mat != NULL);
+    ai_assert(mat != nullptr);
 
 
     const MaterialMap::const_iterator it = material_mapping.find(mat);
     const MaterialMap::const_iterator it = material_mapping.find(mat);
     if(it == material_mapping.end()) {
     if(it == material_mapping.end()) {
@@ -643,6 +613,7 @@ unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj)
     }
     }
 
 
     ai_assert((*it).second < mat_count);
     ai_assert((*it).second < mat_count);
+
     return (*it).second;
     return (*it).second;
 }
 }
 
 

+ 6 - 12
code/C4DImporter.h → code/C4D/C4DImporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2012, assimp team
+Copyright (c) 2006-2019, assimp team
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 Redistribution and use of this software in source and binary forms,
@@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/LogAux.h>
 #include <assimp/LogAux.h>
 
 
 #include <map>
 #include <map>
+
+// Forward declarations
 struct aiNode;
 struct aiNode;
 struct aiMesh;
 struct aiMesh;
 struct aiMaterial;
 struct aiMaterial;
@@ -61,8 +63,7 @@ namespace melange {
     class BaseShader;
     class BaseShader;
 }
 }
 
 
-namespace Assimp    {
-
+namespace Assimp  {
     // TinyFormatter.h
     // TinyFormatter.h
     namespace Formatter {
     namespace Formatter {
         template <typename T,typename TR, typename A> class basic_formatter;
         template <typename T,typename TR, typename A> class basic_formatter;
@@ -75,17 +76,10 @@ namespace Assimp    {
  *
  *
  *  Note that Melange is not free software. */
  *  Note that Melange is not free software. */
 // -------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------
-class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter>
-{
+class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> {
 public:
 public:
-
     C4DImporter();
     C4DImporter();
     ~C4DImporter();
     ~C4DImporter();
-
-
-public:
-
-    // --------------------
     bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
     bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
         bool checkSig) const;
         bool checkSig) const;
 
 
@@ -119,5 +113,5 @@ private:
 }; // !class C4DImporter
 }; // !class C4DImporter
 
 
 } // end of namespace Assimp
 } // end of namespace Assimp
-#endif // INCLUDED_AI_CINEMA_4D_LOADER_H
 
 
+#endif // INCLUDED_AI_CINEMA_4D_LOADER_H

+ 2 - 3
code/AssimpCExport.cpp → code/CApi/AssimpCExport.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -49,7 +49,7 @@ Assimp C export interface. See Exporter.cpp for some notes.
 
 
 #include "CInterfaceIOWrapper.h"
 #include "CInterfaceIOWrapper.h"
 #include <assimp/SceneCombiner.h>
 #include <assimp/SceneCombiner.h>
-#include "ScenePrivate.h"
+#include "Common/ScenePrivate.h"
 #include <assimp/Exporter.hpp>
 #include <assimp/Exporter.hpp>
 
 
 using namespace Assimp;
 using namespace Assimp;
@@ -60,7 +60,6 @@ ASSIMP_API size_t aiGetExportFormatCount(void)
     return Exporter().GetExportFormatCount();
     return Exporter().GetExportFormatCount();
 }
 }
 
 
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t index)
 ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t index)
 {
 {

+ 1 - 1
code/CInterfaceIOWrapper.cpp → code/CApi/CInterfaceIOWrapper.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 

+ 1 - 1
code/CInterfaceIOWrapper.h → code/CApi/CInterfaceIOWrapper.h

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 637 - 466
code/CMakeLists.txt


+ 18 - 13
code/COBLoader.cpp → code/COB/COBLoader.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -45,20 +45,22 @@ 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 "COBScene.h"
-#include "ConvertToLHProcess.h"
+#include "COB/COBLoader.h"
+#include "COB/COBScene.h"
+#include "PostProcessing/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 <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/scene.h>
 #include <assimp/scene.h>
 #include <assimp/importerdesc.h>
 #include <assimp/importerdesc.h>
 
 
+#include <memory>
+
 using namespace Assimp;
 using namespace Assimp;
 using namespace Assimp::COB;
 using namespace Assimp::COB;
 using namespace Assimp::Formatter;
 using namespace Assimp::Formatter;
@@ -144,7 +146,7 @@ void COBImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
     // check header
     // check header
     char head[32];
     char head[32];
     stream->CopyAndAdvance(head,32);
     stream->CopyAndAdvance(head,32);
-    if (strncmp(head,"Caligari ",9)) {
+    if (strncmp(head,"Caligari ",9) != 0) {
         ThrowException("Could not found magic id: `Caligari`");
         ThrowException("Could not found magic id: `Caligari`");
     }
     }
 
 
@@ -656,14 +658,14 @@ void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const Chunk
     ReadFloat3Tuple_Ascii(msh.color ,&rgb);
     ReadFloat3Tuple_Ascii(msh.color ,&rgb);
 
 
     SkipSpaces(&rgb);
     SkipSpaces(&rgb);
-    if (strncmp(rgb,"cone angle",10)) {
+    if (strncmp(rgb,"cone angle",10) != 0) {
         ASSIMP_LOG_WARN_F( "Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id );
         ASSIMP_LOG_WARN_F( "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) != 0) {
         ASSIMP_LOG_WARN_F( "Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
         ASSIMP_LOG_WARN_F( "Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
     }
     }
     SkipSpaces(rgb+11,&rgb);
     SkipSpaces(rgb+11,&rgb);
@@ -896,6 +898,7 @@ public:
     : nfo(nfo)
     : nfo(nfo)
     , reader(reader)
     , reader(reader)
     , cur(reader.GetCurrentPos()) {
     , cur(reader.GetCurrentPos()) {
+        // empty
     }
     }
 
 
     ~chunk_guard() {
     ~chunk_guard() {
@@ -903,7 +906,7 @@ public:
         if(nfo.size != static_cast<unsigned int>(-1)) {
         if(nfo.size != static_cast<unsigned int>(-1)) {
             try {
             try {
                 reader.IncPtr( static_cast< int >( nfo.size ) - reader.GetCurrentPos() + cur );
                 reader.IncPtr( static_cast< int >( nfo.size ) - reader.GetCurrentPos() + cur );
-            } catch ( DeadlyImportError e ) {
+            } catch (const DeadlyImportError& ) {
                 // out of limit so correct the value
                 // out of limit so correct the value
                 reader.IncPtr( reader.GetReadLimit() );
                 reader.IncPtr( reader.GetReadLimit() );
             }
             }
@@ -911,15 +914,17 @@ public:
     }
     }
 
 
 private:
 private:
-
     const COB::ChunkInfo& nfo;
     const COB::ChunkInfo& nfo;
     StreamReaderLE& reader;
     StreamReaderLE& reader;
     long cur;
     long cur;
 };
 };
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBinaryFile(Scene& out, StreamReaderLE* reader)
-{
+void COBImporter::ReadBinaryFile(Scene& out, StreamReaderLE* reader) {
+    if (nullptr == reader) {
+        return;
+    }
+
     while(1) {
     while(1) {
         std::string type;
         std::string type;
          type += reader -> GetI1()
          type += reader -> GetI1()
@@ -1214,7 +1219,7 @@ void COBImporter::ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const
 
 
     const chunk_guard cn(nfo,reader);
     const chunk_guard cn(nfo,reader);
 
 
-    out.nodes.push_back(std::shared_ptr<Group>(new Group()));
+    out.nodes.push_back(std::make_shared<Group>());
     Group& msh = (Group&)(*out.nodes.back().get());
     Group& msh = (Group&)(*out.nodes.back().get());
     msh = nfo;
     msh = nfo;
 
 

+ 1 - 1
code/COBLoader.h → code/COB/COBLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 1 - 1
code/COBScene.h → code/COB/COBScene.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 1 - 1
code/CSMLoader.cpp → code/CSM/CSMLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 

+ 1 - 1
code/CSMLoader.h → code/CSM/CSMLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 81 - 52
code/ColladaExporter.cpp → code/Collada/ColladaExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include "ColladaExporter.h"
 #include "ColladaExporter.h"
 #include <assimp/Bitmap.h>
 #include <assimp/Bitmap.h>
+#include <assimp/MathFunctions.h>
 #include <assimp/fast_atof.h>
 #include <assimp/fast_atof.h>
 #include <assimp/SceneCombiner.h>
 #include <assimp/SceneCombiner.h>
 #include <assimp/StringUtils.h>
 #include <assimp/StringUtils.h>
@@ -64,13 +65,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 using namespace Assimp;
 using namespace Assimp;
 
 
-namespace Assimp
-{
+namespace Assimp {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
 // Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
-void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
-{
+void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) {
     std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
     std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
     std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
     std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
 
 
@@ -93,15 +92,15 @@ void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* p
 
 
 } // end of namespace Assimp
 } // end of namespace Assimp
 
 
-
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Constructor for a specific scene to export
 // Constructor for a specific scene to export
-ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file)
-{
+ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) 
+: mIOSystem(pIOSystem)
+, mPath(path)
+, mFile(file) {
     // make sure that all formatting happens using the standard, C locale and not the user's current locale
     // make sure that all formatting happens using the standard, C locale and not the user's current locale
     mOutput.imbue( std::locale("C") );
     mOutput.imbue( std::locale("C") );
-    mOutput.precision(16);
+    mOutput.precision(ASSIMP_AI_REAL_TEXT_PRECISION);
 
 
     mScene = pScene;
     mScene = pScene;
     mSceneOwned = false;
     mSceneOwned = false;
@@ -115,17 +114,15 @@ ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, co
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor
 // Destructor
-ColladaExporter::~ColladaExporter()
-{
-    if(mSceneOwned) {
+ColladaExporter::~ColladaExporter() {
+    if ( mSceneOwned ) {
         delete mScene;
         delete mScene;
     }
     }
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Starts writing the contents
 // Starts writing the contents
-void ColladaExporter::WriteFile()
-{
+void ColladaExporter::WriteFile() {
     // write the DTD
     // write the DTD
     mOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" << endstr;
     mOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" << endstr;
     // COLLADA element start
     // COLLADA element start
@@ -158,9 +155,8 @@ void ColladaExporter::WriteFile()
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Writes the asset header
 // Writes the asset header
-void ColladaExporter::WriteHeader()
-{
-    static const ai_real epsilon = ai_real( 0.00001 );
+void ColladaExporter::WriteHeader() {
+    static const ai_real epsilon = Math::getEpsilon<ai_real>();
     static const aiQuaternion x_rot(aiMatrix3x3(
     static const aiQuaternion x_rot(aiMatrix3x3(
         0, -1,  0,
         0, -1,  0,
         1,  0,  0,
         1,  0,  0,
@@ -238,25 +234,64 @@ void ColladaExporter::WriteHeader()
     mOutput << startstr << "<contributor>" << endstr;
     mOutput << startstr << "<contributor>" << endstr;
     PushTag();
     PushTag();
 
 
-    aiMetadata* meta = mScene->mRootNode->mMetaData;
+    // If no Scene metadata, use root node metadata
+    aiMetadata* meta = mScene->mMetaData;
+    if (nullptr == meta) {
+        meta = mScene->mRootNode->mMetaData;
+    }
+
     aiString value;
     aiString value;
-    if (!meta || !meta->Get("Author", value))
+    if (!meta || !meta->Get("Author", value)) {
         mOutput << startstr << "<author>" << "Assimp" << "</author>" << endstr;
         mOutput << startstr << "<author>" << "Assimp" << "</author>" << endstr;
-    else
+    } else {
         mOutput << startstr << "<author>" << XMLEscape(value.C_Str()) << "</author>" << endstr;
         mOutput << startstr << "<author>" << XMLEscape(value.C_Str()) << "</author>" << endstr;
+    }
 
 
-    if (!meta || !meta->Get("AuthoringTool", value))
+    if (nullptr == meta || !meta->Get("AuthoringTool", value)) {
         mOutput << startstr << "<authoring_tool>" << "Assimp Exporter" << "</authoring_tool>" << endstr;
         mOutput << startstr << "<authoring_tool>" << "Assimp Exporter" << "</authoring_tool>" << endstr;
-    else
+    } else {
         mOutput << startstr << "<authoring_tool>" << XMLEscape(value.C_Str()) << "</authoring_tool>" << endstr;
         mOutput << startstr << "<authoring_tool>" << XMLEscape(value.C_Str()) << "</authoring_tool>" << endstr;
+    }
 
 
-    //mOutput << startstr << "<author>" << mScene->author.C_Str() << "</author>" << endstr;
-    //mOutput << startstr << "<authoring_tool>" << mScene->authoringTool.C_Str() << "</authoring_tool>" << endstr;
+    if (meta) {
+        if (meta->Get("Comments", value)) {
+            mOutput << startstr << "<comments>" << XMLEscape(value.C_Str()) << "</comments>" << endstr;
+        }
+        if (meta->Get("Copyright", value)) {
+            mOutput << startstr << "<copyright>" << XMLEscape(value.C_Str()) << "</copyright>" << endstr;
+        }
+        if (meta->Get("SourceData", value)) {
+            mOutput << startstr << "<source_data>" << XMLEscape(value.C_Str()) << "</source_data>" << endstr;
+        }
+    }
 
 
     PopTag();
     PopTag();
     mOutput << startstr << "</contributor>" << endstr;
     mOutput << startstr << "</contributor>" << endstr;
-    mOutput << startstr << "<created>" << date_str << "</created>" << endstr;
+
+    if (nullptr == meta || !meta->Get("Created", value)) {
+        mOutput << startstr << "<created>" << date_str << "</created>" << endstr;
+    } else {
+        mOutput << startstr << "<created>" << XMLEscape(value.C_Str()) << "</created>" << endstr;
+    }
+
+    // Modified date is always the date saved
     mOutput << startstr << "<modified>" << date_str << "</modified>" << endstr;
     mOutput << startstr << "<modified>" << date_str << "</modified>" << endstr;
+
+    if (meta) {
+        if (meta->Get("Keywords", value)) {
+            mOutput << startstr << "<keywords>" << XMLEscape(value.C_Str()) << "</keywords>" << endstr;
+        }
+        if (meta->Get("Revision", value)) {
+            mOutput << startstr << "<revision>" << XMLEscape(value.C_Str()) << "</revision>" << endstr;
+        }
+        if (meta->Get("Subject", value)) {
+            mOutput << startstr << "<subject>" << XMLEscape(value.C_Str()) << "</subject>" << endstr;
+        }
+        if (meta->Get("Title", value)) {
+            mOutput << startstr << "<title>" << XMLEscape(value.C_Str()) << "</title>" << endstr;
+        }
+    }
+
     mOutput << startstr << "<unit name=\"meter\" meter=\"" << scale << "\" />" << endstr;
     mOutput << startstr << "<unit name=\"meter\" meter=\"" << scale << "\" />" << endstr;
     mOutput << startstr << "<up_axis>" << up_axis << "</up_axis>" << endstr;
     mOutput << startstr << "<up_axis>" << up_axis << "</up_axis>" << endstr;
     PopTag();
     PopTag();
@@ -269,18 +304,21 @@ void ColladaExporter::WriteTextures() {
     static const unsigned int buffer_size = 1024;
     static const unsigned int buffer_size = 1024;
     char str[buffer_size];
     char str[buffer_size];
 
 
-    if(mScene->HasTextures()) {
+    if (mScene->HasTextures()) {
         for(unsigned int i = 0; i < mScene->mNumTextures; i++) {
         for(unsigned int i = 0; i < mScene->mNumTextures; i++) {
             // It would be great to be able to create a directory in portable standard C++, but it's not the case,
             // It would be great to be able to create a directory in portable standard C++, but it's not the case,
             // so we just write the textures in the current directory.
             // so we just write the textures in the current directory.
 
 
             aiTexture* texture = mScene->mTextures[i];
             aiTexture* texture = mScene->mTextures[i];
+            if ( nullptr == texture ) {
+                continue;
+            }
 
 
             ASSIMP_itoa10(str, buffer_size, i + 1);
             ASSIMP_itoa10(str, buffer_size, i + 1);
 
 
             std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char*) texture->achFormatHint);
             std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char*) texture->achFormatHint);
 
 
-            std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + name, "wb"));
+            std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + mIOSystem->getOsSeparator() + name, "wb"));
             if(outfile == NULL) {
             if(outfile == NULL) {
                 throw DeadlyExportError("could not open output texture file: " + mPath + name);
                 throw DeadlyExportError("could not open output texture file: " + mPath + name);
             }
             }
@@ -428,6 +466,7 @@ void ColladaExporter::WritePointLight(const aiLight *const light){
     mOutput << startstr << "</point>" << endstr;
     mOutput << startstr << "</point>" << endstr;
 
 
 }
 }
+
 void ColladaExporter::WriteDirectionalLight(const aiLight *const light){
 void ColladaExporter::WriteDirectionalLight(const aiLight *const light){
     const aiColor3D &color=  light->mColorDiffuse;
     const aiColor3D &color=  light->mColorDiffuse;
     mOutput << startstr << "<directional>" << endstr;
     mOutput << startstr << "<directional>" << endstr;
@@ -440,6 +479,7 @@ void ColladaExporter::WriteDirectionalLight(const aiLight *const light){
     mOutput << startstr << "</directional>" << endstr;
     mOutput << startstr << "</directional>" << endstr;
 
 
 }
 }
+
 void ColladaExporter::WriteSpotLight(const aiLight *const light){
 void ColladaExporter::WriteSpotLight(const aiLight *const light){
 
 
     const aiColor3D &color=  light->mColorDiffuse;
     const aiColor3D &color=  light->mColorDiffuse;
@@ -496,18 +536,16 @@ void ColladaExporter::WriteAmbienttLight(const aiLight *const light){
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Reads a single surface entry from the given material keys
 // Reads a single surface entry from the given material keys
-void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex)
-{
-  if( pSrcMat->GetTextureCount( pTexture) > 0 )
-  {
+void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, 
+                                          aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex) {
+  if( pSrcMat->GetTextureCount( pTexture) > 0 ) {
     aiString texfile;
     aiString texfile;
     unsigned int uvChannel = 0;
     unsigned int uvChannel = 0;
     pSrcMat->GetTexture( pTexture, 0, &texfile, NULL, &uvChannel);
     pSrcMat->GetTexture( pTexture, 0, &texfile, NULL, &uvChannel);
 
 
     std::string index_str(texfile.C_Str());
     std::string index_str(texfile.C_Str());
 
 
-    if(index_str.size() != 0 && index_str[0] == '*')
-    {
+    if(index_str.size() != 0 && index_str[0] == '*') {
         unsigned int index;
         unsigned int index;
 
 
         index_str = index_str.substr(1, std::string::npos);
         index_str = index_str.substr(1, std::string::npos);
@@ -525,15 +563,13 @@ void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial*
         } else {
         } else {
             throw DeadlyExportError("could not find embedded texture at index " + index_str);
             throw DeadlyExportError("could not find embedded texture at index " + index_str);
         }
         }
-    } else
-    {
+    } else {
         poSurface.texture = texfile.C_Str();
         poSurface.texture = texfile.C_Str();
     }
     }
 
 
     poSurface.channel = uvChannel;
     poSurface.channel = uvChannel;
     poSurface.exist = true;
     poSurface.exist = true;
-  } else
-  {
+  } else {
     if( pKey )
     if( pKey )
       poSurface.exist = pSrcMat->Get( pKey, static_cast<unsigned int>(pType), static_cast<unsigned int>(pIndex), poSurface.color) == aiReturn_SUCCESS;
       poSurface.exist = pSrcMat->Get( pKey, static_cast<unsigned int>(pType), static_cast<unsigned int>(pIndex), poSurface.color) == aiReturn_SUCCESS;
   }
   }
@@ -541,15 +577,13 @@ void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial*
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Reimplementation of isalnum(,C locale), because AppVeyor does not see standard version.
 // Reimplementation of isalnum(,C locale), because AppVeyor does not see standard version.
-static bool isalnum_C(char c)
-{
+static bool isalnum_C(char c) {
   return ( nullptr != strchr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",c) );
   return ( nullptr != strchr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",c) );
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Writes an image entry for the given surface
 // Writes an image entry for the given surface
-void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd)
-{
+void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd) {
   if( !pSurface.texture.empty() )
   if( !pSurface.texture.empty() )
   {
   {
     mOutput << startstr << "<image id=\"" << XMLEscape(pNameAdd) << "\">" << endstr;
     mOutput << startstr << "<image id=\"" << XMLEscape(pNameAdd) << "\">" << endstr;
@@ -803,8 +837,9 @@ void ColladaExporter::WriteControllerLibrary()
     mOutput << startstr << "<library_controllers>" << endstr;
     mOutput << startstr << "<library_controllers>" << endstr;
     PushTag();
     PushTag();
     
     
-    for( size_t a = 0; a < mScene->mNumMeshes; ++a)
+    for( size_t a = 0; a < mScene->mNumMeshes; ++a) {
         WriteController( a);
         WriteController( a);
+    }
 
 
     PopTag();
     PopTag();
     mOutput << startstr << "</library_controllers>" << endstr;
     mOutput << startstr << "</library_controllers>" << endstr;
@@ -1500,24 +1535,18 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
     // otherwise it is a normal node (NODE)
     // otherwise it is a normal node (NODE)
     const char * node_type;
     const char * node_type;
     bool is_joint, is_skeleton_root = false;
     bool is_joint, is_skeleton_root = false;
-    if (NULL == findBone(pScene, pNode->mName.C_Str())) {
+    if (nullptr == findBone(pScene, pNode->mName.C_Str())) {
         node_type = "NODE";
         node_type = "NODE";
         is_joint = false;
         is_joint = false;
     } else {
     } else {
         node_type = "JOINT";
         node_type = "JOINT";
         is_joint = true;
         is_joint = true;
-        if(!pNode->mParent || NULL == findBone(pScene, pNode->mParent->mName.C_Str()))
+        if (!pNode->mParent || nullptr == findBone(pScene, pNode->mParent->mName.C_Str())) {
             is_skeleton_root = true;
             is_skeleton_root = true;
+        }
     }
     }
 
 
     const std::string node_name_escaped = XMLEscape(pNode->mName.data);
     const std::string node_name_escaped = XMLEscape(pNode->mName.data);
-	/* // customized, Note! the id field is crucial for inter-xml look up, it cannot be replaced with sid ?!
-    mOutput << startstr
-            << "<node ";
-    if(is_skeleton_root)
-        mOutput << "id=\"" << "skeleton_root" << "\" "; // For now, only support one skeleton in a scene.
-    mOutput << (is_joint ? "s" : "") << "id=\"" << node_name_escaped;
-	 */
 	mOutput << startstr << "<node ";
 	mOutput << startstr << "<node ";
 	if(is_skeleton_root) {
 	if(is_skeleton_root) {
 		mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"" : "") ; // For now, only support one skeleton in a scene.
 		mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"" : "") ; // For now, only support one skeleton in a scene.

+ 2 - 3
code/ColladaExporter.h → code/Collada/ColladaExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -150,7 +150,6 @@ public:
     /// Stringstream to write all output into
     /// Stringstream to write all output into
     std::stringstream mOutput;
     std::stringstream mOutput;
 
 
-protected:
     /// The IOSystem for output
     /// The IOSystem for output
     IOSystem* mIOSystem;
     IOSystem* mIOSystem;
 
 
@@ -204,7 +203,7 @@ protected:
 
 
   std::map<unsigned int, std::string> textures;
   std::map<unsigned int, std::string> textures;
 
 
-protected:
+public:
   /// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions
   /// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions
   /// Reads a single surface entry from the given material keys
   /// Reads a single surface entry from the given material keys
   void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex);
   void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex);

+ 3 - 7
code/ColladaHelper.h → code/Collada/ColladaHelper.h

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -580,15 +580,11 @@ struct Image
 {
 {
     std::string mFileName;
     std::string mFileName;
 
 
-    /** If image file name is zero, embedded image data
-     */
+    /** Embedded image data */
     std::vector<uint8_t> mImageData;
     std::vector<uint8_t> mImageData;
 
 
-    /** If image file name is zero, file format of
-     *  embedded image data.
-     */
+    /** File format hint ofembedded image data */
     std::string mEmbeddedFormat;
     std::string mEmbeddedFormat;
-
 };
 };
 
 
 /** An animation channel. */
 /** An animation channel. */

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 307 - 298
code/Collada/ColladaLoader.cpp


+ 6 - 6
code/ColladaLoader.h → code/Collada/ColladaLoader.h

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -94,20 +94,20 @@ public:
 public:
 public:
     /** Returns whether the class can handle the format of the given file.
     /** Returns whether the class can handle the format of the given file.
      * See BaseImporter::CanRead() for details. */
      * See BaseImporter::CanRead() for details. */
-    bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
+    bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
 
 
 protected:
 protected:
     /** Return importer meta information.
     /** Return importer meta information.
      * See #BaseImporter::GetInfo for the details
      * See #BaseImporter::GetInfo for the details
      */
      */
-    const aiImporterDesc* GetInfo () const;
+    const aiImporterDesc* GetInfo () const override;
 
 
-    void SetupProperties(const Importer* pImp);
+    void SetupProperties(const Importer* pImp) override;
 
 
     /** Imports the given file into the given scene structure.
     /** Imports the given file into the given scene structure.
      * See BaseImporter::InternReadFile() for details
      * See BaseImporter::InternReadFile() for details
      */
      */
-    void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
+    void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
 
 
     /** Recursively constructs a scene node for the given parser node and returns it. */
     /** Recursively constructs a scene node for the given parser node and returns it. */
     aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
     aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
@@ -120,7 +120,7 @@ protected:
     void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
     void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
         aiNode* pTarget);
         aiNode* pTarget);
 		
 		
-    aiMesh *findMesh(std::string meshid);
+    aiMesh *findMesh(const std::string& meshid);
 
 
     /** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
     /** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
     aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
     aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 411 - 263
code/Collada/ColladaParser.cpp


+ 23 - 1
code/ColladaParser.h → code/Collada/ColladaParser.h

@@ -2,7 +2,7 @@
  Open Asset Import Library (assimp)
  Open Asset Import Library (assimp)
  ----------------------------------------------------------------------
  ----------------------------------------------------------------------
 
 
- Copyright (c) 2006-2018, assimp team
+ Copyright (c) 2006-2019, assimp team
 
 
 
 
  All rights reserved.
  All rights reserved.
@@ -54,6 +54,7 @@
 
 
 namespace Assimp
 namespace Assimp
 {
 {
+    class ZipArchiveIOSystem;
 
 
     // ------------------------------------------------------------------------------------------
     // ------------------------------------------------------------------------------------------
     /** Parser helper class for the Collada loader.
     /** Parser helper class for the Collada loader.
@@ -66,12 +67,18 @@ namespace Assimp
         friend class ColladaLoader;
         friend class ColladaLoader;
 
 
     protected:
     protected:
+        /** Map for generic metadata as aiString */
+        typedef std::map<std::string, aiString> StringMetaData;
+
         /** Constructor from XML file */
         /** Constructor from XML file */
         ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
         ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
 
 
         /** Destructor */
         /** Destructor */
         ~ColladaParser();
         ~ColladaParser();
 
 
+        /** Attempts to read the ZAE manifest and returns the DAE to open */
+        static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
+
         /** Reads the contents of the file */
         /** Reads the contents of the file */
         void ReadContents();
         void ReadContents();
 
 
@@ -81,6 +88,15 @@ namespace Assimp
         /** Reads asset information such as coordinate system information and legal blah */
         /** Reads asset information such as coordinate system information and legal blah */
         void ReadAssetInfo();
         void ReadAssetInfo();
 
 
+        /** Reads contributor information such as author and legal blah */
+        void ReadContributorInfo();
+
+        /** Reads generic metadata into provided map */
+        void ReadMetaDataItem(StringMetaData &metadata);
+
+        /** Convert underscore_seperated to CamelCase "authoring_tool" becomes "AuthoringTool" */
+        static void ToCamelCase(std::string &text);
+
         /** Reads the animation library */
         /** Reads the animation library */
         void ReadAnimationLibrary();
         void ReadAnimationLibrary();
 
 
@@ -223,6 +239,9 @@ namespace Assimp
         // Processes bind_vertex_input and bind elements
         // Processes bind_vertex_input and bind elements
         void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
         void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
 
 
+        /** Reads embedded textures from a ZAE archive*/
+        void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
+
     protected:
     protected:
         /** Aborts the file reading with an exception */
         /** Aborts the file reading with an exception */
         AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;
         AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;
@@ -343,6 +362,9 @@ namespace Assimp
         /** Which is the up vector */
         /** Which is the up vector */
         enum { UP_X, UP_Y, UP_Z } mUpDirection;
         enum { UP_X, UP_Y, UP_Z } mUpDirection;
 
 
+        /** Asset metadata (global for scene) */
+        StringMetaData mAssetMetaData;
+
         /** Collada file format version */
         /** Collada file format version */
         Collada::FormatVersion mFormat;
         Collada::FormatVersion mFormat;
     };
     };

+ 2 - 2
code/Assimp.cpp → code/Common/Assimp.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -54,7 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/Exceptional.h>
 #include <assimp/Exceptional.h>
 #include <assimp/BaseImporter.h>
 #include <assimp/BaseImporter.h>
 
 
-#include "CInterfaceIOWrapper.h"
+#include "CApi/CInterfaceIOWrapper.h"
 #include "Importer.h"
 #include "Importer.h"
 #include "ScenePrivate.h"
 #include "ScenePrivate.h"
 
 

+ 31 - 4
code/BaseImporter.cpp → code/Common/BaseImporter.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -76,9 +76,25 @@ BaseImporter::~BaseImporter() {
     // nothing to do here
     // nothing to do here
 }
 }
 
 
+void BaseImporter::UpdateImporterScale( Importer* pImp )
+{
+    ai_assert(pImp != nullptr);
+    ai_assert(importerScale != 0.0);
+    ai_assert(fileScale != 0.0);
+
+    double activeScale = importerScale * fileScale;
+
+    // Set active scaling
+    pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) );
+
+    ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
+}
+
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // 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(Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) {
+
+
     m_progress = pImp->GetProgressHandler();
     m_progress = pImp->GetProgressHandler();
     if (nullptr == m_progress) {
     if (nullptr == m_progress) {
         return nullptr;
         return nullptr;
@@ -100,6 +116,11 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
     {
     {
         InternReadFile( pFile, sc.get(), &filter);
         InternReadFile( pFile, sc.get(), &filter);
 
 
+        // Calculate import scale hook - required because pImp not available anywhere else
+        // passes scale into ScaleProcess
+        UpdateImporterScale(pImp);
+
+
     } catch( const std::exception& err )    {
     } catch( const std::exception& err )    {
         // extract error description
         // extract error description
         m_ErrorText = err.what();
         m_ErrorText = err.what();
@@ -112,7 +133,7 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void BaseImporter::SetupProperties(const Importer* /*pImp*/)
+void BaseImporter::SetupProperties(const Importer* pImp)
 {
 {
     // the default implementation does nothing
     // the default implementation does nothing
 }
 }
@@ -320,7 +341,11 @@ std::string BaseImporter::GetExtension( const std::string& file ) {
     return false;
     return false;
 }
 }
 
 
-#include "../contrib/utf8cpp/source/utf8.h"
+#ifdef ASSIMP_USE_HUNTER
+#  include <utf8/utf8.h>
+#else
+#  include "../contrib/utf8cpp/source/utf8.h"
+#endif
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Convert to UTF8 data
 // Convert to UTF8 data
@@ -584,6 +609,8 @@ aiScene* BatchLoader::GetImport( unsigned int which )
     return nullptr;
     return nullptr;
 }
 }
 
 
+
+
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 void BatchLoader::LoadAll()
 void BatchLoader::LoadAll()
 {
 {

+ 2 - 2
code/BaseProcess.cpp → code/Common/BaseProcess.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 
@@ -89,7 +89,7 @@ void BaseProcess::ExecuteOnScene( Importer* pImp)
 
 
         // and kill the partially imported data
         // and kill the partially imported data
         delete pImp->Pimpl()->mScene;
         delete pImp->Pimpl()->mScene;
-        pImp->Pimpl()->mScene = NULL;
+        pImp->Pimpl()->mScene = nullptr;
     }
     }
 }
 }
 
 

+ 1 - 1
code/BaseProcess.h → code/Common/BaseProcess.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 1 - 1
code/Bitmap.cpp → code/Common/Bitmap.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 

+ 0 - 4
code/CreateAnimMesh.cpp → code/Common/CreateAnimMesh.cpp

@@ -47,10 +47,6 @@ namespace Assimp    {
 aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh)
 aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh)
 {
 {
     aiAnimMesh *animesh = new aiAnimMesh;
     aiAnimMesh *animesh = new aiAnimMesh;
-    animesh->mVertices = NULL;
-    animesh->mNormals = NULL;
-    animesh->mTangents = NULL;
-    animesh->mBitangents = NULL;
     animesh->mNumVertices = mesh->mNumVertices;
     animesh->mNumVertices = mesh->mNumVertices;
     if (mesh->mVertices) {
     if (mesh->mVertices) {
         animesh->mVertices = new aiVector3D[animesh->mNumVertices];
         animesh->mVertices = new aiVector3D[animesh->mNumVertices];

+ 1 - 1
code/DefaultIOStream.cpp → code/Common/DefaultIOStream.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2018, assimp team
+Copyright (c) 2006-2019, assimp team
 
 
 
 
 
 

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно