[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