fix for all pose-group editing functions crashing when the context didnt have an...
authorCampbell Barton <ideasman42@gmail.com>
Sun, 23 Sep 2012 02:31:30 +0000 (02:31 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 23 Sep 2012 02:31:30 +0000 (02:31 +0000)
fix pose-group-sort and pose-group-moving being disabled for pinned poses.

also fix for own missing NULL check for pose mask clear which would crash when run without an active object

source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/object.c
source/blender/editors/armature/poseobject.c
source/blender/editors/include/ED_armature.h
source/blender/editors/include/ED_screen.h
source/blender/editors/mesh/mesh_data.c
source/blender/editors/screen/screen_ops.c

index 31642da..269d96d 100644 (file)
@@ -93,6 +93,7 @@ void BKE_object_to_mat3(struct Object *ob, float mat[][3]);
 void BKE_object_to_mat4(struct Object *ob, float mat[][4]);
 void BKE_object_apply_mat4(struct Object *ob, float mat[][4], const short use_compat, const short use_parent);
 
+int BKE_object_pose_context_check(struct Object *ob);
 struct Object *BKE_object_pose_armature_get(struct Object *ob);
 
 void BKE_object_where_is_calc(struct Scene *scene, struct Object *ob);
index 958e488..e659441 100644 (file)
@@ -1079,12 +1079,12 @@ static void copy_object_pose(Object *obn, Object *ob)
        }
 }
 
-static int object_pose_context(Object *ob)
+int BKE_object_pose_context_check(Object *ob)
 {
-       if ( (ob) &&
-            (ob->type == OB_ARMATURE) &&
-            (ob->pose) &&
-            (ob->mode & OB_MODE_POSE))
+       if ((ob) &&
+           (ob->type == OB_ARMATURE) &&
+           (ob->pose) &&
+           (ob->mode & OB_MODE_POSE))
        {
                return 1;
        }
@@ -1098,12 +1098,12 @@ Object *BKE_object_pose_armature_get(Object *ob)
        if (ob == NULL)
                return NULL;
 
-       if (object_pose_context(ob))
+       if (BKE_object_pose_context_check(ob))
                return ob;
 
        ob = modifiers_isDeformedByArmature(ob);
 
-       if (object_pose_context(ob))
+       if (BKE_object_pose_context_check(ob))
                return ob;
 
        return NULL;
index ac1766a..2f5eaab 100644 (file)
 
 #include "armature_intern.h"
 
+/* matches logic with ED_operator_posemode_context() */
+Object *ED_pose_object_from_context(bContext *C)
+{
+       ScrArea *sa = CTX_wm_area(C);
+       Object *ob;
+
+       /* since this call may also be used from the buttons window, we need to check for where to get the object */
+       if (sa && sa->spacetype == SPACE_BUTS) {
+               ob = ED_object_context(C);
+       }
+       else {
+               ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+       }
+
+       return ob;
+}
+
 /* This function is used to process the necessary updates for */
 void ED_armature_enter_posemode(bContext *C, Base *base)
 {
@@ -1331,15 +1348,8 @@ void POSE_OT_paste(wmOperatorType *ot)
 
 static int pose_group_add_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       ScrArea *sa = CTX_wm_area(C);
-       Object *ob;
-       
-       /* since this call may also be used from the buttons window, we need to check for where to get the object */
-       if (sa->spacetype == SPACE_BUTS) 
-               ob = ED_object_context(C);
-       else
-               ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
-               
+       Object *ob = ED_pose_object_from_context(C);
+
        /* only continue if there's an object */
        if (ob == NULL)
                return OPERATOR_CANCELLED;
@@ -1362,7 +1372,7 @@ void POSE_OT_group_add(wmOperatorType *ot)
        
        /* api callbacks */
        ot->exec = pose_group_add_exec;
-       ot->poll = ED_operator_posemode;
+       ot->poll = ED_operator_posemode_context;
        
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1371,14 +1381,7 @@ void POSE_OT_group_add(wmOperatorType *ot)
 
 static int pose_group_remove_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       ScrArea *sa = CTX_wm_area(C);
-       Object *ob;
-       
-       /* since this call may also be used from the buttons window, we need to check for where to get the object */
-       if (sa->spacetype == SPACE_BUTS) 
-               ob = ED_object_context(C);
-       else
-               ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+       Object *ob = ED_pose_object_from_context(C);
        
        /* only continue if there's an object */
        if (ob == NULL)
@@ -1402,7 +1405,7 @@ void POSE_OT_group_remove(wmOperatorType *ot)
        
        /* api callbacks */
        ot->exec = pose_group_remove_exec;
-       ot->poll = ED_operator_posemode;
+       ot->poll = ED_operator_posemode_context;
        
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1413,8 +1416,7 @@ void POSE_OT_group_remove(wmOperatorType *ot)
 /* invoke callback which presents a list of bone-groups for the user to choose from */
 static int pose_groups_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
 {
-       ScrArea *sa = CTX_wm_area(C);
-       Object *ob;
+       Object *ob = ED_pose_object_from_context(C);
        bPose *pose;
        
        uiPopupMenu *pup;
@@ -1422,12 +1424,6 @@ static int pose_groups_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(
        bActionGroup *grp;
        int i;
        
-       /* since this call may also be used from the buttons window, we need to check for where to get the object */
-       if (sa->spacetype == SPACE_BUTS) 
-               ob = ED_object_context(C);
-       else
-               ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
-       
        /* only continue if there's an object, and a pose there too */
        if (ELEM(NULL, ob, ob->pose)) 
                return OPERATOR_CANCELLED;
@@ -1466,17 +1462,10 @@ static int pose_groups_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(
 /* Assign selected pchans to the bone group that the user selects */
 static int pose_group_assign_exec(bContext *C, wmOperator *op)
 {
-       ScrArea *sa = CTX_wm_area(C);
-       Object *ob;
+       Object *ob = ED_pose_object_from_context(C);
        bPose *pose;
        short done = FALSE;
-       
-       /* since this call may also be used from the buttons window, we need to check for where to get the object */
-       if (sa->spacetype == SPACE_BUTS) 
-               ob = ED_object_context(C);
-       else
-               ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
-       
+
        /* only continue if there's an object, and a pose there too */
        if (ELEM(NULL, ob, ob->pose))
                return OPERATOR_CANCELLED;
@@ -1518,7 +1507,7 @@ void POSE_OT_group_assign(wmOperatorType *ot)
        /* api callbacks */
        ot->invoke = pose_groups_menu_invoke;
        ot->exec = pose_group_assign_exec;
-       ot->poll = ED_operator_posemode;
+       ot->poll = ED_operator_posemode_context;
        
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1530,16 +1519,9 @@ void POSE_OT_group_assign(wmOperatorType *ot)
 
 static int pose_group_unassign_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       ScrArea *sa = CTX_wm_area(C);
-       Object *ob;
+       Object *ob = ED_pose_object_from_context(C);
        short done = FALSE;
        
-       /* since this call may also be used from the buttons window, we need to check for where to get the object */
-       if (sa->spacetype == SPACE_BUTS) 
-               ob = ED_object_context(C);
-       else
-               ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
-       
        /* only continue if there's an object, and a pose there too */
        if (ELEM(NULL, ob, ob->pose))
                return OPERATOR_CANCELLED;
@@ -1573,7 +1555,7 @@ void POSE_OT_group_unassign(wmOperatorType *ot)
        
        /* api callbacks */
        ot->exec = pose_group_unassign_exec;
-       ot->poll = ED_operator_posemode;
+       ot->poll = ED_operator_posemode_context;
        
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1581,7 +1563,7 @@ void POSE_OT_group_unassign(wmOperatorType *ot)
 
 static int group_move_exec(bContext *C, wmOperator *op)
 {
-       Object *ob = ED_object_context(C);
+       Object *ob = ED_pose_object_from_context(C);
        bPose *pose = (ob) ? ob->pose : NULL;
        bPoseChannel *pchan;
        bActionGroup *grp;
@@ -1654,7 +1636,7 @@ void POSE_OT_group_move(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec = group_move_exec;
-       ot->poll = ED_operator_posemode;
+       ot->poll = ED_operator_posemode_context;
 
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1679,7 +1661,7 @@ static int compare_agroup(const void *sgrp_a_ptr, const void *sgrp_b_ptr)
 
 static int group_sort_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Object *ob = ED_object_context(C);
+       Object *ob = ED_pose_object_from_context(C);
        bPose *pose = (ob) ? ob->pose : NULL;
        bPoseChannel *pchan;
        tSortActionGroup *agrp_array;
@@ -1738,7 +1720,7 @@ void POSE_OT_group_sort(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec = group_sort_exec;
-       ot->poll = ED_operator_posemode;
+       ot->poll = ED_operator_posemode_context;
 
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1766,14 +1748,7 @@ static void pose_group_select(bContext *C, Object *ob, int select)
 
 static int pose_group_select_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       ScrArea *sa = CTX_wm_area(C);
-       Object *ob;
-       
-       /* since this call may also be used from the buttons window, we need to check for where to get the object */
-       if (sa->spacetype == SPACE_BUTS) 
-               ob = ED_object_context(C);
-       else
-               ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+       Object *ob = ED_pose_object_from_context(C);
        
        /* only continue if there's an object, and a pose there too */
        if (ELEM(NULL, ob, ob->pose))
@@ -1796,7 +1771,7 @@ void POSE_OT_group_select(wmOperatorType *ot)
        
        /* api callbacks */
        ot->exec = pose_group_select_exec;
-       ot->poll = ED_operator_posemode;
+       ot->poll = ED_operator_posemode_context;
        
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1804,14 +1779,7 @@ void POSE_OT_group_select(wmOperatorType *ot)
 
 static int pose_group_deselect_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       ScrArea *sa = CTX_wm_area(C);
-       Object *ob;
-       
-       /* since this call may also be used from the buttons window, we need to check for where to get the object */
-       if (sa->spacetype == SPACE_BUTS) 
-               ob = ED_object_context(C);
-       else
-               ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+       Object *ob = ED_pose_object_from_context(C);
        
        /* only continue if there's an object, and a pose there too */
        if (ELEM(NULL, ob, ob->pose))
@@ -1834,7 +1802,7 @@ void POSE_OT_group_deselect(wmOperatorType *ot)
        
        /* api callbacks */
        ot->exec = pose_group_deselect_exec;
-       ot->poll = ED_operator_posemode;
+       ot->poll = ED_operator_posemode_context;
        
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
index 07f3498..4e33404 100644 (file)
@@ -148,6 +148,7 @@ void ED_armature_enter_posemode(struct bContext *C, struct Base *base);
 int ED_pose_channel_in_IK_chain(struct Object *ob, struct bPoseChannel *pchan);
 void ED_pose_deselectall(struct Object *ob, int test);
 void ED_pose_recalculate_paths(struct Scene *scene, struct Object *ob);
+struct Object *ED_pose_object_from_context(struct bContext *C);
 
 /* sketch */
 
index 2e40f8b..860d176 100644 (file)
@@ -171,6 +171,7 @@ int     ED_operator_editmball(struct bContext *C);
 int     ED_operator_uvedit(struct bContext *C);
 int     ED_operator_uvmap(struct bContext *C);
 int     ED_operator_posemode_exclusive(struct bContext *C);
+int     ED_operator_posemode_context(struct bContext *C);
 int     ED_operator_posemode(struct bContext *C);
 int     ED_operator_mask(struct bContext *C);
 
index 60df657..a52c8d4 100644 (file)
@@ -772,14 +772,14 @@ static int mesh_customdata_clear_exec__internal(bContext *C,
 static int mesh_customdata_clear_mask_poll(bContext *C)
 {
        Object *ob = ED_object_context(C);
-
-       /* special case - can't run this if we're in sculpt mode */
-       if (ob->mode & OB_MODE_SCULPT) {
-               return FALSE;
-       }
-
        if (ob && ob->type == OB_MESH) {
                Mesh *me = ob->data;
+
+               /* special case - can't run this if we're in sculpt mode */
+               if (ob->mode & OB_MODE_SCULPT) {
+                       return FALSE;
+               }
+
                if (me->id.lib == NULL) {
                        CustomData *data = GET_CD_DATA(me, vdata);
                        if (CustomData_has_layer(data, CD_PAINT_MASK)) {
index 54d4ec7..c64a4a3 100644 (file)
@@ -372,6 +372,21 @@ int ED_operator_posemode_exclusive(bContext *C)
        return 0;
 }
 
+/* allows for pinned pose objects to be used in the object buttons
+ * and the the non-active pose object to be used in the 3D view */
+int ED_operator_posemode_context(bContext *C)
+{
+       Object *obpose = ED_pose_object_from_context(C);
+
+       if (obpose && !(obpose->mode & OB_MODE_EDIT)) {
+               if (BKE_object_pose_context_check(obpose)) {
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
 int ED_operator_posemode(bContext *C)
 {
        Object *obact = CTX_data_active_object(C);