[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [34741] trunk/blender/source/blender: BKE_mesh_validate() now corrects invalid meshes (optionally), added access for python so it can correct for bad imported geometry - mesh .validate().

Campbell Barton ideasman42 at gmail.com
Wed Feb 9 16:13:24 CET 2011


Revision: 34741
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=34741
Author:   campbellbarton
Date:     2011-02-09 15:13:20 +0000 (Wed, 09 Feb 2011)
Log Message:
-----------
BKE_mesh_validate() now corrects invalid meshes (optionally), added access for python so it can correct for bad imported geometry - mesh.validate().

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_mesh.h
    trunk/blender/source/blender/blenkernel/intern/mesh.c
    trunk/blender/source/blender/blenkernel/intern/mesh_validate.c
    trunk/blender/source/blender/editors/mesh/mesh_data.c
    trunk/blender/source/blender/makesrna/intern/rna_mesh_api.c

Modified: trunk/blender/source/blender/blenkernel/BKE_mesh.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_mesh.h	2011-02-09 12:50:08 UTC (rev 34740)
+++ trunk/blender/source/blender/blenkernel/BKE_mesh.h	2011-02-09 15:13:20 UTC (rev 34741)
@@ -89,7 +89,9 @@
 
 /* if old, it converts mface->edcode to edge drawflags */
 void make_edges(struct Mesh *me, int old);
+
 void mesh_strip_loose_faces(struct Mesh *me);
+void mesh_strip_loose_edges(struct Mesh *me);
 
 	/* Calculate vertex and face normals, face normals are returned in *faceNors_r if non-NULL
 	 * and vertex normals are stored in actual mverts.
@@ -150,10 +152,12 @@
 void mesh_translate(struct Mesh *me, float offset[3], int do_keys);
 
 /* mesh_validate.c */
-void BKE_mesh_validate_arrays(struct MVert *mverts, int totvert, struct MEdge *medges, int totedge, struct MFace *mfaces, int totface);
+void BKE_mesh_validate_arrays(struct Mesh *me, struct MVert *mverts, int totvert, struct MEdge *medges, int totedge, struct MFace *mfaces, int totface, const short do_verbose, const short do_fixes);
 void BKE_mesh_validate(struct Mesh *me);
 void BKE_mesh_validate_dm(struct DerivedMesh *dm);
 
+void BKE_mesh_calc_edges(struct Mesh *mesh, int update);
+
 #ifdef __cplusplus
 }
 #endif

Modified: trunk/blender/source/blender/blenkernel/intern/mesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/mesh.c	2011-02-09 12:50:08 UTC (rev 34740)
+++ trunk/blender/source/blender/blenkernel/intern/mesh.c	2011-02-09 15:13:20 UTC (rev 34741)
@@ -704,6 +704,23 @@
 	me->totface = b;
 }
 
+void mesh_strip_loose_edges(Mesh *me)
+{
+	int a,b;
+
+	for (a=b=0; a<me->totedge; a++) {
+		if (me->medge[a].v1==me->medge[a].v2) {
+			if (a!=b) {
+				memcpy(&me->medge[b],&me->medge[a],sizeof(me->medge[b]));
+				CustomData_copy_data(&me->edata, &me->edata, a, b, 1);
+				CustomData_free_elem(&me->edata, a, 1);
+			}
+			b++;
+		}
+	}
+	me->totedge = b;
+}
+
 void mball_to_mesh(ListBase *lb, Mesh *me)
 {
 	DispList *dl;

Modified: trunk/blender/source/blender/blenkernel/intern/mesh_validate.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/mesh_validate.c	2011-02-09 12:50:08 UTC (rev 34740)
+++ trunk/blender/source/blender/blenkernel/intern/mesh_validate.c	2011-02-09 15:13:20 UTC (rev 34741)
@@ -31,6 +31,8 @@
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 
+#include "BLO_sys_types.h"
+
 #include "BLI_utildefines.h"
 #include "BLI_edgehash.h"
 
@@ -38,13 +40,47 @@
 
 #include "MEM_guardedalloc.h"
 
-#include "ED_mesh.h"
+#include "BKE_mesh.h"
 
+#define SELECT 1
+
 typedef struct SearchFace {
 	unsigned int v[4];
 	unsigned int index;
 } SearchFace;
 
+typedef union {
+	uint32_t verts[2];
+	int64_t edval;
+} EdgeStore;
+
+static void edge_store_assign(uint32_t verts[2],  const uint32_t v1, const uint32_t v2)
+{
+	if(v1 < v2) {
+		verts[0]= v1;
+		verts[1]= v2;
+	}
+	else {
+		verts[0]= v2;
+		verts[1]= v1;
+	}
+}
+
+static void edge_store_from_mface_quad(EdgeStore es[3], MFace *mf)
+{
+	edge_store_assign(es[0].verts, mf->v1, mf->v2);
+	edge_store_assign(es[1].verts, mf->v2, mf->v3);
+	edge_store_assign(es[2].verts, mf->v3, mf->v4);
+	edge_store_assign(es[2].verts, mf->v4, mf->v1);
+}
+
+static void edge_store_from_mface_tri(EdgeStore es[3], MFace *mf)
+{
+	edge_store_assign(es[0].verts, mf->v1, mf->v2);
+	edge_store_assign(es[1].verts, mf->v2, mf->v3);
+	edge_store_assign(es[2].verts, mf->v3, mf->v1);
+}
+
 static int uint_cmp(const void *v1, const void *v2)
 {
 	const unsigned int x1= GET_INT_FROM_POINTER(v1), x2= GET_INT_FROM_POINTER(v2);
@@ -73,187 +109,296 @@
 	return 0;
 }
 
-void BKE_mesh_validate_arrays(MVert *UNUSED(mverts), int totvert, MEdge *medges, int totedge, MFace *mfaces, int totface)
+void BKE_mesh_validate_arrays(Mesh *me, MVert *UNUSED(mverts), int totvert, MEdge *medges, int totedge, MFace *mfaces, int totface, const short do_verbose, const short do_fixes)
 {
+#	define PRINT if(do_verbose) printf
+#	define REMOVE_EDGE_TAG(_med) { _med->v2= _med->v1; do_edge_free= 1; }
+#	define REMOVE_FACE_TAG(_mf) { _mf->v3=0; do_face_free= 1; }
+
 //	MVert *mv;
 	MEdge *med;
 	MFace *mf;
 	int i;
 
+	int do_face_free= FALSE;
+	int do_edge_free= FALSE;
+
+	int do_edge_recalc= FALSE;
+
 	EdgeHash *edge_hash = BLI_edgehash_new();
 
 	SearchFace *search_faces= MEM_callocN(sizeof(SearchFace) * totface, "search faces");
 	SearchFace *sf;
 	SearchFace *sf_prev;
+	int totsearchface= 0;
 
-	printf("ED_mesh_validate: verts(%d), edges(%d), faces(%d)\n", totvert, totedge, totface);
+	BLI_assert(!(do_fixes && me == NULL));
 
-	if(totedge==0 && totface != 0) {
-		printf("    locical error, %d faces and 0 edges\n", totface);
+	PRINT("ED_mesh_validate: verts(%d), edges(%d), faces(%d)\n", totvert, totedge, totface);
+
+	if(totedge == 0 && totface != 0) {
+		PRINT("    locical error, %d faces and 0 edges\n", totface);
+		do_edge_recalc= TRUE;
 	}
 
-	for(i=0, med=medges; i<totedge; i++, med++) {
+	for(i=0, med= medges; i<totedge; i++, med++) {
+		int remove= FALSE;
 		if(med->v1 == med->v2) {
-			printf("    edge %d: has matching verts, both %d\n", i, med->v1);
+			PRINT("    edge %d: has matching verts, both %d\n", i, med->v1);
+			remove= do_fixes;
 		}
-		if(med->v1 < 0 || med->v1 >= totvert) {
-			printf("    edge %d: v1 index out of range, %d\n", i, med->v1);
+		if(med->v1 >= totvert) {
+			PRINT("    edge %d: v1 index out of range, %d\n", i, med->v1);
+			remove= do_fixes;
 		}
-		if(med->v2 < 0 || med->v2 >= totvert) {
-			printf("    edge %d: v2 index out of range, %d\n", i, med->v2);
+		if(med->v2 >= totvert) {
+			PRINT("    edge %d: v2 index out of range, %d\n", i, med->v2);
+			remove= do_fixes;
 		}
 
 		if(BLI_edgehash_haskey(edge_hash, med->v1, med->v2)) {
-			printf("    edge %d: is a duplicate of, %d\n", i, GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, med->v1, med->v2)));
+			PRINT("    edge %d: is a duplicate of, %d\n", i, GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, med->v1, med->v2)));
+			remove= do_fixes;
 		}
 
-		BLI_edgehash_insert(edge_hash, med->v1, med->v2, SET_INT_IN_POINTER(i));
+		if(remove == FALSE){
+			BLI_edgehash_insert(edge_hash, med->v1, med->v2, SET_INT_IN_POINTER(i));
+		}
+		else {
+			REMOVE_EDGE_TAG(med);
+		}
 	}
 
 	for(i=0, mf=mfaces; i<totface; i++, mf++) {
 		unsigned int fverts[4];
 		// unsigned int fedges[4];
 		int fidx;
+		int remove= FALSE;
 
 		fidx = mf->v4 ? 3:2;
 		do {
 			fverts[fidx]= *(&mf->v1 + fidx);
-			if(fverts[fidx] < 0 || fverts[fidx] >= totvert) {
-				printf("    face %d: 'v%d' index out of range, %d\n", i, fidx + 1, fverts[fidx]);
+			if(fverts[fidx] >= totvert) {
+				PRINT("    face %d: 'v%d' index out of range, %d\n", i, fidx + 1, fverts[fidx]);
+				remove= do_fixes;
 			}
 		} while (fidx--);
 
-		if(mf->v4) {
-			if(mf->v1 == mf->v2) printf("    face %d: verts invalid, v1/v2 both %d\n", i, mf->v1);
-			if(mf->v1 == mf->v3) printf("    face %d: verts invalid, v1/v3 both %d\n", i, mf->v1);
-			if(mf->v1 == mf->v4) printf("    face %d: verts invalid, v1/v4 both %d\n", i, mf->v1);
+		if(remove == FALSE) {
+			if(mf->v4) {
+				if(mf->v1 == mf->v2) { PRINT("    face %d: verts invalid, v1/v2 both %d\n", i, mf->v1); remove= do_fixes; }
+				if(mf->v1 == mf->v3) { PRINT("    face %d: verts invalid, v1/v3 both %d\n", i, mf->v1); remove= do_fixes;  }
+				if(mf->v1 == mf->v4) { PRINT("    face %d: verts invalid, v1/v4 both %d\n", i, mf->v1); remove= do_fixes;  }
 
-			if(mf->v2 == mf->v3) printf("    face %d: verts invalid, v2/v3 both %d\n", i, mf->v2);
-			if(mf->v2 == mf->v4) printf("    face %d: verts invalid, v2/v4 both %d\n", i, mf->v2);
+				if(mf->v2 == mf->v3) { PRINT("    face %d: verts invalid, v2/v3 both %d\n", i, mf->v2); remove= do_fixes;  }
+				if(mf->v2 == mf->v4) { PRINT("    face %d: verts invalid, v2/v4 both %d\n", i, mf->v2); remove= do_fixes;  }
 
-			if(mf->v3 == mf->v4) printf("    face %d: verts invalid, v3/v4 both %d\n", i, mf->v3);
+				if(mf->v3 == mf->v4) { PRINT("    face %d: verts invalid, v3/v4 both %d\n", i, mf->v3); remove= do_fixes;  }
+			}
+			else {
+				if(mf->v1 == mf->v2) { PRINT("    faceT %d: verts invalid, v1/v2 both %d\n", i, mf->v1); remove= do_fixes; }
+				if(mf->v1 == mf->v3) { PRINT("    faceT %d: verts invalid, v1/v3 both %d\n", i, mf->v1); remove= do_fixes; }
 
-			if(totedge) {
-				if(!BLI_edgehash_haskey(edge_hash, mf->v1, mf->v2)) printf("    face %d: edge v1/v2 (%d,%d) is missing egde data\n", i, mf->v1, mf->v2);
-				if(!BLI_edgehash_haskey(edge_hash, mf->v2, mf->v3)) printf("    face %d: edge v2/v3 (%d,%d) is missing egde data\n", i, mf->v2, mf->v3);
-				if(!BLI_edgehash_haskey(edge_hash, mf->v3, mf->v4)) printf("    face %d: edge v3/v4 (%d,%d) is missing egde data\n", i, mf->v3, mf->v4);
-				if(!BLI_edgehash_haskey(edge_hash, mf->v4, mf->v1)) printf("    face %d: edge v4/v1 (%d,%d) is missing egde data\n", i, mf->v4, mf->v1);
+				if(mf->v2 == mf->v3) { PRINT("    faceT %d: verts invalid, v2/v3 both %d\n", i, mf->v2); remove= do_fixes; }
 			}
-			/* TODO, avoid double lookop */
-			/*
-			fedges[0]= GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, mf->v1, mf->v2));
-			fedges[1]= GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, mf->v2, mf->v3));
-			fedges[2]= GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, mf->v3, mf->v4));
-			fedges[3]= GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, mf->v4, mf->v1));
-			*/
-			qsort(fverts, 4, sizeof(int), uint_cmp);
-		}
-		else {
-			if(mf->v1 == mf->v2) printf("    face %d: verts invalid, v1/v2 both %d\n", i, mf->v1);
-			if(mf->v1 == mf->v3) printf("    face %d: verts invalid, v1/v3 both %d\n", i, mf->v1);
 
-			if(mf->v2 == mf->v3) printf("    face %d: verts invalid, v2/v3 both %d\n", i, mf->v2);
+			if(remove == FALSE) {
+				if(totedge) {
+					if(mf->v4) {
+						if(!BLI_edgehash_haskey(edge_hash, mf->v1, mf->v2)) { PRINT("    face %d: edge v1/v2 (%d,%d) is missing egde data\n", i, mf->v1, mf->v2); do_edge_recalc= TRUE; }
+						if(!BLI_edgehash_haskey(edge_hash, mf->v2, mf->v3)) { PRINT("    face %d: edge v2/v3 (%d,%d) is missing egde data\n", i, mf->v2, mf->v3); do_edge_recalc= TRUE; }
+						if(!BLI_edgehash_haskey(edge_hash, mf->v3, mf->v4)) { PRINT("    face %d: edge v3/v4 (%d,%d) is missing egde data\n", i, mf->v3, mf->v4); do_edge_recalc= TRUE; }

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list