Fix T40350: Some texture prop did not have visual feedback they were driven.

This is only a (hacky) partial fix, actually, since `RNA_property_animated()` will still
not work in those cases... Better that than nothing, though.

Thanks to Campbell for review.
This commit is contained in:
Bastien Montagne 2014-10-06 17:03:19 +02:00
parent 0e7d4a828a
commit 8cb1b35bee
Notes: blender-bot 2023-02-14 10:35:29 +01:00
Referenced by issue #91387, PointerProperty in UI slows down extremely
Referenced by issue #42121, Pre-draw callbacks are not called when rendering dome view
Referenced by issue #40350, Offset doesn't turn purple when driver added
6 changed files with 127 additions and 83 deletions

View File

@ -37,8 +37,10 @@ struct Main;
struct AnimData;
struct KeyingSet;
struct KS_Path;
struct bContext;
struct PointerRNA;
struct PropertyRNA;
struct ReportList;
struct bAction;
struct bActionGroup;
@ -127,6 +129,9 @@ void BKE_animdata_separate_by_basepath(struct ID *srcID, struct ID *dstID, struc
/* Move F-Curves from src to destination if it's path is based on basepath */
void action_move_fcurves_by_basepath(struct bAction *srcAct, struct bAction *dstAct, const char basepath[]);
char *BKE_animdata_driver_path_hack(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
char *base_path);
/* ************************************* */
/* Batch AnimData API */

View File

@ -43,6 +43,7 @@ struct DriverVar;
struct DriverTarget;
struct FCM_EnvelopeData;
struct bContext;
struct bAction;
struct BezTriple;
struct StructRNA;
@ -221,8 +222,12 @@ struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, c
*/
int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName);
/* find an f-curve based on an rna property */
struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, struct bAction **action, bool *r_driven);
/* find an f-curve based on an rna property. */
struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex,
struct bAction **action, bool *r_driven);
/* Same as above, but takes a context data, temp hack needed for complex paths like texture ones. */
struct FCurve *rna_get_fcurve_context_ui(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
int rnaindex, struct bAction **action, bool *r_driven);
/* Binary search algorithm for finding where to 'insert' BezTriple with given frame number.
* Returns the index to insert at (data already at that index will be offset if replace is 0)

View File

@ -51,18 +51,23 @@
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_nla.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_library.h"
#include "BKE_report.h"
#include "BKE_texture.h"
#include "RNA_access.h"
@ -551,6 +556,74 @@ void BKE_animdata_separate_by_basepath(ID *srcID, ID *dstID, ListBase *basepaths
}
}
/**
* Temporary wrapper for driver operators for buttons to make it easier to create
* such drivers by rerouting all paths through the active object instead so that
* they will get picked up by the dependency system.
*
* \param C Context pointer - for getting active data
* \param[in,out] ptr RNA pointer for property's datablock. May be modified as result of path remapping.
* \param prop RNA definition of property to add for
* \return MEM_alloc'd string representing the path to the property from the given #PointerRNA
*/
char *BKE_animdata_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop, char *base_path)
{
ID *id = (ID *)ptr->id.data;
ScrArea *sa = CTX_wm_area(C);
/* get standard path which may be extended */
char *basepath = base_path ? base_path : RNA_path_from_ID_to_property(ptr, prop);
char *path = basepath; /* in case no remapping is needed */
/* Remapping will only be performed in the Properties Editor, as only this
* restricts the subspace of options to the 'active' data (a manageable state)
*/
/* TODO: watch out for pinned context? */
if ((sa) && (sa->spacetype == SPACE_BUTS)) {
Object *ob = CTX_data_active_object(C);
if (ob && id) {
/* only id-types which can be remapped to go through objects should be considered */
switch (GS(id->name)) {
case ID_TE: /* textures */
{
Material *ma = give_current_material(ob, ob->actcol);
Tex *tex = give_current_material_texture(ma);
/* assumes: texture will only be shown if it is active material's active texture it's ok */
if ((ID *)tex == id) {
char name_esc_ma[(sizeof(ma->id.name) - 2) * 2];
char name_esc_tex[(sizeof(tex->id.name) - 2) * 2];
BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma));
BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex));
/* create new path */
// TODO: use RNA path functions to construct step by step instead?
// FIXME: maybe this isn't even needed anymore...
path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s",
name_esc_ma, name_esc_tex, basepath);
/* free old one */
if (basepath != base_path)
MEM_freeN(basepath);
}
break;
}
}
/* fix RNA pointer, as we've now changed the ID root by changing the paths */
if (basepath != path) {
/* rebase provided pointer so that it starts from object... */
RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
}
}
}
/* the path should now have been corrected for use */
return path;
}
/* Path Validation -------------------------------------------- */
/* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */

View File

@ -55,6 +55,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_object.h"
@ -309,20 +310,36 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix,
}
FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven)
{
return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, action, r_driven);
}
FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int rnaindex,
bAction **action, bool *r_driven)
{
FCurve *fcu = NULL;
PointerRNA tptr = *ptr;
*r_driven = false;
/* there must be some RNA-pointer + property combon */
if (prop && ptr->id.data && RNA_property_animateable(ptr, prop)) {
AnimData *adt = BKE_animdata_from_id(ptr->id.data);
char *path;
if (prop && tptr.id.data && RNA_property_animateable(&tptr, prop)) {
AnimData *adt = BKE_animdata_from_id(tptr.id.data);
int step = 2;
char *path = NULL;
if (adt) {
if (adt == NULL) {
path = BKE_animdata_driver_path_hack(C, &tptr, prop, NULL);
adt = BKE_animdata_from_id(tptr.id.data);
step--;
}
while (adt && step--) {
if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
/* XXX this function call can become a performance bottleneck */
path = RNA_path_from_ID_to_property(ptr, prop);
if (step) {
path = RNA_path_from_ID_to_property(&tptr, prop);
}
if (path) {
/* animation takes priority over drivers */
@ -337,13 +354,25 @@ FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction
*r_driven = true;
}
if (fcu && action)
if (fcu && action) {
*action = adt->action;
MEM_freeN(path);
break;
}
else if (step) {
char *tpath = BKE_animdata_driver_path_hack(C, &tptr, prop, path);
if (tpath && tpath != path) {
MEM_freeN(path);
path = tpath;
adt = BKE_animdata_from_id(tptr.id.data);
}
else {
adt = NULL;
}
}
}
}
}
MEM_SAFE_FREE(path);
}
return fcu;

View File

@ -426,74 +426,6 @@ bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int a
/* ************************************************** */
/* UI-Button Interface */
/**
* Temporary wrapper for driver operators for buttons to make it easier to create
* such drivers by rerouting all paths through the active object instead so that
* they will get picked up by the dependency system.
*
* \param C Context pointer - for getting active data
* \param[in,out] ptr RNA pointer for property's datablock. May be modified as result of path remapping.
* \param prop RNA definition of property to add for
* \return MEM_alloc'd string representing the path to the property from the given #PointerRNA
*/
static char *get_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
{
ID *id = (ID *)ptr->id.data;
ScrArea *sa = CTX_wm_area(C);
/* get standard path which may be extended */
char *basepath = RNA_path_from_ID_to_property(ptr, prop);
char *path = basepath; /* in case no remapping is needed */
/* Remapping will only be performed in the Properties Editor, as only this
* restricts the subspace of options to the 'active' data (a manageable state)
*/
// TODO: watch out for pinned context?
if ((sa) && (sa->spacetype == SPACE_BUTS)) {
Object *ob = CTX_data_active_object(C);
if (ob && id) {
/* only id-types which can be remapped to go through objects should be considered */
switch (GS(id->name)) {
case ID_TE: /* textures */
{
Material *ma = give_current_material(ob, ob->actcol);
Tex *tex = give_current_material_texture(ma);
/* assumes: texture will only be shown if it is active material's active texture it's ok */
if ((ID *)tex == id) {
char name_esc_ma[(sizeof(ma->id.name) - 2) * 2];
char name_esc_tex[(sizeof(tex->id.name) - 2) * 2];
BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma));
BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex));
/* create new path */
// TODO: use RNA path functions to construct step by step instead?
// FIXME: maybe this isn't even needed anymore...
path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s",
name_esc_ma, name_esc_tex, basepath);
/* free old one */
MEM_freeN(basepath);
}
break;
}
}
/* fix RNA pointer, as we've now changed the ID root by changing the paths */
if (basepath != path) {
/* rebase provided pointer so that it starts from object... */
RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
}
}
}
/* the path should now have been corrected for use */
return path;
}
/* Add Driver Button Operator ------------------------ */
static int add_driver_button_exec(bContext *C, wmOperator *op)
@ -511,7 +443,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
index = -1;
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
char *path = get_driver_path_hack(C, &ptr, prop);
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
if (path) {
@ -566,7 +498,7 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op)
index = -1;
if (ptr.id.data && ptr.data && prop) {
char *path = get_driver_path_hack(C, &ptr, prop);
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
MEM_freeN(path);
@ -613,7 +545,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op)
uiContextActiveProperty(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
char *path = get_driver_path_hack(C, &ptr, prop);
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
if (path) {
/* only copy the driver for the button that this was involved for */
@ -657,7 +589,7 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
uiContextActiveProperty(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
char *path = get_driver_path_hack(C, &ptr, prop);
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
if (path) {
/* only copy the driver for the button that this was involved for */

View File

@ -61,7 +61,7 @@ static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, bool *r_driven)
* but works well enough in typical cases */
int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex;
return rna_get_fcurve(&but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
}
void ui_but_anim_flag(uiBut *but, float cfra)