Blender  V3.3
lib_override_proxy_conversion.c
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 "CLG_log.h"
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_linklist.h"
13 
14 /* Required for proxy to liboverrides conversion code. */
15 #define DNA_DEPRECATED_ALLOW
16 
17 #include "DNA_ID.h"
18 #include "DNA_collection_types.h"
19 #include "DNA_object_types.h"
20 #include "DNA_scene_types.h"
21 
22 #include "DEG_depsgraph.h"
23 
24 #include "BKE_collection.h"
25 #include "BKE_idtype.h"
26 #include "BKE_lib_id.h"
27 #include "BKE_lib_override.h"
28 #include "BKE_main.h"
29 
30 #include "BLO_readfile.h"
31 
32 static CLG_LogRef LOG = {"bke.liboverride_proxy_conversion"};
33 
35  Scene *scene,
36  ViewLayer *view_layer,
37  Object *ob_proxy)
38 {
39  /* `proxy_group`, if defined, is the empty instantiating the collection from which the proxy is
40  * coming. */
41  Object *ob_proxy_group = ob_proxy->proxy_group;
42  const bool is_override_instancing_object = (ob_proxy_group != NULL) &&
43  (ob_proxy_group->instance_collection != NULL);
44  ID *id_root = is_override_instancing_object ? &ob_proxy_group->instance_collection->id :
45  &ob_proxy->proxy->id;
46  ID *id_instance_hint = is_override_instancing_object ? &ob_proxy_group->id : &ob_proxy->id;
47 
48  /* In some cases the instance collection of a proxy object may be local (see e.g. T83875). Not
49  * sure this is a valid state, but for now just abort the overriding process. */
51  if (ob_proxy->proxy != NULL) {
52  ob_proxy->proxy->proxy_from = NULL;
53  }
54  id_us_min((ID *)ob_proxy->proxy);
55  ob_proxy->proxy = ob_proxy->proxy_group = NULL;
56  return false;
57  }
58 
59  /* We manually convert the proxy object into a library override, further override handling will
60  * then be handled by `BKE_lib_override_library_create()` just as for a regular override
61  * creation.
62  */
63  ob_proxy->proxy->id.tag |= LIB_TAG_DOIT;
64  ob_proxy->proxy->id.newid = &ob_proxy->id;
65  BKE_lib_override_library_init(&ob_proxy->id, &ob_proxy->proxy->id);
67 
68  ob_proxy->proxy->proxy_from = NULL;
69  ob_proxy->proxy = ob_proxy->proxy_group = NULL;
70 
72 
73  /* In case of proxy conversion, remap all local ID usages to linked IDs to their newly created
74  * overrides. Also do that for the IDs from the same lib as the proxy in case it is linked.
75  * While this might not be 100% the desired behavior, it is likely to be the case most of the
76  * time. Ref: T91711. */
77  ID *id_iter;
78  FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
79  if (!ID_IS_LINKED(id_iter) || id_iter->lib == ob_proxy->id.lib) {
80  id_iter->tag |= LIB_TAG_DOIT;
81  }
82  }
84 
86  bmain, scene, view_layer, ob_proxy->id.lib, id_root, id_root, id_instance_hint, NULL, false);
87 }
88 
90  Scene *scene,
91  Object *ob_proxy,
92  BlendFileReadReport *reports)
93 {
94  Object *ob_proxy_group = ob_proxy->proxy_group;
95  const bool is_override_instancing_object = ob_proxy_group != NULL;
96 
97  const bool success = BKE_lib_override_library_proxy_convert(bmain, scene, NULL, ob_proxy);
98 
99  if (success) {
100  CLOG_INFO(&LOG,
101  4,
102  "Proxy object '%s' successfully converted to library overrides",
103  ob_proxy->id.name);
104  /* Remove the instance empty from this scene, the items now have an overridden collection
105  * instead. */
106  if (is_override_instancing_object) {
107  BKE_scene_collections_object_remove(bmain, scene, ob_proxy_group, true);
108  }
110  }
111 }
112 
114 {
115  LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
116  LinkNodePair proxy_objects = {NULL};
117 
119  if (object->proxy_group != NULL) {
120  BLI_linklist_append(&proxy_objects, object);
121  }
122  }
124 
126  if (object->proxy != NULL && object->proxy_group == NULL) {
127  BLI_linklist_append(&proxy_objects, object);
128  }
129  }
131 
132  for (LinkNode *proxy_object_iter = proxy_objects.list; proxy_object_iter != NULL;
133  proxy_object_iter = proxy_object_iter->next) {
134  Object *proxy_object = proxy_object_iter->link;
135  lib_override_library_proxy_convert_do(bmain, scene, proxy_object, reports);
136  }
137 
138  BLI_linklist_free(proxy_objects.list, NULL);
139  }
140 
141  LISTBASE_FOREACH (Object *, object, &bmain->objects) {
142  if (object->proxy_group != NULL || object->proxy != NULL) {
143  if (ID_IS_LINKED(object)) {
144  CLOG_WARN(&LOG,
145  "Linked proxy object '%s' from '%s' failed to be converted to library override",
146  object->id.name + 2,
147  object->id.lib->filepath);
148  }
149  else {
150  CLOG_WARN(&LOG,
151  "Proxy object '%s' failed to be converted to library override",
152  object->id.name + 2);
153  }
155  if (object->proxy != NULL) {
156  object->proxy->proxy_from = NULL;
157  }
158  id_us_min((ID *)object->proxy);
159  object->proxy = object->proxy_group = NULL;
160  }
161  }
162 }
#define FOREACH_SCENE_OBJECT_END
bool BKE_scene_collections_object_remove(struct Main *bmain, struct Scene *scene, struct Object *object, bool free_us)
Definition: collection.c:1224
#define FOREACH_SCENE_OBJECT_BEGIN(scene, _instance)
void id_us_min(struct ID *id)
Definition: lib_id.c:313
struct IDOverrideLibrary * BKE_lib_override_library_init(struct ID *local_id, struct ID *reference_id)
bool BKE_lib_override_library_create(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, struct Library *owner_library, struct ID *id_root_reference, struct ID *id_hierarchy_root_reference, struct ID *id_instance_hint, struct ID **r_id_root_override, const bool do_fully_editable)
#define FOREACH_MAIN_ID_END
Definition: BKE_main.h:367
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition: BKE_main.h:361
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
external readfile function prototypes.
#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(struct ID *id, int flag)
ID and Library types, which are fundamental for sdna.
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
#define ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(_id)
Definition: DNA_ID.h:570
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
@ LIB_TAG_DOIT
Definition: DNA_ID.h:707
@ IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED
Definition: DNA_ID.h:327
Object groups, one object can be in many groups at once.
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
Scene scene
bool BKE_lib_override_library_proxy_convert(Main *bmain, Scene *scene, ViewLayer *view_layer, Object *ob_proxy)
void BKE_lib_override_library_main_proxy_convert(Main *bmain, BlendFileReadReport *reports)
static CLG_LogRef LOG
static void lib_override_library_proxy_convert_do(Main *bmain, Scene *scene, Object *ob_proxy, BlendFileReadReport *reports)
int proxies_to_lib_overrides_failures
Definition: BLO_readfile.h:107
struct BlendFileReadReport::@134 count
int proxies_to_lib_overrides_success
Definition: BLO_readfile.h:105
unsigned int flag
Definition: DNA_ID.h:312
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
char name[66]
Definition: DNA_ID.h:378
LinkNode * list
Definition: BLI_linklist.h:34
Definition: BKE_main.h:121
ListBase scenes
Definition: BKE_main.h:168
ListBase objects
Definition: BKE_main.h:170
struct Collection * instance_collection