Quellcode durchsuchen

Better aiMesh ABI compatibility with 5.0.1, make smaller

Move new mTextureCoordsNames member to end of struct
Convert to pointer-to-array, saving ~8KB per aiMesh in almost all cases
Add C++ accessor functions for simpler usage
RichardTea vor 3 Jahren
Ursprung
Commit
86a25b62e4

+ 1 - 1
code/AssetLib/Assxml/AssxmlFileWriter.cpp

@@ -601,7 +601,7 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
                 ioprintf(io, "\t\t<TextureCoords num=\"%u\" set=\"%u\" name=\"%s\" num_components=\"%u\"> \n",
                          mesh->mNumVertices,
                          a,
-                         mesh->mTextureCoordsNames[a].C_Str(),
+                         (mesh->HasTextureCoordsName(a) ? mesh->GetTextureCoordsName(a)->C_Str() : ""),
                          mesh->mNumUVComponents[a]);
 
                 if (!shortened) {

+ 1 - 1
code/AssetLib/FBX/FBXConverter.cpp

@@ -1128,7 +1128,7 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
             *out_uv++ = aiVector3D(v.x, v.y, 0.0f);
         }
 
-        out_mesh->mTextureCoordsNames[i] = mesh.GetTextureCoordChannelName(i);
+        out_mesh->SetTextureCoordsName(i, aiString(mesh.GetTextureCoordChannelName(i)));
 
         out_mesh->mNumUVComponents[i] = 2;
     }

+ 60 - 5
include/assimp/mesh.h

@@ -673,10 +673,6 @@ struct aiMesh {
     */
     C_STRUCT aiVector3D *mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 
-    /** Vertex stream names.
-     */
-    C_STRUCT aiString mTextureCoordsNames[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-
     /** Specifies the number of components for a given UV channel.
     * Up to three channels are supported (UVW, for accessing volume
     * or cube maps). If the value is 2 for a given channel n, the
@@ -744,6 +740,10 @@ struct aiMesh {
      */
     C_STRUCT aiAABB mAABB;
 
+    /** Vertex UV stream names. Pointer to array of size AI_MAX_NUMBER_OF_TEXTURECOORDS
+     */
+    C_STRUCT aiString **mTextureCoordsNames;
+
 #ifdef __cplusplus
 
     //! Default constructor. Initializes all members to 0
@@ -765,7 +765,8 @@ struct aiMesh {
               mNumAnimMeshes(0),
               mAnimMeshes(nullptr),
               mMethod(0),
-              mAABB() {
+              mAABB(),
+              mTextureCoordsNames(nullptr) {
         for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
             mNumUVComponents[a] = 0;
             mTextureCoords[a] = nullptr;
@@ -785,6 +786,14 @@ struct aiMesh {
         for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
             delete[] mTextureCoords[a];
         }
+
+        if (mTextureCoordsNames) {
+            for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
+                delete mTextureCoordsNames[a];
+            }
+            delete[] mTextureCoordsNames;
+        }
+
         for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
             delete[] mColors[a];
         }
@@ -870,6 +879,52 @@ struct aiMesh {
         return mBones != nullptr && mNumBones > 0;
     }
 
+    //! Check whether the mesh contains a texture coordinate set name
+    //! \param pIndex Index of the texture coordinates set
+    bool HasTextureCoordsName(unsigned int pIndex) const {
+        if (mTextureCoordsNames == nullptr || pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
+            return false;
+        }
+        return mTextureCoordsNames[pIndex] != nullptr;
+    }
+
+    //! Set a texture coordinate set name
+    //! \param pIndex Index of the texture coordinates set
+    //! \param texCoordsName name of the texture coordinate set
+    void SetTextureCoordsName(unsigned int pIndex, const aiString &texCoordsName) {
+        if (pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
+            return;
+        }
+
+        if (mTextureCoordsNames == nullptr) {
+            // Construct and null-init array
+            mTextureCoordsNames = new aiString *[AI_MAX_NUMBER_OF_TEXTURECOORDS] {};
+        }
+
+        if (texCoordsName.length == 0) {
+            delete mTextureCoordsNames[pIndex];
+            mTextureCoordsNames[pIndex] = nullptr;
+            return;
+        }
+
+        if (mTextureCoordsNames[pIndex] == nullptr) {
+            mTextureCoordsNames[pIndex] = new aiString(texCoordsName);
+            return;
+        }
+
+        *mTextureCoordsNames[pIndex] = texCoordsName;
+    }
+
+    //! Get a texture coordinate set name
+    //! \param pIndex Index of the texture coordinates set
+    const aiString *GetTextureCoordsName(unsigned int pIndex) const {
+        if (mTextureCoordsNames == nullptr || pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
+            return nullptr;
+        }
+
+        return mTextureCoordsNames[pIndex];
+    }
+
 #endif // __cplusplus
 };
 

+ 1 - 0
test/CMakeLists.txt

@@ -90,6 +90,7 @@ SET( COMMON
   unit/utProfiler.cpp
   unit/utSharedPPData.cpp
   unit/utStringUtils.cpp
+  unit/Common/utMesh.cpp
   unit/Common/utStandardShapes.cpp
   unit/Common/uiScene.cpp
   unit/Common/utLineSplitter.cpp

+ 96 - 0
test/unit/Common/utMesh.cpp

@@ -0,0 +1,96 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2021, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+#include "UnitTestPCH.h"
+
+#include <assimp/mesh.h>
+
+using namespace Assimp;
+
+class utMesh : public ::testing::Test {
+protected:
+  aiMesh* mesh = nullptr;
+
+  void SetUp() override {
+    mesh = new aiMesh;
+  }
+
+  void TearDown() override {
+    delete mesh;
+    mesh = nullptr;
+  }
+};
+
+TEST_F(utMesh, emptyMeshHasNoContentTest) {
+  EXPECT_EQ(0, mesh->mName.length);
+  EXPECT_FALSE(mesh->HasPositions());
+  EXPECT_FALSE(mesh->HasFaces());
+  EXPECT_FALSE(mesh->HasNormals());
+  EXPECT_FALSE(mesh->HasTangentsAndBitangents());
+  EXPECT_FALSE(mesh->HasVertexColors(0));
+  EXPECT_FALSE(mesh->HasVertexColors(AI_MAX_NUMBER_OF_COLOR_SETS));
+  EXPECT_FALSE(mesh->HasTextureCoords(0));
+  EXPECT_FALSE(mesh->HasTextureCoords(AI_MAX_NUMBER_OF_TEXTURECOORDS));
+  EXPECT_EQ(0, mesh->GetNumUVChannels());
+  EXPECT_EQ(0, mesh->GetNumColorChannels());
+  EXPECT_FALSE(mesh->HasBones());
+  EXPECT_FALSE(mesh->HasTextureCoordsName(0));
+  EXPECT_FALSE(mesh->HasTextureCoordsName(AI_MAX_NUMBER_OF_TEXTURECOORDS));
+}
+
+TEST_F(utMesh, setTextureCoordsName) {
+  EXPECT_FALSE(mesh->HasTextureCoordsName(0));
+  const aiString texcoords_name("texcoord_name");
+  mesh->SetTextureCoordsName(0, texcoords_name);
+  EXPECT_TRUE(mesh->HasTextureCoordsName(0));
+  EXPECT_FALSE(mesh->HasTextureCoordsName(1));
+  ASSERT_NE(nullptr, mesh->mTextureCoordsNames);
+  ASSERT_NE(nullptr, mesh->mTextureCoordsNames[0]);
+  EXPECT_STREQ(texcoords_name.C_Str(), mesh->mTextureCoordsNames[0]->C_Str());
+  EXPECT_STREQ(texcoords_name.C_Str(), mesh->GetTextureCoordsName(0)->C_Str());
+
+  // Now clear the name
+  mesh->SetTextureCoordsName(0, aiString());
+  EXPECT_FALSE(mesh->HasTextureCoordsName(0));
+  ASSERT_NE(nullptr, mesh->mTextureCoordsNames);
+  EXPECT_EQ(nullptr, mesh->mTextureCoordsNames[0]);
+  EXPECT_EQ(nullptr, mesh->GetTextureCoordsName(0));
+}