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

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to