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:
authorBastien Montagne <mont29>2022-05-31 18:28:52 +0300
committerBastien Montagne <bastien@blender.org>2022-06-02 13:28:50 +0300
commit901791944da9cb66b68841ff8615758cec407b5a (patch)
tree8db790213853b4b7024a04f5dff21c9d61bbbde4
parent3ca76ae0e8f7cd7f67a352dd3d8a415802506ee2 (diff)
Anim: Refactor 'F-curve from rna path' code.
Move into its own new function the the low-level logic to search for a given RNA path in Action F-curves, then driver F-curves of a given AnimData. This deduplicates code from `BKE_fcurve_find_by_rna_context_ui` and `id_data_find_fcurve`, and will allow for future more usages of this functionality. Differential Revision: https://developer.blender.org/D15068
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h35
-rw-r--r--source/blender/blenkernel/intern/fcurve.c130
2 files changed, 112 insertions, 53 deletions
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 78d80ce200e..30c73e0fcc6 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -259,6 +259,18 @@ struct FCurve *BKE_fcurve_iter_step(struct FCurve *fcu_iter, const char rna_path
/**
* High level function to get an f-curve from C without having the RNA.
+ *
+ * If there is an action assigned to the `id`'s #AnimData, it will be searched for a matching
+ * F-curve first. Drivers are searched only if no valid action F-curve could be found.
+ *
+ * \note: Return pointer parameter (`r_driven`) is optional and may be NULL.
+ *
+ * \warning: In case no animation (from an Action) F-curve is found, returned value is always NULL.
+ * This means that this function will set `r_driven` to True in case a valid driver F-curve is
+ * found, but will not return said F-curve. In other words:
+ * - Animated with FCurve: returns the `FCurve*` and `*r_driven = false`.
+ * - Animated with driver: returns `NULL` and `*r_driven = true`.
+ * - Not animated: returns `NULL` and `*r_driven = false`.
*/
struct FCurve *id_data_find_fcurve(
ID *id, void *data, struct StructRNA *type, const char *prop_name, int index, bool *r_driven);
@@ -279,6 +291,25 @@ struct FCurve *id_data_find_fcurve(
int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName);
/**
+ * Find an F-Curve from its rna path and index.
+ *
+ * If there is an action assigned to the `animdata`, it will be searched for a matching F-curve
+ * first. Drivers are searched only if no valid action F-curve could be found.
+ *
+ * \note: Typically, indices in RNA arrays are stored separately in F-curves, so the rna_path
+ * should not include them (e.g. `rna_path='location[0]'` will not match any F-Curve on an Object,
+ * but `rna_path='location', rna_index=0` will if it exists).
+ *
+ * \note: Return pointer parameters (`r_action`, `r_driven` and `r_special`) are all optional and
+ * may be NULL.
+ */
+struct FCurve *BKE_animadata_fcurve_find_by_rna_path(struct AnimData *animdata,
+ const char *rna_path,
+ const int rna_index,
+ struct bAction **r_action,
+ bool *r_driven);
+
+/**
* Find an f-curve based on an rna property.
*/
struct FCurve *BKE_fcurve_find_by_rna(struct PointerRNA *ptr,
@@ -291,7 +322,9 @@ struct FCurve *BKE_fcurve_find_by_rna(struct PointerRNA *ptr,
/**
* Same as above, but takes a context data,
* temp hack needed for complex paths like texture ones.
- */
+ *
+ * \param r_special Optional, ignored when NULL. Set to `true` if the given RNA `ptr` is a NLA
+ * strip, and the returned F-curve comes from this NLA strip. */
struct FCurve *BKE_fcurve_find_by_rna_context_ui(struct bContext *C,
const struct PointerRNA *ptr,
struct PropertyRNA *prop,
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 952d5df299c..98a2b977d4e 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -229,16 +229,13 @@ FCurve *id_data_find_fcurve(
return NULL;
}
- /* Animation takes priority over drivers. */
- if (adt->action && adt->action->curves.first) {
- fcu = BKE_fcurve_find(&adt->action->curves, path, index);
- }
-
- /* If not animated, check if driven. */
- if (fcu == NULL && adt->drivers.first) {
- fcu = BKE_fcurve_find(&adt->drivers, path, index);
- if (fcu && r_driven) {
- *r_driven = true;
+ /* FIXME: The way drivers are handled here (always NULL-ifying `fcu`) is very weird, this needs
+ * to be re-checked I think?. */
+ bool is_driven = false;
+ fcu = BKE_animadata_fcurve_find_by_rna_path(adt, path, index, NULL, &is_driven);
+ if (is_driven) {
+ if (r_driven != NULL) {
+ *r_driven = is_driven;
}
fcu = NULL;
}
@@ -339,6 +336,47 @@ int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, con
return matches;
}
+FCurve *BKE_animadata_fcurve_find_by_rna_path(
+ AnimData *animdata, const char *rna_path, int rna_index, bAction **r_action, bool *r_driven)
+{
+ if (r_driven != NULL) {
+ *r_driven = false;
+ }
+ if (r_action != NULL) {
+ *r_action = NULL;
+ }
+
+ const bool has_action_fcurves = animdata->action != NULL &&
+ !BLI_listbase_is_empty(&animdata->action->curves);
+ const bool has_drivers = !BLI_listbase_is_empty(&animdata->drivers);
+
+ /* Animation takes priority over drivers. */
+ if (has_action_fcurves) {
+ FCurve *fcu = BKE_fcurve_find(&animdata->action->curves, rna_path, rna_index);
+
+ if (fcu != NULL) {
+ if (r_action != NULL) {
+ *r_action = animdata->action;
+ }
+ return fcu;
+ }
+ }
+
+ /* If not animated, check if driven. */
+ if (has_drivers) {
+ FCurve *fcu = BKE_fcurve_find(&animdata->drivers, rna_path, rna_index);
+
+ if (fcu != NULL) {
+ if (r_driven != NULL) {
+ *r_driven = true;
+ }
+ return fcu;
+ }
+ }
+
+ return NULL;
+}
+
FCurve *BKE_fcurve_find_by_rna(PointerRNA *ptr,
PropertyRNA *prop,
int rnaindex,
@@ -360,17 +398,18 @@ FCurve *BKE_fcurve_find_by_rna_context_ui(bContext *UNUSED(C),
bool *r_driven,
bool *r_special)
{
- FCurve *fcu = NULL;
-
- *r_driven = false;
- *r_special = false;
-
- if (r_animdata) {
+ if (r_animdata != NULL) {
*r_animdata = NULL;
}
- if (r_action) {
+ if (r_action != NULL) {
*r_action = NULL;
}
+ if (r_driven != NULL) {
+ *r_driven = false;
+ }
+ if (r_special) {
+ *r_special = false;
+ }
/* Special case for NLA Control Curves... */
if (BKE_nlastrip_has_curves_for_property(ptr, prop)) {
@@ -379,59 +418,46 @@ FCurve *BKE_fcurve_find_by_rna_context_ui(bContext *UNUSED(C),
/* Set the special flag, since it cannot be a normal action/driver
* if we've been told to start looking here...
*/
- *r_special = true;
+ if (r_special) {
+ *r_special = true;
+ }
+
+ *r_driven = false;
+ if (r_animdata) {
+ *r_animdata = NULL;
+ }
+ if (r_action) {
+ *r_action = NULL;
+ }
/* The F-Curve either exists or it doesn't here... */
- fcu = BKE_fcurve_find(&strip->fcurves, RNA_property_identifier(prop), rnaindex);
- return fcu;
+ return BKE_fcurve_find(&strip->fcurves, RNA_property_identifier(prop), rnaindex);
}
/* There must be some RNA-pointer + property combo. */
if (!prop || !ptr->owner_id || !RNA_property_animateable(ptr, prop)) {
- return fcu;
+ return NULL;
}
AnimData *adt = BKE_animdata_from_id(ptr->owner_id);
if (adt == NULL) {
- return fcu;
+ return NULL;
}
- const bool has_action_fcurves = adt->action != NULL &&
- !BLI_listbase_is_empty(&adt->action->curves);
- const bool has_drivers = !BLI_listbase_is_empty(&adt->drivers);
-
/* XXX This function call can become a performance bottleneck. */
- char *path = RNA_path_from_ID_to_property(ptr, prop);
-
- /* Standard F-Curve - Animation (Action) or Drivers. */
- /* Animation takes priority over drivers. */
- /* XXX: The logic here is duplicated with a function up above. */
- if (has_action_fcurves) {
- fcu = BKE_fcurve_find(&adt->action->curves, path, rnaindex);
-
- if (fcu) {
- if (r_action) {
- *r_action = adt->action;
- }
- if (r_animdata) {
- *r_animdata = adt;
- }
- }
+ char *rna_path = RNA_path_from_ID_to_property(ptr, prop);
+ if (rna_path == NULL) {
+ return NULL;
}
- /* If not animated, check if driven. */
- if (fcu == NULL && has_drivers) {
- fcu = BKE_fcurve_find(&adt->drivers, path, rnaindex);
+ /* Standard F-Curve from animdata - Animation (Action) or Drivers. */
+ FCurve *fcu = BKE_animadata_fcurve_find_by_rna_path(adt, rna_path, rnaindex, r_action, r_driven);
- if (fcu) {
- if (r_animdata) {
- *r_animdata = adt;
- }
- *r_driven = true;
- }
+ if (fcu != NULL && r_animdata != NULL) {
+ *r_animdata = adt;
}
- MEM_SAFE_FREE(path);
+ MEM_freeN(rna_path);
return fcu;
}