[Bf-blender-cvs] [7edeccf81d5] id_copy_refactor: Fleshing a bit new copy logic (using Object datablock as Guinea pig).

Bastien Montagne noreply at git.blender.org
Fri Jun 16 10:51:22 CEST 2017


Commit: 7edeccf81d5a1add62d42b50d825b9e79f810f70
Author: Bastien Montagne
Date:   Wed Jun 14 21:05:07 2017 +0200
Branches: id_copy_refactor
https://developer.blender.org/rB7edeccf81d5a1add62d42b50d825b9e79f810f70

Fleshing a bit new copy logic (using Object datablock as Guinea pig).

===================================================================

M	source/blender/blenkernel/BKE_library.h
M	source/blender/blenkernel/BKE_object.h
M	source/blender/blenkernel/intern/library.c
M	source/blender/blenkernel/intern/mesh.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/makesdna/DNA_ID.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 99aefad4388..3765ae97ebc 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -54,6 +54,7 @@ size_t BKE_libblock_get_alloc_info(short type, const char **name);
 void *BKE_libblock_alloc_notest(short type);
 void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 void  BKE_libblock_init_empty(struct ID *id);
+void BKE_libblock_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag);
 void *BKE_libblock_copy(struct Main *bmain, const struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 void *BKE_libblock_copy_nolib(const struct ID *id, const bool do_action) ATTR_NONNULL();
 void  BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
@@ -87,7 +88,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, const struct ID *id, struct ID **newid, bool test);
-bool BKE_id_copy(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag, const 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 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 --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 0a5035f9a9b..d6ee04f6424 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -105,7 +105,7 @@ bool BKE_object_lod_is_usable(struct Object *ob, struct Scene *scene);
 struct Object *BKE_object_lod_meshob_get(struct Object *ob, struct Scene *scene);
 struct Object *BKE_object_lod_matob_get(struct Object *ob, struct Scene *scene);
 
-struct Object *BKE_object_copy_ex(struct Main *bmain, const struct Object *ob, bool copy_caches);
+void BKE_object_copy_ex(struct Main *bmain, const struct Object *ob, struct Object *obn, const int flag);
 struct Object *BKE_object_copy(struct Main *bmain, const struct Object *ob);
 void BKE_object_make_local(struct Main *bmain, struct Object *ob, const bool lib_local);
 void BKE_object_make_local_ex(struct Main *bmain, struct Object *ob, const bool lib_local, const bool clear_proxy);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 86a6886fb88..db459905eba 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -485,7 +485,12 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
 }
 
 /**
- * Genric entry point for copying a datablock (new API).
+ * Generic entry point for copying a datablock (new API).
+ *
+ * \note Copy is only affecting given data-block (no ID used by copied one will be affected, besides usercount).
+ *       There is only one exception, if LIB_ID_COPY_ACTIONS is defined, actions used by animdata will be duplicated.
+ *
+ * \note Usercount of new copy is always set to 1.
  *
  * \param bmain Main database, may be NULL only if LIB_ID_COPY_NO_MAIN is specified.
  * \param id Source datablock.
@@ -494,97 +499,98 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
  * \param test If set, do not do any copy, just test whether copy is supported.
  * \return False when copying that ID type is not supported, true otherwise.
  */
-bool BKE_id_copy(Main *bmain, const ID *id, ID **r_newid, const int flag, const bool test)
+/* XXX TODO remove test thing, *all* IDs should be copyable that way! */
+bool BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag, const bool test)
 {
-	if (!test && (flag & LIB_ID_COPY_NO_ALLOCATE) == 0) {
-		*r_newid = NULL;
+	if (!test) {
+		/* Check to be removed of course, just here until all BKE_xxx_copy_ex functions are done. */
+		if (ELEM(GS(id->name), ID_OB)) {
+			BKE_libblock_copy_ex(bmain, id, r_newid, flag);
+		}
 	}
 
-	/* conventions:
-	 * - make shallow copy, only this ID block
-	 * - id.us of the new ID is set to 1 */
 	switch ((ID_Type)GS(id->name)) {
 		case ID_OB:
-			if (!test) *r_newid = (ID *)BKE_object_copy(bmain, (Object *)id);
-			return true;
+			if (!test) BKE_object_copy_ex(bmain, (Object *)id, (Object *)*r_newid, flag);
+			break;
 		case ID_ME:
 			if (!test) *r_newid = (ID *)BKE_mesh_copy(bmain, (Mesh *)id);
-			return true;
+			break;
 		case ID_CU:
 			if (!test) *r_newid = (ID *)BKE_curve_copy(bmain, (Curve *)id);
-			return true;
+			break;
 		case ID_MB:
 			if (!test) *r_newid = (ID *)BKE_mball_copy(bmain, (MetaBall *)id);
-			return true;
+			break;
 		case ID_MA:
 			if (!test) *r_newid = (ID *)BKE_material_copy(bmain, (Material *)id);
-			return true;
+			break;
 		case ID_TE:
 			if (!test) *r_newid = (ID *)BKE_texture_copy(bmain, (Tex *)id);
-			return true;
+			break;
 		case ID_IM:
 			if (!test) *r_newid = (ID *)BKE_image_copy(bmain, (Image *)id);
-			return true;
+			break;
 		case ID_LT:
 			if (!test) *r_newid = (ID *)BKE_lattice_copy(bmain, (Lattice *)id);
-			return true;
+			break;
 		case ID_LA:
 			if (!test) *r_newid = (ID *)BKE_lamp_copy(bmain, (Lamp *)id);
-			return true;
+			break;
 		case ID_SPK:
 			if (!test) *r_newid = (ID *)BKE_speaker_copy(bmain, (Speaker *)id);
-			return true;
+			break;
 		case ID_CA:
 			if (!test) *r_newid = (ID *)BKE_camera_copy(bmain, (Camera *)id);
-			return true;
+			break;
 		case ID_KE:
 			if (!test) *r_newid = (ID *)BKE_key_copy(bmain, (Key *)id);
-			return true;
+			break;
 		case ID_WO:
 			if (!test) *r_newid = (ID *)BKE_world_copy(bmain, (World *)id);
-			return true;
+			break;
 		case ID_TXT:
 			if (!test) *r_newid = (ID *)BKE_text_copy(bmain, (Text *)id);
-			return true;
+			break;
 		case ID_GR:
 			if (!test) *r_newid = (ID *)BKE_group_copy(bmain, (Group *)id);
-			return true;
+			break;
 		case ID_AR:
 			if (!test) *r_newid = (ID *)BKE_armature_copy(bmain, (bArmature *)id);
-			return true;
+			break;
 		case ID_AC:
 			if (!test) *r_newid = (ID *)BKE_action_copy(bmain, (bAction *)id);
-			return true;
+			break;
 		case ID_NT:
 			if (!test) *r_newid = (ID *)ntreeCopyTree(bmain, (bNodeTree *)id);
-			return true;
+			break;
 		case ID_BR:
 			if (!test) *r_newid = (ID *)BKE_brush_copy(bmain, (Brush *)id);
-			return true;
+			break;
 		case ID_PA:
 			if (!test) *r_newid = (ID *)BKE_particlesettings_copy(bmain, (ParticleSettings *)id);
-			return true;
+			break;
 		case ID_GD:
 			if (!test) *r_newid = (ID *)BKE_gpencil_data_duplicate(bmain, (bGPdata *)id, false);
-			return true;
+			break;
 		case ID_MC:
 			if (!test) *r_newid = (ID *)BKE_movieclip_copy(bmain, (MovieClip *)id);
-			return true;
+			break;
 		case ID_MSK:
 			if (!test) *r_newid = (ID *)BKE_mask_copy(bmain, (Mask *)id);
-			return true;
+			break;
 		case ID_LS:
 			if (!test) *r_newid = (ID *)BKE_linestyle_copy(bmain, (FreestyleLineStyle *)id);
-			return true;
+			break;
 		case ID_PAL:
 			if (!test) *r_newid = (ID *)BKE_palette_copy(bmain, (Palette *)id);
-			return true;
+			break;
 		case ID_PC:
 			if (!test) *r_newid = (ID *)BKE_paint_curve_copy(bmain, (PaintCurve *)id);
-			return true;
+			break;
 		case ID_CF:
 			if (!test) *r_newid = (ID *)BKE_cachefile_copy(bmain, (CacheFile *)id);
-			return true;
+			break;
 		case ID_SCE:
 		case ID_LI:
 		case ID_SCR:
@@ -597,7 +603,16 @@ bool BKE_id_copy(Main *bmain, const ID *id, ID **r_newid, const int flag, const
 			return false;  /* deprecated */
 	}
 
-	return false;
+	if (!test) {
+		/* Check to be removed of course, just here until all BKE_xxx_copy_ex functions are done. */
+		if (ELEM(GS(id->name), ID_OB)) {
+			/* TODO: add id usage count update here, this should be generic as well.
+			 *       But currently, too much sub-data copying also handle idcount themselves... */
+			BKE_id_copy_ensure_local(bmain, id, *r_newid);
+		}
+	}
+
+	return true;
 }
 
 /**
@@ -606,7 +621,7 @@ bool BKE_id_copy(Main *bmain, const ID *id, ID **r_newid, const int flag, const
  */
 bool id_copy(Main *bmain, const ID *id, ID **newid, bool test)
 {
-	return BKE_id_copy(bmain, id, newid, 0, test);
+	return BKE_id_copy_ex(bmain, id, newid, 0, test);
 }
 
 /** Does *not* set ID->newid pointer. */
@@ -963,6 +978,7 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name)
 		/* alphabetic insertion: is in new_id */
 		BKE_main_unlock(bmain);
 	}
+	/* TODO to be removed from here! */
 	DAG_id_type_tag(bmain, type);
 	return id;
 }
@@ -1106,50 +1122,67 @@ void BKE_libblock_copy_data(ID *id, const ID *id_from, const bool do_action)
 	id_copy_animdata(id, do_action);
 }
 
-/* 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;
+	ID *idn = *r_newid;
 
-	idn = BKE_libblock_alloc(bmain, GS(id->name), id->name + 2);
+	BLI_assert((flag & LIB_ID_COPY_NO_MAIN) != 0 || bmain != NULL);
+	BLI_assert((flag & LIB_ID_COPY_NO_ALLOCATE) == 0 || (flag & LIB_ID_COPY_NO_MAIN) != 0);
 
-	assert(idn != NULL);
+	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) {
+		/* 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)

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list