[Bf-blender-cvs] [b827ca7] override_static: Final bits to get first (very raw, limited and experimental) override working.
Bastien Montagne
noreply at git.blender.org
Wed Dec 14 16:10:33 CET 2016
Commit: b827ca78c781a3962e049a439b838eab4020576a
Author: Bastien Montagne
Date: Mon Dec 12 13:59:49 2016 +0100
Branches: override_static
https://developer.blender.org/rBb827ca78c781a3962e049a439b838eab4020576a
Final bits to get first (very raw, limited and experimental) override working.
Mostly code using override data to selectively update a copy of linked one
with local data.
As said, still totally hackish and experimental, but it works - you can
create overrides of linked Objects, and override their position, yeha! :P
===================================================================
M source/blender/blenkernel/BKE_library.h
M source/blender/blenkernel/BKE_library_override.h
M source/blender/blenkernel/intern/library.c
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.h b/source/blender/blenkernel/BKE_library.h
index 2d9c35f..26f9b83 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -85,6 +85,7 @@ void BKE_id_make_local_generic(struct Main *bmain, struct ID *id, const bool id_
bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const bool force_local);
bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
bool id_copy(struct Main *bmain, struct ID *id, struct ID **newid, bool test);
+void BKE_id_swap(struct ID *id_a, struct ID *id_b);
void id_sort_by_name(struct ListBase *lb, struct ID *id);
void BKE_id_expand_local(struct ID *id);
void BKE_id_copy_ensure_local(struct Main *bmain, struct ID *old_id, struct ID *new_id);
diff --git a/source/blender/blenkernel/BKE_library_override.h b/source/blender/blenkernel/BKE_library_override.h
index c26155a..1fb4b92 100644
--- a/source/blender/blenkernel/BKE_library_override.h
+++ b/source/blender/blenkernel/BKE_library_override.h
@@ -44,7 +44,10 @@ void BKE_override_free(struct IDOverride **override);
bool BKE_override_status_check_local(struct ID *local);
bool BKE_override_status_check_reference(struct ID *local);
-bool BKE_override_synchronize_update(struct ID *local);
+bool BKE_override_operations_update(struct ID *local);
+
+void BKE_override_update(struct ID *local);
+void BKE_main_override_update(struct Main *bmain);
#endif /* __BKE_LIBRARY_OVERRIDE_H__ */
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 65f37d0..b0d60ff 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -582,6 +582,69 @@ bool id_copy(Main *bmain, ID *id, ID **newid, bool test)
return false;
}
+/** Does a mere memory swap over the whole IDs data (including type-specific memory).
+ * \note Most internal ID data itself is not swapped (only IDProperties are). */
+void BKE_id_swap(ID *id_a, ID *id_b)
+{
+ BLI_assert(GS(id_a->name) == GS(id_b->name));
+
+ const ID id_a_back = *id_a;
+ const ID id_b_back = *id_b;
+
+#define CASE_SWAP(_gs, _type) \
+ case _gs: \
+ SWAP(_type, *(_type *)id_a, *(_type *)id_b); \
+ break
+
+ switch ((ID_Type)GS(id_a->name)) {
+ CASE_SWAP(ID_SCE, Scene);
+ CASE_SWAP(ID_LI, Library);
+ CASE_SWAP(ID_OB, Object);
+ CASE_SWAP(ID_ME, Mesh);
+ CASE_SWAP(ID_CU, Curve);
+ CASE_SWAP(ID_MB, MetaBall);
+ CASE_SWAP(ID_MA, Material);
+ CASE_SWAP(ID_TE, Tex);
+ CASE_SWAP(ID_IM, Image);
+ CASE_SWAP(ID_LT, Lattice);
+ CASE_SWAP(ID_LA, Lamp);
+ CASE_SWAP(ID_CA, Camera);
+ CASE_SWAP(ID_KE, Key);
+ CASE_SWAP(ID_WO, World);
+ CASE_SWAP(ID_SCR, bScreen);
+ CASE_SWAP(ID_VF, VFont);
+ CASE_SWAP(ID_TXT, Text);
+ CASE_SWAP(ID_SPK, Speaker);
+ CASE_SWAP(ID_SO, bSound);
+ CASE_SWAP(ID_GR, Group);
+ CASE_SWAP(ID_AR, bArmature);
+ CASE_SWAP(ID_AC, bAction);
+ CASE_SWAP(ID_NT, bNodeTree);
+ CASE_SWAP(ID_BR, Brush);
+ CASE_SWAP(ID_PA, ParticleSettings);
+ CASE_SWAP(ID_WM, wmWindowManager);
+ CASE_SWAP(ID_GD, bGPdata);
+ CASE_SWAP(ID_MC, MovieClip);
+ CASE_SWAP(ID_MSK, Mask);
+ CASE_SWAP(ID_LS, FreestyleLineStyle);
+ CASE_SWAP(ID_PAL, Palette);
+ CASE_SWAP(ID_PC, PaintCurve);
+ CASE_SWAP(ID_CF, CacheFile);
+ case ID_IP:
+ break; /* Deprecated. */
+ }
+
+#undef CASE_SWAP
+
+ /* Restore original ID's internal data. */
+ *id_a = id_a_back;
+ *id_b = id_b_back;
+
+ /* Exception: IDProperties. */
+ id_a->properties = id_b_back.properties;
+ id_b->properties = id_a_back.properties;
+}
+
/** Does *not* set ID->newid pointer. */
bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
{
diff --git a/source/blender/blenkernel/intern/library_override.c b/source/blender/blenkernel/intern/library_override.c
index 07938e6..14528d3 100644
--- a/source/blender/blenkernel/intern/library_override.c
+++ b/source/blender/blenkernel/intern/library_override.c
@@ -33,8 +33,10 @@
#include "DNA_ID.h"
+#include "BKE_global.h" /* XXX Yuck! temp hack! */
#include "BKE_library.h"
#include "BKE_library_override.h"
+#include "BKE_main.h"
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
@@ -163,10 +165,73 @@ bool BKE_override_status_check_reference(ID *local)
/** Compares local and reference data-blocks and create new override operations as needed,
* or reset to reference values if overriding is not allowed.
* \return true is new overriding op was created, or some local data was reset. */
-bool BKE_override_synchronize_update(ID *local)
+bool BKE_override_operations_update(ID *local)
{
BLI_assert(local->override != NULL);
return false;
}
+#include "DNA_object_types.h"
+/** Update given override from its reference (not touching to overriden properties). */
+void BKE_override_update(ID *local)
+{
+ if (local->override == NULL) {
+ return;
+ }
+
+ /* Recursively do 'ancestors' overrides first, if any. */
+ if (local->override->reference->override) {
+ BKE_override_update(local->override->reference);
+ }
+
+ /* We want to avoid having to remap here, however creating up-to-date override is much simpler if based
+ * on reference than on current override.
+ * So we work on temp copy of reference. */
+
+ /* XXX We need a way to get off-Main copies of IDs (similar to localized mats/texts/ etc.)!
+ * However, this is whole bunch of code work in itself, so for now plain stupid ID copy will do,
+ * as innefficient as it is. :/
+ * Actually, maybe not! Since we are swapping with original ID's local content, we want to keep
+ * usercount in correct state when freeing tmp_id (and that usercounts of IDs used by 'new' local data
+ * also remain correct). */
+
+ ID *tmp_id;
+ id_copy(G.main, local->override->reference, &tmp_id, false); /* XXX ...and worse of all, this won't work with scene! */
+
+ if (tmp_id == NULL) {
+ return;
+ }
+
+ PointerRNA rnaptr_local, rnaptr_data;
+ RNA_id_pointer_create(local, &rnaptr_local);
+ RNA_id_pointer_create(tmp_id, &rnaptr_data);
+ RNA_struct_override_update(&rnaptr_local, &rnaptr_data, local->override);
+ /* 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. */
+ BKE_id_swap(local, tmp_id);
+
+ /* Again, horribly innefficient in our case, we need something off-Main and off-usercounting
+ * (aka moar generic nolib copy/free stuff)! */
+ BKE_libblock_free_ex(G.main, tmp_id, true, false);
+}
+
+/** Update all overrides from given \a bmain. */
+void BKE_main_override_update(Main *bmain)
+{
+ ListBase *lbarray[MAX_LIBARRAY];
+ int base_count, i;
+
+ base_count = set_listbasepointers(bmain, lbarray);
+
+ for (i = 0; i < base_count; i++) {
+ ListBase *lb = lbarray[i];
+ ID *id;
+
+ for (id = lb->first; id; id = id->next) {
+ if (id->override != NULL && id->lib == NULL) {
+ BKE_override_update(id);
+ }
+ }
+ }
+}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index b57b720..651d2c8 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -127,6 +127,7 @@
#include "BKE_group.h"
#include "BKE_library.h" // for which_libbase
#include "BKE_library_idmap.h"
+#include "BKE_library_override.h"
#include "BKE_library_query.h"
#include "BKE_idcode.h"
#include "BKE_material.h"
@@ -8621,6 +8622,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
blo_join_main(&mainlist);
lib_link_all(fd, bfd->main);
+
+ /* Now that all our data-blocks are loaded, we can re-generate overrides from their references. */
+ BKE_main_override_update(bfd->main);
+
//do_versions_after_linking(fd, NULL, bfd->main); // XXX: not here (or even in this function at all)! this causes crashes on many files - Aligorith (July 04, 2010)
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 2913477..0d64a8d 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1217,6 +1217,8 @@ 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_struct_override_update(struct PointerRNA *src, struct PointerRNA *dst, struct IDOverride *override);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index f0c3bca..b37dbb5 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -7127,6 +7127,30 @@ bool RNA_struct_override_matches(
return equals;
}
+void RNA_struct_override_update(PointerRNA *src, PointerRNA *dst, IDOverride *override)
+{
+ for (IDOverrideProperty *op = override->properties.first; op; op = op->next) {
+ /* Simplified for now! */
+ PointerRNA src_data, dst_data;
+ PropertyRNA *src_prop, *dst_prop;
+
+ if (RNA_path_resolve_property(src, op->rna_path, &src_data, &src_prop) &&
+ RNA_path_resolve_property(dst, op->rna_path, &dst_data, &dst_prop))
+ {
+ BLI_assert(src_prop == dst_prop);
+
+ for (IDOverridePropertyOperation *opop = op->operations.first; opop; opop = opop->next) {
+ switch (opop->operation) {
+ case IDOVERRIDE_REPLACE:
+ RNA_property_copy(&dst_data, &src_data, src_prop, -1);
+ break;
+ /* TODO other cases! */
+ }
+ }
+ }
+ }
+}
+
bool RNA_path_resolved_create(
PointerRNA *ptr, struct PropertyRNA *prop,
More information about the Bf-blender-cvs
mailing list