Tune up a few hot loops revealed by profiling.

This commit is contained in:
2021-09-21 02:39:33 -07:00
parent c8004ff653
commit a67ff7552c
4 changed files with 135 additions and 42 deletions

View File

@@ -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")

View File

@@ -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];
/* Check leaf nodes marked for topology update */
if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) &&
!(node->flag & PBVH_FullyHidden)) {
EdgeQueueThreadData td;
memset(&td, 0, sizeof(td));
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
*/
if (node->flag & PBVH_Leaf) {
totleaf++;
}
/* Check leaf nodes marked for topology update */
bool ok = ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) &&
!(node->flag & PBVH_FullyHidden));
if (!ok) {
continue;
}
EdgeQueueThreadData td;
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);
}

View File

@@ -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;
}

View File

@@ -193,7 +193,7 @@ float SCULPT_automasking_factor_get(AutomaskingCache *automasking,
}
if (automasking->settings.flags & BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS) {
if (!SCULPT_vertex_has_unique_face_set(ss, vert)) {
if (SCULPT_vertex_is_boundary(ss, vert, SCULPT_BOUNDARY_FACE_SET)) {
return 0.0f;
}
}