forked from bartvdbraak/blender
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:
parent
0e7d4a828a
commit
8cb1b35bee
@ -37,8 +37,10 @@ struct Main;
|
|||||||
struct AnimData;
|
struct AnimData;
|
||||||
struct KeyingSet;
|
struct KeyingSet;
|
||||||
struct KS_Path;
|
struct KS_Path;
|
||||||
|
struct bContext;
|
||||||
|
|
||||||
struct PointerRNA;
|
struct PointerRNA;
|
||||||
|
struct PropertyRNA;
|
||||||
struct ReportList;
|
struct ReportList;
|
||||||
struct bAction;
|
struct bAction;
|
||||||
struct bActionGroup;
|
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 */
|
/* 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[]);
|
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 */
|
/* Batch AnimData API */
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ struct DriverVar;
|
|||||||
struct DriverTarget;
|
struct DriverTarget;
|
||||||
struct FCM_EnvelopeData;
|
struct FCM_EnvelopeData;
|
||||||
|
|
||||||
|
struct bContext;
|
||||||
struct bAction;
|
struct bAction;
|
||||||
struct BezTriple;
|
struct BezTriple;
|
||||||
struct StructRNA;
|
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);
|
int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName);
|
||||||
|
|
||||||
/* find an f-curve based on an rna property */
|
/* 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);
|
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.
|
/* 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)
|
* Returns the index to insert at (data already at that index will be offset if replace is 0)
|
||||||
|
@ -51,18 +51,23 @@
|
|||||||
#include "DNA_material_types.h"
|
#include "DNA_material_types.h"
|
||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
|
#include "DNA_screen_types.h"
|
||||||
|
#include "DNA_space_types.h"
|
||||||
#include "DNA_texture_types.h"
|
#include "DNA_texture_types.h"
|
||||||
#include "DNA_world_types.h"
|
#include "DNA_world_types.h"
|
||||||
|
|
||||||
#include "BKE_animsys.h"
|
#include "BKE_animsys.h"
|
||||||
#include "BKE_action.h"
|
#include "BKE_action.h"
|
||||||
|
#include "BKE_context.h"
|
||||||
#include "BKE_depsgraph.h"
|
#include "BKE_depsgraph.h"
|
||||||
#include "BKE_fcurve.h"
|
#include "BKE_fcurve.h"
|
||||||
#include "BKE_nla.h"
|
#include "BKE_nla.h"
|
||||||
#include "BKE_global.h"
|
#include "BKE_global.h"
|
||||||
#include "BKE_main.h"
|
#include "BKE_main.h"
|
||||||
|
#include "BKE_material.h"
|
||||||
#include "BKE_library.h"
|
#include "BKE_library.h"
|
||||||
#include "BKE_report.h"
|
#include "BKE_report.h"
|
||||||
|
#include "BKE_texture.h"
|
||||||
|
|
||||||
#include "RNA_access.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 -------------------------------------------- */
|
/* Path Validation -------------------------------------------- */
|
||||||
|
|
||||||
/* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */
|
/* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include "BKE_action.h"
|
#include "BKE_action.h"
|
||||||
#include "BKE_armature.h"
|
#include "BKE_armature.h"
|
||||||
#include "BKE_constraint.h"
|
#include "BKE_constraint.h"
|
||||||
|
#include "BKE_context.h"
|
||||||
#include "BKE_curve.h"
|
#include "BKE_curve.h"
|
||||||
#include "BKE_global.h"
|
#include "BKE_global.h"
|
||||||
#include "BKE_object.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)
|
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;
|
FCurve *fcu = NULL;
|
||||||
|
PointerRNA tptr = *ptr;
|
||||||
|
|
||||||
*r_driven = false;
|
*r_driven = false;
|
||||||
|
|
||||||
/* there must be some RNA-pointer + property combon */
|
/* there must be some RNA-pointer + property combon */
|
||||||
if (prop && ptr->id.data && RNA_property_animateable(ptr, prop)) {
|
if (prop && tptr.id.data && RNA_property_animateable(&tptr, prop)) {
|
||||||
AnimData *adt = BKE_animdata_from_id(ptr->id.data);
|
AnimData *adt = BKE_animdata_from_id(tptr.id.data);
|
||||||
char *path;
|
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)) {
|
if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
|
||||||
/* XXX this function call can become a performance bottleneck */
|
/* 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) {
|
if (path) {
|
||||||
/* animation takes priority over drivers */
|
/* animation takes priority over drivers */
|
||||||
@ -337,13 +354,25 @@ FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction
|
|||||||
*r_driven = true;
|
*r_driven = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fcu && action)
|
if (fcu && action) {
|
||||||
*action = adt->action;
|
*action = adt->action;
|
||||||
|
break;
|
||||||
MEM_freeN(path);
|
}
|
||||||
|
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;
|
return fcu;
|
||||||
|
@ -426,74 +426,6 @@ bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int a
|
|||||||
/* ************************************************** */
|
/* ************************************************** */
|
||||||
/* UI-Button Interface */
|
/* 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 ------------------------ */
|
/* Add Driver Button Operator ------------------------ */
|
||||||
|
|
||||||
static int add_driver_button_exec(bContext *C, wmOperator *op)
|
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;
|
index = -1;
|
||||||
|
|
||||||
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
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;
|
short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
@ -566,7 +498,7 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op)
|
|||||||
index = -1;
|
index = -1;
|
||||||
|
|
||||||
if (ptr.id.data && ptr.data && prop) {
|
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);
|
success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
|
||||||
MEM_freeN(path);
|
MEM_freeN(path);
|
||||||
@ -613,7 +545,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op)
|
|||||||
uiContextActiveProperty(C, &ptr, &prop, &index);
|
uiContextActiveProperty(C, &ptr, &prop, &index);
|
||||||
|
|
||||||
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
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) {
|
if (path) {
|
||||||
/* only copy the driver for the button that this was involved for */
|
/* 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);
|
uiContextActiveProperty(C, &ptr, &prop, &index);
|
||||||
|
|
||||||
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
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) {
|
if (path) {
|
||||||
/* only copy the driver for the button that this was involved for */
|
/* only copy the driver for the button that this was involved for */
|
||||||
|
@ -61,7 +61,7 @@ static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, bool *r_driven)
|
|||||||
* but works well enough in typical cases */
|
* but works well enough in typical cases */
|
||||||
int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex;
|
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)
|
void ui_but_anim_flag(uiBut *but, float cfra)
|
||||||
|
Loading…
Reference in New Issue
Block a user