Fix T50081: Grease pencil parented rotation problem

When the parent object matrix change after the layer was parented, the
inverse matrix for strokes must be updated when editing strokes or the
transformations will be wrong.
This commit is contained in:
Antonio Vazquez 2016-11-19 22:41:37 +01:00
parent 8c93178c96
commit dd82d70bc5
Notes: blender-bot 2023-02-14 07:23:33 +01:00
Referenced by issue #50081, Grease pencil parented to object moving- Rotation problem
3 changed files with 47 additions and 1 deletions

View File

@ -96,7 +96,11 @@ static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *UNUSED(op))
/* Just toggle editmode flag... */
gpd->flag ^= GP_DATA_STROKE_EDITMODE;
/* recalculate parent matrix */
if (gpd->flag & GP_DATA_STROKE_EDITMODE) {
ED_gpencil_reset_layers_parent(gpd);
}
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);

View File

@ -997,6 +997,46 @@ void ED_gpencil_parent_location(bGPDlayer *gpl, float diff_mat[4][4])
}
}
/* reset parent matrix for all layers */
void ED_gpencil_reset_layers_parent(bGPdata *gpd)
{
bGPDspoint *pt;
int i;
float diff_mat[4][4];
float cur_mat[4][4];
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpl->parent != NULL) {
/* calculate new matrix */
if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) {
invert_m4_m4(cur_mat, gpl->parent->obmat);
}
else if (gpl->partype == PARBONE) {
bPoseChannel *pchan = BKE_pose_channel_find_name(gpl->parent->pose, gpl->parsubstr);
if (pchan) {
float tmp_mat[4][4];
mul_m4_m4m4(tmp_mat, gpl->parent->obmat, pchan->pose_mat);
invert_m4_m4(cur_mat, tmp_mat);
}
}
/* only redo if any change */
if (!equals_m4m4(gpl->inverse, cur_mat)) {
/* first apply current transformation to all strokes */
ED_gpencil_parent_location(gpl, diff_mat);
for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
mul_m4_v3(diff_mat, &pt->x);
}
}
}
/* set new parent matrix */
copy_m4_m4(gpl->inverse, cur_mat);
}
}
}
}
/* ******************************************************** */
bool ED_gpencil_stroke_minmax(
const bGPDstroke *gps, const bool use_select,

View File

@ -185,6 +185,8 @@ int ED_undo_gpencil_step(struct bContext *C, int step, const char *name);
/* get difference matrix using parent */
void ED_gpencil_parent_location(struct bGPDlayer *gpl, float diff_mat[4][4]);
/* reset parent matrix for all layers */
void ED_gpencil_reset_layers_parent(struct bGPdata *gpd);
#endif /* __ED_GPENCIL_H__ */