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:
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_snap.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c223
1 files changed, 146 insertions, 77 deletions
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 8e6deeddc39..0608c35129d 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -33,15 +33,18 @@
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_object_types.h"
+#include "DNA_meta_types.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BKE_action.h"
#include "BKE_armature.h"
#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"
@@ -53,13 +56,16 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "ED_object.h"
#include "ED_transverts.h"
#include "ED_keyframing.h"
#include "ED_screen.h"
+#include "ED_curve.h"
#include "view3d_intern.h"
static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]);
+static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3]);
/* *********************** operators ******************** */
@@ -205,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;
@@ -221,7 +228,14 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op)
cursor_global = ED_view3d_cursor3d_get(scene, v3d);
if (use_offset) {
- snap_curs_to_sel_ex(C, center_global);
+ if ((v3d && v3d->around == V3D_ACTIVE) &&
+ snap_calc_active_center(C, true, center_global))
+ {
+ /* pass */
+ }
+ else {
+ snap_curs_to_sel_ex(C, center_global);
+ }
sub_v3_v3v3(offset_global, cursor_global, center_global);
}
@@ -260,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) {
@@ -323,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);
}
@@ -344,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);
@@ -592,45 +646,60 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
/* ********************************************** */
-static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op))
+/* this could be exported to be a generic function
+ * see: calculateCenterActive */
+
+static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3])
{
Object *obedit = CTX_data_edit_object(C);
- Object *obact = CTX_data_active_object(C);
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- float *curs;
-
- curs = ED_view3d_cursor3d_get(scene, v3d);
if (obedit) {
- if (obedit->type == OB_MESH) {
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- /* check active */
- BMEditSelection ese;
-
- if (BM_select_history_active_get(em->bm, &ese)) {
- BM_editselection_center(&ese, curs);
- }
-
- mul_m4_v3(obedit->obmat, curs);
+ if (ED_object_editmode_calc_active_center(obedit, select_only, r_center)) {
+ mul_m4_v3(obedit->obmat, r_center);
+ return true;
}
- else if (obedit->type == OB_LATTICE) {
- BPoint *actbp = BKE_lattice_active_point_get(obedit->data);
+ }
+ else {
+ Object *ob = CTX_data_active_object(C);
- if (actbp) {
- copy_v3_v3(curs, actbp->vec);
- mul_m4_v3(obedit->obmat, curs);
+ if (ob) {
+ if (ob->mode & OB_MODE_POSE) {
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+ if (pchan) {
+ if (!select_only || (pchan->bone->flag & BONE_SELECTED)) {
+ copy_v3_v3(r_center, pchan->pose_head);
+ mul_m4_v3(ob->obmat, r_center);
+ return true;
+ }
+ }
+ }
+ else {
+ if (!select_only || (ob->flag & SELECT)) {
+ copy_v3_v3(r_center, ob->obmat[3]);
+ return true;
+ }
}
}
}
+
+ return false;
+}
+
+static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ float *curs;
+
+ curs = ED_view3d_cursor3d_get(scene, v3d);
+
+ if (snap_calc_active_center(C, false, curs)) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ return OPERATOR_FINISHED;
+ }
else {
- if (obact) {
- copy_v3_v3(curs, obact->obmat[3]);
- }
+ return OPERATOR_CANCELLED;
}
-
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
- return OPERATOR_FINISHED;
}
void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)