Blender V4.3
lib_id.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12#include <cctype>
13#include <cstddef>
14#include <cstdio>
15#include <cstdlib>
16#include <cstring>
17
18#include "CLG_log.h"
19
20#include "MEM_guardedalloc.h"
21
22/* all types are needed here, in order to do memory operations */
23#include "DNA_ID.h"
24#include "DNA_anim_types.h"
27#include "DNA_key_types.h"
28#include "DNA_node_types.h"
29#include "DNA_workspace_types.h"
30
31#include "BLI_utildefines.h"
32
33#include "BLI_alloca.h"
34#include "BLI_array.hh"
35#include "BLI_blenlib.h"
36#include "BLI_ghash.h"
37#include "BLI_linklist.h"
38#include "BLI_memarena.h"
39#include "BLI_string_ref.hh"
40#include "BLI_string_utils.hh"
41
42#include "BLT_translation.hh"
43
44#include "BKE_anim_data.hh"
45#include "BKE_armature.hh"
46#include "BKE_asset.hh"
47#include "BKE_bpath.hh"
48#include "BKE_context.hh"
49#include "BKE_global.hh"
50#include "BKE_gpencil_legacy.h"
51#include "BKE_idprop.hh"
52#include "BKE_idtype.hh"
53#include "BKE_key.hh"
54#include "BKE_lib_id.hh"
55#include "BKE_lib_override.hh"
56#include "BKE_lib_query.hh"
57#include "BKE_lib_remap.hh"
58#include "BKE_main.hh"
59#include "BKE_main_namemap.hh"
60#include "BKE_node.hh"
61#include "BKE_rigidbody.h"
62
63#include "DEG_depsgraph.hh"
66
67#include "RNA_access.hh"
68
69#include "BLO_read_write.hh"
70
71#include "atomic_ops.h"
72
73#include "lib_intern.hh"
74
75// #define DEBUG_TIME
76
77#ifdef DEBUG_TIME
78# include "BLI_time_utildefines.h"
79#endif
80
81using blender::Vector;
82
83using namespace blender::bke::id;
84
85static CLG_LogRef LOG = {"bke.lib_id"};
86
88 /*id_code*/ ID_LINK_PLACEHOLDER,
89 /*id_filter*/ 0,
90 /*dependencies_id_types*/ 0,
91 /*main_listbase_index*/ INDEX_ID_NULL,
92 /*struct_size*/ sizeof(ID),
93 /*name*/ "LinkPlaceholder",
94 /*name_plural*/ N_("link_placeholders"),
95 /*translation_context*/ BLT_I18NCONTEXT_ID_ID,
97 /*asset_type_info*/ nullptr,
98
99 /*init_data*/ nullptr,
100 /*copy_data*/ nullptr,
101 /*free_data*/ nullptr,
102 /*make_local*/ nullptr,
103 /*foreach_id*/ nullptr,
104 /*foreach_cache*/ nullptr,
105 /*foreach_path*/ nullptr,
106 /*owner_pointer_get*/ nullptr,
107
108 /*blend_write*/ nullptr,
109 /*blend_read_data*/ nullptr,
110 /*blend_read_after_liblink*/ nullptr,
111
112 /*blend_read_undo_preserve*/ nullptr,
113
114 /*lib_override_apply_post*/ nullptr,
115};
116
117/* GS reads the memory pointed at in a specific ordering.
118 * only use this definition, makes little and big endian systems
119 * work fine, in conjunction with MAKE_ID */
120
121/* ************* general ************************ */
122
128 char *path_dst,
129 size_t path_dst_maxncpy,
130 const char *path_src)
131{
132 const char **data = static_cast<const char **>(bpath_data->user_data);
133 /* be sure there is low chance of the path being too short */
134 char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE];
135 const char *base_new = data[0];
136 const char *base_old = data[1];
137
138 if (BLI_path_is_rel(base_old)) {
139 CLOG_ERROR(&LOG, "old base path '%s' is not absolute.", base_old);
140 return false;
141 }
142
143 /* Make referenced file absolute. This would be a side-effect of
144 * BLI_path_normalize, but we do it explicitly so we know if it changed. */
145 BLI_strncpy(filepath, path_src, FILE_MAX);
146 if (BLI_path_abs(filepath, base_old)) {
147 /* Path was relative and is now absolute. Remap.
148 * Important BLI_path_normalize runs before the path is made relative
149 * because it won't work for paths that start with "//../" */
150 BLI_path_normalize(filepath);
151 BLI_path_rel(filepath, base_new);
152 BLI_strncpy(path_dst, filepath, path_dst_maxncpy);
153 return true;
154 }
155
156 /* Path was not relative to begin with. */
157 return false;
158}
159
177static void lib_id_library_local_paths(Main *bmain, Library *lib_to, Library *lib_from, ID *id)
178{
179 BLI_assert(lib_to || lib_from);
180 const char *bpath_user_data[2] = {
181 lib_to ? lib_to->runtime.filepath_abs : BKE_main_blendfile_path(bmain),
182 lib_from ? lib_from->runtime.filepath_abs : BKE_main_blendfile_path(bmain)};
183
184 BPathForeachPathData path_data{};
185 path_data.bmain = bmain;
186 path_data.callback_function = lib_id_library_local_paths_callback;
188 path_data.user_data = (void *)bpath_user_data;
189 BKE_bpath_foreach_path_id(&path_data, id);
190}
191
193{
194 ID *id = static_cast<ID *>(cb_data->user_data);
195 if (*cb_data->id_pointer == id) {
196 /* Even though the ID itself remain the same after being made local, from depsgraph point of
197 * view this is a different ID. Hence we need to tag all of its users for a copy-on-eval
198 * update. */
202 }
203 return IDWALK_RET_NOP;
204}
205
206void BKE_lib_id_clear_library_data(Main *bmain, ID *id, const int flags)
207{
208 const bool id_in_mainlist = (id->tag & ID_TAG_NO_MAIN) == 0 &&
209 (id->flag & ID_FLAG_EMBEDDED_DATA) == 0;
210
211 if (id_in_mainlist) {
213 }
214
215 lib_id_library_local_paths(bmain, nullptr, id->lib, id);
216
218
219 id->lib = nullptr;
220 id->tag &= ~(ID_TAG_INDIRECT | ID_TAG_EXTERN);
221 id->flag &= ~ID_FLAG_INDIRECT_WEAK_LINK;
222 if (id_in_mainlist) {
224 *which_libbase(bmain, GS(id->name)),
225 *id,
226 nullptr,
228 false);
229 if (!ELEM(result.action,
232 {
233 bmain->is_memfile_undo_written = false;
234 }
235 }
236
237 /* Conceptually, an ID made local is not the same as the linked one anymore. Reflect that by
238 * regenerating its session UID. */
239 if ((id->tag & ID_TAG_TEMP_MAIN) == 0) {
241 }
242
243 if (ID_IS_ASSET(id)) {
244 if ((flags & LIB_ID_MAKELOCAL_ASSET_DATA_CLEAR) != 0) {
245 const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
246 if (idtype_info && idtype_info->asset_type_info &&
248 {
249 idtype_info->asset_type_info->on_clear_asset_fn(id, id->asset_data);
250 }
251 BKE_asset_metadata_free(&id->asset_data);
252 }
253 else {
254 /* Assets should always have a fake user. Ensure this is the case after "Make Local". */
256 }
257 }
258
259 /* We need to tag this IDs and all of its users, conceptually new local ID and original linked
260 * ones are two completely different data-blocks that were virtually remapped, even though in
261 * reality they remain the same data. For undo this info is critical now. */
263 ID *id_iter;
264 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
267 }
269
270 /* Internal shape key blocks inside data-blocks also stores id->lib,
271 * make sure this stays in sync (note that we do not need any explicit handling for real EMBEDDED
272 * IDs here, this is down automatically in `lib_id_expand_local_cb()`. */
273 Key *key = BKE_key_from_id(id);
274 if (key != nullptr) {
275 BKE_lib_id_clear_library_data(bmain, &key->id, flags);
276 }
277
278 /* Even though the ID itself remain the same after being made local, from depsgraph point of view
279 * this is a different ID. Hence we rebuild depsgraph relationships. */
281}
282
284{
285 if (id && ID_IS_LINKED(id)) {
287 if (id->tag & ID_TAG_INDIRECT) {
288 id->tag &= ~ID_TAG_INDIRECT;
289 id->flag &= ~ID_FLAG_INDIRECT_WEAK_LINK;
290 id->tag |= ID_TAG_EXTERN;
291 id->lib->runtime.parent = nullptr;
292 }
293 }
294}
295
297{
298 if (id && ID_IS_LINKED(id)) {
300 if (id->tag & ID_TAG_INDIRECT) {
301 id->flag |= ID_FLAG_INDIRECT_WEAK_LINK;
302 }
303 }
304}
305
307{
308 if (id) {
309 const int limit = ID_FAKE_USERS(id);
310 id->tag |= ID_TAG_EXTRAUSER;
311 if (id->us <= limit) {
312 if (id->us < limit || ((id->us == limit) && (id->tag & ID_TAG_EXTRAUSER_SET))) {
314 "ID user count error: %s (from '%s')",
315 id->name,
316 id->lib ? id->lib->runtime.filepath_abs : "[Main]");
317 }
318 id->us = limit + 1;
319 id->tag |= ID_TAG_EXTRAUSER_SET;
320 }
321 }
322}
323
325{
326 if (id && (id->tag & ID_TAG_EXTRAUSER)) {
327 if (id->tag & ID_TAG_EXTRAUSER_SET) {
328 id->us--;
329 BLI_assert(id->us >= ID_FAKE_USERS(id));
330 }
332 }
333}
334
336{
337 if (id) {
338 if ((id->tag & ID_TAG_EXTRAUSER) && (id->tag & ID_TAG_EXTRAUSER_SET)) {
339 BLI_assert(id->us >= 1);
340 /* No need to increase count, just tag extra user as no more set.
341 * Avoids annoying & inconsistent +1 in user count. */
342 id->tag &= ~ID_TAG_EXTRAUSER_SET;
343 }
344 else {
345 BLI_assert(id->us >= 0);
346 id->us++;
347 }
348 }
349}
350
351void id_us_plus(ID *id)
352{
353 if (id) {
355 id_lib_extern(id);
356 }
357}
358
359void id_us_min(ID *id)
360{
361 if (id) {
362 const int limit = ID_FAKE_USERS(id);
363
364 if (id->us <= limit) {
365 if (!ID_TYPE_IS_DEPRECATED(GS(id->name))) {
366 /* Do not assert on deprecated ID types, we cannot really ensure that their ID
367 * reference-counting is valid. */
369 "ID user decrement error: %s (from '%s'): %d <= %d",
370 id->name,
371 id->lib ? id->lib->runtime.filepath_abs : "[Main]",
372 id->us,
373 limit);
374 }
375 id->us = limit;
376 }
377 else {
378 id->us--;
379 }
380
381 if ((id->us == limit) && (id->tag & ID_TAG_EXTRAUSER)) {
382 /* We need an extra user here, but never actually incremented user count for it so far,
383 * do it now. */
385 }
386 }
387}
388
390{
391 if (id && !(id->flag & ID_FLAG_FAKEUSER)) {
392 id->flag |= ID_FLAG_FAKEUSER;
393 id_us_plus(id);
394 }
395}
396
398{
399 if (id && (id->flag & ID_FLAG_FAKEUSER)) {
400 id->flag &= ~ID_FLAG_FAKEUSER;
401 id_us_min(id);
402 }
403}
404
406{
407 /* We assume that if this ID has no new ID, its embedded data has not either. */
408 if (id->newid == nullptr) {
409 return;
410 }
411
412 id->newid->tag &= ~ID_TAG_NEW;
413 id->newid = nullptr;
414
415 /* Deal with embedded data too. */
416 /* NOTE: even though ShapeKeys are not technically embedded data currently, they behave as such
417 * in most cases, so for sake of consistency treat them as such here. Also mirrors the behavior
418 * in `BKE_lib_id_make_local`. */
419 Key *key = BKE_key_from_id(id);
420 if (key != nullptr) {
422 }
424 if (ntree != nullptr) {
426 }
427 if (GS(id->name) == ID_SCE) {
428 Collection *master_collection = ((Scene *)id)->master_collection;
429 if (master_collection != nullptr) {
430 BKE_id_newptr_and_tag_clear(&master_collection->id);
431 }
432 }
433}
434
436{
437 Main *bmain = cb_data->bmain;
438 ID *self_id = cb_data->self_id;
439 ID **id_pointer = cb_data->id_pointer;
440 int const cb_flag = cb_data->cb_flag;
441 const int flags = POINTER_AS_INT(cb_data->user_data);
442
443 if (cb_flag & IDWALK_CB_LOOPBACK) {
444 /* We should never have anything to do with loop-back pointers here. */
445 return IDWALK_RET_NOP;
446 }
447
449 /* Embedded data-blocks need to be made fully local as well.
450 * Note however that in some cases (when owner ID had to be duplicated instead of being made
451 * local directly), its embedded IDs should also have already been duplicated, and hence be
452 * fully local here already. */
453 if (*id_pointer != nullptr && ID_IS_LINKED(*id_pointer)) {
454 BLI_assert(*id_pointer != self_id);
455
456 BKE_lib_id_clear_library_data(bmain, *id_pointer, flags);
457 }
458 return IDWALK_RET_NOP;
459 }
460
461 /* Can happen that we get un-linkable ID here, e.g. with shape-key referring to itself
462 * (through drivers)...
463 * Just skip it, shape key can only be either indirectly linked, or fully local, period.
464 * And let's curse one more time that stupid useless shape-key ID type! */
465 if (*id_pointer && *id_pointer != self_id &&
466 BKE_idtype_idcode_is_linkable(GS((*id_pointer)->name)))
467 {
468 id_lib_extern(*id_pointer);
469 }
470
471 return IDWALK_RET_NOP;
472}
473
474void BKE_lib_id_expand_local(Main *bmain, ID *id, const int flags)
475{
478}
479
480void lib_id_copy_ensure_local(Main *bmain, const ID *old_id, ID *new_id, const int flags)
481{
482 if (ID_IS_LINKED(old_id)) {
483 BKE_lib_id_expand_local(bmain, new_id, flags);
484 lib_id_library_local_paths(bmain, nullptr, old_id->lib, new_id);
485 }
486}
487
489 Main *bmain, ID *id, int flags, bool *r_force_local, bool *r_force_copy)
490{
491 bool force_local = (flags & LIB_ID_MAKELOCAL_FORCE_LOCAL) != 0;
492 bool force_copy = (flags & LIB_ID_MAKELOCAL_FORCE_COPY) != 0;
493 BLI_assert(force_copy == false || force_copy != force_local);
494
495 if (force_local || force_copy) {
496 /* Already set by caller code, nothing to do here. */
497 *r_force_local = force_local;
498 *r_force_copy = force_copy;
499 return;
500 }
501
502 const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
503 bool is_local = false, is_lib = false;
504
505 /* - no user (neither lib nor local): make local (happens e.g. with UI-used only data).
506 * - only lib users: do nothing (unless force_local is set)
507 * - only local users: make local
508 * - mixed: make copy
509 * In case we make a whole lib's content local,
510 * we always want to localize, and we skip remapping (done later).
511 */
512
513 BKE_library_ID_test_usages(bmain, id, &is_local, &is_lib);
514 if (!lib_local && !is_local && !is_lib) {
515 force_local = true;
516 }
517 else if (lib_local || is_local) {
518 if (!is_lib) {
519 force_local = true;
520 }
521 else {
522 force_copy = true;
523 }
524 }
525
526 *r_force_local = force_local;
527 *r_force_copy = force_copy;
528}
529
530void BKE_lib_id_make_local_generic(Main *bmain, ID *id, const int flags)
531{
532 if (!ID_IS_LINKED(id)) {
533 return;
534 }
535
536 bool force_local, force_copy;
537 BKE_lib_id_make_local_generic_action_define(bmain, id, flags, &force_local, &force_copy);
538
539 if (force_local) {
540 BKE_lib_id_clear_library_data(bmain, id, flags);
541 if ((flags & LIB_ID_MAKELOCAL_LIBOVERRIDE_CLEAR) != 0) {
543 }
544 BKE_lib_id_expand_local(bmain, id, flags);
545 }
546 else if (force_copy) {
547 const int copy_flags =
550 ID *id_new = BKE_id_copy_ex(bmain, id, nullptr, copy_flags);
551
552 /* Should not fail in expected use cases,
553 * but a few ID types cannot be copied (LIB, WM, SCR...). */
554 if (id_new != nullptr) {
555 id_new->us = 0;
556
557 /* setting newid is mandatory for complex make_lib_local logic... */
558 ID_NEW_SET(id, id_new);
559 Key *key = BKE_key_from_id(id), *key_new = BKE_key_from_id(id);
560 if (key && key_new) {
561 ID_NEW_SET(key, key_new);
562 }
564 *ntree_new = blender::bke::node_tree_from_id(id_new);
565 if (ntree && ntree_new) {
566 ID_NEW_SET(ntree, ntree_new);
567 }
568 if (GS(id->name) == ID_SCE) {
569 Collection *master_collection = ((Scene *)id)->master_collection,
570 *master_collection_new = ((Scene *)id_new)->master_collection;
571 if (master_collection && master_collection_new) {
572 ID_NEW_SET(master_collection, master_collection_new);
573 }
574 }
575
576 const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
577 if (!lib_local) {
579 }
580 }
581 }
582}
583
584bool BKE_lib_id_make_local(Main *bmain, ID *id, const int flags)
585{
586 const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
587
588 /* Skip indirectly linked IDs, unless the whole library is made local, or handling them is
589 * explicitly requested. */
590 if (!(lib_local || (flags & LIB_ID_MAKELOCAL_INDIRECT) != 0) && (id->tag & ID_TAG_INDIRECT)) {
591 return false;
592 }
593
594 const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
595
596 if (idtype_info == nullptr) {
597 BLI_assert_msg(0, "IDType Missing IDTypeInfo");
598 return false;
599 }
600
601 BLI_assert((idtype_info->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0);
602
603 if (idtype_info->make_local != nullptr) {
604 idtype_info->make_local(bmain, id, flags);
605 }
606 else {
607 BKE_lib_id_make_local_generic(bmain, id, flags);
608 }
609
610 return true;
611}
612
618
621{
622 ID **id_pointer = cb_data->id_pointer;
623 ID *id = *id_pointer;
624 const int cb_flag = cb_data->cb_flag;
625 IDCopyLibManagementData *data = static_cast<IDCopyLibManagementData *>(cb_data->user_data);
626
627 /* Remap self-references to new copied ID. */
628 if (id == data->id_src) {
629 /* We cannot use self_id here, it is not *always* id_dst (thanks to confounded node-trees!). */
630 id = *id_pointer = data->id_dst;
631 }
632
633 /* Increase used IDs refcount if needed and required. */
634 if ((data->flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0 && (cb_flag & IDWALK_CB_USER)) {
635 if ((data->flag & LIB_ID_CREATE_NO_MAIN) != 0) {
638 }
639 else {
640 id_us_plus(id);
641 }
642 }
643
644 return IDWALK_RET_NOP;
645}
646
648{
649#define LIB_ID_TYPES_NOCOPY ID_LI, ID_SCR, ID_WM, ID_WS /* Not supported */
650
651 return !ID_TYPE_IS_DEPRECATED(GS(id->name)) && !ELEM(GS(id->name), LIB_ID_TYPES_NOCOPY);
652
653#undef LIB_ID_TYPES_NOCOPY
654}
655
657 std::optional<Library *> owner_library,
658 const ID *id,
659 const ID *new_owner_id,
660 ID **new_id_p,
661 const int flag)
662{
663 ID *newid = (new_id_p != nullptr) ? *new_id_p : nullptr;
665 "Copying with 'no allocate' behavior should always get a non-null new ID buffer");
666
667 /* Make sure destination pointer is all good. */
668 if ((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0) {
669 newid = nullptr;
670 }
671 else {
672 if (!newid) {
673 /* Invalid case, already caught by the assert above. */
674 return nullptr;
675 }
676 /* Allow some garbage non-initialized memory to go in, and clean it up here. */
677 const size_t size = BKE_libblock_get_alloc_info(GS(id->name), nullptr);
678 memset(newid, 0, size);
679 }
680
681 /* Early output if source is nullptr. */
682 if (id == nullptr) {
683 return nullptr;
684 }
685
686 const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
687
688 if (idtype_info != nullptr) {
689 if ((idtype_info->flags & IDTYPE_FLAGS_NO_COPY) != 0) {
690 return nullptr;
691 }
692
693 BKE_libblock_copy_in_lib(bmain, owner_library, id, new_owner_id, &newid, flag);
694
695 if (idtype_info->copy_data != nullptr) {
696 idtype_info->copy_data(bmain, owner_library, newid, id, flag);
697 }
698 }
699 else {
700 BLI_assert_msg(0, "IDType Missing IDTypeInfo");
701 }
702
703 BLI_assert_msg(newid, "Could not get an allocated new ID to copy into");
704 if (!newid) {
705 return nullptr;
706 }
707
708 /* Update ID refcount, remap pointers to self in new ID. */
710 data.id_src = id;
711 data.id_dst = newid;
712 data.flag = flag;
713 /* When copying an embedded ID, typically at this point its owner ID pointer will still point to
714 * the owner of the source, this code has no access to its valid (i.e. destination) owner. This
715 * can be added at some point if needed, but currently the #id_copy_libmanagement_cb callback
716 * does need this information. */
719
720 /* FIXME: Check if this code can be moved in #BKE_libblock_copy_in_lib ? Would feel more fitted
721 * there, having library handling split between both functions does not look good. */
722 /* Do not make new copy local in case we are copying outside of main...
723 * XXX TODO: is this behavior OK, or should we need a separate flag to control that? */
724 if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
725 BLI_assert(!owner_library || newid->lib == *owner_library);
726 /* Expanding local linked ID usages should never be needed with embedded IDs - this will be
727 * handled together with their owner ID copying code. */
728 if (!ID_IS_LINKED(newid) && (newid->flag & ID_FLAG_EMBEDDED_DATA) == 0) {
729 lib_id_copy_ensure_local(bmain, id, newid, 0);
730 }
731 /* If the ID was copied into a library, ensure paths are properly remapped, and that it has a
732 * 'linked' tag set. */
733 if (ID_IS_LINKED(newid)) {
734 if (newid->lib != id->lib) {
735 lib_id_library_local_paths(bmain, newid->lib, id->lib, newid);
736 }
737 if ((newid->tag & (ID_TAG_EXTERN | ID_TAG_INDIRECT)) == 0) {
738 newid->tag |= ID_TAG_EXTERN;
739 }
740 }
741 }
742 else {
743 /* NOTE: Do not call `ensure_local` for IDs copied outside of Main, even if they do become
744 * local.
745 *
746 * Most of the time, this would not be the desired behavior currently.
747 *
748 * In the few cases where this is actually needed (e.g. from liboverride resync code, see
749 * #lib_override_library_create_from), calling code is responsible for this. */
750 newid->lib = owner_library ? *owner_library : id->lib;
751 }
752
753 if (new_id_p != nullptr) {
754 *new_id_p = newid;
755 }
756
757 return newid;
758}
759
760ID *BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, const int flag)
761{
762 return BKE_id_copy_in_lib(bmain, std::nullopt, id, nullptr, new_id_p, flag);
763}
764
765ID *BKE_id_copy(Main *bmain, const ID *id)
766{
767 return BKE_id_copy_in_lib(bmain, std::nullopt, id, nullptr, nullptr, LIB_ID_COPY_DEFAULT);
768}
769
771 ID *id,
772 const eDupli_ID_Flags duplicate_flags,
773 const int copy_flags)
774{
775 if (id == nullptr) {
776 return id;
777 }
778 if (id->newid == nullptr) {
779 const bool do_linked_id = (duplicate_flags & USER_DUP_LINKED_ID) != 0;
780 if (!(do_linked_id || !ID_IS_LINKED(id))) {
781 return id;
782 }
783
784 ID *id_new = BKE_id_copy_ex(bmain, id, nullptr, copy_flags);
785 /* Copying add one user by default, need to get rid of that one. */
786 id_us_min(id_new);
787 ID_NEW_SET(id, id_new);
788
789 /* Shape keys are always copied with their owner ID, by default. */
790 ID *key_new = (ID *)BKE_key_from_id(id_new);
791 ID *key = (ID *)BKE_key_from_id(id);
792 if (key != nullptr) {
793 ID_NEW_SET(key, key_new);
794 }
795
796 /* NOTE: embedded data (root node-trees and master collections) should never be referenced by
797 * anything else, so we do not need to set their newid pointer and flag. */
798
799 BKE_animdata_duplicate_id_action(bmain, id_new, duplicate_flags);
800 if (key_new != nullptr) {
801 BKE_animdata_duplicate_id_action(bmain, key_new, duplicate_flags);
802 }
803 /* Note that actions of embedded data (root node-trees and master collections) are handled
804 * by #BKE_animdata_duplicate_id_action as well. */
805 }
806 return id->newid;
807}
808
810{
811 ID **id_p = cb_data->id_pointer;
812
813 if (*id_p) {
814 ID *id = *id_p;
815 *id_p = DEG_get_original_id(id);
816
817 /* If the ID changes increase the user count.
818 *
819 * This means that the reference to evaluated ID has been changed with a reference to the
820 * original ID which implies that the user count of the original ID is increased.
821 *
822 * The evaluated IDs do not maintain their user counter, so do not change it to avoid issues
823 * with the user counter going negative. */
824 if (*id_p != id) {
825 if ((cb_data->cb_flag & IDWALK_CB_USER) != 0) {
826 id_us_plus(*id_p);
827 }
828 }
829 }
830
831 return IDWALK_RET_NOP;
832}
833
835{
836 ID *newid = BKE_id_copy(bmain, id);
837
838 if (newid == nullptr) {
839 return newid;
840 }
841
842 /* Assign ID references directly used by the given ID to their original complementary parts.
843 *
844 * For example, when is called on an evaluated object will assign object->data to its original
845 * pointer, the evaluated object->data will be kept unchanged. */
847 nullptr, newid, foreach_assign_id_to_orig_callback, nullptr, IDWALK_NOP);
848
849 /* Shape keys reference on evaluated ID is preserved to keep driver paths available, but the key
850 * data is likely to be invalid now due to modifiers, so clear the shape key reference avoiding
851 * any possible shape corruption. */
852 if (DEG_is_evaluated_id(id)) {
853 Key **key_p = BKE_key_from_id_p(newid);
854 if (key_p) {
855 *key_p = nullptr;
856 }
857 }
858
859 return newid;
860}
861
862void BKE_id_move_to_same_lib(Main &bmain, ID &id, const ID &owner_id)
863{
864 if (owner_id.lib == id.lib) {
865 /* `id` is already in the target library, nothing to do. */
866 return;
867 }
868 if (ID_IS_LINKED(&id)) {
869 BLI_assert_msg(false, "Only local IDs can be moved into a library");
870 /* Protect release builds against errors in calling code, as continuing here can lead to
871 * critical Main data-base corruption. */
872 return;
873 }
874
875 id.lib = owner_id.lib;
876 id.tag |= ID_TAG_INDIRECT;
877
879 ListBase &lb = *which_libbase(&bmain, GS(id.name));
881 bmain, lb, id, BKE_id_name(id), IDNewNameMode::RenameExistingNever, true);
882}
883
884static void id_embedded_swap(ID **embedded_id_a,
885 ID **embedded_id_b,
886 const bool do_full_id,
887 IDRemapper *remapper_id_a,
888 IDRemapper *remapper_id_b);
889
894static void id_swap(Main *bmain,
895 ID *id_a,
896 ID *id_b,
897 const bool do_full_id,
898 const bool do_self_remap,
899 IDRemapper *input_remapper_id_a,
900 IDRemapper *input_remapper_id_b,
901 const int self_remap_flags)
902{
903 BLI_assert(GS(id_a->name) == GS(id_b->name));
904
905 IDRemapper *remapper_id_a = input_remapper_id_a;
906 IDRemapper *remapper_id_b = input_remapper_id_b;
907 if (do_self_remap) {
908 if (remapper_id_a == nullptr) {
909 remapper_id_a = MEM_new<IDRemapper>(__func__);
910 }
911 if (remapper_id_b == nullptr) {
912 remapper_id_b = MEM_new<IDRemapper>(__func__);
913 }
914 }
915
916 const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id_a);
917 BLI_assert(id_type != nullptr);
918 const size_t id_struct_size = id_type->struct_size;
919
920 const ID id_a_back = *id_a;
921 const ID id_b_back = *id_b;
922
923 char *id_swap_buff = static_cast<char *>(alloca(id_struct_size));
924
925 memcpy(id_swap_buff, id_a, id_struct_size);
926 memcpy(id_a, id_b, id_struct_size);
927 memcpy(id_b, id_swap_buff, id_struct_size);
928
929 if (!do_full_id) {
930 /* Restore original ID's internal data. */
931 *id_a = id_a_back;
932 *id_b = id_b_back;
933
934 /* Exception: IDProperties. */
935 id_a->properties = id_b_back.properties;
936 id_b->properties = id_a_back.properties;
937 /* Exception: recalc flags. */
938 id_a->recalc = id_b_back.recalc;
939 id_b->recalc = id_a_back.recalc;
940 }
941
944 do_full_id,
945 remapper_id_a,
946 remapper_id_b);
947 if (GS(id_a->name) == ID_SCE) {
948 Scene *scene_a = (Scene *)id_a;
949 Scene *scene_b = (Scene *)id_b;
951 (ID **)&scene_b->master_collection,
952 do_full_id,
953 remapper_id_a,
954 remapper_id_b);
955 }
956
957 if (remapper_id_a != nullptr) {
958 remapper_id_a->add(id_b, id_a);
959 }
960 if (remapper_id_b != nullptr) {
961 remapper_id_b->add(id_a, id_b);
962 }
963
964 /* Finalize remapping of internal references to self broken by swapping, if requested. */
965 if (do_self_remap) {
967 bmain, {id_a}, ID_REMAP_TYPE_REMAP, *remapper_id_a, self_remap_flags);
969 bmain, {id_b}, ID_REMAP_TYPE_REMAP, *remapper_id_b, self_remap_flags);
970 }
971
972 if (input_remapper_id_a == nullptr && remapper_id_a != nullptr) {
973 MEM_delete(remapper_id_a);
974 }
975 if (input_remapper_id_b == nullptr && remapper_id_b != nullptr) {
976 MEM_delete(remapper_id_b);
977 }
978}
979
980/* Conceptually, embedded IDs are part of their owner's data. However, some parts of the code
981 * (like e.g. the depsgraph) may treat them as independent IDs, so swapping them here and
982 * switching their pointers in the owner IDs allows to help not break cached relationships and
983 * such (by preserving the pointer values). */
984static void id_embedded_swap(ID **embedded_id_a,
985 ID **embedded_id_b,
986 const bool do_full_id,
987 IDRemapper *remapper_id_a,
988 IDRemapper *remapper_id_b)
989{
990 if (embedded_id_a != nullptr && *embedded_id_a != nullptr) {
991 BLI_assert(embedded_id_b != nullptr);
992
993 if (*embedded_id_b == nullptr) {
994 /* Cannot swap anything if one of the embedded IDs is nullptr. */
995 return;
996 }
997
998 /* Do not remap internal references to itself here, since embedded IDs pointers also need to be
999 * potentially remapped in owner ID's data, which will also handle embedded IDs data. */
1000 id_swap(nullptr,
1001 *embedded_id_a,
1002 *embedded_id_b,
1003 do_full_id,
1004 false,
1005 remapper_id_a,
1006 remapper_id_b,
1007 0);
1008 /* Manual 'remap' of owning embedded pointer in owner ID. */
1009 std::swap(*embedded_id_a, *embedded_id_b);
1010
1011 /* Restore internal pointers to the swapped embedded IDs in their owners' data. This also
1012 * includes the potential self-references inside the embedded IDs themselves. */
1013 if (remapper_id_a != nullptr) {
1014 remapper_id_a->add(*embedded_id_b, *embedded_id_a);
1015 }
1016 if (remapper_id_b != nullptr) {
1017 remapper_id_b->add(*embedded_id_a, *embedded_id_b);
1018 }
1019 }
1020}
1021
1023 Main *bmain, ID *id_a, ID *id_b, const bool do_self_remap, const int self_remap_flags)
1024{
1025 id_swap(bmain, id_a, id_b, false, do_self_remap, nullptr, nullptr, self_remap_flags);
1026}
1027
1029 Main *bmain, ID *id_a, ID *id_b, const bool do_self_remap, const int self_remap_flags)
1030{
1031 id_swap(bmain, id_a, id_b, true, do_self_remap, nullptr, nullptr, self_remap_flags);
1032}
1033
1035{
1036 ID *newid = nullptr;
1037
1038 if (id && (ID_REAL_USERS(id) > 1)) {
1039 /* If property isn't editable,
1040 * we're going to have an extra block hanging around until we save. */
1041 if (RNA_property_editable(ptr, prop)) {
1042 Main *bmain = CTX_data_main(C);
1043 /* copy animation actions too */
1044 newid = BKE_id_copy_ex(bmain, id, nullptr, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS);
1045 if (newid != nullptr) {
1046 /* us is 1 by convention with new IDs, but RNA_property_pointer_set
1047 * will also increment it, decrement it here. */
1048 id_us_min(newid);
1049
1050 /* assign copy */
1051 PointerRNA idptr = RNA_id_pointer_create(newid);
1052 RNA_property_pointer_set(ptr, prop, idptr, nullptr);
1053 RNA_property_update(C, ptr, prop);
1054
1055 /* tag grease pencil data-block and disable onion */
1056 if (GS(id->name) == ID_GD_LEGACY) {
1059 bGPdata *gpd = (bGPdata *)newid;
1060 gpd->flag &= ~GP_DATA_SHOW_ONIONSKINS;
1061 }
1062
1063 return true;
1064 }
1065 }
1066 }
1067
1068 return false;
1069}
1070
1072{
1073 ID **id_pointer = cb_data->id_pointer;
1074 const int cb_flag = cb_data->cb_flag;
1075 if (cb_flag & IDWALK_CB_USER) {
1076 id_us_plus(*id_pointer);
1077 }
1078 if (cb_flag & IDWALK_CB_USER_ONE) {
1079 id_us_ensure_real(*id_pointer);
1080 }
1081
1082 return IDWALK_RET_NOP;
1083}
1084
1086{
1087 ID **id_pointer = cb_data->id_pointer;
1088 const int cb_flag = cb_data->cb_flag;
1089 if (cb_flag & IDWALK_CB_USER) {
1090 id_us_min(*id_pointer);
1091 }
1092 /* We can do nothing in IDWALK_CB_USER_ONE case! */
1093
1094 return IDWALK_RET_NOP;
1095}
1096
1098{
1099 ID *id = static_cast<ID *>(idv);
1100
1101 BLI_assert(bmain != nullptr);
1102 if ((id->tag & ID_TAG_NO_MAIN) == 0) {
1103 return;
1104 }
1105
1106 if ((id->tag & ID_TAG_NOT_ALLOCATED) != 0) {
1107 /* We cannot add non-allocated ID to Main! */
1108 return;
1109 }
1110
1111 /* We cannot allow non-userrefcounting IDs in Main database! */
1112 if ((id->tag & ID_TAG_NO_USER_REFCOUNT) != 0) {
1114 }
1115
1116 ListBase *lb = which_libbase(bmain, GS(id->name));
1117 BKE_main_lock(bmain);
1118 BLI_addtail(lb, id);
1119 /* We need to allow adding extra datablocks into libraries too, e.g. to support generating new
1120 * overrides for recursive resync. */
1121 BKE_id_new_name_validate(*bmain, *lb, *id, nullptr, IDNewNameMode::RenameExistingNever, true);
1122 /* alphabetic insertion: is in new_id */
1124 bmain->is_memfile_undo_written = false;
1125 BKE_main_unlock(bmain);
1126
1128}
1129
1131{
1132 ID *id = static_cast<ID *>(idv);
1133
1134 BLI_assert(bmain != nullptr);
1135 if ((id->tag & ID_TAG_NO_MAIN) != 0) {
1136 return;
1137 }
1138
1139 /* For now, allow userrefcounting IDs to get out of Main - can be handy in some cases... */
1140
1141 ListBase *lb = which_libbase(bmain, GS(id->name));
1142 BKE_main_lock(bmain);
1143 BLI_remlink(lb, id);
1145 id->tag |= ID_TAG_NO_MAIN;
1146 bmain->is_memfile_undo_written = false;
1147 BKE_main_unlock(bmain);
1148}
1149
1151{
1152 ID *id = static_cast<ID *>(idv);
1153
1154 if ((id->tag & ID_TAG_NO_USER_REFCOUNT) == 0) {
1155 return;
1156 }
1157
1159 id->tag &= ~ID_TAG_NO_USER_REFCOUNT;
1160}
1161
1163{
1164 ID *id = static_cast<ID *>(idv);
1165
1166 /* We do not allow IDs in Main database to not be userrefcounting. */
1167 if ((id->tag & ID_TAG_NO_USER_REFCOUNT) != 0 || (id->tag & ID_TAG_NO_MAIN) != 0) {
1168 return;
1169 }
1170
1172 id->tag |= ID_TAG_NO_USER_REFCOUNT;
1173}
1174
1175void BKE_main_id_tag_listbase(ListBase *lb, const int tag, const bool value)
1176{
1177 ID *id;
1178 if (value) {
1179 for (id = static_cast<ID *>(lb->first); id; id = static_cast<ID *>(id->next)) {
1180 id->tag |= tag;
1181 }
1182 }
1183 else {
1184 const int ntag = ~tag;
1185 for (id = static_cast<ID *>(lb->first); id; id = static_cast<ID *>(id->next)) {
1186 id->tag &= ntag;
1187 }
1188 }
1189}
1190
1191void BKE_main_id_tag_idcode(Main *mainvar, const short type, const int tag, const bool value)
1192{
1193 ListBase *lb = which_libbase(mainvar, type);
1194
1195 BKE_main_id_tag_listbase(lb, tag, value);
1196}
1197
1198void BKE_main_id_tag_all(Main *mainvar, const int tag, const bool value)
1199{
1200 ListBase *lbarray[INDEX_ID_MAX];
1201 int a;
1202
1203 a = set_listbasepointers(mainvar, lbarray);
1204 while (a--) {
1205 BKE_main_id_tag_listbase(lbarray[a], tag, value);
1206 }
1207}
1208
1209void BKE_main_id_flag_listbase(ListBase *lb, const int flag, const bool value)
1210{
1211 ID *id;
1212 if (value) {
1213 for (id = static_cast<ID *>(lb->first); id; id = static_cast<ID *>(id->next)) {
1214 id->tag |= flag;
1215 }
1216 }
1217 else {
1218 const int nflag = ~flag;
1219 for (id = static_cast<ID *>(lb->first); id; id = static_cast<ID *>(id->next)) {
1220 id->tag &= nflag;
1221 }
1222 }
1223}
1224
1225void BKE_main_id_flag_all(Main *bmain, const int flag, const bool value)
1226{
1227 ListBase *lbarray[INDEX_ID_MAX];
1228 int a;
1229 a = set_listbasepointers(bmain, lbarray);
1230 while (a--) {
1231 BKE_main_id_flag_listbase(lbarray[a], flag, value);
1232 }
1233}
1234
1236{
1237 int lb_len = 0;
1238 LISTBASE_FOREACH (ID *, id, lb) {
1239 if (!ID_IS_LINKED(id)) {
1240 lb_len += 1;
1241 }
1242 }
1243 if (lb_len <= 1) {
1244 return;
1245 }
1246
1247 /* Fill an array because renaming sorts. */
1248 ID **id_array = static_cast<ID **>(MEM_mallocN(sizeof(*id_array) * lb_len, __func__));
1249 GSet *gset = BLI_gset_str_new_ex(__func__, lb_len);
1250 int i = 0;
1251 LISTBASE_FOREACH (ID *, id, lb) {
1252 if (!ID_IS_LINKED(id)) {
1253 id_array[i] = id;
1254 i++;
1255 }
1256 }
1257 for (i = 0; i < lb_len; i++) {
1258 if (!BLI_gset_add(gset, BKE_id_name(*id_array[i]))) {
1260 *bmain, *lb, *id_array[i], nullptr, IDNewNameMode::RenameExistingNever, false);
1261 }
1262 }
1263 BLI_gset_free(gset, nullptr);
1264 MEM_freeN(id_array);
1265}
1266
1268{
1269 Object *ob;
1270
1271 /* flag for full recalc */
1272 for (ob = static_cast<Object *>(bmain->objects.first); ob;
1273 ob = static_cast<Object *>(ob->id.next))
1274 {
1275 if (ID_IS_LINKED(ob)) {
1277 }
1278 }
1279
1280 DEG_id_type_tag(bmain, ID_OB);
1281}
1282
1283/* *********** ALLOC AND FREE *****************
1284 *
1285 * BKE_libblock_free(ListBase *lb, ID *id )
1286 * provide a list-basis and data-block, but only ID is read
1287 *
1288 * void *BKE_libblock_alloc(ListBase *lb, type, name)
1289 * inserts in list and returns a new ID
1290 *
1291 * **************************** */
1292
1293size_t BKE_libblock_get_alloc_info(short type, const char **r_name)
1294{
1295 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(type);
1296
1297 if (id_type == nullptr) {
1298 if (r_name != nullptr) {
1299 *r_name = nullptr;
1300 }
1301 return 0;
1302 }
1303
1304 if (r_name != nullptr) {
1305 *r_name = id_type->name;
1306 }
1307 return id_type->struct_size;
1308}
1309
1311{
1312 const char *name;
1313 size_t size = BKE_libblock_get_alloc_info(type, &name);
1314 if (size != 0) {
1315 return MEM_callocN(size, name);
1316 }
1317 BLI_assert_msg(0, "Request to allocate unknown data type");
1318 return nullptr;
1319}
1320
1322 std::optional<Library *> owner_library,
1323 short type,
1324 const char *name,
1325 const int flag)
1326{
1328 BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || bmain != nullptr);
1330
1331 ID *id = static_cast<ID *>(BKE_libblock_alloc_notest(type));
1332
1333 if (id) {
1334 if ((flag & LIB_ID_CREATE_NO_MAIN) != 0) {
1335 id->tag |= ID_TAG_NO_MAIN;
1336 }
1337 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) != 0) {
1338 id->tag |= ID_TAG_NO_USER_REFCOUNT;
1339 }
1340 if (flag & LIB_ID_CREATE_LOCAL) {
1341 id->tag |= ID_TAG_LOCALIZED;
1342 }
1343
1344 id->icon_id = 0;
1345 *((short *)id->name) = type;
1346 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
1347 id->us = 1;
1348 }
1349 if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
1350 /* Note that 2.8x versioning has tested not to cause conflicts. Node trees are
1351 * skipped in this check to allow adding a geometry node tree for versioning. */
1352 BLI_assert(bmain->is_locked_for_linking == false || ELEM(type, ID_WS, ID_GR, ID_NT));
1353 ListBase *lb = which_libbase(bmain, type);
1354
1355 /* This is important in 'readfile doversion after liblink' context mainly, but is a good
1356 * behavior for consistency in general: ID created for a Main should get that main's current
1357 * library pointer.
1358 *
1359 * NOTE: A bit convoluted.
1360 * - When Main has a defined `curlib`, it is assumed to be a split main containing only IDs
1361 * from that library. In that case, the library can be set later, and it avoids
1362 * synchronization issues in the namemap between the one of that temp 'library' Main and
1363 * the library ID runtime namemap itself. In a way, the ID can be assumed local to the
1364 * current Main, for its assignment to this Main.
1365 * - In all other cases, the Main is assumed 'complete', i.e. containing all local and
1366 * linked IDs, In that case, it is critical that the ID gets the correct library assigned
1367 * now, to ensure that the call to #BKE_id_new_name_validate gives a fully valid result
1368 * once it has been assigned to the current Main.
1369 */
1370 if (bmain->curlib) {
1371 id->lib = nullptr;
1372 }
1373 else {
1374 id->lib = owner_library ? *owner_library : nullptr;
1375 }
1376
1377 BKE_main_lock(bmain);
1378 BLI_addtail(lb, id);
1379 BKE_id_new_name_validate(*bmain, *lb, *id, name, IDNewNameMode::RenameExistingNever, true);
1380 bmain->is_memfile_undo_written = false;
1381 /* alphabetic insertion: is in new_id */
1382 BKE_main_unlock(bmain);
1383
1384 /* Split Main case, now the ID should get the Main's #curlib. */
1385 if (bmain->curlib) {
1386 BLI_assert(!owner_library || *owner_library == bmain->curlib);
1387 id->lib = bmain->curlib;
1388 }
1389
1390 /* This assert avoids having to keep name_map consistency when changing the library of an ID,
1391 * if this check is not true anymore it will have to be done here too. */
1392 BLI_assert(bmain->curlib == nullptr || bmain->curlib->runtime.name_map == nullptr);
1393
1394 /* TODO: to be removed from here! */
1395 if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0) {
1396 DEG_id_type_tag(bmain, type);
1397 }
1398 }
1399 else {
1400 BLI_strncpy(id->name + 2, name, sizeof(id->name) - 2);
1401 id->lib = owner_library ? *owner_library : nullptr;
1402 }
1403
1404 /* We also need to ensure a valid `session_uid` for some non-main data (like embedded IDs).
1405 * IDs not allocated however should not need those (this would e.g. avoid generating session
1406 * uids for depsgraph evaluated IDs, if it was using this function). */
1407 if ((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0) {
1409 }
1410 }
1411
1412 return id;
1413}
1414
1415void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int flag)
1416{
1417 return BKE_libblock_alloc_in_lib(bmain, std::nullopt, type, name, flag);
1418}
1419
1421{
1422 const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
1423
1424 if (idtype_info != nullptr) {
1425 if (idtype_info->init_data != nullptr) {
1426 idtype_info->init_data(id);
1427 }
1428 return;
1429 }
1430
1431 BLI_assert_msg(0, "IDType Missing IDTypeInfo");
1432}
1433
1435{
1436 id->runtime.remap.status = 0;
1437 id->runtime.remap.skipped_refcounted = 0;
1438 id->runtime.remap.skipped_direct = 0;
1439 id->runtime.remap.skipped_indirect = 0;
1440}
1441
1442/* ********** ID session-wise UID management. ********** */
1444
1446{
1447 if (id->session_uid == MAIN_ID_SESSION_UID_UNSET) {
1448 BLI_assert((id->tag & ID_TAG_TEMP_MAIN) == 0); /* Caller must ensure this. */
1449 id->session_uid = atomic_add_and_fetch_uint32(&global_session_uid, 1);
1450 /* In case overflow happens, still assign a valid ID. This way opening files many times works
1451 * correctly. */
1452 if (UNLIKELY(id->session_uid == MAIN_ID_SESSION_UID_UNSET)) {
1453 id->session_uid = atomic_add_and_fetch_uint32(&global_session_uid, 1);
1454 }
1455 }
1456}
1457
1463
1465 std::optional<Library *> owner_library,
1466 const short type,
1467 const char *name)
1468
1469{
1470 BLI_assert(bmain != nullptr);
1471
1472 if (name == nullptr) {
1473 name = DATA_(BKE_idtype_idcode_to_name(type));
1474 }
1475
1476 ID *id = static_cast<ID *>(BKE_libblock_alloc_in_lib(bmain, owner_library, type, name, 0));
1478
1479 return id;
1480}
1481
1482void *BKE_id_new(Main *bmain, const short type, const char *name)
1483{
1484 return BKE_id_new_in_lib(bmain, std::nullopt, type, name);
1485}
1486
1487void *BKE_id_new_nomain(const short type, const char *name)
1488{
1489 if (name == nullptr) {
1490 name = DATA_(BKE_idtype_idcode_to_name(type));
1491 }
1492
1493 ID *id = static_cast<ID *>(BKE_libblock_alloc(
1494 nullptr,
1495 type,
1496 name,
1499
1500 return id;
1501}
1502
1504 std::optional<Library *> owner_library,
1505 const ID *id,
1506 const ID *new_owner_id,
1507 ID **new_id_p,
1508 const int orig_flag)
1509{
1510 ID *new_id = *new_id_p;
1511 int flag = orig_flag;
1512
1513 const bool is_embedded_id = (id->flag & ID_FLAG_EMBEDDED_DATA) != 0;
1514
1515 BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || bmain != nullptr);
1518
1519 /* Embedded ID handling.
1520 *
1521 * NOTE: This makes copying code of embedded IDs non-reentrant (i.e. copying an embedded ID as
1522 * part of another embedded ID would not work properly). This is not an issue currently, but may
1523 * need to be addressed in the future. */
1524 if ((bmain != nullptr) && is_embedded_id) {
1526 }
1527
1528 /* The id->flag bits to copy over. */
1529 const int copy_idflag_mask = ID_FLAG_EMBEDDED_DATA;
1530 /* The id->tag bits to copy over. */
1531 const int copy_idtag_mask =
1532 /* Only copy potentially existing 'linked' tags if the new ID is being placed into a library.
1533 *
1534 * Further tag and paths remapping is handled in #BKE_id_copy_in_lib.
1535 */
1536 ((owner_library && *owner_library) ? (ID_TAG_EXTERN | ID_TAG_INDIRECT) : 0);
1537
1538 if ((flag & LIB_ID_CREATE_NO_ALLOCATE) != 0) {
1539 /* `new_id_p` already contains pointer to allocated memory. */
1540 /* TODO: do we want to memset(0) whole mem before filling it? */
1541 STRNCPY(new_id->name, id->name);
1542 new_id->us = 0;
1544 new_id->lib = owner_library ? *owner_library : id->lib;
1545 /* TODO: Do we want/need to copy more from ID struct itself? */
1546 }
1547 else {
1548 new_id = static_cast<ID *>(
1549 BKE_libblock_alloc_in_lib(bmain, owner_library, GS(id->name), BKE_id_name(*id), flag));
1550 }
1551 BLI_assert(new_id != nullptr);
1552
1554 new_id->tag |= ID_TAG_COPIED_ON_EVAL;
1555 }
1556 else {
1557 new_id->tag &= ~ID_TAG_COPIED_ON_EVAL;
1558 }
1559
1560 const size_t id_len = BKE_libblock_get_alloc_info(GS(new_id->name), nullptr);
1561 const size_t id_offset = sizeof(ID);
1562 if (int(id_len) - int(id_offset) > 0) { /* signed to allow neg result */ /* XXX ????? */
1563 const char *cp = (const char *)id;
1564 char *cpn = (char *)new_id;
1565
1566 memcpy(cpn + id_offset, cp + id_offset, id_len - id_offset);
1567 }
1568
1569 new_id->flag = (new_id->flag & ~copy_idflag_mask) | (id->flag & copy_idflag_mask);
1570 new_id->tag = (new_id->tag & ~copy_idtag_mask) | (id->tag & copy_idtag_mask);
1571
1572 /* Embedded ID data handling. */
1573 if (is_embedded_id && (orig_flag & LIB_ID_CREATE_NO_MAIN) == 0) {
1574 new_id->tag &= ~ID_TAG_NO_MAIN;
1575 }
1576 /* NOTE: This also needs to run for ShapeKeys, which are not (yet) actual embedded IDs.
1577 * NOTE: for now, keep existing owner ID (i.e. owner of the source embedded ID) if no new one
1578 * is given. In some cases (e.g. depsgraph), this is important for later remapping to work
1579 * properly.
1580 */
1581 if (new_owner_id) {
1582 const IDTypeInfo *idtype = BKE_idtype_get_info_from_id(new_id);
1583 BLI_assert(idtype->owner_pointer_get != nullptr);
1584 ID **owner_id_pointer = idtype->owner_pointer_get(new_id, false);
1585 *owner_id_pointer = const_cast<ID *>(new_owner_id);
1586 }
1587
1588 /* We do not want any handling of user-count in code duplicating the data here, we do that all
1589 * at once in id_copy_libmanagement_cb() at the end. */
1590 const int copy_data_flag = orig_flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
1591
1592 if (id->properties) {
1593 new_id->properties = IDP_CopyProperty_ex(id->properties, copy_data_flag);
1594 }
1595
1596 /* This is never duplicated, only one existing ID should have a given weak ref to library/ID. */
1597 new_id->library_weak_reference = nullptr;
1598
1599 if ((orig_flag & LIB_ID_COPY_NO_LIB_OVERRIDE) == 0) {
1601 /* We do not want to copy existing override rules here, as they would break the proper
1602 * remapping between IDs. Proper overrides rules will be re-generated anyway. */
1603 BKE_lib_override_library_copy(new_id, id, false);
1604 }
1605 else if (ID_IS_OVERRIDE_LIBRARY_VIRTUAL(id)) {
1606 /* Just ensure virtual overrides do get properly tagged, there is not actual override data to
1607 * copy here. */
1609 }
1610 }
1611
1612 if (id_can_have_animdata(new_id)) {
1613 IdAdtTemplate *iat = (IdAdtTemplate *)new_id;
1614
1615 /* the duplicate should get a copy of the animdata */
1616 if ((flag & LIB_ID_COPY_NO_ANIMDATA) == 0) {
1617 /* Note that even though horrors like root node-trees are not in bmain, the actions they use
1618 * in their anim data *are* in bmain... super-mega-hooray. */
1619 BLI_assert((copy_data_flag & LIB_ID_COPY_ACTIONS) == 0 ||
1620 (copy_data_flag & LIB_ID_CREATE_NO_MAIN) == 0);
1621 iat->adt = BKE_animdata_copy_in_lib(bmain, owner_library, iat->adt, copy_data_flag);
1622 }
1623 else {
1624 iat->adt = nullptr;
1625 }
1626 }
1627
1629 if (id->asset_data) {
1630 new_id->asset_data = BKE_asset_metadata_copy(id->asset_data);
1631 }
1632 }
1633
1634 if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0) {
1635 DEG_id_type_tag(bmain, GS(new_id->name));
1636 }
1637
1638 *new_id_p = new_id;
1639}
1640
1641void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **new_id_p, const int orig_flag)
1642{
1643 BKE_libblock_copy_in_lib(bmain, std::nullopt, id, nullptr, new_id_p, orig_flag);
1644}
1645
1646void *BKE_libblock_copy(Main *bmain, const ID *id)
1647{
1648 ID *idn = nullptr;
1649
1650 BKE_libblock_copy_in_lib(bmain, std::nullopt, id, nullptr, &idn, 0);
1651
1652 return idn;
1653}
1654
1655/* ***************** ID ************************ */
1656
1658 const short type,
1659 const char *name,
1660 const std::optional<Library *> lib)
1661{
1662 const ListBase *lb = which_libbase(bmain, type);
1663 BLI_assert(lb != nullptr);
1664
1665 ID *id = static_cast<ID *>(BLI_findstring(lb, name, offsetof(ID, name) + 2));
1666 if (lib) {
1667 while (id && id->lib != *lib) {
1668 id = static_cast<ID *>(BLI_listbase_findafter_string_ptr(
1669 reinterpret_cast<Link *>(id), name, offsetof(ID, name) + 2));
1670 }
1671 }
1672 return id;
1673}
1674
1675ID *BKE_libblock_find_session_uid(Main *bmain, const short type, const uint32_t session_uid)
1676{
1677 const ListBase *lb = which_libbase(bmain, type);
1678 BLI_assert(lb != nullptr);
1679 LISTBASE_FOREACH (ID *, id, lb) {
1680 if (id->session_uid == session_uid) {
1681 return id;
1682 }
1683 }
1684 return nullptr;
1685}
1686
1688 const short type,
1689 const char *name,
1690 const char *lib_name)
1691{
1692 ListBase *lb = which_libbase(bmain, type);
1693 BLI_assert(lb != nullptr);
1694 LISTBASE_FOREACH (ID *, id, lb) {
1695 if (!STREQ(BKE_id_name(*id), name)) {
1696 continue;
1697 }
1698 if (lib_name == nullptr || lib_name[0] == '\0') {
1699 if (id->lib == nullptr) {
1700 return id;
1701 }
1702 return nullptr;
1703 }
1704 if (id->lib == nullptr) {
1705 return nullptr;
1706 }
1707 if (!STREQ(BKE_id_name(id->lib->id), lib_name)) {
1708 continue;
1709 }
1710 return id;
1711 }
1712 return nullptr;
1713}
1714
1716 short type,
1717 const char *name,
1718 const char *lib_filepath_abs)
1719{
1720 ListBase *lb = which_libbase(bmain, type);
1721 BLI_assert(lb != nullptr);
1722 LISTBASE_FOREACH (ID *, id, lb) {
1723 if (!STREQ(BKE_id_name(*id), name)) {
1724 continue;
1725 }
1726 if (id->lib == nullptr && lib_filepath_abs == nullptr) {
1727 return id;
1728 }
1729 else if (id->lib && lib_filepath_abs && STREQ(id->lib->runtime.filepath_abs, lib_filepath_abs))
1730 {
1731 return id;
1732 }
1733 }
1734 return nullptr;
1735}
1736
1737void id_sort_by_name(ListBase *lb, ID *id, ID *id_sorting_hint)
1738{
1739#define ID_SORT_STEP_SIZE 512
1740
1741 ID *idtest;
1742
1743 /* insert alphabetically */
1744 if (lb->first == lb->last) {
1745 return;
1746 }
1747
1748 BLI_remlink(lb, id);
1749
1750 /* Check if we can actually insert id before or after id_sorting_hint, if given. */
1751 if (!ELEM(id_sorting_hint, nullptr, id) && id_sorting_hint->lib == id->lib) {
1752 BLI_assert(BLI_findindex(lb, id_sorting_hint) >= 0);
1753
1754 ID *id_sorting_hint_next = static_cast<ID *>(id_sorting_hint->next);
1755 if (BLI_strcasecmp(id_sorting_hint->name, id->name) < 0 &&
1756 (id_sorting_hint_next == nullptr || id_sorting_hint_next->lib != id->lib ||
1757 BLI_strcasecmp(id_sorting_hint_next->name, id->name) > 0))
1758 {
1759 BLI_insertlinkafter(lb, id_sorting_hint, id);
1760 return;
1761 }
1762
1763 ID *id_sorting_hint_prev = static_cast<ID *>(id_sorting_hint->prev);
1764 if (BLI_strcasecmp(id_sorting_hint->name, id->name) > 0 &&
1765 (id_sorting_hint_prev == nullptr || id_sorting_hint_prev->lib != id->lib ||
1766 BLI_strcasecmp(id_sorting_hint_prev->name, id->name) < 0))
1767 {
1768 BLI_insertlinkbefore(lb, id_sorting_hint, id);
1769 return;
1770 }
1771 }
1772
1773 void *item_array[ID_SORT_STEP_SIZE];
1774 int item_array_index;
1775
1776 /* Step one: We go backward over a whole chunk of items at once, until we find a limit item
1777 * that is lower than, or equal (should never happen!) to the one we want to insert. */
1778 /* NOTE: We start from the end, because in typical 'heavy' case (insertion of lots of IDs at
1779 * once using the same base name), newly inserted items will generally be towards the end
1780 * (higher extension numbers). */
1781 bool is_in_library = false;
1782 item_array_index = ID_SORT_STEP_SIZE - 1;
1783 for (idtest = static_cast<ID *>(lb->last); idtest != nullptr;
1784 idtest = static_cast<ID *>(idtest->prev))
1785 {
1786 if (is_in_library) {
1787 if (idtest->lib != id->lib) {
1788 /* We got out of expected library 'range' in the list, so we are done here and can move on
1789 * to the next step. */
1790 break;
1791 }
1792 }
1793 else if (idtest->lib == id->lib) {
1794 /* We are entering the expected library 'range' of IDs in the list. */
1795 is_in_library = true;
1796 }
1797
1798 if (!is_in_library) {
1799 continue;
1800 }
1801
1802 item_array[item_array_index] = idtest;
1803 if (item_array_index == 0) {
1804 if (BLI_strcasecmp(idtest->name, id->name) <= 0) {
1805 break;
1806 }
1807 item_array_index = ID_SORT_STEP_SIZE;
1808 }
1809 item_array_index--;
1810 }
1811
1812 /* Step two: we go forward in the selected chunk of items and check all of them, as we know
1813 * that our target is in there. */
1814
1815 /* If we reached start of the list, current item_array_index is off-by-one.
1816 * Otherwise, we already know that it points to an item lower-or-equal-than the one we want to
1817 * insert, no need to redo the check for that one.
1818 * So we can increment that index in any case. */
1819 for (item_array_index++; item_array_index < ID_SORT_STEP_SIZE; item_array_index++) {
1820 idtest = static_cast<ID *>(item_array[item_array_index]);
1821 if (BLI_strcasecmp(idtest->name, id->name) > 0) {
1822 BLI_insertlinkbefore(lb, idtest, id);
1823 break;
1824 }
1825 }
1826 if (item_array_index == ID_SORT_STEP_SIZE) {
1827 if (idtest == nullptr) {
1828 /* If idtest is nullptr here, it means that in the first loop, the last comparison was
1829 * performed exactly on the first item of the list, and that it also failed. And that the
1830 * second loop was not walked at all.
1831 *
1832 * In other words, if `id` is local, all the items in the list are greater than the inserted
1833 * one, so we can put it at the start of the list. Or, if `id` is linked, it is the first one
1834 * of its library, and we can put it at the very end of the list. */
1835 if (ID_IS_LINKED(id)) {
1836 BLI_addtail(lb, id);
1837 }
1838 else {
1839 BLI_addhead(lb, id);
1840 }
1841 }
1842 else {
1843 BLI_insertlinkafter(lb, idtest, id);
1844 }
1845 }
1846
1847#undef ID_SORT_STEP_SIZE
1848}
1849
1851 ListBase &lb,
1852 ID &id,
1853 const char *newname,
1854 IDNewNameMode mode,
1855 const bool do_linked_data)
1856{
1857 char name[MAX_ID_NAME - 2];
1858
1859 /* If library, don't rename (unless explicitly required), but do ensure proper sorting. */
1860 if (!do_linked_data && ID_IS_LINKED(&id)) {
1861 id_sort_by_name(&lb, &id, nullptr);
1862
1863 return {IDNewNameResult::Action::UNCHANGED, nullptr};
1864 }
1865
1866 /* If no name given, use name of current ID. */
1867 if (newname == nullptr) {
1868 newname = BKE_id_name(id);
1869 }
1870 /* Make a copy of given name (newname args can be const). */
1871 STRNCPY(name, newname);
1872
1873 if (name[0] == '\0') {
1874 /* Disallow empty names. */
1876 }
1877 else {
1878 /* disallow non utf8 chars,
1879 * the interface checks for this but new ID's based on file names don't */
1880 BLI_str_utf8_invalid_strip(name, strlen(name));
1881 }
1882
1883 /* Store original requested new name, in modes that may solve name conflict by renaming the
1884 * existing conflicting ID. */
1885 char orig_name[MAX_ID_NAME - 2];
1887 STRNCPY(orig_name, name);
1888 }
1889
1890 const bool had_name_collision = BKE_main_namemap_get_name(&bmain, &id, name, false);
1891
1892 if (had_name_collision &&
1894 {
1895 char prev_name[MAX_ID_NAME - 2];
1896 char prev_name_root[MAX_ID_NAME - 2];
1897 int prev_number = 0;
1898 char new_name_root[MAX_ID_NAME - 2];
1899 int new_number = 0;
1900 STRNCPY(prev_name, BKE_id_name(id));
1902 BLI_string_split_name_number(BKE_id_name(id), '.', prev_name_root, &prev_number);
1903 BLI_string_split_name_number(name, '.', new_name_root, &new_number);
1904 }
1905
1906 ID *id_other = BKE_libblock_find_name(&bmain, GS(id.name), orig_name, id.lib);
1907 BLI_assert(id_other);
1908
1909 /* In case of #RenameExistingSameRoot, the existing ID (`id_other`) is only renamed if it has
1910 * the same 'root' name as the current name of the renamed `id`. */
1912 (mode == IDNewNameMode::RenameExistingSameRoot && STREQ(prev_name_root, new_name_root)))
1913 {
1914 BLI_strncpy(id_other->name + 2, name, sizeof(id_other->name) - 2);
1915 id_sort_by_name(&lb, id_other, nullptr);
1916
1917 const bool is_idname_changed = !STREQ(BKE_id_name(id), orig_name);
1919 if (is_idname_changed) {
1920 BLI_strncpy(id.name + 2, orig_name, sizeof(id.name) - 2);
1922 }
1923 id_sort_by_name(&lb, &id, nullptr);
1924 return result;
1925 }
1926 }
1927
1928 /* The requested new name may be available (not collide with any other existing ID name), but
1929 * still differ from the current name of the renamed ID.
1930 * Conversely, the requested new name may have been colliding with an existing one, and the
1931 * generated unique name may end up being the current ID's name. */
1932 const bool is_idname_changed = !STREQ(BKE_id_name(id), name);
1933
1935 if (is_idname_changed) {
1936 BLI_strncpy(id.name + 2, name, sizeof(id.name) - 2);
1937 result.action = had_name_collision ? IDNewNameResult::Action::RENAMED_COLLISION_ADJUSTED :
1939 }
1940 else if (had_name_collision) {
1942 }
1943 id_sort_by_name(&lb, &id, nullptr);
1944 return result;
1945}
1946
1948{
1949 ID *id;
1950
1951 FOREACH_MAIN_ID_BEGIN (bmain, id) {
1953 }
1955}
1956
1958{
1959 ID **id_pointer = cb_data->id_pointer;
1960 const int cb_flag = cb_data->cb_flag;
1961 const bool do_linked_only = bool(POINTER_AS_INT(cb_data->user_data));
1962
1963 if (*id_pointer == nullptr) {
1964 return IDWALK_RET_NOP;
1965 }
1966 if (do_linked_only && !ID_IS_LINKED(*id_pointer)) {
1967 return IDWALK_RET_NOP;
1968 }
1969
1970 if (cb_flag & IDWALK_CB_USER) {
1971 /* Do not touch to direct/indirect linked status here... */
1972 id_us_plus_no_lib(*id_pointer);
1973 }
1974 if (cb_flag & IDWALK_CB_USER_ONE) {
1975 id_us_ensure_real(*id_pointer);
1976 }
1977
1978 return IDWALK_RET_NOP;
1979}
1980
1981void BKE_main_id_refcount_recompute(Main *bmain, const bool do_linked_only)
1982{
1983 ID *id;
1984
1985 FOREACH_MAIN_ID_BEGIN (bmain, id) {
1986 if (!ID_IS_LINKED(id) && do_linked_only) {
1987 continue;
1988 }
1989 id->us = ID_FAKE_USERS(id);
1990 /* Note that we keep EXTRAUSER tag here, since some UI users may define it too... */
1991 if (id->tag & ID_TAG_EXTRAUSER) {
1992 id->tag &= ~(ID_TAG_EXTRAUSER | ID_TAG_EXTRAUSER_SET);
1994 }
1995 if (ELEM(GS(id->name), ID_SCE, ID_WM, ID_WS)) {
1996 /* These IDs should always have a 'virtual' user. */
1998 }
1999 }
2001
2002 /* Go over whole Main database to re-generate proper user-counts. */
2003 FOREACH_MAIN_ID_BEGIN (bmain, id) {
2005 id,
2007 POINTER_FROM_INT(int(do_linked_only)),
2009 }
2011}
2012
2014 GSet *loop_tags,
2015 MainIDRelations *id_relations,
2016 GSet *done_ids)
2017{
2018 if (BLI_gset_haskey(done_ids, id)) {
2019 return; /* Already checked, nothing else to do. */
2020 }
2021
2022 MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
2023 BLI_ghash_lookup(id_relations->relations_from_pointers, id));
2024 BLI_gset_insert(loop_tags, id);
2025 for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != nullptr;
2026 from_id_entry = from_id_entry->next)
2027 {
2028 /* Our oh-so-beloved 'from' pointers... Those should always be ignored here, since the actual
2029 * relation we want to check is in the other way around. */
2030 if (from_id_entry->usage_flag & IDWALK_CB_LOOPBACK) {
2031 continue;
2032 }
2033
2034 ID *from_id = from_id_entry->id_pointer.from;
2035
2036 /* Shape-keys are considered 'private' to their owner ID here, and never tagged
2037 * (since they cannot be linked), so we have to switch effective parent to their owner.
2038 */
2039 if (GS(from_id->name) == ID_KE) {
2040 from_id = ((Key *)from_id)->from;
2041 }
2042
2043 if (!ID_IS_LINKED(from_id)) {
2044 /* Local user, early out to avoid some gset querying... */
2045 continue;
2046 }
2047 if (!BLI_gset_haskey(done_ids, from_id)) {
2048 if (BLI_gset_haskey(loop_tags, from_id)) {
2049 /* We are in a 'dependency loop' of IDs, this does not say us anything, skip it.
2050 * Note that this is the situation that can lead to archipelagos of linked data-blocks
2051 * (since all of them have non-local users, they would all be duplicated,
2052 * leading to a loop of unused linked data-blocks that cannot be freed since they all use
2053 * each other...). */
2054 continue;
2055 }
2056 /* Else, recursively check that user ID. */
2057 library_make_local_copying_check(from_id, loop_tags, id_relations, done_ids);
2058 }
2059
2060 if (from_id->tag & ID_TAG_DOIT) {
2061 /* This user will be fully local in future, so far so good,
2062 * nothing to do here but check next user. */
2063 }
2064 else {
2065 /* This user won't be fully local in future, so current ID won't be either.
2066 * And we are done checking it. */
2067 id->tag &= ~ID_TAG_DOIT;
2068 break;
2069 }
2070 }
2071 BLI_gset_add(done_ids, id);
2072 BLI_gset_remove(loop_tags, id, nullptr);
2073}
2074
2076 const Library *lib,
2077 GHash *old_to_new_ids,
2078 const bool untagged_only,
2079 const bool set_fake,
2080 const bool clear_asset_data)
2081{
2082 /* NOTE: Old (2.77) version was simply making (tagging) data-blocks as local,
2083 * without actually making any check whether they were also indirectly used or not...
2084 *
2085 * Current version uses regular id_make_local callback, with advanced pre-processing step to
2086 * detect all cases of IDs currently indirectly used, but which will be used by local data only
2087 * once this function is finished. This allows to avoid any unneeded duplication of IDs, and
2088 * hence all time lost afterwards to remove orphaned linked data-blocks. */
2089
2090 ListBase *lbarray[INDEX_ID_MAX];
2091
2092 LinkNode *todo_ids = nullptr;
2093 LinkNode *copied_ids = nullptr;
2094 MemArena *linklist_mem = BLI_memarena_new(512 * sizeof(*todo_ids), __func__);
2095
2096 GSet *done_ids = BLI_gset_ptr_new(__func__);
2097
2098#ifdef DEBUG_TIME
2099 TIMEIT_START(make_local);
2100#endif
2101
2102 BKE_main_relations_create(bmain, 0);
2103
2104#ifdef DEBUG_TIME
2105 printf("Pre-compute current ID relations: Done.\n");
2106 TIMEIT_VALUE_PRINT(make_local);
2107#endif
2108
2109 /* Step 1: Detect data-blocks to make local. */
2110 for (int a = set_listbasepointers(bmain, lbarray); a--;) {
2111 ID *id = static_cast<ID *>(lbarray[a]->first);
2112
2113 /* Do not explicitly make local non-linkable IDs (shape-keys, in fact),
2114 * they are assumed to be handled by real data-blocks responsible of them. */
2115 const bool do_skip = (id && !BKE_idtype_idcode_is_linkable(GS(id->name)));
2116
2117 for (; id; id = static_cast<ID *>(id->next)) {
2118 ID *ntree = (ID *)blender::bke::node_tree_from_id(id);
2119
2120 id->tag &= ~ID_TAG_DOIT;
2121 if (ntree != nullptr) {
2122 ntree->tag &= ~ID_TAG_DOIT;
2123 }
2124
2125 if (!ID_IS_LINKED(id)) {
2126 id->tag &= ~(ID_TAG_EXTERN | ID_TAG_INDIRECT | ID_TAG_NEW);
2127 id->flag &= ~ID_FLAG_INDIRECT_WEAK_LINK;
2129 ELEM(lib, nullptr, id->override_library->reference->lib) &&
2130 ((untagged_only == false) || !(id->tag & ID_TAG_PRE_EXISTING)))
2131 {
2132 /* Validating liboverride hierarchy root pointers will happen later in this function,
2133 * rather than doing it for each and every localized ID. */
2135 }
2136 }
2137 /* The check on the fourth line (ID_TAG_PRE_EXISTING) is done so it's possible to tag data
2138 * you don't want to be made local, used for appending data,
2139 * so any libdata already linked won't become local (very nasty
2140 * to discover all your links are lost after appending).
2141 * Also, never ever make proxified objects local, would not make any sense. */
2142 /* Some more notes:
2143 * - Shape-keys are never tagged here (since they are not linkable).
2144 * - Node-trees used in materials etc. have to be tagged manually,
2145 * since they do not exist in Main (!).
2146 * This is ok-ish on 'make local' side of things
2147 * (since those are handled by their 'owner' IDs),
2148 * but complicates slightly the pre-processing of relations between IDs at step 2... */
2149 else if (!do_skip && id->tag & (ID_TAG_EXTERN | ID_TAG_INDIRECT | ID_TAG_NEW) &&
2150 ELEM(lib, nullptr, id->lib) &&
2151 ((untagged_only == false) || !(id->tag & ID_TAG_PRE_EXISTING)))
2152 {
2153 BLI_linklist_prepend_arena(&todo_ids, id, linklist_mem);
2154 id->tag |= ID_TAG_DOIT;
2155
2156 /* Tag those nasty non-ID node-trees,
2157 * but do not add them to todo list, making them local is handled by 'owner' ID.
2158 * This is needed for library_make_local_copying_check() to work OK at step 2. */
2159 if (ntree != nullptr) {
2160 ntree->tag |= ID_TAG_DOIT;
2161 }
2162 }
2163 else {
2164 /* Linked ID that we won't be making local (needed info for step 2, see below). */
2165 BLI_gset_add(done_ids, id);
2166 }
2167 }
2168 }
2169
2170#ifdef DEBUG_TIME
2171 printf("Step 1: Detect data-blocks to make local: Done.\n");
2172 TIMEIT_VALUE_PRINT(make_local);
2173#endif
2174
2175 /* Step 2: Check which data-blocks we can directly make local
2176 * (because they are only used by already, or future, local data),
2177 * others will need to be duplicated. */
2178 GSet *loop_tags = BLI_gset_ptr_new(__func__);
2179 for (LinkNode *it = todo_ids; it; it = it->next) {
2181 static_cast<ID *>(it->link), loop_tags, bmain->relations, done_ids);
2182 BLI_assert(BLI_gset_len(loop_tags) == 0);
2183 }
2184 BLI_gset_free(loop_tags, nullptr);
2185 BLI_gset_free(done_ids, nullptr);
2186
2187 /* Next step will most likely add new IDs, better to get rid of this mapping now. */
2189
2190#ifdef DEBUG_TIME
2191 printf("Step 2: Check which data-blocks we can directly make local: Done.\n");
2192 TIMEIT_VALUE_PRINT(make_local);
2193#endif
2194
2195 const int make_local_flags = clear_asset_data ? LIB_ID_MAKELOCAL_ASSET_DATA_CLEAR : 0;
2196
2197 /* Step 3: Make IDs local, either directly (quick and simple), or using generic process,
2198 * which involves more complex checks and might instead
2199 * create a local copy of original linked ID. */
2200 for (LinkNode *it = todo_ids, *it_next; it; it = it_next) {
2201 it_next = it->next;
2202 ID *id = static_cast<ID *>(it->link);
2203
2204 if (id->tag & ID_TAG_DOIT) {
2205 /* We know all users of this object are local or will be made fully local, even if
2206 * currently there are some indirect usages. So instead of making a copy that we'll likely
2207 * get rid of later, directly make that data block local.
2208 * Saves a tremendous amount of time with complex scenes... */
2209 BKE_lib_id_clear_library_data(bmain, id, make_local_flags);
2210 BKE_lib_id_expand_local(bmain, id, 0);
2211 id->tag &= ~ID_TAG_DOIT;
2212
2213 if (GS(id->name) == ID_OB) {
2215 }
2216 }
2217 else {
2218 /* In this specific case, we do want to make ID local even if it has no local usage yet... */
2219 BKE_lib_id_make_local(bmain, id, make_local_flags | LIB_ID_MAKELOCAL_FULL_LIBRARY);
2220
2221 if (id->newid) {
2222 if (GS(id->newid->name) == ID_OB) {
2223 BKE_rigidbody_ensure_local_object(bmain, (Object *)id->newid);
2224 }
2225
2226 /* Reuse already allocated LinkNode (transferring it from todo_ids to copied_ids). */
2227 BLI_linklist_prepend_nlink(&copied_ids, id, it);
2228 }
2229 }
2230
2231 if (set_fake) {
2232 if (!ELEM(GS(id->name), ID_OB, ID_GR)) {
2233 /* do not set fake user on objects, groups (instancing) */
2234 id_fake_user_set(id);
2235 }
2236 }
2237 }
2238
2239#ifdef DEBUG_TIME
2240 printf("Step 3: Make IDs local: Done.\n");
2241 TIMEIT_VALUE_PRINT(make_local);
2242#endif
2243
2244 /* At this point, we are done with directly made local IDs.
2245 * Now we have to handle duplicated ones, since their
2246 * remaining linked original counterpart may not be needed anymore... */
2247 todo_ids = nullptr;
2248
2249 /* Step 4: We have to remap local usages of old (linked) ID to new (local)
2250 * ID in a separated loop,
2251 * as lbarray ordering is not enough to ensure us we did catch all dependencies
2252 * (e.g. if making local a parent object before its child...). See #48907. */
2253 /* TODO: This is now the biggest step by far (in term of processing time).
2254 * We may be able to gain here by using again main->relations mapping, but...
2255 * this implies BKE_libblock_remap & co to be able to update main->relations on the fly.
2256 * Have to think about it a bit more, and see whether new code is OK first, anyway. */
2257 for (LinkNode *it = copied_ids; it; it = it->next) {
2258 ID *id = static_cast<ID *>(it->link);
2259
2260 BLI_assert(id->newid != nullptr);
2262
2263 BKE_libblock_remap(bmain, id, id->newid, ID_REMAP_SKIP_INDIRECT_USAGE);
2264 if (old_to_new_ids) {
2265 BLI_ghash_insert(old_to_new_ids, id, id->newid);
2266 }
2267
2268 /* Special hack for groups... Thing is, since we can't instantiate them here, we need to
2269 * ensure they remain 'alive' (only instantiation is a real group 'user'... *sigh* See
2270 * #49722. */
2271 if (GS(id->name) == ID_GR && (id->tag & ID_TAG_INDIRECT) != 0) {
2272 id_us_ensure_real(id->newid);
2273 }
2274 }
2275
2276 /* Making some liboverride local may have had some impact on validity of liboverrides hierarchy
2277 * roots, these need to be re-validated/re-generated. */
2279
2280#ifdef DEBUG_TIME
2281 printf("Step 4: Remap local usages of old (linked) ID to new (local) ID: Done.\n");
2282 TIMEIT_VALUE_PRINT(make_local);
2283#endif
2284
2285 /* This is probably more of a hack than something we should do here, but...
2286 * Issue is, the whole copying + remapping done in complex cases above may leave pose-channels
2287 * of armatures in complete invalid state (more precisely, the bone pointers of the
2288 * pose-channels - very crappy cross-data-blocks relationship), so we tag it to be fully
2289 * recomputed, but this does not seems to be enough in some cases, and evaluation code ends up
2290 * trying to evaluate a not-yet-updated armature object's deformations.
2291 * Try "make all local" in 04_01_H.lighting.blend from Agent327 without this, e.g. */
2292 for (Object *ob = static_cast<Object *>(bmain->objects.first); ob;
2293 ob = static_cast<Object *>(ob->id.next))
2294 {
2295 if (ob->data != nullptr && ob->type == OB_ARMATURE && ob->pose != nullptr &&
2296 ob->pose->flag & POSE_RECALC)
2297 {
2298 BKE_pose_rebuild(bmain, ob, static_cast<bArmature *>(ob->data), true);
2299 }
2300 }
2301
2302#ifdef DEBUG_TIME
2303 printf("Hack: Forcefully rebuild armature object poses: Done.\n");
2304 TIMEIT_VALUE_PRINT(make_local);
2305#endif
2306
2308 BLI_memarena_free(linklist_mem);
2309
2310#ifdef DEBUG_TIME
2311 printf("Cleanup and finish: Done.\n");
2312 TIMEIT_END(make_local);
2313#endif
2314}
2315
2317 ID &id,
2319 const IDNewNameMode mode)
2320{
2321 BLI_assert(BKE_id_is_in_main(&bmain, &id));
2322
2323 if (STREQ(BKE_id_name(id), name.c_str())) {
2324 return {IDNewNameResult::Action::UNCHANGED, nullptr};
2325 }
2326 BKE_main_namemap_remove_name(&bmain, &id, BKE_id_name(id));
2327 ListBase &lb = *which_libbase(&bmain, GS(id.name));
2328 IDNewNameResult result = BKE_id_new_name_validate(bmain, lb, id, name.c_str(), mode, true);
2329 if (!ELEM(result.action,
2332 {
2333 bmain.is_memfile_undo_written = false;
2334 }
2335 return result;
2336}
2337
2339 ID &id,
2341 const IDNewNameMode mode)
2342{
2343 const IDNewNameResult result = BKE_libblock_rename(bmain, id, name, mode);
2344
2345 if (!ELEM(result.action,
2348 {
2349 switch (GS(id.name)) {
2350 case ID_OB: {
2351 Object &ob = reinterpret_cast<Object &>(id);
2352 if (ob.type == OB_MBALL) {
2354 }
2355 break;
2356 }
2357 default:
2358 break;
2359 }
2360 }
2361
2362 return result;
2363}
2364
2365void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separator_char)
2366{
2368
2369 if (ID_IS_LINKED(id)) {
2370 const size_t idname_len = strlen(BKE_id_name(*id));
2371 const size_t libname_len = strlen(BKE_id_name(id->lib->id));
2372
2373 name[idname_len] = separator_char ? separator_char : ' ';
2374 name[idname_len + 1] = '[';
2376 name + idname_len + 2, BKE_id_name(id->lib->id), MAX_ID_FULL_NAME - (idname_len + 2));
2377 name[idname_len + 2 + libname_len] = ']';
2378 name[idname_len + 2 + libname_len + 1] = '\0';
2379 }
2380}
2381
2383 const ID *id,
2384 const bool add_lib_hint,
2385 char separator_char,
2386 int *r_prefix_len)
2387{
2388 int i = 0;
2389
2390 if (add_lib_hint) {
2391 name[i++] = id->lib ? (ID_MISSING(id) ? 'M' : 'L') : ID_IS_OVERRIDE_LIBRARY(id) ? 'O' : ' ';
2392 }
2393 name[i++] = (id->flag & ID_FLAG_FAKEUSER) ? 'F' : ((id->us == 0) ? '0' : ' ');
2394 name[i++] = ' ';
2395
2396 BKE_id_full_name_get(name + i, id, separator_char);
2397
2398 if (r_prefix_len) {
2399 *r_prefix_len = i;
2400 }
2401}
2402
2404{
2405 if (!ID_IS_LINKED(id)) {
2406 return BLI_strdup(id->name);
2407 }
2408
2409 /* Prefix with an ascii character in the range of 32..96 (visible)
2410 * this ensures we can't have a library ID pair that collide.
2411 * Where 'LIfooOBbarOBbaz' could be ('LIfoo, OBbarOBbaz') or ('LIfooOBbar', 'OBbaz'). */
2412 const char ascii_len = strlen(BKE_id_name(id->lib->id)) + 32;
2413 return BLI_sprintfN("%c%s%s", ascii_len, id->lib->id.name, id->name);
2414}
2415
2416void BKE_id_tag_set_atomic(ID *id, int tag)
2417{
2418 atomic_fetch_and_or_int32(&id->tag, tag);
2419}
2420
2421void BKE_id_tag_clear_atomic(ID *id, int tag)
2422{
2423 atomic_fetch_and_and_int32(&id->tag, ~tag);
2424}
2425
2426bool BKE_id_is_in_main(Main *bmain, ID *id)
2427{
2428 /* We do not want to fail when id is nullptr here, even though this is a bit strange behavior...
2429 */
2430 return (id == nullptr || BLI_findindex(which_libbase(bmain, GS(id->name)), id) != -1);
2431}
2432
2434{
2435 return BKE_id_is_in_main(G_MAIN, id);
2436}
2437
2439{
2440 return ID_IS_EDITABLE(id) && !ID_IS_OVERRIDE_LIBRARY(id) &&
2442}
2443
2444ID *BKE_id_owner_get(ID *id, const bool debug_relationship_assert)
2445{
2446 const IDTypeInfo *idtype = BKE_idtype_get_info_from_id(id);
2447 if (idtype->owner_pointer_get != nullptr) {
2448 ID **owner_id_pointer = idtype->owner_pointer_get(id, debug_relationship_assert);
2449 if (owner_id_pointer != nullptr) {
2450 return *owner_id_pointer;
2451 }
2452 }
2453 return nullptr;
2454}
2455
2456bool BKE_id_is_editable(const Main *bmain, const ID *id)
2457{
2459}
2460
2461bool BKE_id_can_use_id(const ID &id_from, const ID &id_to)
2462{
2463 /* Can't point from linked to local. */
2464 if (id_from.lib && !id_to.lib) {
2465 return false;
2466 }
2467 /* Can't point from ID in main database to one outside of it. */
2468 if (!(id_from.tag & ID_TAG_NO_MAIN) && (id_to.tag & ID_TAG_NO_MAIN)) {
2469 return false;
2470 }
2471
2472 return true;
2473}
2474
2475/************************* Datablock order in UI **************************/
2476
2477static int *id_order_get(ID *id)
2478{
2479 /* Only for workspace tabs currently. */
2480 switch (GS(id->name)) {
2481 case ID_WS:
2482 return &((WorkSpace *)id)->order;
2483 default:
2484 return nullptr;
2485 }
2486}
2487
2488static bool id_order_compare(ID *a, ID *b)
2489{
2490 int *order_a = id_order_get(a);
2491 int *order_b = id_order_get(b);
2492
2493 if (order_a && order_b) {
2494 if (*order_a < *order_b) {
2495 return true;
2496 }
2497 if (*order_a > *order_b) {
2498 return false;
2499 }
2500 }
2501
2502 return strcmp(a->name, b->name) < 0;
2503}
2504
2506{
2507 Vector<ID *> ordered;
2508
2509 LISTBASE_FOREACH (ID *, id, lb) {
2510 ordered.append(id);
2511 }
2512
2513 std::sort(ordered.begin(), ordered.end(), id_order_compare);
2514
2515 for (const int i : ordered.index_range()) {
2516 if (int *order = id_order_get(ordered[i])) {
2517 *order = i;
2518 }
2519 }
2520
2521 return ordered;
2522}
2523
2524void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after)
2525{
2526 int *id_order = id_order_get(id);
2527 int relative_order;
2528
2529 if (relative) {
2530 relative_order = *id_order_get(relative);
2531 }
2532 else {
2533 relative_order = (after) ? BLI_listbase_count(lb) : 0;
2534 }
2535
2536 if (after) {
2537 /* Insert after. */
2538 LISTBASE_FOREACH (ID *, other, lb) {
2539 int *order = id_order_get(other);
2540 if (*order > relative_order) {
2541 (*order)++;
2542 }
2543 }
2544
2545 *id_order = relative_order + 1;
2546 }
2547 else {
2548 /* Insert before. */
2549 LISTBASE_FOREACH (ID *, other, lb) {
2550 int *order = id_order_get(other);
2551 if (*order < relative_order) {
2552 (*order)--;
2553 }
2554 }
2555
2556 *id_order = relative_order - 1;
2557 }
2558}
2559
2561{
2562 if (id->asset_data) {
2563 BKE_asset_metadata_write(writer, id->asset_data);
2564 }
2565
2566 if (id->library_weak_reference != nullptr) {
2567 BLO_write_struct(writer, LibraryWeakReference, id->library_weak_reference);
2568 }
2569
2570 /* ID_WM's id->properties are considered runtime only, and never written in .blend file. */
2571 if (id->properties && !ELEM(GS(id->name), ID_WM)) {
2572 IDP_BlendWrite(writer, id->properties);
2573 }
2574
2575 BKE_animdata_blend_write(writer, id);
2576
2577 if (id->override_library) {
2578 BLO_write_struct(writer, IDOverrideLibrary, id->override_library);
2579
2580 BLO_write_struct_list(writer, IDOverrideLibraryProperty, &id->override_library->properties);
2581 LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) {
2582 BLO_write_string(writer, op->rna_path);
2583
2585 LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
2586 if (opop->subitem_reference_name) {
2587 BLO_write_string(writer, opop->subitem_reference_name);
2588 }
2589 if (opop->subitem_local_name) {
2590 BLO_write_string(writer, opop->subitem_local_name);
2591 }
2592 }
2593 }
2594 }
2595}
AnimData * BKE_animdata_copy_in_lib(Main *bmain, std::optional< Library * > owner_library, AnimData *adt, int flag)
Definition anim_data.cc:364
void BKE_animdata_blend_write(BlendWriter *writer, ID *id)
bool id_can_have_animdata(const ID *id)
Definition anim_data.cc:79
void BKE_animdata_duplicate_id_action(Main *bmain, ID *id, uint duplicate_flags)
Definition anim_data.cc:521
void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, bool do_id_user)
Definition armature.cc:2767
AssetMetaData * BKE_asset_metadata_copy(const AssetMetaData *source)
Definition asset.cc:44
void BKE_asset_metadata_free(AssetMetaData **asset_data)
Definition asset.cc:38
void BKE_asset_metadata_write(BlendWriter *writer, AssetMetaData *asset_data)
Definition asset.cc:204
void BKE_bpath_foreach_path_id(BPathForeachPathData *bpath_data, ID *id)
Definition bpath.cc:73
@ BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE
Definition BKE_bpath.hh:55
Main * CTX_data_main(const bContext *C)
#define G_MAIN
IDProperty * IDP_CopyProperty_ex(const IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:843
void IDP_BlendWrite(BlendWriter *writer, const IDProperty *prop)
Definition idprop.cc:1437
@ IDTYPE_FLAGS_NO_COPY
Definition BKE_idtype.hh:30
@ IDTYPE_FLAGS_NO_LIBLINKING
Definition BKE_idtype.hh:32
const IDTypeInfo * BKE_idtype_get_info_from_id(const ID *id)
Definition idtype.cc:150
const IDTypeInfo * BKE_idtype_get_info_from_idcode(short id_code)
Definition idtype.cc:145
const char * BKE_idtype_idcode_to_name(short idcode)
Definition idtype.cc:168
bool BKE_idtype_idcode_is_linkable(short idcode)
Definition idtype.cc:201
Key ** BKE_key_from_id_p(ID *id)
Definition key.cc:1775
Key * BKE_key_from_id(ID *id)
Definition key.cc:1800
IDNewNameMode
@ LIB_ID_CREATE_NO_ALLOCATE
@ LIB_ID_COPY_ASSET_METADATA
@ LIB_ID_COPY_NO_LIB_OVERRIDE
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
@ LIB_ID_CREATE_LOCAL
@ LIB_ID_COPY_ACTIONS
@ LIB_ID_CREATE_NO_USER_REFCOUNT
@ LIB_ID_COPY_NO_ANIMDATA
@ LIB_ID_CREATE_NO_MAIN
@ LIB_ID_COPY_DEFAULT
@ LIB_ID_CREATE_NO_DEG_TAG
#define MAIN_ID_SESSION_UID_UNSET
#define MAX_ID_FULL_NAME_UI
const char * BKE_id_name(const ID &id)
@ LIB_ID_MAKELOCAL_INDIRECT
@ 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
#define MAX_ID_FULL_NAME
void BKE_lib_override_library_main_hierarchy_root_ensure(Main *bmain)
bool BKE_lib_override_library_is_system_defined(const Main *bmain, const ID *id)
void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id, bool do_full_copy)
void BKE_lib_override_library_make_local(Main *bmain, ID *id)
void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *r_is_used_local, bool *r_is_used_linked)
Definition lib_query.cc:618
@ IDWALK_RET_STOP_ITER
@ IDWALK_RET_NOP
@ IDWALK_CB_LOOPBACK
@ IDWALK_CB_USER_ONE
@ IDWALK_CB_USER
@ IDWALK_CB_EMBEDDED_NOT_OWNING
@ IDWALK_CB_EMBEDDED
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_INCLUDE_UI
@ IDWALK_IGNORE_MISSING_OWNER_ID
@ IDWALK_NOP
@ IDWALK_READONLY
@ ID_REMAP_SKIP_INDIRECT_USAGE
void BKE_libblock_relink_multiple(Main *bmain, const blender::Span< ID * > ids, eIDRemapType remap_type, blender::bke::id::IDRemapper &id_remapper, int remap_flags)
Definition lib_remap.cc:782
@ ID_REMAP_TYPE_REMAP
void void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, int remap_flags) ATTR_NONNULL(1
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:500
ListBase * which_libbase(Main *bmain, short type)
Definition main.cc:842
void BKE_main_lock(Main *bmain)
Definition main.cc:479
int set_listbasepointers(Main *bmain, ListBase *lb[])
Definition main.cc:929
void BKE_main_relations_create(Main *bmain, short flag)
Definition main.cc:544
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:494
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:832
void BKE_main_unlock(Main *bmain)
Definition main.cc:484
void BKE_main_relations_free(Main *bmain)
Definition main.cc:580
bool BKE_main_namemap_get_name(Main *bmain, ID *id, char *name, const bool do_unique_in_bmain) ATTR_NONNULL()
void BKE_main_namemap_remove_name(Main *bmain, ID *id, const char *name) ATTR_NONNULL()
API for Blender-side Rigid Body stuff.
void BKE_rigidbody_ensure_local_object(struct Main *bmain, struct Object *ob)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
struct GSet GSet
Definition BLI_ghash.h:341
GSet * BLI_gset_ptr_new(const char *info)
bool BLI_gset_haskey(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:1004
unsigned int BLI_gset_len(const GSet *gs) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:954
void BLI_gset_insert(GSet *gs, void *key)
Definition BLI_ghash.c:959
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:731
GSet * BLI_gset_str_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.c:707
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition BLI_ghash.c:1034
bool BLI_gset_add(GSet *gs, void *key)
Definition BLI_ghash.c:966
bool BLI_gset_remove(GSet *gs, const void *key, GSetKeyFreeFP keyfreefp)
Definition BLI_ghash.c:999
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:90
#define LISTBASE_FOREACH(type, var, list)
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition listbase.cc:331
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
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition listbase.cc:370
void * BLI_listbase_findafter_string_ptr(struct Link *link, const char *id, const int offset)
Definition listbase.cc:671
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
#define FILE_MAXFILE
#define FILE_MAX
int BLI_path_normalize(char *path) ATTR_NONNULL(1)
bool BLI_path_is_rel(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool void BLI_path_rel(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1)
#define FILE_MAXDIR
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.c:40
#define STRNCPY(dst, src)
Definition BLI_string.h:593
int char char int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
int BLI_str_utf8_invalid_strip(char *str, size_t length) ATTR_NONNULL(1)
#define STRNCPY_UTF8(dst, src)
size_t BLI_string_split_name_number(const char *name, char delim, char *r_name_left, int *r_number) ATTR_NONNULL(1
unsigned int uint
Utility defines for timing/benchmarks.
#define TIMEIT_START(var)
#define TIMEIT_VALUE_PRINT(var)
#define TIMEIT_END(var)
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define BLO_write_struct_list(writer, struct_name, list_ptr)
#define BLT_I18NCONTEXT_ID_ID
#define DATA_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:182
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_id_type_tag(Main *bmain, short id_type)
void DEG_id_tag_update_ex(Main *bmain, ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
bool DEG_is_evaluated_id(const ID *id)
ID * DEG_get_original_id(ID *id)
ID and Library types, which are fundamental for SDNA.
#define ID_IS_OVERRIDE_LIBRARY_VIRTUAL(_id)
Definition DNA_ID.h:680
#define ID_FAKE_USERS(id)
Definition DNA_ID.h:616
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1021
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_TAG_FOR_UNDO
Definition DNA_ID.h:1119
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1044
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
#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
struct ID ID
#define ID_IS_ASSET(_id)
Definition DNA_ID.h:690
#define ID_TYPE_IS_DEPRECATED(id_type)
Definition DNA_ID.h:700
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:658
@ ID_FLAG_INDIRECT_WEAK_LINK
Definition DNA_ID.h:731
@ ID_FLAG_EMBEDDED_DATA_LIB_OVERRIDE
Definition DNA_ID.h:736
@ ID_FLAG_FAKEUSER
Definition DNA_ID.h:720
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:725
@ ID_TAG_NEW
Definition DNA_ID.h:865
@ ID_TAG_COPIED_ON_EVAL
Definition DNA_ID.h:964
@ ID_TAG_EXTRAUSER
Definition DNA_ID.h:824
@ ID_TAG_NO_USER_REFCOUNT
Definition DNA_ID.h:985
@ ID_TAG_TEMP_MAIN
Definition DNA_ID.h:938
@ ID_TAG_INDIRECT
Definition DNA_ID.h:794
@ ID_TAG_PRE_EXISTING
Definition DNA_ID.h:872
@ ID_TAG_EXTERN
Definition DNA_ID.h:788
@ ID_TAG_LOCALIZED
Definition DNA_ID.h:954
@ ID_TAG_DOIT
Definition DNA_ID.h:1003
@ ID_TAG_NOT_ALLOCATED
Definition DNA_ID.h:992
@ ID_TAG_EXTRAUSER_SET
Definition DNA_ID.h:830
@ ID_TAG_NO_MAIN
Definition DNA_ID.h:945
#define INDEX_ID_MAX
Definition DNA_ID.h:1328
@ INDEX_ID_NULL
Definition DNA_ID.h:1325
#define ID_REAL_USERS(id)
Definition DNA_ID.h:637
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:683
#define ID_NEW_SET(_id, _idn)
Definition DNA_ID.h:707
#define ID_MISSING(_id)
Definition DNA_ID.h:652
@ ID_WM
@ ID_WS
@ ID_NT
@ ID_KE
@ ID_SCE
@ ID_GD_LEGACY
@ ID_GR
@ ID_OB
#define ID_LINK_PLACEHOLDER
@ POSE_RECALC
Object groups, one object can be in many groups at once.
@ OB_MBALL
@ OB_ARMATURE
eDupli_ID_Flags
@ USER_DUP_LINKED_ID
Read Guarded memory(de)allocation.
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE int32_t atomic_fetch_and_or_int32(int32_t *p, int32_t x)
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x)
void append(const T &value)
IndexRange index_range() const
void add(ID *old_id, ID *new_id)
local_group_size(16, 16) .push_constant(Type b
#define printf
#define offsetof(t, d)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
#define GS(x)
Definition iris.cc:202
void BKE_id_newptr_and_tag_clear(ID *id)
Definition lib_id.cc:405
ID * BKE_id_owner_get(ID *id, const bool debug_relationship_assert)
Definition lib_id.cc:2444
void BKE_libblock_init_empty(ID *id)
Definition lib_id.cc:1420
void id_lib_extern(ID *id)
Definition lib_id.cc:283
void BKE_main_id_refcount_recompute(Main *bmain, const bool do_linked_only)
Definition lib_id.cc:1981
void * BKE_id_new_in_lib(Main *bmain, std::optional< Library * > owner_library, const short type, const char *name)
Definition lib_id.cc:1464
void BKE_main_id_repair_duplicate_names_listbase(Main *bmain, ListBase *lb)
Definition lib_id.cc:1235
void BKE_library_make_local(Main *bmain, const Library *lib, GHash *old_to_new_ids, const bool untagged_only, const bool set_fake, const bool clear_asset_data)
Definition lib_id.cc:2075
static int id_copy_libmanagement_cb(LibraryIDLinkCallbackData *cb_data)
Definition lib_id.cc:620
#define ID_SORT_STEP_SIZE
ID * BKE_id_copy_for_use_in_bmain(Main *bmain, const ID *id)
Definition lib_id.cc:834
void BKE_id_tag_clear_atomic(ID *id, int tag)
Definition lib_id.cc:2421
void BKE_lib_id_clear_library_data(Main *bmain, ID *id, const int flags)
Definition lib_id.cc:206
bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
Definition lib_id.cc:1034
ID * BKE_libblock_find_name(Main *bmain, const short type, const char *name, const std::optional< Library * > lib)
Definition lib_id.cc:1657
void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **new_id_p, const int orig_flag)
Definition lib_id.cc:1641
void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separator_char)
Definition lib_id.cc:2365
ID * BKE_libblock_find_name_and_library(Main *bmain, const short type, const char *name, const char *lib_name)
Definition lib_id.cc:1687
static bool lib_id_library_local_paths_callback(BPathForeachPathData *bpath_data, char *path_dst, size_t path_dst_maxncpy, const char *path_src)
Definition lib_id.cc:127
bool BKE_id_is_editable(const Main *bmain, const ID *id)
Definition lib_id.cc:2456
static int id_refcount_recompute_callback(LibraryIDLinkCallbackData *cb_data)
Definition lib_id.cc:1957
char * BKE_id_to_unique_string_key(const ID *id)
Definition lib_id.cc:2403
void BKE_main_id_flag_listbase(ListBase *lb, const int flag, const bool value)
Definition lib_id.cc:1209
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
bool BKE_id_copy_is_allowed(const ID *id)
Definition lib_id.cc:647
void BKE_main_id_tag_idcode(Main *mainvar, const short type, const int tag, const bool value)
Definition lib_id.cc:1191
void BKE_libblock_management_main_remove(Main *bmain, void *idv)
Definition lib_id.cc:1130
ID * BKE_libblock_find_name_and_library_filepath(Main *bmain, short type, const char *name, const char *lib_filepath_abs)
Definition lib_id.cc:1715
static int libblock_management_us_plus(LibraryIDLinkCallbackData *cb_data)
Definition lib_id.cc:1071
void BKE_lib_id_expand_local(Main *bmain, ID *id, const int flags)
Definition lib_id.cc:474
static void id_swap(Main *bmain, ID *id_a, ID *id_b, const bool do_full_id, const bool do_self_remap, IDRemapper *input_remapper_id_a, IDRemapper *input_remapper_id_b, const int self_remap_flags)
Definition lib_id.cc:894
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, const int flag)
Definition lib_id.cc:760
void BKE_id_tag_set_atomic(ID *id, int tag)
Definition lib_id.cc:2416
void BKE_id_move_to_same_lib(Main &bmain, ID &id, const ID &owner_id)
Definition lib_id.cc:862
bool BKE_id_can_use_id(const ID &id_from, const ID &id_to)
Definition lib_id.cc:2461
#define LIB_ID_TYPES_NOCOPY
void id_fake_user_set(ID *id)
Definition lib_id.cc:389
void BKE_lib_id_swap(Main *bmain, ID *id_a, ID *id_b, const bool do_self_remap, const int self_remap_flags)
Definition lib_id.cc:1022
void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after)
Definition lib_id.cc:2524
void * BKE_libblock_copy(Main *bmain, const ID *id)
Definition lib_id.cc:1646
void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI], const ID *id, const bool add_lib_hint, char separator_char, int *r_prefix_len)
Definition lib_id.cc:2382
IDNewNameResult BKE_libblock_rename(Main &bmain, ID &id, blender::StringRefNull name, const IDNewNameMode mode)
Definition lib_id.cc:2316
void BKE_main_id_flag_all(Main *bmain, const int flag, const bool value)
Definition lib_id.cc:1225
void * BKE_libblock_alloc_notest(short type)
Definition lib_id.cc:1310
static void lib_id_library_local_paths(Main *bmain, Library *lib_to, Library *lib_from, ID *id)
Definition lib_id.cc:177
void BKE_libblock_copy_in_lib(Main *bmain, std::optional< Library * > owner_library, const ID *id, const ID *new_owner_id, ID **new_id_p, const int orig_flag)
Definition lib_id.cc:1503
static int lib_id_expand_local_cb(LibraryIDLinkCallbackData *cb_data)
Definition lib_id.cc:435
bool BKE_id_is_in_main(Main *bmain, ID *id)
Definition lib_id.cc:2426
void BKE_libblock_runtime_reset_remapping_status(ID *id)
Definition lib_id.cc:1434
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
Definition lib_id.cc:1947
void BKE_lib_libblock_session_uid_ensure(ID *id)
Definition lib_id.cc:1445
void * BKE_id_new_nomain(const short type, const char *name)
Definition lib_id.cc:1487
void id_us_ensure_real(ID *id)
Definition lib_id.cc:306
void BKE_lib_id_make_local_generic(Main *bmain, ID *id, const int flags)
Definition lib_id.cc:530
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 BKE_lib_id_swap_full(Main *bmain, ID *id_a, ID *id_b, const bool do_self_remap, const int self_remap_flags)
Definition lib_id.cc:1028
void BKE_libblock_management_usercounts_set(Main *bmain, void *idv)
Definition lib_id.cc:1150
void BKE_lib_id_make_local_generic_action_define(Main *bmain, ID *id, int flags, bool *r_force_local, bool *r_force_copy)
Definition lib_id.cc:488
void BKE_main_lib_objects_recalc_all(Main *bmain)
Definition lib_id.cc:1267
ID * BKE_id_copy(Main *bmain, const ID *id)
Definition lib_id.cc:765
void id_us_plus_no_lib(ID *id)
Definition lib_id.cc:335
static void library_make_local_copying_check(ID *id, GSet *loop_tags, MainIDRelations *id_relations, GSet *done_ids)
Definition lib_id.cc:2013
void BKE_main_id_tag_listbase(ListBase *lb, const int tag, const bool value)
Definition lib_id.cc:1175
void lib_id_copy_ensure_local(Main *bmain, const ID *old_id, ID *new_id, const int flags)
Definition lib_id.cc:480
void BKE_main_id_tag_all(Main *mainvar, const int tag, const bool value)
Definition lib_id.cc:1198
void id_lib_indirect_weak_link(ID *id)
Definition lib_id.cc:296
bool BKE_lib_id_make_local(Main *bmain, ID *id, const int flags)
Definition lib_id.cc:584
void * BKE_id_new(Main *bmain, const short type, const char *name)
Definition lib_id.cc:1482
void id_us_min(ID *id)
Definition lib_id.cc:359
static int * id_order_get(ID *id)
Definition lib_id.cc:2477
void * BKE_libblock_alloc_in_lib(Main *bmain, std::optional< Library * > owner_library, short type, const char *name, const int flag)
Definition lib_id.cc:1321
static uint global_session_uid
Definition lib_id.cc:1443
Vector< ID * > BKE_id_ordered_list(const ListBase *lb)
Definition lib_id.cc:2505
ID * BKE_id_copy_in_lib(Main *bmain, std::optional< Library * > owner_library, const ID *id, const ID *new_owner_id, ID **new_id_p, const int flag)
Definition lib_id.cc:656
void * BKE_libblock_alloc(Main *bmain, short type, const char *name, const int flag)
Definition lib_id.cc:1415
static CLG_LogRef LOG
Definition lib_id.cc:85
IDTypeInfo IDType_ID_LINK_PLACEHOLDER
Definition lib_id.cc:87
IDNewNameResult BKE_id_new_name_validate(Main &bmain, ListBase &lb, ID &id, const char *newname, IDNewNameMode mode, const bool do_linked_data)
Definition lib_id.cc:1850
static void id_embedded_swap(ID **embedded_id_a, ID **embedded_id_b, const bool do_full_id, IDRemapper *remapper_id_a, IDRemapper *remapper_id_b)
Definition lib_id.cc:984
static int lib_id_clear_library_data_users_update_cb(LibraryIDLinkCallbackData *cb_data)
Definition lib_id.cc:192
static int libblock_management_us_min(LibraryIDLinkCallbackData *cb_data)
Definition lib_id.cc:1085
ID * BKE_libblock_find_session_uid(Main *bmain, const short type, const uint32_t session_uid)
Definition lib_id.cc:1675
void BKE_id_blend_write(BlendWriter *writer, ID *id)
Definition lib_id.cc:2560
void BKE_libblock_management_main_add(Main *bmain, void *idv)
Definition lib_id.cc:1097
ID * BKE_id_copy_for_duplicate(Main *bmain, ID *id, const eDupli_ID_Flags duplicate_flags, const int copy_flags)
Definition lib_id.cc:770
void BKE_libblock_management_usercounts_clear(Main *bmain, void *idv)
Definition lib_id.cc:1162
static bool id_order_compare(ID *a, ID *b)
Definition lib_id.cc:2488
static int foreach_assign_id_to_orig_callback(LibraryIDLinkCallbackData *cb_data)
Definition lib_id.cc:809
size_t BKE_libblock_get_alloc_info(short type, const char **r_name)
Definition lib_id.cc:1293
bool BKE_id_can_be_asset(const ID *id)
Definition lib_id.cc:2438
IDNewNameResult BKE_id_rename(Main &bmain, ID &id, blender::StringRefNull name, const IDNewNameMode mode)
Definition lib_id.cc:2338
bool BKE_id_is_in_global_main(ID *id)
Definition lib_id.cc:2433
void BKE_lib_libblock_session_uid_renew(ID *id)
Definition lib_id.cc:1458
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
bNodeTree ** node_tree_ptr_from_id(ID *id)
Definition node.cc:3712
bNodeTree * node_tree_from_id(ID *id)
Definition node.cc:3732
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value, ReportList *reports)
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_editable(const PointerRNA *ptr, PropertyRNA *prop)
PointerRNA RNA_id_pointer_create(ID *id)
unsigned int uint32_t
Definition stdint.h:80
OnClearAssetDataFn on_clear_asset_fn
Definition BKE_asset.hh:40
const char * name
IDTypeCopyDataFunction copy_data
IDTypeInitDataFunction init_data
uint32_t flags
size_t struct_size
IDTypeMakeLocalFunction make_local
AssetTypeInfo * asset_type_info
IDTypeEmbeddedOwnerPointerGetFunction owner_pointer_get
Definition DNA_ID.h:413
unsigned int recalc
Definition DNA_ID.h:437
int tag
Definition DNA_ID.h:434
struct AssetMetaData * asset_data
Definition DNA_ID.h:422
struct Library * lib
Definition DNA_ID.h:419
int us
Definition DNA_ID.h:435
void * prev
Definition DNA_ID.h:416
IDProperty * properties
Definition DNA_ID.h:456
short flag
Definition DNA_ID.h:430
void * next
Definition DNA_ID.h:416
char name[66]
Definition DNA_ID.h:425
struct LibraryWeakReference * library_weak_reference
Definition DNA_ID.h:490
struct UniqueName_Map * name_map
Definition DNA_ID.h:497
char filepath_abs[1024]
Definition DNA_ID.h:509
struct Library_Runtime runtime
Definition DNA_ID.h:535
struct LinkNode * next
void * last
void * first
MainIDRelationsEntryItem * from_ids
Definition BKE_main.hh:67
GHash * relations_from_pointers
Definition BKE_main.hh:108
bool is_locked_for_linking
Definition BKE_main.hh:176
bool is_memfile_undo_written
Definition BKE_main.hh:160
Library * curlib
Definition BKE_main.hh:209
MainIDRelations * relations
Definition BKE_main.hh:260
ListBase objects
Definition BKE_main.hh:212
struct Collection * master_collection
#define N_(msgid)
static DynamicLibrary lib
PointerRNA * ptr
Definition wm_files.cc:4126
uint8_t flag
Definition wm_window.cc:138