[Bf-blender-cvs] [a67ff7552cb] sculpt-dev: Tune up a few hot loops revealed by profiling.
Joseph Eagar
noreply at git.blender.org
Wed Sep 22 11:48:12 CEST 2021
Commit: a67ff7552cb313f3836712d6985ca049ec01d5e7
Author: Joseph Eagar
Date: Tue Sep 21 02:39:33 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rBa67ff7552cb313f3836712d6985ca049ec01d5e7
Tune up a few hot loops revealed by profiling.
===================================================================
M release/scripts/startup/bl_ui/properties_paint_common.py
M source/blender/blenkernel/intern/dyntopo.c
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_automasking.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 8025b17cbed..51356824491 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -125,8 +125,9 @@ class UnifiedPaintPanel:
row = layout.row(align=True)
- typeprop = "float_value"
+ if ch.type == "FLOAT":
+ typeprop = "float_value" if "spacing" in ch.idname else "factor_value"
if ch.type == "INT":
typeprop = "int_value"
elif ch.type == "BOOL":
@@ -139,7 +140,7 @@ class UnifiedPaintPanel:
typeprop = "color3_value"
elif ch.type == "VEC4":
typeprop = "color4_value"
-
+
if text is None:
s = prop_name.lower().replace("_", " ").split(" ");
text = ''
@@ -191,14 +192,14 @@ class UnifiedPaintPanel:
#if unified_name and not header:
# # NOTE: We don't draw UnifiedPaintSettings in the header to reduce clutter. D5928#136281
# row.prop(ups, unified_name, text="", icon='BRUSHES_ALL')
- if not header and ch.type != "BOOL":
+ if not header: # and ch.type != "BOOL":
if ch.type == "BITMASK" and not toolsettings_only and ch == finalch:
row.prop(ch, "inherit_if_unset", text="Combine With Defaults")
if not toolsettings_only:
row.prop(ch, "inherit", text="", icon='BRUSHES_ALL')
- if ch.type == "BITMASK":
+ if ch.type == "BITMASK" or ch.type == "BOOL":
return
row.prop(ch, "ui_expanded", text="", icon="TRIA_DOWN" if ch.ui_expanded else "TRIA_RIGHT")
@@ -806,7 +807,16 @@ def brush_settings(layout, context, brush, popover=False):
box.prop(brush, "ignore_falloff_for_topology_rake")
if context.sculpt_object.use_dynamic_topology_sculpting:
- layout.prop(brush.dyntopo, "disabled", text="Disable Dyntopo")
+ UnifiedPaintPanel.channel_unified(
+ layout,
+ context,
+ brush,
+ "dyntopo_disabled",
+ #text="Weight By Face Area",
+ slider=True,
+ header=True
+ )
+ #layout.prop(brush.dyntopo, "disabled", text="Disable Dyntopo")
# normal_weight
if capabilities.has_normal_weight:
@@ -1018,7 +1028,16 @@ def brush_settings(layout, context, brush, popover=False):
col = layout.column()
col.prop(brush, "boundary_smooth_factor")
- col.prop(brush, "use_weighted_smooth")
+ UnifiedPaintPanel.channel_unified(
+ layout,
+ context,
+ brush,
+ "use_weighted_smooth",
+ #text="Weight By Face Area",
+ slider=True,
+ )
+
+ #col.prop(brush, "use_weighted_smooth")
col.prop(brush, "preserve_faceset_boundary")
if brush.preserve_faceset_boundary:
col.prop(brush, "autosmooth_fset_slide")
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 51757540ba3..af07f0ace81 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -1628,6 +1628,7 @@ typedef struct EdgeQueueThreadData {
int totedge;
int size;
bool is_collapse;
+ int seed;
} EdgeQueueThreadData;
static void edge_thread_data_insert(EdgeQueueThreadData *tdata, BMEdge *e)
@@ -1962,6 +1963,16 @@ static void long_edge_queue_edge_add_recursive_2(EdgeQueueThreadData *tdata,
static int _long_edge_queue_task_cb_seed = 0;
+BLI_INLINE int dyntopo_thread_rand(int seed)
+{
+ // glibc
+ const uint32_t multiplier = 1103515245;
+ const uint32_t addend = 12345;
+ const uint32_t mask = (1 << 31) - 1;
+
+ return (seed * multiplier + addend) & mask;
+}
+
static void long_edge_queue_task_cb(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
@@ -1973,18 +1984,43 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
BMVert **val34 = NULL;
BLI_array_declare(val34);
- BMFace *f;
+ int seed = tdata->seed + n;
+
+ BMFace *f, **faces = NULL;
+ BLI_array_declare(faces);
const int cd_dyn_vert = tdata->pbvh->cd_dyn_vert;
+#if 1
+# if 0
+ // try to be nice to branch predictor
+ int off = (seed = dyntopo_thread_rand(seed));
+ int stepi = off & 65535;
+# endif
+ /*
+ we care more about convergence to accurate results
+ then accuracy in any individual runs. profiling
+ has shown this loop overwhelms the L3 cache,
+ so randomly skip bits of it.
+ */
TGSET_ITER (f, node->bm_faces) {
BMLoop *l = f->l_first;
+# if 0
+ if ((stepi++) & 3) {
+ continue;
+ }
+# else
+ if ((seed = dyntopo_thread_rand(seed)) & 3) {
+ continue;
+ }
+# endif
do {
l->e->head.hflag &= ~BM_ELEM_TAG;
l = l->next;
} while (l != f->l_first);
}
TGSET_ITER_END
+#endif
TGSET_ITER (f, node->bm_faces) {
#ifdef USE_EDGEQUEUE_FRONTFACE
@@ -2014,7 +2050,9 @@ 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.5) {
+ int randval = (seed = dyntopo_thread_rand(seed)) & 255;
+
+ if (randval > 127) {
surface_smooth_v_safe(tdata->pbvh, l_iter->v, eq_ctx->surface_smooth_fac);
}
@@ -2040,6 +2078,7 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
TGSET_ITER_END
BLI_rng_free(rng);
+ BLI_array_free(faces);
tdata->val34_verts = val34;
tdata->val34_verts_tot = BLI_array_len(val34);
@@ -2055,15 +2094,23 @@ static void short_edge_queue_task_cb(void *__restrict userdata,
BMFace *f;
+ int seed = tdata->seed + n;
+
+ // see comment in similar loop in long_edge_queue_task_cb
TGSET_ITER (f, node->bm_faces) {
+#if 0
+ if ((stepi++) & 3) {
+ continue;
+ }
+#else
+ if ((seed = dyntopo_thread_rand(seed)) & 3) {
+ continue;
+ }
+#endif
+
BMLoop *l = f->l_first;
do {
- if (!l->e) {
- printf("bmesh error! %s\n", __func__);
- continue;
- }
-
l->e->head.hflag &= ~BM_ELEM_TAG;
l = l->next;
} while (l != f->l_first);
@@ -2562,30 +2609,41 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
EdgeQueueThreadData *tdata = NULL;
BLI_array_declare(tdata);
+ int totleaf = 0;
+
for (int n = 0; n < pbvh->totnode; n++) {
PBVHNode *node = &pbvh->nodes[n];
+ if (node->flag & PBVH_Leaf) {
+ totleaf++;
+ }
+
/* Check leaf nodes marked for topology update */
- if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) &&
- !(node->flag & PBVH_FullyHidden)) {
- EdgeQueueThreadData td;
+ bool ok = ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) &&
+ !(node->flag & PBVH_FullyHidden));
- memset(&td, 0, sizeof(td));
+ if (!ok) {
+ continue;
+ }
- td.pbvh = pbvh;
- td.node = node;
- td.eq_ctx = eq_ctx;
+ EdgeQueueThreadData td;
- BLI_array_append(tdata, td);
- /* Check each face */
- /*
- BMFace *f;
- TGSET_ITER (f, node->bm_faces) {
- long_edge_queue_face_add(eq_ctx, f);
- }
- TGSET_ITER_END
- */
+ memset(&td, 0, sizeof(td));
+
+ td.seed = BLI_thread_rand(0);
+ td.pbvh = pbvh;
+ td.node = node;
+ td.eq_ctx = eq_ctx;
+
+ BLI_array_append(tdata, td);
+ /* Check each face */
+ /*
+ BMFace *f;
+ TGSET_ITER (f, node->bm_faces) {
+ long_edge_queue_face_add(eq_ctx, f);
}
+ TGSET_ITER_END
+ */
}
int count = BLI_array_len(tdata);
@@ -2953,9 +3011,11 @@ static void short_edge_queue_create(EdgeQueueContext *eq_ctx,
if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) &&
!(node->flag & PBVH_FullyHidden)) {
memset(&td, 0, sizeof(td));
+
td.pbvh = pbvh;
td.node = node;
td.eq_ctx = eq_ctx;
+ td.seed = BLI_thread_rand(0);
BLI_array_append(tdata, td);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 5feca19a698..df3afa42257 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1158,22 +1158,35 @@ bool SCULPT_vertex_has_face_set(SculptSession *ss, SculptVertRef index, int face
return false;
}
case PBVH_BMESH: {
- BMIter iter;
- BMLoop *l;
+ BMEdge *e;
BMVert *v = (BMVert *)index.i;
if (ss->cd_faceset_offset == -1) {
return false;
}
- BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- BMFace *f = l->f;
+ e = v->e;
- if (abs(BM_ELEM_CD_GET_INT(f, ss->cd_faceset_offset)) == abs(face_set)) {
- return true;
- }
+ if (UNLIKELY(!e)) {
+ return false;
}
+ do {
+ BMLoop *l = e->l;
+
+ if (UNLIKELY(!l)) {
+ continue;
+ }
+
+ do {
+ BMFace *f = l->f;
+
+ if (abs(BM_ELEM_CD_GET_INT(f, ss->cd_faceset_offset)) == abs(face_set)) {
+ return true;
+ }
+ } while ((l = l->radial_next) != e->l);
+ } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
+
return false;
}
case PBVH_GRIDS: {
@@ -9321,7 +9334,8 @@ ATTR_NO_OPT static void SCULPT_run_command_list(
break;
case SCULPT_TOOL_DYNTOPO:
if (has_dyntopo) {
- do_symmetrical_brush_actions(sd, ob, sculpt_topology_update, ups);
+ sculpt_topology_update(sd, ob, brush, ups);
+ // do_symmetrical_brush_actions(sd, ob, sculpt_topology_update, ups);
}
break;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.c b/source/blender
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list