Blender V4.3
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
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
29#include "BLI_blenlib.h"
30#include "BLI_ghash.h"
31#include "BLI_linklist.h"
32#include "BLI_math_vector.h"
33#include "BLI_string_ref.hh"
34#include "BLI_utildefines.h"
35#include "BLI_vector.hh"
36
37#include "BLT_translation.hh"
38
39#include "RNA_access.hh"
40#include "RNA_prototypes.hh"
41
42#include "BKE_callbacks.hh"
44#include "BKE_idtype.hh"
45#include "BKE_key.hh"
46#include "BKE_layer.hh"
47#include "BKE_lib_id.hh"
48#include "BKE_lib_override.hh"
49#include "BKE_lib_query.hh"
50#include "BKE_lib_remap.hh"
51#include "BKE_library.hh"
52#include "BKE_main.hh"
53#include "BKE_main_namemap.hh"
54#include "BKE_material.h"
56#include "BKE_object.hh"
57#include "BKE_report.hh"
58#include "BKE_rigidbody.h"
59#include "BKE_scene.hh"
60
62
63#include "BLO_writefile.hh"
64
65static CLG_LogRef LOG = {"bke.blendfile_link_append"};
66
67/* -------------------------------------------------------------------- */
93
95 BlendfileLinkAppendContext &lapp_context,
97 ReportList *reports)
98{
99 if (reports != nullptr) {
100 lib_context.bf_reports.reports = reports;
101 }
102
103 const blender::StringRefNull libname = lib_context.path;
104 BlendHandle *blo_handle = lib_context.blo_handle;
105 if (blo_handle == nullptr) {
106 if (libname == BLO_EMBEDDED_STARTUP_BLEND) {
107 blo_handle = BLO_blendhandle_from_memory(lapp_context.blendfile_mem,
108 int(lapp_context.blendfile_memsize),
109 &lib_context.bf_reports);
110 }
111 else {
112 blo_handle = BLO_blendhandle_from_file(libname.c_str(), &lib_context.bf_reports);
113 }
114 lib_context.blo_handle = blo_handle;
115 lib_context.blo_handle_is_owned = true;
116 }
117
118 return blo_handle;
119}
120
122 BlendfileLinkAppendContext & /*lapp_context*/, BlendfileLinkAppendContextLibrary &lib_context)
123{
124 if (lib_context.blo_handle_is_owned && lib_context.blo_handle != nullptr) {
126 lib_context.blo_handle = nullptr;
127 }
128}
129
131{
132 BlendfileLinkAppendContext *lapp_context = MEM_new<BlendfileLinkAppendContext>(__func__);
133 lapp_context->params = params;
135 return lapp_context;
136}
137
139{
140 for (BlendfileLinkAppendContextLibrary &lib_context : lapp_context->libraries) {
141 link_append_context_library_blohandle_release(*lapp_context, lib_context);
142 }
143
144 BLI_assert(lapp_context->library_weak_reference_mapping == nullptr);
145
146 MEM_delete(lapp_context);
147}
148
150 const int flag,
151 const bool do_set)
152{
153 if (do_set) {
154 lapp_context->params->flag |= flag;
155 }
156 else {
157 lapp_context->params->flag &= ~flag;
158 }
159}
160
162 BlendfileLinkAppendContext *lapp_context, const void *blendfile_mem, int blendfile_memsize)
163{
164 BLI_assert_msg(lapp_context->blendfile_mem == nullptr,
165 "Please explicitly clear reference to an embedded blender memfile before "
166 "setting a new one");
167 lapp_context->blendfile_mem = blendfile_mem;
168 lapp_context->blendfile_memsize = size_t(blendfile_memsize);
169}
170
172 BlendfileLinkAppendContext *lapp_context)
173{
174 lapp_context->blendfile_mem = nullptr;
175 lapp_context->blendfile_memsize = 0;
176}
177
179 const char *libname,
180 BlendHandle *blo_handle)
181{
182 BLI_assert(lapp_context->items.empty());
184
185 BlendfileLinkAppendContextLibrary lib_context = {};
186
187 lib_context.path = libname;
188 lib_context.blo_handle = blo_handle;
189 /* Always steal the ownership on the blendfile handle, as it may be freed by readfile code in
190 * case of endianness conversion. */
191 lib_context.blo_handle_is_owned = true;
192
193 lapp_context->libraries.append(lib_context);
194}
195
197 BlendfileLinkAppendContext *lapp_context,
198 const char *idname,
199 const short idcode,
200 void *userdata)
201{
203
204 item.lapp_context = lapp_context;
205
206 item.name = idname;
207 item.idcode = idcode;
208 item.libraries = blender::BitVector<>(lapp_context->libraries.size(), false);
209
210 item.new_id = nullptr;
212 item.userdata = userdata;
213
214 lapp_context->items.push_back(item);
215
216 return &lapp_context->items.back();
217}
218
220 BlendfileLinkAppendContext *lapp_context,
221 ReportList *reports,
222 const uint64_t id_types_filter,
223 const int library_index)
224{
226
227 int id_num = 0;
228 int id_code_iter = 0;
229 short id_code;
230
231 BlendfileLinkAppendContextLibrary &lib_context = lapp_context->libraries[library_index];
232 BlendHandle *blo_handle = link_append_context_library_blohandle_ensure(
233 *lapp_context, lib_context, reports);
234
235 if (blo_handle == nullptr) {
237 }
238
239 const bool use_assets_only = (lapp_context->params->flag & FILE_ASSETS_ONLY) != 0;
240
241 while ((id_code = BKE_idtype_idcode_iter_step(&id_code_iter))) {
242 if (!BKE_idtype_idcode_is_linkable(id_code) ||
243 (id_types_filter != 0 && (BKE_idtype_idcode_to_idfilter(id_code) & id_types_filter) == 0))
244 {
245 continue;
246 }
247
248 int id_names_num;
250 blo_handle, id_code, use_assets_only, &id_names_num);
251
252 for (LinkNode *link_next = nullptr; id_names_list != nullptr; id_names_list = link_next) {
253 link_next = id_names_list->next;
254
255 char *id_name = static_cast<char *>(id_names_list->link);
257 lapp_context, id_name, id_code, nullptr);
259 lapp_context, item, library_index);
260
262 MEM_freeN(id_names_list);
263 }
264
265 id_num += id_names_num;
266 }
267
268 return id_num;
269}
270
272 BlendfileLinkAppendContext *lapp_context,
274 const int library_index)
275{
277 UNUSED_VARS_NDEBUG(lapp_context);
278 item->libraries[library_index].set();
279}
280
282{
283 return lapp_context->items.empty();
284}
285
291
299
302 ID *new_id)
303{
305 BLI_assert(item->new_id);
307 BLI_assert(new_id->lib == item->new_id->lib);
308 BLI_assert(!lapp_context->new_id_to_item.contains(new_id));
309
310 lapp_context->new_id_to_item.remove(item->new_id);
311 item->new_id = new_id;
312 lapp_context->new_id_to_item.add(new_id, item);
313}
314
322
328
330 BlendfileLinkAppendContext *lapp_context,
332 BlendfileLinkAppendContextItem *item)> callback_function,
334{
335 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
337 (item.tag & LINK_APPEND_TAG_INDIRECT) == 0)
338 {
339 continue;
340 }
342 (item.tag & LINK_APPEND_TAG_INDIRECT) != 0)
343 {
344 continue;
345 }
346
347 if (!callback_function(lapp_context, &item)) {
348 break;
349 }
350 }
351}
352
354{
356
357 PointerRNA ctx_ptr = RNA_pointer_create(nullptr, &RNA_BlendImportContext, lapp_context);
358 PointerRNA *pointers[1] = {&ctx_ptr};
359 BKE_callback_exec(lapp_context->params->bmain, pointers, 1, BKE_CB_EVT_BLENDIMPORT_PRE);
360}
361
374
377/* -------------------------------------------------------------------- */
382/* Struct gathering all required data to handle instantiation of loose data-blocks. */
385
386 /* The collection in which to add loose collections/objects. */
388};
389
390static bool object_in_any_scene(Main *bmain, Object *ob)
391{
392 LISTBASE_FOREACH (Scene *, sce, &bmain->scenes) {
393 /* #BKE_scene_has_object checks bases cache of the scenes' view-layer, not actual content of
394 * their collections. */
395 if (BKE_collection_has_object_recursive(sce->master_collection, ob)) {
396 return true;
397 }
398 }
399
400 return false;
401}
402
403static bool object_in_any_collection(Main *bmain, Object *ob)
404{
405 LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
406 if (BKE_collection_has_object(collection, ob)) {
407 return true;
408 }
409 }
410
411 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
412 if (scene->master_collection != nullptr &&
413 BKE_collection_has_object(scene->master_collection, ob))
414 {
415 return true;
416 }
417 }
418
419 return false;
420}
421
423{
424 LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
425 if (ob->type == OB_EMPTY && ob->instance_collection == collection) {
426 return true;
427 }
428 }
429 return false;
430}
431
434{
435 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
436 /* In linking case, we always want to handle instantiation. */
437 if (lapp_context->params->flag & FILE_LINK) {
438 return item->new_id;
439 }
440
441 /* We consider that if we either kept it linked, or re-used already local data, instantiation
442 * status of those should not be modified. */
444 return nullptr;
445 }
446
447 ID *id = item->new_id;
448 if (id == nullptr) {
449 return nullptr;
450 }
451
453 return id;
454}
455
457 LooseDataInstantiateContext *instantiate_context)
458{
459
460 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
461 Main *bmain = instantiate_context->lapp_context->params->bmain;
462 Scene *scene = instantiate_context->lapp_context->params->context.scene;
463 ViewLayer *view_layer = instantiate_context->lapp_context->params->context.view_layer;
464
465 /* Find or add collection as needed. When `active_collection` is non-null, it is assumed to be
466 * editable. */
467 if (instantiate_context->active_collection == nullptr) {
468 if (lapp_context->params->flag & FILE_ACTIVE_COLLECTION) {
471 view_layer, lc->collection);
472 }
473 else {
474 if (lapp_context->params->flag & FILE_LINK) {
475 instantiate_context->active_collection = BKE_collection_add(
476 bmain, scene->master_collection, DATA_("Linked Data"));
477 }
478 else {
479 instantiate_context->active_collection = BKE_collection_add(
480 bmain, scene->master_collection, DATA_("Appended Data"));
481 }
482 }
483 }
484}
485
487 Collection *collection,
488 Object *ob,
489 const Scene *scene,
490 ViewLayer *view_layer,
491 const View3D *v3d,
492 const int flag,
493 bool set_active)
494{
495 /* Auto-select and appending. */
496 if ((flag & FILE_AUTOSELECT) && ((flag & FILE_LINK) == 0)) {
497 /* While in general the object should not be manipulated,
498 * when the user requests the object to be selected, ensure it's visible and selectable. */
500 }
501
502 BKE_collection_object_add(bmain, collection, ob);
503 BKE_view_layer_synced_ensure(scene, view_layer);
504 Base *base = BKE_view_layer_base_find(view_layer, ob);
505
506 if (v3d != nullptr) {
507 base->local_view_bits |= v3d->local_view_uid;
508 }
509
510 if (flag & FILE_AUTOSELECT) {
511 /* All objects that use #FILE_AUTOSELECT must be selectable (unless linking data). */
512 BLI_assert((base->flag & BASE_SELECTABLE) || (flag & FILE_LINK));
513 if (base->flag & BASE_SELECTABLE) {
514 base->flag |= BASE_SELECTED;
515 }
516 }
517
518 if (set_active) {
519 view_layer->basact = base;
520 }
521
523}
524
525/* Tag obdata that actually need to be instantiated (those referenced by an object do not, since
526 * the object will be instantiated instead if needed. */
528 LooseDataInstantiateContext *instantiate_context)
529{
530 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
531
532 /* First pass on obdata to enable their instantiation by default, then do a second pass on
533 * objects to clear it for any obdata already in use. */
534 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
535 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
536 if (id == nullptr) {
537 continue;
538 }
539 const ID_Type idcode = GS(id->name);
540 if (!OB_DATA_SUPPORT_ID(idcode)) {
541 continue;
542 }
543 if (idcode == ID_GD_LEGACY) {
544 const bGPdata *legacy_gpd = reinterpret_cast<bGPdata *>(id);
545 if ((legacy_gpd->flag & GP_DATA_ANNOTATIONS) != 0) {
546 continue;
547 }
548 }
549
550 id->tag |= ID_TAG_DOIT;
551 }
552 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
553 ID *id = item.new_id;
554 if (id == nullptr || GS(id->name) != ID_OB) {
555 continue;
556 }
557
558 Object *ob = reinterpret_cast<Object *>(id);
559 Object *new_ob = reinterpret_cast<Object *>(id->newid);
560 if (ob->data != nullptr) {
561 (static_cast<ID *>(ob->data))->tag &= ~ID_TAG_DOIT;
562 }
563 if (new_ob != nullptr && new_ob->data != nullptr) {
564 (static_cast<ID *>(new_ob->data))->tag &= ~ID_TAG_DOIT;
565 }
566 }
567}
568
569/* Test whether some ancestor collection is also tagged for instantiation (return true) or not
570 * (return false). */
572{
573 for (CollectionParent *parent_collection =
574 static_cast<CollectionParent *>(collection->runtime.parents.first);
575 parent_collection != nullptr;
576 parent_collection = parent_collection->next)
577 {
578 if ((parent_collection->collection->id.tag & ID_TAG_DOIT) != 0) {
579 return true;
580 }
581 if (loose_data_instantiate_collection_parents_check_recursive(parent_collection->collection)) {
582 return true;
583 }
584 }
585 return false;
586}
587
589 LooseDataInstantiateContext *instantiate_context)
590{
591 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
592 Main *bmain = lapp_context->params->bmain;
593 Scene *scene = lapp_context->params->context.scene;
594 ViewLayer *view_layer = lapp_context->params->context.view_layer;
595 const View3D *v3d = lapp_context->params->context.v3d;
596
597 const bool do_append = (lapp_context->params->flag & FILE_LINK) == 0;
598 const bool do_instantiate_as_empty = (lapp_context->params->flag &
600
601 /* NOTE: For collections we only view_layer-instantiate duplicated collections that have
602 * non-instantiated objects in them.
603 * NOTE: Also avoid view-layer-instantiating of collections children of other instantiated
604 * collections. This is why we need two passes here. */
605 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
606 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
607 if (id == nullptr || GS(id->name) != ID_GR) {
608 continue;
609 }
610
611 /* Forced instantiation of indirectly appended collections is not wanted. Users can now
612 * easily instantiate collections (and their objects) as needed by themselves. See #67032. */
613 /* We need to check that objects in that collections are already instantiated in a scene.
614 * Otherwise, it's better to add the collection to the scene's active collection, than to
615 * instantiate its objects in active scene's collection directly. See #61141.
616 *
617 * NOTE: We only check object directly into that collection, not recursively into its
618 * children.
619 */
620 Collection *collection = (Collection *)id;
621 /* The collection could be linked/appended together with an Empty object instantiating it,
622 * better not instantiate the collection in the view-layer in that case.
623 *
624 * Can easily happen when copy/pasting such instantiating empty, see #93839. */
625 const bool collection_is_instantiated = collection_instantiated_by_any_object(bmain,
626 collection);
627 /* Always consider adding collections directly selected by the user. */
628 bool do_add_collection = (item.tag & LINK_APPEND_TAG_INDIRECT) == 0 &&
629 !collection_is_instantiated;
630 /* In linking case, do not enforce instantiating non-directly linked collections/objects.
631 * This avoids cluttering the view-layers, user can instantiate themselves specific collections
632 * or objects easily from the Outliner if needed. */
633 if (!do_add_collection && do_append && !collection_is_instantiated) {
634 LISTBASE_FOREACH (CollectionObject *, coll_ob, &collection->gobject) {
635 Object *ob = coll_ob->ob;
636 if (!object_in_any_scene(bmain, ob)) {
637 do_add_collection = true;
638 break;
639 }
640 }
641 }
642 if (do_add_collection) {
643 collection->id.tag |= ID_TAG_DOIT;
644 }
645 }
646
647 /* Second loop to actually instantiate collections tagged as such in first loop, unless some of
648 * their ancestor is also instantiated in case this is not an empty-instantiation. */
649 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
650 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
651 if (id == nullptr || GS(id->name) != ID_GR) {
652 continue;
653 }
654
655 Collection *collection = reinterpret_cast<Collection *>(id);
656 bool do_add_collection = (id->tag & ID_TAG_DOIT) != 0;
657
658 if (!do_add_collection) {
659 continue;
660 }
661 /* When instantiated into view-layer, do not add collections if one of their parents is also
662 * instantiated. */
663 if (!do_instantiate_as_empty &&
665 {
666 continue;
667 }
668 /* When instantiated as empty, do not add indirectly linked (i.e. non-user-selected)
669 * collections. */
670 if (do_instantiate_as_empty && (item.tag & LINK_APPEND_TAG_INDIRECT) != 0) {
671 continue;
672 }
673
675 Collection *active_collection = instantiate_context->active_collection;
676
677 if (do_instantiate_as_empty) {
678 /* BKE_object_add(...) messes with the selection. */
679 Object *ob = BKE_object_add_only_object(bmain, OB_EMPTY, collection->id.name + 2);
680 ob->type = OB_EMPTY;
681 ob->empty_drawsize = U.collection_instance_empty_size;
682
683 const bool set_selected = (lapp_context->params->flag & FILE_AUTOSELECT) != 0;
684 /* TODO: why is it OK to make this active here but not in other situations?
685 * See other callers of #object_base_instance_init */
686 const bool set_active = set_selected;
688 active_collection,
689 ob,
690 scene,
691 view_layer,
692 v3d,
693 lapp_context->params->flag,
694 set_active);
695
696 /* Assign the collection. */
697 ob->instance_collection = collection;
698 id_us_plus(&collection->id);
700 copy_v3_v3(ob->loc, scene->cursor.location);
701 }
702 else {
703 /* Add collection as child of active collection. */
704 BKE_collection_child_add(bmain, active_collection, collection);
705 BKE_view_layer_synced_ensure(scene, view_layer);
706
707 if ((lapp_context->params->flag & FILE_AUTOSELECT) != 0) {
708 LISTBASE_FOREACH (CollectionObject *, coll_ob, &collection->gobject) {
709 Object *ob = coll_ob->ob;
710 Base *base = BKE_view_layer_base_find(view_layer, ob);
711 if (base) {
712 base->flag |= BASE_SELECTED;
714 }
715 }
716 }
717 }
718 }
719}
720
722{
723 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
724 Main *bmain = lapp_context->params->bmain;
725 const Scene *scene = lapp_context->params->context.scene;
726 ViewLayer *view_layer = lapp_context->params->context.view_layer;
727 const View3D *v3d = lapp_context->params->context.v3d;
728
729 /* Do NOT make base active here! screws up GUI stuff,
730 * if you want it do it at the editor level. */
731 const bool object_set_active = false;
732
733 const bool is_linking = (lapp_context->params->flag & FILE_LINK) != 0;
734
735 /* NOTE: For objects we only view_layer-instantiate duplicated objects that are not yet used
736 * anywhere. */
737 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
738 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
739 if (id == nullptr || GS(id->name) != ID_OB) {
740 continue;
741 }
742
743 /* In linking case, never instantiate stray objects that are not directly linked.
744 *
745 * While this is not ideal (in theory no object should remain un-owned), in case of indirectly
746 * linked objects, the other solution would be to add them to a local collection, which would
747 * make them directly linked. Think for now keeping them indirectly linked is more important.
748 * Ref. #93757.
749 */
750 if (is_linking && (item.tag & LINK_APPEND_TAG_INDIRECT) != 0) {
751 continue;
752 }
753
754 Object *ob = (Object *)id;
755
756 if (object_in_any_collection(bmain, ob)) {
757 continue;
758 }
759
761 Collection *active_collection = instantiate_context->active_collection;
762
763 CLAMP_MIN(ob->id.us, 0);
764 ob->mode = OB_MODE_OBJECT;
765
767 active_collection,
768 ob,
769 scene,
770 view_layer,
771 v3d,
772 lapp_context->params->flag,
773 object_set_active);
774 }
775}
776
778{
779 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
780 Main *bmain = lapp_context->params->bmain;
781 Scene *scene = lapp_context->params->context.scene;
782 ViewLayer *view_layer = lapp_context->params->context.view_layer;
783 const View3D *v3d = lapp_context->params->context.v3d;
784
785 /* Do NOT make base active here! screws up GUI stuff,
786 * if you want it do it at the editor level. */
787 const bool object_set_active = false;
788
789 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
790 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
791 if (id == nullptr) {
792 continue;
793 }
794 const ID_Type idcode = GS(id->name);
795 if (!OB_DATA_SUPPORT_ID(idcode)) {
796 continue;
797 }
798 if ((id->tag & ID_TAG_DOIT) == 0) {
799 continue;
800 }
801
803 Collection *active_collection = instantiate_context->active_collection;
804
805 const int type = BKE_object_obdata_to_type(id);
806 BLI_assert(type != -1);
807 Object *ob = BKE_object_add_only_object(bmain, type, id->name + 2);
808 ob->data = id;
809 id_us_plus(id);
810 BKE_object_materials_test(bmain, ob, static_cast<ID *>(ob->data));
811
813 active_collection,
814 ob,
815 scene,
816 view_layer,
817 v3d,
818 lapp_context->params->flag,
819 object_set_active);
820
821 copy_v3_v3(ob->loc, scene->cursor.location);
822
823 id->tag &= ~ID_TAG_DOIT;
824 }
825}
826
828 LooseDataInstantiateContext *instantiate_context)
829{
830 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
831 Main *bmain = lapp_context->params->bmain;
832
833 /* Add rigid body objects and constraints to current RB world(s). */
834 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
835 ID *id = loose_data_instantiate_process_check(instantiate_context, &item);
836 if (id == nullptr || GS(id->name) != ID_OB) {
837 continue;
838 }
839 BKE_rigidbody_ensure_local_object(bmain, reinterpret_cast<Object *>(id));
840 }
841}
842
844{
845 if (instantiate_context->lapp_context->params->context.scene == nullptr) {
846 /* In some cases, like the asset drag&drop e.g., the caller code manages instantiation itself.
847 */
848 return;
849 }
850
851 BlendfileLinkAppendContext *lapp_context = instantiate_context->lapp_context;
852 const bool do_obdata = (lapp_context->params->flag & BLO_LIBLINK_OBDATA_INSTANCE) != 0;
853
854 /* First pass on obdata to enable their instantiation by default, then do a second pass on
855 * objects to clear it for any obdata already in use. */
856 if (do_obdata) {
857 loose_data_instantiate_obdata_preprocess(instantiate_context);
858 }
859
860 /* First do collections, then objects, then obdata. */
862 loose_data_instantiate_object_process(instantiate_context);
863 if (do_obdata) {
864 loose_data_instantiate_obdata_process(instantiate_context);
865 }
866
868}
869
871 ID *id,
873{
874 lapp_context.new_id_to_item.add(id, &item);
875}
876
877/* Generate a mapping between newly linked IDs and their items, and tag linked IDs used as
878 * liboverride references as already existing. */
880{
881 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
882 ID *id = item.new_id;
883 if (id == nullptr) {
884 continue;
885 }
886
887 new_id_to_item_mapping_add(lapp_context, id, item);
888 }
889}
890
891/* All callbacks processing dependencies of an ID for link/append post-processing share a same
892 * common logic to skip some cases. This is factorized in this helper function.
893 *
894 * Returns false if further processing should be skipped. */
897{
900 {
901 return false;
902 }
903
904 ID *id = *cb_data->id_pointer;
905 if (id == nullptr) {
906 return false;
907 }
908 if (!ID_IS_LINKED(id)) {
910 &LOG,
911 "Local ID '%s' found as part of the linked data hierarchy, this should never happen",
912 id->name);
913 return false;
914 }
915
916 if (!BKE_idtype_idcode_is_linkable(GS(id->name))) {
917 /* While we do not want to add non-linkable ID (shape keys...) to the list of linked items,
918 * unfortunately they can use fully linkable valid IDs too, like actions. Those need to be
919 * processed, so we need to recursively deal with them here. */
920 /* NOTE: Since we are by-passing checks in `BKE_library_foreach_ID_link` by manually calling it
921 * recursively, we need to take care of potential recursion cases ourselves (e.g.anim-data of
922 * shape-key referencing the shape-key itself). */
923 /* NOTE: in case both IDs (owner and 'used' ones) are non-linkable, we can assume we can break
924 * the dependency here. Indeed, either they are both linked in another way (through their own
925 * meshes for shape keys e.g.), or this is an unsupported case (two shape-keys depending on
926 * each-other need to be also 'linked' in by their respective meshes, independent shape-keys
927 * are not allowed). ref #96048. */
928 if (id != cb_data->self_id && BKE_idtype_idcode_is_linkable(GS(cb_data->self_id->name))) {
930 }
931 return false;
932 }
933
934 return true;
935}
936
943{
946 {
947 return IDWALK_RET_NOP;
948 }
949 ID *id = *cb_data->id_pointer;
951 static_cast<BlendfileLinkAppendContextCallBack *>(cb_data->user_data);
952
953 /* NOTE: In append case, all dependencies are needed in the items list, to cover potential
954 * complex cases (e.g. linked data from another library referencing other IDs from the */
955
957 id, nullptr);
958 if (item == nullptr) {
960 data->lapp_context, BKE_id_name(*id), GS(id->name), nullptr);
961 item->new_id = id;
962 item->source_library = id->lib;
963 /* Since we did not have an item for that ID yet, we know user did not select it explicitly,
964 * it was rather linked indirectly. This info is important for instantiation of collections.
965 */
968 new_id_to_item_mapping_add(*data->lapp_context, id, *item);
969
970 if ((cb_data->cb_flag & IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE) != 0 ||
971 data->is_liboverride_dependency_only)
972 {
973 /* New item, (currently) detected as only used as a liboverride linked dependency. */
975 }
976 else if (data->is_liboverride_dependency) {
977 /* New item, (currently) detected as used as a liboverride linked dependency, among
978 * others. */
980 }
981 }
982 else {
983 if ((cb_data->cb_flag & IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE) != 0 ||
984 data->is_liboverride_dependency_only)
985 {
986 /* Existing item, here only used as a liboverride reference dependency. If it was not
987 * tagged as such before, it is also used by non-liboverride reference data. */
990 }
991 }
992 else if ((item->tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) != 0) {
993 /* Existing item, here used in a non-liboverride dependency context. If it was
994 * tagged as a liboverride dependency only, its tag and action need to be updated. */
995 item->tag &= ~LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY;
997 }
998 }
999
1000 return IDWALK_RET_NOP;
1001}
1002
1005{
1008 {
1009 return IDWALK_RET_NOP;
1010 }
1011 ID *id = *cb_data->id_pointer;
1013 static_cast<BlendfileLinkAppendContextCallBack *>(cb_data->user_data);
1014
1015 if (!data->item->reusable_local_id) {
1016 return IDWALK_RET_NOP;
1017 }
1018
1020 BLI_assert(item != nullptr);
1021
1022 /* If the currently processed owner ID is not defined as being kept linked, and is using a
1023 * dependency that cannot be reused form local data, then the owner ID should not reuse its
1024 * local data either. */
1025 if (item->action != LINK_APPEND_ACT_KEEP_LINKED && item->reusable_local_id == nullptr) {
1026 BKE_main_library_weak_reference_remove_item(data->lapp_context->library_weak_reference_mapping,
1027 cb_data->owner_id->lib->filepath,
1028 cb_data->owner_id->name,
1029 data->item->reusable_local_id);
1030 data->item->reusable_local_id = nullptr;
1031 }
1032
1033 return IDWALK_RET_NOP;
1034}
1035
1037{
1040 {
1041 return IDWALK_RET_NOP;
1042 }
1043 ID *id = *cb_data->id_pointer;
1045 cb_data->user_data);
1046
1048 BLI_assert(item != nullptr);
1049 BLI_assert(data->item->action == LINK_APPEND_ACT_KEEP_LINKED);
1050
1051 if (item->action == LINK_APPEND_ACT_MAKE_LOCAL) {
1052 CLOG_INFO(&LOG,
1053 3,
1054 "Appended ID '%s' was to be made directly local, but is also used by data that is "
1055 "kept linked, so duplicating it instead.",
1056 id->name);
1058 }
1059 return IDWALK_RET_NOP;
1060}
1061
1063 ReportList *reports)
1064{
1065 Main *bmain = lapp_context.params->bmain;
1066
1067 const bool do_recursive = (lapp_context.params->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0;
1068 const bool do_reuse_local_id = (lapp_context.params->flag & BLO_LIBLINK_APPEND_LOCAL_ID_REUSE) !=
1069 0;
1070
1071 /* In case of non-recursive appending, gather a set of all 'original' libraries (i.e. libraries
1072 * containing data that was explicitly selected by the user). */
1073 blender::Set<Library *> direct_libraries;
1074 if (!do_recursive) {
1075 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1076 ID *id = item.new_id;
1077 if (id == nullptr) {
1078 continue;
1079 }
1080 direct_libraries.add(id->lib);
1081 }
1082 }
1083
1084 /* Add items for all not yet known IDs (i.e. implicitly linked indirect dependencies) to the
1085 * list.
1086 * NOTE: Since items are appended, this list will grow and these IDs will be processed later,
1087 * leading to a flatten recursive processing of all the linked dependencies.
1088 */
1089 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1090 ID *id = item.new_id;
1091 if (id == nullptr) {
1092 continue;
1093 }
1094 BLI_assert(item.reusable_local_id == nullptr);
1095
1096 /* NOTE: handling of reusable local ID info is needed, even if their usage is not requested
1097 * for that append operation:
1098 * - Newly appended data need to get their weak reference, such that it can be reused later
1099 * if requested.
1100 * - Existing appended data may need to get this 'reuse' weak reference cleared, e.g. if a
1101 * new version of it is made local. */
1102 item.reusable_local_id = BKE_idtype_idcode_append_is_reusable(GS(id->name)) ?
1104 lapp_context.library_weak_reference_mapping,
1105 id->lib->filepath,
1106 id->name) :
1107 nullptr;
1108
1110 cb_data.lapp_context = &lapp_context;
1111 cb_data.item = &item;
1112 cb_data.reports = reports;
1113 cb_data.is_liboverride_dependency = (item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) != 0;
1114 cb_data.is_liboverride_dependency_only = (item.tag &
1118 }
1119
1120 /* At this point, linked IDs that should remain linked can already be defined as such:
1121 * - In case of non-recursive appending, IDs from other libraries.
1122 * - IDs only used as liboverride references. */
1123 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1124 /* These tags should have been set in above loop, here they can be check for validity (they
1125 * are mutually exclusive). */
1126 BLI_assert(
1127 (item.tag &
1130
1131 ID *id = item.new_id;
1132 if (id == nullptr) {
1133 continue;
1134 }
1135 /* IDs exclusively used as liboverride reference should not be made local at all. */
1136 if ((item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY) != 0) {
1137 CLOG_INFO(
1138 &LOG,
1139 3,
1140 "Appended ID '%s' is only used as a liboverride linked dependency, keeping it linked.",
1141 id->name);
1142 item.action = LINK_APPEND_ACT_KEEP_LINKED;
1143 item.reusable_local_id = nullptr;
1144 }
1145 /* In non-recursive append case, only IDs from the same libraries as the directly appended
1146 * ones are made local. All dependencies from other libraries are kept linked. */
1147 if (!do_recursive && !direct_libraries.contains(id->lib)) {
1148 CLOG_INFO(&LOG,
1149 3,
1150 "Appended ID '%s' belongs to another library and recursive append is disabled, "
1151 "keeping it linked.",
1152 id->name);
1153 item.action = LINK_APPEND_ACT_KEEP_LINKED;
1154 item.reusable_local_id = nullptr;
1155 }
1156 }
1157
1158 /* The reusable local IDs can cause severe issues in hierarchies of appended data. If an ID
1159 * user e.g. still has a local reusable ID found, but one of its dependencies does not (i.e.
1160 * either there were some changes in the library data, or the previously appended local
1161 * dependencies was modified in current file and therefore cannot be re-used anymore), then the
1162 * user ID should not be considered as usable either. */
1163 /* TODO: This process is currently fairly raw and inefficient. This is likely not a
1164 * (significant) issue currently anyway. But would be good to refactor this whole code to use
1165 * modern CPP containers (list of items could be an `std::deque` e.g., to be iterable in both
1166 * directions). Being able to loop backward here (i.e. typically process the dependencies
1167 * before the user IDs) could avoid a lot of iterations. */
1168 for (bool keep_looping = do_reuse_local_id; keep_looping;) {
1169 keep_looping = false;
1170 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1171 ID *id = item.new_id;
1172 if (id == nullptr) {
1173 continue;
1174 }
1175 if (!item.reusable_local_id) {
1176 continue;
1177 }
1179 cb_data.lapp_context = &lapp_context;
1180 cb_data.item = &item;
1181 cb_data.reports = reports;
1182 cb_data.is_liboverride_dependency = (item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) != 0;
1183 cb_data.is_liboverride_dependency_only = (item.tag &
1186 id,
1188 &cb_data,
1189 IDWALK_NOP);
1190 if (!item.reusable_local_id) {
1191 /* If some reusable ID was cleared, another loop over all items is needed to potentially
1192 * propagate this change higher in the dependency hierarchy. */
1193 keep_looping = true;
1194 }
1195 }
1196 }
1197
1198 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1199 ID *id = item.new_id;
1200 if (id == nullptr) {
1201 continue;
1202 }
1203
1204 if (item.action != LINK_APPEND_ACT_UNSET) {
1205 /* Already set, pass. */
1207 continue;
1208 }
1210
1211 if (do_reuse_local_id && item.reusable_local_id != nullptr) {
1212 CLOG_INFO(&LOG, 3, "Appended ID '%s' as a matching local one, re-using it.", id->name);
1213 item.action = LINK_APPEND_ACT_REUSE_LOCAL;
1214 }
1215 else if (id->tag & ID_TAG_PRE_EXISTING) {
1216 CLOG_INFO(&LOG, 3, "Appended ID '%s' was already linked, duplicating it.", id->name);
1217 item.action = LINK_APPEND_ACT_COPY_LOCAL;
1218 }
1219 else if (item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) {
1220 CLOG_INFO(
1221 &LOG,
1222 3,
1223 "Appended ID '%s' is also used as a liboverride linked dependency, duplicating it.",
1224 id->name);
1225 item.action = LINK_APPEND_ACT_COPY_LOCAL;
1226 }
1227 else {
1228 /* That last action, making linked data directly local, can still be changed to
1229 * #LINK_APPEND_ACT_COPY_LOCAL in the last checks below. This can happen in rare cases with
1230 * complex relationships involving IDs that are kept linked and IDs that are made local,
1231 * both using some same dependencies. */
1232 CLOG_INFO(&LOG, 3, "Appended ID '%s' will be made local.", id->name);
1233 item.action = LINK_APPEND_ACT_MAKE_LOCAL;
1234 }
1235 }
1236
1237 /* Some linked IDs marked to be made directly local may also be used by other items
1238 * marked to be kept linked. in such case, they need to be copied for the local data, such that
1239 * a linked version of these remains available as dependency for other linked data. */
1240 for (BlendfileLinkAppendContextItem &item : lapp_context.items) {
1241 ID *id = item.new_id;
1242 if (id == nullptr) {
1243 continue;
1244 }
1245
1246 /* Only IDs kept as linked need to be checked here. */
1247 if (item.action == LINK_APPEND_ACT_KEEP_LINKED) {
1249 cb_data.lapp_context = &lapp_context;
1250 cb_data.item = &item;
1251 cb_data.reports = reports;
1252 cb_data.is_liboverride_dependency = (item.tag & LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) != 0;
1253 cb_data.is_liboverride_dependency_only = (item.tag &
1257 }
1258
1259 /* If we found a matching existing local id but are not re-using it, we need to properly
1260 * clear its weak reference to linked data. */
1261 if (item.reusable_local_id != nullptr &&
1263 {
1264 BLI_assert_msg(!do_reuse_local_id,
1265 "This code should only be reached when the current append operation does not "
1266 "try to reuse local data.");
1268 id->lib->filepath,
1269 id->name,
1270 item.reusable_local_id);
1271 item.reusable_local_id = nullptr;
1272 }
1273 }
1274}
1275
1277{
1280
1281 if (lapp_context->items.empty()) {
1282 /* Nothing to append. */
1283 return;
1284 }
1285
1286 Main *bmain = lapp_context->params->bmain;
1287
1288 BLI_assert((lapp_context->params->flag & FILE_LINK) == 0);
1289
1290 const bool set_fakeuser = (lapp_context->params->flag & BLO_LIBLINK_APPEND_SET_FAKEUSER) != 0;
1291
1292 const int make_local_common_flags =
1294 ((lapp_context->params->flag & BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR) != 0 ?
1296 0) |
1297 /* In recursive case (i.e. everything becomes local), clear liboverrides. Otherwise (i.e.
1298 * only data from immediately linked libraries is made local), preserve liboverrides. */
1299 ((lapp_context->params->flag & BLO_LIBLINK_APPEND_RECURSIVE) != 0 ?
1301 0);
1302
1303 new_id_to_item_mapping_create(*lapp_context);
1305
1306 /* Add missing items (the indirectly linked ones), and carefully define which action should be
1307 * applied to each of them. */
1308 blendfile_append_define_actions(*lapp_context, reports);
1309
1310 /* Effectively perform required operation on every linked ID. */
1311 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1312 ID *id = item.new_id;
1313 if (id == nullptr) {
1314 continue;
1315 }
1316
1317 ID *local_appended_new_id = nullptr;
1318 char lib_filepath[FILE_MAX];
1319 STRNCPY(lib_filepath, id->lib->filepath);
1320 char lib_id_name[MAX_ID_NAME];
1321 STRNCPY(lib_id_name, id->name);
1322
1323 switch (item.action) {
1325 BKE_lib_id_make_local(bmain, id, make_local_common_flags | LIB_ID_MAKELOCAL_FORCE_COPY);
1326 local_appended_new_id = id->newid;
1327 break;
1329 BKE_lib_id_make_local(bmain, id, make_local_common_flags | LIB_ID_MAKELOCAL_FORCE_LOCAL);
1330 BLI_assert(id->newid == nullptr);
1331 local_appended_new_id = id;
1332 break;
1334 /* Nothing to do here. */
1335 break;
1337 BLI_assert(item.reusable_local_id != nullptr);
1338 /* We only need to set `newid` to ID found in previous loop, for proper remapping. */
1339 ID_NEW_SET(id, item.reusable_local_id);
1340 /* This is not a 'new' local appended id, do not set `local_appended_new_id` here. */
1341 break;
1343 CLOG_ERROR(
1344 &LOG, "Unexpected unset append action for '%s' ID, assuming 'keep link'", id->name);
1345 break;
1346 default:
1348 }
1349
1350 if (local_appended_new_id != nullptr) {
1351 if (BKE_idtype_idcode_append_is_reusable(GS(local_appended_new_id->name))) {
1353 lib_filepath,
1354 lib_id_name,
1355 local_appended_new_id);
1356 }
1357
1358 if (set_fakeuser) {
1359 if (!ELEM(GS(local_appended_new_id->name), ID_OB, ID_GR)) {
1360 /* Do not set fake user on objects nor collections (instancing). */
1361 id_fake_user_set(local_appended_new_id);
1362 }
1363 }
1364 }
1365 }
1366
1368 lapp_context->library_weak_reference_mapping = nullptr;
1369
1370 /* Remap IDs as needed. */
1371 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1372 if (item.action == LINK_APPEND_ACT_KEEP_LINKED) {
1373 continue;
1374 }
1375
1376 ID *id = item.new_id;
1377 if (id == nullptr) {
1378 continue;
1379 }
1382 id = id->newid;
1383 if (id == nullptr) {
1384 continue;
1385 }
1386 }
1387
1389
1390 BKE_libblock_relink_to_newid(bmain, id, 0);
1391 }
1392
1393 /* Remove linked IDs when a local existing data has been reused instead. */
1394 BKE_main_id_tag_all(bmain, ID_TAG_DOIT, false);
1395 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1397 continue;
1398 }
1399
1400 ID *id = item.new_id;
1401 if (id == nullptr) {
1402 continue;
1403 }
1405 BLI_assert(id->newid != nullptr);
1406
1407 /* Calling code may want to access newly appended IDs from the link/append context items. */
1408 item.new_id = id->newid;
1409
1410 /* Only the 'reuse local' action should leave unused newly linked data behind. */
1411 if (item.action != LINK_APPEND_ACT_REUSE_LOCAL) {
1412 continue;
1413 }
1414 /* Do NOT delete a linked data that was already linked before this append. */
1415 if (id->tag & ID_TAG_PRE_EXISTING) {
1416 continue;
1417 }
1418 /* Do NOT delete a linked data that is (also) used a liboverride dependency. */
1421 continue;
1422 }
1423
1424 id->tag |= ID_TAG_DOIT;
1425 }
1427
1429
1430 BlendFileReadReport bf_reports{};
1431 bf_reports.reports = reports;
1432 BLO_read_do_version_after_setup(bmain, lapp_context, &bf_reports);
1433}
1434
1441{
1443 {
1444 return IDWALK_RET_NOP;
1445 }
1446 ID *id = *cb_data->id_pointer;
1448 static_cast<BlendfileLinkAppendContextCallBack *>(cb_data->user_data);
1449
1450 if ((id->tag & ID_TAG_PRE_EXISTING) != 0) {
1451 /* About to re-use a linked data that was already there, and that will stay linked. This case
1452 * does not need any further processing of the child hierarchy (existing linked data
1453 * instantiation status should not be modified here). */
1454 return IDWALK_RET_NOP;
1455 }
1456
1457 /* In linking case, all linked IDs are considered for instantiation, including from other
1458 * libraries. So all linked IDs that were not skipped so far need to be added to the items
1459 * list.
1460 */
1462 id, nullptr);
1463 /* NOTE: liboverride info (tags like #LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY) can be
1464 * ignored/skipped here, since all data are kept linked anyway, they are not useful currently.
1465 */
1466 if (item == nullptr) {
1468 data->lapp_context, BKE_id_name(*id), GS(id->name), nullptr);
1469 item->new_id = id;
1470 item->source_library = id->lib;
1471 /* Since there is no item for that ID yet, the user did not select it explicitly, it was
1472 * rather linked indirectly. This info is important for instantiation of collections. */
1474 /* In linking case we already know what we want to do with these items. */
1476 new_id_to_item_mapping_add(*data->lapp_context, id, *item);
1477 }
1478 return IDWALK_RET_NOP;
1479}
1480
1482 ReportList *reports)
1483{
1484 BLI_assert(ELEM(lapp_context->process_stage,
1488
1489 if (!lapp_context->params->context.scene) {
1490 return;
1491 }
1492 if (lapp_context->params->flag & FILE_LINK) {
1493 new_id_to_item_mapping_create(*lapp_context);
1494 /* Add items for all not yet known IDs (i.e. implicitly linked indirect dependencies) to the
1495 * list.
1496 * NOTE: Since items are appended to the list, this list will grow and these IDs will be
1497 * processed later, leading to a flatten recursive processing of all the linked dependencies.
1498 */
1499 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1500 ID *id = item.new_id;
1501 if (id == nullptr) {
1502 continue;
1503 }
1504 BLI_assert(item.userdata == nullptr);
1505
1507 cb_data.lapp_context = lapp_context;
1508 cb_data.item = &item;
1509 cb_data.reports = reports;
1511 id,
1513 &cb_data,
1514 IDWALK_NOP);
1515 }
1516 }
1517
1518 LooseDataInstantiateContext instantiate_context{};
1519 instantiate_context.lapp_context = lapp_context;
1520 instantiate_context.active_collection = nullptr;
1521 loose_data_instantiate(&instantiate_context);
1522}
1523
1525{
1528
1529 if (lapp_context->items.empty()) {
1530 /* Nothing to be linked. */
1531 return;
1532 }
1533
1534 BLI_assert(!lapp_context->libraries.is_empty());
1535
1536 Main *mainl;
1537 Library *lib;
1538
1539 for (const int lib_idx : lapp_context->libraries.index_range()) {
1540 BlendfileLinkAppendContextLibrary &lib_context = lapp_context->libraries[lib_idx];
1541 const char *libname = lib_context.path.c_str();
1542
1543 if (!link_append_context_library_blohandle_ensure(*lapp_context, lib_context, reports)) {
1544 /* Unlikely since we just browsed it, but possible
1545 * Error reports will have been made by BLO_blendhandle_from_file() */
1546 continue;
1547 }
1548
1549 /* here appending/linking starts */
1550
1551 mainl = BLO_library_link_begin(&lib_context.blo_handle, libname, lapp_context->params);
1552 lib = mainl->curlib;
1553 BLI_assert(lib != nullptr);
1554 /* In case lib was already existing but not found originally, see #99820. */
1555 lib->id.tag &= ~ID_TAG_MISSING;
1556
1557 if (mainl->versionfile < 250) {
1558 BKE_reportf(reports,
1560 "Linking or appending from a very old .blend file format (%d.%d), no animation "
1561 "conversion will "
1562 "be done! You may want to re-save your lib file with current Blender",
1563 mainl->versionfile,
1564 mainl->subversionfile);
1565 }
1566
1567 /* For each lib file, we try to link all items belonging to that lib,
1568 * and tag those successful to not try to load them again with the other libraries. */
1569 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1570 ID *new_id;
1571
1572 if (!item.libraries[lib_idx]) {
1573 continue;
1574 }
1575
1577 mainl, &lib_context.blo_handle, item.idcode, item.name.c_str(), lapp_context->params);
1578
1579 if (new_id) {
1580 /* If the link is successful, clear item's libraries 'todo' flags.
1581 * This avoids trying to link same item with other libraries to come. */
1582 item.libraries.fill(false);
1583 item.new_id = new_id;
1584 item.source_library = new_id->lib;
1585 }
1586 }
1587
1588 BLO_library_link_end(mainl, &lib_context.blo_handle, lapp_context->params);
1589 link_append_context_library_blohandle_release(*lapp_context, lib_context);
1590 }
1591
1592 /* In linking case finalizing process (ensuring all data is valid, instantiating loose
1593 * collections or objects, etc.) can be done here directly.
1594 *
1595 * In append case, the finalizing process is much more complex and requires and additional call
1596 * to #BKE_blendfile_append for caller code. */
1597 if (lapp_context->params->flag & FILE_LINK) {
1598 BlendFileReadReport bf_reports{};
1599 bf_reports.reports = reports;
1600 BLO_read_do_version_after_setup(lapp_context->params->bmain, lapp_context, &bf_reports);
1601 }
1602}
1603
1605 const eBKELibLinkOverride flags,
1606 ReportList * /*reports*/)
1607{
1608 if (lapp_context->items.empty()) {
1609 /* Nothing to override. */
1610 return;
1611 }
1612
1613 Main *bmain = lapp_context->params->bmain;
1614
1615 /* Liboverride only makes sense if data was linked, not appended. */
1616 BLI_assert((lapp_context->params->flag & FILE_LINK) != 0);
1617
1618 const bool set_runtime = (flags & BKE_LIBLINK_OVERRIDE_CREATE_RUNTIME) != 0;
1619 const bool do_use_exisiting_liboverrides = (flags &
1621
1622 blender::Map<ID *, ID *> linked_ids_to_local_liboverrides;
1623 if (do_use_exisiting_liboverrides) {
1624 ID *id_iter;
1625 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
1626 if (ID_IS_LINKED(id_iter)) {
1627 continue;
1628 }
1629 if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_iter)) {
1630 continue;
1631 }
1632 /* Do not consider regular liboverrides if runtime ones are requested, and vice-versa. */
1633 if ((set_runtime && (id_iter->tag & ID_TAG_RUNTIME) == 0) ||
1634 (!set_runtime && (id_iter->tag & ID_TAG_RUNTIME) != 0))
1635 {
1636 continue;
1637 }
1638
1639 /* In case several liboverrides exist of the same data, only consider the first found one, so
1640 * don't use `add_overwrite`. */
1641 linked_ids_to_local_liboverrides.add(id_iter->override_library->reference, id_iter);
1642 }
1644 }
1645
1646 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1647 ID *id = item.new_id;
1648 if (id == nullptr) {
1649 continue;
1650 }
1651 BLI_assert(item.userdata == nullptr);
1652
1653 if (do_use_exisiting_liboverrides) {
1654 item.liboverride_id = linked_ids_to_local_liboverrides.lookup_default(id, nullptr);
1655 }
1656 if (item.liboverride_id == nullptr) {
1657 item.liboverride_id = BKE_lib_override_library_create_from_id(bmain, id, false);
1658 if (set_runtime) {
1659 item.liboverride_id->tag |= ID_TAG_RUNTIME;
1660 if ((id->tag & ID_TAG_PRE_EXISTING) == 0) {
1661 /* If the linked ID is newly linked, in case its override is runtime-only, assume its
1662 * reference to be indirectly linked.
1663 *
1664 * This is more of an heuristic for 'as best as possible' user feedback in the UI
1665 * (Outliner), which is expected to be valid in almost all practical use-cases. Direct or
1666 * indirect linked status is properly checked before saving .blend file. */
1667 id->tag &= ~ID_TAG_EXTERN;
1668 id->tag |= ID_TAG_INDIRECT;
1669 }
1670 }
1671 }
1672 }
1673
1675}
1676
1683 ID *old_id,
1684 ID *new_id,
1685 ReportList *reports,
1686 const bool do_reload,
1687 const int remap_flags)
1688{
1689 BLI_assert(old_id);
1690 if (do_reload) {
1691 /* Since we asked for placeholders in case of missing IDs,
1692 * we expect to always get a valid one. */
1693 BLI_assert(new_id);
1694 }
1695 if (new_id) {
1696 CLOG_INFO(&LOG,
1697 4,
1698 "Before remap of %s, old_id users: %d, new_id users: %d",
1699 old_id->name,
1700 old_id->us,
1701 new_id->us);
1702 BKE_libblock_remap_locked(bmain, old_id, new_id, remap_flags);
1703
1704 if (old_id->flag & ID_FLAG_FAKEUSER) {
1705 id_fake_user_clear(old_id);
1706 id_fake_user_set(new_id);
1707 }
1708
1709 CLOG_INFO(&LOG,
1710 4,
1711 "After remap of %s, old_id users: %d, new_id users: %d",
1712 old_id->name,
1713 old_id->us,
1714 new_id->us);
1715
1716 /* In some cases, new_id might become direct link, remove parent of library in this case. */
1717 if (new_id->lib->runtime.parent && (new_id->tag & ID_TAG_INDIRECT) == 0) {
1718 if (do_reload) {
1719 BLI_assert_unreachable(); /* Should not happen in 'pure' reload case... */
1720 }
1721 new_id->lib->runtime.parent = nullptr;
1722 }
1723 }
1724
1725 if (old_id->us > 0 && new_id && old_id->lib == new_id->lib) {
1726 /* Note that this *should* not happen - but better be safe than sorry in this area,
1727 * at least until we are 100% sure this cannot ever happen.
1728 * Also, we can safely assume names were unique so far,
1729 * so just replacing '.' by '~' should work,
1730 * but this does not totally rules out the possibility of name collision. */
1731 size_t len = strlen(old_id->name);
1732 size_t dot_pos;
1733 bool has_num = false;
1734
1735 for (dot_pos = len; dot_pos--;) {
1736 char c = old_id->name[dot_pos];
1737 if (c == '.') {
1738 break;
1739 }
1740 if (c < '0' || c > '9') {
1741 has_num = false;
1742 break;
1743 }
1744 has_num = true;
1745 }
1746
1747 if (has_num) {
1748 old_id->name[dot_pos] = '~';
1749 }
1750 else {
1751 len = std::min<size_t>(len, MAX_ID_NAME - 7);
1752 BLI_strncpy(&old_id->name[len], "~000", 7);
1753 }
1754
1755 id_sort_by_name(which_libbase(bmain, GS(old_id->name)), old_id, nullptr);
1756
1758 reports,
1760 "Lib Reload: Replacing all references to old data-block '%s' by reloaded one failed, "
1761 "old one (%d remaining users) had to be kept and was renamed to '%s'",
1762 new_id->name,
1763 old_id->us,
1764 old_id->name);
1765 }
1766}
1767
1769 ReportList *reports,
1770 Library *library,
1771 const bool do_reload)
1772{
1773 ListBase *lbarray[INDEX_ID_MAX];
1774 int lba_idx;
1775
1776 Main *bmain = lapp_context->params->bmain;
1777
1778 /* All override rules need to be up to date, since there will be no do_version here, otherwise
1779 * older, now-invalid rules might be applied and likely fail, or some changes might be missing,
1780 * etc. See #93353. */
1782
1783 /* Remove all IDs to be reloaded from Main. */
1784 lba_idx = set_listbasepointers(bmain, lbarray);
1785 while (lba_idx--) {
1786 ID *id = static_cast<ID *>(lbarray[lba_idx]->first);
1787 const short idcode = id ? GS(id->name) : 0;
1788
1789 if (!id || !BKE_idtype_idcode_is_linkable(idcode)) {
1790 /* No need to reload non-linkable data-types,
1791 * those will get relinked with their 'users ID'. */
1792 continue;
1793 }
1794
1795 for (; id; id = static_cast<ID *>(id->next)) {
1796 if (id->lib == library) {
1798
1799 /* We remove it from current Main, and add it to items to link... */
1800 /* Note that non-linkable IDs (like e.g. shape-keys) are also explicitly linked here... */
1801 BLI_remlink(lbarray[lba_idx], id);
1802 /* Usual special code for ShapeKeys snowflakes... */
1803 Key *old_key = BKE_key_from_id(id);
1804 if (old_key != nullptr) {
1805 BLI_remlink(which_libbase(bmain, GS(old_key->id.name)), &old_key->id);
1806 }
1807
1809 lapp_context, BKE_id_name(*id), idcode, id);
1810 item->libraries.fill(true);
1811
1812 CLOG_INFO(&LOG, 4, "Datablock to seek for: %s", id->name);
1813 }
1814 }
1815 }
1816
1817 if (lapp_context->items.empty()) {
1818 /* Early out in case there is nothing to do. */
1819 return;
1820 }
1821
1823
1825
1826 /* We do not want any instantiation here! */
1827 BKE_blendfile_link(lapp_context, reports);
1828
1829 BKE_main_lock(bmain);
1830
1831 /* We add back old id to bmain.
1832 * We need to do this in a first, separated loop, otherwise some of those may not be handled by
1833 * ID remapping, which means they would still reference old data to be deleted... */
1834 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1835 ID *old_id = static_cast<ID *>(item.userdata);
1836
1837 BLI_assert(old_id);
1838 BLI_addtail(which_libbase(bmain, GS(old_id->name)), old_id);
1839
1840 /* Usual special code for ShapeKeys snowflakes... */
1841 Key *old_key = BKE_key_from_id(old_id);
1842 if (old_key != nullptr) {
1843 BLI_addtail(which_libbase(bmain, GS(old_key->id.name)), &old_key->id);
1844 }
1845 }
1846
1847 /* Since our (old) reloaded IDs were removed from main, the user count done for them in linking
1848 * code is wrong, we need to redo it here after adding them back to main. */
1849 BKE_main_id_refcount_recompute(bmain, false);
1850
1852 /* Note that in reload case, we also want to replace indirect usages. */
1853 const int remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE |
1854 (do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
1855 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1856 ID *old_id = static_cast<ID *>(item.userdata);
1857 ID *new_id = item.new_id;
1858
1859 blendfile_library_relocate_remap(bmain, old_id, new_id, reports, do_reload, remap_flags);
1860 if (new_id == nullptr) {
1861 continue;
1862 }
1863 /* Usual special code for ShapeKeys snowflakes... */
1864 Key **old_key_p = BKE_key_from_id_p(old_id);
1865 if (old_key_p == nullptr) {
1866 continue;
1867 }
1868 Key *old_key = *old_key_p;
1869 Key *new_key = BKE_key_from_id(new_id);
1870 if (old_key != nullptr) {
1871 *old_key_p = nullptr;
1872 id_us_min(&old_key->id);
1874 bmain, &old_key->id, &new_key->id, reports, do_reload, remap_flags);
1875 *old_key_p = old_key;
1876 id_us_plus_no_lib(&old_key->id);
1877 }
1878 }
1881
1882 BKE_main_unlock(bmain);
1883
1884 /* Delete all no more used old IDs. */
1885 /* NOTE: While this looping over until we are sure we deleted everything is very far from
1886 * efficient, doing otherwise would require a much more complex handling of indirectly linked IDs
1887 * in steps above. Currently, in case of relocation, those are skipped in remapping phase, though
1888 * in some cases (essentially internal links between IDs from the same library) remapping should
1889 * happen. But getting this to work reliably would be very difficult, so since this is not a
1890 * performance-critical code, better to go with the (relatively) simpler, brute-force approach
1891 * here in 'removal of old IDs' step. */
1892 bool keep_looping = true;
1893 while (keep_looping) {
1894 keep_looping = false;
1895
1896 BKE_main_id_tag_all(bmain, ID_TAG_DOIT, false);
1897 for (BlendfileLinkAppendContextItem &item : lapp_context->items) {
1898 ID *old_id = static_cast<ID *>(item.userdata);
1899
1900 if (old_id == nullptr) {
1901 continue;
1902 }
1903
1904 if (GS(old_id->name) == ID_KE) {
1905 /* Shape Keys are handled as part of their owning obdata (see below). This implies that
1906 * there is no way to know when the old pointer gets invalid, so just clear it immediately.
1907 */
1908 item.userdata = nullptr;
1909 continue;
1910 }
1911
1912 /* In case the active scene was reloaded, the context pointers in
1913 * `lapp_context->params->context` need to be updated before the old Scene ID is freed. */
1914 if (old_id == &lapp_context->params->context.scene->id) {
1915 BLI_assert(GS(old_id->name) == ID_SCE);
1916 Scene *new_scene = reinterpret_cast<Scene *>(item.new_id);
1917 BLI_assert(new_scene != nullptr);
1918 lapp_context->params->context.scene = new_scene;
1919 if (lapp_context->params->context.view_layer != nullptr) {
1920 ViewLayer *new_view_layer = BKE_view_layer_find(
1921 new_scene, lapp_context->params->context.view_layer->name);
1922 lapp_context->params->context.view_layer = static_cast<ViewLayer *>(
1923 (new_view_layer != nullptr) ? new_view_layer : new_scene->view_layers.first);
1924 }
1925 /* lapp_context->params->context.v3d should never become invalid by newly linked data here.
1926 */
1927 }
1928
1929 if (old_id->us == 0) {
1930 old_id->tag |= ID_TAG_DOIT;
1931 item.userdata = nullptr;
1932 keep_looping = true;
1933 Key *old_key = BKE_key_from_id(old_id);
1934 if (old_key != nullptr) {
1935 old_key->id.tag |= ID_TAG_DOIT;
1936 }
1937 }
1938 }
1940 /* Should not be needed, all tagged IDs should have been deleted above, just 'in case'. */
1941 BKE_main_id_tag_all(bmain, ID_TAG_DOIT, false);
1942 }
1943
1944 /* Some datablocks can get reloaded/replaced 'silently' because they are not linkable
1945 * (shape keys e.g.), so we need another loop here to clear old ones if possible. */
1946 lba_idx = set_listbasepointers(bmain, lbarray);
1947 while (lba_idx--) {
1948 ID *id, *id_next;
1949 for (id = static_cast<ID *>(lbarray[lba_idx]->first); id; id = id_next) {
1950 id_next = static_cast<ID *>(id->next);
1951 /* XXX That check may be a bit to generic/permissive? */
1952 if (id->lib && (id->flag & ID_TAG_PRE_EXISTING) && id->us == 0) {
1953 BKE_id_free(bmain, id);
1954 }
1955 }
1956 }
1957
1958 /* Get rid of no more used libraries... */
1960 lba_idx = set_listbasepointers(bmain, lbarray);
1961 while (lba_idx--) {
1962 ID *id;
1963 for (id = static_cast<ID *>(lbarray[lba_idx]->first); id; id = static_cast<ID *>(id->next)) {
1964 if (id->lib) {
1965 id->lib->id.tag &= ~ID_TAG_DOIT;
1966 }
1967 }
1968 }
1969 Library *lib, *lib_next;
1970 for (lib = static_cast<Library *>(which_libbase(bmain, ID_LI)->first); lib; lib = lib_next) {
1971 lib_next = static_cast<Library *>(lib->id.next);
1972 if (lib->id.tag & ID_TAG_DOIT) {
1973 id_us_clear_real(&lib->id);
1974 if (lib->id.us == 0) {
1975 BKE_id_delete(bmain, lib);
1976 }
1977 }
1978 }
1979
1980 /* Update overrides of reloaded linked data-blocks. */
1981 ID *id;
1982 FOREACH_MAIN_ID_BEGIN (bmain, id) {
1983 if (ID_IS_LINKED(id) || !ID_IS_OVERRIDE_LIBRARY_REAL(id) ||
1984 (id->tag & ID_TAG_PRE_EXISTING) == 0)
1985 {
1986 continue;
1987 }
1988 if ((id->override_library->reference->tag & ID_TAG_MISSING) == 0) {
1989 id->tag &= ~ID_TAG_MISSING;
1990 }
1991 if ((id->override_library->reference->tag & ID_TAG_PRE_EXISTING) == 0) {
1993 }
1994 }
1996
1998
1999 /* Resync overrides if needed. */
2000 if (!USER_EXPERIMENTAL_TEST(&U, no_override_auto_resync) &&
2001 lapp_context->params->context.scene != nullptr)
2002 {
2003 BlendFileReadReport report{};
2004 report.reports = reports;
2006 lapp_context->params->context.scene,
2007 lapp_context->params->context.view_layer,
2008 &report);
2009 /* We need to rebuild some of the deleted override rules (for UI feedback purpose). */
2011 }
2012
2014}
2015
void BKE_callback_exec(Main *bmain, PointerRNA **pointers, int num_pointers, eCbEvent evt)
Definition callbacks.cc:28
@ BKE_CB_EVT_BLENDIMPORT_POST
@ BKE_CB_EVT_BLENDIMPORT_PRE
bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
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)
bool BKE_collection_object_add(Main *bmain, Collection *collection, Object *ob)
uint64_t BKE_idtype_idcode_to_idfilter(short idcode)
Definition idtype.cc:369
bool BKE_idtype_idcode_is_linkable(short idcode)
Definition idtype.cc:201
short BKE_idtype_idcode_iter_step(int *idtype_index)
Definition idtype.cc:379
bool BKE_idtype_idcode_append_is_reusable(short idcode)
Definition idtype.cc:220
Key ** BKE_key_from_id_p(ID *id)
Definition key.cc:1775
Key * BKE_key_from_id(ID *id)
Definition key.cc:1800
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 BKE_id_delete(Main *bmain, void *idv) ATTR_NONNULL()
void size_t BKE_id_multi_tagged_delete(Main *bmain) ATTR_NONNULL()
void BKE_main_id_tag_idcode(Main *mainvar, short type, int tag, bool value)
Definition lib_id.cc:1191
void BKE_id_free(Main *bmain, void *idv)
void id_us_plus(ID *id)
Definition lib_id.cc:351
void id_sort_by_name(ListBase *lb, ID *id, ID *id_sorting_hint)
Definition lib_id.cc:1737
void id_fake_user_set(ID *id)
Definition lib_id.cc:389
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
Definition lib_id.cc:1947
bool BKE_lib_id_make_local(Main *bmain, ID *id, int flags)
Definition lib_id.cc:584
void id_fake_user_clear(ID *id)
Definition lib_id.cc:397
void id_us_clear_real(ID *id)
Definition lib_id.cc:324
void id_us_plus_no_lib(ID *id)
Definition lib_id.cc:335
const char * BKE_id_name(const ID &id)
@ 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 id_us_min(ID *id)
Definition lib_id.cc:359
void BKE_main_id_refcount_recompute(Main *bmain, bool do_linked_only)
Definition lib_id.cc:1981
void BKE_main_id_tag_all(Main *mainvar, int tag, bool value)
Definition lib_id.cc:1198
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, 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, int flag)
Definition lib_query.cc:416
@ IDWALK_NOP
@ ID_REMAP_SKIP_NEVER_NULL_USAGE
@ ID_REMAP_SKIP_INDIRECT_USAGE
void BKE_libblock_relink_to_newid(Main *bmain, ID *id, int remap_flag) ATTR_NONNULL()
Definition lib_remap.cc:921
void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, int remap_flags) ATTR_NONNULL(1
void BKE_library_main_rebuild_hierarchy(Main *bmain)
Definition library.cc:234
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:500
ListBase * which_libbase(Main *bmain, short type)
Definition main.cc:842
void BKE_main_library_weak_reference_destroy(MainLibraryWeakReferenceMap *library_weak_reference_mapping) ATTR_NONNULL()
Definition main.cc:686
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:692
void BKE_main_lock(Main *bmain)
Definition main.cc:479
int set_listbasepointers(Main *bmain, ListBase *lb[])
Definition main.cc:929
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:494
MainLibraryWeakReferenceMap * BKE_main_library_weak_reference_create(Main *bmain) ATTR_NONNULL()
Definition main.cc:656
void BKE_main_unlock(Main *bmain)
Definition main.cc:484
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:743
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:701
void BKE_main_namemap_clear(Main *bmain) ATTR_NONNULL()
General operations, lookup, etc. for materials.
void BKE_object_materials_test(struct Main *bmain, struct Object *ob, struct 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:2820
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:130
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define FILE_MAX
#define STRNCPY(dst, src)
Definition BLI_string.h:593
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_APPEND_LOCAL_ID_REUSE
@ BLO_LIBLINK_COLLECTION_INSTANCE
#define BLO_EMBEDDED_STARTUP_BLEND
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:4248
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:4332
void BLO_read_do_version_after_setup(Main *new_bmain, BlendfileLinkAppendContext *lapp_context, BlendFileReadReport *reports)
void BLO_library_link_end(Main *mainl, BlendHandle **bh, const LibraryLink_Params *params)
Definition readfile.cc:4484
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.
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
Definition DNA_ID.h:676
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:654
#define MAX_ID_NAME
Definition DNA_ID.h:377
@ ID_FLAG_FAKEUSER
Definition DNA_ID.h:720
@ ID_TAG_INDIRECT
Definition DNA_ID.h:794
@ ID_TAG_RUNTIME
Definition DNA_ID.h:805
@ ID_TAG_PRE_EXISTING
Definition DNA_ID.h:872
@ ID_TAG_MISSING
Definition DNA_ID.h:813
@ ID_TAG_DOIT
Definition DNA_ID.h:1003
#define INDEX_ID_MAX
Definition DNA_ID.h:1328
#define ID_NEW_SET(_id, _idn)
Definition DNA_ID.h:707
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_DUPLICOLLECTION
#define BASE_SELECTED(v3d, base)
#define BASE_SELECTABLE(v3d, base)
@ FILE_ACTIVE_COLLECTION
@ FILE_AUTOSELECT
@ FILE_LINK
@ FILE_ASSETS_ONLY
#define USER_EXPERIMENTAL_TEST(userdef, member)
Read Guarded memory(de)allocation.
unsigned int U
Definition btGjkEpa3.h:78
bool add(const Key &key, const Value &value)
Definition BLI_map.hh:271
const Value & lookup(const Key &key) const
Definition BLI_map.hh:506
Value lookup_default(const Key &key, const Value &default_value) const
Definition BLI_map.hh:531
bool remove(const Key &key)
Definition BLI_map.hh:344
bool contains(const Key &key) const
Definition BLI_map.hh:329
bool contains(const Key &key) const
Definition BLI_set.hh:291
bool add(const Key &key)
Definition BLI_set.hh:248
constexpr const char * c_str() const
int64_t size() const
void append(const T &value)
bool is_empty() const
IndexRange index_range() const
void fill(const bool value)
std::string id_name(void *id)
DEGForeachIDComponentCallback callback
int len
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define GS(x)
Definition iris.cc:202
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
unsigned __int64 uint64_t
Definition stdint.h:90
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 ID * reference
Definition DNA_ID.h:333
Definition DNA_ID.h:413
int tag
Definition DNA_ID.h:434
struct Library * lib
Definition DNA_ID.h:419
int us
Definition DNA_ID.h:435
struct ID * newid
Definition DNA_ID.h:417
IDOverrideLibrary * override_library
Definition DNA_ID.h:459
short flag
Definition DNA_ID.h:430
char name[66]
Definition DNA_ID.h:425
struct Collection * collection
struct Library * parent
Definition DNA_ID.h:512
char filepath[1024]
Definition DNA_ID.h:531
struct Library_Runtime runtime
Definition DNA_ID.h:535
ID id
Definition DNA_ID.h:529
void * link
struct LinkNode * next
void * first
BlendfileLinkAppendContext * lapp_context
ListBase scenes
Definition BKE_main.hh:210
short subversionfile
Definition BKE_main.hh:137
short versionfile
Definition BKE_main.hh:137
ListBase collections
Definition BKE_main.hh:231
Library * curlib
Definition BKE_main.hh:209
ListBase objects
Definition BKE_main.hh:212
short transflag
struct Collection * instance_collection
float loc[3]
short visibility_flag
float empty_drawsize
ListBase view_layers
unsigned short local_view_uid
struct Base * basact
char name[64]
static DynamicLibrary lib
uint8_t flag
Definition wm_window.cc:138