[Bf-blender-cvs] [575e62f] id_override_static: More WIP work towards supporting override differentila operations.
Bastien Montagne
noreply at git.blender.org
Thu Jan 5 20:51:41 CET 2017
Commit: 575e62f051ad2f2e628b2141211599e652d680ee
Author: Bastien Montagne
Date: Thu Jan 5 20:50:51 2017 +0100
Branches: id_override_static
https://developer.blender.org/rB575e62f051ad2f2e628b2141211599e652d680ee
More WIP work towards supporting override differentila operations.
Code compiles, is mostly neither tested nor hooked to anything yet.
===================================================================
M source/blender/blenkernel/BKE_library_override.h
M source/blender/blenkernel/intern/library_override.c
M source/blender/blenloader/intern/readfile.c
M source/blender/makesrna/RNA_access.h
M source/blender/makesrna/intern/rna_access.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_library_override.h b/source/blender/blenkernel/BKE_library_override.h
index 0ab90ed..68238df 100644
--- a/source/blender/blenkernel/BKE_library_override.h
+++ b/source/blender/blenkernel/BKE_library_override.h
@@ -59,8 +59,8 @@ bool BKE_override_status_check_reference(struct ID *local);
bool BKE_override_operations_create(struct ID *local);
-void BKE_override_update(struct ID *local);
-void BKE_main_override_update(struct Main *bmain);
+void BKE_override_update(struct ID *local, const bool do_init);
+void BKE_main_override_update(struct Main *bmain, const bool do_init);
#endif /* __BKE_LIBRARY_OVERRIDE_H__ */
diff --git a/source/blender/blenkernel/intern/library_override.c b/source/blender/blenkernel/intern/library_override.c
index f65d31a..77dffa4 100644
--- a/source/blender/blenkernel/intern/library_override.c
+++ b/source/blender/blenkernel/intern/library_override.c
@@ -290,7 +290,7 @@ bool BKE_override_operations_create(ID *local)
}
/** Update given override from its reference (re-applying overriden properties). */
-void BKE_override_update(ID *local)
+void BKE_override_update(ID *local, const bool do_init)
{
if (local->override == NULL) {
return;
@@ -298,7 +298,7 @@ void BKE_override_update(ID *local)
/* Recursively do 'ancestors' overrides first, if any. */
if (local->override->reference->override && (local->override->reference->tag & LIB_TAG_OVERRIDE_OK) == 0) {
- BKE_override_update(local->override->reference);
+ BKE_override_update(local->override->reference, do_init);
}
/* We want to avoid having to remap here, however creating up-to-date override is much simpler if based
@@ -323,7 +323,7 @@ void BKE_override_update(ID *local)
RNA_id_pointer_create(local, &rnaptr_local);
RNA_id_pointer_create(tmp_id, &rnaptr_final);
- RNA_struct_override_apply(&rnaptr_final, &rnaptr_local, local->override);
+ RNA_struct_override_apply(&rnaptr_final, &rnaptr_local, local->override, do_init);
/* This also transfers all pointers (memory) owned by local to tmp_id, and vice-versa. So when we'll free tmp_id,
* we'll actually free old, outdated data from local. */
@@ -336,7 +336,7 @@ void BKE_override_update(ID *local)
}
/** Update all overrides from given \a bmain. */
-void BKE_main_override_update(Main *bmain)
+void BKE_main_override_update(Main *bmain, const bool do_init)
{
ListBase *lbarray[MAX_LIBARRAY];
int base_count, i;
@@ -349,7 +349,7 @@ void BKE_main_override_update(Main *bmain)
for (id = lb->first; id; id = id->next) {
if (id->override != NULL && id->lib == NULL) {
- BKE_override_update(id);
+ BKE_override_update(id, do_init);
}
}
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index c6aad1b..ed6d16c 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8644,7 +8644,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
BKE_main_id_tag_all(bfd->main, LIB_TAG_NEW, false);
/* Now that all our data-blocks are loaded, we can re-generate overrides from their references. */
- BKE_main_override_update(bfd->main);
+ if (fd->memfile == NULL) {
+ /* Do not apply in undo case! */
+ BKE_main_override_update(bfd->main, true);
+ }
lib_verify_nodetree(bfd->main, true);
fix_relpaths_library(fd->relabase, bfd->main); /* make all relative paths, relative to the open blend file */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 9aa07ab..0c2aac3 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1221,9 +1221,11 @@ bool RNA_struct_equals(struct PointerRNA *a, struct PointerRNA *b, eRNAEqualsMod
bool RNA_struct_override_matches(struct PointerRNA *local, struct PointerRNA *reference,
struct IDOverride *override, const bool ignore_non_overridable, const bool ignore_overridden);
-void RNA_property_override_apply(struct PointerRNA *dst,
- struct PointerRNA *src, struct PropertyRNA *prop, struct IDOverrideProperty *op);
-void RNA_struct_override_apply(struct PointerRNA *dst, struct PointerRNA *src, struct IDOverride *override);
+void RNA_property_override_apply(
+ struct PointerRNA *dst, struct PointerRNA *src, struct PropertyRNA *prop,
+ struct IDOverrideProperty *op, const bool do_init);
+void RNA_struct_override_apply(
+ struct PointerRNA *dst, struct PointerRNA *src, struct IDOverride *override, const bool do_init);
bool RNA_struct_auto_override(struct PointerRNA *local, struct PointerRNA *reference, struct IDOverride *override);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 29f0425..6b61117 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -6758,12 +6758,11 @@ bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
}
}
-static bool rna_property_override_operation_apply(
- PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index, int override_op);
+static bool rna_property_override_operation_apply(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index, int override_op, const bool do_init);
bool RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index)
{
- return rna_property_override_operation_apply(ptr, fromptr, prop, index, IDOVERRIDE_REPLACE);
+ return rna_property_override_operation_apply(ptr, fromptr, prop, index, IDOVERRIDE_REPLACE, false);
}
/* use RNA_warning macro which includes __func__ suffix */
@@ -7131,7 +7130,7 @@ static bool rna_property_override_equals(
}
static bool rna_property_override_operation_apply(
- PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index, int override_op)
+ PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index, int override_op, const bool do_init)
{
int len, fromlen;
PropertyRNA *fromprop = prop;
@@ -7140,6 +7139,13 @@ static bool rna_property_override_operation_apply(
return false;
}
+ if (ELEM(override_op, IDOVERRIDE_ADD, IDOVERRIDE_SUBTRACT, IDOVERRIDE_MULTIPLY) && !do_init) {
+ /* We cannot re-apply (aka update) 'diff' override operations, those assume that the current values
+ * in local data-block are other operands of the diff, which is only true in small number of cases
+ * (mainly right after reading them from .blend file currently!). */
+ return false;
+ }
+
if (prop->magic != RNA_MAGIC) {
/* In case of IDProperty, we have to find the *real* idprop of ptr,
* since prop in this case is just a fake wrapper around actual IDProp data, and not a 'real' PropertyRNA. */
@@ -7420,6 +7426,334 @@ static bool rna_property_override_operation_apply(
return false;
}
+/* Modify local data-block to make it ready for override application (only needed for diff operations, where we use
+ * the local data-block's data as second operand). */
+static bool rna_property_override_operation_store(
+ PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, IDOverrideProperty *op)
+{
+ int len, fromlen;
+ PropertyRNA *fromprop = prop;
+ bool changed = false;
+
+ if (prop->magic != RNA_MAGIC) {
+ /* In case of IDProperty, we have to find the *real* idprop of ptr,
+ * since prop in this case is just a fake wrapper around actual IDProp data, and not a 'real' PropertyRNA. */
+ prop = (PropertyRNA *)rna_idproperty_find(ptr, ((IDProperty *)fromprop)->name);
+
+ /* its possible the custom-prop doesn't exist on this data-block */
+ if (prop == NULL) {
+ return false;
+ }
+
+ /* Even though currently we now prop will always be the 'fromprop', this might not be the case in the future. */
+ if (prop == fromprop) {
+ fromprop = (PropertyRNA *)rna_idproperty_find(fromptr, ((IDProperty *)prop)->name);
+ }
+ }
+
+ /* get the length of the array to work with */
+ len = RNA_property_array_length(ptr, prop);
+ fromlen = RNA_property_array_length(fromptr, fromprop);
+
+ if (len != fromlen) {
+ /* Do not handle override in that case, we do not support insertion/deletion from arrays for now. */
+ return changed;
+ }
+
+ for (IDOverridePropertyOperation *opop = op->operations.first; opop; opop = opop->next) {
+ /* Only needed for dii operations. */
+ if (!ELEM(opop->operation, IDOVERRIDE_ADD, IDOVERRIDE_SUBTRACT, IDOVERRIDE_MULTIPLY)) {
+ continue;
+ }
+
+ const int index = opop->subitem_reference_index;
+
+ /* XXX TODO About range limits.
+ * Ideally, it woudl be great to get rid of RNA range in that specific case.
+ * However, this won't be that easy and will add yet another layer of complexity in generated code,
+ * not to mention that we could most likely *not* bypass custom setters anyway.
+ * So for now, if needed second operand value is not in valid range, we simply fall back
+ * to a mere REPLACE operation.
+ * Time will say whether this is acceptable limitation or not. */
+ switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN:
+ BLI_assert(0 && "Boolean properties support no override diff operation");
+ break;
+ case PROP_INT:
+ {
+ int prop_min, prop_max;
+ RNA_property_int_range(ptr, prop, &prop_min, &prop_max);
+
+ if (len) {
+ if (index == -1) {
+ int fixed_a[16], fixed_b[16];
+ int *array_a, *array_b;
+
+ array_a = (len > 16) ? MEM_mallocN(sizeof(*array_a) * len, __func__) : fixed_a;
+
+ RNA_property_int_get_array(fromptr, fromprop, array_a);
+ switch (opop->operation) {
+ case IDOVERRIDE_ADD:
+ case IDOVERRIDE_SUBTRACT:
+ {
+ const int fac = opop->operation == IDOVERRIDE_ADD ? 1 : -1;
+ const int other_op = opop->operation == IDOVERRIDE_ADD ? IDOVERRIDE_SUBTRACT : IDOVERRIDE_ADD;
+ bool do_set = true;
+ array_b = (len > 16) ? MEM_mallocN(sizeof(*array_b) * len, __func__) : fixed_b;
+ RNA_property_int_get_array(ptr, prop, array_b);
+ for (int i = len; i--;) {
+ array_b[i] = fac * (array_b[i] - array_a[i]);
+ if (array_b[i] < prop_min || array_b[i] > prop_max) {
+ opop->operation = other_op;
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list