Blender  V2.93
lib_query.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2014 by Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <stdlib.h>
25 
26 #include "DNA_anim_types.h"
27 
28 #include "BLI_ghash.h"
29 #include "BLI_linklist_stack.h"
30 #include "BLI_listbase.h"
31 #include "BLI_utildefines.h"
32 
33 #include "BKE_anim_data.h"
34 #include "BKE_idprop.h"
35 #include "BKE_idtype.h"
36 #include "BKE_lib_id.h"
37 #include "BKE_lib_query.h"
38 #include "BKE_main.h"
39 #include "BKE_node.h"
40 
41 /* status */
42 enum {
43  IDWALK_STOP = 1 << 0,
44 };
45 
46 typedef struct LibraryForeachIDData {
58 
60  int flag;
62  int cb_flag;
65 
66  /* Function to call for every ID pointers of current processed data, and its opaque user data
67  * pointer. */
69  void *user_data;
72  int status;
73 
74  /* To handle recursion. */
75  GSet *ids_handled; /* All IDs that are either already done, or still in ids_todo stack. */
76  BLI_LINKSTACK_DECLARE(ids_todo, ID *);
78 
80 {
81  if (!(data->status & IDWALK_STOP)) {
82  const int flag = data->flag;
83  ID *old_id = *id_pp;
84 
85  /* Update the callback flags with the ones defined (or forbidden) in `data` by the generic
86  * caller code. */
87  cb_flag = ((cb_flag | data->cb_flag) & ~data->cb_flag_clear);
88 
89  /* Update the callback flags with some extra information regarding overrides: all 'loopback',
90  * 'internal', 'embedded' etc. ID pointers are never overridable. */
94  }
95 
96  const int callback_return = data->callback(
97  &(struct LibraryIDLinkCallbackData){.user_data = data->user_data,
98  .bmain = data->bmain,
99  .id_owner = data->owner_id,
100  .id_self = data->self_id,
101  .id_pointer = id_pp,
102  .cb_flag = cb_flag});
103  if (flag & IDWALK_READONLY) {
104  BLI_assert(*(id_pp) == old_id);
105  }
106  if (old_id && (flag & IDWALK_RECURSE)) {
107  if (BLI_gset_add((data)->ids_handled, old_id)) {
108  if (!(callback_return & IDWALK_RET_STOP_RECURSION)) {
109  BLI_LINKSTACK_PUSH(data->ids_todo, old_id);
110  }
111  }
112  }
113  if (callback_return & IDWALK_RET_STOP_ITER) {
114  data->status |= IDWALK_STOP;
115  return false;
116  }
117  return true;
118  }
119 
120  return false;
121 }
122 
124 {
125  return data->flag;
126 }
127 
129  const int cb_flag,
130  const bool do_replace)
131 {
132  const int cb_flag_backup = data->cb_flag;
133  if (do_replace) {
134  data->cb_flag = cb_flag;
135  }
136  else {
137  data->cb_flag |= cb_flag;
138  }
139  return cb_flag_backup;
140 }
141 
142 static void library_foreach_ID_link(Main *bmain,
143  ID *id_owner,
144  ID *id,
146  void *user_data,
147  int flag,
148  LibraryForeachIDData *inherit_data);
149 
151 {
152  BLI_assert(id_prop->type == IDP_ID);
153 
155  const int cb_flag = IDWALK_CB_USER | ((id_prop->flag & IDP_FLAG_OVERRIDABLE_LIBRARY) ?
156  0 :
158  BKE_LIB_FOREACHID_PROCESS_ID(data, id_prop->data.pointer, cb_flag);
159 }
160 
162 {
163  /* Needed e.g. for callbacks handling relationships. This call shall be absolutely read-only. */
164  ID *id = *id_pp;
165  const int flag = data->flag;
166 
168  return false;
169  }
170  BLI_assert(id == *id_pp);
171 
172  if (id == NULL) {
173  return true;
174  }
175 
176  if (flag & IDWALK_IGNORE_EMBEDDED_ID) {
177  /* Do Nothing. */
178  }
179  else if (flag & IDWALK_RECURSE) {
180  /* Defer handling into main loop, recursively calling BKE_library_foreach_ID_link in
181  * IDWALK_RECURSE case is troublesome, see T49553. */
182  /* XXX note that this breaks the 'owner id' thing now, we likely want to handle that
183  * differently at some point, but for now it should not be a problem in practice. */
184  if (BLI_gset_add(data->ids_handled, id)) {
185  BLI_LINKSTACK_PUSH(data->ids_todo, id);
186  }
187  }
188  else {
190  data->bmain, data->owner_id, id, data->callback, data->user_data, data->flag, data);
191  }
192 
193  return true;
194 }
195 
196 static void library_foreach_ID_link(Main *bmain,
197  ID *id_owner,
198  ID *id,
200  void *user_data,
201  int flag,
202  LibraryForeachIDData *inherit_data)
203 {
204  LibraryForeachIDData data = {.bmain = bmain};
205 
206  BLI_assert(inherit_data == NULL || data.bmain == inherit_data->bmain);
207 
208  if (flag & IDWALK_RECURSE) {
209  /* For now, recursion implies read-only, and no internal pointers. */
210  flag |= IDWALK_READONLY;
212 
214  BLI_LINKSTACK_INIT(data.ids_todo);
215 
216  BLI_gset_add(data.ids_handled, id);
217  }
218  else {
219  data.ids_handled = NULL;
220  }
221  data.flag = flag;
222  data.status = 0;
223  data.callback = callback;
224  data.user_data = user_data;
225 
226 #define CALLBACK_INVOKE_ID(check_id, cb_flag) \
227  BKE_LIB_FOREACHID_PROCESS_ID(&data, check_id, cb_flag)
228 
229 #define CALLBACK_INVOKE(check_id_super, cb_flag) \
230  BKE_LIB_FOREACHID_PROCESS(&data, check_id_super, cb_flag)
231 
232  for (; id != NULL; id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL) {
233  data.self_id = id;
234  /* Note that we may call this functions sometime directly on an embedded ID, without any
235  * knowledge of the owner ID then.
236  * While not great, and that should be probably sanitized at some point, we cal live with it
237  * for now. */
238  data.owner_id = ((id->flag & LIB_EMBEDDED_DATA) != 0 && id_owner != NULL) ? id_owner :
239  data.self_id;
240 
241  /* inherit_data is non-NULL when this function is called for some sub-data ID
242  * (like root node-tree of a material).
243  * In that case, we do not want to generate those 'generic flags' from our current sub-data ID
244  * (the node tree), but re-use those generated for the 'owner' ID (the material). */
245  if (inherit_data == NULL) {
246  data.cb_flag = ID_IS_LINKED(id) ? IDWALK_CB_INDIRECT_USAGE : 0;
247  /* When an ID is not in Main database, it should never refcount IDs it is using.
248  * Exceptions: NodeTrees (yeah!) directly used by Materials. */
249  data.cb_flag_clear = (id->tag & LIB_TAG_NO_MAIN) ? IDWALK_CB_USER | IDWALK_CB_USER_ONE : 0;
250  }
251  else {
252  data.cb_flag = inherit_data->cb_flag;
253  data.cb_flag_clear = inherit_data->cb_flag_clear;
254  }
255 
256  if (bmain != NULL && bmain->relations != NULL && (flag & IDWALK_READONLY) &&
257  (flag & IDWALK_DO_INTERNAL_RUNTIME_POINTERS) == 0 &&
258  (((bmain->relations->flag & MAINIDRELATIONS_INCLUDE_UI) == 0) ==
259  ((data.flag & IDWALK_INCLUDE_UI) == 0))) {
260  /* Note that this is minor optimization, even in worst cases (like id being an object with
261  * lots of drivers and constraints and modifiers, or material etc. with huge node tree),
262  * but we might as well use it (Main->relations is always assumed valid,
263  * it's responsibility of code creating it to free it,
264  * especially if/when it starts modifying Main database). */
266  id);
267  for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL;
268  to_id_entry = to_id_entry->next) {
270  &data, to_id_entry->id_pointer.to, to_id_entry->usage_flag);
271  }
272  continue;
273  }
274 
275  /* Note: ID.lib pointer is purposefully fully ignored here...
276  * We may want to add it at some point? */
277 
281  }
282 
283  if (id->override_library != NULL) {
288  }
289 
293  &data);
294 
295  AnimData *adt = BKE_animdata_from_id(id);
296  if (adt) {
298  }
299 
300  const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
301  if (id_type->foreach_id != NULL) {
302  id_type->foreach_id(id, &data);
303 
304  if (data.status & IDWALK_STOP) {
305  break;
306  }
307  }
308  }
309 
310  if (data.ids_handled) {
311  BLI_gset_free(data.ids_handled, NULL);
312  BLI_LINKSTACK_FREE(data.ids_todo);
313  }
314 
315 #undef CALLBACK_INVOKE_ID
316 #undef CALLBACK_INVOKE
317 }
318 
323  Main *bmain, ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
324 {
325  library_foreach_ID_link(bmain, NULL, id, callback, user_data, flag, NULL);
326 }
327 
331 void BKE_library_update_ID_link_user(ID *id_dst, ID *id_src, const int cb_flag)
332 {
333  if (cb_flag & IDWALK_CB_USER) {
334  id_us_min(id_src);
335  id_us_plus(id_dst);
336  }
337  else if (cb_flag & IDWALK_CB_USER_ONE) {
338  id_us_ensure_real(id_dst);
339  }
340 }
341 
348 bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
349 {
350  /* any type of ID can be used in custom props. */
351  if (id_owner->properties) {
352  return true;
353  }
354 
355  const short id_type_owner = GS(id_owner->name);
356 
357  /* IDProps of armature bones and nodes, and bNode->id can use virtually any type of ID. */
358  if (ELEM(id_type_owner, ID_NT, ID_AR)) {
359  return true;
360  }
361 
362  if (ntreeFromID(id_owner)) {
363  return true;
364  }
365 
366  if (BKE_animdata_from_id(id_owner)) {
367  /* AnimationData can use virtually any kind of data-blocks, through drivers especially. */
368  return true;
369  }
370 
371  switch ((ID_Type)id_type_owner) {
372  case ID_LI:
373  return ELEM(id_type_used, ID_LI);
374  case ID_SCE:
375  return (ELEM(id_type_used,
376  ID_OB,
377  ID_WO,
378  ID_SCE,
379  ID_MC,
380  ID_MA,
381  ID_GR,
382  ID_TXT,
383  ID_LS,
384  ID_MSK,
385  ID_SO,
386  ID_GD,
387  ID_BR,
388  ID_PAL,
389  ID_IM,
390  ID_NT));
391  case ID_OB:
392  /* Could be more specific, but simpler to just always say 'yes' here. */
393  return true;
394  case ID_ME:
395  return ELEM(id_type_used, ID_ME, ID_KE, ID_MA, ID_IM);
396  case ID_CU:
397  return ELEM(id_type_used, ID_OB, ID_KE, ID_MA, ID_VF);
398  case ID_MB:
399  return ELEM(id_type_used, ID_MA);
400  case ID_MA:
401  return (ELEM(id_type_used, ID_TE, ID_GR));
402  case ID_TE:
403  return (ELEM(id_type_used, ID_IM, ID_OB));
404  case ID_LT:
405  return ELEM(id_type_used, ID_KE);
406  case ID_LA:
407  return (ELEM(id_type_used, ID_TE));
408  case ID_CA:
409  return ELEM(id_type_used, ID_OB, ID_IM);
410  case ID_KE:
411  /* Warning! key->from, could be more types in future? */
412  return ELEM(id_type_used, ID_ME, ID_CU, ID_LT);
413  case ID_SCR:
414  return ELEM(id_type_used, ID_SCE);
415  case ID_WO:
416  return (ELEM(id_type_used, ID_TE));
417  case ID_SPK:
418  return ELEM(id_type_used, ID_SO);
419  case ID_GR:
420  return ELEM(id_type_used, ID_OB, ID_GR);
421  case ID_NT:
422  /* Could be more specific, but node.id has no type restriction... */
423  return true;
424  case ID_BR:
425  return ELEM(id_type_used, ID_BR, ID_IM, ID_PC, ID_TE, ID_MA);
426  case ID_PA:
427  return ELEM(id_type_used, ID_OB, ID_GR, ID_TE);
428  case ID_MC:
429  return ELEM(id_type_used, ID_GD, ID_IM);
430  case ID_MSK:
431  /* WARNING! mask->parent.id, not typed. */
432  return ELEM(id_type_used, ID_MC);
433  case ID_LS:
434  return (ELEM(id_type_used, ID_TE, ID_OB));
435  case ID_LP:
436  return ELEM(id_type_used, ID_IM);
437  case ID_GD:
438  return ELEM(id_type_used, ID_MA);
439  case ID_WS:
440  return ELEM(id_type_used, ID_SCR, ID_SCE);
441  case ID_HA:
442  return ELEM(id_type_used, ID_MA);
443  case ID_PT:
444  return ELEM(id_type_used, ID_MA);
445  case ID_VO:
446  return ELEM(id_type_used, ID_MA);
447  case ID_SIM:
448  return ELEM(id_type_used, ID_OB, ID_IM);
449  case ID_WM:
450  return ELEM(id_type_used, ID_SCE, ID_WS);
451  case ID_IM:
452  case ID_VF:
453  case ID_TXT:
454  case ID_SO:
455  case ID_AR:
456  case ID_AC:
457  case ID_PAL:
458  case ID_PC:
459  case ID_CF:
460  /* Those types never use/reference other IDs... */
461  return false;
462  case ID_IP:
463  /* Deprecated... */
464  return false;
465  }
466  return false;
467 }
468 
469 /* ***** ID users iterator. ***** */
470 typedef struct IDUsersIter {
471  ID *id;
472 
474  int lb_idx;
475 
477  int count_direct, count_indirect; /* Set by callback. */
479 
481 {
482  ID **id_p = cb_data->id_pointer;
483  const int cb_flag = cb_data->cb_flag;
484  IDUsersIter *iter = cb_data->user_data;
485 
486  if (*id_p) {
487  /* 'Loopback' ID pointers (the ugly 'from' ones, Object->proxy_from and Key->from).
488  * Those are not actually ID usage, we can ignore them here.
489  */
490  if (cb_flag & IDWALK_CB_LOOPBACK) {
491  return IDWALK_RET_NOP;
492  }
493 
494  if (*id_p == iter->id) {
495 #if 0
496  printf(
497  "%s uses %s (refcounted: %d, userone: %d, used_one: %d, used_one_active: %d, "
498  "indirect_usage: %d)\n",
499  iter->curr_id->name,
500  iter->id->name,
501  (cb_flag & IDWALK_USER) ? 1 : 0,
502  (cb_flag & IDWALK_USER_ONE) ? 1 : 0,
503  (iter->id->tag & LIB_TAG_EXTRAUSER) ? 1 : 0,
504  (iter->id->tag & LIB_TAG_EXTRAUSER_SET) ? 1 : 0,
505  (cb_flag & IDWALK_INDIRECT_USAGE) ? 1 : 0);
506 #endif
507  if (cb_flag & IDWALK_CB_INDIRECT_USAGE) {
508  iter->count_indirect++;
509  }
510  else {
511  iter->count_direct++;
512  }
513  }
514  }
515 
516  return IDWALK_RET_NOP;
517 }
518 
529 int BKE_library_ID_use_ID(ID *id_user, ID *id_used)
530 {
531  IDUsersIter iter;
532 
533  /* We do not care about iter.lb_array/lb_idx here... */
534  iter.id = id_used;
535  iter.curr_id = id_user;
536  iter.count_direct = iter.count_indirect = 0;
537 
540 
541  return iter.count_direct + iter.count_indirect;
542 }
543 
544 static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked)
545 {
546  IDUsersIter iter;
547  ListBase *lb_array[INDEX_ID_MAX];
548  ID *id = idv;
549  int i = set_listbasepointers(bmain, lb_array);
550  bool is_defined = false;
551 
552  iter.id = id;
553  iter.count_direct = iter.count_indirect = 0;
554  while (i-- && !is_defined) {
555  ID *id_curr = lb_array[i]->first;
556 
557  if (!id_curr || !BKE_library_id_can_use_idtype(id_curr, GS(id->name))) {
558  continue;
559  }
560 
561  for (; id_curr && !is_defined; id_curr = id_curr->next) {
562  if (id_curr == id) {
563  /* We are not interested in self-usages (mostly from drivers or bone constraints...). */
564  continue;
565  }
566  iter.curr_id = id_curr;
568  bmain, id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_READONLY);
569 
570  is_defined = ((check_linked ? iter.count_indirect : iter.count_direct) != 0);
571  }
572  }
573 
574  return is_defined;
575 }
576 
580 bool BKE_library_ID_is_locally_used(Main *bmain, void *idv)
581 {
582  return library_ID_is_used(bmain, idv, false);
583 }
584 
589 {
590  return library_ID_is_used(bmain, idv, true);
591 }
592 
597 void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *is_used_local, bool *is_used_linked)
598 {
599  IDUsersIter iter;
600  ListBase *lb_array[INDEX_ID_MAX];
601  ID *id = idv;
602  int i = set_listbasepointers(bmain, lb_array);
603  bool is_defined = false;
604 
605  iter.id = id;
606  iter.count_direct = iter.count_indirect = 0;
607  while (i-- && !is_defined) {
608  ID *id_curr = lb_array[i]->first;
609 
610  if (!id_curr || !BKE_library_id_can_use_idtype(id_curr, GS(id->name))) {
611  continue;
612  }
613 
614  for (; id_curr && !is_defined; id_curr = id_curr->next) {
615  if (id_curr == id) {
616  /* We are not interested in self-usages (mostly from drivers or bone constraints...). */
617  continue;
618  }
619  iter.curr_id = id_curr;
621  bmain, id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_READONLY);
622 
623  is_defined = (iter.count_direct != 0 && iter.count_indirect != 0);
624  }
625  }
626 
627  *is_used_local = (iter.count_direct != 0);
628  *is_used_linked = (iter.count_indirect != 0);
629 }
630 
631 /* ***** IDs usages.checking/tagging. ***** */
633  const int tag,
634  const bool do_local_ids,
635  const bool do_linked_ids,
636  ID *id,
637  int *r_num_tagged)
638 {
639  /* We should never deal with embedded, not-in-main IDs here. */
640  BLI_assert((id->flag & LIB_EMBEDDED_DATA) == 0);
641 
642  if ((!do_linked_ids && ID_IS_LINKED(id)) || (!do_local_ids && !ID_IS_LINKED(id))) {
643  return;
644  }
645 
647  id);
648  if ((id_relations->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED) != 0) {
649  return;
650  }
652 
653  if ((id->tag & tag) != 0) {
654  return;
655  }
656 
657  if ((id->flag & LIB_FAKEUSER) != 0) {
658  /* This ID is forcefully kept around, and therefore never unused, no need to check it further.
659  */
660  return;
661  }
662 
663  if (ELEM(GS(id->name), ID_WM, ID_WS, ID_SCE, ID_SCR, ID_LI)) {
664  /* Some 'root' ID types are never unused (even though they may not have actual users), unless
665  * their actual user-count is set to 0. */
666  return;
667  }
668 
669  /* An ID user is 'valid' (i.e. may affect the 'used'/'not used' status of the ID it uses) if it
670  * does not match `ignored_usages`, and does match `required_usages`. */
671  const int ignored_usages = (IDWALK_CB_LOOPBACK | IDWALK_CB_EMBEDDED);
672  const int required_usages = (IDWALK_CB_USER | IDWALK_CB_USER_ONE);
673 
674  /* This ID may be tagged as unused if none of its users are 'valid', as defined above.
675  *
676  * First recursively check all its valid users, if all of them can be tagged as
677  * unused, then we can tag this ID as such too. */
678  bool has_valid_from_users = false;
679  for (MainIDRelationsEntryItem *id_from_item = id_relations->from_ids; id_from_item != NULL;
680  id_from_item = id_from_item->next) {
681  if ((id_from_item->usage_flag & ignored_usages) != 0 ||
682  (id_from_item->usage_flag & required_usages) == 0) {
683  continue;
684  }
685 
686  ID *id_from = id_from_item->id_pointer.from;
687  if ((id_from->flag & LIB_EMBEDDED_DATA) != 0) {
688  /* Directly 'by-pass' to actual real ID owner. */
689  const IDTypeInfo *type_info_from = BKE_idtype_get_info_from_id(id_from);
690  BLI_assert(type_info_from->owner_get != NULL);
691  id_from = type_info_from->owner_get(bmain, id_from);
692  }
693 
695  bmain, tag, do_local_ids, do_linked_ids, id_from, r_num_tagged);
696  if ((id_from->tag & tag) == 0) {
697  has_valid_from_users = true;
698  break;
699  }
700  }
701  if (!has_valid_from_users) {
702  /* This ID has no 'valid' users, tag it as unused. */
703  id->tag |= tag;
704  if (r_num_tagged != NULL) {
705  r_num_tagged[INDEX_ID_NULL]++;
706  r_num_tagged[BKE_idtype_idcode_to_index(GS(id->name))]++;
707  }
708  }
709 }
710 
727  const int tag,
728  const bool do_local_ids,
729  const bool do_linked_ids,
730  const bool do_tag_recursive,
731  int *r_num_tagged)
732 {
733  /* First loop, to only check for immediately unused IDs (those with 0 user count).
734  * NOTE: It also takes care of clearing given tag for used IDs. */
735  ID *id;
736  FOREACH_MAIN_ID_BEGIN (bmain, id) {
737  if ((!do_linked_ids && ID_IS_LINKED(id)) || (!do_local_ids && !ID_IS_LINKED(id))) {
738  id->tag &= ~tag;
739  }
740  else if (id->us == 0) {
741  id->tag |= tag;
742  if (r_num_tagged != NULL) {
743  r_num_tagged[INDEX_ID_NULL]++;
744  r_num_tagged[BKE_idtype_idcode_to_index(GS(id->name))]++;
745  }
746  }
747  else {
748  id->tag &= ~tag;
749  }
750  }
752 
753  if (!do_tag_recursive) {
754  return;
755  }
756 
757  BKE_main_relations_create(bmain, 0);
758  FOREACH_MAIN_ID_BEGIN (bmain, id) {
759  lib_query_unused_ids_tag_recurse(bmain, tag, do_local_ids, do_linked_ids, id, r_num_tagged);
760  }
763 }
764 
766 {
767  ID *self_id = cb_data->id_self;
768  ID **id_p = cb_data->id_pointer;
769  const int cb_flag = cb_data->cb_flag;
770  bool *is_changed = cb_data->user_data;
771 
772  if (*id_p) {
773  /* The infamous 'from' pointers (Key.from, Object.proxy_from, ...).
774  * those are not actually ID usage, so we ignore them here. */
775  if (cb_flag & IDWALK_CB_LOOPBACK) {
776  return IDWALK_RET_NOP;
777  }
778 
779  /* If checked id is used by an assumed used ID,
780  * then it is also used and not part of any linked archipelago. */
781  if (!(self_id->tag & LIB_TAG_DOIT) && ((*id_p)->tag & LIB_TAG_DOIT)) {
782  (*id_p)->tag &= ~LIB_TAG_DOIT;
783  *is_changed = true;
784  }
785  }
786 
787  return IDWALK_RET_NOP;
788 }
789 
799 void BKE_library_unused_linked_data_set_tag(Main *bmain, const bool do_init_tag)
800 {
801  ID *id;
802 
803  if (do_init_tag) {
804  FOREACH_MAIN_ID_BEGIN (bmain, id) {
805  if (id->lib && (id->tag & LIB_TAG_INDIRECT) != 0) {
806  id->tag |= LIB_TAG_DOIT;
807  }
808  else {
809  id->tag &= ~LIB_TAG_DOIT;
810  }
811  }
813  }
814 
815  for (bool do_loop = true; do_loop;) {
816  do_loop = false;
817  FOREACH_MAIN_ID_BEGIN (bmain, id) {
818  /* We only want to check that ID if it is currently known as used... */
819  if ((id->tag & LIB_TAG_DOIT) == 0) {
822  }
823  }
825  }
826 }
827 
837 {
838  ListBase *lb_array[INDEX_ID_MAX];
839 
840  bool do_loop = true;
841  while (do_loop) {
842  int i = set_listbasepointers(bmain, lb_array);
843  do_loop = false;
844 
845  while (i--) {
846  LISTBASE_FOREACH (ID *, id, lb_array[i]) {
847  if (id->lib == NULL || id->tag & LIB_TAG_DOIT) {
848  /* Local or non-indirectly-used ID (so far), no need to check it further. */
849  continue;
850  }
853  }
854  }
855  }
856 }
void BKE_animdata_foreach_id(struct AnimData *adt, struct LibraryForeachIDData *data)
Definition: anim_data.c:294
struct AnimData * BKE_animdata_from_id(struct ID *id)
Definition: anim_data.c:96
void IDP_foreach_property(struct IDProperty *id_property_root, const int type_filter, IDPForeachPropertyCallback callback, void *user_data)
Definition: idprop.c:1072
int BKE_idtype_idcode_to_index(const short idcode)
Definition: idtype.c:345
const struct IDTypeInfo * BKE_idtype_get_info_from_id(const struct ID *id)
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void id_us_ensure_real(struct ID *id)
Definition: lib_id.c:238
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
int(* LibraryIDLinkCallback)(LibraryIDLinkCallbackData *cb_data)
@ IDWALK_RECURSE
@ IDWALK_INCLUDE_UI
@ IDWALK_READONLY
@ IDWALK_DO_INTERNAL_RUNTIME_POINTERS
@ IDWALK_IGNORE_EMBEDDED_ID
@ IDWALK_RET_STOP_RECURSION
@ IDWALK_RET_STOP_ITER
Definition: BKE_lib_query.h:99
@ IDWALK_RET_NOP
Definition: BKE_lib_query.h:97
@ IDWALK_CB_LOOPBACK
Definition: BKE_lib_query.h:68
@ IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE
Definition: BKE_lib_query.h:74
@ IDWALK_CB_USER_ONE
Definition: BKE_lib_query.h:93
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:87
@ IDWALK_CB_INTERNAL
Definition: BKE_lib_query.h:81
@ IDWALK_CB_EMBEDDED
Definition: BKE_lib_query.h:62
@ IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE
Definition: BKE_lib_query.h:71
@ IDWALK_CB_INDIRECT_USAGE
Definition: BKE_lib_query.h:55
#define BKE_LIB_FOREACHID_PROCESS_ID(_data, _id, _cb_flag)
#define FOREACH_MAIN_ID_END
Definition: BKE_main.h:250
@ MAINIDRELATIONS_INCLUDE_UI
Definition: BKE_main.h:113
void BKE_main_relations_create(struct Main *bmain, const short flag)
Definition: main.c:265
int set_listbasepointers(struct Main *main, struct ListBase *lb[])
@ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED
Definition: BKE_main.h:96
void BKE_main_relations_free(struct Main *bmain)
Definition: main.c:300
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition: BKE_main.h:244
struct bNodeTree * ntreeFromID(struct ID *id)
Definition: node.cc:3147
#define BLI_assert(a)
Definition: BLI_assert.h:58
struct GSet GSet
Definition: BLI_ghash.h:189
unsigned int BLI_ghashutil_ptrhash(const void *key)
GSet * BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1125
bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1253
bool BLI_gset_add(GSet *gs, void *key)
Definition: BLI_ghash.c:1160
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:803
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
#define ELEM(...)
@ LIB_TAG_EXTRAUSER_SET
Definition: DNA_ID.h:547
@ LIB_TAG_INDIRECT
Definition: DNA_ID.h:524
@ LIB_TAG_EXTRAUSER
Definition: DNA_ID.h:545
@ LIB_TAG_DOIT
Definition: DNA_ID.h:554
@ LIB_TAG_NO_MAIN
Definition: DNA_ID.h:572
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
@ IDP_ID
Definition: DNA_ID.h:102
@ LIB_EMBEDDED_DATA
Definition: DNA_ID.h:482
@ LIB_FAKEUSER
Definition: DNA_ID.h:477
@ IDP_TYPE_FILTER_ID
Definition: DNA_ID.h:115
@ IDP_FLAG_OVERRIDABLE_LIBRARY
Definition: DNA_ID.h:132
@ INDEX_ID_NULL
Definition: DNA_ID.h:858
@ INDEX_ID_MAX
Definition: DNA_ID.h:859
ID_Type
Definition: DNA_ID_enums.h:56
@ ID_WM
Definition: DNA_ID_enums.h:84
@ ID_CA
Definition: DNA_ID_enums.h:68
@ ID_AR
Definition: DNA_ID_enums.h:78
@ ID_MC
Definition: DNA_ID_enums.h:85
@ ID_CF
Definition: DNA_ID_enums.h:90
@ ID_LI
Definition: DNA_ID_enums.h:58
@ ID_TE
Definition: DNA_ID_enums.h:64
@ ID_IM
Definition: DNA_ID_enums.h:65
@ ID_VO
Definition: DNA_ID_enums.h:95
@ ID_WS
Definition: DNA_ID_enums.h:91
@ ID_NT
Definition: DNA_ID_enums.h:80
@ ID_LA
Definition: DNA_ID_enums.h:67
@ ID_KE
Definition: DNA_ID_enums.h:70
@ ID_TXT
Definition: DNA_ID_enums.h:74
@ ID_SO
Definition: DNA_ID_enums.h:76
@ ID_SCE
Definition: DNA_ID_enums.h:57
@ ID_LS
Definition: DNA_ID_enums.h:87
@ ID_MSK
Definition: DNA_ID_enums.h:86
@ ID_GD
Definition: DNA_ID_enums.h:83
@ ID_PAL
Definition: DNA_ID_enums.h:88
@ ID_BR
Definition: DNA_ID_enums.h:81
@ ID_LP
Definition: DNA_ID_enums.h:92
@ ID_HA
Definition: DNA_ID_enums.h:93
@ ID_WO
Definition: DNA_ID_enums.h:71
@ ID_SIM
Definition: DNA_ID_enums.h:96
@ ID_MA
Definition: DNA_ID_enums.h:63
@ ID_AC
Definition: DNA_ID_enums.h:79
@ ID_SCR
Definition: DNA_ID_enums.h:72
@ ID_VF
Definition: DNA_ID_enums.h:73
@ ID_ME
Definition: DNA_ID_enums.h:60
@ ID_IP
Definition: DNA_ID_enums.h:69
@ ID_GR
Definition: DNA_ID_enums.h:77
@ ID_SPK
Definition: DNA_ID_enums.h:75
@ ID_MB
Definition: DNA_ID_enums.h:62
@ ID_LT
Definition: DNA_ID_enums.h:66
@ ID_OB
Definition: DNA_ID_enums.h:59
@ ID_PA
Definition: DNA_ID_enums.h:82
@ ID_PT
Definition: DNA_ID_enums.h:94
@ ID_CU
Definition: DNA_ID_enums.h:61
@ ID_PC
Definition: DNA_ID_enums.h:89
void * user_data
DEGForeachIDComponentCallback callback
#define GS(x)
Definition: iris.c:241
void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *is_used_local, bool *is_used_linked)
Definition: lib_query.c:597
bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int cb_flag)
Definition: lib_query.c:79
static void library_foreach_ID_link(Main *bmain, ID *id_owner, ID *id, LibraryIDLinkCallback callback, void *user_data, int flag, LibraryForeachIDData *inherit_data)
Definition: lib_query.c:196
void BKE_library_unused_linked_data_set_tag(Main *bmain, const bool do_init_tag)
Definition: lib_query.c:799
struct LibraryForeachIDData LibraryForeachIDData
bool BKE_library_ID_is_indirectly_used(Main *bmain, void *idv)
Definition: lib_query.c:588
static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked)
Definition: lib_query.c:544
void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
Definition: lib_query.c:322
static void lib_query_unused_ids_tag_recurse(Main *bmain, const int tag, const bool do_local_ids, const bool do_linked_ids, ID *id, int *r_num_tagged)
Definition: lib_query.c:632
int BKE_library_ID_use_ID(ID *id_user, ID *id_used)
Definition: lib_query.c:529
int BKE_lib_query_foreachid_process_flags_get(LibraryForeachIDData *data)
Definition: lib_query.c:123
@ IDWALK_STOP
Definition: lib_query.c:43
int BKE_lib_query_foreachid_process_callback_flag_override(LibraryForeachIDData *data, const int cb_flag, const bool do_replace)
Definition: lib_query.c:128
#define CALLBACK_INVOKE_ID(check_id, cb_flag)
void BKE_lib_query_idpropertiesForeachIDLink_callback(IDProperty *id_prop, void *user_data)
Definition: lib_query.c:150
static int foreach_libblock_id_users_callback(LibraryIDLinkCallbackData *cb_data)
Definition: lib_query.c:480
void BKE_lib_query_unused_ids_tag(Main *bmain, const int tag, const bool do_local_ids, const bool do_linked_ids, const bool do_tag_recursive, int *r_num_tagged)
Definition: lib_query.c:726
void BKE_library_update_ID_link_user(ID *id_dst, ID *id_src, const int cb_flag)
Definition: lib_query.c:331
struct IDUsersIter IDUsersIter
bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
Definition: lib_query.c:348
void BKE_library_indirectly_used_data_tag_clear(Main *bmain)
Definition: lib_query.c:836
bool BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp)
Definition: lib_query.c:161
bool BKE_library_ID_is_locally_used(Main *bmain, void *idv)
Definition: lib_query.c:580
static int foreach_libblock_used_linked_data_tag_clear_cb(LibraryIDLinkCallbackData *cb_data)
Definition: lib_query.c:765
struct ID * storage
Definition: DNA_ID.h:257
struct ID * reference
Definition: DNA_ID.h:250
void * pointer
Definition: DNA_ID.h:63
short flag
Definition: DNA_ID.h:72
IDPropertyData data
Definition: DNA_ID.h:80
char type
Definition: DNA_ID.h:71
IDTypeEmbeddedOwnerGetFunction owner_get
Definition: BKE_idtype.h:189
IDTypeForeachIDFunction foreach_id
Definition: BKE_idtype.h:179
int count_direct
Definition: lib_query.c:477
ListBase * lb_array[INDEX_ID_MAX]
Definition: lib_query.c:473
int count_indirect
Definition: lib_query.c:477
ID * curr_id
Definition: lib_query.c:476
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
struct Library * lib
Definition: DNA_ID.h:277
int us
Definition: DNA_ID.h:293
struct ID * newid
Definition: DNA_ID.h:275
IDProperty * properties
Definition: DNA_ID.h:314
IDOverrideLibrary * override_library
Definition: DNA_ID.h:317
struct ID * orig_id
Definition: DNA_ID.h:324
short flag
Definition: DNA_ID.h:288
void * next
Definition: DNA_ID.h:274
char name[66]
Definition: DNA_ID.h:283
BLI_LINKSTACK_DECLARE(ids_todo, ID *)
LibraryIDLinkCallback callback
Definition: lib_query.c:68
void * first
Definition: DNA_listBase.h:47
struct MainIDRelationsEntryItem * to_ids
Definition: BKE_main.h:82
struct MainIDRelationsEntryItem * from_ids
Definition: BKE_main.h:80
struct GHash * relations_from_pointers
Definition: BKE_main.h:102
Definition: BKE_main.h:116
struct MainIDRelations * relations
Definition: BKE_main.h:192