Blender V5.0
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"
45#include "BKE_idtype.hh"
46#include "BKE_key.hh"
47#include "BKE_layer.hh"
48#include "BKE_lib_id.hh"
49#include "BKE_lib_override.hh"
50#include "BKE_lib_query.hh"
51#include "BKE_lib_remap.hh"
52#include "BKE_library.hh"
53#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 = {"lib.link_append"};
68
69using namespace blender::bke;
70
71/* -------------------------------------------------------------------- */
74
97
99 BlendfileLinkAppendContext &lapp_context,
101 ReportList *reports)
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,
225 ReportList *reports,
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
265 MEM_freeN(id_name);
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
380
382
383/* -------------------------------------------------------------------- */
387
388/* Struct gathering all required data to handle instantiation of loose data-blocks. */
391
392 /* The collection in which to add loose collections/objects. */
394};
395
396static bool object_in_any_scene(Main *bmain, Object *ob)
397{
398 LISTBASE_FOREACH (Scene *, sce, &bmain->scenes) {
399 /* #BKE_scene_has_object checks bases cache of the scenes' view-layer, not actual content of
400 * their collections. */
401 if (BKE_collection_has_object_recursive(sce->master_collection, ob)) {
402 return true;
403 }
404 }
405
406 return false;
407}
408
409static bool object_in_any_collection(Main *bmain, Object *ob)
410{
411 LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
412 if (BKE_collection_has_object(collection, ob)) {
413 return true;
414 }
415 }
416
417 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
418 if (scene->master_collection != nullptr &&
419 BKE_collection_has_object(scene->master_collection, ob))
420 {
421 return true;
422 }
423 }
424
425 return false;
426}
427
429{
430 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
431 if (ob->type == OB_EMPTY && ob->instance_collection == collection) {
432 return true;
433 }
434 }
435 return false;
436}
437
440{
441 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
442 /* In linking case, we always want to handle instantiation. */
443 if (lapp_context->params->flag & FILE_LINK) {
444 return item->new_id;
445 }
446
447 /* We consider that if we either kept it linked, or re-used already local data, instantiation
448 * status of those should not be modified. */
450 return nullptr;
451 }
452
453 ID *id = item->new_id;
454 if (id == nullptr) {
455 return nullptr;
456 }
457
459 return id;
460}
461
463 LooseDataInstantiateContext *instantiate_context)
464{
465
466 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
467 Main *bmain = instantiate_context->lapp_context->params->bmain;
468 Scene *scene = instantiate_context->lapp_context->params->context.scene;
469 ViewLayer *view_layer = instantiate_context->lapp_context->params->context.view_layer;
470
471 /* Find or add collection as needed. When `active_collection` is non-null, it is assumed to be
472 * editable. */
473 if (instantiate_context->active_collection == nullptr) {
474 if (lapp_context->params->flag & FILE_ACTIVE_COLLECTION) {
477 view_layer, lc->collection);
478 }
479 else {
480 if (lapp_context->params->flag & FILE_LINK) {
481 instantiate_context->active_collection = BKE_collection_add(
482 bmain, scene->master_collection, DATA_("Linked Data"));
483 }
484 else {
485 instantiate_context->active_collection = BKE_collection_add(
486 bmain, scene->master_collection, DATA_("Appended Data"));
487 }
488 }
489 }
490}
491
493 Collection *collection,
494 Object *ob,
495 const Scene *scene,
496 ViewLayer *view_layer,
497 const View3D *v3d,
498 const int flag,
499 bool set_active)
500{
501 /* Auto-select and appending. */
502 if ((flag & FILE_AUTOSELECT) && ((flag & FILE_LINK) == 0)) {
503 /* While in general the object should not be manipulated,
504 * when the user requests the object to be selected, ensure it's visible and selectable. */
506 }
507
508 BKE_collection_object_add(bmain, collection, ob);
509 BKE_view_layer_synced_ensure(scene, view_layer);
510 Base *base = BKE_view_layer_base_find(view_layer, ob);
511
512 if (v3d != nullptr) {
513 base->local_view_bits |= v3d->local_view_uid;
514 }
515
516 if (flag & FILE_AUTOSELECT) {
517 /* All objects that use #FILE_AUTOSELECT must be selectable (unless linking data). */
518 BLI_assert((base->flag & BASE_SELECTABLE) || (flag & FILE_LINK));
519 if (base->flag & BASE_SELECTABLE) {
520 base->flag |= BASE_SELECTED;
521 }
522 }
523
524 if (set_active) {
525 view_layer->basact = base;
526 }
527
529}
530
531/* Tag obdata that actually need to be instantiated (those referenced by an object do not, since
532 * the object will be instantiated instead if needed. */
534 LooseDataInstantiateContext *instantiate_context)
535{
536 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
537
538 /* First pass on obdata to enable their instantiation by default, then do a second pass on
539 * objects to clear it for any obdata already in use. */
540 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
541 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
542 if (id == nullptr) {
543 continue;
544 }
545 const ID_Type idcode = GS(id->name);
546 if (!OB_DATA_SUPPORT_ID(idcode)) {
547 continue;
548 }
549 if (idcode == ID_GD_LEGACY) {
550 const bGPdata *legacy_gpd = reinterpret_cast<bGPdata *>(id);
551 if ((legacy_gpd->flag & GP_DATA_ANNOTATIONS) != 0) {
552 continue;
553 }
554 }
555
556 id->tag |= ID_TAG_DOIT;
557 }
558 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
559 ID *id = item.new_id;
560 if (id == nullptr || GS(id->name) != ID_OB) {
561 continue;
562 }
563
564 Object *ob = reinterpret_cast<Object *>(id);
565 Object *new_ob = reinterpret_cast<Object *>(id->newid);
566 if (ob->data != nullptr) {
567 (static_cast<ID *>(ob->data))->tag &= ~ID_TAG_DOIT;
568 }
569 if (new_ob != nullptr && new_ob->data != nullptr) {
570 (static_cast<ID *>(new_ob->data))->tag &= ~ID_TAG_DOIT;
571 }
572 }
573}
574
575/* Test whether some ancestor collection is also tagged for instantiation (return true) or not
576 * (return false). */
578{
579 for (CollectionParent *parent_collection =
580 static_cast<CollectionParent *>(collection->runtime->parents.first);
581 parent_collection != nullptr;
582 parent_collection = parent_collection->next)
583 {
584 if ((parent_collection->collection->id.tag & ID_TAG_DOIT) != 0) {
585 return true;
586 }
587 if (loose_data_instantiate_collection_parents_check_recursive(parent_collection->collection)) {
588 return true;
589 }
590 }
591 return false;
592}
593
595 LooseDataInstantiateContext *instantiate_context)
596{
597 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
598 Main *bmain = lapp_context->params->bmain;
599 Scene *scene = lapp_context->params->context.scene;
600 ViewLayer *view_layer = lapp_context->params->context.view_layer;
601 const View3D *v3d = lapp_context->params->context.v3d;
602
603 const bool do_append = (lapp_context->params->flag & FILE_LINK) == 0;
604 const bool do_instantiate_as_empty = (lapp_context->params->flag &
606
607 /* NOTE: For collections we only view_layer-instantiate duplicated collections that have
608 * non-instantiated objects in them.
609 * NOTE: Also avoid view-layer-instantiating of collections children of other instantiated
610 * collections. This is why we need two passes here. */
611 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
612 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
613 if (id == nullptr || GS(id->name) != ID_GR) {
614 continue;
615 }
616
617 /* Forced instantiation of indirectly appended collections is not wanted. Users can now
618 * easily instantiate collections (and their objects) as needed by themselves. See #67032. */
619 /* We need to check that objects in that collections are already instantiated in a scene.
620 * Otherwise, it's better to add the collection to the scene's active collection, than to
621 * instantiate its objects in active scene's collection directly. See #61141.
622 *
623 * NOTE: We only check object directly into that collection, not recursively into its
624 * children.
625 */
626 Collection *collection = (Collection *)id;
627 /* The collection could be linked/appended together with an Empty object instantiating it,
628 * better not instantiate the collection in the view-layer in that case.
629 *
630 * Can easily happen when copy/pasting such instantiating empty, see #93839. */
631 const bool collection_is_instantiated = collection_instantiated_by_any_object(bmain,
632 collection);
633 /* Always consider adding collections directly selected by the user. */
634 bool do_add_collection = (item.tag & LINK_APPEND_TAG_INDIRECT) == 0 &&
635 !collection_is_instantiated;
636 /* In linking case, do not enforce instantiating non-directly linked collections/objects.
637 * This avoids cluttering the view-layers, user can instantiate themselves specific collections
638 * or objects easily from the Outliner if needed. */
639 if (!do_add_collection && do_append && !collection_is_instantiated) {
640 LISTBASE_FOREACH (CollectionObject *, coll_ob, &collection->gobject) {
641 Object *ob = coll_ob->ob;
642 if (!object_in_any_scene(bmain, ob)) {
643 do_add_collection = true;
644 break;
645 }
646 }
647 }
648 if (do_add_collection) {
649 collection->id.tag |= ID_TAG_DOIT;
650 }
651 }
652
653 /* Second loop to actually instantiate collections tagged as such in first loop, unless some of
654 * their ancestor is also instantiated in case this is not an empty-instantiation. */
655 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
656 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
657 if (id == nullptr || GS(id->name) != ID_GR) {
658 continue;
659 }
660
661 Collection *collection = reinterpret_cast<Collection *>(id);
662 bool do_add_collection = (id->tag & ID_TAG_DOIT) != 0;
663
664 if (!do_add_collection) {
665 continue;
666 }
667 /* When instantiated into view-layer, do not add collections if one of their parents is also
668 * instantiated. */
669 if (!do_instantiate_as_empty &&
671 {
672 continue;
673 }
674 /* When instantiated as empty, do not add indirectly linked (i.e. non-user-selected)
675 * collections. */
676 if (do_instantiate_as_empty && (item.tag & LINK_APPEND_TAG_INDIRECT) != 0) {
677 continue;
678 }
679
681 Collection *active_collection = instantiate_context->active_collection;
682
683 if (do_instantiate_as_empty) {
684 /* BKE_object_add(...) messes with the selection. */
685 Object *ob = BKE_object_add_only_object(bmain, OB_EMPTY, collection->id.name + 2);
686 ob->type = OB_EMPTY;
687 ob->empty_drawsize = U.collection_instance_empty_size;
688
689 const bool set_selected = (lapp_context->params->flag & FILE_AUTOSELECT) != 0;
690 /* TODO: why is it OK to make this active here but not in other situations?
691 * See other callers of #object_base_instance_init */
692 const bool set_active = set_selected;
694 active_collection,
695 ob,
696 scene,
697 view_layer,
698 v3d,
699 lapp_context->params->flag,
700 set_active);
701
702 /* Assign the collection. */
703 ob->instance_collection = collection;
704 id_us_plus(&collection->id);
706 copy_v3_v3(ob->loc, scene->cursor.location);
707 }
708 else {
709 /* Add collection as child of active collection. */
710 BKE_collection_child_add(bmain, active_collection, collection);
711 BKE_view_layer_synced_ensure(scene, view_layer);
712
713 if ((lapp_context->params->flag & FILE_AUTOSELECT) != 0) {
714 /* All objects contained in this collection need to be processed, including the ones
715 * belonging to children collections. */
717 Base *base = BKE_view_layer_base_find(view_layer, ob);
718 if (base) {
719 base->flag |= BASE_SELECTED;
721 }
722 }
724 }
725 }
726 }
727}
728
730{
731 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
732 Main *bmain = lapp_context->params->bmain;
733 const Scene *scene = lapp_context->params->context.scene;
734 ViewLayer *view_layer = lapp_context->params->context.view_layer;
735 const View3D *v3d = lapp_context->params->context.v3d;
736
737 const bool do_object_active_done = (lapp_context->params->flag &
739
740 /* Do NOT make base active here! screws up GUI stuff,
741 * if you want it do it at the editor level (unless `do_object_active_done` is set). */
742 bool object_set_active = false;
743
744 const bool is_linking = (lapp_context->params->flag & FILE_LINK) != 0;
745
746 /* NOTE: For objects we only view_layer-instantiate duplicated objects that are not yet used
747 * anywhere. */
748 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
749 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
750 if (id == nullptr || GS(id->name) != ID_OB) {
751 continue;
752 }
753
754 /* In linking case, never instantiate stray objects that are not directly linked.
755 *
756 * While this is not ideal (in theory no object should remain un-owned), in case of indirectly
757 * linked objects, the other solution would be to add them to a local collection, which would
758 * make them directly linked. Think for now keeping them indirectly linked is more important.
759 * Ref. #93757.
760 */
761 if (is_linking && (item.tag & LINK_APPEND_TAG_INDIRECT) != 0) {
762 continue;
763 }
764
765 Object *ob = (Object *)id;
766
767 if (object_in_any_collection(bmain, ob)) {
768 continue;
769 }
770
772 Collection *active_collection = instantiate_context->active_collection;
773
774 CLAMP_MIN(ob->id.us, 0);
775 ob->mode = OB_MODE_OBJECT;
776
777 object_set_active = do_object_active_done && (ob->flag & OB_FLAG_ACTIVE_CLIPBOARD);
778
780 active_collection,
781 ob,
782 scene,
783 view_layer,
784 v3d,
785 lapp_context->params->flag,
786 object_set_active);
787 }
788}
789
791{
792 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
793 Main *bmain = lapp_context->params->bmain;
794 Scene *scene = lapp_context->params->context.scene;
795 ViewLayer *view_layer = lapp_context->params->context.view_layer;
796 const View3D *v3d = lapp_context->params->context.v3d;
797
798 /* Do NOT make base active here! screws up GUI stuff,
799 * if you want it do it at the editor level. */
800 const bool object_set_active = false;
801
802 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
803 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
804 if (id == nullptr) {
805 continue;
806 }
807 const ID_Type idcode = GS(id->name);
808 if (!OB_DATA_SUPPORT_ID(idcode)) {
809 continue;
810 }
811 if ((id->tag & ID_TAG_DOIT) == 0) {
812 continue;
813 }
814
816 Collection *active_collection = instantiate_context->active_collection;
817
818 const int type = BKE_object_obdata_to_type(id);
819 BLI_assert(type != -1);
820 Object *ob = BKE_object_add_only_object(bmain, type, id->name + 2);
821 ob->data = id;
822 id_us_plus(id);
823 BKE_object_materials_sync_length(bmain, ob, static_cast<ID *>(ob->data));
824
826 active_collection,
827 ob,
828 scene,
829 view_layer,
830 v3d,
831 lapp_context->params->flag,
832 object_set_active);
833
834 copy_v3_v3(ob->loc, scene->cursor.location);
835
836 id->tag &= ~ID_TAG_DOIT;
837 }
838}
839
841 LooseDataInstantiateContext *instantiate_context)
842{
843 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
844 Main *bmain = lapp_context->params->bmain;
845
846 /* Add rigid body objects and constraints to current RB world(s). */
847 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
848 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
849 if (id == nullptr || GS(id->name) != ID_OB) {
850 continue;
851 }
852 BKE_rigidbody_ensure_local_object(bmain, reinterpret_cast<Object *>(id));
853 }
854}
855
857{
858 if (instantiate_context->lapp_context->params->context.scene == nullptr) {
859 /* In some cases, like the asset drag&drop e.g., the caller code manages instantiation itself.
860 */
861 return;
862 }
863
864 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
865 const bool do_obdata = (lapp_context->params->flag & BLO_LIBLINK_OBDATA_INSTANCE) != 0;
866
867 /* First pass on obdata to enable their instantiation by default, then do a second pass on
868 * objects to clear it for any obdata already in use. */
869 if (do_obdata) {
870 loose_data_instantiate_obdata_preprocess(instantiate_context);
871 }
872
873 /* First do collections, then objects, then obdata. */
875 loose_data_instantiate_object_process(instantiate_context);
876 if (do_obdata) {
877 loose_data_instantiate_obdata_process(instantiate_context);
878 }
879
881}
882
884 ID *id,
886{
887 lapp_context.new_id_to_item.add(id, &item);
888}
889
890/* Generate a mapping between newly linked IDs and their items, and tag linked IDs used as
891 * liboverride references as already existing. */
893{
894 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
895 ID *id = item.new_id;
896 if (id == nullptr) {
897 continue;
898 }
899
900 new_id_to_item_mapping_add(lapp_context, id, item);
901 }
902}
903
904/* All callbacks processing dependencies of an ID for link/append post-processing share a same
905 * common logic to skip some cases. This is factorized in this helper function.
906 *
907 * Returns false if further processing should be skipped. */
910{
913 {
914 return false;
915 }
916
917 ID *id = *cb_data->id_pointer;
918 if (id == nullptr) {
919 return false;
920 }
921 if (!ID_IS_LINKED(id)) {
923 &LOG,
924 "Local ID '%s' found as part of the linked data hierarchy, this should never happen",
925 id->name);
926 return false;
927 }
928
929 if (!BKE_idtype_idcode_is_linkable(GS(id->name))) {
930 /* While we do not want to add non-linkable ID (shape keys...) to the list of linked items,
931 * unfortunately they can use fully linkable valid IDs too, like actions. Those need to be
932 * processed, so we need to recursively deal with them here. */
933 /* NOTE: Since we are bypassing checks in `BKE_library_foreach_ID_link` by manually calling it
934 * recursively, we need to take care of potential recursion cases ourselves (e.g.anim-data of
935 * shape-key referencing the shape-key itself). */
936 /* NOTE: in case both IDs (owner and 'used' ones) are non-linkable, we can assume we can break
937 * the dependency here. Indeed, either they are both linked in another way (through their own
938 * meshes for shape keys e.g.), or this is an unsupported case (two shape-keys depending on
939 * each-other need to be also 'linked' in by their respective meshes, independent shape-keys
940 * are not allowed). ref #96048. */
941 if (id != cb_data->self_id && BKE_idtype_idcode_is_linkable(GS(cb_data->self_id->name))) {
942 BKE_library_foreach_ID_link(cb_data->bmain, id, callback, cb_data->user_data, IDWALK_NOP);
943 }
944 return false;
945 }
946
947 return true;
948}
949
951
954
956{
957 Main *bmain = lapp_context->params->bmain;
958
959 new_id_to_item_mapping_create(*lapp_context);
960
961 /* Find all newly linked data-blocks, these will need to be deleted after they have been
962 * successfully packed, to avoid keeping lots of unused linked IDs around.
963 *
964 * Also add them to the items list, such that they can be checked, and removed from the deletion
965 * set in case packing fails. */
966 blender::Set<ID *> linked_ids_to_delete;
967
968 ID *id_iter;
969 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
970 if (!ID_IS_LINKED(id_iter) || ID_IS_PACKED(id_iter) ||
971 (id_iter->tag & ID_TAG_PRE_EXISTING) != 0)
972 {
973 continue;
974 }
975
976 linked_ids_to_delete.add(id_iter);
977
979 nullptr);
980 if (item == nullptr) {
982 lapp_context, BKE_id_name(*id_iter), GS(id_iter->name), nullptr);
983 item->new_id = id_iter;
984 item->source_library = id_iter->lib;
985 /* Since we did not have an item for that ID yet, we know user did not select it
986 * explicitly, it was rather linked indirectly. This info is important for
987 * instantiation of collections.
988 */
991 new_id_to_item_mapping_add(*lapp_context, id_iter, *item);
992 }
993 }
995
996 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
997 ID *id = item.new_id;
998 if (id == nullptr) {
999 continue;
1000 }
1002 if (!(ID_IS_PACKED(id) || (id->newid && ID_IS_PACKED(id->newid)))) {
1003 /* No yet packed. */
1005 }
1006 /* Calling code may want to access newly packed embedded IDs from the link/append context
1007 * items. */
1008 if (id->newid) {
1009 item.new_id = id->newid;
1010 }
1011
1012 /* If packing failed for a linked ID, do not delete its linked version. */
1013 if (!ID_IS_PACKED(item.new_id) && linked_ids_to_delete.contains(id)) {
1014 linked_ids_to_delete.remove(id);
1015 }
1016 }
1018
1019 BKE_id_multi_delete(bmain, linked_ids_to_delete);
1020}
1021
1023
1026
1028{
1031 {
1032 return IDWALK_RET_NOP;
1033 }
1034 ID *id = *cb_data->id_pointer;
1036 static_cast<BlendfileLinkAppendContextCallBack *>(cb_data->user_data);
1037
1038 /* NOTE: In append case, all dependencies are needed in the items list, to cover potential
1039 * complex cases (e.g. linked data from another library referencing other IDs from the */
1040
1041 BlendfileLinkAppendContextItem *item = data->lapp_context->new_id_to_item.lookup_default(
1042 id, nullptr);
1043 if (item == nullptr) {
1045 data->lapp_context, BKE_id_name(*id), GS(id->name), nullptr);
1046 item->new_id = id;
1047 item->source_library = id->lib;
1048 /* Since we did not have an item for that ID yet, we know user did not select it explicitly,
1049 * it was rather linked indirectly. This info is important for instantiation of collections.
1050 */
1053 new_id_to_item_mapping_add(*data->lapp_context, id, *item);
1054
1055 if ((cb_data->cb_flag & IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE) != 0 ||
1056 data->is_liboverride_dependency_only)
1057 {
1058 /* New item, (currently) detected as only used as a liboverride linked dependency. */
1060 }
1061 else if (data->is_liboverride_dependency) {
1062 /* New item, (currently) detected as used as a liboverride linked dependency, among
1063 * others. */
1065 }
1066 }
1067 else {
1068 if ((cb_data->cb_flag & IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE) != 0 ||
1069 data->is_liboverride_dependency_only)
1070 {
1071 /* Existing item, here only used as a liboverride reference dependency. If it was not
1072 * tagged as such before, it is also used by non-liboverride reference data. */
1075 }
1076 }
1077 else if ((item->tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) != 0) {
1078 /* Existing item, here used in a non-liboverride dependency context. If it was
1079 * tagged as a liboverride dependency only, its tag and action need to be updated. */
1082 }
1083 }
1084
1085 return IDWALK_RET_NOP;
1086}
1087
1090{
1093 {
1094 return IDWALK_RET_NOP;
1095 }
1096 ID *id = *cb_data->id_pointer;
1098 static_cast<BlendfileLinkAppendContextCallBack *>(cb_data->user_data);
1099
1100 if (!data->item->reusable_local_id) {
1101 return IDWALK_RET_NOP;
1102 }
1103
1104 BlendfileLinkAppendContextItem *item = data->lapp_context->new_id_to_item.lookup(id);
1105 BLI_assert(item != nullptr);
1106
1107 /* If the currently processed owner ID is not defined as being kept linked, and is using a
1108 * dependency that cannot be reused form local data, then the owner ID should not reuse its
1109 * local data either. */
1110 if (item->action != LINK_APPEND_ACT_KEEP_LINKED && item->reusable_local_id == nullptr) {
1111 BKE_main_library_weak_reference_remove_item(data->lapp_context->library_weak_reference_mapping,
1112 cb_data->owner_id->lib->filepath,
1113 cb_data->owner_id->name,
1114 data->item->reusable_local_id);
1115 data->item->reusable_local_id = nullptr;
1116 }
1117
1118 return IDWALK_RET_NOP;
1119}
1120
1122{
1125 {
1126 return IDWALK_RET_NOP;
1127 }
1128 ID *id = *cb_data->id_pointer;
1130 cb_data->user_data);
1131
1132 BlendfileLinkAppendContextItem *item = data->lapp_context->new_id_to_item.lookup(id);
1133 BLI_assert(item != nullptr);
1135
1136 if (item->action == LINK_APPEND_ACT_MAKE_LOCAL) {
1137 CLOG_DEBUG(&LOG,
1138 "Appended ID '%s' was to be made directly local, but is also used by data that is "
1139 "kept linked, so duplicating it instead.",
1140 id->name);
1142 }
1143 return IDWALK_RET_NOP;
1144}
1145
1147 ReportList *reports)
1148{
1149 Main *bmain = lapp_context.params->bmain;
1150
1151 const bool do_recursive = (lapp_context.params->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0;
1152 const bool do_reuse_local_id = (lapp_context.params->flag & BLO_LIBLINK_APPEND_LOCAL_ID_REUSE) !=
1153 0;
1154
1155 /* In case of non-recursive appending, gather a set of all 'original' libraries (i.e. libraries
1156 * containing data that was explicitly selected by the user). */
1157 blender::Set<Library *> direct_libraries;
1158 if (!do_recursive) {
1159 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1160 ID *id = item.new_id;
1161 if (id == nullptr) {
1162 continue;
1163 }
1164 direct_libraries.add(id->lib);
1165 }
1166 }
1167
1168 /* Add items for all not yet known IDs (i.e. implicitly linked indirect dependencies) to the
1169 * list.
1170 * NOTE: Since items are appended, this list will grow and these IDs will be processed later,
1171 * leading to a flatten recursive processing of all the linked dependencies.
1172 */
1173 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1174 ID *id = item.new_id;
1175 if (id == nullptr) {
1176 continue;
1177 }
1178 BLI_assert(item.reusable_local_id == nullptr);
1179
1180 /* NOTE: handling of reusable local ID info is needed, even if their usage is not requested
1181 * for that append operation:
1182 * - Newly appended data need to get their weak reference, such that it can be reused later
1183 * if requested.
1184 * - Existing appended data may need to get this 'reuse' weak reference cleared, e.g. if a
1185 * new version of it is made local. */
1188 lapp_context.library_weak_reference_mapping,
1189 id->lib->filepath,
1190 id->name) :
1191 nullptr;
1192
1194 cb_data.lapp_context = &lapp_context;
1195 cb_data.item = &item;
1196 cb_data.reports = reports;
1198 cb_data.is_liboverride_dependency_only = (item.tag &
1202 }
1203
1204 /* At this point, linked IDs that should remain linked can already be defined as such:
1205 * - In case of non-recursive appending, IDs from other libraries.
1206 * - IDs only used as liboverride references. */
1207 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1208 /* These tags should have been set in above loop, here they can be check for validity (they
1209 * are mutually exclusive). */
1210 BLI_assert(
1211 (item.tag &
1214
1215 ID *id = item.new_id;
1216 if (id == nullptr) {
1217 continue;
1218 }
1219 /* IDs exclusively used as liboverride reference should not be made local at all. */
1221 CLOG_DEBUG(
1222 &LOG,
1223 "Appended ID '%s' is only used as a liboverride linked dependency, keeping it linked.",
1224 id->name);
1226 item.reusable_local_id = nullptr;
1227 }
1228 /* In non-recursive append case, only IDs from the same libraries as the directly appended
1229 * ones are made local. All dependencies from other libraries are kept linked. */
1230 if (!do_recursive && !direct_libraries.contains(id->lib)) {
1231 CLOG_DEBUG(&LOG,
1232 "Appended ID '%s' belongs to another library and recursive append is disabled, "
1233 "keeping it linked.",
1234 id->name);
1236 item.reusable_local_id = nullptr;
1237 }
1238 }
1239
1240 /* The reusable local IDs can cause severe issues in hierarchies of appended data. If an ID
1241 * user e.g. still has a local reusable ID found, but one of its dependencies does not (i.e.
1242 * either there were some changes in the library data, or the previously appended local
1243 * dependencies was modified in current file and therefore cannot be re-used anymore), then the
1244 * user ID should not be considered as usable either. */
1245 /* TODO: This process is currently fairly raw and inefficient. This is likely not a
1246 * (significant) issue currently anyway. But would be good to refactor this whole code to use
1247 * modern CPP containers (list of items could be an `std::deque` e.g., to be iterable in both
1248 * directions). Being able to loop backward here (i.e. typically process the dependencies
1249 * before the user IDs) could avoid a lot of iterations. */
1250 for (bool keep_looping = do_reuse_local_id; keep_looping;) {
1251 keep_looping = false;
1252 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1253 ID *id = item.new_id;
1254 if (id == nullptr) {
1255 continue;
1256 }
1257 if (!item.reusable_local_id) {
1258 continue;
1259 }
1261 cb_data.lapp_context = &lapp_context;
1262 cb_data.item = &item;
1263 cb_data.reports = reports;
1265 cb_data.is_liboverride_dependency_only = (item.tag &
1268 id,
1270 &cb_data,
1271 IDWALK_NOP);
1272 if (!item.reusable_local_id) {
1273 /* If some reusable ID was cleared, another loop over all items is needed to potentially
1274 * propagate this change higher in the dependency hierarchy. */
1275 keep_looping = true;
1276 }
1277 }
1278 }
1279
1280 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1281 ID *id = item.new_id;
1282 if (id == nullptr) {
1283 continue;
1284 }
1285
1286 if (item.action != LINK_APPEND_ACT_UNSET) {
1287 /* Already set, pass. */
1289 continue;
1290 }
1292
1293 if (do_reuse_local_id && item.reusable_local_id != nullptr) {
1294 CLOG_DEBUG(&LOG, "Appended ID '%s' as a matching local one, re-using it.", id->name);
1296 }
1297 else if (id->tag & ID_TAG_PRE_EXISTING) {
1298 CLOG_DEBUG(&LOG, "Appended ID '%s' was already linked, duplicating it.", id->name);
1300 }
1302 CLOG_DEBUG(
1303 &LOG,
1304 "Appended ID '%s' is also used as a liboverride linked dependency, duplicating it.",
1305 id->name);
1307 }
1308 else if (ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY(id)) {
1309 /* While in theory liboverrides can be directly made local, this causes complex potential
1310 * problems, e.g. because hierarchy roots can become temporarily invalid when the root is
1311 * made local, etc.
1312 *
1313 * So for now, simpler to always duplicate linked liboverrides. */
1314 CLOG_DEBUG(&LOG, "Appended ID '%s' is a liboverride, duplicating it.", id->name);
1316 }
1317 else {
1318 /* That last action, making linked data directly local, can still be changed to
1319 * #LINK_APPEND_ACT_COPY_LOCAL in the last checks below. This can happen in rare cases with
1320 * complex relationships involving IDs that are kept linked and IDs that are made local,
1321 * both using some same dependencies. */
1322 CLOG_DEBUG(&LOG, "Appended ID '%s' will be made local.", id->name);
1324 }
1325 }
1326
1327 /* Some linked IDs marked to be made directly local may also be used by other items
1328 * marked to be kept linked. in such case, they need to be copied for the local data, such that
1329 * a linked version of these remains available as dependency for other linked data. */
1330 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1331 ID *id = item.new_id;
1332 if (id == nullptr) {
1333 continue;
1334 }
1335
1336 /* Only IDs kept as linked need to be checked here. */
1337 if (item.action == LINK_APPEND_ACT_KEEP_LINKED) {
1339 cb_data.lapp_context = &lapp_context;
1340 cb_data.item = &item;
1341 cb_data.reports = reports;
1343 cb_data.is_liboverride_dependency_only = (item.tag &
1347 }
1348
1349 /* If we found a matching existing local id but are not re-using it, we need to properly
1350 * clear its weak reference to linked data. */
1351 if (item.reusable_local_id != nullptr &&
1353 {
1354 BLI_assert_msg(!do_reuse_local_id,
1355 "This code should only be reached when the current append operation does not "
1356 "try to reuse local data.");
1358 id->lib->filepath,
1359 id->name,
1360 item.reusable_local_id);
1361 item.reusable_local_id = nullptr;
1362 }
1363 }
1364}
1365
1367{
1370
1371 if (lapp_context->items.empty()) {
1372 /* Nothing to append. */
1373 return;
1374 }
1375
1376 Main *bmain = lapp_context->params->bmain;
1377
1378 BLI_assert((lapp_context->params->flag & FILE_LINK) == 0);
1379
1380 const bool set_fakeuser = (lapp_context->params->flag & BLO_LIBLINK_APPEND_SET_FAKEUSER) != 0;
1381
1382 const int make_local_common_flags =
1384 ((lapp_context->params->flag & BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR) != 0 ?
1386 0) |
1387 /* In recursive case (i.e. everything becomes local), clear liboverrides. Otherwise (i.e.
1388 * only data from immediately linked libraries is made local), preserve liboverrides. */
1389 ((lapp_context->params->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0 ?
1391 0);
1392
1393 new_id_to_item_mapping_create(*lapp_context);
1395
1396 /* Add missing items (the indirectly linked ones), and carefully define which action should be
1397 * applied to each of them. */
1398 blendfile_append_define_actions(*lapp_context, reports);
1399
1400 /* Effectively perform required operation on every linked ID. */
1401 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1402 ID *id = item.new_id;
1403 if (id == nullptr) {
1404 continue;
1405 }
1406
1407 ID *local_appended_new_id = nullptr;
1408 char lib_filepath[FILE_MAX];
1409 STRNCPY(lib_filepath, id->lib->filepath);
1410 char lib_id_name[MAX_ID_NAME];
1411 STRNCPY(lib_id_name, id->name);
1412
1413 switch (item.action) {
1415 BKE_lib_id_make_local(bmain, id, make_local_common_flags | LIB_ID_MAKELOCAL_FORCE_COPY);
1416 local_appended_new_id = id->newid;
1417 break;
1419 BKE_lib_id_make_local(bmain, id, make_local_common_flags | LIB_ID_MAKELOCAL_FORCE_LOCAL);
1420 BLI_assert(id->newid == nullptr);
1421 local_appended_new_id = id;
1422 break;
1424 /* Nothing to do here. */
1425 break;
1427 BLI_assert(item.reusable_local_id != nullptr);
1428 /* We only need to set `newid` to ID found in previous loop, for proper remapping. */
1429 ID_NEW_SET(id, item.reusable_local_id);
1430 /* This is not a 'new' local appended id, do not set `local_appended_new_id` here. */
1431 break;
1433 CLOG_ERROR(
1434 &LOG, "Unexpected unset append action for '%s' ID, assuming 'keep link'", id->name);
1435 break;
1436 default:
1438 }
1439
1440 if (local_appended_new_id != nullptr) {
1441 if (BKE_idtype_idcode_append_is_reusable(GS(local_appended_new_id->name))) {
1443 lib_filepath,
1444 lib_id_name,
1445 local_appended_new_id);
1446 }
1447
1448 if (set_fakeuser) {
1449 if (!ELEM(GS(local_appended_new_id->name), ID_OB, ID_GR)) {
1450 /* Do not set fake user on objects nor collections (instancing). */
1451 id_fake_user_set(local_appended_new_id);
1452 }
1453 }
1454 }
1455 }
1456
1458 lapp_context->library_weak_reference_mapping = nullptr;
1459
1460 /* Remap IDs as needed. */
1461 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1462 if (item.action == LINK_APPEND_ACT_KEEP_LINKED) {
1463 continue;
1464 }
1465
1466 ID *id = item.new_id;
1467 if (id == nullptr) {
1468 continue;
1469 }
1472 id = id->newid;
1473 if (id == nullptr) {
1474 continue;
1475 }
1476 }
1477
1479
1480 BKE_libblock_relink_to_newid(bmain, id, 0);
1481 }
1482
1483 /* Remove linked IDs when a local existing data has been reused instead. */
1484 BKE_main_id_tag_all(bmain, ID_TAG_DOIT, false);
1485 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1487 continue;
1488 }
1489
1490 ID *id = item.new_id;
1491 if (id == nullptr) {
1492 continue;
1493 }
1495 BLI_assert(id->newid != nullptr);
1496
1497 /* Calling code may want to access newly appended IDs from the link/append context items. */
1498 item.new_id = id->newid;
1499
1500 /* Only the 'reuse local' action should leave unused newly linked data behind. */
1501 if (item.action != LINK_APPEND_ACT_REUSE_LOCAL) {
1502 continue;
1503 }
1504 /* Do NOT delete a linked data that was already linked before this append. */
1505 if (id->tag & ID_TAG_PRE_EXISTING) {
1506 continue;
1507 }
1508 /* Do NOT delete a linked data that is (also) used a liboverride dependency. */
1511 continue;
1512 }
1513
1514 id->tag |= ID_TAG_DOIT;
1515 }
1517
1519
1520 BlendFileReadReport bf_reports{};
1521 bf_reports.reports = reports;
1522 BLO_read_do_version_after_setup(bmain, lapp_context, &bf_reports);
1523
1525}
1526
1528
1531
1533{
1535 {
1536 return IDWALK_RET_NOP;
1537 }
1538 ID *id = *cb_data->id_pointer;
1540 static_cast<BlendfileLinkAppendContextCallBack *>(cb_data->user_data);
1541
1542 if ((id->tag & ID_TAG_PRE_EXISTING) != 0) {
1543 /* About to re-use a linked data that was already there, and that will stay linked. This case
1544 * does not need any further processing of the child hierarchy (existing linked data
1545 * instantiation status should not be modified here). */
1546 return IDWALK_RET_NOP;
1547 }
1548
1549 /* In linking case, all linked IDs are considered for instantiation, including from other
1550 * libraries. So all linked IDs that were not skipped so far need to be added to the items
1551 * list.
1552 */
1553 BlendfileLinkAppendContextItem *item = data->lapp_context->new_id_to_item.lookup_default(
1554 id, nullptr);
1555 /* NOTE: liboverride info (tags like #LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) can be
1556 * ignored/skipped here, since all data are kept linked anyway, they are not useful currently.
1557 */
1558 if (item == nullptr) {
1560 data->lapp_context, BKE_id_name(*id), GS(id->name), nullptr);
1561 item->new_id = id;
1562 item->source_library = id->lib;
1563 /* Since there is no item for that ID yet, the user did not select it explicitly, it was
1564 * rather linked indirectly. This info is important for instantiation of collections. */
1566 /* In linking case we already know what we want to do with these items. */
1568 new_id_to_item_mapping_add(*data->lapp_context, id, *item);
1569 }
1570 return IDWALK_RET_NOP;
1571}
1572
1574 ReportList *reports)
1575{
1576 BLI_assert(ELEM(lapp_context->process_stage,
1580
1581 if (!lapp_context->params->context.scene) {
1582 return;
1583 }
1584 if (lapp_context->params->flag & FILE_LINK) {
1585 new_id_to_item_mapping_create(*lapp_context);
1586 /* Add items for all not yet known IDs (i.e. implicitly linked indirect dependencies) to the
1587 * list.
1588 * NOTE: Since items are appended to the list, this list will grow and these IDs will be
1589 * processed later, leading to a flatten recursive processing of all the linked dependencies.
1590 */
1591 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1592 ID *id = item.new_id;
1593 if (id == nullptr) {
1594 continue;
1595 }
1596 BLI_assert(item.userdata == nullptr);
1597
1599 cb_data.lapp_context = lapp_context;
1600 cb_data.item = &item;
1601 cb_data.reports = reports;
1603 id,
1605 &cb_data,
1606 IDWALK_NOP);
1607 }
1608 }
1609
1610 LooseDataInstantiateContext instantiate_context{};
1611 instantiate_context.lapp_context = lapp_context;
1612 instantiate_context.active_collection = nullptr;
1613 loose_data_instantiate(&instantiate_context);
1614}
1615
1617{
1620
1621 if (lapp_context->items.empty()) {
1622 /* Nothing to be linked. */
1623 return;
1624 }
1625
1626 BLI_assert(!lapp_context->libraries.is_empty());
1627
1628 Main *mainl;
1629 Library *lib;
1630
1631 for (const int lib_idx : lapp_context->libraries.index_range()) {
1632 BlendfileLinkAppendContextLibrary &lib_context = lapp_context->libraries[lib_idx];
1633 const char *libname = lib_context.path.c_str();
1634
1635 if (!link_append_context_library_blohandle_ensure(*lapp_context, lib_context, reports)) {
1636 /* Unlikely since we just browsed it, but possible
1637 * Error reports will have been made by BLO_blendhandle_from_file() */
1638 continue;
1639 }
1640
1641 /* here appending/linking starts */
1642
1643 mainl = BLO_library_link_begin(&lib_context.blo_handle, libname, lapp_context->params);
1644 lib = mainl->curlib;
1645 BLI_assert(lib != nullptr);
1646 /* In case lib was already existing but not found originally, see #99820. */
1647 lib->id.tag &= ~ID_TAG_MISSING;
1648
1649 if (mainl->versionfile < 250) {
1650 BKE_reportf(reports,
1652 "Linking or appending from a very old .blend file format (%d.%d), no animation "
1653 "conversion will "
1654 "be done! You may want to re-save your lib file with current Blender",
1655 mainl->versionfile,
1656 mainl->subversionfile);
1657 }
1658
1659 /* For each lib file, we try to link all items belonging to that lib,
1660 * and tag those successful to not try to load them again with the other libraries. */
1661 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1662 ID *new_id;
1663
1664 if (!item.libraries[lib_idx]) {
1665 continue;
1666 }
1667
1669 mainl, &lib_context.blo_handle, item.idcode, item.name.c_str(), lapp_context->params);
1670
1671 if (new_id) {
1672 /* If the link is successful, clear item's libraries 'todo' flags.
1673 * This avoids trying to link same item with other libraries to come. */
1674 item.libraries.fill(false);
1675 item.new_id = new_id;
1676 item.source_library = new_id->lib;
1677 }
1678 }
1679
1680 BLO_library_link_end(mainl, &lib_context.blo_handle, lapp_context->params, reports);
1681 link_append_context_library_blohandle_release(*lapp_context, lib_context);
1682 }
1683
1684 /* In linking case finalizing process (ensuring all data is valid, instantiating loose
1685 * collections or objects, etc.) can be done here directly.
1686 *
1687 * In append case, the finalizing process is much more complex and requires and additional call
1688 * to #BKE_blendfile_append for caller code. */
1689 if (lapp_context->params->flag & FILE_LINK) {
1690 BlendFileReadReport bf_reports{};
1691 bf_reports.reports = reports;
1692 BLO_read_do_version_after_setup(lapp_context->params->bmain, lapp_context, &bf_reports);
1693
1695 }
1696}
1697
1699 const eBKELibLinkOverride flags,
1700 ReportList * /*reports*/)
1701{
1702 if (lapp_context->items.empty()) {
1703 /* Nothing to override. */
1704 return;
1705 }
1706
1707 Main *bmain = lapp_context->params->bmain;
1708
1709 /* Liboverride only makes sense if data was linked, not appended. */
1710 BLI_assert((lapp_context->params->flag & FILE_LINK) != 0);
1711
1712 const bool set_runtime = (flags & BKE_LIBLINK_OVERRIDE_CREATE_RUNTIME) != 0;
1713 const bool do_use_exisiting_liboverrides = (flags &
1715
1716 blender::Map<ID *, ID *> linked_ids_to_local_liboverrides;
1717 if (do_use_exisiting_liboverrides) {
1718 ID *id_iter;
1719 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
1720 if (ID_IS_LINKED(id_iter)) {
1721 continue;
1722 }
1723 if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_iter)) {
1724 continue;
1725 }
1726 /* Do not consider regular liboverrides if runtime ones are requested, and vice-versa. */
1727 if ((set_runtime && (id_iter->tag & ID_TAG_RUNTIME) == 0) ||
1728 (!set_runtime && (id_iter->tag & ID_TAG_RUNTIME) != 0))
1729 {
1730 continue;
1731 }
1732
1733 /* In case several liboverrides exist of the same data, only consider the first found one, so
1734 * don't use `add_overwrite`. */
1735 linked_ids_to_local_liboverrides.add(id_iter->override_library->reference, id_iter);
1736 }
1738 }
1739
1740 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1741 ID *id = item.new_id;
1742 if (id == nullptr) {
1743 continue;
1744 }
1745 BLI_assert(item.userdata == nullptr);
1746
1747 if (do_use_exisiting_liboverrides) {
1748 item.liboverride_id = linked_ids_to_local_liboverrides.lookup_default(id, nullptr);
1749 }
1750 if (item.liboverride_id == nullptr) {
1752 if (set_runtime) {
1754 if ((id->tag & ID_TAG_PRE_EXISTING) == 0) {
1755 /* If the linked ID is newly linked, in case its override is runtime-only, assume its
1756 * reference to be indirectly linked.
1757 *
1758 * This is more of an heuristic for 'as best as possible' user feedback in the UI
1759 * (Outliner), which is expected to be valid in almost all practical use-cases. Direct or
1760 * indirect linked status is properly checked before saving .blend file. */
1761 id->tag &= ~ID_TAG_EXTERN;
1762 id->tag |= ID_TAG_INDIRECT;
1763 }
1764 }
1765 }
1766 }
1767
1768 BKE_main_namemap_clear(*bmain);
1769}
1770
1772
1775
1777 id::IDRemapper &remapper,
1778 blender::Map<ID *, ID *> &old_owner_id_to_shapekey,
1779 ID *old_id,
1780 ID *new_id,
1781 const bool do_reload)
1782{
1783 BLI_assert(old_id);
1784 if (do_reload) {
1785 /* Since we asked for placeholders in case of missing IDs,
1786 * we expect to always get a valid one. */
1787 BLI_assert(new_id);
1788 }
1789 if (new_id) {
1790 CLOG_DEBUG(&LOG,
1791 "Before remap of %s, old_id users: %d, new_id users: %d",
1792 old_id->name,
1793 old_id->us,
1794 new_id->us);
1795 remapper.add(old_id, new_id);
1796 }
1797
1798 /* Usual special code for ShapeKeys snowflakes...
1799 *
1800 * NOTE: Unfortunately, actual reasons for why the old shapekeys needs to be removed from their
1801 * old owner ID was not documented in the initial commit. Suspect it's related to the fact that
1802 * the old ID should not end up using the new shapekeys? */
1803 Key **old_key_p = BKE_key_from_id_p(old_id);
1804 if (old_key_p == nullptr) {
1805 return;
1806 }
1807 Key *old_key = *old_key_p;
1808 Key *new_key = BKE_key_from_id(new_id);
1809 if (old_key != nullptr) {
1810 old_owner_id_to_shapekey.add(old_id, &old_key->id);
1811 *old_key_p = nullptr;
1812 id_us_min(&old_key->id);
1813 remapper.add(&old_key->id, &new_key->id);
1814 }
1815}
1816
1818 Main *bmain,
1819 blender::Map<ID *, ID *> &old_owner_id_to_shapekey,
1820 ID *old_id,
1821 ID *new_id,
1822 ReportList *reports,
1823 const bool do_reload)
1824{
1825 /* Restore old shapekey pointer in old id (see also
1826 * #blendfile_library_relocate_id_remap_prepare above). */
1827 Key **old_key_p = BKE_key_from_id_p(old_id);
1828 if (old_key_p) {
1829 Key *old_key = reinterpret_cast<Key *>(
1830 old_owner_id_to_shapekey.lookup_default_as(old_id, nullptr));
1831 if (old_key) {
1832 BLI_assert(GS(old_key->id.name) == ID_KE);
1833 *old_key_p = old_key;
1834 id_us_plus_no_lib(&old_key->id);
1835 }
1836 }
1837
1838 if (old_id->flag & ID_FLAG_FAKEUSER) {
1839 id_fake_user_clear(old_id);
1840 id_fake_user_set(new_id);
1841 }
1842
1843 CLOG_DEBUG(&LOG,
1844 "After remap of %s, old_id users: %d, new_id users: %d",
1845 old_id->name,
1846 old_id->us,
1847 new_id->us);
1848
1849 /* In some cases, new_id might become direct link, remove parent of library in this case. */
1850 if (new_id->lib->runtime->parent && (new_id->tag & ID_TAG_INDIRECT) == 0) {
1851 if (do_reload) {
1852 BLI_assert_unreachable(); /* Should not happen in 'pure' reload case... */
1853 }
1854 new_id->lib->runtime->parent = nullptr;
1855 }
1856
1857 if (old_id->us > 0 && old_id->lib == new_id->lib) {
1858 /* Note that this *should* not happen - but better be safe than sorry in this area,
1859 * at least until we are 100% sure this cannot ever happen.
1860 * Also, we can safely assume names were unique so far,
1861 * so just replacing '.' by '~' should work,
1862 * but this does not totally rules out the possibility of name collision. */
1863 size_t len = strlen(old_id->name);
1864 size_t dot_pos;
1865 bool has_num = false;
1866
1867 for (dot_pos = len; dot_pos--;) {
1868 char c = old_id->name[dot_pos];
1869 if (c == '.') {
1870 break;
1871 }
1872 if (c < '0' || c > '9') {
1873 has_num = false;
1874 break;
1875 }
1876 has_num = true;
1877 }
1878
1879 if (has_num) {
1880 old_id->name[dot_pos] = '~';
1881 }
1882 else {
1883 len = std::min<size_t>(len, MAX_ID_NAME - 7);
1884 BLI_strncpy(&old_id->name[len], "~000", 7);
1885 }
1886
1887 id_sort_by_name(which_libbase(bmain, GS(old_id->name)), old_id, nullptr);
1888
1890 reports,
1892 "Lib Reload: Replacing all references to old data-block '%s' by reloaded one failed, "
1893 "old one (%d remaining users) had to be kept and was renamed to '%s'",
1894 new_id->name,
1895 old_id->us,
1896 old_id->name);
1897 }
1898}
1899
1901 ReportList *reports,
1902 const bool do_reload,
1903 const int remap_flags)
1904{
1905 Main *bmain = lapp_context.params->bmain;
1906
1907 id::IDRemapper remapper;
1908 blender::Map<ID *, ID *> old_owner_id_to_shapekey;
1909
1910 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1911 ID *old_id = static_cast<ID *>(item.userdata);
1912 if (!old_id) {
1913 continue;
1914 }
1915 ID *new_id = item.new_id;
1917 remapper, old_owner_id_to_shapekey, old_id, new_id, do_reload);
1918 }
1919
1920 BKE_libblock_remap_multiple_locked(bmain, remapper, remap_flags);
1921
1922 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1923 ID *old_id = static_cast<ID *>(item.userdata);
1924 if (!old_id) {
1925 continue;
1926 }
1927 ID *new_id = item.new_id;
1928 if (!new_id) {
1929 if (do_reload) {
1930 /* Since we asked for placeholders in case of missing IDs, we expect to always get a valid
1931 * one. */
1932 BLI_assert_msg(false,
1933 "On library reload, placeholders should be generated when a linked ID is "
1934 "missing, so there should never be a nullptr 'new_id' here");
1935 }
1936 /* If finding a valid matching ID for `old_id` in the searched library(-ies) failed, do not
1937 * clear references to the current 'old_id' placeholder. */
1938 continue;
1939 }
1941 bmain, old_owner_id_to_shapekey, old_id, new_id, reports, do_reload);
1942 }
1943}
1944
1947{
1948 Main &bmain = *lapp_context.params->bmain;
1949
1950 blender::Set<ID *> ids_to_delete = {};
1951 ID *id_iter;
1952
1953 /* Delete all no more used old IDs. */
1954 /* NOTE: While this looping over until we are sure we deleted everything is very far from
1955 * efficient, doing otherwise would require a much more complex handling of indirectly linked IDs
1956 * in steps above. Currently, in case of relocation, those are skipped in remapping phase, though
1957 * in some cases (essentially internal links between IDs from the same library) remapping should
1958 * happen. But getting this to work reliably would be very difficult, so since this is not a
1959 * performance-critical code, better to go with the (relatively) simpler, brute-force approach
1960 * here in 'removal of old IDs' step. */
1961 bool keep_looping = true;
1962 while (keep_looping) {
1963 keep_looping = false;
1964
1965 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1966 ID *old_id = static_cast<ID *>(item.userdata);
1967
1968 if (old_id == nullptr) {
1969 continue;
1970 }
1971
1972 if (GS(old_id->name) == ID_KE) {
1973 /* Shape Keys are handled as part of their owning obdata (see below). This implies that
1974 * there is no way to know when the old pointer gets invalid, so just clear it immediately.
1975 */
1976 item.userdata = nullptr;
1977 continue;
1978 }
1979
1980 /* In case the active scene was reloaded, the context pointers in
1981 * `lapp_context->params->context` need to be updated before the old Scene ID is freed. */
1982 if (old_id == &lapp_context.params->context.scene->id) {
1983 BLI_assert(GS(old_id->name) == ID_SCE);
1984 Scene *new_scene = reinterpret_cast<Scene *>(item.new_id);
1985 BLI_assert(new_scene != nullptr);
1986 lapp_context.params->context.scene = new_scene;
1987 if (lapp_context.params->context.view_layer != nullptr) {
1988 ViewLayer *new_view_layer = BKE_view_layer_find(
1989 new_scene, lapp_context.params->context.view_layer->name);
1990 lapp_context.params->context.view_layer = static_cast<ViewLayer *>(
1991 (new_view_layer != nullptr) ? new_view_layer : new_scene->view_layers.first);
1992 }
1993 /* lapp_context->params->context.v3d should never be made invalid by newly linked data
1994 * here, as it is UI data, ultimately owned by a #bScreen ID, which is not linkable. */
1995 }
1996
1997 if (old_id->us == 0) {
1998 ids_to_delete.add(old_id);
1999 item.userdata = nullptr;
2000 keep_looping = true;
2001 Key *old_key = BKE_key_from_id(old_id);
2002 if (old_key != nullptr) {
2003 ids_to_delete.add(&old_key->id);
2004 }
2005 }
2006 }
2007 BKE_id_multi_delete(&bmain, ids_to_delete);
2008 ids_to_delete.clear();
2009 }
2010
2011 /* Some datablocks can get reloaded/replaced 'silently' because they are not linkable
2012 * (shape keys e.g.), so we need another loop here to clear old ones if possible. */
2013 FOREACH_MAIN_ID_BEGIN (&bmain, id_iter) {
2014 /* XXX That check may be a bit to generic/permissive? */
2015 if (id_iter->lib && (id_iter->flag & ID_TAG_PRE_EXISTING) && id_iter->us == 0) {
2016 ids_to_delete.add(id_iter);
2017 }
2018 }
2020 BKE_id_multi_delete(&bmain, ids_to_delete);
2021 ids_to_delete.clear();
2022
2023 /* Get rid of no more used libraries... */
2024 ListBase *libraries = which_libbase(&bmain, ID_LI);
2025 LISTBASE_FOREACH (ID *, id_iter, libraries) {
2026 ids_to_delete.add(id_iter);
2027 }
2028 FOREACH_MAIN_ID_BEGIN (&bmain, id_iter) {
2029 if (id_iter->lib) {
2030 ids_to_delete.remove(&id_iter->lib->id);
2031 /* If the used library is an archive one, its owner 'normal' library is also used. */
2032 if (id_iter->lib->archive_parent_library) {
2034 ids_to_delete.remove(&id_iter->lib->archive_parent_library->id);
2035 }
2036 }
2037 }
2039 BKE_id_multi_delete(&bmain, ids_to_delete);
2040}
2041
2044 BlendfileLinkAppendContext &lapp_context,
2045 const blender::Map<Library *, Library *> &new_to_old_libraries_map,
2046 ReportList *reports)
2047{
2048 Main &bmain = *lapp_context.params->bmain;
2049
2050 ID *id_iter;
2051 FOREACH_MAIN_ID_BEGIN (&bmain, id_iter) {
2052 if (ID_IS_LINKED(id_iter) || !ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) ||
2053 (id_iter->tag & ID_TAG_PRE_EXISTING) == 0)
2054 {
2055 continue;
2056 }
2057 if ((id_iter->override_library->reference->tag & ID_TAG_MISSING) == 0) {
2058 id_iter->tag &= ~ID_TAG_MISSING;
2059 }
2060 if ((id_iter->override_library->reference->tag & ID_TAG_PRE_EXISTING) == 0) {
2061 BKE_lib_override_library_update(&bmain, id_iter);
2062 }
2063 }
2065
2067
2068 /* Resync overrides if needed. */
2069 if (liboverride::is_auto_resync_enabled() && lapp_context.params->context.scene != nullptr) {
2070 BlendFileReadReport report{};
2071 report.reports = reports;
2073 &new_to_old_libraries_map,
2074 lapp_context.params->context.scene,
2075 lapp_context.params->context.view_layer,
2076 &report);
2077 /* We need to rebuild some of the deleted override rules (for UI feedback purpose). */
2079 }
2080}
2081
2083 ReportList *reports,
2085 const bool do_reload)
2086{
2087 Main *bmain = lapp_context->params->bmain;
2088
2089 /* All override rules need to be up to date, since there will be no do_version here, otherwise
2090 * older, now-invalid rules might be applied and likely fail, or some changes might be missing,
2091 * etc. See #93353. */
2093
2094 /* Remove all IDs to be reloaded from Main. */
2095 MainListsArray lbarray = BKE_main_lists_get(*bmain);
2096 int lba_idx = lbarray.size();
2097 while (lba_idx--) {
2098 ID *id = static_cast<ID *>(lbarray[lba_idx]->first);
2099 const short idcode = id ? GS(id->name) : 0;
2100
2101 if (!id || !BKE_idtype_idcode_is_linkable(idcode)) {
2102 /* No need to reload non-linkable data-types,
2103 * those will get relinked with their 'users ID'. */
2104 continue;
2105 }
2106
2107 for (; id; id = static_cast<ID *>(id->next)) {
2108 if (id->lib == library) {
2110
2111 /* We remove it from current Main, and add it to items to link... */
2112 /* Note that non-linkable IDs (like e.g. shape-keys) are also explicitly linked here... */
2113 BLI_remlink(lbarray[lba_idx], id);
2114 /* Usual special code for ShapeKeys snowflakes... */
2115 Key *old_key = BKE_key_from_id(id);
2116 if (old_key != nullptr) {
2117 BLI_remlink(which_libbase(bmain, GS(old_key->id.name)), &old_key->id);
2118 }
2119
2121 lapp_context, BKE_id_name(*id), idcode, id);
2122 item->libraries.fill(true);
2123
2124 CLOG_DEBUG(&LOG, "Data-block to seek for: %s", id->name);
2125 }
2126 }
2127 }
2128
2129 if (lapp_context->items.empty()) {
2130 /* Early out in case there is nothing to do. */
2131 return;
2132 }
2133
2135
2136 /* Since some IDs have been removed from Main, trying to rebuild collections hierarchy should not
2137 * happen. It has to be done manually below once removed IDs have been added back to Main. Also
2138 * see #136432. */
2141
2143
2144 /* We do not want any instantiation here! */
2145 BKE_blendfile_link(lapp_context, reports);
2146
2147 BKE_main_lock(bmain);
2148
2149 /* We add back old id to bmain.
2150 * We need to do this in a first, separated loop, otherwise some of those may not be handled by
2151 * ID remapping, which means they would still reference old data to be deleted... */
2152 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
2153 ID *old_id = static_cast<ID *>(item.userdata);
2154
2155 BLI_assert(old_id);
2156 BLI_addtail(which_libbase(bmain, GS(old_id->name)), old_id);
2157
2158 /* Usual special code for ShapeKeys snowflakes... */
2159 Key *old_key = BKE_key_from_id(old_id);
2160 if (old_key != nullptr) {
2161 BLI_addtail(which_libbase(bmain, GS(old_key->id.name)), &old_key->id);
2162 }
2163 }
2164
2165 /* FIXME Temporary 'fix' to a problem in how temp ID are copied in
2166 * `BKE_lib_override_library_main_update`, see #103062.
2167 * Proper fix involves first addressing #90610. */
2169
2170 /* Since our (old) reloaded IDs were removed from main, the user count done for them in linking
2171 * code is wrong, we need to redo it here after adding them back to main. */
2172 BKE_main_id_refcount_recompute(bmain, false);
2173
2174 /* Mapping from old to new libraries, needed to allow liboverride resync to map properly old and
2175 * new data. */
2176 blender::Map<Library *, Library *> new_to_old_libraries_map;
2177
2178 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
2179 ID *old_id = static_cast<ID *>(item.userdata);
2180 ID *new_id = item.new_id;
2181 if (new_id) {
2182 new_to_old_libraries_map.add(new_id->lib, old_id->lib);
2183 }
2184 }
2185
2187
2188 /* Note that in reload case, we also want to replace indirect usages. */
2189 const int remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE |
2190 (do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
2191 blendfile_library_relocate_id_remap(*lapp_context, reports, do_reload, remap_flags);
2192
2195
2196 BKE_main_unlock(bmain);
2197
2198 /* Delete all no more used old IDs. */
2200
2201 /* Update and resync liboverrides of reloaded linked data-blocks. */
2202 blendfile_relocate_postprocess_liboverrides(*lapp_context, new_to_old_libraries_map, reports);
2203
2205}
2206
2208{
2209 if (lapp_context.items.empty()) {
2210 /* Nothing to relocate. */
2211 return;
2212 }
2213 /* Only support relocating one ID at a time currently. */
2214 BLI_assert(lapp_context.items.size() == 1);
2215
2216 Main *bmain = lapp_context.params->bmain;
2217
2218 /* Relocate only works on linked data currently. */
2219 BLI_assert((lapp_context.params->flag & FILE_LINK) != 0);
2220
2221 /* Tag everything, its generally useful to know what is new.
2222 *
2223 * Take extra care `BKE_main_id_flag_all(bmain, ID_TAG_PRE_EXISTING, false)` is called after! */
2225
2226 /* XXX We'd need re-entrant locking on Main for this to work... */
2227 // BKE_main_lock(bmain);
2228
2229 BKE_blendfile_link(&lapp_context, reports);
2230
2231 // BKE_main_unlock(bmain);
2232
2233 /* Finalize relocation (remap ID usages, rebuild LibOverrides if needed, etc.). */
2234
2235 /* Mapping from old to new libraries, needed to allow liboverride resync to map properly old and
2236 * new data. */
2237 blender::Map<Library *, Library *> new_to_old_libraries_map{};
2238
2239 /* The first item should be the root of the relocation, and the only one containing a non-null
2240 * `userdata`. */
2241 BlendfileLinkAppendContextItem &root_item = lapp_context.items.front();
2242 BLI_assert(root_item.userdata);
2243 ID *old_id = static_cast<ID *>(root_item.userdata);
2244 ID *new_id = root_item.new_id;
2245 new_to_old_libraries_map.add(new_id->lib, old_id->lib);
2246 BLI_assert(GS(old_id->name) == GS(new_id->name));
2247#ifndef NDEBUG
2248 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
2249 BLI_assert(&item == &root_item || item.userdata == nullptr);
2250 }
2251#endif
2252
2253 BKE_main_lock(bmain);
2255
2256 /* Do not affect indirect usages. */
2258 blendfile_library_relocate_id_remap(lapp_context, reports, false, remap_flags);
2259
2262 BKE_main_unlock(bmain);
2263
2264 /* Delete all no more used old IDs. */
2266
2267 /* Update and resync liboverrides of reloaded linked data-blocks. */
2268 blendfile_relocate_postprocess_liboverrides(lapp_context, new_to_old_libraries_map, reports);
2269
2271
2272 /* Important we unset, otherwise these object won't
2273 * link into other scenes from this blend file. */
2275}
2276
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:363
bool BKE_idtype_idcode_is_linkable(short idcode)
Definition idtype.cc:197
short BKE_idtype_idcode_iter_step(int *idtype_index)
Definition idtype.cc:373
bool BKE_idtype_idcode_append_is_reusable(short idcode)
Definition idtype.cc:216
Key ** BKE_key_from_id_p(ID *id)
Definition key.cc:1746
Key * BKE_key_from_id(ID *id)
Definition key.cc:1771
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)
@ 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
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:358
void id_sort_by_name(ListBase *lb, ID *id, ID *id_sorting_hint)
Definition lib_id.cc:1790
void id_fake_user_set(ID *id)
Definition lib_id.cc:396
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
Definition lib_id.cc:2001
bool BKE_lib_id_make_local(Main *bmain, ID *id, int flags)
Definition lib_id.cc:598
void id_fake_user_clear(ID *id)
Definition lib_id.cc:404
void id_us_plus_no_lib(ID *id)
Definition lib_id.cc:342
const char * BKE_id_name(const ID &id)
void id_us_min(ID *id)
Definition lib_id.cc:366
void BKE_main_id_refcount_recompute(Main *bmain, bool do_linked_only)
Definition lib_id.cc:2035
void BKE_main_id_tag_all(Main *mainvar, int tag, bool value)
Definition lib_id.cc:1224
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_RET_NOP
@ 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_NOP
void BKE_libblock_remap_multiple_locked(Main *bmain, blender::bke::id::IDRemapper &mappings, const int remap_flags)
Definition lib_remap.cc:655
void BKE_libblock_relink_to_newid(Main *bmain, ID *id, int remap_flag) ATTR_NONNULL()
Definition lib_remap.cc:931
@ ID_REMAP_SKIP_NEVER_NULL_USAGE
@ ID_REMAP_SKIP_INDIRECT_USAGE
void BKE_library_main_rebuild_hierarchy(Main *bmain)
Definition library.cc:328
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:583
MainListsArray BKE_main_lists_get(Main &bmain)
Definition main.cc:987
ListBase * which_libbase(Main *bmain, short type)
Definition main.cc:902
void BKE_main_library_weak_reference_destroy(MainLibraryWeakReferenceMap *library_weak_reference_mapping) ATTR_NONNULL()
Definition main.cc:694
std::array< ListBase *, INDEX_ID_MAX - 1 > MainListsArray
Definition BKE_main.hh:645
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:700
void BKE_main_lock(Main *bmain)
Definition main.cc:486
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:577
MainLibraryWeakReferenceMap * BKE_main_library_weak_reference_create(Main *bmain) ATTR_NONNULL()
Definition main.cc:664
void BKE_main_unlock(Main *bmain)
Definition main.cc:491
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:755
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:709
void BKE_main_ensure_invariants(Main &bmain, std::optional< blender::Span< ID * > > modified_ids=std::nullopt)
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
@ RPT_WARNING
Definition BKE_report.hh:38
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:2858
#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:693
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_SET_OB_ACTIVE_CLIPBOARD
@ 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:5293
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:5037
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:5133
void BLO_readfile_id_runtime_data_free_all(Main &bmain)
Definition readfile.cc:2225
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:188
#define CLOG_DEBUG(clg_ref,...)
Definition CLG_log.h:191
ID and Library types, which are fundamental for SDNA.
#define ID_IS_PACKED(_id)
Definition DNA_ID.h:700
@ ID_TAG_INDIRECT
Definition DNA_ID.h:848
@ ID_TAG_RUNTIME
Definition DNA_ID.h:859
@ ID_TAG_PRE_EXISTING
Definition DNA_ID.h:926
@ ID_TAG_EXTERN
Definition DNA_ID.h:842
@ ID_TAG_MISSING
Definition DNA_ID.h:867
@ ID_TAG_DOIT
Definition DNA_ID.h:1036
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
Definition DNA_ID.h:723
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:694
#define MAX_ID_NAME
Definition DNA_ID.h:373
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:730
#define ID_NEW_SET(_id, _idn)
Definition DNA_ID.h:756
@ ID_FLAG_FAKEUSER
Definition DNA_ID.h:769
@ LIBRARY_FLAG_IS_ARCHIVE
Definition DNA_ID.h:593
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.
@ OB_HIDE_SELECT
@ OB_HIDE_VIEWPORT
#define OB_DATA_SUPPORT_ID(_id_type)
@ OB_EMPTY
@ OB_FLAG_ACTIVE_CLIPBOARD
@ 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.
#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
Value lookup_default(const Key &key, const Value &default_value) const
Definition BLI_map.hh:570
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
Value lookup_default_as(const ForwardKey &key, ForwardValue &&...default_value) const
Definition BLI_map.hh:575
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)
void add(ID *old_id, ID *new_id)
#define GS(x)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define LOG(level)
Definition log.h:97
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
void pack_linked_id_hierarchy(Main &bmain, ID &root_id)
Definition library.cc:658
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
CollectionRuntimeHandle * runtime
struct ID * reference
Definition DNA_ID.h:334
Definition DNA_ID.h:414
int tag
Definition DNA_ID.h:442
struct Library * lib
Definition DNA_ID.h:420
char name[258]
Definition DNA_ID.h:432
int us
Definition DNA_ID.h:443
struct ID * newid
Definition DNA_ID.h:418
IDOverrideLibrary * override_library
Definition DNA_ID.h:494
short flag
Definition DNA_ID.h:438
struct Collection * collection
LibraryForeachIDCallbackFlag cb_flag
char filepath[1024]
Definition DNA_ID.h:552
ID id
Definition DNA_ID.h:550
uint16_t flag
Definition DNA_ID.h:555
LibraryRuntimeHandle * runtime
Definition DNA_ID.h:579
struct Library * archive_parent_library
Definition DNA_ID.h:563
void * link
struct LinkNode * next
void * first
BlendfileLinkAppendContext * lapp_context
ListBase scenes
Definition BKE_main.hh:278
short subversionfile
Definition BKE_main.hh:182
short versionfile
Definition BKE_main.hh:181
ListBase collections
Definition BKE_main.hh:298
Library * curlib
Definition BKE_main.hh:269
ListBase objects
Definition BKE_main.hh:280
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:145