[Bf-blender-cvs] [e02d84eb3be] master: GPencil: Add new parameteres to transform layers

Antonio Vazquez noreply at git.blender.org
Sat Jan 16 16:04:10 CET 2021


Commit: e02d84eb3bea710aa4a658629813bd7e4c67ce4c
Author: Antonio Vazquez
Date:   Sat Jan 16 15:33:38 2021 +0100
Branches: master
https://developer.blender.org/rBe02d84eb3bea710aa4a658629813bd7e4c67ce4c

GPencil: Add new parameteres to transform layers

When using grease pencil for drawing Storyboards, it's very common to require a transform of the layers. This transform can be done using the offset modifier, but in some cases, the scene requires a lot of modifiers and makes the file hard to work.

This new feature adds a transforms Location, Rotation and Scale at Layer level, and allows to transform the layer without using a modifier, keeping the scene more clean.

{F9480695}

This feature was suggested by @pepeland after receiving feedback from several artists.

Also, done some code cleanup and rename some functions to get a better naming.

Maniphest Tasks: T83660

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

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

M	release/scripts/startup/bl_ui/properties_grease_pencil_common.py
M	source/blender/blenkernel/BKE_gpencil.h
M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/blenkernel/intern/gpencil_modifier.c
M	source/blender/blenkernel/intern/object_update.c
M	source/blender/blenloader/intern/versioning_290.c
M	source/blender/draw/engines/overlay/overlay_gpencil.c
M	source/blender/draw/intern/draw_cache_impl_gpencil.c
M	source/blender/editors/gpencil/gpencil_convert.c
M	source/blender/editors/gpencil/gpencil_data.c
M	source/blender/editors/gpencil/gpencil_edit.c
M	source/blender/editors/gpencil/gpencil_fill.c
M	source/blender/editors/gpencil/gpencil_intern.h
M	source/blender/editors/gpencil/gpencil_paint.c
M	source/blender/editors/gpencil/gpencil_primitive.c
M	source/blender/editors/gpencil/gpencil_sculpt_paint.c
M	source/blender/editors/gpencil/gpencil_utils.c
M	source/blender/editors/gpencil/gpencil_vertex_paint.c
M	source/blender/editors/gpencil/gpencil_weight_paint.c
M	source/blender/editors/include/ED_gpencil.h
M	source/blender/editors/object/object_transform.c
M	source/blender/editors/transform/transform_convert_gpencil.c
M	source/blender/editors/transform/transform_gizmo_3d.c
M	source/blender/makesdna/DNA_gpencil_types.h
M	source/blender/makesrna/intern/rna_gpencil.c

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

diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index 8b404c4a306..fecc09da539 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -759,6 +759,16 @@ class GreasePencilLayerAdjustmentsPanel:
         col = layout.row(align=True)
         col.prop(gpl, "lock_material")
 
+        # Transforms
+        row = layout.row(align=True)
+        row.prop(gpl, "location")
+
+        row = layout.row(align=True)
+        row.prop(gpl, "rotation")
+
+        row = layout.row(align=True)
+        row.prop(gpl, "scale")
+
 
 class GPENCIL_UL_masks(UIList):
     def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index df5711f5120..8903abee432 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -280,12 +280,12 @@ void BKE_gpencil_frame_original_pointers_update(const struct bGPDframe *gpf_orig
                                                 const struct bGPDframe *gpf_eval);
 void BKE_gpencil_update_orig_pointers(const struct Object *ob_orig, const struct Object *ob_eval);
 
-void BKE_gpencil_parent_matrix_get(const struct Depsgraph *depsgraph,
-                                   struct Object *obact,
-                                   struct bGPDlayer *gpl,
-                                   float diff_mat[4][4]);
+void BKE_gpencil_layer_transform_matrix_get(const struct Depsgraph *depsgraph,
+                                            struct Object *obact,
+                                            struct bGPDlayer *gpl,
+                                            float diff_mat[4][4]);
 
-void BKE_gpencil_update_layer_parent(const struct Depsgraph *depsgraph, struct Object *ob);
+void BKE_gpencil_update_layer_transforms(const struct Depsgraph *depsgraph, struct Object *ob);
 
 int BKE_gpencil_material_find_index_by_name_prefix(struct Object *ob, const char *name_prefix);
 
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index c7ca82c92fc..83b20e602c3 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -95,6 +95,32 @@ static void greasepencil_copy_data(Main *UNUSED(bmain),
     /* TODO here too could add unused flags... */
     bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate(gpl_src);
 
+    /* Apply local layer transform to all frames. Calc the active frame is not enough
+     * because onion skin can use more frames. This is more slow but required here. */
+    if (gpl_dst->actframe != NULL) {
+      bool transfomed = ((!is_zero_v3(gpl_dst->location)) || (!is_zero_v3(gpl_dst->rotation)) ||
+                         (!is_one_v3(gpl_dst->scale)));
+      if (transfomed) {
+        loc_eul_size_to_mat4(
+            gpl_dst->layer_mat, gpl_dst->location, gpl_dst->rotation, gpl_dst->scale);
+        bool do_onion = ((gpl_dst->onion_flag & GP_LAYER_ONIONSKIN) != 0);
+        bGPDframe *init_gpf = (do_onion) ? gpl_dst->frames.first : gpl_dst->actframe;
+        for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+          LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+            bGPDspoint *pt;
+            int i;
+            for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+              mul_m4_v3(gpl_dst->layer_mat, &pt->x);
+            }
+          }
+          /* if not onion, exit loop. */
+          if (!do_onion) {
+            break;
+          }
+        }
+      }
+    }
+
     BLI_addtail(&gpd_dst->layers, gpl_dst);
   }
 }
@@ -686,6 +712,14 @@ bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setacti
 
   /* Enable always affected by scene lights. */
   gpl->flag |= GP_LAYER_USE_LIGHTS;
+
+  /* Init transform. */
+  zero_v3(gpl->location);
+  zero_v3(gpl->rotation);
+  copy_v3_fl(gpl->scale, 1.0f);
+  loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+  invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
+
   /* make this one the active one */
   if (setactive) {
     BKE_gpencil_layer_active_set(gpd, gpl);
@@ -2759,10 +2793,10 @@ void BKE_gpencil_update_orig_pointers(const Object *ob_orig, const Object *ob_ev
  * \param gpl: Grease pencil layer
  * \param diff_mat: Result parent matrix
  */
-void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
-                                   Object *obact,
-                                   bGPDlayer *gpl,
-                                   float diff_mat[4][4])
+void BKE_gpencil_layer_transform_matrix_get(const Depsgraph *depsgraph,
+                                            Object *obact,
+                                            bGPDlayer *gpl,
+                                            float diff_mat[4][4])
 {
   Object *ob_eval = depsgraph != NULL ? DEG_get_evaluated_object(depsgraph, obact) : obact;
   Object *obparent = gpl->parent;
@@ -2771,11 +2805,10 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
 
   /* if not layer parented, try with object parented */
   if (obparent_eval == NULL) {
-    if (ob_eval != NULL) {
-      if (ob_eval->type == OB_GPENCIL) {
-        copy_m4_m4(diff_mat, ob_eval->obmat);
-        return;
-      }
+    if ((ob_eval != NULL) && (ob_eval->type == OB_GPENCIL)) {
+      copy_m4_m4(diff_mat, ob_eval->obmat);
+      mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
+      return;
     }
     /* not gpencil object */
     unit_m4(diff_mat);
@@ -2785,6 +2818,7 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
   if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
     mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
     add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
+    mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
     return;
   }
   if (gpl->partype == PARBONE) {
@@ -2800,6 +2834,7 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
       mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
       add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
     }
+    mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
     return;
   }
 
@@ -2807,11 +2842,11 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
 }
 
 /**
- * Update parent matrix.
+ * Update parent matrix and local transforms.
  * \param depsgraph: Depsgraph
  * \param ob: Grease pencil object
  */
-void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob)
+void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
 {
   if (ob->type != OB_GPENCIL) {
     return;
@@ -2820,31 +2855,50 @@ void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob)
   bGPdata *gpd = (bGPdata *)ob->data;
   float cur_mat[4][4];
 
+  bool changed = false;
   LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
-    if ((gpl->parent != NULL) && (gpl->actframe != NULL)) {
-      Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
-      /* calculate new matrix */
-      if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
-        copy_m4_m4(cur_mat, ob_parent->obmat);
-      }
-      else if (gpl->partype == PARBONE) {
-        bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
-        if (pchan != NULL) {
-          copy_m4_m4(cur_mat, ob->imat);
-          mul_m4_m4m4(cur_mat, ob_parent->obmat, pchan->pose_mat);
+    unit_m4(cur_mat);
+    if (gpl->actframe != NULL) {
+      if (gpl->parent != NULL) {
+        Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
+        /* calculate new matrix */
+        if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
+          copy_m4_m4(cur_mat, ob_parent->obmat);
         }
-        else {
-          unit_m4(cur_mat);
+        else if (gpl->partype == PARBONE) {
+          bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
+          if (pchan != NULL) {
+            copy_m4_m4(cur_mat, ob->imat);
+            mul_m4_m4m4(cur_mat, ob_parent->obmat, pchan->pose_mat);
+          }
+          else {
+            unit_m4(cur_mat);
+          }
         }
+        changed = !equals_m4m4(gpl->inverse, cur_mat);
       }
+
+      /* Calc local layer transform. */
+      bool transfomed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
+                         (!is_one_v3(gpl->scale)));
+      if (transfomed) {
+        loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+      }
+
       /* only redo if any change */
-      if (!equals_m4m4(gpl->inverse, cur_mat)) {
+      if (changed || transfomed) {
         LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
           bGPDspoint *pt;
           int i;
           for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
-            mul_m4_v3(gpl->inverse, &pt->x);
-            mul_m4_v3(cur_mat, &pt->x);
+            if (changed) {
+              mul_m4_v3(gpl->inverse, &pt->x);
+              mul_m4_v3(cur_mat, &pt->x);
+            }
+
+            if (transfomed) {
+              mul_m4_v3(gpl->layer_mat, &pt->x);
+            }
           }
         }
       }
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 1be2cba31b5..8b12e1b5fca 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -701,13 +701,18 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
   Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
   bGPdata *gpd_orig = (bGPdata *)ob_orig->data;
 
-  /* Need check if some layer is parented. */
+  /* Need check if some layer is parented or transformed. */
   bool do_parent = false;
+  bool do_transform = false;
   LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_orig->layers) {
     if (gpl->parent != NULL) {
       do_parent = true;
       break;
     }
+    if ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gp

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list