diff options
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r-- | source/blender/blenloader/BLO_readfile.h | 4 | ||||
-rw-r--r-- | source/blender/blenloader/BLO_soundfile.h | 2 | ||||
-rw-r--r-- | source/blender/blenloader/BLO_sys_types.h | 29 | ||||
-rw-r--r-- | source/blender/blenloader/SConscript | 3 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readblenentry.c | 7 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1296 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.h | 5 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 228 |
8 files changed, 1280 insertions, 294 deletions
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 9cf300ea460..1219b1ba0c5 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -237,9 +237,9 @@ int BLO_has_bfile_extension(char *str); void BLO_library_append(struct SpaceFile *sfile, char *dir, int idcode, struct Scene *scene); void BLO_library_append_(BlendHandle **libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode, struct Scene *scene); -void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcode, short flag, struct Scene *scene); +void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, struct Scene *scene); -BlendFileData* blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r); +BlendFileData* blo_read_blendafterruntime(int file, char *name, int actualsize, BlendReadError *error_r); #ifdef __cplusplus } diff --git a/source/blender/blenloader/BLO_soundfile.h b/source/blender/blenloader/BLO_soundfile.h index 3d133b2d3bd..a239c7d8965 100644 --- a/source/blender/blenloader/BLO_soundfile.h +++ b/source/blender/blenloader/BLO_soundfile.h @@ -35,7 +35,5 @@ struct bSound; struct PackedFile; -//void sound_read_wav_data(bSound * sound, PackedFile * pf); - #endif diff --git a/source/blender/blenloader/BLO_sys_types.h b/source/blender/blenloader/BLO_sys_types.h index a1885894fe3..49155260b31 100644 --- a/source/blender/blenloader/BLO_sys_types.h +++ b/source/blender/blenloader/BLO_sys_types.h @@ -43,17 +43,13 @@ #ifdef __cplusplus extern "C" { #endif - -#ifdef FREE_WINDOWS -typedef unsigned char uint8_t; -typedef unsigned int uint32_t; -#endif #if defined(_WIN32) && !defined(FREE_WINDOWS) /* The __intXX are built-in types of the visual complier! So we don't * need to include anything else here. */ + typedef signed __int8 int8_t; typedef signed __int16 int16_t; typedef signed __int32 int32_t; @@ -64,6 +60,24 @@ typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; +#ifndef _INTPTR_T_DEFINED +#ifdef _WIN64 +typedef __int64 intptr_t; +#else +typedef long intptr_t; +#endif +#define _INTPTR_T_DEFINED +#endif + +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned long uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif + #elif defined(__linux__) /* Linux-i386, Linux-Alpha, Linux-ppc */ @@ -73,6 +87,10 @@ typedef unsigned __int64 uint64_t; #include <inttypes.h> +#elif defined(FREE_WINDOWS) + +#include <stdint.h> + #else /* FreeBSD, Irix, Solaris */ @@ -80,6 +98,7 @@ typedef unsigned __int64 uint64_t; #endif /* ifdef platform for types */ + #ifdef _WIN32 #define htonl(x) correctByteOrder(x) #define ntohl(x) correctByteOrder(x) diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 37d5f5381fa..ac3b1262cb7 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -5,7 +5,6 @@ sources = env.Glob('intern/*.c') incs = '. #/intern/guardedalloc ../blenlib ../blenkernel' incs += ' ../makesdna ../readblenfile ../editors/include' -incs += ' ../python ../../kernel/gen_messaging' incs += ' ../render/extern/include' incs += ' ' + env['BF_ZLIB_INC'] @@ -15,4 +14,4 @@ if env['WITH_BF_VERSE']: defs += ' WITH_VERSE' incs += ' ' + env['BF_VERSE_INCLUDE'] -env.BlenderLib ( 'bf_blenloader', sources, Split(incs), Split(defs), libtype=['core','player'], priority = [85, 25] ) +env.BlenderLib ( 'bf_blenloader', sources, Split(incs), Split(defs), libtype=['core','player'], priority = [70, 30] ) diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index 24239b3e088..d5f5bb663ab 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -63,6 +63,8 @@ #include "BLO_readblenfile.h" +#include "BLO_sys_types.h" // needed for intptr_t + /** * IDType stuff, I plan to move this * out into its own file + prefix, and @@ -193,7 +195,7 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp) buf[2]= buf[2]?buf[2]:' '; buf[3]= buf[3]?buf[3]:' '; - fprintf(fp, "['%.4s', '%s', %d, %ld ], \n", buf, name, bhead->nr, (long)bhead->len+sizeof(BHead)); + fprintf(fp, "['%.4s', '%s', %d, %ld ], \n", buf, name, bhead->nr, (intptr_t)bhead->len+sizeof(BHead)); } } fprintf(fp, "]\n"); @@ -362,6 +364,9 @@ BlendFileData *BLO_read_from_memfile(const char *filename, MemFile *memfile, Ble if (fd) { strcpy(fd->filename, filename); + /* clear ob->proxy_from pointers in G.main */ + blo_clear_proxy_pointers_from_lib(fd); + /* separate libraries from G.main */ blo_split_main(&mainlist, G.main); /* add the library pointers in oldmap lookup */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 5c8583cd5ee..1ecd402bd56 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -34,6 +34,7 @@ #include "BLI_winstuff.h" #endif +#include <limits.h> #include <stdio.h> // for printf fopen fwrite fclose sprintf FILE #include <stdlib.h> // for getenv atoi #include <fcntl.h> // for open @@ -53,6 +54,7 @@ #include "DNA_actuator_types.h" #include "DNA_brush_types.h" #include "DNA_camera_types.h" +#include "DNA_cloth_types.h" #include "DNA_color_types.h" #include "DNA_controller_types.h" #include "DNA_constraint_types.h" @@ -62,6 +64,7 @@ #include "DNA_fileglobal_types.h" #include "DNA_genfile.h" #include "DNA_group_types.h" +#include "DNA_gpencil_types.h" #include "DNA_ipo_types.h" #include "DNA_image_types.h" #include "DNA_key_types.h" @@ -104,13 +107,14 @@ #include "BKE_action.h" #include "BKE_armature.h" +#include "BKE_cloth.h" #include "BKE_colortools.h" #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_depsgraph.h" -#include "BKE_effect.h" // for give_parteff +#include "BKE_effect.h" /* give_parteff */ #include "BKE_global.h" // for G #include "BKE_group.h" #include "BKE_image.h" @@ -123,10 +127,13 @@ #include "BKE_node.h" // for tree type defines #include "BKE_object.h" #include "BKE_particle.h" -#include "BKE_property.h" // for get_property +#include "BKE_pointcache.h" +#include "BKE_property.h" // for get_ob_property #include "BKE_sca.h" // for init_actuator #include "BKE_scene.h" #include "BKE_softbody.h" // sbNew() +#include "BKE_bullet.h" // bsbNew() +#include "BKE_sculpt.h" #include "BKE_texture.h" // for open_plugin_tex #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND #include "BKE_idprop.h" @@ -704,7 +711,7 @@ BHead *blo_firstbhead(FileData *fd) BHead *blo_prevbhead(FileData *fd, BHead *thisblock) { - BHeadN *bheadn= (BHeadN *) (((char *) thisblock) - (int) (&((BHeadN*)0)->bhead)); + BHeadN *bheadn= (BHeadN *) (((char *) thisblock) - GET_INT_FROM_POINTER( &((BHeadN*)0)->bhead) ); BHeadN *prev= bheadn->prev; return prev?&prev->bhead:NULL; @@ -712,13 +719,13 @@ BHead *blo_prevbhead(FileData *fd, BHead *thisblock) BHead *blo_nextbhead(FileData *fd, BHead *thisblock) { - BHeadN *new_bhead = 0; - BHead *bhead = 0; + BHeadN *new_bhead = NULL; + BHead *bhead = NULL; if (thisblock) { // bhead is actually a sub part of BHeadN // We calculate the BHeadN pointer from the BHead pointer below - new_bhead = (BHeadN *) (((char *) thisblock) - (int) (&((BHeadN*)0)->bhead)); + new_bhead = (BHeadN *) (((char *) thisblock) - GET_INT_FROM_POINTER( &((BHeadN*)0)->bhead) ); // get the next BHeadN. If it doesn't exist we read in the next one new_bhead = new_bhead->next; @@ -843,6 +850,7 @@ static int fd_read_from_memfile(FileData *filedata, void *buffer, int size) static unsigned int seek= 1<<30; /* the current position */ static unsigned int offset= 0; /* size of previous chunks */ static MemFileChunk *chunk=NULL; + unsigned int chunkoffset, readsize, totread; if(size==0) return 0; @@ -860,29 +868,39 @@ static int fd_read_from_memfile(FileData *filedata, void *buffer, int size) } if(chunk) { - /* first check if it's on the end if current chunk */ - if( seek-offset == chunk->size) { - offset+= chunk->size; - chunk= chunk->next; - } - - /* debug, should never happen */ - if(chunk==NULL) { - printf("illegal read, chunk zero\n"); - return 0; - } - else if( (seek-offset)+size > chunk->size) { - size= chunk->size - (seek-offset); - printf("chunk too large, clipped to %d\n", size); - } - - memcpy(buffer, chunk->buf + (seek-offset), size); - filedata->seek += size; - seek+= size; - - return (size); + totread= 0; + + do { + /* first check if it's on the end if current chunk */ + if(seek-offset == chunk->size) { + offset+= chunk->size; + chunk= chunk->next; + } + + /* debug, should never happen */ + if(chunk==NULL) { + printf("illegal read, chunk zero\n"); + return 0; + } + + chunkoffset= seek-offset; + readsize= size-totread; + + /* data can be spread over multiple chunks, so clamp size + * to within this chunk, and then it will read further in + * the next chunk */ + if(chunkoffset+readsize > chunk->size) + readsize= chunk->size-chunkoffset; + + memcpy((char*)buffer+totread, chunk->buf+chunkoffset, readsize); + totread += readsize; + filedata->seek += readsize; + seek += readsize; + } while(totread < size); + return totread; } + return 0; } @@ -940,9 +958,11 @@ FileData *blo_openblenderfile(char *name, BlendReadError *error_r) } else { FileData *fd = filedata_new(); fd->gzfiledes = gzfile; - BLI_strncpy(fd->filename, name, sizeof(fd->filename)); // now only in use by library append fd->read = fd_read_gzip_from_file; + /* needed for library_append and read_libraries */ + BLI_strncpy(fd->filename, name, sizeof(fd->filename)); + return blo_decode_and_check(fd, error_r); } } @@ -1016,7 +1036,9 @@ void blo_freefiledata(FileData *fd) oldnewmap_free(fd->imamap); if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP)) oldnewmap_free(fd->libmap); - + if (fd->bheadmap) + MEM_freeN(fd->bheadmap); + MEM_freeN(fd); } } @@ -1094,6 +1116,19 @@ static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, voi } } +/* lib linked proxy objects point to our local data, we need + * to clear that pointer before reading the undo memfile since + * the object might be removed, it is set again in reading + * if the local object still exists */ +void blo_clear_proxy_pointers_from_lib(FileData *fd) +{ + Object *ob= G.main->object.first; + + for(;ob; ob= ob->id.next) + if(ob->id.lib) + ob->proxy_from= NULL; +} + /* assumed; G.main still exists */ void blo_make_image_pointer_map(FileData *fd) { @@ -1106,6 +1141,8 @@ void blo_make_image_pointer_map(FileData *fd) Link *ibuf= ima->ibufs.first; for(; ibuf; ibuf= ibuf->next) oldnewmap_insert(fd->imamap, ibuf, ibuf, 0); + if(ima->gputexture) + oldnewmap_insert(fd->imamap, ima->gputexture, ima->gputexture, 0); } for(; sce; sce= sce->id.next) { if(sce->nodetree) { @@ -1140,8 +1177,11 @@ void blo_end_image_pointer_map(FileData *fd) if(NULL==newimaadr(fd, ibuf)) { /* so was restored */ BLI_remlink(&ima->ibufs, ibuf); ima->bindcode= 0; + ima->gputexture= NULL; } } + + ima->gputexture= newimaadr(fd, ima->gputexture); } for(; sce; sce= sce->id.next) { if(sce->nodetree) { @@ -1306,7 +1346,7 @@ static void test_pointer_array(FileData *fd, void **mat) void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd); void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, void *fd); -void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, void *fd) +static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, void *fd) { int i; @@ -1315,20 +1355,26 @@ void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, void *fd) prop->data.pointer = newdataadr(fd, prop->data.pointer); if (switch_endian) { - for (i=0; i<prop->len; i++) { - SWITCH_INT(((int*)prop->data.pointer)[i]); + if (prop->subtype != IDP_DOUBLE) { + for (i=0; i<prop->len; i++) { + SWITCH_INT(((int*)prop->data.pointer)[i]); + } + } else { + for (i=0; i<prop->len; i++) { + SWITCH_LONGINT(((double*)prop->data.pointer)[i]); + } } } } -void IDP_DirectLinkString(IDProperty *prop, int switch_endian, void *fd) +static void IDP_DirectLinkString(IDProperty *prop, int switch_endian, void *fd) { /*since we didn't save the extra string buffer, set totallen to len.*/ prop->totallen = prop->len; prop->data.pointer = newdataadr(fd, prop->data.pointer); } -void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, void *fd) +static void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, void *fd) { ListBase *lb = &prop->data.group; IDProperty *loop; @@ -1353,6 +1399,24 @@ void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd) case IDP_ARRAY: IDP_DirectLinkArray(prop, switch_endian, fd); break; + case IDP_DOUBLE: + /*erg, stupid doubles. since I'm storing them + in the same field as int val; val2 in the + IDPropertyData struct, they have to deal with + endianness specifically + + in theory, val and val2 would've already been swapped + if switch_endian is true, so we have to first unswap + them then reswap them as a single 64-bit entity. + */ + + if (switch_endian) { + SWITCH_INT(prop->data.val); + SWITCH_INT(prop->data.val2); + SWITCH_LONGINT(prop->data.val); + } + + break; } } @@ -1392,6 +1456,12 @@ static void direct_link_brush(FileData *fd, Brush *brush) brush->mtex[a]= newdataadr(fd, brush->mtex[a]); } +static void direct_link_script(FileData *fd, Script *script) +{ + script->id.us = 1; + SCRIPT_SET_NULL(script) +} + /* ************ READ CurveMapping *************** */ /* cuma itself has been read! */ @@ -1434,11 +1504,18 @@ static void lib_link_nodetree(FileData *fd, Main *main) } /* verify types for nodes and groups, all data has to be read */ -static void lib_verify_nodetree(Main *main) +/* open = 0: appending/linking, open = 1: open new file (need to clean out dynamic + * typedefs*/ +static void lib_verify_nodetree(Main *main, int open) { Scene *sce; Material *ma; bNodeTree *ntree; + + /* this crashes blender on undo/redo + if(open==1) { + reinit_nodesystem(); + }*/ /* now create the own typeinfo structs an verify nodes */ /* here we still assume no groups in groups */ @@ -1475,6 +1552,12 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) link_list(fd, &ntree->nodes); for(node= ntree->nodes.first; node; node= node->next) { + if(node->type == NODE_DYNAMIC) { + node->custom1= 0; + node->custom1= BSET(node->custom1, NODE_DYNAMIC_LOADED); + node->typeinfo= NULL; + } + node->storage= newdataadr(fd, node->storage); if(node->storage) { @@ -1509,6 +1592,22 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) link->tosock= newdataadr(fd, link->tosock); } + /* set selin and selout */ + for(node= ntree->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->flag & SOCK_SEL) { + ntree->selin= sock; + break; + } + } + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->flag & SOCK_SEL) { + ntree->selout= sock; + break; + } + } + } + /* type verification is in lib-link */ } @@ -1721,6 +1820,13 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist) data->tar = newlibadr(fd, id->lib, data->tar); } break; + case CONSTRAINT_TYPE_DISTLIMIT: + { + bDistLimitConstraint *data; + data= ((bDistLimitConstraint*)con->data); + data->tar = newlibadr(fd, id->lib, data->tar); + } + break; case CONSTRAINT_TYPE_NULL: break; } @@ -1734,6 +1840,7 @@ static void direct_link_constraints(FileData *fd, ListBase *lb) link_list(fd, lb); for (cons=lb->first; cons; cons=cons->next) { cons->data = newdataadr(fd, cons->data); + if (cons->type == CONSTRAINT_TYPE_PYTHON) { bPythonConstraint *data= cons->data; link_list(fd, &data->targets); @@ -1800,12 +1907,12 @@ static void lib_link_action(FileData *fd, Main *main) while(act) { if(act->id.flag & LIB_NEEDLINK) { act->id.flag -= LIB_NEEDLINK; - + for (chan=act->chanbase.first; chan; chan=chan->next) { chan->ipo= newlibadr_us(fd, act->id.lib, chan->ipo); lib_link_constraint_channels(fd, &act->id, &chan->constraintChannels); } - + } act= act->id.next; } @@ -1828,12 +1935,24 @@ static void direct_link_bones(FileData *fd, Bone* bone) static void direct_link_action(FileData *fd, bAction *act) { bActionChannel *achan; + bActionGroup *agrp; link_list(fd, &act->chanbase); + link_list(fd, &act->groups); + link_list(fd, &act->markers); - for (achan = act->chanbase.first; achan; achan=achan->next) + for (achan = act->chanbase.first; achan; achan=achan->next) { + achan->grp= newdataadr(fd, achan->grp); + link_list(fd, &achan->constraintChannels); - + } + + for (agrp = act->groups.first; agrp; agrp= agrp->next) { + if (agrp->channels.first) { + agrp->channels.first= newdataadr(fd, agrp->channels.first); + agrp->channels.last= newdataadr(fd, agrp->channels.last); + } + } } static void direct_link_armature(FileData *fd, bArmature *arm) @@ -2162,6 +2281,7 @@ static void direct_link_text(FileData *fd, Text *text) */ link_list(fd, &text->lines); + link_list(fd, &text->markers); text->curl= newdataadr(fd, text->curl); text->sell= newdataadr(fd, text->sell); @@ -2228,8 +2348,10 @@ static void direct_link_image(FileData *fd, Image *ima) ima->ibufs.first= ima->ibufs.last= NULL; /* if not restored, we keep the binded opengl index */ - if(ima->ibufs.first==NULL) + if(ima->ibufs.first==NULL) { ima->bindcode= 0; + ima->gputexture= NULL; + } ima->anim= NULL; ima->rr= NULL; @@ -2440,10 +2562,17 @@ static void direct_link_material(FileData *fd, Material *ma) direct_link_nodetree(fd, ma->nodetree); ma->preview = direct_link_preview_image(fd, ma->preview); + ma->gpumaterial.first = ma->gpumaterial.last = NULL; } /* ************ READ PARTICLE SETTINGS ***************** */ +static void direct_link_pointcache(FileData *fd, PointCache *cache) +{ + cache->flag &= ~(PTCACHE_SIMULATION_VALID|PTCACHE_BAKE_EDIT_ACTIVE); + cache->simframe= 0; +} + static void lib_link_particlesettings(FileData *fd, Main *main) { ParticleSettings *part; @@ -2465,21 +2594,36 @@ static void lib_link_particlesettings(FileData *fd, Main *main) static void direct_link_particlesettings(FileData *fd, ParticleSettings *part) { part->pd= newdataadr(fd, part->pd); + part->pd2= newdataadr(fd, part->pd2); } -static void lib_link_particlesystems(FileData *fd, ID *id, ListBase *particles) +static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles) { - ParticleSystem *psys; + ParticleSystem *psys, *psysnext; int a; - for(psys=particles->first; psys; psys=psys->next){ + for(psys=particles->first; psys; psys=psysnext){ ParticleData *pa; + + psysnext= psys->next; + psys->part = newlibadr_us(fd, id->lib, psys->part); - psys->target_ob = newlibadr(fd, id->lib, psys->target_ob); - psys->keyed_ob = newlibadr(fd, id->lib, psys->keyed_ob); + if(psys->part) { + psys->target_ob = newlibadr(fd, id->lib, psys->target_ob); + psys->keyed_ob = newlibadr(fd, id->lib, psys->keyed_ob); + + for(a=0,pa=psys->particles; a<psys->totpart; a++,pa++){ + pa->stick_ob=newlibadr(fd, id->lib, pa->stick_ob); + } + } + else { + /* particle modifier must be removed before particle system */ + ParticleSystemModifierData *psmd= psys_get_modifier(ob,psys); + BLI_remlink(&ob->modifiers, psmd); + modifier_free((ModifierData *)psmd); - for(a=0,pa=psys->particles; a<psys->totpart; a++,pa++){ - pa->stick_ob=newlibadr(fd, id->lib, pa->stick_ob); + BLI_remlink(particles, psys); + MEM_freeN(psys); } } } @@ -2495,6 +2639,15 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) for(a=0; a<psys->totpart; a++, pa++) pa->hair=newdataadr(fd,pa->hair); } + if(psys->particles && psys->particles->keys){ + ParticleData *pa = psys->particles; + for(a=0; a<psys->totpart; a++, pa++) { + pa->keys= NULL; + pa->totkey= 0; + } + + psys->flag &= ~PSYS_KEYED; + } psys->child=newdataadr(fd,psys->child); psys->effectors.first=psys->effectors.last=0; @@ -2505,12 +2658,22 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) sb->bpoint= NULL; // init pointers so it gets rebuilt nicely sb->bspring= NULL; sb->scratch= NULL; + + sb->pointcache= newdataadr(fd, sb->pointcache); + if(sb->pointcache) + direct_link_pointcache(fd, sb->pointcache); } psys->edit = 0; psys->pathcache = 0; psys->childcache = 0; + psys->pathcachebufs.first = psys->pathcachebufs.last = 0; + psys->childcachebufs.first = psys->childcachebufs.last = 0; psys->reactevents.first = psys->reactevents.last = 0; + + psys->pointcache= newdataadr(fd, psys->pointcache); + if(psys->pointcache) + direct_link_pointcache(fd, psys->pointcache); } return; } @@ -2753,6 +2916,7 @@ static void lib_link_object(FileData *fd, Main *main) ob->track= newlibadr(fd, ob->id.lib, ob->track); ob->ipo= newlibadr_us(fd, ob->id.lib, ob->ipo); ob->action = newlibadr_us(fd, ob->id.lib, ob->action); + ob->poselib= newlibadr_us(fd, ob->id.lib, ob->poselib); ob->dup_group= newlibadr_us(fd, ob->id.lib, ob->dup_group); ob->proxy= newlibadr_us(fd, ob->id.lib, ob->proxy); @@ -2781,8 +2945,7 @@ static void lib_link_object(FileData *fd, Main *main) else printf("Object %s lost data.", ob->id.name+2); if(ob->pose) { - free_pose_channels(ob->pose); - MEM_freeN(ob->pose); + free_pose(ob->pose); ob->pose= NULL; ob->flag &= ~OB_POSEMODE; } @@ -2806,11 +2969,9 @@ static void lib_link_object(FileData *fd, Main *main) sens= ob->sensors.first; while(sens) { - if(ob->id.lib==NULL) { // done in expand_main - for(a=0; a<sens->totlinks; a++) { - sens->links[a]= newglobadr(fd, sens->links[a]); - } - } + for(a=0; a<sens->totlinks; a++) + sens->links[a]= newglobadr(fd, sens->links[a]); + if(sens->type==SENS_TOUCH) { bTouchSensor *ts= sens->data; ts->ma= newlibadr(fd, ob->id.lib, ts->ma); @@ -2825,11 +2986,9 @@ static void lib_link_object(FileData *fd, Main *main) cont= ob->controllers.first; while(cont) { - if(ob->id.lib==NULL) { // done in expand_main - for(a=0; a<cont->totlinks; a++) { - cont->links[a]= newglobadr(fd, cont->links[a]); - } - } + for(a=0; a<cont->totlinks; a++) + cont->links[a]= newglobadr(fd, cont->links[a]); + if(cont->type==CONT_PYTHON) { bPythonCont *pc= cont->data; pc->text= newlibadr(fd, ob->id.lib, pc->text); @@ -2880,6 +3039,10 @@ static void lib_link_object(FileData *fd, Main *main) bActionActuator *aa= act->data; aa->act= newlibadr(fd, ob->id.lib, aa->act); } + else if(act->type==ACT_SHAPEACTION) { + bActionActuator *aa= act->data; + aa->act= newlibadr(fd, ob->id.lib, aa->act); + } else if(act->type==ACT_PROPERTY) { bPropertyActuator *pa= act->data; pa->ob= newlibadr(fd, ob->id.lib, pa->ob); @@ -2888,11 +3051,25 @@ static void lib_link_object(FileData *fd, Main *main) bMessageActuator *ma= act->data; ma->toObject= newlibadr(fd, ob->id.lib, ma->toObject); } + else if(act->type==ACT_2DFILTER){ + bTwoDFilterActuator *_2dfa = act->data; + _2dfa->text= newlibadr(fd, ob->id.lib, _2dfa->text); + } + else if(act->type==ACT_PARENT) { + bParentActuator *parenta = act->data; + parenta->ob = newlibadr(fd, ob->id.lib, parenta->ob); + } + else if(act->type==ACT_STATE) { + /* bStateActuator *statea = act->data; */ + } act= act->next; } - - if(ob->fluidsimSettings) { - ob->fluidsimSettings->ipo = newlibadr_us(fd, ob->id.lib, ob->fluidsimSettings->ipo); + + { + FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); + + if(fluidmd && fluidmd->fss) + fluidmd->fss->ipo = newlibadr_us(fd, ob->id.lib, fluidmd->fss->ipo); } /* texture field */ @@ -2901,7 +3078,7 @@ static void lib_link_object(FileData *fd, Main *main) ob->pd->tex=newlibadr_us(fd, ob->id.lib, ob->pd->tex); lib_link_scriptlink(fd, &ob->id, &ob->scriptlink); - lib_link_particlesystems(fd, &ob->id, &ob->particlesystem); + lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem); lib_link_modifiers(fd, ob); } ob= ob->id.next; @@ -2911,14 +3088,15 @@ static void lib_link_object(FileData *fd, Main *main) } -static void direct_link_pose(FileData *fd, bPose *pose) { - +static void direct_link_pose(FileData *fd, bPose *pose) +{ bPoseChannel *pchan; if (!pose) return; link_list(fd, &pose->chanbase); + link_list(fd, &pose->agroups); for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) { pchan->bone= NULL; @@ -2928,7 +3106,6 @@ static void direct_link_pose(FileData *fd, bPose *pose) { pchan->iktree.first= pchan->iktree.last= NULL; pchan->path= NULL; } - } static void direct_link_modifiers(FileData *fd, ListBase *lb) @@ -2948,7 +3125,57 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) SubsurfModifierData *smd = (SubsurfModifierData*) md; smd->emCache = smd->mCache = 0; - } else if (md->type==eModifierType_Hook) { + } + else if (md->type==eModifierType_Cloth) { + ClothModifierData *clmd = (ClothModifierData*) md; + + clmd->clothObject = NULL; + + clmd->sim_parms= newdataadr(fd, clmd->sim_parms); + clmd->coll_parms= newdataadr(fd, clmd->coll_parms); + clmd->point_cache= newdataadr(fd, clmd->point_cache); + + if(clmd->point_cache) + direct_link_pointcache(fd, clmd->point_cache); + + if(clmd->sim_parms) { + if(clmd->sim_parms->presets > 10) + clmd->sim_parms->presets = 0; + } + + } + else if (md->type==eModifierType_Fluidsim) { + FluidsimModifierData *fluidmd = (FluidsimModifierData*) md; + + fluidmd->fss= newdataadr(fd, fluidmd->fss); + } + else if (md->type==eModifierType_Collision) { + + CollisionModifierData *collmd = (CollisionModifierData*) md; + /* + // TODO: CollisionModifier should use pointcache + // + have proper reset events before enabling this + collmd->x = newdataadr(fd, collmd->x); + collmd->xnew = newdataadr(fd, collmd->xnew); + collmd->mfaces = newdataadr(fd, collmd->mfaces); + + collmd->current_x = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_x"); + collmd->current_xnew = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_xnew"); + collmd->current_v = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_v"); + */ + + collmd->x = NULL; + collmd->xnew = NULL; + collmd->current_x = NULL; + collmd->current_xnew = NULL; + collmd->current_v = NULL; + collmd->time = -1; + collmd->numverts = 0; + collmd->bvhtree = NULL; + collmd->mfaces = NULL; + + } + else if (md->type==eModifierType_Hook) { HookModifierData *hmd = (HookModifierData*) md; hmd->indexar= newdataadr(fd, hmd->indexar); @@ -3093,7 +3320,6 @@ static void direct_link_object(FileData *fd, Object *ob) sb->bpoint= NULL; // init pointers so it gets rebuilt nicely sb->bspring= NULL; sb->scratch= NULL; - /* although not used anymore */ /* still have to be loaded to be compatible with old files */ sb->keys= newdataadr(fd, sb->keys); @@ -3103,15 +3329,13 @@ static void direct_link_object(FileData *fd, Object *ob) sb->keys[a]= newdataadr(fd, sb->keys[a]); } } + + sb->pointcache= newdataadr(fd, sb->pointcache); + if(sb->pointcache) + direct_link_pointcache(fd, sb->pointcache); } + ob->bsoft= newdataadr(fd, ob->bsoft); ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */ - if(ob->fluidsimSettings) { - // reinit mesh pointers - ob->fluidsimSettings->orgMesh = NULL; //ob->data; - ob->fluidsimSettings->meshSurface = NULL; - ob->fluidsimSettings->meshBB = NULL; - ob->fluidsimSettings->meshSurfNormals = NULL; - } link_list(fd, &ob->particlesystem); direct_link_particlesystems(fd,&ob->particlesystem); @@ -3136,11 +3360,19 @@ static void direct_link_object(FileData *fd, Object *ob) direct_link_constraints(fd, &ob->constraints); link_glob_list(fd, &ob->controllers); + if (ob->init_state) { + /* if a known first state is specified, set it so that the game will start ok */ + ob->state = ob->init_state; + } else if (!ob->state) { + ob->state = 1; + } cont= ob->controllers.first; while(cont) { cont->data= newdataadr(fd, cont->data); cont->links= newdataadr(fd, cont->links); test_pointer_array(fd, (void **)&cont->links); + if (cont->state_mask == 0) + cont->state_mask = 1; cont= cont->next; } @@ -3185,6 +3417,7 @@ static void direct_link_object(FileData *fd, Object *ob) ob->bb= NULL; ob->derivedDeform= NULL; ob->derivedFinal= NULL; + ob->gpulamp.first= ob->gpulamp.last= NULL; } /* ************ READ SCENE ***************** */ @@ -3340,6 +3573,10 @@ static void direct_link_scene(FileData *fd, Scene *sce) if(seq->strip && seq->strip->done==0) { seq->strip->done= 1; seq->strip->tstripdata = 0; + seq->strip->tstripdata_startstill = 0; + seq->strip->tstripdata_endstill = 0; + seq->strip->ibuf_startstill = 0; + seq->strip->ibuf_endstill = 0; if(seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE || @@ -3350,6 +3587,30 @@ static void direct_link_scene(FileData *fd, Scene *sce) } else { seq->strip->stripdata = 0; } + if (seq->flag & SEQ_USE_CROP) { + seq->strip->crop = newdataadr( + fd, seq->strip->crop); + } else { + seq->strip->crop = 0; + } + if (seq->flag & SEQ_USE_TRANSFORM) { + seq->strip->transform = newdataadr( + fd, seq->strip->transform); + } else { + seq->strip->transform = 0; + } + if (seq->flag & SEQ_USE_PROXY) { + seq->strip->proxy = newdataadr( + fd, seq->strip->proxy); + } else { + seq->strip->proxy = 0; + } + if (seq->flag & SEQ_USE_COLOR_BALANCE) { + seq->strip->color_balance = newdataadr( + fd, seq->strip->color_balance); + } else { + seq->strip->color_balance = 0; + } } } END_SEQ @@ -3358,9 +3619,9 @@ static void direct_link_scene(FileData *fd, Scene *sce) { Sequence temp; char *poin; - long offset; + intptr_t offset; - offset= ((long)&(temp.seqbase)) - ((long)&temp); + offset= ((intptr_t)&(temp.seqbase)) - ((intptr_t)&temp); /* root pointer */ if(ed->seqbasep == old_seqbasep) { @@ -3406,8 +3667,18 @@ static void direct_link_scene(FileData *fd, Scene *sce) if (sce->r.qtcodecdata) { sce->r.qtcodecdata->cdParms = newdataadr(fd, sce->r.qtcodecdata->cdParms); } - + if (sce->r.ffcodecdata.properties) { + sce->r.ffcodecdata.properties = newdataadr( + fd, sce->r.ffcodecdata.properties); + if (sce->r.ffcodecdata.properties) { + IDP_DirectLinkProperty( + sce->r.ffcodecdata.properties, + (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + } + } + link_list(fd, &(sce->markers)); + link_list(fd, &(sce->transform_spaces)); link_list(fd, &(sce->r.layers)); sce->nodetree= newdataadr(fd, sce->nodetree); @@ -3521,6 +3792,32 @@ static void lib_link_windowmanager(FileData *fd, Main *main) /* ************ READ SCREEN ***************** */ +/* relinks grease-pencil data for 3d-view(s) - used for direct_link */ +static void link_gpencil(FileData *fd, bGPdata *gpd) +{ + bGPDlayer *gpl; + bGPDframe *gpf; + bGPDstroke *gps; + + /* relink layers */ + link_list(fd, &gpd->layers); + + for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { + /* relink frames */ + link_list(fd, &gpl->frames); + gpl->actframe= newdataadr(fd, gpl->actframe); + + for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { + /* relink strokes (and their points) */ + link_list(fd, &gpf->strokes); + + for (gps= gpf->strokes.first; gps; gps= gps->next) { + gps->points= newdataadr(fd, gps->points); + } + } + } +} + /* note: file read without screens option G_FILE_NO_UI; check lib pointers in call below */ static void lib_link_screen(FileData *fd, Main *main) @@ -3532,23 +3829,23 @@ static void lib_link_screen(FileData *fd, Main *main) if(sc->id.flag & LIB_NEEDLINK) { sc->id.us= 1; sc->scene= newlibadr(fd, sc->id.lib, sc->scene); - + sa= sc->areabase.first; while(sa) { SpaceLink *sl; - + sa->full= newlibadr(fd, sc->id.lib, sa->full); - + /* space handler scriptlinks */ lib_link_scriptlink(fd, &sc->id, &sa->scriptlink); - + for (sl= sa->spacedata.first; sl; sl= sl->next) { if(sl->spacetype==SPACE_VIEW3D) { View3D *v3d= (View3D*) sl; - + v3d->camera= newlibadr(fd, sc->id.lib, v3d->camera); v3d->ob_centre= newlibadr(fd, sc->id.lib, v3d->ob_centre); - + if(v3d->bgpic) { v3d->bgpic->ima= newlibadr_us(fd, sc->id.lib, v3d->bgpic->ima); } @@ -3611,9 +3908,15 @@ static void lib_link_screen(FileData *fd, Main *main) } else if(sl->spacetype==SPACE_SCRIPT) { - SpaceScript *sc= (SpaceScript *)sl; - sc->script = NULL; + SpaceScript *scpt= (SpaceScript *)sl; + /*scpt->script = NULL; - 2.45 set to null, better re-run the script */ + if (scpt->script) { + scpt->script= newlibadr(fd, sc->id.lib, scpt->script); + if (scpt->script) { + SCRIPT_SET_NULL(scpt->script) + } + } } else if(sl->spacetype==SPACE_OOPS) { SpaceOops *so= (SpaceOops *)sl; @@ -3686,7 +3989,9 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene) for(sc= newmain->screen.first; sc; sc= sc->id.next) { - sc->scene= curscene; + sc->scene= restore_pointer_by_name(newmain, (ID *)sc->scene, 1); + if(sc->scene==NULL) + sc->scene= curscene; sa= sc->areabase.first; while(sa) { @@ -3784,9 +4089,14 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene) if(st->text==NULL) st->text= newmain->text.first; } else if(sl->spacetype==SPACE_SCRIPT) { - SpaceScript *sc= (SpaceScript *)sl; - - sc->script = NULL; + SpaceScript *scpt= (SpaceScript *)sl; + + scpt->script= restore_pointer_by_name(newmain, (ID *)scpt->script, 1); + + /*sc->script = NULL; - 2.45 set to null, better re-run the script */ + if (scpt->script) { + SCRIPT_SET_NULL(scpt->script) + } } else if(sl->spacetype==SPACE_OOPS) { SpaceOops *so= (SpaceOops *)sl; @@ -3854,7 +4164,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) for(se= sc->edgebase.first; se; se= se->next) { se->v1= newdataadr(fd, se->v1); se->v2= newdataadr(fd, se->v2); - if( (long)se->v1 > (long)se->v2) { + if( (intptr_t)se->v1 > (intptr_t)se->v2) { sv= se->v1; se->v1= se->v2; se->v2= sv; @@ -3897,6 +4207,10 @@ static void direct_link_screen(FileData *fd, bScreen *sc) v3d->bgpic= newdataadr(fd, v3d->bgpic); if(v3d->bgpic) v3d->bgpic->iuser.ok= 1; + if(v3d->gpd) { + v3d->gpd= newdataadr(fd, v3d->gpd); + link_gpencil(fd, v3d->gpd); + } v3d->localvd= newdataadr(fd, v3d->localvd); v3d->afterdraw.first= v3d->afterdraw.last= NULL; v3d->clipbb= newdataadr(fd, v3d->clipbb); @@ -3927,15 +4241,28 @@ static void direct_link_screen(FileData *fd, bScreen *sc) sima->cumap= newdataadr(fd, sima->cumap); if(sima->cumap) direct_link_curvemapping(fd, sima->cumap); - sima->info_str= sima->info_spare= NULL; - sima->spare= NULL; + sima->gpd= newdataadr(fd, sima->gpd); + if (sima->gpd) + link_gpencil(fd, sima->gpd); sima->iuser.ok= 1; } else if(sl->spacetype==SPACE_NODE) { SpaceNode *snode= (SpaceNode *)sl; + + if(snode->gpd) { + snode->gpd= newdataadr(fd, snode->gpd); + link_gpencil(fd, snode->gpd); + } snode->nodetree= snode->edittree= NULL; snode->flag |= SNODE_DO_PREVIEW; } + else if(sl->spacetype==SPACE_SEQ) { + SpaceSeq *sseq= (SpaceSeq *)sl; + if(sseq->gpd) { + sseq->gpd= newdataadr(fd, sseq->gpd); + link_gpencil(fd, sseq->gpd); + } + } } for(ar= sa->regionbase.first; ar; ar= ar->next) { @@ -4000,11 +4327,26 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) static void lib_link_library(FileData *fd, Main *main) { Library *lib; - - lib= main->library.first; - while(lib) { + for(lib= main->library.first; lib; lib= lib->id.next) { lib->id.us= 1; - lib= lib->id.next; + } +} + +/* Always call this once you havbe loaded new library data to set the relative paths correctly in relation to the blend file */ +static void fix_relpaths_library(const char *basepath, Main *main) +{ + Library *lib; + /* BLO_read_from_memory uses a blank filename */ + if (basepath==NULL || basepath[0] == '\0') + return; + + for(lib= main->library.first; lib; lib= lib->id.next) { + /* Libraries store both relative and abs paths, recreate relative paths, + * relative to the blend file since indirectly linked libs will be relative to their direct linked library */ + if (strncmp(lib->name, "//", 2)==0) { /* if this is relative to begin with? */ + strncpy(lib->name, lib->filename, sizeof(lib->name)); + BLI_makestringcode(basepath, lib->name); + } } } @@ -4245,12 +4587,17 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID case ID_PA: direct_link_particlesettings(fd, (ParticleSettings*)id); break; + case ID_SCRIPT: + direct_link_script(fd, (Script*)id); + break; } /*link direct data of ID properties*/ if (id->properties) { id->properties = newdataadr(fd, id->properties); - IDP_DirectLinkProperty(id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + if (id->properties) { /* this case means the data was written incorrectly, it should not happen */ + IDP_DirectLinkProperty(id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + } } oldnewmap_free_unused(fd->datamap); @@ -4566,6 +4913,118 @@ static void do_version_ntree_242_2(bNodeTree *ntree) } } +static void ntree_version_245(FileData *fd, Library *lib, bNodeTree *ntree) +{ + bNode *node; + NodeTwoFloats *ntf; + ID *nodeid; + Image *image; + ImageUser *iuser; + + if(ntree->type==NTREE_COMPOSIT) { + for(node= ntree->nodes.first; node; node= node->next) { + if(node->type == CMP_NODE_ALPHAOVER) { + if(!node->storage) { + ntf= MEM_callocN(sizeof(NodeTwoFloats), "NodeTwoFloats"); + node->storage= ntf; + if(node->custom1) + ntf->x= 1.0f; + } + } + + /* fix for temporary flag changes during 245 cycle */ + nodeid= newlibadr(fd, lib, node->id); + if(node->storage && nodeid && GS(nodeid->name) == ID_IM) { + image= (Image*)nodeid; + iuser= node->storage; + if(iuser->flag & IMA_OLD_PREMUL) { + iuser->flag &= ~IMA_OLD_PREMUL; + iuser->flag |= IMA_DO_PREMUL; + } + if(iuser->flag & IMA_DO_PREMUL) { + image->flag &= ~IMA_OLD_PREMUL; + image->flag |= IMA_DO_PREMUL; + } + } + } + } +} + +static void idproperties_fix_groups_lengths_recurse(IDProperty *prop) +{ + IDProperty *loop; + int i; + + for (loop=prop->data.group.first, i=0; loop; loop=loop->next, i++) { + if (loop->type == IDP_GROUP) idproperties_fix_groups_lengths_recurse(loop); + } + + if (prop->len != i) { + printf("Found and fixed bad id property group length.\n"); + prop->len = i; + } +} + +static void idproperties_fix_group_lengths(ListBase idlist) +{ + ID *id; + + for (id=idlist.first; id; id=id->next) { + if (id->properties) { + idproperties_fix_groups_lengths_recurse(id->properties); + } + } +} + +static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me) +{ + Material *ma; + MFace *mf; + MTFace *tf; + int a, b, texalpha; + + /* verify we have a tface layer */ + for(b=0; b<me->fdata.totlayer; b++) + if(me->fdata.layers[b].type == CD_MTFACE) + break; + + if(b == me->fdata.totlayer) + return; + + /* if we do, set alpha sort if the game engine did it before */ + for(a=0, mf=me->mface; a<me->totface; a++, mf++) { + if(mf->mat_nr < me->totcol) { + ma= newlibadr(fd, lib, me->mat[mf->mat_nr]); + texalpha = 0; + + /* we can't read from this if it comes from a library, + * because direct_link might not have happened on it, + * so ma->mtex is not pointing to valid memory yet */ + if(ma && ma->id.lib) + ma= NULL; + + for(b=0; ma && b<MAX_MTEX; b++) + if(ma->mtex && ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA) + texalpha = 1; + } + else { + ma= NULL; + texalpha = 0; + } + + for(b=0; b<me->fdata.totlayer; b++) { + if(me->fdata.layers[b].type == CD_MTFACE) { + tf = ((MTFace*)me->fdata.layers[b].data) + a; + + tf->mode &= ~TF_ALPHASORT; + if(ma && (ma->mode & MA_ZTRA)) + if(ELEM(tf->transp, TF_ALPHA, TF_ADD) || (texalpha && (tf->transp != TF_CLIP))) + tf->mode |= TF_ALPHASORT; + } + } + } +} + static void do_versions_windowmanager_2_50(bScreen *screen) { struct ScrArea *sa; @@ -4908,7 +5367,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) while(ob) { ob->mass= 1.0f; ob->damping= 0.1f; - ob->quat[1]= 1.0f; + /*ob->quat[1]= 1.0f;*/ /* quats arnt used yet */ ob= ob->id.next; } @@ -4978,7 +5437,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) while (act) { if(act->type==ACT_IPO) { ia= act->data; - prop= get_property(ob, ia->name); + prop= get_ob_property(ob, ia->name); if(prop) { ia->type= ACT_IPO_FROM_PROP; } @@ -6282,7 +6741,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) sce->toolsettings->uvcalc_cubesize = 1.0f; sce->toolsettings->uvcalc_mapdir = 1; sce->toolsettings->uvcalc_mapalign = 1; - sce->toolsettings->uvcalc_flag = 1; + sce->toolsettings->uvcalc_flag = UVCALC_FILLHOLES; sce->toolsettings->unwrapper = 1; } @@ -6746,7 +7205,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main) Lamp *la; Material *ma; ParticleSettings *part; + World *wrld; Mesh *me; + bNodeTree *ntree; + Tex *tex; + ModifierData *md; + ParticleSystem *psys; /* unless the file was created 2.44.3 but not 2.45, update the constraints */ if ( !(main->versionfile==244 && main->subversionfile==3) && @@ -6776,14 +7240,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) curcon->ownspace = CONSTRAINT_SPACE_LOCAL; } break; - case CONSTRAINT_TYPE_STRETCHTO: - { - bStretchToConstraint *data= (bStretchToConstraint *)curcon->data; - - /* force recalc of rest-length */ - data->orglength = 0; - } - break; } } } @@ -6815,14 +7271,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) curcon->tarspace = CONSTRAINT_SPACE_LOCAL; } break; - case CONSTRAINT_TYPE_STRETCHTO: - { - bStretchToConstraint *data= (bStretchToConstraint *)curcon->data; - - /* force recalc of rest-length */ - data->orglength = 0; - } - break; } } @@ -6887,6 +7335,27 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + /* add point caches */ + for(ob=main->object.first; ob; ob=ob->id.next) { + if(ob->soft && !ob->soft->pointcache) + ob->soft->pointcache= BKE_ptcache_add(); + + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + if(psys->soft && !psys->soft->pointcache) + psys->soft->pointcache= BKE_ptcache_add(); + if(!psys->pointcache) + psys->pointcache= BKE_ptcache_add(); + } + + for(md=ob->modifiers.first; md; md=md->next) { + if(md->type==eModifierType_Cloth) { + ClothModifierData *clmd = (ClothModifierData*) md; + if(!clmd->point_cache) + clmd->point_cache= BKE_ptcache_add(); + } + } + } + /* Copy over old per-level multires vertex data into a single vertex array in struct Multires */ for(me = main->mesh.first; me; me=me->id.next) { @@ -6942,6 +7411,54 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + for(wrld=main->world.first; wrld; wrld= wrld->id.next) { + if(wrld->ao_approx_error == 0.0f) + wrld->ao_approx_error= 0.25f; + } + + for(sce= main->scene.first; sce; sce= sce->id.next) { + if(sce->nodetree) + ntree_version_245(fd, lib, sce->nodetree); + + if(sce->r.simplify_shadowsamples == 0) { + sce->r.simplify_subsurf= 6; + sce->r.simplify_particles= 1.0f; + sce->r.simplify_shadowsamples= 16; + sce->r.simplify_aosss= 1.0f; + } + + if(sce->r.cineongamma == 0) { + sce->r.cineonblack= 95; + sce->r.cineonwhite= 685; + sce->r.cineongamma= 1.7f; + } + } + + for(ntree=main->nodetree.first; ntree; ntree= ntree->id.next) + ntree_version_245(fd, lib, ntree); + + /* fix for temporary flag changes during 245 cycle */ + for(ima= main->image.first; ima; ima= ima->id.next) { + if(ima->flag & IMA_OLD_PREMUL) { + ima->flag &= ~IMA_OLD_PREMUL; + ima->flag |= IMA_DO_PREMUL; + } + } + + for(tex=main->tex.first; tex; tex=tex->id.next) { + if(tex->iuser.flag & IMA_OLD_PREMUL) { + tex->iuser.flag &= ~IMA_OLD_PREMUL; + tex->iuser.flag |= IMA_DO_PREMUL; + + } + + ima= newlibadr(fd, lib, tex->ima); + if(ima && (tex->iuser.flag & IMA_DO_PREMUL)) { + ima->flag &= ~IMA_OLD_PREMUL; + ima->flag |= IMA_DO_PREMUL; + } + } + if (main->versionfile < 245 || main->subversionfile < 12) { /* initialize skeleton generation toolsettings */ @@ -6964,6 +7481,24 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } + + /* sanity check for skgen + * */ + { + Scene *sce; + for(sce=main->scene.first; sce; sce = sce->id.next) + { + if (sce->toolsettings->skgen_subdivisions[0] == sce->toolsettings->skgen_subdivisions[1] || + sce->toolsettings->skgen_subdivisions[0] == sce->toolsettings->skgen_subdivisions[2] || + sce->toolsettings->skgen_subdivisions[1] == sce->toolsettings->skgen_subdivisions[2]) + { + sce->toolsettings->skgen_subdivisions[0] = SKGEN_SUB_CORRELATION; + sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH; + sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE; + } + } + } + if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 2)) { Image *ima; @@ -7092,62 +7627,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) sb->keys = NULL; sb->totkey = 0; - ob->softflag &= ~OB_SB_BAKESET; - } - } - } - - if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 7)) { - Object *ob; - bPoseChannel *pchan; - bConstraint *con; - bConstraintTarget *ct; - - for(ob = main->object.first; ob; ob= ob->id.next) { - if(ob->pose) { - for(pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) { - for(con=pchan->constraints.first; con; con=con->next) { - if(con->type==CONSTRAINT_TYPE_PYTHON) { - bPythonConstraint *data= (bPythonConstraint *)con->data; - if (data->tar) { - /* version patching needs to be done */ - ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget"); - - ct->tar = data->tar; - strcpy(ct->subtarget, data->subtarget); - ct->space = con->tarspace; - - BLI_addtail(&data->targets, ct); - data->tarnum++; - - /* clear old targets to avoid problems */ - data->tar = NULL; - strcpy(data->subtarget, ""); - } - } - } - } - } - - for(con=ob->constraints.first; con; con=con->next) { - if(con->type==CONSTRAINT_TYPE_PYTHON) { - bPythonConstraint *data= (bPythonConstraint *)con->data; - if (data->tar) { - /* version patching needs to be done */ - ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget"); - - ct->tar = data->tar; - strcpy(ct->subtarget, data->subtarget); - ct->space = con->tarspace; - - BLI_addtail(&data->targets, ct); - data->tarnum++; - - /* clear old targets to avoid problems */ - data->tar = NULL; - strcpy(data->subtarget, ""); - } - } } } } @@ -7171,7 +7650,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) sb->keys = NULL; sb->totkey = 0; - ob->softflag &= ~OB_SB_BAKESET; } /* convert old particles to new system */ @@ -7183,17 +7661,19 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* create new particle system */ psys = MEM_callocN(sizeof(ParticleSystem), "particle_system"); + psys->pointcache = BKE_ptcache_add(); part = psys->part = psys_new_settings("PSys", main); /* needed for proper libdata lookup */ oldnewmap_insert(fd->libmap, psys->part, psys->part, 0); + part->id.lib= ob->id.lib; part->id.us--; part->id.flag |= (ob->id.flag & LIB_NEEDLINK); psys->totpart=0; - psys->flag=PSYS_ENABLED|PSYS_CURRENT; + psys->flag= PSYS_ENABLED|PSYS_CURRENT; BLI_addtail(&ob->particlesystem, psys); @@ -7217,6 +7697,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) part->eff_group = paf->group; + /* old system didn't interpolate between keypoints at render time */ + part->draw_step = part->ren_step = 0; + /* physics */ part->normfac = paf->normfac * 25.0f; part->obfac = paf->obfac; @@ -7269,10 +7752,20 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ob->transflag &= ~OB_DUPLIVERTS; part->draw_as = PART_DRAW_OB; + + /* needed for proper libdata lookup */ + oldnewmap_insert(fd->libmap, dup, dup, 0); } } } + + { + FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); + if(fluidmd && fluidmd->fss && fluidmd->fss->type == OB_FLUIDSIM_PARTICLE) + part->type = PART_FLUID; + } + free_effects(&ob->effect); printf("Old particle system converted to new system.\n"); @@ -7340,17 +7833,259 @@ static void do_versions(FileData *fd, Library *lib, Main *main) strip->scale = length / (repeat * actlength); if (strip->scale == 0.0f) strip->scale= 1.0f; } + if(ob->soft){ + ob->soft->inpush = ob->soft->inspring; + ob->soft->shearstiff = 1.0f; + } } } + + if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 14)) { + Scene *sce= main->scene.first; + Sequence *seq; + Editing *ed; + while(sce) { + ed= sce->ed; + if(ed) { + WHILE_SEQ(&ed->seqbase) { + if (seq->blend_mode == 0) { + seq->blend_opacity = 100.0; + } + } + END_SEQ + } + + sce= sce->id.next; + } + } + + /*fix broken group lengths in id properties*/ + if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 15)) { + idproperties_fix_group_lengths(main->scene); + idproperties_fix_group_lengths(main->library); + idproperties_fix_group_lengths(main->object); + idproperties_fix_group_lengths(main->mesh); + idproperties_fix_group_lengths(main->curve); + idproperties_fix_group_lengths(main->mball); + idproperties_fix_group_lengths(main->mat); + idproperties_fix_group_lengths(main->tex); + idproperties_fix_group_lengths(main->image); + idproperties_fix_group_lengths(main->wave); + idproperties_fix_group_lengths(main->latt); + idproperties_fix_group_lengths(main->lamp); + idproperties_fix_group_lengths(main->camera); + idproperties_fix_group_lengths(main->ipo); + idproperties_fix_group_lengths(main->key); + idproperties_fix_group_lengths(main->world); + idproperties_fix_group_lengths(main->screen); + idproperties_fix_group_lengths(main->script); + idproperties_fix_group_lengths(main->vfont); + idproperties_fix_group_lengths(main->text); + idproperties_fix_group_lengths(main->sound); + idproperties_fix_group_lengths(main->group); + idproperties_fix_group_lengths(main->armature); + idproperties_fix_group_lengths(main->action); + idproperties_fix_group_lengths(main->nodetree); + idproperties_fix_group_lengths(main->brush); + idproperties_fix_group_lengths(main->particle); + } + + /* sun/sky */ + if(main->versionfile < 246) { + Object *ob; + bActuator *act; + + /* dRot actuator change direction in 2.46 */ + for(ob = main->object.first; ob; ob= ob->id.next) { + for(act= ob->actuators.first; act; act= act->next) { + if (act->type == ACT_OBJECT) { + bObjectActuator *ba= act->data; + + ba->drot[0] = -ba->drot[0]; + ba->drot[1] = -ba->drot[1]; + ba->drot[2] = -ba->drot[2]; + } + } + } + } + + // convert fluids to modifier + if(main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)) + { + Object *ob; + for(ob = main->object.first; ob; ob= ob->id.next) { + if(ob->fluidsimSettings) + { + FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifier_new(eModifierType_Fluidsim); + BLI_addhead(&ob->modifiers, (ModifierData *)fluidmd); + + MEM_freeN(fluidmd->fss); + fluidmd->fss = MEM_dupallocN(ob->fluidsimSettings); + fluidmd->fss->ipo = newlibadr_us(fd, ob->id.lib, ob->fluidsimSettings->ipo); + MEM_freeN(ob->fluidsimSettings); + + fluidmd->fss->lastgoodframe = INT_MAX; + fluidmd->fss->flag = 0; + } + } + } + + + if(main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)) { + Mesh *me; + + for(me=main->mesh.first; me; me= me->id.next) + alphasort_version_246(fd, lib, me); + } + + if(main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)){ + Object *ob; + for(ob = main->object.first; ob; ob= ob->id.next) { + if(ob->pd && (ob->pd->forcefield == PFIELD_WIND)) + ob->pd->f_noise = 0.0; + } + } + + if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 2)){ + Object *ob; + for(ob = main->object.first; ob; ob= ob->id.next) { + ob->gameflag |= OB_COLLISION; + ob->margin = 0.06; + } + } + + if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 3)){ + Object *ob; + for(ob = main->object.first; ob; ob= ob->id.next) { + // Starting from subversion 3, ACTOR is a separate feature. + // Before it was conditioning all the other dynamic flags + if (!(ob->gameflag & OB_ACTOR)) + ob->gameflag &= ~(OB_GHOST|OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY|OB_COLLISION_RESPONSE); + /* suitable default for older files */ + } + } + + if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 4)){ + Scene *sce= main->scene.first; + while(sce) { + if(sce->frame_step==0) + sce->frame_step= 1; + sce= sce->id.next; + } + } + + if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 5)) { + Lamp *la= main->lamp.first; + for(; la; la= la->id.next) { + la->skyblendtype= MA_RAMP_ADD; + la->skyblendfac= 1.0f; + } + } + + /* set the curve radius interpolation to 2.47 default - easy */ + if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 6)) { + Curve *cu; + Nurb *nu; + + for(cu= main->curve.first; cu; cu= cu->id.next) { + for(nu= cu->nurb.first; nu; nu= nu->next) { + if (nu) { + nu->radius_interp = 3; + + /* resolu and resolv are now used differently for surfaces + * rather then using the resolution to define the entire number of divisions, + * use it for the number of divisions per segment + */ + if (nu->pntsv > 1) { + nu->resolu = MAX2( 1, (int)(((float)nu->resolu / (float)nu->pntsu)+0.5f) ); + nu->resolv = MAX2( 1, (int)(((float)nu->resolv / (float)nu->pntsv)+0.5f) ); + } + } + } + } + } + /* direction constraint actuators were always local in previous version */ + if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 7)) { + bActuator *act; + Object *ob; + + for(ob = main->object.first; ob; ob= ob->id.next) { + for(act= ob->actuators.first; act; act= act->next) { + if (act->type == ACT_CONSTRAINT) { + bConstraintActuator *coa = act->data; + if (coa->type == ACT_CONST_TYPE_DIST) { + coa->flag |= ACT_CONST_LOCAL; + } + } + } + } + } + /* autokey mode settings now used from scene, but need to be initialised off userprefs */ + if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 8)) { + Scene *sce; + + for (sce= main->scene.first; sce; sce= sce->id.next) { + if (sce->autokey_mode == 0) + sce->autokey_mode= U.autokey_mode; + } + } + + if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 9)) { + Lamp *la= main->lamp.first; + for(; la; la= la->id.next) { + la->sky_exposure= 1.0f; + } + } + + /* BGE message actuators needed OB prefix, very confusing */ + if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 10)) { + bActuator *act; + Object *ob; + + for(ob = main->object.first; ob; ob= ob->id.next) { + for(act= ob->actuators.first; act; act= act->next) { + if (act->type == ACT_MESSAGE) { + bMessageActuator *msgAct = (bMessageActuator *) act->data; + if (strlen(msgAct->toPropName) > 2) { + /* strip first 2 chars, would have only worked if these were OB anyway */ + memmove( msgAct->toPropName, msgAct->toPropName+2, sizeof(msgAct->toPropName)-2 ); + } else { + msgAct->toPropName[0] = '\0'; + } + } + } + } + } + + if (main->versionfile < 248) { + Lamp *la; + + for(la=main->lamp.first; la; la= la->id.next) { + if(la->atm_turbidity == 0.0) { + la->sun_effect_type = 0; + la->horizon_brightness = 1.0; + la->spread = 1.0; + la->sun_brightness = 1.0; + la->sun_size = 1.0; + la->backscattered_light = 1.0; + la->atm_turbidity = 2.0; + la->atm_inscattering_factor = 1.0; + la->atm_extinction_factor = 1.0; + la->atm_distance_factor = 1.0; + la->sun_intensity = 1.0; + } + } + } + if (main->versionfile < 250) { bScreen *screen; for(screen= main->screen.first; screen; screen= screen->id.next) do_versions_windowmanager_2_50(screen); } - + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ @@ -7461,13 +8196,14 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r) /* do before read_libraries, but skip undo case */ // if(fd->memfile==NULL) (the mesh shuffle hacks don't work yet? ton) do_versions(fd, NULL, bfd->main); - + read_libraries(fd, &fd->mainlist); blo_join_main(&fd->mainlist); lib_link_all(fd, bfd->main); - lib_verify_nodetree(bfd->main); + lib_verify_nodetree(bfd->main, 1); + fix_relpaths_library(fd->filename, bfd->main); /* make all relative paths, relative to the open blend file */ link_global(fd, bfd); /* as last */ @@ -7476,6 +8212,43 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r) /* ************* APPEND LIBRARY ************** */ +struct bheadsort { + BHead *bhead; + void *old; +}; + +static int verg_bheadsort(const void *v1, const void *v2) +{ + const struct bheadsort *x1=v1, *x2=v2; + + if( x1->old > x2->old) return 1; + else if( x1->old < x2->old) return -1; + return 0; +} + +static void sort_bhead_old_map(FileData *fd) +{ + BHead *bhead; + struct bheadsort *bhs; + int tot= 0; + + for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) + tot++; + + fd->tot_bheadmap= tot; + if(tot==0) return; + + bhs= fd->bheadmap= MEM_mallocN(tot*sizeof(struct bheadsort), "bheadsort"); + + for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead), bhs++) { + bhs->bhead= bhead; + bhs->old= bhead->old; + } + + qsort(fd->bheadmap, tot, sizeof(struct bheadsort), verg_bheadsort); + +} + static BHead *find_previous_lib(FileData *fd, BHead *bhead) { for (; bhead; bhead= blo_prevbhead(fd, bhead)) @@ -7487,14 +8260,28 @@ static BHead *find_previous_lib(FileData *fd, BHead *bhead) static BHead *find_bhead(FileData *fd, void *old) { +#if 0 BHead *bhead; - +#endif + struct bheadsort *bhs, bhs_s; + if (!old) return NULL; + if (fd->bheadmap==NULL) + sort_bhead_old_map(fd); + + bhs_s.old= old; + bhs= bsearch(&bhs_s, fd->bheadmap, fd->tot_bheadmap, sizeof(struct bheadsort), verg_bheadsort); + + if(bhs) + return bhs->bhead; + +#if 0 for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) if (bhead->old==old) return bhead; +#endif return NULL; } @@ -7547,7 +8334,13 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) ptr->curlib->parent= mainvar->curlib; } else { - //oldnewmap_insert(fd->libmap, bhead->old, id, 1); + /* The line below was commented by Ton (I assume), when Hos did the merge from the orange branch. rev 6568 + * This line is NEEDED, the case is that you have 3 blend files... + * user.blend, lib.blend and lib_indirect.blend - if user.blend alredy references a "tree" from + * lib_indirect.blend but lib.blend does too, linking in a Scene or Group from lib.blend can result in an + * empty without the dupli group referenced. Once you save and reload the group would appier. - Campbell */ + /* This crashes files, must look further into it */ + /*oldnewmap_insert(fd->libmap, bhead->old, id, 1);*/ change_idid_adr_fd(fd, bhead->old, id); if(G.f & G_DEBUG) printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name); @@ -7571,6 +8364,14 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) } } +static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSettings *part) +{ + expand_doit(fd, mainvar, part->dup_ob); + expand_doit(fd, mainvar, part->dup_group); + expand_doit(fd, mainvar, part->eff_group); + expand_doit(fd, mainvar, part->bb_ob); +} + static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo) { IpoCurve *icu; @@ -7841,6 +8642,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb) expand_doit(fd, mainvar, data->tar); } break; + case CONSTRAINT_TYPE_DISTLIMIT: + { + bDistLimitConstraint *data = (bDistLimitConstraint*)curcon->data; + expand_doit(fd, mainvar, data->tar); + } + break; default: break; } @@ -7919,6 +8726,12 @@ static void expand_modifier(FileData *fd, Main *mainvar, ModifierData *md) expand_doit(fd, mainvar, mmd->mirror_ob); } + else if (md->type==eModifierType_Displace) { + DisplaceModifierData *dmd = (DisplaceModifierData*) md; + + expand_doit(fd, mainvar, dmd->map_object); + expand_doit(fd, mainvar, dmd->texture); + } } static void expand_scriptlink(FileData *fd, Main *mainvar, ScriptLink *slink) @@ -7945,6 +8758,7 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) expand_doit(fd, mainvar, ob->data); expand_doit(fd, mainvar, ob->ipo); expand_doit(fd, mainvar, ob->action); + expand_doit(fd, mainvar, ob->poselib); for (md=ob->modifiers.first; md; md=md->next) { expand_modifier(fd, mainvar, md); @@ -7981,9 +8795,6 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) sens= ob->sensors.first; while(sens) { - for(a=0; a<sens->totlinks; a++) { - sens->links[a]= newglobadr(fd, sens->links[a]); - } if(sens->type==SENS_TOUCH) { bTouchSensor *ts= sens->data; expand_doit(fd, mainvar, ts->ma); @@ -7997,9 +8808,6 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) cont= ob->controllers.first; while(cont) { - for(a=0; a<cont->totlinks; a++) { - cont->links[a]= newglobadr(fd, cont->links[a]); - } if(cont->type==CONT_PYTHON) { bPythonCont *pc= cont->data; expand_doit(fd, mainvar, pc->text); @@ -8033,6 +8841,10 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) bActionActuator *aa= act->data; expand_doit(fd, mainvar, aa->act); } + else if(act->type==ACT_SHAPEACTION) { + bActionActuator *aa= act->data; + expand_doit(fd, mainvar, aa->act); + } else if(act->type==ACT_PROPERTY) { bPropertyActuator *pa= act->data; expand_doit(fd, mainvar, pa->ob); @@ -8043,6 +8855,9 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) } act= act->next; } + + if(ob->pd && ob->pd->tex) + expand_doit(fd, mainvar, ob->pd->tex); expand_scriptlink(fd, mainvar, &ob->scriptlink); } @@ -8156,6 +8971,8 @@ static void expand_main(FileData *fd, Main *mainvar) case ID_IP: expand_ipo(fd, mainvar, (Ipo *)id); break; + case ID_PA: + expand_particlesettings(fd, mainvar, (ParticleSettings *)id); } doit= 1; @@ -8179,34 +8996,42 @@ static int object_in_any_scene(Object *ob) } /* when *lib set, it also does objects that were in the appended group */ -static void give_base_to_objects(Scene *sce, ListBase *lb, Library *lib) +static void give_base_to_objects(Scene *sce, ListBase *lb, Library *lib, int is_group_append) { Object *ob; Base *base; /* give all objects which are LIB_INDIRECT a base, or for a group when *lib has been set */ for(ob= lb->first; ob; ob= ob->id.next) { - + if( ob->id.flag & LIB_INDIRECT ) { - int do_it= 0; - if(ob->id.us==0) - do_it= 1; - else if(ob->id.us==1 && lib) - if(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(ob)==0) + /* IF below is quite confusing! + if we are appending, but this object wasnt just added allong with a group, + then this is alredy used indirectly in the scene somewhere else and we didnt just append it. + + (ob->id.flag & LIB_APPEND_TAG)==0 means that this is a newly appended object - Campbell */ + if (is_group_append==0 || (ob->id.flag & LIB_APPEND_TAG)==0) { + + int do_it= 0; + + if(ob->id.us==0) do_it= 1; + else if(ob->id.us==1 && lib) + if(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(ob)==0) + do_it= 1; + + if(do_it) { + base= MEM_callocN( sizeof(Base), "add_ext_base"); + BLI_addtail(&(sce->base), base); + base->lay= ob->lay; + base->object= ob; + base->flag= ob->flag; + ob->id.us= 1; - if(do_it) { - base= MEM_callocN( sizeof(Base), "add_ext_base"); - BLI_addtail(&(sce->base), base); - base->lay= ob->lay; - base->object= ob; - base->flag= ob->flag; - ob->id.us= 1; - - ob->id.flag -= LIB_INDIRECT; - ob->id.flag |= LIB_EXTERN; - + ob->id.flag -= LIB_INDIRECT; + ob->id.flag |= LIB_EXTERN; + } } } } @@ -8295,38 +9120,38 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r) /* common routine to append/link something from a library */ static Library* library_append(Scene *scene, char* file, char *dir, int idcode, - int totsel, FileData *fd, struct direntry* filelist, int totfile, short flag) + int totsel, FileData **fd, struct direntry* filelist, int totfile, short flag) { Main *mainl; Library *curlib; /* make mains */ - blo_split_main(&fd->mainlist, G.main); + blo_split_main(&(*fd)->mainlist, G.main); /* which one do we need? */ - mainl = blo_find_main(fd, &fd->mainlist, dir, G.sce); + mainl = blo_find_main(*fd, &(*fd)->mainlist, dir, G.sce); - mainl->versionfile= fd->fileversion; /* needed for do_version */ + mainl->versionfile= (*fd)->fileversion; /* needed for do_version */ curlib= mainl->curlib; if(totsel==0) { - append_named_part(fd, mainl, scene, file, idcode, flag); + append_named_part(*fd, mainl, scene, file, idcode, flag); } else { int a; for(a=0; a<totfile; a++) { if(filelist[a].flags & ACTIVE) { - append_named_part(fd, mainl, scene, filelist[a].relname, idcode, flag); + append_named_part(*fd, mainl, scene, filelist[a].relname, idcode, flag); } } } /* make main consistant */ - expand_main(fd, mainl); + expand_main(*fd, mainl); /* do this when expand found other libs */ - read_libraries(fd, &fd->mainlist); + read_libraries(*fd, &(*fd)->mainlist); if(flag & FILE_STRINGCODE) { @@ -8337,25 +9162,31 @@ static Library* library_append(Scene *scene, char* file, char *dir, int idcode, BLI_makestringcode(G.sce, mainl->curlib->name); } - blo_join_main(&fd->mainlist); - G.main= fd->mainlist.first; + blo_join_main(&(*fd)->mainlist); + G.main= (*fd)->mainlist.first; - lib_link_all(fd, G.main); - lib_verify_nodetree(G.main); + lib_link_all(*fd, G.main); + lib_verify_nodetree(G.main, 0); + fix_relpaths_library(G.sce, G.main); /* make all relative paths, relative to the open blend file */ /* give a base to loose objects. If group append, do it for objects too */ - if(idcode==ID_GR) - give_base_to_objects(scene, &(G.main->object), (flag & FILE_LINK)?NULL:curlib); - else - give_base_to_objects(scene, &(G.main->object), NULL); - + if(idcode==ID_GR) { + if (flag & FILE_LINK) { + give_base_to_objects(scene, &(G.main->object), NULL, 0); + } else { + give_base_to_objects(scene, &(G.main->object), curlib, 1); + } + } else { + give_base_to_objects(scene, &(G.main->object), NULL, 0); + } /* has been removed... erm, why? s..ton) */ /* 20040907: looks like they are give base already in append_named_part(); -Nathan L */ /* 20041208: put back. It only linked direct, not indirect objects (ton) */ /* patch to prevent switch_endian happens twice */ - if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) { - blo_freefiledata( fd ); + if((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) { + blo_freefiledata( *fd ); + *fd = NULL; } return curlib; @@ -8366,11 +9197,11 @@ static Library* library_append(Scene *scene, char* file, char *dir, int idcode, /* append to scene */ /* this should probably be moved into the Python code anyway */ -void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, +void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, Scene *scene ) { /* try to append the requested object */ - library_append(scene, name, dir, idcode, 0, (FileData *)bh, NULL, 0, flag ); + library_append(scene, name, dir, idcode, 0, (FileData **)bh, NULL, 0, flag ); /* do we need to do this? */ DAG_scene_sort(scene); @@ -8387,7 +9218,6 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode, Scene *scene) void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode, Scene *scene) { - FileData *fd= (FileData*) (*libfiledata); Library *curlib; Base *centerbase; Object *ob; @@ -8420,12 +9250,7 @@ void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, i if(flag & FILE_AUTOSELECT) scene_deselect_all(scene); - curlib = library_append(scene, file, dir, idcode, totsel, fd, filelist, totfile,flag ); - - /* patch to prevent switch_endian happens twice */ - if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) { - (*libfiledata)= 0; - } + curlib = library_append(scene, file, dir, idcode, totsel, (FileData**) libfiledata, filelist, totfile,flag ); /* when not linking (appending)... */ if((flag & FILE_LINK)==0) { @@ -8599,13 +9424,13 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if(mainptr->curlib->filedata) blo_freefiledata(mainptr->curlib->filedata); mainptr->curlib->filedata= NULL; - } } + /* reading runtime */ -BlendFileData *blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r) +BlendFileData *blo_read_blendafterruntime(int file, char *name, int actualsize, BlendReadError *error_r) { BlendFileData *bfd = NULL; FileData *fd = filedata_new(); @@ -8613,6 +9438,9 @@ BlendFileData *blo_read_blendafterruntime(int file, int actualsize, BlendReadErr fd->buffersize = actualsize; fd->read = fd_read_from_file; + /* needed for library_append and read_libraries */ + BLI_strncpy(fd->filename, name, sizeof(fd->filename)); + fd = blo_decode_and_check(fd, error_r); if (!fd) return NULL; diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index 51160a179fb..8547a4d9652 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -34,6 +34,7 @@ struct OldNewMap; struct MemFile; +struct bheadsort; typedef struct FileData { // linked list of BHeadN's @@ -73,6 +74,9 @@ typedef struct FileData { struct OldNewMap *libmap; struct OldNewMap *imamap; + struct bheadsort *bheadmap; + int tot_bheadmap; + ListBase mainlist; /* ick ick, used to return @@ -108,6 +112,7 @@ FileData *blo_openblenderfile( char *name, BlendReadError *error_r); FileData *blo_openblendermemory( void *buffer, int buffersize, BlendReadError *error_r); FileData *blo_openblendermemfile(struct MemFile *memfile, BlendReadError *error_r); +void blo_clear_proxy_pointers_from_lib(FileData *fd); void blo_make_image_pointer_map(FileData *fd); void blo_end_image_pointer_map(FileData *fd); void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 383a732fbca..a4883087cfa 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -6,7 +6,7 @@ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,7 +23,7 @@ * * Contributor(s): Blender Foundation * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ /* @@ -94,6 +94,7 @@ Any case: direct data is ALWAYS after the lib block #include "DNA_actuator_types.h" #include "DNA_brush_types.h" #include "DNA_camera_types.h" +#include "DNA_cloth_types.h" #include "DNA_color_types.h" #include "DNA_constraint_types.h" #include "DNA_controller_types.h" @@ -102,6 +103,7 @@ Any case: direct data is ALWAYS after the lib block #include "DNA_effect_types.h" #include "DNA_genfile.h" #include "DNA_group_types.h" +#include "DNA_gpencil_types.h" #include "DNA_image_types.h" #include "DNA_ipo_types.h" #include "DNA_fileglobal_types.h" @@ -143,6 +145,7 @@ Any case: direct data is ALWAYS after the lib block #include "BKE_action.h" #include "BKE_blender.h" +#include "BKE_cloth.h" #include "BKE_curve.h" #include "BKE_customdata.h" #include "BKE_constraint.h" @@ -162,8 +165,6 @@ Any case: direct data is ALWAYS after the lib block //XXX #include "BIF_verse.h" #endif -#include "GEN_messaging.h" - #include "BLO_writefile.h" #include "BLO_readfile.h" #include "BLO_undofile.h" @@ -172,7 +173,10 @@ Any case: direct data is ALWAYS after the lib block #include <errno.h> -/* ********* my write, buffered writing with minimum 50k chunks ************ */ +/* ********* my write, buffered writing with minimum size chunks ************ */ + +#define MYWRITE_BUFFER_SIZE 100000 +#define MYWRITE_MAX_CHUNK 32768 typedef struct { struct SDNA *sdna; @@ -198,7 +202,7 @@ static WriteData *writedata_new(int file) wd->file= file; - wd->buf= MEM_mallocN(100000, "wd->buf"); + wd->buf= MEM_mallocN(MYWRITE_BUFFER_SIZE, "wd->buf"); return wd; } @@ -238,12 +242,13 @@ int mywfile; * @warning Talks to other functions with global parameters */ -#define MYWRITE_FLUSH NULL +#define MYWRITE_FLUSH NULL static void mywrite( WriteData *wd, void *adr, int len) { if (wd->error) return; + /* flush helps compression for undo-save */ if(adr==MYWRITE_FLUSH) { if(wd->count) { writedata_do_write(wd, wd->buf, wd->count); @@ -254,21 +259,33 @@ static void mywrite( WriteData *wd, void *adr, int len) wd->tot+= len; - if(len>50000) { + /* if we have a single big chunk, write existing data in + * buffer and write out big chunk in smaller pieces */ + if(len>MYWRITE_MAX_CHUNK) { if(wd->count) { writedata_do_write(wd, wd->buf, wd->count); wd->count= 0; } - writedata_do_write(wd, adr, len); + + do { + int writelen= MIN2(len, MYWRITE_MAX_CHUNK); + writedata_do_write(wd, adr, writelen); + adr = (char*)adr + writelen; + len -= writelen; + } while(len > 0); + return; } - if(len+wd->count>99999) { + + /* if data would overflow buffer, write out the buffer */ + if(len+wd->count>MYWRITE_BUFFER_SIZE-1) { writedata_do_write(wd, wd->buf, wd->count); wd->count= 0; } + + /* append data at end of buffer */ memcpy(&wd->buf[wd->count], adr, len); wd->count+= len; - } /** @@ -367,7 +384,7 @@ static void writedata(WriteData *wd, int filecode, int len, void *adr) /* do not void IDP_WriteProperty_OnlyData(IDProperty *prop, void *wd); void IDP_WriteProperty(IDProperty *prop, void *wd); -void IDP_WriteArray(IDProperty *prop, void *wd) +static void IDP_WriteArray(IDProperty *prop, void *wd) { /*REMEMBER to set totalen to len in the linking code!!*/ if (prop->data.pointer) { @@ -375,13 +392,13 @@ void IDP_WriteArray(IDProperty *prop, void *wd) } } -void IDP_WriteString(IDProperty *prop, void *wd) +static void IDP_WriteString(IDProperty *prop, void *wd) { /*REMEMBER to set totalen to len in the linking code!!*/ writedata(wd, DATA, prop->len+1, prop->data.pointer); } -void IDP_WriteGroup(IDProperty *prop, void *wd) +static void IDP_WriteGroup(IDProperty *prop, void *wd) { IDProperty *loop; @@ -434,7 +451,7 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) writestruct(wd, DATA, "bNode", 1, node); for(node= ntree->nodes.first; node; node= node->next) { - if(node->storage) { + if(node->storage && node->type!=NODE_DYNAMIC) { /* could be handlerized at some point, now only 1 exception still */ if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)) write_curvemapping(wd, node->storage); @@ -492,25 +509,6 @@ static void write_userdef(WriteData *wd) } } -static void write_effects(WriteData *wd, ListBase *lb) -{ - Effect *eff; - - eff= lb->first; - while(eff) { - - switch(eff->type) { - case EFF_PARTICLE: - writestruct(wd, DATA, "PartEff", 1, eff); - break; - default: - writedata(wd, DATA, MEM_allocN_len(eff), eff); - } - - eff= eff->next; - } -} - static void write_particlesettings(WriteData *wd, ListBase *idbase) { ParticleSettings *part; @@ -520,7 +518,9 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase) if(part->id.us>0 || wd->current) { /* write LibData */ writestruct(wd, ID_PA, "ParticleSettings", 1, part); + if (part->id.properties) IDP_WriteProperty(part->id.properties, wd); writestruct(wd, DATA, "PartDeflect", 1, part->pd); + writestruct(wd, DATA, "PartDeflect", 1, part->pd2); } part= part->id.next; } @@ -540,11 +540,13 @@ static void write_particlesystems(WriteData *wd, ListBase *particles) ParticleData *pa = psys->particles; for(a=0; a<psys->totpart; a++, pa++) - writedata(wd, DATA, MEM_allocN_len(pa->hair),pa->hair); + writestruct(wd, DATA, "HairKey", pa->totkey, pa->hair); } } if(psys->child) writestruct(wd, DATA, "ChildParticle", psys->totchild ,psys->child); writestruct(wd, DATA, "SoftBody", 1, psys->soft); + if(psys->soft) writestruct(wd, DATA, "PointCache", 1, psys->soft->pointcache); + writestruct(wd, DATA, "PointCache", 1, psys->pointcache); } } @@ -589,6 +591,12 @@ static void write_sensors(WriteData *wd, ListBase *lb) case SENS_PROPERTY: writestruct(wd, DATA, "bPropertySensor", 1, sens->data); break; + case SENS_ACTUATOR: + writestruct(wd, DATA, "bActuatorSensor", 1, sens->data); + break; + case SENS_DELAY: + writestruct(wd, DATA, "bDelaySensor", 1, sens->data); + break; case SENS_COLLISION: writestruct(wd, DATA, "bCollisionSensor", 1, sens->data); break; @@ -650,6 +658,7 @@ static void write_actuators(WriteData *wd, ListBase *lb) switch(act->type) { case ACT_ACTION: + case ACT_SHAPEACTION: writestruct(wd, DATA, "bActionActuator", 1, act->data); break; case ACT_SOUND: @@ -694,6 +703,15 @@ static void write_actuators(WriteData *wd, ListBase *lb) case ACT_VISIBILITY: writestruct(wd, DATA, "bVisibilityActuator", 1, act->data); break; + case ACT_2DFILTER: + writestruct(wd, DATA, "bTwoDFilterActuator", 1, act->data); + break; + case ACT_PARENT: + writestruct(wd, DATA, "bParentActuator", 1, act->data); + break; + case ACT_STATE: + writestruct(wd, DATA, "bStateActuator", 1, act->data); + break; default: ; /* error: don't know how to write this file */ } @@ -754,6 +772,7 @@ static void write_constraints(WriteData *wd, ListBase *conlist) static void write_pose(WriteData *wd, bPose *pose) { bPoseChannel *chan; + bActionGroup *grp; /* Write each channel */ if (!pose) @@ -769,6 +788,10 @@ static void write_pose(WriteData *wd, bPose *pose) writestruct(wd, DATA, "bPoseChannel", 1, chan); } + + /* Write groups */ + for (grp=pose->agroups.first; grp; grp=grp->next) + writestruct(wd, DATA, "bActionGroup", 1, grp); /* Write this pose */ writestruct(wd, DATA, "bPose", 1, pose); @@ -807,6 +830,29 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) writedata(wd, DATA, sizeof(int)*hmd->totindex, hmd->indexar); } + else if(md->type==eModifierType_Cloth) { + ClothModifierData *clmd = (ClothModifierData*) md; + + writestruct(wd, DATA, "ClothSimSettings", 1, clmd->sim_parms); + writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms); + writestruct(wd, DATA, "PointCache", 1, clmd->point_cache); + } + else if(md->type==eModifierType_Fluidsim) { + FluidsimModifierData *fluidmd = (FluidsimModifierData*) md; + + writestruct(wd, DATA, "FluidsimSettings", 1, fluidmd->fss); + } + else if (md->type==eModifierType_Collision) { + + /* + CollisionModifierData *collmd = (CollisionModifierData*) md; + // TODO: CollisionModifier should use pointcache + // + have proper reset events before enabling this + writestruct(wd, DATA, "MVert", collmd->numverts, collmd->x); + writestruct(wd, DATA, "MVert", collmd->numverts, collmd->xnew); + writestruct(wd, DATA, "MFace", collmd->numfaces, collmd->mfaces); + */ + } else if (md->type==eModifierType_MeshDeform) { MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; int size = mmd->dyngridsize; @@ -846,7 +892,7 @@ static void write_objects(WriteData *wd, ListBase *idbase) /* direct data */ writedata(wd, DATA, sizeof(void *)*ob->totcol, ob->mat); - write_effects(wd, &ob->effect); + /* write_effects(wd, &ob->effect); */ /* not used anymore */ write_properties(wd, &ob->prop); write_sensors(wd, &ob->sensors); write_controllers(wd, &ob->controllers); @@ -860,7 +906,8 @@ static void write_objects(WriteData *wd, ListBase *idbase) writestruct(wd, DATA, "PartDeflect", 1, ob->pd); writestruct(wd, DATA, "SoftBody", 1, ob->soft); - writestruct(wd, DATA, "FluidsimSettings", 1, ob->fluidsimSettings); // NT + if(ob->soft) writestruct(wd, DATA, "PointCache", 1, ob->soft->pointcache); + writestruct(wd, DATA, "BulletSoftBody", 1, ob->bsoft); write_particlesystems(wd, &ob->particlesystem); write_modifiers(wd, &ob->modifiers); @@ -1004,7 +1051,7 @@ static void write_mballs(WriteData *wd, ListBase *idbase) } } -int amount_of_chars(char *str) +static int amount_of_chars(char *str) { // Since the data is saved as UTF-8 to the cu->str // The cu->len is not same as the strlen(cu->str) @@ -1385,6 +1432,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase) MetaStack *ms; Strip *strip; TimeMarker *marker; + TransformOrientation *ts; SceneRenderLayer *srl; int a; @@ -1448,9 +1496,20 @@ static void write_scenes(WriteData *wd, ListBase *scebase) strip= seq->strip; writestruct(wd, DATA, "Strip", 1, strip); - + if(seq->flag & SEQ_USE_CROP && strip->crop) { + writestruct(wd, DATA, "StripCrop", 1, strip->crop); + } + if(seq->flag & SEQ_USE_TRANSFORM && strip->transform) { + writestruct(wd, DATA, "StripTransform", 1, strip->transform); + } + if(seq->flag & SEQ_USE_PROXY && strip->proxy) { + writestruct(wd, DATA, "StripProxy", 1, strip->proxy); + } + if(seq->flag & SEQ_USE_COLOR_BALANCE && strip->color_balance) { + writestruct(wd, DATA, "StripColorBalance", 1, strip->color_balance); + } if(seq->type==SEQ_IMAGE) - writestruct(wd, DATA, "StripElem", strip->len, strip->stripdata); + writestruct(wd, DATA, "StripElem", MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem), strip->stripdata); else if(seq->type==SEQ_MOVIE || seq->type==SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) writestruct(wd, DATA, "StripElem", 1, strip->stripdata); @@ -1477,11 +1536,18 @@ static void write_scenes(WriteData *wd, ListBase *scebase) writestruct(wd, DATA, "QuicktimeCodecData", 1, sce->r.qtcodecdata); if (sce->r.qtcodecdata->cdParms) writedata(wd, DATA, sce->r.qtcodecdata->cdSize, sce->r.qtcodecdata->cdParms); } + if (sce->r.ffcodecdata.properties) { + IDP_WriteProperty(sce->r.ffcodecdata.properties, wd); + } /* writing dynamic list of TimeMarkers to the blend file */ for(marker= sce->markers.first; marker; marker= marker->next) writestruct(wd, DATA, "TimeMarker", 1, marker); + /* writing dynamic list of TransformOrientations to the blend file */ + for(ts = sce->transform_spaces.first; ts; ts = ts->next) + writestruct(wd, DATA, "TransformOrientation", 1, ts); + for(srl= sce->r.layers.first; srl; srl= srl->next) writestruct(wd, DATA, "SceneRenderLayer", 1, srl); @@ -1496,6 +1562,32 @@ static void write_scenes(WriteData *wd, ListBase *scebase) mywrite(wd, MYWRITE_FLUSH, 0); } +static void write_gpencil(WriteData *wd, bGPdata *gpd) +{ + bGPDlayer *gpl; + bGPDframe *gpf; + bGPDstroke *gps; + + /* write gpd data block to file */ + writestruct(wd, DATA, "bGPdata", 1, gpd); + + /* write grease-pencil layers to file */ + for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { + writestruct(wd, DATA, "bGPDlayer", 1, gpl); + + /* write this layer's frames to file */ + for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { + writestruct(wd, DATA, "bGPDframe", 1, gpf); + + /* write strokes */ + for (gps= gpf->strokes.first; gps; gps= gps->next) { + writestruct(wd, DATA, "bGPDstroke", 1, gps); + writestruct(wd, DATA, "bGPDspoint", gps->totpoints, gps->points); + } + } + } +} + static void write_windowmanagers(WriteData *wd, ListBase *lb) { wmWindowManager *wm; @@ -1550,11 +1642,12 @@ static void write_screens(WriteData *wd, ListBase *scrbase) sl= sa->spacedata.first; while(sl) { if(sl->spacetype==SPACE_VIEW3D) { - View3D *v3d= (View3D*) sl; + View3D *v3d= (View3D *) sl; writestruct(wd, DATA, "View3D", 1, v3d); if(v3d->bgpic) writestruct(wd, DATA, "BGpic", 1, v3d->bgpic); if(v3d->localvd) writestruct(wd, DATA, "View3D", 1, v3d->localvd); if(v3d->clipbb) writestruct(wd, DATA, "BoundBox", 1, v3d->clipbb); + if(v3d->gpd) write_gpencil(wd, v3d->gpd); } else if(sl->spacetype==SPACE_IPO) { writestruct(wd, DATA, "SpaceIpo", 1, sl); @@ -1566,7 +1659,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase) writestruct(wd, DATA, "SpaceFile", 1, sl); } else if(sl->spacetype==SPACE_SEQ) { + SpaceSeq *sseq= (SpaceSeq *)sl; writestruct(wd, DATA, "SpaceSeq", 1, sl); + if(sseq->gpd) write_gpencil(wd, sseq->gpd); } else if(sl->spacetype==SPACE_OOPS) { SpaceOops *so= (SpaceOops *)sl; @@ -1603,7 +1698,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase) writestruct(wd, DATA, "SpaceImage", 1, sl); if(sima->cumap) - write_curvemapping(wd, sima->cumap); + write_curvemapping(wd, sima->cumap); + if(sima->gpd) + write_gpencil(wd, sima->gpd); } else if(sl->spacetype==SPACE_IMASEL) { writestruct(wd, DATA, "SpaceImaSel", 1, sl); @@ -1629,7 +1726,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase) writestruct(wd, DATA, "SpaceTime", 1, sl); } else if(sl->spacetype==SPACE_NODE){ + SpaceNode *snode= (SpaceNode *)sl; writestruct(wd, DATA, "SpaceNode", 1, sl); + if(snode->gpd) write_gpencil(wd, snode->gpd); } sl= sl->next; } @@ -1722,16 +1821,26 @@ static void write_actions(WriteData *wd, ListBase *idbase) { bAction *act; bActionChannel *chan; + bActionGroup *grp; + TimeMarker *marker; for(act=idbase->first; act; act= act->id.next) { if (act->id.us>0 || wd->current) { writestruct(wd, ID_AC, "bAction", 1, act); if (act->id.properties) IDP_WriteProperty(act->id.properties, wd); - + for (chan=act->chanbase.first; chan; chan=chan->next) { writestruct(wd, DATA, "bActionChannel", 1, chan); write_constraint_channels(wd, &chan->constraintChannels); } + + for (grp=act->groups.first; grp; grp=grp->next) { + writestruct(wd, DATA, "bActionGroup", 1, grp); + } + + for (marker=act->markers.first; marker; marker=marker->next) { + writestruct(wd, DATA, "TimeMarker", 1, marker); + } } } } @@ -1740,6 +1849,7 @@ static void write_texts(WriteData *wd, ListBase *idbase) { Text *text; TextLine *tmp; + TextMarker *mrk; text= idbase->first; while(text) { @@ -1763,7 +1873,16 @@ static void write_texts(WriteData *wd, ListBase *idbase) writedata(wd, DATA, tmp->len+1, tmp->line); tmp= tmp->next; } + + /* write markers */ + mrk= text->markers.first; + while (mrk) { + writestruct(wd, DATA, "TextMarker", 1, mrk); + mrk= mrk->next; + } } + + text= text->id.next; } @@ -1870,9 +1989,21 @@ static void write_brushes(WriteData *wd, ListBase *idbase) } } +static void write_scripts(WriteData *wd, ListBase *idbase) +{ + Script *script; + + for(script=idbase->first; script; script= script->id.next) { + if(script->id.us>0 || wd->current) { + writestruct(wd, ID_SCRIPT, "Script", 1, script); + if (script->id.properties) IDP_WriteProperty(script->id.properties, wd); + } + } +} + /* context is usually defined by WM, two cases where no WM is available: -/* - for forward compatibility, curscreen has to be saved */ -/* - for undofile, curscene needs to be saved */ + * - for forward compatibility, curscreen has to be saved + * - for undofile, curscene needs to be saved */ /* XXX still remap G */ static void write_global(bContext *C, WriteData *wd) { @@ -1943,6 +2074,7 @@ static int write_file_handle(bContext *C, int handle, MemFile *compare, MemFile write_particlesettings(wd, &G.main->particle); write_nodetrees(wd, &G.main->nodetree); write_brushes (wd, &G.main->brush); + write_scripts (wd, &G.main->script); if(current==NULL) write_libraries(wd, G.main->next); /* no library save in undo */ @@ -2003,7 +2135,7 @@ int BLO_write_file(bContext *C, char *dir, int write_flags, char **error_r) } } else - if(BLI_rename(tempname, dir) < 0) { + if(BLI_rename(tempname, dir) != 0) { *error_r= "Can't change old file. File saved with @"; return 0; } @@ -2039,7 +2171,7 @@ int BLO_write_file_mem(bContext *C, MemFile *compare, MemFile *current, int writ #define PATHSEPERATOR "/" #endif -static char *get_install_dir(void) { +char *get_install_dir(void) { extern char bprogname[]; char *tmpname = BLI_strdup(bprogname); char *cut; @@ -2167,7 +2299,7 @@ static int handle_append_runtime(int handle, char *exename, char **cause_r) unsigned char buf[1024]; int count, progfd= -1; - if (!runtime) { + if (!BLI_exists(runtime)) { cause= "Unable to find runtime"; goto cleanup; } |