Blender  V3.3
lib_id.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
11 #include <ctype.h>
12 #include <stddef.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 
17 #include "CLG_log.h"
18 
19 #include "MEM_guardedalloc.h"
20 
21 /* all types are needed here, in order to do memory operations */
22 #include "DNA_ID.h"
23 #include "DNA_anim_types.h"
24 #include "DNA_collection_types.h"
25 #include "DNA_gpencil_types.h"
26 #include "DNA_key_types.h"
27 #include "DNA_node_types.h"
28 #include "DNA_workspace_types.h"
29 
30 #include "BLI_utildefines.h"
31 
32 #include "BLI_alloca.h"
33 #include "BLI_blenlib.h"
34 #include "BLI_ghash.h"
35 #include "BLI_linklist.h"
36 #include "BLI_memarena.h"
37 #include "BLI_string_utils.h"
38 
39 #include "BLT_translation.h"
40 
41 #include "BKE_anim_data.h"
42 #include "BKE_armature.h"
43 #include "BKE_asset.h"
44 #include "BKE_bpath.h"
45 #include "BKE_context.h"
46 #include "BKE_global.h"
47 #include "BKE_gpencil.h"
48 #include "BKE_idprop.h"
49 #include "BKE_idtype.h"
50 #include "BKE_key.h"
51 #include "BKE_lib_id.h"
52 #include "BKE_lib_override.h"
53 #include "BKE_lib_query.h"
54 #include "BKE_lib_remap.h"
55 #include "BKE_main.h"
56 #include "BKE_main_namemap.h"
57 #include "BKE_node.h"
58 #include "BKE_rigidbody.h"
59 
60 #include "DEG_depsgraph.h"
61 #include "DEG_depsgraph_build.h"
62 
63 #include "RNA_access.h"
64 
65 #include "BLO_read_write.h"
66 
67 #include "atomic_ops.h"
68 
69 //#define DEBUG_TIME
70 
71 #ifdef DEBUG_TIME
72 # include "PIL_time_utildefines.h"
73 #endif
74 
75 static CLG_LogRef LOG = {.identifier = "bke.lib_id"};
76 
79  .id_filter = 0,
80  .main_listbase_index = INDEX_ID_NULL,
81  .struct_size = sizeof(ID),
82  .name = "LinkPlaceholder",
83  .name_plural = "link_placeholders",
84  .translation_context = BLT_I18NCONTEXT_ID_ID,
86  .asset_type_info = NULL,
87 
88  .init_data = NULL,
89  .copy_data = NULL,
90  .free_data = NULL,
91  .make_local = NULL,
92  .foreach_id = NULL,
93  .foreach_cache = NULL,
94  .foreach_path = NULL,
95  .owner_get = NULL,
96 
97  .blend_write = NULL,
98  .blend_read_data = NULL,
99  .blend_read_lib = NULL,
100  .blend_read_expand = NULL,
101 
102  .blend_read_undo_preserve = NULL,
103 
104  .lib_override_apply_post = NULL,
105 };
106 
107 /* GS reads the memory pointed at in a specific ordering.
108  * only use this definition, makes little and big endian systems
109  * work fine, in conjunction with MAKE_ID */
110 
111 /* ************* general ************************ */
112 
118  char *r_path_dst,
119  const char *path_src)
120 {
121  const char **data = bpath_data->user_data;
122  /* be sure there is low chance of the path being too short */
123  char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE];
124  const char *base_new = data[0];
125  const char *base_old = data[1];
126 
127  if (BLI_path_is_rel(base_old)) {
128  CLOG_ERROR(&LOG, "old base path '%s' is not absolute.", base_old);
129  return false;
130  }
131 
132  /* Make referenced file absolute. This would be a side-effect of
133  * BLI_path_normalize, but we do it explicitly so we know if it changed. */
134  BLI_strncpy(filepath, path_src, FILE_MAX);
135  if (BLI_path_abs(filepath, base_old)) {
136  /* Path was relative and is now absolute. Remap.
137  * Important BLI_path_normalize runs before the path is made relative
138  * because it won't work for paths that start with "//../" */
139  BLI_path_normalize(base_new, filepath);
140  BLI_path_rel(filepath, base_new);
141  BLI_strncpy(r_path_dst, filepath, FILE_MAX);
142  return true;
143  }
144 
145  /* Path was not relative to begin with. */
146  return false;
147 }
148 
153 /* TODO: This can probably be replaced by an ID-level version of #BKE_bpath_relative_rebase. */
154 static void lib_id_library_local_paths(Main *bmain, Library *lib, ID *id)
155 {
156  const char *bpath_user_data[2] = {BKE_main_blendfile_path(bmain), lib->filepath_abs};
157 
159  &(BPathForeachPathData){.bmain = bmain,
160  .callback_function = lib_id_library_local_paths_callback,
162  .user_data = (void *)bpath_user_data},
163  id);
164 }
165 
167 {
168  ID *id = cb_data->user_data;
169  if (*cb_data->id_pointer == id) {
172  return IDWALK_RET_STOP_ITER;
173  }
174  return IDWALK_RET_NOP;
175 }
176 
177 void BKE_lib_id_clear_library_data(Main *bmain, ID *id, const int flags)
178 {
179  const bool id_in_mainlist = (id->tag & LIB_TAG_NO_MAIN) == 0 &&
180  (id->flag & LIB_EMBEDDED_DATA) == 0;
181 
182  if (id_in_mainlist) {
183  BKE_main_namemap_remove_name(bmain, id, id->name + 2);
184  }
185 
186  lib_id_library_local_paths(bmain, id->lib, id);
187 
188  id_fake_user_clear(id);
189 
190  id->lib = NULL;
191  id->tag &= ~(LIB_TAG_INDIRECT | LIB_TAG_EXTERN);
192  id->flag &= ~LIB_INDIRECT_WEAK_LINK;
193  if (id_in_mainlist) {
194  if (BKE_id_new_name_validate(bmain, which_libbase(bmain, GS(id->name)), id, NULL, false)) {
195  bmain->is_memfile_undo_written = false;
196  }
197  }
198 
199  /* Conceptually, an ID made local is not the same as the linked one anymore. Reflect that by
200  * regenerating its session UUID. */
201  if ((id->tag & LIB_TAG_TEMP_MAIN) == 0) {
203  }
204 
205  if (ID_IS_ASSET(id)) {
206  if ((flags & LIB_ID_MAKELOCAL_ASSET_DATA_CLEAR) != 0) {
208  }
209  else {
210  /* Assets should always have a fake user. Ensure this is the case after "Make Local". */
211  id_fake_user_set(id);
212  }
213  }
214 
215  /* We need to tag this IDs and all of its users, conceptually new local ID and original linked
216  * ones are two completely different data-blocks that were virtually remapped, even though in
217  * reality they remain the same data. For undo this info is critical now. */
219  ID *id_iter;
220  FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
223  }
225 
226  /* Internal shape key blocks inside data-blocks also stores id->lib,
227  * make sure this stays in sync (note that we do not need any explicit handling for real EMBEDDED
228  * IDs here, this is down automatically in `lib_id_expand_local_cb()`. */
229  Key *key = BKE_key_from_id(id);
230  if (key != NULL) {
231  BKE_lib_id_clear_library_data(bmain, &key->id, flags);
232  }
233 
235 }
236 
237 void id_lib_extern(ID *id)
238 {
239  if (id && ID_IS_LINKED(id)) {
241  if (id->tag & LIB_TAG_INDIRECT) {
242  id->tag &= ~LIB_TAG_INDIRECT;
243  id->flag &= ~LIB_INDIRECT_WEAK_LINK;
244  id->tag |= LIB_TAG_EXTERN;
245  id->lib->parent = NULL;
246  }
247  }
248 }
249 
251 {
252  if (id && ID_IS_LINKED(id)) {
254  if (id->tag & LIB_TAG_INDIRECT) {
255  id->flag |= LIB_INDIRECT_WEAK_LINK;
256  }
257  }
258 }
259 
261 {
262  if (id) {
263  const int limit = ID_FAKE_USERS(id);
264  id->tag |= LIB_TAG_EXTRAUSER;
265  if (id->us <= limit) {
266  if (id->us < limit || ((id->us == limit) && (id->tag & LIB_TAG_EXTRAUSER_SET))) {
267  CLOG_ERROR(&LOG,
268  "ID user count error: %s (from '%s')",
269  id->name,
270  id->lib ? id->lib->filepath_abs : "[Main]");
271  }
272  id->us = limit + 1;
273  id->tag |= LIB_TAG_EXTRAUSER_SET;
274  }
275  }
276 }
277 
279 {
280  if (id && (id->tag & LIB_TAG_EXTRAUSER)) {
281  if (id->tag & LIB_TAG_EXTRAUSER_SET) {
282  id->us--;
283  BLI_assert(id->us >= ID_FAKE_USERS(id));
284  }
286  }
287 }
288 
290 {
291  if (id) {
292  if ((id->tag & LIB_TAG_EXTRAUSER) && (id->tag & LIB_TAG_EXTRAUSER_SET)) {
293  BLI_assert(id->us >= 1);
294  /* No need to increase count, just tag extra user as no more set.
295  * Avoids annoying & inconsistent +1 in user count. */
296  id->tag &= ~LIB_TAG_EXTRAUSER_SET;
297  }
298  else {
299  BLI_assert(id->us >= 0);
300  id->us++;
301  }
302  }
303 }
304 
305 void id_us_plus(ID *id)
306 {
307  if (id) {
308  id_us_plus_no_lib(id);
309  id_lib_extern(id);
310  }
311 }
312 
313 void id_us_min(ID *id)
314 {
315  if (id) {
316  const int limit = ID_FAKE_USERS(id);
317 
318  if (id->us <= limit) {
319  if (!ID_TYPE_IS_DEPRECATED(GS(id->name))) {
320  /* Do not assert on deprecated ID types, we cannot really ensure that their ID refcounting
321  * is valid... */
322  CLOG_ERROR(&LOG,
323  "ID user decrement error: %s (from '%s'): %d <= %d",
324  id->name,
325  id->lib ? id->lib->filepath_abs : "[Main]",
326  id->us,
327  limit);
328  }
329  id->us = limit;
330  }
331  else {
332  id->us--;
333  }
334 
335  if ((id->us == limit) && (id->tag & LIB_TAG_EXTRAUSER)) {
336  /* We need an extra user here, but never actually incremented user count for it so far,
337  * do it now. */
338  id_us_ensure_real(id);
339  }
340  }
341 }
342 
344 {
345  if (id && !(id->flag & LIB_FAKEUSER)) {
346  id->flag |= LIB_FAKEUSER;
347  id_us_plus(id);
348  }
349 }
350 
352 {
353  if (id && (id->flag & LIB_FAKEUSER)) {
354  id->flag &= ~LIB_FAKEUSER;
355  id_us_min(id);
356  }
357 }
358 
360 {
361  /* We assume that if this ID has no new ID, its embedded data has not either. */
362  if (id->newid == NULL) {
363  return;
364  }
365 
366  id->newid->tag &= ~LIB_TAG_NEW;
367  id->newid = NULL;
368 
369  /* Deal with embedded data too. */
370  /* NOTE: even though ShapeKeys are not technically embedded data currently, they behave as such
371  * in most cases, so for sake of consistency treat them as such here. Also mirrors the behavior
372  * in `BKE_lib_id_make_local`. */
373  Key *key = BKE_key_from_id(id);
374  if (key != NULL) {
376  }
377  bNodeTree *ntree = ntreeFromID(id);
378  if (ntree != NULL) {
380  }
381  if (GS(id->name) == ID_SCE) {
382  Collection *master_collection = ((Scene *)id)->master_collection;
383  if (master_collection != NULL) {
384  BKE_id_newptr_and_tag_clear(&master_collection->id);
385  }
386  }
387 }
388 
390 {
391  Main *bmain = cb_data->bmain;
392  ID *id_self = cb_data->id_self;
393  ID **id_pointer = cb_data->id_pointer;
394  int const cb_flag = cb_data->cb_flag;
395  const int flags = POINTER_AS_INT(cb_data->user_data);
396 
397  if (cb_flag & IDWALK_CB_LOOPBACK) {
398  /* We should never have anything to do with loop-back pointers here. */
399  return IDWALK_RET_NOP;
400  }
401 
402  if (cb_flag & IDWALK_CB_EMBEDDED) {
403  /* Embedded data-blocks need to be made fully local as well.
404  * Note however that in some cases (when owner ID had to be duplicated instead of being made
405  * local directly), its embedded IDs should also have already been duplicated, and hence be
406  * fully local here already. */
407  if (*id_pointer != NULL && ID_IS_LINKED(*id_pointer)) {
408  BLI_assert(*id_pointer != id_self);
409 
410  BKE_lib_id_clear_library_data(bmain, *id_pointer, flags);
411  }
412  return IDWALK_RET_NOP;
413  }
414 
415  /* Can happen that we get un-linkable ID here, e.g. with shape-key referring to itself
416  * (through drivers)...
417  * Just skip it, shape key can only be either indirectly linked, or fully local, period.
418  * And let's curse one more time that stupid useless shapekey ID type! */
419  if (*id_pointer && *id_pointer != id_self &&
420  BKE_idtype_idcode_is_linkable(GS((*id_pointer)->name))) {
421  id_lib_extern(*id_pointer);
422  }
423 
424  return IDWALK_RET_NOP;
425 }
426 
427 void BKE_lib_id_expand_local(Main *bmain, ID *id, const int flags)
428 {
431 }
432 
436 static void lib_id_copy_ensure_local(Main *bmain, const ID *old_id, ID *new_id, const int flags)
437 {
438  if (ID_IS_LINKED(old_id)) {
439  BKE_lib_id_expand_local(bmain, new_id, flags);
440  lib_id_library_local_paths(bmain, old_id->lib, new_id);
441  }
442 }
443 
445  struct Main *bmain, struct ID *id, int flags, bool *r_force_local, bool *r_force_copy)
446 {
447  bool force_local = (flags & LIB_ID_MAKELOCAL_FORCE_LOCAL) != 0;
448  bool force_copy = (flags & LIB_ID_MAKELOCAL_FORCE_COPY) != 0;
449  BLI_assert(force_copy == false || force_copy != force_local);
450 
451  if (force_local || force_copy) {
452  /* Already set by caller code, nothing to do here. */
453  *r_force_local = force_local;
454  *r_force_copy = force_copy;
455  return;
456  }
457 
458  const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
459  bool is_local = false, is_lib = false;
460 
461  /* - no user (neither lib nor local): make local (happens e.g. with UI-used only data).
462  * - only lib users: do nothing (unless force_local is set)
463  * - only local users: make local
464  * - mixed: make copy
465  * In case we make a whole lib's content local,
466  * we always want to localize, and we skip remapping (done later).
467  */
468 
469  BKE_library_ID_test_usages(bmain, id, &is_local, &is_lib);
470  if (!lib_local && !is_local && !is_lib) {
471  force_local = true;
472  }
473  else if (lib_local || is_local) {
474  if (!is_lib) {
475  force_local = true;
476  }
477  else {
478  force_copy = true;
479  }
480  }
481 
482  *r_force_local = force_local;
483  *r_force_copy = force_copy;
484 }
485 
486 void BKE_lib_id_make_local_generic(Main *bmain, ID *id, const int flags)
487 {
488  if (!ID_IS_LINKED(id)) {
489  return;
490  }
491 
492  bool force_local, force_copy;
493  BKE_lib_id_make_local_generic_action_define(bmain, id, flags, &force_local, &force_copy);
494 
495  if (force_local) {
496  BKE_lib_id_clear_library_data(bmain, id, flags);
497  BKE_lib_id_expand_local(bmain, id, flags);
498  }
499  else if (force_copy) {
500  ID *id_new = BKE_id_copy(bmain, id);
501 
502  /* Should not fail in expected use cases,
503  * but a few ID types cannot be copied (LIB, WM, SCR...). */
504  if (id_new != NULL) {
505  id_new->us = 0;
506 
507  /* setting newid is mandatory for complex make_lib_local logic... */
508  ID_NEW_SET(id, id_new);
509  Key *key = BKE_key_from_id(id), *key_new = BKE_key_from_id(id);
510  if (key && key_new) {
511  ID_NEW_SET(key, key_new);
512  }
513  bNodeTree *ntree = ntreeFromID(id), *ntree_new = ntreeFromID(id_new);
514  if (ntree && ntree_new) {
515  ID_NEW_SET(ntree, ntree_new);
516  }
517  if (GS(id->name) == ID_SCE) {
518  Collection *master_collection = ((Scene *)id)->master_collection,
519  *master_collection_new = ((Scene *)id_new)->master_collection;
520  if (master_collection && master_collection_new) {
521  ID_NEW_SET(master_collection, master_collection_new);
522  }
523  }
524 
525  const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
526  if (!lib_local) {
528  }
529  }
530  }
531 }
532 
533 bool BKE_lib_id_make_local(Main *bmain, ID *id, const int flags)
534 {
535  const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
536 
537  /* We don't care whether ID is directly or indirectly linked
538  * in case we are making a whole lib local... */
539  if (!lib_local && (id->tag & LIB_TAG_INDIRECT)) {
540  return false;
541  }
542 
543  const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
544 
545  if (idtype_info == NULL) {
546  BLI_assert_msg(0, "IDType Missing IDTypeInfo");
547  return false;
548  }
549 
550  BLI_assert((idtype_info->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0);
551 
552  if (idtype_info->make_local != NULL) {
553  idtype_info->make_local(bmain, id, flags);
554  }
555  else {
556  BKE_lib_id_make_local_generic(bmain, id, flags);
557  }
558 
559  return true;
560 }
561 
563  const ID *id_src;
565  int flag;
566 };
567 
568 /* Increases usercount as required, and remap self ID pointers. */
570 {
571  ID **id_pointer = cb_data->id_pointer;
572  ID *id = *id_pointer;
573  const int cb_flag = cb_data->cb_flag;
574  struct IDCopyLibManagementData *data = cb_data->user_data;
575 
576  /* Remap self-references to new copied ID. */
577  if (id == data->id_src) {
578  /* We cannot use id_self here, it is not *always* id_dst (thanks to $£!+@#&/? nodetrees). */
579  id = *id_pointer = data->id_dst;
580  }
581 
582  /* Increase used IDs refcount if needed and required. */
583  if ((data->flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0 && (cb_flag & IDWALK_CB_USER)) {
584  if ((data->flag & LIB_ID_CREATE_NO_MAIN) != 0) {
585  BLI_assert(cb_data->id_self->tag & LIB_TAG_NO_MAIN);
586  id_us_plus_no_lib(id);
587  }
588  else {
589  id_us_plus(id);
590  }
591  }
592 
593  return IDWALK_RET_NOP;
594 }
595 
596 bool BKE_id_copy_is_allowed(const ID *id)
597 {
598 #define LIB_ID_TYPES_NOCOPY ID_LI, ID_SCR, ID_WM, ID_WS /* Not supported */
599 
601 
602 #undef LIB_ID_TYPES_NOCOPY
603 }
604 
605 ID *BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag)
606 {
607  ID *newid = (r_newid != NULL) ? *r_newid : NULL;
608  /* Make sure destination pointer is all good. */
609  if ((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0) {
610  newid = NULL;
611  }
612  else {
613  if (newid != NULL) {
614  /* Allow some garbage non-initialized memory to go in, and clean it up here. */
615  const size_t size = BKE_libblock_get_alloc_info(GS(id->name), NULL);
616  memset(newid, 0, size);
617  }
618  }
619 
620  /* Early output if source is NULL. */
621  if (id == NULL) {
622  return NULL;
623  }
624 
625  const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
626 
627  if (idtype_info != NULL) {
628  if ((idtype_info->flags & IDTYPE_FLAGS_NO_COPY) != 0) {
629  return NULL;
630  }
631 
632  BKE_libblock_copy_ex(bmain, id, &newid, flag);
633 
634  if (idtype_info->copy_data != NULL) {
635  idtype_info->copy_data(bmain, newid, id, flag);
636  }
637  }
638  else {
639  BLI_assert_msg(0, "IDType Missing IDTypeInfo");
640  }
641 
642  /* Update ID refcount, remap pointers to self in new ID. */
643  struct IDCopyLibManagementData data = {
644  .id_src = id,
645  .id_dst = newid,
646  .flag = flag,
647  };
649 
650  /* Do not make new copy local in case we are copying outside of main...
651  * XXX TODO: is this behavior OK, or should we need own flag to control that? */
652  if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
654  lib_id_copy_ensure_local(bmain, id, newid, 0);
655  }
656  else {
657  newid->lib = id->lib;
658  }
659 
660  if (r_newid != NULL) {
661  *r_newid = newid;
662  }
663 
664  return newid;
665 }
666 
667 ID *BKE_id_copy(Main *bmain, const ID *id)
668 {
669  return BKE_id_copy_ex(bmain, id, NULL, LIB_ID_COPY_DEFAULT);
670 }
671 
673  ID *id,
674  const eDupli_ID_Flags duplicate_flags,
675  const int copy_flags)
676 {
677  if (id == NULL) {
678  return id;
679  }
680  if (id->newid == NULL) {
681  const bool do_linked_id = (duplicate_flags & USER_DUP_LINKED_ID) != 0;
682  if (!(do_linked_id || !ID_IS_LINKED(id))) {
683  return id;
684  }
685 
686  ID *id_new = BKE_id_copy_ex(bmain, id, NULL, copy_flags);
687  /* Copying add one user by default, need to get rid of that one. */
688  id_us_min(id_new);
689  ID_NEW_SET(id, id_new);
690 
691  /* Shape keys are always copied with their owner ID, by default. */
692  ID *key_new = (ID *)BKE_key_from_id(id_new);
693  ID *key = (ID *)BKE_key_from_id(id);
694  if (key != NULL) {
695  ID_NEW_SET(key, key_new);
696  }
697 
698  /* NOTE: embedded data (root nodetrees and master collections) should never be referenced by
699  * anything else, so we do not need to set their newid pointer and flag. */
700 
701  BKE_animdata_duplicate_id_action(bmain, id_new, duplicate_flags);
702  if (key_new != NULL) {
703  BKE_animdata_duplicate_id_action(bmain, key_new, duplicate_flags);
704  }
705  /* Note that actions of embedded data (root nodetrees and master collections) are handled
706  * by `BKE_animdata_duplicate_id_action` as well. */
707  }
708  return id->newid;
709 }
710 
715 static void id_swap(Main *bmain, ID *id_a, ID *id_b, const bool do_full_id)
716 {
717  BLI_assert(GS(id_a->name) == GS(id_b->name));
718 
719  const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id_a);
720  BLI_assert(id_type != NULL);
721  const size_t id_struct_size = id_type->struct_size;
722 
723  const ID id_a_back = *id_a;
724  const ID id_b_back = *id_b;
725 
726  char *id_swap_buff = alloca(id_struct_size);
727 
728  memcpy(id_swap_buff, id_a, id_struct_size);
729  memcpy(id_a, id_b, id_struct_size);
730  memcpy(id_b, id_swap_buff, id_struct_size);
731 
732  if (!do_full_id) {
733  /* Restore original ID's internal data. */
734  *id_a = id_a_back;
735  *id_b = id_b_back;
736 
737  /* Exception: IDProperties. */
738  id_a->properties = id_b_back.properties;
739  id_b->properties = id_a_back.properties;
740  /* Exception: recalc flags. */
741  id_a->recalc = id_b_back.recalc;
742  id_b->recalc = id_a_back.recalc;
743  }
744 
745  if (bmain != NULL) {
746  /* Swap will have broken internal references to itself, restore them. */
747  BKE_libblock_relink_ex(bmain, id_a, id_b, id_a, ID_REMAP_SKIP_NEVER_NULL_USAGE);
748  BKE_libblock_relink_ex(bmain, id_b, id_a, id_b, ID_REMAP_SKIP_NEVER_NULL_USAGE);
749  }
750 }
751 
752 void BKE_lib_id_swap(Main *bmain, ID *id_a, ID *id_b)
753 {
754  id_swap(bmain, id_a, id_b, false);
755 }
756 
757 void BKE_lib_id_swap_full(Main *bmain, ID *id_a, ID *id_b)
758 {
759  id_swap(bmain, id_a, id_b, true);
760 }
761 
763 {
764  ID *newid = NULL;
765  PointerRNA idptr;
766 
767  if (id) {
768  /* If property isn't editable,
769  * we're going to have an extra block hanging around until we save. */
770  if (RNA_property_editable(ptr, prop)) {
771  Main *bmain = CTX_data_main(C);
772  /* copy animation actions too */
774  if (newid != NULL) {
775  /* us is 1 by convention with new IDs, but RNA_property_pointer_set
776  * will also increment it, decrement it here. */
777  id_us_min(newid);
778 
779  /* assign copy */
780  RNA_id_pointer_create(newid, &idptr);
781  RNA_property_pointer_set(ptr, prop, idptr, NULL);
782  RNA_property_update(C, ptr, prop);
783 
784  /* tag grease pencil data-block and disable onion */
785  if (GS(id->name) == ID_GD) {
788  bGPdata *gpd = (bGPdata *)newid;
789  gpd->flag &= ~GP_DATA_SHOW_ONIONSKINS;
790  }
791 
792  return true;
793  }
794  }
795  }
796 
797  return false;
798 }
799 
801 {
802  ID **id_pointer = cb_data->id_pointer;
803  const int cb_flag = cb_data->cb_flag;
804  if (cb_flag & IDWALK_CB_USER) {
805  id_us_plus(*id_pointer);
806  }
807  if (cb_flag & IDWALK_CB_USER_ONE) {
808  id_us_ensure_real(*id_pointer);
809  }
810 
811  return IDWALK_RET_NOP;
812 }
813 
815 {
816  ID **id_pointer = cb_data->id_pointer;
817  const int cb_flag = cb_data->cb_flag;
818  if (cb_flag & IDWALK_CB_USER) {
819  id_us_min(*id_pointer);
820  }
821  /* We can do nothing in IDWALK_CB_USER_ONE case! */
822 
823  return IDWALK_RET_NOP;
824 }
825 
826 void BKE_libblock_management_main_add(Main *bmain, void *idv)
827 {
828  ID *id = idv;
829 
830  BLI_assert(bmain != NULL);
831  if ((id->tag & LIB_TAG_NO_MAIN) == 0) {
832  return;
833  }
834 
835  if ((id->tag & LIB_TAG_NOT_ALLOCATED) != 0) {
836  /* We cannot add non-allocated ID to Main! */
837  return;
838  }
839 
840  /* We cannot allow non-userrefcounting IDs in Main database! */
841  if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) != 0) {
843  }
844 
845  ListBase *lb = which_libbase(bmain, GS(id->name));
846  BKE_main_lock(bmain);
847  BLI_addtail(lb, id);
848  /* We need to allow adding extra datablocks into libraries too, e.g. to support generating new
849  * overrides for recursive resync. */
850  BKE_id_new_name_validate(bmain, lb, id, NULL, true);
851  /* alphabetic insertion: is in new_id */
853  bmain->is_memfile_undo_written = false;
854  BKE_main_unlock(bmain);
855 
857 }
858 
860 {
861  ID *id = idv;
862 
863  BLI_assert(bmain != NULL);
864  if ((id->tag & LIB_TAG_NO_MAIN) != 0) {
865  return;
866  }
867 
868  /* For now, allow userrefcounting IDs to get out of Main - can be handy in some cases... */
869 
870  ListBase *lb = which_libbase(bmain, GS(id->name));
871  BKE_main_lock(bmain);
872  BLI_remlink(lb, id);
873  BKE_main_namemap_remove_name(bmain, id, id->name + 2);
874  id->tag |= LIB_TAG_NO_MAIN;
875  bmain->is_memfile_undo_written = false;
876  BKE_main_unlock(bmain);
877 }
878 
880 {
881  ID *id = idv;
882 
883  if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) == 0) {
884  return;
885  }
886 
888  id->tag &= ~LIB_TAG_NO_USER_REFCOUNT;
889 }
890 
892 {
893  ID *id = idv;
894 
895  /* We do not allow IDs in Main database to not be userrefcounting. */
896  if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) != 0 || (id->tag & LIB_TAG_NO_MAIN) != 0) {
897  return;
898  }
899 
901  id->tag |= LIB_TAG_NO_USER_REFCOUNT;
902 }
903 
904 void BKE_main_id_tag_listbase(ListBase *lb, const int tag, const bool value)
905 {
906  ID *id;
907  if (value) {
908  for (id = lb->first; id; id = id->next) {
909  id->tag |= tag;
910  }
911  }
912  else {
913  const int ntag = ~tag;
914  for (id = lb->first; id; id = id->next) {
915  id->tag &= ntag;
916  }
917  }
918 }
919 
920 void BKE_main_id_tag_idcode(struct Main *mainvar,
921  const short type,
922  const int tag,
923  const bool value)
924 {
925  ListBase *lb = which_libbase(mainvar, type);
926 
927  BKE_main_id_tag_listbase(lb, tag, value);
928 }
929 
930 void BKE_main_id_tag_all(struct Main *mainvar, const int tag, const bool value)
931 {
932  ListBase *lbarray[INDEX_ID_MAX];
933  int a;
934 
935  a = set_listbasepointers(mainvar, lbarray);
936  while (a--) {
937  BKE_main_id_tag_listbase(lbarray[a], tag, value);
938  }
939 }
940 
941 void BKE_main_id_flag_listbase(ListBase *lb, const int flag, const bool value)
942 {
943  ID *id;
944  if (value) {
945  for (id = lb->first; id; id = id->next) {
946  id->tag |= flag;
947  }
948  }
949  else {
950  const int nflag = ~flag;
951  for (id = lb->first; id; id = id->next) {
952  id->tag &= nflag;
953  }
954  }
955 }
956 
957 void BKE_main_id_flag_all(Main *bmain, const int flag, const bool value)
958 {
959  ListBase *lbarray[INDEX_ID_MAX];
960  int a;
961  a = set_listbasepointers(bmain, lbarray);
962  while (a--) {
963  BKE_main_id_flag_listbase(lbarray[a], flag, value);
964  }
965 }
966 
968 {
969  int lb_len = 0;
970  LISTBASE_FOREACH (ID *, id, lb) {
971  if (!ID_IS_LINKED(id)) {
972  lb_len += 1;
973  }
974  }
975  if (lb_len <= 1) {
976  return;
977  }
978 
979  /* Fill an array because renaming sorts. */
980  ID **id_array = MEM_mallocN(sizeof(*id_array) * lb_len, __func__);
981  GSet *gset = BLI_gset_str_new_ex(__func__, lb_len);
982  int i = 0;
983  LISTBASE_FOREACH (ID *, id, lb) {
984  if (!ID_IS_LINKED(id)) {
985  id_array[i] = id;
986  i++;
987  }
988  }
989  for (i = 0; i < lb_len; i++) {
990  if (!BLI_gset_add(gset, id_array[i]->name + 2)) {
991  BKE_id_new_name_validate(bmain, lb, id_array[i], NULL, false);
992  }
993  }
994  BLI_gset_free(gset, NULL);
995  MEM_freeN(id_array);
996 }
997 
999 {
1000  Object *ob;
1001 
1002  /* flag for full recalc */
1003  for (ob = bmain->objects.first; ob; ob = ob->id.next) {
1004  if (ID_IS_LINKED(ob)) {
1006  }
1007  }
1008 
1009  DEG_id_type_tag(bmain, ID_OB);
1010 }
1011 
1012 /* *********** ALLOC AND FREE *****************
1013  *
1014  * BKE_libblock_free(ListBase *lb, ID *id )
1015  * provide a list-basis and data-block, but only ID is read
1016  *
1017  * void *BKE_libblock_alloc(ListBase *lb, type, name)
1018  * inserts in list and returns a new ID
1019  *
1020  * **************************** */
1021 
1022 size_t BKE_libblock_get_alloc_info(short type, const char **name)
1023 {
1025 
1026  if (id_type == NULL) {
1027  if (name != NULL) {
1028  *name = NULL;
1029  }
1030  return 0;
1031  }
1032 
1033  if (name != NULL) {
1034  *name = id_type->name;
1035  }
1036  return id_type->struct_size;
1037 }
1038 
1040 {
1041  const char *name;
1042  size_t size = BKE_libblock_get_alloc_info(type, &name);
1043  if (size != 0) {
1044  return MEM_callocN(size, name);
1045  }
1046  BLI_assert_msg(0, "Request to allocate unknown data type");
1047  return NULL;
1048 }
1049 
1050 void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int flag)
1051 {
1053  BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || bmain != NULL);
1055 
1057 
1058  if (id) {
1059  if ((flag & LIB_ID_CREATE_NO_MAIN) != 0) {
1060  id->tag |= LIB_TAG_NO_MAIN;
1061  }
1062  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) != 0) {
1063  id->tag |= LIB_TAG_NO_USER_REFCOUNT;
1064  }
1065  if (flag & LIB_ID_CREATE_LOCAL) {
1066  id->tag |= LIB_TAG_LOCALIZED;
1067  }
1068 
1069  id->icon_id = 0;
1070  *((short *)id->name) = type;
1071  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
1072  id->us = 1;
1073  }
1074  if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
1075  /* Note that 2.8x versioning has tested not to cause conflicts. Node trees are
1076  * skipped in this check to allow adding a geometry node tree for versioning. */
1077  BLI_assert(bmain->is_locked_for_linking == false || ELEM(type, ID_WS, ID_GR, ID_NT));
1078  ListBase *lb = which_libbase(bmain, type);
1079 
1080  BKE_main_lock(bmain);
1081  BLI_addtail(lb, id);
1082  BKE_id_new_name_validate(bmain, lb, id, name, false);
1083  bmain->is_memfile_undo_written = false;
1084  /* alphabetic insertion: is in new_id */
1085  BKE_main_unlock(bmain);
1086 
1087  /* This assert avoids having to keep name_map consistency when changing the library of an ID,
1088  * if this check is not true anymore it will have to be done here too. */
1089  BLI_assert(bmain->curlib == NULL || bmain->curlib->runtime.name_map == NULL);
1090  /* This is important in 'readfile doversion after liblink' context mainly, but is a good
1091  * consistency change in general: ID created for a Main should get that main's current
1092  * library pointer. */
1093  id->lib = bmain->curlib;
1094 
1095  /* TODO: to be removed from here! */
1096  if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0) {
1097  DEG_id_type_tag(bmain, type);
1098  }
1099  }
1100  else {
1101  BLI_strncpy(id->name + 2, name, sizeof(id->name) - 2);
1102  }
1103 
1104  /* We also need to ensure a valid `session_uuid` for some non-main data (like embedded IDs).
1105  * IDs not allocated however should not need those (this would e.g. avoid generating session
1106  * uuids for depsgraph CoW IDs, if it was using this function). */
1107  if ((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0) {
1109  }
1110  }
1111 
1112  return id;
1113 }
1114 
1116 {
1117  const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
1118 
1119  if (idtype_info != NULL) {
1120  if (idtype_info->init_data != NULL) {
1121  idtype_info->init_data(id);
1122  }
1123  return;
1124  }
1125 
1126  BLI_assert_msg(0, "IDType Missing IDTypeInfo");
1127 }
1128 
1130 {
1131  id->runtime.remap.status = 0;
1132  id->runtime.remap.skipped_refcounted = 0;
1133  id->runtime.remap.skipped_direct = 0;
1134  id->runtime.remap.skipped_indirect = 0;
1135 }
1136 
1137 /* ********** ID session-wise UUID management. ********** */
1139 
1141 {
1143  BLI_assert((id->tag & LIB_TAG_TEMP_MAIN) == 0); /* Caller must ensure this. */
1144  id->session_uuid = atomic_add_and_fetch_uint32(&global_session_uuid, 1);
1145  /* In case overflow happens, still assign a valid ID. This way opening files many times works
1146  * correctly. */
1148  id->session_uuid = atomic_add_and_fetch_uint32(&global_session_uuid, 1);
1149  }
1150  }
1151 }
1152 
1154 {
1155  id->session_uuid = MAIN_ID_SESSION_UUID_UNSET;
1157 }
1158 
1159 void *BKE_id_new(Main *bmain, const short type, const char *name)
1160 {
1161  BLI_assert(bmain != NULL);
1162 
1163  if (name == NULL) {
1165  }
1166 
1167  ID *id = BKE_libblock_alloc(bmain, type, name, 0);
1169 
1170  return id;
1171 }
1172 
1173 void *BKE_id_new_nomain(const short type, const char *name)
1174 {
1175  if (name == NULL) {
1177  }
1178 
1179  ID *id = BKE_libblock_alloc(NULL,
1180  type,
1181  name,
1185 
1186  return id;
1187 }
1188 
1189 void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int orig_flag)
1190 {
1191  ID *new_id = *r_newid;
1192  int flag = orig_flag;
1193 
1194  const bool is_private_id_data = (id->flag & LIB_EMBEDDED_DATA) != 0;
1195 
1196  BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || bmain != NULL);
1199 
1200  /* 'Private ID' data handling. */
1201  if ((bmain != NULL) && is_private_id_data) {
1203  }
1204 
1205  /* The id->flag bits to copy over. */
1206  const int copy_idflag_mask = LIB_EMBEDDED_DATA;
1207 
1208  if ((flag & LIB_ID_CREATE_NO_ALLOCATE) != 0) {
1209  /* r_newid already contains pointer to allocated memory. */
1210  /* TODO: do we want to memset(0) whole mem before filling it? */
1211  BLI_strncpy(new_id->name, id->name, sizeof(new_id->name));
1212  new_id->us = 0;
1214  /* TODO: Do we want/need to copy more from ID struct itself? */
1215  }
1216  else {
1217  new_id = BKE_libblock_alloc(bmain, GS(id->name), id->name + 2, flag);
1218  }
1219  BLI_assert(new_id != NULL);
1220 
1221  if ((flag & LIB_ID_COPY_SET_COPIED_ON_WRITE) != 0) {
1222  new_id->tag |= LIB_TAG_COPIED_ON_WRITE;
1223  }
1224  else {
1225  new_id->tag &= ~LIB_TAG_COPIED_ON_WRITE;
1226  }
1227 
1228  const size_t id_len = BKE_libblock_get_alloc_info(GS(new_id->name), NULL);
1229  const size_t id_offset = sizeof(ID);
1230  if ((int)id_len - (int)id_offset > 0) { /* signed to allow neg result */ /* XXX ????? */
1231  const char *cp = (const char *)id;
1232  char *cpn = (char *)new_id;
1233 
1234  memcpy(cpn + id_offset, cp + id_offset, id_len - id_offset);
1235  }
1236 
1237  new_id->flag = (new_id->flag & ~copy_idflag_mask) | (id->flag & copy_idflag_mask);
1238 
1239  /* We do not want any handling of usercount in code duplicating the data here, we do that all
1240  * at once in id_copy_libmanagement_cb() at the end. */
1241  const int copy_data_flag = orig_flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
1242 
1243  if (id->properties) {
1244  new_id->properties = IDP_CopyProperty_ex(id->properties, copy_data_flag);
1245  }
1246 
1247  /* This is never duplicated, only one existing ID should have a given weak ref to library/ID. */
1248  new_id->library_weak_reference = NULL;
1249 
1250  if ((orig_flag & LIB_ID_COPY_NO_LIB_OVERRIDE) == 0) {
1251  if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
1252  /* We do not want to copy existing override rules here, as they would break the proper
1253  * remapping between IDs. Proper overrides rules will be re-generated anyway. */
1254  BKE_lib_override_library_copy(new_id, id, false);
1255  }
1256  else if (ID_IS_OVERRIDE_LIBRARY_VIRTUAL(id)) {
1257  /* Just ensure virtual overrides do get properly tagged, there is not actual override data to
1258  * copy here. */
1260  }
1261  }
1262 
1263  if (id_can_have_animdata(new_id)) {
1264  IdAdtTemplate *iat = (IdAdtTemplate *)new_id;
1265 
1266  /* the duplicate should get a copy of the animdata */
1267  if ((flag & LIB_ID_COPY_NO_ANIMDATA) == 0) {
1268  /* Note that even though horrors like root nodetrees are not in bmain, the actions they use
1269  * in their anim data *are* in bmain... super-mega-hooray. */
1270  BLI_assert((copy_data_flag & LIB_ID_COPY_ACTIONS) == 0 ||
1271  (copy_data_flag & LIB_ID_CREATE_NO_MAIN) == 0);
1272  iat->adt = BKE_animdata_copy(bmain, iat->adt, copy_data_flag);
1273  }
1274  else {
1275  iat->adt = NULL;
1276  }
1277  }
1278 
1279  if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0) {
1280  DEG_id_type_tag(bmain, GS(new_id->name));
1281  }
1282 
1283  *r_newid = new_id;
1284 }
1285 
1286 void *BKE_libblock_copy(Main *bmain, const ID *id)
1287 {
1288  ID *idn;
1289 
1290  BKE_libblock_copy_ex(bmain, id, &idn, 0);
1291 
1292  return idn;
1293 }
1294 
1295 /* ***************** ID ************************ */
1296 
1297 ID *BKE_libblock_find_name(struct Main *bmain, const short type, const char *name)
1298 {
1299  ListBase *lb = which_libbase(bmain, type);
1300  BLI_assert(lb != NULL);
1301  return BLI_findstring(lb, name, offsetof(ID, name) + 2);
1302 }
1303 
1305  const short type,
1306  const uint32_t session_uuid)
1307 {
1308  ListBase *lb = which_libbase(bmain, type);
1309  BLI_assert(lb != NULL);
1310  LISTBASE_FOREACH (ID *, id, lb) {
1311  if (id->session_uuid == session_uuid) {
1312  return id;
1313  }
1314  }
1315  return NULL;
1316 }
1317 
1318 void id_sort_by_name(ListBase *lb, ID *id, ID *id_sorting_hint)
1319 {
1320 #define ID_SORT_STEP_SIZE 512
1321 
1322  ID *idtest;
1323 
1324  /* insert alphabetically */
1325  if (lb->first == lb->last) {
1326  return;
1327  }
1328 
1329  BLI_remlink(lb, id);
1330 
1331  /* Check if we can actually insert id before or after id_sorting_hint, if given. */
1332  if (!ELEM(id_sorting_hint, NULL, id) && id_sorting_hint->lib == id->lib) {
1333  BLI_assert(BLI_findindex(lb, id_sorting_hint) >= 0);
1334 
1335  ID *id_sorting_hint_next = id_sorting_hint->next;
1336  if (BLI_strcasecmp(id_sorting_hint->name, id->name) < 0 &&
1337  (id_sorting_hint_next == NULL || id_sorting_hint_next->lib != id->lib ||
1338  BLI_strcasecmp(id_sorting_hint_next->name, id->name) > 0)) {
1339  BLI_insertlinkafter(lb, id_sorting_hint, id);
1340  return;
1341  }
1342 
1343  ID *id_sorting_hint_prev = id_sorting_hint->prev;
1344  if (BLI_strcasecmp(id_sorting_hint->name, id->name) > 0 &&
1345  (id_sorting_hint_prev == NULL || id_sorting_hint_prev->lib != id->lib ||
1346  BLI_strcasecmp(id_sorting_hint_prev->name, id->name) < 0)) {
1347  BLI_insertlinkbefore(lb, id_sorting_hint, id);
1348  return;
1349  }
1350  }
1351 
1352  void *item_array[ID_SORT_STEP_SIZE];
1353  int item_array_index;
1354 
1355  /* Step one: We go backward over a whole chunk of items at once, until we find a limit item
1356  * that is lower than, or equal (should never happen!) to the one we want to insert. */
1357  /* NOTE: We start from the end, because in typical 'heavy' case (insertion of lots of IDs at
1358  * once using the same base name), newly inserted items will generally be towards the end
1359  * (higher extension numbers). */
1360  bool is_in_library = false;
1361  item_array_index = ID_SORT_STEP_SIZE - 1;
1362  for (idtest = lb->last; idtest != NULL; idtest = idtest->prev) {
1363  if (is_in_library) {
1364  if (idtest->lib != id->lib) {
1365  /* We got out of expected library 'range' in the list, so we are done here and can move on
1366  * to the next step. */
1367  break;
1368  }
1369  }
1370  else if (idtest->lib == id->lib) {
1371  /* We are entering the expected library 'range' of IDs in the list. */
1372  is_in_library = true;
1373  }
1374 
1375  if (!is_in_library) {
1376  continue;
1377  }
1378 
1379  item_array[item_array_index] = idtest;
1380  if (item_array_index == 0) {
1381  if (BLI_strcasecmp(idtest->name, id->name) <= 0) {
1382  break;
1383  }
1384  item_array_index = ID_SORT_STEP_SIZE;
1385  }
1386  item_array_index--;
1387  }
1388 
1389  /* Step two: we go forward in the selected chunk of items and check all of them, as we know
1390  * that our target is in there. */
1391 
1392  /* If we reached start of the list, current item_array_index is off-by-one.
1393  * Otherwise, we already know that it points to an item lower-or-equal-than the one we want to
1394  * insert, no need to redo the check for that one.
1395  * So we can increment that index in any case. */
1396  for (item_array_index++; item_array_index < ID_SORT_STEP_SIZE; item_array_index++) {
1397  idtest = item_array[item_array_index];
1398  if (BLI_strcasecmp(idtest->name, id->name) > 0) {
1399  BLI_insertlinkbefore(lb, idtest, id);
1400  break;
1401  }
1402  }
1403  if (item_array_index == ID_SORT_STEP_SIZE) {
1404  if (idtest == NULL) {
1405  /* If idtest is NULL here, it means that in the first loop, the last comparison was
1406  * performed exactly on the first item of the list, and that it also failed. And that the
1407  * second loop was not walked at all.
1408  *
1409  * In other words, if `id` is local, all the items in the list are greater than the inserted
1410  * one, so we can put it at the start of the list. Or, if `id` is linked, it is the first one
1411  * of its library, and we can put it at the very end of the list. */
1412  if (ID_IS_LINKED(id)) {
1413  BLI_addtail(lb, id);
1414  }
1415  else {
1416  BLI_addhead(lb, id);
1417  }
1418  }
1419  else {
1420  BLI_insertlinkafter(lb, idtest, id);
1421  }
1422  }
1423 
1424 #undef ID_SORT_STEP_SIZE
1425 }
1426 
1428  struct Main *bmain, ListBase *lb, ID *id, const char *tname, const bool do_linked_data)
1429 {
1430  bool result = false;
1431  char name[MAX_ID_NAME - 2];
1432 
1433  /* If library, don't rename (unless explicitly required), but do ensure proper sorting. */
1434  if (!do_linked_data && ID_IS_LINKED(id)) {
1435  id_sort_by_name(lb, id, NULL);
1436 
1437  return result;
1438  }
1439 
1440  /* if no name given, use name of current ID
1441  * else make a copy (tname args can be const) */
1442  if (tname == NULL) {
1443  tname = id->name + 2;
1444  }
1445 
1446  BLI_strncpy(name, tname, sizeof(name));
1447 
1448  if (name[0] == '\0') {
1449  /* Disallow empty names. */
1451  }
1452  else {
1453  /* disallow non utf8 chars,
1454  * the interface checks for this but new ID's based on file names don't */
1456  }
1457 
1458  result = BKE_main_namemap_get_name(bmain, id, name);
1459 
1460  strcpy(id->name + 2, name);
1461  id_sort_by_name(lb, id, NULL);
1462  return result;
1463 }
1464 
1466 {
1467  ID *id;
1468 
1469  FOREACH_MAIN_ID_BEGIN (bmain, id) {
1471  }
1473 }
1474 
1476 {
1477  ID **id_pointer = cb_data->id_pointer;
1478  const int cb_flag = cb_data->cb_flag;
1479  const bool do_linked_only = (bool)POINTER_AS_INT(cb_data->user_data);
1480 
1481  if (*id_pointer == NULL) {
1482  return IDWALK_RET_NOP;
1483  }
1484  if (do_linked_only && !ID_IS_LINKED(*id_pointer)) {
1485  return IDWALK_RET_NOP;
1486  }
1487 
1488  if (cb_flag & IDWALK_CB_USER) {
1489  /* Do not touch to direct/indirect linked status here... */
1490  id_us_plus_no_lib(*id_pointer);
1491  }
1492  if (cb_flag & IDWALK_CB_USER_ONE) {
1493  id_us_ensure_real(*id_pointer);
1494  }
1495 
1496  return IDWALK_RET_NOP;
1497 }
1498 
1499 void BKE_main_id_refcount_recompute(struct Main *bmain, const bool do_linked_only)
1500 {
1501  ID *id;
1502 
1503  FOREACH_MAIN_ID_BEGIN (bmain, id) {
1504  if (!ID_IS_LINKED(id) && do_linked_only) {
1505  continue;
1506  }
1507  id->us = ID_FAKE_USERS(id);
1508  /* Note that we keep EXTRAUSER tag here, since some UI users may define it too... */
1509  if (id->tag & LIB_TAG_EXTRAUSER) {
1510  id->tag &= ~(LIB_TAG_EXTRAUSER | LIB_TAG_EXTRAUSER_SET);
1511  id_us_ensure_real(id);
1512  }
1513  }
1515 
1516  /* Go over whole Main database to re-generate proper usercounts... */
1517  FOREACH_MAIN_ID_BEGIN (bmain, id) {
1519  id,
1521  POINTER_FROM_INT((int)do_linked_only),
1523  }
1525 }
1526 
1528  GSet *loop_tags,
1529  MainIDRelations *id_relations,
1530  GSet *done_ids)
1531 {
1532  if (BLI_gset_haskey(done_ids, id)) {
1533  return; /* Already checked, nothing else to do. */
1534  }
1535 
1537  BLI_gset_insert(loop_tags, id);
1538  for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != NULL;
1539  from_id_entry = from_id_entry->next) {
1540  /* Our oh-so-beloved 'from' pointers... Those should always be ignored here, since the actual
1541  * relation we want to check is in the other way around. */
1542  if (from_id_entry->usage_flag & IDWALK_CB_LOOPBACK) {
1543  continue;
1544  }
1545 
1546  ID *from_id = from_id_entry->id_pointer.from;
1547 
1548  /* Shape-keys are considered 'private' to their owner ID here, and never tagged
1549  * (since they cannot be linked), so we have to switch effective parent to their owner.
1550  */
1551  if (GS(from_id->name) == ID_KE) {
1552  from_id = ((Key *)from_id)->from;
1553  }
1554 
1555  if (!ID_IS_LINKED(from_id)) {
1556  /* Local user, early out to avoid some gset querying... */
1557  continue;
1558  }
1559  if (!BLI_gset_haskey(done_ids, from_id)) {
1560  if (BLI_gset_haskey(loop_tags, from_id)) {
1561  /* We are in a 'dependency loop' of IDs, this does not say us anything, skip it.
1562  * Note that this is the situation that can lead to archipelagoes of linked data-blocks
1563  * (since all of them have non-local users, they would all be duplicated,
1564  * leading to a loop of unused linked data-blocks that cannot be freed since they all use
1565  * each other...). */
1566  continue;
1567  }
1568  /* Else, recursively check that user ID. */
1569  library_make_local_copying_check(from_id, loop_tags, id_relations, done_ids);
1570  }
1571 
1572  if (from_id->tag & LIB_TAG_DOIT) {
1573  /* This user will be fully local in future, so far so good,
1574  * nothing to do here but check next user. */
1575  }
1576  else {
1577  /* This user won't be fully local in future, so current ID won't be either.
1578  * And we are done checking it. */
1579  id->tag &= ~LIB_TAG_DOIT;
1580  break;
1581  }
1582  }
1583  BLI_gset_add(done_ids, id);
1584  BLI_gset_remove(loop_tags, id, NULL);
1585 }
1586 
1587 /* NOTE: Old (2.77) version was simply making (tagging) data-blocks as local,
1588  * without actually making any check whether they were also indirectly used or not...
1589  *
1590  * Current version uses regular id_make_local callback, with advanced pre-processing step to
1591  * detect all cases of IDs currently indirectly used, but which will be used by local data only
1592  * once this function is finished. This allows to avoid any unneeded duplication of IDs, and
1593  * hence all time lost afterwards to remove orphaned linked data-blocks. */
1595  const Library *lib,
1596  GHash *old_to_new_ids,
1597  const bool untagged_only,
1598  const bool set_fake)
1599 {
1600 
1601  ListBase *lbarray[INDEX_ID_MAX];
1602 
1603  LinkNode *todo_ids = NULL;
1604  LinkNode *copied_ids = NULL;
1605  MemArena *linklist_mem = BLI_memarena_new(512 * sizeof(*todo_ids), __func__);
1606 
1607  GSet *done_ids = BLI_gset_ptr_new(__func__);
1608 
1609 #ifdef DEBUG_TIME
1610  TIMEIT_START(make_local);
1611 #endif
1612 
1613  BKE_main_relations_create(bmain, 0);
1614 
1615 #ifdef DEBUG_TIME
1616  printf("Pre-compute current ID relations: Done.\n");
1617  TIMEIT_VALUE_PRINT(make_local);
1618 #endif
1619 
1620  /* Step 1: Detect data-blocks to make local. */
1621  for (int a = set_listbasepointers(bmain, lbarray); a--;) {
1622  ID *id = lbarray[a]->first;
1623 
1624  /* Do not explicitly make local non-linkable IDs (shape-keys, in fact),
1625  * they are assumed to be handled by real data-blocks responsible of them. */
1626  const bool do_skip = (id && !BKE_idtype_idcode_is_linkable(GS(id->name)));
1627 
1628  for (; id; id = id->next) {
1629  ID *ntree = (ID *)ntreeFromID(id);
1630 
1631  id->tag &= ~LIB_TAG_DOIT;
1632  if (ntree != NULL) {
1633  ntree->tag &= ~LIB_TAG_DOIT;
1634  }
1635 
1636  if (!ID_IS_LINKED(id)) {
1637  id->tag &= ~(LIB_TAG_EXTERN | LIB_TAG_INDIRECT | LIB_TAG_NEW);
1638  id->flag &= ~LIB_INDIRECT_WEAK_LINK;
1639  if (ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
1641  ((untagged_only == false) || !(id->tag & LIB_TAG_PRE_EXISTING))) {
1643  }
1644  }
1645  /* The check on the fourth line (LIB_TAG_PRE_EXISTING) is done so it's possible to tag data
1646  * you don't want to be made local, used for appending data,
1647  * so any libdata already linked won't become local (very nasty
1648  * to discover all your links are lost after appending).
1649  * Also, never ever make proxified objects local, would not make any sense. */
1650  /* Some more notes:
1651  * - Shape-keys are never tagged here (since they are not linkable).
1652  * - Node-trees used in materials etc. have to be tagged manually,
1653  * since they do not exist in Main (!).
1654  * This is ok-ish on 'make local' side of things
1655  * (since those are handled by their 'owner' IDs),
1656  * but complicates slightly the pre-processing of relations between IDs at step 2... */
1657  else if (!do_skip && id->tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT | LIB_TAG_NEW) &&
1658  ELEM(lib, NULL, id->lib) &&
1659  ((untagged_only == false) || !(id->tag & LIB_TAG_PRE_EXISTING))) {
1660  BLI_linklist_prepend_arena(&todo_ids, id, linklist_mem);
1661  id->tag |= LIB_TAG_DOIT;
1662 
1663  /* Tag those nasty non-ID nodetrees,
1664  * but do not add them to todo list, making them local is handled by 'owner' ID.
1665  * This is needed for library_make_local_copying_check() to work OK at step 2. */
1666  if (ntree != NULL) {
1667  ntree->tag |= LIB_TAG_DOIT;
1668  }
1669  }
1670  else {
1671  /* Linked ID that we won't be making local (needed info for step 2, see below). */
1672  BLI_gset_add(done_ids, id);
1673  }
1674  }
1675  }
1676 
1677 #ifdef DEBUG_TIME
1678  printf("Step 1: Detect data-blocks to make local: Done.\n");
1679  TIMEIT_VALUE_PRINT(make_local);
1680 #endif
1681 
1682  /* Step 2: Check which data-blocks we can directly make local
1683  * (because they are only used by already, or future, local data),
1684  * others will need to be duplicated. */
1685  GSet *loop_tags = BLI_gset_ptr_new(__func__);
1686  for (LinkNode *it = todo_ids; it; it = it->next) {
1687  library_make_local_copying_check(it->link, loop_tags, bmain->relations, done_ids);
1688  BLI_assert(BLI_gset_len(loop_tags) == 0);
1689  }
1690  BLI_gset_free(loop_tags, NULL);
1691  BLI_gset_free(done_ids, NULL);
1692 
1693  /* Next step will most likely add new IDs, better to get rid of this mapping now. */
1694  BKE_main_relations_free(bmain);
1695 
1696 #ifdef DEBUG_TIME
1697  printf("Step 2: Check which data-blocks we can directly make local: Done.\n");
1698  TIMEIT_VALUE_PRINT(make_local);
1699 #endif
1700 
1701  /* Step 3: Make IDs local, either directly (quick and simple), or using generic process,
1702  * which involves more complex checks and might instead
1703  * create a local copy of original linked ID. */
1704  for (LinkNode *it = todo_ids, *it_next; it; it = it_next) {
1705  it_next = it->next;
1706  ID *id = it->link;
1707 
1708  if (id->tag & LIB_TAG_DOIT) {
1709  /* We know all users of this object are local or will be made fully local, even if
1710  * currently there are some indirect usages. So instead of making a copy that we'll likely
1711  * get rid of later, directly make that data block local.
1712  * Saves a tremendous amount of time with complex scenes... */
1713  BKE_lib_id_clear_library_data(bmain, id, 0);
1714  BKE_lib_id_expand_local(bmain, id, 0);
1715  id->tag &= ~LIB_TAG_DOIT;
1716 
1717  if (GS(id->name) == ID_OB) {
1719  }
1720  }
1721  else {
1722  /* In this specific case, we do want to make ID local even if it has no local usage yet... */
1724 
1725  if (id->newid) {
1726  if (GS(id->newid->name) == ID_OB) {
1728  }
1729 
1730  /* Reuse already allocated LinkNode (transferring it from todo_ids to copied_ids). */
1731  BLI_linklist_prepend_nlink(&copied_ids, id, it);
1732  }
1733  }
1734 
1735  if (set_fake) {
1736  if (!ELEM(GS(id->name), ID_OB, ID_GR)) {
1737  /* do not set fake user on objects, groups (instancing) */
1738  id_fake_user_set(id);
1739  }
1740  }
1741  }
1742 
1743 #ifdef DEBUG_TIME
1744  printf("Step 3: Make IDs local: Done.\n");
1745  TIMEIT_VALUE_PRINT(make_local);
1746 #endif
1747 
1748  /* At this point, we are done with directly made local IDs.
1749  * Now we have to handle duplicated ones, since their
1750  * remaining linked original counterpart may not be needed anymore... */
1751  todo_ids = NULL;
1752 
1753  /* Step 4: We have to remap local usages of old (linked) ID to new (local)
1754  * ID in a separated loop,
1755  * as lbarray ordering is not enough to ensure us we did catch all dependencies
1756  * (e.g. if making local a parent object before its child...). See T48907. */
1757  /* TODO: This is now the biggest step by far (in term of processing time).
1758  * We may be able to gain here by using again main->relations mapping, but...
1759  * this implies BKE_libblock_remap & co to be able to update main->relations on the fly.
1760  * Have to think about it a bit more, and see whether new code is OK first, anyway. */
1761  for (LinkNode *it = copied_ids; it; it = it->next) {
1762  ID *id = it->link;
1763 
1764  BLI_assert(id->newid != NULL);
1765  BLI_assert(ID_IS_LINKED(id));
1766 
1768  if (old_to_new_ids) {
1769  BLI_ghash_insert(old_to_new_ids, id, id->newid);
1770  }
1771 
1772  /* Special hack for groups... Thing is, since we can't instantiate them here, we need to
1773  * ensure they remain 'alive' (only instantiation is a real group 'user'... *sigh* See
1774  * T49722. */
1775  if (GS(id->name) == ID_GR && (id->tag & LIB_TAG_INDIRECT) != 0) {
1777  }
1778  }
1779 
1780 #ifdef DEBUG_TIME
1781  printf("Step 4: Remap local usages of old (linked) ID to new (local) ID: Done.\n");
1782  TIMEIT_VALUE_PRINT(make_local);
1783 #endif
1784 
1785  /* This is probably more of a hack than something we should do here, but...
1786  * Issue is, the whole copying + remapping done in complex cases above may leave pose-channels
1787  * of armatures in complete invalid state (more precisely, the bone pointers of the
1788  * pose-channels - very crappy cross-data-blocks relationship), se we tag it to be fully
1789  * recomputed, but this does not seems to be enough in some cases, and evaluation code ends up
1790  * trying to evaluate a not-yet-updated armature object's deformations.
1791  * Try "make all local" in 04_01_H.lighting.blend from Agent327 without this, e.g. */
1792  for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
1793  if (ob->data != NULL && ob->type == OB_ARMATURE && ob->pose != NULL &&
1794  ob->pose->flag & POSE_RECALC) {
1795  BKE_pose_rebuild(bmain, ob, ob->data, true);
1796  }
1797  }
1798 
1799 #ifdef DEBUG_TIME
1800  printf("Hack: Forcefully rebuild armature object poses: Done.\n");
1801  TIMEIT_VALUE_PRINT(make_local);
1802 #endif
1803 
1805  BLI_memarena_free(linklist_mem);
1806 
1807 #ifdef DEBUG_TIME
1808  printf("Cleanup and finish: Done.\n");
1809  TIMEIT_END(make_local);
1810 #endif
1811 }
1812 
1813 void BLI_libblock_ensure_unique_name(Main *bmain, const char *name)
1814 {
1815  ListBase *lb;
1816  ID *idtest;
1817 
1818  lb = which_libbase(bmain, GS(name));
1819  if (lb == NULL) {
1820  return;
1821  }
1822 
1823  /* search for id */
1824  idtest = BLI_findstring(lb, name + 2, offsetof(ID, name) + 2);
1825  if (idtest != NULL && !ID_IS_LINKED(idtest)) {
1826  /* BKE_id_new_name_validate also takes care of sorting. */
1827  BKE_id_new_name_validate(bmain, lb, idtest, NULL, false);
1828  bmain->is_memfile_undo_written = false;
1829  }
1830 }
1831 
1832 void BKE_libblock_rename(Main *bmain, ID *id, const char *name)
1833 {
1834  BLI_assert(!ID_IS_LINKED(id));
1835  BKE_main_namemap_remove_name(bmain, id, id->name + 2);
1836  ListBase *lb = which_libbase(bmain, GS(id->name));
1837  if (BKE_id_new_name_validate(bmain, lb, id, name, false)) {
1838  bmain->is_memfile_undo_written = false;
1839  }
1840 }
1841 
1842 void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separator_char)
1843 {
1844  strcpy(name, id->name + 2);
1845 
1846  if (ID_IS_LINKED(id)) {
1847  const size_t idname_len = strlen(id->name + 2);
1848  const size_t libname_len = strlen(id->lib->id.name + 2);
1849 
1850  name[idname_len] = separator_char ? separator_char : ' ';
1851  name[idname_len + 1] = '[';
1852  strcpy(name + idname_len + 2, id->lib->id.name + 2);
1853  name[idname_len + 2 + libname_len] = ']';
1854  name[idname_len + 2 + libname_len + 1] = '\0';
1855  }
1856 }
1857 
1859  const ID *id,
1860  const bool add_lib_hint,
1861  char separator_char,
1862  int *r_prefix_len)
1863 {
1864  int i = 0;
1865 
1866  if (add_lib_hint) {
1867  name[i++] = id->lib ? (ID_MISSING(id) ? 'M' : 'L') : ID_IS_OVERRIDE_LIBRARY(id) ? 'O' : ' ';
1868  }
1869  name[i++] = (id->flag & LIB_FAKEUSER) ? 'F' : ((id->us == 0) ? '0' : ' ');
1870  name[i++] = ' ';
1871 
1872  BKE_id_full_name_get(name + i, id, separator_char);
1873 
1874  if (r_prefix_len) {
1875  *r_prefix_len = i;
1876  }
1877 }
1878 
1879 char *BKE_id_to_unique_string_key(const struct ID *id)
1880 {
1881  if (!ID_IS_LINKED(id)) {
1882  return BLI_strdup(id->name);
1883  }
1884 
1885  /* Prefix with an ascii character in the range of 32..96 (visible)
1886  * this ensures we can't have a library ID pair that collide.
1887  * Where 'LIfooOBbarOBbaz' could be ('LIfoo, OBbarOBbaz') or ('LIfooOBbar', 'OBbaz'). */
1888  const char ascii_len = strlen(id->lib->id.name + 2) + 32;
1889  return BLI_sprintfN("%c%s%s", ascii_len, id->lib->id.name, id->name);
1890 }
1891 
1893 {
1895 }
1896 
1898 {
1900 }
1901 
1903 {
1904  /* We do not want to fail when id is NULL here, even though this is a bit strange behavior...
1905  */
1906  return (id == NULL || BLI_findindex(which_libbase(G_MAIN, GS(id->name)), id) != -1);
1907 }
1908 
1909 bool BKE_id_can_be_asset(const ID *id)
1910 {
1911  return !ID_IS_LINKED(id) && !ID_IS_OVERRIDE_LIBRARY(id) &&
1913 }
1914 
1915 bool BKE_id_is_editable(const Main *bmain, const ID *id)
1916 {
1917  return !(ID_IS_LINKED(id) || BKE_lib_override_library_is_system_defined(bmain, id));
1918 }
1919 
1920 /************************* Datablock order in UI **************************/
1921 
1922 static int *id_order_get(ID *id)
1923 {
1924  /* Only for workspace tabs currently. */
1925  switch (GS(id->name)) {
1926  case ID_WS:
1927  return &((WorkSpace *)id)->order;
1928  default:
1929  return NULL;
1930  }
1931 }
1932 
1933 static int id_order_compare(const void *a, const void *b)
1934 {
1935  ID *id_a = ((LinkData *)a)->data;
1936  ID *id_b = ((LinkData *)b)->data;
1937 
1938  int *order_a = id_order_get(id_a);
1939  int *order_b = id_order_get(id_b);
1940 
1941  if (order_a && order_b) {
1942  if (*order_a < *order_b) {
1943  return -1;
1944  }
1945  if (*order_a > *order_b) {
1946  return 1;
1947  }
1948  }
1949 
1950  return strcmp(id_a->name, id_b->name);
1951 }
1952 
1953 void BKE_id_ordered_list(ListBase *ordered_lb, const ListBase *lb)
1954 {
1955  BLI_listbase_clear(ordered_lb);
1956 
1957  LISTBASE_FOREACH (ID *, id, lb) {
1958  BLI_addtail(ordered_lb, BLI_genericNodeN(id));
1959  }
1960 
1961  BLI_listbase_sort(ordered_lb, id_order_compare);
1962 
1963  int num = 0;
1964  LISTBASE_FOREACH (LinkData *, link, ordered_lb) {
1965  int *order = id_order_get(link->data);
1966  if (order) {
1967  *order = num++;
1968  }
1969  }
1970 }
1971 
1972 void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after)
1973 {
1974  int *id_order = id_order_get(id);
1975  int relative_order;
1976 
1977  if (relative) {
1978  relative_order = *id_order_get(relative);
1979  }
1980  else {
1981  relative_order = (after) ? BLI_listbase_count(lb) : 0;
1982  }
1983 
1984  if (after) {
1985  /* Insert after. */
1986  LISTBASE_FOREACH (ID *, other, lb) {
1987  int *order = id_order_get(other);
1988  if (*order > relative_order) {
1989  (*order)++;
1990  }
1991  }
1992 
1993  *id_order = relative_order + 1;
1994  }
1995  else {
1996  /* Insert before. */
1997  LISTBASE_FOREACH (ID *, other, lb) {
1998  int *order = id_order_get(other);
1999  if (*order < relative_order) {
2000  (*order)--;
2001  }
2002  }
2003 
2004  *id_order = relative_order - 1;
2005  }
2006 }
2007 
2009 {
2010  if (id->asset_data) {
2012  }
2013 
2014  if (id->library_weak_reference != NULL) {
2016  }
2017 
2018  /* ID_WM's id->properties are considered runtime only, and never written in .blend file. */
2019  if (id->properties && !ELEM(GS(id->name), ID_WM)) {
2020  IDP_BlendWrite(writer, id->properties);
2021  }
2022 
2023  if (id->override_library) {
2025 
2028  BLO_write_string(writer, op->rna_path);
2029 
2031  LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
2032  if (opop->subitem_reference_name) {
2033  BLO_write_string(writer, opop->subitem_reference_name);
2034  }
2035  if (opop->subitem_local_name) {
2036  BLO_write_string(writer, opop->subitem_local_name);
2037  }
2038  }
2039  }
2040  }
2041 }
void BKE_animdata_duplicate_id_action(struct Main *bmain, struct ID *id, uint duplicate_flags)
bool id_can_have_animdata(const struct ID *id)
struct AnimData * BKE_animdata_copy(struct Main *bmain, struct AnimData *adt, int flag)
Definition: anim_data.c:275
void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm, bool do_id_user)
Definition: armature.c:2362
void BKE_asset_metadata_write(struct BlendWriter *writer, struct AssetMetaData *asset_data)
Definition: asset.cc:154
void BKE_asset_metadata_free(struct AssetMetaData **asset_data)
Definition: asset.cc:35
void BKE_bpath_foreach_path_id(BPathForeachPathData *bpath_data, struct ID *id)
Definition: bpath.c:80
@ BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE
Definition: BKE_bpath.h:55
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
#define G_MAIN
Definition: BKE_global.h:267
struct IDProperty * IDP_CopyProperty_ex(const struct IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void IDP_BlendWrite(struct BlendWriter *writer, const struct IDProperty *prop)
const char * BKE_idtype_idcode_to_name(short idcode)
Definition: idtype.c:142
const struct IDTypeInfo * BKE_idtype_get_info_from_idcode(short id_code)
Definition: idtype.c:112
@ IDTYPE_FLAGS_NO_COPY
Definition: BKE_idtype.h:30
@ IDTYPE_FLAGS_NO_LIBLINKING
Definition: BKE_idtype.h:32
bool BKE_idtype_idcode_is_linkable(short idcode)
Definition: idtype.c:175
const struct IDTypeInfo * BKE_idtype_get_info_from_id(const struct ID *id)
struct Key * BKE_key_from_id(struct ID *id)
Definition: key.c:1783
@ LIB_ID_CREATE_NO_ALLOCATE
Definition: BKE_lib_id.h:130
@ LIB_ID_COPY_NO_LIB_OVERRIDE
Definition: BKE_lib_id.h:158
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
Definition: BKE_lib_id.h:143
@ LIB_ID_CREATE_LOCAL
Definition: BKE_lib_id.h:139
@ LIB_ID_COPY_ACTIONS
Definition: BKE_lib_id.h:166
@ LIB_ID_COPY_KEEP_LIB
Definition: BKE_lib_id.h:168
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:126
@ LIB_ID_COPY_NO_ANIMDATA
Definition: BKE_lib_id.h:154
@ LIB_ID_CREATE_NO_MAIN
Definition: BKE_lib_id.h:122
@ LIB_ID_COPY_DEFAULT
Definition: BKE_lib_id.h:181
@ LIB_ID_CREATE_NO_DEG_TAG
Definition: BKE_lib_id.h:133
@ LIB_ID_MAKELOCAL_FORCE_LOCAL
Definition: BKE_lib_id.h:363
@ LIB_ID_MAKELOCAL_ASSET_DATA_CLEAR
Definition: BKE_lib_id.h:369
@ LIB_ID_MAKELOCAL_FULL_LIBRARY
Definition: BKE_lib_id.h:360
@ LIB_ID_MAKELOCAL_FORCE_COPY
Definition: BKE_lib_id.h:365
#define MAX_ID_FULL_NAME_UI
Definition: BKE_lib_id.h:551
#define MAIN_ID_SESSION_UUID_UNSET
Definition: BKE_lib_id.h:82
#define MAX_ID_FULL_NAME
Definition: BKE_lib_id.h:550
void BKE_lib_override_library_make_local(struct ID *id)
void BKE_lib_override_library_copy(struct ID *dst_id, const struct ID *src_id, bool do_full_copy)
bool BKE_lib_override_library_is_system_defined(const struct Main *bmain, const struct ID *id)
void BKE_library_foreach_ID_link(struct Main *bmain, struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
Definition: lib_query.c:350
@ IDWALK_INCLUDE_UI
@ IDWALK_NOP
@ IDWALK_READONLY
void BKE_library_ID_test_usages(struct Main *bmain, void *idv, bool *is_used_local, bool *is_used_linked)
Definition: lib_query.c:620
@ IDWALK_CB_LOOPBACK
Definition: BKE_lib_query.h:54
@ IDWALK_CB_USER_ONE
Definition: BKE_lib_query.h:79
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
@ IDWALK_CB_EMBEDDED
Definition: BKE_lib_query.h:48
@ IDWALK_RET_STOP_ITER
Definition: BKE_lib_query.h:85
@ IDWALK_RET_NOP
Definition: BKE_lib_query.h:83
@ ID_REMAP_SKIP_NEVER_NULL_USAGE
Definition: BKE_lib_remap.h:45
@ ID_REMAP_SKIP_INDIRECT_USAGE
Definition: BKE_lib_remap.h:36
void void BKE_libblock_remap(struct Main *bmain, void *old_idv, void *new_idv, short remap_flags) ATTR_NONNULL(1
void BKE_libblock_relink_ex(struct Main *bmain, void *idv, void *old_idv, void *new_idv, short remap_flags) ATTR_NONNULL(1
#define FOREACH_MAIN_ID_END
Definition: BKE_main.h:367
int set_listbasepointers(struct Main *main, struct ListBase *lb[])
Definition: main.c:654
void BKE_main_unlock(struct Main *bmain)
Definition: main.c:219
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
void BKE_main_relations_create(struct Main *bmain, short flag)
Definition: main.c:276
void BKE_main_lock(struct Main *bmain)
Definition: main.c:214
void BKE_main_relations_free(struct Main *bmain)
Definition: main.c:311
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition: BKE_main.h:361
struct ListBase * which_libbase(struct Main *bmain, short type)
Definition: main.c:567
void BKE_main_namemap_remove_name(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL()
bool BKE_main_namemap_get_name(struct Main *bmain, struct ID *id, char *name) ATTR_NONNULL()
struct bNodeTree * ntreeFromID(struct ID *id)
Definition: node.cc:3231
API for Blender-side Rigid Body stuff.
void BKE_rigidbody_ensure_local_object(struct Main *bmain, struct Object *ob)
Definition: rigidbody.c:2329
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
struct GSet GSet
Definition: BLI_ghash.h:340
bool BLI_gset_haskey(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1007
GSet * BLI_gset_ptr_new(const char *info)
GSet * BLI_gset_str_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
unsigned int BLI_gset_len(const GSet *gs) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:957
void BLI_gset_insert(GSet *gs, void *key)
Definition: BLI_ghash.c:962
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:710
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
bool BLI_gset_add(GSet *gs, void *key)
Definition: BLI_ghash.c:969
bool BLI_gset_remove(GSet *gs, const void *key, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1002
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:60
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
struct LinkData * BLI_genericNodeN(void *data)
Definition: listbase.c:842
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:301
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
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.c:340
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
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)
Definition: BLI_memarena.c:94
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
Definition: BLI_memarena.c:64
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:347
#define FILE_MAXFILE
#define FILE_MAX
void BLI_path_normalize(const char *relabase, char *path) ATTR_NONNULL(2)
Definition: path_util.c:131
void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL()
Definition: path_util.c:450
#define FILE_MAXDIR
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:897
size_t size_t char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:623
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
int BLI_str_utf8_invalid_strip(char *str, size_t length) ATTR_NONNULL(1)
Definition: string_utf8.c:181
unsigned int uint
Definition: BLI_sys_types.h:67
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
#define UNLIKELY(x)
#define ELEM(...)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
Definition: writefile.c:1601
#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:190
void DEG_id_type_tag(struct Main *bmain, short id_type)
void DEG_id_tag_update_ex(struct Main *bmain, struct ID *id, int flag)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
ID and Library types, which are fundamental for sdna.
#define ID_IS_OVERRIDE_LIBRARY_VIRTUAL(_id)
Definition: DNA_ID.h:585
#define ID_FAKE_USERS(id)
Definition: DNA_ID.h:552
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:771
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ ID_RECALC_TAG_FOR_UNDO
Definition: DNA_ID.h:868
@ ID_RECALC_ANIMATION
Definition: DNA_ID.h:794
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
Definition: DNA_ID.h:581
@ INDEX_ID_NULL
Definition: DNA_ID.h:1057
@ INDEX_ID_MAX
Definition: DNA_ID.h:1058
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
#define MAX_ID_NAME
Definition: DNA_ID.h:337
struct ID ID
#define ID_IS_ASSET(_id)
Definition: DNA_ID.h:598
#define ID_TYPE_IS_DEPRECATED(id_type)
Definition: DNA_ID.h:608
@ LIB_TAG_EXTRAUSER_SET
Definition: DNA_ID.h:700
@ LIB_TAG_NO_USER_REFCOUNT
Definition: DNA_ID.h:745
@ LIB_TAG_NOT_ALLOCATED
Definition: DNA_ID.h:748
@ LIB_TAG_INDIRECT
Definition: DNA_ID.h:677
@ LIB_TAG_EXTRAUSER
Definition: DNA_ID.h:698
@ LIB_TAG_TEMP_MAIN
Definition: DNA_ID.h:757
@ LIB_TAG_NEW
Definition: DNA_ID.h:704
@ LIB_TAG_PRE_EXISTING
Definition: DNA_ID.h:709
@ LIB_TAG_COPIED_ON_WRITE
Definition: DNA_ID.h:720
@ LIB_TAG_LOCALIZED
Definition: DNA_ID.h:740
@ LIB_TAG_DOIT
Definition: DNA_ID.h:707
@ LIB_TAG_EXTERN
Definition: DNA_ID.h:674
@ LIB_TAG_NO_MAIN
Definition: DNA_ID.h:744
@ LIB_EMBEDDED_DATA
Definition: DNA_ID.h:635
@ LIB_FAKEUSER
Definition: DNA_ID.h:630
@ LIB_EMBEDDED_DATA_LIB_OVERRIDE
Definition: DNA_ID.h:646
@ LIB_INDIRECT_WEAK_LINK
Definition: DNA_ID.h:641
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:588
#define ID_NEW_SET(_id, _idn)
Definition: DNA_ID.h:617
#define ID_MISSING(_id)
Definition: DNA_ID.h:564
@ ID_WM
Definition: DNA_ID_enums.h:72
@ ID_WS
Definition: DNA_ID_enums.h:79
@ ID_NT
Definition: DNA_ID_enums.h:68
@ ID_KE
Definition: DNA_ID_enums.h:58
@ ID_SCE
Definition: DNA_ID_enums.h:45
@ ID_GD
Definition: DNA_ID_enums.h:71
@ ID_GR
Definition: DNA_ID_enums.h:65
@ ID_OB
Definition: DNA_ID_enums.h:47
#define ID_LINK_PLACEHOLDER
Definition: DNA_ID_enums.h:88
@ POSE_RECALC
Object groups, one object can be in many groups at once.
@ GP_DATA_SHOW_ONIONSKINS
@ OB_ARMATURE
eDupli_ID_Flags
@ USER_DUP_LINKED_ID
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint order
Read Guarded memory(de)allocation.
static void init_data(ModifierData *md)
Utility defines for timing/benchmarks.
#define TIMEIT_START(var)
#define TIMEIT_VALUE_PRINT(var)
#define TIMEIT_END(var)
#define C
Definition: RandGen.cpp:25
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)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
bNodeTree * ntree
DRWShaderLibrary * lib
#define GS(x)
Definition: iris.c:225
void BKE_id_newptr_and_tag_clear(ID *id)
Definition: lib_id.c:359
static uint global_session_uuid
Definition: lib_id.c:1138
void BKE_libblock_init_empty(ID *id)
Definition: lib_id.c:1115
void id_lib_extern(ID *id)
Definition: lib_id.c:237
static bool lib_id_library_local_paths_callback(BPathForeachPathData *bpath_data, char *r_path_dst, const char *path_src)
Definition: lib_id.c:117
void BKE_main_id_repair_duplicate_names_listbase(Main *bmain, ListBase *lb)
Definition: lib_id.c:967
void BKE_lib_libblock_session_uuid_renew(ID *id)
Definition: lib_id.c:1153
ID * BKE_id_copy_for_duplicate(Main *bmain, ID *id, const eDupli_ID_Flags duplicate_flags, const int copy_flags)
Definition: lib_id.c:672
static int id_copy_libmanagement_cb(LibraryIDLinkCallbackData *cb_data)
Definition: lib_id.c:569
bool BKE_id_new_name_validate(struct Main *bmain, ListBase *lb, ID *id, const char *tname, const bool do_linked_data)
Definition: lib_id.c:1427
#define ID_SORT_STEP_SIZE
static int * id_order_get(ID *id)
Definition: lib_id.c:1922
void * BKE_libblock_copy(Main *bmain, const ID *id)
Definition: lib_id.c:1286
void BKE_id_tag_clear_atomic(ID *id, int tag)
Definition: lib_id.c:1897
void BKE_lib_id_clear_library_data(Main *bmain, ID *id, const int flags)
Definition: lib_id.c:177
void * BKE_id_new_nomain(const short type, const char *name)
Definition: lib_id.c:1173
bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
Definition: lib_id.c:762
void BKE_main_id_tag_all(struct Main *mainvar, const int tag, const bool value)
Definition: lib_id.c:930
void BLI_libblock_ensure_unique_name(Main *bmain, const char *name)
Definition: lib_id.c:1813
void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separator_char)
Definition: lib_id.c:1842
bool BKE_id_is_editable(const Main *bmain, const ID *id)
Definition: lib_id.c:1915
static int id_refcount_recompute_callback(LibraryIDLinkCallbackData *cb_data)
Definition: lib_id.c:1475
char * BKE_id_to_unique_string_key(const struct ID *id)
Definition: lib_id.c:1879
void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int orig_flag)
Definition: lib_id.c:1189
size_t BKE_libblock_get_alloc_info(short type, const char **name)
Definition: lib_id.c:1022
void BKE_main_id_flag_listbase(ListBase *lb, const int flag, const bool value)
Definition: lib_id.c:941
void id_us_plus(ID *id)
Definition: lib_id.c:305
void id_sort_by_name(ListBase *lb, ID *id, ID *id_sorting_hint)
Definition: lib_id.c:1318
static void lib_id_library_local_paths(Main *bmain, Library *lib, ID *id)
Definition: lib_id.c:154
bool BKE_id_copy_is_allowed(const ID *id)
Definition: lib_id.c:596
void BKE_libblock_management_main_remove(Main *bmain, void *idv)
Definition: lib_id.c:859
static int libblock_management_us_plus(LibraryIDLinkCallbackData *cb_data)
Definition: lib_id.c:800
void BKE_lib_id_expand_local(Main *bmain, ID *id, const int flags)
Definition: lib_id.c:427
static int id_order_compare(const void *a, const void *b)
Definition: lib_id.c:1933
void BKE_id_tag_set_atomic(ID *id, int tag)
Definition: lib_id.c:1892
#define LIB_ID_TYPES_NOCOPY
void id_fake_user_set(ID *id)
Definition: lib_id.c:343
void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after)
Definition: lib_id.c:1972
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.c:1858
void * BKE_libblock_alloc_notest(short type)
Definition: lib_id.c:1039
void BKE_lib_id_swap(Main *bmain, ID *id_a, ID *id_b)
Definition: lib_id.c:752
void BKE_main_id_flag_all(Main *bmain, const int flag, const bool value)
Definition: lib_id.c:957
static int lib_id_expand_local_cb(LibraryIDLinkCallbackData *cb_data)
Definition: lib_id.c:389
void * BKE_id_new(Main *bmain, const short type, const char *name)
Definition: lib_id.c:1159
void BKE_libblock_runtime_reset_remapping_status(ID *id)
Definition: lib_id.c:1129
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
Definition: lib_id.c:1465
void BKE_library_make_local(Main *bmain, const Library *lib, GHash *old_to_new_ids, const bool untagged_only, const bool set_fake)
Definition: lib_id.c:1594
void BKE_libblock_rename(Main *bmain, ID *id, const char *name)
Definition: lib_id.c:1832
void id_us_ensure_real(ID *id)
Definition: lib_id.c:260
void BKE_lib_id_make_local_generic(Main *bmain, ID *id, const int flags)
Definition: lib_id.c:486
void id_fake_user_clear(ID *id)
Definition: lib_id.c:351
void id_us_clear_real(ID *id)
Definition: lib_id.c:278
void BKE_libblock_management_usercounts_set(Main *bmain, void *idv)
Definition: lib_id.c:879
void BKE_main_lib_objects_recalc_all(Main *bmain)
Definition: lib_id.c:998
ID * BKE_id_copy(Main *bmain, const ID *id)
Definition: lib_id.c:667
void id_us_plus_no_lib(ID *id)
Definition: lib_id.c:289
ID * BKE_libblock_find_name(struct Main *bmain, const short type, const char *name)
Definition: lib_id.c:1297
static void library_make_local_copying_check(ID *id, GSet *loop_tags, MainIDRelations *id_relations, GSet *done_ids)
Definition: lib_id.c:1527
void BKE_main_id_tag_listbase(ListBase *lb, const int tag, const bool value)
Definition: lib_id.c:904
void BKE_main_id_tag_idcode(struct Main *mainvar, const short type, const int tag, const bool value)
Definition: lib_id.c:920
void id_lib_indirect_weak_link(ID *id)
Definition: lib_id.c:250
bool BKE_lib_id_make_local(Main *bmain, ID *id, const int flags)
Definition: lib_id.c:533
void id_us_min(ID *id)
Definition: lib_id.c:313
static CLG_LogRef LOG
Definition: lib_id.c:75
IDTypeInfo IDType_ID_LINK_PLACEHOLDER
Definition: lib_id.c:77
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag)
Definition: lib_id.c:605
void BKE_main_id_refcount_recompute(struct Main *bmain, const bool do_linked_only)
Definition: lib_id.c:1499
static int lib_id_clear_library_data_users_update_cb(LibraryIDLinkCallbackData *cb_data)
Definition: lib_id.c:166
static int libblock_management_us_min(LibraryIDLinkCallbackData *cb_data)
Definition: lib_id.c:814
void BKE_id_ordered_list(ListBase *ordered_lb, const ListBase *lb)
Definition: lib_id.c:1953
void BKE_id_blend_write(BlendWriter *writer, ID *id)
Definition: lib_id.c:2008
void BKE_libblock_management_main_add(Main *bmain, void *idv)
Definition: lib_id.c:826
static void id_swap(Main *bmain, ID *id_a, ID *id_b, const bool do_full_id)
Definition: lib_id.c:715
void BKE_lib_libblock_session_uuid_ensure(ID *id)
Definition: lib_id.c:1140
struct ID * BKE_libblock_find_session_uuid(Main *bmain, const short type, const uint32_t session_uuid)
Definition: lib_id.c:1304
void BKE_libblock_management_usercounts_clear(Main *bmain, void *idv)
Definition: lib_id.c:891
void BKE_lib_id_make_local_generic_action_define(struct Main *bmain, struct ID *id, int flags, bool *r_force_local, bool *r_force_copy)
Definition: lib_id.c:444
bool BKE_id_can_be_asset(const ID *id)
Definition: lib_id.c:1909
bool BKE_id_is_in_global_main(ID *id)
Definition: lib_id.c:1902
static void lib_id_copy_ensure_local(Main *bmain, const ID *old_id, ID *new_id, const int flags)
Definition: lib_id.c:436
void BKE_lib_id_swap_full(Main *bmain, ID *id_a, ID *id_b)
Definition: lib_id.c:757
void * BKE_libblock_alloc(Main *bmain, short type, const char *name, const int flag)
Definition: lib_id.c:1050
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1966
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value, ReportList *reports)
Definition: rna_access.c:3532
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2138
unsigned int uint32_t
Definition: stdint.h:80
const char * identifier
Definition: CLG_log.h:105
const ID * id_src
Definition: lib_id.c:563
ListBase properties
Definition: DNA_ID.h:296
struct ID * reference
Definition: DNA_ID.h:294
short id_code
Definition: BKE_idtype.h:114
const char * name
Definition: BKE_idtype.h:132
IDTypeCopyDataFunction copy_data
Definition: BKE_idtype.h:157
IDTypeInitDataFunction init_data
Definition: BKE_idtype.h:151
uint32_t flags
Definition: BKE_idtype.h:139
size_t struct_size
Definition: BKE_idtype.h:129
IDTypeMakeLocalFunction make_local
Definition: BKE_idtype.h:168
Definition: DNA_ID.h:368
int tag
Definition: DNA_ID.h:387
struct AssetMetaData * asset_data
Definition: DNA_ID.h:375
struct Library * lib
Definition: DNA_ID.h:372
int recalc
Definition: DNA_ID.h:390
int us
Definition: DNA_ID.h:388
struct ID * newid
Definition: DNA_ID.h:370
void * prev
Definition: DNA_ID.h:369
IDProperty * properties
Definition: DNA_ID.h:409
IDOverrideLibrary * override_library
Definition: DNA_ID.h:412
short flag
Definition: DNA_ID.h:383
unsigned int session_uuid
Definition: DNA_ID.h:407
void * next
Definition: DNA_ID.h:369
char name[66]
Definition: DNA_ID.h:378
struct LibraryWeakReference * library_weak_reference
Definition: DNA_ID.h:443
AnimData * adt
ID id
Definition: DNA_key_types.h:63
struct UniqueName_Map * name_map
Definition: DNA_ID.h:450
struct Library_Runtime runtime
Definition: DNA_ID.h:486
ID id
Definition: DNA_ID.h:458
char filepath_abs[1024]
Definition: DNA_ID.h:471
struct LinkNode * next
Definition: BLI_linklist.h:23
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
struct MainIDRelationsEntryItem * from_ids
Definition: BKE_main.h:66
struct GHash * relations_from_pointers
Definition: BKE_main.h:107
Definition: BKE_main.h:121
char is_locked_for_linking
Definition: BKE_main.h:156
char is_memfile_undo_written
Definition: BKE_main.h:140
struct MainIDRelations * relations
Definition: BKE_main.h:218
ListBase objects
Definition: BKE_main.h:170
struct Library * curlib
Definition: BKE_main.h:167
PointerRNA * ptr
Definition: wm_files.c:3480