Introduce limits for vertices, faces (per mesh), face indices (per face) and weights (per bone).

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@783 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2010-07-16 11:44:31 +00:00
parent 1c0e25288b
commit e5aad11944
4 changed files with 80 additions and 44 deletions

View File

@ -132,6 +132,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// whether a new vertex was created for the index (true) or if it was replaced by an existing // whether a new vertex was created for the index (true) or if it was replaced by an existing
// unique vertex (false). This saves an additional std::vector<bool> and greatly enhances // unique vertex (false). This saves an additional std::vector<bool> and greatly enhances
// branching performance. // branching performance.
BOOST_STATIC_ASSERT(AI_MAX_VERTICES == 0x7fffffff);
std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff); std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
// A little helper to find locally close vertices faster. // A little helper to find locally close vertices faster.

View File

@ -370,14 +370,21 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
ReportError("The mesh contains no vertices"); ReportError("The mesh contains no vertices");
} }
if (pMesh->mNumVertices > AI_MAX_VERTICES) {
ReportError("Mesh has too many vertices: %u, but the limit is %u",pMesh->mNumVertices,AI_MAX_VERTICES);
}
if (pMesh->mNumFaces > AI_MAX_FACES) {
ReportError("Mesh has too many faces: %u, but the limit is %u",pMesh->mNumFaces,AI_MAX_FACES);
}
// if tangents are there there must also be bitangent vectors ... // if tangents are there there must also be bitangent vectors ...
if ((pMesh->mTangents != NULL) != (pMesh->mBitangents != NULL)) { if ((pMesh->mTangents != NULL) != (pMesh->mBitangents != NULL)) {
ReportError("If there are tangents there must also be bitangent vectors"); ReportError("If there are tangents, bitangent vectors must be present as well");
} }
// faces, too // faces, too
if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags)) { if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags)) {
ReportError("The mesh contains no faces"); ReportError("Mesh contains no faces");
} }
// now check whether the face indexing layout is correct: // now check whether the face indexing layout is correct:
@ -387,6 +394,10 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
for (unsigned int i = 0; i < pMesh->mNumFaces;++i) for (unsigned int i = 0; i < pMesh->mNumFaces;++i)
{ {
aiFace& face = pMesh->mFaces[i]; aiFace& face = pMesh->mFaces[i];
if (face.mNumIndices > AI_MAX_FACE_INDICES) {
ReportError("Face %u has too many faces: %u, but the limit is %u",i,face.mNumIndices,AI_MAX_FACE_INDICES);
}
for (unsigned int a = 0; a < face.mNumIndices;++a) for (unsigned int a = 0; a < face.mNumIndices;++a)
{ {
if (face.mIndices[a] >= pMesh->mNumVertices) { if (face.mIndices[a] >= pMesh->mNumVertices) {
@ -450,10 +461,10 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
ReportError("aiMesh::mBones is NULL (aiMesh::mNumBones is %i)", ReportError("aiMesh::mBones is NULL (aiMesh::mNumBones is %i)",
pMesh->mNumBones); pMesh->mNumBones);
} }
float* afSum = NULL; boost::scoped_array<float> afSum(NULL);
if (pMesh->mNumVertices) if (pMesh->mNumVertices)
{ {
afSum = new float[pMesh->mNumVertices]; afSum.reset(new float[pMesh->mNumVertices]);
for (unsigned int i = 0; i < pMesh->mNumVertices;++i) for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
afSum[i] = 0.0f; afSum[i] = 0.0f;
} }
@ -461,19 +472,22 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
// check whether there are duplicate bone names // check whether there are duplicate bone names
for (unsigned int i = 0; i < pMesh->mNumBones;++i) for (unsigned int i = 0; i < pMesh->mNumBones;++i)
{ {
const aiBone* bone = pMesh->mBones[i];
if (bone->mNumWeights > AI_MAX_BONE_WEIGHTS) {
ReportError("Bone %u has too many weights: %u, but the limit is %u",i,bone->mNumWeights,AI_MAX_BONE_WEIGHTS);
}
if (!pMesh->mBones[i]) if (!pMesh->mBones[i])
{ {
delete[] afSum;
ReportError("aiMesh::mBones[%i] is NULL (aiMesh::mNumBones is %i)", ReportError("aiMesh::mBones[%i] is NULL (aiMesh::mNumBones is %i)",
i,pMesh->mNumBones); i,pMesh->mNumBones);
} }
Validate(pMesh,pMesh->mBones[i],afSum); Validate(pMesh,pMesh->mBones[i],afSum.get());
for (unsigned int a = i+1; a < pMesh->mNumBones;++a) for (unsigned int a = i+1; a < pMesh->mNumBones;++a)
{ {
if (pMesh->mBones[i]->mName == pMesh->mBones[a]->mName) if (pMesh->mBones[i]->mName == pMesh->mBones[a]->mName)
{ {
delete[] afSum;
ReportError("aiMesh::mBones[%i] has the same name as " ReportError("aiMesh::mBones[%i] has the same name as "
"aiMesh::mBones[%i]",i,a); "aiMesh::mBones[%i]",i,a);
} }
@ -486,7 +500,6 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
ReportWarning("aiMesh::mVertices[%i]: bone weight sum != 1.0 (sum is %f)",i,afSum[i]); ReportWarning("aiMesh::mVertices[%i]: bone weight sum != 1.0 (sum is %f)",i,afSum[i]);
} }
} }
delete[] afSum;
} }
else if (pMesh->mBones) else if (pMesh->mBones)
{ {

Binary file not shown.

View File

@ -52,6 +52,54 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
extern "C" { extern "C" {
#endif #endif
// ---------------------------------------------------------------------------
// Limits. These values are required to match the settings Assimp was
// compiled against. Therfore, do not redefine them unless you build the
// library from source using the same definitions.
// ---------------------------------------------------------------------------
/** @def AI_MAX_FACE_INDICES
* Maximum number of indices per face (polygon). */
#ifndef AI_MAX_FACE_INDICES
# define AI_MAX_FACE_INDICES 0x7fff
#endif
/** @def AI_MAX_BONE_WEIGHTS
* Maximum number of indices per face (polygon). */
#ifndef AI_MAX_BONE_WEIGHTS
# define AI_MAX_BONE_WEIGHTS 0x7fffffff
#endif
/** @def AI_MAX_VERTICES
* Maximum number of vertices per mesh. */
#ifndef AI_MAX_VERTICES
# define AI_MAX_VERTICES 0x7fffffff
#endif
/** @def AI_MAX_FACES
* Maximum number of faces per mesh. */
#ifndef AI_MAX_FACES
# define AI_MAX_FACES 0x7fffffff
#endif
/** @def AI_MAX_NUMBER_OF_COLOR_SETS
* Supported number of vertex color sets per mesh. */
#ifndef AI_MAX_NUMBER_OF_COLOR_SETS
# define AI_MAX_NUMBER_OF_COLOR_SETS 0x4
#endif // !! AI_MAX_NUMBER_OF_COLOR_SETS
/** @def AI_MAX_NUMBER_OF_TEXTURECOORDS
* Supported number of texture coord sets (UV(W) channels) per mesh */
#ifndef AI_MAX_NUMBER_OF_TEXTURECOORDS
# define AI_MAX_NUMBER_OF_TEXTURECOORDS 0x4
#endif // !! AI_MAX_NUMBER_OF_TEXTURECOORDS
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief A single face in a mesh, referring to multiple vertices. /** @brief A single face in a mesh, referring to multiple vertices.
* *
@ -76,7 +124,8 @@ extern "C" {
*/ */
struct aiFace struct aiFace
{ {
//! Number of indices defining this face. 3 for a triangle, >3 for polygon //! Number of indices defining this face.
//! The maximum value for this member is #AI_MAX_FACE_INDICES.
unsigned int mNumIndices; unsigned int mNumIndices;
//! Pointer to the indices array. Size of the array is given in numIndices. //! Pointer to the indices array. Size of the array is given in numIndices.
@ -181,6 +230,7 @@ struct aiBone
C_STRUCT aiString mName; C_STRUCT aiString mName;
//! The number of vertices affected by this bone //! The number of vertices affected by this bone
//! The maximum value for this member is #AI_MAX_BONE_WEIGHTS.
unsigned int mNumWeights; unsigned int mNumWeights;
//! The vertices affected by this bone //! The vertices affected by this bone
@ -219,36 +269,6 @@ struct aiBone
#endif // __cplusplus #endif // __cplusplus
}; };
#ifndef AI_MAX_NUMBER_OF_COLOR_SETS
// ---------------------------------------------------------------------------
/** @def AI_MAX_NUMBER_OF_COLOR_SETS
* Maximum number of vertex color sets per mesh.
*
* Normally: Diffuse, specular, ambient and emissive
* However one could use the vertex color sets for any other purpose, too.
*
* @note Some internal structures expect (and assert) this value
* to be at least 4. For the moment it is absolutely safe to assume that
* this will never change.
*/
# define AI_MAX_NUMBER_OF_COLOR_SETS 0x4
#endif // !! AI_MAX_NUMBER_OF_COLOR_SETS
#ifndef AI_MAX_NUMBER_OF_TEXTURECOORDS
// ---------------------------------------------------------------------------
/** @def AI_MAX_NUMBER_OF_TEXTURECOORDS
* Maximum number of texture coord sets (UV(W) channels) per mesh
*
* The material system uses the AI_MATKEY_UVWSRC_XXX keys to specify
* which UVW channel serves as data source for a texture.
*
* @note Some internal structures expect (and assert) this value
* to be at least 4. For the moment it is absolutely safe to assume that
* this will never change.
*/
# define AI_MAX_NUMBER_OF_TEXTURECOORDS 0x4
#endif // !! AI_MAX_NUMBER_OF_TEXTURECOORDS
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Enumerates the types of geometric primitives supported by Assimp. /** @brief Enumerates the types of geometric primitives supported by Assimp.
@ -430,7 +450,7 @@ struct aiAnimMesh
* *
* A Mesh uses only a single material which is referenced by a material ID. * A Mesh uses only a single material which is referenced by a material ID.
* @note The mPositions member is usually not optional. However, vertex positions * @note The mPositions member is usually not optional. However, vertex positions
* *could* be missing if the AI_SCENE_FLAGS_INCOMPLETE flag is set in * *could* be missing if the #AI_SCENE_FLAGS_INCOMPLETE flag is set in
* @code * @code
* aiScene::mFlags * aiScene::mFlags
* @endcode * @endcode
@ -445,12 +465,14 @@ struct aiMesh
unsigned int mPrimitiveTypes; unsigned int mPrimitiveTypes;
/** The number of vertices in this mesh. /** The number of vertices in this mesh.
* This is also the size of all of the per-vertex data arrays * This is also the size of all of the per-vertex data arrays.
* The maximum value for this member is #AI_MAX_VERTICES.
*/ */
unsigned int mNumVertices; unsigned int mNumVertices;
/** The number of primitives (triangles, polygons, lines) in this mesh. /** The number of primitives (triangles, polygons, lines) in this mesh.
* This is also the size of the mFaces array * This is also the size of the mFaces array.
* The maximum value for this member is #AI_MAX_FACES.
*/ */
unsigned int mNumFaces; unsigned int mNumFaces;
@ -531,7 +553,7 @@ struct aiMesh
/** The faces the mesh is constructed from. /** The faces the mesh is constructed from.
* Each face refers to a number of vertices by their indices. * Each face refers to a number of vertices by their indices.
* This array is always present in a mesh, its size is given * This array is always present in a mesh, its size is given
* in mNumFaces. If the AI_SCENE_FLAGS_NON_VERBOSE_FORMAT * in mNumFaces. If the #AI_SCENE_FLAGS_NON_VERBOSE_FORMAT
* is NOT set each face references an unique set of vertices. * is NOT set each face references an unique set of vertices.
*/ */
C_STRUCT aiFace* mFaces; C_STRUCT aiFace* mFaces;
@ -631,7 +653,7 @@ struct aiMesh
} }
//! Check whether the mesh contains positions. Provided no special //! Check whether the mesh contains positions. Provided no special
//! scene flags are set (such as AI_SCENE_FLAGS_ANIM_SKELETON_ONLY), //! scene flags are set (such as #AI_SCENE_FLAGS_ANIM_SKELETON_ONLY),
//! this will always be true //! this will always be true
bool HasPositions() const bool HasPositions() const
{ return mVertices != NULL && mNumVertices > 0; } { return mVertices != NULL && mNumVertices > 0; }