[Bf-blender-cvs] [87cafe92ce2] master: Sculpt/Paint: Brush world spacing option for sculpt mode

Pablo Dobarro noreply at git.blender.org
Tue Aug 27 14:58:41 CEST 2019


Commit: 87cafe92ce2f99d8da620b80e1c26f8078554f93
Author: Pablo Dobarro
Date:   Mon Aug 19 17:03:55 2019 +0200
Branches: master
https://developer.blender.org/rB87cafe92ce2f99d8da620b80e1c26f8078554f93

Sculpt/Paint: Brush world spacing option for sculpt mode

New brush option to calculate the distance to generate a new brush step using the cursor position over the mesh instead of the screen coordinates. This avoids artifacts when sculpting across curved surfaces.

Reviewed By: brecht

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

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

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenloader/intern/versioning_270.c
M	source/blender/editors/sculpt_paint/paint_stroke.c
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesrna/intern/rna_brush.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 9fd35808b4b..a3c8f759f06 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -913,6 +913,8 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
             if brush.sculpt_capabilities.has_space_attenuation:
                 col.prop(brush, "use_space_attenuation")
 
+            col.prop(brush, "use_scene_spacing")
+
             if brush.sculpt_capabilities.has_jitter:
 
                 row = col.row(align=True)
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index b61692799ed..5010cc8071d 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -1748,7 +1748,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
       for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
         br->falloff_angle = DEG2RADF(80);
         br->flag &= ~(BRUSH_FLAG_UNUSED_1 | BRUSH_FLAG_UNUSED_6 | BRUSH_FLAG_UNUSED_7 |
-                      BRUSH_FLAG_UNUSED_17 | BRUSH_FRONTFACE_FALLOFF);
+                      BRUSH_SCENE_SPACING | BRUSH_FRONTFACE_FALLOFF);
       }
 
       for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 694dae49d30..b4b1ae3b0af 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -57,6 +57,7 @@
 #include "IMB_imbuf_types.h"
 
 #include "paint_intern.h"
+#include "sculpt_intern.h"
 
 #include <float.h>
 #include <math.h>
@@ -93,6 +94,8 @@ typedef struct PaintStroke {
   int cur_sample;
 
   float last_mouse_position[2];
+  float last_scene_space_position[3];
+  bool stroke_over_mesh;
   /* space distance covered so far */
   float stroke_distance;
 
@@ -233,6 +236,17 @@ static bool paint_tool_require_location(Brush *brush, ePaintMode mode)
   return true;
 }
 
+static bool paint_stroke_use_scene_spacing(Brush *brush, ePaintMode mode)
+{
+  switch (mode) {
+    case PAINT_MODE_SCULPT:
+      return brush->flag & BRUSH_SCENE_SPACING;
+    default:
+      break;
+  }
+  return false;
+}
+
 static bool paint_tool_require_inbetween_mouse_events(Brush *brush, ePaintMode mode)
 {
   switch (mode) {
@@ -523,6 +537,10 @@ static void paint_brush_stroke_add_step(bContext *C,
   copy_v2_v2(stroke->last_mouse_position, mouse_in);
   stroke->last_pressure = pressure;
 
+  if (paint_stroke_use_scene_spacing(brush, mode)) {
+    sculpt_stroke_get_location(C, stroke->last_scene_space_position, stroke->last_mouse_position);
+  }
+
   if (paint_stroke_use_jitter(mode, brush, stroke->stroke_mode == BRUSH_STROKE_INVERT)) {
     float delta[2];
     float factor = stroke->zoom_2d;
@@ -600,14 +618,32 @@ static bool paint_smooth_stroke(PaintStroke *stroke,
   return true;
 }
 
-static float paint_space_stroke_spacing(const Scene *scene,
+static float paint_space_stroke_spacing(bContext *C,
+                                        const Scene *scene,
                                         PaintStroke *stroke,
                                         float size_pressure,
                                         float spacing_pressure)
 {
-  /* brushes can have a minimum size of 1.0 but with pressure it can be smaller then a pixel
-   * causing very high step sizes, hanging blender [#32381] */
-  const float size_clamp = max_ff(1.0f, BKE_brush_size_get(scene, stroke->brush) * size_pressure);
+  Paint *paint = BKE_paint_get_active_from_context(C);
+  ePaintMode mode = BKE_paintmode_get_active_from_context(C);
+  Brush *brush = BKE_paint_brush(paint);
+  float size_clamp = 0.0f;
+  float size = BKE_brush_size_get(scene, stroke->brush) * size_pressure;
+  if (paint_stroke_use_scene_spacing(brush, mode)) {
+    if (!BKE_brush_use_locked_size(scene, brush)) {
+      size_clamp = paint_calc_object_space_radius(
+          &stroke->vc, stroke->last_scene_space_position, size);
+    }
+    else {
+      size_clamp = BKE_brush_unprojected_radius_get(scene, brush) * size_pressure;
+    }
+  }
+  else {
+    /* brushes can have a minimum size of 1.0 but with pressure it can be smaller then a pixel
+     * causing very high step sizes, hanging blender [#32381] */
+    size_clamp = max_ff(1.0f, size);
+  }
+
   float spacing = stroke->brush->spacing;
 
   /* apply spacing pressure */
@@ -619,7 +655,12 @@ static float paint_space_stroke_spacing(const Scene *scene,
    * the fact that brush can be scaled there. */
   spacing *= stroke->zoom_2d;
 
-  return max_ff(1.0, size_clamp * spacing / 50.0f);
+  if (paint_stroke_use_scene_spacing(brush, mode)) {
+    return size_clamp * spacing / 50.0f;
+  }
+  else {
+    return max_ff(1.0, size_clamp * spacing / 50.0f);
+  }
 }
 
 static float paint_stroke_overlapped_curve(Brush *br, float x, float spacing)
@@ -677,14 +718,18 @@ static float paint_stroke_integrate_overlap(Brush *br, float factor)
   }
 }
 
-static float paint_space_stroke_spacing_variable(
-    const Scene *scene, PaintStroke *stroke, float pressure, float dpressure, float length)
+static float paint_space_stroke_spacing_variable(bContext *C,
+                                                 const Scene *scene,
+                                                 PaintStroke *stroke,
+                                                 float pressure,
+                                                 float dpressure,
+                                                 float length)
 {
   if (BKE_brush_use_size_pressure(scene, stroke->brush)) {
     /* use pressure to modify size. set spacing so that at 100%, the circles
      * are aligned nicely with no overlap. for this the spacing needs to be
      * the average of the previous and next size. */
-    float s = paint_space_stroke_spacing(scene, stroke, 1.0f, pressure);
+    float s = paint_space_stroke_spacing(C, scene, stroke, 1.0f, pressure);
     float q = s * dpressure / (2.0f * length);
     float pressure_fac = (1.0f + q) / (1.0f - q);
 
@@ -692,14 +737,15 @@ static float paint_space_stroke_spacing_variable(
     float new_size_pressure = stroke->last_pressure * pressure_fac;
 
     /* average spacing */
-    float last_spacing = paint_space_stroke_spacing(scene, stroke, last_size_pressure, pressure);
-    float new_spacing = paint_space_stroke_spacing(scene, stroke, new_size_pressure, pressure);
+    float last_spacing = paint_space_stroke_spacing(
+        C, scene, stroke, last_size_pressure, pressure);
+    float new_spacing = paint_space_stroke_spacing(C, scene, stroke, new_size_pressure, pressure);
 
     return 0.5f * (last_spacing + new_spacing);
   }
   else {
     /* no size pressure */
-    return paint_space_stroke_spacing(scene, stroke, 1.0f, pressure);
+    return paint_space_stroke_spacing(C, scene, stroke, 1.0f, pressure);
   }
 }
 
@@ -711,29 +757,57 @@ static int paint_space_stroke(bContext *C,
                               float final_pressure)
 {
   const Scene *scene = CTX_data_scene(C);
+  ARegion *ar = CTX_wm_region(C);
   PaintStroke *stroke = op->customdata;
   UnifiedPaintSettings *ups = stroke->ups;
+  Paint *paint = BKE_paint_get_active_from_context(C);
+  ePaintMode mode = BKE_paintmode_get_active_from_context(C);
+  Brush *brush = BKE_paint_brush(paint);
   int cnt = 0;
 
   float pressure, dpressure;
   float mouse[2], dmouse[2];
+  float scene_space_position[3], d_scene_space_position[3], final_scene_space_position[3];
   float length;
-  float no_pressure_spacing = paint_space_stroke_spacing(scene, stroke, 1.0f, 1.0f);
-
-  sub_v2_v2v2(dmouse, final_mouse, stroke->last_mouse_position);
-
+  float no_pressure_spacing = paint_space_stroke_spacing(C, scene, stroke, 1.0f, 1.0f);
   pressure = stroke->last_pressure;
   dpressure = final_pressure - stroke->last_pressure;
-
+  sub_v2_v2v2(dmouse, final_mouse, stroke->last_mouse_position);
   length = normalize_v2(dmouse);
 
+  if (paint_stroke_use_scene_spacing(brush, mode)) {
+    bool hit = sculpt_stroke_get_location(C, scene_space_position, final_mouse);
+    if (hit && stroke->stroke_over_mesh) {
+      sub_v3_v3v3(d_scene_space_position, scene_space_position, stroke->last_scene_space_position);
+      length = len_v3(d_scene_space_position);
+      stroke->stroke_over_mesh = true;
+    }
+    else {
+      length = 0.0f;
+      stroke->stroke_over_mesh = hit;
+      if (stroke->stroke_over_mesh) {
+        copy_v3_v3(stroke->last_scene_space_position, scene_space_position);
+      }
+    }
+  }
+
   while (length > 0.0f) {
     float spacing = paint_space_stroke_spacing_variable(
-        scene, stroke, pressure, dpressure, length);
+        C, scene, stroke, pressure, dpressure, length);
 
     if (length >= spacing) {
-      mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing;
-      mouse[1] = stroke->last_mouse_position[1] + dmouse[1] * spacing;
+      if (paint_stroke_use_scene_spacing(brush, mode)) {
+        normalize_v3(d_scene_space_position);
+        mul_v3_v3fl(final_scene_space_position, d_scene_space_position, spacing);
+        add_v3_v3v3(final_scene_space_position,
+                    stroke->last_scene_space_position,
+                    final_scene_space_position);
+        ED_view3d_project(ar, final_scene_space_position, mouse);
+      }
+      else {
+        mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing;
+        mouse[1] = stroke->last_mouse_position[1] + dmouse[1] * spacing;
+      }
       pressure = stroke->last_pressure + (spacing / length) * dpressure;
 
       ups->overlap_factor = paint_stroke_integrate_overlap(stroke->brush,
@@ -1079,7 +1153,7 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str
   if (br->flag & BRUSH_CURVE) {
     UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
     const Scene *scene = CTX_data_scene(C);
-    const float spacing = paint_space_stroke_spacing(scene, stroke, 1.0f, 1.0f);
+    const float 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list