Fix for bug #8957: undo lost scenes assigned to screens.
[plumiferos.git] / source / blender / blenloader / intern / readfile.c
blob3322702a24335e2ad0f19e7085aa8ac7c27b8098
1 /*
2 * $Id: readfile.c 13029 2007-12-28 08:04:37Z bebraw $
4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
35 #include "zlib.h"
37 #ifdef WIN32
38 #include "winsock2.h"
39 #include "BLI_winstuff.h"
40 #endif
42 #include <stdio.h> // for printf fopen fwrite fclose sprintf FILE
43 #include <stdlib.h> // for getenv atoi
44 #include <fcntl.h> // for open
45 #include <string.h> // for strrchr strncmp strstr
46 #include <math.h> // for fabs
48 #ifndef WIN32
49 #include <unistd.h> // for read close
50 #include <sys/param.h> // for MAXPATHLEN
51 #else
52 #include <io.h> // for open close read
53 #endif
55 #include "nla.h"
57 #include "DNA_action_types.h"
58 #include "DNA_armature_types.h"
59 #include "DNA_ID.h"
60 #include "DNA_actuator_types.h"
61 #include "DNA_brush_types.h"
62 #include "DNA_camera_types.h"
63 #include "DNA_color_types.h"
64 #include "DNA_controller_types.h"
65 #include "DNA_constraint_types.h"
66 #include "DNA_curve_types.h"
67 #include "DNA_customdata_types.h"
68 #include "DNA_effect_types.h"
69 #include "DNA_fileglobal_types.h"
70 #include "DNA_group_types.h"
71 #include "DNA_ipo_types.h"
72 #include "DNA_image_types.h"
73 #include "DNA_key_types.h"
74 #include "DNA_lattice_types.h"
75 #include "DNA_lamp_types.h"
76 #include "DNA_meta_types.h"
77 #include "DNA_material_types.h"
78 #include "DNA_mesh_types.h"
79 #include "DNA_meshdata_types.h"
80 #include "DNA_modifier_types.h"
81 #include "DNA_nla_types.h"
82 #include "DNA_node_types.h"
83 #include "DNA_object_types.h"
84 #include "DNA_object_force.h"
85 #include "DNA_object_fluidsim.h" // NT
86 #include "DNA_oops_types.h"
87 #include "DNA_object_force.h"
88 #include "DNA_packedFile_types.h"
89 #include "DNA_property_types.h"
90 #include "DNA_text_types.h"
91 #include "DNA_view3d_types.h"
92 #include "DNA_screen_types.h"
93 #include "DNA_sensor_types.h"
94 #include "DNA_sdna_types.h"
95 #include "DNA_scene_types.h"
96 #include "DNA_sequence_types.h"
97 #include "DNA_sound_types.h"
98 #include "DNA_space_types.h"
99 #include "DNA_texture_types.h"
100 #include "DNA_userdef_types.h"
101 #include "DNA_vfont_types.h"
102 #include "DNA_world_types.h"
104 #include "MEM_guardedalloc.h"
105 #include "BLI_blenlib.h"
106 #include "BLI_arithb.h"
107 #include "BLI_storage_types.h" // for relname flags
109 #include "BDR_sculptmode.h"
111 #include "BKE_bad_level_calls.h" // for reopen_text build_seqar (from WHILE_SEQ) set_rects_butspace check_imasel_copy
113 #include "BKE_action.h"
114 #include "BKE_armature.h"
115 #include "BKE_colortools.h"
116 #include "BKE_constraint.h"
117 #include "BKE_curve.h"
118 #include "BKE_customdata.h"
119 #include "BKE_deform.h"
120 #include "BKE_depsgraph.h"
121 #include "BKE_effect.h" // for give_parteff
122 #include "BKE_global.h" // for G
123 #include "BKE_group.h"
124 #include "BKE_image.h"
125 #include "BKE_lattice.h"
126 #include "BKE_library.h" // for wich_libbase
127 #include "BKE_main.h" // for Main
128 #include "BKE_mesh.h" // for ME_ defines (patching)
129 #include "BKE_modifier.h"
130 #include "BKE_node.h" // for tree type defines
131 #include "BKE_object.h"
132 #include "BKE_property.h" // for get_property
133 #include "BKE_sca.h" // for init_actuator
134 #include "BKE_scene.h"
135 #include "BKE_softbody.h" // sbNew()
136 #include "BKE_texture.h" // for open_plugin_tex
137 #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
138 #include "BKE_idprop.h"
140 #include "BIF_butspace.h" // badlevel, for do_versions, patching event codes
141 #include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo
142 #include "BLO_readfile.h"
143 #include "BLO_undofile.h"
144 #include "BLO_readblenfile.h" // streaming read pipe, for BLO_readblenfile BLO_readblenfilememory
146 #include "multires.h"
148 #include "readfile.h"
150 #include "genfile.h"
152 #include "mydevice.h"
153 #include "blendef.h"
155 #include <errno.h>
158 Remark: still a weak point is the newadress() function, that doesnt solve reading from
159 multiple files at the same time
161 (added remark: oh, i thought that was solved? will look at that... (ton)
163 READ
164 - Existing Library (Main) push or free
165 - allocate new Main
166 - load file
167 - read SDNA
168 - for each LibBlock
169 - read LibBlock
170 - if a Library
171 - make a new Main
172 - attach ID's to it
173 - else
174 - read associated 'direct data'
175 - link direct data (internal and to LibBlock)
176 - read FileGlobal
177 - read USER data, only when indicated (file is ~/.B.blend)
178 - free file
179 - per Library (per Main)
180 - read file
181 - read SDNA
182 - find LibBlocks and attach IDs to Main
183 - if external LibBlock
184 - search all Main's
185 - or it's already read,
186 - or not read yet
187 - or make new Main
188 - per LibBlock
189 - read recursive
190 - read associated direct data
191 - link direct data (internal and to LibBlock)
192 - free file
193 - per Library with unread LibBlocks
194 - read file
195 - read SDNA
196 - per LibBlock
197 - read recursive
198 - read associated direct data
199 - link direct data (internal and to LibBlock)
200 - free file
201 - join all Mains
202 - link all LibBlocks and indirect pointers to libblocks
203 - initialize FileGlobal and copy pointers to Global
206 /* also occurs in library.c */
207 /* GS reads the memory pointed at in a specific ordering. There are,
208 * however two definitions for it. I have jotted them down here, both,
209 * but I think the first one is actually used. The thing is that
210 * big-endian systems might read this the wrong way round. OTOH, we
211 * constructed the IDs that are read out with this macro explicitly as
212 * well. I expect we'll sort it out soon... */
214 /* from blendef: */
215 #define GS(a) (*((short *)(a)))
217 /* from misc_util: flip the bytes from x */
218 /* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
220 // only used here in readfile.c
221 #define SWITCH_LONGINT(a) { \
222 char s_i, *p_i; \
223 p_i= (char *)&(a); \
224 s_i=p_i[0]; p_i[0]=p_i[7]; p_i[7]=s_i; \
225 s_i=p_i[1]; p_i[1]=p_i[6]; p_i[6]=s_i; \
226 s_i=p_i[2]; p_i[2]=p_i[5]; p_i[5]=s_i; \
227 s_i=p_i[3]; p_i[3]=p_i[4]; p_i[4]=s_i; }
229 /***/
231 typedef struct OldNew {
232 void *old, *newp;
233 int nr;
234 } OldNew;
236 typedef struct OldNewMap {
237 OldNew *entries;
238 int nentries, entriessize;
239 int sorted;
240 int lasthit;
241 } OldNewMap;
244 /* local prototypes */
245 static void *read_struct(FileData *fd, BHead *bh, char *blockname);
248 static OldNewMap *oldnewmap_new(void)
250 OldNewMap *onm= MEM_callocN(sizeof(*onm), "OldNewMap");
252 onm->entriessize= 1024;
253 onm->entries= MEM_mallocN(sizeof(*onm->entries)*onm->entriessize, "OldNewMap.entries");
255 return onm;
258 static int verg_oldnewmap(const void *v1, const void *v2)
260 const struct OldNew *x1=v1, *x2=v2;
262 if( x1->old > x2->old) return 1;
263 else if( x1->old < x2->old) return -1;
264 return 0;
268 static void oldnewmap_sort(FileData *fd)
270 qsort(fd->libmap->entries, fd->libmap->nentries, sizeof(OldNew), verg_oldnewmap);
271 fd->libmap->sorted= 1;
274 /* nr is zero for data, and ID code for libdata */
275 static void oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int nr)
277 OldNew *entry;
279 if(oldaddr==NULL || newaddr==NULL) return;
281 if (onm->nentries==onm->entriessize) {
282 int osize= onm->entriessize;
283 OldNew *oentries= onm->entries;
285 onm->entriessize*= 2;
286 onm->entries= MEM_mallocN(sizeof(*onm->entries)*onm->entriessize, "OldNewMap.entries");
288 memcpy(onm->entries, oentries, sizeof(*oentries)*osize);
289 MEM_freeN(oentries);
292 entry= &onm->entries[onm->nentries++];
293 entry->old= oldaddr;
294 entry->newp= newaddr;
295 entry->nr= nr;
298 static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr)
300 int i;
302 if (onm->lasthit<onm->nentries-1) {
303 OldNew *entry= &onm->entries[++onm->lasthit];
305 if (entry->old==addr) {
306 entry->nr++;
307 return entry->newp;
311 for (i=0; i<onm->nentries; i++) {
312 OldNew *entry= &onm->entries[i];
314 if (entry->old==addr) {
315 onm->lasthit= i;
317 entry->nr++;
318 return entry->newp;
322 return NULL;
325 /* for libdata, nr has ID code, no increment */
326 static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib)
328 int i;
330 if(addr==NULL) return NULL;
332 /* lasthit works fine for non-libdata, linking there is done in same sequence as writing */
333 if(onm->sorted) {
334 OldNew entry_s, *entry;
336 entry_s.old= addr;
338 entry= bsearch(&entry_s, onm->entries, onm->nentries, sizeof(OldNew), verg_oldnewmap);
339 if(entry) {
340 ID *id= entry->newp;
342 if (id && (!lib || id->lib)) {
343 return entry->newp;
348 for (i=0; i<onm->nentries; i++) {
349 OldNew *entry= &onm->entries[i];
351 if (entry->old==addr) {
352 ID *id= entry->newp;
354 if (id && (!lib || id->lib)) {
355 return entry->newp;
360 return NULL;
363 static void oldnewmap_free_unused(OldNewMap *onm)
365 int i;
367 for (i=0; i<onm->nentries; i++) {
368 OldNew *entry= &onm->entries[i];
369 if (entry->nr==0) {
370 MEM_freeN(entry->newp);
371 entry->newp= NULL;
376 static void oldnewmap_clear(OldNewMap *onm)
378 onm->nentries= 0;
379 onm->lasthit= 0;
382 static void oldnewmap_free(OldNewMap *onm)
384 MEM_freeN(onm->entries);
385 MEM_freeN(onm);
388 /***/
390 static void read_libraries(FileData *basefd, ListBase *mainlist);
392 /* ************ help functions ***************** */
394 static void add_main_to_main(Main *mainvar, Main *from)
396 ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY];
397 int a;
399 a= set_listbasepointers(mainvar, lbarray);
400 a= set_listbasepointers(from, fromarray);
401 while(a--) {
402 addlisttolist(lbarray[a], fromarray[a]);
406 void blo_join_main(ListBase *mainlist)
408 Main *tojoin, *mainl;
411 mainl= mainlist->first;
412 while ((tojoin= mainl->next)) {
413 add_main_to_main(mainl, tojoin);
414 BLI_remlink(mainlist, tojoin);
415 MEM_freeN(tojoin);
419 static void split_libdata(ListBase *lb, Main *first)
421 ListBase *lbn;
422 ID *id, *idnext;
423 Main *mainvar;
425 id= lb->first;
426 while(id) {
427 idnext= id->next;
428 if(id->lib) {
429 mainvar= first;
430 while(mainvar) {
431 if(mainvar->curlib==id->lib) {
432 lbn= wich_libbase(mainvar, GS(id->name));
433 BLI_remlink(lb, id);
434 BLI_addtail(lbn, id);
435 break;
437 mainvar= mainvar->next;
439 if(mainvar==0) printf("error split_libdata\n");
441 id= idnext;
445 void blo_split_main(ListBase *mainlist, Main *main)
447 ListBase *lbarray[MAX_LIBARRAY];
448 Library *lib;
449 int i;
451 mainlist->first= mainlist->last= main;
452 main->next= NULL;
454 if(main->library.first==NULL)
455 return;
457 for (lib= main->library.first; lib; lib= lib->id.next) {
458 Main *libmain= MEM_callocN(sizeof(Main), "libmain");
459 libmain->curlib= lib;
460 BLI_addtail(mainlist, libmain);
463 i= set_listbasepointers(main, lbarray);
464 while(i--)
465 split_libdata(lbarray[i], main->next);
468 /* removes things like /blah/blah/../../blah/ etc, then writes in *name the full path */
469 static void cleanup_path(const char *relabase, char *name)
471 char filename[FILE_MAXFILE];
473 BLI_splitdirstring(name, filename);
474 BLI_cleanup_dir(relabase, name);
475 strcat(name, filename);
478 static Main *blo_find_main(ListBase *mainlist, const char *name, const char *relabase)
480 Main *m;
481 Library *lib;
482 char name1[FILE_MAXDIR+FILE_MAXFILE];
484 strncpy(name1, name, sizeof(name1)-1);
485 cleanup_path(relabase, name1);
486 // printf("blo_find_main: original in %s\n", name);
487 // printf("blo_find_main: converted to %s\n", name1);
489 for (m= mainlist->first; m; m= m->next) {
490 char *libname= (m->curlib)?m->curlib->filename:m->name;
492 if (BLI_streq(name1, libname)) {
493 if(G.f & G_DEBUG) printf("blo_find_main: found library %s\n", libname);
494 return m;
498 m= MEM_callocN(sizeof(Main), "find_main");
499 BLI_addtail(mainlist, m);
501 lib= alloc_libblock(&m->library, ID_LI, "lib");
502 strncpy(lib->name, name, sizeof(lib->name)-1);
503 BLI_strncpy(lib->filename, name1, sizeof(lib->filename));
505 m->curlib= lib;
507 if(G.f & G_DEBUG) printf("blo_find_main: added new lib %s\n", name);
508 return m;
512 /* ************ FILE PARSING ****************** */
514 static void switch_endian_bh4(BHead4 *bhead)
516 /* the ID_.. codes */
517 if((bhead->code & 0xFFFF)==0) bhead->code >>=16;
519 if (bhead->code != ENDB) {
520 SWITCH_INT(bhead->len);
521 SWITCH_INT(bhead->SDNAnr);
522 SWITCH_INT(bhead->nr);
526 static void switch_endian_bh8(BHead8 *bhead)
528 /* the ID_.. codes */
529 if((bhead->code & 0xFFFF)==0) bhead->code >>=16;
531 if (bhead->code != ENDB) {
532 SWITCH_INT(bhead->len);
533 SWITCH_INT(bhead->SDNAnr);
534 SWITCH_INT(bhead->nr);
538 static void bh4_from_bh8(BHead *bhead, BHead8 *bhead8, int do_endian_swap)
540 BHead4 *bhead4 = (BHead4 *) bhead;
541 #if defined(WIN32) && !defined(FREE_WINDOWS)
542 __int64 old;
543 #else
544 long long old;
545 #endif
547 bhead4->code= bhead8->code;
548 bhead4->len= bhead8->len;
550 if (bhead4->code != ENDB) {
552 // why is this here ??
553 if (do_endian_swap) {
554 SWITCH_LONGINT(bhead8->old);
557 /* this patch is to avoid a long long being read from not-eight aligned positions
558 is necessary on any modern 64bit architecture) */
559 memcpy(&old, &bhead8->old, 8);
560 bhead4->old = (int) (old >> 3);
562 bhead4->SDNAnr= bhead8->SDNAnr;
563 bhead4->nr= bhead8->nr;
567 static void bh8_from_bh4(BHead *bhead, BHead4 *bhead4)
569 BHead8 *bhead8 = (BHead8 *) bhead;
571 bhead8->code= bhead4->code;
572 bhead8->len= bhead4->len;
574 if (bhead8->code != ENDB) {
575 bhead8->old= bhead4->old;
576 bhead8->SDNAnr= bhead4->SDNAnr;
577 bhead8->nr= bhead4->nr;
581 static BHeadN *get_bhead(FileData *fd)
583 BHead8 bhead8;
584 BHead4 bhead4;
585 BHead bhead;
586 BHeadN *new_bhead = 0;
587 int readsize;
589 if (fd) {
590 if ( ! fd->eof) {
592 // First read the bhead structure.
593 // Depending on the platform the file was written on this can
594 // be a big or little endian BHead4 or BHead8 structure.
596 // As usual 'ENDB' (the last *partial* bhead of the file)
597 // needs some special handling. We don't want to EOF just yet.
599 if (fd->flags & FD_FLAGS_FILE_POINTSIZE_IS_4) {
600 bhead4.code = DATA;
601 readsize = fd->read(fd, &bhead4, sizeof(bhead4));
603 if (readsize == sizeof(bhead4) || bhead4.code == ENDB) {
604 if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
605 switch_endian_bh4(&bhead4);
608 if (fd->flags & FD_FLAGS_POINTSIZE_DIFFERS) {
609 bh8_from_bh4(&bhead, &bhead4);
610 } else {
611 memcpy(&bhead, &bhead4, sizeof(bhead));
613 } else {
614 fd->eof = 1;
615 bhead.len= 0;
617 } else {
618 bhead8.code = DATA;
619 readsize = fd->read(fd, &bhead8, sizeof(bhead8));
621 if (readsize == sizeof(bhead8) || bhead8.code == ENDB) {
622 if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
623 switch_endian_bh8(&bhead8);
626 if (fd->flags & FD_FLAGS_POINTSIZE_DIFFERS) {
627 bh4_from_bh8(&bhead, &bhead8, (fd->flags & FD_FLAGS_SWITCH_ENDIAN));
628 } else {
629 memcpy(&bhead, &bhead8, sizeof(bhead));
631 } else {
632 fd->eof = 1;
633 bhead.len= 0;
637 /* make sure people are not trying to pass bad blend files */
638 if (bhead.len < 0) fd->eof = 1;
640 // bhead now contains the (converted) bhead structure. Now read
641 // the associated data and put everything in a BHeadN (creative naming !)
643 if ( ! fd->eof) {
644 new_bhead = MEM_mallocN(sizeof(BHeadN) + bhead.len, "new_bhead");
645 if (new_bhead) {
646 new_bhead->next = new_bhead->prev = 0;
647 new_bhead->bhead = bhead;
649 readsize = fd->read(fd, new_bhead + 1, bhead.len);
651 if (readsize != bhead.len) {
652 fd->eof = 1;
653 MEM_freeN(new_bhead);
654 new_bhead = 0;
656 } else {
657 fd->eof = 1;
663 // We've read a new block. Now add it to the list
664 // of blocks.
666 if (new_bhead) {
667 BLI_addtail(&fd->listbase, new_bhead);
670 return(new_bhead);
673 BHead *blo_firstbhead(FileData *fd)
675 BHeadN *new_bhead;
676 BHead *bhead = 0;
678 // Rewind the file
679 // Read in a new block if necessary
681 new_bhead = fd->listbase.first;
682 if (new_bhead == 0) {
683 new_bhead = get_bhead(fd);
686 if (new_bhead) {
687 bhead = &new_bhead->bhead;
690 return(bhead);
693 BHead *blo_prevbhead(FileData *fd, BHead *thisblock)
695 BHeadN *bheadn= (BHeadN *) (((char *) thisblock) - (int) (&((BHeadN*)0)->bhead));
696 BHeadN *prev= bheadn->prev;
698 return prev?&prev->bhead:NULL;
701 BHead *blo_nextbhead(FileData *fd, BHead *thisblock)
703 BHeadN *new_bhead = NULL;
704 BHead *bhead = NULL;
706 if (thisblock) {
707 // bhead is actually a sub part of BHeadN
708 // We calculate the BHeadN pointer from the BHead pointer below
709 new_bhead = (BHeadN *) (((char *) thisblock) - (int) (&((BHeadN*)0)->bhead));
711 // get the next BHeadN. If it doesn't exist we read in the next one
712 new_bhead = new_bhead->next;
713 if (new_bhead == 0) {
714 new_bhead = get_bhead(fd);
718 if (new_bhead) {
719 // here we do the reverse:
720 // go from the BHeadN pointer to the BHead pointer
721 bhead = &new_bhead->bhead;
724 return(bhead);
727 #if 0
728 static void get_blender_subversion(FileData *fd)
730 BHead *bhead;
732 for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
733 if (bhead->code==GLOB) {
734 FileGlobal *fg= read_struct(fd, bhead, "Global");
735 fd->filesubversion= fg->subversion;
736 fd->fileminversion= fg->minversion;
737 fd->fileminsubversion= fg->minsubversion;
738 MEM_freeN(fg);
739 return;
741 else if (bhead->code==ENDB)
742 break;
745 #endif
747 static void decode_blender_header(FileData *fd)
749 char header[SIZEOFBLENDERHEADER], num[4];
750 int readsize;
752 // read in the header data
753 readsize = fd->read(fd, header, sizeof(header));
755 if (readsize == sizeof(header)) {
756 if(strncmp(header, "BLENDER", 7) == 0) {
757 int remove_this_endian_test= 1;
759 fd->flags |= FD_FLAGS_FILE_OK;
761 // what size are pointers in the file ?
762 if(header[7]=='_') {
763 fd->flags |= FD_FLAGS_FILE_POINTSIZE_IS_4;
764 if (sizeof(void *) != 4) {
765 fd->flags |= FD_FLAGS_POINTSIZE_DIFFERS;
767 } else {
768 if (sizeof(void *) != 8) {
769 fd->flags |= FD_FLAGS_POINTSIZE_DIFFERS;
773 // is the file saved in a different endian
774 // than we need ?
775 if (((((char*)&remove_this_endian_test)[0]==1)?L_ENDIAN:B_ENDIAN) != ((header[8]=='v')?L_ENDIAN:B_ENDIAN)) {
776 fd->flags |= FD_FLAGS_SWITCH_ENDIAN;
779 // get the version number
781 memcpy(num, header+9, 3);
782 num[3] = 0;
783 fd->fileversion = atoi(num);
788 static int read_file_dna(FileData *fd)
790 BHead *bhead;
792 for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
793 if (bhead->code==DNA1) {
794 int do_endian_swap= (fd->flags&FD_FLAGS_SWITCH_ENDIAN)?1:0;
796 fd->filesdna= dna_sdna_from_data(&bhead[1], bhead->len, do_endian_swap);
797 if (fd->filesdna) {
799 fd->compflags= dna_get_structDNA_compareflags(fd->filesdna, fd->memsdna);
800 /* used to retrieve ID names from (bhead+1) */
801 fd->id_name_offs= dna_elem_offset(fd->filesdna, "ID", "char", "name[]");
804 return 1;
805 } else if (bhead->code==ENDB)
806 break;
809 return 0;
812 static int fd_read_from_file(FileData *filedata, void *buffer, int size)
814 int readsize = read(filedata->filedes, buffer, size);
816 if (readsize < 0) {
817 readsize = EOF;
818 } else {
819 filedata->seek += readsize;
822 return (readsize);
825 static int fd_read_gzip_from_file(FileData *filedata, void *buffer, int size)
827 int readsize = gzread(filedata->gzfiledes, buffer, size);
829 if (readsize < 0) {
830 readsize = EOF;
831 } else {
832 filedata->seek += readsize;
835 return (readsize);
838 static int fd_read_from_memory(FileData *filedata, void *buffer, int size)
840 // don't read more bytes then there are available in the buffer
841 int readsize = MIN2(size, filedata->buffersize - filedata->seek);
843 memcpy(buffer, filedata->buffer + filedata->seek, readsize);
844 filedata->seek += readsize;
846 return (readsize);
849 static int fd_read_from_memfile(FileData *filedata, void *buffer, int size)
851 static unsigned int seek= 1<<30; /* the current position */
852 static unsigned int offset= 0; /* size of previous chunks */
853 static MemFileChunk *chunk=NULL;
855 if(size==0) return 0;
857 if(seek != (unsigned int)filedata->seek) {
858 chunk= filedata->memfile->chunks.first;
859 seek= 0;
861 while(chunk) {
862 if(seek + chunk->size > (unsigned) filedata->seek) break;
863 seek+= chunk->size;
864 chunk= chunk->next;
866 offset= seek;
867 seek= filedata->seek;
870 if(chunk) {
871 /* first check if it's on the end if current chunk */
872 if( seek-offset == chunk->size) {
873 offset+= chunk->size;
874 chunk= chunk->next;
877 /* debug, should never happen */
878 if(chunk==NULL) {
879 printf("illegal read, chunk zero\n");
880 return 0;
882 else if( (seek-offset)+size > chunk->size) {
883 size= chunk->size - (seek-offset);
884 printf("chunk too large, clipped to %d\n", size);
887 memcpy(buffer, chunk->buf + (seek-offset), size);
888 filedata->seek += size;
889 seek+= size;
891 return (size);
894 return 0;
897 static FileData *filedata_new(void)
899 extern unsigned char DNAstr[]; /* DNA.c */
900 extern int DNAlen;
901 FileData *fd = MEM_callocN(sizeof(FileData), "FileData");
903 fd->filedes = -1;
904 fd->gzfiledes = NULL;
906 /* XXX, this doesn't need to be done all the time,
907 * but it keeps us reentrant, remove once we have
908 * a lib that provides a nice lock. - zr
910 fd->memsdna = dna_sdna_from_data(DNAstr, DNAlen, 0);
912 fd->datamap = oldnewmap_new();
913 fd->globmap = oldnewmap_new();
914 fd->libmap = oldnewmap_new();
916 return fd;
919 static FileData *blo_decode_and_check(FileData *fd, BlendReadError *error_r)
921 decode_blender_header(fd);
923 if (fd->flags & FD_FLAGS_FILE_OK) {
924 if (!read_file_dna(fd)) {
925 *error_r = BRE_INCOMPLETE;
926 blo_freefiledata(fd);
927 fd= NULL;
930 else {
931 *error_r = BRE_NOT_A_BLEND;
932 blo_freefiledata(fd);
933 fd= NULL;
936 return fd;
939 /* cannot be called with relative paths anymore! */
940 /* on each new library added, it now checks for the current FileData and expands relativeness */
941 FileData *blo_openblenderfile(char *name, BlendReadError *error_r)
943 gzFile gzfile;
945 gzfile= gzopen(name, "rb");
947 if (NULL == gzfile) {
948 *error_r = BRE_UNABLE_TO_OPEN;
949 return NULL;
950 } else {
951 FileData *fd = filedata_new();
952 fd->gzfiledes = gzfile;
953 BLI_strncpy(fd->filename, name, sizeof(fd->filename)); // now only in use by library append
954 fd->read = fd_read_gzip_from_file;
956 return blo_decode_and_check(fd, error_r);
960 FileData *blo_openblendermemory(void *mem, int memsize, BlendReadError *error_r)
962 if (!mem || memsize<SIZEOFBLENDERHEADER) {
963 *error_r = mem?BRE_UNABLE_TO_READ:BRE_UNABLE_TO_OPEN;
964 return NULL;
965 } else {
966 FileData *fd= filedata_new();
967 fd->buffer= mem;
968 fd->buffersize= memsize;
969 fd->read= fd_read_from_memory;
970 fd->flags|= FD_FLAGS_NOT_MY_BUFFER;
972 return blo_decode_and_check(fd, error_r);
976 FileData *blo_openblendermemfile(MemFile *memfile, BlendReadError *error_r)
978 if (!memfile) {
979 *error_r = BRE_UNABLE_TO_OPEN;
980 return NULL;
981 } else {
982 FileData *fd= filedata_new();
983 fd->memfile= memfile;
985 fd->read= fd_read_from_memfile;
986 fd->flags|= FD_FLAGS_NOT_MY_BUFFER;
988 return blo_decode_and_check(fd, error_r);
993 void blo_freefiledata(FileData *fd)
995 if (fd) {
997 if (fd->filedes != -1) {
998 close(fd->filedes);
1001 if (fd->gzfiledes != NULL)
1003 gzclose(fd->gzfiledes);
1006 if (fd->buffer && !(fd->flags & FD_FLAGS_NOT_MY_BUFFER)) {
1007 MEM_freeN(fd->buffer);
1008 fd->buffer = 0;
1011 // Free all BHeadN data blocks
1012 BLI_freelistN(&fd->listbase);
1014 if (fd->memsdna)
1015 dna_freestructDNA(fd->memsdna);
1016 if (fd->filesdna)
1017 dna_freestructDNA(fd->filesdna);
1018 if (fd->compflags)
1019 MEM_freeN(fd->compflags);
1021 if (fd->datamap)
1022 oldnewmap_free(fd->datamap);
1023 if (fd->globmap)
1024 oldnewmap_free(fd->globmap);
1025 if (fd->imamap)
1026 oldnewmap_free(fd->imamap);
1027 if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP))
1028 oldnewmap_free(fd->libmap);
1029 if (fd->bheadmap)
1030 MEM_freeN(fd->bheadmap);
1032 MEM_freeN(fd);
1036 /* ************ DIV ****************** */
1038 int BLO_has_bfile_extension(char *str)
1040 return (BLI_testextensie(str, ".ble") || BLI_testextensie(str, ".blend")||BLI_testextensie(str, ".blend.gz"));
1043 /* ************** OLD POINTERS ******************* */
1045 static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */
1047 return oldnewmap_lookup_and_inc(fd->datamap, adr);
1050 static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with global linking */
1052 return oldnewmap_lookup_and_inc(fd->globmap, adr);
1055 static void *newimaadr(FileData *fd, void *adr) /* used to restore image data after undo */
1057 if(fd->imamap && adr)
1058 return oldnewmap_lookup_and_inc(fd->imamap, adr);
1059 return NULL;
1063 static void *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */
1065 return oldnewmap_liblookup(fd->libmap, adr, lib);
1068 static void *newlibadr_us(FileData *fd, void *lib, void *adr) /* increases user number */
1070 ID *id= newlibadr(fd, lib, adr);
1072 if(id)
1073 id->us++;
1075 return id;
1078 static void change_idid_adr_fd(FileData *fd, void *old, void *new)
1080 int i;
1082 for (i=0; i<fd->libmap->nentries; i++) {
1083 OldNew *entry= &fd->libmap->entries[i];
1085 if (old==entry->newp && entry->nr==ID_ID) {
1086 entry->newp= new;
1087 if(new) entry->nr= GS( ((ID *)new)->name );
1088 break;
1093 static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, void *new)
1095 Main *mainptr;
1097 for(mainptr= mainlist->first; mainptr; mainptr= mainptr->next) {
1098 FileData *fd;
1100 if(mainptr->curlib) fd= mainptr->curlib->filedata;
1101 else fd= basefd;
1103 if(fd) {
1104 change_idid_adr_fd(fd, old, new);
1109 /* assumed; G.main still exists */
1110 void blo_make_image_pointer_map(FileData *fd)
1112 Image *ima= G.main->image.first;
1113 Scene *sce= G.main->scene.first;
1115 fd->imamap= oldnewmap_new();
1117 for(;ima; ima= ima->id.next) {
1118 Link *ibuf= ima->ibufs.first;
1119 for(; ibuf; ibuf= ibuf->next)
1120 oldnewmap_insert(fd->imamap, ibuf, ibuf, 0);
1122 for(; sce; sce= sce->id.next) {
1123 if(sce->nodetree) {
1124 bNode *node;
1125 for(node= sce->nodetree->nodes.first; node; node= node->next)
1126 oldnewmap_insert(fd->imamap, node->preview, node->preview, 0);
1131 /* set G.main image ibufs to zero if it has been restored */
1132 /* this works because freeing G.main only happens after this call */
1133 void blo_end_image_pointer_map(FileData *fd)
1135 OldNew *entry= fd->imamap->entries;
1136 Image *ima= G.main->image.first;
1137 Scene *sce= G.main->scene.first;
1138 int i;
1140 /* used entries were restored, so we put them to zero */
1141 for (i=0; i<fd->imamap->nentries; i++, entry++) {
1142 if (entry->nr>0)
1143 entry->newp= NULL;
1146 for(;ima; ima= ima->id.next) {
1147 Link *ibuf, *next;
1149 /* this mirrors direct_link_image */
1150 for(ibuf= ima->ibufs.first; ibuf; ibuf= next) {
1151 next= ibuf->next;
1152 if(NULL==newimaadr(fd, ibuf)) { /* so was restored */
1153 BLI_remlink(&ima->ibufs, ibuf);
1154 ima->bindcode= 0;
1158 for(; sce; sce= sce->id.next) {
1159 if(sce->nodetree) {
1160 bNode *node;
1161 for(node= sce->nodetree->nodes.first; node; node= node->next)
1162 node->preview= newimaadr(fd, node->preview);
1167 /* undo file support: add all library pointers in lookup */
1168 void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd)
1170 Main *ptr= mainlist->first;
1171 ListBase *lbarray[MAX_LIBARRAY];
1173 for(ptr= ptr->next; ptr; ptr= ptr->next) {
1174 int i= set_listbasepointers(ptr, lbarray);
1175 while(i--) {
1176 ID *id;
1177 for(id= lbarray[i]->first; id; id= id->next)
1178 oldnewmap_insert(fd->libmap, id, id, GS(id->name));
1184 /* ********** END OLD POINTERS ****************** */
1185 /* ********** READ FILE ****************** */
1187 static void switch_endian_structs(struct SDNA *filesdna, BHead *bhead)
1189 int blocksize, nblocks;
1190 char *data;
1192 data= (char *)(bhead+1);
1193 blocksize= filesdna->typelens[ filesdna->structs[bhead->SDNAnr][0] ];
1195 nblocks= bhead->nr;
1196 while(nblocks--) {
1197 dna_switch_endian_struct(filesdna, bhead->SDNAnr, data);
1199 data+= blocksize;
1203 static void *read_struct(FileData *fd, BHead *bh, char *blockname)
1205 void *temp= NULL;
1207 if (bh->len) {
1208 /* switch is based on file dna */
1209 if (bh->SDNAnr && (fd->flags & FD_FLAGS_SWITCH_ENDIAN))
1210 switch_endian_structs(fd->filesdna, bh);
1212 if (fd->compflags[bh->SDNAnr]) { /* flag==0: doesn't exist anymore */
1213 if(fd->compflags[bh->SDNAnr]==2) {
1214 temp= dna_reconstruct(fd->memsdna, fd->filesdna, fd->compflags, bh->SDNAnr, bh->nr, (bh+1));
1215 } else {
1216 temp= MEM_mallocN(bh->len, blockname);
1217 memcpy(temp, (bh+1), bh->len);
1222 return temp;
1225 static void link_list(FileData *fd, ListBase *lb) /* only direct data */
1227 Link *ln, *prev;
1229 if(lb->first==NULL) return;
1231 lb->first= newdataadr(fd, lb->first);
1232 ln= lb->first;
1233 prev= NULL;
1234 while(ln) {
1235 ln->next= newdataadr(fd, ln->next);
1236 ln->prev= prev;
1237 prev= ln;
1238 ln= ln->next;
1240 lb->last= prev;
1243 static void link_glob_list(FileData *fd, ListBase *lb) /* for glob data */
1245 Link *ln, *prev;
1246 void *poin;
1248 if(lb->first==0) return;
1249 poin= newdataadr(fd, lb->first);
1250 if(lb->first) {
1251 oldnewmap_insert(fd->globmap, lb->first, poin, 0);
1253 lb->first= poin;
1255 ln= lb->first;
1256 prev= 0;
1257 while(ln) {
1258 poin= newdataadr(fd, ln->next);
1259 if(ln->next) {
1260 oldnewmap_insert(fd->globmap, ln->next, poin, 0);
1262 ln->next= poin;
1263 ln->prev= prev;
1264 prev= ln;
1265 ln= ln->next;
1267 lb->last= prev;
1270 static void test_pointer_array(FileData *fd, void **mat)
1272 #if defined(WIN32) && !defined(FREE_WINDOWS)
1273 __int64 *lpoin, *lmat;
1274 #else
1275 long long *lpoin, *lmat;
1276 #endif
1277 int len, *ipoin, *imat;
1279 /* manually convert the pointer array in
1280 * the old dna format to a pointer array in
1281 * the new dna format.
1283 if(*mat) {
1284 len= MEM_allocN_len(*mat)/fd->filesdna->pointerlen;
1286 if(fd->filesdna->pointerlen==8 && fd->memsdna->pointerlen==4) {
1287 ipoin=imat= MEM_mallocN( len*4, "newmatar");
1288 lpoin= *mat;
1290 while(len-- > 0) {
1291 if((fd->flags & FD_FLAGS_SWITCH_ENDIAN))
1292 SWITCH_LONGINT(*lpoin);
1293 *ipoin= (int) ((*lpoin) >> 3);
1294 ipoin++;
1295 lpoin++;
1297 MEM_freeN(*mat);
1298 *mat= imat;
1301 if(fd->filesdna->pointerlen==4 && fd->memsdna->pointerlen==8) {
1302 lpoin=lmat= MEM_mallocN( len*8, "newmatar");
1303 ipoin= *mat;
1305 while(len-- > 0) {
1306 *lpoin= *ipoin;
1307 ipoin++;
1308 lpoin++;
1310 MEM_freeN(*mat);
1311 *mat= lmat;
1316 /* ************ READ ID Properties *************** */
1318 void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd);
1319 void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, void *fd);
1321 void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, void *fd)
1323 int i;
1325 /*since we didn't save the extra buffer, set totallen to len.*/
1326 prop->totallen = prop->len;
1327 prop->data.pointer = newdataadr(fd, prop->data.pointer);
1329 if (switch_endian) {
1330 for (i=0; i<prop->len; i++) {
1331 SWITCH_INT(((int*)prop->data.pointer)[i]);
1336 void IDP_DirectLinkString(IDProperty *prop, int switch_endian, void *fd)
1338 /*since we didn't save the extra string buffer, set totallen to len.*/
1339 prop->totallen = prop->len;
1340 prop->data.pointer = newdataadr(fd, prop->data.pointer);
1343 void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, void *fd)
1345 ListBase *lb = &prop->data.group;
1346 IDProperty *loop;
1348 link_list(fd, lb);
1350 /*Link child id properties now*/
1351 for (loop=prop->data.group.first; loop; loop=loop->next) {
1352 IDP_DirectLinkProperty(loop, switch_endian, fd);
1356 void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd)
1358 switch (prop->type) {
1359 case IDP_GROUP:
1360 IDP_DirectLinkGroup(prop, switch_endian, fd);
1361 break;
1362 case IDP_STRING:
1363 IDP_DirectLinkString(prop, switch_endian, fd);
1364 break;
1365 case IDP_ARRAY:
1366 IDP_DirectLinkArray(prop, switch_endian, fd);
1367 break;
1371 /*stub function*/
1372 void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, void *fd)
1376 /* ************ READ Brush *************** */
1377 /* library brush linking after fileread */
1378 static void lib_link_brush(FileData *fd, Main *main)
1380 Brush *brush;
1381 MTex *mtex;
1382 int a;
1384 /* only link ID pointers */
1385 for(brush= main->brush.first; brush; brush= brush->id.next) {
1386 if(brush->id.flag & LIB_NEEDLINK) {
1387 brush->id.flag -= LIB_NEEDLINK;
1389 for(a=0; a<MAX_MTEX; a++) {
1390 mtex= brush->mtex[a];
1391 if(mtex)
1392 mtex->tex= newlibadr_us(fd, brush->id.lib, mtex->tex);
1398 static void direct_link_brush(FileData *fd, Brush *brush)
1400 /* brush itself has been read */
1401 int a;
1403 for(a=0; a<MAX_MTEX; a++)
1404 brush->mtex[a]= newdataadr(fd, brush->mtex[a]);
1407 /* ************ READ CurveMapping *************** */
1409 /* cuma itself has been read! */
1410 static void direct_link_curvemapping(FileData *fd, CurveMapping *cumap)
1412 int a;
1414 /* flag seems to be able to hang? Maybe old files... not bad to clear anyway */
1415 cumap->flag &= ~CUMA_PREMULLED;
1417 for(a=0; a<CM_TOT; a++) {
1418 cumap->cm[a].curve= newdataadr(fd, cumap->cm[a].curve);
1419 cumap->cm[a].table= NULL;
1423 /* levmap itself has been read! */
1424 static void direct_link_levelmapping(FileData *fd, LevelMapping *levmap)
1426 levmap->data= NULL;
1427 levmap->dataR= NULL;
1428 levmap->dataG= NULL;
1429 levmap->dataB= NULL;
1432 /* ************ READ NODE TREE *************** */
1434 /* singe node tree (also used for material/scene trees), ntree is not NULL */
1435 static void lib_link_ntree(FileData *fd, ID *id, bNodeTree *ntree)
1437 bNode *node;
1439 for(node= ntree->nodes.first; node; node= node->next)
1440 node->id= newlibadr_us(fd, id->lib, node->id);
1443 /* library ntree linking after fileread */
1444 static void lib_link_nodetree(FileData *fd, Main *main)
1446 bNodeTree *ntree;
1448 /* only link ID pointers */
1449 for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) {
1450 if(ntree->id.flag & LIB_NEEDLINK) {
1451 ntree->id.flag -= LIB_NEEDLINK;
1452 lib_link_ntree(fd, &ntree->id, ntree);
1457 /* verify types for nodes and groups, all data has to be read */
1458 static void lib_verify_nodetree(Main *main)
1460 Scene *sce;
1461 Material *ma;
1462 bNodeTree *ntree;
1464 /* now create the own typeinfo structs an verify nodes */
1465 /* here we still assume no groups in groups */
1466 for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) {
1467 ntreeVerifyTypes(ntree); /* internal nodes, no groups! */
1468 ntreeMakeOwnType(ntree); /* for group usage */
1471 /* now verify all types in material trees, groups are set OK now */
1472 for(ma= main->mat.first; ma; ma= ma->id.next) {
1473 if(ma->nodetree)
1474 ntreeVerifyTypes(ma->nodetree);
1476 /* and scene trees */
1477 for(sce= main->scene.first; sce; sce= sce->id.next) {
1478 if(sce->nodetree)
1479 ntreeVerifyTypes(sce->nodetree);
1485 /* ntree itself has been read! */
1486 static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
1488 /* note: writing and reading goes in sync, for speed */
1489 bNode *node;
1490 bNodeSocket *sock;
1491 bNodeLink *link;
1493 ntree->init= 0; /* to set callbacks and force setting types */
1494 ntree->owntype= NULL;
1495 ntree->timecursor= NULL;
1497 link_list(fd, &ntree->nodes);
1498 for(node= ntree->nodes.first; node; node= node->next) {
1499 node->storage= newdataadr(fd, node->storage);
1500 if(node->storage) {
1502 /* could be handlerized at some point */
1503 if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB))
1504 direct_link_curvemapping(fd, node->storage);
1505 else if(ntree->type==NTREE_COMPOSIT) {
1506 if( ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB))
1507 direct_link_curvemapping(fd, node->storage);
1508 else if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
1509 ((ImageUser *)node->storage)->ok= 1;
1512 link_list(fd, &node->inputs);
1513 link_list(fd, &node->outputs);
1515 link_list(fd, &ntree->links);
1517 /* and we connect the rest */
1518 for(node= ntree->nodes.first; node; node= node->next) {
1519 node->preview= newimaadr(fd, node->preview);
1520 node->lasty= 0;
1521 for(sock= node->inputs.first; sock; sock= sock->next)
1522 sock->link= newdataadr(fd, sock->link);
1523 for(sock= node->outputs.first; sock; sock= sock->next)
1524 sock->ns.data= NULL;
1526 for(link= ntree->links.first; link; link= link->next) {
1527 link->fromnode= newdataadr(fd, link->fromnode);
1528 link->tonode= newdataadr(fd, link->tonode);
1529 link->fromsock= newdataadr(fd, link->fromsock);
1530 link->tosock= newdataadr(fd, link->tosock);
1533 /* set selin and selout */
1534 for(node= ntree->nodes.first; node; node= node->next) {
1535 for(sock= node->inputs.first; sock; sock= sock->next) {
1536 if(sock->flag & SOCK_SEL) {
1537 ntree->selin= sock;
1538 break;
1541 for(sock= node->outputs.first; sock; sock= sock->next) {
1542 if(sock->flag & SOCK_SEL) {
1543 ntree->selout= sock;
1544 break;
1549 /* type verification is in lib-link */
1552 /* ************ READ PACKEDFILE *************** */
1554 static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf)
1556 PackedFile *pf= newdataadr(fd, oldpf);
1558 if (pf) {
1559 pf->data= newdataadr(fd, pf->data);
1562 return pf;
1565 /* ************ READ IMAGE PREVIEW *************** */
1567 static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_prv)
1569 PreviewImage *prv= newdataadr(fd, old_prv);
1571 if (prv) {
1572 prv->rect = newdataadr(fd, prv->rect);
1575 return prv;
1578 /* ************ READ SCRIPTLINK *************** */
1580 static void lib_link_scriptlink(FileData *fd, ID *id, ScriptLink *slink)
1582 int i;
1584 for(i=0; i<slink->totscript; i++) {
1585 slink->scripts[i]= newlibadr(fd, id->lib, slink->scripts[i]);
1589 static void direct_link_scriptlink(FileData *fd, ScriptLink *slink)
1591 slink->scripts= newdataadr(fd, slink->scripts);
1592 test_pointer_array(fd, (void **)&slink->scripts);
1594 slink->flag= newdataadr(fd, slink->flag);
1596 if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
1597 int a;
1599 for(a=0; a<slink->totscript; a++) {
1600 SWITCH_SHORT(slink->flag[a]);
1605 /* ************ READ ARMATURE ***************** */
1607 static void lib_link_nlastrips(FileData *fd, ID *id, ListBase *striplist)
1609 bActionStrip *strip;
1610 bActionModifier *amod;
1612 for (strip=striplist->first; strip; strip=strip->next){
1613 strip->object = newlibadr(fd, id->lib, strip->object);
1614 strip->act = newlibadr_us(fd, id->lib, strip->act);
1615 strip->ipo = newlibadr(fd, id->lib, strip->ipo);
1616 for(amod= strip->modifiers.first; amod; amod= amod->next)
1617 amod->ob= newlibadr(fd, id->lib, amod->ob);
1621 static void lib_link_constraint_channels(FileData *fd, ID *id, ListBase *chanbase)
1623 bConstraintChannel *chan;
1625 for (chan=chanbase->first; chan; chan=chan->next){
1626 chan->ipo = newlibadr_us(fd, id->lib, chan->ipo);
1630 static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
1632 bConstraint *con;
1634 for (con = conlist->first; con; con=con->next) {
1635 /* patch for error introduced by changing constraints (dunno how) */
1636 /* if con->data type changes, dna cannot resolve the pointer! (ton) */
1637 if(con->data==NULL) {
1638 con->type= CONSTRAINT_TYPE_NULL;
1641 switch (con->type) {
1642 case CONSTRAINT_TYPE_PYTHON:
1644 bPythonConstraint *data;
1645 data= (bPythonConstraint*)con->data;
1646 data->tar = newlibadr(fd, id->lib, data->tar);
1647 data->text = newlibadr(fd, id->lib, data->text);
1648 //IDP_LibLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
1650 break;
1651 case CONSTRAINT_TYPE_ACTION:
1653 bActionConstraint *data;
1654 data= ((bActionConstraint*)con->data);
1655 data->tar = newlibadr(fd, id->lib, data->tar);
1656 data->act = newlibadr(fd, id->lib, data->act);
1658 break;
1659 case CONSTRAINT_TYPE_LOCLIKE:
1661 bLocateLikeConstraint *data;
1662 data= ((bLocateLikeConstraint*)con->data);
1663 data->tar = newlibadr(fd, id->lib, data->tar);
1665 break;
1666 case CONSTRAINT_TYPE_ROTLIKE:
1668 bRotateLikeConstraint *data;
1669 data= ((bRotateLikeConstraint*)con->data);
1670 data->tar = newlibadr(fd, id->lib, data->tar);
1672 break;
1673 case CONSTRAINT_TYPE_SIZELIKE:
1675 bSizeLikeConstraint *data;
1676 data= ((bSizeLikeConstraint*)con->data);
1677 data->tar = newlibadr(fd, id->lib, data->tar);
1679 break;
1680 case CONSTRAINT_TYPE_KINEMATIC:
1682 bKinematicConstraint *data;
1683 data = ((bKinematicConstraint*)con->data);
1684 data->tar = newlibadr(fd, id->lib, data->tar);
1686 break;
1687 case CONSTRAINT_TYPE_TRACKTO:
1689 bTrackToConstraint *data;
1690 data = ((bTrackToConstraint*)con->data);
1691 data->tar = newlibadr(fd, id->lib, data->tar);
1693 break;
1694 case CONSTRAINT_TYPE_MINMAX:
1696 bMinMaxConstraint *data;
1697 data = ((bMinMaxConstraint*)con->data);
1698 data->tar = newlibadr(fd, id->lib, data->tar);
1700 break;
1701 case CONSTRAINT_TYPE_LOCKTRACK:
1703 bLockTrackConstraint *data;
1704 data= ((bLockTrackConstraint*)con->data);
1705 data->tar = newlibadr(fd, id->lib, data->tar);
1707 break;
1708 case CONSTRAINT_TYPE_FOLLOWPATH:
1710 bFollowPathConstraint *data;
1711 data= ((bFollowPathConstraint*)con->data);
1712 data->tar = newlibadr(fd, id->lib, data->tar);
1714 break;
1715 case CONSTRAINT_TYPE_DISTANCELIMIT:
1717 bDistanceLimitConstraint *data;
1718 data= ((bDistanceLimitConstraint*)con->data);
1719 data->tar = newlibadr(fd, id->lib, data->tar);
1721 break;
1722 case CONSTRAINT_TYPE_STRETCHTO:
1724 bStretchToConstraint *data;
1725 data= ((bStretchToConstraint*)con->data);
1726 data->tar = newlibadr(fd, id->lib, data->tar);
1728 break;
1729 case CONSTRAINT_TYPE_RIGIDBODYJOINT:
1731 bRigidBodyJointConstraint *data;
1732 data= ((bRigidBodyJointConstraint*)con->data);
1733 data->tar = newlibadr(fd, id->lib, data->tar);
1735 break;
1736 case CONSTRAINT_TYPE_CLAMPTO:
1738 bClampToConstraint *data;
1739 data= ((bClampToConstraint*)con->data);
1740 data->tar = newlibadr(fd, id->lib, data->tar);
1742 break;
1744 case CONSTRAINT_TYPE_NULL:
1745 break;
1750 static void direct_link_constraints(FileData *fd, ListBase *lb)
1752 bConstraint *cons;
1754 link_list(fd, lb);
1755 for (cons=lb->first; cons; cons=cons->next) {
1756 cons->data = newdataadr(fd, cons->data);
1757 if (cons->type == CONSTRAINT_TYPE_PYTHON) {
1758 bPythonConstraint *data= cons->data;
1759 data->prop = newdataadr(fd, data->prop);
1760 IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
1765 static void lib_link_pose(FileData *fd, Object *ob, bPose *pose)
1767 bPoseChannel *pchan;
1768 bArmature *arm= ob->data;
1769 int rebuild;
1771 if (!pose || !arm)
1772 return;
1774 /* always rebuild to match proxy or lib changes */
1775 rebuild= ob->proxy || (ob->id.lib==NULL && arm->id.lib);
1777 for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
1778 lib_link_constraints(fd, (ID *)ob, &pchan->constraints);
1780 /* hurms... loop in a loop, but yah... later... (ton) */
1781 pchan->bone= get_named_bone(arm, pchan->name);
1783 pchan->custom= newlibadr(fd, arm->id.lib, pchan->custom);
1784 if(pchan->bone==NULL)
1785 rebuild= 1;
1786 else if(ob->id.lib==NULL && arm->id.lib) {
1787 /* local pose selection copied to armature, bit hackish */
1788 pchan->bone->flag &= ~(BONE_SELECTED|BONE_ACTIVE);
1789 pchan->bone->flag |= pchan->selectflag;
1793 if(rebuild) {
1794 ob->recalc= OB_RECALC;
1795 pose->flag |= POSE_RECALC;
1799 static void lib_link_armature(FileData *fd, Main *main)
1801 bArmature *arm;
1803 arm= main->armature.first;
1805 while(arm) {
1806 if(arm->id.flag & LIB_NEEDLINK) {
1807 arm->id.flag -= LIB_NEEDLINK;
1809 arm= arm->id.next;
1813 static void lib_link_action(FileData *fd, Main *main)
1815 bAction *act;
1816 bActionChannel *chan;
1818 act= main->action.first;
1819 while(act) {
1820 if(act->id.flag & LIB_NEEDLINK) {
1821 act->id.flag -= LIB_NEEDLINK;
1823 for (chan=act->chanbase.first; chan; chan=chan->next) {
1824 chan->ipo= newlibadr_us(fd, act->id.lib, chan->ipo);
1825 lib_link_constraint_channels(fd, &act->id, &chan->constraintChannels);
1829 act= act->id.next;
1833 static void direct_link_bones(FileData *fd, Bone* bone)
1835 Bone *child;
1837 bone->parent= newdataadr(fd, bone->parent);
1839 link_list(fd, &bone->childbase);
1841 for (child=bone->childbase.first; child; child=child->next) {
1842 direct_link_bones(fd, child);
1847 static void direct_link_action(FileData *fd, bAction *act)
1849 bActionChannel *achan;
1851 link_list(fd, &act->chanbase);
1853 for (achan = act->chanbase.first; achan; achan=achan->next)
1854 link_list(fd, &achan->constraintChannels);
1858 static void direct_link_armature(FileData *fd, bArmature *arm)
1860 Bone *bone;
1862 link_list(fd, &arm->bonebase);
1864 bone=arm->bonebase.first;
1865 while (bone) {
1866 direct_link_bones(fd, bone);
1867 bone=bone->next;
1871 /* ************ READ CAMERA ***************** */
1873 static void lib_link_camera(FileData *fd, Main *main)
1875 Camera *ca;
1877 ca= main->camera.first;
1878 while(ca) {
1879 if(ca->id.flag & LIB_NEEDLINK) {
1881 ca->ipo= newlibadr_us(fd, ca->id.lib, ca->ipo);
1883 lib_link_scriptlink(fd, &ca->id, &ca->scriptlink);
1885 ca->id.flag -= LIB_NEEDLINK;
1887 ca= ca->id.next;
1891 static void direct_link_camera(FileData *fd, Camera *ca)
1893 direct_link_scriptlink(fd, &ca->scriptlink);
1897 /* ************ READ LAMP ***************** */
1899 static void lib_link_lamp(FileData *fd, Main *main)
1901 Lamp *la;
1902 MTex *mtex;
1903 int a;
1905 la= main->lamp.first;
1906 while(la) {
1907 if(la->id.flag & LIB_NEEDLINK) {
1909 for(a=0; a<MAX_MTEX; a++) {
1910 mtex= la->mtex[a];
1911 if(mtex) {
1912 mtex->tex= newlibadr_us(fd, la->id.lib, mtex->tex);
1913 mtex->object= newlibadr(fd, la->id.lib, mtex->object);
1917 la->ipo= newlibadr_us(fd, la->id.lib, la->ipo);
1919 lib_link_scriptlink(fd, &la->id, &la->scriptlink);
1921 la->id.flag -= LIB_NEEDLINK;
1923 la= la->id.next;
1927 static void direct_link_lamp(FileData *fd, Lamp *la)
1929 int a;
1931 direct_link_scriptlink(fd, &la->scriptlink);
1933 for(a=0; a<MAX_MTEX; a++) {
1934 la->mtex[a]= newdataadr(fd, la->mtex[a]);
1937 la->curfalloff= newdataadr(fd, la->curfalloff);
1938 if(la->curfalloff)
1939 direct_link_curvemapping(fd, la->curfalloff);
1942 /* ************ READ keys ***************** */
1944 static void lib_link_key(FileData *fd, Main *main)
1946 Key *key;
1948 key= main->key.first;
1949 while(key) {
1950 if(key->id.flag & LIB_NEEDLINK) {
1952 key->ipo= newlibadr_us(fd, key->id.lib, key->ipo);
1953 key->from= newlibadr(fd, key->id.lib, key->from);
1955 key->id.flag -= LIB_NEEDLINK;
1957 key= key->id.next;
1961 static void switch_endian_keyblock(Key *key, KeyBlock *kb)
1963 int elemsize, a, b;
1964 char *data, *poin, *cp;
1966 elemsize= key->elemsize;
1967 data= kb->data;
1969 for(a=0; a<kb->totelem; a++) {
1971 cp= key->elemstr;
1972 poin= data;
1974 while( cp[0] ) { /* cp[0]==amount */
1976 switch(cp[1]) { /* cp[1]= type */
1977 case IPO_FLOAT:
1978 case IPO_BPOINT:
1979 case IPO_BEZTRIPLE:
1980 b= cp[0];
1981 while(b--) {
1982 SWITCH_INT((*poin));
1983 poin+= 4;
1985 break;
1988 cp+= 2;
1991 data+= elemsize;
1995 static void direct_link_key(FileData *fd, Key *key)
1997 KeyBlock *kb;
1999 link_list(fd, &(key->block));
2001 key->refkey= newdataadr(fd, key->refkey);
2003 kb= key->block.first;
2004 while(kb) {
2006 kb->data= newdataadr(fd, kb->data);
2008 if(fd->flags & FD_FLAGS_SWITCH_ENDIAN)
2009 switch_endian_keyblock(key, kb);
2011 kb= kb->next;
2015 /* ************ READ mball ***************** */
2017 static void lib_link_mball(FileData *fd, Main *main)
2019 MetaBall *mb;
2020 int a;
2022 mb= main->mball.first;
2023 while(mb) {
2024 if(mb->id.flag & LIB_NEEDLINK) {
2026 for(a=0; a<mb->totcol; a++) mb->mat[a]= newlibadr_us(fd, mb->id.lib, mb->mat[a]);
2028 mb->ipo= newlibadr_us(fd, mb->id.lib, mb->ipo);
2030 mb->id.flag -= LIB_NEEDLINK;
2032 mb= mb->id.next;
2036 static void direct_link_mball(FileData *fd, MetaBall *mb)
2038 mb->mat= newdataadr(fd, mb->mat);
2039 test_pointer_array(fd, (void **)&mb->mat);
2041 link_list(fd, &(mb->elems));
2043 mb->disp.first= mb->disp.last= 0;
2045 mb->bb= 0;
2048 /* ************ READ WORLD ***************** */
2050 static void lib_link_world(FileData *fd, Main *main)
2052 World *wrld;
2053 MTex *mtex;
2054 int a;
2056 wrld= main->world.first;
2057 while(wrld) {
2058 if(wrld->id.flag & LIB_NEEDLINK) {
2060 wrld->ipo= newlibadr_us(fd, wrld->id.lib, wrld->ipo);
2062 for(a=0; a<MAX_MTEX; a++) {
2063 mtex= wrld->mtex[a];
2064 if(mtex) {
2065 mtex->tex= newlibadr_us(fd, wrld->id.lib, mtex->tex);
2066 mtex->object= newlibadr(fd, wrld->id.lib, mtex->object);
2070 lib_link_scriptlink(fd, &wrld->id, &wrld->scriptlink);
2072 wrld->id.flag -= LIB_NEEDLINK;
2074 wrld= wrld->id.next;
2078 static void direct_link_world(FileData *fd, World *wrld)
2080 int a;
2082 direct_link_scriptlink(fd, &wrld->scriptlink);
2084 for(a=0; a<MAX_MTEX; a++) {
2085 wrld->mtex[a]= newdataadr(fd, wrld->mtex[a]);
2090 /* ************ READ IPO ***************** */
2092 static void lib_link_ipo(FileData *fd, Main *main)
2094 Ipo *ipo;
2096 ipo= main->ipo.first;
2097 while(ipo) {
2098 if(ipo->id.flag & LIB_NEEDLINK) {
2099 IpoCurve *icu;
2100 for(icu= ipo->curve.first; icu; icu= icu->next) {
2101 if(icu->driver)
2102 icu->driver->ob= newlibadr(fd, ipo->id.lib, icu->driver->ob);
2104 ipo->id.flag -= LIB_NEEDLINK;
2106 ipo= ipo->id.next;
2110 static void direct_link_ipo(FileData *fd, Ipo *ipo)
2112 IpoCurve *icu;
2114 link_list(fd, &(ipo->curve));
2115 icu= ipo->curve.first;
2116 while(icu) {
2117 icu->bezt= newdataadr(fd, icu->bezt);
2118 icu->bp= newdataadr(fd, icu->bp);
2119 icu->driver= newdataadr(fd, icu->driver);
2120 icu= icu->next;
2124 /* ************ READ VFONT ***************** */
2126 static void lib_link_vfont(FileData *fd, Main *main)
2128 VFont *vf;
2130 vf= main->vfont.first;
2131 while(vf) {
2132 if(vf->id.flag & LIB_NEEDLINK) {
2133 vf->id.flag -= LIB_NEEDLINK;
2135 vf= vf->id.next;
2139 static void direct_link_vfont(FileData *fd, VFont *vf)
2141 vf->data= NULL;
2142 vf->packedfile= direct_link_packedfile(fd, vf->packedfile);
2145 /* ************ READ TEXT ****************** */
2147 static void lib_link_text(FileData *fd, Main *main)
2149 Text *text;
2151 text= main->text.first;
2152 while(text) {
2153 if(text->id.flag & LIB_NEEDLINK) {
2154 text->id.flag -= LIB_NEEDLINK;
2156 text= text->id.next;
2160 static void direct_link_text(FileData *fd, Text *text)
2162 TextLine *ln;
2164 text->name= newdataadr(fd, text->name);
2166 text->undo_pos= -1;
2167 text->undo_len= TXT_INIT_UNDO;
2168 text->undo_buf= MEM_mallocN(text->undo_len, "undo buf");
2170 text->compiled= NULL;
2173 if(text->flags & TXT_ISEXT) {
2174 reopen_text(text);
2175 } else {
2178 link_list(fd, &text->lines);
2180 text->curl= newdataadr(fd, text->curl);
2181 text->sell= newdataadr(fd, text->sell);
2183 ln= text->lines.first;
2184 while(ln) {
2185 ln->line= newdataadr(fd, ln->line);
2186 ln->format= NULL;
2188 if (ln->len != (int) strlen(ln->line)) {
2189 printf("Error loading text, line lengths differ\n");
2190 ln->len = strlen(ln->line);
2193 ln= ln->next;
2196 text->flags = (text->flags|TXT_ISTMP) & ~TXT_ISEXT;
2198 text->id.us= 1;
2201 /* ************ READ IMAGE ***************** */
2203 static void lib_link_image(FileData *fd, Main *main)
2205 Image *ima;
2207 ima= main->image.first;
2208 while (ima) {
2209 if(ima->id.flag & LIB_NEEDLINK) {
2210 if (ima->id.properties) IDP_LibLinkProperty(ima->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
2212 ima->id.flag -= LIB_NEEDLINK;
2214 ima= ima->id.next;
2218 static void link_ibuf_list(FileData *fd, ListBase *lb)
2220 Link *ln, *prev;
2222 if(lb->first==NULL) return;
2224 lb->first= newimaadr(fd, lb->first);
2225 ln= lb->first;
2226 prev= NULL;
2227 while(ln) {
2228 ln->next= newimaadr(fd, ln->next);
2229 ln->prev= prev;
2230 prev= ln;
2231 ln= ln->next;
2233 lb->last= prev;
2236 static void direct_link_image(FileData *fd, Image *ima)
2238 /* for undo system, pointers could be restored */
2239 if(fd->imamap)
2240 link_ibuf_list(fd, &ima->ibufs);
2241 else
2242 ima->ibufs.first= ima->ibufs.last= NULL;
2244 /* if not restored, we keep the binded opengl index */
2245 if(ima->ibufs.first==NULL)
2246 ima->bindcode= 0;
2248 ima->anim= NULL;
2249 ima->rr= NULL;
2250 ima->repbind= NULL;
2252 ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
2253 ima->preview = direct_link_preview_image(fd, ima->preview);
2254 ima->ok= 1;
2258 /* ************ READ CURVE ***************** */
2260 static void lib_link_curve(FileData *fd, Main *main)
2262 Curve *cu;
2263 int a;
2265 cu= main->curve.first;
2266 while(cu) {
2267 if(cu->id.flag & LIB_NEEDLINK) {
2269 for(a=0; a<cu->totcol; a++) cu->mat[a]= newlibadr_us(fd, cu->id.lib, cu->mat[a]);
2271 cu->bevobj= newlibadr(fd, cu->id.lib, cu->bevobj);
2272 cu->taperobj= newlibadr(fd, cu->id.lib, cu->taperobj);
2273 cu->textoncurve= newlibadr(fd, cu->id.lib, cu->textoncurve);
2274 cu->vfont= newlibadr_us(fd, cu->id.lib, cu->vfont);
2275 cu->vfontb= newlibadr_us(fd, cu->id.lib, cu->vfontb);
2276 cu->vfonti= newlibadr_us(fd, cu->id.lib, cu->vfonti);
2277 cu->vfontbi= newlibadr_us(fd, cu->id.lib, cu->vfontbi);
2279 cu->ipo= newlibadr_us(fd, cu->id.lib, cu->ipo);
2280 cu->key= newlibadr_us(fd, cu->id.lib, cu->key);
2282 cu->id.flag -= LIB_NEEDLINK;
2284 cu= cu->id.next;
2289 static void switch_endian_knots(Nurb *nu)
2291 int len;
2293 if(nu->knotsu) {
2294 len= KNOTSU(nu);
2295 while(len--) {
2296 SWITCH_INT(nu->knotsu[len]);
2299 if(nu->knotsv) {
2300 len= KNOTSV(nu);
2301 while(len--) {
2302 SWITCH_INT(nu->knotsv[len]);
2307 static void direct_link_curve(FileData *fd, Curve *cu)
2309 Nurb *nu;
2310 TextBox *tb;
2312 cu->mat= newdataadr(fd, cu->mat);
2313 test_pointer_array(fd, (void **)&cu->mat);
2314 cu->str= newdataadr(fd, cu->str);
2315 cu->strinfo= newdataadr(fd, cu->strinfo);
2316 cu->tb= newdataadr(fd, cu->tb);
2318 if(cu->vfont==0) link_list(fd, &(cu->nurb));
2319 else {
2320 cu->nurb.first=cu->nurb.last= 0;
2322 tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "TextBoxread");
2323 if (cu->tb) {
2324 memcpy(tb, cu->tb, cu->totbox*sizeof(TextBox));
2325 MEM_freeN(cu->tb);
2326 cu->tb= tb;
2327 } else {
2328 cu->totbox = 1;
2329 cu->actbox = 1;
2330 cu->tb = tb;
2331 cu->tb[0].w = cu->linewidth;
2333 if (cu->wordspace == 0.0) cu->wordspace = 1.0;
2336 cu->bev.first=cu->bev.last= 0;
2337 cu->disp.first=cu->disp.last= 0;
2338 cu->path= 0;
2340 nu= cu->nurb.first;
2341 while(nu) {
2342 nu->bezt= newdataadr(fd, nu->bezt);
2343 nu->bp= newdataadr(fd, nu->bp);
2344 nu->knotsu= newdataadr(fd, nu->knotsu);
2345 nu->knotsv= newdataadr(fd, nu->knotsv);
2346 if (cu->vfont==0) nu->charidx= nu->mat_nr;
2348 if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
2349 switch_endian_knots(nu);
2352 nu= nu->next;
2354 cu->bb= NULL;
2357 /* ************ READ TEX ***************** */
2359 static void lib_link_texture(FileData *fd, Main *main)
2361 Tex *tex;
2363 tex= main->tex.first;
2364 while(tex) {
2365 if(tex->id.flag & LIB_NEEDLINK) {
2367 tex->ima= newlibadr_us(fd, tex->id.lib, tex->ima);
2368 tex->ipo= newlibadr_us(fd, tex->id.lib, tex->ipo);
2369 if(tex->env) tex->env->object= newlibadr(fd, tex->id.lib, tex->env->object);
2371 tex->id.flag -= LIB_NEEDLINK;
2373 tex= tex->id.next;
2377 static void direct_link_texture(FileData *fd, Tex *tex)
2379 tex->plugin= newdataadr(fd, tex->plugin);
2380 if(tex->plugin) {
2381 tex->plugin->handle= 0;
2382 open_plugin_tex(tex->plugin);
2383 /* initialize data for this instance, if an initialization
2384 * function exists.
2386 if (tex->plugin->instance_init)
2387 tex->plugin->instance_init((void *) tex->plugin->data);
2389 tex->coba= newdataadr(fd, tex->coba);
2390 tex->env= newdataadr(fd, tex->env);
2391 if(tex->env) {
2392 tex->env->ima= NULL;
2393 memset(tex->env->cube, 0, 6*sizeof(void *));
2394 tex->env->ok= 0;
2396 tex->iuser.ok= 1;
2401 /* ************ READ MATERIAL ***************** */
2403 static void lib_link_material(FileData *fd, Main *main)
2405 Material *ma;
2406 MTex *mtex;
2407 int a;
2409 ma= main->mat.first;
2410 while(ma) {
2411 if(ma->id.flag & LIB_NEEDLINK) {
2412 /*Link ID Properties -- and copy this comment EXACTLY for easy finding
2413 of library blocks that implement this.*/
2414 if (ma->id.properties) IDP_LibLinkProperty(ma->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
2416 ma->ipo= newlibadr_us(fd, ma->id.lib, ma->ipo);
2417 ma->group= newlibadr_us(fd, ma->id.lib, ma->group);
2419 for(a=0; a<MAX_MTEX; a++) {
2420 mtex= ma->mtex[a];
2421 if(mtex) {
2422 mtex->tex= newlibadr_us(fd, ma->id.lib, mtex->tex);
2423 mtex->object= newlibadr(fd, ma->id.lib, mtex->object);
2426 lib_link_scriptlink(fd, &ma->id, &ma->scriptlink);
2428 if(ma->nodetree)
2429 lib_link_ntree(fd, &ma->id, ma->nodetree);
2431 ma->id.flag -= LIB_NEEDLINK;
2433 ma= ma->id.next;
2437 static void direct_link_material(FileData *fd, Material *ma)
2439 int a;
2441 for(a=0; a<MAX_MTEX; a++) {
2442 ma->mtex[a]= newdataadr(fd, ma->mtex[a]);
2445 ma->ramp_col= newdataadr(fd, ma->ramp_col);
2446 ma->ramp_spec= newdataadr(fd, ma->ramp_spec);
2448 direct_link_scriptlink(fd, &ma->scriptlink);
2450 ma->nodetree= newdataadr(fd, ma->nodetree);
2451 if(ma->nodetree)
2452 direct_link_nodetree(fd, ma->nodetree);
2455 /* ************ READ MESH ***************** */
2457 static void lib_link_mtface(FileData *fd, Mesh *me, MTFace *mtface, int totface)
2459 MTFace *tf= mtface;
2460 int i;
2462 for (i=0; i<totface; i++, tf++) {
2463 tf->tpage= newlibadr(fd, me->id.lib, tf->tpage);
2464 if(tf->tpage && tf->tpage->id.us==0)
2465 tf->tpage->id.us= 1;
2469 static void lib_link_customdata_mtface(FileData *fd, Mesh *me, CustomData *fdata, int totface)
2471 int i;
2472 for(i=0; i<fdata->totlayer; i++) {
2473 CustomDataLayer *layer = &fdata->layers[i];
2475 if(layer->type == CD_MTFACE)
2476 lib_link_mtface(fd, me, layer->data, totface);
2481 static void lib_link_mesh(FileData *fd, Main *main)
2483 Mesh *me;
2485 me= main->mesh.first;
2486 while(me) {
2487 if(me->id.flag & LIB_NEEDLINK) {
2488 int i;
2490 /*Link ID Properties -- and copy this comment EXACTLY for easy finding
2491 of library blocks that implement this.*/
2492 if (me->id.properties) IDP_LibLinkProperty(me->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
2494 /* this check added for python created meshes */
2495 if(me->mat) {
2496 for(i=0; i<me->totcol; i++) {
2497 me->mat[i]= newlibadr_us(fd, me->id.lib, me->mat[i]);
2500 else me->totcol= 0;
2502 me->ipo= newlibadr_us(fd, me->id.lib, me->ipo);
2503 me->key= newlibadr_us(fd, me->id.lib, me->key);
2504 me->texcomesh= newlibadr_us(fd, me->id.lib, me->texcomesh);
2506 lib_link_customdata_mtface(fd, me, &me->fdata, me->totface);
2507 if(me->mr && me->mr->levels.first)
2508 lib_link_customdata_mtface(fd, me, &me->mr->fdata,
2509 ((MultiresLevel*)me->mr->levels.first)->totface);
2511 me->id.flag -= LIB_NEEDLINK;
2513 me= me->id.next;
2517 static void direct_link_dverts(FileData *fd, int count, MDeformVert *mdverts)
2519 int i;
2521 if (!mdverts)
2522 return;
2524 for (i=0; i<count; i++) {
2525 mdverts[i].dw=newdataadr(fd, mdverts[i].dw);
2526 if (!mdverts[i].dw)
2527 mdverts[i].totweight=0;
2531 static void direct_link_customdata(FileData *fd, CustomData *data, int count)
2533 int i = 0;
2535 data->layers= newdataadr(fd, data->layers);
2537 while (i < data->totlayer) {
2538 CustomDataLayer *layer = &data->layers[i];
2540 if (CustomData_verify_versions(data, i)) {
2541 layer->data = newdataadr(fd, layer->data);
2542 i++;
2547 static void direct_link_mesh(FileData *fd, Mesh *mesh)
2549 mesh->mat= newdataadr(fd, mesh->mat);
2550 test_pointer_array(fd, (void **)&mesh->mat);
2552 mesh->mvert= newdataadr(fd, mesh->mvert);
2553 mesh->medge= newdataadr(fd, mesh->medge);
2554 mesh->mface= newdataadr(fd, mesh->mface);
2555 mesh->tface= newdataadr(fd, mesh->tface);
2556 mesh->mtface= newdataadr(fd, mesh->mtface);
2557 mesh->mcol= newdataadr(fd, mesh->mcol);
2558 mesh->msticky= newdataadr(fd, mesh->msticky);
2559 mesh->dvert= newdataadr(fd, mesh->dvert);
2561 /* Partial-mesh visibility (do this before using totvert, totface, or totedge!) */
2562 mesh->pv= newdataadr(fd, mesh->pv);
2563 if(mesh->pv) {
2564 mesh->pv->vert_map= newdataadr(fd, mesh->pv->vert_map);
2565 mesh->pv->edge_map= newdataadr(fd, mesh->pv->edge_map);
2566 mesh->pv->old_faces= newdataadr(fd, mesh->pv->old_faces);
2567 mesh->pv->old_edges= newdataadr(fd, mesh->pv->old_edges);
2570 /* normally direct_link_dverts should be called in direct_link_customdata,
2571 but for backwards compat in do_versions to work we do it here */
2572 direct_link_dverts(fd, mesh->pv ? mesh->pv->totvert : mesh->totvert, mesh->dvert);
2574 direct_link_customdata(fd, &mesh->vdata, mesh->pv ? mesh->pv->totvert : mesh->totvert);
2575 direct_link_customdata(fd, &mesh->edata, mesh->pv ? mesh->pv->totedge : mesh->totedge);
2576 direct_link_customdata(fd, &mesh->fdata, mesh->pv ? mesh->pv->totface : mesh->totface);
2578 mesh->bb= NULL;
2579 mesh->oc= 0;
2580 mesh->mselect= NULL;
2582 /* Multires data */
2583 mesh->mr= newdataadr(fd, mesh->mr);
2584 if(mesh->mr) {
2585 MultiresLevel *lvl;
2587 link_list(fd, &mesh->mr->levels);
2588 lvl= mesh->mr->levels.first;
2590 direct_link_customdata(fd, &mesh->mr->vdata, lvl->totvert);
2591 direct_link_dverts(fd, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
2592 direct_link_customdata(fd, &mesh->mr->fdata, lvl->totface);
2594 if(mesh->mr->edge_flags)
2595 mesh->mr->edge_flags= newdataadr(fd, mesh->mr->edge_flags);
2596 if(mesh->mr->edge_creases)
2597 mesh->mr->edge_creases= newdataadr(fd, mesh->mr->edge_creases);
2599 if(!mesh->mr->edge_flags)
2600 mesh->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "Multires Edge Flags");
2601 if(!mesh->mr->edge_creases)
2602 mesh->mr->edge_creases= MEM_callocN(sizeof(char)*lvl->totedge, "Multires Edge Creases");
2604 mesh->mr->verts = newdataadr(fd, mesh->mr->verts);
2606 for(; lvl; lvl= lvl->next) {
2607 lvl->verts= newdataadr(fd, lvl->verts);
2608 lvl->faces= newdataadr(fd, lvl->faces);
2609 lvl->edges= newdataadr(fd, lvl->edges);
2610 lvl->colfaces= newdataadr(fd, lvl->colfaces);
2612 /* Recalculating the maps is faster than reading them from the file */
2613 multires_calc_level_maps(lvl);
2617 if((fd->flags & FD_FLAGS_SWITCH_ENDIAN) && mesh->tface) {
2618 TFace *tf= mesh->tface;
2619 int i;
2621 for (i=0; i< (mesh->pv ? mesh->pv->totface : mesh->totface); i++, tf++) {
2622 SWITCH_INT(tf->col[0]);
2623 SWITCH_INT(tf->col[1]);
2624 SWITCH_INT(tf->col[2]);
2625 SWITCH_INT(tf->col[3]);
2630 /* ************ READ LATTICE ***************** */
2632 static void lib_link_latt(FileData *fd, Main *main)
2634 Lattice *lt;
2636 lt= main->latt.first;
2637 while(lt) {
2638 if(lt->id.flag & LIB_NEEDLINK) {
2640 lt->ipo= newlibadr_us(fd, lt->id.lib, lt->ipo);
2641 lt->key= newlibadr_us(fd, lt->id.lib, lt->key);
2643 lt->id.flag -= LIB_NEEDLINK;
2645 lt= lt->id.next;
2649 static void direct_link_latt(FileData *fd, Lattice *lt)
2651 lt->def= newdataadr(fd, lt->def);
2653 lt->dvert= newdataadr(fd, lt->dvert);
2654 direct_link_dverts(fd, lt->pntsu*lt->pntsv*lt->pntsw, lt->dvert);
2658 /* ************ READ OBJECT ***************** */
2660 static void lib_link_modifiers__linkModifiers(void *userData, Object *ob,
2661 ID **idpoin)
2663 FileData *fd = userData;
2665 *idpoin = newlibadr(fd, ob->id.lib, *idpoin);
2666 /* hardcoded bad exception; non-object modifier data gets user count (texture, displace) */
2667 if(*idpoin && GS((*idpoin)->name)!=ID_OB)
2668 (*idpoin)->us++;
2670 static void lib_link_modifiers(FileData *fd, Object *ob)
2672 modifiers_foreachIDLink(ob, lib_link_modifiers__linkModifiers, fd);
2675 static void lib_link_object(FileData *fd, Main *main)
2677 Object *ob;
2678 PartEff *paf;
2679 bSensor *sens;
2680 bController *cont;
2681 bActuator *act;
2682 void *poin;
2683 int warn=0, a;
2685 ob= main->object.first;
2686 while(ob) {
2687 if(ob->id.flag & LIB_NEEDLINK) {
2688 if (ob->id.properties) IDP_LibLinkProperty(ob->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
2690 ob->parent= newlibadr(fd, ob->id.lib, ob->parent);
2691 ob->track= newlibadr(fd, ob->id.lib, ob->track);
2692 ob->ipo= newlibadr_us(fd, ob->id.lib, ob->ipo);
2693 ob->action = newlibadr_us(fd, ob->id.lib, ob->action);
2694 ob->dup_group= newlibadr_us(fd, ob->id.lib, ob->dup_group);
2696 ob->proxy= newlibadr_us(fd, ob->id.lib, ob->proxy);
2697 if(ob->proxy) {
2698 /* paranoia check, actually a proxy_from pointer should never be written... */
2699 if(ob->proxy->id.lib==NULL) {
2700 ob->proxy->proxy_from= NULL;
2701 ob->proxy= NULL;
2703 else {
2704 /* this triggers object_update to always use a copy */
2705 ob->proxy->proxy_from= ob;
2706 /* force proxy updates after load/undo, a bit weak */
2707 ob->recalc= ob->proxy->recalc= OB_RECALC;
2710 ob->proxy_group= newlibadr(fd, ob->id.lib, ob->proxy_group);
2712 poin= ob->data;
2713 ob->data= newlibadr_us(fd, ob->id.lib, ob->data);
2715 if(ob->data==NULL && poin!=NULL) {
2716 ob->type= OB_EMPTY;
2717 warn= 1;
2718 if(ob->id.lib) printf("Can't find obdata of %s lib %s\n", ob->id.name+2, ob->id.lib->name);
2719 else printf("Object %s lost data.", ob->id.name+2);
2721 if(ob->pose) {
2722 free_pose_channels(ob->pose);
2723 MEM_freeN(ob->pose);
2724 ob->pose= NULL;
2725 ob->flag &= ~OB_POSEMODE;
2728 for(a=0; a<ob->totcol; a++) ob->mat[a]= newlibadr_us(fd, ob->id.lib, ob->mat[a]);
2730 ob->id.flag -= LIB_NEEDLINK;
2731 /* if id.us==0 a new base will be created later on */
2733 /* WARNING! Also check expand_object(), should reflect the stuff below. */
2734 lib_link_pose(fd, ob, ob->pose);
2735 lib_link_constraints(fd, &ob->id, &ob->constraints);
2736 lib_link_nlastrips(fd, &ob->id, &ob->nlastrips);
2737 lib_link_constraint_channels(fd, &ob->id, &ob->constraintChannels);
2739 for(paf= ob->effect.first; paf; paf= paf->next) {
2740 if(paf->type==EFF_PARTICLE) {
2741 paf->group= newlibadr_us(fd, ob->id.lib, paf->group);
2745 sens= ob->sensors.first;
2746 while(sens) {
2747 if(ob->id.lib==NULL) { // done in expand_main
2748 for(a=0; a<sens->totlinks; a++) {
2749 sens->links[a]= newglobadr(fd, sens->links[a]);
2752 if(sens->type==SENS_TOUCH) {
2753 bTouchSensor *ts= sens->data;
2754 ts->ma= newlibadr(fd, ob->id.lib, ts->ma);
2756 else if(sens->type==SENS_MESSAGE) {
2757 bMessageSensor *ms= sens->data;
2758 ms->fromObject=
2759 newlibadr(fd, ob->id.lib, ms->fromObject);
2761 sens= sens->next;
2764 cont= ob->controllers.first;
2765 while(cont) {
2766 if(ob->id.lib==NULL) { // done in expand_main
2767 for(a=0; a<cont->totlinks; a++) {
2768 cont->links[a]= newglobadr(fd, cont->links[a]);
2771 if(cont->type==CONT_PYTHON) {
2772 bPythonCont *pc= cont->data;
2773 pc->text= newlibadr(fd, ob->id.lib, pc->text);
2775 cont->slinks= NULL;
2776 cont->totslinks= 0;
2778 cont= cont->next;
2781 act= ob->actuators.first;
2782 while(act) {
2783 if(act->type==ACT_SOUND) {
2784 bSoundActuator *sa= act->data;
2785 sa->sound= newlibadr_us(fd, ob->id.lib, sa->sound);
2787 else if(act->type==ACT_CD) {
2788 /* bCDActuator *cda= act->data; */
2790 else if(act->type==ACT_GAME) {
2791 /* bGameActuator *ga= act->data; */
2793 else if(act->type==ACT_CAMERA) {
2794 bCameraActuator *ca= act->data;
2795 ca->ob= newlibadr(fd, ob->id.lib, ca->ob);
2797 /* leave this one, it's obsolete but necessary to read for conversion */
2798 else if(act->type==ACT_ADD_OBJECT) {
2799 bAddObjectActuator *eoa= act->data;
2800 if(eoa) eoa->ob= newlibadr(fd, ob->id.lib, eoa->ob);
2802 else if(act->type==ACT_EDIT_OBJECT) {
2803 bEditObjectActuator *eoa= act->data;
2804 if(eoa==NULL) {
2805 init_actuator(act);
2807 else {
2808 eoa->ob= newlibadr(fd, ob->id.lib, eoa->ob);
2809 eoa->me= newlibadr(fd, ob->id.lib, eoa->me);
2812 else if(act->type==ACT_SCENE) {
2813 bSceneActuator *sa= act->data;
2814 sa->camera= newlibadr(fd, ob->id.lib, sa->camera);
2815 sa->scene= newlibadr(fd, ob->id.lib, sa->scene);
2817 else if(act->type==ACT_ACTION) {
2818 bActionActuator *aa= act->data;
2819 aa->act= newlibadr(fd, ob->id.lib, aa->act);
2821 else if(act->type==ACT_PROPERTY) {
2822 bPropertyActuator *pa= act->data;
2823 pa->ob= newlibadr(fd, ob->id.lib, pa->ob);
2825 else if(act->type==ACT_MESSAGE) {
2826 bMessageActuator *ma= act->data;
2827 ma->toObject= newlibadr(fd, ob->id.lib, ma->toObject);
2829 act= act->next;
2832 if(ob->fluidsimSettings) {
2833 ob->fluidsimSettings->ipo = newlibadr_us(fd, ob->id.lib, ob->fluidsimSettings->ipo);
2836 lib_link_scriptlink(fd, &ob->id, &ob->scriptlink);
2837 lib_link_modifiers(fd, ob);
2839 ob= ob->id.next;
2842 if(warn) error("WARNING IN CONSOLE");
2846 static void direct_link_pose(FileData *fd, bPose *pose) {
2848 bPoseChannel *pchan;
2850 if (!pose)
2851 return;
2853 link_list(fd, &pose->chanbase);
2855 for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
2856 pchan->bone= NULL;
2857 pchan->parent= newdataadr(fd, pchan->parent);
2858 pchan->child= newdataadr(fd, pchan->child);
2859 direct_link_constraints(fd, &pchan->constraints);
2860 pchan->iktree.first= pchan->iktree.last= NULL;
2861 pchan->path= NULL;
2866 static void direct_link_modifiers(FileData *fd, ListBase *lb)
2868 ModifierData *md;
2870 link_list(fd, lb);
2872 for (md=lb->first; md; md=md->next) {
2873 md->error = NULL;
2875 /* if modifiers disappear, or for upward compatibility */
2876 if(NULL==modifierType_getInfo(md->type))
2877 md->type= eModifierType_None;
2879 if (md->type==eModifierType_Subsurf) {
2880 SubsurfModifierData *smd = (SubsurfModifierData*) md;
2882 smd->emCache = smd->mCache = 0;
2883 } else if (md->type==eModifierType_Hook) {
2884 HookModifierData *hmd = (HookModifierData*) md;
2886 hmd->indexar= newdataadr(fd, hmd->indexar);
2887 if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
2888 int a;
2889 for(a=0; a<hmd->totindex; a++) {
2890 SWITCH_INT(hmd->indexar[a]);
2897 static void direct_link_nlastrips(FileData *fd, ListBase *strips)
2899 bActionStrip *strip;
2901 link_list(fd, strips);
2903 for(strip= strips->first; strip; strip= strip->next)
2904 link_list(fd, &strip->modifiers);
2907 static void direct_link_object(FileData *fd, Object *ob)
2909 PartEff *paf;
2910 bProperty *prop;
2911 bSensor *sens;
2912 bController *cont;
2913 bActuator *act;
2914 int a;
2916 /* weak weak... this was only meant as draw flag, now is used in give_base too */
2917 ob->flag &= ~OB_FROMGROUP;
2919 ob->disp.first=ob->disp.last= NULL;
2921 ob->pose= newdataadr(fd, ob->pose);
2922 direct_link_pose(fd, ob->pose);
2924 link_list(fd, &ob->defbase);
2925 direct_link_nlastrips(fd, &ob->nlastrips);
2926 link_list(fd, &ob->constraintChannels);
2928 direct_link_scriptlink(fd, &ob->scriptlink);
2930 ob->mat= newdataadr(fd, ob->mat);
2931 test_pointer_array(fd, (void **)&ob->mat);
2933 /* do it here, below old data gets converted */
2934 direct_link_modifiers(fd, &ob->modifiers);
2936 link_list(fd, &ob->effect);
2937 paf= ob->effect.first;
2938 while(paf) {
2939 if(paf->type==EFF_PARTICLE) {
2940 paf->keys= NULL;
2942 if(paf->type==EFF_WAVE) {
2943 WaveEff *wav = (WaveEff*) paf;
2944 PartEff *next = paf->next;
2945 WaveModifierData *wmd = (WaveModifierData*) modifier_new(eModifierType_Wave);
2947 wmd->damp = wav->damp;
2948 wmd->flag = wav->flag;
2949 wmd->height = wav->height;
2950 wmd->lifetime = wav->lifetime;
2951 wmd->narrow = wav->narrow;
2952 wmd->speed = wav->speed;
2953 wmd->startx = wav->startx;
2954 wmd->starty = wav->startx;
2955 wmd->timeoffs = wav->timeoffs;
2956 wmd->width = wav->width;
2958 BLI_addtail(&ob->modifiers, wmd);
2960 BLI_remlink(&ob->effect, paf);
2961 MEM_freeN(paf);
2963 paf = next;
2964 continue;
2966 if(paf->type==EFF_BUILD) {
2967 BuildEff *baf = (BuildEff*) paf;
2968 PartEff *next = paf->next;
2969 BuildModifierData *bmd = (BuildModifierData*) modifier_new(eModifierType_Build);
2971 bmd->start = baf->sfra;
2972 bmd->length = baf->len;
2973 bmd->randomize = 0;
2974 bmd->seed = 1;
2976 BLI_addtail(&ob->modifiers, bmd);
2978 BLI_remlink(&ob->effect, paf);
2979 MEM_freeN(paf);
2981 paf = next;
2982 continue;
2984 paf= paf->next;
2987 ob->pd= newdataadr(fd, ob->pd);
2988 ob->soft= newdataadr(fd, ob->soft);
2989 if(ob->soft) {
2990 SoftBody *sb= ob->soft;
2992 sb->bpoint= NULL; // init pointers so it gets rebuilt nicely
2993 sb->bspring= NULL;
2994 sb->scratch= NULL;
2997 sb->keys= newdataadr(fd, sb->keys);
2998 test_pointer_array(fd, (void **)&sb->keys);
2999 if(sb->keys) {
3000 for(a=0; a<sb->totkey; a++) {
3001 sb->keys[a]= newdataadr(fd, sb->keys[a]);
3005 ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */
3006 if(ob->fluidsimSettings) {
3007 // reinit mesh pointers
3008 ob->fluidsimSettings->orgMesh = NULL; //ob->data;
3009 ob->fluidsimSettings->meshSurface = NULL;
3010 ob->fluidsimSettings->meshBB = NULL;
3011 ob->fluidsimSettings->meshSurfNormals = NULL;
3014 link_list(fd, &ob->prop);
3015 prop= ob->prop.first;
3016 while(prop) {
3017 prop->poin= newdataadr(fd, prop->poin);
3018 if(prop->poin==0) prop->poin= &prop->data;
3019 prop= prop->next;
3022 link_list(fd, &ob->sensors);
3023 sens= ob->sensors.first;
3024 while(sens) {
3025 sens->data= newdataadr(fd, sens->data);
3026 sens->links= newdataadr(fd, sens->links);
3027 test_pointer_array(fd, (void **)&sens->links);
3028 sens= sens->next;
3031 direct_link_constraints(fd, &ob->constraints);
3033 link_glob_list(fd, &ob->controllers);
3034 cont= ob->controllers.first;
3035 while(cont) {
3036 cont->data= newdataadr(fd, cont->data);
3037 cont->links= newdataadr(fd, cont->links);
3038 test_pointer_array(fd, (void **)&cont->links);
3039 cont= cont->next;
3042 link_glob_list(fd, &ob->actuators);
3043 act= ob->actuators.first;
3044 while(act) {
3045 act->data= newdataadr(fd, act->data);
3046 act= act->next;
3049 link_list(fd, &ob->hooks);
3050 while (ob->hooks.first) {
3051 ObHook *hook = ob->hooks.first;
3052 HookModifierData *hmd = (HookModifierData*) modifier_new(eModifierType_Hook);
3054 hook->indexar= newdataadr(fd, hook->indexar);
3055 if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
3056 int a;
3057 for(a=0; a<hook->totindex; a++) {
3058 SWITCH_INT(hook->indexar[a]);
3062 /* Do conversion here because if we have loaded
3063 * a hook we need to make sure it gets converted
3064 * and free'd, regardless of version.
3066 VECCOPY(hmd->cent, hook->cent);
3067 hmd->falloff = hook->falloff;
3068 hmd->force = hook->force;
3069 hmd->indexar = hook->indexar;
3070 hmd->object = hook->parent;
3071 memcpy(hmd->parentinv, hook->parentinv, sizeof(hmd->parentinv));
3072 hmd->totindex = hook->totindex;
3074 BLI_addhead(&ob->modifiers, hmd);
3075 BLI_remlink(&ob->hooks, hook);
3077 MEM_freeN(hook);
3080 ob->bb= NULL;
3081 ob->derivedDeform= NULL;
3082 ob->derivedFinal= NULL;
3085 /* ************ READ SCENE ***************** */
3087 static void lib_link_scene(FileData *fd, Main *main)
3089 Scene *sce;
3090 Base *base, *next;
3091 Editing *ed;
3092 Sequence *seq;
3093 SceneRenderLayer *srl;
3094 ScenePlumi *spl;
3095 int a;
3097 sce= main->scene.first;
3098 while(sce) {
3099 if(sce->id.flag & LIB_NEEDLINK) {
3100 /*Link ID Properties -- and copy this comment EXACTLY for easy finding
3101 of library blocks that implement this.*/
3102 if (sce->id.properties) IDP_LibLinkProperty(sce->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
3104 sce->camera= newlibadr(fd, sce->id.lib, sce->camera);
3105 sce->world= newlibadr_us(fd, sce->id.lib, sce->world);
3106 sce->set= newlibadr(fd, sce->id.lib, sce->set);
3107 sce->ima= newlibadr_us(fd, sce->id.lib, sce->ima);
3108 sce->toolsettings->imapaint.brush=
3109 newlibadr_us(fd, sce->id.lib, sce->toolsettings->imapaint.brush);
3111 /* Sculptdata textures */
3112 for(a=0; a<MAX_MTEX; ++a) {
3113 MTex *mtex= sce->sculptdata.mtex[a];
3114 if(mtex)
3115 mtex->tex= newlibadr_us(fd, sce->id.lib, mtex->tex);
3118 for(base= sce->base.first; base; base= next) {
3119 next= base->next;
3121 /* base->object= newlibadr_us(fd, sce->id.lib, base->object); */
3122 base->object= newlibadr_us(fd, sce->id.lib, base->object);
3124 /* when save during radiotool, needs cleared */
3125 base->flag &= ~OB_RADIO;
3127 if(base->object==NULL) {
3128 printf("LIB ERROR: base removed\n");
3129 BLI_remlink(&sce->base, base);
3130 if(base==sce->basact) sce->basact= 0;
3131 MEM_freeN(base);
3135 ed= sce->ed;
3136 if(ed) {
3137 WHILE_SEQ(&ed->seqbase) {
3138 if(seq->ipo) seq->ipo= newlibadr_us(fd, sce->id.lib, seq->ipo);
3139 if(seq->scene) seq->scene= newlibadr(fd, sce->id.lib, seq->scene);
3140 if(seq->sound) {
3141 seq->sound= newlibadr(fd, sce->id.lib, seq->sound);
3142 if (seq->sound) {
3143 seq->sound->id.us++;
3144 seq->sound->flags |= SOUND_FLAGS_SEQUENCE;
3147 seq->anim= 0;
3148 seq->hdaudio = 0;
3150 END_SEQ
3153 lib_link_scriptlink(fd, &sce->id, &sce->scriptlink);
3155 if(sce->nodetree)
3156 lib_link_ntree(fd, &sce->id, sce->nodetree);
3158 for(srl= sce->r.layers.first; srl; srl= srl->next) {
3159 srl->mat_override= newlibadr_us(fd, sce->id.lib, srl->mat_override);
3160 srl->light_override= newlibadr_us(fd, sce->id.lib, srl->light_override);
3163 for(spl= sce->bg_scenes.first; spl; spl= spl->next) {
3164 spl->scene= newlibadr_us(fd, sce->id.lib, spl->scene);
3167 for(spl= sce->compo_scenes.first; spl; spl= spl->next) {
3168 spl->scene= newlibadr_us(fd, sce->id.lib, spl->scene);
3171 sce->id.flag -= LIB_NEEDLINK;
3174 sce= sce->id.next;
3178 static void link_recurs_seq(FileData *fd, ListBase *lb)
3180 Sequence *seq;
3182 link_list(fd, lb);
3183 seq= lb->first;
3184 while(seq) {
3185 if(seq->seqbase.first) link_recurs_seq(fd, &seq->seqbase);
3186 seq= seq->next;
3190 static void direct_link_scene(FileData *fd, Scene *sce)
3192 Editing *ed;
3193 Sequence *seq;
3194 MetaStack *ms;
3195 int a;
3197 sce->theDag = NULL;
3198 sce->dagisvalid = 0;
3199 /* set users to one by default, not in lib-link, this will increase it for compo nodes */
3200 sce->id.us= 1;
3202 link_list(fd, &(sce->base));
3204 sce->basact= newdataadr(fd, sce->basact);
3206 sce->radio= newdataadr(fd, sce->radio);
3208 sce->toolsettings= newdataadr(fd, sce->toolsettings);
3210 sce->sculptdata.session= NULL;
3211 /* SculptData textures */
3212 for(a=0; a<MAX_MTEX; ++a)
3213 sce->sculptdata.mtex[a]= newdataadr(fd,sce->sculptdata.mtex[a]);
3215 if(sce->ed) {
3216 ListBase *old_seqbasep= &((Editing *)sce->ed)->seqbase;
3218 ed= sce->ed= newdataadr(fd, sce->ed);
3220 /* recursive link sequences, lb will be correctly initialized */
3221 link_recurs_seq(fd, &ed->seqbase);
3223 WHILE_SEQ(&ed->seqbase) {
3224 seq->seq1= newdataadr(fd, seq->seq1);
3225 seq->seq2= newdataadr(fd, seq->seq2);
3226 seq->seq3= newdataadr(fd, seq->seq3);
3227 /* a patch: after introduction of effects with 3 input strips */
3228 if(seq->seq3==0) seq->seq3= seq->seq2;
3230 seq->plugin= newdataadr(fd, seq->plugin);
3231 seq->effectdata= newdataadr(fd, seq->effectdata);
3233 if (seq->type & SEQ_EFFECT) {
3234 seq->flag |= SEQ_EFFECT_NOT_LOADED;
3237 seq->strip= newdataadr(fd, seq->strip);
3238 if(seq->strip && seq->strip->done==0) {
3239 seq->strip->done= 1;
3240 seq->strip->tstripdata = 0;
3242 if(seq->type == SEQ_IMAGE ||
3243 seq->type == SEQ_MOVIE ||
3244 seq->type == SEQ_RAM_SOUND ||
3245 seq->type == SEQ_HD_SOUND) {
3246 seq->strip->stripdata = newdataadr(
3247 fd, seq->strip->stripdata);
3248 } else {
3249 seq->strip->stripdata = 0;
3251 if (seq->flag & SEQ_USE_CROP) {
3252 seq->strip->crop = newdataadr(
3253 fd, seq->strip->crop);
3254 } else {
3255 seq->strip->crop = 0;
3257 if (seq->flag & SEQ_USE_TRANSFORM) {
3258 seq->strip->transform = newdataadr(
3259 fd, seq->strip->transform);
3260 } else {
3261 seq->strip->transform = 0;
3263 if (seq->flag & SEQ_USE_PROXY) {
3264 seq->strip->proxy = newdataadr(
3265 fd, seq->strip->proxy);
3266 } else {
3267 seq->strip->proxy = 0;
3271 END_SEQ
3273 /* link metastack, slight abuse of structs here, have to restore pointer to internal part in struct */
3275 Sequence temp;
3276 char *poin;
3277 long offset;
3279 offset= ((long)&(temp.seqbase)) - ((long)&temp);
3281 /* root pointer */
3282 if(ed->seqbasep == old_seqbasep) {
3283 ed->seqbasep= &ed->seqbase;
3285 else {
3287 poin= (char *)ed->seqbasep;
3288 poin -= offset;
3290 poin= newdataadr(fd, poin);
3291 if(poin) ed->seqbasep= (ListBase *)(poin+offset);
3292 else ed->seqbasep= &ed->seqbase;
3294 /* stack */
3295 link_list(fd, &(ed->metastack));
3297 for(ms= ed->metastack.first; ms; ms= ms->next) {
3298 ms->parseq= newdataadr(fd, ms->parseq);
3300 if(ms->oldbasep == old_seqbasep)
3301 ms->oldbasep= &ed->seqbase;
3302 else {
3303 poin= (char *)ms->oldbasep;
3304 poin -= offset;
3305 poin= newdataadr(fd, poin);
3306 if(poin) ms->oldbasep= (ListBase *)(poin+offset);
3307 else ms->oldbasep= &ed->seqbase;
3313 direct_link_scriptlink(fd, &sce->scriptlink);
3315 sce->r.avicodecdata = newdataadr(fd, sce->r.avicodecdata);
3316 if (sce->r.avicodecdata) {
3317 sce->r.avicodecdata->lpFormat = newdataadr(fd, sce->r.avicodecdata->lpFormat);
3318 sce->r.avicodecdata->lpParms = newdataadr(fd, sce->r.avicodecdata->lpParms);
3321 sce->r.qtcodecdata = newdataadr(fd, sce->r.qtcodecdata);
3322 if (sce->r.qtcodecdata) {
3323 sce->r.qtcodecdata->cdParms = newdataadr(fd, sce->r.qtcodecdata->cdParms);
3326 link_list(fd, &(sce->markers));
3327 link_list(fd, &(sce->r.layers));
3328 link_list(fd, &(sce->bg_scenes));
3329 link_list(fd, &(sce->compo_scenes));
3331 sce->nodetree= newdataadr(fd, sce->nodetree);
3332 if(sce->nodetree)
3333 direct_link_nodetree(fd, sce->nodetree);
3337 /* Nasty exception; IpoWindow stores a non-ID pointer in *from for sequence
3338 strips... bad code warning!
3340 We work around it by retrieving the missing pointer from the corresponding
3341 Sequence-structure.
3343 This is needed, to make Ipo-Pinning work for Sequence-Ipos...
3345 static Sequence * find_sequence_from_ipo_helper(Main * main, Ipo * ipo)
3347 Editing *ed;
3348 Sequence *seq = NULL;
3350 Scene * sce= main->scene.first;
3351 while(sce) {
3352 if(sce->ed) {
3353 int found = 0;
3355 ed= sce->ed;
3357 WHILE_SEQ(&ed->seqbase) {
3358 if (seq->ipo == ipo) {
3359 found = 1;
3360 break;
3363 END_SEQ
3364 if (found) {
3365 break;
3367 seq = NULL;
3369 sce= sce->id.next;
3371 if (seq)
3372 return seq;
3373 else
3374 return NULL;
3377 static void lib_link_screen_sequence_ipos(Main *main)
3379 bScreen *sc;
3380 ScrArea *sa;
3382 for(sc= main->screen.first; sc; sc= sc->id.next) {
3383 for(sa= sc->areabase.first; sa; sa= sa->next) {
3384 SpaceLink *sl;
3385 for (sl= sa->spacedata.first; sl; sl= sl->next) {
3386 if(sl->spacetype == SPACE_IPO) {
3387 SpaceIpo *sipo= (SpaceIpo *)sl;
3388 if(sipo->blocktype==ID_SEQ) {
3389 sipo->from = (ID*) find_sequence_from_ipo_helper(main, sipo->ipo);
3397 /* ************ READ SCREEN ***************** */
3399 /* note: file read without screens option G_FILE_NO_UI;
3400 check lib pointers in call below */
3401 static void lib_link_screen(FileData *fd, Main *main)
3403 bScreen *sc;
3404 ScrArea *sa;
3406 for(sc= main->screen.first; sc; sc= sc->id.next) {
3407 if(sc->id.flag & LIB_NEEDLINK) {
3408 sc->id.us= 1;
3409 sc->scene= newlibadr(fd, sc->id.lib, sc->scene);
3411 sa= sc->areabase.first;
3412 while(sa) {
3413 SpaceLink *sl;
3415 sa->full= newlibadr(fd, sc->id.lib, sa->full);
3417 /* space handler scriptlinks */
3418 lib_link_scriptlink(fd, &sc->id, &sa->scriptlink);
3420 for (sl= sa->spacedata.first; sl; sl= sl->next) {
3421 if(sl->spacetype==SPACE_VIEW3D) {
3422 View3D *v3d= (View3D*) sl;
3424 v3d->camera= newlibadr(fd, sc->id.lib, v3d->camera);
3425 v3d->ob_centre= newlibadr(fd, sc->id.lib, v3d->ob_centre);
3427 if(v3d->bgpic) {
3428 v3d->bgpic->ima= newlibadr_us(fd, sc->id.lib, v3d->bgpic->ima);
3430 if(v3d->localvd) {
3431 v3d->localvd->camera= newlibadr(fd, sc->id.lib, v3d->localvd->camera);
3433 v3d->depths= NULL;
3434 v3d->ri= NULL;
3436 else if(sl->spacetype==SPACE_IPO) {
3437 SpaceIpo *sipo= (SpaceIpo *)sl;
3438 sipo->editipo= 0;
3440 if(sipo->blocktype==ID_SEQ) sipo->from= NULL; // no libdata
3441 else sipo->from= newlibadr(fd, sc->id.lib, sipo->from);
3443 sipo->ipokey.first= sipo->ipokey.last= 0;
3444 sipo->ipo= newlibadr(fd, sc->id.lib, sipo->ipo);
3446 else if(sl->spacetype==SPACE_BUTS) {
3447 SpaceButs *sbuts= (SpaceButs *)sl;
3448 sbuts->lockpoin= NULL;
3449 sbuts->ri= NULL;
3450 if(main->versionfile<132) set_rects_butspace(sbuts);
3452 else if(sl->spacetype==SPACE_FILE) {
3453 SpaceFile *sfile= (SpaceFile *)sl;
3455 sfile->filelist= NULL;
3456 sfile->libfiledata= NULL;
3457 sfile->returnfunc= NULL;
3458 sfile->menup= NULL;
3459 sfile->pupmenu= NULL;
3461 else if(sl->spacetype==SPACE_IMASEL) {
3462 check_imasel_copy((SpaceImaSel *)sl);
3464 else if(sl->spacetype==SPACE_ACTION) {
3465 SpaceAction *saction= (SpaceAction *)sl;
3466 saction->action = newlibadr(fd, sc->id.lib, saction->action);
3468 else if(sl->spacetype==SPACE_IMAGE) {
3469 SpaceImage *sima= (SpaceImage *)sl;
3471 sima->image= newlibadr_us(fd, sc->id.lib, sima->image);
3473 else if(sl->spacetype==SPACE_NLA){
3474 /* SpaceNla *snla= (SpaceNla *)sl; */
3476 else if(sl->spacetype==SPACE_TEXT) {
3477 SpaceText *st= (SpaceText *)sl;
3479 st->text= newlibadr(fd, sc->id.lib, st->text);
3482 else if(sl->spacetype==SPACE_SCRIPT) {
3483 SpaceScript *sc= (SpaceScript *)sl;
3485 sc->script = NULL;
3487 else if(sl->spacetype==SPACE_OOPS) {
3488 SpaceOops *so= (SpaceOops *)sl;
3489 Oops *oops;
3490 TreeStoreElem *tselem;
3491 int a;
3493 oops= so->oops.first;
3494 while(oops) {
3495 oops->id= newlibadr(fd, NULL, oops->id);
3496 oops= oops->next;
3498 so->lockpoin= NULL;
3499 so->tree.first= so->tree.last= NULL;
3500 so->search_tse.id= newlibadr(fd, NULL, so->search_tse.id);
3502 if(so->treestore) {
3503 tselem= so->treestore->data;
3504 for(a=0; a<so->treestore->usedelem; a++, tselem++) {
3505 tselem->id= newlibadr(fd, NULL, tselem->id);
3509 else if(sl->spacetype==SPACE_SOUND) {
3510 SpaceSound *ssound= (SpaceSound *)sl;
3512 ssound->sound= newlibadr_us(fd, sc->id.lib, ssound->sound);
3515 sa= sa->next;
3517 sc->id.flag -= LIB_NEEDLINK;
3522 /* Only for undo files, or to restore a screen after reading without UI... */
3523 static void *restore_pointer_by_name(Main *mainp, ID *id, int user)
3526 if(id) {
3527 ListBase *lb= wich_libbase(mainp, GS(id->name));
3529 if(lb) { // there's still risk of checking corrupt mem (freed Ids in oops)
3530 ID *idn= lb->first;
3531 char *name= id->name+2;
3533 while(idn) {
3534 if(idn->name[2]==name[0] && strcmp(idn->name+2, name)==0) {
3535 if(idn->lib==id->lib) {
3536 if(user && idn->us==0) idn->us++;
3537 break;
3540 idn= idn->next;
3542 return idn;
3545 return NULL;
3548 /* called from kernel/blender.c */
3549 /* used to link a file (without UI) to the current UI */
3550 /* note that it assumes the old pointers in UI are still valid, so old Main is not freed */
3551 void lib_link_screen_restore(Main *newmain, Scene *curscene)
3553 bScreen *sc;
3554 ScrArea *sa;
3556 for(sc= newmain->screen.first; sc; sc= sc->id.next) {
3558 sc->scene= restore_pointer_by_name(newmain, (ID *)sc->scene, 1);
3559 if(sc->scene==NULL)
3560 sc->scene= curscene;
3562 sa= sc->areabase.first;
3563 while(sa) {
3564 SpaceLink *sl;
3566 if (sa->scriptlink.totscript) {
3567 /* restore screen area script links */
3568 ScriptLink *slink = &sa->scriptlink;
3569 int script_idx;
3570 for (script_idx = 0; script_idx < slink->totscript; script_idx++) {
3571 slink->scripts[script_idx] = restore_pointer_by_name(newmain,
3572 (ID *)slink->scripts[script_idx], 1);
3576 for (sl= sa->spacedata.first; sl; sl= sl->next) {
3577 if(sl->spacetype==SPACE_VIEW3D) {
3578 View3D *v3d= (View3D*) sl;
3580 v3d->camera= restore_pointer_by_name(newmain, (ID *)v3d->camera, 1);
3581 if(v3d->camera==NULL)
3582 v3d->camera= sc->scene->camera;
3583 v3d->ob_centre= restore_pointer_by_name(newmain, (ID *)v3d->ob_centre, 1);
3585 if(v3d->bgpic) {
3586 v3d->bgpic->ima= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->ima, 1);
3588 if(v3d->localvd) {
3589 Base *base;
3591 v3d->localvd->camera= sc->scene->camera;
3593 /* localview can become invalid during undo/redo steps, so we exit it when no could be found */
3594 for(base= sc->scene->base.first; base; base= base->next) {
3595 if(base->lay & v3d->lay) break;
3597 if(base==NULL) {
3598 v3d->lay= v3d->localvd->lay;
3599 v3d->layact= v3d->localvd->layact;
3600 MEM_freeN(v3d->localvd);
3601 v3d->localvd= NULL;
3602 v3d->localview= 0;
3605 else if(v3d->scenelock) v3d->lay= sc->scene->lay;
3607 /* not very nice, but could help */
3608 if((v3d->layact & v3d->lay)==0) v3d->layact= v3d->lay;
3611 else if(sl->spacetype==SPACE_IPO) {
3612 SpaceIpo *sipo= (SpaceIpo *)sl;
3614 if(sipo->blocktype==ID_SEQ) sipo->from= NULL; // no libdata
3615 else sipo->from= restore_pointer_by_name(newmain, (ID *)sipo->from, 0);
3617 // not free sipo->ipokey, creates dependency with src/
3618 sipo->ipo= restore_pointer_by_name(newmain, (ID *)sipo->ipo, 0);
3619 if(sipo->editipo) MEM_freeN(sipo->editipo);
3620 sipo->editipo= NULL;
3622 else if(sl->spacetype==SPACE_BUTS) {
3623 SpaceButs *sbuts= (SpaceButs *)sl;
3624 sbuts->lockpoin= NULL;
3625 if (sbuts->ri) sbuts->ri->curtile = 0;
3627 else if(sl->spacetype==SPACE_FILE) {
3628 SpaceFile *sfile= (SpaceFile *)sl;
3629 if(sfile->libfiledata)
3630 BLO_blendhandle_close(sfile->libfiledata);
3631 sfile->libfiledata= 0;
3633 else if(sl->spacetype==SPACE_IMASEL) {
3636 else if(sl->spacetype==SPACE_ACTION) {
3637 SpaceAction *saction= (SpaceAction *)sl;
3638 saction->action = restore_pointer_by_name(newmain, (ID *)saction->action, 1);
3640 else if(sl->spacetype==SPACE_IMAGE) {
3641 SpaceImage *sima= (SpaceImage *)sl;
3643 sima->image= restore_pointer_by_name(newmain, (ID *)sima->image, 1);
3645 else if(sl->spacetype==SPACE_NLA){
3646 /* SpaceNla *snla= (SpaceNla *)sl; */
3648 else if(sl->spacetype==SPACE_TEXT) {
3649 SpaceText *st= (SpaceText *)sl;
3651 st->text= restore_pointer_by_name(newmain, (ID *)st->text, 1);
3652 if(st->text==NULL) st->text= newmain->text.first;
3654 else if(sl->spacetype==SPACE_SCRIPT) {
3655 SpaceScript *sc= (SpaceScript *)sl;
3657 sc->script = NULL;
3659 else if(sl->spacetype==SPACE_OOPS) {
3660 SpaceOops *so= (SpaceOops *)sl;
3661 Oops *oops;
3662 int a;
3664 oops= so->oops.first;
3665 while(oops) {
3666 oops->id= restore_pointer_by_name(newmain, (ID *)oops->id, 0);
3667 oops= oops->next;
3669 so->lockpoin= NULL;
3670 so->search_tse.id= restore_pointer_by_name(newmain, so->search_tse.id, 0);
3672 if(so->treestore) {
3673 TreeStore *ts= so->treestore;
3674 TreeStoreElem *tselem=ts->data;
3675 for(a=0; a<ts->usedelem; a++, tselem++) {
3676 tselem->id= restore_pointer_by_name(newmain, tselem->id, 0);
3680 else if(sl->spacetype==SPACE_SOUND) {
3681 SpaceSound *ssound= (SpaceSound *)sl;
3683 ssound->sound= restore_pointer_by_name(newmain, (ID *)ssound->sound, 1);
3685 else if(sl->spacetype==SPACE_NODE) {
3686 SpaceNode *snode= (SpaceNode *)sl;
3688 snode->nodetree= snode->edittree= NULL;
3689 snode->flag |= SNODE_DO_PREVIEW;
3692 sa= sa->next;
3697 static void direct_link_screen(FileData *fd, bScreen *sc)
3699 ScrArea *sa;
3700 ScrVert *sv;
3701 ScrEdge *se;
3702 Oops *oops;
3703 int a;
3705 link_list(fd, &(sc->vertbase));
3706 link_list(fd, &(sc->edgebase));
3707 link_list(fd, &(sc->areabase));
3708 sc->winakt= 0;
3710 /* hacky patch... but people have been saving files with the verse-blender,
3711 causing the handler to keep running for ever, with no means to disable it */
3712 for(a=0; a<SCREEN_MAXHANDLER; a+=2) {
3713 if( sc->handler[a]==SCREEN_HANDLER_VERSE) {
3714 sc->handler[a]= 0;
3715 break;
3719 /* edges */
3720 se= sc->edgebase.first;
3721 while(se) {
3722 se->v1= newdataadr(fd, se->v1);
3723 se->v2= newdataadr(fd, se->v2);
3724 if( (long)se->v1 > (long)se->v2) {
3725 sv= se->v1;
3726 se->v1= se->v2;
3727 se->v2= sv;
3730 if(se->v1==NULL) {
3731 printf("error reading screen... file corrupt\n");
3732 se->v1= se->v2;
3734 se= se->next;
3737 /* areas */
3738 sa= sc->areabase.first;
3739 while(sa) {
3740 Panel *pa;
3741 SpaceLink *sl;
3743 link_list(fd, &(sa->spacedata));
3744 link_list(fd, &(sa->panels));
3746 /* accident can happen when read/save new file with older version */
3747 if(sa->spacedata.first==NULL && sa->spacetype>SPACE_NLA)
3748 sa->spacetype= SPACE_EMPTY;
3750 for(pa= sa->panels.first; pa; pa=pa->next) {
3751 pa->paneltab= newdataadr(fd, pa->paneltab);
3752 pa->active= 0;
3753 pa->sortcounter= 0;
3756 for (sl= sa->spacedata.first; sl; sl= sl->next) {
3757 if (sl->spacetype==SPACE_VIEW3D) {
3758 View3D *v3d= (View3D*) sl;
3759 v3d->bgpic= newdataadr(fd, v3d->bgpic);
3760 if(v3d->bgpic)
3761 v3d->bgpic->iuser.ok= 1;
3762 v3d->localvd= newdataadr(fd, v3d->localvd);
3763 v3d->afterdraw.first= v3d->afterdraw.last= NULL;
3764 v3d->clipbb= newdataadr(fd, v3d->clipbb);
3765 v3d->retopo_view_data= NULL;
3766 v3d->properties_storage= NULL;
3768 else if (sl->spacetype==SPACE_OOPS) {
3769 SpaceOops *soops= (SpaceOops*) sl;
3771 link_list(fd, &(soops->oops));
3772 oops= soops->oops.first;
3773 while(oops) {
3774 oops->link.first= oops->link.last= 0;
3775 oops= oops->next;
3778 soops->treestore= newdataadr(fd, soops->treestore);
3779 if(soops->treestore) {
3780 soops->treestore->data= newdataadr(fd, soops->treestore->data);
3781 /* we only saved what was used */
3782 soops->treestore->totelem= soops->treestore->usedelem;
3783 soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw
3786 else if(sl->spacetype==SPACE_IMAGE) {
3787 SpaceImage *sima= (SpaceImage *)sl;
3789 sima->cumap= newdataadr(fd, sima->cumap);
3790 if(sima->cumap)
3791 direct_link_curvemapping(fd, sima->cumap);
3792 sima->levmap= newdataadr(fd, sima->levmap);
3793 if(sima->levmap)
3794 direct_link_levelmapping(fd, sima->levmap);
3795 sima->info_str= sima->info_spare= NULL;
3796 sima->spare= NULL;
3797 sima->iuser.ok= 1;
3799 else if(sl->spacetype==SPACE_NODE) {
3800 SpaceNode *snode= (SpaceNode *)sl;
3801 snode->nodetree= snode->edittree= NULL;
3802 snode->flag |= SNODE_DO_PREVIEW;
3806 sa->v1= newdataadr(fd, sa->v1);
3807 sa->v2= newdataadr(fd, sa->v2);
3808 sa->v3= newdataadr(fd, sa->v3);
3809 sa->v4= newdataadr(fd, sa->v4);
3811 sa->win= sa->headwin= 0;
3813 sa->uiblocks.first= sa->uiblocks.last= NULL;
3815 /* space handler scriptlinks */
3816 direct_link_scriptlink(fd, &sa->scriptlink);
3818 sa= sa->next;
3822 /* ********** READ LIBRARY *************** */
3825 static void direct_link_library(FileData *fd, Library *lib, Main *main)
3827 Main *newmain;
3829 for(newmain= fd->mainlist.first; newmain; newmain= newmain->next) {
3830 if(newmain->curlib) {
3831 if(strcmp(newmain->curlib->filename, lib->filename)==0) {
3832 printf("Fixed error in file; multiple instances of lib:\n %s\n", lib->filename);
3834 change_idid_adr(&fd->mainlist, fd, lib, newmain->curlib);
3835 // change_idid_adr_fd(fd, lib, newmain->curlib);
3837 BLI_remlink(&main->library, lib);
3838 MEM_freeN(lib);
3840 error("Library had multiple instances, save and reload!");
3841 return;
3845 /* make sure we have full path in lib->filename */
3846 BLI_strncpy(lib->filename, lib->name, sizeof(lib->name));
3847 cleanup_path(fd->filename, lib->filename);
3849 // printf("direct_link_library: name %s\n", lib->name);
3850 // printf("direct_link_library: filename %s\n", lib->filename);
3852 /* new main */
3853 newmain= MEM_callocN(sizeof(Main), "directlink");
3854 BLI_addtail(&fd->mainlist, newmain);
3855 newmain->curlib= lib;
3857 lib->parent= NULL;
3860 static void lib_link_library(FileData *fd, Main *main)
3862 Library *lib;
3864 lib= main->library.first;
3865 while(lib) {
3866 lib->id.us= 1;
3867 lib= lib->id.next;
3871 /* ************** READ SOUND ******************* */
3873 static void direct_link_sound(FileData *fd, bSound *sound)
3875 sound->sample = NULL;
3876 sound->snd_sound = NULL;
3878 sound->packedfile = direct_link_packedfile(fd, sound->packedfile);
3879 sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile);
3882 static void lib_link_sound(FileData *fd, Main *main)
3884 bSound *sound;
3886 sound= main->sound.first;
3887 while(sound) {
3888 if(sound->id.flag & LIB_NEEDLINK) {
3889 sound->id.flag -= LIB_NEEDLINK;
3890 sound->ipo= newlibadr_us(fd, sound->id.lib, sound->ipo);
3891 sound->stream = 0;
3893 sound= sound->id.next;
3896 /* ***************** READ GROUP *************** */
3898 static void direct_link_group(FileData *fd, Group *group)
3900 link_list(fd, &group->gobject);
3903 static void lib_link_group(FileData *fd, Main *main)
3905 Group *group= main->group.first;
3906 GroupObject *go;
3907 int add_us;
3909 while(group) {
3910 if(group->id.flag & LIB_NEEDLINK) {
3911 group->id.flag -= LIB_NEEDLINK;
3913 add_us= 0;
3915 go= group->gobject.first;
3916 while(go) {
3917 go->ob= newlibadr(fd, group->id.lib, go->ob);
3918 if(go->ob) {
3919 go->ob->flag |= OB_FROMGROUP;
3920 /* if group has an object, it increments user... */
3921 add_us= 1;
3922 if(go->ob->id.us==0)
3923 go->ob->id.us= 1;
3925 go= go->next;
3927 if(add_us) group->id.us++;
3928 rem_from_group(group, NULL); /* removes NULL entries */
3930 group= group->id.next;
3934 /* ************** GENERAL & MAIN ******************** */
3937 static char *dataname(short id_code)
3940 switch( id_code ) {
3941 case ID_OB: return "Data from OB";
3942 case ID_ME: return "Data from ME";
3943 case ID_IP: return "Data from IP";
3944 case ID_SCE: return "Data from SCE";
3945 case ID_MA: return "Data from MA";
3946 case ID_TE: return "Data from TE";
3947 case ID_CU: return "Data from CU";
3948 case ID_GR: return "Data from GR";
3949 case ID_AR: return "Data from AR";
3950 case ID_AC: return "Data from AC";
3951 case ID_LI: return "Data from LI";
3952 case ID_MB: return "Data from MB";
3953 case ID_IM: return "Data from IM";
3954 case ID_LT: return "Data from LT";
3955 case ID_LA: return "Data from LA";
3956 case ID_CA: return "Data from CA";
3957 case ID_KE: return "Data from KE";
3958 case ID_WO: return "Data from WO";
3959 case ID_SCR: return "Data from SCR";
3960 case ID_VF: return "Data from VF";
3961 case ID_TXT : return "Data from TXT";
3962 case ID_SO: return "Data from SO";
3963 case ID_NT: return "Data from NT";
3964 case ID_BR: return "Data from BR";
3966 return "Data from Lib Block";
3970 static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID **id_r)
3972 /* this routine reads a libblock and its direct data. Use link functions
3973 * to connect it all
3976 ID *id;
3977 ListBase *lb;
3978 char *allocname;
3980 /* read libblock */
3981 id = read_struct(fd, bhead, "lib block");
3982 if (id_r)
3983 *id_r= id;
3984 if (!id)
3985 return blo_nextbhead(fd, bhead);
3987 oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); /* for ID_ID check */
3989 /* do after read_struct, for dna reconstruct */
3990 if(bhead->code==ID_ID) {
3991 lb= wich_libbase(main, GS(id->name));
3993 else {
3994 lb= wich_libbase(main, bhead->code);
3997 BLI_addtail(lb, id);
3999 /* clear first 8 bits */
4000 id->flag= (id->flag & 0xFF00) | flag | LIB_NEEDLINK;
4001 id->lib= main->curlib;
4002 if(id->flag & LIB_FAKEUSER) id->us= 1;
4003 else id->us= 0;
4004 id->icon_id = 0;
4006 /* this case cannot be direct_linked: it's just the ID part */
4007 if(bhead->code==ID_ID) {
4008 return blo_nextbhead(fd, bhead);
4011 bhead = blo_nextbhead(fd, bhead);
4013 /* need a name for the mallocN, just for debugging and sane prints on leaks */
4014 allocname= dataname(GS(id->name));
4016 /* read all data */
4017 while(bhead && bhead->code==DATA) {
4018 void *data= read_struct(fd, bhead, allocname);
4020 if (data) {
4021 oldnewmap_insert(fd->datamap, bhead->old, data, 0);
4024 bhead = blo_nextbhead(fd, bhead);
4027 /* init pointers direct data */
4028 switch( GS(id->name) ) {
4029 case ID_SCR:
4030 direct_link_screen(fd, (bScreen *)id);
4031 break;
4032 case ID_SCE:
4033 direct_link_scene(fd, (Scene *)id);
4034 break;
4035 case ID_OB:
4036 direct_link_object(fd, (Object *)id);
4037 break;
4038 case ID_ME:
4039 direct_link_mesh(fd, (Mesh *)id);
4040 break;
4041 case ID_CU:
4042 direct_link_curve(fd, (Curve *)id);
4043 break;
4044 case ID_MB:
4045 direct_link_mball(fd, (MetaBall *)id);
4046 break;
4047 case ID_MA:
4048 direct_link_material(fd, (Material *)id);
4049 break;
4050 case ID_TE:
4051 direct_link_texture(fd, (Tex *)id);
4052 break;
4053 case ID_IM:
4054 direct_link_image(fd, (Image *)id);
4055 break;
4056 case ID_LA:
4057 direct_link_lamp(fd, (Lamp *)id);
4058 break;
4059 case ID_VF:
4060 direct_link_vfont(fd, (VFont *)id);
4061 break;
4062 case ID_TXT:
4063 direct_link_text(fd, (Text *)id);
4064 break;
4065 case ID_IP:
4066 direct_link_ipo(fd, (Ipo *)id);
4067 break;
4068 case ID_KE:
4069 direct_link_key(fd, (Key *)id);
4070 break;
4071 case ID_LT:
4072 direct_link_latt(fd, (Lattice *)id);
4073 break;
4074 case ID_WO:
4075 direct_link_world(fd, (World *)id);
4076 break;
4077 case ID_LI:
4078 direct_link_library(fd, (Library *)id, main);
4079 break;
4080 case ID_CA:
4081 direct_link_camera(fd, (Camera *)id);
4082 break;
4083 case ID_SO:
4084 direct_link_sound(fd, (bSound *)id);
4085 break;
4086 case ID_GR:
4087 direct_link_group(fd, (Group *)id);
4088 break;
4089 case ID_AR:
4090 direct_link_armature(fd, (bArmature*)id);
4091 break;
4092 case ID_AC:
4093 direct_link_action(fd, (bAction*)id);
4094 break;
4095 case ID_NT:
4096 direct_link_nodetree(fd, (bNodeTree*)id);
4097 break;
4098 case ID_BR:
4099 direct_link_brush(fd, (Brush*)id);
4100 break;
4103 /*link direct data of ID properties*/
4104 if (id->properties) {
4105 id->properties = newdataadr(fd, id->properties);
4106 IDP_DirectLinkProperty(id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
4109 oldnewmap_free_unused(fd->datamap);
4110 oldnewmap_clear(fd->datamap);
4112 return (bhead);
4115 static void link_global(FileData *fd, BlendFileData *bfd, FileGlobal *fg)
4117 // this is nonsense... make it struct once (ton)
4118 bfd->winpos= fg->winpos;
4119 bfd->fileflags= fg->fileflags;
4120 bfd->displaymode= fg->displaymode;
4121 bfd->globalf= fg->globalf;
4123 bfd->curscreen= newlibadr(fd, 0, fg->curscreen);
4124 bfd->curscene= newlibadr(fd, 0, fg->curscene);
4125 // this happens in files older than 2.35
4126 if(bfd->curscene==NULL) {
4127 if(bfd->curscreen) bfd->curscene= bfd->curscreen->scene;
4131 static void vcol_to_fcol(Mesh *me)
4133 MFace *mface;
4134 unsigned int *mcol, *mcoln, *mcolmain;
4135 int a;
4137 if(me->totface==0 || me->mcol==0) return;
4139 mcoln= mcolmain= MEM_mallocN(4*sizeof(int)*me->totface, "mcoln");
4140 mcol = (unsigned int *)me->mcol;
4141 mface= me->mface;
4142 for(a=me->totface; a>0; a--, mface++) {
4143 mcoln[0]= mcol[mface->v1];
4144 mcoln[1]= mcol[mface->v2];
4145 mcoln[2]= mcol[mface->v3];
4146 mcoln[3]= mcol[mface->v4];
4147 mcoln+= 4;
4150 MEM_freeN(me->mcol);
4151 me->mcol= (MCol *)mcolmain;
4154 static int map_223_keybd_code_to_224_keybd_code(int code)
4156 switch (code) {
4157 case 312: return F12KEY;
4158 case 159: return PADSLASHKEY;
4159 case 161: return PAD0;
4160 case 154: return PAD1;
4161 case 150: return PAD2;
4162 case 155: return PAD3;
4163 case 151: return PAD4;
4164 case 156: return PAD5;
4165 case 152: return PAD6;
4166 case 157: return PAD7;
4167 case 153: return PAD8;
4168 case 158: return PAD9;
4169 default: return code;
4173 static void bone_version_238(ListBase *lb)
4175 Bone *bone;
4177 for(bone= lb->first; bone; bone= bone->next) {
4178 if(bone->rad_tail==0.0f && bone->rad_head==0.0f) {
4179 bone->rad_head= 0.25f*bone->length;
4180 bone->rad_tail= 0.1f*bone->length;
4182 bone->dist-= bone->rad_head;
4183 if(bone->dist<=0.0f) bone->dist= 0.0f;
4185 bone_version_238(&bone->childbase);
4189 static void bone_version_239(ListBase *lb)
4191 Bone *bone;
4193 for(bone= lb->first; bone; bone= bone->next) {
4194 if(bone->layer==0)
4195 bone->layer= 1;
4196 bone_version_239(&bone->childbase);
4200 static void ntree_version_241(bNodeTree *ntree)
4202 bNode *node;
4204 if(ntree->type==NTREE_COMPOSIT) {
4205 for(node= ntree->nodes.first; node; node= node->next) {
4206 if(node->type==CMP_NODE_BLUR) {
4207 if(node->storage==NULL) {
4208 NodeBlurData *nbd= MEM_callocN(sizeof(NodeBlurData), "node blur patch");
4209 nbd->sizex= node->custom1;
4210 nbd->sizey= node->custom2;
4211 nbd->filtertype= R_FILTER_QUAD;
4212 node->storage= nbd;
4215 else if(node->type==CMP_NODE_VECBLUR) {
4216 if(node->storage==NULL) {
4217 NodeBlurData *nbd= MEM_callocN(sizeof(NodeBlurData), "node blur patch");
4218 nbd->samples= node->custom1;
4219 nbd->maxspeed= node->custom2;
4220 nbd->fac= 1.0f;
4221 node->storage= nbd;
4228 static void ntree_version_242(bNodeTree *ntree)
4230 bNode *node;
4232 if(ntree->type==NTREE_COMPOSIT) {
4233 for(node= ntree->nodes.first; node; node= node->next) {
4234 if(node->type==CMP_NODE_HUE_SAT) {
4235 if(node->storage) {
4236 NodeHueSat *nhs= node->storage;
4237 if(nhs->val==0.0f) nhs->val= 1.0f;
4242 else if(ntree->type==NTREE_SHADER) {
4243 for(node= ntree->nodes.first; node; node= node->next)
4244 if(node->type == SH_NODE_GEOMETRY && node->storage == NULL)
4245 node->storage= MEM_callocN(sizeof(NodeGeometry), "NodeGeometry");
4250 static void ntree_version_245_2(bNodeTree *ntree)
4252 bNode *node;
4254 if(ntree->type==NTREE_COMPOSIT) {
4255 for(node= ntree->nodes.first; node; node= node->next) {
4256 if(node->type==CMP_NODE_FGBLUR) {
4257 if(node->storage==NULL) {
4258 NodeFGBlurData *nbd= MEM_callocN(sizeof(NodeFGBlurData), "node fg blur patch");
4259 nbd->sizex= 0.0f;
4260 nbd->sizey= 0.0f;
4261 nbd->percentx= 0.0f;
4262 nbd->percenty= 0.0f;
4263 nbd->relative= 0;
4264 node->storage= nbd;
4271 static void ntree_version_245_4(bNodeTree *ntree)
4273 bNode *node;
4274 NodeTwoFloats *ntf;
4276 if(ntree->type==NTREE_COMPOSIT) {
4277 for(node= ntree->nodes.first; node; node= node->next) {
4278 if(node->type==CMP_NODE_ALPHAOVER) {
4279 if(node->storage==NULL) {
4280 ntf= MEM_callocN(sizeof(NodeTwoFloats), "NodeTwoFloats");
4281 node->storage= ntf;
4282 if(node->custom1)
4283 ntf->x= 1.0f;
4290 /* somehow, probably importing via python, keyblock adrcodes are not in order */
4291 static void sort_shape_fix(Main *main)
4293 Key *key;
4294 KeyBlock *kb;
4295 int sorted= 0;
4297 while(sorted==0) {
4298 sorted= 1;
4299 for(key= main->key.first; key; key= key->id.next) {
4300 for(kb= key->block.first; kb; kb= kb->next) {
4301 if(kb->next && kb->adrcode>kb->next->adrcode) {
4302 KeyBlock *next= kb->next;
4303 BLI_remlink(&key->block, kb);
4304 BLI_insertlink(&key->block, next, kb);
4305 kb= next;
4306 sorted= 0;
4310 if(sorted==0) printf("warning, shape keys were sorted incorrect, fixed it!\n");
4314 static void customdata_version_242(Mesh *me)
4316 CustomDataLayer *layer;
4317 MTFace *mtf;
4318 MCol *mcol;
4319 TFace *tf;
4320 int a, mtfacen, mcoln;
4322 if (!me->vdata.totlayer) {
4323 CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, me->mvert, me->totvert);
4325 if (me->msticky)
4326 CustomData_add_layer(&me->vdata, CD_MSTICKY, CD_ASSIGN, me->msticky, me->totvert);
4327 if (me->dvert)
4328 CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_ASSIGN, me->dvert, me->totvert);
4331 if (!me->edata.totlayer)
4332 CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, me->medge, me->totedge);
4334 if (!me->fdata.totlayer) {
4335 CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, me->mface, me->totface);
4337 if (me->tface) {
4338 if (me->mcol)
4339 MEM_freeN(me->mcol);
4341 me->mcol= CustomData_add_layer(&me->fdata, CD_MCOL, CD_CALLOC, NULL, me->totface);
4342 me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface);
4344 mtf= me->mtface;
4345 mcol= me->mcol;
4346 tf= me->tface;
4348 for (a=0; a < me->totface; a++, mtf++, tf++, mcol+=4) {
4349 memcpy(mcol, tf->col, sizeof(tf->col));
4350 memcpy(mtf->uv, tf->uv, sizeof(tf->uv));
4352 mtf->flag= tf->flag;
4353 mtf->unwrap= tf->unwrap;
4354 mtf->mode= tf->mode;
4355 mtf->tile= tf->tile;
4356 mtf->tpage= tf->tpage;
4357 mtf->transp= tf->transp;
4360 MEM_freeN(me->tface);
4361 me->tface= NULL;
4363 else if (me->mcol) {
4364 me->mcol= CustomData_add_layer(&me->fdata, CD_MCOL, CD_ASSIGN, me->mcol, me->totface);
4368 if (me->tface) {
4369 MEM_freeN(me->tface);
4370 me->tface= NULL;
4373 for (a=0, mtfacen=0, mcoln=0; a < me->fdata.totlayer; a++) {
4374 layer= &me->fdata.layers[a];
4376 if (layer->type == CD_MTFACE) {
4377 if (layer->name[0] == 0) {
4378 if (mtfacen == 0) strcpy(layer->name, "UVTex");
4379 else sprintf(layer->name, "UVTex.%.3d", mtfacen);
4381 mtfacen++;
4383 else if (layer->type == CD_MCOL) {
4384 if (layer->name[0] == 0) {
4385 if (mcoln == 0) strcpy(layer->name, "Col");
4386 else sprintf(layer->name, "Col.%.3d", mcoln);
4388 mcoln++;
4392 mesh_update_customdata_pointers(me);
4395 /*only copy render texface layer from active*/
4396 static void customdata_version_243(Mesh *me)
4398 CustomDataLayer *layer;
4399 int a;
4401 for (a=0; a < me->fdata.totlayer; a++) {
4402 layer= &me->fdata.layers[a];
4403 layer->active_rnd = layer->active;
4407 /* struct NodeImageAnim moved to ImageUser, and we make it default available */
4408 static void do_version_ntree_242_2(bNodeTree *ntree)
4410 bNode *node;
4412 if(ntree->type==NTREE_COMPOSIT) {
4413 for(node= ntree->nodes.first; node; node= node->next) {
4414 if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
4415 /* only image had storage */
4416 if(node->storage) {
4417 NodeImageAnim *nia= node->storage;
4418 ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "ima user node");
4420 iuser->frames= nia->frames;
4421 iuser->sfra= nia->sfra;
4422 iuser->offset= nia->nr-1;
4423 iuser->cycl= nia->cyclic;
4424 iuser->fie_ima= 2;
4425 iuser->ok= 1;
4427 node->storage= iuser;
4428 MEM_freeN(nia);
4430 else {
4431 ImageUser *iuser= node->storage= MEM_callocN(sizeof(ImageUser), "node image user");
4432 iuser->sfra= 1;
4433 iuser->fie_ima= 2;
4434 iuser->ok= 1;
4441 static void do_versions(FileData *fd, Library *lib, Main *main)
4443 /* WATCH IT!!!: pointers from libdata have not been converted */
4445 if(G.f & G_DEBUG)
4446 printf("read file %s\n Version %d sub %d\n", fd->filename, main->versionfile, main->subversionfile);
4448 if(main->versionfile == 100) {
4449 /* tex->extend and tex->imageflag have changed: */
4450 Tex *tex = main->tex.first;
4451 while(tex) {
4452 if(tex->id.flag & LIB_NEEDLINK) {
4454 if(tex->extend==0) {
4455 if(tex->xrepeat || tex->yrepeat) tex->extend= TEX_REPEAT;
4456 else {
4457 tex->extend= TEX_EXTEND;
4458 tex->xrepeat= tex->yrepeat= 1;
4463 tex= tex->id.next;
4466 if(main->versionfile <= 101) {
4467 /* frame mapping */
4468 Scene *sce = main->scene.first;
4469 while(sce) {
4470 sce->r.framapto= 100;
4471 sce->r.images= 100;
4472 sce->r.framelen= 1.0;
4473 sce= sce->id.next;
4476 if(main->versionfile <= 102) {
4477 /* init halo's at 1.0 */
4478 Material *ma = main->mat.first;
4479 while(ma) {
4480 ma->add= 1.0;
4481 ma= ma->id.next;
4484 if(main->versionfile <= 103) {
4485 /* new variable in object: colbits */
4486 Object *ob = main->object.first;
4487 int a;
4488 while(ob) {
4489 ob->colbits= 0;
4490 if(ob->totcol) {
4491 for(a=0; a<ob->totcol; a++) {
4492 if(ob->mat[a]) ob->colbits |= (1<<a);
4495 ob= ob->id.next;
4498 if(main->versionfile <= 104) {
4499 /* timeoffs moved */
4500 Object *ob = main->object.first;
4501 while(ob) {
4502 if(ob->transflag & 1) {
4503 ob->transflag -= 1;
4504 ob->ipoflag |= OB_OFFS_OB;
4506 ob= ob->id.next;
4509 if(main->versionfile <= 105) {
4510 Object *ob = main->object.first;
4511 while(ob) {
4512 ob->dupon= 1; ob->dupoff= 0;
4513 ob->dupsta= 1; ob->dupend= 100;
4514 ob= ob->id.next;
4517 if(main->versionfile <= 106) {
4518 /* mcol changed */
4519 Mesh *me = main->mesh.first;
4520 while(me) {
4521 if(me->mcol) vcol_to_fcol(me);
4522 me= me->id.next;
4526 if(main->versionfile <= 107) {
4527 Object *ob;
4528 Scene *sce = main->scene.first;
4529 while(sce) {
4530 sce->r.mode |= R_GAMMA;
4531 sce= sce->id.next;
4533 ob= main->object.first;
4534 while(ob) {
4535 ob->ipoflag |= OB_OFFS_PARENT;
4536 if(ob->dt==0) ob->dt= OB_SOLID;
4537 ob= ob->id.next;
4541 if(main->versionfile <= 109) {
4542 /* new variable: gridlines */
4543 bScreen *sc = main->screen.first;
4544 while(sc) {
4545 ScrArea *sa= sc->areabase.first;
4546 while(sa) {
4547 SpaceLink *sl= sa->spacedata.first;
4548 while (sl) {
4549 if (sl->spacetype==SPACE_VIEW3D) {
4550 View3D *v3d= (View3D*) sl;
4552 if (v3d->gridlines==0) v3d->gridlines= 20;
4554 sl= sl->next;
4556 sa= sa->next;
4558 sc= sc->id.next;
4561 if(main->versionfile <= 112) {
4562 Mesh *me = main->mesh.first;
4563 while(me) {
4564 me->cubemapsize= 1.0;
4565 me= me->id.next;
4568 if(main->versionfile <= 113) {
4569 Material *ma = main->mat.first;
4570 while(ma) {
4571 if(ma->flaresize==0.0) ma->flaresize= 1.0;
4572 ma->subsize= 1.0;
4573 ma->flareboost= 1.0;
4574 ma= ma->id.next;
4578 if(main->versionfile <= 134) {
4579 Tex *tex = main->tex.first;
4580 while (tex) {
4581 if ((tex->rfac == 0.0) &&
4582 (tex->gfac == 0.0) &&
4583 (tex->bfac == 0.0)) {
4584 tex->rfac = 1.0;
4585 tex->gfac = 1.0;
4586 tex->bfac = 1.0;
4587 tex->filtersize = 1.0;
4589 tex = tex->id.next;
4592 if(main->versionfile <= 140) {
4593 /* r-g-b-fac in texure */
4594 Tex *tex = main->tex.first;
4595 while (tex) {
4596 if ((tex->rfac == 0.0) &&
4597 (tex->gfac == 0.0) &&
4598 (tex->bfac == 0.0)) {
4599 tex->rfac = 1.0;
4600 tex->gfac = 1.0;
4601 tex->bfac = 1.0;
4602 tex->filtersize = 1.0;
4604 tex = tex->id.next;
4607 if(main->versionfile <= 153) {
4608 Scene *sce = main->scene.first;
4609 while(sce) {
4610 if(sce->r.blurfac==0.0) sce->r.blurfac= 1.0;
4611 sce= sce->id.next;
4614 if(main->versionfile <= 163) {
4615 Scene *sce = main->scene.first;
4616 while(sce) {
4617 if(sce->r.frs_sec==0) sce->r.frs_sec= 25;
4618 sce= sce->id.next;
4621 if(main->versionfile <= 164) {
4622 Mesh *me= main->mesh.first;
4623 while(me) {
4624 me->smoothresh= 30;
4625 me= me->id.next;
4628 if(main->versionfile <= 165) {
4629 Mesh *me= main->mesh.first;
4630 TFace *tface;
4631 int nr;
4632 char *cp;
4634 while(me) {
4635 if(me->tface) {
4636 nr= me->totface;
4637 tface= me->tface;
4638 while(nr--) {
4639 cp= (char *)&tface->col[0];
4640 if(cp[1]>126) cp[1]= 255; else cp[1]*=2;
4641 if(cp[2]>126) cp[2]= 255; else cp[2]*=2;
4642 if(cp[3]>126) cp[3]= 255; else cp[3]*=2;
4643 cp= (char *)&tface->col[1];
4644 if(cp[1]>126) cp[1]= 255; else cp[1]*=2;
4645 if(cp[2]>126) cp[2]= 255; else cp[2]*=2;
4646 if(cp[3]>126) cp[3]= 255; else cp[3]*=2;
4647 cp= (char *)&tface->col[2];
4648 if(cp[1]>126) cp[1]= 255; else cp[1]*=2;
4649 if(cp[2]>126) cp[2]= 255; else cp[2]*=2;
4650 if(cp[3]>126) cp[3]= 255; else cp[3]*=2;
4651 cp= (char *)&tface->col[3];
4652 if(cp[1]>126) cp[1]= 255; else cp[1]*=2;
4653 if(cp[2]>126) cp[2]= 255; else cp[2]*=2;
4654 if(cp[3]>126) cp[3]= 255; else cp[3]*=2;
4656 tface++;
4659 me= me->id.next;
4663 if(main->versionfile <= 169) {
4664 Mesh *me= main->mesh.first;
4665 while(me) {
4666 if(me->subdiv==0) me->subdiv= 1;
4667 me= me->id.next;
4671 if(main->versionfile <= 169) {
4672 bScreen *sc= main->screen.first;
4673 while(sc) {
4674 ScrArea *sa= sc->areabase.first;
4675 while(sa) {
4676 SpaceLink *sl= sa->spacedata.first;
4677 while(sl) {
4678 if(sl->spacetype==SPACE_IPO) {
4679 SpaceIpo *sipo= (SpaceIpo*) sl;
4680 sipo->v2d.max[0]= 15000.0;
4682 sl= sl->next;
4684 sa= sa->next;
4686 sc= sc->id.next;
4690 if(main->versionfile <= 170) {
4691 Object *ob = main->object.first;
4692 PartEff *paf;
4693 while (ob) {
4694 paf = give_parteff(ob);
4695 if (paf) {
4696 if (paf->staticstep == 0) {
4697 paf->staticstep= 5;
4700 ob = ob->id.next;
4704 if(main->versionfile <= 171) {
4705 bScreen *sc= main->screen.first;
4706 while(sc) {
4707 ScrArea *sa= sc->areabase.first;
4708 while(sa) {
4709 SpaceLink *sl= sa->spacedata.first;
4710 while(sl) {
4711 if(sl->spacetype==SPACE_TEXT) {
4712 SpaceText *st= (SpaceText*) sl;
4713 if(st->font_id>1) {
4714 st->font_id= 0;
4715 st->lheight= 13;
4718 sl= sl->next;
4720 sa= sa->next;
4722 sc= sc->id.next;
4726 if(main->versionfile <= 173) {
4727 int a, b;
4728 Mesh *me= main->mesh.first;
4729 while(me) {
4730 if(me->tface) {
4731 TFace *tface= me->tface;
4732 for(a=0; a<me->totface; a++, tface++) {
4733 for(b=0; b<4; b++) {
4734 tface->uv[b][0]/= 32767.0;
4735 tface->uv[b][1]/= 32767.0;
4739 me= me->id.next;
4743 if(main->versionfile <= 191) {
4744 bScreen *sc= main->screen.first;
4745 Object *ob= main->object.first;
4746 Material *ma = main->mat.first;
4748 /* let faces have default add factor of 0.0 */
4749 while(ma) {
4750 if (!(ma->mode & MA_HALO)) ma->add = 0.0;
4751 ma = ma->id.next;
4754 while(ob) {
4755 ob->mass= 1.0f;
4756 ob->damping= 0.1f;
4757 ob->quat[1]= 1.0f;
4758 ob= ob->id.next;
4761 while(sc) {
4762 ScrArea *sa= sc->areabase.first;
4763 while(sa) {
4764 SpaceLink *sl= sa->spacedata.first;
4765 while(sl) {
4766 if(sl->spacetype==SPACE_BUTS) {
4767 SpaceButs *sbuts= (SpaceButs*) sl;
4768 sbuts->scaflag= BUTS_SENS_LINK|BUTS_SENS_ACT|BUTS_CONT_ACT|BUTS_ACT_ACT|BUTS_ACT_LINK;
4770 sl= sl->next;
4772 sa= sa->next;
4774 sc= sc->id.next;
4778 if(main->versionfile <= 193) {
4779 Object *ob= main->object.first;
4780 while(ob) {
4781 ob->inertia= 1.0f;
4782 ob->rdamping= 0.1f;
4783 ob= ob->id.next;
4787 if(main->versionfile <= 196) {
4788 Mesh *me= main->mesh.first;
4789 int a, b;
4790 while(me) {
4791 if(me->tface) {
4792 TFace *tface= me->tface;
4793 for(a=0; a<me->totface; a++, tface++) {
4794 for(b=0; b<4; b++) {
4795 tface->mode |= TF_DYNAMIC;
4796 tface->mode &= ~TF_INVISIBLE;
4800 me= me->id.next;
4804 if(main->versionfile <= 200) {
4805 Object *ob= main->object.first;
4806 while(ob) {
4807 ob->scaflag = ob->gameflag & (64+128+256+512+1024+2048);
4808 /* 64 is do_fh */
4809 ob->gameflag &= ~(128+256+512+1024+2048);
4810 ob = ob->id.next;
4814 if(main->versionfile <= 201) {
4815 /* add-object + end-object are joined to edit-object actuator */
4816 Object *ob = main->object.first;
4817 bProperty *prop;
4818 bActuator *act;
4819 bIpoActuator *ia;
4820 bEditObjectActuator *eoa;
4821 bAddObjectActuator *aoa;
4822 while (ob) {
4823 act = ob->actuators.first;
4824 while (act) {
4825 if(act->type==ACT_IPO) {
4826 ia= act->data;
4827 prop= get_property(ob, ia->name);
4828 if(prop) {
4829 ia->type= ACT_IPO_FROM_PROP;
4832 else if(act->type==ACT_ADD_OBJECT) {
4833 aoa= act->data;
4834 eoa= MEM_callocN(sizeof(bEditObjectActuator), "edit ob act");
4835 eoa->type= ACT_EDOB_ADD_OBJECT;
4836 eoa->ob= aoa->ob;
4837 eoa->time= aoa->time;
4838 MEM_freeN(aoa);
4839 act->data= eoa;
4840 act->type= act->otype= ACT_EDIT_OBJECT;
4842 else if(act->type==ACT_END_OBJECT) {
4843 eoa= MEM_callocN(sizeof(bEditObjectActuator), "edit ob act");
4844 eoa->type= ACT_EDOB_END_OBJECT;
4845 act->data= eoa;
4846 act->type= act->otype= ACT_EDIT_OBJECT;
4848 act= act->next;
4850 ob = ob->id.next;
4854 if(main->versionfile <= 202) {
4855 /* add-object and end-object are joined to edit-object
4856 * actuator */
4857 Object *ob= main->object.first;
4858 bActuator *act;
4859 bObjectActuator *oa;
4860 while(ob) {
4861 act= ob->actuators.first;
4862 while(act) {
4863 if(act->type==ACT_OBJECT) {
4864 oa= act->data;
4865 oa->flag &= ~(ACT_TORQUE_LOCAL|ACT_DROT_LOCAL); /* this actuator didn't do local/glob rot before */
4867 act= act->next;
4869 ob= ob->id.next;
4873 if(main->versionfile <= 204) {
4874 /* patches for new physics */
4875 Object *ob= main->object.first;
4876 bActuator *act;
4877 bObjectActuator *oa;
4878 bSound *sound;
4879 while(ob) {
4881 /* please check this for demo20 files like
4882 * original Egypt levels etc. converted
4883 * rotation factor of 50 is not workable */
4884 act= ob->actuators.first;
4885 while(act) {
4886 if(act->type==ACT_OBJECT) {
4887 oa= act->data;
4889 oa->forceloc[0]*= 25.0;
4890 oa->forceloc[1]*= 25.0;
4891 oa->forceloc[2]*= 25.0;
4893 oa->forcerot[0]*= 10.0;
4894 oa->forcerot[1]*= 10.0;
4895 oa->forcerot[2]*= 10.0;
4897 act= act->next;
4899 ob= ob->id.next;
4902 sound = main->sound.first;
4903 while (sound) {
4904 if (sound->volume < 0.01) {
4905 sound->volume = 1.0;
4907 sound = sound->id.next;
4911 if(main->versionfile <= 205) {
4912 /* patches for new physics */
4913 Object *ob= main->object.first;
4914 bActuator *act;
4915 bSensor *sens;
4916 bEditObjectActuator *oa;
4917 bRaySensor *rs;
4918 bCollisionSensor *cs;
4919 while(ob) {
4920 /* Set anisotropic friction off for old objects,
4921 * values to 1.0. */
4922 ob->gameflag &= ~OB_ANISOTROPIC_FRICTION;
4923 ob->anisotropicFriction[0] = 1.0;
4924 ob->anisotropicFriction[1] = 1.0;
4925 ob->anisotropicFriction[2] = 1.0;
4927 act= ob->actuators.first;
4928 while(act) {
4929 if(act->type==ACT_EDIT_OBJECT) {
4930 /* Zero initial velocity for newly
4931 * added objects */
4932 oa= act->data;
4933 oa->linVelocity[0] = 0.0;
4934 oa->linVelocity[1] = 0.0;
4935 oa->linVelocity[2] = 0.0;
4936 oa->localflag = 0;
4938 act= act->next;
4941 sens= ob->sensors.first;
4942 while (sens) {
4943 /* Extra fields for radar sensors. */
4944 if(sens->type == SENS_RADAR) {
4945 bRadarSensor *s = sens->data;
4946 s->range = 10000.0;
4949 /* Pulsing: defaults for new sensors. */
4950 if(sens->type != SENS_ALWAYS) {
4951 sens->pulse = 0;
4952 sens->freq = 0;
4953 } else {
4954 sens->pulse = 1;
4957 /* Invert: off. */
4958 sens->invert = 0;
4960 /* Collision and ray: default = trigger
4961 * on property. The material field can
4962 * remain empty. */
4963 if(sens->type == SENS_COLLISION) {
4964 cs = (bCollisionSensor*) sens->data;
4965 cs->mode = 0;
4967 if(sens->type == SENS_RAY) {
4968 rs = (bRaySensor*) sens->data;
4969 rs->mode = 0;
4971 sens = sens->next;
4973 ob= ob->id.next;
4975 /* have to check the exact multiplier */
4978 if(main->versionfile <= 211) {
4979 /* Render setting: per scene, the applicable gamma value
4980 * can be set. Default is 1.0, which means no
4981 * correction. */
4982 bActuator *act;
4983 bObjectActuator *oa;
4984 Object *ob;
4986 /* added alpha in obcolor */
4987 ob= main->object.first;
4988 while(ob) {
4989 ob->col[3]= 1.0;
4990 ob= ob->id.next;
4993 /* added alpha in obcolor */
4994 ob= main->object.first;
4995 while(ob) {
4996 act= ob->actuators.first;
4997 while(act) {
4998 if (act->type==ACT_OBJECT) {
4999 /* multiply velocity with 50 in old files */
5000 oa= act->data;
5001 if (fabs(oa->linearvelocity[0]) >= 0.01f)
5002 oa->linearvelocity[0] *= 50.0;
5003 if (fabs(oa->linearvelocity[1]) >= 0.01f)
5004 oa->linearvelocity[1] *= 50.0;
5005 if (fabs(oa->linearvelocity[2]) >= 0.01f)
5006 oa->linearvelocity[2] *= 50.0;
5007 if (fabs(oa->angularvelocity[0])>=0.01f)
5008 oa->angularvelocity[0] *= 50.0;
5009 if (fabs(oa->angularvelocity[1])>=0.01f)
5010 oa->angularvelocity[1] *= 50.0;
5011 if (fabs(oa->angularvelocity[2])>=0.01f)
5012 oa->angularvelocity[2] *= 50.0;
5014 act= act->next;
5016 ob= ob->id.next;
5020 if(main->versionfile <= 212) {
5022 bSound* sound;
5023 bProperty *prop;
5024 Object *ob;
5025 Mesh *me;
5027 sound = main->sound.first;
5028 while (sound)
5030 sound->max_gain = 1.0;
5031 sound->min_gain = 0.0;
5032 sound->distance = 1.0;
5034 if (sound->attenuation > 0.0)
5035 sound->flags |= SOUND_FLAGS_3D;
5036 else
5037 sound->flags &= ~SOUND_FLAGS_3D;
5039 sound = sound->id.next;
5042 ob = main->object.first;
5044 while (ob) {
5045 prop= ob->prop.first;
5046 while(prop) {
5047 if (prop->type == PROP_TIME) {
5048 // convert old PROP_TIME values from int to float
5049 *((float *)&prop->data) = (float) prop->data;
5052 prop= prop->next;
5054 ob = ob->id.next;
5057 /* me->subdiv changed to reflect the actual reparametization
5058 * better, and smeshes were removed - if it was a smesh make
5059 * it a subsurf, and reset the subdiv level because subsurf
5060 * takes a lot more work to calculate.
5062 for (me= main->mesh.first; me; me= me->id.next) {
5063 if (me->flag&ME_SMESH) {
5064 me->flag&= ~ME_SMESH;
5065 me->flag|= ME_SUBSURF;
5067 me->subdiv= 1;
5068 } else {
5069 if (me->subdiv<2)
5070 me->subdiv= 1;
5071 else
5072 me->subdiv--;
5077 if(main->versionfile <= 220) {
5078 Object *ob;
5079 Mesh *me;
5081 ob = main->object.first;
5083 /* adapt form factor in order to get the 'old' physics
5084 * behaviour back...*/
5086 while (ob) {
5087 /* in future, distinguish between different
5088 * object bounding shapes */
5089 ob->formfactor = 0.4f;
5090 /* patch form factor , note that inertia equiv radius
5091 * of a rotation symmetrical obj */
5092 if (ob->inertia != 1.0) {
5093 ob->formfactor /= ob->inertia * ob->inertia;
5095 ob = ob->id.next;
5098 /* Began using alpha component of vertex colors, but
5099 * old file vertex colors are undefined, reset them
5100 * to be fully opaque. -zr
5102 for (me= main->mesh.first; me; me= me->id.next) {
5103 if (me->mcol) {
5104 int i;
5106 for (i=0; i<me->totface*4; i++) {
5107 MCol *mcol= &me->mcol[i];
5108 mcol->a= 255;
5111 if (me->tface) {
5112 int i, j;
5114 for (i=0; i<me->totface; i++) {
5115 TFace *tf= &((TFace*) me->tface)[i];
5117 for (j=0; j<4; j++) {
5118 char *col= (char*) &tf->col[j];
5120 col[0]= 255;
5126 if(main->versionfile <= 221) {
5127 Scene *sce= main->scene.first;
5129 // new variables for std-alone player and runtime
5130 while(sce) {
5132 sce->r.xplay= 640;
5133 sce->r.yplay= 480;
5134 sce->r.freqplay= 60;
5136 sce= sce->id.next;
5140 if(main->versionfile <= 222) {
5141 Scene *sce= main->scene.first;
5143 // new variables for std-alone player and runtime
5144 while(sce) {
5146 sce->r.depth= 32;
5148 sce= sce->id.next;
5153 if(main->versionfile <= 223) {
5154 VFont *vf;
5155 Image *ima;
5156 Object *ob;
5158 for (vf= main->vfont.first; vf; vf= vf->id.next) {
5159 if (BLI_streq(vf->name+strlen(vf->name)-6, ".Bfont")) {
5160 strcpy(vf->name, "<builtin>");
5164 /* Old textures animate at 25 FPS */
5165 for (ima = main->image.first; ima; ima=ima->id.next){
5166 ima->animspeed = 25;
5169 /* Zr remapped some keyboard codes to be linear (stupid zr) */
5170 for (ob= main->object.first; ob; ob= ob->id.next) {
5171 bSensor *sens;
5173 for (sens= ob->sensors.first; sens; sens= sens->next) {
5174 if (sens->type==SENS_KEYBOARD) {
5175 bKeyboardSensor *ks= sens->data;
5177 ks->key= map_223_keybd_code_to_224_keybd_code(ks->key);
5178 ks->qual= map_223_keybd_code_to_224_keybd_code(ks->qual);
5179 ks->qual2= map_223_keybd_code_to_224_keybd_code(ks->qual2);
5184 if(main->versionfile <= 224) {
5185 bSound* sound;
5186 Scene *sce;
5187 Mesh *me;
5188 bScreen *sc;
5190 for (sound=main->sound.first; sound; sound=sound->id.next) {
5191 if (sound->packedfile) {
5192 if (sound->newpackedfile == NULL) {
5193 sound->newpackedfile = sound->packedfile;
5195 sound->packedfile = NULL;
5198 /* Make sure that old subsurf meshes don't have zero subdivision level for rendering */
5199 for (me=main->mesh.first; me; me=me->id.next){
5200 if ((me->flag & ME_SUBSURF) && (me->subdivr==0))
5201 me->subdivr=me->subdiv;
5204 for (sce= main->scene.first; sce; sce= sce->id.next) {
5205 sce->r.stereomode = 1; // no stereo
5208 /* some oldfile patch, moved from set_func_space */
5209 for (sc= main->screen.first; sc; sc= sc->id.next) {
5210 ScrArea *sa;
5212 for (sa= sc->areabase.first; sa; sa= sa->next) {
5213 SpaceLink *sl;
5215 for (sl= sa->spacedata.first; sl; sl= sl->next) {
5216 if (sl->spacetype==SPACE_IPO) {
5217 SpaceSeq *sseq= (SpaceSeq*) sl;
5218 sseq->v2d.keeptot= 0;
5227 if(main->versionfile <= 225) {
5228 World *wo;
5229 /* Use Sumo for old games */
5230 for (wo = main->world.first; wo; wo= wo->id.next) {
5231 wo->physicsEngine = 2;
5235 if(main->versionfile <= 227) {
5236 Scene *sce;
5237 Material *ma;
5238 bScreen *sc;
5239 Object *ob;
5241 /* As of now, this insures that the transition from the old Track system
5242 to the new full constraint Track is painless for everyone. - theeth
5244 ob = main->object.first;
5246 while (ob) {
5247 ListBase *list;
5248 list = &ob->constraints;
5250 /* check for already existing TrackTo constraint
5251 set their track and up flag correctly */
5253 if (list){
5254 bConstraint *curcon;
5255 for (curcon = list->first; curcon; curcon=curcon->next){
5256 if (curcon->type == CONSTRAINT_TYPE_TRACKTO){
5257 bTrackToConstraint *data = curcon->data;
5258 data->reserved1 = ob->trackflag;
5259 data->reserved2 = ob->upflag;
5264 if (ob->type == OB_ARMATURE) {
5265 if (ob->pose){
5266 bConstraint *curcon;
5267 bPoseChannel *pchan;
5268 for (pchan = ob->pose->chanbase.first;
5269 pchan; pchan=pchan->next){
5270 for (curcon = pchan->constraints.first;
5271 curcon; curcon=curcon->next){
5272 if (curcon->type == CONSTRAINT_TYPE_TRACKTO){
5273 bTrackToConstraint *data = curcon->data;
5274 data->reserved1 = ob->trackflag;
5275 data->reserved2 = ob->upflag;
5282 /* Change Ob->Track in real TrackTo constraint */
5284 if (ob->track){
5285 bConstraint *con;
5286 bTrackToConstraint *data;
5288 list = &ob->constraints;
5289 if (list)
5291 con = MEM_callocN(sizeof(bConstraint), "constraint");
5292 strcpy (con->name, "AutoTrack");
5293 unique_constraint_name(con, list);
5294 con->flag |= CONSTRAINT_EXPAND;
5295 con->enforce=1.0F;
5296 con->type = CONSTRAINT_TYPE_TRACKTO;
5297 data = (bTrackToConstraint *)
5298 new_constraint_data(CONSTRAINT_TYPE_TRACKTO);
5300 data->tar = ob->track;
5301 data->reserved1 = ob->trackflag;
5302 data->reserved2 = ob->upflag;
5303 con->data= (void*) data;
5304 BLI_addtail(list, con);
5306 ob->track = 0;
5309 ob = ob->id.next;
5313 for (sce= main->scene.first; sce; sce= sce->id.next) {
5314 sce->audio.mixrate = 44100;
5315 sce->audio.flag |= AUDIO_SCRUB;
5316 sce->r.mode |= R_ENVMAP;
5318 // init new shader vars
5319 for (ma= main->mat.first; ma; ma= ma->id.next) {
5320 ma->refrac= 4.0f;
5321 ma->roughness= 0.5f;
5322 ma->param[0]= 0.5f;
5323 ma->param[1]= 0.1f;
5324 ma->param[2]= 0.1f;
5325 ma->param[3]= 0.05f;
5327 // patch for old wrong max view2d settings, allows zooming out more
5328 for (sc= main->screen.first; sc; sc= sc->id.next) {
5329 ScrArea *sa;
5331 for (sa= sc->areabase.first; sa; sa= sa->next) {
5332 SpaceLink *sl;
5334 for (sl= sa->spacedata.first; sl; sl= sl->next) {
5335 if (sl->spacetype==SPACE_ACTION) {
5336 SpaceAction *sac= (SpaceAction *) sl;
5337 sac->v2d.max[0]= 32000;
5339 else if (sl->spacetype==SPACE_NLA) {
5340 SpaceNla *sla= (SpaceNla *) sl;
5341 sla->v2d.max[0]= 32000;
5347 if(main->versionfile <= 228) {
5348 Scene *sce;
5349 bScreen *sc;
5350 Object *ob;
5353 /* As of now, this insures that the transition from the old Track system
5354 to the new full constraint Track is painless for everyone.*/
5355 ob = main->object.first;
5357 while (ob) {
5358 ListBase *list;
5359 list = &ob->constraints;
5361 /* check for already existing TrackTo constraint
5362 set their track and up flag correctly */
5364 if (list){
5365 bConstraint *curcon;
5366 for (curcon = list->first; curcon; curcon=curcon->next){
5367 if (curcon->type == CONSTRAINT_TYPE_TRACKTO){
5368 bTrackToConstraint *data = curcon->data;
5369 data->reserved1 = ob->trackflag;
5370 data->reserved2 = ob->upflag;
5375 if (ob->type == OB_ARMATURE) {
5376 if (ob->pose){
5377 bConstraint *curcon;
5378 bPoseChannel *pchan;
5379 for (pchan = ob->pose->chanbase.first;
5380 pchan; pchan=pchan->next){
5381 for (curcon = pchan->constraints.first;
5382 curcon; curcon=curcon->next){
5383 if (curcon->type == CONSTRAINT_TYPE_TRACKTO){
5384 bTrackToConstraint *data = curcon->data;
5385 data->reserved1 = ob->trackflag;
5386 data->reserved2 = ob->upflag;
5393 ob = ob->id.next;
5396 for (sce= main->scene.first; sce; sce= sce->id.next) {
5397 sce->r.mode |= R_ENVMAP;
5400 // convert old mainb values for new button panels
5401 for (sc= main->screen.first; sc; sc= sc->id.next) {
5402 ScrArea *sa;
5404 for (sa= sc->areabase.first; sa; sa= sa->next) {
5405 SpaceLink *sl;
5407 for (sl= sa->spacedata.first; sl; sl= sl->next) {
5408 if (sl->spacetype==SPACE_BUTS) {
5409 SpaceButs *sbuts= (SpaceButs *) sl;
5411 sbuts->v2d.maxzoom= 1.2f;
5412 sbuts->align= 1; /* horizontal default */
5414 if(sbuts->mainb==BUTS_LAMP) {
5415 sbuts->mainb= CONTEXT_SHADING;
5416 sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_LAMP;
5418 else if(sbuts->mainb==BUTS_MAT) {
5419 sbuts->mainb= CONTEXT_SHADING;
5420 sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
5422 else if(sbuts->mainb==BUTS_TEX) {
5423 sbuts->mainb= CONTEXT_SHADING;
5424 sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_TEX;
5426 else if(sbuts->mainb==BUTS_ANIM) {
5427 sbuts->mainb= CONTEXT_OBJECT;
5429 else if(sbuts->mainb==BUTS_WORLD) {
5430 sbuts->mainb= CONTEXT_SCENE;
5431 sbuts->tab[CONTEXT_SCENE]= TAB_SCENE_WORLD;
5433 else if(sbuts->mainb==BUTS_RENDER) {
5434 sbuts->mainb= CONTEXT_SCENE;
5435 sbuts->tab[CONTEXT_SCENE]= TAB_SCENE_RENDER;
5437 else if(sbuts->mainb==BUTS_GAME) {
5438 sbuts->mainb= CONTEXT_LOGIC;
5440 else if(sbuts->mainb==BUTS_FPAINT) {
5441 sbuts->mainb= CONTEXT_EDITING;
5443 else if(sbuts->mainb==BUTS_RADIO) {
5444 sbuts->mainb= CONTEXT_SHADING;
5445 sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_RAD;
5447 else if(sbuts->mainb==BUTS_CONSTRAINT) {
5448 sbuts->mainb= CONTEXT_OBJECT;
5450 else if(sbuts->mainb==BUTS_SCRIPT) {
5451 sbuts->mainb= CONTEXT_OBJECT;
5453 else if(sbuts->mainb==BUTS_EDIT) {
5454 sbuts->mainb= CONTEXT_EDITING;
5456 else sbuts->mainb= CONTEXT_SCENE;
5462 /* ton: made this 230 instead of 229,
5463 to be sure (tuho files) and this is a reliable check anyway
5464 nevertheless, we might need to think over a fitness (initialize)
5465 check apart from the do_versions() */
5467 if(main->versionfile <= 230) {
5468 bScreen *sc;
5470 // new variable blockscale, for panels in any area
5471 for (sc= main->screen.first; sc; sc= sc->id.next) {
5472 ScrArea *sa;
5474 for (sa= sc->areabase.first; sa; sa= sa->next) {
5475 SpaceLink *sl;
5477 for (sl= sa->spacedata.first; sl; sl= sl->next) {
5478 if(sl->blockscale==0.0) sl->blockscale= 0.7f;
5479 /* added: 5x better zoom in for action */
5480 if(sl->spacetype==SPACE_ACTION) {
5481 SpaceAction *sac= (SpaceAction *)sl;
5482 sac->v2d.maxzoom= 50;
5488 if(main->versionfile <= 231) {
5489 /* new bit flags for showing/hiding grid floor and axes */
5490 bScreen *sc = main->screen.first;
5491 while(sc) {
5492 ScrArea *sa= sc->areabase.first;
5493 while(sa) {
5494 SpaceLink *sl= sa->spacedata.first;
5495 while (sl) {
5496 if (sl->spacetype==SPACE_VIEW3D) {
5497 View3D *v3d= (View3D*) sl;
5499 if (v3d->gridflag==0) {
5500 v3d->gridflag |= V3D_SHOW_X;
5501 v3d->gridflag |= V3D_SHOW_Y;
5502 v3d->gridflag |= V3D_SHOW_FLOOR;
5503 v3d->gridflag &= ~V3D_SHOW_Z;
5506 sl= sl->next;
5508 sa= sa->next;
5510 sc= sc->id.next;
5513 if(main->versionfile <= 231) {
5514 Material *ma= main->mat.first;
5515 bScreen *sc = main->screen.first;
5516 Scene *sce;
5517 Lamp *la;
5518 World *wrld;
5520 /* introduction of raytrace */
5521 while(ma) {
5522 if(ma->fresnel_tra_i==0.0) ma->fresnel_tra_i= 1.25;
5523 if(ma->fresnel_mir_i==0.0) ma->fresnel_mir_i= 1.25;
5525 ma->ang= 1.0;
5526 ma->ray_depth= 2;
5527 ma->ray_depth_tra= 2;
5528 ma->fresnel_tra= 0.0;
5529 ma->fresnel_mir= 0.0;
5531 ma= ma->id.next;
5533 sce= main->scene.first;
5534 while(sce) {
5535 if(sce->r.gauss==0.0) sce->r.gauss= 1.0;
5536 sce= sce->id.next;
5538 la= main->lamp.first;
5539 while(la) {
5540 if(la->k==0.0) la->k= 1.0;
5541 if(la->ray_samp==0) la->ray_samp= 1;
5542 if(la->ray_sampy==0) la->ray_sampy= 1;
5543 if(la->ray_sampz==0) la->ray_sampz= 1;
5544 if(la->area_size==0.0) la->area_size= 1.0;
5545 if(la->area_sizey==0.0) la->area_sizey= 1.0;
5546 if(la->area_sizez==0.0) la->area_sizez= 1.0;
5547 la= la->id.next;
5549 wrld= main->world.first;
5550 while(wrld) {
5551 if(wrld->range==0.0) {
5552 wrld->range= 1.0f/wrld->exposure;
5554 wrld= wrld->id.next;
5557 /* new bit flags for showing/hiding grid floor and axes */
5559 while(sc) {
5560 ScrArea *sa= sc->areabase.first;
5561 while(sa) {
5562 SpaceLink *sl= sa->spacedata.first;
5563 while (sl) {
5564 if (sl->spacetype==SPACE_VIEW3D) {
5565 View3D *v3d= (View3D*) sl;
5567 if (v3d->gridflag==0) {
5568 v3d->gridflag |= V3D_SHOW_X;
5569 v3d->gridflag |= V3D_SHOW_Y;
5570 v3d->gridflag |= V3D_SHOW_FLOOR;
5571 v3d->gridflag &= ~V3D_SHOW_Z;
5574 sl= sl->next;
5576 sa= sa->next;
5578 sc= sc->id.next;
5581 if(main->versionfile <= 232) {
5582 Tex *tex= main->tex.first;
5583 World *wrld= main->world.first;
5584 bScreen *sc;
5585 Scene *sce;
5587 while(tex) {
5588 if((tex->flag & (TEX_CHECKER_ODD+TEX_CHECKER_EVEN))==0) {
5589 tex->flag |= TEX_CHECKER_ODD;
5591 /* copied from kernel texture.c */
5592 if(tex->ns_outscale==0.0) {
5593 /* musgrave */
5594 tex->mg_H = 1.0f;
5595 tex->mg_lacunarity = 2.0f;
5596 tex->mg_octaves = 2.0f;
5597 tex->mg_offset = 1.0f;
5598 tex->mg_gain = 1.0f;
5599 tex->ns_outscale = 1.0f;
5600 /* distnoise */
5601 tex->dist_amount = 1.0f;
5602 /* voronoi */
5603 tex->vn_w1 = 1.0f;
5604 tex->vn_mexp = 2.5f;
5606 tex= tex->id.next;
5609 while(wrld) {
5610 if(wrld->aodist==0.0) {
5611 wrld->aodist= 10.0f;
5612 wrld->aobias= 0.05f;
5614 if(wrld->aosamp==0.0) wrld->aosamp= 5;
5615 if(wrld->aoenergy==0.0) wrld->aoenergy= 1.0;
5616 wrld= wrld->id.next;
5620 // new variable blockscale, for panels in any area, do again because new
5621 // areas didnt initialize it to 0.7 yet
5622 for (sc= main->screen.first; sc; sc= sc->id.next) {
5623 ScrArea *sa;
5624 for (sa= sc->areabase.first; sa; sa= sa->next) {
5625 SpaceLink *sl;
5626 for (sl= sa->spacedata.first; sl; sl= sl->next) {
5627 if(sl->blockscale==0.0) sl->blockscale= 0.7f;
5629 /* added: 5x better zoom in for nla */
5630 if(sl->spacetype==SPACE_NLA) {
5631 SpaceNla *snla= (SpaceNla *)sl;
5632 snla->v2d.maxzoom= 50;
5637 sce= main->scene.first;
5638 while(sce) {
5639 if(sce->r.ocres==0) sce->r.ocres= 64;
5640 sce= sce->id.next;
5644 if(main->versionfile <= 233) {
5645 bScreen *sc;
5646 Material *ma= main->mat.first;
5647 Object *ob= main->object.first;
5649 while(ma) {
5650 if(ma->rampfac_col==0.0) ma->rampfac_col= 1.0;
5651 if(ma->rampfac_spec==0.0) ma->rampfac_spec= 1.0;
5652 if(ma->pr_lamp==0) ma->pr_lamp= 3;
5653 ma= ma->id.next;
5656 /* this should have been done loooong before! */
5657 while(ob) {
5658 if(ob->ipowin==0) ob->ipowin= ID_OB;
5659 ob= ob->id.next;
5662 for (sc= main->screen.first; sc; sc= sc->id.next) {
5663 ScrArea *sa;
5664 for (sa= sc->areabase.first; sa; sa= sa->next) {
5665 SpaceLink *sl;
5666 for (sl= sa->spacedata.first; sl; sl= sl->next) {
5667 if(sl->spacetype==SPACE_VIEW3D) {
5668 View3D *v3d= (View3D *)sl;
5669 v3d->flag |= V3D_SELECT_OUTLINE;
5679 if(main->versionfile <= 234) {
5680 Scene *sce;
5681 World *wo;
5682 bScreen *sc;
5683 int set_zbuf_sel=0;
5685 // force sumo engine to be active
5686 for (wo = main->world.first; wo; wo= wo->id.next) {
5687 if(wo->physicsEngine==0) wo->physicsEngine = 2;
5690 for (sce= main->scene.first; sce; sce= sce->id.next) {
5691 if(sce->selectmode==0) {
5692 sce->selectmode= SCE_SELECT_VERTEX;
5693 set_zbuf_sel= 1;
5696 for (sc= main->screen.first; sc; sc= sc->id.next) {
5697 ScrArea *sa;
5698 for (sa= sc->areabase.first; sa; sa= sa->next) {
5699 SpaceLink *sl;
5700 for (sl= sa->spacedata.first; sl; sl= sl->next) {
5701 if(sl->spacetype==SPACE_VIEW3D) {
5702 View3D *v3d= (View3D *)sl;
5703 if(set_zbuf_sel) v3d->flag |= V3D_ZBUF_SELECT;
5705 else if(sl->spacetype==SPACE_TEXT) {
5706 SpaceText *st= (SpaceText *)sl;
5707 if(st->tabnumber==0) st->tabnumber= 2;
5713 if(main->versionfile <= 235) {
5714 Tex *tex= main->tex.first;
5715 Scene *sce= main->scene.first;
5716 Sequence *seq;
5717 Editing *ed;
5719 while(tex) {
5720 if(tex->nabla==0.0) tex->nabla= 0.025f;
5721 tex= tex->id.next;
5723 while(sce) {
5724 ed= sce->ed;
5725 if(ed) {
5726 WHILE_SEQ(&ed->seqbase) {
5727 if(seq->type==SEQ_IMAGE || seq->type==SEQ_MOVIE) seq->flag |= SEQ_MAKE_PREMUL;
5729 END_SEQ
5732 sce= sce->id.next;
5735 if(main->versionfile <= 236) {
5736 Object *ob;
5737 Scene *sce= main->scene.first;
5738 Camera *cam= main->camera.first;
5739 Material *ma;
5740 bScreen *sc;
5742 while(sce) {
5743 if(sce->editbutsize==0.0) sce->editbutsize= 0.1f;
5745 sce= sce->id.next;
5747 while(cam) {
5748 if(cam->ortho_scale==0.0) {
5749 cam->ortho_scale= 256.0f/cam->lens;
5750 if(cam->type==CAM_ORTHO) printf("NOTE: ortho render has changed, tweak new Camera 'scale' value.\n");
5752 cam= cam->id.next;
5754 /* set manipulator type */
5755 /* force oops draw if depgraph was set*/
5756 /* set time line var */
5757 for (sc= main->screen.first; sc; sc= sc->id.next) {
5758 ScrArea *sa;
5759 for (sa= sc->areabase.first; sa; sa= sa->next) {
5760 SpaceLink *sl;
5761 for (sl= sa->spacedata.first; sl; sl= sl->next) {
5762 if(sl->spacetype==SPACE_VIEW3D) {
5763 View3D *v3d= (View3D *)sl;
5764 if(v3d->twtype==0) v3d->twtype= V3D_MANIP_TRANSLATE;
5766 #ifndef SHOWDEPGRAPH
5767 else if(sl->spacetype==SPACE_OOPS) {
5768 if ( ((SpaceOops *)sl)->type==SO_DEPSGRAPH)
5769 ((SpaceOops *)sl)->type=SO_OOPS;
5771 #endif
5772 else if(sl->spacetype==SPACE_TIME) {
5773 SpaceTime *stime= (SpaceTime *)sl;
5774 if(stime->redraws==0)
5775 stime->redraws= TIME_ALL_3D_WIN|TIME_ALL_ANIM_WIN;
5780 // init new shader vars
5781 for (ma= main->mat.first; ma; ma= ma->id.next) {
5782 if(ma->darkness==0.0) {
5783 ma->rms=0.1f;
5784 ma->darkness=1.0f;
5788 /* softbody init new vars */
5789 for(ob= main->object.first; ob; ob= ob->id.next) {
5790 if(ob->soft) {
5791 if(ob->soft->defgoal==0.0) ob->soft->defgoal= 0.7f;
5792 if(ob->soft->physics_speed==0.0) ob->soft->physics_speed= 1.0f;
5794 if(ob->soft->interval==0) {
5795 ob->soft->interval= 2;
5796 ob->soft->sfra= 1;
5797 ob->soft->efra= 100;
5800 if(ob->soft && ob->soft->vertgroup==0) {
5801 bDeformGroup *locGroup = get_named_vertexgroup(ob, "SOFTGOAL");
5802 if(locGroup){
5803 /* retrieve index for that group */
5804 ob->soft->vertgroup = 1 + get_defgroup_num(ob, locGroup);
5809 if(main->versionfile <= 237) {
5810 bArmature *arm;
5811 bConstraint *con;
5812 Object *ob;
5814 // armature recode checks
5815 for(arm= main->armature.first; arm; arm= arm->id.next) {
5816 where_is_armature(arm);
5818 for(ob= main->object.first; ob; ob= ob->id.next) {
5819 if(ob->parent) {
5820 Object *parent= newlibadr(fd, lib, ob->parent);
5821 if (parent && parent->type==OB_LATTICE)
5822 ob->partype = PARSKEL;
5825 // btw. armature_rebuild_pose is further only called on leave editmode
5826 if(ob->type==OB_ARMATURE) {
5827 if(ob->pose)
5828 ob->pose->flag |= POSE_RECALC;
5829 ob->recalc |= OB_RECALC; // cannot call stuff now (pointers!), done in setup_app_data
5831 /* new generic xray option */
5832 arm= newlibadr(fd, lib, ob->data);
5833 if(arm->flag & ARM_DRAWXRAY) {
5834 ob->dtx |= OB_DRAWXRAY;
5836 } else if (ob->type==OB_MESH) {
5837 Mesh *me = newlibadr(fd, lib, ob->data);
5839 if ((me->flag&ME_SUBSURF)) {
5840 SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf);
5842 smd->levels = MAX2(1, me->subdiv);
5843 smd->renderLevels = MAX2(1, me->subdivr);
5844 smd->subdivType = me->subsurftype;
5846 smd->modifier.mode = 0;
5847 if (me->subdiv!=0)
5848 smd->modifier.mode |= 1;
5849 if (me->subdivr!=0)
5850 smd->modifier.mode |= 2;
5851 if (me->flag&ME_OPT_EDGES)
5852 smd->flags |= eSubsurfModifierFlag_ControlEdges;
5854 BLI_addtail(&ob->modifiers, smd);
5858 // follow path constraint needs to set the 'path' option in curves...
5859 for(con=ob->constraints.first; con; con= con->next) {
5860 if(con->type==CONSTRAINT_TYPE_FOLLOWPATH) {
5861 bFollowPathConstraint *data = con->data;
5862 Object *obc= newlibadr(fd, lib, data->tar);
5864 if(obc && obc->type==OB_CURVE) {
5865 Curve *cu= newlibadr(fd, lib, obc->data);
5866 if(cu) cu->flag |= CU_PATH;
5872 if(main->versionfile <= 238) {
5873 Lattice *lt;
5874 Object *ob;
5875 bArmature *arm;
5876 Mesh *me;
5877 Key *key;
5878 Scene *sce= main->scene.first;
5880 while(sce){
5881 if(sce->toolsettings == NULL){
5882 sce->toolsettings = MEM_callocN(sizeof(struct ToolSettings),"Tool Settings Struct");
5883 sce->toolsettings->cornertype=0;
5884 sce->toolsettings->degr = 90;
5885 sce->toolsettings->step = 9;
5886 sce->toolsettings->turn = 1;
5887 sce->toolsettings->extr_offs = 1;
5888 sce->toolsettings->doublimit = 0.001f;
5889 sce->toolsettings->segments = 32;
5890 sce->toolsettings->rings = 32;
5891 sce->toolsettings->vertices = 32;
5892 sce->toolsettings->editbutflag =1;
5894 sce= sce->id.next;
5897 for (lt=main->latt.first; lt; lt=lt->id.next) {
5898 if (lt->fu==0.0 && lt->fv==0.0 && lt->fw==0.0) {
5899 calc_lat_fudu(lt->flag, lt->pntsu, &lt->fu, &lt->du);
5900 calc_lat_fudu(lt->flag, lt->pntsv, &lt->fv, &lt->dv);
5901 calc_lat_fudu(lt->flag, lt->pntsw, &lt->fw, &lt->dw);
5905 for(ob=main->object.first; ob; ob= ob->id.next) {
5906 ModifierData *md;
5907 PartEff *paf;
5909 for (md=ob->modifiers.first; md; md=md->next) {
5910 if (md->type==eModifierType_Subsurf) {
5911 SubsurfModifierData *smd = (SubsurfModifierData*) md;
5913 smd->flags &= ~(eSubsurfModifierFlag_Incremental|eSubsurfModifierFlag_DebugIncr);
5917 if ((ob->softflag&OB_SB_ENABLE) && !modifiers_findByType(ob, eModifierType_Softbody)) {
5918 if (ob->softflag&OB_SB_POSTDEF) {
5919 md = ob->modifiers.first;
5921 while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
5922 md = md->next;
5925 BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(eModifierType_Softbody));
5926 } else {
5927 BLI_addhead(&ob->modifiers, modifier_new(eModifierType_Softbody));
5930 ob->softflag &= ~OB_SB_ENABLE;
5932 if(ob->pose) {
5933 bPoseChannel *pchan;
5934 bConstraint *con;
5935 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
5936 // note, pchan->bone is also lib-link stuff
5937 if (pchan->limitmin[0] == 0.0f && pchan->limitmax[0] == 0.0f) {
5938 pchan->limitmin[0]= pchan->limitmin[1]= pchan->limitmin[2]= -180.0f;
5939 pchan->limitmax[0]= pchan->limitmax[1]= pchan->limitmax[2]= 180.0f;
5941 for(con= pchan->constraints.first; con; con= con->next) {
5942 if(con->type == CONSTRAINT_TYPE_KINEMATIC) {
5943 bKinematicConstraint *data = (bKinematicConstraint*)con->data;
5944 data->weight = 1.0f;
5945 data->orientweight = 1.0f;
5946 data->flag &= ~CONSTRAINT_IK_ROT;
5948 /* enforce conversion from old IK_TOPARENT to rootbone index */
5949 data->rootbone= -1;
5951 /* update_pose_etc handles rootbone==-1 */
5952 ob->pose->flag |= POSE_RECALC;
5959 paf = give_parteff(ob);
5960 if (paf) {
5961 if(paf->disp == 0)
5962 paf->disp = 100;
5963 if(paf->speedtex == 0)
5964 paf->speedtex = 8;
5965 if(paf->omat == 0)
5966 paf->omat = 1;
5970 for(arm=main->armature.first; arm; arm= arm->id.next) {
5971 bone_version_238(&arm->bonebase);
5972 arm->deformflag |= ARM_DEF_VGROUP;
5975 for(me=main->mesh.first; me; me= me->id.next) {
5976 if (!me->medge) {
5977 make_edges(me, 1); /* 1 = use mface->edcode */
5978 } else {
5979 mesh_strip_loose_faces(me);
5983 for(key= main->key.first; key; key= key->id.next) {
5984 KeyBlock *kb;
5985 int index= 1;
5987 /* trick to find out if we already introduced adrcode */
5988 for(kb= key->block.first; kb; kb= kb->next)
5989 if(kb->adrcode) break;
5991 if(kb==NULL) {
5992 for(kb= key->block.first; kb; kb= kb->next) {
5993 if(kb==key->refkey) {
5994 if(kb->name[0]==0)
5995 strcpy(kb->name, "Basis");
5997 else {
5998 if(kb->name[0]==0)
5999 sprintf(kb->name, "Key %d", index);
6000 kb->adrcode= index++;
6006 if(main->versionfile <= 239) {
6007 bArmature *arm;
6008 Object *ob;
6009 Scene *sce= main->scene.first;
6010 Camera *cam= main->camera.first;
6011 Material *ma= main->mat.first;
6012 int set_passepartout= 0;
6014 /* deformflag is local in modifier now */
6015 for(ob=main->object.first; ob; ob= ob->id.next) {
6016 ModifierData *md;
6018 for (md=ob->modifiers.first; md; md=md->next) {
6019 if (md->type==eModifierType_Armature) {
6020 ArmatureModifierData *amd = (ArmatureModifierData*) md;
6021 if(amd->object && amd->deformflag==0) {
6022 Object *oba= newlibadr(fd, lib, amd->object);
6023 bArmature *arm= newlibadr(fd, lib, oba->data);
6024 amd->deformflag= arm->deformflag;
6030 /* updating stepsize for ghost drawing */
6031 for(arm= main->armature.first; arm; arm= arm->id.next) {
6032 if (arm->ghostsize==0) arm->ghostsize=1;
6033 bone_version_239(&arm->bonebase);
6034 if(arm->layer==0) arm->layer= 1;
6037 for(;sce;sce= sce->id.next) {
6038 /* make 'innervert' the default subdivide type, for backwards compat */
6039 sce->toolsettings->cornertype=1;
6041 if(sce->r.scemode & R_PASSEPARTOUT) {
6042 set_passepartout= 1;
6043 sce->r.scemode &= ~R_PASSEPARTOUT;
6045 /* gauss is filter variable now */
6046 if(sce->r.mode & R_GAUSS) {
6047 sce->r.filtertype= R_FILTER_GAUSS;
6048 sce->r.mode &= ~R_GAUSS;
6052 for(;cam; cam= cam->id.next) {
6053 if(set_passepartout)
6054 cam->flag |= CAM_SHOWPASSEPARTOUT;
6056 /* make sure old cameras have title safe on */
6057 if (!(cam->flag & CAM_SHOWTITLESAFE))
6058 cam->flag |= CAM_SHOWTITLESAFE;
6060 /* set an appropriate camera passepartout alpha */
6061 if (!(cam->passepartalpha)) cam->passepartalpha = 0.2f;
6064 for(; ma; ma= ma->id.next) {
6065 if(ma->strand_sta==0.0f) {
6066 ma->strand_sta= ma->strand_end= 1.0f;
6067 ma->mode |= MA_TANGENT_STR;
6069 if(ma->mode & MA_TRACEBLE) ma->mode |= MA_SHADBUF;
6073 if(main->versionfile <= 241) {
6074 Object *ob;
6075 Tex *tex;
6076 Scene *sce;
6077 World *wo;
6078 Lamp *la;
6079 Material *ma;
6080 bArmature *arm;
6081 bNodeTree *ntree;
6083 for (wo = main->world.first; wo; wo= wo->id.next) {
6084 /* Migrate to Bullet for games, except for the NaN versions */
6085 /* People can still explicitely choose for Sumo (after 2.42 is out) */
6086 if(main->versionfile > 225)
6087 wo->physicsEngine = WOPHY_BULLET;
6088 if(WO_AODIST == wo->aomode)
6089 wo->aocolor= WO_AOPLAIN;
6092 /* updating layers still */
6093 for(arm= main->armature.first; arm; arm= arm->id.next) {
6094 bone_version_239(&arm->bonebase);
6095 if(arm->layer==0) arm->layer= 1;
6097 for(sce= main->scene.first; sce; sce= sce->id.next) {
6098 bScreen *sc;
6100 if(sce->jumpframe==0) sce->jumpframe= 10;
6101 if(sce->audio.mixrate==0) sce->audio.mixrate= 44100;
6103 if(sce->r.xparts<2) sce->r.xparts= 4;
6104 if(sce->r.yparts<2) sce->r.yparts= 4;
6105 /* adds default layer */
6106 if(sce->r.layers.first==NULL)
6107 scene_add_render_layer(sce);
6108 else {
6109 SceneRenderLayer *srl;
6110 /* new layer flag for sky, was default for solid */
6111 for(srl= sce->r.layers.first; srl; srl= srl->next) {
6112 if(srl->layflag & SCE_LAY_SOLID)
6113 srl->layflag |= SCE_LAY_SKY;
6114 srl->passflag &= (SCE_PASS_COMBINED|SCE_PASS_Z|SCE_PASS_NORMAL|SCE_PASS_VECTOR);
6118 /* node version changes */
6119 if(sce->nodetree)
6120 ntree_version_241(sce->nodetree);
6122 /* uv calculation options moved to toolsettings */
6123 if (sce->toolsettings->uvcalc_radius == 0.0) {
6124 sce->toolsettings->uvcalc_radius = 1.0f;
6125 sce->toolsettings->uvcalc_cubesize = 1.0f;
6126 sce->toolsettings->uvcalc_mapdir = 1;
6127 sce->toolsettings->uvcalc_mapalign = 1;
6128 sce->toolsettings->uvcalc_flag = 1;
6129 sce->toolsettings->unwrapper = 1;
6132 /* enable uv editor local sticky by default */
6133 for (sc= main->screen.first; sc; sc= sc->id.next) {
6134 ScrArea *sa;
6135 for (sa= sc->areabase.first; sa; sa= sa->next) {
6136 SpaceLink *sl;
6137 for (sl= sa->spacedata.first; sl; sl= sl->next) {
6138 if(sl->spacetype==SPACE_IMAGE) {
6139 SpaceImage *sima= (SpaceImage*)sl;
6140 if(!(sima->flag & SI_STICKYUVS))
6141 sima->flag |= SI_LOCALSTICKY;
6146 if(sce->r.mode & R_PANORAMA) {
6147 /* all these checks to ensure saved files with cvs version keep working... */
6148 if(sce->r.xsch < sce->r.ysch) {
6149 Object *obc= newlibadr(fd, lib, sce->camera);
6150 if(obc && obc->type==OB_CAMERA) {
6151 Camera *cam= newlibadr(fd, lib, obc->data);
6152 if(cam->lens>=10.0f) {
6153 sce->r.xsch*= sce->r.xparts;
6154 cam->lens*= (float)sce->r.ysch/(float)sce->r.xsch;
6161 for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
6162 ntree_version_241(ntree);
6164 for(la= main->lamp.first; la; la= la->id.next)
6165 if(la->buffers==0)
6166 la->buffers= 1;
6168 for(tex= main->tex.first; tex; tex= tex->id.next) {
6169 if(tex->env && tex->env->viewscale==0.0f)
6170 tex->env->viewscale= 1.0f;
6171 // tex->imaflag |= TEX_GAUSS_MIP;
6174 /* for empty drawsize and drawtype */
6175 for(ob=main->object.first; ob; ob= ob->id.next) {
6176 if(ob->empty_drawsize==0.0f) {
6177 ob->empty_drawtype = OB_ARROWS;
6178 ob->empty_drawsize = 1.0;
6182 for(ma= main->mat.first; ma; ma= ma->id.next) {
6183 /* stucci returns intensity from now on */
6184 int a;
6185 for(a=0; a<MAX_MTEX; a++) {
6186 if(ma->mtex[a] && ma->mtex[a]->tex) {
6187 Tex *tex= newlibadr(fd, lib, ma->mtex[a]->tex);
6188 if(tex && tex->type==TEX_STUCCI)
6189 ma->mtex[a]->mapto &= ~(MAP_COL|MAP_SPEC|MAP_REF);
6192 /* transmissivity defaults */
6193 if(ma->tx_falloff==0.0) ma->tx_falloff= 1.0;
6196 /* during 2.41 images with this name were used for viewer node output, lets fix that */
6197 if(main->versionfile == 241) {
6198 Image *ima;
6199 for(ima= main->image.first; ima; ima= ima->id.next)
6200 if(strcmp(ima->name, "Compositor")==0) {
6201 strcpy(ima->id.name+2, "Viewer Node");
6202 strcpy(ima->name, "Viewer Node");
6207 if(main->versionfile <= 242) {
6208 Scene *sce;
6209 bScreen *sc;
6210 Object *ob;
6211 Curve *cu;
6212 Material *ma;
6213 Mesh *me;
6214 Group *group;
6215 Nurb *nu;
6216 BezTriple *bezt;
6217 BPoint *bp;
6218 bNodeTree *ntree;
6219 int a;
6221 for(sc= main->screen.first; sc; sc= sc->id.next) {
6222 ScrArea *sa;
6223 sa= sc->areabase.first;
6224 while(sa) {
6225 SpaceLink *sl;
6227 for (sl= sa->spacedata.first; sl; sl= sl->next) {
6228 if(sl->spacetype==SPACE_VIEW3D) {
6229 View3D *v3d= (View3D*) sl;
6230 if (v3d->gridsubdiv == 0)
6231 v3d->gridsubdiv = 10;
6234 sa = sa->next;
6238 for(sce= main->scene.first; sce; sce= sce->id.next) {
6239 if (sce->toolsettings->select_thresh == 0.0f)
6240 sce->toolsettings->select_thresh= 0.01f;
6241 if (sce->toolsettings->clean_thresh == 0.0f)
6242 sce->toolsettings->clean_thresh = 0.1f;
6244 if (sce->r.threads==0) {
6245 if (sce->r.mode & R_THREADS)
6246 sce->r.threads= 2;
6247 else
6248 sce->r.threads= 1;
6250 if(sce->nodetree)
6251 ntree_version_242(sce->nodetree);
6254 for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
6255 ntree_version_242(ntree);
6257 /* add default radius values to old curve points */
6258 for(cu= main->curve.first; cu; cu= cu->id.next) {
6259 for(nu= cu->nurb.first; nu; nu= nu->next) {
6260 if (nu) {
6261 if(nu->bezt) {
6262 for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
6263 if (!bezt->radius) bezt->radius= 1.0;
6266 else if(nu->bp) {
6267 for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
6268 if(!bp->radius) bp->radius= 1.0;
6275 for(ob = main->object.first; ob; ob= ob->id.next) {
6276 ModifierData *md;
6277 ListBase *list;
6278 list = &ob->constraints;
6280 /* check for already existing MinMax (floor) constraint
6281 and update the sticky flagging */
6283 if (list){
6284 bConstraint *curcon;
6285 for (curcon = list->first; curcon; curcon=curcon->next){
6286 switch (curcon->type) {
6287 case CONSTRAINT_TYPE_MINMAX:
6289 bMinMaxConstraint *data = curcon->data;
6290 if (data->sticky==1)
6291 data->flag |= MINMAX_STICKY;
6292 else
6293 data->flag &= ~MINMAX_STICKY;
6295 break;
6296 case CONSTRAINT_TYPE_ROTLIKE:
6298 bRotateLikeConstraint *data = curcon->data;
6300 /* version patch from buttons_object.c */
6301 if(data->flag==0)
6302 data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
6304 break;
6309 if (ob->type == OB_ARMATURE) {
6310 if (ob->pose){
6311 bConstraint *curcon;
6312 bPoseChannel *pchan;
6313 for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
6314 for (curcon = pchan->constraints.first; curcon; curcon=curcon->next){
6315 switch (curcon->type) {
6316 case CONSTRAINT_TYPE_MINMAX:
6318 bMinMaxConstraint *data = curcon->data;
6319 if (data->sticky==1)
6320 data->flag |= MINMAX_STICKY;
6321 else
6322 data->flag &= ~MINMAX_STICKY;
6324 break;
6325 case CONSTRAINT_TYPE_KINEMATIC:
6327 bKinematicConstraint *data = curcon->data;
6328 if (!(data->flag & CONSTRAINT_IK_POS)) {
6329 data->flag |= CONSTRAINT_IK_POS;
6330 data->flag |= CONSTRAINT_IK_STRETCH;
6333 break;
6334 case CONSTRAINT_TYPE_ROTLIKE:
6336 bRotateLikeConstraint *data = curcon->data;
6338 /* version patch from buttons_object.c */
6339 if(data->flag==0)
6340 data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
6342 break;
6349 /* copy old object level track settings to curve modifers */
6350 for (md=ob->modifiers.first; md; md=md->next) {
6351 if (md->type==eModifierType_Curve) {
6352 CurveModifierData *cmd = (CurveModifierData*) md;
6354 if (cmd->defaxis == 0) cmd->defaxis = ob->trackflag+1;
6360 for(ma = main->mat.first; ma; ma= ma->id.next) {
6361 if(ma->shad_alpha==0.0f)
6362 ma->shad_alpha= 1.0f;
6363 if(ma->nodetree)
6364 ntree_version_242(ma->nodetree);
6367 for(me=main->mesh.first; me; me=me->id.next)
6368 customdata_version_242(me);
6370 for(group= main->group.first; group; group= group->id.next)
6371 if(group->layer==0)
6372 group->layer= (1<<20)-1;
6374 /* History fix (python?), shape key adrcode numbers have to be sorted */
6375 sort_shape_fix(main);
6377 /* now, subversion control! */
6378 if(main->subversionfile < 3) {
6379 bScreen *sc;
6380 Image *ima;
6381 Tex *tex;
6383 /* Image refactor initialize */
6384 for(ima= main->image.first; ima; ima= ima->id.next) {
6385 ima->source= IMA_SRC_FILE;
6386 ima->type= IMA_TYPE_IMAGE;
6388 ima->gen_x= 256; ima->gen_y= 256;
6389 ima->gen_type= 1;
6391 if(0==strncmp(ima->id.name+2, "Viewer Node", sizeof(ima->id.name+2))) {
6392 ima->source= IMA_SRC_VIEWER;
6393 ima->type= IMA_TYPE_COMPOSITE;
6395 if(0==strncmp(ima->id.name+2, "Render Result", sizeof(ima->id.name+2))) {
6396 ima->source= IMA_SRC_VIEWER;
6397 ima->type= IMA_TYPE_R_RESULT;
6401 for(tex= main->tex.first; tex; tex= tex->id.next) {
6402 if(tex->type==TEX_IMAGE && tex->ima) {
6403 ima= newlibadr(fd, lib, tex->ima);
6404 if(ima) {
6405 if(tex->imaflag & TEX_ANIM5_)
6406 ima->source= IMA_SRC_MOVIE;
6407 if(tex->imaflag & TEX_FIELDS_)
6408 ima->flag |= IMA_FIELDS;
6409 if(tex->imaflag & TEX_STD_FIELD_)
6410 ima->flag |= IMA_STD_FIELD;
6411 if(tex->imaflag & TEX_ANTIALI_)
6412 ima->flag |= IMA_ANTIALI;
6414 else
6415 printf("This is a broken .blend file!!!\n");
6417 tex->iuser.frames= tex->frames;
6418 tex->iuser.fie_ima= tex->fie_ima;
6419 tex->iuser.offset= tex->offset;
6420 tex->iuser.sfra= tex->sfra;
6421 tex->iuser.cycl= (tex->imaflag & TEX_ANIMCYCLIC_)!=0;
6423 for(sce= main->scene.first; sce; sce= sce->id.next) {
6424 if(sce->nodetree)
6425 do_version_ntree_242_2(sce->nodetree);
6427 if(main->nodetree.first) {
6428 for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
6429 do_version_ntree_242_2(ntree);
6431 for(ma = main->mat.first; ma; ma= ma->id.next)
6432 if(ma->nodetree)
6433 do_version_ntree_242_2(ma->nodetree);
6435 for(sc= main->screen.first; sc; sc= sc->id.next) {
6436 ScrArea *sa;
6437 for(sa= sc->areabase.first; sa; sa= sa->next) {
6438 SpaceLink *sl;
6439 for (sl= sa->spacedata.first; sl; sl= sl->next) {
6440 if(sl->spacetype==SPACE_IMAGE)
6441 ((SpaceImage *)sl)->iuser.fie_ima= 2;
6442 else if(sl->spacetype==SPACE_VIEW3D) {
6443 View3D *v3d= (View3D *)sl;
6444 if(v3d->bgpic)
6445 v3d->bgpic->iuser.fie_ima= 2;
6452 if(main->subversionfile < 4) {
6453 for(sce= main->scene.first; sce; sce= sce->id.next) {
6454 sce->r.bake_mode= 1; /* prevent to include render stuff here */
6455 sce->r.bake_filter= 2;
6456 sce->r.bake_osa= 5;
6457 sce->r.bake_flag= R_BAKE_CLEAR;
6461 if(main->subversionfile < 5) {
6462 for(sce= main->scene.first; sce; sce= sce->id.next) {
6463 /* improved triangle to quad conversion settings */
6464 if(sce->toolsettings->jointrilimit==0.0f)
6465 sce->toolsettings->jointrilimit= 0.8f;
6469 if(main->versionfile <= 243) {
6470 Object *ob= main->object.first;
6471 Camera *cam = main->camera.first;
6472 Scene *scn;
6473 Material *ma;
6475 for(; cam; cam= cam->id.next) {
6476 cam->angle= 360.0f * atan(16.0f/cam->lens) / M_PI;
6479 for(ma=main->mat.first; ma; ma= ma->id.next) {
6480 if(ma->sss_scale==0.0f) {
6481 ma->sss_radius[0]= 1.0f;
6482 ma->sss_radius[1]= 1.0f;
6483 ma->sss_radius[2]= 1.0f;
6484 ma->sss_col[0]= 0.8f;
6485 ma->sss_col[1]= 0.8f;
6486 ma->sss_col[2]= 0.8f;
6487 ma->sss_error= 0.05f;
6488 ma->sss_scale= 0.1f;
6489 ma->sss_ior= 1.3f;
6490 ma->sss_colfac= 1.0f;
6491 ma->sss_texfac= 0.0f;
6493 if(ma->sss_front==0 && ma->sss_back==0) {
6494 ma->sss_front= 1.0f;
6495 ma->sss_back= 1.0f;
6497 if(ma->sss_col[0]==0 && ma->sss_col[1]==0 && ma->sss_col[2]==0) {
6498 ma->sss_col[0]= ma->r;
6499 ma->sss_col[1]= ma->g;
6500 ma->sss_col[2]= ma->b;
6504 for(; ob; ob= ob->id.next) {
6505 bDeformGroup *curdef;
6507 for(curdef= ob->defbase.first; curdef; curdef=curdef->next) {
6508 /* replace an empty-string name with unique name */
6509 if (curdef->name[0] == '\0') {
6510 unique_vertexgroup_name(curdef, ob);
6514 if(main->versionfile < 243 || main->subversionfile < 1) {
6515 ModifierData *md;
6517 /* translate old mirror modifier axis values to new flags */
6518 for (md=ob->modifiers.first; md; md=md->next) {
6519 if (md->type==eModifierType_Mirror) {
6520 MirrorModifierData *mmd = (MirrorModifierData*) md;
6522 switch(mmd->axis)
6524 case 0:
6525 mmd->flag |= MOD_MIR_AXIS_X;
6526 break;
6527 case 1:
6528 mmd->flag |= MOD_MIR_AXIS_Y;
6529 break;
6530 case 2:
6531 mmd->flag |= MOD_MIR_AXIS_Z;
6532 break;
6535 mmd->axis = 0;
6542 * Bad hack!!!, need this to cleanup old
6543 * files in plumiferos.
6545 for(scn= main->scene.first; scn; scn= scn->id.next) {
6546 if(scn->r.mode & 0x20000) {
6547 scn->r.mode &= ~0x20000;
6548 scn->r.scemode |= R_STAMP_INFO;
6549 scn->r.stamp |= (R_STAMP_TIME|R_STAMP_FRAME|R_STAMP_DATE|R_STAMP_CAMERA|R_STAMP_SCENE);
6552 if(scn->r.mode & 0x40000)
6553 scn->r.mode &= ~0x40000;
6556 /* render layer added, this is not the active layer */
6557 if(main->versionfile <= 243 || main->subversionfile < 2) {
6558 Mesh *me;
6559 for(me=main->mesh.first; me; me=me->id.next)
6560 customdata_version_243(me);
6563 if(main->versionfile <= 244) {
6564 bScreen *sc;
6565 Scene *sce;
6567 if(main->versionfile != 244 || main->subversionfile < 2) {
6568 Mesh *me;
6570 for(sce= main->scene.first; sce; sce= sce->id.next) {
6571 sce->r.mode |= R_SSS;
6572 sce->bg_scenes.first= sce->bg_scenes.last= NULL;
6573 sce->bg_flags= 0;
6576 /* Copy over old per-level multires vertex data
6577 into a single vertex array in struct Multires */
6579 for(me = main->mesh.first; me; me=me->id.next) {
6580 if(me->mr) {
6581 MultiresLevel *lvl = me->mr->levels.last;
6582 if(lvl) {
6583 me->mr->verts = lvl->verts;
6584 lvl->verts = NULL;
6585 /* Don't need the other vert arrays */
6586 for(lvl = lvl->prev; lvl; lvl = lvl->prev) {
6587 MEM_freeN(lvl->verts);
6588 lvl->verts = NULL;
6594 /* correct older action editors - incorrect scrolling */
6595 for(sc= main->screen.first; sc; sc= sc->id.next) {
6596 ScrArea *sa;
6597 sa= sc->areabase.first;
6598 while(sa) {
6599 SpaceLink *sl;
6601 for (sl= sa->spacedata.first; sl; sl= sl->next) {
6602 if(sl->spacetype==SPACE_ACTION) {
6603 SpaceAction *saction= (SpaceAction*) sl;
6605 saction->v2d.tot.ymin= -1000.0;
6606 saction->v2d.tot.ymax= 0.0;
6608 saction->v2d.cur.ymin= -75.0;
6609 saction->v2d.cur.ymax= 5.0;
6611 else if(sl->spacetype==SPACE_NODE) {
6612 SpaceNode *snode= (SpaceNode *)sl;
6613 snode->v2d.minzoom= 0.09f;
6614 snode->v2d.maxzoom= 2.31f;
6617 sa = sa->next;
6622 if(main->versionfile <= 245) {
6623 Scene *sce;
6624 bNodeTree *ntree;
6626 if(main->versionfile != 245) {
6627 for(sce= main->scene.first; sce; sce= sce->id.next)
6628 sce->frame_step= 1;
6631 if(main->versionfile != 245 || main->subversionfile < 1) {
6632 for(sce= main->scene.first; sce; sce= sce->id.next) {
6633 sce->compo_scenes.first= sce->compo_scenes.last= NULL;
6634 sce->compo_flags= 0;
6637 if(main->versionfile != 245 || main->subversionfile < 2) {
6638 for(sce= main->scene.first; sce; sce= sce->id.next) {
6639 if (sce->r.frs_sec_base == 0) {
6640 sce->r.frs_sec_base = 1;
6643 if(sce->nodetree)
6644 ntree_version_245_2(sce->nodetree);
6647 for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
6648 ntree_version_245_2(ntree);
6650 if(main->versionfile != 245 || main->subversionfile < 3) {
6651 Image *ima;
6653 for(ima= main->image.first; ima; ima= ima->id.next) {
6654 if (!(ima->flag & IMA_DO_PREMUL))
6655 ima->flag|= IMA_DO_PREMUL;
6658 if(main->versionfile != 245 || main->subversionfile < 4) {
6659 Material *ma;
6660 Lamp *la;
6661 World *wrld;
6663 /* QMC sampler. */
6664 for(ma= main->mat.first; ma; ma= ma->id.next) {
6665 ma->gloss_mir= ma->gloss_tra= 1.0;
6666 ma->aniso_gloss_mir= 1.0;
6667 ma->samp_gloss_mir= ma->samp_gloss_tra= 18;
6668 ma->adapt_thresh_mir= ma->adapt_thresh_tra= 0.005;
6669 ma->dist_mir= 0.0;
6670 ma->fadeto_mir= MA_RAYMIR_FADETOSKY;
6673 for(wrld= main->world.first; wrld; wrld= wrld->id.next) {
6674 if (wrld->mode & WO_AMB_OCC)
6675 wrld->ao_samp_method= WO_AOSAMP_CONSTANT;
6676 else
6677 wrld->ao_samp_method= WO_AOSAMP_HAMMERSLEY;
6679 wrld->ao_adapt_thresh= 0.005;
6682 for(la= main->lamp.first; la; la= la->id.next) {
6683 if (la->type == LA_AREA)
6684 la->ray_samp_method= LA_SAMP_CONSTANT;
6685 else
6686 la->ray_samp_method= LA_SAMP_HALTON;
6688 la->adapt_thresh= 0.001;
6689 if (la->mode & LA_QUAD) la->falloff_type = LA_FALLOFF_SLIDERS;
6690 else la->falloff_type = LA_FALLOFF_INVLINEAR;
6692 la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
6693 curvemapping_initialize(la->curfalloff);
6696 if(main->versionfile != 245 || main->subversionfile < 5) {
6697 for(sce= main->scene.first; sce; sce= sce->id.next) {
6698 if(sce->nodetree)
6699 ntree_version_245_4(sce->nodetree);
6702 for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
6703 ntree_version_245_4(ntree);
6706 for(sce= main->scene.first; sce; sce= sce->id.next) {
6707 if(sce->r.cineongamma == 0.0) {
6708 sce->r.cineonblack= 95;
6709 sce->r.cineonwhite= 685;
6710 sce->r.cineongamma= 1.7f;
6715 /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
6716 /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
6718 /* don't forget to set version number in blender.c! */
6721 static void lib_link_all(FileData *fd, Main *main)
6723 oldnewmap_sort(fd);
6725 lib_link_screen(fd, main);
6726 lib_link_scene(fd, main);
6727 lib_link_object(fd, main);
6728 lib_link_curve(fd, main);
6729 lib_link_mball(fd, main);
6730 lib_link_material(fd, main);
6731 lib_link_texture(fd, main);
6732 lib_link_image(fd, main);
6733 lib_link_ipo(fd, main);
6734 lib_link_key(fd, main);
6735 lib_link_world(fd, main);
6736 lib_link_lamp(fd, main);
6737 lib_link_latt(fd, main);
6738 lib_link_text(fd, main);
6739 lib_link_camera(fd, main);
6740 lib_link_sound(fd, main);
6741 lib_link_group(fd, main);
6742 lib_link_armature(fd, main);
6743 lib_link_action(fd, main);
6744 lib_link_vfont(fd, main);
6745 lib_link_screen_sequence_ipos(main);
6746 lib_link_nodetree(fd, main); /* has to be done after scene/materials, this will verify group nodes */
6747 lib_link_brush(fd, main);
6749 lib_link_mesh(fd, main); /* as last: tpage images with users at zero */
6751 lib_link_library(fd, main); /* only init users */
6754 static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
6756 Link *link;
6758 bfd->user= read_struct(fd, bhead, "user def");
6759 bfd->user->themes.first= bfd->user->themes.last= NULL;
6761 bhead = blo_nextbhead(fd, bhead);
6763 /* read all attached data */
6764 while(bhead && bhead->code==DATA) {
6765 link= read_struct(fd, bhead, "user def data");
6766 BLI_addtail(&bfd->user->themes, link);
6767 bhead = blo_nextbhead(fd, bhead);
6770 return bhead;
6773 BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
6775 BHead *bhead= blo_firstbhead(fd);
6776 BlendFileData *bfd;
6777 FileGlobal *fg = (FileGlobal *)NULL;
6779 bfd= MEM_callocN(sizeof(BlendFileData), "blendfiledata");
6780 bfd->main= MEM_callocN(sizeof(Main), "main");
6781 BLI_addtail(&fd->mainlist, bfd->main);
6783 bfd->main->versionfile= fd->fileversion;
6785 while(bhead) {
6786 switch(bhead->code) {
6787 case GLOB:
6788 case DATA:
6789 case DNA1:
6790 case TEST:
6791 case REND:
6792 if (bhead->code==GLOB) {
6793 fg= read_struct(fd, bhead, "Global");
6794 /* set right away */
6795 bfd->main->subversionfile= fg->subversion;
6796 bfd->main->minversionfile= fg->minversion;
6797 bfd->main->minsubversionfile= fg->minsubversion;
6799 bhead = blo_nextbhead(fd, bhead);
6800 break;
6801 case USER:
6802 bhead= read_userdef(bfd, fd, bhead);
6803 break;
6804 case ENDB:
6805 bhead = NULL;
6806 break;
6808 case ID_LI:
6809 bhead = read_libblock(fd, bfd->main, bhead, LIB_LOCAL, NULL);
6810 break;
6811 case ID_ID:
6812 /* always adds to the most recently loaded
6813 * ID_LI block, see direct_link_library.
6814 * this is part of the file format definition.
6816 bhead = read_libblock(fd, fd->mainlist.last, bhead, LIB_READ+LIB_EXTERN, NULL);
6817 break;
6819 default:
6820 bhead = read_libblock(fd, bfd->main, bhead, LIB_LOCAL, NULL);
6824 /* do before read_libraries, but skip undo case */
6825 // if(fd->memfile==NULL) (the mesh shuffle hacks don't work yet? ton)
6826 do_versions(fd, NULL, bfd->main);
6828 read_libraries(fd, &fd->mainlist);
6830 blo_join_main(&fd->mainlist);
6832 lib_link_all(fd, bfd->main);
6833 lib_verify_nodetree(bfd->main);
6835 if(fg)
6836 link_global(fd, bfd, fg); /* as last */
6838 /* removed here: check for existance of curscreen/scene, moved to kernel setup_app */
6839 MEM_freeN(fg);
6841 return bfd;
6844 /* ************* APPEND LIBRARY ************** */
6846 struct bheadsort {
6847 BHead *bhead;
6848 void *old;
6851 static int verg_bheadsort(const void *v1, const void *v2)
6853 const struct bheadsort *x1=v1, *x2=v2;
6855 if( x1->old > x2->old) return 1;
6856 else if( x1->old < x2->old) return -1;
6857 return 0;
6860 static void sort_bhead_old_map(FileData *fd)
6862 BHead *bhead;
6863 struct bheadsort *bhs;
6864 int tot= 0;
6866 for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead))
6867 tot++;
6869 fd->tot_bheadmap= tot;
6870 if(tot==0) return;
6872 bhs= fd->bheadmap= MEM_mallocN(tot*sizeof(struct bheadsort), "bheadsort");
6874 for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead), bhs++) {
6875 bhs->bhead= bhead;
6876 bhs->old= bhead->old;
6879 qsort(fd->bheadmap, tot, sizeof(struct bheadsort), verg_bheadsort);
6883 static BHead *find_previous_lib(FileData *fd, BHead *bhead)
6885 for (; bhead; bhead= blo_prevbhead(fd, bhead))
6886 if (bhead->code==ID_LI)
6887 break;
6889 return bhead;
6892 static BHead *find_bhead(FileData *fd, void *old)
6894 // BHead *bhead;
6895 struct bheadsort *bhs, bhs_s;
6897 if (!old)
6898 return NULL;
6900 if (fd->bheadmap==NULL)
6901 sort_bhead_old_map(fd);
6903 bhs_s.old= old;
6904 bhs= bsearch(&bhs_s, fd->bheadmap, fd->tot_bheadmap, sizeof(struct bheadsort), verg_bheadsort);
6906 if(bhs)
6907 return bhs->bhead;
6909 // for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead))
6910 // if (bhead->old==old)
6911 // return bhead;
6913 return NULL;
6916 char *bhead_id_name(FileData *fd, BHead *bhead)
6918 return ((char *)(bhead+1)) + fd->id_name_offs;
6921 static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
6923 ListBase *lb;
6924 char *idname= bhead_id_name(fd, bhead);
6926 lb= wich_libbase(mainvar, GS(idname));
6928 if(lb) {
6929 ID *id= lb->first;
6930 while(id) {
6931 if( strcmp(id->name, idname)==0 )
6932 return id;
6933 id= id->next;
6936 return NULL;
6939 static void expand_doit(FileData *fd, Main *mainvar, void *old)
6941 BHead *bhead;
6942 ID *id;
6944 bhead= find_bhead(fd, old);
6945 if(bhead) {
6946 /* from another library? */
6947 if(bhead->code==ID_ID) {
6948 BHead *bheadlib= find_previous_lib(fd, bhead);
6950 if(bheadlib) {
6951 Library *lib= read_struct(fd, bheadlib, "Library");
6952 Main *ptr= blo_find_main(&fd->mainlist, lib->name, fd->filename);
6954 id= is_yet_read(fd, ptr, bhead);
6956 if(id==NULL) {
6957 read_libblock(fd, ptr, bhead, LIB_READ+LIB_INDIRECT, NULL);
6958 if(G.f & G_DEBUG) printf("expand_doit: other lib %s\n", lib->name);
6960 /* for outliner dependency only */
6961 ptr->curlib->parent= mainvar->curlib;
6963 else {
6964 //oldnewmap_insert(fd->libmap, bhead->old, id, 1);
6966 change_idid_adr_fd(fd, bhead->old, id);
6967 if(G.f & G_DEBUG) printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name);
6970 MEM_freeN(lib);
6973 else {
6974 id= is_yet_read(fd, mainvar, bhead);
6975 if(id==NULL) {
6976 read_libblock(fd, mainvar, bhead, LIB_TESTIND, NULL);
6978 else {
6979 /* this is actually only needed on UI call? when ID was already read before, and another append
6980 happens which invokes same ID... in that case the lookup table needs this entry */
6981 oldnewmap_insert(fd->libmap, bhead->old, id, 1);
6982 if(G.f & G_DEBUG) printf("expand: already read %s\n", id->name);
6988 static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo)
6990 IpoCurve *icu;
6991 for(icu= ipo->curve.first; icu; icu= icu->next) {
6992 if(icu->driver)
6993 expand_doit(fd, mainvar, icu->driver->ob);
6997 static void expand_group(FileData *fd, Main *mainvar, Group *group)
6999 GroupObject *go;
7001 for(go= group->gobject.first; go; go= go->next) {
7002 expand_doit(fd, mainvar, go->ob);
7006 static void expand_key(FileData *fd, Main *mainvar, Key *key)
7008 expand_doit(fd, mainvar, key->ipo);
7012 static void expand_texture(FileData *fd, Main *mainvar, Tex *tex)
7014 expand_doit(fd, mainvar, tex->ima);
7015 expand_doit(fd, mainvar, tex->ipo);
7018 static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
7020 int a;
7022 for(a=0; a<MAX_MTEX; a++)
7023 if(brush->mtex[a])
7024 expand_doit(fd, mainvar, brush->mtex[a]->tex);
7025 expand_doit(fd, mainvar, brush->clone.image);
7028 static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
7030 bNode *node;
7032 for(node= ntree->nodes.first; node; node= node->next)
7033 if(node->id && node->type!=CMP_NODE_R_LAYERS)
7034 expand_doit(fd, mainvar, node->id);
7038 static void expand_material(FileData *fd, Main *mainvar, Material *ma)
7040 int a;
7042 for(a=0; a<MAX_MTEX; a++) {
7043 if(ma->mtex[a]) {
7044 expand_doit(fd, mainvar, ma->mtex[a]->tex);
7045 expand_doit(fd, mainvar, ma->mtex[a]->object);
7049 expand_doit(fd, mainvar, ma->ipo);
7051 if(ma->nodetree)
7052 expand_nodetree(fd, mainvar, ma->nodetree);
7055 static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la)
7057 int a;
7059 for(a=0; a<MAX_MTEX; a++) {
7060 if(la->mtex[a]) {
7061 expand_doit(fd, mainvar, la->mtex[a]->tex);
7062 expand_doit(fd, mainvar, la->mtex[a]->object);
7065 expand_doit(fd, mainvar, la->ipo);
7068 static void expand_lattice(FileData *fd, Main *mainvar, Lattice *lt)
7070 expand_doit(fd, mainvar, lt->ipo);
7071 expand_doit(fd, mainvar, lt->key);
7075 static void expand_world(FileData *fd, Main *mainvar, World *wrld)
7077 int a;
7079 for(a=0; a<MAX_MTEX; a++) {
7080 if(wrld->mtex[a]) {
7081 expand_doit(fd, mainvar, wrld->mtex[a]->tex);
7082 expand_doit(fd, mainvar, wrld->mtex[a]->object);
7085 expand_doit(fd, mainvar, wrld->ipo);
7089 static void expand_mball(FileData *fd, Main *mainvar, MetaBall *mb)
7091 int a;
7093 for(a=0; a<mb->totcol; a++) {
7094 expand_doit(fd, mainvar, mb->mat[a]);
7098 static void expand_curve(FileData *fd, Main *mainvar, Curve *cu)
7100 int a;
7102 for(a=0; a<cu->totcol; a++) {
7103 expand_doit(fd, mainvar, cu->mat[a]);
7105 expand_doit(fd, mainvar, cu->vfont);
7106 expand_doit(fd, mainvar, cu->vfontb);
7107 expand_doit(fd, mainvar, cu->vfonti);
7108 expand_doit(fd, mainvar, cu->vfontbi);
7109 expand_doit(fd, mainvar, cu->key);
7110 expand_doit(fd, mainvar, cu->ipo);
7111 expand_doit(fd, mainvar, cu->bevobj);
7112 expand_doit(fd, mainvar, cu->taperobj);
7113 expand_doit(fd, mainvar, cu->textoncurve);
7116 static void expand_mesh(FileData *fd, Main *mainvar, Mesh *me)
7118 CustomDataLayer *layer;
7119 MTFace *mtf;
7120 TFace *tf;
7121 int a, i;
7123 for(a=0; a<me->totcol; a++) {
7124 expand_doit(fd, mainvar, me->mat[a]);
7127 expand_doit(fd, mainvar, me->key);
7128 expand_doit(fd, mainvar, me->texcomesh);
7130 if(me->tface) {
7131 tf= me->tface;
7132 for(i=0; i<me->totface; i++, tf++)
7133 if(tf->tpage)
7134 expand_doit(fd, mainvar, tf->tpage);
7137 for(a=0; a<me->fdata.totlayer; a++) {
7138 layer= &me->fdata.layers[a];
7140 if(layer->type == CD_MTFACE) {
7141 mtf= (MTFace*)layer->data;
7142 for(i=0; i<me->totface; i++, mtf++)
7143 if(mtf->tpage)
7144 expand_doit(fd, mainvar, mtf->tpage);
7149 static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
7151 bConstraint *curcon;
7153 for (curcon=lb->first; curcon; curcon=curcon->next) {
7154 switch (curcon->type) {
7155 case CONSTRAINT_TYPE_PYTHON:
7157 bPythonConstraint *data = (bPythonConstraint*)curcon->data;
7158 expand_doit(fd, mainvar, data->tar);
7159 expand_doit(fd, mainvar, data->text);
7160 break;
7162 case CONSTRAINT_TYPE_ACTION:
7164 bActionConstraint *data = (bActionConstraint*)curcon->data;
7165 expand_doit(fd, mainvar, data->tar);
7166 expand_doit(fd, mainvar, data->act);
7168 break;
7169 case CONSTRAINT_TYPE_LOCLIKE:
7171 bLocateLikeConstraint *data = (bLocateLikeConstraint*)curcon->data;
7172 expand_doit(fd, mainvar, data->tar);
7173 break;
7175 case CONSTRAINT_TYPE_ROTLIKE:
7177 bRotateLikeConstraint *data = (bRotateLikeConstraint*)curcon->data;
7178 expand_doit(fd, mainvar, data->tar);
7179 break;
7181 case CONSTRAINT_TYPE_SIZELIKE:
7183 bSizeLikeConstraint *data = (bSizeLikeConstraint*)curcon->data;
7184 expand_doit(fd, mainvar, data->tar);
7185 break;
7187 case CONSTRAINT_TYPE_KINEMATIC:
7189 bKinematicConstraint *data = (bKinematicConstraint*)curcon->data;
7190 expand_doit(fd, mainvar, data->tar);
7191 break;
7193 case CONSTRAINT_TYPE_TRACKTO:
7195 bTrackToConstraint *data = (bTrackToConstraint*)curcon->data;
7196 expand_doit(fd, mainvar, data->tar);
7197 break;
7199 case CONSTRAINT_TYPE_MINMAX:
7201 bMinMaxConstraint *data = (bMinMaxConstraint*)curcon->data;
7202 expand_doit(fd, mainvar, data->tar);
7203 break;
7205 case CONSTRAINT_TYPE_LOCKTRACK:
7207 bLockTrackConstraint *data = (bLockTrackConstraint*)curcon->data;
7208 expand_doit(fd, mainvar, data->tar);
7209 break;
7211 case CONSTRAINT_TYPE_FOLLOWPATH:
7213 bFollowPathConstraint *data = (bFollowPathConstraint*)curcon->data;
7214 expand_doit(fd, mainvar, data->tar);
7215 break;
7217 case CONSTRAINT_TYPE_DISTANCELIMIT:
7219 bDistanceLimitConstraint *data = (bDistanceLimitConstraint*)curcon->data;
7220 expand_doit(fd, mainvar, data->tar);
7221 break;
7223 case CONSTRAINT_TYPE_STRETCHTO:
7225 bStretchToConstraint *data = (bStretchToConstraint*)curcon->data;
7226 expand_doit(fd, mainvar, data->tar);
7227 break;
7229 case CONSTRAINT_TYPE_RIGIDBODYJOINT:
7231 bRigidBodyJointConstraint *data = (bRigidBodyJointConstraint*)curcon->data;
7232 expand_doit(fd, mainvar, data->tar);
7233 break;
7235 case CONSTRAINT_TYPE_CLAMPTO:
7237 bClampToConstraint *data = (bClampToConstraint*)curcon->data;
7238 expand_doit(fd, mainvar, data->tar);
7239 break;
7241 case CONSTRAINT_TYPE_NULL:
7242 break;
7243 default:
7244 break;
7249 static void expand_bones(FileData *fd, Main *mainvar, Bone *bone)
7251 Bone *curBone;
7253 for (curBone = bone->childbase.first; curBone; curBone=curBone->next) {
7254 expand_bones(fd, mainvar, curBone);
7259 static void expand_pose(FileData *fd, Main *mainvar, bPose *pose)
7261 bPoseChannel *chan;
7263 if (!pose)
7264 return;
7266 for (chan = pose->chanbase.first; chan; chan=chan->next) {
7267 expand_constraints(fd, mainvar, &chan->constraints);
7268 expand_doit(fd, mainvar, chan->custom);
7272 static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm)
7274 Bone *curBone;
7276 for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) {
7277 expand_bones(fd, mainvar, curBone);
7281 static void expand_constraint_channels(FileData *fd, Main *mainvar, ListBase *chanbase)
7283 bConstraintChannel *chan;
7284 for (chan=chanbase->first; chan; chan=chan->next){
7285 expand_doit(fd, mainvar, chan->ipo);
7289 static void expand_action(FileData *fd, Main *mainvar, bAction *act)
7291 bActionChannel *chan;
7292 for (chan=act->chanbase.first; chan; chan=chan->next) {
7293 expand_doit(fd, mainvar, chan->ipo);
7294 expand_constraint_channels(fd, mainvar, &chan->constraintChannels);
7298 static void expand_modifier(FileData *fd, Main *mainvar, ModifierData *md)
7300 if (md->type==eModifierType_Lattice) {
7301 LatticeModifierData *lmd = (LatticeModifierData*) md;
7303 expand_doit(fd, mainvar, lmd->object);
7305 else if (md->type==eModifierType_Curve) {
7306 CurveModifierData *cmd = (CurveModifierData*) md;
7308 expand_doit(fd, mainvar, cmd->object);
7310 else if (md->type==eModifierType_Array) {
7311 ArrayModifierData *amd = (ArrayModifierData*) md;
7313 expand_doit(fd, mainvar, amd->curve_ob);
7314 expand_doit(fd, mainvar, amd->offset_ob);
7316 else if (md->type==eModifierType_Mirror) {
7317 MirrorModifierData *mmd = (MirrorModifierData*) md;
7319 expand_doit(fd, mainvar, mmd->mirror_ob);
7323 static void expand_scriptlink(FileData *fd, Main *mainvar, ScriptLink *slink)
7325 int i;
7327 for(i=0; i<slink->totscript; i++) {
7328 expand_doit(fd, mainvar, slink->scripts[i]);
7332 static void expand_object(FileData *fd, Main *mainvar, Object *ob)
7334 ModifierData *md;
7335 bSensor *sens;
7336 bController *cont;
7337 bActuator *act;
7338 bActionStrip *strip;
7339 PartEff *paf;
7340 int a;
7343 expand_doit(fd, mainvar, ob->data);
7344 expand_doit(fd, mainvar, ob->ipo);
7345 expand_doit(fd, mainvar, ob->action);
7347 for (md=ob->modifiers.first; md; md=md->next) {
7348 expand_modifier(fd, mainvar, md);
7351 expand_pose(fd, mainvar, ob->pose);
7352 expand_constraints(fd, mainvar, &ob->constraints);
7353 expand_constraint_channels(fd, mainvar, &ob->constraintChannels);
7355 for (strip=ob->nlastrips.first; strip; strip=strip->next){
7356 expand_doit(fd, mainvar, strip->object);
7357 expand_doit(fd, mainvar, strip->act);
7358 expand_doit(fd, mainvar, strip->ipo);
7361 for(a=0; a<ob->totcol; a++) {
7362 expand_doit(fd, mainvar, ob->mat[a]);
7365 paf = give_parteff(ob);
7366 if (paf && paf->group)
7367 expand_doit(fd, mainvar, paf->group);
7369 if(ob->dup_group)
7370 expand_doit(fd, mainvar, ob->dup_group);
7372 if(ob->proxy)
7373 expand_doit(fd, mainvar, ob->proxy);
7374 if(ob->proxy_group)
7375 expand_doit(fd, mainvar, ob->proxy_group);
7377 sens= ob->sensors.first;
7378 while(sens) {
7379 for(a=0; a<sens->totlinks; a++) {
7380 sens->links[a]= newglobadr(fd, sens->links[a]);
7382 if(sens->type==SENS_TOUCH) {
7383 bTouchSensor *ts= sens->data;
7384 expand_doit(fd, mainvar, ts->ma);
7386 else if(sens->type==SENS_MESSAGE) {
7387 bMessageSensor *ms= sens->data;
7388 expand_doit(fd, mainvar, ms->fromObject);
7390 sens= sens->next;
7393 cont= ob->controllers.first;
7394 while(cont) {
7395 for(a=0; a<cont->totlinks; a++) {
7396 cont->links[a]= newglobadr(fd, cont->links[a]);
7398 if(cont->type==CONT_PYTHON) {
7399 bPythonCont *pc= cont->data;
7400 expand_doit(fd, mainvar, pc->text);
7402 cont= cont->next;
7405 act= ob->actuators.first;
7406 while(act) {
7407 if(act->type==ACT_SOUND) {
7408 bSoundActuator *sa= act->data;
7409 expand_doit(fd, mainvar, sa->sound);
7411 else if(act->type==ACT_CAMERA) {
7412 bCameraActuator *ca= act->data;
7413 expand_doit(fd, mainvar, ca->ob);
7415 else if(act->type==ACT_EDIT_OBJECT) {
7416 bEditObjectActuator *eoa= act->data;
7417 if(eoa) {
7418 expand_doit(fd, mainvar, eoa->ob);
7419 expand_doit(fd, mainvar, eoa->me);
7422 else if(act->type==ACT_SCENE) {
7423 bSceneActuator *sa= act->data;
7424 expand_doit(fd, mainvar, sa->camera);
7425 expand_doit(fd, mainvar, sa->scene);
7427 else if(act->type==ACT_ACTION) {
7428 bActionActuator *aa= act->data;
7429 expand_doit(fd, mainvar, aa->act);
7431 else if(act->type==ACT_PROPERTY) {
7432 bPropertyActuator *pa= act->data;
7433 expand_doit(fd, mainvar, pa->ob);
7435 else if(act->type==ACT_MESSAGE) {
7436 bMessageActuator *ma= act->data;
7437 expand_doit(fd, mainvar, ma->toObject);
7439 act= act->next;
7442 expand_scriptlink(fd, mainvar, &ob->scriptlink);
7445 static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
7447 Base *base;
7448 SceneRenderLayer *srl;
7450 for(base= sce->base.first; base; base= base->next) {
7451 expand_doit(fd, mainvar, base->object);
7453 expand_doit(fd, mainvar, sce->camera);
7454 expand_doit(fd, mainvar, sce->world);
7456 if(sce->nodetree)
7457 expand_nodetree(fd, mainvar, sce->nodetree);
7459 for(srl= sce->r.layers.first; srl; srl= srl->next) {
7460 expand_doit(fd, mainvar, srl->mat_override);
7461 expand_doit(fd, mainvar, srl->light_override);
7466 static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
7468 expand_doit(fd, mainvar, ca->ipo);
7471 static void expand_sound(FileData *fd, Main *mainvar, bSound *snd)
7473 expand_doit(fd, mainvar, snd->ipo);
7477 static void expand_main(FileData *fd, Main *mainvar)
7479 ListBase *lbarray[MAX_LIBARRAY];
7480 ID *id;
7481 int a, doit= 1;
7483 if(fd==0) return;
7485 while(doit) {
7486 doit= 0;
7488 a= set_listbasepointers(mainvar, lbarray);
7489 while(a--) {
7490 id= lbarray[a]->first;
7492 while(id) {
7493 if(id->flag & LIB_TEST) {
7495 switch(GS(id->name)) {
7497 case ID_OB:
7498 expand_object(fd, mainvar, (Object *)id);
7499 break;
7500 case ID_ME:
7501 expand_mesh(fd, mainvar, (Mesh *)id);
7502 break;
7503 case ID_CU:
7504 expand_curve(fd, mainvar, (Curve *)id);
7505 break;
7506 case ID_MB:
7507 expand_mball(fd, mainvar, (MetaBall *)id);
7508 break;
7509 case ID_SCE:
7510 expand_scene(fd, mainvar, (Scene *)id);
7511 break;
7512 case ID_MA:
7513 expand_material(fd, mainvar, (Material *)id);
7514 break;
7515 case ID_TE:
7516 expand_texture(fd, mainvar, (Tex *)id);
7517 break;
7518 case ID_WO:
7519 expand_world(fd, mainvar, (World *)id);
7520 break;
7521 case ID_LT:
7522 expand_lattice(fd, mainvar, (Lattice *)id);
7523 break;
7524 case ID_LA:
7525 expand_lamp(fd, mainvar,(Lamp *)id);
7526 break;
7527 case ID_KE:
7528 expand_key(fd, mainvar, (Key *)id);
7529 break;
7530 case ID_CA:
7531 expand_camera(fd, mainvar, (Camera *)id);
7532 break;
7533 case ID_SO:
7534 expand_sound(fd, mainvar, (bSound *)id);
7535 break;
7536 case ID_AR:
7537 expand_armature(fd, mainvar, (bArmature *)id);
7538 break;
7539 case ID_AC:
7540 expand_action(fd, mainvar, (bAction *)id);
7541 break;
7542 case ID_GR:
7543 expand_group(fd, mainvar, (Group *)id);
7544 break;
7545 case ID_NT:
7546 expand_nodetree(fd, mainvar, (bNodeTree *)id);
7547 break;
7548 case ID_BR:
7549 expand_brush(fd, mainvar, (Brush *)id);
7550 break;
7551 case ID_IP:
7552 expand_ipo(fd, mainvar, (Ipo *)id);
7553 break;
7556 doit= 1;
7557 id->flag -= LIB_TEST;
7560 id= id->next;
7566 static int object_in_any_scene(Object *ob)
7568 Scene *sce;
7570 for(sce= G.main->scene.first; sce; sce= sce->id.next)
7571 if(object_in_scene(ob, sce))
7572 return 1;
7573 return 0;
7576 /* when *lib set, it also does objects that were in the appended group */
7577 static void give_base_to_objects(Scene *sce, ListBase *lb, Library *lib)
7579 Object *ob;
7580 Base *base;
7582 /* give all objects which are LIB_INDIRECT a base, or for a group when *lib has been set */
7583 for(ob= lb->first; ob; ob= ob->id.next) {
7585 if( ob->id.flag & LIB_INDIRECT ) {
7586 int do_it= 0;
7588 if(ob->id.us==0)
7589 do_it= 1;
7590 else if(ob->id.us==1 && lib)
7591 if(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(ob)==0)
7592 do_it= 1;
7594 if(do_it) {
7595 base= MEM_callocN( sizeof(Base), "add_ext_base");
7596 BLI_addtail(&(sce->base), base);
7597 base->lay= ob->lay;
7598 base->object= ob;
7599 base->flag= ob->flag;
7600 ob->id.us= 1;
7602 ob->id.flag -= LIB_INDIRECT;
7603 ob->id.flag |= LIB_EXTERN;
7611 static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *name, int idcode, short flag)
7613 Object *ob;
7614 Base *base;
7615 BHead *bhead;
7616 ID *id;
7617 int endloop=0;
7619 bhead = blo_firstbhead(fd);
7620 while(bhead && endloop==0) {
7622 if(bhead->code==ENDB) endloop= 1;
7623 else if(bhead->code==idcode) {
7624 char *idname= bhead_id_name(fd, bhead);
7626 if(strcmp(idname+2, name)==0) {
7628 id= is_yet_read(fd, mainvar, bhead);
7629 if(id==NULL) {
7630 read_libblock(fd, mainvar, bhead, LIB_TESTEXT, NULL);
7632 else {
7633 printf("append: already linked\n");
7634 oldnewmap_insert(fd->libmap, bhead->old, id, 1);
7635 if(id->flag & LIB_INDIRECT) {
7636 id->flag -= LIB_INDIRECT;
7637 id->flag |= LIB_EXTERN;
7641 if(idcode==ID_OB) { /* loose object: give a base */
7642 base= MEM_callocN( sizeof(Base), "app_nam_part");
7643 BLI_addtail(&scene->base, base);
7645 if(id==NULL) ob= mainvar->object.last;
7646 else ob= (Object *)id;
7648 /* this is bad code... G.vd nor G.scene should be used on this level... */
7649 if((flag & FILE_ACTIVELAY)) {
7650 if(G.vd) ob->lay= G.vd->layact;
7651 else ob->lay = G.scene->lay;
7653 base->lay= ob->lay;
7654 base->object= ob;
7655 ob->id.us++;
7657 if(flag & FILE_AUTOSELECT) {
7658 base->flag |= SELECT;
7659 base->object->flag = base->flag;
7660 /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
7663 endloop= 1;
7667 bhead = blo_nextbhead(fd, bhead);
7671 static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
7673 BHead *bhead;
7675 for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
7676 if (bhead->code == GS(id->name)) {
7678 if (BLI_streq(id->name, bhead_id_name(fd, bhead))) {
7679 id->flag &= ~LIB_READ;
7680 id->flag |= LIB_TEST;
7681 // printf("read lib block %s\n", id->name);
7682 read_libblock(fd, mainvar, bhead, id->flag, id_r);
7684 break;
7686 } else if (bhead->code==ENDB)
7687 break;
7691 /* common routine to append/link something from a library */
7693 static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int idcode,
7694 int totsel, FileData *fd)
7696 Main *mainl;
7697 Library *curlib;
7699 /* make mains */
7700 blo_split_main(&fd->mainlist, G.main);
7702 /* which one do we need? */
7703 mainl = blo_find_main(&fd->mainlist, dir, G.sce);
7705 mainl->versionfile= fd->fileversion; /* needed for do_version */
7707 curlib= mainl->curlib;
7709 if(totsel==0) {
7710 append_named_part(fd, mainl, scene, sfile->file, idcode, sfile->flag);
7712 else {
7713 int a;
7714 for(a=0; a<sfile->totfile; a++) {
7715 if(sfile->filelist[a].flags & ACTIVE) {
7716 append_named_part(fd, mainl, scene, sfile->filelist[a].relname, idcode, sfile->flag);
7721 /* make main consistant */
7722 expand_main(fd, mainl);
7724 /* do this when expand found other libs */
7725 read_libraries(fd, &fd->mainlist);
7727 if(sfile->flag & FILE_STRINGCODE) {
7729 /* use the full path, this could have been read by other library even */
7730 BLI_strncpy(mainl->curlib->name, mainl->curlib->filename, sizeof(mainl->curlib->name));
7732 /* uses current .blend file as reference */
7733 BLI_makestringcode(G.sce, mainl->curlib->name);
7736 blo_join_main(&fd->mainlist);
7737 G.main= fd->mainlist.first;
7739 lib_link_all(fd, G.main);
7740 lib_verify_nodetree(G.main);
7742 /* give a base to loose objects. If group append, do it for objects too */
7743 if(idcode==ID_GR)
7744 give_base_to_objects(scene, &(G.main->object), (sfile->flag & FILE_LINK)?NULL:curlib);
7745 else
7746 give_base_to_objects(scene, &(G.main->object), NULL);
7748 /* has been removed... erm, why? s..ton) */
7749 /* 20040907: looks like they are give base already in append_named_part(); -Nathan L */
7750 /* 20041208: put back. It only linked direct, not indirect objects (ton) */
7752 /* patch to prevent switch_endian happens twice */
7753 if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
7754 blo_freefiledata( fd );
7755 sfile->libfiledata= 0;
7758 return curlib;
7761 /* this is a version of BLO_library_append needed by the BPython API, so
7762 * scripts can load data from .blend files -- see Blender.Library module.*/
7763 /* append to G.scene */
7764 /* this should probably be moved into the Python code anyway */
7766 void BLO_script_library_append(BlendHandle *bh, char *dir, char *name,
7767 int idcode, short flag, Scene *scene )
7769 SpaceFile sfile;
7771 /* build a minimal "fake" SpaceFile object */
7772 sfile.flag = flag;
7773 sfile.totfile = 0;
7774 strcpy(sfile.file, name);
7776 /* try to append the requested object */
7778 library_append( scene, &sfile, dir, idcode, 0, (FileData *)bh );
7780 /* do we need to do this? */
7781 DAG_scene_sort(G.scene);
7784 /* append to G.scene */
7785 /* dir is a full path */
7786 void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
7788 FileData *fd= (FileData*) sfile->libfiledata;
7789 Library *curlib;
7790 Base *centerbase;
7791 Object *ob;
7792 int a, totsel=0;
7794 /* are there files selected? */
7795 for(a=0; a<sfile->totfile; a++) {
7796 if(sfile->filelist[a].flags & ACTIVE) {
7797 totsel++;
7801 if(totsel==0) {
7802 /* is the indicated file in the filelist? */
7803 if(sfile->file[0]) {
7804 for(a=0; a<sfile->totfile; a++) {
7805 if( strcmp(sfile->filelist[a].relname, sfile->file)==0) break;
7807 if(a==sfile->totfile) {
7808 error("Wrong indicated name");
7809 return;
7812 else {
7813 error("Nothing indicated");
7814 return;
7817 /* now we have or selected, or an indicated file */
7819 if(sfile->flag & FILE_AUTOSELECT) scene_deselect_all(G.scene);
7821 curlib = library_append( G.scene, sfile, dir, idcode, totsel, fd );
7823 /* when not linking (appending)... */
7824 if((sfile->flag & FILE_LINK)==0) {
7825 if(sfile->flag & FILE_ATCURSOR) {
7826 float *curs, centerloc[3], vec[3], min[3], max[3];
7827 int count= 0;
7829 INIT_MINMAX(min, max);
7831 centerbase= (G.scene->base.first);
7832 while(centerbase) {
7833 if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
7834 VECCOPY(vec, centerbase->object->loc);
7835 DO_MINMAX(vec, min, max);
7836 count++;
7838 centerbase= centerbase->next;
7840 if(count) {
7841 centerloc[0]= (min[0]+max[0])/2;
7842 centerloc[1]= (min[1]+max[1])/2;
7843 centerloc[2]= (min[2]+max[2])/2;
7844 curs = G.scene->cursor;
7845 VECSUB(centerloc,curs,centerloc);
7847 centerbase= (G.scene->base.first);
7848 while(centerbase) {
7849 if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
7850 ob= centerbase->object;
7851 ob->loc[0] += centerloc[0];
7852 ob->loc[1] += centerloc[1];
7853 ob->loc[2] += centerloc[2];
7855 centerbase= centerbase->next;
7862 /* ************* READ LIBRARY ************** */
7864 static int mainvar_count_libread_blocks(Main *mainvar)
7866 ListBase *lbarray[MAX_LIBARRAY];
7867 int a, tot= 0;
7869 a= set_listbasepointers(mainvar, lbarray);
7870 while(a--) {
7871 ID *id= lbarray[a]->first;
7873 for (id= lbarray[a]->first; id; id= id->next)
7874 if (id->flag & LIB_READ)
7875 tot++;
7877 return tot;
7880 static void read_libraries(FileData *basefd, ListBase *mainlist)
7882 Main *mainl= mainlist->first;
7883 Main *mainptr;
7884 ListBase *lbarray[MAX_LIBARRAY];
7885 int a, doit= 1;
7887 while(doit) {
7888 doit= 0;
7890 /* test 1: read libdata */
7891 mainptr= mainl->next;
7892 while(mainptr) {
7893 int tot= mainvar_count_libread_blocks(mainptr);
7895 // printf("found LIB_READ %s\n", mainptr->curlib->name);
7896 if(tot) {
7897 FileData *fd= mainptr->curlib->filedata;
7899 if(fd==NULL) {
7900 BlendReadError err;
7901 printf("read library: lib %s\n", mainptr->curlib->name);
7902 fd= blo_openblenderfile(mainptr->curlib->filename, &err);
7903 if (fd) {
7904 if (fd->libmap)
7905 oldnewmap_free(fd->libmap);
7907 fd->libmap = oldnewmap_new();
7909 mainptr->curlib->filedata= fd;
7910 mainptr->versionfile= fd->fileversion;
7912 else mainptr->curlib->filedata= NULL;
7914 if (fd==NULL)
7915 printf("ERROR: can't find lib %s \n", mainptr->curlib->filename);
7917 if(fd) {
7918 doit= 1;
7919 a= set_listbasepointers(mainptr, lbarray);
7920 while(a--) {
7921 ID *id= lbarray[a]->first;
7923 while(id) {
7924 ID *idn= id->next;
7925 if(id->flag & LIB_READ) {
7926 ID *realid= NULL;
7927 BLI_remlink(lbarray[a], id);
7929 append_id_part(fd, mainptr, id, &realid);
7930 if (!realid)
7931 printf("LIB ERROR: can't find %s\n", id->name);
7933 change_idid_adr(mainlist, basefd, id, realid);
7935 MEM_freeN(id);
7937 id= idn;
7941 expand_main(fd, mainptr);
7943 /* dang FileData... now new libraries need to be appended to original filedata, it is not a good replacement for the old global (ton) */
7944 while( fd->mainlist.first ) {
7945 Main *mp= fd->mainlist.first;
7946 BLI_remlink(&fd->mainlist, mp);
7947 BLI_addtail(&basefd->mainlist, mp);
7952 mainptr= mainptr->next;
7956 /* test if there are unread libblocks */
7957 for(mainptr= mainl->next; mainptr; mainptr= mainptr->next) {
7958 a= set_listbasepointers(mainptr, lbarray);
7959 while(a--) {
7960 ID *id= lbarray[a]->first;
7961 while(id) {
7962 ID *idn= id->next;
7963 if(id->flag & LIB_READ) {
7964 BLI_remlink(lbarray[a], id);
7966 printf("LIB ERROR: can't find %s\n", id->name);
7967 change_idid_adr(mainlist, basefd, id, NULL);
7969 MEM_freeN(id);
7971 id= idn;
7976 /* do versions, link, and free */
7977 for(mainptr= mainl->next; mainptr; mainptr= mainptr->next) {
7978 /* some mains still have to be read, then
7979 * versionfile is still zero! */
7980 if(mainptr->versionfile) {
7981 if(mainptr->curlib->filedata) // can be zero... with shift+f1 append
7982 do_versions(mainptr->curlib->filedata, mainptr->curlib, mainptr);
7983 else
7984 do_versions(basefd, NULL, mainptr);
7987 if(mainptr->curlib->filedata)
7988 lib_link_all(mainptr->curlib->filedata, mainptr);
7990 if(mainptr->curlib->filedata) blo_freefiledata(mainptr->curlib->filedata);
7991 mainptr->curlib->filedata= NULL;
7996 /* reading runtime */
7998 BlendFileData *blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r)
8000 BlendFileData *bfd = NULL;
8001 FileData *fd = filedata_new();
8002 fd->filedes = file;
8003 fd->buffersize = actualsize;
8004 fd->read = fd_read_from_file;
8006 fd = blo_decode_and_check(fd, error_r);
8007 if (!fd)
8008 return NULL;
8010 bfd= blo_read_file_internal(fd, error_r);
8011 blo_freefiledata(fd);
8013 return bfd;