diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-04-17 18:20:34 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-04-17 18:22:33 +0300 |
commit | 821722ac057da5fc4614e7696e77d8aa8a2e44c9 (patch) | |
tree | bf4922673fec710e9515ed74542cf2f2e45832bc /source/blender/editors | |
parent | c6681f735ed5eb517047c62b36a5ea62b22574ea (diff) |
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!
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/interface/interface.c | 95 |
1 files changed, 85 insertions, 10 deletions
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; |