[Bf-blender-cvs] [a283aa9505b] greasepencil-object: GPencil: Redesign Vetex Paint Smear Tool

Antonio Vazquez noreply at git.blender.org
Mon Nov 11 10:18:44 CET 2019


Commit: a283aa9505b3040f5ca56ab26b5739e83566a3d1
Author: Antonio Vazquez
Date:   Mon Nov 11 10:17:59 2019 +0100
Branches: greasepencil-object
https://developer.blender.org/rBa283aa9505b3040f5ca56ab26b5739e83566a3d1

GPencil: Redesign Vetex Paint Smear Tool

Now instead to rorate the grid, the point is extracted using the direction and not the cell above in a rotated grid. This simplifies the process and gets better results.

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

M	source/blender/editors/gpencil/gpencil_vertex_paint.c

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

diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index 6ac611194e7..b5006b93401 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -72,13 +72,9 @@ typedef enum eGPDvertex_brush_Flag {
 /* Grid of Colors for Smear. */
 typedef struct tGP_Grid {
   /** Lower right corner of rectangle of grid cell. */
-  float bottom_a[2];
-  /** Lower left corner of rectangle of grid cell. */
-  float bottom_b[2];
-  /** Upper right corner of rectangle of grid cell. */
-  float top_a[2];
+  float bottom[2];
   /** Upper left corner of rectangle of grid cell. */
-  float top_b[2];
+  float top[2];
   /** Average Color */
   float color[4];
   /** Total points included. */
@@ -134,8 +130,6 @@ typedef struct tGP_BrushVertexpaintData {
 
   /* - Effect 2D vector */
   float dvec[2];
-  /* Angle relative to Down 2D vector (0, -1} vector */
-  float angle;
 
   /* - multiframe falloff factor */
   float mf_falloff;
@@ -153,10 +147,10 @@ typedef struct tGP_BrushVertexpaintData {
 
   /** Grid of average colors */
   tGP_Grid *grid;
-  /** Total number of rows. */
-  int grid_row;
-  /** Total number of cells in the grid. */
+  /** Total number of rows/cols. */
   int grid_size;
+  /** Total number of cells elments in the grid array. */
+  int grid_len;
   /** Grid is ready to use */
   bool grid_ready;
 
@@ -254,113 +248,124 @@ static float brush_influence_calc(tGP_BrushVertexpaintData *gso, const int radiu
 /* Compute effect vector for directional brushes. */
 static void brush_calc_dvec_2d(tGP_BrushVertexpaintData *gso)
 {
-  const float vaxis[2] = {0.0f, -1.0f};
-
   gso->dvec[0] = (float)(gso->mval[0] - gso->mval_prev[0]);
   gso->dvec[1] = (float)(gso->mval[1] - gso->mval_prev[1]);
 
   normalize_v2(gso->dvec);
-  gso->angle = angle_signed_v2v2(vaxis, gso->dvec);
 }
 
 /* Init a grid of cells around mouse position.
  *
  * For each Cell.
  *
- *      Top A *--------* Top B
- *            |        |
- *            |        |
- *   Bottom A *--------* Bottom B
+ *          *--------* Top
+ *          |        |
+ *          |        |
+ *   Bottom *--------*
  *
- * The cell is rotated using the relative angle of the movement of the mouse.
  * The number of cells is calculated using the brush size and a predefined
  * number of pixels (see: GP_GRID_PIXEL_SIZE)
  */
 
-static void gp_grid_init(tGP_BrushVertexpaintData *gso)
+static void gp_grid_cells_init(tGP_BrushVertexpaintData *gso)
 {
   tGP_Grid *grid;
-  float bottom_a[2], bottom_b[2];
-  float top_a[2], top_b[2];
+  float bottom[2];
+  float top[2];
   int grid_index = 0;
 
-  bottom_a[0] = gso->brush_rect.xmin;
-  bottom_a[1] = gso->brush_rect.ymax - GP_GRID_PIXEL_SIZE;
+  /* The grid center is (0,0). */
+  bottom[0] = gso->brush_rect.xmin - gso->mval[0];
+  bottom[1] = gso->brush_rect.ymax - GP_GRID_PIXEL_SIZE - gso->mval[1];
 
   /* Calc all cell of the grid from top/left. */
-  for (int y = gso->grid_row - 1; y >= 0; y--) {
-    bottom_b[1] = bottom_a[1];
-    top_a[1] = bottom_a[1] + GP_GRID_PIXEL_SIZE;
-    top_b[1] = top_a[1];
-    for (int x = 0; x < gso->grid_row; x++) {
-      bottom_b[0] = bottom_a[0] + GP_GRID_PIXEL_SIZE;
-      top_a[0] = bottom_a[0];
-      top_b[0] = bottom_b[0];
+  for (int y = gso->grid_size - 1; y >= 0; y--) {
+    top[1] = bottom[1] + GP_GRID_PIXEL_SIZE;
+
+    for (int x = 0; x < gso->grid_size; x++) {
+      top[0] = bottom[0] + GP_GRID_PIXEL_SIZE;
 
       grid = &gso->grid[grid_index];
 
-      copy_v2_v2(grid->bottom_a, bottom_a);
-      copy_v2_v2(grid->bottom_b, bottom_b);
-      copy_v2_v2(grid->top_a, top_a);
-      copy_v2_v2(grid->top_b, top_b);
+      copy_v2_v2(grid->bottom, bottom);
+      copy_v2_v2(grid->top, top);
 
-      bottom_a[0] += GP_GRID_PIXEL_SIZE;
+      bottom[0] += GP_GRID_PIXEL_SIZE;
 
       grid_index++;
     }
 
     /* Reset for new row. */
-    bottom_a[0] = gso->brush_rect.xmin;
-    bottom_a[1] -= GP_GRID_PIXEL_SIZE;
+    bottom[0] = gso->brush_rect.xmin - gso->mval[0];
+    bottom[1] -= GP_GRID_PIXEL_SIZE;
   }
+}
 
-  /* Rotate the grid cells using the relative angle. */
-  grid_index = 0;
-  for (int y = gso->grid_row - 1; y >= 0; y--) {
-    for (int x = 0; x < gso->grid_row; x++) {
-      grid = &gso->grid[grid_index];
-
-      if (gso->angle != 0.0f) {
-        sub_v2_v2(grid->bottom_a, gso->mval);
-        sub_v2_v2(grid->bottom_b, gso->mval);
-        sub_v2_v2(grid->top_a, gso->mval);
-        sub_v2_v2(grid->top_b, gso->mval);
-
-        rotate_v2_v2fl(bottom_a, grid->bottom_a, gso->angle);
-        rotate_v2_v2fl(bottom_b, grid->bottom_b, gso->angle);
-        rotate_v2_v2fl(top_a, grid->top_a, gso->angle);
-        rotate_v2_v2fl(top_b, grid->top_b, gso->angle);
-
-        add_v2_v2v2(grid->bottom_a, bottom_a, gso->mval);
-        add_v2_v2v2(grid->bottom_b, bottom_b, gso->mval);
-        add_v2_v2v2(grid->top_a, top_a, gso->mval);
-        add_v2_v2v2(grid->top_b, top_b, gso->mval);
-      }
-
-      grid_index++;
+/* Get the index used in the grid base on dvec. */
+static void gp_grid_cell_average_color_idx_get(tGP_BrushVertexpaintData *gso, int r_idx[2])
+{
+  /* Lower direction. */
+  if (gso->dvec[1] < 0.0f) {
+    if ((gso->dvec[0] >= -1.0f) && (gso->dvec[0] < -0.8f)) {
+      r_idx[0] = 0;
+      r_idx[1] = -1;
+    }
+    else if ((gso->dvec[0] >= -0.8f) && (gso->dvec[0] < -0.6f)) {
+      r_idx[0] = -1;
+      r_idx[1] = -1;
+    }
+    else if ((gso->dvec[0] >= -0.6f) && (gso->dvec[0] < 0.6f)) {
+      r_idx[0] = -1;
+      r_idx[1] = 0;
+    }
+    else if ((gso->dvec[0] >= 0.6f) && (gso->dvec[0] < 0.8f)) {
+      r_idx[0] = -1;
+      r_idx[1] = 1;
+    }
+    else if (gso->dvec[0] >= 0.8f) {
+      r_idx[0] = 0;
+      r_idx[1] = 1;
+    }
+  }
+  /* Upper direction. */
+  else {
+    if ((gso->dvec[0] >= -1.0f) && (gso->dvec[0] < -0.8f)) {
+      r_idx[0] = 0;
+      r_idx[1] = -1;
+    }
+    else if ((gso->dvec[0] >= -0.8f) && (gso->dvec[0] < -0.6f)) {
+      r_idx[0] = 1;
+      r_idx[1] = -1;
+    }
+    else if ((gso->dvec[0] >= -0.6f) && (gso->dvec[0] < 0.6f)) {
+      r_idx[0] = 1;
+      r_idx[1] = 0;
+    }
+    else if ((gso->dvec[0] >= 0.6f) && (gso->dvec[0] < 0.8f)) {
+      r_idx[0] = 1;
+      r_idx[1] = 1;
+    }
+    else if (gso->dvec[0] >= 0.8f) {
+      r_idx[0] = 0;
+      r_idx[1] = 1;
     }
   }
 }
 
 static int gp_grid_cell_index_get(tGP_BrushVertexpaintData *gso, float pc[2])
 {
-  for (int i = 0; i < gso->grid_size; i++) {
+  float bottom[2], top[2];
+
+  for (int i = 0; i < gso->grid_len; i++) {
     tGP_Grid *grid = &gso->grid[i];
+    add_v2_v2v2(bottom, grid->bottom, gso->mval);
+    add_v2_v2v2(top, grid->top, gso->mval);
 
-    float w[3];
-    /* Test first triangle. */
-    if (barycentric_coords_v2(grid->bottom_a, grid->top_a, grid->top_b, pc, w)) {
-      if (barycentric_inside_triangle_v2(w)) {
-        return i;
-      }
-    }
-    /* Test second triangle. */
-    if (barycentric_coords_v2(grid->bottom_a, grid->bottom_b, grid->top_b, pc, w)) {
-      if (barycentric_inside_triangle_v2(w)) {
-        return i;
-      }
+    if (pc[0] >= bottom[0] && pc[0] <= top[0] && pc[1] >= bottom[1] && pc[1] <= top[1]) {
+      return i;
     }
   }
+
   return -1;
 }
 
@@ -398,7 +403,7 @@ static void gp_grid_colors_calc(tGP_BrushVertexpaintData *gso)
   }
 
   /* Average colors. */
-  for (int i = 0; i < gso->grid_size; i++) {
+  for (int i = 0; i < gso->grid_len; i++) {
     grid = &gso->grid[i];
     if (grid->totcol > 0) {
       mul_v3_fl(grid->color, (1.0f / (float)grid->totcol));
@@ -617,54 +622,69 @@ static bool brush_smear_apply(tGP_BrushVertexpaintData *gso,
                               tGP_Selected *selected)
 {
   Brush *brush = gso->brush;
+  tGP_Grid *grid = NULL;
   float pcf[2];
+  int average_idx[2];
+  bool changed = false;
 
   /* Need some movement, so first input is not done. */
   if (gso->first) {
     return false;
   }
 
+  bGPDspoint *pt = &gps->points[pt_index];
+
   /* Need get average colors in the grid. */
   if ((!gso->grid_ready) && (gso->pbuffer_used > 0)) {
     gp_grid_colors_calc(gso);
   }
 
-  /* Attenuate factor to get a smoother tinting. */
-  float inf = (brush_influence_calc(gso, radius, selected->pc) *
-               brush->gpencil_settings->draw_strength) /
-              100.0f;
-  float inf_fill = (gso->pressure * brush->gpencil_settings->draw_strength) / 1000.0f;
+  /* The influence is equal to strength and no decay around brush radius. */
+  float inf = brush->gpencil_settings->draw_strength;
+  if (brush->flag & GP_BRUSH_USE_PRESSURE) {
+    inf *= gso->pressure;
+  }
 
-  bGPDspoint *pt = &gps->points[pt_index];
+  /* Retry row and col for average color. */
+  gp_grid_cell_average_color_idx_get(gso, average_idx);
+
+  /* Retry average color cell. */
+  copy_v2fl_v2i(pcf, selected->pc);
+  int grid_index = gp_grid_cell_index_get(gso, pcf);
+  if (grid_index > -1) {
+    int row = grid_index / gso->grid_size;
+    int col = grid_index - (gso->grid_size * row);
+    row += average_idx[0];
+    col += average_idx[1];
+    CLAMP(row, 0, gso->grid_size);
+    CLAMP(col, 0, gso->grid_size);
+
+    int new_index = (row * gso->grid_size) + col;
+    grid = &gso->grid[new_index];
+  }
 
   /* Apply color to Stroke point. */
   if (GPENCIL_TINT_VERTEX_COLOR_STROKE(brush)) {
-    copy_v2fl_v2i(pcf, selected->pc);
-    int grid_index = gp_grid_cell_index_get(gso, pcf);
-    if (grid_index >= gso->grid_row) {
-      /* Take the row above in the grid */
-      tGP_Grid *grid = &gso->grid[grid_index - gso->grid_row];
+    if (grid_index > -1) {
       if (grid->color[3] > 0.0f) {
-        copy_v3_v3(pt->mix_color, grid->color);
-        // interp_v3_v3v3(pt->mix_color, pt->mix_color, grid->color, inf);
+        // copy_v3_v3(pt->mix_color, grid->color);
+        interp_v3_v3v3(pt->mix_color, pt->mix_color, grid->color, inf);
+        changed = true;
       }
     }
   }
 
   /* Apply color to Fill area (all with same color and factor). */
   if (GPENCIL_TINT_VERTEX_COLOR_FILL(brush)) {
-    copy_v2fl_v2i(pcf, selected->pc);
-    int grid_index = gp_grid_cell_index_get(gso, pcf);
-    if (grid_index >= g

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list