Blender  V2.93
lib_remap.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 
23 #include "CLG_log.h"
24 
25 #include "BLI_utildefines.h"
26 
27 #include "DNA_collection_types.h"
28 #include "DNA_object_types.h"
29 
30 #include "BKE_armature.h"
31 #include "BKE_collection.h"
32 #include "BKE_curve.h"
33 #include "BKE_layer.h"
34 #include "BKE_lib_id.h"
35 #include "BKE_lib_query.h"
36 #include "BKE_lib_remap.h"
37 #include "BKE_main.h"
38 #include "BKE_material.h"
39 #include "BKE_mball.h"
40 #include "BKE_modifier.h"
41 #include "BKE_multires.h"
42 #include "BKE_node.h"
43 #include "BKE_object.h"
44 
45 #include "DEG_depsgraph.h"
46 #include "DEG_depsgraph_build.h"
47 
48 #include "lib_intern.h" /* own include */
49 
50 static CLG_LogRef LOG = {.identifier = "bke.lib_remap"};
51 
53 
55 {
57 }
58 
60 
63 {
65 }
66 
67 typedef struct IDRemap {
68  Main *bmain; /* Only used to trigger depsgraph updates in the right bmain. */
73  short flag;
74 
75  /* 'Output' data. */
76  short status;
84 
85 /* IDRemap->flag enums defined in BKE_lib.h */
86 
87 /* IDRemap->status */
88 enum {
89  /* *** Set by callback. *** */
90  ID_REMAP_IS_LINKED_DIRECT = 1 << 0, /* new_id is directly linked in current .blend. */
91  ID_REMAP_IS_USER_ONE_SKIPPED = 1 << 1, /* There was some skipped 'user_one' usages of old_id. */
92 };
93 
95 {
96  const int cb_flag = cb_data->cb_flag;
97 
98  if (cb_flag & IDWALK_CB_EMBEDDED) {
99  return IDWALK_RET_NOP;
100  }
101 
102  ID *id_owner = cb_data->id_owner;
103  ID *id_self = cb_data->id_self;
104  ID **id_p = cb_data->id_pointer;
105  IDRemap *id_remap_data = cb_data->user_data;
106  ID *old_id = id_remap_data->old_id;
107  ID *new_id = id_remap_data->new_id;
108 
109  /* Those asserts ensure the general sanity of ID tags regarding 'embedded' ID data (root
110  * nodetrees and co). */
111  BLI_assert(id_owner == id_remap_data->id_owner);
112  BLI_assert(id_self == id_owner || (id_self->flag & LIB_EMBEDDED_DATA) != 0);
113 
114  if (!old_id) { /* Used to cleanup all IDs used by a specific one. */
115  BLI_assert(!new_id);
116  old_id = *id_p;
117  }
118 
119  if (*id_p && (*id_p == old_id)) {
120  /* Better remap to NULL than not remapping at all,
121  * then we can handle it as a regular remap-to-NULL case. */
122  if ((cb_flag & IDWALK_CB_NEVER_SELF) && (new_id == id_self)) {
123  new_id = NULL;
124  }
125 
126  const bool is_reference = (cb_flag & IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE) != 0;
127  const bool is_indirect = (cb_flag & IDWALK_CB_INDIRECT_USAGE) != 0;
128  const bool skip_indirect = (id_remap_data->flag & ID_REMAP_SKIP_INDIRECT_USAGE) != 0;
129  /* Note: proxy usage implies LIB_TAG_EXTERN, so on this aspect it is direct,
130  * on the other hand since they get reset to lib data on file open/reload it is indirect too.
131  * Edit Mode is also a 'skip direct' case. */
132  const bool is_obj = (GS(id_owner->name) == ID_OB);
133  const bool is_obj_proxy = (is_obj &&
134  (((Object *)id_owner)->proxy || ((Object *)id_owner)->proxy_group));
135  const bool is_obj_editmode = (is_obj && BKE_object_is_in_editmode((Object *)id_owner));
136  const bool is_never_null = ((cb_flag & IDWALK_CB_NEVER_NULL) && (new_id == NULL) &&
137  (id_remap_data->flag & ID_REMAP_FORCE_NEVER_NULL_USAGE) == 0);
138  const bool skip_reference = (id_remap_data->flag & ID_REMAP_SKIP_OVERRIDE_LIBRARY) != 0;
139  const bool skip_never_null = (id_remap_data->flag & ID_REMAP_SKIP_NEVER_NULL_USAGE) != 0;
140 
141 #ifdef DEBUG_PRINT
142  printf(
143  "In %s (lib %p): Remapping %s (%p) to %s (%p) "
144  "(is_indirect: %d, skip_indirect: %d, is_reference: %d, skip_reference: %d)\n",
145  id->name,
146  id->lib,
147  old_id->name,
148  old_id,
149  new_id ? new_id->name : "<NONE>",
150  new_id,
151  is_indirect,
152  skip_indirect,
153  is_reference,
154  skip_reference);
155 #endif
156 
157  if ((id_remap_data->flag & ID_REMAP_FLAG_NEVER_NULL_USAGE) &&
158  (cb_flag & IDWALK_CB_NEVER_NULL)) {
159  id_owner->tag |= LIB_TAG_DOIT;
160  }
161 
162  /* Special hack in case it's Object->data and we are in edit mode, and new_id is not NULL
163  * (otherwise, we follow common NEVER_NULL flags).
164  * (skipped_indirect too). */
165  if ((is_never_null && skip_never_null) ||
166  (is_obj_editmode && (((Object *)id_owner)->data == *id_p) && new_id != NULL) ||
167  (skip_indirect && is_indirect) || (is_reference && skip_reference)) {
168  if (is_indirect) {
169  id_remap_data->skipped_indirect++;
170  if (is_obj) {
171  Object *ob = (Object *)id_owner;
172  if (ob->data == *id_p && ob->proxy != NULL) {
173  /* And another 'Proudly brought to you by Proxy Hell' hack!
174  * This will allow us to avoid clearing 'LIB_EXTERN' flag of obdata of proxies... */
175  id_remap_data->skipped_direct++;
176  }
177  }
178  }
179  else if (is_never_null || is_obj_editmode || is_reference) {
180  id_remap_data->skipped_direct++;
181  }
182  else {
183  BLI_assert(0);
184  }
185  if (cb_flag & IDWALK_CB_USER) {
186  id_remap_data->skipped_refcounted++;
187  }
188  else if (cb_flag & IDWALK_CB_USER_ONE) {
189  /* No need to count number of times this happens, just a flag is enough. */
190  id_remap_data->status |= ID_REMAP_IS_USER_ONE_SKIPPED;
191  }
192  }
193  else {
194  if (!is_never_null) {
195  *id_p = new_id;
196  DEG_id_tag_update_ex(id_remap_data->bmain,
197  id_self,
199  if (id_self != id_owner) {
200  DEG_id_tag_update_ex(id_remap_data->bmain,
201  id_owner,
203  }
204  }
205  if (cb_flag & IDWALK_CB_USER) {
206  /* NOTE: We don't user-count IDs which are not in the main database.
207  * This is because in certain conditions we can have data-blocks in
208  * the main which are referencing data-blocks outside of it.
209  * For example, BKE_mesh_new_from_object() called on an evaluated
210  * object will cause such situation.
211  */
212  if ((old_id->tag & LIB_TAG_NO_MAIN) == 0) {
213  id_us_min(old_id);
214  }
215  if (new_id != NULL && (new_id->tag & LIB_TAG_NO_MAIN) == 0) {
216  /* We do not want to handle LIB_TAG_INDIRECT/LIB_TAG_EXTERN here. */
217  new_id->us++;
218  }
219  }
220  else if (cb_flag & IDWALK_CB_USER_ONE) {
221  id_us_ensure_real(new_id);
222  /* We cannot affect old_id->us directly, LIB_TAG_EXTRAUSER(_SET)
223  * are assumed to be set as needed, that extra user is processed in final handling. */
224  }
225  if (!is_indirect || is_obj_proxy) {
226  id_remap_data->status |= ID_REMAP_IS_LINKED_DIRECT;
227  }
228  /* We need to remap proxy_from pointer of remapped proxy... sigh. */
229  if (is_obj_proxy && new_id != NULL) {
230  Object *ob = (Object *)id_owner;
231  if (ob->proxy == (Object *)new_id) {
232  ob->proxy->proxy_from = ob;
233  }
234  }
235  }
236  }
237 
238  return IDWALK_RET_NOP;
239 }
240 
241 static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
242 {
243  switch (GS(r_id_remap_data->id_owner->name)) {
244  case ID_OB: {
245  ID *old_id = r_id_remap_data->old_id;
246  if (!old_id || GS(old_id->name) == ID_AR) {
247  Object *ob = (Object *)r_id_remap_data->id_owner;
248  /* Object's pose holds reference to armature bones. sic */
249  /* Note that in theory, we should have to bother about linked/non-linked/never-null/etc.
250  * flags/states.
251  * Fortunately, this is just a tag, so we can accept to 'over-tag' a bit for pose recalc,
252  * and avoid another complex and risky condition nightmare like the one we have in
253  * foreach_libblock_remap_callback(). */
254  if (ob->pose && (!old_id || ob->data == old_id)) {
255  BLI_assert(ob->type == OB_ARMATURE);
256  ob->pose->flag |= POSE_RECALC;
257  /* We need to clear pose bone pointers immediately, some code may access those before
258  * pose is actually recomputed, which can lead to segfault. */
260  }
261  }
262  break;
263  }
264  default:
265  break;
266  }
267 }
268 
274  Object *old_ob,
275  Object *new_ob)
276 {
277  if (new_ob == NULL) {
278  /* In case we unlinked old_ob (new_ob is NULL), the object has already
279  * been removed from the scenes and their collections. We still have
280  * to remove the NULL children from collections not used in any scene. */
282  }
283 
285 
286  if (old_ob == NULL) {
287  for (Object *ob = bmain->objects.first; ob != NULL; ob = ob->id.next) {
288  if (ob->type == OB_MBALL && BKE_mball_is_basis(ob)) {
290  }
291  }
292  }
293  else {
294  for (Object *ob = bmain->objects.first; ob != NULL; ob = ob->id.next) {
295  if (ob->type == OB_MBALL && BKE_mball_is_basis_for(ob, old_ob)) {
297  break; /* There is only one basis... */
298  }
299  }
300  }
301 }
302 
303 /* Can be called with both old_collection and new_collection being NULL,
304  * this means we have to check whole Main database then. */
306  Collection *owner_collection,
307  Collection *UNUSED(old_collection),
308  Collection *new_collection)
309 {
310  if (new_collection == NULL) {
311  /* XXX Complex cases can lead to NULL pointers in other collections than old_collection,
312  * and BKE_main_collection_sync_remap() does not tolerate any of those, so for now always check
313  * whole existing collections for NULL pointers.
314  * I'd consider optimizing that whole collection remapping process a TODO for later. */
315  BKE_collections_child_remove_nulls(bmain, owner_collection, NULL /*old_collection*/);
316  }
317  else {
318  /* Temp safe fix, but a "tad" brute force... We should probably be able to use parents from
319  * old_collection instead? */
321  }
322 
324 }
325 
327 {
328  if (ob->data == new_id) {
329  switch (GS(new_id->name)) {
330  case ID_ME:
332  break;
333  case ID_CU:
335  break;
336  default:
337  break;
338  }
340  BKE_object_materials_test(bmain, ob, new_id);
341  }
342 }
343 
345 {
346  /* Update all group nodes using a node group. */
347  ntreeUpdateAllUsers(bmain, new_id);
348 }
349 
372 ATTR_NONNULL(1)
374  Main *bmain, ID *id, ID *old_id, ID *new_id, const short remap_flags, IDRemap *r_id_remap_data)
375 {
376  IDRemap id_remap_data;
377  const int foreach_id_flags = ((remap_flags & ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE) != 0 ?
379  IDWALK_NOP) |
380  ((remap_flags & ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS) != 0 ?
382  IDWALK_NOP);
383 
384  if (r_id_remap_data == NULL) {
385  r_id_remap_data = &id_remap_data;
386  }
387  r_id_remap_data->bmain = bmain;
388  r_id_remap_data->old_id = old_id;
389  r_id_remap_data->new_id = new_id;
390  r_id_remap_data->id_owner = NULL;
391  r_id_remap_data->flag = remap_flags;
392  r_id_remap_data->status = 0;
393  r_id_remap_data->skipped_direct = 0;
394  r_id_remap_data->skipped_indirect = 0;
395  r_id_remap_data->skipped_refcounted = 0;
396 
397  if (id) {
398 #ifdef DEBUG_PRINT
399  printf("\tchecking id %s (%p, %p)\n", id->name, id, id->lib);
400 #endif
401  r_id_remap_data->id_owner = id;
402  libblock_remap_data_preprocess(r_id_remap_data);
404  NULL, id, foreach_libblock_remap_callback, (void *)r_id_remap_data, foreach_id_flags);
405  }
406  else {
407  /* Note that this is a very 'brute force' approach,
408  * maybe we could use some depsgraph to only process objects actually using given old_id...
409  * sounds rather unlikely currently, though, so this will do for now. */
410  ID *id_curr;
411 
412  FOREACH_MAIN_ID_BEGIN (bmain, id_curr) {
413  if (BKE_library_id_can_use_idtype(id_curr, GS(old_id->name))) {
414  /* Note that we cannot skip indirect usages of old_id here (if requested),
415  * we still need to check it for the user count handling...
416  * XXX No more true (except for debug usage of those skipping counters). */
417  r_id_remap_data->id_owner = id_curr;
418  libblock_remap_data_preprocess(r_id_remap_data);
420  id_curr,
422  (void *)r_id_remap_data,
423  foreach_id_flags);
424  }
425  }
427  }
428 
429  if ((remap_flags & ID_REMAP_SKIP_USER_CLEAR) == 0) {
430  /* XXX We may not want to always 'transfer' fake-user from old to new id...
431  * Think for now it's desired behavior though,
432  * we can always add an option (flag) to control this later if needed. */
433  if (old_id && (old_id->flag & LIB_FAKEUSER)) {
434  id_fake_user_clear(old_id);
435  id_fake_user_set(new_id);
436  }
437 
438  id_us_clear_real(old_id);
439  }
440 
441  if (new_id && (new_id->tag & LIB_TAG_INDIRECT) &&
442  (r_id_remap_data->status & ID_REMAP_IS_LINKED_DIRECT)) {
443  new_id->tag &= ~LIB_TAG_INDIRECT;
444  new_id->flag &= ~LIB_INDIRECT_WEAK_LINK;
445  new_id->tag |= LIB_TAG_EXTERN;
446  }
447 
448 #ifdef DEBUG_PRINT
449  printf("%s: %d occurrences skipped (%d direct and %d indirect ones)\n",
450  __func__,
451  r_id_remap_data->skipped_direct + r_id_remap_data->skipped_indirect,
452  r_id_remap_data->skipped_direct,
453  r_id_remap_data->skipped_indirect);
454 #endif
455 }
456 
461 void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, const short remap_flags)
462 {
463  IDRemap id_remap_data;
464  ID *old_id = old_idv;
465  ID *new_id = new_idv;
466  int skipped_direct, skipped_refcounted;
467 
468  BLI_assert(old_id != NULL);
469  BLI_assert((new_id == NULL) || GS(old_id->name) == GS(new_id->name));
470  BLI_assert(old_id != new_id);
471 
472  libblock_remap_data(bmain, NULL, old_id, new_id, remap_flags, &id_remap_data);
473 
476  }
477 
478  /* We assume editors do not hold references to their IDs... This is false in some cases
479  * (Image is especially tricky here),
480  * editors' code is to handle refcount (id->us) itself then. */
482  remap_editor_id_reference_cb(old_id, new_id);
483  }
484 
485  skipped_direct = id_remap_data.skipped_direct;
486  skipped_refcounted = id_remap_data.skipped_refcounted;
487 
488  if ((remap_flags & ID_REMAP_SKIP_USER_CLEAR) == 0) {
489  /* If old_id was used by some ugly 'user_one' stuff (like Image or Clip editors...), and user
490  * count has actually been incremented for that, we have to decrease once more its user
491  * count... unless we had to skip some 'user_one' cases. */
492  if ((old_id->tag & LIB_TAG_EXTRAUSER_SET) &&
493  !(id_remap_data.status & ID_REMAP_IS_USER_ONE_SKIPPED)) {
494  id_us_clear_real(old_id);
495  }
496  }
497 
498  if (old_id->us - skipped_refcounted < 0) {
499  CLOG_ERROR(&LOG,
500  "Error in remapping process from '%s' (%p) to '%s' (%p): "
501  "wrong user count in old ID after process (summing up to %d)",
502  old_id->name,
503  old_id,
504  new_id ? new_id->name : "<NULL>",
505  new_id,
506  old_id->us - skipped_refcounted);
507  BLI_assert(0);
508  }
509 
510  if (skipped_direct == 0) {
511  /* old_id is assumed to not be used directly anymore... */
512  if (old_id->lib && (old_id->tag & LIB_TAG_EXTERN)) {
513  old_id->tag &= ~LIB_TAG_EXTERN;
514  old_id->tag |= LIB_TAG_INDIRECT;
515  }
516  }
517 
518  /* Some after-process updates.
519  * This is a bit ugly, but cannot see a way to avoid it.
520  * Maybe we should do a per-ID callback for this instead? */
521  switch (GS(old_id->name)) {
522  case ID_OB:
523  libblock_remap_data_postprocess_object_update(bmain, (Object *)old_id, (Object *)new_id);
524  break;
525  case ID_GR:
527  bmain, NULL, (Collection *)old_id, (Collection *)new_id);
528  break;
529  case ID_ME:
530  case ID_CU:
531  case ID_MB:
532  case ID_HA:
533  case ID_PT:
534  case ID_VO:
535  if (new_id) { /* Only affects us in case obdata was relinked (changed). */
536  for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
538  }
539  }
540  break;
541  default:
542  break;
543  }
544 
545  /* Node trees may virtually use any kind of data-block... */
546  /* XXX Yuck!!!! nodetree update can do pretty much any thing when talking about py nodes,
547  * including creating new data-blocks (see T50385), so we need to unlock main here. :(
548  * Why can't we have re-entrent locks? */
549  BKE_main_unlock(bmain);
551  BKE_main_lock(bmain);
552 
553  /* Full rebuild of DEG! */
555 }
556 
557 void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, const short remap_flags)
558 {
559  BKE_main_lock(bmain);
560 
561  BKE_libblock_remap_locked(bmain, old_idv, new_idv, remap_flags);
562 
563  BKE_main_unlock(bmain);
564 }
565 
574  void *idv,
575  const bool do_flag_never_null,
576  const bool do_skip_indirect)
577 {
578  const short remap_flags = (do_skip_indirect ? ID_REMAP_SKIP_INDIRECT_USAGE : 0) |
579  (do_flag_never_null ? ID_REMAP_FLAG_NEVER_NULL_USAGE : 0);
580 
581  BKE_main_lock(bmain);
582 
583  BKE_libblock_remap_locked(bmain, idv, NULL, remap_flags);
584 
585  BKE_main_unlock(bmain);
586 }
587 
597 /* Should be able to replace all _relink() funcs (constraints, rigidbody, etc.) ? */
598 /* XXX Arg! Naming... :(
599  * _relink? avoids confusion with _remap, but is confusing with _unlink
600  * _remap_used_ids?
601  * _remap_datablocks?
602  * BKE_id_remap maybe?
603  * ... sigh
604  */
606  Main *bmain, void *idv, void *old_idv, void *new_idv, const short remap_flags)
607 {
608  ID *id = idv;
609  ID *old_id = old_idv;
610  ID *new_id = new_idv;
611 
612  /* No need to lock here, we are only affecting given ID, not bmain database. */
613 
614  BLI_assert(id);
615  if (old_id) {
616  BLI_assert((new_id == NULL) || GS(old_id->name) == GS(new_id->name));
617  BLI_assert(old_id != new_id);
618  }
619  else {
620  BLI_assert(new_id == NULL);
621  }
622 
623  libblock_remap_data(bmain, id, old_id, new_id, remap_flags, NULL);
624 
625  /* Some after-process updates.
626  * This is a bit ugly, but cannot see a way to avoid it.
627  * Maybe we should do a per-ID callback for this instead?
628  */
629  switch (GS(id->name)) {
630  case ID_SCE:
631  case ID_GR: {
632  /* Note: here we know which collection we have affected, so at lest for NULL children
633  * detection we can only process that one.
634  * This is also a required fix in case `id` would not be in Main anymore, which can happen
635  * e.g. when called from `id_delete`. */
636  Collection *owner_collection = (GS(id->name) == ID_GR) ? (Collection *)id :
637  ((Scene *)id)->master_collection;
638  if (old_id) {
639  switch (GS(old_id->name)) {
640  case ID_OB:
642  bmain, (Object *)old_id, (Object *)new_id);
643  break;
644  case ID_GR:
646  bmain, owner_collection, (Collection *)old_id, (Collection *)new_id);
647  break;
648  default:
649  break;
650  }
651  }
652  else {
653  /* No choice but to check whole objects/collections. */
656  }
657  break;
658  }
659  case ID_OB:
660  if (new_id) { /* Only affects us in case obdata was relinked (changed). */
662  }
663  break;
664  default:
665  break;
666  }
667 
669 }
670 
672 {
673  const int cb_flag = cb_data->cb_flag;
674  if (cb_flag & IDWALK_CB_EMBEDDED) {
675  return IDWALK_RET_NOP;
676  }
677 
678  ID **id_pointer = cb_data->id_pointer;
679  ID *id = *id_pointer;
680  if (id) {
681  /* See: NEW_ID macro */
682  if (id->newid) {
684  id = id->newid;
685  *id_pointer = id;
686  }
687  if (id->tag & LIB_TAG_NEW) {
688  id->tag &= ~LIB_TAG_NEW;
690  }
691  }
692  return IDWALK_RET_NOP;
693 }
694 
703 {
704  if (ID_IS_LINKED(id)) {
705  return;
706  }
707 
709 }
void BKE_pose_clear_pointers(struct bPose *pose)
Definition: armature.c:2490
void BKE_collections_child_remove_nulls(struct Main *bmain, struct Collection *parent_collection, struct Collection *child_collection)
Definition: collection.c:1318
void BKE_collections_object_remove_nulls(struct Main *bmain)
Definition: collection.c:1271
void BKE_main_collections_parent_relations_rebuild(struct Main *bmain)
Definition: collection.c:1671
void BKE_curve_type_test(struct Object *ob)
Definition: curve.c:484
void BKE_main_collection_sync_remap(const struct Main *bmain)
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void id_fake_user_set(struct ID *id)
Definition: lib_id.c:328
void id_us_ensure_real(struct ID *id)
Definition: lib_id.c:238
void id_us_clear_real(struct ID *id)
Definition: lib_id.c:257
void id_fake_user_clear(struct ID *id)
Definition: lib_id.c:336
@ IDWALK_NOP
@ IDWALK_NO_INDIRECT_PROXY_DATA_USAGE
@ IDWALK_DO_INTERNAL_RUNTIME_POINTERS
void BKE_library_foreach_ID_link(struct Main *bmain, struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
Definition: lib_query.c:322
@ IDWALK_RET_NOP
Definition: BKE_lib_query.h:97
@ IDWALK_CB_NEVER_SELF
Definition: BKE_lib_query.h:49
@ IDWALK_CB_USER_ONE
Definition: BKE_lib_query.h:93
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:87
@ IDWALK_CB_EMBEDDED
Definition: BKE_lib_query.h:62
@ IDWALK_CB_NEVER_NULL
Definition: BKE_lib_query.h:48
@ IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE
Definition: BKE_lib_query.h:71
@ IDWALK_CB_INDIRECT_USAGE
Definition: BKE_lib_query.h:55
bool BKE_library_id_can_use_idtype(struct ID *id_owner, const short id_type_used)
Definition: lib_query.c:348
void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, const int cb_flag)
Definition: lib_query.c:331
void(* BKE_library_free_notifier_reference_cb)(const void *)
void(* BKE_library_remap_editor_id_reference_cb)(struct ID *, struct ID *)
@ ID_REMAP_SKIP_USER_CLEAR
Definition: BKE_lib_remap.h:80
@ ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS
Definition: BKE_lib_remap.h:87
@ ID_REMAP_SKIP_OVERRIDE_LIBRARY
Definition: BKE_lib_remap.h:78
@ ID_REMAP_SKIP_NEVER_NULL_USAGE
Definition: BKE_lib_remap.h:55
@ ID_REMAP_FLAG_NEVER_NULL_USAGE
Definition: BKE_lib_remap.h:60
@ ID_REMAP_SKIP_INDIRECT_USAGE
Definition: BKE_lib_remap.h:46
@ ID_REMAP_FORCE_NEVER_NULL_USAGE
Definition: BKE_lib_remap.h:67
@ ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE
Definition: BKE_lib_remap.h:76
#define FOREACH_MAIN_ID_END
Definition: BKE_main.h:250
void BKE_main_unlock(struct Main *bmain)
Definition: main.c:207
void BKE_main_lock(struct Main *bmain)
Definition: main.c:202
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition: BKE_main.h:244
General operations, lookup, etc. for materials.
void BKE_object_materials_test(struct Main *bmain, struct Object *ob, struct ID *id)
Definition: material.c:772
bool BKE_mball_is_basis_for(struct Object *ob1, struct Object *ob2)
Definition: mball.c:406
bool BKE_mball_is_basis(struct Object *ob)
Test, if ob is a basis meta-ball.
Definition: mball.c:398
void BKE_modifiers_test_object(struct Object *ob)
void multires_force_sculpt_rebuild(struct Object *object)
Definition: multires.c:456
void ntreeUpdateAllUsers(struct Main *main, struct ID *id)
Definition: node.cc:4219
General operations, lookup, etc. for blender objects.
bool BKE_object_is_in_editmode(const struct Object *ob)
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define ATTR_NONNULL(...)
#define UNUSED(x)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:204
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_RECALC_TRANSFORM
Definition: DNA_ID.h:599
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ LIB_TAG_EXTRAUSER_SET
Definition: DNA_ID.h:547
@ LIB_TAG_INDIRECT
Definition: DNA_ID.h:524
@ LIB_TAG_NEW
Definition: DNA_ID.h:551
@ LIB_TAG_DOIT
Definition: DNA_ID.h:554
@ LIB_TAG_EXTERN
Definition: DNA_ID.h:521
@ LIB_TAG_NO_MAIN
Definition: DNA_ID.h:572
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
@ LIB_EMBEDDED_DATA
Definition: DNA_ID.h:482
@ LIB_FAKEUSER
Definition: DNA_ID.h:477
@ LIB_INDIRECT_WEAK_LINK
Definition: DNA_ID.h:488
@ ID_AR
Definition: DNA_ID_enums.h:78
@ ID_VO
Definition: DNA_ID_enums.h:95
@ ID_SCE
Definition: DNA_ID_enums.h:57
@ ID_HA
Definition: DNA_ID_enums.h:93
@ ID_ME
Definition: DNA_ID_enums.h:60
@ ID_GR
Definition: DNA_ID_enums.h:77
@ ID_MB
Definition: DNA_ID_enums.h:62
@ ID_OB
Definition: DNA_ID_enums.h:59
@ ID_PT
Definition: DNA_ID_enums.h:94
@ ID_CU
Definition: DNA_ID_enums.h:61
@ POSE_RECALC
Object groups, one object can be in many groups at once.
Object is a sort of wrapper for general info.
@ OB_MBALL
@ OB_ARMATURE
#define GS(x)
Definition: iris.c:241
static void libblock_remap_data_postprocess_collection_update(Main *bmain, Collection *owner_collection, Collection *UNUSED(old_collection), Collection *new_collection)
Definition: lib_remap.c:305
BKE_library_remap_editor_id_reference_cb remap_editor_id_reference_cb
Definition: lib_remap.c:59
static int id_relink_to_newid_looper(LibraryIDLinkCallbackData *cb_data)
Definition: lib_remap.c:671
void BKE_library_callback_remap_editor_id_reference_set(BKE_library_remap_editor_id_reference_cb func)
Definition: lib_remap.c:61
struct IDRemap IDRemap
void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, const short remap_flags)
Definition: lib_remap.c:557
void BKE_libblock_relink_ex(Main *bmain, void *idv, void *old_idv, void *new_idv, const short remap_flags)
Definition: lib_remap.c:605
void BKE_libblock_unlink(Main *bmain, void *idv, const bool do_flag_never_null, const bool do_skip_indirect)
Definition: lib_remap.c:573
@ ID_REMAP_IS_LINKED_DIRECT
Definition: lib_remap.c:90
@ ID_REMAP_IS_USER_ONE_SKIPPED
Definition: lib_remap.c:91
static void libblock_remap_data_postprocess_object_update(Main *bmain, Object *old_ob, Object *new_ob)
Definition: lib_remap.c:273
static void libblock_remap_data(Main *bmain, ID *id, ID *old_id, ID *new_id, const short remap_flags, IDRemap *r_id_remap_data)
Definition: lib_remap.c:373
void BKE_library_callback_free_notifier_reference_set(BKE_library_free_notifier_reference_cb func)
Definition: lib_remap.c:54
static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
Definition: lib_remap.c:241
void BKE_libblock_relink_to_newid(ID *id)
Definition: lib_remap.c:702
static void libblock_remap_data_postprocess_obdata_relink(Main *bmain, Object *ob, ID *new_id)
Definition: lib_remap.c:326
void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, const short remap_flags)
Definition: lib_remap.c:461
static CLG_LogRef LOG
Definition: lib_remap.c:50
BKE_library_free_notifier_reference_cb free_notifier_reference_cb
Definition: lib_remap.c:52
static int foreach_libblock_remap_callback(LibraryIDLinkCallbackData *cb_data)
Definition: lib_remap.c:94
static void libblock_remap_data_postprocess_nodetree_update(Main *bmain, ID *new_id)
Definition: lib_remap.c:344
const char * identifier
Definition: CLG_log.h:119
ID * old_id
Definition: lib_remap.c:69
short status
Definition: lib_remap.c:76
ID * new_id
Definition: lib_remap.c:70
short flag
Definition: lib_remap.c:73
ID * id_owner
Definition: lib_remap.c:72
int skipped_indirect
Definition: lib_remap.c:80
Main * bmain
Definition: lib_remap.c:68
int skipped_direct
Definition: lib_remap.c:78
int skipped_refcounted
Definition: lib_remap.c:82
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
short flag
Definition: DNA_ID.h:288
char name[66]
Definition: DNA_ID.h:283
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase objects
Definition: BKE_main.h:148
struct bPose * pose
struct Object * proxy_from
struct Object * proxy
void * data
short flag