Core: Add proper support to add or copy IDs into libraries. #108328
|
@ -8,6 +8,8 @@
|
||||||
* \ingroup bke
|
* \ingroup bke
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "BLI_sys_types.h" /* for bool */
|
#include "BLI_sys_types.h" /* for bool */
|
||||||
|
|
||||||
struct AnimData;
|
struct AnimData;
|
||||||
|
@ -15,6 +17,7 @@ struct BlendDataReader;
|
||||||
struct BlendLibReader;
|
struct BlendLibReader;
|
||||||
struct BlendWriter;
|
struct BlendWriter;
|
||||||
struct ID;
|
struct ID;
|
||||||
|
struct Library;
|
||||||
struct LibraryForeachIDData;
|
struct LibraryForeachIDData;
|
||||||
struct Main;
|
struct Main;
|
||||||
struct ReportList;
|
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.
|
* 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.
|
* \return The copied animdata.
|
||||||
*/
|
*/
|
||||||
AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, int flag);
|
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<Library *> owner_library,
|
||||||
|
AnimData *adt,
|
||||||
|
int flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \param flag: Control ID pointers management,
|
* \param flag: Control ID pointers management,
|
||||||
* see LIB_ID_CREATE_.../LIB_ID_COPY_... flags in BKE_lib_id.hh
|
* see LIB_ID_CREATE_.../LIB_ID_COPY_... flags in BKE_lib_id.hh
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
* ID type structure, helping to factorize common operations and data for all data-block types.
|
* ID type structure, helping to factorize common operations and data for all data-block types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "BLI_sys_types.h"
|
#include "BLI_sys_types.h"
|
||||||
|
|
||||||
struct AssetTypeInfo;
|
struct AssetTypeInfo;
|
||||||
|
@ -18,6 +20,7 @@ struct BlendDataReader;
|
||||||
struct BlendLibReader;
|
struct BlendLibReader;
|
||||||
struct BlendWriter;
|
struct BlendWriter;
|
||||||
struct ID;
|
struct ID;
|
||||||
|
struct Library;
|
||||||
struct LibraryForeachIDData;
|
struct LibraryForeachIDData;
|
||||||
struct Main;
|
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);
|
using IDTypeInitDataFunction = void (*)(ID *id);
|
||||||
|
|
||||||
/** \param flag: Copying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more). */
|
/** \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<Library *> owner_library, ID *id_dst, const ID *id_src, int flag);
|
||||||
|
|
||||||
using IDTypeFreeDataFunction = void (*)(ID *id);
|
using IDTypeFreeDataFunction = void (*)(ID *id);
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
* specific cases requiring advanced (and potentially dangerous) handling.
|
* specific cases requiring advanced (and potentially dangerous) handling.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "BLI_compiler_attrs.h"
|
#include "BLI_compiler_attrs.h"
|
||||||
#include "BLI_set.hh"
|
#include "BLI_set.hh"
|
||||||
#include "BLI_utildefines.h"
|
#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;
|
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.
|
* (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
|
* The user count is set to 1, all other content (apart from name and links) being
|
||||||
* initialized to zero.
|
* 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)
|
void *BKE_libblock_alloc(Main *bmain, short type, const char *name, int flag)
|
||||||
ATTR_WARN_UNUSED_RESULT;
|
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<Library *> 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.
|
* Initialize an ID of given type, such that it has valid 'empty' data.
|
||||||
* ID is assumed to be just calloc'ed.
|
* 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.
|
* 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.
|
* \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);
|
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<Library *> owner_library,
|
||||||
|
short type,
|
||||||
|
const char *name);
|
||||||
/**
|
/**
|
||||||
* Generic helper to create a new temporary empty data-block of given type,
|
* Generic helper to create a new temporary empty data-block of given type,
|
||||||
* *outside* of any Main database.
|
* *outside* of any Main database.
|
||||||
|
@ -163,8 +196,6 @@ enum {
|
||||||
/* *** Ideally we should not have those, but we need them for now... *** */
|
/* *** Ideally we should not have those, but we need them for now... *** */
|
||||||
/** EXCEPTION! Deep-copy actions used by animation-data of copied ID. */
|
/** EXCEPTION! Deep-copy actions used by animation-data of copied ID. */
|
||||||
LIB_ID_COPY_ACTIONS = 1 << 24,
|
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. */
|
/** EXCEPTION! Deep-copy shape-keys used by copied obdata ID. */
|
||||||
LIB_ID_COPY_SHAPEKEY = 1 << 26,
|
LIB_ID_COPY_SHAPEKEY = 1 << 26,
|
||||||
/** EXCEPTION! Specific deep-copy of node trees used e.g. for rendering purposes. */
|
/** 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);
|
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<Library *> owner_library,
|
||||||
|
const ID *id,
|
||||||
|
ID **r_newid,
|
||||||
|
int orig_flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used everywhere in blenkernel.
|
* 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();
|
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 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 bmain: Main database, may be NULL only if LIB_ID_CREATE_NO_MAIN is specified.
|
||||||
* \param id: Source data-block.
|
* \param id: Source data-block.
|
||||||
* \param r_newid: Pointer to new (copied) ID pointer, may be NULL.
|
* \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.
|
* \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);
|
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<Library *> 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.
|
* Invoke the appropriate copy method for the block and return the new id as result.
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#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).
|
* \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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
bAction *action_dst = (bAction *)id_dst;
|
bAction *action_dst = (bAction *)id_dst;
|
||||||
const bAction *action_src = (const bAction *)id_src;
|
const bAction *action_src = (const bAction *)id_src;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "BKE_action.h"
|
#include "BKE_action.h"
|
||||||
#include "BKE_anim_data.hh"
|
#include "BKE_anim_data.hh"
|
||||||
|
@ -303,7 +304,10 @@ void BKE_animdata_foreach_id(AnimData *adt, LibraryForeachIDData *data)
|
||||||
|
|
||||||
/* Copying -------------------------------------------- */
|
/* Copying -------------------------------------------- */
|
||||||
|
|
||||||
AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag)
|
AnimData *BKE_animdata_copy_in_lib(Main *bmain,
|
||||||
|
std::optional<Library *> owner_library,
|
||||||
|
AnimData *adt,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
AnimData *dadt;
|
AnimData *dadt;
|
||||||
|
|
||||||
|
@ -333,8 +337,10 @@ AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag)
|
||||||
flag;
|
flag;
|
||||||
BLI_assert(bmain != nullptr);
|
BLI_assert(bmain != nullptr);
|
||||||
BLI_assert(dadt->action == nullptr || dadt->action != dadt->tmpact);
|
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->action = reinterpret_cast<bAction *>(BKE_id_copy_in_lib(
|
||||||
dadt->tmpact = (bAction *)BKE_id_copy_ex(bmain, (ID *)dadt->tmpact, nullptr, id_copy_flag);
|
bmain, owner_library, reinterpret_cast<ID *>(dadt->action), nullptr, id_copy_flag));
|
||||||
|
dadt->tmpact = reinterpret_cast<bAction *>(BKE_id_copy_in_lib(
|
||||||
|
bmain, owner_library, reinterpret_cast<ID *>(dadt->tmpact), nullptr, id_copy_flag));
|
||||||
}
|
}
|
||||||
else if (do_id_user) {
|
else if (do_id_user) {
|
||||||
id_us_plus((ID *)dadt->action);
|
id_us_plus((ID *)dadt->action);
|
||||||
|
@ -355,6 +361,11 @@ AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag)
|
||||||
return dadt;
|
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)
|
bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, const int flag)
|
||||||
{
|
{
|
||||||
AnimData *adt;
|
AnimData *adt;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#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).
|
* \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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
bArmature *armature_dst = (bArmature *)id_dst;
|
bArmature *armature_dst = (bArmature *)id_dst;
|
||||||
const bArmature *armature_src = (const bArmature *)id_src;
|
const bArmature *armature_src = (const bArmature *)id_src;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
/** \file
|
/** \file
|
||||||
* \ingroup bke
|
* \ingroup bke
|
||||||
*/
|
*/
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
@ -55,7 +56,11 @@ static void brush_init_data(ID *id)
|
||||||
BKE_brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
|
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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Brush *brush_dst = (Brush *)id_dst;
|
Brush *brush_dst = (Brush *)id_dst;
|
||||||
const Brush *brush_src = (const Brush *)id_src;
|
const Brush *brush_src = (const Brush *)id_src;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "DNA_cachefile_types.h"
|
#include "DNA_cachefile_types.h"
|
||||||
#include "DNA_object_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*/,
|
static void cache_file_copy_data(Main * /*bmain*/,
|
||||||
|
std::optional<Library *> /*owner_library*/,
|
||||||
ID *id_dst,
|
ID *id_dst,
|
||||||
const ID *id_src,
|
const ID *id_src,
|
||||||
const int /*flag*/)
|
const int /*flag*/)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
/* Allow using deprecated functionality for .blend file I/O. */
|
/* Allow using deprecated functionality for .blend file I/O. */
|
||||||
#define DNA_DEPRECATED_ALLOW
|
#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).
|
* \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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Camera *cam_dst = (Camera *)id_dst;
|
Camera *cam_dst = (Camera *)id_dst;
|
||||||
const Camera *cam_src = (const Camera *)id_src;
|
const Camera *cam_src = (const Camera *)id_src;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "CLG_log.h"
|
#include "CLG_log.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_iterator.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).
|
* \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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Collection *collection_dst = (Collection *)id_dst;
|
Collection *collection_dst = (Collection *)id_dst;
|
||||||
const Collection *collection_src = (const Collection *)id_src;
|
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);
|
BLI_assert(scene != nullptr && scene->master_collection == nullptr);
|
||||||
|
|
||||||
/* Not an actual datablock, but owned by scene. */
|
/* Not an actual datablock, but owned by scene. */
|
||||||
Collection *master_collection = static_cast<Collection *>(
|
Collection *master_collection = static_cast<Collection *>(BKE_libblock_alloc_in_lib(
|
||||||
BKE_libblock_alloc(nullptr, ID_GR, BKE_SCENE_COLLECTION_NAME, LIB_ID_CREATE_NO_MAIN));
|
nullptr, scene->id.lib, ID_GR, BKE_SCENE_COLLECTION_NAME, LIB_ID_CREATE_NO_MAIN));
|
||||||
master_collection->id.flag |= LIB_EMBEDDED_DATA;
|
master_collection->id.flag |= LIB_EMBEDDED_DATA;
|
||||||
master_collection->owner_id = &scene->id;
|
master_collection->owner_id = &scene->id;
|
||||||
master_collection->flag |= COLLECTION_IS_MASTER;
|
master_collection->flag |= COLLECTION_IS_MASTER;
|
||||||
master_collection->color_tag = COLLECTION_COLOR_NONE;
|
master_collection->color_tag = COLLECTION_COLOR_NONE;
|
||||||
|
|
||||||
|
BLI_assert(scene->id.lib == master_collection->id.lib);
|
||||||
|
|
||||||
return master_collection;
|
return master_collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <cmath> /* floor */
|
#include <cmath> /* floor */
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#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);
|
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<Library *> owner_library,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Curve *curve_dst = (Curve *)id_dst;
|
Curve *curve_dst = (Curve *)id_dst;
|
||||||
const Curve *curve_src = (const Curve *)id_src;
|
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);
|
curve_dst->bevel_profile = BKE_curveprofile_copy(curve_src->bevel_profile);
|
||||||
|
|
||||||
if (curve_src->key && (flag & LIB_ID_COPY_SHAPEKEY)) {
|
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... */
|
/* XXX This is not nice, we need to make BKE_id_copy_ex fully re-entrant... */
|
||||||
curve_dst->key->from = &curve_dst->id;
|
curve_dst->key->from = &curve_dst->id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
@ -61,7 +62,11 @@ static void curves_init_data(ID *id)
|
||||||
new (&curves->geometry) blender::bke::CurvesGeometry();
|
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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int /*flag*/)
|
||||||
{
|
{
|
||||||
Curves *curves_dst = (Curves *)id_dst;
|
Curves *curves_dst = (Curves *)id_dst;
|
||||||
const Curves *curves_src = (const Curves *)id_src;
|
const Curves *curves_src = (const Curves *)id_src;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "CLG_log.h"
|
#include "CLG_log.h"
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@
|
||||||
static CLG_LogRef LOG = {"bke.gpencil"};
|
static CLG_LogRef LOG = {"bke.gpencil"};
|
||||||
|
|
||||||
static void greasepencil_copy_data(Main * /*bmain*/,
|
static void greasepencil_copy_data(Main * /*bmain*/,
|
||||||
|
std::optional<Library *> /*owner_library*/,
|
||||||
ID *id_dst,
|
ID *id_dst,
|
||||||
const ID *id_src,
|
const ID *id_src,
|
||||||
const int /*flag*/)
|
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.) */
|
/* 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 new */
|
||||||
return gpd_dst;
|
return gpd_dst;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "BKE_action.h"
|
#include "BKE_action.h"
|
||||||
#include "BKE_anim_data.hh"
|
#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*/,
|
static void grease_pencil_copy_data(Main * /*bmain*/,
|
||||||
|
std::optional<Library *> /*owner_library*/,
|
||||||
ID *id_dst,
|
ID *id_dst,
|
||||||
const ID *id_src,
|
const ID *id_src,
|
||||||
const int /*flag*/)
|
const int /*flag*/)
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <optional>
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#else
|
#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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Image *image_dst = (Image *)id_dst;
|
Image *image_dst = (Image *)id_dst;
|
||||||
const Image *image_src = (const Image *)id_src;
|
const Image *image_src = (const Image *)id_src;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
@ -54,7 +55,11 @@
|
||||||
|
|
||||||
#include "BLO_read_write.hh"
|
#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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int /*flag*/)
|
||||||
{
|
{
|
||||||
Key *key_dst = (Key *)id_dst;
|
Key *key_dst = (Key *)id_dst;
|
||||||
const Key *key_src = (const Key *)id_src;
|
const Key *key_src = (const Key *)id_src;
|
||||||
|
|
|
@ -56,7 +56,11 @@ static void lattice_init_data(ID *id)
|
||||||
BKE_lattice_resize(lattice, 2, 2, 2, nullptr); /* creates a uniform lattice */
|
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<Library *> owner_library,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Lattice *lattice_dst = (Lattice *)id_dst;
|
Lattice *lattice_dst = (Lattice *)id_dst;
|
||||||
const Lattice *lattice_src = (const Lattice *)id_src;
|
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<BPoint *>(MEM_dupallocN(lattice_src->def));
|
lattice_dst->def = static_cast<BPoint *>(MEM_dupallocN(lattice_src->def));
|
||||||
|
|
||||||
if (lattice_src->key && (flag & LIB_ID_COPY_SHAPEKEY)) {
|
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... */
|
/* XXX This is not nice, we need to make BKE_id_copy_ex fully re-entrant... */
|
||||||
lattice_dst->key->from = &lattice_dst->id;
|
lattice_dst->key->from = &lattice_dst->id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -626,19 +626,28 @@ bool BKE_id_copy_is_allowed(const ID *id)
|
||||||
#undef LIB_ID_TYPES_NOCOPY
|
#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<Library *> owner_library,
|
||||||
|
const ID *id,
|
||||||
|
ID **r_newid,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
ID *newid = (r_newid != nullptr) ? *r_newid : nullptr;
|
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. */
|
/* Make sure destination pointer is all good. */
|
||||||
if ((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0) {
|
if ((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0) {
|
||||||
newid = nullptr;
|
newid = nullptr;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (newid != nullptr) {
|
if (!newid) {
|
||||||
/* Allow some garbage non-initialized memory to go in, and clean it up here. */
|
/* Invalid case, already caught by the assert above. */
|
||||||
const size_t size = BKE_libblock_get_alloc_info(GS(id->name), nullptr);
|
return nullptr;
|
||||||
memset(newid, 0, size);
|
|
||||||
}
|
}
|
||||||
|
/* 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. */
|
/* 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;
|
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) {
|
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 {
|
else {
|
||||||
BLI_assert_msg(0, "IDType Missing IDTypeInfo");
|
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. */
|
/* Update ID refcount, remap pointers to self in new ID. */
|
||||||
IDCopyLibManagementData data{};
|
IDCopyLibManagementData data{};
|
||||||
data.id_src = id;
|
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...
|
/* 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? */
|
* XXX TODO: is this behavior OK, or should we need own flag to control that? */
|
||||||
if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
|
if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
|
||||||
BLI_assert((flag & LIB_ID_COPY_KEEP_LIB) == 0);
|
BLI_assert(!owner_library || newid->lib == *owner_library);
|
||||||
lib_id_copy_ensure_local(bmain, id, newid, 0);
|
if (!ID_IS_LINKED(newid)) {
|
||||||
|
lib_id_copy_ensure_local(bmain, id, newid, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
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) {
|
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;
|
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)
|
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,
|
ID *BKE_id_copy_for_duplicate(Main *bmain,
|
||||||
|
@ -1220,7 +1248,11 @@ void *BKE_libblock_alloc_notest(short type)
|
||||||
return nullptr;
|
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<Library *> 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_ALLOCATE) == 0);
|
||||||
BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || bmain != nullptr);
|
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));
|
BLI_assert(bmain->is_locked_for_linking == false || ELEM(type, ID_WS, ID_GR, ID_NT));
|
||||||
ListBase *lb = which_libbase(bmain, type);
|
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);
|
BKE_main_lock(bmain);
|
||||||
BLI_addtail(lb, id);
|
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;
|
bmain->is_memfile_undo_written = false;
|
||||||
/* alphabetic insertion: is in new_id */
|
/* alphabetic insertion: is in new_id */
|
||||||
BKE_main_unlock(bmain);
|
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,
|
/* 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. */
|
* 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);
|
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! */
|
/* TODO: to be removed from here! */
|
||||||
if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0) {
|
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 {
|
else {
|
||||||
BLI_strncpy(id->name + 2, name, sizeof(id->name) - 2);
|
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).
|
/* 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;
|
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)
|
void BKE_libblock_init_empty(ID *id)
|
||||||
{
|
{
|
||||||
const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_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);
|
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<Library *> owner_library,
|
||||||
|
const short type,
|
||||||
|
const char *name)
|
||||||
|
|
||||||
{
|
{
|
||||||
BLI_assert(bmain != nullptr);
|
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));
|
name = DATA_(BKE_idtype_idcode_to_name(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
ID *id = static_cast<ID *>(BKE_libblock_alloc(bmain, type, name, 0));
|
ID *id = static_cast<ID *>(BKE_libblock_alloc_in_lib(bmain, owner_library, type, name, 0));
|
||||||
BKE_libblock_init_empty(id);
|
BKE_libblock_init_empty(id);
|
||||||
|
|
||||||
return 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)
|
void *BKE_id_new_nomain(const short type, const char *name)
|
||||||
{
|
{
|
||||||
if (name == nullptr) {
|
if (name == nullptr) {
|
||||||
|
@ -1359,7 +1430,11 @@ void *BKE_id_new_nomain(const short type, const char *name)
|
||||||
return id;
|
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<Library *> owner_library,
|
||||||
|
const ID *id,
|
||||||
|
ID **r_newid,
|
||||||
|
const int orig_flag)
|
||||||
{
|
{
|
||||||
ID *new_id = *r_newid;
|
ID *new_id = *r_newid;
|
||||||
int flag = orig_flag;
|
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);
|
STRNCPY(new_id->name, id->name);
|
||||||
new_id->us = 0;
|
new_id->us = 0;
|
||||||
new_id->tag |= LIB_TAG_NOT_ALLOCATED | LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT;
|
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? */
|
/* TODO: Do we want/need to copy more from ID struct itself? */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
new_id = static_cast<ID *>(BKE_libblock_alloc(bmain, GS(id->name), id->name + 2, flag));
|
new_id = static_cast<ID *>(
|
||||||
|
BKE_libblock_alloc_in_lib(bmain, owner_library, GS(id->name), id->name + 2, flag));
|
||||||
}
|
}
|
||||||
BLI_assert(new_id != nullptr);
|
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. */
|
* in their anim data *are* in bmain... super-mega-hooray. */
|
||||||
BLI_assert((copy_data_flag & LIB_ID_COPY_ACTIONS) == 0 ||
|
BLI_assert((copy_data_flag & LIB_ID_COPY_ACTIONS) == 0 ||
|
||||||
(copy_data_flag & LIB_ID_CREATE_NO_MAIN) == 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 {
|
else {
|
||||||
iat->adt = nullptr;
|
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;
|
*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)
|
void *BKE_libblock_copy(Main *bmain, const ID *id)
|
||||||
{
|
{
|
||||||
ID *idn;
|
ID *idn;
|
||||||
|
|
||||||
BKE_libblock_copy_ex(bmain, id, &idn, 0);
|
BKE_libblock_copy_in_lib(bmain, std::nullopt, id, &idn, 0);
|
||||||
|
|
||||||
return idn;
|
return idn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,11 +253,17 @@ static ID *lib_override_library_create_from(Main *bmain,
|
||||||
const int lib_id_copy_flags)
|
const int lib_id_copy_flags)
|
||||||
{
|
{
|
||||||
/* NOTE: do not copy possible override data from the reference here. */
|
/* NOTE: do not copy possible override data from the reference here. */
|
||||||
ID *local_id = BKE_id_copy_ex(bmain,
|
ID *local_id = BKE_id_copy_in_lib(
|
||||||
reference_id,
|
bmain,
|
||||||
nullptr,
|
owner_library,
|
||||||
LIB_ID_COPY_DEFAULT | LIB_ID_COPY_NO_LIB_OVERRIDE |
|
reference_id,
|
||||||
lib_id_copy_flags);
|
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,
|
/* 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
|
* 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);
|
id_sort_by_name(which_libbase(bmain, GS(local_id->name)), local_id, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local_id == nullptr) {
|
/* In `NO_MAIN` case, generic `BKE_id_copy` code won't call this.
|
||||||
return nullptr;
|
* 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.
|
||||||
id_us_min(local_id);
|
*
|
||||||
|
* NOTE: This is likely not the best place to do this. Ideally, #BKE_libblock_management_main_add
|
||||||
/* TODO: Handle this properly in LIB_NO_MAIN case as well (i.e. resync case). Or offload to
|
* e.g. should take care of this. But for the time being, this works and has been battle-proofed.
|
||||||
* generic ID copy code? Would probably be better to have a version of #BKE_id_copy_ex that takes
|
*/
|
||||||
* an extra `target_lib` parameter. */
|
if ((lib_id_copy_flags & LIB_ID_CREATE_NO_MAIN) != 0 && !ID_IS_LINKED(local_id)) {
|
||||||
local_id->lib = owner_library;
|
|
||||||
if ((lib_id_copy_flags & LIB_ID_CREATE_NO_MAIN) != 0 && owner_library == nullptr) {
|
|
||||||
lib_id_copy_ensure_local(bmain, reference_id, local_id, 0);
|
lib_id_copy_ensure_local(bmain, reference_id, local_id, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#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).
|
* \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<Library *> owner_library,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Light *la_dst = (Light *)id_dst;
|
Light *la_dst = (Light *)id_dst;
|
||||||
const Light *la_src = (const Light *)id_src;
|
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);
|
la_dst->nodetree = ntreeLocalize(la_src->nodetree);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BKE_id_copy_ex(
|
BKE_id_copy_in_lib(bmain,
|
||||||
bmain, (ID *)la_src->nodetree, (ID **)&la_dst->nodetree, flag_private_id_data);
|
owner_library,
|
||||||
|
(ID *)la_src->nodetree,
|
||||||
|
(ID **)&la_dst->nodetree,
|
||||||
|
flag_private_id_data);
|
||||||
}
|
}
|
||||||
la_dst->nodetree->owner_id = &la_dst->id;
|
la_dst->nodetree->owner_id = &la_dst->id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#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);
|
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<Library *> owner_library,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
FreestyleLineStyle *linestyle_dst = (FreestyleLineStyle *)id_dst;
|
FreestyleLineStyle *linestyle_dst = (FreestyleLineStyle *)id_dst;
|
||||||
const FreestyleLineStyle *linestyle_src = (const FreestyleLineStyle *)id_src;
|
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) {
|
if (linestyle_src->nodetree) {
|
||||||
BKE_id_copy_ex(bmain,
|
BKE_id_copy_in_lib(bmain,
|
||||||
(ID *)linestyle_src->nodetree,
|
owner_library,
|
||||||
(ID **)&linestyle_dst->nodetree,
|
(ID *)linestyle_src->nodetree,
|
||||||
flag_private_id_data);
|
(ID **)&linestyle_dst->nodetree,
|
||||||
|
flag_private_id_data);
|
||||||
linestyle_dst->nodetree->owner_id = &linestyle_dst->id;
|
linestyle_dst->nodetree->owner_id = &linestyle_dst->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -401,6 +401,7 @@ bool BKE_main_namemap_get_name(Main *bmain, ID *id, char *name, const bool do_un
|
||||||
* truncated name again. */
|
* truncated name again. */
|
||||||
is_name_changed = true;
|
is_name_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return is_name_changed;
|
return is_name_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "CLG_log.h"
|
#include "CLG_log.h"
|
||||||
|
|
||||||
|
@ -49,7 +50,11 @@
|
||||||
|
|
||||||
static CLG_LogRef LOG = {"bke.mask"};
|
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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int /*flag*/)
|
||||||
{
|
{
|
||||||
Mask *mask_dst = (Mask *)id_dst;
|
Mask *mask_dst = (Mask *)id_dst;
|
||||||
const Mask *mask_src = (const Mask *)id_src;
|
const Mask *mask_src = (const Mask *)id_src;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "CLG_log.h"
|
#include "CLG_log.h"
|
||||||
|
|
||||||
|
@ -91,7 +92,11 @@ static void material_init_data(ID *id)
|
||||||
*((short *)id->name) = ID_MA;
|
*((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<Library *> owner_library,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Material *material_dst = (Material *)id_dst;
|
Material *material_dst = (Material *)id_dst;
|
||||||
const Material *material_src = (const Material *)id_src;
|
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);
|
material_dst->nodetree = ntreeLocalize(material_src->nodetree);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BKE_id_copy_ex(bmain,
|
BKE_id_copy_in_lib(bmain,
|
||||||
(ID *)material_src->nodetree,
|
owner_library,
|
||||||
(ID **)&material_dst->nodetree,
|
(ID *)material_src->nodetree,
|
||||||
flag_private_id_data);
|
(ID **)&material_dst->nodetree,
|
||||||
|
flag_private_id_data);
|
||||||
}
|
}
|
||||||
material_dst->nodetree->owner_id = &material_dst->id;
|
material_dst->nodetree->owner_id = &material_dst->id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#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);
|
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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int /*flag*/)
|
||||||
{
|
{
|
||||||
MetaBall *metaball_dst = (MetaBall *)id_dst;
|
MetaBall *metaball_dst = (MetaBall *)id_dst;
|
||||||
const MetaBall *metaball_src = (const MetaBall *)id_src;
|
const MetaBall *metaball_src = (const MetaBall *)id_src;
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
* \ingroup bke
|
* \ingroup bke
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
/* Allow using deprecated functionality for .blend file I/O. */
|
/* 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);
|
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<Library *> owner_library,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Mesh *mesh_dst = reinterpret_cast<Mesh *>(id_dst);
|
Mesh *mesh_dst = reinterpret_cast<Mesh *>(id_dst);
|
||||||
const Mesh *mesh_src = reinterpret_cast<const Mesh *>(id_src);
|
const Mesh *mesh_src = reinterpret_cast<const Mesh *>(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? */
|
/* TODO: Do we want to add flag to prevent this? */
|
||||||
if (mesh_src->key && (flag & LIB_ID_COPY_SHAPEKEY)) {
|
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... */
|
/* XXX This is not nice, we need to make BKE_id_copy_ex fully re-entrant... */
|
||||||
mesh_dst->key->from = &mesh_dst->id;
|
mesh_dst->key->from = &mesh_dst->id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
|
@ -81,7 +82,11 @@ static void movie_clip_init_data(ID *id)
|
||||||
BKE_color_managed_colorspace_settings_init(&movie_clip->colorspace_settings);
|
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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
MovieClip *movie_clip_dst = (MovieClip *)id_dst;
|
MovieClip *movie_clip_dst = (MovieClip *)id_dst;
|
||||||
const MovieClip *movie_clip_src = (const MovieClip *)id_src;
|
const MovieClip *movie_clip_src = (const MovieClip *)id_src;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
/* Allow using deprecated functionality for .blend file I/O. */
|
/* Allow using deprecated functionality for .blend file I/O. */
|
||||||
#define DNA_DEPRECATED_ALLOW
|
#define DNA_DEPRECATED_ALLOW
|
||||||
|
@ -150,7 +151,11 @@ static void ntree_init_data(ID *id)
|
||||||
ntree_set_typeinfo(ntree, nullptr);
|
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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
bNodeTree *ntree_dst = reinterpret_cast<bNodeTree *>(id_dst);
|
bNodeTree *ntree_dst = reinterpret_cast<bNodeTree *>(id_dst);
|
||||||
const bNodeTree *ntree_src = reinterpret_cast<const bNodeTree *>(id_src);
|
const bNodeTree *ntree_src = reinterpret_cast<const bNodeTree *>(id_src);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "CLG_log.h"
|
#include "CLG_log.h"
|
||||||
|
|
||||||
|
@ -188,7 +189,11 @@ static void object_init_data(ID *id)
|
||||||
animviz_settings_init(&ob->avs);
|
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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Object *ob_dst = (Object *)id_dst;
|
Object *ob_dst = (Object *)id_dst;
|
||||||
const Object *ob_src = (const Object *)id_src;
|
const Object *ob_src = (const Object *)id_src;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
@ -100,7 +101,11 @@ static void palette_init_data(ID *id)
|
||||||
id_fake_user_set(&palette->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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int /*flag*/)
|
||||||
{
|
{
|
||||||
Palette *palette_dst = (Palette *)id_dst;
|
Palette *palette_dst = (Palette *)id_dst;
|
||||||
const Palette *palette_src = (const Palette *)id_src;
|
const Palette *palette_src = (const Palette *)id_src;
|
||||||
|
@ -172,6 +177,7 @@ IDTypeInfo IDType_ID_PAL = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void paint_curve_copy_data(Main * /*bmain*/,
|
static void paint_curve_copy_data(Main * /*bmain*/,
|
||||||
|
std::optional<Library *> /*owner_library*/,
|
||||||
ID *id_dst,
|
ID *id_dst,
|
||||||
const ID *id_src,
|
const ID *id_src,
|
||||||
const int /*flag*/)
|
const int /*flag*/)
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
@ -99,6 +100,7 @@ static void particle_settings_init(ID *id)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void particle_settings_copy_data(Main * /*bmain*/,
|
static void particle_settings_copy_data(Main * /*bmain*/,
|
||||||
|
std::optional<Library *> /*owner_library*/,
|
||||||
ID *id_dst,
|
ID *id_dst,
|
||||||
const ID *id_src,
|
const ID *id_src,
|
||||||
const int /*flag*/)
|
const int /*flag*/)
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
* \ingroup bke
|
* \ingroup bke
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "DNA_defaults.h"
|
#include "DNA_defaults.h"
|
||||||
|
@ -68,6 +70,7 @@ static void pointcloud_init_data(ID *id)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointcloud_copy_data(Main * /*bmain*/,
|
static void pointcloud_copy_data(Main * /*bmain*/,
|
||||||
|
std::optional<Library *> /*owner_library*/,
|
||||||
ID *id_dst,
|
ID *id_dst,
|
||||||
const ID *id_src,
|
const ID *id_src,
|
||||||
const int /*flag*/)
|
const int /*flag*/)
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#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<Library *> owner_library,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Scene *scene_dst = (Scene *)id_dst;
|
Scene *scene_dst = (Scene *)id_dst;
|
||||||
const Scene *scene_src = (const Scene *)id_src;
|
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 */
|
/* Master Collection */
|
||||||
if (scene_src->master_collection) {
|
if (scene_src->master_collection) {
|
||||||
BKE_id_copy_ex(bmain,
|
BKE_id_copy_in_lib(bmain,
|
||||||
(ID *)scene_src->master_collection,
|
owner_library,
|
||||||
(ID **)&scene_dst->master_collection,
|
reinterpret_cast<ID *>(scene_src->master_collection),
|
||||||
flag_private_id_data);
|
reinterpret_cast<ID **>(&scene_dst->master_collection),
|
||||||
|
flag_private_id_data);
|
||||||
scene_dst->master_collection->owner_id = &scene_dst->id;
|
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));
|
BKE_keyingsets_copy(&(scene_dst->keyingsets), &(scene_src->keyingsets));
|
||||||
|
|
||||||
if (scene_src->nodetree) {
|
if (scene_src->nodetree) {
|
||||||
BKE_id_copy_ex(
|
BKE_id_copy_in_lib(bmain,
|
||||||
bmain, (ID *)scene_src->nodetree, (ID **)&scene_dst->nodetree, flag_private_id_data);
|
owner_library,
|
||||||
|
(ID *)scene_src->nodetree,
|
||||||
|
(ID **)&scene_dst->nodetree,
|
||||||
|
flag_private_id_data);
|
||||||
BKE_libblock_relink_ex(bmain,
|
BKE_libblock_relink_ex(bmain,
|
||||||
scene_dst->nodetree,
|
scene_dst->nodetree,
|
||||||
(void *)(&scene_src->id),
|
(void *)(&scene_src->id),
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
@ -58,7 +59,11 @@
|
||||||
|
|
||||||
static void sound_free_audio(bSound *sound);
|
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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int /*flag*/)
|
||||||
{
|
{
|
||||||
bSound *sound_dst = (bSound *)id_dst;
|
bSound *sound_dst = (bSound *)id_dst;
|
||||||
const bSound *sound_src = (const bSound *)id_src;
|
const bSound *sound_src = (const bSound *)id_src;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <cstdlib> /* abort */
|
#include <cstdlib> /* abort */
|
||||||
#include <cstring> /* strstr */
|
#include <cstring> /* strstr */
|
||||||
#include <cwctype>
|
#include <cwctype>
|
||||||
|
#include <optional>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -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).
|
* \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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int /*flag*/)
|
||||||
{
|
{
|
||||||
Text *text_dst = (Text *)id_dst;
|
Text *text_dst = (Text *)id_dst;
|
||||||
const Text *text_src = (Text *)id_src;
|
const Text *text_src = (Text *)id_src;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
@ -65,7 +66,11 @@ static void texture_init_data(ID *id)
|
||||||
BKE_imageuser_default(&texture->iuser);
|
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<Library *> owner_library,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
Tex *texture_dst = (Tex *)id_dst;
|
Tex *texture_dst = (Tex *)id_dst;
|
||||||
const Tex *texture_src = (const Tex *)id_src;
|
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);
|
texture_dst->nodetree = ntreeLocalize(texture_src->nodetree);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BKE_id_copy_ex(
|
BKE_id_copy_in_lib(bmain,
|
||||||
bmain, (ID *)texture_src->nodetree, (ID **)&texture_dst->nodetree, flag_private_id_data);
|
owner_library,
|
||||||
|
(ID *)texture_src->nodetree,
|
||||||
|
(ID **)&texture_dst->nodetree,
|
||||||
|
flag_private_id_data);
|
||||||
}
|
}
|
||||||
texture_dst->nodetree->owner_id = &texture_dst->id;
|
texture_dst->nodetree->owner_id = &texture_dst->id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cwctype>
|
#include <cwctype>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "CLG_log.h"
|
#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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID * /*id_src*/,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
VFont *vfont_dst = (VFont *)id_dst;
|
VFont *vfont_dst = (VFont *)id_dst;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
* \ingroup bke
|
* \ingroup bke
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "DNA_defaults.h"
|
#include "DNA_defaults.h"
|
||||||
|
@ -148,7 +150,11 @@ static void volume_init_data(ID *id)
|
||||||
STRNCPY(volume->velocity_grid, "velocity");
|
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<Library *> /*owner_library*/,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int /*flag*/)
|
||||||
{
|
{
|
||||||
Volume *volume_dst = (Volume *)id_dst;
|
Volume *volume_dst = (Volume *)id_dst;
|
||||||
const Volume *volume_src = (const Volume *)id_src;
|
const Volume *volume_src = (const Volume *)id_src;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#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).
|
* \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<Library *> owner_library,
|
||||||
|
ID *id_dst,
|
||||||
|
const ID *id_src,
|
||||||
|
const int flag)
|
||||||
{
|
{
|
||||||
World *wrld_dst = (World *)id_dst;
|
World *wrld_dst = (World *)id_dst;
|
||||||
const World *wrld_src = (const World *)id_src;
|
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);
|
wrld_dst->nodetree = ntreeLocalize(wrld_src->nodetree);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BKE_id_copy_ex(
|
BKE_id_copy_in_lib(bmain,
|
||||||
bmain, (ID *)wrld_src->nodetree, (ID **)&wrld_dst->nodetree, flag_private_id_data);
|
owner_library,
|
||||||
|
(ID *)wrld_src->nodetree,
|
||||||
|
(ID **)&wrld_dst->nodetree,
|
||||||
|
flag_private_id_data);
|
||||||
}
|
}
|
||||||
wrld_dst->nodetree->owner_id = &wrld_dst->id;
|
wrld_dst->nodetree->owner_id = &wrld_dst->id;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue