Blender  V3.3
lib_override.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Blender Foundation. All rights reserved. */
3 
8 #include <cstdlib>
9 #include <cstring>
10 
11 #include "CLG_log.h"
12 
13 #include "MEM_guardedalloc.h"
14 
15 #include "DNA_ID.h"
16 #include "DNA_collection_types.h"
17 #include "DNA_key_types.h"
18 #include "DNA_object_types.h"
19 #include "DNA_scene_types.h"
20 
21 #include "DEG_depsgraph.h"
22 #include "DEG_depsgraph_build.h"
23 
24 #include "BKE_anim_data.h"
25 #include "BKE_armature.h"
26 #include "BKE_collection.h"
27 #include "BKE_fcurve.h"
28 #include "BKE_global.h"
29 #include "BKE_idtype.h"
30 #include "BKE_key.h"
31 #include "BKE_layer.h"
32 #include "BKE_lib_id.h"
33 #include "BKE_lib_override.h"
34 #include "BKE_lib_query.h"
35 #include "BKE_lib_remap.h"
36 #include "BKE_main.h"
37 #include "BKE_main_namemap.h"
38 #include "BKE_node.h"
39 #include "BKE_report.h"
40 #include "BKE_scene.h"
41 
42 #include "BLO_readfile.h"
43 
44 #include "BLI_ghash.h"
45 #include "BLI_linklist.h"
46 #include "BLI_listbase.h"
47 #include "BLI_memarena.h"
48 #include "BLI_string.h"
49 #include "BLI_task.h"
50 #include "BLI_utildefines.h"
51 
52 #include "PIL_time.h"
53 
54 #include "RNA_access.h"
55 #include "RNA_path.h"
56 #include "RNA_prototypes.h"
57 #include "RNA_types.h"
58 
59 #include "atomic_ops.h"
60 
61 #define OVERRIDE_AUTO_CHECK_DELAY 0.2 /* 200ms between auto-override checks. */
62 //#define DEBUG_OVERRIDE_TIMEIT
63 
64 #ifdef DEBUG_OVERRIDE_TIMEIT
65 # include "PIL_time_utildefines.h"
66 #endif
67 
68 static CLG_LogRef LOG = {"bke.liboverride"};
69 
74 
78 
83 {
84  if (GS(id_src->name) == ID_OB && GS(id_dst->name) == ID_OB) {
85  Object *ob_src = reinterpret_cast<Object *>(id_src);
86  Object *ob_dst = reinterpret_cast<Object *>(id_dst);
87  if (ob_src->type == OB_ARMATURE && (ob_src->mode & OB_MODE_POSE) != 0) {
88  ob_dst->restore_mode = ob_dst->mode;
89  ob_dst->mode |= OB_MODE_POSE;
90  }
91  }
92 }
93 
96  const ID *id,
97  const ID *owner_id_hint,
98  const ID **r_owner_id)
99 {
100  if (r_owner_id != nullptr) {
101  *r_owner_id = id;
102  }
104  const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
105  if (id_type->owner_get != nullptr) {
106  /* The #IDTypeInfo::owner_get callback should not modify the arguments, so casting away const
107  * is okay. */
108  const ID *owner_id = id_type->owner_get(
109  const_cast<Main *>(bmain), const_cast<ID *>(id), const_cast<ID *>(owner_id_hint));
110  if (r_owner_id != nullptr) {
111  *r_owner_id = owner_id;
112  }
113  return owner_id->override_library;
114  }
115  BLI_assert_msg(0, "IDTypeInfo of liboverride-embedded ID with no owner getter");
116  }
117  return id->override_library;
118 }
119 
121  ID *id,
122  ID *owner_id_hint,
123  ID **r_owner_id)
124 {
125  /* Reuse the implementation of the const access function, which does not change the arguments.
126  * Add const explicitly to make it clear to the compiler to avoid just calling this function. */
127  return const_cast<IDOverrideLibrary *>(
128  BKE_lib_override_library_get(const_cast<const Main *>(bmain),
129  const_cast<const ID *>(id),
130  const_cast<const ID *>(owner_id_hint),
131  const_cast<const ID **>(r_owner_id)));
132 }
133 
135 {
136  /* If reference_id is nullptr, we are creating an override template for purely local data.
137  * Else, reference *must* be linked data. */
138  BLI_assert(reference_id == nullptr || ID_IS_LINKED(reference_id));
139  BLI_assert(local_id->override_library == nullptr);
140 
141  ID *ancestor_id;
142  for (ancestor_id = reference_id;
143  ancestor_id != nullptr && ancestor_id->override_library != nullptr &&
144  ancestor_id->override_library->reference != nullptr;
145  ancestor_id = ancestor_id->override_library->reference) {
146  /* pass */
147  }
148 
149  if (ancestor_id != nullptr && ancestor_id->override_library != nullptr) {
150  /* Original ID has a template, use it! */
151  BKE_lib_override_library_copy(local_id, ancestor_id, true);
152  if (local_id->override_library->reference != reference_id) {
154  local_id->override_library->reference = reference_id;
156  }
157  return local_id->override_library;
158  }
159 
160  /* Else, generate new empty override. */
161  local_id->override_library = MEM_cnew<IDOverrideLibrary>(__func__);
162  local_id->override_library->reference = reference_id;
164  local_id->tag &= ~LIB_TAG_OVERRIDE_LIBRARY_REFOK;
165  /* By default initialized liboverrides are 'system overrides', higher-level code is responsible
166  * to unset this flag for specific IDs. */
168  /* TODO: do we want to add tag or flag to referee to mark it as such? */
169  return local_id->override_library;
170 }
171 
172 void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id, const bool do_full_copy)
173 {
175 
176  if (dst_id->override_library != nullptr) {
177  if (src_id->override_library == nullptr) {
179  return;
180  }
181 
183  }
184  else if (src_id->override_library == nullptr) {
185  /* Virtual overrides of embedded data does not require any extra work. */
186  return;
187  }
188  else {
189  BKE_lib_override_library_init(dst_id, nullptr);
190  }
191 
192  /* If source is already overriding data, we copy it but reuse its reference for dest ID.
193  * Otherwise, source is only an override template, it then becomes reference of dest ID. */
195  src_id->override_library->reference :
196  const_cast<ID *>(src_id);
198 
200  dst_id->override_library->flag = src_id->override_library->flag;
201 
202  if (do_full_copy) {
204  &src_id->override_library->properties);
205  for (IDOverrideLibraryProperty *op_dst = static_cast<IDOverrideLibraryProperty *>(
207  *op_src = static_cast<IDOverrideLibraryProperty *>(
209  op_dst;
210  op_dst = op_dst->next, op_src = op_src->next) {
211  lib_override_library_property_copy(op_dst, op_src);
212  }
213  }
214 
216 }
217 
218 void BKE_lib_override_library_clear(IDOverrideLibrary *override, const bool do_id_user)
219 {
220  BLI_assert(override != nullptr);
221 
222  if (!ELEM(nullptr, override->runtime, override->runtime->rna_path_to_override_properties)) {
223  BLI_ghash_clear(override->runtime->rna_path_to_override_properties, nullptr, nullptr);
224  }
225 
226  LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &override->properties) {
228  }
229  BLI_freelistN(&override->properties);
230 
231  if (do_id_user) {
232  id_us_min(override->reference);
233  /* override->storage should never be refcounted... */
234  }
235 }
236 
237 void BKE_lib_override_library_free(IDOverrideLibrary **override, const bool do_id_user)
238 {
239  BLI_assert(*override != nullptr);
240 
241  if ((*override)->runtime != nullptr) {
242  if ((*override)->runtime->rna_path_to_override_properties != nullptr) {
243  BLI_ghash_free((*override)->runtime->rna_path_to_override_properties, nullptr, nullptr);
244  }
245  MEM_SAFE_FREE((*override)->runtime);
246  }
247 
248  BKE_lib_override_library_clear(*override, do_id_user);
249  MEM_freeN(*override);
250  *override = nullptr;
251 }
252 
254  Library *owner_library,
255  ID *reference_id,
256  const int lib_id_copy_flags)
257 {
258  /* NOTE: We do not want to copy possible override data from reference here (whether it is an
259  * override template, or already an override of some other ref data). */
260  ID *local_id = BKE_id_copy_ex(bmain,
261  reference_id,
262  nullptr,
264  lib_id_copy_flags);
265 
266  if (local_id == nullptr) {
267  return nullptr;
268  }
269  id_us_min(local_id);
270 
271  /* TODO: Handle this properly in LIB_NO_MAIN case as well (i.e. resync case). Or offload to
272  * generic ID copy code? */
273  if ((lib_id_copy_flags & LIB_ID_CREATE_NO_MAIN) == 0) {
274  local_id->lib = owner_library;
275  }
276 
277  BKE_lib_override_library_init(local_id, reference_id);
278 
279  /* NOTE: From liboverride perspective (and RNA one), shape keys are considered as local embedded
280  * data-blocks, just like root node trees or master collections. Therefore, we never need to
281  * create overrides for them. We need a way to mark them as overrides though. */
282  Key *reference_key;
283  if ((reference_key = BKE_key_from_id(reference_id)) != nullptr) {
284  Key *local_key = BKE_key_from_id(local_id);
285  BLI_assert(local_key != nullptr);
286  local_key->id.flag |= LIB_EMBEDDED_DATA_LIB_OVERRIDE;
287  }
288 
289  return local_id;
290 }
291 
292 /* TODO: This could be simplified by storing a flag in #IDOverrideLibrary
293  * during the diffing process? */
295 {
296 
297  if (!ID_IS_OVERRIDE_LIBRARY(id)) {
298  return false;
299  }
300 
301  /* A bit weird, but those embedded IDs are handled by their owner ID anyway, so we can just
302  * assume they are never user-edited, actual proper detection will happen from their owner check.
303  */
304  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
305  return false;
306  }
307 
309  LISTBASE_FOREACH (const IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
310  if ((opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) != 0) {
311  continue;
312  }
313  if (opop->operation == IDOVERRIDE_LIBRARY_OP_NOOP) {
314  continue;
315  }
316  /* If an operation does not match the filters above, it is considered as a user-editing one,
317  * therefore this override is user-edited. */
318  return true;
319  }
320  }
321  return false;
322 }
323 
325 {
326  if (ID_IS_OVERRIDE_LIBRARY(id)) {
327  const ID *override_owner_id;
328  BKE_lib_override_library_get(bmain, id, nullptr, &override_owner_id);
329  return (override_owner_id->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED) !=
330  0;
331  }
332  return false;
333 }
334 
336  const IDOverrideLibraryProperty *override_prop,
337  const PropertyRNA *override_rna_prop,
338  const int rnaprop_index)
339 {
340  AnimData *anim_data = BKE_animdata_from_id(id);
341  if (anim_data != nullptr) {
342  struct FCurve *fcurve;
343  char *index_token_start = const_cast<char *>(
344  RNA_path_array_index_token_find(override_prop->rna_path, override_rna_prop));
345  if (index_token_start != nullptr) {
346  const char index_token_start_backup = *index_token_start;
347  *index_token_start = '\0';
349  anim_data, override_prop->rna_path, rnaprop_index, nullptr, nullptr);
350  *index_token_start = index_token_start_backup;
351  }
352  else {
354  anim_data, override_prop->rna_path, 0, nullptr, nullptr);
355  }
356  if (fcurve != nullptr) {
357  return true;
358  }
359  }
360  return false;
361 }
362 
364 {
365  ID *id_owner = cb_data->id_owner;
366  ID *id = *cb_data->id_pointer;
367  bool *is_leaf = static_cast<bool *>(cb_data->user_data);
368 
369  if (cb_data->cb_flag & IDWALK_CB_LOOPBACK) {
370  return IDWALK_RET_NOP;
371  }
372 
373  if (id != nullptr && ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
374  id->override_library->hierarchy_root == id_owner->override_library->hierarchy_root) {
375  *is_leaf = false;
376  return IDWALK_RET_STOP_ITER;
377  }
378  return IDWALK_RET_NOP;
379 }
380 
382 {
383  if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
384  bool is_leaf = true;
386  bmain, id, foreachid_is_hierarchy_leaf_fn, &is_leaf, IDWALK_READONLY);
387  return is_leaf;
388  }
389 
390  return false;
391 }
392 
394  ID *reference_id,
395  const bool do_tagged_remap)
396 {
397  BLI_assert(reference_id != nullptr);
398  BLI_assert(ID_IS_LINKED(reference_id));
399 
400  ID *local_id = lib_override_library_create_from(bmain, nullptr, reference_id, 0);
401  /* We cannot allow automatic hierarchy resync on this ID, it is highly likely to generate a giant
402  * mess in case there are a lot of hidden, non-instantiated, non-properly organized dependencies.
403  * Ref T94650. */
406  local_id->override_library->hierarchy_root = local_id;
407 
408  if (do_tagged_remap) {
409  Key *reference_key, *local_key = nullptr;
410  if ((reference_key = BKE_key_from_id(reference_id)) != nullptr) {
411  local_key = BKE_key_from_id(local_id);
412  BLI_assert(local_key != nullptr);
413  }
414 
415  ID *other_id;
416  FOREACH_MAIN_ID_BEGIN (bmain, other_id) {
417  if ((other_id->tag & LIB_TAG_DOIT) != 0 && !ID_IS_LINKED(other_id)) {
418  /* Note that using ID_REMAP_SKIP_INDIRECT_USAGE below is superfluous, as we only remap
419  * local IDs usages anyway. */
421  other_id,
422  reference_id,
423  local_id,
425  if (reference_key != nullptr) {
427  other_id,
428  &reference_key->id,
429  &local_key->id,
431  }
432  }
433  }
435  }
436 
437  return local_id;
438 }
439 
440 static void lib_override_prefill_newid_from_existing_overrides(Main *bmain, ID *id_hierarchy_root)
441 {
442  ID *id_iter;
443  FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
444  ID *id = id_iter;
445  if (GS(id_iter->name) == ID_KE) {
446  id = reinterpret_cast<Key *>(id_iter)->from;
447  BLI_assert(id != nullptr);
448  }
449  if (ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
450  id->override_library->hierarchy_root == id_hierarchy_root) {
451  id->override_library->reference->newid = id;
452  if (GS(id_iter->name) == ID_KE) {
453  Key *reference_key = BKE_key_from_id(id->override_library->reference);
454  if (reference_key != nullptr) {
455  reference_key->id.newid = id_iter;
456  }
457  }
458  }
459  }
461 }
462 
463 static void lib_override_remapper_overrides_add(IDRemapper *id_remapper,
464  ID *reference_id,
465  ID *local_id)
466 {
467  BKE_id_remapper_add(id_remapper, reference_id, local_id);
468 
469  Key *reference_key, *local_key = nullptr;
470  if ((reference_key = BKE_key_from_id(reference_id)) != nullptr) {
471  if (reference_id->newid != nullptr) {
472  local_key = BKE_key_from_id(reference_id->newid);
473  BLI_assert(local_key != nullptr);
474  }
475 
476  BKE_id_remapper_add(id_remapper, &reference_key->id, &local_key->id);
477  }
478 }
479 
480 /* TODO: Make this static local function instead? API is becoming complex, and it's not used
481  * outside of this file anyway. */
483  Library *owner_library,
484  const ID *id_root_reference,
485  ID *id_hierarchy_root,
486  const ID *id_hierarchy_root_reference,
487  const bool do_no_main,
488  const bool do_fully_editable)
489 {
490  BLI_assert(id_root_reference != nullptr && ID_IS_LINKED(id_root_reference));
491  /* If we do not have any hierarchy root given, then the root reference must be tagged for
492  * override. */
493  BLI_assert(id_hierarchy_root != nullptr || id_hierarchy_root_reference != nullptr ||
494  (id_root_reference->tag & LIB_TAG_DOIT) != 0);
495  /* At least one of the hierarchy root pointers must be nullptr, passing both is useless and can
496  * create confusion. */
497  BLI_assert(ELEM(nullptr, id_hierarchy_root, id_hierarchy_root_reference));
498 
499  if (id_hierarchy_root != nullptr) {
500  /* If the hierarchy root is given, it must be a valid existing override (used during partial
501  * resync process mainly). */
502  BLI_assert((ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root) &&
503  id_hierarchy_root->override_library->reference->lib == id_root_reference->lib));
504 
505  if (!do_no_main) {
506  /* When processing within Main, set existing overrides in given hierarchy as 'newid' of their
507  * linked reference. This allows to re-use existing overrides instead of creating new ones in
508  * partial override cases. */
509  lib_override_prefill_newid_from_existing_overrides(bmain, id_hierarchy_root);
510  }
511  }
512  if (!ELEM(id_hierarchy_root_reference, nullptr, id_root_reference)) {
513  /* If the reference hierarchy root is given, it must be from the same library as the reference
514  * root, and also tagged for override. */
515  BLI_assert((id_hierarchy_root_reference->lib == id_root_reference->lib &&
516  (id_hierarchy_root_reference->tag & LIB_TAG_DOIT) != 0));
517  }
518 
519  const Library *reference_library = id_root_reference->lib;
520 
521  ID *reference_id;
522  bool success = true;
523 
524  ListBase todo_ids = {nullptr};
525  LinkData *todo_id_iter;
526 
527  /* Get all IDs we want to override. */
528  FOREACH_MAIN_ID_BEGIN (bmain, reference_id) {
529  if ((reference_id->tag & LIB_TAG_DOIT) != 0 && reference_id->lib == reference_library &&
530  BKE_idtype_idcode_is_linkable(GS(reference_id->name))) {
531  todo_id_iter = MEM_cnew<LinkData>(__func__);
532  todo_id_iter->data = reference_id;
533  BLI_addtail(&todo_ids, todo_id_iter);
534  }
535  }
537 
538  /* Override the IDs. */
539  for (todo_id_iter = static_cast<LinkData *>(todo_ids.first); todo_id_iter != nullptr;
540  todo_id_iter = todo_id_iter->next) {
541  reference_id = static_cast<ID *>(todo_id_iter->data);
542 
543  /* If `newid` is already set, assume it has been handled by calling code.
544  * Only current use case: re-using proxy ID when converting to liboverride. */
545  if (reference_id->newid == nullptr) {
546  /* NOTE: `no main` case is used during resync procedure, to support recursive resync.
547  * This requires extra care further down the resync process,
548  * see: #BKE_lib_override_library_resync. */
549  reference_id->newid = lib_override_library_create_from(
550  bmain, owner_library, reference_id, do_no_main ? LIB_ID_CREATE_NO_MAIN : 0);
551  if (reference_id->newid == nullptr) {
552  success = false;
553  break;
554  }
555  if (do_fully_editable) {
557  }
558  }
559  /* We also tag the new IDs so that in next step we can remap their pointers too. */
560  reference_id->newid->tag |= LIB_TAG_DOIT;
561 
562  Key *reference_key;
563  if ((reference_key = BKE_key_from_id(reference_id)) != nullptr) {
564  reference_key->id.tag |= LIB_TAG_DOIT;
565 
566  Key *local_key = BKE_key_from_id(reference_id->newid);
567  BLI_assert(local_key != nullptr);
568  reference_key->id.newid = &local_key->id;
569  /* We also tag the new IDs so that in next step we can remap their pointers too. */
570  local_key->id.tag |= LIB_TAG_DOIT;
571  }
572  }
573 
574  /* Only remap new local ID's pointers, we don't want to force our new overrides onto our whole
575  * existing linked IDs usages. */
576  if (success) {
577  if (id_hierarchy_root_reference != nullptr) {
578  id_hierarchy_root = id_hierarchy_root_reference->newid;
579  }
580  else if (id_root_reference->newid != nullptr &&
581  (id_hierarchy_root == nullptr ||
582  id_hierarchy_root->override_library->reference == id_root_reference)) {
583  id_hierarchy_root = id_root_reference->newid;
584  }
585  BLI_assert(id_hierarchy_root != nullptr);
586 
587  LinkNode *relinked_ids = nullptr;
588  IDRemapper *id_remapper = BKE_id_remapper_create();
589  /* Still checking the whole Main, that way we can tag other local IDs as needing to be
590  * remapped to use newly created overriding IDs, if needed. */
591  ID *id;
592  FOREACH_MAIN_ID_BEGIN (bmain, id) {
593  ID *other_id;
594  /* In case we created new overrides as 'no main', they are not accessible directly in this
595  * loop, but we can get to them through their reference's `newid` pointer. */
596  if (do_no_main && id->lib == id_root_reference->lib && id->newid != nullptr) {
597  other_id = id->newid;
598  /* Otherwise we cannot properly distinguish between IDs that are actually from the
599  * linked library (and should not be remapped), and IDs that are overrides re-generated
600  * from the reference from the linked library, and must therefore be remapped.
601  *
602  * This is reset afterwards at the end of this loop. */
603  other_id->lib = nullptr;
604  }
605  else {
606  other_id = id;
607  }
608 
609  /* If other ID is a linked one, but not from the same library as our reference, then we
610  * consider we should also relink it, as part of recursive resync. */
611  if ((other_id->tag & LIB_TAG_DOIT) != 0 && other_id->lib != id_root_reference->lib) {
612  BLI_linklist_prepend(&relinked_ids, other_id);
613  if (ID_IS_OVERRIDE_LIBRARY_REAL(other_id) &&
614  other_id->override_library->hierarchy_root == id_hierarchy_root) {
615  reference_id = other_id->override_library->reference;
616  ID *local_id = reference_id->newid;
617  if (other_id == local_id) {
618  lib_override_remapper_overrides_add(id_remapper, reference_id, local_id);
619  }
620  }
621  }
622  if (other_id != id) {
623  other_id->lib = id_root_reference->lib;
624  }
625  }
627 
628  for (todo_id_iter = static_cast<LinkData *>(todo_ids.first); todo_id_iter != nullptr;
629  todo_id_iter = todo_id_iter->next) {
630  reference_id = static_cast<ID *>(todo_id_iter->data);
631  ID *local_id = reference_id->newid;
632 
633  if (local_id == nullptr) {
634  continue;
635  }
636 
637  local_id->override_library->hierarchy_root = id_hierarchy_root;
638 
639  lib_override_remapper_overrides_add(id_remapper, reference_id, local_id);
640  }
641 
643  relinked_ids,
645  id_remapper,
647 
648  BKE_id_remapper_free(id_remapper);
649  BLI_linklist_free(relinked_ids, nullptr);
650  }
651  else {
652  /* We need to cleanup potentially already created data. */
653  for (todo_id_iter = static_cast<LinkData *>(todo_ids.first); todo_id_iter != nullptr;
654  todo_id_iter = todo_id_iter->next) {
655  reference_id = static_cast<ID *>(todo_id_iter->data);
656  BKE_id_delete(bmain, reference_id->newid);
657  reference_id->newid = nullptr;
658  }
659  }
660 
661  BLI_freelistN(&todo_ids);
662 
663  return success;
664 }
665 
673  /* Whether we are looping on override data, or their references (linked) one. */
675  /* Whether we are creating new override, or resyncing existing one. */
676  bool is_resync;
677 
678  /* Mapping linked objects to all their instantiating collections (as a linked list).
679  * Avoids calling #BKE_collection_object_find over and over, this function is very expansive. */
682 };
683 
686 {
687  LISTBASE_FOREACH (CollectionObject *, collection_object, &collection->gobject) {
688  Object *ob = collection_object->ob;
689  if (!ID_IS_LINKED(ob)) {
690  continue;
691  }
692 
693  LinkNodePair **collections_linkedlist_p;
694  if (!BLI_ghash_ensure_p(data->linked_object_to_instantiating_collections,
695  ob,
696  reinterpret_cast<void ***>(&collections_linkedlist_p))) {
697  *collections_linkedlist_p = static_cast<LinkNodePair *>(
698  BLI_memarena_calloc(data->mem_arena, sizeof(**collections_linkedlist_p)));
699  }
700  BLI_linklist_append_arena(*collections_linkedlist_p, collection, data->mem_arena);
701  }
702 }
703 
704 /* Initialize complex data, `data` is expected to be already initialized with basic pointers and
705  * other simple data.
706  *
707  * NOTE: Currently creates a mapping from linked object to all of their instantiating collections
708  * (as returned by #BKE_collection_object_find). */
710 {
711  data->mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
712 
713  data->linked_object_to_instantiating_collections = BLI_ghash_new(
715  if (data->scene != nullptr) {
717  data, data->scene->master_collection);
718  }
719  LISTBASE_FOREACH (Collection *, collection, &data->bmain->collections) {
721  }
722 }
723 
725 {
726  BLI_ghash_free(data->linked_object_to_instantiating_collections, nullptr, nullptr);
727  BLI_memarena_free(data->mem_arena);
728  memset(data, 0, sizeof(*data));
729 }
730 
732 {
733  Main *bmain = data->bmain;
734  ID *id = data->id_root;
735  const bool is_override = data->is_override;
736 
737  if ((*reinterpret_cast<uint *>(&id->tag) & data->tag) == 0) {
738  /* This ID is not tagged, no reason to proceed further to its parents. */
739  return;
740  }
741 
742  MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
744  BLI_assert(entry != nullptr);
745 
747  /* This ID has already been processed. */
748  return;
749  }
750  /* This way we won't process again that ID, should we encounter it again through another
751  * relationship hierarchy. */
753 
754  for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != nullptr;
755  from_id_entry = from_id_entry->next) {
756  if ((from_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
757  /* Never consider non-overridable relationships ('from', 'parents', 'owner' etc. pointers)
758  * as actual dependencies. */
759  continue;
760  }
761  /* We only consider IDs from the same library. */
762  ID *from_id = from_id_entry->id_pointer.from;
763  if (from_id == nullptr || from_id->lib != id->lib ||
764  (is_override && !ID_IS_OVERRIDE_LIBRARY(from_id))) {
765  /* IDs from different libraries, or non-override IDs in case we are processing overrides,
766  * are both barriers of dependency. */
767  continue;
768  }
769  from_id->tag |= data->tag;
770  LibOverrideGroupTagData sub_data = *data;
771  sub_data.id_root = from_id;
773  }
774 }
775 
776 /* Tag all IDs in dependency relationships within an override hierarchy/group.
777  *
778  * Requires existing `Main.relations`.
779  *
780  * NOTE: This is typically called to complete `lib_override_linked_group_tag()`.
781  */
783 {
784  Main *bmain = data->bmain;
785  ID *id = data->id_root;
786  const bool is_override = data->is_override;
787  const bool is_resync = data->is_resync;
788 
789  MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
791  BLI_assert(entry != nullptr);
792 
794  /* This ID has already been processed. */
795  return (*reinterpret_cast<uint *>(&id->tag) & data->tag) != 0;
796  }
797  /* This way we won't process again that ID, should we encounter it again through another
798  * relationship hierarchy. */
800 
801  for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != nullptr;
802  to_id_entry = to_id_entry->next) {
803  if ((to_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
804  /* Never consider non-overridable relationships ('from', 'parents', 'owner' etc. pointers) as
805  * actual dependencies. */
806  continue;
807  }
808  /* We only consider IDs from the same library. */
809  ID *to_id = *to_id_entry->id_pointer.to;
810  if (to_id == nullptr || to_id->lib != id->lib ||
811  (is_override && !ID_IS_OVERRIDE_LIBRARY(to_id))) {
812  /* IDs from different libraries, or non-override IDs in case we are processing overrides, are
813  * both barriers of dependency. */
814  continue;
815  }
816  LibOverrideGroupTagData sub_data = *data;
817  sub_data.id_root = to_id;
819  id->tag |= data->tag;
820  }
821  }
822 
823  /* If the current ID is/has been tagged for override above, then check its reversed dependencies
824  * (i.e. IDs that depend on the current one).
825  *
826  * This will cover e.g. the case where user override an armature, and would expect the mesh
827  * object deformed by that armature to also be overridden. */
828  if ((*reinterpret_cast<uint *>(&id->tag) & data->tag) != 0 && !is_resync) {
830  }
831 
832  return (*reinterpret_cast<uint *>(&id->tag) & data->tag) != 0;
833 }
834 
836 {
837  Main *bmain = data->bmain;
838  ID *id_owner = data->id_root;
839  BLI_assert(ID_IS_LINKED(id_owner));
840  BLI_assert(!data->is_override);
841  const uint tag = data->tag;
842  const uint missing_tag = data->missing_tag;
843 
844  MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
846  BLI_assert(entry != nullptr);
847 
849  /* This ID has already been processed. */
850  return;
851  }
852  /* This way we won't process again that ID, should we encounter it again through another
853  * relationship hierarchy. */
855 
856  for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != nullptr;
857  to_id_entry = to_id_entry->next) {
858  if ((to_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
859  /* Never consider non-overridable relationships as actual dependencies. */
860  continue;
861  }
862 
863  ID *to_id = *to_id_entry->id_pointer.to;
864  if (ELEM(to_id, nullptr, id_owner)) {
865  continue;
866  }
867  /* We only consider IDs from the same library. */
868  if (to_id->lib != id_owner->lib) {
869  continue;
870  }
871  BLI_assert(ID_IS_LINKED(to_id));
872 
873  /* We tag all collections and objects for override. And we also tag all other data-blocks which
874  * would use one of those.
875  * NOTE: missing IDs (aka placeholders) are never overridden. */
876  if (ELEM(GS(to_id->name), ID_OB, ID_GR)) {
877  if (to_id->tag & LIB_TAG_MISSING) {
878  to_id->tag |= missing_tag;
879  }
880  else {
881  to_id->tag |= tag;
882  }
883  }
884 
885  /* Recursively process the dependencies. */
886  LibOverrideGroupTagData sub_data = *data;
887  sub_data.id_root = to_id;
889  }
890 }
891 
894 {
895  /* NOTE: Collection's object cache (using bases, as returned by #BKE_collection_object_cache_get)
896  * is not usable here, as it may have become invalid from some previous operation and it should
897  * not be updated here. So instead only use collections' reliable 'raw' data to check if some
898  * object in the hierarchy of the given collection is still tagged for override. */
899  for (CollectionObject *collection_object =
900  static_cast<CollectionObject *>(collection->gobject.first);
901  collection_object != nullptr;
902  collection_object = collection_object->next) {
903  Object *object = collection_object->ob;
904  if (object == nullptr) {
905  continue;
906  }
907  if ((object->id.tag & data->tag) != 0) {
908  return true;
909  }
910  }
911 
912  for (CollectionChild *collection_child =
913  static_cast<CollectionChild *>(collection->children.first);
914  collection_child != nullptr;
915  collection_child = collection_child->next) {
917  data, collection_child->collection)) {
918  return true;
919  }
920  }
921 
922  return false;
923 }
924 
926 {
927  Main *bmain = data->bmain;
928  ID *id_root = data->id_root;
929 
930  /* Remove (untag) bone shape objects, they shall never need to be to directly/explicitly
931  * overridden. */
932  LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
933  if (ob->type == OB_ARMATURE && ob->pose != nullptr && (ob->id.tag & data->tag)) {
934  for (bPoseChannel *pchan = static_cast<bPoseChannel *>(ob->pose->chanbase.first);
935  pchan != nullptr;
936  pchan = pchan->next) {
937  if (pchan->custom != nullptr && &pchan->custom->id != id_root) {
938  pchan->custom->id.tag &= ~data->tag;
939  }
940  }
941  }
942  }
943 
944  /* Remove (untag) collections if they do not own any tagged object (either themselves, or in
945  * their children collections). */
946  LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
947  if ((collection->id.tag & data->tag) == 0 || &collection->id == id_root) {
948  continue;
949  }
950 
952  collection->id.tag &= ~data->tag;
953  }
954  }
955 }
956 
957 /* This will tag at least all 'boundary' linked IDs for a potential override group.
958  *
959  * Requires existing `Main.relations`.
960  *
961  * Note that you will then need to call #lib_override_hierarchy_dependencies_recursive_tag to
962  * complete tagging of all dependencies within the override group.
963  *
964  * We currently only consider Collections and Objects (that are not used as bone shapes) as valid
965  * boundary IDs to define an override group.
966  */
968 {
969  Main *bmain = data->bmain;
970  ID *id_root = data->id_root;
971  const bool is_resync = data->is_resync;
972  BLI_assert(!data->is_override);
973 
974  if (id_root->tag & LIB_TAG_MISSING) {
975  id_root->tag |= data->missing_tag;
976  }
977  else {
978  id_root->tag |= data->tag;
979  }
980 
981  /* Tag all collections and objects recursively. */
983 
984  /* Do not override objects used as bone shapes, nor their collections if possible. */
986 
987  /* For each object tagged for override, ensure we get at least one local or liboverride
988  * collection to host it. Avoids getting a bunch of random object in the scene's master
989  * collection when all objects' dependencies are not properly 'packed' into a single root
990  * collection.
991  *
992  * NOTE: In resync case, we do not handle this at all, since:
993  * - In normal, valid cases nothing would be needed anyway (resync process takes care
994  * of tagging needed 'owner' collection then).
995  * - Partial resync makes it extremely difficult to properly handle such extra
996  * collection 'tagging for override' (since one would need to know if the new object
997  * is actually going to replace an already existing override [most common case], or
998  * if it is actually a real new 'orphan' one).
999  * - While not ideal, having objects dangling around is less critical than both points
1000  * above.
1001  * So if users add new objects to their library override hierarchy in an invalid way, so
1002  * be it. Trying to find a collection to override and host this new object would most
1003  * likely make existing override very unclean anyway. */
1004  if (is_resync) {
1005  return;
1006  }
1007  LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1008  if (ID_IS_LINKED(ob) && (ob->id.tag & data->tag) != 0) {
1009  Collection *instantiating_collection = nullptr;
1010  Collection *instantiating_collection_override_candidate = nullptr;
1011  /* Loop over all collections instantiating the object, if we already have a 'locale' one we
1012  * have nothing to do, otherwise try to find a 'linked' one that we can override too. */
1013  LinkNodePair *instantiating_collection_linklist = static_cast<LinkNodePair *>(
1014  BLI_ghash_lookup(data->linked_object_to_instantiating_collections, ob));
1015  if (instantiating_collection_linklist != nullptr) {
1016  for (LinkNode *instantiating_collection_linknode = instantiating_collection_linklist->list;
1017  instantiating_collection_linknode != nullptr;
1018  instantiating_collection_linknode = instantiating_collection_linknode->next) {
1019  instantiating_collection = static_cast<Collection *>(
1020  instantiating_collection_linknode->link);
1021  if (!ID_IS_LINKED(instantiating_collection)) {
1022  /* There is a local collection instantiating the linked object to override, nothing
1023  * else to be done here. */
1024  break;
1025  }
1026  if (instantiating_collection->id.tag & data->tag) {
1027  /* There is a linked collection instantiating the linked object to override,
1028  * already tagged to be overridden, nothing else to be done here. */
1029  break;
1030  }
1031  instantiating_collection_override_candidate = instantiating_collection;
1032  instantiating_collection = nullptr;
1033  }
1034  }
1035 
1036  if (instantiating_collection == nullptr &&
1037  instantiating_collection_override_candidate != nullptr) {
1038  if (instantiating_collection_override_candidate->id.tag & LIB_TAG_MISSING) {
1039  instantiating_collection_override_candidate->id.tag |= data->missing_tag;
1040  }
1041  else {
1042  instantiating_collection_override_candidate->id.tag |= data->tag;
1043  }
1044  }
1045  }
1046  }
1047 }
1048 
1050 {
1051  Main *bmain = data->bmain;
1052  ID *id_owner = data->id_root;
1054  BLI_assert(data->is_override);
1055 
1056  ID *id_hierarchy_root = data->hierarchy_root_id;
1057 
1058  if (ID_IS_OVERRIDE_LIBRARY_REAL(id_owner) &&
1060  return;
1061  }
1062 
1063  const uint tag = data->tag;
1064  const uint missing_tag = data->missing_tag;
1065 
1066  MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
1068  BLI_assert(entry != nullptr);
1069 
1071  /* This ID has already been processed. */
1072  return;
1073  }
1074  /* This way we won't process again that ID, should we encounter it again through another
1075  * relationship hierarchy. */
1077 
1078  for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != nullptr;
1079  to_id_entry = to_id_entry->next) {
1080  if ((to_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
1081  /* Never consider non-overridable relationships as actual dependencies. */
1082  continue;
1083  }
1084 
1085  ID *to_id = *to_id_entry->id_pointer.to;
1086  if (ELEM(to_id, nullptr, id_owner)) {
1087  continue;
1088  }
1089  /* Different libraries or different hierarchy roots are break points in override hierarchies.
1090  */
1091  if (!ID_IS_OVERRIDE_LIBRARY(to_id) || (to_id->lib != id_owner->lib)) {
1092  continue;
1093  }
1094  if (ID_IS_OVERRIDE_LIBRARY_REAL(to_id) &&
1095  to_id->override_library->hierarchy_root != id_hierarchy_root) {
1096  continue;
1097  }
1098 
1099  const Library *reference_lib =
1100  BKE_lib_override_library_get(bmain, id_owner, nullptr, nullptr)->reference->lib;
1101  const ID *to_id_reference =
1102  BKE_lib_override_library_get(bmain, to_id, nullptr, nullptr)->reference;
1103  if (to_id_reference->lib != reference_lib) {
1104  /* We do not override data-blocks from other libraries, nor do we process them. */
1105  continue;
1106  }
1107 
1108  if (to_id_reference->tag & LIB_TAG_MISSING) {
1109  to_id->tag |= missing_tag;
1110  }
1111  else {
1112  to_id->tag |= tag;
1113  }
1114 
1115  /* Recursively process the dependencies. */
1116  LibOverrideGroupTagData sub_data = *data;
1117  sub_data.id_root = to_id;
1119  }
1120 }
1121 
1122 /* This will tag all override IDs of an override group defined by the given `id_root`. */
1124 {
1125  ID *id_root = data->id_root;
1127  BLI_assert(data->is_override);
1128 
1129  ID *id_hierarchy_root = data->hierarchy_root_id;
1130  BLI_assert(id_hierarchy_root != nullptr);
1131  BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root));
1132  UNUSED_VARS_NDEBUG(id_hierarchy_root);
1133 
1134  if (id_root->override_library->reference->tag & LIB_TAG_MISSING) {
1135  id_root->tag |= data->missing_tag;
1136  }
1137  else {
1138  id_root->tag |= data->tag;
1139  }
1140 
1141  /* Tag all local overrides in id_root's group. */
1143 }
1144 
1146  Scene *scene,
1147  Library *owner_library,
1148  ID *id_root_reference,
1149  ID *id_hierarchy_root_reference,
1150  const bool do_fully_editable)
1151 {
1152  BKE_main_relations_create(bmain, 0);
1154  data.bmain = bmain;
1155  data.scene = scene;
1156  data.id_root = id_root_reference;
1157  data.tag = LIB_TAG_DOIT;
1158  data.missing_tag = LIB_TAG_MISSING;
1159  data.is_override = false;
1160  data.is_resync = false;
1163 
1166 
1167  /* In case the operation is on an already partially overridden hierarchy, all existing overrides
1168  * in that hierarchy need to be tagged for remapping from linked reference ID usages to newly
1169  * created overrides ones. */
1170  if (id_hierarchy_root_reference->lib != id_root_reference->lib) {
1171  BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root_reference));
1172  BLI_assert(id_hierarchy_root_reference->override_library->reference->lib ==
1173  id_root_reference->lib);
1174 
1176  data.hierarchy_root_id = id_hierarchy_root_reference;
1177  data.id_root = id_hierarchy_root_reference;
1178  data.is_override = true;
1180  }
1181 
1182  BKE_main_relations_free(bmain);
1184 
1185  bool success = false;
1186  if (id_hierarchy_root_reference->lib != id_root_reference->lib) {
1188  owner_library,
1189  id_root_reference,
1190  id_hierarchy_root_reference,
1191  nullptr,
1192  false,
1193  do_fully_editable);
1194  }
1195  else {
1197  owner_library,
1198  id_root_reference,
1199  nullptr,
1200  id_hierarchy_root_reference,
1201  false,
1202  do_fully_editable);
1203  }
1204 
1205  return success;
1206 }
1207 
1209  Scene *scene,
1210  ViewLayer *view_layer,
1211  const Library *owner_library,
1212  ID *id_root,
1213  ID *id_instance_hint,
1214  Collection *residual_storage,
1215  const Object *old_active_object,
1216  const bool is_resync)
1217 {
1218  /* If there is an old active object, there should also always be a given view layer. */
1219  BLI_assert(old_active_object == nullptr || view_layer != nullptr);
1220 
1221  /* NOTE: We only care about local IDs here, if a linked object is not instantiated in any way we
1222  * do not do anything about it. */
1223 
1224  /* We need to use the `_remap` version here as we prevented any LayerCollection resync during the
1225  * whole liboverride resyncing, which involves a lot of ID remapping.
1226  *
1227  * Otherwise, cached Base GHash e.g. can contain invalid stale data. */
1229 
1230  /* We create a set of all objects referenced into the scene by its hierarchy of collections.
1231  * NOTE: This is different that the list of bases, since objects in excluded collections etc.
1232  * won't have a base, but are still considered as instanced from our point of view. */
1233  GSet *all_objects_in_scene = BKE_scene_objects_as_gset(scene, nullptr);
1234 
1235  /* Instantiating the root collection or object should never be needed in resync case, since the
1236  * old override would be remapped to the new one. */
1237  if (!is_resync && id_root != nullptr && id_root->newid != nullptr &&
1238  (!ID_IS_LINKED(id_root->newid) || id_root->newid->lib == owner_library)) {
1239  switch (GS(id_root->name)) {
1240  case ID_GR: {
1241  Object *ob_reference = id_instance_hint != nullptr && GS(id_instance_hint->name) == ID_OB ?
1242  reinterpret_cast<Object *>(id_instance_hint) :
1243  nullptr;
1244  Collection *collection_new = (reinterpret_cast<Collection *>(id_root->newid));
1245  if (is_resync && BKE_collection_is_in_scene(collection_new)) {
1246  break;
1247  }
1248  if (ob_reference != nullptr) {
1249  BKE_collection_add_from_object(bmain, scene, ob_reference, collection_new);
1250  }
1251  else if (id_instance_hint != nullptr) {
1252  BLI_assert(GS(id_instance_hint->name) == ID_GR);
1254  bmain, scene, (reinterpret_cast<Collection *>(id_instance_hint)), collection_new);
1255  }
1256  else {
1258  bmain, scene, (reinterpret_cast<Collection *>(id_root)), collection_new);
1259  }
1260 
1261  BLI_assert(BKE_collection_is_in_scene(collection_new));
1262 
1263  all_objects_in_scene = BKE_scene_objects_as_gset(scene, all_objects_in_scene);
1264  break;
1265  }
1266  case ID_OB: {
1267  Object *ob_new = reinterpret_cast<Object *>(id_root->newid);
1268  if (BLI_gset_lookup(all_objects_in_scene, ob_new) == nullptr) {
1270  bmain, scene, reinterpret_cast<Object *>(id_root), ob_new);
1271  all_objects_in_scene = BKE_scene_objects_as_gset(scene, all_objects_in_scene);
1272  }
1273  break;
1274  }
1275  default:
1276  break;
1277  }
1278  }
1279 
1280  /* We need to ensure all new overrides of objects are properly instantiated. */
1281  Collection *default_instantiating_collection = residual_storage;
1282  LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
1283  Object *ob_new = reinterpret_cast<Object *>(ob->id.newid);
1284  if (ob_new == nullptr || (ID_IS_LINKED(ob_new) && ob_new->id.lib != owner_library)) {
1285  continue;
1286  }
1287 
1288  BLI_assert(ob_new->id.override_library != nullptr &&
1289  ob_new->id.override_library->reference == &ob->id);
1290 
1291  if (old_active_object == ob) {
1292  Base *basact = BKE_view_layer_base_find(view_layer, ob_new);
1293  if (basact != nullptr) {
1294  view_layer->basact = basact;
1295  }
1297  }
1298 
1299  if (BLI_gset_lookup(all_objects_in_scene, ob_new) == nullptr) {
1300  if (id_root != nullptr && default_instantiating_collection == nullptr) {
1301  ID *id_ref = id_root->newid != nullptr ? id_root->newid : id_root;
1302  switch (GS(id_ref->name)) {
1303  case ID_GR: {
1304  /* Adding the object to a specific collection outside of the root overridden one is a
1305  * fairly bad idea (it breaks the override hierarchy concept). But there is no other
1306  * way to do this currently (we cannot add new collections to overridden root one,
1307  * this is not currently supported).
1308  * Since that will be fairly annoying and noisy, only do that in case the override
1309  * object is not part of any existing collection (i.e. its user count is 0). In
1310  * practice this should never happen I think. */
1311  if (ID_REAL_USERS(ob_new) != 0) {
1312  continue;
1313  }
1314  default_instantiating_collection = static_cast<Collection *>(
1315  BKE_id_new(bmain, ID_GR, "OVERRIDE_HIDDEN"));
1316  id_us_min(&default_instantiating_collection->id);
1317  /* Hide the collection from viewport and render. */
1318  default_instantiating_collection->flag |= COLLECTION_HIDE_VIEWPORT |
1320  break;
1321  }
1322  case ID_OB: {
1323  /* Add the other objects to one of the collections instantiating the
1324  * root object, or scene's master collection if none found. */
1325  Object *ob_ref = reinterpret_cast<Object *>(id_ref);
1326  LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
1327  if (BKE_collection_has_object(collection, ob_ref) &&
1328  (view_layer != nullptr ?
1329  BKE_view_layer_has_collection(view_layer, collection) :
1331  !ID_IS_LINKED(collection) && !ID_IS_OVERRIDE_LIBRARY(collection)) {
1332  default_instantiating_collection = collection;
1333  }
1334  }
1335  break;
1336  }
1337  default:
1338  break;
1339  }
1340  }
1341  if (default_instantiating_collection == nullptr) {
1342  default_instantiating_collection = scene->master_collection;
1343  }
1344 
1345  BKE_collection_object_add(bmain, default_instantiating_collection, ob_new);
1347  }
1348  }
1349 
1350  if (id_root != nullptr &&
1351  !ELEM(default_instantiating_collection, nullptr, scene->master_collection)) {
1352  ID *id_ref = id_root->newid != nullptr ? id_root->newid : id_root;
1353  switch (GS(id_ref->name)) {
1354  case ID_GR:
1356  scene,
1357  reinterpret_cast<Collection *>(id_ref),
1358  default_instantiating_collection);
1359  break;
1360  default:
1361  /* Add to master collection. */
1363  bmain, scene, nullptr, default_instantiating_collection);
1364  break;
1365  }
1366  }
1367 
1368  BLI_gset_free(all_objects_in_scene, nullptr);
1369 }
1370 
1372  Scene *scene,
1373  ViewLayer *view_layer,
1374  Library *owner_library,
1375  ID *id_root_reference,
1376  ID *id_hierarchy_root_reference,
1377  ID *id_instance_hint,
1378  ID **r_id_root_override,
1379  const bool do_fully_editable)
1380 {
1381  if (r_id_root_override != nullptr) {
1382  *r_id_root_override = nullptr;
1383  }
1384 
1385  if (id_hierarchy_root_reference == nullptr) {
1386  id_hierarchy_root_reference = id_root_reference;
1387  }
1388 
1389  const Object *old_active_object = (view_layer != nullptr) ? OBACT(view_layer) : nullptr;
1390 
1391  const bool success = lib_override_library_create_do(bmain,
1392  scene,
1393  owner_library,
1394  id_root_reference,
1395  id_hierarchy_root_reference,
1396  do_fully_editable);
1397 
1398  if (!success) {
1399  return success;
1400  }
1401 
1402  if (r_id_root_override != nullptr) {
1403  *r_id_root_override = id_root_reference->newid;
1404  }
1405 
1407  scene,
1408  view_layer,
1409  owner_library,
1410  id_root_reference,
1411  id_instance_hint,
1412  nullptr,
1413  old_active_object,
1414  false);
1415 
1416  /* Cleanup. */
1418  BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
1419 
1420  /* We need to rebuild some of the deleted override rules (for UI feedback purpose). */
1422 
1423  return success;
1424 }
1425 
1427 {
1428  if (ID_IS_LINKED(id)) {
1429  return false;
1430  }
1431  if (ID_IS_OVERRIDE_LIBRARY(id)) {
1432  return false;
1433  }
1434 
1435  BKE_lib_override_library_init(id, nullptr);
1436  return true;
1437 }
1438 
1439 static ID *lib_override_root_find(Main *bmain, ID *id, const int curr_level, int *r_best_level)
1440 {
1441  if (curr_level > 1000) {
1442  CLOG_ERROR(&LOG,
1443  "Levels of dependency relationships between library overrides IDs is way too high, "
1444  "skipping further processing loops (involves at least '%s')",
1445  id->name);
1446  return nullptr;
1447  }
1448 
1449  if (!ID_IS_OVERRIDE_LIBRARY(id)) {
1451  return nullptr;
1452  }
1453 
1454  MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
1456  BLI_assert(entry != nullptr);
1457 
1459  if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
1460  /* This ID has already been processed. */
1461  *r_best_level = curr_level;
1462  return id->override_library->hierarchy_root;
1463  }
1464 
1466  ID *id_owner;
1467  int best_level_placeholder = 0;
1468  BKE_lib_override_library_get(bmain, id, nullptr, &id_owner);
1469  return lib_override_root_find(bmain, id_owner, curr_level + 1, &best_level_placeholder);
1470  }
1471  /* This way we won't process again that ID, should we encounter it again through another
1472  * relationship hierarchy. */
1474 
1475  int best_level_candidate = curr_level;
1476  ID *best_root_id_candidate = id;
1477 
1478  for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != nullptr;
1479  from_id_entry = from_id_entry->next) {
1480  if ((from_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
1481  /* Never consider non-overridable relationships as actual dependencies. */
1482  continue;
1483  }
1484 
1485  ID *from_id = from_id_entry->id_pointer.from;
1486  if (ELEM(from_id, nullptr, id)) {
1487  continue;
1488  }
1489  if (!ID_IS_OVERRIDE_LIBRARY(from_id) || (from_id->lib != id->lib)) {
1490  continue;
1491  }
1492 
1493  int level_candidate = curr_level + 1;
1494  /* Recursively process the parent. */
1495  ID *root_id_candidate = lib_override_root_find(
1496  bmain, from_id, curr_level + 1, &level_candidate);
1497  if (level_candidate > best_level_candidate && root_id_candidate != nullptr) {
1498  best_root_id_candidate = root_id_candidate;
1499  best_level_candidate = level_candidate;
1500  }
1501  }
1502 
1503  if (!ID_IS_OVERRIDE_LIBRARY_REAL(best_root_id_candidate)) {
1505  ID *id_owner;
1506  int best_level_placeholder = 0;
1507  BKE_lib_override_library_get(bmain, best_root_id_candidate, nullptr, &id_owner);
1508  best_root_id_candidate = lib_override_root_find(
1509  bmain, id_owner, curr_level + 1, &best_level_placeholder);
1510  }
1511 
1512  BLI_assert(best_root_id_candidate != nullptr);
1513  BLI_assert((best_root_id_candidate->flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE) == 0);
1514 
1515  *r_best_level = best_level_candidate;
1516  return best_root_id_candidate;
1517 }
1518 
1519 static void lib_override_root_hierarchy_set(Main *bmain, ID *id_root, ID *id, ID *id_from)
1520 {
1521  if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
1522  if (id->override_library->hierarchy_root == id_root) {
1523  /* Already set, nothing else to do here, sub-hierarchy is also assumed to be properly set
1524  * then. */
1525  return;
1526  }
1527 
1528  /* Hierarchy root already set, and not matching currently proposed one, try to find which is
1529  * best. */
1530  if (id->override_library->hierarchy_root != nullptr) {
1531  /* Check if given `id_from` matches with the hierarchy of the linked reference ID, in which
1532  * case we assume that the given hierarchy root is the 'real' one.
1533  *
1534  * NOTE: This can fail if user mixed dependencies between several overrides of a same
1535  * reference linked hierarchy. Not much to be done in that case, it's virtually impossible to
1536  * fix this automatically in a reliable way. */
1537  if (id_from == nullptr || !ID_IS_OVERRIDE_LIBRARY_REAL(id_from)) {
1538  /* Too complicated to deal with for now. */
1539  CLOG_WARN(&LOG,
1540  "Inconsistency in library override hierarchy of ID '%s'.\n"
1541  "\tNot enough data to verify validity of current proposed root '%s', assuming "
1542  "already set one '%s' is valid.",
1543  id->name,
1544  id_root->name,
1546  return;
1547  }
1548 
1549  ID *id_from_ref = id_from->override_library->reference;
1552  BLI_assert(entry != nullptr);
1553 
1554  bool do_replace_root = false;
1555  for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != nullptr;
1556  from_id_entry = from_id_entry->next) {
1557  if ((from_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
1558  /* Never consider non-overridable relationships as actual dependencies. */
1559  continue;
1560  }
1561 
1562  if (id_from_ref == from_id_entry->id_pointer.from) {
1563  /* A matching parent was found in reference linked data, assume given hierarchy root is
1564  * the valid one. */
1565  do_replace_root = true;
1566  CLOG_WARN(
1567  &LOG,
1568  "Inconsistency in library override hierarchy of ID '%s'.\n"
1569  "\tCurrent proposed root '%s' detected as valid, will replace already set one '%s'.",
1570  id->name,
1571  id_root->name,
1573  break;
1574  }
1575  }
1576 
1577  if (!do_replace_root) {
1578  CLOG_WARN(
1579  &LOG,
1580  "Inconsistency in library override hierarchy of ID '%s'.\n"
1581  "\tCurrent proposed root '%s' not detected as valid, keeping already set one '%s'.",
1582  id->name,
1583  id_root->name,
1585  return;
1586  }
1587  }
1588 
1589  id->override_library->hierarchy_root = id_root;
1590  }
1591 
1592  MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
1594  BLI_assert(entry != nullptr);
1595 
1596  for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != nullptr;
1597  to_id_entry = to_id_entry->next) {
1598  if ((to_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
1599  /* Never consider non-overridable relationships as actual dependencies. */
1600  continue;
1601  }
1602 
1603  ID *to_id = *to_id_entry->id_pointer.to;
1604  if (ELEM(to_id, nullptr, id)) {
1605  continue;
1606  }
1607  if (!ID_IS_OVERRIDE_LIBRARY(to_id) || (to_id->lib != id->lib)) {
1608  continue;
1609  }
1610 
1611  /* Recursively process the sub-hierarchy. */
1612  lib_override_root_hierarchy_set(bmain, id_root, to_id, id);
1613  }
1614 }
1615 
1617 {
1618  ID *id;
1619 
1620  BKE_main_relations_create(bmain, 0);
1621 
1622  FOREACH_MAIN_ID_BEGIN (bmain, id) {
1623  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
1624  continue;
1625  }
1626  if (id->override_library->hierarchy_root != nullptr) {
1629  CLOG_ERROR(
1630  &LOG,
1631  "Existing override hierarchy root ('%s') for ID '%s' is invalid, will try to find a "
1632  "new valid one",
1633  id->override_library->hierarchy_root != nullptr ?
1635  "<NONE>",
1636  id->name);
1637  id->override_library->hierarchy_root = nullptr;
1638  }
1639  else {
1640  continue;
1641  }
1642  }
1643 
1645 
1646  int best_level = 0;
1647  ID *id_root = lib_override_root_find(bmain, id, best_level, &best_level);
1648 
1649  if (!ELEM(id_root->override_library->hierarchy_root, id_root, nullptr)) {
1650  CLOG_WARN(&LOG,
1651  "Potential inconsistency in library override hierarchy of ID '%s', detected as "
1652  "part of the hierarchy of '%s', which has a different root '%s'",
1653  id->name,
1654  id_root->name,
1655  id_root->override_library->hierarchy_root->name);
1656  continue;
1657  }
1658 
1659  lib_override_root_hierarchy_set(bmain, id_root, id, nullptr);
1660 
1662  }
1664 
1665  BKE_main_relations_free(bmain);
1666 }
1667 
1669  const ID *id_root_reference,
1670  GHash *linkedref_to_old_override)
1671 {
1672  ID *id;
1673  IDRemapper *remapper = BKE_id_remapper_create();
1674  LinkNode *nomain_ids = nullptr;
1675 
1676  FOREACH_MAIN_ID_BEGIN (bmain, id) {
1677  if (id->tag & LIB_TAG_DOIT && id->newid != nullptr && id->lib == id_root_reference->lib) {
1678  ID *id_override_new = id->newid;
1679  ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id));
1680  if (id_override_old == nullptr) {
1681  continue;
1682  }
1683 
1684  BKE_id_remapper_add(remapper, id_override_old, id_override_new);
1685  }
1686  }
1688 
1689  /* Remap no-main override IDs we just created too. */
1690  GHashIterator linkedref_to_old_override_iter;
1691  GHASH_ITER (linkedref_to_old_override_iter, linkedref_to_old_override) {
1692  ID *id_override_old_iter = static_cast<ID *>(
1693  BLI_ghashIterator_getValue(&linkedref_to_old_override_iter));
1694  if ((id_override_old_iter->tag & LIB_TAG_NO_MAIN) == 0) {
1695  continue;
1696  }
1697 
1698  BLI_linklist_prepend(&nomain_ids, id_override_old_iter);
1699  }
1700 
1701  /* Remap all IDs to use the new override. */
1702  BKE_libblock_remap_multiple(bmain, remapper, 0);
1704  nomain_ids,
1706  remapper,
1708  BKE_id_remapper_free(remapper);
1709  BLI_linklist_free(nomain_ids, nullptr);
1710 }
1711 
1713  Scene *scene,
1714  ViewLayer *view_layer,
1715  ID *id_root,
1716  LinkNode *id_resync_roots,
1717  ListBase *no_main_ids_list,
1718  Collection *override_resync_residual_storage,
1719  const bool do_hierarchy_enforce,
1720  const bool do_post_process,
1721  BlendFileReadReport *reports)
1722 {
1724 
1725  ID *id_root_reference = id_root->override_library->reference;
1726  ID *id;
1727  const Object *old_active_object = view_layer ? OBACT(view_layer) : nullptr;
1728 
1729  if (id_root_reference->tag & LIB_TAG_MISSING) {
1730  BKE_reportf(reports != nullptr ? reports->reports : nullptr,
1731  RPT_ERROR,
1732  "Impossible to resync data-block %s and its dependencies, as its linked reference "
1733  "is missing",
1734  id_root->name + 2);
1735  return false;
1736  }
1737 
1738  BKE_main_relations_create(bmain, 0);
1740  data.bmain = bmain;
1741  data.scene = scene;
1742  data.id_root = id_root;
1743  data.hierarchy_root_id = id_root->override_library->hierarchy_root;
1744  data.tag = LIB_TAG_DOIT;
1745  data.missing_tag = LIB_TAG_MISSING;
1746  data.is_override = true;
1747  data.is_resync = true;
1749 
1750  /* Mapping 'linked reference IDs' -> 'Local override IDs' of existing overrides, populated from
1751  * each sub-tree that actually needs to be resynced. */
1752  GHash *linkedref_to_old_override = BLI_ghash_new(
1754 
1755  /* Only tag linked IDs from related linked reference hierarchy that are actually part of
1756  * the sub-trees of each detected sub-roots needing resync. */
1757  for (LinkNode *resync_root_link = id_resync_roots; resync_root_link != nullptr;
1758  resync_root_link = resync_root_link->next) {
1759  ID *id_resync_root = static_cast<ID *>(resync_root_link->link);
1760  BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_resync_root));
1761 
1762  if ((id_resync_root->tag & LIB_TAG_NO_MAIN) != 0) {
1763  CLOG_ERROR(&LOG,
1764  "While dealing with root '%s', resync root ID '%s' (%p) found to be alreaady "
1765  "resynced.\n",
1766  id_root->name,
1767  id_resync_root->name,
1768  id_resync_root);
1769  }
1770  // if (no_main_ids_list && BLI_findindex(no_main_ids_list, id_resync_root) != -1) {
1771  // CLOG_ERROR(
1772  // &LOG,
1773  // "While dealing with root '%s', resync root ID '%s' found to be alreaady
1774  // resynced.\n", id_root->name, id_resync_root->name);
1775  // }
1776 
1777  ID *id_resync_root_reference = id_resync_root->override_library->reference;
1778 
1779  if (id_resync_root_reference->tag & LIB_TAG_MISSING) {
1780  BKE_reportf(
1781  reports != nullptr ? reports->reports : nullptr,
1782  RPT_ERROR,
1783  "Impossible to resync data-block %s and its dependencies, as its linked reference "
1784  "is missing",
1785  id_root->name + 2);
1786  BLI_ghash_free(linkedref_to_old_override, nullptr, nullptr);
1787  BKE_main_relations_free(bmain);
1789  return false;
1790  }
1791 
1792  /* Tag local overrides of the current resync sub-hierarchy. */
1794  data.id_root = id_resync_root;
1795  data.is_override = true;
1797 
1798  /* Tag reference data matching the current resync sub-hierarchy. */
1800  data.id_root = id_resync_root->override_library->reference;
1801  data.is_override = false;
1803 
1806 
1807  FOREACH_MAIN_ID_BEGIN (bmain, id) {
1808  if ((id->lib != id_root->lib) || !ID_IS_OVERRIDE_LIBRARY(id)) {
1809  continue;
1810  }
1811 
1812  /* IDs that get fully removed from linked data remain as local overrides (using place-holder
1813  * linked IDs as reference), but they are often not reachable from any current valid local
1814  * override hierarchy anymore. This will ensure they get properly deleted at the end of this
1815  * function. */
1816  if (!ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
1818  /* Unfortunately deleting obdata means deleting their objects too. Since there is no
1819  * guarantee that a valid override object using an obsolete override obdata gets properly
1820  * updated, we ignore those here for now. In practice this should not be a big issue. */
1821  !OB_DATA_SUPPORT_ID(GS(id->name))) {
1822  id->tag |= LIB_TAG_MISSING;
1823  }
1824 
1825  /* While this should not happen in typical cases (and won't be properly supported here),
1826  * user is free to do all kind of very bad things, including having different local
1827  * overrides of a same linked ID in a same hierarchy. */
1828  IDOverrideLibrary *id_override_library = BKE_lib_override_library_get(
1829  bmain, id, nullptr, nullptr);
1830 
1831  if (id_override_library->hierarchy_root != id_root->override_library->hierarchy_root) {
1832  continue;
1833  }
1834 
1835  ID *reference_id = id_override_library->reference;
1836  if (GS(reference_id->name) != GS(id->name)) {
1837  switch (GS(id->name)) {
1838  case ID_KE:
1839  reference_id = reinterpret_cast<ID *>(BKE_key_from_id(reference_id));
1840  break;
1841  case ID_GR:
1842  BLI_assert(GS(reference_id->name) == ID_SCE);
1843  reference_id = reinterpret_cast<ID *>(
1844  reinterpret_cast<Scene *>(reference_id)->master_collection);
1845  break;
1846  case ID_NT:
1847  reference_id = reinterpret_cast<ID *>(ntreeFromID(id));
1848  break;
1849  default:
1850  break;
1851  }
1852  }
1853  if (reference_id == nullptr) {
1854  /* Can happen e.g. when there is a local override of a shapekey, but the matching linked
1855  * obdata (mesh etc.) does not have any shapekey anymore. */
1856  continue;
1857  }
1858  BLI_assert(GS(reference_id->name) == GS(id->name));
1859 
1860  if (!BLI_ghash_haskey(linkedref_to_old_override, reference_id)) {
1861  BLI_ghash_insert(linkedref_to_old_override, reference_id, id);
1862  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) || (id->tag & LIB_TAG_DOIT) == 0) {
1863  continue;
1864  }
1865  if ((id->override_library->reference->tag & LIB_TAG_DOIT) == 0) {
1866  /* We have an override, but now it does not seem to be necessary to override that ID
1867  * anymore. Check if there are some actual overrides from the user, otherwise assume
1868  * that we can get rid of this local override. */
1870  if (!ELEM(op->rna_prop_type, PROP_POINTER, PROP_COLLECTION)) {
1871  id->override_library->reference->tag |= LIB_TAG_DOIT;
1872  break;
1873  }
1874 
1875  bool do_break = false;
1876  LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) {
1877  if ((opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) {
1878  id->override_library->reference->tag |= LIB_TAG_DOIT;
1879  do_break = true;
1880  break;
1881  }
1882  }
1883  if (do_break) {
1884  break;
1885  }
1886  }
1887  }
1888  }
1889  }
1891 
1892  /* Code above may have added some tags, we need to update this too. */
1895  }
1896 
1897  /* Tag all local overrides of the current hierarchy. */
1899  data.id_root = id_root;
1900  data.is_override = true;
1902 
1903  BKE_main_relations_free(bmain);
1905 
1906  /* Make new override from linked data. */
1907  /* Note that this call also remaps all pointers of tagged IDs from old override IDs to new
1908  * override IDs (including within the old overrides themselves, since those are tagged too
1909  * above). */
1910  const bool success = BKE_lib_override_library_create_from_tag(
1911  bmain,
1912  nullptr,
1913  id_root_reference,
1914  id_root->override_library->hierarchy_root,
1915  nullptr,
1916  true,
1917  false);
1918 
1919  if (!success) {
1920  BLI_ghash_free(linkedref_to_old_override, nullptr, nullptr);
1921  return success;
1922  }
1923 
1924  ListBase *lb;
1925  FOREACH_MAIN_LISTBASE_BEGIN (bmain, lb) {
1927  if ((id->tag & LIB_TAG_DOIT) == 0 || id->newid == nullptr ||
1928  id->lib != id_root_reference->lib) {
1929  continue;
1930  }
1931  ID *id_override_new = id->newid;
1932  ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id));
1933 
1934  BLI_assert((id_override_new->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0);
1935 
1936  /* We need to 'move back' newly created override into its proper library (since it was
1937  * duplicated from the reference ID with 'no main' option, it should currently be the same
1938  * as the reference ID one). */
1939  BLI_assert( id_override_new->lib == id->lib);
1940  BLI_assert(id_override_old == nullptr || id_override_old->lib == id_root->lib);
1941  id_override_new->lib = id_root->lib;
1942  /* Remap step below will tag directly linked ones properly as needed. */
1943  if (ID_IS_LINKED(id_override_new)) {
1944  id_override_new->tag |= LIB_TAG_INDIRECT;
1945  }
1946 
1947  if (id_override_old != nullptr) {
1948  /* Swap the names between old override ID and new one. */
1949  char id_name_buf[MAX_ID_NAME];
1950  memcpy(id_name_buf, id_override_old->name, sizeof(id_name_buf));
1951  memcpy(id_override_old->name, id_override_new->name, sizeof(id_override_old->name));
1952  memcpy(id_override_new->name, id_name_buf, sizeof(id_override_new->name));
1953 
1954  BLI_insertlinkreplace(lb, id_override_old, id_override_new);
1955  id_override_old->tag |= LIB_TAG_NO_MAIN;
1956  id_override_new->tag &= ~LIB_TAG_NO_MAIN;
1957 
1958  lib_override_object_posemode_transfer(id_override_new, id_override_old);
1959 
1960  if (ID_IS_OVERRIDE_LIBRARY_REAL(id_override_new)) {
1961  BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_override_old));
1962 
1963  id_override_new->override_library->flag = id_override_old->override_library->flag;
1964 
1965  /* Copy over overrides rules from old override ID to new one. */
1966  BLI_duplicatelist(&id_override_new->override_library->properties,
1967  &id_override_old->override_library->properties);
1968  IDOverrideLibraryProperty *op_new = static_cast<IDOverrideLibraryProperty *>(
1969  id_override_new->override_library->properties.first);
1970  IDOverrideLibraryProperty *op_old = static_cast<IDOverrideLibraryProperty *>(
1971  id_override_old->override_library->properties.first);
1972  for (; op_new; op_new = op_new->next, op_old = op_old->next) {
1973  lib_override_library_property_copy(op_new, op_old);
1974  }
1975  }
1976 
1977  BLI_addtail(no_main_ids_list, id_override_old);
1978  }
1979  else {
1980  /* Add to proper main list, ensure unique name for local ID, sort, and clear relevant
1981  * tags. */
1982  BKE_libblock_management_main_add(bmain, id_override_new);
1983  }
1984  }
1986  }
1988 
1989  /* We remap old to new override usages in a separate loop, after all new overrides have
1990  * been added to Main. */
1991  lib_override_library_remap(bmain, id_root_reference, linkedref_to_old_override);
1992 
1993  BKE_main_collection_sync(bmain);
1994 
1995  LinkNode *id_override_old_list = nullptr;
1996 
1997  /* We need to apply override rules in a separate loop, after all ID pointers have been properly
1998  * remapped, and all new local override IDs have gotten their proper original names, otherwise
1999  * override operations based on those ID names would fail. */
2000  FOREACH_MAIN_ID_BEGIN (bmain, id) {
2001  if ((id->tag & LIB_TAG_DOIT) == 0 || id->newid == nullptr ||
2002  id->lib != id_root_reference->lib) {
2003  continue;
2004  }
2005 
2006  ID *id_override_new = id->newid;
2007  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_override_new)) {
2008  continue;
2009  }
2010 
2011  ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id));
2012  if (id_override_old == nullptr) {
2013  continue;
2014  }
2015 
2016  if (ID_IS_OVERRIDE_LIBRARY_REAL(id_override_old)) {
2017  /* Apply rules on new override ID using old one as 'source' data. */
2018  /* Note that since we already remapped ID pointers in old override IDs to new ones, we
2019  * can also apply ID pointer override rules safely here. */
2020  PointerRNA rnaptr_src, rnaptr_dst;
2021  RNA_id_pointer_create(id_override_old, &rnaptr_src);
2022  RNA_id_pointer_create(id_override_new, &rnaptr_dst);
2023 
2024  /* We remove any operation tagged with `IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE`,
2025  * that way the potentially new pointer will be properly kept, when old one is still valid
2026  * too (typical case: assigning new ID to some usage, while old one remains used elsewhere
2027  * in the override hierarchy). */
2029  IDOverrideLibraryProperty *, op, &id_override_new->override_library->properties) {
2033  BLI_freelinkN(&op->operations, opop);
2034  }
2035  }
2036  if (BLI_listbase_is_empty(&op->operations)) {
2038  }
2039  }
2040 
2042  &rnaptr_dst,
2043  &rnaptr_src,
2044  nullptr,
2045  id_override_new->override_library,
2046  do_hierarchy_enforce ? RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS :
2048  }
2049 
2050  BLI_linklist_prepend(&id_override_old_list, id_override_old);
2051  }
2053 
2054  /* Once overrides have been properly 'transferred' from old to new ID, we can clear ID usages
2055  * of the old one.
2056  * This is necessary in case said old ID is not in Main anymore. */
2057  IDRemapper *id_remapper = BKE_id_remapper_create();
2059  id_override_old_list,
2061  id_remapper,
2063  for (LinkNode *ln_iter = id_override_old_list; ln_iter != nullptr; ln_iter = ln_iter->next) {
2064  ID *id_override_old = static_cast<ID *>(ln_iter->link);
2065  id_override_old->tag |= LIB_TAG_NO_USER_REFCOUNT;
2066  }
2067  BKE_id_remapper_free(id_remapper);
2068  BLI_linklist_free(id_override_old_list, nullptr);
2069 
2070  /* Delete old override IDs.
2071  * Note that we have to use tagged group deletion here, since ID deletion also uses
2072  * LIB_TAG_DOIT. This improves performances anyway, so everything is fine. */
2073  int user_edited_overrides_deletion_count = 0;
2074  FOREACH_MAIN_ID_BEGIN (bmain, id) {
2075  if (id->tag & LIB_TAG_DOIT) {
2076  /* Note that this works because linked IDs are always after local ones (including
2077  * overrides), so we will only ever tag an old override ID after we have already checked it
2078  * in this loop, hence we cannot untag it later. */
2079  if (id->newid != nullptr && id->lib == id_root_reference->lib) {
2080  ID *id_override_old = static_cast<ID *>(BLI_ghash_lookup(linkedref_to_old_override, id));
2081 
2082  if (id_override_old != nullptr) {
2083  id->newid->tag &= ~LIB_TAG_DOIT;
2084  id_override_old->tag |= LIB_TAG_DOIT;
2085  if (id_override_old->tag & LIB_TAG_NO_MAIN) {
2086  BLI_assert(BLI_findindex(no_main_ids_list, id_override_old) != -1);
2087  }
2088  }
2089  }
2090  id->tag &= ~LIB_TAG_DOIT;
2091  }
2092  /* Also deal with old overrides that went missing in new linked data - only for real local
2093  * overrides for now, not those who are linked. */
2094  else if (id->tag & LIB_TAG_MISSING && !ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY(id)) {
2095  if (ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
2097  /* Do not delete overrides which reference is missing because the library itself is missing
2098  * (ref. T100586). */
2099  }
2101  /* If user never edited them, we can delete them. */
2102  id->tag |= LIB_TAG_DOIT;
2103  id->tag &= ~LIB_TAG_MISSING;
2104  CLOG_INFO(&LOG, 2, "Old override %s is being deleted", id->name);
2105  }
2106 #if 0
2107  else {
2108  /* Otherwise, keep them, user needs to decide whether what to do with them. */
2109  BLI_assert((id->tag & LIB_TAG_DOIT) == 0);
2110  id_fake_user_set(id);
2112  CLOG_INFO(&LOG, 2, "Old override %s is being kept around as it was user-edited", id->name);
2113  }
2114 #else
2115  else {
2116  /* Delete them nevertheless, with fat warning, user needs to decide whether they want to
2117  * save that version of the file (and accept the loss), or not. */
2118  id->tag |= LIB_TAG_DOIT;
2119  id->tag &= ~LIB_TAG_MISSING;
2120  CLOG_WARN(
2121  &LOG, "Old override %s is being deleted even though it was user-edited", id->name);
2122  user_edited_overrides_deletion_count++;
2123  }
2124 #endif
2125  }
2126  }
2128 
2129  /* Cleanup, many pointers in this GHash are already invalid now. */
2130  BLI_ghash_free(linkedref_to_old_override, nullptr, nullptr);
2131 
2133 
2134  /* At this point, `id_root` may have been resynced, therefore deleted. In that case we need to
2135  * update it to its new version.
2136  */
2137  if (id_root_reference->newid != nullptr) {
2138  id_root = id_root_reference->newid;
2139  }
2140 
2141  if (user_edited_overrides_deletion_count > 0) {
2142  BKE_reportf(reports != nullptr ? reports->reports : nullptr,
2143  RPT_WARNING,
2144  "During resync of data-block %s, %d obsolete overrides were deleted, that had "
2145  "local changes defined by user",
2146  id_root->name + 2,
2147  user_edited_overrides_deletion_count);
2148  }
2149 
2150  if (do_post_process) {
2151  /* Essentially ensures that potentially new overrides of new objects will be instantiated. */
2152  /* NOTE: Here 'reference' collection and 'newly added' collection are the same, which is fine
2153  * since we already relinked old root override collection to new resync'ed one above. So this
2154  * call is not expected to instantiate this new resync'ed collection anywhere, just to ensure
2155  * that we do not have any stray objects. */
2157  scene,
2158  view_layer,
2159  nullptr,
2160  id_root_reference,
2161  id_root,
2162  override_resync_residual_storage,
2163  old_active_object,
2164  true);
2165  }
2166 
2167  /* Cleanup. */
2169  BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); /* That one should not be needed in fact. */
2170 
2171  return success;
2172 }
2173 
2175  Scene *scene,
2176  ViewLayer *view_layer,
2177  ID *id_root,
2178  Collection *override_resync_residual_storage,
2179  const bool do_hierarchy_enforce,
2180  BlendFileReadReport *reports)
2181 {
2182  ListBase no_main_ids_list = {nullptr};
2183  LinkNode id_resync_roots{};
2184  id_resync_roots.link = id_root;
2185  id_resync_roots.next = nullptr;
2186 
2187  const bool success = lib_override_library_resync(bmain,
2188  scene,
2189  view_layer,
2190  id_root,
2191  &id_resync_roots,
2192  &no_main_ids_list,
2193  override_resync_residual_storage,
2194  do_hierarchy_enforce,
2195  true,
2196  reports);
2197 
2198  LISTBASE_FOREACH_MUTABLE (ID *, id_iter, &no_main_ids_list) {
2199  BKE_id_free(bmain, id_iter);
2200  }
2201 
2202  return success;
2203 }
2204 
2206  const int library_indirect_level,
2207  const bool do_strict_equal)
2208 {
2209  const int id_lib_level = (ID_IS_LINKED(id) ? id->lib->temp_index : 0);
2210  return do_strict_equal ? id_lib_level == library_indirect_level :
2211  id_lib_level <= library_indirect_level;
2212 }
2213 
2214 /* Find the root of the override hierarchy the given `id` belongs to. */
2216 {
2217  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
2218  const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
2219  if (id_type->owner_get != nullptr) {
2220  id = id_type->owner_get(bmain, id, nullptr);
2221  }
2223  }
2224 
2225  ID *hierarchy_root_id = id->override_library->hierarchy_root;
2226  BLI_assert(hierarchy_root_id != nullptr);
2227  BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(hierarchy_root_id));
2228  return hierarchy_root_id;
2229 }
2230 
2231 /* Check ancestors overrides for resync, to ensure all IDs in-between two tagged-for-resync ones
2232  * are also properly tagged, and to identify the resync root of this subset of the whole hierarchy.
2233  *
2234  * WARNING: Expects `bmain` to have valid relation data.
2235  *
2236  * Returns `true` if it finds an ancestor within the current liboverride hierarchy also tagged as
2237  * needing resync, `false` otherwise.
2238  *
2239  * NOTE: If `check_only` is true, it only does the check and returns, without any modification to
2240  * the data. Used for debug/data validation purposes.
2241  */
2243  Main *bmain, ID *id, GHash *id_roots, const int library_indirect_level, const bool check_only)
2244 {
2246 
2247  if (!lib_override_resync_id_lib_level_is_valid(id, library_indirect_level, false) &&
2248  !check_only) {
2249  CLOG_ERROR(
2250  &LOG,
2251  "While processing indirect level %d, ID %s from lib %s of indirect level %d detected "
2252  "as needing resync, skipping.",
2253  library_indirect_level,
2254  id->name,
2255  id->lib->filepath,
2256  id->lib->temp_index);
2258  return false;
2259  }
2260 
2261  MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
2263  BLI_assert(entry != nullptr);
2264 
2266  /* This ID has already been processed. */
2268  }
2269 
2270  /* This way we won't process again that ID, should we encounter it again through another
2271  * relationship hierarchy. */
2273 
2274  /* There can be dependency loops in relationships, e.g.:
2275  * - Rig object uses armature ID.
2276  * - Armature ID has some drivers using rig object as variable.
2277  *
2278  * In that case, if this function is initially called on the rig object (therefore tagged as
2279  * needing resync), it will:
2280  * - Process the rig object
2281  * -- Recurse over the armature ID
2282  * --- Recurse over the rig object again
2283  * --- The rig object is detected as already processed and returns true.
2284  * -- The armature has a tagged ancestor (the rig object), so it is not a resync root.
2285  * - The rig object has a tagged ancestor (the armature), so it is not a resync root.
2286  * ...and this ends up with no resync root.
2287  *
2288  * Removing the 'need resync' tag before doing the recursive calls allow to break this loop and
2289  * results in actually getting a resync root, even though it may not be the 'logical' one.
2290  *
2291  * In the example above, the armature will become the resync root.
2292  */
2293  const int id_tag_need_resync = (id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC);
2295 
2296  bool is_ancestor_tagged_for_resync = false;
2297  for (MainIDRelationsEntryItem *entry_item = entry->from_ids; entry_item != nullptr;
2298  entry_item = entry_item->next) {
2299  if (entry_item->usage_flag &
2301  continue;
2302  }
2303 
2304  ID *id_from = entry_item->id_pointer.from;
2305 
2306  /* Check if this ID has an override hierarchy ancestor already tagged for resync. */
2307  if (id_from != id && ID_IS_OVERRIDE_LIBRARY_REAL(id_from) && id_from->lib == id->lib &&
2309  const bool is_ancestor_tagged_for_resync_prev = is_ancestor_tagged_for_resync;
2310  is_ancestor_tagged_for_resync |= lib_override_resync_tagging_finalize_recurse(
2311  bmain, id_from, id_roots, library_indirect_level, check_only);
2312 
2313  if (!check_only && is_ancestor_tagged_for_resync && !is_ancestor_tagged_for_resync_prev) {
2314  CLOG_INFO(&LOG,
2315  4,
2316  "ID %s (%p) now tagged as needing resync because they are used by %s (%p) "
2317  "that needs to be resynced",
2318  id->name,
2319  id->lib,
2320  id_from->name,
2321  id_from->lib);
2322  }
2323  }
2324  }
2325 
2326  /* Re-enable 'need resync' tag if needed. */
2327  id->tag |= id_tag_need_resync;
2328 
2329  if (check_only) {
2330  return is_ancestor_tagged_for_resync;
2331  }
2332 
2333  if (is_ancestor_tagged_for_resync) {
2334  /* If a tagged-for-resync ancestor was found, this id is not a resync sub-tree root, but it is
2335  * part of one, and therefore needs to be tagged for resync too. */
2337  }
2338  else if (id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) {
2339  CLOG_INFO(&LOG,
2340  4,
2341  "ID %s (%p) is tagged as needing resync, but none of its override hierarchy "
2342  "ancestors are tagged for resync, so it is a partial resync root",
2343  id->name,
2344  id->lib);
2345 
2346  /* If no tagged-for-resync ancestor was found, but this id is tagged for resync, then it is a
2347  * root of a resync sub-tree. Find the root of the whole override hierarchy and add this ID as
2348  * one of its resync sub-tree roots. */
2349  ID *id_root = lib_override_library_main_resync_root_get(bmain, id);
2350  BLI_assert(id_root->lib == id->lib);
2351 
2352  CLOG_INFO(&LOG, 4, "Found root ID '%s' for resync root ID '%s'", id_root->name, id->name);
2353 
2354  BLI_assert(id_root->override_library != nullptr);
2355 
2356  LinkNodePair **id_resync_roots_p;
2357  if (!BLI_ghash_ensure_p(id_roots, id_root, reinterpret_cast<void ***>(&id_resync_roots_p))) {
2358  *id_resync_roots_p = MEM_cnew<LinkNodePair>(__func__);
2359  }
2360 
2361  BLI_linklist_append(*id_resync_roots_p, id);
2362  is_ancestor_tagged_for_resync = true;
2363  }
2364 
2365  return is_ancestor_tagged_for_resync;
2366 }
2367 
2368 /* Ensure resync of all overrides at one level of indirect usage.
2369  *
2370  * We need to handle each level independently, since an override at level n may be affected by
2371  * other overrides from level n + 1 etc. (i.e. from linked overrides it may use).
2372  */
2374  Main *bmain,
2375  Scene *scene,
2376  ViewLayer *view_layer,
2377  Collection *override_resync_residual_storage,
2378  const int library_indirect_level,
2379  BlendFileReadReport *reports)
2380 {
2381  const bool do_reports_recursive_resync_timing = (library_indirect_level != 0);
2382  const double init_time = do_reports_recursive_resync_timing ? PIL_check_seconds_timer() : 0.0;
2383 
2384  BKE_main_relations_create(bmain, 0);
2385  BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
2386 
2387  /* NOTE: in code below, the order in which `FOREACH_MAIN_ID_BEGIN` processes ID types ensures
2388  * that we always process 'higher-level' overrides first (i.e. scenes, then collections, then
2389  * objects, then other types). */
2390 
2391  /* Detect all linked data that would need to be overridden if we had to create an override from
2392  * those used by current existing overrides. */
2394  data.bmain = bmain;
2395  data.scene = scene;
2396  data.id_root = nullptr;
2397  data.tag = LIB_TAG_DOIT;
2398  data.missing_tag = LIB_TAG_MISSING;
2399  data.is_override = false;
2400  data.is_resync = true;
2402  ID *id;
2403  FOREACH_MAIN_ID_BEGIN (bmain, id) {
2404  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
2405  continue;
2406  }
2407 
2408  if (!lib_override_resync_id_lib_level_is_valid(id, library_indirect_level, true)) {
2409  continue;
2410  }
2411 
2412  if (id->tag & (LIB_TAG_DOIT | LIB_TAG_MISSING)) {
2413  /* We already processed that ID as part of another ID's hierarchy. */
2414  continue;
2415  }
2416 
2417  /* Do not attempt to resync from missing data. */
2418  if (((id->tag | id->override_library->reference->tag) & LIB_TAG_MISSING) != 0) {
2419  continue;
2420  }
2421 
2423  /* This ID is not part of an override hierarchy. */
2424  continue;
2425  }
2426 
2427  data.id_root = id->override_library->reference;
2432  }
2435 
2436  GHash *id_roots = BLI_ghash_ptr_new(__func__);
2437 
2438  /* Now check existing overrides, those needing resync will be the one either already tagged as
2439  * such, or the one using linked data that is now tagged as needing override. */
2441  FOREACH_MAIN_ID_BEGIN (bmain, id) {
2442  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
2443  continue;
2444  }
2445 
2446  if (!lib_override_resync_id_lib_level_is_valid(id, library_indirect_level, true)) {
2447  continue;
2448  }
2449 
2450  /* Do not attempt to resync from missing data. */
2451  if (((id->tag | id->override_library->reference->tag) & LIB_TAG_MISSING) != 0) {
2452  continue;
2453  }
2454 
2456  /* This ID is not part of an override hierarchy. */
2458  continue;
2459  }
2460 
2462  CLOG_INFO(&LOG, 4, "ID %s (%p) was already tagged as needing resync", id->name, id->lib);
2464  bmain, id, id_roots, library_indirect_level, false);
2465  continue;
2466  }
2467 
2468  MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
2470  BLI_assert(entry != nullptr);
2471 
2472  for (MainIDRelationsEntryItem *entry_item = entry->to_ids; entry_item != nullptr;
2473  entry_item = entry_item->next) {
2474  if (entry_item->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) {
2475  continue;
2476  }
2477  ID *id_to = *entry_item->id_pointer.to;
2478 
2479  /* Case where this ID pointer was to a linked ID, that now needs to be overridden. */
2480  if (ID_IS_LINKED(id_to) && (id_to->lib != id->lib) && (id_to->tag & LIB_TAG_DOIT) != 0) {
2482  CLOG_INFO(&LOG,
2483  3,
2484  "ID %s (%p) now tagged as needing resync because they use linked %s (%p) that "
2485  "now needs to be overridden",
2486  id->name,
2487  id->lib,
2488  id_to->name,
2489  id_to->lib);
2491  bmain, id, id_roots, library_indirect_level, false);
2492  break;
2493  }
2494  }
2495  }
2497 
2498 #ifndef NDEBUG
2499  /* Check for validity/integrity of the computed set of root IDs, and their sub-branches defined
2500  * by their resync root IDs. */
2501  {
2503  GHashIterator *id_roots_iter = BLI_ghashIterator_new(id_roots);
2504  while (!BLI_ghashIterator_done(id_roots_iter)) {
2505  ID *id_root = static_cast<ID *>(BLI_ghashIterator_getKey(id_roots_iter));
2506  LinkNodePair *id_resync_roots = static_cast<LinkNodePair *>(
2507  BLI_ghashIterator_getValue(id_roots_iter));
2508  CLOG_INFO(
2509  &LOG, 2, "Checking validity of computed TODO data for root '%s'... \n", id_root->name);
2510  for (LinkNode *id_resync_root_iter = id_resync_roots->list; id_resync_root_iter != nullptr;
2511  id_resync_root_iter = id_resync_root_iter->next) {
2512  ID *id_resync_root = static_cast<ID *>(id_resync_root_iter->link);
2513  BLI_assert(id_resync_root == id_root || !BLI_ghash_haskey(id_roots, id_resync_root));
2514  if (id_resync_root == id_root) {
2515  BLI_assert(id_resync_root_iter == id_resync_roots->list &&
2516  id_resync_root_iter == id_resync_roots->last_node);
2517  }
2519  bmain, id_resync_root, id_roots, library_indirect_level, true));
2520  }
2521  BLI_ghashIterator_step(id_roots_iter);
2522  }
2523  BLI_ghashIterator_free(id_roots_iter);
2524  }
2525 #endif
2526 
2527  BKE_main_relations_free(bmain);
2528  BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
2529 
2530  ListBase no_main_ids_list = {nullptr};
2531 
2532  GHashIterator *id_roots_iter = BLI_ghashIterator_new(id_roots);
2533  while (!BLI_ghashIterator_done(id_roots_iter)) {
2534  ID *id_root = static_cast<ID *>(BLI_ghashIterator_getKey(id_roots_iter));
2535  Library *library = id_root->lib;
2536  LinkNodePair *id_resync_roots = static_cast<LinkNodePair *>(
2537  BLI_ghashIterator_getValue(id_roots_iter));
2538 
2539  if (ID_IS_LINKED(id_root)) {
2540  id_root->lib->tag |= LIBRARY_TAG_RESYNC_REQUIRED;
2541  }
2542 
2543  CLOG_INFO(&LOG,
2544  2,
2545  "Resyncing all dependencies under root %s (%p), first one being '%s'...",
2546  id_root->name,
2547  reinterpret_cast<void *>(library),
2548  reinterpret_cast<ID *>(id_resync_roots->list->link)->name);
2549  const bool success = lib_override_library_resync(bmain,
2550  scene,
2551  view_layer,
2552  id_root,
2553  id_resync_roots->list,
2554  &no_main_ids_list,
2555  override_resync_residual_storage,
2556  false,
2557  false,
2558  reports);
2559  CLOG_INFO(&LOG, 2, "\tSuccess: %d", success);
2560  if (success) {
2561  reports->count.resynced_lib_overrides++;
2562  if (library_indirect_level > 0 && reports->do_resynced_lib_overrides_libraries_list &&
2566  }
2567  }
2568 
2569  BLI_linklist_free(id_resync_roots->list, nullptr);
2570  BLI_ghashIterator_step(id_roots_iter);
2571  }
2572  BLI_ghashIterator_free(id_roots_iter);
2573 
2574  LISTBASE_FOREACH_MUTABLE (ID *, id_iter, &no_main_ids_list) {
2575  BKE_id_free(bmain, id_iter);
2576  }
2577  BLI_listbase_clear(&no_main_ids_list);
2578 
2579  /* Check there are no left-over IDs needing resync from the current (or higher) level of indirect
2580  * library level. */
2581  FOREACH_MAIN_ID_BEGIN (bmain, id) {
2582  if (!ID_IS_OVERRIDE_LIBRARY(id)) {
2583  continue;
2584  }
2585  /* Do not attempt to resync to/from missing data. */
2587  LIB_TAG_MISSING) != 0) {
2588  continue;
2589  }
2590 
2591  const bool is_valid_tagged_need_resync = ((id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0 ||
2593  id, library_indirect_level - 1, false));
2594  if (!is_valid_tagged_need_resync) {
2595  CLOG_ERROR(&LOG,
2596  "ID override %s from library level %d still found as needing resync, when all "
2597  "IDs from that level should have been processed after tackling library level %d",
2598  id->name,
2599  ID_IS_LINKED(id) ? id->lib->temp_index : 0,
2600  library_indirect_level);
2602  }
2603  }
2605 
2606  BLI_ghash_free(id_roots, nullptr, MEM_freeN);
2607 
2608  /* In some fairly rare (and degenerate) cases, some root ID from other liboverrides may have been
2609  * freed, and therefore set to nullptr. Attempt to fix this as best as possible. */
2611 
2612  if (do_reports_recursive_resync_timing) {
2614  }
2615 }
2616 
2618 {
2619  if (cb_data->cb_flag & IDWALK_CB_LOOPBACK) {
2620  return IDWALK_RET_NOP;
2621  }
2622  ID *id_owner = cb_data->id_owner;
2623  ID *id = *cb_data->id_pointer;
2624  if (id != nullptr && ID_IS_LINKED(id) && id->lib != id_owner->lib) {
2625  const int owner_library_indirect_level = ID_IS_LINKED(id_owner) ? id_owner->lib->temp_index :
2626  0;
2627  if (owner_library_indirect_level > 100) {
2628  CLOG_ERROR(&LOG,
2629  "Levels of indirect usages of libraries is way too high, there are most likely "
2630  "dependency loops, skipping further building loops (involves at least '%s' from "
2631  "'%s' and '%s' from '%s')",
2632  id_owner->name,
2633  id_owner->lib->filepath,
2634  id->name,
2635  id->lib->filepath);
2636  return IDWALK_RET_NOP;
2637  }
2638  if (owner_library_indirect_level > 90) {
2639  CLOG_WARN(
2640  &LOG,
2641  "Levels of indirect usages of libraries is suspiciously too high, there are most likely "
2642  "dependency loops (involves at least '%s' from '%s' and '%s' from '%s')",
2643  id_owner->name,
2644  id_owner->lib->filepath,
2645  id->name,
2646  id->lib->filepath);
2647  }
2648 
2649  if (owner_library_indirect_level >= id->lib->temp_index) {
2650  id->lib->temp_index = owner_library_indirect_level + 1;
2651  *reinterpret_cast<bool *>(cb_data->user_data) = true;
2652  }
2653  }
2654  return IDWALK_RET_NOP;
2655 }
2656 
2662 {
2663  LISTBASE_FOREACH (Library *, library, &bmain->libraries) {
2664  /* index 0 is reserved for local data. */
2665  library->temp_index = 1;
2666  }
2667  bool do_continue = true;
2668  while (do_continue) {
2669  do_continue = false;
2670  ID *id;
2671  FOREACH_MAIN_ID_BEGIN (bmain, id) {
2673  bmain, id, lib_override_sort_libraries_func, &do_continue, IDWALK_READONLY);
2674  }
2676  }
2677 
2678  int library_indirect_level_max = 0;
2679  LISTBASE_FOREACH (Library *, library, &bmain->libraries) {
2680  if (library->temp_index > library_indirect_level_max) {
2681  library_indirect_level_max = library->temp_index;
2682  }
2683  }
2684  return library_indirect_level_max;
2685 }
2686 
2688  Scene *scene,
2689  ViewLayer *view_layer,
2690  BlendFileReadReport *reports)
2691 {
2692  /* We use a specific collection to gather/store all 'orphaned' override collections and objects
2693  * generated by re-sync-process. This avoids putting them in scene's master collection. */
2694 #define OVERRIDE_RESYNC_RESIDUAL_STORAGE_NAME "OVERRIDE_RESYNC_LEFTOVERS"
2695  Collection *override_resync_residual_storage = static_cast<Collection *>(BLI_findstring(
2696  &bmain->collections, OVERRIDE_RESYNC_RESIDUAL_STORAGE_NAME, offsetof(ID, name) + 2));
2697  if (override_resync_residual_storage != nullptr &&
2698  ID_IS_LINKED(override_resync_residual_storage)) {
2699  override_resync_residual_storage = nullptr;
2700  }
2701  if (override_resync_residual_storage == nullptr) {
2702  override_resync_residual_storage = BKE_collection_add(
2704  /* Hide the collection from viewport and render. */
2705  override_resync_residual_storage->flag |= COLLECTION_HIDE_VIEWPORT | COLLECTION_HIDE_RENDER;
2706  }
2707 
2708  const Object *old_active_object = OBACT(view_layer);
2709 
2710  /* Necessary to improve performances, and prevent layers matching override sub-collections to be
2711  * lost when re-syncing the parent override collection.
2712  * Ref. T73411. */
2714 
2715  int library_indirect_level = lib_override_libraries_index_define(bmain);
2716  while (library_indirect_level >= 0) {
2717  /* Update overrides from each indirect level separately. */
2719  scene,
2720  view_layer,
2721  override_resync_residual_storage,
2722  library_indirect_level,
2723  reports);
2724  library_indirect_level--;
2725  }
2726 
2728 
2729  /* Essentially ensures that potentially new overrides of new objects will be instantiated. */
2731  scene,
2732  view_layer,
2733  nullptr,
2734  nullptr,
2735  nullptr,
2736  override_resync_residual_storage,
2737  old_active_object,
2738  true);
2739 
2740  if (BKE_collection_is_empty(override_resync_residual_storage)) {
2741  BKE_collection_delete(bmain, override_resync_residual_storage, true);
2742  }
2743 
2744  LISTBASE_FOREACH (Library *, library, &bmain->libraries) {
2745  if (library->tag & LIBRARY_TAG_RESYNC_REQUIRED) {
2746  CLOG_INFO(&LOG,
2747  2,
2748  "library '%s' contains some linked overrides that required recursive resync, "
2749  "consider updating it",
2750  library->filepath);
2751  }
2752  }
2753 
2755 }
2756 
2758 {
2760 
2761  /* Tag all library overrides in the chains of dependencies from the given root one. */
2762  BKE_main_relations_create(bmain, 0);
2764  data.bmain = bmain;
2765  data.scene = nullptr;
2766  data.id_root = id_root;
2767  data.hierarchy_root_id = id_root->override_library->hierarchy_root;
2768  data.tag = LIB_TAG_DOIT;
2769  data.missing_tag = LIB_TAG_MISSING;
2770  data.is_override = true;
2771  data.is_resync = false;
2774 
2775  BKE_main_relations_free(bmain);
2777 
2778  ID *id;
2779  FOREACH_MAIN_ID_BEGIN (bmain, id) {
2780  if (id->tag & LIB_TAG_DOIT) {
2781  if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
2782  ID *id_override_reference = id->override_library->reference;
2783 
2784  /* Remap the whole local IDs to use the linked data. */
2785  BKE_libblock_remap(bmain, id, id_override_reference, ID_REMAP_SKIP_INDIRECT_USAGE);
2786  }
2787  }
2788  }
2790 
2791  /* Delete the override IDs. */
2793 
2794  /* Should not actually be needed here. */
2795  BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
2796 }
2797 
2799 {
2800  if (!ID_IS_OVERRIDE_LIBRARY(id)) {
2801  return;
2802  }
2804  /* We should never directly 'make local' virtual overrides (aka shape keys). */
2806  id->flag &= ~LIB_EMBEDDED_DATA_LIB_OVERRIDE;
2807  return;
2808  }
2809 
2811 
2812  Key *shape_key = BKE_key_from_id(id);
2813  if (shape_key != nullptr) {
2814  shape_key->id.flag &= ~LIB_EMBEDDED_DATA_LIB_OVERRIDE;
2815  }
2816 
2817  if (GS(id->name) == ID_SCE) {
2818  Collection *master_collection = reinterpret_cast<Scene *>(id)->master_collection;
2819  if (master_collection != nullptr) {
2820  master_collection->id.flag &= ~LIB_EMBEDDED_DATA_LIB_OVERRIDE;
2821  }
2822  }
2823 
2825  if (node_tree != nullptr) {
2827  }
2828 }
2829 
2831  IDOverrideLibrary *override)
2832 {
2833  if (override->runtime == nullptr) {
2834  override->runtime = MEM_cnew<IDOverrideLibraryRuntime>(__func__);
2835  }
2836  return override->runtime;
2837 }
2838 
2839 /* We only build override GHash on request. */
2841 {
2843  if (override_runtime->rna_path_to_override_properties == nullptr) {
2844  override_runtime->rna_path_to_override_properties = BLI_ghash_new(
2846  for (IDOverrideLibraryProperty *op =
2847  static_cast<IDOverrideLibraryProperty *>(override->properties.first);
2848  op != nullptr;
2849  op = op->next) {
2850  BLI_ghash_insert(override_runtime->rna_path_to_override_properties, op->rna_path, op);
2851  }
2852  }
2853 
2854  return override_runtime->rna_path_to_override_properties;
2855 }
2856 
2858  const char *rna_path)
2859 {
2860  GHash *override_runtime = override_library_rna_path_mapping_ensure(override);
2861  return static_cast<IDOverrideLibraryProperty *>(BLI_ghash_lookup(override_runtime, rna_path));
2862 }
2863 
2865  const char *rna_path,
2866  bool *r_created)
2867 {
2869 
2870  if (op == nullptr) {
2871  op = MEM_cnew<IDOverrideLibraryProperty>(__func__);
2872  op->rna_path = BLI_strdup(rna_path);
2873  BLI_addtail(&override->properties, op);
2874 
2875  GHash *override_runtime = override_library_rna_path_mapping_ensure(override);
2876  BLI_ghash_insert(override_runtime, op->rna_path, op);
2877 
2878  if (r_created) {
2879  *r_created = true;
2880  }
2881  }
2882  else if (r_created) {
2883  *r_created = false;
2884  }
2885 
2886  return op;
2887 }
2888 
2890  const IDOverrideLibraryProperty *library_prop,
2891  PointerRNA *r_override_poin,
2892  PropertyRNA **r_override_prop,
2893  int *r_index)
2894 {
2897  idpoin, library_prop->rna_path, r_override_poin, r_override_prop, r_index);
2898 }
2899 
2901  IDOverrideLibraryProperty *op_src)
2902 {
2903  op_dst->rna_path = BLI_strdup(op_src->rna_path);
2904  BLI_duplicatelist(&op_dst->operations, &op_src->operations);
2905 
2907  opop_dst = static_cast<IDOverrideLibraryPropertyOperation *>(op_dst->operations.first),
2908  *opop_src = static_cast<IDOverrideLibraryPropertyOperation *>(op_src->operations.first);
2909  opop_dst;
2910  opop_dst = opop_dst->next, opop_src = opop_src->next) {
2912  }
2913 }
2914 
2916 {
2917  BLI_assert(op->rna_path != nullptr);
2918 
2919  MEM_freeN(op->rna_path);
2920 
2923  }
2924  BLI_freelistN(&op->operations);
2925 }
2926 
2928  IDOverrideLibraryProperty *override_property)
2929 {
2930  if (!ELEM(nullptr, override->runtime, override->runtime->rna_path_to_override_properties)) {
2931  BLI_ghash_remove(override->runtime->rna_path_to_override_properties,
2932  override_property->rna_path,
2933  nullptr,
2934  nullptr);
2935  }
2936  lib_override_library_property_clear(override_property);
2937  BLI_freelinkN(&override->properties, override_property);
2938 }
2939 
2941  IDOverrideLibraryProperty *override_property,
2942  const char *subitem_refname,
2943  const char *subitem_locname,
2944  const int subitem_refindex,
2945  const int subitem_locindex,
2946  const bool strict,
2947  bool *r_strict)
2948 {
2950  const int subitem_defindex = -1;
2951 
2952  if (r_strict) {
2953  *r_strict = true;
2954  }
2955 
2956  if (subitem_locname != nullptr) {
2957  opop = static_cast<IDOverrideLibraryPropertyOperation *>(
2958  BLI_findstring_ptr(&override_property->operations,
2959  subitem_locname,
2960  offsetof(IDOverrideLibraryPropertyOperation, subitem_local_name)));
2961 
2962  if (opop == nullptr) {
2963  return nullptr;
2964  }
2965 
2966  if (subitem_refname == nullptr || opop->subitem_reference_name == nullptr) {
2967  return subitem_refname == opop->subitem_reference_name ? opop : nullptr;
2968  }
2969  return (subitem_refname != nullptr && opop->subitem_reference_name != nullptr &&
2970  STREQ(subitem_refname, opop->subitem_reference_name)) ?
2971  opop :
2972  nullptr;
2973  }
2974 
2975  if (subitem_refname != nullptr) {
2976  opop = static_cast<IDOverrideLibraryPropertyOperation *>(
2977  BLI_findstring_ptr(&override_property->operations,
2978  subitem_refname,
2979  offsetof(IDOverrideLibraryPropertyOperation, subitem_reference_name)));
2980 
2981  if (opop == nullptr) {
2982  return nullptr;
2983  }
2984 
2985  if (subitem_locname == nullptr || opop->subitem_local_name == nullptr) {
2986  return subitem_locname == opop->subitem_local_name ? opop : nullptr;
2987  }
2988  return (subitem_locname != nullptr && opop->subitem_local_name != nullptr &&
2989  STREQ(subitem_locname, opop->subitem_local_name)) ?
2990  opop :
2991  nullptr;
2992  }
2993 
2995  &override_property->operations,
2996  &subitem_locindex,
2997  sizeof(subitem_locindex),
2998  offsetof(IDOverrideLibraryPropertyOperation, subitem_local_index))))) {
2999  return ELEM(subitem_refindex, -1, opop->subitem_reference_index) ? opop : nullptr;
3000  }
3001 
3003  &override_property->operations,
3004  &subitem_refindex,
3005  sizeof(subitem_refindex),
3006  offsetof(IDOverrideLibraryPropertyOperation, subitem_reference_index))))) {
3007  return ELEM(subitem_locindex, -1, opop->subitem_local_index) ? opop : nullptr;
3008  }
3009 
3010  /* `index == -1` means all indices, that is a valid fallback in case we requested specific index.
3011  */
3012  if (!strict && (subitem_locindex != subitem_defindex) &&
3014  &override_property->operations,
3015  &subitem_defindex,
3016  sizeof(subitem_defindex),
3017  offsetof(IDOverrideLibraryPropertyOperation, subitem_local_index))))) {
3018  if (r_strict) {
3019  *r_strict = false;
3020  }
3021  return opop;
3022  }
3023 
3024  return nullptr;
3025 }
3026 
3028  IDOverrideLibraryProperty *override_property,
3029  const short operation,
3030  const char *subitem_refname,
3031  const char *subitem_locname,
3032  const int subitem_refindex,
3033  const int subitem_locindex,
3034  const bool strict,
3035  bool *r_strict,
3036  bool *r_created)
3037 {
3039  override_property,
3040  subitem_refname,
3041  subitem_locname,
3042  subitem_refindex,
3043  subitem_locindex,
3044  strict,
3045  r_strict);
3046 
3047  if (opop == nullptr) {
3048  opop = MEM_cnew<IDOverrideLibraryPropertyOperation>(__func__);
3049  opop->operation = operation;
3050  if (subitem_locname) {
3051  opop->subitem_local_name = BLI_strdup(subitem_locname);
3052  }
3053  if (subitem_refname) {
3054  opop->subitem_reference_name = BLI_strdup(subitem_refname);
3055  }
3056  opop->subitem_local_index = subitem_locindex;
3057  opop->subitem_reference_index = subitem_refindex;
3058 
3059  BLI_addtail(&override_property->operations, opop);
3060 
3061  if (r_created) {
3062  *r_created = true;
3063  }
3064  }
3065  else if (r_created) {
3066  *r_created = false;
3067  }
3068 
3069  return opop;
3070 }
3071 
3074 {
3075  if (opop_src->subitem_reference_name) {
3077  }
3078  if (opop_src->subitem_local_name) {
3079  opop_dst->subitem_local_name = BLI_strdup(opop_src->subitem_local_name);
3080  }
3081 }
3082 
3084 {
3085  if (opop->subitem_reference_name) {
3087  }
3088  if (opop->subitem_local_name) {
3090  }
3091 }
3092 
3094  IDOverrideLibraryProperty *override_property,
3095  IDOverrideLibraryPropertyOperation *override_property_operation)
3096 {
3097  lib_override_library_property_operation_clear(override_property_operation);
3098  BLI_freelinkN(&override_property->operations, override_property_operation);
3099 }
3100 
3102  IDOverrideLibraryPropertyOperation *override_property_operation,
3103  PointerRNA *ptr_dst,
3104  PointerRNA *ptr_src,
3105  PointerRNA *ptr_storage,
3106  PropertyRNA *prop_dst,
3107  PropertyRNA *prop_src,
3108  PropertyRNA *prop_storage)
3109 {
3110  switch (override_property_operation->operation) {
3112  return true;
3118  if (ptr_storage == nullptr || ptr_storage->data == nullptr || prop_storage == nullptr) {
3119  BLI_assert_msg(0, "Missing data to apply differential override operation.");
3120  return false;
3121  }
3128  if ((ptr_dst == nullptr || ptr_dst->data == nullptr || prop_dst == nullptr) ||
3129  (ptr_src == nullptr || ptr_src->data == nullptr || prop_src == nullptr)) {
3130  BLI_assert_msg(0, "Missing data to apply override operation.");
3131  return false;
3132  }
3133  }
3134 
3135  return true;
3136 }
3137 
3139 {
3140  if (!ID_IS_OVERRIDE_LIBRARY(id)) {
3141  return;
3142  }
3143 
3144  ID *liboverride_id = id;
3145  IDOverrideLibrary *liboverride = id->override_library;
3147  liboverride = BKE_lib_override_library_get(bmain, id, nullptr, &liboverride_id);
3148  if (!liboverride) {
3149  /* Happens in case the given ID is a liboverride-embedded one (actual embedded ID like
3150  * NodeTree or master collection, or shapekeys), used by a totally not-liboverride owner ID.
3151  * Just clear the relevant ID flag.
3152  */
3153  id->flag &= ~LIB_EMBEDDED_DATA_LIB_OVERRIDE;
3154  return;
3155  }
3156  }
3157  BLI_assert(liboverride);
3158 
3159  /* NOTE: In code deleting liboverride data below, #BKE_lib_override_library_make_local is used
3160  * instead of directly calling #BKE_lib_override_library_free, because the former also handles
3161  * properly 'liboverride embedded' IDs, like root nodetrees, or shapekeys. */
3162 
3163  if (liboverride->reference == nullptr) {
3164  /* This (probably) used to be a template ID, could be linked or local, not an override. */
3165  BKE_reportf(reports,
3166  RPT_WARNING,
3167  "Library override templates have been removed: removing all override data from "
3168  "the data-block '%s'",
3169  liboverride_id->name);
3170  BKE_lib_override_library_make_local(liboverride_id);
3171  return;
3172  }
3173  if (liboverride->reference == liboverride_id) {
3174  /* Very serious data corruption, cannot do much about it besides removing the liboverride data.
3175  */
3176  BKE_reportf(reports,
3177  RPT_ERROR,
3178  "Data corruption: data-block '%s' is using itself as library override reference, "
3179  "removing all override data",
3180  liboverride_id->name);
3181  BKE_lib_override_library_make_local(liboverride_id);
3182  return;
3183  }
3184  if (!ID_IS_LINKED(liboverride->reference)) {
3185  /* Very serious data corruption, cannot do much about it besides removing the liboverride data.
3186  */
3187  BKE_reportf(reports,
3188  RPT_ERROR,
3189  "Data corruption: data-block '%s' is using another local data-block ('%s') as "
3190  "library override reference, removing all override data",
3191  liboverride_id->name,
3192  liboverride->reference->name);
3193  BKE_lib_override_library_make_local(liboverride_id);
3194  return;
3195  }
3196 }
3197 
3199 {
3200  ID *id;
3201 
3202  FOREACH_MAIN_ID_BEGIN (bmain, id) {
3203  if (ID_IS_OVERRIDE_LIBRARY(id)) {
3204  BKE_lib_override_library_validate(bmain, id, reports);
3205  }
3206  }
3208 }
3209 
3211 {
3213 
3214  ID *reference = local->override_library->reference;
3215 
3216  if (reference == nullptr) {
3217  /* This is an override template, local status is always OK! */
3218  return true;
3219  }
3220 
3221  BLI_assert(GS(local->name) == GS(reference->name));
3222 
3223  if (GS(local->name) == ID_OB) {
3224  /* Our beloved pose's bone cross-data pointers. Usually, depsgraph evaluation would
3225  * ensure this is valid, but in some situations (like hidden collections etc.) this won't
3226  * be the case, so we need to take care of this ourselves. */
3227  Object *ob_local = reinterpret_cast<Object *>(local);
3228  if (ob_local->type == OB_ARMATURE) {
3229  Object *ob_reference = reinterpret_cast<Object *>(local->override_library->reference);
3230  BLI_assert(ob_local->data != nullptr);
3231  BLI_assert(ob_reference->data != nullptr);
3232  BKE_pose_ensure(bmain, ob_local, static_cast<bArmature *>(ob_local->data), true);
3233  BKE_pose_ensure(bmain, ob_reference, static_cast<bArmature *>(ob_reference->data), true);
3234  }
3235  }
3236 
3237  /* Note that reference is assumed always valid, caller has to ensure that itself. */
3238 
3239  PointerRNA rnaptr_local, rnaptr_reference;
3240  RNA_id_pointer_create(local, &rnaptr_local);
3241  RNA_id_pointer_create(reference, &rnaptr_reference);
3242 
3244  bmain,
3245  &rnaptr_local,
3246  &rnaptr_reference,
3247  nullptr,
3248  0,
3249  local->override_library,
3252  nullptr)) {
3254  return false;
3255  }
3256 
3257  return true;
3258 }
3259 
3261 {
3263 
3264  ID *reference = local->override_library->reference;
3265 
3266  if (reference == nullptr) {
3267  /* This is an override template, reference is virtual, so its status is always OK! */
3268  return true;
3269  }
3270 
3271  BLI_assert(GS(local->name) == GS(reference->name));
3272 
3273  if (reference->override_library && (reference->tag & LIB_TAG_OVERRIDE_LIBRARY_REFOK) == 0) {
3274  if (!BKE_lib_override_library_status_check_reference(bmain, reference)) {
3275  /* If reference is also an override of another data-block, and its status is not OK,
3276  * then this override is not OK either.
3277  * Note that this should only happen when reloading libraries. */
3279  return false;
3280  }
3281  }
3282 
3283  if (GS(local->name) == ID_OB) {
3284  /* Our beloved pose's bone cross-data pointers. Usually, depsgraph evaluation would
3285  * ensure this is valid, but in some situations (like hidden collections etc.) this won't
3286  * be the case, so we need to take care of this ourselves. */
3287  Object *ob_local = reinterpret_cast<Object *>(local);
3288  if (ob_local->type == OB_ARMATURE) {
3289  Object *ob_reference = reinterpret_cast<Object *>(local->override_library->reference);
3290  BLI_assert(ob_local->data != nullptr);
3291  BLI_assert(ob_reference->data != nullptr);
3292  BKE_pose_ensure(bmain, ob_local, static_cast<bArmature *>(ob_local->data), true);
3293  BKE_pose_ensure(bmain, ob_reference, static_cast<bArmature *>(ob_reference->data), true);
3294  }
3295  }
3296 
3297  PointerRNA rnaptr_local, rnaptr_reference;
3298  RNA_id_pointer_create(local, &rnaptr_local);
3299  RNA_id_pointer_create(reference, &rnaptr_reference);
3300 
3301  if (!RNA_struct_override_matches(bmain,
3302  &rnaptr_local,
3303  &rnaptr_reference,
3304  nullptr,
3305  0,
3306  local->override_library,
3308  nullptr)) {
3310  return false;
3311  }
3312 
3313  return true;
3314 }
3315 
3317 {
3318  BLI_assert(!ID_IS_LINKED(local));
3319  BLI_assert(local->override_library != nullptr);
3320  const bool is_template = (local->override_library->reference == nullptr);
3321  bool created = false;
3322 
3323  if (!is_template) {
3324  /* Do not attempt to generate overriding rules from an empty place-holder generated by link
3325  * code when it cannot find the actual library/ID. Much better to keep the local data-block as
3326  * is in the file in that case, until broken lib is fixed. */
3327  if (ID_MISSING(local->override_library->reference)) {
3328  return created;
3329  }
3330 
3331  if (GS(local->name) == ID_OB) {
3332  /* Our beloved pose's bone cross-data pointers. Usually, depsgraph evaluation would
3333  * ensure this is valid, but in some situations (like hidden collections etc.) this won't
3334  * be the case, so we need to take care of this ourselves. */
3335  Object *ob_local = reinterpret_cast<Object *>(local);
3336  if (ob_local->type == OB_ARMATURE) {
3337  Object *ob_reference = reinterpret_cast<Object *>(local->override_library->reference);
3338  BLI_assert(ob_local->data != nullptr);
3339  BLI_assert(ob_reference->data != nullptr);
3340  BKE_pose_ensure(bmain, ob_local, static_cast<bArmature *>(ob_local->data), true);
3341  BKE_pose_ensure(bmain, ob_reference, static_cast<bArmature *>(ob_reference->data), true);
3342  }
3343  }
3344 
3345  PointerRNA rnaptr_local, rnaptr_reference;
3346  RNA_id_pointer_create(local, &rnaptr_local);
3347  RNA_id_pointer_create(local->override_library->reference, &rnaptr_reference);
3348 
3351  bmain,
3352  &rnaptr_local,
3353  &rnaptr_reference,
3354  nullptr,
3355  0,
3356  local->override_library,
3358  &report_flags);
3359 
3360  if (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) {
3361  created = true;
3362  }
3363 
3364  if (report_flags & RNA_OVERRIDE_MATCH_RESULT_RESTORED) {
3365  CLOG_INFO(&LOG, 2, "We did restore some properties of %s from its reference", local->name);
3366  }
3367  if (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) {
3368  CLOG_INFO(&LOG, 2, "We did generate library override rules for %s", local->name);
3369  }
3370  else {
3371  CLOG_INFO(&LOG, 2, "No new library override rules for %s", local->name);
3372  }
3373  }
3374  return created;
3375 }
3376 
3379  bool changed;
3380 };
3381 
3382 static void lib_override_library_operations_create_cb(TaskPool *__restrict pool, void *taskdata)
3383 {
3384  LibOverrideOpCreateData *create_data = static_cast<LibOverrideOpCreateData *>(
3386  ID *id = static_cast<ID *>(taskdata);
3387 
3388  if (BKE_lib_override_library_operations_create(create_data->bmain, id)) {
3389  /* Technically no need for atomic, all jobs write the same value and we only care if one did
3390  * it. But play safe and avoid implicit assumptions. */
3391  atomic_fetch_and_or_uint8(reinterpret_cast<uint8_t *>(&create_data->changed), true);
3392  }
3393 }
3394 
3395 bool BKE_lib_override_library_main_operations_create(Main *bmain, const bool force_auto)
3396 {
3397  ID *id;
3398 
3399 #ifdef DEBUG_OVERRIDE_TIMEIT
3401 #endif
3402 
3403  /* When force-auto is set, we also remove all unused existing override properties & operations.
3404  */
3405  if (force_auto) {
3407  }
3408 
3409  /* Usual pose bones issue, need to be done outside of the threaded process or we may run into
3410  * concurrency issues here.
3411  * Note that calling #BKE_pose_ensure again in thread in
3412  * #BKE_lib_override_library_operations_create is not a problem then. */
3413  LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
3414  if (ob->type == OB_ARMATURE) {
3415  BLI_assert(ob->data != nullptr);
3416  BKE_pose_ensure(bmain, ob, static_cast<bArmature *>(ob->data), true);
3417  }
3418  }
3419 
3420  LibOverrideOpCreateData create_pool_data{};
3421  create_pool_data.bmain = bmain;
3422  create_pool_data.changed = false;
3424 
3425  FOREACH_MAIN_ID_BEGIN (bmain, id) {
3426  if (!ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
3427  (force_auto || (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH))) {
3428  /* Usual issue with pose, it's quiet rare but sometimes they may not be up to date when this
3429  * function is called. */
3430  if (GS(id->name) == ID_OB) {
3431  Object *ob = reinterpret_cast<Object *>(id);
3432  if (ob->type == OB_ARMATURE) {
3433  BLI_assert(ob->data != nullptr);
3434  BKE_pose_ensure(bmain, ob, static_cast<bArmature *>(ob->data), true);
3435  }
3436  }
3437  /* Only check overrides if we do have the real reference data available, and not some empty
3438  * 'placeholder' for missing data (broken links). */
3439  if ((id->override_library->reference->tag & LIB_TAG_MISSING) == 0) {
3442  }
3443  else {
3446  }
3447  }
3448  else {
3449  /* Clear 'unused' tag for un-processed IDs, otherwise e.g. linked overrides will loose their
3450  * list of overridden properties. */
3453  }
3455  }
3457 
3459 
3461 
3462  if (force_auto) {
3464  }
3465 
3466 #ifdef DEBUG_OVERRIDE_TIMEIT
3468 #endif
3469 
3470  return create_pool_data.changed;
3471 }
3472 
3474  ID *id_root,
3475  const bool do_reset_system_override)
3476 {
3477  bool was_op_deleted = false;
3478 
3479  if (do_reset_system_override) {
3481  }
3482 
3485  bool do_op_delete = true;
3486  const bool is_collection = op->rna_prop_type == PROP_COLLECTION;
3487  if (is_collection || op->rna_prop_type == PROP_POINTER) {
3488  PointerRNA ptr_root, ptr_root_lib, ptr, ptr_lib;
3489  PropertyRNA *prop, *prop_lib;
3490 
3491  RNA_pointer_create(id_root, &RNA_ID, id_root, &ptr_root);
3493  &RNA_ID,
3494  id_root->override_library->reference,
3495  &ptr_root_lib);
3496 
3497  bool prop_exists = RNA_path_resolve_property(&ptr_root, op->rna_path, &ptr, &prop);
3498  if (prop_exists) {
3499  prop_exists = RNA_path_resolve_property(&ptr_root_lib, op->rna_path, &ptr_lib, &prop_lib);
3500 
3501  if (prop_exists) {
3503  BLI_assert(RNA_property_type(prop) == RNA_property_type(prop_lib));
3504  if (is_collection) {
3506  ptr_lib.type = RNA_property_pointer_type(&ptr_lib, prop_lib);
3507  }
3508  else {
3509  ptr = RNA_property_pointer_get(&ptr, prop);
3510  ptr_lib = RNA_property_pointer_get(&ptr_lib, prop_lib);
3511  }
3512  if (ptr.owner_id != nullptr && ptr_lib.owner_id != nullptr) {
3513  BLI_assert(ptr.type == ptr_lib.type);
3514  do_op_delete = !(RNA_struct_is_ID(ptr.type) &&
3515  ptr.owner_id->override_library != nullptr &&
3517  }
3518  }
3519  }
3520  }
3521 
3522  if (do_op_delete) {
3524  was_op_deleted = true;
3525  }
3526  }
3527 
3528  if (was_op_deleted) {
3531  id_root->override_library);
3532  override_runtime->tag |= IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD;
3533  }
3534 
3535  return was_op_deleted;
3536 }
3537 
3539  ID *id_root,
3540  const bool do_reset_system_override)
3541 {
3542  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
3543  return;
3544  }
3545 
3546  if (lib_override_library_id_reset_do(bmain, id_root, do_reset_system_override)) {
3547  if (id_root->override_library->runtime != nullptr &&
3549  0) {
3550  BKE_lib_override_library_update(bmain, id_root);
3552  }
3553  }
3554 }
3555 
3557  ID *id_root,
3558  const bool do_reset_system_override)
3559 {
3560  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
3561  return;
3562  }
3563 
3564  void **entry_vp = BLI_ghash_lookup_p(bmain->relations->relations_from_pointers, id_root);
3565  if (entry_vp == nullptr) {
3566  /* This ID is not used by nor using any other ID. */
3567  lib_override_library_id_reset_do(bmain, id_root, do_reset_system_override);
3568  return;
3569  }
3570 
3571  MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(*entry_vp);
3573  /* This ID has already been processed. */
3574  return;
3575  }
3576 
3577  lib_override_library_id_reset_do(bmain, id_root, do_reset_system_override);
3578 
3579  /* This way we won't process again that ID, should we encounter it again through another
3580  * relationship hierarchy. */
3582 
3583  for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != nullptr;
3584  to_id_entry = to_id_entry->next) {
3585  if ((to_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
3586  /* Never consider non-overridable relationships ('from', 'parents', 'owner' etc. pointers) as
3587  * actual dependencies. */
3588  continue;
3589  }
3590  /* We only consider IDs from the same library. */
3591  if (*to_id_entry->id_pointer.to != nullptr) {
3592  ID *to_id = *to_id_entry->id_pointer.to;
3593  if (to_id->override_library != nullptr) {
3594  lib_override_library_id_hierarchy_recursive_reset(bmain, to_id, do_reset_system_override);
3595  }
3596  }
3597  }
3598 }
3599 
3601  ID *id_root,
3602  const bool do_reset_system_override)
3603 {
3604  BKE_main_relations_create(bmain, 0);
3605 
3606  lib_override_library_id_hierarchy_recursive_reset(bmain, id_root, do_reset_system_override);
3607 
3608  BKE_main_relations_free(bmain);
3609 
3610  ID *id;
3611  FOREACH_MAIN_ID_BEGIN (bmain, id) {
3612  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) || id->override_library->runtime == nullptr ||
3614  continue;
3615  }
3617  id->override_library->runtime->tag &= ~IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD;
3618  }
3620 }
3621 
3623  const short tag,
3624  const bool do_set)
3625 {
3626  if (override_property != nullptr) {
3627  if (do_set) {
3628  override_property->tag |= tag;
3629  }
3630  else {
3631  override_property->tag &= ~tag;
3632  }
3633 
3634  LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &override_property->operations) {
3635  if (do_set) {
3636  opop->tag |= tag;
3637  }
3638  else {
3639  opop->tag &= ~tag;
3640  }
3641  }
3642  }
3643 }
3644 
3646  const short tag,
3647  const bool do_set)
3648 {
3649  if (override != nullptr) {
3650  LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &override->properties) {
3651  BKE_lib_override_library_operations_tag(op, tag, do_set);
3652  }
3653  }
3654 }
3655 
3656 void BKE_lib_override_library_main_tag(Main *bmain, const short tag, const bool do_set)
3657 {
3658  ID *id;
3659 
3660  FOREACH_MAIN_ID_BEGIN (bmain, id) {
3661  if (ID_IS_OVERRIDE_LIBRARY(id)) {
3663  }
3664  }
3666 }
3667 
3669 {
3670  if (ID_IS_OVERRIDE_LIBRARY_REAL(local)) {
3673  if (op->tag & IDOVERRIDE_LIBRARY_TAG_UNUSED) {
3675  }
3676  else {
3678  if (opop->tag & IDOVERRIDE_LIBRARY_TAG_UNUSED) {
3680  }
3681  }
3682  }
3683  }
3684  }
3685 }
3686 
3688 {
3689  ID *id;
3690 
3691  FOREACH_MAIN_ID_BEGIN (bmain, id) {
3692  if (ID_IS_OVERRIDE_LIBRARY(id)) {
3694  }
3695  }
3697 }
3698 
3699 static void lib_override_id_swap(Main *bmain, ID *id_local, ID *id_temp)
3700 {
3701  BKE_lib_id_swap(bmain, id_local, id_temp);
3702  /* We need to keep these tags from temp ID into orig one.
3703  * ID swap does not swap most of ID data itself. */
3704  id_local->tag |= (id_temp->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC);
3705 }
3706 
3708 {
3709  if (!ID_IS_OVERRIDE_LIBRARY_REAL(local)) {
3710  return;
3711  }
3712 
3713  /* Do not attempt to apply overriding rules over an empty place-holder generated by link code
3714  * when it cannot find the actual library/ID. Much better to keep the local data-block as loaded
3715  * from the file in that case, until broken lib is fixed. */
3716  if (ID_MISSING(local->override_library->reference)) {
3717  return;
3718  }
3719 
3720  /* Recursively do 'ancestor' overrides first, if any. */
3724  }
3725 
3726  /* We want to avoid having to remap here, however creating up-to-date override is much simpler
3727  * if based on reference than on current override.
3728  * So we work on temp copy of reference, and 'swap' its content with local. */
3729 
3730  /* XXX We need a way to get off-Main copies of IDs (similar to localized mats/texts/ etc.)!
3731  * However, this is whole bunch of code work in itself, so for now plain stupid ID copy
3732  * will do, as inefficient as it is. :/
3733  * Actually, maybe not! Since we are swapping with original ID's local content, we want to
3734  * keep user-count in correct state when freeing tmp_id
3735  * (and that user-counts of IDs used by 'new' local data also remain correct). */
3736  /* This would imply change in handling of user-count all over RNA
3737  * (and possibly all over Blender code).
3738  * Not impossible to do, but would rather see first if extra useless usual user handling
3739  * is actually a (performances) issue here. */
3740 
3741  ID *tmp_id = BKE_id_copy_ex(bmain,
3742  local->override_library->reference,
3743  nullptr,
3745 
3746  if (tmp_id == nullptr) {
3747  return;
3748  }
3749 
3750  /* Remove the pair (idname, lib) of this temp id from the name map. */
3751  BKE_main_namemap_remove_name(bmain, tmp_id, tmp_id->name + 2);
3752 
3753  tmp_id->lib = local->lib;
3754 
3755  /* This ID name is problematic, since it is an 'rna name property' it should not be editable or
3756  * different from reference linked ID. But local ID names need to be unique in a given type
3757  * list of Main, so we cannot always keep it identical, which is why we need this special
3758  * manual handling here. */
3759  BLI_strncpy(tmp_id->name, local->name, sizeof(tmp_id->name));
3760 
3761  /* Those ugly loop-back pointers again. Luckily we only need to deal with the shape keys here,
3762  * collections' parents are fully runtime and reconstructed later. */
3763  Key *local_key = BKE_key_from_id(local);
3764  Key *tmp_key = BKE_key_from_id(tmp_id);
3765  if (local_key != nullptr && tmp_key != nullptr) {
3766  tmp_key->id.flag |= (local_key->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE);
3767  BKE_main_namemap_remove_name(bmain, &tmp_key->id, tmp_key->id.name + 2);
3768  tmp_key->id.lib = local_key->id.lib;
3769  BLI_strncpy(tmp_key->id.name, local_key->id.name, sizeof(tmp_key->id.name));
3770  }
3771 
3772  PointerRNA rnaptr_src, rnaptr_dst, rnaptr_storage_stack, *rnaptr_storage = nullptr;
3773  RNA_id_pointer_create(local, &rnaptr_src);
3774  RNA_id_pointer_create(tmp_id, &rnaptr_dst);
3775  if (local->override_library->storage) {
3776  rnaptr_storage = &rnaptr_storage_stack;
3777  RNA_id_pointer_create(local->override_library->storage, rnaptr_storage);
3778  }
3779 
3781  &rnaptr_dst,
3782  &rnaptr_src,
3783  rnaptr_storage,
3784  local->override_library,
3786 
3788 
3789  /* This also transfers all pointers (memory) owned by local to tmp_id, and vice-versa.
3790  * So when we'll free tmp_id, we'll actually free old, outdated data from local. */
3791  lib_override_id_swap(bmain, local, tmp_id);
3792 
3793  if (local_key != nullptr && tmp_key != nullptr) {
3794  /* This is some kind of hard-coded 'always enforced override'. */
3795  lib_override_id_swap(bmain, &local_key->id, &tmp_key->id);
3796  tmp_key->id.flag |= (local_key->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE);
3797  /* The swap of local and tmp_id inverted those pointers, we need to redefine proper
3798  * relationships. */
3799  *BKE_key_from_id_p(local) = local_key;
3800  *BKE_key_from_id_p(tmp_id) = tmp_key;
3801  local_key->from = local;
3802  tmp_key->from = tmp_id;
3803  }
3804 
3805  /* Again, horribly inefficient in our case, we need something off-Main
3806  * (aka more generic nolib copy/free stuff).
3807  * NOTE: Do not remove this tmp_id's name from the namemap here, since this name actually still
3808  * exists in `bmain`. */
3810 
3811  if (GS(local->name) == ID_AR) {
3812  /* Fun times again, thanks to bone pointers in pose data of objects. We keep same ID addresses,
3813  * but internal data has changed for sure, so we need to invalidate pose-bones caches. */
3814  LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
3815  if (ob->pose != nullptr && ob->data == local) {
3816  BLI_assert(ob->type == OB_ARMATURE);
3817  ob->pose->flag |= POSE_RECALC;
3818  /* We need to clear pose bone pointers immediately, some code may access those before pose
3819  * is actually recomputed, which can lead to segfault. */
3820  BKE_pose_clear_pointers(ob->pose);
3821  }
3822  }
3823  }
3824 
3825  if (local->override_library->storage) {
3826  /* We know this data-block is not used anywhere besides local->override->storage. */
3827  /* XXX For until we get fully shadow copies, we still need to ensure storage releases
3828  * its usage of any ID pointers it may have. */
3830  local->override_library->storage = nullptr;
3831  }
3832 
3834 
3835  /* NOTE: Since we reload full content from linked ID here, potentially from edited local
3836  * override, we do not really have a way to know *what* is changed, so we need to rely on the
3837  * massive destruction weapon of `ID_RECALC_ALL` here. */
3838  DEG_id_tag_update_ex(bmain, local, ID_RECALC_ALL);
3839  /* For same reason as above, also assume that the relationships between IDs changed. */
3840  DEG_relations_tag_update(bmain);
3841 }
3842 
3844 {
3845  ID *id;
3846 
3847  /* This temporary swap of G_MAIN is rather ugly,
3848  * but necessary to avoid asserts checks in some RNA assignment functions,
3849  * since those always use on G_MAIN when they need access to a Main database. */
3850  Main *orig_gmain = G_MAIN;
3851  G_MAIN = bmain;
3852 
3854 
3855  FOREACH_MAIN_ID_BEGIN (bmain, id) {
3856  if (id->override_library != nullptr) {
3858  }
3859  }
3861 
3863 
3864  G_MAIN = orig_gmain;
3865 }
3866 
3868 {
3869  /* The only strong known case currently are objects used by override collections. */
3870  /* TODO: There are most likely other cases... This may need to be addressed in a better way at
3871  * some point. */
3872  if (GS(id->name) != ID_OB) {
3873  return true;
3874  }
3875  Object *ob = reinterpret_cast<Object *>(id);
3876  LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
3877  if (!ID_IS_OVERRIDE_LIBRARY(collection)) {
3878  continue;
3879  }
3880  if (BKE_collection_has_object(collection, ob)) {
3881  return false;
3882  }
3883  }
3884  return true;
3885 }
3886 
3904 {
3905  return BKE_main_new();
3906 }
3907 
3909  OverrideLibraryStorage *override_storage,
3910  ID *local)
3911 {
3913  /* This is actually purely local data with an override template, or one of those embedded IDs
3914  * (root node trees, master collections or shape-keys) that cannot have their own override.
3915  * Nothing to do here! */
3916  return nullptr;
3917  }
3918 
3920  BLI_assert(override_storage != nullptr);
3921  UNUSED_VARS_NDEBUG(override_storage);
3922 
3923  /* Forcefully ensure we know about all needed override operations. */
3925 
3926  ID *storage_id;
3927 #ifdef DEBUG_OVERRIDE_TIMEIT
3929 #endif
3930 
3931  /* This is fully disabled for now, as it generated very hard to solve issues with Collections and
3932  * how they reference each-other in their parents/children relations.
3933  * Core of the issue is creating and storing those copies in a separate Main, while collection
3934  * copy code re-assign blindly parents/children, even if they do not belong to the same Main.
3935  * One solution could be to implement special flag as discussed below, and prevent any
3936  * other-ID-reference creation/update in that case (since no differential operation is expected
3937  * to involve those anyway). */
3938 #if 0
3939  /* XXX TODO: We may also want a specialized handling of things here too, to avoid copying heavy
3940  * never-overridable data (like Mesh geometry etc.)? And also maybe avoid lib
3941  * reference-counting completely (shallow copy). */
3942  /* This would imply change in handling of user-count all over RNA
3943  * (and possibly all over Blender code).
3944  * Not impossible to do, but would rather see first is extra useless usual user handling is
3945  * actually a (performances) issue here, before doing it. */
3946  storage_id = BKE_id_copy(reinterpret_cast<Main *>(override_storage), local);
3947 
3948  if (storage_id != nullptr) {
3949  PointerRNA rnaptr_reference, rnaptr_final, rnaptr_storage;
3950  RNA_id_pointer_create(local->override_library->reference, &rnaptr_reference);
3951  RNA_id_pointer_create(local, &rnaptr_final);
3952  RNA_id_pointer_create(storage_id, &rnaptr_storage);
3953 
3955  bmain, &rnaptr_final, &rnaptr_reference, &rnaptr_storage, local->override_library)) {
3956  BKE_id_free_ex(override_storage, storage_id, LIB_ID_FREE_NO_UI_USER, true);
3957  storage_id = nullptr;
3958  }
3959  }
3960 #else
3961  storage_id = nullptr;
3962 #endif
3963 
3964  local->override_library->storage = storage_id;
3965 
3966 #ifdef DEBUG_OVERRIDE_TIMEIT
3968 #endif
3969  return storage_id;
3970 }
3971 
3973  OverrideLibraryStorage *UNUSED(override_storage), ID *local)
3974 {
3976 
3977  /* Nothing else to do here really, we need to keep all temp override storage data-blocks in
3978  * memory until whole file is written anyway (otherwise we'd get mem pointers overlap). */
3979  local->override_library->storage = nullptr;
3980 }
3981 
3983 {
3984  /* We cannot just call BKE_main_free(override_storage), not until we have option to make
3985  * 'ghost' copies of IDs without increasing usercount of used data-blocks. */
3986  ID *id;
3987 
3988  FOREACH_MAIN_ID_BEGIN (override_storage, id) {
3989  BKE_id_free_ex(override_storage, id, LIB_ID_FREE_NO_UI_USER, true);
3990  }
3992 
3993  BKE_main_free(override_storage);
3994 }
struct AnimData * BKE_animdata_from_id(const struct ID *id)
void BKE_pose_ensure(struct Main *bmain, struct Object *ob, struct bArmature *arm, bool do_id_user)
Definition: armature.c:2419
void BKE_pose_clear_pointers(struct bPose *pose)
Definition: armature.c:2324
struct Collection * BKE_collection_add(struct Main *bmain, struct Collection *parent, const char *name)
Definition: collection.c:425
void BKE_collection_object_add_from(struct Main *bmain, struct Scene *scene, struct Object *ob_src, struct Object *ob_dst)
Definition: collection.c:1148
bool BKE_collection_object_add(struct Main *bmain, struct Collection *collection, struct Object *ob)
Definition: collection.c:1125
struct GSet * BKE_scene_objects_as_gset(struct Scene *scene, struct GSet *objects_gset)
Definition: collection.c:2086
void BKE_collection_add_from_object(struct Main *bmain, struct Scene *scene, const struct Object *ob_src, struct Collection *collection_dst)
bool BKE_collection_has_object(struct Collection *collection, const struct Object *ob)
bool BKE_collection_has_collection(const struct Collection *parent, const struct Collection *collection)
void BKE_collection_add_from_collection(struct Main *bmain, struct Scene *scene, struct Collection *collection_src, struct Collection *collection_dst)
Definition: collection.c:455
bool BKE_collection_is_in_scene(struct Collection *collection)
Definition: collection.c:1385
bool BKE_collection_is_empty(const struct Collection *collection)
bool BKE_collection_delete(struct Main *bmain, struct Collection *collection, bool hierarchy)
Definition: collection.c:495
struct FCurve * BKE_animadata_fcurve_find_by_rna_path(struct AnimData *animdata, const char *rna_path, const int rna_index, struct bAction **r_action, bool *r_driven)
Definition: fcurve.c:339
#define G_MAIN
Definition: BKE_global.h:267
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
struct Key ** BKE_key_from_id_p(struct ID *id)
Definition: key.c:1758
void BKE_main_collection_sync(const struct Main *bmain)
bool BKE_view_layer_has_collection(const struct ViewLayer *view_layer, const struct Collection *collection)
void BKE_layer_collection_resync_allow(void)
Definition: layer.c:766
struct Base * BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob)
Definition: layer.c:379
void BKE_layer_collection_resync_forbid(void)
Definition: layer.c:761
void BKE_main_collection_sync_remap(const struct Main *bmain)
struct ID * BKE_id_copy(struct Main *bmain, const struct ID *id)
@ LIB_ID_COPY_NO_LIB_OVERRIDE
Definition: BKE_lib_id.h:158
@ LIB_ID_COPY_NO_LIB_OVERRIDE_LOCAL_DATA_FLAG
Definition: BKE_lib_id.h:161
@ LIB_ID_CREATE_NO_MAIN
Definition: BKE_lib_id.h:122
@ LIB_ID_COPY_DEFAULT
Definition: BKE_lib_id.h:181
void BKE_libblock_management_main_add(struct Main *bmain, void *idv)
Definition: lib_id.c:826
void BKE_main_id_newptr_and_tag_clear(struct Main *bmain)
Definition: lib_id.c:1465
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, int flag)
void BKE_main_id_tag_all(struct Main *mainvar, int tag, bool value)
Definition: lib_id.c:930
void id_us_min(struct ID *id)
Definition: lib_id.c:313
void id_fake_user_set(struct ID *id)
Definition: lib_id.c:343
@ LIB_ID_FREE_NO_UI_USER
Definition: BKE_lib_id.h:256
@ LIB_ID_FREE_NO_NAMEMAP_REMOVE
Definition: BKE_lib_id.h:258
void BKE_id_free(struct Main *bmain, void *idv)
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
void BKE_id_free_ex(struct Main *bmain, void *idv, int flag, bool use_flag_from_idtag)
Definition: lib_id_delete.c:82
void * BKE_id_new(struct Main *bmain, short type, const char *name)
Definition: lib_id.c:1159
void BKE_id_delete(struct Main *bmain, void *idv) ATTR_NONNULL()
size_t BKE_id_multi_tagged_delete(struct Main *bmain) ATTR_NONNULL()
void BKE_lib_id_swap(struct Main *bmain, struct ID *id_a, struct ID *id_b)
Definition: lib_id.c:752
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_READONLY
@ IDWALK_CB_LOOPBACK
Definition: BKE_lib_query.h:54
@ IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE
Definition: BKE_lib_query.h:60
@ IDWALK_RET_STOP_ITER
Definition: BKE_lib_query.h:85
@ IDWALK_RET_NOP
Definition: BKE_lib_query.h:83
@ ID_REMAP_SKIP_OVERRIDE_LIBRARY
Definition: BKE_lib_remap.h:59
@ ID_REMAP_FORCE_USER_REFCOUNT
Definition: BKE_lib_remap.h:74
@ ID_REMAP_SKIP_INDIRECT_USAGE
Definition: BKE_lib_remap.h:36
@ ID_REMAP_FORCE_NEVER_NULL_USAGE
Definition: BKE_lib_remap.h:57
void void BKE_libblock_remap(struct Main *bmain, void *old_idv, void *new_idv, short remap_flags) ATTR_NONNULL(1
void BKE_id_remapper_add(struct IDRemapper *id_remapper, struct ID *old_id, struct ID *new_id)
@ ID_REMAP_TYPE_REMAP
Definition: BKE_lib_remap.h:85
@ ID_REMAP_TYPE_CLEANUP
Definition: BKE_lib_remap.h:88
void BKE_libblock_relink_ex(struct Main *bmain, void *idv, void *old_idv, void *new_idv, short remap_flags) ATTR_NONNULL(1
struct IDRemapper * BKE_id_remapper_create(void)
void BKE_id_remapper_free(struct IDRemapper *id_remapper)
void void BKE_libblock_relink_multiple(struct Main *bmain, struct LinkNode *ids, eIDRemapType remap_type, struct IDRemapper *id_remapper, short remap_flags)
Definition: lib_remap.c:754
void BKE_libblock_remap_multiple(struct Main *bmain, struct IDRemapper *mappings, short remap_flags)
Definition: lib_remap.c:661
#define FOREACH_MAIN_ID_END
Definition: BKE_main.h:367
struct Main * BKE_main_new(void)
Definition: main.c:32
#define FOREACH_MAIN_LISTBASE_ID_END
Definition: BKE_main.h:336
void BKE_main_relations_tag_set(struct Main *bmain, eMainIDRelationsEntryTags tag, bool value)
Definition: main.c:323
#define FOREACH_MAIN_LISTBASE_ID_BEGIN(_lb, _id)
Definition: BKE_main.h:330
#define FOREACH_MAIN_LISTBASE_END
Definition: BKE_main.h:348
@ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_TO
Definition: BKE_main.h:84
@ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED
Definition: BKE_main.h:89
@ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_FROM
Definition: BKE_main.h:87
void BKE_main_relations_create(struct Main *bmain, short flag)
Definition: main.c:276
void BKE_main_relations_free(struct Main *bmain)
Definition: main.c:311
#define FOREACH_MAIN_LISTBASE_BEGIN(_bmain, _lb)
Definition: BKE_main.h:341
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition: BKE_main.h:361
void BKE_main_free(struct Main *mainvar)
Definition: main.c:40
void BKE_main_namemap_remove_name(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL()
bool BKE_main_namemap_validate(struct Main *bmain) ATTR_NONNULL()
struct bNodeTree * ntreeFromID(struct ID *id)
Definition: node.cc:3231
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
#define ATTR_FALLTHROUGH
#define BLI_INLINE
struct GSet GSet
Definition: BLI_ghash.h:340
bool BLI_ghashutil_strcmp(const void *a, const void *b)
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:298
bool BLI_ghash_haskey(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:822
void BLI_ghashIterator_step(GHashIterator *ghi)
Definition: BLI_ghash.c:914
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:858
unsigned int BLI_ghashutil_ptrhash(const void *key)
void BLI_ghashIterator_free(GHashIterator *ghi)
Definition: BLI_ghash.c:928
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:302
#define GHASH_ITER(gh_iter_, ghash_)
Definition: BLI_ghash.h:321
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:689
void * BLI_gset_lookup(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1061
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
unsigned int BLI_ghashutil_strhash_p_murmur(const void *ptr)
GHashIterator * BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:891
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:790
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:710
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:748
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:755
BLI_INLINE bool BLI_ghashIterator_done(const GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:310
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
void * BLI_findstring_ptr(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink) ATTR_NONNULL(1
void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:354
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void * BLI_listbase_bytes_find(const ListBase *listbase, const void *bytes, size_t bytes_size, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) 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
#define BLI_MEMARENA_STD_BUFSIZE
Definition: BLI_memarena.h:20
void * BLI_memarena_calloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
Definition: BLI_memarena.c:153
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
unsigned int uint
Definition: BLI_sys_types.h:67
@ TASK_PRIORITY_HIGH
Definition: BLI_task.h:57
void * BLI_task_pool_user_data(TaskPool *pool)
Definition: task_pool.cc:525
void BLI_task_pool_work_and_wait(TaskPool *pool)
Definition: task_pool.cc:480
TaskPool * BLI_task_pool_create(void *userdata, eTaskPriority priority)
Definition: task_pool.cc:390
void BLI_task_pool_free(TaskPool *pool)
Definition: task_pool.cc:440
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
Definition: task_pool.cc:459
#define UNUSED_VARS_NDEBUG(...)
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
external readfile function prototypes.
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:190
#define CLOG_WARN(clg_ref,...)
Definition: CLG_log.h:189
#define CLOG_INFO(clg_ref, level,...)
Definition: CLG_log.h:187
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
@ IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE
Definition: DNA_ID.h:244
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:771
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ ID_RECALC_SELECT
Definition: DNA_ID.h:818
@ ID_RECALC_ALL
Definition: DNA_ID.h:891
@ ID_RECALC_BASE_FLAGS
Definition: DNA_ID.h:821
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
Definition: DNA_ID.h:581
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
#define MAX_ID_NAME
Definition: DNA_ID.h:337
@ IDOVERRIDE_LIBRARY_OP_MULTIPLY
Definition: DNA_ID.h:227
@ IDOVERRIDE_LIBRARY_OP_INSERT_AFTER
Definition: DNA_ID.h:230
@ IDOVERRIDE_LIBRARY_OP_NOOP
Definition: DNA_ID.h:218
@ IDOVERRIDE_LIBRARY_OP_SUBTRACT
Definition: DNA_ID.h:225
@ IDOVERRIDE_LIBRARY_OP_ADD
Definition: DNA_ID.h:223
@ IDOVERRIDE_LIBRARY_OP_INSERT_BEFORE
Definition: DNA_ID.h:231
@ IDOVERRIDE_LIBRARY_OP_REPLACE
Definition: DNA_ID.h:220
@ LIB_TAG_NO_USER_REFCOUNT
Definition: DNA_ID.h:745
@ LIB_TAG_INDIRECT
Definition: DNA_ID.h:677
@ LIB_TAG_DOIT
Definition: DNA_ID.h:707
@ LIB_TAG_OVERRIDE_LIBRARY_REFOK
Definition: DNA_ID.h:693
@ LIB_TAG_NO_MAIN
Definition: DNA_ID.h:744
@ LIB_TAG_MISSING
Definition: DNA_ID.h:690
@ LIB_TAG_LIB_OVERRIDE_NEED_RESYNC
Definition: DNA_ID.h:762
@ LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH
Definition: DNA_ID.h:695
@ LIB_LIB_OVERRIDE_RESYNC_LEFTOVER
Definition: DNA_ID.h:651
@ LIB_EMBEDDED_DATA_LIB_OVERRIDE
Definition: DNA_ID.h:646
#define ID_REAL_USERS(id)
Definition: DNA_ID.h:553
@ IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD
Definition: DNA_ID.h:288
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:588
@ LIBRARY_TAG_RESYNC_REQUIRED
Definition: DNA_ID.h:492
@ IDOVERRIDE_LIBRARY_TAG_UNUSED
Definition: DNA_ID.h:275
#define ID_IS_OVERRIDE_LIBRARY_TEMPLATE(_id)
Definition: DNA_ID.h:595
#define ID_MISSING(_id)
Definition: DNA_ID.h:564
@ IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY
Definition: DNA_ID.h:322
@ IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED
Definition: DNA_ID.h:327
@ ID_AR
Definition: DNA_ID_enums.h:66
@ 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_GR
Definition: DNA_ID_enums.h:65
@ ID_OB
Definition: DNA_ID_enums.h:47
@ POSE_RECALC
Object groups, one object can be in many groups at once.
@ COLLECTION_HIDE_RENDER
@ COLLECTION_HIDE_VIEWPORT
@ OB_MODE_POSE
Object is a sort of wrapper for general info.
#define OB_DATA_SUPPORT_ID(_id_type)
@ OB_ARMATURE
#define OBACT(_view_layer)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Platform independent time functions.
Utility defines for timing/benchmarks.
#define TIMEIT_START_AVERAGED(var)
#define TIMEIT_END_AVERAGED(var)
@ RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS
Definition: RNA_access.h:861
@ RNA_OVERRIDE_APPLY_FLAG_NOP
Definition: RNA_access.h:856
eRNAOverrideMatch
Definition: RNA_access.h:793
@ RNA_OVERRIDE_COMPARE_IGNORE_OVERRIDDEN
Definition: RNA_access.h:797
@ RNA_OVERRIDE_COMPARE_CREATE
Definition: RNA_access.h:800
@ RNA_OVERRIDE_COMPARE_IGNORE_NON_OVERRIDABLE
Definition: RNA_access.h:795
@ RNA_OVERRIDE_COMPARE_RESTORE
Definition: RNA_access.h:802
eRNAOverrideMatchResult
Definition: RNA_access.h:805
@ RNA_OVERRIDE_MATCH_RESULT_RESTORED
Definition: RNA_access.h:812
@ RNA_OVERRIDE_MATCH_RESULT_CREATED
Definition: RNA_access.h:810
@ PROP_POINTER
Definition: RNA_types.h:64
@ PROP_COLLECTION
Definition: RNA_types.h:65
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b)
StackEntry * from
Scene scene
TaskPool * task_pool
#define GS(x)
Definition: iris.c:225
static void lib_override_remapper_overrides_add(IDRemapper *id_remapper, ID *reference_id, ID *local_id)
void BKE_lib_override_library_main_hierarchy_root_ensure(Main *bmain)
void BKE_lib_override_library_main_tag(Main *bmain, const short tag, const bool do_set)
static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTagData *data)
static void lib_override_library_create_post_process(Main *bmain, Scene *scene, ViewLayer *view_layer, const Library *owner_library, ID *id_root, ID *id_instance_hint, Collection *residual_storage, const Object *old_active_object, const bool is_resync)
void BKE_lib_override_library_operations_store_finalize(OverrideLibraryStorage *override_storage)
static bool lib_override_resync_id_lib_level_is_valid(ID *id, const int library_indirect_level, const bool do_strict_equal)
static void lib_override_library_property_clear(IDOverrideLibraryProperty *op)
static void lib_override_group_tag_data_object_to_collection_init_collection_process(LibOverrideGroupTagData *data, Collection *collection)
static void lib_override_group_tag_data_object_to_collection_init(LibOverrideGroupTagData *data)
static void lib_override_hierarchy_dependencies_recursive_tag_from(LibOverrideGroupTagData *data)
ID * BKE_lib_override_library_create_from_id(Main *bmain, ID *reference_id, const bool do_tagged_remap)
void BKE_lib_override_library_free(IDOverrideLibrary **override, const bool do_id_user)
void BKE_lib_override_library_main_validate(Main *bmain, ReportList *reports)
static void lib_override_overrides_group_tag_recursive(LibOverrideGroupTagData *data)
void BKE_lib_override_library_operations_tag(IDOverrideLibraryProperty *override_property, const short tag, const bool do_set)
static void lib_override_root_hierarchy_set(Main *bmain, ID *id_root, ID *id, ID *id_from)
bool BKE_lib_override_library_id_is_user_deletable(Main *bmain, ID *id)
static void lib_override_linked_group_tag(LibOverrideGroupTagData *data)
IDOverrideLibraryProperty * BKE_lib_override_library_property_get(IDOverrideLibrary *override, const char *rna_path, bool *r_created)
bool BKE_lib_override_library_is_system_defined(const Main *bmain, const ID *id)
ID * BKE_lib_override_library_operations_store_start(Main *bmain, OverrideLibraryStorage *override_storage, ID *local)
void BKE_lib_override_library_properties_tag(IDOverrideLibrary *override, const short tag, const bool do_set)
bool BKE_lib_override_library_property_operation_operands_validate(IDOverrideLibraryPropertyOperation *override_property_operation, PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *ptr_storage, PropertyRNA *prop_dst, PropertyRNA *prop_src, PropertyRNA *prop_storage)
#define OVERRIDE_RESYNC_RESIDUAL_STORAGE_NAME
BLI_INLINE const IDOverrideLibrary * BKE_lib_override_library_get(const Main *bmain, const ID *id, const ID *owner_id_hint, const ID **r_owner_id)
Definition: lib_override.cc:95
static void lib_override_library_property_operation_copy(IDOverrideLibraryPropertyOperation *opop_dst, IDOverrideLibraryPropertyOperation *opop_src)
void BKE_lib_override_library_clear(IDOverrideLibrary *override, const bool do_id_user)
bool BKE_lib_override_library_status_check_reference(Main *bmain, ID *local)
bool BKE_lib_override_library_operations_create(Main *bmain, ID *local)
void BKE_lib_override_library_update(Main *bmain, ID *local)
static ID * lib_override_root_find(Main *bmain, ID *id, const int curr_level, int *r_best_level)
static void lib_override_id_swap(Main *bmain, ID *id_local, ID *id_temp)
OverrideLibraryStorage * BKE_lib_override_library_operations_store_init(void)
BLI_INLINE GHash * override_library_rna_path_mapping_ensure(IDOverrideLibrary *override)
IDOverrideLibraryPropertyOperation * BKE_lib_override_library_property_operation_get(IDOverrideLibraryProperty *override_property, const short operation, const char *subitem_refname, const char *subitem_locname, const int subitem_refindex, const int subitem_locindex, const bool strict, bool *r_strict, bool *r_created)
IDOverrideLibrary * BKE_lib_override_library_init(ID *local_id, ID *reference_id)
static void lib_override_library_remap(Main *bmain, const ID *id_root_reference, GHash *linkedref_to_old_override)
void BKE_lib_override_library_id_unused_cleanup(ID *local)
static void lib_override_library_operations_create_cb(TaskPool *__restrict pool, void *taskdata)
static bool lib_override_library_create_do(Main *bmain, Scene *scene, Library *owner_library, ID *id_root_reference, ID *id_hierarchy_root_reference, const bool do_fully_editable)
static void lib_override_group_tag_data_clear(LibOverrideGroupTagData *data)
void BKE_lib_override_library_main_resync(Main *bmain, Scene *scene, ViewLayer *view_layer, BlendFileReadReport *reports)
static ID * lib_override_library_main_resync_root_get(Main *bmain, ID *id)
bool BKE_lib_override_library_create(Main *bmain, Scene *scene, ViewLayer *view_layer, Library *owner_library, ID *id_root_reference, ID *id_hierarchy_root_reference, ID *id_instance_hint, ID **r_id_root_override, const bool do_fully_editable)
static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root, const bool do_reset_system_override)
bool BKE_lib_override_library_is_user_edited(const ID *id)
void BKE_lib_override_library_operations_store_end(OverrideLibraryStorage *UNUSED(override_storage), ID *local)
bool BKE_lib_override_library_create_from_tag(Main *bmain, Library *owner_library, const ID *id_root_reference, ID *id_hierarchy_root, const ID *id_hierarchy_root_reference, const bool do_no_main, const bool do_fully_editable)
void BKE_lib_override_library_id_reset(Main *bmain, ID *id_root, const bool do_reset_system_override)
bool BKE_lib_override_rna_property_find(PointerRNA *idpoin, const IDOverrideLibraryProperty *library_prop, PointerRNA *r_override_poin, PropertyRNA **r_override_prop, int *r_index)
bool BKE_lib_override_library_status_check_local(Main *bmain, ID *local)
static void lib_override_linked_group_tag_clear_boneshapes_objects(LibOverrideGroupTagData *data)
static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, ID *id_root, const bool do_reset_system_override)
static void lib_override_library_main_resync_on_library_indirect_level(Main *bmain, Scene *scene, ViewLayer *view_layer, Collection *override_resync_residual_storage, const int library_indirect_level, BlendFileReadReport *reports)
bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_layer, ID *id_root, Collection *override_resync_residual_storage, const bool do_hierarchy_enforce, BlendFileReadReport *reports)
static ID * lib_override_library_create_from(Main *bmain, Library *owner_library, ID *reference_id, const int lib_id_copy_flags)
static int lib_override_sort_libraries_func(LibraryIDLinkCallbackData *cb_data)
void BKE_lib_override_library_property_delete(IDOverrideLibrary *override, IDOverrideLibraryProperty *override_property)
static bool lib_override_linked_group_tag_collections_keep_tagged_check_recursive(LibOverrideGroupTagData *data, Collection *collection)
static bool lib_override_resync_tagging_finalize_recurse(Main *bmain, ID *id, GHash *id_roots, const int library_indirect_level, const bool check_only)
void BKE_lib_override_library_validate(Main *bmain, ID *id, ReportList *reports)
BLI_INLINE void lib_override_object_posemode_transfer(ID *id_dst, ID *id_src)
Definition: lib_override.cc:82
static bool lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_layer, ID *id_root, LinkNode *id_resync_roots, ListBase *no_main_ids_list, Collection *override_resync_residual_storage, const bool do_hierarchy_enforce, const bool do_post_process, BlendFileReadReport *reports)
bool BKE_lib_override_library_property_is_animated(const ID *id, const IDOverrideLibraryProperty *override_prop, const PropertyRNA *override_rna_prop, const int rnaprop_index)
void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
bool BKE_lib_override_library_is_hierarchy_leaf(Main *bmain, ID *id)
static CLG_LogRef LOG
Definition: lib_override.cc:68
static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *data)
static int foreachid_is_hierarchy_leaf_fn(LibraryIDLinkCallbackData *cb_data)
void BKE_lib_override_library_id_hierarchy_reset(Main *bmain, ID *id_root, const bool do_reset_system_override)
static void lib_override_library_property_operation_clear(IDOverrideLibraryPropertyOperation *opop)
void BKE_lib_override_library_main_update(Main *bmain)
void BKE_lib_override_library_main_unused_cleanup(Main *bmain)
void BKE_lib_override_library_make_local(ID *id)
static void lib_override_overrides_group_tag(LibOverrideGroupTagData *data)
BLI_INLINE IDOverrideLibraryRuntime * override_library_rna_path_runtime_ensure(IDOverrideLibrary *override)
IDOverrideLibraryPropertyOperation * BKE_lib_override_library_property_operation_find(IDOverrideLibraryProperty *override_property, const char *subitem_refname, const char *subitem_locname, const int subitem_refindex, const int subitem_locindex, const bool strict, bool *r_strict)
IDOverrideLibraryProperty * BKE_lib_override_library_property_find(IDOverrideLibrary *override, const char *rna_path)
bool BKE_lib_override_library_main_operations_create(Main *bmain, const bool force_auto)
static void lib_override_prefill_newid_from_existing_overrides(Main *bmain, ID *id_hierarchy_root)
void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id, const bool do_full_copy)
void BKE_lib_override_library_property_operation_delete(IDOverrideLibraryProperty *override_property, IDOverrideLibraryPropertyOperation *override_property_operation)
static int lib_override_libraries_index_define(Main *bmain)
static void lib_override_library_property_copy(IDOverrideLibraryProperty *op_dst, IDOverrideLibraryProperty *op_src)
bool BKE_lib_override_library_template_create(ID *id)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
bool RNA_struct_is_ID(const StructRNA *type)
Definition: rna_access.c:655
PropertyType RNA_property_type(PropertyRNA *prop)
Definition: rna_access.c:1010
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3493
StructRNA * RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1405
bool RNA_struct_override_store(Main *bmain, PointerRNA *ptr_local, PointerRNA *ptr_reference, PointerRNA *ptr_storage, IDOverrideLibrary *override)
void RNA_struct_override_apply(Main *bmain, PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *ptr_storage, IDOverrideLibrary *override, const eRNAOverrideApplyFlag flag)
bool RNA_struct_override_matches(Main *bmain, PointerRNA *ptr_local, PointerRNA *ptr_reference, const char *root_path, const size_t root_path_len, IDOverrideLibrary *override, const eRNAOverrideMatch flags, eRNAOverrideMatchResult *r_report_flags)
bool RNA_path_resolve_property(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition: rna_path.cc:531
bool RNA_path_resolve_property_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
Definition: rna_path.cc:543
const char * RNA_path_array_index_token_find(const char *rna_path, const PropertyRNA *array_prop)
Definition: rna_path.cc:693
unsigned char uint8_t
Definition: stdint.h:78
double lib_overrides_recursive_resync
Definition: BLO_readfile.h:88
struct ReportList * reports
Definition: BLO_readfile.h:80
bool do_resynced_lib_overrides_libraries_list
Definition: BLO_readfile.h:115
struct LinkNode * resynced_lib_overrides_libraries
Definition: BLO_readfile.h:116
int resynced_lib_overrides_libraries_count
Definition: BLO_readfile.h:114
struct BlendFileReadReport::@134 count
struct BlendFileReadReport::@133 duration
struct CollectionChild * next
struct CollectionObject * next
struct IDOverrideLibraryPropertyOperation * next
Definition: DNA_ID.h:189
struct IDOverrideLibraryProperty * next
Definition: DNA_ID.h:249
struct GHash * rna_path_to_override_properties
Definition: DNA_ID.h:281
struct ID * storage
Definition: DNA_ID.h:308
ListBase properties
Definition: DNA_ID.h:296
unsigned int flag
Definition: DNA_ID.h:312
struct ID * hierarchy_root
Definition: DNA_ID.h:303
struct ID * reference
Definition: DNA_ID.h:294
IDOverrideLibraryRuntime * runtime
Definition: DNA_ID.h:310
IDTypeEmbeddedOwnerGetFunction owner_get
Definition: BKE_idtype.h:189
Definition: DNA_ID.h:368
int tag
Definition: DNA_ID.h:387
struct Library * lib
Definition: DNA_ID.h:372
struct ID * newid
Definition: DNA_ID.h:370
IDOverrideLibrary * override_library
Definition: DNA_ID.h:412
short flag
Definition: DNA_ID.h:383
void * next
Definition: DNA_ID.h:369
char name[66]
Definition: DNA_ID.h:378
ID * from
Definition: DNA_key_types.h:88
ID id
Definition: DNA_key_types.h:63
GHash * linked_object_to_instantiating_collections
char filepath[1024]
Definition: DNA_ID.h:461
ID id
Definition: DNA_ID.h:458
int temp_index
Definition: DNA_ID.h:482
ushort tag
Definition: DNA_ID.h:478
void * data
Definition: DNA_listBase.h:26
struct LinkData * next
Definition: DNA_listBase.h:25
LinkNode * last_node
Definition: BLI_linklist.h:34
LinkNode * list
Definition: BLI_linklist.h:34
void * link
Definition: BLI_linklist.h:24
struct LinkNode * next
Definition: BLI_linklist.h:23
void * first
Definition: DNA_listBase.h:31
struct MainIDRelationsEntryItem * next
Definition: BKE_main.h:50
struct MainIDRelationsEntryItem * to_ids
Definition: BKE_main.h:68
struct MainIDRelationsEntryItem * from_ids
Definition: BKE_main.h:66
struct GHash * relations_from_pointers
Definition: BKE_main.h:107
Definition: BKE_main.h:121
ListBase libraries
Definition: BKE_main.h:169
struct MainIDRelations * relations
Definition: BKE_main.h:218
ListBase collections
Definition: BKE_main.h:189
ListBase objects
Definition: BKE_main.h:170
int restore_mode
void * data
struct StructRNA * type
Definition: RNA_types.h:37
void * data
Definition: RNA_types.h:38
struct ID * owner_id
Definition: RNA_types.h:36
struct Collection * master_collection
struct Base * basact
struct bPoseChannel * next
double PIL_check_seconds_timer(void)
Definition: time.c:64
static FT_Library library
PointerRNA * ptr
Definition: wm_files.c:3480
bool override
Definition: wm_files.c:1022