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:
authorJoshua Leung <aligorith@gmail.com>2011-04-19 17:01:50 +0400
committerJoshua Leung <aligorith@gmail.com>2011-04-19 17:01:50 +0400
commit94b99b5d4a7c20cf2f4488b599e74619a7c860a6 (patch)
tree3ab0c737968a6d739e72b2a990eedbbdc329ac57 /source/blender/makesrna/intern
parentc4debb1c642af4f97818d1e33986223b69b0aa6d (diff)
Bugfix [#25960] Action/NLA Editor issues with animdata context
Actions now get tagged with an ID-code, which is used to determine what ID-blocks they can be assigned to. This ensures that material actions cannot be assigned to the object-level for example. * Action lists in general will now show only the actions that can be set for that particular slot. This prevents selection of invalid actions, and helps cut down the list of actions. ** An exception here is the Add Action Clip in NLA Editor, which will show all actions but will only add where appropriate. This is because it's not easy/possible to tell in advance which blocktypes to filter for when building this list. (TODO?) * The "Action Editor" is now strictly for object-level action editing+setting now. This avoids repeateded confusion by people who try using this to view their shapekey actions, which should go to the Shape Key Editor instead! ** A context switcher for the legitimate times where this capability might come in handy is still being investigated. * "Floating" actions (i.e. actions in some action_library.blend) are NOT able to be automatically tagged until they are assigned to some datablocks (i.e. loaded onto the rig + played back once). It is possible to write scripts that check for certain RNA-paths and "guess" what datablocks they work on, but it is recommended that you load up the Datablocks Viewer, and go through such actions by hand, setting the "ID Root Type" property as appropriate per action.
Diffstat (limited to 'source/blender/makesrna/intern')
-rw-r--r--source/blender/makesrna/intern/rna_action.c72
-rw-r--r--source/blender/makesrna/intern/rna_animation.c36
-rw-r--r--source/blender/makesrna/intern/rna_internal.h3
-rw-r--r--source/blender/makesrna/intern/rna_nla.c1
-rw-r--r--source/blender/makesrna/intern/rna_space.c29
5 files changed, 133 insertions, 8 deletions
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 418451801ca..7fdb96fda6e 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "rna_internal.h"
@@ -194,6 +195,56 @@ static void rna_Action_frame_range_get(PointerRNA *ptr,float *values)
calc_action_range(ptr->id.data, values, values+1, 1);
}
+
+/* used to check if an action (value pointer) is suitable to be assigned to the ID-block that is ptr */
+int rna_Action_id_poll(PointerRNA *ptr, PointerRNA value)
+{
+ ID *srcId = (ID *)ptr->id.data;
+ bAction *act = (bAction *)value.id.data;
+
+ if (act) {
+ /* there can still be actions that will have undefined id-root
+ * (i.e. floating "action-library" members) which we will not
+ * be able to resolve an idroot for automatically, so let these through
+ */
+ if (act->idroot == 0)
+ return 1;
+ else if (srcId)
+ return GS(srcId->name) == act->idroot;
+ }
+
+ return 0;
+}
+
+/* used to check if an action (value pointer) can be assigned to Action Editor given current mode */
+int rna_Action_actedit_assign_poll(PointerRNA *ptr, PointerRNA value)
+{
+ SpaceAction *saction = (SpaceAction *)ptr->data;
+ bAction *act = (bAction *)value.id.data;
+
+ if (act) {
+ /* there can still be actions that will have undefined id-root
+ * (i.e. floating "action-library" members) which we will not
+ * be able to resolve an idroot for automatically, so let these through
+ */
+ if (act->idroot == 0)
+ return 1;
+
+ if (saction) {
+ if (saction->mode == SACTCONT_ACTION) {
+ /* this is only Object-level for now... */
+ return act->idroot == ID_OB;
+ }
+ else if (saction->mode == SACTCONT_SHAPEKEY) {
+ /* obviously shapekeys only */
+ return act->idroot == ID_KE;
+ }
+ }
+ }
+
+ return 0;
+}
+
#else
static void rna_def_dopesheet(BlenderRNA *brna)
@@ -515,34 +566,43 @@ static void rna_def_action(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna= RNA_def_struct(brna, "Action", "ID");
RNA_def_struct_sdna(srna, "bAction");
RNA_def_struct_ui_text(srna, "Action", "A collection of F-Curves for animation");
RNA_def_struct_ui_icon(srna, ICON_ACTION);
-
+
+ /* collections */
prop= RNA_def_property(srna, "fcurves", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "curves", NULL);
RNA_def_property_struct_type(prop, "FCurve");
RNA_def_property_ui_text(prop, "F-Curves", "The individual F-Curves that make up the Action");
rna_def_action_fcurves(brna, prop);
-
+
prop= RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "groups", NULL);
RNA_def_property_struct_type(prop, "ActionGroup");
RNA_def_property_ui_text(prop, "Groups", "Convenient groupings of F-Curves");
rna_def_action_groups(brna, prop);
-
+
prop= RNA_def_property(srna, "pose_markers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "markers", NULL);
RNA_def_property_struct_type(prop, "TimelineMarker");
RNA_def_property_ui_text(prop, "Pose Markers", "Markers specific to this Action, for labeling poses");
rna_def_action_pose_markers(brna, prop);
-
+
+ /* properties */
prop= RNA_def_float_vector(srna, "frame_range" , 2 , NULL , 0, 0, "Frame Range" , "The final frame range of all fcurves within this action" , 0 , 0);
RNA_def_property_float_funcs(prop, "rna_Action_frame_range_get" , NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
+ /* special "type" limiter - should not really be edited in general, but is still available/editable in 'emergencies' */
+ prop= RNA_def_property(srna, "id_root", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "idroot");
+ RNA_def_property_enum_items(prop, id_type_items);
+ RNA_def_property_ui_text(prop, "ID Root Type", "Type of ID-block that action can be used on. DO NOT CHANGE UNLESS YOU KNOW WHAT YOU'RE DOING");
+
+ /* API calls */
RNA_api_action(srna);
}
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 17d2e27c462..8e210a7a4cb 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -70,6 +70,41 @@ static int rna_AnimData_action_editable(PointerRNA *ptr)
return 1;
}
+static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value)
+{
+ ID *ownerId = (ID *)ptr->id.data;
+ AnimData *adt = (AnimData *)ptr->data;
+
+ /* assume that AnimData's action can in fact be edited... */
+ if ((value.data) && (ownerId)) {
+ bAction *act = (bAction *)value.data;
+
+ /* action must have same type as owner */
+ if (ownerId) {
+ if (ELEM(act->idroot, 0, GS(ownerId->name))) {
+ /* can set */
+ adt->action = act;
+ }
+ else {
+ /* cannot set */
+ printf("ERROR: Couldn't set Action '%s' onto ID '%s', as it doesn't have suitably rooted paths for this purpose\n",
+ act->id.name+2, ownerId->name);
+ }
+ }
+ else {
+ /* cannot tell if we can set, so let's just be generous... */
+ printf("Warning: Set Action '%s' onto AnimData block with an unknown ID-owner. May have attached invalid data\n",
+ act->id.name+2);
+
+ adt->action = act;
+ }
+ }
+ else {
+ /* just clearing the action... */
+ adt->action = NULL;
+ }
+}
+
/* ****************************** */
/* wrapper for poll callback */
@@ -739,6 +774,7 @@ void rna_def_animdata(BlenderRNA *brna)
/* Active Action */
prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE); /* this flag as well as the dynamic test must be defined for this to be editable... */
+ RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Action_id_poll");
RNA_def_property_editable_func(prop, "rna_AnimData_action_editable");
RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock");
RNA_def_property_update(prop, NC_ANIMATION, NULL); /* this will do? */
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 4dc98ceb0a4..1d060c8a362 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -222,6 +222,9 @@ int rna_Curve_object_poll(struct PointerRNA *ptr, struct PointerRNA value);
int rna_Lattice_object_poll(struct PointerRNA *ptr, struct PointerRNA value);
int rna_Mesh_object_poll(struct PointerRNA *ptr, struct PointerRNA value);
+/* basic poll functions for actions (to prevent actions getting set in wrong places) */
+int rna_Action_id_poll(struct PointerRNA *ptr, struct PointerRNA value);
+int rna_Action_actedit_assign_poll(struct PointerRNA *ptr, struct PointerRNA value);
char *rna_TextureSlot_path(struct PointerRNA *ptr);
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index 09837579949..9bf5f53f8b7 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -426,6 +426,7 @@ static void rna_def_nlastrip(BlenderRNA *brna)
/* Action */
prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "act");
+ RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Action_id_poll");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Action", "Action referenced by this strip");
RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 3d9d8a8e9f4..52fae14a023 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -644,7 +644,32 @@ static void rna_ConsoleLine_cursor_index_range(PointerRNA *ptr, int *min, int *m
static void rna_SpaceDopeSheetEditor_action_set(PointerRNA *ptr, PointerRNA value)
{
SpaceAction *saction= (SpaceAction*)(ptr->data);
- saction->action= value.data;
+ bAction *act = (bAction*)value.data;
+
+ if ((act == NULL) || (act->idroot == 0)) {
+ /* just set if we're clearing the action or if the action is "amorphous" still */
+ saction->action= act;
+ }
+ else {
+ /* action to set must strictly meet the mode criteria... */
+ if (saction->mode == SACTCONT_ACTION) {
+ /* currently, this is "object-level" only, until we have some way of specifying this */
+ if (act->idroot == ID_OB)
+ saction->action = act;
+ else
+ printf("ERROR: cannot assign Action '%s' to Action Editor, as action is not object-level animation\n", act->id.name+2);
+ }
+ else if (saction->mode == SACTCONT_SHAPEKEY) {
+ /* as the name says, "shapekey-level" only... */
+ if (act->idroot == ID_KE)
+ saction->action = act;
+ else
+ printf("ERROR: cannot assign Action '%s' to Shape Key Editor, as action doesn't animate Shape Keys\n", act->id.name+2);
+ }
+ else {
+ printf("ACK: who's trying to set an action while not in a mode displaying a single Action only?\n");
+ }
+ }
}
static void rna_SpaceDopeSheetEditor_action_update(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -1771,7 +1796,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
/* data */
prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceDopeSheetEditor_action_set", NULL, NULL);
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceDopeSheetEditor_action_set", NULL, "rna_Action_actedit_assign_poll");
RNA_def_property_ui_text(prop, "Action", "Action displayed and edited in this space");
RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, "rna_SpaceDopeSheetEditor_action_update");