[Bf-blender-cvs] [48e1058e9df] temp-trimesh-sculpt: edge collapse mostly works. need to track down more memory corruption bugs.

Joseph Eagar noreply at git.blender.org
Wed Oct 14 04:05:51 CEST 2020


Commit: 48e1058e9df1a6a153aab22e3ccf78d1e7d0e1a7
Author: Joseph Eagar
Date:   Tue Oct 13 18:59:21 2020 -0700
Branches: temp-trimesh-sculpt
https://developer.blender.org/rB48e1058e9df1a6a153aab22e3ccf78d1e7d0e1a7

edge collapse mostly works.  need to track down more memory corruption
bugs.

===================================================================

M	source/blender/blenkernel/intern/pbvh_trimesh.c
M	source/blender/blenlib/BLI_threadsafe_mempool.h
M	source/blender/blenlib/intern/BLI_threadsafe_mempool.c
M	source/blender/trimesh/intern/trimesh_private.h
M	source/blender/trimesh/trimesh.h

===================================================================

diff --git a/source/blender/blenkernel/intern/pbvh_trimesh.c b/source/blender/blenkernel/intern/pbvh_trimesh.c
index 486b04fa7d8..4129cddac9f 100644
--- a/source/blender/blenkernel/intern/pbvh_trimesh.c
+++ b/source/blender/blenkernel/intern/pbvh_trimesh.c
@@ -435,7 +435,7 @@ static TMVert *pbvh_trimesh_vert_create(
   TMVert *v = TM_make_vert(bvh->tm, co, no, 0, false);
 
   if (node_index < 0 || node_index >= bvh->totnode) {
-    printf("eek!");
+    printf("eek!\n");
     return v;
   }
 
@@ -932,7 +932,7 @@ static void long_edge_queue_face_add(EdgeQueueContext *eq_ctx, TMFace *f)
 
       if (len_sq > eq_ctx->q->limit_len_squared) {
         if (e->v1->edges.length > 24 || e->v2->edges.length > 24) {
-          printf("eek! %.4f", len_sq);
+          //printf("eek! %.4f %d %d\n", len_sq, e->v1->edges.length, e->v2->edges.length);
           continue;
         }
 
@@ -1307,13 +1307,19 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
   pbvh_trimesh_vert_remove(bvh, v_del);
 
   /* Remove all faces adjacent to the edge */
-  for (int i=0; i<e->tris.length; i++) {
+  while (e->tris.length) {
+    int lastlen = e->tris.length;
     TMFace *f_adj = e->tris.items[0];
 
     pbvh_trimesh_face_remove(bvh, f_adj);
 
     //XXX check threadnr argument!
     TM_kill_tri(bvh->tm, f_adj, 0, false, false);
+
+    if (lastlen == e->tris.length) { //paranoia check
+      printf("eek! %s %d\n", __FILE__, __LINE__);
+      break;
+    }
   }
 
   /* Kill the edge */
@@ -1329,13 +1335,43 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
   * really buy anything. */
   BLI_buffer_clear(deleted_faces);
 
+  TM_ITER_VERT_TRIEDGES(v_del, tri, e) {
+    tri->flag &= ~TRIMESH_TEMP_TAG;
+
+    TMEdge *e2 = TM_nextEdgeInTri(tri, e);
+    for (int i=0; i<e2->tris.length; i++) {
+      TMFace *tri2 = e2->tris.items[i];
+
+      tri2->flag &= ~TRIMESH_TEMP_TAG;
+
+      for (int j=0; j<3; j++) {
+        TMEdge *e3 = TM_GET_TRI_EDGE(tri2, j);
+        for (int k=0; k<e3->tris.length; k++) {
+          TMFace *tri3 = e3->tris.items[k];
+
+          tri3->flag &= ~TRIMESH_TEMP_TAG;
+        }
+      }
+    }
+  } TM_ITER_VERT_TRIEDGES_END
+
   TM_ITER_VERT_TRIEDGES(v_del, tri, e) {
     TMEdge *e2 = TM_nextEdgeInTri(tri, e);
     TMFace *existing_face = NULL;
+    TMVert *v2 = TM_nextVertInTri(tri, v_del);
+
+    if (v2 == TM_other_vert(e, v_del)) {
+      v2 = TM_prevVertInTri(tri, v_del);
+    }
 
-    if (UNLIKELY(existing_face = TM_tri_exists(v_conn, e2->v1, e->v2))) {
-      BLI_buffer_append(deleted_faces, TMFace *, existing_face);
-    } else {
+    if (UNLIKELY(existing_face = TM_tri_exists(v_conn, v2, v_del))) {
+      if (!(existing_face->flag & TRIMESH_TEMP_TAG)) {
+        BLI_buffer_append(deleted_faces, TMFace *, existing_face);
+        existing_face->flag |= TRIMESH_TEMP_TAG;
+      } else {
+        printf("eek! %s %d\n", __FILE__, __LINE__);
+      }
+    } else if (1) {
       TMVert *v_tri[3] = {v_conn, TM_nextVertInTri(tri, v_del), TM_prevVertInTri(tri, v_del)};
 
       //BLI_assert(!BM_face_exists(v_tri, 3));
@@ -1351,6 +1387,11 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
         BLI_gset_add(n->tm_other_verts, v_conn);
       }
     }
+
+    if (!(tri->flag & TRIMESH_TEMP_TAG)) {
+      tri->flag |= TRIMESH_TEMP_TAG;
+      BLI_buffer_append(deleted_faces, TMFace *, tri);
+    }
   } TM_ITER_VERT_TRIEDGES_END
 
   /* Delete the tagged faces */
@@ -1363,14 +1404,16 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
     TMEdge *e_tri[3];
 
     v_tri[0] = f_del->v1;
-    e_tri[0] = f_del->e1;
     v_tri[1] = f_del->v2;
-    e_tri[1] = f_del->e2;
     v_tri[2] = f_del->v3;
+
+    e_tri[0] = f_del->e1;
+    e_tri[1] = f_del->e2;
     e_tri[2] = f_del->e3;
 
     /* Remove the face */
     pbvh_trimesh_face_remove(bvh, f_del);
+
     TM_kill_tri(bvh->tm, f_del, 0, false, false);
 
     /* Check if any of the face's edges are now unused by any
@@ -1423,6 +1466,10 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
 
   /* Delete v_del */
   BLI_assert(!TM_vert_face_check(v_del));
+  if (TM_vert_face_check(v_del)) {
+    printf("eek! %s %d\n", __FILE__, __LINE__);
+  }
+
   BLI_trimesh_log_vert_kill(bvh->tm_log, v_del);
 
   /* v_conn == NULL is OK */
@@ -1434,7 +1481,6 @@ static bool pbvh_trimesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
   PBVH *bvh,
   BLI_Buffer *deleted_faces)
 {
-  return false;
   const float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
   bool any_collapsed = false;
   /* deleted verts point to vertices they were merged into, or NULL when removed. */
diff --git a/source/blender/blenlib/BLI_threadsafe_mempool.h b/source/blender/blenlib/BLI_threadsafe_mempool.h
index 0a97104343c..d11c1eb83fa 100644
--- a/source/blender/blenlib/BLI_threadsafe_mempool.h
+++ b/source/blender/blenlib/BLI_threadsafe_mempool.h
@@ -78,7 +78,7 @@ typedef struct pool_thread_data {
 
 typedef struct BLI_ThreadSafePool {
   pool_thread_data* threadchunks;
-  int maxthread;
+  int maxthread, checkmagic;
 
 #ifdef BLI_SAFEPOOL_HAVE_LENGTH
   unsigned int length;
@@ -89,6 +89,7 @@ typedef struct BLI_ThreadSafePool {
 
 
 #define DEAD_MAGIC ('d' | ('e' << 8) | ('a' << 16) | ('d' || 24))
+#define _SPOOL_MAGIC ('s' | ('p' << 8) | ('o' << 16) | ('l' || 24))
 
 BLI_INLINE void lock_all_threads(BLI_ThreadSafePool* pool) {
   for (int i = 0; i < pool->maxthread; i++) {
diff --git a/source/blender/blenlib/intern/BLI_threadsafe_mempool.c b/source/blender/blenlib/intern/BLI_threadsafe_mempool.c
index 1c58d88688d..84c4a354b4f 100644
--- a/source/blender/blenlib/intern/BLI_threadsafe_mempool.c
+++ b/source/blender/blenlib/intern/BLI_threadsafe_mempool.c
@@ -89,6 +89,8 @@ static poolchunk *new_chunk(BLI_ThreadSafePool *pool, pool_thread_data* thread_d
 BLI_ThreadSafePool* BLI_safepool_create(int elemsize, int chunksize, int maxthread) {
   BLI_ThreadSafePool* pool = MEM_callocN(sizeof(*pool), "BLI_ThreadSafePool");
 
+  pool->checkmagic = _SPOOL_MAGIC;
+
   //align to pointer size
   if (elemsize & 7) {
     elemsize += 8 - (elemsize & 7);
@@ -142,6 +144,8 @@ void BLI_safepool_destroy(BLI_ThreadSafePool* pool) {
   BLI_rw_mutex_end(&pool->length_lock);
 #endif
 
+  pool->checkmagic = 0;
+
   MEM_freeN(pool->threadchunks);
   MEM_freeN(pool);
 }
@@ -165,6 +169,9 @@ void* BLI_safepool_alloc(BLI_ThreadSafePool *pool) {
     pool->length++;
     BLI_rw_mutex_unlock(&pool->lengthlock);
 #endif
+
+    de->dead_magic = 0;
+
     return (void*) &de->next;
   }
 
@@ -185,13 +192,58 @@ int get_elem_thread(BLI_ThreadSafePool* pool, void* elem) {
   return ret;
 }
 
+static bool memcheck(void *mem) {
+  bool bad = !mem;
+  bad = bad || (((intptr_t)mem) & 0x7);
+
+  return bad;
+}
+
+bool check_safepool_elem(BLI_ThreadSafePool* pool, void* elem) {
+  if (pool->checkmagic != _SPOOL_MAGIC) {
+    printf("corrupted pool in safepool free! %p\n", pool);
+    return false;
+  }
+
+  if (memcheck((void*)pool)) {
+    printf("bad pool in safepool free! %p\n", pool);
+    return false;
+  }
+
+  bool bad = !elem;
+  bad = bad || (((intptr_t)elem) & 0x7);
+
+  if (bad) {
+    printf("bad memory in safepool free! %p\n", elem);
+    return false;
+  }
+
+  return true;
+
+  for (int i=0; i<pool->maxthread; i++) {
+    pool_thread_data *data = pool->threadchunks + i;
+    poolchunk *chunk;
+
+    for (chunk = (poolchunk*) data->chunks.first; chunk; chunk=chunk->next) {
+      char *p1 = (char*) chunk;
+      char *p2 = (char*) elem;
+
+      if (p2 >= p1 && p2 < p1 + sizeof(poolchunk) + pool->esize*pool->csize) {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
 void BLI_safepool_free(BLI_ThreadSafePool* pool, void* elem) {
-  /*hrm.  I could add to the current pool's freelist, couldn't I
-    let's try that
+  //XXX
 
-    int thread = get_elem_thread(pool, elem);
-   */
+  if (!check_safepool_elem(pool, elem)) {
+    return;
+  }
 
+  //add to current thread's free list
   int thread = BLI_thread_local_get(curthread);
 
   if (!pool) {
@@ -204,7 +256,12 @@ void BLI_safepool_free(BLI_ThreadSafePool* pool, void* elem) {
 
   poolelem *de = getelem(elem);
 
-  de->next = tdata->freehead;
+  if (de->dead_magic == DEAD_MAGIC) {
+    printf("error: double free in mem pool %p\n", elem);
+    return;
+  }
+
+  de->next = (poolelem*) tdata->freehead;
   de->dead_magic = DEAD_MAGIC;
   tdata->freehead = de;
   
diff --git a/source/blender/trimesh/intern/trimesh_private.h b/source/blender/trimesh/intern/trimesh_private.h
index a4785cf69f2..05de55ffd93 100644
--- a/source/blender/trimesh/intern/trimesh_private.h
+++ b/source/blender/trimesh/intern/trimesh_private.h
@@ -35,10 +35,14 @@ static void trimesh_simplelist_remove(struct TM_TriMesh *tm, struct optmesh_simp
 
   for (int i=0; i<list->length; i++) {
     if (list->items[i] == item) {
+      //swap with last
+      list->items[i] = list->items[list->length-1];
+
+      /*
       while (i < list->length-1) {
         list->items[i] = list->items[i+1];
         i++;
-      }
+      }*/
 
       list->items[list->length-1] = NULL;
       list->length--;
diff --git a/source/blender/trimesh/trimesh.h b/source/blender/trimesh/trimesh.h
index 8608a6a5a37..549f38c3f43 100644
--- a/source/blender/trimesh/trimesh.h
+++ b/source/blender/trimesh/trimesh.h
@@ -414,6 +414,11 @@ BLI_INLINE int TM_edgeTriIndex(TMEdge *e, TMFace *t) {
   return -1;
 }
 
+
+BLI_INLINE TMVert *TM_other_vert(TMEdge *e, TMVert *v) {
+  return v == e->v1 ? e->v2 : e->v1;
+}
+
 BLI_INLINE TMFace *TM_nextTriInEdge(TMEdge *e, TMFace *t) {
   int i = TM_edgeTriIndex(e, t);
 
@@ -515,39 +520,49 @@ BLI_INLINE TMFace *TM_tri_exists(TMVert *v1, TMVert *v2, TMVert *v3) {
 
 #define TM_ITER_VERT_TRIS(v, tname)\
 for (int _i=0; _i<v->edges.length; _i++) {\
-  TMEdge *e = v->edges.items[_i];\
-  for (int _j=0; _j<e->tris.length; _j++) {\
-    TMFace *t = e->tris.items[_j];\
-    t->flag &= ~TRIMESH_VT_ITERFLAG;\
-  }\
-}\
-for (int _i=0; _i<v->edges.length; _i++) {\
-  TMEdge *e = v->edges.items[_i];\
-  for (int _j=0; _j<e->tris.length; _j++) {\
-    TMFace *tname = e->tris.items[_j];\
-    if (tname->flag & TRIMESH_VT_ITERFLAG) {\
-      continue;\
-    }\
-    tname->flag |= TRIMESH_VT_ITERFLAG;
+  TMEdge *_e = v->edges.items[_i];\
+  for (int 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list