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
This commit is contained in:
parent
302584bd6e
commit
b31f5b8ce7
Notes:
blender-bot
2023-05-03 10:14:48 +02:00
Referenced by issue #97799, Regression: Transforming a layer in GreasePencil doesn't transform Onion skin in >3.2
|
@ -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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* 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++) {
|
||||
|
|
Loading…
Reference in New Issue