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) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup blenloader
22  */
23 
24 #include "zlib.h"
25 
26 #include <ctype.h> /* for isdigit. */
27 #include <fcntl.h> /* for open flags (O_BINARY, O_RDONLY). */
28 #include <limits.h>
29 #include <stdarg.h> /* for va_start/end. */
30 #include <stddef.h> /* for offsetof. */
31 #include <stdlib.h> /* for atoi. */
32 #include <time.h>   /* for gmtime. */
33 
34 #include "BLI_utildefines.h"
35 #ifndef WIN32
36 #  include <unistd.h> /* for read close */
37 #else
38 #  include "BLI_winstuff.h"
39 #  include "winsock2.h"
40 #  include <io.h> /* for open close read */
41 #endif
42 
43 /* allow readfile to use deprecated functionality */
44 #define DNA_DEPRECATED_ALLOW
45 
46 #include "DNA_anim_types.h"
47 #include "DNA_armature_types.h"
48 #include "DNA_brush_types.h"
49 #include "DNA_cachefile_types.h"
50 #include "DNA_camera_types.h"
51 #include "DNA_cloth_types.h"
52 #include "DNA_collection_types.h"
53 #include "DNA_constraint_types.h"
54 #include "DNA_curveprofile_types.h"
55 #include "DNA_dynamicpaint_types.h"
56 #include "DNA_effect_types.h"
57 #include "DNA_fileglobal_types.h"
58 #include "DNA_fluid_types.h"
59 #include "DNA_genfile.h"
60 #include "DNA_gpencil_modifier_types.h"
61 #include "DNA_gpencil_types.h"
62 #include "DNA_hair_types.h"
63 #include "DNA_ipo_types.h"
64 #include "DNA_key_types.h"
65 #include "DNA_lattice_types.h"
66 #include "DNA_layer_types.h"
67 #include "DNA_light_types.h"
68 #include "DNA_lightprobe_types.h"
69 #include "DNA_linestyle_types.h"
70 #include "DNA_mask_types.h"
71 #include "DNA_material_types.h"
72 #include "DNA_mesh_types.h"
73 #include "DNA_meshdata_types.h"
74 #include "DNA_meta_types.h"
75 #include "DNA_movieclip_types.h"
76 #include "DNA_nla_types.h"
77 #include "DNA_node_types.h"
78 #include "DNA_object_fluidsim_types.h"
79 #include "DNA_object_types.h"
80 #include "DNA_packedFile_types.h"
81 #include "DNA_particle_types.h"
82 #include "DNA_pointcache_types.h"
83 #include "DNA_pointcloud_types.h"
84 #include "DNA_rigidbody_types.h"
85 #include "DNA_scene_types.h"
86 #include "DNA_screen_types.h"
87 #include "DNA_sdna_types.h"
88 #include "DNA_sequence_types.h"
89 #include "DNA_shader_fx_types.h"
90 #include "DNA_simulation_types.h"
91 #include "DNA_sound_types.h"
92 #include "DNA_space_types.h"
93 #include "DNA_speaker_types.h"
94 #include "DNA_text_types.h"
95 #include "DNA_vfont_types.h"
96 #include "DNA_view3d_types.h"
97 #include "DNA_volume_types.h"
98 #include "DNA_workspace_types.h"
99 #include "DNA_world_types.h"
100 
101 #include "MEM_guardedalloc.h"
102 
103 #include "BLI_blenlib.h"
104 #include "BLI_endian_switch.h"
105 #include "BLI_ghash.h"
106 #include "BLI_linklist.h"
107 #include "BLI_math.h"
108 #include "BLI_memarena.h"
109 #include "BLI_mempool.h"
110 #include "BLI_threads.h"
111 
112 #include "BLT_translation.h"
113 
114 #include "BKE_action.h"
115 #include "BKE_anim_data.h"
116 #include "BKE_animsys.h"
117 #include "BKE_armature.h"
118 #include "BKE_brush.h"
119 #include "BKE_collection.h"
120 #include "BKE_colortools.h"
121 #include "BKE_constraint.h"
122 #include "BKE_curve.h"
123 #include "BKE_curveprofile.h"
124 #include "BKE_deform.h"
125 #include "BKE_effect.h"
126 #include "BKE_fcurve.h"
127 #include "BKE_fcurve_driver.h"
128 #include "BKE_fluid.h"
129 #include "BKE_global.h" /* for G */
130 #include "BKE_gpencil.h"
131 #include "BKE_gpencil_modifier.h"
132 #include "BKE_hair.h"
133 #include "BKE_icons.h"
134 #include "BKE_idprop.h"
135 #include "BKE_idtype.h"
136 #include "BKE_image.h"
137 #include "BKE_layer.h"
138 #include "BKE_lib_id.h"
139 #include "BKE_lib_override.h"
140 #include "BKE_lib_query.h"
141 #include "BKE_main.h" /* for Main */
142 #include "BKE_main_idmap.h"
143 #include "BKE_material.h"
144 #include "BKE_mesh.h" /* for ME_ defines (patching) */
145 #include "BKE_mesh_runtime.h"
146 #include "BKE_modifier.h"
147 #include "BKE_multires.h"
148 #include "BKE_nla.h"
149 #include "BKE_node.h" /* for tree type defines */
150 #include "BKE_object.h"
151 #include "BKE_packedFile.h"
152 #include "BKE_paint.h"
153 #include "BKE_particle.h"
154 #include "BKE_pointcache.h"
155 #include "BKE_pointcloud.h"
156 #include "BKE_report.h"
157 #include "BKE_scene.h"
158 #include "BKE_screen.h"
159 #include "BKE_sequencer.h"
160 #include "BKE_shader_fx.h"
161 #include "BKE_simulation.h"
162 #include "BKE_sound.h"
163 #include "BKE_volume.h"
164 #include "BKE_workspace.h"
165 
166 #include "DRW_engine.h"
167 
168 #include "DEG_depsgraph.h"
169 
170 #include "NOD_socket.h"
171 
172 #include "BLO_blend_defs.h"
173 #include "BLO_blend_validate.h"
174 #include "BLO_read_write.h"
175 #include "BLO_readfile.h"
176 #include "BLO_undofile.h"
177 
178 #include "RE_engine.h"
179 
180 #include "engines/eevee/eevee_lightcache.h"
181 
182 #include "readfile.h"
183 
184 #include <errno.h>
185 
186 /* Make preferences read-only. */
187 #define U (*((const UserDef *)&U))
188 
189 /**
190  * READ
191  * ====
192  *
193  * - Existing Library (#Main) push or free
194  * - allocate new #Main
195  * - load file
196  * - read #SDNA
197  * - for each LibBlock
198  *   - read LibBlock
199  *   - if a Library
200  *     - make a new #Main
201  *     - attach ID's to it
202  *   - else
203  *     - read associated 'direct data'
204  *     - link direct data (internal and to LibBlock)
205  * - read #FileGlobal
206  * - read #USER data, only when indicated (file is `~/.config/blender/X.XX/config/userpref.blend`)
207  * - free file
208  * - per Library (per #Main)
209  *   - read file
210  *   - read #SDNA
211  *   - find LibBlocks and attach #ID's to #Main
212  *     - if external LibBlock
213  *       - search all #Main's
214  *         - or it's already read,
215  *         - or not read yet
216  *         - or make new #Main
217  *   - per LibBlock
218  *     - read recursive
219  *     - read associated direct data
220  *     - link direct data (internal and to LibBlock)
221  *   - free file
222  * - per Library with unread LibBlocks
223  *   - read file
224  *   - read #SDNA
225  *   - per LibBlock
226  *     - read recursive
227  *     - read associated direct data
228  *     - link direct data (internal and to LibBlock)
229  *   - free file
230  * - join all #Main's
231  * - link all LibBlocks and indirect pointers to libblocks
232  * - initialize #FileGlobal and copy pointers to #Global
233  *
234  * \note Still a weak point is the new-address function, that doesn't solve reading from
235  * multiple files at the same time.
236  * (added remark: oh, i thought that was solved? will look at that... (ton).
237  */
238 
239 /**
240  * Delay reading blocks we might not use (especially applies to library linking).
241  * which keeps large arrays in memory from data-blocks we may not even use.
242  *
243  * \note This is disabled when using compression,
244  * while zlib supports seek it's unusably slow, see: T61880.
245  */
246 #define USE_BHEAD_READ_ON_DEMAND
247 
248 /* use GHash for BHead name-based lookups (speeds up linking) */
249 #define USE_GHASH_BHEAD
250 
251 /* Use GHash for restoring pointers by name */
252 #define USE_GHASH_RESTORE_POINTER
253 
254 /* Define this to have verbose debug prints. */
255 //#define USE_DEBUG_PRINT
256 
257 #ifdef USE_DEBUG_PRINT
258 #  define DEBUG_PRINTF(...) printf(__VA_ARGS__)
259 #else
260 #  define DEBUG_PRINTF(...)
261 #endif
262 
263 /* local prototypes */
264 static void read_libraries(FileData *basefd, ListBase *mainlist);
265 static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
266 static void direct_link_modifiers(BlendDataReader *reader, ListBase *lb, Object *ob);
267 static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
268 static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
269 static bool library_link_idcode_needs_tag_check(const short idcode, const int flag);
270 
271 #ifdef USE_COLLECTION_COMPAT_28
272 static void expand_scene_collection(BlendExpander *expander, SceneCollection *sc);
273 #endif
274 
275 typedef struct BHeadN {
276   struct BHeadN *next, *prev;
277 #ifdef USE_BHEAD_READ_ON_DEMAND
278   /** Use to read the data from the file directly into memory as needed. */
279   off64_t file_offset;
280   /** When set, the remainder of this allocation is the data, otherwise it needs to be read. */
281   bool has_data;
282 #endif
283   bool is_memchunk_identical;
284   struct BHead bhead;
285 } BHeadN;
286 
287 #define BHEADN_FROM_BHEAD(bh) ((BHeadN *)POINTER_OFFSET(bh, -(int)offsetof(BHeadN, bhead)))
288 
289 /* We could change this in the future, for now it's simplest if only data is delayed
290  * because ID names are used in lookup tables. */
291 #define BHEAD_USE_READ_ON_DEMAND(bhead) ((bhead)->code == DATA)
292 
293 /**
294  * This function ensures that reports are printed,
295  * in the case of library linking errors this is important!
296  *
297  * bit kludge but better than doubling up on prints,
298  * we could alternatively have a versions of a report function which forces printing - campbell
299  */
blo_reportf_wrap(ReportList * reports,ReportType type,const char * format,...)300 void blo_reportf_wrap(ReportList *reports, ReportType type, const char *format, ...)
301 {
302   char fixed_buf[1024]; /* should be long enough */
303 
304   va_list args;
305 
306   va_start(args, format);
307   vsnprintf(fixed_buf, sizeof(fixed_buf), format, args);
308   va_end(args);
309 
310   fixed_buf[sizeof(fixed_buf) - 1] = '\0';
311 
312   BKE_report(reports, type, fixed_buf);
313 
314   if (G.background == 0) {
315     printf("%s: %s\n", BKE_report_type_str(type), fixed_buf);
316   }
317 }
318 
319 /* for reporting linking messages */
library_parent_filepath(Library * lib)320 static const char *library_parent_filepath(Library *lib)
321 {
322   return lib->parent ? lib->parent->filepath_abs : "<direct>";
323 }
324 
325 /* -------------------------------------------------------------------- */
326 /** \name OldNewMap API
327  * \{ */
328 
329 typedef struct OldNew {
330   const void *oldp;
331   void *newp;
332   /* `nr` is "user count" for data, and ID code for libdata. */
333   int nr;
334 } OldNew;
335 
336 typedef struct OldNewMap {
337   /* Array that stores the actual entries. */
338   OldNew *entries;
339   int nentries;
340   /* Hashmap that stores indices into the `entries` array. */
341   int32_t *map;
342 
343   int capacity_exp;
344 } OldNewMap;
345 
346 #define ENTRIES_CAPACITY(onm) (1ll << (onm)->capacity_exp)
347 #define MAP_CAPACITY(onm) (1ll << ((onm)->capacity_exp + 1))
348 #define SLOT_MASK(onm) (MAP_CAPACITY(onm) - 1)
349 #define DEFAULT_SIZE_EXP 6
350 #define PERTURB_SHIFT 5
351 
352 /* based on the probing algorithm used in Python dicts. */
353 #define ITER_SLOTS(onm, KEY, SLOT_NAME, INDEX_NAME) \
354   uint32_t hash = BLI_ghashutil_ptrhash(KEY); \
355   uint32_t mask = SLOT_MASK(onm); \
356   uint perturb = hash; \
357   int SLOT_NAME = mask & hash; \
358   int INDEX_NAME = onm->map[SLOT_NAME]; \
359   for (;; SLOT_NAME = mask & ((5 * SLOT_NAME) + 1 + perturb), \
360           perturb >>= PERTURB_SHIFT, \
361           INDEX_NAME = onm->map[SLOT_NAME])
362 
oldnewmap_insert_index_in_map(OldNewMap * onm,const void * ptr,int index)363 static void oldnewmap_insert_index_in_map(OldNewMap *onm, const void *ptr, int index)
364 {
365   ITER_SLOTS (onm, ptr, slot, stored_index) {
366     if (stored_index == -1) {
367       onm->map[slot] = index;
368       break;
369     }
370   }
371 }
372 
oldnewmap_insert_or_replace(OldNewMap * onm,OldNew entry)373 static void oldnewmap_insert_or_replace(OldNewMap *onm, OldNew entry)
374 {
375   ITER_SLOTS (onm, entry.oldp, slot, index) {
376     if (index == -1) {
377       onm->entries[onm->nentries] = entry;
378       onm->map[slot] = onm->nentries;
379       onm->nentries++;
380       break;
381     }
382     if (onm->entries[index].oldp == entry.oldp) {
383       onm->entries[index] = entry;
384       break;
385     }
386   }
387 }
388 
oldnewmap_lookup_entry(const OldNewMap * onm,const void * addr)389 static OldNew *oldnewmap_lookup_entry(const OldNewMap *onm, const void *addr)
390 {
391   ITER_SLOTS (onm, addr, slot, index) {
392     if (index >= 0) {
393       OldNew *entry = &onm->entries[index];
394       if (entry->oldp == addr) {
395         return entry;
396       }
397     }
398     else {
399       return NULL;
400     }
401   }
402 }
403 
oldnewmap_clear_map(OldNewMap * onm)404 static void oldnewmap_clear_map(OldNewMap *onm)
405 {
406   memset(onm->map, 0xFF, MAP_CAPACITY(onm) * sizeof(*onm->map));
407 }
408 
oldnewmap_increase_size(OldNewMap * onm)409 static void oldnewmap_increase_size(OldNewMap *onm)
410 {
411   onm->capacity_exp++;
412   onm->entries = MEM_reallocN(onm->entries, sizeof(*onm->entries) * ENTRIES_CAPACITY(onm));
413   onm->map = MEM_reallocN(onm->map, sizeof(*onm->map) * MAP_CAPACITY(onm));
414   oldnewmap_clear_map(onm);
415   for (int i = 0; i < onm->nentries; i++) {
416     oldnewmap_insert_index_in_map(onm, onm->entries[i].oldp, i);
417   }
418 }
419 
420 /* Public OldNewMap API */
421 
oldnewmap_new(void)422 static OldNewMap *oldnewmap_new(void)
423 {
424   OldNewMap *onm = MEM_callocN(sizeof(*onm), "OldNewMap");
425 
426   onm->capacity_exp = DEFAULT_SIZE_EXP;
427   onm->entries = MEM_malloc_arrayN(
428       ENTRIES_CAPACITY(onm), sizeof(*onm->entries), "OldNewMap.entries");
429   onm->map = MEM_malloc_arrayN(MAP_CAPACITY(onm), sizeof(*onm->map), "OldNewMap.map");
430   oldnewmap_clear_map(onm);
431 
432   return onm;
433 }
434 
oldnewmap_insert(OldNewMap * onm,const void * oldaddr,void * newaddr,int nr)435 static void oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, int nr)
436 {
437   if (oldaddr == NULL || newaddr == NULL) {
438     return;
439   }
440 
441   if (UNLIKELY(onm->nentries == ENTRIES_CAPACITY(onm))) {
442     oldnewmap_increase_size(onm);
443   }
444 
445   OldNew entry;
446   entry.oldp = oldaddr;
447   entry.newp = newaddr;
448   entry.nr = nr;
449   oldnewmap_insert_or_replace(onm, entry);
450 }
451 
blo_do_versions_oldnewmap_insert(OldNewMap * onm,const void * oldaddr,void * newaddr,int nr)452 void blo_do_versions_oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, int nr)
453 {
454   oldnewmap_insert(onm, oldaddr, newaddr, nr);
455 }
456 
oldnewmap_lookup_and_inc(OldNewMap * onm,const void * addr,bool increase_users)457 static void *oldnewmap_lookup_and_inc(OldNewMap *onm, const void *addr, bool increase_users)
458 {
459   OldNew *entry = oldnewmap_lookup_entry(onm, addr);
460   if (entry == NULL) {
461     return NULL;
462   }
463   if (increase_users) {
464     entry->nr++;
465   }
466   return entry->newp;
467 }
468 
469 /* for libdata, OldNew.nr has ID code, no increment */
oldnewmap_liblookup(OldNewMap * onm,const void * addr,const void * lib)470 static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const void *lib)
471 {
472   if (addr == NULL) {
473     return NULL;
474   }
475 
476   ID *id = oldnewmap_lookup_and_inc(onm, addr, false);
477   if (id == NULL) {
478     return NULL;
479   }
480   if (!lib || id->lib) {
481     return id;
482   }
483   return NULL;
484 }
485 
oldnewmap_clear(OldNewMap * onm)486 static void oldnewmap_clear(OldNewMap *onm)
487 {
488   /* Free unused data. */
489   for (int i = 0; i < onm->nentries; i++) {
490     OldNew *entry = &onm->entries[i];
491     if (entry->nr == 0) {
492       MEM_freeN(entry->newp);
493       entry->newp = NULL;
494     }
495   }
496 
497   onm->capacity_exp = DEFAULT_SIZE_EXP;
498   oldnewmap_clear_map(onm);
499   onm->nentries = 0;
500 }
501 
oldnewmap_free(OldNewMap * onm)502 static void oldnewmap_free(OldNewMap *onm)
503 {
504   MEM_freeN(onm->entries);
505   MEM_freeN(onm->map);
506   MEM_freeN(onm);
507 }
508 
509 #undef ENTRIES_CAPACITY
510 #undef MAP_CAPACITY
511 #undef SLOT_MASK
512 #undef DEFAULT_SIZE_EXP
513 #undef PERTURB_SHIFT
514 #undef ITER_SLOTS
515 
516 /** \} */
517 
518 /* -------------------------------------------------------------------- */
519 /** \name Helper Functions
520  * \{ */
521 
add_main_to_main(Main * mainvar,Main * from)522 static void add_main_to_main(Main *mainvar, Main *from)
523 {
524   ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY];
525   int a;
526 
527   set_listbasepointers(mainvar, lbarray);
528   a = set_listbasepointers(from, fromarray);
529   while (a--) {
530     BLI_movelisttolist(lbarray[a], fromarray[a]);
531   }
532 }
533 
blo_join_main(ListBase * mainlist)534 void blo_join_main(ListBase *mainlist)
535 {
536   Main *tojoin, *mainl;
537 
538   mainl = mainlist->first;
539   while ((tojoin = mainl->next)) {
540     add_main_to_main(mainl, tojoin);
541     BLI_remlink(mainlist, tojoin);
542     BKE_main_free(tojoin);
543   }
544 }
545 
split_libdata(ListBase * lb_src,Main ** lib_main_array,const uint lib_main_array_len)546 static void split_libdata(ListBase *lb_src, Main **lib_main_array, const uint lib_main_array_len)
547 {
548   for (ID *id = lb_src->first, *idnext; id; id = idnext) {
549     idnext = id->next;
550 
551     if (id->lib) {
552       if (((uint)id->lib->temp_index < lib_main_array_len) &&
553           /* this check should never fail, just in case 'id->lib' is a dangling pointer. */
554           (lib_main_array[id->lib->temp_index]->curlib == id->lib)) {
555         Main *mainvar = lib_main_array[id->lib->temp_index];
556         ListBase *lb_dst = which_libbase(mainvar, GS(id->name));
557         BLI_remlink(lb_src, id);
558         BLI_addtail(lb_dst, id);
559       }
560       else {
561         printf("%s: invalid library for '%s'\n", __func__, id->name);
562         BLI_assert(0);
563       }
564     }
565   }
566 }
567 
blo_split_main(ListBase * mainlist,Main * main)568 void blo_split_main(ListBase *mainlist, Main *main)
569 {
570   mainlist->first = mainlist->last = main;
571   main->next = NULL;
572 
573   if (BLI_listbase_is_empty(&main->libraries)) {
574     return;
575   }
576 
577   /* (Library.temp_index -> Main), lookup table */
578   const uint lib_main_array_len = BLI_listbase_count(&main->libraries);
579   Main **lib_main_array = MEM_malloc_arrayN(lib_main_array_len, sizeof(*lib_main_array), __func__);
580 
581   int i = 0;
582   for (Library *lib = main->libraries.first; lib; lib = lib->id.next, i++) {
583     Main *libmain = BKE_main_new();
584     libmain->curlib = lib;
585     libmain->versionfile = lib->versionfile;
586     libmain->subversionfile = lib->subversionfile;
587     BLI_addtail(mainlist, libmain);
588     lib->temp_index = i;
589     lib_main_array[i] = libmain;
590   }
591 
592   ListBase *lbarray[MAX_LIBARRAY];
593   i = set_listbasepointers(main, lbarray);
594   while (i--) {
595     ID *id = lbarray[i]->first;
596     if (id == NULL || GS(id->name) == ID_LI) {
597       /* No ID_LI data-lock should ever be linked anyway, but just in case, better be explicit. */
598       continue;
599     }
600     split_libdata(lbarray[i], lib_main_array, lib_main_array_len);
601   }
602 
603   MEM_freeN(lib_main_array);
604 }
605 
read_file_version(FileData * fd,Main * main)606 static void read_file_version(FileData *fd, Main *main)
607 {
608   BHead *bhead;
609 
610   for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
611     if (bhead->code == GLOB) {
612       FileGlobal *fg = read_struct(fd, bhead, "Global");
613       if (fg) {
614         main->subversionfile = fg->subversion;
615         main->minversionfile = fg->minversion;
616         main->minsubversionfile = fg->minsubversion;
617         MEM_freeN(fg);
618       }
619       else if (bhead->code == ENDB) {
620         break;
621       }
622     }
623   }
624   if (main->curlib) {
625     main->curlib->versionfile = main->versionfile;
626     main->curlib->subversionfile = main->subversionfile;
627   }
628 }
629 
630 #ifdef USE_GHASH_BHEAD
read_file_bhead_idname_map_create(FileData * fd)631 static void read_file_bhead_idname_map_create(FileData *fd)
632 {
633   BHead *bhead;
634 
635   /* dummy values */
636   bool is_link = false;
637   int code_prev = ENDB;
638   uint reserve = 0;
639 
640   for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
641     if (code_prev != bhead->code) {
642       code_prev = bhead->code;
643       is_link = BKE_idtype_idcode_is_valid(code_prev) ? BKE_idtype_idcode_is_linkable(code_prev) :
644                                                         false;
645     }
646 
647     if (is_link) {
648       reserve += 1;
649     }
650   }
651 
652   BLI_assert(fd->bhead_idname_hash == NULL);
653 
654   fd->bhead_idname_hash = BLI_ghash_str_new_ex(__func__, reserve);
655 
656   for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
657     if (code_prev != bhead->code) {
658       code_prev = bhead->code;
659       is_link = BKE_idtype_idcode_is_valid(code_prev) ? BKE_idtype_idcode_is_linkable(code_prev) :
660                                                         false;
661     }
662 
663     if (is_link) {
664       BLI_ghash_insert(fd->bhead_idname_hash, (void *)blo_bhead_id_name(fd, bhead), bhead);
665     }
666   }
667 }
668 #endif
669 
blo_find_main(FileData * fd,const char * filepath,const char * relabase)670 static Main *blo_find_main(FileData *fd, const char *filepath, const char *relabase)
671 {
672   ListBase *mainlist = fd->mainlist;
673   Main *m;
674   Library *lib;
675   char name1[FILE_MAX];
676 
677   BLI_strncpy(name1, filepath, sizeof(name1));
678   BLI_path_normalize(relabase, name1);
679 
680   //  printf("blo_find_main: relabase  %s\n", relabase);
681   //  printf("blo_find_main: original in  %s\n", filepath);
682   //  printf("blo_find_main: converted to %s\n", name1);
683 
684   for (m = mainlist->first; m; m = m->next) {
685     const char *libname = (m->curlib) ? m->curlib->filepath_abs : m->name;
686 
687     if (BLI_path_cmp(name1, libname) == 0) {
688       if (G.debug & G_DEBUG) {
689         printf("blo_find_main: found library %s\n", libname);
690       }
691       return m;
692     }
693   }
694 
695   m = BKE_main_new();
696   BLI_addtail(mainlist, m);
697 
698   /* Add library data-block itself to 'main' Main, since libraries are **never** linked data.
699    * Fixes bug where you could end with all ID_LI data-blocks having the same name... */
700   lib = BKE_libblock_alloc(mainlist->first, ID_LI, BLI_path_basename(filepath), 0);
701 
702   /* Important, consistency with main ID reading code from read_libblock(). */
703   lib->id.us = ID_FAKE_USERS(lib);
704 
705   /* Matches direct_link_library(). */
706   id_us_ensure_real(&lib->id);
707 
708   BLI_strncpy(lib->filepath, filepath, sizeof(lib->filepath));
709   BLI_strncpy(lib->filepath_abs, name1, sizeof(lib->filepath_abs));
710 
711   m->curlib = lib;
712 
713   read_file_version(fd, m);
714 
715   if (G.debug & G_DEBUG) {
716     printf("blo_find_main: added new lib %s\n", filepath);
717   }
718   return m;
719 }
720 
721 /** \} */
722 
723 /* -------------------------------------------------------------------- */
724 /** \name File Parsing
725  * \{ */
726 
727 typedef struct BlendDataReader {
728   FileData *fd;
729 } BlendDataReader;
730 
731 typedef struct BlendLibReader {
732   FileData *fd;
733   Main *main;
734 } BlendLibReader;
735 
736 typedef struct BlendExpander {
737   FileData *fd;
738   Main *main;
739 } BlendExpander;
740 
switch_endian_bh4(BHead4 * bhead)741 static void switch_endian_bh4(BHead4 *bhead)
742 {
743   /* the ID_.. codes */
744   if ((bhead->code & 0xFFFF) == 0) {
745     bhead->code >>= 16;
746   }
747 
748   if (bhead->code != ENDB) {
749     BLI_endian_switch_int32(&bhead->len);
750     BLI_endian_switch_int32(&bhead->SDNAnr);
751     BLI_endian_switch_int32(&bhead->nr);
752   }
753 }
754 
switch_endian_bh8(BHead8 * bhead)755 static void switch_endian_bh8(BHead8 *bhead)
756 {
757   /* the ID_.. codes */
758   if ((bhead->code & 0xFFFF) == 0) {
759     bhead->code >>= 16;
760   }
761 
762   if (bhead->code != ENDB) {
763     BLI_endian_switch_int32(&bhead->len);
764     BLI_endian_switch_int32(&bhead->SDNAnr);
765     BLI_endian_switch_int32(&bhead->nr);
766   }
767 }
768 
bh4_from_bh8(BHead * bhead,BHead8 * bhead8,bool do_endian_swap)769 static void bh4_from_bh8(BHead *bhead, BHead8 *bhead8, bool do_endian_swap)
770 {
771   BHead4 *bhead4 = (BHead4 *)bhead;
772   int64_t old;
773 
774   bhead4->code = bhead8->code;
775   bhead4->len = bhead8->len;
776 
777   if (bhead4->code != ENDB) {
778     /* perform a endian swap on 64bit pointers, otherwise the pointer might map to zero
779      * 0x0000000000000000000012345678 would become 0x12345678000000000000000000000000
780      */
781     if (do_endian_swap) {
782       BLI_endian_switch_uint64(&bhead8->old);
783     }
784 
785     /* this patch is to avoid a long long being read from not-eight aligned positions
786      * is necessary on any modern 64bit architecture) */
787     memcpy(&old, &bhead8->old, 8);
788     bhead4->old = (int)(old >> 3);
789 
790     bhead4->SDNAnr = bhead8->SDNAnr;
791     bhead4->nr = bhead8->nr;
792   }
793 }
794 
bh8_from_bh4(BHead * bhead,BHead4 * bhead4)795 static void bh8_from_bh4(BHead *bhead, BHead4 *bhead4)
796 {
797   BHead8 *bhead8 = (BHead8 *)bhead;
798 
799   bhead8->code = bhead4->code;
800   bhead8->len = bhead4->len;
801 
802   if (bhead8->code != ENDB) {
803     bhead8->old = bhead4->old;
804     bhead8->SDNAnr = bhead4->SDNAnr;
805     bhead8->nr = bhead4->nr;
806   }
807 }
808 
get_bhead(FileData * fd)809 static BHeadN *get_bhead(FileData *fd)
810 {
811   BHeadN *new_bhead = NULL;
812   ssize_t readsize;
813 
814   if (fd) {
815     if (!fd->is_eof) {
816       /* initializing to zero isn't strictly needed but shuts valgrind up
817        * since uninitialized memory gets compared */
818       BHead8 bhead8 = {0};
819       BHead4 bhead4 = {0};
820       BHead bhead = {0};
821 
822       /* First read the bhead structure.
823        * Depending on the platform the file was written on this can
824        * be a big or little endian BHead4 or BHead8 structure.
825        *
826        * As usual 'ENDB' (the last *partial* bhead of the file)
827        * needs some special handling. We don't want to EOF just yet.
828        */
829       if (fd->flags & FD_FLAGS_FILE_POINTSIZE_IS_4) {
830         bhead4.code = DATA;
831         readsize = fd->read(fd, &bhead4, sizeof(bhead4), NULL);
832 
833         if (readsize == sizeof(bhead4) || bhead4.code == ENDB) {
834           if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
835             switch_endian_bh4(&bhead4);
836           }
837 
838           if (fd->flags & FD_FLAGS_POINTSIZE_DIFFERS) {
839             bh8_from_bh4(&bhead, &bhead4);
840           }
841           else {
842             /* MIN2 is only to quiet '-Warray-bounds' compiler warning. */
843             BLI_assert(sizeof(bhead) == sizeof(bhead4));
844             memcpy(&bhead, &bhead4, MIN2(sizeof(bhead), sizeof(bhead4)));
845           }
846         }
847         else {
848           fd->is_eof = true;
849           bhead.len = 0;
850         }
851       }
852       else {
853         bhead8.code = DATA;
854         readsize = fd->read(fd, &bhead8, sizeof(bhead8), NULL);
855 
856         if (readsize == sizeof(bhead8) || bhead8.code == ENDB) {
857           if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
858             switch_endian_bh8(&bhead8);
859           }
860 
861           if (fd->flags & FD_FLAGS_POINTSIZE_DIFFERS) {
862             bh4_from_bh8(&bhead, &bhead8, (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0);
863           }
864           else {
865             /* MIN2 is only to quiet '-Warray-bounds' compiler warning. */
866             BLI_assert(sizeof(bhead) == sizeof(bhead8));
867             memcpy(&bhead, &bhead8, MIN2(sizeof(bhead), sizeof(bhead8)));
868           }
869         }
870         else {
871           fd->is_eof = true;
872           bhead.len = 0;
873         }
874       }
875 
876       /* make sure people are not trying to pass bad blend files */
877       if (bhead.len < 0) {
878         fd->is_eof = true;
879       }
880 
881       /* bhead now contains the (converted) bhead structure. Now read
882        * the associated data and put everything in a BHeadN (creative naming !)
883        */
884       if (fd->is_eof) {
885         /* pass */
886       }
887 #ifdef USE_BHEAD_READ_ON_DEMAND
888       else if (fd->seek != NULL && BHEAD_USE_READ_ON_DEMAND(&bhead)) {
889         /* Delay reading bhead content. */
890         new_bhead = MEM_mallocN(sizeof(BHeadN), "new_bhead");
891         if (new_bhead) {
892           new_bhead->next = new_bhead->prev = NULL;
893           new_bhead->file_offset = fd->file_offset;
894           new_bhead->has_data = false;
895           new_bhead->is_memchunk_identical = false;
896           new_bhead->bhead = bhead;
897           off64_t seek_new = fd->seek(fd, bhead.len, SEEK_CUR);
898           if (seek_new == -1) {
899             fd->is_eof = true;
900             MEM_freeN(new_bhead);
901             new_bhead = NULL;
902           }
903           BLI_assert(fd->file_offset == seek_new);
904         }
905         else {
906           fd->is_eof = true;
907         }
908       }
909 #endif
910       else {
911         new_bhead = MEM_mallocN(sizeof(BHeadN) + (size_t)bhead.len, "new_bhead");
912         if (new_bhead) {
913           new_bhead->next = new_bhead->prev = NULL;
914 #ifdef USE_BHEAD_READ_ON_DEMAND
915           new_bhead->file_offset = 0; /* don't seek. */
916           new_bhead->has_data = true;
917 #endif
918           new_bhead->is_memchunk_identical = false;
919           new_bhead->bhead = bhead;
920 
921           readsize = fd->read(
922               fd, new_bhead + 1, (size_t)bhead.len, &new_bhead->is_memchunk_identical);
923 
924           if (readsize != (ssize_t)bhead.len) {
925             fd->is_eof = true;
926             MEM_freeN(new_bhead);
927             new_bhead = NULL;
928           }
929         }
930         else {
931           fd->is_eof = true;
932         }
933       }
934     }
935   }
936 
937   /* We've read a new block. Now add it to the list
938    * of blocks.
939    */
940   if (new_bhead) {
941     BLI_addtail(&fd->bhead_list, new_bhead);
942   }
943 
944   return new_bhead;
945 }
946 
blo_bhead_first(FileData * fd)947 BHead *blo_bhead_first(FileData *fd)
948 {
949   BHeadN *new_bhead;
950   BHead *bhead = NULL;
951 
952   /* Rewind the file
953    * Read in a new block if necessary
954    */
955   new_bhead = fd->bhead_list.first;
956   if (new_bhead == NULL) {
957     new_bhead = get_bhead(fd);
958   }
959 
960   if (new_bhead) {
961     bhead = &new_bhead->bhead;
962   }
963 
964   return bhead;
965 }
966 
blo_bhead_prev(FileData * UNUSED (fd),BHead * thisblock)967 BHead *blo_bhead_prev(FileData *UNUSED(fd), BHead *thisblock)
968 {
969   BHeadN *bheadn = BHEADN_FROM_BHEAD(thisblock);
970   BHeadN *prev = bheadn->prev;
971 
972   return (prev) ? &prev->bhead : NULL;
973 }
974 
blo_bhead_next(FileData * fd,BHead * thisblock)975 BHead *blo_bhead_next(FileData *fd, BHead *thisblock)
976 {
977   BHeadN *new_bhead = NULL;
978   BHead *bhead = NULL;
979 
980   if (thisblock) {
981     /* bhead is actually a sub part of BHeadN
982      * We calculate the BHeadN pointer from the BHead pointer below */
983     new_bhead = BHEADN_FROM_BHEAD(thisblock);
984 
985     /* get the next BHeadN. If it doesn't exist we read in the next one */
986     new_bhead = new_bhead->next;
987     if (new_bhead == NULL) {
988       new_bhead = get_bhead(fd);
989     }
990   }
991 
992   if (new_bhead) {
993     /* here we do the reverse:
994      * go from the BHeadN pointer to the BHead pointer */
995     bhead = &new_bhead->bhead;
996   }
997 
998   return bhead;
999 }
1000 
1001 #ifdef USE_BHEAD_READ_ON_DEMAND
blo_bhead_read_data(FileData * fd,BHead * thisblock,void * buf)1002 static bool blo_bhead_read_data(FileData *fd, BHead *thisblock, void *buf)
1003 {
1004   bool success = true;
1005   BHeadN *new_bhead = BHEADN_FROM_BHEAD(thisblock);
1006   BLI_assert(new_bhead->has_data == false && new_bhead->file_offset != 0);
1007   off64_t offset_backup = fd->file_offset;
1008   if (UNLIKELY(fd->seek(fd, new_bhead->file_offset, SEEK_SET) == -1)) {
1009     success = false;
1010   }
1011   else {
1012     if (fd->read(fd, buf, (size_t)new_bhead->bhead.len, &new_bhead->is_memchunk_identical) !=
1013         (ssize_t)new_bhead->bhead.len) {
1014       success = false;
1015     }
1016   }
1017   if (fd->seek(fd, offset_backup, SEEK_SET) == -1) {
1018     success = false;
1019   }
1020   return success;
1021 }
1022 
blo_bhead_read_full(FileData * fd,BHead * thisblock)1023 static BHead *blo_bhead_read_full(FileData *fd, BHead *thisblock)
1024 {
1025   BHeadN *new_bhead = BHEADN_FROM_BHEAD(thisblock);
1026   BHeadN *new_bhead_data = MEM_mallocN(sizeof(BHeadN) + new_bhead->bhead.len, "new_bhead");
1027   new_bhead_data->bhead = new_bhead->bhead;
1028   new_bhead_data->file_offset = new_bhead->file_offset;
1029   new_bhead_data->has_data = true;
1030   new_bhead_data->is_memchunk_identical = false;
1031   if (!blo_bhead_read_data(fd, thisblock, new_bhead_data + 1)) {
1032     MEM_freeN(new_bhead_data);
1033     return NULL;
1034   }
1035   return &new_bhead_data->bhead;
1036 }
1037 #endif /* USE_BHEAD_READ_ON_DEMAND */
1038 
1039 /* Warning! Caller's responsibility to ensure given bhead **is** and ID one! */
blo_bhead_id_name(const FileData * fd,const BHead * bhead)1040 const char *blo_bhead_id_name(const FileData *fd, const BHead *bhead)
1041 {
1042   return (const char *)POINTER_OFFSET(bhead, sizeof(*bhead) + fd->id_name_offs);
1043 }
1044 
decode_blender_header(FileData * fd)1045 static void decode_blender_header(FileData *fd)
1046 {
1047   char header[SIZEOFBLENDERHEADER], num[4];
1048   ssize_t readsize;
1049 
1050   /* read in the header data */
1051   readsize = fd->read(fd, header, sizeof(header), NULL);
1052 
1053   if (readsize == sizeof(header) && STREQLEN(header, "BLENDER", 7) && ELEM(header[7], '_', '-') &&
1054       ELEM(header[8], 'v', 'V') &&
1055       (isdigit(header[9]) && isdigit(header[10]) && isdigit(header[11]))) {
1056     fd->flags |= FD_FLAGS_FILE_OK;
1057 
1058     /* what size are pointers in the file ? */
1059     if (header[7] == '_') {
1060       fd->flags |= FD_FLAGS_FILE_POINTSIZE_IS_4;
1061       if (sizeof(void *) != 4) {
1062         fd->flags |= FD_FLAGS_POINTSIZE_DIFFERS;
1063       }
1064     }
1065     else {
1066       if (sizeof(void *) != 8) {
1067         fd->flags |= FD_FLAGS_POINTSIZE_DIFFERS;
1068       }
1069     }
1070 
1071     /* is the file saved in a different endian
1072      * than we need ?
1073      */
1074     if (((header[8] == 'v') ? L_ENDIAN : B_ENDIAN) != ENDIAN_ORDER) {
1075       fd->flags |= FD_FLAGS_SWITCH_ENDIAN;
1076     }
1077 
1078     /* get the version number */
1079     memcpy(num, header + 9, 3);
1080     num[3] = 0;
1081     fd->fileversion = atoi(num);
1082   }
1083 }
1084 
1085 /**
1086  * \return Success if the file is read correctly, else set \a r_error_message.
1087  */
read_file_dna(FileData * fd,const char ** r_error_message)1088 static bool read_file_dna(FileData *fd, const char **r_error_message)
1089 {
1090   BHead *bhead;
1091   int subversion = 0;
1092 
1093   for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
1094     if (bhead->code == GLOB) {
1095       /* Before this, the subversion didn't exist in 'FileGlobal' so the subversion
1096        * value isn't accessible for the purpose of DNA versioning in this case. */
1097       if (fd->fileversion <= 242) {
1098         continue;
1099       }
1100       /* We can't use read_global because this needs 'DNA1' to be decoded,
1101        * however the first 4 chars are _always_ the subversion. */
1102       FileGlobal *fg = (void *)&bhead[1];
1103       BLI_STATIC_ASSERT(offsetof(FileGlobal, subvstr) == 0, "Must be first: subvstr")
1104       char num[5];
1105       memcpy(num, fg->subvstr, 4);
1106       num[4] = 0;
1107       subversion = atoi(num);
1108     }
1109     else if (bhead->code == DNA1) {
1110       const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
1111 
1112       fd->filesdna = DNA_sdna_from_data(
1113           &bhead[1], bhead->len, do_endian_swap, true, r_error_message);
1114       if (fd->filesdna) {
1115         blo_do_versions_dna(fd->filesdna, fd->fileversion, subversion);
1116         fd->compflags = DNA_struct_get_compareflags(fd->filesdna, fd->memsdna);
1117         fd->reconstruct_info = DNA_reconstruct_info_create(
1118             fd->filesdna, fd->memsdna, fd->compflags);
1119         /* used to retrieve ID names from (bhead+1) */
1120         fd->id_name_offs = DNA_elem_offset(fd->filesdna, "ID", "char", "name[]");
1121         BLI_assert(fd->id_name_offs != -1);
1122 
1123         return true;
1124       }
1125 
1126       return false;
1127     }
1128     else if (bhead->code == ENDB) {
1129       break;
1130     }
1131   }
1132 
1133   *r_error_message = "Missing DNA block";
1134   return false;
1135 }
1136 
read_file_thumbnail(FileData * fd)1137 static int *read_file_thumbnail(FileData *fd)
1138 {
1139   BHead *bhead;
1140   int *blend_thumb = NULL;
1141 
1142   for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
1143     if (bhead->code == TEST) {
1144       const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
1145       int *data = (int *)(bhead + 1);
1146 
1147       if (bhead->len < (sizeof(int[2]))) {
1148         break;
1149       }
1150 
1151       if (do_endian_swap) {
1152         BLI_endian_switch_int32(&data[0]);
1153         BLI_endian_switch_int32(&data[1]);
1154       }
1155 
1156       const int width = data[0];
1157       const int height = data[1];
1158       if (!BLEN_THUMB_MEMSIZE_IS_VALID(width, height)) {
1159         break;
1160       }
1161       if (bhead->len < BLEN_THUMB_MEMSIZE_FILE(width, height)) {
1162         break;
1163       }
1164 
1165       blend_thumb = data;
1166       break;
1167     }
1168     if (bhead->code != REND) {
1169       /* Thumbnail is stored in TEST immediately after first REND... */
1170       break;
1171     }
1172   }
1173 
1174   return blend_thumb;
1175 }
1176 
1177 /** \} */
1178 
1179 /* -------------------------------------------------------------------- */
1180 /** \name File Data API
1181  * \{ */
1182 
1183 /* Regular file reading. */
1184 
fd_read_data_from_file(FileData * filedata,void * buffer,size_t size,bool * UNUSED (r_is_memchunck_identical))1185 static ssize_t fd_read_data_from_file(FileData *filedata,
1186                                       void *buffer,
1187                                       size_t size,
1188                                       bool *UNUSED(r_is_memchunck_identical))
1189 {
1190   ssize_t readsize = read(filedata->filedes, buffer, size);
1191 
1192   if (readsize < 0) {
1193     readsize = EOF;
1194   }
1195   else {
1196     filedata->file_offset += readsize;
1197   }
1198 
1199   return readsize;
1200 }
1201 
fd_seek_data_from_file(FileData * filedata,off64_t offset,int whence)1202 static off64_t fd_seek_data_from_file(FileData *filedata, off64_t offset, int whence)
1203 {
1204   filedata->file_offset = BLI_lseek(filedata->filedes, offset, whence);
1205   return filedata->file_offset;
1206 }
1207 
1208 /* GZip file reading. */
1209 
fd_read_gzip_from_file(FileData * filedata,void * buffer,size_t size,bool * UNUSED (r_is_memchunck_identical))1210 static ssize_t fd_read_gzip_from_file(FileData *filedata,
1211                                       void *buffer,
1212                                       size_t size,
1213                                       bool *UNUSED(r_is_memchunck_identical))
1214 {
1215   BLI_assert(size <= INT_MAX);
1216 
1217   ssize_t readsize = gzread(filedata->gzfiledes, buffer, (uint)size);
1218 
1219   if (readsize < 0) {
1220     readsize = EOF;
1221   }
1222   else {
1223     filedata->file_offset += readsize;
1224   }
1225 
1226   return readsize;
1227 }
1228 
1229 /* Memory reading. */
1230 
fd_read_from_memory(FileData * filedata,void * buffer,size_t size,bool * UNUSED (r_is_memchunck_identical))1231 static ssize_t fd_read_from_memory(FileData *filedata,
1232                                    void *buffer,
1233                                    size_t size,
1234                                    bool *UNUSED(r_is_memchunck_identical))
1235 {
1236   /* don't read more bytes than there are available in the buffer */
1237   ssize_t readsize = (ssize_t)MIN2(size, filedata->buffersize - (size_t)filedata->file_offset);
1238 
1239   memcpy(buffer, filedata->buffer + filedata->file_offset, (size_t)readsize);
1240   filedata->file_offset += readsize;
1241 
1242   return readsize;
1243 }
1244 
1245 /* MemFile reading. */
1246 
fd_read_from_memfile(FileData * filedata,void * buffer,size_t size,bool * r_is_memchunck_identical)1247 static ssize_t fd_read_from_memfile(FileData *filedata,
1248                                     void *buffer,
1249                                     size_t size,
1250                                     bool *r_is_memchunck_identical)
1251 {
1252   static size_t seek = SIZE_MAX; /* the current position */
1253   static size_t offset = 0;      /* size of previous chunks */
1254   static MemFileChunk *chunk = NULL;
1255   size_t chunkoffset, readsize, totread;
1256 
1257   if (r_is_memchunck_identical != NULL) {
1258     *r_is_memchunck_identical = true;
1259   }
1260 
1261   if (size == 0) {
1262     return 0;
1263   }
1264 
1265   if (seek != (size_t)filedata->file_offset) {
1266     chunk = filedata->memfile->chunks.first;
1267     seek = 0;
1268 
1269     while (chunk) {
1270       if (seek + chunk->size > (size_t)filedata->file_offset) {
1271         break;
1272       }
1273       seek += chunk->size;
1274       chunk = chunk->next;
1275     }
1276     offset = seek;
1277     seek = (size_t)filedata->file_offset;
1278   }
1279 
1280   if (chunk) {
1281     totread = 0;
1282 
1283     do {
1284       /* first check if it's on the end if current chunk */
1285       if (seek - offset == chunk->size) {
1286         offset += chunk->size;
1287         chunk = chunk->next;
1288       }
1289 
1290       /* debug, should never happen */
1291       if (chunk == NULL) {
1292         printf("illegal read, chunk zero\n");
1293         return 0;
1294       }
1295 
1296       chunkoffset = seek - offset;
1297       readsize = size - totread;
1298 
1299       /* data can be spread over multiple chunks, so clamp size
1300        * to within this chunk, and then it will read further in
1301        * the next chunk */
1302       if (chunkoffset + readsize > chunk->size) {
1303         readsize = chunk->size - chunkoffset;
1304       }
1305 
1306       memcpy(POINTER_OFFSET(buffer, totread), chunk->buf + chunkoffset, readsize);
1307       totread += readsize;
1308       filedata->file_offset += readsize;
1309       seek += readsize;
1310       if (r_is_memchunck_identical != NULL) {
1311         /* `is_identical` of current chunk represents whether it changed compared to previous undo
1312          * step. this is fine in redo case (filedata->undo_direction > 0), but not in undo case,
1313          * where we need an extra flag defined when saving the next (future) step after the one we
1314          * want to restore, as we are supposed to 'come from' that future undo step, and not the
1315          * one before current one. */
1316         *r_is_memchunck_identical &= filedata->undo_direction > 0 ? chunk->is_identical :
1317                                                                     chunk->is_identical_future;
1318       }
1319     } while (totread < size);
1320 
1321     return (ssize_t)totread;
1322   }
1323 
1324   return 0;
1325 }
1326 
filedata_new(void)1327 static FileData *filedata_new(void)
1328 {
1329   FileData *fd = MEM_callocN(sizeof(FileData), "FileData");
1330 
1331   fd->filedes = -1;
1332   fd->gzfiledes = NULL;
1333 
1334   fd->memsdna = DNA_sdna_current_get();
1335 
1336   fd->datamap = oldnewmap_new();
1337   fd->globmap = oldnewmap_new();
1338   fd->libmap = oldnewmap_new();
1339 
1340   return fd;
1341 }
1342 
blo_decode_and_check(FileData * fd,ReportList * reports)1343 static FileData *blo_decode_and_check(FileData *fd, ReportList *reports)
1344 {
1345   decode_blender_header(fd);
1346 
1347   if (fd->flags & FD_FLAGS_FILE_OK) {
1348     const char *error_message = NULL;
1349     if (read_file_dna(fd, &error_message) == false) {
1350       BKE_reportf(
1351           reports, RPT_ERROR, "Failed to read blend file '%s': %s", fd->relabase, error_message);
1352       blo_filedata_free(fd);
1353       fd = NULL;
1354     }
1355   }
1356   else {
1357     BKE_reportf(
1358         reports, RPT_ERROR, "Failed to read blend file '%s', not a blend file", fd->relabase);
1359     blo_filedata_free(fd);
1360     fd = NULL;
1361   }
1362 
1363   return fd;
1364 }
1365 
blo_filedata_from_file_descriptor(const char * filepath,ReportList * reports,int file)1366 static FileData *blo_filedata_from_file_descriptor(const char *filepath,
1367                                                    ReportList *reports,
1368                                                    int file)
1369 {
1370   FileDataReadFn *read_fn = NULL;
1371   FileDataSeekFn *seek_fn = NULL; /* Optional. */
1372 
1373   gzFile gzfile = (gzFile)Z_NULL;
1374 
1375   char header[7];
1376 
1377   /* Regular file. */
1378   errno = 0;
1379   if (read(file, header, sizeof(header)) != sizeof(header)) {
1380     BKE_reportf(reports,
1381                 RPT_WARNING,
1382                 "Unable to read '%s': %s",
1383                 filepath,
1384                 errno ? strerror(errno) : TIP_("insufficient content"));
1385     return NULL;
1386   }
1387 
1388   BLI_lseek(file, 0, SEEK_SET);
1389 
1390   /* Regular file. */
1391   if (memcmp(header, "BLENDER", sizeof(header)) == 0) {
1392     read_fn = fd_read_data_from_file;
1393     seek_fn = fd_seek_data_from_file;
1394   }
1395 
1396   /* Gzip file. */
1397   errno = 0;
1398   if ((read_fn == NULL) &&
1399       /* Check header magic. */
1400       (header[0] == 0x1f && header[1] == 0x8b)) {
1401     gzfile = BLI_gzopen(filepath, "rb");
1402     if (gzfile == (gzFile)Z_NULL) {
1403       BKE_reportf(reports,
1404                   RPT_WARNING,
1405                   "Unable to open '%s': %s",
1406                   filepath,
1407                   errno ? strerror(errno) : TIP_("unknown error reading file"));
1408       return NULL;
1409     }
1410 
1411     /* 'seek_fn' is too slow for gzip, don't set it. */
1412     read_fn = fd_read_gzip_from_file;
1413     /* Caller must close. */
1414     file = -1;
1415   }
1416 
1417   if (read_fn == NULL) {
1418     BKE_reportf(reports, RPT_WARNING, "Unrecognized file format '%s'", filepath);
1419     return NULL;
1420   }
1421 
1422   FileData *fd = filedata_new();
1423 
1424   fd->filedes = file;
1425   fd->gzfiledes = gzfile;
1426 
1427   fd->read = read_fn;
1428   fd->seek = seek_fn;
1429 
1430   return fd;
1431 }
1432 
blo_filedata_from_file_open(const char * filepath,ReportList * reports)1433 static FileData *blo_filedata_from_file_open(const char *filepath, ReportList *reports)
1434 {
1435   errno = 0;
1436   const int file = BLI_open(filepath, O_BINARY | O_RDONLY, 0);
1437   if (file == -1) {
1438     BKE_reportf(reports,
1439                 RPT_WARNING,
1440                 "Unable to open '%s': %s",
1441                 filepath,
1442                 errno ? strerror(errno) : TIP_("unknown error reading file"));
1443     return NULL;
1444   }
1445   FileData *fd = blo_filedata_from_file_descriptor(filepath, reports, file);
1446   if ((fd == NULL) || (fd->filedes == -1)) {
1447     close(file);
1448   }
1449   return fd;
1450 }
1451 
1452 /* cannot be called with relative paths anymore! */
1453 /* on each new library added, it now checks for the current FileData and expands relativeness */
blo_filedata_from_file(const char * filepath,ReportList * reports)1454 FileData *blo_filedata_from_file(const char *filepath, ReportList *reports)
1455 {
1456   FileData *fd = blo_filedata_from_file_open(filepath, reports);
1457   if (fd != NULL) {
1458     /* needed for library_append and read_libraries */
1459     BLI_strncpy(fd->relabase, filepath, sizeof(fd->relabase));
1460 
1461     return blo_decode_and_check(fd, reports);
1462   }
1463   return NULL;
1464 }
1465 
1466 /**
1467  * Same as blo_filedata_from_file(), but does not reads DNA data, only header.
1468  * Use it for light access (e.g. thumbnail reading).
1469  */
blo_filedata_from_file_minimal(const char * filepath)1470 static FileData *blo_filedata_from_file_minimal(const char *filepath)
1471 {
1472   FileData *fd = blo_filedata_from_file_open(filepath, NULL);
1473   if (fd != NULL) {
1474     decode_blender_header(fd);
1475     if (fd->flags & FD_FLAGS_FILE_OK) {
1476       return fd;
1477     }
1478     blo_filedata_free(fd);
1479   }
1480   return NULL;
1481 }
1482 
fd_read_gzip_from_memory(FileData * filedata,void * buffer,size_t size,bool * UNUSED (r_is_memchunck_identical))1483 static ssize_t fd_read_gzip_from_memory(FileData *filedata,
1484                                         void *buffer,
1485                                         size_t size,
1486                                         bool *UNUSED(r_is_memchunck_identical))
1487 {
1488   int err;
1489 
1490   filedata->strm.next_out = (Bytef *)buffer;
1491   filedata->strm.avail_out = (uint)size;
1492 
1493   /* Inflate another chunk. */
1494   err = inflate(&filedata->strm, Z_SYNC_FLUSH);
1495 
1496   if (err == Z_STREAM_END) {
1497     return 0;
1498   }
1499   if (err != Z_OK) {
1500     printf("fd_read_gzip_from_memory: zlib error\n");
1501     return 0;
1502   }
1503 
1504   filedata->file_offset += size;
1505 
1506   return (ssize_t)size;
1507 }
1508 
fd_read_gzip_from_memory_init(FileData * fd)1509 static int fd_read_gzip_from_memory_init(FileData *fd)
1510 {
1511 
1512   fd->strm.next_in = (Bytef *)fd->buffer;
1513   fd->strm.avail_in = fd->buffersize;
1514   fd->strm.total_out = 0;
1515   fd->strm.zalloc = Z_NULL;
1516   fd->strm.zfree = Z_NULL;
1517 
1518   if (inflateInit2(&fd->strm, (16 + MAX_WBITS)) != Z_OK) {
1519     return 0;
1520   }
1521 
1522   fd->read = fd_read_gzip_from_memory;
1523 
1524   return 1;
1525 }
1526 
blo_filedata_from_memory(const void * mem,int memsize,ReportList * reports)1527 FileData *blo_filedata_from_memory(const void *mem, int memsize, ReportList *reports)
1528 {
1529   if (!mem || memsize < SIZEOFBLENDERHEADER) {
1530     BKE_report(reports, RPT_WARNING, (mem) ? TIP_("Unable to read") : TIP_("Unable to open"));
1531     return NULL;
1532   }
1533 
1534   FileData *fd = filedata_new();
1535   const char *cp = mem;
1536 
1537   fd->buffer = mem;
1538   fd->buffersize = memsize;
1539 
1540   /* test if gzip */
1541   if (cp[0] == 0x1f && cp[1] == 0x8b) {
1542     if (0 == fd_read_gzip_from_memory_init(fd)) {
1543       blo_filedata_free(fd);
1544       return NULL;
1545     }
1546   }
1547   else {
1548     fd->read = fd_read_from_memory;
1549   }
1550 
1551   fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
1552 
1553   return blo_decode_and_check(fd, reports);
1554 }
1555 
blo_filedata_from_memfile(MemFile * memfile,const struct BlendFileReadParams * params,ReportList * reports)1556 FileData *blo_filedata_from_memfile(MemFile *memfile,
1557                                     const struct BlendFileReadParams *params,
1558                                     ReportList *reports)
1559 {
1560   if (!memfile) {
1561     BKE_report(reports, RPT_WARNING, "Unable to open blend <memory>");
1562     return NULL;
1563   }
1564 
1565   FileData *fd = filedata_new();
1566   fd->memfile = memfile;
1567   fd->undo_direction = params->undo_direction;
1568 
1569   fd->read = fd_read_from_memfile;
1570   fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
1571 
1572   return blo_decode_and_check(fd, reports);
1573 }
1574 
blo_filedata_free(FileData * fd)1575 void blo_filedata_free(FileData *fd)
1576 {
1577   if (fd) {
1578     if (fd->filedes != -1) {
1579       close(fd->filedes);
1580     }
1581 
1582     if (fd->gzfiledes != NULL) {
1583       gzclose(fd->gzfiledes);
1584     }
1585 
1586     if (fd->strm.next_in) {
1587       if (inflateEnd(&fd->strm) != Z_OK) {
1588         printf("close gzip stream error\n");
1589       }
1590     }
1591 
1592     if (fd->buffer && !(fd->flags & FD_FLAGS_NOT_MY_BUFFER)) {
1593       MEM_freeN((void *)fd->buffer);
1594       fd->buffer = NULL;
1595     }
1596 
1597     /* Free all BHeadN data blocks */
1598 #ifndef NDEBUG
1599     BLI_freelistN(&fd->bhead_list);
1600 #else
1601     /* Sanity check we're not keeping memory we don't need. */
1602     LISTBASE_FOREACH_MUTABLE (BHeadN *, new_bhead, &fd->bhead_list) {
1603       if (fd->seek != NULL && BHEAD_USE_READ_ON_DEMAND(&new_bhead->bhead)) {
1604         BLI_assert(new_bhead->has_data == 0);
1605       }
1606       MEM_freeN(new_bhead);
1607     }
1608 #endif
1609 
1610     if (fd->filesdna) {
1611       DNA_sdna_free(fd->filesdna);
1612     }
1613     if (fd->compflags) {
1614       MEM_freeN((void *)fd->compflags);
1615     }
1616     if (fd->reconstruct_info) {
1617       DNA_reconstruct_info_free(fd->reconstruct_info);
1618     }
1619 
1620     if (fd->datamap) {
1621       oldnewmap_free(fd->datamap);
1622     }
1623     if (fd->globmap) {
1624       oldnewmap_free(fd->globmap);
1625     }
1626     if (fd->packedmap) {
1627       oldnewmap_free(fd->packedmap);
1628     }
1629     if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP)) {
1630       oldnewmap_free(fd->libmap);
1631     }
1632     if (fd->old_idmap != NULL) {
1633       BKE_main_idmap_destroy(fd->old_idmap);
1634     }
1635     blo_cache_storage_end(fd);
1636     if (fd->bheadmap) {
1637       MEM_freeN(fd->bheadmap);
1638     }
1639 
1640 #ifdef USE_GHASH_BHEAD
1641     if (fd->bhead_idname_hash) {
1642       BLI_ghash_free(fd->bhead_idname_hash, NULL, NULL);
1643     }
1644 #endif
1645 
1646     MEM_freeN(fd);
1647   }
1648 }
1649 
1650 /** \} */
1651 
1652 /* -------------------------------------------------------------------- */
1653 /** \name Public Utilities
1654  * \{ */
1655 
1656 /**
1657  * Check whether given path ends with a blend file compatible extension
1658  * (`.blend`, `.ble` or `.blend.gz`).
1659  *
1660  * \param str: The path to check.
1661  * \return true is this path ends with a blender file extension.
1662  */
BLO_has_bfile_extension(const char * str)1663 bool BLO_has_bfile_extension(const char *str)
1664 {
1665   const char *ext_test[4] = {".blend", ".ble", ".blend.gz", NULL};
1666   return BLI_path_extension_check_array(str, ext_test);
1667 }
1668 
1669 /**
1670  * Try to explode given path into its 'library components'
1671  * (i.e. a .blend file, id type/group, and data-block itself).
1672  *
1673  * \param path: the full path to explode.
1674  * \param r_dir: the string that'll contain path up to blend file itself ('library' path).
1675  * WARNING! Must be #FILE_MAX_LIBEXTRA long (it also stores group and name strings)!
1676  * \param r_group: the string that'll contain 'group' part of the path, if any. May be NULL.
1677  * \param r_name: the string that'll contain data's name part of the path, if any. May be NULL.
1678  * \return true if path contains a blend file.
1679  */
BLO_library_path_explode(const char * path,char * r_dir,char ** r_group,char ** r_name)1680 bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, char **r_name)
1681 {
1682   /* We might get some data names with slashes,
1683    * so we have to go up in path until we find blend file itself,
1684    * then we know next path item is group, and everything else is data name. */
1685   char *slash = NULL, *prev_slash = NULL, c = '\0';
1686 
1687   r_dir[0] = '\0';
1688   if (r_group) {
1689     *r_group = NULL;
1690   }
1691   if (r_name) {
1692     *r_name = NULL;
1693   }
1694 
1695   /* if path leads to an existing directory, we can be sure we're not (in) a library */
1696   if (BLI_is_dir(path)) {
1697     return false;
1698   }
1699 
1700   strcpy(r_dir, path);
1701 
1702   while ((slash = (char *)BLI_path_slash_rfind(r_dir))) {
1703     char tc = *slash;
1704     *slash = '\0';
1705     if (BLO_has_bfile_extension(r_dir) && BLI_is_file(r_dir)) {
1706       break;
1707     }
1708     if (STREQ(r_dir, BLO_EMBEDDED_STARTUP_BLEND)) {
1709       break;
1710     }
1711 
1712     if (prev_slash) {
1713       *prev_slash = c;
1714     }
1715     prev_slash = slash;
1716     c = tc;
1717   }
1718 
1719   if (!slash) {
1720     return false;
1721   }
1722 
1723   if (slash[1] != '\0') {
1724     BLI_assert(strlen(slash + 1) < BLO_GROUP_MAX);
1725     if (r_group) {
1726       *r_group = slash + 1;
1727     }
1728   }
1729 
1730   if (prev_slash && (prev_slash[1] != '\0')) {
1731     BLI_assert(strlen(prev_slash + 1) < MAX_ID_NAME - 2);
1732     if (r_name) {
1733       *r_name = prev_slash + 1;
1734     }
1735   }
1736 
1737   return true;
1738 }
1739 
1740 /**
1741  * Does a very light reading of given .blend file to extract its stored thumbnail.
1742  *
1743  * \param filepath: The path of the file to extract thumbnail from.
1744  * \return The raw thumbnail
1745  * (MEM-allocated, as stored in file, use #BKE_main_thumbnail_to_imbuf()
1746  * to convert it to ImBuf image).
1747  */
BLO_thumbnail_from_file(const char * filepath)1748 BlendThumbnail *BLO_thumbnail_from_file(const char *filepath)
1749 {
1750   FileData *fd;
1751   BlendThumbnail *data = NULL;
1752   int *fd_data;
1753 
1754   fd = blo_filedata_from_file_minimal(filepath);
1755   fd_data = fd ? read_file_thumbnail(fd) : NULL;
1756 
1757   if (fd_data) {
1758     const int width = fd_data[0];
1759     const int height = fd_data[1];
1760     if (BLEN_THUMB_MEMSIZE_IS_VALID(width, height)) {
1761       const size_t sz = BLEN_THUMB_MEMSIZE(width, height);
1762       data = MEM_mallocN(sz, __func__);
1763       if (data) {
1764         BLI_assert((sz - sizeof(*data)) ==
1765                    (BLEN_THUMB_MEMSIZE_FILE(width, height) - (sizeof(*fd_data) * 2)));
1766         data->width = width;
1767         data->height = height;
1768         memcpy(data->rect, &fd_data[2], sz - sizeof(*data));
1769       }
1770     }
1771   }
1772 
1773   blo_filedata_free(fd);
1774 
1775   return data;
1776 }
1777 
1778 /** \} */
1779 
1780 /* -------------------------------------------------------------------- */
1781 /** \name Old/New Pointer Map
1782  * \{ */
1783 
1784 /* only direct databocks */
newdataadr(FileData * fd,const void * adr)1785 static void *newdataadr(FileData *fd, const void *adr)
1786 {
1787   return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
1788 }
1789 
1790 /* only direct databocks */
newdataadr_no_us(FileData * fd,const void * adr)1791 static void *newdataadr_no_us(FileData *fd, const void *adr)
1792 {
1793   return oldnewmap_lookup_and_inc(fd->datamap, adr, false);
1794 }
1795 
1796 /* direct datablocks with global linking */
blo_read_get_new_globaldata_address(FileData * fd,const void * adr)1797 void *blo_read_get_new_globaldata_address(FileData *fd, const void *adr)
1798 {
1799   return oldnewmap_lookup_and_inc(fd->globmap, adr, true);
1800 }
1801 
1802 /* used to restore packed data after undo */
newpackedadr(FileData * fd,const void * adr)1803 static void *newpackedadr(FileData *fd, const void *adr)
1804 {
1805   if (fd->packedmap && adr) {
1806     return oldnewmap_lookup_and_inc(fd->packedmap, adr, true);
1807   }
1808 
1809   return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
1810 }
1811 
1812 /* only lib data */
newlibadr(FileData * fd,const void * lib,const void * adr)1813 static void *newlibadr(FileData *fd, const void *lib, const void *adr)
1814 {
1815   return oldnewmap_liblookup(fd->libmap, adr, lib);
1816 }
1817 
1818 /* only lib data */
blo_do_versions_newlibadr(FileData * fd,const void * lib,const void * adr)1819 void *blo_do_versions_newlibadr(FileData *fd, const void *lib, const void *adr)
1820 {
1821   return newlibadr(fd, lib, adr);
1822 }
1823 
1824 /* increases user number */
change_link_placeholder_to_real_ID_pointer_fd(FileData * fd,const void * old,void * new)1825 static void change_link_placeholder_to_real_ID_pointer_fd(FileData *fd, const void *old, void *new)
1826 {
1827   for (int i = 0; i < fd->libmap->nentries; i++) {
1828     OldNew *entry = &fd->libmap->entries[i];
1829 
1830     if (old == entry->newp && entry->nr == ID_LINK_PLACEHOLDER) {
1831       entry->newp = new;
1832       if (new) {
1833         entry->nr = GS(((ID *)new)->name);
1834       }
1835     }
1836   }
1837 }
1838 
change_link_placeholder_to_real_ID_pointer(ListBase * mainlist,FileData * basefd,void * old,void * new)1839 static void change_link_placeholder_to_real_ID_pointer(ListBase *mainlist,
1840                                                        FileData *basefd,
1841                                                        void *old,
1842                                                        void *new)
1843 {
1844   LISTBASE_FOREACH (Main *, mainptr, mainlist) {
1845     FileData *fd;
1846 
1847     if (mainptr->curlib) {
1848       fd = mainptr->curlib->filedata;
1849     }
1850     else {
1851       fd = basefd;
1852     }
1853 
1854     if (fd) {
1855       change_link_placeholder_to_real_ID_pointer_fd(fd, old, new);
1856     }
1857   }
1858 }
1859 
1860 /* lib linked proxy objects point to our local data, we need
1861  * to clear that pointer before reading the undo memfile since
1862  * the object might be removed, it is set again in reading
1863  * if the local object still exists.
1864  * This is only valid for local proxy objects though, linked ones should not be affected here.
1865  */
blo_clear_proxy_pointers_from_lib(Main * oldmain)1866 void blo_clear_proxy_pointers_from_lib(Main *oldmain)
1867 {
1868   LISTBASE_FOREACH (Object *, ob, &oldmain->objects) {
1869     if (ob->id.lib != NULL && ob->proxy_from != NULL && ob->proxy_from->id.lib == NULL) {
1870       ob->proxy_from = NULL;
1871     }
1872   }
1873 }
1874 
1875 /* XXX disabled this feature - packed files also belong in temp saves and quit.blend,
1876  * to make restore work. */
1877 
insert_packedmap(FileData * fd,PackedFile * pf)1878 static void insert_packedmap(FileData *fd, PackedFile *pf)
1879 {
1880   oldnewmap_insert(fd->packedmap, pf, pf, 0);
1881   oldnewmap_insert(fd->packedmap, pf->data, pf->data, 0);
1882 }
1883 
blo_make_packed_pointer_map(FileData * fd,Main * oldmain)1884 void blo_make_packed_pointer_map(FileData *fd, Main *oldmain)
1885 {
1886   fd->packedmap = oldnewmap_new();
1887 
1888   LISTBASE_FOREACH (Image *, ima, &oldmain->images) {
1889     if (ima->packedfile) {
1890       insert_packedmap(fd, ima->packedfile);
1891     }
1892 
1893     LISTBASE_FOREACH (ImagePackedFile *, imapf, &ima->packedfiles) {
1894       if (imapf->packedfile) {
1895         insert_packedmap(fd, imapf->packedfile);
1896       }
1897     }
1898   }
1899 
1900   LISTBASE_FOREACH (VFont *, vfont, &oldmain->fonts) {
1901     if (vfont->packedfile) {
1902       insert_packedmap(fd, vfont->packedfile);
1903     }
1904   }
1905 
1906   LISTBASE_FOREACH (bSound *, sound, &oldmain->sounds) {
1907     if (sound->packedfile) {
1908       insert_packedmap(fd, sound->packedfile);
1909     }
1910   }
1911 
1912   LISTBASE_FOREACH (Volume *, volume, &oldmain->volumes) {
1913     if (volume->packedfile) {
1914       insert_packedmap(fd, volume->packedfile);
1915     }
1916   }
1917 
1918   LISTBASE_FOREACH (Library *, lib, &oldmain->libraries) {
1919     if (lib->packedfile) {
1920       insert_packedmap(fd, lib->packedfile);
1921     }
1922   }
1923 }
1924 
1925 /* set old main packed data to zero if it has been restored */
1926 /* this works because freeing old main only happens after this call */
blo_end_packed_pointer_map(FileData * fd,Main * oldmain)1927 void blo_end_packed_pointer_map(FileData *fd, Main *oldmain)
1928 {
1929   OldNew *entry = fd->packedmap->entries;
1930 
1931   /* used entries were restored, so we put them to zero */
1932   for (int i = 0; i < fd->packedmap->nentries; i++, entry++) {
1933     if (entry->nr > 0) {
1934       entry->newp = NULL;
1935     }
1936   }
1937 
1938   LISTBASE_FOREACH (Image *, ima, &oldmain->images) {
1939     ima->packedfile = newpackedadr(fd, ima->packedfile);
1940 
1941     LISTBASE_FOREACH (ImagePackedFile *, imapf, &ima->packedfiles) {
1942       imapf->packedfile = newpackedadr(fd, imapf->packedfile);
1943     }
1944   }
1945 
1946   LISTBASE_FOREACH (VFont *, vfont, &oldmain->fonts) {
1947     vfont->packedfile = newpackedadr(fd, vfont->packedfile);
1948   }
1949 
1950   LISTBASE_FOREACH (bSound *, sound, &oldmain->sounds) {
1951     sound->packedfile = newpackedadr(fd, sound->packedfile);
1952   }
1953 
1954   LISTBASE_FOREACH (Library *, lib, &oldmain->libraries) {
1955     lib->packedfile = newpackedadr(fd, lib->packedfile);
1956   }
1957 
1958   LISTBASE_FOREACH (Volume *, volume, &oldmain->volumes) {
1959     volume->packedfile = newpackedadr(fd, volume->packedfile);
1960   }
1961 }
1962 
1963 /* undo file support: add all library pointers in lookup */
blo_add_library_pointer_map(ListBase * old_mainlist,FileData * fd)1964 void blo_add_library_pointer_map(ListBase *old_mainlist, FileData *fd)
1965 {
1966   ListBase *lbarray[MAX_LIBARRAY];
1967 
1968   LISTBASE_FOREACH (Main *, ptr, old_mainlist) {
1969     int i = set_listbasepointers(ptr, lbarray);
1970     while (i--) {
1971       LISTBASE_FOREACH (ID *, id, lbarray[i]) {
1972         oldnewmap_insert(fd->libmap, id, id, GS(id->name));
1973       }
1974     }
1975   }
1976 
1977   fd->old_mainlist = old_mainlist;
1978 }
1979 
1980 /* Build a GSet of old main (we only care about local data here, so we can do that after
1981  * split_main() call. */
blo_make_old_idmap_from_main(FileData * fd,Main * bmain)1982 void blo_make_old_idmap_from_main(FileData *fd, Main *bmain)
1983 {
1984   if (fd->old_idmap != NULL) {
1985     BKE_main_idmap_destroy(fd->old_idmap);
1986   }
1987   fd->old_idmap = BKE_main_idmap_create(bmain, false, NULL, MAIN_IDMAP_TYPE_UUID);
1988 }
1989 
1990 typedef struct BLOCacheStorage {
1991   GHash *cache_map;
1992   MemArena *memarena;
1993 } BLOCacheStorage;
1994 
1995 /** Register a cache data entry to be preserved when reading some undo memfile. */
blo_cache_storage_entry_register(ID * id,const IDCacheKey * key,void ** UNUSED (cache_p),uint UNUSED (flags),void * cache_storage_v)1996 static void blo_cache_storage_entry_register(ID *id,
1997                                              const IDCacheKey *key,
1998                                              void **UNUSED(cache_p),
1999                                              uint UNUSED(flags),
2000                                              void *cache_storage_v)
2001 {
2002   BLI_assert(key->id_session_uuid == id->session_uuid);
2003   UNUSED_VARS_NDEBUG(id);
2004 
2005   BLOCacheStorage *cache_storage = cache_storage_v;
2006   BLI_assert(!BLI_ghash_haskey(cache_storage->cache_map, key));
2007 
2008   IDCacheKey *storage_key = BLI_memarena_alloc(cache_storage->memarena, sizeof(*storage_key));
2009   *storage_key = *key;
2010   BLI_ghash_insert(cache_storage->cache_map, storage_key, POINTER_FROM_UINT(0));
2011 }
2012 
2013 /** Restore a cache data entry from old ID into new one, when reading some undo memfile. */
blo_cache_storage_entry_restore_in_new(ID * UNUSED (id),const IDCacheKey * key,void ** cache_p,uint flags,void * cache_storage_v)2014 static void blo_cache_storage_entry_restore_in_new(
2015     ID *UNUSED(id), const IDCacheKey *key, void **cache_p, uint flags, void *cache_storage_v)
2016 {
2017   BLOCacheStorage *cache_storage = cache_storage_v;
2018 
2019   if (cache_storage == NULL) {
2020     /* In non-undo case, only clear the pointer if it is a purely runtime one.
2021      * If it may be stored in a persistent way in the .blend file, direct_link code is responsible
2022      * to properly deal with it. */
2023     if ((flags & IDTYPE_CACHE_CB_FLAGS_PERSISTENT) == 0) {
2024       *cache_p = NULL;
2025     }
2026     return;
2027   }
2028 
2029   void **value = BLI_ghash_lookup_p(cache_storage->cache_map, key);
2030   if (value == NULL) {
2031     *cache_p = NULL;
2032     return;
2033   }
2034   *value = POINTER_FROM_UINT(POINTER_AS_UINT(*value) + 1);
2035   *cache_p = key->cache_v;
2036 }
2037 
2038 /** Clear as needed a cache data entry from old ID, when reading some undo memfile. */
blo_cache_storage_entry_clear_in_old(ID * UNUSED (id),const IDCacheKey * key,void ** cache_p,uint UNUSED (flags),void * cache_storage_v)2039 static void blo_cache_storage_entry_clear_in_old(ID *UNUSED(id),
2040                                                  const IDCacheKey *key,
2041                                                  void **cache_p,
2042                                                  uint UNUSED(flags),
2043                                                  void *cache_storage_v)
2044 {
2045   BLOCacheStorage *cache_storage = cache_storage_v;
2046 
2047   void **value = BLI_ghash_lookup_p(cache_storage->cache_map, key);
2048   if (value == NULL) {
2049     *cache_p = NULL;
2050     return;
2051   }
2052   /* If that cache has been restored into some new ID, we want to remove it from old one, otherwise
2053    * keep it there so that it gets properly freed together with its ID. */
2054   *cache_p = POINTER_AS_UINT(*value) != 0 ? NULL : key->cache_v;
2055 }
2056 
blo_cache_storage_init(FileData * fd,Main * bmain)2057 void blo_cache_storage_init(FileData *fd, Main *bmain)
2058 {
2059   if (fd->memfile != NULL) {
2060     BLI_assert(fd->cache_storage == NULL);
2061     fd->cache_storage = MEM_mallocN(sizeof(*fd->cache_storage), __func__);
2062     fd->cache_storage->memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
2063     fd->cache_storage->cache_map = BLI_ghash_new(
2064         BKE_idtype_cache_key_hash, BKE_idtype_cache_key_cmp, __func__);
2065 
2066     ListBase *lb;
2067     FOREACH_MAIN_LISTBASE_BEGIN (bmain, lb) {
2068       ID *id = lb->first;
2069       if (id == NULL) {
2070         continue;
2071       }
2072 
2073       const IDTypeInfo *type_info = BKE_idtype_get_info_from_id(id);
2074       if (type_info->foreach_cache == NULL) {
2075         continue;
2076       }
2077 
2078       FOREACH_MAIN_LISTBASE_ID_BEGIN (lb, id) {
2079         if (ID_IS_LINKED(id)) {
2080           continue;
2081         }
2082         BKE_idtype_id_foreach_cache(id, blo_cache_storage_entry_register, fd->cache_storage);
2083       }
2084       FOREACH_MAIN_LISTBASE_ID_END;
2085     }
2086     FOREACH_MAIN_LISTBASE_END;
2087   }
2088   else {
2089     fd->cache_storage = NULL;
2090   }
2091 }
2092 
blo_cache_storage_old_bmain_clear(FileData * fd,Main * bmain_old)2093 void blo_cache_storage_old_bmain_clear(FileData *fd, Main *bmain_old)
2094 {
2095   if (fd->cache_storage != NULL) {
2096     ListBase *lb;
2097     FOREACH_MAIN_LISTBASE_BEGIN (bmain_old, lb) {
2098       ID *id = lb->first;
2099       if (id == NULL) {
2100         continue;
2101       }
2102 
2103       const IDTypeInfo *type_info = BKE_idtype_get_info_from_id(id);
2104       if (type_info->foreach_cache == NULL) {
2105         continue;
2106       }
2107 
2108       FOREACH_MAIN_LISTBASE_ID_BEGIN (lb, id) {
2109         if (ID_IS_LINKED(id)) {
2110           continue;
2111         }
2112         BKE_idtype_id_foreach_cache(id, blo_cache_storage_entry_clear_in_old, fd->cache_storage);
2113       }
2114       FOREACH_MAIN_LISTBASE_ID_END;
2115     }
2116     FOREACH_MAIN_LISTBASE_END;
2117   }
2118 }
2119 
blo_cache_storage_end(FileData * fd)2120 void blo_cache_storage_end(FileData *fd)
2121 {
2122   if (fd->cache_storage != NULL) {
2123     BLI_ghash_free(fd->cache_storage->cache_map, NULL, NULL);
2124     BLI_memarena_free(fd->cache_storage->memarena);
2125     MEM_freeN(fd->cache_storage);
2126     fd->cache_storage = NULL;
2127   }
2128 }
2129 
2130 /** \} */
2131 
2132 /* -------------------------------------------------------------------- */
2133 /** \name DNA Struct Loading
2134  * \{ */
2135 
switch_endian_structs(const struct SDNA * filesdna,BHead * bhead)2136 static void switch_endian_structs(const struct SDNA *filesdna, BHead *bhead)
2137 {
2138   int blocksize, nblocks;
2139   char *data;
2140 
2141   data = (char *)(bhead + 1);
2142   blocksize = filesdna->types_size[filesdna->structs[bhead->SDNAnr]->type];
2143 
2144   nblocks = bhead->nr;
2145   while (nblocks--) {
2146     DNA_struct_switch_endian(filesdna, bhead->SDNAnr, data);
2147 
2148     data += blocksize;
2149   }
2150 }
2151 
read_struct(FileData * fd,BHead * bh,const char * blockname)2152 static void *read_struct(FileData *fd, BHead *bh, const char *blockname)
2153 {
2154   void *temp = NULL;
2155 
2156   if (bh->len) {
2157 #ifdef USE_BHEAD_READ_ON_DEMAND
2158     BHead *bh_orig = bh;
2159 #endif
2160 
2161     /* switch is based on file dna */
2162     if (bh->SDNAnr && (fd->flags & FD_FLAGS_SWITCH_ENDIAN)) {
2163 #ifdef USE_BHEAD_READ_ON_DEMAND
2164       if (BHEADN_FROM_BHEAD(bh)->has_data == false) {
2165         bh = blo_bhead_read_full(fd, bh);
2166         if (UNLIKELY(bh == NULL)) {
2167           fd->flags &= ~FD_FLAGS_FILE_OK;
2168           return NULL;
2169         }
2170       }
2171 #endif
2172       switch_endian_structs(fd->filesdna, bh);
2173     }
2174 
2175     if (fd->compflags[bh->SDNAnr] != SDNA_CMP_REMOVED) {
2176       if (fd->compflags[bh->SDNAnr] == SDNA_CMP_NOT_EQUAL) {
2177 #ifdef USE_BHEAD_READ_ON_DEMAND
2178         if (BHEADN_FROM_BHEAD(bh)->has_data == false) {
2179           bh = blo_bhead_read_full(fd, bh);
2180           if (UNLIKELY(bh == NULL)) {
2181             fd->flags &= ~FD_FLAGS_FILE_OK;
2182             return NULL;
2183           }
2184         }
2185 #endif
2186         temp = DNA_struct_reconstruct(fd->reconstruct_info, bh->SDNAnr, bh->nr, (bh + 1));
2187       }
2188       else {
2189         /* SDNA_CMP_EQUAL */
2190         temp = MEM_mallocN(bh->len, blockname);
2191 #ifdef USE_BHEAD_READ_ON_DEMAND
2192         if (BHEADN_FROM_BHEAD(bh)->has_data) {
2193           memcpy(temp, (bh + 1), bh->len);
2194         }
2195         else {
2196           /* Instead of allocating the bhead, then copying it,
2197            * read the data from the file directly into the memory. */
2198           if (UNLIKELY(!blo_bhead_read_data(fd, bh, temp))) {
2199             fd->flags &= ~FD_FLAGS_FILE_OK;
2200             MEM_freeN(temp);
2201             temp = NULL;
2202           }
2203         }
2204 #else
2205         memcpy(temp, (bh + 1), bh->len);
2206 #endif
2207       }
2208     }
2209 
2210 #ifdef USE_BHEAD_READ_ON_DEMAND
2211     if (bh_orig != bh) {
2212       MEM_freeN(BHEADN_FROM_BHEAD(bh));
2213     }
2214 #endif
2215   }
2216 
2217   return temp;
2218 }
2219 
2220 /* Like read_struct, but gets a pointer without allocating. Only works for
2221  * undo since DNA must match. */
peek_struct_undo(FileData * fd,BHead * bhead)2222 static const void *peek_struct_undo(FileData *fd, BHead *bhead)
2223 {
2224   BLI_assert(fd->memfile != NULL);
2225   UNUSED_VARS_NDEBUG(fd);
2226   return (bhead->len) ? (const void *)(bhead + 1) : NULL;
2227 }
2228 
link_glob_list(FileData * fd,ListBase * lb)2229 static void link_glob_list(FileData *fd, ListBase *lb) /* for glob data */
2230 {
2231   Link *ln, *prev;
2232   void *poin;
2233 
2234   if (BLI_listbase_is_empty(lb)) {
2235     return;
2236   }
2237   poin = newdataadr(fd, lb->first);
2238   if (lb->first) {
2239     oldnewmap_insert(fd->globmap, lb->first, poin, 0);
2240   }
2241   lb->first = poin;
2242 
2243   ln = lb->first;
2244   prev = NULL;
2245   while (ln) {
2246     poin = newdataadr(fd, ln->next);
2247     if (ln->next) {
2248       oldnewmap_insert(fd->globmap, ln->next, poin, 0);
2249     }
2250     ln->next = poin;
2251     ln->prev = prev;
2252     prev = ln;
2253     ln = ln->next;
2254   }
2255   lb->last = prev;
2256 }
2257 
2258 /** \} */
2259 
2260 /* -------------------------------------------------------------------- */
2261 /** \name Read ID
2262  * \{ */
2263 
2264 static void lib_link_id(BlendLibReader *reader, ID *id);
2265 static void lib_link_collection(BlendLibReader *reader, Collection *collection);
2266 
lib_link_id_embedded_id(BlendLibReader * reader,ID * id)2267 static void lib_link_id_embedded_id(BlendLibReader *reader, ID *id)
2268 {
2269 
2270   /* Handle 'private IDs'. */
2271   bNodeTree *nodetree = ntreeFromID(id);
2272   if (nodetree != NULL) {
2273     lib_link_id(reader, &nodetree->id);
2274     ntreeBlendReadLib(reader, nodetree);
2275   }
2276 
2277   if (GS(id->name) == ID_SCE) {
2278     Scene *scene = (Scene *)id;
2279     if (scene->master_collection != NULL) {
2280       lib_link_id(reader, &scene->master_collection->id);
2281       lib_link_collection(reader, scene->master_collection);
2282     }
2283   }
2284 }
2285 
lib_link_id(BlendLibReader * reader,ID * id)2286 static void lib_link_id(BlendLibReader *reader, ID *id)
2287 {
2288   /* Note: WM IDProperties are never written to file, hence they should always be NULL here. */
2289   BLI_assert((GS(id->name) != ID_WM) || id->properties == NULL);
2290   IDP_BlendReadLib(reader, id->properties);
2291 
2292   AnimData *adt = BKE_animdata_from_id(id);
2293   if (adt != NULL) {
2294     BKE_animdata_blend_read_lib(reader, id, adt);
2295   }
2296 
2297   if (id->override_library) {
2298     BLO_read_id_address(reader, id->lib, &id->override_library->reference);
2299     BLO_read_id_address(reader, id->lib, &id->override_library->storage);
2300   }
2301 
2302   lib_link_id_embedded_id(reader, id);
2303 }
2304 
direct_link_id_override_property_operation_cb(BlendDataReader * reader,void * data)2305 static void direct_link_id_override_property_operation_cb(BlendDataReader *reader, void *data)
2306 {
2307   IDOverrideLibraryPropertyOperation *opop = data;
2308 
2309   BLO_read_data_address(reader, &opop->subitem_reference_name);
2310   BLO_read_data_address(reader, &opop->subitem_local_name);
2311 
2312   opop->tag = 0; /* Runtime only. */
2313 }
2314 
direct_link_id_override_property_cb(BlendDataReader * reader,void * data)2315 static void direct_link_id_override_property_cb(BlendDataReader *reader, void *data)
2316 {
2317   IDOverrideLibraryProperty *op = data;
2318 
2319   BLO_read_data_address(reader, &op->rna_path);
2320 
2321   op->tag = 0; /* Runtime only. */
2322 
2323   BLO_read_list_cb(reader, &op->operations, direct_link_id_override_property_operation_cb);
2324 }
2325 
2326 static void direct_link_id_common(
2327     BlendDataReader *reader, Library *current_library, ID *id, ID *id_old, const int tag);
2328 static void direct_link_collection(BlendDataReader *reader, Collection *collection);
2329 
direct_link_id_embedded_id(BlendDataReader * reader,Library * current_library,ID * id,ID * id_old)2330 static void direct_link_id_embedded_id(BlendDataReader *reader,
2331                                        Library *current_library,
2332                                        ID *id,
2333                                        ID *id_old)
2334 {
2335   /* Handle 'private IDs'. */
2336   bNodeTree **nodetree = BKE_ntree_ptr_from_id(id);
2337   if (nodetree != NULL && *nodetree != NULL) {
2338     BLO_read_data_address(reader, nodetree);
2339     direct_link_id_common(reader,
2340                           current_library,
2341                           (ID *)*nodetree,
2342                           id_old != NULL ? (ID *)ntreeFromID(id_old) : NULL,
2343                           0);
2344     ntreeBlendReadData(reader, *nodetree);
2345   }
2346 
2347   if (GS(id->name) == ID_SCE) {
2348     Scene *scene = (Scene *)id;
2349     if (scene->master_collection != NULL) {
2350       BLO_read_data_address(reader, &scene->master_collection);
2351       direct_link_id_common(reader,
2352                             current_library,
2353                             &scene->master_collection->id,
2354                             id_old != NULL ? &((Scene *)id_old)->master_collection->id : NULL,
2355                             0);
2356       direct_link_collection(reader, scene->master_collection);
2357     }
2358   }
2359 }
2360 
direct_link_id_restore_recalc_exceptions(const ID * id_current)2361 static int direct_link_id_restore_recalc_exceptions(const ID *id_current)
2362 {
2363   /* Exception for armature objects, where the pose has direct points to the
2364    * armature databolock. */
2365   if (GS(id_current->name) == ID_OB && ((Object *)id_current)->pose) {
2366     return ID_RECALC_GEOMETRY;
2367   }
2368 
2369   return 0;
2370 }
2371 
direct_link_id_restore_recalc(const FileData * fd,const ID * id_target,const ID * id_current,const bool is_identical)2372 static int direct_link_id_restore_recalc(const FileData *fd,
2373                                          const ID *id_target,
2374                                          const ID *id_current,
2375                                          const bool is_identical)
2376 {
2377   /* These are the evaluations that had not been performed yet at the time the
2378    * target undo state was written. These need to be done again, since they may
2379    * flush back changes to the original datablock. */
2380   int recalc = id_target->recalc;
2381 
2382   if (id_current == NULL) {
2383     /* ID does not currently exist in the database, so also will not exist in
2384      * the dependency graphs. That means it will be newly created and as a
2385      * result also fully re-evaluated regardless of the recalc flag set here. */
2386     recalc |= ID_RECALC_ALL;
2387   }
2388   else {
2389     /* If the contents datablock changed, the depsgraph needs to copy the
2390      * datablock again to ensure it matches the original datablock. */
2391     if (!is_identical) {
2392       recalc |= ID_RECALC_COPY_ON_WRITE;
2393     }
2394 
2395     /* Special exceptions. */
2396     recalc |= direct_link_id_restore_recalc_exceptions(id_current);
2397 
2398     /* Evaluations for the current state that have not been performed yet
2399      * by the time we are performing this undo step. */
2400     recalc |= id_current->recalc;
2401 
2402     /* Tags that were set between the target state and the current state,
2403      * that we need to perform again. */
2404     if (fd->undo_direction < 0) {
2405       /* Undo: tags from target to the current state. */
2406       recalc |= id_current->recalc_up_to_undo_push;
2407     }
2408     else {
2409       /* Redo: tags from current to the target state. */
2410       recalc |= id_target->recalc_up_to_undo_push;
2411     }
2412   }
2413 
2414   return recalc;
2415 }
2416 
direct_link_id_common(BlendDataReader * reader,Library * current_library,ID * id,ID * id_old,const int tag)2417 static void direct_link_id_common(
2418     BlendDataReader *reader, Library *current_library, ID *id, ID *id_old, const int tag)
2419 {
2420   if (!BLO_read_data_is_undo(reader)) {
2421     /* When actually reading a file , we do want to reset/re-generate session uuids.
2422      * In undo case, we want to re-use existing ones. */
2423     id->session_uuid = MAIN_ID_SESSION_UUID_UNSET;
2424   }
2425 
2426   BKE_lib_libblock_session_uuid_ensure(id);
2427 
2428   id->lib = current_library;
2429   id->us = ID_FAKE_USERS(id);
2430   id->icon_id = 0;
2431   id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */
2432   id->orig_id = NULL;
2433   id->py_instance = NULL;
2434 
2435   /* Initialize with provided tag. */
2436   id->tag = tag;
2437 
2438   if (tag & LIB_TAG_ID_LINK_PLACEHOLDER) {
2439     /* For placeholder we only need to set the tag and properly initialize generic ID fields above,
2440      * no further data to read. */
2441     return;
2442   }
2443 
2444   /*link direct data of ID properties*/
2445   if (id->properties) {
2446     BLO_read_data_address(reader, &id->properties);
2447     /* this case means the data was written incorrectly, it should not happen */
2448     IDP_BlendDataRead(reader, &id->properties);
2449   }
2450 
2451   id->flag &= ~LIB_INDIRECT_WEAK_LINK;
2452 
2453   /* NOTE: It is important to not clear the recalc flags for undo/redo.
2454    * Preserving recalc flags on redo/undo is the only way to make dependency graph detect
2455    * that animation is to be evaluated on undo/redo. If this is not enforced by the recalc
2456    * flags dependency graph does not do animation update to avoid loss of unkeyed changes.,
2457    * which conflicts with undo/redo of changes to animation data itself.
2458    *
2459    * But for regular file load we clear the flag, since the flags might have been changed since
2460    * the version the file has been saved with. */
2461   if (!BLO_read_data_is_undo(reader)) {
2462     id->recalc = 0;
2463     id->recalc_after_undo_push = 0;
2464   }
2465   else if ((reader->fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0) {
2466     id->recalc = direct_link_id_restore_recalc(reader->fd, id, id_old, false);
2467     id->recalc_after_undo_push = 0;
2468   }
2469 
2470   /* Link direct data of overrides. */
2471   if (id->override_library) {
2472     BLO_read_data_address(reader, &id->override_library);
2473     BLO_read_list_cb(
2474         reader, &id->override_library->properties, direct_link_id_override_property_cb);
2475     id->override_library->runtime = NULL;
2476   }
2477 
2478   DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
2479   if (drawdata) {
2480     BLI_listbase_clear((ListBase *)drawdata);
2481   }
2482 
2483   /* Handle 'private IDs'. */
2484   direct_link_id_embedded_id(reader, current_library, id, id_old);
2485 }
2486 
2487 /** \} */
2488 
2489 /* -------------------------------------------------------------------- */
2490 /** \name Read Animation (legacy for version patching)
2491  * \{ */
2492 
2493 /* XXX deprecated - old animation system */
lib_link_ipo(BlendLibReader * reader,Ipo * ipo)2494 static void lib_link_ipo(BlendLibReader *reader, Ipo *ipo)
2495 {
2496   LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) {
2497     if (icu->driver) {
2498       BLO_read_id_address(reader, ipo->id.lib, &icu->driver->ob);
2499     }
2500   }
2501 }
2502 
2503 /* XXX deprecated - old animation system */
direct_link_ipo(BlendDataReader * reader,Ipo * ipo)2504 static void direct_link_ipo(BlendDataReader *reader, Ipo *ipo)
2505 {
2506   BLO_read_list(reader, &(ipo->curve));
2507 
2508   LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) {
2509     BLO_read_data_address(reader, &icu->bezt);
2510     BLO_read_data_address(reader, &icu->bp);
2511     BLO_read_data_address(reader, &icu->driver);
2512 
2513     /* Undo generic endian switching. */
2514     if (BLO_read_requires_endian_switch(reader)) {
2515       BLI_endian_switch_int16(&icu->blocktype);
2516       if (icu->driver != NULL) {
2517 
2518         /* Undo generic endian switching. */
2519         if (BLO_read_requires_endian_switch(reader)) {
2520           BLI_endian_switch_int16(&icu->blocktype);
2521           if (icu->driver != NULL) {
2522             BLI_endian_switch_int16(&icu->driver->blocktype);
2523           }
2524         }
2525       }
2526 
2527       /* Undo generic endian switching. */
2528       if (BLO_read_requires_endian_switch(reader)) {
2529         BLI_endian_switch_int16(&ipo->blocktype);
2530         if (icu->driver != NULL) {
2531           BLI_endian_switch_int16(&icu->driver->blocktype);
2532         }
2533       }
2534     }
2535   }
2536 
2537   /* Undo generic endian switching. */
2538   if (BLO_read_requires_endian_switch(reader)) {
2539     BLI_endian_switch_int16(&ipo->blocktype);
2540   }
2541 }
2542 
2543 /* XXX deprecated - old animation system */
lib_link_nlastrips(BlendLibReader * reader,ID * id,ListBase * striplist)2544 static void lib_link_nlastrips(BlendLibReader *reader, ID *id, ListBase *striplist)
2545 {
2546   LISTBASE_FOREACH (bActionStrip *, strip, striplist) {
2547     BLO_read_id_address(reader, id->lib, &strip->object);
2548     BLO_read_id_address(reader, id->lib, &strip->act);
2549     BLO_read_id_address(reader, id->lib, &strip->ipo);
2550     LISTBASE_FOREACH (bActionModifier *, amod, &strip->modifiers) {
2551       BLO_read_id_address(reader, id->lib, &amod->ob);
2552     }
2553   }
2554 }
2555 
2556 /* XXX deprecated - old animation system */
direct_link_nlastrips(BlendDataReader * reader,ListBase * strips)2557 static void direct_link_nlastrips(BlendDataReader *reader, ListBase *strips)
2558 {
2559   BLO_read_list(reader, strips);
2560 
2561   LISTBASE_FOREACH (bActionStrip *, strip, strips) {
2562     BLO_read_list(reader, &strip->modifiers);
2563   }
2564 }
2565 
2566 /* XXX deprecated - old animation system */
lib_link_constraint_channels(BlendLibReader * reader,ID * id,ListBase * chanbase)2567 static void lib_link_constraint_channels(BlendLibReader *reader, ID *id, ListBase *chanbase)
2568 {
2569   LISTBASE_FOREACH (bConstraintChannel *, chan, chanbase) {
2570     BLO_read_id_address(reader, id->lib, &chan->ipo);
2571   }
2572 }
2573 
2574 /** \} */
2575 
2576 /* -------------------------------------------------------------------- */
2577 /** \name Read ID: WorkSpace
2578  * \{ */
2579 
lib_link_workspaces(BlendLibReader * reader,WorkSpace * workspace)2580 static void lib_link_workspaces(BlendLibReader *reader, WorkSpace *workspace)
2581 {
2582   ID *id = (ID *)workspace;
2583 
2584   /* Restore proper 'parent' pointers to relevant data, and clean up unused/invalid entries. */
2585   LISTBASE_FOREACH_MUTABLE (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) {
2586     relation->parent = NULL;
2587     LISTBASE_FOREACH (wmWindowManager *, wm, &reader->main->wm) {
2588       LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
2589         if (win->winid == relation->parentid) {
2590           relation->parent = win->workspace_hook;
2591         }
2592       }
2593     }
2594     if (relation->parent == NULL) {
2595       BLI_freelinkN(&workspace->hook_layout_relations, relation);
2596     }
2597   }
2598 
2599   LISTBASE_FOREACH_MUTABLE (WorkSpaceLayout *, layout, &workspace->layouts) {
2600     BLO_read_id_address(reader, id->lib, &layout->screen);
2601 
2602     if (layout->screen) {
2603       if (ID_IS_LINKED(id)) {
2604         layout->screen->winid = 0;
2605         if (layout->screen->temp) {
2606           /* delete temp layouts when appending */
2607           BKE_workspace_layout_remove(reader->main, workspace, layout);
2608         }
2609       }
2610     }
2611     else {
2612       /* If we're reading a layout without screen stored, it's useless and we shouldn't keep it
2613        * around. */
2614       BKE_workspace_layout_remove(reader->main, workspace, layout);
2615     }
2616   }
2617 }
2618 
direct_link_workspace(BlendDataReader * reader,WorkSpace * workspace)2619 static void direct_link_workspace(BlendDataReader *reader, WorkSpace *workspace)
2620 {
2621   BLO_read_list(reader, &workspace->layouts);
2622   BLO_read_list(reader, &workspace->hook_layout_relations);
2623   BLO_read_list(reader, &workspace->owner_ids);
2624   BLO_read_list(reader, &workspace->tools);
2625 
2626   LISTBASE_FOREACH (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) {
2627     /* parent pointer does not belong to workspace data and is therefore restored in lib_link step
2628      * of window manager.*/
2629     BLO_read_data_address(reader, &relation->value);
2630   }
2631 
2632   LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) {
2633     tref->runtime = NULL;
2634     BLO_read_data_address(reader, &tref->properties);
2635     IDP_BlendDataRead(reader, &tref->properties);
2636   }
2637 
2638   workspace->status_text = NULL;
2639 
2640   id_us_ensure_real(&workspace->id);
2641 }
2642 
lib_link_workspace_instance_hook(BlendLibReader * reader,WorkSpaceInstanceHook * hook,ID * id)2643 static void lib_link_workspace_instance_hook(BlendLibReader *reader,
2644                                              WorkSpaceInstanceHook *hook,
2645                                              ID *id)
2646 {
2647   WorkSpace *workspace = BKE_workspace_active_get(hook);
2648   BLO_read_id_address(reader, id->lib, &workspace);
2649   BKE_workspace_active_set(hook, workspace);
2650 }
2651 
2652 /** \} */
2653 
2654 /* -------------------------------------------------------------------- */
2655 /** \name Read ID: Armature
2656  * \{ */
2657 
2658 /* temp struct used to transport needed info to lib_link_constraint_cb() */
2659 typedef struct tConstraintLinkData {
2660   BlendLibReader *reader;
2661   ID *id;
2662 } tConstraintLinkData;
2663 /* callback function used to relink constraint ID-links */
lib_link_constraint_cb(bConstraint * UNUSED (con),ID ** idpoin,bool UNUSED (is_reference),void * userdata)2664 static void lib_link_constraint_cb(bConstraint *UNUSED(con),
2665                                    ID **idpoin,
2666                                    bool UNUSED(is_reference),
2667                                    void *userdata)
2668 {
2669   tConstraintLinkData *cld = (tConstraintLinkData *)userdata;
2670   BLO_read_id_address(cld->reader, cld->id->lib, idpoin);
2671 }
2672 
lib_link_constraints(BlendLibReader * reader,ID * id,ListBase * conlist)2673 static void lib_link_constraints(BlendLibReader *reader, ID *id, ListBase *conlist)
2674 {
2675   tConstraintLinkData cld;
2676 
2677   /* legacy fixes */
2678   LISTBASE_FOREACH (bConstraint *, con, conlist) {
2679     /* patch for error introduced by changing constraints (dunno how) */
2680     /* if con->data type changes, dna cannot resolve the pointer! (ton) */
2681     if (con->data == NULL) {
2682       con->type = CONSTRAINT_TYPE_NULL;
2683     }
2684     /* own ipo, all constraints have it */
2685     BLO_read_id_address(reader, id->lib, &con->ipo); /* XXX deprecated - old animation system */
2686 
2687     /* If linking from a library, clear 'local' library override flag. */
2688     if (id->lib != NULL) {
2689       con->flag &= ~CONSTRAINT_OVERRIDE_LIBRARY_LOCAL;
2690     }
2691   }
2692 
2693   /* relink all ID-blocks used by the constraints */
2694   cld.reader = reader;
2695   cld.id = id;
2696 
2697   BKE_constraints_id_loop(conlist, lib_link_constraint_cb, &cld);
2698 }
2699 
direct_link_constraints(BlendDataReader * reader,ListBase * lb)2700 static void direct_link_constraints(BlendDataReader *reader, ListBase *lb)
2701 {
2702   BLO_read_list(reader, lb);
2703   LISTBASE_FOREACH (bConstraint *, con, lb) {
2704     BLO_read_data_address(reader, &con->data);
2705 
2706     switch (con->type) {
2707       case CONSTRAINT_TYPE_PYTHON: {
2708         bPythonConstraint *data = con->data;
2709 
2710         BLO_read_list(reader, &data->targets);
2711 
2712         BLO_read_data_address(reader, &data->prop);
2713         IDP_BlendDataRead(reader, &data->prop);
2714         break;
2715       }
2716       case CONSTRAINT_TYPE_ARMATURE: {
2717         bArmatureConstraint *data = con->data;
2718 
2719         BLO_read_list(reader, &data->targets);
2720 
2721         break;
2722       }
2723       case CONSTRAINT_TYPE_SPLINEIK: {
2724         bSplineIKConstraint *data = con->data;
2725 
2726         BLO_read_data_address(reader, &data->points);
2727         break;
2728       }
2729       case CONSTRAINT_TYPE_KINEMATIC: {
2730         bKinematicConstraint *data = con->data;
2731 
2732         con->lin_error = 0.f;
2733         con->rot_error = 0.f;
2734 
2735         /* version patch for runtime flag, was not cleared in some case */
2736         data->flag &= ~CONSTRAINT_IK_AUTO;
2737         break;
2738       }
2739       case CONSTRAINT_TYPE_CHILDOF: {
2740         /* XXX version patch, in older code this flag wasn't always set, and is inherent to type */
2741         if (con->ownspace == CONSTRAINT_SPACE_POSE) {
2742           con->flag |= CONSTRAINT_SPACEONCE;
2743         }
2744         break;
2745       }
2746       case CONSTRAINT_TYPE_TRANSFORM_CACHE: {
2747         bTransformCacheConstraint *data = con->data;
2748         data->reader = NULL;
2749         data->reader_object_path[0] = '\0';
2750       }
2751     }
2752   }
2753 }
2754 
lib_link_pose(BlendLibReader * reader,Object * ob,bPose * pose)2755 static void lib_link_pose(BlendLibReader *reader, Object *ob, bPose *pose)
2756 {
2757   bArmature *arm = ob->data;
2758 
2759   if (!pose || !arm) {
2760     return;
2761   }
2762 
2763   /* always rebuild to match proxy or lib changes, but on Undo */
2764   bool rebuild = false;
2765 
2766   if (!BLO_read_lib_is_undo(reader)) {
2767     if (ob->proxy || ob->id.lib != arm->id.lib) {
2768       rebuild = true;
2769     }
2770   }
2771 
2772   if (ob->proxy) {
2773     /* sync proxy layer */
2774     if (pose->proxy_layer) {
2775       arm->layer = pose->proxy_layer;
2776     }
2777 
2778     /* sync proxy active bone */
2779     if (pose->proxy_act_bone[0]) {
2780       Bone *bone = BKE_armature_find_bone_name(arm, pose->proxy_act_bone);
2781       if (bone) {
2782         arm->act_bone = bone;
2783       }
2784     }
2785   }
2786 
2787   LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
2788     lib_link_constraints(reader, (ID *)ob, &pchan->constraints);
2789 
2790     pchan->bone = BKE_armature_find_bone_name(arm, pchan->name);
2791 
2792     IDP_BlendReadLib(reader, pchan->prop);
2793 
2794     BLO_read_id_address(reader, arm->id.lib, &pchan->custom);
2795     if (UNLIKELY(pchan->bone == NULL)) {
2796       rebuild = true;
2797     }
2798     else if ((ob->id.lib == NULL) && arm->id.lib) {
2799       /* local pose selection copied to armature, bit hackish */
2800       pchan->bone->flag &= ~BONE_SELECTED;
2801       pchan->bone->flag |= pchan->selectflag;
2802     }
2803   }
2804 
2805   if (rebuild) {
2806     DEG_id_tag_update_ex(
2807         reader->main, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
2808     BKE_pose_tag_recalc(reader->main, pose);
2809   }
2810 }
2811 
2812 /** \} */
2813 
2814 /* -------------------------------------------------------------------- */
2815 /** \name Read ID: Shape Keys
2816  * \{ */
2817 
blo_do_versions_key_uidgen(Key * key)2818 void blo_do_versions_key_uidgen(Key *key)
2819 {
2820   key->uidgen = 1;
2821   LISTBASE_FOREACH (KeyBlock *, block, &key->block) {
2822     block->uid = key->uidgen++;
2823   }
2824 }
2825 
2826 /** \} */
2827 
2828 /* -------------------------------------------------------------------- */
2829 /** \name Read ID: Particle Settings
2830  * \{ */
2831 
2832 /* update this also to writefile.c */
2833 static const char *ptcache_data_struct[] = {
2834     "",         /* BPHYS_DATA_INDEX */
2835     "",         /* BPHYS_DATA_LOCATION */
2836     "",         /* BPHYS_DATA_VELOCITY */
2837     "",         /* BPHYS_DATA_ROTATION */
2838     "",         /* BPHYS_DATA_AVELOCITY / BPHYS_DATA_XCONST */
2839     "",         /* BPHYS_DATA_SIZE: */
2840     "",         /* BPHYS_DATA_TIMES: */
2841     "BoidData", /* case BPHYS_DATA_BOIDS: */
2842 };
2843 
direct_link_pointcache_cb(BlendDataReader * reader,void * data)2844 static void direct_link_pointcache_cb(BlendDataReader *reader, void *data)
2845 {
2846   PTCacheMem *pm = data;
2847   for (int i = 0; i < BPHYS_TOT_DATA; i++) {
2848     BLO_read_data_address(reader, &pm->data[i]);
2849 
2850     /* the cache saves non-struct data without DNA */
2851     if (pm->data[i] && ptcache_data_struct[i][0] == '\0' &&
2852         BLO_read_requires_endian_switch(reader)) {
2853       /* data_size returns bytes. */
2854       int tot = (BKE_ptcache_data_size(i) * pm->totpoint) / sizeof(int);
2855 
2856       int *poin = pm->data[i];
2857 
2858       BLI_endian_switch_int32_array(poin, tot);
2859     }
2860   }
2861 
2862   BLO_read_list(reader, &pm->extradata);
2863 
2864   LISTBASE_FOREACH (PTCacheExtra *, extra, &pm->extradata) {
2865     BLO_read_data_address(reader, &extra->data);
2866   }
2867 }
2868 
direct_link_pointcache(BlendDataReader * reader,PointCache * cache)2869 static void direct_link_pointcache(BlendDataReader *reader, PointCache *cache)
2870 {
2871   if ((cache->flag & PTCACHE_DISK_CACHE) == 0) {
2872     BLO_read_list_cb(reader, &cache->mem_cache, direct_link_pointcache_cb);
2873   }
2874   else {
2875     BLI_listbase_clear(&cache->mem_cache);
2876   }
2877 
2878   cache->flag &= ~PTCACHE_SIMULATION_VALID;
2879   cache->simframe = 0;
2880   cache->edit = NULL;
2881   cache->free_edit = NULL;
2882   cache->cached_frames = NULL;
2883   cache->cached_frames_len = 0;
2884 }
2885 
direct_link_pointcache_list(BlendDataReader * reader,ListBase * ptcaches,PointCache ** ocache,int force_disk)2886 static void direct_link_pointcache_list(BlendDataReader *reader,
2887                                         ListBase *ptcaches,
2888                                         PointCache **ocache,
2889                                         int force_disk)
2890 {
2891   if (ptcaches->first) {
2892     BLO_read_list(reader, ptcaches);
2893     LISTBASE_FOREACH (PointCache *, cache, ptcaches) {
2894       direct_link_pointcache(reader, cache);
2895       if (force_disk) {
2896         cache->flag |= PTCACHE_DISK_CACHE;
2897         cache->step = 1;
2898       }
2899     }
2900 
2901     BLO_read_data_address(reader, ocache);
2902   }
2903   else if (*ocache) {
2904     /* old "single" caches need to be linked too */
2905     BLO_read_data_address(reader, ocache);
2906     direct_link_pointcache(reader, *ocache);
2907     if (force_disk) {
2908       (*ocache)->flag |= PTCACHE_DISK_CACHE;
2909       (*ocache)->step = 1;
2910     }
2911 
2912     ptcaches->first = ptcaches->last = *ocache;
2913   }
2914 }
2915 
lib_link_partdeflect(BlendLibReader * reader,ID * id,PartDeflect * pd)2916 static void lib_link_partdeflect(BlendLibReader *reader, ID *id, PartDeflect *pd)
2917 {
2918   if (pd && pd->tex) {
2919     BLO_read_id_address(reader, id->lib, &pd->tex);
2920   }
2921   if (pd && pd->f_source) {
2922     BLO_read_id_address(reader, id->lib, &pd->f_source);
2923   }
2924 }
2925 
lib_link_particlesettings(BlendLibReader * reader,ParticleSettings * part)2926 static void lib_link_particlesettings(BlendLibReader *reader, ParticleSettings *part)
2927 {
2928   BLO_read_id_address(
2929       reader, part->id.lib, &part->ipo); /* XXX deprecated - old animation system */
2930 
2931   BLO_read_id_address(reader, part->id.lib, &part->instance_object);
2932   BLO_read_id_address(reader, part->id.lib, &part->instance_collection);
2933   BLO_read_id_address(reader, part->id.lib, &part->force_group);
2934   BLO_read_id_address(reader, part->id.lib, &part->bb_ob);
2935   BLO_read_id_address(reader, part->id.lib, &part->collision_group);
2936 
2937   lib_link_partdeflect(reader, &part->id, part->pd);
2938   lib_link_partdeflect(reader, &part->id, part->pd2);
2939 
2940   if (part->effector_weights) {
2941     BLO_read_id_address(reader, part->id.lib, &part->effector_weights->group);
2942   }
2943   else {
2944     part->effector_weights = BKE_effector_add_weights(part->force_group);
2945   }
2946 
2947   if (part->instance_weights.first && part->instance_collection) {
2948     LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) {
2949       BLO_read_id_address(reader, part->id.lib, &dw->ob);
2950     }
2951   }
2952   else {
2953     BLI_listbase_clear(&part->instance_weights);
2954   }
2955 
2956   if (part->boids) {
2957     LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
2958       LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
2959         switch (rule->type) {
2960           case eBoidRuleType_Goal:
2961           case eBoidRuleType_Avoid: {
2962             BoidRuleGoalAvoid *brga = (BoidRuleGoalAvoid *)rule;
2963             BLO_read_id_address(reader, part->id.lib, &brga->ob);
2964             break;
2965           }
2966           case eBoidRuleType_FollowLeader: {
2967             BoidRuleFollowLeader *brfl = (BoidRuleFollowLeader *)rule;
2968             BLO_read_id_address(reader, part->id.lib, &brfl->ob);
2969             break;
2970           }
2971         }
2972       }
2973     }
2974   }
2975 
2976   for (int a = 0; a < MAX_MTEX; a++) {
2977     MTex *mtex = part->mtex[a];
2978     if (mtex) {
2979       BLO_read_id_address(reader, part->id.lib, &mtex->tex);
2980       BLO_read_id_address(reader, part->id.lib, &mtex->object);
2981     }
2982   }
2983 }
2984 
direct_link_partdeflect(PartDeflect * pd)2985 static void direct_link_partdeflect(PartDeflect *pd)
2986 {
2987   if (pd) {
2988     pd->rng = NULL;
2989   }
2990 }
2991 
direct_link_particlesettings(BlendDataReader * reader,ParticleSettings * part)2992 static void direct_link_particlesettings(BlendDataReader *reader, ParticleSettings *part)
2993 {
2994   BLO_read_data_address(reader, &part->adt);
2995   BLO_read_data_address(reader, &part->pd);
2996   BLO_read_data_address(reader, &part->pd2);
2997 
2998   BKE_animdata_blend_read_data(reader, part->adt);
2999   direct_link_partdeflect(part->pd);
3000   direct_link_partdeflect(part->pd2);
3001 
3002   BLO_read_data_address(reader, &part->clumpcurve);
3003   if (part->clumpcurve) {
3004     BKE_curvemapping_blend_read(reader, part->clumpcurve);
3005   }
3006   BLO_read_data_address(reader, &part->roughcurve);
3007   if (part->roughcurve) {
3008     BKE_curvemapping_blend_read(reader, part->roughcurve);
3009   }
3010   BLO_read_data_address(reader, &part->twistcurve);
3011   if (part->twistcurve) {
3012     BKE_curvemapping_blend_read(reader, part->twistcurve);
3013   }
3014 
3015   BLO_read_data_address(reader, &part->effector_weights);
3016   if (!part->effector_weights) {
3017     part->effector_weights = BKE_effector_add_weights(part->force_group);
3018   }
3019 
3020   BLO_read_list(reader, &part->instance_weights);
3021 
3022   BLO_read_data_address(reader, &part->boids);
3023   BLO_read_data_address(reader, &part->fluid);
3024 
3025   if (part->boids) {
3026     BLO_read_list(reader, &part->boids->states);
3027 
3028     LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
3029       BLO_read_list(reader, &state->rules);
3030       BLO_read_list(reader, &state->conditions);
3031       BLO_read_list(reader, &state->actions);
3032     }
3033   }
3034   for (int a = 0; a < MAX_MTEX; a++) {
3035     BLO_read_data_address(reader, &part->mtex[a]);
3036   }
3037 
3038   /* Protect against integer overflow vulnerability. */
3039   CLAMP(part->trail_count, 1, 100000);
3040 }
3041 
lib_link_particlesystems(BlendLibReader * reader,Object * ob,ID * id,ListBase * particles)3042 static void lib_link_particlesystems(BlendLibReader *reader,
3043                                      Object *ob,
3044                                      ID *id,
3045                                      ListBase *particles)
3046 {
3047   LISTBASE_FOREACH_MUTABLE (ParticleSystem *, psys, particles) {
3048 
3049     BLO_read_id_address(reader, id->lib, &psys->part);
3050     if (psys->part) {
3051       LISTBASE_FOREACH (ParticleTarget *, pt, &psys->targets) {
3052         BLO_read_id_address(reader, id->lib, &pt->ob);
3053       }
3054 
3055       BLO_read_id_address(reader, id->lib, &psys->parent);
3056       BLO_read_id_address(reader, id->lib, &psys->target_ob);
3057 
3058       if (psys->clmd) {
3059         /* XXX - from reading existing code this seems correct but intended usage of
3060          * pointcache /w cloth should be added in 'ParticleSystem' - campbell */
3061         psys->clmd->point_cache = psys->pointcache;
3062         psys->clmd->ptcaches.first = psys->clmd->ptcaches.last = NULL;
3063         BLO_read_id_address(reader, id->lib, &psys->clmd->coll_parms->group);
3064         psys->clmd->modifier.error = NULL;
3065       }
3066     }
3067     else {
3068       /* particle modifier must be removed before particle system */
3069       ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
3070       BLI_remlink(&ob->modifiers, psmd);
3071       BKE_modifier_free((ModifierData *)psmd);
3072 
3073       BLI_remlink(particles, psys);
3074       MEM_freeN(psys);
3075     }
3076   }
3077 }
direct_link_particlesystems(BlendDataReader * reader,ListBase * particles)3078 static void direct_link_particlesystems(BlendDataReader *reader, ListBase *particles)
3079 {
3080   ParticleData *pa;
3081   int a;
3082 
3083   LISTBASE_FOREACH (ParticleSystem *, psys, particles) {
3084     BLO_read_data_address(reader, &psys->particles);
3085 
3086     if (psys->particles && psys->particles->hair) {
3087       for (a = 0, pa = psys->particles; a < psys->totpart; a++, pa++) {
3088         BLO_read_data_address(reader, &pa->hair);
3089       }
3090     }
3091 
3092     if (psys->particles && psys->particles->keys) {
3093       for (a = 0, pa = psys->particles; a < psys->totpart; a++, pa++) {
3094         pa->keys = NULL;
3095         pa->totkey = 0;
3096       }
3097 
3098       psys->flag &= ~PSYS_KEYED;
3099     }
3100 
3101     if (psys->particles && psys->particles->boid) {
3102       pa = psys->particles;
3103       BLO_read_data_address(reader, &pa->boid);
3104 
3105       /* This is purely runtime data, but still can be an issue if left dangling. */
3106       pa->boid->ground = NULL;
3107 
3108       for (a = 1, pa++; a < psys->totpart; a++, pa++) {
3109         pa->boid = (pa - 1)->boid + 1;
3110         pa->boid->ground = NULL;
3111       }
3112     }
3113     else if (psys->particles) {
3114       for (a = 0, pa = psys->particles; a < psys->totpart; a++, pa++) {
3115         pa->boid = NULL;
3116       }
3117     }
3118 
3119     BLO_read_data_address(reader, &psys->fluid_springs);
3120 
3121     BLO_read_data_address(reader, &psys->child);
3122     psys->effectors = NULL;
3123 
3124     BLO_read_list(reader, &psys->targets);
3125 
3126     psys->edit = NULL;
3127     psys->free_edit = NULL;
3128     psys->pathcache = NULL;
3129     psys->childcache = NULL;
3130     BLI_listbase_clear(&psys->pathcachebufs);
3131     BLI_listbase_clear(&psys->childcachebufs);
3132     psys->pdd = NULL;
3133 
3134     if (psys->clmd) {
3135       BLO_read_data_address(reader, &psys->clmd);
3136       psys->clmd->clothObject = NULL;
3137       psys->clmd->hairdata = NULL;
3138 
3139       BLO_read_data_address(reader, &psys->clmd->sim_parms);
3140       BLO_read_data_address(reader, &psys->clmd->coll_parms);
3141 
3142       if (psys->clmd->sim_parms) {
3143         psys->clmd->sim_parms->effector_weights = NULL;
3144         if (psys->clmd->sim_parms->presets > 10) {
3145           psys->clmd->sim_parms->presets = 0;
3146         }
3147       }
3148 
3149       psys->hair_in_mesh = psys->hair_out_mesh = NULL;
3150       psys->clmd->solver_result = NULL;
3151     }
3152 
3153     direct_link_pointcache_list(reader, &psys->ptcaches, &psys->pointcache, 0);
3154     if (psys->clmd) {
3155       psys->clmd->point_cache = psys->pointcache;
3156     }
3157 
3158     psys->tree = NULL;
3159     psys->bvhtree = NULL;
3160 
3161     psys->orig_psys = NULL;
3162     psys->batch_cache = NULL;
3163   }
3164 }
3165 
3166 /** \} */
3167 
3168 /* -------------------------------------------------------------------- */
3169 /** \name Read ID: Mesh
3170  * \{ */
3171 
3172 /** \} */
3173 
3174 /* -------------------------------------------------------------------- */
3175 /** \name Read ID: Object
3176  * \{ */
3177 
lib_link_modifiers_common(void * userData,Object * ob,ID ** idpoin,int cb_flag)3178 static void lib_link_modifiers_common(void *userData, Object *ob, ID **idpoin, int cb_flag)
3179 {
3180   BlendLibReader *reader = userData;
3181 
3182   BLO_read_id_address(reader, ob->id.lib, idpoin);
3183   if (*idpoin != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
3184     id_us_plus_no_lib(*idpoin);
3185   }
3186 }
3187 
lib_link_modifiers(BlendLibReader * reader,Object * ob)3188 static void lib_link_modifiers(BlendLibReader *reader, Object *ob)
3189 {
3190   BKE_modifiers_foreach_ID_link(ob, lib_link_modifiers_common, reader);
3191 
3192   /* If linking from a library, clear 'local' library override flag. */
3193   if (ob->id.lib != NULL) {
3194     LISTBASE_FOREACH (ModifierData *, mod, &ob->modifiers) {
3195       mod->flag &= ~eModifierFlag_OverrideLibrary_Local;
3196     }
3197   }
3198 }
3199 
lib_link_gpencil_modifiers(BlendLibReader * reader,Object * ob)3200 static void lib_link_gpencil_modifiers(BlendLibReader *reader, Object *ob)
3201 {
3202   BKE_gpencil_modifiers_foreach_ID_link(ob, lib_link_modifiers_common, reader);
3203 
3204   /* If linking from a library, clear 'local' library override flag. */
3205   if (ob->id.lib != NULL) {
3206     LISTBASE_FOREACH (GpencilModifierData *, mod, &ob->greasepencil_modifiers) {
3207       mod->flag &= ~eGpencilModifierFlag_OverrideLibrary_Local;
3208     }
3209   }
3210 }
3211 
lib_link_shaderfxs(BlendLibReader * reader,Object * ob)3212 static void lib_link_shaderfxs(BlendLibReader *reader, Object *ob)
3213 {
3214   BKE_shaderfx_foreach_ID_link(ob, lib_link_modifiers_common, reader);
3215 
3216   /* If linking from a library, clear 'local' library override flag. */
3217   if (ob->id.lib != NULL) {
3218     LISTBASE_FOREACH (ShaderFxData *, fx, &ob->shader_fx) {
3219       fx->flag &= ~eShaderFxFlag_OverrideLibrary_Local;
3220     }
3221   }
3222 }
3223 
lib_link_object(BlendLibReader * reader,Object * ob)3224 static void lib_link_object(BlendLibReader *reader, Object *ob)
3225 {
3226   bool warn = false;
3227 
3228   /* XXX deprecated - old animation system <<< */
3229   BLO_read_id_address(reader, ob->id.lib, &ob->ipo);
3230   BLO_read_id_address(reader, ob->id.lib, &ob->action);
3231   /* >>> XXX deprecated - old animation system */
3232 
3233   BLO_read_id_address(reader, ob->id.lib, &ob->parent);
3234   BLO_read_id_address(reader, ob->id.lib, &ob->track);
3235   BLO_read_id_address(reader, ob->id.lib, &ob->poselib);
3236 
3237   /* 2.8x drops support for non-empty dupli instances. */
3238   if (ob->type == OB_EMPTY) {
3239     BLO_read_id_address(reader, ob->id.lib, &ob->instance_collection);
3240   }
3241   else {
3242     if (ob->instance_collection != NULL) {
3243       ID *id = BLO_read_get_new_id_address(reader, ob->id.lib, &ob->instance_collection->id);
3244       blo_reportf_wrap(reader->fd->reports,
3245                        RPT_WARNING,
3246                        TIP_("Non-Empty object '%s' cannot duplicate collection '%s' "
3247                             "anymore in Blender 2.80, removed instancing"),
3248                        ob->id.name + 2,
3249                        id->name + 2);
3250     }
3251     ob->instance_collection = NULL;
3252     ob->transflag &= ~OB_DUPLICOLLECTION;
3253   }
3254 
3255   BLO_read_id_address(reader, ob->id.lib, &ob->proxy);
3256   if (ob->proxy) {
3257     /* paranoia check, actually a proxy_from pointer should never be written... */
3258     if (ob->proxy->id.lib == NULL) {
3259       ob->proxy->proxy_from = NULL;
3260       ob->proxy = NULL;
3261 
3262       if (ob->id.lib) {
3263         printf("Proxy lost from  object %s lib %s\n", ob->id.name + 2, ob->id.lib->filepath);
3264       }
3265       else {
3266         printf("Proxy lost from  object %s lib <NONE>\n", ob->id.name + 2);
3267       }
3268     }
3269     else {
3270       /* this triggers object_update to always use a copy */
3271       ob->proxy->proxy_from = ob;
3272     }
3273   }
3274   BLO_read_id_address(reader, ob->id.lib, &ob->proxy_group);
3275 
3276   void *poin = ob->data;
3277   BLO_read_id_address(reader, ob->id.lib, &ob->data);
3278 
3279   if (ob->data == NULL && poin != NULL) {
3280     if (ob->id.lib) {
3281       printf("Can't find obdata of %s lib %s\n", ob->id.name + 2, ob->id.lib->filepath);
3282     }
3283     else {
3284       printf("Object %s lost data.\n", ob->id.name + 2);
3285     }
3286 
3287     ob->type = OB_EMPTY;
3288     warn = true;
3289 
3290     if (ob->pose) {
3291       /* we can't call #BKE_pose_free() here because of library linking
3292        * freeing will recurse down into every pose constraints ID pointers
3293        * which are not always valid, so for now free directly and suffer
3294        * some leaked memory rather than crashing immediately
3295        * while bad this _is_ an exceptional case - campbell */
3296 #if 0
3297       BKE_pose_free(ob->pose);
3298 #else
3299       MEM_freeN(ob->pose);
3300 #endif
3301       ob->pose = NULL;
3302       ob->mode &= ~OB_MODE_POSE;
3303     }
3304   }
3305   for (int a = 0; a < ob->totcol; a++) {
3306     BLO_read_id_address(reader, ob->id.lib, &ob->mat[a]);
3307   }
3308 
3309   /* When the object is local and the data is library its possible
3310    * the material list size gets out of sync. T22663. */
3311   if (ob->data && ob->id.lib != ((ID *)ob->data)->lib) {
3312     const short *totcol_data = BKE_object_material_len_p(ob);
3313     /* Only expand so as not to lose any object materials that might be set. */
3314     if (totcol_data && (*totcol_data > ob->totcol)) {
3315       /* printf("'%s' %d -> %d\n", ob->id.name, ob->totcol, *totcol_data); */
3316       BKE_object_material_resize(reader->main, ob, *totcol_data, false);
3317     }
3318   }
3319 
3320   BLO_read_id_address(reader, ob->id.lib, &ob->gpd);
3321 
3322   /* if id.us==0 a new base will be created later on */
3323 
3324   /* WARNING! Also check expand_object(), should reflect the stuff below. */
3325   lib_link_pose(reader, ob, ob->pose);
3326   lib_link_constraints(reader, &ob->id, &ob->constraints);
3327 
3328   /* XXX deprecated - old animation system <<< */
3329   lib_link_constraint_channels(reader, &ob->id, &ob->constraintChannels);
3330   lib_link_nlastrips(reader, &ob->id, &ob->nlastrips);
3331   /* >>> XXX deprecated - old animation system */
3332 
3333   LISTBASE_FOREACH (PartEff *, paf, &ob->effect) {
3334     if (paf->type == EFF_PARTICLE) {
3335       BLO_read_id_address(reader, ob->id.lib, &paf->group);
3336     }
3337   }
3338 
3339   {
3340     FluidsimModifierData *fluidmd = (FluidsimModifierData *)BKE_modifiers_findby_type(
3341         ob, eModifierType_Fluidsim);
3342 
3343     if (fluidmd && fluidmd->fss) {
3344       BLO_read_id_address(
3345           reader, ob->id.lib, &fluidmd->fss->ipo); /* XXX deprecated - old animation system */
3346     }
3347   }
3348 
3349   {
3350     FluidModifierData *fmd = (FluidModifierData *)BKE_modifiers_findby_type(ob,
3351                                                                             eModifierType_Fluid);
3352 
3353     if (fmd && (fmd->type == MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
3354       /* Flag for refreshing the simulation after loading */
3355       fmd->domain->flags |= FLUID_DOMAIN_FILE_LOAD;
3356     }
3357     else if (fmd && (fmd->type == MOD_FLUID_TYPE_FLOW) && fmd->flow) {
3358       fmd->flow->flags &= ~FLUID_FLOW_NEEDS_UPDATE;
3359     }
3360     else if (fmd && (fmd->type == MOD_FLUID_TYPE_EFFEC) && fmd->effector) {
3361       fmd->effector->flags &= ~FLUID_EFFECTOR_NEEDS_UPDATE;
3362     }
3363   }
3364 
3365   /* texture field */
3366   if (ob->pd) {
3367     lib_link_partdeflect(reader, &ob->id, ob->pd);
3368   }
3369 
3370   if (ob->soft) {
3371     BLO_read_id_address(reader, ob->id.lib, &ob->soft->collision_group);
3372 
3373     BLO_read_id_address(reader, ob->id.lib, &ob->soft->effector_weights->group);
3374   }
3375 
3376   lib_link_particlesystems(reader, ob, &ob->id, &ob->particlesystem);
3377   lib_link_modifiers(reader, ob);
3378   lib_link_gpencil_modifiers(reader, ob);
3379   lib_link_shaderfxs(reader, ob);
3380 
3381   if (ob->rigidbody_constraint) {
3382     BLO_read_id_address(reader, ob->id.lib, &ob->rigidbody_constraint->ob1);
3383     BLO_read_id_address(reader, ob->id.lib, &ob->rigidbody_constraint->ob2);
3384   }
3385 
3386   if (warn) {
3387     BKE_report(reader->fd->reports, RPT_WARNING, "Warning in console");
3388   }
3389 }
3390 
3391 /* direct data for cache */
direct_link_motionpath(BlendDataReader * reader,bMotionPath * mpath)3392 static void direct_link_motionpath(BlendDataReader *reader, bMotionPath *mpath)
3393 {
3394   /* sanity check */
3395   if (mpath == NULL) {
3396     return;
3397   }
3398 
3399   /* relink points cache */
3400   BLO_read_data_address(reader, &mpath->points);
3401 
3402   mpath->points_vbo = NULL;
3403   mpath->batch_line = NULL;
3404   mpath->batch_points = NULL;
3405 }
3406 
direct_link_pose(BlendDataReader * reader,bPose * pose)3407 static void direct_link_pose(BlendDataReader *reader, bPose *pose)
3408 {
3409   if (!pose) {
3410     return;
3411   }
3412 
3413   BLO_read_list(reader, &pose->chanbase);
3414   BLO_read_list(reader, &pose->agroups);
3415 
3416   pose->chanhash = NULL;
3417   pose->chan_array = NULL;
3418 
3419   LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
3420     BKE_pose_channel_runtime_reset(&pchan->runtime);
3421     BKE_pose_channel_session_uuid_generate(pchan);
3422 
3423     pchan->bone = NULL;
3424     BLO_read_data_address(reader, &pchan->parent);
3425     BLO_read_data_address(reader, &pchan->child);
3426     BLO_read_data_address(reader, &pchan->custom_tx);
3427 
3428     BLO_read_data_address(reader, &pchan->bbone_prev);
3429     BLO_read_data_address(reader, &pchan->bbone_next);
3430 
3431     direct_link_constraints(reader, &pchan->constraints);
3432 
3433     BLO_read_data_address(reader, &pchan->prop);
3434     IDP_BlendDataRead(reader, &pchan->prop);
3435 
3436     BLO_read_data_address(reader, &pchan->mpath);
3437     if (pchan->mpath) {
3438       direct_link_motionpath(reader, pchan->mpath);
3439     }
3440 
3441     BLI_listbase_clear(&pchan->iktree);
3442     BLI_listbase_clear(&pchan->siktree);
3443 
3444     /* in case this value changes in future, clamp else we get undefined behavior */
3445     CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
3446 
3447     pchan->draw_data = NULL;
3448   }
3449   pose->ikdata = NULL;
3450   if (pose->ikparam != NULL) {
3451     BLO_read_data_address(reader, &pose->ikparam);
3452   }
3453 }
3454 
3455 /* TODO(sergey): Find a better place for this.
3456  *
3457  * Unfortunately, this can not be done as a regular do_versions() since the modifier type is
3458  * set to NONE, so the do_versions code wouldn't know where the modifier came from.
3459  *
3460  * The best approach seems to have the functionality in versioning_280.c but still call the
3461  * function from #direct_link_modifiers().
3462  */
3463 
3464 /* Domain, inflow, ... */
modifier_ensure_type(FluidModifierData * fluid_modifier_data,int type)3465 static void modifier_ensure_type(FluidModifierData *fluid_modifier_data, int type)
3466 {
3467   fluid_modifier_data->type = type;
3468   BKE_fluid_modifier_free(fluid_modifier_data);
3469   BKE_fluid_modifier_create_type_data(fluid_modifier_data);
3470 }
3471 
3472 /**
3473  * \note The old_modifier_data is NOT linked.
3474  * This means that in order to access sub-data pointers #newdataadr is to be used.
3475  */
modifier_replace_with_fluid(FileData * fd,Object * object,ListBase * modifiers,ModifierData * old_modifier_data)3476 static ModifierData *modifier_replace_with_fluid(FileData *fd,
3477                                                  Object *object,
3478                                                  ListBase *modifiers,
3479                                                  ModifierData *old_modifier_data)
3480 {
3481   ModifierData *new_modifier_data = BKE_modifier_new(eModifierType_Fluid);
3482   FluidModifierData *fluid_modifier_data = (FluidModifierData *)new_modifier_data;
3483 
3484   if (old_modifier_data->type == eModifierType_Fluidsim) {
3485     FluidsimModifierData *old_fluidsim_modifier_data = (FluidsimModifierData *)old_modifier_data;
3486     FluidsimSettings *old_fluidsim_settings = newdataadr(fd, old_fluidsim_modifier_data->fss);
3487     switch (old_fluidsim_settings->type) {
3488       case OB_FLUIDSIM_ENABLE:
3489         modifier_ensure_type(fluid_modifier_data, 0);
3490         break;
3491       case OB_FLUIDSIM_DOMAIN:
3492         modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_DOMAIN);
3493         BKE_fluid_domain_type_set(object, fluid_modifier_data->domain, FLUID_DOMAIN_TYPE_LIQUID);
3494         break;
3495       case OB_FLUIDSIM_FLUID:
3496         modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
3497         BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
3498         /* No need to emit liquid far away from surface. */
3499         fluid_modifier_data->flow->surface_distance = 0.0f;
3500         break;
3501       case OB_FLUIDSIM_OBSTACLE:
3502         modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_EFFEC);
3503         BKE_fluid_effector_type_set(
3504             object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_COLLISION);
3505         break;
3506       case OB_FLUIDSIM_INFLOW:
3507         modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
3508         BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
3509         BKE_fluid_flow_behavior_set(object, fluid_modifier_data->flow, FLUID_FLOW_BEHAVIOR_INFLOW);
3510         /* No need to emit liquid far away from surface. */
3511         fluid_modifier_data->flow->surface_distance = 0.0f;
3512         break;
3513       case OB_FLUIDSIM_OUTFLOW:
3514         modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
3515         BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
3516         BKE_fluid_flow_behavior_set(
3517             object, fluid_modifier_data->flow, FLUID_FLOW_BEHAVIOR_OUTFLOW);
3518         break;
3519       case OB_FLUIDSIM_PARTICLE:
3520         /* "Particle" type objects not being used by Mantaflow fluid simulations.
3521          * Skip this object, secondary particles can only be enabled through the domain object. */
3522         break;
3523       case OB_FLUIDSIM_CONTROL:
3524         /* "Control" type objects not being used by Mantaflow fluid simulations.
3525          * Use guiding type instead which is similar. */
3526         modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_EFFEC);
3527         BKE_fluid_effector_type_set(
3528             object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_GUIDE);
3529         break;
3530     }
3531   }
3532   else if (old_modifier_data->type == eModifierType_Smoke) {
3533     SmokeModifierData *old_smoke_modifier_data = (SmokeModifierData *)old_modifier_data;
3534     modifier_ensure_type(fluid_modifier_data, old_smoke_modifier_data->type);
3535     if (fluid_modifier_data->type == MOD_FLUID_TYPE_DOMAIN) {
3536       BKE_fluid_domain_type_set(object, fluid_modifier_data->domain, FLUID_DOMAIN_TYPE_GAS);
3537     }
3538     else if (fluid_modifier_data->type == MOD_FLUID_TYPE_FLOW) {
3539       BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_SMOKE);
3540     }
3541     else if (fluid_modifier_data->type == MOD_FLUID_TYPE_EFFEC) {
3542       BKE_fluid_effector_type_set(
3543           object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_COLLISION);
3544     }
3545   }
3546 
3547   /* Replace modifier data in the stack. */
3548   new_modifier_data->next = old_modifier_data->next;
3549   new_modifier_data->prev = old_modifier_data->prev;
3550   if (new_modifier_data->prev != NULL) {
3551     new_modifier_data->prev->next = new_modifier_data;
3552   }
3553   if (new_modifier_data->next != NULL) {
3554     new_modifier_data->next->prev = new_modifier_data;
3555   }
3556   if (modifiers->first == old_modifier_data) {
3557     modifiers->first = new_modifier_data;
3558   }
3559   if (modifiers->last == old_modifier_data) {
3560     modifiers->last = new_modifier_data;
3561   }
3562 
3563   /* Free old modifier data. */
3564   MEM_freeN(old_modifier_data);
3565 
3566   return new_modifier_data;
3567 }
3568 
direct_link_modifiers(BlendDataReader * reader,ListBase * lb,Object * ob)3569 static void direct_link_modifiers(BlendDataReader *reader, ListBase *lb, Object *ob)
3570 {
3571   BLO_read_list(reader, lb);
3572 
3573   LISTBASE_FOREACH (ModifierData *, md, lb) {
3574     BKE_modifier_session_uuid_generate(md);
3575 
3576     md->error = NULL;
3577     md->runtime = NULL;
3578 
3579     /* Modifier data has been allocated as a part of data migration process and
3580      * no reading of nested fields from file is needed. */
3581     bool is_allocated = false;
3582 
3583     if (md->type == eModifierType_Fluidsim) {
3584       blo_reportf_wrap(
3585           reader->fd->reports,
3586           RPT_WARNING,
3587           TIP_("Possible data loss when saving this file! %s modifier is deprecated (Object: %s)"),
3588           md->name,
3589           ob->id.name + 2);
3590       md = modifier_replace_with_fluid(reader->fd, ob, lb, md);
3591       is_allocated = true;
3592     }
3593     else if (md->type == eModifierType_Smoke) {
3594       blo_reportf_wrap(
3595           reader->fd->reports,
3596           RPT_WARNING,
3597           TIP_("Possible data loss when saving this file! %s modifier is deprecated (Object: %s)"),
3598           md->name,
3599           ob->id.name + 2);
3600       md = modifier_replace_with_fluid(reader->fd, ob, lb, md);
3601       is_allocated = true;
3602     }
3603 
3604     const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
3605 
3606     /* if modifiers disappear, or for upward compatibility */
3607     if (mti == NULL) {
3608       md->type = eModifierType_None;
3609     }
3610 
3611     if (is_allocated) {
3612       /* All the fields has been properly allocated. */
3613     }
3614     else if (md->type == eModifierType_Cloth) {
3615       ClothModifierData *clmd = (ClothModifierData *)md;
3616 
3617       clmd->clothObject = NULL;
3618       clmd->hairdata = NULL;
3619 
3620       BLO_read_data_address(reader, &clmd->sim_parms);
3621       BLO_read_data_address(reader, &clmd->coll_parms);
3622 
3623       direct_link_pointcache_list(reader, &clmd->ptcaches, &clmd->point_cache, 0);
3624 
3625       if (clmd->sim_parms) {
3626         if (clmd->sim_parms->presets > 10) {
3627           clmd->sim_parms->presets = 0;
3628         }
3629 
3630         clmd->sim_parms->reset = 0;
3631 
3632         BLO_read_data_address(reader, &clmd->sim_parms->effector_weights);
3633 
3634         if (!clmd->sim_parms->effector_weights) {
3635           clmd->sim_parms->effector_weights = BKE_effector_add_weights(NULL);
3636         }
3637       }
3638 
3639       clmd->solver_result = NULL;
3640     }
3641     else if (md->type == eModifierType_Fluid) {
3642 
3643       FluidModifierData *fmd = (FluidModifierData *)md;
3644 
3645       if (fmd->type == MOD_FLUID_TYPE_DOMAIN) {
3646         fmd->flow = NULL;
3647         fmd->effector = NULL;
3648         BLO_read_data_address(reader, &fmd->domain);
3649         fmd->domain->fmd = fmd;
3650 
3651         fmd->domain->fluid = NULL;
3652         fmd->domain->fluid_mutex = BLI_rw_mutex_alloc();
3653         fmd->domain->tex_density = NULL;
3654         fmd->domain->tex_color = NULL;
3655         fmd->domain->tex_shadow = NULL;
3656         fmd->domain->tex_flame = NULL;
3657         fmd->domain->tex_flame_coba = NULL;
3658         fmd->domain->tex_coba = NULL;
3659         fmd->domain->tex_field = NULL;
3660         fmd->domain->tex_velocity_x = NULL;
3661         fmd->domain->tex_velocity_y = NULL;
3662         fmd->domain->tex_velocity_z = NULL;
3663         fmd->domain->tex_wt = NULL;
3664         fmd->domain->mesh_velocities = NULL;
3665         BLO_read_data_address(reader, &fmd->domain->coba);
3666 
3667         BLO_read_data_address(reader, &fmd->domain->effector_weights);
3668         if (!fmd->domain->effector_weights) {
3669           fmd->domain->effector_weights = BKE_effector_add_weights(NULL);
3670         }
3671 
3672         direct_link_pointcache_list(
3673             reader, &(fmd->domain->ptcaches[0]), &(fmd->domain->point_cache[0]), 1);
3674 
3675         /* Manta sim uses only one cache from now on, so store pointer convert */
3676         if (fmd->domain->ptcaches[1].first || fmd->domain->point_cache[1]) {
3677           if (fmd->domain->point_cache[1]) {
3678             PointCache *cache = BLO_read_get_new_data_address(reader, fmd->domain->point_cache[1]);
3679             if (cache->flag & PTCACHE_FAKE_SMOKE) {
3680               /* Manta-sim/smoke was already saved in "new format" and this cache is a fake one. */
3681             }
3682             else {
3683               printf(
3684                   "High resolution manta cache not available due to pointcache update. Please "
3685                   "reset the simulation.\n");
3686             }
3687             BKE_ptcache_free(cache);
3688           }
3689           BLI_listbase_clear(&fmd->domain->ptcaches[1]);
3690           fmd->domain->point_cache[1] = NULL;
3691         }
3692       }
3693       else if (fmd->type == MOD_FLUID_TYPE_FLOW) {
3694         fmd->domain = NULL;
3695         fmd->effector = NULL;
3696         BLO_read_data_address(reader, &fmd->flow);
3697         fmd->flow->fmd = fmd;
3698         fmd->flow->mesh = NULL;
3699         fmd->flow->verts_old = NULL;
3700         fmd->flow->numverts = 0;
3701         BLO_read_data_address(reader, &fmd->flow->psys);
3702       }
3703       else if (fmd->type == MOD_FLUID_TYPE_EFFEC) {
3704         fmd->flow = NULL;
3705         fmd->domain = NULL;
3706         BLO_read_data_address(reader, &fmd->effector);
3707         if (fmd->effector) {
3708           fmd->effector->fmd = fmd;
3709           fmd->effector->verts_old = NULL;
3710           fmd->effector->numverts = 0;
3711           fmd->effector->mesh = NULL;
3712         }
3713         else {
3714           fmd->type = 0;
3715           fmd->flow = NULL;
3716           fmd->domain = NULL;
3717           fmd->effector = NULL;
3718         }
3719       }
3720     }
3721     else if (md->type == eModifierType_DynamicPaint) {
3722       DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
3723 
3724       if (pmd->canvas) {
3725         BLO_read_data_address(reader, &pmd->canvas);
3726         pmd->canvas->pmd = pmd;
3727         pmd->canvas->flags &= ~MOD_DPAINT_BAKING; /* just in case */
3728 
3729         if (pmd->canvas->surfaces.first) {
3730           BLO_read_list(reader, &pmd->canvas->surfaces);
3731 
3732           LISTBASE_FOREACH (DynamicPaintSurface *, surface, &pmd->canvas->surfaces) {
3733             surface->canvas = pmd->canvas;
3734             surface->data = NULL;
3735             direct_link_pointcache_list(reader, &(surface->ptcaches), &(surface->pointcache), 1);
3736 
3737             BLO_read_data_address(reader, &surface->effector_weights);
3738             if (surface->effector_weights == NULL) {
3739               surface->effector_weights = BKE_effector_add_weights(NULL);
3740             }
3741           }
3742         }
3743       }
3744       if (pmd->brush) {
3745         BLO_read_data_address(reader, &pmd->brush);
3746         pmd->brush->pmd = pmd;
3747         BLO_read_data_address(reader, &pmd->brush->psys);
3748         BLO_read_data_address(reader, &pmd->brush->paint_ramp);
3749         BLO_read_data_address(reader, &pmd->brush->vel_ramp);
3750       }
3751     }
3752 
3753     if (mti->blendRead != NULL) {
3754       mti->blendRead(reader, md);
3755     }
3756   }
3757 }
3758 
direct_link_gpencil_modifiers(BlendDataReader * reader,ListBase * lb)3759 static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
3760 {
3761   BLO_read_list(reader, lb);
3762 
3763   LISTBASE_FOREACH (GpencilModifierData *, md, lb) {
3764     md->error = NULL;
3765 
3766     /* if modifiers disappear, or for upward compatibility */
3767     if (NULL == BKE_gpencil_modifier_get_info(md->type)) {
3768       md->type = eModifierType_None;
3769     }
3770 
3771     if (md->type == eGpencilModifierType_Lattice) {
3772       LatticeGpencilModifierData *gpmd = (LatticeGpencilModifierData *)md;
3773       gpmd->cache_data = NULL;
3774     }
3775     else if (md->type == eGpencilModifierType_Hook) {
3776       HookGpencilModifierData *hmd = (HookGpencilModifierData *)md;
3777 
3778       BLO_read_data_address(reader, &hmd->curfalloff);
3779       if (hmd->curfalloff) {
3780         BKE_curvemapping_blend_read(reader, hmd->curfalloff);
3781       }
3782     }
3783     else if (md->type == eGpencilModifierType_Noise) {
3784       NoiseGpencilModifierData *gpmd = (NoiseGpencilModifierData *)md;
3785 
3786       BLO_read_data_address(reader, &gpmd->curve_intensity);
3787       if (gpmd->curve_intensity) {
3788         BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
3789         /* initialize the curve. Maybe this could be moved to modififer logic */
3790         BKE_curvemapping_init(gpmd->curve_intensity);
3791       }
3792     }
3793     else if (md->type == eGpencilModifierType_Thick) {
3794       ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md;
3795 
3796       BLO_read_data_address(reader, &gpmd->curve_thickness);
3797       if (gpmd->curve_thickness) {
3798         BKE_curvemapping_blend_read(reader, gpmd->curve_thickness);
3799         BKE_curvemapping_init(gpmd->curve_thickness);
3800       }
3801     }
3802     else if (md->type == eGpencilModifierType_Tint) {
3803       TintGpencilModifierData *gpmd = (TintGpencilModifierData *)md;
3804       BLO_read_data_address(reader, &gpmd->colorband);
3805       BLO_read_data_address(reader, &gpmd->curve_intensity);
3806       if (gpmd->curve_intensity) {
3807         BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
3808         BKE_curvemapping_init(gpmd->curve_intensity);
3809       }
3810     }
3811     else if (md->type == eGpencilModifierType_Smooth) {
3812       SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md;
3813       BLO_read_data_address(reader, &gpmd->curve_intensity);
3814       if (gpmd->curve_intensity) {
3815         BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
3816         BKE_curvemapping_init(gpmd->curve_intensity);
3817       }
3818     }
3819     else if (md->type == eGpencilModifierType_Color) {
3820       ColorGpencilModifierData *gpmd = (ColorGpencilModifierData *)md;
3821       BLO_read_data_address(reader, &gpmd->curve_intensity);
3822       if (gpmd->curve_intensity) {
3823         BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
3824         BKE_curvemapping_init(gpmd->curve_intensity);
3825       }
3826     }
3827     else if (md->type == eGpencilModifierType_Opacity) {
3828       OpacityGpencilModifierData *gpmd = (OpacityGpencilModifierData *)md;
3829       BLO_read_data_address(reader, &gpmd->curve_intensity);
3830       if (gpmd->curve_intensity) {
3831         BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
3832         BKE_curvemapping_init(gpmd->curve_intensity);
3833       }
3834     }
3835   }
3836 }
3837 
direct_link_shaderfxs(BlendDataReader * reader,ListBase * lb)3838 static void direct_link_shaderfxs(BlendDataReader *reader, ListBase *lb)
3839 {
3840   BLO_read_list(reader, lb);
3841 
3842   LISTBASE_FOREACH (ShaderFxData *, fx, lb) {
3843     fx->error = NULL;
3844 
3845     /* if shader disappear, or for upward compatibility */
3846     if (NULL == BKE_shaderfx_get_info(fx->type)) {
3847       fx->type = eShaderFxType_None;
3848     }
3849   }
3850 }
3851 
direct_link_object(BlendDataReader * reader,Object * ob)3852 static void direct_link_object(BlendDataReader *reader, Object *ob)
3853 {
3854   PartEff *paf;
3855 
3856   /* XXX This should not be needed - but seems like it can happen in some cases,
3857    * so for now play safe. */
3858   ob->proxy_from = NULL;
3859 
3860   const bool is_undo = BLO_read_data_is_undo(reader);
3861   if (ob->id.tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT)) {
3862     /* Do not allow any non-object mode for linked data.
3863      * See T34776, T42780, T81027 for more information. */
3864     ob->mode &= ~OB_MODE_ALL_MODE_DATA;
3865   }
3866   else if (is_undo) {
3867     /* For undo we want to stay in object mode during undo presses, so keep some edit modes
3868      * disabled.
3869      * TODO: Check if we should not disable more edit modes here? */
3870     ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT);
3871   }
3872 
3873   BLO_read_data_address(reader, &ob->adt);
3874   BKE_animdata_blend_read_data(reader, ob->adt);
3875 
3876   BLO_read_data_address(reader, &ob->pose);
3877   direct_link_pose(reader, ob->pose);
3878 
3879   BLO_read_data_address(reader, &ob->mpath);
3880   if (ob->mpath) {
3881     direct_link_motionpath(reader, ob->mpath);
3882   }
3883 
3884   BLO_read_list(reader, &ob->defbase);
3885   BLO_read_list(reader, &ob->fmaps);
3886   /* XXX deprecated - old animation system <<< */
3887   direct_link_nlastrips(reader, &ob->nlastrips);
3888   BLO_read_list(reader, &ob->constraintChannels);
3889   /* >>> XXX deprecated - old animation system */
3890 
3891   BLO_read_pointer_array(reader, (void **)&ob->mat);
3892   BLO_read_data_address(reader, &ob->matbits);
3893 
3894   /* do it here, below old data gets converted */
3895   direct_link_modifiers(reader, &ob->modifiers, ob);
3896   direct_link_gpencil_modifiers(reader, &ob->greasepencil_modifiers);
3897   direct_link_shaderfxs(reader, &ob->shader_fx);
3898 
3899   BLO_read_list(reader, &ob->effect);
3900   paf = ob->effect.first;
3901   while (paf) {
3902     if (paf->type == EFF_PARTICLE) {
3903       paf->keys = NULL;
3904     }
3905     if (paf->type == EFF_WAVE) {
3906       WaveEff *wav = (WaveEff *)paf;
3907       PartEff *next = paf->next;
3908       WaveModifierData *wmd = (WaveModifierData *)BKE_modifier_new(eModifierType_Wave);
3909 
3910       wmd->damp = wav->damp;
3911       wmd->flag = wav->flag;
3912       wmd->height = wav->height;
3913       wmd->lifetime = wav->lifetime;
3914       wmd->narrow = wav->narrow;
3915       wmd->speed = wav->speed;
3916       wmd->startx = wav->startx;
3917       wmd->starty = wav->startx;
3918       wmd->timeoffs = wav->timeoffs;
3919       wmd->width = wav->width;
3920 
3921       BLI_addtail(&ob->modifiers, wmd);
3922 
3923       BLI_remlink(&ob->effect, paf);
3924       MEM_freeN(paf);
3925 
3926       paf = next;
3927       continue;
3928     }
3929     if (paf->type == EFF_BUILD) {
3930       BuildEff *baf = (BuildEff *)paf;
3931       PartEff *next = paf->next;
3932       BuildModifierData *bmd = (BuildModifierData *)BKE_modifier_new(eModifierType_Build);
3933 
3934       bmd->start = baf->sfra;
3935       bmd->length = baf->len;
3936       bmd->randomize = 0;
3937       bmd->seed = 1;
3938 
3939       BLI_addtail(&ob->modifiers, bmd);
3940 
3941       BLI_remlink(&ob->effect, paf);
3942       MEM_freeN(paf);
3943 
3944       paf = next;
3945       continue;
3946     }
3947     paf = paf->next;
3948   }
3949 
3950   BLO_read_data_address(reader, &ob->pd);
3951   direct_link_partdeflect(ob->pd);
3952   BLO_read_data_address(reader, &ob->soft);
3953   if (ob->soft) {
3954     SoftBody *sb = ob->soft;
3955 
3956     sb->bpoint = NULL; /* init pointers so it gets rebuilt nicely */
3957     sb->bspring = NULL;
3958     sb->scratch = NULL;
3959     /* although not used anymore */
3960     /* still have to be loaded to be compatible with old files */
3961     BLO_read_pointer_array(reader, (void **)&sb->keys);
3962     if (sb->keys) {
3963       for (int a = 0; a < sb->totkey; a++) {
3964         BLO_read_data_address(reader, &sb->keys[a]);
3965       }
3966     }
3967 
3968     BLO_read_data_address(reader, &sb->effector_weights);
3969     if (!sb->effector_weights) {
3970       sb->effector_weights = BKE_effector_add_weights(NULL);
3971     }
3972 
3973     BLO_read_data_address(reader, &sb->shared);
3974     if (sb->shared == NULL) {
3975       /* Link deprecated caches if they exist, so we can use them for versioning.
3976        * We should only do this when sb->shared == NULL, because those pointers
3977        * are always set (for compatibility with older Blenders). We mustn't link
3978        * the same pointcache twice. */
3979       direct_link_pointcache_list(reader, &sb->ptcaches, &sb->pointcache, false);
3980     }
3981     else {
3982       /* link caches */
3983       direct_link_pointcache_list(reader, &sb->shared->ptcaches, &sb->shared->pointcache, false);
3984     }
3985   }
3986   BLO_read_data_address(reader, &ob->fluidsimSettings); /* NT */
3987 
3988   BLO_read_data_address(reader, &ob->rigidbody_object);
3989   if (ob->rigidbody_object) {
3990     RigidBodyOb *rbo = ob->rigidbody_object;
3991     /* Allocate runtime-only struct */
3992     rbo->shared = MEM_callocN(sizeof(*rbo->shared), "RigidBodyObShared");
3993   }
3994   BLO_read_data_address(reader, &ob->rigidbody_constraint);
3995   if (ob->rigidbody_constraint) {
3996     ob->rigidbody_constraint->physics_constraint = NULL;
3997   }
3998 
3999   BLO_read_list(reader, &ob->particlesystem);
4000   direct_link_particlesystems(reader, &ob->particlesystem);
4001 
4002   direct_link_constraints(reader, &ob->constraints);
4003 
4004   BLO_read_list(reader, &ob->hooks);
4005   while (ob->hooks.first) {
4006     ObHook *hook = ob->hooks.first;
4007     HookModifierData *hmd = (HookModifierData *)BKE_modifier_new(eModifierType_Hook);
4008 
4009     BLO_read_int32_array(reader, hook->totindex, &hook->indexar);
4010 
4011     /* Do conversion here because if we have loaded
4012      * a hook we need to make sure it gets converted
4013      * and freed, regardless of version.
4014      */
4015     copy_v3_v3(hmd->cent, hook->cent);
4016     hmd->falloff = hook->falloff;
4017     hmd->force = hook->force;
4018     hmd->indexar = hook->indexar;
4019     hmd->object = hook->parent;
4020     memcpy(hmd->parentinv, hook->parentinv, sizeof(hmd->parentinv));
4021     hmd->totindex = hook->totindex;
4022 
4023     BLI_addhead(&ob->modifiers, hmd);
4024     BLI_remlink(&ob->hooks, hook);
4025 
4026     BKE_modifier_unique_name(&ob->modifiers, (ModifierData *)hmd);
4027 
4028     MEM_freeN(hook);
4029   }
4030 
4031   BLO_read_data_address(reader, &ob->iuser);
4032   if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE && !ob->iuser) {
4033     BKE_object_empty_draw_type_set(ob, ob->empty_drawtype);
4034   }
4035 
4036   BKE_object_runtime_reset(ob);
4037   BLO_read_list(reader, &ob->pc_ids);
4038 
4039   /* in case this value changes in future, clamp else we get undefined behavior */
4040   CLAMP(ob->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
4041 
4042   if (ob->sculpt) {
4043     ob->sculpt = NULL;
4044     /* Only create data on undo, otherwise rely on editor mode switching. */
4045     if (BLO_read_data_is_undo(reader) && (ob->mode & OB_MODE_ALL_SCULPT)) {
4046       BKE_object_sculpt_data_create(ob);
4047     }
4048   }
4049 
4050   BLO_read_data_address(reader, &ob->preview);
4051   BKE_previewimg_blend_read(reader, ob->preview);
4052 }
4053 
direct_link_view_settings(BlendDataReader * reader,ColorManagedViewSettings * view_settings)4054 static void direct_link_view_settings(BlendDataReader *reader,
4055                                       ColorManagedViewSettings *view_settings)
4056 {
4057   BLO_read_data_address(reader, &view_settings->curve_mapping);
4058 
4059   if (view_settings->curve_mapping) {
4060     BKE_curvemapping_blend_read(reader, view_settings->curve_mapping);
4061   }
4062 }
4063 
4064 /** \} */
4065 
4066 /* -------------------------------------------------------------------- */
4067 /** \name Read View Layer (Collection Data)
4068  * \{ */
4069 
direct_link_layer_collections(BlendDataReader * reader,ListBase * lb,bool master)4070 static void direct_link_layer_collections(BlendDataReader *reader, ListBase *lb, bool master)
4071 {
4072   BLO_read_list(reader, lb);
4073   LISTBASE_FOREACH (LayerCollection *, lc, lb) {
4074 #ifdef USE_COLLECTION_COMPAT_28
4075     BLO_read_data_address(reader, &lc->scene_collection);
4076 #endif
4077 
4078     /* Master collection is not a real data-lock. */
4079     if (master) {
4080       BLO_read_data_address(reader, &lc->collection);
4081     }
4082 
4083     direct_link_layer_collections(reader, &lc->layer_collections, false);
4084   }
4085 }
4086 
direct_link_view_layer(BlendDataReader * reader,ViewLayer * view_layer)4087 static void direct_link_view_layer(BlendDataReader *reader, ViewLayer *view_layer)
4088 {
4089   view_layer->stats = NULL;
4090   BLO_read_list(reader, &view_layer->object_bases);
4091   BLO_read_data_address(reader, &view_layer->basact);
4092 
4093   direct_link_layer_collections(reader, &view_layer->layer_collections, true);
4094   BLO_read_data_address(reader, &view_layer->active_collection);
4095 
4096   BLO_read_data_address(reader, &view_layer->id_properties);
4097   IDP_BlendDataRead(reader, &view_layer->id_properties);
4098 
4099   BLO_read_list(reader, &(view_layer->freestyle_config.modules));
4100   BLO_read_list(reader, &(view_layer->freestyle_config.linesets));
4101 
4102   BLI_listbase_clear(&view_layer->drawdata);
4103   view_layer->object_bases_array = NULL;
4104   view_layer->object_bases_hash = NULL;
4105 }
4106 
lib_link_layer_collection(BlendLibReader * reader,Library * lib,LayerCollection * layer_collection,bool master)4107 static void lib_link_layer_collection(BlendLibReader *reader,
4108                                       Library *lib,
4109                                       LayerCollection *layer_collection,
4110                                       bool master)
4111 {
4112   /* Master collection is not a real data-lock. */
4113   if (!master) {
4114     BLO_read_id_address(reader, lib, &layer_collection->collection);
4115   }
4116 
4117   LISTBASE_FOREACH (
4118       LayerCollection *, layer_collection_nested, &layer_collection->layer_collections) {
4119     lib_link_layer_collection(reader, lib, layer_collection_nested, false);
4120   }
4121 }
4122 
lib_link_view_layer(BlendLibReader * reader,Library * lib,ViewLayer * view_layer)4123 static void lib_link_view_layer(BlendLibReader *reader, Library *lib, ViewLayer *view_layer)
4124 {
4125   LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) {
4126     BLO_read_id_address(reader, lib, &fmc->script);
4127   }
4128 
4129   LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
4130     BLO_read_id_address(reader, lib, &fls->linestyle);
4131     BLO_read_id_address(reader, lib, &fls->group);
4132   }
4133 
4134   for (Base *base = view_layer->object_bases.first, *base_next = NULL; base; base = base_next) {
4135     base_next = base->next;
4136 
4137     /* we only bump the use count for the collection objects */
4138     BLO_read_id_address(reader, lib, &base->object);
4139 
4140     if (base->object == NULL) {
4141       /* Free in case linked object got lost. */
4142       BLI_freelinkN(&view_layer->object_bases, base);
4143       if (view_layer->basact == base) {
4144         view_layer->basact = NULL;
4145       }
4146     }
4147   }
4148 
4149   LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
4150     lib_link_layer_collection(reader, lib, layer_collection, true);
4151   }
4152 
4153   BLO_read_id_address(reader, lib, &view_layer->mat_override);
4154 
4155   IDP_BlendReadLib(reader, view_layer->id_properties);
4156 }
4157 
4158 /** \} */
4159 
4160 /* -------------------------------------------------------------------- */
4161 /** \name Read ID: Collection
4162  * \{ */
4163 
4164 #ifdef USE_COLLECTION_COMPAT_28
direct_link_scene_collection(BlendDataReader * reader,SceneCollection * sc)4165 static void direct_link_scene_collection(BlendDataReader *reader, SceneCollection *sc)
4166 {
4167   BLO_read_list(reader, &sc->objects);
4168   BLO_read_list(reader, &sc->scene_collections);
4169 
4170   LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
4171     direct_link_scene_collection(reader, nsc);
4172   }
4173 }
4174 
lib_link_scene_collection(BlendLibReader * reader,Library * lib,SceneCollection * sc)4175 static void lib_link_scene_collection(BlendLibReader *reader, Library *lib, SceneCollection *sc)
4176 {
4177   LISTBASE_FOREACH (LinkData *, link, &sc->objects) {
4178     BLO_read_id_address(reader, lib, &link->data);
4179     BLI_assert(link->data);
4180   }
4181 
4182   LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
4183     lib_link_scene_collection(reader, lib, nsc);
4184   }
4185 }
4186 #endif
4187 
direct_link_collection(BlendDataReader * reader,Collection * collection)4188 static void direct_link_collection(BlendDataReader *reader, Collection *collection)
4189 {
4190   BLO_read_list(reader, &collection->gobject);
4191   BLO_read_list(reader, &collection->children);
4192 
4193   BLO_read_data_address(reader, &collection->preview);
4194   BKE_previewimg_blend_read(reader, collection->preview);
4195 
4196   collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
4197   collection->tag = 0;
4198   BLI_listbase_clear(&collection->object_cache);
4199   BLI_listbase_clear(&collection->parents);
4200 
4201 #ifdef USE_COLLECTION_COMPAT_28
4202   /* This runs before the very first doversion. */
4203   BLO_read_data_address(reader, &collection->collection);
4204   if (collection->collection != NULL) {
4205     direct_link_scene_collection(reader, collection->collection);
4206   }
4207 
4208   BLO_read_data_address(reader, &collection->view_layer);
4209   if (collection->view_layer != NULL) {
4210     direct_link_view_layer(reader, collection->view_layer);
4211   }
4212 #endif
4213 }
4214 
lib_link_collection_data(BlendLibReader * reader,Library * lib,Collection * collection)4215 static void lib_link_collection_data(BlendLibReader *reader, Library *lib, Collection *collection)
4216 {
4217   LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection->gobject) {
4218     BLO_read_id_address(reader, lib, &cob->ob);
4219 
4220     if (cob->ob == NULL) {
4221       BLI_freelinkN(&collection->gobject, cob);
4222     }
4223   }
4224 
4225   LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
4226     BLO_read_id_address(reader, lib, &child->collection);
4227   }
4228 }
4229 
lib_link_collection(BlendLibReader * reader,Collection * collection)4230 static void lib_link_collection(BlendLibReader *reader, Collection *collection)
4231 {
4232 #ifdef USE_COLLECTION_COMPAT_28
4233   if (collection->collection) {
4234     lib_link_scene_collection(reader, collection->id.lib, collection->collection);
4235   }
4236 
4237   if (collection->view_layer) {
4238     lib_link_view_layer(reader, collection->id.lib, collection->view_layer);
4239   }
4240 #endif
4241 
4242   lib_link_collection_data(reader, collection->id.lib, collection);
4243 }
4244 
4245 /** \} */
4246 
4247 /* -------------------------------------------------------------------- */
4248 /** \name Read ID: Scene
4249  * \{ */
4250 
4251 /* patch for missing scene IDs, can't be in do-versions */
composite_patch(bNodeTree * ntree,Scene * scene)4252 static void composite_patch(bNodeTree *ntree, Scene *scene)
4253 {
4254 
4255   LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
4256     if (node->id == NULL && node->type == CMP_NODE_R_LAYERS) {
4257       node->id = &scene->id;
4258     }
4259   }
4260 }
4261 
link_paint(BlendLibReader * reader,Scene * sce,Paint * p)4262 static void link_paint(BlendLibReader *reader, Scene *sce, Paint *p)
4263 {
4264   if (p) {
4265     BLO_read_id_address(reader, sce->id.lib, &p->brush);
4266     for (int i = 0; i < p->tool_slots_len; i++) {
4267       if (p->tool_slots[i].brush != NULL) {
4268         BLO_read_id_address(reader, sce->id.lib, &p->tool_slots[i].brush);
4269       }
4270     }
4271     BLO_read_id_address(reader, sce->id.lib, &p->palette);
4272     p->paint_cursor = NULL;
4273 
4274     BKE_paint_runtime_init(sce->toolsettings, p);
4275   }
4276 }
4277 
lib_link_sequence_modifiers(BlendLibReader * reader,Scene * scene,ListBase * lb)4278 static void lib_link_sequence_modifiers(BlendLibReader *reader, Scene *scene, ListBase *lb)
4279 {
4280   LISTBASE_FOREACH (SequenceModifierData *, smd, lb) {
4281     if (smd->mask_id) {
4282       BLO_read_id_address(reader, scene->id.lib, &smd->mask_id);
4283     }
4284   }
4285 }
4286 
direct_link_lightcache_texture(BlendDataReader * reader,LightCacheTexture * lctex)4287 static void direct_link_lightcache_texture(BlendDataReader *reader, LightCacheTexture *lctex)
4288 {
4289   lctex->tex = NULL;
4290 
4291   if (lctex->data) {
4292     BLO_read_data_address(reader, &lctex->data);
4293     if (lctex->data && BLO_read_requires_endian_switch(reader)) {
4294       int data_size = lctex->components * lctex->tex_size[0] * lctex->tex_size[1] *
4295                       lctex->tex_size[2];
4296 
4297       if (lctex->data_type == LIGHTCACHETEX_FLOAT) {
4298         BLI_endian_switch_float_array((float *)lctex->data, data_size * sizeof(float));
4299       }
4300       else if (lctex->data_type == LIGHTCACHETEX_UINT) {
4301         BLI_endian_switch_uint32_array((uint *)lctex->data, data_size * sizeof(uint));
4302       }
4303     }
4304   }
4305 
4306   if (lctex->data == NULL) {
4307     zero_v3_int(lctex->tex_size);
4308   }
4309 }
4310 
direct_link_lightcache(BlendDataReader * reader,LightCache * cache)4311 static void direct_link_lightcache(BlendDataReader *reader, LightCache *cache)
4312 {
4313   cache->flag &= ~LIGHTCACHE_NOT_USABLE;
4314   direct_link_lightcache_texture(reader, &cache->cube_tx);
4315   direct_link_lightcache_texture(reader, &cache->grid_tx);
4316 
4317   if (cache->cube_mips) {
4318     BLO_read_data_address(reader, &cache->cube_mips);
4319     for (int i = 0; i < cache->mips_len; i++) {
4320       direct_link_lightcache_texture(reader, &cache->cube_mips[i]);
4321     }
4322   }
4323 
4324   BLO_read_data_address(reader, &cache->cube_data);
4325   BLO_read_data_address(reader, &cache->grid_data);
4326 }
4327 
direct_link_view3dshading(BlendDataReader * reader,View3DShading * shading)4328 static void direct_link_view3dshading(BlendDataReader *reader, View3DShading *shading)
4329 {
4330   if (shading->prop) {
4331     BLO_read_data_address(reader, &shading->prop);
4332     IDP_BlendDataRead(reader, &shading->prop);
4333   }
4334 }
4335 
4336 /* check for cyclic set-scene,
4337  * libs can cause this case which is normally prevented, see (T#####) */
4338 #define USE_SETSCENE_CHECK
4339 
4340 #ifdef USE_SETSCENE_CHECK
4341 /**
4342  * A version of #BKE_scene_validate_setscene with special checks for linked libs.
4343  */
scene_validate_setscene__liblink(Scene * sce,const int totscene)4344 static bool scene_validate_setscene__liblink(Scene *sce, const int totscene)
4345 {
4346   Scene *sce_iter;
4347   int a;
4348 
4349   if (sce->set == NULL) {
4350     return true;
4351   }
4352 
4353   for (a = 0, sce_iter = sce; sce_iter->set; sce_iter = sce_iter->set, a++) {
4354     /* This runs per library (before each libraries #Main has been joined),
4355      * so we can't step into other libraries since `totscene` is only for this library.
4356      *
4357      * Also, other libraries may not have been linked yet,
4358      * while we could check #LIB_TAG_NEED_LINK the library pointer check is sufficient. */
4359     if (sce->id.lib != sce_iter->id.lib) {
4360       return true;
4361     }
4362     if (sce_iter->flag & SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK) {
4363       return true;
4364     }
4365 
4366     if (a > totscene) {
4367       sce->set = NULL;
4368       return false;
4369     }
4370   }
4371 
4372   return true;
4373 }
4374 #endif
4375 
lib_link_scene(BlendLibReader * reader,Scene * sce)4376 static void lib_link_scene(BlendLibReader *reader, Scene *sce)
4377 {
4378   BKE_keyingsets_blend_read_lib(reader, &sce->id, &sce->keyingsets);
4379 
4380   BLO_read_id_address(reader, sce->id.lib, &sce->camera);
4381   BLO_read_id_address(reader, sce->id.lib, &sce->world);
4382   BLO_read_id_address(reader, sce->id.lib, &sce->set);
4383   BLO_read_id_address(reader, sce->id.lib, &sce->gpd);
4384 
4385   link_paint(reader, sce, &sce->toolsettings->imapaint.paint);
4386   if (sce->toolsettings->sculpt) {
4387     link_paint(reader, sce, &sce->toolsettings->sculpt->paint);
4388   }
4389   if (sce->toolsettings->vpaint) {
4390     link_paint(reader, sce, &sce->toolsettings->vpaint->paint);
4391   }
4392   if (sce->toolsettings->wpaint) {
4393     link_paint(reader, sce, &sce->toolsettings->wpaint->paint);
4394   }
4395   if (sce->toolsettings->uvsculpt) {
4396     link_paint(reader, sce, &sce->toolsettings->uvsculpt->paint);
4397   }
4398   if (sce->toolsettings->gp_paint) {
4399     link_paint(reader, sce, &sce->toolsettings->gp_paint->paint);
4400   }
4401   if (sce->toolsettings->gp_vertexpaint) {
4402     link_paint(reader, sce, &sce->toolsettings->gp_vertexpaint->paint);
4403   }
4404   if (sce->toolsettings->gp_sculptpaint) {
4405     link_paint(reader, sce, &sce->toolsettings->gp_sculptpaint->paint);
4406   }
4407   if (sce->toolsettings->gp_weightpaint) {
4408     link_paint(reader, sce, &sce->toolsettings->gp_weightpaint->paint);
4409   }
4410 
4411   if (sce->toolsettings->sculpt) {
4412     BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->sculpt->gravity_object);
4413   }
4414 
4415   if (sce->toolsettings->imapaint.stencil) {
4416     BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->imapaint.stencil);
4417   }
4418 
4419   if (sce->toolsettings->imapaint.clone) {
4420     BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->imapaint.clone);
4421   }
4422 
4423   if (sce->toolsettings->imapaint.canvas) {
4424     BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->imapaint.canvas);
4425   }
4426 
4427   BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->particle.shape_object);
4428 
4429   BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->gp_sculpt.guide.reference_object);
4430 
4431   LISTBASE_FOREACH_MUTABLE (Base *, base_legacy, &sce->base) {
4432     BLO_read_id_address(reader, sce->id.lib, &base_legacy->object);
4433 
4434     if (base_legacy->object == NULL) {
4435       blo_reportf_wrap(reader->fd->reports,
4436                        RPT_WARNING,
4437                        TIP_("LIB: object lost from scene: '%s'"),
4438                        sce->id.name + 2);
4439       BLI_remlink(&sce->base, base_legacy);
4440       if (base_legacy == sce->basact) {
4441         sce->basact = NULL;
4442       }
4443       MEM_freeN(base_legacy);
4444     }
4445   }
4446 
4447   Sequence *seq;
4448   SEQ_ALL_BEGIN (sce->ed, seq) {
4449     IDP_BlendReadLib(reader, seq->prop);
4450 
4451     if (seq->ipo) {
4452       BLO_read_id_address(
4453           reader, sce->id.lib, &seq->ipo); /* XXX deprecated - old animation system */
4454     }
4455     seq->scene_sound = NULL;
4456     if (seq->scene) {
4457       BLO_read_id_address(reader, sce->id.lib, &seq->scene);
4458       seq->scene_sound = NULL;
4459     }
4460     if (seq->clip) {
4461       BLO_read_id_address(reader, sce->id.lib, &seq->clip);
4462     }
4463     if (seq->mask) {
4464       BLO_read_id_address(reader, sce->id.lib, &seq->mask);
4465     }
4466     if (seq->scene_camera) {
4467       BLO_read_id_address(reader, sce->id.lib, &seq->scene_camera);
4468     }
4469     if (seq->sound) {
4470       seq->scene_sound = NULL;
4471       if (seq->type == SEQ_TYPE_SOUND_HD) {
4472         seq->type = SEQ_TYPE_SOUND_RAM;
4473       }
4474       else {
4475         BLO_read_id_address(reader, sce->id.lib, &seq->sound);
4476       }
4477       if (seq->sound) {
4478         id_us_plus_no_lib((ID *)seq->sound);
4479         seq->scene_sound = NULL;
4480       }
4481     }
4482     if (seq->type == SEQ_TYPE_TEXT) {
4483       TextVars *t = seq->effectdata;
4484       BLO_read_id_address(reader, sce->id.lib, &t->text_font);
4485     }
4486     BLI_listbase_clear(&seq->anims);
4487 
4488     lib_link_sequence_modifiers(reader, sce, &seq->modifiers);
4489   }
4490   SEQ_ALL_END;
4491 
4492   LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
4493     IDP_BlendReadLib(reader, marker->prop);
4494 
4495     if (marker->camera) {
4496       BLO_read_id_address(reader, sce->id.lib, &marker->camera);
4497     }
4498   }
4499 
4500   /* rigidbody world relies on its linked collections */
4501   if (sce->rigidbody_world) {
4502     RigidBodyWorld *rbw = sce->rigidbody_world;
4503     if (rbw->group) {
4504       BLO_read_id_address(reader, sce->id.lib, &rbw->group);
4505     }
4506     if (rbw->constraints) {
4507       BLO_read_id_address(reader, sce->id.lib, &rbw->constraints);
4508     }
4509     if (rbw->effector_weights) {
4510       BLO_read_id_address(reader, sce->id.lib, &rbw->effector_weights->group);
4511     }
4512   }
4513 
4514   if (sce->nodetree) {
4515     composite_patch(sce->nodetree, sce);
4516   }
4517 
4518   LISTBASE_FOREACH (SceneRenderLayer *, srl, &sce->r.layers) {
4519     BLO_read_id_address(reader, sce->id.lib, &srl->mat_override);
4520     LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &srl->freestyleConfig.modules) {
4521       BLO_read_id_address(reader, sce->id.lib, &fmc->script);
4522     }
4523     LISTBASE_FOREACH (FreestyleLineSet *, fls, &srl->freestyleConfig.linesets) {
4524       BLO_read_id_address(reader, sce->id.lib, &fls->linestyle);
4525       BLO_read_id_address(reader, sce->id.lib, &fls->group);
4526     }
4527   }
4528   /* Motion Tracking */
4529   BLO_read_id_address(reader, sce->id.lib, &sce->clip);
4530 
4531 #ifdef USE_COLLECTION_COMPAT_28
4532   if (sce->collection) {
4533     lib_link_scene_collection(reader, sce->id.lib, sce->collection);
4534   }
4535 #endif
4536 
4537   LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
4538     lib_link_view_layer(reader, sce->id.lib, view_layer);
4539   }
4540 
4541   if (sce->r.bake.cage_object) {
4542     BLO_read_id_address(reader, sce->id.lib, &sce->r.bake.cage_object);
4543   }
4544 
4545 #ifdef USE_SETSCENE_CHECK
4546   if (sce->set != NULL) {
4547     sce->flag |= SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK;
4548   }
4549 #endif
4550 }
4551 
lib_link_scenes_check_set(Main * bmain)4552 static void lib_link_scenes_check_set(Main *bmain)
4553 {
4554 #ifdef USE_SETSCENE_CHECK
4555   const int totscene = BLI_listbase_count(&bmain->scenes);
4556   LISTBASE_FOREACH (Scene *, sce, &bmain->scenes) {
4557     if (sce->flag & SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK) {
4558       sce->flag &= ~SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK;
4559       if (!scene_validate_setscene__liblink(sce, totscene)) {
4560         printf("Found cyclic background scene when linking %s\n", sce->id.name + 2);
4561       }
4562     }
4563   }
4564 #else
4565   UNUSED_VARS(bmain, totscene);
4566 #endif
4567 }
4568 
4569 #undef USE_SETSCENE_CHECK
4570 
link_recurs_seq(BlendDataReader * reader,ListBase * lb)4571 static void link_recurs_seq(BlendDataReader *reader, ListBase *lb)
4572 {
4573   BLO_read_list(reader, lb);
4574 
4575   LISTBASE_FOREACH (Sequence *, seq, lb) {
4576     if (seq->seqbase.first) {
4577       link_recurs_seq(reader, &seq->seqbase);
4578     }
4579   }
4580 }
4581 
direct_link_paint(BlendDataReader * reader,const Scene * scene,Paint * p)4582 static void direct_link_paint(BlendDataReader *reader, const Scene *scene, Paint *p)
4583 {
4584   if (p->num_input_samples < 1) {
4585     p->num_input_samples = 1;
4586   }
4587 
4588   BLO_read_data_address(reader, &p->cavity_curve);
4589   if (p->cavity_curve) {
4590     BKE_curvemapping_blend_read(reader, p->cavity_curve);
4591   }
4592   else {
4593     BKE_paint_cavity_curve_preset(p, CURVE_PRESET_LINE);
4594   }
4595 
4596   BLO_read_data_address(reader, &p->tool_slots);
4597 
4598   /* Workaround for invalid data written in older versions. */
4599   const size_t expected_size = sizeof(PaintToolSlot) * p->tool_slots_len;
4600   if (p->tool_slots && MEM_allocN_len(p->tool_slots) < expected_size) {
4601     MEM_freeN(p->tool_slots);
4602     p->tool_slots = MEM_callocN(expected_size, "PaintToolSlot");
4603   }
4604 
4605   BKE_paint_runtime_init(scene->toolsettings, p);
4606 }
4607 
direct_link_paint_helper(BlendDataReader * reader,const Scene * scene,Paint ** paint)4608 static void direct_link_paint_helper(BlendDataReader *reader, const Scene *scene, Paint **paint)
4609 {
4610   /* TODO. is this needed */
4611   BLO_read_data_address(reader, paint);
4612 
4613   if (*paint) {
4614     direct_link_paint(reader, scene, *paint);
4615   }
4616 }
4617 
direct_link_sequence_modifiers(BlendDataReader * reader,ListBase * lb)4618 static void direct_link_sequence_modifiers(BlendDataReader *reader, ListBase *lb)
4619 {
4620   BLO_read_list(reader, lb);
4621 
4622   LISTBASE_FOREACH (SequenceModifierData *, smd, lb) {
4623     if (smd->mask_sequence) {
4624       BLO_read_data_address(reader, &smd->mask_sequence);
4625     }
4626 
4627     if (smd->type == seqModifierType_Curves) {
4628       CurvesModifierData *cmd = (CurvesModifierData *)smd;
4629 
4630       BKE_curvemapping_blend_read(reader, &cmd->curve_mapping);
4631     }
4632     else if (smd->type == seqModifierType_HueCorrect) {
4633       HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
4634 
4635       BKE_curvemapping_blend_read(reader, &hcmd->curve_mapping);
4636     }
4637   }
4638 }
4639 
direct_link_scene(BlendDataReader * reader,Scene * sce)4640 static void direct_link_scene(BlendDataReader *reader, Scene *sce)
4641 {
4642   sce->depsgraph_hash = NULL;
4643   sce->fps_info = NULL;
4644 
4645   memset(&sce->customdata_mask, 0, sizeof(sce->customdata_mask));
4646   memset(&sce->customdata_mask_modal, 0, sizeof(sce->customdata_mask_modal));
4647 
4648   BKE_sound_reset_scene_runtime(sce);
4649 
4650   /* set users to one by default, not in lib-link, this will increase it for compo nodes */
4651   id_us_ensure_real(&sce->id);
4652 
4653   BLO_read_list(reader, &(sce->base));
4654 
4655   BLO_read_data_address(reader, &sce->adt);
4656   BKE_animdata_blend_read_data(reader, sce->adt);
4657 
4658   BLO_read_list(reader, &sce->keyingsets);
4659   BKE_keyingsets_blend_read_data(reader, &sce->keyingsets);
4660 
4661   BLO_read_data_address(reader, &sce->basact);
4662 
4663   BLO_read_data_address(reader, &sce->toolsettings);
4664   if (sce->toolsettings) {
4665 
4666     /* Reset last_location and last_hit, so they are not remembered across sessions. In some files
4667      * these are also NaN, which could lead to crashes in painting. */
4668     struct UnifiedPaintSettings *ups = &sce->toolsettings->unified_paint_settings;
4669     zero_v3(ups->last_location);
4670     ups->last_hit = 0;
4671 
4672     direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->sculpt);
4673     direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->vpaint);
4674     direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->wpaint);
4675     direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->uvsculpt);
4676     direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_paint);
4677     direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_vertexpaint);
4678     direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_sculptpaint);
4679     direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_weightpaint);
4680 
4681     direct_link_paint(reader, sce, &sce->toolsettings->imapaint.paint);
4682 
4683     sce->toolsettings->particle.paintcursor = NULL;
4684     sce->toolsettings->particle.scene = NULL;
4685     sce->toolsettings->particle.object = NULL;
4686     sce->toolsettings->gp_sculpt.paintcursor = NULL;
4687 
4688     /* relink grease pencil interpolation curves */
4689     BLO_read_data_address(reader, &sce->toolsettings->gp_interpolate.custom_ipo);
4690     if (sce->toolsettings->gp_interpolate.custom_ipo) {
4691       BKE_curvemapping_blend_read(reader, sce->toolsettings->gp_interpolate.custom_ipo);
4692     }
4693     /* relink grease pencil multiframe falloff curve */
4694     BLO_read_data_address(reader, &sce->toolsettings->gp_sculpt.cur_falloff);
4695     if (sce->toolsettings->gp_sculpt.cur_falloff) {
4696       BKE_curvemapping_blend_read(reader, sce->toolsettings->gp_sculpt.cur_falloff);
4697     }
4698     /* relink grease pencil primitive curve */
4699     BLO_read_data_address(reader, &sce->toolsettings->gp_sculpt.cur_primitive);
4700     if (sce->toolsettings->gp_sculpt.cur_primitive) {
4701       BKE_curvemapping_blend_read(reader, sce->toolsettings->gp_sculpt.cur_primitive);
4702     }
4703 
4704     /* Relink toolsettings curve profile */
4705     BLO_read_data_address(reader, &sce->toolsettings->custom_bevel_profile_preset);
4706     if (sce->toolsettings->custom_bevel_profile_preset) {
4707       BKE_curveprofile_blend_read(reader, sce->toolsettings->custom_bevel_profile_preset);
4708     }
4709   }
4710 
4711   if (sce->ed) {
4712     ListBase *old_seqbasep = &sce->ed->seqbase;
4713 
4714     BLO_read_data_address(reader, &sce->ed);
4715     Editing *ed = sce->ed;
4716 
4717     BLO_read_data_address(reader, &ed->act_seq);
4718     ed->cache = NULL;
4719     ed->prefetch_job = NULL;
4720 
4721     /* recursive link sequences, lb will be correctly initialized */
4722     link_recurs_seq(reader, &ed->seqbase);
4723 
4724     Sequence *seq;
4725     SEQ_ALL_BEGIN (ed, seq) {
4726       /* Do as early as possible, so that other parts of reading can rely on valid session UUID. */
4727       BKE_sequence_session_uuid_generate(seq);
4728 
4729       BLO_read_data_address(reader, &seq->seq1);
4730       BLO_read_data_address(reader, &seq->seq2);
4731       BLO_read_data_address(reader, &seq->seq3);
4732 
4733       /* a patch: after introduction of effects with 3 input strips */
4734       if (seq->seq3 == NULL) {
4735         seq->seq3 = seq->seq2;
4736       }
4737 
4738       BLO_read_data_address(reader, &seq->effectdata);
4739       BLO_read_data_address(reader, &seq->stereo3d_format);
4740 
4741       if (seq->type & SEQ_TYPE_EFFECT) {
4742         seq->flag |= SEQ_EFFECT_NOT_LOADED;
4743       }
4744 
4745       if (seq->type == SEQ_TYPE_SPEED) {
4746         SpeedControlVars *s = seq->effectdata;
4747         s->frameMap = NULL;
4748       }
4749 
4750       if (seq->type == SEQ_TYPE_TEXT) {
4751         TextVars *t = seq->effectdata;
4752         t->text_blf_id = SEQ_FONT_NOT_LOADED;
4753       }
4754 
4755       BLO_read_data_address(reader, &seq->prop);
4756       IDP_BlendDataRead(reader, &seq->prop);
4757 
4758       BLO_read_data_address(reader, &seq->strip);
4759       if (seq->strip && seq->strip->done == 0) {
4760         seq->strip->done = true;
4761 
4762         if (ELEM(seq->type,
4763                  SEQ_TYPE_IMAGE,
4764                  SEQ_TYPE_MOVIE,
4765                  SEQ_TYPE_SOUND_RAM,
4766                  SEQ_TYPE_SOUND_HD)) {
4767           BLO_read_data_address(reader, &seq->strip->stripdata);
4768         }
4769         else {
4770           seq->strip->stripdata = NULL;
4771         }
4772         BLO_read_data_address(reader, &seq->strip->crop);
4773         BLO_read_data_address(reader, &seq->strip->transform);
4774         BLO_read_data_address(reader, &seq->strip->proxy);
4775         if (seq->strip->proxy) {
4776           seq->strip->proxy->anim = NULL;
4777         }
4778         else if (seq->flag & SEQ_USE_PROXY) {
4779           BKE_sequencer_proxy_set(seq, true);
4780         }
4781 
4782         /* need to load color balance to it could be converted to modifier */
4783         BLO_read_data_address(reader, &seq->strip->color_balance);
4784       }
4785 
4786       direct_link_sequence_modifiers(reader, &seq->modifiers);
4787     }
4788     SEQ_ALL_END;
4789 
4790     /* link metastack, slight abuse of structs here,
4791      * have to restore pointer to internal part in struct */
4792     {
4793       Sequence temp;
4794       void *poin;
4795       intptr_t offset;
4796 
4797       offset = ((intptr_t) & (temp.seqbase)) - ((intptr_t)&temp);
4798 
4799       /* root pointer */
4800       if (ed->seqbasep == old_seqbasep) {
4801         ed->seqbasep = &ed->seqbase;
4802       }
4803       else {
4804         poin = POINTER_OFFSET(ed->seqbasep, -offset);
4805 
4806         poin = BLO_read_get_new_data_address(reader, poin);
4807 
4808         if (poin) {
4809           ed->seqbasep = (ListBase *)POINTER_OFFSET(poin, offset);
4810         }
4811         else {
4812           ed->seqbasep = &ed->seqbase;
4813         }
4814       }
4815       /* stack */
4816       BLO_read_list(reader, &(ed->metastack));
4817 
4818       LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
4819         BLO_read_data_address(reader, &ms->parseq);
4820 
4821         if (ms->oldbasep == old_seqbasep) {
4822           ms->oldbasep = &ed->seqbase;
4823         }
4824         else {
4825           poin = POINTER_OFFSET(ms->oldbasep, -offset);
4826           poin = BLO_read_get_new_data_address(reader, poin);
4827           if (poin) {
4828             ms->oldbasep = (ListBase *)POINTER_OFFSET(poin, offset);
4829           }
4830           else {
4831             ms->oldbasep = &ed->seqbase;
4832           }
4833         }
4834       }
4835     }
4836   }
4837 
4838 #ifdef DURIAN_CAMERA_SWITCH
4839   /* Runtime */
4840   sce->r.mode &= ~R_NO_CAMERA_SWITCH;
4841 #endif
4842 
4843   BLO_read_data_address(reader, &sce->r.avicodecdata);
4844   if (sce->r.avicodecdata) {
4845     BLO_read_data_address(reader, &sce->r.avicodecdata->lpFormat);
4846     BLO_read_data_address(reader, &sce->r.avicodecdata->lpParms);
4847   }
4848   if (sce->r.ffcodecdata.properties) {
4849     BLO_read_data_address(reader, &sce->r.ffcodecdata.properties);
4850     IDP_BlendDataRead(reader, &sce->r.ffcodecdata.properties);
4851   }
4852 
4853   BLO_read_list(reader, &(sce->markers));
4854   LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
4855     BLO_read_data_address(reader, &marker->prop);
4856     IDP_BlendDataRead(reader, &marker->prop);
4857   }
4858 
4859   BLO_read_list(reader, &(sce->transform_spaces));
4860   BLO_read_list(reader, &(sce->r.layers));
4861   BLO_read_list(reader, &(sce->r.views));
4862 
4863   LISTBASE_FOREACH (SceneRenderLayer *, srl, &sce->r.layers) {
4864     BLO_read_data_address(reader, &srl->prop);
4865     IDP_BlendDataRead(reader, &srl->prop);
4866     BLO_read_list(reader, &(srl->freestyleConfig.modules));
4867     BLO_read_list(reader, &(srl->freestyleConfig.linesets));
4868   }
4869 
4870   direct_link_view_settings(reader, &sce->view_settings);
4871 
4872   BLO_read_data_address(reader, &sce->rigidbody_world);
4873   RigidBodyWorld *rbw = sce->rigidbody_world;
4874   if (rbw) {
4875     BLO_read_data_address(reader, &rbw->shared);
4876 
4877     if (rbw->shared == NULL) {
4878       /* Link deprecated caches if they exist, so we can use them for versioning.
4879        * We should only do this when rbw->shared == NULL, because those pointers
4880        * are always set (for compatibility with older Blenders). We mustn't link
4881        * the same pointcache twice. */
4882       direct_link_pointcache_list(reader, &rbw->ptcaches, &rbw->pointcache, false);
4883 
4884       /* make sure simulation starts from the beginning after loading file */
4885       if (rbw->pointcache) {
4886         rbw->ltime = (float)rbw->pointcache->startframe;
4887       }
4888     }
4889     else {
4890       /* must nullify the reference to physics sim object, since it no-longer exist
4891        * (and will need to be recalculated)
4892        */
4893       rbw->shared->physics_world = NULL;
4894 
4895       /* link caches */
4896       direct_link_pointcache_list(reader, &rbw->shared->ptcaches, &rbw->shared->pointcache, false);
4897 
4898       /* make sure simulation starts from the beginning after loading file */
4899       if (rbw->shared->pointcache) {
4900         rbw->ltime = (float)rbw->shared->pointcache->startframe;
4901       }
4902     }
4903     rbw->objects = NULL;
4904     rbw->numbodies = 0;
4905 
4906     /* set effector weights */
4907     BLO_read_data_address(reader, &rbw->effector_weights);
4908     if (!rbw->effector_weights) {
4909       rbw->effector_weights = BKE_effector_add_weights(NULL);
4910     }
4911   }
4912 
4913   BLO_read_data_address(reader, &sce->preview);
4914   BKE_previewimg_blend_read(reader, sce->preview);
4915 
4916   BKE_curvemapping_blend_read(reader, &sce->r.mblur_shutter_curve);
4917 
4918 #ifdef USE_COLLECTION_COMPAT_28
4919   /* this runs before the very first doversion */
4920   if (sce->collection) {
4921     BLO_read_data_address(reader, &sce->collection);
4922     direct_link_scene_collection(reader, sce->collection);
4923   }
4924 #endif
4925 
4926   /* insert into global old-new map for reading without UI (link_global accesses it again) */
4927   link_glob_list(reader->fd, &sce->view_layers);
4928   LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
4929     direct_link_view_layer(reader, view_layer);
4930   }
4931 
4932   if (BLO_read_data_is_undo(reader)) {
4933     /* If it's undo do nothing here, caches are handled by higher-level generic calling code. */
4934   }
4935   else {
4936     /* else try to read the cache from file. */
4937     BLO_read_data_address(reader, &sce->eevee.light_cache_data);
4938     if (sce->eevee.light_cache_data) {
4939       direct_link_lightcache(reader, sce->eevee.light_cache_data);
4940     }
4941   }
4942   EEVEE_lightcache_info_update(&sce->eevee);
4943 
4944   direct_link_view3dshading(reader, &sce->display.shading);
4945 
4946   BLO_read_data_address(reader, &sce->layer_properties);
4947   IDP_BlendDataRead(reader, &sce->layer_properties);
4948 }
4949 
4950 /** \} */
4951 
4952 /* -------------------------------------------------------------------- */
4953 /** \name Read Screen Area/Region (Screen Data)
4954  * \{ */
4955 
direct_link_panel_list(BlendDataReader * reader,ListBase * lb)4956 static void direct_link_panel_list(BlendDataReader *reader, ListBase *lb)
4957 {
4958   BLO_read_list(reader, lb);
4959 
4960   LISTBASE_FOREACH (Panel *, panel, lb) {
4961     panel->runtime_flag = 0;
4962     panel->activedata = NULL;
4963     panel->type = NULL;
4964     panel->runtime.custom_data_ptr = NULL;
4965     direct_link_panel_list(reader, &panel->children);
4966   }
4967 }
4968 
direct_link_region(BlendDataReader * reader,ARegion * region,int spacetype)4969 static void direct_link_region(BlendDataReader *reader, ARegion *region, int spacetype)
4970 {
4971   direct_link_panel_list(reader, &region->panels);
4972 
4973   BLO_read_list(reader, &region->panels_category_active);
4974 
4975   BLO_read_list(reader, &region->ui_lists);
4976 
4977   /* The area's search filter is runtime only, so we need to clear the active flag on read. */
4978   region->flag &= ~RGN_FLAG_SEARCH_FILTER_ACTIVE;
4979 
4980   LISTBASE_FOREACH (uiList *, ui_list, &region->ui_lists) {
4981     ui_list->type = NULL;
4982     ui_list->dyn_data = NULL;
4983     BLO_read_data_address(reader, &ui_list->properties);
4984     IDP_BlendDataRead(reader, &ui_list->properties);
4985   }
4986 
4987   BLO_read_list(reader, &region->ui_previews);
4988 
4989   if (spacetype == SPACE_EMPTY) {
4990     /* unknown space type, don't leak regiondata */
4991     region->regiondata = NULL;
4992   }
4993   else if (region->flag & RGN_FLAG_TEMP_REGIONDATA) {
4994     /* Runtime data, don't use. */
4995     region->regiondata = NULL;
4996   }
4997   else {
4998     BLO_read_data_address(reader, &region->regiondata);
4999     if (region->regiondata) {
5000       if (spacetype == SPACE_VIEW3D) {
5001         RegionView3D *rv3d = region->regiondata;
5002 
5003         BLO_read_data_address(reader, &rv3d->localvd);
5004         BLO_read_data_address(reader, &rv3d->clipbb);
5005 
5006         rv3d->depths = NULL;
5007         rv3d->render_engine = NULL;
5008         rv3d->sms = NULL;
5009         rv3d->smooth_timer = NULL;
5010 
5011         rv3d->rflag &= ~(RV3D_NAVIGATING | RV3D_PAINTING);
5012         rv3d->runtime_viewlock = 0;
5013       }
5014     }
5015   }
5016 
5017   region->v2d.sms = NULL;
5018   region->v2d.alpha_hor = region->v2d.alpha_vert = 255; /* visible by default */
5019   BLI_listbase_clear(&region->panels_category);
5020   BLI_listbase_clear(&region->handlers);
5021   BLI_listbase_clear(&region->uiblocks);
5022   region->headerstr = NULL;
5023   region->visible = 0;
5024   region->type = NULL;
5025   region->do_draw = 0;
5026   region->gizmo_map = NULL;
5027   region->regiontimer = NULL;
5028   region->draw_buffer = NULL;
5029   memset(&region->drawrct, 0, sizeof(region->drawrct));
5030 }
5031 
direct_link_area(BlendDataReader * reader,ScrArea * area)5032 static void direct_link_area(BlendDataReader *reader, ScrArea *area)
5033 {
5034   BLO_read_list(reader, &(area->spacedata));
5035   BLO_read_list(reader, &(area->regionbase));
5036 
5037   BLI_listbase_clear(&area->handlers);
5038   area->type = NULL; /* spacetype callbacks */
5039 
5040   /* Should always be unset so that rna_Area_type_get works correctly. */
5041   area->butspacetype = SPACE_EMPTY;
5042 
5043   area->region_active_win = -1;
5044 
5045   area->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE;
5046 
5047   BLO_read_data_address(reader, &area->global);
5048 
5049   /* if we do not have the spacetype registered we cannot
5050    * free it, so don't allocate any new memory for such spacetypes. */
5051   if (!BKE_spacetype_exists(area->spacetype)) {
5052     /* Hint for versioning code to replace deprecated space types. */
5053     area->butspacetype = area->spacetype;
5054 
5055     area->spacetype = SPACE_EMPTY;
5056   }
5057 
5058   LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
5059     direct_link_region(reader, region, area->spacetype);
5060   }
5061 
5062   /* accident can happen when read/save new file with older version */
5063   /* 2.50: we now always add spacedata for info */
5064   if (area->spacedata.first == NULL) {
5065     SpaceInfo *sinfo = MEM_callocN(sizeof(SpaceInfo), "spaceinfo");
5066     area->spacetype = sinfo->spacetype = SPACE_INFO;
5067     BLI_addtail(&area->spacedata, sinfo);
5068   }
5069   /* add local view3d too */
5070   else if (area->spacetype == SPACE_VIEW3D) {
5071     blo_do_versions_view3d_split_250(area->spacedata.first, &area->regionbase);
5072   }
5073 
5074   LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
5075     BLO_read_list(reader, &(sl->regionbase));
5076 
5077     /* if we do not have the spacetype registered we cannot
5078      * free it, so don't allocate any new memory for such spacetypes. */
5079     if (!BKE_spacetype_exists(sl->spacetype)) {
5080       sl->spacetype = SPACE_EMPTY;
5081     }
5082 
5083     LISTBASE_FOREACH (ARegion *, region, &sl->regionbase) {
5084       direct_link_region(reader, region, sl->spacetype);
5085     }
5086 
5087     if (sl->spacetype == SPACE_VIEW3D) {
5088       View3D *v3d = (View3D *)sl;
5089 
5090       v3d->flag |= V3D_INVALID_BACKBUF;
5091 
5092       if (v3d->gpd) {
5093         BLO_read_data_address(reader, &v3d->gpd);
5094         BKE_gpencil_blend_read_data(reader, v3d->gpd);
5095       }
5096       BLO_read_data_address(reader, &v3d->localvd);
5097 
5098       /* Runtime data */
5099       v3d->runtime.properties_storage = NULL;
5100       v3d->runtime.flag = 0;
5101 
5102       /* render can be quite heavy, set to solid on load */
5103       if (v3d->shading.type == OB_RENDER) {
5104         v3d->shading.type = OB_SOLID;
5105       }
5106       v3d->shading.prev_type = OB_SOLID;
5107 
5108       direct_link_view3dshading(reader, &v3d->shading);
5109 
5110       blo_do_versions_view3d_split_250(v3d, &sl->regionbase);
5111     }
5112     else if (sl->spacetype == SPACE_GRAPH) {
5113       SpaceGraph *sipo = (SpaceGraph *)sl;
5114 
5115       BLO_read_data_address(reader, &sipo->ads);
5116       BLI_listbase_clear(&sipo->runtime.ghost_curves);
5117     }
5118     else if (sl->spacetype == SPACE_NLA) {
5119       SpaceNla *snla = (SpaceNla *)sl;
5120 
5121       BLO_read_data_address(reader, &snla->ads);
5122     }
5123     else if (sl->spacetype == SPACE_OUTLINER) {
5124       SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
5125 
5126       /* use newdataadr_no_us and do not free old memory avoiding double
5127        * frees and use of freed memory. this could happen because of a
5128        * bug fixed in revision 58959 where the treestore memory address
5129        * was not unique */
5130       TreeStore *ts = newdataadr_no_us(reader->fd, space_outliner->treestore);
5131       space_outliner->treestore = NULL;
5132       if (ts) {
5133         TreeStoreElem *elems = newdataadr_no_us(reader->fd, ts->data);
5134 
5135         space_outliner->treestore = BLI_mempool_create(
5136             sizeof(TreeStoreElem), ts->usedelem, 512, BLI_MEMPOOL_ALLOW_ITER);
5137         if (ts->usedelem && elems) {
5138           for (int i = 0; i < ts->usedelem; i++) {
5139             TreeStoreElem *new_elem = BLI_mempool_alloc(space_outliner->treestore);
5140             *new_elem = elems[i];
5141           }
5142         }
5143         /* we only saved what was used */
5144         space_outliner->storeflag |= SO_TREESTORE_CLEANUP; /* at first draw */
5145       }
5146       space_outliner->treehash = NULL;
5147       space_outliner->tree.first = space_outliner->tree.last = NULL;
5148     }
5149     else if (sl->spacetype == SPACE_IMAGE) {
5150       SpaceImage *sima = (SpaceImage *)sl;
5151 
5152       sima->iuser.scene = NULL;
5153       sima->iuser.ok = 1;
5154       sima->scopes.waveform_1 = NULL;
5155       sima->scopes.waveform_2 = NULL;
5156       sima->scopes.waveform_3 = NULL;
5157       sima->scopes.vecscope = NULL;
5158       sima->scopes.ok = 0;
5159 
5160       /* WARNING: gpencil data is no longer stored directly in sima after 2.5
5161        * so sacrifice a few old files for now to avoid crashes with new files!
5162        * committed: r28002 */
5163 #if 0
5164       sima->gpd = newdataadr(fd, sima->gpd);
5165       if (sima->gpd) {
5166         BKE_gpencil_blend_read_data(fd, sima->gpd);
5167       }
5168 #endif
5169     }
5170     else if (sl->spacetype == SPACE_NODE) {
5171       SpaceNode *snode = (SpaceNode *)sl;
5172 
5173       if (snode->gpd) {
5174         BLO_read_data_address(reader, &snode->gpd);
5175         BKE_gpencil_blend_read_data(reader, snode->gpd);
5176       }
5177 
5178       BLO_read_list(reader, &snode->treepath);
5179       snode->edittree = NULL;
5180       snode->iofsd = NULL;
5181       BLI_listbase_clear(&snode->linkdrag);
5182     }
5183     else if (sl->spacetype == SPACE_TEXT) {
5184       SpaceText *st = (SpaceText *)sl;
5185       memset(&st->runtime, 0, sizeof(st->runtime));
5186     }
5187     else if (sl->spacetype == SPACE_SEQ) {
5188       SpaceSeq *sseq = (SpaceSeq *)sl;
5189 
5190       /* grease pencil data is not a direct data and can't be linked from direct_link*
5191        * functions, it should be linked from lib_link* functions instead
5192        *
5193        * otherwise it'll lead to lost grease data on open because it'll likely be
5194        * read from file after all other users of grease pencil and newdataadr would
5195        * simple return NULL here (sergey)
5196        */
5197 #if 0
5198       if (sseq->gpd) {
5199         sseq->gpd = newdataadr(fd, sseq->gpd);
5200         BKE_gpencil_blend_read_data(fd, sseq->gpd);
5201       }
5202 #endif
5203       sseq->scopes.reference_ibuf = NULL;
5204       sseq->scopes.zebra_ibuf = NULL;
5205       sseq->scopes.waveform_ibuf = NULL;
5206       sseq->scopes.sep_waveform_ibuf = NULL;
5207       sseq->scopes.vector_ibuf = NULL;
5208       sseq->scopes.histogram_ibuf = NULL;
5209     }
5210     else if (sl->spacetype == SPACE_PROPERTIES) {
5211       SpaceProperties *sbuts = (SpaceProperties *)sl;
5212 
5213       sbuts->path = NULL;
5214       sbuts->texuser = NULL;
5215       sbuts->mainbo = sbuts->mainb;
5216       sbuts->mainbuser = sbuts->mainb;
5217       sbuts->runtime = NULL;
5218     }
5219     else if (sl->spacetype == SPACE_CONSOLE) {
5220       SpaceConsole *sconsole = (SpaceConsole *)sl;
5221 
5222       BLO_read_list(reader, &sconsole->scrollback);
5223       BLO_read_list(reader, &sconsole->history);
5224 
5225       /* comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression,
5226        * from left to right.  the right-most expression sets the result of the comma
5227        * expression as a whole*/
5228       LISTBASE_FOREACH_MUTABLE (ConsoleLine *, cl, &sconsole->history) {
5229         BLO_read_data_address(reader, &cl->line);
5230         if (cl->line) {
5231           /* the allocted length is not written, so reset here */
5232           cl->len_alloc = cl->len + 1;
5233         }
5234         else {
5235           BLI_remlink(&sconsole->history, cl);
5236           MEM_freeN(cl);
5237         }
5238       }
5239     }
5240     else if (sl->spacetype == SPACE_FILE) {
5241       SpaceFile *sfile = (SpaceFile *)sl;
5242 
5243       /* this sort of info is probably irrelevant for reloading...
5244        * plus, it isn't saved to files yet!
5245        */
5246       sfile->folders_prev = sfile->folders_next = NULL;
5247       sfile->files = NULL;
5248       sfile->layout = NULL;
5249       sfile->op = NULL;
5250       sfile->previews_timer = NULL;
5251       BLO_read_data_address(reader, &sfile->params);
5252     }
5253     else if (sl->spacetype == SPACE_CLIP) {
5254       SpaceClip *sclip = (SpaceClip *)sl;
5255 
5256       sclip->scopes.track_search = NULL;
5257       sclip->scopes.track_preview = NULL;
5258       sclip->scopes.ok = 0;
5259     }
5260   }
5261 
5262   BLI_listbase_clear(&area->actionzones);
5263 
5264   BLO_read_data_address(reader, &area->v1);
5265   BLO_read_data_address(reader, &area->v2);
5266   BLO_read_data_address(reader, &area->v3);
5267   BLO_read_data_address(reader, &area->v4);
5268 }
5269 
lib_link_area(BlendLibReader * reader,ID * parent_id,ScrArea * area)5270 static void lib_link_area(BlendLibReader *reader, ID *parent_id, ScrArea *area)
5271 {
5272   BLO_read_id_address(reader, parent_id->lib, &area->full);
5273 
5274   memset(&area->runtime, 0x0, sizeof(area->runtime));
5275 
5276   LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
5277     switch (sl->spacetype) {
5278       case SPACE_VIEW3D: {
5279         View3D *v3d = (View3D *)sl;
5280 
5281         BLO_read_id_address(reader, parent_id->lib, &v3d->camera);
5282         BLO_read_id_address(reader, parent_id->lib, &v3d->ob_center);
5283 
5284         if (v3d->localvd) {
5285           BLO_read_id_address(reader, parent_id->lib, &v3d->localvd->camera);
5286         }
5287         break;
5288       }
5289       case SPACE_GRAPH: {
5290         SpaceGraph *sipo = (SpaceGraph *)sl;
5291         bDopeSheet *ads = sipo->ads;
5292 
5293         if (ads) {
5294           BLO_read_id_address(reader, parent_id->lib, &ads->source);
5295           BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
5296         }
5297         break;
5298       }
5299       case SPACE_PROPERTIES: {
5300         SpaceProperties *sbuts = (SpaceProperties *)sl;
5301         BLO_read_id_address(reader, parent_id->lib, &sbuts->pinid);
5302         if (sbuts->pinid == NULL) {
5303           sbuts->flag &= ~SB_PIN_CONTEXT;
5304         }
5305         break;
5306       }
5307       case SPACE_FILE:
5308         break;
5309       case SPACE_ACTION: {
5310         SpaceAction *saction = (SpaceAction *)sl;
5311         bDopeSheet *ads = &saction->ads;
5312 
5313         if (ads) {
5314           BLO_read_id_address(reader, parent_id->lib, &ads->source);
5315           BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
5316         }
5317 
5318         BLO_read_id_address(reader, parent_id->lib, &saction->action);
5319         break;
5320       }
5321       case SPACE_IMAGE: {
5322         SpaceImage *sima = (SpaceImage *)sl;
5323 
5324         BLO_read_id_address(reader, parent_id->lib, &sima->image);
5325         BLO_read_id_address(reader, parent_id->lib, &sima->mask_info.mask);
5326 
5327         /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
5328          * so fingers crossed this works fine!
5329          */
5330         BLO_read_id_address(reader, parent_id->lib, &sima->gpd);
5331         break;
5332       }
5333       case SPACE_SEQ: {
5334         SpaceSeq *sseq = (SpaceSeq *)sl;
5335 
5336         /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
5337          * so fingers crossed this works fine!
5338          */
5339         BLO_read_id_address(reader, parent_id->lib, &sseq->gpd);
5340         break;
5341       }
5342       case SPACE_NLA: {
5343         SpaceNla *snla = (SpaceNla *)sl;
5344         bDopeSheet *ads = snla->ads;
5345 
5346         if (ads) {
5347           BLO_read_id_address(reader, parent_id->lib, &ads->source);
5348           BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp);
5349         }
5350         break;
5351       }
5352       case SPACE_TEXT: {
5353         SpaceText *st = (SpaceText *)sl;
5354 
5355         BLO_read_id_address(reader, parent_id->lib, &st->text);
5356         break;
5357       }
5358       case SPACE_SCRIPT: {
5359         SpaceScript *scpt = (SpaceScript *)sl;
5360         /*scpt->script = NULL; - 2.45 set to null, better re-run the script */
5361         if (scpt->script) {
5362           BLO_read_id_address(reader, parent_id->lib, &scpt->script);
5363           if (scpt->script) {
5364             SCRIPT_SET_NULL(scpt->script);
5365           }
5366         }
5367         break;
5368       }
5369       case SPACE_OUTLINER: {
5370         SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
5371         BLO_read_id_address(reader, NULL, &space_outliner->search_tse.id);
5372 
5373         if (space_outliner->treestore) {
5374           TreeStoreElem *tselem;
5375           BLI_mempool_iter iter;
5376 
5377           BLI_mempool_iternew(space_outliner->treestore, &iter);
5378           while ((tselem = BLI_mempool_iterstep(&iter))) {
5379             BLO_read_id_address(reader, NULL, &tselem->id);
5380           }
5381           if (space_outliner->treehash) {
5382             /* rebuild hash table, because it depends on ids too */
5383             space_outliner->storeflag |= SO_TREESTORE_REBUILD;
5384           }
5385         }
5386         break;
5387       }
5388       case SPACE_NODE: {
5389         SpaceNode *snode = (SpaceNode *)sl;
5390 
5391         /* node tree can be stored locally in id too, link this first */
5392         BLO_read_id_address(reader, parent_id->lib, &snode->id);
5393         BLO_read_id_address(reader, parent_id->lib, &snode->from);
5394 
5395         bNodeTree *ntree = snode->id ? ntreeFromID(snode->id) : NULL;
5396         if (ntree) {
5397           snode->nodetree = ntree;
5398         }
5399         else {
5400           BLO_read_id_address(reader, parent_id->lib, &snode->nodetree);
5401         }
5402 
5403         bNodeTreePath *path;
5404         for (path = snode->treepath.first; path; path = path->next) {
5405           if (path == snode->treepath.first) {
5406             /* first nodetree in path is same as snode->nodetree */
5407             path->nodetree = snode->nodetree;
5408           }
5409           else {
5410             BLO_read_id_address(reader, parent_id->lib, &path->nodetree);
5411           }
5412 
5413           if (!path->nodetree) {
5414             break;
5415           }
5416         }
5417 
5418         /* remaining path entries are invalid, remove */
5419         bNodeTreePath *path_next;
5420         for (; path; path = path_next) {
5421           path_next = path->next;
5422 
5423           BLI_remlink(&snode->treepath, path);
5424           MEM_freeN(path);
5425         }
5426 
5427         /* edittree is just the last in the path,
5428          * set this directly since the path may have been shortened above */
5429         if (snode->treepath.last) {
5430           path = snode->treepath.last;
5431           snode->edittree = path->nodetree;
5432         }
5433         else {
5434           snode->edittree = NULL;
5435         }
5436         break;
5437       }
5438       case SPACE_CLIP: {
5439         SpaceClip *sclip = (SpaceClip *)sl;
5440         BLO_read_id_address(reader, parent_id->lib, &sclip->clip);
5441         BLO_read_id_address(reader, parent_id->lib, &sclip->mask_info.mask);
5442         break;
5443       }
5444       default:
5445         break;
5446     }
5447   }
5448 }
5449 
5450 /**
5451  * \return false on error.
5452  */
direct_link_area_map(BlendDataReader * reader,ScrAreaMap * area_map)5453 static bool direct_link_area_map(BlendDataReader *reader, ScrAreaMap *area_map)
5454 {
5455   BLO_read_list(reader, &area_map->vertbase);
5456   BLO_read_list(reader, &area_map->edgebase);
5457   BLO_read_list(reader, &area_map->areabase);
5458   LISTBASE_FOREACH (ScrArea *, area, &area_map->areabase) {
5459     direct_link_area(reader, area);
5460   }
5461 
5462   /* edges */
5463   LISTBASE_FOREACH (ScrEdge *, se, &area_map->edgebase) {
5464     BLO_read_data_address(reader, &se->v1);
5465     BLO_read_data_address(reader, &se->v2);
5466     BKE_screen_sort_scrvert(&se->v1, &se->v2);
5467 
5468     if (se->v1 == NULL) {
5469       BLI_remlink(&area_map->edgebase, se);
5470 
5471       return false;
5472     }
5473   }
5474 
5475   return true;
5476 }
5477 
5478 /** \} */
5479 
5480 /* -------------------------------------------------------------------- */
5481 /** \name XR-data
5482  * \{ */
5483 
direct_link_wm_xr_data(BlendDataReader * reader,wmXrData * xr_data)5484 static void direct_link_wm_xr_data(BlendDataReader *reader, wmXrData *xr_data)
5485 {
5486   direct_link_view3dshading(reader, &xr_data->session_settings.shading);
5487 }
5488 
lib_link_wm_xr_data(BlendLibReader * reader,ID * parent_id,wmXrData * xr_data)5489 static void lib_link_wm_xr_data(BlendLibReader *reader, ID *parent_id, wmXrData *xr_data)
5490 {
5491   BLO_read_id_address(reader, parent_id->lib, &xr_data->session_settings.base_pose_object);
5492 }
5493 
5494 /** \} */
5495 
5496 /* -------------------------------------------------------------------- */
5497 /** \name Read ID: Window Manager
5498  * \{ */
5499 
direct_link_windowmanager(BlendDataReader * reader,wmWindowManager * wm)5500 static void direct_link_windowmanager(BlendDataReader *reader, wmWindowManager *wm)
5501 {
5502   id_us_ensure_real(&wm->id);
5503   BLO_read_list(reader, &wm->windows);
5504 
5505   LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
5506     BLO_read_data_address(reader, &win->parent);
5507 
5508     WorkSpaceInstanceHook *hook = win->workspace_hook;
5509     BLO_read_data_address(reader, &win->workspace_hook);
5510 
5511     /* This will be NULL for any pre-2.80 blend file. */
5512     if (win->workspace_hook != NULL) {
5513       /* We need to restore a pointer to this later when reading workspaces,
5514        * so store in global oldnew-map.
5515        * Note that this is only needed for versioning of older .blend files now.. */
5516       oldnewmap_insert(reader->fd->globmap, hook, win->workspace_hook, 0);
5517       /* Cleanup pointers to data outside of this data-block scope. */
5518       win->workspace_hook->act_layout = NULL;
5519       win->workspace_hook->temp_workspace_store = NULL;
5520       win->workspace_hook->temp_layout_store = NULL;
5521     }
5522 
5523     direct_link_area_map(reader, &win->global_areas);
5524 
5525     win->ghostwin = NULL;
5526     win->gpuctx = NULL;
5527     win->eventstate = NULL;
5528     win->cursor_keymap_status = NULL;
5529     win->tweak = NULL;
5530 #ifdef WIN32
5531     win->ime_data = NULL;
5532 #endif
5533 
5534     BLI_listbase_clear(&win->queue);
5535     BLI_listbase_clear(&win->handlers);
5536     BLI_listbase_clear(&win->modalhandlers);
5537     BLI_listbase_clear(&win->gesture);
5538 
5539     win->active = 0;
5540 
5541     win->cursor = 0;
5542     win->lastcursor = 0;
5543     win->modalcursor = 0;
5544     win->grabcursor = 0;
5545     win->addmousemove = true;
5546     BLO_read_data_address(reader, &win->stereo3d_format);
5547 
5548     /* Multi-view always fallback to anaglyph at file opening
5549      * otherwise quad-buffer saved files can break Blender. */
5550     if (win->stereo3d_format) {
5551       win->stereo3d_format->display_mode = S3D_DISPLAY_ANAGLYPH;
5552     }
5553   }
5554 
5555   direct_link_wm_xr_data(reader, &wm->xr);
5556 
5557   BLI_listbase_clear(&wm->timers);
5558   BLI_listbase_clear(&wm->operators);
5559   BLI_listbase_clear(&wm->paintcursors);
5560   BLI_listbase_clear(&wm->queue);
5561   BKE_reports_init(&wm->reports, RPT_STORE);
5562 
5563   BLI_listbase_clear(&wm->keyconfigs);
5564   wm->defaultconf = NULL;
5565   wm->addonconf = NULL;
5566   wm->userconf = NULL;
5567   wm->undo_stack = NULL;
5568 
5569   wm->message_bus = NULL;
5570 
5571   wm->xr.runtime = NULL;
5572 
5573   BLI_listbase_clear(&wm->jobs);
5574   BLI_listbase_clear(&wm->drags);
5575 
5576   wm->windrawable = NULL;
5577   wm->winactive = NULL;
5578   wm->initialized = 0;
5579   wm->op_undo_depth = 0;
5580   wm->is_interface_locked = 0;
5581 }
5582 
lib_link_windowmanager(BlendLibReader * reader,wmWindowManager * wm)5583 static void lib_link_windowmanager(BlendLibReader *reader, wmWindowManager *wm)
5584 {
5585   LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
5586     if (win->workspace_hook) { /* NULL for old files */
5587       lib_link_workspace_instance_hook(reader, win->workspace_hook, &wm->id);
5588     }
5589     BLO_read_id_address(reader, wm->id.lib, &win->scene);
5590     /* deprecated, but needed for versioning (will be NULL'ed then) */
5591     BLO_read_id_address(reader, NULL, &win->screen);
5592 
5593     LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) {
5594       lib_link_area(reader, &wm->id, area);
5595     }
5596 
5597     lib_link_wm_xr_data(reader, &wm->id, &wm->xr);
5598   }
5599 }
5600 
5601 /** \} */
5602 
5603 /* -------------------------------------------------------------------- */
5604 /** \name Read ID: Screen
5605  * \{ */
5606 
5607 /* note: file read without screens option G_FILE_NO_UI;
5608  * check lib pointers in call below */
lib_link_screen(BlendLibReader * reader,bScreen * screen)5609 static void lib_link_screen(BlendLibReader *reader, bScreen *screen)
5610 {
5611   /* deprecated, but needed for versioning (will be NULL'ed then) */
5612   BLO_read_id_address(reader, screen->id.lib, &screen->scene);
5613 
5614   screen->animtimer = NULL; /* saved in rare cases */
5615   screen->tool_tip = NULL;
5616   screen->scrubbing = false;
5617 
5618   LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
5619     lib_link_area(reader, &screen->id, area);
5620   }
5621 }
5622 
5623 /* how to handle user count on pointer restore */
5624 typedef enum ePointerUserMode {
5625   USER_IGNORE = 0, /* ignore user count */
5626   USER_REAL = 1,   /* ensure at least one real user (fake user ignored) */
5627 } ePointerUserMode;
5628 
restore_pointer_user(ID * id,ID * newid,ePointerUserMode user)5629 static void restore_pointer_user(ID *id, ID *newid, ePointerUserMode user)
5630 {
5631   BLI_assert(STREQ(newid->name + 2, id->name + 2));
5632   BLI_assert(newid->lib == id->lib);
5633   UNUSED_VARS_NDEBUG(id);
5634 
5635   if (user == USER_REAL) {
5636     id_us_ensure_real(newid);
5637   }
5638 }
5639 
5640 #ifndef USE_GHASH_RESTORE_POINTER
5641 /**
5642  * A version of #restore_pointer_by_name that performs a full search (slow!).
5643  * Use only for limited lookups, when the overhead of
5644  * creating a #IDNameLib_Map for a single lookup isn't worthwhile.
5645  */
restore_pointer_by_name_main(Main * mainp,ID * id,ePointerUserMode user)5646 static void *restore_pointer_by_name_main(Main *mainp, ID *id, ePointerUserMode user)
5647 {
5648   if (id) {
5649     ListBase *lb = which_libbase(mainp, GS(id->name));
5650     if (lb) { /* there's still risk of checking corrupt mem (freed Ids in oops) */
5651       ID *idn = lb->first;
5652       for (; idn; idn = idn->next) {
5653         if (STREQ(idn->name + 2, id->name + 2)) {
5654           if (idn->lib == id->lib) {
5655             restore_pointer_user(id, idn, user);
5656             break;
5657           }
5658         }
5659       }
5660       return idn;
5661     }
5662   }
5663   return NULL;
5664 }
5665 #endif
5666 
5667 /**
5668  * Only for undo files, or to restore a screen after reading without UI...
5669  *
5670  * \param user:
5671  * - USER_IGNORE: no user-count change.
5672  * - USER_REAL: ensure a real user (even if a fake one is set).
5673  * \param id_map: lookup table, use when performing many lookups.
5674  * this could be made an optional argument (falling back to a full lookup),
5675  * however at the moment it's always available.
5676  */
restore_pointer_by_name(struct IDNameLib_Map * id_map,ID * id,ePointerUserMode user)5677 static void *restore_pointer_by_name(struct IDNameLib_Map *id_map, ID *id, ePointerUserMode user)
5678 {
5679 #ifdef USE_GHASH_RESTORE_POINTER
5680   if (id) {
5681     /* use fast lookup when available */
5682     ID *idn = BKE_main_idmap_lookup_id(id_map, id);
5683     if (idn) {
5684       restore_pointer_user(id, idn, user);
5685     }
5686     return idn;
5687   }
5688   return NULL;
5689 #else
5690   Main *mainp = BKE_main_idmap_main_get(id_map);
5691   return restore_pointer_by_name_main(mainp, id, user);
5692 #endif
5693 }
5694 
lib_link_seq_clipboard_pt_restore(ID * id,struct IDNameLib_Map * id_map)5695 static void lib_link_seq_clipboard_pt_restore(ID *id, struct IDNameLib_Map *id_map)
5696 {
5697   if (id) {
5698     /* clipboard must ensure this */
5699     BLI_assert(id->newid != NULL);
5700     id->newid = restore_pointer_by_name(id_map, id->newid, USER_REAL);
5701   }
5702 }
lib_link_seq_clipboard_cb(Sequence * seq,void * arg_pt)5703 static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
5704 {
5705   struct IDNameLib_Map *id_map = arg_pt;
5706 
5707   lib_link_seq_clipboard_pt_restore((ID *)seq->scene, id_map);
5708   lib_link_seq_clipboard_pt_restore((ID *)seq->scene_camera, id_map);
5709   lib_link_seq_clipboard_pt_restore((ID *)seq->clip, id_map);
5710   lib_link_seq_clipboard_pt_restore((ID *)seq->mask, id_map);
5711   lib_link_seq_clipboard_pt_restore((ID *)seq->sound, id_map);
5712   return 1;
5713 }
5714 
lib_link_clipboard_restore(struct IDNameLib_Map * id_map)5715 static void lib_link_clipboard_restore(struct IDNameLib_Map *id_map)
5716 {
5717   /* update IDs stored in sequencer clipboard */
5718   BKE_sequencer_base_recursive_apply(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map);
5719 }
5720 
lib_link_main_data_restore_cb(LibraryIDLinkCallbackData * cb_data)5721 static int lib_link_main_data_restore_cb(LibraryIDLinkCallbackData *cb_data)
5722 {
5723   const int cb_flag = cb_data->cb_flag;
5724   ID **id_pointer = cb_data->id_pointer;
5725   if (cb_flag & IDWALK_CB_EMBEDDED || *id_pointer == NULL) {
5726     return IDWALK_RET_NOP;
5727   }
5728 
5729   /* Special ugly case here, thanks again for those non-IDs IDs... */
5730   /* We probably need to add more cases here (hint: nodetrees),
5731    * but will wait for changes from D5559 to get in first. */
5732   if (GS((*id_pointer)->name) == ID_GR) {
5733     Collection *collection = (Collection *)*id_pointer;
5734     if (collection->flag & COLLECTION_IS_MASTER) {
5735       /* We should never reach that point anymore, since master collection private ID should be
5736        * properly tagged with IDWALK_CB_EMBEDDED. */
5737       BLI_assert(0);
5738       return IDWALK_RET_NOP;
5739     }
5740   }
5741 
5742   struct IDNameLib_Map *id_map = cb_data->user_data;
5743 
5744   /* Note: Handling of usercount here is really bad, defining its own system...
5745    * Will have to be refactored at some point, but that is not top priority task for now.
5746    * And all user-counts are properly recomputed at the end of the undo management code anyway. */
5747   *id_pointer = restore_pointer_by_name(
5748       id_map, *id_pointer, (cb_flag & IDWALK_CB_USER_ONE) ? USER_REAL : USER_IGNORE);
5749 
5750   return IDWALK_RET_NOP;
5751 }
5752 
lib_link_main_data_restore(struct IDNameLib_Map * id_map,Main * newmain)5753 static void lib_link_main_data_restore(struct IDNameLib_Map *id_map, Main *newmain)
5754 {
5755   ID *id;
5756   FOREACH_MAIN_ID_BEGIN (newmain, id) {
5757     BKE_library_foreach_ID_link(newmain, id, lib_link_main_data_restore_cb, id_map, IDWALK_NOP);
5758   }
5759   FOREACH_MAIN_ID_END;
5760 }
5761 
lib_link_wm_xr_data_restore(struct IDNameLib_Map * id_map,wmXrData * xr_data)5762 static void lib_link_wm_xr_data_restore(struct IDNameLib_Map *id_map, wmXrData *xr_data)
5763 {
5764   xr_data->session_settings.base_pose_object = restore_pointer_by_name(
5765       id_map, (ID *)xr_data->session_settings.base_pose_object, USER_REAL);
5766 }
5767 
lib_link_window_scene_data_restore(wmWindow * win,Scene * scene,ViewLayer * view_layer)5768 static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene, ViewLayer *view_layer)
5769 {
5770   bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
5771 
5772   LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
5773     LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
5774       if (sl->spacetype == SPACE_VIEW3D) {
5775         View3D *v3d = (View3D *)sl;
5776 
5777         if (v3d->camera == NULL || v3d->scenelock) {
5778           v3d->camera = scene->camera;
5779         }
5780 
5781         if (v3d->localvd) {
5782           Base *base = NULL;
5783 
5784           v3d->localvd->camera = scene->camera;
5785 
5786           /* Localview can become invalid during undo/redo steps,
5787            * so we exit it when no could be found. */
5788           for (base = view_layer->object_bases.first; base; base = base->next) {
5789             if (base->local_view_bits & v3d->local_view_uuid) {
5790               break;
5791             }
5792           }
5793           if (base == NULL) {
5794             MEM_freeN(v3d->localvd);
5795             v3d->localvd = NULL;
5796             v3d->local_view_uuid = 0;
5797 
5798             /* Regionbase storage is different depending if the space is active. */
5799             ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
5800                                                                    &sl->regionbase;
5801             LISTBASE_FOREACH (ARegion *, region, regionbase) {
5802               if (region->regiontype == RGN_TYPE_WINDOW) {
5803                 RegionView3D *rv3d = region->regiondata;
5804                 if (rv3d->localvd) {
5805                   MEM_freeN(rv3d->localvd);
5806                   rv3d->localvd = NULL;
5807                 }
5808               }
5809             }
5810           }
5811         }
5812       }
5813     }
5814   }
5815 }
5816 
lib_link_workspace_layout_restore(struct IDNameLib_Map * id_map,Main * newmain,WorkSpaceLayout * layout)5817 static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
5818                                               Main *newmain,
5819                                               WorkSpaceLayout *layout)
5820 {
5821   bScreen *screen = BKE_workspace_layout_screen_get(layout);
5822 
5823   /* avoid conflicts with 2.8x branch */
5824   {
5825     LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
5826       LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
5827         if (sl->spacetype == SPACE_VIEW3D) {
5828           View3D *v3d = (View3D *)sl;
5829 
5830           v3d->camera = restore_pointer_by_name(id_map, (ID *)v3d->camera, USER_REAL);
5831           v3d->ob_center = restore_pointer_by_name(id_map, (ID *)v3d->ob_center, USER_REAL);
5832         }
5833         else if (sl->spacetype == SPACE_GRAPH) {
5834           SpaceGraph *sipo = (SpaceGraph *)sl;
5835           bDopeSheet *ads = sipo->ads;
5836 
5837           if (ads) {
5838             ads->source = restore_pointer_by_name(id_map, (ID *)ads->source, USER_REAL);
5839 
5840             if (ads->filter_grp) {
5841               ads->filter_grp = restore_pointer_by_name(
5842                   id_map, (ID *)ads->filter_grp, USER_IGNORE);
5843             }
5844           }
5845 
5846           /* force recalc of list of channels (i.e. includes calculating F-Curve colors)
5847            * thus preventing the "black curves" problem post-undo
5848            */
5849           sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR;
5850         }
5851         else if (sl->spacetype == SPACE_PROPERTIES) {
5852           SpaceProperties *sbuts = (SpaceProperties *)sl;
5853           sbuts->pinid = restore_pointer_by_name(id_map, sbuts->pinid, USER_IGNORE);
5854           if (sbuts->pinid == NULL) {
5855             sbuts->flag &= ~SB_PIN_CONTEXT;
5856           }
5857 
5858           /* TODO: restore path pointers: T40046
5859            * (complicated because this contains data pointers too, not just ID)*/
5860           MEM_SAFE_FREE(sbuts->path);
5861         }
5862         else if (sl->spacetype == SPACE_FILE) {
5863           SpaceFile *sfile = (SpaceFile *)sl;
5864           sfile->op = NULL;
5865           sfile->previews_timer = NULL;
5866         }
5867         else if (sl->spacetype == SPACE_ACTION) {
5868           SpaceAction *saction = (SpaceAction *)sl;
5869 
5870           saction->action = restore_pointer_by_name(id_map, (ID *)saction->action, USER_REAL);
5871           saction->ads.source = restore_pointer_by_name(
5872               id_map, (ID *)saction->ads.source, USER_REAL);
5873 
5874           if (saction->ads.filter_grp) {
5875             saction->ads.filter_grp = restore_pointer_by_name(
5876                 id_map, (ID *)saction->ads.filter_grp, USER_IGNORE);
5877           }
5878 
5879           /* force recalc of list of channels, potentially updating the active action
5880            * while we're at it (as it can only be updated that way) T28962.
5881            */
5882           saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
5883         }
5884         else if (sl->spacetype == SPACE_IMAGE) {
5885           SpaceImage *sima = (SpaceImage *)sl;
5886 
5887           sima->image = restore_pointer_by_name(id_map, (ID *)sima->image, USER_REAL);
5888 
5889           /* this will be freed, not worth attempting to find same scene,
5890            * since it gets initialized later */
5891           sima->iuser.scene = NULL;
5892 
5893 #if 0
5894           /* Those are allocated and freed by space code, no need to handle them here. */
5895           MEM_SAFE_FREE(sima->scopes.waveform_1);
5896           MEM_SAFE_FREE(sima->scopes.waveform_2);
5897           MEM_SAFE_FREE(sima->scopes.waveform_3);
5898           MEM_SAFE_FREE(sima->scopes.vecscope);
5899 #endif
5900           sima->scopes.ok = 0;
5901 
5902           /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
5903            * so assume that here we're doing for undo only...
5904            */
5905           sima->gpd = restore_pointer_by_name(id_map, (ID *)sima->gpd, USER_REAL);
5906           sima->mask_info.mask = restore_pointer_by_name(
5907               id_map, (ID *)sima->mask_info.mask, USER_REAL);
5908         }
5909         else if (sl->spacetype == SPACE_SEQ) {
5910           SpaceSeq *sseq = (SpaceSeq *)sl;
5911 
5912           /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
5913            * so assume that here we're doing for undo only...
5914            */
5915           sseq->gpd = restore_pointer_by_name(id_map, (ID *)sseq->gpd, USER_REAL);
5916         }
5917         else if (sl->spacetype == SPACE_NLA) {
5918           SpaceNla *snla = (SpaceNla *)sl;
5919           bDopeSheet *ads = snla->ads;
5920 
5921           if (ads) {
5922             ads->source = restore_pointer_by_name(id_map, (ID *)ads->source, USER_REAL);
5923 
5924             if (ads->filter_grp) {
5925               ads->filter_grp = restore_pointer_by_name(
5926                   id_map, (ID *)ads->filter_grp, USER_IGNORE);
5927             }
5928           }
5929         }
5930         else if (sl->spacetype == SPACE_TEXT) {
5931           SpaceText *st = (SpaceText *)sl;
5932 
5933           st->text = restore_pointer_by_name(id_map, (ID *)st->text, USER_REAL);
5934           if (st->text == NULL) {
5935             st->text = newmain->texts.first;
5936           }
5937         }
5938         else if (sl->spacetype == SPACE_SCRIPT) {
5939           SpaceScript *scpt = (SpaceScript *)sl;
5940 
5941           scpt->script = restore_pointer_by_name(id_map, (ID *)scpt->script, USER_REAL);
5942 
5943           /*screen->script = NULL; - 2.45 set to null, better re-run the script */
5944           if (scpt->script) {
5945             SCRIPT_SET_NULL(scpt->script);
5946           }
5947         }
5948         else if (sl->spacetype == SPACE_OUTLINER) {
5949           SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
5950 
5951           space_outliner->search_tse.id = restore_pointer_by_name(
5952               id_map, space_outliner->search_tse.id, USER_IGNORE);
5953 
5954           if (space_outliner->treestore) {
5955             TreeStoreElem *tselem;
5956             BLI_mempool_iter iter;
5957 
5958             BLI_mempool_iternew(space_outliner->treestore, &iter);
5959             while ((tselem = BLI_mempool_iterstep(&iter))) {
5960               /* Do not try to restore pointers to drivers/sequence/etc.,
5961                * can crash in undo case! */
5962               if (TSE_IS_REAL_ID(tselem)) {
5963                 tselem->id = restore_pointer_by_name(id_map, tselem->id, USER_IGNORE);
5964               }
5965               else {
5966                 tselem->id = NULL;
5967               }
5968             }
5969             if (space_outliner->treehash) {
5970               /* rebuild hash table, because it depends on ids too */
5971               space_outliner->storeflag |= SO_TREESTORE_REBUILD;
5972             }
5973           }
5974         }
5975         else if (sl->spacetype == SPACE_NODE) {
5976           SpaceNode *snode = (SpaceNode *)sl;
5977           bNodeTreePath *path, *path_next;
5978           bNodeTree *ntree;
5979 
5980           /* node tree can be stored locally in id too, link this first */
5981           snode->id = restore_pointer_by_name(id_map, snode->id, USER_REAL);
5982           snode->from = restore_pointer_by_name(id_map, snode->from, USER_IGNORE);
5983 
5984           ntree = snode->id ? ntreeFromID(snode->id) : NULL;
5985           snode->nodetree = ntree ?
5986                                 ntree :
5987                                 restore_pointer_by_name(id_map, (ID *)snode->nodetree, USER_REAL);
5988 
5989           for (path = snode->treepath.first; path; path = path->next) {
5990             if (path == snode->treepath.first) {
5991               /* first nodetree in path is same as snode->nodetree */
5992               path->nodetree = snode->nodetree;
5993             }
5994             else {
5995               path->nodetree = restore_pointer_by_name(id_map, (ID *)path->nodetree, USER_REAL);
5996             }
5997 
5998             if (!path->nodetree) {
5999               break;
6000             }
6001           }
6002 
6003           /* remaining path entries are invalid, remove */
6004           for (; path; path = path_next) {
6005             path_next = path->next;
6006 
6007             BLI_remlink(&snode->treepath, path);
6008             MEM_freeN(path);
6009           }
6010 
6011           /* edittree is just the last in the path,
6012            * set this directly since the path may have been shortened above */
6013           if (snode->treepath.last) {
6014             path = snode->treepath.last;
6015             snode->edittree = path->nodetree;
6016           }
6017           else {
6018             snode->edittree = NULL;
6019           }
6020         }
6021         else if (sl->spacetype == SPACE_CLIP) {
6022           SpaceClip *sclip = (SpaceClip *)sl;
6023 
6024           sclip->clip = restore_pointer_by_name(id_map, (ID *)sclip->clip, USER_REAL);
6025           sclip->mask_info.mask = restore_pointer_by_name(
6026               id_map, (ID *)sclip->mask_info.mask, USER_REAL);
6027 
6028           sclip->scopes.ok = 0;
6029         }
6030       }
6031     }
6032   }
6033 }
6034 
6035 /**
6036  * Used to link a file (without UI) to the current UI.
6037  * Note that it assumes the old pointers in UI are still valid, so old Main is not freed.
6038  */
blo_lib_link_restore(Main * oldmain,Main * newmain,wmWindowManager * curwm,Scene * curscene,ViewLayer * cur_view_layer)6039 void blo_lib_link_restore(Main *oldmain,
6040                           Main *newmain,
6041                           wmWindowManager *curwm,
6042                           Scene *curscene,
6043                           ViewLayer *cur_view_layer)
6044 {
6045   struct IDNameLib_Map *id_map = BKE_main_idmap_create(
6046       newmain, true, oldmain, MAIN_IDMAP_TYPE_NAME);
6047 
6048   LISTBASE_FOREACH (WorkSpace *, workspace, &newmain->workspaces) {
6049     LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) {
6050       lib_link_workspace_layout_restore(id_map, newmain, layout);
6051     }
6052   }
6053 
6054   LISTBASE_FOREACH (wmWindow *, win, &curwm->windows) {
6055     WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
6056     ID *workspace_id = (ID *)workspace;
6057     Scene *oldscene = win->scene;
6058 
6059     workspace = restore_pointer_by_name(id_map, workspace_id, USER_REAL);
6060     BKE_workspace_active_set(win->workspace_hook, workspace);
6061     win->scene = restore_pointer_by_name(id_map, (ID *)win->scene, USER_REAL);
6062     if (win->scene == NULL) {
6063       win->scene = curscene;
6064     }
6065     if (BKE_view_layer_find(win->scene, win->view_layer_name) == NULL) {
6066       STRNCPY(win->view_layer_name, cur_view_layer->name);
6067     }
6068     BKE_workspace_active_set(win->workspace_hook, workspace);
6069 
6070     /* keep cursor location through undo */
6071     memcpy(&win->scene->cursor, &oldscene->cursor, sizeof(win->scene->cursor));
6072 
6073     /* Note: even though that function seems to redo part of what is done by
6074      * `lib_link_workspace_layout_restore()` above, it seems to have a slightly different scope:
6075      * while the former updates the whole UI pointers from Main db (going over all layouts of
6076      * all workspaces), that one only focuses one current active screen, takes care of
6077      * potential local view, and needs window's scene pointer to be final... */
6078     lib_link_window_scene_data_restore(win, win->scene, cur_view_layer);
6079 
6080     BLI_assert(win->screen == NULL);
6081   }
6082 
6083   lib_link_wm_xr_data_restore(id_map, &curwm->xr);
6084 
6085   /* Restore all ID pointers in Main database itself
6086    * (especially IDProperties might point to some word-space of other 'weirdly unchanged' ID
6087    * pointers, see T69146).
6088    * Note that this will re-apply again a few pointers in workspaces or so,
6089    * but since we are remapping final ones already set above,
6090    * that is just some minor harmless double-processing. */
6091   lib_link_main_data_restore(id_map, newmain);
6092 
6093   /* update IDs stored in all possible clipboards */
6094   lib_link_clipboard_restore(id_map);
6095 
6096   BKE_main_idmap_destroy(id_map);
6097 }
6098 
6099 /* for the saved 2.50 files without regiondata */
6100 /* and as patch for 2.48 and older */
blo_do_versions_view3d_split_250(View3D * v3d,ListBase * regions)6101 void blo_do_versions_view3d_split_250(View3D *v3d, ListBase *regions)
6102 {
6103   LISTBASE_FOREACH (ARegion *, region, regions) {
6104     if (region->regiontype == RGN_TYPE_WINDOW && region->regiondata == NULL) {
6105       RegionView3D *rv3d;
6106 
6107       rv3d = region->regiondata = MEM_callocN(sizeof(RegionView3D), "region v3d patch");
6108       rv3d->persp = (char)v3d->persp;
6109       rv3d->view = (char)v3d->view;
6110       rv3d->dist = v3d->dist;
6111       copy_v3_v3(rv3d->ofs, v3d->ofs);
6112       copy_qt_qt(rv3d->viewquat, v3d->viewquat);
6113     }
6114   }
6115 
6116   /* this was not initialized correct always */
6117   if (v3d->gridsubdiv == 0) {
6118     v3d->gridsubdiv = 10;
6119   }
6120 }
6121 
direct_link_screen(BlendDataReader * reader,bScreen * screen)6122 static bool direct_link_screen(BlendDataReader *reader, bScreen *screen)
6123 {
6124   bool success = true;
6125 
6126   screen->regionbase.first = screen->regionbase.last = NULL;
6127   screen->context = NULL;
6128   screen->active_region = NULL;
6129 
6130   BLO_read_data_address(reader, &screen->preview);
6131   BKE_previewimg_blend_read(reader, screen->preview);
6132 
6133   if (!direct_link_area_map(reader, AREAMAP_FROM_SCREEN(screen))) {
6134     printf("Error reading Screen %s... removing it.\n", screen->id.name + 2);
6135     success = false;
6136   }
6137 
6138   return success;
6139 }
6140 
6141 /** \} */
6142 
6143 /* -------------------------------------------------------------------- */
6144 /** \name Read ID: Library
6145  * \{ */
6146 
direct_link_library(FileData * fd,Library * lib,Main * main)6147 static void direct_link_library(FileData *fd, Library *lib, Main *main)
6148 {
6149   Main *newmain;
6150 
6151   /* check if the library was already read */
6152   for (newmain = fd->mainlist->first; newmain; newmain = newmain->next) {
6153     if (newmain->curlib) {
6154       if (BLI_path_cmp(newmain->curlib->filepath_abs, lib->filepath_abs) == 0) {
6155         blo_reportf_wrap(fd->reports,
6156                          RPT_WARNING,
6157                          TIP_("Library '%s', '%s' had multiple instances, save and reload!"),
6158                          lib->filepath,
6159                          lib->filepath_abs);
6160 
6161         change_link_placeholder_to_real_ID_pointer(fd->mainlist, fd, lib, newmain->curlib);
6162         /*              change_link_placeholder_to_real_ID_pointer_fd(fd, lib, newmain->curlib); */
6163 
6164         BLI_remlink(&main->libraries, lib);
6165         MEM_freeN(lib);
6166 
6167         /* Now, since Blender always expect **latest** Main pointer from fd->mainlist
6168          * to be the active library Main pointer,
6169          * where to add all non-library data-blocks found in file next, we have to switch that
6170          * 'dupli' found Main to latest position in the list!
6171          * Otherwise, you get weird disappearing linked data on a rather inconsistent basis.
6172          * See also T53977 for reproducible case. */
6173         BLI_remlink(fd->mainlist, newmain);
6174         BLI_addtail(fd->mainlist, newmain);
6175 
6176         return;
6177       }
6178     }
6179   }
6180 
6181   /* Make sure we have full path in lib->filepath_abs */
6182   BLI_strncpy(lib->filepath_abs, lib->filepath, sizeof(lib->filepath));
6183   BLI_path_normalize(fd->relabase, lib->filepath_abs);
6184 
6185   //  printf("direct_link_library: filepath %s\n", lib->filepath);
6186   //  printf("direct_link_library: filepath_abs %s\n", lib->filepath_abs);
6187 
6188   BlendDataReader reader = {fd};
6189   BKE_packedfile_blend_read(&reader, &lib->packedfile);
6190 
6191   /* new main */
6192   newmain = BKE_main_new();
6193   BLI_addtail(fd->mainlist, newmain);
6194   newmain->curlib = lib;
6195 
6196   lib->parent = NULL;
6197 
6198   id_us_ensure_real(&lib->id);
6199 }
6200 
lib_link_library(BlendLibReader * UNUSED (reader),Library * UNUSED (lib))6201 static void lib_link_library(BlendLibReader *UNUSED(reader), Library *UNUSED(lib))
6202 {
6203 }
6204 
6205 /* Always call this once you have loaded new library data to set the relative paths correctly
6206  * in relation to the blend file. */
fix_relpaths_library(const char * basepath,Main * main)6207 static void fix_relpaths_library(const char *basepath, Main *main)
6208 {
6209   /* BLO_read_from_memory uses a blank filename */
6210   if (basepath == NULL || basepath[0] == '\0') {
6211     LISTBASE_FOREACH (Library *, lib, &main->libraries) {
6212       /* when loading a linked lib into a file which has not been saved,
6213        * there is nothing we can be relative to, so instead we need to make
6214        * it absolute. This can happen when appending an object with a relative
6215        * link into an unsaved blend file. See T27405.
6216        * The remap relative option will make it relative again on save - campbell */
6217       if (BLI_path_is_rel(lib->filepath)) {
6218         BLI_strncpy(lib->filepath, lib->filepath_abs, sizeof(lib->filepath));
6219       }
6220     }
6221   }
6222   else {
6223     LISTBASE_FOREACH (Library *, lib, &main->libraries) {
6224       /* Libraries store both relative and abs paths, recreate relative paths,
6225        * relative to the blend file since indirectly linked libs will be
6226        * relative to their direct linked library. */
6227       if (BLI_path_is_rel(lib->filepath)) { /* if this is relative to begin with? */
6228         BLI_strncpy(lib->filepath, lib->filepath_abs, sizeof(lib->filepath));
6229         BLI_path_rel(lib->filepath, basepath);
6230       }
6231     }
6232   }
6233 }
6234 
6235 /** \} */
6236 
6237 /* -------------------------------------------------------------------- */
6238 /** \name Read Library Data Block
6239  * \{ */
6240 
create_placeholder(Main * mainvar,const short idcode,const char * idname,const int tag)6241 static ID *create_placeholder(Main *mainvar, const short idcode, const char *idname, const int tag)
6242 {
6243   ListBase *lb = which_libbase(mainvar, idcode);
6244   ID *ph_id = BKE_libblock_alloc_notest(idcode);
6245 
6246   *((short *)ph_id->name) = idcode;
6247   BLI_strncpy(ph_id->name + 2, idname, sizeof(ph_id->name) - 2);
6248   BKE_libblock_init_empty(ph_id);
6249   ph_id->lib = mainvar->curlib;
6250   ph_id->tag = tag | LIB_TAG_MISSING;
6251   ph_id->us = ID_FAKE_USERS(ph_id);
6252   ph_id->icon_id = 0;
6253 
6254   BLI_addtail(lb, ph_id);
6255   id_sort_by_name(lb, ph_id, NULL);
6256 
6257   BKE_lib_libblock_session_uuid_ensure(ph_id);
6258 
6259   return ph_id;
6260 }
6261 
placeholders_ensure_valid(Main * bmain)6262 static void placeholders_ensure_valid(Main *bmain)
6263 {
6264   /* Placeholder ObData IDs won't have any material, we have to update their objects for that,
6265    * otherwise the inconsistency between both will lead to crashes (especially in Eevee?). */
6266   LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
6267     ID *obdata = ob->data;
6268     if (obdata != NULL && obdata->tag & LIB_TAG_MISSING) {
6269       BKE_object_materials_test(bmain, ob, obdata);
6270     }
6271   }
6272 }
6273 
dataname(short id_code)6274 static const char *dataname(short id_code)
6275 {
6276   switch ((ID_Type)id_code) {
6277     case ID_OB:
6278       return "Data from OB";
6279     case ID_ME:
6280       return "Data from ME";
6281     case ID_IP:
6282       return "Data from IP";
6283     case ID_SCE:
6284       return "Data from SCE";
6285     case ID_MA:
6286       return "Data from MA";
6287     case ID_TE:
6288       return "Data from TE";
6289     case ID_CU:
6290       return "Data from CU";
6291     case ID_GR:
6292       return "Data from GR";
6293     case ID_AR:
6294       return "Data from AR";
6295     case ID_AC:
6296       return "Data from AC";
6297     case ID_LI:
6298       return "Data from LI";
6299     case ID_MB:
6300       return "Data from MB";
6301     case ID_IM:
6302       return "Data from IM";
6303     case ID_LT:
6304       return "Data from LT";
6305     case ID_LA:
6306       return "Data from LA";
6307     case ID_CA:
6308       return "Data from CA";
6309     case ID_KE:
6310       return "Data from KE";
6311     case ID_WO:
6312       return "Data from WO";
6313     case ID_SCR:
6314       return "Data from SCR";
6315     case ID_VF:
6316       return "Data from VF";
6317     case ID_TXT:
6318       return "Data from TXT";
6319     case ID_SPK:
6320       return "Data from SPK";
6321     case ID_LP:
6322       return "Data from LP";
6323     case ID_SO:
6324       return "Data from SO";
6325     case ID_NT:
6326       return "Data from NT";
6327     case ID_BR:
6328       return "Data from BR";
6329     case ID_PA:
6330       return "Data from PA";
6331     case ID_PAL:
6332       return "Data from PAL";
6333     case ID_PC:
6334       return "Data from PCRV";
6335     case ID_GD:
6336       return "Data from GD";
6337     case ID_WM:
6338       return "Data from WM";
6339     case ID_MC:
6340       return "Data from MC";
6341     case ID_MSK:
6342       return "Data from MSK";
6343     case ID_LS:
6344       return "Data from LS";
6345     case ID_CF:
6346       return "Data from CF";
6347     case ID_WS:
6348       return "Data from WS";
6349     case ID_HA:
6350       return "Data from HA";
6351     case ID_PT:
6352       return "Data from PT";
6353     case ID_VO:
6354       return "Data from VO";
6355     case ID_SIM:
6356       return "Data from SIM";
6357   }
6358   return "Data from Lib Block";
6359 }
6360 
direct_link_id(FileData * fd,Main * main,const int tag,ID * id,ID * id_old)6361 static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *id_old)
6362 {
6363   BlendDataReader reader = {fd};
6364 
6365   /* Read part of datablock that is common between real and embedded datablocks. */
6366   direct_link_id_common(&reader, main->curlib, id, id_old, tag);
6367 
6368   if (tag & LIB_TAG_ID_LINK_PLACEHOLDER) {
6369     /* For placeholder we only need to set the tag, no further data to read. */
6370     id->tag = tag;
6371     return true;
6372   }
6373 
6374   const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
6375   if (id_type->blend_read_data != NULL) {
6376     id_type->blend_read_data(&reader, id);
6377   }
6378 
6379   /* XXX Very weakly handled currently, see comment in read_libblock() before trying to
6380    * use it for anything new. */
6381   bool success = true;
6382 
6383   switch (GS(id->name)) {
6384     case ID_WM:
6385       direct_link_windowmanager(&reader, (wmWindowManager *)id);
6386       break;
6387     case ID_SCR:
6388       success = direct_link_screen(&reader, (bScreen *)id);
6389       break;
6390     case ID_SCE:
6391       direct_link_scene(&reader, (Scene *)id);
6392       break;
6393     case ID_OB:
6394       direct_link_object(&reader, (Object *)id);
6395       break;
6396     case ID_IP:
6397       direct_link_ipo(&reader, (Ipo *)id);
6398       break;
6399     case ID_LI:
6400       direct_link_library(fd, (Library *)id, main);
6401       break;
6402     case ID_GR:
6403       direct_link_collection(&reader, (Collection *)id);
6404       break;
6405     case ID_PA:
6406       direct_link_particlesettings(&reader, (ParticleSettings *)id);
6407       break;
6408     case ID_WS:
6409       direct_link_workspace(&reader, (WorkSpace *)id);
6410       break;
6411     case ID_ME:
6412     case ID_LT:
6413     case ID_AC:
6414     case ID_NT:
6415     case ID_LS:
6416     case ID_TXT:
6417     case ID_VF:
6418     case ID_MC:
6419     case ID_PAL:
6420     case ID_PC:
6421     case ID_BR:
6422     case ID_IM:
6423     case ID_LA:
6424     case ID_MA:
6425     case ID_MB:
6426     case ID_CU:
6427     case ID_CA:
6428     case ID_WO:
6429     case ID_MSK:
6430     case ID_SPK:
6431     case ID_AR:
6432     case ID_LP:
6433     case ID_KE:
6434     case ID_TE:
6435     case ID_GD:
6436     case ID_HA:
6437     case ID_PT:
6438     case ID_VO:
6439     case ID_SIM:
6440     case ID_SO:
6441     case ID_CF:
6442       /* Do nothing. Handled by IDTypeInfo callback. */
6443       break;
6444   }
6445 
6446   /* try to restore (when undoing) or clear ID's cache pointers. */
6447   if (id_type->foreach_cache != NULL) {
6448     BKE_idtype_id_foreach_cache(
6449         id, blo_cache_storage_entry_restore_in_new, reader.fd->cache_storage);
6450   }
6451 
6452   return success;
6453 }
6454 
6455 /* Read all data associated with a datablock into datamap. */
read_data_into_datamap(FileData * fd,BHead * bhead,const char * allocname)6456 static BHead *read_data_into_datamap(FileData *fd, BHead *bhead, const char *allocname)
6457 {
6458   bhead = blo_bhead_next(fd, bhead);
6459 
6460   while (bhead && bhead->code == DATA) {
6461     /* The code below is useful for debugging leaks in data read from the blend file.
6462      * Without this the messages only tell us what ID-type the memory came from,
6463      * eg: `Data from OB len 64`, see #dataname.
6464      * With the code below we get the struct-name to help tracking down the leak.
6465      * This is kept disabled as the #malloc for the text always leaks memory. */
6466 #if 0
6467     {
6468       const short *sp = fd->filesdna->structs[bhead->SDNAnr];
6469       allocname = fd->filesdna->types[sp[0]];
6470       size_t allocname_size = strlen(allocname) + 1;
6471       char *allocname_buf = malloc(allocname_size);
6472       memcpy(allocname_buf, allocname, allocname_size);
6473       allocname = allocname_buf;
6474     }
6475 #endif
6476 
6477     void *data = read_struct(fd, bhead, allocname);
6478     if (data) {
6479       oldnewmap_insert(fd->datamap, bhead->old, data, 0);
6480     }
6481 
6482     bhead = blo_bhead_next(fd, bhead);
6483   }
6484 
6485   return bhead;
6486 }
6487 
6488 /* Verify if the datablock and all associated data is identical. */
read_libblock_is_identical(FileData * fd,BHead * bhead)6489 static bool read_libblock_is_identical(FileData *fd, BHead *bhead)
6490 {
6491   /* Test ID itself. */
6492   if (bhead->len && !BHEADN_FROM_BHEAD(bhead)->is_memchunk_identical) {
6493     return false;
6494   }
6495 
6496   /* Test any other data that is part of ID (logic must match read_data_into_datamap). */
6497   bhead = blo_bhead_next(fd, bhead);
6498 
6499   while (bhead && bhead->code == DATA) {
6500     if (bhead->len && !BHEADN_FROM_BHEAD(bhead)->is_memchunk_identical) {
6501       return false;
6502     }
6503 
6504     bhead = blo_bhead_next(fd, bhead);
6505   }
6506 
6507   return true;
6508 }
6509 
6510 /* For undo, restore matching library datablock from the old main. */
read_libblock_undo_restore_library(FileData * fd,Main * main,const ID * id)6511 static bool read_libblock_undo_restore_library(FileData *fd, Main *main, const ID *id)
6512 {
6513   /* In undo case, most libs and linked data should be kept as is from previous state
6514    * (see BLO_read_from_memfile).
6515    * However, some needed by the snapshot being read may have been removed in previous one,
6516    * and would go missing.
6517    * This leads e.g. to disappearing objects in some undo/redo case, see T34446.
6518    * That means we have to carefully check whether current lib or
6519    * libdata already exits in old main, if it does we merely copy it over into new main area,
6520    * otherwise we have to do a full read of that bhead... */
6521   DEBUG_PRINTF("UNDO: restore library %s\n", id->name);
6522 
6523   Main *libmain = fd->old_mainlist->first;
6524   /* Skip oldmain itself... */
6525   for (libmain = libmain->next; libmain; libmain = libmain->next) {
6526     DEBUG_PRINTF("  compare with %s -> ", libmain->curlib ? libmain->curlib->id.name : "<NULL>");
6527     if (libmain->curlib && STREQ(id->name, libmain->curlib->id.name)) {
6528       Main *oldmain = fd->old_mainlist->first;
6529       DEBUG_PRINTF("match!\n");
6530       /* In case of a library, we need to re-add its main to fd->mainlist,
6531        * because if we have later a missing ID_LINK_PLACEHOLDER,
6532        * we need to get the correct lib it is linked to!
6533        * Order is crucial, we cannot bulk-add it in BLO_read_from_memfile()
6534        * like it used to be. */
6535       BLI_remlink(fd->old_mainlist, libmain);
6536       BLI_remlink_safe(&oldmain->libraries, libmain->curlib);
6537       BLI_addtail(fd->mainlist, libmain);
6538       BLI_addtail(&main->libraries, libmain->curlib);
6539       return true;
6540     }
6541     DEBUG_PRINTF("no match\n");
6542   }
6543 
6544   return false;
6545 }
6546 
6547 /* For undo, restore existing linked datablock from the old main. */
read_libblock_undo_restore_linked(FileData * fd,Main * main,const ID * id,BHead * bhead)6548 static bool read_libblock_undo_restore_linked(FileData *fd, Main *main, const ID *id, BHead *bhead)
6549 {
6550   DEBUG_PRINTF("UNDO: restore linked datablock %s\n", id->name);
6551   DEBUG_PRINTF("  from %s (%s): ",
6552                main->curlib ? main->curlib->id.name : "<NULL>",
6553                main->curlib ? main->curlib->filepath : "<NULL>");
6554 
6555   ID *id_old = BKE_libblock_find_name(main, GS(id->name), id->name + 2);
6556   if (id_old != NULL) {
6557     DEBUG_PRINTF("  found!\n");
6558     /* Even though we found our linked ID, there is no guarantee its address
6559      * is still the same. */
6560     if (id_old != bhead->old) {
6561       oldnewmap_insert(fd->libmap, bhead->old, id_old, GS(id_old->name));
6562     }
6563 
6564     /* No need to do anything else for ID_LINK_PLACEHOLDER, it's assumed
6565      * already present in its lib's main. */
6566     return true;
6567   }
6568 
6569   DEBUG_PRINTF("  not found\n");
6570   return false;
6571 }
6572 
6573 /* For undo, restore unchanged datablock from old main. */
read_libblock_undo_restore_identical(FileData * fd,Main * main,const ID * UNUSED (id),ID * id_old,const int tag)6574 static void read_libblock_undo_restore_identical(
6575     FileData *fd, Main *main, const ID *UNUSED(id), ID *id_old, const int tag)
6576 {
6577   BLI_assert((fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0);
6578   BLI_assert(id_old != NULL);
6579 
6580   /* Some tags need to be preserved here. */
6581   id_old->tag = tag | (id_old->tag & LIB_TAG_EXTRAUSER);
6582   id_old->lib = main->curlib;
6583   id_old->us = ID_FAKE_USERS(id_old);
6584   /* Do not reset id->icon_id here, memory allocated for it remains valid. */
6585   /* Needed because .blend may have been saved with crap value here... */
6586   id_old->newid = NULL;
6587   id_old->orig_id = NULL;
6588 
6589   const short idcode = GS(id_old->name);
6590   Main *old_bmain = fd->old_mainlist->first;
6591   ListBase *old_lb = which_libbase(old_bmain, idcode);
6592   ListBase *new_lb = which_libbase(main, idcode);
6593   BLI_remlink(old_lb, id_old);
6594   BLI_addtail(new_lb, id_old);
6595 
6596   /* Recalc flags, mostly these just remain as they are. */
6597   id_old->recalc |= direct_link_id_restore_recalc_exceptions(id_old);
6598   id_old->recalc_after_undo_push = 0;
6599 
6600   /* As usual, proxies require some special love...
6601    * In `blo_clear_proxy_pointers_from_lib()` we clear all `proxy_from` pointers to local IDs, for
6602    * undo. This is required since we do not re-read linked data in that case, so we also do not
6603    * re-'lib_link' their pointers.
6604    * Those `proxy_from` pointers are then re-defined properly when lib_linking the newly read local
6605    * object. However, in case of re-used data 'as-is', we never lib_link it again, so we have to
6606    * fix those backward pointers here. */
6607   if (GS(id_old->name) == ID_OB) {
6608     Object *ob = (Object *)id_old;
6609     if (ob->proxy != NULL) {
6610       ob->proxy->proxy_from = ob;
6611     }
6612     /* For undo we stay in object mode during undo presses, so keep editmode disabled for re-used
6613      * data-blocks too. */
6614     ob->mode &= ~OB_MODE_EDIT;
6615   }
6616 }
6617 
6618 /* For undo, store changed datablock at old address. */
read_libblock_undo_restore_at_old_address(FileData * fd,Main * main,ID * id,ID * id_old)6619 static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main, ID *id, ID *id_old)
6620 {
6621   /* During memfile undo, if an ID changed and we cannot directly re-use existing one from old
6622    * bmain, we do a full read of the new id from the memfile, and then fully swap its content
6623    * with the old id. This allows us to keep the same pointer even for modified data, which
6624    * helps reducing further detected changes by the depsgraph (since unchanged IDs remain fully
6625    * unchanged, even if they are using/pointing to a changed one). */
6626   BLI_assert((fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0);
6627   BLI_assert(id_old != NULL);
6628 
6629   const short idcode = GS(id->name);
6630 
6631   /* XXX 3DCursor (witch is UI data and as such should not be affected by undo) is stored in
6632    * Scene... So this requires some special handling, previously done in `blo_lib_link_restore()`,
6633    * but this cannot work anymore when we overwrite existing memory... */
6634   if (idcode == ID_SCE) {
6635     Scene *scene_old = (Scene *)id_old;
6636     Scene *scene = (Scene *)id;
6637     SWAP(View3DCursor, scene_old->cursor, scene->cursor);
6638   }
6639 
6640   Main *old_bmain = fd->old_mainlist->first;
6641   ListBase *old_lb = which_libbase(old_bmain, idcode);
6642   ListBase *new_lb = which_libbase(main, idcode);
6643   BLI_remlink(old_lb, id_old);
6644   BLI_remlink(new_lb, id);
6645 
6646   /* We do not need any remapping from this call here, since no ID pointer is valid in the data
6647    * currently (they are all pointing to old addresses, and need to go through `lib_link`
6648    * process). So we can pass NULL for the Main pointer parameter. */
6649   BKE_lib_id_swap_full(NULL, id, id_old);
6650 
6651   BLI_addtail(new_lb, id_old);
6652   BLI_addtail(old_lb, id);
6653 }
6654 
read_libblock_undo_restore(FileData * fd,Main * main,BHead * bhead,const int tag,ID ** r_id_old)6655 static bool read_libblock_undo_restore(
6656     FileData *fd, Main *main, BHead *bhead, const int tag, ID **r_id_old)
6657 {
6658   /* Get pointer to memory of new ID that we will be reading. */
6659   const ID *id = peek_struct_undo(fd, bhead);
6660   const short idcode = GS(id->name);
6661 
6662   if (bhead->code == ID_LI) {
6663     /* Restore library datablock. */
6664     if (read_libblock_undo_restore_library(fd, main, id)) {
6665       return true;
6666     }
6667   }
6668   else if (bhead->code == ID_LINK_PLACEHOLDER) {
6669     /* Restore linked datablock. */
6670     if (read_libblock_undo_restore_linked(fd, main, id, bhead)) {
6671       return true;
6672     }
6673   }
6674   else if (ELEM(idcode, ID_WM, ID_SCR, ID_WS)) {
6675     /* Skip reading any UI datablocks, existing ones are kept. We don't
6676      * support pointers from other datablocks to UI datablocks so those
6677      * we also don't put UI datablocks in fd->libmap. */
6678     return true;
6679   }
6680 
6681   /* Restore local datablocks. */
6682   DEBUG_PRINTF("UNDO: read %s (uuid %u) -> ", id->name, id->session_uuid);
6683 
6684   ID *id_old = NULL;
6685   const bool do_partial_undo = (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0;
6686   if (do_partial_undo && (bhead->code != ID_LINK_PLACEHOLDER)) {
6687     /* This code should only ever be reached for local data-blocks. */
6688     BLI_assert(main->curlib == NULL);
6689 
6690     /* Find the 'current' existing ID we want to reuse instead of the one we
6691      * would read from the undo memfile. */
6692     BLI_assert(fd->old_idmap != NULL);
6693     id_old = BKE_main_idmap_lookup_uuid(fd->old_idmap, id->session_uuid);
6694   }
6695 
6696   if (id_old != NULL && read_libblock_is_identical(fd, bhead)) {
6697     /* Local datablock was unchanged, restore from the old main. */
6698     DEBUG_PRINTF("keep identical datablock\n");
6699 
6700     /* Do not add LIB_TAG_NEW here, this should not be needed/used in undo case anyway (as
6701      * this is only for do_version-like code), but for sake of consistency, and also because
6702      * it will tell us which ID is re-used from old Main, and which one is actually new. */
6703     /* Also do not add LIB_TAG_NEED_LINK, those IDs will never be re-liblinked, hence that tag will
6704      * never be cleared, leading to critical issue in link/append code. */
6705     const int id_tag = tag | LIB_TAG_UNDO_OLD_ID_REUSED;
6706     read_libblock_undo_restore_identical(fd, main, id, id_old, id_tag);
6707 
6708     /* Insert into library map for lookup by newly read datablocks (with pointer value bhead->old).
6709      * Note that existing datablocks in memory (which pointer value would be id_old) are not
6710      * remapped anymore, so no need to store this info here. */
6711     oldnewmap_insert(fd->libmap, bhead->old, id_old, bhead->code);
6712 
6713     *r_id_old = id_old;
6714     return true;
6715   }
6716   if (id_old != NULL) {
6717     /* Local datablock was changed. Restore at the address of the old datablock. */
6718     DEBUG_PRINTF("read to old existing address\n");
6719     *r_id_old = id_old;
6720     return false;
6721   }
6722 
6723   /* Local datablock does not exist in the undo step, so read from scratch. */
6724   DEBUG_PRINTF("read at new address\n");
6725   return false;
6726 }
6727 
6728 /* This routine reads a datablock and its direct data, and advances bhead to
6729  * the next datablock. For library linked datablocks, only a placeholder will
6730  * be generated, to be replaced in read_library_linked_ids.
6731  *
6732  * When reading for undo, libraries, linked datablocks and unchanged datablocks
6733  * will be restored from the old database. Only new or changed datablocks will
6734  * actually be read. */
read_libblock(FileData * fd,Main * main,BHead * bhead,const int tag,const bool placeholder_set_indirect_extern,ID ** r_id)6735 static BHead *read_libblock(FileData *fd,
6736                             Main *main,
6737                             BHead *bhead,
6738                             const int tag,
6739                             const bool placeholder_set_indirect_extern,
6740                             ID **r_id)
6741 {
6742   /* First attempt to restore existing datablocks for undo.
6743    * When datablocks are changed but still exist, we restore them at the old
6744    * address and inherit recalc flags for the dependency graph. */
6745   ID *id_old = NULL;
6746   if (fd->memfile != NULL) {
6747     if (read_libblock_undo_restore(fd, main, bhead, tag, &id_old)) {
6748       if (r_id) {
6749         *r_id = id_old;
6750       }
6751       return blo_bhead_next(fd, bhead);
6752     }
6753   }
6754 
6755   /* Read libblock struct. */
6756   ID *id = read_struct(fd, bhead, "lib block");
6757   if (id == NULL) {
6758     if (r_id) {
6759       *r_id = NULL;
6760     }
6761     return blo_bhead_next(fd, bhead);
6762   }
6763 
6764   /* Determine ID type and add to main database list. */
6765   const short idcode = GS(id->name);
6766   ListBase *lb = which_libbase(main, idcode);
6767   if (lb == NULL) {
6768     /* Unknown ID type. */
6769     printf("%s: unknown id code '%c%c'\n", __func__, (idcode & 0xff), (idcode >> 8));
6770     MEM_freeN(id);
6771     if (r_id) {
6772       *r_id = NULL;
6773     }
6774     return blo_bhead_next(fd, bhead);
6775   }
6776 
6777   /* NOTE: id must be added to the list before direct_link_id(), since
6778    * direct_link_library() may remove it from there in case of duplicates. */
6779   BLI_addtail(lb, id);
6780 
6781   /* Insert into library map for lookup by newly read datablocks (with pointer value bhead->old).
6782    * Note that existing datablocks in memory (which pointer value would be id_old) are not remapped
6783    * remapped anymore, so no need to store this info here. */
6784   ID *id_target = id_old ? id_old : id;
6785   oldnewmap_insert(fd->libmap, bhead->old, id_target, bhead->code);
6786 
6787   if (r_id) {
6788     *r_id = id_target;
6789   }
6790 
6791   /* Set tag for new datablock to indicate lib linking and versioning needs
6792    * to be done still. */
6793   int id_tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_NEW;
6794 
6795   if (bhead->code == ID_LINK_PLACEHOLDER) {
6796     /* Read placeholder for linked datablock. */
6797     id_tag |= LIB_TAG_ID_LINK_PLACEHOLDER;
6798 
6799     if (placeholder_set_indirect_extern) {
6800       if (id->flag & LIB_INDIRECT_WEAK_LINK) {
6801         id_tag |= LIB_TAG_INDIRECT;
6802       }
6803       else {
6804         id_tag |= LIB_TAG_EXTERN;
6805       }
6806     }
6807 
6808     direct_link_id(fd, main, id_tag, id, id_old);
6809     return blo_bhead_next(fd, bhead);
6810   }
6811 
6812   /* Read datablock contents.
6813    * Use convenient malloc name for debugging and better memory link prints. */
6814   const char *allocname = dataname(idcode);
6815   bhead = read_data_into_datamap(fd, bhead, allocname);
6816   const bool success = direct_link_id(fd, main, id_tag, id, id_old);
6817   oldnewmap_clear(fd->datamap);
6818 
6819   if (!success) {
6820     /* XXX This is probably working OK currently given the very limited scope of that flag.
6821      * However, it is absolutely **not** handled correctly: it is freeing an ID pointer that has
6822      * been added to the fd->libmap mapping, which in theory could lead to nice crashes...
6823      * This should be properly solved at some point. */
6824     BKE_id_free(main, id);
6825     if (r_id != NULL) {
6826       *r_id = NULL;
6827     }
6828   }
6829   else if (id_old) {
6830     /* For undo, store contents read into id at id_old. */
6831     read_libblock_undo_restore_at_old_address(fd, main, id, id_old);
6832   }
6833 
6834   return bhead;
6835 }
6836 
6837 /** \} */
6838 
6839 /* -------------------------------------------------------------------- */
6840 /** \name Read Global Data
6841  * \{ */
6842 
6843 /* note, this has to be kept for reading older files... */
6844 /* also version info is written here */
read_global(BlendFileData * bfd,FileData * fd,BHead * bhead)6845 static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
6846 {
6847   FileGlobal *fg = read_struct(fd, bhead, "Global");
6848 
6849   /* copy to bfd handle */
6850   bfd->main->subversionfile = fg->subversion;
6851   bfd->main->minversionfile = fg->minversion;
6852   bfd->main->minsubversionfile = fg->minsubversion;
6853   bfd->main->build_commit_timestamp = fg->build_commit_timestamp;
6854   BLI_strncpy(bfd->main->build_hash, fg->build_hash, sizeof(bfd->main->build_hash));
6855 
6856   bfd->fileflags = fg->fileflags;
6857   bfd->globalf = fg->globalf;
6858   BLI_strncpy(bfd->filename, fg->filename, sizeof(bfd->filename));
6859 
6860   /* Error in 2.65 and older: main->name was not set if you save from startup
6861    * (not after loading file). */
6862   if (bfd->filename[0] == 0) {
6863     if (fd->fileversion < 265 || (fd->fileversion == 265 && fg->subversion < 1)) {
6864       if ((G.fileflags & G_FILE_RECOVER) == 0) {
6865         BLI_strncpy(bfd->filename, BKE_main_blendfile_path(bfd->main), sizeof(bfd->filename));
6866       }
6867     }
6868 
6869     /* early 2.50 version patch - filename not in FileGlobal struct at all */
6870     if (fd->fileversion <= 250) {
6871       BLI_strncpy(bfd->filename, BKE_main_blendfile_path(bfd->main), sizeof(bfd->filename));
6872     }
6873   }
6874 
6875   if (G.fileflags & G_FILE_RECOVER) {
6876     BLI_strncpy(fd->relabase, fg->filename, sizeof(fd->relabase));
6877   }
6878 
6879   bfd->curscreen = fg->curscreen;
6880   bfd->curscene = fg->curscene;
6881   bfd->cur_view_layer = fg->cur_view_layer;
6882 
6883   MEM_freeN(fg);
6884 
6885   fd->globalf = bfd->globalf;
6886   fd->fileflags = bfd->fileflags;
6887 
6888   return blo_bhead_next(fd, bhead);
6889 }
6890 
6891 /* note, this has to be kept for reading older files... */
link_global(FileData * fd,BlendFileData * bfd)6892 static void link_global(FileData *fd, BlendFileData *bfd)
6893 {
6894   bfd->cur_view_layer = blo_read_get_new_globaldata_address(fd, bfd->cur_view_layer);
6895   bfd->curscreen = newlibadr(fd, NULL, bfd->curscreen);
6896   bfd->curscene = newlibadr(fd, NULL, bfd->curscene);
6897   /* this happens in files older than 2.35 */
6898   if (bfd->curscene == NULL) {
6899     if (bfd->curscreen) {
6900       bfd->curscene = bfd->curscreen->scene;
6901     }
6902   }
6903 }
6904 
6905 /** \} */
6906 
6907 /* -------------------------------------------------------------------- */
6908 /** \name Versioning
6909  * \{ */
6910 
do_versions_userdef(FileData * UNUSED (fd),BlendFileData * bfd)6911 static void do_versions_userdef(FileData *UNUSED(fd), BlendFileData *bfd)
6912 {
6913   UserDef *user = bfd->user;
6914 
6915   if (user == NULL) {
6916     return;
6917   }
6918 
6919   blo_do_versions_userdef(user);
6920 }
6921 
do_versions(FileData * fd,Library * lib,Main * main)6922 static void do_versions(FileData *fd, Library *lib, Main *main)
6923 {
6924   /* WATCH IT!!!: pointers from libdata have not been converted */
6925 
6926   /* Don't allow versioning to create new data-blocks. */
6927   main->is_locked_for_linking = true;
6928 
6929   if (G.debug & G_DEBUG) {
6930     char build_commit_datetime[32];
6931     time_t temp_time = main->build_commit_timestamp;
6932     struct tm *tm = (temp_time) ? gmtime(&temp_time) : NULL;
6933     if (LIKELY(tm)) {
6934       strftime(build_commit_datetime, sizeof(build_commit_datetime), "%Y-%m-%d %H:%M", tm);
6935     }
6936     else {
6937       BLI_strncpy(build_commit_datetime, "unknown", sizeof(build_commit_datetime));
6938     }
6939 
6940     printf("read file %s\n  Version %d sub %d date %s hash %s\n",
6941            fd->relabase,
6942            main->versionfile,
6943            main->subversionfile,
6944            build_commit_datetime,
6945            main->build_hash);
6946   }
6947 
6948   blo_do_versions_pre250(fd, lib, main);
6949   blo_do_versions_250(fd, lib, main);
6950   blo_do_versions_260(fd, lib, main);
6951   blo_do_versions_270(fd, lib, main);
6952   blo_do_versions_280(fd, lib, main);
6953   blo_do_versions_290(fd, lib, main);
6954   blo_do_versions_cycles(fd, lib, main);
6955 
6956   /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
6957   /* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
6958 
6959   /* don't forget to set version number in BKE_blender_version.h! */
6960 
6961   main->is_locked_for_linking = false;
6962 }
6963 
do_versions_after_linking(Main * main,ReportList * reports)6964 static void do_versions_after_linking(Main *main, ReportList *reports)
6965 {
6966   //  printf("%s for %s (%s), %d.%d\n", __func__, main->curlib ? main->curlib->filepath :
6967   //         main->name, main->curlib ? "LIB" : "MAIN", main->versionfile, main->subversionfile);
6968 
6969   /* Don't allow versioning to create new data-blocks. */
6970   main->is_locked_for_linking = true;
6971 
6972   do_versions_after_linking_250(main);
6973   do_versions_after_linking_260(main);
6974   do_versions_after_linking_270(main);
6975   do_versions_after_linking_280(main, reports);
6976   do_versions_after_linking_290(main, reports);
6977   do_versions_after_linking_cycles(main);
6978 
6979   main->is_locked_for_linking = false;
6980 }
6981 
6982 /** \} */
6983 
6984 /* -------------------------------------------------------------------- */
6985 /** \name Read Library Data Block (all)
6986  * \{ */
6987 
lib_link_all(FileData * fd,Main * bmain)6988 static void lib_link_all(FileData *fd, Main *bmain)
6989 {
6990   const bool do_partial_undo = (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0;
6991 
6992   BlendLibReader reader = {fd, bmain};
6993 
6994   ID *id;
6995   FOREACH_MAIN_ID_BEGIN (bmain, id) {
6996     if ((id->tag & LIB_TAG_NEED_LINK) == 0) {
6997       /* This ID does not need liblink, just skip to next one. */
6998       continue;
6999     }
7000 
7001     if (fd->memfile != NULL && GS(id->name) == ID_WM) {
7002       /* No load UI for undo memfiles.
7003        * Only WM currently, SCR needs it still (see below), and so does WS? */
7004       continue;
7005     }
7006 
7007     if (fd->memfile != NULL && do_partial_undo && (id->tag & LIB_TAG_UNDO_OLD_ID_REUSED) != 0) {
7008       /* This ID has been re-used from 'old' bmain. Since it was therefore unchanged across
7009        * current undo step, and old IDs re-use their old memory address, we do not need to liblink
7010        * it at all. */
7011       continue;
7012     }
7013 
7014     lib_link_id(&reader, id);
7015 
7016     const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
7017     if (id_type->blend_read_lib != NULL) {
7018       id_type->blend_read_lib(&reader, id);
7019     }
7020 
7021     /* Note: ID types are processed in reverse order as defined by INDEX_ID_XXX enums in DNA_ID.h.
7022      * This ensures handling of most dependencies in proper order, as elsewhere in code.
7023      * Please keep order of entries in that switch matching that order, it's easier to quickly see
7024      * whether something is wrong then. */
7025     switch (GS(id->name)) {
7026       case ID_WM:
7027         lib_link_windowmanager(&reader, (wmWindowManager *)id);
7028         break;
7029       case ID_WS:
7030         /* Could we skip WS in undo case? */
7031         lib_link_workspaces(&reader, (WorkSpace *)id);
7032         break;
7033       case ID_SCE:
7034         lib_link_scene(&reader, (Scene *)id);
7035         break;
7036       case ID_OB:
7037         lib_link_object(&reader, (Object *)id);
7038         break;
7039       case ID_SCR:
7040         /* DO NOT skip screens here, 3D viewport may contains pointers
7041          * to other ID data (like #View3D.ob_center)! See T41411. */
7042         lib_link_screen(&reader, (bScreen *)id);
7043         break;
7044       case ID_PA:
7045         lib_link_particlesettings(&reader, (ParticleSettings *)id);
7046         break;
7047       case ID_GR:
7048         lib_link_collection(&reader, (Collection *)id);
7049         break;
7050       case ID_IP:
7051         /* XXX deprecated... still needs to be maintained for version patches still. */
7052         lib_link_ipo(&reader, (Ipo *)id);
7053         break;
7054       case ID_LI:
7055         lib_link_library(&reader, (Library *)id); /* Only init users. */
7056         break;
7057       case ID_ME:
7058       case ID_LT:
7059       case ID_AC:
7060       case ID_NT:
7061       case ID_LS:
7062       case ID_TXT:
7063       case ID_VF:
7064       case ID_MC:
7065       case ID_PAL:
7066       case ID_PC:
7067       case ID_BR:
7068       case ID_IM:
7069       case ID_LA:
7070       case ID_MA:
7071       case ID_MB:
7072       case ID_CU:
7073       case ID_CA:
7074       case ID_WO:
7075       case ID_MSK:
7076       case ID_SPK:
7077       case ID_AR:
7078       case ID_LP:
7079       case ID_KE:
7080       case ID_TE:
7081       case ID_GD:
7082       case ID_HA:
7083       case ID_PT:
7084       case ID_VO:
7085       case ID_SIM:
7086       case ID_SO:
7087       case ID_CF:
7088         /* Do nothing. Handled by IDTypeInfo callback. */
7089         break;
7090     }
7091 
7092     id->tag &= ~LIB_TAG_NEED_LINK;
7093   }
7094   FOREACH_MAIN_ID_END;
7095 
7096   /* Check for possible cycles in scenes' 'set' background property. */
7097   lib_link_scenes_check_set(bmain);
7098 
7099   /* We could integrate that to mesh/curve/lattice lib_link, but this is really cheap process,
7100    * so simpler to just use it directly in this single call. */
7101   BLO_main_validate_shapekeys(bmain, NULL);
7102 
7103   /* We have to rebuild that runtime information *after* all data-blocks have been properly linked.
7104    */
7105   BKE_main_collections_parent_relations_rebuild(bmain);
7106 
7107 #ifndef NDEBUG
7108   /* Double check we do not have any 'need link' tag remaining, this should never be the case once
7109    * this function has run. */
7110   FOREACH_MAIN_ID_BEGIN (bmain, id) {
7111     BLI_assert((id->tag & LIB_TAG_NEED_LINK) == 0);
7112   }
7113   FOREACH_MAIN_ID_END;
7114 #endif
7115 }
7116 
7117 /** \} */
7118 
7119 /* -------------------------------------------------------------------- */
7120 /** \name Read User Preferences
7121  * \{ */
7122 
direct_link_keymapitem(BlendDataReader * reader,wmKeyMapItem * kmi)7123 static void direct_link_keymapitem(BlendDataReader *reader, wmKeyMapItem *kmi)
7124 {
7125   BLO_read_data_address(reader, &kmi->properties);
7126   IDP_BlendDataRead(reader, &kmi->properties);
7127   kmi->ptr = NULL;
7128   kmi->flag &= ~KMI_UPDATE;
7129 }
7130 
read_userdef(BlendFileData * bfd,FileData * fd,BHead * bhead)7131 static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
7132 {
7133   UserDef *user;
7134   bfd->user = user = read_struct(fd, bhead, "user def");
7135 
7136   /* User struct has separate do-version handling */
7137   user->versionfile = bfd->main->versionfile;
7138   user->subversionfile = bfd->main->subversionfile;
7139 
7140   /* read all data into fd->datamap */
7141   bhead = read_data_into_datamap(fd, bhead, "user def");
7142 
7143   BlendDataReader reader_ = {fd};
7144   BlendDataReader *reader = &reader_;
7145 
7146   BLO_read_list(reader, &user->themes);
7147   BLO_read_list(reader, &user->user_keymaps);
7148   BLO_read_list(reader, &user->user_keyconfig_prefs);
7149   BLO_read_list(reader, &user->user_menus);
7150   BLO_read_list(reader, &user->addons);
7151   BLO_read_list(reader, &user->autoexec_paths);
7152 
7153   LISTBASE_FOREACH (wmKeyMap *, keymap, &user->user_keymaps) {
7154     keymap->modal_items = NULL;
7155     keymap->poll = NULL;
7156     keymap->flag &= ~KEYMAP_UPDATE;
7157 
7158     BLO_read_list(reader, &keymap->diff_items);
7159     BLO_read_list(reader, &keymap->items);
7160 
7161     LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &keymap->diff_items) {
7162       BLO_read_data_address(reader, &kmdi->remove_item);
7163       BLO_read_data_address(reader, &kmdi->add_item);
7164 
7165       if (kmdi->remove_item) {
7166         direct_link_keymapitem(reader, kmdi->remove_item);
7167       }
7168       if (kmdi->add_item) {
7169         direct_link_keymapitem(reader, kmdi->add_item);
7170       }
7171     }
7172 
7173     LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
7174       direct_link_keymapitem(reader, kmi);
7175     }
7176   }
7177 
7178   LISTBASE_FOREACH (wmKeyConfigPref *, kpt, &user->user_keyconfig_prefs) {
7179     BLO_read_data_address(reader, &kpt->prop);
7180     IDP_BlendDataRead(reader, &kpt->prop);
7181   }
7182 
7183   LISTBASE_FOREACH (bUserMenu *, um, &user->user_menus) {
7184     BLO_read_list(reader, &um->items);
7185     LISTBASE_FOREACH (bUserMenuItem *, umi, &um->items) {
7186       if (umi->type == USER_MENU_TYPE_OPERATOR) {
7187         bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
7188         BLO_read_data_address(reader, &umi_op->prop);
7189         IDP_BlendDataRead(reader, &umi_op->prop);
7190       }
7191     }
7192   }
7193 
7194   LISTBASE_FOREACH (bAddon *, addon, &user->addons) {
7195     BLO_read_data_address(reader, &addon->prop);
7196     IDP_BlendDataRead(reader, &addon->prop);
7197   }
7198 
7199   /* XXX */
7200   user->uifonts.first = user->uifonts.last = NULL;
7201 
7202   BLO_read_list(reader, &user->uistyles);
7203 
7204   /* Don't read the active app template, use the default one. */
7205   user->app_template[0] = '\0';
7206 
7207   /* Clear runtime data. */
7208   user->runtime.is_dirty = false;
7209   user->edit_studio_light = 0;
7210 
7211   /* free fd->datamap again */
7212   oldnewmap_clear(fd->datamap);
7213 
7214   return bhead;
7215 }
7216 
7217 /** \} */
7218 
7219 /* -------------------------------------------------------------------- */
7220 /** \name Read File (Internal)
7221  * \{ */
7222 
blo_read_file_internal(FileData * fd,const char * filepath)7223 BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
7224 {
7225   BHead *bhead = blo_bhead_first(fd);
7226   BlendFileData *bfd;
7227   ListBase mainlist = {NULL, NULL};
7228 
7229   if (fd->memfile != NULL) {
7230     DEBUG_PRINTF("\nUNDO: read step\n");
7231   }
7232 
7233   bfd = MEM_callocN(sizeof(BlendFileData), "blendfiledata");
7234 
7235   bfd->main = BKE_main_new();
7236   bfd->main->versionfile = fd->fileversion;
7237 
7238   bfd->type = BLENFILETYPE_BLEND;
7239 
7240   if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
7241     BLI_addtail(&mainlist, bfd->main);
7242     fd->mainlist = &mainlist;
7243     BLI_strncpy(bfd->main->name, filepath, sizeof(bfd->main->name));
7244   }
7245 
7246   if (G.background) {
7247     /* We only read & store .blend thumbnail in background mode
7248      * (because we cannot re-generate it, no OpenGL available).
7249      */
7250     const int *data = read_file_thumbnail(fd);
7251 
7252     if (data) {
7253       const int width = data[0];
7254       const int height = data[1];
7255       if (BLEN_THUMB_MEMSIZE_IS_VALID(width, height)) {
7256         const size_t sz = BLEN_THUMB_MEMSIZE(width, height);
7257         bfd->main->blen_thumb = MEM_mallocN(sz, __func__);
7258 
7259         BLI_assert((sz - sizeof(*bfd->main->blen_thumb)) ==
7260                    (BLEN_THUMB_MEMSIZE_FILE(width, height) - (sizeof(*data) * 2)));
7261         bfd->main->blen_thumb->width = width;
7262         bfd->main->blen_thumb->height = height;
7263         memcpy(bfd->main->blen_thumb->rect, &data[2], sz - sizeof(*bfd->main->blen_thumb));
7264       }
7265     }
7266   }
7267 
7268   while (bhead) {
7269     switch (bhead->code) {
7270       case DATA:
7271       case DNA1:
7272       case TEST: /* used as preview since 2.5x */
7273       case REND:
7274         bhead = blo_bhead_next(fd, bhead);
7275         break;
7276       case GLOB:
7277         bhead = read_global(bfd, fd, bhead);
7278         break;
7279       case USER:
7280         if (fd->skip_flags & BLO_READ_SKIP_USERDEF) {
7281           bhead = blo_bhead_next(fd, bhead);
7282         }
7283         else {
7284           bhead = read_userdef(bfd, fd, bhead);
7285         }
7286         break;
7287       case ENDB:
7288         bhead = NULL;
7289         break;
7290 
7291       case ID_LINK_PLACEHOLDER:
7292         if (fd->skip_flags & BLO_READ_SKIP_DATA) {
7293           bhead = blo_bhead_next(fd, bhead);
7294         }
7295         else {
7296           /* Add link placeholder to the main of the library it belongs to.
7297            * The library is the most recently loaded ID_LI block, according
7298            * to the file format definition. So we can use the entry at the
7299            * end of mainlist, added in direct_link_library. */
7300           Main *libmain = mainlist.last;
7301           bhead = read_libblock(fd, libmain, bhead, 0, true, NULL);
7302         }
7303         break;
7304         /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
7305       case ID_SCRN:
7306         bhead->code = ID_SCR;
7307         /* pass on to default */
7308         ATTR_FALLTHROUGH;
7309       default:
7310         if (fd->skip_flags & BLO_READ_SKIP_DATA) {
7311           bhead = blo_bhead_next(fd, bhead);
7312         }
7313         else {
7314           bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, false, NULL);
7315         }
7316     }
7317   }
7318 
7319   /* do before read_libraries, but skip undo case */
7320   if (fd->memfile == NULL) {
7321     if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
7322       do_versions(fd, NULL, bfd->main);
7323     }
7324 
7325     if ((fd->skip_flags & BLO_READ_SKIP_USERDEF) == 0) {
7326       do_versions_userdef(fd, bfd);
7327     }
7328   }
7329 
7330   if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
7331     read_libraries(fd, &mainlist);
7332 
7333     blo_join_main(&mainlist);
7334 
7335     lib_link_all(fd, bfd->main);
7336 
7337     /* Skip in undo case. */
7338     if (fd->memfile == NULL) {
7339       /* Note that we can't recompute user-counts at this point in undo case, we play too much with
7340        * IDs from different memory realms, and Main database is not in a fully valid state yet.
7341        */
7342       /* Some versioning code does expect some proper user-reference-counting, e.g. in conversion
7343        * from groups to collections... We could optimize out that first call when we are reading a
7344        * current version file, but again this is really not a bottle neck currently.
7345        * So not worth it. */
7346       BKE_main_id_refcount_recompute(bfd->main, false);
7347 
7348       /* Yep, second splitting... but this is a very cheap operation, so no big deal. */
7349       blo_split_main(&mainlist, bfd->main);
7350       LISTBASE_FOREACH (Main *, mainvar, &mainlist) {
7351         BLI_assert(mainvar->versionfile != 0);
7352         do_versions_after_linking(mainvar, fd->reports);
7353       }
7354       blo_join_main(&mainlist);
7355 
7356       /* And we have to compute those user-reference-counts again, as `do_versions_after_linking()`
7357        * does not always properly handle user counts, and/or that function does not take into
7358        * account old, deprecated data. */
7359       BKE_main_id_refcount_recompute(bfd->main, false);
7360 
7361       /* After all data has been read and versioned, uses LIB_TAG_NEW. */
7362       ntreeUpdateAllNew(bfd->main);
7363     }
7364 
7365     placeholders_ensure_valid(bfd->main);
7366 
7367     BKE_main_id_tag_all(bfd->main, LIB_TAG_NEW, false);
7368 
7369     /* Now that all our data-blocks are loaded,
7370      * we can re-generate overrides from their references. */
7371     if (fd->memfile == NULL) {
7372       /* Do not apply in undo case! */
7373       BKE_lib_override_library_main_update(bfd->main);
7374     }
7375 
7376     BKE_collections_after_lib_link(bfd->main);
7377 
7378     /* Make all relative paths, relative to the open blend file. */
7379     fix_relpaths_library(fd->relabase, bfd->main);
7380 
7381     link_global(fd, bfd); /* as last */
7382   }
7383 
7384   fd->mainlist = NULL; /* Safety, this is local variable, shall not be used afterward. */
7385 
7386   return bfd;
7387 }
7388 
7389 /** \} */
7390 
7391 /* -------------------------------------------------------------------- */
7392 /** \name Library Linking
7393  *
7394  * Also used for append.
7395  * \{ */
7396 
7397 struct BHeadSort {
7398   BHead *bhead;
7399   const void *old;
7400 };
7401 
verg_bheadsort(const void * v1,const void * v2)7402 static int verg_bheadsort(const void *v1, const void *v2)
7403 {
7404   const struct BHeadSort *x1 = v1, *x2 = v2;
7405 
7406   if (x1->old > x2->old) {
7407     return 1;
7408   }
7409   if (x1->old < x2->old) {
7410     return -1;
7411   }
7412   return 0;
7413 }
7414 
sort_bhead_old_map(FileData * fd)7415 static void sort_bhead_old_map(FileData *fd)
7416 {
7417   BHead *bhead;
7418   struct BHeadSort *bhs;
7419   int tot = 0;
7420 
7421   for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
7422     tot++;
7423   }
7424 
7425   fd->tot_bheadmap = tot;
7426   if (tot == 0) {
7427     return;
7428   }
7429 
7430   bhs = fd->bheadmap = MEM_malloc_arrayN(tot, sizeof(struct BHeadSort), "BHeadSort");
7431 
7432   for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead), bhs++) {
7433     bhs->bhead = bhead;
7434     bhs->old = bhead->old;
7435   }
7436 
7437   qsort(fd->bheadmap, tot, sizeof(struct BHeadSort), verg_bheadsort);
7438 }
7439 
find_previous_lib(FileData * fd,BHead * bhead)7440 static BHead *find_previous_lib(FileData *fd, BHead *bhead)
7441 {
7442   /* Skip library data-blocks in undo, see comment in read_libblock. */
7443   if (fd->memfile) {
7444     return NULL;
7445   }
7446 
7447   for (; bhead; bhead = blo_bhead_prev(fd, bhead)) {
7448     if (bhead->code == ID_LI) {
7449       break;
7450     }
7451   }
7452 
7453   return bhead;
7454 }
7455 
find_bhead(FileData * fd,void * old)7456 static BHead *find_bhead(FileData *fd, void *old)
7457 {
7458 #if 0
7459   BHead* bhead;
7460 #endif
7461   struct BHeadSort *bhs, bhs_s;
7462 
7463   if (!old) {
7464     return NULL;
7465   }
7466 
7467   if (fd->bheadmap == NULL) {
7468     sort_bhead_old_map(fd);
7469   }
7470 
7471   bhs_s.old = old;
7472   bhs = bsearch(&bhs_s, fd->bheadmap, fd->tot_bheadmap, sizeof(struct BHeadSort), verg_bheadsort);
7473 
7474   if (bhs) {
7475     return bhs->bhead;
7476   }
7477 
7478 #if 0
7479   for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
7480     if (bhead->old == old) {
7481       return bhead;
7482     }
7483   }
7484 #endif
7485 
7486   return NULL;
7487 }
7488 
find_bhead_from_code_name(FileData * fd,const short idcode,const char * name)7489 static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name)
7490 {
7491 #ifdef USE_GHASH_BHEAD
7492 
7493   char idname_full[MAX_ID_NAME];
7494 
7495   *((short *)idname_full) = idcode;
7496   BLI_strncpy(idname_full + 2, name, sizeof(idname_full) - 2);
7497 
7498   return BLI_ghash_lookup(fd->bhead_idname_hash, idname_full);
7499 
7500 #else
7501   BHead *bhead;
7502 
7503   for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
7504     if (bhead->code == idcode) {
7505       const char *idname_test = blo_bhead_id_name(fd, bhead);
7506       if (STREQ(idname_test + 2, name)) {
7507         return bhead;
7508       }
7509     }
7510     else if (bhead->code == ENDB) {
7511       break;
7512     }
7513   }
7514 
7515   return NULL;
7516 #endif
7517 }
7518 
find_bhead_from_idname(FileData * fd,const char * idname)7519 static BHead *find_bhead_from_idname(FileData *fd, const char *idname)
7520 {
7521 #ifdef USE_GHASH_BHEAD
7522   return BLI_ghash_lookup(fd->bhead_idname_hash, idname);
7523 #else
7524   return find_bhead_from_code_name(fd, GS(idname), idname + 2);
7525 #endif
7526 }
7527 
is_yet_read(FileData * fd,Main * mainvar,BHead * bhead)7528 static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
7529 {
7530   const char *idname = blo_bhead_id_name(fd, bhead);
7531   /* which_libbase can be NULL, intentionally not using idname+2 */
7532   return BLI_findstring(which_libbase(mainvar, GS(idname)), idname, offsetof(ID, name));
7533 }
7534 
7535 /** \} */
7536 
7537 /* -------------------------------------------------------------------- */
7538 /** \name Library Linking (expand pointers)
7539  * \{ */
7540 
expand_doit_library(void * fdhandle,Main * mainvar,void * old)7541 static void expand_doit_library(void *fdhandle, Main *mainvar, void *old)
7542 {
7543   FileData *fd = fdhandle;
7544 
7545   BHead *bhead = find_bhead(fd, old);
7546   if (bhead == NULL) {
7547     return;
7548   }
7549 
7550   if (bhead->code == ID_LINK_PLACEHOLDER) {
7551     /* Placeholder link to data-lock in another library. */
7552     BHead *bheadlib = find_previous_lib(fd, bhead);
7553     if (bheadlib == NULL) {
7554       return;
7555     }
7556 
7557     Library *lib = read_struct(fd, bheadlib, "Library");
7558     Main *libmain = blo_find_main(fd, lib->filepath, fd->relabase);
7559 
7560     if (libmain->curlib == NULL) {
7561       const char *idname = blo_bhead_id_name(fd, bhead);
7562 
7563       blo_reportf_wrap(fd->reports,
7564                        RPT_WARNING,
7565                        TIP_("LIB: Data refers to main .blend file: '%s' from %s"),
7566                        idname,
7567                        mainvar->curlib->filepath_abs);
7568       return;
7569     }
7570 
7571     ID *id = is_yet_read(fd, libmain, bhead);
7572 
7573     if (id == NULL) {
7574       /* ID has not been read yet, add placeholder to the main of the
7575        * library it belongs to, so that it will be read later. */
7576       read_libblock(fd, libmain, bhead, LIB_TAG_INDIRECT, false, NULL);
7577       /* commented because this can print way too much */
7578       // if (G.debug & G_DEBUG) printf("expand_doit: other lib %s\n", lib->filepath);
7579 
7580       /* for outliner dependency only */
7581       libmain->curlib->parent = mainvar->curlib;
7582     }
7583     else {
7584       /* Convert any previously read weak link to regular link
7585        * to signal that we want to read this data-block. */
7586       if (id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) {
7587         id->flag &= ~LIB_INDIRECT_WEAK_LINK;
7588       }
7589 
7590       /* "id" is either a placeholder or real ID that is already in the
7591        * main of the library (A) it belongs to. However it might have been
7592        * put there by another library (C) which only updated its own
7593        * fd->libmap. In that case we also need to update the fd->libmap
7594        * of the current library (B) so we can find it for lookups.
7595        *
7596        * An example of such a setup is:
7597        * (A) tree.blend: contains Tree object.
7598        * (B) forest.blend: contains Forest collection linking in Tree from tree.blend.
7599        * (C) shot.blend: links in both Tree from tree.blend and Forest from forest.blend.
7600        */
7601       oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);
7602 
7603       /* If "id" is a real data-lock and not a placeholder, we need to
7604        * update fd->libmap to replace ID_LINK_PLACEHOLDER with the real
7605        * ID_* code.
7606        *
7607        * When the real ID is read this replacement happens for all
7608        * libraries read so far, but not for libraries that have not been
7609        * read yet at that point. */
7610       change_link_placeholder_to_real_ID_pointer_fd(fd, bhead->old, id);
7611 
7612       /* Commented because this can print way too much. */
7613 #if 0
7614       if (G.debug & G_DEBUG) {
7615         printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->filepath);
7616       }
7617 #endif
7618     }
7619 
7620     MEM_freeN(lib);
7621   }
7622   else {
7623     /* Data-block in same library. */
7624     /* In 2.50+ file identifier for screens is patched, forward compatibility. */
7625     if (bhead->code == ID_SCRN) {
7626       bhead->code = ID_SCR;
7627     }
7628 
7629     ID *id = is_yet_read(fd, mainvar, bhead);
7630     if (id == NULL) {
7631       read_libblock(fd, mainvar, bhead, LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT, false, NULL);
7632     }
7633     else {
7634       /* Convert any previously read weak link to regular link
7635        * to signal that we want to read this data-block. */
7636       if (id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) {
7637         id->flag &= ~LIB_INDIRECT_WEAK_LINK;
7638       }
7639 
7640       /* this is actually only needed on UI call? when ID was already read before,
7641        * and another append happens which invokes same ID...
7642        * in that case the lookup table needs this entry */
7643       oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);
7644       /* commented because this can print way too much */
7645       // if (G.debug & G_DEBUG) printf("expand: already read %s\n", id->name);
7646     }
7647   }
7648 }
7649 
7650 static BLOExpandDoitCallback expand_doit;
7651 
7652 // XXX deprecated - old animation system
expand_ipo(BlendExpander * expander,Ipo * ipo)7653 static void expand_ipo(BlendExpander *expander, Ipo *ipo)
7654 {
7655   LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) {
7656     if (icu->driver) {
7657       BLO_expand(expander, icu->driver->ob);
7658     }
7659   }
7660 }
7661 
7662 /* XXX deprecated - old animation system */
expand_constraint_channels(BlendExpander * expander,ListBase * chanbase)7663 static void expand_constraint_channels(BlendExpander *expander, ListBase *chanbase)
7664 {
7665   LISTBASE_FOREACH (bConstraintChannel *, chan, chanbase) {
7666     BLO_expand(expander, chan->ipo);
7667   }
7668 }
7669 
7670 static void expand_id(BlendExpander *expander, ID *id);
7671 static void expand_collection(BlendExpander *expander, Collection *collection);
7672 
expand_id_embedded_id(BlendExpander * expander,ID * id)7673 static void expand_id_embedded_id(BlendExpander *expander, ID *id)
7674 {
7675   /* Handle 'private IDs'. */
7676   bNodeTree *nodetree = ntreeFromID(id);
7677   if (nodetree != NULL) {
7678     expand_id(expander, &nodetree->id);
7679     ntreeBlendReadExpand(expander, nodetree);
7680   }
7681 
7682   if (GS(id->name) == ID_SCE) {
7683     Scene *scene = (Scene *)id;
7684     if (scene->master_collection != NULL) {
7685       expand_id(expander, &scene->master_collection->id);
7686       expand_collection(expander, scene->master_collection);
7687     }
7688   }
7689 }
7690 
expand_id(BlendExpander * expander,ID * id)7691 static void expand_id(BlendExpander *expander, ID *id)
7692 {
7693   IDP_BlendReadExpand(expander, id->properties);
7694 
7695   if (id->override_library) {
7696     BLO_expand(expander, id->override_library->reference);
7697     BLO_expand(expander, id->override_library->storage);
7698   }
7699 
7700   AnimData *adt = BKE_animdata_from_id(id);
7701   if (adt != NULL) {
7702     BKE_animdata_blend_read_expand(expander, adt);
7703   }
7704 
7705   expand_id_embedded_id(expander, id);
7706 }
7707 
expand_particlesettings(BlendExpander * expander,ParticleSettings * part)7708 static void expand_particlesettings(BlendExpander *expander, ParticleSettings *part)
7709 {
7710   BLO_expand(expander, part->instance_object);
7711   BLO_expand(expander, part->instance_collection);
7712   BLO_expand(expander, part->force_group);
7713   BLO_expand(expander, part->bb_ob);
7714   BLO_expand(expander, part->collision_group);
7715 
7716   for (int a = 0; a < MAX_MTEX; a++) {
7717     if (part->mtex[a]) {
7718       BLO_expand(expander, part->mtex[a]->tex);
7719       BLO_expand(expander, part->mtex[a]->object);
7720     }
7721   }
7722 
7723   if (part->effector_weights) {
7724     BLO_expand(expander, part->effector_weights->group);
7725   }
7726 
7727   if (part->pd) {
7728     BLO_expand(expander, part->pd->tex);
7729     BLO_expand(expander, part->pd->f_source);
7730   }
7731   if (part->pd2) {
7732     BLO_expand(expander, part->pd2->tex);
7733     BLO_expand(expander, part->pd2->f_source);
7734   }
7735 
7736   if (part->boids) {
7737     LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
7738       LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
7739         if (rule->type == eBoidRuleType_Avoid) {
7740           BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
7741           BLO_expand(expander, gabr->ob);
7742         }
7743         else if (rule->type == eBoidRuleType_FollowLeader) {
7744           BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
7745           BLO_expand(expander, flbr->ob);
7746         }
7747       }
7748     }
7749   }
7750 
7751   LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) {
7752     BLO_expand(expander, dw->ob);
7753   }
7754 }
7755 
expand_collection(BlendExpander * expander,Collection * collection)7756 static void expand_collection(BlendExpander *expander, Collection *collection)
7757 {
7758   LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
7759     BLO_expand(expander, cob->ob);
7760   }
7761 
7762   LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
7763     BLO_expand(expander, child->collection);
7764   }
7765 
7766 #ifdef USE_COLLECTION_COMPAT_28
7767   if (collection->collection != NULL) {
7768     expand_scene_collection(expander, collection->collection);
7769   }
7770 #endif
7771 }
7772 
7773 /* callback function used to expand constraint ID-links */
expand_constraint_cb(bConstraint * UNUSED (con),ID ** idpoin,bool UNUSED (is_reference),void * userdata)7774 static void expand_constraint_cb(bConstraint *UNUSED(con),
7775                                  ID **idpoin,
7776                                  bool UNUSED(is_reference),
7777                                  void *userdata)
7778 {
7779   BlendExpander *expander = userdata;
7780   BLO_expand(expander, *idpoin);
7781 }
7782 
expand_constraints(BlendExpander * expander,ListBase * lb)7783 static void expand_constraints(BlendExpander *expander, ListBase *lb)
7784 {
7785   BKE_constraints_id_loop(lb, expand_constraint_cb, expander);
7786 
7787   /* deprecated manual expansion stuff */
7788   LISTBASE_FOREACH (bConstraint *, curcon, lb) {
7789     if (curcon->ipo) {
7790       BLO_expand(expander, curcon->ipo); /* XXX deprecated - old animation system */
7791     }
7792   }
7793 }
7794 
expand_pose(BlendExpander * expander,bPose * pose)7795 static void expand_pose(BlendExpander *expander, bPose *pose)
7796 {
7797   if (!pose) {
7798     return;
7799   }
7800 
7801   LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
7802     expand_constraints(expander, &chan->constraints);
7803     IDP_BlendReadExpand(expander, chan->prop);
7804     BLO_expand(expander, chan->custom);
7805   }
7806 }
7807 
expand_object_expandModifiers(void * userData,Object * UNUSED (ob),ID ** idpoin,int UNUSED (cb_flag))7808 static void expand_object_expandModifiers(void *userData,
7809                                           Object *UNUSED(ob),
7810                                           ID **idpoin,
7811                                           int UNUSED(cb_flag))
7812 {
7813   BlendExpander *expander = userData;
7814   BLO_expand(expander, *idpoin);
7815 }
7816 
expand_object(BlendExpander * expander,Object * ob)7817 static void expand_object(BlendExpander *expander, Object *ob)
7818 {
7819   BLO_expand(expander, ob->data);
7820 
7821   /* expand_object_expandModifier() */
7822   if (ob->modifiers.first) {
7823     BKE_modifiers_foreach_ID_link(ob, expand_object_expandModifiers, expander);
7824   }
7825 
7826   /* expand_object_expandModifier() */
7827   if (ob->greasepencil_modifiers.first) {
7828     BKE_gpencil_modifiers_foreach_ID_link(ob, expand_object_expandModifiers, expander);
7829   }
7830 
7831   /* expand_object_expandShaderFx() */
7832   if (ob->shader_fx.first) {
7833     BKE_shaderfx_foreach_ID_link(ob, expand_object_expandModifiers, expander);
7834   }
7835 
7836   expand_pose(expander, ob->pose);
7837   BLO_expand(expander, ob->poselib);
7838   expand_constraints(expander, &ob->constraints);
7839 
7840   BLO_expand(expander, ob->gpd);
7841 
7842   /* XXX deprecated - old animation system (for version patching only) */
7843   BLO_expand(expander, ob->ipo);
7844   BLO_expand(expander, ob->action);
7845 
7846   expand_constraint_channels(expander, &ob->constraintChannels);
7847 
7848   LISTBASE_FOREACH (bActionStrip *, strip, &ob->nlastrips) {
7849     BLO_expand(expander, strip->object);
7850     BLO_expand(expander, strip->act);
7851     BLO_expand(expander, strip->ipo);
7852   }
7853   /* XXX deprecated - old animation system (for version patching only) */
7854 
7855   for (int a = 0; a < ob->totcol; a++) {
7856     BLO_expand(expander, ob->mat[a]);
7857   }
7858 
7859   PartEff *paf = blo_do_version_give_parteff_245(ob);
7860   if (paf && paf->group) {
7861     BLO_expand(expander, paf->group);
7862   }
7863 
7864   if (ob->instance_collection) {
7865     BLO_expand(expander, ob->instance_collection);
7866   }
7867 
7868   if (ob->proxy) {
7869     BLO_expand(expander, ob->proxy);
7870   }
7871   if (ob->proxy_group) {
7872     BLO_expand(expander, ob->proxy_group);
7873   }
7874 
7875   LISTBASE_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
7876     BLO_expand(expander, psys->part);
7877   }
7878 
7879   if (ob->pd) {
7880     BLO_expand(expander, ob->pd->tex);
7881     BLO_expand(expander, ob->pd->f_source);
7882   }
7883 
7884   if (ob->soft) {
7885     BLO_expand(expander, ob->soft->collision_group);
7886 
7887     if (ob->soft->effector_weights) {
7888       BLO_expand(expander, ob->soft->effector_weights->group);
7889     }
7890   }
7891 
7892   if (ob->rigidbody_constraint) {
7893     BLO_expand(expander, ob->rigidbody_constraint->ob1);
7894     BLO_expand(expander, ob->rigidbody_constraint->ob2);
7895   }
7896 }
7897 
7898 #ifdef USE_COLLECTION_COMPAT_28
expand_scene_collection(BlendExpander * expander,SceneCollection * sc)7899 static void expand_scene_collection(BlendExpander *expander, SceneCollection *sc)
7900 {
7901   LISTBASE_FOREACH (LinkData *, link, &sc->objects) {
7902     BLO_expand(expander, link->data);
7903   }
7904 
7905   LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
7906     expand_scene_collection(expander, nsc);
7907   }
7908 }
7909 #endif
7910 
expand_scene(BlendExpander * expander,Scene * sce)7911 static void expand_scene(BlendExpander *expander, Scene *sce)
7912 {
7913   LISTBASE_FOREACH (Base *, base_legacy, &sce->base) {
7914     BLO_expand(expander, base_legacy->object);
7915   }
7916   BLO_expand(expander, sce->camera);
7917   BLO_expand(expander, sce->world);
7918 
7919   BKE_keyingsets_blend_read_expand(expander, &sce->keyingsets);
7920 
7921   if (sce->set) {
7922     BLO_expand(expander, sce->set);
7923   }
7924 
7925   LISTBASE_FOREACH (SceneRenderLayer *, srl, &sce->r.layers) {
7926     BLO_expand(expander, srl->mat_override);
7927     LISTBASE_FOREACH (FreestyleModuleConfig *, module, &srl->freestyleConfig.modules) {
7928       if (module->script) {
7929         BLO_expand(expander, module->script);
7930       }
7931     }
7932     LISTBASE_FOREACH (FreestyleLineSet *, lineset, &srl->freestyleConfig.linesets) {
7933       if (lineset->group) {
7934         BLO_expand(expander, lineset->group);
7935       }
7936       BLO_expand(expander, lineset->linestyle);
7937     }
7938   }
7939 
7940   LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
7941     IDP_BlendReadExpand(expander, view_layer->id_properties);
7942 
7943     LISTBASE_FOREACH (FreestyleModuleConfig *, module, &view_layer->freestyle_config.modules) {
7944       if (module->script) {
7945         BLO_expand(expander, module->script);
7946       }
7947     }
7948 
7949     LISTBASE_FOREACH (FreestyleLineSet *, lineset, &view_layer->freestyle_config.linesets) {
7950       if (lineset->group) {
7951         BLO_expand(expander, lineset->group);
7952       }
7953       BLO_expand(expander, lineset->linestyle);
7954     }
7955   }
7956 
7957   if (sce->gpd) {
7958     BLO_expand(expander, sce->gpd);
7959   }
7960 
7961   if (sce->ed) {
7962     Sequence *seq;
7963 
7964     SEQ_ALL_BEGIN (sce->ed, seq) {
7965       IDP_BlendReadExpand(expander, seq->prop);
7966 
7967       if (seq->scene) {
7968         BLO_expand(expander, seq->scene);
7969       }
7970       if (seq->scene_camera) {
7971         BLO_expand(expander, seq->scene_camera);
7972       }
7973       if (seq->clip) {
7974         BLO_expand(expander, seq->clip);
7975       }
7976       if (seq->mask) {
7977         BLO_expand(expander, seq->mask);
7978       }
7979       if (seq->sound) {
7980         BLO_expand(expander, seq->sound);
7981       }
7982 
7983       if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
7984         TextVars *data = seq->effectdata;
7985         BLO_expand(expander, data->text_font);
7986       }
7987     }
7988     SEQ_ALL_END;
7989   }
7990 
7991   if (sce->rigidbody_world) {
7992     BLO_expand(expander, sce->rigidbody_world->group);
7993     BLO_expand(expander, sce->rigidbody_world->constraints);
7994   }
7995 
7996   LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
7997     IDP_BlendReadExpand(expander, marker->prop);
7998 
7999     if (marker->camera) {
8000       BLO_expand(expander, marker->camera);
8001     }
8002   }
8003 
8004   BLO_expand(expander, sce->clip);
8005 
8006 #ifdef USE_COLLECTION_COMPAT_28
8007   if (sce->collection) {
8008     expand_scene_collection(expander, sce->collection);
8009   }
8010 #endif
8011 
8012   if (sce->r.bake.cage_object) {
8013     BLO_expand(expander, sce->r.bake.cage_object);
8014   }
8015 }
8016 
expand_workspace(BlendExpander * expander,WorkSpace * workspace)8017 static void expand_workspace(BlendExpander *expander, WorkSpace *workspace)
8018 {
8019   LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) {
8020     BLO_expand(expander, BKE_workspace_layout_screen_get(layout));
8021   }
8022 }
8023 
8024 /**
8025  * Set the callback func used over all ID data found by \a BLO_expand_main func.
8026  *
8027  * \param expand_doit_func: Called for each ID block it finds.
8028  */
BLO_main_expander(BLOExpandDoitCallback expand_doit_func)8029 void BLO_main_expander(BLOExpandDoitCallback expand_doit_func)
8030 {
8031   expand_doit = expand_doit_func;
8032 }
8033 
8034 /**
8035  * Loop over all ID data in Main to mark relations.
8036  * Set (id->tag & LIB_TAG_NEED_EXPAND) to mark expanding. Flags get cleared after expanding.
8037  *
8038  * \param fdhandle: usually filedata, or own handle.
8039  * \param mainvar: the Main database to expand.
8040  */
BLO_expand_main(void * fdhandle,Main * mainvar)8041 void BLO_expand_main(void *fdhandle, Main *mainvar)
8042 {
8043   ListBase *lbarray[MAX_LIBARRAY];
8044   FileData *fd = fdhandle;
8045   ID *id;
8046   int a;
8047   bool do_it = true;
8048 
8049   BlendExpander expander = {fd, mainvar};
8050 
8051   while (do_it) {
8052     do_it = false;
8053 
8054     a = set_listbasepointers(mainvar, lbarray);
8055     while (a--) {
8056       id = lbarray[a]->first;
8057       while (id) {
8058         if (id->tag & LIB_TAG_NEED_EXPAND) {
8059           expand_id(&expander, id);
8060 
8061           const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
8062           if (id_type->blend_read_expand != NULL) {
8063             id_type->blend_read_expand(&expander, id);
8064           }
8065 
8066           switch (GS(id->name)) {
8067             case ID_OB:
8068               expand_object(&expander, (Object *)id);
8069               break;
8070             case ID_SCE:
8071               expand_scene(&expander, (Scene *)id);
8072               break;
8073             case ID_GR:
8074               expand_collection(&expander, (Collection *)id);
8075               break;
8076             case ID_IP:
8077               expand_ipo(&expander, (Ipo *)id); /* XXX deprecated - old animation system */
8078               break;
8079             case ID_PA:
8080               expand_particlesettings(&expander, (ParticleSettings *)id);
8081               break;
8082             case ID_WS:
8083               expand_workspace(&expander, (WorkSpace *)id);
8084               break;
8085             default:
8086               break;
8087           }
8088 
8089           do_it = true;
8090           id->tag &= ~LIB_TAG_NEED_EXPAND;
8091         }
8092         id = id->next;
8093       }
8094     }
8095   }
8096 }
8097 
8098 /** \} */
8099 
8100 /* -------------------------------------------------------------------- */
8101 /** \name Library Linking (helper functions)
8102  * \{ */
8103 
object_in_any_scene(Main * bmain,Object * ob)8104 static bool object_in_any_scene(Main *bmain, Object *ob)
8105 {
8106   LISTBASE_FOREACH (Scene *, sce, &bmain->scenes) {
8107     if (BKE_scene_object_find(sce, ob)) {
8108       return true;
8109     }
8110   }
8111 
8112   return false;
8113 }
8114 
object_in_any_collection(Main * bmain,Object * ob)8115 static bool object_in_any_collection(Main *bmain, Object *ob)
8116 {
8117   LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
8118     if (BKE_collection_has_object(collection, ob)) {
8119       return true;
8120     }
8121   }
8122 
8123   return false;
8124 }
8125 
add_loose_objects_to_scene(Main * mainvar,Main * bmain,Scene * scene,ViewLayer * view_layer,const View3D * v3d,Library * lib,const short flag)8126 static void add_loose_objects_to_scene(Main *mainvar,
8127                                        Main *bmain,
8128                                        Scene *scene,
8129                                        ViewLayer *view_layer,
8130                                        const View3D *v3d,
8131                                        Library *lib,
8132                                        const short flag)
8133 {
8134   Collection *active_collection = NULL;
8135   const bool do_append = (flag & FILE_LINK) == 0;
8136 
8137   BLI_assert(scene);
8138 
8139   /* Give all objects which are LIB_TAG_INDIRECT a base,
8140    * or for a collection when *lib has been set. */
8141   LISTBASE_FOREACH (Object *, ob, &mainvar->objects) {
8142     bool do_it = (ob->id.tag & LIB_TAG_DOIT) != 0;
8143     if (do_it || ((ob->id.tag & LIB_TAG_INDIRECT) && (ob->id.tag & LIB_TAG_PRE_EXISTING) == 0)) {
8144       if (do_append) {
8145         if (ob->id.us == 0) {
8146           do_it = true;
8147         }
8148         else if ((ob->id.lib == lib) && !object_in_any_collection(bmain, ob)) {
8149           /* When appending, make sure any indirectly loaded object gets a base,
8150            * when they are not part of any collection yet. */
8151           do_it = true;
8152         }
8153       }
8154 
8155       if (do_it) {
8156         /* Find or add collection as needed. */
8157         if (active_collection == NULL) {
8158           if (flag & FILE_ACTIVE_COLLECTION) {
8159             LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
8160             active_collection = lc->collection;
8161           }
8162           else {
8163             active_collection = BKE_collection_add(bmain, scene->master_collection, NULL);
8164           }
8165         }
8166 
8167         CLAMP_MIN(ob->id.us, 0);
8168         ob->mode = OB_MODE_OBJECT;
8169 
8170         BKE_collection_object_add(bmain, active_collection, ob);
8171         Base *base = BKE_view_layer_base_find(view_layer, ob);
8172 
8173         if (v3d != NULL) {
8174           base->local_view_bits |= v3d->local_view_uuid;
8175         }
8176 
8177         if ((flag & FILE_AUTOSELECT) && (base->flag & BASE_SELECTABLE)) {
8178           /* Do NOT make base active here! screws up GUI stuff,
8179            * if you want it do it at the editor level. */
8180           base->flag |= BASE_SELECTED;
8181         }
8182 
8183         BKE_scene_object_base_flag_sync_from_base(base);
8184 
8185         ob->id.tag &= ~LIB_TAG_INDIRECT;
8186         ob->id.flag &= ~LIB_INDIRECT_WEAK_LINK;
8187         ob->id.tag |= LIB_TAG_EXTERN;
8188       }
8189     }
8190   }
8191 }
8192 
add_loose_object_data_to_scene(Main * mainvar,Main * bmain,Scene * scene,ViewLayer * view_layer,const View3D * v3d,const short flag)8193 static void add_loose_object_data_to_scene(Main *mainvar,
8194                                            Main *bmain,
8195                                            Scene *scene,
8196                                            ViewLayer *view_layer,
8197                                            const View3D *v3d,
8198                                            const short flag)
8199 {
8200   if ((flag & FILE_OBDATA_INSTANCE) == 0) {
8201     return;
8202   }
8203 
8204   Collection *active_collection = scene->master_collection;
8205   if (flag & FILE_ACTIVE_COLLECTION) {
8206     LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
8207     active_collection = lc->collection;
8208   }
8209 
8210   /* Loop over all ID types, instancing object-data for ID types that have support for it. */
8211   ListBase *lbarray[MAX_LIBARRAY];
8212   int i = set_listbasepointers(mainvar, lbarray);
8213   while (i--) {
8214     const short idcode = BKE_idtype_idcode_from_index(i);
8215     if (!OB_DATA_SUPPORT_ID(idcode)) {
8216       continue;
8217     }
8218 
8219     LISTBASE_FOREACH (ID *, id, lbarray[i]) {
8220       if (id->tag & LIB_TAG_DOIT) {
8221         const int type = BKE_object_obdata_to_type(id);
8222         BLI_assert(type != -1);
8223         Object *ob = BKE_object_add_only_object(bmain, type, id->name + 2);
8224         ob->data = id;
8225         id_us_plus(id);
8226         BKE_object_materials_test(bmain, ob, ob->data);
8227 
8228         BKE_collection_object_add(bmain, active_collection, ob);
8229         Base *base = BKE_view_layer_base_find(view_layer, ob);
8230 
8231         if (v3d != NULL) {
8232           base->local_view_bits |= v3d->local_view_uuid;
8233         }
8234 
8235         if ((flag & FILE_AUTOSELECT) && (base->flag & BASE_SELECTABLE)) {
8236           /* Do NOT make base active here! screws up GUI stuff,
8237            * if you want it do it at the editor level. */
8238           base->flag |= BASE_SELECTED;
8239         }
8240 
8241         BKE_scene_object_base_flag_sync_from_base(base);
8242 
8243         copy_v3_v3(ob->loc, scene->cursor.location);
8244       }
8245     }
8246   }
8247 }
8248 
add_collections_to_scene(Main * mainvar,Main * bmain,Scene * scene,ViewLayer * view_layer,const View3D * v3d,Library * lib,const short flag)8249 static void add_collections_to_scene(Main *mainvar,
8250                                      Main *bmain,
8251                                      Scene *scene,
8252                                      ViewLayer *view_layer,
8253                                      const View3D *v3d,
8254                                      Library *lib,
8255                                      const short flag)
8256 {
8257   Collection *active_collection = scene->master_collection;
8258   if (flag & FILE_ACTIVE_COLLECTION) {
8259     LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
8260     active_collection = lc->collection;
8261   }
8262 
8263   /* Give all objects which are tagged a base. */
8264   LISTBASE_FOREACH (Collection *, collection, &mainvar->collections) {
8265     if ((flag & FILE_COLLECTION_INSTANCE) && (collection->id.tag & LIB_TAG_DOIT)) {
8266       /* Any indirect collection should not have been tagged. */
8267       BLI_assert((collection->id.tag & LIB_TAG_INDIRECT) == 0);
8268 
8269       /* BKE_object_add(...) messes with the selection. */
8270       Object *ob = BKE_object_add_only_object(bmain, OB_EMPTY, collection->id.name + 2);
8271       ob->type = OB_EMPTY;
8272       ob->empty_drawsize = U.collection_instance_empty_size;
8273 
8274       BKE_collection_object_add(bmain, active_collection, ob);
8275       Base *base = BKE_view_layer_base_find(view_layer, ob);
8276 
8277       if (v3d != NULL) {
8278         base->local_view_bits |= v3d->local_view_uuid;
8279       }
8280 
8281       if ((flag & FILE_AUTOSELECT) && (base->flag & BASE_SELECTABLE)) {
8282         base->flag |= BASE_SELECTED;
8283       }
8284 
8285       BKE_scene_object_base_flag_sync_from_base(base);
8286       DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
8287 
8288       if (flag & FILE_AUTOSELECT) {
8289         view_layer->basact = base;
8290       }
8291 
8292       /* Assign the collection. */
8293       ob->instance_collection = collection;
8294       id_us_plus(&collection->id);
8295       ob->transflag |= OB_DUPLICOLLECTION;
8296       copy_v3_v3(ob->loc, scene->cursor.location);
8297     }
8298     /* We do not want to force instantiation of indirectly linked collections,
8299      * not even when appending. Users can now easily instantiate collections (and their objects)
8300      * as needed by themselves. See T67032. */
8301     else if ((collection->id.tag & LIB_TAG_INDIRECT) == 0) {
8302       bool do_add_collection = (collection->id.tag & LIB_TAG_DOIT) != 0;
8303       if (!do_add_collection) {
8304         /* We need to check that objects in that collections are already instantiated in a scene.
8305          * Otherwise, it's better to add the collection to the scene's active collection, than to
8306          * instantiate its objects in active scene's collection directly. See T61141.
8307          * Note that we only check object directly into that collection,
8308          * not recursively into its children.
8309          */
8310         LISTBASE_FOREACH (CollectionObject *, coll_ob, &collection->gobject) {
8311           Object *ob = coll_ob->ob;
8312           if ((ob->id.tag & (LIB_TAG_PRE_EXISTING | LIB_TAG_DOIT | LIB_TAG_INDIRECT)) == 0 &&
8313               (ob->id.lib == lib) && (object_in_any_scene(bmain, ob) == 0)) {
8314             do_add_collection = true;
8315             break;
8316           }
8317         }
8318       }
8319       if (do_add_collection) {
8320         /* Add collection as child of active collection. */
8321         BKE_collection_child_add(bmain, active_collection, collection);
8322 
8323         if (flag & FILE_AUTOSELECT) {
8324           LISTBASE_FOREACH (CollectionObject *, coll_ob, &collection->gobject) {
8325             Object *ob = coll_ob->ob;
8326             Base *base = BKE_view_layer_base_find(view_layer, ob);
8327             if (base) {
8328               base->flag |= BASE_SELECTED;
8329               BKE_scene_object_base_flag_sync_from_base(base);
8330             }
8331           }
8332         }
8333 
8334         /* Those are kept for safety and consistency, but should not be needed anymore? */
8335         collection->id.tag &= ~LIB_TAG_INDIRECT;
8336         collection->id.flag &= ~LIB_INDIRECT_WEAK_LINK;
8337         collection->id.tag |= LIB_TAG_EXTERN;
8338       }
8339     }
8340   }
8341 }
8342 
8343 /* returns true if the item was found
8344  * but it may already have already been appended/linked */
link_named_part(Main * mainl,FileData * fd,const short idcode,const char * name,const int flag)8345 static ID *link_named_part(
8346     Main *mainl, FileData *fd, const short idcode, const char *name, const int flag)
8347 {
8348   BHead *bhead = find_bhead_from_code_name(fd, idcode, name);
8349   ID *id;
8350 
8351   const bool use_placeholders = (flag & BLO_LIBLINK_USE_PLACEHOLDERS) != 0;
8352   const bool force_indirect = (flag & BLO_LIBLINK_FORCE_INDIRECT) != 0;
8353 
8354   BLI_assert(BKE_idtype_idcode_is_linkable(idcode) && BKE_idtype_idcode_is_valid(idcode));
8355 
8356   if (bhead) {
8357     id = is_yet_read(fd, mainl, bhead);
8358     if (id == NULL) {
8359       /* not read yet */
8360       const int tag = force_indirect ? LIB_TAG_INDIRECT : LIB_TAG_EXTERN;
8361       read_libblock(fd, mainl, bhead, tag | LIB_TAG_NEED_EXPAND, false, &id);
8362 
8363       if (id) {
8364         /* sort by name in list */
8365         ListBase *lb = which_libbase(mainl, idcode);
8366         id_sort_by_name(lb, id, NULL);
8367       }
8368     }
8369     else {
8370       /* already linked */
8371       if (G.debug) {
8372         printf("append: already linked\n");
8373       }
8374       oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);
8375       if (!force_indirect && (id->tag & LIB_TAG_INDIRECT)) {
8376         id->tag &= ~LIB_TAG_INDIRECT;
8377         id->flag &= ~LIB_INDIRECT_WEAK_LINK;
8378         id->tag |= LIB_TAG_EXTERN;
8379       }
8380     }
8381   }
8382   else if (use_placeholders) {
8383     /* XXX flag part is weak! */
8384     id = create_placeholder(
8385         mainl, idcode, name, force_indirect ? LIB_TAG_INDIRECT : LIB_TAG_EXTERN);
8386   }
8387   else {
8388     id = NULL;
8389   }
8390 
8391   /* if we found the id but the id is NULL, this is really bad */
8392   BLI_assert(!((bhead != NULL) && (id == NULL)));
8393 
8394   /* Tag as loose object (or data associated with objects)
8395    * needing to be instantiated in #LibraryLink_Params.scene. */
8396   if ((id != NULL) && (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT)) {
8397     if (library_link_idcode_needs_tag_check(idcode, flag)) {
8398       id->tag |= LIB_TAG_DOIT;
8399     }
8400   }
8401 
8402   return id;
8403 }
8404 
8405 /**
8406  * Simple reader for copy/paste buffers.
8407  */
BLO_library_link_copypaste(Main * mainl,BlendHandle * bh,const uint64_t id_types_mask)8408 int BLO_library_link_copypaste(Main *mainl, BlendHandle *bh, const uint64_t id_types_mask)
8409 {
8410   FileData *fd = (FileData *)(bh);
8411   BHead *bhead;
8412   int num_directly_linked = 0;
8413 
8414   for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
8415     ID *id = NULL;
8416 
8417     if (bhead->code == ENDB) {
8418       break;
8419     }
8420 
8421     if (BKE_idtype_idcode_is_valid(bhead->code) && BKE_idtype_idcode_is_linkable(bhead->code) &&
8422         (id_types_mask == 0 ||
8423          (BKE_idtype_idcode_to_idfilter((short)bhead->code) & id_types_mask) != 0)) {
8424       read_libblock(fd, mainl, bhead, LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT, false, &id);
8425       num_directly_linked++;
8426     }
8427 
8428     if (id) {
8429       /* sort by name in list */
8430       ListBase *lb = which_libbase(mainl, GS(id->name));
8431       id_sort_by_name(lb, id, NULL);
8432 
8433       if (bhead->code == ID_OB) {
8434         /* Instead of instancing Base's directly, postpone until after collections are loaded
8435          * otherwise the base's flag is set incorrectly when collections are used */
8436         Object *ob = (Object *)id;
8437         ob->mode = OB_MODE_OBJECT;
8438         /* ensure add_loose_objects_to_scene runs on this object */
8439         BLI_assert(id->us == 0);
8440       }
8441     }
8442   }
8443 
8444   return num_directly_linked;
8445 }
8446 
8447 /**
8448  * Link a named data-block from an external blend file.
8449  *
8450  * \param mainl: The main database to link from (not the active one).
8451  * \param bh: The blender file handle.
8452  * \param idcode: The kind of data-block to link.
8453  * \param name: The name of the data-block (without the 2 char ID prefix).
8454  * \return the linked ID when found.
8455  */
BLO_library_link_named_part(Main * mainl,BlendHandle ** bh,const short idcode,const char * name,const struct LibraryLink_Params * params)8456 ID *BLO_library_link_named_part(Main *mainl,
8457                                 BlendHandle **bh,
8458                                 const short idcode,
8459                                 const char *name,
8460                                 const struct LibraryLink_Params *params)
8461 {
8462   FileData *fd = (FileData *)(*bh);
8463   return link_named_part(mainl, fd, idcode, name, params->flag);
8464 }
8465 
8466 /* common routine to append/link something from a library */
8467 
8468 /**
8469  * Checks if the \a idcode needs to be tagged with #LIB_TAG_DOIT when linking/appending.
8470  */
library_link_idcode_needs_tag_check(const short idcode,const int flag)8471 static bool library_link_idcode_needs_tag_check(const short idcode, const int flag)
8472 {
8473   if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) {
8474     /* Always true because of #add_loose_objects_to_scene & #add_collections_to_scene. */
8475     if (ELEM(idcode, ID_OB, ID_GR)) {
8476       return true;
8477     }
8478     if (flag & FILE_OBDATA_INSTANCE) {
8479       if (OB_DATA_SUPPORT_ID(idcode)) {
8480         return true;
8481       }
8482     }
8483   }
8484   return false;
8485 }
8486 
8487 /**
8488  * Clears #LIB_TAG_DOIT based on the result of #library_link_idcode_needs_tag_check.
8489  */
library_link_clear_tag(Main * mainvar,const int flag)8490 static void library_link_clear_tag(Main *mainvar, const int flag)
8491 {
8492   for (int i = 0; i < MAX_LIBARRAY; i++) {
8493     const short idcode = BKE_idtype_idcode_from_index(i);
8494     BLI_assert(idcode != -1);
8495     if (library_link_idcode_needs_tag_check(idcode, flag)) {
8496       BKE_main_id_tag_idcode(mainvar, idcode, LIB_TAG_DOIT, false);
8497     }
8498   }
8499 }
8500 
library_link_begin(Main * mainvar,FileData ** fd,const char * filepath,const int flag)8501 static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepath, const int flag)
8502 {
8503   Main *mainl;
8504 
8505   (*fd)->mainlist = MEM_callocN(sizeof(ListBase), "FileData.mainlist");
8506 
8507   if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) {
8508     /* Clear for objects and collections instantiating tag. */
8509     library_link_clear_tag(mainvar, flag);
8510   }
8511 
8512   /* make mains */
8513   blo_split_main((*fd)->mainlist, mainvar);
8514 
8515   /* which one do we need? */
8516   mainl = blo_find_main(*fd, filepath, BKE_main_blendfile_path(mainvar));
8517 
8518   /* needed for do_version */
8519   mainl->versionfile = (*fd)->fileversion;
8520   read_file_version(*fd, mainl);
8521 #ifdef USE_GHASH_BHEAD
8522   read_file_bhead_idname_map_create(*fd);
8523 #endif
8524 
8525   return mainl;
8526 }
8527 
BLO_library_link_params_init(struct LibraryLink_Params * params,struct Main * bmain,const int flag)8528 void BLO_library_link_params_init(struct LibraryLink_Params *params,
8529                                   struct Main *bmain,
8530                                   const int flag)
8531 {
8532   memset(params, 0, sizeof(*params));
8533   params->bmain = bmain;
8534   params->flag = flag;
8535 }
8536 
BLO_library_link_params_init_with_context(struct LibraryLink_Params * params,struct Main * bmain,const int flag,struct Scene * scene,struct ViewLayer * view_layer,const struct View3D * v3d)8537 void BLO_library_link_params_init_with_context(struct LibraryLink_Params *params,
8538                                                struct Main *bmain,
8539                                                const int flag,
8540                                                /* Context arguments. */
8541                                                struct Scene *scene,
8542                                                struct ViewLayer *view_layer,
8543                                                const struct View3D *v3d)
8544 {
8545   BLO_library_link_params_init(params, bmain, flag);
8546   if (scene != NULL) {
8547     /* Tagging is needed for instancing. */
8548     params->flag |= BLO_LIBLINK_NEEDS_ID_TAG_DOIT;
8549 
8550     params->context.scene = scene;
8551     params->context.view_layer = view_layer;
8552     params->context.v3d = v3d;
8553   }
8554 }
8555 
8556 /**
8557  * Initialize the #BlendHandle for linking library data.
8558  *
8559  * \param bh: A blender file handle as returned by
8560  * #BLO_blendhandle_from_file or #BLO_blendhandle_from_memory.
8561  * \param filepath: Used for relative linking, copied to the `lib->filepath`.
8562  * \param params: Settings for linking that don't change from beginning to end of linking.
8563  * \return the library #Main, to be passed to #BLO_library_link_named_part as \a mainl.
8564  */
BLO_library_link_begin(BlendHandle ** bh,const char * filepath,const struct LibraryLink_Params * params)8565 Main *BLO_library_link_begin(BlendHandle **bh,
8566                              const char *filepath,
8567                              const struct LibraryLink_Params *params)
8568 {
8569   FileData *fd = (FileData *)(*bh);
8570   return library_link_begin(params->bmain, &fd, filepath, params->flag);
8571 }
8572 
split_main_newid(Main * mainptr,Main * main_newid)8573 static void split_main_newid(Main *mainptr, Main *main_newid)
8574 {
8575   /* We only copy the necessary subset of data in this temp main. */
8576   main_newid->versionfile = mainptr->versionfile;
8577   main_newid->subversionfile = mainptr->subversionfile;
8578   BLI_strncpy(main_newid->name, mainptr->name, sizeof(main_newid->name));
8579   main_newid->curlib = mainptr->curlib;
8580 
8581   ListBase *lbarray[MAX_LIBARRAY];
8582   ListBase *lbarray_newid[MAX_LIBARRAY];
8583   int i = set_listbasepointers(mainptr, lbarray);
8584   set_listbasepointers(main_newid, lbarray_newid);
8585   while (i--) {
8586     BLI_listbase_clear(lbarray_newid[i]);
8587 
8588     LISTBASE_FOREACH_MUTABLE (ID *, id, lbarray[i]) {
8589       if (id->tag & LIB_TAG_NEW) {
8590         BLI_remlink(lbarray[i], id);
8591         BLI_addtail(lbarray_newid[i], id);
8592       }
8593     }
8594   }
8595 }
8596 
8597 /**
8598  * \param scene: The scene in which to instantiate objects/collections
8599  * (if NULL, no instantiation is done).
8600  * \param v3d: The active 3D viewport.
8601  * (only to define active layers for instantiated objects & collections, can be NULL).
8602  */
library_link_end(Main * mainl,FileData ** fd,Main * bmain,const int flag,Scene * scene,ViewLayer * view_layer,const View3D * v3d)8603 static void library_link_end(Main *mainl,
8604                              FileData **fd,
8605                              Main *bmain,
8606                              const int flag,
8607                              Scene *scene,
8608                              ViewLayer *view_layer,
8609                              const View3D *v3d)
8610 {
8611   Main *mainvar;
8612   Library *curlib;
8613 
8614   /* expander now is callback function */
8615   BLO_main_expander(expand_doit_library);
8616 
8617   /* make main consistent */
8618   BLO_expand_main(*fd, mainl);
8619 
8620   /* do this when expand found other libs */
8621   read_libraries(*fd, (*fd)->mainlist);
8622 
8623   curlib = mainl->curlib;
8624 
8625   /* make the lib path relative if required */
8626   if (flag & FILE_RELPATH) {
8627     /* use the full path, this could have been read by other library even */
8628     BLI_strncpy(curlib->filepath, curlib->filepath_abs, sizeof(curlib->filepath));
8629 
8630     /* uses current .blend file as reference */
8631     BLI_path_rel(curlib->filepath, BKE_main_blendfile_path_from_global());
8632   }
8633 
8634   blo_join_main((*fd)->mainlist);
8635   mainvar = (*fd)->mainlist->first;
8636   mainl = NULL; /* blo_join_main free's mainl, cant use anymore */
8637 
8638   lib_link_all(*fd, mainvar);
8639 
8640   /* Some versioning code does expect some proper userrefcounting, e.g. in conversion from
8641    * groups to collections... We could optimize out that first call when we are reading a
8642    * current version file, but again this is really not a bottle neck currently. so not worth
8643    * it. */
8644   BKE_main_id_refcount_recompute(mainvar, false);
8645 
8646   BKE_collections_after_lib_link(mainvar);
8647 
8648   /* Yep, second splitting... but this is a very cheap operation, so no big deal. */
8649   blo_split_main((*fd)->mainlist, mainvar);
8650   Main *main_newid = BKE_main_new();
8651   for (mainvar = ((Main *)(*fd)->mainlist->first)->next; mainvar; mainvar = mainvar->next) {
8652     BLI_assert(mainvar->versionfile != 0);
8653     /* We need to split out IDs already existing,
8654      * or they will go again through do_versions - bad, very bad! */
8655     split_main_newid(mainvar, main_newid);
8656 
8657     do_versions_after_linking(main_newid, (*fd)->reports);
8658 
8659     add_main_to_main(mainvar, main_newid);
8660   }
8661 
8662   BKE_main_free(main_newid);
8663   blo_join_main((*fd)->mainlist);
8664   mainvar = (*fd)->mainlist->first;
8665   MEM_freeN((*fd)->mainlist);
8666 
8667   /* This does not take into account old, deprecated data, so we also have to do it after
8668    * `do_versions_after_linking()`. */
8669   BKE_main_id_refcount_recompute(mainvar, false);
8670 
8671   /* After all data has been read and versioned, uses LIB_TAG_NEW. */
8672   ntreeUpdateAllNew(mainvar);
8673 
8674   placeholders_ensure_valid(mainvar);
8675 
8676   BKE_main_id_tag_all(mainvar, LIB_TAG_NEW, false);
8677 
8678   /* Make all relative paths, relative to the open blend file. */
8679   fix_relpaths_library(BKE_main_blendfile_path(mainvar), mainvar);
8680 
8681   /* Give a base to loose objects and collections.
8682    * Only directly linked objects & collections are instantiated by
8683    * #BLO_library_link_named_part & co,
8684    * here we handle indirect ones and other possible edge-cases. */
8685   if (flag & BLO_LIBLINK_NEEDS_ID_TAG_DOIT) {
8686     /* Should always be true. */
8687     if (scene != NULL) {
8688       add_collections_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag);
8689       add_loose_objects_to_scene(mainvar, bmain, scene, view_layer, v3d, curlib, flag);
8690       add_loose_object_data_to_scene(mainvar, bmain, scene, view_layer, v3d, flag);
8691     }
8692 
8693     /* Clear objects and collections instantiating tag. */
8694     library_link_clear_tag(mainvar, flag);
8695   }
8696 
8697   /* patch to prevent switch_endian happens twice */
8698   if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
8699     blo_filedata_free(*fd);
8700     *fd = NULL;
8701   }
8702 }
8703 
8704 /**
8705  * Finalize linking from a given .blend file (library).
8706  * Optionally instance the indirect object/collection in the scene when the flags are set.
8707  * \note Do not use \a bh after calling this function, it may frees it.
8708  *
8709  * \param mainl: The main database to link from (not the active one).
8710  * \param bh: The blender file handle (WARNING! may be freed by this function!).
8711  * \param params: Settings for linking that don't change from beginning to end of linking.
8712  */
BLO_library_link_end(Main * mainl,BlendHandle ** bh,const struct LibraryLink_Params * params)8713 void BLO_library_link_end(Main *mainl, BlendHandle **bh, const struct LibraryLink_Params *params)
8714 {
8715   FileData *fd = (FileData *)(*bh);
8716   library_link_end(mainl,
8717                    &fd,
8718                    params->bmain,
8719                    params->flag,
8720                    params->context.scene,
8721                    params->context.view_layer,
8722                    params->context.v3d);
8723   *bh = (BlendHandle *)fd;
8724 }
8725 
BLO_library_read_struct(FileData * fd,BHead * bh,const char * blockname)8726 void *BLO_library_read_struct(FileData *fd, BHead *bh, const char *blockname)
8727 {
8728   return read_struct(fd, bh, blockname);
8729 }
8730 
8731 /** \} */
8732 
8733 /* -------------------------------------------------------------------- */
8734 /** \name Library Reading
8735  * \{ */
8736 
has_linked_ids_to_read(Main * mainvar)8737 static int has_linked_ids_to_read(Main *mainvar)
8738 {
8739   ListBase *lbarray[MAX_LIBARRAY];
8740   int a = set_listbasepointers(mainvar, lbarray);
8741 
8742   while (a--) {
8743     LISTBASE_FOREACH (ID *, id, lbarray[a]) {
8744       if ((id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) && !(id->flag & LIB_INDIRECT_WEAK_LINK)) {
8745         return true;
8746       }
8747     }
8748   }
8749 
8750   return false;
8751 }
8752 
read_library_linked_id(ReportList * reports,FileData * fd,Main * mainvar,ID * id,ID ** r_id)8753 static void read_library_linked_id(
8754     ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id)
8755 {
8756   BHead *bhead = NULL;
8757   const bool is_valid = BKE_idtype_idcode_is_linkable(GS(id->name)) ||
8758                         ((id->tag & LIB_TAG_EXTERN) == 0);
8759 
8760   if (fd) {
8761     bhead = find_bhead_from_idname(fd, id->name);
8762   }
8763 
8764   if (!is_valid) {
8765     blo_reportf_wrap(reports,
8766                      RPT_ERROR,
8767                      TIP_("LIB: %s: '%s' is directly linked from '%s' (parent '%s'), but is a "
8768                           "non-linkable data type"),
8769                      BKE_idtype_idcode_to_name(GS(id->name)),
8770                      id->name + 2,
8771                      mainvar->curlib->filepath_abs,
8772                      library_parent_filepath(mainvar->curlib));
8773   }
8774 
8775   id->tag &= ~LIB_TAG_ID_LINK_PLACEHOLDER;
8776   id->flag &= ~LIB_INDIRECT_WEAK_LINK;
8777 
8778   if (bhead) {
8779     id->tag |= LIB_TAG_NEED_EXPAND;
8780     // printf("read lib block %s\n", id->name);
8781     read_libblock(fd, mainvar, bhead, id->tag, false, r_id);
8782   }
8783   else {
8784     blo_reportf_wrap(reports,
8785                      RPT_WARNING,
8786                      TIP_("LIB: %s: '%s' missing from '%s', parent '%s'"),
8787                      BKE_idtype_idcode_to_name(GS(id->name)),
8788                      id->name + 2,
8789                      mainvar->curlib->filepath_abs,
8790                      library_parent_filepath(mainvar->curlib));
8791 
8792     /* Generate a placeholder for this ID (simplified version of read_libblock actually...). */
8793     if (r_id) {
8794       *r_id = is_valid ? create_placeholder(mainvar, GS(id->name), id->name + 2, id->tag) : NULL;
8795     }
8796   }
8797 }
8798 
read_library_linked_ids(FileData * basefd,FileData * fd,ListBase * mainlist,Main * mainvar)8799 static void read_library_linked_ids(FileData *basefd,
8800                                     FileData *fd,
8801                                     ListBase *mainlist,
8802                                     Main *mainvar)
8803 {
8804   GHash *loaded_ids = BLI_ghash_str_new(__func__);
8805 
8806   ListBase *lbarray[MAX_LIBARRAY];
8807   int a = set_listbasepointers(mainvar, lbarray);
8808 
8809   while (a--) {
8810     ID *id = lbarray[a]->first;
8811     ListBase pending_free_ids = {NULL};
8812 
8813     while (id) {
8814       ID *id_next = id->next;
8815       if ((id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) && !(id->flag & LIB_INDIRECT_WEAK_LINK)) {
8816         BLI_remlink(lbarray[a], id);
8817 
8818         /* When playing with lib renaming and such, you may end with cases where
8819          * you have more than one linked ID of the same data-block from same
8820          * library. This is absolutely horrible, hence we use a ghash to ensure
8821          * we go back to a single linked data when loading the file. */
8822         ID **realid = NULL;
8823         if (!BLI_ghash_ensure_p(loaded_ids, id->name, (void ***)&realid)) {
8824           read_library_linked_id(basefd->reports, fd, mainvar, id, realid);
8825         }
8826 
8827         /* realid shall never be NULL - unless some source file/lib is broken
8828          * (known case: some directly linked shapekey from a missing lib...). */
8829         /* BLI_assert(*realid != NULL); */
8830 
8831         /* Now that we have a real ID, replace all pointers to placeholders in
8832          * fd->libmap with pointers to the real data-blocks. We do this for all
8833          * libraries since multiple might be referencing this ID. */
8834         change_link_placeholder_to_real_ID_pointer(mainlist, basefd, id, *realid);
8835 
8836         /* We cannot free old lib-ref placeholder ID here anymore, since we use
8837          * its name as key in loaded_ids hash. */
8838         BLI_addtail(&pending_free_ids, id);
8839       }
8840       id = id_next;
8841     }
8842 
8843     /* Clear GHash and free link placeholder IDs of the current type. */
8844     BLI_ghash_clear(loaded_ids, NULL, NULL);
8845     BLI_freelistN(&pending_free_ids);
8846   }
8847 
8848   BLI_ghash_free(loaded_ids, NULL, NULL);
8849 }
8850 
read_library_clear_weak_links(FileData * basefd,ListBase * mainlist,Main * mainvar)8851 static void read_library_clear_weak_links(FileData *basefd, ListBase *mainlist, Main *mainvar)
8852 {
8853   /* Any remaining weak links at this point have been lost, silently drop
8854    * those by setting them to NULL pointers. */
8855   ListBase *lbarray[MAX_LIBARRAY];
8856   int a = set_listbasepointers(mainvar, lbarray);
8857 
8858   while (a--) {
8859     ID *id = lbarray[a]->first;
8860 
8861     while (id) {
8862       ID *id_next = id->next;
8863       if ((id->tag & LIB_TAG_ID_LINK_PLACEHOLDER) && (id->flag & LIB_INDIRECT_WEAK_LINK)) {
8864         /* printf("Dropping weak link to %s\n", id->name); */
8865         change_link_placeholder_to_real_ID_pointer(mainlist, basefd, id, NULL);
8866         BLI_freelinkN(lbarray[a], id);
8867       }
8868       id = id_next;
8869     }
8870   }
8871 }
8872 
read_library_file_data(FileData * basefd,ListBase * mainlist,Main * mainl,Main * mainptr)8873 static FileData *read_library_file_data(FileData *basefd,
8874                                         ListBase *mainlist,
8875                                         Main *mainl,
8876                                         Main *mainptr)
8877 {
8878   FileData *fd = mainptr->curlib->filedata;
8879 
8880   if (fd != NULL) {
8881     /* File already open. */
8882     return fd;
8883   }
8884 
8885   if (mainptr->curlib->packedfile) {
8886     /* Read packed file. */
8887     PackedFile *pf = mainptr->curlib->packedfile;
8888 
8889     blo_reportf_wrap(basefd->reports,
8890                      RPT_INFO,
8891                      TIP_("Read packed library:  '%s', parent '%s'"),
8892                      mainptr->curlib->filepath,
8893                      library_parent_filepath(mainptr->curlib));
8894     fd = blo_filedata_from_memory(pf->data, pf->size, basefd->reports);
8895 
8896     /* Needed for library_append and read_libraries. */
8897     BLI_strncpy(fd->relabase, mainptr->curlib->filepath_abs, sizeof(fd->relabase));
8898   }
8899   else {
8900     /* Read file on disk. */
8901     blo_reportf_wrap(basefd->reports,
8902                      RPT_INFO,
8903                      TIP_("Read library:  '%s', '%s', parent '%s'"),
8904                      mainptr->curlib->filepath_abs,
8905                      mainptr->curlib->filepath,
8906                      library_parent_filepath(mainptr->curlib));
8907     fd = blo_filedata_from_file(mainptr->curlib->filepath_abs, basefd->reports);
8908   }
8909 
8910   if (fd) {
8911     /* Share the mainlist, so all libraries are added immediately in a
8912      * single list. It used to be that all FileData's had their own list,
8913      * but with indirectly linking this meant we didn't catch duplicate
8914      * libraries properly. */
8915     fd->mainlist = mainlist;
8916 
8917     fd->reports = basefd->reports;
8918 
8919     if (fd->libmap) {
8920       oldnewmap_free(fd->libmap);
8921     }
8922 
8923     fd->libmap = oldnewmap_new();
8924 
8925     mainptr->curlib->filedata = fd;
8926     mainptr->versionfile = fd->fileversion;
8927 
8928     /* subversion */
8929     read_file_version(fd, mainptr);
8930 #ifdef USE_GHASH_BHEAD
8931     read_file_bhead_idname_map_create(fd);
8932 #endif
8933   }
8934   else {
8935     mainptr->curlib->filedata = NULL;
8936     mainptr->curlib->id.tag |= LIB_TAG_MISSING;
8937     /* Set lib version to current main one... Makes assert later happy. */
8938     mainptr->versionfile = mainptr->curlib->versionfile = mainl->versionfile;
8939     mainptr->subversionfile = mainptr->curlib->subversionfile = mainl->subversionfile;
8940   }
8941 
8942   if (fd == NULL) {
8943     blo_reportf_wrap(
8944         basefd->reports, RPT_WARNING, TIP_("Cannot find lib '%s'"), mainptr->curlib->filepath_abs);
8945   }
8946 
8947   return fd;
8948 }
8949 
read_libraries(FileData * basefd,ListBase * mainlist)8950 static void read_libraries(FileData *basefd, ListBase *mainlist)
8951 {
8952   Main *mainl = mainlist->first;
8953   bool do_it = true;
8954 
8955   /* Expander is now callback function. */
8956   BLO_main_expander(expand_doit_library);
8957 
8958   /* At this point the base blend file has been read, and each library blend
8959    * encountered so far has a main with placeholders for linked data-blocks.
8960    *
8961    * Now we will read the library blend files and replace the placeholders
8962    * with actual data-blocks. We loop over library mains multiple times in
8963    * case a library needs to link additional data-blocks from another library
8964    * that had been read previously. */
8965   while (do_it) {
8966     do_it = false;
8967 
8968     /* Loop over mains of all library blend files encountered so far. Note
8969      * this list gets longer as more indirectly library blends are found. */
8970     for (Main *mainptr = mainl->next; mainptr; mainptr = mainptr->next) {
8971       /* Does this library have any more linked data-blocks we need to read? */
8972       if (has_linked_ids_to_read(mainptr)) {
8973 #if 0
8974         printf("Reading linked data-blocks from %s (%s)\n",
8975           mainptr->curlib->id.name,
8976           mainptr->curlib->filepath);
8977 #endif
8978 
8979         /* Open file if it has not been done yet. */
8980         FileData *fd = read_library_file_data(basefd, mainlist, mainl, mainptr);
8981 
8982         if (fd) {
8983           do_it = true;
8984         }
8985 
8986         /* Read linked data-locks for each link placeholder, and replace
8987          * the placeholder with the real data-lock. */
8988         read_library_linked_ids(basefd, fd, mainlist, mainptr);
8989 
8990         /* Test if linked data-locks need to read further linked data-locks
8991          * and create link placeholders for them. */
8992         BLO_expand_main(fd, mainptr);
8993       }
8994     }
8995   }
8996 
8997   Main *main_newid = BKE_main_new();
8998   for (Main *mainptr = mainl->next; mainptr; mainptr = mainptr->next) {
8999     /* Drop weak links for which no data-block was found. */
9000     read_library_clear_weak_links(basefd, mainlist, mainptr);
9001 
9002     /* Do versioning for newly added linked data-locks. If no data-locks
9003      * were read from a library versionfile will still be zero and we can
9004      * skip it. */
9005     if (mainptr->versionfile) {
9006       /* Split out already existing IDs to avoid them going through
9007        * do_versions multiple times, which would have bad consequences. */
9008       split_main_newid(mainptr, main_newid);
9009 
9010       /* File data can be zero with link/append. */
9011       if (mainptr->curlib->filedata) {
9012         do_versions(mainptr->curlib->filedata, mainptr->curlib, main_newid);
9013       }
9014       else {
9015         do_versions(basefd, NULL, main_newid);
9016       }
9017 
9018       add_main_to_main(mainptr, main_newid);
9019     }
9020 
9021     /* Lib linking. */
9022     if (mainptr->curlib->filedata) {
9023       lib_link_all(mainptr->curlib->filedata, mainptr);
9024     }
9025 
9026     /* Note: No need to call #do_versions_after_linking() or #BKE_main_id_refcount_recompute()
9027      * here, as this function is only called for library 'subset' data handling, as part of
9028      * either full blendfile reading (#blo_read_file_internal()), or library-data linking
9029      * (#library_link_end()). */
9030 
9031     /* Free file data we no longer need. */
9032     if (mainptr->curlib->filedata) {
9033       blo_filedata_free(mainptr->curlib->filedata);
9034     }
9035     mainptr->curlib->filedata = NULL;
9036   }
9037   BKE_main_free(main_newid);
9038 }
9039 
BLO_read_get_new_data_address(BlendDataReader * reader,const void * old_address)9040 void *BLO_read_get_new_data_address(BlendDataReader *reader, const void *old_address)
9041 {
9042   return newdataadr(reader->fd, old_address);
9043 }
9044 
BLO_read_get_new_packed_address(BlendDataReader * reader,const void * old_address)9045 void *BLO_read_get_new_packed_address(BlendDataReader *reader, const void *old_address)
9046 {
9047   return newpackedadr(reader->fd, old_address);
9048 }
9049 
BLO_read_get_new_id_address(BlendLibReader * reader,Library * lib,ID * id)9050 ID *BLO_read_get_new_id_address(BlendLibReader *reader, Library *lib, ID *id)
9051 {
9052   return newlibadr(reader->fd, lib, id);
9053 }
9054 
BLO_read_requires_endian_switch(BlendDataReader * reader)9055 bool BLO_read_requires_endian_switch(BlendDataReader *reader)
9056 {
9057   return (reader->fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
9058 }
9059 
9060 /**
9061  * Updates all ->prev and ->next pointers of the list elements.
9062  * Updates the list->first and list->last pointers.
9063  * When not NULL, calls the callback on every element.
9064  */
BLO_read_list_cb(BlendDataReader * reader,ListBase * list,BlendReadListFn callback)9065 void BLO_read_list_cb(BlendDataReader *reader, ListBase *list, BlendReadListFn callback)
9066 {
9067   if (BLI_listbase_is_empty(list)) {
9068     return;
9069   }
9070 
9071   BLO_read_data_address(reader, &list->first);
9072   if (callback != NULL) {
9073     callback(reader, list->first);
9074   }
9075   Link *ln = list->first;
9076   Link *prev = NULL;
9077   while (ln) {
9078     BLO_read_data_address(reader, &ln->next);
9079     if (ln->next != NULL && callback != NULL) {
9080       callback(reader, ln->next);
9081     }
9082     ln->prev = prev;
9083     prev = ln;
9084     ln = ln->next;
9085   }
9086   list->last = prev;
9087 }
9088 
BLO_read_list(BlendDataReader * reader,struct ListBase * list)9089 void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
9090 {
9091   BLO_read_list_cb(reader, list, NULL);
9092 }
9093 
BLO_read_int32_array(BlendDataReader * reader,int array_size,int32_t ** ptr_p)9094 void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr_p)
9095 {
9096   BLO_read_data_address(reader, ptr_p);
9097   if (BLO_read_requires_endian_switch(reader)) {
9098     BLI_endian_switch_int32_array(*ptr_p, array_size);
9099   }
9100 }
9101 
BLO_read_uint32_array(BlendDataReader * reader,int array_size,uint32_t ** ptr_p)9102 void BLO_read_uint32_array(BlendDataReader *reader, int array_size, uint32_t **ptr_p)
9103 {
9104   BLO_read_data_address(reader, ptr_p);
9105   if (BLO_read_requires_endian_switch(reader)) {
9106     BLI_endian_switch_uint32_array(*ptr_p, array_size);
9107   }
9108 }
9109 
BLO_read_float_array(BlendDataReader * reader,int array_size,float ** ptr_p)9110 void BLO_read_float_array(BlendDataReader *reader, int array_size, float **ptr_p)
9111 {
9112   BLO_read_data_address(reader, ptr_p);
9113   if (BLO_read_requires_endian_switch(reader)) {
9114     BLI_endian_switch_float_array(*ptr_p, array_size);
9115   }
9116 }
9117 
BLO_read_float3_array(BlendDataReader * reader,int array_size,float ** ptr_p)9118 void BLO_read_float3_array(BlendDataReader *reader, int array_size, float **ptr_p)
9119 {
9120   BLO_read_float_array(reader, array_size * 3, ptr_p);
9121 }
9122 
BLO_read_double_array(BlendDataReader * reader,int array_size,double ** ptr_p)9123 void BLO_read_double_array(BlendDataReader *reader, int array_size, double **ptr_p)
9124 {
9125   BLO_read_data_address(reader, ptr_p);
9126   if (BLO_read_requires_endian_switch(reader)) {
9127     BLI_endian_switch_double_array(*ptr_p, array_size);
9128   }
9129 }
9130 
convert_pointer_array_64_to_32(BlendDataReader * reader,uint array_size,const uint64_t * src,uint32_t * dst)9131 static void convert_pointer_array_64_to_32(BlendDataReader *reader,
9132                                            uint array_size,
9133                                            const uint64_t *src,
9134                                            uint32_t *dst)
9135 {
9136   /* Match pointer conversion rules from bh4_from_bh8 and cast_pointer. */
9137   if (BLO_read_requires_endian_switch(reader)) {
9138     for (int i = 0; i < array_size; i++) {
9139       uint64_t ptr = src[i];
9140       BLI_endian_switch_uint64(&ptr);
9141       dst[i] = (uint32_t)(ptr >> 3);
9142     }
9143   }
9144   else {
9145     for (int i = 0; i < array_size; i++) {
9146       dst[i] = (uint32_t)(src[i] >> 3);
9147     }
9148   }
9149 }
9150 
convert_pointer_array_32_to_64(BlendDataReader * UNUSED (reader),uint array_size,const uint32_t * src,uint64_t * dst)9151 static void convert_pointer_array_32_to_64(BlendDataReader *UNUSED(reader),
9152                                            uint array_size,
9153                                            const uint32_t *src,
9154                                            uint64_t *dst)
9155 {
9156   /* Match pointer conversion rules from bh8_from_bh4 and cast_pointer_32_to_64. */
9157   for (int i = 0; i < array_size; i++) {
9158     dst[i] = src[i];
9159   }
9160 }
9161 
BLO_read_pointer_array(BlendDataReader * reader,void ** ptr_p)9162 void BLO_read_pointer_array(BlendDataReader *reader, void **ptr_p)
9163 {
9164   FileData *fd = reader->fd;
9165 
9166   void *orig_array = newdataadr(fd, *ptr_p);
9167   if (orig_array == NULL) {
9168     *ptr_p = NULL;
9169     return;
9170   }
9171 
9172   int file_pointer_size = fd->filesdna->pointer_size;
9173   int current_pointer_size = fd->memsdna->pointer_size;
9174 
9175   /* Over-allocation is fine, but might be better to pass the length as parameter. */
9176   int array_size = MEM_allocN_len(orig_array) / file_pointer_size;
9177 
9178   void *final_array = NULL;
9179 
9180   if (file_pointer_size == current_pointer_size) {
9181     /* No pointer conversion necessary. */
9182     final_array = orig_array;
9183   }
9184   else if (file_pointer_size == 8 && current_pointer_size == 4) {
9185     /* Convert pointers from 64 to 32 bit. */
9186     final_array = MEM_malloc_arrayN(array_size, 4, "new pointer array");
9187     convert_pointer_array_64_to_32(
9188         reader, array_size, (uint64_t *)orig_array, (uint32_t *)final_array);
9189     MEM_freeN(orig_array);
9190   }
9191   else if (file_pointer_size == 4 && current_pointer_size == 8) {
9192     /* Convert pointers from 32 to 64 bit. */
9193     final_array = MEM_malloc_arrayN(array_size, 8, "new pointer array");
9194     convert_pointer_array_32_to_64(
9195         reader, array_size, (uint32_t *)orig_array, (uint64_t *)final_array);
9196     MEM_freeN(orig_array);
9197   }
9198   else {
9199     BLI_assert(false);
9200   }
9201 
9202   *ptr_p = final_array;
9203 }
9204 
BLO_read_data_is_undo(BlendDataReader * reader)9205 bool BLO_read_data_is_undo(BlendDataReader *reader)
9206 {
9207   return reader->fd->memfile != NULL;
9208 }
9209 
BLO_read_lib_is_undo(BlendLibReader * reader)9210 bool BLO_read_lib_is_undo(BlendLibReader *reader)
9211 {
9212   return reader->fd->memfile != NULL;
9213 }
9214 
BLO_expand_id(BlendExpander * expander,ID * id)9215 void BLO_expand_id(BlendExpander *expander, ID *id)
9216 {
9217   expand_doit(expander->fd, expander->main, id);
9218 }
9219 
9220 /** \} */
9221