Selaa lähdekoodia

Merge branch 'master' into MemoryOptimizationForGLTFWithSharedAttr

Kim Kulling 2 vuotta sitten
vanhempi
commit
19ff57a6c3
100 muutettua tiedostoa jossa 1232 lisäystä ja 899 poistoa
  1. 128 0
      CODE_OF_CONDUCT.md
  2. 18 23
      Readme.md
  3. 1 0
      code/AssetLib/AMF/AMFImporter_Postprocess.cpp
  4. 1 1
      code/AssetLib/Blender/BlenderScene.cpp
  5. 21 14
      code/AssetLib/FBX/FBXConverter.cpp
  6. 8 4
      code/AssetLib/FBX/FBXDeformer.cpp
  7. 5 4
      code/AssetLib/FBX/FBXDocument.h
  8. 5 2
      code/AssetLib/FBX/FBXMeshGeometry.cpp
  9. 5 4
      code/AssetLib/FBX/FBXMeshGeometry.h
  10. 39 5
      code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp
  11. 11 1
      code/AssetLib/MDL/HalfLife/HL1MDLLoader.h
  12. 0 2
      code/CApi/AssimpCExport.cpp
  13. 10 10
      code/CApi/CInterfaceIOWrapper.cpp
  14. 33 22
      code/CApi/CInterfaceIOWrapper.h
  15. 71 1
      code/CMakeLists.txt
  16. 2 20
      code/Common/PolyTools.h
  17. 1 0
      code/Common/Subdivision.cpp
  18. 79 0
      code/Geometry/GeometryUtils.cpp
  19. 67 0
      code/Geometry/GeometryUtils.h
  20. 0 4
      code/PostProcessing/CalcTangentsProcess.cpp
  21. 6 13
      code/PostProcessing/CalcTangentsProcess.h
  22. 0 8
      code/PostProcessing/ComputeUVMappingProcess.cpp
  23. 7 12
      code/PostProcessing/ComputeUVMappingProcess.h
  24. 0 16
      code/PostProcessing/ConvertToLHProcess.cpp
  25. 10 17
      code/PostProcessing/ConvertToLHProcess.h
  26. 28 51
      code/PostProcessing/DeboneProcess.cpp
  27. 4 4
      code/PostProcessing/DeboneProcess.h
  28. 0 8
      code/PostProcessing/DropFaceNormalsProcess.cpp
  29. 4 5
      code/PostProcessing/DropFaceNormalsProcess.h
  30. 0 4
      code/PostProcessing/EmbedTexturesProcess.cpp
  31. 5 5
      code/PostProcessing/EmbedTexturesProcess.h
  32. 2 36
      code/PostProcessing/FindDegenerates.cpp
  33. 8 12
      code/PostProcessing/FindDegenerates.h
  34. 0 4
      code/PostProcessing/FindInstancesProcess.cpp
  35. 10 15
      code/PostProcessing/FindInstancesProcess.h
  36. 0 4
      code/PostProcessing/FindInvalidDataProcess.cpp
  37. 16 14
      code/PostProcessing/FindInvalidDataProcess.h
  38. 2 13
      code/PostProcessing/FixNormalsStep.cpp
  39. 7 6
      code/PostProcessing/FixNormalsStep.h
  40. 0 4
      code/PostProcessing/GenBoundingBoxesProcess.cpp
  41. 14 9
      code/PostProcessing/GenBoundingBoxesProcess.h
  42. 0 8
      code/PostProcessing/GenFaceNormalsProcess.cpp
  43. 11 13
      code/PostProcessing/GenFaceNormalsProcess.h
  44. 5 8
      code/PostProcessing/GenVertexNormalsProcess.cpp
  45. 6 5
      code/PostProcessing/GenVertexNormalsProcess.h
  46. 0 4
      code/PostProcessing/ImproveCacheLocality.cpp
  47. 8 11
      code/PostProcessing/ImproveCacheLocality.h
  48. 6 10
      code/PostProcessing/JoinVerticesProcess.h
  49. 3 5
      code/PostProcessing/LimitBoneWeightsProcess.cpp
  50. 12 10
      code/PostProcessing/LimitBoneWeightsProcess.h
  51. 0 4
      code/PostProcessing/MakeVerboseFormat.cpp
  52. 7 10
      code/PostProcessing/MakeVerboseFormat.h
  53. 0 4
      code/PostProcessing/OptimizeGraph.cpp
  54. 3 1
      code/PostProcessing/OptimizeGraph.h
  55. 0 4
      code/PostProcessing/OptimizeMeshes.cpp
  56. 6 9
      code/PostProcessing/OptimizeMeshes.h
  57. 0 4
      code/PostProcessing/PretransformVertices.cpp
  58. 3 1
      code/PostProcessing/PretransformVertices.h
  59. 0 4
      code/PostProcessing/RemoveRedundantMaterials.cpp
  60. 6 7
      code/PostProcessing/RemoveRedundantMaterials.h
  61. 0 4
      code/PostProcessing/RemoveVCProcess.cpp
  62. 8 11
      code/PostProcessing/RemoveVCProcess.h
  63. 19 24
      code/PostProcessing/ScaleProcess.cpp
  64. 6 7
      code/PostProcessing/ScaleProcess.h
  65. 0 4
      code/PostProcessing/SortByPTypeProcess.cpp
  66. 6 4
      code/PostProcessing/SortByPTypeProcess.h
  67. 63 121
      code/PostProcessing/SplitByBoneCountProcess.cpp
  68. 19 27
      code/PostProcessing/SplitByBoneCountProcess.h
  69. 0 6
      code/PostProcessing/SplitLargeMeshes.cpp
  70. 12 24
      code/PostProcessing/SplitLargeMeshes.h
  71. 10 24
      code/PostProcessing/TextureTransform.cpp
  72. 9 15
      code/PostProcessing/TextureTransform.h
  73. 15 9
      code/PostProcessing/TriangulateProcess.cpp
  74. 6 4
      code/PostProcessing/TriangulateProcess.h
  75. 7 7
      code/PostProcessing/ValidateDataStructure.cpp
  76. 6 8
      code/PostProcessing/ValidateDataStructure.h
  77. 326 98
      contrib/stb/stb_image.h
  78. 2 1
      contrib/unzip/crypt.c
  79. 9 1
      contrib/zlib/CMakeLists.txt
  80. 5 1
      port/PyAssimp/pyassimp/core.py
  81. BIN
      test/models-nonbsd/BLEND/guard1_body.png
  82. BIN
      test/models-nonbsd/BLEND/guard1_face.png
  83. BIN
      test/models-nonbsd/BLEND/guard1_helmet.png
  84. BIN
      test/models-nonbsd/BLEND/iron_grill.png
  85. BIN
      test/models-nonbsd/BLEND/round_grill.png
  86. BIN
      test/models-nonbsd/IRR/skybox.xml
  87. BIN
      test/models-nonbsd/IRR/skybox_UTF16LE.xml
  88. BIN
      test/models/COB/axe.jpg
  89. BIN
      test/models/COB/dwarf.jpg
  90. BIN
      test/models/COB/dwarf2.jpg
  91. BIN
      test/models/IRR/1.png
  92. BIN
      test/models/IRR/EpisodeII_TheDwarfesStrikeBack.irr
  93. BIN
      test/models/IRR/EpisodeII_TheDwarfesStrikeBack_UTF16LE.irr
  94. BIN
      test/models/IRR/EpisodeI_ANewDwarf.irr
  95. BIN
      test/models/IRR/EpisodeI_ANewDwarf_UTF16LE.irr
  96. BIN
      test/models/IRR/animMesh.irr
  97. BIN
      test/models/IRR/animMesh_UTF16LE.irr
  98. BIN
      test/models/IRR/box.irr
  99. BIN
      test/models/IRR/box_UTF16LE.irr
  100. BIN
      test/models/IRR/brownground_1-1.jpg

+ 128 - 0
CODE_OF_CONDUCT.md

@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+  and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+  overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+  advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+  address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior,  harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.

+ 18 - 23
Readme.md

@@ -1,6 +1,8 @@
 Open Asset Import Library (assimp)
 ==================================
-A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
+
+Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
+
 ### Current project status ###
 [![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp) 
 ![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
@@ -14,7 +16,6 @@ A library to import and export various 3d-model-formats including scene-post-pro
 [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
 [![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
-[![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
 <br>
 
 APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
@@ -23,15 +24,19 @@ Additionally, assimp features various __mesh post processing tools__: normals an
 ### Latest Doc's ###
 Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/). 
 
-### Get involved ###
-This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
-<br>
-You find a bug in the docs? Use [Doc-Repo](https://github.com/assimp/assimp-docs).
-<br>
-Please check our Wiki as well: https://github.com/assimp/assimp/wiki
+### Prebuild binaries ###
+Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib)
 
 If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
 
+### Communities ###
+- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
+- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/)
+- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). 
+- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
+
+And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
+
 #### Supported file formats ####
 You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
 
@@ -66,28 +71,18 @@ Open Asset Import Library is implemented in C++. The directory structure looks l
 	/port		Ports to other languages and scripts to maintain those.
 	/test		Unit- and regression tests, test suite of models
 	/tools		Tools (old assimp viewer, command line `assimp`)
-	/samples	A small number of samples to illustrate possible
-                        use cases for Assimp
+	/samples	A small number of samples to illustrate possible use-cases for Assimp
 
 The source code is organized in the following way:
 
 	code/Common			The base implementation for importers and the infrastructure
+	code/CApi                       Special implementations which are only used for the C-API
+	code/Geometry                   A collection of geometry tools
+	code/Material                   The material system
+	code/PBR                        An exporter for physical based models
 	code/PostProcessing		The post-processing steps
 	code/AssetLib/<FormatName>	Implementation for import and export for the format
 
-### Where to get help ###
-To find our documentation, visit [our website](https://assimp.org/) or check out [Wiki](https://github.com/assimp/assimp/wiki)
-
-If the docs don't solve your problem, you can:
-- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). 
-- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/)
-- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
-- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
-
-Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
-
-And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
-
 ### Contributing ###
 Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
 a pull request with your changes against the main repository's `master` branch.

+ 1 - 0
code/AssetLib/AMF/AMFImporter_Postprocess.cpp

@@ -815,6 +815,7 @@ nl_clean_loop:
             for (; next_it != nodeArray.end(); ++next_it) {
                 if ((*next_it)->FindNode((*nl_it)->mName) != nullptr) {
                     // if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
+                    // FIXME: this leaks memory on test models test8.amf and test9.amf
                     nodeArray.erase(nl_it);
 
                     goto nl_clean_loop;

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

@@ -569,7 +569,7 @@ void Structure ::Convert<MVert>(
         const FileDatabase &db) const {
 
     ReadFieldArray<ErrorPolicy_Fail>(dest.co, "co", db);
-    ReadFieldArray<ErrorPolicy_Fail>(dest.no, "no", db);
+    ReadFieldArray<ErrorPolicy_Warn>(dest.no, "no", db);
     ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
     //ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
     ReadField<ErrorPolicy_Igno>(dest.bweight, "bweight", db);

+ 21 - 14
code/AssetLib/FBX/FBXConverter.cpp

@@ -640,7 +640,7 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
 bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
     const PropertyTable &props = model.Props();
 
-    const auto zero_epsilon = ai_epsilon;
+    const auto zero_epsilon = Math::getEpsilon<ai_real>();
     const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
     for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
         const TransformationComp comp = static_cast<TransformationComp>(i);
@@ -1180,15 +1180,23 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
     std::vector<aiAnimMesh *> animMeshes;
     for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
         for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
-            const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
-            for (size_t i = 0; i < shapeGeometries.size(); i++) {
+            const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
+            for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
                 aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
-                const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
-                const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
-                const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
-                const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
+                const auto &curVertices = shapeGeometry->GetVertices();
+                const auto &curNormals = shapeGeometry->GetNormals();
+                const auto &curIndices = shapeGeometry->GetIndices();
                 //losing channel name if using shapeGeometry->Name()
-                animMesh->mName.Set(FixAnimMeshName(blendShapeChannel->Name()));
+                // if blendShapeChannel Name is empty or don't have a ".", add geoMetryName;
+                auto aniName = FixAnimMeshName(blendShapeChannel->Name());
+                auto geoMetryName = FixAnimMeshName(shapeGeometry->Name());
+                if (aniName.empty()) {
+                    aniName = geoMetryName;
+                }
+                else if (aniName.find('.') == aniName.npos) {
+                    aniName += "." + geoMetryName;
+                }
+                animMesh->mName.Set(aniName);
                 for (size_t j = 0; j < curIndices.size(); j++) {
                     const unsigned int curIndex = curIndices.at(j);
                     aiVector3D vertex = curVertices.at(j);
@@ -1410,13 +1418,12 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
     std::vector<aiAnimMesh *> animMeshes;
     for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
         for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
-            const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
-            for (size_t i = 0; i < shapeGeometries.size(); i++) {
+            const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
+            for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
                 aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
-                const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
-                const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
-                const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
-                const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
+                const auto& curVertices = shapeGeometry->GetVertices();
+                const auto& curNormals = shapeGeometry->GetNormals();
+                const auto& curIndices = shapeGeometry->GetIndices();
                 animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
                 for (size_t j = 0; j < curIndices.size(); j++) {
                     unsigned int curIndex = curIndices.at(j);

+ 8 - 4
code/AssetLib/FBX/FBXDeformer.cpp

@@ -154,8 +154,10 @@ BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc,
     for (const Connection* con : conns) {
         const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
         if (bspc) {
-            blendShapeChannels.push_back(bspc);
-            continue;
+            auto pr = blendShapeChannels.insert(bspc);
+            if (!pr.second) {
+                FBXImporter::LogWarn("there is the same blendShapeChannel id ", bspc->ID());
+            }
         }
     }
 }
@@ -179,8 +181,10 @@ BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const
     for (const Connection* con : conns) {
         const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
         if (sg) {
-            shapeGeometries.push_back(sg);
-            continue;
+            auto pr = shapeGeometries.insert(sg);
+            if (!pr.second) {
+                FBXImporter::LogWarn("there is the same shapeGeometrie id ", sg->ID());
+            }
         }
     }
 }

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

@@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define INCLUDED_AI_FBX_DOCUMENT_H
 
 #include <numeric>
+#include <unordered_set>
 #include <stdint.h>
 #include <assimp/mesh.h>
 #include "FBXProperties.h"
@@ -855,14 +856,14 @@ public:
         return fullWeights;
     }
 
-    const std::vector<const ShapeGeometry*>& GetShapeGeometries() const {
+    const std::unordered_set<const ShapeGeometry*>& GetShapeGeometries() const {
         return shapeGeometries;
     }
 
 private:
     float percent;
     WeightArray fullWeights;
-    std::vector<const ShapeGeometry*> shapeGeometries;
+    std::unordered_set<const ShapeGeometry*> shapeGeometries;
 };
 
 /** DOM class for BlendShape deformers */
@@ -872,12 +873,12 @@ public:
 
     virtual ~BlendShape();
 
-    const std::vector<const BlendShapeChannel*>& BlendShapeChannels() const {
+    const std::unordered_set<const BlendShapeChannel*>& BlendShapeChannels() const {
         return blendShapeChannels;
     }
 
 private:
-    std::vector<const BlendShapeChannel*> blendShapeChannels;
+    std::unordered_set<const BlendShapeChannel*> blendShapeChannels;
 };
 
 /** DOM class for skin deformer clusters (aka sub-deformers) */

+ 5 - 2
code/AssetLib/FBX/FBXMeshGeometry.cpp

@@ -69,13 +69,16 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
         }
         const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
         if (bsp) {
-            blendShapes.push_back(bsp);
+            auto pr = blendShapes.insert(bsp);
+            if (!pr.second) {
+                FBXImporter::LogWarn("there is the same blendShape id ", bsp->ID());
+            }
         }
     }
 }
 
 // ------------------------------------------------------------------------------------------------
-const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
+const std::unordered_set<const BlendShape*>& Geometry::GetBlendShapes() const {
     return blendShapes;
 }
 

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

@@ -62,7 +62,7 @@ public:
     /// @param name     The name instance
     /// @param doc      The document instance
     Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
-    
+
     /// @brief The class destructor, default.
     virtual ~Geometry() = default;
 
@@ -72,11 +72,12 @@ public:
 
     /// @brief Get the BlendShape attached to this geometry or nullptr
     /// @return The blendshape arrays.
-    const std::vector<const BlendShape*>& GetBlendShapes() const;
+    const std::unordered_set<const BlendShape*>& GetBlendShapes() const;
 
 private:
     const Skin* skin;
-    std::vector<const BlendShape*> blendShapes;
+    std::unordered_set<const BlendShape*> blendShapes;
+
 };
 
 typedef std::vector<int> MatIndexArray;
@@ -112,7 +113,7 @@ public:
     /// @return The binomal vector.
     const std::vector<aiVector3D>& GetBinormals() const;
 
-    /// @brief Return list of faces - each entry denotes a face and specifies how many vertices it has. 
+    /// @brief Return list of faces - each entry denotes a face and specifies how many vertices it has.
     ///        Vertices are taken from the vertex data arrays in sequential order.
     /// @return The face indices vector.
     const std::vector<unsigned int>& GetFaceIndexCounts() const;

+ 39 - 5
code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp

@@ -470,14 +470,16 @@ void HL1MDLLoader::read_bones() {
 
     temp_bones_.resize(header_->numbones);
 
+    // Create the main 'bones' node that will contain all MDL root bones.
     aiNode *bones_node = new aiNode(AI_MDL_HL1_NODE_BONES);
     rootnode_children_.push_back(bones_node);
-    bones_node->mNumChildren = static_cast<unsigned int>(header_->numbones);
-    bones_node->mChildren = new aiNode *[bones_node->mNumChildren];
+
+    // Store roots bones IDs temporarily.
+    std::vector<int> roots;
 
     // Create bone matrices in local space.
     for (int i = 0; i < header_->numbones; ++i) {
-        aiNode *bone_node = temp_bones_[i].node = bones_node->mChildren[i] = new aiNode(unique_bones_names[i]);
+        aiNode *bone_node = temp_bones_[i].node = new aiNode(unique_bones_names[i]);
 
         aiVector3D angles(pbone[i].value[3], pbone[i].value[4], pbone[i].value[5]);
         temp_bones_[i].absolute_transform = bone_node->mTransformation =
@@ -485,9 +487,11 @@ void HL1MDLLoader::read_bones() {
                         aiVector3D(pbone[i].value[0], pbone[i].value[1], pbone[i].value[2]));
 
         if (pbone[i].parent == -1) {
-            bone_node->mParent = scene_->mRootNode;
+            bone_node->mParent = bones_node;
+            roots.push_back(i); // This bone has no parent. Add it to the roots list.
         } else {
-            bone_node->mParent = bones_node->mChildren[pbone[i].parent];
+            bone_node->mParent = temp_bones_[pbone[i].parent].node;
+            temp_bones_[pbone[i].parent].children.push_back(i); // Add this bone to the parent bone's children list.
 
             temp_bones_[i].absolute_transform =
                     temp_bones_[pbone[i].parent].absolute_transform * bone_node->mTransformation;
@@ -496,6 +500,36 @@ void HL1MDLLoader::read_bones() {
         temp_bones_[i].offset_matrix = temp_bones_[i].absolute_transform;
         temp_bones_[i].offset_matrix.Inverse();
     }
+
+    // Allocate memory for each MDL root bone.
+    bones_node->mNumChildren = static_cast<unsigned int>(roots.size());
+    bones_node->mChildren = new aiNode *[bones_node->mNumChildren];
+
+    // Build all bones children hierarchy starting from each MDL root bone.
+    for (size_t i = 0; i < roots.size(); ++i)
+    {
+        const TempBone &root_bone = temp_bones_[roots[i]];
+        bones_node->mChildren[i] = root_bone.node;
+        build_bone_children_hierarchy(root_bone);
+    }
+}
+
+void HL1MDLLoader::build_bone_children_hierarchy(const TempBone &bone)
+{
+    if (bone.children.empty())
+        return;
+
+    aiNode* bone_node = bone.node;
+    bone_node->mNumChildren = static_cast<unsigned int>(bone.children.size());
+    bone_node->mChildren = new aiNode *[bone_node->mNumChildren];
+
+    // Build each child bone's hierarchy recursively.
+    for (size_t i = 0; i < bone.children.size(); ++i)
+    {
+        const TempBone &child_bone = temp_bones_[bone.children[i]];
+        bone_node->mChildren[i] = child_bone.node;
+        build_bone_children_hierarchy(child_bone);
+    }
 }
 
 // ------------------------------------------------------------------------------------------------

+ 11 - 1
code/AssetLib/MDL/HalfLife/HL1MDLLoader.h

@@ -143,6 +143,14 @@ private:
      */
     static bool get_num_blend_controllers(const int num_blend_animations, int &num_blend_controllers);
 
+    /**
+     *  \brief Build a bone's node children hierarchy.
+     *
+     * \param[in] bone The bone for which we must build all children hierarchy.
+     */
+    struct TempBone;
+    void build_bone_children_hierarchy(const TempBone& bone);
+
     /** Output scene to be filled */
     aiScene *scene_;
 
@@ -198,11 +206,13 @@ private:
         TempBone() :
             node(nullptr),
             absolute_transform(),
-            offset_matrix() {}
+            offset_matrix(),
+            children() {}
 
         aiNode *node;
         aiMatrix4x4 absolute_transform;
         aiMatrix4x4 offset_matrix;
+        std::vector<int> children; // Bone children
     };
 
     std::vector<TempBone> temp_bones_;

+ 0 - 2
code/CApi/AssimpCExport.cpp

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2022, assimp team
 
-
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 10 - 10
code/CApi/CInterfaceIOWrapper.cpp

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2022, assimp team
 
-
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -47,14 +45,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 namespace Assimp {
 
+// ------------------------------------------------------------------------------------------------
 CIOStreamWrapper::~CIOStreamWrapper() {
-    /* Various places depend on this destructor to close the file */
-    if (mFile) {
+    // Various places depend on this destructor to close the file
+    if (mFile != nullptr) {
+        
         mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile);
     }
 }
 
-// ...................................................................
+// ------------------------------------------------------------------------------------------------
 size_t CIOStreamWrapper::Read(void *pvBuffer,
         size_t pSize,
         size_t pCount) {
@@ -62,7 +62,7 @@ size_t CIOStreamWrapper::Read(void *pvBuffer,
     return mFile->ReadProc(mFile, (char *)pvBuffer, pSize, pCount);
 }
 
-// ...................................................................
+// ------------------------------------------------------------------------------------------------
 size_t CIOStreamWrapper::Write(const void *pvBuffer,
         size_t pSize,
         size_t pCount) {
@@ -70,23 +70,23 @@ size_t CIOStreamWrapper::Write(const void *pvBuffer,
     return mFile->WriteProc(mFile, (const char *)pvBuffer, pSize, pCount);
 }
 
-// ...................................................................
+// ------------------------------------------------------------------------------------------------
 aiReturn CIOStreamWrapper::Seek(size_t pOffset,
         aiOrigin pOrigin) {
     return mFile->SeekProc(mFile, pOffset, pOrigin);
 }
 
-// ...................................................................
+// ------------------------------------------------------------------------------------------------
 size_t CIOStreamWrapper::Tell() const {
     return mFile->TellProc(mFile);
 }
 
-// ...................................................................
+// ------------------------------------------------------------------------------------------------
 size_t CIOStreamWrapper::FileSize() const {
     return mFile->FileSizeProc(mFile);
 }
 
-// ...................................................................
+// ------------------------------------------------------------------------------------------------
 void CIOStreamWrapper::Flush() {
     return mFile->FlushProc(mFile);
 }

+ 33 - 22
code/CApi/CInterfaceIOWrapper.h

@@ -47,48 +47,59 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/cfileio.h>
 #include <assimp/IOStream.hpp>
 #include <assimp/IOSystem.hpp>
+#include <assimp/ai_assert.h>
 
 namespace Assimp {
 
 class CIOSystemWrapper;
 
 // ------------------------------------------------------------------------------------------------
-// Custom IOStream implementation for the C-API
-class CIOStreamWrapper : public IOStream {
+/// @brief Custom IOStream implementation for the C-API-
+// ------------------------------------------------------------------------------------------------
+class CIOStreamWrapper final : public IOStream {
 public:
-    explicit CIOStreamWrapper(aiFile *pFile, CIOSystemWrapper *io) :
-            mFile(pFile),
-            mIO(io) {}
-    ~CIOStreamWrapper(void);
-
-    size_t Read(void *pvBuffer, size_t pSize, size_t pCount);
-    size_t Write(const void *pvBuffer, size_t pSize, size_t pCount);
-    aiReturn Seek(size_t pOffset, aiOrigin pOrigin);
-    size_t Tell(void) const;
-    size_t FileSize() const;
-    void Flush();
+    explicit CIOStreamWrapper(aiFile *pFile, CIOSystemWrapper *io);
+    ~CIOStreamWrapper() override;
+    size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;
+    size_t Write(const void *pvBuffer, size_t pSize, size_t pCount) override;
+    aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override;
+    size_t Tell(void) const override;
+    size_t FileSize() const override;
+    void Flush() override;
 
 private:
     aiFile *mFile;
     CIOSystemWrapper *mIO;
 };
 
-class CIOSystemWrapper : public IOSystem {
+inline CIOStreamWrapper::CIOStreamWrapper(aiFile *pFile, CIOSystemWrapper *io) :
+        mFile(pFile),
+        mIO(io) {
+    ai_assert(io != nullptr);
+}
+
+// ------------------------------------------------------------------------------------------------
+/// @brief Custom IO-System wrapper implementation for the C-API.
+// ------------------------------------------------------------------------------------------------
+class CIOSystemWrapper final : public IOSystem {
     friend class CIOStreamWrapper;
 
 public:
-    explicit CIOSystemWrapper(aiFileIO *pFile) :
-            mFileSystem(pFile) {}
-
-    bool Exists(const char *pFile) const;
-    char getOsSeparator() const;
-    IOStream *Open(const char *pFile, const char *pMode = "rb");
-    void Close(IOStream *pFile);
+    explicit CIOSystemWrapper(aiFileIO *pFile);
+    ~CIOSystemWrapper() override = default;
+    bool Exists(const char *pFile) const override;
+    char getOsSeparator() const override;
+    IOStream *Open(const char *pFile, const char *pMode = "rb") override;
+    void Close(IOStream *pFile) override;
 
 private:
     aiFileIO *mFileSystem;
 };
 
+inline CIOSystemWrapper::CIOSystemWrapper(aiFileIO *pFile) : mFileSystem(pFile) {
+    ai_assert(pFile != nullptr);
+}
+
 } // namespace Assimp
 
-#endif
+#endif // AI_CIOSYSTEM_H_INCLUDED

+ 71 - 1
code/CMakeLists.txt

@@ -218,6 +218,12 @@ SET( CApi_SRCS
 )
 SOURCE_GROUP(CApi FILES ${CApi_SRCS})
 
+SET(Geometry_SRCS
+  Geometry/GeometryUtils.h
+  Geometry/GeometryUtils.cpp
+)
+SOURCE_GROUP(Geometry FILES ${Geometry_SRCS})
+
 SET( STEPParser_SRCS
   AssetLib/STEPParser/STEPFileReader.h
   AssetLib/STEPParser/STEPFileReader.cpp
@@ -1129,6 +1135,7 @@ SET( assimp_src
   ${Core_SRCS}
   ${CApi_SRCS}
   ${Common_SRCS}
+  ${Geometry_SRCS}
   ${Logging_SRCS}
   ${Exporter_SRCS}
   ${PostProcessing_SRCS}
@@ -1188,7 +1195,70 @@ TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp)
 IF (ASSIMP_WARNINGS_AS_ERRORS)
   MESSAGE(STATUS "Treating all warnings as errors (for assimp library only)")
   IF (MSVC)
-    TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX)
+
+    IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
+      TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror
+        -Wno-unused-function
+        -Wno-microsoft-enum-value
+        -Wno-switch-enum
+        -Wno-covered-switch-default
+        -Wno-reserved-identifier
+        -Wno-c++98-compat-pedantic
+        -Wno-c++98-compat
+        -Wno-documentation
+        -Wno-documentation-unknown-command
+        -Wno-deprecated-dynamic-exception-spec
+        -Wno-undef
+        -Wno-suggest-destructor-override
+        -Wno-suggest-override
+        -Wno-inconsistent-missing-destructor-override
+        -Wno-zero-as-null-pointer-constant
+        -Wno-global-constructors
+        -Wno-exit-time-destructors
+        -Wno-extra-semi-stmt
+        -Wno-missing-prototypes
+        -Wno-old-style-cast
+        -Wno-cast-align
+        -Wno-cast-qual
+        -Wno-float-equal
+        -Wno-implicit-int-float-conversion
+        -Wno-sign-conversion
+        -Wno-implicit-float-conversion
+        -Wno-implicit-int-conversion
+        -Wno-float-conversion
+        -Wno-double-promotion
+        -Wno-unused-macros
+        -Wno-disabled-macro-expansion
+        -Wno-shadow-field
+        -Wno-shadow
+        -Wno-language-extension-token
+        -Wno-header-hygiene
+        -Wno-tautological-value-range-compare
+        -Wno-tautological-type-limit-compare
+        -Wno-missing-noreturn
+        -Wno-missing-variable-declarations
+        -Wno-extra-semi
+        -Wno-nonportable-system-include-path
+        -Wno-undefined-reinterpret-cast
+        -Wno-shift-sign-overflow
+        -Wno-deprecated-copy-with-user-provided-dtor
+        -Wno-deprecated-copy-with-dtor
+        -Wno-deprecated
+        -Wno-format-nonliteral
+        -Wno-format-non-iso
+        -Wno-comma
+        -Wno-unreachable-code-break
+        -Wno-unreachable-code-return
+        -Wno-unreachable-code
+        -Wno-implicit-fallthrough
+        -Wno-unused-template
+        -Wno-undefined-func-template
+        -Wno-nested-anon-types
+        -Wno-declaration-after-statement
+      )
+    ELSE()
+      TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX)
+    ENDIF()
   ELSE()
     TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror)
   ENDIF()

+ 2 - 20
code/Common/PolyTools.h

@@ -74,26 +74,8 @@ inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2) {
  *  both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
 template <typename T>
 inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp) {
-    // Point in triangle test using baryzentric coordinates
-    const aiVector2D v0 = p1 - p0;
-    const aiVector2D v1 = p2 - p0;
-    const aiVector2D v2 = pp - p0;
-
-    double dot00 = v0 * v0;
-    double dot11 = v1 * v1;
-    const double dot01 = v0 * v1;
-    const double dot02 = v0 * v2;
-    const double dot12 = v1 * v2;
-    const double denom = dot00 * dot11 - dot01 * dot01;
-    if (denom == 0.0) {
-        return false;
-    }
-
-    const double invDenom = 1.0 / denom;
-    dot11 = (dot11 * dot02 - dot01 * dot12) * invDenom;
-    dot00 = (dot00 * dot12 - dot01 * dot02) * invDenom;
-
-    return (dot11 > 0) && (dot00 > 0) && (dot11 + dot00 < 1);
+    // pp should be left side of the three triangle side, by ccw arrow
+    return OnLeftSideOfLine2D(p0, p1, pp) && OnLeftSideOfLine2D(p1, p2, pp) && OnLeftSideOfLine2D(p2, p0, pp);
 }
 
 

+ 1 - 0
code/Common/Subdivision.cpp

@@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <unordered_map>
 
 using namespace Assimp;
+
 void mydummy() {}
 
 #ifdef _MSC_VER

+ 79 - 0
code/Geometry/GeometryUtils.cpp

@@ -0,0 +1,79 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2022, 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 "GeometryUtils.h"
+
+#include <assimp/vector3.h>
+
+namespace Assimp {
+
+ai_real GeometryUtils::heron( ai_real a, ai_real b, ai_real c ) {
+    ai_real s = (a + b + c) / 2;
+    ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
+    return area;
+}
+
+ai_real GeometryUtils::distance3D( const aiVector3D &vA, aiVector3D &vB ) {
+    const ai_real lx = ( vB.x - vA.x );
+    const ai_real ly = ( vB.y - vA.y );
+    const ai_real lz = ( vB.z - vA.z );
+    ai_real a = lx*lx + ly*ly + lz*lz;
+    ai_real d = pow( a, (ai_real)0.5 );
+
+    return d;
+}
+
+ai_real GeometryUtils::calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
+    ai_real area = 0;
+
+    aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
+    aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
+    aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
+
+    ai_real a( distance3D( vA, vB ) );
+    ai_real b( distance3D( vB, vC ) );
+    ai_real c( distance3D( vC, vA ) );
+    area = heron( a, b, c );
+
+    return area;
+}
+
+} // namespace Assimp

+ 67 - 0
code/Geometry/GeometryUtils.h

@@ -0,0 +1,67 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2022, 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 <assimp/types.h>
+#include <assimp/mesh.h>
+
+namespace Assimp {
+
+// ---------------------------------------------------------------------------
+/// @brief This helper class supports some basic geometry algorithms.
+// ---------------------------------------------------------------------------
+class GeometryUtils {
+public:
+    static ai_real heron( ai_real a, ai_real b, ai_real c );
+    
+    /// @brief Will compute the distance between 2 3D-vectors
+    /// @param vA  Vector a.
+    /// @param vB  Vector b.
+    /// @return The distance.
+    static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB );
+
+    /// @brief Will calculate the area of a triangle described by a aiFace.
+    /// @param face   The face
+    /// @param mesh   The mesh containing the face
+    /// @return The area.
+    static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh );
+};
+
+} // namespace Assimp

+ 0 - 4
code/PostProcessing/CalcTangentsProcess.cpp

@@ -60,10 +60,6 @@ CalcTangentsProcess::CalcTangentsProcess() :
     // nothing to do here
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-CalcTangentsProcess::~CalcTangentsProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool CalcTangentsProcess::IsActive(unsigned int pFlags) const {

+ 6 - 13
code/PostProcessing/CalcTangentsProcess.h

@@ -59,14 +59,11 @@ namespace Assimp
  * because the joining of vertices also considers tangents and bitangents for
  * uniqueness.
  */
-class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess
-{
+class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess {
 public:
-
     CalcTangentsProcess();
-    ~CalcTangentsProcess();
+    ~CalcTangentsProcess() override = default;
 
-public:
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag.
     * @param pFlags The processing flags the importer was called with.
@@ -74,24 +71,21 @@ public:
     * @return true if the process is present in this flag fields,
     *   false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Called prior to ExecuteOnScene().
     * The function is a request to the process to update its configuration
     * basing on the Importer's configuration property list.
     */
-    void SetupProperties(const Importer* pImp);
-
+    void SetupProperties(const Importer* pImp) override;
 
     // setter for configMaxAngle
-    inline void SetMaxSmoothAngle(float f)
-    {
+    void SetMaxSmoothAngle(float f) {
         configMaxAngle =f;
     }
 
 protected:
-
     // -------------------------------------------------------------------
     /** Calculates tangents and bitangents for a specific mesh.
     * @param pMesh The mesh to process.
@@ -103,10 +97,9 @@ protected:
     /** Executes the post processing step on the given imported data.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
 private:
-
     /** Configuration option: maximum smoothing angle, in radians*/
     float configMaxAngle;
     unsigned int configSourceUV;

+ 0 - 8
code/PostProcessing/ComputeUVMappingProcess.cpp

@@ -57,14 +57,6 @@ namespace {
     const static ai_real angle_epsilon = ai_real( 0.95 );
 }
 
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ComputeUVMappingProcess::ComputeUVMappingProcess() = default;
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ComputeUVMappingProcess::~ComputeUVMappingProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const

+ 7 - 12
code/PostProcessing/ComputeUVMappingProcess.h

@@ -59,13 +59,10 @@ namespace Assimp {
 /** ComputeUVMappingProcess - converts special mappings, such as spherical,
  *  cylindrical or boxed to proper UV coordinates for rendering.
 */
-class ComputeUVMappingProcess : public BaseProcess
-{
-public:
-    ComputeUVMappingProcess();
-    ~ComputeUVMappingProcess();
-
+class ComputeUVMappingProcess : public BaseProcess {
 public:
+    ComputeUVMappingProcess() = default;
+    ~ComputeUVMappingProcess() override = default;
 
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag field.
@@ -73,14 +70,14 @@ public:
     *   combination of #aiPostProcessSteps.
     * @return true if the process is present in this flag fields, false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
 protected:
 
@@ -125,8 +122,7 @@ protected:
 private:
 
     // temporary structure to describe a mapping
-    struct MappingInfo
-    {
+    struct MappingInfo {
         explicit MappingInfo(aiTextureMapping _type)
             : type  (_type)
             , axis  (0.f,1.f,0.f)
@@ -137,8 +133,7 @@ private:
         aiVector3D axis;
         unsigned int uv;
 
-        bool operator== (const MappingInfo& other)
-        {
+        bool operator== (const MappingInfo& other) {
             return type == other.type && axis == other.axis;
         }
     };

+ 0 - 16
code/PostProcessing/ConvertToLHProcess.cpp

@@ -79,14 +79,6 @@ void flipUVs(aiMeshType *pMesh) {
 
 } // namespace
 
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MakeLeftHandedProcess::MakeLeftHandedProcess() = default;
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MakeLeftHandedProcess::~MakeLeftHandedProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool MakeLeftHandedProcess::IsActive(unsigned int pFlags) const {
@@ -305,14 +297,6 @@ void FlipUVsProcess::ProcessMesh(aiMesh *pMesh) {
 #ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
 // # FlipWindingOrderProcess
 
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FlipWindingOrderProcess::FlipWindingOrderProcess() = default;
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FlipWindingOrderProcess::~FlipWindingOrderProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool FlipWindingOrderProcess::IsActive(unsigned int pFlags) const {

+ 10 - 17
code/PostProcessing/ConvertToLHProcess.h

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2022, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -72,22 +71,18 @@ namespace Assimp    {
  *
  * @note RH-LH and LH-RH is the same, so this class can be used for both
  */
-class MakeLeftHandedProcess : public BaseProcess
-{
-
-
+class MakeLeftHandedProcess : public BaseProcess {
 public:
-    MakeLeftHandedProcess();
-    ~MakeLeftHandedProcess();
+    MakeLeftHandedProcess() = default;
+    ~MakeLeftHandedProcess() override = default;
 
     // -------------------------------------------------------------------
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
 protected:
-
     // -------------------------------------------------------------------
     /** Recursively converts a node and all of its children
      */
@@ -120,24 +115,22 @@ protected:
 // ---------------------------------------------------------------------------
 /** Postprocessing step to flip the face order of the imported data
  */
-class FlipWindingOrderProcess : public BaseProcess
-{
+class FlipWindingOrderProcess : public BaseProcess {
     friend class Importer;
 
 public:
     /** Constructor to be privately used by Importer */
-    FlipWindingOrderProcess();
+    FlipWindingOrderProcess() = default;
 
     /** Destructor, private as well */
-    ~FlipWindingOrderProcess();
+    ~FlipWindingOrderProcess() override = default;
 
     // -------------------------------------------------------------------
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
-public:
     /** Some other types of post-processing require winding order flips */
     static void ProcessMesh( aiMesh* pMesh);
 };

+ 28 - 51
code/PostProcessing/DeboneProcess.cpp

@@ -43,42 +43,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /// @file DeboneProcess.cpp
 /** Implementation of the DeboneProcess post processing step */
 
-
-
 // internal headers of the post-processing framework
 #include "ProcessHelper.h"
 #include "DeboneProcess.h"
 #include <stdio.h>
 
-
 using namespace Assimp;
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-DeboneProcess::DeboneProcess()
-{
-    mNumBones = 0;
-    mNumBonesCanDoWithout = 0;
-
-    mThreshold = AI_DEBONE_THRESHOLD;
-    mAllOrNone = false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-DeboneProcess::~DeboneProcess() = default;
+DeboneProcess::DeboneProcess() : mNumBones(0), mNumBonesCanDoWithout(0), mThreshold(AI_DEBONE_THRESHOLD), mAllOrNone(false) {}
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
-bool DeboneProcess::IsActive( unsigned int pFlags) const
-{
+bool DeboneProcess::IsActive( unsigned int pFlags) const {
     return (pFlags & aiProcess_Debone) != 0;
 }
 
 // ------------------------------------------------------------------------------------------------
 // Executes the post processing step on the given imported data.
-void DeboneProcess::SetupProperties(const Importer* pImp)
-{
+void DeboneProcess::SetupProperties(const Importer* pImp) {
     // get the current value of the property
     mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false;
     mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD);
@@ -86,8 +70,7 @@ void DeboneProcess::SetupProperties(const Importer* pImp)
 
 // ------------------------------------------------------------------------------------------------
 // Executes the post processing step on the given imported data.
-void DeboneProcess::Execute( aiScene* pScene)
-{
+void DeboneProcess::Execute( aiScene* pScene) {
     ASSIMP_LOG_DEBUG("DeboneProcess begin");
 
     if(!pScene->mNumMeshes) {
@@ -117,10 +100,8 @@ void DeboneProcess::Execute( aiScene* pScene)
         // build a new array of meshes for the scene
         std::vector<aiMesh*> meshes;
 
-        for(unsigned int a=0;a<pScene->mNumMeshes;a++)
-        {
+        for (unsigned int a=0;a<pScene->mNumMeshes; ++a) {
             aiMesh* srcMesh = pScene->mMeshes[a];
-
             std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes;
 
             if(splitList[a]) {
@@ -150,8 +131,7 @@ void DeboneProcess::Execute( aiScene* pScene)
 
                 // and destroy the source mesh. It should be completely contained inside the new submeshes
                 delete srcMesh;
-            }
-            else    {
+            } else {
                 // Mesh is kept unchanged - store it's new place in the mesh array
                 mSubMeshIndices[a].emplace_back(static_cast<unsigned int>(meshes.size()), (aiNode *)nullptr);
                 meshes.push_back(srcMesh);
@@ -173,8 +153,7 @@ void DeboneProcess::Execute( aiScene* pScene)
 
 // ------------------------------------------------------------------------------------------------
 // Counts bones total/removable in a given mesh.
-bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
-{
+bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh) {
     if(!pMesh->HasBones()) {
         return false;
     }
@@ -193,25 +172,23 @@ bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
     for(unsigned int i=0;i<pMesh->mNumBones;i++)    {
         for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++)   {
             float w = pMesh->mBones[i]->mWeights[j].mWeight;
-
-            if(w==0.0f) {
+            if (w == 0.0f) {
                 continue;
             }
 
             unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
-            if(w>=mThreshold)   {
-
-                if(vertexBones[vid]!=cUnowned)  {
-                    if(vertexBones[vid]==i) //double entry
-                    {
+            if (w >= mThreshold)   {
+                if (vertexBones[vid] != cUnowned) {
+                    //double entry
+                    if(vertexBones[vid]==i)  {
                         ASSIMP_LOG_WARN("Encountered double entry in bone weights");
-                    }
-                    else //TODO: track attraction in order to break tie
-                    {
+                    } else  {
+                        //TODO: track attraction in order to break tie
                         vertexBones[vid] = cCoowned;
                     }
-                }
-                else vertexBones[vid] = i;
+                } else {
+                    vertexBones[vid] = i;
+                } 
             }
 
             if(!isBoneNecessary[i]) {
@@ -227,13 +204,16 @@ bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
     if(isInterstitialRequired) {
         for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
             unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
-
-            for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
+            for (unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
                 unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
 
-                if(v!=w)    {
-                    if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
-                    if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
+                if (v != w) {
+                    if(v<pMesh->mNumBones) {
+                        isBoneNecessary[v] = true;
+                    }
+                    if (w<pMesh->mNumBones) {
+                        isBoneNecessary[w] = true;
+                    }
                 }
             }
         }
@@ -252,8 +232,7 @@ bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
 
 // ------------------------------------------------------------------------------------------------
 // Splits the given mesh by bone count.
-void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const
-{
+void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const {
     // same deal here as ConsiderMesh basically
 
     std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
@@ -371,8 +350,7 @@ void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMe
 
 // ------------------------------------------------------------------------------------------------
 // Recursively updates the node's mesh list to account for the changed mesh list
-void DeboneProcess::UpdateNode(aiNode* pNode) const
-{
+void DeboneProcess::UpdateNode(aiNode* pNode) const {
     // rebuild the node's mesh index list
 
     std::vector<unsigned int> newMeshList;
@@ -430,8 +408,7 @@ void DeboneProcess::UpdateNode(aiNode* pNode) const
 
 // ------------------------------------------------------------------------------------------------
 // Apply the node transformation to a mesh
-void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const
-{
+void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const {
     // Check whether we need to transform the coordinates at all
     if (!mat.IsIdentity()) {
 

+ 4 - 4
code/PostProcessing/DeboneProcess.h

@@ -70,7 +70,7 @@ namespace Assimp {
 class DeboneProcess : public BaseProcess {
 public:
     DeboneProcess();
-    ~DeboneProcess();
+    ~DeboneProcess() override = default;
 
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag.
@@ -79,14 +79,14 @@ public:
     * @return true if the process is present in this flag fields,
     *   false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Called prior to ExecuteOnScene().
     * The function is a request to the process to update its configuration
     * basing on the Importer's configuration property list.
     */
-    void SetupProperties(const Importer* pImp);
+    void SetupProperties(const Importer* pImp) override;
 
 protected:
     // -------------------------------------------------------------------
@@ -94,7 +94,7 @@ protected:
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
     /** Counts bones total/removable in a given mesh.

+ 0 - 8
code/PostProcessing/DropFaceNormalsProcess.cpp

@@ -54,14 +54,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 using namespace Assimp;
 
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-DropFaceNormalsProcess::DropFaceNormalsProcess() = default;
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-DropFaceNormalsProcess::~DropFaceNormalsProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool DropFaceNormalsProcess::IsActive( unsigned int pFlags) const {

+ 4 - 5
code/PostProcessing/DropFaceNormalsProcess.h

@@ -55,8 +55,8 @@ namespace Assimp {
 */
 class ASSIMP_API_WINONLY DropFaceNormalsProcess : public BaseProcess {
 public:
-    DropFaceNormalsProcess();
-    ~DropFaceNormalsProcess();
+    DropFaceNormalsProcess() = default;
+    ~DropFaceNormalsProcess() override = default;
 
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag field.
@@ -64,15 +64,14 @@ public:
     *   combination of #aiPostProcessSteps.
     * @return true if the process is present in this flag fields, false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
-
+    void Execute( aiScene* pScene) override;
 
 private:
     bool DropMeshFaceNormals(aiMesh* pcMesh);

+ 0 - 4
code/PostProcessing/EmbedTexturesProcess.cpp

@@ -49,10 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 using namespace Assimp;
 
-EmbedTexturesProcess::EmbedTexturesProcess() = default;
-
-EmbedTexturesProcess::~EmbedTexturesProcess() = default;
-
 bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const {
     return (pFlags & aiProcess_EmbedTextures) != 0;
 }

+ 5 - 5
code/PostProcessing/EmbedTexturesProcess.h

@@ -62,19 +62,19 @@ namespace Assimp {
 class ASSIMP_API EmbedTexturesProcess : public BaseProcess {
 public:
     /// The default class constructor.
-    EmbedTexturesProcess();
+    EmbedTexturesProcess() = default;
 
     /// The class destructor.
-    virtual ~EmbedTexturesProcess();
+    ~EmbedTexturesProcess() override = default;
 
     /// Overwritten, @see BaseProcess
-    virtual bool IsActive(unsigned int pFlags) const;
+    bool IsActive(unsigned int pFlags) const override;
 
     /// Overwritten, @see BaseProcess
-    virtual void SetupProperties(const Importer* pImp);
+    void SetupProperties(const Importer* pImp) override;
 
     /// Overwritten, @see BaseProcess
-    virtual void Execute(aiScene* pScene);
+    virtual void Execute(aiScene* pScene) override;
 
 private:
     // Resolve the path and add the file content to the scene as a texture.

+ 2 - 36
code/PostProcessing/FindDegenerates.cpp

@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "ProcessHelper.h"
 #include "FindDegenerates.h"
+#include "Geometry/GeometryUtils.h"
 
 #include <assimp/Exceptional.h>
 
@@ -63,10 +64,6 @@ FindDegeneratesProcess::FindDegeneratesProcess() :
     // empty
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FindDegeneratesProcess::~FindDegeneratesProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const {
@@ -132,37 +129,6 @@ static void updateSceneGraph(aiNode* pNode, const std::unordered_map<unsigned in
     }
 }
 
-static ai_real heron( ai_real a, ai_real b, ai_real c ) {
-    ai_real s = (a + b + c) / 2;
-    ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
-    return area;
-}
-
-static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB ) {
-    const ai_real lx = ( vB.x - vA.x );
-    const ai_real ly = ( vB.y - vA.y );
-    const ai_real lz = ( vB.z - vA.z );
-    ai_real a = lx*lx + ly*ly + lz*lz;
-    ai_real d = pow( a, (ai_real)0.5 );
-
-    return d;
-}
-
-static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
-    ai_real area = 0;
-
-    aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
-    aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
-    aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
-
-    ai_real a( distance3D( vA, vB ) );
-    ai_real b( distance3D( vB, vC ) );
-    ai_real c( distance3D( vC, vA ) );
-    area = heron( a, b, c );
-
-    return area;
-}
-
 // ------------------------------------------------------------------------------------------------
 // Executes the post processing step on the given imported mesh
 bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
@@ -218,7 +184,7 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
 
             if ( mConfigCheckAreaOfTriangle ) {
                 if ( face.mNumIndices == 3 ) {
-                    ai_real area = calculateAreaOfTriangle( face, mesh );
+                    ai_real area = GeometryUtils::calculateAreaOfTriangle( face, mesh );
                     if (area < ai_epsilon) {
                         if ( mConfigRemoveDegenerates ) {
                             remove_me[ a ] = true;

+ 8 - 12
code/PostProcessing/FindDegenerates.h

@@ -59,19 +59,19 @@ namespace Assimp    {
 class ASSIMP_API FindDegeneratesProcess : public BaseProcess {
 public:
     FindDegeneratesProcess();
-    ~FindDegeneratesProcess();
+    ~FindDegeneratesProcess() override = default;
 
     // -------------------------------------------------------------------
     // Check whether step is active
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     // Execute step on a given scene
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
     // Setup import settings
-    void SetupProperties(const Importer* pImp);
+    void SetupProperties(const Importer* pImp) override;
 
     // -------------------------------------------------------------------
     // Execute step on a given mesh
@@ -105,23 +105,19 @@ private:
     bool mConfigCheckAreaOfTriangle;
 };
 
-inline
-void FindDegeneratesProcess::EnableInstantRemoval(bool enabled) {
+inline void FindDegeneratesProcess::EnableInstantRemoval(bool enabled) {
     mConfigRemoveDegenerates = enabled;
 }
 
-inline
-bool FindDegeneratesProcess::IsInstantRemoval() const {
+inline bool FindDegeneratesProcess::IsInstantRemoval() const {
     return mConfigRemoveDegenerates;
 }
 
-inline
-void FindDegeneratesProcess::EnableAreaCheck( bool enabled ) {
+inline void FindDegeneratesProcess::EnableAreaCheck( bool enabled ) {
     mConfigCheckAreaOfTriangle = enabled;
 }
 
-inline
-bool FindDegeneratesProcess::isAreaCheckEnabled() const {
+inline bool FindDegeneratesProcess::isAreaCheckEnabled() const {
     return mConfigCheckAreaOfTriangle;
 }
 

+ 0 - 4
code/PostProcessing/FindInstancesProcess.cpp

@@ -58,10 +58,6 @@ FindInstancesProcess::FindInstancesProcess()
 :   configSpeedFlag (false)
 {}
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FindInstancesProcess::~FindInstancesProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool FindInstancesProcess::IsActive( unsigned int pFlags) const

+ 10 - 15
code/PostProcessing/FindInstancesProcess.h

@@ -50,7 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "PostProcessing/ProcessHelper.h"
 
 class FindInstancesProcessTest;
-namespace Assimp    {
+
+namespace Assimp {
 
 // -------------------------------------------------------------------------------
 /** @brief Get a pseudo(!)-hash representing a mesh.
@@ -60,8 +61,7 @@ namespace Assimp    {
  *  @param in Input mesh
  *  @return Hash.
  */
-inline
-uint64_t GetMeshHash(aiMesh* in) {
+inline uint64_t GetMeshHash(aiMesh* in) {
     ai_assert(nullptr != in);
 
     // ... get an unique value representing the vertex format of the mesh
@@ -83,8 +83,7 @@ uint64_t GetMeshHash(aiMesh* in) {
  *  @param e Epsilon
  *  @return true if the arrays are identical
  */
-inline
-bool CompareArrays(const aiVector3D* first, const aiVector3D* second,
+inline bool CompareArrays(const aiVector3D* first, const aiVector3D* second,
         unsigned int size, float e) {
     for (const aiVector3D* end = first+size; first != end; ++first,++second) {
         if ( (*first - *second).SquareLength() >= e)
@@ -107,31 +106,27 @@ inline bool CompareArrays(const aiColor4D* first, const aiColor4D* second,
 // ---------------------------------------------------------------------------
 /** @brief A post-processing steps to search for instanced meshes
 */
-class FindInstancesProcess : public BaseProcess
-{
+class FindInstancesProcess : public BaseProcess {
 public:
-
     FindInstancesProcess();
-    ~FindInstancesProcess();
+    ~FindInstancesProcess() override = default;
 
-public:
     // -------------------------------------------------------------------
     // Check whether step is active in given flags combination
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     // Execute step on a given scene
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
     // Setup properties prior to executing the process
-    void SetupProperties(const Importer* pImp);
+    void SetupProperties(const Importer* pImp) override;
 
 private:
-
     bool configSpeedFlag;
-
 }; // ! end class FindInstancesProcess
+
 }  // ! end namespace Assimp
 
 #endif // !! AI_FINDINSTANCES_H_INC

+ 0 - 4
code/PostProcessing/FindInvalidDataProcess.cpp

@@ -60,10 +60,6 @@ FindInvalidDataProcess::FindInvalidDataProcess() :
     // nothing to do here
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FindInvalidDataProcess::~FindInvalidDataProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool FindInvalidDataProcess::IsActive(unsigned int pFlags) const {

+ 16 - 14
code/PostProcessing/FindInvalidDataProcess.h

@@ -64,35 +64,37 @@ namespace Assimp {
  *  which have zero normal vectors. */
 class ASSIMP_API FindInvalidDataProcess : public BaseProcess {
 public:
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     FindInvalidDataProcess();
-    ~FindInvalidDataProcess();
+    ~FindInvalidDataProcess() override = default;
 
     // -------------------------------------------------------------------
-    //
-    bool IsActive(unsigned int pFlags) const;
+    /// Returns active state.
+    bool IsActive(unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
-    // Setup import settings
-    void SetupProperties(const Importer *pImp);
+    /// Setup import settings
+    void SetupProperties(const Importer *pImp) override;
 
     // -------------------------------------------------------------------
-    // Run the step
-    void Execute(aiScene *pScene);
+    /// Run the step
+    void Execute(aiScene *pScene) override;
 
     // -------------------------------------------------------------------
-    /** Executes the post-processing step on the given mesh
-     * @param pMesh The mesh to process.
-     * @return 0 - nothing, 1 - removed sth, 2 - please delete me  */
+    /// Executes the post-processing step on the given mesh
+    /// @param pMesh The mesh to process.
+    /// @return 0 - nothing, 1 - removed sth, 2 - please delete me  */
     int ProcessMesh(aiMesh *pMesh);
 
     // -------------------------------------------------------------------
-    /** Executes the post-processing step on the given animation
-     * @param anim The animation to process.  */
+    /// Executes the post-processing step on the given animation
+    /// @param anim The animation to process.  */
     void ProcessAnimation(aiAnimation *anim);
 
     // -------------------------------------------------------------------
-    /** Executes the post-processing step on the given anim channel
-     * @param anim The animation channel to process.*/
+    /// Executes the post-processing step on the given anim channel
+    /// @param anim The animation channel to process.*/
     void ProcessAnimationChannel(aiNodeAnim *anim);
 
 private:

+ 2 - 13
code/PostProcessing/FixNormalsStep.cpp

@@ -56,26 +56,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 using namespace Assimp;
 
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FixInfacingNormalsProcess::FixInfacingNormalsProcess() = default;
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FixInfacingNormalsProcess::~FixInfacingNormalsProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
-bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const
-{
+bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const {
     return (pFlags & aiProcess_FixInfacingNormals) != 0;
 }
 
 // ------------------------------------------------------------------------------------------------
 // Executes the post processing step on the given imported data.
-void FixInfacingNormalsProcess::Execute( aiScene* pScene)
-{
+void FixInfacingNormalsProcess::Execute( aiScene* pScene) {
     ASSIMP_LOG_DEBUG("FixInfacingNormalsProcess begin");
 
     bool bHas( false );

+ 7 - 6
code/PostProcessing/FixNormalsStep.h

@@ -49,8 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 struct aiMesh;
 
-namespace Assimp
-{
+namespace Assimp {
 
 // ---------------------------------------------------------------------------
 /** The FixInfacingNormalsProcess tries to determine whether the normal
@@ -59,8 +58,10 @@ namespace Assimp
  */
 class FixInfacingNormalsProcess : public BaseProcess {
 public:
-    FixInfacingNormalsProcess();
-    ~FixInfacingNormalsProcess();
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
+    FixInfacingNormalsProcess() = default;
+    ~FixInfacingNormalsProcess() override = default;
 
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag field.
@@ -68,14 +69,14 @@ public:
      *   combination of #aiPostProcessSteps.
      * @return true if the process is present in this flag fields, false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
 protected:
 

+ 0 - 4
code/PostProcessing/GenBoundingBoxesProcess.cpp

@@ -48,10 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 namespace Assimp {
 
-GenBoundingBoxesProcess::GenBoundingBoxesProcess() = default;
-
-GenBoundingBoxesProcess::~GenBoundingBoxesProcess() = default;
-
 bool GenBoundingBoxesProcess::IsActive(unsigned int pFlags) const {
     return 0 != ( pFlags & aiProcess_GenBoundingBoxes );
 }

+ 14 - 9
code/PostProcessing/GenBoundingBoxesProcess.h

@@ -19,7 +19,7 @@ conditions are met:
   copyright notice, this list of conditions and the
   following disclaimer in the documentation and/or other
   materials provided with the distribution.
-
+s
 * 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
@@ -54,18 +54,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 namespace Assimp {
 
-/** Post-processing process to find axis-aligned bounding volumes for amm meshes
- *  used in a scene
+/** 
+ * @brief Post-processing process to find axis-aligned bounding volumes for amm meshes
+ *        used in a scene.
  */
 class ASSIMP_API GenBoundingBoxesProcess : public BaseProcess {
 public:
-    /// The class constructor.
-    GenBoundingBoxesProcess();
-    /// The class destructor.
-    ~GenBoundingBoxesProcess();
-    /// Will return true, if aiProcess_GenBoundingBoxes is defined.
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
+    GenBoundingBoxesProcess() = default;
+    ~GenBoundingBoxesProcess() override = default;
+
+    // -------------------------------------------------------------------
+    /// @brief Will return true, if aiProcess_GenBoundingBoxes is defined.
     bool IsActive(unsigned int pFlags) const override;
-    /// The execution callback.
+
+    // -------------------------------------------------------------------
+    /// @brief The execution callback.
     void Execute(aiScene* pScene) override;
 };
 

+ 0 - 8
code/PostProcessing/GenFaceNormalsProcess.cpp

@@ -54,14 +54,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 using namespace Assimp;
 
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-GenFaceNormalsProcess::GenFaceNormalsProcess() = default;
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-GenFaceNormalsProcess::~GenFaceNormalsProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const {

+ 11 - 13
code/PostProcessing/GenFaceNormalsProcess.h

@@ -47,35 +47,33 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "Common/BaseProcess.h"
 #include <assimp/mesh.h>
 
-namespace Assimp
-{
+namespace Assimp {
 
 // ---------------------------------------------------------------------------
-/** The GenFaceNormalsProcess computes face normals for all faces of all meshes
-*/
-class ASSIMP_API_WINONLY GenFaceNormalsProcess : public BaseProcess
-{
+/** 
+ * @brief The GenFaceNormalsProcess computes face normals for all faces of all meshes
+ */
+class ASSIMP_API_WINONLY GenFaceNormalsProcess : public BaseProcess {
 public:
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
+    GenFaceNormalsProcess() = default;
+    ~GenFaceNormalsProcess() override = default;
 
-    GenFaceNormalsProcess();
-    ~GenFaceNormalsProcess();
-
-public:
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag field.
     * @param pFlags The processing flags the importer was called with. A bitwise
     *   combination of #aiPostProcessSteps.
     * @return true if the process is present in this flag fields, false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
-
+    void Execute( aiScene* pScene) override;
 
 private:
     bool GenMeshFaceNormals(aiMesh* pcMesh);

+ 5 - 8
code/PostProcessing/GenVertexNormalsProcess.cpp

@@ -60,10 +60,6 @@ GenVertexNormalsProcess::GenVertexNormalsProcess() :
     // empty
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-GenVertexNormalsProcess::~GenVertexNormalsProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const {
@@ -109,10 +105,10 @@ void GenVertexNormalsProcess::Execute(aiScene *pScene) {
 // Executes the post processing step on the given imported data.
 bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int meshIndex) {
     if (nullptr != pMesh->mNormals) {
-        if (force_)
-            delete[] pMesh->mNormals;
-        else
+        if (!force_) {
             return false;
+        }
+        delete[] pMesh->mNormals;
     }
 
     // If the mesh consists of lines and/or points but not of
@@ -144,8 +140,9 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int m
         const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]];
         // Boolean XOR - if either but not both of these flags is set, then the winding order has
         // changed and the cross product to calculate the normal needs to be reversed
-        if (flippedWindingOrder_ != leftHanded_)
+        if (flippedWindingOrder_ != leftHanded_) {
             std::swap(pV2, pV3);
+        }
         const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
 
         for (unsigned int i = 0; i < face.mNumIndices; ++i) {

+ 6 - 5
code/PostProcessing/GenVertexNormalsProcess.h

@@ -60,8 +60,10 @@ namespace Assimp {
 */
 class ASSIMP_API GenVertexNormalsProcess : public BaseProcess {
 public:
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     GenVertexNormalsProcess();
-    ~GenVertexNormalsProcess();
+    ~GenVertexNormalsProcess() override = default;
 
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag.
@@ -70,22 +72,21 @@ public:
     * @return true if the process is present in this flag fields,
     *   false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Called prior to ExecuteOnScene().
     * The function is a request to the process to update its configuration
     * basing on the Importer's configuration property list.
     */
-    void SetupProperties(const Importer* pImp);
+    void SetupProperties(const Importer* pImp) override;
 
     // -------------------------------------------------------------------
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
-
+    void Execute( aiScene* pScene) override;
 
     // setter for configMaxAngle
     inline void SetMaxSmoothAngle(ai_real f) {

+ 0 - 4
code/PostProcessing/ImproveCacheLocality.cpp

@@ -68,10 +68,6 @@ ImproveCacheLocalityProcess::ImproveCacheLocalityProcess()
     // empty
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ImproveCacheLocalityProcess::~ImproveCacheLocalityProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const {

+ 8 - 11
code/PostProcessing/ImproveCacheLocality.h

@@ -51,8 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 struct aiMesh;
 
-namespace Assimp
-{
+namespace Assimp {
 
 // ---------------------------------------------------------------------------
 /** The ImproveCacheLocalityProcess reorders all faces for improved vertex
@@ -61,26 +60,24 @@ namespace Assimp
  *
  *  @note This step expects triagulated input data.
  */
-class ImproveCacheLocalityProcess : public BaseProcess
-{
+class ImproveCacheLocalityProcess : public BaseProcess {
 public:
-
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     ImproveCacheLocalityProcess();
-    ~ImproveCacheLocalityProcess();
-
-public:
+    ~ImproveCacheLocalityProcess() override = default;
 
     // -------------------------------------------------------------------
     // Check whether the pp step is active
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     // Executes the pp step on a given scene
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
     // Configures the pp step
-    void SetupProperties(const Importer* pImp);
+    void SetupProperties(const Importer* pImp) override;
 
 protected:
     // -------------------------------------------------------------------

+ 6 - 10
code/PostProcessing/JoinVerticesProcess.h

@@ -51,8 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 struct aiMesh;
 
-namespace Assimp
-{
+namespace Assimp {
 
 // ---------------------------------------------------------------------------
 /** The JoinVerticesProcess unites identical vertices in all imported meshes.
@@ -65,12 +64,9 @@ namespace Assimp
 class ASSIMP_API JoinVerticesProcess : public BaseProcess {
 public:
     // -------------------------------------------------------------------
-    /// @brief  The default class constructor.
-    JoinVerticesProcess() = default;
-    
-    // -------------------------------------------------------------------
-    /// @brief  The default class destructor.
-    ~JoinVerticesProcess() = default;
+    /// The default class constructor / destructor.
+    JoinVerticesProcess() = default;    
+    ~JoinVerticesProcess() override = default;
 
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag field.
@@ -78,14 +74,14 @@ public:
      *   combination of #aiPostProcessSteps.
      * @return true if the process is present in this flag fields, false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
     /** Unites identical vertices in the given mesh.

+ 3 - 5
code/PostProcessing/LimitBoneWeightsProcess.cpp

@@ -53,11 +53,9 @@ namespace Assimp {
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-LimitBoneWeightsProcess::LimitBoneWeightsProcess() : mMaxWeights(AI_LMW_MAX_WEIGHTS) {}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-LimitBoneWeightsProcess::~LimitBoneWeightsProcess() = default;
+LimitBoneWeightsProcess::LimitBoneWeightsProcess() : mMaxWeights(AI_LMW_MAX_WEIGHTS) {
+    // empty
+}
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.

+ 12 - 10
code/PostProcessing/LimitBoneWeightsProcess.h

@@ -74,8 +74,10 @@ namespace Assimp {
 */
 class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess {
 public:
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     LimitBoneWeightsProcess();
-    ~LimitBoneWeightsProcess();
+    ~LimitBoneWeightsProcess() override = default;
 
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag.
@@ -84,27 +86,27 @@ public:
     * @return true if the process is present in this flag fields,
     *   false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Called prior to ExecuteOnScene().
     * The function is a request to the process to update its configuration
     * basing on the Importer's configuration property list.
     */
-    void SetupProperties(const Importer* pImp);
-
-    // -------------------------------------------------------------------
-    /** Limits the bone weight count for all vertices in the given mesh.
-    * @param pMesh The mesh to process.
-    */
-    void ProcessMesh( aiMesh* pMesh);
+    void SetupProperties(const Importer* pImp) override;
 
     // -------------------------------------------------------------------
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
+
+    // -------------------------------------------------------------------
+    /** Limits the bone weight count for all vertices in the given mesh.
+    * @param pMesh The mesh to process.
+    */
+    void ProcessMesh( aiMesh* pMesh);
 
     // -------------------------------------------------------------------
     /** Describes a bone weight on a vertex */

+ 0 - 4
code/PostProcessing/MakeVerboseFormat.cpp

@@ -49,10 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 using namespace Assimp;
 
-// ------------------------------------------------------------------------------------------------
-MakeVerboseFormatProcess::MakeVerboseFormatProcess() = default;
-// ------------------------------------------------------------------------------------------------
-MakeVerboseFormatProcess::~MakeVerboseFormatProcess() = default;
 // ------------------------------------------------------------------------------------------------
 // Executes the post processing step on the given imported data.
 void MakeVerboseFormatProcess::Execute(aiScene *pScene) {

+ 7 - 10
code/PostProcessing/MakeVerboseFormat.h

@@ -66,22 +66,19 @@ namespace Assimp    {
  * The step has been added because it was required by the viewer, however
  * it has been moved to the main library since others might find it
  * useful, too. */
-class ASSIMP_API_WINONLY MakeVerboseFormatProcess : public BaseProcess
-{
-public:
-
-
-    MakeVerboseFormatProcess();
-    ~MakeVerboseFormatProcess();
-
+class ASSIMP_API_WINONLY MakeVerboseFormatProcess : public BaseProcess {
 public:
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
+    MakeVerboseFormatProcess() = default;
+    ~MakeVerboseFormatProcess() override = default;
 
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag field.
     * @param pFlags The processing flags the importer was called with. A bitwise
     *   combination of #aiPostProcessSteps.
     * @return true if the process is present in this flag fields, false if not */
-    bool IsActive( unsigned int /*pFlags*/ ) const
+    bool IsActive( unsigned int /*pFlags*/ ) const  override
     {
         // NOTE: There is no direct flag that corresponds to
         // this postprocess step.
@@ -92,7 +89,7 @@ public:
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at. */
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
 public:
 

+ 0 - 4
code/PostProcessing/OptimizeGraph.cpp

@@ -78,10 +78,6 @@ OptimizeGraphProcess::OptimizeGraphProcess() :
 	// empty
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-OptimizeGraphProcess::~OptimizeGraphProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool OptimizeGraphProcess::IsActive(unsigned int pFlags) const {

+ 3 - 1
code/PostProcessing/OptimizeGraph.h

@@ -71,8 +71,10 @@ namespace Assimp    {
  */
 class OptimizeGraphProcess : public BaseProcess {
 public:
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     OptimizeGraphProcess();
-    ~OptimizeGraphProcess();
+    ~OptimizeGraphProcess() override = default;
 
     // -------------------------------------------------------------------
     bool IsActive( unsigned int pFlags) const override;

+ 0 - 4
code/PostProcessing/OptimizeMeshes.cpp

@@ -69,10 +69,6 @@ OptimizeMeshesProcess::OptimizeMeshesProcess()
     // empty
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-OptimizeMeshesProcess::~OptimizeMeshesProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool OptimizeMeshesProcess::IsActive( unsigned int pFlags) const

+ 6 - 9
code/PostProcessing/OptimizeMeshes.h

@@ -68,11 +68,10 @@ namespace Assimp    {
  */
 class OptimizeMeshesProcess : public BaseProcess {
 public:
-    /// @brief  The class constructor.
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     OptimizeMeshesProcess();
-
-    /// @brief  The class destructor.
-    ~OptimizeMeshesProcess();
+    ~OptimizeMeshesProcess() override = default;
 
     /** @brief Internal utility to store additional mesh info
      */
@@ -94,16 +93,14 @@ public:
         unsigned int output_id;
     };
 
-public:
     // -------------------------------------------------------------------
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
-    void SetupProperties(const Importer* pImp);
-
+    void SetupProperties(const Importer* pImp) override;
 
     // -------------------------------------------------------------------
     /** @brief Specify whether you want meshes with different

+ 0 - 4
code/PostProcessing/PretransformVertices.cpp

@@ -68,10 +68,6 @@ PretransformVertices::PretransformVertices() :
 	// empty
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-PretransformVertices::~PretransformVertices() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool PretransformVertices::IsActive(unsigned int pFlags) const {

+ 3 - 1
code/PostProcessing/PretransformVertices.h

@@ -68,8 +68,10 @@ namespace Assimp {
 */
 class ASSIMP_API PretransformVertices : public BaseProcess {
 public:
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
 	PretransformVertices();
-	~PretransformVertices();
+	~PretransformVertices() override = default;
 
 	// -------------------------------------------------------------------
 	// Check whether step is active

+ 0 - 4
code/PostProcessing/RemoveRedundantMaterials.cpp

@@ -62,10 +62,6 @@ RemoveRedundantMatsProcess::RemoveRedundantMatsProcess()
     // nothing to do here
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-RemoveRedundantMatsProcess::~RemoveRedundantMatsProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const

+ 6 - 7
code/PostProcessing/RemoveRedundantMaterials.h

@@ -59,23 +59,22 @@ namespace Assimp    {
  */
 class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess {
 public:
-    /// The default class constructor.
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     RemoveRedundantMatsProcess();
-
-    /// The class destructor.
-    ~RemoveRedundantMatsProcess();
+    ~RemoveRedundantMatsProcess() override = default;
 
     // -------------------------------------------------------------------
     // Check whether step is active
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     // Execute step on a given scene
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
     // Setup import settings
-    void SetupProperties(const Importer* pImp);
+    void SetupProperties(const Importer* pImp) override;
 
     // -------------------------------------------------------------------
     /** @brief Set list of fixed (inmutable) materials

+ 0 - 4
code/PostProcessing/RemoveVCProcess.cpp

@@ -56,10 +56,6 @@ using namespace Assimp;
 RemoveVCProcess::RemoveVCProcess() :
         configDeleteFlags(), mScene() {}
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-RemoveVCProcess::~RemoveVCProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool RemoveVCProcess::IsActive(unsigned int pFlags) const {

+ 8 - 11
code/PostProcessing/RemoveVCProcess.h

@@ -58,11 +58,10 @@ namespace Assimp {
 */
 class ASSIMP_API RemoveVCProcess : public BaseProcess {
 public:
-    /// The default class constructor.
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     RemoveVCProcess();
-
-    /// The class destructor.
-    ~RemoveVCProcess();
+    ~RemoveVCProcess() override = default;
 
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag field.
@@ -70,37 +69,35 @@ public:
     *   combination of #aiPostProcessSteps.
     * @return true if the process is present in this flag fields, false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
     /** Called prior to ExecuteOnScene().
     * The function is a request to the process to update its configuration
     * basing on the Importer's configuration property list.
     */
-    virtual void SetupProperties(const Importer* pImp);
+    virtual void SetupProperties(const Importer* pImp) override;
 
     // -------------------------------------------------------------------
     /** Manually setup the configuration flags for the step
      *
      *  @param Bitwise combination of the #aiComponent enumerated values.
     */
-    void SetDeleteFlags(unsigned int f)
-    {
+    void SetDeleteFlags(unsigned int f) {
         configDeleteFlags = f;
     }
 
     // -------------------------------------------------------------------
     /** Query the current configuration.
     */
-    unsigned int GetDeleteFlags() const
-    {
+    unsigned int GetDeleteFlags() const {
         return configDeleteFlags;
     }
 

+ 19 - 24
code/PostProcessing/ScaleProcess.cpp

@@ -47,25 +47,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 namespace Assimp {
 
-ScaleProcess::ScaleProcess()
-: BaseProcess()
-, mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
+// ------------------------------------------------------------------------------------------------
+ScaleProcess::ScaleProcess() : BaseProcess(), mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
+    // empty
 }
 
-ScaleProcess::~ScaleProcess() = default;
-
+// ------------------------------------------------------------------------------------------------
 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 ) {
     // User scaling
     mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 1.0f );
@@ -78,6 +80,7 @@ void ScaleProcess::SetupProperties( const Importer* pImp ) {
     mScale *= importerScale;
 }
 
+// ------------------------------------------------------------------------------------------------
 void ScaleProcess::Execute( aiScene* pScene ) {
     if(mScale == 1.0f)  {
         return; // nothing to scale
@@ -96,37 +99,30 @@ void ScaleProcess::Execute( aiScene* pScene ) {
     }
 
     // Process animations and update position transform to new unit system
-    for( unsigned int animationID = 0; animationID < pScene->mNumAnimations; animationID++ )
-    {
+    for( unsigned int animationID = 0; animationID < pScene->mNumAnimations; animationID++ ) {
         aiAnimation* animation = pScene->mAnimations[animationID];
 
-        for( unsigned int animationChannel = 0; animationChannel < animation->mNumChannels; animationChannel++)
-        {
+        for( unsigned int animationChannel = 0; animationChannel < animation->mNumChannels; animationChannel++) {
             aiNodeAnim* anim = animation->mChannels[animationChannel];
 
-            for( unsigned int posKey = 0; posKey < anim->mNumPositionKeys; posKey++)
-            {
+            for( unsigned int posKey = 0; posKey < anim->mNumPositionKeys; posKey++) {
                 aiVectorKey& vectorKey = anim->mPositionKeys[posKey];
                 vectorKey.mValue *= mScale;
             }
         }
     }
 
-    for( unsigned int meshID = 0; meshID < pScene->mNumMeshes; meshID++)
-    {
+    for( unsigned int meshID = 0; meshID < pScene->mNumMeshes; meshID++) {
         aiMesh *mesh = pScene->mMeshes[meshID];
 
         // Reconstruct mesh vertices to the new unit system
-        for( unsigned int vertexID = 0; vertexID < mesh->mNumVertices; vertexID++)
-        {
+        for( unsigned int vertexID = 0; vertexID < mesh->mNumVertices; vertexID++) {
             aiVector3D& vertex = mesh->mVertices[vertexID];
             vertex *= mScale;
         }
 
-
         // bone placement / scaling
-        for( unsigned int boneID = 0; boneID < mesh->mNumBones; boneID++)
-        {
+        for( unsigned int boneID = 0; boneID < mesh->mNumBones; boneID++) {
             // Reconstruct matrix by transform rather than by scale
             // This prevent scale values being changed which can
             // be meaningful in some cases
@@ -152,12 +148,10 @@ void ScaleProcess::Execute( aiScene* pScene ) {
 
         // animation mesh processing
         // convert by position rather than scale.
-        for( unsigned int animMeshID = 0; animMeshID < mesh->mNumAnimMeshes; animMeshID++)
-        {
+        for( unsigned int animMeshID = 0; animMeshID < mesh->mNumAnimMeshes; animMeshID++) {
             aiAnimMesh * animMesh = mesh->mAnimMeshes[animMeshID];
 
-            for( unsigned int vertexID = 0; vertexID < animMesh->mNumVertices; vertexID++)
-            {
+            for( unsigned int vertexID = 0; vertexID < animMesh->mNumVertices; vertexID++) {
                 aiVector3D& vertex = animMesh->mVertices[vertexID];
                 vertex *= mScale;
             }
@@ -167,16 +161,17 @@ void ScaleProcess::Execute( aiScene* pScene ) {
     traverseNodes( pScene->mRootNode );
 }
 
+// ------------------------------------------------------------------------------------------------
 void ScaleProcess::traverseNodes( aiNode *node, unsigned int nested_node_id ) {
     applyScaling( node );
 
-    for( size_t i = 0; i < node->mNumChildren; i++)
-    {
+    for( size_t i = 0; i < node->mNumChildren; i++) {
         // recurse into the tree until we are done!
         traverseNodes( node->mChildren[i], nested_node_id+1 );
     }
 }
 
+// ------------------------------------------------------------------------------------------------
 void ScaleProcess::applyScaling( aiNode *currentNode ) {
     if ( nullptr != currentNode ) {
         // Reconstruct matrix by transform rather than by scale

+ 6 - 7
code/PostProcessing/ScaleProcess.h

@@ -62,11 +62,10 @@ namespace Assimp {
 */
 class ASSIMP_API ScaleProcess : public BaseProcess {
 public:
-    /// The default class constructor.
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     ScaleProcess();
-
-    /// The class destructor.
-    virtual ~ScaleProcess();
+    ~ScaleProcess() override = default;
 
     /// Will set the scale manually.
     void setScale( ai_real scale );
@@ -75,13 +74,13 @@ public:
     ai_real getScale() const;
 
     /// Overwritten, @see BaseProcess
-    virtual bool IsActive( unsigned int pFlags ) const;
+    virtual bool IsActive( unsigned int pFlags ) const override;
 
     /// Overwritten, @see BaseProcess
-    virtual void SetupProperties( const Importer* pImp );
+    virtual void SetupProperties( const Importer* pImp ) override;
 
     /// Overwritten, @see BaseProcess
-    virtual void Execute( aiScene* pScene );
+    virtual void Execute( aiScene* pScene ) override;
 
 private:
     void traverseNodes( aiNode *currentNode, unsigned int nested_node_id = 0 );

+ 0 - 4
code/PostProcessing/SortByPTypeProcess.cpp

@@ -59,10 +59,6 @@ SortByPTypeProcess::SortByPTypeProcess() :
     // empty
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-SortByPTypeProcess::~SortByPTypeProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool SortByPTypeProcess::IsActive(unsigned int pFlags) const {

+ 6 - 4
code/PostProcessing/SortByPTypeProcess.h

@@ -60,17 +60,19 @@ namespace Assimp    {
 */
 class ASSIMP_API SortByPTypeProcess : public BaseProcess {
 public:
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     SortByPTypeProcess();
-    ~SortByPTypeProcess();
+    ~SortByPTypeProcess() override = default;
 
     // -------------------------------------------------------------------
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
-    void SetupProperties(const Importer* pImp);
+    void SetupProperties(const Importer* pImp) override;
 
 private:
     int mConfigRemoveMeshes;

+ 63 - 121
code/PostProcessing/SplitByBoneCountProcess.cpp

@@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ----------------------------------------------------------------------
 */
 
-
 /// @file SplitByBoneCountProcess.cpp
 /// Implementation of the SplitByBoneCount postprocessing step
 
@@ -59,47 +58,36 @@ using namespace Assimp::Formatter;
 
 // ------------------------------------------------------------------------------------------------
 // Constructor
-SplitByBoneCountProcess::SplitByBoneCountProcess()
-{
-    // set default, might be overridden by importer config
-    mMaxBoneCount = AI_SBBC_DEFAULT_MAX_BONES;
+SplitByBoneCountProcess::SplitByBoneCountProcess() : mMaxBoneCount(AI_SBBC_DEFAULT_MAX_BONES) {
+    // empty
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor
-SplitByBoneCountProcess::~SplitByBoneCountProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag.
-bool SplitByBoneCountProcess::IsActive( unsigned int pFlags) const
-{
+bool SplitByBoneCountProcess::IsActive( unsigned int pFlags) const {
     return !!(pFlags & aiProcess_SplitByBoneCount);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Updates internal properties
-void SplitByBoneCountProcess::SetupProperties(const Importer* pImp)
-{
+void SplitByBoneCountProcess::SetupProperties(const Importer* pImp) {
     mMaxBoneCount = pImp->GetPropertyInteger(AI_CONFIG_PP_SBBC_MAX_BONES,AI_SBBC_DEFAULT_MAX_BONES);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Executes the post processing step on the given imported data.
-void SplitByBoneCountProcess::Execute( aiScene* pScene)
-{
+void SplitByBoneCountProcess::Execute( aiScene* pScene) {
     ASSIMP_LOG_DEBUG("SplitByBoneCountProcess begin");
 
     // early out
     bool isNecessary = false;
     for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
-        if( pScene->mMeshes[a]->mNumBones > mMaxBoneCount )
-        {
+        if( pScene->mMeshes[a]->mNumBones > mMaxBoneCount ) {
             isNecessary = true;
             break;
         }
 
-    if( !isNecessary )
-    {
+    if( !isNecessary ) {
         ASSIMP_LOG_DEBUG("SplitByBoneCountProcess early-out: no meshes with more than ", mMaxBoneCount, " bones." );
         return;
     }
@@ -111,28 +99,23 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene)
     // build a new array of meshes for the scene
     std::vector<aiMesh*> meshes;
 
-    for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
-    {
+    for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
         aiMesh* srcMesh = pScene->mMeshes[a];
 
         std::vector<aiMesh*> newMeshes;
         SplitMesh( pScene->mMeshes[a], newMeshes);
 
         // mesh was split
-        if( !newMeshes.empty() )
-        {
+        if( !newMeshes.empty() ) {
             // store new meshes and indices of the new meshes
-            for( unsigned int b = 0; b < newMeshes.size(); ++b)
-            {
+            for( unsigned int b = 0; b < newMeshes.size(); ++b) {
                 mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
                 meshes.push_back( newMeshes[b]);
             }
 
             // and destroy the source mesh. It should be completely contained inside the new submeshes
             delete srcMesh;
-        }
-        else
-        {
+        } else {
             // Mesh is kept unchanged - store it's new place in the mesh array
             mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
             meshes.push_back( srcMesh);
@@ -153,11 +136,9 @@ void SplitByBoneCountProcess::Execute( aiScene* pScene)
 
 // ------------------------------------------------------------------------------------------------
 // Splits the given mesh by bone count.
-void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh*>& poNewMeshes) const
-{
+void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh*>& poNewMeshes) const {
     // skip if not necessary
-    if( pMesh->mNumBones <= mMaxBoneCount )
-    {
+    if( pMesh->mNumBones <= mMaxBoneCount ) {
         return;
     }
 
@@ -165,27 +146,22 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
     // TODO: (thom) maybe add a custom allocator here to avoid allocating tens of thousands of small arrays
     typedef std::pair<unsigned int, float> BoneWeight;
     std::vector< std::vector<BoneWeight> > vertexBones( pMesh->mNumVertices);
-    for( unsigned int a = 0; a < pMesh->mNumBones; ++a)
-    {
+    for( unsigned int a = 0; a < pMesh->mNumBones; ++a) {
         const aiBone* bone = pMesh->mBones[a];
-        for( unsigned int b = 0; b < bone->mNumWeights; ++b)
-        {
-          if (bone->mWeights[b].mWeight > 0.0f)
-          {
-            int vertexId = bone->mWeights[b].mVertexId;
-            vertexBones[vertexId].emplace_back(a, bone->mWeights[b].mWeight);
-            if (vertexBones[vertexId].size() > mMaxBoneCount)
-            {
-              throw DeadlyImportError("SplitByBoneCountProcess: Single face requires more bones than specified max bone count!");
+        for( unsigned int b = 0; b < bone->mNumWeights; ++b) {
+            if (bone->mWeights[b].mWeight > 0.0f) {
+                int vertexId = bone->mWeights[b].mVertexId;
+                vertexBones[vertexId].emplace_back(a, bone->mWeights[b].mWeight);
+                if (vertexBones[vertexId].size() > mMaxBoneCount) {
+                    throw DeadlyImportError("SplitByBoneCountProcess: Single face requires more bones than specified max bone count!");
+                }
             }
-          }
         }
     }
 
     unsigned int numFacesHandled = 0;
     std::vector<bool> isFaceHandled( pMesh->mNumFaces, false);
-    while( numFacesHandled < pMesh->mNumFaces )
-    {
+    while( numFacesHandled < pMesh->mNumFaces ) {
         // which bones are used in the current submesh
         unsigned int numBones = 0;
         std::vector<bool> isBoneUsed( pMesh->mNumBones, false);
@@ -196,11 +172,9 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
         unsigned int numSubMeshVertices = 0;
 
         // add faces to the new submesh as long as all bones affecting the faces' vertices fit in the limit
-        for( unsigned int a = 0; a < pMesh->mNumFaces; ++a)
-        {
+        for( unsigned int a = 0; a < pMesh->mNumFaces; ++a) {
             // skip if the face is already stored in a submesh
-            if( isFaceHandled[a] )
-            {
+            if( isFaceHandled[a] ) {
                 continue;
             }
             // a small local set of new bones for the current face. State of all used bones for that face
@@ -209,33 +183,27 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
 
             const aiFace& face = pMesh->mFaces[a];
             // check every vertex if its bones would still fit into the current submesh
-            for( unsigned int b = 0; b < face.mNumIndices; ++b )
-            {
-              const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]];
-              for( unsigned int c = 0; c < vb.size(); ++c)
-              {
-                unsigned int boneIndex = vb[c].first;
-                if( !isBoneUsed[boneIndex] )
-                {
-                  newBonesAtCurrentFace.insert(boneIndex);
+            for( unsigned int b = 0; b < face.mNumIndices; ++b ) {
+                const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]];
+                for( unsigned int c = 0; c < vb.size(); ++c) {
+                    unsigned int boneIndex = vb[c].first;
+                    if( !isBoneUsed[boneIndex] ) {
+                        newBonesAtCurrentFace.insert(boneIndex);
+                    }
                 }
-              }
             }
 
             // leave out the face if the new bones required for this face don't fit the bone count limit anymore
-            if( numBones + newBonesAtCurrentFace.size() > mMaxBoneCount )
-            {
+            if( numBones + newBonesAtCurrentFace.size() > mMaxBoneCount ) {
                 continue;
             }
 
             // mark all new bones as necessary
-            for (std::set<unsigned int>::iterator it = newBonesAtCurrentFace.begin(); it != newBonesAtCurrentFace.end(); ++it)
-            {
-              if (!isBoneUsed[*it])
-              {
-                isBoneUsed[*it] = true;
-                numBones++;
-              }
+            for (std::set<unsigned int>::iterator it = newBonesAtCurrentFace.begin(); it != newBonesAtCurrentFace.end(); ++it) {
+                if (!isBoneUsed[*it]) {
+                    isBoneUsed[*it] = true;
+                    numBones++;
+                }
             }
 
             // store the face index and the vertex count
@@ -261,27 +229,21 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
         newMesh->mNumVertices = numSubMeshVertices;
         newMesh->mNumFaces = static_cast<unsigned int>(subMeshFaces.size());
         newMesh->mVertices = new aiVector3D[newMesh->mNumVertices];
-        if( pMesh->HasNormals() )
-        {
+        if( pMesh->HasNormals() ) {
             newMesh->mNormals = new aiVector3D[newMesh->mNumVertices];
         }
-        if( pMesh->HasTangentsAndBitangents() )
-        {
+        if( pMesh->HasTangentsAndBitangents() ) {
             newMesh->mTangents = new aiVector3D[newMesh->mNumVertices];
             newMesh->mBitangents = new aiVector3D[newMesh->mNumVertices];
         }
-        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
-        {
-            if( pMesh->HasTextureCoords( a) )
-            {
+        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a ) {
+            if( pMesh->HasTextureCoords( a) ) {
                 newMesh->mTextureCoords[a] = new aiVector3D[newMesh->mNumVertices];
             }
             newMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a];
         }
-        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
-        {
-            if( pMesh->HasVertexColors( a) )
-            {
+        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a ) {
+            if( pMesh->HasVertexColors( a) ) {
                 newMesh->mColors[a] = new aiColor4D[newMesh->mNumVertices];
             }
         }
@@ -290,41 +252,33 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
         newMesh->mFaces = new aiFace[subMeshFaces.size()];
         unsigned int nvi = 0; // next vertex index
         std::vector<unsigned int> previousVertexIndices( numSubMeshVertices, std::numeric_limits<unsigned int>::max()); // per new vertex: its index in the source mesh
-        for( unsigned int a = 0; a < subMeshFaces.size(); ++a )
-        {
+        for( unsigned int a = 0; a < subMeshFaces.size(); ++a ) {
             const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
             aiFace& dstFace = newMesh->mFaces[a];
             dstFace.mNumIndices = srcFace.mNumIndices;
             dstFace.mIndices = new unsigned int[dstFace.mNumIndices];
 
             // accumulate linearly all the vertices of the source face
-            for( unsigned int b = 0; b < dstFace.mNumIndices; ++b )
-            {
+            for( unsigned int b = 0; b < dstFace.mNumIndices; ++b ) {
                 unsigned int srcIndex = srcFace.mIndices[b];
                 dstFace.mIndices[b] = nvi;
                 previousVertexIndices[nvi] = srcIndex;
 
                 newMesh->mVertices[nvi] = pMesh->mVertices[srcIndex];
-                if( pMesh->HasNormals() )
-                {
+                if( pMesh->HasNormals() ) {
                     newMesh->mNormals[nvi] = pMesh->mNormals[srcIndex];
                 }
-                if( pMesh->HasTangentsAndBitangents() )
-                {
+                if( pMesh->HasTangentsAndBitangents() ) {
                     newMesh->mTangents[nvi] = pMesh->mTangents[srcIndex];
                     newMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex];
                 }
-                for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c )
-                {
-                    if( pMesh->HasTextureCoords( c) )
-                    {
+                for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c ) {
+                    if( pMesh->HasTextureCoords( c) ) {
                         newMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex];
                     }
                 }
-                for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c )
-                {
-                    if( pMesh->HasVertexColors( c) )
-                    {
+                for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c ) {
+                    if( pMesh->HasVertexColors( c) ) {
                         newMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex];
                     }
                 }
@@ -340,10 +294,8 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
         newMesh->mBones = new aiBone*[numBones];
 
         std::vector<unsigned int> mappedBoneIndex( pMesh->mNumBones, std::numeric_limits<unsigned int>::max());
-        for( unsigned int a = 0; a < pMesh->mNumBones; ++a )
-        {
-            if( !isBoneUsed[a] )
-            {
+        for( unsigned int a = 0; a < pMesh->mNumBones; ++a ) {
+            if( !isBoneUsed[a] ) {
                 continue;
             }
 
@@ -360,24 +312,20 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
         ai_assert( newMesh->mNumBones == numBones );
 
         // iterate over all new vertices and count which bones affected its old vertex in the source mesh
-        for( unsigned int a = 0; a < numSubMeshVertices; ++a )
-        {
+        for( unsigned int a = 0; a < numSubMeshVertices; ++a ) {
             unsigned int oldIndex = previousVertexIndices[a];
             const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[oldIndex];
 
-            for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b )
-            {
+            for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b ) {
                 unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
-                if( newBoneIndex != std::numeric_limits<unsigned int>::max() )
-                {
+                if( newBoneIndex != std::numeric_limits<unsigned int>::max() ) {
                     newMesh->mBones[newBoneIndex]->mNumWeights++;
                 }
             }
         }
 
         // allocate all bone weight arrays accordingly
-        for( unsigned int a = 0; a < newMesh->mNumBones; ++a )
-        {
+        for( unsigned int a = 0; a < newMesh->mNumBones; ++a ) {
             aiBone* bone = newMesh->mBones[a];
             ai_assert( bone->mNumWeights > 0 );
             bone->mWeights = new aiVertexWeight[bone->mNumWeights];
@@ -385,16 +333,14 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
         }
 
         // now copy all the bone vertex weights for all the vertices which made it into the new submesh
-        for( unsigned int a = 0; a < numSubMeshVertices; ++a)
-        {
+        for( unsigned int a = 0; a < numSubMeshVertices; ++a) {
             // find the source vertex for it in the source mesh
             unsigned int previousIndex = previousVertexIndices[a];
             // these bones were affecting it
             const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[previousIndex];
             // all of the bones affecting it should be present in the new submesh, or else
             // the face it comprises shouldn't be present
-            for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b)
-            {
+            for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b) {
                 unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
                 ai_assert( newBoneIndex != std::numeric_limits<unsigned int>::max() );
                 aiVertexWeight* dstWeight = newMesh->mBones[newBoneIndex]->mWeights + newMesh->mBones[newBoneIndex]->mNumWeights;
@@ -450,14 +396,11 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
 
 // ------------------------------------------------------------------------------------------------
 // Recursively updates the node's mesh list to account for the changed mesh list
-void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
-{
+void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const {
     // rebuild the node's mesh index list
-    if( pNode->mNumMeshes > 0 )
-    {
+    if( pNode->mNumMeshes == 0 ) {
         std::vector<unsigned int> newMeshList;
-        for( unsigned int a = 0; a < pNode->mNumMeshes; ++a)
-        {
+        for( unsigned int a = 0; a < pNode->mNumMeshes; ++a) {
             unsigned int srcIndex = pNode->mMeshes[a];
             const std::vector<unsigned int>& replaceMeshes = mSubMeshIndices[srcIndex];
             newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
@@ -470,8 +413,7 @@ void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
     }
 
     // do that also recursively for all children
-    for( unsigned int a = 0; a < pNode->mNumChildren; ++a )
-    {
+    for( unsigned int a = 0; a < pNode->mNumChildren; ++a ) {
         UpdateNode( pNode->mChildren[a]);
     }
 }

+ 19 - 27
code/PostProcessing/SplitByBoneCountProcess.h

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2022, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -51,9 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/mesh.h>
 #include <assimp/scene.h>
 
-namespace Assimp
-{
-
+namespace Assimp {
 
 /** Postprocessing filter to split meshes with many bones into submeshes
  * so that each submesh has a certain max bone count.
@@ -61,34 +58,29 @@ namespace Assimp
  * Applied BEFORE the JoinVertices-Step occurs.
  * Returns NON-UNIQUE vertices, splits by bone count.
 */
-class SplitByBoneCountProcess : public BaseProcess
-{
+class SplitByBoneCountProcess : public BaseProcess {
 public:
-
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     SplitByBoneCountProcess();
-    ~SplitByBoneCountProcess();
+    ~SplitByBoneCountProcess() override = default;
 
-public:
-    /** Returns whether the processing step is present in the given flag.
-    * @param pFlags The processing flags the importer was called with. A
-    *   bitwise combination of #aiPostProcessSteps.
-    * @return true if the process is present in this flag fields,
-    *   false if not.
-    */
-    bool IsActive( unsigned int pFlags) const;
-
-    /** Called prior to ExecuteOnScene().
-    * The function is a request to the process to update its configuration
-    * basing on the Importer's configuration property list.
-    */
-    virtual void SetupProperties(const Importer* pImp);
+    /// @brief Returns whether the processing step is present in the given flag.
+    /// @param pFlags The processing flags the importer was called with. A
+    ///        bitwise combination of #aiPostProcessSteps.
+    /// @return true if the process is present in this flag fields, false if not.
+    bool IsActive( unsigned int pFlags) const override;
+
+    /// @brief Called prior to ExecuteOnScene().
+    /// The function is a request to the process to update its configuration
+    /// basing on the Importer's configuration property list.
+    virtual void SetupProperties(const Importer* pImp) override;
 
 protected:
-    /** Executes the post processing step on the given imported data.
-    * At the moment a process is not supposed to fail.
-    * @param pScene The imported data to work at.
-    */
-    void Execute( aiScene* pScene);
+    /// Executes the post processing step on the given imported data.
+    /// At the moment a process is not supposed to fail.
+    /// @param pScene The imported data to work at.
+    void Execute( aiScene* pScene) override;
 
     /// Splits the given mesh by bone count.
     /// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split.

+ 0 - 6
code/PostProcessing/SplitLargeMeshes.cpp

@@ -55,9 +55,6 @@ SplitLargeMeshesProcess_Triangle::SplitLargeMeshesProcess_Triangle() {
     LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES;
 }
 
-// ------------------------------------------------------------------------------------------------
-SplitLargeMeshesProcess_Triangle::~SplitLargeMeshesProcess_Triangle() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const {
@@ -329,9 +326,6 @@ SplitLargeMeshesProcess_Vertex::SplitLargeMeshesProcess_Vertex() {
     LIMIT = AI_SLM_DEFAULT_MAX_VERTICES;
 }
 
-// ------------------------------------------------------------------------------------------------
-SplitLargeMeshesProcess_Vertex::~SplitLargeMeshesProcess_Vertex() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool SplitLargeMeshesProcess_Vertex::IsActive( unsigned int pFlags) const {

+ 12 - 24
code/PostProcessing/SplitLargeMeshes.h

@@ -83,16 +83,15 @@ class SplitLargeMeshesProcess_Vertex;
  * Applied BEFORE the JoinVertices-Step occurs.
  * Returns NON-UNIQUE vertices, splits by triangle number.
 */
-class ASSIMP_API SplitLargeMeshesProcess_Triangle : public BaseProcess
-{
+class ASSIMP_API SplitLargeMeshesProcess_Triangle : public BaseProcess {
     friend class SplitLargeMeshesProcess_Vertex;
 
 public:
-
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     SplitLargeMeshesProcess_Triangle();
-    ~SplitLargeMeshesProcess_Triangle();
+    ~SplitLargeMeshesProcess_Triangle() override = default;
 
-public:
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag.
     * @param pFlags The processing flags the importer was called with. A
@@ -100,16 +99,14 @@ public:
     * @return true if the process is present in this flag fields,
     *   false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
-
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Called prior to ExecuteOnScene().
     * The function is a request to the process to update its configuration
     * basing on the Importer's configuration property list.
     */
-    virtual void SetupProperties(const Importer* pImp);
-
+    void SetupProperties(const Importer* pImp) override;
 
     //! Set the split limit - needed for unit testing
     inline void SetLimit(unsigned int l)
@@ -119,14 +116,12 @@ public:
     inline unsigned int GetLimit() const
         {return LIMIT;}
 
-public:
-
     // -------------------------------------------------------------------
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
     //! Apply the algorithm to a given mesh
@@ -144,36 +139,31 @@ public:
     unsigned int LIMIT;
 };
 
-
 // ---------------------------------------------------------------------------
 /** Post-processing filter to split large meshes into sub-meshes
  *
  * Applied AFTER the JoinVertices-Step occurs.
  * Returns UNIQUE vertices, splits by vertex number.
 */
-class ASSIMP_API SplitLargeMeshesProcess_Vertex : public BaseProcess
-{
+class ASSIMP_API SplitLargeMeshesProcess_Vertex : public BaseProcess {
 public:
-
     SplitLargeMeshesProcess_Vertex();
-    ~SplitLargeMeshesProcess_Vertex();
+    ~SplitLargeMeshesProcess_Vertex() override = default;
 
-public:
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag field.
     * @param pFlags The processing flags the importer was called with. A bitwise
     *   combination of #aiPostProcessSteps.
     * @return true if the process is present in this flag fields, false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Called prior to ExecuteOnScene().
     * The function is a request to the process to update its configuration
     * basing on the Importer's configuration property list.
     */
-    virtual void SetupProperties(const Importer* pImp);
-
+    void SetupProperties(const Importer* pImp) override;
 
     //! Set the split limit - needed for unit testing
     inline void SetLimit(unsigned int l)
@@ -183,14 +173,12 @@ public:
     inline unsigned int GetLimit() const
         {return LIMIT;}
 
-public:
-
     // -------------------------------------------------------------------
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
     //! Apply the algorithm to a given mesh

+ 10 - 24
code/PostProcessing/TextureTransform.cpp

@@ -56,33 +56,24 @@ using namespace Assimp;
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-TextureTransformStep::TextureTransformStep() :
-    configFlags()
-{
+TextureTransformStep::TextureTransformStep() : configFlags()  {
     // nothing to do here
 }
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-TextureTransformStep::~TextureTransformStep() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
-bool TextureTransformStep::IsActive( unsigned int pFlags) const
-{
+bool TextureTransformStep::IsActive( unsigned int pFlags) const {
     return  (pFlags & aiProcess_TransformUVCoords) != 0;
 }
 
 // ------------------------------------------------------------------------------------------------
 // Setup properties
-void TextureTransformStep::SetupProperties(const Importer* pImp)
-{
+void TextureTransformStep::SetupProperties(const Importer* pImp) {
     configFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_TUV_EVALUATE,AI_UVTRAFO_ALL);
 }
 
 // ------------------------------------------------------------------------------------------------
-void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
-{
+void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info) {
     /*  This function tries to simplify the input UV transformation.
      *  That's very important as it allows us to reduce the number
      *  of output UV channels. The order in which the transformations
@@ -90,7 +81,7 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
      */
 
 	int rounded;
-	char szTemp[512];
+	char szTemp[512] = {};
 
     /* Optimize the rotation angle. That's slightly difficult as
      * we have an inprecise floating-point number (when comparing
@@ -98,12 +89,10 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
      * an epsilon of 5 degrees). If there is a rotation value, we can't
      * perform any further optimizations.
      */
-    if (info.mRotation)
-    {
+    if (info.mRotation) {
         float out = info.mRotation;
         rounded = static_cast<int>((info.mRotation / static_cast<float>(AI_MATH_TWO_PI)));
-        if (rounded)
-        {
+        if (rounded) {
             out -= rounded * static_cast<float>(AI_MATH_PI);
             ASSIMP_LOG_INFO("Texture coordinate rotation ", info.mRotation, " can be simplified to ", out);
         }
@@ -187,8 +176,7 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
 }
 
 // ------------------------------------------------------------------------------------------------
-void UpdateUVIndex(const std::list<TTUpdateInfo>& l, unsigned int n)
-{
+void UpdateUVIndex(const std::list<TTUpdateInfo>& l, unsigned int n) {
     // Don't set if == 0 && wasn't set before
     for (std::list<TTUpdateInfo>::const_iterator it = l.begin();it != l.end(); ++it) {
         const TTUpdateInfo& info = *it;
@@ -203,8 +191,7 @@ void UpdateUVIndex(const std::list<TTUpdateInfo>& l, unsigned int n)
 }
 
 // ------------------------------------------------------------------------------------------------
-inline const char* MappingModeToChar(aiTextureMapMode map)
-{
+inline static const char* MappingModeToChar(aiTextureMapMode map) {
     if (aiTextureMapMode_Wrap == map)
         return "-w";
 
@@ -215,8 +202,7 @@ inline const char* MappingModeToChar(aiTextureMapMode map)
 }
 
 // ------------------------------------------------------------------------------------------------
-void TextureTransformStep::Execute( aiScene* pScene)
-{
+void TextureTransformStep::Execute( aiScene* pScene) {
     ASSIMP_LOG_DEBUG("TransformUVCoordsProcess begin");
 
 

+ 9 - 15
code/PostProcessing/TextureTransform.h

@@ -193,28 +193,23 @@ struct STransformVecInfo : public aiUVTransform {
 /** Helper step to compute final UV coordinate sets if there are scalings
  *  or rotations in the original data read from the file.
 */
-class TextureTransformStep : public BaseProcess
-{
+class TextureTransformStep : public BaseProcess {
 public:
-
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     TextureTransformStep();
-    ~TextureTransformStep();
-
-public:
+    ~TextureTransformStep() override = default;
 
     // -------------------------------------------------------------------
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
-    void SetupProperties(const Importer* pImp);
-
+    void SetupProperties(const Importer* pImp) override;
 
 protected:
-
-
     // -------------------------------------------------------------------
     /** Preprocess a specific UV transformation setup
      *
@@ -223,10 +218,9 @@ protected:
     void PreProcessUVTransform(STransformVecInfo& info);
 
 private:
-
     unsigned int configFlags;
 };
-
-}
+ 
+} // namespace Assimp
 
 #endif //! AI_TEXTURE_TRANSFORM_H_INCLUDED

+ 15 - 9
code/PostProcessing/TriangulateProcess.cpp

@@ -156,15 +156,6 @@ namespace {
 
 }
 
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-TriangulateProcess::TriangulateProcess() = default;
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-TriangulateProcess::~TriangulateProcess() = default;
-
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
 bool TriangulateProcess::IsActive( unsigned int pFlags) const
@@ -468,6 +459,21 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
                         continue;
                     }
 
+                    // Skip when three point is in a line
+                    aiVector2D left = *pnt0 - *pnt1;
+                    aiVector2D right = *pnt2 - *pnt1;
+
+                    left.Normalize();
+                    right.Normalize();
+                    auto mul = left * right;
+
+                    // if the angle is 0 or 180
+                    if (std::abs(mul - 1.f) < ai_epsilon || std::abs(mul + 1.f) < ai_epsilon) {
+                        // skip this ear
+                        ASSIMP_LOG_WARN("Skip a ear, due to its angle is near 0 or 180.");
+                        continue;
+                    }
+
                     // and no other point may be contained in this triangle
                     for ( tmp = 0; tmp < max; ++tmp) {
 

+ 6 - 4
code/PostProcessing/TriangulateProcess.h

@@ -61,8 +61,10 @@ namespace Assimp {
  */
 class ASSIMP_API TriangulateProcess : public BaseProcess {
 public:
-    TriangulateProcess();
-    ~TriangulateProcess();
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
+    TriangulateProcess() = default;
+    ~TriangulateProcess() override = default;
 
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag field.
@@ -70,14 +72,14 @@ public:
      *   combination of #aiPostProcessSteps.
      * @return true if the process is present in this flag fields, false if not.
     */
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
     /** Executes the post processing step on the given imported data.
     * At the moment a process is not supposed to fail.
     * @param pScene The imported data to work at.
     */
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
     // -------------------------------------------------------------------
     /** Triangulates the given mesh.

+ 7 - 7
code/PostProcessing/ValidateDataStructure.cpp

@@ -60,12 +60,7 @@ using namespace Assimp;
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-ValidateDSProcess::ValidateDSProcess() :
-        mScene() {}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ValidateDSProcess::~ValidateDSProcess() = default;
+ValidateDSProcess::ValidateDSProcess() : mScene(nullptr) {}
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the processing step is present in the given flag field.
@@ -916,7 +911,12 @@ void ValidateDSProcess::Validate(const aiNode *pNode) {
                     nodeName, pNode->mNumChildren);
         }
         for (unsigned int i = 0; i < pNode->mNumChildren; ++i) {
-            Validate(pNode->mChildren[i]);
+            const aiNode *pChild = pNode->mChildren[i];
+            Validate(pChild);
+            if (pChild->mParent != pNode) {
+                const char *parentName = (pChild->mParent != nullptr) ? pChild->mParent->mName.C_Str() : "null";
+                ReportError("aiNode \"%s\" child %i \"%s\" parent is someone else: \"%s\"", pNode->mName.C_Str(), i, pChild->mName.C_Str(), parentName);
+            }
         }
     }
 }

+ 6 - 8
code/PostProcessing/ValidateDataStructure.h

@@ -69,22 +69,20 @@ namespace Assimp    {
 /** Validates the whole ASSIMP scene data structure for correctness.
  *  ImportErrorException is thrown of the scene is corrupt.*/
 // --------------------------------------------------------------------------------------
-class ValidateDSProcess : public BaseProcess
-{
+class ValidateDSProcess : public BaseProcess {
 public:
-
+    // -------------------------------------------------------------------
+    /// The default class constructor / destructor.
     ValidateDSProcess();
-    ~ValidateDSProcess();
+    ~ValidateDSProcess() override = default;
 
-public:
     // -------------------------------------------------------------------
-    bool IsActive( unsigned int pFlags) const;
+    bool IsActive( unsigned int pFlags) const override;
 
     // -------------------------------------------------------------------
-    void Execute( aiScene* pScene);
+    void Execute( aiScene* pScene) override;
 
 protected:
-
     // -------------------------------------------------------------------
     /** Report a validation error. This will throw an exception,
      *  control won't return.

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 326 - 98
contrib/stb/stb_image.h


+ 2 - 1
contrib/unzip/crypt.c

@@ -103,7 +103,7 @@ int cryptrand(unsigned char *buf, unsigned int len)
     unsigned __int64 pentium_tsc[1];
     int result = 0;
 
-
+    #if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP
     if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
     {
         result = CryptGenRandom(provider, len, buf);
@@ -111,6 +111,7 @@ int cryptrand(unsigned char *buf, unsigned int len)
         if (result)
             return len;
     }
+    #endif
 
     for (rlen = 0; rlen < (int)len; ++rlen)
     {

+ 9 - 1
contrib/zlib/CMakeLists.txt

@@ -76,7 +76,15 @@ if(MSVC)
     set(CMAKE_DEBUG_POSTFIX "d")
     add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
     add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
+    if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
+        SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-non-prototype")
+    endif()
+
     include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+else()
+    if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
+        SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-non-prototype")
+    endif()
 endif()
 
 if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
@@ -88,7 +96,7 @@ if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
         message(STATUS "to 'zconf.h.included' because this file is included with zlib")
         message(STATUS "but CMake generates it automatically in the build directory.")
         file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included)
-  endif()
+    endif()
 endif()
 
 set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc)

+ 5 - 1
port/PyAssimp/pyassimp/core.py

@@ -115,6 +115,10 @@ def _init(self, target = None, parent = None):
         if m.startswith("_"):
             continue
 
+        # We should not be accessing `mPrivate` according to structs.Scene.
+        if m == 'mPrivate':
+            continue
+
         if m.startswith('mNum'):
             if 'm' + m[4:] in dirself:
                 continue # will be processed later on
@@ -211,7 +215,7 @@ def _init(self, target = None, parent = None):
 
 
             else: # starts with 'm' but not iterable
-                setattr(target, m, obj)
+                setattr(target, name, obj)
                 logger.debug("Added " + name + " as self." + name + " (type: " + str(type(obj)) + ")")
 
                 if _is_init_type(obj):

BIN
test/models-nonbsd/BLEND/guard1_body.png


BIN
test/models-nonbsd/BLEND/guard1_face.png


BIN
test/models-nonbsd/BLEND/guard1_helmet.png


BIN
test/models-nonbsd/BLEND/iron_grill.png


BIN
test/models-nonbsd/BLEND/round_grill.png


BIN
test/models-nonbsd/IRR/skybox.xml


BIN
test/models-nonbsd/IRR/skybox_UTF16LE.xml


BIN
test/models/COB/axe.jpg


BIN
test/models/COB/dwarf.jpg


BIN
test/models/COB/dwarf2.jpg


BIN
test/models/IRR/1.png


BIN
test/models/IRR/EpisodeII_TheDwarfesStrikeBack.irr


BIN
test/models/IRR/EpisodeII_TheDwarfesStrikeBack_UTF16LE.irr


BIN
test/models/IRR/EpisodeI_ANewDwarf.irr


BIN
test/models/IRR/EpisodeI_ANewDwarf_UTF16LE.irr


BIN
test/models/IRR/animMesh.irr


BIN
test/models/IRR/animMesh_UTF16LE.irr


BIN
test/models/IRR/box.irr


BIN
test/models/IRR/box_UTF16LE.irr


BIN
test/models/IRR/brownground_1-1.jpg


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