[Bf-blender-cvs] [a721ee8835c] id_override_static: Merge branch 'id_copy_refactor' into id_override_static
Bastien Montagne
noreply at git.blender.org
Mon Jul 17 12:35:24 CEST 2017
Commit: a721ee8835c97705d59f7da9635f67ef75b0dc77
Author: Bastien Montagne
Date: Mon Jul 17 12:35:10 2017 +0200
Branches: id_override_static
https://developer.blender.org/rBa721ee8835c97705d59f7da9635f67ef75b0dc77
Merge branch 'id_copy_refactor' into id_override_static
Conflicts:
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/intern/library_remap.c
source/blender/blenloader/intern/writefile.c
===================================================================
===================================================================
diff --cc source/blender/blenkernel/BKE_library.h
index 154ff7cb985,004442fb013..b5b44228daf
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@@ -87,7 -142,7 +142,8 @@@ void BKE_id_make_local_generic(struct M
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, const struct ID *id, struct ID **newid, bool test);
+ bool BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag, const 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 Main *bmain, struct ID *id);
void BKE_id_copy_ensure_local(struct Main *bmain, const struct ID *old_id, struct ID *new_id);
diff --cc source/blender/blenkernel/intern/library.c
index ef0c8570095,f288e963a2a..4f8c417d403
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@@ -584,80 -637,33 +638,96 @@@ bool BKE_id_copy_ex(Main *bmain, const
case ID_LI:
case ID_SCR:
case ID_WM:
- return false; /* can't be copied from here */
- case ID_VF:
- case ID_SO:
- return false; /* not implemented */
case ID_IP:
- return false; /* deprecated */
+ BLI_assert(0); /* Should have been rejected at start of function! */
+ break;
}
-
- return false;
+
+ /* Update ID refcount, remap pointers to self in new ID. */
+ struct IDCopyLibManagementData data = {.id_src=id, .flag=flag};
+ BKE_library_foreach_ID_link(bmain, *r_newid, id_copy_libmanagement_cb, &data, IDWALK_NOP);
+
+ /* Do not make new copy local in case we are copying outside of main...
+ * XXX TODO: is this behavior OK, or should we need own flag to control that? */
+ if ((flag & LIB_ID_COPY_NO_MAIN) == 0) {
+ BKE_id_copy_ensure_local(bmain, id, *r_newid);
+ }
+
+ return true;
+ }
+
+ /**
+ * Invokes the appropriate copy method for the block and returns the result in
+ * newid, unless test. Returns true if the block can be copied.
+ */
+ bool id_copy(Main *bmain, const ID *id, ID **newid, bool test)
+ {
+ return BKE_id_copy_ex(bmain, id, newid, 0, test);
}
+/** 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)
{
@@@ -1146,36 -1153,49 +1217,58 @@@ static void id_copy_animdata(Main *bmai
}
/* material nodes use this since they are not treated as libdata */
- void BKE_libblock_copy_data(ID *id, const ID *id_from, const bool do_action)
+ void BKE_libblock_copy_data(Main *bmain, ID *id, const ID *id_from, const int flag)
{
if (id_from->properties)
- id->properties = IDP_CopyProperty(id_from->properties);
+ id->properties = IDP_CopyProperty_ex(id_from->properties, flag);
+ /* XXX Again... We need a way to control what we copy in a much more refined way.
+ * Wa cannot always copy this, some internal copying will die on it! */
+ /* For now, upper level code will have to do that itself when required. */
+#if 0
+ if (id_from->override != NULL) {
+ BKE_override_copy(id, id_from);
+ }
+#endif
+
/* the duplicate should get a copy of the animdata */
- id_copy_animdata(id, do_action);
+ id_copy_animdata(bmain, id, (flag & LIB_ID_COPY_ACTIONS) != 0);
}
- /* used everywhere in blenkernel */
- void *BKE_libblock_copy(Main *bmain, const ID *id)
+ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag)
{
- ID *idn;
- size_t idn_len;
-
- idn = BKE_libblock_alloc(bmain, GS(id->name), id->name + 2);
-
- assert(idn != NULL);
+ ID *idn = *r_newid;
+
+ /* Grrrrrrrrr... Not adding 'root' nodetrees to bmain.... grrrrrrrrrrrrrrrrrrrr! */
+ /* This is taken from original ntree copy code, might be weak actually? */
+ const bool use_nodetree_alloc_exception = ((GS(id->name) == ID_NT) && (bmain != NULL) &&
+ (BLI_findindex(&bmain->nodetree, id) < 0));
+
+ BLI_assert((flag & LIB_ID_COPY_NO_MAIN) != 0 || bmain != NULL);
+ BLI_assert((flag & LIB_ID_COPY_NO_MAIN) != 0 || (flag & LIB_ID_COPY_NO_ALLOCATE) == 0);
+ BLI_assert((flag & LIB_ID_COPY_NO_MAIN) == 0 || (flag & LIB_ID_COPY_NO_USER_REFCOUNT) != 0);
+
+ if ((flag & LIB_ID_COPY_NO_ALLOCATE) != 0) {
+ /* r_newid already contains pointer to allocated memory. */
+ /* TODO do we want to memset(0) whole mem before filling it? */
+ BLI_strncpy(idn->name, id->name, sizeof(idn->name));
+ idn->us = 1;
+ /* TODO Do we want/need to copy more from ID struct itself? */
+ }
+ else if ((flag & LIB_ID_COPY_NO_MAIN) != 0 || use_nodetree_alloc_exception) {
+ /* Allocate r_newid but do not register it in Main database. */
+ idn = BKE_libblock_alloc_notest(GS(id->name));
+ BLI_strncpy(idn->name, id->name, sizeof(idn->name));
+ idn->us = 1;
+ }
+ else {
+ idn = BKE_libblock_alloc(bmain, GS(id->name), id->name + 2);
+ }
+ BLI_assert(idn != NULL);
- idn_len = MEM_allocN_len(idn);
- if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */
+ const size_t id_len = BKE_libblock_get_alloc_info(GS(idn->name), NULL);
+ const size_t id_offset = sizeof(ID);
+ if ((int)id_len - (int)id_offset > 0) { /* signed to allow neg result */ /* XXX ????? */
const char *cp = (const char *)id;
char *cpn = (char *)idn;
diff --cc source/blender/blenkernel/intern/library_remap.c
index 81fe5ca313b,e764df437e1..f78550c02d7
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@@ -732,12 -731,10 +732,14 @@@ void BKE_libblock_free_data(ID *id, con
MEM_freeN(id->properties);
}
+ if (id->override) {
+ BKE_override_free(&id->override);
+ }
++
+ /* XXX TODO remove animdata handling from each type's freeing func, and do it here, like for copy! */
}
- void BKE_libblock_free_datablock(ID *id)
+ void BKE_libblock_free_datablock(ID *id, const int UNUSED(flag))
{
const short type = GS(id->name);
switch (type) {
diff --cc source/blender/blenloader/intern/writefile.c
index 8b078653b43,fbaaa91bc4d..72036d068f5
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@@ -3853,148 -3831,131 +3853,151 @@@ static bool write_file_handle
* avoid thumbnail detecting changes because of this. */
mywrite_flush(wd);
- ListBase *lbarray[MAX_LIBARRAY];
- int a = set_listbasepointers(mainvar, lbarray);
- while (a--) {
- ID *id = lbarray[a]->first;
+ OverrideStorage *override_storage = !wd->current ? BKE_override_operations_store_initialize() : NULL;
- if (id && GS(id->name) == ID_LI) {
- continue; /* Libraries are handled separately below. */
- }
+ /* This outer loop allows to save first datablocks from real mainvar, then the temp ones from override process,
+ * if needed, without duplicating whole code. */
+ Main *main = mainvar;
+ do {
+ ListBase *lbarray[MAX_LIBARRAY];
+ int a = set_listbasepointers(main, lbarray);
+ while (a--) {
+ ID *id = lbarray[a]->first;
- for (; id; id = id->next) {
- /* We should never attempt to write non-regular IDs (i.e. all kind of temp/runtime ones). */
- BLI_assert((id->tag & (LIB_TAG_FREE_NO_MAIN | LIB_TAG_FREE_NO_USER_REFCOUNT | LIB_TAG_FREE_NOT_ALLOCATED)) == 0);
+ if (id && GS(id->name) == ID_LI) {
+ continue; /* Libraries are handled separately below. */
+ }
- switch ((ID_Type)GS(id->name)) {
- case ID_WM:
- write_windowmanager(wd, (wmWindowManager *)id);
- break;
- case ID_SCR:
- write_screen(wd, (bScreen *)id);
- break;
- case ID_MC:
- write_movieclip(wd, (MovieClip *)id);
- break;
- case ID_MSK:
- write_mask(wd, (Mask *)id);
- break;
- case ID_SCE:
- write_scene(wd, (Scene *)id);
- break;
- case ID_CU:
- write_curve(wd, (Curve *)id);
- break;
- case ID_MB:
- write_mball(wd, (MetaBall *)id);
- break;
- case ID_IM:
- write_image(wd, (Image *)id);
- break;
- case ID_CA:
- write_camera(wd, (Camera *)id);
- break;
- case ID_LA:
- write_lamp(wd, (Lamp *)id);
- break;
- case ID_LT:
- write_lattice(wd, (Lattice *)id);
- break;
- case
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list