[Bf-blender-cvs] [a1830859fa9] master: Curves: Add soft selection in sculpt mode

Hans Goudey noreply at git.blender.org
Tue May 31 19:01:16 CEST 2022


Commit: a1830859fa98d529a2eae709b2557a91f1bbe9e7
Author: Hans Goudey
Date:   Tue May 31 19:00:24 2022 +0200
Branches: master
https://developer.blender.org/rBa1830859fa98d529a2eae709b2557a91f1bbe9e7

Curves: Add soft selection in sculpt mode

This commit adds a float selection to curve control points or curves,
a sculpt tool to paint the selection, and uses the selection influence
in the existing sculpt brushes.

The selection is the inverse of the "mask" from mesh sculpt mode
currently. That change is described in more detail here: T97903

Since some sculpt tools are really "per curve" tools, they use the
average point selection of all of their points. The delete brush
considers a curve selected if any of its points have a non-zero
selection.

There is a new option to choose the selection domain, which affects how
painting the selection works. You can also turn the selection off by
clicking on the active domain.

Sculpt brushes can be faster when the selection is small, because
finding selected curves or points is generally faster than the
existing brush intersection and distance checks.

The main limitation currently is that we can't see the selection in the
viewport by default. For now, to see the selection one has to add a
simple material to the curves object as shown in the differential
revision. And one has to switch to Material Preview in the 3d view.

Differential Revision: https://developer.blender.org/D14934

===================================================================

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	release/scripts/startup/bl_ui/properties_paint_common.py
M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/blenkernel/BKE_curves.hh
M	source/blender/blenkernel/intern/curves_geometry.cc
M	source/blender/editors/curves/intern/curves_ops.cc
M	source/blender/editors/sculpt_paint/CMakeLists.txt
M	source/blender/editors/sculpt_paint/curves_sculpt_add.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_intern.hh
M	source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
A	source/blender/editors/sculpt_paint/curves_sculpt_selection.cc
A	source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
M	source/blender/makesdna/DNA_brush_enums.h
M	source/blender/makesdna/DNA_curves_types.h
M	source/blender/makesrna/RNA_enum_items.h
M	source/blender/makesrna/intern/rna_attribute.c
M	source/blender/makesrna/intern/rna_brush.c
M	source/blender/makesrna/intern/rna_curves.c

===================================================================

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 180dc9a894d..adaebf7ce7b 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -5594,7 +5594,14 @@ def km_sculpt_curves(params):
          {"properties": [("mode", 'NORMAL')]}),
         ("sculpt_curves.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
          {"properties": [("mode", 'INVERT')]}),
+        ("sculpt_curves.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
+         {"properties": [("mode", 'SMOOTH')]}),
+        ("curves.set_selection_domain", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("domain", 'POINT')]}),
+        ("curves.set_selection_domain", {"type": 'TWO', "value": 'PRESS'}, {"properties": [("domain", 'CURVE')]}),
+        ("curves.disable_selection", {"type": 'ONE', "value": 'PRESS', "alt": True}, None),
+        ("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None),
         *_template_paint_radial_control("curves_sculpt"),
+        *_template_items_select_actions(params, "sculpt_curves.select_all"),
     ])
 
     return keymap
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index d5b106635ab..d7325257084 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -859,7 +859,7 @@ def brush_shared_settings(layout, context, brush, popover=False):
     if mode == 'SCULPT_CURVES':
         size = True
         strength = True
-        direction = brush.curves_sculpt_tool == 'GROW_SHRINK'
+        direction = brush.curves_sculpt_tool in {'GROW_SHRINK', 'SELECTION_PAINT'}
 
     ### Draw settings. ###
     ups = context.scene.tool_settings.unified_paint_settings
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index 5c6ca13776e..1c526cc89e4 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -2316,14 +2316,58 @@ class _defs_gpencil_weight:
 
 class _defs_curves_sculpt:
 
-    @staticmethod
-    def generate_from_brushes(context):
-        return generate_from_enum_ex(
-            context,
-            idname_prefix="builtin_brush.",
-            icon_prefix="ops.curves.sculpt_",
-            type=bpy.types.Brush,
-            attr="curves_sculpt_tool",
+    @ToolDef.from_fn
+    def selection_paint():
+        return dict(
+            idname="builtin_brush.selection_paint",
+            label="Selection Paint",
+            icon="ops.generic.select_paint",
+            data_block="SELECTION_PAINT"
+        )
+
+    @ToolDef.from_fn
+    def comb():
+        return dict(
+            idname="builtin_brush.comb",
+            label="Comb",
+            icon="ops.curves.sculpt_comb",
+            data_block='COMB'
+        )
+
+    @ToolDef.from_fn
+    def add():
+        return dict(
+            idname="builtin_brush.add",
+            label="Add",
+            icon="ops.curves.sculpt_add",
+            data_block='ADD'
+        )
+
+    @ToolDef.from_fn
+    def delete():
+        return dict(
+            idname="builtin_brush.delete",
+            label="Delete",
+            icon="ops.curves.sculpt_delete",
+            data_block='DELETE'
+        )
+
+    @ToolDef.from_fn
+    def snake_hook():
+        return dict(
+            idname="builtin_brush.snake_hook",
+            label="Snake Hook",
+            icon="ops.curves.sculpt_snake_hook",
+            data_block='SNAKE_HOOK'
+        )
+
+    @ToolDef.from_fn
+    def grow_shrink():
+        return dict(
+            idname="builtin_brush.grow_shrink",
+            label="Grow/Shrink",
+            icon="ops.curves.sculpt_grow_shrink",
+            data_block='GROW_SHRINK'
         )
 
 
@@ -3076,7 +3120,21 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
             ),
         ],
         'SCULPT_CURVES': [
-            _defs_curves_sculpt.generate_from_brushes,
+            lambda context: (
+                (
+                    _defs_curves_sculpt.selection_paint,
+                    None,
+                )
+                if context is None or context.preferences.experimental.use_new_curves_tools
+                else ()
+            ),
+            _defs_curves_sculpt.comb,
+            _defs_curves_sculpt.add,
+            _defs_curves_sculpt.delete,
+            _defs_curves_sculpt.snake_hook,
+            _defs_curves_sculpt.grow_shrink,
+            None,
+            *_tools_annotate,
         ],
     }
 
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 1af70895be9..116dd280b5c 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -535,6 +535,11 @@ class _draw_tool_settings_context_mode:
         if brush.curves_sculpt_tool == 'DELETE':
             layout.prop(brush, "falloff_shape", expand=True)
 
+        if brush.curves_sculpt_tool == 'SELECTION_PAINT':
+            layout.prop(brush, "direction", expand=True, text="")
+            layout.prop(brush, "falloff_shape", expand=True)
+            layout.popover("VIEW3D_PT_tools_brush_falloff")
+
 
 class VIEW3D_HT_header(Header):
     bl_space_type = 'VIEW_3D'
@@ -687,6 +692,24 @@ class VIEW3D_HT_header(Header):
             if object_mode == 'PARTICLE_EDIT':
                 row = layout.row()
                 row.prop(tool_settings.particle_edit, "select_mode", text="", expand=True)
+            elif object_mode == 'SCULPT_CURVES' and obj.type == 'CURVES':
+                curves = obj.data
+
+                row = layout.row(align=True)
+
+                experimental = context.preferences.experimental
+                if experimental.use_new_curves_tools:
+                    # Combine the "use selection" toggle with the "set domain" operators
+                    # to allow turning selection off directly.
+                    domain = curves.selection_domain
+                    if domain == 'POINT':
+                        row.prop(curves, "use_sculpt_selection", text="", icon='CURVE_BEZCIRCLE')
+                    else:
+                        row.operator("curves.set_selection_domain", text="", icon='CURVE_BEZCIRCLE').domain = 'POINT'
+                    if domain == 'CURVE':
+                        row.prop(curves, "use_sculpt_selection", text="", icon='CURVE_PATH')
+                    else:
+                        row.operator("curves.set_selection_domain", text="", icon='CURVE_PATH').domain = 'CURVE'
 
         # Grease Pencil
         if obj and obj.type == 'GPENCIL' and context.gpencil_data:
@@ -939,6 +962,7 @@ class VIEW3D_MT_editor_menus(Menu):
                 layout.menu("VIEW3D_MT_mask")
                 layout.menu("VIEW3D_MT_face_sets")
             if mode_string == 'SCULPT_CURVES':
+                layout.menu("VIEW3D_MT_select_sculpt_curves")
                 layout.menu("VIEW3D_MT_sculpt_curves")
 
         else:
@@ -1976,6 +2000,17 @@ class VIEW3D_MT_select_edit_curves(Menu):
         pass
 
 
+class VIEW3D_MT_select_sculpt_curves(Menu):
+    bl_label = "Select"
+
+    def draw(self, _context):
+        layout = self.layout
+
+        layout.operator("sculpt_curves.select_all", text="All").action = 'SELECT'
+        layout.operator("sculpt_curves.select_all", text="None").action = 'DESELECT'
+        layout.operator("sculpt_curves.select_all", text="Invert").action = 'INVERT'
+
+
 class VIEW3D_MT_angle_control(Menu):
     bl_label = "Angle Control"
 
@@ -7703,6 +7738,7 @@ classes = (
     VIEW3D_MT_select_paint_mask,
     VIEW3D_MT_select_paint_mask_vertex,
     VIEW3D_MT_select_edit_curves,
+    VIEW3D_MT_select_sculpt_curves,
     VIEW3D_MT_angle_control,
     VIEW3D_MT_mesh_add,
     VIEW3D_MT_curve_add,
diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh
index cc056dab248..445f8d46f2d 100644
--- a/source/blender/blenkernel/BKE_curves.hh
+++ b/source/blender/blenkernel/BKE_curves.hh
@@ -281,6 +281,11 @@ class CurvesGeometry : public ::CurvesGeometry {
   Span<float2> surface_triangle_coords() const;
   MutableSpan<float2> surface_triangle_coords_for_write();
 
+  VArray<float> selection_point_float() const;
+  MutableSpan<float> selection_point_float_for_write();
+  VArray<float> selection_curve_float() const;
+  MutableSpan<float> selection_curve_float_for_write();
+
   /**
    * Calculate the largest and smallest position values, only including control points
    * (rather than evaluated points). The existing values of `min` and `max` are taken into account.
@@ -406,6 +411,11 @@ class CurvesGeometry : public ::CurvesGeometry {
    */
 
   GVArray adapt_domain(const GVArray &varray, AttributeDomain from, AttributeDomain to) const;
+  template<typename T>
+  VArray<T> adapt_domain(const VArray<T> &varray, AttributeDomain from, AttributeDomain to) const
+  {
+    return this->adapt_domain(GVArray(varray), from, to).typed<T>();
+  }
 };
 
 namespace curves {
diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc
index 0fd58a52f81..07e50eea88c 100644
--- a/source/blender/blenkernel/intern/curves_geometry.cc
+++ b/source/blender/blenkernel/intern/curves_geometry.cc
@@ -37,6 +37,8 @@ static const std::string ATTR_NURBS_WEIGHT = "nurbs_weight";
 static const std::string ATTR_NURBS_KNOTS_MODE = "knots_mode";
 static const std::string ATTR_SURFACE_TRIANGLE_INDEX = "surface_triangle_index";
 static const std::string ATTR_SURFACE_TRIANGLE_COORDINATE = "surface_triangle_coordinate";
+static const std::string ATTR_SELECTION_POINT_FLOAT = ".selection_point_float";
+static const std::string ATTR_SELECTION_CURVE_FLOAT = ".selection_curve_float";
 
 /* -------------------------------------------------------------------- */
 /** \name Constructors/Destructor
@@ -438,6 +440,26 @@ MutableSpan<

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list