tornavis/source/blender/blenkernel/BKE_lib_override.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

443 lines
18 KiB
C
Raw Normal View History

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2016 by Blender Foundation.
* All rights reserved.
*/
#pragma once
/** \file
* \ingroup bke
*
2020-02-15 05:58:06 +01:00
* API to manage data-blocks inside of Blender's Main data-base, or as independent runtime-only
* data.
*
* \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_override_library_` should be used for function affecting a single ID.
* - `BKE_lib_override_library_main_` should be used for function affecting the whole collection
* of IDs in a given Main data-base.
*/
#ifdef __cplusplus
extern "C" {
#endif
struct BlendFileReadReport;
2021-07-16 03:48:54 +02:00
struct Collection;
struct ID;
struct IDOverrideLibrary;
struct IDOverrideLibraryProperty;
struct IDOverrideLibraryPropertyOperation;
struct Library;
struct Main;
2020-09-30 03:51:13 +02:00
struct Object;
struct PointerRNA;
struct PropertyRNA;
struct ReportList;
struct Scene;
struct ViewLayer;
/**
* Initialize empty overriding of \a reference_id by \a local_id.
*/
struct IDOverrideLibrary *BKE_lib_override_library_init(struct ID *local_id,
struct ID *reference_id);
/**
* Shallow or deep copy of a whole override from \a src_id to \a dst_id.
*/
void BKE_lib_override_library_copy(struct ID *dst_id, const struct ID *src_id, bool do_full_copy);
/**
* Clear any overriding data from given \a override.
*/
void BKE_lib_override_library_clear(struct IDOverrideLibrary *override, bool do_id_user);
/**
* Free given \a override.
*/
void BKE_lib_override_library_free(struct IDOverrideLibrary **override, bool do_id_user);
/**
* Check if given ID has some override rules that actually indicate the user edited it.
*/
bool BKE_lib_override_library_is_user_edited(struct ID *id);
/**
* Create an overridden local copy of linked reference.
*
2022-01-06 03:54:52 +01:00
* \note This function is very basic, low-level. It does not consider any hierarchical dependency,
* and also prevents any automatic re-sync of this local override.
*/
struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
struct ID *reference_id,
bool do_tagged_remap);
/**
* Create overridden local copies of all tagged data-blocks in given Main.
*
* \note Set `id->newid` of overridden libs with newly created overrides,
* caller is responsible to clean those pointers before/after usage as needed.
*
* \note By default, it will only remap newly created local overriding data-blocks between
* themselves, to avoid 'enforcing' those overrides into all other usages of the linked data in
* main. You can add more local IDs to be remapped to use new overriding ones by setting their
* LIB_TAG_DOIT tag.
*
* \param owner_library: the library in which the overrides should be created. Besides versioning
* and resync code path, this should always be NULL (i.e. the local .blend file).
*
* \param reference_library: the library from which the linked data being overridden come from
* (i.e. the library of the linked reference ID).
*
* \param do_no_main: Create the new override data outside of Main database.
* Used for resyncing of linked overrides.
*
* \return \a true on success, \a false otherwise.
*/
bool BKE_lib_override_library_create_from_tag(struct Main *bmain,
struct Library *owner_library,
const struct ID *id_root_reference,
bool do_no_main);
/**
* Advanced 'smart' function to create fully functional overrides.
*
* \note Currently it only does special things if given \a id_root is an object or collection, more
* specific behaviors may be added in the future for other ID types.
*
* \note It will override all IDs tagged with \a LIB_TAG_DOIT, and it does not clear that tag at
* its beginning, so caller code can add extra data-blocks to be overridden as well.
*
* \param view_layer: the active view layer to search instantiated collections in, can be NULL (in
* which case \a scene's master collection children hierarchy is used instead).
*
* \param owner_library: the library in which the overrides should be created. Besides versioning
* and resync code path, this should always be NULL (i.e. the local .blend file).
*
* \param id_root: The root ID to create an override from.
*
* \param id_reference: Some reference ID used to do some post-processing after overrides have been
* created, may be NULL. Typically, the Empty object instantiating the linked collection we
* override, currently.
*
* \param r_id_root_override: if not NULL, the override generated for the given \a id_root.
*
* \return true if override was successfully created.
*/
bool BKE_lib_override_library_create(struct Main *bmain,
struct Scene *scene,
struct ViewLayer *view_layer,
struct Library *owner_library,
struct ID *id_root,
struct ID *id_reference,
struct ID **r_id_root_override);
/**
* Create a library override template.
*/
bool BKE_lib_override_library_template_create(struct ID *id);
/**
* Convert a given proxy object into a library override.
*
* \note This is a thin wrapper around \a BKE_lib_override_library_create, only extra work is to
* actually convert the proxy itself into an override first.
*
* \param view_layer: the active view layer to search instantiated collections in, can be NULL (in
* which case \a scene's master collection children hierarchy is used instead).
* \return true if override was successfully created.
*/
bool BKE_lib_override_library_proxy_convert(struct Main *bmain,
struct Scene *scene,
struct ViewLayer *view_layer,
struct Object *ob_proxy);
/**
* Convert all proxy objects into library overrides.
*
* \note Only affects local proxies, linked ones are not affected.
*/
void BKE_lib_override_library_main_proxy_convert(struct Main *bmain,
struct BlendFileReadReport *reports);
/**
* Find and set the 'hierarchy root' ID pointer of all library overrides in given `bmain`.
*
* NOTE: Cannot be called from `do_versions_after_linking` as this code needs a single complete
* Main database, not a split-by-libraries one.
*/
void BKE_lib_override_library_main_hierarchy_root_ensure(struct Main *bmain);
/**
* Advanced 'smart' function to resync, re-create fully functional overrides up-to-date with linked
* data, from an existing override hierarchy.
*
* \param view_layer: the active view layer to search instantiated collections in, can be NULL (in
* which case \a scene's master collection children hierarchy is used instead).
* \param id_root: The root liboverride ID to resync from.
* \return true if override was successfully resynced.
*/
bool BKE_lib_override_library_resync(struct Main *bmain,
struct Scene *scene,
struct ViewLayer *view_layer,
struct ID *id_root,
struct Collection *override_resync_residual_storage,
bool do_hierarchy_enforce,
struct BlendFileReadReport *reports);
/**
* Detect and handle required resync of overrides data, when relations between reference linked IDs
* have changed.
*
* This is a fairly complex and costly operation, typically it should be called after
* #BKE_lib_override_library_main_update, which would already detect and tag a lot of cases.
*
* This function will first detect the remaining cases requiring a resync (namely, either when an
* existing linked ID that did not require to be overridden before now would be, or when new IDs
* are added to the hierarchy).
*
* Then it will handle the resync of necessary IDs (through calls to
* #BKE_lib_override_library_resync).
*
* \param view_layer: the active view layer to search instantiated collections in, can be NULL (in
* which case \a scene's master collection children hierarchy is used instead).
*/
void BKE_lib_override_library_main_resync(struct Main *bmain,
struct Scene *scene,
struct ViewLayer *view_layer,
struct BlendFileReadReport *reports);
/**
* Advanced 'smart' function to delete library overrides (including their existing override
* hierarchy) and remap their usages to their linked reference IDs.
*
* \note All IDs tagged with #LIB_TAG_DOIT will be deleted.
*
* \param id_root: The root liboverride ID to delete.
*/
void BKE_lib_override_library_delete(struct Main *bmain, struct ID *id_root);
/**
* Make given ID fully local.
*
* \note Only differs from lower-level #BKE_lib_override_library_free in infamous embedded ID
* cases.
*/
void BKE_lib_override_library_make_local(struct ID *id);
/**
* Find override property from given RNA path, if it exists.
*/
struct IDOverrideLibraryProperty *BKE_lib_override_library_property_find(
struct IDOverrideLibrary *override, const char *rna_path);
/**
* Find override property from given RNA path, or create it if it does not exist.
*/
struct IDOverrideLibraryProperty *BKE_lib_override_library_property_get(
struct IDOverrideLibrary *override, const char *rna_path, bool *r_created);
/**
* Remove and free given \a override_property from given ID \a override.
*/
void BKE_lib_override_library_property_delete(struct IDOverrideLibrary *override,
struct IDOverrideLibraryProperty *override_property);
/**
* Get the RNA-property matching the \a library_prop override property. Used for UI to query
* additional data about the overridden property (e.g. UI name).
*
* \param idpoin: Pointer to the override ID.
* \param library_prop: The library override property to find the matching RNA property for.
*/
bool BKE_lib_override_rna_property_find(struct PointerRNA *idpoin,
const struct IDOverrideLibraryProperty *library_prop,
struct PointerRNA *r_override_poin,
struct PropertyRNA **r_override_prop);
/**
* Find override property operation from given sub-item(s), if it exists.
*/
struct IDOverrideLibraryPropertyOperation *BKE_lib_override_library_property_operation_find(
struct IDOverrideLibraryProperty *override_property,
const char *subitem_refname,
const char *subitem_locname,
int subitem_refindex,
int subitem_locindex,
bool strict,
bool *r_strict);
/**
* Find override property operation from given sub-item(s), or create it if it does not exist.
*/
struct IDOverrideLibraryPropertyOperation *BKE_lib_override_library_property_operation_get(
struct IDOverrideLibraryProperty *override_property,
short operation,
const char *subitem_refname,
const char *subitem_locname,
int subitem_refindex,
int subitem_locindex,
bool strict,
bool *r_strict,
bool *r_created);
/**
* Remove and free given \a override_property_operation from given ID \a override_property.
*/
void BKE_lib_override_library_property_operation_delete(
struct IDOverrideLibraryProperty *override_property,
struct IDOverrideLibraryPropertyOperation *override_property_operation);
/**
* Validate that required data for a given operation are available.
*/
bool BKE_lib_override_library_property_operation_operands_validate(
struct IDOverrideLibraryPropertyOperation *override_property_operation,
struct PointerRNA *ptr_dst,
struct PointerRNA *ptr_src,
struct PointerRNA *ptr_storage,
struct PropertyRNA *prop_dst,
struct PropertyRNA *prop_src,
struct PropertyRNA *prop_storage);
/**
* Check against potential \a bmain.
*/
void BKE_lib_override_library_validate(struct Main *bmain,
struct ID *id,
struct ReportList *reports);
/**
* Check against potential \a bmain.
*/
void BKE_lib_override_library_main_validate(struct Main *bmain, struct ReportList *reports);
/**
* Check that status of local data-block is still valid against current reference one.
*
* It means that all overridable, but not overridden, properties' local values must be equal to
* reference ones. Clears #LIB_TAG_OVERRIDE_OK if they do not.
*
* This is typically used to detect whether some property has been changed in local and a new
* #IDOverrideProperty (of #IDOverridePropertyOperation) has to be added.
*
* \return true if status is OK, false otherwise.
*/
bool BKE_lib_override_library_status_check_local(struct Main *bmain, struct ID *local);
/**
* Check that status of reference data-block is still valid against current local one.
*
* It means that all non-overridden properties' local values must be equal to reference ones.
* Clears LIB_TAG_OVERRIDE_OK if they do not.
*
* This is typically used to detect whether some reference has changed and local
* needs to be updated against it.
*
* \return true if status is OK, false otherwise.
*/
bool BKE_lib_override_library_status_check_reference(struct Main *bmain, struct ID *local);
/**
* Compare local and reference data-blocks and create new override operations as needed,
* or reset to reference values if overriding is not allowed.
*
* \note Defining override operations is only mandatory before saving a `.blend` file on disk
* (not for undo!).
* Knowing that info at runtime is only useful for UI/UX feedback.
*
* \note This is by far the biggest operation (the more time-consuming) of the three so far,
* since it has to go over all properties in depth (all overridable ones at least).
* Generating differential values and applying overrides are much cheaper.
*
* \return true if any library operation was created.
*/
bool BKE_lib_override_library_operations_create(struct Main *bmain, struct ID *local);
/**
* Check all overrides from given \a bmain and create/update overriding operations as needed.
*/
bool BKE_lib_override_library_main_operations_create(struct Main *bmain, bool force_auto);
/**
* Reset all overrides in given \a id_root, while preserving ID relations.
*/
void BKE_lib_override_library_id_reset(struct Main *bmain, struct ID *id_root);
/**
* Reset all overrides in given \a id_root and its dependencies, while preserving ID relations.
*/
void BKE_lib_override_library_id_hierarchy_reset(struct Main *bmain, struct ID *id_root);
/**
* Set or clear given tag in all operations in that override property data.
*/
void BKE_lib_override_library_operations_tag(struct IDOverrideLibraryProperty *override_property,
short tag,
bool do_set);
/**
* Set or clear given tag in all properties and operations in that override data.
*/
void BKE_lib_override_library_properties_tag(struct IDOverrideLibrary *override,
short tag,
bool do_set);
/**
* Set or clear given tag in all properties and operations in that Main's ID override data.
*/
void BKE_lib_override_library_main_tag(struct Main *bmain, short tag, bool do_set);
/**
* Remove all tagged-as-unused properties and operations from that ID override data.
*/
void BKE_lib_override_library_id_unused_cleanup(struct ID *local);
/**
* Remove all tagged-as-unused properties and operations from that Main's ID override data.
*/
void BKE_lib_override_library_main_unused_cleanup(struct Main *bmain);
/**
* Update given override from its reference (re-applying overridden properties).
*/
void BKE_lib_override_library_update(struct Main *bmain, struct ID *local);
/**
* Update all overrides from given \a bmain.
*/
void BKE_lib_override_library_main_update(struct Main *bmain);
/**
* In case an ID is used by another liboverride ID, user may not be allowed to delete it.
*/
bool BKE_lib_override_library_id_is_user_deletable(struct Main *bmain, struct ID *id);
/* Storage (.blend file writing) part. */
/* For now, we just use a temp main list. */
typedef struct Main OverrideLibraryStorage;
/**
* Initialize an override storage.
*/
OverrideLibraryStorage *BKE_lib_override_library_operations_store_init(void);
/**
* Generate suitable 'write' data (this only affects differential override operations).
*
* Note that \a local ID is no more modified by this call,
* all extra data are stored in its temp \a storage_id copy.
*/
struct ID *BKE_lib_override_library_operations_store_start(
struct Main *bmain, OverrideLibraryStorage *override_storage, struct ID *local);
/**
* Restore given ID modified by #BKE_lib_override_library_operations_store_start, to its
* original state.
*/
void BKE_lib_override_library_operations_store_end(OverrideLibraryStorage *override_storage,
struct ID *local);
void BKE_lib_override_library_operations_store_finalize(OverrideLibraryStorage *override_storage);
#ifdef __cplusplus
}
#endif