Browse Source

Merge branch 'master' into md2_fix

Kim Kulling 7 years ago
parent
commit
29cf414468
73 changed files with 829 additions and 294 deletions
  1. 1 2
      .travis.sh
  2. 0 4
      .travis.yml
  3. 1 1
      assimp.pc.in
  4. 1 1
      code/3DSExporter.cpp
  5. 1 1
      code/AMFImporter_Postprocess.cpp
  6. 1 1
      code/AssbinExporter.cpp
  7. 11 0
      code/AssbinLoader.cpp
  8. 1 1
      code/AssxmlExporter.cpp
  9. 1 1
      code/BlenderDNA.inl
  10. 1 1
      code/BlenderIntermediate.h
  11. 3 1
      code/BlenderModifier.cpp
  12. 2 0
      code/CMakeLists.txt
  13. 1 1
      code/ColladaExporter.cpp
  14. 1 2
      code/ColladaParser.cpp
  15. 1 1
      code/D3MFImporter.cpp
  16. 1 0
      code/D3MFOpcPackage.cpp
  17. 1 1
      code/DeboneProcess.h
  18. 4 1
      code/Exporter.cpp
  19. 12 4
      code/FBXConverter.cpp
  20. 1 0
      code/FBXParser.cpp
  21. 4 4
      code/FIReader.cpp
  22. 15 10
      code/FindInvalidDataProcess.cpp
  23. 1 4
      code/FixNormalsStep.h
  24. 51 100
      code/IFCCurve.cpp
  25. 3 3
      code/IFCReaderGen1.cpp
  26. 1 1
      code/IRRLoader.cpp
  27. 8 12
      code/LineSplitter.h
  28. 1 1
      code/MMDImporter.cpp
  29. 1 1
      code/MMDPmxParser.cpp
  30. 1 1
      code/MMDVmdParser.h
  31. 36 11
      code/ObjExporter.cpp
  32. 2 2
      code/ObjExporter.h
  33. 3 0
      code/ObjFileParser.cpp
  34. 1 1
      code/OpenGEXExporter.cpp
  35. 11 11
      code/OpenGEXImporter.cpp
  36. 2 2
      code/PlyExporter.cpp
  37. 6 1
      code/PlyParser.cpp
  38. 1 0
      code/Q3BSPZipArchive.cpp
  39. 1 3
      code/RemoveVCProcess.h
  40. 1 1
      code/SIBImporter.cpp
  41. 1 1
      code/STEPFile.h
  42. 2 2
      code/STLExporter.cpp
  43. 55 35
      code/STLLoader.cpp
  44. 34 26
      code/STLLoader.h
  45. 105 0
      code/ScaleProcess.cpp
  46. 87 0
      code/ScaleProcess.h
  47. 1 1
      code/X3DExporter.cpp
  48. 1 1
      code/X3DImporter_Metadata.cpp
  49. 1 1
      code/glTF2Asset.h
  50. 5 5
      code/glTF2Asset.inl
  51. 4 4
      code/glTF2AssetWriter.inl
  52. 1 1
      code/glTF2Exporter.cpp
  53. 5 3
      code/glTF2Importer.cpp
  54. 1 1
      code/glTFAsset.h
  55. 4 4
      code/glTFAsset.inl
  56. 5 5
      code/glTFAssetWriter.inl
  57. 3 1
      code/glTFImporter.cpp
  58. 1 1
      contrib/Open3DGC/o3dgcTriangleListEncoder.inl
  59. 1 1
      contrib/openddlparser/code/DDLNode.cpp
  60. 1 1
      contrib/openddlparser/code/Value.cpp
  61. 4 0
      contrib/openddlparser/include/openddlparser/OpenDDLParser.h
  62. 1 1
      doc/Doxyfile.in
  63. 1 1
      include/assimp/Exporter.hpp
  64. 8 0
      include/assimp/config.h.in
  65. 11 1
      include/assimp/postprocess.h
  66. 3 0
      port/PyAssimp/pyassimp/helper.py
  67. 11 3
      test/CMakeLists.txt
  68. 18 0
      test/models/STL/triangle_with_two_solids.stl
  69. 7 1
      test/unit/TestModelFactory.h
  70. 36 0
      test/unit/utObjImportExport.cpp
  71. 68 0
      test/unit/utSTLImportExport.cpp
  72. 85 0
      test/unit/utScaleProcess.cpp
  73. 62 0
      test/unit/utX3DImportExport.cpp

+ 1 - 2
.travis.sh

@@ -5,8 +5,7 @@
 #
 #
 # License see LICENSE file
 # License see LICENSE file
 #
 #
-function generate()
-{
+function generate() {
     OPTIONS="-DASSIMP_WERROR=ON"
     OPTIONS="-DASSIMP_WERROR=ON"
 
 
     if [ "$DISABLE_EXPORTERS" = "YES" ] ; then
     if [ "$DISABLE_EXPORTERS" = "YES" ] ; then

+ 0 - 4
.travis.yml

@@ -18,10 +18,6 @@ before_install:
   # install latest LCOV (1.9 was failing)
   # install latest LCOV (1.9 was failing)
   - if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz && tar xf lcov_1.11.orig.tar.gz && sudo make -C lcov-1.11/ install && gem install coveralls-lcov && lcov --version && g++ --version ; fi
   - if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz && tar xf lcov_1.11.orig.tar.gz && sudo make -C lcov-1.11/ install && gem install coveralls-lcov && lcov --version && g++ --version ; fi
 
 
-branches:
-  only:
-    - master
-
 os:
 os:
   - linux
   - linux
 
 

+ 1 - 1
assimp.pc.in

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

+ 1 - 1
code/3DSExporter.cpp

@@ -151,7 +151,7 @@ namespace {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
 // Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
-void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
+void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
 {
 {
     std::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
     std::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
     if(!outfile) {
     if(!outfile) {

+ 1 - 1
code/AMFImporter_Postprocess.cpp

@@ -60,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp
 namespace Assimp
 {
 {
 
 
-aiColor4D AMFImporter::SPP_Material::GetColor(const float pX, const float pY, const float pZ) const
+aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*pY*/, const float /*pZ*/) const
 {
 {
     aiColor4D tcol;
     aiColor4D tcol;
 
 

+ 1 - 1
code/AssbinExporter.cpp

@@ -810,7 +810,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
         }
         }
     };
     };
 
 
-void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
+void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
 {
 {
     AssbinExport exporter;
     AssbinExport exporter;
     exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
     exporter.WriteBinaryDump( pFile, pIOSystem, pScene );

+ 11 - 0
code/AssbinLoader.cpp

@@ -200,6 +200,7 @@ template <typename T> void ReadBounds( IOStream * stream, T* /*p*/, unsigned int
 
 
 void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) {
 void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) {
     uint32_t chunkID = Read<uint32_t>(stream);
     uint32_t chunkID = Read<uint32_t>(stream);
+    (void)(chunkID);
     ai_assert(chunkID == ASSBIN_CHUNK_AINODE);
     ai_assert(chunkID == ASSBIN_CHUNK_AINODE);
     /*uint32_t size =*/ Read<uint32_t>(stream);
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
 
@@ -274,6 +275,7 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* p
 void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
 void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
 {
 {
     uint32_t chunkID = Read<uint32_t>(stream);
     uint32_t chunkID = Read<uint32_t>(stream);
+    (void)(chunkID);
     ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
     ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
     /*uint32_t size =*/ Read<uint32_t>(stream);
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
 
@@ -298,6 +300,7 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
 void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
 void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
 {
 {
     uint32_t chunkID = Read<uint32_t>(stream);
     uint32_t chunkID = Read<uint32_t>(stream);
+    (void)(chunkID);
     ai_assert(chunkID == ASSBIN_CHUNK_AIMESH);
     ai_assert(chunkID == ASSBIN_CHUNK_AIMESH);
     /*uint32_t size =*/ Read<uint32_t>(stream);
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
 
@@ -423,6 +426,7 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
 void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop)
 void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop)
 {
 {
     uint32_t chunkID = Read<uint32_t>(stream);
     uint32_t chunkID = Read<uint32_t>(stream);
+    (void)(chunkID);
     ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
     ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
     /*uint32_t size =*/ Read<uint32_t>(stream);
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
 
@@ -440,6 +444,7 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro
 void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
 void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
 {
 {
     uint32_t chunkID = Read<uint32_t>(stream);
     uint32_t chunkID = Read<uint32_t>(stream);
+    (void)(chunkID);
     ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
     ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
     /*uint32_t size =*/ Read<uint32_t>(stream);
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
 
@@ -462,6 +467,7 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
 void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
 void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
 {
 {
     uint32_t chunkID = Read<uint32_t>(stream);
     uint32_t chunkID = Read<uint32_t>(stream);
+    (void)(chunkID);
     ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
     ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
     /*uint32_t size =*/ Read<uint32_t>(stream);
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
 
@@ -511,6 +517,7 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
 void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
 void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
 {
 {
     uint32_t chunkID = Read<uint32_t>(stream);
     uint32_t chunkID = Read<uint32_t>(stream);
+    (void)(chunkID);
     ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
     ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
     /*uint32_t size =*/ Read<uint32_t>(stream);
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
 
@@ -532,6 +539,7 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
 void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
 void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
 {
 {
     uint32_t chunkID = Read<uint32_t>(stream);
     uint32_t chunkID = Read<uint32_t>(stream);
+    (void)(chunkID);
     ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
     ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
     /*uint32_t size =*/ Read<uint32_t>(stream);
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
 
@@ -556,6 +564,7 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
 void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
 void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
 {
 {
     uint32_t chunkID = Read<uint32_t>(stream);
     uint32_t chunkID = Read<uint32_t>(stream);
+    (void)(chunkID);
     ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
     ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
     /*uint32_t size =*/ Read<uint32_t>(stream);
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
 
@@ -583,6 +592,7 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
 void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
 void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
 {
 {
     uint32_t chunkID = Read<uint32_t>(stream);
     uint32_t chunkID = Read<uint32_t>(stream);
+    (void)(chunkID);
     ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
     ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
     /*uint32_t size =*/ Read<uint32_t>(stream);
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
 
@@ -599,6 +609,7 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
 void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
 void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
 {
 {
     uint32_t chunkID = Read<uint32_t>(stream);
     uint32_t chunkID = Read<uint32_t>(stream);
+    (void)(chunkID);
     ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
     ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
     /*uint32_t size =*/ Read<uint32_t>(stream);
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
 

+ 1 - 1
code/AssxmlExporter.cpp

@@ -631,7 +631,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
 
 
 } // end of namespace AssxmlExport
 } // end of namespace AssxmlExport
 
 
-void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
+void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
 {
 {
     IOStream * out = pIOSystem->Open( pFile, "wt" );
     IOStream * out = pIOSystem->Open( pFile, "wt" );
     if (!out) return;
     if (!out) return;

+ 1 - 1
code/BlenderDNA.inl

@@ -585,7 +585,7 @@ template <> inline void Structure :: Convert<int>    (int& dest,const FileDataba
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<short>  (short& dest,const FileDatabase& db) const
+template<> inline void Structure :: Convert<short>  (short& dest,const FileDatabase& db) const
 {
 {
     // automatic rescaling from short to float and vice versa (seems to be used by normals)
     // automatic rescaling from short to float and vice versa (seems to be used by normals)
     if (name == "float") {
     if (name == "float") {

+ 1 - 1
code/BlenderIntermediate.h

@@ -110,7 +110,7 @@ namespace Blender {
         void operator= (const TempArray&)  {
         void operator= (const TempArray&)  {
         }
         }
 
 
-        TempArray(const TempArray& arr) {
+        TempArray(const TempArray& /*arr*/) {
         }
         }
 
 
     private:
     private:

+ 3 - 1
code/BlenderModifier.cpp

@@ -310,7 +310,9 @@ void  BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data
 
 
     std::unique_ptr<Subdivider> subd(Subdivider::Create(algo));
     std::unique_ptr<Subdivider> subd(Subdivider::Create(algo));
     ai_assert(subd);
     ai_assert(subd);
-
+    if ( conv_data.meshes->empty() ) {
+        return;
+    }
     aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
     aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
     std::unique_ptr<aiMesh*[]> tempmeshes(new aiMesh*[out.mNumMeshes]());
     std::unique_ptr<aiMesh*[]> tempmeshes(new aiMesh*[out.mNumMeshes]());
 
 

+ 2 - 0
code/CMakeLists.txt

@@ -156,6 +156,8 @@ SET( Common_SRCS
   SkeletonMeshBuilder.h
   SkeletonMeshBuilder.h
   SplitByBoneCountProcess.cpp
   SplitByBoneCountProcess.cpp
   SplitByBoneCountProcess.h
   SplitByBoneCountProcess.h
+  ScaleProcess.cpp
+  ScaleProcess.h
   SmoothingGroups.h
   SmoothingGroups.h
   StandardShapes.cpp
   StandardShapes.cpp
   StandardShapes.h
   StandardShapes.h

+ 1 - 1
code/ColladaExporter.cpp

@@ -68,7 +68,7 @@ namespace Assimp
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
 // Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
-void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
+void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
 {
 {
     std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
     std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
     std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
     std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));

+ 1 - 2
code/ColladaParser.cpp

@@ -2469,8 +2469,7 @@ void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t n
     size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets;
     size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets;
 
 
     // don't overrun the boundaries of the index list
     // don't overrun the boundaries of the index list
-    size_t maxIndexRequested = baseOffset + numOffsets - 1;
-    ai_assert(maxIndexRequested < indices.size());
+    ai_assert((baseOffset + numOffsets - 1) < indices.size());
 
 
     // extract per-vertex channels using the global per-vertex offset
     // extract per-vertex channels using the global per-vertex offset
     for (std::vector<InputChannel>::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it)
     for (std::vector<InputChannel>::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it)

+ 1 - 1
code/D3MFImporter.cpp

@@ -344,7 +344,7 @@ bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool
     return false;
     return false;
 }
 }
 
 
-void D3MFImporter::SetupProperties(const Importer *pImp)
+void D3MFImporter::SetupProperties(const Importer */*pImp*/)
 {
 {
 
 
 }
 }

+ 1 - 0
code/D3MFOpcPackage.cpp

@@ -379,6 +379,7 @@ IOStream *D3MFZipArchive::Open(const char* pFile, const char* /*pMode*/) {
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 //  Close a filestream.
 //  Close a filestream.
 void D3MFZipArchive::Close(IOStream *pFile) {
 void D3MFZipArchive::Close(IOStream *pFile) {
+    (void)(pFile);
     ai_assert(pFile != NULL);
     ai_assert(pFile != NULL);
 
 
     // We don't do anything in case the file would be opened again in the future
     // We don't do anything in case the file would be opened again in the future

+ 1 - 1
code/DeboneProcess.h

@@ -1,4 +1,4 @@
-                   /*
+/*
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 

+ 4 - 1
code/Exporter.cpp

@@ -83,6 +83,7 @@ void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportPrope
 void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneStep(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneStep(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneObjNoMtl(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
@@ -115,6 +116,8 @@ Exporter::ExportFormatEntry gExporters[] =
 #ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
 #ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
     Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
     Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
         aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */),
         aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */),
+    Exporter::ExportFormatEntry( "objnomtl", "Wavefront OBJ format without material file", "obj", &ExportSceneObjNoMtl,
+        aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */),
 #endif
 #endif
 
 
 #ifndef ASSIMP_BUILD_NO_STL_EXPORTER
 #ifndef ASSIMP_BUILD_NO_STL_EXPORTER
@@ -241,7 +244,7 @@ bool Exporter::IsDefaultIOHandler() const {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId,
 const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId,
-                                                unsigned int, const ExportProperties* pProperties ) {
+                                                unsigned int, const ExportProperties* /*pProperties*/ ) {
     if (pimpl->blob) {
     if (pimpl->blob) {
         delete pimpl->blob;
         delete pimpl->blob;
         pimpl->blob = NULL;
         pimpl->blob = NULL;

+ 12 - 4
code/FBXConverter.cpp

@@ -645,7 +645,6 @@ void Converter::ConvertCameras( const Model& model )
     }
     }
 }
 }
 
 
-
 void Converter::ConvertLight( const Model& model, const Light& light )
 void Converter::ConvertLight( const Model& model, const Light& light )
 {
 {
     lights.push_back( new aiLight() );
     lights.push_back( new aiLight() );
@@ -783,7 +782,6 @@ const char* Converter::NameTransformationComp( TransformationComp comp )
     return NULL;
     return NULL;
 }
 }
 
 
-
 const char* Converter::NameTransformationCompProperty( TransformationComp comp )
 const char* Converter::NameTransformationCompProperty( TransformationComp comp )
 {
 {
     switch ( comp )
     switch ( comp )
@@ -2239,9 +2237,17 @@ void Converter::ConvertAnimations()
     }
     }
 }
 }
 
 
+void Converter::RenameNode( const std::string& fixed_name, const std::string& new_name ) {
+    if ( node_names.find( fixed_name ) == node_names.end() ) {
+        FBXImporter::LogError( "Cannot rename node " + fixed_name + ", not existing.");
+        return;
+    }
+
+    if ( node_names.find( new_name ) != node_names.end() ) {
+        FBXImporter::LogError( "Cannot rename node " + fixed_name + " to " + new_name +", name already existing." );
+        return;
+    }
 
 
-void Converter::RenameNode( const std::string& fixed_name, const std::string& new_name )
-{
     ai_assert( node_names.find( fixed_name ) != node_names.end() );
     ai_assert( node_names.find( fixed_name ) != node_names.end() );
     ai_assert( node_names.find( new_name ) == node_names.end() );
     ai_assert( node_names.find( new_name ) == node_names.end() );
 
 
@@ -2429,6 +2435,7 @@ void Converter::ConvertAnimationStack( const AnimationStack& st )
     anim->mTicksPerSecond = anim_fps;
     anim->mTicksPerSecond = anim_fps;
 }
 }
 
 
+#ifdef ASSIMP_BUILD_DEBUG
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // sanity check whether the input is ok
 // sanity check whether the input is ok
 static void validateAnimCurveNodes( const std::vector<const AnimationCurveNode*>& curves,
 static void validateAnimCurveNodes( const std::vector<const AnimationCurveNode*>& curves,
@@ -2446,6 +2453,7 @@ static void validateAnimCurveNodes( const std::vector<const AnimationCurveNode*>
         }
         }
     }
     }
 }
 }
+#endif // ASSIMP_BUILD_DEBUG
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
 void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,

+ 1 - 0
code/FBXParser.cpp

@@ -103,6 +103,7 @@ namespace {
     T SafeParse(const char* data, const char* end) {
     T SafeParse(const char* data, const char* end) {
         // Actual size validation happens during Tokenization so
         // Actual size validation happens during Tokenization so
         // this is valid as an assertion.
         // this is valid as an assertion.
+        (void)(end);
         ai_assert(static_cast<size_t>(end - data) >= sizeof(T));
         ai_assert(static_cast<size_t>(end - data) >= sizeof(T));
         T result = static_cast<T>(0);
         T result = static_cast<T>(0);
         ::memcpy(&result, data, sizeof(T));
         ::memcpy(&result, data, sizeof(T));

+ 4 - 4
code/FIReader.cpp

@@ -1776,17 +1776,17 @@ public:
         return reader->getParserFormat();
         return reader->getParserFormat();
     }
     }
 
 
-    virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const /*override*/ {
+    virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int /*idx*/) const /*override*/ {
         return nullptr;
         return nullptr;
     }
     }
 
 
-    virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* name) const /*override*/ {
+    virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* /*name*/) const /*override*/ {
         return nullptr;
         return nullptr;
     }
     }
 
 
-    virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr<FIDecoder> decoder) /*override*/ {}
+    virtual void registerDecoder(const std::string &/*algorithmUri*/, std::unique_ptr<FIDecoder> /*decoder*/) /*override*/ {}
 
 
-    virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) /*override*/ {}
+    virtual void registerVocabulary(const std::string &/*vocabularyUri*/, const FIVocabulary */*vocabulary*/) /*override*/ {}
 
 
 private:
 private:
 
 

+ 15 - 10
code/FindInvalidDataProcess.cpp

@@ -169,8 +169,8 @@ void FindInvalidDataProcess::Execute( aiScene* pScene)
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 template <typename T>
 template <typename T>
-inline const char* ValidateArrayContents(const T* arr, unsigned int size,
-    const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true)
+inline const char* ValidateArrayContents(const T* /*arr*/, unsigned int /*size*/,
+    const std::vector<bool>& /*dirtyMask*/, bool /*mayBeIdentical = false*/, bool /*mayBeZero = true*/)
 {
 {
     return NULL;
     return NULL;
 }
 }
@@ -339,32 +339,37 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
 int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
 int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
 {
 {
     bool ret = false;
     bool ret = false;
-    std::vector<bool> dirtyMask(pMesh->mNumVertices,(pMesh->mNumFaces ? true : false));
+    std::vector<bool> dirtyMask(pMesh->mNumVertices, pMesh->mNumFaces);
 
 
     // Ignore elements that are not referenced by vertices.
     // Ignore elements that are not referenced by vertices.
     // (they are, for example, caused by the FindDegenerates step)
     // (they are, for example, caused by the FindDegenerates step)
-    for (unsigned int m = 0; m < pMesh->mNumFaces;++m)  {
+    for (unsigned int m = 0; m < pMesh->mNumFaces; ++m) {
         const aiFace& f = pMesh->mFaces[m];
         const aiFace& f = pMesh->mFaces[m];
 
 
-        for (unsigned int i = 0; i < f.mNumIndices;++i) {
+        for (unsigned int i = 0; i < f.mNumIndices; ++i) {
             dirtyMask[f.mIndices[i]] = false;
             dirtyMask[f.mIndices[i]] = false;
         }
         }
     }
     }
 
 
     // Process vertex positions
     // Process vertex positions
-    if(pMesh->mVertices && ProcessArray(pMesh->mVertices,pMesh->mNumVertices,"positions",dirtyMask))    {
+    if (pMesh->mVertices && ProcessArray(pMesh->mVertices, pMesh->mNumVertices, "positions", dirtyMask)) {
         DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions");
         DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions");
+
         return 2;
         return 2;
     }
     }
 
 
     // process texture coordinates
     // process texture coordinates
-    for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i];++i)    {
-        if (ProcessArray(pMesh->mTextureCoords[i],pMesh->mNumVertices,"uvcoords",dirtyMask))    {
+    for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i]; ++i) {
+        if (ProcessArray(pMesh->mTextureCoords[i], pMesh->mNumVertices, "uvcoords", dirtyMask)) {
+            pMesh->mNumUVComponents[i] = 0;
 
 
             // delete all subsequent texture coordinate sets.
             // delete all subsequent texture coordinate sets.
-            for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a)  {
-                delete[] pMesh->mTextureCoords[a]; pMesh->mTextureCoords[a] = NULL;
+            for (unsigned int a = i + 1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
+                delete[] pMesh->mTextureCoords[a];
+                pMesh->mTextureCoords[a] = NULL;
+                pMesh->mNumUVComponents[a] = 0;
             }
             }
+
             ret = true;
             ret = true;
         }
         }
     }
     }

+ 1 - 4
code/FixNormalsStep.h

@@ -56,14 +56,11 @@ namespace Assimp
  * vectors of an object are facing inwards. In this case they will be
  * vectors of an object are facing inwards. In this case they will be
  * flipped.
  * flipped.
  */
  */
-class FixInfacingNormalsProcess : public BaseProcess
-{
+class FixInfacingNormalsProcess : public BaseProcess {
 public:
 public:
-
     FixInfacingNormalsProcess();
     FixInfacingNormalsProcess();
     ~FixInfacingNormalsProcess();
     ~FixInfacingNormalsProcess();
 
 
-public:
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag field.
     /** Returns whether the processing step is present in the given flag field.
      * @param pFlags The processing flags the importer was called with. A bitwise
      * @param pFlags The processing flags the importer was called with. A bitwise

+ 51 - 100
code/IFCCurve.cpp

@@ -43,28 +43,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *  @brief Read profile and curves entities from IFC files
  *  @brief Read profile and curves entities from IFC files
  */
  */
 
 
-
-
 #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
 #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
 #include "IFCUtil.h"
 #include "IFCUtil.h"
 
 
 namespace Assimp {
 namespace Assimp {
-    namespace IFC {
-        namespace {
+namespace IFC {
+namespace {
 
 
 
 
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 // Conic is the base class for Circle and Ellipse
 // Conic is the base class for Circle and Ellipse
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
-class Conic : public Curve
-{
-
+class Conic : public Curve {
 public:
 public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     Conic(const IfcConic& entity, ConversionData& conv)
     Conic(const IfcConic& entity, ConversionData& conv)
-        : Curve(entity,conv)
-    {
+    : Curve(entity,conv) {
         IfcMatrix4 trafo;
         IfcMatrix4 trafo;
         ConvertAxisPlacement(trafo,*entity.Position,conv);
         ConvertAxisPlacement(trafo,*entity.Position,conv);
 
 
@@ -75,8 +69,6 @@ public:
         p[2] = IfcVector3(trafo.a3,trafo.b3,trafo.c3);
         p[2] = IfcVector3(trafo.a3,trafo.b3,trafo.c3);
     }
     }
 
 
-public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     bool IsClosed() const {
     bool IsClosed() const {
         return true;
         return true;
@@ -84,7 +76,8 @@ public:
 
 
     // --------------------------------------------------
     // --------------------------------------------------
     size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
     size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
-        ai_assert(InRange(a) && InRange(b));
+        ai_assert( InRange( a ) );
+        ai_assert( InRange( b ) );
 
 
         a *= conv.angle_scale;
         a *= conv.angle_scale;
         b *= conv.angle_scale;
         b *= conv.angle_scale;
@@ -104,15 +97,11 @@ protected:
     IfcVector3 location, p[3];
     IfcVector3 location, p[3];
 };
 };
 
 
-
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 // Circle
 // Circle
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
-class Circle : public Conic
-{
-
+class Circle : public Conic {
 public:
 public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     Circle(const IfcCircle& entity, ConversionData& conv)
     Circle(const IfcCircle& entity, ConversionData& conv)
         : Conic(entity,conv)
         : Conic(entity,conv)
@@ -120,8 +109,6 @@ public:
     {
     {
     }
     }
 
 
-public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     IfcVector3 Eval(IfcFloat u) const {
     IfcVector3 Eval(IfcFloat u) const {
         u = -conv.angle_scale * u;
         u = -conv.angle_scale * u;
@@ -137,20 +124,15 @@ private:
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 // Ellipse
 // Ellipse
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
-class Ellipse : public Conic
-{
-
+class Ellipse : public Conic {
 public:
 public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     Ellipse(const IfcEllipse& entity, ConversionData& conv)
     Ellipse(const IfcEllipse& entity, ConversionData& conv)
-        : Conic(entity,conv)
-        , entity(entity)
-    {
+    : Conic(entity,conv)
+    , entity(entity) {
+        // empty
     }
     }
 
 
-public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     IfcVector3 Eval(IfcFloat u) const {
     IfcVector3 Eval(IfcFloat u) const {
         u = -conv.angle_scale * u;
         u = -conv.angle_scale * u;
@@ -162,25 +144,18 @@ private:
     const IfcEllipse& entity;
     const IfcEllipse& entity;
 };
 };
 
 
-
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 // Line
 // Line
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
-class Line : public Curve
-{
-
+class Line : public Curve {
 public:
 public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     Line(const IfcLine& entity, ConversionData& conv)
     Line(const IfcLine& entity, ConversionData& conv)
-        : Curve(entity,conv)
-    {
+    : Curve(entity,conv) {
         ConvertCartesianPoint(p,entity.Pnt);
         ConvertCartesianPoint(p,entity.Pnt);
         ConvertVector(v,entity.Dir);
         ConvertVector(v,entity.Dir);
     }
     }
 
 
-public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     bool IsClosed() const {
     bool IsClosed() const {
         return false;
         return false;
@@ -193,16 +168,17 @@ public:
 
 
     // --------------------------------------------------
     // --------------------------------------------------
     size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
     size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
-        ai_assert(InRange(a) && InRange(b));
+        ai_assert( InRange( a ) );
+        ai_assert( InRange( b ) );
         // two points are always sufficient for a line segment
         // two points are always sufficient for a line segment
         return a==b ? 1 : 2;
         return a==b ? 1 : 2;
     }
     }
 
 
 
 
     // --------------------------------------------------
     // --------------------------------------------------
-    void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
-    {
-        ai_assert(InRange(a) && InRange(b));
+    void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const {
+        ai_assert( InRange( a ) );
+        ai_assert( InRange( b ) );
 
 
         if (a == b) {
         if (a == b) {
             out.verts.push_back(Eval(a));
             out.verts.push_back(Eval(a));
@@ -227,18 +203,14 @@ private:
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 // CompositeCurve joins multiple smaller, bounded curves
 // CompositeCurve joins multiple smaller, bounded curves
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
-class CompositeCurve : public BoundedCurve
-{
-
+class CompositeCurve : public BoundedCurve {
     typedef std::pair< std::shared_ptr< BoundedCurve >, bool > CurveEntry;
     typedef std::pair< std::shared_ptr< BoundedCurve >, bool > CurveEntry;
 
 
 public:
 public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     CompositeCurve(const IfcCompositeCurve& entity, ConversionData& conv)
     CompositeCurve(const IfcCompositeCurve& entity, ConversionData& conv)
-        : BoundedCurve(entity,conv)
-        , total()
-    {
+    : BoundedCurve(entity,conv)
+    , total() {
         curves.reserve(entity.Segments.size());
         curves.reserve(entity.Segments.size());
         for(const IfcCompositeCurveSegment& curveSegment :entity.Segments) {
         for(const IfcCompositeCurveSegment& curveSegment :entity.Segments) {
             // according to the specification, this must be a bounded curve
             // according to the specification, this must be a bounded curve
@@ -263,8 +235,6 @@ public:
         }
         }
     }
     }
 
 
-public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     IfcVector3 Eval(IfcFloat u) const {
     IfcVector3 Eval(IfcFloat u) const {
         if (curves.empty()) {
         if (curves.empty()) {
@@ -287,7 +257,8 @@ public:
 
 
     // --------------------------------------------------
     // --------------------------------------------------
     size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
     size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
-        ai_assert(InRange(a) && InRange(b));
+        ai_assert( InRange( a ) );
+        ai_assert( InRange( b ) );
         size_t cnt = 0;
         size_t cnt = 0;
 
 
         IfcFloat acc = 0;
         IfcFloat acc = 0;
@@ -306,9 +277,9 @@ public:
     }
     }
 
 
     // --------------------------------------------------
     // --------------------------------------------------
-    void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
-    {
-        ai_assert(InRange(a) && InRange(b));
+    void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const {
+        ai_assert( InRange( a ) );
+        ai_assert( InRange( b ) );
 
 
         const size_t cnt = EstimateSampleCount(a,b);
         const size_t cnt = EstimateSampleCount(a,b);
         out.verts.reserve(out.verts.size() + cnt);
         out.verts.reserve(out.verts.size() + cnt);
@@ -330,19 +301,14 @@ public:
 
 
 private:
 private:
     std::vector< CurveEntry > curves;
     std::vector< CurveEntry > curves;
-
     IfcFloat total;
     IfcFloat total;
 };
 };
 
 
-
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 // TrimmedCurve can be used to trim an unbounded curve to a bounded range
 // TrimmedCurve can be used to trim an unbounded curve to a bounded range
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
-class TrimmedCurve : public BoundedCurve
-{
-
+class TrimmedCurve : public BoundedCurve {
 public:
 public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     TrimmedCurve(const IfcTrimmedCurve& entity, ConversionData& conv)
     TrimmedCurve(const IfcTrimmedCurve& entity, ConversionData& conv)
         : BoundedCurve(entity,conv)
         : BoundedCurve(entity,conv)
@@ -409,8 +375,6 @@ public:
         ai_assert(maxval >= 0);
         ai_assert(maxval >= 0);
     }
     }
 
 
-public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     IfcVector3 Eval(IfcFloat p) const {
     IfcVector3 Eval(IfcFloat p) const {
         ai_assert(InRange(p));
         ai_assert(InRange(p));
@@ -419,7 +383,8 @@ public:
 
 
     // --------------------------------------------------
     // --------------------------------------------------
     size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
     size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
-        ai_assert(InRange(a) && InRange(b));
+        ai_assert( InRange( a ) );
+        ai_assert( InRange( b ) );
         return base->EstimateSampleCount(TrimParam(a),TrimParam(b));
         return base->EstimateSampleCount(TrimParam(a),TrimParam(b));
     }
     }
 
 
@@ -435,13 +400,11 @@ public:
     }
     }
 
 
 private:
 private:
-
     // --------------------------------------------------
     // --------------------------------------------------
     IfcFloat TrimParam(IfcFloat f) const {
     IfcFloat TrimParam(IfcFloat f) const {
         return agree_sense ? f + range.first :  range.second - f;
         return agree_sense ? f + range.first :  range.second - f;
     }
     }
 
 
-
 private:
 private:
     ParamRange range;
     ParamRange range;
     IfcFloat maxval;
     IfcFloat maxval;
@@ -454,11 +417,8 @@ private:
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 // PolyLine is a 'curve' defined by linear interpolation over a set of discrete points
 // PolyLine is a 'curve' defined by linear interpolation over a set of discrete points
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
-class PolyLine : public BoundedCurve
-{
-
+class PolyLine : public BoundedCurve {
 public:
 public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     PolyLine(const IfcPolyline& entity, ConversionData& conv)
     PolyLine(const IfcPolyline& entity, ConversionData& conv)
         : BoundedCurve(entity,conv)
         : BoundedCurve(entity,conv)
@@ -472,8 +432,6 @@ public:
         }
         }
     }
     }
 
 
-public:
-
     // --------------------------------------------------
     // --------------------------------------------------
     IfcVector3 Eval(IfcFloat p) const {
     IfcVector3 Eval(IfcFloat p) const {
         ai_assert(InRange(p));
         ai_assert(InRange(p));
@@ -502,13 +460,10 @@ private:
     std::vector<IfcVector3> points;
     std::vector<IfcVector3> points;
 };
 };
 
 
-
 } // anon
 } // anon
 
 
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv)
-{
+Curve* Curve::Convert(const IFC::IfcCurve& curve,ConversionData& conv) {
     if(curve.ToPtr<IfcBoundedCurve>()) {
     if(curve.ToPtr<IfcBoundedCurve>()) {
         if(const IfcPolyline* c = curve.ToPtr<IfcPolyline>()) {
         if(const IfcPolyline* c = curve.ToPtr<IfcPolyline>()) {
             return new PolyLine(*c,conv);
             return new PolyLine(*c,conv);
@@ -519,9 +474,6 @@ Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv)
         if(const IfcCompositeCurve* c = curve.ToPtr<IfcCompositeCurve>()) {
         if(const IfcCompositeCurve* c = curve.ToPtr<IfcCompositeCurve>()) {
             return new CompositeCurve(*c,conv);
             return new CompositeCurve(*c,conv);
         }
         }
-        //if(const IfcBSplineCurve* c = curve.ToPtr<IfcBSplineCurve>()) {
-        //  return new BSplineCurve(*c,conv);
-        //}
     }
     }
 
 
     if(curve.ToPtr<IfcConic>()) {
     if(curve.ToPtr<IfcConic>()) {
@@ -543,8 +495,7 @@ Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv)
 
 
 #ifdef ASSIMP_BUILD_DEBUG
 #ifdef ASSIMP_BUILD_DEBUG
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-bool Curve :: InRange(IfcFloat u) const
-{
+bool Curve::InRange(IfcFloat u) const {
     const ParamRange range = GetParametricRange();
     const ParamRange range = GetParametricRange();
     if (IsClosed()) {
     if (IsClosed()) {
         return true;
         return true;
@@ -555,24 +506,24 @@ bool Curve :: InRange(IfcFloat u) const
 #endif
 #endif
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-IfcFloat Curve :: GetParametricRangeDelta() const
-{
+IfcFloat Curve::GetParametricRangeDelta() const {
     const ParamRange& range = GetParametricRange();
     const ParamRange& range = GetParametricRange();
     return std::abs(range.second - range.first);
     return std::abs(range.second - range.first);
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-size_t Curve :: EstimateSampleCount(IfcFloat a, IfcFloat b) const
-{
-    ai_assert(InRange(a) && InRange(b));
+size_t Curve::EstimateSampleCount(IfcFloat a, IfcFloat b) const {
+    (void)(a); (void)(b);  
+    ai_assert( InRange( a ) );
+    ai_assert( InRange( b ) );
 
 
     // arbitrary default value, deriving classes should supply better suited values
     // arbitrary default value, deriving classes should supply better suited values
     return 16;
     return 16;
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, IfcFloat b, unsigned int samples, IfcFloat threshold, unsigned int recurse = 0, unsigned int max_recurse = 15)
-{
+IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, IfcFloat b,
+        unsigned int samples, IfcFloat threshold, unsigned int recurse = 0, unsigned int max_recurse = 15) {
     ai_assert(samples>1);
     ai_assert(samples>1);
 
 
     const IfcFloat delta = (b-a)/samples, inf = std::numeric_limits<IfcFloat>::infinity();
     const IfcFloat delta = (b-a)/samples, inf = std::numeric_limits<IfcFloat>::infinity();
@@ -594,7 +545,8 @@ IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, Ifc
         }
         }
     }
     }
 
 
-    ai_assert(min_diff[0] != inf && min_diff[1] != inf);
+    ai_assert( min_diff[ 0 ] != inf );
+    ai_assert( min_diff[ 1 ] != inf );
     if ( std::fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
     if ( std::fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
         return min_point[0];
         return min_point[0];
     }
     }
@@ -615,15 +567,15 @@ IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, Ifc
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-bool Curve :: ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const
+bool Curve::ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const
 {
 {
     // note: the following algorithm is not guaranteed to find the 'right' parameter value
     // note: the following algorithm is not guaranteed to find the 'right' parameter value
     // in all possible cases, but it will always return at least some value so this function
     // in all possible cases, but it will always return at least some value so this function
     // will never fail in the default implementation.
     // will never fail in the default implementation.
 
 
     // XXX derive threshold from curve topology
     // XXX derive threshold from curve topology
-    const IfcFloat threshold = 1e-4f;
-    const unsigned int samples = 16;
+    static const IfcFloat threshold = 1e-4f;
+    static const unsigned int samples = 16;
 
 
     const ParamRange& range = GetParametricRange();
     const ParamRange& range = GetParametricRange();
     paramOut = RecursiveSearch(this,val,range.first,range.second,samples,threshold);
     paramOut = RecursiveSearch(this,val,range.first,range.second,samples,threshold);
@@ -632,9 +584,9 @@ bool Curve :: ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void Curve :: SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
-{
-    ai_assert(InRange(a) && InRange(b));
+void Curve::SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const {
+    ai_assert( InRange( a ) );
+    ai_assert( InRange( b ) );
 
 
     const size_t cnt = std::max(static_cast<size_t>(0),EstimateSampleCount(a,b));
     const size_t cnt = std::max(static_cast<size_t>(0),EstimateSampleCount(a,b));
     out.verts.reserve( out.verts.size() + cnt + 1);
     out.verts.reserve( out.verts.size() + cnt + 1);
@@ -646,16 +598,15 @@ void Curve :: SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-bool BoundedCurve :: IsClosed() const
-{
+bool BoundedCurve::IsClosed() const {
     return false;
     return false;
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void BoundedCurve :: SampleDiscrete(TempMesh& out) const
-{
+void BoundedCurve::SampleDiscrete(TempMesh& out) const {
     const ParamRange& range = GetParametricRange();
     const ParamRange& range = GetParametricRange();
-    ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity());
+    ai_assert( range.first != std::numeric_limits<IfcFloat>::infinity() );
+    ai_assert( range.second != std::numeric_limits<IfcFloat>::infinity() );
 
 
     return SampleDiscrete(out,range.first,range.second);
     return SampleDiscrete(out,range.first,range.second);
 }
 }

+ 3 - 3
code/IFCReaderGen1.cpp

@@ -1045,7 +1045,7 @@ void IFC::GetSchema(EXPRESS::ConversionSchema& out)
 namespace STEP {
 namespace STEP {
 
 
 // -----------------------------------------------------------------------------------------------------------
 // -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<NotImplemented>(const STEP::DB& db, const LIST& params, NotImplemented* in)
+template <> size_t GenericFill<NotImplemented>(const STEP::DB& /*db*/, const LIST& /*params*/, NotImplemented* /*in*/)
 {
 {
 	return 0;
 	return 0;
 }
 }
@@ -1253,7 +1253,7 @@ template <> size_t GenericFill<IfcPerformanceHistory>(const DB& db, const LIST&
 	return base;
 	return base;
 }
 }
 // -----------------------------------------------------------------------------------------------------------
 // -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcRepresentationItem>(const DB& db, const LIST& params, IfcRepresentationItem* in)
+template <> size_t GenericFill<IfcRepresentationItem>(const DB& /*db*/, const LIST& /*params*/, IfcRepresentationItem* /*in*/)
 {
 {
 	size_t base = 0;
 	size_t base = 0;
 	return base;
 	return base;
@@ -1715,7 +1715,7 @@ template <> size_t GenericFill<IfcPlateType>(const DB& db, const LIST& params, I
 	return base;
 	return base;
 }
 }
 // -----------------------------------------------------------------------------------------------------------
 // -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcObjectPlacement>(const DB& db, const LIST& params, IfcObjectPlacement* in)
+template <> size_t GenericFill<IfcObjectPlacement>(const DB& /*db*/, const LIST& /*params*/, IfcObjectPlacement* /*in*/)
 {
 {
 	size_t base = 0;
 	size_t base = 0;
 	return base;
 	return base;

+ 1 - 1
code/IRRLoader.cpp

@@ -394,7 +394,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
                 angles[1] %= 360;
                 angles[1] %= 360;
                 angles[2] %= 360;
                 angles[2] %= 360;
 
 
-                if ((angles[0]*angles[1]) && (angles[1]*angles[2]))
+                if ( bool(angles[0]*angles[1]) && bool(angles[1]*angles[2]) )
                 {
                 {
                     FindSuitableMultiple(angles[0]);
                     FindSuitableMultiple(angles[0]);
                     FindSuitableMultiple(angles[1]);
                     FindSuitableMultiple(angles[1]);

+ 8 - 12
code/LineSplitter.h

@@ -69,27 +69,23 @@ for(LineSplitter splitter(stream);splitter;++splitter) {
 
 
     std::cout << "Current line is: " << splitter.get_index() << std::endl;
     std::cout << "Current line is: " << splitter.get_index() << std::endl;
 }
 }
-@endcode */
+@endcode
+*/
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-class LineSplitter
-{
+class LineSplitter {
 public:
 public:
-
     typedef size_t line_idx;
     typedef size_t line_idx;
 
 
-public:
-
     // -----------------------------------------
     // -----------------------------------------
     /** construct from existing stream reader
     /** construct from existing stream reader
     note: trim is *always* assumed true if skyp_empty_lines==true
     note: trim is *always* assumed true if skyp_empty_lines==true
     */
     */
     LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true)
     LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true)
-        : idx( 0 )
-        , stream(stream)
-        , swallow()
-        , skip_empty_lines(skip_empty_lines)
-        , trim(trim)
-    {
+    : idx( 0 )
+    , stream(stream)
+    , swallow()
+    , skip_empty_lines(skip_empty_lines)
+    , trim(trim) {
         cur.reserve(1024);
         cur.reserve(1024);
         operator++();
         operator++();
 
 

+ 1 - 1
code/MMDImporter.cpp

@@ -107,7 +107,7 @@ const aiImporterDesc *MMDImporter::GetInfo() const { return &desc; }
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 //  MMD import implementation
 //  MMD import implementation
 void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
 void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
-                                 IOSystem *pIOHandler) {
+                                 IOSystem */*pIOHandler*/) {
   // Read file by istream
   // Read file by istream
   std::filebuf fb;
   std::filebuf fb;
   if (!fb.open(file, std::ios::in | std::ios::binary)) {
   if (!fb.open(file, std::ios::in | std::ios::binary)) {

+ 1 - 1
code/MMDPmxParser.cpp

@@ -471,7 +471,7 @@ namespace pmx
 		stream->read((char*) &this->is_near, sizeof(uint8_t));
 		stream->read((char*) &this->is_near, sizeof(uint8_t));
 	}
 	}
 
 
-	void PmxSoftBody::Read(std::istream *stream, PmxSetting *setting)
+    void PmxSoftBody::Read(std::istream */*stream*/, PmxSetting */*setting*/)
 	{
 	{
 		// 未実装
 		// 未実装
 		std::cerr << "Not Implemented Exception" << std::endl;
 		std::cerr << "Not Implemented Exception" << std::endl;

+ 1 - 1
code/MMDVmdParser.h

@@ -302,7 +302,7 @@ namespace vmd
 			return result;
 			return result;
 		}
 		}
 
 
-		bool SaveToFile(const std::u16string& filename)
+        bool SaveToFile(const std::u16string& /*filename*/)
 		{
 		{
 			// TODO: How to adapt u16string to string?
 			// TODO: How to adapt u16string to string?
 			/*
 			/*

+ 36 - 11
code/ObjExporter.cpp

@@ -58,7 +58,7 @@ namespace Assimp {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp
 // Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp
-void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties) {
+void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) {
     // invoke the exporter
     // invoke the exporter
     ObjExporter exporter(pFile, pScene);
     ObjExporter exporter(pFile, pScene);
 
 
@@ -83,18 +83,40 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
     }
     }
 }
 }
 
 
+// ------------------------------------------------------------------------------------------------
+// Worker function for exporting a scene to Wavefront OBJ without the material file. Prototyped and registered in Exporter.cpp
+void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties) {
+    // invoke the exporter
+    ObjExporter exporter(pFile, pScene, true);
+
+    if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
+        throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
+    }
+
+    // we're still here - export successfully completed. Write both the main OBJ file and the material script
+    {
+        std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
+        if(outfile == NULL) {
+            throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
+        }
+        outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
+    }
+
+
+}
+
 } // end of namespace Assimp
 } // end of namespace Assimp
 
 
 static const std::string MaterialExt = ".mtl";
 static const std::string MaterialExt = ".mtl";
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene)
+ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene, bool noMtl)
 : filename(_filename)
 : filename(_filename)
 , pScene(pScene)
 , pScene(pScene)
 , vp()
 , vp()
 , vn()
 , vn()
 , vt()
 , vt()
-, vc() 
+, vc()
 , mVpMap()
 , mVpMap()
 , mVnMap()
 , mVnMap()
 , mVtMap()
 , mVtMap()
@@ -108,8 +130,9 @@ ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene)
     mOutputMat.imbue(l);
     mOutputMat.imbue(l);
     mOutputMat.precision(16);
     mOutputMat.precision(16);
 
 
-    WriteGeometryFile();
-    WriteMaterialFile();
+    WriteGeometryFile(noMtl);
+    if (!noMtl)
+        WriteMaterialFile();
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -193,7 +216,7 @@ void ObjExporter::WriteMaterialFile()
         if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_TRANSPARENT,c)) {
         if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_TRANSPARENT,c)) {
             mOutputMat << "Tf " << c.r << " " << c.g << " " << c.b << endl;
             mOutputMat << "Tf " << c.r << " " << c.g << " " << c.b << endl;
         }
         }
-        
+
         ai_real o;
         ai_real o;
         if(AI_SUCCESS == mat->Get(AI_MATKEY_OPACITY,o)) {
         if(AI_SUCCESS == mat->Get(AI_MATKEY_OPACITY,o)) {
             mOutputMat << "d " << o << endl;
             mOutputMat << "d " << o << endl;
@@ -236,9 +259,10 @@ void ObjExporter::WriteMaterialFile()
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void ObjExporter::WriteGeometryFile() {
+void ObjExporter::WriteGeometryFile(bool noMtl) {
     WriteHeader(mOutput);
     WriteHeader(mOutput);
-    mOutput << "mtllib "  << GetMaterialLibName() << endl << endl;
+    if (!noMtl)
+        mOutput << "mtllib "  << GetMaterialLibName() << endl << endl;
 
 
     // collect mesh geometry
     // collect mesh geometry
     aiMatrix4x4 mBase;
     aiMatrix4x4 mBase;
@@ -284,7 +308,8 @@ void ObjExporter::WriteGeometryFile() {
         if (!m.name.empty()) {
         if (!m.name.empty()) {
             mOutput << "g " << m.name << endl;
             mOutput << "g " << m.name << endl;
         }
         }
-        mOutput << "usemtl " << m.matname << endl;
+        if (!noMtl)
+            mOutput << "usemtl " << m.matname << endl;
 
 
         for(const Face& f : m.faces) {
         for(const Face& f : m.faces) {
             mOutput << f.kind << ' ';
             mOutput << f.kind << ' ';
@@ -341,7 +366,7 @@ int ObjExporter::colIndexMap::getIndex( const aiColor4D& col ) {
     colMap[ col ] = mNextIndex;
     colMap[ col ] = mNextIndex;
     int ret = mNextIndex;
     int ret = mNextIndex;
     mNextIndex++;
     mNextIndex++;
-    
+
     return ret;
     return ret;
 }
 }
 
 
@@ -358,7 +383,7 @@ void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4
     mMeshes.push_back(MeshInstance());
     mMeshes.push_back(MeshInstance());
     MeshInstance& mesh = mMeshes.back();
     MeshInstance& mesh = mMeshes.back();
 
 
-    mesh.name = std::string(name.data,name.length) + (m->mName.length ? "_" + std::string(m->mName.data,m->mName.length) : "");
+    mesh.name = std::string( name.data, name.length );
     mesh.matname = GetMaterialName(m->mMaterialIndex);
     mesh.matname = GetMaterialName(m->mMaterialIndex);
 
 
     mesh.faces.resize(m->mNumFaces);
     mesh.faces.resize(m->mNumFaces);

+ 2 - 2
code/ObjExporter.h

@@ -62,7 +62,7 @@ namespace Assimp {
 class ObjExporter {
 class ObjExporter {
 public:
 public:
     /// Constructor for a specific scene to export
     /// Constructor for a specific scene to export
-    ObjExporter(const char* filename, const aiScene* pScene);
+    ObjExporter(const char* filename, const aiScene* pScene, bool noMtl=false);
     ~ObjExporter();
     ~ObjExporter();
     std::string GetMaterialLibName();
     std::string GetMaterialLibName();
     std::string GetMaterialLibFileName();
     std::string GetMaterialLibFileName();
@@ -97,7 +97,7 @@ private:
 
 
     void WriteHeader(std::ostringstream& out);
     void WriteHeader(std::ostringstream& out);
     void WriteMaterialFile();
     void WriteMaterialFile();
-    void WriteGeometryFile();
+    void WriteGeometryFile(bool noMtl=false);
     std::string GetMaterialName(unsigned int index);
     std::string GetMaterialName(unsigned int index);
     void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat);
     void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat);
     void AddNode(const aiNode* nd, const aiMatrix4x4& mParent);
     void AddNode(const aiNode* nd, const aiMatrix4x4& mParent);

+ 3 - 0
code/ObjFileParser.cpp

@@ -477,6 +477,9 @@ void ObjFileParser::getFace( aiPrimitiveType type ) {
                 }
                 }
             } else {
             } else {
                 //On error, std::atoi will return 0 which is not a valid value
                 //On error, std::atoi will return 0 which is not a valid value
+                delete face;
+                delete m_pModel;
+                m_pModel = nullptr;
                 throw DeadlyImportError("OBJ: Invalid face indice");
                 throw DeadlyImportError("OBJ: Invalid face indice");
             }
             }
 
 

+ 1 - 1
code/OpenGEXExporter.cpp

@@ -51,7 +51,7 @@ OpenGEXExporter::OpenGEXExporter() {
 OpenGEXExporter::~OpenGEXExporter() {
 OpenGEXExporter::~OpenGEXExporter() {
 }
 }
 
 
-bool OpenGEXExporter::exportScene( const char *filename, const aiScene* pScene ) {
+bool OpenGEXExporter::exportScene( const char */*filename*/, const aiScene* /*pScene*/ ) {
     return true;
     return true;
 }
 }
 
 

+ 11 - 11
code/OpenGEXImporter.cpp

@@ -431,7 +431,7 @@ void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) {
 }
 }
 
 
 //------------------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene *pScene ) {
+void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene * /*pScene*/ ) {
     if( nullptr == node || nullptr == m_ctx ) {
     if( nullptr == node || nullptr == m_ctx ) {
         return;
         return;
     }
     }
@@ -467,7 +467,7 @@ void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene *pScene ) {
 }
 }
 
 
 //------------------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene *pScene ) {
+void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene * /*pScene*/ ) {
     if( nullptr == m_currentNode ) {
     if( nullptr == m_currentNode ) {
         throw DeadlyImportError( "No current node for name." );
         throw DeadlyImportError( "No current node for name." );
         return;
         return;
@@ -512,7 +512,7 @@ static void getRefNames( DDLNode *node, std::vector<std::string> &names ) {
 }
 }
 
 
 //------------------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene *pScene ) {
+void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene * /*pScene*/ ) {
     if( nullptr == m_currentNode ) {
     if( nullptr == m_currentNode ) {
         throw DeadlyImportError( "No parent node for name." );
         throw DeadlyImportError( "No parent node for name." );
         return;
         return;
@@ -536,7 +536,7 @@ void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene *pScene ) {
 }
 }
 
 
 //------------------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
+void OpenGEXImporter::handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
     if( nullptr == m_currentNode ) {
     if( nullptr == m_currentNode ) {
         throw DeadlyImportError( "No parent node for name." );
         throw DeadlyImportError( "No parent node for name." );
         return;
         return;
@@ -674,7 +674,7 @@ static void setMatrix( aiNode *node, DataArrayList *transformData ) {
 }
 }
 
 
 //------------------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleTransformNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
+void OpenGEXImporter::handleTransformNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
     if( nullptr == m_currentNode ) {
     if( nullptr == m_currentNode ) {
         throw DeadlyImportError( "No parent node for name." );
         throw DeadlyImportError( "No parent node for name." );
         return;
         return;
@@ -819,7 +819,7 @@ static void copyColor4DArray( size_t numItems, DataArrayList *vaList, aiColor4D
 }
 }
 
 
 //------------------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
+void OpenGEXImporter::handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
     if( nullptr == node ) {
     if( nullptr == node ) {
         throw DeadlyImportError( "No parent node for name." );
         throw DeadlyImportError( "No parent node for name." );
         return;
         return;
@@ -862,7 +862,7 @@ void OpenGEXImporter::handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene
 }
 }
 
 
 //------------------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
+void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
     if( nullptr == node ) {
     if( nullptr == node ) {
         throw DeadlyImportError( "No parent node for name." );
         throw DeadlyImportError( "No parent node for name." );
         return;
         return;
@@ -1001,7 +1001,7 @@ void OpenGEXImporter::handleMaterialNode( ODDLParser::DDLNode *node, aiScene *pS
 }
 }
 
 
 //------------------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleColorNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
+void OpenGEXImporter::handleColorNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
     if( nullptr == node ) {
     if( nullptr == node ) {
         return;
         return;
     }
     }
@@ -1040,7 +1040,7 @@ void OpenGEXImporter::handleColorNode( ODDLParser::DDLNode *node, aiScene *pScen
 }
 }
 
 
 //------------------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
+void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
     if( nullptr == node ) {
     if( nullptr == node ) {
         return;
         return;
     }
     }
@@ -1074,7 +1074,7 @@ void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene *pSc
 }
 }
 
 
 //------------------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleParamNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
+void OpenGEXImporter::handleParamNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
     if ( nullptr == node ) {
     if ( nullptr == node ) {
         return;
         return;
     }
     }
@@ -1103,7 +1103,7 @@ void OpenGEXImporter::handleParamNode( ODDLParser::DDLNode *node, aiScene *pScen
 }
 }
 
 
 //------------------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleAttenNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
+void OpenGEXImporter::handleAttenNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
     if ( nullptr == node ) {
     if ( nullptr == node ) {
         return;
         return;
     }
     }

+ 2 - 2
code/PlyExporter.cpp

@@ -65,7 +65,7 @@ template<> const char* type_of(double&) { return "double"; }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to PLY. Prototyped and registered in Exporter.cpp
 // Worker function for exporting a scene to PLY. Prototyped and registered in Exporter.cpp
-void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
+void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
 {
 {
     // invoke the exporter
     // invoke the exporter
     PlyExporter exporter(pFile, pScene);
     PlyExporter exporter(pFile, pScene);
@@ -83,7 +83,7 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
     outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
     outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
 }
 }
 
 
-void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
+void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
 {
 {
     // invoke the exporter
     // invoke the exporter
     PlyExporter exporter(pFile, pScene, true);
     PlyExporter exporter(pFile, pScene, true);

+ 6 - 1
code/PlyParser.cpp

@@ -381,6 +381,11 @@ bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<
   {
   {
     char* endPos = &buffer[0] + (strlen(&buffer[0]) - 1);
     char* endPos = &buffer[0] + (strlen(&buffer[0]) - 1);
     pOut->szName = std::string(&buffer[0], endPos);
     pOut->szName = std::string(&buffer[0], endPos);
+
+    // go to the next line
+    PLY::DOM::SkipSpacesAndLineEnd(buffer);
+
+    return true;
   }
   }
 
 
   //parse the number of occurrences of this element
   //parse the number of occurrences of this element
@@ -933,7 +938,7 @@ bool PLY::PropertyInstance::ParseValue(const char* &pCur,
 {
 {
   ai_assert(NULL != pCur);
   ai_assert(NULL != pCur);
   ai_assert(NULL != out);
   ai_assert(NULL != out);
-  
+
   //calc element size
   //calc element size
   bool ret = true;
   bool ret = true;
   switch (eType)
   switch (eType)

+ 1 - 0
code/Q3BSPZipArchive.cpp

@@ -255,6 +255,7 @@ IOStream *Q3BSPZipArchive::Open(const char* pFile, const char* /*pMode*/) {
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 //  Close a filestream.
 //  Close a filestream.
 void Q3BSPZipArchive::Close(IOStream *pFile) {
 void Q3BSPZipArchive::Close(IOStream *pFile) {
+    (void)(pFile);
     ai_assert(pFile != NULL);
     ai_assert(pFile != NULL);
 
 
     // We don't do anything in case the file would be opened again in the future
     // We don't do anything in case the file would be opened again in the future

+ 1 - 3
code/RemoveVCProcess.h

@@ -54,8 +54,7 @@ namespace Assimp {
 /** RemoveVCProcess: Class to exclude specific parts of the data structure
 /** RemoveVCProcess: Class to exclude specific parts of the data structure
  *  from further processing by removing them,
  *  from further processing by removing them,
 */
 */
-class ASSIMP_API RemoveVCProcess : public BaseProcess
-{
+class ASSIMP_API RemoveVCProcess : public BaseProcess {
 public:
 public:
     /// The default class constructor.
     /// The default class constructor.
     RemoveVCProcess();
     RemoveVCProcess();
@@ -63,7 +62,6 @@ public:
     /// The class destructor.
     /// The class destructor.
     ~RemoveVCProcess();
     ~RemoveVCProcess();
 
 
-public:
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag field.
     /** Returns whether the processing step is present in the given flag field.
     * @param pFlags The processing flags the importer was called with. A bitwise
     * @param pFlags The processing flags the importer was called with. A bitwise

+ 1 - 1
code/SIBImporter.cpp

@@ -163,7 +163,7 @@ static aiColor3D ReadColor(StreamReaderLE* stream)
     return aiColor3D(r, g, b);
     return aiColor3D(r, g, b);
 }
 }
 
 
-static void UnknownChunk(StreamReaderLE* stream, const SIBChunk& chunk)
+static void UnknownChunk(StreamReaderLE* /*stream*/, const SIBChunk& chunk)
 {
 {
     char temp[5] = {
     char temp[5] = {
         static_cast<char>(( chunk.Tag>>24 ) & 0xff),
         static_cast<char>(( chunk.Tag>>24 ) & 0xff),

+ 1 - 1
code/STEPFile.h

@@ -55,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 //
 #if _MSC_VER > 1500 || (defined __GNUC___)
 #if _MSC_VER > 1500 || (defined __GNUC___)
 #   define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
 #   define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
-#   else
+#else
 #   define step_unordered_map map
 #   define step_unordered_map map
 #   define step_unordered_multimap multimap
 #   define step_unordered_multimap multimap
 #endif
 #endif

+ 2 - 2
code/STLExporter.cpp

@@ -57,7 +57,7 @@ namespace Assimp    {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to Stereolithograpy. Prototyped and registered in Exporter.cpp
 // Worker function for exporting a scene to Stereolithograpy. Prototyped and registered in Exporter.cpp
-void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
+void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
 {
 {
     // invoke the exporter
     // invoke the exporter
     STLExporter exporter(pFile, pScene);
     STLExporter exporter(pFile, pScene);
@@ -74,7 +74,7 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
 
 
     outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
     outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
 }
 }
-void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
+void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
 {
 {
     // invoke the exporter
     // invoke the exporter
     STLExporter exporter(pFile, pScene, true);
     STLExporter exporter(pFile, pScene, true);

+ 55 - 35
code/STLLoader.cpp

@@ -80,7 +80,9 @@ static bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
         return false;
         return false;
     }
     }
 
 
-    const uint32_t faceCount = *reinterpret_cast<const uint32_t*>(buffer + 80);
+    const char *facecount_pos = buffer + 80;
+    uint32_t faceCount( 0 );
+    ::memcpy( &faceCount, facecount_pos, sizeof( uint32_t ) );
     const uint32_t expectedBinaryFileSize = faceCount * 50 + 84;
     const uint32_t expectedBinaryFileSize = faceCount * 50 + 84;
 
 
     return expectedBinaryFileSize == fileSize;
     return expectedBinaryFileSize == fileSize;
@@ -200,17 +202,17 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
     if (IsBinarySTL(mBuffer, fileSize)) {
     if (IsBinarySTL(mBuffer, fileSize)) {
         bMatClr = LoadBinaryFile();
         bMatClr = LoadBinaryFile();
     } else if (IsAsciiSTL(mBuffer, fileSize)) {
     } else if (IsAsciiSTL(mBuffer, fileSize)) {
-        LoadASCIIFile();
+        LoadASCIIFile( pScene->mRootNode );
     } else {
     } else {
         throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
         throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
     }
     }
 
 
     // add all created meshes to the single node
     // add all created meshes to the single node
-    pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
+    /*pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
     pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
     pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
     for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
     for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
         pScene->mRootNode->mMeshes[i] = i;
         pScene->mRootNode->mMeshes[i] = i;
-
+    */
     // create a single default material, using a white diffuse color for consistency with
     // create a single default material, using a white diffuse color for consistency with
     // other geometric types (e.g., PLY).
     // other geometric types (e.g., PLY).
     aiMaterial* pcMat = new aiMaterial();
     aiMaterial* pcMat = new aiMaterial();
@@ -231,11 +233,12 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
     pScene->mMaterials = new aiMaterial*[1];
     pScene->mMaterials = new aiMaterial*[1];
     pScene->mMaterials[0] = pcMat;
     pScene->mMaterials[0] = pcMat;
 }
 }
+
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Read an ASCII STL file
 // Read an ASCII STL file
-void STLImporter::LoadASCIIFile()
-{
+void STLImporter::LoadASCIIFile( aiNode *root ) {
     std::vector<aiMesh*> meshes;
     std::vector<aiMesh*> meshes;
+    std::vector<aiNode*> nodes;
     const char* sz = mBuffer;
     const char* sz = mBuffer;
     const char* bufferEnd = mBuffer + fileSize;
     const char* bufferEnd = mBuffer + fileSize;
     std::vector<aiVector3D> positionBuffer;
     std::vector<aiVector3D> positionBuffer;
@@ -247,12 +250,15 @@ void STLImporter::LoadASCIIFile()
     positionBuffer.reserve(sizeEstimate);
     positionBuffer.reserve(sizeEstimate);
     normalBuffer.reserve(sizeEstimate);
     normalBuffer.reserve(sizeEstimate);
 
 
-    while (IsAsciiSTL(sz, static_cast<unsigned int>(bufferEnd - sz)))
-    {
+    while (IsAsciiSTL(sz, static_cast<unsigned int>(bufferEnd - sz))) {
+        std::vector<unsigned int> meshIndices;
         aiMesh* pMesh = new aiMesh();
         aiMesh* pMesh = new aiMesh();
         pMesh->mMaterialIndex = 0;
         pMesh->mMaterialIndex = 0;
+        meshIndices.push_back( meshes.size() );
         meshes.push_back(pMesh);
         meshes.push_back(pMesh);
-
+        aiNode *node = new aiNode;
+        node->mParent = root;
+        nodes.push_back( node );
         SkipSpaces(&sz);
         SkipSpaces(&sz);
         ai_assert(!IsLineEnd(sz));
         ai_assert(!IsLineEnd(sz));
 
 
@@ -265,20 +271,21 @@ void STLImporter::LoadASCIIFile()
 
 
         size_t temp;
         size_t temp;
         // setup the name of the node
         // setup the name of the node
-        if ((temp = (size_t)(sz-szMe)))    {
+        if ((temp = (size_t)(sz-szMe))) {
             if (temp >= MAXLEN) {
             if (temp >= MAXLEN) {
                 throw DeadlyImportError( "STL: Node name too long" );
                 throw DeadlyImportError( "STL: Node name too long" );
             }
             }
-
-            pScene->mRootNode->mName.length = temp;
-            memcpy(pScene->mRootNode->mName.data,szMe,temp);
-            pScene->mRootNode->mName.data[temp] = '\0';
+            std::string name( szMe, temp );
+            node->mName.Set( name.c_str() );
+            //pScene->mRootNode->mName.length = temp;
+            //memcpy(pScene->mRootNode->mName.data,szMe,temp);
+            //pScene->mRootNode->mName.data[temp] = '\0';
+        } else {
+            pScene->mRootNode->mName.Set("<STL_ASCII>");
         }
         }
-        else pScene->mRootNode->mName.Set("<STL_ASCII>");
 
 
         unsigned int faceVertexCounter = 3;
         unsigned int faceVertexCounter = 3;
-        for ( ;; )
-        {
+        for ( ;; ) {
             // go to the next token
             // go to the next token
             if(!SkipSpacesAndLineEnd(&sz))
             if(!SkipSpacesAndLineEnd(&sz))
             {
             {
@@ -300,9 +307,7 @@ void STLImporter::LoadASCIIFile()
                 SkipSpaces(&sz);
                 SkipSpaces(&sz);
                 if (strncmp(sz,"normal",6))    {
                 if (strncmp(sz,"normal",6))    {
                     DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
                     DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
-                }
-                else
-                {
+                } else {
                     if (sz[6] == '\0') {
                     if (sz[6] == '\0') {
                         throw DeadlyImportError("STL: unexpected EOF while parsing facet");
                         throw DeadlyImportError("STL: unexpected EOF while parsing facet");
                     }
                     }
@@ -316,16 +321,11 @@ void STLImporter::LoadASCIIFile()
                     normalBuffer.push_back(*vn);
                     normalBuffer.push_back(*vn);
                     normalBuffer.push_back(*vn);
                     normalBuffer.push_back(*vn);
                 }
                 }
-            }
-            // vertex 1.50000 1.50000 0.00000
-            else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6)))
-            {
+            } else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6))) { // vertex 1.50000 1.50000 0.00000
                 if (faceVertexCounter >= 3) {
                 if (faceVertexCounter >= 3) {
                     DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
                     DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
                     ++sz;
                     ++sz;
-                }
-                else
-                {
+                } else {
                     if (sz[6] == '\0') {
                     if (sz[6] == '\0') {
                         throw DeadlyImportError("STL: unexpected EOF while parsing facet");
                         throw DeadlyImportError("STL: unexpected EOF while parsing facet");
                     }
                     }
@@ -340,17 +340,14 @@ void STLImporter::LoadASCIIFile()
                     sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->z );
                     sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->z );
                     faceVertexCounter++;
                     faceVertexCounter++;
                 }
                 }
-            }
-            else if (!::strncmp(sz,"endsolid",8))    {
+            } else if (!::strncmp(sz,"endsolid",8))    {
                 do {
                 do {
                     ++sz;
                     ++sz;
                 } while (!::IsLineEnd(*sz));
                 } while (!::IsLineEnd(*sz));
                 SkipSpacesAndLineEnd(&sz);
                 SkipSpacesAndLineEnd(&sz);
                 // finished!
                 // finished!
                 break;
                 break;
-            }
-            // else skip the whole identifier
-            else {
+            } else { // else skip the whole identifier
                 do {
                 do {
                     ++sz;
                     ++sz;
                 } while (!::IsSpaceOrNewLine(*sz));
                 } while (!::IsSpaceOrNewLine(*sz));
@@ -380,13 +377,22 @@ void STLImporter::LoadASCIIFile()
 
 
         // now copy faces
         // now copy faces
         addFacesToMesh(pMesh);
         addFacesToMesh(pMesh);
+
+        // assign the meshes to the current node
+        pushMeshesToNode( meshIndices, node );
     }
     }
+
     // now add the loaded meshes
     // now add the loaded meshes
     pScene->mNumMeshes = (unsigned int)meshes.size();
     pScene->mNumMeshes = (unsigned int)meshes.size();
     pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
     pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
-    for (size_t i = 0; i < meshes.size(); i++)
-    {
-        pScene->mMeshes[i] = meshes[i];
+    for (size_t i = 0; i < meshes.size(); i++) {
+        pScene->mMeshes[ i ] = meshes[i];
+    }
+
+    root->mNumChildren = nodes.size();
+    root->mChildren = new aiNode*[ root->mNumChildren ];
+    for ( size_t i=0; i<nodes.size(); ++i ) {
+        root->mChildren[ i ] = nodes[ i ];
     }
     }
 }
 }
 
 
@@ -513,4 +519,18 @@ bool STLImporter::LoadBinaryFile()
     return false;
     return false;
 }
 }
 
 
+void STLImporter::pushMeshesToNode( std::vector<unsigned int> &meshIndices, aiNode *node ) {
+    ai_assert( nullptr != node );
+    if ( meshIndices.empty() ) {
+        return;
+    }
+
+    node->mNumMeshes = static_cast<unsigned int>( meshIndices.size() );
+    node->mMeshes = new unsigned int[ meshIndices.size() ];
+    for ( size_t i=0; i<meshIndices.size(); ++i ) {
+        node->mMeshes[ i ] = meshIndices[ i ];
+    }
+    meshIndices.clear();
+}
+
 #endif // !! ASSIMP_BUILD_NO_STL_IMPORTER
 #endif // !! ASSIMP_BUILD_NO_STL_IMPORTER

+ 34 - 26
code/STLLoader.h

@@ -48,53 +48,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "BaseImporter.h"
 #include "BaseImporter.h"
 #include <assimp/types.h>
 #include <assimp/types.h>
 
 
-namespace Assimp    {
+// Forward declarations
+struct aiNode;
+
+namespace Assimp {
+
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
-/** Importer class for the sterolithography STL file format
-*/
-class STLImporter : public BaseImporter
-{
+/**
+ * @brief   Importer class for the sterolithography STL file format.
+ */
+class STLImporter : public BaseImporter {
 public:
 public:
+    /**
+     * @brief STLImporter, the class default constructor.
+     */
     STLImporter();
     STLImporter();
-    ~STLImporter();
 
 
+    /**
+     * @brief   The class destructor.
+     */
+    ~STLImporter();
 
 
-public:
-
-    // -------------------------------------------------------------------
-    /** Returns whether the class can handle the format of the given file.
-     * See BaseImporter::CanRead() for details.
+    /**
+     * @brief   Returns whether the class can handle the format of the given file.
+     *  See BaseImporter::CanRead() for details.
      */
      */
-    bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
-        bool checkSig) const;
+    bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
 
 
 protected:
 protected:
 
 
-    // -------------------------------------------------------------------
-    /** Return importer meta information.
-     * See #BaseImporter::GetInfo for the details
+    /**
+     * @brief   Return importer meta information.
+     *  See #BaseImporter::GetInfo for the details
      */
      */
     const aiImporterDesc* GetInfo () const;
     const aiImporterDesc* GetInfo () const;
 
 
-    // -------------------------------------------------------------------
-    /** Imports the given file into the given scene structure.
+    /**
+     * @brief   Imports the given file into the given scene structure.
     * See BaseImporter::InternReadFile() for details
     * See BaseImporter::InternReadFile() for details
     */
     */
     void InternReadFile( const std::string& pFile, aiScene* pScene,
     void InternReadFile( const std::string& pFile, aiScene* pScene,
         IOSystem* pIOHandler);
         IOSystem* pIOHandler);
 
 
-
-    // -------------------------------------------------------------------
-    /** Loads a binary .stl file
+    /**
+     * @brief   Loads a binary .stl file
      * @return true if the default vertex color must be used as material color
      * @return true if the default vertex color must be used as material color
-    */
+     */
     bool LoadBinaryFile();
     bool LoadBinaryFile();
 
 
-    // -------------------------------------------------------------------
-    /** Loads a ASCII text .stl file
-    */
-    void LoadASCIIFile();
+    /**
+     * @brief   Loads a ASCII text .stl file
+     */
+    void LoadASCIIFile( aiNode *root );
+
+    void pushMeshesToNode( std::vector<unsigned int> &meshIndices, aiNode *node );
 
 
 protected:
 protected:
 
 

+ 105 - 0
code/ScaleProcess.cpp

@@ -0,0 +1,105 @@
+/*
+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 "ScaleProcess.h"
+
+#include <assimp/scene.h>
+#include <assimp/postprocess.h>
+
+namespace Assimp {
+
+ScaleProcess::ScaleProcess()
+: BaseProcess()
+, mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
+    // empty
+}
+
+ScaleProcess::~ScaleProcess() {
+    // empty
+}
+
+void ScaleProcess::setScale( ai_real scale ) {
+    mScale = scale;
+}
+
+ai_real ScaleProcess::getScale() const {
+    return mScale;
+}
+
+bool ScaleProcess::IsActive( unsigned int pFlags ) const {
+    return ( pFlags & aiProcess_GlobalScale ) != 0;
+}
+
+void ScaleProcess::SetupProperties( const Importer* pImp ) {
+    mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 0 );
+}
+
+void ScaleProcess::Execute( aiScene* pScene ) {
+    if ( nullptr == pScene ) {
+        return;
+    }
+
+    if ( nullptr == pScene->mRootNode ) {
+        return;
+    }
+
+    traverseNodes( pScene->mRootNode );
+}
+
+void ScaleProcess::traverseNodes( aiNode *node ) {
+    applyScaling( node );
+
+    /*for ( unsigned int i = 0; i < node->mNumChildren; ++i ) {
+        aiNode *currentNode = currentNode->mChildren[ i ];
+        if ( nullptr != currentNode ) {
+            traverseNodes( currentNode );
+        }
+    }*/
+}
+
+void ScaleProcess::applyScaling( aiNode *currentNode ) {
+    if ( nullptr != currentNode ) {
+        currentNode->mTransformation.a1 = currentNode->mTransformation.a1 * mScale;
+        currentNode->mTransformation.b2 = currentNode->mTransformation.b2 * mScale;
+        currentNode->mTransformation.c3 = currentNode->mTransformation.c3 * mScale;
+    }
+}
+
+} // Namespace Assimp

+ 87 - 0
code/ScaleProcess.h

@@ -0,0 +1,87 @@
+/*
+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"
+
+struct aiNode;
+
+#if (!defined AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT)
+#   define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT  1.0f
+#endif // !! AI_DEBONE_THRESHOLD
+
+namespace Assimp {
+
+// ---------------------------------------------------------------------------
+/** ScaleProcess: Class to rescale the whole model.
+*/
+class ASSIMP_API ScaleProcess : public BaseProcess {
+public:
+    /// The default class constructor.
+    ScaleProcess();
+
+    /// The class destructor.
+    virtual ~ScaleProcess();
+
+    /// Will set the scale manually.
+    void setScale( ai_real scale );
+
+    /// Returns the current scaling value.
+    ai_real getScale() const;
+
+    /// 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:
+    void traverseNodes( aiNode *currentNode );
+    void applyScaling( aiNode *currentNode );
+
+private:
+    ai_real mScale;
+};
+
+} // Namespace Assimp

+ 1 - 1
code/X3DExporter.cpp

@@ -692,7 +692,7 @@ bool found = false;
 	return true;
 	return true;
 }
 }
 
 
-X3DExporter::X3DExporter(const char* pFileName, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
+X3DExporter::X3DExporter(const char* pFileName, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
 	: mScene(pScene)
 	: mScene(pScene)
 {
 {
 list<SAttribute> attr_list;
 list<SAttribute> attr_list;

+ 1 - 1
code/X3DImporter_Metadata.cpp

@@ -105,7 +105,7 @@ bool X3DImporter::ParseHelper_CheckRead_X3DMetadataObject()
 	return true;
 	return true;
 }
 }
 
 
-void X3DImporter::ParseNode_Metadata(CX3DImporter_NodeElement* pParentElement, const std::string& pNodeName)
+void X3DImporter::ParseNode_Metadata(CX3DImporter_NodeElement* pParentElement, const std::string& /*pNodeName*/)
 {
 {
 	ParseHelper_Node_Enter(pParentElement);
 	ParseHelper_Node_Enter(pParentElement);
 	MACRO_NODECHECK_METADATA(mReader->getNodeName());
 	MACRO_NODECHECK_METADATA(mReader->getNodeName());

+ 1 - 1
code/glTF2Asset.h

@@ -403,7 +403,7 @@ namespace glTF2
         virtual ~Object() {}
         virtual ~Object() {}
 
 
         //! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
         //! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
-        static const char* TranslateId(Asset& r, const char* id)
+        static const char* TranslateId(Asset& /*r*/, const char* id)
             { return id; }
             { return id; }
     };
     };
 
 

+ 5 - 5
code/glTF2Asset.inl

@@ -288,7 +288,7 @@ inline Buffer::~Buffer()
 	for(SEncodedRegion* reg : EncodedRegion_List) delete reg;
 	for(SEncodedRegion* reg : EncodedRegion_List) delete reg;
 }
 }
 
 
-inline const char* Buffer::TranslateId(Asset& r, const char* id)
+inline const char* Buffer::TranslateId(Asset& /*r*/, const char* id)
 {
 {
     return id;
     return id;
 }
 }
@@ -623,7 +623,7 @@ inline Image::Image()
 
 
 }
 }
 
 
-inline void Image::Read(Value& obj, Asset& r)
+inline void Image::Read(Value& obj, Asset& /*r*/)
 {
 {
     if (!mDataLength) {
     if (!mDataLength) {
         if (Value* uri = FindString(obj, "uri")) {
         if (Value* uri = FindString(obj, "uri")) {
@@ -668,7 +668,7 @@ inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
     }
     }
 }
 }
 
 
-inline void Sampler::Read(Value& obj, Asset& r)
+inline void Sampler::Read(Value& obj, Asset& /*r*/)
 {
 {
     SetDefaults();
     SetDefaults();
 
 
@@ -886,7 +886,7 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
     }
     }
 }
 }
 
 
-inline void Camera::Read(Value& obj, Asset& r)
+inline void Camera::Read(Value& obj, Asset& /*r*/)
 {
 {
     type = MemberOrDefault(obj, "type", Camera::Perspective);
     type = MemberOrDefault(obj, "type", Camera::Perspective);
 
 
@@ -1087,7 +1087,7 @@ inline void Asset::ReadExtensionsUsed(Document& doc)
     #undef CHECK_EXT
     #undef CHECK_EXT
 }
 }
 
 
-inline IOStream* Asset::OpenFile(std::string path, const char* mode, bool absolute)
+inline IOStream* Asset::OpenFile(std::string path, const char* mode, bool /*absolute*/)
 {
 {
     #ifdef ASSIMP_API
     #ifdef ASSIMP_API
         return mIOSystem->Open(path, mode);
         return mIOSystem->Open(path, mode);

+ 4 - 4
code/glTF2AssetWriter.inl

@@ -72,7 +72,7 @@ namespace glTF2 {
             return val;
             return val;
         }
         }
 
 
-        inline Value& MakeValue(Value& val, float r, MemoryPoolAllocator<>& al) {
+        inline Value& MakeValue(Value& val, float r, MemoryPoolAllocator<>& /*al*/) {
             val.SetDouble(r);
             val.SetDouble(r);
 
 
             return val;
             return val;
@@ -171,7 +171,7 @@ namespace glTF2 {
         obj.AddMember("target", int(bv.target), w.mAl);
         obj.AddMember("target", int(bv.target), w.mAl);
     }
     }
 
 
-    inline void Write(Value& obj, Camera& c, AssetWriter& w)
+    inline void Write(Value& /*obj*/, Camera& /*c*/, AssetWriter& /*w*/)
     {
     {
 
 
     }
     }
@@ -432,7 +432,7 @@ namespace glTF2 {
         }
         }
     }
     }
 
 
-    inline void Write(Value& obj, Program& b, AssetWriter& w)
+    inline void Write(Value& /*obj*/, Program& /*b*/, AssetWriter& /*w*/)
     {
     {
 
 
     }
     }
@@ -465,7 +465,7 @@ namespace glTF2 {
         AddRefsVector(scene, "nodes", s.nodes, w.mAl);
         AddRefsVector(scene, "nodes", s.nodes, w.mAl);
     }
     }
 
 
-    inline void Write(Value& obj, Shader& b, AssetWriter& w)
+    inline void Write(Value& /*obj*/, Shader& /*b*/, AssetWriter& /*w*/)
     {
     {
 
 
     }
     }

+ 1 - 1
code/glTF2Exporter.cpp

@@ -80,7 +80,7 @@ namespace Assimp {
 } // end of namespace Assimp
 } // end of namespace Assimp
 
 
 glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
 glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
-                           const ExportProperties* pProperties, bool isBinary)
+                           const ExportProperties* pProperties, bool /*isBinary*/)
     : mFilename(filename)
     : mFilename(filename)
     , mIOSystem(pIOSystem)
     , mIOSystem(pIOSystem)
     , mProperties(pProperties)
     , mProperties(pProperties)

+ 5 - 3
code/glTF2Importer.cpp

@@ -159,21 +159,21 @@ static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
     o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
     o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
 }
 }
 
 
-inline void SetMaterialColorProperty(Asset& r, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
+inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
 {
 {
     aiColor4D col;
     aiColor4D col;
     CopyValue(prop, col);
     CopyValue(prop, col);
     mat->AddProperty(&col, 1, pKey, type, idx);
     mat->AddProperty(&col, 1, pKey, type, idx);
 }
 }
 
 
-inline void SetMaterialColorProperty(Asset& r, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
+inline void SetMaterialColorProperty(Asset& /*r*/, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
 {
 {
     aiColor4D col;
     aiColor4D col;
     CopyValue(prop, col);
     CopyValue(prop, col);
     mat->AddProperty(&col, 1, pKey, type, idx);
     mat->AddProperty(&col, 1, pKey, type, idx);
 }
 }
 
 
-inline void SetMaterialTextureProperty(std::vector<int>& embeddedTexIdxs, Asset& r, glTF2::TextureInfo prop, aiMaterial* mat, aiTextureType texType, unsigned int texSlot = 0)
+inline void SetMaterialTextureProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF2::TextureInfo prop, aiMaterial* mat, aiTextureType texType, unsigned int texSlot = 0)
 {
 {
     if (prop.texture && prop.texture->source) {
     if (prop.texture && prop.texture->source) {
         aiString uri(prop.texture->source->uri);
         aiString uri(prop.texture->source->uri);
@@ -296,6 +296,7 @@ static inline void SetFace(aiFace& face, int a, int b, int c)
     face.mIndices[2] = c;
     face.mIndices[2] = c;
 }
 }
 
 
+#ifdef ASSIMP_BUILD_DEBUG
 static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsigned nVerts)
 static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsigned nVerts)
 {
 {
     for (unsigned i = 0; i < nFaces; ++i) {
     for (unsigned i = 0; i < nFaces; ++i) {
@@ -307,6 +308,7 @@ static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsign
     }
     }
     return true;
     return true;
 }
 }
+#endif // ASSIMP_BUILD_DEBUG
 
 
 void glTF2Importer::ImportMeshes(glTF2::Asset& r)
 void glTF2Importer::ImportMeshes(glTF2::Asset& r)
 {
 {

+ 1 - 1
code/glTFAsset.h

@@ -393,7 +393,7 @@ namespace glTF
         virtual ~Object() {}
         virtual ~Object() {}
 
 
         //! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
         //! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
-        static const char* TranslateId(Asset& r, const char* id)
+        static const char* TranslateId(Asset& /*r*/, const char* id)
             { return id; }
             { return id; }
     };
     };
 
 

+ 4 - 4
code/glTFAsset.inl

@@ -675,7 +675,7 @@ inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
     }
     }
 }
 }
 
 
-inline void Sampler::Read(Value& obj, Asset& r)
+inline void Sampler::Read(Value& obj, Asset& /*r*/)
 {
 {
     SetDefaults();
     SetDefaults();
 
 
@@ -1093,7 +1093,7 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
 }
 }
 #endif
 #endif
 
 
-inline void Camera::Read(Value& obj, Asset& r)
+inline void Camera::Read(Value& obj, Asset& /*r*/)
 {
 {
     type = MemberOrDefault(obj, "type", Camera::Perspective);
     type = MemberOrDefault(obj, "type", Camera::Perspective);
 
 
@@ -1116,7 +1116,7 @@ inline void Camera::Read(Value& obj, Asset& r)
     }
     }
 }
 }
 
 
-inline void Light::Read(Value& obj, Asset& r)
+inline void Light::Read(Value& obj, Asset& /*r*/)
 {
 {
     SetDefaults();
     SetDefaults();
 
 
@@ -1414,7 +1414,7 @@ inline void Asset::ReadExtensionsUsed(Document& doc)
     #undef CHECK_EXT
     #undef CHECK_EXT
 }
 }
 
 
-inline IOStream* Asset::OpenFile(std::string path, const char* mode, bool absolute)
+inline IOStream* Asset::OpenFile(std::string path, const char* mode, bool /*absolute*/)
 {
 {
     #ifdef ASSIMP_API
     #ifdef ASSIMP_API
         return mIOSystem->Open(path, mode);
         return mIOSystem->Open(path, mode);

+ 5 - 5
code/glTFAssetWriter.inl

@@ -187,7 +187,7 @@ namespace glTF {
         obj.AddMember("target", int(bv.target), w.mAl);
         obj.AddMember("target", int(bv.target), w.mAl);
     }
     }
 
 
-    inline void Write(Value& obj, Camera& c, AssetWriter& w)
+    inline void Write(Value& /*obj*/, Camera& /*c*/, AssetWriter& /*w*/)
     {
     {
 
 
     }
     }
@@ -398,7 +398,7 @@ namespace glTF {
         }
         }
     }
     }
 
 
-    inline void Write(Value& obj, Program& b, AssetWriter& w)
+    inline void Write(Value& /*obj*/, Program& /*b*/, AssetWriter& /*w*/)
     {
     {
 
 
     }
     }
@@ -424,7 +424,7 @@ namespace glTF {
         AddRefsVector(scene, "nodes", s.nodes, w.mAl);
         AddRefsVector(scene, "nodes", s.nodes, w.mAl);
     }
     }
 
 
-    inline void Write(Value& obj, Shader& b, AssetWriter& w)
+    inline void Write(Value& /*obj*/, Shader& /*b*/, AssetWriter& /*w*/)
     {
     {
 
 
     }
     }
@@ -452,7 +452,7 @@ namespace glTF {
 
 
     }
     }
 
 
-    inline void Write(Value& obj, Technique& b, AssetWriter& w)
+    inline void Write(Value& /*obj*/, Technique& /*b*/, AssetWriter& /*w*/)
     {
     {
 
 
     }
     }
@@ -467,7 +467,7 @@ namespace glTF {
         }
         }
     }
     }
 
 
-    inline void Write(Value& obj, Light& b, AssetWriter& w)
+    inline void Write(Value& /*obj*/, Light& /*b*/, AssetWriter& /*w*/)
     {
     {
 
 
     }
     }

+ 3 - 1
code/glTFImporter.cpp

@@ -154,7 +154,7 @@ static void CopyValue(const glTF::mat4& v, aiMatrix4x4& o)
     o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
     o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
 }
 }
 
 
-inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& r, glTF::TexProperty prop, aiMaterial* mat,
+inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
     aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx)
     aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx)
 {
 {
     if (prop.texture) {
     if (prop.texture) {
@@ -234,6 +234,7 @@ static inline void SetFace(aiFace& face, int a, int b, int c)
     face.mIndices[2] = c;
     face.mIndices[2] = c;
 }
 }
 
 
+#ifdef ASSIMP_BUILD_DEBUG
 static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsigned nVerts)
 static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsigned nVerts)
 {
 {
     for (unsigned i = 0; i < nFaces; ++i) {
     for (unsigned i = 0; i < nFaces; ++i) {
@@ -245,6 +246,7 @@ static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsign
     }
     }
     return true;
     return true;
 }
 }
+#endif // ASSIMP_BUILD_DEBUG
 
 
 void glTFImporter::ImportMeshes(glTF::Asset& r)
 void glTFImporter::ImportMeshes(glTF::Asset& r)
 {
 {

+ 1 - 1
contrib/Open3DGC/o3dgcTriangleListEncoder.inl

@@ -125,7 +125,7 @@ namespace o3dgc
         }
         }
         return true;
         return true;
     }
     }
-    inline bool IsCase6(long degree, long numIndices, const long * const ops, const long * const indices)
+    inline bool IsCase6(long degree, long numIndices, const long * const ops, const long * const /*indices*/)
     {
     {
         // ops: 0000000 indices: 
         // ops: 0000000 indices: 
         if (numIndices!= 0) 
         if (numIndices!= 0) 

+ 1 - 1
contrib/openddlparser/code/DDLNode.cpp

@@ -191,7 +191,7 @@ Reference *DDLNode::getReferences() const {
     return m_references;
     return m_references;
 }
 }
 
 
-void DDLNode::dump(IOStreamBase &stream) {
+void DDLNode::dump(IOStreamBase &/*stream*/) {
     // Todo!    
     // Todo!    
 }
 }
 
 

+ 1 - 1
contrib/openddlparser/code/Value.cpp

@@ -294,7 +294,7 @@ Reference *Value::getRef() const {
     return (Reference*) m_data;
     return (Reference*) m_data;
 }
 }
 
 
-void Value::dump( IOStreamBase &stream ) {
+void Value::dump( IOStreamBase &/*stream*/ ) {
     switch( m_type ) {
     switch( m_type ) {
         case ddl_none:
         case ddl_none:
             std::cout << "None" << std::endl;
             std::cout << "None" << std::endl;

+ 4 - 0
contrib/openddlparser/include/openddlparser/OpenDDLParser.h

@@ -42,6 +42,10 @@ struct Property;
 template<class T>
 template<class T>
 inline
 inline
 bool isEmbeddedCommentOpenTag( T *in, T *end ) {
 bool isEmbeddedCommentOpenTag( T *in, T *end ) {
+    if ( in == end ) {
+        return false;
+    }
+
     if ( in == '/' && in+1 == '*' ) {
     if ( in == '/' && in+1 == '*' ) {
         return true;
         return true;
     }
     }

+ 1 - 1
doc/Doxyfile.in

@@ -725,7 +725,7 @@ RECURSIVE              = YES
 # Note that relative paths are relative to the directory from which doxygen is 
 # Note that relative paths are relative to the directory from which doxygen is 
 # run.
 # run.
 
 
-EXCLUDE                = 
+EXCLUDE                = irrXML.h
 
 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or 
 # directories that are symbolic links (a Unix file system feature) are excluded 
 # directories that are symbolic links (a Unix file system feature) are excluded 

+ 1 - 1
include/assimp/Exporter.hpp

@@ -171,7 +171,7 @@ public:
     *   Any IO handlers set via #SetIOHandler are ignored here.
     *   Any IO handlers set via #SetIOHandler are ignored here.
     * @note Use aiCopyScene() to get a modifiable copy of a previously
     * @note Use aiCopyScene() to get a modifiable copy of a previously
     *   imported scene. */
     *   imported scene. */
-    const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
+    const aiExportDataBlob* ExportToBlob(const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* = NULL);
     const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
     const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
 
 
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------

+ 8 - 0
include/assimp/config.h.in

@@ -933,6 +933,14 @@ enum aiComponent
 
 
 #define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
 #define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
 
 
+/**
+ *  @brief  Specifies a gobal key factor for scale, float value
+ */
+#define AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY "GLOBAL_SCALE_FACTOR"
+
+#if (!defined AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT)
+#   define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT  1.0f
+#endif // !! AI_DEBONE_THRESHOLD
 
 
 // ---------- All the Build/Compile-time defines ------------
 // ---------- All the Build/Compile-time defines ------------
 
 

+ 11 - 1
include/assimp/postprocess.h

@@ -525,7 +525,17 @@ enum aiPostProcessSteps
      *  Use <tt>#AI_CONFIG_PP_DB_ALL_OR_NONE</tt> if you want bones removed if and
      *  Use <tt>#AI_CONFIG_PP_DB_ALL_OR_NONE</tt> if you want bones removed if and
      *  only if all bones within the scene qualify for removal.
      *  only if all bones within the scene qualify for removal.
     */
     */
-    aiProcess_Debone  = 0x4000000
+    aiProcess_Debone  = 0x4000000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step will perform a global scale of the model.
+    *
+    *  Some importers are providing a mechanism to define a scaling unit for the
+    *  model. This post processing step can be used to do so.
+    *
+    *  Use <tt>#AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY</tt> to control this.
+    */
+    aiProcess_GlobalScale = 0x8000000
 
 
     // aiProcess_GenEntityMeshes = 0x100000,
     // aiProcess_GenEntityMeshes = 0x100000,
     // aiProcess_OptimizeAnimations = 0x200000
     // aiProcess_OptimizeAnimations = 0x200000

+ 3 - 0
port/PyAssimp/pyassimp/helper.py

@@ -30,6 +30,9 @@ if os.name=='posix':
     additional_dirs.append('/usr/lib/x86_64-linux-gnu')
     additional_dirs.append('/usr/lib/x86_64-linux-gnu')
     additional_dirs.append('/usr/local/lib/')
     additional_dirs.append('/usr/local/lib/')
 
 
+    if 'LD_LIBRARY_PATH' in os.environ:
+        additional_dirs.extend([item for item in os.environ['LD_LIBRARY_PATH'].split(':') if item])
+
     # check if running from anaconda.
     # check if running from anaconda.
     if "conda" or "continuum" in sys.version.lower():
     if "conda" or "continuum" in sys.version.lower():
       cur_path = get_python_lib()
       cur_path = get_python_lib()

+ 11 - 3
test/CMakeLists.txt

@@ -114,8 +114,6 @@ SET( TEST_SRCS
   unit/utPMXImporter.cpp
   unit/utPMXImporter.cpp
   unit/utRemoveComments.cpp
   unit/utRemoveComments.cpp
   unit/utRemoveComponent.cpp
   unit/utRemoveComponent.cpp
-  unit/utRemoveRedundantMaterials.cpp
-  unit/utRemoveVCProcess.cpp
   unit/utScenePreprocessor.cpp
   unit/utScenePreprocessor.cpp
   unit/utSceneCombiner.cpp
   unit/utSceneCombiner.cpp
   unit/utSharedPPData.cpp
   unit/utSharedPPData.cpp
@@ -131,12 +129,21 @@ SET( TEST_SRCS
   unit/utVersion.cpp
   unit/utVersion.cpp
   unit/utVector3.cpp
   unit/utVector3.cpp
   unit/utXImporterExporter.cpp
   unit/utXImporterExporter.cpp
+  unit/utX3DImportExport.cpp
   unit/utD3MFImportExport.cpp
   unit/utD3MFImportExport.cpp
   unit/utQ3DImportExport.cpp
   unit/utQ3DImportExport.cpp
+  unit/utSTLImportExport.cpp
   unit/utProfiler.cpp
   unit/utProfiler.cpp
 )
 )
+SET( POST_PROCESSES
+  unit/utRemoveRedundantMaterials.cpp
+  unit/utRemoveVCProcess.cpp
+  unit/utScaleProcess.cpp
+  unit/utJoinVertices.cpp
+)
 
 
-SOURCE_GROUP( tests FILES  ${TEST_SRCS} )
+SOURCE_GROUP( tests             FILES  ${TEST_SRCS} )
+SOURCE_GROUP( tests/PostProcess FILES  ${POST_PROCESSES})
 
 
 add_executable( unit
 add_executable( unit
     ../contrib/gtest/src/gtest-all.cc
     ../contrib/gtest/src/gtest-all.cc
@@ -144,6 +151,7 @@ add_executable( unit
     unit/Main.cpp
     unit/Main.cpp
     ../code/Version.cpp
     ../code/Version.cpp
     ${TEST_SRCS}
     ${TEST_SRCS}
+    ${POST_PROCESSES}
 )
 )
 
 
 add_definitions(-DASSIMP_TEST_MODELS_DIR="${CMAKE_CURRENT_LIST_DIR}/models")
 add_definitions(-DASSIMP_TEST_MODELS_DIR="${CMAKE_CURRENT_LIST_DIR}/models")

+ 18 - 0
test/models/STL/triangle_with_two_solids.stl

@@ -0,0 +1,18 @@
+solid testTriangle_1
+  facet normal 0.0 0.0 1.0 
+    outer loop 
+      vertex 1.0 1.0 0.0 
+      vertex -1.0 1.0 0.0 
+      vertex 0.0 -1.0 0.0 
+    endloop 
+  endfacet 
+endsolid
+solid testTriangle_2
+  facet normal 0.0 0.0 1.0 
+    outer loop 
+      vertex 3.0 3.0 0.0 
+      vertex 2.0 3.0 0.0 
+      vertex 0.0 2.0 0.0 
+    endloop 
+  endfacet 
+endsolid

+ 7 - 1
test/unit/TestModelFactory.h

@@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include "UnitTestPCH.h"
 #include "UnitTestPCH.h"
 #include <assimp/scene.h>
 #include <assimp/scene.h>
+#include <assimp/mesh.h>
 #include <assimp/material.h>
 #include <assimp/material.h>
 
 
 namespace Assimp {
 namespace Assimp {
@@ -57,7 +58,7 @@ public:
         // empty
         // empty
     }
     }
 
 
-    static aiScene *createDefaultTestModel( float &opacity  ) {
+    static aiScene *createDefaultTestModel( float &opacity ) {
         aiScene *scene( new aiScene );
         aiScene *scene( new aiScene );
         scene->mNumMaterials = 1;
         scene->mNumMaterials = 1;
         scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
         scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
@@ -93,6 +94,11 @@ public:
 
 
         return scene;
         return scene;
     }
     }
+
+    static void releaseDefaultTestModel( aiScene **scene ) {
+        delete *scene;
+        *scene = nullptr;
+    }
 };
 };
 
 
 }
 }

+ 36 - 0
test/unit/utObjImportExport.cpp

@@ -205,6 +205,7 @@ protected:
         const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/OBJ/spider.obj", 0 );
         const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/OBJ/spider.obj", 0 );
         EXPECT_NE( nullptr, scene );
         EXPECT_NE( nullptr, scene );
         EXPECT_EQ( aiReturn_SUCCESS, exporter.Export( scene, "obj", ASSIMP_TEST_MODELS_DIR "/OBJ/spider_test.obj" ) );
         EXPECT_EQ( aiReturn_SUCCESS, exporter.Export( scene, "obj", ASSIMP_TEST_MODELS_DIR "/OBJ/spider_test.obj" ) );
+        EXPECT_EQ( aiReturn_SUCCESS, exporter.Export( scene, "objnomtl", ASSIMP_TEST_MODELS_DIR "/OBJ/spider_nomtl_test.obj" ) );
         
         
         return true;
         return true;
     }
     }
@@ -305,3 +306,38 @@ TEST_F(utObjImportExport, relative_indices_Test) {
     }
     }
 
 
 }
 }
+
+TEST_F(utObjImportExport, homogeneous_coordinates_Test) {
+    static const std::string ObjModel =
+        "v -0.500000 0.000000 0.400000 0.50000\n"
+        "v -0.500000 0.000000 -0.800000 1.00000\n"
+        "v 0.500000 1.000000 -0.800000 0.5000\n"
+        "f 1 2 3\nB";
+
+    Assimp::Importer myimporter;
+    const aiScene *scene = myimporter.ReadFileFromMemory(ObjModel.c_str(), ObjModel.size(), aiProcess_ValidateDataStructure);
+    EXPECT_NE(nullptr, scene);
+
+    EXPECT_EQ(scene->mNumMeshes, 1);
+    const aiMesh *mesh = scene->mMeshes[0];
+    EXPECT_EQ(mesh->mNumVertices, 3);
+    EXPECT_EQ(mesh->mNumFaces, 1);
+    const aiFace face = mesh->mFaces[0];
+    EXPECT_EQ(face.mNumIndices, 3);
+    const aiVector3D vertice = mesh->mVertices[0];
+    EXPECT_EQ(vertice.x, -1.0f);
+    EXPECT_EQ(vertice.y, 0.0f);
+    EXPECT_EQ(vertice.z, 0.8f);
+}
+
+TEST_F(utObjImportExport, 0based_array_Test) {
+    static const std::string ObjModel =
+        "v -0.500000 0.000000 0.400000\n"
+        "v -0.500000 0.000000 -0.800000\n"
+        "v -0.500000 1.000000 -0.800000\n"
+        "f 0 1 2\nB";
+
+    Assimp::Importer myimporter;
+    const aiScene *scene = myimporter.ReadFileFromMemory(ObjModel.c_str(), ObjModel.size(), 0);
+    EXPECT_EQ(nullptr, scene);
+}

+ 68 - 0
test/unit/utSTLImportExport.cpp

@@ -0,0 +1,68 @@
+/*
+---------------------------------------------------------------------------
+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 "UnitTestPCH.h"
+#include "SceneDiffer.h"
+#include "AbstractImportExportBase.h"
+
+#include <assimp/Importer.hpp>
+
+using namespace Assimp;
+
+class utSTLImporterExporter : public AbstractImportExportBase {
+public:
+    virtual bool importerTest() {
+        Assimp::Importer importer;
+        const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/Spider_ascii.stl", 0 );
+        return nullptr != scene;
+    }
+};
+
+TEST_F( utSTLImporterExporter, importXFromFileTest ) {
+    EXPECT_TRUE( importerTest() );
+}
+
+TEST_F( utSTLImporterExporter, test_with_two_solids ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/triangle_with_two_solids.stl", 0 );
+    EXPECT_NE( nullptr, scene );
+}

+ 85 - 0
test/unit/utScaleProcess.cpp

@@ -0,0 +1,85 @@
+/*
+---------------------------------------------------------------------------
+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 "UnitTestPCH.h"
+#include "ScaleProcess.h"
+#include "TestModelFactory.h"
+
+namespace Assimp {
+namespace UnitTest {
+
+class utScaleProcess : public ::testing::Test {
+    // empty
+};
+
+TEST_F( utScaleProcess, createTest ) {
+    bool ok = true;
+    try {
+        ScaleProcess process;
+    } catch ( ... ) {
+        ok = false;
+    }
+    EXPECT_TRUE( ok );
+}
+
+TEST_F( utScaleProcess, accessScaleTest ) {
+    ScaleProcess process;
+    EXPECT_FLOAT_EQ( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT, process.getScale() );
+
+    process.setScale( 2.0f );
+    EXPECT_FLOAT_EQ( 2.0f, process.getScale() );
+}
+
+TEST_F( utScaleProcess, rescaleModelTest ) {
+    float opacity;
+    aiScene *testScene = TestModelFacttory::createDefaultTestModel( opacity );
+    ai_real v1 = testScene->mRootNode->mTransformation.a1;
+    ScaleProcess process;
+    process.setScale( 10.0f );
+    process.Execute( testScene );
+    ai_real v2 = testScene->mRootNode->mTransformation.a1;
+    const ai_real scale = v2 / v1;
+    EXPECT_FLOAT_EQ( scale, 10.0f );
+    TestModelFacttory::releaseDefaultTestModel( &testScene );
+}
+
+} // Namespace UnitTest
+} // Namespace Assimp

+ 62 - 0
test/unit/utX3DImportExport.cpp

@@ -0,0 +1,62 @@
+/*
+---------------------------------------------------------------------------
+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 "UnitTestPCH.h"
+#include "SceneDiffer.h"
+#include "AbstractImportExportBase.h"
+
+#include <assimp/Importer.hpp>
+
+using namespace Assimp;
+
+class utX3DImportExport : public AbstractImportExportBase {
+public:
+    virtual bool importerTest() {
+        Assimp::Importer importer;
+        const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/X3D/ComputerKeyboard.x3d", 0 );
+        return nullptr != scene;
+    }
+};
+
+TEST_F( utX3DImportExport, importX3DFromFileTest ) {
+    EXPECT_TRUE( importerTest() );
+}