[Bf-blender-cvs] [8bfbbc467a3] temp_bmesh_multires: Sculpt dyntopo
Joseph Eagar
noreply at git.blender.org
Wed Sep 1 20:49:13 CEST 2021
Commit: 8bfbbc467a3b6cb958c21ef68ae408705748ee3b
Author: Joseph Eagar
Date: Wed Sep 1 11:47:03 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB8bfbbc467a3b6cb958c21ef68ae408705748ee3b
Sculpt dyntopo
* Wrote a simple fix for drawing face sets
in inverse (ctrl) mode with face set automasking
on.
* Various fixes related to hard edges and smoothing.
* Started writing some code to defragment bmesh mempools.
Need to figure out how to avoid triggering excessive
PBVH node rebuilds.
===================================================================
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/intern/brush.c
M source/blender/blenkernel/intern/dyntopo.c
M source/blender/blenkernel/intern/paint.c
M source/blender/blenkernel/intern/pbvh_bmesh.c
M source/blender/blenlib/BLI_mempool.h
M source/blender/blenlib/intern/BLI_mempool.c
M source/blender/bmesh/intern/bmesh_log.c
M source/blender/bmesh/intern/bmesh_mesh.c
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M source/blender/editors/sculpt_paint/sculpt_face_set.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
M source/blender/editors/sculpt_paint/sculpt_smooth.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 76adab9168b..afed28d8120 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -33,6 +33,9 @@
extern "C" {
#endif
+// experimental feature to detect quad diagonals and mark (but not dissolve) them
+//#define SCULPT_DIAGONAL_EDGE_MARKS
+
typedef struct SculptVertRef {
intptr_t i;
} SculptVertRef;
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index b0870e0558e..956b69d608f 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1789,6 +1789,8 @@ void BKE_brush_sculpt_reset(Brush *br)
break;
case SCULPT_TOOL_SMOOTH:
br->flag &= ~BRUSH_SPACE_ATTEN;
+ br->flag2 |= BRUSH_SMOOTH_PRESERVE_FACE_SETS | BRUSH_SMOOTH_USE_AREA_WEIGHT;
+
br->spacing = 5;
br->alpha = 0.7f;
br->surface_smooth_shape_preservation = 0.5f;
@@ -1801,9 +1803,10 @@ void BKE_brush_sculpt_reset(Brush *br)
br->alpha = 1.0f;
br->rake_factor = 1.0f;
br->dyntopo.inherit = DYNTOPO_INHERIT_BITMASK &
- ~(DYNTOPO_INHERIT_ALL | DYNTOPO_LOCAL_COLLAPSE | DYNTOPO_INHERIT_DETAIL_RANGE);
+ ~(DYNTOPO_INHERIT_ALL | DYNTOPO_LOCAL_COLLAPSE |
+ DYNTOPO_INHERIT_DETAIL_RANGE);
br->dyntopo.flag |= DYNTOPO_LOCAL_COLLAPSE;
- br->dyntopo.detail_range = 0.5f;
+ br->dyntopo.detail_range = 0.4f;
break;
case SCULPT_TOOL_THUMB:
br->size = 75;
@@ -1980,13 +1983,14 @@ void BKE_brush_sculpt_reset(Brush *br)
// don't use DYNTOPO_INHERIT_BITMASK, we want to include
// future bits
- br->flag |= BRUSH_SMOOTH_PRESERVE_FACE_SETS | BRUSH_SMOOTH_USE_AREA_WEIGHT |
- BRUSH_CURVATURE_RAKE;
+ br->flag2 |= BRUSH_SMOOTH_PRESERVE_FACE_SETS | BRUSH_SMOOTH_USE_AREA_WEIGHT |
+ BRUSH_CURVATURE_RAKE;
br->dyntopo.inherit = 0x7FFFFFFF &
~(DYNTOPO_INHERIT_ALL | DYNTOPO_SUBDIVIDE | DYNTOPO_COLLAPSE);
br->dyntopo.flag |= DYNTOPO_COLLAPSE | DYNTOPO_SUBDIVIDE;
br->autosmooth_factor = 0.05;
br->topology_rake_factor = 0.35;
+ br->topology_rake_projection = 0.975;
break;
case SCULPT_TOOL_VCOL_BOUNDARY:
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 766a1b95b21..d2324788561 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -61,16 +61,18 @@
* (avoids performing subdivisions too far away). */
#define EVEN_GENERATION_SCALE 1.1f
-// recursion depth to start applying front face test
+/* recursion depth to start applying front face test */
#define DEPTH_START_LIMIT 5
-//#define FANCY_EDGE_WEIGHTS
-#define SKINNY_EDGE_FIX
+//#define FANCY_EDGE_WEIGHTS <= too slow
+//#define SKINNY_EDGE_FIX
-// slightly relax geometry by this factor along surface tangents
-// to improve convergence of remesher
+/* slightly relax geometry by this factor along surface tangents
+ to improve convergence of remesher */
#define DYNTOPO_SAFE_SMOOTH_FAC 0.05f
+#define DYNTOPO_SAFE_SMOOTH_SUBD_ONLY_FAC 0.75f
+
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
# include "BKE_global.h"
#endif
@@ -157,8 +159,12 @@ struct EdgeQueueContext;
static bool check_face_is_tri(PBVH *pbvh, BMFace *f);
static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v);
-static void pbvh_split_edges(
- PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge, bool ignore_isolated_edges);
+static void pbvh_split_edges(struct EdgeQueueContext *eq_ctx,
+ PBVH *pbvh,
+ BMesh *bm,
+ BMEdge **edges,
+ int totedge,
+ bool ignore_isolated_edges);
void bm_log_message(const char *fmt, ...);
void pbvh_bmesh_check_nodes_simple(PBVH *pbvh);
static void edge_queue_create_local(struct EdgeQueueContext *eq_ctx,
@@ -458,7 +464,7 @@ static BMEdge *bmesh_edge_create_log(PBVH *pbvh, BMVert *v1, BMVert *v2, BMEdge
return e;
}
-BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
+BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
{
float co[3];
float tan[3];
@@ -516,9 +522,9 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
float x = v->co[0], y = v->co[1], z = v->co[2];
// conflicts here should be pretty rare.
- atomic_cas_float(&v->co[0], x, x + co[0] * DYNTOPO_SAFE_SMOOTH_FAC);
- atomic_cas_float(&v->co[1], y, y + co[1] * DYNTOPO_SAFE_SMOOTH_FAC);
- atomic_cas_float(&v->co[2], z, z + co[2] * DYNTOPO_SAFE_SMOOTH_FAC);
+ atomic_cas_float(&v->co[0], x, x + co[0] * fac);
+ atomic_cas_float(&v->co[1], y, y + co[1] * fac);
+ atomic_cas_float(&v->co[2], z, z + co[2] * fac);
}
static void pbvh_kill_vert(PBVH *pbvh, BMVert *v)
@@ -1229,6 +1235,7 @@ typedef struct EdgeQueueContext {
int val34_verts_tot;
int val34_verts_size;
bool local_mode;
+ float surface_smooth_fac;
} EdgeQueueContext;
static void edge_queue_insert_val34_vert(EdgeQueueContext *eq_ctx, BMVert *v)
@@ -1279,9 +1286,15 @@ BLI_INLINE float calc_weighted_edge_split(EdgeQueueContext *eq_ctx, BMVert *v1,
{
#ifdef FANCY_EDGE_WEIGHTS
float l = len_squared_v3v3(v1->co, v2->co);
- float val = (float)BM_vert_edge_count(v1) + (float)BM_vert_edge_count(v2);
- val = MAX2(val * 0.5 - 6.0f, 1.0f);
- val = powf(val, 0.5);
+ // float val = (float)BM_vert_edge_count(v1) + (float)BM_vert_edge_count(v2);
+ MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(eq_ctx->cd_dyn_vert, v1);
+ MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(eq_ctx->cd_dyn_vert, v2);
+ float val = (float)(mv1->valence + mv2->valence) * 0.5f;
+
+ val -= 6.0f;
+ val = MAX2(val, 1.0f);
+
+ // val = powf(val, 0.5);
l *= val;
return l;
@@ -1301,14 +1314,16 @@ BLI_INLINE float calc_weighted_edge_collapse(EdgeQueueContext *eq_ctx, BMVert *v
{
#ifdef FANCY_EDGE_WEIGHTS
float l = len_squared_v3v3(v1->co, v2->co);
- float val = (float)BM_vert_edge_count(v1) + (float)BM_vert_edge_count(v2);
- val = MAX2(val * 0.5 - 6.0f, 1.0f);
- val = powf(val, 0.5);
- l /= val;
+ // float val = (float)BM_vert_edge_count(v1) + (float)BM_vert_edge_count(v2);
+ MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(eq_ctx->cd_dyn_vert, v1);
+ MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(eq_ctx->cd_dyn_vert, v2);
+ float val = (float)(mv1->valence + mv2->valence) * 0.5f;
+
+ val -= 6.0f;
+ val = MAX2(val, 1.0f);
- // if (BM_vert_edge_count(v1) == 4 || BM_vert_edge_count(v2) == 4) {
- // l *= 0.25f;
- //}
+ // val = powf(val, 0.5);
+ l *= val;
return l;
#else
@@ -1548,11 +1563,6 @@ static void long_edge_queue_edge_add_recursive(EdgeQueueContext *eq_ctx,
edge_queue_insert(eq_ctx, l_edge->e, -len_sq, eq_ctx->q->limit_len);
}
- /* temp support previous behavior! */
- if (UNLIKELY(G.debug_value == 1234)) {
- return;
- }
-
if ((l_edge->radial_next != l_edge)) {
const float len_sq_cmp = len_sq * EVEN_EDGELEN_THRESHOLD;
@@ -1678,11 +1688,6 @@ static void short_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
edge_thread_data_insert(tdata, l_edge->e);
- /* temp support previous behavior! */
- if (UNLIKELY(G.debug_value == 1234)) {
- return;
- }
-
if ((l_edge->radial_next != l_edge)) {
const float len_sq_cmp = len_sq * EVEN_EDGELEN_THRESHOLD;
@@ -1716,7 +1721,8 @@ static void long_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
BMLoop *l_end,
const float len_sq,
float limit_len,
- int depth)
+ int depth,
+ bool insert)
{
BLI_assert(len_sq > square_f(limit_len));
@@ -1732,11 +1738,8 @@ static void long_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
}
#endif
- edge_thread_data_insert(tdata, l_edge->e);
-
- /* temp support previous behavior! */
- if (UNLIKELY(G.debug_value == 1234)) {
- return;
+ if (insert) {
+ edge_thread_data_insert(tdata, l_edge->e);
}
if ((l_edge->radial_next != l_edge)) {
@@ -1758,14 +1761,24 @@ static void long_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
len_sq_other *= w * w;
- if (len_sq_other > max_ff(len_sq_cmp, limit_len_sq)) {
- long_edge_queue_edge_add_recursive_2(tdata,
- l_adjacent[i]->radial_next,
- l_adjacent[i],
- len_sq_other,
- limit_len,
- depth + 1);
+ bool insert_ok = len_sq_other > max_ff(len_sq_cmp, limit_len_sq);
+#ifdef EVEN_NO_TEST_DEPTH_LIMIT
+ if (!insert_ok && depth >= EVEN_NO_TEST_DEPTH_LIMIT) {
+ continue;
+ }
+#else
+ if (!insert_ok) {
+ continue;
}
+#endif
+
+ long_edge_queue_edge_add_recursive_2(tdata,
+ l_adjacent[i]->radial_next,
+ l_adjacent[i],
+ len_sq_other,
+ limit_len,
+ depth + 1,
+ insert_ok);
}
} while ((l_iter = l_iter->radial_next) != l_end);
}
@@ -1825,8 +1838,8 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
// try to improve convergence by applying a small amount of smoothing to topology,
// but tangentially to surface.
- if (BLI_rng_get_float(rng) > 0.75) {
- surface_smooth_v_safe(tdata->pbvh, l_iter->v);
+ if (BLI_rng_get_float(rng) > 0.5) {
+ surface_smooth_v_safe(tdata->pbvh, l_iter->v, eq_ctx->surface_sm
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list