[Bf-blender-cvs] [bbc69563d07] master: Sculpt: Normal-based automasking modes

Joseph Eagar noreply at git.blender.org
Thu Sep 29 08:22:38 CEST 2022


Commit: bbc69563d0704a8269318d8699e7c2bf4edc91c2
Author: Joseph Eagar
Date:   Wed Sep 28 23:21:56 2022 -0700
Branches: master
https://developer.blender.org/rBbbc69563d0704a8269318d8699e7c2bf4edc91c2

Sculpt: Normal-based automasking modes

Two new normal-based automasking modes.

The first mode, "brush", compares vertex normals with the initial
normal at the beginning of the brush stroke.

The second, "view", compares vertex normals with the view normal.
If "occlusion" is on then rays will be shot from each vertex to test
if it is occluded by other geometry (note: this can be very slow).\
Only geometry inside the sculpt mesh is considered.

Each mode has an associated angular limit and a falloff.

Reviewed by: Julien Kaspar and Jeroen Bakker
Differential Revision: https://developer.blender.org/D15297
Ref D15297

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

M	release/scripts/startup/bl_ui/properties_paint_common.py
M	release/scripts/startup/bl_ui/space_view3d.py
M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/intern/paint.cc
M	source/blender/editors/include/ED_sculpt.h
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_automasking.cc
M	source/blender/editors/sculpt_paint/sculpt_boundary.c
M	source/blender/editors/sculpt_paint/sculpt_brush_types.c
M	source/blender/editors/sculpt_paint/sculpt_cloth.c
M	source/blender/editors/sculpt_paint/sculpt_face_set.cc
M	source/blender/editors/sculpt_paint/sculpt_filter_color.c
M	source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
M	source/blender/editors/sculpt_paint/sculpt_ops.c
M	source/blender/editors/sculpt_paint/sculpt_paint_color.c
M	source/blender/editors/sculpt_paint/sculpt_paint_image.cc
M	source/blender/editors/sculpt_paint/sculpt_pose.c
M	source/blender/editors/sculpt_paint/sculpt_smooth.c
M	source/blender/editors/sculpt_paint/sculpt_transform.c
M	source/blender/editors/transform/transform_convert_sculpt.c
M	source/blender/makesdna/DNA_brush_enums.h
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_brush.c
M	source/blender/makesrna/intern/rna_sculpt_paint.c

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

diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index a4a328fce1a..72a87703bd5 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -945,10 +945,27 @@ def brush_settings_advanced(layout, context, brush, popover=False):
         col.prop(brush, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
         col.prop(brush, "use_automasking_cavity", text="Cavity")
         col.prop(brush, "use_automasking_cavity_inverted", text="Cavity (Inverted)")
+        col.prop(brush, "use_automasking_start_normal", text="Area Normal")
+        col.prop(brush, "use_automasking_view_normal", text="View Normal")
 
         col.separator()
         col.prop(brush, "automasking_boundary_edges_propagation_steps")
 
+        sculpt = context.tool_settings.sculpt
+
+        if brush.use_automasking_start_normal:
+            col.separator()
+
+            col.prop(sculpt, "automasking_start_normal_limit")
+            col.prop(sculpt, "automasking_start_normal_falloff")
+
+        if brush.use_automasking_view_normal:
+            col.separator()
+
+            col.prop(brush, "use_automasking_view_occlusion", text="Occlusion")
+            col.prop(sculpt, "automasking_view_normal_limit")
+            col.prop(sculpt, "automasking_view_normal_falloff")
+
         if brush.use_automasking_cavity or brush.use_automasking_cavity_inverted:
             col.separator()
 
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index fcf00ee80f6..ada2993a16f 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -5497,6 +5497,8 @@ class VIEW3D_MT_sculpt_automasking_pie(Menu):
         pie.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
         pie.prop(sculpt, "use_automasking_cavity", text="Cavity")
         pie.prop(sculpt, "use_automasking_cavity_inverted", text="Cavity (Inverted)")
+        pie.prop(sculpt, "use_automasking_start_normal", text="Area Normal")
+        pie.prop(sculpt, "use_automasking_view_normal", text="View Normal")
 
 
 class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu):
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index d18b75e78af..6946ab54ca7 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -974,6 +974,21 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
         col.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
         col.prop(sculpt, "use_automasking_cavity", text="Cavity")
         col.prop(sculpt, "use_automasking_cavity_inverted", text="Cavity (Inverted)")
+        col.prop(sculpt, "use_automasking_start_normal", text="Area Normal")
+        col.prop(sculpt, "use_automasking_view_normal", text="View Normal")
+        
+        if sculpt.use_automasking_start_normal:
+            col.separator()
+
+            col.prop(sculpt, "automasking_start_normal_limit")
+            col.prop(sculpt, "automasking_start_normal_falloff")
+
+        if sculpt.use_automasking_view_normal:
+            col.separator()
+
+            col.prop(sculpt, "use_automasking_view_occlusion", text="Occlusion")
+            col.prop(sculpt, "automasking_view_normal_limit")
+            col.prop(sculpt, "automasking_view_normal_falloff")
 
         col.separator()
         col.prop(sculpt.brush, "automasking_boundary_edges_propagation_steps")
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 386fecfd278..ed7ef5d5efd 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -474,11 +474,6 @@ typedef struct SculptBoundary {
   } twist;
 } SculptBoundary;
 
-typedef struct CavityMaskData {
-  float factor;
-  int stroke_id;
-} CavityMaskData;
-
 typedef struct SculptFakeNeighbors {
   bool use_fake_neighbors;
 
@@ -554,13 +549,13 @@ typedef struct SculptAttributePointers {
   /* Precomputed auto-mask factor indexed by vertex, owned by the auto-masking system and
    * initialized in #SCULPT_automasking_cache_init when needed. */
   SculptAttribute *automasking_factor;
+  SculptAttribute *automasking_occlusion; /* CD_PROP_INT8. */
+  SculptAttribute *automasking_stroke_id;
+  SculptAttribute *automasking_cavity;
 
   /* BMesh */
   SculptAttribute *dyntopo_node_id_vertex;
   SculptAttribute *dyntopo_node_id_face;
-
-  SculptAttribute *stroke_id;
-  SculptAttribute *cavity;
 } SculptAttributePointers;
 
 typedef struct SculptSession {
@@ -747,14 +742,16 @@ typedef struct SculptSession {
    */
   bool sticky_shading_color;
 
+  uchar stroke_id;
+
   /**
    * Last used painting canvas key.
    */
   char *last_paint_canvas_key;
+  float last_normal[3];
 
-  uchar stroke_id;
   int last_automasking_settings_hash;
-  uchar last_cavity_stroke_id;
+  uchar last_automask_stroke_id;
 } SculptSession;
 
 void BKE_sculptsession_free(struct Object *ob);
diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc
index 08e49550426..e0a27a3d03e 100644
--- a/source/blender/blenkernel/intern/paint.cc
+++ b/source/blender/blenkernel/intern/paint.cc
@@ -2079,6 +2079,14 @@ void BKE_sculpt_toolsettings_data_ensure(Scene *scene)
     sd->constant_detail = 3.0f;
   }
 
+  if (!sd->automasking_start_normal_limit) {
+    sd->automasking_start_normal_limit = 20.0f / 180.0f * M_PI;
+    sd->automasking_start_normal_falloff = 0.25f;
+
+    sd->automasking_view_normal_limit = 90.0f / 180.0f * M_PI;
+    sd->automasking_view_normal_falloff = 0.25f;
+  }
+
   /* Set sane default tiling offsets. */
   if (!sd->paint.tile_offset[0]) {
     sd->paint.tile_offset[0] = 1.0f;
diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h
index 1e220d33ff4..59b2d8d31b9 100644
--- a/source/blender/editors/include/ED_sculpt.h
+++ b/source/blender/editors/include/ED_sculpt.h
@@ -34,7 +34,7 @@ bool ED_sculpt_mask_box_select(struct bContext *C,
 /* sculpt_transform.c */
 
 void ED_sculpt_update_modal_transform(struct bContext *C, struct Object *ob);
-void ED_sculpt_init_transform(struct bContext *C, struct Object *ob, const char *undo_name);
+void ED_sculpt_init_transform(struct bContext *C, struct Object *ob, const int mval[2], const char *undo_name);
 void ED_sculpt_end_transform(struct bContext *C, struct Object *ob);
 
 /* sculpt_undo.c */
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 54810436d20..7fc5df8237a 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1268,11 +1268,11 @@ static bool sculpt_brush_use_topology_rake(const SculptSession *ss, const Brush
 /**
  * Test whether the #StrokeCache.sculpt_normal needs update in #do_brush_action
  */
-static int sculpt_brush_needs_normal(const SculptSession *ss, const Brush *brush)
+static int sculpt_brush_needs_normal(const SculptSession *ss, Sculpt *sd, const Brush *brush)
 {
   return ((SCULPT_TOOL_HAS_NORMAL_WEIGHT(brush->sculpt_tool) &&
            (ss->cache->normal_weight > 0.0f)) ||
-
+          SCULPT_automasking_needs_normal(ss, sd, brush) ||
           ELEM(brush->sculpt_tool,
                SCULPT_TOOL_BLOB,
                SCULPT_TOOL_CREASE,
@@ -2413,7 +2413,8 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
                                    const float fno[3],
                                    float mask,
                                    const PBVHVertRef vertex,
-                                   int thread_id)
+                                   const int thread_id,
+                                   AutomaskingNodeData *automask_data)
 {
   StrokeCache *cache = ss->cache;
   const Scene *scene = cache->vc->scene;
@@ -2497,7 +2498,7 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
   avg *= 1.0f - mask;
 
   /* Auto-masking. */
-  avg *= SCULPT_automasking_factor_get(cache->automasking, ss, vertex);
+  avg *= SCULPT_automasking_factor_get(cache->automasking, ss, vertex, automask_data);
 
   return avg;
 }
@@ -3087,7 +3088,8 @@ static void do_gravity_task_cb_ex(void *__restrict userdata,
                                                     vd.fno,
                                                     vd.mask ? *vd.mask : 0.0f,
                                                     vd.vertex,
-                                                    thread_id);
+                                                    thread_id,
+                                                    NULL);
 
     mul_v3_v3fl(proxy[vd.i], offset, fade);
 
@@ -3396,7 +3398,7 @@ static void do_brush_action(Sculpt *sd,
     BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
   }
 
-  if (sculpt_brush_needs_normal(ss, brush)) {
+  if (sculpt_brush_needs_normal(ss, sd, brush)) {
     update_sculpt_normal(sd, ob, nodes, totnode);
   }
 
@@ -3548,7 +3550,7 @@ static void do_brush_action(Sculpt *sd,
     SCULPT_bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
   }
 
-  if (!SCULPT_tool_can_reuse_cavity_mask(brush->sculpt_tool) ||
+  if (!SCULPT_tool_can_reuse_automask(brush->sculpt_tool) ||
       (ss->cache->supports_gravity && sd->gravity_factor > 0.0f)) {
     /* Clear cavity mask cache. */
     ss->last_automasking_settings_hash = 0;
@@ -4242,8 +4244,6 @@ static void sculpt_update_cache_invariants(
 
   ss->cache = cache;
 
-  cache->stroke_id = ss->stroke_id;
-
   /* Set scaling adjustment. */
   max_scale = 0.0f;
   for (int i = 0; i < 3; i++) {
@@ -5413,6 +5413,7 @@ static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const f
     }
 
     SCULPT_stroke_id_next(ob);
+    ss->cache->stroke_id = ss->stroke_id;
 
     return true;
   }
@@ -6012,6 +6013,70 @@ void SCULPT_fake_neighbors_free(Object *ob)
   sculpt_pose_fake_neighbors_free(ss);
 }
 
+void SCULPT_automasking_node_begin(Object *o

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list