[Bf-blender-cvs] [821722ac057] blender2.8: Interface: Show properties values from evaluated datablocks

Sergey Sharybin noreply at git.blender.org
Tue Apr 17 17:28:21 CEST 2018


Commit: 821722ac057da5fc4614e7696e77d8aa8a2e44c9
Author: Sergey Sharybin
Date:   Tue Apr 17 17:20:34 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB821722ac057da5fc4614e7696e77d8aa8a2e44c9

Interface: Show properties values from evaluated datablocks

This is a way to deal with animated properties in evaluated version
off datablock. Previously, running blender with copy-on-write enabled
will show original values. Now we can see proper properties, while
typing values in still goes to the original datablock.

Thanks Brecht for the review!

===================================================================

M	source/blender/editors/interface/interface.c

===================================================================

diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 12ee1ad35a1..a98d62be3ca 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -51,6 +51,7 @@
 
 #include "BLI_utildefines.h"
 
+#include "BKE_animsys.h"
 #include "BKE_context.h"
 #include "BKE_unit.h"
 #include "BKE_scene.h"
@@ -80,6 +81,8 @@
 
 #include "IMB_colormanagement.h"
 
+#include "DEG_depsgraph_query.h"
+
 #include "interface_intern.h"
 
 /* avoid unneeded calls to ui_but_value_get */
@@ -1705,6 +1708,74 @@ void ui_linkline_remove(uiLinkLine *line, uiBut *but)
  * this either works with the pointed to data, or can work with
  * an edit override pointer while dragging for example */
 
+/* Get PointerRNA which will point to a data inside of an evaluated
+ * ID datablock.
+ */
+static PointerRNA ui_but_evaluated_rnapoin_get(uiBut *but)
+{
+	BLI_assert(but->rnaprop != NULL);
+	/* TODO(sergey): evil_C sounds.. EVIL! Any clear way to avoid this? */
+	PointerRNA rnapoin_eval = but->rnapoin;
+	/* If there is no animation or drivers, it doesn't matter if we read value
+	 * from evaluated datablock or from original one.
+	 *
+	 * Reading from original one is much faster, since we don't need to do any
+	 * PointerRNA remapping or hash lookup.
+	 */
+	if (BKE_animdata_from_id(but->rnapoin.id.data) == NULL) {
+		return rnapoin_eval;
+	}
+	/* Same goes for the properties which can not be animated. */
+	if (!RNA_property_animateable(&but->rnapoin, but->rnaprop)) {
+		return rnapoin_eval;
+	}
+	Depsgraph *depsgraph = CTX_data_depsgraph(but->block->evil_C);
+	/* ID pointer we can always remap, they are inside of depsgraph. */
+	rnapoin_eval.id.data =
+	        DEG_get_evaluated_id(depsgraph, rnapoin_eval.id.data);
+	/* Some of ID datablocks do not have their evaluated copy inside
+	 * of dependency graph. If it's such datablock, no need to worry about
+	 * data pointer.
+	 */
+	if (rnapoin_eval.id.data == but->rnapoin.id.data) {
+		return rnapoin_eval;
+	}
+	/* For the data pointer it's getting a bit more involved, since it can
+	 * whether be and ID, or can be a property deep inside of ID.
+	 *
+	 * We start from checking if it's an ID, since that is the less involved
+	 * code path, and probably is executed in most of the cases.
+	 */
+	if (but->rnapoin.data == but->rnapoin.id.data) {
+		rnapoin_eval.data = DEG_get_evaluated_id(depsgraph, rnapoin_eval.data);
+		return rnapoin_eval;
+	}
+	/* We aren't as lucky as we thought we are :(
+	 *
+	 * Since we don't know what the property is, we get it's RNA path
+	 * relative to the original ID, and then we decent down from evaluated
+	 * ID to the same property.
+	 *
+	 * This seems to be most straightforward way to get sub-data pointers
+	 * which can be buried deep inside of ID block.
+	 */
+	const char *rna_path =
+	       RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
+	if (rna_path != NULL) {
+		PointerRNA id_ptr;
+		RNA_id_pointer_create(rnapoin_eval.id.data, &id_ptr);
+		if (!RNA_path_resolve_full(&id_ptr,
+		                           rna_path,
+		                           &rnapoin_eval,
+		                           NULL, NULL))
+		{
+			/* TODO(sergey): Anything to do here to recover? */
+		}
+		MEM_freeN((void *)rna_path);
+	}
+	return rnapoin_eval;
+}
+
 /* for buttons pointing to color for example */
 void ui_but_v3_get(uiBut *but, float vec[3])
 {
@@ -1720,16 +1791,18 @@ void ui_but_v3_get(uiBut *but, float vec[3])
 
 		zero_v3(vec);
 
+		PointerRNA rnapoin_eval = ui_but_evaluated_rnapoin_get(but);
+
 		if (RNA_property_type(prop) == PROP_FLOAT) {
-			int tot = RNA_property_array_length(&but->rnapoin, prop);
+			int tot = RNA_property_array_length(&rnapoin_eval, prop);
 			BLI_assert(tot > 0);
 			if (tot == 3) {
-				RNA_property_float_get_array(&but->rnapoin, prop, vec);
+				RNA_property_float_get_array(&rnapoin_eval, prop, vec);
 			}
 			else {
 				tot = min_ii(tot, 3);
 				for (a = 0; a < tot; a++) {
-					vec[a] = RNA_property_float_get_index(&but->rnapoin, prop, a);
+					vec[a] = RNA_property_float_get_index(&rnapoin_eval, prop, a);
 				}
 			}
 		}
@@ -1909,27 +1982,29 @@ double ui_but_value_get(uiBut *but)
 
 		BLI_assert(but->rnaindex != -1);
 
+		PointerRNA rnapoin_eval = ui_but_evaluated_rnapoin_get(but);
+
 		switch (RNA_property_type(prop)) {
 			case PROP_BOOLEAN:
 				if (RNA_property_array_check(prop))
-					value = RNA_property_boolean_get_index(&but->rnapoin, prop, but->rnaindex);
+					value = RNA_property_boolean_get_index(&rnapoin_eval, prop, but->rnaindex);
 				else
-					value = RNA_property_boolean_get(&but->rnapoin, prop);
+					value = RNA_property_boolean_get(&rnapoin_eval, prop);
 				break;
 			case PROP_INT:
 				if (RNA_property_array_check(prop))
-					value = RNA_property_int_get_index(&but->rnapoin, prop, but->rnaindex);
+					value = RNA_property_int_get_index(&rnapoin_eval, prop, but->rnaindex);
 				else
-					value = RNA_property_int_get(&but->rnapoin, prop);
+					value = RNA_property_int_get(&rnapoin_eval, prop);
 				break;
 			case PROP_FLOAT:
 				if (RNA_property_array_check(prop))
-					value = RNA_property_float_get_index(&but->rnapoin, prop, but->rnaindex);
+					value = RNA_property_float_get_index(&rnapoin_eval, prop, but->rnaindex);
 				else
-					value = RNA_property_float_get(&but->rnapoin, prop);
+					value = RNA_property_float_get(&rnapoin_eval, prop);
 				break;
 			case PROP_ENUM:
-				value = RNA_property_enum_get(&but->rnapoin, prop);
+				value = RNA_property_enum_get(&rnapoin_eval, prop);
 				break;
 			default:
 				value = 0.0;



More information about the Bf-blender-cvs mailing list