[Bf-blender-cvs] [9c30155c47f] sculpt-dev: Sculpt: fix drag-dot/anchored for face sets
Joseph Eagar
noreply at git.blender.org
Thu Sep 30 10:36:37 CEST 2021
Commit: 9c30155c47f51bb796a305b633bdcae87856b0ef
Author: Joseph Eagar
Date: Thu Sep 30 01:36:08 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rB9c30155c47f51bb796a305b633bdcae87856b0ef
Sculpt: fix drag-dot/anchored for face sets
* Added an API for original face sets
based on the SculptCustomLayer API.
===================================================================
M source/blender/blenkernel/BKE_paint.h
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_face_set.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 63d0357de49..31aa0b3d2b5 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -567,6 +567,7 @@ enum {
SCULPT_SCL_PERS_DISP,
SCULPT_SCL_LAYER_DISP,
SCULPT_SCL_LAYER_STROKE_ID,
+ SCULPT_SCL_ORIG_FSETS,
SCULPT_SCL_LAYER_MAX
};
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 6db155e03f1..f4cb0dac6ed 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -38,6 +38,17 @@ extern "C" {
// experimental feature to detect quad diagonals and mark (but not dissolve) them
//#define SCULPT_DIAGONAL_EDGE_MARKS
+/*
+ These structs represent logical verts/edges/faces.
+ for PBVH_GRIDS and PBVH_FACES they store integer
+ offsets, PBVH_BMESH stores pointers.
+
+ The idea is to enforce stronger type checking by encapsulating
+ intptr_t's in structs.*/
+typedef struct SculptElemRef {
+ intptr_t i;
+} SculptElemRef;
+
typedef struct SculptVertRef {
intptr_t i;
} SculptVertRef;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index f8f44cc54a8..c15ec5340d6 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -2959,11 +2959,18 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
SCULPT_orig_vert_data_unode_init(&orig_data, data->ob, unode);
+ bool modified = false;
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (orig_data.unode->type == SCULPT_UNDO_COORDS) {
+ if (len_squared_v3v3(vd.co, orig_data.co) > FLT_EPSILON) {
+ modified = true;
+ }
+
copy_v3_v3(vd.co, orig_data.co);
+
if (vd.no) {
copy_v3_v3_short(vd.no, orig_data.no);
}
@@ -2972,9 +2979,17 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
}
}
else if (orig_data.unode->type == SCULPT_UNDO_MASK) {
+ if ((*vd.mask - orig_data.mask) * (*vd.mask - orig_data.mask) > FLT_EPSILON) {
+ modified = true;
+ }
+
*vd.mask = orig_data.mask;
}
else if (orig_data.unode->type == SCULPT_UNDO_COLOR && vd.col && orig_data.col) {
+ if (len_squared_v4v4(vd.col, orig_data.col) > FLT_EPSILON) {
+ modified = true;
+ }
+
copy_v4_v4(vd.col, orig_data.col);
}
@@ -2984,7 +2999,9 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
}
BKE_pbvh_vertex_iter_end;
- BKE_pbvh_node_mark_update(data->nodes[n]);
+ if (modified) {
+ BKE_pbvh_node_mark_update(data->nodes[n]);
+ }
}
static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
@@ -2997,11 +3014,6 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
- /**
- * Disable multi-threading when dynamic-topology is enabled. Otherwise,
- * new entries might be inserted by #SCULPT_undo_push_node() into the #GHash
- * used internally by #BM_log_original_vert_co() by a different thread. See T33787.
- */
SculptThreadedTaskData data = {
.sd = sd,
.ob = ob,
@@ -3010,7 +3022,7 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true && !ss->bm, totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, paint_mesh_restore_co_task_cb, &settings);
BKE_pbvh_node_color_buffer_free(ss->pbvh);
@@ -3784,10 +3796,10 @@ static void calc_area_normal_and_center(
* values pull vertices, negative values push. Uses tablet pressure and a
* special multiplier found experimentally to scale the strength factor.
*/
-ATTR_NO_OPT static float brush_strength(const Sculpt *sd,
- const StrokeCache *cache,
- const float feather,
- const UnifiedPaintSettings *ups)
+static float brush_strength(const Sculpt *sd,
+ const StrokeCache *cache,
+ const float feather,
+ const UnifiedPaintSettings *ups)
{
const Scene *scene = cache->vc->scene;
const Brush *brush = cache->brush; // BKE_paint_brush((Paint *)&sd->paint);
@@ -8784,8 +8796,20 @@ void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings
* Check that original data is for anchored and drag dot modes
*/
if (brush->flag & (BRUSH_ANCHORED | BRUSH_DRAG_DOT)) {
+ if (SCULPT_stroke_is_first_brush_step(ss->cache) &&
+ brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS) {
+
+ SCULPT_face_ensure_original(ss);
+
+ for (int i = 0; i < ss->totfaces; i++) {
+ SculptFaceRef face = BKE_pbvh_table_index_to_face(ss->pbvh, i);
+ SCULPT_face_check_origdata(ss, face);
+ }
+ }
+
for (int i = 0; i < totnode; i++) {
PBVHVertexIter vd;
+
BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[i], vd, PBVH_ITER_UNIQUE) {
SCULPT_vertex_check_origdata(ss, vd.vertex);
}
@@ -11421,13 +11445,11 @@ static void sculpt_restore_mesh(Sculpt *sd, Object *ob)
BKE_brush_use_size_pressure(brush)) ||
(brush->flag & BRUSH_DRAG_DOT)) {
- if (BKE_pbvh_type(ss->pbvh) != PBVH_BMESH) {
- SculptUndoNode *unode = SCULPT_undo_get_first_node();
- if (unode && unode->type == SCULPT_UNDO_FACE_SETS) {
- for (int i = 0; i < ss->totfaces; i++) {
- ss->face_sets[i] = unode->face_sets[i];
- }
- }
+ for (int i = 0; i < ss->totfaces; i++) {
+ SculptFaceRef face = BKE_pbvh_table_index_to_face(ss->pbvh, i);
+ int origf = SCULPT_face_set_original_get(ss, face);
+
+ SCULPT_face_set_set(ss, face, origf);
}
paint_mesh_restore_co(sd, ob);
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index 53ac6793f3c..85a8eccf11a 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -127,6 +127,57 @@ int SCULPT_face_set_set(SculptSession *ss, SculptFaceRef face, int fset)
return ret;
}
+const char orig_faceset_attr_name[] = "_sculpt_original_fsets";
+
+void SCULPT_face_check_origdata(SculptSession *ss, SculptFaceRef face)
+{
+ if (!ss->custom_layers[SCULPT_SCL_ORIG_FSETS]) {
+ return;
+ }
+
+ short *s = (short *)SCULPT_temp_cdata_get_f(face, ss->custom_layers[SCULPT_SCL_ORIG_FSETS]);
+
+ // pack ss->stroke_id in higher 16 bits
+ if (s[1] != ss->stroke_id) {
+ s[0] = SCULPT_face_set_get(ss, face);
+ s[1] = ss->stroke_id;
+ }
+}
+
+int SCULPT_face_set_original_get(SculptSession *ss, SculptFaceRef face)
+{
+ if (!ss->custom_layers[SCULPT_SCL_ORIG_FSETS]) {
+ return SCULPT_face_set_get(ss, face);
+ }
+
+ short *s = (short *)SCULPT_temp_cdata_get_f(face, ss->custom_layers[SCULPT_SCL_ORIG_FSETS]);
+
+ if (s[1] != ss->stroke_id) {
+ s[0] = SCULPT_face_set_get(ss, face);
+ s[1] = ss->stroke_id;
+ }
+
+ return s[0];
+}
+
+void SCULPT_face_ensure_original(SculptSession *ss)
+{
+ if (ss->custom_layers[SCULPT_SCL_ORIG_FSETS]) {
+ return;
+ }
+
+ SculptCustomLayer *scl = MEM_callocN(sizeof(*scl), "orig fset scl");
+
+ SCULPT_temp_customlayer_get(ss,
+ ATTR_DOMAIN_FACE,
+ CD_PROP_INT32,
+ "orig_faceset_attr_name",
+ scl,
+ &((SculptLayerParams){.permanent = false, .simple_array = false}));
+
+ ss->custom_layers[SCULPT_SCL_ORIG_FSETS] = scl;
+}
+
int SCULPT_face_set_flag_get(SculptSession *ss, SculptFaceRef face, char flag)
{
if (ss->bm) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index cbf2cb6b3b3..600cc8e3cc9 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -336,6 +336,10 @@ bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, SculptVertRef ind
void SCULPT_face_sets_visibility_invert(SculptSession *ss);
void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible);
+void SCULPT_face_ensure_original(SculptSession *ss);
+int SCULPT_face_set_original_get(SculptSession *ss, SculptFaceRef face);
+void SCULPT_face_check_origdata(SculptSession *ss, SculptFaceRef face);
+
int SCULPT_face_set_get(SculptSession *ss, SculptFaceRef face);
// returns previous face set
@@ -1800,7 +1804,6 @@ int SCULPT_get_symmetry_pass(const SculptSession *ss);
void SCULPT_on_sculptsession_bmesh_free(SculptSession *ss);
void SCULPT_reorder_bmesh(SculptSession *ss);
-// TODO: support faces
static inline void *SCULPT_temp_cdata_get(SculptVertRef vertex, SculptCustomLayer *scl)
{
if (scl->data) {
@@ -1808,14 +1811,36 @@ static inline void *SCULPT_temp_cdata_get(SculptVertRef vertex, SculptCustomLaye
int idx = (int)vertex.i;
if (scl->from_bmesh) {
- BMVert *v = (BMVert *)vertex.i;
+ BMElem *v = (BMElem *)vertex.i;
+ idx = v->head.index;
+ }
+
+ return p + scl->elemsize * (int)vertex.i;
+ }
+ else {
+ BMElem *v = (BMElem *)vertex.i;
+ return BM_ELEM_CD_GET_VOID_P(v, scl->cd_offset);
+ }
+
+ return NULL;
+}
+
+// arg, duplicate functions!
+static inline void *SCULPT_temp_cdata_get_f(SculptFaceRef vertex, SculptCustomLayer *scl)
+{
+ if (scl->data) {
+ char *p = (char *)scl->data;
+ int idx = (int)vertex.i;
+
+ if (scl->from_bmesh) {
+ BMElem *v = (BMElem *)vertex.i;
idx = v->head.index;
}
return p + scl->elemsize * (int)vertex.i;
}
else {
- BMVert *v = (BMVert *)vertex.i;
+ BMElem *v = (BMElem *)vertex.i;
return BM_ELEM_CD_GET_VOID_P(v, scl->cd_offset);
}
More information about the Bf-blender-cvs
mailing list