diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-03-04 06:38:16 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-03-04 07:13:10 +0300 |
commit | cf2876b77aaf84a50922f7398f89feaeb56bad0b (patch) | |
tree | 83dc6d710a485114e5d267ced2f19e91475c2626 | |
parent | d48c3666da8600ffbf60a803cbd47f593bdf14fa (diff) |
Fix for snap to cursor /w parents (object/pose)
Also don't use pose-bone transform unless the user is in pose-mode.
-rw-r--r-- | source/blender/blenkernel/BKE_armature.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_object.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 13 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_snap.c | 138 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_armature_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 2 |
7 files changed, 122 insertions, 50 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index fdf0795fe02..66e204e51e0 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -87,6 +87,8 @@ int bone_autoside_name(char name[64], int strip_number, short axis, float head, struct Bone *BKE_armature_find_bone_name(struct bArmature *arm, const char *name); +bool BKE_armature_bone_flag_test_recursive(const struct Bone *bone, int flag); + float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3], float r1, float r2, float rdist); void BKE_armature_where_is(struct bArmature *arm); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 0ea460d1a60..46ec4697737 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -184,6 +184,8 @@ int BKE_object_insert_ptcache(struct Object *ob); void BKE_object_delete_ptcache(struct Object *ob, int index); struct KeyBlock *BKE_object_insert_shape_key(struct Object *ob, const char *name, const bool from_mix); +bool BKE_object_flag_test_recursive(const struct Object *ob, short flag); + bool BKE_object_is_child_recursive(struct Object *ob_parent, struct Object *ob_child); bool BKE_object_is_animated(struct Scene *scene, struct Object *ob); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 31695b05352..6b67a4e5763 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -263,6 +263,19 @@ Bone *BKE_armature_find_bone_name(bArmature *arm, const char *name) return bone; } +bool BKE_armature_bone_flag_test_recursive(const Bone *bone, int flag) +{ + if (bone->flag & flag) { + return true; + } + else if (bone->parent) { + return BKE_armature_bone_flag_test_recursive(bone->parent, flag); + } + else { + return false; + } +} + /* Finds the best possible extension to the name on a particular axis. (For renaming, check for * unique names afterwards) strip_number: removes number extensions (TODO: not used) * axis: the axis to name on diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index fa0ad32f62d..da6d4e27cf8 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -3478,6 +3478,19 @@ KeyBlock *BKE_object_insert_shape_key(Object *ob, const char *name, const bool f } +bool BKE_object_flag_test_recursive(const Object *ob, short flag) +{ + if (ob->flag & flag) { + return true; + } + else if (ob->parent) { + return BKE_object_flag_test_recursive(ob->parent, flag); + } + else { + return false; + } +} + bool BKE_object_is_child_recursive(Object *ob_parent, Object *ob_child) { for (ob_child = ob_child->parent; ob_child; ob_child = ob_child->parent) { diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index ed934706e2d..0608c35129d 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -44,6 +44,7 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_lattice.h" +#include "BKE_main.h" #include "BKE_mball.h" #include "BKE_object.h" #include "BKE_editmesh.h" @@ -210,8 +211,9 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) static int snap_sel_to_curs_exec(bContext *C, wmOperator *op) { - Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + Object *obact = CTX_data_active_object(C); View3D *v3d = CTX_wm_view3d(C); TransVertStore tvs = {NULL}; TransVert *tv; @@ -272,59 +274,98 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op) ED_transverts_update_obedit(&tvs, obedit); ED_transverts_free(&tvs); } - else { + else if (obact && (obact->mode & OB_MODE_POSE)) { struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) - { - if (ob->mode & OB_MODE_POSE) { - bPoseChannel *pchan; - bArmature *arm = ob->data; - float cursor_local[3]; - - invert_m4_m4(ob->imat, ob->obmat); - mul_v3_m4v3(cursor_local, ob->imat, cursor_global); + bPoseChannel *pchan; + bArmature *arm = obact->data; + float cursor_local[3]; - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if (pchan->bone->flag & BONE_SELECTED) { - if (PBONE_VISIBLE(arm, pchan->bone)) { - if ((pchan->bone->flag & BONE_CONNECTED) == 0) { - /* Get position in pchan (pose) space. */ - float cursor_pose[3]; + invert_m4_m4(obact->imat, obact->obmat); + mul_v3_m4v3(cursor_local, obact->imat, cursor_global); - if (use_offset) { - mul_v3_m4v3(cursor_pose, ob->obmat, pchan->pose_mat[3]); - add_v3_v3(cursor_pose, offset_global); + for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) { + if ((pchan->bone->flag & BONE_SELECTED) && + (PBONE_VISIBLE(arm, pchan->bone)) && + /* if the bone has a parent and is connected to the parent, + * don't do anything - will break chain unless we do auto-ik. + */ + (pchan->bone->flag & BONE_CONNECTED) == 0) + { + pchan->bone->flag |= BONE_TRANSFORM; + } + else { + pchan->bone->flag &= ~BONE_TRANSFORM; + } + } - mul_m4_v3(ob->imat, cursor_pose); - BKE_armature_loc_pose_to_bone(pchan, cursor_pose, cursor_pose); - } - else { - BKE_armature_loc_pose_to_bone(pchan, cursor_local, cursor_pose); - } + for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) { + if ((pchan->bone->flag & BONE_TRANSFORM) && + /* check that our parents not transformed (if we have one) */ + ((pchan->bone->parent && + BKE_armature_bone_flag_test_recursive(pchan->bone->parent, BONE_TRANSFORM)) == 0)) + { + /* Get position in pchan (pose) space. */ + float cursor_pose[3]; - /* copy new position */ - if ((pchan->protectflag & OB_LOCK_LOCX) == 0) - pchan->loc[0] = cursor_pose[0]; - if ((pchan->protectflag & OB_LOCK_LOCY) == 0) - pchan->loc[1] = cursor_pose[1]; - if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) - pchan->loc[2] = cursor_pose[2]; + if (use_offset) { + mul_v3_m4v3(cursor_pose, obact->obmat, pchan->pose_mat[3]); + add_v3_v3(cursor_pose, offset_global); - /* auto-keyframing */ - ED_autokeyframe_pchan(C, scene, ob, pchan, ks); - } - /* if the bone has a parent and is connected to the parent, - * don't do anything - will break chain unless we do auto-ik. - */ - } - } + mul_m4_v3(obact->imat, cursor_pose); + BKE_armature_loc_pose_to_bone(pchan, cursor_pose, cursor_pose); } - ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK); - - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + else { + BKE_armature_loc_pose_to_bone(pchan, cursor_local, cursor_pose); + } + + /* copy new position */ + if ((pchan->protectflag & OB_LOCK_LOCX) == 0) + pchan->loc[0] = cursor_pose[0]; + if ((pchan->protectflag & OB_LOCK_LOCY) == 0) + pchan->loc[1] = cursor_pose[1]; + if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) + pchan->loc[2] = cursor_pose[2]; + + /* auto-keyframing */ + ED_autokeyframe_pchan(C, scene, obact, pchan, ks); } - else { + } + + for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) { + pchan->bone->flag &= ~BONE_TRANSFORM; + } + + obact->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK); + + DAG_id_tag_update(&obact->id, OB_RECALC_DATA); + } + else { + struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); + Main *bmain = CTX_data_main(C); + + ListBase ctx_data_list; + CollectionPointerLink *ctx_ob; + Object *ob; + + CTX_data_selected_editable_objects(C, &ctx_data_list); + + /* reset flags */ + for (ob = bmain->object.first; ob; ob = ob->id.next) { + ob->flag &= ~OB_DONE; + } + + /* tag objects we're transforming */ + for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) { + ob = ctx_ob->ptr.data; + ob->flag |= OB_DONE; + } + + for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) { + ob = ctx_ob->ptr.data; + + if ((ob->parent && BKE_object_flag_test_recursive(ob->parent, OB_DONE)) == 0) { + float cursor_parent[3]; /* parent-relative */ if (use_offset) { @@ -335,11 +376,11 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op) } sub_v3_v3(cursor_parent, ob->obmat[3]); - + if (ob->parent) { float originmat[3][3]; BKE_object_where_is_calc_ex(scene, NULL, ob, originmat); - + invert_m3_m3(imat, originmat); mul_m3_v3(imat, cursor_parent); } @@ -356,7 +397,8 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_OB); } } - CTX_DATA_END; + + BLI_freelistN(&ctx_data_list); } WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index b6d4a8c9db8..6b7e70f454b 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -188,7 +188,7 @@ typedef enum eBone_Flag { BONE_SELECTED = (1 << 0), BONE_ROOTSEL = (1 << 1), BONE_TIPSEL = (1 << 2), - BONE_TRANSFORM = (1 << 3), /* Used instead of BONE_SELECTED during transform */ + BONE_TRANSFORM = (1 << 3), /* Used instead of BONE_SELECTED during transform (clear before use) */ BONE_CONNECTED = (1 << 4), /* when bone has a parent, connect head of bone to parent's tail*/ /* 32 used to be quatrot, was always set in files, do not reuse unless you clear it always */ BONE_HIDDEN_P = (1 << 6), /* hidden Bones when drawing PoseChannels */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 0bcc6bfd70e..2699bb5f22f 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -510,7 +510,7 @@ enum { #define OB_FROMDUPLI (1 << 9) -#define OB_DONE (1 << 10) +#define OB_DONE (1 << 10) /* unknown state, clear before use */ /* #define OB_RADIO (1 << 11) */ /* deprecated */ #define OB_FROMGROUP (1 << 12) |