diff options
Diffstat (limited to 'source/blender/editors/armature/poseobject.c')
-rw-r--r-- | source/blender/editors/armature/poseobject.c | 412 |
1 files changed, 259 insertions, 153 deletions
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 54d052d52b5..c5ae60e982b 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -36,6 +36,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_dynstr.h" +#include "BLI_utildefines.h" #include "DNA_anim_types.h" #include "DNA_armature_types.h" @@ -70,14 +71,39 @@ #include "armature_intern.h" -/* ************* XXX *************** */ -static int pupmenu(const char *dummy) {return 0;} -static void error(const char *dummy) {}; -static void BIF_undo_push(const char *dummy) {} -/* ************* XXX *************** */ +static int object_pose_context(Object *ob) +{ + if( (ob) && + (ob->type == OB_ARMATURE) && + (ob->pose) && + (ob->mode & OB_MODE_POSE) + ) { + return 1; + } + else { + return 0; + } +} + +Object *ED_object_pose_armature(Object *ob) +{ + if(ob==NULL) + return NULL; + + if(object_pose_context(ob)) + return ob; + + ob= modifiers_isDeformedByArmature(ob); + + if(object_pose_context(ob)) + return ob; + + return NULL; +} + /* This function is used to indicate that a bone is selected and needs keyframes inserted */ -void set_pose_keys (Object *ob) +static void set_pose_keys (Object *ob) { bArmature *arm= ob->data; bPoseChannel *chan; @@ -96,14 +122,15 @@ void set_pose_keys (Object *ob) /* This function is used to process the necessary updates for */ void ED_armature_enter_posemode(bContext *C, Base *base) { + ReportList *reports= CTX_wm_reports(C); Object *ob= base->object; - if (ob->id.lib){ - error ("Can't pose libdata"); + if (ob->id.lib) { + BKE_report(reports, RPT_WARNING, "Can't pose libdata"); return; } - switch (ob->type){ + switch (ob->type) { case OB_ARMATURE: ob->restore_mode = ob->mode; ob->mode |= OB_MODE_POSE; @@ -114,7 +141,8 @@ void ED_armature_enter_posemode(bContext *C, Base *base) default: return; } - + + // XXX: disabled as this would otherwise cause a nasty loop... //ED_object_toggle_modes(C, ob->mode); } @@ -132,7 +160,8 @@ void ED_armature_exit_posemode(bContext *C, Base *base) /* if a selected or active bone is protected, throw error (oonly if warn==1) and return 1 */ /* only_selected==1 : the active bone is allowed to be protected */ -static short pose_has_protected_selected(Object *ob, short only_selected, short warn) +#if 0 /* UNUSED 2.5 */ +static short pose_has_protected_selected(Object *ob, short warn) { /* check protection */ if (ob->proxy) { @@ -142,8 +171,7 @@ static short pose_has_protected_selected(Object *ob, short only_selected, short for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if (pchan->bone && (pchan->bone->layer & arm->layer)) { if (pchan->bone->layer & arm->layer_protected) { - if (only_selected && (pchan->bone == arm->act_bone)); - else if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone) + if (pchan->bone->flag & BONE_SELECTED) break; } } @@ -155,9 +183,10 @@ static short pose_has_protected_selected(Object *ob, short only_selected, short } return 0; } +#endif /* only for real IK, not for auto-IK */ -int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan) +static int pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan, int level) { bConstraint *con; Bone *bone; @@ -167,18 +196,25 @@ int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan) for(con= pchan->constraints.first; con; con= con->next) { if(con->type==CONSTRAINT_TYPE_KINEMATIC) { bKinematicConstraint *data= con->data; - if((data->flag & CONSTRAINT_IK_AUTO)==0) - return 1; + if(data->rootbone == 0 || data->rootbone > level) { + if((data->flag & CONSTRAINT_IK_AUTO)==0) + return 1; + } } } for(bone= pchan->bone->childbase.first; bone; bone= bone->next) { pchan= get_pose_channel(ob->pose, bone->name); - if(pchan && ED_pose_channel_in_IK_chain(ob, pchan)) + if(pchan && pose_channel_in_IK_chain(ob, pchan, level + 1)) return 1; } return 0; } +int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan) +{ + return pose_channel_in_IK_chain(ob, pchan, 0); +} + /* ********************************************** */ /* Motion Paths */ @@ -187,7 +223,7 @@ int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan) * * To be called from various tools that do incremental updates */ -void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob) +void ED_pose_recalculate_paths(Scene *scene, Object *ob) { ListBase targets = {NULL, NULL}; @@ -203,7 +239,7 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob) /* For the object with pose/action: create path curves for selected bones * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range */ -static int pose_calculate_paths_exec (bContext *C, wmOperator *op) +static int pose_calculate_paths_exec (bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa= CTX_wm_area(C); Scene *scene= CTX_data_scene(C); @@ -213,7 +249,7 @@ static int pose_calculate_paths_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); if (ELEM(NULL, ob, ob->pose)) return OPERATOR_CANCELLED; @@ -228,7 +264,7 @@ static int pose_calculate_paths_exec (bContext *C, wmOperator *op) /* calculate the bones that now have motionpaths... */ // TODO: only make for the selected bones? - ED_pose_recalculate_paths(C, scene, ob); + ED_pose_recalculate_paths(scene, ob); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); @@ -254,7 +290,7 @@ void POSE_OT_paths_calculate (wmOperatorType *ot) /* --------- */ /* for the object with pose/action: clear path curves for selected bones only */ -void ED_pose_clear_paths(Object *ob) +static void ED_pose_clear_paths(Object *ob) { bPoseChannel *pchan; short skipped = 0; @@ -280,7 +316,7 @@ void ED_pose_clear_paths(Object *ob) } /* operator callback for this */ -static int pose_clear_paths_exec (bContext *C, wmOperator *op) +static int pose_clear_paths_exec (bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa= CTX_wm_area(C); Object *ob; @@ -289,7 +325,7 @@ static int pose_clear_paths_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object */ if ELEM(NULL, ob, ob->pose) @@ -321,16 +357,15 @@ void POSE_OT_paths_clear (wmOperatorType *ot) /* ******************* Select Constraint Target Operator ************* */ -static int pose_select_constraint_target_exec(bContext *C, wmOperator *op) +static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_active_object(C); - bArmature *arm= ob->data; + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bConstraint *con; int found= 0; CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) { - if ((pchan->bone->flag & BONE_SELECTED) || (pchan->bone == arm->act_bone)) { + if (pchan->bone->flag & BONE_SELECTED) { for (con= pchan->constraints.first; con; con= con->next) { bConstraintTypeInfo *cti= constraint_get_typeinfo(con); ListBase targets = {NULL, NULL}; @@ -370,6 +405,7 @@ void POSE_OT_select_constraint_target(wmOperatorType *ot) /* identifiers */ ot->name= "Select Constraint Target"; ot->idname= "POSE_OT_select_constraint_target"; + ot->description= "Select bones used as targets for the currently selected bones"; /* api callbacks */ ot->exec= pose_select_constraint_target_exec; @@ -383,7 +419,7 @@ void POSE_OT_select_constraint_target(wmOperatorType *ot) static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= ob->data; Bone *curbone, *pabone, *chbone; int direction = RNA_enum_get(op->ptr, "direction"); @@ -400,7 +436,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) if (pchan->parent == NULL) continue; else pabone= pchan->parent->bone; - if ((arm->layer & pabone->layer) && !(pabone->flag & BONE_HIDDEN_P)) { + if (PBONE_VISIBLE(arm, pabone)) { if (!add_to_sel) curbone->flag &= ~BONE_SELECTED; pabone->flag |= BONE_SELECTED; arm->act_bone= pabone; @@ -413,7 +449,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) if (pchan->child == NULL) continue; else chbone = pchan->child->bone; - if ((arm->layer & chbone->layer) && !(chbone->flag & BONE_HIDDEN_P)) { + if (PBONE_VISIBLE(arm, chbone)) { if (!add_to_sel) curbone->flag &= ~BONE_SELECTED; chbone->flag |= BONE_SELECTED; arm->act_bone= chbone; @@ -438,14 +474,15 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op) void POSE_OT_select_hierarchy(wmOperatorType *ot) { static EnumPropertyItem direction_items[]= { - {BONE_SELECT_PARENT, "PARENT", 0, "Select Parent", ""}, - {BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""}, - {0, NULL, 0, NULL, NULL} + {BONE_SELECT_PARENT, "PARENT", 0, "Select Parent", ""}, + {BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ ot->name= "Select Hierarchy"; ot->idname= "POSE_OT_select_hierarchy"; + ot->description= "Select immediate parent/children of selected bones"; /* api callbacks */ ot->exec= pose_select_hierarchy_exec; @@ -488,7 +525,7 @@ static short pose_select_same_group (bContext *C, Object *ob, short extend) CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) { /* keep track of group as group to use later? */ - if ((pchan->bone->flag & BONE_SELECTED) || (pchan->bone == arm->act_bone)) { + if (pchan->bone->flag & BONE_SELECTED) { group_flags[pchan->agrp_index] = 1; tagged= 1; } @@ -535,7 +572,7 @@ static short pose_select_same_layer (bContext *C, Object *ob, short extend) CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) { /* keep track of layers to use later? */ - if ((pchan->bone->flag & BONE_SELECTED) || (pchan->bone == arm->act_bone)) + if (pchan->bone->flag & BONE_SELECTED) layers |= pchan->bone->layer; /* deselect all bones before selecting new ones? */ @@ -563,7 +600,7 @@ static short pose_select_same_layer (bContext *C, Object *ob, short extend) static int pose_select_grouped_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); short extend= RNA_boolean_get(op->ptr, "extend"); short changed = 0; @@ -603,7 +640,7 @@ void POSE_OT_select_grouped (wmOperatorType *ot) /* identifiers */ ot->name= "Select Grouped"; - ot->description = "Select all visible bones grouped by various properties"; + ot->description = "Select all visible bones grouped by similar properties"; ot->idname= "POSE_OT_select_grouped"; /* api callbacks */ @@ -619,13 +656,69 @@ void POSE_OT_select_grouped (wmOperatorType *ot) ot->prop= RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", ""); } + /* ********************************************** */ -void pose_copy_menu(Scene *scene) +/* context active object, or weightpainted object with armature in posemode */ +static int pose_bone_flip_active_exec (bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob_act= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(ob_act); + + if(ob && (ob->mode & OB_MODE_POSE)) { + bArmature *arm= ob->data; + + if(arm->act_bone) { + bPoseChannel *pchanf; + char name[MAXBONENAME]; + flip_side_name(name, arm->act_bone->name, TRUE); + + pchanf= get_pose_channel(ob->pose, name); + if(pchanf && pchanf->bone != arm->act_bone) { + arm->act_bone->flag &= ~BONE_SELECTED; + pchanf->bone->flag |= BONE_SELECTED; + + arm->act_bone= pchanf->bone; + + /* in weightpaint we select the associated vertex group too */ + if(ob_act->mode & OB_MODE_WEIGHT_PAINT) { + ED_vgroup_select_by_name(ob_act, name); + DAG_id_tag_update(&ob_act->id, OB_RECALC_DATA); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob); + + return OPERATOR_FINISHED; + } + } + } + + return OPERATOR_CANCELLED; +} + +void POSE_OT_select_flip_active(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Flip Selected Active Bone"; + ot->idname= "POSE_OT_select_flip_active"; + ot->description= "Activate the bone with a flipped name."; + + /* api callbacks */ + ot->exec= pose_bone_flip_active_exec; + ot->poll= ED_operator_posemode; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + + +/* ********************************************** */ +#if 0 /* UNUSED 2.5 */ +static void pose_copy_menu(Scene *scene) { Object *obedit= scene->obedit; // XXX context Object *ob= OBACT; - bArmature *arm= ob->data; + bArmature *arm; bPoseChannel *pchan, *pchanact; short nr=0; int i=0; @@ -638,11 +731,12 @@ void pose_copy_menu(Scene *scene) if (pchan==NULL) return; pchanact= pchan; - + arm= ob->data; + /* if proxy-protected bones selected, some things (such as locks + displays) shouldn't be changable, * but for constraints (just add local constraints) */ - if (pose_has_protected_selected(ob, 1, 0)) { + if (pose_has_protected_selected(ob, 0)) { i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ if (i < 25) nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5"); @@ -692,7 +786,7 @@ void pose_copy_menu(Scene *scene) for (con= tmp_constraints.first; con; con= con->next) con->flag |= CONSTRAINT_PROXY_LOCAL; } - addlisttolist(&pchan->constraints, &tmp_constraints); + BLI_movelisttolist(&pchan->constraints, &tmp_constraints); /* update flags (need to add here, not just copy) */ pchan->constflag |= pchanact->constflag; @@ -754,7 +848,7 @@ void pose_copy_menu(Scene *scene) } else { /* constraints, optional (note: max we can have is 24 constraints) */ bConstraint *con, *con_back; - int const_toggle[24]; + int const_toggle[24]= {0}; /* XXX, initialize as 0 to quiet errors */ ListBase const_copy = {NULL, NULL}; BLI_duplicatelist(&const_copy, &(pchanact->constraints)); @@ -794,14 +888,12 @@ void pose_copy_menu(Scene *scene) * appending to list of constraints for this channel */ copy_constraints(&tmp_constraints, &const_copy, TRUE); - if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) { - bConstraint *con; - + if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) { /* add proxy-local tags */ for (con= tmp_constraints.first; con; con= con->next) con->flag |= CONSTRAINT_PROXY_LOCAL; } - addlisttolist(&pchan->constraints, &tmp_constraints); + BLI_movelisttolist(&pchan->constraints, &tmp_constraints); /* update flags (need to add here, not just copy) */ pchan->constflag |= pchanact->constflag; @@ -814,11 +906,12 @@ void pose_copy_menu(Scene *scene) ob->pose->flag |= POSE_RECALC; } - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); // and all its relations + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); // and all its relations BIF_undo_push("Copy Pose Attributes"); } +#endif /* ******************** copy/paste pose ********************** */ @@ -849,7 +942,7 @@ void free_posebuf(void) static int pose_copy_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); /* sanity checking */ if ELEM(NULL, ob, ob->pose) { @@ -888,9 +981,10 @@ void POSE_OT_copy (wmOperatorType *ot) static int pose_paste_exec (bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bPoseChannel *chan, *pchan; int flip= RNA_boolean_get(op->ptr, "flipped"); + int selOnly= RNA_boolean_get(op->ptr, "selected_mask"); /* sanity checks */ if ELEM(NULL, ob, ob->pose) @@ -904,17 +998,28 @@ static int pose_paste_exec (bContext *C, wmOperator *op) /* Safely merge all of the channels in the buffer pose into any existing pose */ for (chan= g_posebuf->chanbase.first; chan; chan=chan->next) { if (chan->flag & POSE_KEY) { - /* get the name - if flipping, we must flip this first */ char name[32]; + short paste_ok; + + /* get the name - if flipping, we must flip this first */ if (flip) flip_side_name(name, chan->name, 0); /* 0 = don't strip off number extensions */ else BLI_strncpy(name, chan->name, sizeof(name)); - - /* only copy when channel exists, poses are not meant to add random channels to anymore */ + + /* only copy when: + * 1) channel exists - poses are not meant to add random channels to anymore + * 2) if selection-masking is on, channel is selected - only selected bones get pasted on, allowing making both sides symmetrical + */ pchan= get_pose_channel(ob->pose, name); - if (pchan) { + if (selOnly) + paste_ok= ((pchan) && (pchan->bone->flag & BONE_SELECTED)); + else + paste_ok= ((pchan != NULL)); + + /* continue? */ + if (paste_ok) { /* only loc rot size * - only copies transform info for the pose */ @@ -978,6 +1083,7 @@ static int pose_paste_exec (bContext *C, wmOperator *op) else { float eul[3]; + normalize_qt(pchan->quat); quat_to_eul(eul, pchan->quat); eul[1]*= -1; eul[2]*= -1; @@ -1005,16 +1111,9 @@ static int pose_paste_exec (bContext *C, wmOperator *op) /* keyframing tagging */ if (autokeyframe_cfra_can_key(scene, &ob->id)) { ListBase dsources = {NULL, NULL}; - KeyingSet *ks = NULL; - /* get KeyingSet to use - * - use the active KeyingSet if defined (and user wants to use it for all autokeying), - * or otherwise key transforms only - */ - if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (scene->active_keyingset)) - ks = ANIM_scene_get_active_keyingset(scene); - else - ks = ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); + /* get KeyingSet to use */ + KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, "LocRotScale"); /* now insert the keyframe(s) using the Keying Set * 1) add datasource override for the PoseChannel @@ -1039,7 +1138,7 @@ static int pose_paste_exec (bContext *C, wmOperator *op) } /* Update event for pose and deformation children */ - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); @@ -1062,13 +1161,14 @@ void POSE_OT_paste (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - RNA_def_boolean(ot->srna, "flipped", 0, "Flipped on X-Axis", ""); + RNA_def_boolean(ot->srna, "flipped", 0, "Flipped on X-Axis", "Paste the stored pose flipped on to current pose"); + RNA_def_boolean(ot->srna, "selected_mask", 0, "On Selected Only", "Only paste the stored post on to selected bones in the current pose"); } /* ********************************************** */ -static int pose_group_add_exec (bContext *C, wmOperator *op) +static int pose_group_add_exec (bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa= CTX_wm_area(C); Object *ob; @@ -1077,7 +1177,7 @@ static int pose_group_add_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object */ if (ob == NULL) @@ -1108,7 +1208,7 @@ void POSE_OT_group_add (wmOperatorType *ot) } -static int pose_group_remove_exec (bContext *C, wmOperator *op) +static int pose_group_remove_exec (bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa= CTX_wm_area(C); Object *ob; @@ -1117,7 +1217,7 @@ static int pose_group_remove_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object */ if (ob == NULL) @@ -1150,7 +1250,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 *evt) +static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *UNUSED(evt)) { ScrArea *sa= CTX_wm_area(C); Object *ob; @@ -1165,7 +1265,7 @@ static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object, and a pose there too */ if (ELEM(NULL, ob, ob->pose)) @@ -1175,20 +1275,20 @@ static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt) /* if there's no active group (or active is invalid), create a new menu to find it */ if (pose->active_group <= 0) { /* create a new menu, and start populating it with group names */ - pup= uiPupMenuBegin(C, op->type->name, 0); + pup= uiPupMenuBegin(C, op->type->name, ICON_NULL); layout= uiPupMenuLayout(pup); /* special entry - allow to create new group, then use that * (not to be used for removing though) */ if (strstr(op->idname, "assign")) { - uiItemIntO(layout, "New Group", 0, op->idname, "type", 0); + uiItemIntO(layout, "New Group", ICON_NULL, op->idname, "type", 0); uiItemS(layout); } /* add entries for each group */ for (grp= pose->agroups.first, i=1; grp; grp=grp->next, i++) - uiItemIntO(layout, grp->name, 0, op->idname, "type", i); + uiItemIntO(layout, grp->name, ICON_NULL, op->idname, "type", i); /* finish building the menu, and process it (should result in calling self again) */ uiPupMenuEnd(C, pup); @@ -1207,7 +1307,6 @@ static int pose_group_assign_exec (bContext *C, wmOperator *op) { ScrArea *sa= CTX_wm_area(C); Object *ob; - bArmature *arm; bPose *pose; short done= 0; @@ -1215,12 +1314,12 @@ static int pose_group_assign_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(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; - arm= ob->data; + pose= ob->pose; /* set the active group number to the one from operator props @@ -1268,25 +1367,21 @@ void POSE_OT_group_assign (wmOperatorType *ot) } -static int pose_group_unassign_exec (bContext *C, wmOperator *op) +static int pose_group_unassign_exec (bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa= CTX_wm_area(C); Object *ob; - bArmature *arm; - bPose *pose; short done= 0; /* 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= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(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; - pose= ob->pose; - arm= ob->data; /* find selected bones to remove from all bone groups */ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) @@ -1343,7 +1438,7 @@ static void pose_group_select(bContext *C, Object *ob, int select) CTX_DATA_END; } -static int pose_group_select_exec (bContext *C, wmOperator *op) +static int pose_group_select_exec (bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa= CTX_wm_area(C); Object *ob; @@ -1352,7 +1447,7 @@ static int pose_group_select_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object, and a pose there too */ if (ELEM(NULL, ob, ob->pose)) @@ -1381,7 +1476,7 @@ void POSE_OT_group_select (wmOperatorType *ot) ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } -static int pose_group_deselect_exec (bContext *C, wmOperator *op) +static int pose_group_deselect_exec (bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa= CTX_wm_area(C); Object *ob; @@ -1390,7 +1485,7 @@ static int pose_group_deselect_exec (bContext *C, wmOperator *op) if (sa->spacetype == SPACE_BUTS) ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; else - ob= CTX_data_active_object(C); + ob= ED_object_pose_armature(CTX_data_active_object(C)); /* only continue if there's an object, and a pose there too */ if (ELEM(NULL, ob, ob->pose)) @@ -1421,9 +1516,9 @@ void POSE_OT_group_deselect (wmOperatorType *ot) /* ********************************************** */ -static int pose_flip_names_exec (bContext *C, wmOperator *op) +static int pose_flip_names_exec (bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm; /* paranoia checks */ @@ -1441,7 +1536,7 @@ static int pose_flip_names_exec (bContext *C, wmOperator *op) CTX_DATA_END; /* since we renamed stuff... */ - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); @@ -1454,7 +1549,7 @@ void POSE_OT_flip_names (wmOperatorType *ot) /* identifiers */ ot->name= "Flip Names"; ot->idname= "POSE_OT_flip_names"; - ot->description= "Flips (and corrects) the names of selected bones"; + ot->description= "Flips (and corrects) the axis suffixes of the the names of selected bones"; /* api callbacks */ ot->exec= pose_flip_names_exec; @@ -1468,7 +1563,7 @@ void POSE_OT_flip_names (wmOperatorType *ot) static int pose_autoside_names_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm; char newname[32]; short axis= RNA_enum_get(op->ptr, "axis"); @@ -1488,7 +1583,7 @@ static int pose_autoside_names_exec (bContext *C, wmOperator *op) CTX_DATA_END; /* since we renamed stuff... */ - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); @@ -1523,51 +1618,68 @@ void POSE_OT_autoside_names (wmOperatorType *ot) /* ********************************************** */ -/* context active object, or weightpainted object with armature in posemode */ -void pose_activate_flipped_bone(Scene *scene) +/* Show all armature layers */ +static int pose_armature_layers_showall_poll (bContext *C) { - Object *ob= OBACT; - bArmature *arm= ob->data; - - if(ob==NULL) return; - - if(ob->mode & OB_MODE_WEIGHT_PAINT) { - ob= modifiers_isDeformedByArmature(ob); - } - if(ob && (ob->mode & OB_MODE_POSE)) { - bPoseChannel *pchanf; - - if(arm->act_bone) { - char name[32]; - flip_side_name(name, arm->act_bone->name, TRUE); - - pchanf= get_pose_channel(ob->pose, name); - if(pchanf && pchanf->bone != arm->act_bone) { - arm->act_bone->flag &= ~BONE_SELECTED; - pchanf->bone->flag |= BONE_SELECTED; - - arm->act_bone= pchanf->bone; + /* this single operator can be used in posemode OR editmode for armatures */ + return ED_operator_posemode(C) || ED_operator_editarmature(C); +} - /* in weightpaint we select the associated vertex group too */ - if(ob->mode & OB_MODE_WEIGHT_PAINT) { - ED_vgroup_select_by_name(OBACT, name); - DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA); - } - - // XXX notifiers need to be sent to other editors to update - - } - } - } +static int pose_armature_layers_showall_exec (bContext *C, wmOperator *op) +{ + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); + bArmature *arm = (ob)? ob->data : NULL; + PointerRNA ptr; + int maxLayers = (RNA_boolean_get(op->ptr, "all"))? 32 : 16; + int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */ + int i; + + /* sanity checking */ + if (arm == NULL) + return OPERATOR_CANCELLED; + + /* use RNA to set the layers + * although it would be faster to just set directly using bitflags, we still + * need to setup a RNA pointer so that we get the "update" callbacks for free... + */ + RNA_id_pointer_create(&arm->id, &ptr); + + for (i = 0; i < maxLayers; i++) + layers[i] = 1; + + RNA_boolean_set_array(&ptr, "layers", layers); + + /* note, notifier might evolve */ + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); + + /* done */ + return OPERATOR_FINISHED; } +void ARMATURE_OT_layers_show_all (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Show All Layers"; + ot->idname= "ARMATURE_OT_layers_show_all"; + ot->description= "Make all armature layers visible"; + + /* callbacks */ + ot->exec= pose_armature_layers_showall_exec; + ot->poll= pose_armature_layers_showall_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All Layers", "Enable all layers or just the first 16 (top row)"); +} -/* ********************************************** */ +/* ------------------- */ /* Present a popup to get the layers that should be used */ static int pose_armature_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= (ob)? ob->data : NULL; PointerRNA ptr; int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */ @@ -1588,7 +1700,7 @@ static int pose_armature_layers_invoke (bContext *C, wmOperator *op, wmEvent *ev /* Set the visible layers for the active armature (edit and pose modes) */ static int pose_armature_layers_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= (ob)? ob->data : NULL; PointerRNA ptr; int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */ @@ -1650,11 +1762,9 @@ void ARMATURE_OT_armature_layers (wmOperatorType *ot) /* Present a popup to get the layers that should be used */ static int pose_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt) { - int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */ - - /* get layers that are active already */ - memset(&layers, 0, sizeof(layers)); /* set all layers to be off by default */ + int layers[32]= {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */ + /* get layers that are active already */ CTX_DATA_BEGIN(C, bPoseChannel *, pchan, selected_pose_bones) { short bit; @@ -1677,7 +1787,7 @@ static int pose_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt) /* Set the visible layers for the active armature (edit and pose modes) */ static int pose_bone_layers_exec (bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); bArmature *arm= (ob)? ob->data : NULL; PointerRNA ptr; int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */ @@ -1724,11 +1834,9 @@ void POSE_OT_bone_layers (wmOperatorType *ot) /* Present a popup to get the layers that should be used */ static int armature_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt) { - int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */ + int layers[32]= {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */ /* get layers that are active already */ - memset(&layers, 0, sizeof(layers)); /* set all layers to be off by default */ - CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { short bit; @@ -1795,10 +1903,10 @@ void ARMATURE_OT_bone_layers (wmOperatorType *ot) /* ********************************************** */ -static int pose_flip_quats_exec (bContext *C, wmOperator *op) +static int pose_flip_quats_exec (bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_active_object(C); + Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); /* loop through all selected pchans, flipping and keying (as needed) */ @@ -1807,11 +1915,8 @@ static int pose_flip_quats_exec (bContext *C, wmOperator *op) /* only if bone is using quaternion rotation */ if (pchan->rotmode == ROT_MODE_QUAT) { /* quaternions have 720 degree range */ - pchan->quat[0]= -pchan->quat[0]; - pchan->quat[1]= -pchan->quat[1]; - pchan->quat[2]= -pchan->quat[2]; - pchan->quat[3]= -pchan->quat[3]; - + negate_v4(pchan->quat); + /* tagging */ if (autokeyframe_cfra_can_key(scene, &ob->id)) { ListBase dsources = {NULL, NULL}; @@ -1839,7 +1944,7 @@ static int pose_flip_quats_exec (bContext *C, wmOperator *op) CTX_DATA_END; /* notifiers and updates */ - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); return OPERATOR_FINISHED; @@ -1863,9 +1968,9 @@ void POSE_OT_quaternions_flip (wmOperatorType *ot) /* ********************************************** */ /* context: active channel */ +#if 0 void pose_special_editmenu(Scene *scene) { -#if 0 Object *obedit= scene->obedit; // XXX context Object *ob= OBACT; short nr; @@ -1888,7 +1993,7 @@ void pose_special_editmenu(Scene *scene) pose_clear_paths(ob); } else if(nr==5) { - pose_clear_user_transforms(scene, ob); + pose_clear_user_transforms(ob); } else if(nr==6) { pose_relax(); @@ -1896,11 +2001,11 @@ void pose_special_editmenu(Scene *scene) else if(ELEM3(nr, 7, 8, 9)) { pose_autoside_names(nr-7); } -#endif } + /* Restore selected pose-bones to 'action'-defined pose */ -void pose_clear_user_transforms(Scene *scene, Object *ob) +static void pose_clear_user_transforms(Object *ob) { bArmature *arm= ob->data; bPoseChannel *pchan; @@ -1928,7 +2033,8 @@ void pose_clear_user_transforms(Scene *scene, Object *ob) rest_pose(ob->pose); } - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); BIF_undo_push("Clear User Transform"); } +#endif |