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. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to