[Bf-blender-cvs] [82a225acb50] temp-gpencil-bezier-v2: GPencil: Transform code for bezier strokes

Falk David noreply at git.blender.org
Fri Mar 12 23:34:01 CET 2021


Commit: 82a225acb50cc6c16a2dc720c2d51700af3c62bd
Author: Falk David
Date:   Fri Mar 12 23:32:45 2021 +0100
Branches: temp-gpencil-bezier-v2
https://developer.blender.org/rB82a225acb50cc6c16a2dc720c2d51700af3c62bd

GPencil: Transform code for bezier strokes

This commits implements transformations for both poly and bezier strokes.

Every control point is treated as a stroke point (with some exceptions).
This also refactors some of the old transform code to be a bit
more readable.

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

M	source/blender/editors/transform/transform_convert_gpencil.c

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

diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c
index 45df0e66691..37e11203aef 100644
--- a/source/blender/editors/transform/transform_convert_gpencil.c
+++ b/source/blender/editors/transform/transform_convert_gpencil.c
@@ -97,54 +97,77 @@ static short get_bezt_sel_triple_flag(BezTriple *bezt, const bool handles_visibl
   return flag;
 }
 
-static void createTransGPencil_curves(bContext *C,
-                                      TransInfo *t,
-                                      Depsgraph *depsgraph,
-                                      ToolSettings *ts,
-                                      Object *obact,
-                                      bGPdata *gpd,
-                                      const int cfra_scene,
-                                      const bool is_multiedit,
-                                      const bool use_multiframe_falloff,
-                                      const bool is_prop_edit,
-                                      const bool is_prop_edit_connected,
-                                      const bool is_scale_thickness)
+static void createTransGPencil_strokes(TransInfo *t,
+                                       Depsgraph *depsgraph,
+                                       ToolSettings *ts,
+                                       Object *obact,
+                                       bGPdata *gpd,
+                                       const int cfra_scene,
+                                       const bool is_multiedit,
+                                       const bool use_multiframe_falloff,
+                                       const bool is_prop_edit,
+                                       const bool is_prop_edit_connected,
+                                       const bool is_scale_thickness)
 {
 #define SEL_F1 (1 << 0)
 #define SEL_F2 (1 << 1)
 #define SEL_F3 (1 << 2)
-
   View3D *v3d = t->view;
-  Scene *scene = CTX_data_scene(C);
+  Scene *scene = t->scene;
+  TransData *td = NULL;
+  float mtx[3][3], smtx[3][3];
+
   const bool handle_only_selected_visible = (v3d->overlay.handle_display == CURVE_HANDLE_SELECTED);
   const bool handle_all_visible = (v3d->overlay.handle_display == CURVE_HANDLE_ALL);
 
   TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+  /* == Grease Pencil Strokes to Transform Data ==
+   * Grease Pencil stroke points can be a mixture of 2D (screen-space),
+   * or 3D coordinates. However, they're always saved as 3D points.
+   * For now, we just do these without creating TransData2D for the 2D
+   * strokes. This may cause issues in future though.
+   */
   tc->data_len = 0;
 
-  /* Number of selected curve points */
+  /* First Pass: Count the number of data-points required for the strokes,
+   * (and additional info about the configuration - e.g. 2D/3D?).
+   */
   uint32_t tot_curve_points = 0, tot_sel_curve_points = 0, tot_points = 0, tot_sel_points = 0;
   LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
     /* Only editable and visible layers are considered. */
-    if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
-      bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
-      for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
-        if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
-          LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
-            /* skip strokes that are invalid for current view */
-            if (ED_gpencil_stroke_can_use(C, gps) == false) {
-              continue;
-            }
-            /* Check if the color is editable. */
-            if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
-              continue;
+    if (!BKE_gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) {
+      continue;
+    }
+
+    bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+    for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+      if ((gpf != gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) == 0 && (is_multiedit))) {
+        continue;
+      }
+      LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+        /* skip strokes that are invalid for current view */
+        if (ED_gpencil_stroke_can_use(t->context, gps) == false) {
+          continue;
+        }
+        /* Check if the color is editable. */
+        if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
+          continue;
+        }
+
+        if (GPENCIL_STROKE_TYPE_BEZIER(gps)) {
+          bGPDcurve *gpc = gps->editcurve;
+          if (is_prop_edit) {
+            /* Add all points if prop edit or prop edit connected + stroke is selected. */
+            if (is_prop_edit_connected && gpc->flag & GP_CURVE_SELECT) {
+              tot_curve_points += gpc->tot_curve_points;
+              tot_points += gpc->tot_curve_points * 3;
             }
-            /* Check if stroke has an editcurve */
-            if (gps->editcurve == NULL) {
-              continue;
+            else {
+              tot_curve_points += gpc->tot_curve_points;
+              tot_points += gpc->tot_curve_points * 3;
             }
-
-            bGPDcurve *gpc = gps->editcurve;
+          }
+          else if (gpc->flag & GP_CURVE_SELECT) {
             for (int i = 0; i < gpc->tot_curve_points; i++) {
               bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
               BezTriple *bezt = &gpc_pt->bezt;
@@ -169,60 +192,66 @@ static void createTransGPencil_curves(bContext *C,
                 }
                 tot_sel_curve_points++;
               }
-
-              if (is_prop_edit) {
-                tot_points += 3;
-                tot_curve_points++;
-              }
             }
           }
         }
-
-        /* If not multiedit out of loop. */
-        if (!is_multiedit) {
-          break;
+        else {
+          if (is_prop_edit) {
+            /* Add all points if prop edit or prop edit connected + stroke is selected. */
+            if (is_prop_edit_connected && gps->flag & GP_STROKE_SELECT) {
+              tot_points += gps->totpoints;
+            }
+            else {
+              tot_points += gps->totpoints;
+            }
+          }
+          else if (gps->flag & GP_STROKE_SELECT) {
+            /* Only selected stroke points are considered. */
+            for (int i = 0; i < gps->totpoints; i++) {
+              bGPDspoint *pt = &gps->points[i];
+              if (pt->flag & GP_SPOINT_SELECT) {
+                tot_sel_points++;
+              }
+            }
+          }
         }
       }
+      /* If not multiedit out of loop. */
+      if (!is_multiedit) {
+        break;
+      }
     }
   }
 
-  if (((is_prop_edit && !is_prop_edit_connected) ? tot_curve_points : tot_sel_points) == 0) {
-    tc->data_len = 0;
-    return;
-  }
-
-  int data_len_pt = 0;
-
-  if (is_prop_edit) {
-    tc->data_len = tot_points;
-    data_len_pt = tot_curve_points;
-  }
-  else {
-    tc->data_len = tot_sel_points;
-    data_len_pt = tot_sel_curve_points;
-  }
+  tc->data_len = (is_prop_edit || is_prop_edit_connected) ? tot_points : tot_sel_points;
 
+  /* Stop trying if nothing selected. */
   if (tc->data_len == 0) {
     return;
   }
 
-  transform_around_single_fallback_ex(t, data_len_pt);
+  transform_around_single_fallback_ex(t, tc->data_len);
 
-  tc->data = MEM_callocN(tc->data_len * sizeof(TransData), __func__);
-  TransData *td = tc->data;
+  /* Allocate memory for data */
+  tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransData(GPencil)");
+  td = tc->data;
+
+  unit_m3(smtx);
+  unit_m3(mtx);
 
   const bool use_around_origins_for_handles_test = ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
                                                     transform_mode_use_local_origins(t));
 
+  /* Second Pass: Build transdata array. */
   LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
-    /* Only editable and visible layers are considered. */
+    /* only editable and visible layers are considered */
     if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
       const int cfra = (gpl->flag & GP_LAYER_FRAMELOCK) ? gpl->actframe->framenum : cfra_scene;
       bGPDframe *gpf = gpl->actframe;
-      bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
-      float diff_mat[4][4], mtx[3][3];
-      float smtx[3][3];
+      float diff_mat[4][4];
+      // float inverse_diff_mat[4][4];
 
+      bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
       /* Init multiframe falloff options. */
       int f_init = 0;
       int f_end = 0;
@@ -231,6 +260,12 @@ static void createTransGPencil_curves(bContext *C,
         BKE_gpencil_frame_range_selected(gpl, &f_init, &f_end);
       }
 
+      /* Make a new frame to work on if the layer's frame
+       * and the current scene frame don't match up.
+       *
+       * - This is useful when animating as it saves that "uh-oh" moment when you realize you've
+       *   spent too much time editing the wrong frame...
+       */
       if ((gpf->framenum != cfra) && (!is_multiedit)) {
         if (IS_AUTOKEY_ON(scene)) {
           gpf = BKE_gpencil_frame_addcopy(gpl, cfra);
@@ -246,41 +281,75 @@ static void createTransGPencil_curves(bContext *C,
 
       /* Calculate difference matrix. */
       BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+      // /* Undo matrix. */
+      // invert_m4_m4(inverse_diff_mat, diff_mat);
+
       copy_m3_m4(mtx, diff_mat);
       pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
 
+      /* Loop over strokes, adding TransData for points as needed... */
       for (gpf = init_gpf; gpf; gpf = gpf->next) {
-        if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
-          /* If multi-frame and falloff, recalculate and save value. */
-          float falloff = 1.0f; /* by default no falloff */
-          if ((is_multiedit) && (use_multiframe_falloff)) {
-            /* Falloff depends on distance to active frame
-             * (relative to the overall frame range). */
-            falloff = BKE_gpenci

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list