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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs