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
20 /** \file
21 * \ingroup bke
22 */
23
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 {
47 Main *bmain;
48 /**
49 * 'Real' ID, the one that might be in bmain, only differs from self_id when the later is a
50 * private one.
51 */
52 ID *owner_id;
53 /**
54 * ID from which the current ID pointer is being processed. It may be an embedded ID like master
55 * collection or root node tree.
56 */
57 ID *self_id;
58
59 int flag;
60 int cb_flag;
61 int cb_flag_clear;
62 LibraryIDLinkCallback callback;
63 void *user_data;
64 int status;
65
66 /* To handle recursion. */
67 GSet *ids_handled; /* All IDs that are either already done, or still in ids_todo stack. */
68 BLI_LINKSTACK_DECLARE(ids_todo, ID *);
69 } LibraryForeachIDData;
70
BKE_lib_query_foreachid_process(LibraryForeachIDData * data,ID ** id_pp,int cb_flag)71 bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int cb_flag)
72 {
73 if (!(data->status & IDWALK_STOP)) {
74 const int flag = data->flag;
75 ID *old_id = *id_pp;
76 const int callback_return = data->callback(&(struct LibraryIDLinkCallbackData){
77 .user_data = data->user_data,
78 .bmain = data->bmain,
79 .id_owner = data->owner_id,
80 .id_self = data->self_id,
81 .id_pointer = id_pp,
82 .cb_flag = ((cb_flag | data->cb_flag) & ~data->cb_flag_clear)});
83 if (flag & IDWALK_READONLY) {
84 BLI_assert(*(id_pp) == old_id);
85 }
86 if (old_id && (flag & IDWALK_RECURSE)) {
87 if (BLI_gset_add((data)->ids_handled, old_id)) {
88 if (!(callback_return & IDWALK_RET_STOP_RECURSION)) {
89 BLI_LINKSTACK_PUSH(data->ids_todo, old_id);
90 }
91 }
92 }
93 if (callback_return & IDWALK_RET_STOP_ITER) {
94 data->status |= IDWALK_STOP;
95 return false;
96 }
97 return true;
98 }
99
100 return false;
101 }
102
BKE_lib_query_foreachid_process_flags_get(LibraryForeachIDData * data)103 int BKE_lib_query_foreachid_process_flags_get(LibraryForeachIDData *data)
104 {
105 return data->flag;
106 }
107
BKE_lib_query_foreachid_process_callback_flag_override(LibraryForeachIDData * data,const int cb_flag,const bool do_replace)108 int BKE_lib_query_foreachid_process_callback_flag_override(LibraryForeachIDData *data,
109 const int cb_flag,
110 const bool do_replace)
111 {
112 const int cb_flag_backup = data->cb_flag;
113 if (do_replace) {
114 data->cb_flag = cb_flag;
115 }
116 else {
117 data->cb_flag |= cb_flag;
118 }
119 return cb_flag_backup;
120 }
121
122 static void library_foreach_ID_link(Main *bmain,
123 ID *id_owner,
124 ID *id,
125 LibraryIDLinkCallback callback,
126 void *user_data,
127 int flag,
128 LibraryForeachIDData *inherit_data);
129
BKE_lib_query_idpropertiesForeachIDLink_callback(IDProperty * id_prop,void * user_data)130 void BKE_lib_query_idpropertiesForeachIDLink_callback(IDProperty *id_prop, void *user_data)
131 {
132 BLI_assert(id_prop->type == IDP_ID);
133
134 LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
135 BKE_LIB_FOREACHID_PROCESS_ID(data, id_prop->data.pointer, IDWALK_CB_USER);
136 }
137
BKE_library_foreach_ID_embedded(LibraryForeachIDData * data,ID ** id_pp)138 bool BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp)
139 {
140 /* Needed e.g. for callbacks handling relationships... This call shall be absolutely readonly. */
141 ID *id = *id_pp;
142 const int flag = data->flag;
143
144 if (!BKE_lib_query_foreachid_process(data, id_pp, IDWALK_CB_EMBEDDED)) {
145 return false;
146 }
147 BLI_assert(id == *id_pp);
148
149 if (id == NULL) {
150 return true;
151 }
152
153 if (flag & IDWALK_IGNORE_EMBEDDED_ID) {
154 /* Do Nothing. */
155 }
156 else if (flag & IDWALK_RECURSE) {
157 /* Defer handling into main loop, recursively calling BKE_library_foreach_ID_link in
158 * IDWALK_RECURSE case is troublesome, see T49553. */
159 /* XXX note that this breaks the 'owner id' thing now, we likely want to handle that
160 * differently at some point, but for now it should not be a problem in practice. */
161 if (BLI_gset_add(data->ids_handled, id)) {
162 BLI_LINKSTACK_PUSH(data->ids_todo, id);
163 }
164 }
165 else {
166 library_foreach_ID_link(
167 data->bmain, data->owner_id, id, data->callback, data->user_data, data->flag, data);
168 }
169
170 return true;
171 }
172
library_foreach_ID_link(Main * bmain,ID * id_owner,ID * id,LibraryIDLinkCallback callback,void * user_data,int flag,LibraryForeachIDData * inherit_data)173 static void library_foreach_ID_link(Main *bmain,
174 ID *id_owner,
175 ID *id,
176 LibraryIDLinkCallback callback,
177 void *user_data,
178 int flag,
179 LibraryForeachIDData *inherit_data)
180 {
181 LibraryForeachIDData data = {.bmain = bmain};
182
183 BLI_assert(inherit_data == NULL || data.bmain == inherit_data->bmain);
184
185 if (flag & IDWALK_RECURSE) {
186 /* For now, recursion implies read-only. */
187 flag |= IDWALK_READONLY;
188
189 data.ids_handled = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
190 BLI_LINKSTACK_INIT(data.ids_todo);
191
192 BLI_gset_add(data.ids_handled, id);
193 }
194 else {
195 data.ids_handled = NULL;
196 }
197 data.flag = flag;
198 data.status = 0;
199 data.callback = callback;
200 data.user_data = user_data;
201
202 #define CALLBACK_INVOKE_ID(check_id, cb_flag) \
203 BKE_LIB_FOREACHID_PROCESS_ID(&data, check_id, cb_flag)
204
205 #define CALLBACK_INVOKE(check_id_super, cb_flag) \
206 BKE_LIB_FOREACHID_PROCESS(&data, check_id_super, cb_flag)
207
208 for (; id != NULL; id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL) {
209 data.self_id = id;
210 /* Note that we may call this functions sometime directly on an embedded ID, without any
211 * knowledge of the owner ID then.
212 * While not great, and that should be probably sanitized at some point, we cal live with it
213 * for now. */
214 data.owner_id = ((id->flag & LIB_EMBEDDED_DATA) != 0 && id_owner != NULL) ? id_owner :
215 data.self_id;
216
217 /* inherit_data is non-NULL when this function is called for some sub-data ID
218 * (like root nodetree of a material).
219 * In that case, we do not want to generate those 'generic flags' from our current sub-data ID
220 * (the node tree), but re-use those generated for the 'owner' ID (the material). */
221 if (inherit_data == NULL) {
222 data.cb_flag = ID_IS_LINKED(id) ? IDWALK_CB_INDIRECT_USAGE : 0;
223 /* When an ID is not in Main database, it should never refcount IDs it is using.
224 * Exceptions: NodeTrees (yeah!) directly used by Materials. */
225 data.cb_flag_clear = (id->tag & LIB_TAG_NO_MAIN) ? IDWALK_CB_USER | IDWALK_CB_USER_ONE : 0;
226 }
227 else {
228 data.cb_flag = inherit_data->cb_flag;
229 data.cb_flag_clear = inherit_data->cb_flag_clear;
230 }
231
232 if (bmain != NULL && bmain->relations != NULL && (flag & IDWALK_READONLY) &&
233 (((bmain->relations->flag & MAINIDRELATIONS_INCLUDE_UI) == 0) ==
234 ((data.flag & IDWALK_INCLUDE_UI) == 0))) {
235 /* Note that this is minor optimization, even in worst cases (like id being an object with
236 * lots of drivers and constraints and modifiers, or material etc. with huge node tree),
237 * but we might as well use it (Main->relations is always assumed valid,
238 * it's responsibility of code creating it to free it,
239 * especially if/when it starts modifying Main database). */
240 MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->id_user_to_used, id);
241 for (; entry != NULL; entry = entry->next) {
242 BKE_lib_query_foreachid_process(&data, entry->id_pointer, entry->usage_flag);
243 }
244 continue;
245 }
246
247 /* Note: ID.lib pointer is purposefully fully ignored here...
248 * We may want to add it at some point? */
249
250 if (id->override_library != NULL) {
251 CALLBACK_INVOKE_ID(id->override_library->reference,
252 IDWALK_CB_USER | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE);
253 CALLBACK_INVOKE_ID(id->override_library->storage,
254 IDWALK_CB_USER | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE);
255 }
256
257 IDP_foreach_property(id->properties,
258 IDP_TYPE_FILTER_ID,
259 BKE_lib_query_idpropertiesForeachIDLink_callback,
260 &data);
261
262 AnimData *adt = BKE_animdata_from_id(id);
263 if (adt) {
264 BKE_animdata_foreach_id(adt, &data);
265 }
266
267 const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
268 if (id_type->foreach_id != NULL) {
269 id_type->foreach_id(id, &data);
270
271 if (data.status & IDWALK_STOP) {
272 break;
273 }
274 }
275 }
276
277 if (data.ids_handled) {
278 BLI_gset_free(data.ids_handled, NULL);
279 BLI_LINKSTACK_FREE(data.ids_todo);
280 }
281
282 #undef CALLBACK_INVOKE_ID
283 #undef CALLBACK_INVOKE
284 }
285
286 /**
287 * Loop over all of the ID's this data-block links to.
288 */
BKE_library_foreach_ID_link(Main * bmain,ID * id,LibraryIDLinkCallback callback,void * user_data,int flag)289 void BKE_library_foreach_ID_link(
290 Main *bmain, ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
291 {
292 library_foreach_ID_link(bmain, NULL, id, callback, user_data, flag, NULL);
293 }
294
295 /**
296 * re-usable function, use when replacing ID's
297 */
BKE_library_update_ID_link_user(ID * id_dst,ID * id_src,const int cb_flag)298 void BKE_library_update_ID_link_user(ID *id_dst, ID *id_src, const int cb_flag)
299 {
300 if (cb_flag & IDWALK_CB_USER) {
301 id_us_min(id_src);
302 id_us_plus(id_dst);
303 }
304 else if (cb_flag & IDWALK_CB_USER_ONE) {
305 id_us_ensure_real(id_dst);
306 }
307 }
308
309 /**
310 * Say whether given \a id_owner may use (in any way) a data-block of \a id_type_used.
311 *
312 * This is a 'simplified' abstract version of #BKE_library_foreach_ID_link() above,
313 * quite useful to reduce useless iterations in some cases.
314 */
BKE_library_id_can_use_idtype(ID * id_owner,const short id_type_used)315 bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
316 {
317 /* any type of ID can be used in custom props. */
318 if (id_owner->properties) {
319 return true;
320 }
321
322 const short id_type_owner = GS(id_owner->name);
323
324 /* IDProps of armature bones and nodes, and bNode->id can use virtually any type of ID. */
325 if (ELEM(id_type_owner, ID_NT, ID_AR)) {
326 return true;
327 }
328
329 if (ntreeFromID(id_owner)) {
330 return true;
331 }
332
333 if (BKE_animdata_from_id(id_owner)) {
334 /* AnimationData can use virtually any kind of data-blocks, through drivers especially. */
335 return true;
336 }
337
338 switch ((ID_Type)id_type_owner) {
339 case ID_LI:
340 return ELEM(id_type_used, ID_LI);
341 case ID_SCE:
342 return (ELEM(id_type_used,
343 ID_OB,
344 ID_WO,
345 ID_SCE,
346 ID_MC,
347 ID_MA,
348 ID_GR,
349 ID_TXT,
350 ID_LS,
351 ID_MSK,
352 ID_SO,
353 ID_GD,
354 ID_BR,
355 ID_PAL,
356 ID_IM,
357 ID_NT));
358 case ID_OB:
359 /* Could be more specific, but simpler to just always say 'yes' here. */
360 return true;
361 case ID_ME:
362 return ELEM(id_type_used, ID_ME, ID_KE, ID_MA, ID_IM);
363 case ID_CU:
364 return ELEM(id_type_used, ID_OB, ID_KE, ID_MA, ID_VF);
365 case ID_MB:
366 return ELEM(id_type_used, ID_MA);
367 case ID_MA:
368 return (ELEM(id_type_used, ID_TE, ID_GR));
369 case ID_TE:
370 return (ELEM(id_type_used, ID_IM, ID_OB));
371 case ID_LT:
372 return ELEM(id_type_used, ID_KE);
373 case ID_LA:
374 return (ELEM(id_type_used, ID_TE));
375 case ID_CA:
376 return ELEM(id_type_used, ID_OB);
377 case ID_KE:
378 /* Warning! key->from, could be more types in future? */
379 return ELEM(id_type_used, ID_ME, ID_CU, ID_LT);
380 case ID_SCR:
381 return ELEM(id_type_used, ID_SCE);
382 case ID_WO:
383 return (ELEM(id_type_used, ID_TE));
384 case ID_SPK:
385 return ELEM(id_type_used, ID_SO);
386 case ID_GR:
387 return ELEM(id_type_used, ID_OB, ID_GR);
388 case ID_NT:
389 /* Could be more specific, but node.id has no type restriction... */
390 return true;
391 case ID_BR:
392 return ELEM(id_type_used, ID_BR, ID_IM, ID_PC, ID_TE, ID_MA);
393 case ID_PA:
394 return ELEM(id_type_used, ID_OB, ID_GR, ID_TE);
395 case ID_MC:
396 return ELEM(id_type_used, ID_GD, ID_IM);
397 case ID_MSK:
398 /* WARNING! mask->parent.id, not typed. */
399 return ELEM(id_type_used, ID_MC);
400 case ID_LS:
401 return (ELEM(id_type_used, ID_TE, ID_OB));
402 case ID_LP:
403 return ELEM(id_type_used, ID_IM);
404 case ID_GD:
405 return ELEM(id_type_used, ID_MA);
406 case ID_WS:
407 return ELEM(id_type_used, ID_SCR, ID_SCE);
408 case ID_HA:
409 return ELEM(id_type_used, ID_MA);
410 case ID_PT:
411 return ELEM(id_type_used, ID_MA);
412 case ID_VO:
413 return ELEM(id_type_used, ID_MA);
414 case ID_SIM:
415 return ELEM(id_type_used, ID_OB, ID_IM);
416 case ID_IM:
417 case ID_VF:
418 case ID_TXT:
419 case ID_SO:
420 case ID_AR:
421 case ID_AC:
422 case ID_WM:
423 case ID_PAL:
424 case ID_PC:
425 case ID_CF:
426 /* Those types never use/reference other IDs... */
427 return false;
428 case ID_IP:
429 /* Deprecated... */
430 return false;
431 }
432 return false;
433 }
434
435 /* ***** ID users iterator. ***** */
436 typedef struct IDUsersIter {
437 ID *id;
438
439 ListBase *lb_array[MAX_LIBARRAY];
440 int lb_idx;
441
442 ID *curr_id;
443 int count_direct, count_indirect; /* Set by callback. */
444 } IDUsersIter;
445
foreach_libblock_id_users_callback(LibraryIDLinkCallbackData * cb_data)446 static int foreach_libblock_id_users_callback(LibraryIDLinkCallbackData *cb_data)
447 {
448 ID **id_p = cb_data->id_pointer;
449 const int cb_flag = cb_data->cb_flag;
450 IDUsersIter *iter = cb_data->user_data;
451
452 if (*id_p) {
453 /* 'Loopback' ID pointers (the ugly 'from' ones, Object->proxy_from and Key->from).
454 * Those are not actually ID usage, we can ignore them here.
455 */
456 if (cb_flag & IDWALK_CB_LOOPBACK) {
457 return IDWALK_RET_NOP;
458 }
459
460 if (*id_p == iter->id) {
461 #if 0
462 printf(
463 "%s uses %s (refcounted: %d, userone: %d, used_one: %d, used_one_active: %d, "
464 "indirect_usage: %d)\n",
465 iter->curr_id->name,
466 iter->id->name,
467 (cb_flag & IDWALK_USER) ? 1 : 0,
468 (cb_flag & IDWALK_USER_ONE) ? 1 : 0,
469 (iter->id->tag & LIB_TAG_EXTRAUSER) ? 1 : 0,
470 (iter->id->tag & LIB_TAG_EXTRAUSER_SET) ? 1 : 0,
471 (cb_flag & IDWALK_INDIRECT_USAGE) ? 1 : 0);
472 #endif
473 if (cb_flag & IDWALK_CB_INDIRECT_USAGE) {
474 iter->count_indirect++;
475 }
476 else {
477 iter->count_direct++;
478 }
479 }
480 }
481
482 return IDWALK_RET_NOP;
483 }
484
485 /**
486 * Return the number of times given \a id_user uses/references \a id_used.
487 *
488 * \note This only checks for pointer references of an ID, shallow usages
489 * (like e.g. by RNA paths, as done for FCurves) are not detected at all.
490 *
491 * \param id_user: the ID which is supposed to use (reference) \a id_used.
492 * \param id_used: the ID which is supposed to be used (referenced) by \a id_user.
493 * \return the number of direct usages/references of \a id_used by \a id_user.
494 */
BKE_library_ID_use_ID(ID * id_user,ID * id_used)495 int BKE_library_ID_use_ID(ID *id_user, ID *id_used)
496 {
497 IDUsersIter iter;
498
499 /* We do not care about iter.lb_array/lb_idx here... */
500 iter.id = id_used;
501 iter.curr_id = id_user;
502 iter.count_direct = iter.count_indirect = 0;
503
504 BKE_library_foreach_ID_link(
505 NULL, iter.curr_id, foreach_libblock_id_users_callback, (void *)&iter, IDWALK_READONLY);
506
507 return iter.count_direct + iter.count_indirect;
508 }
509
library_ID_is_used(Main * bmain,void * idv,const bool check_linked)510 static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked)
511 {
512 IDUsersIter iter;
513 ListBase *lb_array[MAX_LIBARRAY];
514 ID *id = idv;
515 int i = set_listbasepointers(bmain, lb_array);
516 bool is_defined = false;
517
518 iter.id = id;
519 iter.count_direct = iter.count_indirect = 0;
520 while (i-- && !is_defined) {
521 ID *id_curr = lb_array[i]->first;
522
523 if (!id_curr || !BKE_library_id_can_use_idtype(id_curr, GS(id->name))) {
524 continue;
525 }
526
527 for (; id_curr && !is_defined; id_curr = id_curr->next) {
528 if (id_curr == id) {
529 /* We are not interested in self-usages (mostly from drivers or bone constraints...). */
530 continue;
531 }
532 iter.curr_id = id_curr;
533 BKE_library_foreach_ID_link(
534 bmain, id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_READONLY);
535
536 is_defined = ((check_linked ? iter.count_indirect : iter.count_direct) != 0);
537 }
538 }
539
540 return is_defined;
541 }
542
543 /**
544 * Check whether given ID is used locally (i.e. by another non-linked ID).
545 */
BKE_library_ID_is_locally_used(Main * bmain,void * idv)546 bool BKE_library_ID_is_locally_used(Main *bmain, void *idv)
547 {
548 return library_ID_is_used(bmain, idv, false);
549 }
550
551 /**
552 * Check whether given ID is used indirectly (i.e. by another linked ID).
553 */
BKE_library_ID_is_indirectly_used(Main * bmain,void * idv)554 bool BKE_library_ID_is_indirectly_used(Main *bmain, void *idv)
555 {
556 return library_ID_is_used(bmain, idv, true);
557 }
558
559 /**
560 * Combine #BKE_library_ID_is_locally_used() and #BKE_library_ID_is_indirectly_used()
561 * in a single call.
562 */
BKE_library_ID_test_usages(Main * bmain,void * idv,bool * is_used_local,bool * is_used_linked)563 void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *is_used_local, bool *is_used_linked)
564 {
565 IDUsersIter iter;
566 ListBase *lb_array[MAX_LIBARRAY];
567 ID *id = idv;
568 int i = set_listbasepointers(bmain, lb_array);
569 bool is_defined = false;
570
571 iter.id = id;
572 iter.count_direct = iter.count_indirect = 0;
573 while (i-- && !is_defined) {
574 ID *id_curr = lb_array[i]->first;
575
576 if (!id_curr || !BKE_library_id_can_use_idtype(id_curr, GS(id->name))) {
577 continue;
578 }
579
580 for (; id_curr && !is_defined; id_curr = id_curr->next) {
581 if (id_curr == id) {
582 /* We are not interested in self-usages (mostly from drivers or bone constraints...). */
583 continue;
584 }
585 iter.curr_id = id_curr;
586 BKE_library_foreach_ID_link(
587 bmain, id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_READONLY);
588
589 is_defined = (iter.count_direct != 0 && iter.count_indirect != 0);
590 }
591 }
592
593 *is_used_local = (iter.count_direct != 0);
594 *is_used_linked = (iter.count_indirect != 0);
595 }
596
597 /* ***** IDs usages.checking/tagging. ***** */
foreach_libblock_used_linked_data_tag_clear_cb(LibraryIDLinkCallbackData * cb_data)598 static int foreach_libblock_used_linked_data_tag_clear_cb(LibraryIDLinkCallbackData *cb_data)
599 {
600 ID *self_id = cb_data->id_self;
601 ID **id_p = cb_data->id_pointer;
602 const int cb_flag = cb_data->cb_flag;
603 bool *is_changed = cb_data->user_data;
604
605 if (*id_p) {
606 /* The infamous 'from' pointers (Key.from, Object.proxy_from, ...).
607 * those are not actually ID usage, so we ignore them here. */
608 if (cb_flag & IDWALK_CB_LOOPBACK) {
609 return IDWALK_RET_NOP;
610 }
611
612 /* If checked id is used by an assumed used ID,
613 * then it is also used and not part of any linked archipelago. */
614 if (!(self_id->tag & LIB_TAG_DOIT) && ((*id_p)->tag & LIB_TAG_DOIT)) {
615 (*id_p)->tag &= ~LIB_TAG_DOIT;
616 *is_changed = true;
617 }
618 }
619
620 return IDWALK_RET_NOP;
621 }
622
623 /**
624 * Detect orphaned linked data blocks (i.e. linked data not used (directly or indirectly)
625 * in any way by any local data), including complex cases like 'linked archipelagoes', i.e.
626 * linked data-blocks that use each other in loops,
627 * which prevents their deletion by 'basic' usage checks.
628 *
629 * \param do_init_tag: if \a true, all linked data are checked, if \a false,
630 * only linked data-blocks already tagged with #LIB_TAG_DOIT are checked.
631 */
BKE_library_unused_linked_data_set_tag(Main * bmain,const bool do_init_tag)632 void BKE_library_unused_linked_data_set_tag(Main *bmain, const bool do_init_tag)
633 {
634 ID *id;
635
636 if (do_init_tag) {
637 FOREACH_MAIN_ID_BEGIN (bmain, id) {
638 if (id->lib && (id->tag & LIB_TAG_INDIRECT) != 0) {
639 id->tag |= LIB_TAG_DOIT;
640 }
641 else {
642 id->tag &= ~LIB_TAG_DOIT;
643 }
644 }
645 FOREACH_MAIN_ID_END;
646 }
647
648 for (bool do_loop = true; do_loop;) {
649 do_loop = false;
650 FOREACH_MAIN_ID_BEGIN (bmain, id) {
651 /* We only want to check that ID if it is currently known as used... */
652 if ((id->tag & LIB_TAG_DOIT) == 0) {
653 BKE_library_foreach_ID_link(
654 bmain, id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_READONLY);
655 }
656 }
657 FOREACH_MAIN_ID_END;
658 }
659 }
660
661 /**
662 * Untag linked data blocks used by other untagged linked data-blocks.
663 * Used to detect data-blocks that we can forcefully make local
664 * (instead of copying them to later get rid of original):
665 * All data-blocks we want to make local are tagged by caller,
666 * after this function has ran caller knows data-blocks still tagged can directly be made local,
667 * since they are only used by other data-blocks that will also be made fully local.
668 */
BKE_library_indirectly_used_data_tag_clear(Main * bmain)669 void BKE_library_indirectly_used_data_tag_clear(Main *bmain)
670 {
671 ListBase *lb_array[MAX_LIBARRAY];
672
673 bool do_loop = true;
674 while (do_loop) {
675 int i = set_listbasepointers(bmain, lb_array);
676 do_loop = false;
677
678 while (i--) {
679 LISTBASE_FOREACH (ID *, id, lb_array[i]) {
680 if (id->lib == NULL || id->tag & LIB_TAG_DOIT) {
681 /* Local or non-indirectly-used ID (so far), no need to check it further. */
682 continue;
683 }
684 BKE_library_foreach_ID_link(
685 bmain, id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_READONLY);
686 }
687 }
688 }
689 }
690