[Bf-blender-cvs] [b31f5b8ce7a] blender-v3.2-release: GPencil: Apply layer transforms to visible frames

Yann Lanthony noreply at git.blender.org
Wed May 4 12:59:37 CEST 2022


Commit: b31f5b8ce7ae0f3f8195dc04a2006945fe6b4bff
Author: Yann Lanthony
Date:   Wed May 4 12:54:09 2022 +0200
Branches: blender-v3.2-release
https://developer.blender.org/rBb31f5b8ce7ae0f3f8195dc04a2006945fe6b4bff

GPencil: Apply layer transforms to visible frames

Fix regression described in T97799.

Apply layer transform and layer parenting to all visible frames, i.e. active frame + onion skinning frames.

Reviewed By: #grease_pencil, antoniov

Maniphest Tasks: T97799

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

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

M	source/blender/blenkernel/intern/gpencil.c

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

diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 087d8b8fcd4..84621be1960 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -2742,35 +2742,75 @@ void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
   LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
     bool changed = false;
     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)) {
-          mul_m4_m4m4(cur_mat, ob->imat, ob_parent->obmat);
+
+    /* Skip non-visible layers. */
+    if (gpl->flag & GP_LAYER_HIDE || is_zero_v3(gpl->scale)) {
+      continue;
+    }
+
+    /* Skip empty layers. */
+    if (BLI_listbase_is_empty(&gpl->frames)) {
+      continue;
+    }
+
+    /* Determine frame range to transform. */
+    bGPDframe *gpf_start = NULL;
+    bGPDframe *gpf_end = NULL;
+
+    /* If onion skinning is activated, consider all frames. */
+    if (gpl->onion_flag & GP_LAYER_ONIONSKIN) {
+      gpf_start = gpl->frames.first;
+    }
+    /* Otherwise, consider only active frame. */
+    else {
+      /* Skip layer if it has no active frame to transform. */
+      if (gpl->actframe == NULL) {
+        continue;
+      }
+      gpf_start = gpl->actframe;
+      gpf_end = gpl->actframe->next;
+    }
+
+    if (gpl->parent != NULL) {
+      Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
+      /* calculate new matrix */
+      if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
+        mul_m4_m4m4(cur_mat, ob->imat, ob_parent->obmat);
+      }
+      else if (gpl->partype == PARBONE) {
+        bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
+        if (pchan != NULL) {
+          mul_m4_series(cur_mat, ob->imat, ob_parent->obmat, pchan->pose_mat);
         }
-        else if (gpl->partype == PARBONE) {
-          bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
-          if (pchan != NULL) {
-            mul_m4_series(cur_mat, ob->imat, ob_parent->obmat, pchan->pose_mat);
-          }
-          else {
-            unit_m4(cur_mat);
-          }
+        else {
+          unit_m4(cur_mat);
         }
-        changed = !equals_m4m4(gpl->inverse, cur_mat);
       }
+      changed = !equals_m4m4(gpl->inverse, cur_mat);
+    }
 
-      /* Calc local layer transform. */
-      bool transformed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
-                          (!is_one_v3(gpl->scale)));
-      if (transformed) {
-        loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+    /* Calc local layer transform. */
+    bool transformed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
+                        (!is_one_v3(gpl->scale)));
+    if (transformed) {
+      loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
+    }
+
+    /* Continue if no transformations are applied to this layer. */
+    if (!changed && !transformed) {
+      continue;
+    }
+
+    /* Iterate over frame range. */
+    for (bGPDframe *gpf = gpf_start; gpf != NULL && gpf != gpf_end; gpf = gpf->next) {
+      /* Skip frames without a valid onion skinning id (note: active frame has one). */
+      if (gpf->runtime.onion_id == INT_MAX) {
+        continue;
       }
 
-      /* only redo if any change */
+      /* Apply transformations only if needed. */
       if (changed || transformed) {
-        LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
+        LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
           bGPDspoint *pt;
           int i;
           for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {



More information about the Bf-blender-cvs mailing list