2022-02-11 09:07:11 +11:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
* Copyright 2014 Blender Foundation. All rights reserved. */
|
2020-02-10 16:54:24 +01:00
|
|
|
#pragma once
|
2014-03-26 16:55:20 +06:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup bke
|
2020-02-10 15:05:54 +01:00
|
|
|
*
|
|
|
|
* API to perform operations over all ID pointers used by a given data-block.
|
|
|
|
*
|
|
|
|
* \note `BKE_lib_` files are for operations over data-blocks themselves, although they might
|
|
|
|
* alter Main as well (when creating/renaming/deleting an ID e.g.).
|
|
|
|
*
|
|
|
|
* \section Function Names
|
|
|
|
*
|
|
|
|
* \warning Descriptions below is ideal goal, current status of naming does not yet fully follow it
|
|
|
|
* (this is WIP).
|
|
|
|
*
|
|
|
|
* - `BKE_lib_query_` should be used for functions in that file.
|
2014-03-26 16:55:20 +06:00
|
|
|
*/
|
|
|
|
|
2022-02-11 08:23:52 +01:00
|
|
|
#include "BLI_sys_types.h"
|
|
|
|
|
2020-03-02 15:07:49 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2014-03-26 16:55:20 +06:00
|
|
|
struct ID;
|
2020-05-07 12:36:35 +02:00
|
|
|
struct IDProperty;
|
ID-Remap - Step one: core work (cleanup and rework of generic ID datablock handling).
This commit changes a lot of how IDs are handled internally, especially the unlinking/freeing
processes. So far, this was very fuzy, to summarize cleanly deleting or replacing a datablock
was pretty much impossible, except for a few special cases.
Also, unlinking was handled by each datatype, in a rather messy and prone-to-errors way (quite
a few ID usages were missed or wrongly handled that way).
One of the main goal of id-remap branch was to cleanup this, and fatorize ID links handling
by using library_query utils to allow generic handling of those, which is now the case
(now, generic ID links handling is only "knwon" from readfile.c and library_query.c).
This commit also adds backends to allow live replacement and deletion of datablocks in Blender
(so-called 'remapping' process, where we replace all usages of a given ID pointer by a new one,
or NULL one in case of unlinking).
This will allow nice new features, like ability to easily reload or relocate libraries, real immediate
deletion of datablocks in blender, replacement of one datablock by another, etc.
Some of those are for next commits.
A word of warning: this commit is highly risky, because it affects potentially a lot in Blender core.
Though it was tested rather deeply, being totally impossible to check all possible ID usage cases,
it's likely there are some remaining issues and bugs in new code... Please report them! ;)
Review task: D2027 (https://developer.blender.org/D2027).
Reviewed by campbellbarton, thanks a bunch.
2016-06-22 17:29:38 +02:00
|
|
|
struct Main;
|
2014-03-26 16:55:20 +06:00
|
|
|
|
|
|
|
/* Tips for the callback for cases it's gonna to modify the pointer. */
|
|
|
|
enum {
|
2017-01-31 09:47:59 +01:00
|
|
|
IDWALK_CB_NOP = 0,
|
|
|
|
IDWALK_CB_NEVER_NULL = (1 << 0),
|
|
|
|
IDWALK_CB_NEVER_SELF = (1 << 1),
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-07-08 19:33:22 +02:00
|
|
|
/**
|
|
|
|
* Indicates whether this is direct (i.e. by local data) or indirect (i.e. by linked data) usage.
|
|
|
|
*/
|
2017-01-31 09:47:59 +01:00
|
|
|
IDWALK_CB_INDIRECT_USAGE = (1 << 2),
|
2022-11-30 11:13:37 +01:00
|
|
|
/**
|
|
|
|
* Indicates that this is a direct weak link usage, i.e. if the user is a local ID, and is using
|
|
|
|
* (pointing to) a linked ID, that usage does not make the linked ID directly linked.
|
|
|
|
*
|
|
|
|
* E.g. usages of linked collections or objects by ViewLayerCollections or Bases in scenes.
|
|
|
|
*
|
|
|
|
* See also #LIB_INDIRECT_WEAK_LINK in DNA_ID.h
|
|
|
|
*/
|
|
|
|
IDWALK_CB_DIRECT_WEAK_LINK = (1 << 3),
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-27 12:07:07 +10:00
|
|
|
/**
|
2020-03-11 12:47:25 +01:00
|
|
|
* That ID is used as mere sub-data by its owner (only case currently: those root nodetrees in
|
|
|
|
* materials etc., and the Scene's master collections).
|
|
|
|
* This means callback shall not *do* anything, only use this as informative data if it needs it.
|
2019-04-27 12:07:07 +10:00
|
|
|
*/
|
2022-11-30 11:13:37 +01:00
|
|
|
IDWALK_CB_EMBEDDED = (1 << 4),
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-11 12:47:25 +01:00
|
|
|
/**
|
|
|
|
* That ID is not really used by its owner, it's just an internal hint/helper.
|
2022-02-03 17:57:40 +01:00
|
|
|
* This marks the 'from' pointers issue, like Key->from.
|
2017-05-05 16:13:01 +02:00
|
|
|
* How to handle that kind of cases totally depends on what caller code is doing... */
|
2022-11-30 11:13:37 +01:00
|
|
|
IDWALK_CB_LOOPBACK = (1 << 5),
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-14 23:16:04 +02:00
|
|
|
/** That ID is used as library override's reference by its owner. */
|
2022-11-30 11:13:37 +01:00
|
|
|
IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE = (1 << 6),
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-05-05 12:31:38 +02:00
|
|
|
/** That ID pointer is not overridable. */
|
2022-11-30 11:13:37 +01:00
|
|
|
IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE = (1 << 7),
|
2021-05-05 12:31:38 +02:00
|
|
|
|
2021-03-12 09:39:23 +01:00
|
|
|
/**
|
|
|
|
* Indicates that this is an internal runtime ID pointer, like e.g. `ID.newid` or `ID.original`.
|
|
|
|
* \note Those should be ignored in most cases, and won't be processed/generated anyway unless
|
|
|
|
* `IDWALK_DO_INTERNAL_RUNTIME_POINTERS` option is enabled.
|
|
|
|
*/
|
2022-11-30 11:13:37 +01:00
|
|
|
IDWALK_CB_INTERNAL = (1 << 8),
|
2021-03-12 09:39:23 +01:00
|
|
|
|
2015-10-08 20:09:30 +11:00
|
|
|
/**
|
2020-04-22 15:58:55 +02:00
|
|
|
* This ID usage is fully refcounted.
|
|
|
|
* Callback is responsible to deal accordingly with #ID.us if needed.
|
2015-10-08 20:09:30 +11:00
|
|
|
*/
|
2022-11-30 11:13:37 +01:00
|
|
|
IDWALK_CB_USER = (1 << 9),
|
2020-04-22 15:58:55 +02:00
|
|
|
/**
|
|
|
|
* This ID usage is not refcounted, but at least one user should be generated by it (to avoid
|
2021-02-05 19:07:03 -08:00
|
|
|
* e.g. losing the used ID on save/reload).
|
2020-04-22 15:58:55 +02:00
|
|
|
* Callback is responsible to deal accordingly with #ID.us if needed.
|
|
|
|
*/
|
2022-11-30 11:13:37 +01:00
|
|
|
IDWALK_CB_USER_ONE = (1 << 10),
|
2014-03-26 16:55:20 +06:00
|
|
|
};
|
|
|
|
|
2016-03-24 12:28:41 +01:00
|
|
|
enum {
|
|
|
|
IDWALK_RET_NOP = 0,
|
2019-07-02 22:17:22 +10:00
|
|
|
/** Completely stop iteration. */
|
|
|
|
IDWALK_RET_STOP_ITER = 1 << 0,
|
|
|
|
/** Stop recursion, that is, do not loop over ID used by current one. */
|
|
|
|
IDWALK_RET_STOP_RECURSION = 1 << 1,
|
2016-03-24 12:28:41 +01:00
|
|
|
};
|
|
|
|
|
2020-02-13 12:56:10 +01:00
|
|
|
typedef struct LibraryIDLinkCallbackData {
|
|
|
|
void *user_data;
|
2020-05-25 15:26:58 +02:00
|
|
|
/** Main database used to call `BKE_library_foreach_ID_link()`. */
|
|
|
|
struct Main *bmain;
|
2020-03-11 12:37:25 +01:00
|
|
|
/**
|
|
|
|
* 'Real' ID, the one that might be in bmain, only differs from self_id when the later is an
|
2020-03-11 17:29:20 +01:00
|
|
|
* embedded one.
|
2020-03-11 12:37:25 +01:00
|
|
|
*/
|
2020-02-13 15:13:19 +01:00
|
|
|
struct ID *id_owner;
|
2020-03-11 12:37:25 +01:00
|
|
|
/**
|
2020-03-11 17:29:20 +01:00
|
|
|
* ID from which the current ID pointer is being processed. It may be an embedded ID like master
|
2020-03-11 12:37:25 +01:00
|
|
|
* collection or root node tree.
|
|
|
|
*/
|
2020-02-13 12:56:10 +01:00
|
|
|
struct ID *id_self;
|
|
|
|
struct ID **id_pointer;
|
|
|
|
int cb_flag;
|
|
|
|
} LibraryIDLinkCallbackData;
|
|
|
|
|
2016-03-24 12:28:41 +01:00
|
|
|
/**
|
|
|
|
* Call a callback for each ID link which the given ID uses.
|
2014-03-26 16:55:20 +06:00
|
|
|
*
|
2016-04-01 10:02:59 +11:00
|
|
|
* \return a set of flags to control further iteration (0 to keep going).
|
2014-03-26 16:55:20 +06:00
|
|
|
*/
|
2020-02-13 12:56:10 +01:00
|
|
|
typedef int (*LibraryIDLinkCallback)(LibraryIDLinkCallbackData *cb_data);
|
2014-03-26 16:55:20 +06:00
|
|
|
|
|
|
|
/* Flags for the foreach function itself. */
|
|
|
|
enum {
|
2017-01-31 09:47:59 +01:00
|
|
|
IDWALK_NOP = 0,
|
2022-03-16 13:14:32 +01:00
|
|
|
/** The callback will never modify the ID pointers it processes. */
|
2014-03-26 16:55:20 +06:00
|
|
|
IDWALK_READONLY = (1 << 0),
|
2022-03-16 13:14:32 +01:00
|
|
|
/** Recurse into 'descendant' IDs.
|
|
|
|
* Each ID is only processed once. Order of ID processing is not guaranteed.
|
|
|
|
*
|
|
|
|
* Also implies IDWALK_READONLY, and excludes IDWALK_DO_INTERNAL_RUNTIME_POINTERS.
|
|
|
|
*
|
|
|
|
* NOTE: When enabled, embedded IDs are processed separately from their owner, as if they were
|
|
|
|
* regular IDs. Owner ID is not available then in the #LibraryForeachIDData callback data.
|
|
|
|
*/
|
|
|
|
IDWALK_RECURSE = (1 << 1),
|
|
|
|
/** Include UI pointers (from WM and screens editors). */
|
|
|
|
IDWALK_INCLUDE_UI = (1 << 2),
|
2020-03-11 17:25:31 +01:00
|
|
|
/** Do not process ID pointers inside embedded IDs. Needed by depsgraph processing e.g. */
|
|
|
|
IDWALK_IGNORE_EMBEDDED_ID = (1 << 3),
|
2017-06-26 18:55:30 +02:00
|
|
|
|
2021-03-12 09:39:23 +01:00
|
|
|
/** Also process internal ID pointers like `ID.newid` or `ID.orig_id`.
|
|
|
|
* WARNING: Dangerous, use with caution. */
|
|
|
|
IDWALK_DO_INTERNAL_RUNTIME_POINTERS = (1 << 9),
|
2014-03-26 16:55:20 +06:00
|
|
|
};
|
|
|
|
|
2020-05-07 12:36:35 +02:00
|
|
|
typedef struct LibraryForeachIDData LibraryForeachIDData;
|
|
|
|
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Check whether current iteration over ID usages should be stopped or not.
|
|
|
|
* \return true if the iteration should be stopped, false otherwise.
|
|
|
|
*/
|
2021-10-26 17:23:38 +02:00
|
|
|
bool BKE_lib_query_foreachid_iter_stop(struct LibraryForeachIDData *data);
|
2021-10-27 12:16:31 +02:00
|
|
|
void BKE_lib_query_foreachid_process(struct LibraryForeachIDData *data,
|
2020-05-07 12:36:35 +02:00
|
|
|
struct ID **id_pp,
|
|
|
|
int cb_flag);
|
2020-05-18 18:51:06 +02:00
|
|
|
int BKE_lib_query_foreachid_process_flags_get(struct LibraryForeachIDData *data);
|
2020-05-21 19:09:48 +02:00
|
|
|
int BKE_lib_query_foreachid_process_callback_flag_override(struct LibraryForeachIDData *data,
|
2022-01-07 11:38:08 +11:00
|
|
|
int cb_flag,
|
|
|
|
bool do_replace);
|
2020-05-07 12:36:35 +02:00
|
|
|
|
|
|
|
#define BKE_LIB_FOREACHID_PROCESS_ID(_data, _id, _cb_flag) \
|
|
|
|
{ \
|
|
|
|
CHECK_TYPE_ANY((_id), ID *, void *); \
|
2021-10-26 17:23:38 +02:00
|
|
|
BKE_lib_query_foreachid_process((_data), (ID **)&(_id), (_cb_flag)); \
|
|
|
|
if (BKE_lib_query_foreachid_iter_stop((_data))) { \
|
2020-05-07 12:36:35 +02:00
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
((void)0)
|
|
|
|
|
2021-10-26 10:40:36 +02:00
|
|
|
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag) \
|
2020-05-07 12:36:35 +02:00
|
|
|
{ \
|
|
|
|
CHECK_TYPE(&((_id_super)->id), ID *); \
|
2021-10-26 17:23:38 +02:00
|
|
|
BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag)); \
|
|
|
|
if (BKE_lib_query_foreachid_iter_stop((_data))) { \
|
2020-05-07 12:36:35 +02:00
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
((void)0)
|
|
|
|
|
2021-10-27 11:30:43 +02:00
|
|
|
#define BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(_data, _func_call) \
|
|
|
|
{ \
|
|
|
|
_func_call; \
|
|
|
|
if (BKE_lib_query_foreachid_iter_stop((_data))) { \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
((void)0)
|
|
|
|
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Process embedded ID pointers (root node-trees, master collections, ...).
|
|
|
|
*
|
|
|
|
* Those require specific care, since they are technically sub-data of their owner, yet in some
|
|
|
|
* cases they still behave as regular IDs.
|
|
|
|
*/
|
2021-10-27 12:16:31 +02:00
|
|
|
void BKE_library_foreach_ID_embedded(struct LibraryForeachIDData *data, struct ID **id_pp);
|
2020-05-07 12:36:35 +02:00
|
|
|
void BKE_lib_query_idpropertiesForeachIDLink_callback(struct IDProperty *id_prop, void *user_data);
|
|
|
|
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Loop over all of the ID's this data-block links to.
|
|
|
|
*/
|
2017-01-30 21:41:44 +01:00
|
|
|
void BKE_library_foreach_ID_link(
|
|
|
|
struct Main *bmain, struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag);
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Re-usable function, use when replacing ID's.
|
|
|
|
*/
|
2022-01-07 11:38:08 +11:00
|
|
|
void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, int cb_flag);
|
2014-03-26 16:55:20 +06:00
|
|
|
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Return the number of times given \a id_user uses/references \a id_used.
|
|
|
|
*
|
|
|
|
* \note This only checks for pointer references of an ID, shallow usages
|
|
|
|
* (like e.g. by RNA paths, as done for FCurves) are not detected at all.
|
|
|
|
*
|
|
|
|
* \param id_user: the ID which is supposed to use (reference) \a id_used.
|
|
|
|
* \param id_used: the ID which is supposed to be used (referenced) by \a id_user.
|
|
|
|
* \return the number of direct usages/references of \a id_used by \a id_user.
|
|
|
|
*/
|
2016-01-06 19:34:42 +01:00
|
|
|
int BKE_library_ID_use_ID(struct ID *id_user, struct ID *id_used);
|
|
|
|
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Say whether given \a id_owner may use (in any way) a data-block of \a id_type_used.
|
|
|
|
*
|
|
|
|
* This is a 'simplified' abstract version of #BKE_library_foreach_ID_link() above,
|
|
|
|
* quite useful to reduce useless iterations in some cases.
|
|
|
|
*/
|
2022-01-07 11:38:08 +11:00
|
|
|
bool BKE_library_id_can_use_idtype(struct ID *id_owner, short id_type_used);
|
2016-07-07 20:51:21 +02:00
|
|
|
|
2022-02-11 08:23:52 +01:00
|
|
|
/**
|
|
|
|
* Given the id_owner return the type of id_types it can use as a filter_id.
|
|
|
|
*/
|
|
|
|
uint64_t BKE_library_id_can_use_filter_id(const struct ID *id_owner);
|
|
|
|
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Check whether given ID is used locally (i.e. by another non-linked ID).
|
|
|
|
*/
|
2016-07-07 19:39:14 +02:00
|
|
|
bool BKE_library_ID_is_locally_used(struct Main *bmain, void *idv);
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Check whether given ID is used indirectly (i.e. by another linked ID).
|
|
|
|
*/
|
"Fix" crash when deleting linked object which has indirect usages.
This is in fact very hairy situation here... Objects are only refcounted by scenes,
any other usage is 'free', which means once all object instanciations are gone Blender
considers it can delete it.
There is a trap here though: indirect usages. Typically, we should never modify linked data
(because it is essencially useless, changes would be ignored and ost on next reload or
even undo/redo). This means indirect usages are not affected by default 'safe' remapping/unlinking.
For unlinking preceeding deletion however, this is not acceptable - we are likely to end with
a zero-user ID (aka deletable one) which is still actually used by other linked data.
Solution choosen here is double:
I) From 'user-space' (i.e. outliner, operators...), we check for cases where deleting datablocks
should not be allowed (indirect data or indirectly used data), and abort (with report) if needed.
II) From 'lower' level (BKE_library_remap and RNA), we also unlink from linked data,
which makes actual deletion possible and safe.
Note that with previous behavior (2.77 one), linked object would be deleted, including from linked data -
but then, once file is saved and reloaded, indirect usage would link back the deleted object,
without any instanciation in scene, which made it somehow virtual and unreachable...
With new behavior, this is no more possible, but on the other hand it means that in situations of dependency cycles
(two linked objects using each other), linked objects become impossible to delete (from user space).
Not sure what's best here, behavior with those corner cases of library linking is very poorly defined... :(
2016-07-01 17:51:08 +02:00
|
|
|
bool BKE_library_ID_is_indirectly_used(struct Main *bmain, void *idv);
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Combine #BKE_library_ID_is_locally_used() and #BKE_library_ID_is_indirectly_used()
|
|
|
|
* in a single call.
|
|
|
|
*/
|
2016-07-07 19:39:14 +02:00
|
|
|
void BKE_library_ID_test_usages(struct Main *bmain,
|
|
|
|
void *idv,
|
|
|
|
bool *is_used_local,
|
|
|
|
bool *is_used_linked);
|
"Fix" crash when deleting linked object which has indirect usages.
This is in fact very hairy situation here... Objects are only refcounted by scenes,
any other usage is 'free', which means once all object instanciations are gone Blender
considers it can delete it.
There is a trap here though: indirect usages. Typically, we should never modify linked data
(because it is essencially useless, changes would be ignored and ost on next reload or
even undo/redo). This means indirect usages are not affected by default 'safe' remapping/unlinking.
For unlinking preceeding deletion however, this is not acceptable - we are likely to end with
a zero-user ID (aka deletable one) which is still actually used by other linked data.
Solution choosen here is double:
I) From 'user-space' (i.e. outliner, operators...), we check for cases where deleting datablocks
should not be allowed (indirect data or indirectly used data), and abort (with report) if needed.
II) From 'lower' level (BKE_library_remap and RNA), we also unlink from linked data,
which makes actual deletion possible and safe.
Note that with previous behavior (2.77 one), linked object would be deleted, including from linked data -
but then, once file is saved and reloaded, indirect usage would link back the deleted object,
without any instanciation in scene, which made it somehow virtual and unreachable...
With new behavior, this is no more possible, but on the other hand it means that in situations of dependency cycles
(two linked objects using each other), linked objects become impossible to delete (from user space).
Not sure what's best here, behavior with those corner cases of library linking is very poorly defined... :(
2016-07-01 17:51:08 +02:00
|
|
|
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Tag all unused IDs (a.k.a 'orphaned').
|
|
|
|
*
|
|
|
|
* By default only tag IDs with `0` user count.
|
|
|
|
* If `do_tag_recursive` is set, it will check dependencies to detect all IDs that are not actually
|
|
|
|
* used in current file, including 'archipelagos` (i.e. set of IDs referencing each other in
|
|
|
|
* loops, but without any 'external' valid usages.
|
|
|
|
*
|
|
|
|
* Valid usages here are defined as ref-counting usages, which are not towards embedded or
|
|
|
|
* loop-back data.
|
|
|
|
*
|
|
|
|
* \param r_num_tagged: If non-NULL, must be a zero-initialized array of #INDEX_ID_MAX integers.
|
|
|
|
* Number of tagged-as-unused IDs is then set for each type, and as total in
|
|
|
|
* #INDEX_ID_NULL item.
|
|
|
|
*/
|
2021-02-25 12:37:31 +01:00
|
|
|
void BKE_lib_query_unused_ids_tag(struct Main *bmain,
|
2022-01-07 11:38:08 +11:00
|
|
|
int tag,
|
|
|
|
bool do_local_ids,
|
|
|
|
bool do_linked_ids,
|
|
|
|
bool do_tag_recursive,
|
2021-02-25 12:37:31 +01:00
|
|
|
int *r_num_tagged);
|
|
|
|
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Detect orphaned linked data blocks (i.e. linked data not used (directly or indirectly)
|
|
|
|
* in any way by any local data), including complex cases like 'linked archipelagoes', i.e.
|
|
|
|
* linked data-blocks that use each other in loops,
|
|
|
|
* which prevents their deletion by 'basic' usage checks.
|
|
|
|
*
|
|
|
|
* \param do_init_tag: if \a true, all linked data are checked, if \a false,
|
|
|
|
* only linked data-blocks already tagged with #LIB_TAG_DOIT are checked.
|
|
|
|
*/
|
2022-01-07 11:38:08 +11:00
|
|
|
void BKE_library_unused_linked_data_set_tag(struct Main *bmain, bool do_init_tag);
|
2021-12-07 17:19:15 +11:00
|
|
|
/**
|
|
|
|
* Untag linked data blocks used by other untagged linked data-blocks.
|
|
|
|
* Used to detect data-blocks that we can forcefully make local
|
|
|
|
* (instead of copying them to later get rid of original):
|
|
|
|
* All data-blocks we want to make local are tagged by caller,
|
|
|
|
* after this function has ran caller knows data-blocks still tagged can directly be made local,
|
|
|
|
* since they are only used by other data-blocks that will also be made fully local.
|
|
|
|
*/
|
2016-11-11 22:29:54 +01:00
|
|
|
void BKE_library_indirectly_used_data_tag_clear(struct Main *bmain);
|
2016-10-19 14:29:43 +02:00
|
|
|
|
2020-03-02 15:07:49 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|