diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..18c914718
--- /dev/null
+++ b/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.
diff --git a/Readme.md b/Readme.md
index 917b8e8aa..9a8ac7c33 100644
--- a/Readme.md
+++ b/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/)
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).
-
-You find a bug in the docs? Use [Doc-Repo](https://github.com/assimp/assimp-docs).
-
-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)
+
#### 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/ 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)
-
### 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.
diff --git a/code/AssetLib/AMF/AMFImporter_Postprocess.cpp b/code/AssetLib/AMF/AMFImporter_Postprocess.cpp
index a65f9260e..d5160870a 100644
--- a/code/AssetLib/AMF/AMFImporter_Postprocess.cpp
+++ b/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;
diff --git a/code/AssetLib/Blender/BlenderScene.cpp b/code/AssetLib/Blender/BlenderScene.cpp
index 3a9a02fd0..ac10d7302 100644
--- a/code/AssetLib/Blender/BlenderScene.cpp
+++ b/code/AssetLib/Blender/BlenderScene.cpp
@@ -569,7 +569,7 @@ void Structure ::Convert(
const FileDatabase &db) const {
ReadFieldArray(dest.co, "co", db);
- ReadFieldArray(dest.no, "no", db);
+ ReadFieldArray(dest.no, "no", db);
ReadField(dest.flag, "flag", db);
//ReadField(dest.mat_nr,"mat_nr",db);
ReadField(dest.bweight, "bweight", db);
diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp
index 37654746e..257845384 100644
--- a/code/AssetLib/FBX/FBXConverter.cpp
+++ b/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();
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
const TransformationComp comp = static_cast(i);
@@ -1180,15 +1180,23 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
std::vector animMeshes;
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
- const std::vector &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 &curVertices = shapeGeometry->GetVertices();
- const std::vector &curNormals = shapeGeometry->GetNormals();
- const std::vector &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 animMeshes;
for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
- const std::vector &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 &curVertices = shapeGeometry->GetVertices();
- const std::vector &curNormals = shapeGeometry->GetNormals();
- const std::vector &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);
diff --git a/code/AssetLib/FBX/FBXDeformer.cpp b/code/AssetLib/FBX/FBXDeformer.cpp
index df134a401..1aab55ea9 100644
--- a/code/AssetLib/FBX/FBXDeformer.cpp
+++ b/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(*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(*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());
+ }
}
}
}
diff --git a/code/AssetLib/FBX/FBXDocument.h b/code/AssetLib/FBX/FBXDocument.h
index 8873d65fd..821d4d5cb 100644
--- a/code/AssetLib/FBX/FBXDocument.h
+++ b/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
+#include
#include
#include
#include "FBXProperties.h"
@@ -855,14 +856,14 @@ public:
return fullWeights;
}
- const std::vector& GetShapeGeometries() const {
+ const std::unordered_set& GetShapeGeometries() const {
return shapeGeometries;
}
private:
float percent;
WeightArray fullWeights;
- std::vector shapeGeometries;
+ std::unordered_set shapeGeometries;
};
/** DOM class for BlendShape deformers */
@@ -872,12 +873,12 @@ public:
virtual ~BlendShape();
- const std::vector& BlendShapeChannels() const {
+ const std::unordered_set& BlendShapeChannels() const {
return blendShapeChannels;
}
private:
- std::vector blendShapeChannels;
+ std::unordered_set blendShapeChannels;
};
/** DOM class for skin deformer clusters (aka sub-deformers) */
diff --git a/code/AssetLib/FBX/FBXMeshGeometry.cpp b/code/AssetLib/FBX/FBXMeshGeometry.cpp
index ace4ad749..fcbaac169 100644
--- a/code/AssetLib/FBX/FBXMeshGeometry.cpp
+++ b/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(*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& Geometry::GetBlendShapes() const {
+const std::unordered_set& Geometry::GetBlendShapes() const {
return blendShapes;
}
diff --git a/code/AssetLib/FBX/FBXMeshGeometry.h b/code/AssetLib/FBX/FBXMeshGeometry.h
index f4a1a2673..3d67ec567 100644
--- a/code/AssetLib/FBX/FBXMeshGeometry.h
+++ b/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& GetBlendShapes() const;
+ const std::unordered_set& GetBlendShapes() const;
private:
const Skin* skin;
- std::vector blendShapes;
+ std::unordered_set blendShapes;
+
};
typedef std::vector MatIndexArray;
@@ -112,7 +113,7 @@ public:
/// @return The binomal vector.
const std::vector& 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& GetFaceIndexCounts() const;
diff --git a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp b/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp
index 93d37536c..a8141fcc1 100644
--- a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp
+++ b/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(header_->numbones);
- bones_node->mChildren = new aiNode *[bones_node->mNumChildren];
+
+ // Store roots bones IDs temporarily.
+ std::vector 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(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(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);
+ }
}
// ------------------------------------------------------------------------------------------------
diff --git a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.h b/code/AssetLib/MDL/HalfLife/HL1MDLLoader.h
index 0dba5099d..286b6e64c 100644
--- a/code/AssetLib/MDL/HalfLife/HL1MDLLoader.h
+++ b/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 children; // Bone children
};
std::vector temp_bones_;
diff --git a/code/CApi/AssimpCExport.cpp b/code/CApi/AssimpCExport.cpp
index 5e43958d0..21e40205c 100644
--- a/code/CApi/AssimpCExport.cpp
+++ b/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,
diff --git a/code/CApi/CInterfaceIOWrapper.cpp b/code/CApi/CInterfaceIOWrapper.cpp
index 579545ecc..f0e46cd08 100644
--- a/code/CApi/CInterfaceIOWrapper.cpp
+++ b/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);
}
diff --git a/code/CApi/CInterfaceIOWrapper.h b/code/CApi/CInterfaceIOWrapper.h
index 768be3746..28d4c3e75 100644
--- a/code/CApi/CInterfaceIOWrapper.h
+++ b/code/CApi/CInterfaceIOWrapper.h
@@ -47,48 +47,59 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include
#include
#include
+#include
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
diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt
index a098f3e85..e05b4dd7b 100644
--- a/code/CMakeLists.txt
+++ b/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()
diff --git a/code/Common/PolyTools.h b/code/Common/PolyTools.h
index 9837a2991..a5bd1090b 100644
--- a/code/Common/PolyTools.h
+++ b/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
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);
}
diff --git a/code/Common/Subdivision.cpp b/code/Common/Subdivision.cpp
index ac4078b47..3aea5d4c5 100644
--- a/code/Common/Subdivision.cpp
+++ b/code/Common/Subdivision.cpp
@@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include
using namespace Assimp;
+
void mydummy() {}
#ifdef _MSC_VER
diff --git a/code/Geometry/GeometryUtils.cpp b/code/Geometry/GeometryUtils.cpp
new file mode 100644
index 000000000..ab735aa6e
--- /dev/null
+++ b/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
+
+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
diff --git a/code/Geometry/GeometryUtils.h b/code/Geometry/GeometryUtils.h
new file mode 100644
index 000000000..ab49380de
--- /dev/null
+++ b/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
+#include
+
+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
diff --git a/code/PostProcessing/CalcTangentsProcess.cpp b/code/PostProcessing/CalcTangentsProcess.cpp
index efc457766..a23ac856b 100644
--- a/code/PostProcessing/CalcTangentsProcess.cpp
+++ b/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 {
diff --git a/code/PostProcessing/CalcTangentsProcess.h b/code/PostProcessing/CalcTangentsProcess.h
index 018789bae..aaccb5307 100644
--- a/code/PostProcessing/CalcTangentsProcess.h
+++ b/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;
diff --git a/code/PostProcessing/ComputeUVMappingProcess.cpp b/code/PostProcessing/ComputeUVMappingProcess.cpp
index 237409f02..a5472668b 100644
--- a/code/PostProcessing/ComputeUVMappingProcess.cpp
+++ b/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
diff --git a/code/PostProcessing/ComputeUVMappingProcess.h b/code/PostProcessing/ComputeUVMappingProcess.h
index 74744be7f..c4158f402 100644
--- a/code/PostProcessing/ComputeUVMappingProcess.h
+++ b/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;
}
};
diff --git a/code/PostProcessing/ConvertToLHProcess.cpp b/code/PostProcessing/ConvertToLHProcess.cpp
index 359c5a284..08e3fe48a 100644
--- a/code/PostProcessing/ConvertToLHProcess.cpp
+++ b/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 {
diff --git a/code/PostProcessing/ConvertToLHProcess.h b/code/PostProcessing/ConvertToLHProcess.h
index 474056c3a..d0532277d 100644
--- a/code/PostProcessing/ConvertToLHProcess.h
+++ b/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);
};
diff --git a/code/PostProcessing/DeboneProcess.cpp b/code/PostProcessing/DeboneProcess.cpp
index 22a4397bf..2a8499dc5 100644
--- a/code/PostProcessing/DeboneProcess.cpp
+++ b/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
-
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 meshes;
- for(unsigned int a=0;amNumMeshes;a++)
- {
+ for (unsigned int a=0;amNumMeshes; ++a) {
aiMesh* srcMesh = pScene->mMeshes[a];
-
std::vector > 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(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;imNumBones;i++) {
for(unsigned int j=0;jmBones[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;imNumFaces;i++) {
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
-
- for(unsigned int j=1;jmFaces[i].mNumIndices;j++) {
+ for (unsigned int j=1;jmFaces[i].mNumIndices;j++) {
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
- if(v!=w) {
- if(vmNumBones) isBoneNecessary[v] = true;
- if(wmNumBones) isBoneNecessary[w] = true;
+ if (v != w) {
+ if(vmNumBones) {
+ isBoneNecessary[v] = true;
+ }
+ if (wmNumBones) {
+ 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 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 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()) {
diff --git a/code/PostProcessing/DeboneProcess.h b/code/PostProcessing/DeboneProcess.h
index cb072b7eb..ae4448e0e 100644
--- a/code/PostProcessing/DeboneProcess.h
+++ b/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.
diff --git a/code/PostProcessing/DropFaceNormalsProcess.cpp b/code/PostProcessing/DropFaceNormalsProcess.cpp
index f85daa588..223482374 100644
--- a/code/PostProcessing/DropFaceNormalsProcess.cpp
+++ b/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 {
diff --git a/code/PostProcessing/DropFaceNormalsProcess.h b/code/PostProcessing/DropFaceNormalsProcess.h
index 50abdc727..df542f2ba 100644
--- a/code/PostProcessing/DropFaceNormalsProcess.h
+++ b/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);
diff --git a/code/PostProcessing/EmbedTexturesProcess.cpp b/code/PostProcessing/EmbedTexturesProcess.cpp
index dc7e54ac1..d5d2ef872 100644
--- a/code/PostProcessing/EmbedTexturesProcess.cpp
+++ b/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;
}
diff --git a/code/PostProcessing/EmbedTexturesProcess.h b/code/PostProcessing/EmbedTexturesProcess.h
index c3e63612c..77d4d9c72 100644
--- a/code/PostProcessing/EmbedTexturesProcess.h
+++ b/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.
diff --git a/code/PostProcessing/FindDegenerates.cpp b/code/PostProcessing/FindDegenerates.cpp
index 344979949..5874c17d2 100644
--- a/code/PostProcessing/FindDegenerates.cpp
+++ b/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
@@ -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_mapmVertices[ 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;
diff --git a/code/PostProcessing/FindDegenerates.h b/code/PostProcessing/FindDegenerates.h
index 6fe1e929b..6b37a47cf 100644
--- a/code/PostProcessing/FindDegenerates.h
+++ b/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;
}
diff --git a/code/PostProcessing/FindInstancesProcess.cpp b/code/PostProcessing/FindInstancesProcess.cpp
index 07a0f66db..55974b1c3 100644
--- a/code/PostProcessing/FindInstancesProcess.cpp
+++ b/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
diff --git a/code/PostProcessing/FindInstancesProcess.h b/code/PostProcessing/FindInstancesProcess.h
index b501d88d5..6927301ca 100644
--- a/code/PostProcessing/FindInstancesProcess.h
+++ b/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
diff --git a/code/PostProcessing/FindInvalidDataProcess.cpp b/code/PostProcessing/FindInvalidDataProcess.cpp
index c65208cbd..bb8e365a1 100644
--- a/code/PostProcessing/FindInvalidDataProcess.cpp
+++ b/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 {
diff --git a/code/PostProcessing/FindInvalidDataProcess.h b/code/PostProcessing/FindInvalidDataProcess.h
index 5ea895c59..024eb9b1e 100644
--- a/code/PostProcessing/FindInvalidDataProcess.h
+++ b/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:
diff --git a/code/PostProcessing/FixNormalsStep.cpp b/code/PostProcessing/FixNormalsStep.cpp
index 3791bd35a..54ac05cc8 100644
--- a/code/PostProcessing/FixNormalsStep.cpp
+++ b/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 );
diff --git a/code/PostProcessing/FixNormalsStep.h b/code/PostProcessing/FixNormalsStep.h
index b7d3ba386..20be1958b 100644
--- a/code/PostProcessing/FixNormalsStep.h
+++ b/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:
diff --git a/code/PostProcessing/GenBoundingBoxesProcess.cpp b/code/PostProcessing/GenBoundingBoxesProcess.cpp
index 52a0861e5..ca8e4d6d0 100644
--- a/code/PostProcessing/GenBoundingBoxesProcess.cpp
+++ b/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 );
}
diff --git a/code/PostProcessing/GenBoundingBoxesProcess.h b/code/PostProcessing/GenBoundingBoxesProcess.h
index 0b7591b6d..0cf8514f4 100644
--- a/code/PostProcessing/GenBoundingBoxesProcess.h
+++ b/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;
};
diff --git a/code/PostProcessing/GenFaceNormalsProcess.cpp b/code/PostProcessing/GenFaceNormalsProcess.cpp
index d3520d4b2..1d259ce22 100644
--- a/code/PostProcessing/GenFaceNormalsProcess.cpp
+++ b/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 {
diff --git a/code/PostProcessing/GenFaceNormalsProcess.h b/code/PostProcessing/GenFaceNormalsProcess.h
index c2f157e20..94794631e 100644
--- a/code/PostProcessing/GenFaceNormalsProcess.h
+++ b/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
-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);
diff --git a/code/PostProcessing/GenVertexNormalsProcess.cpp b/code/PostProcessing/GenVertexNormalsProcess.cpp
index 5b9033383..c8afac297 100644
--- a/code/PostProcessing/GenVertexNormalsProcess.cpp
+++ b/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) {
diff --git a/code/PostProcessing/GenVertexNormalsProcess.h b/code/PostProcessing/GenVertexNormalsProcess.h
index 370bf42b1..b7db9c4f2 100644
--- a/code/PostProcessing/GenVertexNormalsProcess.h
+++ b/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) {
diff --git a/code/PostProcessing/ImproveCacheLocality.cpp b/code/PostProcessing/ImproveCacheLocality.cpp
index 197856171..9336d6b17 100644
--- a/code/PostProcessing/ImproveCacheLocality.cpp
+++ b/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 {
diff --git a/code/PostProcessing/ImproveCacheLocality.h b/code/PostProcessing/ImproveCacheLocality.h
index b2074a17c..6f4d55719 100644
--- a/code/PostProcessing/ImproveCacheLocality.h
+++ b/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:
// -------------------------------------------------------------------
diff --git a/code/PostProcessing/JoinVerticesProcess.h b/code/PostProcessing/JoinVerticesProcess.h
index b05d74ef5..aa8dc5794 100644
--- a/code/PostProcessing/JoinVerticesProcess.h
+++ b/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.
diff --git a/code/PostProcessing/LimitBoneWeightsProcess.cpp b/code/PostProcessing/LimitBoneWeightsProcess.cpp
index 51fb43dfc..7047ec0f1 100644
--- a/code/PostProcessing/LimitBoneWeightsProcess.cpp
+++ b/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.
diff --git a/code/PostProcessing/LimitBoneWeightsProcess.h b/code/PostProcessing/LimitBoneWeightsProcess.h
index 22d286b68..b19d536cf 100644
--- a/code/PostProcessing/LimitBoneWeightsProcess.h
+++ b/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 */
diff --git a/code/PostProcessing/MakeVerboseFormat.cpp b/code/PostProcessing/MakeVerboseFormat.cpp
index 0f5276cf3..1cc2fdc02 100644
--- a/code/PostProcessing/MakeVerboseFormat.cpp
+++ b/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) {
diff --git a/code/PostProcessing/MakeVerboseFormat.h b/code/PostProcessing/MakeVerboseFormat.h
index 6b81da622..f21f5919e 100644
--- a/code/PostProcessing/MakeVerboseFormat.h
+++ b/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:
diff --git a/code/PostProcessing/OptimizeGraph.cpp b/code/PostProcessing/OptimizeGraph.cpp
index 26b06e9b6..bcd654634 100644
--- a/code/PostProcessing/OptimizeGraph.cpp
+++ b/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 {
diff --git a/code/PostProcessing/OptimizeGraph.h b/code/PostProcessing/OptimizeGraph.h
index f5caa139c..23e59e67d 100644
--- a/code/PostProcessing/OptimizeGraph.h
+++ b/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;
diff --git a/code/PostProcessing/OptimizeMeshes.cpp b/code/PostProcessing/OptimizeMeshes.cpp
index a8c01e2d7..0fd597808 100644
--- a/code/PostProcessing/OptimizeMeshes.cpp
+++ b/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
diff --git a/code/PostProcessing/OptimizeMeshes.h b/code/PostProcessing/OptimizeMeshes.h
index b80f98d5d..0b062959a 100644
--- a/code/PostProcessing/OptimizeMeshes.h
+++ b/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
diff --git a/code/PostProcessing/PretransformVertices.cpp b/code/PostProcessing/PretransformVertices.cpp
index 9ac90d277..b6bb6155e 100644
--- a/code/PostProcessing/PretransformVertices.cpp
+++ b/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 {
diff --git a/code/PostProcessing/PretransformVertices.h b/code/PostProcessing/PretransformVertices.h
index 14e5139ec..7c2b5e99e 100644
--- a/code/PostProcessing/PretransformVertices.h
+++ b/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
diff --git a/code/PostProcessing/RemoveRedundantMaterials.cpp b/code/PostProcessing/RemoveRedundantMaterials.cpp
index 3c3cd59e0..dbc3c8822 100644
--- a/code/PostProcessing/RemoveRedundantMaterials.cpp
+++ b/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
diff --git a/code/PostProcessing/RemoveRedundantMaterials.h b/code/PostProcessing/RemoveRedundantMaterials.h
index e8c1478fd..1b42bea55 100644
--- a/code/PostProcessing/RemoveRedundantMaterials.h
+++ b/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
diff --git a/code/PostProcessing/RemoveVCProcess.cpp b/code/PostProcessing/RemoveVCProcess.cpp
index 8bbe791f6..35047dc0a 100644
--- a/code/PostProcessing/RemoveVCProcess.cpp
+++ b/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 {
diff --git a/code/PostProcessing/RemoveVCProcess.h b/code/PostProcessing/RemoveVCProcess.h
index cf1086882..45c0b3a71 100644
--- a/code/PostProcessing/RemoveVCProcess.h
+++ b/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;
}
diff --git a/code/PostProcessing/ScaleProcess.cpp b/code/PostProcessing/ScaleProcess.cpp
index 34f68539a..665f28a7e 100644
--- a/code/PostProcessing/ScaleProcess.cpp
+++ b/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
diff --git a/code/PostProcessing/ScaleProcess.h b/code/PostProcessing/ScaleProcess.h
index b6eb75de7..ae1c3ed00 100644
--- a/code/PostProcessing/ScaleProcess.h
+++ b/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 );
diff --git a/code/PostProcessing/SortByPTypeProcess.cpp b/code/PostProcessing/SortByPTypeProcess.cpp
index 6312fa173..1be75fc48 100644
--- a/code/PostProcessing/SortByPTypeProcess.cpp
+++ b/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 {
diff --git a/code/PostProcessing/SortByPTypeProcess.h b/code/PostProcessing/SortByPTypeProcess.h
index e30342a86..ce4f7da62 100644
--- a/code/PostProcessing/SortByPTypeProcess.h
+++ b/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;
diff --git a/code/PostProcessing/SplitByBoneCountProcess.cpp b/code/PostProcessing/SplitByBoneCountProcess.cpp
index a501d3bd6..5324160d4 100644
--- a/code/PostProcessing/SplitByBoneCountProcess.cpp
+++ b/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 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 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(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(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& poNewMeshes) const
-{
+void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector& 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 BoneWeight;
std::vector< std::vector > 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 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 isBoneUsed( pMesh->mNumBones, false);
@@ -196,11 +172,9 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vectormNumFaces; ++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::vectormFaces[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& 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& 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::iterator it = newBonesAtCurrentFace.begin(); it != newBonesAtCurrentFace.end(); ++it)
- {
- if (!isBoneUsed[*it])
- {
- isBoneUsed[*it] = true;
- numBones++;
- }
+ for (std::set::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::vectormNumVertices = numSubMeshVertices;
newMesh->mNumFaces = static_cast(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::vectormFaces = new aiFace[subMeshFaces.size()];
unsigned int nvi = 0; // next vertex index
std::vector previousVertexIndices( numSubMeshVertices, std::numeric_limits::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::vectormBones = new aiBone*[numBones];
std::vector mappedBoneIndex( pMesh->mNumBones, std::numeric_limits::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::vectormNumBones == 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& 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::max() )
- {
+ if( newBoneIndex != std::numeric_limits::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& 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::max() );
aiVertexWeight* dstWeight = newMesh->mBones[newBoneIndex]->mWeights + newMesh->mBones[newBoneIndex]->mNumWeights;
@@ -450,14 +396,11 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vectormNumMeshes > 0 )
- {
+ if( pNode->mNumMeshes == 0 ) {
std::vector 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& 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]);
}
}
diff --git a/code/PostProcessing/SplitByBoneCountProcess.h b/code/PostProcessing/SplitByBoneCountProcess.h
index 938b00c7f..625019e0c 100644
--- a/code/PostProcessing/SplitByBoneCountProcess.h
+++ b/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
#include
-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;
+ /// @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;
- /** 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 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.
diff --git a/code/PostProcessing/SplitLargeMeshes.cpp b/code/PostProcessing/SplitLargeMeshes.cpp
index 151ac4991..73e0cc5d8 100644
--- a/code/PostProcessing/SplitLargeMeshes.cpp
+++ b/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 {
diff --git a/code/PostProcessing/SplitLargeMeshes.h b/code/PostProcessing/SplitLargeMeshes.h
index e5a8d4c1b..4e0d764c1 100644
--- a/code/PostProcessing/SplitLargeMeshes.h
+++ b/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
diff --git a/code/PostProcessing/TextureTransform.cpp b/code/PostProcessing/TextureTransform.cpp
index efbf4d2c6..2ed17f390 100644
--- a/code/PostProcessing/TextureTransform.cpp
+++ b/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((info.mRotation / static_cast(AI_MATH_TWO_PI)));
- if (rounded)
- {
+ if (rounded) {
out -= rounded * static_cast(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& l, unsigned int n)
-{
+void UpdateUVIndex(const std::list& l, unsigned int n) {
// Don't set if == 0 && wasn't set before
for (std::list::const_iterator it = l.begin();it != l.end(); ++it) {
const TTUpdateInfo& info = *it;
@@ -203,8 +191,7 @@ void UpdateUVIndex(const std::list& 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");
diff --git a/code/PostProcessing/TextureTransform.h b/code/PostProcessing/TextureTransform.h
index c1cccf8ef..c9f0480ba 100644
--- a/code/PostProcessing/TextureTransform.h
+++ b/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
diff --git a/code/PostProcessing/TriangulateProcess.cpp b/code/PostProcessing/TriangulateProcess.cpp
index 52e760361..52cfa66bf 100644
--- a/code/PostProcessing/TriangulateProcess.cpp
+++ b/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) {
diff --git a/code/PostProcessing/TriangulateProcess.h b/code/PostProcessing/TriangulateProcess.h
index ed5f4a587..ac31e4377 100644
--- a/code/PostProcessing/TriangulateProcess.h
+++ b/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.
diff --git a/code/PostProcessing/ValidateDataStructure.cpp b/code/PostProcessing/ValidateDataStructure.cpp
index d234e220b..e31054972 100644
--- a/code/PostProcessing/ValidateDataStructure.cpp
+++ b/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);
+ }
}
}
}
diff --git a/code/PostProcessing/ValidateDataStructure.h b/code/PostProcessing/ValidateDataStructure.h
index 077a47b70..9cfd4ced1 100644
--- a/code/PostProcessing/ValidateDataStructure.h
+++ b/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();
-
-public:
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
+ ~ValidateDSProcess() override = default;
// -------------------------------------------------------------------
- void Execute( aiScene* pScene);
+ bool IsActive( unsigned int pFlags) const override;
+
+ // -------------------------------------------------------------------
+ void Execute( aiScene* pScene) override;
protected:
-
// -------------------------------------------------------------------
/** Report a validation error. This will throw an exception,
* control won't return.
diff --git a/contrib/stb/stb_image.h b/contrib/stb/stb_image.h
index 8d173c66a..5e807a0a6 100644
--- a/contrib/stb/stb_image.h
+++ b/contrib/stb/stb_image.h
@@ -1,4 +1,4 @@
-/* stb_image - v2.26 - public domain image loader - http://nothings.org/stb
+/* stb_image - v2.28 - public domain image loader - http://nothings.org/stb
no warranty implied; use at your own risk
Do this:
@@ -48,6 +48,8 @@ LICENSE
RECENT REVISION HISTORY:
+ 2.28 (2023-01-29) many error fixes, security errors, just tons of stuff
+ 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
2.26 (2020-07-13) many minor fixes
2.25 (2020-02-02) fix warnings
2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically
@@ -89,7 +91,7 @@ RECENT REVISION HISTORY:
Jeremy Sawicki (handle all ImageNet JPGs)
Optimizations & bugfixes Mikhail Morozov (1-bit BMP)
Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query)
- Arseny Kapoulkine
+ Arseny Kapoulkine Simon Breuss (16-bit PNM)
John-Mark Allen
Carmelo J Fdez-Aguera
@@ -102,19 +104,21 @@ RECENT REVISION HISTORY:
Thomas Ruf Ronny Chevalier github:rlyeh
Janez Zemva John Bartholomew Michal Cichon github:romigrou
Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
- Laurent Gomila Cort Stratton github:snagar
+ Eugene Golushkov Laurent Gomila Cort Stratton github:snagar
Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex
Cass Everitt Ryamond Barbiero github:grim210
Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
- Josh Tobin Matthew Gregan github:poppolopoppo
+ Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
- Brad Weinberger Matvey Cherevko [reserved]
+ Brad Weinberger Matvey Cherevko github:mosra
Luca Sas Alexander Veselov Zack Middleton [reserved]
Ryan C. Gordon [reserved] [reserved]
DO NOT ADD YOUR NAME HERE
+ Jacko Dirks
+
To add your name to the credits, pick a random blank space in the middle and fill it.
80% of merge conflicts on stb PRs are due to people adding their name at the end
of the credits.
@@ -137,7 +141,7 @@ RECENT REVISION HISTORY:
// // ... x = width, y = height, n = # 8-bit components per pixel ...
// // ... replace '0' with '1'..'4' to force that many components per pixel
// // ... but 'n' will always be the number that it would have been if you said 0
-// stbi_image_free(data)
+// stbi_image_free(data);
//
// Standard parameters:
// int *x -- outputs image width in pixels
@@ -176,6 +180,32 @@ RECENT REVISION HISTORY:
//
// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized.
//
+// To query the width, height and component count of an image without having to
+// decode the full file, you can use the stbi_info family of functions:
+//
+// int x,y,n,ok;
+// ok = stbi_info(filename, &x, &y, &n);
+// // returns ok=1 and sets x, y, n if image is a supported format,
+// // 0 otherwise.
+//
+// Note that stb_image pervasively uses ints in its public API for sizes,
+// including sizes of memory buffers. This is now part of the API and thus
+// hard to change without causing breakage. As a result, the various image
+// loaders all have certain limits on image size; these differ somewhat
+// by format but generally boil down to either just under 2GB or just under
+// 1GB. When the decoded image would be larger than this, stb_image decoding
+// will fail.
+//
+// Additionally, stb_image will reject image files that have any of their
+// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS,
+// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit,
+// the only way to have an image with such dimensions load correctly
+// is for it to have a rather extreme aspect ratio. Either way, the
+// assumption here is that such larger images are likely to be malformed
+// or malicious. If you do need to load an image with individual dimensions
+// larger than that, and it still fits in the overall size limit, you can
+// #define STBI_MAX_DIMENSIONS on your own to be something larger.
+//
// ===========================================================================
//
// UNICODE:
@@ -281,11 +311,10 @@ RECENT REVISION HISTORY:
//
// iPhone PNG support:
//
-// By default we convert iphone-formatted PNGs back to RGB, even though
-// they are internally encoded differently. You can disable this conversion
-// by calling stbi_convert_iphone_png_to_rgb(0), in which case
-// you will always just get the native iphone "format" through (which
-// is BGR stored in RGB).
+// We optionally support converting iPhone-formatted PNGs (which store
+// premultiplied BGRA) back to RGB, even though they're internally encoded
+// differently. To enable this conversion, call
+// stbi_convert_iphone_png_to_rgb(1).
//
// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per
// pixel to remove any premultiplied alpha *only* if the image file explicitly
@@ -489,6 +518,8 @@ STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
// as above, but only applies to images loaded on the thread that calls the function
// this function is only available if your compiler supports thread-local variables;
// calling it will fail to link if your compiler doesn't
+STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply);
+STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert);
STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip);
// ZLIB client - used by PNG, available for other purposes
@@ -605,7 +636,7 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
#endif
#endif
-#ifdef _MSC_VER
+#if defined(_MSC_VER) || defined(__SYMBIAN32__)
typedef unsigned short stbi__uint16;
typedef signed short stbi__int16;
typedef unsigned int stbi__uint32;
@@ -634,7 +665,7 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#ifdef STBI_HAS_LROTL
#define stbi_lrot(x,y) _lrotl(x,y)
#else
- #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
+ #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31)))
#endif
#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
@@ -748,9 +779,12 @@ static int stbi__sse2_available(void)
#ifdef STBI_NEON
#include
-// assume GCC or Clang on ARM targets
+#ifdef _MSC_VER
+#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
+#else
#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
#endif
+#endif
#ifndef STBI_SIMD_ALIGN
#define STBI_SIMD_ALIGN(type, name) type name
@@ -924,6 +958,7 @@ static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp);
static int stbi__pnm_test(stbi__context *s);
static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
+static int stbi__pnm_is16(stbi__context *s);
#endif
static
@@ -998,7 +1033,7 @@ static int stbi__mad3sizes_valid(int a, int b, int c, int add)
}
// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow
-#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
+#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM)
static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
{
return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
@@ -1021,7 +1056,7 @@ static void *stbi__malloc_mad3(int a, int b, int c, int add)
return stbi__malloc(a*b*c + add);
}
-#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
+#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM)
static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
{
if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL;
@@ -1029,6 +1064,23 @@ static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
}
#endif
+// returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow.
+static int stbi__addints_valid(int a, int b)
+{
+ if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow
+ if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0.
+ return a <= INT_MAX - b;
+}
+
+// returns 1 if the product of two signed shorts is valid, 0 on overflow.
+static int stbi__mul2shorts_valid(short a, short b)
+{
+ if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow
+ if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid
+ if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN
+ return a >= SHRT_MIN / b;
+}
+
// stbi__err - error
// stbi__errpf - error returning pointer to float
// stbi__errpuc - error returning pointer to unsigned char
@@ -1087,9 +1139,8 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
ri->num_channels = 0;
- #ifndef STBI_NO_JPEG
- if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
- #endif
+ // test the formats with a very explicit header first (at least a FOURCC
+ // or distinctive magic number first)
#ifndef STBI_NO_PNG
if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri);
#endif
@@ -1107,6 +1158,13 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
#ifndef STBI_NO_PIC
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri);
#endif
+
+ // then the formats that can end up attempting to load with just 1 or 2
+ // bytes matching expectations; these are prone to false positives, so
+ // try them later
+ #ifndef STBI_NO_JPEG
+ if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
+ #endif
#ifndef STBI_NO_PNM
if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri);
#endif
@@ -1262,12 +1320,12 @@ static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, in
#ifndef STBI_NO_STDIO
-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
+#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
#endif
-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
+#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
{
return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
@@ -1277,16 +1335,16 @@ STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wch
static FILE *stbi__fopen(char const *filename, char const *mode)
{
FILE *f;
-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
+#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
wchar_t wMode[64];
wchar_t wFilename[1024];
- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename)))
return 0;
- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
return 0;
-#if _MSC_VER >= 1400
+#if defined(_MSC_VER) && _MSC_VER >= 1400
if (0 != _wfopen_s(&f, wFilename, wMode))
f = 0;
#else
@@ -1662,7 +1720,8 @@ static int stbi__get16le(stbi__context *s)
static stbi__uint32 stbi__get32le(stbi__context *s)
{
stbi__uint32 z = stbi__get16le(s);
- return z + (stbi__get16le(s) << 16);
+ z += (stbi__uint32)stbi__get16le(s) << 16;
+ return z;
}
#endif
@@ -1944,9 +2003,12 @@ static int stbi__build_huffman(stbi__huffman *h, int *count)
int i,j,k=0;
unsigned int code;
// build size list for each symbol (from JPEG spec)
- for (i=0; i < 16; ++i)
- for (j=0; j < count[i]; ++j)
+ for (i=0; i < 16; ++i) {
+ for (j=0; j < count[i]; ++j) {
h->size[k++] = (stbi_uc) (i+1);
+ if(k >= 257) return stbi__err("bad size list","Corrupt JPEG");
+ }
+ }
h->size[k] = 0;
// compute actual symbols (from jpeg spec)
@@ -2071,6 +2133,8 @@ stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h)
// convert the huffman code to the symbol id
c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k];
+ if(c < 0 || c >= 256) // symbol id out of bounds!
+ return -1;
STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]);
// convert the id to a symbol
@@ -2089,14 +2153,14 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
unsigned int k;
int sgn;
if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
+ if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing
- sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
+ sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative)
k = stbi_lrot(j->code_buffer, n);
- if (n < 0 || n >= (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))) return 0;
j->code_buffer = k & ~stbi__bmask[n];
k &= stbi__bmask[n];
j->code_bits -= n;
- return k + (stbi__jbias[n] & ~sgn);
+ return k + (stbi__jbias[n] & (sgn - 1));
}
// get some unsigned bits
@@ -2104,6 +2168,7 @@ stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n)
{
unsigned int k;
if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
+ if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing
k = stbi_lrot(j->code_buffer, n);
j->code_buffer = k & ~stbi__bmask[n];
k &= stbi__bmask[n];
@@ -2115,6 +2180,7 @@ stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j)
{
unsigned int k;
if (j->code_bits < 1) stbi__grow_buffer_unsafe(j);
+ if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing
k = j->code_buffer;
j->code_buffer <<= 1;
--j->code_bits;
@@ -2146,14 +2212,16 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
t = stbi__jpeg_huff_decode(j, hdc);
- if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG");
+ if (t < 0 || t > 15) return stbi__err("bad huffman code","Corrupt JPEG");
// 0 all the ac values now so we can do it 32-bits at a time
memset(data,0,64*sizeof(data[0]));
diff = t ? stbi__extend_receive(j, t) : 0;
+ if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta","Corrupt JPEG");
dc = j->img_comp[b].dc_pred + diff;
j->img_comp[b].dc_pred = dc;
+ if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
data[0] = (short) (dc * dequant[0]);
// decode AC components, see JPEG spec
@@ -2167,6 +2235,7 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
if (r) { // fast-AC path
k += (r >> 4) & 15; // run
s = r & 15; // combined length
+ if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available");
j->code_buffer <<= s;
j->code_bits -= s;
// decode into unzigzag'd location
@@ -2203,12 +2272,14 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
// first scan for DC coefficient, must be first
memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
t = stbi__jpeg_huff_decode(j, hdc);
- if (t == -1) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
+ if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
diff = t ? stbi__extend_receive(j, t) : 0;
+ if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG");
dc = j->img_comp[b].dc_pred + diff;
j->img_comp[b].dc_pred = dc;
- data[0] = (short) (dc << j->succ_low);
+ if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
+ data[0] = (short) (dc * (1 << j->succ_low));
} else {
// refinement scan for DC coefficient
if (stbi__jpeg_get_bit(j))
@@ -2242,10 +2313,11 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
if (r) { // fast-AC path
k += (r >> 4) & 15; // run
s = r & 15; // combined length
+ if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available");
j->code_buffer <<= s;
j->code_bits -= s;
zig = stbi__jpeg_dezigzag[k++];
- data[zig] = (short) ((r >> 8) << shift);
+ data[zig] = (short) ((r >> 8) * (1 << shift));
} else {
int rs = stbi__jpeg_huff_decode(j, hac);
if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
@@ -2263,7 +2335,7 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
} else {
k += r;
zig = stbi__jpeg_dezigzag[k++];
- data[zig] = (short) (stbi__extend_receive(j,s) << shift);
+ data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift));
}
}
} while (k <= j->spec_end);
@@ -3062,6 +3134,7 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
sizes[i] = stbi__get8(z->s);
n += sizes[i];
}
+ if(n > 256) return stbi__err("bad DHT header","Corrupt JPEG"); // Loop over i < n would write past end of values!
L -= 17;
if (tc == 0) {
if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0;
@@ -3227,6 +3300,13 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v;
}
+ // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios
+ // and I've never seen a non-corrupted JPEG file actually use them
+ for (i=0; i < s->img_n; ++i) {
+ if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H","Corrupt JPEG");
+ if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V","Corrupt JPEG");
+ }
+
// compute interleaved mcu info
z->img_h_max = h_max;
z->img_v_max = v_max;
@@ -3304,6 +3384,28 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
return 1;
}
+static int stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
+{
+ // some JPEGs have junk at end, skip over it but if we find what looks
+ // like a valid marker, resume there
+ while (!stbi__at_eof(j->s)) {
+ int x = stbi__get8(j->s);
+ while (x == 255) { // might be a marker
+ if (stbi__at_eof(j->s)) return STBI__MARKER_none;
+ x = stbi__get8(j->s);
+ if (x != 0x00 && x != 0xff) {
+ // not a stuffed zero or lead-in to another marker, looks
+ // like an actual marker, return it
+ return x;
+ }
+ // stuffed zero has x=0 now which ends the loop, meaning we go
+ // back to regular scan loop.
+ // repeated 0xff keeps trying to read the next byte of the marker.
+ }
+ }
+ return STBI__MARKER_none;
+}
+
// decode image to YCbCr format
static int stbi__decode_jpeg_image(stbi__jpeg *j)
{
@@ -3320,25 +3422,22 @@ static int stbi__decode_jpeg_image(stbi__jpeg *j)
if (!stbi__process_scan_header(j)) return 0;
if (!stbi__parse_entropy_coded_data(j)) return 0;
if (j->marker == STBI__MARKER_none ) {
- // handle 0s at the end of image data from IP Kamera 9060
- while (!stbi__at_eof(j->s)) {
- int x = stbi__get8(j->s);
- if (x == 255) {
- j->marker = stbi__get8(j->s);
- break;
- }
- }
+ j->marker = stbi__skip_jpeg_junk_at_end(j);
// if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
}
+ m = stbi__get_marker(j);
+ if (STBI__RESTART(m))
+ m = stbi__get_marker(j);
} else if (stbi__DNL(m)) {
int Ld = stbi__get16be(j->s);
stbi__uint32 NL = stbi__get16be(j->s);
if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG");
if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG");
+ m = stbi__get_marker(j);
} else {
- if (!stbi__process_marker(j, m)) return 0;
+ if (!stbi__process_marker(j, m)) return 1;
+ m = stbi__get_marker(j);
}
- m = stbi__get_marker(j);
}
if (j->progressive)
stbi__jpeg_finish(j);
@@ -3782,6 +3881,10 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
else
decode_n = z->s->img_n;
+ // nothing to do if no components requested; check this now to avoid
+ // accessing uninitialized coutput[0] later
+ if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; }
+
// resample and color-convert
{
int k;
@@ -3924,6 +4027,8 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re
{
unsigned char* result;
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
+ if (!j) return stbi__errpuc("outofmem", "Out of memory");
+ memset(j, 0, sizeof(stbi__jpeg));
STBI_NOTUSED(ri);
j->s = s;
stbi__setup_jpeg(j);
@@ -3936,6 +4041,8 @@ static int stbi__jpeg_test(stbi__context *s)
{
int r;
stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
+ if (!j) return stbi__err("outofmem", "Out of memory");
+ memset(j, 0, sizeof(stbi__jpeg));
j->s = s;
stbi__setup_jpeg(j);
r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
@@ -3960,6 +4067,8 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
{
int result;
stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
+ if (!j) return stbi__err("outofmem", "Out of memory");
+ memset(j, 0, sizeof(stbi__jpeg));
j->s = s;
result = stbi__jpeg_info_raw(j, x, y, comp);
STBI_FREE(j);
@@ -3979,6 +4088,7 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
// fast-way is faster to check than jpeg huffman, but slow way is slower
#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables
#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1)
+#define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet
// zlib-style huffman encoding
// (jpegs packs from left, zlib from right, so can't share code)
@@ -3988,8 +4098,8 @@ typedef struct
stbi__uint16 firstcode[16];
int maxcode[17];
stbi__uint16 firstsymbol[16];
- stbi_uc size[288];
- stbi__uint16 value[288];
+ stbi_uc size[STBI__ZNSYMS];
+ stbi__uint16 value[STBI__ZNSYMS];
} stbi__zhuffman;
stbi_inline static int stbi__bitreverse16(int n)
@@ -4120,7 +4230,7 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
if (s >= 16) return -1; // invalid code!
// code size is s, so:
b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
- if ((unsigned int)b >= sizeof (z->size)) return -1; // some data was corrupt somewhere!
+ if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere!
if (z->size[b] != s) return -1; // was originally an assert, but report failure instead.
a->code_buffer >>= s;
a->num_bits -= s;
@@ -4201,11 +4311,12 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
a->zout = zout;
return 1;
}
+ if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data
z -= 257;
len = stbi__zlength_base[z];
if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]);
z = stbi__zhuffman_decode(a, &a->z_distance);
- if (z < 0) return stbi__err("bad huffman code","Corrupt PNG");
+ if (z < 0 || z >= 30) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data
dist = stbi__zdist_base[z];
if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]);
if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG");
@@ -4317,7 +4428,7 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
return 1;
}
-static const stbi_uc stbi__zdefault_length[288] =
+static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] =
{
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
@@ -4363,7 +4474,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
} else {
if (type == 1) {
// use fixed code lengths
- if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0;
+ if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , STBI__ZNSYMS)) return 0;
if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0;
} else {
if (!stbi__compute_huffman_codes(a)) return 0;
@@ -4759,6 +4870,7 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint3
// de-interlacing
final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0);
+ if (!final) return stbi__err("outofmem", "Out of memory");
for (p=0; p < 7; ++p) {
int xorig[] = { 0,4,0,2,0,1,0 };
int yorig[] = { 0,0,4,0,2,0,1 };
@@ -4879,19 +4991,46 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int
return 1;
}
-static int stbi__unpremultiply_on_load = 0;
-static int stbi__de_iphone_flag = 0;
+static int stbi__unpremultiply_on_load_global = 0;
+static int stbi__de_iphone_flag_global = 0;
STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply)
{
- stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply;
+ stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply;
}
STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)
{
- stbi__de_iphone_flag = flag_true_if_should_convert;
+ stbi__de_iphone_flag_global = flag_true_if_should_convert;
}
+#ifndef STBI_THREAD_LOCAL
+#define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global
+#define stbi__de_iphone_flag stbi__de_iphone_flag_global
+#else
+static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set;
+static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set;
+
+STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply)
+{
+ stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply;
+ stbi__unpremultiply_on_load_set = 1;
+}
+
+STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert)
+{
+ stbi__de_iphone_flag_local = flag_true_if_should_convert;
+ stbi__de_iphone_flag_set = 1;
+}
+
+#define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \
+ ? stbi__unpremultiply_on_load_local \
+ : stbi__unpremultiply_on_load_global)
+#define stbi__de_iphone_flag (stbi__de_iphone_flag_set \
+ ? stbi__de_iphone_flag_local \
+ : stbi__de_iphone_flag_global)
+#endif // STBI_THREAD_LOCAL
+
static void stbi__de_iphone(stbi__png *z)
{
stbi__context *s = z->s;
@@ -4941,7 +5080,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
{
stbi_uc palette[1024], pal_img_n=0;
stbi_uc has_trans=0, tc[3]={0};
- stbi__uint16 tc16[3]={0};
+ stbi__uint16 tc16[3];
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
int first=1,k,interlace=0, color=0, is_iphone=0;
stbi__context *s = z->s;
@@ -4981,14 +5120,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (!pal_img_n) {
s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0);
if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode");
- if (scan == STBI__SCAN_header) return 1;
} else {
// if paletted, then pal_n is our final components, and
// img_n is # components to decompress/filter.
s->img_n = 1;
if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG");
- // if SCAN_header, have to scan to see if we have a tRNS
}
+ // even with SCAN_header, have to scan to see if we have a tRNS
break;
}
@@ -5020,6 +5158,8 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
has_trans = 1;
+ // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now.
+ if (scan == STBI__SCAN_header) { ++s->img_n; return 1; }
if (z->depth == 16) {
for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
} else {
@@ -5032,7 +5172,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
case STBI__PNG_TYPE('I','D','A','T'): {
if (first) return stbi__err("first not IHDR", "Corrupt PNG");
if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG");
- if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; }
+ if (scan == STBI__SCAN_header) {
+ // header scan definitely stops at first IDAT
+ if (pal_img_n)
+ s->img_n = pal_img_n;
+ return 1;
+ }
+ if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes");
if ((int)(ioff + c.length) < (int)ioff) return 0;
if (ioff + c.length > idata_limit) {
stbi__uint32 idata_limit_old = idata_limit;
@@ -5272,6 +5418,32 @@ typedef struct
int extra_read;
} stbi__bmp_data;
+static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress)
+{
+ // BI_BITFIELDS specifies masks explicitly, don't override
+ if (compress == 3)
+ return 1;
+
+ if (compress == 0) {
+ if (info->bpp == 16) {
+ info->mr = 31u << 10;
+ info->mg = 31u << 5;
+ info->mb = 31u << 0;
+ } else if (info->bpp == 32) {
+ info->mr = 0xffu << 16;
+ info->mg = 0xffu << 8;
+ info->mb = 0xffu << 0;
+ info->ma = 0xffu << 24;
+ info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
+ } else {
+ // otherwise, use defaults, which is all-0
+ info->mr = info->mg = info->mb = info->ma = 0;
+ }
+ return 1;
+ }
+ return 0; // error
+}
+
static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
{
int hsz;
@@ -5299,6 +5471,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
if (hsz != 12) {
int compress = stbi__get32le(s);
if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
+ if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes
+ if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel
stbi__get32le(s); // discard sizeof
stbi__get32le(s); // discard hres
stbi__get32le(s); // discard vres
@@ -5313,17 +5487,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
}
if (info->bpp == 16 || info->bpp == 32) {
if (compress == 0) {
- if (info->bpp == 32) {
- info->mr = 0xffu << 16;
- info->mg = 0xffu << 8;
- info->mb = 0xffu << 0;
- info->ma = 0xffu << 24;
- info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
- } else {
- info->mr = 31u << 10;
- info->mg = 31u << 5;
- info->mb = 31u << 0;
- }
+ stbi__bmp_set_mask_defaults(info, compress);
} else if (compress == 3) {
info->mr = stbi__get32le(s);
info->mg = stbi__get32le(s);
@@ -5338,6 +5502,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
return stbi__errpuc("bad BMP", "bad BMP");
}
} else {
+ // V4/V5 header
int i;
if (hsz != 108 && hsz != 124)
return stbi__errpuc("bad BMP", "bad BMP");
@@ -5345,6 +5510,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
info->mg = stbi__get32le(s);
info->mb = stbi__get32le(s);
info->ma = stbi__get32le(s);
+ if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs
+ stbi__bmp_set_mask_defaults(info, compress);
stbi__get32le(s); // discard color space
for (i=0; i < 12; ++i)
stbi__get32le(s); // discard color space parameters
@@ -5394,9 +5561,22 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
psize = (info.offset - info.extra_read - info.hsz) >> 2;
}
if (psize == 0) {
- STBI_ASSERT(info.offset == s->callback_already_read + (int) (s->img_buffer - s->img_buffer_original));
- if (info.offset != s->callback_already_read + (s->img_buffer - s->buffer_start)) {
- return stbi__errpuc("bad offset", "Corrupt BMP");
+ // accept some number of extra bytes after the header, but if the offset points either to before
+ // the header ends or implies a large amount of extra data, reject the file as malformed
+ int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original);
+ int header_limit = 1024; // max we actually read is below 256 bytes currently.
+ int extra_data_limit = 256*4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size.
+ if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) {
+ return stbi__errpuc("bad header", "Corrupt BMP");
+ }
+ // we established that bytes_read_so_far is positive and sensible.
+ // the first half of this test rejects offsets that are either too small positives, or
+ // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn
+ // ensures the number computed in the second half of the test can't overflow.
+ if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) {
+ return stbi__errpuc("bad offset", "Corrupt BMP");
+ } else {
+ stbi__skip(s, info.offset - bytes_read_so_far);
}
}
@@ -6342,6 +6522,7 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c
// intermediate buffer is RGBA
result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0);
+ if (!result) return stbi__errpuc("outofmem", "Out of memory");
memset(result, 0xff, x*y*4);
if (!stbi__pic_load_core(s,x,y,comp, result)) {
@@ -6457,6 +6638,7 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
{
stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
+ if (!g) return stbi__err("outofmem", "Out of memory");
if (!stbi__gif_header(s, g, comp, 1)) {
STBI_FREE(g);
stbi__rewind( s );
@@ -6766,6 +6948,17 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
}
}
+static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **delays)
+{
+ STBI_FREE(g->out);
+ STBI_FREE(g->history);
+ STBI_FREE(g->background);
+
+ if (out) STBI_FREE(out);
+ if (delays && *delays) STBI_FREE(*delays);
+ return stbi__errpuc("outofmem", "Out of memory");
+}
+
static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
{
if (stbi__gif_test(s)) {
@@ -6775,6 +6968,12 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
stbi_uc *two_back = 0;
stbi__gif g;
int stride;
+ int out_size = 0;
+ int delays_size = 0;
+
+ STBI_NOTUSED(out_size);
+ STBI_NOTUSED(delays_size);
+
memset(&g, 0, sizeof(g));
if (delays) {
*delays = 0;
@@ -6791,24 +6990,31 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
stride = g.w * g.h * 4;
if (out) {
- void *tmp = (stbi_uc*) STBI_REALLOC( out, layers * stride );
- if (NULL == tmp) {
- STBI_FREE(g.out);
- STBI_FREE(g.history);
- STBI_FREE(g.background);
- return stbi__errpuc("outofmem", "Out of memory");
- }
+ void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride );
+ if (!tmp)
+ return stbi__load_gif_main_outofmem(&g, out, delays);
else {
out = (stbi_uc*) tmp;
+ out_size = layers * stride;
}
if (delays) {
- *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
+ int *new_delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers );
+ if (!new_delays)
+ return stbi__load_gif_main_outofmem(&g, out, delays);
+ *delays = new_delays;
+ delays_size = layers * sizeof(int);
}
} else {
out = (stbi_uc*)stbi__malloc( layers * stride );
+ if (!out)
+ return stbi__load_gif_main_outofmem(&g, out, delays);
+ out_size = layers * stride;
if (delays) {
*delays = (int*) stbi__malloc( layers * sizeof(int) );
+ if (!*delays)
+ return stbi__load_gif_main_outofmem(&g, out, delays);
+ delays_size = layers * sizeof(int);
}
}
memcpy( out + ((layers - 1) * stride), u, stride );
@@ -7058,12 +7264,12 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
// Run
value = stbi__get8(s);
count -= 128;
- if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
+ if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
for (z = 0; z < count; ++z)
scanline[i++ * 4 + k] = value;
} else {
// Dump
- if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
+ if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
for (z = 0; z < count; ++z)
scanline[i++ * 4 + k] = stbi__get8(s);
}
@@ -7132,9 +7338,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
info.all_a = 255;
p = stbi__bmp_parse_header(s, &info);
- stbi__rewind( s );
- if (p == NULL)
+ if (p == NULL) {
+ stbi__rewind( s );
return 0;
+ }
if (x) *x = s->img_x;
if (y) *y = s->img_y;
if (comp) {
@@ -7200,8 +7407,8 @@ static int stbi__psd_is16(stbi__context *s)
stbi__rewind( s );
return 0;
}
- (void) stbi__get32be(s);
- (void) stbi__get32be(s);
+ STBI_NOTUSED(stbi__get32be(s));
+ STBI_NOTUSED(stbi__get32be(s));
depth = stbi__get16be(s);
if (depth != 16) {
stbi__rewind( s );
@@ -7280,7 +7487,6 @@ static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
// Known limitations:
// Does not support comments in the header section
// Does not support ASCII image data (formats P2 and P3)
-// Does not support 16-bit-per-channel
#ifndef STBI_NO_PNM
@@ -7301,7 +7507,8 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
stbi_uc *out;
STBI_NOTUSED(ri);
- if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
+ ri->bits_per_channel = stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n);
+ if (ri->bits_per_channel == 0)
return 0;
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
@@ -7311,15 +7518,22 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
*y = s->img_y;
if (comp) *comp = s->img_n;
- if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0))
+ if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0))
return stbi__errpuc("too large", "PNM too large");
- out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0);
+ out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0);
if (!out) return stbi__errpuc("outofmem", "Out of memory");
- stbi__getn(s, out, s->img_n * s->img_x * s->img_y);
+ if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) {
+ STBI_FREE(out);
+ return stbi__errpuc("bad PNM", "PNM file truncated");
+ }
if (req_comp && req_comp != s->img_n) {
- out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
+ if (ri->bits_per_channel == 16) {
+ out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y);
+ } else {
+ out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
+ }
if (out == NULL) return out; // stbi__convert_format frees input on failure
}
return out;
@@ -7356,6 +7570,8 @@ static int stbi__pnm_getinteger(stbi__context *s, char *c)
while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) {
value = value*10 + (*c - '0');
*c = (char) stbi__get8(s);
+ if((value > 214748364) || (value == 214748364 && *c > '7'))
+ return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int");
}
return value;
@@ -7386,17 +7602,29 @@ static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
stbi__pnm_skip_whitespace(s, &c);
*x = stbi__pnm_getinteger(s, &c); // read width
+ if(*x == 0)
+ return stbi__err("invalid width", "PPM image header had zero or overflowing width");
stbi__pnm_skip_whitespace(s, &c);
*y = stbi__pnm_getinteger(s, &c); // read height
+ if (*y == 0)
+ return stbi__err("invalid width", "PPM image header had zero or overflowing width");
stbi__pnm_skip_whitespace(s, &c);
maxv = stbi__pnm_getinteger(s, &c); // read max value
-
- if (maxv > 255)
- return stbi__err("max value > 255", "PPM image not 8-bit");
+ if (maxv > 65535)
+ return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images");
+ else if (maxv > 255)
+ return 16;
else
- return 1;
+ return 8;
+}
+
+static int stbi__pnm_is16(stbi__context *s)
+{
+ if (stbi__pnm_info(s, NULL, NULL, NULL) == 16)
+ return 1;
+ return 0;
}
#endif
@@ -7452,6 +7680,9 @@ static int stbi__is_16_main(stbi__context *s)
if (stbi__psd_is16(s)) return 1;
#endif
+ #ifndef STBI_NO_PNM
+ if (stbi__pnm_is16(s)) return 1;
+ #endif
return 0;
}
diff --git a/contrib/unzip/crypt.c b/contrib/unzip/crypt.c
index 4cc731b3e..cc6650630 100644
--- a/contrib/unzip/crypt.c
+++ b/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)
{
diff --git a/contrib/zlib/CMakeLists.txt b/contrib/zlib/CMakeLists.txt
index 469151ff6..5bc2d6065 100644
--- a/contrib/zlib/CMakeLists.txt
+++ b/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)
diff --git a/port/PyAssimp/pyassimp/core.py b/port/PyAssimp/pyassimp/core.py
index 35ad882b3..edde8b29a 100644
--- a/port/PyAssimp/pyassimp/core.py
+++ b/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):
diff --git a/test/models-nonbsd/BLEND/guard1_body.png b/test/models-nonbsd/BLEND/guard1_body.png
new file mode 100644
index 000000000..2eb3f2caa
Binary files /dev/null and b/test/models-nonbsd/BLEND/guard1_body.png differ
diff --git a/test/models-nonbsd/BLEND/guard1_face.png b/test/models-nonbsd/BLEND/guard1_face.png
new file mode 100644
index 000000000..b7e17d375
Binary files /dev/null and b/test/models-nonbsd/BLEND/guard1_face.png differ
diff --git a/test/models-nonbsd/BLEND/guard1_helmet.png b/test/models-nonbsd/BLEND/guard1_helmet.png
new file mode 100644
index 000000000..166d790fd
Binary files /dev/null and b/test/models-nonbsd/BLEND/guard1_helmet.png differ
diff --git a/test/models-nonbsd/BLEND/iron_grill.png b/test/models-nonbsd/BLEND/iron_grill.png
new file mode 100644
index 000000000..53a3bbbcc
Binary files /dev/null and b/test/models-nonbsd/BLEND/iron_grill.png differ
diff --git a/test/models-nonbsd/BLEND/round_grill.png b/test/models-nonbsd/BLEND/round_grill.png
new file mode 100644
index 000000000..502a1d782
Binary files /dev/null and b/test/models-nonbsd/BLEND/round_grill.png differ
diff --git a/test/models-nonbsd/IRR/skybox.xml b/test/models-nonbsd/IRR/skybox.xml
index a572e473f..a2be5b785 100644
Binary files a/test/models-nonbsd/IRR/skybox.xml and b/test/models-nonbsd/IRR/skybox.xml differ
diff --git a/test/models-nonbsd/IRR/skybox_UTF16LE.xml b/test/models-nonbsd/IRR/skybox_UTF16LE.xml
new file mode 100644
index 000000000..a572e473f
Binary files /dev/null and b/test/models-nonbsd/IRR/skybox_UTF16LE.xml differ
diff --git a/test/models/COB/axe.jpg b/test/models/COB/axe.jpg
new file mode 100644
index 000000000..ba14ae0ea
Binary files /dev/null and b/test/models/COB/axe.jpg differ
diff --git a/test/models/COB/dwarf.jpg b/test/models/COB/dwarf.jpg
new file mode 100644
index 000000000..9c07e0038
Binary files /dev/null and b/test/models/COB/dwarf.jpg differ
diff --git a/test/models/COB/dwarf2.jpg b/test/models/COB/dwarf2.jpg
new file mode 100644
index 000000000..cf54b0657
Binary files /dev/null and b/test/models/COB/dwarf2.jpg differ
diff --git a/test/models/IRR/1.png b/test/models/IRR/1.png
new file mode 100644
index 000000000..e7200658b
Binary files /dev/null and b/test/models/IRR/1.png differ
diff --git a/test/models/IRR/EpisodeII_TheDwarfesStrikeBack.irr b/test/models/IRR/EpisodeII_TheDwarfesStrikeBack.irr
index 1f0916d4d..94d0bae6f 100644
Binary files a/test/models/IRR/EpisodeII_TheDwarfesStrikeBack.irr and b/test/models/IRR/EpisodeII_TheDwarfesStrikeBack.irr differ
diff --git a/test/models/IRR/EpisodeII_TheDwarfesStrikeBack_UTF16LE.irr b/test/models/IRR/EpisodeII_TheDwarfesStrikeBack_UTF16LE.irr
new file mode 100644
index 000000000..1f0916d4d
Binary files /dev/null and b/test/models/IRR/EpisodeII_TheDwarfesStrikeBack_UTF16LE.irr differ
diff --git a/test/models/IRR/EpisodeI_ANewDwarf.irr b/test/models/IRR/EpisodeI_ANewDwarf.irr
index 39d99e440..6daeec96c 100644
Binary files a/test/models/IRR/EpisodeI_ANewDwarf.irr and b/test/models/IRR/EpisodeI_ANewDwarf.irr differ
diff --git a/test/models/IRR/EpisodeI_ANewDwarf_UTF16LE.irr b/test/models/IRR/EpisodeI_ANewDwarf_UTF16LE.irr
new file mode 100644
index 000000000..39d99e440
Binary files /dev/null and b/test/models/IRR/EpisodeI_ANewDwarf_UTF16LE.irr differ
diff --git a/test/models/IRR/animMesh.irr b/test/models/IRR/animMesh.irr
index d1c9e1018..c1c247ff2 100644
Binary files a/test/models/IRR/animMesh.irr and b/test/models/IRR/animMesh.irr differ
diff --git a/test/models/IRR/animMesh_UTF16LE.irr b/test/models/IRR/animMesh_UTF16LE.irr
new file mode 100644
index 000000000..d1c9e1018
Binary files /dev/null and b/test/models/IRR/animMesh_UTF16LE.irr differ
diff --git a/test/models/IRR/box.irr b/test/models/IRR/box.irr
index efc165d93..8a094ded6 100644
Binary files a/test/models/IRR/box.irr and b/test/models/IRR/box.irr differ
diff --git a/test/models/IRR/box_UTF16LE.irr b/test/models/IRR/box_UTF16LE.irr
new file mode 100644
index 000000000..efc165d93
Binary files /dev/null and b/test/models/IRR/box_UTF16LE.irr differ
diff --git a/test/models/IRR/brownground_1-1.jpg b/test/models/IRR/brownground_1-1.jpg
new file mode 100644
index 000000000..fda7d45c6
Binary files /dev/null and b/test/models/IRR/brownground_1-1.jpg differ
diff --git a/test/models/IRR/crackedground_1-6.jpg b/test/models/IRR/crackedground_1-6.jpg
new file mode 100644
index 000000000..48da577fd
Binary files /dev/null and b/test/models/IRR/crackedground_1-6.jpg differ
diff --git a/test/models/IRR/dawfInCellar_ChildOfCellar.irr b/test/models/IRR/dawfInCellar_ChildOfCellar.irr
index 698530d3a..fd2c80ae7 100644
Binary files a/test/models/IRR/dawfInCellar_ChildOfCellar.irr and b/test/models/IRR/dawfInCellar_ChildOfCellar.irr differ
diff --git a/test/models/IRR/dawfInCellar_ChildOfCellar_UTF16LE.irr b/test/models/IRR/dawfInCellar_ChildOfCellar_UTF16LE.irr
new file mode 100644
index 000000000..698530d3a
Binary files /dev/null and b/test/models/IRR/dawfInCellar_ChildOfCellar_UTF16LE.irr differ
diff --git a/test/models/IRR/dawfInCellar_SameHierarchy.irr b/test/models/IRR/dawfInCellar_SameHierarchy.irr
index 83d4ab932..5fbfbe655 100644
Binary files a/test/models/IRR/dawfInCellar_SameHierarchy.irr and b/test/models/IRR/dawfInCellar_SameHierarchy.irr differ
diff --git a/test/models/IRR/dawfInCellar_SameHierarchy_UTF16LE.irr b/test/models/IRR/dawfInCellar_SameHierarchy_UTF16LE.irr
new file mode 100644
index 000000000..83d4ab932
Binary files /dev/null and b/test/models/IRR/dawfInCellar_SameHierarchy_UTF16LE.irr differ
diff --git a/test/models/IRR/multipleAnimators.irr b/test/models/IRR/multipleAnimators.irr
index fb468aa11..9e4bc4b7c 100644
Binary files a/test/models/IRR/multipleAnimators.irr and b/test/models/IRR/multipleAnimators.irr differ
diff --git a/test/models/IRR/multipleAnimators_UTF16LE.irr b/test/models/IRR/multipleAnimators_UTF16LE.irr
new file mode 100644
index 000000000..fb468aa11
Binary files /dev/null and b/test/models/IRR/multipleAnimators_UTF16LE.irr differ
diff --git a/test/models/IRR/scenegraphAnim.irr b/test/models/IRR/scenegraphAnim.irr
index 3cf28a960..ff7a612e0 100644
Binary files a/test/models/IRR/scenegraphAnim.irr and b/test/models/IRR/scenegraphAnim.irr differ
diff --git a/test/models/IRR/scenegraphAnim_UTF16LE.irr b/test/models/IRR/scenegraphAnim_UTF16LE.irr
new file mode 100644
index 000000000..3cf28a960
Binary files /dev/null and b/test/models/IRR/scenegraphAnim_UTF16LE.irr differ
diff --git a/test/models/IRR/sphere.irr b/test/models/IRR/sphere.irr
index ab4219268..f21e8f133 100644
Binary files a/test/models/IRR/sphere.irr and b/test/models/IRR/sphere.irr differ
diff --git a/test/models/IRR/sphere_UTF16LE.irr b/test/models/IRR/sphere_UTF16LE.irr
new file mode 100644
index 000000000..ab4219268
Binary files /dev/null and b/test/models/IRR/sphere_UTF16LE.irr differ
diff --git a/test/models/IRRMesh/cellar.irrmesh b/test/models/IRRMesh/cellar.irrmesh
index d8d3a661b..0278c9239 100644
Binary files a/test/models/IRRMesh/cellar.irrmesh and b/test/models/IRRMesh/cellar.irrmesh differ
diff --git a/test/models/IRRMesh/cellar_UTF16LE.irrmesh b/test/models/IRRMesh/cellar_UTF16LE.irrmesh
new file mode 100644
index 000000000..d8d3a661b
Binary files /dev/null and b/test/models/IRRMesh/cellar_UTF16LE.irrmesh differ
diff --git a/test/models/IRRMesh/spider.irrmesh b/test/models/IRRMesh/spider.irrmesh
index c6ad9291f..f956130e1 100644
Binary files a/test/models/IRRMesh/spider.irrmesh and b/test/models/IRRMesh/spider.irrmesh differ
diff --git a/test/models/IRRMesh/spider_UTF16LE.irrmesh b/test/models/IRRMesh/spider_UTF16LE.irrmesh
new file mode 100644
index 000000000..c6ad9291f
Binary files /dev/null and b/test/models/IRRMesh/spider_UTF16LE.irrmesh differ
diff --git a/test/models/IRRMesh/testFormatDetection.xml b/test/models/IRRMesh/testFormatDetection.xml
index aa73560d4..0986eaf61 100644
Binary files a/test/models/IRRMesh/testFormatDetection.xml and b/test/models/IRRMesh/testFormatDetection.xml differ
diff --git a/test/models/IRRMesh/testFormatDetection_UTF16LE.xml b/test/models/IRRMesh/testFormatDetection_UTF16LE.xml
new file mode 100644
index 000000000..aa73560d4
Binary files /dev/null and b/test/models/IRRMesh/testFormatDetection_UTF16LE.xml differ
diff --git a/test/models/MDL/MDL (HL1)/multiple_roots.mdl b/test/models/MDL/MDL (HL1)/multiple_roots.mdl
new file mode 100644
index 000000000..f8fc1eed7
Binary files /dev/null and b/test/models/MDL/MDL (HL1)/multiple_roots.mdl differ
diff --git a/test/models/PLY/pond.0.ply b/test/models/PLY/pond.0.ply
index 02b7683ce..a45e0322d 100644
Binary files a/test/models/PLY/pond.0.ply and b/test/models/PLY/pond.0.ply differ
diff --git a/test/unit/ImportExport/MDL/utMDLImporter_HL1_ImportSettings.cpp b/test/unit/ImportExport/MDL/utMDLImporter_HL1_ImportSettings.cpp
index 4614066e6..d50c2b35a 100644
--- a/test/unit/ImportExport/MDL/utMDLImporter_HL1_ImportSettings.cpp
+++ b/test/unit/ImportExport/MDL/utMDLImporter_HL1_ImportSettings.cpp
@@ -190,7 +190,7 @@ private:
Assimp::Importer importer;
importer.SetPropertyBool(setting_key, setting_value);
const aiScene *scene = importer.ReadFile(file_path, aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene);
func(scene);
}
diff --git a/test/unit/ImportExport/MDL/utMDLImporter_HL1_Materials.cpp b/test/unit/ImportExport/MDL/utMDLImporter_HL1_Materials.cpp
index 2389c0ffc..f733893ca 100644
--- a/test/unit/ImportExport/MDL/utMDLImporter_HL1_Materials.cpp
+++ b/test/unit/ImportExport/MDL/utMDLImporter_HL1_Materials.cpp
@@ -61,8 +61,8 @@ public:
void flatShadeTexture() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "chrome_sphere.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
- EXPECT_NE(nullptr, scene->mMaterials);
+ ASSERT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene->mMaterials);
aiShadingMode shading_mode = aiShadingMode_Flat;
scene->mMaterials[0]->Get(AI_MATKEY_SHADING_MODEL, shading_mode);
@@ -74,8 +74,8 @@ public:
void chromeTexture() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "chrome_sphere.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
- EXPECT_NE(nullptr, scene->mMaterials);
+ ASSERT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene->mMaterials);
int chrome;
scene->mMaterials[0]->Get(AI_MDL_HL1_MATKEY_CHROME(aiTextureType_DIFFUSE, 0), chrome);
@@ -87,8 +87,8 @@ public:
void additiveBlendTexture() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "blend_additive.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
- EXPECT_NE(nullptr, scene->mMaterials);
+ ASSERT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene->mMaterials);
aiBlendMode blend_mode = aiBlendMode_Default;
scene->mMaterials[0]->Get(AI_MATKEY_BLEND_FUNC, blend_mode);
@@ -101,8 +101,8 @@ public:
void textureWithColorMask() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "alpha_test.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
- EXPECT_NE(nullptr, scene->mMaterials);
+ ASSERT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene->mMaterials);
int texture_flags = 0;
scene->mMaterials[0]->Get(AI_MATKEY_TEXFLAGS_DIFFUSE(0), texture_flags);
diff --git a/test/unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp b/test/unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp
index 4420727e9..49ae8a16c 100644
--- a/test/unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp
+++ b/test/unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp
@@ -55,6 +55,17 @@ using namespace Assimp;
class utMDLImporter_HL1_Nodes : public ::testing::Test {
+ /**
+ * @note Represents a flattened node hierarchy where each item is a pair
+ * containing the node level and it's name.
+ */
+ using Hierarchy = std::vector>;
+
+ /**
+ * @note A vector of strings. Used for symplifying syntax.
+ */
+ using StringVector = std::vector;
+
public:
/**
* @note The following tests require a basic understanding
@@ -63,6 +74,51 @@ public:
* (Valve Developer Community).
*/
+ // Given a model, verify that the bones nodes hierarchy is correctly formed.
+ void checkBoneHierarchy() {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "multiple_roots.mdl", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene->mRootNode);
+
+ // First, check that "" and "" are linked.
+ const aiNode* node_MDL_root = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_ROOT);
+ ASSERT_NE(nullptr, node_MDL_root);
+
+ const aiNode *node_MDL_bones = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BONES);
+ ASSERT_NE(nullptr, node_MDL_bones);
+ ASSERT_NE(nullptr, node_MDL_bones->mParent);
+ ASSERT_EQ(node_MDL_root, node_MDL_bones->mParent);
+
+ // Second, verify "" hierarchy.
+ const Hierarchy expected_hierarchy = {
+ { 0, AI_MDL_HL1_NODE_BONES },
+ { 1, "root1_bone1" },
+ { 2, "root1_bone2" },
+ { 3, "root1_bone4" },
+ { 3, "root1_bone5" },
+ { 2, "root1_bone3" },
+ { 3, "root1_bone6" },
+ { 1, "root2_bone1" },
+ { 2, "root2_bone2" },
+ { 2, "root2_bone3" },
+ { 3, "root2_bone5" },
+ { 2, "root2_bone4" },
+ { 3, "root2_bone6" },
+ { 1, "root3_bone1" },
+ { 2, "root3_bone2" },
+ { 2, "root3_bone3" },
+ { 2, "root3_bone4" },
+ { 3, "root3_bone5" },
+ { 4, "root3_bone6" },
+ { 4, "root3_bone7" },
+ };
+
+ Hierarchy actual_hierarchy;
+ flatten_hierarchy(node_MDL_bones, actual_hierarchy);
+ ASSERT_EQ(expected_hierarchy, actual_hierarchy);
+ }
+
/* Given a model with bones that have empty names,
verify that all the bones of the imported model
have unique and no empty names.
@@ -80,9 +136,9 @@ public:
void emptyBonesNames() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "unnamed_bones.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene);
- const std::vector expected_bones_names = {
+ const StringVector expected_bones_names = {
"Bone",
"Bone_0",
"Bone_1",
@@ -94,7 +150,9 @@ public:
"Bone_7"
};
- expect_named_children(scene, AI_MDL_HL1_NODE_BONES, expected_bones_names);
+ StringVector actual_bones_names;
+ get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BONES), actual_bones_names);
+ ASSERT_EQ(expected_bones_names, actual_bones_names);
}
/* Given a model with bodyparts that have empty names,
@@ -114,9 +172,9 @@ public:
void emptyBodypartsNames() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "unnamed_bodyparts.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene);
- const std::vector expected_bodyparts_names = {
+ const StringVector expected_bodyparts_names = {
"Bodypart",
"Bodypart_1",
"Bodypart_5",
@@ -128,7 +186,10 @@ public:
"Bodypart_7"
};
- expect_named_children(scene, AI_MDL_HL1_NODE_BODYPARTS, expected_bodyparts_names);
+ StringVector actual_bodyparts_names;
+ // Get the bodyparts names "without" the submodels.
+ get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BODYPARTS), actual_bodyparts_names, 0);
+ ASSERT_EQ(expected_bodyparts_names, actual_bodyparts_names);
}
/* Given a model with bodyparts that have duplicate names,
@@ -148,9 +209,9 @@ public:
void duplicateBodypartsNames() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "duplicate_bodyparts.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene);
- const std::vector expected_bodyparts_names = {
+ const StringVector expected_bodyparts_names = {
"Bodypart",
"Bodypart_1",
"Bodypart_2",
@@ -162,7 +223,10 @@ public:
"Bodypart_4"
};
- expect_named_children(scene, AI_MDL_HL1_NODE_BODYPARTS, expected_bodyparts_names);
+ StringVector actual_bodyparts_names;
+ // Get the bodyparts names "without" the submodels.
+ get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BODYPARTS), actual_bodyparts_names, 0);
+ ASSERT_EQ(expected_bodyparts_names, actual_bodyparts_names);
}
/* Given a model with several bodyparts that contains multiple
@@ -190,9 +254,9 @@ public:
void duplicateSubModelsNames() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "duplicate_submodels.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene);
- const std::vector> expected_bodypart_sub_models_names = {
+ const std::vector expected_bodypart_sub_models_names = {
{
"triangle",
"triangle_0",
@@ -208,11 +272,15 @@ public:
};
const aiNode *bodyparts_node = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BODYPARTS);
- EXPECT_NE(nullptr, bodyparts_node);
+ ASSERT_NE(nullptr, bodyparts_node);
EXPECT_EQ(3u, bodyparts_node->mNumChildren);
- for (unsigned int i = 0; i < bodyparts_node->mNumChildren; ++i) {
- expect_named_children(bodyparts_node->mChildren[i],
- expected_bodypart_sub_models_names[i]);
+
+ StringVector actual_submodels_names;
+ for (unsigned int i = 0; i < bodyparts_node->mNumChildren; ++i)
+ {
+ actual_submodels_names.clear();
+ get_node_children_names(bodyparts_node->mChildren[i], actual_submodels_names);
+ ASSERT_EQ(expected_bodypart_sub_models_names[i], actual_submodels_names);
}
}
@@ -233,9 +301,9 @@ public:
void duplicateSequenceNames() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "duplicate_sequences.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene);
- const std::vector expected_sequence_names = {
+ const StringVector expected_sequence_names = {
"idle_1",
"idle",
"idle_2",
@@ -247,7 +315,9 @@ public:
"idle_7"
};
- expect_named_children(scene, AI_MDL_HL1_NODE_SEQUENCE_INFOS, expected_sequence_names);
+ StringVector actual_sequence_names;
+ get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_INFOS), actual_sequence_names);
+ ASSERT_EQ(expected_sequence_names, actual_sequence_names);
}
/* Given a model with sequences that have empty names, verify
@@ -267,9 +337,9 @@ public:
void emptySequenceNames() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "unnamed_sequences.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene);
- const std::vector expected_sequence_names = {
+ const StringVector expected_sequence_names = {
"Sequence",
"Sequence_1",
"Sequence_0",
@@ -281,7 +351,9 @@ public:
"Sequence_6"
};
- expect_named_children(scene, AI_MDL_HL1_NODE_SEQUENCE_INFOS, expected_sequence_names);
+ StringVector actual_sequence_names;
+ get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_INFOS), actual_sequence_names);
+ ASSERT_EQ(expected_sequence_names, actual_sequence_names);
}
/* Given a model with sequence groups that have duplicate names,
@@ -302,9 +374,9 @@ public:
void duplicateSequenceGroupNames() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "duplicate_sequence_groups/duplicate_sequence_groups.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene);
- const std::vector expected_sequence_names = {
+ const StringVector expected_sequence_names = {
"default",
"SequenceGroup",
"SequenceGroup_1",
@@ -317,7 +389,9 @@ public:
"SequenceGroup_2"
};
- expect_named_children(scene, AI_MDL_HL1_NODE_SEQUENCE_GROUPS, expected_sequence_names);
+ StringVector actual_sequence_names;
+ get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_GROUPS), actual_sequence_names);
+ ASSERT_EQ(expected_sequence_names, actual_sequence_names);
}
/* Given a model with sequence groups that have empty names,
@@ -338,9 +412,9 @@ public:
void emptySequenceGroupNames() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "unnamed_sequence_groups/unnamed_sequence_groups.mdl", aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene);
- const std::vector expected_sequence_names = {
+ const StringVector expected_sequence_names = {
"default",
"SequenceGroup",
"SequenceGroup_2",
@@ -353,7 +427,9 @@ public:
"SequenceGroup_4"
};
- expect_named_children(scene, AI_MDL_HL1_NODE_SEQUENCE_GROUPS, expected_sequence_names);
+ StringVector actual_sequence_names;
+ get_node_children_names(scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_GROUPS), actual_sequence_names);
+ ASSERT_EQ(expected_sequence_names, actual_sequence_names);
}
/* Verify that mOffsetMatrix applies the correct
@@ -364,7 +440,7 @@ public:
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(MDL_HL1_FILE_MAN, aiProcess_ValidateDataStructure);
- EXPECT_NE(nullptr, scene);
+ ASSERT_NE(nullptr, scene);
aiNode *scene_bones_node = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BONES);
@@ -398,26 +474,58 @@ public:
}
private:
- void expect_named_children(const aiNode *parent_node, const std::vector &expected_names) {
- EXPECT_NE(nullptr, parent_node);
- EXPECT_EQ(expected_names.size(), parent_node->mNumChildren);
-
- for (unsigned int i = 0; i < parent_node->mNumChildren; ++i)
- EXPECT_EQ(expected_names[i], parent_node->mChildren[i]->mName.C_Str());
- }
-
- void expect_named_children(const aiScene *scene, const char *node_name, const std::vector &expected_names) {
- expect_named_children(scene->mRootNode->FindNode(node_name), expected_names);
- }
-
void expect_equal_matrices(const aiMatrix4x4 &expected, const aiMatrix4x4 &actual, float abs_error) {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j)
EXPECT_NEAR(expected[i][j], actual[i][j], abs_error);
}
}
+
+ /** Get a flattened representation of a node's hierarchy.
+ * \param[in] node The node.
+ * \param[out] hierarchy The flattened node's hierarchy.
+ */
+ void flatten_hierarchy(const aiNode *node, Hierarchy &hierarchy)
+ {
+ flatten_hierarchy_impl(node, hierarchy, 0);
+ }
+
+ void flatten_hierarchy_impl(const aiNode *node, Hierarchy &hierarchy, unsigned int level)
+ {
+ hierarchy.push_back({ level, node->mName.C_Str() });
+ for (size_t i = 0; i < node->mNumChildren; ++i)
+ {
+ flatten_hierarchy_impl(node->mChildren[i], hierarchy, level + 1);
+ }
+ }
+
+ /** Get all node's children names beneath max_level.
+ * \param[in] node The parent node from which to get all children names.
+ * \param[out] names The list of children names.
+ * \param[in] max_level If set to -1, all children names will be collected.
+ */
+ void get_node_children_names(const aiNode *node, StringVector &names, const int max_level = -1)
+ {
+ get_node_children_names_impl(node, names, 0, max_level);
+ }
+
+ void get_node_children_names_impl(const aiNode *node, StringVector &names, int level, const int max_level = -1)
+ {
+ for (size_t i = 0; i < node->mNumChildren; ++i)
+ {
+ names.push_back(node->mChildren[i]->mName.C_Str());
+ if (max_level == -1 || level < max_level)
+ {
+ get_node_children_names_impl(node->mChildren[i], names, level + 1, max_level);
+ }
+ }
+ }
};
+TEST_F(utMDLImporter_HL1_Nodes, checkBoneHierarchy) {
+ checkBoneHierarchy();
+}
+
TEST_F(utMDLImporter_HL1_Nodes, emptyBonesNames) {
emptyBonesNames();
}
diff --git a/test/unit/ut3DImportExport.cpp b/test/unit/ut3DImportExport.cpp
index 5ff1d7940..32b77ddf8 100644
--- a/test/unit/ut3DImportExport.cpp
+++ b/test/unit/ut3DImportExport.cpp
@@ -65,3 +65,24 @@ TEST(ut3DImportExport, importBoxUC) {
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3D/box.uc", aiProcess_ValidateDataStructure);
ASSERT_NE(nullptr, scene);
}
+
+
+TEST(ut3DImportExport, importMarRifle) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/3D/mar_rifle.uc", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(ut3DImportExport, importMarRifleA) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/3D/mar_rifle_a.3d", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(ut3DImportExport, importMarRifleD) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/3D/mar_rifle_d.3d", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
diff --git a/test/unit/ut3DSImportExport.cpp b/test/unit/ut3DSImportExport.cpp
index 01406362d..7279227fc 100644
--- a/test/unit/ut3DSImportExport.cpp
+++ b/test/unit/ut3DSImportExport.cpp
@@ -70,3 +70,115 @@ TEST_F(ut3DSImportExport, import3DSformatdetection) {
EXPECT_NE(nullptr, scene);
}
+
+
+TEST_F(ut3DSImportExport, importCameraRollAnim) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3DS/CameraRollAnim.3ds", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importCameraRollAnimWithChildObject) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3DS/CameraRollAnimWithChildObject.3ds", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importCubesWithAlpha) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3DS/cubes_with_alpha.3DS", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importCubeWithDiffuseTexture) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3DS/cube_with_diffuse_texture.3DS", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importCubeWithSpecularTexture) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3DS/cube_with_specular_texture.3DS", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importRotatingCube) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3DS/RotatingCube.3DS", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importTargetCameraAnim) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3DS/TargetCameraAnim.3ds", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importTest1) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3DS/test1.3ds", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importCartWheel) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/3DS/cart_wheel.3DS", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importGranate) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/3DS/Granate.3DS", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importJeep1) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/3DS/jeep1.3ds", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importMarRifle) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/3DS/mar_rifle.3ds", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importMp5Sil) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/3DS/mp5_sil.3ds", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(ut3DSImportExport, importPyramob) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/3DS/pyramob.3DS", aiProcess_ValidateDataStructure);
+
+ EXPECT_NE(nullptr, scene);
+}
diff --git a/test/unit/utAMFImportExport.cpp b/test/unit/utAMFImportExport.cpp
index 78309a105..7319320cf 100644
--- a/test/unit/utAMFImportExport.cpp
+++ b/test/unit/utAMFImportExport.cpp
@@ -60,6 +60,81 @@ TEST_F(utAMFImportExport, importAMFFromFileTest) {
EXPECT_TRUE(importerTest());
}
+
+// TODO: test models-nonbsd/AMF/3_bananas.amf.7z
+// requires uncompressing it in memory and we don't currently have 7z decompressor
+
+
+TEST_F(utAMFImportExport, importTest2) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AMF/test2.amf", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utAMFImportExport, importTest3) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AMF/test3.amf", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utAMFImportExport, importTest4) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AMF/test4.amf", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utAMFImportExport, importTest5) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AMF/test5.amf", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utAMFImportExport, importTest5a) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AMF/test5a.amf", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utAMFImportExport, importTest6) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AMF/test6.amf", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utAMFImportExport, importTest7) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AMF/test7.amf", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+#if 0
+// FIXME: these tests are disabled because they leak memory in AMFImporter_Postprocess.cpp
+
+
+TEST_F(utAMFImportExport, importTest8) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AMF/test8.amf", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utAMFImportExport, importTest9) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AMF/test9.amf", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+#endif // 0
+
+
TEST_F(utAMFImportExport, importAMFWithMatFromFileTest) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AMF/test_with_mat.amf", aiProcess_ValidateDataStructure);
diff --git a/test/unit/utASEImportExport.cpp b/test/unit/utASEImportExport.cpp
index 8014cbbc7..af05a2fe5 100644
--- a/test/unit/utASEImportExport.cpp
+++ b/test/unit/utASEImportExport.cpp
@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include
#include
+#include
using namespace Assimp;
@@ -63,3 +64,112 @@ public:
TEST_F(utASEImportExport, importACFromFileTest) {
EXPECT_TRUE(importerTest());
}
+
+
+TEST_F(utASEImportExport, importAnim1) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/anim.ASE", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utASEImportExport, importAnim2) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/anim2.ASE", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utASEImportExport, importCameraRollAnim) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/CameraRollAnim.ase", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utASEImportExport, importMotionCaptureROM) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/MotionCaptureROM.ase", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utASEImportExport, importRotatingCube) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/RotatingCube.ASE", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utASEImportExport, importTargetCameraAnim) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/TargetCameraAnim.ase", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utASEImportExport, importTestFormatDetection) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/TestFormatDetection", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utASEImportExport, importThreeCubesGreen) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/ThreeCubesGreen.ASE", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+
+ ::Assimp::Importer importerLE;
+ const aiScene *sceneLE = importerLE.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/ThreeCubesGreen_UTF16LE.ASE", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, sceneLE);
+
+ ::Assimp::Importer importerBE;
+ const aiScene *sceneBE = importerBE.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/ThreeCubesGreen_UTF16BE.ASE", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, sceneBE);
+
+ // TODO: these scenes should probably be identical
+ // verify that is the case and then add tests to check it
+}
+
+
+TEST_F(utASEImportExport, importUVTransform_Normal) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/TestUVTransform/UVTransform_Normal.ASE", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utASEImportExport, importUVTransform_ScaleUV1_2_OffsetUV0_0_9_Rotate_72_mirrorU) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/TestUVTransform/UVTransform_ScaleUV1-2_OffsetUV0-0.9_Rotate-72_mirrorU.ase", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utASEImportExport, importUVTransform_ScaleUV2x) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/TestUVTransform/UVTransform_ScaleUV2x.ASE", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utASEImportExport, importUVTransform_ScaleUV2x_Rotate45) {
+ ::Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/ASE/TestUVTransform/UVTransform_ScaleUV2x_Rotate45.ASE", aiProcess_ValidateDataStructure);
+
+ ASSERT_NE(nullptr, scene);
+}
diff --git a/test/unit/utBVHImportExport.cpp b/test/unit/utBVHImportExport.cpp
index d69ac7987..5a0ff1e10 100644
--- a/test/unit/utBVHImportExport.cpp
+++ b/test/unit/utBVHImportExport.cpp
@@ -55,6 +55,20 @@ public:
}
};
-TEST_F(utBVHImportExport, importBlenFromFileTest) {
+TEST_F(utBVHImportExport, import01_01) {
EXPECT_TRUE(importerTest());
}
+
+
+TEST_F(utBVHImportExport, import01_03) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BVH/01_03.bvh", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
+
+
+TEST_F(utBVHImportExport, importBoxingToes) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BVH/Boxing_Toes.bvh", aiProcess_ValidateDataStructure);
+ ASSERT_NE(nullptr, scene);
+}
diff --git a/test/unit/utDXFImporterExporter.cpp b/test/unit/utDXFImporterExporter.cpp
index 9193946b5..53c5328e4 100644
--- a/test/unit/utDXFImporterExporter.cpp
+++ b/test/unit/utDXFImporterExporter.cpp
@@ -71,3 +71,17 @@ TEST_F(utDXFImporterExporter, issue2229) {
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/DXF/issue_2229.dxf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
+
+
+TEST_F(utDXFImporterExporter, importWuson) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/DXF/wuson.dxf", aiProcess_ValidateDataStructure);
+ EXPECT_NE(nullptr, scene);
+}
+
+
+TEST_F(utDXFImporterExporter, importRifle) {
+ Assimp::Importer importer;
+ const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/DXF/rifle.dxf", aiProcess_ValidateDataStructure);
+ EXPECT_NE(nullptr, scene);
+}