[Bf-blender-cvs] [1f2be8894dd] temp-gpencil-fill: GPencil: Calculate Zoom level base on strokes

Antonio Vazquez noreply at git.blender.org
Thu Jan 28 18:26:58 CET 2021


Commit: 1f2be8894dd9d5c5aef09f1e398280f6efd4ae5e
Author: Antonio Vazquez
Date:   Thu Jan 14 17:07:15 2021 +0100
Branches: temp-gpencil-fill
https://developer.blender.org/rB1f2be8894dd9d5c5aef09f1e398280f6efd4ae5e

GPencil: Calculate Zoom level base on strokes

It uses the stroke bounding box (2D) to determine if the stroke fit in the window.

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

M	source/blender/editors/gpencil/gpencil_fill.c
M	source/blender/editors/gpencil/gpencil_utils.c
M	source/blender/editors/include/ED_gpencil.h

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

diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 160306ac8be..42ffe88be5a 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -171,6 +171,9 @@ typedef struct tGPDfill {
   int bwiny;
   rcti brect;
 
+  /* Space Conversion Data */
+  GP_SpaceConversion gsc;
+
   /** Zoom factor. */
   float zoom;
 } tGPDfill;
@@ -182,7 +185,8 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
                                       const bool cyclic,
                                       const float ink[4],
                                       const int flag,
-                                      const float thershold)
+                                      const float thershold,
+                                      const float thickness)
 {
   bGPDspoint *points = gps->points;
 
@@ -205,7 +209,7 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
   immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
 
   /* draw stroke curve */
-  GPU_line_width(1.0f);
+  GPU_line_width(thickness);
   immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints + cyclic_add);
   const bGPDspoint *pt = points;
 
@@ -257,10 +261,54 @@ static void draw_mouse_position(tGPDfill *tgpf)
 
   /* Draw mouse click position in Blue. */
   const float mouse_color[4] = {0.0f, 0.0f, 1.0f, 1.0f};
-  gpencil_draw_basic_stroke(tgpf, tgpf->gps_mouse, tgpw.diff_mat, 0, mouse_color, 0, 1.0f);
+  gpencil_draw_basic_stroke(tgpf, tgpf->gps_mouse, tgpw.diff_mat, 0, mouse_color, 0, 1.0f, 5.0f);
 }
 
-/* loop all layers */
+/* Helper: Check if must skip the layer */
+bool skip_layer_check(short fill_layer_mode, int gpl_active_index, int gpl_index)
+{
+  bool skip = false;
+
+  switch (fill_layer_mode) {
+    case GP_FILL_GPLMODE_ACTIVE: {
+      if (gpl_index != gpl_active_index) {
+        skip = true;
+      }
+      break;
+    }
+    case GP_FILL_GPLMODE_ABOVE: {
+      if (gpl_index != gpl_active_index + 1) {
+        skip = true;
+      }
+      break;
+    }
+    case GP_FILL_GPLMODE_BELOW: {
+      if (gpl_index != gpl_active_index - 1) {
+        skip = true;
+      }
+      break;
+    }
+    case GP_FILL_GPLMODE_ALL_ABOVE: {
+      if (gpl_index <= gpl_active_index) {
+        skip = true;
+      }
+      break;
+    }
+    case GP_FILL_GPLMODE_ALL_BELOW: {
+      if (gpl_index >= gpl_active_index) {
+        skip = true;
+      }
+      break;
+    }
+    case GP_FILL_GPLMODE_VISIBLE:
+    default:
+      break;
+  }
+
+  return skip;
+}
+
+/* Loop all layers to draw strokes. */
 static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
 {
   Object *ob = tgpf->ob;
@@ -301,43 +349,8 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
 
     /* Decide if the strokes of layers are included or not depending on the layer mode.
      * Cannot skip the layer because it can use boundary strokes and must be used. */
-    bool skip = false;
     const int gpl_index = BLI_findindex(&gpd->layers, gpl);
-    switch (brush_settings->fill_layer_mode) {
-      case GP_FILL_GPLMODE_ACTIVE: {
-        if (gpl_index != gpl_active_index) {
-          skip = true;
-        }
-        break;
-      }
-      case GP_FILL_GPLMODE_ABOVE: {
-        if (gpl_index != gpl_active_index + 1) {
-          skip = true;
-        }
-        break;
-      }
-      case GP_FILL_GPLMODE_BELOW: {
-        if (gpl_index != gpl_active_index - 1) {
-          skip = true;
-        }
-        break;
-      }
-      case GP_FILL_GPLMODE_ALL_ABOVE: {
-        if (gpl_index <= gpl_active_index) {
-          skip = true;
-        }
-        break;
-      }
-      case GP_FILL_GPLMODE_ALL_BELOW: {
-        if (gpl_index >= gpl_active_index) {
-          skip = true;
-        }
-        break;
-      }
-      case GP_FILL_GPLMODE_VISIBLE:
-      default:
-        break;
-    }
+    bool skip = skip_layer_check(brush_settings->fill_layer_mode, gpl_active_index, gpl_index);
 
     /* if active layer and no keyframe, create a new one */
     if (gpl == tgpf->gpl) {
@@ -401,7 +414,8 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
                                   gps->flag & GP_STROKE_CYCLIC,
                                   ink,
                                   tgpf->flag,
-                                  tgpf->fill_threshold);
+                                  tgpf->fill_threshold,
+                                  1.0f);
       }
     }
   }
@@ -1418,8 +1432,9 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
   tgpf->win = CTX_wm_window(C);
   tgpf->active_cfra = CFRA;
 
-  /* TODO: Zoom GPXX(need calculation). */
-  tgpf->zoom = 3.0f;
+  /* Setup space conversions. */
+  gpencil_point_conversion_init(C, &tgpf->gsc);
+  tgpf->zoom = 1.0f;
 
   /* set GP datablock */
   tgpf->gpd = gpd;
@@ -1599,6 +1614,103 @@ static int gpencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
   return OPERATOR_RUNNING_MODAL;
 }
 
+/* Helper: Calc the maximum bounding box size of strokes to get the zoom level of the viewport.
+ * For each stroke, the 2D projected bounding box is calculated and using this data, the total
+ * object bounding box (all strokes) is calculated. To select an stroke, the stroke bounding box
+ * is checked with the mouse position to verify if the stroke is used or not.
+ */
+static void gpencil_zoom_level_set(tGPDfill *tgpf)
+{
+  Object *ob = tgpf->ob;
+  bGPdata *gpd = tgpf->gpd;
+  BrushGpencilSettings *brush_settings = tgpf->brush->gpencil_settings;
+  bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd);
+  BLI_assert(gpl_active != NULL);
+
+  const int gpl_active_index = BLI_findindex(&gpd->layers, gpl_active);
+  BLI_assert(gpl_active_index >= 0);
+
+  float objectbox_min[2], objectbox_max[2];
+  INIT_MINMAX2(objectbox_min, objectbox_max);
+
+  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+    if (gpl->flag & GP_LAYER_HIDE) {
+      continue;
+    }
+    float diff_mat[4][4];
+    /* calculate parent matrix */
+    BKE_gpencil_parent_matrix_get(tgpf->depsgraph, ob, gpl, diff_mat);
+
+    /* Decide if the strokes of layers are included or not depending on the layer mode.
+     * Cannot skip the layer because it can use boundary strokes and must be used. */
+    const int gpl_index = BLI_findindex(&gpd->layers, gpl);
+    bool skip = skip_layer_check(brush_settings->fill_layer_mode, gpl_active_index, gpl_index);
+
+    /* Get frame to check. */
+    bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, tgpf->active_cfra, GP_GETFRAME_USE_PREV);
+    if (gpf == NULL) {
+      continue;
+    }
+
+    /* Read all strokes. */
+    LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+      /* check if stroke can be drawn */
+      if ((gps->points == NULL) || (gps->totpoints < 2)) {
+        continue;
+      }
+      /* check if the color is visible */
+      MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
+      if ((gp_style == NULL) || (gp_style->flag & GP_MATERIAL_HIDE)) {
+        continue;
+      }
+
+      /* If the layer must be skipped, but the stroke is not boundary, skip stroke. */
+      if ((skip) && ((gps->flag & GP_STROKE_NOFILL) == 0)) {
+        continue;
+      }
+
+      /* Check if the stroke collide with mouse. */
+      float mouse[2];
+      copy_v2fl_v2i(mouse, tgpf->mouse);
+      if (!ED_gpencil_stroke_check_collision(&tgpf->gsc, gps, mouse, 100.0f, diff_mat)) {
+        continue;
+      }
+
+      float boundbox_min[2];
+      float boundbox_max[2];
+      ED_gpencil_projected_2d_bound_box(&tgpf->gsc, gps, diff_mat, boundbox_min, boundbox_max);
+      minmax_v2v2_v2(objectbox_min, objectbox_max, boundbox_min);
+      minmax_v2v2_v2(objectbox_min, objectbox_max, boundbox_max);
+    }
+  }
+
+  /* Calculate total width used. */
+  float width = tgpf->region->winx;
+  if (objectbox_min[0] < 0.0f) {
+    width -= objectbox_min[0];
+  }
+  if (objectbox_max[0] > tgpf->region->winx) {
+    width += objectbox_max[0] - tgpf->region->winx;
+  }
+  /* Calculate total height used. */
+  float height = tgpf->region->winy;
+  if (objectbox_min[1] < 0.0f) {
+    height -= objectbox_min[1];
+  }
+  if (objectbox_max[1] > tgpf->region->winy) {
+    height += objectbox_max[1] - tgpf->region->winy;
+  }
+
+  width = ceilf(width);
+  height = ceilf(height);
+
+  float zoomx = (width > tgpf->region->winx) ? width / (float)tgpf->region->winx : 1.0f;
+  float zoomy = (height > tgpf->region->winy) ? height / (float)tgpf->region->winy : 1.0f;
+  if ((zoomx != 1.0f) || (zoomy != 1.0f)) {
+    tgpf->zoom = ceil(max_ff(zoomx, zoomy) + 1.5f);
+  }
+}
+
 /* events handling during interactive part of operator */
 static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
 {
@@ -1631,7 +1743,8 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
           if ((in_bounds) && (region->regiontype == RGN_TYPE_WINDOW)) {
             tgpf->mouse[0] = event->mval[0];
             tgpf->mouse[1] = event->mval[1];
-
+            /* Define Zoom level. */
+            gpencil_zoom_level_set(tgpf);
             /* Create Temp stroke. */
             tgpf->gps_mouse = BKE_gpencil_stroke_new(0, 2, 10.0f);
             /* Add two points to have a line. */
@@ -1642,7 +1755,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
                 tgpf->scene, tgpf->region, tgpf->ob, &point2D, NULL, &pt->x);
 
             pt = &tgpf->gps_mouse->points[1];
-            point2D.x += 2.0f;
+            point2D.x += 3.0f * tgpf->zoom;
             gpencil_stroke_convertcoords_tpoint(
                 tgpf->scene, tgpf->region, tgpf->ob, &point2D, NULL, &pt->x);
 
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 7c796f7b7a1..027fea773ad 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -3003,12 +3003,12 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph,
   }
 }
 
-/* Helper to get the bigger 2D bound box points. */
-static void gpencil_projected_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list