[Bf-blender-cvs] [1e259426c62] temp-sculpt-cavity-mask: temp-sculpt-cavity-mask: Add automask baking tool
Joseph Eagar
noreply at git.blender.org
Wed Jun 29 09:52:44 CEST 2022
Commit: 1e259426c62075307f881cbc2c2c729da50f91bc
Author: Joseph Eagar
Date: Wed Jun 29 00:51:56 2022 -0700
Branches: temp-sculpt-cavity-mask
https://developer.blender.org/rB1e259426c62075307f881cbc2c2c729da50f91bc
temp-sculpt-cavity-mask: Add automask baking tool
Tools lives in the Mask menu and also a subpanel in
the Options panel in the workspace properties.
===================================================================
M release/scripts/startup/bl_ui/space_view3d_toolbar.py
M source/blender/editors/sculpt_paint/sculpt_ops.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 3bde852b216..7264cd6d7f8 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-or-later
-from bpy.types import Menu, Panel, UIList
+from bpy.types import Menu, Panel, UIList, WindowManager
from bl_ui.properties_grease_pencil_common import (
GreasePencilSculptAdvancedPanel,
GreasePencilDisplayPanel,
@@ -939,7 +939,6 @@ class VIEW3D_PT_sculpt_voxel_remesh(Panel, View3DPaintPanel):
layout.operator("object.voxel_remesh", text="Remesh")
-
# TODO, move to space_view3d.py
class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
bl_context = ".sculpt_mode" # dot on purpose (access from topbar)
@@ -1011,7 +1010,29 @@ class VIEW3D_PT_sculpt_options_gravity(Panel, View3DPaintPanel):
col.active = capabilities.has_gravity
col.prop(sculpt, "gravity", slider=True, text="Factor")
col.prop(sculpt, "gravity_object")
+
+class VIEW3D_PT_sculpt_automask_bake(Panel, View3DPaintPanel):
+ bl_context = ".sculpt_mode" # dot on purpose (access from topbar)
+ bl_label = "Bake Automask"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_ui_units_x = 12
+ bl_parent_id = "VIEW3D_PT_sculpt_options"
+
+ @classmethod
+ def poll(cls, context):
+ return (context.sculpt_object and context.tool_settings.sculpt)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ tool_settings = context.tool_settings
+ sculpt = tool_settings.sculpt
+ layout.prop(WindowManager.operator_properties_last("sculpt.bake_automask"), "mix_mode")
+ layout.prop(WindowManager.operator_properties_last("sculpt.bake_automask"), "factor")
+ props = layout.operator("sculpt.bake_automask")
# TODO, move to space_view3d.py
class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel):
@@ -2455,6 +2476,7 @@ classes = (
VIEW3D_PT_tools_grease_pencil_brush_vertex_color,
VIEW3D_PT_tools_grease_pencil_brush_vertex_palette,
VIEW3D_PT_tools_grease_pencil_brush_vertex_falloff,
+ VIEW3D_PT_sculpt_automask_bake,
)
if __name__ == "__main__": # only for live edit.
diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.c b/source/blender/editors/sculpt_paint/sculpt_ops.c
index f16763be735..2271c968cd3 100644
--- a/source/blender/editors/sculpt_paint/sculpt_ops.c
+++ b/source/blender/editors/sculpt_paint/sculpt_ops.c
@@ -1127,6 +1127,155 @@ static void SCULPT_OT_mask_by_color(wmOperatorType *ot)
1.0f);
}
+typedef enum {
+ AUTOMASK_BAKE_MIX,
+ AUTOMASK_BAKE_MULTIPLY,
+ AUTOMASK_BAKE_DIVIDE,
+ AUTOMASK_BAKE_ADD,
+ AUTOMASK_BAKE_SUBTRACT,
+} AutomaskBakeMixMode;
+
+typedef struct AutomaskBakeTaskData {
+ SculptSession *ss;
+ AutomaskingCache *automasking;
+ PBVHNode **nodes;
+ AutomaskBakeMixMode mode;
+ float factor;
+ Object *ob;
+} AutomaskBakeTaskData;
+
+static void sculpt_bake_automask_exec_task_cb(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ AutomaskBakeTaskData *tdata = userdata;
+ SculptSession *ss = tdata->ss;
+ PBVHNode *node = tdata->nodes[n];
+ PBVHVertexIter vd;
+ const AutomaskBakeMixMode mode = tdata->mode;
+ const float factor = tdata->factor;
+
+ SCULPT_undo_push_node(tdata->ob, node, SCULPT_UNDO_MASK);
+
+ BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
+ float automask = SCULPT_automasking_factor_get(tdata->automasking, ss, vd.index);
+ float mask;
+
+ switch (mode) {
+ case AUTOMASK_BAKE_MIX:
+ mask = automask;
+ break;
+ case AUTOMASK_BAKE_MULTIPLY:
+ mask = *vd.mask * automask;
+ break;
+ break;
+ case AUTOMASK_BAKE_DIVIDE:
+ mask = automask > 0.00001f ? *vd.mask / automask : 0.0f;
+ break;
+ break;
+ case AUTOMASK_BAKE_ADD:
+ mask = *vd.mask + automask;
+ break;
+ case AUTOMASK_BAKE_SUBTRACT:
+ mask = *vd.mask - automask;
+ break;
+ }
+
+ mask = *vd.mask + (mask - *vd.mask) * factor;
+ CLAMP(mask, 0.0f, 1.0f);
+
+ *vd.mask = mask;
+
+ if (vd.mvert) {
+ BKE_pbvh_vert_mark_update(ss->pbvh, vd.index);
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+
+ BKE_pbvh_node_mark_redraw(node);
+}
+
+static int sculpt_bake_automask_exec(bContext *C, wmOperator *op)
+{
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
+ SCULPT_vertex_random_access_ensure(ss);
+
+ SCULPT_undo_push_begin(ob, "Bake Automask");
+
+ AutomaskBakeMixMode mode = RNA_enum_get(op->ptr, "mix_mode");
+ float factor = RNA_float_get(op->ptr, "factor");
+
+ PBVHNode **nodes;
+ int totnode;
+
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+
+ AutomaskBakeTaskData tdata;
+
+ tdata.ob = ob;
+ tdata.mode = mode;
+ tdata.factor = factor;
+ tdata.ss = ss;
+ tdata.nodes = nodes;
+ tdata.automasking = SCULPT_automasking_cache_init(sd, brush, ob);
+
+ ss->stroke_id++;
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &tdata, sculpt_bake_automask_exec_task_cb, &settings);
+
+ MEM_SAFE_FREE(nodes);
+ SCULPT_automasking_cache_free(tdata.automasking);
+
+ BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
+ SCULPT_undo_push_end(ob);
+
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
+
+ /* Unlike other operators we do not tag the ID for update here;
+ * it triggers a PBVH rebuild which is too slow and ruins
+ * the interactivity of the tool. */
+
+ return OPERATOR_FINISHED;
+}
+
+static void SCULPT_OT_bake_automask(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Bake Automask";
+ ot->idname = "SCULPT_OT_bake_automask";
+ ot->description = "Creates a mask based on automasking settings";
+
+ static EnumPropertyItem mix_modes[] = {
+ {AUTOMASK_BAKE_MIX, "MIX", ICON_NONE, "Mix", ""},
+ {AUTOMASK_BAKE_MIX, "MULTIPLY", ICON_NONE, "Multiply", ""},
+ {AUTOMASK_BAKE_MIX, "DIVIDE", ICON_NONE, "Divide", ""},
+ {AUTOMASK_BAKE_MIX, "ADD", ICON_NONE, "Add", ""},
+ {AUTOMASK_BAKE_MIX, "SUBTRACT", ICON_NONE, "Subtract", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ /* api callbacks */
+ ot->exec = sculpt_bake_automask_exec;
+ ot->poll = SCULPT_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER;
+
+ PropertyRNA *prop;
+
+ prop = RNA_def_enum(ot->srna, "mix_mode", mix_modes, AUTOMASK_BAKE_MIX, "Mode", "Mix mode");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+
+ RNA_def_float(ot->srna, "factor", 1.0f, 0.0f, 4.0f, "Mix Factor", "", 0.0f, 1.0f);
+}
+
void ED_operatortypes_sculpt(void)
{
WM_operatortype_append(SCULPT_OT_brush_stroke);
@@ -1164,4 +1313,5 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_mask_init);
WM_operatortype_append(SCULPT_OT_expand);
+ WM_operatortype_append(SCULPT_OT_bake_automask);
}
More information about the Bf-blender-cvs
mailing list