[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