소스 검색

Merge branch 'master' into doc/find_degenerates_parameters

Kim Kulling 7 년 전
부모
커밋
6cde21bf2f
100개의 변경된 파일1260개의 추가작업 그리고 775개의 파일을 삭제
  1. 1 0
      .gitignore
  2. 1 1
      CMakeLists.txt
  3. 1 1
      Readme.md
  4. 2 3
      code/3DSConverter.cpp
  5. 1 1
      code/3DSExporter.cpp
  6. 1 1
      code/3DSExporter.h
  7. 73 11
      code/3DSHelper.h
  8. 11 11
      code/3DSLoader.cpp
  9. 2 2
      code/3DSLoader.h
  10. 4 4
      code/ACLoader.cpp
  11. 1 1
      code/ACLoader.h
  12. 1 1
      code/AMFImporter.cpp
  13. 2 2
      code/AMFImporter.hpp
  14. 2 2
      code/AMFImporter_Postprocess.cpp
  15. 9 10
      code/ASELoader.cpp
  16. 1 1
      code/ASELoader.h
  17. 3 3
      code/ASEParser.cpp
  18. 47 4
      code/ASEParser.h
  19. 1 1
      code/AssbinExporter.cpp
  20. 1 1
      code/AssbinLoader.cpp
  21. 1 1
      code/AssbinLoader.h
  22. 3 3
      code/Assimp.cpp
  23. 1 1
      code/B3DImporter.cpp
  24. 1 1
      code/B3DImporter.h
  25. 3 3
      code/BVHLoader.cpp
  26. 1 1
      code/BVHLoader.h
  27. 2 2
      code/BaseImporter.cpp
  28. 1 1
      code/BaseProcess.cpp
  29. 1 1
      code/BaseProcess.h
  30. 4 3
      code/Bitmap.cpp
  31. 1 1
      code/BlenderBMesh.h
  32. 3 3
      code/BlenderDNA.cpp
  33. 2 2
      code/BlenderDNA.h
  34. 1 1
      code/BlenderDNA.inl
  35. 4 4
      code/BlenderLoader.cpp
  36. 2 2
      code/BlenderLoader.h
  37. 1 1
      code/BlenderModifier.cpp
  38. 1 1
      code/BlenderModifier.h
  39. 1 1
      code/BlenderTessellator.h
  40. 1 1
      code/C4DImporter.cpp
  41. 2 2
      code/C4DImporter.h
  42. 63 55
      code/CMakeLists.txt
  43. 5 5
      code/COBLoader.cpp
  44. 2 2
      code/COBLoader.h
  45. 1 1
      code/COBScene.h
  46. 3 3
      code/CSMLoader.cpp
  47. 1 1
      code/CSMLoader.h
  48. 2 2
      code/CalcTangentsProcess.cpp
  49. 5 5
      code/ColladaExporter.cpp
  50. 1 1
      code/ColladaExporter.h
  51. 9 4
      code/ColladaLoader.cpp
  52. 1 1
      code/ColladaLoader.h
  53. 4 4
      code/ColladaParser.cpp
  54. 2 2
      code/ColladaParser.h
  55. 1 1
      code/ComputeUVMappingProcess.cpp
  56. 1 1
      code/CreateAnimMesh.cpp
  57. 1 1
      code/D3MFExporter.cpp
  58. 3 3
      code/D3MFImporter.cpp
  59. 1 1
      code/D3MFImporter.h
  60. 1 1
      code/D3MFOpcPackage.cpp
  61. 1 1
      code/D3MFOpcPackage.h
  62. 4 4
      code/DXFHelper.h
  63. 2 2
      code/DXFLoader.cpp
  64. 1 1
      code/DXFLoader.h
  65. 2 1
      code/DefaultIOStream.cpp
  66. 76 31
      code/DefaultIOSystem.cpp
  67. 1 1
      code/DefaultLogger.cpp
  68. 147 0
      code/EmbedTexturesProcess.cpp
  69. 84 0
      code/EmbedTexturesProcess.h
  70. 2 2
      code/Exporter.cpp
  71. 16 23
      code/FBXBinaryTokenizer.cpp
  72. 132 433
      code/FBXConverter.cpp
  73. 382 0
      code/FBXConverter.h
  74. 4 5
      code/FBXDocument.cpp
  75. 1 2
      code/FBXDocument.h
  76. 1 1
      code/FBXDocumentUtil.h
  77. 4 4
      code/FBXImportSettings.h
  78. 4 5
      code/FBXImporter.cpp
  79. 2 2
      code/FBXImporter.h
  80. 1 1
      code/FBXMaterial.cpp
  81. 8 2
      code/FBXMeshGeometry.cpp
  82. 23 18
      code/FBXParser.cpp
  83. 4 5
      code/FBXParser.h
  84. 1 4
      code/FBXProperties.cpp
  85. 16 4
      code/FBXProperties.h
  86. 2 4
      code/FBXTokenizer.cpp
  87. 1 1
      code/FBXUtil.cpp
  88. 5 5
      code/FIReader.cpp
  89. 2 0
      code/FIReader.hpp
  90. 2 2
      code/FileSystemFilter.h
  91. 1 1
      code/FindDegenerates.cpp
  92. 3 3
      code/FindInvalidDataProcess.cpp
  93. 1 1
      code/FixNormalsStep.cpp
  94. 2 2
      code/GenFaceNormalsProcess.cpp
  95. 2 2
      code/GenVertexNormalsProcess.cpp
  96. 1 1
      code/HMPLoader.h
  97. 1 1
      code/IFF.h
  98. 5 5
      code/IRRLoader.cpp
  99. 1 1
      code/IRRLoader.h
  100. 3 3
      code/IRRMeshLoader.cpp

+ 1 - 0
.gitignore

@@ -60,6 +60,7 @@ test/gtest/src/gtest-stamp/Debug/gtest-build
 *.lib
 test/gtest/src/gtest-stamp/Debug/
 tools/assimp_view/assimp_viewer.vcxproj.user
+*.pyc
 
 # Unix editor backups
 *~

+ 1 - 1
CMakeLists.txt

@@ -103,6 +103,7 @@ OPTION ( BUILD_DOCS
   OFF
 )
 
+# Use subset of Windows.h
 if (WIN32)
   ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
 endif()
@@ -203,7 +204,6 @@ IF( UNIX )
   INCLUDE(GNUInstallDirs)
 ENDIF( UNIX )
 
-
 # Grouped compiler settings
 IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
   # hide all not-exported symbols

+ 1 - 1
Readme.md

@@ -43,7 +43,7 @@ __Importers__:
 - AMJ
 - ASE
 - ASK
-- B3D;
+- B3D
 - BLEND (Blender)
 - BVH
 - COB

+ 2 - 3
code/3DSConverter.cpp

@@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "TargetAnimation.h"
 #include <assimp/scene.h>
 #include <assimp/DefaultLogger.hpp>
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
 #include <memory>
 #include <cctype>
 
@@ -127,9 +127,8 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
     if (cnt && idx == mScene->mMaterials.size())
     {
         // We need to create our own default material
-        D3DS::Material sMat;
+        D3DS::Material sMat("%%%DEFAULT");
         sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f);
-        sMat.mName = "%%%DEFAULT";
         mScene->mMaterials.push_back(sMat);
 
         DefaultLogger::get()->info("3DS: Generating default material");

+ 1 - 1
code/3DSExporter.cpp

@@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "3DSHelper.h"
 #include <assimp/SceneCombiner.h>
 #include "SplitLargeMeshes.h"
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
 #include <assimp/IOSystem.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/Exporter.hpp>

+ 1 - 1
code/3DSExporter.h

@@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <map>
 #include <memory>
 
-#include "StreamWriter.h"
+#include <assimp/StreamWriter.h>
 #include <assimp/material.h>
 
 struct aiScene;

+ 73 - 11
code/3DSHelper.h

@@ -44,10 +44,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_3DSFILEHELPER_H_INC
 #define AI_3DSFILEHELPER_H_INC
 
-#include "SpatialSort.h"
-#include "SmoothingGroups.h"
-#include "StringUtils.h"
-#include "qnan.h"
+#include <assimp/SpatialSort.h>
+#include <assimp/SmoothingGroups.h>
+#include <assimp/StringUtils.h>
+#include <assimp/qnan.h>
 #include <assimp/material.h>
 #include <assimp/camera.h>
 #include <assimp/light.h>
@@ -370,9 +370,14 @@ struct Texture
 /** Helper structure representing a 3ds material */
 struct Material
 {
-    //! Default constructor. Builds a default name for the material
-    Material()
-    : mDiffuse            ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black
+    //! Default constructor has been deleted
+    Material() = delete;
+
+
+    //! Constructor with explicit name
+    explicit Material(const std::string &name)
+    : mName(name)
+    , mDiffuse            ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black
     , mSpecularExponent   ( ai_real( 0.0 ) )
     , mShininessStrength  ( ai_real( 1.0 ) )
     , mShading(Discreet3DS::Gouraud)
@@ -380,13 +385,70 @@ struct Material
     , mBumpHeight         ( ai_real( 1.0 ) )
     , mTwoSided           (false)
     {
-        static int iCnt = 0;
+    }
 
-        char szTemp[128];
-        ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
-        mName = szTemp;
+
+    Material(const Material &other)            = default;
+    Material &operator=(const Material &other) = default;
+
+
+    //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
+    Material(Material &&other)
+    : 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))
+    , sTexDiffuse(std::move(other.sTexDiffuse))
+    , sTexOpacity(std::move(other.sTexOpacity))
+    , sTexSpecular(std::move(other.sTexSpecular))
+    , sTexReflective(std::move(other.sTexReflective))
+    , sTexBump(std::move(other.sTexBump))
+    , sTexEmissive(std::move(other.sTexEmissive))
+    , sTexShininess(std::move(other.sTexShininess))
+    , mBumpHeight(std::move(other.mBumpHeight))
+    , mEmissive(std::move(other.mEmissive))
+    , sTexAmbient(std::move(other.sTexAmbient))
+    , mTwoSided(std::move(other.mTwoSided))
+    {
     }
 
+
+    Material &operator=(Material &&other) {
+        if (this == &other) {
+            return *this;
+        }
+
+        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);
+        sTexDiffuse = std::move(other.sTexDiffuse);
+        sTexOpacity = std::move(other.sTexOpacity);
+        sTexSpecular = std::move(other.sTexSpecular);
+        sTexReflective = std::move(other.sTexReflective);
+        sTexBump = std::move(other.sTexBump);
+        sTexEmissive = std::move(other.sTexEmissive);
+        sTexShininess = std::move(other.sTexShininess);
+        mBumpHeight = std::move(other.mBumpHeight);
+        mEmissive = std::move(other.mEmissive);
+        sTexAmbient = std::move(other.sTexAmbient);
+        mTwoSided = std::move(other.mTwoSided);
+
+        return *this;
+    }
+
+
+    ~Material() {}
+
+
     //! Name of the material
     std::string mName;
     //! Diffuse color of the material

+ 11 - 11
code/3DSLoader.cpp

@@ -51,12 +51,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // internal headers
 #include "3DSLoader.h"
-#include "Macros.h"
+#include <assimp/Macros.h>
 #include <assimp/IOSystem.hpp>
 #include <assimp/scene.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/importerdesc.h>
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
 
 using namespace Assimp;
 
@@ -105,14 +105,14 @@ static const aiImporterDesc desc = {
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 Discreet3DSImporter::Discreet3DSImporter()
-    : stream(),
-    mLastNodeIndex(),
-    mCurrentNode(),
-    mRootNode(),
-    mScene(),
-    mMasterScale(),
-    bHasBG(),
-    bIsPrj()
+: stream()
+, mLastNodeIndex()
+, mCurrentNode()
+, mRootNode()
+, mScene()
+, mMasterScale()
+, bHasBG()
+, bIsPrj()
 {}
 
 // ------------------------------------------------------------------------------------------------
@@ -346,7 +346,7 @@ void Discreet3DSImporter::ParseObjectChunk()
     case Discreet3DS::CHUNK_MAT_MATERIAL:
 
         // Add a new material to the list
-        mScene->mMaterials.push_back(D3DS::Material());
+        mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + std::to_string(mScene->mMaterials.size()))));
         ParseMaterialChunk();
         break;
 

+ 2 - 2
code/3DSLoader.h

@@ -46,13 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_3DSIMPORTER_H_INC
 #define AI_3DSIMPORTER_H_INC
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <assimp/types.h>
 
 #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
 
 #include "3DSHelper.h"
-#include "StreamReader.h"
+#include <assimp/StreamReader.h>
 
 struct aiNode;
 

+ 4 - 4
code/ACLoader.cpp

@@ -49,11 +49,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // internal headers
 #include "ACLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include "Subdivision.h"
+#include <assimp/ParsingUtils.h>
+#include <assimp/fast_atof.h>
+#include <assimp/Subdivision.h>
 #include "Importer.h"
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <assimp/Importer.hpp>
 #include <assimp/light.h>
 #include <assimp/DefaultLogger.hpp>

+ 1 - 1
code/ACLoader.h

@@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <vector>
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <assimp/types.h>
 
 struct aiNode;

+ 1 - 1
code/AMFImporter.cpp

@@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "AMFImporter.hpp"
 #include "AMFImporter_Macro.hpp"
 
-#include "fast_atof.h"
+#include <assimp/fast_atof.h>
 #include <assimp/DefaultIOSystem.h>
 
 // Header files, stdlib.

+ 2 - 2
code/AMFImporter.hpp

@@ -56,8 +56,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/importerdesc.h>
 #include "assimp/types.h"
-#include "BaseImporter.h"
-#include "irrXMLWrapper.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/irrXMLWrapper.h>
 
 // Header files, stdlib.
 #include <set>

+ 2 - 2
code/AMFImporter_Postprocess.cpp

@@ -51,8 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Header files, Assimp.
 #include <assimp/SceneCombiner.h>
-#include "StandardShapes.h"
-#include "StringUtils.h"
+#include <assimp/StandardShapes.h>
+#include <assimp/StringUtils.h>
 
 // Header files, stdlib.
 #include <iterator>

+ 9 - 10
code/ASELoader.cpp

@@ -50,8 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // internal headers
 #include "ASELoader.h"
-#include "StringComparison.h"
-#include "SkeletonMeshBuilder.h"
+#include <assimp/StringComparison.h>
+#include <assimp/SkeletonMeshBuilder.h>
 #include "TargetAnimation.h"
 #include <assimp/Importer.hpp>
 #include <assimp/IOSystem.hpp>
@@ -62,7 +62,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <memory>
 
 // utilities
-#include "fast_atof.h"
+#include <assimp/fast_atof.h>
 
 using namespace Assimp;
 using namespace Assimp::ASE;
@@ -83,11 +83,11 @@ static const aiImporterDesc desc = {
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 ASEImporter::ASEImporter()
-    : mParser(),
-    mBuffer(),
-    pcScene(),
-    configRecomputeNormals(),
-    noSkeletonMesh()
+: mParser()
+, mBuffer()
+, pcScene()
+, configRecomputeNormals()
+, noSkeletonMesh()
 {}
 
 // ------------------------------------------------------------------------------------------------
@@ -276,14 +276,13 @@ void ASEImporter::GenerateDefaultMaterial()
     }
     if (bHas || mParser->m_vMaterials.empty())  {
         // add a simple material without submaterials to the parser's list
-        mParser->m_vMaterials.push_back ( ASE::Material() );
+        mParser->m_vMaterials.push_back ( ASE::Material(AI_DEFAULT_MATERIAL_NAME) );
         ASE::Material& mat = mParser->m_vMaterials.back();
 
         mat.mDiffuse  = aiColor3D(0.6f,0.6f,0.6f);
         mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f);
         mat.mAmbient  = aiColor3D(0.05f,0.05f,0.05f);
         mat.mShading  = Discreet3DS::Gouraud;
-        mat.mName     = AI_DEFAULT_MATERIAL_NAME;
     }
 }
 

+ 1 - 1
code/ASELoader.h

@@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_ASELOADER_H_INCLUDED
 #define AI_ASELOADER_H_INCLUDED
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <assimp/types.h>
 #include "ASEParser.h"
 

+ 3 - 3
code/ASEParser.cpp

@@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // internal headers
 #include "TextureTransform.h"
 #include "ASELoader.h"
-#include "fast_atof.h"
+#include <assimp/fast_atof.h>
 #include <assimp/DefaultLogger.hpp>
 
 using namespace Assimp;
@@ -528,7 +528,7 @@ void Parser::ParseLV1MaterialListBlock()
                 ParseLV4MeshLong(iMaterialCount);
 
                 // now allocate enough storage to hold all materials
-                m_vMaterials.resize(iOldMaterialCount+iMaterialCount);
+                m_vMaterials.resize(iOldMaterialCount+iMaterialCount, Material("INVALID"));
                 continue;
             }
             if (TokenMatch(filePtr,"MATERIAL",8))
@@ -706,7 +706,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
                 ParseLV4MeshLong(iNumSubMaterials);
 
                 // allocate enough storage
-                mat.avSubMaterials.resize(iNumSubMaterials);
+                mat.avSubMaterials.resize(iNumSubMaterials, Material("INVALID SUBMATERIAL"));
             }
             // submaterial chunks
             if (TokenMatch(filePtr,"SUBMATERIAL",11))

+ 47 - 4
code/ASEParser.h

@@ -52,8 +52,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
 
 // for some helper routines like IsSpace()
-#include "ParsingUtils.h"
-#include "qnan.h"
+#include <assimp/ParsingUtils.h>
+#include <assimp/qnan.h>
 
 // ASE is quite similar to 3ds. We can reuse some structures
 #include "3DSLoader.h"
@@ -67,10 +67,53 @@ using namespace D3DS;
 /** Helper structure representing an ASE material */
 struct Material : public D3DS::Material
 {
-    //! Default constructor
-    Material() : pcInstance(NULL), bNeed (false)
+    //! Default constructor has been deleted
+    Material() = delete;
+
+
+    //! Constructor with explicit name
+    explicit Material(const std::string &name)
+    : D3DS::Material(name)
+    , pcInstance(NULL)
+    , bNeed (false)
     {}
 
+
+    Material(const Material &other)            = default;
+    Material &operator=(const Material &other) = default;
+
+
+    //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
+    Material(Material &&other)
+    : D3DS::Material(std::move(other))
+    , avSubMaterials(std::move(other.avSubMaterials))
+    , pcInstance(std::move(other.pcInstance))
+    , bNeed(std::move(other.bNeed))
+    {
+        other.pcInstance = nullptr;
+    }
+
+
+    Material &operator=(Material &&other) {
+        if (this == &other) {
+            return *this;
+        }
+
+        D3DS::Material::operator=(std::move(other));
+
+        avSubMaterials = std::move(other.avSubMaterials);
+        pcInstance = std::move(other.pcInstance);
+        bNeed = std::move(other.bNeed);
+
+        other.pcInstance = nullptr;
+
+        return *this;
+    }
+
+
+    ~Material() {}
+
+
     //! Contains all sub materials of this material
     std::vector<Material> avSubMaterials;
 

+ 1 - 1
code/AssbinExporter.cpp

@@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/IOSystem.hpp>
 #include <assimp/Exporter.hpp>
 #include "ProcessHelper.h"
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 
 #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
 #   include <zlib.h>

+ 1 - 1
code/AssbinLoader.cpp

@@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // internal headers
 #include "AssbinLoader.h"
 #include "assbin_chunks.h"
-#include "MemoryIOWrapper.h"
+#include <assimp/MemoryIOWrapper.h>
 #include <assimp/mesh.h>
 #include <assimp/anim.h>
 #include <assimp/scene.h>

+ 1 - 1
code/AssbinLoader.h

@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_ASSBINIMPORTER_H_INC
 #define AI_ASSBINIMPORTER_H_INC
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 
 struct aiMesh;
 struct aiNode;

+ 3 - 3
code/Assimp.cpp

@@ -50,12 +50,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/importerdesc.h>
 #include <assimp/scene.h>
 
-#include "GenericProperty.h"
+#include <assimp/GenericProperty.h>
 #include "CInterfaceIOWrapper.h"
 #include "Importer.h"
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 #include "ScenePrivate.h"
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <list>
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/B3DImporter.cpp

@@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "B3DImporter.h"
 #include "TextureTransform.h"
 #include "ConvertToLHProcess.h"
-#include "StringUtils.h"
+#include <assimp/StringUtils.h>
 #include <memory>
 #include <assimp/IOSystem.hpp>
 #include <assimp/anim.h>

+ 1 - 1
code/B3DImporter.h

@@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/types.h>
 #include <assimp/mesh.h>
 #include <assimp/material.h>
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 
 #include <memory>
 #include <vector>

+ 3 - 3
code/BVHLoader.cpp

@@ -45,11 +45,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
 
 #include "BVHLoader.h"
-#include "fast_atof.h"
-#include "SkeletonMeshBuilder.h"
+#include <assimp/fast_atof.h>
+#include <assimp/SkeletonMeshBuilder.h>
 #include <assimp/Importer.hpp>
 #include <memory>
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 #include <assimp/IOSystem.hpp>
 #include <assimp/scene.h>
 #include <assimp/importerdesc.h>

+ 1 - 1
code/BVHLoader.h

@@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_BVHLOADER_H_INC
 #define AI_BVHLOADER_H_INC
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 
 struct aiNode;
 

+ 2 - 2
code/BaseImporter.cpp

@@ -44,10 +44,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *  @brief Implementation of BaseImporter
  */
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include "FileSystemFilter.h"
 #include "Importer.h"
-#include "ByteSwapper.h"
+#include <assimp/ByteSwapper.h>
 #include <assimp/scene.h>
 #include <assimp/Importer.hpp>
 #include <assimp/postprocess.h>

+ 1 - 1
code/BaseProcess.cpp

@@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 /** @file Implementation of BaseProcess */
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include "BaseProcess.h"
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/scene.h>

+ 1 - 1
code/BaseProcess.h

@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define INCLUDED_AI_BASEPROCESS_H
 
 #include <map>
-#include "GenericProperty.h"
+#include <assimp/GenericProperty.h>
 
 struct aiScene;
 

+ 4 - 3
code/Bitmap.cpp

@@ -47,10 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 
-#include "Bitmap.h"
+#include <assimp/Bitmap.h>
 #include <assimp/texture.h>
 #include <assimp/IOStream.hpp>
-#include "ByteSwapper.h"
+#include <assimp/ByteSwapper.h>
 
 namespace Assimp {
 
@@ -84,7 +84,8 @@ namespace Assimp {
     }
 
     template<typename T>
-    inline std::size_t Copy(uint8_t* data, T& field) {
+    inline 
+    std::size_t Copy(uint8_t* data, const T &field) {
 #ifdef AI_BUILD_BIG_ENDIAN
         T field_swapped=AI_BE(field);
         std::memcpy(data, &field_swapped, sizeof(field)); return sizeof(field);

+ 1 - 1
code/BlenderBMesh.h

@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_BLEND_BMESH_H
 #define INCLUDED_AI_BLEND_BMESH_H
 
-#include "LogAux.h"
+#include <assimp/LogAux.h>
 
 namespace Assimp
 {

+ 3 - 3
code/BlenderDNA.cpp

@@ -47,9 +47,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
 #include "BlenderDNA.h"
-#include "StreamReader.h"
-#include "fast_atof.h"
-#include "TinyFormatter.h"
+#include <assimp/StreamReader.h>
+#include <assimp/fast_atof.h>
+#include <assimp/TinyFormatter.h>
 
 using namespace Assimp;
 using namespace Assimp::Blender;

+ 2 - 2
code/BlenderDNA.h

@@ -46,8 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_BLEND_DNA_H
 #define INCLUDED_AI_BLEND_DNA_H
 
-#include "BaseImporter.h"
-#include "StreamReader.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/StreamReader.h>
 #include <assimp/DefaultLogger.hpp>
 #include <stdint.h>
 #include <memory>

+ 1 - 1
code/BlenderDNA.inl

@@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define INCLUDED_AI_BLEND_DNA_INL
 
 #include <memory>
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 
 namespace Assimp {
 namespace Blender {

+ 4 - 4
code/BlenderLoader.cpp

@@ -53,13 +53,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "BlenderIntermediate.h"
 #include "BlenderModifier.h"
 #include "BlenderBMesh.h"
-#include "StringUtils.h"
+#include <assimp/StringUtils.h>
 #include <assimp/scene.h>
 #include <assimp/importerdesc.h>
 
-#include "StringComparison.h"
-#include "StreamReader.h"
-#include "MemoryIOWrapper.h"
+#include <assimp/StringComparison.h>
+#include <assimp/StreamReader.h>
+#include <assimp/MemoryIOWrapper.h>
 
 #include <cctype>
 

+ 2 - 2
code/BlenderLoader.h

@@ -45,8 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_BLEND_LOADER_H
 #define INCLUDED_AI_BLEND_LOADER_H
 
-#include "BaseImporter.h"
-#include "LogAux.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/LogAux.h>
 #include <memory>
 
 struct aiNode;

+ 1 - 1
code/BlenderModifier.cpp

@@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "BlenderModifier.h"
 #include <assimp/SceneCombiner.h>
-#include "Subdivision.h"
+#include <assimp/Subdivision.h>
 #include <assimp/scene.h>
 #include <memory>
 

+ 1 - 1
code/BlenderModifier.h

@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define INCLUDED_AI_BLEND_MODIFIER_H
 
 #include "BlenderIntermediate.h"
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 
 namespace Assimp {
 namespace Blender {

+ 1 - 1
code/BlenderTessellator.h

@@ -58,7 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #   define ASSIMP_BLEND_WITH_POLY_2_TRI 1
 #endif
 
-#include "LogAux.h"
+#include <assimp/LogAux.h>
 
 #if ASSIMP_BLEND_WITH_GLU_TESSELLATE
 

+ 1 - 1
code/C4DImporter.cpp

@@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "C4DImporter.h"
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 #include <memory>
 #include <assimp/IOSystem.hpp>
 #include <assimp/scene.h>

+ 2 - 2
code/C4DImporter.h

@@ -44,8 +44,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_CINEMA_4D_LOADER_H
 #define INCLUDED_AI_CINEMA_4D_LOADER_H
 
-#include "BaseImporter.h"
-#include "LogAux.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/LogAux.h>
 
 #include <map>
 struct aiNode;

+ 63 - 55
code/CMakeLists.txt

@@ -98,6 +98,40 @@ SET( PUBLIC_HEADERS
   ${HEADER_PATH}/DefaultIOStream.h
   ${HEADER_PATH}/DefaultIOSystem.h
   ${HEADER_PATH}/SceneCombiner.h
+  ${HEADER_PATH}/fast_atof.h
+  ${HEADER_PATH}/qnan.h
+  ${HEADER_PATH}/BaseImporter.h
+  ${HEADER_PATH}/Hash.h
+  ${HEADER_PATH}/MemoryIOWrapper.h
+  ${HEADER_PATH}/ParsingUtils.h
+  ${HEADER_PATH}/StreamReader.h
+  ${HEADER_PATH}/StreamWriter.h
+  ${HEADER_PATH}/StringComparison.h
+  ${HEADER_PATH}/StringUtils.h
+  ${HEADER_PATH}/SGSpatialSort.h
+  ${HEADER_PATH}/GenericProperty.h
+  ${HEADER_PATH}/SpatialSort.h
+  ${HEADER_PATH}/SkeletonMeshBuilder.h
+  ${HEADER_PATH}/SmoothingGroups.h
+  ${HEADER_PATH}/SmoothingGroups.inl
+  ${HEADER_PATH}/StandardShapes.h
+  ${HEADER_PATH}/RemoveComments.h
+  ${HEADER_PATH}/Subdivision.h
+  ${HEADER_PATH}/Vertex.h
+  ${HEADER_PATH}/LineSplitter.h
+  ${HEADER_PATH}/TinyFormatter.h
+  ${HEADER_PATH}/Profiler.h
+  ${HEADER_PATH}/LogAux.h
+  ${HEADER_PATH}/Bitmap.h
+  ${HEADER_PATH}/XMLTools.h
+  ${HEADER_PATH}/IOStreamBuffer.h
+  ${HEADER_PATH}/CreateAnimMesh.h
+  ${HEADER_PATH}/irrXMLWrapper.h
+  ${HEADER_PATH}/BlobIOSystem.h
+  ${HEADER_PATH}/MathFunctions.h
+  ${HEADER_PATH}/Macros.h
+  ${HEADER_PATH}/Exceptional.h
+  ${HEADER_PATH}/ByteSwapper.h
 )
 
 SET( Core_SRCS
@@ -117,68 +151,40 @@ SET( Logging_SRCS
 SOURCE_GROUP(Logging FILES ${Logging_SRCS})
 
 SET( Common_SRCS
-  fast_atof.h
-  qnan.h
   BaseImporter.cpp
-  BaseImporter.h
   BaseProcess.cpp
   BaseProcess.h
   Importer.h
   ScenePrivate.h
   PostStepRegistry.cpp
   ImporterRegistry.cpp
-  ByteSwapper.h
   DefaultProgressHandler.h
   DefaultIOStream.cpp
   DefaultIOSystem.cpp
   CInterfaceIOWrapper.cpp
   CInterfaceIOWrapper.h
-  Hash.h
   Importer.cpp
   IFF.h
-  MemoryIOWrapper.h
-  ParsingUtils.h
-  StreamReader.h
-  StreamWriter.h
-  StringComparison.h
-  StringUtils.h
   SGSpatialSort.cpp
-  SGSpatialSort.h
   VertexTriangleAdjacency.cpp
   VertexTriangleAdjacency.h
-  GenericProperty.h
   SpatialSort.cpp
-  SpatialSort.h
   SceneCombiner.cpp
   ScenePreprocessor.cpp
   ScenePreprocessor.h
   SkeletonMeshBuilder.cpp
-  SkeletonMeshBuilder.h
   SplitByBoneCountProcess.cpp
   SplitByBoneCountProcess.h
   ScaleProcess.cpp
   ScaleProcess.h
-  SmoothingGroups.h
   StandardShapes.cpp
-  StandardShapes.h
   TargetAnimation.cpp
   TargetAnimation.h
   RemoveComments.cpp
-  RemoveComments.h
   Subdivision.cpp
-  Subdivision.h
   scene.cpp
-  Vertex.h
-  LineSplitter.h
-  TinyFormatter.h
-  Profiler.h
-  LogAux.h
   Bitmap.cpp
-  Bitmap.h
-  XMLTools.h
   Version.cpp
-  IOStreamBuffer.h
-  CreateAnimMesh.h
   CreateAnimMesh.cpp
 )
 SOURCE_GROUP(Common FILES ${Common_SRCS})
@@ -457,24 +463,23 @@ ADD_ASSIMP_IMPORTER( BLEND
 )
 
 ADD_ASSIMP_IMPORTER( IFC
-  IFCLoader.cpp
-  IFCLoader.h
-  IFCReaderGen1.cpp
-  IFCReaderGen2.cpp
-  IFCReaderGen.h
-  IFCUtil.h
-  IFCUtil.cpp
-  IFCGeometry.cpp
-  IFCMaterial.cpp
-  IFCProfile.cpp
-  IFCCurve.cpp
-  IFCBoolean.cpp
-  IFCOpenings.cpp
-  STEPFile.h
-  STEPFileReader.h
-  STEPFileReader.cpp
-  STEPFileEncoding.cpp
-  STEPFileEncoding.h
+  Importer/IFC/IFCLoader.cpp
+  Importer/IFC/IFCLoader.h
+  Importer/IFC/IFCReaderGen1_2x3.cpp
+  Importer/IFC/IFCReaderGen2_2x3.cpp
+  Importer/IFC/IFCReaderGen_2x3.h
+  Importer/IFC/IFCUtil.h
+  Importer/IFC/IFCUtil.cpp
+  Importer/IFC/IFCGeometry.cpp
+  Importer/IFC/IFCMaterial.cpp
+  Importer/IFC/IFCProfile.cpp
+  Importer/IFC/IFCCurve.cpp
+  Importer/IFC/IFCBoolean.cpp
+  Importer/IFC/IFCOpenings.cpp
+  Importer/IFC/STEPFileReader.h
+  Importer/IFC/STEPFileReader.cpp
+  Importer/IFC/STEPFileEncoding.cpp
+  Importer/IFC/STEPFileEncoding.h
 )
 if (ASSIMP_BUILD_IFC_IMPORTER)
   if (MSVC)
@@ -525,6 +530,8 @@ SET( PostProcessing_SRCS
   ComputeUVMappingProcess.h
   ConvertToLHProcess.cpp
   ConvertToLHProcess.h
+  EmbedTexturesProcess.cpp
+  EmbedTexturesProcess.h
   FindDegenerates.cpp
   FindDegenerates.h
   FindInstancesProcess.cpp
@@ -573,7 +580,7 @@ SET( PostProcessing_SRCS
 )
 SOURCE_GROUP( PostProcessing FILES ${PostProcessing_SRCS})
 
-SET( IrrXML_SRCS irrXMLWrapper.h )
+SET( IrrXML_SRCS ${HEADER_PATH}/irrXMLWrapper.h )
 SOURCE_GROUP( IrrXML FILES ${IrrXML_SRCS})
 
 ADD_ASSIMP_IMPORTER( Q3D
@@ -695,6 +702,7 @@ ADD_ASSIMP_IMPORTER( MMD
 )
 
 SET( Step_SRCS
+  STEPFile.h
   StepExporter.h
   StepExporter.cpp
 )
@@ -703,7 +711,7 @@ SOURCE_GROUP( Step FILES ${Step_SRCS})
 SET( Exporter_SRCS
   Exporter.cpp
   AssimpCExport.cpp
-  BlobIOSystem.h
+  ${HEADER_PATH}/BlobIOSystem.h
 )
 SOURCE_GROUP( Exporter FILES ${Exporter_SRCS})
 
@@ -940,13 +948,13 @@ if (APPLE)
 
     # PUBLIC_HEADER option does not support directory structure creation
     # add ./Compiler/*.h to assimp.framework via copy command
-    ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD 
-      COMMAND "${CMAKE_COMMAND}" -E copy_directory 
+    ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD
+      COMMAND "${CMAKE_COMMAND}" -E copy_directory
          "../${HEADER_PATH}/Compiler"
          assimp.framework/Headers/Compiler
       COMMENT "Copying public ./Compiler/ header files to framework bundle's Headers/Compiler/")
-  endif(BUILD_FRAMEWORK)
-endif(APPLE)
+  ENDIF(BUILD_FRAMEWORK)
+ENDIF(APPLE)
 
 # Build against external unzip, or add ../contrib/unzip so
 # assimp can #include "unzip.h"
@@ -975,7 +983,7 @@ if (ASSIMP_ANDROID_JNIIOSYSTEM)
   INSTALL(FILES ${HEADER_PATH}/${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/AndroidJNIIOSystem.h
     DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}
     COMPONENT assimp-dev)
-endif(ASSIMP_ANDROID_JNIIOSYSTEM)
+ENDIF(ASSIMP_ANDROID_JNIIOSYSTEM)
 
 if(MSVC AND ASSIMP_INSTALL_PDB)
   IF(CMAKE_GENERATOR MATCHES "^Visual Studio")
@@ -997,7 +1005,7 @@ if(MSVC AND ASSIMP_INSTALL_PDB)
       CONFIGURATIONS RelWithDebInfo
     )
   ENDIF()
-endif ()
+ENDIF ()
 
 if (ASSIMP_COVERALLS)
     include(Coveralls)
@@ -1009,4 +1017,4 @@ if (ASSIMP_COVERALLS)
         "${COVERAGE_SRCS}" # The source files.
         ON                 # If we should upload.
         "${PROJECT_SOURCE_DIR}/cmake-modules/") # (Optional) Alternate project cmake module path.
-endif()
+ENDIF()

+ 5 - 5
code/COBLoader.cpp

@@ -47,12 +47,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "COBLoader.h"
 #include "COBScene.h"
 
-#include "StreamReader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
+#include <assimp/StreamReader.h>
+#include <assimp/ParsingUtils.h>
+#include <assimp/fast_atof.h>
 
-#include "LineSplitter.h"
-#include "TinyFormatter.h"
+#include <assimp/LineSplitter.h>
+#include <assimp/TinyFormatter.h>
 #include <memory>
 #include <assimp/IOSystem.hpp>
 #include <assimp/DefaultLogger.hpp>

+ 2 - 2
code/COBLoader.h

@@ -45,8 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_COB_LOADER_H
 #define INCLUDED_AI_COB_LOADER_H
 
-#include "BaseImporter.h"
-#include "StreamReader.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/StreamReader.h>
 
 struct aiNode;
 

+ 1 - 1
code/COBScene.h

@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <deque>
 #include <map>
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <assimp/material.h>
 
 namespace Assimp {

+ 3 - 3
code/CSMLoader.cpp

@@ -49,9 +49,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
 
 #include "CSMLoader.h"
-#include "SkeletonMeshBuilder.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
+#include <assimp/SkeletonMeshBuilder.h>
+#include <assimp/ParsingUtils.h>
+#include <assimp/fast_atof.h>
 #include <assimp/Importer.hpp>
 #include <memory>
 #include <assimp/IOSystem.hpp>

+ 1 - 1
code/CSMLoader.h

@@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_CSM_LOADER_H
 #define INCLUDED_AI_CSM_LOADER_H
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 
 namespace Assimp    {
 

+ 2 - 2
code/CalcTangentsProcess.cpp

@@ -47,8 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // internal headers
 #include "CalcTangentsProcess.h"
 #include "ProcessHelper.h"
-#include "TinyFormatter.h"
-#include "qnan.h"
+#include <assimp/TinyFormatter.h>
+#include <assimp/qnan.h>
 
 using namespace Assimp;
 

+ 5 - 5
code/ColladaExporter.cpp

@@ -43,17 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
 
 #include "ColladaExporter.h"
-#include "Bitmap.h"
-#include "fast_atof.h"
+#include <assimp/Bitmap.h>
+#include <assimp/fast_atof.h>
 #include <assimp/SceneCombiner.h>
-#include "StringUtils.h"
-#include "XMLTools.h"
+#include <assimp/StringUtils.h>
+#include <assimp/XMLTools.h>
 #include <assimp/DefaultIOSystem.h>
 #include <assimp/IOSystem.hpp>
 #include <assimp/Exporter.hpp>
 #include <assimp/scene.h>
 
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 
 #include <memory>
 #include <ctime>

+ 1 - 1
code/ColladaExporter.h

@@ -54,7 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <vector>
 #include <map>
 
-#include "StringUtils.h"
+#include <assimp/StringUtils.h>
 
 struct aiScene;
 struct aiNode;

+ 9 - 4
code/ColladaLoader.cpp

@@ -53,10 +53,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/importerdesc.h>
 
 #include "ColladaParser.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include "SkeletonMeshBuilder.h"
-#include "CreateAnimMesh.h"
+#include <assimp/fast_atof.h>
+#include <assimp/ParsingUtils.h>
+#include <assimp/SkeletonMeshBuilder.h>
+#include <assimp/CreateAnimMesh.h>
 
 #include "time.h"
 #include "math.h"
@@ -1778,6 +1778,11 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
         tex->pcData = (aiTexel*)new char[tex->mWidth];
         memcpy(tex->pcData,&imIt->second.mImageData[0],tex->mWidth);
 
+        // TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
+        // In FBX files textures are now stored internally by Assimp with their filename included
+        // Now Assimp can lookup thru the loaded textures after all data is processed
+        // We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
+        // This may occur on this case too, it has to be studied
         // setup texture reference string
         result.data[0] = '*';
         result.length = 1 + ASSIMP_itoa10(result.data+1,static_cast<unsigned int>(MAXLEN-1),static_cast<int32_t>(mTextures.size()));

+ 1 - 1
code/ColladaLoader.h

@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_COLLADALOADER_H_INC
 #define AI_COLLADALOADER_H_INC
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include "ColladaParser.h"
 
 struct aiNode;

+ 4 - 4
code/ColladaParser.cpp

@@ -49,13 +49,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <sstream>
 #include <stdarg.h>
 #include "ColladaParser.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include "StringUtils.h"
+#include <assimp/fast_atof.h>
+#include <assimp/ParsingUtils.h>
+#include <assimp/StringUtils.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/light.h>
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 
 #include <memory>
 

+ 2 - 2
code/ColladaParser.h

@@ -46,10 +46,10 @@
 #ifndef AI_COLLADAPARSER_H_INC
 #define AI_COLLADAPARSER_H_INC
 
-#include "irrXMLWrapper.h"
+#include <assimp/irrXMLWrapper.h>
 #include "ColladaHelper.h"
 #include <assimp/ai_assert.h>
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 
 namespace Assimp
 {

+ 1 - 1
code/ComputeUVMappingProcess.cpp

@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "ComputeUVMappingProcess.h"
 #include "ProcessHelper.h"
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 
 using namespace Assimp;
 

+ 1 - 1
code/CreateAnimMesh.cpp

@@ -40,7 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-#include "CreateAnimMesh.h"
+#include <assimp/CreateAnimMesh.h>
 
 namespace Assimp    {
 

+ 1 - 1
code/D3MFExporter.cpp

@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/Exporter.hpp>
 #include <assimp/DefaultLogger.hpp>
 
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 #include "3MFXmlTags.h"
 #include "D3MFOpcPackage.h"
 

+ 3 - 3
code/D3MFImporter.cpp

@@ -47,8 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/IOSystem.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/importerdesc.h>
-#include "StringComparison.h"
-#include "StringUtils.h"
+#include <assimp/StringComparison.h>
+#include <assimp/StringUtils.h>
 
 #include <string>
 #include <vector>
@@ -58,7 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "D3MFOpcPackage.h"
 #include <contrib/unzip/unzip.h>
-#include "irrXMLWrapper.h"
+#include <assimp/irrXMLWrapper.h>
 #include "3MFXmlTags.h"
 
 namespace Assimp {

+ 1 - 1
code/D3MFImporter.h

@@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_D3MFLOADER_H_INCLUDED
 #define AI_D3MFLOADER_H_INCLUDED
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 
 namespace Assimp {
 

+ 1 - 1
code/D3MFOpcPackage.cpp

@@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
 
 #include "D3MFOpcPackage.h"
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 
 #include <assimp/IOStream.hpp>
 #include <assimp/IOSystem.hpp>

+ 1 - 1
code/D3MFOpcPackage.h

@@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <memory>
 
 #include <assimp/IOSystem.hpp>
-#include "irrXMLWrapper.h"
+#include <assimp/irrXMLWrapper.h>
 
 namespace Assimp {
 namespace D3MF {

+ 4 - 4
code/DXFHelper.h

@@ -46,10 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_DXFHELPER_H
 #define INCLUDED_DXFHELPER_H
 
-#include "LineSplitter.h"
-#include "TinyFormatter.h"
-#include "StreamReader.h"
-#include "fast_atof.h"
+#include <assimp/LineSplitter.h>
+#include <assimp/TinyFormatter.h>
+#include <assimp/StreamReader.h>
+#include <assimp/fast_atof.h>
 #include <vector>
 #include <assimp/DefaultLogger.hpp>
 

+ 2 - 2
code/DXFLoader.cpp

@@ -48,9 +48,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
 
 #include "DXFLoader.h"
-#include "ParsingUtils.h"
+#include <assimp/ParsingUtils.h>
 #include "ConvertToLHProcess.h"
-#include "fast_atof.h"
+#include <assimp/fast_atof.h>
 
 #include "DXFHelper.h"
 #include <assimp/IOSystem.hpp>

+ 1 - 1
code/DXFLoader.h

@@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_DXFLOADER_H_INCLUDED
 #define AI_DXFLOADER_H_INCLUDED
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <map>
 
 namespace Assimp    {

+ 2 - 1
code/DefaultIOStream.cpp

@@ -123,7 +123,8 @@ size_t DefaultIOStream::FileSize() const
         // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
 #if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
         struct __stat64 fileStat;
-        int err = _stat64(  mFilename.c_str(), &fileStat );
+        //using fileno + fstat avoids having to handle the filename
+        int err = _fstat64(  _fileno(mFile), &fileStat );
         if (0 != err)
             return 0;
         mCachedSize = (size_t) (fileStat.st_size);

+ 76 - 31
code/DefaultIOSystem.cpp

@@ -41,7 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 /** @file Default implementation of IOSystem using the standard C file functions */
 
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
 
 #include <assimp/DefaultIOSystem.h>
 #include <assimp/DefaultIOStream.h>
@@ -54,31 +54,49 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <stdlib.h>
 #endif
 
-using namespace Assimp;
+#ifdef _WIN32
+#include <windows.h>
+#endif
 
-// ------------------------------------------------------------------------------------------------
-// Constructor.
-DefaultIOSystem::DefaultIOSystem()
-{
-    // nothing to do here
-}
+using namespace Assimp;
 
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-DefaultIOSystem::~DefaultIOSystem()
-{
-    // nothing to do here
-}
+// maximum path length
+// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
+#ifdef PATH_MAX
+#   define PATHLIMIT PATH_MAX
+#else
+#   define PATHLIMIT 4096
+#endif
 
 // ------------------------------------------------------------------------------------------------
 // Tests for the existence of a file at the given path.
 bool DefaultIOSystem::Exists( const char* pFile) const
 {
+#ifdef _WIN32
+    wchar_t fileName16[PATHLIMIT];
+
+    bool isUnicode = IsTextUnicode(pFile, strlen(pFile), NULL);
+    if (isUnicode) {
+
+        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
+        struct _stat64 filestat;
+        if (0 != _wstat64(fileName16, &filestat)) {
+            return false;
+        }
+    } else {
+        FILE* file = ::fopen(pFile, "rb");
+        if (!file)
+            return false;
+
+        ::fclose(file);
+    }
+#else
     FILE* file = ::fopen( pFile, "rb");
     if( !file)
         return false;
 
     ::fclose( file);
+#endif
     return true;
 }
 
@@ -88,10 +106,22 @@ IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
 {
     ai_assert(NULL != strFile);
     ai_assert(NULL != strMode);
-
-    FILE* file = ::fopen( strFile, strMode);
-    if( NULL == file)
-        return NULL;
+    FILE* file;
+#ifdef _WIN32
+    wchar_t fileName16[PATHLIMIT];
+    bool isUnicode = IsTextUnicode(strFile, strlen(strFile), NULL );
+    if (isUnicode) {
+        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
+        std::string mode8(strMode);
+        file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str());
+    } else {
+        file = ::fopen(strFile, strMode);
+    }
+#else
+    file = ::fopen(strFile, strMode);
+#endif
+    if (nullptr == file)
+        return nullptr;
 
     return new DefaultIOStream(file, (std::string) strFile);
 }
@@ -121,32 +151,47 @@ bool IOSystem::ComparePaths (const char* one, const char* second) const
     return !ASSIMP_stricmp(one,second);
 }
 
-// maximum path length
-// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
-#ifdef PATH_MAX
-#   define PATHLIMIT PATH_MAX
-#else
-#   define PATHLIMIT 4096
-#endif
-
 // ------------------------------------------------------------------------------------------------
 // Convert a relative path into an absolute path
-inline void MakeAbsolutePath (const char* in, char* _out)
+inline static void MakeAbsolutePath (const char* in, char* _out)
 {
     ai_assert(in && _out);
-    char* ret;
 #if defined( _MSC_VER ) || defined( __MINGW32__ )
-    ret = ::_fullpath( _out, in, PATHLIMIT );
+    bool isUnicode = IsTextUnicode(in, strlen(in), NULL);
+    if (isUnicode) {
+        wchar_t out16[PATHLIMIT];
+        wchar_t in16[PATHLIMIT];
+        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, in, -1, out16, PATHLIMIT);
+        wchar_t* ret = ::_wfullpath(out16, in16, PATHLIMIT);
+        if (ret) {
+            WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr);
+        }
+        if (!ret) {
+            // preserve the input path, maybe someone else is able to fix
+            // the path before it is accessed (e.g. our file system filter)
+            DefaultLogger::get()->warn("Invalid path: " + std::string(in));
+            strcpy(_out, in);
+        }
+
+    } else {
+        char* ret = :: _fullpath(_out, in, PATHLIMIT);
+        if (!ret) {
+            // preserve the input path, maybe someone else is able to fix
+            // the path before it is accessed (e.g. our file system filter)
+            DefaultLogger::get()->warn("Invalid path: " + std::string(in));
+            strcpy(_out, in);
+        }
+    }
 #else
     // use realpath
-    ret = realpath(in, _out);
-#endif
+    char* ret = realpath(in, _out);
     if(!ret) {
         // preserve the input path, maybe someone else is able to fix
         // the path before it is accessed (e.g. our file system filter)
         DefaultLogger::get()->warn("Invalid path: "+std::string(in));
         strcpy(_out,in);
     }
+#endif
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/DefaultLogger.cpp

@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "Win32DebugLogStream.h"
 #include "StdOStreamLogStream.h"
 #include "FileLogStream.h"
-#include "StringUtils.h"
+#include <assimp/StringUtils.h>
 
 #include <assimp/DefaultIOSystem.h>
 #include <assimp/NullLogger.hpp>

+ 147 - 0
code/EmbedTexturesProcess.cpp

@@ -0,0 +1,147 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2017, 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 "EmbedTexturesProcess.h"
+#include <assimp/ParsingUtils.h>
+#include "ProcessHelper.h"
+
+#include <fstream>
+
+using namespace Assimp;
+
+EmbedTexturesProcess::EmbedTexturesProcess()
+: BaseProcess() {
+}
+
+EmbedTexturesProcess::~EmbedTexturesProcess() {
+}
+
+bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const {
+    return (pFlags & aiProcess_EmbedTextures) != 0;
+}
+
+void EmbedTexturesProcess::SetupProperties(const Importer* pImp) {
+    mRootPath = pImp->GetPropertyString("sourceFilePath");
+    mRootPath = mRootPath.substr(0, mRootPath.find_last_of("\\/") + 1u);
+}
+
+void EmbedTexturesProcess::Execute(aiScene* pScene) {
+    if (pScene == nullptr || pScene->mRootNode == nullptr) return;
+
+    aiString path;
+
+    uint32_t embeddedTexturesCount = 0u;
+
+    for (auto matId = 0u; matId < pScene->mNumMaterials; ++matId) {
+        auto material = pScene->mMaterials[matId];
+
+        for (auto ttId = 1u; ttId < AI_TEXTURE_TYPE_MAX; ++ttId) {
+            auto tt = static_cast<aiTextureType>(ttId);
+            auto texturesCount = material->GetTextureCount(tt);
+
+            for (auto texId = 0u; texId < texturesCount; ++texId) {
+                material->GetTexture(tt, texId, &path);
+                if (path.data[0] == '*') continue; // Already embedded
+
+                // Indeed embed
+                if (addTexture(pScene, path.data)) {
+                    auto embeddedTextureId = pScene->mNumTextures - 1u;
+                    ::ai_snprintf(path.data, 1024, "*%u", embeddedTextureId);
+                    material->AddProperty(&path, AI_MATKEY_TEXTURE(tt, texId));
+                    embeddedTexturesCount++;
+                }
+            }
+        }
+    }
+
+    char stringBuffer[128];
+    ::ai_snprintf(stringBuffer, 128, "EmbedTexturesProcess finished. Embedded %u textures.", embeddedTexturesCount);
+    DefaultLogger::get()->info(stringBuffer);
+}
+
+bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
+    uint32_t imageSize = 0;
+    std::string imagePath = path;
+
+    // Test path directly
+    std::ifstream file(imagePath, std::ios::binary | std::ios::ate);
+    if ((imageSize = file.tellg()) == -1u) {
+        DefaultLogger::get()->warn("EmbedTexturesProcess: Cannot find image: " + imagePath + ". Will try to find it in root folder.");
+
+        // Test path in root path
+        imagePath = mRootPath + path;
+        file.open(imagePath, std::ios::binary | std::ios::ate);
+        if ((imageSize = file.tellg()) == -1u) {
+            // Test path basename in root path
+            imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u);
+            file.open(imagePath, std::ios::binary | std::ios::ate);
+            if ((imageSize = file.tellg()) == -1u) {
+                DefaultLogger::get()->error("EmbedTexturesProcess: Unable to embed texture: " + path + ".");
+                return false;
+            }
+        }
+    }
+
+    aiTexel* imageContent = new aiTexel[1u + imageSize / sizeof(aiTexel)];
+    file.seekg(0, std::ios::beg);
+    file.read(reinterpret_cast<char*>(imageContent), imageSize);
+
+    // Enlarging the textures table
+    auto textureId = pScene->mNumTextures++;
+    auto oldTextures = pScene->mTextures;
+    pScene->mTextures = new aiTexture*[pScene->mNumTextures];
+    memmove(pScene->mTextures, oldTextures, sizeof(aiTexture*) * (pScene->mNumTextures - 1u));
+
+    // Add the new texture
+    auto pTexture = new aiTexture();
+    pTexture->mHeight = 0; // Means that this is still compressed
+    pTexture->mWidth = imageSize;
+    pTexture->pcData = imageContent;
+
+    auto extension = path.substr(path.find_last_of('.') + 1u);
+    std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
+    if (extension == "jpeg") extension = "jpg";
+    strcpy(pTexture->achFormatHint, extension.c_str());
+
+    pScene->mTextures[textureId] = pTexture;
+
+    return true;
+}

+ 84 - 0
code/EmbedTexturesProcess.h

@@ -0,0 +1,84 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2017, 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 "BaseProcess.h"
+
+#include <string>
+
+struct aiNode;
+
+namespace Assimp {
+
+/**
+ *  Force embedding of textures (using the path = "*1" convention).
+ *  If a texture's file does not exist at the specified path
+ *  (due, for instance, to an absolute path generated on another system),
+ *  it will check if a file with the same name exists at the root folder
+ *  of the imported model. And if so, it uses that.
+ */
+class ASSIMP_API EmbedTexturesProcess : public BaseProcess {
+public:
+    /// The default class constructor.
+    EmbedTexturesProcess();
+
+    /// The class destructor.
+    virtual ~EmbedTexturesProcess();
+
+    /// Overwritten, @see BaseProcess
+    virtual bool IsActive(unsigned int pFlags) const;
+
+    /// Overwritten, @see BaseProcess
+    virtual void SetupProperties(const Importer* pImp);
+
+    /// Overwritten, @see BaseProcess
+    virtual void Execute(aiScene* pScene);
+
+private:
+    // Resolve the path and add the file content to the scene as a texture.
+    bool addTexture(aiScene* pScene, std::string path) const;
+
+private:
+    std::string mRootPath;
+};
+
+} // namespace Assimp

+ 2 - 2
code/Exporter.cpp

@@ -53,7 +53,7 @@ Here we implement only the C++ interface (Assimp::Exporter).
 
 #ifndef ASSIMP_BUILD_NO_EXPORT
 
-#include "BlobIOSystem.h"
+#include <assimp/BlobIOSystem.h>
 #include <assimp/SceneCombiner.h>
 #include "BaseProcess.h"
 #include "Importer.h" // need this for GetPostProcessingStepInstanceList()
@@ -61,7 +61,7 @@ Here we implement only the C++ interface (Assimp::Exporter).
 #include "JoinVerticesProcess.h"
 #include "MakeVerboseFormat.h"
 #include "ConvertToLHProcess.h"
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 #include "ScenePrivate.h"
 #include <memory>
 

+ 16 - 23
code/FBXBinaryTokenizer.cpp

@@ -50,8 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXUtil.h"
 #include <assimp/defs.h>
 #include <stdint.h>
-#include "Exceptional.h"
-#include "ByteSwapper.h"
+#include <assimp/Exceptional.h>
+#include <assimp/ByteSwapper.h>
 
 namespace Assimp {
 namespace FBX {
@@ -129,30 +129,26 @@ AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offse
 
 
 // ------------------------------------------------------------------------------------------------
-uint32_t Offset(const char* begin, const char* cursor)
-{
+uint32_t Offset(const char* begin, const char* cursor) {
     ai_assert(begin <= cursor);
+
     return static_cast<unsigned int>(cursor - begin);
 }
 
-
 // ------------------------------------------------------------------------------------------------
-void TokenizeError(const std::string& message, const char* begin, const char* cursor)
-{
+void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
     TokenizeError(message, Offset(begin, cursor));
 }
 
-
 // ------------------------------------------------------------------------------------------------
-uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
-{
+uint32_t ReadWord(const char* input, const char*& cursor, const char* end) {
     const size_t k_to_read = sizeof( uint32_t );
     if(Offset(cursor, end) < k_to_read ) {
         TokenizeError("cannot ReadWord, out of bounds",input, cursor);
     }
 
     uint32_t word;
-    memcpy(&word, cursor, 4);
+    ::memcpy(&word, cursor, 4);
     AI_SWAP4(word);
 
     cursor += k_to_read;
@@ -167,7 +163,8 @@ uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
         TokenizeError("cannot ReadDoubleWord, out of bounds",input, cursor);
     }
 
-    uint64_t dword = *reinterpret_cast<const uint64_t*>(cursor);
+    uint64_t dword /*= *reinterpret_cast<const uint64_t*>(cursor)*/;
+    ::memcpy( &dword, cursor, sizeof( uint64_t ) );
     AI_SWAP8(dword);
 
     cursor += k_to_read;
@@ -176,24 +173,21 @@ uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
 }
 
 // ------------------------------------------------------------------------------------------------
-uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
-{
+uint8_t ReadByte(const char* input, const char*& cursor, const char* end) {
     if(Offset(cursor, end) < sizeof( uint8_t ) ) {
         TokenizeError("cannot ReadByte, out of bounds",input, cursor);
     }
 
-    uint8_t word = *reinterpret_cast<const uint8_t*>(cursor);
+    uint8_t word;/* = *reinterpret_cast< const uint8_t* >( cursor )*/
+    ::memcpy( &word, cursor, sizeof( uint8_t ) );
     ++cursor;
 
     return word;
 }
 
-
 // ------------------------------------------------------------------------------------------------
-unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end,
-    bool long_length = false,
-    bool allow_null = false)
-{
+unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input,
+        const char*& cursor, const char* end, bool long_length = false, bool allow_null = false) {
     const uint32_t len_len = long_length ? 4 : 1;
     if(Offset(cursor, end) < len_len) {
         TokenizeError("cannot ReadString, out of bounds reading length",input, cursor);
@@ -222,8 +216,7 @@ unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const ch
 }
 
 // ------------------------------------------------------------------------------------------------
-void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end)
-{
+void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end) {
     if(Offset(cursor, end) < 1) {
         TokenizeError("cannot ReadData, out of bounds reading length",input, cursor);
     }
@@ -422,7 +415,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
     return true;
 }
 
-}
+} // anonymous namespace
 
 // ------------------------------------------------------------------------------------------------
 // TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent

+ 132 - 433
code/FBXConverter.cpp

@@ -52,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXUtil.h"
 #include "FBXProperties.h"
 #include "FBXImporter.h"
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
 
 #include <assimp/scene.h>
 
@@ -66,7 +66,6 @@ namespace FBX {
 
 using namespace Util;
 
-
 #define MAGIC_NODE_TAG "_$AssimpFbx$"
 
 #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
@@ -74,387 +73,11 @@ using namespace Util;
 // XXX vc9's debugger won't step into anonymous namespaces
 //namespace {
 
-/** Dummy class to encapsulate the conversion process */
-class Converter
-{
-public:
-    /**
-     *  The different parts that make up the final local transformation of a fbx-node
-     */
-    enum TransformationComp
-    {
-        TransformationComp_Translation = 0,
-        TransformationComp_RotationOffset,
-        TransformationComp_RotationPivot,
-        TransformationComp_PreRotation,
-        TransformationComp_Rotation,
-        TransformationComp_PostRotation,
-        TransformationComp_RotationPivotInverse,
-        TransformationComp_ScalingOffset,
-        TransformationComp_ScalingPivot,
-        TransformationComp_Scaling,
-        TransformationComp_ScalingPivotInverse,
-        TransformationComp_GeometricTranslation,
-        TransformationComp_GeometricRotation,
-        TransformationComp_GeometricScaling,
-
-        TransformationComp_MAXIMUM
-    };
-
-public:
-    Converter( aiScene* out, const Document& doc );
-    ~Converter();
-
-private:
-    // ------------------------------------------------------------------------------------------------
-    // find scene root and trigger recursive scene conversion
-    void ConvertRootNode();
-
-    // ------------------------------------------------------------------------------------------------
-    // collect and assign child nodes
-    void ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4() );
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertLights( const Model& model );
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertCameras( const Model& model );
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertLight( const Model& model, const Light& light );
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertCamera( const Model& model, const Camera& cam );
-
-    // ------------------------------------------------------------------------------------------------
-    // this returns unified names usable within assimp identifiers (i.e. no space characters -
-    // while these would be allowed, they are a potential trouble spot so better not use them).
-    const char* NameTransformationComp( TransformationComp comp );
-
-    // ------------------------------------------------------------------------------------------------
-    // note: this returns the REAL fbx property names
-    const char* NameTransformationCompProperty( TransformationComp comp );
-
-    // ------------------------------------------------------------------------------------------------
-    aiVector3D TransformationCompDefaultValue( TransformationComp comp );
-
-    // ------------------------------------------------------------------------------------------------
-    void GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out );
-    // ------------------------------------------------------------------------------------------------
-    /**
-     *  checks if a node has more than just scaling, rotation and translation components
-     */
-    bool NeedsComplexTransformationChain( const Model& model );
-
-    // ------------------------------------------------------------------------------------------------
-    // note: name must be a FixNodeName() result
-    std::string NameTransformationChainNode( const std::string& name, TransformationComp comp );
-
-    // ------------------------------------------------------------------------------------------------
-    /**
-     *  note: memory for output_nodes will be managed by the caller
-     */
-    void GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes );
-
-    // ------------------------------------------------------------------------------------------------
-    void SetupNodeMetadata( const Model& model, aiNode& nd );
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform );
-
-    // ------------------------------------------------------------------------------------------------
-    // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
-    std::vector<unsigned int> ConvertMesh( const MeshGeometry& mesh, const Model& model,
-        const aiMatrix4x4& node_global_transform );
-
-    // ------------------------------------------------------------------------------------------------
-    aiMesh* SetupEmptyMesh( const MeshGeometry& mesh );
-
-    // ------------------------------------------------------------------------------------------------
-    unsigned int ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model,
-        const aiMatrix4x4& node_global_transform );
-
-    // ------------------------------------------------------------------------------------------------
-    std::vector<unsigned int> ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
-        const aiMatrix4x4& node_global_transform );
-
-    // ------------------------------------------------------------------------------------------------
-    unsigned int ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
-        MatIndexArray::value_type index,
-        const aiMatrix4x4& node_global_transform );
-
-    // ------------------------------------------------------------------------------------------------
-    static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
-        static_cast<unsigned int>(-1);
-
-    // ------------------------------------------------------------------------------------------------
-    /**
-     *  - if materialIndex == NO_MATERIAL_SEPARATION, materials are not taken into
-     *    account when determining which weights to include.
-     *  - outputVertStartIndices is only used when a material index is specified, it gives for
-     *    each output vertex the DOM index it maps to.
-     */
-    void ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo,
-        const aiMatrix4x4& node_global_transform = aiMatrix4x4(),
-        unsigned int materialIndex = NO_MATERIAL_SEPARATION,
-        std::vector<unsigned int>* outputVertStartIndices = NULL );
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertCluster( std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
-        std::vector<size_t>& out_indices,
-        std::vector<size_t>& index_out_indices,
-        std::vector<size_t>& count_out_indices,
-        const aiMatrix4x4& node_global_transform );
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo,
-        MatIndexArray::value_type materialIndex );
-
-    // ------------------------------------------------------------------------------------------------
-    unsigned int GetDefaultMaterial();
-
-
-    // ------------------------------------------------------------------------------------------------
-    // Material -> aiMaterial
-    unsigned int ConvertMaterial( const Material& material, const MeshGeometry* const mesh );
-
-    // ------------------------------------------------------------------------------------------------
-    // Video -> aiTexture
-    unsigned int ConvertVideo( const Video& video );
-
-    // ------------------------------------------------------------------------------------------------
-    void TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
-        const std::string& propName,
-        aiTextureType target, const MeshGeometry* const mesh );
-
-    // ------------------------------------------------------------------------------------------------
-    void TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
-        const std::string& propName,
-        aiTextureType target, const MeshGeometry* const mesh );
-
-    // ------------------------------------------------------------------------------------------------
-    void SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh );
-
-    // ------------------------------------------------------------------------------------------------
-    void SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh );
-
-    // ------------------------------------------------------------------------------------------------
-    aiColor3D GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName,
-        bool& result );
-
-    // ------------------------------------------------------------------------------------------------
-    void SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props );
-
-    // ------------------------------------------------------------------------------------------------
-    // get the number of fps for a FrameRate enumerated value
-    static double FrameRateToDouble( FileGlobalSettings::FrameRate fp, double customFPSVal = -1.0 );
-
-    // ------------------------------------------------------------------------------------------------
-    // convert animation data to aiAnimation et al
-    void ConvertAnimations();
-
-    // ------------------------------------------------------------------------------------------------
-    // rename a node already partially converted. fixed_name is a string previously returned by
-    // FixNodeName, new_name specifies the string FixNodeName should return on all further invocations
-    // which would previously have returned the old value.
-    //
-    // this also updates names in node animations, cameras and light sources and is thus slow.
-    //
-    // NOTE: the caller is responsible for ensuring that the new name is unique and does
-    // not collide with any other identifiers. The best way to ensure this is to only
-    // append to the old name, which is guaranteed to match these requirements.
-    void RenameNode( const std::string& fixed_name, const std::string& new_name );
-
-    // ------------------------------------------------------------------------------------------------
-    // takes a fbx node name and returns the identifier to be used in the assimp output scene.
-    // the function is guaranteed to provide consistent results over multiple invocations
-    // UNLESS RenameNode() is called for a particular node name.
-    std::string FixNodeName( const std::string& name );
-
-    typedef std::map<const AnimationCurveNode*, const AnimationLayer*> LayerMap;
-
-    // XXX: better use multi_map ..
-    typedef std::map<std::string, std::vector<const AnimationCurveNode*> > NodeMap;
-
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertAnimationStack( const AnimationStack& st );
-
-    // ------------------------------------------------------------------------------------------------
-    void GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
-        const std::string& fixed_name,
-        const std::vector<const AnimationCurveNode*>& curves,
-        const LayerMap& layer_map,
-        int64_t start, int64_t stop,
-        double& max_time,
-        double& min_time );
-
-    // ------------------------------------------------------------------------------------------------
-    bool IsRedundantAnimationData( const Model& target,
-        TransformationComp comp,
-        const std::vector<const AnimationCurveNode*>& curves );
-
-    // ------------------------------------------------------------------------------------------------
-    aiNodeAnim* GenerateRotationNodeAnim( const std::string& name,
-        const Model& target,
-        const std::vector<const AnimationCurveNode*>& curves,
-        const LayerMap& layer_map,
-        int64_t start, int64_t stop,
-        double& max_time,
-        double& min_time );
-
-    // ------------------------------------------------------------------------------------------------
-    aiNodeAnim* GenerateScalingNodeAnim( const std::string& name,
-        const Model& /*target*/,
-        const std::vector<const AnimationCurveNode*>& curves,
-        const LayerMap& layer_map,
-        int64_t start, int64_t stop,
-        double& max_time,
-        double& min_time );
-
-    // ------------------------------------------------------------------------------------------------
-    aiNodeAnim* GenerateTranslationNodeAnim( const std::string& name,
-        const Model& /*target*/,
-        const std::vector<const AnimationCurveNode*>& curves,
-        const LayerMap& layer_map,
-        int64_t start, int64_t stop,
-        double& max_time,
-        double& min_time,
-        bool inverse = false );
-
-    // ------------------------------------------------------------------------------------------------
-    // generate node anim, extracting only Rotation, Scaling and Translation from the given chain
-    aiNodeAnim* GenerateSimpleNodeAnim( const std::string& name,
-        const Model& target,
-        NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ],
-        NodeMap::const_iterator iter_end,
-        const LayerMap& layer_map,
-        int64_t start, int64_t stop,
-        double& max_time,
-        double& min_time,
-        bool reverse_order = false );
-
-    // key (time), value, mapto (component index)
-    typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
-    typedef std::vector<KeyFrameList> KeyFrameListList;
-
-    // ------------------------------------------------------------------------------------------------
-    KeyFrameListList GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop );
-
-    // ------------------------------------------------------------------------------------------------
-    KeyTimeList GetKeyTimeList( const KeyFrameListList& inputs );
-
-    // ------------------------------------------------------------------------------------------------
-    void InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
-        const aiVector3D& def_value,
-        double& max_time,
-        double& min_time );
-
-    // ------------------------------------------------------------------------------------------------
-    void InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
-        const aiVector3D& def_value,
-        double& maxTime,
-        double& minTime,
-        Model::RotOrder order );
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale,
-        aiVectorKey* out_translation,
-        const KeyFrameListList& scaling,
-        const KeyFrameListList& translation,
-        const KeyFrameListList& rotation,
-        const KeyTimeList& times,
-        double& maxTime,
-        double& minTime,
-        Model::RotOrder order,
-        const aiVector3D& def_scale,
-        const aiVector3D& def_translate,
-        const aiVector3D& def_rotation );
-
-    // ------------------------------------------------------------------------------------------------
-    // euler xyz -> quat
-    aiQuaternion EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order );
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
-        int64_t start, int64_t stop,
-        double& maxTime,
-        double& minTime );
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
-        const LayerMap& /*layers*/,
-        int64_t start, int64_t stop,
-        double& maxTime,
-        double& minTime );
-
-    // ------------------------------------------------------------------------------------------------
-    void ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
-        const LayerMap& /*layers*/,
-        int64_t start, int64_t stop,
-        double& maxTime,
-        double& minTime,
-        Model::RotOrder order );
-
-    // ------------------------------------------------------------------------------------------------
-    // copy generated meshes, animations, lights, cameras and textures to the output scene
-    void TransferDataToScene();
-
-private:
-
-    // 0: not assigned yet, others: index is value - 1
-    unsigned int defaultMaterialIndex;
-
-    std::vector<aiMesh*> meshes;
-    std::vector<aiMaterial*> materials;
-    std::vector<aiAnimation*> animations;
-    std::vector<aiLight*> lights;
-    std::vector<aiCamera*> cameras;
-    std::vector<aiTexture*> textures;
-
-    typedef std::map<const Material*, unsigned int> MaterialMap;
-    MaterialMap materials_converted;
-
-    typedef std::map<const Video*, unsigned int> VideoMap;
-    VideoMap textures_converted;
-
-    typedef std::map<const Geometry*, std::vector<unsigned int> > MeshMap;
-    MeshMap meshes_converted;
-
-    // fixed node name -> which trafo chain components have animations?
-    typedef std::map<std::string, unsigned int> NodeAnimBitMap;
-    NodeAnimBitMap node_anim_chain_bits;
-
-    // name -> has had its prefix_stripped?
-    typedef std::map<std::string, bool> NodeNameMap;
-    NodeNameMap node_names;
-
-    typedef std::map<std::string, std::string> NameNameMap;
-    NameNameMap renamed_nodes;
-
-    double anim_fps;
-
-    aiScene* const out;
-    const FBX::Document& doc;
-
-	bool FindTextureIndexByFilename(const Video& video, unsigned int& index) {
-		index = 0;
-		const char* videoFileName = video.FileName().c_str();
-		for (auto texture = textures_converted.begin(); texture != textures_converted.end(); ++texture) {
-			if (!strcmp(texture->first->FileName().c_str(), videoFileName)) {
-                index = texture->second;
-				return true;
-			}
-		}
-		return false;
-	}
-};
 
 Converter::Converter( aiScene* out, const Document& doc )
-    : defaultMaterialIndex()
-    , out( out )
-    , doc( doc )
-{
+: defaultMaterialIndex()
+, out( out )
+, doc( doc ) {
     // animations need to be converted first since this will
     // populate the node_anim_chain_bits map, which is needed
     // to determine which nodes need to be generated.
@@ -480,6 +103,7 @@ Converter::Converter( aiScene* out, const Document& doc )
         }
     }
 
+    ConvertGlobalSettings();
     TransferDataToScene();
 
     // if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
@@ -491,8 +115,7 @@ Converter::Converter( aiScene* out, const Document& doc )
 }
 
 
-Converter::~Converter()
-{
+Converter::~Converter() {
     std::for_each( meshes.begin(), meshes.end(), Util::delete_fun<aiMesh>() );
     std::for_each( materials.begin(), materials.end(), Util::delete_fun<aiMaterial>() );
     std::for_each( animations.begin(), animations.end(), Util::delete_fun<aiAnimation>() );
@@ -501,8 +124,7 @@ Converter::~Converter()
     std::for_each( textures.begin(), textures.end(), Util::delete_fun<aiTexture>() );
 }
 
-void Converter::ConvertRootNode()
-{
+void Converter::ConvertRootNode() {
     out->mRootNode = new aiNode();
     out->mRootNode->mName.Set( "RootNode" );
 
@@ -729,10 +351,12 @@ void Converter::ConvertCamera( const Model& model, const Camera& cam )
     out_camera->mName.Set( FixNodeName( model.Name() ) );
 
     out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
+
     //cameras are defined along positive x direction
-    out_camera->mPosition = aiVector3D(0.0f);
-    out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
-    out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
+    out_camera->mPosition = cam.Position();
+    out_camera->mLookAt = ( cam.InterestPosition() - out_camera->mPosition ).Normalize();
+    out_camera->mUp = cam.UpVector();
+
     out_camera->mHorizontalFOV = AI_DEG_TO_RAD( cam.FieldOfView() );
     out_camera->mClipPlaneNear = cam.NearPlane();
     out_camera->mClipPlaneFar = cam.FarPlane();
@@ -1505,14 +1129,14 @@ unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, cons
                 out_mesh->mBitangents[ cursor ] = ( *binormals )[ in_cursor ];
             }
 
-            for ( unsigned int i = 0; i < num_uvs; ++i ) {
-                const std::vector<aiVector2D>& uvs = mesh.GetTextureCoords( i );
-                out_mesh->mTextureCoords[ i ][ cursor ] = aiVector3D( uvs[ in_cursor ].x, uvs[ in_cursor ].y, 0.0f );
+            for ( unsigned int j = 0; j < num_uvs; ++j ) {
+                const std::vector<aiVector2D>& uvs = mesh.GetTextureCoords( j );
+                out_mesh->mTextureCoords[ j ][ cursor ] = aiVector3D( uvs[ in_cursor ].x, uvs[ in_cursor ].y, 0.0f );
             }
 
-            for ( unsigned int i = 0; i < num_vcs; ++i ) {
-                const std::vector<aiColor4D>& cols = mesh.GetVertexColors( i );
-                out_mesh->mColors[ i ][ cursor ] = cols[ in_cursor ];
+            for ( unsigned int j = 0; j < num_vcs; ++j ) {
+                const std::vector<aiColor4D>& cols = mesh.GetVertexColors( j );
+                out_mesh->mColors[ j ][ cursor ] = cols[ in_cursor ];
             }
         }
     }
@@ -1728,7 +1352,7 @@ unsigned int Converter::ConvertMaterial( const Material& material, const MeshGeo
 
     aiString str;
 
-    // stip Material:: prefix
+    // strip Material:: prefix
     std::string name = material.Name();
     if ( name.substr( 0, 10 ) == "Material::" ) {
         name = name.substr( 10 );
@@ -1776,6 +1400,8 @@ unsigned int Converter::ConvertVideo( const Video& video )
         memcpy( out_tex->achFormatHint, ext.c_str(), ext.size() );
     }
 
+    out_tex->mFilename.Set(video.FileName().c_str());
+
     return static_cast<unsigned int>( textures.size() - 1 );
 }
 
@@ -1810,15 +1436,19 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
 					textures_converted[media] = index;
 					textureReady = true;
 				}
-				else if (doc.Settings().searchEmbeddedTextures) { //try to find the texture on the already-loaded textures by the filename, if the flag is on					
-					textureReady = FindTextureIndexByFilename(*media, index);
-				}
 			}
 
 			// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture), if the texture is ready
-			if (textureReady) {
-				path.data[0] = '*';
-				path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
+			if (doc.Settings().useLegacyEmbeddedTextureNaming) {
+                if (textureReady) {
+                    // TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
+                    // In FBX files textures are now stored internally by Assimp with their filename included
+                    // Now Assimp can lookup thru the loaded textures after all data is processed
+                    // We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
+                    // This may occur on this case too, it has to be studied
+                    path.data[0] = '*';
+                    path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
+                }
 			}
 		}  
 
@@ -2083,40 +1713,62 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureM
     TrySetTextureProperties( out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh );
 }
 
-aiColor3D Converter::GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName,
-    bool& result )
+aiColor3D Converter::GetColorPropertyFactored( const PropertyTable& props, const std::string& colorName,
+    const std::string& factorName, bool& result, bool useTemplate )
 {
     result = true;
 
     bool ok;
-    const aiVector3D& Diffuse = PropertyGet<aiVector3D>( props, baseName, ok );
-    if ( ok ) {
-        return aiColor3D( Diffuse.x, Diffuse.y, Diffuse.z );
+    aiVector3D BaseColor = PropertyGet<aiVector3D>( props, colorName, ok, useTemplate );
+    if ( ! ok ) {
+        result = false;
+        return aiColor3D( 0.0f, 0.0f, 0.0f );
     }
-    else {
-        aiVector3D DiffuseColor = PropertyGet<aiVector3D>( props, baseName + "Color", ok );
-        if ( ok ) {
-            float DiffuseFactor = PropertyGet<float>( props, baseName + "Factor", ok );
-            if ( ok ) {
-                DiffuseColor *= DiffuseFactor;
-            }
 
-            return aiColor3D( DiffuseColor.x, DiffuseColor.y, DiffuseColor.z );
-        }
+    // if no factor name, return the colour as is
+    if ( factorName.empty() ) {
+        return aiColor3D( BaseColor.x, BaseColor.y, BaseColor.z );
     }
-    result = false;
-    return aiColor3D( 0.0f, 0.0f, 0.0f );
+
+    // otherwise it should be multiplied by the factor, if found.
+    float factor = PropertyGet<float>( props, factorName, ok, useTemplate );
+    if ( ok ) {
+        BaseColor *= factor;
+    }
+    return aiColor3D( BaseColor.x, BaseColor.y, BaseColor.z );
+}
+
+aiColor3D Converter::GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName,
+    bool& result )
+{
+    return GetColorPropertyFactored( props, baseName + "Color", baseName + "Factor", result, true );
 }
 
+aiColor3D Converter::GetColorProperty( const PropertyTable& props, const std::string& colorName,
+    bool& result, bool useTemplate )
+{
+    result = true;
+    bool ok;
+    const aiVector3D& ColorVec = PropertyGet<aiVector3D>( props, colorName, ok, useTemplate );
+    if ( ! ok ) {
+        result = false;
+        return aiColor3D( 0.0f, 0.0f, 0.0f );
+    }
+    return aiColor3D( ColorVec.x, ColorVec.y, ColorVec.z );
+}
 
 void Converter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props )
 {
-    // set shading properties. There are various, redundant ways in which FBX materials
-    // specify their shading settings (depending on shading models, prop
-    // template etc.). No idea which one is right in a particular context.
-    // Just try to make sense of it - there's no spec to verify this against,
-    // so why should we.
+    // Set shading properties.
+    // Modern FBX Files have two separate systems for defining these,
+    // with only the more comprehensive one described in the property template.
+    // Likely the other values are a legacy system,
+    // which is still always exported by the official FBX SDK.
+    //
+    // Blender's FBX import and export mostly ignore this legacy system,
+    // and as we only support recent versions of FBX anyway, we can do the same.
     bool ok;
+
     const aiColor3D& Diffuse = GetColorPropertyFromMaterial( props, "Diffuse", ok );
     if ( ok ) {
         out_mat->AddProperty( &Diffuse, 1, AI_MATKEY_COLOR_DIFFUSE );
@@ -2132,29 +1784,64 @@ void Converter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyT
         out_mat->AddProperty( &Ambient, 1, AI_MATKEY_COLOR_AMBIENT );
     }
 
-    const aiColor3D& Specular = GetColorPropertyFromMaterial( props, "Specular", ok );
+    // we store specular factor as SHININESS_STRENGTH, so just get the color
+    const aiColor3D& Specular = GetColorProperty( props, "SpecularColor", ok, true );
     if ( ok ) {
         out_mat->AddProperty( &Specular, 1, AI_MATKEY_COLOR_SPECULAR );
     }
 
-    const float Opacity = PropertyGet<float>( props, "Opacity", ok );
+    // and also try to get SHININESS_STRENGTH
+    const float SpecularFactor = PropertyGet<float>( props, "SpecularFactor", ok, true );
     if ( ok ) {
-        out_mat->AddProperty( &Opacity, 1, AI_MATKEY_OPACITY );
+        out_mat->AddProperty( &SpecularFactor, 1, AI_MATKEY_SHININESS_STRENGTH );
+    }
+
+    // and the specular exponent
+    const float ShininessExponent = PropertyGet<float>( props, "ShininessExponent", ok );
+    if ( ok ) {
+        out_mat->AddProperty( &ShininessExponent, 1, AI_MATKEY_SHININESS );
     }
 
-    const float Reflectivity = PropertyGet<float>( props, "Reflectivity", ok );
+    // TransparentColor / TransparencyFactor... gee thanks FBX :rolleyes:
+    const aiColor3D& Transparent = GetColorPropertyFactored( props, "TransparentColor", "TransparencyFactor", ok );
+    float CalculatedOpacity = 1.0;
     if ( ok ) {
-        out_mat->AddProperty( &Reflectivity, 1, AI_MATKEY_REFLECTIVITY );
+        out_mat->AddProperty( &Transparent, 1, AI_MATKEY_COLOR_TRANSPARENT );
+        // as calculated by FBX SDK 2017:
+        CalculatedOpacity = 1.0 - ((Transparent.r + Transparent.g + Transparent.b) / 3.0);
     }
 
-    const float Shininess = PropertyGet<float>( props, "Shininess", ok );
+    // use of TransparencyFactor is inconsistent.
+    // Maya always stores it as 1.0,
+    // so we can't use it to set AI_MATKEY_OPACITY.
+    // Blender is more sensible and stores it as the alpha value.
+    // However both the FBX SDK and Blender always write an additional
+    // legacy "Opacity" field, so we can try to use that.
+    //
+    // If we can't find it,
+    // we can fall back to the value which the FBX SDK calculates
+    // from transparency colour (RGB) and factor (F) as
+    // 1.0 - F*((R+G+B)/3).
+    //
+    // There's no consistent way to interpret this opacity value,
+    // so it's up to clients to do the correct thing.
+    const float Opacity = PropertyGet<float>( props, "Opacity", ok );
     if ( ok ) {
-        out_mat->AddProperty( &Shininess, 1, AI_MATKEY_SHININESS_STRENGTH );
+        out_mat->AddProperty( &Opacity, 1, AI_MATKEY_OPACITY );
+    }
+    else if ( CalculatedOpacity != 1.0 ) {
+        out_mat->AddProperty( &CalculatedOpacity, 1, AI_MATKEY_OPACITY );
     }
 
-    const float ShininessExponent = PropertyGet<float>( props, "ShininessExponent", ok );
+    // reflection color and factor are stored separately
+    const aiColor3D& Reflection = GetColorProperty( props, "ReflectionColor", ok, true );
     if ( ok ) {
-        out_mat->AddProperty( &ShininessExponent, 1, AI_MATKEY_SHININESS );
+        out_mat->AddProperty( &Reflection, 1, AI_MATKEY_COLOR_REFLECTIVE );
+    }
+
+    float ReflectionFactor = PropertyGet<float>( props, "ReflectionFactor", ok, true );
+    if ( ok ) {
+        out_mat->AddProperty( &ReflectionFactor, 1, AI_MATKEY_REFLECTIVITY );
     }
 
     const float BumpFactor = PropertyGet<float>(props, "BumpFactor", ok);
@@ -3286,8 +2973,20 @@ void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const Ani
 
     na->mNumRotationKeys = static_cast<unsigned int>( keys.size() );
     na->mRotationKeys = new aiQuatKey[ keys.size() ];
-    if ( keys.size() > 0 )
-        InterpolateKeys( na->mRotationKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime, order );
+    if (!keys.empty()) {
+        InterpolateKeys(na->mRotationKeys, keys, inputs, aiVector3D(0.0f, 0.0f, 0.0f), maxTime, minTime, order);
+    }
+}
+
+void Converter::ConvertGlobalSettings() {
+    if (nullptr == out) {
+        return;
+    }
+
+    out->mMetaData = aiMetadata::Alloc(1);
+    unsigned int index(0);
+    const double unitScalFactor(doc.GlobalSettings().UnitScaleFactor());
+    out->mMetaData->Set(index, "UnitScaleFactor", unitScalFactor);
 }
 
 void Converter::TransferDataToScene()

+ 382 - 0
code/FBXConverter.h

@@ -45,7 +45,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_FBX_CONVERTER_H
 #define INCLUDED_AI_FBX_CONVERTER_H
 
+#include "FBXParser.h"
+#include "FBXMeshGeometry.h"
+#include "FBXDocument.h"
+#include "FBXUtil.h"
+#include "FBXProperties.h"
+#include "FBXImporter.h"
+#include <assimp/anim.h>
+#include <assimp/material.h>
+#include <assimp/light.h>
+#include <assimp/texture.h>
+#include <assimp/camera.h>
+#include <assimp/StringComparison.h>
+
 struct aiScene;
+struct aiNode;
+struct aiMaterial;
 
 namespace Assimp {
 namespace FBX {
@@ -59,6 +74,373 @@ class Document;
  */
 void ConvertToAssimpScene(aiScene* out, const Document& doc);
 
+/** Dummy class to encapsulate the conversion process */
+class Converter {
+public:
+    /**
+    *  The different parts that make up the final local transformation of a fbx-node
+    */
+    enum TransformationComp {
+        TransformationComp_Translation = 0,
+        TransformationComp_RotationOffset,
+        TransformationComp_RotationPivot,
+        TransformationComp_PreRotation,
+        TransformationComp_Rotation,
+        TransformationComp_PostRotation,
+        TransformationComp_RotationPivotInverse,
+        TransformationComp_ScalingOffset,
+        TransformationComp_ScalingPivot,
+        TransformationComp_Scaling,
+        TransformationComp_ScalingPivotInverse,
+        TransformationComp_GeometricTranslation,
+        TransformationComp_GeometricRotation,
+        TransformationComp_GeometricScaling,
+
+        TransformationComp_MAXIMUM
+    };
+
+public:
+    Converter(aiScene* out, const Document& doc);
+    ~Converter();
+
+private:
+    // ------------------------------------------------------------------------------------------------
+    // find scene root and trigger recursive scene conversion
+    void ConvertRootNode();
+
+    // ------------------------------------------------------------------------------------------------
+    // collect and assign child nodes
+    void ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4());
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertLights(const Model& model);
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertCameras(const Model& model);
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertLight(const Model& model, const Light& light);
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertCamera(const Model& model, const Camera& cam);
+
+    // ------------------------------------------------------------------------------------------------
+    // this returns unified names usable within assimp identifiers (i.e. no space characters -
+    // while these would be allowed, they are a potential trouble spot so better not use them).
+    const char* NameTransformationComp(TransformationComp comp);
+
+    // ------------------------------------------------------------------------------------------------
+    // note: this returns the REAL fbx property names
+    const char* NameTransformationCompProperty(TransformationComp comp);
+
+    // ------------------------------------------------------------------------------------------------
+    aiVector3D TransformationCompDefaultValue(TransformationComp comp);
+
+    // ------------------------------------------------------------------------------------------------
+    void GetRotationMatrix(Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out);
+    // ------------------------------------------------------------------------------------------------
+    /**
+    *  checks if a node has more than just scaling, rotation and translation components
+    */
+    bool NeedsComplexTransformationChain(const Model& model);
+
+    // ------------------------------------------------------------------------------------------------
+    // note: name must be a FixNodeName() result
+    std::string NameTransformationChainNode(const std::string& name, TransformationComp comp);
+
+    // ------------------------------------------------------------------------------------------------
+    /**
+    *  note: memory for output_nodes will be managed by the caller
+    */
+    void GenerateTransformationNodeChain(const Model& model, std::vector<aiNode*>& output_nodes);
+
+    // ------------------------------------------------------------------------------------------------
+    void SetupNodeMetadata(const Model& model, aiNode& nd);
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform);
+
+    // ------------------------------------------------------------------------------------------------
+    // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
+    std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh, const Model& model,
+        const aiMatrix4x4& node_global_transform);
+
+    // ------------------------------------------------------------------------------------------------
+    aiMesh* SetupEmptyMesh(const MeshGeometry& mesh);
+
+    // ------------------------------------------------------------------------------------------------
+    unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
+        const aiMatrix4x4& node_global_transform);
+
+    // ------------------------------------------------------------------------------------------------
+    std::vector<unsigned int> ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
+        const aiMatrix4x4& node_global_transform);
+
+    // ------------------------------------------------------------------------------------------------
+    unsigned int ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
+        MatIndexArray::value_type index,
+        const aiMatrix4x4& node_global_transform);
+
+    // ------------------------------------------------------------------------------------------------
+    static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
+        static_cast<unsigned int>(-1);
+
+    // ------------------------------------------------------------------------------------------------
+    /**
+    *  - if materialIndex == NO_MATERIAL_SEPARATION, materials are not taken into
+    *    account when determining which weights to include.
+    *  - outputVertStartIndices is only used when a material index is specified, it gives for
+    *    each output vertex the DOM index it maps to.
+    */
+    void ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
+        const aiMatrix4x4& node_global_transform = aiMatrix4x4(),
+        unsigned int materialIndex = NO_MATERIAL_SEPARATION,
+        std::vector<unsigned int>* outputVertStartIndices = NULL);
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertCluster(std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
+        std::vector<size_t>& out_indices,
+        std::vector<size_t>& index_out_indices,
+        std::vector<size_t>& count_out_indices,
+        const aiMatrix4x4& node_global_transform);
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
+        MatIndexArray::value_type materialIndex);
+
+    // ------------------------------------------------------------------------------------------------
+    unsigned int GetDefaultMaterial();
+
+    // ------------------------------------------------------------------------------------------------
+    // Material -> aiMaterial
+    unsigned int ConvertMaterial(const Material& material, const MeshGeometry* const mesh);
+
+    // ------------------------------------------------------------------------------------------------
+    // Video -> aiTexture
+    unsigned int ConvertVideo(const Video& video);
+
+    // ------------------------------------------------------------------------------------------------
+    void TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures,
+        const std::string& propName,
+        aiTextureType target, const MeshGeometry* const mesh);
+
+    // ------------------------------------------------------------------------------------------------
+    void TrySetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
+        const std::string& propName,
+        aiTextureType target, const MeshGeometry* const mesh);
+
+    // ------------------------------------------------------------------------------------------------
+    void SetTextureProperties(aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh);
+
+    // ------------------------------------------------------------------------------------------------
+    void SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh);
+
+    // ------------------------------------------------------------------------------------------------
+    aiColor3D GetColorPropertyFromMaterial(const PropertyTable& props, const std::string& baseName,
+        bool& result);
+    aiColor3D GetColorPropertyFactored(const PropertyTable& props, const std::string& colorName,
+        const std::string& factorName, bool& result, bool useTemplate = true);
+    aiColor3D GetColorProperty(const PropertyTable& props, const std::string& colorName,
+        bool& result, bool useTemplate = true);
+
+    // ------------------------------------------------------------------------------------------------
+    void SetShadingPropertiesCommon(aiMaterial* out_mat, const PropertyTable& props);
+
+    // ------------------------------------------------------------------------------------------------
+    // get the number of fps for a FrameRate enumerated value
+    static double FrameRateToDouble(FileGlobalSettings::FrameRate fp, double customFPSVal = -1.0);
+
+    // ------------------------------------------------------------------------------------------------
+    // convert animation data to aiAnimation et al
+    void ConvertAnimations();
+
+    // ------------------------------------------------------------------------------------------------
+    // rename a node already partially converted. fixed_name is a string previously returned by
+    // FixNodeName, new_name specifies the string FixNodeName should return on all further invocations
+    // which would previously have returned the old value.
+    //
+    // this also updates names in node animations, cameras and light sources and is thus slow.
+    //
+    // NOTE: the caller is responsible for ensuring that the new name is unique and does
+    // not collide with any other identifiers. The best way to ensure this is to only
+    // append to the old name, which is guaranteed to match these requirements.
+    void RenameNode(const std::string& fixed_name, const std::string& new_name);
+
+    // ------------------------------------------------------------------------------------------------
+    // takes a fbx node name and returns the identifier to be used in the assimp output scene.
+    // the function is guaranteed to provide consistent results over multiple invocations
+    // UNLESS RenameNode() is called for a particular node name.
+    std::string FixNodeName(const std::string& name);
+
+    typedef std::map<const AnimationCurveNode*, const AnimationLayer*> LayerMap;
+
+    // XXX: better use multi_map ..
+    typedef std::map<std::string, std::vector<const AnimationCurveNode*> > NodeMap;
+
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertAnimationStack(const AnimationStack& st);
+
+    // ------------------------------------------------------------------------------------------------
+    void GenerateNodeAnimations(std::vector<aiNodeAnim*>& node_anims,
+        const std::string& fixed_name,
+        const std::vector<const AnimationCurveNode*>& curves,
+        const LayerMap& layer_map,
+        int64_t start, int64_t stop,
+        double& max_time,
+        double& min_time);
+
+    // ------------------------------------------------------------------------------------------------
+    bool IsRedundantAnimationData(const Model& target,
+        TransformationComp comp,
+        const std::vector<const AnimationCurveNode*>& curves);
+
+    // ------------------------------------------------------------------------------------------------
+    aiNodeAnim* GenerateRotationNodeAnim(const std::string& name,
+        const Model& target,
+        const std::vector<const AnimationCurveNode*>& curves,
+        const LayerMap& layer_map,
+        int64_t start, int64_t stop,
+        double& max_time,
+        double& min_time);
+
+    // ------------------------------------------------------------------------------------------------
+    aiNodeAnim* GenerateScalingNodeAnim(const std::string& name,
+        const Model& /*target*/,
+        const std::vector<const AnimationCurveNode*>& curves,
+        const LayerMap& layer_map,
+        int64_t start, int64_t stop,
+        double& max_time,
+        double& min_time);
+
+    // ------------------------------------------------------------------------------------------------
+    aiNodeAnim* GenerateTranslationNodeAnim(const std::string& name,
+        const Model& /*target*/,
+        const std::vector<const AnimationCurveNode*>& curves,
+        const LayerMap& layer_map,
+        int64_t start, int64_t stop,
+        double& max_time,
+        double& min_time,
+        bool inverse = false);
+
+    // ------------------------------------------------------------------------------------------------
+    // generate node anim, extracting only Rotation, Scaling and Translation from the given chain
+    aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name,
+        const Model& target,
+        NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
+        NodeMap::const_iterator iter_end,
+        const LayerMap& layer_map,
+        int64_t start, int64_t stop,
+        double& max_time,
+        double& min_time,
+        bool reverse_order = false);
+
+    // key (time), value, mapto (component index)
+    typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
+    typedef std::vector<KeyFrameList> KeyFrameListList;
+
+    // ------------------------------------------------------------------------------------------------
+    KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop);
+
+    // ------------------------------------------------------------------------------------------------
+    KeyTimeList GetKeyTimeList(const KeyFrameListList& inputs);
+
+    // ------------------------------------------------------------------------------------------------
+    void InterpolateKeys(aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
+        const aiVector3D& def_value,
+        double& max_time,
+        double& min_time);
+
+    // ------------------------------------------------------------------------------------------------
+    void InterpolateKeys(aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
+        const aiVector3D& def_value,
+        double& maxTime,
+        double& minTime,
+        Model::RotOrder order);
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertTransformOrder_TRStoSRT(aiQuatKey* out_quat, aiVectorKey* out_scale,
+        aiVectorKey* out_translation,
+        const KeyFrameListList& scaling,
+        const KeyFrameListList& translation,
+        const KeyFrameListList& rotation,
+        const KeyTimeList& times,
+        double& maxTime,
+        double& minTime,
+        Model::RotOrder order,
+        const aiVector3D& def_scale,
+        const aiVector3D& def_translate,
+        const aiVector3D& def_rotation);
+
+    // ------------------------------------------------------------------------------------------------
+    // euler xyz -> quat
+    aiQuaternion EulerToQuaternion(const aiVector3D& rot, Model::RotOrder order);
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
+        int64_t start, int64_t stop,
+        double& maxTime,
+        double& minTime);
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
+        const LayerMap& /*layers*/,
+        int64_t start, int64_t stop,
+        double& maxTime,
+        double& minTime);
+
+    // ------------------------------------------------------------------------------------------------
+    void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
+        const LayerMap& /*layers*/,
+        int64_t start, int64_t stop,
+        double& maxTime,
+        double& minTime,
+        Model::RotOrder order);
+
+    void ConvertGlobalSettings();
+
+    // ------------------------------------------------------------------------------------------------
+    // copy generated meshes, animations, lights, cameras and textures to the output scene
+    void TransferDataToScene();
+
+private:
+
+    // 0: not assigned yet, others: index is value - 1
+    unsigned int defaultMaterialIndex;
+
+    std::vector<aiMesh*> meshes;
+    std::vector<aiMaterial*> materials;
+    std::vector<aiAnimation*> animations;
+    std::vector<aiLight*> lights;
+    std::vector<aiCamera*> cameras;
+    std::vector<aiTexture*> textures;
+
+    typedef std::map<const Material*, unsigned int> MaterialMap;
+    MaterialMap materials_converted;
+
+    typedef std::map<const Video*, unsigned int> VideoMap;
+    VideoMap textures_converted;
+
+    typedef std::map<const Geometry*, std::vector<unsigned int> > MeshMap;
+    MeshMap meshes_converted;
+
+    // fixed node name -> which trafo chain components have animations?
+    typedef std::map<std::string, unsigned int> NodeAnimBitMap;
+    NodeAnimBitMap node_anim_chain_bits;
+
+    // name -> has had its prefix_stripped?
+    typedef std::map<std::string, bool> NodeNameMap;
+    NodeNameMap node_names;
+
+    typedef std::map<std::string, std::string> NameNameMap;
+    NameNameMap renamed_nodes;
+
+    double anim_fps;
+
+    aiScene* const out;
+    const FBX::Document& doc;
+};
+
 }
 }
 

+ 4 - 5
code/FBXDocument.cpp

@@ -344,9 +344,8 @@ void Document::ReadGlobalSettings()
 {
     const Scope& sc = parser.GetRootScope();
     const Element* const ehead = sc["GlobalSettings"];
-    if(!ehead || !ehead->Compound()) {
-        DOMWarning("no GlobalSettings dictionary found");
-
+    if ( nullptr == ehead || !ehead->Compound() ) {
+        DOMWarning( "no GlobalSettings dictionary found" );
         globals.reset(new FileGlobalSettings(*this, std::make_shared<const PropertyTable>()));
         return;
     }
@@ -619,10 +618,10 @@ std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_
 }
 
 // ------------------------------------------------------------------------------------------------
-std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t dest, const char* classname) const
+std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t src, const char* classname) const
 {
     const char* arr[] = {classname};
-    return GetConnectionsBySourceSequenced(dest, arr,1);
+    return GetConnectionsBySourceSequenced(src, arr,1);
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 2
code/FBXDocument.h

@@ -999,8 +999,7 @@ typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
 
 /** DOM class for global document settings, a single instance per document can
  *  be accessed via Document.Globals(). */
-class FileGlobalSettings
-{
+class FileGlobalSettings {
 public:
     FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props);
     ~FileGlobalSettings();

+ 1 - 1
code/FBXDocumentUtil.h

@@ -105,7 +105,7 @@ inline const T* ProcessSimpleConnection(const Connection& con,
 
     const Object* const ob = con.SourceObject();
     if(!ob) {
-        DOMWarning("failed to read source object for incoming" + std::string(name) +
+        DOMWarning("failed to read source object for incoming " + std::string(name) +
             " link, ignoring",
             &element);
         return NULL;

+ 4 - 4
code/FBXImportSettings.h

@@ -63,7 +63,7 @@ struct ImportSettings
         , readWeights(true)
         , preservePivots(true)
         , optimizeEmptyAnimationCurves(true)
-		, searchEmbeddedTextures(false)
+        , useLegacyEmbeddedTextureNaming(false)
     {}
 
 
@@ -139,9 +139,9 @@ struct ImportSettings
      *  The default value is true. */
     bool optimizeEmptyAnimationCurves;
 
-	/** search for embedded loaded textures, where no embedded texture data is provided.
-	*  The default value is false. */
-	bool searchEmbeddedTextures;
+    /** use legacy naming for embedded textures eg: (*0, *1, *2)
+    **/
+    bool useLegacyEmbeddedTextureNaming;
 };
 
 

+ 4 - 5
code/FBXImporter.cpp

@@ -53,8 +53,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXDocument.h"
 #include "FBXConverter.h"
 
-#include "StreamReader.h"
-#include "MemoryIOWrapper.h"
+#include <assimp/StreamReader.h>
+#include <assimp/MemoryIOWrapper.h>
 #include <assimp/Importer.hpp>
 #include <assimp/importerdesc.h>
 
@@ -135,13 +135,12 @@ void FBXImporter::SetupProperties(const Importer* pImp)
     settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
     settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
     settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
-	settings.searchEmbeddedTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES, false);
+    settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure.
-void FBXImporter::InternReadFile( const std::string& pFile,
-    aiScene* pScene, IOSystem* pIOHandler)
+void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
 {
     std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
     if (!stream) {

+ 2 - 2
code/FBXImporter.h

@@ -45,8 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_FBX_IMPORTER_H
 #define INCLUDED_AI_FBX_IMPORTER_H
 
-#include "BaseImporter.h"
-#include "LogAux.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/LogAux.h>
 
 #include "FBXImportSettings.h"
 

+ 1 - 1
code/FBXMaterial.cpp

@@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXImportSettings.h"
 #include "FBXDocumentUtil.h"
 #include "FBXProperties.h"
-#include "ByteSwapper.h"
+#include <assimp/ByteSwapper.h>
 
 namespace Assimp {
 namespace FBX {

+ 8 - 2
code/FBXMeshGeometry.cpp

@@ -433,7 +433,11 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
     // deal with this more elegantly and with less redundancy, but right
     // now it seems unavoidable.
     if (MappingInformationType == "ByVertice" && ReferenceInformationType == "Direct") {
-		std::vector<T> tempData;
+        if ( !HasElement( source, indexDataElementName ) ) {
+            return;
+        }
+
+        std::vector<T> tempData;
 		ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
 
         data_out.resize(vertex_count);
@@ -450,10 +454,12 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
 		ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
 
         data_out.resize(vertex_count);
+        if ( !HasElement( source, indexDataElementName ) ) {
+            return;
+        }
 
         std::vector<int> uvIndices;
         ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
-
         for (size_t i = 0, e = uvIndices.size(); i < e; ++i) {
 
             const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i];

+ 23 - 18
code/FBXParser.cpp

@@ -45,7 +45,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
 
-
 #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
 #   include <zlib.h>
 #else
@@ -56,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXParser.h"
 #include "FBXUtil.h"
 
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include "ByteSwapper.h"
+#include <assimp/ParsingUtils.h>
+#include <assimp/fast_atof.h>
+#include <assimp/ByteSwapper.h>
 
 #include <iostream>
 
@@ -67,7 +66,6 @@ using namespace Assimp::FBX;
 
 namespace {
 
-
     // ------------------------------------------------------------------------------------------------
     // signal parse error, this is always unrecoverable. Throws DeadlyImportError.
     AI_WONT_RETURN void ParseError(const std::string& message, const Token& token) AI_WONT_RETURN_SUFFIX;
@@ -213,7 +211,6 @@ Scope::~Scope()
     }
 }
 
-
 // ------------------------------------------------------------------------------------------------
 Parser::Parser (const TokenList& tokens, bool is_binary)
 : tokens(tokens)
@@ -537,18 +534,18 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
     uint32_t stride = 0;
     switch(type)
     {
-    case 'f':
-    case 'i':
-        stride = 4;
-        break;
-
-    case 'd':
-    case 'l':
-        stride = 8;
-        break;
-
-    default:
-        ai_assert(false);
+        case 'f':
+        case 'i':
+            stride = 4;
+            break;
+
+        case 'd':
+        case 'l':
+            stride = 8;
+            break;
+
+        default:
+            ai_assert(false);
     };
 
     const uint32_t full_length = stride * count;
@@ -1197,6 +1194,14 @@ std::string ParseTokenAsString(const Token& t)
     return i;
 }
 
+bool HasElement( const Scope& sc, const std::string& index ) {
+    const Element* el = sc[ index ];
+    if ( nullptr == el ) {
+        return false;
+    }
+
+    return true;
+}
 
 // ------------------------------------------------------------------------------------------------
 // extract a required element from a scope, abort if the element cannot be found

+ 4 - 5
code/FBXParser.h

@@ -48,8 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <stdint.h>
 #include <map>
 #include <memory>
-#include "LogAux.h"
-#include "fast_atof.h"
+#include <assimp/LogAux.h>
+#include <assimp/fast_atof.h>
 
 #include "FBXCompileConfig.h"
 #include "FBXTokenizer.h"
@@ -174,11 +174,9 @@ private:
     friend class Element;
 
     TokenPtr AdvanceToNextToken();
-
     TokenPtr LastToken() const;
     TokenPtr CurrentToken() const;
 
-
 private:
     const TokenList& tokens;
 
@@ -199,7 +197,6 @@ int ParseTokenAsInt(const Token& t, const char*& err_out);
 int64_t ParseTokenAsInt64(const Token& t, const char*& err_out);
 std::string ParseTokenAsString(const Token& t, const char*& err_out);
 
-
 /* wrapper around ParseTokenAsXXX() with DOMError handling */
 uint64_t ParseTokenAsID(const Token& t);
 size_t ParseTokenAsDim(const Token& t);
@@ -218,6 +215,8 @@ void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el);
 void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& e);
 void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el);
 
+bool HasElement( const Scope& sc, const std::string& index );
+
 // extract a required element from a scope, abort if the element cannot be found
 const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL);
 

+ 1 - 4
code/FBXProperties.cpp

@@ -108,7 +108,7 @@ Property* ReadTypedProperty(const Element& element)
             ParseTokenAsFloat(*tok[6]))
         );
     }
-    else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView")) {
+    else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView") || !strcmp( cs, "UnitScaleFactor" ) ) {
         return new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
     }
     return NULL;
@@ -138,7 +138,6 @@ PropertyTable::PropertyTable()
 {
 }
 
-
 // ------------------------------------------------------------------------------------------------
 PropertyTable::PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps)
 : templateProps(templateProps)
@@ -229,8 +228,6 @@ DirectPropertyMap PropertyTable::GetUnparsedProperties() const
     return result;
 }
 
-
-
 } //! FBX
 } //! Assimp
 

+ 16 - 4
code/FBXProperties.h

@@ -148,11 +148,23 @@ T PropertyGet(const PropertyTable& in, const std::string& name, const T& default
 // ------------------------------------------------------------------------------------------------
 template <typename T>
 inline 
-T PropertyGet(const PropertyTable& in, const std::string& name, bool& result) {
-    const Property* const prop = in.Get(name);
+T PropertyGet(const PropertyTable& in, const std::string& name, bool& result, bool useTemplate=false ) {
+    const Property* prop = in.Get(name);
     if( nullptr == prop) {
-        result = false;
-        return T();
+        if ( ! useTemplate ) {
+            result = false;
+            return T();
+        }
+        const PropertyTable* templ = in.TemplateProps();
+        if ( nullptr == templ ) {
+            result = false;
+            return T();
+        }
+        prop = templ->Get(name);
+        if ( nullptr == prop ) {
+            result = false;
+            return T();
+        }
     }
 
     // strong typing, no need to be lenient

+ 2 - 4
code/FBXTokenizer.cpp

@@ -48,11 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // tab width for logging columns
 #define ASSIMP_FBX_TAB_WIDTH 4
 
-#include "ParsingUtils.h"
+#include <assimp/ParsingUtils.h>
 
 #include "FBXTokenizer.h"
 #include "FBXUtil.h"
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 
 namespace Assimp {
 namespace FBX {
@@ -76,13 +76,11 @@ Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int
     ai_assert(static_cast<size_t>(send-sbegin) > 0);
 }
 
-
 // ------------------------------------------------------------------------------------------------
 Token::~Token()
 {
 }
 
-
 namespace {
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/FBXUtil.cpp

@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXUtil.h"
 #include "FBXTokenizer.h"
 
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 #include <string>
 
 #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER

+ 5 - 5
code/FIReader.cpp

@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
 
 #include "FIReader.hpp"
-#include "StringUtils.h"
+#include <assimp/StringUtils.h>
 
 // Workaround for issue #1361
 // https://github.com/assimp/assimp/issues/1361
@@ -54,13 +54,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #  define _GLIBCXX_USE_C99 1
 #endif
 
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 #include <assimp/IOStream.hpp>
 #include <assimp/types.h>
-#include "MemoryIOWrapper.h"
-#include "irrXMLWrapper.h"
+#include <assimp/MemoryIOWrapper.h>
+#include <assimp/irrXMLWrapper.h>
 #include "../contrib/utf8cpp/source/utf8.h"
-#include "fast_atof.h"
+#include <assimp/fast_atof.h>
 #include <stack>
 #include <map>
 #include <iostream>

+ 2 - 0
code/FIReader.hpp

@@ -62,6 +62,7 @@ namespace Assimp {
 
 struct FIValue {
     virtual const std::string &toString() const = 0;
+    virtual ~FIValue() {}
 };
 
 struct FIStringValue: public FIValue {
@@ -121,6 +122,7 @@ struct FICDATAValue: public FIStringValue {
 
 struct FIDecoder {
     virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) = 0;
+    virtual ~FIDecoder() {}
 };
 
 struct FIQName {

+ 2 - 2
code/FileSystemFilter.h

@@ -47,8 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "../include/assimp/IOSystem.hpp"
 #include "../include/assimp/DefaultLogger.hpp"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
+#include "../include/assimp/fast_atof.h"
+#include "../include/assimp/ParsingUtils.h"
 
 namespace Assimp    {
 

+ 1 - 1
code/FindDegenerates.cpp

@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // internal headers
 #include "ProcessHelper.h"
 #include "FindDegenerates.h"
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 
 using namespace Assimp;
 

+ 3 - 3
code/FindInvalidDataProcess.cpp

@@ -50,9 +50,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // internal headers
 #include "FindInvalidDataProcess.h"
 #include "ProcessHelper.h"
-#include "Macros.h"
-#include "Exceptional.h"
-#include "qnan.h"
+#include <assimp/Macros.h>
+#include <assimp/Exceptional.h>
+#include <assimp/qnan.h>
 
 using namespace Assimp;
 

+ 1 - 1
code/FixNormalsStep.cpp

@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // internal headers
 #include "FixNormalsStep.h"
-#include "StringUtils.h"
+#include <assimp/StringUtils.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/postprocess.h>
 #include <assimp/scene.h>

+ 2 - 2
code/GenFaceNormalsProcess.cpp

@@ -49,8 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/postprocess.h>
 #include <assimp/scene.h>
 #include <assimp/DefaultLogger.hpp>
-#include "Exceptional.h"
-#include "qnan.h"
+#include <assimp/Exceptional.h>
+#include <assimp/qnan.h>
 
 
 using namespace Assimp;

+ 2 - 2
code/GenVertexNormalsProcess.cpp

@@ -49,8 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // internal headers
 #include "GenVertexNormalsProcess.h"
 #include "ProcessHelper.h"
-#include "Exceptional.h"
-#include "qnan.h"
+#include <assimp/Exceptional.h>
+#include <assimp/qnan.h>
 
 using namespace Assimp;
 

+ 1 - 1
code/HMPLoader.h

@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define AI_HMPLOADER_H_INCLUDED
 
 // internal headers
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include "MDLLoader.h"
 #include "HMPFileData.h"
 

+ 1 - 1
code/IFF.h

@@ -5,7 +5,7 @@
 #ifndef AI_IFF_H_INCLUDED
 #define AI_IFF_H_INCLUDED
 
-#include "ByteSwapper.h"
+#include <assimp/ByteSwapper.h>
 
 namespace Assimp    {
 namespace IFF       {

+ 5 - 5
code/IRRLoader.cpp

@@ -49,16 +49,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
 
 #include "IRRLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include "GenericProperty.h"
+#include <assimp/ParsingUtils.h>
+#include <assimp/fast_atof.h>
+#include <assimp/GenericProperty.h>
 
 #include <assimp/SceneCombiner.h>
-#include "StandardShapes.h"
+#include <assimp/StandardShapes.h>
 #include "Importer.h"
 
 // We need MathFunctions.h to compute the lcm/gcd of a number
-#include "MathFunctions.h"
+#include <assimp/MathFunctions.h>
 #include <memory>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/mesh.h>

+ 1 - 1
code/IRRLoader.h

@@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "IRRShared.h"
 #include <assimp/SceneCombiner.h>
 #include "Importer.h"
-#include "StringUtils.h"
+#include <assimp/StringUtils.h>
 #include <assimp/anim.h>
 
 namespace Assimp    {

+ 3 - 3
code/IRRMeshLoader.cpp

@@ -47,8 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
 
 #include "IRRMeshLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
+#include <assimp/ParsingUtils.h>
+#include <assimp/fast_atof.h>
 #include <memory>
 #include <assimp/IOSystem.hpp>
 #include <assimp/mesh.h>
@@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/material.h>
 #include <assimp/scene.h>
 #include <assimp/importerdesc.h>
-#include "Macros.h"
+#include <assimp/Macros.h>
 
 using namespace Assimp;
 using namespace irr;

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.