Commit: 1694e2aca4f8dd4203ee63ef2581b480d7a61f09
Author: Joseph Eagar
Date: Tue Jul 20 04:14:59 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB1694e2aca4f8dd4203ee63ef2581b480d7a61f09
Sculpt dyntopo: Face set boundaries are now presered with dyntopo
* Face set boundaries are now preserved on dyntopo remeshing.
* MDynTopoVert->flag now has a DYNVERT_FSET_BOUNDARY flag
in addition to DYNVERT_BOUNDARY.
* Instrumented uiBut with ASAN poison regions to hopefully
find the super evil memory corruption bug that's been driving
me insane. It's frustratingly intermittent. There are five
poison regions.
===================================================================
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/intern/dyntopo.c
M source/blender/blenkernel/intern/pbvh_bmesh.c
M source/blender/blenkernel/intern/pbvh_intern.h
M source/blender/editors/interface/interface.c
M source/blender/editors/interface/interface_handlers.c
M source/blender/editors/interface/interface_intern.h
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M source/blender/makesdna/DNA_meshdata_types.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_pbvh.h
b/source/blender/blenkernel/BKE_pbvh.h
index 84c46ed5315..67c97f17cc0 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -734,6 +734,7 @@ PBVHNode *BKE_pbvh_node_from_face_bmesh(PBVH *pbvh, struct
BMFace *f);
PBVHNode *BKE_pbvh_node_from_index(PBVH *pbvh, int node_i);
struct BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh);
+void BKE_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset,
struct BMVert *v);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/dyntopo.c
b/source/blender/blenkernel/intern/dyntopo.c
index b35a12cc06d..ea64b81a713 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -29,6 +29,8 @@
#include <stdio.h>
+#define DYNVERT_ALL_BOUNDARY (DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY)
+
#define DYNTOPO_MAX_ITER 4096
#define DYNTOPO_USE_HEAP
@@ -138,7 +140,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh);
} \
((void)0)
-BLI_INLINE void surface_smooth_v_safe(BMVert *v, int cd_dyn_vert)
+BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
{
float co[3];
float tan[3];
@@ -152,15 +154,19 @@ BLI_INLINE void surface_smooth_v_safe(BMVert *v, int
cd_dyn_vert)
if (!e) {
return;
}
+ pbvh_check_vert_boundary(pbvh, v);
+ const int cd_dyn_vert = pbvh->cd_dyn_vert;
MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(cd_dyn_vert, v);
- const bool bound1 = mv1->flag & DYNVERT_BOUNDARY;
+ const bool bound1 = mv1->flag & DYNVERT_ALL_BOUNDARY;
do {
BMVert *v2 = e->v1 == v ? e->v2 : e->v1;
+ pbvh_check_vert_boundary(pbvh, v2);
+
MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(cd_dyn_vert, v2);
- const bool bound2 = mv2->flag & DYNVERT_BOUNDARY;
+ const bool bound2 = mv2->flag & DYNVERT_ALL_BOUNDARY;
if (bound1 != bound2) {
e = v == e->v1 ? e->v1_disk_link.next : e->v2_disk_link.next;
@@ -1349,7 +1355,7 @@ static void long_edge_queue_task_cb(void *__restrict
userdata,
do {
// try to improve convergence by applying a small amount of smoothing
to topology,
// but tangentially to surface.
- surface_smooth_v_safe(l_iter->v, cd_dyn_vert);
+ surface_smooth_v_safe(tdata->pbvh, l_iter->v);
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
float w = maskcb_get(eq_ctx, l_iter->e);
@@ -1636,7 +1642,10 @@ static void short_edge_queue_create(EdgeQueueContext
*eq_ctx,
mv1 = BKE_PBVH_DYNVERT(cd_dyn_vert, e->v1);
mv2 = BKE_PBVH_DYNVERT(cd_dyn_vert, e->v2);
- if ((mv1->flag & DYNVERT_BOUNDARY) != (mv2->flag & DYNVERT_BOUNDARY)) {
+ pbvh_check_vert_boundary(pbvh, e->v1);
+ pbvh_check_vert_boundary(pbvh, e->v2);
+
+ if ((mv1->flag & DYNVERT_ALL_BOUNDARY) != (mv2->flag &
DYNVERT_ALL_BOUNDARY)) {
continue;
}
@@ -1675,8 +1684,10 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext
*eq_ctx,
MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, e->v1);
MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, e->v2);
- bool boundary = (mv1->flag & DYNVERT_BOUNDARY) && (mv2->flag &
DYNVERT_BOUNDARY);
- bool check_boundary = (mv1->flag & DYNVERT_BOUNDARY) | (mv2->flag &
DYNVERT_BOUNDARY);
+ pbvh_check_vert_boundary(pbvh, e->v1);
+ pbvh_check_vert_boundary(pbvh, e->v2);
+
+ bool boundary = (mv1->flag & DYNVERT_ALL_BOUNDARY) && (mv2->flag &
DYNVERT_ALL_BOUNDARY);
/* Get all faces adjacent to the edge */
pbvh_bmesh_edge_loops(edge_loops, e);
@@ -1847,14 +1858,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext
*eq_ctx,
BM_edge_kill(pbvh->bm, e);
MDynTopoVert *mv_new = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v_new);
- bool boundary2 = boundary || (check_boundary && BM_vert_is_boundary(v_new));
-
- if (boundary2) {
- mv_new->flag |= DYNVERT_BOUNDARY;
- }
- else {
- mv_new->flag &= ~DYNVERT_BOUNDARY;
- }
+ bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset,
v_new);
}
static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
@@ -2247,12 +2251,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
MDynTopoVert *mv_conn = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v_conn);
- if (BM_vert_is_boundary(v_conn)) {
- mv_conn->flag |= DYNVERT_BOUNDARY;
- }
- else {
- mv_conn->flag &= ~DYNVERT_BOUNDARY;
- }
+ bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset,
v_conn);
}
/* Delete v_del */
@@ -2409,6 +2408,11 @@ ATTR_NO_OPT static bool cleanup_valence_3_4(PBVH *pbvh,
continue;
}
+ MDynTopoVert *mv = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_dyn_vert);
+ if (mv->flag & DYNVERT_ALL_BOUNDARY) {
+ continue;
+ }
+
const int val = BM_vert_edge_count(v);
if (val != 4 && val != 3) {
continue;
@@ -2474,6 +2478,23 @@ ATTR_NO_OPT static bool cleanup_valence_3_4(PBVH *pbvh,
printf("error!\n");
BLI_table_gset_remove(pbvh->nodes[ni].bm_other_verts, v, NULL);
}
+ else if (ni < 0) {
+ printf("error!\n");
+
+ // attempt to recover
+
+ BMFace *f;
+ BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
+ int ni2 = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
+
+ if (ni2 != DYNTOPO_NODE_NONE) {
+ PBVHNode *node2 = pbvh->nodes + ni2;
+
+ BLI_table_gset_remove(node2->bm_unique_verts, v, NULL);
+ BLI_table_gset_remove(node2->bm_other_verts, v, NULL);
+ }
+ }
+ }
BM_log_vert_removed(pbvh->bm_log, v, pbvh->cd_vert_mask_offset);
pbvh_bmesh_vert_remove(pbvh, v);
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c
b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 9b733f007d0..7bad50e55c6 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -64,6 +64,10 @@ Topology rake:
#include "bmesh.h"
#include "pbvh_intern.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
void pbvh_bmesh_check_nodes(PBVH *pbvh)
{
#if 0
@@ -1128,6 +1132,56 @@ static void pbvh_bmesh_create_nodes_fast_recursive(
/***************************** Public API *****************************/
+void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset,
BMVert *v)
+{
+ MDynTopoVert *mv = BKE_PBVH_DYNVERT(cd_dyn_vert, v);
+
+ BMEdge *e = v->e;
+ mv->flag &= ~(DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY |
DYNVERT_NEED_BOUNDARY);
+
+ if (!e) {
+ mv->flag |= DYNVERT_BOUNDARY;
+ return;
+ }
+
+ int lastfset = 0;
+ bool first = true;
+
+ do {
+ if (e->l) {
+ int fset = abs(BM_ELEM_CD_GET_INT(e->l->f, cd_faceset_offset));
+
+ if (!first && fset != lastfset) {
+ mv->flag |= DYNVERT_FSET_BOUNDARY;
+ }
+
+ lastfset = fset;
+ first = false;
+
+ // also check e->l->radial_next, in case we are not manifold
+ // which can mess up the loop order
+ if (e->l->radial_next != e->l) {
+ fset = abs(BM_ELEM_CD_GET_INT(e->l->radial_next->f,
cd_faceset_offset));
+
+ if (fset != lastfset) {
+ mv->flag |= DYNVERT_FSET_BOUNDARY;
+ }
+ }
+ }
+
+ if (!e->l || e->l->radial_next == e->l) {
+ mv->flag |= DYNVERT_BOUNDARY;
+ }
+
+ e = e->v1 == v ? e->v1_disk_link.next : e->v2_disk_link.next;
+ } while (e != v->e);
+}
+
+void BKE_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset,
BMVert *v)
+{
+ bke_pbvh_update_vert_boundary(cd_dyn_vert, cd_faceset_offset, v);
+}
+
/*Used by symmetrize to update boundary flags*/
void BKE_pbvh_recalc_bmesh_boundary(PBVH *pbvh)
{
@@ -1135,14 +1189,7 @@ void BKE_pbvh_recalc_bmesh_boundary(PBVH *pbvh)
BMIter iter;
BM_ITER_MESH (v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
- MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
-
- if (BM_vert_is_boundary(v)) {
- mv->flag |= DYNVERT_BOUNDARY;
- }
- else {
- mv->flag &= ~DYNVERT_BOUNDARY;
- }
+ bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset,
v);
}
}
@@ -1184,9 +1231,7 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
mv->flag = 0;
- if (BM_vert_is_boundary(v)) {
- mv->flag |= DYNVERT_BOUNDARY;
- }
+ bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset,
v);
copy_v3_v3(mv->origco, v->co);
copy_v3_v3(mv->origno, v->no);
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h
b/source/blender/blenkernel/intern/pbvh_intern.h
index 853152c97cf..bce00b79c8c 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -16,10 +16,13 @@
#pragma once
+#include "BLI_compiler_compat.h"
#include "BLI_ghash.h"
#include "DNA_customdata_types.h"
#include "DNA_material_types.h"
+#include "bmesh.h"
+
/** \file
* \ingroup bli
*/
@@ -305,3 +308,16 @@ bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int
node_index);
void pbvh_bmesh_check_nodes(PBVH *pbvh);
void bke_pbvh_insert_face_finalize(PBVH *pbvh, BMFace *f, const int ni);
void bke_pbvh_insert_face(PBVH *pbvh, struct BMFace *f);
+void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset,
BMVert *v);
+
+BLI_INLINE bool pbvh_check_vert_boundary(PBVH *pbvh, struct BMVert *v)
+{
+ MDynTopoVert *mv = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_dyn_vert);
+
+ if (mv->flag & DYNVERT_NEED_BOUNDARY) {
+ bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset,
v);
+ return true;
+ }
+
+ return false;
+}
diff --git a/source/blender/editors/interface/interface.c
b/source/blender/editors/interface/interface.c
index ddde4f5a9dc..9aeb8dc62ad 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -86,8 +86,27 @@
#include "DEG_depsgraph_query.h"
+#include "BLI_asan.h"
#include "interface_intern.h"
+void poison_ui_but(struct uiBut *but)
+{
+ BLI_asan_poison(but->poison1, sizeof(but->poison1));
+ BLI_asan_poison(but->poison2, sizeof(but->poison2));
+ BLI_asan_poison(but->poison3, sizeof(but->poison3));
+ BLI_asan_poison(but->poison4, sizeof(but->poison4));
+ BLI_asan_poison(but->poison5, sizeof(but->poison5));
+}
+
+void unpo
@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs