[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