Armature Editing Bugfixes:
authorJoshua Leung <aligorith@gmail.com>
Thu, 5 Nov 2009 08:54:33 +0000 (08:54 +0000)
committerJoshua Leung <aligorith@gmail.com>
Thu, 5 Nov 2009 08:54:33 +0000 (08:54 +0000)
* #19790: Circle Select doesn't work for Armature edit mode or pose mode
* Duplicate bones (Shift-D) was calling the wrong operator. This now uses the macro version, instead of the copy only.

source/blender/editors/animation/drivers.c
source/blender/editors/animation/keyframing.c
source/blender/editors/armature/armature_ops.c
source/blender/editors/space_view3d/view3d_select.c

index 5442598a2616901b9eb947b44b615e4bca67ee59..5c2cbce4c5d55949da4255023ecd0b6f36f5d4bd 100644 (file)
@@ -156,17 +156,17 @@ short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short fla
                return 0;
        }
        
-       if(array_index==-1) { /* Key All */
+       /* key entire array convenience method */
+       if (array_index == -1) {
                array_index= 0;
                array_index_max= RNA_property_array_length(&ptr, prop) + 1;
        }
-
+       
        /* will only loop once unless the array index was -1 */
-       for( ; array_index < array_index_max; array_index++) {
-               
+       for (; array_index < array_index_max; array_index++) {
                /* create F-Curve with Driver */
                fcu= verify_driver_fcurve(id, rna_path, array_index, 1);
-
+               
                if (fcu && fcu->driver) {
                        fcu->driver->type= type;
                        
@@ -181,19 +181,19 @@ short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short fla
                                if (proptype == PROP_BOOLEAN) {
                                        if (!array) val= RNA_property_boolean_get(&ptr, prop);
                                        else val= RNA_property_boolean_get_index(&ptr, prop, array_index);
-
+                                       
                                        BLI_strncpy(expression, (val)? "True": "False", maxlen);
                                }
                                else if (proptype == PROP_INT) {
                                        if (!array) val= RNA_property_int_get(&ptr, prop);
                                        else val= RNA_property_int_get_index(&ptr, prop, array_index);
-
+                                       
                                        BLI_snprintf(expression, maxlen, "%d", val);
                                }
                                else if (proptype == PROP_FLOAT) {
                                        if (!array) fval= RNA_property_float_get(&ptr, prop);
                                        else fval= RNA_property_float_get_index(&ptr, prop, array_index);
-
+                                       
                                        BLI_snprintf(expression, maxlen, "%.3f", fval);
                                }
                        }
index 13ff8c84b7ad79318013d58d2512c4094fd6c5e6..0412ee89e517135ede0feccb2e6d2ba3b6b5ead8 100644 (file)
@@ -832,20 +832,21 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
                //}
        }
 #endif
-
-       if(array_index==-1) { /* Key All */
+       
+       /* key entire array convenience method */
+       if (array_index == -1) { 
                array_index= 0;
                array_index_max= RNA_property_array_length(&ptr, prop) + 1;
        }
-
+       
        /* will only loop once unless the array index was -1 */
-       for; array_index < array_index_max; array_index++) {
+       for (; array_index < array_index_max; array_index++) {
                fcu= verify_fcurve(act, group, rna_path, array_index, 1);
-
+               
                /* insert keyframe */
-               ret |= insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
+               ret += insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
        }
-
+       
        return ret;
 }
 
index 159effe0960b79f64c2504ee826a6c96adaa49d3..e49e3d99c495c9d2aa0d0f4aa9635ee8d1337e15 100644 (file)
@@ -232,7 +232,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
        
        WM_keymap_add_item(keymap, "ARMATURE_OT_delete", XKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "ARMATURE_OT_delete", DELKEY, KM_PRESS, 0, 0);
-       WM_keymap_add_item(keymap, "ARMATURE_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
+       WM_keymap_add_item(keymap, "ARMATURE_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
        WM_keymap_add_item(keymap, "ARMATURE_OT_extrude_move", EKEY, KM_PRESS, 0, 0);
        kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_extrude_move", EKEY, KM_PRESS, KM_SHIFT, 0);
        //      RNA_boolean_set(kmi->ptr, "forked", 1); // XXX this doesn't work ok for macros it seems...
index b13d83c01573a3b01b018e0d9075d2676abe846b..0c90347063fc0d6568253aba3c7b8c4836606e23 100644 (file)
@@ -1810,6 +1810,79 @@ static void lattice_circle_select(ViewContext *vc, int selecting, short *mval, f
        lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data);
 }
 
+
+static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head)
+{
+       struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData;
+       int mx = x - data->mval[0], my = y - data->mval[1];
+       float r = sqrt(mx*mx + my*my);
+       
+       if (r <= data->radius) {
+               if (head) {
+                       if (data->select)
+                               ebone->flag |= BONE_ROOTSEL;
+                       else 
+                               ebone->flag &= ~BONE_ROOTSEL;
+               }
+               else {
+                       if (data->select)
+                               ebone->flag |= BONE_TIPSEL;
+                       else 
+                               ebone->flag &= ~BONE_TIPSEL;
+               }
+               return 1;
+       }
+       return 0;
+}
+static void armature_circle_select(ViewContext *vc, int selecting, short *mval, float rad)
+{
+       struct {ViewContext *vc; short select, mval[2]; float radius; } data;
+       bArmature *arm= vc->obedit->data;
+       EditBone *ebone;
+       
+       /* set vc->edit data */
+       data.select = selecting;
+       data.mval[0] = mval[0];
+       data.mval[1] = mval[1];
+       data.radius = rad;
+
+       ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+       
+       /* check each EditBone... */
+       // TODO: could be optimised at some point
+       for (ebone= arm->edbo->first; ebone; ebone=ebone->next) {
+               short sco1[2], sco2[2], didpoint=0;
+               float vec[3];
+               
+               /* project head location to screenspace */
+               VECCOPY(vec, ebone->head);
+               Mat4MulVecfl(vc->obedit->obmat, vec);
+               project_short(vc->ar, vec, sco1);
+               
+               /* project tail location to screenspace */
+               VECCOPY(vec, ebone->tail);
+               Mat4MulVecfl(vc->obedit->obmat, vec);
+               project_short(vc->ar, vec, sco2);
+               
+               /* check if the head and/or tail is in the circle 
+                *      - the call to check also does the selection already
+                */
+               if (armature_circle_doSelectJoint(&data, ebone, sco1[0], sco1[1], 1))
+                       didpoint= 1;
+               if (armature_circle_doSelectJoint(&data, ebone, sco2[0], sco2[1], 0))
+                       didpoint= 1;
+                       
+               /* only if the endpoints didn't get selected, deal with the middle of the bone too */
+               // XXX should we just do this always?
+               if ( (didpoint==0) && edge_inside_circle(mval[0], mval[1], rad, sco1[0], sco1[1], sco2[0], sco2[1]) ) {
+                       if (selecting) 
+                               ebone->flag |= BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED;
+                       else 
+                               ebone->flag &= ~(BONE_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); 
+               }
+       }
+}
+
 /** Callbacks for circle selection in Editmode */
 
 static void obedit_circle_select(ViewContext *vc, short selecting, short *mval, float rad) 
@@ -1825,6 +1898,9 @@ static void obedit_circle_select(ViewContext *vc, short selecting, short *mval,
        case OB_LATTICE:
                lattice_circle_select(vc, selecting, mval, rad);
                break;
+       case OB_ARMATURE:
+               armature_circle_select(vc, selecting, mval, rad);
+               break;
        default:
                return;
        }