Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_blendfile_link_append.h3
-rw-r--r--source/blender/blenkernel/BKE_lib_principle_properties.h85
-rw-r--r--source/blender/blenkernel/intern/blendfile_link_append.c47
-rw-r--r--source/blender/blenkernel/intern/lib_principle_properties.c106
4 files changed, 235 insertions, 6 deletions
diff --git a/source/blender/blenkernel/BKE_blendfile_link_append.h b/source/blender/blenkernel/BKE_blendfile_link_append.h
index b70f2c2563a..bd00ed51d99 100644
--- a/source/blender/blenkernel/BKE_blendfile_link_append.h
+++ b/source/blender/blenkernel/BKE_blendfile_link_append.h
@@ -197,6 +197,9 @@ void BKE_blendfile_link(struct BlendfileLinkAppendContext *lapp_context,
* - Add all IDs to search for to `lapp_context`.
* - Mark which libraries should be considered for each ID.
* - Call this function.
+ *
+ * NOTE: content of `lapp_context` after execution of that function should not be assumed valid
+ * anymore, and should immediately be freed.
*/
void BKE_blendfile_library_relocate(struct BlendfileLinkAppendContext *lapp_context,
struct ReportList *reports,
diff --git a/source/blender/blenkernel/BKE_lib_principle_properties.h b/source/blender/blenkernel/BKE_lib_principle_properties.h
new file mode 100644
index 00000000000..10d0d33a0c4
--- /dev/null
+++ b/source/blender/blenkernel/BKE_lib_principle_properties.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+#pragma once
+
+/** \file
+ * \ingroup bke
+ *
+ * API to manage principle properties in data-blocks.
+ *
+ * Principle properties are properties that are defined as the ones most user will need to
+ * edit when using this data-block.
+ *
+ * They current main usage in is library overrides.
+ *
+ * \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
+ *
+ * - `BKE_lib_principleprop_` should be used for function affecting a single ID.
+ * - `BKE_lib_principleprop_main_` should be used for function affecting the whole collection
+ * of IDs in a given Main data-base.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ID;
+struct IDPrincipleProperties;
+struct IDPrincipleProperty;
+struct PointerRNA;
+struct PropertyRNA;
+struct ReportList;
+
+/**
+ * Initialize empty list of principle properties for \a id.
+ */
+struct IDPrincipleProperties *BKE_lib_principleprop_init(struct ID *id);
+#if 0
+/**
+ * Shallow or deep copy of a whole princple properties from \a src_id to \a dst_id.
+ */
+void BKE_lib_principleprop_copy(struct ID *dst_id, const struct ID *src_id, bool do_full_copy);
+#endif
+/**
+ * Clear any principle properties data from given \a override.
+ */
+void BKE_lib_principleprop_clear(struct IDPrincipleProperties *principle_props, bool do_id_user);
+/**
+ * Free given \a principle_props.
+ */
+void BKE_lib_principleprop_free(struct IDPrincipleProperties **principle_props, bool do_id_user);
+
+/**
+ * Find principle property from given RNA path, if it exists.
+ */
+struct IDPrincipleProperty *BKE_lib_principleprop_find(
+ struct IDPrincipleProperties *principle_props, const char *rna_path);
+/**
+ * Find principle property from given RNA path, or create it if it does not exist.
+ */
+struct IDPrincipleProperty *BKE_lib_principleprop_get(
+ struct IDPrincipleProperties *principle_props, const char *rna_path, bool *r_created);
+/**
+ * Remove and free given \a principle_prop from given ID \a principle_props.
+ */
+void BKE_lib_principleprop_delete(struct IDPrincipleProperties *principle_props,
+ struct IDPrincipleProperty *principle_prop);
+/**
+ * Get the RNA-property matching the \a principle_prop principle property. Used for UI to query
+ * additional data about the principle property (e.g. UI name).
+ *
+ * \param idpoin: RNA Pointer of the ID.
+ * \param principle_prop: The principle property to find the matching RNA property for.
+ */
+bool BKE_lib_principleprop_rna_property_find(struct PointerRNA *idpoin,
+ const struct IDPrincipleProperty *principle_prop,
+ struct PointerRNA *r_principle_poin,
+ struct PropertyRNA **r_principle_prop);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenkernel/intern/blendfile_link_append.c b/source/blender/blenkernel/intern/blendfile_link_append.c
index da48365a43e..555c4690308 100644
--- a/source/blender/blenkernel/intern/blendfile_link_append.c
+++ b/source/blender/blenkernel/intern/blendfile_link_append.c
@@ -1541,14 +1541,49 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
BKE_main_unlock(bmain);
- for (item_idx = 0, itemlink = lapp_context->items.list; itemlink;
- item_idx++, itemlink = itemlink->next) {
- BlendfileLinkAppendContextItem *item = itemlink->link;
- ID *old_id = item->userdata;
+ /* Delete all no more used old IDs. */
+ /* NOTE: While this looping over until we are sure we deleted everything is very far from
+ * efficient, doing otherwise would require a much more complex handling of indirectly linked IDs
+ * in steps above. Currently, in case of relocation, those are skipped in remapping phase, though
+ * in some cases (essentially internal links between IDs from the same library) remapping should
+ * happen. But getting this to work reliably would be very difficult, so since this is not a
+ * performance-critical code, better to go with the (relatively) simpler, brute-force approach
+ * here in 'removal of old IDs' step. */
+ bool keep_looping = true;
+ while (keep_looping) {
+ keep_looping = false;
+
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+ for (item_idx = 0, itemlink = lapp_context->items.list; itemlink;
+ item_idx++, itemlink = itemlink->next) {
+ BlendfileLinkAppendContextItem *item = itemlink->link;
+ ID *old_id = item->userdata;
+
+ if (old_id == NULL) {
+ continue;
+ }
+
+ if (GS(old_id->name) == ID_KE) {
+ /* Shape Keys are handled as part of their owning obdata (see below). This implies thar
+ * there is no way to know when the old pointer gets invalid, so just clear it immediately.
+ */
+ item->userdata = NULL;
+ continue;
+ }
- if (old_id->us == 0) {
- BKE_id_free(bmain, old_id);
+ if (old_id->us == 0) {
+ old_id->tag |= LIB_TAG_DOIT;
+ item->userdata = NULL;
+ keep_looping = true;
+ Key *old_key = BKE_key_from_id(old_id);
+ if (old_key != NULL) {
+ old_key->id.tag |= LIB_TAG_DOIT;
+ }
+ }
}
+ BKE_id_multi_tagged_delete(bmain);
+ /* Should not be needed, all tagged IDs should have been deleted above, just 'in case'. */
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
}
/* Some datablocks can get reloaded/replaced 'silently' because they are not linkable
diff --git a/source/blender/blenkernel/intern/lib_principle_properties.c b/source/blender/blenkernel/intern/lib_principle_properties.c
new file mode 100644
index 00000000000..204ca9ff9d6
--- /dev/null
+++ b/source/blender/blenkernel/intern/lib_principle_properties.c
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "CLG_log.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_ID.h"
+
+#include "BKE_lib_id.h"
+#include "BKE_lib_principle_properties.h"
+#include "BKE_report.h"
+
+#include "BLO_readfile.h"
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+
+#include "RNA_access.h"
+#include "RNA_prototypes.h"
+#include "RNA_types.h"
+
+static CLG_LogRef LOG = {"bke.idprincipleprops"};
+
+IDPrincipleProperties *BKE_lib_principleprop_init(ID *id)
+{
+ BLI_assert(id->principle_properties == NULL);
+
+ /* Else, generate new empty override. */
+ id->principle_properties = MEM_callocN(sizeof(*id->principle_properties), __func__);
+
+ return id->principle_properties;
+}
+
+void BKE_lib_principleprop_clear(IDPrincipleProperties *principle_props, bool UNUSED(do_id_user))
+{
+ LISTBASE_FOREACH_MUTABLE (IDPrincipleProperty *, pprop, &principle_props->properties) {
+ BLI_assert(pprop->rna_path != NULL);
+ MEM_freeN(pprop->rna_path);
+ MEM_freeN(pprop);
+ }
+ BLI_listbase_clear(&principle_props->properties);
+ principle_props->flag = 0;
+}
+
+void BKE_lib_principleprop_free(IDPrincipleProperties **principle_props, bool do_id_user)
+{
+ BLI_assert(*principle_props != NULL);
+
+ BKE_lib_principleprop_clear(*principle_props, do_id_user);
+ MEM_freeN(*principle_props);
+ *principle_props = NULL;
+}
+
+IDPrincipleProperty *BKE_lib_principleprop_find(IDPrincipleProperties *principle_props,
+ const char *rna_path)
+{
+ return BLI_findstring_ptr(
+ &principle_props->properties, rna_path, offsetof(IDPrincipleProperty, rna_path));
+}
+
+IDPrincipleProperty *BKE_lib_principleprop_get(IDPrincipleProperties *principle_props,
+ const char *rna_path,
+ bool *r_created)
+{
+ IDPrincipleProperty *pprop = BKE_lib_principleprop_find(principle_props, rna_path);
+
+ if (pprop == NULL) {
+ pprop = MEM_callocN(sizeof(*pprop), __func__);
+ pprop->rna_path = BLI_strdup(rna_path);
+ BLI_addtail(&principle_props->properties, pprop);
+
+ if (r_created) {
+ *r_created = true;
+ }
+ }
+ else if (r_created) {
+ *r_created = false;
+ }
+
+ return pprop;
+}
+
+void BKE_lib_principleprop_delete(IDPrincipleProperties *principle_props,
+ IDPrincipleProperty *principle_prop)
+{
+ BLI_remlink(&principle_props->properties, principle_prop);
+}
+
+bool BKE_lib_principleprop_rna_property_find(struct PointerRNA *idpoin,
+ const struct IDPrincipleProperty *principle_prop,
+ struct PointerRNA *r_principle_poin,
+ struct PropertyRNA **r_principle_prop)
+{
+ BLI_assert(RNA_struct_is_ID(idpoin->type));
+ return RNA_path_resolve_property(
+ idpoin, principle_prop->rna_path, r_principle_poin, r_principle_prop);
+}