Offset doesn't turn purple when driver added #40350

Closed
opened 2014-05-25 05:30:43 +02:00 by Matt · 26 comments

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.

**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.
Author

Changed status to: 'Open'

Changed status to: 'Open'
Author

Added subscriber: @MattVG-4

Added subscriber: @MattVG-4
Member

Added subscriber: @totoro-4

Added subscriber: @totoro-4
Member

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.

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.

Added subscriber: @mont29

Added subscriber: @mont29

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)!

I can’t confirm this, please test with latest builds from [the buildbot](http://builder.blender.org/download), 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…

> 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…

Added subscriber: @willi-2

Added subscriber: @willi-2

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

Can confirm this on Win7/64, blender-2.70-7fb33e5-win64: ![Bild_333.png](https://archive.blender.org/developer/F90697/Bild_333.png)

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!

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!
Bastien Montagne self-assigned this 2014-05-25 13:56:07 +02:00

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!

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!

Added subscriber: @JoshuaLeung

Added subscriber: @JoshuaLeung

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?

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.

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.
Member

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).

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).
Member

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.
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).

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).
Member

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?

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?

Added subscribers: @brecht, @ideasman42

Added subscribers: @brecht, @ideasman42

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

P68: #40350

diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 80d2750..d804268 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -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_get_driver_path_hack(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
+                               char *base_path);
+
 /* ************************************* */
 /* Batch AnimData API */
 
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 0e86be9..2e6f3f4 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -43,6 +43,7 @@ struct DriverVar;
 struct DriverTarget;
 struct FCM_EnvelopeData;
 
+struct bContext;
 struct bAction;
 struct BezTriple;
 struct StructRNA;
@@ -221,8 +222,9 @@ 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 (context may be NULL). */
+struct FCurve *rna_get_fcurve(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)
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 6a9c4c8..497a67d 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -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"
 
@@ -549,6 +554,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.
+ *
+ * < C: context pointer - for getting active data
+ * <> ptr: RNA pointer for property's datablock. May be modified as result of path remapping.
+ * < prop: RNA definition of property to add for
+ *
+ * > returns: MEM_alloc'd string representing the path to the property from the given PointerRNA
+ */
+char *BKE_get_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 */
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 65b9d21..49b9126 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -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"
@@ -308,21 +309,31 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix,
 	return matches;
 }
 
-FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven)
+FCurve *rna_get_fcurve(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_get_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 +348,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_get_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;
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 8392849..72c437d 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -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.
- *
- * < C: context pointer - for getting active data 
- * <> ptr: RNA pointer for property's datablock. May be modified as result of path remapping.
- * < prop: RNA definition of property to add for
- *
- * > returns: 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_get_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_get_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_get_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_get_driver_path_hack(C, &ptr, prop, NULL);
 		
 		if (path) {
 			/* only copy the driver for the button that this was involved for */
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index fa0832b..fcf3931 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -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(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
 }
 
 void ui_but_anim_flag(uiBut *but, float cfra)
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index ded0278..e5c9c5d 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -1571,7 +1571,7 @@ bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
 		len = RNA_property_array_length(ptr, prop);
 
 	for (index = 0; index < len; index++)
-		if (rna_get_fcurve(ptr, prop, index, NULL, &driven))
+		if (rna_get_fcurve(NULL, ptr, prop, index, NULL, &driven))
 			return true;
 
 	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?

Here is a patch that fixes UI (not `RNA_property_animated()`, though, since there is no context available here :( ): [P68: #40350](https://archive.blender.org/developer/P68.txt) ```diff diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index 80d2750..d804268 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -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_get_driver_path_hack(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, + char *base_path); + /* ************************************* */ /* Batch AnimData API */ diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 0e86be9..2e6f3f4 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -43,6 +43,7 @@ struct DriverVar; struct DriverTarget; struct FCM_EnvelopeData; +struct bContext; struct bAction; struct BezTriple; struct StructRNA; @@ -221,8 +222,9 @@ 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 (context may be NULL). */ +struct FCurve *rna_get_fcurve(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) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 6a9c4c8..497a67d 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -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" @@ -549,6 +554,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. + * + * < C: context pointer - for getting active data + * <> ptr: RNA pointer for property's datablock. May be modified as result of path remapping. + * < prop: RNA definition of property to add for + * + * > returns: MEM_alloc'd string representing the path to the property from the given PointerRNA + */ +char *BKE_get_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 */ diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 65b9d21..49b9126 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -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" @@ -308,21 +309,31 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, return matches; } -FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven) +FCurve *rna_get_fcurve(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_get_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 +348,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_get_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; diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 8392849..72c437d 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -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. - * - * < C: context pointer - for getting active data - * <> ptr: RNA pointer for property's datablock. May be modified as result of path remapping. - * < prop: RNA definition of property to add for - * - * > returns: 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_get_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_get_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_get_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_get_driver_path_hack(C, &ptr, prop, NULL); if (path) { /* only copy the driver for the button that this was involved for */ diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index fa0832b..fcf3931 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -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(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, action, r_driven); } void ui_but_anim_flag(uiBut *but, float cfra) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index ded0278..e5c9c5d 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -1571,7 +1571,7 @@ bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop) len = RNA_property_array_length(ptr, prop); for (index = 0; index < len; index++) - if (rna_get_fcurve(ptr, prop, index, NULL, &driven)) + if (rna_get_fcurve(NULL, ptr, prop, index, NULL, &driven)) return true; 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?
Author

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

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 ](http://i3.photobucket.com/albums/y58/MattVG/Blender271testbuild1-ImageSequenceoffsetfieldfailstoshowpurplewhendriveradded.jpg)

IMHO this should be postponed until after 2.71 release.

IMHO this should be postponed until after 2.71 release.

New patch after talk with Campbell:

P152: Fork of P68 #40350

diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 80d2750..e79822d 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -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 */
 
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 0e86be9..c377769 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -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)
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 5ee82bb..91864b0 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -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 */
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 09c1dcf..de6e6c5 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -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"
@@ -310,19 +311,35 @@ 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;
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 481912f..296a52e 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -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 */
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index fa0832b..48e5427 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -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)

New patch after talk with Campbell: [P152: Fork of P68 #40350](https://archive.blender.org/developer/P152.txt) ```diff diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index 80d2750..e79822d 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -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 */ diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 0e86be9..c377769 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -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) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 5ee82bb..91864b0 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -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 */ diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 09c1dcf..de6e6c5 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -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" @@ -310,19 +311,35 @@ 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; diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 481912f..296a52e 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -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 */ diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index fa0832b..48e5427 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -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) ```

This issue was referenced by 8cb1b35bee

This issue was referenced by 8cb1b35bee80f52e8957ee8855f0a4624b8ad333

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'

Closed by commit 8cb1b35bee.

Closed by commit 8cb1b35bee.
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
7 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#40350
No description provided.