[Bf-blender-cvs] [221c24912df] temp-gpencil-interpolate: GPencil : New Flip automatic calculation

Antonio Vazquez noreply at git.blender.org
Wed Feb 17 19:44:10 CET 2021


Commit: 221c24912dfd6ee1a69e6c636813009491643332
Author: Antonio Vazquez
Date:   Wed Feb 17 19:44:03 2021 +0100
Branches: temp-gpencil-interpolate
https://developer.blender.org/rB221c24912dfd6ee1a69e6c636813009491643332

GPencil : New Flip automatic calculation

Now the stroke is flipped automatically if the visual lines between extremes intersect. Also, instead to use a checkbox, now there is a list of flip modes: No Flip, Flip and Automatic.

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

M	source/blender/editors/gpencil/gpencil_intern.h
M	source/blender/editors/gpencil/gpencil_interpolate.c
M	source/blender/makesdna/DNA_scene_types.h

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

diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 8a45010b313..c6f74c39beb 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -103,65 +103,6 @@ typedef struct tGPDdraw {
   float diff_mat[4][4];        /* matrix */
 } tGPDdraw;
 
-/* Temporary interpolate operation data */
-typedef struct tGPDinterpolate_layer {
-  struct tGPDinterpolate_layer *next, *prev;
-
-  /** layer */
-  struct bGPDlayer *gpl;
-  /** frame before current frame (interpolate-from) */
-  struct bGPDframe *prevFrame;
-  /** frame after current frame (interpolate-to) */
-  struct bGPDframe *nextFrame;
-  /** interpolated frame */
-  struct bGPDframe *interFrame;
-  /** interpolate factor */
-  float factor;
-
-  /* Hash tablets to create temp relationship between strokes. */
-  struct GHash *used_strokes;
-  struct GHash *pair_strokes;
-
-} tGPDinterpolate_layer;
-
-typedef struct tGPDinterpolate {
-  /** Current depsgraph from context */
-  struct Depsgraph *depsgraph;
-  /** current scene from context */
-  struct Scene *scene;
-  /** area where painting originated */
-  struct ScrArea *area;
-  /** region where painting originated */
-  struct ARegion *region;
-  /** current object */
-  struct Object *ob;
-  /** current GP datablock */
-  struct bGPdata *gpd;
-  /** current material */
-  struct Material *mat;
-
-  /** current frame number */
-  int cframe;
-  /** (tGPDinterpolate_layer) layers to be interpolated */
-  ListBase ilayers;
-  /** value for determining the displacement influence */
-  float shift;
-  /** initial interpolation factor for active layer */
-  float init_factor;
-  /** shift low limit (-100%) */
-  float low_limit;
-  /** shift upper limit (200%) */
-  float high_limit;
-  /** flag from toolsettings */
-  int flag;
-  /** smooth factor */
-  float smooth_factor;
-  /** smooth iterations */
-  int smooth_steps;
-
-  NumInput num; /* numeric input */
-} tGPDinterpolate;
-
 /* Modal Operator Drawing Callbacks ------------------------ */
 void ED_gpencil_draw_fill(struct tGPDdraw *tgpw);
 
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 2784fbaf943..bc5648352b8 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -69,6 +69,78 @@
 
 #include "gpencil_intern.h"
 
+/* Temporary interpolate operation data */
+typedef struct tGPDinterpolate_layer {
+  struct tGPDinterpolate_layer *next, *prev;
+
+  /** layer */
+  struct bGPDlayer *gpl;
+  /** frame before current frame (interpolate-from) */
+  struct bGPDframe *prevFrame;
+  /** frame after current frame (interpolate-to) */
+  struct bGPDframe *nextFrame;
+  /** interpolated frame */
+  struct bGPDframe *interFrame;
+  /** interpolate factor */
+  float factor;
+
+  /* Hash tablets to create temp relationship between strokes. */
+  struct GHash *used_strokes;
+  struct GHash *pair_strokes;
+
+} tGPDinterpolate_layer;
+
+typedef struct tGPDinterpolate {
+  /** Current depsgraph from context */
+  struct Depsgraph *depsgraph;
+  /** current scene from context */
+  struct Scene *scene;
+  /** area where painting originated */
+  struct ScrArea *area;
+  /** region where painting originated */
+  struct ARegion *region;
+  /** current object */
+  struct Object *ob;
+  /** current GP datablock */
+  struct bGPdata *gpd;
+  /** current material */
+  struct Material *mat;
+  /* Space Conversion Data */
+  struct GP_SpaceConversion gsc;
+
+  /** current frame number */
+  int cframe;
+  /** (tGPDinterpolate_layer) layers to be interpolated */
+  ListBase ilayers;
+  /** value for determining the displacement influence */
+  float shift;
+  /** initial interpolation factor for active layer */
+  float init_factor;
+  /** shift low limit (-100%) */
+  float low_limit;
+  /** shift upper limit (200%) */
+  float high_limit;
+  /** flag from toolsettings */
+  int flag;
+  /** Flip mode. */
+  enum eGP_InterpolateFlipMode flipmode;
+  /** smooth factor */
+  float smooth_factor;
+  /** smooth iterations */
+  int smooth_steps;
+
+  NumInput num; /* numeric input */
+} tGPDinterpolate;
+
+typedef enum eGP_InterpolateFlipMode {
+  /* No flip. */
+  GP_INTERPOLATE_NOFLIP = 0,
+  /* Flip always. */
+  GP_INTERPOLATE_FLIP = 1,
+  /* Flip if needed. */
+  GP_INTERPOLATE_FLIPAUTO = 2,
+} eGP_InterpolateFlipMode;
+
 /* ************************************************ */
 /* Core/Shared Utilities */
 
@@ -92,6 +164,46 @@ static bool gpencil_view3d_poll(bContext *C)
   return true;
 }
 
+/* Return if the stroke must be flipped or not. The logic of the calculation
+ * is to check if the lines from extremes crossed. All is done in 2D. */
+static bool gpencil_stroke_need_flip(Depsgraph *depsgraph,
+                                     Object *ob,
+                                     bGPDlayer *gpl,
+                                     GP_SpaceConversion *gsc,
+                                     bGPDstroke *gps_from,
+                                     bGPDstroke *gps_to)
+{
+  float diff_mat[4][4];
+  /* calculate parent matrix */
+  BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
+  bGPDspoint *pt, pt_dummy_ps;
+  float v1a[2], v1b[2], v2a[2], v2b[2];
+
+  /* Line from start of strokes. */
+  pt = &gps_from->points[0];
+  gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
+  gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v1a[0], &v1a[1]);
+
+  pt = &gps_to->points[0];
+  gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
+  gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v1b[0], &v1b[1]);
+
+  /* Line from end of strokes. */
+  pt = &gps_from->points[gps_from->totpoints - 1];
+  gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
+  gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v2a[0], &v2a[1]);
+
+  pt = &gps_to->points[gps_to->totpoints - 1];
+  gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
+  gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v2b[0], &v2b[1]);
+
+  if (isect_seg_seg_v2(v1a, v1b, v2a, v2b) == ISECT_LINE_LINE_CROSS) {
+    return true;
+  }
+
+  return false;
+}
+
 /* Return the stroke related to the selection index, returning the stroke with
  * the smallest selection index greater than reference index. */
 static bGPDstroke *gpencil_stroke_get_related(GHash *used_strokes,
@@ -388,9 +500,16 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
         BKE_gpencil_stroke_uniform_subdivide(gpd, gps_from, gps_to->totpoints, true);
       }
 
-      if (tgpi->flag & GP_TOOLFLAG_INTERPOLATE_FLIP) {
+      /* Flip stroke. */
+      if (tgpi->flipmode == GP_INTERPOLATE_FLIP) {
         BKE_gpencil_stroke_flip(gps_to);
       }
+      else if (tgpi->flipmode == GP_INTERPOLATE_FLIPAUTO) {
+        if (gpencil_stroke_need_flip(
+                tgpi->depsgraph, tgpi->ob, gpl, &tgpi->gsc, gps_from, gps_to)) {
+          BKE_gpencil_stroke_flip(gps_to);
+        }
+      }
 
       /* Create new stroke. */
       bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true);
@@ -528,6 +647,8 @@ static bool gpencil_interpolate_set_init_values(bContext *C, wmOperator *op, tGP
   tgpi->area = CTX_wm_area(C);
   tgpi->region = CTX_wm_region(C);
   tgpi->ob = CTX_data_active_object(C);
+  /* Setup space conversions. */
+  gpencil_point_conversion_init(C, &tgpi->gsc);
 
   /* set current frame number */
   tgpi->cframe = tgpi->scene->r.cfra;
@@ -542,7 +663,8 @@ static bool gpencil_interpolate_set_init_values(bContext *C, wmOperator *op, tGP
       tgpi->flag,
       ((GPENCIL_EDIT_MODE(tgpi->gpd)) && (RNA_boolean_get(op->ptr, "interpolate_selected_only"))),
       GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED);
-  SET_FLAG_FROM_TEST(tgpi->flag, RNA_boolean_get(op->ptr, "flip"), GP_TOOLFLAG_INTERPOLATE_FLIP);
+
+  tgpi->flipmode = RNA_enum_get(op->ptr, "flip");
 
   tgpi->smooth_factor = RNA_float_get(op->ptr, "smooth_factor");
   tgpi->smooth_steps = RNA_int_get(op->ptr, "smooth_steps");
@@ -767,6 +889,13 @@ static void gpencil_interpolate_cancel(bContext *C, wmOperator *op)
 
 void GPENCIL_OT_interpolate(wmOperatorType *ot)
 {
+  static const EnumPropertyItem flip_modes[] = {
+      {GP_INTERPOLATE_NOFLIP, "NOFLIP", 0, "No Flip", ""},
+      {GP_INTERPOLATE_FLIP, "FLIP", 0, "Flip", ""},
+      {GP_INTERPOLATE_FLIPAUTO, "AUTO", 0, "Automatic", ""},
+      {0, NULL, 0, NULL, NULL},
+  };
+
   PropertyRNA *prop;
 
   /* identifiers */
@@ -814,11 +943,12 @@ void GPENCIL_OT_interpolate(wmOperatorType *ot)
                   "Only Selected",
                   "Interpolate only selected strokes");
 
-  RNA_def_boolean(ot->srna,
-                  "flip",
-                  0,
-                  "Flip Strokes",
-                  "Invert destination stroke to match start and end with source stroke");
+  RNA_def_enum(ot->srna,
+               "flip",
+               flip_modes,
+               GP_INTERPOLATE_FLIPAUTO,
+               "Flip Mode",
+               "Invert destination stroke to match start and end with source stroke");
 
   RNA_def_int(ot->srna,
               "smooth_steps",
@@ -1054,11 +1184,16 @@ static float gpencil_interpolate_seq_easing_calc(wmOperator *op,
 
 static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
 {
+  Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
   Scene *scene = CTX_data_scene(C);
   ToolSettings *ts = CTX_data_tool_settings(C);
   Object *ob = CTX_data_active_object(C);
   bGPdata *gpd = ob->data;
   bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C);
+  /* Setup space conversions. */
+  GP_SpaceConversion gsc;
+  gpencil_point_conversion_init(C, &gsc);
+
   int cfra = CFRA;
 
   GP_Interpolate_Settings *ipo_settings = &ts->gp_interpolate;
@@ -1068,7 +1203,8 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
   const bool only_selected = ((GPENCIL_EDIT_MODE(gpd)) &&
                               (RNA_boolean_get(op->ptr, "interpolate_selected_only") != 0));
 
-  const bool flip = RNA_boolean_get(op->ptr, "flip");
+  eGP_InterpolateFl

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list