ソースを参照

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
aramis_acg 15 年 前
コミット
e5aad11944

+ 1 - 0
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
 	//	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.

+ 21 - 8
code/ValidateDataStructure.cpp

@@ -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)
 	{
 	{

BIN
doc/AssimpDoc_Html/AssimpDoc.chm


+ 58 - 36
include/aiMesh.h

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