Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYann Lanthony <yann-lty>2022-05-04 13:54:09 +0300
committerFalk David <falkdavid@gmx.de>2022-05-04 13:58:57 +0300
commitb31f5b8ce7ae0f3f8195dc04a2006945fe6b4bff (patch)
tree876bbcabc1520f0ebe671618bbf3e807f109548e /source/blender/blenkernel/intern/gpencil.c
parent302584bd6eef7ff4e37d31974302f2d6ce2174cb (diff)
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
Diffstat (limited to 'source/blender/blenkernel/intern/gpencil.c')
-rw-r--r--source/blender/blenkernel/intern/gpencil.c84
1 files changed, 62 insertions, 22 deletions
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++) {