Page Menu
Home
Search
Configure Global Search
Log In
Files
F13644
outliner-poselib2.patch
Public
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Torsten Rupp (rupp)
Nov 13 2013, 2:45 PM
Size
12 KB
Subscribers
None
outliner-poselib2.patch
View Options
Index: source/blender/editors/space_outliner/outliner.c
===================================================================
--- source/blender/editors/space_outliner/outliner.c (revision 37993)
+++ source/blender/editors/space_outliner/outliner.c (working copy)
@@ -69,7 +69,9 @@
#endif
+#include "BKE_action.h"
#include "BKE_animsys.h"
+#include "BKE_armature.h"
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_depsgraph.h"
@@ -83,7 +85,9 @@
#include "BKE_scene.h"
#include "BKE_sequencer.h"
+#include "ED_anim_api.h"
#include "ED_armature.h"
+#include "ED_keyframes_edit.h"
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_util.h"
@@ -538,6 +542,20 @@
}
}
+/* add pose library pose names to outliner */
+static void outliner_add_poselib_contents(SpaceOops *soops, ListBase *UNUSED(lb), bAction *act, TreeElement *te)
+{
+ TreeElement *ten;
+ int a;
+ TimeMarker *marker;
+
+ for (a=0, marker= act->markers.first; marker; marker= marker->next, a++) {
+ ten= outliner_add_element(soops, &te->subtree, act, te, TSE_POSELIB, a);
+ ten->name= marker->name;
+ ten->directdata= marker;
+ }
+}
+
static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *sce, TreeElement *te)
{
SceneRenderLayer *srl;
@@ -859,6 +877,7 @@
{
// XXX do we want to be exposing the F-Curves here?
//bAction *act= (bAction *)id;
+ outliner_add_poselib_contents(soops, &te->subtree, (bAction *)id, te);
}
break;
case ID_AR:
@@ -2342,6 +2361,20 @@
return 0;
}
+static int tree_element_active_poselib(bContext *C, Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tselem, int set)
+{
+ bAction *act= (bAction *)tselem->id;
+
+ if(set) {
+ act->active_marker= te->index+1;
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, act);
+ }
+ else {
+ if (act->active_marker== te->index+1) return 1;
+ }
+ return 0;
+}
+
/* generic call for ID data check or make/check active in UI */
static int tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set)
{
@@ -2462,6 +2495,8 @@
return tree_element_active_pose(C, scene, te, tselem, set);
case TSE_POSE_CHANNEL:
return tree_element_active_posechannel(C, scene, te, tselem, set);
+ case TSE_POSELIB:
+ return tree_element_active_poselib(C, scene, te, tselem, set);
case TSE_CONSTRAINT:
return tree_element_active_constraint(C, te, tselem, set);
case TSE_R_LAYER:
@@ -2474,7 +2509,6 @@
return tree_element_active_sequence_dup(scene, te, tselem, set);
case TSE_KEYMAP_ITEM:
return tree_element_active_keymap_item(C, te, tselem, set);
-
}
return 0;
}
@@ -3345,7 +3379,7 @@
/* ******************************************** */
-static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem))
+static void pchan_cb(bContext *UNUSED(C), Scene *UNUSED(scene), int event, TreeElement *te, TreeStoreElem *UNUSED(tselem))
{
bPoseChannel *pchan= (bPoseChannel *)te->directdata;
@@ -3361,7 +3395,7 @@
pchan->bone->flag &= ~BONE_HIDDEN_P;
}
-static void bone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem))
+static void bone_cb(bContext *UNUSED(C), Scene *UNUSED(scene), int event, TreeElement *te, TreeStoreElem *UNUSED(tselem))
{
Bone *bone= (Bone *)te->directdata;
@@ -3377,7 +3411,7 @@
bone->flag &= ~BONE_HIDDEN_P;
}
-static void ebone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem))
+static void ebone_cb(bContext *UNUSED(C), Scene *UNUSED(scene), int event, TreeElement *te, TreeStoreElem *UNUSED(tselem))
{
EditBone *ebone= (EditBone *)te->directdata;
@@ -3393,7 +3427,7 @@
ebone->flag &= ~BONE_HIDDEN_A;
}
-static void sequence_cb(int event, TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tselem))
+static void sequence_cb(bContext *UNUSED(C), Scene *UNUSED(scene), int event, TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tselem))
{
// Sequence *seq= (Sequence*) te->directdata;
if(event==1) {
@@ -3401,8 +3435,8 @@
}
}
-static void outliner_do_data_operation(SpaceOops *soops, int type, int event, ListBase *lb,
- void (*operation_cb)(int, TreeElement *, TreeStoreElem *))
+static void outliner_do_data_operation(bContext *C, Scene *scene, SpaceOops *soops, int type, int event, ListBase *lb,
+ void (*operation_cb)(bContext *C, Scene *scene, int, TreeElement *, TreeStoreElem *))
{
TreeElement *te;
TreeStoreElem *tselem;
@@ -3411,11 +3445,11 @@
tselem= TREESTORE(te);
if(tselem->flag & TSE_SELECTED) {
if(tselem->type==type) {
- operation_cb(event, te, tselem);
+ operation_cb(C, scene, event, te, tselem);
}
}
if((tselem->flag & TSE_CLOSED)==0) {
- outliner_do_data_operation(soops, type, event, &te->subtree, operation_cb);
+ outliner_do_data_operation(C, scene, soops, type, event, &te->subtree, operation_cb);
}
}
}
@@ -3652,6 +3686,153 @@
/* **************************************** */
+static EnumPropertyItem prop_poselib_op_types[] = {
+ {1, "UNLINK", 0, "Unlink", ""},
+ {2, "APPLY", 0, "Apply", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static void poselib_cb(bContext *C, Scene *scene, int event, TreeElement *te, TreeStoreElem *tselem)
+{
+ bAction *act= (bAction *)tselem->id;
+ TimeMarker *marker= (TimeMarker*)te->directdata;
+
+ if(marker) {
+ if(event==1) {
+ FCurve *fcu;
+
+ /* remove relevant keyframes */
+ for (fcu= act->curves.first; fcu; fcu= fcu->next) {
+ BezTriple *bezt;
+ int i;
+
+ if (fcu->bezt) {
+ for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ /* check if remove */
+ if (IS_EQ(bezt->vec[1][0], marker->frame)) {
+ delete_fcurve_key(fcu, i, 1);
+ break;
+ }
+ }
+ }
+ }
+
+ /* remove poselib from list */
+ BLI_freelinkN(&act->markers, marker);
+
+ /* fix active pose number */
+ act->active_marker= 0;
+ }
+ else if(event==2) {
+ Object *ob= CTX_data_active_object(C);
+ PointerRNA ptr;
+ bArmature *arm= ob->data;
+ bPose *pose= ob->pose;
+ bPoseChannel *pchan;
+ bActionGroup *agrp;
+
+ KeyframeEditData ked;
+ KeyframeEditFunc group_ok_cb;
+ int frame= 1;
+
+ /* apply pose */
+ RNA_id_pointer_create(&ob->id, &ptr);
+
+ /* get the frame */
+ if (marker)
+ frame= marker->frame;
+ else
+ return;
+
+ /* lock pose */
+ pose->flag |= POSE_LOCKED;
+ pose->flag &= ~POSE_DO_UNLOCK;
+
+
+ /* init settings for testing groups for keyframes */
+ group_ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
+ memset(&ked, 0, sizeof(KeyframeEditData));
+ ked.f1= ((float)frame) - 0.5f;
+ ked.f2= ((float)frame) + 0.5f;
+
+
+ /* start applying - only those channels which have a key at this point in time! */
+ for (agrp= act->groups.first; agrp; agrp= agrp->next) {
+ /* check if group has any keyframes */
+ if (ANIM_animchanneldata_keyframes_loop(&ked, agrp, ALE_GROUP, NULL, group_ok_cb, NULL, 0)) {
+ /* has keyframe on this frame, so try to get a PoseChannel with this name */
+ pchan= get_pose_channel(pose, agrp->name);
+
+ if (pchan) {
+ animsys_evaluate_action_group(&ptr, act, agrp, NULL, (float)frame);
+ }
+ }
+ }
+
+ /* unlock pose */
+ pose->flag |= POSE_DO_UNLOCK;
+
+ /* old optimize trick... this enforces to bypass the depgraph
+ * - note: code copied from transform_generics.c -> recalcData()
+ */
+ // FIXME: shouldn't this use the builtin stuff?
+ if ((arm->flag & ARM_DELAYDEFORM)==0)
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
+ else
+ where_is_pose(scene, ob);
+ }
+ }
+}
+
+static int outliner_poselib_operation_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ SpaceOops *soops= CTX_wm_space_outliner(C);
+ int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0;
+ int event;
+
+ /* check for invalid states */
+ if (soops == NULL)
+ return OPERATOR_CANCELLED;
+
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+
+ event= RNA_enum_get(op->ptr, "type");
+
+ if(event==1) {
+ outliner_do_data_operation(C, scene, soops, datalevel, event, &soops->tree, poselib_cb);
+ ED_undo_push(C, "Unlink PoseLib");
+ }
+ else if(event==2) {
+ outliner_do_data_operation(C, scene, soops, datalevel, event, &soops->tree, poselib_cb);
+ ED_undo_push(C, "Apply PoseLib to Scene");
+ }
+
+ WM_event_add_notifier(C, NC_GROUP, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+
+void OUTLINER_OT_poselib_operation(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Outliner PoseLib Operation";
+ ot->idname= "OUTLINER_OT_poselib_operation";
+ ot->description= "";
+
+ /* callbacks */
+ ot->invoke= WM_menu_invoke;
+ ot->exec= outliner_poselib_operation_exec;
+ ot->poll= ED_operator_outliner_active;
+
+ ot->flag= 0;
+
+ ot->prop= RNA_def_enum(ot->srna, "type", prop_poselib_op_types, 0, "PoseLib Operation", "");
+}
+
+/* **************************************** */
+
static EnumPropertyItem prop_data_op_types[] = {
{1, "SELECT", 0, "Select", ""},
{2, "DESELECT", 0, "Deselect", ""},
@@ -3662,6 +3843,7 @@
static int outliner_data_operation_exec(bContext *C, wmOperator *op)
{
+ Scene *scene= CTX_data_scene(C);
SpaceOops *soops= CTX_wm_space_outliner(C);
int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0;
int event;
@@ -3675,28 +3857,28 @@
if(datalevel==TSE_POSE_CHANNEL) {
if(event>0) {
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, pchan_cb);
+ outliner_do_data_operation(C, scene, soops, datalevel, event, &soops->tree, pchan_cb);
WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL);
ED_undo_push(C, "PoseChannel operation");
}
}
else if(datalevel==TSE_BONE) {
if(event>0) {
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, bone_cb);
+ outliner_do_data_operation(C, scene, soops, datalevel, event, &soops->tree, bone_cb);
WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL);
ED_undo_push(C, "Bone operation");
}
}
else if(datalevel==TSE_EBONE) {
if(event>0) {
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, ebone_cb);
+ outliner_do_data_operation(C, scene, soops, datalevel, event, &soops->tree, ebone_cb);
WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL);
ED_undo_push(C, "EditBone operation");
}
}
else if(datalevel==TSE_SEQUENCE) {
if(event>0) {
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb);
+ outliner_do_data_operation(C, scene, soops, datalevel, event, &soops->tree, sequence_cb);
}
}
@@ -3765,7 +3947,10 @@
else if(datalevel) {
if(datalevel==-1) error("Mixed selection");
else {
- WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL);
+ if (datalevel==TSE_POSELIB)
+ WM_operator_name_call(C, "OUTLINER_OT_poselib_operation", WM_OP_INVOKE_REGION_WIN, NULL);
+ else
+ WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL);
}
}
Index: source/blender/editors/space_outliner/outliner_ops.c
===================================================================
--- source/blender/editors/space_outliner/outliner_ops.c (revision 37993)
+++ source/blender/editors/space_outliner/outliner_ops.c (working copy)
@@ -56,6 +56,7 @@
WM_operatortype_append(OUTLINER_OT_object_operation);
WM_operatortype_append(OUTLINER_OT_group_operation);
WM_operatortype_append(OUTLINER_OT_id_operation);
+ WM_operatortype_append(OUTLINER_OT_poselib_operation);
WM_operatortype_append(OUTLINER_OT_data_operation);
WM_operatortype_append(OUTLINER_OT_show_one_level);
Index: source/blender/editors/space_outliner/outliner_intern.h
===================================================================
--- source/blender/editors/space_outliner/outliner_intern.h (revision 37993)
+++ source/blender/editors/space_outliner/outliner_intern.h (working copy)
@@ -104,6 +104,8 @@
#define TSE_KEYMAP 34
#define TSE_KEYMAP_ITEM 35
+#define TSE_POSELIB 36
+
/* button events */
#define OL_NAMEBUTTON 1
@@ -127,6 +129,7 @@
void OUTLINER_OT_object_operation(struct wmOperatorType *ot);
void OUTLINER_OT_group_operation(struct wmOperatorType *ot);
void OUTLINER_OT_id_operation(struct wmOperatorType *ot);
+void OUTLINER_OT_poselib_operation(struct wmOperatorType *ot);
void OUTLINER_OT_data_operation(struct wmOperatorType *ot);
void OUTLINER_OT_show_one_level(struct wmOperatorType *ot);
File Metadata
Details
Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
65/a1/06cc9828f1850775b8fc3666e53e
Event Timeline
Log In to Comment