[Bf-blender-cvs] [118edbef0e6] sculpt-dev: Sculpt-dev: bke_pbvh_update_vert_boundary is now atomic
Joseph Eagar
noreply at git.blender.org
Sat Jan 8 22:01:51 CET 2022
Commit: 118edbef0e644883812f72a2ac9bda07f0e5db72
Author: Joseph Eagar
Date: Sat Jan 8 12:57:29 2022 -0800
Branches: sculpt-dev
https://developer.blender.org/rB118edbef0e644883812f72a2ac9bda07f0e5db72
Sculpt-dev: bke_pbvh_update_vert_boundary is
now atomic
* bke_pbvh_update_vert_boundary now uses atomics
* This allows dyntopo surface smoothing
(surface_smooth_v_safe) to update vertex boundary
flags inside of a thread. This lessens degenerate
geometry created by hard edged brushes like
clay strips.
===================================================================
M source/blender/blenkernel/intern/dyntopo.c
M source/blender/blenkernel/intern/pbvh_bmesh.c
===================================================================
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index f5b695275c0..15b35676bcb 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -34,8 +34,9 @@
#include <stdio.h>
-//#define DYNTOPO_REPORT
+#define DYNTOPO_REPORT
//#define WITH_ADAPTIVE_CURVATURE
+//#define DYNTOPO_NO_THREADING
#define SCULPTVERT_VALENCE_TEMP SCULPTVERT_SPLIT_TEMP
@@ -595,7 +596,7 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
}
if (mv1->flag & SCULPTVERT_NEED_BOUNDARY) {
- return; // can't update boundary in thread
+ pbvh_check_vert_boundary(pbvh, v);
}
// pbvh_check_vert_boundary(pbvh, v);
@@ -2843,8 +2844,12 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
+#ifdef DYNTOPO_NO_THREADING
+ settings.use_threading = false;
+#endif
BLI_task_parallel_range(0, count, tdata, long_edge_queue_task_cb, &settings);
+
const int cd_sculpt_vert = pbvh->cd_sculpt_vert;
for (int i = 0; i < count; i++) {
@@ -2967,6 +2972,10 @@ static void edge_queue_create_local(EdgeQueueContext *eq_ctx,
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
+#ifdef DYNTOPO_NO_THREADING
+ settings.use_threading = false;
+#endif
+
BLI_task_parallel_range(0, count, tdata, short_edge_queue_task_cb_local, &settings);
const int cd_sculpt_vert = pbvh->cd_sculpt_vert;
@@ -3240,6 +3249,10 @@ static void short_edge_queue_create(EdgeQueueContext *eq_ctx,
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
+#ifdef DYNTOPO_NO_THREADING
+ settings.use_threading = false;
+#endif
+
BLI_task_parallel_range(0, count, tdata, short_edge_queue_task_cb, &settings);
const int cd_sculpt_vert = pbvh->cd_sculpt_vert;
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 6f1d4f95491..efb166bc8a3 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -1760,6 +1760,19 @@ static int color_boundary_key(float col[4])
}
#endif
+/* calls atomic_cas_uint32 on two adjacent (and int aligned) shorts */
+BLI_INLINE void atomic_cas_short2(ushort *base, ushort olda, ushort oldb, ushort newa, ushort newb) {
+ uint oldi, newi;
+
+ ((ushort *)&oldi)[0] = olda;
+ ((ushort *)&oldi)[1] = oldb;
+
+ ((ushort *)&newi)[0] = newa;
+ ((ushort *)&newi)[1] = newb;
+
+ atomic_cas_uint32((uint32_t *)base, oldi, newi);
+}
+
void bke_pbvh_update_vert_boundary(int cd_sculpt_vert,
int cd_faceset_offset,
int cd_vert_node_offset,
@@ -1774,16 +1787,25 @@ void bke_pbvh_update_vert_boundary(int cd_sculpt_vert,
float curv = 0.0f, totcurv = 0.0f;
+ int newflag = mv->flag;
+ int oldflag = newflag;
+ int oldval = mv->valence;
+
BMEdge *e = v->e;
- mv->flag &= ~(SCULPTVERT_BOUNDARY | SCULPTVERT_FSET_BOUNDARY | SCULPTVERT_NEED_BOUNDARY |
+ newflag &= ~(SCULPTVERT_BOUNDARY | SCULPTVERT_FSET_BOUNDARY | SCULPTVERT_NEED_BOUNDARY |
SCULPTVERT_NEED_TRIANGULATE | SCULPTVERT_FSET_CORNER | SCULPTVERT_CORNER |
SCULPTVERT_NEED_VALENCE | SCULPTVERT_SEAM_BOUNDARY | SCULPTVERT_SHARP_BOUNDARY |
SCULPTVERT_SEAM_CORNER | SCULPTVERT_SHARP_CORNER | SCULPTVERT_PBVH_BOUNDARY |
SCULPTVERT_UV_BOUNDARY | SCULPTVERT_UV_CORNER);
+ ushort stroke_id = (ushort)mv->stroke_id;
+
if (!e) {
- mv->flag |= SCULPTVERT_BOUNDARY;
- mv->valence = 0;
+ newflag |= SCULPTVERT_BOUNDARY;
+
+ atomic_cas_int32(&mv->flag, oldflag, newflag);
+ atomic_cas_short2(&mv->valence, (ushort)oldval, stroke_id, 0, stroke_id);
+
return;
}
@@ -1838,15 +1860,15 @@ void bke_pbvh_update_vert_boundary(int cd_sculpt_vert,
#endif
if (BM_ELEM_CD_GET_INT(v2, cd_vert_node_offset) != ni) {
- mv->flag |= SCULPTVERT_PBVH_BOUNDARY;
+ newflag |= SCULPTVERT_PBVH_BOUNDARY;
}
if (e->head.hflag & BM_ELEM_SEAM) {
- mv->flag |= SCULPTVERT_SEAM_BOUNDARY;
+ newflag |= SCULPTVERT_SEAM_BOUNDARY;
seamcount++;
if (seamcount > 2) {
- mv->flag |= SCULPTVERT_SEAM_CORNER;
+ newflag |= SCULPTVERT_SEAM_CORNER;
}
}
@@ -1863,17 +1885,17 @@ void bke_pbvh_update_vert_boundary(int cd_sculpt_vert,
int colorkey2 = color_boundary_key(color2);
if (colorkey1 != colorkey2) {
- mv->flag |= SCULPTVERT_FSET_BOUNDARY;
+ newflag |= SCULPTVERT_FSET_BOUNDARY;
}
}
#endif
if (!(e->head.hflag & BM_ELEM_SMOOTH)) {
- mv->flag |= SCULPTVERT_SHARP_BOUNDARY;
+ newflag |= SCULPTVERT_SHARP_BOUNDARY;
sharpcount++;
if (sharpcount > 2) {
- mv->flag |= SCULPTVERT_SHARP_CORNER;
+ newflag |= SCULPTVERT_SHARP_CORNER;
}
}
@@ -1904,11 +1926,11 @@ void bke_pbvh_update_vert_boundary(int cd_sculpt_vert,
len_squared_v2v2(lastuv2[i], luv->uv) > uv_snap_limit;
if (!same) {
- mv->flag |= SCULPTVERT_UV_BOUNDARY;
+ newflag |= SCULPTVERT_UV_BOUNDARY;
}
if (corner) {
- mv->flag |= SCULPTVERT_UV_CORNER;
+ newflag |= SCULPTVERT_UV_CORNER;
}
if (!same) {
@@ -1922,7 +1944,7 @@ void bke_pbvh_update_vert_boundary(int cd_sculpt_vert,
}
if (BM_ELEM_CD_GET_INT(e->l->f, cd_face_node_offset) != ni) {
- mv->flag |= SCULPTVERT_PBVH_BOUNDARY;
+ newflag |= SCULPTVERT_PBVH_BOUNDARY;
}
if (e->l != e->l->radial_next) {
@@ -1935,7 +1957,7 @@ void bke_pbvh_update_vert_boundary(int cd_sculpt_vert,
}
if (BM_ELEM_CD_GET_INT(e->l->radial_next->f, cd_face_node_offset) != ni) {
- mv->flag |= SCULPTVERT_PBVH_BOUNDARY;
+ newflag |= SCULPTVERT_PBVH_BOUNDARY;
}
}
@@ -1943,7 +1965,7 @@ void bke_pbvh_update_vert_boundary(int cd_sculpt_vert,
BM_ELEM_CD_GET_INT(e->l->f, cd_faceset_offset), bound_symmetry, v2->co);
if (e->l->f->len > 3) {
- mv->flag |= SCULPTVERT_NEED_TRIANGULATE;
+ newflag |= SCULPTVERT_NEED_TRIANGULATE;
}
bool ok = true;
@@ -1983,37 +2005,36 @@ void bke_pbvh_update_vert_boundary(int cd_sculpt_vert,
}
if (e->l->radial_next->f->len > 3) {
- mv->flag |= SCULPTVERT_NEED_TRIANGULATE;
+ newflag |= SCULPTVERT_NEED_TRIANGULATE;
}
}
}
if (!e->l || e->l->radial_next == e->l) {
- mv->flag |= SCULPTVERT_BOUNDARY;
+ newflag |= SCULPTVERT_BOUNDARY;
}
val++;
} while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
if (BLI_array_len(fsets) > 1) {
- mv->flag |= SCULPTVERT_FSET_BOUNDARY;
+ newflag |= SCULPTVERT_FSET_BOUNDARY;
}
if (BLI_array_len(fsets) > 2) {
- mv->flag |= SCULPTVERT_FSET_CORNER;
+ newflag |= SCULPTVERT_FSET_CORNER;
}
if (sharpcount == 1) {
- mv->flag |= SCULPTVERT_SHARP_CORNER;
+ newflag |= SCULPTVERT_SHARP_CORNER;
}
if (seamcount == 1) {
- mv->flag |= SCULPTVERT_SEAM_CORNER;
+ newflag |= SCULPTVERT_SEAM_CORNER;
}
- mv->valence = val;
- if ((mv->flag & SCULPTVERT_BOUNDARY) && quadcount >= 3) {
- mv->flag |= SCULPTVERT_CORNER;
+ if ((newflag & SCULPTVERT_BOUNDARY) && quadcount >= 3) {
+ newflag |= SCULPTVERT_CORNER;
}
#if 0
@@ -2034,8 +2055,16 @@ void bke_pbvh_update_vert_boundary(int cd_sculpt_vert,
}
#endif
- // mv->curv = (short)(fabsf(min_ff(curv * 50.0f, 1.0f)) * 32767.0f);
- mv->curv = (short)(min_ff(fabsf(curv), 1.0f) * 65535.0f);
+ atomic_cas_int32(&mv->flag, oldflag, newflag);
+ atomic_cas_short2(&mv->valence, (ushort)oldval, stroke_id, (ushort)val, stroke_id);
+
+ /* no atomic_cas_int16, so do origmask and curv at once */
+
+ ushort newcurv = (unsigned short)(min_ff(fabsf(curv), 1.0f) * 65535.0f);
+ ushort oldcurv = mv->curv;
+ ushort origmask = mv->origmask;
+
+ atomic_cas_short2(&mv->origmask, origmask, oldcurv, origmask, newcurv);
BLI_array_free(fsets);
}
More information about the Bf-blender-cvs
mailing list