[Bf-blender-cvs] [f031000b28f] sculpt-dev: Sculpt: Mask Init operator and random init modes
Pablo Dobarro
noreply at git.blender.org
Thu Dec 24 16:30:40 CET 2020
Commit: f031000b28fb05a59bfe3573f8d7a9d12dcf691e
Author: Pablo Dobarro
Date: Tue Dec 22 23:59:25 2020 +0100
Branches: sculpt-dev
https://developer.blender.org/rBf031000b28fb05a59bfe3573f8d7a9d12dcf691e
Sculpt: Mask Init operator and random init modes
===================================================================
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
===================================================================
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 3ed5a358d08..51cd1ad0b9f 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -3570,12 +3570,13 @@ static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
/** \name Sculpt Scene Project Brush
* \{ */
-static void sculpt_stroke_cache_snap_context_init(bContext *C, Object *ob) {
+static void sculpt_stroke_cache_snap_context_init(bContext *C, Object *ob)
+{
SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache;
if (ss->cache && ss->cache->snap_context) {
- return;
+ return;
}
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -3583,15 +3584,13 @@ static void sculpt_stroke_cache_snap_context_init(bContext *C, Object *ob) {
ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
- cache->snap_context = ED_transform_snap_object_context_create_view3d(
- scene, 0, region, v3d);
+ cache->snap_context = ED_transform_snap_object_context_create_view3d(scene, 0, region, v3d);
cache->depsgraph = depsgraph;
}
-
static void do_scene_project_brush_task_cb_ex(void *__restrict userdata,
- const int n,
- const TaskParallelTLS *__restrict tls)
+ const int n,
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -3634,20 +3633,19 @@ static void do_scene_project_brush_task_cb_ex(void *__restrict userdata,
normalize_v3(ray_normal);
const bool hit = ED_transform_snap_object_project_ray(ss->cache->snap_context,
- ss->cache->depsgraph,
- &(const struct SnapObjectParams){
- .snap_select = SNAP_NOT_ACTIVE,
- .use_object_edit_cage = true,
- },
- ss->cache->view_origin,
- ray_normal,
- NULL,
- world_space_hit_co,
- NULL);
-
+ ss->cache->depsgraph,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_NOT_ACTIVE,
+ .use_object_edit_cage = true,
+ },
+ ss->cache->view_origin,
+ ray_normal,
+ NULL,
+ world_space_hit_co,
+ NULL);
if (!hit) {
- continue;
+ continue;
}
mul_v3_m4v3(hit_co, data->ob->imat, world_space_hit_co);
@@ -6989,7 +6987,7 @@ void SCULPT_cache_free(StrokeCache *cache)
MEM_SAFE_FREE(cache->limit_surface_co);
if (cache->snap_context) {
- ED_transform_snap_object_context_destroy(cache->snap_context);
+ ED_transform_snap_object_context_destroy(cache->snap_context);
}
if (cache->pose_ik_chain) {
@@ -7160,7 +7158,6 @@ static void sculpt_update_cache_invariants(
copy_v3_v3(cache->true_view_origin, cache->vc->rv3d->viewinv[3]);
-
cache->supports_gravity = (!ELEM(brush->sculpt_tool,
SCULPT_TOOL_MASK,
SCULPT_TOOL_SMOOTH,
@@ -8193,7 +8190,7 @@ static void sculpt_stroke_update_step(bContext *C,
const Brush *brush = BKE_paint_brush(&sd->paint);
if (brush->sculpt_tool == SCULPT_TOOL_SCENE_PROJECT) {
- sculpt_stroke_cache_snap_context_init(C, ob);
+ sculpt_stroke_cache_snap_context_init(C, ob);
}
SCULPT_stroke_modifiers_check(C, ob, brush);
@@ -10077,6 +10074,135 @@ static void SCULPT_OT_dyntopo_detail_size_edit(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+typedef enum eSculptMaskInitMode {
+ SCULPT_MASK_INIT_RANDOM_PER_VERTEX,
+ SCULPT_MASK_INIT_RANDOM_PER_FACE_SET,
+ SCULPT_MASK_INIT_RANDOM_PER_COMPONENT,
+} eSculptMaskInitMode;
+
+static EnumPropertyItem prop_sculpt_mask_init_mode_types[] = {
+ {
+ SCULPT_MASK_INIT_RANDOM_PER_VERTEX,
+ "RANDOM_PER_VERTEX",
+ 0,
+ "Random per Vertex",
+ "",
+ },
+ {
+ SCULPT_MASK_INIT_RANDOM_PER_FACE_SET,
+ "RANDOM_PER_FACE_SET",
+ 0,
+ "Random per Face Set",
+ "",
+ },
+ {
+ SCULPT_MASK_INIT_RANDOM_PER_COMPONENT,
+ "RANDOM_PER_COMPONENT",
+ 0,
+ "Random per Component",
+ "",
+ },
+ {0, NULL, 0, NULL, NULL},
+
+};
+
+static void mask_init_task_cb(void *__restrict userdata,
+ const int i,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ PBVHNode *node = data->nodes[i];
+ PBVHVertexIter vd;
+ const int mode = data->mask_init_mode;
+ const int seed = data->mask_init_seed;
+ SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_MASK);
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+ {
+ switch (mode) {
+ case SCULPT_MASK_INIT_RANDOM_PER_VERTEX:
+ *vd.mask = BLI_hash_int_01(vd.index + seed);
+ break;
+ case SCULPT_MASK_INIT_RANDOM_PER_FACE_SET: {
+ const int face_set = SCULPT_vertex_face_set_get(ss, vd.index);
+ *vd.mask = BLI_hash_int_01(face_set + seed);
+ break;
+ }
+ case SCULPT_MASK_INIT_RANDOM_PER_COMPONENT:
+ *vd.mask = BLI_hash_int_01(ss->vertex_info.connected_component[vd.index] + seed);
+ break;
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+ BKE_pbvh_node_mark_update_mask(data->nodes[i]);
+}
+
+static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+
+ const int mode = RNA_enum_get(op->ptr, "mode");
+
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
+
+ PBVH *pbvh = ob->sculpt->pbvh;
+ PBVHNode **nodes;
+ int totnode;
+ BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
+
+ if (!nodes) {
+ return OPERATOR_CANCELLED;
+ }
+
+ SCULPT_undo_push_begin(ob, "init mask");
+
+ if (mode == SCULPT_MASK_INIT_RANDOM_PER_COMPONENT) {
+ SCULPT_connected_components_ensure(ob);
+ }
+
+ SculptThreadedTaskData data = {
+ .ob = ob,
+ .nodes = nodes,
+ .mask_init_mode = mode,
+ .mask_init_seed = PIL_check_seconds_timer(),
+ };
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &data, mask_init_task_cb, &settings);
+
+ multires_stitch_grids(ob);
+
+ SCULPT_undo_push_end();
+
+ BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
+ MEM_SAFE_FREE(nodes);
+ SCULPT_tag_update_overlays(C);
+ return OPERATOR_FINISHED;
+}
+
+static void SCULPT_OT_mask_init(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Init Mask";
+ ot->description = "Creates a new mask for the mesh";
+ ot->idname = "SCULPT_OT_mask_init";
+
+ /* api callbacks */
+ ot->exec = sculpt_mask_init_exec;
+ ot->poll = SCULPT_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ RNA_def_enum(ot->srna,
+ "mode",
+ prop_sculpt_mask_init_mode_types,
+ SCULPT_MASK_INIT_RANDOM_PER_VERTEX,
+ "Mode",
+ "");
+}
+
void ED_operatortypes_sculpt(void)
{
WM_operatortype_append(SCULPT_OT_brush_stroke);
@@ -10113,4 +10239,5 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_color_filter);
WM_operatortype_append(SCULPT_OT_mask_by_color);
WM_operatortype_append(SCULPT_OT_dyntopo_detail_size_edit);
+ WM_operatortype_append(SCULPT_OT_mask_init);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index dfb65b50c62..9abe1028868 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -782,6 +782,9 @@ typedef struct SculptThreadedTaskData {
int face_set;
int filter_undo_type;
+ int mask_init_mode;
+ int mask_init_seed;
+
ThreadMutex mutex;
} SculptThreadedTaskData;
More information about the Bf-blender-cvs
mailing list