Commit: 4ada2909566c6966607d3a4d78964902ad9e19a6
Author: Antonio Vazquez
Date:   Mon Aug 10 16:34:19 2020 +0200
Branches: master
https://developer.blender.org/rB4ada2909566c6966607d3a4d78964902ad9e19a6

GPencil: Invert Filled area pressing Ctrl key

This feature was suggested in 
https://blender.community/c/rightclickselect/rggbbc/

When press `Ctrl+LMB`, the filled area is inverted.

{F8749306}

{F8749307}

Filling several areas:

{F8759399}

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

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

M       release/scripts/presets/keyconfig/keymap_data/blender_default.py
M       
release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
M       release/scripts/startup/bl_ui/properties_paint_common.py
M       source/blender/editors/gpencil/gpencil_fill.c
M       source/blender/editors/gpencil/gpencil_paint.c
M       source/blender/makesdna/DNA_brush_types.h
M       source/blender/makesrna/intern/rna_brush.c

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

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py 
b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index efa4b9b00a0..b945a92020f 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -3364,16 +3364,14 @@ def km_grease_pencil_stroke_paint_fill(params):
         # Fill
         ("gpencil.fill", {"type": 'LEFTMOUSE', "value": 'PRESS'},
          {"properties": [("on_back", False)]}),
-        ("gpencil.fill", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": 
True},
-         {"properties": [("on_back", True)]}),
+        ("gpencil.fill", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
+         {"properties": [("on_back", False)]}),
         # If press alternate key, the brush now it's for drawing areas
-        ("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
-         {"properties": [("mode", 'DRAW'), ("wait_for_input", False), 
("disable_straight", True)]}),
+        ("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": 
True},
+         {"properties": [("mode", 'DRAW'), ("wait_for_input", False), 
("disable_straight", True), ("disable_stabilizer", True)]}),
         # If press alternative key, the brush now it's for drawing lines
-        ("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
-         {"properties": [("mode", 'DRAW'), ("wait_for_input", False), 
("disable_straight", True), ("disable_fill", True)]}),
-        # Lasso select
-        ("gpencil.select_lasso", {"type": params.action_tweak, "value": 'ANY', 
"ctrl": True, "alt": True}, None),
+        ("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True, 
"shift": True},
+         {"properties": [("mode", 'DRAW'), ("wait_for_input", False), 
("disable_straight", True), ("disable_stabilizer", True), ("disable_fill", 
True)]}),
     ])
 
     return keymap
diff --git 
a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py 
b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
index eedf07935c8..04721a1704a 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -2465,16 +2465,14 @@ def km_grease_pencil_stroke_paint_fill(params):
         # Fill
         ("gpencil.fill", {"type": 'LEFTMOUSE', "value": 'PRESS'},
          {"properties": [("on_back", False)]}),
-        ("gpencil.fill", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": 
True},
-         {"properties": [("on_back", True)]}),
+        ("gpencil.fill", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
+         {"properties": [("on_back", False)]}),
         # If press alternate key, the brush now it's for drawing areas
-        ("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
-         {"properties": [("mode", 'DRAW'), ("wait_for_input", False), 
("disable_straight", True)]}),
+        ("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": 
True},
+         {"properties": [("mode", 'DRAW'), ("wait_for_input", False), 
("disable_straight", True), ("disable_stabilizer", True)]}),
         # If press alternative key, the brush now it's for drawing lines
         ("gpencil.draw", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True, 
"shift": True},
-         {"properties": [("mode", 'DRAW'), ("wait_for_input", False), 
("disable_straight", True), ("disable_fill", True)]}),
-        # Lasso select
-        ("gpencil.select_lasso", {"type": params.action_tweak, "value": 'ANY', 
"ctrl": True, "alt": True}, None),
+         {"properties": [("mode", 'DRAW'), ("wait_for_input", False), 
("disable_straight", True), ("disable_stabilizer", True), ("disable_fill", 
True)]}),
     ])
 
     return keymap
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py 
b/release/scripts/startup/bl_ui/properties_paint_common.py
index 01f9eedd96e..12f02acedc2 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -1137,6 +1137,8 @@ def brush_basic_gpencil_paint_settings(layout, context, 
brush, *, compact=False)
 
     # FIXME: tools must use their own UI drawing!
     elif brush.gpencil_tool == 'FILL':
+        row = layout.row(align=True)
+        row.prop(gp_settings, "fill_direction", text="", expand=True)
         row = layout.row(align=True)
         row.prop(gp_settings, "fill_leak", text="Leak Size")
         row = layout.row(align=True)
diff --git a/source/blender/editors/gpencil/gpencil_fill.c 
b/source/blender/editors/gpencil/gpencil_fill.c
index a70bbfc9d48..2855f2cc0d7 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -750,6 +750,92 @@ static void gpencil_set_borders(tGPDfill *tgpf, const bool 
transparent)
   tgpf->ima->id.tag |= LIB_TAG_DOIT;
 }
 
+/* Invert image to paint invese area. */
+static void gpencil_invert_image(tGPDfill *tgpf)
+{
+  ImBuf *ibuf;
+  void *lock;
+  const float fill_col[3][4] = {
+      {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 
0.0f}};
+  ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
+
+  const int maxpixel = (ibuf->x * ibuf->y) - 1;
+
+  for (int v = maxpixel; v != 0; v--) {
+    float color[4];
+    get_pixel(ibuf, v, color);
+    /* Green. */
+    if (color[1] == 1.0f) {
+      set_pixel(ibuf, v, fill_col[0]);
+    }
+    else if (color[0] == 1.0f) {
+      set_pixel(ibuf, v, fill_col[1]);
+    }
+    else {
+      set_pixel(ibuf, v, fill_col[2]);
+    }
+  }
+
+  /* release ibuf */
+  if (ibuf) {
+    BKE_image_release_ibuf(tgpf->ima, ibuf, lock);
+  }
+
+  tgpf->ima->id.tag |= LIB_TAG_DOIT;
+}
+
+/* Mark and clear processed areas. */
+static void gpencil_erase_processed_area(tGPDfill *tgpf)
+{
+  ImBuf *ibuf;
+  void *lock;
+  const float blue_col[4] = {0.0f, 0.0f, 1.0f, 1.0f};
+  const float clear_col[4] = {1.0f, 0.0f, 0.0f, 1.0f};
+  tGPspoint *point2D;
+
+  if (tgpf->sbuffer_used == 0) {
+    return;
+  }
+
+  ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
+  point2D = (tGPspoint *)tgpf->sbuffer;
+
+  /* First set in blue the perimeter. */
+  for (int i = 0; i < tgpf->sbuffer_used && point2D; i++, point2D++) {
+    int image_idx = ibuf->x * (int)point2D->y + (int)point2D->x;
+    set_pixel(ibuf, image_idx, blue_col);
+  }
+
+  /* Second, clean by lines any pixel between blue pixels. */
+  float rgba[4];
+
+  for (int idy = 0; idy < ibuf->y; idy++) {
+    bool clear = false;
+    for (int idx = 0; idx < ibuf->x; idx++) {
+      int image_idx = ibuf->x * idy + idx;
+      get_pixel(ibuf, image_idx, rgba);
+      /* Blue. */
+      if (rgba[2] == 1.0f) {
+        clear = true;
+      }
+      /* Red. */
+      else if (rgba[0] == 1.0f) {
+        clear = false;
+      }
+      if (clear) {
+        set_pixel(ibuf, image_idx, clear_col);
+      }
+    }
+  }
+
+  /* release ibuf */
+  if (ibuf) {
+    BKE_image_release_ibuf(tgpf->ima, ibuf, lock);
+  }
+
+  tgpf->ima->id.tag |= LIB_TAG_DOIT;
+}
+
 /* Naive dilate
  *
  * Expand green areas into enclosing red areas.
@@ -761,7 +847,7 @@ static void gpencil_set_borders(tGPDfill *tgpf, const bool 
transparent)
  *   XXXX
  * -----------
  */
-static void dilate(ImBuf *ibuf)
+static void dilate_shape(ImBuf *ibuf)
 {
   BLI_Stack *stack = BLI_stack_new(sizeof(int), __func__);
   const float green[4] = {0.0f, 1.0f, 0.0f, 1.0f};
@@ -860,7 +946,7 @@ static void dilate(ImBuf *ibuf)
  * This is a Blender customized version of the general algorithm described
  * in https://en.wikipedia.org/wiki/Moore_neighborhood
  */
-static void gpencil_get_outline_points(tGPDfill *tgpf)
+static void gpencil_get_outline_points(tGPDfill *tgpf, const bool dilate)
 {
   ImBuf *ibuf;
   float rgba[4];
@@ -892,8 +978,10 @@ static void gpencil_get_outline_points(tGPDfill *tgpf)
   ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
   int imagesize = ibuf->x * ibuf->y;
 
-  /* dilate */
-  dilate(ibuf);
+  /* Dilate. */
+  if (dilate) {
+    dilate_shape(ibuf);
+  }
 
   /* find the initial point to start outline analysis */
   for (int idx = imagesize - 1; idx != 0; idx--) {
@@ -1027,12 +1115,12 @@ static void gpencil_get_depth_array(tGPDfill *tgpf)
 }
 
 /* create array of points using stack as source */
-static void gpencil_points_from_stack(tGPDfill *tgpf)
+static int gpencil_points_from_stack(tGPDfill *tgpf)
 {
   tGPspoint *point2D;
   int totpoints = BLI_stack_count(tgpf->stack);
   if (totpoints == 0) {
-    return;
+    return 0;
   }
 
   tgpf->sbuffer_used = (short)totpoints;
@@ -1050,6 +1138,8 @@ static void gpencil_points_from_stack(tGPDfill *tgpf)
     point2D->time = 0.0f;
     point2D++;
   }
+
+  return totpoints;
 }
 
 /* create a grease pencil stroke using points in buffer */
@@ -1461,6 +1551,10 @@ static int gpencil_fill_modal(bContext *C, wmOperator 
*op, const wmEvent *event)
 {
   tGPDfill *tgpf = op->customdata;
   Scene *scene = tgpf->scene;
+  Brush *brush = tgpf->brush;
+  BrushGpencilSettings *brush_settings = brush->gpencil_settings;
+  const bool is_brush_inv = brush_settings->fill_direction == BRUSH_DIR_IN;
+  const bool is_inverted = (is_brush_inv && !event->ctrl) || (!is_brush_inv && 
event->ctrl);
 
   int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through */
 
@@ -1489,6 +1583,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator 
*op, const wmEvent *event)
             tgpf->active_cfra = CFRA;
 
             /* render screen to temp image */
+            int totpoints = 1;
             if (gpencil_render_offscreen(tgpf)) {
 
               /* Set red borders to create a external limit. */
@@ -1497,30 +1592,45 @@ static int gpencil_fill_modal(bContext *C, wmOperator 
*op, const wmEvent *event)
               /* apply boundary fill */
               gpencil_boundaryfill_area(tgpf);
 
+              /* Invert direction if press Ctrl. */
+              if (is_inverted) {
+                gpencil_invert_image(tgpf);
+              }
+
               /* Clean borders to avoid infinite loops. */
               gpencil_set_borders(tgpf, false);
 
-      

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to