svn merge ^/trunk/blender -r42466:42495
[blender-staging.git] / source / blender / editors / space_view3d / view3d_snap.c
index efa7837087a1821cccc0f20f0f895ad5a586f744..cf61fe9281428cc9e019023cb70fbb21e919ed1a 100644 (file)
@@ -94,9 +94,7 @@ static int tottrans= 0;
 /* copied from editobject.c, now uses (almost) proper depgraph */
 static void special_transvert_update(Object *obedit)
 {
-       
        if(obedit) {
-               
                DAG_id_tag_update(obedit->data, 0);
                
                if(obedit->type==OB_MESH) {
@@ -180,7 +178,7 @@ static void special_transvert_update(Object *obedit)
                                        }
                                }
                        }
-                       if(arm->flag & ARM_MIRROR_EDIT) 
+                       if(arm->flag & ARM_MIRROR_EDIT)
                                transform_armature_mirror_update(obedit);
                }
                else if(obedit->type==OB_LATTICE) {
@@ -209,7 +207,7 @@ static void set_mapped_co(void *vuserdata, int index, float *co, float *UNUSED(n
 /* mode flags: */
 #define TM_ALL_JOINTS          1 /* all joints (for bones only) */
 #define TM_SKIP_HANDLES                2 /* skip handles when control point is selected (for curves only) */
-static void make_trans_verts(Object *obedit, float *min, float *max, int mode) 
+static void make_trans_verts(Object *obedit, float *min, float *max, int mode)
 {
        Nurb *nu;
        BezTriple *bezt;
@@ -337,7 +335,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode)
                                if ((tipsel && rootsel) || (rootsel)) {
                                        /* Don't add the tip (unless mode & TM_ALL_JOINTS, for getting all joints),
                                         * otherwise we get zero-length bones as tips will snap to the same
-                                        * location as heads. 
+                                        * location as heads.
                                         */
                                        if (rootok) {
                                                copy_v3_v3(tv->oldloc, ebo->head);
@@ -355,7 +353,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode)
                                                tv->flag= 1;
                                                tv++;
                                                tottrans++;
-                                       }                                       
+                                       }
                                }
                                else if (tipsel) {
                                        copy_v3_v3(tv->oldloc, ebo->tail);
@@ -365,7 +363,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode)
                                        tv++;
                                        tottrans++;
                                }
-                       }                       
+                       }
                }
        }
        else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
@@ -524,7 +522,7 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
        if(obedit) {
                tottrans= 0;
                
-               if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) 
+               if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)
                        make_trans_verts(obedit, bmat[0], bmat[1], 0);
                if(tottrans==0) return OPERATOR_CANCELLED;
                
@@ -533,7 +531,6 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
                
                tv= transvmain;
                for(a=0; a<tottrans; a++, tv++) {
-                       
                        copy_v3_v3(vec, tv->loc);
                        mul_m3_v3(bmat, vec);
                        add_v3_v3(vec, obedit->obmat[3]);
@@ -550,7 +547,6 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
                
                MEM_freeN(transvmain);
                transvmain= NULL;
-       
        }
        else {
                struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
@@ -560,34 +556,42 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
                                bPoseChannel *pchan;
                                bArmature *arm= ob->data;
                                
+                               invert_m4_m4(ob->imat, ob->obmat);
+                               
                                for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                                        if(pchan->bone->flag & BONE_SELECTED) {
                                                if(pchan->bone->layer & arm->layer) {
-                                                       if((pchan->bone->flag & BONE_CONNECTED)==0) { 
-                                                               float vecN[3], nLoc[3]; 
+                                                       if((pchan->bone->flag & BONE_CONNECTED)==0) {
+                                                               float nLoc[3];
+                                                               float inv_restmat[4][4];
                                                                
                                                                /* get nearest grid point to snap to */
                                                                copy_v3_v3(nLoc, pchan->pose_mat[3]);
+                                                               /* We must operate in world space! */
+                                                               mul_m4_v3(ob->obmat, nLoc);
                                                                vec[0]= gridf * (float)(floor(0.5f+ nLoc[0]/gridf));
                                                                vec[1]= gridf * (float)(floor(0.5f+ nLoc[1]/gridf));
                                                                vec[2]= gridf * (float)(floor(0.5f+ nLoc[2]/gridf));
+                                                               /* Back in object space... */
+                                                               mul_m4_v3(ob->imat, vec);
                                                                
-                                                               /* get bone-space location of grid point */
-                                                               armature_loc_pose_to_bone(pchan, vec, vecN);
+                                                               /* get location of grid point in *rest* bone-space */
+                                                               invert_m4_m4(inv_restmat, pchan->bone->arm_mat);
+                                                               mul_m4_v3(inv_restmat, vec);
                                                                
                                                                /* adjust location */
-                                                               if ((pchan->protectflag & OB_LOCK_LOCX)==0)     
-                                                                       pchan->loc[0]= vecN[0];
-                                                               if ((pchan->protectflag & OB_LOCK_LOCY)==0)     
-                                                                       pchan->loc[0]= vecN[1];
-                                                               if ((pchan->protectflag & OB_LOCK_LOCZ)==0)     
-                                                                       pchan->loc[0]= vecN[2];
+                                                               if ((pchan->protectflag & OB_LOCK_LOCX)==0)
+                                                                       pchan->loc[0]= vec[0];
+                                                               if ((pchan->protectflag & OB_LOCK_LOCY)==0)
+                                                                       pchan->loc[1]= vec[1];
+                                                               if ((pchan->protectflag & OB_LOCK_LOCZ)==0)
+                                                                       pchan->loc[2]= vec[2];
 
                                                                /* 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. 
+                                                       /* if the bone has a parent and is connected to the parent,
+                                                        * don't do anything - will break chain unless we do auto-ik.
                                                         */
                                                }
                                        }
@@ -631,7 +635,6 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
 
 void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
 {
-       
        /* identifiers */
        ot->name= "Snap Selection to Grid";
        ot->description= "Snap selected item(s) to nearest grid node";
@@ -662,7 +665,7 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
        if(obedit) {
                tottrans= 0;
                
-               if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) 
+               if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)
                        make_trans_verts(obedit, bmat[0], bmat[1], 0);
                if(tottrans==0) return OPERATOR_CANCELLED;
                
@@ -680,7 +683,6 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
                
                MEM_freeN(transvmain);
                transvmain= NULL;
-               
        }
        else {
                struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
@@ -689,34 +691,34 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
                        if(ob->mode & OB_MODE_POSE) {
                                bPoseChannel *pchan;
                                bArmature *arm= ob->data;
-                               float cursp[3];
                                
                                invert_m4_m4(ob->imat, ob->obmat);
-                               copy_v3_v3(cursp, curs);
-                               mul_m4_v3(ob->imat, cursp);
+                               copy_v3_v3(vec, curs);
+                               mul_m4_v3(ob->imat, vec);
                                
                                for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) {
                                        if(pchan->bone->flag & BONE_SELECTED) {
                                                if(pchan->bone->layer & arm->layer) {
-                                                       if((pchan->bone->flag & BONE_CONNECTED)==0) { 
-                                                               float curspn[3];
+                                                       if((pchan->bone->flag & BONE_CONNECTED)==0) {
+                                                               float inv_restmat[4][4];
                                                                
-                                                               /* get location of cursor in bone-space */
-                                                               armature_loc_pose_to_bone(pchan, cursp, curspn);
+                                                               /* get location of cursor in *rest* bone-space */
+                                                               invert_m4_m4(inv_restmat, pchan->bone->arm_mat);
+                                                               mul_m4_v3(inv_restmat, vec);
                                                                
                                                                /* copy new position */
-                                                               if ((pchan->protectflag & OB_LOCK_LOCX)==0)     
-                                                                       pchan->loc[0]= curspn[0];
-                                                               if ((pchan->protectflag & OB_LOCK_LOCY)==0)     
-                                                                       pchan->loc[1]= curspn[1];
-                                                               if ((pchan->protectflag & OB_LOCK_LOCZ)==0)     
-                                                                       pchan->loc[2]= curspn[2];
+                                                               if ((pchan->protectflag & OB_LOCK_LOCX)==0)
+                                                                       pchan->loc[0]= vec[0];
+                                                               if ((pchan->protectflag & OB_LOCK_LOCY)==0)
+                                                                       pchan->loc[1]= vec[1];
+                                                               if ((pchan->protectflag & OB_LOCK_LOCZ)==0)
+                                                                       pchan->loc[2]= vec[2];
 
                                                                /* 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. 
+                                                       /* if the bone has a parent and is connected to the parent,
+                                                        * don't do anything - will break chain unless we do auto-ik.
                                                         */
                                                }
                                        }
@@ -760,7 +762,6 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
 
 void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
 {
-       
        /* identifiers */
        ot->name= "Snap Selection to Cursor";
        ot->description= "Snap selected item(s) to cursor";
@@ -797,7 +798,6 @@ static int snap_curs_to_grid(bContext *C, wmOperator *UNUSED(op))
 
 void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
 {
-       
        /* identifiers */
        ot->name= "Snap Cursor to Grid";
        ot->description= "Snap cursor to nearest grid node";
@@ -862,7 +862,7 @@ static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op))
        if(obedit) {
                tottrans=0;
                
-               if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) 
+               if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)
                        make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS|TM_SKIP_HANDLES);
                if(tottrans==0) return OPERATOR_CANCELLED;
                
@@ -940,10 +940,9 @@ static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op))
 
 void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
 {
-       
        /* identifiers */
        ot->name= "Snap Cursor to Selected";
-       ot->description= "Snap cursor to center of selected item(s)"; 
+       ot->description= "Snap cursor to center of selected item(s)";
        ot->idname= "VIEW3D_OT_snap_cursor_to_selected";
        
        /* api callbacks */
@@ -991,7 +990,6 @@ static int snap_curs_to_active(bContext *C, wmOperator *UNUSED(op))
 
 void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
 {
-       
        /* identifiers */
        ot->name= "Snap Cursor to Active";
        ot->description= "Snap cursor to active item";
@@ -1025,13 +1023,12 @@ static int snap_curs_to_center(bContext *C, wmOperator *UNUSED(op))
 
 void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot)
 {
-       
        /* identifiers */
        ot->name= "Snap Cursor to Center";
        ot->description= "Snap cursor to the Center";
        ot->idname= "VIEW3D_OT_snap_cursor_to_center";
        
-       /* api callbacks */ 
+       /* api callbacks */
        ot->exec= snap_curs_to_center;
        ot->poll= ED_operator_view3d_active;
        
@@ -1049,7 +1046,7 @@ int minmax_verts(Object *obedit, float *min, float *max)
        int a;
 
        tottrans=0;
-       if ELEM5(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) 
+       if ELEM5(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE)
                make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS);
        
        if(tottrans==0) return 0;
@@ -1057,12 +1054,12 @@ int minmax_verts(Object *obedit, float *min, float *max)
        copy_m3_m4(bmat, obedit->obmat);
        
        tv= transvmain;
-       for(a=0; a<tottrans; a++, tv++) {               
+       for(a=0; a<tottrans; a++, tv++) {
                copy_v3_v3(vec, tv->maploc);
                mul_m3_v3(bmat, vec);
                add_v3_v3(vec, obedit->obmat[3]);
                add_v3_v3(centroid, vec);
-               DO_MINMAX(vec, min, max);               
+               DO_MINMAX(vec, min, max);
        }
        
        MEM_freeN(transvmain);