[Bf-blender-cvs] [9f6d0c3dc6c] temp-gpencil-fill: GPencil: Fill optimizations

Antonio Vazquez noreply at git.blender.org
Fri Feb 5 17:17:42 CET 2021


Commit: 9f6d0c3dc6c5a5dc17dacb5cc75ccfe6f5a03734
Author: Antonio Vazquez
Date:   Fri Feb 5 16:40:21 2021 +0100
Branches: temp-gpencil-fill
https://developer.blender.org/rB9f6d0c3dc6c5a5dc17dacb5cc75ccfe6f5a03734

GPencil: Fill optimizations

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

M	source/blender/editors/gpencil/gpencil_fill.c
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesdna/DNA_gpencil_types.h
M	source/blender/makesrna/intern/rna_brush.c

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

diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 1e7fcf5f095..8680834ab5d 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -580,9 +580,9 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
       tgpw.gpf = gpf;
       tgpw.t_gpf = gpf;
 
-      /* reduce thickness to avoid gaps */
       tgpw.is_fill_stroke = (tgpf->fill_draw_mode == GP_FILL_DMODE_CONTROL) ? false : true;
-      tgpw.lthick = gpl->line_change;
+      /* Reduce thickness to avoid gaps. */
+      tgpw.lthick = gpl->line_change - (20 * tgpf->fill_factor);
       tgpw.opacity = 1.0;
       copy_v4_v4(tgpw.tintcolor, ink);
       tgpw.onion = true;
@@ -751,17 +751,10 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
 /* return pixel data (rgba) at index */
 static void get_pixel(const ImBuf *ibuf, const int idx, float r_col[4])
 {
-  if (ibuf->rect_float) {
-    const float *frgba = &ibuf->rect_float[idx * 4];
-    copy_v4_v4(r_col, frgba);
-  }
-  else {
-    /* XXX: This case probably doesn't happen, as we only write to the float buffer,
-     * but we get compiler warnings about uninitialized vars otherwise
-     */
-    BLI_assert(!"gpencil_fill.c - get_pixel() non-float case is used!");
-    zero_v4(r_col);
-  }
+  BLI_assert(ibuf->rect_float != NULL);
+
+  const float *frgba = &ibuf->rect_float[idx * 4];
+  copy_v4_v4(r_col, frgba);
 }
 
 /* set pixel data (rgba) at index */
@@ -782,6 +775,13 @@ static void set_pixel(ImBuf *ibuf, int idx, const float col[4])
   }
 }
 
+/* Helper: Check if one image row is empty. */
+static bool is_row_filled(const ImBuf *ibuf, const int row_index)
+{
+  float *row = &ibuf->rect_float[ibuf->x * 4 * row_index];
+  return (row[0] == 0.0f && memcmp(row, row + 1, ((ibuf->x * 4) - 1) * sizeof(float)) != 0);
+}
+
 /**
  * Check if the size of the leak is narrow to determine if the stroke is closed
  * this is used for strokes with small gaps between them to get a full fill
@@ -1113,30 +1113,34 @@ static void gpencil_erase_processed_area(tGPDfill *tgpf)
  *   XXXX
  * -----------
  */
-static void dilate_shape(ImBuf *ibuf, int factor)
+static bool dilate_shape(ImBuf *ibuf)
 {
-  if (factor == 0) {
-    return;
-  }
+  bool done = false;
 
   BLI_Stack *stack = BLI_stack_new(sizeof(int), __func__);
   const float green[4] = {0.0f, 1.0f, 0.0f, 1.0f};
-  const int maxpixel = (ibuf->x * ibuf->y) - 1;
+  // const int maxpixel = (ibuf->x * ibuf->y) - 1;
   /* detect pixels and expand into red areas */
-  for (int v = maxpixel; v != 0; v--) {
-    float color[4];
-    int index;
-    get_pixel(ibuf, v, color);
-    if (color[1] == 1.0f) {
-      for (int i = 1; i < factor + 1; i++) {
+  for (int row = 0; row < ibuf->y; row++) {
+    if (!is_row_filled(ibuf, row)) {
+      continue;
+    }
+    int maxpixel = (ibuf->x * (row + 1)) - 1;
+    int minpixel = ibuf->x * row;
+
+    for (int v = maxpixel; v != minpixel; v--) {
+      float color[4];
+      int index;
+      get_pixel(ibuf, v, color);
+      if (color[1] == 1.0f) {
         int tp = 0;
         int bm = 0;
         int lt = 0;
         int rt = 0;
 
         /* pixel left */
-        if (v - i >= 0) {
-          index = v - i;
+        if (v - 1 >= 0) {
+          index = v - 1;
           get_pixel(ibuf, index, color);
           if (color[0] == 1.0f) {
             BLI_stack_push(stack, &index);
@@ -1144,8 +1148,8 @@ static void dilate_shape(ImBuf *ibuf, int factor)
           }
         }
         /* pixel right */
-        if (v + i <= maxpixel) {
-          index = v + i;
+        if (v + 1 <= maxpixel) {
+          index = v + 1;
           get_pixel(ibuf, index, color);
           if (color[0] == 1.0f) {
             BLI_stack_push(stack, &index);
@@ -1153,8 +1157,8 @@ static void dilate_shape(ImBuf *ibuf, int factor)
           }
         }
         /* pixel top */
-        if (v + (ibuf->x * i) <= maxpixel) {
-          index = v + (ibuf->x * i);
+        if (v + (ibuf->x * 1) <= maxpixel) {
+          index = v + (ibuf->x * 1);
           get_pixel(ibuf, index, color);
           if (color[0] == 1.0f) {
             BLI_stack_push(stack, &index);
@@ -1162,8 +1166,8 @@ static void dilate_shape(ImBuf *ibuf, int factor)
           }
         }
         /* pixel bottom */
-        if (v - (ibuf->x * i) >= 0) {
-          index = v - (ibuf->x * i);
+        if (v - (ibuf->x * 1) >= 0) {
+          index = v - (ibuf->x * 1);
           get_pixel(ibuf, index, color);
           if (color[0] == 1.0f) {
             BLI_stack_push(stack, &index);
@@ -1172,7 +1176,7 @@ static void dilate_shape(ImBuf *ibuf, int factor)
         }
         /* pixel top-left */
         if (tp && lt) {
-          index = tp - i;
+          index = tp - 1;
           get_pixel(ibuf, index, color);
           if (color[0] == 1.0f) {
             BLI_stack_push(stack, &index);
@@ -1180,7 +1184,7 @@ static void dilate_shape(ImBuf *ibuf, int factor)
         }
         /* pixel top-right */
         if (tp && rt) {
-          index = tp + i;
+          index = tp + 1;
           get_pixel(ibuf, index, color);
           if (color[0] == 1.0f) {
             BLI_stack_push(stack, &index);
@@ -1188,7 +1192,7 @@ static void dilate_shape(ImBuf *ibuf, int factor)
         }
         /* pixel bottom-left */
         if (bm && lt) {
-          index = bm - i;
+          index = bm - 1;
           get_pixel(ibuf, index, color);
           if (color[0] == 1.0f) {
             BLI_stack_push(stack, &index);
@@ -1196,7 +1200,7 @@ static void dilate_shape(ImBuf *ibuf, int factor)
         }
         /* pixel bottom-right */
         if (bm && rt) {
-          index = bm + i;
+          index = bm + 1;
           get_pixel(ibuf, index, color);
           if (color[0] == 1.0f) {
             BLI_stack_push(stack, &index);
@@ -1205,14 +1209,16 @@ static void dilate_shape(ImBuf *ibuf, int factor)
       }
     }
   }
-
   /* set dilated pixels */
   while (!BLI_stack_is_empty(stack)) {
     int v;
     BLI_stack_pop(stack, &v);
     set_pixel(ibuf, v, green);
+    done = true;
   }
   BLI_stack_free(stack);
+
+  return done;
 }
 
 /* Get the outline points of a shape using Moore Neighborhood algorithm
@@ -1255,10 +1261,13 @@ static void gpencil_get_outline_points(tGPDfill *tgpf, const bool dilate)
   /* Dilate. */
   if (dilate) {
     int dilate_fac = (tgpf->fill_factor <= 1.0) ? 0 : (int)ceilf(tgpf->fill_factor);
-    dilate_shape(ibuf, (dilate_fac * dilate_fac) * 2);
+    for (int i = 0; i < dilate_fac; i++) {
+      if (!dilate_shape(ibuf)) {
+        break;
+      }
+    };
   }
 
-  /* find the initial point to start outline analysis */
   for (int idx = imagesize - 1; idx != 0; idx--) {
     get_pixel(ibuf, idx, rgba);
     if (rgba[1] == 1.0f) {
@@ -1673,7 +1682,7 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
   tgpf->fill_draw_mode = brush->gpencil_settings->fill_draw_mode;
   tgpf->fill_extend_fac = brush->gpencil_settings->fill_extend_fac;
   tgpf->fill_factor = max_ff(GPENCIL_MIN_FILL_FAC,
-                             min_ff(brush->gpencil_settings->fill_factor, 8.0f));
+                             min_ff(brush->gpencil_settings->fill_factor, GPENCIL_MAX_FILL_FAC));
   tgpf->fill_leak = (int)ceil((float)brush->gpencil_settings->fill_leak * tgpf->fill_factor);
 
   int totcol = tgpf->ob->totcol;
@@ -2100,8 +2109,9 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
                   }
                   else {
                     tgpf->zoom = 1.0f;
-                    tgpf->fill_factor = max_ff(GPENCIL_MIN_FILL_FAC,
-                                               min_ff(brush->gpencil_settings->fill_factor, 8.0f));
+                    tgpf->fill_factor = max_ff(
+                        GPENCIL_MIN_FILL_FAC,
+                        min_ff(brush->gpencil_settings->fill_factor, GPENCIL_MAX_FILL_FAC));
                   }
                 }
                 loop_limit++;
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 5e359e4cd22..1d68c0dad11 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -47,8 +47,6 @@ typedef struct BrushClone {
   char _pad[4];
 } BrushClone;
 
-#define GPENCIL_MIN_FILL_FAC 0.05f
-
 typedef struct BrushGpencilSettings {
   /** Amount of smoothing to apply to newly created strokes. */
   float draw_smoothfac;
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 9a9f449f9b3..e02757c1249 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -45,6 +45,9 @@ struct MDeformVert;
 #define GP_DEFAULT_CURVE_ERROR 0.1f
 #define GP_DEFAULT_CURVE_EDIT_CORNER_ANGLE M_PI_2
 
+#define GPENCIL_MIN_FILL_FAC 0.05f
+#define GPENCIL_MAX_FILL_FAC 5.0f
+
 /* ***************************************** */
 /* GP Stroke Points */
 
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index bd3fe16a437..e86ff9072ec 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -1466,7 +1466,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
   /* fill factor size */
   prop = RNA_def_property(srna, "fill_factor", PROP_FLOAT, PROP_NONE);
   RNA_def_property_float_sdna(prop, NULL, "fill_factor");
-  RNA_def_property_range(prop, GPENCIL_MIN_FILL_FAC, 8.0f);
+  RNA_def_property_range(prop, GPENCIL_MIN_FILL_FAC, GPENCIL_MAX_FILL_FAC);
   RNA_def_property_ui_text(
       prop,
       "Precision",



More information about the Bf-blender-cvs mailing list