[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