Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/armature/poseobject.c')
-rw-r--r--source/blender/editors/armature/poseobject.c412
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