Browse Source

Merge branch 'master' into 1-1922

Kim Kulling 2 years ago
parent
commit
f81bb90f89

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

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

+ 20 - 13
code/AssetLib/FBX/FBXConverter.cpp

@@ -1180,15 +1180,23 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
     std::vector<aiAnimMesh *> animMeshes;
     for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
         for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
-            const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
-            for (size_t i = 0; i < shapeGeometries.size(); i++) {
+            const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
+            for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
                 aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
-                const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
-                const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
-                const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
-                const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
+                const auto &curVertices = shapeGeometry->GetVertices();
+                const auto &curNormals = shapeGeometry->GetNormals();
+                const auto &curIndices = shapeGeometry->GetIndices();
                 //losing channel name if using shapeGeometry->Name()
-                animMesh->mName.Set(FixAnimMeshName(blendShapeChannel->Name()));
+                // if blendShapeChannel Name is empty or don't have a ".", add geoMetryName;
+                auto aniName = FixAnimMeshName(blendShapeChannel->Name());
+                auto geoMetryName = FixAnimMeshName(shapeGeometry->Name());
+                if (aniName.empty()) {
+                    aniName = geoMetryName;
+                }
+                else if (aniName.find('.') == aniName.npos) {
+                    aniName += "." + geoMetryName;
+                }
+                animMesh->mName.Set(aniName);
                 for (size_t j = 0; j < curIndices.size(); j++) {
                     const unsigned int curIndex = curIndices.at(j);
                     aiVector3D vertex = curVertices.at(j);
@@ -1410,13 +1418,12 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
     std::vector<aiAnimMesh *> animMeshes;
     for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
         for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
-            const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
-            for (size_t i = 0; i < shapeGeometries.size(); i++) {
+            const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
+            for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
                 aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
-                const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
-                const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
-                const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
-                const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
+                const auto& curVertices = shapeGeometry->GetVertices();
+                const auto& curNormals = shapeGeometry->GetNormals();
+                const auto& curIndices = shapeGeometry->GetIndices();
                 animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
                 for (size_t j = 0; j < curIndices.size(); j++) {
                     unsigned int curIndex = curIndices.at(j);

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

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

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

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

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

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

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

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

+ 6 - 1
code/PostProcessing/ValidateDataStructure.cpp

@@ -911,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);
+            }
         }
     }
 }

+ 1 - 1
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);
     }
 

+ 8 - 8
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);

+ 10 - 10
test/unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp

@@ -136,7 +136,7 @@ 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 StringVector expected_bones_names = {
             "Bone",
@@ -172,7 +172,7 @@ 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 StringVector expected_bodyparts_names = {
             "Bodypart",
@@ -209,7 +209,7 @@ 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 StringVector expected_bodyparts_names = {
             "Bodypart",
@@ -254,7 +254,7 @@ 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<StringVector> expected_bodypart_sub_models_names = {
             {
@@ -272,7 +272,7 @@ 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);
 
         StringVector actual_submodels_names;
@@ -301,7 +301,7 @@ 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 StringVector expected_sequence_names = {
             "idle_1",
@@ -337,7 +337,7 @@ 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 StringVector expected_sequence_names = {
             "Sequence",
@@ -374,7 +374,7 @@ 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 StringVector expected_sequence_names = {
             "default",
@@ -412,7 +412,7 @@ 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 StringVector expected_sequence_names = {
             "default",
@@ -440,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);
 

+ 110 - 0
test/unit/utASEImportExport.cpp

@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <assimp/postprocess.h>
 #include <assimp/Importer.hpp>
+#include <assimp/scene.h>
 
 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);
+}