[Bf-blender-cvs] [c2cece8b29] id_override_static: Preliminary step to support static override of armatures.
Bastien Montagne
noreply at git.blender.org
Tue Feb 7 20:18:21 CET 2017
Commit: c2cece8b29f00761af525e2fc0db3c58b3327858
Author: Bastien Montagne
Date: Tue Feb 7 20:14:57 2017 +0100
Branches: id_override_static
https://developer.blender.org/rBc2cece8b29f00761af525e2fc0db3c58b3327858
Preliminary step to support static override of armatures.
I.e. support override of loc/rot/scale of posechannels.
Also implied to add some minimal support of collections in 'diff
generating' RNA code.
Still much to be done of course.
===================================================================
M source/blender/blenkernel/intern/library_override.c
M source/blender/makesrna/RNA_access.h
M source/blender/makesrna/intern/rna_access.c
M source/blender/makesrna/intern/rna_object.c
M source/blender/makesrna/intern/rna_pose.c
===================================================================
diff --git a/source/blender/blenkernel/intern/library_override.c b/source/blender/blenkernel/intern/library_override.c
index aa3161e6c9..abe2573fb9 100644
--- a/source/blender/blenkernel/intern/library_override.c
+++ b/source/blender/blenkernel/intern/library_override.c
@@ -337,7 +337,7 @@ bool BKE_override_operations_create(ID *local)
RNA_id_pointer_create(local, &rnaptr_local);
RNA_id_pointer_create(local->override->reference, &rnaptr_reference);
- if (RNA_struct_auto_override(&rnaptr_local, &rnaptr_reference, local->override)) {
+ if (RNA_struct_auto_override(&rnaptr_local, &rnaptr_reference, local->override, NULL)) {
printf("We did generate static override rules for %s\n", local->name);
}
else {
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 58e6e48d50..73360b5063 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1230,7 +1230,8 @@ void RNA_property_override_apply(
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);
+bool RNA_struct_auto_override(
+ struct PointerRNA *local, struct PointerRNA *reference, struct IDOverride *override, const char *root_path);
#ifdef __cplusplus
}
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index f11a55e867..f607182419 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -6829,6 +6829,52 @@ bool RNA_struct_equals(PointerRNA *a, PointerRNA *b, eRNAEqualsMode mode)
/* Low-level functions, also used by non-override RNA API like copy or equality check. */
+/* Used for both Pointer and Collection properties. */
+static bool rna_property_override_equals_propptr(
+ PointerRNA *propptr_a, PointerRNA *propptr_b, eRNAEqualsMode mode,
+ IDOverride *override, const char *rna_path, bool *r_override_changed,
+ const bool ignore_non_overridable, const bool ignore_overridden)
+{
+ if (RNA_struct_is_ID(propptr_a->type)) {
+ /* In case this is an ID, do not compare structs!
+ * This is a quite safe path to infinite loop.
+ * Instead, just compare ID pointers themselves (we assume sub-ID structs cannot loop). */
+ const bool equals = propptr_a->id.data != propptr_b->id.data;
+
+ if (!equals && rna_path) {
+ bool created = false;
+ IDOverrideProperty *op = BKE_override_property_get(override, rna_path, &created);
+
+ if (op != NULL && created) { /* If not yet overridden... */
+ BKE_override_property_operation_get(op, IDOVERRIDE_REPLACE, NULL, NULL, -1, -1, NULL);
+ if (r_override_changed) {
+ *r_override_changed = *r_override_changed || created;
+ }
+ }
+ }
+
+ return equals;
+ }
+ else if (override) {
+ if (rna_path) {
+ const bool changed = RNA_struct_auto_override(propptr_a, propptr_b, override, rna_path);
+ if (r_override_changed) {
+ *r_override_changed = *r_override_changed || changed;
+ }
+ /* XXX Simplification here, if no override was added we assume they are equal,
+ * this may not be good behavior, time will say. */
+ return !changed;
+ }
+ else {
+ return RNA_struct_override_matches(
+ propptr_a, propptr_b, override, ignore_non_overridable, ignore_overridden);
+ }
+ }
+ else {
+ return RNA_struct_equals(propptr_a, propptr_b, mode);
+ }
+}
+
static bool rna_property_override_equals(
PointerRNA *a, PointerRNA *b, PropertyRNA *prop, eRNAEqualsMode mode,
IDOverride *override, const char *rna_path, bool *r_override_changed,
@@ -7078,50 +7124,80 @@ static bool rna_property_override_equals(
else {
PointerRNA propptr_a = RNA_property_pointer_get(a, prop);
PointerRNA propptr_b = RNA_property_pointer_get(b, prop);
- if (RNA_struct_is_ID(propptr_a.type)) {
- /* In case this is an ID, do not compare structs!
- * This is a quite safe path to infinite loop.
- * Instead, just compare ID pointers themselves (we assume sub-ID structs cannot loop). */
- const bool equals = propptr_a.id.data != propptr_b.id.data;
-
- if (!equals && rna_path) {
- bool created = false;
- IDOverrideProperty *op = BKE_override_property_get(override, rna_path, &created);
-
- if (op != NULL && created) { /* If not yet overridden... */
- BKE_override_property_operation_get(op, IDOVERRIDE_REPLACE, NULL, NULL, -1, -1, NULL);
- if (r_override_changed) {
- *r_override_changed = created;
- }
- }
- }
+ rna_property_override_equals_propptr(
+ &propptr_a, &propptr_b, mode,
+ override, rna_path, r_override_changed, ignore_non_overridable, ignore_overridden);
+ }
+ break;
+ }
+
+ case PROP_COLLECTION:
+ {
+ bool equals = true;
+ int idx = 0;
+
+ CollectionPropertyIterator iter_a, iter_b;
+ RNA_property_collection_begin(a, prop, &iter_a);
+ RNA_property_collection_begin(b, prop, &iter_b);
- return equals;
+ for (; iter_a.valid && iter_b.valid;
+ RNA_property_collection_next(&iter_a), RNA_property_collection_next(&iter_b), idx++)
+ {
+ char *extended_rna_path = NULL;
+
+ if (iter_a.ptr.type != iter_b.ptr.type) {
+ /* nothing we can do (for until we support adding/removing from collections), skip it. */
+ equals = false;
+ continue;
}
- else if (override) {
- if (rna_path) {
- const bool changed = RNA_struct_auto_override(&propptr_a, &propptr_b, override);
- if (r_override_changed) {
- *r_override_changed = changed;
- }
- /* XXX Simplification here, if no override was added we assume they are equal,
- * this may not be good behavior, time will say. */
- return !changed;
+
+ PropertyRNA *propname = RNA_struct_name_property(iter_a.ptr.type);
+ char propname_buff_a[256], propname_buff_b[256];
+ char *propname_a = NULL, *propname_b = NULL;
+
+ if (propname != NULL) {
+ propname_a = RNA_property_string_get_alloc(&iter_a.ptr, propname, propname_buff_a, sizeof(propname_buff_a), NULL);
+ propname_b = RNA_property_string_get_alloc(&iter_b.ptr, propname, propname_buff_b, sizeof(propname_buff_b), NULL);
+ if (!STREQ(propname_a, propname_b)) {
+ /* Same as above, not same structs. */
+ equals = false;
}
- else {
- return RNA_struct_override_matches(
- &propptr_a, &propptr_b, override, ignore_non_overridable, ignore_overridden);
+ else if (rna_path) {
+ extended_rna_path = BLI_sprintfN("%s[\"%s\"]", rna_path, propname_a); /* XXX TODO escape propname! */
}
}
- else {
- return RNA_struct_equals(&propptr_a, &propptr_b, mode);
+ else { /* Based on index... */
+ if (rna_path) {
+ extended_rna_path = BLI_sprintfN("%s[%d]", rna_path, idx);
+ }
+ }
+
+ {
+ bool eq = rna_property_override_equals_propptr(
+ &iter_a.ptr, &iter_b.ptr, mode,
+ override, extended_rna_path, r_override_changed, ignore_non_overridable, ignore_overridden);
+ equals = equals && eq;
+ }
+
+ if (propname_a != propname_buff_a) {
+ MEM_freeN(propname_a);
+ }
+ if (propname_b != propname_buff_b) {
+ MEM_freeN(propname_b);
+ }
+ MEM_SAFE_FREE(extended_rna_path);
+
+ if (!rna_path && !equals) {
+ break; /* Early out in case we do not want to loop over whole collection. */
}
}
- break;
- }
- case PROP_COLLECTION:
- /* TODO! for override... */
+ equals = equals && !(iter_a.valid || iter_b.valid); /* Not same number of items in both collections... */
+ RNA_property_collection_end(&iter_a);
+ RNA_property_collection_end(&iter_b);
+
+ return equals;
+ }
default:
break;
@@ -7857,7 +7933,7 @@ void RNA_struct_override_apply(PointerRNA *dst, PointerRNA *src, IDOverride *ove
}
/** Automatically define override rules by comparing \a local and \a reference RNA structs. */
-bool RNA_struct_auto_override(PointerRNA *local, PointerRNA *reference, IDOverride *override)
+bool RNA_struct_auto_override(PointerRNA *local, PointerRNA *reference, IDOverride *override, const char *root_path)
{
CollectionPropertyIterator iter;
PropertyRNA *iterprop;
@@ -7880,7 +7956,14 @@ bool RNA_struct_auto_override(PointerRNA *local, PointerRNA *reference, IDOverri
}
/* XXX TODO this will have to be refined to handle collections insertions, and array items */
- char *rna_path = RNA_path_from_ID_to_property(local, prop);
+ char *rna_path;
+ if (root_path) {
+ /* Inlined building, much much more efficient. */
+ rna_path = BLI_sprintfN("%s.%s", root_path, RNA_property_identifier(prop));
+ }
+ else {
+ rna_path = RNA_path_from_ID_to_property(local, prop);
+ }
if (rna_path == NULL) {
continue;
}
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 28714c8f87..27310f4424 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -2801,6 +2801,7 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "pose", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "pose");
RNA_def_property_struct_type(prop, "Pose");
+ RNA_def_property_flag(prop, PROP_OVERRIDABLE);
RNA_def_property_ui_text(prop, "Pose", "Current pose for armatures");
/* shape keys */
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 28ce63a61b..db376320c8 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -833,6 +833,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
/* Transformation settings */
prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "loc");
+ RNA_def_property_flag(prop, PROP_OVERRIDABLE);
RNA_def_property_editable_array_func(prop, "rna_PoseChannel_location_editable");
RNA_def_property_ui_text(prop, "Location", "");
RN
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list