Sculpt/Paint: Dash Ratio and Dash Samples
authorPablo Dobarro <pablodp606@gmail.com>
Mon, 18 Nov 2019 21:47:23 +0000 (22:47 +0100)
committerPablo Dobarro <pablodp606@gmail.com>
Thu, 21 Nov 2019 16:55:36 +0000 (17:55 +0100)
Dash Ratio and Dash Samples are brush properties to modify the strength of the brush during a stroke. This is useful to create dashed lines in texture paint or stitches in sculpt mode.

Reviewed By: jbakker

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

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

index d99c7ae65b0f62f4ec75313670373a982f44467e..efd26c2daf86497fad8ca14e2314f9a3ee3e2a8b 100644 (file)
@@ -972,10 +972,14 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
             row = col.row(align=True)
             row.prop(brush, "spacing", text="Spacing")
             row.prop(brush, "use_pressure_spacing", toggle=True, text="")
+            col.prop(brush, "dash_ratio")
+            col.prop(brush, "dash_samples")
 
         if brush.use_line or brush.use_curve:
             row = col.row(align=True)
             row.prop(brush, "spacing", text="Spacing")
+            col.prop(brush, "dash_ratio")
+            col.prop(brush, "dash_samples")
 
         if brush.use_curve:
             col.template_ID(brush, "paint_curve", new="paintcurve.new")
index 761424a587950b999924916d7905883a1259746a..488cf6b02133fede80625f62353afbc31d5f181d 100644 (file)
@@ -3964,5 +3964,13 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
         }
       }
     }
+
+    /* Dash Ratio and Dash Samples */
+    if (!DNA_struct_elem_find(fd->filesdna, "Brush", "float", "dash_ratio")) {
+      for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
+        br->dash_ratio = 1.0f;
+        br->dash_samples = 20;
+      }
+    }
   }
 }
index 3641804555169ecdbf77c466c2ad8323cd8600f4..ee359def68c6aa57ba5352ba6d462be2fc2d0666 100644 (file)
@@ -91,6 +91,7 @@ typedef struct PaintStroke {
   PaintSample samples[PAINT_MAX_INPUT_SAMPLES];
   int num_samples;
   int cur_sample;
+  int tot_samples;
 
   float last_mouse_position[2];
   float last_world_space_position[3];
@@ -482,6 +483,12 @@ static bool paint_brush_update(bContext *C,
   return location_success && (is_dry_run == false);
 }
 
+static bool paint_stroke_use_dash(Brush *brush)
+{
+  /* Only these stroke modes support dash lines */
+  return brush->flag & BRUSH_SPACE || brush->flag & BRUSH_LINE || brush->flag & BRUSH_CURVE;
+}
+
 static bool paint_stroke_use_jitter(ePaintMode mode, Brush *brush, bool invert)
 {
   bool use_jitter = (brush->flag & BRUSH_ABSOLUTE_JITTER) ? (brush->jitter_absolute != 0) :
@@ -582,19 +589,33 @@ static void paint_brush_stroke_add_step(bContext *C,
     return;
   }
 
+  /* Dash */
+  bool add_step = true;
+  if (paint_stroke_use_dash(brush)) {
+    int dash_samples = stroke->tot_samples % brush->dash_samples;
+    float dash = (float)dash_samples / (float)brush->dash_samples;
+    if (dash > brush->dash_ratio) {
+      add_step = false;
+    }
+  }
+
   /* Add to stroke */
-  RNA_collection_add(op->ptr, "stroke", &itemptr);
-  RNA_float_set(&itemptr, "size", ups->pixel_radius);
-  RNA_float_set_array(&itemptr, "location", location);
-  RNA_float_set_array(&itemptr, "mouse", mouse_out);
-  RNA_boolean_set(&itemptr, "pen_flip", stroke->pen_flip);
-  RNA_float_set(&itemptr, "pressure", pressure);
-
-  stroke->update_step(C, stroke, &itemptr);
-
-  /* don't record this for now, it takes up a lot of memory when doing long
-   * strokes with small brush size, and operators have register disabled */
-  RNA_collection_clear(op->ptr, "stroke");
+  if (add_step) {
+    RNA_collection_add(op->ptr, "stroke", &itemptr);
+    RNA_float_set(&itemptr, "size", ups->pixel_radius);
+    RNA_float_set_array(&itemptr, "location", location);
+    RNA_float_set_array(&itemptr, "mouse", mouse_out);
+    RNA_boolean_set(&itemptr, "pen_flip", stroke->pen_flip);
+    RNA_float_set(&itemptr, "pressure", pressure);
+
+    stroke->update_step(C, stroke, &itemptr);
+
+    /* don't record this for now, it takes up a lot of memory when doing long
+     * strokes with small brush size, and operators have register disabled */
+    RNA_collection_clear(op->ptr, "stroke");
+  }
+
+  stroke->tot_samples++;
 }
 
 /* Returns zero if no sculpt changes should be made, non-zero otherwise */
index b2d4124a348cfcc0fc0d870b0ac8eb9a430b0ef8..ff1f8c9a1c02f11922f9d7cbc4c5474bcf77306e 100644 (file)
     .rate = 0.1f, \
  \
     .jitter = 0.0f, \
+ \
+    /* Dash */ \
+    .dash_ratio = 1.0f, \
+    .dash_samples = 20, \
  \
     .texture_sample_bias = 0, /* value to added to texture samples */ \
     .texture_overlay_alpha = 33, \
index 63fbf576bba7d65318c9136a6b2e9e07ae565039..67bca60e7e1e137ea953b3564297a7b53d96a34f 100644 (file)
@@ -272,6 +272,10 @@ typedef struct Brush {
   /** Background color. */
   float secondary_rgb[3];
 
+  /** Rate */
+  float dash_ratio;
+  int dash_samples;
+
   /** The direction of movement for sculpt vertices. */
   int sculpt_plane;
 
index a392e4c080fa7d687a0117f8484756fd36dfeba3..3f269299461c988450ae0bae56e956093dd676ad 100644 (file)
@@ -1788,6 +1788,22 @@ static void rna_def_brush(BlenderRNA *brna)
       prop, "Strength", "How powerful the effect of the brush is when applied");
   RNA_def_property_update(prop, 0, "rna_Brush_update");
 
+  prop = RNA_def_property(srna, "dash_ratio", PROP_FLOAT, PROP_FACTOR);
+  RNA_def_property_float_sdna(prop, NULL, "dash_ratio");
+  RNA_def_property_range(prop, 0.0f, 1.0f);
+  RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.001, 3);
+  RNA_def_property_ui_text(
+      prop, "Dash Ratio", "Ratio of samples in a cycle that the brush is enabled");
+  RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+  prop = RNA_def_property(srna, "dash_samples", PROP_INT, PROP_UNSIGNED);
+  RNA_def_property_int_sdna(prop, NULL, "dash_samples");
+  RNA_def_property_range(prop, 1, 10000);
+  RNA_def_property_ui_range(prop, 1, 10000, 5, -1);
+  RNA_def_property_ui_text(
+      prop, "Dash Length", "Length of a dash cycle measured in stroke samples");
+  RNA_def_property_update(prop, 0, "rna_Brush_update");
+
   prop = RNA_def_property(srna, "plane_offset", PROP_FLOAT, PROP_DISTANCE);
   RNA_def_property_float_sdna(prop, NULL, "plane_offset");
   RNA_def_property_float_default(prop, 0);