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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs