[Bf-blender-cvs] [13206a6dc04] master: Sculpt: Mask Filter and Dirty Mask generator

Pablo Dobarro noreply at git.blender.org
Mon Sep 9 16:29:07 CEST 2019


Commit: 13206a6dc04eaf6f4b5eea28c135df842f43542b
Author: Pablo Dobarro
Date:   Mon Sep 9 16:20:40 2019 +0200
Branches: master
https://developer.blender.org/rB13206a6dc04eaf6f4b5eea28c135df842f43542b

Sculpt: Mask Filter and Dirty Mask generator

The mask filter operator modifies the whole paint mask. In includes multiple operations like smooth, grow or contrast accessible from a pie menu.
The dirty mask generator is similar to Dirty Vertex Colors, but it generates a paint mask. It can be used to mask cavities in the sculpt.

Reviewed By: brecht

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

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

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h

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

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 6d4c3616ca4..328edf3a1fb 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -3900,6 +3900,7 @@ def km_sculpt(params):
          {"properties": [("data_path", 'tool_settings.sculpt.brush.use_smooth_stroke')]}),
         op_menu("VIEW3D_MT_angle_control", {"type": 'R', "value": 'PRESS'}),
         op_panel("VIEW3D_PT_sculpt_context_menu", params.context_menu_event),
+        op_menu_pie("VIEW3D_MT_sculpt_mask_edit_pie", {"type" : 'A', "value": 'PRESS'})
     ])
 
     if params.legacy:
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 69fa5bc8f4b..5351fe07ed3 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2845,6 +2845,36 @@ class VIEW3D_MT_sculpt(Menu):
         props = layout.operator("view3d.select_box", text="Box Mask")
         props = layout.operator("paint.mask_lasso_gesture", text="Lasso Mask")
 
+        layout.separator()
+
+        props = layout.operator("sculpt.mask_filter", text='Smooth Mask')
+        props.filter_type = 'SMOOTH'
+        props.auto_iteration_count = True;
+
+        props = layout.operator("sculpt.mask_filter", text='Sharpen Mask')
+        props.filter_type = 'SHARPEN'
+        props.auto_iteration_count = True;
+
+        props = layout.operator("sculpt.mask_filter", text='Grow Mask')
+        props.filter_type = 'GROW'
+        props.auto_iteration_count = True;
+
+        props = layout.operator("sculpt.mask_filter", text='Shrink Mask')
+        props.filter_type = 'SHRINK'
+        props.auto_iteration_count = True;
+
+        props = layout.operator("sculpt.mask_filter", text='Increase Contrast')
+        props.filter_type = 'CONTRAST_INCREASE'
+        props.auto_iteration_count = False;
+
+        props = layout.operator("sculpt.mask_filter", text='Decrease Contrast')
+        props.filter_type = 'CONTRAST_DECREASE'
+        props.auto_iteration_count = False;
+
+        layout.separator()
+
+        props = layout.operator("sculpt.dirty_mask", text='Dirty Mask')
+
 
 class VIEW3D_MT_particle(Menu):
     bl_label = "Particle"
@@ -4783,6 +4813,36 @@ class VIEW3D_MT_proportional_editing_falloff_pie(Menu):
 
         pie.prop(tool_settings, "proportional_edit_falloff", expand=True)
 
+class VIEW3D_MT_sculpt_mask_edit_pie(Menu):
+    bl_label = "Mask Edit"
+
+    def draw(self, _context):
+        layout = self.layout
+        pie = layout.menu_pie()
+
+        op = pie.operator("paint.mask_flood_fill", text='Invert Mask')
+        op.mode = 'INVERT'
+        op = pie.operator("paint.mask_flood_fill", text='Clear Mask')
+        op.mode = 'VALUE'
+        op = pie.operator("sculpt.mask_filter", text='Smooth Mask')
+        op.filter_type = 'SMOOTH'
+        op.auto_iteration_count = True;
+        op = pie.operator("sculpt.mask_filter", text='Sharpen Mask')
+        op.filter_type = 'SHARPEN'
+        op.auto_iteration_count = True;
+        op = pie.operator("sculpt.mask_filter", text='Grow Mask')
+        op.filter_type = 'GROW'
+        op.auto_iteration_count = True;
+        op = pie.operator("sculpt.mask_filter", text='Shrink Mask')
+        op.filter_type = 'SHRINK'
+        op.auto_iteration_count = True;
+        op = pie.operator("sculpt.mask_filter", text='Increase Contrast')
+        op.filter_type = 'CONTRAST_INCREASE'
+        op.auto_iteration_count = False;
+        op = pie.operator("sculpt.mask_filter", text='Decrease Contrast')
+        op.filter_type = 'CONTRAST_DECREASE'
+        op.auto_iteration_count = False;
+
 
 # ********** Panel **********
 
@@ -6766,6 +6826,7 @@ classes = (
     VIEW3D_MT_snap_pie,
     VIEW3D_MT_orientations_pie,
     VIEW3D_MT_proportional_editing_falloff_pie,
+    VIEW3D_MT_sculpt_mask_edit_pie,
     VIEW3D_PT_active_tool,
     VIEW3D_PT_active_tool_duplicate,
     VIEW3D_PT_view3d_properties,
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index da1ee8c3310..69b23040993 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -116,8 +116,6 @@ static void sculpt_vertex_random_access_init(SculptSession *ss)
   }
 }
 
-#if 0 /* UNUSED */
-
 static int sculpt_active_vertex_get(SculptSession *ss)
 {
   switch (BKE_pbvh_type(ss->pbvh)) {
@@ -142,7 +140,6 @@ static int sculpt_vertex_count_get(SculptSession *ss)
   }
 }
 
-
 static void sculpt_vertex_normal_get(SculptSession *ss, int index, float no[3])
 {
   switch (BKE_pbvh_type(ss->pbvh)) {
@@ -156,20 +153,6 @@ static void sculpt_vertex_normal_get(SculptSession *ss, int index, float no[3])
   }
 }
 
-static void sculpt_vertex_co_set(SculptSession *ss, int index, float co[3])
-{
-  switch (BKE_pbvh_type(ss->pbvh)) {
-    case PBVH_FACES:
-      copy_v3_v3(ss->mvert[index].co, co);
-      return;
-    case PBVH_BMESH:
-      copy_v3_v3(BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co, co);
-      return;
-    default:
-      return;
-  }
-}
-
 static void sculpt_vertex_mask_set(SculptSession *ss, int index, float mask)
 {
   BMVert *v;
@@ -204,6 +187,20 @@ static float sculpt_vertex_mask_get(SculptSession *ss, int index)
   }
 }
 
+static void sculpt_vertex_co_set(SculptSession *ss, int index, float co[3])
+{
+  switch (BKE_pbvh_type(ss->pbvh)) {
+    case PBVH_FACES:
+      copy_v3_v3(ss->mvert[index].co, co);
+      return;
+    case PBVH_BMESH:
+      copy_v3_v3(BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co, co);
+      return;
+    default:
+      return;
+  }
+}
+
 static void sculpt_vertex_tag_update(SculptSession *ss, int index)
 {
   switch (BKE_pbvh_type(ss->pbvh)) {
@@ -217,7 +214,7 @@ static void sculpt_vertex_tag_update(SculptSession *ss, int index)
   }
 }
 
-#  define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256
+#define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256
 
 typedef struct SculptVertexNeighborIter {
   int *neighbors;
@@ -320,19 +317,29 @@ static void sculpt_vertex_neighbors_get(SculptSession *ss,
   }
 }
 
-#  define sculpt_vertex_neighbors_iter_begin(ss, v_index, neighbor_iterator) \
-    sculpt_vertex_neighbors_get(ss, v_index, &neighbor_iterator); \
-    for (neighbor_iterator.i = 0; neighbor_iterator.i < neighbor_iterator.size; \
-         neighbor_iterator.i++) { \
-      neighbor_iterator.index = ni.neighbors[ni.i];
+#define sculpt_vertex_neighbors_iter_begin(ss, v_index, neighbor_iterator) \
+  sculpt_vertex_neighbors_get(ss, v_index, &neighbor_iterator); \
+  for (neighbor_iterator.i = 0; neighbor_iterator.i < neighbor_iterator.size; \
+       neighbor_iterator.i++) { \
+    neighbor_iterator.index = ni.neighbors[ni.i];
 
-#  define sculpt_vertex_neighbors_iter_end(neighbor_iterator) \
-    } \
-    if (neighbor_iterator.neighbors != neighbor_iterator.neighbors_fixed) { \
-      MEM_freeN(neighbor_iterator.neighbors); \
-    }
+#define sculpt_vertex_neighbors_iter_end(neighbor_iterator) \
+  } \
+  if (neighbor_iterator.neighbors != neighbor_iterator.neighbors_fixed) { \
+    MEM_freeN(neighbor_iterator.neighbors); \
+  }
 
-#endif /* UNUSED */
+/* Utils */
+static void sculpt_vertex_mask_clamp(SculptSession *ss, int index, float min, float max)
+{
+  float mask = sculpt_vertex_mask_get(ss, index);
+  if (mask > max) {
+    sculpt_vertex_mask_set(ss, index, max);
+  }
+  else if (mask < min) {
+    sculpt_vertex_mask_set(ss, index, min);
+  }
+}
 
 /** \name Tool Capabilities
  *
@@ -7267,7 +7274,6 @@ static void SCULPT_OT_set_detail_size(wmOperatorType *ot)
 
   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
-
 static void filter_cache_init_task_cb(void *__restrict userdata,
                                       const int i,
                                       const TaskParallelTLS *__restrict UNUSED(tls))
@@ -7608,6 +7614,412 @@ static void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
                     "Apply the deformation in the selected axis");
 }
 
+typedef enum eSculptMaskFilterTypes {
+  MASK_FILTER_SMOOTH = 0,
+  MASK_FILTER_SHARPEN = 1,
+  MASK_FILTER_GROW = 2,
+  MASK_FILTER_SHRINK = 3,
+  MASK_FILTER_CONTRAST_INCREASE = 5,
+  MASK_FILTER_CONTRAST_DECREASE = 6,
+} eSculptMaskFilterTypes;
+
+EnumPropertyItem prop_mask_filter_types[] = {
+    {MASK_FILTER_SMOOTH, "SMOOTH", 0, "Smooth Mask", "Smooth mask"},
+    {MASK_FILTER_SHARPEN, "SHARPEN", 0, "Sharpen Mask", "Sharpen mask"},
+    {MASK_FILTER_GROW, "GROW", 0, "Grow Mask", "Grow mask"},
+    {MASK_FILTER_SHRINK, "SHRINK", 0, "Shrink Mask", "Shrink mask"},
+    {MASK_FILTER_CONTRAST_INCREASE,
+     "CONTRAST_INCREASE",
+     0,
+     "Increase contrast",
+     "Increase the contrast of the paint mask"},
+    {MASK_FILTER_CONTRAST_DECREASE,
+     "CONTRAST_DECREASE",
+     0,
+     "Decrease contrast",
+     "Decrease the contrast of the paint mask"},
+    {0, NULL, 0, NULL, NULL},
+};
+
+static void mask_filter_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];
+  bool update = false;
+
+  const int mode = data->filter_type;
+  float contrast = 0.0f;
+
+  PBVHVertexIter vd;
+
+  if (mode == MASK_FILTER_CONTRAST_INCREASE) {
+    contrast = 0.1f;
+  }
+
+  if (mode == MASK_FILTER_CONTRAST_DECREASE) {
+    contrast = -0.1f;
+  }
+
+  BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+  {
+    float val;
+    float delta, gain, offset, max, min;
+    float prev_val = *vd.mask;
+    SculptVertexNeighborIter ni;
+    switch (mode) {
+      case MASK_FILTER_SMOOTH:
+        if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
+          val = neighbor_average_mask(ss, vd.index) - *vd.mask;
+        }
+        else {
+          val = bmesh_neighbor_average_mask(vd.bm_vert, vd.cd_vert_mask_offset) - *vd.mask;
+        }
+        *vd.mask += val;
+        break;
+      case MASK_FILTER_SHA

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list