diff options
author | Antonioya <blendergit@gmail.com> | 2016-11-20 00:41:37 +0300 |
---|---|---|
committer | Antonioya <blendergit@gmail.com> | 2016-11-20 00:41:37 +0300 |
commit | dd82d70bc5eade5dddd6d20ef81eb81ba43463da (patch) | |
tree | a16fa347ee5ecc89da98671bce1a473448ee2a48 /source/blender/editors/gpencil | |
parent | 8c93178c964bac93684fe7ed5d9c4a7c4d9e572a (diff) |
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.
Diffstat (limited to 'source/blender/editors/gpencil')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_edit.c | 6 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_utils.c | 40 |
2 files changed, 45 insertions, 1 deletions
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 12d837dfb29..15f65b394a9 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -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); diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 564ba639983..8073b13ba10 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -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, |