Blender V4.5
blendfile_link_append.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12
13#include <algorithm>
14#include <cstdlib>
15#include <cstring>
16
17#include "CLG_log.h"
18
19#include "MEM_guardedalloc.h"
20
21#include "DNA_ID.h"
24#include "DNA_key_types.h"
25#include "DNA_object_types.h"
26#include "DNA_scene_types.h"
27#include "DNA_space_types.h"
28#include "DNA_userdef_types.h"
29
30#include "BLI_linklist.h"
31#include "BLI_listbase.h"
32#include "BLI_math_vector.h"
33#include "BLI_set.hh"
34#include "BLI_string.h"
35#include "BLI_string_ref.hh"
36#include "BLI_utildefines.h"
37#include "BLI_vector.hh"
38
39#include "BLT_translation.hh"
40
41#include "RNA_access.hh"
42#include "RNA_prototypes.hh"
43
44#include "BKE_callbacks.hh"
46#include "BKE_idtype.hh"
47#include "BKE_key.hh"
48#include "BKE_layer.hh"
49#include "BKE_lib_id.hh"
50#include "BKE_lib_override.hh"
51#include "BKE_lib_query.hh"
52#include "BKE_lib_remap.hh"
53#include "BKE_library.hh"
54#include "BKE_main.hh"
55#include "BKE_main_namemap.hh"
56#include "BKE_material.hh"
58#include "BKE_object.hh"
59#include "BKE_report.hh"
60#include "BKE_rigidbody.h"
61#include "BKE_scene.hh"
62
64
65#include "BLO_writefile.hh"
66
67static CLG_LogRef LOG = {"bke.blendfile_link_append"};
68
69using namespace blender::bke;
70
71/* -------------------------------------------------------------------- */
74
97
99 BlendfileLinkAppendContext &lapp_context,
102{
103 if (reports != nullptr) {
104 lib_context.bf_reports.reports = reports;
105 }
106
107 const blender::StringRefNull libname = lib_context.path;
108 BlendHandle *blo_handle = lib_context.blo_handle;
109 if (blo_handle == nullptr) {
110 if (libname == BLO_EMBEDDED_STARTUP_BLEND) {
111 blo_handle = BLO_blendhandle_from_memory(lapp_context.blendfile_mem,
112 int(lapp_context.blendfile_memsize),
113 &lib_context.bf_reports);
114 }
115 else {
116 blo_handle = BLO_blendhandle_from_file(libname.c_str(), &lib_context.bf_reports);
117 }
118 lib_context.blo_handle = blo_handle;
119 lib_context.blo_handle_is_owned = true;
120 }
121
122 return blo_handle;
123}
124
126 BlendfileLinkAppendContext & /*lapp_context*/, BlendfileLinkAppendContextLibrary &lib_context)
127{
128 if (lib_context.blo_handle_is_owned && lib_context.blo_handle != nullptr) {
130 lib_context.blo_handle = nullptr;
131 }
132}
133
135{
136 BlendfileLinkAppendContext *lapp_context = MEM_new<BlendfileLinkAppendContext>(__func__);
137 lapp_context->params = params;
139 return lapp_context;
140}
141
143{
144 for (BlendfileLinkAppendContextLibrary &lib_context : lapp_context->libraries) {
145 link_append_context_library_blohandle_release(*lapp_context, lib_context);
146 }
147
148 BLI_assert(lapp_context->library_weak_reference_mapping == nullptr);
149
150 MEM_delete(lapp_context);
151}
152
154 const int flag,
155 const bool do_set)
156{
157 if (do_set) {
158 lapp_context->params->flag |= flag;
159 }
160 else {
161 lapp_context->params->flag &= ~flag;
162 }
163}
164
166 BlendfileLinkAppendContext *lapp_context, const void *blendfile_mem, int blendfile_memsize)
167{
168 BLI_assert_msg(lapp_context->blendfile_mem == nullptr,
169 "Please explicitly clear reference to an embedded blender memfile before "
170 "setting a new one");
171 lapp_context->blendfile_mem = blendfile_mem;
172 lapp_context->blendfile_memsize = size_t(blendfile_memsize);
173}
174
176 BlendfileLinkAppendContext *lapp_context)
177{
178 lapp_context->blendfile_mem = nullptr;
179 lapp_context->blendfile_memsize = 0;
180}
181
183 const char *libname,
184 BlendHandle *blo_handle)
185{
186 BLI_assert(lapp_context->items.empty());
188
189 BlendfileLinkAppendContextLibrary lib_context = {};
190
191 lib_context.path = libname;
192 lib_context.blo_handle = blo_handle;
193 /* Always steal the ownership on the blendfile handle, as it may be freed by readfile code in
194 * case of endianness conversion. */
195 lib_context.blo_handle_is_owned = true;
196
197 lapp_context->libraries.append(lib_context);
198}
199
201 BlendfileLinkAppendContext *lapp_context,
202 const char *idname,
203 const short idcode,
204 void *userdata)
205{
207
208 item.lapp_context = lapp_context;
209
210 item.name = idname;
211 item.idcode = idcode;
212 item.libraries = blender::BitVector<>(lapp_context->libraries.size(), false);
213
214 item.new_id = nullptr;
216 item.userdata = userdata;
217
218 lapp_context->items.push_back(item);
219
220 return &lapp_context->items.back();
221}
222
224 BlendfileLinkAppendContext *lapp_context,
226 const uint64_t id_types_filter,
227 const int library_index)
228{
230
231 int id_num = 0;
232 int id_code_iter = 0;
233 short id_code;
234
235 BlendfileLinkAppendContextLibrary &lib_context = lapp_context->libraries[library_index];
236 BlendHandle *blo_handle = link_append_context_library_blohandle_ensure(
237 *lapp_context, lib_context, reports);
238
239 if (blo_handle == nullptr) {
241 }
242
243 const bool use_assets_only = (lapp_context->params->flag & FILE_ASSETS_ONLY) != 0;
244
245 while ((id_code = BKE_idtype_idcode_iter_step(&id_code_iter))) {
246 if (!BKE_idtype_idcode_is_linkable(id_code) ||
247 (id_types_filter != 0 && (BKE_idtype_idcode_to_idfilter(id_code) & id_types_filter) == 0))
248 {
249 continue;
250 }
251
252 int id_names_num;
254 blo_handle, id_code, use_assets_only, &id_names_num);
255
256 for (LinkNode *link_next = nullptr; id_names_list != nullptr; id_names_list = link_next) {
257 link_next = id_names_list->next;
258
259 char *id_name = static_cast<char *>(id_names_list->link);
261 lapp_context, id_name, id_code, nullptr);
263 lapp_context, item, library_index);
264
266 MEM_freeN(id_names_list);
267 }
268
269 id_num += id_names_num;
270 }
271
272 return id_num;
273}
274
276 BlendfileLinkAppendContext *lapp_context,
278 const int library_index)
279{
281 UNUSED_VARS_NDEBUG(lapp_context);
282 item->libraries[library_index].set();
283}
284
286{
287 return lapp_context->items.empty();
288}
289
295
303
306 ID *new_id)
307{
309 BLI_assert(item->new_id);
311 BLI_assert(new_id->lib == item->new_id->lib);
312 BLI_assert(!lapp_context->new_id_to_item.contains(new_id));
313
314 lapp_context->new_id_to_item.remove(item->new_id);
315 item->new_id = new_id;
316 lapp_context->new_id_to_item.add(new_id, item);
317}
318
326
332
334 BlendfileLinkAppendContext *lapp_context,
336 BlendfileLinkAppendContextItem *item)> callback_function,
338{
339 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
341 (item.tag & LINK_APPEND_TAG_INDIRECT) == 0)
342 {
343 continue;
344 }
346 (item.tag & LINK_APPEND_TAG_INDIRECT) != 0)
347 {
348 continue;
349 }
350
351 if (!callback_function(lapp_context, &item)) {
352 break;
353 }
354 }
355}
356
358{
360
361 PointerRNA ctx_ptr = RNA_pointer_create_discrete(nullptr, &RNA_BlendImportContext, lapp_context);
362 PointerRNA *pointers[1] = {&ctx_ptr};
363 BKE_callback_exec(lapp_context->params->bmain, pointers, 1, BKE_CB_EVT_BLENDIMPORT_PRE);
364}
365
378
380
381/* -------------------------------------------------------------------- */
385
386/* Struct gathering all required data to handle instantiation of loose data-blocks. */
389
390 /* The collection in which to add loose collections/objects. */
392};
393
394static bool object_in_any_scene(Main *bmain, Object *ob)
395{
396 LISTBASE_FOREACH (Scene *, sce, &bmain->scenes) {
397 /* #BKE_scene_has_object checks bases cache of the scenes' view-layer, not actual content of
398 * their collections. */
399 if (BKE_collection_has_object_recursive(sce->master_collection, ob)) {
400 return true;
401 }
402 }
403
404 return false;
405}
406
407static bool object_in_any_collection(Main *bmain, Object *ob)
408{
409 LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
410 if (BKE_collection_has_object(collection, ob)) {
411 return true;
412 }
413 }
414
415 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
416 if (scene->master_collection != nullptr &&
417 BKE_collection_has_object(scene->master_collection, ob))
418 {
419 return true;
420 }
421 }
422
423 return false;
424}
425
427{
428 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
429 if (ob->type == OB_EMPTY && ob->instance_collection == collection) {
430 return true;
431 }
432 }
433 return false;
434}
435
438{
439 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
440 /* In linking case, we always want to handle instantiation. */
441 if (lapp_context->params->flag & FILE_LINK) {
442 return item->new_id;
443 }
444
445 /* We consider that if we either kept it linked, or re-used already local data, instantiation
446 * status of those should not be modified. */
448 return nullptr;
449 }
450
451 ID *id = item->new_id;
452 if (id == nullptr) {
453 return nullptr;
454 }
455
457 return id;
458}
459
461 LooseDataInstantiateContext *instantiate_context)
462{
463
464 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
465 Main *bmain = instantiate_context->lapp_context->params->bmain;
466 Scene *scene = instantiate_context->lapp_context->params->context.scene;
467 ViewLayer *view_layer = instantiate_context->lapp_context->params->context.view_layer;
468
469 /* Find or add collection as needed. When `active_collection` is non-null, it is assumed to be
470 * editable. */
471 if (instantiate_context->active_collection == nullptr) {
472 if (lapp_context->params->flag & FILE_ACTIVE_COLLECTION) {
475 view_layer, lc->collection);
476 }
477 else {
478 if (lapp_context->params->flag & FILE_LINK) {
479 instantiate_context->active_collection = BKE_collection_add(
480 bmain, scene->master_collection, DATA_("Linked Data"));
481 }
482 else {
483 instantiate_context->active_collection = BKE_collection_add(
484 bmain, scene->master_collection, DATA_("Appended Data"));
485 }
486 }
487 }
488}
489
491 Collection *collection,
492 Object *ob,
493 const Scene *scene,
494 ViewLayer *view_layer,
495 const View3D *v3d,
496 const int flag,
497 bool set_active)
498{
499 /* Auto-select and appending. */
500 if ((flag & FILE_AUTOSELECT) && ((flag & FILE_LINK) == 0)) {
501 /* While in general the object should not be manipulated,
502 * when the user requests the object to be selected, ensure it's visible and selectable. */
504 }
505
506 BKE_collection_object_add(bmain, collection, ob);
507 BKE_view_layer_synced_ensure(scene, view_layer);
508 Base *base = BKE_view_layer_base_find(view_layer, ob);
509
510 if (v3d != nullptr) {
511 base->local_view_bits |= v3d->local_view_uid;
512 }
513
514 if (flag & FILE_AUTOSELECT) {
515 /* All objects that use #FILE_AUTOSELECT must be selectable (unless linking data). */
516 BLI_assert((base->flag & BASE_SELECTABLE) || (flag & FILE_LINK));
517 if (base->flag & BASE_SELECTABLE) {
518 base->flag |= BASE_SELECTED;
519 }
520 }
521
522 if (set_active) {
523 view_layer->basact = base;
524 }
525
527}
528
529/* Tag obdata that actually need to be instantiated (those referenced by an object do not, since
530 * the object will be instantiated instead if needed. */
532 LooseDataInstantiateContext *instantiate_context)
533{
534 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
535
536 /* First pass on obdata to enable their instantiation by default, then do a second pass on
537 * objects to clear it for any obdata already in use. */
538 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
539 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
540 if (id == nullptr) {
541 continue;
542 }
543 const ID_Type idcode = GS(id->name);
544 if (!OB_DATA_SUPPORT_ID(idcode)) {
545 continue;
546 }
547 if (idcode == ID_GD_LEGACY) {
548 const bGPdata *legacy_gpd = reinterpret_cast<bGPdata *>(id);
549 if ((legacy_gpd->flag & GP_DATA_ANNOTATIONS) != 0) {
550 continue;
551 }
552 }
553
554 id->tag |= ID_TAG_DOIT;
555 }
556 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
557 ID *id = item.new_id;
558 if (id == nullptr || GS(id->name) != ID_OB) {
559 continue;
560 }
561
562 Object *ob = reinterpret_cast<Object *>(id);
563 Object *new_ob = reinterpret_cast<Object *>(id->newid);
564 if (ob->data != nullptr) {
565 (static_cast<ID *>(ob->data))->tag &= ~ID_TAG_DOIT;
566 }
567 if (new_ob != nullptr && new_ob->data != nullptr) {
568 (static_cast<ID *>(new_ob->data))->tag &= ~ID_TAG_DOIT;
569 }
570 }
571}
572
573/* Test whether some ancestor collection is also tagged for instantiation (return true) or not
574 * (return false). */
576{
577 for (CollectionParent *parent_collection =
578 static_cast<CollectionParent *>(collection->runtime.parents.first);
579 parent_collection != nullptr;
580 parent_collection = parent_collection->next)
581 {
582 if ((parent_collection->collection->id.tag & ID_TAG_DOIT) != 0) {
583 return true;
584 }
585 if (loose_data_instantiate_collection_parents_check_recursive(parent_collection->collection)) {
586 return true;
587 }
588 }
589 return false;
590}
591
593 LooseDataInstantiateContext *instantiate_context)
594{
595 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
596 Main *bmain = lapp_context->params->bmain;
597 Scene *scene = lapp_context->params->context.scene;
598 ViewLayer *view_layer = lapp_context->params->context.view_layer;
599 const View3D *v3d = lapp_context->params->context.v3d;
600
601 const bool do_append = (lapp_context->params->flag & FILE_LINK) == 0;
602 const bool do_instantiate_as_empty = (lapp_context->params->flag &
604
605 /* NOTE: For collections we only view_layer-instantiate duplicated collections that have
606 * non-instantiated objects in them.
607 * NOTE: Also avoid view-layer-instantiating of collections children of other instantiated
608 * collections. This is why we need two passes here. */
609 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
610 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
611 if (id == nullptr || GS(id->name) != ID_GR) {
612 continue;
613 }
614
615 /* Forced instantiation of indirectly appended collections is not wanted. Users can now
616 * easily instantiate collections (and their objects) as needed by themselves. See #67032. */
617 /* We need to check that objects in that collections are already instantiated in a scene.
618 * Otherwise, it's better to add the collection to the scene's active collection, than to
619 * instantiate its objects in active scene's collection directly. See #61141.
620 *
621 * NOTE: We only check object directly into that collection, not recursively into its
622 * children.
623 */
624 Collection *collection = (Collection *)id;
625 /* The collection could be linked/appended together with an Empty object instantiating it,
626 * better not instantiate the collection in the view-layer in that case.
627 *
628 * Can easily happen when copy/pasting such instantiating empty, see #93839. */
629 const bool collection_is_instantiated = collection_instantiated_by_any_object(bmain,
630 collection);
631 /* Always consider adding collections directly selected by the user. */
632 bool do_add_collection = (item.tag & LINK_APPEND_TAG_INDIRECT) == 0 &&
633 !collection_is_instantiated;
634 /* In linking case, do not enforce instantiating non-directly linked collections/objects.
635 * This avoids cluttering the view-layers, user can instantiate themselves specific collections
636 * or objects easily from the Outliner if needed. */
637 if (!do_add_collection && do_append && !collection_is_instantiated) {
638 LISTBASE_FOREACH (CollectionObject *, coll_ob, &collection->gobject) {
639 Object *ob = coll_ob->ob;
640 if (!object_in_any_scene(bmain, ob)) {
641 do_add_collection = true;
642 break;
643 }
644 }
645 }
646 if (do_add_collection) {
647 collection->id.tag |= ID_TAG_DOIT;
648 }
649 }
650
651 /* Second loop to actually instantiate collections tagged as such in first loop, unless some of
652 * their ancestor is also instantiated in case this is not an empty-instantiation. */
653 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
654 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
655 if (id == nullptr || GS(id->name) != ID_GR) {
656 continue;
657 }
658
659 Collection *collection = reinterpret_cast<Collection *>(id);
660 bool do_add_collection = (id->tag & ID_TAG_DOIT) != 0;
661
662 if (!do_add_collection) {
663 continue;
664 }
665 /* When instantiated into view-layer, do not add collections if one of their parents is also
666 * instantiated. */
667 if (!do_instantiate_as_empty &&
669 {
670 continue;
671 }
672 /* When instantiated as empty, do not add indirectly linked (i.e. non-user-selected)
673 * collections. */
674 if (do_instantiate_as_empty && (item.tag & LINK_APPEND_TAG_INDIRECT) != 0) {
675 continue;
676 }
677
679 Collection *active_collection = instantiate_context->active_collection;
680
681 if (do_instantiate_as_empty) {
682 /* BKE_object_add(...) messes with the selection. */
683 Object *ob = BKE_object_add_only_object(bmain, OB_EMPTY, collection->id.name + 2);
684 ob->type = OB_EMPTY;
685 ob->empty_drawsize = U.collection_instance_empty_size;
686
687 const bool set_selected = (lapp_context->params->flag & FILE_AUTOSELECT) != 0;
688 /* TODO: why is it OK to make this active here but not in other situations?
689 * See other callers of #object_base_instance_init */
690 const bool set_active = set_selected;
692 active_collection,
693 ob,
694 scene,
695 view_layer,
696 v3d,
697 lapp_context->params->flag,
698 set_active);
699
700 /* Assign the collection. */
701 ob->instance_collection = collection;
702 id_us_plus(&collection->id);
704 copy_v3_v3(ob->loc, scene->cursor.location);
705 }
706 else {
707 /* Add collection as child of active collection. */
708 BKE_collection_child_add(bmain, active_collection, collection);
709 BKE_view_layer_synced_ensure(scene, view_layer);
710
711 if ((lapp_context->params->flag & FILE_AUTOSELECT) != 0) {
712 /* All objects contained in this collection need to be processed, including the ones
713 * belonging to children collections. */
715 Base *base = BKE_view_layer_base_find(view_layer, ob);
716 if (base) {
717 base->flag |= BASE_SELECTED;
719 }
720 }
722 }
723 }
724 }
725}
726
728{
729 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
730 Main *bmain = lapp_context->params->bmain;
731 const Scene *scene = lapp_context->params->context.scene;
732 ViewLayer *view_layer = lapp_context->params->context.view_layer;
733 const View3D *v3d = lapp_context->params->context.v3d;
734
735 /* Do NOT make base active here! screws up GUI stuff,
736 * if you want it do it at the editor level. */
737 const bool object_set_active = false;
738
739 const bool is_linking = (lapp_context->params->flag & FILE_LINK) != 0;
740
741 /* NOTE: For objects we only view_layer-instantiate duplicated objects that are not yet used
742 * anywhere. */
743 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
744 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
745 if (id == nullptr || GS(id->name) != ID_OB) {
746 continue;
747 }
748
749 /* In linking case, never instantiate stray objects that are not directly linked.
750 *
751 * While this is not ideal (in theory no object should remain un-owned), in case of indirectly
752 * linked objects, the other solution would be to add them to a local collection, which would
753 * make them directly linked. Think for now keeping them indirectly linked is more important.
754 * Ref. #93757.
755 */
756 if (is_linking && (item.tag & LINK_APPEND_TAG_INDIRECT) != 0) {
757 continue;
758 }
759
760 Object *ob = (Object *)id;
761
762 if (object_in_any_collection(bmain, ob)) {
763 continue;
764 }
765
767 Collection *active_collection = instantiate_context->active_collection;
768
769 CLAMP_MIN(ob->id.us, 0);
770 ob->mode = OB_MODE_OBJECT;
771
773 active_collection,
774 ob,
775 scene,
776 view_layer,
777 v3d,
778 lapp_context->params->flag,
779 object_set_active);
780 }
781}
782
784{
785 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
786 Main *bmain = lapp_context->params->bmain;
787 Scene *scene = lapp_context->params->context.scene;
788 ViewLayer *view_layer = lapp_context->params->context.view_layer;
789 const View3D *v3d = lapp_context->params->context.v3d;
790
791 /* Do NOT make base active here! screws up GUI stuff,
792 * if you want it do it at the editor level. */
793 const bool object_set_active = false;
794
795 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
796 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
797 if (id == nullptr) {
798 continue;
799 }
800 const ID_Type idcode = GS(id->name);
801 if (!OB_DATA_SUPPORT_ID(idcode)) {
802 continue;
803 }
804 if ((id->tag & ID_TAG_DOIT) == 0) {
805 continue;
806 }
807
809 Collection *active_collection = instantiate_context->active_collection;
810
811 const int type = BKE_object_obdata_to_type(id);
812 BLI_assert(type != -1);
813 Object *ob = BKE_object_add_only_object(bmain, type, id->name + 2);
814 ob->data = id;
815 id_us_plus(id);
816 BKE_object_materials_sync_length(bmain, ob, static_cast<ID *>(ob->data));
817
819 active_collection,
820 ob,
821 scene,
822 view_layer,
823 v3d,
824 lapp_context->params->flag,
825 object_set_active);
826
827 copy_v3_v3(ob->loc, scene->cursor.location);
828
829 id->tag &= ~ID_TAG_DOIT;
830 }
831}
832
834 LooseDataInstantiateContext *instantiate_context)
835{
836 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
837 Main *bmain = lapp_context->params->bmain;
838
839 /* Add rigid body objects and constraints to current RB world(s). */
840 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
841 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
842 if (id == nullptr || GS(id->name) != ID_OB) {
843 continue;
844 }
845 BKE_rigidbody_ensure_local_object(bmain, reinterpret_cast<Object *>(id));
846 }
847}
848
850{
851 if (instantiate_context->lapp_context->params->context.scene == nullptr) {
852 /* In some cases, like the asset drag&drop e.g., the caller code manages instantiation itself.
853 */
854 return;
855 }
856
857 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
858 const bool do_obdata = (lapp_context->params->flag & BLO_LIBLINK_OBDATA_INSTANCE) != 0;
859
860 /* First pass on obdata to enable their instantiation by default, then do a second pass on
861 * objects to clear it for any obdata already in use. */
862 if (do_obdata) {
863 loose_data_instantiate_obdata_preprocess(instantiate_context);
864 }
865
866 /* First do collections, then objects, then obdata. */
868 loose_data_instantiate_object_process(instantiate_context);
869 if (do_obdata) {
870 loose_data_instantiate_obdata_process(instantiate_context);
871 }
872
874}
875
877 ID *id,
879{
880 lapp_context.new_id_to_item.add(id, &item);
881}
882
883/* Generate a mapping between newly linked IDs and their items, and tag linked IDs used as
884 * liboverride references as already existing. */
886{
887 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
888 ID *id = item.new_id;
889 if (id == nullptr) {
890 continue;
891 }
892
893 new_id_to_item_mapping_add(lapp_context, id, item);
894 }
895}
896
897/* All callbacks processing dependencies of an ID for link/append post-processing share a same
898 * common logic to skip some cases. This is factorized in this helper function.
899 *
900 * Returns false if further processing should be skipped. */
903{
906 {
907 return false;
908 }
909
910 ID *id = *cb_data->id_pointer;
911 if (id == nullptr) {
912 return false;
913 }
914 if (!ID_IS_LINKED(id)) {
916 &LOG,
917 "Local ID '%s' found as part of the linked data hierarchy, this should never happen",
918 id->name);
919 return false;
920 }
921
922 if (!BKE_idtype_idcode_is_linkable(GS(id->name))) {
923 /* While we do not want to add non-linkable ID (shape keys...) to the list of linked items,
924 * unfortunately they can use fully linkable valid IDs too, like actions. Those need to be
925 * processed, so we need to recursively deal with them here. */
926 /* NOTE: Since we are by-passing checks in `BKE_library_foreach_ID_link` by manually calling it
927 * recursively, we need to take care of potential recursion cases ourselves (e.g.anim-data of
928 * shape-key referencing the shape-key itself). */
929 /* NOTE: in case both IDs (owner and 'used' ones) are non-linkable, we can assume we can break
930 * the dependency here. Indeed, either they are both linked in another way (through their own
931 * meshes for shape keys e.g.), or this is an unsupported case (two shape-keys depending on
932 * each-other need to be also 'linked' in by their respective meshes, independent shape-keys
933 * are not allowed). ref #96048. */
934 if (id != cb_data->self_id && BKE_idtype_idcode_is_linkable(GS(cb_data->self_id->name))) {
935 BKE_library_foreach_ID_link(cb_data->bmain, id, callback, cb_data->user_data, IDWALK_NOP);
936 }
937 return false;
938 }
939
940 return true;
941}
942
944
947
949{
952 {
953 return IDWALK_RET_NOP;
954 }
955 ID *id = *cb_data->id_pointer;
957 static_cast<BlendfileLinkAppendContextCallBack *>(cb_data->user_data);
958
959 /* NOTE: In append case, all dependencies are needed in the items list, to cover potential
960 * complex cases (e.g. linked data from another library referencing other IDs from the */
961
962 BlendfileLinkAppendContextItem *item = data->lapp_context->new_id_to_item.lookup_default(
963 id, nullptr);
964 if (item == nullptr) {
966 data->lapp_context, BKE_id_name(*id), GS(id->name), nullptr);
967 item->new_id = id;
968 item->source_library = id->lib;
969 /* Since we did not have an item for that ID yet, we know user did not select it explicitly,
970 * it was rather linked indirectly. This info is important for instantiation of collections.
971 */
974 new_id_to_item_mapping_add(*data->lapp_context, id, *item);
975
976 if ((cb_data->cb_flag & IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE) != 0 ||
977 data->is_liboverride_dependency_only)
978 {
979 /* New item, (currently) detected as only used as a liboverride linked dependency. */
981 }
982 else if (data->is_liboverride_dependency) {
983 /* New item, (currently) detected as used as a liboverride linked dependency, among
984 * others. */
986 }
987 }
988 else {
989 if ((cb_data->cb_flag & IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE) != 0 ||
990 data->is_liboverride_dependency_only)
991 {
992 /* Existing item, here only used as a liboverride reference dependency. If it was not
993 * tagged as such before, it is also used by non-liboverride reference data. */
996 }
997 }
998 else if ((item->tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) != 0) {
999 /* Existing item, here used in a non-liboverride dependency context. If it was
1000 * tagged as a liboverride dependency only, its tag and action need to be updated. */
1003 }
1004 }
1005
1006 return IDWALK_RET_NOP;
1007}
1008
1011{
1014 {
1015 return IDWALK_RET_NOP;
1016 }
1017 ID *id = *cb_data->id_pointer;
1019 static_cast<BlendfileLinkAppendContextCallBack *>(cb_data->user_data);
1020
1021 if (!data->item->reusable_local_id) {
1022 return IDWALK_RET_NOP;
1023 }
1024
1025 BlendfileLinkAppendContextItem *item = data->lapp_context->new_id_to_item.lookup(id);
1026 BLI_assert(item != nullptr);
1027
1028 /* If the currently processed owner ID is not defined as being kept linked, and is using a
1029 * dependency that cannot be reused form local data, then the owner ID should not reuse its
1030 * local data either. */
1031 if (item->action != LINK_APPEND_ACT_KEEP_LINKED && item->reusable_local_id == nullptr) {
1032 BKE_main_library_weak_reference_remove_item(data->lapp_context->library_weak_reference_mapping,
1033 cb_data->owner_id->lib->filepath,
1034 cb_data->owner_id->name,
1035 data->item->reusable_local_id);
1036 data->item->reusable_local_id = nullptr;
1037 }
1038
1039 return IDWALK_RET_NOP;
1040}
1041
1043{
1046 {
1047 return IDWALK_RET_NOP;
1048 }
1049 ID *id = *cb_data->id_pointer;
1051 cb_data->user_data);
1052
1053 BlendfileLinkAppendContextItem *item = data->lapp_context->new_id_to_item.lookup(id);
1054 BLI_assert(item != nullptr);
1056
1057 if (item->action == LINK_APPEND_ACT_MAKE_LOCAL) {
1058 CLOG_INFO(&LOG,
1059 3,
1060 "Appended ID '%s' was to be made directly local, but is also used by data that is "
1061 "kept linked, so duplicating it instead.",
1062 id->name);
1064 }
1065 return IDWALK_RET_NOP;
1066}
1067
1070{
1071 Main *bmain = lapp_context.params->bmain;
1072
1073 const bool do_recursive = (lapp_context.params->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0;
1074 const bool do_reuse_local_id = (lapp_context.params->flag & BLO_LIBLINK_APPEND_LOCAL_ID_REUSE) !=
1075 0;
1076
1077 /* In case of non-recursive appending, gather a set of all 'original' libraries (i.e. libraries
1078 * containing data that was explicitly selected by the user). */
1079 blender::Set<Library *> direct_libraries;
1080 if (!do_recursive) {
1081 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1082 ID *id = item.new_id;
1083 if (id == nullptr) {
1084 continue;
1085 }
1086 direct_libraries.add(id->lib);
1087 }
1088 }
1089
1090 /* Add items for all not yet known IDs (i.e. implicitly linked indirect dependencies) to the
1091 * list.
1092 * NOTE: Since items are appended, this list will grow and these IDs will be processed later,
1093 * leading to a flatten recursive processing of all the linked dependencies.
1094 */
1095 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1096 ID *id = item.new_id;
1097 if (id == nullptr) {
1098 continue;
1099 }
1100 BLI_assert(item.reusable_local_id == nullptr);
1101
1102 /* NOTE: handling of reusable local ID info is needed, even if their usage is not requested
1103 * for that append operation:
1104 * - Newly appended data need to get their weak reference, such that it can be reused later
1105 * if requested.
1106 * - Existing appended data may need to get this 'reuse' weak reference cleared, e.g. if a
1107 * new version of it is made local. */
1110 lapp_context.library_weak_reference_mapping,
1111 id->lib->filepath,
1112 id->name) :
1113 nullptr;
1114
1116 cb_data.lapp_context = &lapp_context;
1117 cb_data.item = &item;
1118 cb_data.reports = reports;
1120 cb_data.is_liboverride_dependency_only = (item.tag &
1124 }
1125
1126 /* At this point, linked IDs that should remain linked can already be defined as such:
1127 * - In case of non-recursive appending, IDs from other libraries.
1128 * - IDs only used as liboverride references. */
1129 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1130 /* These tags should have been set in above loop, here they can be check for validity (they
1131 * are mutually exclusive). */
1132 BLI_assert(
1133 (item.tag &
1136
1137 ID *id = item.new_id;
1138 if (id == nullptr) {
1139 continue;
1140 }
1141 /* IDs exclusively used as liboverride reference should not be made local at all. */
1143 CLOG_INFO(
1144 &LOG,
1145 3,
1146 "Appended ID '%s' is only used as a liboverride linked dependency, keeping it linked.",
1147 id->name);
1149 item.reusable_local_id = nullptr;
1150 }
1151 /* In non-recursive append case, only IDs from the same libraries as the directly appended
1152 * ones are made local. All dependencies from other libraries are kept linked. */
1153 if (!do_recursive && !direct_libraries.contains(id->lib)) {
1154 CLOG_INFO(&LOG,
1155 3,
1156 "Appended ID '%s' belongs to another library and recursive append is disabled, "
1157 "keeping it linked.",
1158 id->name);
1160 item.reusable_local_id = nullptr;
1161 }
1162 }
1163
1164 /* The reusable local IDs can cause severe issues in hierarchies of appended data. If an ID
1165 * user e.g. still has a local reusable ID found, but one of its dependencies does not (i.e.
1166 * either there were some changes in the library data, or the previously appended local
1167 * dependencies was modified in current file and therefore cannot be re-used anymore), then the
1168 * user ID should not be considered as usable either. */
1169 /* TODO: This process is currently fairly raw and inefficient. This is likely not a
1170 * (significant) issue currently anyway. But would be good to refactor this whole code to use
1171 * modern CPP containers (list of items could be an `std::deque` e.g., to be iterable in both
1172 * directions). Being able to loop backward here (i.e. typically process the dependencies
1173 * before the user IDs) could avoid a lot of iterations. */
1174 for (bool keep_looping = do_reuse_local_id; keep_looping;) {
1175 keep_looping = false;
1176 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1177 ID *id = item.new_id;
1178 if (id == nullptr) {
1179 continue;
1180 }
1181 if (!item.reusable_local_id) {
1182 continue;
1183 }
1185 cb_data.lapp_context = &lapp_context;
1186 cb_data.item = &item;
1187 cb_data.reports = reports;
1189 cb_data.is_liboverride_dependency_only = (item.tag &
1192 id,
1194 &cb_data,
1195 IDWALK_NOP);
1196 if (!item.reusable_local_id) {
1197 /* If some reusable ID was cleared, another loop over all items is needed to potentially
1198 * propagate this change higher in the dependency hierarchy. */
1199 keep_looping = true;
1200 }
1201 }
1202 }
1203
1204 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1205 ID *id = item.new_id;
1206 if (id == nullptr) {
1207 continue;
1208 }
1209
1210 if (item.action != LINK_APPEND_ACT_UNSET) {
1211 /* Already set, pass. */
1213 continue;
1214 }
1216
1217 if (do_reuse_local_id && item.reusable_local_id != nullptr) {
1218 CLOG_INFO(&LOG, 3, "Appended ID '%s' as a matching local one, re-using it.", id->name);
1220 }
1221 else if (id->tag & ID_TAG_PRE_EXISTING) {
1222 CLOG_INFO(&LOG, 3, "Appended ID '%s' was already linked, duplicating it.", id->name);
1224 }
1226 CLOG_INFO(
1227 &LOG,
1228 3,
1229 "Appended ID '%s' is also used as a liboverride linked dependency, duplicating it.",
1230 id->name);
1232 }
1233 else if (ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY(id)) {
1234 /* While in theory liboverrides can be directly made local, this causes complex potential
1235 * problems, e.g. because hierarchy roots can become temporarily invalid when the root is
1236 * made local, etc.
1237 *
1238 * So for now, simpler to always duplicate linked liboverrides. */
1239 CLOG_INFO(&LOG, 3, "Appended ID '%s' is a liboverride, duplicating it.", id->name);
1241 }
1242 else {
1243 /* That last action, making linked data directly local, can still be changed to
1244 * #LINK_APPEND_ACT_COPY_LOCAL in the last checks below. This can happen in rare cases with
1245 * complex relationships involving IDs that are kept linked and IDs that are made local,
1246 * both using some same dependencies. */
1247 CLOG_INFO(&LOG, 3, "Appended ID '%s' will be made local.", id->name);
1249 }
1250 }
1251
1252 /* Some linked IDs marked to be made directly local may also be used by other items
1253 * marked to be kept linked. in such case, they need to be copied for the local data, such that
1254 * a linked version of these remains available as dependency for other linked data. */
1255 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1256 ID *id = item.new_id;
1257 if (id == nullptr) {
1258 continue;
1259 }
1260
1261 /* Only IDs kept as linked need to be checked here. */
1262 if (item.action == LINK_APPEND_ACT_KEEP_LINKED) {
1264 cb_data.lapp_context = &lapp_context;
1265 cb_data.item = &item;
1266 cb_data.reports = reports;
1268 cb_data.is_liboverride_dependency_only = (item.tag &
1272 }
1273
1274 /* If we found a matching existing local id but are not re-using it, we need to properly
1275 * clear its weak reference to linked data. */
1276 if (item.reusable_local_id != nullptr &&
1278 {
1279 BLI_assert_msg(!do_reuse_local_id,
1280 "This code should only be reached when the current append operation does not "
1281 "try to reuse local data.");
1283 id->lib->filepath,
1284 id->name,
1285 item.reusable_local_id);
1286 item.reusable_local_id = nullptr;
1287 }
1288 }
1289}
1290
1292{
1295
1296 if (lapp_context->items.empty()) {
1297 /* Nothing to append. */
1298 return;
1299 }
1300
1301 Main *bmain = lapp_context->params->bmain;
1302
1303 BLI_assert((lapp_context->params->flag & FILE_LINK) == 0);
1304
1305 const bool set_fakeuser = (lapp_context->params->flag & BLO_LIBLINK_APPEND_SET_FAKEUSER) != 0;
1306
1307 const int make_local_common_flags =
1309 ((lapp_context->params->flag & BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR) != 0 ?
1311 0) |
1312 /* In recursive case (i.e. everything becomes local), clear liboverrides. Otherwise (i.e.
1313 * only data from immediately linked libraries is made local), preserve liboverrides. */
1314 ((lapp_context->params->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0 ?
1316 0);
1317
1318 new_id_to_item_mapping_create(*lapp_context);
1320
1321 /* Add missing items (the indirectly linked ones), and carefully define which action should be
1322 * applied to each of them. */
1324
1325 /* Effectively perform required operation on every linked ID. */
1326 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1327 ID *id = item.new_id;
1328 if (id == nullptr) {
1329 continue;
1330 }
1331
1332 ID *local_appended_new_id = nullptr;
1333 char lib_filepath[FILE_MAX];
1334 STRNCPY(lib_filepath, id->lib->filepath);
1335 char lib_id_name[MAX_ID_NAME];
1336 STRNCPY(lib_id_name, id->name);
1337
1338 switch (item.action) {
1340 BKE_lib_id_make_local(bmain, id, make_local_common_flags | LIB_ID_MAKELOCAL_FORCE_COPY);
1341 local_appended_new_id = id->newid;
1342 break;
1344 BKE_lib_id_make_local(bmain, id, make_local_common_flags | LIB_ID_MAKELOCAL_FORCE_LOCAL);
1345 BLI_assert(id->newid == nullptr);
1346 local_appended_new_id = id;
1347 break;
1349 /* Nothing to do here. */
1350 break;
1352 BLI_assert(item.reusable_local_id != nullptr);
1353 /* We only need to set `newid` to ID found in previous loop, for proper remapping. */
1354 ID_NEW_SET(id, item.reusable_local_id);
1355 /* This is not a 'new' local appended id, do not set `local_appended_new_id` here. */
1356 break;
1358 CLOG_ERROR(
1359 &LOG, "Unexpected unset append action for '%s' ID, assuming 'keep link'", id->name);
1360 break;
1361 default:
1363 }
1364
1365 if (local_appended_new_id != nullptr) {
1366 if (BKE_idtype_idcode_append_is_reusable(GS(local_appended_new_id->name))) {
1368 lib_filepath,
1369 lib_id_name,
1370 local_appended_new_id);
1371 }
1372
1373 if (set_fakeuser) {
1374 if (!ELEM(GS(local_appended_new_id->name), ID_OB, ID_GR)) {
1375 /* Do not set fake user on objects nor collections (instancing). */
1376 id_fake_user_set(local_appended_new_id);
1377 }
1378 }
1379 }
1380 }
1381
1383 lapp_context->library_weak_reference_mapping = nullptr;
1384
1385 /* Remap IDs as needed. */
1386 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1387 if (item.action == LINK_APPEND_ACT_KEEP_LINKED) {
1388 continue;
1389 }
1390
1391 ID *id = item.new_id;
1392 if (id == nullptr) {
1393 continue;
1394 }
1397 id = id->newid;
1398 if (id == nullptr) {
1399 continue;
1400 }
1401 }
1402
1404
1405 BKE_libblock_relink_to_newid(bmain, id, 0);
1406 }
1407
1408 /* Remove linked IDs when a local existing data has been reused instead. */
1409 BKE_main_id_tag_all(bmain, ID_TAG_DOIT, false);
1410 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1412 continue;
1413 }
1414
1415 ID *id = item.new_id;
1416 if (id == nullptr) {
1417 continue;
1418 }
1420 BLI_assert(id->newid != nullptr);
1421
1422 /* Calling code may want to access newly appended IDs from the link/append context items. */
1423 item.new_id = id->newid;
1424
1425 /* Only the 'reuse local' action should leave unused newly linked data behind. */
1426 if (item.action != LINK_APPEND_ACT_REUSE_LOCAL) {
1427 continue;
1428 }
1429 /* Do NOT delete a linked data that was already linked before this append. */
1430 if (id->tag & ID_TAG_PRE_EXISTING) {
1431 continue;
1432 }
1433 /* Do NOT delete a linked data that is (also) used a liboverride dependency. */
1436 continue;
1437 }
1438
1439 id->tag |= ID_TAG_DOIT;
1440 }
1442
1444
1445 BlendFileReadReport bf_reports{};
1446 bf_reports.reports = reports;
1447 BLO_read_do_version_after_setup(bmain, lapp_context, &bf_reports);
1448
1450}
1451
1453
1456
1458{
1460 {
1461 return IDWALK_RET_NOP;
1462 }
1463 ID *id = *cb_data->id_pointer;
1465 static_cast<BlendfileLinkAppendContextCallBack *>(cb_data->user_data);
1466
1467 if ((id->tag & ID_TAG_PRE_EXISTING) != 0) {
1468 /* About to re-use a linked data that was already there, and that will stay linked. This case
1469 * does not need any further processing of the child hierarchy (existing linked data
1470 * instantiation status should not be modified here). */
1471 return IDWALK_RET_NOP;
1472 }
1473
1474 /* In linking case, all linked IDs are considered for instantiation, including from other
1475 * libraries. So all linked IDs that were not skipped so far need to be added to the items
1476 * list.
1477 */
1478 BlendfileLinkAppendContextItem *item = data->lapp_context->new_id_to_item.lookup_default(
1479 id, nullptr);
1480 /* NOTE: liboverride info (tags like #LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) can be
1481 * ignored/skipped here, since all data are kept linked anyway, they are not useful currently.
1482 */
1483 if (item == nullptr) {
1485 data->lapp_context, BKE_id_name(*id), GS(id->name), nullptr);
1486 item->new_id = id;
1487 item->source_library = id->lib;
1488 /* Since there is no item for that ID yet, the user did not select it explicitly, it was
1489 * rather linked indirectly. This info is important for instantiation of collections. */
1491 /* In linking case we already know what we want to do with these items. */
1493 new_id_to_item_mapping_add(*data->lapp_context, id, *item);
1494 }
1495 return IDWALK_RET_NOP;
1496}
1497
1500{
1501 BLI_assert(ELEM(lapp_context->process_stage,
1505
1506 if (!lapp_context->params->context.scene) {
1507 return;
1508 }
1509 if (lapp_context->params->flag & FILE_LINK) {
1510 new_id_to_item_mapping_create(*lapp_context);
1511 /* Add items for all not yet known IDs (i.e. implicitly linked indirect dependencies) to the
1512 * list.
1513 * NOTE: Since items are appended to the list, this list will grow and these IDs will be
1514 * processed later, leading to a flatten recursive processing of all the linked dependencies.
1515 */
1516 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1517 ID *id = item.new_id;
1518 if (id == nullptr) {
1519 continue;
1520 }
1521 BLI_assert(item.userdata == nullptr);
1522
1524 cb_data.lapp_context = lapp_context;
1525 cb_data.item = &item;
1526 cb_data.reports = reports;
1528 id,
1530 &cb_data,
1531 IDWALK_NOP);
1532 }
1533 }
1534
1535 LooseDataInstantiateContext instantiate_context{};
1536 instantiate_context.lapp_context = lapp_context;
1537 instantiate_context.active_collection = nullptr;
1538 loose_data_instantiate(&instantiate_context);
1539}
1540
1542{
1545
1546 if (lapp_context->items.empty()) {
1547 /* Nothing to be linked. */
1548 return;
1549 }
1550
1551 BLI_assert(!lapp_context->libraries.is_empty());
1552
1553 Main *mainl;
1554 Library *lib;
1555
1556 for (const int lib_idx : lapp_context->libraries.index_range()) {
1557 BlendfileLinkAppendContextLibrary &lib_context = lapp_context->libraries[lib_idx];
1558 const char *libname = lib_context.path.c_str();
1559
1560 if (!link_append_context_library_blohandle_ensure(*lapp_context, lib_context, reports)) {
1561 /* Unlikely since we just browsed it, but possible
1562 * Error reports will have been made by BLO_blendhandle_from_file() */
1563 continue;
1564 }
1565
1566 /* here appending/linking starts */
1567
1568 mainl = BLO_library_link_begin(&lib_context.blo_handle, libname, lapp_context->params);
1569 lib = mainl->curlib;
1570 BLI_assert(lib != nullptr);
1571 /* In case lib was already existing but not found originally, see #99820. */
1572 lib->id.tag &= ~ID_TAG_MISSING;
1573
1574 if (mainl->versionfile < 250) {
1577 "Linking or appending from a very old .blend file format (%d.%d), no animation "
1578 "conversion will "
1579 "be done! You may want to re-save your lib file with current Blender",
1580 mainl->versionfile,
1581 mainl->subversionfile);
1582 }
1583
1584 /* For each lib file, we try to link all items belonging to that lib,
1585 * and tag those successful to not try to load them again with the other libraries. */
1586 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1587 ID *new_id;
1588
1589 if (!item.libraries[lib_idx]) {
1590 continue;
1591 }
1592
1594 mainl, &lib_context.blo_handle, item.idcode, item.name.c_str(), lapp_context->params);
1595
1596 if (new_id) {
1597 /* If the link is successful, clear item's libraries 'todo' flags.
1598 * This avoids trying to link same item with other libraries to come. */
1599 item.libraries.fill(false);
1600 item.new_id = new_id;
1601 item.source_library = new_id->lib;
1602 }
1603 }
1604
1605 BLO_library_link_end(mainl, &lib_context.blo_handle, lapp_context->params, reports);
1606 link_append_context_library_blohandle_release(*lapp_context, lib_context);
1607 }
1608
1609 /* In linking case finalizing process (ensuring all data is valid, instantiating loose
1610 * collections or objects, etc.) can be done here directly.
1611 *
1612 * In append case, the finalizing process is much more complex and requires and additional call
1613 * to #BKE_blendfile_append for caller code. */
1614 if (lapp_context->params->flag & FILE_LINK) {
1615 BlendFileReadReport bf_reports{};
1616 bf_reports.reports = reports;
1617 BLO_read_do_version_after_setup(lapp_context->params->bmain, lapp_context, &bf_reports);
1618
1620 }
1621}
1622
1624 const eBKELibLinkOverride flags,
1625 ReportList * /*reports*/)
1626{
1627 if (lapp_context->items.empty()) {
1628 /* Nothing to override. */
1629 return;
1630 }
1631
1632 Main *bmain = lapp_context->params->bmain;
1633
1634 /* Liboverride only makes sense if data was linked, not appended. */
1635 BLI_assert((lapp_context->params->flag & FILE_LINK) != 0);
1636
1637 const bool set_runtime = (flags & BKE_LIBLINK_OVERRIDE_CREATE_RUNTIME) != 0;
1638 const bool do_use_exisiting_liboverrides = (flags &
1640
1641 blender::Map<ID *, ID *> linked_ids_to_local_liboverrides;
1642 if (do_use_exisiting_liboverrides) {
1643 ID *id_iter;
1644 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
1645 if (ID_IS_LINKED(id_iter)) {
1646 continue;
1647 }
1648 if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_iter)) {
1649 continue;
1650 }
1651 /* Do not consider regular liboverrides if runtime ones are requested, and vice-versa. */
1652 if ((set_runtime && (id_iter->tag & ID_TAG_RUNTIME) == 0) ||
1653 (!set_runtime && (id_iter->tag & ID_TAG_RUNTIME) != 0))
1654 {
1655 continue;
1656 }
1657
1658 /* In case several liboverrides exist of the same data, only consider the first found one, so
1659 * don't use `add_overwrite`. */
1660 linked_ids_to_local_liboverrides.add(id_iter->override_library->reference, id_iter);
1661 }
1663 }
1664
1665 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1666 ID *id = item.new_id;
1667 if (id == nullptr) {
1668 continue;
1669 }
1670 BLI_assert(item.userdata == nullptr);
1671
1672 if (do_use_exisiting_liboverrides) {
1673 item.liboverride_id = linked_ids_to_local_liboverrides.lookup_default(id, nullptr);
1674 }
1675 if (item.liboverride_id == nullptr) {
1677 if (set_runtime) {
1679 if ((id->tag & ID_TAG_PRE_EXISTING) == 0) {
1680 /* If the linked ID is newly linked, in case its override is runtime-only, assume its
1681 * reference to be indirectly linked.
1682 *
1683 * This is more of an heuristic for 'as best as possible' user feedback in the UI
1684 * (Outliner), which is expected to be valid in almost all practical use-cases. Direct or
1685 * indirect linked status is properly checked before saving .blend file. */
1686 id->tag &= ~ID_TAG_EXTERN;
1687 id->tag |= ID_TAG_INDIRECT;
1688 }
1689 }
1690 }
1691 }
1692
1693 BKE_main_namemap_clear(*bmain);
1694}
1695
1697
1700
1702 ID *old_id,
1703 ID *new_id,
1705 const bool do_reload,
1706 const int remap_flags)
1707{
1708 BLI_assert(old_id);
1709 if (do_reload) {
1710 /* Since we asked for placeholders in case of missing IDs,
1711 * we expect to always get a valid one. */
1712 BLI_assert(new_id);
1713 }
1714 if (new_id) {
1715 CLOG_INFO(&LOG,
1716 4,
1717 "Before remap of %s, old_id users: %d, new_id users: %d",
1718 old_id->name,
1719 old_id->us,
1720 new_id->us);
1721 BKE_libblock_remap_locked(bmain, old_id, new_id, remap_flags);
1722
1723 if (old_id->flag & ID_FLAG_FAKEUSER) {
1724 id_fake_user_clear(old_id);
1725 id_fake_user_set(new_id);
1726 }
1727
1728 CLOG_INFO(&LOG,
1729 4,
1730 "After remap of %s, old_id users: %d, new_id users: %d",
1731 old_id->name,
1732 old_id->us,
1733 new_id->us);
1734
1735 /* In some cases, new_id might become direct link, remove parent of library in this case. */
1736 if (new_id->lib->runtime->parent && (new_id->tag & ID_TAG_INDIRECT) == 0) {
1737 if (do_reload) {
1738 BLI_assert_unreachable(); /* Should not happen in 'pure' reload case... */
1739 }
1740 new_id->lib->runtime->parent = nullptr;
1741 }
1742 }
1743
1744 if (old_id->us > 0 && new_id && old_id->lib == new_id->lib) {
1745 /* Note that this *should* not happen - but better be safe than sorry in this area,
1746 * at least until we are 100% sure this cannot ever happen.
1747 * Also, we can safely assume names were unique so far,
1748 * so just replacing '.' by '~' should work,
1749 * but this does not totally rules out the possibility of name collision. */
1750 size_t len = strlen(old_id->name);
1751 size_t dot_pos;
1752 bool has_num = false;
1753
1754 for (dot_pos = len; dot_pos--;) {
1755 char c = old_id->name[dot_pos];
1756 if (c == '.') {
1757 break;
1758 }
1759 if (c < '0' || c > '9') {
1760 has_num = false;
1761 break;
1762 }
1763 has_num = true;
1764 }
1765
1766 if (has_num) {
1767 old_id->name[dot_pos] = '~';
1768 }
1769 else {
1770 len = std::min<size_t>(len, MAX_ID_NAME - 7);
1771 BLI_strncpy(&old_id->name[len], "~000", 7);
1772 }
1773
1774 id_sort_by_name(which_libbase(bmain, GS(old_id->name)), old_id, nullptr);
1775
1777 reports,
1779 "Lib Reload: Replacing all references to old data-block '%s' by reloaded one failed, "
1780 "old one (%d remaining users) had to be kept and was renamed to '%s'",
1781 new_id->name,
1782 old_id->us,
1783 old_id->name);
1784 }
1785}
1786
1788 ID *old_id,
1789 ID *new_id,
1791 const bool do_reload,
1792 const int remap_flags)
1793{
1794 blendfile_library_relocate_id_remap_do(bmain, old_id, new_id, reports, do_reload, remap_flags);
1795 if (new_id == nullptr) {
1796 return;
1797 }
1798 /* Usual special code for ShapeKeys snowflakes... */
1799 Key **old_key_p = BKE_key_from_id_p(old_id);
1800 if (old_key_p == nullptr) {
1801 return;
1802 }
1803 Key *old_key = *old_key_p;
1804 Key *new_key = BKE_key_from_id(new_id);
1805 if (old_key != nullptr) {
1806 *old_key_p = nullptr;
1807 id_us_min(&old_key->id);
1809 bmain, &old_key->id, &new_key->id, reports, do_reload, remap_flags);
1810 *old_key_p = old_key;
1811 id_us_plus_no_lib(&old_key->id);
1812 }
1813}
1814
1817{
1818 Main &bmain = *lapp_context.params->bmain;
1819
1820 blender::Set<ID *> ids_to_delete = {};
1821 ID *id_iter;
1822
1823 /* Delete all no more used old IDs. */
1824 /* NOTE: While this looping over until we are sure we deleted everything is very far from
1825 * efficient, doing otherwise would require a much more complex handling of indirectly linked IDs
1826 * in steps above. Currently, in case of relocation, those are skipped in remapping phase, though
1827 * in some cases (essentially internal links between IDs from the same library) remapping should
1828 * happen. But getting this to work reliably would be very difficult, so since this is not a
1829 * performance-critical code, better to go with the (relatively) simpler, brute-force approach
1830 * here in 'removal of old IDs' step. */
1831 bool keep_looping = true;
1832 while (keep_looping) {
1833 keep_looping = false;
1834
1835 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1836 ID *old_id = static_cast<ID *>(item.userdata);
1837
1838 if (old_id == nullptr) {
1839 continue;
1840 }
1841
1842 if (GS(old_id->name) == ID_KE) {
1843 /* Shape Keys are handled as part of their owning obdata (see below). This implies that
1844 * there is no way to know when the old pointer gets invalid, so just clear it immediately.
1845 */
1846 item.userdata = nullptr;
1847 continue;
1848 }
1849
1850 /* In case the active scene was reloaded, the context pointers in
1851 * `lapp_context->params->context` need to be updated before the old Scene ID is freed. */
1852 if (old_id == &lapp_context.params->context.scene->id) {
1853 BLI_assert(GS(old_id->name) == ID_SCE);
1854 Scene *new_scene = reinterpret_cast<Scene *>(item.new_id);
1855 BLI_assert(new_scene != nullptr);
1856 lapp_context.params->context.scene = new_scene;
1857 if (lapp_context.params->context.view_layer != nullptr) {
1858 ViewLayer *new_view_layer = BKE_view_layer_find(
1859 new_scene, lapp_context.params->context.view_layer->name);
1860 lapp_context.params->context.view_layer = static_cast<ViewLayer *>(
1861 (new_view_layer != nullptr) ? new_view_layer : new_scene->view_layers.first);
1862 }
1863 /* lapp_context->params->context.v3d should never be made invalid by newly linked data
1864 * here, as it is UI data, ultimately owned by a #bScreen ID, which is not linkable. */
1865 }
1866
1867 if (old_id->us == 0) {
1868 ids_to_delete.add(old_id);
1869 item.userdata = nullptr;
1870 keep_looping = true;
1871 Key *old_key = BKE_key_from_id(old_id);
1872 if (old_key != nullptr) {
1873 ids_to_delete.add(&old_key->id);
1874 }
1875 }
1876 }
1877 BKE_id_multi_delete(&bmain, ids_to_delete);
1878 ids_to_delete.clear();
1879 }
1880
1881 /* Some datablocks can get reloaded/replaced 'silently' because they are not linkable
1882 * (shape keys e.g.), so we need another loop here to clear old ones if possible. */
1883 FOREACH_MAIN_ID_BEGIN (&bmain, id_iter) {
1884 /* XXX That check may be a bit to generic/permissive? */
1885 if (id_iter->lib && (id_iter->flag & ID_TAG_PRE_EXISTING) && id_iter->us == 0) {
1886 ids_to_delete.add(id_iter);
1887 }
1888 }
1890 BKE_id_multi_delete(&bmain, ids_to_delete);
1891 ids_to_delete.clear();
1892
1893 /* Get rid of no more used libraries... */
1894 ListBase *libraries = which_libbase(&bmain, ID_LI);
1895 LISTBASE_FOREACH (ID *, id_iter, libraries) {
1896 ids_to_delete.add(id_iter);
1897 }
1898 FOREACH_MAIN_ID_BEGIN (&bmain, id_iter) {
1899 if (id_iter->lib) {
1900 ids_to_delete.remove(&id_iter->lib->id);
1901 }
1902 }
1904 BKE_id_multi_delete(&bmain, ids_to_delete);
1905}
1906
1909 BlendfileLinkAppendContext &lapp_context,
1910 const blender::Map<Library *, Library *> &new_to_old_libraries_map,
1912{
1913 Main &bmain = *lapp_context.params->bmain;
1914
1915 ID *id_iter;
1916 FOREACH_MAIN_ID_BEGIN (&bmain, id_iter) {
1917 if (ID_IS_LINKED(id_iter) || !ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) ||
1918 (id_iter->tag & ID_TAG_PRE_EXISTING) == 0)
1919 {
1920 continue;
1921 }
1922 if ((id_iter->override_library->reference->tag & ID_TAG_MISSING) == 0) {
1923 id_iter->tag &= ~ID_TAG_MISSING;
1924 }
1925 if ((id_iter->override_library->reference->tag & ID_TAG_PRE_EXISTING) == 0) {
1926 BKE_lib_override_library_update(&bmain, id_iter);
1927 }
1928 }
1930
1932
1933 /* Resync overrides if needed. */
1934 if (liboverride::is_auto_resync_enabled() && lapp_context.params->context.scene != nullptr) {
1935 BlendFileReadReport report{};
1936 report.reports = reports;
1938 &new_to_old_libraries_map,
1939 lapp_context.params->context.scene,
1940 lapp_context.params->context.view_layer,
1941 &report);
1942 /* We need to rebuild some of the deleted override rules (for UI feedback purpose). */
1944 }
1945}
1946
1950 const bool do_reload)
1951{
1952 Main *bmain = lapp_context->params->bmain;
1953
1954 /* All override rules need to be up to date, since there will be no do_version here, otherwise
1955 * older, now-invalid rules might be applied and likely fail, or some changes might be missing,
1956 * etc. See #93353. */
1958
1959 /* Remove all IDs to be reloaded from Main. */
1960 MainListsArray lbarray = BKE_main_lists_get(*bmain);
1961 int lba_idx = lbarray.size();
1962 while (lba_idx--) {
1963 ID *id = static_cast<ID *>(lbarray[lba_idx]->first);
1964 const short idcode = id ? GS(id->name) : 0;
1965
1966 if (!id || !BKE_idtype_idcode_is_linkable(idcode)) {
1967 /* No need to reload non-linkable data-types,
1968 * those will get relinked with their 'users ID'. */
1969 continue;
1970 }
1971
1972 for (; id; id = static_cast<ID *>(id->next)) {
1973 if (id->lib == library) {
1975
1976 /* We remove it from current Main, and add it to items to link... */
1977 /* Note that non-linkable IDs (like e.g. shape-keys) are also explicitly linked here... */
1978 BLI_remlink(lbarray[lba_idx], id);
1979 /* Usual special code for ShapeKeys snowflakes... */
1980 Key *old_key = BKE_key_from_id(id);
1981 if (old_key != nullptr) {
1982 BLI_remlink(which_libbase(bmain, GS(old_key->id.name)), &old_key->id);
1983 }
1984
1986 lapp_context, BKE_id_name(*id), idcode, id);
1987 item->libraries.fill(true);
1988
1989 CLOG_INFO(&LOG, 4, "Datablock to seek for: %s", id->name);
1990 }
1991 }
1992 }
1993
1994 if (lapp_context->items.empty()) {
1995 /* Early out in case there is nothing to do. */
1996 return;
1997 }
1998
2000
2001 /* Since some IDs have been removed from Main, trying to rebuild collections hierarchy should not
2002 * happen. It has to be done manually below once removed IDs have been added back to Main. Also
2003 * see #136432. */
2005
2007
2008 /* We do not want any instantiation here! */
2009 BKE_blendfile_link(lapp_context, reports);
2010
2011 BKE_main_lock(bmain);
2012
2013 /* We add back old id to bmain.
2014 * We need to do this in a first, separated loop, otherwise some of those may not be handled by
2015 * ID remapping, which means they would still reference old data to be deleted... */
2016 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
2017 ID *old_id = static_cast<ID *>(item.userdata);
2018
2019 BLI_assert(old_id);
2020 BLI_addtail(which_libbase(bmain, GS(old_id->name)), old_id);
2021
2022 /* Usual special code for ShapeKeys snowflakes... */
2023 Key *old_key = BKE_key_from_id(old_id);
2024 if (old_key != nullptr) {
2025 BLI_addtail(which_libbase(bmain, GS(old_key->id.name)), &old_key->id);
2026 }
2027 }
2028
2029 /* FIXME Temporary 'fix' to a problem in how temp ID are copied in
2030 * `BKE_lib_override_library_main_update`, see #103062.
2031 * Proper fix involves first addressing #90610. */
2033
2034 /* Since our (old) reloaded IDs were removed from main, the user count done for them in linking
2035 * code is wrong, we need to redo it here after adding them back to main. */
2036 BKE_main_id_refcount_recompute(bmain, false);
2037
2038 /* Mapping from old to new libraries, needed to allow liboverride resync to map properly old and
2039 * new data. */
2040 blender::Map<Library *, Library *> new_to_old_libraries_map;
2041
2043 /* Note that in reload case, we also want to replace indirect usages. */
2044 const int remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE |
2045 (do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
2046 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
2047 ID *old_id = static_cast<ID *>(item.userdata);
2048 ID *new_id = item.new_id;
2049 if (new_id) {
2050 new_to_old_libraries_map.add(new_id->lib, old_id->lib);
2051 }
2052 blendfile_library_relocate_id_remap(bmain, old_id, new_id, reports, do_reload, remap_flags);
2053 }
2056
2057 BKE_main_unlock(bmain);
2058
2059 /* Delete all no more used old IDs. */
2061
2062 /* Update and resync liboverrides of reloaded linked data-blocks. */
2063 blendfile_relocate_postprocess_liboverrides(*lapp_context, new_to_old_libraries_map, reports);
2064
2066}
2067
2069{
2070 if (lapp_context.items.empty()) {
2071 /* Nothing to relocate. */
2072 return;
2073 }
2074 /* Only support relocating one ID at a time currently. */
2075 BLI_assert(lapp_context.items.size() == 1);
2076
2077 Main *bmain = lapp_context.params->bmain;
2078
2079 /* Relocate only works on linked data currently. */
2080 BLI_assert((lapp_context.params->flag & FILE_LINK) != 0);
2081
2082 /* Tag everything, its generally useful to know what is new.
2083 *
2084 * Take extra care `BKE_main_id_flag_all(bmain, ID_TAG_PRE_EXISTING, false)` is called after! */
2086
2087 /* XXX We'd need re-entrant locking on Main for this to work... */
2088 // BKE_main_lock(bmain);
2089
2090 BKE_blendfile_link(&lapp_context, reports);
2091
2092 // BKE_main_unlock(bmain);
2093
2094 /* Finalize relocation (remap ID usages, rebuild LibOverrides if needed, etc.). */
2095
2096 /* Mapping from old to new libraries, needed to allow liboverride resync to map properly old and
2097 * new data. */
2098 blender::Map<Library *, Library *> new_to_old_libraries_map{};
2099
2100 /* The first item should be the root of the relocation, and the only one containing a non-null
2101 * `userdata`. */
2102 BlendfileLinkAppendContextItem &root_item = lapp_context.items.front();
2103 BLI_assert(root_item.userdata);
2104 ID *old_id = static_cast<ID *>(root_item.userdata);
2105 ID *new_id = root_item.new_id;
2106 new_to_old_libraries_map.add(new_id->lib, old_id->lib);
2107 BLI_assert(GS(old_id->name) == GS(new_id->name));
2108#ifndef NDEBUG
2109 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
2110 BLI_assert(&item == &root_item || item.userdata == nullptr);
2111 }
2112#endif
2113
2114 BKE_main_lock(bmain);
2116
2117 /* Do not affect indirect usages. */
2119 blendfile_library_relocate_id_remap(bmain, old_id, new_id, reports, false, remap_flags);
2120
2123 BKE_main_unlock(bmain);
2124
2125 /* Delete all no more used old IDs. */
2127
2128 /* Update and resync liboverrides of reloaded linked data-blocks. */
2129 blendfile_relocate_postprocess_liboverrides(lapp_context, new_to_old_libraries_map, reports);
2130
2132
2133 /* Important we unset, otherwise these object won't
2134 * link into other scenes from this blend file. */
2136}
2137
void BKE_callback_exec(Main *bmain, PointerRNA **pointers, int num_pointers, eCbEvent evt)
Definition callbacks.cc:27
@ BKE_CB_EVT_BLENDIMPORT_POST
@ BKE_CB_EVT_BLENDIMPORT_PRE
bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
#define FOREACH_COLLECTION_OBJECT_RECURSIVE_END
Collection * BKE_collection_add(Main *bmain, Collection *collection_parent, const char *name_custom)
bool BKE_collection_has_object(Collection *collection, const Object *ob)
bool BKE_collection_child_add(Main *bmain, Collection *parent, Collection *child)
Collection * BKE_collection_parent_editable_find_recursive(const ViewLayer *view_layer, Collection *collection)
#define FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(_collection, _object)
void BKE_main_collections_parent_relations_rebuild(Main *bmain)
bool BKE_collection_object_add(Main *bmain, Collection *collection, Object *ob)
uint64_t BKE_idtype_idcode_to_idfilter(short idcode)
Definition idtype.cc:366
bool BKE_idtype_idcode_is_linkable(short idcode)
Definition idtype.cc:198
short BKE_idtype_idcode_iter_step(int *idtype_index)
Definition idtype.cc:376
bool BKE_idtype_idcode_append_is_reusable(short idcode)
Definition idtype.cc:217
Key ** BKE_key_from_id_p(ID *id)
Definition key.cc:1779
Key * BKE_key_from_id(ID *id)
Definition key.cc:1804
LayerCollection * BKE_layer_collection_get_active(ViewLayer *view_layer)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
void BKE_layer_collection_resync_forbid()
void BKE_main_collection_sync_remap(const Main *bmain)
void BKE_layer_collection_resync_allow()
ViewLayer * BKE_view_layer_find(const Scene *scene, const char *layer_name)
void BKE_main_collection_sync(const Main *bmain)
Base * BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
void size_t BKE_id_multi_tagged_delete(Main *bmain) ATTR_NONNULL()
size_t BKE_id_multi_delete(Main *bmain, blender::Set< ID * > &ids_to_delete)
void id_us_plus(ID *id)
Definition lib_id.cc:353
void id_sort_by_name(ListBase *lb, ID *id, ID *id_sorting_hint)
Definition lib_id.cc:1770
void id_fake_user_set(ID *id)
Definition lib_id.cc:391
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
Definition lib_id.cc:1981
bool BKE_lib_id_make_local(Main *bmain, ID *id, int flags)
Definition lib_id.cc:586
void id_fake_user_clear(ID *id)
Definition lib_id.cc:399
void id_us_plus_no_lib(ID *id)
Definition lib_id.cc:337
@ LIB_ID_MAKELOCAL_FORCE_LOCAL
@ LIB_ID_MAKELOCAL_LIBOVERRIDE_CLEAR
@ LIB_ID_MAKELOCAL_ASSET_DATA_CLEAR
@ LIB_ID_MAKELOCAL_FULL_LIBRARY
@ LIB_ID_MAKELOCAL_FORCE_COPY
const char * BKE_id_name(const ID &id)
void id_us_min(ID *id)
Definition lib_id.cc:361
void BKE_main_id_refcount_recompute(Main *bmain, bool do_linked_only)
Definition lib_id.cc:2015
void BKE_main_id_tag_all(Main *mainvar, int tag, bool value)
Definition lib_id.cc:1214
ID * BKE_lib_override_library_create_from_id(Main *bmain, ID *reference_id, bool do_tagged_remap)
void BKE_lib_override_library_update(Main *bmain, ID *local)
void BKE_lib_override_library_main_resync(Main *bmain, const blender::Map< Library *, Library * > *new_to_old_libraries_map, Scene *scene, ViewLayer *view_layer, BlendFileReadReport *reports)
void BKE_lib_override_library_main_operations_create(Main *bmain, bool force_auto, int *r_report_flags)
@ IDWALK_CB_LOOPBACK
@ IDWALK_CB_INTERNAL
@ IDWALK_CB_EMBEDDED_NOT_OWNING
@ IDWALK_CB_EMBEDDED
@ IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE
void BKE_library_foreach_ID_link(Main *bmain, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, LibraryForeachIDFlag flag)
Definition lib_query.cc:431
@ IDWALK_RET_NOP
@ IDWALK_NOP
void BKE_libblock_relink_to_newid(Main *bmain, ID *id, int remap_flag) ATTR_NONNULL()
Definition lib_remap.cc:919
void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, int remap_flags) ATTR_NONNULL(1
@ ID_REMAP_SKIP_NEVER_NULL_USAGE
@ ID_REMAP_SKIP_INDIRECT_USAGE
void BKE_library_main_rebuild_hierarchy(Main *bmain)
Definition library.cc:270
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:563
MainListsArray BKE_main_lists_get(Main &bmain)
Definition main.cc:974
ListBase * which_libbase(Main *bmain, short type)
Definition main.cc:887
void BKE_main_library_weak_reference_destroy(MainLibraryWeakReferenceMap *library_weak_reference_mapping) ATTR_NONNULL()
Definition main.cc:692
std::array< ListBase *, INDEX_ID_MAX - 1 > MainListsArray
Definition BKE_main.hh:621
ID * BKE_main_library_weak_reference_search_item(MainLibraryWeakReferenceMap *library_weak_reference_mapping, const char *library_filepath, const char *library_id_name) ATTR_NONNULL()
Definition main.cc:698
void BKE_main_lock(Main *bmain)
Definition main.cc:484
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:557
MainLibraryWeakReferenceMap * BKE_main_library_weak_reference_create(Main *bmain) ATTR_NONNULL()
Definition main.cc:662
void BKE_main_unlock(Main *bmain)
Definition main.cc:489
void BKE_main_library_weak_reference_remove_item(MainLibraryWeakReferenceMap *library_weak_reference_mapping, const char *library_filepath, const char *library_id_name, ID *old_id) ATTR_NONNULL()
Definition main.cc:745
void BKE_main_library_weak_reference_add_item(MainLibraryWeakReferenceMap *library_weak_reference_mapping, const char *library_filepath, const char *library_id_name, ID *new_id) ATTR_NONNULL()
Definition main.cc:707
void BKE_main_namemap_clear(Main &bmain)
General operations, lookup, etc. for materials.
void BKE_object_materials_sync_length(Main *bmain, Object *ob, ID *id)
General operations, lookup, etc. for blender objects.
Object * BKE_object_add_only_object(Main *bmain, int type, const char *name) ATTR_RETURNS_NONNULL
int BKE_object_obdata_to_type(const ID *id) ATTR_NONNULL(1)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
API for Blender-side Rigid Body stuff.
void BKE_rigidbody_ensure_local_object(struct Main *bmain, struct Object *ob)
void BKE_scene_object_base_flag_sync_from_base(Base *base)
Definition scene.cc:2870
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define FILE_MAX
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define UNUSED_VARS_NDEBUG(...)
#define ELEM(...)
#define CLAMP_MIN(a, b)
@ BLO_LIBLINK_APPEND_RECURSIVE
@ BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR
@ BLO_LIBLINK_OBDATA_INSTANCE
@ BLO_LIBLINK_APPEND_SET_FAKEUSER
@ BLO_LIBLINK_COLLECTION_NO_HIERARCHY_REBUILD
@ BLO_LIBLINK_APPEND_LOCAL_ID_REUSE
@ BLO_LIBLINK_COLLECTION_INSTANCE
#define BLO_EMBEDDED_STARTUP_BLEND
void BLO_library_link_end(Main *mainl, BlendHandle **bh, const LibraryLink_Params *params, ReportList *reports)
Definition readfile.cc:4787
BlendHandle * BLO_blendhandle_from_file(const char *filepath, BlendFileReadReport *reports)
BlendHandle * BLO_blendhandle_from_memory(const void *mem, int memsize, BlendFileReadReport *reports)
void BLO_blendhandle_close(BlendHandle *bh) ATTR_NONNULL(1)
ID * BLO_library_link_named_part(Main *mainl, BlendHandle **bh, short idcode, const char *name, const LibraryLink_Params *params)
Definition readfile.cc:4549
LinkNode * BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype, bool use_assets_only, int *r_tot_names)
Main * BLO_library_link_begin(BlendHandle **bh, const char *filepath, const LibraryLink_Params *params)
Definition readfile.cc:4631
void BLO_readfile_id_runtime_data_free_all(Main &bmain)
Definition readfile.cc:2250
void BLO_read_do_version_after_setup(Main *new_bmain, BlendfileLinkAppendContext *lapp_context, BlendFileReadReport *reports)
external writefile.cc function prototypes.
#define DATA_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:182
#define CLOG_INFO(clg_ref, level,...)
Definition CLG_log.h:179
ID and Library types, which are fundamental for SDNA.
@ ID_TAG_INDIRECT
Definition DNA_ID.h:756
@ ID_TAG_RUNTIME
Definition DNA_ID.h:767
@ ID_TAG_PRE_EXISTING
Definition DNA_ID.h:834
@ ID_TAG_EXTERN
Definition DNA_ID.h:750
@ ID_TAG_MISSING
Definition DNA_ID.h:775
@ ID_TAG_DOIT
Definition DNA_ID.h:944
@ ID_FLAG_FAKEUSER
Definition DNA_ID.h:682
ID_Type
@ ID_LI
@ ID_KE
@ ID_SCE
@ ID_GD_LEGACY
@ ID_GR
@ ID_OB
Object groups, one object can be in many groups at once.
@ OB_MODE_OBJECT
Object is a sort of wrapper for general info.
#define OB_DATA_SUPPORT_ID(_id_type)
@ OB_HIDE_SELECT
@ OB_HIDE_VIEWPORT
@ OB_EMPTY
@ OB_DUPLICOLLECTION
#define BASE_SELECTED(v3d, base)
#define BASE_SELECTABLE(v3d, base)
@ FILE_ACTIVE_COLLECTION
@ FILE_AUTOSELECT
@ FILE_LINK
@ FILE_ASSETS_ONLY
Read Guarded memory(de)allocation.
ReportList * reports
Definition WM_types.hh:1025
#define U
BMesh const char void * data
unsigned long long int uint64_t
bool add(const Key &key, const Value &value)
Definition BLI_map.hh:295
bool remove(const Key &key)
Definition BLI_map.hh:368
bool contains(const Key &key) const
Definition BLI_map.hh:353
int64_t size() const
void append(const T &value)
bool is_empty() const
IndexRange index_range() const
bool add(const Key &key, const Value &value)
Definition BLI_map.hh:295
Value lookup_default(const Key &key, const Value &default_value) const
Definition BLI_map.hh:570
bool contains(const Key &key) const
Definition BLI_set.hh:310
bool add(const Key &key)
Definition BLI_set.hh:248
void clear()
Definition BLI_set.hh:551
bool remove(const Key &key)
Definition BLI_set.hh:385
constexpr const char * c_str() const
void fill(const bool value)
std::string id_name(void *id)
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
#define ID_IS_LINKED(_id)
#define MAX_ID_NAME
#define ID_IS_OVERRIDE_LIBRARY(_id)
#define ID_NEW_SET(_id, _idn)
#define GS(a)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define LOG(severity)
Definition log.h:32
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
short flag
unsigned short local_view_bits
BlendfileLinkAppendContext * lapp_context
BlendfileLinkAppendContextItem * item
BlendfileLinkAppendContext * lapp_context
MainLibraryWeakReferenceMap * library_weak_reference_mapping
blender::Map< ID *, BlendfileLinkAppendContextItem * > new_id_to_item
blender::Vector< BlendfileLinkAppendContextLibrary > libraries
std::list< BlendfileLinkAppendContextItem > items
struct CollectionParent * next
Collection_Runtime runtime
struct ID * reference
Definition DNA_ID.h:324
Definition DNA_ID.h:404
int tag
Definition DNA_ID.h:424
struct Library * lib
Definition DNA_ID.h:410
int us
Definition DNA_ID.h:425
struct ID * newid
Definition DNA_ID.h:408
IDOverrideLibrary * override_library
Definition DNA_ID.h:459
short flag
Definition DNA_ID.h:420
char name[66]
Definition DNA_ID.h:415
struct Collection * collection
LibraryForeachIDCallbackFlag cb_flag
char filepath[1024]
Definition DNA_ID.h:507
ID id
Definition DNA_ID.h:505
LibraryRuntimeHandle * runtime
Definition DNA_ID.h:516
void * link
struct LinkNode * next
void * first
BlendfileLinkAppendContext * lapp_context
ListBase scenes
Definition BKE_main.hh:245
short subversionfile
Definition BKE_main.hh:156
short versionfile
Definition BKE_main.hh:156
ListBase collections
Definition BKE_main.hh:267
Library * curlib
Definition BKE_main.hh:241
ListBase objects
Definition BKE_main.hh:247
short transflag
struct Collection * instance_collection
float loc[3]
short visibility_flag
float empty_drawsize
struct Collection * master_collection
View3DCursor cursor
ListBase view_layers
unsigned short local_view_uid
struct Base * basact
char name[64]
uint len
static DynamicLibrary lib
uint8_t flag
Definition wm_window.cc:139