diff --git a/code/JoinVerticesProcess.cpp b/code/JoinVerticesProcess.cpp index d5dc1dedb..785837759 100644 --- a/code/JoinVerticesProcess.cpp +++ b/code/JoinVerticesProcess.cpp @@ -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 // unique vertex (false). This saves an additional std::vector and greatly enhances // branching performance. + BOOST_STATIC_ASSERT(AI_MAX_VERTICES == 0x7fffffff); std::vector replaceIndex( pMesh->mNumVertices, 0xffffffff); // A little helper to find locally close vertices faster. diff --git a/code/ValidateDataStructure.cpp b/code/ValidateDataStructure.cpp index c4ad27d8e..4413c28bb 100644 --- a/code/ValidateDataStructure.cpp +++ b/code/ValidateDataStructure.cpp @@ -370,14 +370,21 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh) 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 ((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 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: @@ -387,6 +394,10 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh) for (unsigned int i = 0; i < pMesh->mNumFaces;++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) { 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)", pMesh->mNumBones); } - float* afSum = NULL; + boost::scoped_array afSum(NULL); if (pMesh->mNumVertices) { - afSum = new float[pMesh->mNumVertices]; + afSum.reset(new float[pMesh->mNumVertices]); for (unsigned int i = 0; i < pMesh->mNumVertices;++i) afSum[i] = 0.0f; } @@ -461,19 +472,22 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh) // check whether there are duplicate bone names 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]) { - delete[] afSum; ReportError("aiMesh::mBones[%i] is NULL (aiMesh::mNumBones is %i)", 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) { if (pMesh->mBones[i]->mName == pMesh->mBones[a]->mName) { - delete[] afSum; ReportError("aiMesh::mBones[%i] has the same name as " "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]); } } - delete[] afSum; } else if (pMesh->mBones) { diff --git a/doc/AssimpDoc_Html/AssimpDoc.chm b/doc/AssimpDoc_Html/AssimpDoc.chm index b36e076d8..a25a79302 100644 Binary files a/doc/AssimpDoc_Html/AssimpDoc.chm and b/doc/AssimpDoc_Html/AssimpDoc.chm differ diff --git a/include/aiMesh.h b/include/aiMesh.h index 0844f1601..7c6f0879e 100644 --- a/include/aiMesh.h +++ b/include/aiMesh.h @@ -52,6 +52,54 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. extern "C" { #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. * @@ -76,7 +124,8 @@ extern "C" { */ 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; //! Pointer to the indices array. Size of the array is given in numIndices. @@ -181,6 +230,7 @@ struct aiBone C_STRUCT aiString mName; //! The number of vertices affected by this bone + //! The maximum value for this member is #AI_MAX_BONE_WEIGHTS. unsigned int mNumWeights; //! The vertices affected by this bone @@ -219,36 +269,6 @@ struct aiBone #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. @@ -430,7 +450,7 @@ struct aiAnimMesh * * 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 -* *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 * aiScene::mFlags * @endcode @@ -445,12 +465,14 @@ struct aiMesh unsigned int mPrimitiveTypes; /** 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; /** 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; @@ -531,7 +553,7 @@ struct aiMesh /** The faces the mesh is constructed from. * Each face refers to a number of vertices by their indices. * 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. */ C_STRUCT aiFace* mFaces; @@ -631,7 +653,7 @@ struct aiMesh } //! 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 bool HasPositions() const { return mVertices != NULL && mNumVertices > 0; }