Selaa lähdekoodia

Merge branch 'master' into x3d_pugi_migration

René Martin 4 vuotta sitten
vanhempi
commit
3001d88172
100 muutettua tiedostoa jossa 2014 lisäystä ja 2652 poistoa
  1. 1 1
      .gitignore
  2. 11 9
      CMakeLists.txt
  3. 0 17
      cmake-modules/FindIrrXML.cmake
  4. 0 0
      cmake-modules/HunterGate.cmake
  5. 19 0
      cmake-modules/assimp-hunter-config.cmake.in
  6. 0 0
      cmake-modules/assimp-plain-config.cmake.in
  7. 0 18
      cmake/assimp-hunter-config.cmake.in
  8. 3 8
      code/AssetLib/3DS/3DSConverter.cpp
  9. 1 1
      code/AssetLib/3DS/3DSExporter.cpp
  10. 38 38
      code/AssetLib/3DS/3DSHelper.h
  11. 9 0
      code/AssetLib/3DS/3DSLoader.h
  12. 165 0
      code/AssetLib/3MF/3MFTypes.h
  13. 10 2
      code/AssetLib/3MF/3MFXmlTags.h
  14. 15 507
      code/AssetLib/3MF/D3MFImporter.cpp
  15. 28 6
      code/AssetLib/3MF/D3MFImporter.h
  16. 58 11
      code/AssetLib/3MF/D3MFOpcPackage.cpp
  17. 10 4
      code/AssetLib/3MF/D3MFOpcPackage.h
  18. 594 0
      code/AssetLib/3MF/XmlSerializer.cpp
  19. 96 0
      code/AssetLib/3MF/XmlSerializer.h
  20. 1 1
      code/AssetLib/AMF/AMFImporter.cpp
  21. 3 3
      code/AssetLib/AMF/AMFImporter_Geometry.cpp
  22. 3 3
      code/AssetLib/AMF/AMFImporter_Postprocess.cpp
  23. 4 4
      code/AssetLib/ASE/ASEParser.h
  24. 1 1
      code/AssetLib/Assbin/AssbinFileWriter.cpp
  25. 27 15
      code/AssetLib/Assjson/json_exporter.cpp
  26. 4 4
      code/AssetLib/Assjson/mesh_splitter.cpp
  27. 3 3
      code/AssetLib/Assjson/mesh_splitter.h
  28. 1 1
      code/AssetLib/Assxml/AssxmlExporter.cpp
  29. 1 1
      code/AssetLib/B3D/B3DImporter.cpp
  30. 1 1
      code/AssetLib/B3D/B3DImporter.h
  31. 1 1
      code/AssetLib/Blender/BlenderLoader.cpp
  32. 9 9
      code/AssetLib/Blender/BlenderModifier.h
  33. 6 0
      code/AssetLib/C4D/C4DImporter.cpp
  34. 2 2
      code/AssetLib/COB/COBLoader.cpp
  35. 1 1
      code/AssetLib/COB/COBLoader.h
  36. 15 10
      code/AssetLib/Collada/ColladaLoader.cpp
  37. 114 125
      code/AssetLib/Collada/ColladaParser.cpp
  38. 1 3
      code/AssetLib/DXF/DXFLoader.cpp
  39. 1 1
      code/AssetLib/DXF/DXFLoader.h
  40. 11 6
      code/AssetLib/FBX/FBXConverter.cpp
  41. 2 2
      code/AssetLib/FBX/FBXConverter.h
  42. 5 6
      code/AssetLib/FBX/FBXDocument.cpp
  43. 5 0
      code/AssetLib/FBX/FBXDocument.h
  44. 2 3
      code/AssetLib/FBX/FBXExportNode.cpp
  45. 3 4
      code/AssetLib/FBX/FBXExportNode.h
  46. 110 35
      code/AssetLib/FBX/FBXExporter.cpp
  47. 10 11
      code/AssetLib/FBX/FBXExporter.h
  48. 9 4
      code/AssetLib/FBX/FBXMaterial.cpp
  49. 1 1
      code/AssetLib/FBX/FBXMeshGeometry.cpp
  50. 4 4
      code/AssetLib/FBX/FBXMeshGeometry.h
  51. 12 16
      code/AssetLib/FBX/FBXParser.cpp
  52. 4 5
      code/AssetLib/FBX/FBXProperties.cpp
  53. 3 3
      code/AssetLib/FBX/FBXProperties.h
  54. 1 1
      code/AssetLib/FBX/FBXUtil.cpp
  55. 2 2
      code/AssetLib/HMP/HMPLoader.cpp
  56. 1 1
      code/AssetLib/IFC/IFCBoolean.cpp
  57. 1 1
      code/AssetLib/IFC/IFCCurve.cpp
  58. 1 1
      code/AssetLib/IFC/IFCGeometry.cpp
  59. 3 3
      code/AssetLib/IFC/IFCMaterial.cpp
  60. 4 4
      code/AssetLib/IFC/IFCOpenings.cpp
  61. 116 116
      code/AssetLib/IFC/IFCReaderGen1_2x3.cpp
  62. 81 81
      code/AssetLib/IFC/IFCReaderGen2_2x3.cpp
  63. 129 129
      code/AssetLib/IFC/IFCReaderGen_4.cpp
  64. 13 13
      code/AssetLib/IFC/IFCReaderGen_4.h
  65. 6 8
      code/AssetLib/IFC/IFCUtil.h
  66. 1 1
      code/AssetLib/Irr/IRRLoader.h
  67. 1 1
      code/AssetLib/LWO/LWOAnimation.h
  68. 3 3
      code/AssetLib/LWS/LWSLoader.cpp
  69. 8 8
      code/AssetLib/M3D/M3DImporter.cpp
  70. 2 2
      code/AssetLib/M3D/M3DImporter.h
  71. 50 18
      code/AssetLib/M3D/M3DWrapper.h
  72. 0 1224
      code/AssetLib/M3D/m3d.h
  73. 1 1
      code/AssetLib/MD5/MD5Loader.cpp
  74. 2 2
      code/AssetLib/MDC/MDCFileData.h
  75. 2 2
      code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp
  76. 4 4
      code/AssetLib/MMD/MMDPmxParser.cpp
  77. 5 5
      code/AssetLib/OFF/OFFLoader.cpp
  78. 9 9
      code/AssetLib/Obj/ObjExporter.h
  79. 2 2
      code/AssetLib/Obj/ObjFileImporter.cpp
  80. 1 1
      code/AssetLib/Obj/ObjFileMtlImporter.cpp
  81. 2 2
      code/AssetLib/Ogre/OgreMaterial.cpp
  82. 6 2
      code/AssetLib/Ply/PlyParser.cpp
  83. 2 2
      code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp
  84. 1 1
      code/AssetLib/SMD/SMDLoader.cpp
  85. 5 4
      code/AssetLib/STEPParser/STEPFileReader.cpp
  86. 4 4
      code/AssetLib/STL/STLExporter.cpp
  87. 2 2
      code/AssetLib/STL/STLLoader.cpp
  88. 2 2
      code/AssetLib/Step/STEPFile.h
  89. 79 47
      code/AssetLib/Step/StepExporter.cpp
  90. 3 3
      code/AssetLib/X/XFileExporter.cpp
  91. 3 3
      code/AssetLib/X/XFileExporter.h
  92. 1 3
      code/AssetLib/X/XFileImporter.cpp
  93. 3 3
      code/AssetLib/X3D/X3DExporter.hpp
  94. 0 1
      code/AssetLib/X3D/X3DImporter.cpp
  95. 3 6
      code/AssetLib/XGL/XGLLoader.cpp
  96. 1 1
      code/AssetLib/XGL/XGLLoader.h
  97. 4 6
      code/AssetLib/glTF/glTFAsset.h
  98. 1 1
      code/AssetLib/glTF/glTFAsset.inl
  99. 3 3
      code/AssetLib/glTF/glTFCommon.h
  100. 2 2
      code/AssetLib/glTF/glTFExporter.cpp

+ 1 - 1
.gitignore

@@ -25,7 +25,7 @@ CMakeSettings.json
 # Output
 # Output
 bin/
 bin/
 lib/
 lib/
-
+x64/
 # QtCreator
 # QtCreator
 CMakeLists.txt.user
 CMakeLists.txt.user
 
 

+ 11 - 9
CMakeLists.txt

@@ -44,10 +44,10 @@ CMAKE_MINIMUM_REQUIRED( VERSION 3.10 )
 option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
 option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
 
 
 IF(ASSIMP_HUNTER_ENABLED)
 IF(ASSIMP_HUNTER_ENABLED)
-  include("cmake/HunterGate.cmake")
+  include("cmake-modules/HunterGate.cmake")
   HunterGate(
   HunterGate(
-    URL "https://github.com/cpp-pm/hunter/archive/v0.23.293.tar.gz"
-    SHA1 "e8e5470652db77149d9b38656db2a6c0b7642693"
+    URL "https://github.com/cpp-pm/hunter/archive/v0.23.311.tar.gz"
+    SHA1 "1a82b9b73055879181cb1466b2ab5d48ee8ae410"
   )
   )
 
 
   add_definitions(-DASSIMP_USE_HUNTER)
   add_definitions(-DASSIMP_USE_HUNTER)
@@ -135,11 +135,11 @@ IF ( WIN32 )
   # Use subset of Windows.h
   # Use subset of Windows.h
   ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
   ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
 
 
-  OPTION ( ASSIMP_BUILD_ASSIMP_VIEW
-    "If the Assimp view tool is built. (requires DirectX)"
-    OFF )
-
   IF(MSVC)
   IF(MSVC)
+    OPTION ( ASSIMP_BUILD_ASSIMP_VIEW
+      "If the Assimp view tool is built. (requires DirectX)"
+      OFF )
+
     OPTION( ASSIMP_INSTALL_PDB
     OPTION( ASSIMP_INSTALL_PDB
       "Install MSVC debug files."
       "Install MSVC debug files."
       ON )
       ON )
@@ -268,6 +268,8 @@ ELSEIF(MSVC)
     ADD_COMPILE_OPTIONS(/wd4351)
     ADD_COMPILE_OPTIONS(/wd4351)
   ENDIF()
   ENDIF()
   SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
   SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
+  SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
+  SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
 ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
 ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
   IF(NOT ASSIMP_HUNTER_ENABLED)
   IF(NOT ASSIMP_HUNTER_ENABLED)
     SET(CMAKE_CXX_STANDARD 11)
     SET(CMAKE_CXX_STANDARD 11)
@@ -395,14 +397,14 @@ set(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
 
 
 IF(ASSIMP_HUNTER_ENABLED)
 IF(ASSIMP_HUNTER_ENABLED)
   set(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
   set(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
-  set(CMAKE_CONFIG_TEMPLATE_FILE "cmake/assimp-hunter-config.cmake.in")
+  set(CMAKE_CONFIG_TEMPLATE_FILE "cmake-modules/assimp-hunter-config.cmake.in")
   set(NAMESPACE "${PROJECT_NAME}::")
   set(NAMESPACE "${PROJECT_NAME}::")
   set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
   set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
   set(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
   set(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
   set(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
   set(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
 ELSE()
 ELSE()
   set(CONFIG_INSTALL_DIR "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
   set(CONFIG_INSTALL_DIR "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
-  set(CMAKE_CONFIG_TEMPLATE_FILE "cmake/assimp-plain-config.cmake.in")
+  set(CMAKE_CONFIG_TEMPLATE_FILE "cmake-modules/assimp-plain-config.cmake.in")
   string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE)
   string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE)
   set(NAMESPACE "${PROJECT_NAME_LOWERCASE}::")
   set(NAMESPACE "${PROJECT_NAME_LOWERCASE}::")
   set(TARGETS_EXPORT_NAME "${PROJECT_NAME_LOWERCASE}Targets")
   set(TARGETS_EXPORT_NAME "${PROJECT_NAME_LOWERCASE}Targets")

+ 0 - 17
cmake-modules/FindIrrXML.cmake

@@ -1,17 +0,0 @@
-# Find IrrXMl from irrlicht project
-#
-# Find LibIrrXML headers and library
-#
-#   IRRXML_FOUND          - IrrXML found
-#   IRRXML_INCLUDE_DIR    - Headers location
-#   IRRXML_LIBRARY        - IrrXML main library
-
-find_path(IRRXML_INCLUDE_DIR irrXML.h
-    PATH_SUFFIXES include/irrlicht include/irrxml)
-find_library(IRRXML_LIBRARY IrrXML)
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(IrrXML REQUIRED_VARS IRRXML_INCLUDE_DIR IRRXML_LIBRARY)
-
-
-mark_as_advanced(IRRXML_INCLUDE_DIR IRRXML_LIBRARY)

+ 0 - 0
cmake/HunterGate.cmake → cmake-modules/HunterGate.cmake


+ 19 - 0
cmake-modules/assimp-hunter-config.cmake.in

@@ -0,0 +1,19 @@
+@PACKAGE_INIT@
+
+find_package(RapidJSON     CONFIG REQUIRED)
+find_package(ZLIB          CONFIG REQUIRED)
+find_package(utf8cpp       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)
+find_package(pugixml       CONFIG REQUIRED)
+find_package(stb           CONFIG REQUIRED)
+
+if(@ASSIMP_BUILD_DRACO@)
+  find_package(draco CONFIG REQUIRED)
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
+check_required_components("@PROJECT_NAME@")

+ 0 - 0
cmake/assimp-plain-config.cmake.in → cmake-modules/assimp-plain-config.cmake.in


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

@@ -1,18 +0,0 @@
-@PACKAGE_INIT@
-
-find_package(RapidJSON CONFIG REQUIRED)
-find_package(ZLIB CONFIG REQUIRED)
-find_package(utf8cpp 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)
-find_package(pugixml CONFIG REQUIRED)
-
-if(@ASSIMP_BUILD_DRACO@)
-  find_package(draco CONFIG REQUIRED)
-endif()
-
-include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
-check_required_components("@PROJECT_NAME@")

+ 3 - 8
code/AssetLib/3DS/3DSConverter.cpp

@@ -68,8 +68,8 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
     unsigned int idx(NotSet);
     unsigned int idx(NotSet);
     for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
     for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
         std::string s = mScene->mMaterials[i].mName;
         std::string s = mScene->mMaterials[i].mName;
-        for (std::string::iterator it = s.begin(); it != s.end(); ++it) {
-            *it = static_cast<char>(::tolower(static_cast<unsigned char>(*it)));
+        for (char & it : s) {
+            it = static_cast<char>(::tolower(static_cast<unsigned char>(it)));
         }
         }
 
 
         if (std::string::npos == s.find("default")) continue;
         if (std::string::npos == s.find("default")) continue;
@@ -79,12 +79,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
                 mScene->mMaterials[i].mDiffuse.r !=
                 mScene->mMaterials[i].mDiffuse.r !=
                         mScene->mMaterials[i].mDiffuse.b) continue;
                         mScene->mMaterials[i].mDiffuse.b) continue;
 
 
-        if (mScene->mMaterials[i].sTexDiffuse.mMapName.length() != 0 ||
-                mScene->mMaterials[i].sTexBump.mMapName.length() != 0 ||
-                mScene->mMaterials[i].sTexOpacity.mMapName.length() != 0 ||
-                mScene->mMaterials[i].sTexEmissive.mMapName.length() != 0 ||
-                mScene->mMaterials[i].sTexSpecular.mMapName.length() != 0 ||
-                mScene->mMaterials[i].sTexShininess.mMapName.length() != 0) {
+        if (ContainsTextures(i)) {
             continue;
             continue;
         }
         }
         idx = i;
         idx = i;

+ 1 - 1
code/AssetLib/3DS/3DSExporter.cpp

@@ -291,7 +291,7 @@ void Discreet3DSExporter::WriteMaterials() {
             ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
             ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
             WriteColor(color);
             WriteColor(color);
         }
         }
-                
+
         if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
         if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
             ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
             ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
             WriteColor(color);
             WriteColor(color);

+ 38 - 38
code/AssetLib/3DS/3DSHelper.h

@@ -348,16 +348,16 @@ struct Texture {
         // empty
         // empty
     }
     }
 
 
-    Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(std::move(other.mTextureBlend)),
+    Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(other.mTextureBlend),
                                             mMapName(std::move(other.mMapName)),
                                             mMapName(std::move(other.mMapName)),
-                                            mOffsetU(std::move(other.mOffsetU)),
-                                            mOffsetV(std::move(other.mOffsetV)),
-                                            mScaleU(std::move(other.mScaleU)),
-                                            mScaleV(std::move(other.mScaleV)),
-                                            mRotation(std::move(other.mRotation)),
-                                            mMapMode(std::move(other.mMapMode)),
-                                            bPrivate(std::move(other.bPrivate)),
-                                            iUVSrc(std::move(other.iUVSrc)) {
+                                            mOffsetU(other.mOffsetU),
+                                            mOffsetV(other.mOffsetV),
+                                            mScaleU(other.mScaleU),
+                                            mScaleV(other.mScaleV),
+                                            mRotation(other.mRotation),
+                                            mMapMode(other.mMapMode),
+                                            bPrivate(other.bPrivate),
+                                            iUVSrc(other.iUVSrc) {
         // empty
         // empty
     }
     }
 
 
@@ -366,16 +366,16 @@ struct Texture {
             return *this;
             return *this;
         }
         }
 
 
-        mTextureBlend = std::move(other.mTextureBlend);
+        mTextureBlend = other.mTextureBlend;
         mMapName = std::move(other.mMapName);
         mMapName = std::move(other.mMapName);
-        mOffsetU = std::move(other.mOffsetU);
-        mOffsetV = std::move(other.mOffsetV);
-        mScaleU = std::move(other.mScaleU);
-        mScaleV = std::move(other.mScaleV);
-        mRotation = std::move(other.mRotation);
-        mMapMode = std::move(other.mMapMode);
-        bPrivate = std::move(other.bPrivate);
-        iUVSrc = std::move(other.iUVSrc);
+        mOffsetU = other.mOffsetU;
+        mOffsetV = other.mOffsetV;
+        mScaleU = other.mScaleU;
+        mScaleV = other.mScaleV;
+        mRotation = other.mRotation;
+        mMapMode = other.mMapMode;
+        bPrivate = other.bPrivate;
+        iUVSrc = other.iUVSrc;
 
 
         return *this;
         return *this;
     }
     }
@@ -461,13 +461,13 @@ struct Material {
 
 
     //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
     //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
     Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)),
     Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)),
-                                              mDiffuse(std::move(other.mDiffuse)),
-                                              mSpecularExponent(std::move(other.mSpecularExponent)),
-                                              mShininessStrength(std::move(other.mShininessStrength)),
-                                              mSpecular(std::move(other.mSpecular)),
-                                              mAmbient(std::move(other.mAmbient)),
-                                              mShading(std::move(other.mShading)),
-                                              mTransparency(std::move(other.mTransparency)),
+                                              mDiffuse(other.mDiffuse),
+                                              mSpecularExponent(other.mSpecularExponent),
+                                              mShininessStrength(other.mShininessStrength),
+                                              mSpecular(other.mSpecular),
+                                              mAmbient(other.mAmbient),
+                                              mShading(other.mShading),
+                                              mTransparency(other.mTransparency),
                                               sTexDiffuse(std::move(other.sTexDiffuse)),
                                               sTexDiffuse(std::move(other.sTexDiffuse)),
                                               sTexOpacity(std::move(other.sTexOpacity)),
                                               sTexOpacity(std::move(other.sTexOpacity)),
                                               sTexSpecular(std::move(other.sTexSpecular)),
                                               sTexSpecular(std::move(other.sTexSpecular)),
@@ -475,10 +475,10 @@ struct Material {
                                               sTexBump(std::move(other.sTexBump)),
                                               sTexBump(std::move(other.sTexBump)),
                                               sTexEmissive(std::move(other.sTexEmissive)),
                                               sTexEmissive(std::move(other.sTexEmissive)),
                                               sTexShininess(std::move(other.sTexShininess)),
                                               sTexShininess(std::move(other.sTexShininess)),
-                                              mBumpHeight(std::move(other.mBumpHeight)),
-                                              mEmissive(std::move(other.mEmissive)),
+                                              mBumpHeight(other.mBumpHeight),
+                                              mEmissive(other.mEmissive),
                                               sTexAmbient(std::move(other.sTexAmbient)),
                                               sTexAmbient(std::move(other.sTexAmbient)),
-                                              mTwoSided(std::move(other.mTwoSided)) {
+                                              mTwoSided(other.mTwoSided) {
         // empty
         // empty
     }
     }
 
 
@@ -488,13 +488,13 @@ struct Material {
         }
         }
 
 
         mName = std::move(other.mName);
         mName = std::move(other.mName);
-        mDiffuse = std::move(other.mDiffuse);
-        mSpecularExponent = std::move(other.mSpecularExponent);
-        mShininessStrength = std::move(other.mShininessStrength),
-        mSpecular = std::move(other.mSpecular);
-        mAmbient = std::move(other.mAmbient);
-        mShading = std::move(other.mShading);
-        mTransparency = std::move(other.mTransparency);
+        mDiffuse = other.mDiffuse;
+        mSpecularExponent = other.mSpecularExponent;
+        mShininessStrength = other.mShininessStrength,
+        mSpecular = other.mSpecular;
+        mAmbient = other.mAmbient;
+        mShading = other.mShading;
+        mTransparency = other.mTransparency;
         sTexDiffuse = std::move(other.sTexDiffuse);
         sTexDiffuse = std::move(other.sTexDiffuse);
         sTexOpacity = std::move(other.sTexOpacity);
         sTexOpacity = std::move(other.sTexOpacity);
         sTexSpecular = std::move(other.sTexSpecular);
         sTexSpecular = std::move(other.sTexSpecular);
@@ -502,10 +502,10 @@ struct Material {
         sTexBump = std::move(other.sTexBump);
         sTexBump = std::move(other.sTexBump);
         sTexEmissive = std::move(other.sTexEmissive);
         sTexEmissive = std::move(other.sTexEmissive);
         sTexShininess = std::move(other.sTexShininess);
         sTexShininess = std::move(other.sTexShininess);
-        mBumpHeight = std::move(other.mBumpHeight);
-        mEmissive = std::move(other.mEmissive);
+        mBumpHeight = other.mBumpHeight;
+        mEmissive = other.mEmissive;
         sTexAmbient = std::move(other.sTexAmbient);
         sTexAmbient = std::move(other.sTexAmbient);
-        mTwoSided = std::move(other.mTwoSided);
+        mTwoSided = other.mTwoSided;
 
 
         return *this;
         return *this;
     }
     }

+ 9 - 0
code/AssetLib/3DS/3DSLoader.h

@@ -208,6 +208,15 @@ protected:
     */
     */
     void ReplaceDefaultMaterial();
     void ReplaceDefaultMaterial();
 
 
+    bool ContainsTextures(unsigned int i) const {
+        return !mScene->mMaterials[i].sTexDiffuse.mMapName.empty() ||
+               !mScene->mMaterials[i].sTexBump.mMapName.empty() ||
+               !mScene->mMaterials[i].sTexOpacity.mMapName.empty() ||
+               !mScene->mMaterials[i].sTexEmissive.mMapName.empty() ||
+               !mScene->mMaterials[i].sTexSpecular.mMapName.empty() ||
+               !mScene->mMaterials[i].sTexShininess.mMapName.empty() ;
+    }
+
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Convert the whole scene
     /** Convert the whole scene
     */
     */

+ 165 - 0
code/AssetLib/3MF/3MFTypes.h

@@ -0,0 +1,165 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2021, 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.
+
+----------------------------------------------------------------------
+*/
+#pragma once
+
+#include <assimp/vector3.h>
+#include <assimp/matrix4x4.h>
+#include <assimp/ParsingUtils.h>
+#include <vector>
+#include <string>
+
+struct aiMaterial;
+struct aiMesh;
+
+namespace Assimp {
+namespace D3MF {
+
+enum class ResourceType {
+    RT_Object,
+    RT_BaseMaterials,
+    RT_EmbeddedTexture2D,
+    RT_Texture2DGroup,
+    RT_Unknown
+}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
+
+class Resource {
+public:
+    int mId;
+
+    Resource(int id) :
+            mId(id) {
+        // empty
+    }
+
+    virtual ~Resource() {
+        // empty
+    }
+
+    virtual ResourceType getType() const {
+        return ResourceType::RT_Unknown;
+    }
+};
+
+class EmbeddedTexture : public Resource {
+public:
+    std::string mPath;
+    std::string mContentType;
+    std::string mTilestyleU;
+    std::string mTilestyleV;
+    std::vector<char> mBuffer;
+
+    EmbeddedTexture(int id) :
+            Resource(id),
+            mPath(),
+            mContentType(),
+            mTilestyleU(),
+            mTilestyleV() {
+        // empty
+    }
+
+    ~EmbeddedTexture() = default;
+
+    ResourceType getType() const override {
+        return ResourceType::RT_EmbeddedTexture2D;
+    }
+};
+
+class Texture2DGroup : public Resource {
+public:
+    std::vector<aiVector2D> mTex2dCoords;
+    int mTexId;
+    Texture2DGroup(int id) :
+            Resource(id),
+            mTexId(-1) {
+        // empty
+    }
+
+    ~Texture2DGroup() = default;
+
+    ResourceType getType() const override {
+        return ResourceType::RT_Texture2DGroup;
+    }
+};
+
+class BaseMaterials : public Resource {
+public:
+    std::vector<unsigned int> mMaterialIndex;
+
+    BaseMaterials(int id) :
+            Resource(id),
+            mMaterialIndex() {
+        // empty
+    }
+
+    ~BaseMaterials() = default;
+
+    ResourceType getType() const override {
+        return ResourceType::RT_BaseMaterials;
+    }
+};
+
+struct Component {
+    int mObjectId;
+    aiMatrix4x4 mTransformation;
+};
+
+class Object : public Resource {
+public:
+    std::vector<aiMesh *> mMeshes;
+    std::vector<unsigned int> mMeshIndex;
+    std::vector<Component> mComponents;
+    std::string mName;
+
+    Object(int id) :
+            Resource(id),
+            mName(std::string("Object_") + ai_to_string(id)) {
+        // empty
+    }
+
+    ~Object() = default;
+
+    ResourceType getType() const override {
+        return ResourceType::RT_Object;
+    }
+};
+
+} // namespace D3MF
+} // namespace Assimp

+ 10 - 2
code/AssetLib/3MF/3MFXmlTags.h

@@ -80,13 +80,21 @@ namespace XmlTag {
     const char* const item = "item";
     const char* const item = "item";
     const char* const objectid = "objectid";
     const char* const objectid = "objectid";
     const char* const transform = "transform";
     const char* const transform = "transform";
+    const char *const path = "path";
 
 
     // Material definitions
     // Material definitions
     const char* const basematerials = "basematerials";
     const char* const basematerials = "basematerials";
-    const char* const basematerials_id = "id";
     const char* const basematerials_base = "base";
     const char* const basematerials_base = "base";
     const char* const basematerials_name = "name";
     const char* const basematerials_name = "name";
     const char* const basematerials_displaycolor = "displaycolor";
     const char* const basematerials_displaycolor = "displaycolor";
+    const char* const texture_2d = "m:texture2d";
+    const char *const texture_group = "m:texture2dgroup";
+    const char *const texture_content_type = "contenttype";
+    const char *const texture_tilestyleu = "tilestyleu";
+    const char *const texture_tilestylev = "tilestylev";
+    const char *const texture_2d_coord = "m:tex2coord";
+    const char *const texture_cuurd_u = "u";
+    const char *const texture_cuurd_v = "v";
 
 
     // Meta info tags
     // Meta info tags
     const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
     const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
@@ -103,7 +111,7 @@ namespace XmlTag {
     const char* const PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
     const char* const PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
     const char* const PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
     const char* const PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
     const char* const PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
     const char* const PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
-    }
+}
 
 
 } // Namespace D3MF
 } // Namespace D3MF
 } // Namespace Assimp
 } // Namespace Assimp

+ 15 - 507
code/AssetLib/3MF/D3MFImporter.cpp

@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "D3MFImporter.h"
 #include "D3MFImporter.h"
 #include "3MFXmlTags.h"
 #include "3MFXmlTags.h"
 #include "D3MFOpcPackage.h"
 #include "D3MFOpcPackage.h"
+#include "XmlSerializer.h"
 
 
 #include <assimp/StringComparison.h>
 #include <assimp/StringComparison.h>
 #include <assimp/StringUtils.h>
 #include <assimp/StringUtils.h>
@@ -61,513 +62,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 #include <iomanip>
 #include <iomanip>
-#include <string.h>
+#include <cstring>
 
 
 namespace Assimp {
 namespace Assimp {
-namespace D3MF {
-
-enum class ResourceType {
-    RT_Object,
-    RT_BaseMaterials,
-    RT_Unknown
-}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
-
-class Resource {
-public:
-    int mId;
-
-    Resource(int id) :
-            mId(id) {
-        // empty
-    }
-
-    virtual ~Resource() {
-        // empty
-    }
-
-    virtual ResourceType getType() const {
-        return ResourceType::RT_Unknown;
-    }
-};
-
-class BaseMaterials : public Resource {
-public:
-    std::vector<aiMaterial *> mMaterials;
-    std::vector<unsigned int> mMaterialIndex;
-
-    BaseMaterials(int id) :
-            Resource(id),
-            mMaterials(),
-            mMaterialIndex() {
-        // empty
-    }
-
-    ~BaseMaterials() = default;
-
-    ResourceType getType() const override {
-        return ResourceType::RT_BaseMaterials;
-    }
-};
-
-struct Component {
-    int mObjectId;
-    aiMatrix4x4 mTransformation;
-};
-
-class Object : public Resource {
-public:
-    std::vector<aiMesh *> mMeshes;
-    std::vector<unsigned int> mMeshIndex;
-    std::vector<Component> mComponents;
-    std::string mName;
-
-    Object(int id) :
-            Resource(id),
-            mName(std::string("Object_") + ai_to_string(id)) {
-        // empty
-    }
-
-    ~Object() = default;
-
-    ResourceType getType() const override {
-        return ResourceType::RT_Object;
-    }
-};
-
-class XmlSerializer {
-public:
-    XmlSerializer(XmlParser *xmlParser) :
-            mResourcesDictionnary(),
-            mMaterialCount(0),
-            mMeshCount(0),
-            mXmlParser(xmlParser) {
-        // empty
-    }
-
-    ~XmlSerializer() {
-        for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it ) {
-            delete it->second;
-        }
-    }
-
-    void ImportXml(aiScene *scene) {
-        if (nullptr == scene) {
-            return;
-        }
-
-        scene->mRootNode = new aiNode(XmlTag::RootTag);
-
-        XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
-        if (node.empty()) {
-            return;
-        }
-        XmlNode resNode = node.child(XmlTag::resources);
-        for (auto &currentNode : resNode.children()) {
-            const std::string currentNodeName = currentNode.name();
-            if (currentNodeName == XmlTag::object) {
-                ReadObject(currentNode);
-            } else if (currentNodeName == XmlTag::basematerials) {
-                ReadBaseMaterials(currentNode);
-            } else if (currentNodeName == XmlTag::meta) {
-                ReadMetadata(currentNode);
-            }
-        }
-
-        XmlNode buildNode = node.child(XmlTag::build);
-        for (auto &currentNode : buildNode.children()) {
-            const std::string currentNodeName = currentNode.name();
-            if (currentNodeName == XmlTag::item) {
-                int objectId = -1;
-                std::string transformationMatrixStr;
-                aiMatrix4x4 transformationMatrix;
-                getNodeAttribute(currentNode, D3MF::XmlTag::objectid, objectId);
-                bool hasTransform = getNodeAttribute(currentNode, D3MF::XmlTag::transform, transformationMatrixStr);
-
-                auto it = mResourcesDictionnary.find(objectId);
-                if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
-                    Object *obj = static_cast<Object *>(it->second);
-                    if (hasTransform) {
-                        transformationMatrix = parseTransformMatrix(transformationMatrixStr);
-                    }
-
-                    addObjectToNode(scene->mRootNode, obj, transformationMatrix);
-                }
-            }
-        }
-
-        // import the metadata
-        if (!mMetaData.empty()) {
-            const size_t numMeta = mMetaData.size();
-            scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(numMeta));
-            for (size_t i = 0; i < numMeta; ++i) {
-                aiString val(mMetaData[i].value);
-                scene->mMetaData->Set(static_cast<unsigned int>(i), mMetaData[i].name, val);
-            }
-        }
-
-        // import the meshes
-        scene->mNumMeshes = static_cast<unsigned int>(mMeshCount);
-        if (scene->mNumMeshes != 0) {
-            scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
-            for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) {
-                if (it->second->getType() == ResourceType::RT_Object) {
-                    Object *obj = static_cast<Object *>(it->second);
-                    ai_assert(nullptr != obj);
-                    for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
-                        scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
-                    }
-                }
-            }
-        }
-
-        // import the materials
-        scene->mNumMaterials = mMaterialCount;
-        if (scene->mNumMaterials != 0) {
-            scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
-            for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) {
-                if (it->second->getType() == ResourceType::RT_BaseMaterials) {
-                    BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
-                    for (unsigned int i = 0; i < baseMaterials->mMaterials.size(); ++i) {
-                        scene->mMaterials[baseMaterials->mMaterialIndex[i]] = baseMaterials->mMaterials[i];
-                    }
-                }
-            }
-        }
-    }
-
-private:
-    void addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform) {
-        ai_assert(nullptr != obj);
-
-        aiNode *sceneNode = new aiNode(obj->mName);
-        sceneNode->mNumMeshes = static_cast<unsigned int>(obj->mMeshes.size());
-        sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes];
-        std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes);
-
-        sceneNode->mTransformation = nodeTransform;
-        if (nullptr != parent) {
-            parent->addChildren(1, &sceneNode);
-        }
-
-        for (size_t i = 0; i < obj->mComponents.size(); ++i) {
-            Component c = obj->mComponents[i];
-            auto it = mResourcesDictionnary.find(c.mObjectId);
-            if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
-                addObjectToNode(sceneNode, static_cast<Object *>(it->second), c.mTransformation);
-            }
-        }
-    }
-
-    bool getNodeAttribute(const XmlNode &node, const std::string &attribute, std::string &value) {
-        pugi::xml_attribute objectAttribute = node.attribute(attribute.c_str());
-        if (!objectAttribute.empty()) {
-            value = objectAttribute.as_string();
-            return true;
-        }
-
-        return false;
-    }
-
-    bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
-        std::string strValue;
-        bool ret = getNodeAttribute(node, attribute, strValue);
-        if (ret) {
-            value = std::atoi(strValue.c_str());
-            return true;
-        } 
-
-        return false;
-    }
-
-    aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
-        // split the string
-        std::vector<float> numbers;
-        std::string currentNumber;
-        for (size_t i = 0; i < matrixStr.size(); ++i) {
-            const char c = matrixStr[i];
-            if (c == ' ') {
-                if (currentNumber.size() > 0) {
-                    float f = std::stof(currentNumber);
-                    numbers.push_back(f);
-                    currentNumber.clear();
-                }
-            } else {
-                currentNumber.push_back(c);
-            }
-        }
-        if (currentNumber.size() > 0) {
-            const float f = std::stof(currentNumber);
-            numbers.push_back(f);
-        }
-
-        aiMatrix4x4 transformMatrix;
-        transformMatrix.a1 = numbers[0];
-        transformMatrix.b1 = numbers[1];
-        transformMatrix.c1 = numbers[2];
-        transformMatrix.d1 = 0;
-
-        transformMatrix.a2 = numbers[3];
-        transformMatrix.b2 = numbers[4];
-        transformMatrix.c2 = numbers[5];
-        transformMatrix.d2 = 0;
-
-        transformMatrix.a3 = numbers[6];
-        transformMatrix.b3 = numbers[7];
-        transformMatrix.c3 = numbers[8];
-        transformMatrix.d3 = 0;
-
-        transformMatrix.a4 = numbers[9];
-        transformMatrix.b4 = numbers[10];
-        transformMatrix.c4 = numbers[11];
-        transformMatrix.d4 = 1;
-
-        return transformMatrix;
-    }
-
-    void ReadObject(XmlNode &node) {
-        int id = -1, pid = -1, pindex = -1;
-        bool hasId = getNodeAttribute(node, XmlTag::id, id);
-        bool hasPid = getNodeAttribute(node, XmlTag::pid, pid);
-        bool hasPindex = getNodeAttribute(node, XmlTag::pindex, pindex);
-        if (!hasId) {
-            return;
-        }
-
-        Object *obj = new Object(id);
-
-        for (XmlNode &currentNode : node.children()) {
-            const std::string &currentName = currentNode.name();
-            if (currentName == D3MF::XmlTag::mesh) {
-                auto mesh = ReadMesh(currentNode);
-                mesh->mName.Set(ai_to_string(id));
-
-                if (hasPid) {
-                    auto it = mResourcesDictionnary.find(pid);
-                    if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
-                        BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
-                        mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
-                    }
-                }
-
-                obj->mMeshes.push_back(mesh);
-                obj->mMeshIndex.push_back(mMeshCount);
-                mMeshCount++;
-            } else if (currentName == D3MF::XmlTag::components) {
-                for (XmlNode &currentSubNode : currentNode.children()) {
-                    const std::string subNodeName = currentSubNode.name();
-                    if (subNodeName == D3MF::XmlTag::component) {
-                        int objectId = -1;
-                        std::string componentTransformStr;
-                        aiMatrix4x4 componentTransform;
-                        if (getNodeAttribute(currentSubNode, D3MF::XmlTag::transform, componentTransformStr)) {
-                            componentTransform = parseTransformMatrix(componentTransformStr);
-                        }
-
-                        if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) {
-                            obj->mComponents.push_back({ objectId, componentTransform });
-                        }
-                    }
-                }
-            }
-        }
-
-        mResourcesDictionnary.insert(std::make_pair(id, obj));
-    }
-
-    aiMesh *ReadMesh(XmlNode &node) {
-        aiMesh *mesh = new aiMesh();
-
-        for (XmlNode &currentNode : node.children()) {
-            const std::string currentName = currentNode.name();
-            if (currentName == XmlTag::vertices) {
-                ImportVertices(currentNode, mesh);
-            } else if (currentName == XmlTag::triangles) {
-                ImportTriangles(currentNode, mesh);
-            }
-        }
-
-        return mesh;
-    }
-
-    void ReadMetadata(XmlNode &node) {
-        pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name);
-        const std::string name = attribute.as_string();
-        const std::string value = node.value();
-        if (name.empty()) {
-            return;
-        }
-
-        MetaEntry entry;
-        entry.name = name;
-        entry.value = value;
-        mMetaData.push_back(entry);
-    }
-
-    void ImportVertices(XmlNode &node, aiMesh *mesh) {
-        std::vector<aiVector3D> vertices;
-        for (XmlNode &currentNode : node.children()) {
-            const std::string currentName = currentNode.name();
-            if (currentName == XmlTag::vertex) {
-                vertices.push_back(ReadVertex(currentNode));
-            }
-        }
-
-        mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
-        mesh->mVertices = new aiVector3D[mesh->mNumVertices];
-        std::copy(vertices.begin(), vertices.end(), mesh->mVertices);
-    }
-
-    aiVector3D ReadVertex(XmlNode &node) {
-        aiVector3D vertex;
-        vertex.x = ai_strtof(node.attribute(XmlTag::x).as_string(), nullptr);
-        vertex.y = ai_strtof(node.attribute(XmlTag::y).as_string(), nullptr);
-        vertex.z = ai_strtof(node.attribute(XmlTag::z).as_string(), nullptr);
-
-        return vertex;
-    }
-
-    void ImportTriangles(XmlNode &node, aiMesh *mesh) {
-        std::vector<aiFace> faces;
-        for (XmlNode &currentNode : node.children()) {
-            const std::string currentName = currentNode.name();
-            if (currentName == XmlTag::triangle) {
-                aiFace face = ReadTriangle(currentNode);
-                faces.push_back(face);
-
-                int pid = 0, p1 = 0;
-                bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
-                bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
-
-                if (hasPid && hasP1) {
-                    auto it = mResourcesDictionnary.find(pid);
-                    if (it != mResourcesDictionnary.end()) {
-                        if (it->second->getType() == ResourceType::RT_BaseMaterials) {
-                            BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
-                            mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
-                        }
-                        // TODO: manage the separation into several meshes if the triangles of the mesh do not all refer to the same material
-                    }
-                }
-            }
-        }
-
-        mesh->mNumFaces = static_cast<unsigned int>(faces.size());
-        mesh->mFaces = new aiFace[mesh->mNumFaces];
-        mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
-        std::copy(faces.begin(), faces.end(), mesh->mFaces);
-    }
-
-    aiFace ReadTriangle(XmlNode &node) {
-        aiFace face;
-
-        face.mNumIndices = 3;
-        face.mIndices = new unsigned int[face.mNumIndices];
-        face.mIndices[0] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v1).as_string()));
-        face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
-        face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
-
-        return face;
-    }
-
-    void ReadBaseMaterials(XmlNode &node) {
-        int id = -1;
-        if (getNodeAttribute(node, D3MF::XmlTag::basematerials_id, id)) {
-            BaseMaterials *baseMaterials = new BaseMaterials(id);
-
-            for (XmlNode &currentNode : node.children()) {
-                const std::string currentName = currentNode.name();
-                if (currentName == XmlTag::basematerials_base) {
-                    baseMaterials->mMaterialIndex.push_back(mMaterialCount);
-                    baseMaterials->mMaterials.push_back(readMaterialDef(currentNode, id));
-                    ++mMaterialCount;
-                }
-            }
-
-            mResourcesDictionnary.insert(std::make_pair(id, baseMaterials));
-        }
-    }
-
-    bool parseColor(const char *color, aiColor4D &diffuse) {
-        if (nullptr == color) {
-            return false;
-        }
-
-        //format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
-        const size_t len = strlen(color);
-        if (9 != len && 7 != len) {
-            return false;
-        }
-
-        const char *buf(color);
-        if ('#' != buf[0]) {
-            return false;
-        }
-
-        char r[3] = { buf[1], buf[2], '\0' };
-        diffuse.r = static_cast<ai_real>(strtol(r, nullptr, 16)) / ai_real(255.0);
-
-        char g[3] = { buf[3], buf[4], '\0' };
-        diffuse.g = static_cast<ai_real>(strtol(g, nullptr, 16)) / ai_real(255.0);
-
-        char b[3] = { buf[5], buf[6], '\0' };
-        diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
-
-        if (7 == len)
-            return true;
-
-        char a[3] = { buf[7], buf[8], '\0' };
-        diffuse.a = static_cast<ai_real>(strtol(a, nullptr, 16)) / ai_real(255.0);
-
-        return true;
-    }
-
-    void assignDiffuseColor(XmlNode &node, aiMaterial *mat) {
-        const char *color = node.attribute(XmlTag::basematerials_displaycolor).as_string();
-        aiColor4D diffuse;
-        if (parseColor(color, diffuse)) {
-            mat->AddProperty<aiColor4D>(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
-        }
-    }
-
-    aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId) {
-        aiMaterial *material = new aiMaterial();
-        material->mNumProperties = 0;
-        std::string name;
-        bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
-
-        std::string stdMaterialName;
-        const std::string strId(ai_to_string(basematerialsId));
-        stdMaterialName += "id";
-        stdMaterialName += strId;
-        stdMaterialName += "_";
-        if (hasName) {
-            stdMaterialName += std::string(name);
-        } else {
-            stdMaterialName += "basemat_";
-            stdMaterialName += ai_to_string(mMaterialCount - basematerialsId);
-        }
-
-        aiString assimpMaterialName(stdMaterialName);
-        material->AddProperty(&assimpMaterialName, AI_MATKEY_NAME);
-
-        assignDiffuseColor(node, material);
-
-        return material;
-    }
-
-private:
-    struct MetaEntry {
-        std::string name;
-        std::string value;
-    };
-    std::vector<MetaEntry> mMetaData;
-    std::map<unsigned int, Resource *> mResourcesDictionnary;
-    unsigned int mMaterialCount, mMeshCount;
-    XmlParser *mXmlParser;
-};
-
-} //namespace D3MF
 
 
 using namespace D3MF;
 using namespace D3MF;
 
 
@@ -597,7 +94,9 @@ bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bo
     const std::string extension(GetExtension(filename));
     const std::string extension(GetExtension(filename));
     if (extension == desc.mFileExtensions) {
     if (extension == desc.mFileExtensions) {
         return true;
         return true;
-    } else if (!extension.length() || checkSig) {
+    } 
+
+    if (!extension.length() || checkSig) {
         if (nullptr == pIOHandler) {
         if (nullptr == pIOHandler) {
             return false;
             return false;
         }
         }
@@ -611,7 +110,7 @@ bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bo
     return false;
     return false;
 }
 }
 
 
-void D3MFImporter::SetupProperties(const Importer * /*pImp*/) {
+void D3MFImporter::SetupProperties(const Importer*) {
     // empty
     // empty
 }
 }
 
 
@@ -626,6 +125,15 @@ void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene,
     if (xmlParser.parse(opcPackage.RootStream())) {
     if (xmlParser.parse(opcPackage.RootStream())) {
         XmlSerializer xmlSerializer(&xmlParser);
         XmlSerializer xmlSerializer(&xmlParser);
         xmlSerializer.ImportXml(pScene);
         xmlSerializer.ImportXml(pScene);
+
+        const std::vector<aiTexture*> &tex =  opcPackage.GetEmbeddedTextures();
+        if (!tex.empty()) {
+            pScene->mNumTextures = static_cast<unsigned int>(tex.size());
+            pScene->mTextures = new aiTexture *[pScene->mNumTextures];
+            for (unsigned int i = 0; i < pScene->mNumTextures; ++i) {
+                pScene->mTextures[i] = tex[i];
+            }
+        }
     }
     }
 }
 }
 
 

+ 28 - 6
code/AssetLib/3MF/D3MFImporter.h

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 
 Copyright (c) 2006-2021, assimp team
 Copyright (c) 2006-2021, 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,
@@ -47,17 +46,40 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 namespace Assimp {
 namespace Assimp {
 
 
+// ---------------------------------------------------------------------------
 /// @brief  The 3MF-importer class.
 /// @brief  The 3MF-importer class.
+///
+/// Implements the basic topology import and embedded textures.
+// ---------------------------------------------------------------------------
 class D3MFImporter : public BaseImporter {
 class D3MFImporter : public BaseImporter {
 public:
 public:
+    /// @brief The default class constructor.
     D3MFImporter();
     D3MFImporter();
-    ~D3MFImporter();
-    bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
-    void SetupProperties(const Importer *pImp);
-    const aiImporterDesc *GetInfo() const;
+
+    ///	@brief  The class destructor.
+    ~D3MFImporter() override;
+
+    /// @brief Performs the data format detection.
+    /// @param pFile        The filename to check.
+    /// @param pIOHandler   The used IO-System.
+    /// @param checkSig     true for signature checking.
+    /// @return true for can be loaded, false for not.
+    bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
+
+    /// @brief  Not used
+    /// @param pImp Not used
+    void SetupProperties(const Importer *pImp) override;
+
+    /// @brief The importer description getter.
+    /// @return The info
+    const aiImporterDesc *GetInfo() const override;
 
 
 protected:
 protected:
-    void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
+    /// @brief Internal read function, performs the file parsing.
+    /// @param pFile        The filename
+    /// @param pScene       The scene to load in.
+    /// @param pIOHandler   The io-system
+    void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
 };
 };
 
 
 } // Namespace Assimp
 } // Namespace Assimp

+ 58 - 11
code/AssetLib/3MF/D3MFOpcPackage.cpp

@@ -43,14 +43,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include "D3MFOpcPackage.h"
 #include "D3MFOpcPackage.h"
 #include <assimp/Exceptional.h>
 #include <assimp/Exceptional.h>
-
 #include <assimp/XmlParser.h>
 #include <assimp/XmlParser.h>
 #include <assimp/ZipArchiveIOSystem.h>
 #include <assimp/ZipArchiveIOSystem.h>
 #include <assimp/ai_assert.h>
 #include <assimp/ai_assert.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/IOStream.hpp>
 #include <assimp/IOStream.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
-
+#include <assimp/texture.h>
 #include "3MFXmlTags.h"
 #include "3MFXmlTags.h"
 #include <algorithm>
 #include <algorithm>
 #include <cassert>
 #include <cassert>
@@ -64,11 +63,12 @@ namespace Assimp {
 namespace D3MF {
 namespace D3MF {
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 
 
-typedef std::shared_ptr<OpcPackageRelationship> OpcPackageRelationshipPtr;
+using OpcPackageRelationshipPtr = std::shared_ptr<OpcPackageRelationship>;
 
 
 class OpcPackageRelationshipReader {
 class OpcPackageRelationshipReader {
 public:
 public:
-    OpcPackageRelationshipReader(XmlParser &parser) {
+    OpcPackageRelationshipReader(XmlParser &parser) :
+            m_relationShips() {
         XmlNode root = parser.getRootNode();
         XmlNode root = parser.getRootNode();
         ParseRootNode(root);
         ParseRootNode(root);
     }
     }
@@ -91,6 +91,7 @@ public:
         if (relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty()) {
         if (relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty()) {
             return false;
             return false;
         }
         }
+
         return true;
         return true;
     }
     }
 
 
@@ -100,7 +101,7 @@ public:
         }
         }
 
 
         for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
         for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
-            std::string name = currentNode.name();
+            const std::string name = currentNode.name();
             if (name == "Relationship") {
             if (name == "Relationship") {
                 OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
                 OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
                 relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID).as_string();
                 relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID).as_string();
@@ -116,11 +117,23 @@ public:
     std::vector<OpcPackageRelationshipPtr> m_relationShips;
     std::vector<OpcPackageRelationshipPtr> m_relationShips;
 };
 };
 
 
+static bool IsEmbeddedTexture( const std::string &filename ) {
+    const std::string extension = BaseImporter::GetExtension(filename);
+    if (extension == "jpg" || extension == "png") {
+        std::string::size_type pos = filename.find("thumbnail");
+        if (pos == std::string::npos) {
+            return false;
+        }
+        return true;
+    }
+
+    return false;
+}
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
 D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
         mRootStream(nullptr),
         mRootStream(nullptr),
         mZipArchive() {
         mZipArchive() {
-    mZipArchive.reset(new ZipArchiveIOSystem(pIOHandler, rFile));
+    mZipArchive = new ZipArchiveIOSystem(pIOHandler, rFile);
     if (!mZipArchive->isOpen()) {
     if (!mZipArchive->isOpen()) {
         throw DeadlyImportError("Failed to open file ", rFile, ".");
         throw DeadlyImportError("Failed to open file ", rFile, ".");
     }
     }
@@ -141,13 +154,13 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
             }
             }
 
 
             std::string rootFile = ReadPackageRootRelationship(fileStream);
             std::string rootFile = ReadPackageRootRelationship(fileStream);
-            if (rootFile.size() > 0 && rootFile[0] == '/') {
+            if (!rootFile.empty() && rootFile[0] == '/') {
                 rootFile = rootFile.substr(1);
                 rootFile = rootFile.substr(1);
                 if (rootFile[0] == '/') {
                 if (rootFile[0] == '/') {
                     // deal with zip-bug
                     // deal with zip-bug
                     rootFile = rootFile.substr(1);
                     rootFile = rootFile.substr(1);
                 }
                 }
-            }
+            } 
 
 
             ASSIMP_LOG_VERBOSE_DEBUG(rootFile);
             ASSIMP_LOG_VERBOSE_DEBUG(rootFile);
 
 
@@ -158,9 +171,12 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
             if (nullptr == mRootStream) {
             if (nullptr == mRootStream) {
                 throw DeadlyImportError("Cannot open root-file in archive : " + rootFile);
                 throw DeadlyImportError("Cannot open root-file in archive : " + rootFile);
             }
             }
-
         } else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
         } else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
             ASSIMP_LOG_WARN("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file);
             ASSIMP_LOG_WARN("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file);
+        } else if (IsEmbeddedTexture(file)) {
+            IOStream *fileStream = mZipArchive->Open(file.c_str());
+            LoadEmbeddedTextures(fileStream, file);
+            mZipArchive->Close(fileStream);
         } else {
         } else {
             ASSIMP_LOG_WARN("Ignored file of unknown type: ", file);
             ASSIMP_LOG_WARN("Ignored file of unknown type: ", file);
         }
         }
@@ -169,20 +185,26 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
 
 
 D3MFOpcPackage::~D3MFOpcPackage() {
 D3MFOpcPackage::~D3MFOpcPackage() {
     mZipArchive->Close(mRootStream);
     mZipArchive->Close(mRootStream);
+    delete mZipArchive;
+    mZipArchive = nullptr;
 }
 }
 
 
 IOStream *D3MFOpcPackage::RootStream() const {
 IOStream *D3MFOpcPackage::RootStream() const {
     return mRootStream;
     return mRootStream;
 }
 }
 
 
-static const std::string ModelRef = "3D/3dmodel.model";
+const std::vector<aiTexture *> &D3MFOpcPackage::GetEmbeddedTextures() const {
+    return mEmbeddedTextures;
+}
+
+static const char *const ModelRef = "3D/3dmodel.model";
 
 
 bool D3MFOpcPackage::validate() {
 bool D3MFOpcPackage::validate() {
     if (nullptr == mRootStream || nullptr == mZipArchive) {
     if (nullptr == mRootStream || nullptr == mZipArchive) {
         return false;
         return false;
     }
     }
 
 
-    return mZipArchive->Exists(ModelRef.c_str());
+    return mZipArchive->Exists(ModelRef);
 }
 }
 
 
 std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
 std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
@@ -204,6 +226,31 @@ std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
     return (*itr)->target;
     return (*itr)->target;
 }
 }
 
 
+void D3MFOpcPackage::LoadEmbeddedTextures(IOStream *fileStream, const std::string &filename) {
+    if (nullptr == fileStream) {
+        return;
+    }
+
+    const size_t size = fileStream->FileSize();
+    if (0 == size) {
+        return;
+    }
+
+    unsigned char *data = new unsigned char[size];
+    fileStream->Read(data, 1, size);
+    aiTexture *texture = new aiTexture;
+    std::string embName = "*" + filename;
+    texture->mFilename.Set(embName.c_str());
+    texture->mWidth = static_cast<unsigned int>(size);
+    texture->mHeight = 0;
+    texture->achFormatHint[0] = 'p';
+    texture->achFormatHint[1] = 'n';
+    texture->achFormatHint[2] = 'g';
+    texture->achFormatHint[3] = '\0';
+    texture->pcData = (aiTexel*) data;
+    mEmbeddedTextures.emplace_back(texture);
+}
+
 } // Namespace D3MF
 } // Namespace D3MF
 } // Namespace Assimp
 } // Namespace Assimp
 
 

+ 10 - 4
code/AssetLib/3MF/D3MFOpcPackage.h

@@ -46,8 +46,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <string>
 #include <string>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 
 
+struct aiTexture;
+
 namespace Assimp {
 namespace Assimp {
-    class ZipArchiveIOSystem;
+
+class ZipArchiveIOSystem;
 
 
 namespace D3MF {
 namespace D3MF {
 
 
@@ -63,16 +66,19 @@ public:
     ~D3MFOpcPackage();
     ~D3MFOpcPackage();
     IOStream* RootStream() const;
     IOStream* RootStream() const;
     bool validate();
     bool validate();
+    const std::vector<aiTexture*> &GetEmbeddedTextures() const;
 
 
 protected:
 protected:
     std::string ReadPackageRootRelationship(IOStream* stream);
     std::string ReadPackageRootRelationship(IOStream* stream);
+    void LoadEmbeddedTextures(IOStream *fileStream, const std::string &filename);
 
 
 private:
 private:
     IOStream* mRootStream;
     IOStream* mRootStream;
-    std::unique_ptr<ZipArchiveIOSystem> mZipArchive;
+    ZipArchiveIOSystem *mZipArchive;
+    std::vector<aiTexture *> mEmbeddedTextures;
 };
 };
 
 
-} // Namespace D3MF
-} // Namespace Assimp
+} // namespace D3MF
+} // namespace Assimp
 
 
 #endif // D3MFOPCPACKAGE_H
 #endif // D3MFOPCPACKAGE_H

+ 594 - 0
code/AssetLib/3MF/XmlSerializer.cpp

@@ -0,0 +1,594 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2021, 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.
+
+----------------------------------------------------------------------
+*/
+#include "XmlSerializer.h"
+#include "D3MFOpcPackage.h"
+#include "3MFXmlTags.h"
+#include "3MFTypes.h"
+#include <assimp/scene.h>
+
+namespace Assimp {
+namespace D3MF {
+
+static const int IdNotSet = -1;
+
+namespace {
+
+static const size_t ColRGBA_Len = 9;
+static const size_t ColRGB_Len = 7;
+
+// format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
+bool validateColorString(const char *color) {
+    const size_t len = strlen(color);
+    if (ColRGBA_Len != len && ColRGB_Len != len) {
+        return false;
+    }
+
+    return true;
+}
+
+aiFace ReadTriangle(XmlNode &node) {
+    aiFace face;
+
+    face.mNumIndices = 3;
+    face.mIndices = new unsigned int[face.mNumIndices];
+    face.mIndices[0] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v1).as_string()));
+    face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
+    face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
+
+    return face;
+}
+
+aiVector3D ReadVertex(XmlNode &node) {
+    aiVector3D vertex;
+    vertex.x = ai_strtof(node.attribute(XmlTag::x).as_string(), nullptr);
+    vertex.y = ai_strtof(node.attribute(XmlTag::y).as_string(), nullptr);
+    vertex.z = ai_strtof(node.attribute(XmlTag::z).as_string(), nullptr);
+
+    return vertex;
+}
+
+bool getNodeAttribute(const XmlNode &node, const std::string &attribute, std::string &value) {
+    pugi::xml_attribute objectAttribute = node.attribute(attribute.c_str());
+    if (!objectAttribute.empty()) {
+        value = objectAttribute.as_string();
+        return true;
+    }
+
+    return false;
+}
+
+bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
+    std::string strValue;
+    const bool ret = getNodeAttribute(node, attribute, strValue);
+    if (ret) {
+        value = std::atoi(strValue.c_str());
+        return true;
+    }
+
+    return false;
+}
+
+aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
+    // split the string
+    std::vector<float> numbers;
+    std::string currentNumber;
+    for (char c : matrixStr) {
+        if (c == ' ') {
+            if (!currentNumber.empty()) {
+                float f = std::stof(currentNumber);
+                numbers.push_back(f);
+                currentNumber.clear();
+            }
+        } else {
+            currentNumber.push_back(c);
+        }
+    }
+    if (!currentNumber.empty()) {
+        const float f = std::stof(currentNumber);
+        numbers.push_back(f);
+    }
+
+    aiMatrix4x4 transformMatrix;
+    transformMatrix.a1 = numbers[0];
+    transformMatrix.b1 = numbers[1];
+    transformMatrix.c1 = numbers[2];
+    transformMatrix.d1 = 0;
+
+    transformMatrix.a2 = numbers[3];
+    transformMatrix.b2 = numbers[4];
+    transformMatrix.c2 = numbers[5];
+    transformMatrix.d2 = 0;
+
+    transformMatrix.a3 = numbers[6];
+    transformMatrix.b3 = numbers[7];
+    transformMatrix.c3 = numbers[8];
+    transformMatrix.d3 = 0;
+
+    transformMatrix.a4 = numbers[9];
+    transformMatrix.b4 = numbers[10];
+    transformMatrix.c4 = numbers[11];
+    transformMatrix.d4 = 1;
+
+    return transformMatrix;
+}
+
+bool parseColor(const char *color, aiColor4D &diffuse) {
+    if (nullptr == color) {
+        return false;
+    }
+
+    if (!validateColorString(color)) {
+        return false;
+    }
+
+    //const char *buf(color);
+    if ('#' != color[0]) {
+        return false;
+    }
+
+    char r[3] = { color[1], color[2], '\0' };
+    diffuse.r = static_cast<ai_real>(strtol(r, nullptr, 16)) / ai_real(255.0);
+
+    char g[3] = { color[3], color[4], '\0' };
+    diffuse.g = static_cast<ai_real>(strtol(g, nullptr, 16)) / ai_real(255.0);
+
+    char b[3] = { color[5], color[6], '\0' };
+    diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
+    const size_t len = strlen(color);
+    if (ColRGB_Len == len) {
+        return true;
+    }
+
+    char a[3] = { color[7], color[8], '\0' };
+    diffuse.a = static_cast<ai_real>(strtol(a, nullptr, 16)) / ai_real(255.0);
+
+    return true;
+}
+
+void assignDiffuseColor(XmlNode &node, aiMaterial *mat) {
+    const char *color = node.attribute(XmlTag::basematerials_displaycolor).as_string();
+    aiColor4D diffuse;
+    if (parseColor(color, diffuse)) {
+        mat->AddProperty<aiColor4D>(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
+    }
+}
+
+} // namespace
+
+XmlSerializer::XmlSerializer(XmlParser *xmlParser) :
+        mResourcesDictionnary(),
+        mMeshCount(0),
+        mXmlParser(xmlParser) {
+    ai_assert(nullptr != xmlParser);
+}
+
+XmlSerializer::~XmlSerializer() {
+    for (auto &it : mResourcesDictionnary) {
+        delete it.second;
+    }
+}
+
+void XmlSerializer::ImportXml(aiScene *scene) {
+    if (nullptr == scene) {
+        return;
+    }
+    
+    scene->mRootNode = new aiNode(XmlTag::RootTag);
+    XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
+    if (node.empty()) {
+        return;
+    }
+
+    XmlNode resNode = node.child(XmlTag::resources);
+    for (auto &currentNode : resNode.children()) {
+        const std::string currentNodeName = currentNode.name();
+        if (currentNodeName == XmlTag::texture_2d) {
+            ReadEmbeddecTexture(currentNode);
+        } else if (currentNodeName == XmlTag::texture_group) {
+            ReadTextureGroup(currentNode);
+        } else if (currentNodeName == XmlTag::object) {
+            ReadObject(currentNode);
+        } else if (currentNodeName == XmlTag::basematerials) {
+            ReadBaseMaterials(currentNode);
+        } else if (currentNodeName == XmlTag::meta) {
+            ReadMetadata(currentNode);
+        }
+    }
+    StoreMaterialsInScene(scene);
+    XmlNode buildNode = node.child(XmlTag::build);
+    if (buildNode.empty()) {
+        return;
+    }
+
+    for (auto &currentNode : buildNode.children()) {
+        const std::string currentNodeName = currentNode.name();
+        if (currentNodeName == XmlTag::item) {
+            int objectId = IdNotSet;
+            std::string transformationMatrixStr;
+            aiMatrix4x4 transformationMatrix;
+            getNodeAttribute(currentNode, D3MF::XmlTag::objectid, objectId);
+            bool hasTransform = getNodeAttribute(currentNode, D3MF::XmlTag::transform, transformationMatrixStr);
+
+            auto it = mResourcesDictionnary.find(objectId);
+            if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
+                Object *obj = static_cast<Object *>(it->second);
+                if (hasTransform) {
+                    transformationMatrix = parseTransformMatrix(transformationMatrixStr);
+                }
+
+                addObjectToNode(scene->mRootNode, obj, transformationMatrix);
+            }
+        }
+    }
+
+    // import the metadata
+    if (!mMetaData.empty()) {
+        const size_t numMeta = mMetaData.size();
+        scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(numMeta));
+        for (size_t i = 0; i < numMeta; ++i) {
+            aiString val(mMetaData[i].value);
+            scene->mMetaData->Set(static_cast<unsigned int>(i), mMetaData[i].name, val);
+        }
+    }
+
+    // import the meshes, materials are already stored
+    scene->mNumMeshes = static_cast<unsigned int>(mMeshCount);
+    if (scene->mNumMeshes != 0) {
+        scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
+        for (auto &it : mResourcesDictionnary) {
+            if (it.second->getType() == ResourceType::RT_Object) {
+                Object *obj = static_cast<Object *>(it.second);
+                ai_assert(nullptr != obj);
+                for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
+                    scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
+                }
+            }
+        }
+    }
+}
+
+void XmlSerializer::addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform) {
+    ai_assert(nullptr != obj);
+
+    aiNode *sceneNode = new aiNode(obj->mName);
+    sceneNode->mNumMeshes = static_cast<unsigned int>(obj->mMeshes.size());
+    sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes];
+    std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes);
+
+    sceneNode->mTransformation = nodeTransform;
+    if (nullptr != parent) {
+        parent->addChildren(1, &sceneNode);
+    }
+
+    for (Assimp::D3MF::Component c : obj->mComponents) {
+        auto it = mResourcesDictionnary.find(c.mObjectId);
+        if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
+            addObjectToNode(sceneNode, static_cast<Object *>(it->second), c.mTransformation);
+        }
+    }
+}
+
+void XmlSerializer::ReadObject(XmlNode &node) {
+    int id = IdNotSet, pid = IdNotSet, pindex = IdNotSet;
+    bool hasId = getNodeAttribute(node, XmlTag::id, id);
+    if (!hasId) {
+        return;
+    }
+
+    bool hasPid = getNodeAttribute(node, XmlTag::pid, pid);
+    bool hasPindex = getNodeAttribute(node, XmlTag::pindex, pindex);
+
+    Object *obj = new Object(id);
+    for (XmlNode &currentNode : node.children()) {
+        const std::string currentName = currentNode.name();
+        if (currentName == D3MF::XmlTag::mesh) {
+            auto mesh = ReadMesh(currentNode);
+            mesh->mName.Set(ai_to_string(id));
+
+            if (hasPid) {
+                auto it = mResourcesDictionnary.find(pid);
+                if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
+                    BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
+                    mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
+                }
+            }
+
+            obj->mMeshes.push_back(mesh);
+            obj->mMeshIndex.push_back(mMeshCount);
+            mMeshCount++;
+        } else if (currentName == D3MF::XmlTag::components) {
+            for (XmlNode &currentSubNode : currentNode.children()) {
+                const std::string subNodeName = currentSubNode.name();
+                if (subNodeName == D3MF::XmlTag::component) {
+                    int objectId = IdNotSet;
+                    std::string componentTransformStr;
+                    aiMatrix4x4 componentTransform;
+                    if (getNodeAttribute(currentSubNode, D3MF::XmlTag::transform, componentTransformStr)) {
+                        componentTransform = parseTransformMatrix(componentTransformStr);
+                    }
+
+                    if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) {
+                        obj->mComponents.push_back({ objectId, componentTransform });
+                    }
+                }
+            }
+        }
+    }
+
+    mResourcesDictionnary.insert(std::make_pair(id, obj));
+}
+
+aiMesh *XmlSerializer::ReadMesh(XmlNode &node) {
+    if (node.empty()) {
+        return nullptr;
+    }
+
+    aiMesh *mesh = new aiMesh();
+    for (XmlNode &currentNode : node.children()) {
+        const std::string currentName = currentNode.name();
+        if (currentName == XmlTag::vertices) {
+            ImportVertices(currentNode, mesh);
+        } else if (currentName == XmlTag::triangles) {
+            ImportTriangles(currentNode, mesh);
+        }
+    }
+
+    return mesh;
+}
+
+void XmlSerializer::ReadMetadata(XmlNode &node) {
+    pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name);
+    const std::string name = attribute.as_string();
+    const std::string value = node.value();
+    if (name.empty()) {
+        return;
+    }
+
+    MetaEntry entry;
+    entry.name = name;
+    entry.value = value;
+    mMetaData.push_back(entry);
+}
+
+void XmlSerializer::ImportVertices(XmlNode &node, aiMesh *mesh) {
+    ai_assert(nullptr != mesh);
+
+    std::vector<aiVector3D> vertices;
+    for (XmlNode &currentNode : node.children()) {
+        const std::string currentName = currentNode.name();
+        if (currentName == XmlTag::vertex) {
+            vertices.push_back(ReadVertex(currentNode));
+        }
+    }
+
+    mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
+    mesh->mVertices = new aiVector3D[mesh->mNumVertices];
+    std::copy(vertices.begin(), vertices.end(), mesh->mVertices);
+}
+
+void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
+    std::vector<aiFace> faces;
+    for (XmlNode &currentNode : node.children()) {
+        const std::string currentName = currentNode.name();
+        if (currentName == XmlTag::triangle) {
+            int pid = IdNotSet, p1 = IdNotSet;
+            bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
+            bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
+
+            if (hasPid && hasP1) {
+                auto it = mResourcesDictionnary.find(pid);
+                if (it != mResourcesDictionnary.end()) {
+                    if (it->second->getType() == ResourceType::RT_BaseMaterials) {
+                        BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
+                        mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
+                    } else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
+                        if (mesh->mTextureCoords[0] == nullptr) {
+                            Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second);
+                            const std::string name = ai_to_string(group->mTexId);
+                            for (size_t i = 0; i < mMaterials.size(); ++i) {
+                                if (name == mMaterials[i]->GetName().C_Str()) {
+                                    mesh->mMaterialIndex = static_cast<unsigned int>(i);
+                                }
+                            }
+                            mesh->mTextureCoords[0] = new aiVector3D[group->mTex2dCoords.size()];
+                            for (unsigned int i = 0; i < group->mTex2dCoords.size(); ++i) {
+                                mesh->mTextureCoords[0][i] = aiVector3D(group->mTex2dCoords[i].x, group->mTex2dCoords[i].y, 0);
+                            }
+                        }
+                    } 
+                }
+            }
+
+            aiFace face = ReadTriangle(currentNode);
+            faces.push_back(face);
+        }
+    }
+
+    mesh->mNumFaces = static_cast<unsigned int>(faces.size());
+    mesh->mFaces = new aiFace[mesh->mNumFaces];
+    mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
+
+    std::copy(faces.begin(), faces.end(), mesh->mFaces);
+}
+
+void XmlSerializer::ReadBaseMaterials(XmlNode &node) {
+    int id = IdNotSet;
+    if (getNodeAttribute(node, D3MF::XmlTag::id, id)) {
+        BaseMaterials *baseMaterials = new BaseMaterials(id);
+
+        for (XmlNode &currentNode : node.children()) {
+            const std::string currentName = currentNode.name();
+            if (currentName == XmlTag::basematerials_base) {
+                baseMaterials->mMaterialIndex.push_back(static_cast<unsigned int>(mMaterials.size()));
+                mMaterials.push_back(readMaterialDef(currentNode, id));
+            }
+        }
+
+        mResourcesDictionnary.insert(std::make_pair(id, baseMaterials));
+    }
+}
+
+void XmlSerializer::ReadEmbeddecTexture(XmlNode &node) {
+    if (node.empty()) {
+        return;
+    }
+
+    std::string value;
+    EmbeddedTexture *tex2D = nullptr;
+    if (XmlParser::getStdStrAttribute(node, XmlTag::id, value)) {
+        tex2D = new EmbeddedTexture(atoi(value.c_str()));
+    }
+    if (nullptr == tex2D) {
+        return;
+    }
+
+    if (XmlParser::getStdStrAttribute(node, XmlTag::path, value)) {
+        tex2D->mPath = value;
+    }
+    if (XmlParser::getStdStrAttribute(node, XmlTag::texture_content_type, value)) {
+        tex2D->mContentType = value;
+    }
+    if (XmlParser::getStdStrAttribute(node, XmlTag::texture_tilestyleu, value)) {
+        tex2D->mTilestyleU = value;
+    }
+    if (XmlParser::getStdStrAttribute(node, XmlTag::texture_tilestylev, value)) {
+        tex2D->mTilestyleV = value;
+    }
+    mEmbeddedTextures.emplace_back(tex2D);
+    StoreEmbeddedTexture(tex2D);
+}
+
+void XmlSerializer::StoreEmbeddedTexture(EmbeddedTexture *tex) {
+    aiMaterial *mat = new aiMaterial;
+    aiString s;
+    s.Set(ai_to_string(tex->mId).c_str());
+    mat->AddProperty(&s, AI_MATKEY_NAME);
+    const std::string name = "*" + tex->mPath;
+    s.Set(name);
+    mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
+
+    aiColor3D col;
+    mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_DIFFUSE);
+    mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_AMBIENT);
+    mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_EMISSIVE);
+    mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_SPECULAR);
+    mMaterials.emplace_back(mat);
+}
+
+void XmlSerializer::ReadTextureCoords2D(XmlNode &node, Texture2DGroup *tex2DGroup) {
+    if (node.empty() || nullptr == tex2DGroup) {
+        return;
+    }
+
+    int id = IdNotSet;
+    if (XmlParser::getIntAttribute(node, "texid", id)) {
+        tex2DGroup->mTexId = id;
+    }
+
+    double value = 0.0;
+    for (XmlNode currentNode : node.children()) {
+        const std::string currentName = currentNode.name();
+        aiVector2D texCoord;
+        if (currentName == XmlTag::texture_2d_coord) {
+            XmlParser::getDoubleAttribute(currentNode, XmlTag::texture_cuurd_u, value);
+            texCoord.x = (ai_real)value;
+            XmlParser::getDoubleAttribute(currentNode, XmlTag::texture_cuurd_v, value);
+            texCoord.y = (ai_real)value;
+            tex2DGroup->mTex2dCoords.push_back(texCoord);
+        }
+    }
+}
+
+void XmlSerializer::ReadTextureGroup(XmlNode &node) {
+    if (node.empty()) {
+        return;
+    }
+
+    int id = IdNotSet;
+    if (!XmlParser::getIntAttribute(node, XmlTag::id, id)) {
+        return;
+    }
+
+    Texture2DGroup *group = new Texture2DGroup(id);
+    ReadTextureCoords2D(node, group);
+    mResourcesDictionnary.insert(std::make_pair(id, group));
+}
+
+aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basematerialsId) {
+    aiMaterial *material = new aiMaterial();
+    material->mNumProperties = 0;
+    std::string name;
+    bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
+
+    std::string stdMaterialName;
+    const std::string strId(ai_to_string(basematerialsId));
+    stdMaterialName += "id";
+    stdMaterialName += strId;
+    stdMaterialName += "_";
+    if (hasName) {
+        stdMaterialName += std::string(name);
+    } else {
+        stdMaterialName += "basemat_";
+        stdMaterialName += ai_to_string(mMaterials.size());
+    }
+
+    aiString assimpMaterialName(stdMaterialName);
+    material->AddProperty(&assimpMaterialName, AI_MATKEY_NAME);
+
+    assignDiffuseColor(node, material);
+
+    return material;
+}
+
+void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
+    if (nullptr == scene || mMaterials.empty()) {
+        return;
+    }
+
+    scene->mNumMaterials = static_cast<unsigned int>(mMaterials.size());
+    scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
+    for (size_t i = 0; i < mMaterials.size(); ++i) {
+        scene->mMaterials[i] = mMaterials[i];
+    }
+}
+
+} // namespace D3MF
+} // namespace Assimp

+ 96 - 0
code/AssetLib/3MF/XmlSerializer.h

@@ -0,0 +1,96 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2021, 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.
+
+----------------------------------------------------------------------
+*/
+#pragma once
+
+#include <assimp/XmlParser.h>
+#include <assimp/mesh.h>
+#include <vector>
+#include <map>
+
+struct aiNode;
+struct aiMesh;
+struct aiMaterial;
+
+namespace Assimp {
+namespace D3MF {
+
+class Resource;
+class D3MFOpcPackage;
+class Object;
+class Texture2DGroup;
+class EmbeddedTexture;
+
+class XmlSerializer {
+public:
+    XmlSerializer(XmlParser *xmlParser);
+    ~XmlSerializer();
+    void ImportXml(aiScene *scene);
+
+private:
+    void addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform);
+    void ReadObject(XmlNode &node);
+    aiMesh *ReadMesh(XmlNode &node);
+    void ReadMetadata(XmlNode &node);
+    void ImportVertices(XmlNode &node, aiMesh *mesh);
+    void ImportTriangles(XmlNode &node, aiMesh *mesh);
+    void ReadBaseMaterials(XmlNode &node);
+    void ReadEmbeddecTexture(XmlNode &node);
+    void StoreEmbeddedTexture(EmbeddedTexture *tex);
+    void ReadTextureCoords2D(XmlNode &node, Texture2DGroup *tex2DGroup);
+    void ReadTextureGroup(XmlNode &node);
+    aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId);
+    void StoreMaterialsInScene(aiScene *scene);
+
+private:
+    struct MetaEntry {
+        std::string name;
+        std::string value;
+    };
+    std::vector<MetaEntry> mMetaData;
+    std::vector<EmbeddedTexture *> mEmbeddedTextures;
+    std::vector<aiMaterial *> mMaterials;
+    std::map<unsigned int, Resource *> mResourcesDictionnary;
+    unsigned int mMeshCount;
+    XmlParser *mXmlParser;
+};
+
+} // namespace D3MF
+} // namespace Assimp

+ 1 - 1
code/AssetLib/AMF/AMFImporter.cpp

@@ -303,7 +303,7 @@ void AMFImporter::ParseNode_Root() {
     }
     }
     XmlNode node = *root;
     XmlNode node = *root;
     mUnit = ai_tolower(std::string(node.attribute("unit").as_string()));
     mUnit = ai_tolower(std::string(node.attribute("unit").as_string()));
-    
+
     mVersion = node.attribute("version").as_string();
     mVersion = node.attribute("version").as_string();
 
 
     // Read attributes for node <amf>.
     // Read attributes for node <amf>.

+ 3 - 3
code/AssetLib/AMF/AMFImporter_Geometry.cpp

@@ -75,7 +75,7 @@ void AMFImporter::ParseNode_Mesh(XmlNode &node) {
             found_volumes = true;
             found_volumes = true;
         }
         }
         ParseHelper_Node_Exit();
         ParseHelper_Node_Exit();
-    } 
+    }
 
 
     if (!found_verts && !found_volumes) {
     if (!found_verts && !found_volumes) {
         mNodeElement_Cur->Child.push_back(ne);
         mNodeElement_Cur->Child.push_back(ne);
@@ -199,9 +199,9 @@ void AMFImporter::ParseNode_Volume(XmlNode &node) {
 
 
     // Read attributes for node <color>.
     // Read attributes for node <color>.
     // and assign read data
     // and assign read data
-   
+
     ((AMFVolume *)ne)->MaterialID = node.attribute("materialid").as_string();
     ((AMFVolume *)ne)->MaterialID = node.attribute("materialid").as_string();
-     
+
     ((AMFVolume *)ne)->Type = type;
     ((AMFVolume *)ne)->Type = type;
     // Check for child nodes
     // Check for child nodes
     bool col_read = false;
     bool col_read = false;

+ 3 - 3
code/AssetLib/AMF/AMFImporter_Postprocess.cpp

@@ -69,7 +69,7 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
     }
     }
 
 
     tcol = Color->Color;
     tcol = Color->Color;
-    
+
     // Check if default color must be used
     // Check if default color must be used
     if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) {
     if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) {
         tcol.r = 0.5f;
         tcol.r = 0.5f;
@@ -99,10 +99,10 @@ void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &nodeEleme
     }
     }
 
 
     // all coordinates stored as child and we need to reserve space for future push_back's.
     // all coordinates stored as child and we need to reserve space for future push_back's.
-    vertexCoordinateArray.reserve(vn->Child.size()); 
+    vertexCoordinateArray.reserve(vn->Child.size());
 
 
     // colors count equal vertices count.
     // colors count equal vertices count.
-    pVertexColorArray.resize(vn->Child.size()); 
+    pVertexColorArray.resize(vn->Child.size());
     col_idx = 0;
     col_idx = 0;
 
 
     // Inside vertices collect all data and place to arrays
     // Inside vertices collect all data and place to arrays

+ 4 - 4
code/AssetLib/ASE/ASEParser.h

@@ -95,8 +95,8 @@ struct Material : public D3DS::Material {
     Material(Material &&other) AI_NO_EXCEPT
     Material(Material &&other) AI_NO_EXCEPT
             : D3DS::Material(std::move(other)),
             : D3DS::Material(std::move(other)),
               avSubMaterials(std::move(other.avSubMaterials)),
               avSubMaterials(std::move(other.avSubMaterials)),
-              pcInstance(std::move(other.pcInstance)),
-              bNeed(std::move(other.bNeed)) {
+              pcInstance(other.pcInstance),
+              bNeed(other.bNeed) {
         other.pcInstance = nullptr;
         other.pcInstance = nullptr;
     }
     }
 
 
@@ -108,8 +108,8 @@ struct Material : public D3DS::Material {
         //D3DS::Material::operator=(std::move(other));
         //D3DS::Material::operator=(std::move(other));
 
 
         avSubMaterials = std::move(other.avSubMaterials);
         avSubMaterials = std::move(other.avSubMaterials);
-        pcInstance = std::move(other.pcInstance);
-        bNeed = std::move(other.bNeed);
+        pcInstance = other.pcInstance;
+        bNeed = other.bNeed;
 
 
         other.pcInstance = nullptr;
         other.pcInstance = nullptr;
 
 

+ 1 - 1
code/AssetLib/Assbin/AssbinFileWriter.cpp

@@ -172,7 +172,7 @@ inline size_t Write<aiQuaternion>(IOStream *stream, const aiQuaternion &v) {
     t += Write<float>(stream, v.z);
     t += Write<float>(stream, v.z);
     ai_assert(t == 16);
     ai_assert(t == 16);
 
 
-    return 16;
+    return t;
 }
 }
 
 
 // -----------------------------------------------------------------------------------
 // -----------------------------------------------------------------------------------

+ 27 - 15
code/AssetLib/Assjson/json_exporter.cpp

@@ -41,12 +41,17 @@ public:
     enum {
     enum {
         Flag_DoNotIndent = 0x1,
         Flag_DoNotIndent = 0x1,
         Flag_WriteSpecialFloats = 0x2,
         Flag_WriteSpecialFloats = 0x2,
+        Flag_SkipWhitespaces = 0x4
     };
     };
-
+    
     JSONWriter(Assimp::IOStream &out, unsigned int flags = 0u) :
     JSONWriter(Assimp::IOStream &out, unsigned int flags = 0u) :
-            out(out), first(), flags(flags) {
+            out(out), indent (""), newline("\n"), space(" "), buff (), first(false), flags(flags) {
         // 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
         buff.imbue(std::locale("C"));
         buff.imbue(std::locale("C"));
+        if (flags & Flag_SkipWhitespaces) {
+            newline = "";
+            space = "";
+        }
     }
     }
 
 
     ~JSONWriter() {
     ~JSONWriter() {
@@ -70,7 +75,7 @@ public:
     void Key(const std::string &name) {
     void Key(const std::string &name) {
         AddIndentation();
         AddIndentation();
         Delimit();
         Delimit();
-        buff << '\"' + name + "\": ";
+        buff << '\"' + name + "\":" << space;
     }
     }
 
 
     template <typename Literal>
     template <typename Literal>
@@ -78,12 +83,12 @@ public:
         AddIndentation();
         AddIndentation();
         Delimit();
         Delimit();
 
 
-        LiteralToString(buff, name) << '\n';
+        LiteralToString(buff, name) << newline;
     }
     }
 
 
     template <typename Literal>
     template <typename Literal>
     void SimpleValue(const Literal &s) {
     void SimpleValue(const Literal &s) {
-        LiteralToString(buff, s) << '\n';
+        LiteralToString(buff, s) << newline;
     }
     }
 
 
     void SimpleValue(const void *buffer, size_t len) {
     void SimpleValue(const void *buffer, size_t len) {
@@ -102,7 +107,7 @@ public:
             }
             }
         }
         }
 
 
-        buff << '\"' << cur_out << "\"\n";
+        buff << '\"' << cur_out << "\"" << newline;
         delete[] cur_out;
         delete[] cur_out;
     }
     }
 
 
@@ -115,7 +120,7 @@ public:
             }
             }
         }
         }
         first = true;
         first = true;
-        buff << "{\n";
+        buff << "{" << newline;
         PushIndent();
         PushIndent();
     }
     }
 
 
@@ -123,7 +128,7 @@ public:
         PopIndent();
         PopIndent();
         AddIndentation();
         AddIndentation();
         first = false;
         first = false;
-        buff << "}\n";
+        buff << "}" << newline;
     }
     }
 
 
     void StartArray(bool is_element = false) {
     void StartArray(bool is_element = false) {
@@ -135,19 +140,19 @@ public:
             }
             }
         }
         }
         first = true;
         first = true;
-        buff << "[\n";
+        buff << "[" << newline;
         PushIndent();
         PushIndent();
     }
     }
 
 
     void EndArray() {
     void EndArray() {
         PopIndent();
         PopIndent();
         AddIndentation();
         AddIndentation();
-        buff << "]\n";
+        buff << "]" << newline;
         first = false;
         first = false;
     }
     }
 
 
     void AddIndentation() {
     void AddIndentation() {
-        if (!(flags & Flag_DoNotIndent)) {
+        if (!(flags & Flag_DoNotIndent) && !(flags & Flag_SkipWhitespaces)) {
             buff << indent;
             buff << indent;
         }
         }
     }
     }
@@ -156,7 +161,7 @@ public:
         if (!first) {
         if (!first) {
             buff << ',';
             buff << ',';
         } else {
         } else {
-            buff << ' ';
+            buff << space;
             first = false;
             first = false;
         }
         }
     }
     }
@@ -227,7 +232,9 @@ private:
 
 
 private:
 private:
     Assimp::IOStream &out;
     Assimp::IOStream &out;
-    std::string indent, newline;
+    std::string indent;
+    std::string newline;
+    std::string space;
     std::stringstream buff;
     std::stringstream buff;
     bool first;
     bool first;
 
 
@@ -765,7 +772,7 @@ void Write(JSONWriter &out, const aiScene &ai) {
     out.EndObj();
     out.EndObj();
 }
 }
 
 
-void ExportAssimp2Json(const char *file, Assimp::IOSystem *io, const aiScene *scene, const Assimp::ExportProperties *) {
+void ExportAssimp2Json(const char *file, Assimp::IOSystem *io, const aiScene *scene, const Assimp::ExportProperties *pProperties) {
     std::unique_ptr<Assimp::IOStream> str(io->Open(file, "wt"));
     std::unique_ptr<Assimp::IOStream> str(io->Open(file, "wt"));
     if (!str) {
     if (!str) {
         throw DeadlyExportError("could not open output file");
         throw DeadlyExportError("could not open output file");
@@ -782,7 +789,12 @@ void ExportAssimp2Json(const char *file, Assimp::IOSystem *io, const aiScene *sc
         splitter.Execute(scenecopy_tmp);
         splitter.Execute(scenecopy_tmp);
 
 
         // XXX Flag_WriteSpecialFloats is turned on by default, right now we don't have a configuration interface for exporters
         // 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);
+
+        unsigned int flags = JSONWriter::Flag_WriteSpecialFloats;
+        if (pProperties->GetPropertyBool("JSON_SKIP_WHITESPACES", false)) {
+            flags |= JSONWriter::Flag_SkipWhitespaces;
+        }
+        JSONWriter s(*str, flags);
         Write(s, *scenecopy_tmp);
         Write(s, *scenecopy_tmp);
 
 
     } catch (...) {
     } catch (...) {

+ 4 - 4
code/AssetLib/Assjson/mesh_splitter.cpp

@@ -110,7 +110,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
 	// we need to split this mesh into sub meshes. Estimate submesh size
 	// we need to split this mesh into sub meshes. Estimate submesh size
 	const unsigned int sub_meshes = (in_mesh->mNumVertices / LIMIT) + 1;
 	const unsigned int sub_meshes = (in_mesh->mNumVertices / LIMIT) + 1;
 
 
-	// create a std::vector<unsigned int> to remember which vertices have already 
+	// create a std::vector<unsigned int> to remember which vertices have already
 	// been copied and to which position (i.e. output index)
 	// been copied and to which position (i.e. output index)
 	std::vector<unsigned int> was_copied_to;
 	std::vector<unsigned int> was_copied_to;
 	was_copied_to.resize(in_mesh->mNumVertices,WAS_NOT_COPIED);
 	was_copied_to.resize(in_mesh->mNumVertices,WAS_NOT_COPIED);
@@ -125,7 +125,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
 	while (true) {
 	while (true) {
 		const unsigned int out_vertex_index = LIMIT;
 		const unsigned int out_vertex_index = LIMIT;
 
 
-		aiMesh* out_mesh = new aiMesh();			
+		aiMesh* out_mesh = new aiMesh();
 		out_mesh->mNumVertices = 0;
 		out_mesh->mNumVertices = 0;
 		out_mesh->mMaterialIndex = in_mesh->mMaterialIndex;
 		out_mesh->mMaterialIndex = in_mesh->mMaterialIndex;
 
 
@@ -179,7 +179,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
 
 
 				// check whether we do already have this vertex
 				// check whether we do already have this vertex
 				if (WAS_NOT_COPIED == was_copied_to[index])	{
 				if (WAS_NOT_COPIED == was_copied_to[index])	{
-					iNeed++; 
+					iNeed++;
 				}
 				}
 			}
 			}
 			if (out_mesh->mNumVertices + iNeed > out_vertex_index)	{
 			if (out_mesh->mNumVertices + iNeed > out_vertex_index)	{
@@ -240,7 +240,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
 						out_mesh->mTextureCoords[c][out_mesh->mNumVertices] = in_mesh->mTextureCoords[c][index];
 						out_mesh->mTextureCoords[c][out_mesh->mNumVertices] = in_mesh->mTextureCoords[c][index];
 					}
 					}
 				}
 				}
-				// vertex colors 
+				// vertex colors
 				for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) {
 				for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) {
 					if (in_mesh->HasVertexColors( c)) {
 					if (in_mesh->HasVertexColors( c)) {
 						out_mesh->mColors[c][out_mesh->mNumVertices] = in_mesh->mColors[c][index];
 						out_mesh->mColors[c][out_mesh->mNumVertices] = in_mesh->mColors[c][index];

+ 3 - 3
code/AssetLib/Assjson/mesh_splitter.h

@@ -22,13 +22,13 @@ struct aiNode;
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Splits meshes of unique vertices into meshes with no more vertices than
 /** Splits meshes of unique vertices into meshes with no more vertices than
- *  a given, configurable threshold value. 
+ *  a given, configurable threshold value.
  */
  */
-class MeshSplitter 
+class MeshSplitter
 {
 {
 
 
 public:
 public:
-	
+
 	void SetLimit(unsigned int l) {
 	void SetLimit(unsigned int l) {
 		LIMIT = l;
 		LIMIT = l;
 	}
 	}

+ 1 - 1
code/AssetLib/Assxml/AssxmlExporter.cpp

@@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/Exporter.hpp>
 #include <assimp/Exporter.hpp>
 
 
-namespace Assimp   { 
+namespace Assimp   {
 
 
 void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
 void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
 {
 {

+ 1 - 1
code/AssetLib/B3D/B3DImporter.cpp

@@ -143,7 +143,7 @@ AI_WONT_RETURN void B3DImporter::Oops() {
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-AI_WONT_RETURN void B3DImporter::Fail(string str) {
+AI_WONT_RETURN void B3DImporter::Fail(const string &str) {
 #ifdef DEBUG_B3D
 #ifdef DEBUG_B3D
     ASSIMP_LOG_ERROR("Error in B3D file data: ", str);
     ASSIMP_LOG_ERROR("Error in B3D file data: ", str);
 #endif
 #endif

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

@@ -96,7 +96,7 @@ private:
     };
     };
 
 
     AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
     AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
-    AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
+    AI_WONT_RETURN void Fail(const std::string &str) AI_WONT_RETURN_SUFFIX;
 
 
     void ReadTEXS();
     void ReadTEXS();
     void ReadBRUS();
     void ReadBRUS();

+ 1 - 1
code/AssetLib/Blender/BlenderLoader.cpp

@@ -679,7 +679,7 @@ void BlenderImporter::BuildMaterials(ConversionData &conv_data) {
 
 
     BuildDefaultMaterial(conv_data);
     BuildDefaultMaterial(conv_data);
 
 
-    for (std::shared_ptr<Material> mat : conv_data.materials_raw) {
+    for (const std::shared_ptr<Material> &mat : conv_data.materials_raw) {
 
 
         // reset per material global counters
         // reset per material global counters
         for (size_t i = 0; i < sizeof(conv_data.next_texture) / sizeof(conv_data.next_texture[0]); ++i) {
         for (size_t i = 0; i < sizeof(conv_data.next_texture) / sizeof(conv_data.next_texture[0]); ++i) {

+ 9 - 9
code/AssetLib/Blender/BlenderModifier.h

@@ -52,9 +52,9 @@ namespace Assimp {
 namespace Blender {
 namespace Blender {
 
 
 // -------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------
-/** 
+/**
  *  Dummy base class for all blender modifiers. Modifiers are reused between imports, so
  *  Dummy base class for all blender modifiers. Modifiers are reused between imports, so
- *  they should be stateless and not try to cache model data. 
+ *  they should be stateless and not try to cache model data.
  */
  */
 // -------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------
 class BlenderModifier {
 class BlenderModifier {
@@ -67,7 +67,7 @@ public:
     }
     }
 
 
     // --------------------
     // --------------------
-    /** 
+    /**
      *  Check if *this* modifier is active, given a ModifierData& block.
      *  Check if *this* modifier is active, given a ModifierData& block.
      */
      */
     virtual bool IsActive( const ModifierData& /*modin*/) {
     virtual bool IsActive( const ModifierData& /*modin*/) {
@@ -75,10 +75,10 @@ public:
     }
     }
 
 
     // --------------------
     // --------------------
-    /** 
+    /**
      *  Apply the modifier to a given output node. The original data used
      *  Apply the modifier to a given output node. The original data used
      *  to construct the node is given as well. Not called unless IsActive()
      *  to construct the node is given as well. Not called unless IsActive()
-     *  was called and gave positive response. 
+     *  was called and gave positive response.
      */
      */
     virtual void DoIt(aiNode& /*out*/,
     virtual void DoIt(aiNode& /*out*/,
         ConversionData& /*conv_data*/,
         ConversionData& /*conv_data*/,
@@ -92,8 +92,8 @@ public:
 };
 };
 
 
 // -------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------
-/** 
- *  Manage all known modifiers and instance and apply them if necessary 
+/**
+ *  Manage all known modifiers and instance and apply them if necessary
  */
  */
 // -------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------
 class BlenderModifierShowcase {
 class BlenderModifierShowcase {
@@ -113,8 +113,8 @@ private:
 // MODIFIERS /////////////////////////////////////////////////////////////////////////////////
 // MODIFIERS /////////////////////////////////////////////////////////////////////////////////
 
 
 // -------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------
-/** 
- *  Mirror modifier. Status: implemented. 
+/**
+ *  Mirror modifier. Status: implemented.
  */
  */
 // -------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------
 class BlenderModifier_Mirror : public BlenderModifier {
 class BlenderModifier_Mirror : public BlenderModifier {

+ 6 - 0
code/AssetLib/C4D/C4DImporter.cpp

@@ -146,8 +146,14 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
         ThrowException("failed to read document " + pFile);
         ThrowException("failed to read document " + pFile);
     }
     }
 
 
+    // Generate the root-node
     pScene->mRootNode = new aiNode("<C4DRoot>");
     pScene->mRootNode = new aiNode("<C4DRoot>");
 
 
+    // convert left-handed to right-handed
+    pScene->mRootNode->mTransformation.a1 = 0.01f;
+    pScene->mRootNode->mTransformation.b2 = 0.01f;
+    pScene->mRootNode->mTransformation.c3 = -0.01f;
+
     // first convert all materials
     // first convert all materials
     ReadMaterials(doc->GetFirstMaterial());
     ReadMaterials(doc->GetFirstMaterial());
 
 

+ 2 - 2
code/AssetLib/COB/COBLoader.cpp

@@ -230,7 +230,7 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void ConvertTexture(std::shared_ptr<Texture> tex, aiMaterial *out, aiTextureType type) {
+void ConvertTexture(const std::shared_ptr<Texture> &tex, aiMaterial *out, aiTextureType type) {
     const aiString path(tex->path);
     const aiString path(tex->path);
     out->AddProperty(&path, AI_MATKEY_TEXTURE(type, 0));
     out->AddProperty(&path, AI_MATKEY_TEXTURE(type, 0));
     out->AddProperty(&tex->transform, 1, AI_MATKEY_UVTRANSFORM(type, 0));
     out->AddProperty(&tex->transform, 1, AI_MATKEY_UVTRANSFORM(type, 0));
@@ -884,7 +884,7 @@ void COBImporter::ReadBinaryFile(Scene &out, StreamReaderLE *reader) {
         std::string type;
         std::string type;
         type += reader->GetI1();
         type += reader->GetI1();
         type += reader->GetI1();
         type += reader->GetI1();
-        type += reader->GetI1(); 
+        type += reader->GetI1();
         type += reader->GetI1();
         type += reader->GetI1();
 
 
         ChunkInfo nfo;
         ChunkInfo nfo;

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

@@ -77,7 +77,7 @@ class COBImporter : public BaseImporter
 public:
 public:
     COBImporter();
     COBImporter();
     ~COBImporter();
     ~COBImporter();
-    
+
     // --------------------
     // --------------------
     bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
     bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
         bool checkSig) const;
         bool checkSig) const;

+ 15 - 10
code/AssetLib/Collada/ColladaLoader.cpp

@@ -135,14 +135,15 @@ bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool
 
 
     // XML - too generic, we need to open the file and search for typical keywords
     // XML - too generic, we need to open the file and search for typical keywords
     if (extension == "xml" || !extension.length() || checkSig) {
     if (extension == "xml" || !extension.length() || checkSig) {
-        /*  If CanRead() is called in order to check whether we
-         *  support a specific file extension in general pIOHandler
-         *  might be nullptr and it's our duty to return true here.
-         */
-        if (!pIOHandler) {
+        //  If CanRead() is called in order to check whether we
+        //  support a specific file extension in general pIOHandler
+        //  might be nullptr and it's our duty to return true here.
+        if (nullptr == pIOHandler) {
             return true;
             return true;
         }
         }
-        static const char *tokens[] = { "<collada" };
+        static const char* tokens[] = {
+            "<collada"
+        };
         return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
         return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
     }
     }
 
 
@@ -573,7 +574,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
 
 
     // now place all mesh references we gathered in the target node
     // now place all mesh references we gathered in the target node
     pTarget->mNumMeshes = static_cast<unsigned int>(newMeshRefs.size());
     pTarget->mNumMeshes = static_cast<unsigned int>(newMeshRefs.size());
-    if (newMeshRefs.size()) {
+    if (!newMeshRefs.empty()) {
         struct UIntTypeConverter {
         struct UIntTypeConverter {
             unsigned int operator()(const size_t &v) const {
             unsigned int operator()(const size_t &v) const {
                 return static_cast<unsigned int>(v);
                 return static_cast<unsigned int>(v);
@@ -619,6 +620,10 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
         dstMesh->mName = pSrcMesh->mId;
         dstMesh->mName = pSrcMesh->mId;
     }
     }
 
 
+    if (pSrcMesh->mPositions.empty()) {
+        return dstMesh.release();
+    }
+
     // count the vertices addressed by its faces
     // count the vertices addressed by its faces
     const size_t numVertices = std::accumulate(pSrcMesh->mFaceSize.begin() + pStartFace,
     const size_t numVertices = std::accumulate(pSrcMesh->mFaceSize.begin() + pStartFace,
             pSrcMesh->mFaceSize.begin() + pStartFace + pSubMesh.mNumFaces, size_t(0));
             pSrcMesh->mFaceSize.begin() + pStartFace + pSubMesh.mNumFaces, size_t(0));
@@ -1540,7 +1545,7 @@ void ColladaLoader::AddTexture(aiMaterial &mat,
         map = -1;
         map = -1;
         for (std::string::const_iterator it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
         for (std::string::const_iterator it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
             if (IsNumeric(*it)) {
             if (IsNumeric(*it)) {
-                map = strtoul10(&(*it));
+                map = strtoul10(&(*it));        
                 break;
                 break;
             }
             }
         }
         }
@@ -1671,7 +1676,7 @@ void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/)
         const Material &material = matIt->second;
         const Material &material = matIt->second;
         // a material is only a reference to an effect
         // a material is only a reference to an effect
         ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find(material.mEffect);
         ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find(material.mEffect);
-        if (effIt == pParser.mEffectLibrary.end())  
+        if (effIt == pParser.mEffectLibrary.end())
             continue;
             continue;
         Effect &effect = effIt->second;
         Effect &effect = effIt->second;
 
 
@@ -1682,7 +1687,7 @@ void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/)
 
 
         // store the material
         // store the material
         mMaterialIndexByName[matIt->first] = newMats.size();
         mMaterialIndexByName[matIt->first] = newMats.size();
-        newMats.push_back(std::pair<Effect *, aiMaterial *>(&effect, mat));
+        newMats.emplace_back(&effect, mat);
     }
     }
     // ScenePreprocessor generates a default material automatically if none is there.
     // ScenePreprocessor generates a default material automatically if none is there.
     // All further code here in this loader works well without a valid material so
     // All further code here in this loader works well without a valid material so

+ 114 - 125
code/AssetLib/Collada/ColladaParser.cpp

@@ -170,10 +170,10 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
 ColladaParser::~ColladaParser() {
 ColladaParser::~ColladaParser() {
-    for (auto & it : mNodeLibrary) {
+    for (auto &it : mNodeLibrary) {
         delete it.second;
         delete it.second;
     }
     }
-    for (auto & it : mMeshLibrary) {
+    for (auto &it : mMeshLibrary) {
         delete it.second;
         delete it.second;
     }
     }
 }
 }
@@ -231,11 +231,7 @@ void ColladaParser::UriDecodePath(aiString &ss) {
 
 
     // Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
     // Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
     // I need to filter it without destroying linux paths starting with "/somewhere"
     // I need to filter it without destroying linux paths starting with "/somewhere"
-#if defined(_MSC_VER)
     if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
     if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
-#else
-    if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
-#endif
         --ss.length;
         --ss.length;
         ::memmove(ss.data, ss.data + 1, ss.length);
         ::memmove(ss.data, ss.data + 1, ss.length);
         ss.data[ss.length] = 0;
         ss.data[ss.length] = 0;
@@ -396,7 +392,7 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
 
 
     std::string animName;
     std::string animName;
     if (!XmlParser::getStdStrAttribute(node, "name", animName)) {
     if (!XmlParser::getStdStrAttribute(node, "name", animName)) {
-        if (!XmlParser::getStdStrAttribute( node, "id", animName )) {
+        if (!XmlParser::getStdStrAttribute(node, "id", animName)) {
             animName = std::string("animation_") + ai_to_string(mAnimationClipLibrary.size());
             animName = std::string("animation_") + ai_to_string(mAnimationClipLibrary.size());
         }
         }
     }
     }
@@ -420,7 +416,7 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
 
 
 void ColladaParser::PostProcessControllers() {
 void ColladaParser::PostProcessControllers() {
     std::string meshId;
     std::string meshId;
-    for (auto & it : mControllerLibrary) {
+    for (auto &it : mControllerLibrary) {
         meshId = it.second.mMeshId;
         meshId = it.second.mMeshId;
         if (meshId.empty()) {
         if (meshId.empty()) {
             continue;
             continue;
@@ -445,7 +441,7 @@ void ColladaParser::PostProcessRootAnimations() {
     }
     }
 
 
     Animation temp;
     Animation temp;
-    for (auto & it : mAnimationClipLibrary) {
+    for (auto &it : mAnimationClipLibrary) {
         std::string clipName = it.first;
         std::string clipName = it.first;
 
 
         Animation *clip = new Animation();
         Animation *clip = new Animation();
@@ -453,7 +449,7 @@ void ColladaParser::PostProcessRootAnimations() {
 
 
         temp.mSubAnims.push_back(clip);
         temp.mSubAnims.push_back(clip);
 
 
-        for (std::string animationID : it.second) {
+        for (const std::string &animationID : it.second) {
             AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
             AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
 
 
             if (animation != mAnimationLibrary.end()) {
             if (animation != mAnimationLibrary.end()) {
@@ -529,7 +525,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
                 // have it read into a channel
                 // have it read into a channel
                 ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
                 ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
                 ReadAnimationSampler(currentNode, newChannel->second);
                 ReadAnimationSampler(currentNode, newChannel->second);
-            } 
+            }
         } else if (currentName == "channel") {
         } else if (currentName == "channel") {
             std::string source_name, target;
             std::string source_name, target;
             XmlParser::getStdStrAttribute(currentNode, "source", source_name);
             XmlParser::getStdStrAttribute(currentNode, "source", source_name);
@@ -552,7 +548,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
             pParent->mSubAnims.push_back(anim);
             pParent->mSubAnims.push_back(anim);
         }
         }
 
 
-        for (const auto & channel : channels) {
+        for (const auto &channel : channels) {
             anim->mChannels.push_back(channel.second);
             anim->mChannels.push_back(channel.second);
         }
         }
 
 
@@ -626,8 +622,6 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
     XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
     XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
     XmlNode currentNode;
     XmlNode currentNode;
     while (xmlIt.getNext(currentNode)) {
     while (xmlIt.getNext(currentNode)) {
-
-    //for (XmlNode &currentNode : node.children()) {
         const std::string &currentName = currentNode.name();
         const std::string &currentName = currentNode.name();
         if (currentName == "morph") {
         if (currentName == "morph") {
             controller.mType = Morph;
             controller.mType = Morph;
@@ -644,7 +638,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
         } else if (currentName == "skin") {
         } else if (currentName == "skin") {
             std::string id;
             std::string id;
             if (XmlParser::getStdStrAttribute(currentNode, "source", id)) {
             if (XmlParser::getStdStrAttribute(currentNode, "source", id)) {
-                controller.mMeshId = id.substr(1, id.size()-1);
+                controller.mMeshId = id.substr(1, id.size() - 1);
             }
             }
         } else if (currentName == "bind_shape_matrix") {
         } else if (currentName == "bind_shape_matrix") {
             std::string v;
             std::string v;
@@ -698,7 +692,7 @@ void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pCo
             } else if (strcmp(attrSemantic, "INV_BIND_MATRIX") == 0) {
             } else if (strcmp(attrSemantic, "INV_BIND_MATRIX") == 0) {
                 pController.mJointOffsetMatrixSource = attrSource;
                 pController.mJointOffsetMatrixSource = attrSource;
             } else {
             } else {
-                throw DeadlyImportError("Unknown semantic \"" , attrSemantic , "\" in <joints> data <input> element");
+                throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <joints> data <input> element");
             }
             }
         }
         }
     }
     }
@@ -708,7 +702,7 @@ void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pCo
 // Reads the joint weights for the given controller
 // Reads the joint weights for the given controller
 void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pController) {
 void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pController) {
     // Read vertex count from attributes and resize the array accordingly
     // Read vertex count from attributes and resize the array accordingly
-    int vertexCount=0;
+    int vertexCount = 0;
     XmlParser::getIntAttribute(node, "count", vertexCount);
     XmlParser::getIntAttribute(node, "count", vertexCount);
     pController.mWeightCounts.resize(vertexCount);
     pController.mWeightCounts.resize(vertexCount);
 
 
@@ -723,7 +717,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
 
 
             // local URLS always start with a '#'. We don't support global URLs
             // local URLS always start with a '#'. We don't support global URLs
             if (attrSource[0] != '#') {
             if (attrSource[0] != '#') {
-                throw DeadlyImportError( "Unsupported URL format in \"", attrSource, "\" in source attribute of <vertex_weights> data <input> element");
+                throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of <vertex_weights> data <input> element");
             }
             }
             channel.mAccessor = attrSource + 1;
             channel.mAccessor = attrSource + 1;
 
 
@@ -777,7 +771,7 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) {
         const std::string &currentName = currentNode.name();
         const std::string &currentName = currentNode.name();
         if (currentName == "image") {
         if (currentName == "image") {
             std::string id;
             std::string id;
-            if (XmlParser::getStdStrAttribute( currentNode, "id", id )) {
+            if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
                 mImageLibrary[id] = Image();
                 mImageLibrary[id] = Image();
                 // read on from there
                 // read on from there
                 ReadImage(currentNode, mImageLibrary[id]);
                 ReadImage(currentNode, mImageLibrary[id]);
@@ -907,7 +901,7 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) {
             if (!name.empty()) {
             if (!name.empty()) {
                 cam.mName = name;
                 cam.mName = name;
             }
             }
-            ReadCamera(currentNode, cam);            
+            ReadCamera(currentNode, cam);
         }
         }
     }
     }
 }
 }
@@ -920,7 +914,7 @@ void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
         if (currentName == "instance_effect") {
         if (currentName == "instance_effect") {
             std::string url;
             std::string url;
             readUrlAttribute(currentNode, url);
             readUrlAttribute(currentNode, url);
-            pMaterial.mEffect = url.c_str();
+            pMaterial.mEffect = url;
         }
         }
     }
     }
 }
 }
@@ -1361,8 +1355,8 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) {
         } else if (currentName == "vertices") {
         } else if (currentName == "vertices") {
             ReadVertexData(currentNode, pMesh);
             ReadVertexData(currentNode, pMesh);
         } else if (currentName == "triangles" || currentName == "lines" || currentName == "linestrips" ||
         } else if (currentName == "triangles" || currentName == "lines" || currentName == "linestrips" ||
-                currentName == "polygons" || currentName == "polylist" || currentName == "trifans" ||
-                currentName == "tristrips") {
+                   currentName == "polygons" || currentName == "polylist" || currentName == "trifans" ||
+                   currentName == "tristrips") {
             ReadIndexData(currentNode, pMesh);
             ReadIndexData(currentNode, pMesh);
         }
         }
     }
     }
@@ -1439,9 +1433,8 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
                     throw DeadlyImportError("Expected more values while reading float_array contents.");
                     throw DeadlyImportError("Expected more values while reading float_array contents.");
                 }
                 }
 
 
-                ai_real value;
                 // read a number
                 // read a number
-                //SkipSpacesAndLineEnd(&content);
+                ai_real value;
                 content = fast_atoreal_move<ai_real>(content, value);
                 content = fast_atoreal_move<ai_real>(content, value);
                 data.mValues.push_back(value);
                 data.mValues.push_back(value);
                 // skip whitespace after it
                 // skip whitespace after it
@@ -1489,11 +1482,10 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
             std::string name;
             std::string name;
             if (XmlParser::hasAttribute(currentNode, "name")) {
             if (XmlParser::hasAttribute(currentNode, "name")) {
                 XmlParser::getStdStrAttribute(currentNode, "name", name);
                 XmlParser::getStdStrAttribute(currentNode, "name", name);
-                //name = mReader->getAttributeValue(attrName);
 
 
                 // analyse for common type components and store it's sub-offset in the corresponding field
                 // analyse for common type components and store it's sub-offset in the corresponding field
 
 
-                /* Cartesian coordinates */
+                // Cartesian coordinates
                 if (name == "X")
                 if (name == "X")
                     acc.mSubOffset[0] = acc.mParams.size();
                     acc.mSubOffset[0] = acc.mParams.size();
                 else if (name == "Y")
                 else if (name == "Y")
@@ -1674,12 +1666,9 @@ void ColladaParser::ReadInputChannel(XmlNode &node, std::vector<InputChannel> &p
 
 
     // read set if texture coordinates
     // read set if texture coordinates
     if (channel.mType == IT_Texcoord || channel.mType == IT_Color) {
     if (channel.mType == IT_Texcoord || channel.mType == IT_Color) {
-        int attrSet = -1;
-        if (XmlParser::hasAttribute(node, "set")) {
-            XmlParser::getIntAttribute(node, "set", attrSet);
-        }
-
-        channel.mIndex = attrSet;
+        unsigned int attrSet = 0;
+        if (XmlParser::getUIntAttribute(node, "set", attrSet))
+            channel.mIndex = attrSet;
     }
     }
 
 
     // store, if valid type
     // store, if valid type
@@ -1704,20 +1693,20 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
     // determine the expected number of indices
     // determine the expected number of indices
     size_t expectedPointCount = 0;
     size_t expectedPointCount = 0;
     switch (pPrimType) {
     switch (pPrimType) {
-        case Prim_Polylist: {
-            for (size_t i : pVCount)
-                expectedPointCount += i;
-            break;
-        }
-        case Prim_Lines:
-            expectedPointCount = 2 * pNumPrimitives;
-            break;
-        case Prim_Triangles:
-            expectedPointCount = 3 * pNumPrimitives;
-            break;
-        default:
-            // other primitive types don't state the index count upfront... we need to guess
-            break;
+    case Prim_Polylist: {
+        for (size_t i : pVCount)
+            expectedPointCount += i;
+        break;
+    }
+    case Prim_Lines:
+        expectedPointCount = 2 * pNumPrimitives;
+        break;
+    case Prim_Triangles:
+        expectedPointCount = 3 * pNumPrimitives;
+        break;
+    default:
+        // other primitive types don't state the index count upfront... we need to guess
+        break;
     }
     }
 
 
     // and read all indices into a temporary array
     // and read all indices into a temporary array
@@ -1727,7 +1716,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
     }
     }
 
 
     // It is possible to not contain any indices
     // It is possible to not contain any indices
-    if (pNumPrimitives > 0)  {
+    if (pNumPrimitives > 0) {
         std::string v;
         std::string v;
         XmlParser::getValueAsString(node, v);
         XmlParser::getValueAsString(node, v);
         const char *content = v.c_str();
         const char *content = v.c_str();
@@ -1925,87 +1914,87 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
 
 
     // now we reinterpret it according to the type we're reading here
     // now we reinterpret it according to the type we're reading here
     switch (pInput.mType) {
     switch (pInput.mType) {
-        case IT_Position: // ignore all position streams except 0 - there can be only one position
-            if (pInput.mIndex == 0) {
-                pMesh.mPositions.push_back(aiVector3D(obj[0], obj[1], obj[2]));
-            } else {
-                ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported");
-            }
-            break;
-        case IT_Normal:
-            // pad to current vertex count if necessary
-            if (pMesh.mNormals.size() < pMesh.mPositions.size() - 1)
-                pMesh.mNormals.insert(pMesh.mNormals.end(), pMesh.mPositions.size() - pMesh.mNormals.size() - 1, aiVector3D(0, 1, 0));
+    case IT_Position: // ignore all position streams except 0 - there can be only one position
+        if (pInput.mIndex == 0) {
+            pMesh.mPositions.push_back(aiVector3D(obj[0], obj[1], obj[2]));
+        } else {
+            ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported");
+        }
+        break;
+    case IT_Normal:
+        // pad to current vertex count if necessary
+        if (pMesh.mNormals.size() < pMesh.mPositions.size() - 1)
+            pMesh.mNormals.insert(pMesh.mNormals.end(), pMesh.mPositions.size() - pMesh.mNormals.size() - 1, aiVector3D(0, 1, 0));
 
 
-            // ignore all normal streams except 0 - there can be only one normal
-            if (pInput.mIndex == 0) {
-                pMesh.mNormals.push_back(aiVector3D(obj[0], obj[1], obj[2]));
-            } else {
-                ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported");
-            }
-            break;
-        case IT_Tangent:
+        // ignore all normal streams except 0 - there can be only one normal
+        if (pInput.mIndex == 0) {
+            pMesh.mNormals.push_back(aiVector3D(obj[0], obj[1], obj[2]));
+        } else {
+            ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported");
+        }
+        break;
+    case IT_Tangent:
+        // pad to current vertex count if necessary
+        if (pMesh.mTangents.size() < pMesh.mPositions.size() - 1)
+            pMesh.mTangents.insert(pMesh.mTangents.end(), pMesh.mPositions.size() - pMesh.mTangents.size() - 1, aiVector3D(1, 0, 0));
+
+        // ignore all tangent streams except 0 - there can be only one tangent
+        if (pInput.mIndex == 0) {
+            pMesh.mTangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
+        } else {
+            ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported");
+        }
+        break;
+    case IT_Bitangent:
+        // pad to current vertex count if necessary
+        if (pMesh.mBitangents.size() < pMesh.mPositions.size() - 1) {
+            pMesh.mBitangents.insert(pMesh.mBitangents.end(), pMesh.mPositions.size() - pMesh.mBitangents.size() - 1, aiVector3D(0, 0, 1));
+        }
+
+        // ignore all bitangent streams except 0 - there can be only one bitangent
+        if (pInput.mIndex == 0) {
+            pMesh.mBitangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
+        } else {
+            ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported");
+        }
+        break;
+    case IT_Texcoord:
+        // up to 4 texture coord sets are fine, ignore the others
+        if (pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) {
             // pad to current vertex count if necessary
             // pad to current vertex count if necessary
-            if (pMesh.mTangents.size() < pMesh.mPositions.size() - 1)
-                pMesh.mTangents.insert(pMesh.mTangents.end(), pMesh.mPositions.size() - pMesh.mTangents.size() - 1, aiVector3D(1, 0, 0));
+            if (pMesh.mTexCoords[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
+                pMesh.mTexCoords[pInput.mIndex].insert(pMesh.mTexCoords[pInput.mIndex].end(),
+                        pMesh.mPositions.size() - pMesh.mTexCoords[pInput.mIndex].size() - 1, aiVector3D(0, 0, 0));
 
 
-            // ignore all tangent streams except 0 - there can be only one tangent
-            if (pInput.mIndex == 0) {
-                pMesh.mTangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
-            } else {
-                ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported");
+            pMesh.mTexCoords[pInput.mIndex].push_back(aiVector3D(obj[0], obj[1], obj[2]));
+            if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) {
+                pMesh.mNumUVComponents[pInput.mIndex] = 3;
             }
             }
-            break;
-        case IT_Bitangent:
+        } else {
+            ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping.");
+        }
+        break;
+    case IT_Color:
+        // up to 4 color sets are fine, ignore the others
+        if (pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS) {
             // pad to current vertex count if necessary
             // pad to current vertex count if necessary
-            if (pMesh.mBitangents.size() < pMesh.mPositions.size() - 1) {
-                pMesh.mBitangents.insert(pMesh.mBitangents.end(), pMesh.mPositions.size() - pMesh.mBitangents.size() - 1, aiVector3D(0, 0, 1));
-            }
+            if (pMesh.mColors[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
+                pMesh.mColors[pInput.mIndex].insert(pMesh.mColors[pInput.mIndex].end(),
+                        pMesh.mPositions.size() - pMesh.mColors[pInput.mIndex].size() - 1, aiColor4D(0, 0, 0, 1));
 
 
-            // ignore all bitangent streams except 0 - there can be only one bitangent
-            if (pInput.mIndex == 0) {
-                pMesh.mBitangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
-            } else {
-                ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported");
-            }
-            break;
-        case IT_Texcoord:
-            // up to 4 texture coord sets are fine, ignore the others
-            if (pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) {
-                // pad to current vertex count if necessary
-                if (pMesh.mTexCoords[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
-                    pMesh.mTexCoords[pInput.mIndex].insert(pMesh.mTexCoords[pInput.mIndex].end(),
-                            pMesh.mPositions.size() - pMesh.mTexCoords[pInput.mIndex].size() - 1, aiVector3D(0, 0, 0));
-
-                pMesh.mTexCoords[pInput.mIndex].push_back(aiVector3D(obj[0], obj[1], obj[2]));
-                if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) {
-                    pMesh.mNumUVComponents[pInput.mIndex] = 3;
-                }
-            } else {
-                ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping.");
-            }
-            break;
-        case IT_Color:
-            // up to 4 color sets are fine, ignore the others
-            if (pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS) {
-                // pad to current vertex count if necessary
-                if (pMesh.mColors[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
-                    pMesh.mColors[pInput.mIndex].insert(pMesh.mColors[pInput.mIndex].end(),
-                            pMesh.mPositions.size() - pMesh.mColors[pInput.mIndex].size() - 1, aiColor4D(0, 0, 0, 1));
-
-                aiColor4D result(0, 0, 0, 1);
-                for (size_t i = 0; i < pInput.mResolved->mSize; ++i) {
-                    result[static_cast<unsigned int>(i)] = obj[pInput.mResolved->mSubOffset[i]];
-                }
-                pMesh.mColors[pInput.mIndex].push_back(result);
-            } else {
-                ASSIMP_LOG_ERROR("Collada: too many vertex color sets. Skipping.");
+            aiColor4D result(0, 0, 0, 1);
+            for (size_t i = 0; i < pInput.mResolved->mSize; ++i) {
+                result[static_cast<unsigned int>(i)] = obj[pInput.mResolved->mSubOffset[i]];
             }
             }
+            pMesh.mColors[pInput.mIndex].push_back(result);
+        } else {
+            ASSIMP_LOG_ERROR("Collada: too many vertex color sets. Skipping.");
+        }
 
 
-            break;
-        default:
-            // IT_Invalid and IT_Vertex
-            ai_assert(false && "shouldn't ever get here");
+        break;
+    default:
+        // IT_Invalid and IT_Vertex
+        ai_assert(false && "shouldn't ever get here");
     }
     }
 }
 }
 
 
@@ -2170,10 +2159,10 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
 
 
     // read as many parameters and store in the transformation
     // read as many parameters and store in the transformation
     for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
     for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
+        // skip whitespace before the number
+        SkipSpacesAndLineEnd(&content);
         // read a number
         // read a number
         content = fast_atoreal_move<ai_real>(content, tf.f[a]);
         content = fast_atoreal_move<ai_real>(content, tf.f[a]);
-        // skip whitespace after it
-        SkipSpacesAndLineEnd(&content);
     }
     }
 
 
     // place the transformation at the queue of the node
     // place the transformation at the queue of the node
@@ -2215,8 +2204,8 @@ void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::Seman
 
 
 void ColladaParser::ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive) {
 void ColladaParser::ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive) {
     // Attempt to load any undefined Collada::Image in ImageLibrary
     // Attempt to load any undefined Collada::Image in ImageLibrary
-    for (ImageLibrary::iterator it = mImageLibrary.begin(); it != mImageLibrary.end(); ++it) {
-        Collada::Image &image = (*it).second;
+    for (auto & it : mImageLibrary) {
+        Collada::Image &image = it.second;
 
 
         if (image.mImageData.empty()) {
         if (image.mImageData.empty()) {
             std::unique_ptr<IOStream> image_file(zip_archive.Open(image.mFileName.c_str()));
             std::unique_ptr<IOStream> image_file(zip_archive.Open(image.mFileName.c_str()));

+ 1 - 3
code/AssetLib/DXF/DXFLoader.cpp

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
 
 
 Copyright (c) 2006-2021, assimp team
 Copyright (c) 2006-2021, 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,
@@ -549,7 +547,7 @@ void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
         ++reader;
         ++reader;
     }
     }
 
 
-    ASSIMP_LOG_VERBOSE_DEBUG( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(), 
+    ASSIMP_LOG_VERBOSE_DEBUG( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(),
         " inserted blocks in ENTITIES" );
         " inserted blocks in ENTITIES" );
 }
 }
 
 

+ 1 - 1
code/AssetLib/DXF/DXFLoader.h

@@ -63,7 +63,7 @@ namespace DXF {
 }
 }
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
-/** 
+/**
  *  @brief  DXF importer implementation.
  *  @brief  DXF importer implementation.
  */
  */
 class DXFImporter : public BaseImporter {
 class DXFImporter : public BaseImporter {

+ 11 - 6
code/AssetLib/FBX/FBXConverter.cpp

@@ -862,7 +862,7 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
     output_nodes.push_back(std::move(nd));
     output_nodes.push_back(std::move(nd));
     return false;
     return false;
 }
 }
-  
+
 void FBXConverter::SetupNodeMetadata(const Model &model, aiNode &nd) {
 void FBXConverter::SetupNodeMetadata(const Model &model, aiNode &nd) {
     const PropertyTable &props = model.Props();
     const PropertyTable &props = model.Props();
     DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
     DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
@@ -917,8 +917,10 @@ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root
         } else if (line) {
         } else if (line) {
             const std::vector<unsigned int> &indices = ConvertLine(*line, root_node);
             const std::vector<unsigned int> &indices = ConvertLine(*line, root_node);
             std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
             std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
-        } else {
+        } else if (geo) {
             FBXImporter::LogWarn("ignoring unrecognized geometry: ", geo->Name());
             FBXImporter::LogWarn("ignoring unrecognized geometry: ", geo->Name());
+        } else {
+            FBXImporter::LogWarn("skipping null geometry");
         }
         }
     }
     }
 
 
@@ -1766,6 +1768,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap
         // XXX handle all kinds of UV transformations
         // XXX handle all kinds of UV transformations
         uvTrafo.mScaling = tex->UVScaling();
         uvTrafo.mScaling = tex->UVScaling();
         uvTrafo.mTranslation = tex->UVTranslation();
         uvTrafo.mTranslation = tex->UVTranslation();
+        uvTrafo.mRotation = tex->UVRotation();
         out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, 0);
         out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, 0);
 
 
         const PropertyTable &props = tex->Props();
         const PropertyTable &props = tex->Props();
@@ -1885,6 +1888,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex
         // XXX handle all kinds of UV transformations
         // XXX handle all kinds of UV transformations
         uvTrafo.mScaling = tex->UVScaling();
         uvTrafo.mScaling = tex->UVScaling();
         uvTrafo.mTranslation = tex->UVTranslation();
         uvTrafo.mTranslation = tex->UVTranslation();
+        uvTrafo.mRotation = tex->UVRotation();
         out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, texIndex);
         out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, texIndex);
 
 
         const PropertyTable &props = tex->Props();
         const PropertyTable &props = tex->Props();
@@ -2129,7 +2133,7 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert
     if (ok) {
     if (ok) {
         out_mat->AddProperty(&Emissive, 1, AI_MATKEY_COLOR_EMISSIVE);
         out_mat->AddProperty(&Emissive, 1, AI_MATKEY_COLOR_EMISSIVE);
     } else {
     } else {
-        const aiColor3D &emissiveColor = GetColorPropertyFromMaterial(props, "Maya|emissive", ok);
+        const aiColor3D &emissiveColor = GetColorProperty(props, "Maya|emissive", ok);
         if (ok) {
         if (ok) {
             out_mat->AddProperty(&emissiveColor, 1, AI_MATKEY_COLOR_EMISSIVE);
             out_mat->AddProperty(&emissiveColor, 1, AI_MATKEY_COLOR_EMISSIVE);
         }
         }
@@ -2216,7 +2220,7 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert
     }
     }
 
 
     // PBR material information
     // PBR material information
-    const aiColor3D &baseColor = GetColorPropertyFromMaterial(props, "Maya|base_color", ok);
+    const aiColor3D &baseColor = GetColorProperty(props, "Maya|base_color", ok);
     if (ok) {
     if (ok) {
         out_mat->AddProperty(&baseColor, 1, AI_MATKEY_BASE_COLOR);
         out_mat->AddProperty(&baseColor, 1, AI_MATKEY_BASE_COLOR);
     }
     }
@@ -2324,6 +2328,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa
             // XXX handle all kinds of UV transformations
             // XXX handle all kinds of UV transformations
             uvTrafo.mScaling = tex->UVScaling();
             uvTrafo.mScaling = tex->UVScaling();
             uvTrafo.mTranslation = tex->UVTranslation();
             uvTrafo.mTranslation = tex->UVTranslation();
+            uvTrafo.mRotation = tex->UVRotation();
             out_mat->AddProperty(&uvTrafo, 1, (name + "|uvtrafo").c_str(), aiTextureType_UNKNOWN, 0);
             out_mat->AddProperty(&uvTrafo, 1, (name + "|uvtrafo").c_str(), aiTextureType_UNKNOWN, 0);
 
 
             int uvIndex = 0;
             int uvIndex = 0;
@@ -2599,7 +2604,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) {
             anim->mMorphMeshChannels = new aiMeshMorphAnim *[numMorphMeshChannels];
             anim->mMorphMeshChannels = new aiMeshMorphAnim *[numMorphMeshChannels];
             anim->mNumMorphMeshChannels = numMorphMeshChannels;
             anim->mNumMorphMeshChannels = numMorphMeshChannels;
             unsigned int i = 0;
             unsigned int i = 0;
-            for (auto morphAnimIt : morphAnimDatas) {
+            for (const auto &morphAnimIt : morphAnimDatas) {
                 morphAnimData *animData = morphAnimIt.second;
                 morphAnimData *animData = morphAnimIt.second;
                 unsigned int numKeys = static_cast<unsigned int>(animData->size());
                 unsigned int numKeys = static_cast<unsigned int>(animData->size());
                 aiMeshMorphAnim *meshMorphAnim = new aiMeshMorphAnim();
                 aiMeshMorphAnim *meshMorphAnim = new aiMeshMorphAnim();
@@ -3569,7 +3574,7 @@ void FBXConverter::ConvertOrphanedEmbeddedTextures() {
                         if (texture->Media() && texture->Media()->ContentLength() > 0) {
                         if (texture->Media() && texture->Media()->ContentLength() > 0) {
                             realTexture = texture;
                             realTexture = texture;
                         }
                         }
-                    }    
+                    }
                 }
                 }
             } catch (...) {
             } catch (...) {
                 // do nothing
                 // do nothing

+ 2 - 2
code/AssetLib/FBX/FBXConverter.h

@@ -76,7 +76,7 @@ namespace Assimp {
 namespace FBX {
 namespace FBX {
 
 
 class Document;
 class Document;
-/** 
+/**
  *  Convert a FBX #Document to #aiScene
  *  Convert a FBX #Document to #aiScene
  *  @param out Empty scene to be populated
  *  @param out Empty scene to be populated
  *  @param doc Parsed FBX document
  *  @param doc Parsed FBX document
@@ -182,7 +182,7 @@ private:
     // ------------------------------------------------------------------------------------------------
     // ------------------------------------------------------------------------------------------------
     void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
     void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
                       const aiMatrix4x4 &absolute_transform);
                       const aiMatrix4x4 &absolute_transform);
-    
+
     // ------------------------------------------------------------------------------------------------
     // ------------------------------------------------------------------------------------------------
     // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
     // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
     std::vector<unsigned int>
     std::vector<unsigned int>

+ 5 - 6
code/AssetLib/FBX/FBXDocument.cpp

@@ -57,9 +57,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
 
 
-#include <memory>
 #include <functional>
 #include <functional>
 #include <map>
 #include <map>
+#include <memory>
+#include <utility>
 
 
 namespace Assimp {
 namespace Assimp {
 namespace FBX {
 namespace FBX {
@@ -248,10 +249,8 @@ Object::~Object()
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props)
-: props(props)
-, doc(doc)
-{
+FileGlobalSettings::FileGlobalSettings(const Document &doc, std::shared_ptr<const PropertyTable> props) :
+        props(std::move(props)), doc(doc) {
     // empty
     // empty
 }
 }
 
 
@@ -636,7 +635,7 @@ std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source, 
+std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source,
         const char* const* classnames, size_t count) const
         const char* const* classnames, size_t count) const
 {
 {
     return GetConnectionsSequenced(source, true, ConnectionsBySource(),classnames, count);
     return GetConnectionsSequenced(source, true, ConnectionsBySource(),classnames, count);

+ 5 - 0
code/AssetLib/FBX/FBXDocument.h

@@ -500,6 +500,10 @@ public:
         return uvScaling;
         return uvScaling;
     }
     }
 
 
+    const ai_real &UVRotation() const {
+        return uvRotation;
+    }
+
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
         return *props.get();
         return *props.get();
@@ -517,6 +521,7 @@ public:
 private:
 private:
     aiVector2D uvTrans;
     aiVector2D uvTrans;
     aiVector2D uvScaling;
     aiVector2D uvScaling;
+    ai_real    uvRotation;
 
 
     std::string type;
     std::string type;
     std::string relativeFileName;
     std::string relativeFileName;

+ 2 - 3
code/AssetLib/FBX/FBXExportNode.cpp

@@ -144,9 +144,8 @@ void FBX::Node::AddP70time(
 // public member functions for writing nodes to stream
 // public member functions for writing nodes to stream
 
 
 void FBX::Node::Dump(
 void FBX::Node::Dump(
-    std::shared_ptr<Assimp::IOStream> outfile,
-    bool binary, int indent
-) {
+        const std::shared_ptr<Assimp::IOStream> &outfile,
+        bool binary, int indent) {
     if (binary) {
     if (binary) {
         Assimp::StreamWriterLE outstream(outfile);
         Assimp::StreamWriterLE outstream(outfile);
         DumpBinary(outstream);
         DumpBinary(outstream);

+ 3 - 4
code/AssetLib/FBX/FBXExportNode.h

@@ -60,7 +60,7 @@ namespace FBX {
 }
 }
 
 
 class FBX::Node {
 class FBX::Node {
-public: 
+public:
     // TODO: accessors
     // TODO: accessors
     std::string name; // node name
     std::string name; // node name
     std::vector<FBX::FBXExportProperty> properties; // node properties
     std::vector<FBX::FBXExportProperty> properties; // node properties
@@ -157,9 +157,8 @@ public: // member functions for writing data to a file or stream
 
 
     // write the full node to the given file or stream
     // write the full node to the given file or stream
     void Dump(
     void Dump(
-        std::shared_ptr<Assimp::IOStream> outfile,
-        bool binary, int indent
-    );
+            const std::shared_ptr<Assimp::IOStream> &outfile,
+            bool binary, int indent);
     void Dump(Assimp::StreamWriterLE &s, bool binary, int indent);
     void Dump(Assimp::StreamWriterLE &s, bool binary, int indent);
 
 
     // these other functions are for writing data piece by piece.
     // these other functions are for writing data piece by piece.

+ 110 - 35
code/AssetLib/FBX/FBXExporter.cpp

@@ -498,7 +498,7 @@ void FBXExporter::WriteDocuments ()
     if (!binary) {
     if (!binary) {
         WriteAsciiSectionHeader("Documents Description");
         WriteAsciiSectionHeader("Documents Description");
     }
     }
-    
+
     // not sure what the use of multiple documents would be,
     // not sure what the use of multiple documents would be,
     // or whether any end-application supports it
     // or whether any end-application supports it
     FBX::Node docs("Documents");
     FBX::Node docs("Documents");
@@ -541,10 +541,17 @@ void FBXExporter::WriteReferences ()
 // (before any actual data is written)
 // (before any actual data is written)
 // ---------------------------------------------------------------
 // ---------------------------------------------------------------
 
 
-size_t count_nodes(const aiNode* n) {
-    size_t count = 1;
+size_t count_nodes(const aiNode* n, const aiNode* root) {
+    size_t count;
+    if (n == root) {
+        count = n->mNumMeshes; // (not counting root node)
+    } else if (n->mNumMeshes > 1) {
+        count = n->mNumMeshes + 1;
+    } else {
+        count = 1;
+    }
     for (size_t i = 0; i < n->mNumChildren; ++i) {
     for (size_t i = 0; i < n->mNumChildren; ++i) {
-        count += count_nodes(n->mChildren[i]);
+        count += count_nodes(n->mChildren[i], root);
     }
     }
     return count;
     return count;
 }
 }
@@ -714,7 +721,7 @@ void FBXExporter::WriteDefinitions ()
 
 
     // Model / FbxNode
     // Model / FbxNode
     // <~~ node hierarchy
     // <~~ node hierarchy
-    count = int32_t(count_nodes(mScene->mRootNode)) - 1; // (not counting root node)
+    count = int32_t(count_nodes(mScene->mRootNode, mScene->mRootNode));
     if (count) {
     if (count) {
         n = FBX::Node("ObjectType", "Model");
         n = FBX::Node("ObjectType", "Model");
         n.AddChild("Count", count);
         n.AddChild("Count", count);
@@ -1251,7 +1258,7 @@ void FBXExporter::WriteObjects ()
             indent = 2;
             indent = 2;
             vertexcolors.End(outstream, binary, indent, true);
             vertexcolors.End(outstream, binary, indent, true);
         }
         }
-        
+
         // uvs, if any
         // uvs, if any
         for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) {
         for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) {
             if (m->mNumUVComponents[uvi] > 2) {
             if (m->mNumUVComponents[uvi] > 2) {
@@ -1681,6 +1688,10 @@ void FBXExporter::WriteObjects ()
             // link the image data to the texture
             // link the image data to the texture
             connections.emplace_back("C", "OO", image_uid, texture_uid);
             connections.emplace_back("C", "OO", image_uid, texture_uid);
 
 
+            aiUVTransform trafo;
+            unsigned int max = sizeof(aiUVTransform);
+            aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE, 0), (ai_real *)&trafo, &max);
+
             // now write the actual texture node
             // now write the actual texture node
             FBX::Node tnode("Texture");
             FBX::Node tnode("Texture");
             // TODO: some way to determine texture name?
             // TODO: some way to determine texture name?
@@ -1691,6 +1702,9 @@ void FBXExporter::WriteObjects ()
             tnode.AddChild("Version", int32_t(202));
             tnode.AddChild("Version", int32_t(202));
             tnode.AddChild("TextureName", texture_name);
             tnode.AddChild("TextureName", texture_name);
             FBX::Node p("Properties70");
             FBX::Node p("Properties70");
+            p.AddP70vectorA("Translation", trafo.mTranslation[0], trafo.mTranslation[1], 0.0);
+            p.AddP70vectorA("Rotation", 0, 0, trafo.mRotation);
+            p.AddP70vectorA("Scaling", trafo.mScaling[0], trafo.mScaling[1], 0.0);
             p.AddP70enum("CurrentTextureBlendMode", 0); // TODO: verify
             p.AddP70enum("CurrentTextureBlendMode", 0); // TODO: verify
             //p.AddP70string("UVSet", ""); // TODO: how should this work?
             //p.AddP70string("UVSet", ""); // TODO: how should this work?
             p.AddP70bool("UseMaterial", 1);
             p.AddP70bool("UseMaterial", 1);
@@ -1737,7 +1751,7 @@ void FBXExporter::WriteObjects ()
         bsnode.AddProperty(blendshape_uid);
         bsnode.AddProperty(blendshape_uid);
         bsnode.AddProperty(blendshape_name + FBX::SEPARATOR + "Blendshape");
         bsnode.AddProperty(blendshape_name + FBX::SEPARATOR + "Blendshape");
         bsnode.AddProperty("Shape");
         bsnode.AddProperty("Shape");
-        bsnode.AddChild("Version", int32_t(100));        
+        bsnode.AddChild("Version", int32_t(100));
         bsnode.Begin(outstream, binary, indent);
         bsnode.Begin(outstream, binary, indent);
         bsnode.DumpProperties(outstream, binary, indent);
         bsnode.DumpProperties(outstream, binary, indent);
         bsnode.EndProperties(outstream, binary, indent);
         bsnode.EndProperties(outstream, binary, indent);
@@ -1863,7 +1877,7 @@ void FBXExporter::WriteObjects ()
     // at the same time we can build a list of all the skeleton nodes,
     // at the same time we can build a list of all the skeleton nodes,
     // which will be used later to mark them as type "limbNode".
     // which will be used later to mark them as type "limbNode".
     std::unordered_set<const aiNode*> limbnodes;
     std::unordered_set<const aiNode*> limbnodes;
-    
+
     //actual bone nodes in fbx, without parenting-up
     //actual bone nodes in fbx, without parenting-up
     std::unordered_set<std::string> setAllBoneNamesInScene;
     std::unordered_set<std::string> setAllBoneNamesInScene;
     for(unsigned int m = 0; m < mScene->mNumMeshes; ++ m)
     for(unsigned int m = 0; m < mScene->mNumMeshes; ++ m)
@@ -1873,7 +1887,7 @@ void FBXExporter::WriteObjects ()
             setAllBoneNamesInScene.insert(pMesh->mBones[b]->mName.data);
             setAllBoneNamesInScene.insert(pMesh->mBones[b]->mName.data);
     }
     }
     aiMatrix4x4 mxTransIdentity;
     aiMatrix4x4 mxTransIdentity;
-    
+
     // and a map of nodes by bone name, as finding them is annoying.
     // and a map of nodes by bone name, as finding them is annoying.
     std::map<std::string,aiNode*> node_by_bone;
     std::map<std::string,aiNode*> node_by_bone;
     for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) {
     for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) {
@@ -1942,7 +1956,7 @@ void FBXExporter::WriteObjects ()
                     }
                     }
                     if (end) { break; }
                     if (end) { break; }
                 }
                 }
-                
+
                 // if it was the skeleton root we can finish here
                 // if it was the skeleton root we can finish here
                 if (end) { break; }
                 if (end) { break; }
             }
             }
@@ -2196,7 +2210,65 @@ void FBXExporter::WriteObjects ()
         bpnode.Dump(outstream, binary, indent);
         bpnode.Dump(outstream, binary, indent);
     }*/
     }*/
 
 
-    // TODO: cameras, lights
+    // lights
+    indent = 1;
+    lights_uids.clear();
+    for (size_t li = 0; li < mScene->mNumLights; ++li) {
+        aiLight* l = mScene->mLights[li];
+
+        int64_t uid = generate_uid();
+        const std::string lightNodeAttributeName = l->mName.C_Str() + FBX::SEPARATOR + "NodeAttribute";
+
+        FBX::Node lna("NodeAttribute");
+        lna.AddProperties(uid, lightNodeAttributeName, "Light");
+        FBX::Node lnap("Properties70");
+
+        // Light color.
+        lnap.AddP70colorA("Color", l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b);
+
+        // TODO Assimp light description is quite concise and do not handle light intensity.
+        // Default value to 1000W.
+        lnap.AddP70numberA("Intensity", 1000);
+
+        // FBXLight::EType conversion
+        switch (l->mType) {
+        case aiLightSource_POINT:
+            lnap.AddP70enum("LightType", 0);
+            break;
+        case aiLightSource_DIRECTIONAL:
+            lnap.AddP70enum("LightType", 1);
+            break;
+        case aiLightSource_SPOT:
+            lnap.AddP70enum("LightType", 2);
+            lnap.AddP70numberA("InnerAngle", AI_RAD_TO_DEG(l->mAngleInnerCone));
+            lnap.AddP70numberA("OuterAngle", AI_RAD_TO_DEG(l->mAngleOuterCone));
+            break;
+        // TODO Assimp do not handle 'area' nor 'volume' lights, but FBX does.
+        /*case aiLightSource_AREA:
+            lnap.AddP70enum("LightType", 3);
+            lnap.AddP70enum("AreaLightShape", 0); // 0=Rectangle, 1=Sphere
+            break;
+        case aiLightSource_VOLUME:
+            lnap.AddP70enum("LightType", 4);
+            break;*/
+        default:
+            break;
+        }
+
+        // Did not understood how to configure the decay so disabling attenuation.
+        lnap.AddP70enum("DecayType", 0);
+
+        // Dump to FBX stream
+        lna.AddChild(lnap);
+        lna.AddChild("TypeFlags", FBX::FBXExportProperty("Light"));
+        lna.AddChild("GeometryVersion", FBX::FBXExportProperty(int32_t(124)));
+        lna.Dump(outstream, binary, indent);
+
+        // Store name and uid (will be used later when parsing scene nodes)
+        lights_uids[l->mName.C_Str()] = uid;
+    }
+
+    // TODO: cameras
 
 
     // write nodes (i.e. model hierarchy)
     // write nodes (i.e. model hierarchy)
     // start at root node
     // start at root node
@@ -2600,10 +2672,19 @@ void FBXExporter::WriteModelNodes(
         // and connect them
         // and connect them
         connections.emplace_back("C", "OO", node_attribute_uid, node_uid);
         connections.emplace_back("C", "OO", node_attribute_uid, node_uid);
     } else {
     } else {
-        // generate a null node so we can add children to it
-        WriteModelNode(
-            outstream, binary, node, node_uid, "Null", transform_chain
-        );
+        const auto& lightIt = lights_uids.find(node->mName.C_Str());
+        if(lightIt != lights_uids.end()) {
+            // Node has a light connected to it.
+            WriteModelNode(
+                outstream, binary, node, node_uid, "Light", transform_chain
+            );
+            connections.emplace_back("C", "OO", lightIt->second, node_uid);
+        } else {
+            // generate a null node so we can add children to it
+            WriteModelNode(
+                outstream, binary, node, node_uid, "Null", transform_chain
+            );
+        }
     }
     }
 
 
     // if more than one child mesh, make nodes for each mesh
     // if more than one child mesh, make nodes for each mesh
@@ -2625,17 +2706,14 @@ void FBXExporter::WriteModelNodes(
                 ],
                 ],
                 new_node_uid
                 new_node_uid
             );
             );
-            // write model node
-            FBX::Node m("Model");
+
+            aiNode new_node;
             // take name from mesh name, if it exists
             // take name from mesh name, if it exists
-            std::string name = mScene->mMeshes[node->mMeshes[i]]->mName.C_Str();
-            name += FBX::SEPARATOR + "Model";
-            m.AddProperties(new_node_uid, name, "Mesh");
-            m.AddChild("Version", int32_t(232));
-            FBX::Node p("Properties70");
-            p.AddP70enum("InheritType", 1);
-            m.AddChild(p);
-            m.Dump(outstream, binary, 1);
+            new_node.mName = mScene->mMeshes[node->mMeshes[i]]->mName;
+            // write model node
+            WriteModelNode(
+                outstream, binary, &new_node, new_node_uid, "Mesh", std::vector<std::pair<std::string,aiVector3D>>()
+            );
         }
         }
     }
     }
 
 
@@ -2647,16 +2725,14 @@ void FBXExporter::WriteModelNodes(
     }
     }
 }
 }
 
 
-
 void FBXExporter::WriteAnimationCurveNode(
 void FBXExporter::WriteAnimationCurveNode(
-    StreamWriterLE& outstream,
-    int64_t uid,
-    const std::string& name, // "T", "R", or "S"
-    aiVector3D default_value,
-    std::string property_name, // "Lcl Translation" etc
-    int64_t layer_uid,
-    int64_t node_uid
-) {
+        StreamWriterLE &outstream,
+        int64_t uid,
+        const std::string &name, // "T", "R", or "S"
+        aiVector3D default_value,
+        const std::string &property_name, // "Lcl Translation" etc
+        int64_t layer_uid,
+        int64_t node_uid) {
     FBX::Node n("AnimationCurveNode");
     FBX::Node n("AnimationCurveNode");
     n.AddProperties(uid, name + FBX::SEPARATOR + "AnimCurveNode", "");
     n.AddProperties(uid, name + FBX::SEPARATOR + "AnimCurveNode", "");
     FBX::Node p("Properties70");
     FBX::Node p("Properties70");
@@ -2671,7 +2747,6 @@ void FBXExporter::WriteAnimationCurveNode(
     this->connections.emplace_back("C", "OP", uid, node_uid, property_name);
     this->connections.emplace_back("C", "OP", uid, node_uid, property_name);
 }
 }
 
 
-
 void FBXExporter::WriteAnimationCurve(
 void FBXExporter::WriteAnimationCurve(
     StreamWriterLE& outstream,
     StreamWriterLE& outstream,
     double default_value,
     double default_value,

+ 10 - 11
code/AssetLib/FBX/FBXExporter.h

@@ -63,10 +63,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 struct aiScene;
 struct aiScene;
 struct aiNode;
 struct aiNode;
-//struct aiMaterial;
+struct aiLight;
 
 
-namespace Assimp
-{
+namespace Assimp {
     class IOSystem;
     class IOSystem;
     class IOStream;
     class IOStream;
     class ExportProperties;
     class ExportProperties;
@@ -95,6 +94,7 @@ namespace Assimp
         std::vector<int64_t> mesh_uids;
         std::vector<int64_t> mesh_uids;
         std::vector<int64_t> material_uids;
         std::vector<int64_t> material_uids;
         std::map<const aiNode*,int64_t> node_uids;
         std::map<const aiNode*,int64_t> node_uids;
+        std::map<std::string,int64_t> lights_uids;
 
 
         // this crude unique-ID system is actually fine
         // this crude unique-ID system is actually fine
         int64_t last_uid = 999999;
         int64_t last_uid = 999999;
@@ -154,14 +154,13 @@ namespace Assimp
             FBX::TransformInheritance ti_type=FBX::TransformInheritance_RSrs
             FBX::TransformInheritance ti_type=FBX::TransformInheritance_RSrs
         );
         );
         void WriteAnimationCurveNode(
         void WriteAnimationCurveNode(
-            StreamWriterLE& outstream,
-            int64_t uid,
-            const std::string& name, // "T", "R", or "S"
-            aiVector3D default_value,
-            std::string property_name, // "Lcl Translation" etc
-            int64_t animation_layer_uid,
-            int64_t node_uid
-        );
+                StreamWriterLE &outstream,
+                int64_t uid,
+                const std::string &name, // "T", "R", or "S"
+                aiVector3D default_value,
+                const std::string &property_name, // "Lcl Translation" etc
+                int64_t animation_layer_uid,
+                int64_t node_uid);
         void WriteAnimationCurve(
         void WriteAnimationCurve(
             StreamWriterLE& outstream,
             StreamWriterLE& outstream,
             double default_value,
             double default_value,

+ 9 - 4
code/AssetLib/FBX/FBXMaterial.cpp

@@ -142,8 +142,8 @@ Material::~Material() {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
 Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
-        Object(id,element,name), 
-        uvScaling(1.0f,1.0f), 
+        Object(id,element,name),
+        uvScaling(1.0f,1.0f),
         media(0) {
         media(0) {
     const Scope& sc = GetRequiredScope(element);
     const Scope& sc = GetRequiredScope(element);
 
 
@@ -210,6 +210,11 @@ Texture::Texture(uint64_t id, const Element& element, const Document& doc, const
         uvTrans.y = trans.y;
         uvTrans.y = trans.y;
     }
     }
 
 
+    const aiVector3D &rotation = PropertyGet<aiVector3D>(*props, "Rotation", ok);
+    if (ok) {
+        uvRotation = rotation.z;
+    }
+
     // resolve video links
     // resolve video links
     if(doc.Settings().readTextures) {
     if(doc.Settings().readTextures) {
         const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
         const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
@@ -273,8 +278,8 @@ void LayeredTexture::fillTexture(const Document& doc) {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 Video::Video(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
 Video::Video(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
-        Object(id,element,name), 
-        contentLength(0), 
+        Object(id,element,name),
+        contentLength(0),
         content(0) {
         content(0) {
     const Scope& sc = GetRequiredScope(element);
     const Scope& sc = GetRequiredScope(element);
 
 

+ 1 - 1
code/AssetLib/FBX/FBXMeshGeometry.cpp

@@ -633,7 +633,7 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
     {
     {
         return;
         return;
     }
     }
-    
+
     // materials are handled separately. First of all, they are assigned per-face
     // materials are handled separately. First of all, they are assigned per-face
     // and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect
     // and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect
     // has a slightly different meaning for materials.
     // has a slightly different meaning for materials.

+ 4 - 4
code/AssetLib/FBX/FBXMeshGeometry.h

@@ -52,8 +52,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace Assimp {
 namespace FBX {
 namespace FBX {
 
 
-/** 
- *  DOM base class for all kinds of FBX geometry 
+/**
+ *  DOM base class for all kinds of FBX geometry
  */
  */
 class Geometry : public Object
 class Geometry : public Object
 {
 {
@@ -76,7 +76,7 @@ private:
 typedef std::vector<int> MatIndexArray;
 typedef std::vector<int> MatIndexArray;
 
 
 
 
-/** 
+/**
  *  DOM class for FBX geometry of type "Mesh"
  *  DOM class for FBX geometry of type "Mesh"
  */
  */
 class MeshGeometry : public Geometry
 class MeshGeometry : public Geometry
@@ -84,7 +84,7 @@ class MeshGeometry : public Geometry
 public:
 public:
     /** The class constructor */
     /** The class constructor */
     MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
     MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
-    
+
     /** The class destructor */
     /** The class destructor */
     virtual ~MeshGeometry();
     virtual ~MeshGeometry();
 
 

+ 12 - 16
code/AssetLib/FBX/FBXParser.cpp

@@ -192,6 +192,10 @@ Scope::Scope(Parser& parser,bool topLevel)
         }
         }
 
 
         const std::string& str = n->StringContents();
         const std::string& str = n->StringContents();
+        if (str.empty()) {
+            ParseError("unexpected content: empty string.");
+        }
+        
         elements.insert(ElementMap::value_type(str,new_Element(*n,parser)));
         elements.insert(ElementMap::value_type(str,new_Element(*n,parser)));
 
 
         // Element() should stop at the next Key token (or right after a Close token)
         // Element() should stop at the next Key token (or right after a Close token)
@@ -642,8 +646,7 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
 
 
         ai_assert(data == end);
         ai_assert(data == end);
         uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
         uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
-        ai_assert(buff.size() == dataToRead);
-        if (dataToRead > buff.size()) {
+        if (dataToRead != buff.size()) {
             ParseError("Invalid read size (binary)",&el);
             ParseError("Invalid read size (binary)",&el);
         }
         }
 
 
@@ -733,8 +736,7 @@ void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
 
 
         ai_assert(data == end);
         ai_assert(data == end);
         uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
         uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
-        ai_assert(buff.size() == dataToRead);
-        if (dataToRead > buff.size()) {
+        if (dataToRead != buff.size()) {
             ParseError("Invalid read size (binary)",&el);
             ParseError("Invalid read size (binary)",&el);
         }
         }
 
 
@@ -816,8 +818,7 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
 
 
         ai_assert(data == end);
         ai_assert(data == end);
         uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
         uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
-        ai_assert(buff.size() == dataToRead);
-        if (dataToRead > buff.size()) {
+        if (dataToRead != buff.size()) {
             ParseError("Invalid read size (binary)",&el);
             ParseError("Invalid read size (binary)",&el);
         }
         }
 
 
@@ -892,8 +893,7 @@ void ParseVectorDataArray(std::vector<int>& out, const Element& el)
 
 
         ai_assert(data == end);
         ai_assert(data == end);
         uint64_t dataToRead = static_cast<uint64_t>(count) * 4;
         uint64_t dataToRead = static_cast<uint64_t>(count) * 4;
-        ai_assert(buff.size() == dataToRead);
-        if (dataToRead > buff.size()) {
+        if (dataToRead != buff.size()) {
             ParseError("Invalid read size (binary)",&el);
             ParseError("Invalid read size (binary)",&el);
         }
         }
 
 
@@ -954,8 +954,7 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
 
 
         ai_assert(data == end);
         ai_assert(data == end);
         uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
         uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
-        ai_assert(buff.size() == dataToRead);
-        if (dataToRead > buff.size()) {
+        if (dataToRead != buff.size()) {
             ParseError("Invalid read size (binary)",&el);
             ParseError("Invalid read size (binary)",&el);
         }
         }
 
 
@@ -1019,8 +1018,7 @@ void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
 
 
         ai_assert(data == end);
         ai_assert(data == end);
         uint64_t dataToRead = static_cast<uint64_t>(count) * 4;
         uint64_t dataToRead = static_cast<uint64_t>(count) * 4;
-        ai_assert(buff.size() == dataToRead);
-        if (dataToRead > buff.size()) {
+        if (dataToRead != buff.size()) {
             ParseError("Invalid read size (binary)",&el);
             ParseError("Invalid read size (binary)",&el);
         }
         }
 
 
@@ -1088,8 +1086,7 @@ void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el)
 
 
         ai_assert(data == end);
         ai_assert(data == end);
         uint64_t dataToRead = static_cast<uint64_t>(count) * 8;
         uint64_t dataToRead = static_cast<uint64_t>(count) * 8;
-        ai_assert(buff.size() == dataToRead);
-        if (dataToRead > buff.size()) {
+        if (dataToRead != buff.size()) {
             ParseError("Invalid read size (binary)",&el);
             ParseError("Invalid read size (binary)",&el);
         }
         }
 
 
@@ -1150,8 +1147,7 @@ void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el)
 
 
         ai_assert(data == end);
         ai_assert(data == end);
         uint64_t dataToRead = static_cast<uint64_t>(count) * 8;
         uint64_t dataToRead = static_cast<uint64_t>(count) * 8;
-        ai_assert(buff.size() == dataToRead);
-        if (dataToRead > buff.size()) {
+        if (dataToRead != buff.size()) {
             ParseError("Invalid read size (binary)",&el);
             ParseError("Invalid read size (binary)",&el);
         }
         }
 
 

+ 4 - 5
code/AssetLib/FBX/FBXProperties.cpp

@@ -52,6 +52,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXDocumentUtil.h"
 #include "FBXDocumentUtil.h"
 #include "FBXProperties.h"
 #include "FBXProperties.h"
 
 
+#include <utility>
+
 namespace Assimp {
 namespace Assimp {
 namespace FBX {
 namespace FBX {
 
 
@@ -172,10 +174,8 @@ PropertyTable::PropertyTable()
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-PropertyTable::PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps)
-: templateProps(templateProps)
-, element(&element)
-{
+PropertyTable::PropertyTable(const Element &element, std::shared_ptr<const PropertyTable> templateProps) :
+        templateProps(std::move(templateProps)), element(&element) {
     const Scope& scope = GetRequiredScope(element);
     const Scope& scope = GetRequiredScope(element);
     for(const ElementMap::value_type& v : scope.Elements()) {
     for(const ElementMap::value_type& v : scope.Elements()) {
         if(v.first != "P") {
         if(v.first != "P") {
@@ -199,7 +199,6 @@ PropertyTable::PropertyTable(const Element& element, std::shared_ptr<const Prope
     }
     }
 }
 }
 
 
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 PropertyTable::~PropertyTable()
 PropertyTable::~PropertyTable()
 {
 {

+ 3 - 3
code/AssetLib/FBX/FBXProperties.h

@@ -98,7 +98,7 @@ typedef std::fbx_unordered_map<std::string,std::shared_ptr<Property> > DirectPro
 typedef std::fbx_unordered_map<std::string,const Property*>            PropertyMap;
 typedef std::fbx_unordered_map<std::string,const Property*>            PropertyMap;
 typedef std::fbx_unordered_map<std::string,const Element*>             LazyPropertyMap;
 typedef std::fbx_unordered_map<std::string,const Element*>             LazyPropertyMap;
 
 
-/** 
+/**
  *  Represents a property table as can be found in the newer FBX files (Properties60, Properties70)
  *  Represents a property table as can be found in the newer FBX files (Properties60, Properties70)
  */
  */
 class PropertyTable {
 class PropertyTable {
@@ -130,7 +130,7 @@ private:
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 template <typename T>
 template <typename T>
-inline 
+inline
 T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
 T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
     const Property* const prop = in.Get(name);
     const Property* const prop = in.Get(name);
     if( nullptr == prop) {
     if( nullptr == prop) {
@@ -148,7 +148,7 @@ T PropertyGet(const PropertyTable& in, const std::string& name, const T& default
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 template <typename T>
 template <typename T>
-inline 
+inline
 T PropertyGet(const PropertyTable& in, const std::string& name, bool& result, bool useTemplate=false ) {
 T PropertyGet(const PropertyTable& in, const std::string& name, bool& result, bool useTemplate=false ) {
     const Property* prop = in.Get(name);
     const Property* prop = in.Get(name);
     if( nullptr == prop) {
     if( nullptr == prop) {

+ 1 - 1
code/AssetLib/FBX/FBXUtil.cpp

@@ -101,7 +101,7 @@ std::string GetLineAndColumnText(unsigned int line, unsigned int column)
 std::string GetTokenText(const Token* tok)
 std::string GetTokenText(const Token* tok)
 {
 {
     if(tok->IsBinary()) {
     if(tok->IsBinary()) {
-        return static_cast<std::string>( Formatter::format() << 
+        return static_cast<std::string>( Formatter::format() <<
             " (" << TokenTypeString(tok->Type()) <<
             " (" << TokenTypeString(tok->Type()) <<
             ", offset 0x" << std::hex << tok->Offset() << ") " );
             ", offset 0x" << std::hex << tok->Offset() << ") " );
     }
     }

+ 2 - 2
code/AssetLib/HMP/HMPLoader.cpp

@@ -153,10 +153,10 @@ void HMPImporter::InternReadFile(const std::string &pFile,
     } else {
     } else {
         // Print the magic word to the logger
         // Print the magic word to the logger
         std::string szBuffer = ai_str_toprintable((const char *)&iMagic, sizeof(iMagic));
         std::string szBuffer = ai_str_toprintable((const char *)&iMagic, sizeof(iMagic));
-    
+
         delete[] mBuffer;
         delete[] mBuffer;
         mBuffer = nullptr;
         mBuffer = nullptr;
-        
+
         // We're definitely unable to load this file
         // We're definitely unable to load this file
         throw DeadlyImportError("Unknown HMP subformat ", pFile,
         throw DeadlyImportError("Unknown HMP subformat ", pFile,
                                 ". Magic word (", szBuffer, ") is not known");
                                 ". Magic word (", szBuffer, ") is not known");

+ 1 - 1
code/AssetLib/IFC/IFCBoolean.cpp

@@ -513,7 +513,7 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
             }
             }
 
 
             // we got a list of in-out-combinations of intersections. That should be an even number of intersections, or
             // we got a list of in-out-combinations of intersections. That should be an even number of intersections, or
-            // we're fucked.
+            // we are facing a non-recoverable error.
             if ((intersections.size() & 1) != 0) {
             if ((intersections.size() & 1) != 0) {
                 IFCImporter::LogWarn("Odd number of intersections, can't work with that. Omitting half space boundary check.");
                 IFCImporter::LogWarn("Odd number of intersections, can't work with that. Omitting half space boundary check.");
                 continue;
                 continue;

+ 1 - 1
code/AssetLib/IFC/IFCCurve.cpp

@@ -514,7 +514,7 @@ IfcFloat Curve::GetParametricRangeDelta() const {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 size_t Curve::EstimateSampleCount(IfcFloat a, IfcFloat b) const {
 size_t Curve::EstimateSampleCount(IfcFloat a, IfcFloat b) const {
-    (void)(a); (void)(b);  
+    (void)(a); (void)(b);
     ai_assert( InRange( a ) );
     ai_assert( InRange( a ) );
     ai_assert( InRange( b ) );
     ai_assert( InRange( b ) );
 
 

+ 1 - 1
code/AssetLib/IFC/IFCGeometry.cpp

@@ -740,7 +740,7 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
     bool fix_orientation = false;
     bool fix_orientation = false;
     std::shared_ptr< TempMesh > meshtmp = std::make_shared<TempMesh>();
     std::shared_ptr< TempMesh > meshtmp = std::make_shared<TempMesh>();
     if(const Schema_2x3::IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<Schema_2x3::IfcShellBasedSurfaceModel>()) {
     if(const Schema_2x3::IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<Schema_2x3::IfcShellBasedSurfaceModel>()) {
-        for(std::shared_ptr<const Schema_2x3::IfcShell> shell :shellmod->SbsmBoundary) {
+        for (const std::shared_ptr<const Schema_2x3::IfcShell> &shell : shellmod->SbsmBoundary) {
             try {
             try {
                 const ::Assimp::STEP::EXPRESS::ENTITY& e = shell->To<::Assimp::STEP::EXPRESS::ENTITY>();
                 const ::Assimp::STEP::EXPRESS::ENTITY& e = shell->To<::Assimp::STEP::EXPRESS::ENTITY>();
                 const Schema_2x3::IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<Schema_2x3::IfcConnectedFaceSet>();
                 const Schema_2x3::IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<Schema_2x3::IfcConnectedFaceSet>();

+ 3 - 3
code/AssetLib/IFC/IFCMaterial.cpp

@@ -75,7 +75,7 @@ static void FillMaterial(aiMaterial* mat,const IFC::Schema_2x3::IfcSurfaceStyle*
     mat->AddProperty(&name,AI_MATKEY_NAME);
     mat->AddProperty(&name,AI_MATKEY_NAME);
 
 
     // now see which kinds of surface information are present
     // now see which kinds of surface information are present
-    for(std::shared_ptr< const IFC::Schema_2x3::IfcSurfaceStyleElementSelect > sel2 : surf->Styles) {
+    for (const std::shared_ptr<const IFC::Schema_2x3::IfcSurfaceStyleElementSelect> &sel2 : surf->Styles) {
         if (const IFC::Schema_2x3::IfcSurfaceStyleShading* shade = sel2->ResolveSelectPtr<IFC::Schema_2x3::IfcSurfaceStyleShading>(conv.db)) {
         if (const IFC::Schema_2x3::IfcSurfaceStyleShading* shade = sel2->ResolveSelectPtr<IFC::Schema_2x3::IfcSurfaceStyleShading>(conv.db)) {
             aiColor4D col_base,col;
             aiColor4D col_base,col;
 
 
@@ -124,7 +124,7 @@ static void FillMaterial(aiMaterial* mat,const IFC::Schema_2x3::IfcSurfaceStyle*
                     }
                     }
                 }
                 }
             }
             }
-        } 
+        }
     }
     }
 }
 }
 
 
@@ -134,7 +134,7 @@ unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionDat
     for(;range.first != range.second; ++range.first) {
     for(;range.first != range.second; ++range.first) {
         if(const IFC::Schema_2x3::IfcStyledItem* const styled = conv.db.GetObject((*range.first).second)->ToPtr<IFC::Schema_2x3::IfcStyledItem>()) {
         if(const IFC::Schema_2x3::IfcStyledItem* const styled = conv.db.GetObject((*range.first).second)->ToPtr<IFC::Schema_2x3::IfcStyledItem>()) {
             for(const IFC::Schema_2x3::IfcPresentationStyleAssignment& as : styled->Styles) {
             for(const IFC::Schema_2x3::IfcPresentationStyleAssignment& as : styled->Styles) {
-                for(std::shared_ptr<const IFC::Schema_2x3::IfcPresentationStyleSelect> sel : as.Styles) {
+                for (const std::shared_ptr<const IFC::Schema_2x3::IfcPresentationStyleSelect> &sel : as.Styles) {
 
 
                     if( const IFC::Schema_2x3::IfcSurfaceStyle* const surf = sel->ResolveSelectPtr<IFC::Schema_2x3::IfcSurfaceStyle>(conv.db) ) {
                     if( const IFC::Schema_2x3::IfcSurfaceStyle* const surf = sel->ResolveSelectPtr<IFC::Schema_2x3::IfcSurfaceStyle>(conv.db) ) {
                         // try to satisfy from cache
                         // try to satisfy from cache

+ 4 - 4
code/AssetLib/IFC/IFCOpenings.cpp

@@ -911,14 +911,14 @@ size_t CloseWindows(ContourVector& contours,
             // compare base poly normal and contour normal to detect if we need to reverse the face winding
             // compare base poly normal and contour normal to detect if we need to reverse the face winding
 			if(curmesh.mVertcnt.size() > 0) {
 			if(curmesh.mVertcnt.size() > 0) {
 				IfcVector3 basePolyNormal = TempMesh::ComputePolygonNormal(curmesh.mVerts.data(), curmesh.mVertcnt.front());
 				IfcVector3 basePolyNormal = TempMesh::ComputePolygonNormal(curmesh.mVerts.data(), curmesh.mVertcnt.front());
-				
+
 				std::vector<IfcVector3> worldSpaceContourVtx(it->contour.size());
 				std::vector<IfcVector3> worldSpaceContourVtx(it->contour.size());
-				
+
 				for(size_t a = 0; a < it->contour.size(); ++a)
 				for(size_t a = 0; a < it->contour.size(); ++a)
 					worldSpaceContourVtx[a] = minv * IfcVector3(it->contour[a].x, it->contour[a].y, 0.0);
 					worldSpaceContourVtx[a] = minv * IfcVector3(it->contour[a].x, it->contour[a].y, 0.0);
-				
+
 				IfcVector3 contourNormal = TempMesh::ComputePolygonNormal(worldSpaceContourVtx.data(), worldSpaceContourVtx.size());
 				IfcVector3 contourNormal = TempMesh::ComputePolygonNormal(worldSpaceContourVtx.data(), worldSpaceContourVtx.size());
-				
+
 				reverseCountourFaces = (contourNormal * basePolyNormal) > 0.0;
 				reverseCountourFaces = (contourNormal * basePolyNormal) > 0.0;
 			}
 			}
 
 

+ 116 - 116
code/AssetLib/IFC/IFCReaderGen1_2x3.cpp

@@ -5,8 +5,8 @@ Open Asset Import Library (ASSIMP)
 Copyright (c) 2006-2020, ASSIMP Development Team
 Copyright (c) 2006-2020, ASSIMP Development Team
 All rights reserved.
 All rights reserved.
 
 
-Redistribution and use of this software in source and binary forms, 
-with or without modification, are permitted provided that the 
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
 following conditions are met:
 following conditions are met:
 
 
 * Redistributions of source code must retain the above
 * Redistributions of source code must retain the above
@@ -23,16 +23,16 @@ following conditions are met:
   derived from this software without specific prior
   derived from this software without specific prior
   written permission of the ASSIMP Development Team.
   written permission of the ASSIMP Development Team.
 
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+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
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 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 
+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.
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
@@ -1063,27 +1063,27 @@ template <> size_t GenericFill<IfcRoot>(const DB& db, const LIST& params, IfcRoo
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRoot"); }    do { // convert the 'GlobalId' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRoot"); }    do { // convert the 'GlobalId' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRoot,4>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRoot,4>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->GlobalId, arg, db ); break; } 
+        try { GenericConvert( in->GlobalId, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRoot to be a `IfcGloballyUniqueId`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRoot to be a `IfcGloballyUniqueId`")); }
     } while(0);
     } while(0);
     do { // convert the 'OwnerHistory' argument
     do { // convert the 'OwnerHistory' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRoot,4>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRoot,4>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->OwnerHistory, arg, db ); break; } 
+        try { GenericConvert( in->OwnerHistory, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRoot to be a `IfcOwnerHistory`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRoot to be a `IfcOwnerHistory`")); }
     } while(0);
     } while(0);
     do { // convert the 'Name' argument
     do { // convert the 'Name' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRoot,4>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRoot,4>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Name, arg, db ); break; } 
+        try { GenericConvert( in->Name, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRoot to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRoot to be a `IfcLabel`")); }
     } while(0);
     } while(0);
     do { // convert the 'Description' argument
     do { // convert the 'Description' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRoot,4>::aux_is_derived[3]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRoot,4>::aux_is_derived[3]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Description, arg, db ); break; } 
+        try { GenericConvert( in->Description, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRoot to be a `IfcText`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRoot to be a `IfcText`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1150,27 +1150,27 @@ template <> size_t GenericFill<IfcRepresentation>(const DB& db, const LIST& para
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRepresentation"); }    do { // convert the 'ContextOfItems' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRepresentation"); }    do { // convert the 'ContextOfItems' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentation,4>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentation,4>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->ContextOfItems, arg, db ); break; } 
+        try { GenericConvert( in->ContextOfItems, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentation to be a `IfcRepresentationContext`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentation to be a `IfcRepresentationContext`")); }
     } while(0);
     } while(0);
     do { // convert the 'RepresentationIdentifier' argument
     do { // convert the 'RepresentationIdentifier' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentation,4>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentation,4>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->RepresentationIdentifier, arg, db ); break; } 
+        try { GenericConvert( in->RepresentationIdentifier, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentation to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentation to be a `IfcLabel`")); }
     } while(0);
     } while(0);
     do { // convert the 'RepresentationType' argument
     do { // convert the 'RepresentationType' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentation,4>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentation,4>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->RepresentationType, arg, db ); break; } 
+        try { GenericConvert( in->RepresentationType, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRepresentation to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRepresentation to be a `IfcLabel`")); }
     } while(0);
     } while(0);
     do { // convert the 'Items' argument
     do { // convert the 'Items' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentation,4>::aux_is_derived[3]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentation,4>::aux_is_derived[3]=true; break; }
-        try { GenericConvert( in->Items, arg, db ); break; } 
+        try { GenericConvert( in->Items, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRepresentation to be a `SET [1:?] OF IfcRepresentationItem`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRepresentation to be a `SET [1:?] OF IfcRepresentationItem`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1237,7 +1237,7 @@ template <> size_t GenericFill<IfcObject>(const DB& db, const LIST& params, IfcO
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcObject,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcObject,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->ObjectType, arg, db ); break; } 
+        try { GenericConvert( in->ObjectType, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcObject to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcObject to be a `IfcLabel`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1290,20 +1290,20 @@ template <> size_t GenericFill<IfcProductRepresentation>(const DB& db, const LIS
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProductRepresentation,3>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProductRepresentation,3>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Name, arg, db ); break; } 
+        try { GenericConvert( in->Name, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProductRepresentation to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProductRepresentation to be a `IfcLabel`")); }
     } while(0);
     } while(0);
     do { // convert the 'Description' argument
     do { // convert the 'Description' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProductRepresentation,3>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProductRepresentation,3>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Description, arg, db ); break; } 
+        try { GenericConvert( in->Description, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProductRepresentation to be a `IfcText`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProductRepresentation to be a `IfcText`")); }
     } while(0);
     } while(0);
     do { // convert the 'Representations' argument
     do { // convert the 'Representations' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProductRepresentation,3>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProductRepresentation,3>::aux_is_derived[2]=true; break; }
-        try { GenericConvert( in->Representations, arg, db ); break; } 
+        try { GenericConvert( in->Representations, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcProductRepresentation to be a `LIST [1:?] OF IfcRepresentation`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcProductRepresentation to be a `LIST [1:?] OF IfcRepresentation`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1316,14 +1316,14 @@ template <> size_t GenericFill<IfcProduct>(const DB& db, const LIST& params, Ifc
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProduct,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProduct,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->ObjectPlacement, arg, db ); break; } 
+        try { GenericConvert( in->ObjectPlacement, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcProduct to be a `IfcObjectPlacement`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcProduct to be a `IfcObjectPlacement`")); }
     } while(0);
     } while(0);
     do { // convert the 'Representation' argument
     do { // convert the 'Representation' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProduct,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProduct,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Representation, arg, db ); break; } 
+        try { GenericConvert( in->Representation, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcProduct to be a `IfcProductRepresentation`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcProduct to be a `IfcProductRepresentation`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1336,7 +1336,7 @@ template <> size_t GenericFill<IfcElement>(const DB& db, const LIST& params, Ifc
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcElement,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcElement,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Tag, arg, db ); break; } 
+        try { GenericConvert( in->Tag, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcElement to be a `IfcIdentifier`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcElement to be a `IfcIdentifier`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1374,13 +1374,13 @@ template <> size_t GenericFill<IfcCompositeCurve>(const DB& db, const LIST& para
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcCompositeCurve"); }    do { // convert the 'Segments' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcCompositeCurve"); }    do { // convert the 'Segments' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCompositeCurve,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCompositeCurve,2>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Segments, arg, db ); break; } 
+        try { GenericConvert( in->Segments, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCompositeCurve to be a `LIST [1:?] OF IfcCompositeCurveSegment`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCompositeCurve to be a `LIST [1:?] OF IfcCompositeCurveSegment`")); }
     } while(0);
     } while(0);
     do { // convert the 'SelfIntersect' argument
     do { // convert the 'SelfIntersect' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCompositeCurve,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCompositeCurve,2>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->SelfIntersect, arg, db ); break; } 
+        try { GenericConvert( in->SelfIntersect, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCompositeCurve to be a `LOGICAL`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCompositeCurve to be a `LOGICAL`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1400,27 +1400,27 @@ template <> size_t GenericFill<IfcCartesianTransformationOperator>(const DB& db,
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCartesianTransformationOperator,4>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCartesianTransformationOperator,4>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Axis1, arg, db ); break; } 
+        try { GenericConvert( in->Axis1, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCartesianTransformationOperator to be a `IfcDirection`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCartesianTransformationOperator to be a `IfcDirection`")); }
     } while(0);
     } while(0);
     do { // convert the 'Axis2' argument
     do { // convert the 'Axis2' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCartesianTransformationOperator,4>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCartesianTransformationOperator,4>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Axis2, arg, db ); break; } 
+        try { GenericConvert( in->Axis2, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCartesianTransformationOperator to be a `IfcDirection`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCartesianTransformationOperator to be a `IfcDirection`")); }
     } while(0);
     } while(0);
     do { // convert the 'LocalOrigin' argument
     do { // convert the 'LocalOrigin' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCartesianTransformationOperator,4>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCartesianTransformationOperator,4>::aux_is_derived[2]=true; break; }
-        try { GenericConvert( in->LocalOrigin, arg, db ); break; } 
+        try { GenericConvert( in->LocalOrigin, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcCartesianTransformationOperator to be a `IfcCartesianPoint`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcCartesianTransformationOperator to be a `IfcCartesianPoint`")); }
     } while(0);
     } while(0);
     do { // convert the 'Scale' argument
     do { // convert the 'Scale' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCartesianTransformationOperator,4>::aux_is_derived[3]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCartesianTransformationOperator,4>::aux_is_derived[3]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Scale, arg, db ); break; } 
+        try { GenericConvert( in->Scale, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcCartesianTransformationOperator to be a `REAL`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcCartesianTransformationOperator to be a `REAL`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1433,7 +1433,7 @@ template <> size_t GenericFill<IfcCartesianTransformationOperator3D>(const DB& d
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCartesianTransformationOperator3D,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCartesianTransformationOperator3D,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Axis3, arg, db ); break; } 
+        try { GenericConvert( in->Axis3, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcCartesianTransformationOperator3D to be a `IfcDirection`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcCartesianTransformationOperator3D to be a `IfcDirection`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1445,14 +1445,14 @@ template <> size_t GenericFill<IfcProperty>(const DB& db, const LIST& params, If
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcProperty"); }    do { // convert the 'Name' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcProperty"); }    do { // convert the 'Name' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProperty,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProperty,2>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Name, arg, db ); break; } 
+        try { GenericConvert( in->Name, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProperty to be a `IfcIdentifier`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProperty to be a `IfcIdentifier`")); }
     } while(0);
     } while(0);
     do { // convert the 'Description' argument
     do { // convert the 'Description' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProperty,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProperty,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Description, arg, db ); break; } 
+        try { GenericConvert( in->Description, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProperty to be a `IfcText`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProperty to be a `IfcText`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1497,7 +1497,7 @@ template <> size_t GenericFill<IfcElementarySurface>(const DB& db, const LIST& p
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcElementarySurface"); }    do { // convert the 'Position' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcElementarySurface"); }    do { // convert the 'Position' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcElementarySurface,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcElementarySurface,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Position, arg, db ); break; } 
+        try { GenericConvert( in->Position, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcElementarySurface to be a `IfcAxis2Placement3D`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcElementarySurface to be a `IfcAxis2Placement3D`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1515,19 +1515,19 @@ template <> size_t GenericFill<IfcBooleanResult>(const DB& db, const LIST& param
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcBooleanResult"); }    do { // convert the 'Operator' argument
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcBooleanResult"); }    do { // convert the 'Operator' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBooleanResult,3>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBooleanResult,3>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Operator, arg, db ); break; } 
+        try { GenericConvert( in->Operator, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBooleanResult to be a `IfcBooleanOperator`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBooleanResult to be a `IfcBooleanOperator`")); }
     } while(0);
     } while(0);
     do { // convert the 'FirstOperand' argument
     do { // convert the 'FirstOperand' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBooleanResult,3>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBooleanResult,3>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->FirstOperand, arg, db ); break; } 
+        try { GenericConvert( in->FirstOperand, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBooleanResult to be a `IfcBooleanOperand`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBooleanResult to be a `IfcBooleanOperand`")); }
     } while(0);
     } while(0);
     do { // convert the 'SecondOperand' argument
     do { // convert the 'SecondOperand' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBooleanResult,3>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBooleanResult,3>::aux_is_derived[2]=true; break; }
-        try { GenericConvert( in->SecondOperand, arg, db ); break; } 
+        try { GenericConvert( in->SecondOperand, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBooleanResult to be a `IfcBooleanOperand`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBooleanResult to be a `IfcBooleanOperand`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1551,7 +1551,7 @@ template <> size_t GenericFill<IfcManifoldSolidBrep>(const DB& db, const LIST& p
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcManifoldSolidBrep"); }    do { // convert the 'Outer' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcManifoldSolidBrep"); }    do { // convert the 'Outer' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcManifoldSolidBrep,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcManifoldSolidBrep,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Outer, arg, db ); break; } 
+        try { GenericConvert( in->Outer, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcManifoldSolidBrep to be a `IfcClosedShell`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcManifoldSolidBrep to be a `IfcClosedShell`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1630,12 +1630,12 @@ template <> size_t GenericFill<IfcRelFillsElement>(const DB& db, const LIST& par
 	size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in));
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelFillsElement"); }    do { // convert the 'RelatingOpeningElement' argument
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelFillsElement"); }    do { // convert the 'RelatingOpeningElement' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->RelatingOpeningElement, arg, db ); break; } 
+        try { GenericConvert( in->RelatingOpeningElement, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelFillsElement to be a `IfcOpeningElement`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelFillsElement to be a `IfcOpeningElement`")); }
     } while(0);
     } while(0);
     do { // convert the 'RelatedBuildingElement' argument
     do { // convert the 'RelatedBuildingElement' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->RelatedBuildingElement, arg, db ); break; } 
+        try { GenericConvert( in->RelatedBuildingElement, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelFillsElement to be a `IfcElement`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelFillsElement to be a `IfcElement`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1681,12 +1681,12 @@ template <> size_t GenericFill<IfcRelContainedInSpatialStructure>(const DB& db,
 	size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in));
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelContainedInSpatialStructure"); }    do { // convert the 'RelatedElements' argument
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelContainedInSpatialStructure"); }    do { // convert the 'RelatedElements' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->RelatedElements, arg, db ); break; } 
+        try { GenericConvert( in->RelatedElements, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelContainedInSpatialStructure to be a `SET [1:?] OF IfcProduct`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelContainedInSpatialStructure to be a `SET [1:?] OF IfcProduct`")); }
     } while(0);
     } while(0);
     do { // convert the 'RelatingStructure' argument
     do { // convert the 'RelatingStructure' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->RelatingStructure, arg, db ); break; } 
+        try { GenericConvert( in->RelatingStructure, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelContainedInSpatialStructure to be a `IfcSpatialStructureElement`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelContainedInSpatialStructure to be a `IfcSpatialStructureElement`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1772,7 +1772,7 @@ template <> size_t GenericFill<IfcDirection>(const DB& db, const LIST& params, I
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcDirection"); }    do { // convert the 'DirectionRatios' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcDirection"); }    do { // convert the 'DirectionRatios' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->DirectionRatios, arg, db ); break; } 
+        try { GenericConvert( in->DirectionRatios, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcDirection to be a `LIST [2:3] OF REAL`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcDirection to be a `LIST [2:3] OF REAL`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1784,14 +1784,14 @@ template <> size_t GenericFill<IfcProfileDef>(const DB& db, const LIST& params,
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcProfileDef"); }    do { // convert the 'ProfileType' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcProfileDef"); }    do { // convert the 'ProfileType' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProfileDef,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProfileDef,2>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->ProfileType, arg, db ); break; } 
+        try { GenericConvert( in->ProfileType, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProfileDef to be a `IfcProfileTypeEnum`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProfileDef to be a `IfcProfileTypeEnum`")); }
     } while(0);
     } while(0);
     do { // convert the 'ProfileName' argument
     do { // convert the 'ProfileName' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProfileDef,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcProfileDef,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->ProfileName, arg, db ); break; } 
+        try { GenericConvert( in->ProfileName, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProfileDef to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProfileDef to be a `IfcLabel`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1803,7 +1803,7 @@ template <> size_t GenericFill<IfcParameterizedProfileDef>(const DB& db, const L
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcParameterizedProfileDef"); }    do { // convert the 'Position' argument
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcParameterizedProfileDef"); }    do { // convert the 'Position' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcParameterizedProfileDef,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcParameterizedProfileDef,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Position, arg, db ); break; } 
+        try { GenericConvert( in->Position, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcParameterizedProfileDef to be a `IfcAxis2Placement2D`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcParameterizedProfileDef to be a `IfcAxis2Placement2D`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1910,7 +1910,7 @@ template <> size_t GenericFill<IfcCircleProfileDef>(const DB& db, const LIST& pa
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcCircleProfileDef"); }    do { // convert the 'Radius' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcCircleProfileDef"); }    do { // convert the 'Radius' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCircleProfileDef,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcCircleProfileDef,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Radius, arg, db ); break; } 
+        try { GenericConvert( in->Radius, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcCircleProfileDef to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcCircleProfileDef to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1921,7 +1921,7 @@ template <> size_t GenericFill<IfcCircleHollowProfileDef>(const DB& db, const LI
 	size_t base = GenericFill(db,params,static_cast<IfcCircleProfileDef*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcCircleProfileDef*>(in));
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcCircleHollowProfileDef"); }    do { // convert the 'WallThickness' argument
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcCircleHollowProfileDef"); }    do { // convert the 'WallThickness' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->WallThickness, arg, db ); break; } 
+        try { GenericConvert( in->WallThickness, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcCircleHollowProfileDef to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcCircleHollowProfileDef to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1933,7 +1933,7 @@ template <> size_t GenericFill<IfcPlacement>(const DB& db, const LIST& params, I
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPlacement"); }    do { // convert the 'Location' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPlacement"); }    do { // convert the 'Location' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcPlacement,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcPlacement,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Location, arg, db ); break; } 
+        try { GenericConvert( in->Location, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPlacement to be a `IfcCartesianPoint`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPlacement to be a `IfcCartesianPoint`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1945,13 +1945,13 @@ template <> size_t GenericFill<IfcAxis2Placement3D>(const DB& db, const LIST& pa
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcAxis2Placement3D"); }    do { // convert the 'Axis' argument
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcAxis2Placement3D"); }    do { // convert the 'Axis' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Axis, arg, db ); break; } 
+        try { GenericConvert( in->Axis, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis2Placement3D to be a `IfcDirection`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis2Placement3D to be a `IfcDirection`")); }
     } while(0);
     } while(0);
     do { // convert the 'RefDirection' argument
     do { // convert the 'RefDirection' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->RefDirection, arg, db ); break; } 
+        try { GenericConvert( in->RefDirection, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcAxis2Placement3D to be a `IfcDirection`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcAxis2Placement3D to be a `IfcDirection`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1964,7 +1964,7 @@ template <> size_t GenericFill<IfcPresentationStyle>(const DB& db, const LIST& p
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcPresentationStyle,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcPresentationStyle,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Name, arg, db ); break; } 
+        try { GenericConvert( in->Name, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPresentationStyle to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPresentationStyle to be a `IfcLabel`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1982,17 +1982,17 @@ template <> size_t GenericFill<IfcCompositeCurveSegment>(const DB& db, const LIS
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcCompositeCurveSegment"); }    do { // convert the 'Transition' argument
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcCompositeCurveSegment"); }    do { // convert the 'Transition' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Transition, arg, db ); break; } 
+        try { GenericConvert( in->Transition, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCompositeCurveSegment to be a `IfcTransitionCode`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCompositeCurveSegment to be a `IfcTransitionCode`")); }
     } while(0);
     } while(0);
     do { // convert the 'SameSense' argument
     do { // convert the 'SameSense' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->SameSense, arg, db ); break; } 
+        try { GenericConvert( in->SameSense, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCompositeCurveSegment to be a `BOOLEAN`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCompositeCurveSegment to be a `BOOLEAN`")); }
     } while(0);
     } while(0);
     do { // convert the 'ParentCurve' argument
     do { // convert the 'ParentCurve' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->ParentCurve, arg, db ); break; } 
+        try { GenericConvert( in->ParentCurve, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcCompositeCurveSegment to be a `IfcCurve`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcCompositeCurveSegment to be a `IfcCurve`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2004,13 +2004,13 @@ template <> size_t GenericFill<IfcRectangleProfileDef>(const DB& db, const LIST&
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcRectangleProfileDef"); }    do { // convert the 'XDim' argument
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcRectangleProfileDef"); }    do { // convert the 'XDim' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRectangleProfileDef,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRectangleProfileDef,2>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->XDim, arg, db ); break; } 
+        try { GenericConvert( in->XDim, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRectangleProfileDef to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRectangleProfileDef to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'YDim' argument
     do { // convert the 'YDim' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRectangleProfileDef,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRectangleProfileDef,2>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->YDim, arg, db ); break; } 
+        try { GenericConvert( in->YDim, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRectangleProfileDef to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRectangleProfileDef to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2106,12 +2106,12 @@ template <> size_t GenericFill<IfcLocalPlacement>(const DB& db, const LIST& para
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcLocalPlacement"); }    do { // convert the 'PlacementRelTo' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcLocalPlacement"); }    do { // convert the 'PlacementRelTo' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->PlacementRelTo, arg, db ); break; } 
+        try { GenericConvert( in->PlacementRelTo, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcLocalPlacement to be a `IfcObjectPlacement`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcLocalPlacement to be a `IfcObjectPlacement`")); }
     } while(0);
     } while(0);
     do { // convert the 'RelativePlacement' argument
     do { // convert the 'RelativePlacement' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->RelativePlacement, arg, db ); break; } 
+        try { GenericConvert( in->RelativePlacement, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcLocalPlacement to be a `IfcAxis2Placement`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcLocalPlacement to be a `IfcAxis2Placement`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2123,13 +2123,13 @@ template <> size_t GenericFill<IfcSweptAreaSolid>(const DB& db, const LIST& para
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcSweptAreaSolid"); }    do { // convert the 'SweptArea' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcSweptAreaSolid"); }    do { // convert the 'SweptArea' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSweptAreaSolid,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSweptAreaSolid,2>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->SweptArea, arg, db ); break; } 
+        try { GenericConvert( in->SweptArea, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSweptAreaSolid to be a `IfcProfileDef`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSweptAreaSolid to be a `IfcProfileDef`")); }
     } while(0);
     } while(0);
     do { // convert the 'Position' argument
     do { // convert the 'Position' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSweptAreaSolid,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSweptAreaSolid,2>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->Position, arg, db ); break; } 
+        try { GenericConvert( in->Position, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSweptAreaSolid to be a `IfcAxis2Placement3D`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSweptAreaSolid to be a `IfcAxis2Placement3D`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2140,12 +2140,12 @@ template <> size_t GenericFill<IfcRevolvedAreaSolid>(const DB& db, const LIST& p
 	size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in));
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRevolvedAreaSolid"); }    do { // convert the 'Axis' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRevolvedAreaSolid"); }    do { // convert the 'Axis' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Axis, arg, db ); break; } 
+        try { GenericConvert( in->Axis, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRevolvedAreaSolid to be a `IfcAxis1Placement`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRevolvedAreaSolid to be a `IfcAxis1Placement`")); }
     } while(0);
     } while(0);
     do { // convert the 'Angle' argument
     do { // convert the 'Angle' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Angle, arg, db ); break; } 
+        try { GenericConvert( in->Angle, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRevolvedAreaSolid to be a `IfcPlaneAngleMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRevolvedAreaSolid to be a `IfcPlaneAngleMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2170,28 +2170,28 @@ template <> size_t GenericFill<IfcSweptDiskSolid>(const DB& db, const LIST& para
 	size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in));
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcSweptDiskSolid"); }    do { // convert the 'Directrix' argument
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcSweptDiskSolid"); }    do { // convert the 'Directrix' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Directrix, arg, db ); break; } 
+        try { GenericConvert( in->Directrix, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSweptDiskSolid to be a `IfcCurve`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSweptDiskSolid to be a `IfcCurve`")); }
     } while(0);
     } while(0);
     do { // convert the 'Radius' argument
     do { // convert the 'Radius' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Radius, arg, db ); break; } 
+        try { GenericConvert( in->Radius, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSweptDiskSolid to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSweptDiskSolid to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'InnerRadius' argument
     do { // convert the 'InnerRadius' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->InnerRadius, arg, db ); break; } 
+        try { GenericConvert( in->InnerRadius, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSweptDiskSolid to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSweptDiskSolid to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'StartParam' argument
     do { // convert the 'StartParam' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->StartParam, arg, db ); break; } 
+        try { GenericConvert( in->StartParam, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSweptDiskSolid to be a `IfcParameterValue`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSweptDiskSolid to be a `IfcParameterValue`")); }
     } while(0);
     } while(0);
     do { // convert the 'EndParam' argument
     do { // convert the 'EndParam' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->EndParam, arg, db ); break; } 
+        try { GenericConvert( in->EndParam, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcSweptDiskSolid to be a `IfcParameterValue`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcSweptDiskSolid to be a `IfcParameterValue`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2203,13 +2203,13 @@ template <> size_t GenericFill<IfcHalfSpaceSolid>(const DB& db, const LIST& para
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcHalfSpaceSolid"); }    do { // convert the 'BaseSurface' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcHalfSpaceSolid"); }    do { // convert the 'BaseSurface' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcHalfSpaceSolid,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcHalfSpaceSolid,2>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->BaseSurface, arg, db ); break; } 
+        try { GenericConvert( in->BaseSurface, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcHalfSpaceSolid to be a `IfcSurface`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcHalfSpaceSolid to be a `IfcSurface`")); }
     } while(0);
     } while(0);
     do { // convert the 'AgreementFlag' argument
     do { // convert the 'AgreementFlag' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcHalfSpaceSolid,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcHalfSpaceSolid,2>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->AgreementFlag, arg, db ); break; } 
+        try { GenericConvert( in->AgreementFlag, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcHalfSpaceSolid to be a `BOOLEAN`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcHalfSpaceSolid to be a `BOOLEAN`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2220,12 +2220,12 @@ template <> size_t GenericFill<IfcPolygonalBoundedHalfSpace>(const DB& db, const
 	size_t base = GenericFill(db,params,static_cast<IfcHalfSpaceSolid*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcHalfSpaceSolid*>(in));
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPolygonalBoundedHalfSpace"); }    do { // convert the 'Position' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPolygonalBoundedHalfSpace"); }    do { // convert the 'Position' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Position, arg, db ); break; } 
+        try { GenericConvert( in->Position, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPolygonalBoundedHalfSpace to be a `IfcAxis2Placement3D`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPolygonalBoundedHalfSpace to be a `IfcAxis2Placement3D`")); }
     } while(0);
     } while(0);
     do { // convert the 'PolygonalBoundary' argument
     do { // convert the 'PolygonalBoundary' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->PolygonalBoundary, arg, db ); break; } 
+        try { GenericConvert( in->PolygonalBoundary, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPolygonalBoundedHalfSpace to be a `IfcBoundedCurve`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPolygonalBoundedHalfSpace to be a `IfcBoundedCurve`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2251,23 +2251,23 @@ template <> size_t GenericFill<IfcProject>(const DB& db, const LIST& params, Ifc
 	if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcProject"); }    do { // convert the 'LongName' argument
 	if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcProject"); }    do { // convert the 'LongName' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->LongName, arg, db ); break; } 
+        try { GenericConvert( in->LongName, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcProject to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcProject to be a `IfcLabel`")); }
     } while(0);
     } while(0);
     do { // convert the 'Phase' argument
     do { // convert the 'Phase' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Phase, arg, db ); break; } 
+        try { GenericConvert( in->Phase, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcProject to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcProject to be a `IfcLabel`")); }
     } while(0);
     } while(0);
     do { // convert the 'RepresentationContexts' argument
     do { // convert the 'RepresentationContexts' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->RepresentationContexts, arg, db ); break; } 
+        try { GenericConvert( in->RepresentationContexts, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcProject to be a `SET [1:?] OF IfcRepresentationContext`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcProject to be a `SET [1:?] OF IfcRepresentationContext`")); }
     } while(0);
     } while(0);
     do { // convert the 'UnitsInContext' argument
     do { // convert the 'UnitsInContext' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->UnitsInContext, arg, db ); break; } 
+        try { GenericConvert( in->UnitsInContext, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcProject to be a `IfcUnitAssignment`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcProject to be a `IfcUnitAssignment`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2327,27 +2327,27 @@ template <> size_t GenericFill<IfcTrimmedCurve>(const DB& db, const LIST& params
 	size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in));
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcTrimmedCurve"); }    do { // convert the 'BasisCurve' argument
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcTrimmedCurve"); }    do { // convert the 'BasisCurve' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->BasisCurve, arg, db ); break; } 
+        try { GenericConvert( in->BasisCurve, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcTrimmedCurve to be a `IfcCurve`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcTrimmedCurve to be a `IfcCurve`")); }
     } while(0);
     } while(0);
     do { // convert the 'Trim1' argument
     do { // convert the 'Trim1' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Trim1, arg, db ); break; } 
+        try { GenericConvert( in->Trim1, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcTrimmedCurve to be a `SET [1:2] OF IfcTrimmingSelect`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcTrimmedCurve to be a `SET [1:2] OF IfcTrimmingSelect`")); }
     } while(0);
     } while(0);
     do { // convert the 'Trim2' argument
     do { // convert the 'Trim2' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Trim2, arg, db ); break; } 
+        try { GenericConvert( in->Trim2, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcTrimmedCurve to be a `SET [1:2] OF IfcTrimmingSelect`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcTrimmedCurve to be a `SET [1:2] OF IfcTrimmingSelect`")); }
     } while(0);
     } while(0);
     do { // convert the 'SenseAgreement' argument
     do { // convert the 'SenseAgreement' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->SenseAgreement, arg, db ); break; } 
+        try { GenericConvert( in->SenseAgreement, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcTrimmedCurve to be a `BOOLEAN`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcTrimmedCurve to be a `BOOLEAN`")); }
     } while(0);
     } while(0);
     do { // convert the 'MasterRepresentation' argument
     do { // convert the 'MasterRepresentation' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->MasterRepresentation, arg, db ); break; } 
+        try { GenericConvert( in->MasterRepresentation, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcTrimmedCurve to be a `IfcTrimmingPreference`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcTrimmedCurve to be a `IfcTrimmingPreference`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2359,7 +2359,7 @@ template <> size_t GenericFill<IfcRelDefines>(const DB& db, const LIST& params,
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcRelDefines"); }    do { // convert the 'RelatedObjects' argument
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcRelDefines"); }    do { // convert the 'RelatedObjects' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRelDefines,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRelDefines,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->RelatedObjects, arg, db ); break; } 
+        try { GenericConvert( in->RelatedObjects, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelDefines to be a `SET [1:?] OF IfcObject`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelDefines to be a `SET [1:?] OF IfcObject`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2371,7 +2371,7 @@ template <> size_t GenericFill<IfcRelDefinesByProperties>(const DB& db, const LI
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelDefinesByProperties"); }    do { // convert the 'RelatingPropertyDefinition' argument
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelDefinesByProperties"); }    do { // convert the 'RelatingPropertyDefinition' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRelDefinesByProperties,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRelDefinesByProperties,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->RelatingPropertyDefinition, arg, db ); break; } 
+        try { GenericConvert( in->RelatingPropertyDefinition, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelDefinesByProperties to be a `IfcPropertySetDefinition`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelDefinesByProperties to be a `IfcPropertySetDefinition`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2404,7 +2404,7 @@ template <> size_t GenericFill<IfcArbitraryOpenProfileDef>(const DB& db, const L
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcArbitraryOpenProfileDef"); }    do { // convert the 'Curve' argument
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcArbitraryOpenProfileDef"); }    do { // convert the 'Curve' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcArbitraryOpenProfileDef,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcArbitraryOpenProfileDef,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Curve, arg, db ); break; } 
+        try { GenericConvert( in->Curve, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcArbitraryOpenProfileDef to be a `IfcBoundedCurve`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcArbitraryOpenProfileDef to be a `IfcBoundedCurve`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2570,13 +2570,13 @@ template <> size_t GenericFill<IfcRelDecomposes>(const DB& db, const LIST& param
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelDecomposes"); }    do { // convert the 'RelatingObject' argument
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelDecomposes"); }    do { // convert the 'RelatingObject' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRelDecomposes,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRelDecomposes,2>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->RelatingObject, arg, db ); break; } 
+        try { GenericConvert( in->RelatingObject, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelDecomposes to be a `IfcObjectDefinition`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelDecomposes to be a `IfcObjectDefinition`")); }
     } while(0);
     } while(0);
     do { // convert the 'RelatedObjects' argument
     do { // convert the 'RelatedObjects' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRelDecomposes,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRelDecomposes,2>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->RelatedObjects, arg, db ); break; } 
+        try { GenericConvert( in->RelatedObjects, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelDecomposes to be a `SET [1:?] OF IfcObjectDefinition`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelDecomposes to be a `SET [1:?] OF IfcObjectDefinition`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2594,7 +2594,7 @@ template <> size_t GenericFill<IfcPolyline>(const DB& db, const LIST& params, If
 	size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in));
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPolyline"); }    do { // convert the 'Points' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPolyline"); }    do { // convert the 'Points' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Points, arg, db ); break; } 
+        try { GenericConvert( in->Points, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPolyline to be a `LIST [2:?] OF IfcCartesianPoint`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPolyline to be a `LIST [2:?] OF IfcCartesianPoint`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2626,12 +2626,12 @@ template <> size_t GenericFill<IfcMappedItem>(const DB& db, const LIST& params,
 	size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in));
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMappedItem"); }    do { // convert the 'MappingSource' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMappedItem"); }    do { // convert the 'MappingSource' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->MappingSource, arg, db ); break; } 
+        try { GenericConvert( in->MappingSource, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcMappedItem to be a `IfcRepresentationMap`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcMappedItem to be a `IfcRepresentationMap`")); }
     } while(0);
     } while(0);
     do { // convert the 'MappingTarget' argument
     do { // convert the 'MappingTarget' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->MappingTarget, arg, db ); break; } 
+        try { GenericConvert( in->MappingTarget, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcMappedItem to be a `IfcCartesianTransformationOperator`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcMappedItem to be a `IfcCartesianTransformationOperator`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2658,13 +2658,13 @@ template <> size_t GenericFill<IfcNamedUnit>(const DB& db, const LIST& params, I
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
 		if (dynamic_cast<const UNSET*>(&*arg)) break;
 		if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcNamedUnit,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcNamedUnit,2>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Dimensions, arg, db ); break; } 
+        try { GenericConvert( in->Dimensions, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcNamedUnit to be a `IfcDimensionalExponents`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcNamedUnit to be a `IfcDimensionalExponents`")); }
     } while(0);
     } while(0);
     do { // convert the 'UnitType' argument
     do { // convert the 'UnitType' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcNamedUnit,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcNamedUnit,2>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->UnitType, arg, db ); break; } 
+        try { GenericConvert( in->UnitType, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcNamedUnit to be a `IfcUnitEnum`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcNamedUnit to be a `IfcUnitEnum`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2719,13 +2719,13 @@ template <> size_t GenericFill<IfcSpatialStructureElement>(const DB& db, const L
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSpatialStructureElement,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSpatialStructureElement,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->LongName, arg, db ); break; } 
+        try { GenericConvert( in->LongName, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcSpatialStructureElement to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcSpatialStructureElement to be a `IfcLabel`")); }
     } while(0);
     } while(0);
     do { // convert the 'CompositionType' argument
     do { // convert the 'CompositionType' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSpatialStructureElement,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSpatialStructureElement,2>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->CompositionType, arg, db ); break; } 
+        try { GenericConvert( in->CompositionType, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSpatialStructureElement to be a `IfcElementCompositionEnum`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSpatialStructureElement to be a `IfcElementCompositionEnum`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2737,19 +2737,19 @@ template <> size_t GenericFill<IfcBuilding>(const DB& db, const LIST& params, If
 	if (params.GetSize() < 12) { throw STEP::TypeError("expected 12 arguments to IfcBuilding"); }    do { // convert the 'ElevationOfRefHeight' argument
 	if (params.GetSize() < 12) { throw STEP::TypeError("expected 12 arguments to IfcBuilding"); }    do { // convert the 'ElevationOfRefHeight' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->ElevationOfRefHeight, arg, db ); break; } 
+        try { GenericConvert( in->ElevationOfRefHeight, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcBuilding to be a `IfcLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcBuilding to be a `IfcLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'ElevationOfTerrain' argument
     do { // convert the 'ElevationOfTerrain' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->ElevationOfTerrain, arg, db ); break; } 
+        try { GenericConvert( in->ElevationOfTerrain, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcBuilding to be a `IfcLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcBuilding to be a `IfcLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'BuildingAddress' argument
     do { // convert the 'BuildingAddress' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->BuildingAddress, arg, db ); break; } 
+        try { GenericConvert( in->BuildingAddress, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 11 to IfcBuilding to be a `IfcPostalAddress`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 11 to IfcBuilding to be a `IfcPostalAddress`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2761,7 +2761,7 @@ template <> size_t GenericFill<IfcConnectedFaceSet>(const DB& db, const LIST& pa
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcConnectedFaceSet"); }    do { // convert the 'CfsFaces' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcConnectedFaceSet"); }    do { // convert the 'CfsFaces' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcConnectedFaceSet,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcConnectedFaceSet,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->CfsFaces, arg, db ); break; } 
+        try { GenericConvert( in->CfsFaces, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcConnectedFaceSet to be a `SET [1:?] OF IfcFace`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcConnectedFaceSet to be a `SET [1:?] OF IfcFace`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2787,7 +2787,7 @@ template <> size_t GenericFill<IfcConic>(const DB& db, const LIST& params, IfcCo
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcConic"); }    do { // convert the 'Position' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcConic"); }    do { // convert the 'Position' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcConic,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcConic,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Position, arg, db ); break; } 
+        try { GenericConvert( in->Position, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcConic to be a `IfcAxis2Placement`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcConic to be a `IfcAxis2Placement`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2834,32 +2834,32 @@ template <> size_t GenericFill<IfcIShapeProfileDef>(const DB& db, const LIST& pa
 	if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcIShapeProfileDef"); }    do { // convert the 'OverallWidth' argument
 	if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcIShapeProfileDef"); }    do { // convert the 'OverallWidth' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcIShapeProfileDef,5>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcIShapeProfileDef,5>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->OverallWidth, arg, db ); break; } 
+        try { GenericConvert( in->OverallWidth, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'OverallDepth' argument
     do { // convert the 'OverallDepth' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcIShapeProfileDef,5>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcIShapeProfileDef,5>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->OverallDepth, arg, db ); break; } 
+        try { GenericConvert( in->OverallDepth, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'WebThickness' argument
     do { // convert the 'WebThickness' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcIShapeProfileDef,5>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcIShapeProfileDef,5>::aux_is_derived[2]=true; break; }
-        try { GenericConvert( in->WebThickness, arg, db ); break; } 
+        try { GenericConvert( in->WebThickness, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'FlangeThickness' argument
     do { // convert the 'FlangeThickness' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcIShapeProfileDef,5>::aux_is_derived[3]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcIShapeProfileDef,5>::aux_is_derived[3]=true; break; }
-        try { GenericConvert( in->FlangeThickness, arg, db ); break; } 
+        try { GenericConvert( in->FlangeThickness, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'FilletRadius' argument
     do { // convert the 'FilletRadius' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcIShapeProfileDef,5>::aux_is_derived[4]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcIShapeProfileDef,5>::aux_is_derived[4]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->FilletRadius, arg, db ); break; } 
+        try { GenericConvert( in->FilletRadius, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2933,13 +2933,13 @@ template <> size_t GenericFill<IfcPropertyListValue>(const DB& db, const LIST& p
 	size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in));
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertyListValue"); }    do { // convert the 'ListValues' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertyListValue"); }    do { // convert the 'ListValues' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->ListValues, arg, db ); break; } 
+        try { GenericConvert( in->ListValues, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPropertyListValue to be a `LIST [1:?] OF IfcValue`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPropertyListValue to be a `LIST [1:?] OF IfcValue`")); }
     } while(0);
     } while(0);
     do { // convert the 'Unit' argument
     do { // convert the 'Unit' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Unit, arg, db ); break; } 
+        try { GenericConvert( in->Unit, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPropertyListValue to be a `IfcUnit`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPropertyListValue to be a `IfcUnit`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2965,13 +2965,13 @@ template <> size_t GenericFill<IfcDoor>(const DB& db, const LIST& params, IfcDoo
 	if (params.GetSize() < 10) { throw STEP::TypeError("expected 10 arguments to IfcDoor"); }    do { // convert the 'OverallHeight' argument
 	if (params.GetSize() < 10) { throw STEP::TypeError("expected 10 arguments to IfcDoor"); }    do { // convert the 'OverallHeight' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->OverallHeight, arg, db ); break; } 
+        try { GenericConvert( in->OverallHeight, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcDoor to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcDoor to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'OverallWidth' argument
     do { // convert the 'OverallWidth' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->OverallWidth, arg, db ); break; } 
+        try { GenericConvert( in->OverallWidth, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcDoor to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcDoor to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -2984,20 +2984,20 @@ template <> size_t GenericFill<IfcStyledItem>(const DB& db, const LIST& params,
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcStyledItem,3>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcStyledItem,3>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Item, arg, db ); break; } 
+        try { GenericConvert( in->Item, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcStyledItem to be a `IfcRepresentationItem`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcStyledItem to be a `IfcRepresentationItem`")); }
     } while(0);
     } while(0);
     do { // convert the 'Styles' argument
     do { // convert the 'Styles' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcStyledItem,3>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcStyledItem,3>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->Styles, arg, db ); break; } 
+        try { GenericConvert( in->Styles, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcStyledItem to be a `SET [1:?] OF IfcPresentationStyleAssignment`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcStyledItem to be a `SET [1:?] OF IfcPresentationStyleAssignment`")); }
     } while(0);
     } while(0);
     do { // convert the 'Name' argument
     do { // convert the 'Name' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcStyledItem,3>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcStyledItem,3>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Name, arg, db ); break; } 
+        try { GenericConvert( in->Name, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcStyledItem to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcStyledItem to be a `IfcLabel`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -3023,7 +3023,7 @@ template <> size_t GenericFill<IfcArbitraryClosedProfileDef>(const DB& db, const
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcArbitraryClosedProfileDef"); }    do { // convert the 'OuterCurve' argument
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcArbitraryClosedProfileDef"); }    do { // convert the 'OuterCurve' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcArbitraryClosedProfileDef,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcArbitraryClosedProfileDef,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->OuterCurve, arg, db ); break; } 
+        try { GenericConvert( in->OuterCurve, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcArbitraryClosedProfileDef to be a `IfcCurve`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcArbitraryClosedProfileDef to be a `IfcCurve`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -3041,12 +3041,12 @@ template <> size_t GenericFill<IfcLine>(const DB& db, const LIST& params, IfcLin
 	size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in));
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcLine"); }    do { // convert the 'Pnt' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcLine"); }    do { // convert the 'Pnt' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Pnt, arg, db ); break; } 
+        try { GenericConvert( in->Pnt, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcLine to be a `IfcCartesianPoint`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcLine to be a `IfcCartesianPoint`")); }
     } while(0);
     } while(0);
     do { // convert the 'Dir' argument
     do { // convert the 'Dir' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Dir, arg, db ); break; } 
+        try { GenericConvert( in->Dir, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcLine to be a `IfcVector`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcLine to be a `IfcVector`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -3072,13 +3072,13 @@ template <> size_t GenericFill<IfcPropertySingleValue>(const DB& db, const LIST&
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertySingleValue"); }    do { // convert the 'NominalValue' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertySingleValue"); }    do { // convert the 'NominalValue' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->NominalValue, arg, db ); break; } 
+        try { GenericConvert( in->NominalValue, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPropertySingleValue to be a `IfcValue`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPropertySingleValue to be a `IfcValue`")); }
     } while(0);
     } while(0);
     do { // convert the 'Unit' argument
     do { // convert the 'Unit' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Unit, arg, db ); break; } 
+        try { GenericConvert( in->Unit, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPropertySingleValue to be a `IfcUnit`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPropertySingleValue to be a `IfcUnit`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -3111,7 +3111,7 @@ template <> size_t GenericFill<IfcSurfaceStyleShading>(const DB& db, const LIST&
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleShading"); }    do { // convert the 'SurfaceColour' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleShading"); }    do { // convert the 'SurfaceColour' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSurfaceStyleShading,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcSurfaceStyleShading,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->SurfaceColour, arg, db ); break; } 
+        try { GenericConvert( in->SurfaceColour, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSurfaceStyleShading to be a `IfcColourRgb`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSurfaceStyleShading to be a `IfcColourRgb`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;

+ 81 - 81
code/AssetLib/IFC/IFCReaderGen2_2x3.cpp

@@ -5,8 +5,8 @@ Open Asset Import Library (ASSIMP)
 Copyright (c) 2006-2020, ASSIMP Development Team
 Copyright (c) 2006-2020, ASSIMP Development Team
 All rights reserved.
 All rights reserved.
 
 
-Redistribution and use of this software in source and binary forms, 
-with or without modification, are permitted provided that the 
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
 following conditions are met:
 following conditions are met:
 
 
 * Redistributions of source code must retain the above
 * Redistributions of source code must retain the above
@@ -23,16 +23,16 @@ following conditions are met:
   derived from this software without specific prior
   derived from this software without specific prior
   written permission of the ASSIMP Development Team.
   written permission of the ASSIMP Development Team.
 
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+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
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 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 
+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.
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
@@ -59,12 +59,12 @@ template <> size_t GenericFill<IfcSurfaceStyle>(const DB& db, const LIST& params
 	size_t base = GenericFill(db,params,static_cast<IfcPresentationStyle*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcPresentationStyle*>(in));
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcSurfaceStyle"); }    do { // convert the 'Side' argument
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcSurfaceStyle"); }    do { // convert the 'Side' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Side, arg, db ); break; } 
+        try { GenericConvert( in->Side, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSurfaceStyle to be a `IfcSurfaceSide`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSurfaceStyle to be a `IfcSurfaceSide`")); }
     } while(0);
     } while(0);
     do { // convert the 'Styles' argument
     do { // convert the 'Styles' argument
         std::shared_ptr<const DataType> arg = params[ base++ ];
         std::shared_ptr<const DataType> arg = params[ base++ ];
-        try { GenericConvert( in->Styles, arg, db ); break; } 
+        try { GenericConvert( in->Styles, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSurfaceStyle to be a `SET [1:5] OF IfcSurfaceStyleElementSelect`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSurfaceStyle to be a `SET [1:5] OF IfcSurfaceStyleElementSelect`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -118,7 +118,7 @@ template <> size_t GenericFill<IfcFace>(const DB& db, const LIST& params, IfcFac
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcFace"); }    do { // convert the 'Bounds' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcFace"); }    do { // convert the 'Bounds' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcFace,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcFace,1>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Bounds, arg, db ); break; } 
+        try { GenericConvert( in->Bounds, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFace to be a `SET [1:?] OF IfcFaceBound`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFace to be a `SET [1:?] OF IfcFaceBound`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -173,7 +173,7 @@ template <> size_t GenericFill<IfcColourSpecification>(const DB& db, const LIST&
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcColourSpecification,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcColourSpecification,1>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Name, arg, db ); break; } 
+        try { GenericConvert( in->Name, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcColourSpecification to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcColourSpecification to be a `IfcLabel`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -184,12 +184,12 @@ template <> size_t GenericFill<IfcVector>(const DB& db, const LIST& params, IfcV
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcVector"); }    do { // convert the 'Orientation' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcVector"); }    do { // convert the 'Orientation' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Orientation, arg, db ); break; } 
+        try { GenericConvert( in->Orientation, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcVector to be a `IfcDirection`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcVector to be a `IfcDirection`")); }
     } while(0);
     } while(0);
     do { // convert the 'Magnitude' argument
     do { // convert the 'Magnitude' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Magnitude, arg, db ); break; } 
+        try { GenericConvert( in->Magnitude, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcVector to be a `IfcLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcVector to be a `IfcLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -207,17 +207,17 @@ template <> size_t GenericFill<IfcColourRgb>(const DB& db, const LIST& params, I
 	size_t base = GenericFill(db,params,static_cast<IfcColourSpecification*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcColourSpecification*>(in));
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcColourRgb"); }    do { // convert the 'Red' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcColourRgb"); }    do { // convert the 'Red' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Red, arg, db ); break; } 
+        try { GenericConvert( in->Red, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'Green' argument
     do { // convert the 'Green' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Green, arg, db ); break; } 
+        try { GenericConvert( in->Green, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'Blue' argument
     do { // convert the 'Blue' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Blue, arg, db ); break; } 
+        try { GenericConvert( in->Blue, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -243,31 +243,31 @@ template <> size_t GenericFill<IfcSite>(const DB& db, const LIST& params, IfcSit
 	if (params.GetSize() < 14) { throw STEP::TypeError("expected 14 arguments to IfcSite"); }    do { // convert the 'RefLatitude' argument
 	if (params.GetSize() < 14) { throw STEP::TypeError("expected 14 arguments to IfcSite"); }    do { // convert the 'RefLatitude' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->RefLatitude, arg, db ); break; } 
+        try { GenericConvert( in->RefLatitude, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcSite to be a `IfcCompoundPlaneAngleMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcSite to be a `IfcCompoundPlaneAngleMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'RefLongitude' argument
     do { // convert the 'RefLongitude' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->RefLongitude, arg, db ); break; } 
+        try { GenericConvert( in->RefLongitude, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcSite to be a `IfcCompoundPlaneAngleMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcSite to be a `IfcCompoundPlaneAngleMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'RefElevation' argument
     do { // convert the 'RefElevation' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->RefElevation, arg, db ); break; } 
+        try { GenericConvert( in->RefElevation, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 11 to IfcSite to be a `IfcLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 11 to IfcSite to be a `IfcLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'LandTitleNumber' argument
     do { // convert the 'LandTitleNumber' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->LandTitleNumber, arg, db ); break; } 
+        try { GenericConvert( in->LandTitleNumber, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 12 to IfcSite to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 12 to IfcSite to be a `IfcLabel`")); }
     } while(0);
     } while(0);
     do { // convert the 'SiteAddress' argument
     do { // convert the 'SiteAddress' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->SiteAddress, arg, db ); break; } 
+        try { GenericConvert( in->SiteAddress, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 13 to IfcSite to be a `IfcPostalAddress`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 13 to IfcSite to be a `IfcPostalAddress`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -412,31 +412,31 @@ template <> size_t GenericFill<IfcBSplineCurve>(const DB& db, const LIST& params
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcBSplineCurve"); }    do { // convert the 'Degree' argument
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcBSplineCurve"); }    do { // convert the 'Degree' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBSplineCurve,5>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBSplineCurve,5>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Degree, arg, db ); break; } 
+        try { GenericConvert( in->Degree, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBSplineCurve to be a `INTEGER`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBSplineCurve to be a `INTEGER`")); }
     } while(0);
     } while(0);
     do { // convert the 'ControlPointsList' argument
     do { // convert the 'ControlPointsList' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBSplineCurve,5>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBSplineCurve,5>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->ControlPointsList, arg, db ); break; } 
+        try { GenericConvert( in->ControlPointsList, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBSplineCurve to be a `LIST [2:?] OF IfcCartesianPoint`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBSplineCurve to be a `LIST [2:?] OF IfcCartesianPoint`")); }
     } while(0);
     } while(0);
     do { // convert the 'CurveForm' argument
     do { // convert the 'CurveForm' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBSplineCurve,5>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBSplineCurve,5>::aux_is_derived[2]=true; break; }
-        try { GenericConvert( in->CurveForm, arg, db ); break; } 
+        try { GenericConvert( in->CurveForm, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBSplineCurve to be a `IfcBSplineCurveForm`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBSplineCurve to be a `IfcBSplineCurveForm`")); }
     } while(0);
     } while(0);
     do { // convert the 'ClosedCurve' argument
     do { // convert the 'ClosedCurve' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBSplineCurve,5>::aux_is_derived[3]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBSplineCurve,5>::aux_is_derived[3]=true; break; }
-        try { GenericConvert( in->ClosedCurve, arg, db ); break; } 
+        try { GenericConvert( in->ClosedCurve, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcBSplineCurve to be a `LOGICAL`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcBSplineCurve to be a `LOGICAL`")); }
     } while(0);
     } while(0);
     do { // convert the 'SelfIntersect' argument
     do { // convert the 'SelfIntersect' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBSplineCurve,5>::aux_is_derived[4]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcBSplineCurve,5>::aux_is_derived[4]=true; break; }
-        try { GenericConvert( in->SelfIntersect, arg, db ); break; } 
+        try { GenericConvert( in->SelfIntersect, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcBSplineCurve to be a `LOGICAL`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcBSplineCurve to be a `LOGICAL`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -474,7 +474,7 @@ template <> size_t GenericFill<IfcShellBasedSurfaceModel>(const DB& db, const LI
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcShellBasedSurfaceModel"); }    do { // convert the 'SbsmBoundary' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcShellBasedSurfaceModel"); }    do { // convert the 'SbsmBoundary' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->SbsmBoundary, arg, db ); break; } 
+        try { GenericConvert( in->SbsmBoundary, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcShellBasedSurfaceModel to be a `SET [1:?] OF IfcShell`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcShellBasedSurfaceModel to be a `SET [1:?] OF IfcShell`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -492,12 +492,12 @@ template <> size_t GenericFill<IfcExtrudedAreaSolid>(const DB& db, const LIST& p
 	size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in));
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcExtrudedAreaSolid"); }    do { // convert the 'ExtrudedDirection' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcExtrudedAreaSolid"); }    do { // convert the 'ExtrudedDirection' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->ExtrudedDirection, arg, db ); break; } 
+        try { GenericConvert( in->ExtrudedDirection, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcExtrudedAreaSolid to be a `IfcDirection`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcExtrudedAreaSolid to be a `IfcDirection`")); }
     } while(0);
     } while(0);
     do { // convert the 'Depth' argument
     do { // convert the 'Depth' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Depth, arg, db ); break; } 
+        try { GenericConvert( in->Depth, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcExtrudedAreaSolid to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcExtrudedAreaSolid to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -522,12 +522,12 @@ template <> size_t GenericFill<IfcRelVoidsElement>(const DB& db, const LIST& par
 	size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in));
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelVoidsElement"); }    do { // convert the 'RelatingBuildingElement' argument
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelVoidsElement"); }    do { // convert the 'RelatingBuildingElement' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->RelatingBuildingElement, arg, db ); break; } 
+        try { GenericConvert( in->RelatingBuildingElement, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelVoidsElement to be a `IfcElement`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelVoidsElement to be a `IfcElement`")); }
     } while(0);
     } while(0);
     do { // convert the 'RelatedOpeningElement' argument
     do { // convert the 'RelatedOpeningElement' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->RelatedOpeningElement, arg, db ); break; } 
+        try { GenericConvert( in->RelatedOpeningElement, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelVoidsElement to be a `IfcFeatureElementSubtraction`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelVoidsElement to be a `IfcFeatureElementSubtraction`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -546,13 +546,13 @@ template <> size_t GenericFill<IfcCartesianTransformationOperator3DnonUniform>(c
 	if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to IfcCartesianTransformationOperator3DnonUniform"); }    do { // convert the 'Scale2' argument
 	if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to IfcCartesianTransformationOperator3DnonUniform"); }    do { // convert the 'Scale2' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Scale2, arg, db ); break; } 
+        try { GenericConvert( in->Scale2, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcCartesianTransformationOperator3DnonUniform to be a `REAL`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcCartesianTransformationOperator3DnonUniform to be a `REAL`")); }
     } while(0);
     } while(0);
     do { // convert the 'Scale3' argument
     do { // convert the 'Scale3' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Scale3, arg, db ); break; } 
+        try { GenericConvert( in->Scale3, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcCartesianTransformationOperator3DnonUniform to be a `REAL`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcCartesianTransformationOperator3DnonUniform to be a `REAL`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -634,7 +634,7 @@ template <> size_t GenericFill<IfcAxis2Placement2D>(const DB& db, const LIST& pa
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcAxis2Placement2D"); }    do { // convert the 'RefDirection' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcAxis2Placement2D"); }    do { // convert the 'RefDirection' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->RefDirection, arg, db ); break; } 
+        try { GenericConvert( in->RefDirection, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis2Placement2D to be a `IfcDirection`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis2Placement2D to be a `IfcDirection`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -658,7 +658,7 @@ template <> size_t GenericFill<IfcCartesianPoint>(const DB& db, const LIST& para
 	size_t base = GenericFill(db,params,static_cast<IfcPoint*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcPoint*>(in));
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcCartesianPoint"); }    do { // convert the 'Coordinates' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcCartesianPoint"); }    do { // convert the 'Coordinates' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Coordinates, arg, db ); break; } 
+        try { GenericConvert( in->Coordinates, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCartesianPoint to be a `LIST [1:3] OF IfcLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCartesianPoint to be a `LIST [1:3] OF IfcLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -682,7 +682,7 @@ template <> size_t GenericFill<IfcPolyLoop>(const DB& db, const LIST& params, If
 	size_t base = GenericFill(db,params,static_cast<IfcLoop*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcLoop*>(in));
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPolyLoop"); }    do { // convert the 'Polygon' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPolyLoop"); }    do { // convert the 'Polygon' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Polygon, arg, db ); break; } 
+        try { GenericConvert( in->Polygon, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPolyLoop to be a `LIST [3:?] OF IfcCartesianPoint`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPolyLoop to be a `LIST [3:?] OF IfcCartesianPoint`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -716,14 +716,14 @@ template <> size_t GenericFill<IfcRepresentationContext>(const DB& db, const LIS
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentationContext,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentationContext,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->ContextIdentifier, arg, db ); break; } 
+        try { GenericConvert( in->ContextIdentifier, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentationContext to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentationContext to be a `IfcLabel`")); }
     } while(0);
     } while(0);
     do { // convert the 'ContextType' argument
     do { // convert the 'ContextType' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentationContext,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcRepresentationContext,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->ContextType, arg, db ); break; } 
+        try { GenericConvert( in->ContextType, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentationContext to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentationContext to be a `IfcLabel`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -735,27 +735,27 @@ template <> size_t GenericFill<IfcGeometricRepresentationContext>(const DB& db,
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcGeometricRepresentationContext"); }    do { // convert the 'CoordinateSpaceDimension' argument
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcGeometricRepresentationContext"); }    do { // convert the 'CoordinateSpaceDimension' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcGeometricRepresentationContext,4>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcGeometricRepresentationContext,4>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->CoordinateSpaceDimension, arg, db ); break; } 
+        try { GenericConvert( in->CoordinateSpaceDimension, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcGeometricRepresentationContext to be a `IfcDimensionCount`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcGeometricRepresentationContext to be a `IfcDimensionCount`")); }
     } while(0);
     } while(0);
     do { // convert the 'Precision' argument
     do { // convert the 'Precision' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcGeometricRepresentationContext,4>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcGeometricRepresentationContext,4>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Precision, arg, db ); break; } 
+        try { GenericConvert( in->Precision, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcGeometricRepresentationContext to be a `REAL`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcGeometricRepresentationContext to be a `REAL`")); }
     } while(0);
     } while(0);
     do { // convert the 'WorldCoordinateSystem' argument
     do { // convert the 'WorldCoordinateSystem' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcGeometricRepresentationContext,4>::aux_is_derived[2]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcGeometricRepresentationContext,4>::aux_is_derived[2]=true; break; }
-        try { GenericConvert( in->WorldCoordinateSystem, arg, db ); break; } 
+        try { GenericConvert( in->WorldCoordinateSystem, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcGeometricRepresentationContext to be a `IfcAxis2Placement`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcGeometricRepresentationContext to be a `IfcAxis2Placement`")); }
     } while(0);
     } while(0);
     do { // convert the 'TrueNorth' argument
     do { // convert the 'TrueNorth' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcGeometricRepresentationContext,4>::aux_is_derived[3]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcGeometricRepresentationContext,4>::aux_is_derived[3]=true; break; }
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->TrueNorth, arg, db ); break; } 
+        try { GenericConvert( in->TrueNorth, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcGeometricRepresentationContext to be a `IfcDirection`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcGeometricRepresentationContext to be a `IfcDirection`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -774,12 +774,12 @@ template <> size_t GenericFill<IfcSIUnit>(const DB& db, const LIST& params, IfcS
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcSIUnit"); }    do { // convert the 'Prefix' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcSIUnit"); }    do { // convert the 'Prefix' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Prefix, arg, db ); break; } 
+        try { GenericConvert( in->Prefix, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSIUnit to be a `IfcSIPrefix`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSIUnit to be a `IfcSIPrefix`")); }
     } while(0);
     } while(0);
     do { // convert the 'Name' argument
     do { // convert the 'Name' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Name, arg, db ); break; } 
+        try { GenericConvert( in->Name, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSIUnit to be a `IfcSIUnitName`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSIUnit to be a `IfcSIUnitName`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -805,7 +805,7 @@ template <> size_t GenericFill<IfcAxis1Placement>(const DB& db, const LIST& para
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcAxis1Placement"); }    do { // convert the 'Axis' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcAxis1Placement"); }    do { // convert the 'Axis' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Axis, arg, db ); break; } 
+        try { GenericConvert( in->Axis, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis1Placement to be a `IfcDirection`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis1Placement to be a `IfcDirection`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -858,12 +858,12 @@ template <> size_t GenericFill<IfcRepresentationMap>(const DB& db, const LIST& p
 	size_t base = 0;
 	size_t base = 0;
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcRepresentationMap"); }    do { // convert the 'MappingOrigin' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcRepresentationMap"); }    do { // convert the 'MappingOrigin' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->MappingOrigin, arg, db ); break; } 
+        try { GenericConvert( in->MappingOrigin, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentationMap to be a `IfcAxis2Placement`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentationMap to be a `IfcAxis2Placement`")); }
     } while(0);
     } while(0);
     do { // convert the 'MappedRepresentation' argument
     do { // convert the 'MappedRepresentation' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->MappedRepresentation, arg, db ); break; } 
+        try { GenericConvert( in->MappedRepresentation, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentationMap to be a `IfcRepresentation`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentationMap to be a `IfcRepresentation`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1012,12 +1012,12 @@ template <> size_t GenericFill<IfcMeasureWithUnit>(const DB& db, const LIST& par
 	size_t base = 0;
 	size_t base = 0;
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMeasureWithUnit"); }    do { // convert the 'ValueComponent' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMeasureWithUnit"); }    do { // convert the 'ValueComponent' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->ValueComponent, arg, db ); break; } 
+        try { GenericConvert( in->ValueComponent, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcMeasureWithUnit to be a `IfcValue`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcMeasureWithUnit to be a `IfcValue`")); }
     } while(0);
     } while(0);
     do { // convert the 'UnitComponent' argument
     do { // convert the 'UnitComponent' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->UnitComponent, arg, db ); break; } 
+        try { GenericConvert( in->UnitComponent, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcMeasureWithUnit to be a `IfcUnit`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcMeasureWithUnit to be a `IfcUnit`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1125,7 +1125,7 @@ template <> size_t GenericFill<IfcFaceBasedSurfaceModel>(const DB& db, const LIS
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcFaceBasedSurfaceModel"); }    do { // convert the 'FbsmFaces' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcFaceBasedSurfaceModel"); }    do { // convert the 'FbsmFaces' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->FbsmFaces, arg, db ); break; } 
+        try { GenericConvert( in->FbsmFaces, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFaceBasedSurfaceModel to be a `SET [1:?] OF IfcConnectedFaceSet`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFaceBasedSurfaceModel to be a `SET [1:?] OF IfcConnectedFaceSet`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1172,13 +1172,13 @@ template <> size_t GenericFill<IfcFaceBound>(const DB& db, const LIST& params, I
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcFaceBound"); }    do { // convert the 'Bound' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcFaceBound"); }    do { // convert the 'Bound' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcFaceBound,2>::aux_is_derived[0]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcFaceBound,2>::aux_is_derived[0]=true; break; }
-        try { GenericConvert( in->Bound, arg, db ); break; } 
+        try { GenericConvert( in->Bound, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFaceBound to be a `IfcLoop`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFaceBound to be a `IfcLoop`")); }
     } while(0);
     } while(0);
     do { // convert the 'Orientation' argument
     do { // convert the 'Orientation' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcFaceBound,2>::aux_is_derived[1]=true; break; }
         if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::Schema_2x3::IfcFaceBound,2>::aux_is_derived[1]=true; break; }
-        try { GenericConvert( in->Orientation, arg, db ); break; } 
+        try { GenericConvert( in->Orientation, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcFaceBound to be a `BOOLEAN`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcFaceBound to be a `BOOLEAN`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1216,12 +1216,12 @@ template <> size_t GenericFill<IfcComplexProperty>(const DB& db, const LIST& par
 	size_t base = GenericFill(db,params,static_cast<IfcProperty*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcProperty*>(in));
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcComplexProperty"); }    do { // convert the 'UsageName' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcComplexProperty"); }    do { // convert the 'UsageName' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->UsageName, arg, db ); break; } 
+        try { GenericConvert( in->UsageName, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcComplexProperty to be a `IfcIdentifier`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcComplexProperty to be a `IfcIdentifier`")); }
     } while(0);
     } while(0);
     do { // convert the 'HasProperties' argument
     do { // convert the 'HasProperties' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->HasProperties, arg, db ); break; } 
+        try { GenericConvert( in->HasProperties, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcComplexProperty to be a `SET [1:?] OF IfcProperty`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcComplexProperty to be a `SET [1:?] OF IfcProperty`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1274,7 +1274,7 @@ template <> size_t GenericFill<IfcUnitAssignment>(const DB& db, const LIST& para
 	size_t base = 0;
 	size_t base = 0;
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcUnitAssignment"); }    do { // convert the 'Units' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcUnitAssignment"); }    do { // convert the 'Units' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Units, arg, db ); break; } 
+        try { GenericConvert( in->Units, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcUnitAssignment to be a `SET [1:?] OF IfcUnit`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcUnitAssignment to be a `SET [1:?] OF IfcUnit`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1307,12 +1307,12 @@ template <> size_t GenericFill<IfcElementQuantity>(const DB& db, const LIST& par
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcElementQuantity"); }    do { // convert the 'MethodOfMeasurement' argument
 	if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcElementQuantity"); }    do { // convert the 'MethodOfMeasurement' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->MethodOfMeasurement, arg, db ); break; } 
+        try { GenericConvert( in->MethodOfMeasurement, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcElementQuantity to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcElementQuantity to be a `IfcLabel`")); }
     } while(0);
     } while(0);
     do { // convert the 'Quantities' argument
     do { // convert the 'Quantities' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Quantities, arg, db ); break; } 
+        try { GenericConvert( in->Quantities, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcElementQuantity to be a `SET [1:?] OF IfcPhysicalQuantity`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcElementQuantity to be a `SET [1:?] OF IfcPhysicalQuantity`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1379,7 +1379,7 @@ template <> size_t GenericFill<IfcPresentationStyleAssignment>(const DB& db, con
 	size_t base = 0;
 	size_t base = 0;
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPresentationStyleAssignment"); }    do { // convert the 'Styles' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPresentationStyleAssignment"); }    do { // convert the 'Styles' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Styles, arg, db ); break; } 
+        try { GenericConvert( in->Styles, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPresentationStyleAssignment to be a `SET [1:?] OF IfcPresentationStyleSelect`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPresentationStyleAssignment to be a `SET [1:?] OF IfcPresentationStyleSelect`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1418,13 +1418,13 @@ template <> size_t GenericFill<IfcSpace>(const DB& db, const LIST& params, IfcSp
 	size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in));
 	if (params.GetSize() < 11) { throw STEP::TypeError("expected 11 arguments to IfcSpace"); }    do { // convert the 'InteriorOrExteriorSpace' argument
 	if (params.GetSize() < 11) { throw STEP::TypeError("expected 11 arguments to IfcSpace"); }    do { // convert the 'InteriorOrExteriorSpace' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->InteriorOrExteriorSpace, arg, db ); break; } 
+        try { GenericConvert( in->InteriorOrExteriorSpace, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcSpace to be a `IfcInternalOrExternalEnum`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcSpace to be a `IfcInternalOrExternalEnum`")); }
     } while(0);
     } while(0);
     do { // convert the 'ElevationWithFlooring' argument
     do { // convert the 'ElevationWithFlooring' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->ElevationWithFlooring, arg, db ); break; } 
+        try { GenericConvert( in->ElevationWithFlooring, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcSpace to be a `IfcLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcSpace to be a `IfcLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1484,7 +1484,7 @@ template <> size_t GenericFill<IfcSurfaceStyleWithTextures>(const DB& db, const
 	size_t base = 0;
 	size_t base = 0;
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleWithTextures"); }    do { // convert the 'Textures' argument
 	if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleWithTextures"); }    do { // convert the 'Textures' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Textures, arg, db ); break; } 
+        try { GenericConvert( in->Textures, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSurfaceStyleWithTextures to be a `LIST [1:?] OF IfcSurfaceTexture`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSurfaceStyleWithTextures to be a `LIST [1:?] OF IfcSurfaceTexture`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1495,22 +1495,22 @@ template <> size_t GenericFill<IfcBoundingBox>(const DB& db, const LIST& params,
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcBoundingBox"); }    do { // convert the 'Corner' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcBoundingBox"); }    do { // convert the 'Corner' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Corner, arg, db ); break; } 
+        try { GenericConvert( in->Corner, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBoundingBox to be a `IfcCartesianPoint`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBoundingBox to be a `IfcCartesianPoint`")); }
     } while(0);
     } while(0);
     do { // convert the 'XDim' argument
     do { // convert the 'XDim' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->XDim, arg, db ); break; } 
+        try { GenericConvert( in->XDim, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'YDim' argument
     do { // convert the 'YDim' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->YDim, arg, db ); break; } 
+        try { GenericConvert( in->YDim, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'ZDim' argument
     do { // convert the 'ZDim' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->ZDim, arg, db ); break; } 
+        try { GenericConvert( in->ZDim, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1535,7 +1535,7 @@ template <> size_t GenericFill<IfcCircle>(const DB& db, const LIST& params, IfcC
 	size_t base = GenericFill(db,params,static_cast<IfcConic*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcConic*>(in));
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcCircle"); }    do { // convert the 'Radius' argument
 	if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcCircle"); }    do { // convert the 'Radius' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Radius, arg, db ); break; } 
+        try { GenericConvert( in->Radius, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCircle to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCircle to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1623,12 +1623,12 @@ template <> size_t GenericFill<IfcConversionBasedUnit>(const DB& db, const LIST&
 	size_t base = GenericFill(db,params,static_cast<IfcNamedUnit*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcNamedUnit*>(in));
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcConversionBasedUnit"); }    do { // convert the 'Name' argument
 	if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcConversionBasedUnit"); }    do { // convert the 'Name' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->Name, arg, db ); break; } 
+        try { GenericConvert( in->Name, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcConversionBasedUnit to be a `IfcLabel`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcConversionBasedUnit to be a `IfcLabel`")); }
     } while(0);
     } while(0);
     do { // convert the 'ConversionFactor' argument
     do { // convert the 'ConversionFactor' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->ConversionFactor, arg, db ); break; } 
+        try { GenericConvert( in->ConversionFactor, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcConversionBasedUnit to be a `IfcMeasureWithUnit`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcConversionBasedUnit to be a `IfcMeasureWithUnit`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1744,12 +1744,12 @@ template <> size_t GenericFill<IfcEllipse>(const DB& db, const LIST& params, Ifc
 	size_t base = GenericFill(db,params,static_cast<IfcConic*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcConic*>(in));
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcEllipse"); }    do { // convert the 'SemiAxis1' argument
 	if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcEllipse"); }    do { // convert the 'SemiAxis1' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->SemiAxis1, arg, db ); break; } 
+        try { GenericConvert( in->SemiAxis1, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcEllipse to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcEllipse to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'SemiAxis2' argument
     do { // convert the 'SemiAxis2' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->SemiAxis2, arg, db ); break; } 
+        try { GenericConvert( in->SemiAxis2, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcEllipse to be a `IfcPositiveLengthMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcEllipse to be a `IfcPositiveLengthMeasure`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1816,7 +1816,7 @@ template <> size_t GenericFill<IfcPropertySet>(const DB& db, const LIST& params,
 	size_t base = GenericFill(db,params,static_cast<IfcPropertySetDefinition*>(in));
 	size_t base = GenericFill(db,params,static_cast<IfcPropertySetDefinition*>(in));
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcPropertySet"); }    do { // convert the 'HasProperties' argument
 	if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcPropertySet"); }    do { // convert the 'HasProperties' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->HasProperties, arg, db ); break; } 
+        try { GenericConvert( in->HasProperties, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcPropertySet to be a `SET [1:?] OF IfcProperty`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcPropertySet to be a `SET [1:?] OF IfcProperty`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;
@@ -1828,48 +1828,48 @@ template <> size_t GenericFill<IfcSurfaceStyleRendering>(const DB& db, const LIS
 	if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcSurfaceStyleRendering"); }    do { // convert the 'Transparency' argument
 	if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcSurfaceStyleRendering"); }    do { // convert the 'Transparency' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->Transparency, arg, db ); break; } 
+        try { GenericConvert( in->Transparency, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSurfaceStyleRendering to be a `IfcNormalisedRatioMeasure`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSurfaceStyleRendering to be a `IfcNormalisedRatioMeasure`")); }
     } while(0);
     } while(0);
     do { // convert the 'DiffuseColour' argument
     do { // convert the 'DiffuseColour' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->DiffuseColour, arg, db ); break; } 
+        try { GenericConvert( in->DiffuseColour, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
     } while(0);
     } while(0);
     do { // convert the 'TransmissionColour' argument
     do { // convert the 'TransmissionColour' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->TransmissionColour, arg, db ); break; } 
+        try { GenericConvert( in->TransmissionColour, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
     } while(0);
     } while(0);
     do { // convert the 'DiffuseTransmissionColour' argument
     do { // convert the 'DiffuseTransmissionColour' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->DiffuseTransmissionColour, arg, db ); break; } 
+        try { GenericConvert( in->DiffuseTransmissionColour, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
     } while(0);
     } while(0);
     do { // convert the 'ReflectionColour' argument
     do { // convert the 'ReflectionColour' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->ReflectionColour, arg, db ); break; } 
+        try { GenericConvert( in->ReflectionColour, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
     } while(0);
     } while(0);
     do { // convert the 'SpecularColour' argument
     do { // convert the 'SpecularColour' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->SpecularColour, arg, db ); break; } 
+        try { GenericConvert( in->SpecularColour, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); }
     } while(0);
     } while(0);
     do { // convert the 'SpecularHighlight' argument
     do { // convert the 'SpecularHighlight' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
         if (dynamic_cast<const UNSET*>(&*arg)) break;
         if (dynamic_cast<const UNSET*>(&*arg)) break;
-        try { GenericConvert( in->SpecularHighlight, arg, db ); break; } 
+        try { GenericConvert( in->SpecularHighlight, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcSurfaceStyleRendering to be a `IfcSpecularHighlightSelect`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcSurfaceStyleRendering to be a `IfcSpecularHighlightSelect`")); }
     } while(0);
     } while(0);
     do { // convert the 'ReflectanceMethod' argument
     do { // convert the 'ReflectanceMethod' argument
         std::shared_ptr<const DataType> arg = params[base++];
         std::shared_ptr<const DataType> arg = params[base++];
-        try { GenericConvert( in->ReflectanceMethod, arg, db ); break; } 
+        try { GenericConvert( in->ReflectanceMethod, arg, db ); break; }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSurfaceStyleRendering to be a `IfcReflectanceMethodEnum`")); }
         catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSurfaceStyleRendering to be a `IfcReflectanceMethodEnum`")); }
     } while(0);
     } while(0);
 	return base;
 	return base;

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 129 - 129
code/AssetLib/IFC/IFCReaderGen_4.cpp


+ 13 - 13
code/AssetLib/IFC/IFCReaderGen_4.h

@@ -5,8 +5,8 @@ Open Asset Import Library (ASSIMP)
 Copyright (c) 2006-2020, ASSIMP Development Team
 Copyright (c) 2006-2020, ASSIMP Development Team
 All rights reserved.
 All rights reserved.
 
 
-Redistribution and use of this software in source and binary forms, 
-with or without modification, are permitted provided that the 
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
 following conditions are met:
 following conditions are met:
 
 
 * Redistributions of source code must retain the above
 * Redistributions of source code must retain the above
@@ -23,16 +23,16 @@ following conditions are met:
   derived from this software without specific prior
   derived from this software without specific prior
   written permission of the ASSIMP Development Team.
   written permission of the ASSIMP Development Team.
 
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+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
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 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 
+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.
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
@@ -51,12 +51,12 @@ namespace Schema_4 {
 
 
 	using namespace STEP;
 	using namespace STEP;
 	using namespace STEP::EXPRESS;
 	using namespace STEP::EXPRESS;
-	
-	
+
+
 	struct NotImplemented : public ObjectHelper<NotImplemented,0> {
 	struct NotImplemented : public ObjectHelper<NotImplemented,0> {
-		
+
 	};
 	};
-	
+
 
 
 	// ******************************************************************************
 	// ******************************************************************************
 	// IFC Custom data types
 	// IFC Custom data types

+ 6 - 8
code/AssetLib/IFC/IFCUtil.h

@@ -54,6 +54,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/mesh.h>
 #include <assimp/mesh.h>
 #include <assimp/material.h>
 #include <assimp/material.h>
 
 
+#include <utility>
+
 struct aiNode;
 struct aiNode;
 
 
 namespace Assimp {
 namespace Assimp {
@@ -137,14 +139,10 @@ struct TempOpening
     }
     }
 
 
     // ------------------------------------------------------------------------------
     // ------------------------------------------------------------------------------
-    TempOpening(const IFC::Schema_2x3::IfcSolidModel* solid,IfcVector3 extrusionDir,
-        std::shared_ptr<TempMesh> profileMesh,
-        std::shared_ptr<TempMesh> profileMesh2D)
-        : solid(solid)
-        , extrusionDir(extrusionDir)
-        , profileMesh(profileMesh)
-        , profileMesh2D(profileMesh2D)
-    {
+    TempOpening(const IFC::Schema_2x3::IfcSolidModel *solid, IfcVector3 extrusionDir,
+            std::shared_ptr<TempMesh> profileMesh,
+            std::shared_ptr<TempMesh> profileMesh2D) :
+            solid(solid), extrusionDir(extrusionDir), profileMesh(std::move(profileMesh)), profileMesh2D(std::move(profileMesh2D)) {
     }
     }
 
 
     // ------------------------------------------------------------------------------
     // ------------------------------------------------------------------------------

+ 1 - 1
code/AssetLib/Irr/IRRLoader.h

@@ -273,7 +273,7 @@ private:
         std::vector<aiNodeAnim*>& anims);
         std::vector<aiNodeAnim*>& anims);
 
 
 private:
 private:
-    /// Configuration option: desired output FPS 
+    /// Configuration option: desired output FPS
     double fps;
     double fps;
 
 
     /// Configuration option: speed flag was set?
     /// Configuration option: speed flag was set?

+ 1 - 1
code/AssetLib/LWO/LWOAnimation.h

@@ -114,7 +114,7 @@ enum PrePostBehaviour
 /** \brief Data structure for a LWO animation keyframe
 /** \brief Data structure for a LWO animation keyframe
  */
  */
 struct Key {
 struct Key {
-    Key() AI_NO_EXCEPT 
+    Key() AI_NO_EXCEPT
     : time()
     : time()
     , value()
     , value()
     , inter(IT_LINE)
     , inter(IT_LINE)

+ 3 - 3
code/AssetLib/LWS/LWSLoader.cpp

@@ -200,7 +200,7 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
 
 
     // reserve enough storage
     // reserve enough storage
     std::list<LWS::Element>::const_iterator it = dad.children.begin();
     std::list<LWS::Element>::const_iterator it = dad.children.begin();
-    
+
     fill.keys.reserve(strtoul10(it->tokens[1].c_str()));
     fill.keys.reserve(strtoul10(it->tokens[1].c_str()));
 
 
     for (++it; it != dad.children.end(); ++it) {
     for (++it; it != dad.children.end(); ++it) {
@@ -318,7 +318,7 @@ void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
             } else {
             } else {
                 ++s;
                 ++s;
             }
             }
-            std::string::size_type t = src.path.substr(s).find_last_of(".");
+            std::string::size_type t = src.path.substr(s).find_last_of('.');
 
 
             nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)", src.path.substr(s).substr(0, t).c_str(), combined);
             nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)", src.path.substr(s).substr(0, t).c_str(), combined);
             return;
             return;
@@ -466,7 +466,7 @@ std::string LWSImporter::FindLWOFile(const std::string &in) {
     std::string tmp(in);
     std::string tmp(in);
     if (in.length() > 3 && in[1] == ':' && in[2] != '\\' && in[2] != '/') {
     if (in.length() > 3 && in[1] == ':' && in[2] != '\\' && in[2] != '/') {
         tmp = in[0] + (std::string(":\\") + in.substr(2));
         tmp = in[0] + (std::string(":\\") + in.substr(2));
-    } 
+    }
 
 
     if (io->Exists(tmp)) {
     if (io->Exists(tmp)) {
         return in;
         return in;

+ 8 - 8
code/AssetLib/M3D/M3DImporter.cpp

@@ -233,12 +233,12 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) {
     ASSIMP_LOG_DEBUG("M3D: importMaterials ", mScene->mNumMaterials);
     ASSIMP_LOG_DEBUG("M3D: importMaterials ", mScene->mNumMaterials);
 
 
     // add a default material as first
     // add a default material as first
-    aiMaterial *mat = new aiMaterial;
-    mat->AddProperty(&name, AI_MATKEY_NAME);
+    aiMaterial *defaultMat = new aiMaterial;
+    defaultMat->AddProperty(&name, AI_MATKEY_NAME);
     c.a = 1.0f;
     c.a = 1.0f;
     c.b = c.g = c.r = 0.6f;
     c.b = c.g = c.r = 0.6f;
-    mat->AddProperty(&c, 1, AI_MATKEY_COLOR_DIFFUSE);
-    mScene->mMaterials[0] = mat;
+    defaultMat->AddProperty(&c, 1, AI_MATKEY_COLOR_DIFFUSE);
+    mScene->mMaterials[0] = defaultMat;
 
 
     if (!m3d->nummaterial || !m3d->material) {
     if (!m3d->nummaterial || !m3d->material) {
         return;
         return;
@@ -300,12 +300,12 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) {
                     m->prop[j].value.textureid < m3d->numtexture &&
                     m->prop[j].value.textureid < m3d->numtexture &&
                     m3d->texture[m->prop[j].value.textureid].name) {
                     m3d->texture[m->prop[j].value.textureid].name) {
                 name.Set(std::string(std::string(m3d->texture[m->prop[j].value.textureid].name) + ".png"));
                 name.Set(std::string(std::string(m3d->texture[m->prop[j].value.textureid].name) + ".png"));
-                mat->AddProperty(&name, aiTxProps[k].pKey, aiTxProps[k].type, aiTxProps[k].index);
+                newMat->AddProperty(&name, aiTxProps[k].pKey, aiTxProps[k].type, aiTxProps[k].index);
                 n = 0;
                 n = 0;
-                mat->AddProperty(&n, 1, _AI_MATKEY_UVWSRC_BASE, aiProps[k].type, aiProps[k].index);
+                newMat->AddProperty(&n, 1, _AI_MATKEY_UVWSRC_BASE, aiProps[k].type, aiProps[k].index);
             }
             }
         }
         }
-        mScene->mMaterials[i + 1] = mat;
+        mScene->mMaterials[i + 1] = newMat;
     }
     }
 }
 }
 
 
@@ -655,7 +655,7 @@ void M3DImporter::convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned in
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // find a node by name
 // find a node by name
-aiNode *M3DImporter::findNode(aiNode *pNode, aiString name) {
+aiNode *M3DImporter::findNode(aiNode *pNode, const aiString &name) {
     ai_assert(pNode != nullptr);
     ai_assert(pNode != nullptr);
     ai_assert(mScene != nullptr);
     ai_assert(mScene != nullptr);
 
 

+ 2 - 2
code/AssetLib/M3D/M3DImporter.h

@@ -89,8 +89,8 @@ private:
 	// helper functions
 	// helper functions
 	aiColor4D mkColor(uint32_t c);
 	aiColor4D mkColor(uint32_t c);
 	void convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned int posid, unsigned int orientid);
 	void convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned int posid, unsigned int orientid);
-	aiNode *findNode(aiNode *pNode, aiString name);
-	void calculateOffsetMatrix(aiNode *pNode, aiMatrix4x4 *m);
+    aiNode *findNode(aiNode *pNode, const aiString &name);
+    void calculateOffsetMatrix(aiNode *pNode, aiMatrix4x4 *m);
 	void populateMesh(const M3DWrapper &m3d, aiMesh *pMesh, std::vector<aiFace> *faces, std::vector<aiVector3D> *verteces,
 	void populateMesh(const M3DWrapper &m3d, aiMesh *pMesh, std::vector<aiFace> *faces, std::vector<aiVector3D> *verteces,
 			std::vector<aiVector3D> *normals, std::vector<aiVector3D> *texcoords, std::vector<aiColor4D> *colors,
 			std::vector<aiVector3D> *normals, std::vector<aiVector3D> *texcoords, std::vector<aiColor4D> *colors,
 			std::vector<unsigned int> *vertexids);
 			std::vector<unsigned int> *vertexids);

+ 50 - 18
code/AssetLib/M3D/M3DWrapper.h

@@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 */
 #ifndef AI_M3DWRAPPER_H_INC
 #ifndef AI_M3DWRAPPER_H_INC
 #define AI_M3DWRAPPER_H_INC
 #define AI_M3DWRAPPER_H_INC
+
 #if !(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER) || !ASSIMP_BUILD_NO_M3D_IMPORTER
 #if !(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER) || !ASSIMP_BUILD_NO_M3D_IMPORTER
 
 
 #include <memory>
 #include <memory>
@@ -55,44 +56,75 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // Assimp specific M3D configuration. Comment out these defines to remove functionality
 // Assimp specific M3D configuration. Comment out these defines to remove functionality
 //#define ASSIMP_USE_M3D_READFILECB
 //#define ASSIMP_USE_M3D_READFILECB
 
 
+// Share stb_image's PNG loader with other importers/exporters instead of bringing our own copy.
+#define STBI_ONLY_PNG
+#include <stb/stb_image.h>
+
 #include "m3d.h"
 #include "m3d.h"
 
 
 namespace Assimp {
 namespace Assimp {
+
 class IOSystem;
 class IOSystem;
 
 
+/// brief   The M3D-Wrapper, provudes c++ access to the data.
 class M3DWrapper {
 class M3DWrapper {
-	m3d_t *m3d_ = nullptr;
-	unsigned char *saved_output_ = nullptr;
-
 public:
 public:
-	// Construct an empty M3D model
+	/// Construct an empty M3D model
 	explicit M3DWrapper();
 	explicit M3DWrapper();
 
 
-	// Construct an M3D model from provided buffer
-	// NOTE: The m3d.h SDK function does not mark the data as const. Have assumed it does not write.
-	// BUG: SECURITY: The m3d.h SDK cannot be informed of the buffer size. BUFFER OVERFLOW IS CERTAIN
+	/// Construct an M3D model from provided buffer
+	/// @note The m3d.h SDK function does not mark the data as const. Have assumed it does not write.
+	/// BUG: SECURITY: The m3d.h SDK cannot be informed of the buffer size. BUFFER OVERFLOW IS CERTAIN
 	explicit M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer);
 	explicit M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer);
 
 
-	~M3DWrapper();
+	/// Theclasss destructor.
+    ~M3DWrapper();
 
 
-	void reset();
+	/// Will reset the wrapper, all data will become nullptr.
+    void reset();
 
 
-	// Name
-	inline std::string Name() const {
-		if (m3d_) return std::string(m3d_->name);
-		return std::string();
-	}
+	// The Name access, empty string returned when no m3d instance.
+	std::string Name() const;
 
 
-	// Execute a save
+	/// Executes a save.
 	unsigned char *Save(int quality, int flags, unsigned int &size);
 	unsigned char *Save(int quality, int flags, unsigned int &size);
+
+    /// Clearer
 	void ClearSave();
 	void ClearSave();
 
 
-	inline explicit operator bool() const { return m3d_ != nullptr; }
+    /// True for m3d instance exists.
+	explicit operator bool() const;
 
 
 	// Allow direct access to M3D API
 	// Allow direct access to M3D API
-	inline m3d_t *operator->() const { return m3d_; }
-	inline m3d_t *M3D() const { return m3d_; }
+	m3d_t *operator->() const;
+	m3d_t *M3D() const;
+
+private:
+	m3d_t *m3d_ = nullptr;
+	unsigned char *saved_output_ = nullptr;
 };
 };
+
+inline std::string M3DWrapper::Name() const {
+    if (nullptr != m3d_) {
+        if (nullptr != m3d_->name) {
+            return std::string(m3d_->name);
+        }
+    }
+    return std::string();
+}
+
+inline M3DWrapper::operator bool() const {
+    return m3d_ != nullptr;
+}
+
+inline m3d_t *M3DWrapper::operator->() const {
+    return m3d_;
+}
+
+inline m3d_t *M3DWrapper::M3D() const {
+    return m3d_;
+}
+
 } // namespace Assimp
 } // namespace Assimp
 
 
 #endif
 #endif

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 1224
code/AssetLib/M3D/m3d.h


+ 1 - 1
code/AssetLib/MD5/MD5Loader.cpp

@@ -485,7 +485,7 @@ void MD5Importer::LoadMD5MeshFile() {
                     }
                     }
 
 
                     MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
                     MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
-                    if (weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON) { 
+                    if (weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON) {
                         continue;
                         continue;
                     }
                     }
 
 

+ 2 - 2
code/AssetLib/MDC/MDCFileData.h

@@ -120,13 +120,13 @@ struct Surface {
     , ulFlags()
     , ulFlags()
     , ulNumCompFrames()
     , ulNumCompFrames()
     , ulNumBaseFrames()
     , ulNumBaseFrames()
-    , ulNumShaders() 
+    , ulNumShaders()
     , ulNumVertices()
     , ulNumVertices()
     , ulNumTriangles()
     , ulNumTriangles()
     , ulOffsetTriangles()
     , ulOffsetTriangles()
     , ulOffsetShaders()
     , ulOffsetShaders()
     , ulOffsetTexCoords()
     , ulOffsetTexCoords()
-    , ulOffsetBaseVerts() 
+    , ulOffsetBaseVerts()
     , ulOffsetCompVerts()
     , ulOffsetCompVerts()
     , ulOffsetFrameBaseFrames()
     , ulOffsetFrameBaseFrames()
     , ulOffsetFrameCompFrames()
     , ulOffsetFrameCompFrames()

+ 2 - 2
code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp

@@ -629,7 +629,7 @@ void HL1MDLLoader::read_meshes() {
             +-- bodypart --+-- model -- [mesh index, mesh index, ...]
             +-- bodypart --+-- model -- [mesh index, mesh index, ...]
             |              |
             |              |
             |              +-- model -- [mesh index, mesh index, ...]
             |              +-- model -- [mesh index, mesh index, ...]
-            |              |           
+            |              |
             |              ...
             |              ...
             |
             |
             |-- bodypart -- ...
             |-- bodypart -- ...
@@ -1298,7 +1298,7 @@ void HL1MDLLoader::read_global_info() {
 *   @note The structure of this method is taken from HL2 source code.
 *   @note The structure of this method is taken from HL2 source code.
 *   Although this is from HL2, it's implementation is almost identical
 *   Although this is from HL2, it's implementation is almost identical
 *   to code found in HL1 SDK. See HL1 and HL2 SDKs for more info.
 *   to code found in HL1 SDK. See HL1 and HL2 SDKs for more info.
-*   
+*
 *   source:
 *   source:
 *       HL1 source code.
 *       HL1 source code.
 *           file: studio_render.cpp
 *           file: studio_render.cpp

+ 4 - 4
code/AssetLib/MMD/MMDPmxParser.cpp

@@ -102,7 +102,7 @@ namespace pmx
 			const unsigned int targetSize = size * 3; // enough to encode
 			const unsigned int targetSize = size * 3; // enough to encode
 			char *targetStart = new char[targetSize];
 			char *targetStart = new char[targetSize];
             std::memset(targetStart, 0, targetSize * sizeof(char));
             std::memset(targetStart, 0, targetSize * sizeof(char));
-            
+
             utf8::utf16to8( sourceStart, sourceStart + size/2, targetStart );
             utf8::utf16to8( sourceStart, sourceStart + size/2, targetStart );
 
 
 			std::string result(targetStart);
 			std::string result(targetStart);
@@ -516,13 +516,13 @@ namespace pmx
 		stream->read((char*) magic, sizeof(char) * 4);
 		stream->read((char*) magic, sizeof(char) * 4);
 		if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
 		if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
         {
         {
-      throw DeadlyImportError("MMD: Invalid magic number.");
-    }
+            throw DeadlyImportError("MMD: Invalid magic number.");
+        }
 		stream->read((char*) &version, sizeof(float));
 		stream->read((char*) &version, sizeof(float));
 		if (version != 2.0f && version != 2.1f)
 		if (version != 2.0f && version != 2.1f)
 		{
 		{
             throw DeadlyImportError("MMD: Unsupported version (must be 2.0 or 2.1): ", ai_to_string(version));
             throw DeadlyImportError("MMD: Unsupported version (must be 2.0 or 2.1): ", ai_to_string(version));
-    }
+        }
 		this->setting.Read(stream);
 		this->setting.Read(stream);
 
 
 		this->model_name = ReadString(stream, setting.encoding);
 		this->model_name = ReadString(stream, setting.encoding);

+ 5 - 5
code/AssetLib/OFF/OFFLoader.cpp

@@ -138,7 +138,7 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
     const char* car = buffer;
     const char* car = buffer;
     const char* end = buffer + mBuffer2.size();
     const char* end = buffer + mBuffer2.size();
     NextToken(&car, end);
     NextToken(&car, end);
-    
+
     if (car < end - 2 && car[0] == 'S' && car[1] == 'T') {
     if (car < end - 2 && car[0] == 'S' && car[1] == 'T') {
       hasTexCoord = true; car += 2;
       hasTexCoord = true; car += 2;
     }
     }
@@ -164,7 +164,7 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
       dimensions = 3;
       dimensions = 3;
       hasHomogenous = false;
       hasHomogenous = false;
       NextToken(&car, end);
       NextToken(&car, end);
-      
+
       // at this point the next token should be an integer number
       // at this point the next token should be an integer number
       if (car >= end - 1 || *car < '0' || *car > '9') {
       if (car >= end - 1 || *car < '0' || *car > '9') {
 	throw DeadlyImportError("OFF: Header is invalid");
 	throw DeadlyImportError("OFF: Header is invalid");
@@ -223,7 +223,7 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
             ASSIMP_LOG_ERROR("OFF: The number of verts in the header is incorrect");
             ASSIMP_LOG_ERROR("OFF: The number of verts in the header is incorrect");
             break;
             break;
         }
         }
-        aiVector3D& v = mesh->mVertices[i];	
+        aiVector3D& v = mesh->mVertices[i];
         sz = line;
         sz = line;
 
 
 	// helper array to write a for loop over possible dimension values
 	// helper array to write a for loop over possible dimension values
@@ -255,7 +255,7 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
 	    SkipSpaces(&sz);
 	    SkipSpaces(&sz);
 	    fast_atoreal_move<ai_real>(sz,(ai_real&)n.z);
 	    fast_atoreal_move<ai_real>(sz,(ai_real&)n.z);
 	}
 	}
-	
+
 	// reading colors is a pain because the specification says it can be
 	// reading colors is a pain because the specification says it can be
 	// integers or floats, and any number of them between 1 and 4 included,
 	// integers or floats, and any number of them between 1 and 4 included,
 	// until the next comment or end of line
 	// until the next comment or end of line
@@ -321,7 +321,7 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
         ++i;
         ++i;
         ++faces;
         ++faces;
     }
     }
-    
+
     // generate the output node graph
     // generate the output node graph
     pScene->mRootNode = new aiNode();
     pScene->mRootNode = new aiNode();
     pScene->mRootNode->mName.Set("<OFFRoot>");
     pScene->mRootNode->mName.Set("<OFFRoot>");

+ 9 - 9
code/AssetLib/Obj/ObjExporter.h

@@ -67,7 +67,7 @@ public:
     ~ObjExporter();
     ~ObjExporter();
     std::string GetMaterialLibName();
     std::string GetMaterialLibName();
     std::string GetMaterialLibFileName();
     std::string GetMaterialLibFileName();
-    
+
     /// public string-streams to write all output into
     /// public string-streams to write all output into
     std::ostringstream mOutput, mOutputMat;
     std::ostringstream mOutput, mOutputMat;
 
 
@@ -137,13 +137,13 @@ private:
         }
         }
     };
     };
 
 
-    struct aiVectorCompare { 
-        bool operator() (const aiVector3D& a, const aiVector3D& b) const { 
-            if(a.x < b.x) return true; 
-            if(a.x > b.x) return false; 
-            if(a.y < b.y) return true; 
-            if(a.y > b.y) return false; 
-            if(a.z < b.z) return true; 
+    struct aiVectorCompare {
+        bool operator() (const aiVector3D& a, const aiVector3D& b) const {
+            if(a.x < b.x) return true;
+            if(a.x > b.x) return false;
+            if(a.y < b.y) return true;
+            if(a.y > b.y) return false;
+            if(a.z < b.z) return true;
             return false;
             return false;
         }
         }
     };
     };
@@ -153,7 +153,7 @@ private:
         int mNextIndex;
         int mNextIndex;
         typedef std::map<T, int, Compare> dataType;
         typedef std::map<T, int, Compare> dataType;
         dataType vecMap;
         dataType vecMap;
-    
+
     public:
     public:
         indexMap()
         indexMap()
         : mNextIndex(1) {
         : mNextIndex(1) {

+ 2 - 2
code/AssetLib/Obj/ObjFileImporter.cpp

@@ -162,7 +162,7 @@ void ObjFileImporter::InternReadFile(const std::string &file, aiScene *pScene, I
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 //  Create the data from parsed obj-file
 //  Create the data from parsed obj-file
 void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene *pScene) {
 void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene *pScene) {
-    if (0L == pModel) {
+    if (nullptr == pModel) {
         return;
         return;
     }
     }
 
 
@@ -468,7 +468,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
             }
             }
 
 
             // Copy all vertex colors
             // Copy all vertex colors
-            if (!pModel->m_VertexColors.empty()) {
+            if (vertex < pModel->m_VertexColors.size()) {
                 const aiVector3D &color = pModel->m_VertexColors[vertex];
                 const aiVector3D &color = pModel->m_VertexColors[vertex];
                 pMesh->mColors[0][newIndex] = aiColor4D(color.x, color.y, color.z, 1.0);
                 pMesh->mColors[0][newIndex] = aiColor4D(color.x, color.y, color.z, 1.0);
             }
             }

+ 1 - 1
code/AssetLib/Obj/ObjFileMtlImporter.cpp

@@ -146,7 +146,7 @@ void ObjFileMtlImporter::load() {
                     ++m_DataIt;
                     ++m_DataIt;
                     ai_real d;
                     ai_real d;
                     getFloatValue(d);
                     getFloatValue(d);
-                    m_pModel->m_pCurrentMaterial->alpha = static_cast<ai_real>(1.0) - d;                    
+                    m_pModel->m_pCurrentMaterial->alpha = static_cast<ai_real>(1.0) - d;
                 }
                 }
                 m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
                 m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
             } break;
             } break;

+ 2 - 2
code/AssetLib/Ogre/OgreMaterial.cpp

@@ -415,8 +415,8 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr
 
 
             // User defined Assimp config property to detect texture type from filename.
             // User defined Assimp config property to detect texture type from filename.
             if (m_detectTextureTypeFromFilename) {
             if (m_detectTextureTypeFromFilename) {
-                size_t posSuffix = textureRef.find_last_of(".");
-                size_t posUnderscore = textureRef.find_last_of("_");
+                size_t posSuffix = textureRef.find_last_of('.');
+                size_t posUnderscore = textureRef.find_last_of('_');
 
 
                 if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) {
                 if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) {
                     string identifier = ai_tolower(textureRef.substr(posUnderscore, posSuffix - posUnderscore));
                     string identifier = ai_tolower(textureRef.substr(posUnderscore, posSuffix - posUnderscore));

+ 6 - 2
code/AssetLib/Ply/PlyParser.cpp

@@ -419,8 +419,7 @@ bool PLY::DOM::ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char>
         if (PLY::Element::ParseElement(streamBuffer, buffer, &out)) {
         if (PLY::Element::ParseElement(streamBuffer, buffer, &out)) {
             // add the element to the list of elements
             // add the element to the list of elements
             alElements.push_back(out);
             alElements.push_back(out);
-        } else if ( TokenMatch(buffer, "end_header\r", 11) || //checks for header end with /r/n ending
-                    TokenMatch(buffer, "end_header", 10)) { //checks for /n ending, if it doesn't end with /r/n
+        } else if (TokenMatch(buffer, "end_header", 10)) { //checks for /n ending, if it doesn't end with /r/n
             // we have reached the end of the header
             // we have reached the end of the header
             break;
             break;
         } else {
         } else {
@@ -501,6 +500,11 @@ bool PLY::DOM::ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, DOM *p_pc
     }
     }
 
 
     streamBuffer.getNextBlock(buffer);
     streamBuffer.getNextBlock(buffer);
+
+    // remove first char if it's /n in case of file with /r/n
+    if (((char *)&buffer[0])[0] == '\n')
+        buffer.erase(buffer.begin(), buffer.begin() + 1);
+
     unsigned int bufferSize = static_cast<unsigned int>(buffer.size());
     unsigned int bufferSize = static_cast<unsigned int>(buffer.size());
     const char *pCur = (char *)&buffer[0];
     const char *pCur = (char *)&buffer[0];
     if (!p_pcOut->ParseElementInstanceListsBinary(streamBuffer, buffer, pCur, bufferSize, loader, p_bBE)) {
     if (!p_pcOut->ParseElementInstanceListsBinary(streamBuffer, buffer, pCur, bufferSize, loader, p_bBE)) {

+ 2 - 2
code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp

@@ -99,7 +99,7 @@ static void extractIds(const std::string &key, int &id1, int &id2) {
         return;
         return;
     }
     }
 
 
-    const std::string::size_type pos = key.find(".");
+    const std::string::size_type pos = key.find('.');
     if (std::string::npos == pos) {
     if (std::string::npos == pos) {
         return;
         return;
     }
     }
@@ -208,7 +208,7 @@ void Q3BSPFileImporter::separateMapName(const std::string &importName, std::stri
         return;
         return;
     }
     }
 
 
-    const std::string::size_type pos = importName.rfind(",");
+    const std::string::size_type pos = importName.rfind(',');
     if (std::string::npos == pos) {
     if (std::string::npos == pos) {
         archiveName = importName;
         archiveName = importName;
         return;
         return;

+ 1 - 1
code/AssetLib/SMD/SMDLoader.cpp

@@ -438,7 +438,7 @@ void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent) {
             pc->mTransformation = bone.sAnim.asKeys[0].matrix;
             pc->mTransformation = bone.sAnim.asKeys[0].matrix;
         }
         }
 
 
-        if (bone.iParent == static_cast<uint32_t>(-1)) { 
+        if (bone.iParent == static_cast<uint32_t>(-1)) {
             bone.mOffsetMatrix = pc->mTransformation;
             bone.mOffsetMatrix = pc->mTransformation;
         } else {
         } else {
             bone.mOffsetMatrix = asBones[bone.iParent].mOffsetMatrix * pc->mTransformation;
             bone.mOffsetMatrix = asBones[bone.iParent].mOffsetMatrix * pc->mTransformation;

+ 5 - 4
code/AssetLib/STEPParser/STEPFileReader.cpp

@@ -49,21 +49,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "STEPFileEncoding.h"
 #include "STEPFileEncoding.h"
 #include <assimp/TinyFormatter.h>
 #include <assimp/TinyFormatter.h>
 #include <assimp/fast_atof.h>
 #include <assimp/fast_atof.h>
-#include <memory>
 #include <functional>
 #include <functional>
+#include <memory>
+#include <utility>
 
 
 using namespace Assimp;
 using namespace Assimp;
 
 
 namespace EXPRESS = STEP::EXPRESS;
 namespace EXPRESS = STEP::EXPRESS;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = "")
+std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = std::string())
 {
 {
     return line == STEP::SyntaxError::LINE_NOT_SPECIFIED ? prefix+s : static_cast<std::string>( (Formatter::format(),prefix,"(line ",line,") ",s) );
     return line == STEP::SyntaxError::LINE_NOT_SPECIFIED ? prefix+s : static_cast<std::string>( (Formatter::format(),prefix,"(line ",line,") ",s) );
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-std::string AddEntityID(const std::string& s,uint64_t entity /*= ENTITY_NOT_SPECIFIED*/, const std::string& prefix = "")
+std::string AddEntityID(const std::string& s,uint64_t entity /*= ENTITY_NOT_SPECIFIED*/, const std::string& prefix = std::string())
 {
 {
     return entity == STEP::TypeError::ENTITY_NOT_SPECIFIED ? prefix+s : static_cast<std::string>( (Formatter::format(),prefix,"(entity #",entity,") ",s));
     return entity == STEP::TypeError::ENTITY_NOT_SPECIFIED ? prefix+s : static_cast<std::string>( (Formatter::format(),prefix,"(entity #",entity,") ",s));
 }
 }
@@ -87,7 +88,7 @@ static const char *ISO_Token         = "ISO-10303-21;";
 static const char *FILE_SCHEMA_Token = "FILE_SCHEMA";
 static const char *FILE_SCHEMA_Token = "FILE_SCHEMA";
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) {
 STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) {
-    std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
+    std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(std::move(stream)));
     std::unique_ptr<STEP::DB> db = std::unique_ptr<STEP::DB>(new STEP::DB(reader));
     std::unique_ptr<STEP::DB> db = std::unique_ptr<STEP::DB>(new STEP::DB(reader));
 
 
     LineSplitter &splitter = db->GetSplitter();
     LineSplitter &splitter = db->GetSplitter();

+ 4 - 4
code/AssetLib/STL/STLExporter.cpp

@@ -69,7 +69,7 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
     if (exporter.mOutput.fail()) {
     if (exporter.mOutput.fail()) {
         throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
         throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
     }
     }
-    
+
     // we're still here - export successfully completed. Write the file.
     // we're still here - export successfully completed. Write the file.
     std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
     std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
     if (outfile == nullptr) {
     if (outfile == nullptr) {
@@ -88,7 +88,7 @@ void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene*
     if (exporter.mOutput.fail()) {
     if (exporter.mOutput.fail()) {
         throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
         throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
     }
     }
-    
+
     // we're still here - export successfully completed. Write the file.
     // we're still here - export successfully completed. Write the file.
     std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wb"));
     std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wb"));
     if (outfile == nullptr) {
     if (outfile == nullptr) {
@@ -139,9 +139,9 @@ STLExporter::STLExporter(const char* _filename, const aiScene* pScene, bool expo
         if (exportPointClouds) {
         if (exportPointClouds) {
             WritePointCloud("Assimp_Pointcloud", pScene );
             WritePointCloud("Assimp_Pointcloud", pScene );
             return;
             return;
-        } 
+        }
 
 
-        // Export the assimp mesh 
+        // Export the assimp mesh
         const std::string name = "AssimpScene";
         const std::string name = "AssimpScene";
         mOutput << SolidToken << " " << name << endl;
         mOutput << SolidToken << " " << name << endl;
         for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
         for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {

+ 2 - 2
code/AssetLib/STL/STLLoader.cpp

@@ -372,7 +372,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
             pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
             pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
             for (size_t i=0; i<pMesh->mNumVertices; ++i ) {
             for (size_t i=0; i<pMesh->mNumVertices; ++i ) {
                 pMesh->mVertices[i].x = positionBuffer[i].x;
                 pMesh->mVertices[i].x = positionBuffer[i].x;
-                pMesh->mVertices[i].y = positionBuffer[i].y;                
+                pMesh->mVertices[i].y = positionBuffer[i].y;
                 pMesh->mVertices[i].z = positionBuffer[i].z;
                 pMesh->mVertices[i].z = positionBuffer[i].z;
             }
             }
             positionBuffer.clear();
             positionBuffer.clear();
@@ -382,7 +382,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
             pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
             pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
             for (size_t i=0; i<pMesh->mNumVertices; ++i ) {
             for (size_t i=0; i<pMesh->mNumVertices; ++i ) {
                 pMesh->mNormals[i].x = normalBuffer[i].x;
                 pMesh->mNormals[i].x = normalBuffer[i].x;
-                pMesh->mNormals[i].y = normalBuffer[i].y;                
+                pMesh->mNormals[i].y = normalBuffer[i].y;
                 pMesh->mNormals[i].z = normalBuffer[i].z;
                 pMesh->mNormals[i].z = normalBuffer[i].z;
             }
             }
             normalBuffer.clear();
             normalBuffer.clear();

+ 2 - 2
code/AssetLib/Step/STEPFile.h

@@ -634,7 +634,7 @@ private:
 };
 };
 
 
 template <typename T>
 template <typename T>
-inline bool operator==(std::shared_ptr<LazyObject> lo, T whatever) {
+inline bool operator==(const std::shared_ptr<LazyObject> &lo, T whatever) {
     return *lo == whatever; // XXX use std::forward if we have 0x
     return *lo == whatever; // XXX use std::forward if we have 0x
 }
 }
 
 
@@ -816,7 +816,7 @@ public:
     typedef std::pair<RefMap::const_iterator, RefMap::const_iterator> RefMapRange;
     typedef std::pair<RefMap::const_iterator, RefMap::const_iterator> RefMapRange;
 
 
 private:
 private:
-    DB(std::shared_ptr<StreamReaderLE> reader) :
+    DB(const std::shared_ptr<StreamReaderLE> &reader) :
             reader(reader), splitter(*reader, true, true), evaluated_count(), schema(nullptr) {}
             reader(reader), splitter(*reader, true, true), evaluated_count(), schema(nullptr) {}
 
 
 public:
 public:

+ 79 - 47
code/AssetLib/Step/StepExporter.cpp

@@ -175,12 +175,11 @@ void StepExporter::WriteFile()
     fColor.b = 0.8f;
     fColor.b = 0.8f;
 
 
     int ind = 100; // the start index to be used
     int ind = 100; // the start index to be used
-    int faceEntryLen = 30; // number of entries for a triangle/face
+    std::vector<int> faceEntryLen; // numbers of entries for a triangle/face
     // prepare unique (count triangles and vertices)
     // prepare unique (count triangles and vertices)
 
 
     VectorIndexUMap uniqueVerts; // use a map to reduce find complexity to log(n)
     VectorIndexUMap uniqueVerts; // use a map to reduce find complexity to log(n)
     VectorIndexUMap::iterator it;
     VectorIndexUMap::iterator it;
-    int countFace = 0;
 
 
     for (unsigned int i=0; i<mScene->mNumMeshes; ++i)
     for (unsigned int i=0; i<mScene->mNumMeshes; ++i)
     {
     {
@@ -189,7 +188,7 @@ void StepExporter::WriteFile()
         {
         {
             aiFace* face = &(mesh->mFaces[j]);
             aiFace* face = &(mesh->mFaces[j]);
 
 
-            if (face->mNumIndices == 3) countFace++;
+            if (face->mNumIndices >= 3) faceEntryLen.push_back(15 + 5 * face->mNumIndices);
         }
         }
         for (unsigned int j=0; j<mesh->mNumVertices; ++j)
         for (unsigned int j=0; j<mesh->mNumVertices; ++j)
         {
         {
@@ -218,10 +217,13 @@ void StepExporter::WriteFile()
     // write the top of data
     // write the top of data
     mOutput << "DATA" << endstr;
     mOutput << "DATA" << endstr;
     mOutput << "#1=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION(' ',(";
     mOutput << "#1=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION(' ',(";
-    for (int i=0; i<countFace; ++i)
+    size_t countFace = faceEntryLen.size();
+    size_t faceLenIndex = ind + 2 * uniqueVerts.size();
+    for (size_t i=0; i<countFace; ++i)
     {
     {
-        mOutput << "#" << i*faceEntryLen + ind + 2*uniqueVerts.size();
+        mOutput << "#" << faceLenIndex;
         if (i!=countFace-1) mOutput << ",";
         if (i!=countFace-1) mOutput << ",";
+        faceLenIndex += faceEntryLen[i];
     }
     }
     mOutput << "),#6)" << endstr;
     mOutput << "),#6)" << endstr;
 
 
@@ -253,10 +255,12 @@ void StepExporter::WriteFile()
     mOutput << "#27=DIRECTION('',(1.0,0.0,0.0))" << endstr;
     mOutput << "#27=DIRECTION('',(1.0,0.0,0.0))" << endstr;
     mOutput << "#28= (NAMED_UNIT(#21)LENGTH_UNIT()SI_UNIT(.MILLI.,.METRE.))" << endstr;
     mOutput << "#28= (NAMED_UNIT(#21)LENGTH_UNIT()SI_UNIT(.MILLI.,.METRE.))" << endstr;
     mOutput << "#29=CLOSED_SHELL('',(";
     mOutput << "#29=CLOSED_SHELL('',(";
-    for (int i=0; i<countFace; ++i)
+    faceLenIndex = ind + 2 * uniqueVerts.size() + 8;
+    for (size_t i=0; i<countFace; ++i)
     {
     {
-        mOutput << "#" << i*faceEntryLen + ind + 2*uniqueVerts.size() + 8;
+        mOutput << "#" << faceLenIndex;
         if (i!=countFace-1) mOutput << ",";
         if (i!=countFace-1) mOutput << ",";
+        faceLenIndex += faceEntryLen[i];
     }
     }
     mOutput << "))" << endstr;
     mOutput << "))" << endstr;
 
 
@@ -289,27 +293,28 @@ void StepExporter::WriteFile()
         {
         {
             aiFace* face = &(mesh->mFaces[j]);
             aiFace* face = &(mesh->mFaces[j]);
 
 
-            if (face->mNumIndices != 3) continue;
-
-            aiVector3D* v1 = &(mesh->mVertices[face->mIndices[0]]);
-            aiVector3D* v2 = &(mesh->mVertices[face->mIndices[1]]);
-            aiVector3D* v3 = &(mesh->mVertices[face->mIndices[2]]);
-            aiVector3D dv12 = *v2 - *v1;
-            aiVector3D dv23 = *v3 - *v2;
-            aiVector3D dv31 = *v1 - *v3;
-            aiVector3D dv13 = *v3 - *v1;
-            dv12.Normalize();
-            dv23.Normalize();
-            dv31.Normalize();
-            dv13.Normalize();
-
-            aiVector3D dvY = dv12;
-            aiVector3D dvX = dvY ^ dv13;
-            dvX.Normalize();
+            const int numIndices = face->mNumIndices;
+            if (numIndices < 3) continue;
 
 
-            int pid1 = uniqueVerts.find(v1)->second;
-            int pid2 = uniqueVerts.find(v2)->second;
-            int pid3 = uniqueVerts.find(v3)->second;
+            std::vector<int> pidArray(numIndices, -1); // vertex id
+            std::vector<aiVector3D> dvArray(numIndices); // edge dir
+            for (int k = 0; k < numIndices; ++k)
+            {
+                aiVector3D *v1 = &(mesh->mVertices[face->mIndices[k]]);
+                pidArray[k] = uniqueVerts.find(v1)->second;
+
+                aiVector3D *v2 = nullptr;
+                if (k + 1 == numIndices)
+                    v2 = &(mesh->mVertices[face->mIndices[0]]);
+                else
+                    v2 = &(mesh->mVertices[face->mIndices[k + 1]]);
+                dvArray[k] = *v2 - *v1;
+                dvArray[k].Normalize();
+            }
+
+            aiVector3D dvY = dvArray[1];
+            aiVector3D dvX = dvY ^ dvArray[0];
+            dvX.Normalize();
 
 
             // mean vertex color for the face if available
             // mean vertex color for the face if available
             if (mesh->HasVertexColors(0))
             if (mesh->HasVertexColors(0))
@@ -339,35 +344,62 @@ void StepExporter::WriteFile()
 
 
             /* 2 directions of the plane */
             /* 2 directions of the plane */
             mOutput << "#" << sid+9 << "=PLANE('',#" << sid+10 << ")" << endstr;
             mOutput << "#" << sid+9 << "=PLANE('',#" << sid+10 << ")" << endstr;
-            mOutput << "#" << sid+10 << "=AXIS2_PLACEMENT_3D('',#" << pid1 << ", #" << sid+11 << ",#" << sid+12 << ")" << endstr;
+            mOutput << "#" << sid+10 << "=AXIS2_PLACEMENT_3D('',#" << pidArray[0] << ",#" << sid+11 << ",#" << sid+12 << ")" << endstr;
 
 
             mOutput << "#" << sid + 11 << "=DIRECTION('',(" << dvX.x << "," << dvX.y << "," << dvX.z << "))" << endstr;
             mOutput << "#" << sid + 11 << "=DIRECTION('',(" << dvX.x << "," << dvX.y << "," << dvX.z << "))" << endstr;
             mOutput << "#" << sid + 12 << "=DIRECTION('',(" << dvY.x << "," << dvY.y << "," << dvY.z << "))" << endstr;
             mOutput << "#" << sid + 12 << "=DIRECTION('',(" << dvY.x << "," << dvY.y << "," << dvY.z << "))" << endstr;
 
 
             mOutput << "#" << sid+13 << "=FACE_BOUND('',#" << sid+14 << ",.T.)" << endstr;
             mOutput << "#" << sid+13 << "=FACE_BOUND('',#" << sid+14 << ",.T.)" << endstr;
-            mOutput << "#" << sid+14 << "=EDGE_LOOP('',(#" << sid+15 << ",#" << sid+16 << ",#" << sid+17 << "))" << endstr;
+            mOutput << "#" << sid+14 << "=EDGE_LOOP('',(";
+            int edgeLoopStart = sid + 15;
+            for (int k = 0; k < numIndices; ++k)
+            {
+                if (k == 0)
+                    mOutput << "#";
+                else
+                    mOutput << ",#";
+                mOutput << edgeLoopStart + k;
+            }
+            mOutput << "))" << endstr;
 
 
             /* edge loop  */
             /* edge loop  */
-            mOutput << "#" << sid+15 << "=ORIENTED_EDGE('',*,*,#" << sid+18 << ",.T.)" << endstr;
-            mOutput << "#" << sid+16 << "=ORIENTED_EDGE('',*,*,#" << sid+19 << ",.T.)" << endstr;
-            mOutput << "#" << sid+17 << "=ORIENTED_EDGE('',*,*,#" << sid+20 << ",.T.)" << endstr;
+            int orientedEdgesStart = edgeLoopStart + numIndices;
+            for (int k=0; k < numIndices; k++)
+            {
+                mOutput << "#" << edgeLoopStart+k << "=ORIENTED_EDGE('',*,*,#" << orientedEdgesStart + k << ",.T.)" << endstr;
+            }
 
 
             /* oriented edges */
             /* oriented edges */
-            mOutput << "#" << sid+18 << "=EDGE_CURVE('',#" << pid1+1 << ",#" << pid2+1 << ",#" << sid+21 << ",.F.)" << endstr;
-            mOutput << "#" << sid+19 << "=EDGE_CURVE('',#" << pid2+1 << ",#" << pid3+1 << ",#" << sid+22 << ",.T.)" << endstr;
-            mOutput << "#" << sid+20 << "=EDGE_CURVE('',#" << pid3+1 << ",#" << pid1+1 << ",#" << sid+23 << ",.T.)" << endstr;
-
-            /* 3 lines and 3 vectors for the lines for the 3 edge curves */
-            mOutput << "#" << sid+21 << "=LINE('',#" << pid1 << ",#" << sid+24 << ")" << endstr;
-            mOutput << "#" << sid+22 << "=LINE('',#" << pid2 << ",#" << sid+25 << ")" << endstr;
-            mOutput << "#" << sid+23 << "=LINE('',#" << pid3 << ",#" << sid+26 << ")" << endstr;
-            mOutput << "#" << sid+24 << "=VECTOR('',#" << sid+27 << ",1.0)" << endstr;
-            mOutput << "#" << sid+25 << "=VECTOR('',#" << sid+28 << ",1.0)" << endstr;
-            mOutput << "#" << sid+26 << "=VECTOR('',#" << sid+29 << ",1.0)" << endstr;
-            mOutput << "#" << sid+27 << "=DIRECTION('',(" << dv12.x << "," << dv12.y << "," << dv12.z << "))" << endstr;
-            mOutput << "#" << sid+28 << "=DIRECTION('',(" << dv23.x << "," << dv23.y << "," << dv23.z << "))" << endstr;
-            mOutput << "#" << sid+29 << "=DIRECTION('',(" << dv31.x << "," << dv31.y << "," << dv31.z << "))" << endstr;
-            ind += faceEntryLen; // increase counter
+            int lineStart = orientedEdgesStart + numIndices;
+            for (int k=0; k < numIndices; ++k)
+            {
+                if (k == 0)
+                    mOutput << "#" << orientedEdgesStart+k << "=EDGE_CURVE('',#" << pidArray[k]+1 << ",#" << pidArray[k+1]+1 << ",#" << lineStart+k << ",.F.)" << endstr;
+                else if (k+1 == numIndices)
+                    mOutput << "#" << orientedEdgesStart+k << "=EDGE_CURVE('',#" << pidArray[k]+1 << ",#" << pidArray[0]+1 << ",#" << lineStart+k << ",.T.)" << endstr;
+                else
+                    mOutput << "#" << orientedEdgesStart+k << "=EDGE_CURVE('',#" << pidArray[k]+1 << ",#" << pidArray[k+1]+1 << ",#" << lineStart+k << ",.T.)" << endstr;
+            }
+
+            /* n lines and n vectors for the lines for the n edge curves */
+            int vectorStart = lineStart + numIndices;
+            for (int k=0; k < numIndices; ++k)
+            {
+                mOutput << "#" << lineStart+k << "=LINE('',#" << pidArray[k] << ",#" << vectorStart+k << ")" << endstr;
+            }
+
+            int directionStart = vectorStart + numIndices;
+            for (int k=0; k < numIndices; ++k)
+            {
+                mOutput << "#" << vectorStart+k << "=VECTOR('',#" << directionStart+k << ",1.0)" << endstr;
+            }
+
+            for (int k=0; k < numIndices; ++k)
+            {
+                const aiVector3D &dv = dvArray[k];
+                mOutput << "#" << directionStart + k << "=DIRECTION('',(" << dv.x << "," << dv.y << "," << dv.z << "))" << endstr;
+            }
+            ind += 15 + 5*numIndices; // increase counter
         }
         }
     }
     }
 
 

+ 3 - 3
code/AssetLib/X/XFileExporter.cpp

@@ -86,7 +86,7 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
     if (iDoTheExportThing.mOutput.fail()) {
     if (iDoTheExportThing.mOutput.fail()) {
         throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
         throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
     }
     }
-    
+
     // we're still here - export successfully completed. Write result to the given IOSYstem
     // we're still here - export successfully completed. Write result to the given IOSYstem
     std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
     std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
     if (outfile == nullptr) {
     if (outfile == nullptr) {
@@ -530,8 +530,8 @@ void XFileExporter::writePath(const aiString &path)
     while( str.find( "\\\\") != std::string::npos)
     while( str.find( "\\\\") != std::string::npos)
         str.replace( str.find( "\\\\"), 2, "\\");
         str.replace( str.find( "\\\\"), 2, "\\");
 
 
-    while( str.find( "\\") != std::string::npos)
-        str.replace( str.find( "\\"), 1, "/");
+    while (str.find('\\') != std::string::npos)
+        str.replace(str.find('\\'), 1, "/");
 
 
     mOutput << str;
     mOutput << str;
 
 

+ 3 - 3
code/AssetLib/X/XFileExporter.h

@@ -94,9 +94,9 @@ protected:
     void PushTag() { startstr.append( "  "); }
     void PushTag() { startstr.append( "  "); }
 
 
     /// Leaves an element, decreasing the indentation
     /// Leaves an element, decreasing the indentation
-    void PopTag() { 
-        ai_assert( startstr.length() > 1); 
-        startstr.erase( startstr.length() - 2); 
+    void PopTag() {
+        ai_assert( startstr.length() > 1);
+        startstr.erase( startstr.length() - 2);
     }
     }
 
 
 public:
 public:

+ 1 - 3
code/AssetLib/X/XFileImporter.cpp

@@ -667,9 +667,7 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Materi
 
 
                 // convert to lower case for easier comparison
                 // convert to lower case for easier comparison
                 for ( unsigned int c = 0; c < sz.length(); ++c ) {
                 for ( unsigned int c = 0; c < sz.length(); ++c ) {
-                    if ( isalpha( (unsigned char) sz[ c ] ) ) {
-                        sz[ c ] = (char) tolower( (unsigned char) sz[ c ] );
-                    }
+                    sz[ c ] = (char) tolower( (unsigned char) sz[ c ] );
                 }
                 }
 
 
                 // Place texture filename property under the corresponding name
                 // Place texture filename property under the corresponding name

+ 3 - 3
code/AssetLib/X3D/X3DExporter.hpp

@@ -63,9 +63,9 @@ class X3DExporter {
             // empty
             // empty
         }
         }
 
 
-        SAttribute(SAttribute && rhs) :
-                Name(std::move(rhs.Name)),
-                Value(std::move(rhs.Value)) {
+        SAttribute(SAttribute &&rhs) AI_NO_EXCEPT :
+                Name(rhs.Name),
+                Value(rhs.Value) {
             // empty
             // empty
         }
         }
     };
     };

+ 0 - 1
code/AssetLib/X3D/X3DImporter.cpp

@@ -2890,7 +2890,6 @@ void X3DImporter::Postprocess_CollectMetadata(const CX3DImporter_NodeElement &pN
     } // if( !meta_list.empty() )
     } // if( !meta_list.empty() )
 }
 }
 
 
-
 #endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
 #endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
 
 
 } // namespace Assimp
 } // namespace Assimp

+ 3 - 6
code/AssetLib/XGL/XGLLoader.cpp

@@ -240,7 +240,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 void XGLImporter::ReadWorld(XmlNode &node, TempScope &scope) {
 void XGLImporter::ReadWorld(XmlNode &node, TempScope &scope) {
     for (XmlNode &currentNode : node.children()) {
     for (XmlNode &currentNode : node.children()) {
         const std::string &s = ai_stdStrToLower(currentNode.name());
         const std::string &s = ai_stdStrToLower(currentNode.name());
-        
+
 		// XXX right now we'd skip <lighting> if it comes after
 		// XXX right now we'd skip <lighting> if it comes after
 		// <object> or <mesh>
 		// <object> or <mesh>
 		if (s == "lighting") {
 		if (s == "lighting") {
@@ -250,7 +250,7 @@ void XGLImporter::ReadWorld(XmlNode &node, TempScope &scope) {
 		}
 		}
 	}
 	}
 
 
-	aiNode *const nd = ReadObject(node, scope, true);
+	aiNode *const nd = ReadObject(node, scope);
 	if (!nd) {
 	if (!nd) {
 		ThrowException("failure reading <world>");
 		ThrowException("failure reading <world>");
 	}
 	}
@@ -296,16 +296,13 @@ aiLight *XGLImporter::ReadDirectionalLight(XmlNode &node) {
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-aiNode *XGLImporter::ReadObject(XmlNode &node, TempScope &scope, bool skipFirst/*, const char *closetag */) {
+aiNode *XGLImporter::ReadObject(XmlNode &node, TempScope &scope) {
 	aiNode *nd = new aiNode;
 	aiNode *nd = new aiNode;
 	std::vector<aiNode *> children;
 	std::vector<aiNode *> children;
 	std::vector<unsigned int> meshes;
 	std::vector<unsigned int> meshes;
 
 
 	try {
 	try {
 		for (XmlNode &child : node.children()) {
 		for (XmlNode &child : node.children()) {
-
-			skipFirst = false;
-
 			const std::string &s = ai_stdStrToLower(child.name());
 			const std::string &s = ai_stdStrToLower(child.name());
 			if (s == "mesh") {
 			if (s == "mesh") {
 				const size_t prev = scope.meshes_linear.size();
 				const size_t prev = scope.meshes_linear.size();

+ 1 - 1
code/AssetLib/XGL/XGLLoader.h

@@ -185,7 +185,7 @@ private:
     void ReadWorld(XmlNode &node, TempScope &scope);
     void ReadWorld(XmlNode &node, TempScope &scope);
     void ReadLighting(XmlNode &node, TempScope &scope);
     void ReadLighting(XmlNode &node, TempScope &scope);
     aiLight *ReadDirectionalLight(XmlNode &node);
     aiLight *ReadDirectionalLight(XmlNode &node);
-    aiNode *ReadObject(XmlNode &node, TempScope &scope, bool skipFirst = false/*, const char *closetag = "object"*/);
+    aiNode *ReadObject(XmlNode &node, TempScope &scope);
     bool ReadMesh(XmlNode &node, TempScope &scope);
     bool ReadMesh(XmlNode &node, TempScope &scope);
     void ReadMaterial(XmlNode &node, TempScope &scope);
     void ReadMaterial(XmlNode &node, TempScope &scope);
     aiVector2D ReadVec2(XmlNode &node);
     aiVector2D ReadVec2(XmlNode &node);

+ 4 - 6
code/AssetLib/glTF/glTFAsset.h

@@ -456,11 +456,10 @@ namespace glTF
 			/// \param [in] pDecodedData - pointer to decoded data array.
 			/// \param [in] pDecodedData - pointer to decoded data array.
 			/// \param [in] pDecodedData_Length - size of encoded region, in bytes.
 			/// \param [in] pDecodedData_Length - size of encoded region, in bytes.
 			/// \param [in] pID - ID of the region.
 			/// \param [in] pID - ID of the region.
-			SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID)
-				: Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID)
-			{}
+            SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID) :
+                    Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID) {}
 
 
-			/// \fn ~SEncodedRegion()
+            /// \fn ~SEncodedRegion()
 			/// Destructor.
 			/// Destructor.
 			~SEncodedRegion() { delete [] DecodedData; }
 			~SEncodedRegion() { delete [] DecodedData; }
 		};
 		};
@@ -1149,8 +1148,7 @@ namespace glTF
 
 
         void ReadExtensionsUsed(Document& doc);
         void ReadExtensionsUsed(Document& doc);
 
 
-
-        IOStream* OpenFile(std::string path, const char* mode, bool absolute = false);
+        IOStream *OpenFile(const std::string &path, const char *mode, bool absolute = false);
     };
     };
 
 
 }
 }

+ 1 - 1
code/AssetLib/glTF/glTFAsset.inl

@@ -1377,7 +1377,7 @@ inline void Asset::ReadExtensionsUsed(Document &doc) {
 #undef CHECK_EXT
 #undef CHECK_EXT
 }
 }
 
 
-inline IOStream *Asset::OpenFile(std::string path, const char *mode, bool absolute) {
+inline IOStream *Asset::OpenFile(const std::string& path, const char *mode, bool absolute) {
 #ifdef ASSIMP_API
 #ifdef ASSIMP_API
     (void)absolute;
     (void)absolute;
     return mIOSystem->Open(path, mode);
     return mIOSystem->Open(path, mode);

+ 3 - 3
code/AssetLib/glTF/glTFCommon.h

@@ -195,11 +195,11 @@ inline void CopyValue(const glTFCommon::mat4 &v, aiMatrix4x4 &o) {
 inline std::string getCurrentAssetDir(const std::string &pFile) {
 inline std::string getCurrentAssetDir(const std::string &pFile) {
     std::string path = pFile;
     std::string path = pFile;
     int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
     int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
-    if (pos != int(std::string::npos)) {
-        path = pFile.substr(0, pos + 1);
+    if (pos == int(std::string::npos)) {
+        return std::string();
     }
     }
 
 
-    return path;
+    return pFile.substr(0, pos + 1);
 }
 }
 #if _MSC_VER
 #if _MSC_VER
 #    pragma warning(pop)
 #    pragma warning(pop)

+ 2 - 2
code/AssetLib/glTF/glTFExporter.cpp

@@ -408,8 +408,7 @@ void glTFExporter::ExportMaterials()
  * Search through node hierarchy and find the node containing the given meshID.
  * Search through node hierarchy and find the node containing the given meshID.
  * Returns true on success, and false otherwise.
  * Returns true on success, and false otherwise.
  */
  */
-bool FindMeshNode(Ref<Node>& nodeIn, Ref<Node>& meshNode, std::string meshID)
-{
+bool FindMeshNode(Ref<Node> &nodeIn, Ref<Node> &meshNode, const std::string &meshID) {
     for (unsigned int i = 0; i < nodeIn->meshes.size(); ++i) {
     for (unsigned int i = 0; i < nodeIn->meshes.size(); ++i) {
         if (meshID.compare(nodeIn->meshes[i]->id) == 0) {
         if (meshID.compare(nodeIn->meshes[i]->id) == 0) {
           meshNode = nodeIn;
           meshNode = nodeIn;
@@ -530,6 +529,7 @@ void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buf
 
 
 #if defined(__has_warning)
 #if defined(__has_warning)
 #if __has_warning("-Wunused-but-set-variable")
 #if __has_warning("-Wunused-but-set-variable")
+#pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #endif
 #endif
 #endif
 #endif

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä