svn merge -r40197:40311 ^/trunk/blender
[blender-staging.git] / source / blender / editors / armature / editarmature.c
index 08f313bfadd3753c323345060ab192b56329f3c3..9a6be695555f3f21e79a9351b1d4d0b97172d385 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id$
- *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -363,7 +361,7 @@ static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist)
                        print_m4("premat", premat);
                        print_m4("postmat", postmat);
                        print_m4("difmat", difmat);
-                       printf ("Roll = %f\n",  (-atan2(difmat[2][0], difmat[2][2]) * (180.0/M_PI)));
+                       printf ("Roll = %f\n",  RAD2DEGF(-atan2(difmat[2][0], difmat[2][2])));
 #endif
                        curBone->roll = (float)-atan2(difmat[2][0], difmat[2][2]);
                        
@@ -645,7 +643,7 @@ static void applyarmature_fix_boneparents (Scene *scene, Object *armob)
 static int apply_armature_pose2bones_exec (bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
-       Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); // must be active object, not edit-object
+       Object *ob= object_pose_armature_get(CTX_data_active_object(C)); // must be active object, not edit-object
        bArmature *arm= get_armature(ob);
        bPose *pose;
        bPoseChannel *pchan;
@@ -747,7 +745,7 @@ void POSE_OT_armature_apply (wmOperatorType *ot)
 /* set the current pose as the restpose */
 static int pose_visual_transform_apply_exec (bContext *C, wmOperator *UNUSED(op))
 {
-       Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); // must be active object, not edit-object
+       Object *ob= object_pose_armature_get(CTX_data_active_object(C)); // must be active object, not edit-object
 
        /* don't check if editmode (should be done by caller) */
        if (ob->type!=OB_ARMATURE)
@@ -3008,28 +3006,31 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone
        /* TODO, copy more things to the new bone */
        newbone->flag= start->flag & (BONE_HINGE|BONE_NO_DEFORM|BONE_NO_SCALE|BONE_NO_CYCLICOFFSET|BONE_NO_LOCAL_LOCATION|BONE_DONE);
        
-       /* step 2a: parent children of in-between bones to newbone */
-       for (chain= chains->first; chain; chain= chain->next) {
-               /* ick: we need to check if parent of each bone in chain is one of the bones in the */
-               short found= 0;
-               for (ebo= chain->data; ebo; ebo= ebo->parent) {
+       /* step 2a: reparent any side chains which may be parented to any bone in the chain of bones to merge 
+        *      - potentially several tips for side chains leading to some tree exist...
+        */
+       for (chain = chains->first; chain; chain = chain->next) {
+               /* traverse down chain until we hit the bottom or if we run into the tip of the chain of bones we're 
+                * merging (need to stop in this case to avoid corrupting this chain too!) 
+                */
+               for (ebone = chain->data; (ebone) && (ebone != end); ebone = ebone->parent) {
+                       short found = 0;
                        
-                       /* try to find which bone from the list to be removed, is the parent */
-                       for (ebone= end; ebone; ebone= ebone->parent) {
-                               if (ebo->parent == ebone) {
-                                       found= 1;
+                       /* check if this bone is parented to one in the merging chain
+                        * ! WATCHIT: must only go check until end of checking chain
+                        */
+                       for (ebo = end; (ebo) && (ebo != start->parent); ebo = ebo->parent) {
+                               /* side-chain found? --> remap parent to new bone, then we're done with this chain :) */
+                               if (ebone->parent == ebo) {
+                                       ebone->parent = newbone;
+                                       found = 1;
                                        break;
                                }
                        }
                        
-                       /* adjust this bone's parent to newbone then */
-                       if (found) {
-                               ebo->parent= newbone;
+                       /* carry on to the next tip now  */
+                       if (found) 
                                break;
-                       }
-               }
-               if (found) {
-                       break;
                }
        }
        
@@ -3065,12 +3066,12 @@ static int armature_merge_exec (bContext *C, wmOperator *op)
                LinkData *chain, *nchain;
                EditBone *ebo;
                
+               armature_tag_select_mirrored(arm);
+               
                /* get chains (ends on chains) */
                chains_find_tips(arm->edbo, &chains);
                if (chains.first == NULL) return OPERATOR_CANCELLED;
-
-               armature_tag_select_mirrored(arm);
-
+               
                /* each 'chain' is the last bone in the chain (with no children) */
                for (chain= chains.first; chain; chain= nchain) {
                        EditBone *bstart= NULL, *bend= NULL;
@@ -3115,7 +3116,7 @@ static int armature_merge_exec (bContext *C, wmOperator *op)
                }               
                
                armature_tag_unselect(arm);
-
+               
                BLI_freelistN(&chains);
        }
        
@@ -4275,30 +4276,74 @@ static int bone_looper(Object *ob, Bone *bone, void *data,
        
        return count;
 }
+// Jason
+Bone* get_other_selected_bone(Object *ob) {
+       Bone *bone;
+       int i;
+       bone = get_indexed_bone(ob, 0);
+       for(i = 0; bone;){
+               if(bone->flag & BONE_SELECTED) {
+                       return bone;
+               }
+               i++;
+               bone = get_indexed_bone(ob, i);
+       }
 
+       return NULL;
+}
 /* called from editview.c, for mode-less pose selection */
 /* assumes scene obact and basact is still on old situation */
 int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short extend)
 {
        Object *ob= base->object;
        Bone *nearBone;
-       
+
        if (!ob || !ob->pose) return 0;
 
        nearBone= get_bone_from_selectbuffer(scene, base, buffer, hits, 1);
-       
+
        /* if the bone cannot be affected, don't do anything */
        if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
                bArmature *arm= ob->data;
                
                /* since we do unified select, we don't shift+select a bone if the armature object was not active yet */
-               if (!(extend) || (base != scene->basact)) {
+               /* Jason was here, I'm doing a select for multibone painting */
+               if (scene->toolsettings->multipaint && (base != scene->basact)) {//if (!(extend) || (base != scene->basact)) {
+                       Bone *new_act_bone;
+                       /* Jason was here */
+                       /* only deselect all if they aren't using 'shift' */
+                       if(!extend) {
+                               ED_pose_deselectall(ob, 0);
+                               nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                               arm->act_bone= nearBone;
+                               ED_vgroup_select_by_name(OBACT, nearBone->name);
+                       }
+                       else {
+                               // Jason deselect this bone specifically if it is selected already
+                               if (nearBone->flag & BONE_SELECTED) {
+                                       nearBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                                       if(nearBone == arm->act_bone) {
+                                               // make a different bone the active one if it exists
+                                               new_act_bone = get_other_selected_bone(ob);
+                                               if(new_act_bone) {
+                                                       new_act_bone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                                                       arm->act_bone = new_act_bone;
+                                                       ED_vgroup_select_by_name(OBACT, new_act_bone->name);
+                                               }
+                                       }
+                               // or select the bone if they are using shift
+                               } else {
+                                       nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                                       arm->act_bone= nearBone;
+                               }
+                       } 
+                       DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA);
+                               // XXX old cruft! use notifiers instead
+                       //select_actionchannel_by_name(ob->action, nearBone->name, 1);
+               } else if (!(extend) || (base != scene->basact)) {
                        ED_pose_deselectall(ob, 0);
                        nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
                        arm->act_bone= nearBone;
-                       
-                               // XXX old cruft! use notifiers instead
-                       //select_actionchannel_by_name(ob->action, nearBone->name, 1);
                }
                else {
                        if (nearBone->flag & BONE_SELECTED) {
@@ -4885,7 +4930,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
                void (*clear_func)(bPoseChannel*), const char default_ksName[])
 {
        Scene *scene= CTX_data_scene(C);
-       Object *ob= ED_object_pose_armature(CTX_data_active_object(C));
+       Object *ob= object_pose_armature_get(CTX_data_active_object(C));
        short autokey = 0;
        
        /* sanity checks */
@@ -5060,6 +5105,10 @@ void POSE_OT_select_inverse(wmOperatorType *ot)
 static int pose_de_select_all_exec(bContext *C, wmOperator *op)
 {
        int action = RNA_enum_get(op->ptr, "action");
+       //Jason
+       Object *ob = NULL;
+       Scene *scene= CTX_data_scene(C);
+       int multipaint = scene->toolsettings->multipaint;
 
        if (action == SEL_TOGGLE) {
                action= CTX_DATA_COUNT(C, selected_pose_bones) ? SEL_DESELECT : SEL_SELECT;
@@ -5089,7 +5138,12 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
        CTX_DATA_END;
 
        WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL);
-       
+       // Jason
+       if(multipaint) {
+               ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       }
+
        return OPERATOR_FINISHED;
 }
 
@@ -5112,7 +5166,7 @@ void POSE_OT_select_all(wmOperatorType *ot)
 
 static int pose_select_parent_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Object *ob= ED_object_pose_armature(CTX_data_active_object(C));
+       Object *ob= object_pose_armature_get(CTX_data_active_object(C));
        bPoseChannel *pchan,*parent;
 
        /*      Determine if there is an active bone */
@@ -5188,7 +5242,7 @@ static int hide_unselected_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr
 /* active object is armature in posemode, poll checked */
 static int pose_hide_exec(bContext *C, wmOperator *op) 
 {
-       Object *ob= ED_object_pose_armature(CTX_data_active_object(C));
+       Object *ob= object_pose_armature_get(CTX_data_active_object(C));
        bArmature *arm= ob->data;
 
        if(RNA_boolean_get(op->ptr, "unselected"))
@@ -5237,7 +5291,7 @@ static int show_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
 /* active object is armature in posemode, poll checked */
 static int pose_reveal_exec(bContext *C, wmOperator *UNUSED(op)) 
 {
-       Object *ob= ED_object_pose_armature(CTX_data_active_object(C));
+       Object *ob= object_pose_armature_get(CTX_data_active_object(C));
        bArmature *arm= ob->data;
        
        bone_looper(ob, arm->bonebase.first, NULL, show_pose_bone_cb);