[Bf-blender-cvs] [bde54e127ea] temp_bmesh_multires: Sculpt dyntopo: Smooth improvements and bug fixes
Joseph Eagar
noreply at git.blender.org
Tue Aug 24 07:55:29 CEST 2021
Commit: bde54e127eace4bc865044673beb21e9034bad60
Author: Joseph Eagar
Date: Mon Aug 23 21:06:10 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rBbde54e127eace4bc865044673beb21e9034bad60
Sculpt dyntopo: Smooth improvements and bug fixes
* Added an option to weight smooth by face areas
* Dyntopo now caches face areas in a CD_PROP_FLOAT layer
* Dyntopo also caches number of edges around verts inside of
MDynTopoVert. To avoid increasing the struct size flag was
made a short.
* Cleanup mode (dissolves 3/4-valence verts) now piggybacks on
subdivide code to build list of verts; this is much faster.
===================================================================
M release/scripts/startup/bl_ui/properties_paint_common.py
M source/blender/blenkernel/BKE_paint.h
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/intern/dyntopo.c
M source/blender/blenkernel/intern/paint.c
M source/blender/blenkernel/intern/pbvh.c
M source/blender/blenkernel/intern/pbvh_bmesh.c
M source/blender/blenkernel/intern/pbvh_intern.h
M source/blender/editors/sculpt_paint/paint_mask.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_smooth.c
M source/blender/editors/sculpt_paint/sculpt_undo.c
M source/blender/makesdna/DNA_brush_enums.h
M source/blender/makesdna/DNA_meshdata_types.h
M source/blender/makesrna/intern/rna_brush.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 1b71dae5e35..1043e8af1dc 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -567,6 +567,8 @@ def brush_settings(layout, context, brush, popover=False):
slider=True,
)
+ box.prop(brush, "use_weighted_smooth")
+
box.prop(brush, "use_custom_auto_smooth_spacing", text="Custom Spacing")
if brush.use_custom_auto_smooth_spacing:
UnifiedPaintPanel.prop_unified(
@@ -812,7 +814,9 @@ def brush_settings(layout, context, brush, popover=False):
elif sculpt_tool == 'SMOOTH':
col = layout.column()
+ col.prop(brush, "use_weighted_smooth")
col.prop(brush, "smooth_deform_type")
+
if brush.smooth_deform_type == 'SURFACE':
col.prop(brush, "surface_smooth_shape_preservation")
col.prop(brush, "surface_smooth_current_vertex")
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index db091a8b878..2b829e8f569 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -533,6 +533,7 @@ typedef struct SculptSession {
int cd_face_node_offset;
int cd_vcol_offset;
int cd_faceset_offset;
+ int cd_face_areas;
bool bm_smooth_shading;
/* Undo/redo log for dynamic topology sculpting */
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 05837f8f847..0b2e288cfb5 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -209,7 +209,11 @@ typedef enum {
PBVH_Delete = 1 << 15,
PBVH_UpdateCurvatureDir = 1 << 16,
PBVH_UpdateTris = 1 << 17,
- PBVH_RebuildNodeVerts = 1 << 18
+ PBVH_RebuildNodeVerts = 1 << 18,
+
+ /* tri areas are not guaranteed to be up to date, tools should
+ update all nodes on first step of brush*/
+ PBVH_UpdateTriAreas = 1 << 19
} PBVHNodeFlags;
typedef struct PBVHFrustumPlanes {
@@ -263,11 +267,13 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
const int cd_vert_node_offset,
const int cd_face_node_offset,
const int cd_dyn_vert,
+ const int cd_face_areas,
bool fast_draw);
void BKE_pbvh_update_offsets(PBVH *pbvh,
const int cd_vert_node_offset,
const int cd_face_node_offset,
- const int cd_dyn_vert);
+ const int cd_dyn_vert,
+ const int cd_face_areas);
void BKE_pbvh_free(PBVH *pbvh);
/** update original data, only data whose r_** parameters are passed in will be updated*/
@@ -436,6 +442,18 @@ bool BKE_pbvh_bmesh_update_topology_nodes(PBVH *pbvh,
void *mask_cb_data);
/* Node Access */
+void BKE_pbvh_check_tri_areas(PBVH *pbvh, PBVHNode *node);
+
+// updates boundaries and valences for whole mesh
+void BKE_pbvh_bmesh_on_mesh_change(PBVH *pbvh);
+bool BKE_pbvh_bmesh_check_valence(PBVH *pbvh, SculptVertRef vertex);
+void BKE_pbvh_bmesh_update_valence(int cd_dyn_vert, SculptVertRef vertex);
+void BKE_pbvh_bmesh_update_all_valence(PBVH *pbvh);
+void BKE_pbvh_bmesh_flag_all_disk_sort(PBVH *pbvh);
+bool BKE_pbvh_bmesh_mark_update_valence(PBVH *pbvh, SculptVertRef vertex);
+
+void BKE_pbvh_node_mark_update_tri_area(PBVHNode *node);
+void BKE_pbvh_update_all_tri_areas(PBVH *pbvh);
void BKE_pbvh_node_mark_update(PBVHNode *node);
void BKE_pbvh_node_mark_update_mask(PBVHNode *node);
void BKE_pbvh_node_mark_update_color(PBVHNode *node);
@@ -751,6 +769,8 @@ void BKE_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, struc
PBVHNode *BKE_pbvh_get_node_leaf_safe(PBVH *pbvh, int i);
+void BKE_pbvh_get_vert_face_areas(PBVH *pbvh, SculptVertRef vertex, float *r_areas, int valence);
+
#if 0
typedef enum {
SCULPT_TEXTURE_UV = 1 << 0, // per-uv
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index da3e42e629d..023cb324346 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -32,6 +32,8 @@
#include <stdio.h>
+#define DYNVERT_VALENCE_TEMP (1 << 14)
+
//#define USE_NEW_SPLIT
#define DYNVERT_ALL_BOUNDARY (DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY)
@@ -162,6 +164,7 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
if (!e) {
return;
}
+
pbvh_check_vert_boundary(pbvh, v);
const int cd_dyn_vert = pbvh->cd_dyn_vert;
@@ -172,7 +175,8 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
do {
BMVert *v2 = e->v1 == v ? e->v2 : e->v1;
- pbvh_check_vert_boundary(pbvh, v2);
+ // can't check for boundary here, thread
+ // pbvh_check_vert_boundary(pbvh, v2);
MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(cd_dyn_vert, v2);
const bool bound2 = mv2->flag & DYNVERT_ALL_BOUNDARY;
@@ -846,8 +850,40 @@ typedef struct {
float max_elen;
float min_elen;
float totedge;
+ BMVert **val34_verts;
+ int val34_verts_tot;
+ int val34_verts_size;
} EdgeQueueContext;
+static void edge_queue_insert_val34_vert(EdgeQueueContext *eq_ctx, BMVert *v)
+{
+ MDynTopoVert *mv = BKE_PBVH_DYNVERT(eq_ctx->cd_dyn_vert, v);
+ // prevent double adding
+
+ if (mv->flag & DYNVERT_VALENCE_TEMP) {
+ return;
+ }
+
+ mv->flag |= DYNVERT_VALENCE_TEMP;
+
+ eq_ctx->val34_verts_tot++;
+
+ if (eq_ctx->val34_verts_tot > eq_ctx->val34_verts_size) {
+ int size2 = 4 + eq_ctx->val34_verts_tot + (eq_ctx->val34_verts_tot >> 1);
+
+ if (eq_ctx->val34_verts) {
+ eq_ctx->val34_verts = MEM_reallocN(eq_ctx->val34_verts, sizeof(void *) * size2);
+ }
+ else {
+ eq_ctx->val34_verts = MEM_mallocN(sizeof(void *) * size2, "val34_verts");
+ }
+
+ eq_ctx->val34_verts_size = size2;
+ }
+
+ eq_ctx->val34_verts[eq_ctx->val34_verts_tot - 1] = v;
+}
+
BLI_INLINE float maskcb_get(EdgeQueueContext *eq_ctx, BMEdge *e)
{
if (eq_ctx->mask_cb) {
@@ -1019,6 +1055,8 @@ typedef struct EdgeQueueThreadData {
PBVH *pbvh;
PBVHNode *node;
BMEdge **edges;
+ BMVert **val34_verts;
+ int val34_verts_tot;
EdgeQueueContext *eq_ctx;
int totedge;
int size;
@@ -1346,6 +1384,8 @@ static void long_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
}
}
+static int _long_edge_queue_task_cb_seed = 0;
+
static void long_edge_queue_task_cb(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
@@ -1353,6 +1393,9 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
EdgeQueueThreadData *tdata = ((EdgeQueueThreadData *)userdata) + n;
PBVHNode *node = tdata->node;
EdgeQueueContext *eq_ctx = tdata->eq_ctx;
+ RNG *rng = BLI_rng_new(_long_edge_queue_task_cb_seed++); // I don't care if seed becomes mangled
+ BMVert **val34 = NULL;
+ BLI_array_declare(val34);
BMFace *f;
const int cd_dyn_vert = tdata->pbvh->cd_dyn_vert;
@@ -1381,9 +1424,23 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
BMLoop *l_iter = l_first;
do {
+ MDynTopoVert *mv = BKE_PBVH_DYNVERT(eq_ctx->cd_dyn_vert, l_iter->v);
+
+ /*
+ If valence is not up to date, just add it to the list;
+ long_edge_queue_create will check and de-duplicate this for us.
+
+ Can't update valence in a thread after all.
+ */
+ if (mv->valence < 5 || (mv->flag & DYNVERT_NEED_VALENCE)) {
+ BLI_array_append(val34, l_iter->v);
+ }
+
// try to improve convergence by applying a small amount of smoothing to topology,
// but tangentially to surface.
- surface_smooth_v_safe(tdata->pbvh, l_iter->v);
+ if (BLI_rng_get_float(rng) > 0.75) {
+ surface_smooth_v_safe(tdata->pbvh, l_iter->v);
+ }
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
float w = maskcb_get(eq_ctx, l_iter->e);
@@ -1405,6 +1462,11 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
}
}
TGSET_ITER_END
+
+ BLI_rng_free(rng);
+
+ tdata->val34_verts = val34;
+ tdata->val34_verts_tot = BLI_array_len(val34);
}
static void short_edge_queue_task_cb(void *__restrict userdata,
@@ -1573,17 +1635,25 @@ static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v)
{
- BMFace **fs = NULL;
- BLI_array_staticdeclare(fs, 32);
-
MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
+
if (!(mv->flag & DYNVERT_NEED_TRIANGULATE)) {
return true;
}
+ BMFace **fs = NULL;
+ BLI_array_staticdeclare(fs, 32);
+
BMIter iter;
BMFace *f;
BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
+ BMLoop *l = f->l_first;
+
+ do {
+ MDynTopoVert *mv_l = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, l->v);
+
+ mv_l->flag |= DYNVERT_NEED_BOUNDARY | DYNVERT_NEED_VALENCE | DYNVERT_NEED_DISK_SORT;
+ } while ((l = l->next) != f->l_first);
BLI_array_append(fs, f);
}
@@ -1598,6 +1668,34 @@ static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v)
return false;
}
+static void edge_queue_init(EdgeQueueContext *eq_ctx,
+ bool use_projected,
+ bool use_frontface,
+ const float center[3],
+ const float view_normal[3],
+ const float radius)
+{
+ if (use_projected) {
+ eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_circle;
+ eq_ctx->q->edge_queue_vert_in_range = edge_queue_vert_in_circle;
+ project_plane_normalized_v3_v3v3(eq_ctx->q->center_proj, center, view_normal);
+ }
+ else {
+ eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_sphere;
+ eq_ctx->q->edge_queue_vert_in_range = edge_queue_vert_in_sphere;
+ }
+
+ eq_ctx->q->center = center;
+ eq_ctx-
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list