diff --git a/source/blender/blenkernel/BKE_anim_data.hh b/source/blender/blenkernel/BKE_anim_data.hh index 667ef2c9ead..f5586b61efd 100644 --- a/source/blender/blenkernel/BKE_anim_data.hh +++ b/source/blender/blenkernel/BKE_anim_data.hh @@ -8,6 +8,8 @@ * \ingroup bke */ +#include + #include "BLI_sys_types.h" /* for bool */ struct AnimData; @@ -15,6 +17,7 @@ struct BlendDataReader; struct BlendLibReader; struct BlendWriter; struct ID; +struct Library; struct LibraryForeachIDData; struct Main; struct ReportList; @@ -84,12 +87,29 @@ void BKE_animdata_foreach_id(AnimData *adt, LibraryForeachIDData *data); /** * Make a copy of the given AnimData - to be used when copying data-blocks. - * \param flag: Control ID pointers management, - * see LIB_ID_CREATE_.../LIB_ID_COPY_... flags in BKE_lib_id.hh + * + * \note: Regarding handling of IDs managed by the #AnimData struct, this function follows the + * behaviors of the generic #BKE_id_copy_ex, please see its documetation for more details. + * + * \param flag: Control ID pointers management, see LIB_ID_CREATE_.../LIB_ID_COPY_... flags in + * #BKE_lib_id.hh + * * \return The copied animdata. */ AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, int flag); +/** + * Same as #BKE_animdata_copy, but allows to duplicate Action IDs into a library. + * + * \param owner_library the Library to 'assign' the newly created ID to. Use `nullptr` to make ID + * not use any library (i.e. become a local ID). Use `std::nullopt` for default behavior (i.e. + * behavior of the #BKE_animdata_copy function). + */ +AnimData *BKE_animdata_copy_in_lib(Main *bmain, + std::optional owner_library, + AnimData *adt, + int flag); + /** * \param flag: Control ID pointers management, * see LIB_ID_CREATE_.../LIB_ID_COPY_... flags in BKE_lib_id.hh diff --git a/source/blender/blenkernel/BKE_idtype.hh b/source/blender/blenkernel/BKE_idtype.hh index 25d2a5ef22d..f10d0365a50 100644 --- a/source/blender/blenkernel/BKE_idtype.hh +++ b/source/blender/blenkernel/BKE_idtype.hh @@ -10,6 +10,8 @@ * ID type structure, helping to factorize common operations and data for all data-block types. */ +#include + #include "BLI_sys_types.h" struct AssetTypeInfo; @@ -18,6 +20,7 @@ struct BlendDataReader; struct BlendLibReader; struct BlendWriter; struct ID; +struct Library; struct LibraryForeachIDData; struct Main; @@ -63,7 +66,8 @@ bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v); using IDTypeInitDataFunction = void (*)(ID *id); /** \param flag: Copying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more). */ -using IDTypeCopyDataFunction = void (*)(Main *bmain, ID *id_dst, const ID *id_src, int flag); +using IDTypeCopyDataFunction = void (*)( + Main *bmain, std::optional owner_library, ID *id_dst, const ID *id_src, int flag); using IDTypeFreeDataFunction = void (*)(ID *id); diff --git a/source/blender/blenkernel/BKE_lib_id.hh b/source/blender/blenkernel/BKE_lib_id.hh index 78e1172f15c..52b3decedd4 100644 --- a/source/blender/blenkernel/BKE_lib_id.hh +++ b/source/blender/blenkernel/BKE_lib_id.hh @@ -30,6 +30,8 @@ * specific cases requiring advanced (and potentially dangerous) handling. */ +#include + #include "BLI_compiler_attrs.h" #include "BLI_set.hh" #include "BLI_utildefines.h" @@ -57,13 +59,29 @@ size_t BKE_libblock_get_alloc_info(short type, const char **name); */ void *BKE_libblock_alloc_notest(short type) ATTR_WARN_UNUSED_RESULT; /** - * Allocates and returns a block of the specified type, with the specified name + * Allocates and returns an ID block of the specified type, with the specified name * (adjusted as necessary to ensure uniqueness), and appended to the specified list. * The user count is set to 1, all other content (apart from name and links) being * initialized to zero. + * + * \note: By default, IDs allocated in a Main database will get the current library of the Main, + * i.e. usually (besides in readfile case), they will have a `nullptr` `lib` pointer and be local + * data. IDs allocated outside of a Main database will always get a `nullptr` `lib` pointer. */ void *BKE_libblock_alloc(Main *bmain, short type, const char *name, int flag) ATTR_WARN_UNUSED_RESULT; +/** + * Same as for #BKE_libblock_alloc, but allows creating a data-block for a given owner library. + * + * \param owner_library the Library to 'assign' the newly created ID to. Use `nullptr` to make ID + * not use any library (i.e. become a local ID). Use `std::nullopt` for default behavior (i.e. + * behavior of the #BKE_libblock_alloc function). + */ +void *BKE_libblock_alloc_in_lib(Main *bmain, + std::optional owner_library, + short type, + const char *name, + int flag) ATTR_WARN_UNUSED_RESULT; /** * Initialize an ID of given type, such that it has valid 'empty' data. * ID is assumed to be just calloc'ed. @@ -102,9 +120,24 @@ void BKE_lib_libblock_session_uid_renew(ID *id); /** * Generic helper to create a new empty data-block of given type in given \a bmain database. * + * \note: By default, IDs created in a Main database will get the current library of the Main, + * i.e. usually (besides in readfile case), they will have a `nullptr` `lib` pointer and be local + * data. IDs created outside of a Main database will always get a `nullptr` `lib` pointer. + * \param name: can be NULL, in which case we get default name for this ID type. */ void *BKE_id_new(Main *bmain, short type, const char *name); +/** + * Same as for #BKE_id_new, but allows creating a data-block for (whithin) a given owner library. + * + * \param owner_library the Library to 'assign' the newly created ID to. Use `nullptr` to make ID + * not use any library (i.e. become a local ID). Use `std::nullopt` for default behavior (i.e. + * behavior of the #BKE_id_new function). + */ +void *BKE_id_new_in_lib(Main *bmain, + std::optional owner_library, + short type, + const char *name); /** * Generic helper to create a new temporary empty data-block of given type, * *outside* of any Main database. @@ -163,8 +196,6 @@ enum { /* *** Ideally we should not have those, but we need them for now... *** */ /** EXCEPTION! Deep-copy actions used by animation-data of copied ID. */ LIB_ID_COPY_ACTIONS = 1 << 24, - /** Keep the library pointer when copying data-block outside of bmain. */ - LIB_ID_COPY_KEEP_LIB = 1 << 25, /** EXCEPTION! Deep-copy shape-keys used by copied obdata ID. */ LIB_ID_COPY_SHAPEKEY = 1 << 26, /** EXCEPTION! Specific deep-copy of node trees used e.g. for rendering purposes. */ @@ -188,8 +219,28 @@ enum { }; void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, int orig_flag); +/** + * Same as #BKE_libblock_copy_ex, but allows copying data into a library, and not as local data + * only. + * + * \param owner_library the Library to 'assign' the newly created ID to. Use `nullptr` to make ID + * not use any library (i.e. become a local ID). Use std::nullopt for default behavior (i.e. + * behavior of the #BKE_libblock_copy_ex function). + */ +void BKE_libblock_copy_in_lib(Main *bmain, + std::optional owner_library, + const ID *id, + ID **r_newid, + int orig_flag); + /** * Used everywhere in blenkernel. + * + * \note Typically, the newly copied ID will be a local data (its `lib` pointer will be `nullptr`). + * In practice, ID copying follows the same behavior as ID creation (see #BKE_libblock_alloc + * documentation), with one special case: when the special flag #LIB_ID_CREATE_NO_ALLOCATE is + * specified, the copied ID will have the same library as the source ID. + * */ void *BKE_libblock_copy(Main *bmain, const ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); @@ -436,6 +487,11 @@ bool BKE_id_copy_is_allowed(const ID *id); * * \note User-count of new copy is always set to 1. * + * \note Typically, the newly copied ID will be a local data (its `lib` pointer will be `nullptr`). + * In practice, ID copying follows the same behavior as ID creation (see #BKE_libblock_alloc + * documentation), with one special case: when the special flag #LIB_ID_CREATE_NO_ALLOCATE is + * specified, the copied ID will have the same library as the source ID. + * * \param bmain: Main database, may be NULL only if LIB_ID_CREATE_NO_MAIN is specified. * \param id: Source data-block. * \param r_newid: Pointer to new (copied) ID pointer, may be NULL. @@ -445,6 +501,17 @@ bool BKE_id_copy_is_allowed(const ID *id); * \return NULL when copying that ID type is not supported, the new copy otherwise. */ ID *BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, int flag); +/** + * Enable coying non-local data into libraries. + * + * See #BKE_id_copy_ex for details. + * + * \param owner_library the Library to 'assign' the newly created ID to. Use `nullptr` to make ID + * not use any library (i.e. become a local ID). Use std::nullopt for default behavior (i.e. + * behavior of the #BKE_id_copy_ex function). + */ +struct ID *BKE_id_copy_in_lib( + Main *bmain, std::optional owner_library, const ID *id, ID **r_newid, int flag); /** * Invoke the appropriate copy method for the block and return the new id as result. * diff --git a/source/blender/blenkernel/intern/action.cc b/source/blender/blenkernel/intern/action.cc index 87aa3d03390..eb41ba1b206 100644 --- a/source/blender/blenkernel/intern/action.cc +++ b/source/blender/blenkernel/intern/action.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -97,7 +98,11 @@ static CLG_LogRef LOG = {"bke.action"}; * * \param flag: Copying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more). */ -static void action_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag) +static void action_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int flag) { bAction *action_dst = (bAction *)id_dst; const bAction *action_src = (const bAction *)id_src; diff --git a/source/blender/blenkernel/intern/anim_data.cc b/source/blender/blenkernel/intern/anim_data.cc index 1811c58bd65..d4658967b67 100644 --- a/source/blender/blenkernel/intern/anim_data.cc +++ b/source/blender/blenkernel/intern/anim_data.cc @@ -8,6 +8,7 @@ #include "MEM_guardedalloc.h" #include +#include #include "BKE_action.h" #include "BKE_anim_data.hh" @@ -303,7 +304,10 @@ void BKE_animdata_foreach_id(AnimData *adt, LibraryForeachIDData *data) /* Copying -------------------------------------------- */ -AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag) +AnimData *BKE_animdata_copy_in_lib(Main *bmain, + std::optional owner_library, + AnimData *adt, + const int flag) { AnimData *dadt; @@ -333,8 +337,10 @@ AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag) flag; BLI_assert(bmain != nullptr); BLI_assert(dadt->action == nullptr || dadt->action != dadt->tmpact); - dadt->action = (bAction *)BKE_id_copy_ex(bmain, (ID *)dadt->action, nullptr, id_copy_flag); - dadt->tmpact = (bAction *)BKE_id_copy_ex(bmain, (ID *)dadt->tmpact, nullptr, id_copy_flag); + dadt->action = reinterpret_cast(BKE_id_copy_in_lib( + bmain, owner_library, reinterpret_cast(dadt->action), nullptr, id_copy_flag)); + dadt->tmpact = reinterpret_cast(BKE_id_copy_in_lib( + bmain, owner_library, reinterpret_cast(dadt->tmpact), nullptr, id_copy_flag)); } else if (do_id_user) { id_us_plus((ID *)dadt->action); @@ -355,6 +361,11 @@ AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag) return dadt; } +AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag) +{ + return BKE_animdata_copy_in_lib(bmain, std::nullopt, adt, flag); +} + bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, const int flag) { AnimData *adt; diff --git a/source/blender/blenkernel/intern/armature.cc b/source/blender/blenkernel/intern/armature.cc index 6573ae5e9b2..cd1c624083b 100644 --- a/source/blender/blenkernel/intern/armature.cc +++ b/source/blender/blenkernel/intern/armature.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -130,7 +131,11 @@ static void copy_bone_collection(bArmature *armature_dst, * * \param flag: Copying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more). */ -static void armature_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag) +static void armature_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int flag) { bArmature *armature_dst = (bArmature *)id_dst; const bArmature *armature_src = (const bArmature *)id_src; diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc index 6806806d088..c9d73e40933 100644 --- a/source/blender/blenkernel/intern/brush.cc +++ b/source/blender/blenkernel/intern/brush.cc @@ -5,6 +5,7 @@ /** \file * \ingroup bke */ +#include #include "MEM_guardedalloc.h" @@ -55,7 +56,11 @@ static void brush_init_data(ID *id) BKE_brush_curve_preset(brush, CURVE_PRESET_SMOOTH); } -static void brush_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag) +static void brush_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int flag) { Brush *brush_dst = (Brush *)id_dst; const Brush *brush_src = (const Brush *)id_src; diff --git a/source/blender/blenkernel/intern/cachefile.cc b/source/blender/blenkernel/intern/cachefile.cc index c8c4c667752..6c4b179eb88 100644 --- a/source/blender/blenkernel/intern/cachefile.cc +++ b/source/blender/blenkernel/intern/cachefile.cc @@ -7,6 +7,7 @@ */ #include +#include #include "DNA_cachefile_types.h" #include "DNA_object_types.h" @@ -59,6 +60,7 @@ static void cache_file_init_data(ID *id) } static void cache_file_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, ID *id_dst, const ID *id_src, const int /*flag*/) diff --git a/source/blender/blenkernel/intern/camera.cc b/source/blender/blenkernel/intern/camera.cc index aaabf3bed1d..5d8fad6e3d1 100644 --- a/source/blender/blenkernel/intern/camera.cc +++ b/source/blender/blenkernel/intern/camera.cc @@ -8,6 +8,7 @@ #include #include +#include /* Allow using deprecated functionality for .blend file I/O. */ #define DNA_DEPRECATED_ALLOW @@ -68,7 +69,11 @@ static void camera_init_data(ID *id) * * \param flag: Copying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more). */ -static void camera_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag) +static void camera_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int flag) { Camera *cam_dst = (Camera *)id_dst; const Camera *cam_src = (const Camera *)id_src; diff --git a/source/blender/blenkernel/intern/collection.cc b/source/blender/blenkernel/intern/collection.cc index e2b03a973ab..95395a9626d 100644 --- a/source/blender/blenkernel/intern/collection.cc +++ b/source/blender/blenkernel/intern/collection.cc @@ -12,6 +12,7 @@ #include "CLG_log.h" #include +#include #include "BLI_blenlib.h" #include "BLI_iterator.h" @@ -132,7 +133,11 @@ static void collection_init_data(ID *id) * * \param flag: Copying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more). */ -static void collection_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) +static void collection_copy_data(Main *bmain, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int flag) { Collection *collection_dst = (Collection *)id_dst; const Collection *collection_src = (const Collection *)id_src; @@ -929,13 +934,15 @@ Collection *BKE_collection_master_add(Scene *scene) BLI_assert(scene != nullptr && scene->master_collection == nullptr); /* Not an actual datablock, but owned by scene. */ - Collection *master_collection = static_cast( - BKE_libblock_alloc(nullptr, ID_GR, BKE_SCENE_COLLECTION_NAME, LIB_ID_CREATE_NO_MAIN)); + Collection *master_collection = static_cast(BKE_libblock_alloc_in_lib( + nullptr, scene->id.lib, ID_GR, BKE_SCENE_COLLECTION_NAME, LIB_ID_CREATE_NO_MAIN)); master_collection->id.flag |= LIB_EMBEDDED_DATA; master_collection->owner_id = &scene->id; master_collection->flag |= COLLECTION_IS_MASTER; master_collection->color_tag = COLLECTION_COLOR_NONE; + BLI_assert(scene->id.lib == master_collection->id.lib); + return master_collection; } diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index 14adcdb2496..55ad75bd48a 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -9,6 +9,7 @@ #include /* floor */ #include #include +#include #include "MEM_guardedalloc.h" @@ -79,7 +80,11 @@ static void curve_init_data(ID *id) MEMCPY_STRUCT_AFTER(curve, DNA_struct_default_get(Curve), id); } -static void curve_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) +static void curve_copy_data(Main *bmain, + std::optional owner_library, + ID *id_dst, + const ID *id_src, + const int flag) { Curve *curve_dst = (Curve *)id_dst; const Curve *curve_src = (const Curve *)id_src; @@ -97,7 +102,7 @@ static void curve_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int curve_dst->bevel_profile = BKE_curveprofile_copy(curve_src->bevel_profile); if (curve_src->key && (flag & LIB_ID_COPY_SHAPEKEY)) { - BKE_id_copy_ex(bmain, &curve_src->key->id, (ID **)&curve_dst->key, flag); + BKE_id_copy_in_lib(bmain, owner_library, &curve_src->key->id, (ID **)&curve_dst->key, flag); /* XXX This is not nice, we need to make BKE_id_copy_ex fully re-entrant... */ curve_dst->key->from = &curve_dst->id; } diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc index 55bd587d0a4..a87ab0366f2 100644 --- a/source/blender/blenkernel/intern/curves.cc +++ b/source/blender/blenkernel/intern/curves.cc @@ -8,6 +8,7 @@ #include #include +#include #include "MEM_guardedalloc.h" @@ -61,7 +62,11 @@ static void curves_init_data(ID *id) new (&curves->geometry) blender::bke::CurvesGeometry(); } -static void curves_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/) +static void curves_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int /*flag*/) { Curves *curves_dst = (Curves *)id_dst; const Curves *curves_src = (const Curves *)id_src; diff --git a/source/blender/blenkernel/intern/gpencil_legacy.cc b/source/blender/blenkernel/intern/gpencil_legacy.cc index 649de3a27d9..3628aa1c7ac 100644 --- a/source/blender/blenkernel/intern/gpencil_legacy.cc +++ b/source/blender/blenkernel/intern/gpencil_legacy.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include "CLG_log.h" @@ -59,6 +60,7 @@ static CLG_LogRef LOG = {"bke.gpencil"}; static void greasepencil_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, ID *id_dst, const ID *id_src, const int /*flag*/) @@ -1059,7 +1061,7 @@ bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool in } /* Copy internal data (layers, etc.) */ - greasepencil_copy_data(bmain, &gpd_dst->id, &gpd_src->id, 0); + greasepencil_copy_data(bmain, std::nullopt, &gpd_dst->id, &gpd_src->id, 0); /* return new */ return gpd_dst; diff --git a/source/blender/blenkernel/intern/grease_pencil.cc b/source/blender/blenkernel/intern/grease_pencil.cc index bbdf542887f..6f115a62d1b 100644 --- a/source/blender/blenkernel/intern/grease_pencil.cc +++ b/source/blender/blenkernel/intern/grease_pencil.cc @@ -7,6 +7,7 @@ */ #include +#include #include "BKE_action.h" #include "BKE_anim_data.hh" @@ -88,6 +89,7 @@ static void grease_pencil_init_data(ID *id) } static void grease_pencil_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, ID *id_dst, const ID *id_src, const int /*flag*/) diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index d10355ed1eb..35f265bd329 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -12,6 +12,7 @@ #include #include #include +#include #ifndef WIN32 # include #else @@ -156,7 +157,11 @@ static void image_init_data(ID *id) } } -static void image_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag) +static void image_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int flag) { Image *image_dst = (Image *)id_dst; const Image *image_src = (const Image *)id_src; diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 4749fc1138e..b40ec9e3644 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -54,7 +55,11 @@ #include "BLO_read_write.hh" -static void shapekey_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/) +static void shapekey_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int /*flag*/) { Key *key_dst = (Key *)id_dst; const Key *key_src = (const Key *)id_src; diff --git a/source/blender/blenkernel/intern/lattice.cc b/source/blender/blenkernel/intern/lattice.cc index 3865391ef7c..fde95d5aa45 100644 --- a/source/blender/blenkernel/intern/lattice.cc +++ b/source/blender/blenkernel/intern/lattice.cc @@ -56,7 +56,11 @@ static void lattice_init_data(ID *id) BKE_lattice_resize(lattice, 2, 2, 2, nullptr); /* creates a uniform lattice */ } -static void lattice_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) +static void lattice_copy_data(Main *bmain, + std::optional owner_library, + ID *id_dst, + const ID *id_src, + const int flag) { Lattice *lattice_dst = (Lattice *)id_dst; const Lattice *lattice_src = (const Lattice *)id_src; @@ -64,7 +68,8 @@ static void lattice_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const i lattice_dst->def = static_cast(MEM_dupallocN(lattice_src->def)); if (lattice_src->key && (flag & LIB_ID_COPY_SHAPEKEY)) { - BKE_id_copy_ex(bmain, &lattice_src->key->id, (ID **)&lattice_dst->key, flag); + BKE_id_copy_in_lib( + bmain, owner_library, &lattice_src->key->id, (ID **)&lattice_dst->key, flag); /* XXX This is not nice, we need to make BKE_id_copy_ex fully re-entrant... */ lattice_dst->key->from = &lattice_dst->id; } diff --git a/source/blender/blenkernel/intern/lib_id.cc b/source/blender/blenkernel/intern/lib_id.cc index 6b906db4af2..8b7cc831ec6 100644 --- a/source/blender/blenkernel/intern/lib_id.cc +++ b/source/blender/blenkernel/intern/lib_id.cc @@ -626,19 +626,28 @@ bool BKE_id_copy_is_allowed(const ID *id) #undef LIB_ID_TYPES_NOCOPY } -ID *BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag) +ID *BKE_id_copy_in_lib(Main *bmain, + std::optional owner_library, + const ID *id, + ID **r_newid, + const int flag) { ID *newid = (r_newid != nullptr) ? *r_newid : nullptr; + BLI_assert_msg(newid || (flag & LIB_ID_CREATE_NO_ALLOCATE) == 0, + "Copying with 'no allocate' behavior should always get a non-null new ID buffer"); + /* Make sure destination pointer is all good. */ if ((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0) { newid = nullptr; } else { - if (newid != nullptr) { - /* Allow some garbage non-initialized memory to go in, and clean it up here. */ - const size_t size = BKE_libblock_get_alloc_info(GS(id->name), nullptr); - memset(newid, 0, size); + if (!newid) { + /* Invalid case, already caught by the assert above. */ + return nullptr; } + /* Allow some garbage non-initialized memory to go in, and clean it up here. */ + const size_t size = BKE_libblock_get_alloc_info(GS(id->name), nullptr); + memset(newid, 0, size); } /* Early output if source is nullptr. */ @@ -653,16 +662,21 @@ ID *BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag) return nullptr; } - BKE_libblock_copy_ex(bmain, id, &newid, flag); + BKE_libblock_copy_in_lib(bmain, owner_library, id, &newid, flag); if (idtype_info->copy_data != nullptr) { - idtype_info->copy_data(bmain, newid, id, flag); + idtype_info->copy_data(bmain, owner_library, newid, id, flag); } } else { BLI_assert_msg(0, "IDType Missing IDTypeInfo"); } + BLI_assert_msg(newid, "Could not get an allocated new ID to copy into"); + if (!newid) { + return nullptr; + } + /* Update ID refcount, remap pointers to self in new ID. */ IDCopyLibManagementData data{}; data.id_src = id; @@ -673,11 +687,20 @@ ID *BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag) /* 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_CREATE_NO_MAIN) == 0) { - BLI_assert((flag & LIB_ID_COPY_KEEP_LIB) == 0); - lib_id_copy_ensure_local(bmain, id, newid, 0); + BLI_assert(!owner_library || newid->lib == *owner_library); + if (!ID_IS_LINKED(newid)) { + lib_id_copy_ensure_local(bmain, id, newid, 0); + } } else { - newid->lib = id->lib; + /* NOTE: Do not call `ensure_local` for IDs copied outside of Main, even if they do become + * local. + * + * Most of the time, this would not be the desired behavior currently. + * + * In the few cases where this is actually needed (e.g. from liboverride resync code, see + * #lib_override_library_create_from), calling code is responsible for this. */ + newid->lib = owner_library ? *owner_library : id->lib; } if (r_newid != nullptr) { @@ -687,9 +710,14 @@ ID *BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag) return newid; } +ID *BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag) +{ + return BKE_id_copy_in_lib(bmain, std::nullopt, id, r_newid, flag); +} + ID *BKE_id_copy(Main *bmain, const ID *id) { - return BKE_id_copy_ex(bmain, id, nullptr, LIB_ID_COPY_DEFAULT); + return BKE_id_copy_in_lib(bmain, std::nullopt, id, nullptr, LIB_ID_COPY_DEFAULT); } ID *BKE_id_copy_for_duplicate(Main *bmain, @@ -1220,7 +1248,11 @@ void *BKE_libblock_alloc_notest(short type) return nullptr; } -void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int flag) +void *BKE_libblock_alloc_in_lib(Main *bmain, + std::optional owner_library, + short type, + const char *name, + const int flag) { BLI_assert((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0); BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || bmain != nullptr); @@ -1250,20 +1282,44 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int fl BLI_assert(bmain->is_locked_for_linking == false || ELEM(type, ID_WS, ID_GR, ID_NT)); ListBase *lb = which_libbase(bmain, type); + /* This is important in 'readfile doversion after liblink' context mainly, but is a good + * behavior for consistency in general: ID created for a Main should get that main's current + * library pointer. + * + * NOTE: A bit convoluted. + * - When Main has a defined `curlib`, it is assumed to be a split main containing only IDs + * from that library. In that case, the library can be set later, and it avoids + * synchronization issues in the namemap between the one of that temp 'library' Main and + * the library ID runtime namemap itself. In a way, the ID can be assumed local to the + * current Main, for its assignment to this Main. + * - In all other cases, the Main is assumed 'complete', i.e. containing all local and + * linked IDs, In that case, it is critical that the ID gets the correct library assigned + * now, to ensure that the call to #BKE_id_new_name_validate gives a fully valid result + * once it has been assigned to the current Main. + */ + if (bmain->curlib) { + id->lib = nullptr; + } + else { + id->lib = owner_library ? *owner_library : nullptr; + } + BKE_main_lock(bmain); BLI_addtail(lb, id); - BKE_id_new_name_validate(bmain, lb, id, name, false); + BKE_id_new_name_validate(bmain, lb, id, name, true); bmain->is_memfile_undo_written = false; /* alphabetic insertion: is in new_id */ BKE_main_unlock(bmain); + /* Split Main case, now the ID should get the Main's #curlib. */ + if (bmain->curlib) { + BLI_assert(!owner_library || *owner_library == bmain->curlib); + id->lib = bmain->curlib; + } + /* This assert avoids having to keep name_map consistency when changing the library of an ID, * if this check is not true anymore it will have to be done here too. */ BLI_assert(bmain->curlib == nullptr || bmain->curlib->runtime.name_map == nullptr); - /* This is important in 'readfile doversion after liblink' context mainly, but is a good - * consistency change in general: ID created for a Main should get that main's current - * library pointer. */ - id->lib = bmain->curlib; /* TODO: to be removed from here! */ if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0) { @@ -1272,6 +1328,7 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int fl } else { BLI_strncpy(id->name + 2, name, sizeof(id->name) - 2); + id->lib = owner_library ? *owner_library : nullptr; } /* We also need to ensure a valid `session_uid` for some non-main data (like embedded IDs). @@ -1285,6 +1342,11 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int fl return id; } +void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int flag) +{ + return BKE_libblock_alloc_in_lib(bmain, std::nullopt, type, name, flag); +} + void BKE_libblock_init_empty(ID *id) { const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id); @@ -1329,7 +1391,11 @@ void BKE_lib_libblock_session_uid_renew(ID *id) BKE_lib_libblock_session_uid_ensure(id); } -void *BKE_id_new(Main *bmain, const short type, const char *name) +void *BKE_id_new_in_lib(Main *bmain, + std::optional owner_library, + const short type, + const char *name) + { BLI_assert(bmain != nullptr); @@ -1337,12 +1403,17 @@ void *BKE_id_new(Main *bmain, const short type, const char *name) name = DATA_(BKE_idtype_idcode_to_name(type)); } - ID *id = static_cast(BKE_libblock_alloc(bmain, type, name, 0)); + ID *id = static_cast(BKE_libblock_alloc_in_lib(bmain, owner_library, type, name, 0)); BKE_libblock_init_empty(id); return id; } +void *BKE_id_new(Main *bmain, const short type, const char *name) +{ + return BKE_id_new_in_lib(bmain, std::nullopt, type, name); +} + void *BKE_id_new_nomain(const short type, const char *name) { if (name == nullptr) { @@ -1359,7 +1430,11 @@ void *BKE_id_new_nomain(const short type, const char *name) return id; } -void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int orig_flag) +void BKE_libblock_copy_in_lib(Main *bmain, + std::optional owner_library, + const ID *id, + ID **r_newid, + const int orig_flag) { ID *new_id = *r_newid; int flag = orig_flag; @@ -1388,10 +1463,12 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int ori STRNCPY(new_id->name, id->name); new_id->us = 0; new_id->tag |= LIB_TAG_NOT_ALLOCATED | LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT; + new_id->lib = owner_library ? *owner_library : id->lib; /* TODO: Do we want/need to copy more from ID struct itself? */ } else { - new_id = static_cast(BKE_libblock_alloc(bmain, GS(id->name), id->name + 2, flag)); + new_id = static_cast( + BKE_libblock_alloc_in_lib(bmain, owner_library, GS(id->name), id->name + 2, flag)); } BLI_assert(new_id != nullptr); @@ -1451,7 +1528,7 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int ori * in their anim data *are* in bmain... super-mega-hooray. */ BLI_assert((copy_data_flag & LIB_ID_COPY_ACTIONS) == 0 || (copy_data_flag & LIB_ID_CREATE_NO_MAIN) == 0); - iat->adt = BKE_animdata_copy(bmain, iat->adt, copy_data_flag); + iat->adt = BKE_animdata_copy_in_lib(bmain, owner_library, iat->adt, copy_data_flag); } else { iat->adt = nullptr; @@ -1465,11 +1542,16 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int ori *r_newid = new_id; } +void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int orig_flag) +{ + BKE_libblock_copy_in_lib(bmain, std::nullopt, id, r_newid, orig_flag); +} + void *BKE_libblock_copy(Main *bmain, const ID *id) { ID *idn; - BKE_libblock_copy_ex(bmain, id, &idn, 0); + BKE_libblock_copy_in_lib(bmain, std::nullopt, id, &idn, 0); return idn; } diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index d0927375f16..7df00b7c0ef 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -253,11 +253,17 @@ static ID *lib_override_library_create_from(Main *bmain, const int lib_id_copy_flags) { /* NOTE: do not copy possible override data from the reference here. */ - ID *local_id = BKE_id_copy_ex(bmain, - reference_id, - nullptr, - LIB_ID_COPY_DEFAULT | LIB_ID_COPY_NO_LIB_OVERRIDE | - lib_id_copy_flags); + ID *local_id = BKE_id_copy_in_lib( + bmain, + owner_library, + reference_id, + nullptr, + (LIB_ID_COPY_DEFAULT | LIB_ID_COPY_NO_LIB_OVERRIDE | lib_id_copy_flags)); + if (local_id == nullptr) { + return nullptr; + } + BLI_assert(local_id->lib == owner_library); + id_us_min(local_id); /* In case we could not get an override ID with the exact same name as its linked reference, * ensure we at least get a uniquely named override ID over the whole current Main data, to @@ -271,16 +277,14 @@ static ID *lib_override_library_create_from(Main *bmain, id_sort_by_name(which_libbase(bmain, GS(local_id->name)), local_id, nullptr); } - if (local_id == nullptr) { - return nullptr; - } - id_us_min(local_id); - - /* TODO: Handle this properly in LIB_NO_MAIN case as well (i.e. resync case). Or offload to - * generic ID copy code? Would probably be better to have a version of #BKE_id_copy_ex that takes - * an extra `target_lib` parameter. */ - local_id->lib = owner_library; - if ((lib_id_copy_flags & LIB_ID_CREATE_NO_MAIN) != 0 && owner_library == nullptr) { + /* In `NO_MAIN` case, generic `BKE_id_copy` code won't call this. + * In liboverride resync case however, the currently not-in-Main new IDs will be added back to + * Main later, so ensure that their linked dependencies and paths are properly handled here. + * + * NOTE: This is likely not the best place to do this. Ideally, #BKE_libblock_management_main_add + * e.g. should take care of this. But for the time being, this works and has been battle-proofed. + */ + if ((lib_id_copy_flags & LIB_ID_CREATE_NO_MAIN) != 0 && !ID_IS_LINKED(local_id)) { lib_id_copy_ensure_local(bmain, reference_id, local_id, 0); } diff --git a/source/blender/blenkernel/intern/light.cc b/source/blender/blenkernel/intern/light.cc index 7a17c5e0e29..7d475b5da03 100644 --- a/source/blender/blenkernel/intern/light.cc +++ b/source/blender/blenkernel/intern/light.cc @@ -7,6 +7,7 @@ */ #include +#include #include "MEM_guardedalloc.h" @@ -53,7 +54,11 @@ static void light_init_data(ID *id) * * \param flag: Copying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more). */ -static void light_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) +static void light_copy_data(Main *bmain, + std::optional owner_library, + ID *id_dst, + const ID *id_src, + const int flag) { Light *la_dst = (Light *)id_dst; const Light *la_src = (const Light *)id_src; @@ -67,8 +72,11 @@ static void light_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int la_dst->nodetree = ntreeLocalize(la_src->nodetree); } else { - BKE_id_copy_ex( - bmain, (ID *)la_src->nodetree, (ID **)&la_dst->nodetree, flag_private_id_data); + BKE_id_copy_in_lib(bmain, + owner_library, + (ID *)la_src->nodetree, + (ID **)&la_dst->nodetree, + flag_private_id_data); } la_dst->nodetree->owner_id = &la_dst->id; } diff --git a/source/blender/blenkernel/intern/linestyle.cc b/source/blender/blenkernel/intern/linestyle.cc index 1891d7d7383..e83bfe745d3 100644 --- a/source/blender/blenkernel/intern/linestyle.cc +++ b/source/blender/blenkernel/intern/linestyle.cc @@ -9,6 +9,8 @@ #include #include #include +#include + #include #include "MEM_guardedalloc.h" @@ -50,7 +52,11 @@ static void linestyle_init_data(ID *id) BKE_linestyle_geometry_modifier_add(linestyle, nullptr, LS_MODIFIER_SAMPLING); } -static void linestyle_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) +static void linestyle_copy_data(Main *bmain, + std::optional owner_library, + ID *id_dst, + const ID *id_src, + const int flag) { FreestyleLineStyle *linestyle_dst = (FreestyleLineStyle *)id_dst; const FreestyleLineStyle *linestyle_src = (const FreestyleLineStyle *)id_src; @@ -68,10 +74,11 @@ static void linestyle_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const } if (linestyle_src->nodetree) { - BKE_id_copy_ex(bmain, - (ID *)linestyle_src->nodetree, - (ID **)&linestyle_dst->nodetree, - flag_private_id_data); + BKE_id_copy_in_lib(bmain, + owner_library, + (ID *)linestyle_src->nodetree, + (ID **)&linestyle_dst->nodetree, + flag_private_id_data); linestyle_dst->nodetree->owner_id = &linestyle_dst->id; } diff --git a/source/blender/blenkernel/intern/main_namemap.cc b/source/blender/blenkernel/intern/main_namemap.cc index 4b39f7dd41f..c5526f92817 100644 --- a/source/blender/blenkernel/intern/main_namemap.cc +++ b/source/blender/blenkernel/intern/main_namemap.cc @@ -401,6 +401,7 @@ bool BKE_main_namemap_get_name(Main *bmain, ID *id, char *name, const bool do_un * truncated name again. */ is_name_changed = true; } + return is_name_changed; } diff --git a/source/blender/blenkernel/intern/mask.cc b/source/blender/blenkernel/intern/mask.cc index b4f922d75a0..d83ce2575dd 100644 --- a/source/blender/blenkernel/intern/mask.cc +++ b/source/blender/blenkernel/intern/mask.cc @@ -8,6 +8,7 @@ #include #include +#include #include "CLG_log.h" @@ -49,7 +50,11 @@ static CLG_LogRef LOG = {"bke.mask"}; -static void mask_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/) +static void mask_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int /*flag*/) { Mask *mask_dst = (Mask *)id_dst; const Mask *mask_src = (const Mask *)id_src; diff --git a/source/blender/blenkernel/intern/material.cc b/source/blender/blenkernel/intern/material.cc index fcfdebc4058..e8a79b8343f 100644 --- a/source/blender/blenkernel/intern/material.cc +++ b/source/blender/blenkernel/intern/material.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include "CLG_log.h" @@ -91,7 +92,11 @@ static void material_init_data(ID *id) *((short *)id->name) = ID_MA; } -static void material_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) +static void material_copy_data(Main *bmain, + std::optional owner_library, + ID *id_dst, + const ID *id_src, + const int flag) { Material *material_dst = (Material *)id_dst; const Material *material_src = (const Material *)id_src; @@ -105,10 +110,11 @@ static void material_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const material_dst->nodetree = ntreeLocalize(material_src->nodetree); } else { - BKE_id_copy_ex(bmain, - (ID *)material_src->nodetree, - (ID **)&material_dst->nodetree, - flag_private_id_data); + BKE_id_copy_in_lib(bmain, + owner_library, + (ID *)material_src->nodetree, + (ID **)&material_dst->nodetree, + flag_private_id_data); } material_dst->nodetree->owner_id = &material_dst->id; } diff --git a/source/blender/blenkernel/intern/mball.cc b/source/blender/blenkernel/intern/mball.cc index 8628846a5b5..8002ed8dca4 100644 --- a/source/blender/blenkernel/intern/mball.cc +++ b/source/blender/blenkernel/intern/mball.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -64,7 +65,11 @@ static void metaball_init_data(ID *id) MEMCPY_STRUCT_AFTER(metaball, DNA_struct_default_get(MetaBall), id); } -static void metaball_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/) +static void metaball_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int /*flag*/) { MetaBall *metaball_dst = (MetaBall *)id_dst; const MetaBall *metaball_src = (const MetaBall *)id_src; diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 6c097019e23..89e968be30f 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -6,6 +6,8 @@ * \ingroup bke */ +#include + #include "MEM_guardedalloc.h" /* Allow using deprecated functionality for .blend file I/O. */ @@ -99,7 +101,11 @@ static void mesh_init_data(ID *id) mesh->face_sets_color_seed = BLI_hash_int(BLI_time_now_seconds_i() & UINT_MAX); } -static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) +static void mesh_copy_data(Main *bmain, + std::optional owner_library, + ID *id_dst, + const ID *id_src, + const int flag) { Mesh *mesh_dst = reinterpret_cast(id_dst); const Mesh *mesh_src = reinterpret_cast(id_src); @@ -193,7 +199,7 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int /* TODO: Do we want to add flag to prevent this? */ if (mesh_src->key && (flag & LIB_ID_COPY_SHAPEKEY)) { - BKE_id_copy_ex(bmain, &mesh_src->key->id, (ID **)&mesh_dst->key, flag); + BKE_id_copy_in_lib(bmain, owner_library, &mesh_src->key->id, (ID **)&mesh_dst->key, flag); /* XXX This is not nice, we need to make BKE_id_copy_ex fully re-entrant... */ mesh_dst->key->from = &mesh_dst->id; } diff --git a/source/blender/blenkernel/intern/movieclip.cc b/source/blender/blenkernel/intern/movieclip.cc index 359192579a2..838d0ab969f 100644 --- a/source/blender/blenkernel/intern/movieclip.cc +++ b/source/blender/blenkernel/intern/movieclip.cc @@ -9,6 +9,7 @@ #include #include #include +#include #ifndef WIN32 # include @@ -81,7 +82,11 @@ static void movie_clip_init_data(ID *id) BKE_color_managed_colorspace_settings_init(&movie_clip->colorspace_settings); } -static void movie_clip_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag) +static void movie_clip_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int flag) { MovieClip *movie_clip_dst = (MovieClip *)id_dst; const MovieClip *movie_clip_src = (const MovieClip *)id_src; diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 31666ef6d79..60048248ec2 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -14,6 +14,7 @@ #include #include #include +#include /* Allow using deprecated functionality for .blend file I/O. */ #define DNA_DEPRECATED_ALLOW @@ -150,7 +151,11 @@ static void ntree_init_data(ID *id) ntree_set_typeinfo(ntree, nullptr); } -static void ntree_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag) +static void ntree_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int flag) { bNodeTree *ntree_dst = reinterpret_cast(id_dst); const bNodeTree *ntree_src = reinterpret_cast(id_src); diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 18c15d74b92..d81e76f090f 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include "CLG_log.h" @@ -188,7 +189,11 @@ static void object_init_data(ID *id) animviz_settings_init(&ob->avs); } -static void object_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) +static void object_copy_data(Main *bmain, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int flag) { Object *ob_dst = (Object *)id_dst; const Object *ob_src = (const Object *)id_src; diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index dc26aca972f..18058a053e7 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -8,6 +8,7 @@ #include #include +#include #include "MEM_guardedalloc.h" @@ -100,7 +101,11 @@ static void palette_init_data(ID *id) id_fake_user_set(&palette->id); } -static void palette_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/) +static void palette_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int /*flag*/) { Palette *palette_dst = (Palette *)id_dst; const Palette *palette_src = (const Palette *)id_src; @@ -172,6 +177,7 @@ IDTypeInfo IDType_ID_PAL = { }; static void paint_curve_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, ID *id_dst, const ID *id_src, const int /*flag*/) diff --git a/source/blender/blenkernel/intern/particle.cc b/source/blender/blenkernel/intern/particle.cc index 17d2594055f..b608d908dd7 100644 --- a/source/blender/blenkernel/intern/particle.cc +++ b/source/blender/blenkernel/intern/particle.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -99,6 +100,7 @@ static void particle_settings_init(ID *id) } static void particle_settings_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, ID *id_dst, const ID *id_src, const int /*flag*/) diff --git a/source/blender/blenkernel/intern/pointcloud.cc b/source/blender/blenkernel/intern/pointcloud.cc index 3ebf1bd1617..aa4a3c1d58e 100644 --- a/source/blender/blenkernel/intern/pointcloud.cc +++ b/source/blender/blenkernel/intern/pointcloud.cc @@ -6,6 +6,8 @@ * \ingroup bke */ +#include + #include "MEM_guardedalloc.h" #include "DNA_defaults.h" @@ -68,6 +70,7 @@ static void pointcloud_init_data(ID *id) } static void pointcloud_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, ID *id_dst, const ID *id_src, const int /*flag*/) diff --git a/source/blender/blenkernel/intern/scene.cc b/source/blender/blenkernel/intern/scene.cc index adb52594082..eac2b61592a 100644 --- a/source/blender/blenkernel/intern/scene.cc +++ b/source/blender/blenkernel/intern/scene.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -251,7 +252,11 @@ static void scene_copy_markers(Scene *scene_dst, const Scene *scene_src, const i } } -static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) +static void scene_copy_data(Main *bmain, + std::optional owner_library, + ID *id_dst, + const ID *id_src, + const int flag) { Scene *scene_dst = (Scene *)id_dst; const Scene *scene_src = (const Scene *)id_src; @@ -266,10 +271,11 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int /* Master Collection */ if (scene_src->master_collection) { - BKE_id_copy_ex(bmain, - (ID *)scene_src->master_collection, - (ID **)&scene_dst->master_collection, - flag_private_id_data); + BKE_id_copy_in_lib(bmain, + owner_library, + reinterpret_cast(scene_src->master_collection), + reinterpret_cast(&scene_dst->master_collection), + flag_private_id_data); scene_dst->master_collection->owner_id = &scene_dst->id; } @@ -293,8 +299,11 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int BKE_keyingsets_copy(&(scene_dst->keyingsets), &(scene_src->keyingsets)); if (scene_src->nodetree) { - BKE_id_copy_ex( - bmain, (ID *)scene_src->nodetree, (ID **)&scene_dst->nodetree, flag_private_id_data); + BKE_id_copy_in_lib(bmain, + owner_library, + (ID *)scene_src->nodetree, + (ID **)&scene_dst->nodetree, + flag_private_id_data); BKE_libblock_relink_ex(bmain, scene_dst->nodetree, (void *)(&scene_src->id), diff --git a/source/blender/blenkernel/intern/sound.cc b/source/blender/blenkernel/intern/sound.cc index 50ec2c9e611..3753152840b 100644 --- a/source/blender/blenkernel/intern/sound.cc +++ b/source/blender/blenkernel/intern/sound.cc @@ -8,6 +8,7 @@ #include #include +#include #include "MEM_guardedalloc.h" @@ -58,7 +59,11 @@ static void sound_free_audio(bSound *sound); -static void sound_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/) +static void sound_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int /*flag*/) { bSound *sound_dst = (bSound *)id_dst; const bSound *sound_src = (const bSound *)id_src; diff --git a/source/blender/blenkernel/intern/text.cc b/source/blender/blenkernel/intern/text.cc index f32ab16f037..3e53bdcefda 100644 --- a/source/blender/blenkernel/intern/text.cc +++ b/source/blender/blenkernel/intern/text.cc @@ -9,6 +9,7 @@ #include /* abort */ #include /* strstr */ #include +#include #include #include @@ -101,7 +102,11 @@ static void text_init_data(ID *id) * * \param flag: Copying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more). */ -static void text_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/) +static void text_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int /*flag*/) { Text *text_dst = (Text *)id_dst; const Text *text_src = (Text *)id_src; diff --git a/source/blender/blenkernel/intern/texture.cc b/source/blender/blenkernel/intern/texture.cc index d69e704c948..a28b566d636 100644 --- a/source/blender/blenkernel/intern/texture.cc +++ b/source/blender/blenkernel/intern/texture.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -65,7 +66,11 @@ static void texture_init_data(ID *id) BKE_imageuser_default(&texture->iuser); } -static void texture_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) +static void texture_copy_data(Main *bmain, + std::optional owner_library, + ID *id_dst, + const ID *id_src, + const int flag) { Tex *texture_dst = (Tex *)id_dst; const Tex *texture_src = (const Tex *)id_src; @@ -90,8 +95,11 @@ static void texture_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const i texture_dst->nodetree = ntreeLocalize(texture_src->nodetree); } else { - BKE_id_copy_ex( - bmain, (ID *)texture_src->nodetree, (ID **)&texture_dst->nodetree, flag_private_id_data); + BKE_id_copy_in_lib(bmain, + owner_library, + (ID *)texture_src->nodetree, + (ID **)&texture_dst->nodetree, + flag_private_id_data); } texture_dst->nodetree->owner_id = &texture_dst->id; } diff --git a/source/blender/blenkernel/intern/vfont.cc b/source/blender/blenkernel/intern/vfont.cc index d131afacbcd..06b920300a0 100644 --- a/source/blender/blenkernel/intern/vfont.cc +++ b/source/blender/blenkernel/intern/vfont.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include "CLG_log.h" @@ -82,7 +83,11 @@ static void vfont_init_data(ID *id) } } -static void vfont_copy_data(Main * /*bmain*/, ID *id_dst, const ID * /*id_src*/, const int flag) +static void vfont_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID * /*id_src*/, + const int flag) { VFont *vfont_dst = (VFont *)id_dst; diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index ac19226b63c..5b3ace72759 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -6,6 +6,8 @@ * \ingroup bke */ +#include + #include "MEM_guardedalloc.h" #include "DNA_defaults.h" @@ -148,7 +150,11 @@ static void volume_init_data(ID *id) STRNCPY(volume->velocity_grid, "velocity"); } -static void volume_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/) +static void volume_copy_data(Main * /*bmain*/, + std::optional /*owner_library*/, + ID *id_dst, + const ID *id_src, + const int /*flag*/) { Volume *volume_dst = (Volume *)id_dst; const Volume *volume_src = (const Volume *)id_src; diff --git a/source/blender/blenkernel/intern/world.cc b/source/blender/blenkernel/intern/world.cc index 3f660215df7..6c6bdc57b02 100644 --- a/source/blender/blenkernel/intern/world.cc +++ b/source/blender/blenkernel/intern/world.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -81,7 +82,11 @@ static void world_init_data(ID *id) * * \param flag: Copying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more). */ -static void world_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) +static void world_copy_data(Main *bmain, + std::optional owner_library, + ID *id_dst, + const ID *id_src, + const int flag) { World *wrld_dst = (World *)id_dst; const World *wrld_src = (const World *)id_src; @@ -95,8 +100,11 @@ static void world_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int wrld_dst->nodetree = ntreeLocalize(wrld_src->nodetree); } else { - BKE_id_copy_ex( - bmain, (ID *)wrld_src->nodetree, (ID **)&wrld_dst->nodetree, flag_private_id_data); + BKE_id_copy_in_lib(bmain, + owner_library, + (ID *)wrld_src->nodetree, + (ID **)&wrld_dst->nodetree, + flag_private_id_data); } wrld_dst->nodetree->owner_id = &wrld_dst->id; }