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, ®ion->panels);
4972
4973 BLO_read_list(reader, ®ion->panels_category_active);
4974
4975 BLO_read_list(reader, ®ion->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, ®ion->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, ®ion->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, ®ion->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(®ion->panels_category);
5020 BLI_listbase_clear(®ion->handlers);
5021 BLI_listbase_clear(®ion->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(®ion->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