forked from blender/blender
main sync #3
@ -218,6 +218,51 @@ static StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr)
|
||||
# include "DEG_depsgraph.h"
|
||||
# include "DEG_depsgraph_build.h"
|
||||
|
||||
/**
|
||||
* \warning this isn't efficient but it's unavoidable
|
||||
* when only the #ID and the #DriverVar are known.
|
||||
*/
|
||||
static FCurve *rna_FCurve_find_driver_by_variable(ID *owner_id, DriverVar *dvar)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(owner_id);
|
||||
BLI_assert(adt != NULL);
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
|
||||
ChannelDriver *driver = fcu->driver;
|
||||
if (driver == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (BLI_findindex(&driver->variables, dvar) != -1) {
|
||||
return fcu;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \warning this isn't efficient but it's unavoidable
|
||||
* when only the #ID and the #DriverTarget are known.
|
||||
*/
|
||||
static FCurve *rna_FCurve_find_driver_by_target(ID *owner_id, DriverTarget *dtar)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(owner_id);
|
||||
BLI_assert(adt != NULL);
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
|
||||
ChannelDriver *driver = fcu->driver;
|
||||
if (driver == NULL) {
|
||||
continue;
|
||||
}
|
||||
LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
|
||||
/* NOTE: Use #MAX_DRIVER_TARGETS instead of `dvar->num_targets` because
|
||||
* it's possible RNA holds a reference to a target that has been removed.
|
||||
* In this case it's best to return the #FCurve it belongs to instead of nothing. */
|
||||
if (ARRAY_HAS_ITEM(dtar, &dvar->targets[0], MAX_DRIVER_TARGETS)) {
|
||||
return fcu;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool rna_ChannelDriver_is_simple_expression_get(PointerRNA *ptr)
|
||||
{
|
||||
ChannelDriver *driver = ptr->data;
|
||||
@ -225,20 +270,27 @@ static bool rna_ChannelDriver_is_simple_expression_get(PointerRNA *ptr)
|
||||
return BKE_driver_has_simple_expression(driver);
|
||||
}
|
||||
|
||||
static void rna_ChannelDriver_update_data(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
static void rna_ChannelDriver_update_data_impl(Main *bmain,
|
||||
Scene *scene,
|
||||
ID *owner_id,
|
||||
ChannelDriver *driver)
|
||||
{
|
||||
ID *id = ptr->owner_id;
|
||||
ChannelDriver *driver = ptr->data;
|
||||
|
||||
driver->flag &= ~DRIVER_FLAG_INVALID;
|
||||
|
||||
/* TODO: this really needs an update guard... */
|
||||
DEG_relations_tag_update(bmain);
|
||||
DEG_id_tag_update(id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
|
||||
DEG_id_tag_update(owner_id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
|
||||
|
||||
WM_main_add_notifier(NC_SCENE | ND_FRAME, scene);
|
||||
}
|
||||
|
||||
static void rna_ChannelDriver_update_data(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
ID *id = ptr->owner_id;
|
||||
ChannelDriver *driver = ptr->data;
|
||||
rna_ChannelDriver_update_data_impl(bmain, scene, id, driver);
|
||||
}
|
||||
|
||||
static void rna_ChannelDriver_update_expr(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
ChannelDriver *driver = ptr->data;
|
||||
@ -252,33 +304,47 @@ static void rna_ChannelDriver_update_expr(Main *bmain, Scene *scene, PointerRNA
|
||||
|
||||
static void rna_DriverTarget_update_data(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
PointerRNA driverptr;
|
||||
ChannelDriver *driver;
|
||||
FCurve *fcu;
|
||||
AnimData *adt = BKE_animdata_from_id(ptr->owner_id);
|
||||
|
||||
/* find the driver this belongs to and update it */
|
||||
for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
|
||||
driver = fcu->driver;
|
||||
DriverTarget *dtar = (DriverTarget *)ptr->data;
|
||||
FCurve *fcu = rna_FCurve_find_driver_by_target(ptr->owner_id, dtar);
|
||||
BLI_assert(fcu); /* This hints at an internal error, data may be corrupt. */
|
||||
if (UNLIKELY(fcu == NULL)) {
|
||||
return;
|
||||
}
|
||||
/* Find function ensures it's never NULL. */
|
||||
ChannelDriver *driver = fcu->driver;
|
||||
fcu->flag &= ~FCURVE_DISABLED;
|
||||
|
||||
if (driver) {
|
||||
/* FIXME: need to be able to search targets for required one. */
|
||||
// BLI_findindex(&driver->targets, ptr->data) != -1)
|
||||
RNA_pointer_create(ptr->owner_id, &RNA_Driver, driver, &driverptr);
|
||||
rna_ChannelDriver_update_data(bmain, scene, &driverptr);
|
||||
}
|
||||
}
|
||||
rna_ChannelDriver_update_data_impl(bmain, scene, ptr->owner_id, driver);
|
||||
}
|
||||
|
||||
static void rna_DriverTarget_update_name(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
static void rna_DriverVariable_update_name(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
ChannelDriver *driver = ptr->data;
|
||||
rna_DriverTarget_update_data(bmain, scene, ptr);
|
||||
|
||||
DriverVar *dvar = (DriverVar *)ptr->data;
|
||||
FCurve *fcu = rna_FCurve_find_driver_by_variable(ptr->owner_id, dvar);
|
||||
BLI_assert(fcu); /* This hints at an internal error, data may be corrupt. */
|
||||
if (UNLIKELY(fcu == NULL)) {
|
||||
return;
|
||||
}
|
||||
/* Find function ensures it's never NULL. */
|
||||
ChannelDriver *driver = fcu->driver;
|
||||
fcu->flag &= ~FCURVE_DISABLED;
|
||||
rna_ChannelDriver_update_data_impl(bmain, scene, ptr->owner_id, driver);
|
||||
BKE_driver_invalidate_expression(driver, false, true);
|
||||
}
|
||||
|
||||
static void rna_DriverVariable_update_data(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
DriverVar *dvar = (DriverVar *)ptr->data;
|
||||
FCurve *fcu = rna_FCurve_find_driver_by_variable(ptr->owner_id, dvar);
|
||||
BLI_assert(fcu); /* This hints at an internal error, data may be corrupt. */
|
||||
if (UNLIKELY(fcu == NULL)) {
|
||||
return;
|
||||
}
|
||||
/* Find function ensures it's never NULL. */
|
||||
ChannelDriver *driver = fcu->driver;
|
||||
fcu->flag &= ~FCURVE_DISABLED;
|
||||
rna_ChannelDriver_update_data_impl(bmain, scene, ptr->owner_id, driver);
|
||||
}
|
||||
|
||||
/* ----------- */
|
||||
|
||||
/* NOTE: this function exists only to avoid id reference-counting. */
|
||||
@ -1951,14 +2017,14 @@ static void rna_def_drivervar(BlenderRNA *brna)
|
||||
"Name",
|
||||
"Name to use in scripted expressions/functions (no spaces or dots are allowed, "
|
||||
"and must start with a letter)");
|
||||
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_name"); /* XXX */
|
||||
RNA_def_property_update(prop, 0, "rna_DriverVariable_update_name");
|
||||
|
||||
/* Enums */
|
||||
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, prop_type_items);
|
||||
RNA_def_property_enum_funcs(prop, NULL, "rna_DriverVariable_type_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Type", "Driver variable type");
|
||||
RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); /* XXX */
|
||||
RNA_def_property_update(prop, 0, "rna_DriverVariable_update_data");
|
||||
|
||||
/* Targets */
|
||||
/* TODO: for nicer api, only expose the relevant props via subclassing,
|
||||
|
Loading…
Reference in New Issue
Block a user