Page MenuHome

Offset doesn't turn purple when driver added
Closed, ResolvedPublic

Description

System Information
Win 7 64bit

Blender Version
Broken: 2.7a (including recent builds)
Worked: none?

Problem
Import a plane, assign an image sequence to it as a texture, right-click the Offset field, Add Driver. The Offset field doesn't change color to indicate a driver has been added. I assume this is a bug.

Related Objects

Event Timeline

Matt (MattVG) raised the priority of this task from to 90.
Matt (MattVG) updated the task description. (Show Details)
Matt (MattVG) added a project: BF Blender.
Matt (MattVG) edited a custom field.
Matt (MattVG) added a subscriber: Matt (MattVG).

Also the "Add driver" option remains in the menu instead of "Remove driver". But it seems the driver is there and produces truncated (rounded towards zero) integers.

Bastien Montagne (mont29) lowered the priority of this task from 90 to 30.May 25 2014, 9:47 AM

I can’t confirm this, please test with latest builds from the buildbot, and attach a simple .blend file to reproduce the issue.

Only thing I do can confirm is that the default interpolation of drivers curves is elastic, which is bad (will fix)!

Only thing I do can confirm is that the default interpolation of drivers curves is elastic, which is bad (will fix)!

Actually, can’t reproduce that with latest master either…

Can confirm this on Win7/64, blender-2.70-7fb33e5-win64:

Bastien Montagne (mont29) raised the priority of this task from 30 to Normal.May 25 2014, 1:55 PM

Arg, we did not talk about the same offset setting (I thought it was mapping offset stuff)! Another illustration of importance of joining a demo .blend file!

Hrrm… on this prop, driver is created in Object's animation_data, while simple fcurves are on Texture one. That’s stupid, one way or the other!

Ok, so culprit is get_driver_path_hack(), which produces ugly complex paths rooted to Object ID for materials' textures, like material_slots["Material"].material.texture_slots["Tex"].texture.image_user.frame_offset, instead of nice simple image_user.frame_offset rooted on texture ID, like anywhere else.

This is done for (again!) depsgraph reasons it seems (though a comment in code suggests it might not be needed anymore). So we either remove this hack, or we tweak rna_get_fcurve() to handle that hack correctly (right now, it’s code simply can’t find drivers with that kind of path).

Joshua, what do you think?

PS: latest option (tweaking rna_get_fcurve()) is probably the only one valid at this stage of release process, removing the hack we do not really have time to test seriously, can backfire easily.

IMO, this is not something very urgent or high priority, and definitely not something new, and not really something I'd consider as a candidate for fixing for the upcoming release (given the current stage in the release cycle).

BTW:

  1. I've just tested removing the hack, and it looks like it's still very much needed. While it might be possible to shorten the path to be rooted on the material instead, that's probably will make things more unstable, since even getting the materials to update is currently a massive hack.
  2. Regard the default interpolation for drivers FCurves - you've probably configured your default interpolation mode to be elastic. So, there shouldn't be any general bug there.

About 2, no, my default is Bezier, but I could never reproduce that, so probably did a wrong manip before I noticed it the first time, definitively not a bug.

About 1, I suspected something like that. Will just update rna_get_fcurve() to handle such situation then (having visual feedback of driven props is rather important, imho).

The driver is working, even it is updating the gui button, so this is not a functional bug. I think the path is working from the driver to the button, but not backwards, right? Why not the driver sets the button state when it updates its displayed value?

Here is a patch that fixes UI (not RNA_property_animated(), though, since there is no context available here :( ):

1diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
2index 80d2750..d804268 100644
3--- a/source/blender/blenkernel/BKE_animsys.h
4+++ b/source/blender/blenkernel/BKE_animsys.h
5@@ -37,8 +37,10 @@ struct Main;
6 struct AnimData;
7 struct KeyingSet;
8 struct KS_Path;
9+struct bContext;
10
11 struct PointerRNA;
12+struct PropertyRNA;
13 struct ReportList;
14 struct bAction;
15 struct bActionGroup;
16@@ -127,6 +129,9 @@ void BKE_animdata_separate_by_basepath(struct ID *srcID, struct ID *dstID, struc
17 /* Move F-Curves from src to destination if it's path is based on basepath */
18 void action_move_fcurves_by_basepath(struct bAction *srcAct, struct bAction *dstAct, const char basepath[]);
19
20+char *BKE_get_driver_path_hack(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
21+ char *base_path);
22+
23 /* ************************************* */
24 /* Batch AnimData API */
25
26diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
27index 0e86be9..2e6f3f4 100644
28--- a/source/blender/blenkernel/BKE_fcurve.h
29+++ b/source/blender/blenkernel/BKE_fcurve.h
30@@ -43,6 +43,7 @@ struct DriverVar;
31 struct DriverTarget;
32 struct FCM_EnvelopeData;
33
34+struct bContext;
35 struct bAction;
36 struct BezTriple;
37 struct StructRNA;
38@@ -221,8 +222,9 @@ struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, c
39 */
40 int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName);
41
42-/* find an f-curve based on an rna property */
43-struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, struct bAction **action, bool *r_driven);
44+/* find an f-curve based on an rna property (context may be NULL). */
45+struct FCurve *rna_get_fcurve(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex,
46+ struct bAction **action, bool *r_driven);
47
48 /* Binary search algorithm for finding where to 'insert' BezTriple with given frame number.
49 * Returns the index to insert at (data already at that index will be offset if replace is 0)
50diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
51index 6a9c4c8..497a67d 100644
52--- a/source/blender/blenkernel/intern/anim_sys.c
53+++ b/source/blender/blenkernel/intern/anim_sys.c
54@@ -51,18 +51,23 @@
55 #include "DNA_material_types.h"
56 #include "DNA_object_types.h"
57 #include "DNA_scene_types.h"
58+#include "DNA_screen_types.h"
59+#include "DNA_space_types.h"
60 #include "DNA_texture_types.h"
61 #include "DNA_world_types.h"
62
63 #include "BKE_animsys.h"
64 #include "BKE_action.h"
65+#include "BKE_context.h"
66 #include "BKE_depsgraph.h"
67 #include "BKE_fcurve.h"
68 #include "BKE_nla.h"
69 #include "BKE_global.h"
70 #include "BKE_main.h"
71+#include "BKE_material.h"
72 #include "BKE_library.h"
73 #include "BKE_report.h"
74+#include "BKE_texture.h"
75
76 #include "RNA_access.h"
77
78@@ -549,6 +554,74 @@ void BKE_animdata_separate_by_basepath(ID *srcID, ID *dstID, ListBase *basepaths
79 }
80 }
81
82+/* Temporary wrapper for driver operators for buttons to make it easier to create
83+ * such drivers by rerouting all paths through the active object instead so that
84+ * they will get picked up by the dependency system.
85+ *
86+ * < C: context pointer - for getting active data
87+ * <> ptr: RNA pointer for property's datablock. May be modified as result of path remapping.
88+ * < prop: RNA definition of property to add for
89+ *
90+ * > returns: MEM_alloc'd string representing the path to the property from the given PointerRNA
91+ */
92+char *BKE_get_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop, char *base_path)
93+{
94+ ID *id = (ID *)ptr->id.data;
95+ ScrArea *sa = CTX_wm_area(C);
96+
97+ /* get standard path which may be extended */
98+ char *basepath = base_path ? base_path : RNA_path_from_ID_to_property(ptr, prop);
99+ char *path = basepath; /* in case no remapping is needed */
100+
101+ /* Remapping will only be performed in the Properties Editor, as only this
102+ * restricts the subspace of options to the 'active' data (a manageable state)
103+ */
104+ // TODO: watch out for pinned context?
105+ if ((sa) && (sa->spacetype == SPACE_BUTS)) {
106+ Object *ob = CTX_data_active_object(C);
107+
108+ if (ob && id) {
109+ /* only id-types which can be remapped to go through objects should be considered */
110+ switch (GS(id->name)) {
111+ case ID_TE: /* textures */
112+ {
113+ Material *ma = give_current_material(ob, ob->actcol);
114+ Tex *tex = give_current_material_texture(ma);
115+
116+ /* assumes: texture will only be shown if it is active material's active texture it's ok */
117+ if ((ID *)tex == id) {
118+ char name_esc_ma[(sizeof(ma->id.name) - 2) * 2];
119+ char name_esc_tex[(sizeof(tex->id.name) - 2) * 2];
120+
121+ BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma));
122+ BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex));
123+
124+ /* create new path */
125+ // TODO: use RNA path functions to construct step by step instead?
126+ // FIXME: maybe this isn't even needed anymore...
127+ path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s",
128+ name_esc_ma, name_esc_tex, basepath);
129+
130+ /* free old one */
131+ if (basepath != base_path)
132+ MEM_freeN(basepath);
133+ }
134+ break;
135+ }
136+ }
137+
138+ /* fix RNA pointer, as we've now changed the ID root by changing the paths */
139+ if (basepath != path) {
140+ /* rebase provided pointer so that it starts from object... */
141+ RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
142+ }
143+ }
144+ }
145+
146+ /* the path should now have been corrected for use */
147+ return path;
148+}
149+
150 /* Path Validation -------------------------------------------- */
151
152 /* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */
153diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
154index 65b9d21..49b9126 100644
155--- a/source/blender/blenkernel/intern/fcurve.c
156+++ b/source/blender/blenkernel/intern/fcurve.c
157@@ -55,6 +55,7 @@
158 #include "BKE_action.h"
159 #include "BKE_armature.h"
160 #include "BKE_constraint.h"
161+#include "BKE_context.h"
162 #include "BKE_curve.h"
163 #include "BKE_global.h"
164 #include "BKE_object.h"
165@@ -308,21 +309,31 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix,
166 return matches;
167 }
168
169-FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven)
170+FCurve *rna_get_fcurve(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven)
171 {
172 FCurve *fcu = NULL;
173+ PointerRNA tptr = *ptr;
174
175 *r_driven = false;
176
177 /* there must be some RNA-pointer + property combon */
178- if (prop && ptr->id.data && RNA_property_animateable(ptr, prop)) {
179- AnimData *adt = BKE_animdata_from_id(ptr->id.data);
180- char *path;
181+ if (prop && tptr.id.data && RNA_property_animateable(&tptr, prop)) {
182+ AnimData *adt = BKE_animdata_from_id(tptr.id.data);
183+ int step = 2;
184+ char *path = NULL;
185
186- if (adt) {
187+ if (adt == NULL) {
188+ path = BKE_get_driver_path_hack(C, &tptr, prop, NULL);
189+ adt = BKE_animdata_from_id(tptr.id.data);
190+ step--;
191+ }
192+
193+ while (adt && step--) {
194 if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
195 /* XXX this function call can become a performance bottleneck */
196- path = RNA_path_from_ID_to_property(ptr, prop);
197+ if (step) {
198+ path = RNA_path_from_ID_to_property(&tptr, prop);
199+ }
200
201 if (path) {
202 /* animation takes priority over drivers */
203@@ -337,13 +348,25 @@ FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction
204 *r_driven = true;
205 }
206
207- if (fcu && action)
208+ if (fcu && action) {
209 *action = adt->action;
210-
211- MEM_freeN(path);
212+ break;
213+ }
214+ else if (step) {
215+ char *tpath = BKE_get_driver_path_hack(C, &tptr, prop, path);
216+ if (tpath && tpath != path) {
217+ MEM_freeN(path);
218+ path = tpath;
219+ adt = BKE_animdata_from_id(tptr.id.data);
220+ }
221+ else {
222+ adt = NULL;
223+ }
224+ }
225 }
226 }
227 }
228+ MEM_SAFE_FREE(path);
229 }
230
231 return fcu;
232diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
233index 8392849..72c437d 100644
234--- a/source/blender/editors/animation/drivers.c
235+++ b/source/blender/editors/animation/drivers.c
236@@ -426,74 +426,6 @@ bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int a
237 /* ************************************************** */
238 /* UI-Button Interface */
239
240-/* Temporary wrapper for driver operators for buttons to make it easier to create
241- * such drivers by rerouting all paths through the active object instead so that
242- * they will get picked up by the dependency system.
243- *
244- * < C: context pointer - for getting active data
245- * <> ptr: RNA pointer for property's datablock. May be modified as result of path remapping.
246- * < prop: RNA definition of property to add for
247- *
248- * > returns: MEM_alloc'd string representing the path to the property from the given PointerRNA
249- */
250-static char *get_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
251-{
252- ID *id = (ID *)ptr->id.data;
253- ScrArea *sa = CTX_wm_area(C);
254-
255- /* get standard path which may be extended */
256- char *basepath = RNA_path_from_ID_to_property(ptr, prop);
257- char *path = basepath; /* in case no remapping is needed */
258-
259-
260- /* Remapping will only be performed in the Properties Editor, as only this
261- * restricts the subspace of options to the 'active' data (a manageable state)
262- */
263- // TODO: watch out for pinned context?
264- if ((sa) && (sa->spacetype == SPACE_BUTS)) {
265- Object *ob = CTX_data_active_object(C);
266-
267- if (ob && id) {
268- /* only id-types which can be remapped to go through objects should be considered */
269- switch (GS(id->name)) {
270- case ID_TE: /* textures */
271- {
272- Material *ma = give_current_material(ob, ob->actcol);
273- Tex *tex = give_current_material_texture(ma);
274-
275- /* assumes: texture will only be shown if it is active material's active texture it's ok */
276- if ((ID *)tex == id) {
277- char name_esc_ma[(sizeof(ma->id.name) - 2) * 2];
278- char name_esc_tex[(sizeof(tex->id.name) - 2) * 2];
279-
280- BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma));
281- BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex));
282-
283- /* create new path */
284- // TODO: use RNA path functions to construct step by step instead?
285- // FIXME: maybe this isn't even needed anymore...
286- path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s",
287- name_esc_ma, name_esc_tex, basepath);
288-
289- /* free old one */
290- MEM_freeN(basepath);
291- }
292- break;
293- }
294- }
295-
296- /* fix RNA pointer, as we've now changed the ID root by changing the paths */
297- if (basepath != path) {
298- /* rebase provided pointer so that it starts from object... */
299- RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
300- }
301- }
302- }
303-
304- /* the path should now have been corrected for use */
305- return path;
306-}
307-
308 /* Add Driver Button Operator ------------------------ */
309
310 static int add_driver_button_exec(bContext *C, wmOperator *op)
311@@ -511,7 +443,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
312 index = -1;
313
314 if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
315- char *path = get_driver_path_hack(C, &ptr, prop);
316+ char *path = BKE_get_driver_path_hack(C, &ptr, prop, NULL);
317 short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
318
319 if (path) {
320@@ -566,7 +498,7 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op)
321 index = -1;
322
323 if (ptr.id.data && ptr.data && prop) {
324- char *path = get_driver_path_hack(C, &ptr, prop);
325+ char *path = BKE_get_driver_path_hack(C, &ptr, prop, NULL);
326
327 success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
328 MEM_freeN(path);
329@@ -613,7 +545,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op)
330 uiContextActiveProperty(C, &ptr, &prop, &index);
331
332 if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
333- char *path = get_driver_path_hack(C, &ptr, prop);
334+ char *path = BKE_get_driver_path_hack(C, &ptr, prop, NULL);
335
336 if (path) {
337 /* only copy the driver for the button that this was involved for */
338@@ -657,7 +589,7 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
339 uiContextActiveProperty(C, &ptr, &prop, &index);
340
341 if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
342- char *path = get_driver_path_hack(C, &ptr, prop);
343+ char *path = BKE_get_driver_path_hack(C, &ptr, prop, NULL);
344
345 if (path) {
346 /* only copy the driver for the button that this was involved for */
347diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
348index fa0832b..fcf3931 100644
349--- a/source/blender/editors/interface/interface_anim.c
350+++ b/source/blender/editors/interface/interface_anim.c
351@@ -61,7 +61,7 @@ static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, bool *r_driven)
352 * but works well enough in typical cases */
353 int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex;
354
355- return rna_get_fcurve(&but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
356+ return rna_get_fcurve(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
357 }
358
359 void ui_but_anim_flag(uiBut *but, float cfra)
360diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
361index ded0278..e5c9c5d 100644
362--- a/source/blender/makesrna/intern/rna_access.c
363+++ b/source/blender/makesrna/intern/rna_access.c
364@@ -1571,7 +1571,7 @@ bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
365 len = RNA_property_array_length(ptr, prop);
366
367 for (index = 0; index < len; index++)
368- if (rna_get_fcurve(ptr, prop, index, NULL, &driven))
369+ if (rna_get_fcurve(NULL, ptr, prop, index, NULL, &driven))
370 return true;
371
372 return false;

Unfortunately, it makes things even more hacky… brecht, campbell, what do you think, can we accept that driven texture properties do not appear as such in the UI? Or can we accept to add more hackish code here?

Regarding the initial bug:

I apologize for not being clear. I was rushed when I was reporting. Here's a screenshot from Blender 2.71 testbuild 1. Blender Internal. I used the Import Image as Plane addon if that makes a difference.

Screenshot

IMHO this should be postponed until after 2.71 release.

New patch after talk with Campbell:

1diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
2index 80d2750..e79822d 100644
3--- a/source/blender/blenkernel/BKE_animsys.h
4+++ b/source/blender/blenkernel/BKE_animsys.h
5@@ -37,8 +37,10 @@ struct Main;
6 struct AnimData;
7 struct KeyingSet;
8 struct KS_Path;
9+struct bContext;
10
11 struct PointerRNA;
12+struct PropertyRNA;
13 struct ReportList;
14 struct bAction;
15 struct bActionGroup;
16@@ -127,6 +129,9 @@ void BKE_animdata_separate_by_basepath(struct ID *srcID, struct ID *dstID, struc
17 /* Move F-Curves from src to destination if it's path is based on basepath */
18 void action_move_fcurves_by_basepath(struct bAction *srcAct, struct bAction *dstAct, const char basepath[]);
19
20+char *BKE_animdata_driver_path_hack(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
21+ char *base_path);
22+
23 /* ************************************* */
24 /* Batch AnimData API */
25
26diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
27index 0e86be9..c377769 100644
28--- a/source/blender/blenkernel/BKE_fcurve.h
29+++ b/source/blender/blenkernel/BKE_fcurve.h
30@@ -43,6 +43,7 @@ struct DriverVar;
31 struct DriverTarget;
32 struct FCM_EnvelopeData;
33
34+struct bContext;
35 struct bAction;
36 struct BezTriple;
37 struct StructRNA;
38@@ -221,8 +222,12 @@ struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, c
39 */
40 int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName);
41
42-/* find an f-curve based on an rna property */
43-struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, struct bAction **action, bool *r_driven);
44+/* find an f-curve based on an rna property. */
45+struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex,
46+ struct bAction **action, bool *r_driven);
47+/* Same as above, but takes a context data, temp hack needed for complex paths like texture ones. */
48+struct FCurve *rna_get_fcurve_context_ui(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
49+ int rnaindex, struct bAction **action, bool *r_driven);
50
51 /* Binary search algorithm for finding where to 'insert' BezTriple with given frame number.
52 * Returns the index to insert at (data already at that index will be offset if replace is 0)
53diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
54index 5ee82bb..91864b0 100644
55--- a/source/blender/blenkernel/intern/anim_sys.c
56+++ b/source/blender/blenkernel/intern/anim_sys.c
57@@ -51,18 +51,23 @@
58 #include "DNA_material_types.h"
59 #include "DNA_object_types.h"
60 #include "DNA_scene_types.h"
61+#include "DNA_screen_types.h"
62+#include "DNA_space_types.h"
63 #include "DNA_texture_types.h"
64 #include "DNA_world_types.h"
65
66 #include "BKE_animsys.h"
67 #include "BKE_action.h"
68+#include "BKE_context.h"
69 #include "BKE_depsgraph.h"
70 #include "BKE_fcurve.h"
71 #include "BKE_nla.h"
72 #include "BKE_global.h"
73 #include "BKE_main.h"
74+#include "BKE_material.h"
75 #include "BKE_library.h"
76 #include "BKE_report.h"
77+#include "BKE_texture.h"
78
79 #include "RNA_access.h"
80
81@@ -551,6 +556,74 @@ void BKE_animdata_separate_by_basepath(ID *srcID, ID *dstID, ListBase *basepaths
82 }
83 }
84
85+/**
86+ * Temporary wrapper for driver operators for buttons to make it easier to create
87+ * such drivers by rerouting all paths through the active object instead so that
88+ * they will get picked up by the dependency system.
89+ *
90+ * \param C Context pointer - for getting active data
91+ * \param[in,out] ptr RNA pointer for property's datablock. May be modified as result of path remapping.
92+ * \param prop RNA definition of property to add for
93+ * \return MEM_alloc'd string representing the path to the property from the given #PointerRNA
94+ */
95+char *BKE_animdata_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop, char *base_path)
96+{
97+ ID *id = (ID *)ptr->id.data;
98+ ScrArea *sa = CTX_wm_area(C);
99+
100+ /* get standard path which may be extended */
101+ char *basepath = base_path ? base_path : RNA_path_from_ID_to_property(ptr, prop);
102+ char *path = basepath; /* in case no remapping is needed */
103+
104+ /* Remapping will only be performed in the Properties Editor, as only this
105+ * restricts the subspace of options to the 'active' data (a manageable state)
106+ */
107+ // TODO: watch out for pinned context?
108+ if ((sa) && (sa->spacetype == SPACE_BUTS)) {
109+ Object *ob = CTX_data_active_object(C);
110+
111+ if (ob && id) {
112+ /* only id-types which can be remapped to go through objects should be considered */
113+ switch (GS(id->name)) {
114+ case ID_TE: /* textures */
115+ {
116+ Material *ma = give_current_material(ob, ob->actcol);
117+ Tex *tex = give_current_material_texture(ma);
118+
119+ /* assumes: texture will only be shown if it is active material's active texture it's ok */
120+ if ((ID *)tex == id) {
121+ char name_esc_ma[(sizeof(ma->id.name) - 2) * 2];
122+ char name_esc_tex[(sizeof(tex->id.name) - 2) * 2];
123+
124+ BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma));
125+ BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex));
126+
127+ /* create new path */
128+ // TODO: use RNA path functions to construct step by step instead?
129+ // FIXME: maybe this isn't even needed anymore...
130+ path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s",
131+ name_esc_ma, name_esc_tex, basepath);
132+
133+ /* free old one */
134+ if (basepath != base_path)
135+ MEM_freeN(basepath);
136+ }
137+ break;
138+ }
139+ }
140+
141+ /* fix RNA pointer, as we've now changed the ID root by changing the paths */
142+ if (basepath != path) {
143+ /* rebase provided pointer so that it starts from object... */
144+ RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
145+ }
146+ }
147+ }
148+
149+ /* the path should now have been corrected for use */
150+ return path;
151+}
152+
153 /* Path Validation -------------------------------------------- */
154
155 /* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */
156diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
157index 09c1dcf..de6e6c5 100644
158--- a/source/blender/blenkernel/intern/fcurve.c
159+++ b/source/blender/blenkernel/intern/fcurve.c
160@@ -55,6 +55,7 @@
161 #include "BKE_action.h"
162 #include "BKE_armature.h"
163 #include "BKE_constraint.h"
164+#include "BKE_context.h"
165 #include "BKE_curve.h"
166 #include "BKE_global.h"
167 #include "BKE_object.h"
168@@ -310,19 +311,35 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix,
169
170 FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven)
171 {
172+ return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, action, r_driven);
173+}
174+
175+FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int rnaindex,
176+ bAction **action, bool *r_driven)
177+{
178 FCurve *fcu = NULL;
179+ PointerRNA tptr = *ptr;
180
181 *r_driven = false;
182
183 /* there must be some RNA-pointer + property combon */
184- if (prop && ptr->id.data && RNA_property_animateable(ptr, prop)) {
185- AnimData *adt = BKE_animdata_from_id(ptr->id.data);
186- char *path;
187+ if (prop && tptr.id.data && RNA_property_animateable(&tptr, prop)) {
188+ AnimData *adt = BKE_animdata_from_id(tptr.id.data);
189+ int step = 2;
190+ char *path = NULL;
191
192- if (adt) {
193+ if (adt == NULL) {
194+ path = BKE_animdata_driver_path_hack(C, &tptr, prop, NULL);
195+ adt = BKE_animdata_from_id(tptr.id.data);
196+ step--;
197+ }
198+
199+ while (adt && step--) {
200 if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
201 /* XXX this function call can become a performance bottleneck */
202- path = RNA_path_from_ID_to_property(ptr, prop);
203+ if (step) {
204+ path = RNA_path_from_ID_to_property(&tptr, prop);
205+ }
206
207 if (path) {
208 /* animation takes priority over drivers */
209@@ -337,13 +354,25 @@ FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction
210 *r_driven = true;
211 }
212
213- if (fcu && action)
214+ if (fcu && action) {
215 *action = adt->action;
216-
217- MEM_freeN(path);
218+ break;
219+ }
220+ else if (step) {
221+ char *tpath = BKE_animdata_driver_path_hack(C, &tptr, prop, path);
222+ if (tpath && tpath != path) {
223+ MEM_freeN(path);
224+ path = tpath;
225+ adt = BKE_animdata_from_id(tptr.id.data);
226+ }
227+ else {
228+ adt = NULL;
229+ }
230+ }
231 }
232 }
233 }
234+ MEM_SAFE_FREE(path);
235 }
236
237 return fcu;
238diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
239index 481912f..296a52e 100644
240--- a/source/blender/editors/animation/drivers.c
241+++ b/source/blender/editors/animation/drivers.c
242@@ -426,74 +426,6 @@ bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int a
243 /* ************************************************** */
244 /* UI-Button Interface */
245
246-/**
247- * Temporary wrapper for driver operators for buttons to make it easier to create
248- * such drivers by rerouting all paths through the active object instead so that
249- * they will get picked up by the dependency system.
250- *
251- * \param C Context pointer - for getting active data
252- * \param[in,out] ptr RNA pointer for property's datablock. May be modified as result of path remapping.
253- * \param prop RNA definition of property to add for
254- * \return MEM_alloc'd string representing the path to the property from the given #PointerRNA
255- */
256-static char *get_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
257-{
258- ID *id = (ID *)ptr->id.data;
259- ScrArea *sa = CTX_wm_area(C);
260-
261- /* get standard path which may be extended */
262- char *basepath = RNA_path_from_ID_to_property(ptr, prop);
263- char *path = basepath; /* in case no remapping is needed */
264-
265-
266- /* Remapping will only be performed in the Properties Editor, as only this
267- * restricts the subspace of options to the 'active' data (a manageable state)
268- */
269- // TODO: watch out for pinned context?
270- if ((sa) && (sa->spacetype == SPACE_BUTS)) {
271- Object *ob = CTX_data_active_object(C);
272-
273- if (ob && id) {
274- /* only id-types which can be remapped to go through objects should be considered */
275- switch (GS(id->name)) {
276- case ID_TE: /* textures */
277- {
278- Material *ma = give_current_material(ob, ob->actcol);
279- Tex *tex = give_current_material_texture(ma);
280-
281- /* assumes: texture will only be shown if it is active material's active texture it's ok */
282- if ((ID *)tex == id) {
283- char name_esc_ma[(sizeof(ma->id.name) - 2) * 2];
284- char name_esc_tex[(sizeof(tex->id.name) - 2) * 2];
285-
286- BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma));
287- BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex));
288-
289- /* create new path */
290- // TODO: use RNA path functions to construct step by step instead?
291- // FIXME: maybe this isn't even needed anymore...
292- path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s",
293- name_esc_ma, name_esc_tex, basepath);
294-
295- /* free old one */
296- MEM_freeN(basepath);
297- }
298- break;
299- }
300- }
301-
302- /* fix RNA pointer, as we've now changed the ID root by changing the paths */
303- if (basepath != path) {
304- /* rebase provided pointer so that it starts from object... */
305- RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
306- }
307- }
308- }
309-
310- /* the path should now have been corrected for use */
311- return path;
312-}
313-
314 /* Add Driver Button Operator ------------------------ */
315
316 static int add_driver_button_exec(bContext *C, wmOperator *op)
317@@ -511,7 +443,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
318 index = -1;
319
320 if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
321- char *path = get_driver_path_hack(C, &ptr, prop);
322+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
323 short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
324
325 if (path) {
326@@ -566,7 +498,7 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op)
327 index = -1;
328
329 if (ptr.id.data && ptr.data && prop) {
330- char *path = get_driver_path_hack(C, &ptr, prop);
331+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
332
333 success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
334 MEM_freeN(path);
335@@ -613,7 +545,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op)
336 uiContextActiveProperty(C, &ptr, &prop, &index);
337
338 if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
339- char *path = get_driver_path_hack(C, &ptr, prop);
340+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
341
342 if (path) {
343 /* only copy the driver for the button that this was involved for */
344@@ -657,7 +589,7 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
345 uiContextActiveProperty(C, &ptr, &prop, &index);
346
347 if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
348- char *path = get_driver_path_hack(C, &ptr, prop);
349+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
350
351 if (path) {
352 /* only copy the driver for the button that this was involved for */
353diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
354index fa0832b..48e5427 100644
355--- a/source/blender/editors/interface/interface_anim.c
356+++ b/source/blender/editors/interface/interface_anim.c
357@@ -61,7 +61,7 @@ static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, bool *r_driven)
358 * but works well enough in typical cases */
359 int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex;
360
361- return rna_get_fcurve(&but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
362+ return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
363 }
364
365 void ui_but_anim_flag(uiBut *but, float cfra)