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
pull/4163/head
RichardTea 2021-11-09 13:03:06 +00:00
parent 2b4b3e820b
commit 86a25b62e4
5 changed files with 159 additions and 7 deletions

View File

@ -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", ioprintf(io, "\t\t<TextureCoords num=\"%u\" set=\"%u\" name=\"%s\" num_components=\"%u\"> \n",
mesh->mNumVertices, mesh->mNumVertices,
a, a,
mesh->mTextureCoordsNames[a].C_Str(), (mesh->HasTextureCoordsName(a) ? mesh->GetTextureCoordsName(a)->C_Str() : ""),
mesh->mNumUVComponents[a]); mesh->mNumUVComponents[a]);
if (!shortened) { if (!shortened) {

View File

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

View File

@ -673,10 +673,6 @@ struct aiMesh {
*/ */
C_STRUCT aiVector3D *mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; 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. /** Specifies the number of components for a given UV channel.
* Up to three channels are supported (UVW, for accessing volume * Up to three channels are supported (UVW, for accessing volume
* or cube maps). If the value is 2 for a given channel n, the * or cube maps). If the value is 2 for a given channel n, the
@ -744,6 +740,10 @@ struct aiMesh {
*/ */
C_STRUCT aiAABB mAABB; C_STRUCT aiAABB mAABB;
/** Vertex UV stream names. Pointer to array of size AI_MAX_NUMBER_OF_TEXTURECOORDS
*/
C_STRUCT aiString **mTextureCoordsNames;
#ifdef __cplusplus #ifdef __cplusplus
//! Default constructor. Initializes all members to 0 //! Default constructor. Initializes all members to 0
@ -765,7 +765,8 @@ struct aiMesh {
mNumAnimMeshes(0), mNumAnimMeshes(0),
mAnimMeshes(nullptr), mAnimMeshes(nullptr),
mMethod(0), mMethod(0),
mAABB() { mAABB(),
mTextureCoordsNames(nullptr) {
for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) { for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
mNumUVComponents[a] = 0; mNumUVComponents[a] = 0;
mTextureCoords[a] = nullptr; mTextureCoords[a] = nullptr;
@ -785,6 +786,14 @@ struct aiMesh {
for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
delete[] mTextureCoords[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++) { for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
delete[] mColors[a]; delete[] mColors[a];
} }
@ -870,6 +879,52 @@ struct aiMesh {
return mBones != nullptr && mNumBones > 0; 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 #endif // __cplusplus
}; };

View File

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

View File

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