diff options
Diffstat (limited to 'source/blender/blenloader/intern')
-rw-r--r-- | source/blender/blenloader/intern/readblenentry.c | 15 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1246 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.h | 4 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_260.c | 4 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_270.c | 262 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_defaults.c | 43 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_legacy.c | 13 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 2298 |
8 files changed, 2136 insertions, 1749 deletions
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index be893177b3b..73109413271 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -317,7 +317,9 @@ void BLO_blendhandle_close(BlendHandle *bh) * \param reports If the return value is NULL, errors indicating the cause of the failure. * \return The data of the file. */ -BlendFileData *BLO_read_from_file(const char *filepath, ReportList *reports) +BlendFileData *BLO_read_from_file( + const char *filepath, + ReportList *reports, eBLOReadSkip skip_flags) { BlendFileData *bfd = NULL; FileData *fd; @@ -325,6 +327,7 @@ BlendFileData *BLO_read_from_file(const char *filepath, ReportList *reports) fd = blo_openblenderfile(filepath, reports); if (fd) { fd->reports = reports; + fd->skip_flags = skip_flags; bfd = blo_read_file_internal(fd, filepath); blo_freefiledata(fd); } @@ -341,7 +344,9 @@ BlendFileData *BLO_read_from_file(const char *filepath, ReportList *reports) * \param reports If the return value is NULL, errors indicating the cause of the failure. * \return The data of the file. */ -BlendFileData *BLO_read_from_memory(const void *mem, int memsize, ReportList *reports) +BlendFileData *BLO_read_from_memory( + const void *mem, int memsize, + ReportList *reports, eBLOReadSkip skip_flags) { BlendFileData *bfd = NULL; FileData *fd; @@ -349,6 +354,7 @@ BlendFileData *BLO_read_from_memory(const void *mem, int memsize, ReportList *re fd = blo_openblendermemory(mem, memsize, reports); if (fd) { fd->reports = reports; + fd->skip_flags = skip_flags; bfd = blo_read_file_internal(fd, ""); blo_freefiledata(fd); } @@ -362,7 +368,9 @@ BlendFileData *BLO_read_from_memory(const void *mem, int memsize, ReportList *re * \param oldmain old main, from which we will keep libraries and other datablocks that should not have changed. * \param filename current file, only for retrieving library data. */ -BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFile *memfile, ReportList *reports) +BlendFileData *BLO_read_from_memfile( + Main *oldmain, const char *filename, MemFile *memfile, + ReportList *reports, eBLOReadSkip skip_flags) { BlendFileData *bfd = NULL; FileData *fd; @@ -371,6 +379,7 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil fd = blo_openblendermemfile(memfile, reports); if (fd) { fd->reports = reports; + fd->skip_flags = skip_flags; BLI_strncpy(fd->relabase, filename, sizeof(fd->relabase)); /* clear ob->proxy_from pointers in old main */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 98c8a260993..3b7662be2b2 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -129,6 +129,7 @@ #include "BKE_library_idmap.h" #include "BKE_library_query.h" #include "BKE_idcode.h" +#include "BKE_idprop.h" #include "BKE_material.h" #include "BKE_main.h" // for Main #include "BKE_mesh.h" // for ME_ defines (patching) @@ -531,6 +532,8 @@ void blo_split_main(ListBase *mainlist, Main *main) for (Library *lib = main->library.first; lib; lib = lib->id.next, i++) { Main *libmain = BKE_main_new(); libmain->curlib = lib; + libmain->versionfile = lib->versionfile; + libmain->subversionfile = lib->subversionfile; BLI_addtail(mainlist, libmain); lib->temp_index = i; lib_main_array[i] = libmain; @@ -562,6 +565,10 @@ static void read_file_version(FileData *fd, Main *main) break; } } + if (main->curlib) { + main->curlib->versionfile = main->versionfile; + main->curlib->subversionfile = main->subversionfile; + } } #ifdef USE_GHASH_BHEAD @@ -631,7 +638,7 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab /* Add library datablock itself to 'main' Main, since libraries are **never** linked data. * Fixes bug where you could end with all ID_LI datablocks having the same name... */ - lib = BKE_libblock_alloc(mainlist->first, ID_LI, "Lib"); + lib = BKE_libblock_alloc(mainlist->first, ID_LI, "Lib", 0); lib->id.us = ID_FAKE_USERS(lib); /* Important, consistency with main ID reading code from read_libblock(). */ BLI_strncpy(lib->name, filepath, sizeof(lib->name)); BLI_strncpy(lib->filepath, name1, sizeof(lib->filepath)); @@ -1995,7 +2002,7 @@ static void test_pointer_array(FileData *fd, void **mat) /* ************ READ ID Properties *************** */ static void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd); -static void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, FileData *fd); +static void IDP_LibLinkProperty(IDProperty *prop, FileData *fd); static void IDP_DirectLinkIDPArray(IDProperty *prop, int switch_endian, FileData *fd) { @@ -2100,8 +2107,19 @@ static void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData BLI_endian_switch_int32(&prop->data.val2); BLI_endian_switch_int64((int64_t *)&prop->data.val); } - break; + case IDP_INT: + case IDP_FLOAT: + case IDP_ID: + break; /* Nothing special to do here. */ + default: + /* Unknown IDP type, nuke it (we cannot handle unknown types everywhere in code, + * IDP are way too polymorphic to do it safely. */ + printf("%s: found unknown IDProperty type %d, reset to Integer one !\n", __func__, prop->type); + /* Note: we do not attempt to free unknown prop, we have no way to know how to do that! */ + prop->type = IDP_INT; + prop->subtype = 0; + IDP_Int(prop) = 0; } } @@ -2126,10 +2144,39 @@ static void _IDP_DirectLinkGroup_OrFree(IDProperty **prop, int switch_endian, Fi } } -/* stub function */ -static void IDP_LibLinkProperty(IDProperty *UNUSED(prop), int UNUSED(switch_endian), FileData *UNUSED(fd)) +static void IDP_LibLinkProperty(IDProperty *prop, FileData *fd) { - /* Should we do something here, prop should be ensured to be non-NULL first... */ + if (!prop) + return; + + switch (prop->type) { + case IDP_ID: /* PointerProperty */ + { + void *newaddr = newlibadr_us(fd, NULL, IDP_Id(prop)); + if (IDP_Id(prop) && !newaddr && G.debug) { + printf("Error while loading \"%s\". Data not found in file!\n", prop->name); + } + prop->data.pointer = newaddr; + break; + } + case IDP_IDPARRAY: /* CollectionProperty */ + { + IDProperty *idp_array = IDP_IDPArray(prop); + for (int i = 0; i < prop->len; i++) { + IDP_LibLinkProperty(&(idp_array[i]), fd); + } + break; + } + case IDP_GROUP: /* PointerProperty */ + { + for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) { + IDP_LibLinkProperty(loop, fd); + } + break; + } + default: + break; /* Nothing to do for other IDProps. */ + } } /* ************ READ IMAGE PREVIEW *************** */ @@ -2186,19 +2233,19 @@ static void direct_link_curvemapping(FileData *fd, CurveMapping *cumap) /* library brush linking after fileread */ static void lib_link_brush(FileData *fd, Main *main) { - Brush *brush; - /* only link ID pointers */ - for (brush = main->brush.first; brush; brush = brush->id.next) { + for (Brush *brush = main->brush.first; brush; brush = brush->id.next) { if (brush->id.tag & LIB_TAG_NEED_LINK) { - brush->id.tag &= ~LIB_TAG_NEED_LINK; - + IDP_LibLinkProperty(brush->id.properties, fd); + /* brush->(mask_)mtex.obj is ignored on purpose? */ brush->mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mtex.tex); brush->mask_mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mask_mtex.tex); brush->clone.image = newlibadr(fd, brush->id.lib, brush->clone.image); brush->toggle_brush = newlibadr(fd, brush->id.lib, brush->toggle_brush); brush->paint_curve = newlibadr_us(fd, brush->id.lib, brush->paint_curve); + + brush->id.tag &= ~LIB_TAG_NEED_LINK; } } } @@ -2221,13 +2268,13 @@ static void direct_link_brush(FileData *fd, Brush *brush) } /* ************ READ Palette *************** */ -static void lib_link_palette(FileData *UNUSED(fd), Main *main) +static void lib_link_palette(FileData *fd, Main *main) { - Palette *palette; - /* only link ID pointers */ - for (palette = main->palettes.first; palette; palette = palette->id.next) { + for (Palette *palette = main->palettes.first; palette; palette = palette->id.next) { if (palette->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(palette->id.properties, fd); + palette->id.tag &= ~LIB_TAG_NEED_LINK; } } @@ -2239,13 +2286,13 @@ static void direct_link_palette(FileData *fd, Palette *palette) link_list(fd, &palette->colors); } -static void lib_link_paint_curve(FileData *UNUSED(fd), Main *main) +static void lib_link_paint_curve(FileData *fd, Main *main) { - PaintCurve *pc; - /* only link ID pointers */ - for (pc = main->paintcurves.first; pc; pc = pc->id.next) { + for (PaintCurve *pc = main->paintcurves.first; pc; pc = pc->id.next) { if (pc->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(pc->id.properties, fd); + pc->id.tag &= ~LIB_TAG_NEED_LINK; } } @@ -2497,15 +2544,12 @@ static void direct_link_fcurves(FileData *fd, ListBase *list) static void lib_link_action(FileData *fd, Main *main) { - bAction *act; - bActionChannel *chan; - - for (act = main->action.first; act; act = act->id.next) { + for (bAction *act = main->action.first; act; act = act->id.next) { if (act->id.tag & LIB_TAG_NEED_LINK) { - act->id.tag &= ~LIB_TAG_NEED_LINK; + IDP_LibLinkProperty(act->id.properties, fd); // XXX deprecated - old animation system <<< - for (chan=act->chanbase.first; chan; chan=chan->next) { + for (bActionChannel *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); } @@ -2518,6 +2562,8 @@ static void lib_link_action(FileData *fd, Main *main) marker->camera = newlibadr(fd, act->id.lib, marker->camera); } } + + act->id.tag &= ~LIB_TAG_NEED_LINK; } } } @@ -2704,26 +2750,20 @@ static void direct_link_animdata(FileData *fd, AnimData *adt) static void lib_link_cachefiles(FileData *fd, Main *bmain) { - CacheFile *cache_file; - /* only link ID pointers */ - for (cache_file = bmain->cachefiles.first; cache_file; cache_file = cache_file->id.next) { + for (CacheFile *cache_file = bmain->cachefiles.first; cache_file; cache_file = cache_file->id.next) { if (cache_file->id.tag & LIB_TAG_NEED_LINK) { - cache_file->id.tag &= ~LIB_TAG_NEED_LINK; - } - - BLI_listbase_clear(&cache_file->object_paths); - cache_file->handle = NULL; - cache_file->handle_mutex = NULL; - - if (cache_file->adt) { + IDP_LibLinkProperty(cache_file->id.properties, fd); lib_link_animdata(fd, &cache_file->id, cache_file->adt); + + cache_file->id.tag &= ~LIB_TAG_NEED_LINK; } } } static void direct_link_cachefile(FileData *fd, CacheFile *cache_file) { + BLI_listbase_clear(&cache_file->object_paths); cache_file->handle = NULL; cache_file->handle_mutex = NULL; @@ -2747,19 +2787,13 @@ static void direct_link_motionpath(FileData *fd, bMotionPath *mpath) /* ************ READ NODE TREE *************** */ -static void lib_link_node_socket(FileData *fd, ID *UNUSED(id), bNodeSocket *sock) -{ - /* Link ID Properties -- and copy this comment EXACTLY for easy finding - * of library blocks that implement this.*/ - IDP_LibLinkProperty(sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); -} - /* Single node tree (also used for material/scene trees), ntree is not NULL */ static void lib_link_ntree(FileData *fd, ID *id, bNodeTree *ntree) { bNode *node; bNodeSocket *sock; + IDP_LibLinkProperty(ntree->id.properties, fd); lib_link_animdata(fd, &ntree->id, ntree->adt); ntree->gpd = newlibadr_us(fd, id->lib, ntree->gpd); @@ -2767,32 +2801,35 @@ static void lib_link_ntree(FileData *fd, ID *id, bNodeTree *ntree) for (node = ntree->nodes.first; node; node = node->next) { /* Link ID Properties -- and copy this comment EXACTLY for easy finding * of library blocks that implement this.*/ - IDP_LibLinkProperty(node->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + IDP_LibLinkProperty(node->prop, fd); - node->id= newlibadr_us(fd, id->lib, node->id); + node->id = newlibadr_us(fd, id->lib, node->id); - for (sock = node->inputs.first; sock; sock = sock->next) - lib_link_node_socket(fd, id, sock); - for (sock = node->outputs.first; sock; sock = sock->next) - lib_link_node_socket(fd, id, sock); + for (sock = node->inputs.first; sock; sock = sock->next) { + IDP_LibLinkProperty(sock->prop, fd); + } + for (sock = node->outputs.first; sock; sock = sock->next) { + IDP_LibLinkProperty(sock->prop, fd); + } } - for (sock = ntree->inputs.first; sock; sock = sock->next) - lib_link_node_socket(fd, id, sock); - for (sock = ntree->outputs.first; sock; sock = sock->next) - lib_link_node_socket(fd, id, sock); + for (sock = ntree->inputs.first; sock; sock = sock->next) { + IDP_LibLinkProperty(sock->prop, fd); + } + for (sock = ntree->outputs.first; sock; sock = sock->next) { + IDP_LibLinkProperty(sock->prop, fd); + } } /* library ntree linking after fileread */ static void lib_link_nodetree(FileData *fd, Main *main) { - bNodeTree *ntree; - /* only link ID pointers */ - for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) { + for (bNodeTree *ntree = main->nodetree.first; ntree; ntree = ntree->id.next) { if (ntree->id.tag & LIB_TAG_NEED_LINK) { - ntree->id.tag &= ~LIB_TAG_NEED_LINK; lib_link_ntree(fd, &ntree->id, ntree); + + ntree->id.tag &= ~LIB_TAG_NEED_LINK; } } } @@ -3083,7 +3120,7 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) else if (ntree->type==NTREE_COMPOSIT) { if (ELEM(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) direct_link_curvemapping(fd, node->storage); - else if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) + else if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_R_LAYERS, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) ((ImageUser *)node->storage)->ok = 1; } else if ( ntree->type==NTREE_TEXTURE) { @@ -3238,6 +3275,11 @@ static void direct_link_constraints(FileData *fd, ListBase *lb) con->flag |= CONSTRAINT_SPACEONCE; break; } + case CONSTRAINT_TYPE_TRANSFORM_CACHE: + { + bTransformCacheConstraint *data = con->data; + data->reader = NULL; + } } } } @@ -3280,6 +3322,8 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose) pchan->bone = BLI_ghash_lookup(bone_hash, pchan->name); + IDP_LibLinkProperty(pchan->prop, fd); + pchan->custom = newlibadr_us(fd, arm->id.lib, pchan->custom); if (UNLIKELY(pchan->bone == NULL)) { rebuild = true; @@ -3300,13 +3344,26 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose) } } +static void lib_link_bones(FileData *fd, Bone *bone) +{ + IDP_LibLinkProperty(bone->prop, fd); + + for (Bone *curbone = bone->childbase.first; curbone; curbone = curbone->next) { + lib_link_bones(fd, curbone); + } +} + static void lib_link_armature(FileData *fd, Main *main) { - bArmature *arm; - - for (arm = main->armature.first; arm; arm = arm->id.next) { + for (bArmature *arm = main->armature.first; arm; arm = arm->id.next) { if (arm->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(arm->id.properties, fd); lib_link_animdata(fd, &arm->id, arm->adt); + + for (Bone *curbone = arm->bonebase.first; curbone; curbone = curbone->next) { + lib_link_bones(fd, curbone); + } + arm->id.tag &= ~LIB_TAG_NEED_LINK; } } @@ -3351,14 +3408,13 @@ static void direct_link_armature(FileData *fd, bArmature *arm) static void lib_link_camera(FileData *fd, Main *main) { - Camera *ca; - - for (ca = main->camera.first; ca; ca = ca->id.next) { + for (Camera *ca = main->camera.first; ca; ca = ca->id.next) { if (ca->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(ca->id.properties, fd); lib_link_animdata(fd, &ca->id, ca->adt); ca->ipo = newlibadr_us(fd, ca->id.lib, ca->ipo); // XXX deprecated - old animation system - + ca->dof_ob = newlibadr(fd, ca->id.lib, ca->dof_ob); ca->id.tag &= ~LIB_TAG_NEED_LINK; @@ -3377,16 +3433,13 @@ static void direct_link_camera(FileData *fd, Camera *ca) static void lib_link_lamp(FileData *fd, Main *main) { - Lamp *la; - MTex *mtex; - int a; - - for (la = main->lamp.first; la; la = la->id.next) { + for (Lamp *la = main->lamp.first; la; la = la->id.next) { if (la->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(la->id.properties, fd); lib_link_animdata(fd, &la->id, la->adt); - for (a = 0; a < MAX_MTEX; a++) { - mtex = la->mtex[a]; + for (int a = 0; a < MAX_MTEX; a++) { + MTex *mtex = la->mtex[a]; if (mtex) { mtex->tex = newlibadr_us(fd, la->id.lib, mtex->tex); mtex->object = newlibadr(fd, la->id.lib, mtex->object); @@ -3443,17 +3496,11 @@ void blo_do_versions_key_uidgen(Key *key) static void lib_link_key(FileData *fd, Main *main) { - Key *key; - - for (key = main->key.first; key; key = key->id.next) { - /*check if we need to generate unique ids for the shapekeys*/ - if (!key->uidgen) { - blo_do_versions_key_uidgen(key); - } - + for (Key *key = main->key.first; key; key = key->id.next) { BLI_assert((key->id.tag & LIB_TAG_EXTERN) == 0); if (key->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(key->id.properties, fd); lib_link_animdata(fd, &key->id, key->adt); key->ipo = newlibadr_us(fd, key->id.lib, key->ipo); // XXX deprecated - old animation system @@ -3516,15 +3563,14 @@ static void direct_link_key(FileData *fd, Key *key) static void lib_link_mball(FileData *fd, Main *main) { - MetaBall *mb; - int a; - - for (mb = main->mball.first; mb; mb = mb->id.next) { + for (MetaBall *mb = main->mball.first; mb; mb = mb->id.next) { if (mb->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(mb->id.properties, fd); lib_link_animdata(fd, &mb->id, mb->adt); - for (a = 0; a < mb->totcol; a++) + for (int a = 0; a < mb->totcol; a++) { mb->mat[a] = newlibadr_us(fd, mb->id.lib, mb->mat[a]); + } mb->ipo = newlibadr_us(fd, mb->id.lib, mb->ipo); // XXX deprecated - old animation system @@ -3553,18 +3599,15 @@ static void direct_link_mball(FileData *fd, MetaBall *mb) static void lib_link_world(FileData *fd, Main *main) { - World *wrld; - MTex *mtex; - int a; - - for (wrld = main->world.first; wrld; wrld = wrld->id.next) { + for (World *wrld = main->world.first; wrld; wrld = wrld->id.next) { if (wrld->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(wrld->id.properties, fd); lib_link_animdata(fd, &wrld->id, wrld->adt); wrld->ipo = newlibadr_us(fd, wrld->id.lib, wrld->ipo); // XXX deprecated - old animation system - for (a=0; a < MAX_MTEX; a++) { - mtex = wrld->mtex[a]; + for (int a = 0; a < MAX_MTEX; a++) { + MTex *mtex = wrld->mtex[a]; if (mtex) { mtex->tex = newlibadr_us(fd, wrld->id.lib, mtex->tex); mtex->object = newlibadr(fd, wrld->id.lib, mtex->object); @@ -3605,12 +3648,12 @@ static void direct_link_world(FileData *fd, World *wrld) /* ************ READ VFONT ***************** */ -static void lib_link_vfont(FileData *UNUSED(fd), Main *main) +static void lib_link_vfont(FileData *fd, Main *main) { - VFont *vf; - - for (vf = main->vfont.first; vf; vf = vf->id.next) { + for (VFont *vf = main->vfont.first; vf; vf = vf->id.next) { if (vf->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(vf->id.properties, fd); + vf->id.tag &= ~LIB_TAG_NEED_LINK; } } @@ -3625,12 +3668,12 @@ static void direct_link_vfont(FileData *fd, VFont *vf) /* ************ READ TEXT ****************** */ -static void lib_link_text(FileData *UNUSED(fd), Main *main) +static void lib_link_text(FileData *fd, Main *main) { - Text *text; - - for (text = main->text.first; text; text = text->id.next) { + for (Text *text = main->text.first; text; text = text->id.next) { if (text->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(text->id.properties, fd); + text->id.tag &= ~LIB_TAG_NEED_LINK; } } @@ -3679,11 +3722,9 @@ static void direct_link_text(FileData *fd, Text *text) static void lib_link_image(FileData *fd, Main *main) { - Image *ima; - - for (ima = main->image.first; ima; ima = ima->id.next) { + for (Image *ima = main->image.first; ima; ima = ima->id.next) { if (ima->id.tag & LIB_TAG_NEED_LINK) { - IDP_LibLinkProperty(ima->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + IDP_LibLinkProperty(ima->id.properties, fd); ima->id.tag &= ~LIB_TAG_NEED_LINK; } @@ -3748,15 +3789,14 @@ static void direct_link_image(FileData *fd, Image *ima) static void lib_link_curve(FileData *fd, Main *main) { - Curve *cu; - int a; - - for (cu = main->curve.first; cu; cu = cu->id.next) { + for (Curve *cu = main->curve.first; cu; cu = cu->id.next) { if (cu->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(cu->id.properties, fd); lib_link_animdata(fd, &cu->id, cu->adt); - for (a = 0; a < cu->totcol; a++) + for (int a = 0; a < cu->totcol; a++) { cu->mat[a] = newlibadr_us(fd, cu->id.lib, cu->mat[a]); + } cu->bevobj = newlibadr(fd, cu->id.lib, cu->bevobj); cu->taperobj = newlibadr(fd, cu->id.lib, cu->taperobj); @@ -3841,10 +3881,9 @@ static void direct_link_curve(FileData *fd, Curve *cu) static void lib_link_texture(FileData *fd, Main *main) { - Tex *tex; - - for (tex = main->tex.first; tex; tex = tex->id.next) { + for (Tex *tex = main->tex.first; tex; tex = tex->id.next) { if (tex->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(tex->id.properties, fd); lib_link_animdata(fd, &tex->id, tex->adt); tex->ima = newlibadr_us(fd, tex->id.lib, tex->ima); @@ -3920,23 +3959,20 @@ static void direct_link_texture(FileData *fd, Tex *tex) static void lib_link_material(FileData *fd, Main *main) { - Material *ma; - MTex *mtex; - int a; - - for (ma = main->mat.first; ma; ma = ma->id.next) { + for (Material *ma = main->mat.first; ma; ma = ma->id.next) { if (ma->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(ma->id.properties, fd); lib_link_animdata(fd, &ma->id, ma->adt); /* Link ID Properties -- and copy this comment EXACTLY for easy finding * of library blocks that implement this.*/ - IDP_LibLinkProperty(ma->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + IDP_LibLinkProperty(ma->id.properties, fd); ma->ipo = newlibadr_us(fd, ma->id.lib, ma->ipo); // XXX deprecated - old animation system ma->group = newlibadr_us(fd, ma->id.lib, ma->group); - for (a = 0; a < MAX_MTEX; a++) { - mtex = ma->mtex[a]; + for (int a = 0; a < MAX_MTEX; a++) { + MTex *mtex = ma->mtex[a]; if (mtex) { mtex->tex = newlibadr_us(fd, ma->id.lib, mtex->tex); mtex->object = newlibadr(fd, ma->id.lib, mtex->object); @@ -4067,14 +4103,11 @@ static void lib_link_partdeflect(FileData *fd, ID *id, PartDeflect *pd) static void lib_link_particlesettings(FileData *fd, Main *main) { - ParticleSettings *part; - ParticleDupliWeight *dw; - MTex *mtex; - int a; - - for (part = main->particle.first; part; part = part->id.next) { + for (ParticleSettings *part = main->particle.first; part; part = part->id.next) { if (part->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(part->id.properties, fd); lib_link_animdata(fd, &part->id, part->adt); + part->ipo = newlibadr_us(fd, part->id.lib, part->ipo); // XXX deprecated - old animation system part->dup_ob = newlibadr(fd, part->id.lib, part->dup_ob); @@ -4094,6 +4127,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main) } if (part->dupliweights.first && part->dup_group) { + ParticleDupliWeight *dw; int index_ok = 0; /* check for old files without indices (all indexes 0) */ if (BLI_listbase_is_single(&part->dupliweights)) { @@ -4158,8 +4192,8 @@ static void lib_link_particlesettings(FileData *fd, Main *main) } } - for (a = 0; a < MAX_MTEX; a++) { - mtex= part->mtex[a]; + for (int a = 0; a < MAX_MTEX; a++) { + MTex *mtex= part->mtex[a]; if (mtex) { mtex->tex = newlibadr_us(fd, part->id.lib, mtex->tex); mtex->object = newlibadr(fd, part->id.lib, mtex->object); @@ -4393,7 +4427,7 @@ static void lib_link_mesh(FileData *fd, Main *main) /* Link ID Properties -- and copy this comment EXACTLY for easy finding * of library blocks that implement this.*/ - IDP_LibLinkProperty(me->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + IDP_LibLinkProperty(me->id.properties, fd); lib_link_animdata(fd, &me->id, me->adt); /* this check added for python created meshes */ @@ -4666,10 +4700,9 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) static void lib_link_latt(FileData *fd, Main *main) { - Lattice *lt; - - for (lt = main->latt.first; lt; lt = lt->id.next) { + for (Lattice *lt = main->latt.first; lt; lt = lt->id.next) { if (lt->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(lt->id.properties, fd); lib_link_animdata(fd, <->id, lt->adt); lt->ipo = newlibadr_us(fd, lt->id.lib, lt->ipo); // XXX deprecated - old animation system @@ -4697,12 +4730,12 @@ static void direct_link_latt(FileData *fd, Lattice *lt) /* ************ READ OBJECT ***************** */ static void lib_link_modifiers__linkModifiers( - void *userData, Object *ob, ID **idpoin, int cd_flag) + void *userData, Object *ob, ID **idpoin, int cb_flag) { FileData *fd = userData; *idpoin = newlibadr(fd, ob->id.lib, *idpoin); - if (*idpoin != NULL && (cd_flag & IDWALK_USER) != 0) { + if (*idpoin != NULL && (cb_flag & IDWALK_CB_USER) != 0) { id_us_plus_no_lib(*idpoin); } } @@ -4713,17 +4746,13 @@ static void lib_link_modifiers(FileData *fd, Object *ob) static void lib_link_object(FileData *fd, Main *main) { - Object *ob; - PartEff *paf; - bSensor *sens; - bController *cont; - bActuator *act; - void *poin; - int warn=0, a; - - for (ob = main->object.first; ob; ob = ob->id.next) { + bool warn = false; + + for (Object *ob = main->object.first; ob; ob = ob->id.next) { if (ob->id.tag & LIB_TAG_NEED_LINK) { - IDP_LibLinkProperty(ob->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + int a; + + IDP_LibLinkProperty(ob->id.properties, fd); lib_link_animdata(fd, &ob->id, ob->adt); // XXX deprecated - old animation system <<< @@ -4755,17 +4784,17 @@ static void lib_link_object(FileData *fd, Main *main) } ob->proxy_group = newlibadr(fd, ob->id.lib, ob->proxy_group); - poin = ob->data; + void *poin = ob->data; ob->data = newlibadr_us(fd, ob->id.lib, ob->data); - if (ob->data==NULL && poin!=NULL) { + if (ob->data == NULL && poin != NULL) { if (ob->id.lib) printf("Can't find obdata of %s lib %s\n", ob->id.name + 2, ob->id.lib->name); else printf("Object %s lost data.\n", ob->id.name + 2); ob->type = OB_EMPTY; - warn = 1; + warn = true; if (ob->pose) { /* we can't call #BKE_pose_free() here because of library linking @@ -4811,13 +4840,13 @@ static void lib_link_object(FileData *fd, Main *main) lib_link_nlastrips(fd, &ob->id, &ob->nlastrips); // >>> XXX deprecated - old animation system - for (paf = ob->effect.first; paf; paf = paf->next) { + for (PartEff *paf = ob->effect.first; paf; paf = paf->next) { if (paf->type == EFF_PARTICLE) { paf->group = newlibadr_us(fd, ob->id.lib, paf->group); } } - for (sens = ob->sensors.first; sens; sens = sens->next) { + for (bSensor *sens = ob->sensors.first; sens; sens = sens->next) { for (a = 0; a < sens->totlinks; a++) sens->links[a] = newglobadr(fd, sens->links[a]); @@ -4828,7 +4857,7 @@ static void lib_link_object(FileData *fd, Main *main) } } - for (cont = ob->controllers.first; cont; cont = cont->next) { + for (bController *cont = ob->controllers.first; cont; cont = cont->next) { for (a=0; a < cont->totlinks; a++) cont->links[a] = newglobadr(fd, cont->links[a]); @@ -4840,86 +4869,117 @@ static void lib_link_object(FileData *fd, Main *main) cont->totslinks = 0; } - for (act = ob->actuators.first; act; act = act->next) { - if (act->type == ACT_SOUND) { - bSoundActuator *sa = act->data; - sa->sound= newlibadr_us(fd, ob->id.lib, sa->sound); - } - else if (act->type == ACT_GAME) { - /* bGameActuator *ga= act->data; */ - } - else if (act->type == ACT_CAMERA) { - bCameraActuator *ca = act->data; - ca->ob= newlibadr(fd, ob->id.lib, ca->ob); - } - /* leave this one, it's obsolete but necessary to read for conversion */ - else if (act->type == ACT_ADD_OBJECT) { - bAddObjectActuator *eoa = act->data; - if (eoa) eoa->ob= newlibadr(fd, ob->id.lib, eoa->ob); - } - else if (act->type == ACT_OBJECT) { - bObjectActuator *oa = act->data; - if (oa == NULL) { - init_actuator(act); + for (bActuator *act = ob->actuators.first; act; act = act->next) { + switch (act->type) { + case ACT_SOUND: + { + bSoundActuator *sa = act->data; + sa->sound = newlibadr_us(fd, ob->id.lib, sa->sound); + break; } - else { - oa->reference = newlibadr(fd, ob->id.lib, oa->reference); + case ACT_GAME: + /* bGameActuator *ga= act->data; */ + break; + case ACT_CAMERA: + { + bCameraActuator *ca = act->data; + ca->ob = newlibadr(fd, ob->id.lib, ca->ob); + break; } - } - else if (act->type == ACT_EDIT_OBJECT) { - bEditObjectActuator *eoa = act->data; - if (eoa == NULL) { - init_actuator(act); + /* leave this one, it's obsolete but necessary to read for conversion */ + case ACT_ADD_OBJECT: + { + bAddObjectActuator *eoa = act->data; + if (eoa) + eoa->ob = newlibadr(fd, ob->id.lib, eoa->ob); + break; } - else { - eoa->ob= newlibadr(fd, ob->id.lib, eoa->ob); - eoa->me= newlibadr(fd, ob->id.lib, eoa->me); + case ACT_OBJECT: + { + bObjectActuator *oa = act->data; + if (oa == NULL) { + init_actuator(act); + } + else { + oa->reference = newlibadr(fd, ob->id.lib, oa->reference); + } + break; } - } - else if (act->type == ACT_SCENE) { - bSceneActuator *sa = act->data; - sa->camera= newlibadr(fd, ob->id.lib, sa->camera); - sa->scene= newlibadr(fd, ob->id.lib, sa->scene); - } - else if (act->type == ACT_ACTION) { - bActionActuator *aa = act->data; - aa->act= newlibadr_us(fd, ob->id.lib, aa->act); - } - else if (act->type == ACT_SHAPEACTION) { - bActionActuator *aa = act->data; - aa->act= newlibadr_us(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); - } - else if (act->type == ACT_MESSAGE) { - 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; */ - } - else if (act->type == ACT_ARMATURE) { - bArmatureActuator *arma= act->data; - arma->target= newlibadr(fd, ob->id.lib, arma->target); - arma->subtarget= newlibadr(fd, ob->id.lib, arma->subtarget); - } - else if (act->type == ACT_STEERING) { - bSteeringActuator *steeringa = act->data; - steeringa->target = newlibadr(fd, ob->id.lib, steeringa->target); - steeringa->navmesh = newlibadr(fd, ob->id.lib, steeringa->navmesh); - } - else if (act->type == ACT_MOUSE) { - /* bMouseActuator *moa= act->data; */ + case ACT_EDIT_OBJECT: + { + bEditObjectActuator *eoa = act->data; + if (eoa == NULL) { + init_actuator(act); + } + else { + eoa->ob = newlibadr(fd, ob->id.lib, eoa->ob); + eoa->me = newlibadr(fd, ob->id.lib, eoa->me); + } + break; + } + case ACT_SCENE: + { + bSceneActuator *sa = act->data; + sa->camera = newlibadr(fd, ob->id.lib, sa->camera); + sa->scene = newlibadr(fd, ob->id.lib, sa->scene); + break; + } + case ACT_ACTION: + { + bActionActuator *aa = act->data; + aa->act = newlibadr_us(fd, ob->id.lib, aa->act); + break; + } + case ACT_SHAPEACTION: + { + bActionActuator *aa = act->data; + aa->act = newlibadr_us(fd, ob->id.lib, aa->act); + break; + } + case ACT_PROPERTY: + { + bPropertyActuator *pa = act->data; + pa->ob = newlibadr(fd, ob->id.lib, pa->ob); + break; + } + case ACT_MESSAGE: + { + bMessageActuator *ma = act->data; + ma->toObject = newlibadr(fd, ob->id.lib, ma->toObject); + break; + } + case ACT_2DFILTER: + { + bTwoDFilterActuator *_2dfa = act->data; + _2dfa->text = newlibadr(fd, ob->id.lib, _2dfa->text); + break; + } + case ACT_PARENT: + { + bParentActuator *parenta = act->data; + parenta->ob = newlibadr(fd, ob->id.lib, parenta->ob); + break; + } + case ACT_STATE: + /* bStateActuator *statea = act->data; */ + break; + case ACT_ARMATURE: + { + bArmatureActuator *arma= act->data; + arma->target = newlibadr(fd, ob->id.lib, arma->target); + arma->subtarget = newlibadr(fd, ob->id.lib, arma->subtarget); + break; + } + case ACT_STEERING: + { + bSteeringActuator *steeringa = act->data; + steeringa->target = newlibadr(fd, ob->id.lib, steeringa->target); + steeringa->navmesh = newlibadr(fd, ob->id.lib, steeringa->navmesh); + break; + } + case ACT_MOUSE: + /* bMouseActuator *moa = act->data; */ + break; } } @@ -5302,6 +5362,41 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) csmd->delta_cache = NULL; csmd->delta_cache_num = 0; } + else if (md->type == eModifierType_MeshSequenceCache) { + MeshSeqCacheModifierData *msmcd = (MeshSeqCacheModifierData *)md; + msmcd->reader = NULL; + } + else if (md->type == eModifierType_SurfaceDeform) { + SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; + + smd->verts = newdataadr(fd, smd->verts); + + if (smd->verts) { + for (int i = 0; i < smd->numverts; i++) { + smd->verts[i].binds = newdataadr(fd, smd->verts[i].binds); + + if (smd->verts[i].binds) { + for (int j = 0; j < smd->verts[i].numbinds; j++) { + smd->verts[i].binds[j].vert_inds = newdataadr(fd, smd->verts[i].binds[j].vert_inds); + smd->verts[i].binds[j].vert_weights = newdataadr(fd, smd->verts[i].binds[j].vert_weights); + + if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) { + if (smd->verts[i].binds[j].vert_inds) + BLI_endian_switch_uint32_array(smd->verts[i].binds[j].vert_inds, smd->verts[i].binds[j].numverts); + + if (smd->verts[i].binds[j].vert_weights) { + if (smd->verts[i].binds[j].mode == MOD_SDEF_MODE_CENTROID || + smd->verts[i].binds[j].mode == MOD_SDEF_MODE_LOOPTRI) + BLI_endian_switch_float_array(smd->verts[i].binds[j].vert_weights, 3); + else + BLI_endian_switch_float_array(smd->verts[i].binds[j].vert_weights, smd->verts[i].binds[j].numverts); + } + } + } + } + } + } + } } } @@ -5616,23 +5711,16 @@ static bool scene_validate_setscene__liblink(Scene *sce, const int totscene) static void lib_link_scene(FileData *fd, Main *main) { - Scene *sce; - Base *base, *next; - Sequence *seq; - SceneRenderLayer *srl; - FreestyleModuleConfig *fmc; - FreestyleLineSet *fls; - #ifdef USE_SETSCENE_CHECK bool need_check_set = false; int totscene = 0; #endif - for (sce = main->scene.first; sce; sce = sce->id.next) { + for (Scene *sce = main->scene.first; sce; sce = sce->id.next) { if (sce->id.tag & LIB_TAG_NEED_LINK) { /* Link ID Properties -- and copy this comment EXACTLY for easy finding * of library blocks that implement this.*/ - IDP_LibLinkProperty(sce->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + IDP_LibLinkProperty(sce->id.properties, fd); lib_link_animdata(fd, &sce->id, sce->adt); lib_link_keyingsets(fd, &sce->id, &sce->keyingsets); @@ -5668,7 +5756,7 @@ static void lib_link_scene(FileData *fd, Main *main) sce->toolsettings->particle.shape_object = newlibadr(fd, sce->id.lib, sce->toolsettings->particle.shape_object); - for (base = sce->base.first; base; base = next) { + for (Base *next, *base = sce->base.first; base; base = next) { next = base->next; base->object = newlibadr_us(fd, sce->id.lib, base->object); @@ -5682,8 +5770,11 @@ static void lib_link_scene(FileData *fd, Main *main) } } + Sequence *seq; SEQ_BEGIN (sce->ed, seq) { + IDP_LibLinkProperty(seq->prop, fd); + if (seq->ipo) seq->ipo = newlibadr_us(fd, sce->id.lib, seq->ipo); // XXX deprecated - old animation system seq->scene_sound = NULL; if (seq->scene) { @@ -5747,13 +5838,13 @@ static void lib_link_scene(FileData *fd, Main *main) composite_patch(sce->nodetree, sce); } - for (srl = sce->r.layers.first; srl; srl = srl->next) { + for (SceneRenderLayer *srl = sce->r.layers.first; srl; srl = srl->next) { srl->mat_override = newlibadr_us(fd, sce->id.lib, srl->mat_override); srl->light_override = newlibadr_us(fd, sce->id.lib, srl->light_override); - for (fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) { + for (FreestyleModuleConfig *fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) { fmc->script = newlibadr(fd, sce->id.lib, fmc->script); } - for (fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) { + for (FreestyleLineSet *fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) { fls->linestyle = newlibadr_us(fd, sce->id.lib, fls->linestyle); fls->group = newlibadr_us(fd, sce->id.lib, fls->group); } @@ -5787,7 +5878,7 @@ static void lib_link_scene(FileData *fd, Main *main) #ifdef USE_SETSCENE_CHECK if (need_check_set) { - for (sce = main->scene.first; sce; sce = sce->id.next) { + for (Scene *sce = main->scene.first; sce; sce = sce->id.next) { if (sce->id.tag & LIB_TAG_NEED_LINK) { sce->id.tag &= ~LIB_TAG_NEED_LINK; if (!scene_validate_setscene__liblink(sce, totscene)) { @@ -5912,16 +6003,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->toolsettings->particle.scene = NULL; sce->toolsettings->particle.object = NULL; sce->toolsettings->gp_sculpt.paintcursor = NULL; - - /* in rare cases this is needed, see [#33806] */ - if (sce->toolsettings->vpaint) { - sce->toolsettings->vpaint->vpaint_prev = NULL; - sce->toolsettings->vpaint->tot = 0; - } - if (sce->toolsettings->wpaint) { - sce->toolsettings->wpaint->wpaint_prev = NULL; - sce->toolsettings->wpaint->tot = 0; - } + /* relink grease pencil drawing brushes */ link_list(fd, &sce->toolsettings->gp_brushes); for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) { @@ -5938,6 +6020,12 @@ static void direct_link_scene(FileData *fd, Scene *sce) direct_link_curvemapping(fd, brush->cur_jitter); } } + + /* relink grease pencil interpolation curves */ + sce->toolsettings->gp_interpolate.custom_ipo = newdataadr(fd, sce->toolsettings->gp_interpolate.custom_ipo); + if (sce->toolsettings->gp_interpolate.custom_ipo) { + direct_link_curvemapping(fd, sce->toolsettings->gp_interpolate.custom_ipo); + } } if (sce->ed) { @@ -5998,9 +6086,13 @@ static void direct_link_scene(FileData *fd, Scene *sce) seq->strip->transform = NULL; } if (seq->flag & SEQ_USE_PROXY) { - seq->strip->proxy = newdataadr( - fd, seq->strip->proxy); - seq->strip->proxy->anim = NULL; + seq->strip->proxy = newdataadr(fd, seq->strip->proxy); + if (seq->strip->proxy) { + seq->strip->proxy->anim = NULL; + } + else { + BKE_sequencer_proxy_set(seq, true); + } } else { seq->strip->proxy = NULL; @@ -6060,11 +6152,6 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->r.avicodecdata->lpFormat = newdataadr(fd, sce->r.avicodecdata->lpFormat); sce->r.avicodecdata->lpParms = newdataadr(fd, sce->r.avicodecdata->lpParms); } - - sce->r.qtcodecdata = newdataadr(fd, sce->r.qtcodecdata); - 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); IDP_DirectLinkGroup_OrFree(&sce->r.ffcodecdata.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); @@ -6075,6 +6162,11 @@ static void direct_link_scene(FileData *fd, Scene *sce) link_list(fd, &(sce->r.layers)); link_list(fd, &(sce->r.views)); + + for (srl = sce->r.layers.first; srl; srl = srl->next) { + srl->prop = newdataadr(fd, srl->prop); + IDP_DirectLinkGroup_OrFree(&srl->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + } for (srl = sce->r.layers.first; srl; srl = srl->next) { link_list(fd, &(srl->freestyleConfig.modules)); } @@ -6190,8 +6282,10 @@ static void lib_link_windowmanager(FileData *fd, Main *main) for (wm = main->wm.first; wm; wm = wm->id.next) { if (wm->id.tag & LIB_TAG_NEED_LINK) { - for (win = wm->windows.first; win; win = win->next) + /* Note: WM IDProperties are never written to file, hence no need to read/link them here. */ + for (win = wm->windows.first; win; win = win->next) { win->screen = newlibadr(fd, NULL, win->screen); + } wm->id.tag &= ~LIB_TAG_NEED_LINK; } @@ -6203,13 +6297,12 @@ static void lib_link_windowmanager(FileData *fd, Main *main) /* relink's grease pencil data's refs */ static void lib_link_gpencil(FileData *fd, Main *main) { - bGPdata *gpd; - - for (gpd = main->gpencil.first; gpd; gpd = gpd->id.next) { + for (bGPdata *gpd = main->gpencil.first; gpd; gpd = gpd->id.next) { if (gpd->id.tag & LIB_TAG_NEED_LINK) { - gpd->id.tag &= ~LIB_TAG_NEED_LINK; - + IDP_LibLinkProperty(gpd->id.properties, fd); lib_link_animdata(fd, &gpd->id, gpd->adt); + + gpd->id.tag &= ~LIB_TAG_NEED_LINK; } } } @@ -6271,12 +6364,11 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd) * check lib pointers in call below */ static void lib_link_screen(FileData *fd, Main *main) { - bScreen *sc; - ScrArea *sa; - - for (sc = main->screen.first; sc; sc = sc->id.next) { + for (bScreen *sc = main->screen.first; sc; sc = sc->id.next) { if (sc->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(sc->id.properties, fd); id_us_ensure_real(&sc->id); + sc->scene = newlibadr(fd, sc->id.lib, sc->scene); /* this should not happen, but apparently it does somehow. Until we figure out the cause, @@ -6287,177 +6379,204 @@ static void lib_link_screen(FileData *fd, Main *main) sc->animtimer = NULL; /* saved in rare cases */ sc->scrubbing = false; - for (sa = sc->areabase.first; sa; sa = sa->next) { - SpaceLink *sl; - + for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { sa->full = newlibadr(fd, sc->id.lib, sa->full); - for (sl = sa->spacedata.first; sl; sl= sl->next) { - if (sl->spacetype == SPACE_VIEW3D) { - View3D *v3d = (View3D*) sl; - BGpic *bgpic = NULL; - - v3d->camera= newlibadr(fd, sc->id.lib, v3d->camera); - v3d->ob_centre= newlibadr(fd, sc->id.lib, v3d->ob_centre); - - /* should be do_versions but not easy adding into the listbase */ - if (v3d->bgpic) { - v3d->bgpic = newlibadr(fd, sc->id.lib, v3d->bgpic); - BLI_addtail(&v3d->bgpicbase, bgpic); - v3d->bgpic = NULL; + for (SpaceLink *sl = sa->spacedata.first; sl; sl= sl->next) { + switch (sl->spacetype) { + case SPACE_VIEW3D: + { + View3D *v3d = (View3D*) sl; + BGpic *bgpic = NULL; + + v3d->camera= newlibadr(fd, sc->id.lib, v3d->camera); + v3d->ob_centre= newlibadr(fd, sc->id.lib, v3d->ob_centre); + + /* should be do_versions but not easy adding into the listbase */ + if (v3d->bgpic) { + v3d->bgpic = newlibadr(fd, sc->id.lib, v3d->bgpic); + BLI_addtail(&v3d->bgpicbase, bgpic); + v3d->bgpic = NULL; + } + + for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { + bgpic->ima = newlibadr_us(fd, sc->id.lib, bgpic->ima); + bgpic->clip = newlibadr_us(fd, sc->id.lib, bgpic->clip); + } + if (v3d->localvd) { + v3d->localvd->camera = newlibadr(fd, sc->id.lib, v3d->localvd->camera); + } + break; } - - for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { - bgpic->ima = newlibadr_us(fd, sc->id.lib, bgpic->ima); - bgpic->clip = newlibadr_us(fd, sc->id.lib, bgpic->clip); + case SPACE_IPO: + { + SpaceIpo *sipo = (SpaceIpo *)sl; + bDopeSheet *ads = sipo->ads; + + if (ads) { + ads->source = newlibadr(fd, sc->id.lib, ads->source); + ads->filter_grp = newlibadr(fd, sc->id.lib, ads->filter_grp); + } + break; } - if (v3d->localvd) { - v3d->localvd->camera = newlibadr(fd, sc->id.lib, v3d->localvd->camera); + case SPACE_BUTS: + { + SpaceButs *sbuts = (SpaceButs *)sl; + sbuts->pinid = newlibadr(fd, sc->id.lib, sbuts->pinid); + if (sbuts->pinid == NULL) { + sbuts->flag &= ~SB_PIN_CONTEXT; + } + break; } - } - else if (sl->spacetype == SPACE_IPO) { - SpaceIpo *sipo = (SpaceIpo *)sl; - bDopeSheet *ads = sipo->ads; - - if (ads) { - ads->source = newlibadr(fd, sc->id.lib, ads->source); - ads->filter_grp = newlibadr(fd, sc->id.lib, ads->filter_grp); + case SPACE_FILE: + break; + case SPACE_ACTION: + { + SpaceAction *saction = (SpaceAction *)sl; + bDopeSheet *ads = &saction->ads; + + if (ads) { + ads->source = newlibadr(fd, sc->id.lib, ads->source); + ads->filter_grp = newlibadr(fd, sc->id.lib, ads->filter_grp); + } + + saction->action = newlibadr(fd, sc->id.lib, saction->action); + break; } - } - else if (sl->spacetype == SPACE_BUTS) { - SpaceButs *sbuts = (SpaceButs *)sl; - sbuts->pinid = newlibadr(fd, sc->id.lib, sbuts->pinid); - if (sbuts->pinid == NULL) { - sbuts->flag &= ~SB_PIN_CONTEXT; + case SPACE_IMAGE: + { + SpaceImage *sima = (SpaceImage *)sl; + + sima->image = newlibadr_real_us(fd, sc->id.lib, sima->image); + sima->mask_info.mask = newlibadr_real_us(fd, sc->id.lib, sima->mask_info.mask); + + /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data + * so fingers crossed this works fine! + */ + sima->gpd = newlibadr_us(fd, sc->id.lib, sima->gpd); + break; } - } - else if (sl->spacetype == SPACE_FILE) { - ; - } - else if (sl->spacetype == SPACE_ACTION) { - SpaceAction *saction = (SpaceAction *)sl; - bDopeSheet *ads = &saction->ads; - - if (ads) { - ads->source = newlibadr(fd, sc->id.lib, ads->source); - ads->filter_grp = newlibadr(fd, sc->id.lib, ads->filter_grp); + case SPACE_SEQ: + { + SpaceSeq *sseq = (SpaceSeq *)sl; + + /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data + * so fingers crossed this works fine! + */ + sseq->gpd = newlibadr_us(fd, sc->id.lib, sseq->gpd); + break; } - - saction->action = newlibadr(fd, sc->id.lib, saction->action); - } - else if (sl->spacetype == SPACE_IMAGE) { - SpaceImage *sima = (SpaceImage *)sl; - - sima->image = newlibadr_real_us(fd, sc->id.lib, sima->image); - sima->mask_info.mask = newlibadr_real_us(fd, sc->id.lib, sima->mask_info.mask); - - /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data - * so fingers crossed this works fine! - */ - sima->gpd = newlibadr_us(fd, sc->id.lib, sima->gpd); - } - else if (sl->spacetype == SPACE_SEQ) { - SpaceSeq *sseq = (SpaceSeq *)sl; - - /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data - * so fingers crossed this works fine! - */ - sseq->gpd = newlibadr_us(fd, sc->id.lib, sseq->gpd); + case SPACE_NLA: + { + SpaceNla *snla= (SpaceNla *)sl; + bDopeSheet *ads= snla->ads; + + if (ads) { + ads->source = newlibadr(fd, sc->id.lib, ads->source); + ads->filter_grp = newlibadr(fd, sc->id.lib, ads->filter_grp); + } + break; + } + case SPACE_TEXT: + { + SpaceText *st= (SpaceText *)sl; - } - else if (sl->spacetype == SPACE_NLA) { - SpaceNla *snla= (SpaceNla *)sl; - bDopeSheet *ads= snla->ads; - - if (ads) { - ads->source = newlibadr(fd, sc->id.lib, ads->source); - ads->filter_grp = newlibadr(fd, sc->id.lib, ads->filter_grp); + st->text= newlibadr(fd, sc->id.lib, st->text); + break; } - } - else if (sl->spacetype == SPACE_TEXT) { - SpaceText *st= (SpaceText *)sl; - - st->text= newlibadr(fd, sc->id.lib, st->text); - } - else if (sl->spacetype == SPACE_SCRIPT) { - 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); + case SPACE_SCRIPT: + { + SpaceScript *scpt = (SpaceScript *)sl; + /*scpt->script = NULL; - 2.45 set to null, better re-run the script */ if (scpt->script) { - SCRIPT_SET_NULL(scpt->script); + scpt->script = newlibadr(fd, sc->id.lib, scpt->script); + if (scpt->script) { + SCRIPT_SET_NULL(scpt->script); + } } + break; } - } - else if (sl->spacetype == SPACE_OUTLINER) { - SpaceOops *so= (SpaceOops *)sl; - so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id); - - if (so->treestore) { - TreeStoreElem *tselem; - BLI_mempool_iter iter; + case SPACE_OUTLINER: + { + SpaceOops *so= (SpaceOops *)sl; + so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id); + + if (so->treestore) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + tselem->id = newlibadr(fd, NULL, tselem->id); + } + if (so->treehash) { + /* rebuild hash table, because it depends on ids too */ + so->storeflag |= SO_TREESTORE_REBUILD; + } + } + break; + } + case SPACE_NODE: + { + SpaceNode *snode = (SpaceNode *)sl; + bNodeTreePath *path, *path_next; + bNodeTree *ntree; + + /* node tree can be stored locally in id too, link this first */ + snode->id = newlibadr(fd, sc->id.lib, snode->id); + snode->from = newlibadr(fd, sc->id.lib, snode->from); + + ntree = snode->id ? ntreeFromID(snode->id) : NULL; + snode->nodetree = ntree ? ntree : newlibadr_us(fd, sc->id.lib, snode->nodetree); + + for (path = snode->treepath.first; path; path = path->next) { + if (path == snode->treepath.first) { + /* first nodetree in path is same as snode->nodetree */ + path->nodetree = snode->nodetree; + } + else + path->nodetree = newlibadr_us(fd, sc->id.lib, path->nodetree); - BLI_mempool_iternew(so->treestore, &iter); - while ((tselem = BLI_mempool_iterstep(&iter))) { - tselem->id = newlibadr(fd, NULL, tselem->id); + if (!path->nodetree) + break; } - if (so->treehash) { - /* rebuild hash table, because it depends on ids too */ - so->storeflag |= SO_TREESTORE_REBUILD; + + /* remaining path entries are invalid, remove */ + for (; path; path = path_next) { + path_next = path->next; + + BLI_remlink(&snode->treepath, path); + MEM_freeN(path); } - } - } - else if (sl->spacetype == SPACE_NODE) { - SpaceNode *snode = (SpaceNode *)sl; - bNodeTreePath *path, *path_next; - bNodeTree *ntree; - - /* node tree can be stored locally in id too, link this first */ - snode->id = newlibadr(fd, sc->id.lib, snode->id); - snode->from = newlibadr(fd, sc->id.lib, snode->from); - - ntree = snode->id ? ntreeFromID(snode->id) : NULL; - snode->nodetree = ntree ? ntree : newlibadr_us(fd, sc->id.lib, snode->nodetree); - - for (path = snode->treepath.first; path; path = path->next) { - if (path == snode->treepath.first) { - /* first nodetree in path is same as snode->nodetree */ - path->nodetree = snode->nodetree; + + /* edittree is just the last in the path, + * set this directly since the path may have been shortened above */ + if (snode->treepath.last) { + path = snode->treepath.last; + snode->edittree = path->nodetree; } - else - path->nodetree = newlibadr_us(fd, sc->id.lib, path->nodetree); - - if (!path->nodetree) - break; + else { + snode->edittree = NULL; + } + break; } - - /* remaining path entries are invalid, remove */ - for (; path; path = path_next) { - path_next = path->next; - - BLI_remlink(&snode->treepath, path); - MEM_freeN(path); + case SPACE_CLIP: + { + SpaceClip *sclip = (SpaceClip *)sl; + + sclip->clip = newlibadr_real_us(fd, sc->id.lib, sclip->clip); + sclip->mask_info.mask = newlibadr_real_us(fd, sc->id.lib, sclip->mask_info.mask); + break; } - - /* edittree is just the last in the path, - * set this directly since the path may have been shortened above */ - if (snode->treepath.last) { - path = snode->treepath.last; - snode->edittree = path->nodetree; + case SPACE_LOGIC: + { + SpaceLogic *slogic = (SpaceLogic *)sl; + + slogic->gpd = newlibadr_us(fd, sc->id.lib, slogic->gpd); + break; } - else - snode->edittree = NULL; - } - else if (sl->spacetype == SPACE_CLIP) { - SpaceClip *sclip = (SpaceClip *)sl; - - sclip->clip = newlibadr_real_us(fd, sc->id.lib, sclip->clip); - sclip->mask_info.mask = newlibadr_real_us(fd, sc->id.lib, sclip->mask_info.mask); - } - else if (sl->spacetype == SPACE_LOGIC) { - SpaceLogic *slogic = (SpaceLogic *)sl; - - slogic->gpd = newlibadr_us(fd, sc->id.lib, slogic->gpd); + default: + break; } } } @@ -7331,13 +7450,13 @@ static void fix_relpaths_library(const char *basepath, Main *main) static void lib_link_speaker(FileData *fd, Main *main) { - Speaker *spk; - - for (spk = main->speaker.first; spk; spk = spk->id.next) { + for (Speaker *spk = main->speaker.first; spk; spk = spk->id.next) { if (spk->id.tag & LIB_TAG_NEED_LINK) { + IDP_LibLinkProperty(spk->id.properties, fd); lib_link_animdata(fd, &spk->id, spk->adt); spk->sound = newlibadr_us(fd, spk->id.lib, spk->sound); + spk->id.tag &= ~LIB_TAG_NEED_LINK; } } @@ -7387,14 +7506,15 @@ static void direct_link_sound(FileData *fd, bSound *sound) static void lib_link_sound(FileData *fd, Main *main) { - bSound *sound; - - for (sound = main->sound.first; sound; sound = sound->id.next) { + for (bSound *sound = main->sound.first; sound; sound = sound->id.next) { if (sound->id.tag & LIB_TAG_NEED_LINK) { - sound->id.tag &= ~LIB_TAG_NEED_LINK; + IDP_LibLinkProperty(sound->id.properties, fd); + sound->ipo = newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX deprecated - old animation system BKE_sound_load(main, sound); + + sound->id.tag &= ~LIB_TAG_NEED_LINK; } } } @@ -7409,17 +7529,13 @@ static void direct_link_group(FileData *fd, Group *group) static void lib_link_group(FileData *fd, Main *main) { - Group *group; - GroupObject *go; - bool add_us; - - for (group = main->group.first; group; group = group->id.next) { + for (Group *group = main->group.first; group; group = group->id.next) { if (group->id.tag & LIB_TAG_NEED_LINK) { - group->id.tag &= ~LIB_TAG_NEED_LINK; + IDP_LibLinkProperty(group->id.properties, fd); - add_us = false; + bool add_us = false; - for (go = group->gobject.first; go; go = go->next) { + for (GroupObject *go = group->gobject.first; go; go = go->next) { go->ob = newlibadr_real_us(fd, group->id.lib, go->ob); if (go->ob) { go->ob->flag |= OB_FROMGROUP; @@ -7431,6 +7547,8 @@ static void lib_link_group(FileData *fd, Main *main) id_us_ensure_real(&group->id); } BKE_group_object_unlink(group, NULL, NULL, NULL); /* removes NULL entries */ + + group->id.tag &= ~LIB_TAG_NEED_LINK; } } } @@ -7535,13 +7653,11 @@ static void lib_link_moviePlaneTracks(FileData *fd, MovieClip *clip, ListBase *t static void lib_link_movieclip(FileData *fd, Main *main) { - MovieClip *clip; - - for (clip = main->movieclip.first; clip; clip = clip->id.next) { + for (MovieClip *clip = main->movieclip.first; clip; clip = clip->id.next) { if (clip->id.tag & LIB_TAG_NEED_LINK) { MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *object; + IDP_LibLinkProperty(clip->id.properties, fd); lib_link_animdata(fd, &clip->id, clip->adt); clip->gpd = newlibadr_us(fd, clip->id.lib, clip->gpd); @@ -7549,7 +7665,7 @@ static void lib_link_movieclip(FileData *fd, Main *main) lib_link_movieTracks(fd, clip, &tracking->tracks); lib_link_moviePlaneTracks(fd, clip, &tracking->plane_tracks); - for (object = tracking->objects.first; object; object = object->next) { + for (MovieTrackingObject *object = tracking->objects.first; object; object = object->next) { lib_link_movieTracks(fd, clip, &object->tracks); lib_link_moviePlaneTracks(fd, clip, &object->plane_tracks); } @@ -7626,16 +7742,12 @@ static void lib_link_mask_parent(FileData *fd, Mask *mask, MaskParent *parent) static void lib_link_mask(FileData *fd, Main *main) { - Mask *mask; - - mask = main->mask.first; - while (mask) { + for (Mask *mask = main->mask.first; mask; mask = mask->id.next) { if (mask->id.tag & LIB_TAG_NEED_LINK) { - MaskLayer *masklay; - + IDP_LibLinkProperty(mask->id.properties, fd); lib_link_animdata(fd, &mask->id, mask->adt); - for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + for (MaskLayer *masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; spline = masklay->splines.first; @@ -7656,7 +7768,6 @@ static void lib_link_mask(FileData *fd, Main *main) mask->id.tag &= ~LIB_TAG_NEED_LINK; } - mask = mask->id.next; } } @@ -7664,18 +7775,13 @@ static void lib_link_mask(FileData *fd, Main *main) static void lib_link_linestyle(FileData *fd, Main *main) { - FreestyleLineStyle *linestyle; - LineStyleModifier *m; - MTex *mtex; - int a; - - linestyle = main->linestyle.first; - while (linestyle) { + for (FreestyleLineStyle *linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) { if (linestyle->id.tag & LIB_TAG_NEED_LINK) { - linestyle->id.tag &= ~LIB_TAG_NEED_LINK; + LineStyleModifier *m; - IDP_LibLinkProperty(linestyle->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + IDP_LibLinkProperty(linestyle->id.properties, fd); lib_link_animdata(fd, &linestyle->id, linestyle->adt); + for (m = linestyle->color_modifiers.first; m; m = m->next) { switch (m->type) { case LS_MODIFIER_DISTANCE_FROM_OBJECT: @@ -7706,8 +7812,8 @@ static void lib_link_linestyle(FileData *fd, Main *main) break; } } - for (a=0; a < MAX_MTEX; a++) { - mtex = linestyle->mtex[a]; + for (int a = 0; a < MAX_MTEX; a++) { + MTex *mtex = linestyle->mtex[a]; if (mtex) { mtex->tex = newlibadr_us(fd, linestyle->id.lib, mtex->tex); mtex->object = newlibadr(fd, linestyle->id.lib, mtex->object); @@ -7717,8 +7823,9 @@ static void lib_link_linestyle(FileData *fd, Main *main) lib_link_ntree(fd, &linestyle->id, linestyle->nodetree); linestyle->nodetree->id.lib = linestyle->id.lib; } + + linestyle->id.tag &= ~LIB_TAG_NEED_LINK; } - linestyle = linestyle->id.next; } } @@ -8102,12 +8209,16 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short id->lib = main->curlib; id->us = ID_FAKE_USERS(id); id->icon_id = 0; + id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */ /* this case cannot be direct_linked: it's just the ID part */ if (bhead->code == ID_ID) { return blo_nextbhead(fd, bhead); } - + + /* That way, we know which datablock needs do_versions (required currently for linking). */ + id->tag |= LIB_TAG_NEW; + /* need a name for the mallocN, just for debugging and sane prints on leaks */ allocname = dataname(GS(id->name)); @@ -8365,14 +8476,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* don't forget to set version number in BKE_blender_version.h! */ } -#if 0 // XXX: disabled for now... we still don't have this in the right place in the loading code for it to work -static void do_versions_after_linking(FileData *fd, Library *lib, Main *main) +static void do_versions_after_linking(Main *main) { - /* old Animation System (using IPO's) needs to be converted to the new Animato system */ - if (main->versionfile < 250) - do_versions_ipos_to_animato(main); +// printf("%s for %s (%s), %d.%d\n", __func__, main->curlib ? main->curlib->name : main->name, +// main->curlib ? "LIB" : "MAIN", main->versionfile, main->subversionfile); + + do_versions_after_linking_270(main); } -#endif static void lib_link_all(FileData *fd, Main *main) { @@ -8386,12 +8496,13 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_screen(fd, main); lib_link_scene(fd, main); lib_link_object(fd, main); + lib_link_mesh(fd, main); lib_link_curve(fd, main); lib_link_mball(fd, main); lib_link_material(fd, main); lib_link_texture(fd, main); lib_link_image(fd, main); - lib_link_ipo(fd, main); // XXX deprecated... still needs to be maintained for version patches still + lib_link_ipo(fd, main); /* XXX deprecated... still needs to be maintained for version patches still */ lib_link_key(fd, main); lib_link_world(fd, main); lib_link_lamp(fd, main); @@ -8404,7 +8515,7 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_armature(fd, main); lib_link_action(fd, main); lib_link_vfont(fd, main); - lib_link_nodetree(fd, main); /* has to be done after scene/materials, this will verify group nodes */ + lib_link_nodetree(fd, main); /* has to be done after scene/materials, this will verify group nodes */ lib_link_brush(fd, main); lib_link_palette(fd, main); lib_link_paint_curve(fd, main); @@ -8415,9 +8526,7 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_gpencil(fd, main); lib_link_cachefiles(fd, main); - lib_link_mesh(fd, main); /* as last: tpage images with users at zero */ - - lib_link_library(fd, main); /* only init users */ + lib_link_library(fd, main); /* only init users */ } static void direct_link_keymapitem(FileData *fd, wmKeyMapItem *kmi) @@ -8541,7 +8650,12 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) bhead = read_global(bfd, fd, bhead); break; case USER: - bhead = read_userdef(bfd, fd, bhead); + if (fd->skip_flags & BLO_READ_SKIP_USERDEF) { + bhead = blo_nextbhead(fd, bhead); + } + else { + bhead = read_userdef(bfd, fd, bhead); + } break; case ENDB: bhead = NULL; @@ -8550,15 +8664,25 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) case ID_ID: /* Always adds to the most recently loaded ID_LI block, see direct_link_library. * This is part of the file format definition. */ - bhead = read_libblock(fd, mainlist.last, bhead, LIB_TAG_READ | LIB_TAG_EXTERN, NULL); + if (fd->skip_flags & BLO_READ_SKIP_DATA) { + bhead = blo_nextbhead(fd, bhead); + } + else { + bhead = read_libblock(fd, mainlist.last, bhead, LIB_TAG_READ | LIB_TAG_EXTERN, NULL); + } break; - /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */ case ID_SCRN: bhead->code = ID_SCR; - /* deliberate pass on to default */ + /* pass on to default */ + ATTR_FALLTHROUGH; default: - bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, NULL); + if (fd->skip_flags & BLO_READ_SKIP_DATA) { + bhead = blo_nextbhead(fd, bhead); + } + else { + bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, NULL); + } } } @@ -8573,7 +8697,20 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) blo_join_main(&mainlist); lib_link_all(fd, bfd->main); - //do_versions_after_linking(fd, NULL, bfd->main); // XXX: not here (or even in this function at all)! this causes crashes on many files - Aligorith (July 04, 2010) + + /* Skip in undo case. */ + if (fd->memfile == NULL) { + /* Yep, second splitting... but this is a very cheap operation, so no big deal. */ + blo_split_main(&mainlist, bfd->main); + for (Main *mainvar = mainlist.first; mainvar; mainvar = mainvar->next) { + BLI_assert(mainvar->versionfile != 0); + do_versions_after_linking(mainvar); + } + blo_join_main(&mainlist); + } + + BKE_main_id_tag_all(bfd->main, LIB_TAG_NEW, false); + lib_verify_nodetree(bfd->main, true); fix_relpaths_library(fd->relabase, bfd->main); /* make all relative paths, relative to the open blend file */ @@ -8810,6 +8947,31 @@ static void expand_constraint_channels(FileData *fd, Main *mainvar, ListBase *ch } } +static void expand_idprops(FileData *fd, Main *mainvar, IDProperty *prop) +{ + if (!prop) + return; + + switch (prop->type) { + case IDP_ID: + expand_doit(fd, mainvar, IDP_Id(prop)); + break; + case IDP_IDPARRAY: + { + IDProperty *idp_array = IDP_IDPArray(prop); + for (int i = 0; i < prop->len; i++) { + expand_idprops(fd, mainvar, &idp_array[i]); + } + break; + } + case IDP_GROUP: + for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) { + expand_idprops(fd, mainvar, loop); + } + break; + } +} + static void expand_fmodifiers(FileData *fd, Main *mainvar, ListBase *list) { FModifier *fcm; @@ -8995,6 +9157,7 @@ static void expand_key(FileData *fd, Main *mainvar, Key *key) static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree) { bNode *node; + bNodeSocket *sock; if (ntree->adt) expand_animdata(fd, mainvar, ntree->adt); @@ -9003,10 +9166,22 @@ static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree) expand_doit(fd, mainvar, ntree->gpd); for (node = ntree->nodes.first; node; node = node->next) { - if (node->id && node->type != CMP_NODE_R_LAYERS) + if (node->id && node->type != CMP_NODE_R_LAYERS) { expand_doit(fd, mainvar, node->id); + } + + expand_idprops(fd, mainvar, node->prop); + + for (sock = node->inputs.first; sock; sock = sock->next) + expand_doit(fd, mainvar, sock->prop); + for (sock = node->outputs.first; sock; sock = sock->next) + expand_doit(fd, mainvar, sock->prop); } + for (sock = ntree->inputs.first; sock; sock = sock->next) + expand_doit(fd, mainvar, sock->prop); + for (sock = ntree->outputs.first; sock; sock = sock->next) + expand_doit(fd, mainvar, sock->prop); } static void expand_texture(FileData *fd, Main *mainvar, Tex *tex) @@ -9224,17 +9399,6 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb) } } -#if 0 /* Disabled as it doesn't actually do anything except recurse... */ -static void expand_bones(FileData *fd, Main *mainvar, Bone *bone) -{ - Bone *curBone; - - for (curBone = bone->childbase.first; curBone; curBone=curBone->next) { - expand_bones(fd, mainvar, curBone); - } -} -#endif - static void expand_pose(FileData *fd, Main *mainvar, bPose *pose) { bPoseChannel *chan; @@ -9244,28 +9408,32 @@ static void expand_pose(FileData *fd, Main *mainvar, bPose *pose) for (chan = pose->chanbase.first; chan; chan = chan->next) { expand_constraints(fd, mainvar, &chan->constraints); + expand_idprops(fd, mainvar, chan->prop); expand_doit(fd, mainvar, chan->custom); } } +static void expand_bones(FileData *fd, Main *mainvar, Bone *bone) +{ + expand_idprops(fd, mainvar, bone->prop); + + for (Bone *curBone = bone->childbase.first; curBone; curBone = curBone->next) { + expand_bones(fd, mainvar, curBone); + } +} + static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm) -{ +{ if (arm->adt) expand_animdata(fd, mainvar, arm->adt); - -#if 0 /* Disabled as this currently only recurses down the chain doing nothing */ - { - Bone *curBone; - - for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) { - expand_bones(fd, mainvar, curBone); - } + + for (Bone *curBone = arm->bonebase.first; curBone; curBone = curBone->next) { + expand_bones(fd, mainvar, curBone); } -#endif } static void expand_object_expandModifiers( - void *userData, Object *UNUSED(ob), ID **idpoin, int UNUSED(cd_flag)) + void *userData, Object *UNUSED(ob), ID **idpoin, int UNUSED(cb_flag)) { struct { FileData *fd; Main *mainvar; } *data= userData; @@ -9489,6 +9657,8 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) SEQ_BEGIN (sce->ed, seq) { + expand_idprops(fd, mainvar, seq->prop); + if (seq->scene) expand_doit(fd, mainvar, seq->scene); if (seq->scene_camera) expand_doit(fd, mainvar, seq->scene_camera); if (seq->clip) expand_doit(fd, mainvar, seq->clip); @@ -9646,6 +9816,8 @@ void BLO_expand_main(void *fdhandle, Main *mainvar) id = lbarray[a]->first; while (id) { if (id->tag & LIB_TAG_NEED_EXPAND) { + expand_idprops(fd, mainvar, id->properties); + switch (GS(id->name)) { case ID_OB: expand_object(fd, mainvar, (Object *)id); @@ -9725,6 +9897,8 @@ void BLO_expand_main(void *fdhandle, Main *mainvar) case ID_CF: expand_cachefile(fd, mainvar, (CacheFile *)id); break; + default: + break; } do_it = true; @@ -9783,9 +9957,15 @@ static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Libra if (active_lay) { ob->lay = active_lay; } + if (flag & FILE_AUTOSELECT) { + /* Note that link_object_postprocess() already checks for FILE_AUTOSELECT flag, + * but it will miss objects from non-instanciated groups... */ + ob->flag |= SELECT; + /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */ + } - base->lay = ob->lay; base->object = ob; + base->lay = ob->lay; base->flag = ob->flag; CLAMP_MIN(ob->id.us, 0); @@ -9966,7 +10146,7 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh) static ID *link_named_part_ex( Main *mainl, FileData *fd, const short idcode, const char *name, const short flag, - Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect) + Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect) { ID *id = link_named_part(mainl, fd, idcode, name, use_placeholders, force_indirect); @@ -10105,6 +10285,32 @@ Main *BLO_library_link_begin(Main *mainvar, BlendHandle **bh, const char *filepa return library_link_begin(mainvar, &fd, filepath); } +static void split_main_newid(Main *mainptr, Main *main_newid) +{ + /* We only copy the necessary subset of data in this temp main. */ + main_newid->versionfile = mainptr->versionfile; + main_newid->subversionfile = mainptr->subversionfile; + BLI_strncpy(main_newid->name, mainptr->name, sizeof(main_newid->name)); + main_newid->curlib = mainptr->curlib; + + ListBase *lbarray[MAX_LIBARRAY]; + ListBase *lbarray_newid[MAX_LIBARRAY]; + int i = set_listbasepointers(mainptr, lbarray); + set_listbasepointers(main_newid, lbarray_newid); + while (i--) { + BLI_listbase_clear(lbarray_newid[i]); + + for (ID *id = lbarray[i]->first, *idnext; id; id = idnext) { + idnext = id->next; + + if (id->tag & LIB_TAG_NEW) { + BLI_remlink(lbarray[i], id); + BLI_addtail(lbarray_newid[i], id); + } + } + } +} + /* scene and v3d may be NULL. */ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene *scene, View3D *v3d) { @@ -10133,10 +10339,28 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene blo_join_main((*fd)->mainlist); mainvar = (*fd)->mainlist->first; - MEM_freeN((*fd)->mainlist); mainl = NULL; /* blo_join_main free's mainl, cant use anymore */ lib_link_all(*fd, mainvar); + + /* Yep, second splitting... but this is a very cheap operation, so no big deal. */ + blo_split_main((*fd)->mainlist, mainvar); + Main main_newid = {0}; + for (mainvar = ((Main *)(*fd)->mainlist->first)->next; mainvar; mainvar = mainvar->next) { + BLI_assert(mainvar->versionfile != 0); + /* We need to split out IDs already existing, or they will go again through do_versions - bad, very bad! */ + split_main_newid(mainvar, &main_newid); + + do_versions_after_linking(&main_newid); + + add_main_to_main(mainvar, &main_newid); + } + blo_join_main((*fd)->mainlist); + mainvar = (*fd)->mainlist->first; + MEM_freeN((*fd)->mainlist); + + BKE_main_id_tag_all(mainvar, LIB_TAG_NEW, false); + lib_verify_nodetree(mainvar, false); fix_relpaths_library(G.main->name, mainvar); /* make all relative paths, relative to the open blend file */ @@ -10307,6 +10531,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) else { mainptr->curlib->filedata = NULL; mainptr->curlib->id.tag |= LIB_TAG_MISSING; + /* Set lib version to current main one... Makes assert later happy. */ + mainptr->versionfile = mainptr->curlib->versionfile = mainl->versionfile; + mainptr->subversionfile = mainptr->curlib->subversionfile = mainl->subversionfile; } if (fd == NULL) { @@ -10376,14 +10603,19 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) } /* do versions, link, and free */ + Main main_newid = {0}; for (mainptr = mainl->next; mainptr; mainptr = mainptr->next) { - /* some mains still have to be read, then - * versionfile is still zero! */ + /* some mains still have to be read, then versionfile is still zero! */ if (mainptr->versionfile) { + /* We need to split out IDs already existing, or they will go again through do_versions - bad, very bad! */ + split_main_newid(mainptr, &main_newid); + if (mainptr->curlib->filedata) // can be zero... with shift+f1 append - do_versions(mainptr->curlib->filedata, mainptr->curlib, mainptr); + do_versions(mainptr->curlib->filedata, mainptr->curlib, &main_newid); else - do_versions(basefd, NULL, mainptr); + do_versions(basefd, NULL, &main_newid); + + add_main_to_main(mainptr, &main_newid); } if (mainptr->curlib->filedata) diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index 7719aaa2b0d..62ce15a640e 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -81,6 +81,8 @@ typedef struct FileData { int id_name_offs; /* used to retrieve ID names from (bhead+1) */ int globalf, fileflags; /* for do_versions patching */ + eBLOReadSkip skip_flags; /* skip some data-blocks */ + struct OldNewMap *datamap; struct OldNewMap *globmap; struct OldNewMap *libmap; @@ -170,5 +172,7 @@ void blo_do_versions_250(struct FileData *fd, struct Library *lib, struct Main * void blo_do_versions_260(struct FileData *fd, struct Library *lib, struct Main *main); void blo_do_versions_270(struct FileData *fd, struct Library *lib, struct Main *main); +void do_versions_after_linking_270(struct Main *main); + #endif diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index 907baab0aee..77542d8deb9 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -56,6 +56,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_string_utils.h" #include "BLT_translation.h" @@ -999,7 +1000,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main) { /* convert extended ascii to utf-8 for text editor */ Text *text; - for (text = main->text.first; text; text = text->id.next) + for (text = main->text.first; text; text = text->id.next) { if (!(text->flags & TXT_ISEXT)) { TextLine *tl; @@ -1012,6 +1013,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main) text->curc = 0; } } + } } { /* set new dynamic paint values */ diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 25d78b73d59..095f21a5b06 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -34,6 +34,7 @@ /* allow readfile to use deprecated functionality */ #define DNA_DEPRECATED_ALLOW +#include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_brush_types.h" #include "DNA_camera_types.h" @@ -46,6 +47,7 @@ #include "DNA_screen_types.h" #include "DNA_object_force.h" #include "DNA_object_types.h" +#include "DNA_mask_types.h" #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_particle_types.h" @@ -57,9 +59,12 @@ #include "DNA_genfile.h" +#include "BKE_animsys.h" +#include "BKE_brush.h" #include "BKE_colortools.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_mask.h" #include "BKE_modifier.h" #include "BKE_node.h" #include "BKE_scene.h" @@ -74,6 +79,10 @@ #include "BLO_readfile.h" +#include "NOD_common.h" +#include "NOD_socket.h" +#include "NOD_composite.h" + #include "readfile.h" #include "MEM_guardedalloc.h" @@ -193,6 +202,89 @@ static void do_version_bones_super_bbone(ListBase *lb) } } +/* TODO(sergey): Consider making it somewhat more generic function in BLI_anim.h. */ +static void anim_change_prop_name(FCurve *fcu, + const char *prefix, + const char *old_prop_name, + const char *new_prop_name) +{ + const char *old_path = BLI_sprintfN("%s.%s", prefix, old_prop_name); + if (STREQ(fcu->rna_path, old_path)) { + MEM_freeN(fcu->rna_path); + fcu->rna_path = BLI_sprintfN("%s.%s", prefix, new_prop_name); + } + MEM_freeN((char *)old_path); +} + +static void do_version_hue_sat_node(bNodeTree *ntree, bNode *node) +{ + if (node->storage == NULL) { + return; + } + + /* Make sure new sockets are properly created. */ + node_verify_socket_templates(ntree, node); + /* Convert value from old storage to new sockets. */ + NodeHueSat *nhs = node->storage; + bNodeSocket *hue = nodeFindSocket(node, SOCK_IN, "Hue"), + *saturation = nodeFindSocket(node, SOCK_IN, "Saturation"), + *value = nodeFindSocket(node, SOCK_IN, "Value"); + ((bNodeSocketValueFloat *)hue->default_value)->value = nhs->hue; + ((bNodeSocketValueFloat *)saturation->default_value)->value = nhs->sat; + ((bNodeSocketValueFloat *)value->default_value)->value = nhs->val; + /* Take care of possible animation. */ + AnimData *adt = BKE_animdata_from_id(&ntree->id); + if (adt != NULL && adt->action != NULL) { + const char *prefix = BLI_sprintfN("nodes[\"%s\"]", node->name); + for (FCurve *fcu = adt->action->curves.first; fcu != NULL; fcu = fcu->next) { + if (STRPREFIX(fcu->rna_path, prefix)) { + anim_change_prop_name(fcu, prefix, "color_hue", "inputs[1].default_value"); + anim_change_prop_name(fcu, prefix, "color_saturation", "inputs[2].default_value"); + anim_change_prop_name(fcu, prefix, "color_value", "inputs[3].default_value"); + } + } + MEM_freeN((char *)prefix); + } + /* Free storage, it is no longer used. */ + MEM_freeN(node->storage); + node->storage = NULL; +} + +static void do_versions_compositor_render_passes_storage(bNode *node) +{ + int pass_index = 0; + const char *sockname; + for (bNodeSocket *sock = node->outputs.first; sock && pass_index < 31; sock = sock->next, pass_index++) { + if (sock->storage == NULL) { + NodeImageLayer *sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer"); + sock->storage = sockdata; + BLI_strncpy(sockdata->pass_name, node_cmp_rlayers_sock_to_pass(pass_index), sizeof(sockdata->pass_name)); + + if (pass_index == 0) sockname = "Image"; + else if (pass_index == 1) sockname = "Alpha"; + else sockname = node_cmp_rlayers_sock_to_pass(pass_index); + BLI_strncpy(sock->name, sockname, sizeof(sock->name)); + } + } +} + +static void do_versions_compositor_render_passes(bNodeTree *ntree) +{ + for (bNode *node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_R_LAYERS) { + /* First we make sure existing sockets have proper names. + * This is important because otherwise verification will + * drop links from sockets which were renamed. + */ + do_versions_compositor_render_passes_storage(node); + /* Make sure new sockets are properly created. */ + node_verify_socket_templates(ntree, node); + /* Make sure all possibly created sockets have proper storage. */ + do_versions_compositor_render_passes_storage(node); + } + } +} + void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) { if (!MAIN_VERSION_ATLEAST(main, 270, 0)) { @@ -1145,12 +1237,19 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) SEQ_BEGIN (scene->ed, seq) { - if (seq->type == SEQ_TYPE_TEXT) { - TextVars *data = seq->effectdata; - if (data->color[3] == 0.0f) { - copy_v4_fl(data->color, 1.0f); - data->shadow_color[3] = 1.0f; - } + if (seq->type != SEQ_TYPE_TEXT) { + continue; + } + + if (seq->effectdata == NULL) { + struct SeqEffectHandle effect_handle = BKE_sequence_get_effect(seq); + effect_handle.init(seq); + } + + TextVars *data = seq->effectdata; + if (data->color[3] == 0.0f) { + copy_v4_fl(data->color, 1.0f); + data->shadow_color[3] = 1.0f; } } SEQ_END @@ -1204,7 +1303,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) for (Camera *camera = main->camera.first; camera != NULL; camera = camera->id.next) { if (camera->stereo.pole_merge_angle_from == 0.0f && - camera->stereo.pole_merge_angle_to == 0.0f) + camera->stereo.pole_merge_angle_to == 0.0f) { camera->stereo.pole_merge_angle_from = DEG2RADF(60.0f); camera->stereo.pole_merge_angle_to = DEG2RADF(75.0f); @@ -1472,5 +1571,154 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) for (Brush *br = main->brush.first; br; br = br->id.next) { br->fill_threshold /= sqrt_3; } + + /* Custom motion paths */ + if (!DNA_struct_elem_find(fd->filesdna, "bMotionPath", "int", "line_thickness")) { + Object *ob; + for (ob = main->object.first; ob; ob = ob->id.next) { + bMotionPath *mpath; + bPoseChannel *pchan; + mpath = ob->mpath; + if (mpath) { + mpath->color[0] = 1.0f; + mpath->color[1] = 0.0f; + mpath->color[2] = 0.0f; + mpath->line_thickness = 1; + mpath->flag |= MOTIONPATH_FLAG_LINES; + } + /* bones motion path */ + if (ob->pose) { + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + mpath = pchan->mpath; + if (mpath) { + mpath->color[0] = 1.0f; + mpath->color[1] = 0.0f; + mpath->color[2] = 0.0f; + mpath->line_thickness = 1; + mpath->flag |= MOTIONPATH_FLAG_LINES; + } + } + } + } + } + } + + if (!MAIN_VERSION_ATLEAST(main, 278, 5)) { + /* Mask primitive adding code was not initializing correctly id_type of its points' parent. */ + for (Mask *mask = main->mask.first; mask; mask = mask->id.next) { + for (MaskLayer *mlayer = mask->masklayers.first; mlayer; mlayer = mlayer->next) { + for (MaskSpline *mspline = mlayer->splines.first; mspline; mspline = mspline->next) { + int i = 0; + for (MaskSplinePoint *mspoint = mspline->points; i < mspline->tot_point; mspoint++, i++) { + if (mspoint->parent.id_type == 0) { + BKE_mask_parent_init(&mspoint->parent); + } + } + } + } + } + + /* Fix for T50736, Glare comp node using same var for two different things. */ + if (!DNA_struct_elem_find(fd->filesdna, "NodeGlare", "char", "star_45")) { + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_COMPOSIT) { + ntreeSetTypes(NULL, ntree); + for (bNode *node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_GLARE) { + NodeGlare *ndg = node->storage; + switch (ndg->type) { + case 2: /* Grrrr! magic numbers :( */ + ndg->streaks = ndg->angle; + break; + case 0: + ndg->star_45 = ndg->angle != 0; + break; + default: + break; + } + } + } + } + } FOREACH_NODETREE_END + } + + if (!DNA_struct_elem_find(fd->filesdna, "SurfaceDeformModifierData", "float", "mat[4][4]")) { + for (Object *ob = main->object.first; ob; ob = ob->id.next) { + for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_SurfaceDeform) { + SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; + unit_m4(smd->mat); + } + } + } + } + + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_COMPOSIT) { + do_versions_compositor_render_passes(ntree); + } + } FOREACH_NODETREE_END + } + + if (!MAIN_VERSION_ATLEAST(main, 279, 0)) { + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + if (scene->r.im_format.exr_codec == R_IMF_EXR_CODEC_DWAB) { + scene->r.im_format.exr_codec = R_IMF_EXR_CODEC_DWAA; + } + } + + /* Fix related to VGroup modifiers creating named defgroup CD layers! See T51520. */ + for (Mesh *me = main->mesh.first; me; me = me->id.next) { + CustomData_set_layer_name(&me->vdata, CD_MDEFORMVERT, 0, ""); + } + } + + { + /* Fix for invalid state of screen due to bug in older versions. */ + for (bScreen *sc = main->screen.first; sc; sc = sc->id.next) { + for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { + if (sa->full && sc->state == SCREENNORMAL) { + sa->full = NULL; + } + } + } + + if (!DNA_struct_elem_find(fd->filesdna, "Brush", "float", "falloff_angle")) { + for (Brush *br = main->brush.first; br; br = br->id.next) { + br->falloff_angle = DEG2RADF(80); + br->flag &= ~( + BRUSH_FLAG_DEPRECATED_1 | BRUSH_FLAG_DEPRECATED_2 | + BRUSH_FLAG_DEPRECATED_3 | BRUSH_FLAG_DEPRECATED_4 | + BRUSH_FRONTFACE_FALLOFF); + } + + for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { + ToolSettings *ts = scene->toolsettings; + for (int i = 0; i < 2; i++) { + VPaint *vp = i ? ts->vpaint : ts->wpaint; + if (vp != NULL) { + /* remove all other flags */ + vp->flag &= (VP_FLAG_VGROUP_RESTRICT); + } + } + } + } + } +} + +void do_versions_after_linking_270(Main *main) +{ + /* To be added to next subversion bump! */ + if (!MAIN_VERSION_ATLEAST(main, 279, 0)) { + FOREACH_NODETREE(main, ntree, id) { + if (ntree->type == NTREE_COMPOSIT) { + ntreeSetTypes(NULL, ntree); + for (bNode *node = ntree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_HUE_SAT) { + do_version_hue_sat_node(ntree, node); + } + } + } + } FOREACH_NODETREE_END } } diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index 99d9e140481..3d3e73eb470 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -58,6 +58,9 @@ void BLO_update_defaults_userpref_blend(void) U.uiflag |= USER_QUIT_PROMPT; U.uiflag |= USER_CONTINUOUS_MOUSE; + /* See T45301 */ + U.uiflag |= USER_LOCK_CURSOR_ADJUST; + U.versions = 1; U.savetime = 2; @@ -68,6 +71,18 @@ void BLO_update_defaults_userpref_blend(void) * but take care since some hardware has driver bugs here (T46962). * Further hardware workarounds should be made in gpu_extensions.c */ U.glalphaclip = (1.0f / 255); + + /* default so DPI is detected automatically */ + U.dpi = 0; + U.ui_scale = 1.0f; + +#ifdef WITH_PYTHON_SECURITY + /* use alternative setting for security nuts + * otherwise we'd need to patch the binary blob - startup.blend.c */ + U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE; +#else + U.flag &= ~USER_SCRIPT_AUTOEXEC_DISABLE; +#endif } /** @@ -94,6 +109,16 @@ void BLO_update_defaults_startup_blend(Main *bmain) sculpt->detail_size = 12; } + if (ts->vpaint) { + VPaint *vp = ts->vpaint; + vp->radial_symm[0] = vp->radial_symm[1] = vp->radial_symm[2] = 1; + } + + if (ts->wpaint) { + VPaint *wp = ts->wpaint; + wp->radial_symm[0] = wp->radial_symm[1] = wp->radial_symm[2] = 1; + } + if (ts->gp_sculpt.brush[0].size == 0) { GP_BrushEdit_Settings *gset = &ts->gp_sculpt; GP_EditBrush_Data *brush; @@ -221,6 +246,20 @@ void BLO_update_defaults_startup_blend(Main *bmain) br->ob_mode = OB_MODE_TEXTURE_PAINT; } + /* Vertex/Weight Paint */ + br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Average"); + if (!br) { + br = BKE_brush_add(bmain, "Average", OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT); + br->vertexpaint_tool = PAINT_BLEND_AVERAGE; + br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT; + } + br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Smear"); + if (!br) { + br = BKE_brush_add(bmain, "Smear", OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT); + br->vertexpaint_tool = PAINT_BLEND_SMEAR; + br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT; + } + br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Mask"); if (br) { br->imagepaint_tool = PAINT_TOOL_MASK; @@ -230,13 +269,13 @@ void BLO_update_defaults_startup_blend(Main *bmain) /* remove polish brush (flatten/contrast does the same) */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Polish"); if (br) { - BKE_libblock_free(bmain, br); + BKE_libblock_delete(bmain, br); } /* remove brush brush (huh?) from some modes (draw brushes do the same) */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Brush"); if (br) { - BKE_libblock_free(bmain, br); + BKE_libblock_delete(bmain, br); } /* remove draw brush from texpaint (draw brushes do the same) */ diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index f2d42849bcc..ad37679800b 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -2296,11 +2296,12 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) /* during 2.41 images with this name were used for viewer node output, lets fix that */ if (main->versionfile == 241) { Image *ima; - for (ima = main->image.first; ima; ima = ima->id.next) + for (ima = main->image.first; ima; ima = ima->id.next) { if (STREQ(ima->name, "Compositor")) { strcpy(ima->id.name + 2, "Viewer Node"); strcpy(ima->name, "Viewer Node"); } + } } } @@ -2910,12 +2911,12 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main) 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] == 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; + sce->toolsettings->skgen_subdivisions[0] = SKGEN_SUB_CORRELATION; + sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH; + sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE; } } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index ad1999c0bc7..2648ebdc395 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -78,7 +78,7 @@ * - write #TEST (#RenderInfo struct. 128x128 blend file preview is optional). * - write #GLOB (#FileGlobal struct) (some global vars). * - write #DNA1 (#SDNA struct) - * - write #USER (#UserDef struct) if filename is ``~/X.XX/config/startup.blend``. + * - write #USER (#UserDef struct) if filename is ``~/.config/blender/X.XX/config/startup.blend``. */ @@ -797,30 +797,22 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves) } } -static void write_actions(WriteData *wd, ListBase *idbase) +static void write_action(WriteData *wd, bAction *act) { - bAction *act; - 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); - write_iddata(wd, &act->id); + if (act->id.us > 0 || wd->current) { + writestruct(wd, ID_AC, bAction, 1, act); + write_iddata(wd, &act->id); - write_fcurves(wd, &act->curves); + write_fcurves(wd, &act->curves); - for (grp = act->groups.first; grp; grp = grp->next) { - writestruct(wd, DATA, bActionGroup, 1, grp); - } + for (bActionGroup *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); - } + for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) { + writestruct(wd, DATA, TimeMarker, 1, marker); } } - - mywrite_flush(wd); } static void write_keyingsets(WriteData *wd, ListBase *list) @@ -969,7 +961,7 @@ static void write_node_socket_interface(WriteData *wd, bNodeTree *UNUSED(ntree), } } /* this is only direct data, tree itself should have been written */ -static void write_nodetree(WriteData *wd, bNodeTree *ntree) +static void write_nodetree_nolib(WriteData *wd, bNodeTree *ntree) { bNode *node; bNodeSocket *sock; @@ -1030,6 +1022,25 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) { /* pass */ } + else if ((ntree->type == NTREE_COMPOSIT) && (node->type == CMP_NODE_GLARE)) { + /* Simple forward compat for fix for T50736. + * Not ideal (there is no ideal solution here), but should do for now. */ + NodeGlare *ndg = node->storage; + /* Not in undo case. */ + if (!wd->current) { + switch (ndg->type) { + case 2: /* Grrrr! magic numbers :( */ + ndg->angle = ndg->streaks; + break; + case 0: + ndg->angle = ndg->star_45; + break; + default: + break; + } + } + writestruct_id(wd, DATA, node->typeinfo->storagename, 1, node->storage); + } else { writestruct_id(wd, DATA, node->typeinfo->storagename, 1, node->storage); } @@ -1041,7 +1052,7 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) writestruct(wd, DATA, NodeImageMultiFileSocket, 1, sock->storage); } } - if (node->type == CMP_NODE_IMAGE) { + if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_R_LAYERS)) { /* write extra socket info */ for (sock = node->outputs.first; sock; sock = sock->next) { writestruct(wd, DATA, NodeImageLayer, 1, sock->storage); @@ -1278,68 +1289,60 @@ static void write_pointcaches(WriteData *wd, ListBase *ptcaches) } } } -static void write_particlesettings(WriteData *wd, ListBase *idbase) -{ - ParticleSettings *part; - ParticleDupliWeight *dw; - GroupObject *go; - int a; - part = idbase->first; - while (part) { - if (part->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_PA, ParticleSettings, 1, part); - write_iddata(wd, &part->id); +static void write_particlesettings(WriteData *wd, ParticleSettings *part) +{ + if (part->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_PA, ParticleSettings, 1, part); + write_iddata(wd, &part->id); - if (part->adt) { - write_animdata(wd, part->adt); - } - writestruct(wd, DATA, PartDeflect, 1, part->pd); - writestruct(wd, DATA, PartDeflect, 1, part->pd2); - writestruct(wd, DATA, EffectorWeights, 1, part->effector_weights); + if (part->adt) { + write_animdata(wd, part->adt); + } + writestruct(wd, DATA, PartDeflect, 1, part->pd); + writestruct(wd, DATA, PartDeflect, 1, part->pd2); + writestruct(wd, DATA, EffectorWeights, 1, part->effector_weights); - if (part->clumpcurve) { - write_curvemapping(wd, part->clumpcurve); - } - if (part->roughcurve) { - write_curvemapping(wd, part->roughcurve); - } + if (part->clumpcurve) { + write_curvemapping(wd, part->clumpcurve); + } + if (part->roughcurve) { + write_curvemapping(wd, part->roughcurve); + } - dw = part->dupliweights.first; - for (; dw; dw = dw->next) { - /* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */ - if (dw->ob != NULL) { - dw->index = 0; - if (part->dup_group) { /* can be NULL if lining fails or set to None */ - for (go = part->dup_group->gobject.first; go && go->ob != dw->ob; go = go->next, dw->index++); - } + for (ParticleDupliWeight *dw = part->dupliweights.first; dw; dw = dw->next) { + /* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */ + if (dw->ob != NULL) { + dw->index = 0; + if (part->dup_group) { /* can be NULL if lining fails or set to None */ + for (GroupObject *go = part->dup_group->gobject.first; + go && go->ob != dw->ob; + go = go->next, dw->index++); } - writestruct(wd, DATA, ParticleDupliWeight, 1, dw); } + writestruct(wd, DATA, ParticleDupliWeight, 1, dw); + } - if (part->boids && part->phystype == PART_PHYS_BOIDS) { - BoidState *state = part->boids->states.first; - - writestruct(wd, DATA, BoidSettings, 1, part->boids); + if (part->boids && part->phystype == PART_PHYS_BOIDS) { + writestruct(wd, DATA, BoidSettings, 1, part->boids); - for (; state; state = state->next) { - write_boid_state(wd, state); - } - } - if (part->fluid && part->phystype == PART_PHYS_FLUID) { - writestruct(wd, DATA, SPHFluidSettings, 1, part->fluid); + for (BoidState *state = part->boids->states.first; state; state = state->next) { + write_boid_state(wd, state); } + } + if (part->fluid && part->phystype == PART_PHYS_FLUID) { + writestruct(wd, DATA, SPHFluidSettings, 1, part->fluid); + } - for (a = 0; a < MAX_MTEX; a++) { - if (part->mtex[a]) { - writestruct(wd, DATA, MTex, 1, part->mtex[a]); - } + for (int a = 0; a < MAX_MTEX; a++) { + if (part->mtex[a]) { + writestruct(wd, DATA, MTex, 1, part->mtex[a]); } } - part = part->id.next; } } + static void write_particlesystems(WriteData *wd, ListBase *particles) { ParticleSystem *psys = particles->first; @@ -1830,242 +1833,207 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) writedata(wd, DATA, sizeof(float[3]) * csmd->bind_coords_num, csmd->bind_coords); } } - } -} + else if (md->type == eModifierType_SurfaceDeform) { + SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; -static void write_objects(WriteData *wd, ListBase *idbase) -{ - Object *ob; + writestruct(wd, DATA, SDefVert, smd->numverts, smd->verts); - ob = idbase->first; - while (ob) { - if (ob->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_OB, Object, 1, ob); - write_iddata(wd, &ob->id); + if (smd->verts) { + for (int i = 0; i < smd->numverts; i++) { + writestruct(wd, DATA, SDefBind, smd->verts[i].numbinds, smd->verts[i].binds); - if (ob->adt) { - write_animdata(wd, ob->adt); - } + if (smd->verts[i].binds) { + for (int j = 0; j < smd->verts[i].numbinds; j++) { + writedata(wd, DATA, sizeof(int) * smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_inds); - /* direct data */ - writedata(wd, DATA, sizeof(void *) * ob->totcol, ob->mat); - writedata(wd, DATA, sizeof(char) * ob->totcol, ob->matbits); - /* write_effects(wd, &ob->effect); */ /* not used anymore */ - write_properties(wd, &ob->prop); - write_sensors(wd, &ob->sensors); - write_controllers(wd, &ob->controllers); - write_actuators(wd, &ob->actuators); - - if (ob->type == OB_ARMATURE) { - bArmature *arm = ob->data; - if (arm && ob->pose && arm->act_bone) { - BLI_strncpy(ob->pose->proxy_act_bone, arm->act_bone->name, sizeof(ob->pose->proxy_act_bone)); + if (smd->verts[i].binds[j].mode == MOD_SDEF_MODE_CENTROID || + smd->verts[i].binds[j].mode == MOD_SDEF_MODE_LOOPTRI) + { + writedata(wd, DATA, sizeof(float) * 3, smd->verts[i].binds[j].vert_weights); + } + else { + writedata(wd, DATA, sizeof(float) * smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_weights); + } + } + } } } + } + } +} - write_pose(wd, ob->pose); - write_defgroups(wd, &ob->defbase); - write_constraints(wd, &ob->constraints); - write_motionpath(wd, ob->mpath); +static void write_object(WriteData *wd, Object *ob) +{ + if (ob->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_OB, Object, 1, ob); + write_iddata(wd, &ob->id); - writestruct(wd, DATA, PartDeflect, 1, ob->pd); - writestruct(wd, DATA, SoftBody, 1, ob->soft); - if (ob->soft) { - write_pointcaches(wd, &ob->soft->ptcaches); - writestruct(wd, DATA, EffectorWeights, 1, ob->soft->effector_weights); - } - writestruct(wd, DATA, BulletSoftBody, 1, ob->bsoft); + if (ob->adt) { + write_animdata(wd, ob->adt); + } - if (ob->rigidbody_object) { - /* TODO: if any extra data is added to handle duplis, will need separate function then */ - writestruct(wd, DATA, RigidBodyOb, 1, ob->rigidbody_object); - } - if (ob->rigidbody_constraint) { - writestruct(wd, DATA, RigidBodyCon, 1, ob->rigidbody_constraint); - } + /* direct data */ + writedata(wd, DATA, sizeof(void *) * ob->totcol, ob->mat); + writedata(wd, DATA, sizeof(char) * ob->totcol, ob->matbits); + /* write_effects(wd, &ob->effect); */ /* not used anymore */ + write_properties(wd, &ob->prop); + write_sensors(wd, &ob->sensors); + write_controllers(wd, &ob->controllers); + write_actuators(wd, &ob->actuators); - if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) { - writestruct(wd, DATA, ImageUser, 1, ob->iuser); + if (ob->type == OB_ARMATURE) { + bArmature *arm = ob->data; + if (arm && ob->pose && arm->act_bone) { + BLI_strncpy(ob->pose->proxy_act_bone, arm->act_bone->name, sizeof(ob->pose->proxy_act_bone)); } + } - write_particlesystems(wd, &ob->particlesystem); - write_modifiers(wd, &ob->modifiers); + write_pose(wd, ob->pose); + write_defgroups(wd, &ob->defbase); + write_constraints(wd, &ob->constraints); + write_motionpath(wd, ob->mpath); - writelist(wd, DATA, LinkData, &ob->pc_ids); - writelist(wd, DATA, LodLevel, &ob->lodlevels); + writestruct(wd, DATA, PartDeflect, 1, ob->pd); + writestruct(wd, DATA, SoftBody, 1, ob->soft); + if (ob->soft) { + write_pointcaches(wd, &ob->soft->ptcaches); + writestruct(wd, DATA, EffectorWeights, 1, ob->soft->effector_weights); } + writestruct(wd, DATA, BulletSoftBody, 1, ob->bsoft); - write_previews(wd, ob->preview); + if (ob->rigidbody_object) { + /* TODO: if any extra data is added to handle duplis, will need separate function then */ + writestruct(wd, DATA, RigidBodyOb, 1, ob->rigidbody_object); + } + if (ob->rigidbody_constraint) { + writestruct(wd, DATA, RigidBodyCon, 1, ob->rigidbody_constraint); + } - ob = ob->id.next; - } + if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) { + writestruct(wd, DATA, ImageUser, 1, ob->iuser); + } - mywrite_flush(wd); -} + write_particlesystems(wd, &ob->particlesystem); + write_modifiers(wd, &ob->modifiers); + writelist(wd, DATA, LinkData, &ob->pc_ids); + writelist(wd, DATA, LodLevel, &ob->lodlevels); -static void write_vfonts(WriteData *wd, ListBase *idbase) -{ - VFont *vf; - PackedFile *pf; + write_previews(wd, ob->preview); + } +} - vf = idbase->first; - while (vf) { - if (vf->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_VF, VFont, 1, vf); - write_iddata(wd, &vf->id); - /* direct data */ +static void write_vfont(WriteData *wd, VFont *vf) +{ + if (vf->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_VF, VFont, 1, vf); + write_iddata(wd, &vf->id); - if (vf->packedfile) { - pf = vf->packedfile; - writestruct(wd, DATA, PackedFile, 1, pf); - writedata(wd, DATA, pf->size, pf->data); - } + /* direct data */ + if (vf->packedfile) { + PackedFile *pf = vf->packedfile; + writestruct(wd, DATA, PackedFile, 1, pf); + writedata(wd, DATA, pf->size, pf->data); } - - vf = vf->id.next; } - - mywrite_flush(wd); } -static void write_keys(WriteData *wd, ListBase *idbase) +static void write_key(WriteData *wd, Key *key) { - Key *key; - KeyBlock *kb; - - key = idbase->first; - while (key) { - if (key->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_KE, Key, 1, key); - write_iddata(wd, &key->id); - - if (key->adt) { - write_animdata(wd, key->adt); - } + if (key->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_KE, Key, 1, key); + write_iddata(wd, &key->id); - /* direct data */ - kb = key->block.first; - while (kb) { - writestruct(wd, DATA, KeyBlock, 1, kb); - if (kb->data) { - writedata(wd, DATA, kb->totelem * key->elemsize, kb->data); - } - kb = kb->next; - } + if (key->adt) { + write_animdata(wd, key->adt); } - key = key->id.next; + /* direct data */ + for (KeyBlock *kb = key->block.first; kb; kb = kb->next) { + writestruct(wd, DATA, KeyBlock, 1, kb); + if (kb->data) { + writedata(wd, DATA, kb->totelem * key->elemsize, kb->data); + } + } } - - mywrite_flush(wd); } -static void write_cameras(WriteData *wd, ListBase *idbase) +static void write_camera(WriteData *wd, Camera *cam) { - Camera *cam; - - cam = idbase->first; - while (cam) { - if (cam->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_CA, Camera, 1, cam); - write_iddata(wd, &cam->id); + if (cam->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_CA, Camera, 1, cam); + write_iddata(wd, &cam->id); - if (cam->adt) { - write_animdata(wd, cam->adt); - } + if (cam->adt) { + write_animdata(wd, cam->adt); } - - cam = cam->id.next; } } -static void write_mballs(WriteData *wd, ListBase *idbase) +static void write_mball(WriteData *wd, MetaBall *mb) { - MetaBall *mb; - MetaElem *ml; - - mb = idbase->first; - while (mb) { - if (mb->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_MB, MetaBall, 1, mb); - write_iddata(wd, &mb->id); + if (mb->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_MB, MetaBall, 1, mb); + write_iddata(wd, &mb->id); - /* direct data */ - writedata(wd, DATA, sizeof(void *) * mb->totcol, mb->mat); - if (mb->adt) { - write_animdata(wd, mb->adt); - } + /* direct data */ + writedata(wd, DATA, sizeof(void *) * mb->totcol, mb->mat); + if (mb->adt) { + write_animdata(wd, mb->adt); + } - ml = mb->elems.first; - while (ml) { - writestruct(wd, DATA, MetaElem, 1, ml); - ml = ml->next; - } + for (MetaElem *ml = mb->elems.first; ml; ml = ml->next) { + writestruct(wd, DATA, MetaElem, 1, ml); } - mb = mb->id.next; } } -static void write_curves(WriteData *wd, ListBase *idbase) +static void write_curve(WriteData *wd, Curve *cu) { - Curve *cu; - Nurb *nu; - - cu = idbase->first; - while (cu) { - if (cu->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_CU, Curve, 1, cu); - write_iddata(wd, &cu->id); + if (cu->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_CU, Curve, 1, cu); + write_iddata(wd, &cu->id); - /* direct data */ - writedata(wd, DATA, sizeof(void *) * cu->totcol, cu->mat); - if (cu->adt) { - write_animdata(wd, cu->adt); - } + /* direct data */ + writedata(wd, DATA, sizeof(void *) * cu->totcol, cu->mat); + if (cu->adt) { + write_animdata(wd, cu->adt); + } - if (cu->vfont) { - writedata(wd, DATA, cu->len + 1, cu->str); - writestruct(wd, DATA, CharInfo, cu->len_wchar + 1, cu->strinfo); - writestruct(wd, DATA, TextBox, cu->totbox, cu->tb); + if (cu->vfont) { + writedata(wd, DATA, cu->len + 1, cu->str); + writestruct(wd, DATA, CharInfo, cu->len_wchar + 1, cu->strinfo); + writestruct(wd, DATA, TextBox, cu->totbox, cu->tb); + } + else { + /* is also the order of reading */ + for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) { + writestruct(wd, DATA, Nurb, 1, nu); } - else { - /* is also the order of reading */ - nu = cu->nurb.first; - while (nu) { - writestruct(wd, DATA, Nurb, 1, nu); - nu = nu->next; + for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + writestruct(wd, DATA, BezTriple, nu->pntsu, nu->bezt); } - nu = cu->nurb.first; - while (nu) { - if (nu->type == CU_BEZIER) { - writestruct(wd, DATA, BezTriple, nu->pntsu, nu->bezt); + else { + writestruct(wd, DATA, BPoint, nu->pntsu * nu->pntsv, nu->bp); + if (nu->knotsu) { + writedata(wd, DATA, KNOTSU(nu) * sizeof(float), nu->knotsu); } - else { - writestruct(wd, DATA, BPoint, nu->pntsu * nu->pntsv, nu->bp); - if (nu->knotsu) { - writedata(wd, DATA, KNOTSU(nu) * sizeof(float), nu->knotsu); - } - if (nu->knotsv) { - writedata(wd, DATA, KNOTSV(nu) * sizeof(float), nu->knotsv); - } + if (nu->knotsv) { + writedata(wd, DATA, KNOTSV(nu) * sizeof(float), nu->knotsv); } - nu = nu->next; } } } - cu = cu->id.next; } - - mywrite_flush(wd); } static void write_dverts(WriteData *wd, int count, MDeformVert *dvlist) @@ -2182,407 +2150,350 @@ static void write_customdata( } } -static void write_meshes(WriteData *wd, ListBase *idbase) +static void write_mesh(WriteData *wd, Mesh *mesh) { - Mesh *mesh; - bool save_for_old_blender = false; - #ifdef USE_BMESH_SAVE_AS_COMPAT - save_for_old_blender = wd->use_mesh_compat; /* option to save with older mesh format */ + const bool save_for_old_blender = wd->use_mesh_compat; /* option to save with older mesh format */ +#else + const bool save_for_old_blender = false; #endif - mesh = idbase->first; - while (mesh) { - CustomDataLayer *vlayers = NULL, vlayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *elayers = NULL, elayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *flayers = NULL, flayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *llayers = NULL, llayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE]; - - if (mesh->id.us > 0 || wd->current) { - /* write LibData */ - if (!save_for_old_blender) { - /* write a copy of the mesh, don't modify in place because it is - * not thread safe for threaded renders that are reading this */ - Mesh *old_mesh = mesh; - Mesh copy_mesh = *mesh; - mesh = ©_mesh; + CustomDataLayer *vlayers = NULL, vlayers_buff[CD_TEMP_CHUNK_SIZE]; + CustomDataLayer *elayers = NULL, elayers_buff[CD_TEMP_CHUNK_SIZE]; + CustomDataLayer *flayers = NULL, flayers_buff[CD_TEMP_CHUNK_SIZE]; + CustomDataLayer *llayers = NULL, llayers_buff[CD_TEMP_CHUNK_SIZE]; + CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE]; + + if (mesh->id.us > 0 || wd->current) { + /* write LibData */ + if (!save_for_old_blender) { + /* write a copy of the mesh, don't modify in place because it is + * not thread safe for threaded renders that are reading this */ + Mesh *old_mesh = mesh; + Mesh copy_mesh = *mesh; + mesh = ©_mesh; #ifdef USE_BMESH_SAVE_WITHOUT_MFACE - /* cache only - don't write */ - mesh->mface = NULL; - mesh->totface = 0; - memset(&mesh->fdata, 0, sizeof(mesh->fdata)); + /* cache only - don't write */ + mesh->mface = NULL; + mesh->totface = 0; + memset(&mesh->fdata, 0, sizeof(mesh->fdata)); #endif /* USE_BMESH_SAVE_WITHOUT_MFACE */ - /** - * Those calls: - * - Reduce mesh->xdata.totlayer to number of layers to write. - * - Fill xlayers with those layers to be written. - * Note that mesh->xdata is from now on invalid for Blender, but this is why the whole mesh is - * a temp local copy! - */ - CustomData_file_write_prepare(&mesh->vdata, &vlayers, vlayers_buff, ARRAY_SIZE(vlayers_buff)); - CustomData_file_write_prepare(&mesh->edata, &elayers, elayers_buff, ARRAY_SIZE(elayers_buff)); + /** + * Those calls: + * - Reduce mesh->xdata.totlayer to number of layers to write. + * - Fill xlayers with those layers to be written. + * Note that mesh->xdata is from now on invalid for Blender, but this is why the whole mesh is + * a temp local copy! + */ + CustomData_file_write_prepare(&mesh->vdata, &vlayers, vlayers_buff, ARRAY_SIZE(vlayers_buff)); + CustomData_file_write_prepare(&mesh->edata, &elayers, elayers_buff, ARRAY_SIZE(elayers_buff)); #ifndef USE_BMESH_SAVE_WITHOUT_MFACE /* Do not copy org fdata in this case!!! */ - CustomData_file_write_prepare(&mesh->fdata, &flayers, flayers_buff, ARRAY_SIZE(flayers_buff)); + CustomData_file_write_prepare(&mesh->fdata, &flayers, flayers_buff, ARRAY_SIZE(flayers_buff)); #else - flayers = flayers_buff; + flayers = flayers_buff; #endif - CustomData_file_write_prepare(&mesh->ldata, &llayers, llayers_buff, ARRAY_SIZE(llayers_buff)); - CustomData_file_write_prepare(&mesh->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); + CustomData_file_write_prepare(&mesh->ldata, &llayers, llayers_buff, ARRAY_SIZE(llayers_buff)); + CustomData_file_write_prepare(&mesh->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); - writestruct_at_address(wd, ID_ME, Mesh, 1, old_mesh, mesh); - write_iddata(wd, &mesh->id); + writestruct_at_address(wd, ID_ME, Mesh, 1, old_mesh, mesh); + write_iddata(wd, &mesh->id); - /* direct data */ - if (mesh->adt) { - write_animdata(wd, mesh->adt); - } + /* direct data */ + if (mesh->adt) { + write_animdata(wd, mesh->adt); + } - writedata(wd, DATA, sizeof(void *) * mesh->totcol, mesh->mat); - writedata(wd, DATA, sizeof(MSelect) * mesh->totselect, mesh->mselect); + writedata(wd, DATA, sizeof(void *) * mesh->totcol, mesh->mat); + writedata(wd, DATA, sizeof(MSelect) * mesh->totselect, mesh->mselect); - write_customdata(wd, &mesh->id, mesh->totvert, &mesh->vdata, vlayers, -1, 0); - write_customdata(wd, &mesh->id, mesh->totedge, &mesh->edata, elayers, -1, 0); - /* fdata is really a dummy - written so slots align */ - write_customdata(wd, &mesh->id, mesh->totface, &mesh->fdata, flayers, -1, 0); - write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, llayers, -1, 0); - write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, players, -1, 0); + write_customdata(wd, &mesh->id, mesh->totvert, &mesh->vdata, vlayers, -1, 0); + write_customdata(wd, &mesh->id, mesh->totedge, &mesh->edata, elayers, -1, 0); + /* fdata is really a dummy - written so slots align */ + write_customdata(wd, &mesh->id, mesh->totface, &mesh->fdata, flayers, -1, 0); + write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, llayers, -1, 0); + write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, players, -1, 0); - /* restore pointer */ - mesh = old_mesh; - } - else { + /* restore pointer */ + mesh = old_mesh; + } + else { #ifdef USE_BMESH_SAVE_AS_COMPAT - /* write a copy of the mesh, don't modify in place because it is - * not thread safe for threaded renders that are reading this */ - Mesh *old_mesh = mesh; - Mesh copy_mesh = *mesh; - mesh = ©_mesh; - - mesh->mpoly = NULL; - mesh->mface = NULL; - mesh->totface = 0; - mesh->totpoly = 0; - mesh->totloop = 0; - CustomData_reset(&mesh->fdata); - CustomData_reset(&mesh->pdata); - CustomData_reset(&mesh->ldata); - mesh->edit_btmesh = NULL; - - /* now fill in polys to mfaces */ - /* XXX This breaks writing design, by using temp allocated memory, which will likely generate - * duplicates in stored 'old' addresses. - * This is very bad, but do not see easy way to avoid this, aside from generating those data - * outside of save process itself. - * Maybe we can live with this, though? - */ - mesh->totface = BKE_mesh_mpoly_to_mface(&mesh->fdata, &old_mesh->ldata, &old_mesh->pdata, - mesh->totface, old_mesh->totloop, old_mesh->totpoly); + /* write a copy of the mesh, don't modify in place because it is + * not thread safe for threaded renders that are reading this */ + Mesh *old_mesh = mesh; + Mesh copy_mesh = *mesh; + mesh = ©_mesh; + + mesh->mpoly = NULL; + mesh->mface = NULL; + mesh->totface = 0; + mesh->totpoly = 0; + mesh->totloop = 0; + CustomData_reset(&mesh->fdata); + CustomData_reset(&mesh->pdata); + CustomData_reset(&mesh->ldata); + mesh->edit_btmesh = NULL; + + /* now fill in polys to mfaces */ + /* XXX This breaks writing design, by using temp allocated memory, which will likely generate + * duplicates in stored 'old' addresses. + * This is very bad, but do not see easy way to avoid this, aside from generating those data + * outside of save process itself. + * Maybe we can live with this, though? + */ + mesh->totface = BKE_mesh_mpoly_to_mface( + &mesh->fdata, &old_mesh->ldata, &old_mesh->pdata, + mesh->totface, old_mesh->totloop, old_mesh->totpoly); - BKE_mesh_update_customdata_pointers(mesh, false); + BKE_mesh_update_customdata_pointers(mesh, false); - CustomData_file_write_prepare(&mesh->vdata, &vlayers, vlayers_buff, ARRAY_SIZE(vlayers_buff)); - CustomData_file_write_prepare(&mesh->edata, &elayers, elayers_buff, ARRAY_SIZE(elayers_buff)); - CustomData_file_write_prepare(&mesh->fdata, &flayers, flayers_buff, ARRAY_SIZE(flayers_buff)); + CustomData_file_write_prepare(&mesh->vdata, &vlayers, vlayers_buff, ARRAY_SIZE(vlayers_buff)); + CustomData_file_write_prepare(&mesh->edata, &elayers, elayers_buff, ARRAY_SIZE(elayers_buff)); + CustomData_file_write_prepare(&mesh->fdata, &flayers, flayers_buff, ARRAY_SIZE(flayers_buff)); #if 0 - CustomData_file_write_prepare(&mesh->ldata, &llayers, llayers_buff, ARRAY_SIZE(llayers_buff)); - CustomData_file_write_prepare(&mesh->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); + CustomData_file_write_prepare(&mesh->ldata, &llayers, llayers_buff, ARRAY_SIZE(llayers_buff)); + CustomData_file_write_prepare(&mesh->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); #endif - writestruct_at_address(wd, ID_ME, Mesh, 1, old_mesh, mesh); - write_iddata(wd, &mesh->id); + writestruct_at_address(wd, ID_ME, Mesh, 1, old_mesh, mesh); + write_iddata(wd, &mesh->id); - /* direct data */ - if (mesh->adt) { - write_animdata(wd, mesh->adt); - } + /* direct data */ + if (mesh->adt) { + write_animdata(wd, mesh->adt); + } - writedata(wd, DATA, sizeof(void *) * mesh->totcol, mesh->mat); - /* writedata(wd, DATA, sizeof(MSelect) * mesh->totselect, mesh->mselect); */ /* pre-bmesh NULL's */ + writedata(wd, DATA, sizeof(void *) * mesh->totcol, mesh->mat); + /* writedata(wd, DATA, sizeof(MSelect) * mesh->totselect, mesh->mselect); */ /* pre-bmesh NULL's */ - write_customdata(wd, &mesh->id, mesh->totvert, &mesh->vdata, vlayers, -1, 0); - write_customdata(wd, &mesh->id, mesh->totedge, &mesh->edata, elayers, -1, 0); - write_customdata(wd, &mesh->id, mesh->totface, &mesh->fdata, flayers, -1, 0); - /* harmless for older blender versioins but _not_ writing these keeps file size down */ + write_customdata(wd, &mesh->id, mesh->totvert, &mesh->vdata, vlayers, -1, 0); + write_customdata(wd, &mesh->id, mesh->totedge, &mesh->edata, elayers, -1, 0); + write_customdata(wd, &mesh->id, mesh->totface, &mesh->fdata, flayers, -1, 0); + /* harmless for older blender versioins but _not_ writing these keeps file size down */ #if 0 - write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, llayers, -1, 0); - write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, players, -1, 0); + write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, llayers, -1, 0); + write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, players, -1, 0); #endif - CustomData_free(&mesh->fdata, mesh->totface); - flayers = NULL; + CustomData_free(&mesh->fdata, mesh->totface); + flayers = NULL; - /* restore pointer */ - mesh = old_mesh; + /* restore pointer */ + mesh = old_mesh; #endif /* USE_BMESH_SAVE_AS_COMPAT */ - } - } - - if (vlayers && vlayers != vlayers_buff) { - MEM_freeN(vlayers); } - if (elayers && elayers != elayers_buff) { - MEM_freeN(elayers); - } - if (flayers && flayers != flayers_buff) { - MEM_freeN(flayers); - } - if (llayers && llayers != llayers_buff) { - MEM_freeN(llayers); - } - if (players && players != players_buff) { - MEM_freeN(players); - } - - mesh = mesh->id.next; } - mywrite_flush(wd); + if (vlayers && vlayers != vlayers_buff) { + MEM_freeN(vlayers); + } + if (elayers && elayers != elayers_buff) { + MEM_freeN(elayers); + } + if (flayers && flayers != flayers_buff) { + MEM_freeN(flayers); + } + if (llayers && llayers != llayers_buff) { + MEM_freeN(llayers); + } + if (players && players != players_buff) { + MEM_freeN(players); + } } -static void write_lattices(WriteData *wd, ListBase *idbase) +static void write_lattice(WriteData *wd, Lattice *lt) { - Lattice *lt; - - lt = idbase->first; - while (lt) { - if (lt->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_LT, Lattice, 1, lt); - write_iddata(wd, <->id); - - /* write animdata */ - if (lt->adt) { - write_animdata(wd, lt->adt); - } + if (lt->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_LT, Lattice, 1, lt); + write_iddata(wd, <->id); - /* direct data */ - writestruct(wd, DATA, BPoint, lt->pntsu * lt->pntsv * lt->pntsw, lt->def); + /* write animdata */ + if (lt->adt) { + write_animdata(wd, lt->adt); + } - write_dverts(wd, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert); + /* direct data */ + writestruct(wd, DATA, BPoint, lt->pntsu * lt->pntsv * lt->pntsw, lt->def); - } - lt = lt->id.next; + write_dverts(wd, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert); } - - mywrite_flush(wd); } -static void write_images(WriteData *wd, ListBase *idbase) +static void write_image(WriteData *wd, Image *ima) { - Image *ima; - PackedFile *pf; - ImageView *iv; - ImagePackedFile *imapf; - - ima = idbase->first; - while (ima) { - if (ima->id.us > 0 || wd->current) { - /* Some trickery to keep forward compatibility of packed images. */ - BLI_assert(ima->packedfile == NULL); - if (ima->packedfiles.first != NULL) { - imapf = ima->packedfiles.first; - ima->packedfile = imapf->packedfile; - } - - /* write LibData */ - writestruct(wd, ID_IM, Image, 1, ima); - write_iddata(wd, &ima->id); + if (ima->id.us > 0 || wd->current) { + ImagePackedFile *imapf; - for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) { - writestruct(wd, DATA, ImagePackedFile, 1, imapf); - if (imapf->packedfile) { - pf = imapf->packedfile; - writestruct(wd, DATA, PackedFile, 1, pf); - writedata(wd, DATA, pf->size, pf->data); - } - } + /* Some trickery to keep forward compatibility of packed images. */ + BLI_assert(ima->packedfile == NULL); + if (ima->packedfiles.first != NULL) { + imapf = ima->packedfiles.first; + ima->packedfile = imapf->packedfile; + } - write_previews(wd, ima->preview); + /* write LibData */ + writestruct(wd, ID_IM, Image, 1, ima); + write_iddata(wd, &ima->id); - for (iv = ima->views.first; iv; iv = iv->next) { - writestruct(wd, DATA, ImageView, 1, iv); + for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) { + writestruct(wd, DATA, ImagePackedFile, 1, imapf); + if (imapf->packedfile) { + PackedFile *pf = imapf->packedfile; + writestruct(wd, DATA, PackedFile, 1, pf); + writedata(wd, DATA, pf->size, pf->data); } - writestruct(wd, DATA, Stereo3dFormat, 1, ima->stereo3d_format); + } - ima->packedfile = NULL; + write_previews(wd, ima->preview); + + for (ImageView *iv = ima->views.first; iv; iv = iv->next) { + writestruct(wd, DATA, ImageView, 1, iv); } - ima = ima->id.next; - } + writestruct(wd, DATA, Stereo3dFormat, 1, ima->stereo3d_format); - mywrite_flush(wd); + ima->packedfile = NULL; + } } -static void write_textures(WriteData *wd, ListBase *idbase) +static void write_texture(WriteData *wd, Tex *tex) { - Tex *tex; - - tex = idbase->first; - while (tex) { - if (tex->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_TE, Tex, 1, tex); - write_iddata(wd, &tex->id); + if (tex->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_TE, Tex, 1, tex); + write_iddata(wd, &tex->id); - if (tex->adt) { - write_animdata(wd, tex->adt); - } + if (tex->adt) { + write_animdata(wd, tex->adt); + } - /* direct data */ - if (tex->coba) { - writestruct(wd, DATA, ColorBand, 1, tex->coba); - } - if (tex->type == TEX_ENVMAP && tex->env) { - writestruct(wd, DATA, EnvMap, 1, tex->env); - } - if (tex->type == TEX_POINTDENSITY && tex->pd) { - writestruct(wd, DATA, PointDensity, 1, tex->pd); - if (tex->pd->coba) { - writestruct(wd, DATA, ColorBand, 1, tex->pd->coba); - } - if (tex->pd->falloff_curve) { - write_curvemapping(wd, tex->pd->falloff_curve); - } - } - if (tex->type == TEX_VOXELDATA) { - writestruct(wd, DATA, VoxelData, 1, tex->vd); - } - if (tex->type == TEX_OCEAN && tex->ot) { - writestruct(wd, DATA, OceanTex, 1, tex->ot); + /* direct data */ + if (tex->coba) { + writestruct(wd, DATA, ColorBand, 1, tex->coba); + } + if (tex->type == TEX_ENVMAP && tex->env) { + writestruct(wd, DATA, EnvMap, 1, tex->env); + } + if (tex->type == TEX_POINTDENSITY && tex->pd) { + writestruct(wd, DATA, PointDensity, 1, tex->pd); + if (tex->pd->coba) { + writestruct(wd, DATA, ColorBand, 1, tex->pd->coba); } - - /* nodetree is integral part of texture, no libdata */ - if (tex->nodetree) { - writestruct(wd, DATA, bNodeTree, 1, tex->nodetree); - write_nodetree(wd, tex->nodetree); + if (tex->pd->falloff_curve) { + write_curvemapping(wd, tex->pd->falloff_curve); } + } + if (tex->type == TEX_VOXELDATA) { + writestruct(wd, DATA, VoxelData, 1, tex->vd); + } + if (tex->type == TEX_OCEAN && tex->ot) { + writestruct(wd, DATA, OceanTex, 1, tex->ot); + } - write_previews(wd, tex->preview); + /* nodetree is integral part of texture, no libdata */ + if (tex->nodetree) { + writestruct(wd, DATA, bNodeTree, 1, tex->nodetree); + write_nodetree_nolib(wd, tex->nodetree); } - tex = tex->id.next; - } - mywrite_flush(wd); + write_previews(wd, tex->preview); + } } -static void write_materials(WriteData *wd, ListBase *idbase) +static void write_material(WriteData *wd, Material *ma) { - Material *ma; - int a; - - ma = idbase->first; - while (ma) { - if (ma->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_MA, Material, 1, ma); - write_iddata(wd, &ma->id); - - if (ma->adt) { - write_animdata(wd, ma->adt); - } + if (ma->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_MA, Material, 1, ma); + write_iddata(wd, &ma->id); - for (a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a]) { - writestruct(wd, DATA, MTex, 1, ma->mtex[a]); - } - } + if (ma->adt) { + write_animdata(wd, ma->adt); + } - if (ma->ramp_col) { - writestruct(wd, DATA, ColorBand, 1, ma->ramp_col); - } - if (ma->ramp_spec) { - writestruct(wd, DATA, ColorBand, 1, ma->ramp_spec); + for (int a = 0; a < MAX_MTEX; a++) { + if (ma->mtex[a]) { + writestruct(wd, DATA, MTex, 1, ma->mtex[a]); } + } - /* nodetree is integral part of material, no libdata */ - if (ma->nodetree) { - writestruct(wd, DATA, bNodeTree, 1, ma->nodetree); - write_nodetree(wd, ma->nodetree); - } + if (ma->ramp_col) { + writestruct(wd, DATA, ColorBand, 1, ma->ramp_col); + } + if (ma->ramp_spec) { + writestruct(wd, DATA, ColorBand, 1, ma->ramp_spec); + } - write_previews(wd, ma->preview); + /* nodetree is integral part of material, no libdata */ + if (ma->nodetree) { + writestruct(wd, DATA, bNodeTree, 1, ma->nodetree); + write_nodetree_nolib(wd, ma->nodetree); } - ma = ma->id.next; + + write_previews(wd, ma->preview); } } -static void write_worlds(WriteData *wd, ListBase *idbase) +static void write_world(WriteData *wd, World *wrld) { - World *wrld; - int a; - - wrld = idbase->first; - while (wrld) { - if (wrld->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_WO, World, 1, wrld); - write_iddata(wd, &wrld->id); - - if (wrld->adt) { - write_animdata(wd, wrld->adt); - } + if (wrld->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_WO, World, 1, wrld); + write_iddata(wd, &wrld->id); - for (a = 0; a < MAX_MTEX; a++) { - if (wrld->mtex[a]) { - writestruct(wd, DATA, MTex, 1, wrld->mtex[a]); - } - } + if (wrld->adt) { + write_animdata(wd, wrld->adt); + } - /* nodetree is integral part of world, no libdata */ - if (wrld->nodetree) { - writestruct(wd, DATA, bNodeTree, 1, wrld->nodetree); - write_nodetree(wd, wrld->nodetree); + for (int a = 0; a < MAX_MTEX; a++) { + if (wrld->mtex[a]) { + writestruct(wd, DATA, MTex, 1, wrld->mtex[a]); } + } - write_previews(wd, wrld->preview); + /* nodetree is integral part of world, no libdata */ + if (wrld->nodetree) { + writestruct(wd, DATA, bNodeTree, 1, wrld->nodetree); + write_nodetree_nolib(wd, wrld->nodetree); } - wrld = wrld->id.next; + + write_previews(wd, wrld->preview); } } -static void write_lamps(WriteData *wd, ListBase *idbase) +static void write_lamp(WriteData *wd, Lamp *la) { - Lamp *la; - int a; - - la = idbase->first; - while (la) { - if (la->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_LA, Lamp, 1, la); - write_iddata(wd, &la->id); - - if (la->adt) { - write_animdata(wd, la->adt); - } - - /* direct data */ - for (a = 0; a < MAX_MTEX; a++) { - if (la->mtex[a]) { - writestruct(wd, DATA, MTex, 1, la->mtex[a]); - } - } + if (la->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_LA, Lamp, 1, la); + write_iddata(wd, &la->id); - if (la->curfalloff) { - write_curvemapping(wd, la->curfalloff); - } + if (la->adt) { + write_animdata(wd, la->adt); + } - /* nodetree is integral part of lamps, no libdata */ - if (la->nodetree) { - writestruct(wd, DATA, bNodeTree, 1, la->nodetree); - write_nodetree(wd, la->nodetree); + /* direct data */ + for (int a = 0; a < MAX_MTEX; a++) { + if (la->mtex[a]) { + writestruct(wd, DATA, MTex, 1, la->mtex[a]); } + } - write_previews(wd, la->preview); + if (la->curfalloff) { + write_curvemapping(wd, la->curfalloff); + } + /* nodetree is integral part of lamps, no libdata */ + if (la->nodetree) { + writestruct(wd, DATA, bNodeTree, 1, la->nodetree); + write_nodetree_nolib(wd, la->nodetree); } - la = la->id.next; - } - mywrite_flush(wd); + write_previews(wd, la->preview); + } } static void write_sequence_modifiers(WriteData *wd, ListBase *modbase) @@ -2626,290 +2537,249 @@ static void write_paint(WriteData *wd, Paint *p) } } -static void write_scenes(WriteData *wd, ListBase *scebase) +static void write_scene(WriteData *wd, Scene *sce) { - Scene *sce; - Base *base; - Editing *ed; - Sequence *seq; - MetaStack *ms; - Strip *strip; - TimeMarker *marker; - TransformOrientation *ts; - SceneRenderLayer *srl; - SceneRenderView *srv; - ToolSettings *tos; - FreestyleModuleConfig *fmc; - FreestyleLineSet *fls; - - sce = scebase->first; - while (sce) { - /* write LibData */ - writestruct(wd, ID_SCE, Scene, 1, sce); - write_iddata(wd, &sce->id); + /* write LibData */ + writestruct(wd, ID_SCE, Scene, 1, sce); + write_iddata(wd, &sce->id); - if (sce->adt) { - write_animdata(wd, sce->adt); - } - write_keyingsets(wd, &sce->keyingsets); + if (sce->adt) { + write_animdata(wd, sce->adt); + } + write_keyingsets(wd, &sce->keyingsets); - /* direct data */ - base = sce->base.first; - while (base) { - writestruct(wd, DATA, Base, 1, base); - base = base->next; - } - - tos = sce->toolsettings; - writestruct(wd, DATA, ToolSettings, 1, tos); - if (tos->vpaint) { - writestruct(wd, DATA, VPaint, 1, tos->vpaint); - write_paint(wd, &tos->vpaint->paint); - } - if (tos->wpaint) { - writestruct(wd, DATA, VPaint, 1, tos->wpaint); - write_paint(wd, &tos->wpaint->paint); - } - if (tos->sculpt) { - writestruct(wd, DATA, Sculpt, 1, tos->sculpt); - write_paint(wd, &tos->sculpt->paint); - } - if (tos->uvsculpt) { - writestruct(wd, DATA, UvSculpt, 1, tos->uvsculpt); - write_paint(wd, &tos->uvsculpt->paint); - } - /* write grease-pencil drawing brushes to file */ - writelist(wd, DATA, bGPDbrush, &tos->gp_brushes); - for (bGPDbrush *brush = tos->gp_brushes.first; brush; brush = brush->next) { - if (brush->cur_sensitivity) { - write_curvemapping(wd, brush->cur_sensitivity); - } - if (brush->cur_strength) { - write_curvemapping(wd, brush->cur_strength); - } - if (brush->cur_jitter) { - write_curvemapping(wd, brush->cur_jitter); - } + /* direct data */ + for (Base *base = sce->base.first; base; base = base->next) { + writestruct(wd, DATA, Base, 1, base); + } + + ToolSettings *tos = sce->toolsettings; + writestruct(wd, DATA, ToolSettings, 1, tos); + if (tos->vpaint) { + writestruct(wd, DATA, VPaint, 1, tos->vpaint); + write_paint(wd, &tos->vpaint->paint); + } + if (tos->wpaint) { + writestruct(wd, DATA, VPaint, 1, tos->wpaint); + write_paint(wd, &tos->wpaint->paint); + } + if (tos->sculpt) { + writestruct(wd, DATA, Sculpt, 1, tos->sculpt); + write_paint(wd, &tos->sculpt->paint); + } + if (tos->uvsculpt) { + writestruct(wd, DATA, UvSculpt, 1, tos->uvsculpt); + write_paint(wd, &tos->uvsculpt->paint); + } + /* write grease-pencil drawing brushes to file */ + writelist(wd, DATA, bGPDbrush, &tos->gp_brushes); + for (bGPDbrush *brush = tos->gp_brushes.first; brush; brush = brush->next) { + if (brush->cur_sensitivity) { + write_curvemapping(wd, brush->cur_sensitivity); + } + if (brush->cur_strength) { + write_curvemapping(wd, brush->cur_strength); } - + if (brush->cur_jitter) { + write_curvemapping(wd, brush->cur_jitter); + } + } + /* write grease-pencil custom ipo curve to file */ + if (tos->gp_interpolate.custom_ipo) { + write_curvemapping(wd, tos->gp_interpolate.custom_ipo); + } - write_paint(wd, &tos->imapaint.paint); - ed = sce->ed; - if (ed) { - writestruct(wd, DATA, Editing, 1, ed); + write_paint(wd, &tos->imapaint.paint); - /* reset write flags too */ + Editing *ed = sce->ed; + if (ed) { + Sequence *seq; - SEQ_BEGIN(ed, seq) - { - if (seq->strip) { - seq->strip->done = false; - } - writestruct(wd, DATA, Sequence, 1, seq); - } - SEQ_END + writestruct(wd, DATA, Editing, 1, ed); - SEQ_BEGIN(ed, seq) - { - if (seq->strip && seq->strip->done == 0) { - /* write strip with 'done' at 0 because readfile */ - - if (seq->effectdata) { - switch (seq->type) { - case SEQ_TYPE_COLOR: - writestruct(wd, DATA, SolidColorVars, 1, seq->effectdata); - break; - case SEQ_TYPE_SPEED: - writestruct(wd, DATA, SpeedControlVars, 1, seq->effectdata); - break; - case SEQ_TYPE_WIPE: - writestruct(wd, DATA, WipeVars, 1, seq->effectdata); - break; - case SEQ_TYPE_GLOW: - writestruct(wd, DATA, GlowVars, 1, seq->effectdata); - break; - case SEQ_TYPE_TRANSFORM: - writestruct(wd, DATA, TransformVars, 1, seq->effectdata); - break; - case SEQ_TYPE_GAUSSIAN_BLUR: - writestruct(wd, DATA, GaussianBlurVars, 1, seq->effectdata); - break; - case SEQ_TYPE_TEXT: - writestruct(wd, DATA, TextVars, 1, seq->effectdata); - break; - } - } + /* reset write flags too */ - writestruct(wd, DATA, Stereo3dFormat, 1, seq->stereo3d_format); + SEQ_BEGIN(ed, seq) + { + if (seq->strip) { + seq->strip->done = false; + } + writestruct(wd, DATA, Sequence, 1, seq); + } + SEQ_END - 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->type == SEQ_TYPE_IMAGE) { - writestruct(wd, DATA, StripElem, - MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem), - strip->stripdata); - } - else if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { - writestruct(wd, DATA, StripElem, 1, strip->stripdata); + SEQ_BEGIN(ed, seq) + { + if (seq->strip && seq->strip->done == 0) { + /* write strip with 'done' at 0 because readfile */ + + if (seq->effectdata) { + switch (seq->type) { + case SEQ_TYPE_COLOR: + writestruct(wd, DATA, SolidColorVars, 1, seq->effectdata); + break; + case SEQ_TYPE_SPEED: + writestruct(wd, DATA, SpeedControlVars, 1, seq->effectdata); + break; + case SEQ_TYPE_WIPE: + writestruct(wd, DATA, WipeVars, 1, seq->effectdata); + break; + case SEQ_TYPE_GLOW: + writestruct(wd, DATA, GlowVars, 1, seq->effectdata); + break; + case SEQ_TYPE_TRANSFORM: + writestruct(wd, DATA, TransformVars, 1, seq->effectdata); + break; + case SEQ_TYPE_GAUSSIAN_BLUR: + writestruct(wd, DATA, GaussianBlurVars, 1, seq->effectdata); + break; + case SEQ_TYPE_TEXT: + writestruct(wd, DATA, TextVars, 1, seq->effectdata); + break; } - - strip->done = true; } - if (seq->prop) { - IDP_WriteProperty(seq->prop, wd); + writestruct(wd, DATA, Stereo3dFormat, 1, seq->stereo3d_format); + + Strip *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->type == SEQ_TYPE_IMAGE) { + writestruct(wd, DATA, StripElem, + MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem), + strip->stripdata); + } + else if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { + writestruct(wd, DATA, StripElem, 1, strip->stripdata); } - write_sequence_modifiers(wd, &seq->modifiers); + strip->done = true; } - SEQ_END - /* new; meta stack too, even when its nasty restore code */ - for (ms = ed->metastack.first; ms; ms = ms->next) { - writestruct(wd, DATA, MetaStack, 1, ms); + if (seq->prop) { + IDP_WriteProperty(seq->prop, wd); } + + write_sequence_modifiers(wd, &seq->modifiers); } + SEQ_END - if (sce->r.avicodecdata) { - writestruct(wd, DATA, AviCodecData, 1, sce->r.avicodecdata); - if (sce->r.avicodecdata->lpFormat) { - writedata(wd, DATA, sce->r.avicodecdata->cbFormat, sce->r.avicodecdata->lpFormat); - } - if (sce->r.avicodecdata->lpParms) { - writedata(wd, DATA, sce->r.avicodecdata->cbParms, sce->r.avicodecdata->lpParms); - } + /* new; meta stack too, even when its nasty restore code */ + for (MetaStack *ms = ed->metastack.first; ms; ms = ms->next) { + writestruct(wd, DATA, MetaStack, 1, ms); } + } - if (sce->r.qtcodecdata) { - 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.avicodecdata) { + writestruct(wd, DATA, AviCodecData, 1, sce->r.avicodecdata); + if (sce->r.avicodecdata->lpFormat) { + writedata(wd, DATA, sce->r.avicodecdata->cbFormat, sce->r.avicodecdata->lpFormat); } - if (sce->r.ffcodecdata.properties) { - IDP_WriteProperty(sce->r.ffcodecdata.properties, wd); + if (sce->r.avicodecdata->lpParms) { + writedata(wd, DATA, sce->r.avicodecdata->cbParms, sce->r.avicodecdata->lpParms); } + } + 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 TimeMarkers to the blend file */ + for (TimeMarker *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); - } + /* writing dynamic list of TransformOrientations to the blend file */ + for (TransformOrientation *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); - for (fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) { - writestruct(wd, DATA, FreestyleModuleConfig, 1, fmc); - } - for (fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) { - writestruct(wd, DATA, FreestyleLineSet, 1, fls); - } + for (SceneRenderLayer *srl = sce->r.layers.first; srl; srl = srl->next) { + writestruct(wd, DATA, SceneRenderLayer, 1, srl); + if (srl->prop) { + IDP_WriteProperty(srl->prop, wd); } - - /* writing MultiView to the blend file */ - for (srv = sce->r.views.first; srv; srv = srv->next) { - writestruct(wd, DATA, SceneRenderView, 1, srv); + for (FreestyleModuleConfig *fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) { + writestruct(wd, DATA, FreestyleModuleConfig, 1, fmc); } - - if (sce->nodetree) { - writestruct(wd, DATA, bNodeTree, 1, sce->nodetree); - write_nodetree(wd, sce->nodetree); + for (FreestyleLineSet *fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) { + writestruct(wd, DATA, FreestyleLineSet, 1, fls); } + } - write_view_settings(wd, &sce->view_settings); + /* writing MultiView to the blend file */ + for (SceneRenderView *srv = sce->r.views.first; srv; srv = srv->next) { + writestruct(wd, DATA, SceneRenderView, 1, srv); + } - /* writing RigidBodyWorld data to the blend file */ - if (sce->rigidbody_world) { - writestruct(wd, DATA, RigidBodyWorld, 1, sce->rigidbody_world); - writestruct(wd, DATA, EffectorWeights, 1, sce->rigidbody_world->effector_weights); - write_pointcaches(wd, &(sce->rigidbody_world->ptcaches)); - } + if (sce->nodetree) { + writestruct(wd, DATA, bNodeTree, 1, sce->nodetree); + write_nodetree_nolib(wd, sce->nodetree); + } - write_previews(wd, sce->preview); - write_curvemapping_curves(wd, &sce->r.mblur_shutter_curve); + write_view_settings(wd, &sce->view_settings); - sce = sce->id.next; + /* writing RigidBodyWorld data to the blend file */ + if (sce->rigidbody_world) { + writestruct(wd, DATA, RigidBodyWorld, 1, sce->rigidbody_world); + writestruct(wd, DATA, EffectorWeights, 1, sce->rigidbody_world->effector_weights); + write_pointcaches(wd, &(sce->rigidbody_world->ptcaches)); } - mywrite_flush(wd); + write_previews(wd, sce->preview); + write_curvemapping_curves(wd, &sce->r.mblur_shutter_curve); } -static void write_gpencils(WriteData *wd, ListBase *lb) +static void write_gpencil(WriteData *wd, bGPdata *gpd) { - bGPdata *gpd; - bGPDlayer *gpl; - bGPDframe *gpf; - bGPDstroke *gps; - bGPDpalette *palette; - - for (gpd = lb->first; gpd; gpd = gpd->id.next) { - if (gpd->id.us > 0 || wd->current) { - /* write gpd data block to file */ - writestruct(wd, ID_GD, bGPdata, 1, gpd); - write_iddata(wd, &gpd->id); - - if (gpd->adt) { - write_animdata(wd, gpd->adt); - } - - /* write grease-pencil layers to file */ - writelist(wd, DATA, bGPDlayer, &gpd->layers); - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - - /* write this layer's frames to file */ - writelist(wd, DATA, bGPDframe, &gpl->frames); - for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { - - /* write strokes */ - writelist(wd, DATA, bGPDstroke, &gpf->strokes); - for (gps = gpf->strokes.first; gps; gps = gps->next) { - writestruct(wd, DATA, bGPDspoint, gps->totpoints, gps->points); - } + if (gpd->id.us > 0 || wd->current) { + /* write gpd data block to file */ + writestruct(wd, ID_GD, bGPdata, 1, gpd); + write_iddata(wd, &gpd->id); + + if (gpd->adt) { + write_animdata(wd, gpd->adt); + } + + /* write grease-pencil layers to file */ + writelist(wd, DATA, bGPDlayer, &gpd->layers); + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* write this layer's frames to file */ + writelist(wd, DATA, bGPDframe, &gpl->frames); + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + /* write strokes */ + writelist(wd, DATA, bGPDstroke, &gpf->strokes); + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + writestruct(wd, DATA, bGPDspoint, gps->totpoints, gps->points); } } - /* write grease-pencil palettes */ - writelist(wd, DATA, bGPDpalette, &gpd->palettes); - for (palette = gpd->palettes.first; palette; palette = palette->next) { - writelist(wd, DATA, bGPDpalettecolor, &palette->colors); - } } - } - mywrite_flush(wd); + /* write grease-pencil palettes */ + writelist(wd, DATA, bGPDpalette, &gpd->palettes); + for (bGPDpalette *palette = gpd->palettes.first; palette; palette = palette->next) { + writelist(wd, DATA, bGPDpalettecolor, &palette->colors); + } + } } -static void write_windowmanagers(WriteData *wd, ListBase *lb) +static void write_windowmanager(WriteData *wd, wmWindowManager *wm) { - wmWindowManager *wm; - wmWindow *win; - - for (wm = lb->first; wm; wm = wm->id.next) { - writestruct(wd, ID_WM, wmWindowManager, 1, wm); - write_iddata(wd, &wm->id); + writestruct(wd, ID_WM, wmWindowManager, 1, wm); + write_iddata(wd, &wm->id); - for (win = wm->windows.first; win; win = win->next) { - writestruct(wd, DATA, wmWindow, 1, win); - writestruct(wd, DATA, Stereo3dFormat, 1, win->stereo3d_format); - } + for (wmWindow *win = wm->windows.first; win; win = win->next) { + writestruct(wd, DATA, wmWindow, 1, win); + writestruct(wd, DATA, Stereo3dFormat, 1, win->stereo3d_format); } - - /* typically flushing wouldn't be needed however this data _always_ changes, - * so flush here for more efficient undo. */ - mywrite_flush(wd); } static void write_region(WriteData *wd, ARegion *ar, int spacetype) @@ -2992,184 +2862,168 @@ static void write_soops(WriteData *wd, SpaceOops *so) } } -static void write_screens(WriteData *wd, ListBase *scrbase) +static void write_screen(WriteData *wd, bScreen *sc) { - bScreen *sc; - ScrArea *sa; - ScrVert *sv; - ScrEdge *se; - - sc = scrbase->first; - while (sc) { + /* write LibData */ + /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */ + writestruct(wd, ID_SCRN, bScreen, 1, sc); + write_iddata(wd, &sc->id); - /* write LibData */ - /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */ - writestruct(wd, ID_SCRN, bScreen, 1, sc); - write_iddata(wd, &sc->id); + /* direct data */ + for (ScrVert *sv = sc->vertbase.first; sv; sv = sv->next) { + writestruct(wd, DATA, ScrVert, 1, sv); + } - /* direct data */ - for (sv = sc->vertbase.first; sv; sv = sv->next) { - writestruct(wd, DATA, ScrVert, 1, sv); - } + for (ScrEdge *se = sc->edgebase.first; se; se = se->next) { + writestruct(wd, DATA, ScrEdge, 1, se); + } - for (se = sc->edgebase.first; se; se = se->next) { - writestruct(wd, DATA, ScrEdge, 1, se); - } + for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + Panel *pa; + uiList *ui_list; + uiPreview *ui_preview; + PanelCategoryStack *pc_act; + ARegion *ar; - for (sa = sc->areabase.first; sa; sa = sa->next) { - SpaceLink *sl; - Panel *pa; - uiList *ui_list; - uiPreview *ui_preview; - PanelCategoryStack *pc_act; - ARegion *ar; + writestruct(wd, DATA, ScrArea, 1, sa); - writestruct(wd, DATA, ScrArea, 1, sa); + for (ar = sa->regionbase.first; ar; ar = ar->next) { + write_region(wd, ar, sa->spacetype); - for (ar = sa->regionbase.first; ar; ar = ar->next) { - write_region(wd, ar, sa->spacetype); + for (pa = ar->panels.first; pa; pa = pa->next) { + writestruct(wd, DATA, Panel, 1, pa); + } - for (pa = ar->panels.first; pa; pa = pa->next) { - writestruct(wd, DATA, Panel, 1, pa); - } + for (pc_act = ar->panels_category_active.first; pc_act; pc_act = pc_act->next) { + writestruct(wd, DATA, PanelCategoryStack, 1, pc_act); + } - for (pc_act = ar->panels_category_active.first; pc_act; pc_act = pc_act->next) { - writestruct(wd, DATA, PanelCategoryStack, 1, pc_act); - } + for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next) { + write_uilist(wd, ui_list); + } - for (ui_list = ar->ui_lists.first; ui_list; ui_list = ui_list->next) { - write_uilist(wd, ui_list); - } + for (ui_preview = ar->ui_previews.first; ui_preview; ui_preview = ui_preview->next) { + writestruct(wd, DATA, uiPreview, 1, ui_preview); + } + } - for (ui_preview = ar->ui_previews.first; ui_preview; ui_preview = ui_preview->next) { - writestruct(wd, DATA, uiPreview, 1, ui_preview); - } + for (sl = sa->spacedata.first; sl; sl = sl->next) { + for (ar = sl->regionbase.first; ar; ar = ar->next) { + write_region(wd, ar, sl->spacetype); } - sl = sa->spacedata.first; - while (sl) { - for (ar = sl->regionbase.first; ar; ar = ar->next) { - write_region(wd, ar, sl->spacetype); + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + BGpic *bgpic; + writestruct(wd, DATA, View3D, 1, v3d); + for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { + writestruct(wd, DATA, BGpic, 1, bgpic); } - - if (sl->spacetype == SPACE_VIEW3D) { - View3D *v3d = (View3D *)sl; - BGpic *bgpic; - writestruct(wd, DATA, View3D, 1, v3d); - for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { - writestruct(wd, DATA, BGpic, 1, bgpic); - } - if (v3d->localvd) { - writestruct(wd, DATA, View3D, 1, v3d->localvd); - } - - if (v3d->fx_settings.ssao) { - writestruct(wd, DATA, GPUSSAOSettings, 1, v3d->fx_settings.ssao); - } - if (v3d->fx_settings.dof) { - writestruct(wd, DATA, GPUDOFSettings, 1, v3d->fx_settings.dof); - } + if (v3d->localvd) { + writestruct(wd, DATA, View3D, 1, v3d->localvd); } - else if (sl->spacetype == SPACE_IPO) { - SpaceIpo *sipo = (SpaceIpo *)sl; - ListBase tmpGhosts = sipo->ghostCurves; - - /* temporarily disable ghost curves when saving */ - sipo->ghostCurves.first = sipo->ghostCurves.last = NULL; - writestruct(wd, DATA, SpaceIpo, 1, sl); - if (sipo->ads) { - writestruct(wd, DATA, bDopeSheet, 1, sipo->ads); - } - - /* reenable ghost curves */ - sipo->ghostCurves = tmpGhosts; + if (v3d->fx_settings.ssao) { + writestruct(wd, DATA, GPUSSAOSettings, 1, v3d->fx_settings.ssao); } - else if (sl->spacetype == SPACE_BUTS) { - writestruct(wd, DATA, SpaceButs, 1, sl); + if (v3d->fx_settings.dof) { + writestruct(wd, DATA, GPUDOFSettings, 1, v3d->fx_settings.dof); } - else if (sl->spacetype == SPACE_FILE) { - SpaceFile *sfile = (SpaceFile *)sl; + } + else if (sl->spacetype == SPACE_IPO) { + SpaceIpo *sipo = (SpaceIpo *)sl; + ListBase tmpGhosts = sipo->ghostCurves; - writestruct(wd, DATA, SpaceFile, 1, sl); - if (sfile->params) { - writestruct(wd, DATA, FileSelectParams, 1, sfile->params); - } - } - else if (sl->spacetype == SPACE_SEQ) { - writestruct(wd, DATA, SpaceSeq, 1, sl); - } - else if (sl->spacetype == SPACE_OUTLINER) { - SpaceOops *so = (SpaceOops *)sl; - write_soops(wd, so); - } - else if (sl->spacetype == SPACE_IMAGE) { - writestruct(wd, DATA, SpaceImage, 1, sl); - } - else if (sl->spacetype == SPACE_TEXT) { - writestruct(wd, DATA, SpaceText, 1, sl); - } - else if (sl->spacetype == SPACE_SCRIPT) { - SpaceScript *scr = (SpaceScript *)sl; - scr->but_refs = NULL; - writestruct(wd, DATA, SpaceScript, 1, sl); - } - else if (sl->spacetype == SPACE_ACTION) { - writestruct(wd, DATA, SpaceAction, 1, sl); - } - else if (sl->spacetype == SPACE_NLA) { - SpaceNla *snla = (SpaceNla *)sl; + /* temporarily disable ghost curves when saving */ + sipo->ghostCurves.first = sipo->ghostCurves.last = NULL; - writestruct(wd, DATA, SpaceNla, 1, snla); - if (snla->ads) { - writestruct(wd, DATA, bDopeSheet, 1, snla->ads); - } - } - else if (sl->spacetype == SPACE_TIME) { - writestruct(wd, DATA, SpaceTime, 1, sl); + writestruct(wd, DATA, SpaceIpo, 1, sl); + if (sipo->ads) { + writestruct(wd, DATA, bDopeSheet, 1, sipo->ads); } - else if (sl->spacetype == SPACE_NODE) { - SpaceNode *snode = (SpaceNode *)sl; - bNodeTreePath *path; - writestruct(wd, DATA, SpaceNode, 1, snode); - for (path = snode->treepath.first; path; path = path->next) { - writestruct(wd, DATA, bNodeTreePath, 1, path); - } - } - else if (sl->spacetype == SPACE_LOGIC) { - writestruct(wd, DATA, SpaceLogic, 1, sl); - } - else if (sl->spacetype == SPACE_CONSOLE) { - SpaceConsole *con = (SpaceConsole *)sl; - ConsoleLine *cl; - - for (cl = con->history.first; cl; cl = cl->next) { - /* 'len_alloc' is invalid on write, set from 'len' on read */ - writestruct(wd, DATA, ConsoleLine, 1, cl); - writedata(wd, DATA, cl->len + 1, cl->line); - } - writestruct(wd, DATA, SpaceConsole, 1, sl); + /* reenable ghost curves */ + sipo->ghostCurves = tmpGhosts; + } + else if (sl->spacetype == SPACE_BUTS) { + writestruct(wd, DATA, SpaceButs, 1, sl); + } + else if (sl->spacetype == SPACE_FILE) { + SpaceFile *sfile = (SpaceFile *)sl; + writestruct(wd, DATA, SpaceFile, 1, sl); + if (sfile->params) { + writestruct(wd, DATA, FileSelectParams, 1, sfile->params); } - else if (sl->spacetype == SPACE_USERPREF) { - writestruct(wd, DATA, SpaceUserPref, 1, sl); + } + else if (sl->spacetype == SPACE_SEQ) { + writestruct(wd, DATA, SpaceSeq, 1, sl); + } + else if (sl->spacetype == SPACE_OUTLINER) { + SpaceOops *so = (SpaceOops *)sl; + write_soops(wd, so); + } + else if (sl->spacetype == SPACE_IMAGE) { + writestruct(wd, DATA, SpaceImage, 1, sl); + } + else if (sl->spacetype == SPACE_TEXT) { + writestruct(wd, DATA, SpaceText, 1, sl); + } + else if (sl->spacetype == SPACE_SCRIPT) { + SpaceScript *scr = (SpaceScript *)sl; + scr->but_refs = NULL; + writestruct(wd, DATA, SpaceScript, 1, sl); + } + else if (sl->spacetype == SPACE_ACTION) { + writestruct(wd, DATA, SpaceAction, 1, sl); + } + else if (sl->spacetype == SPACE_NLA) { + SpaceNla *snla = (SpaceNla *)sl; + + writestruct(wd, DATA, SpaceNla, 1, snla); + if (snla->ads) { + writestruct(wd, DATA, bDopeSheet, 1, snla->ads); } - else if (sl->spacetype == SPACE_CLIP) { - writestruct(wd, DATA, SpaceClip, 1, sl); + } + else if (sl->spacetype == SPACE_TIME) { + writestruct(wd, DATA, SpaceTime, 1, sl); + } + else if (sl->spacetype == SPACE_NODE) { + SpaceNode *snode = (SpaceNode *)sl; + bNodeTreePath *path; + writestruct(wd, DATA, SpaceNode, 1, snode); + + for (path = snode->treepath.first; path; path = path->next) { + writestruct(wd, DATA, bNodeTreePath, 1, path); } - else if (sl->spacetype == SPACE_INFO) { - writestruct(wd, DATA, SpaceInfo, 1, sl); + } + else if (sl->spacetype == SPACE_LOGIC) { + writestruct(wd, DATA, SpaceLogic, 1, sl); + } + else if (sl->spacetype == SPACE_CONSOLE) { + SpaceConsole *con = (SpaceConsole *)sl; + ConsoleLine *cl; + + for (cl = con->history.first; cl; cl = cl->next) { + /* 'len_alloc' is invalid on write, set from 'len' on read */ + writestruct(wd, DATA, ConsoleLine, 1, cl); + writedata(wd, DATA, cl->len + 1, cl->line); } + writestruct(wd, DATA, SpaceConsole, 1, sl); - sl = sl->next; + } + else if (sl->spacetype == SPACE_USERPREF) { + writestruct(wd, DATA, SpaceUserPref, 1, sl); + } + else if (sl->spacetype == SPACE_CLIP) { + writestruct(wd, DATA, SpaceClip, 1, sl); + } + else if (sl->spacetype == SPACE_INFO) { + writestruct(wd, DATA, SpaceInfo, 1, sl); } } - - sc = sc->id.next; } - - mywrite_flush(wd); } static void write_bone(WriteData *wd, Bone *bone) @@ -3192,156 +3046,101 @@ static void write_bone(WriteData *wd, Bone *bone) } } -static void write_armatures(WriteData *wd, ListBase *idbase) +static void write_armature(WriteData *wd, bArmature *arm) { - bArmature *arm; - Bone *bone; - - arm = idbase->first; - while (arm) { - if (arm->id.us > 0 || wd->current) { - writestruct(wd, ID_AR, bArmature, 1, arm); - write_iddata(wd, &arm->id); + if (arm->id.us > 0 || wd->current) { + writestruct(wd, ID_AR, bArmature, 1, arm); + write_iddata(wd, &arm->id); - if (arm->adt) { - write_animdata(wd, arm->adt); - } + if (arm->adt) { + write_animdata(wd, arm->adt); + } - /* Direct data */ - bone = arm->bonebase.first; - while (bone) { - write_bone(wd, bone); - bone = bone->next; - } + /* Direct data */ + for (Bone *bone = arm->bonebase.first; bone; bone = bone->next) { + write_bone(wd, bone); } - arm = arm->id.next; } - - mywrite_flush(wd); } -static void write_texts(WriteData *wd, ListBase *idbase) +static void write_text(WriteData *wd, Text *text) { - Text *text; - TextLine *tmp; + if ((text->flags & TXT_ISMEM) && (text->flags & TXT_ISEXT)) { + text->flags &= ~TXT_ISEXT; + } - text = idbase->first; - while (text) { - if ( (text->flags & TXT_ISMEM) && (text->flags & TXT_ISEXT)) { - text->flags &= ~TXT_ISEXT; - } + /* write LibData */ + writestruct(wd, ID_TXT, Text, 1, text); + write_iddata(wd, &text->id); - /* write LibData */ - writestruct(wd, ID_TXT, Text, 1, text); - write_iddata(wd, &text->id); + if (text->name) { + writedata(wd, DATA, strlen(text->name) + 1, text->name); + } - if (text->name) { - writedata(wd, DATA, strlen(text->name) + 1, text->name); + if (!(text->flags & TXT_ISEXT)) { + /* now write the text data, in two steps for optimization in the readfunction */ + for (TextLine *tmp = text->lines.first; tmp; tmp = tmp->next) { + writestruct(wd, DATA, TextLine, 1, tmp); } - if (!(text->flags & TXT_ISEXT)) { - /* now write the text data, in two steps for optimization in the readfunction */ - tmp = text->lines.first; - while (tmp) { - writestruct(wd, DATA, TextLine, 1, tmp); - tmp = tmp->next; - } - - tmp = text->lines.first; - while (tmp) { - writedata(wd, DATA, tmp->len + 1, tmp->line); - tmp = tmp->next; - } + for (TextLine *tmp = text->lines.first; tmp; tmp = tmp->next) { + writedata(wd, DATA, tmp->len + 1, tmp->line); } - - - text = text->id.next; } - - mywrite_flush(wd); } -static void write_speakers(WriteData *wd, ListBase *idbase) +static void write_speaker(WriteData *wd, Speaker *spk) { - Speaker *spk; - - spk = idbase->first; - while (spk) { - if (spk->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_SPK, Speaker, 1, spk); - write_iddata(wd, &spk->id); + if (spk->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_SPK, Speaker, 1, spk); + write_iddata(wd, &spk->id); - if (spk->adt) { - write_animdata(wd, spk->adt); - } + if (spk->adt) { + write_animdata(wd, spk->adt); } - spk = spk->id.next; } } -static void write_sounds(WriteData *wd, ListBase *idbase) +static void write_sound(WriteData *wd, bSound *sound) { - bSound *sound; - - PackedFile *pf; - - sound = idbase->first; - while (sound) { - if (sound->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_SO, bSound, 1, sound); - write_iddata(wd, &sound->id); + if (sound->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_SO, bSound, 1, sound); + write_iddata(wd, &sound->id); - if (sound->packedfile) { - pf = sound->packedfile; - writestruct(wd, DATA, PackedFile, 1, pf); - writedata(wd, DATA, pf->size, pf->data); - } + if (sound->packedfile) { + PackedFile *pf = sound->packedfile; + writestruct(wd, DATA, PackedFile, 1, pf); + writedata(wd, DATA, pf->size, pf->data); } - sound = sound->id.next; } - - mywrite_flush(wd); } -static void write_groups(WriteData *wd, ListBase *idbase) +static void write_group(WriteData *wd, Group *group) { - Group *group; - GroupObject *go; - - for (group = idbase->first; group; group = group->id.next) { - if (group->id.us > 0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_GR, Group, 1, group); - write_iddata(wd, &group->id); + if (group->id.us > 0 || wd->current) { + /* write LibData */ + writestruct(wd, ID_GR, Group, 1, group); + write_iddata(wd, &group->id); - write_previews(wd, group->preview); + write_previews(wd, group->preview); - go = group->gobject.first; - while (go) { - writestruct(wd, DATA, GroupObject, 1, go); - go = go->next; - } + for (GroupObject *go = group->gobject.first; go; go = go->next) { + writestruct(wd, DATA, GroupObject, 1, go); } } - - mywrite_flush(wd); } -static void write_nodetrees(WriteData *wd, ListBase *idbase) +static void write_nodetree(WriteData *wd, bNodeTree *ntree) { - bNodeTree *ntree; - - for (ntree = idbase->first; ntree; ntree = ntree->id.next) { - if (ntree->id.us > 0 || wd->current) { - writestruct(wd, ID_NT, bNodeTree, 1, ntree); - /* Note that trees directly used by other IDs (materials etc.) are not 'real' ID, they cannot - * be linked, etc., so we write actual id data here only, for 'real' ID trees. */ - write_iddata(wd, &ntree->id); + if (ntree->id.us > 0 || wd->current) { + writestruct(wd, ID_NT, bNodeTree, 1, ntree); + /* Note that trees directly used by other IDs (materials etc.) are not 'real' ID, they cannot + * be linked, etc., so we write actual id data here only, for 'real' ID trees. */ + write_iddata(wd, &ntree->id); - write_nodetree(wd, ntree); - } + write_nodetree_nolib(wd, ntree); } } @@ -3415,53 +3214,41 @@ static void customnodes_free_deprecated_data(Main *mainvar) } #endif -static void write_brushes(WriteData *wd, ListBase *idbase) +static void write_brush(WriteData *wd, Brush *brush) { - Brush *brush; - - for (brush = idbase->first; brush; brush = brush->id.next) { - if (brush->id.us > 0 || wd->current) { - writestruct(wd, ID_BR, Brush, 1, brush); - write_iddata(wd, &brush->id); + if (brush->id.us > 0 || wd->current) { + writestruct(wd, ID_BR, Brush, 1, brush); + write_iddata(wd, &brush->id); - if (brush->curve) { - write_curvemapping(wd, brush->curve); - } - if (brush->gradient) { - writestruct(wd, DATA, ColorBand, 1, brush->gradient); - } + if (brush->curve) { + write_curvemapping(wd, brush->curve); + } + if (brush->gradient) { + writestruct(wd, DATA, ColorBand, 1, brush->gradient); } } } -static void write_palettes(WriteData *wd, ListBase *idbase) +static void write_palette(WriteData *wd, Palette *palette) { - Palette *palette; - - for (palette = idbase->first; palette; palette = palette->id.next) { - if (palette->id.us > 0 || wd->current) { - PaletteColor *color; - writestruct(wd, ID_PAL, Palette, 1, palette); - write_iddata(wd, &palette->id); + if (palette->id.us > 0 || wd->current) { + PaletteColor *color; + writestruct(wd, ID_PAL, Palette, 1, palette); + write_iddata(wd, &palette->id); - for (color = palette->colors.first; color; color = color->next) { - writestruct(wd, DATA, PaletteColor, 1, color); - } + for (color = palette->colors.first; color; color = color->next) { + writestruct(wd, DATA, PaletteColor, 1, color); } } } -static void write_paintcurves(WriteData *wd, ListBase *idbase) +static void write_paintcurve(WriteData *wd, PaintCurve *pc) { - PaintCurve *pc; - - for (pc = idbase->first; pc; pc = pc->id.next) { - if (pc->id.us > 0 || wd->current) { - writestruct(wd, ID_PC, PaintCurve, 1, pc); - write_iddata(wd, &pc->id); + if (pc->id.us > 0 || wd->current) { + writestruct(wd, ID_PC, PaintCurve, 1, pc); + write_iddata(wd, &pc->id); - writestruct(wd, DATA, PaintCurvePoint, pc->tot_points, pc->points); - } + writestruct(wd, DATA, PaintCurvePoint, pc->tot_points, pc->points); } } @@ -3503,103 +3290,85 @@ static void write_movieReconstruction(WriteData *wd, MovieTrackingReconstruction } } -static void write_movieclips(WriteData *wd, ListBase *idbase) +static void write_movieclip(WriteData *wd, MovieClip *clip) { - MovieClip *clip; - - clip = idbase->first; - while (clip) { - if (clip->id.us > 0 || wd->current) { - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *object; + if (clip->id.us > 0 || wd->current) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *object; - writestruct(wd, ID_MC, MovieClip, 1, clip); - write_iddata(wd, &clip->id); + writestruct(wd, ID_MC, MovieClip, 1, clip); + write_iddata(wd, &clip->id); - if (clip->adt) { - write_animdata(wd, clip->adt); - } + if (clip->adt) { + write_animdata(wd, clip->adt); + } - write_movieTracks(wd, &tracking->tracks); - write_moviePlaneTracks(wd, &tracking->plane_tracks); - write_movieReconstruction(wd, &tracking->reconstruction); + write_movieTracks(wd, &tracking->tracks); + write_moviePlaneTracks(wd, &tracking->plane_tracks); + write_movieReconstruction(wd, &tracking->reconstruction); - object = tracking->objects.first; - while (object) { - writestruct(wd, DATA, MovieTrackingObject, 1, object); + object = tracking->objects.first; + while (object) { + writestruct(wd, DATA, MovieTrackingObject, 1, object); - write_movieTracks(wd, &object->tracks); - write_moviePlaneTracks(wd, &object->plane_tracks); - write_movieReconstruction(wd, &object->reconstruction); + write_movieTracks(wd, &object->tracks); + write_moviePlaneTracks(wd, &object->plane_tracks); + write_movieReconstruction(wd, &object->reconstruction); - object = object->next; - } + object = object->next; } - - clip = clip->id.next; } - - mywrite_flush(wd); } -static void write_masks(WriteData *wd, ListBase *idbase) +static void write_mask(WriteData *wd, Mask *mask) { - Mask *mask; - - mask = idbase->first; - while (mask) { - if (mask->id.us > 0 || wd->current) { - MaskLayer *masklay; + if (mask->id.us > 0 || wd->current) { + MaskLayer *masklay; - writestruct(wd, ID_MSK, Mask, 1, mask); - write_iddata(wd, &mask->id); + writestruct(wd, ID_MSK, Mask, 1, mask); + write_iddata(wd, &mask->id); - if (mask->adt) { - write_animdata(wd, mask->adt); - } + if (mask->adt) { + write_animdata(wd, mask->adt); + } - for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { - MaskSpline *spline; - MaskLayerShape *masklay_shape; + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + MaskLayerShape *masklay_shape; - writestruct(wd, DATA, MaskLayer, 1, masklay); + writestruct(wd, DATA, MaskLayer, 1, masklay); - for (spline = masklay->splines.first; spline; spline = spline->next) { - int i; + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; - void *points_deform = spline->points_deform; - spline->points_deform = NULL; + void *points_deform = spline->points_deform; + spline->points_deform = NULL; - writestruct(wd, DATA, MaskSpline, 1, spline); - writestruct(wd, DATA, MaskSplinePoint, spline->tot_point, spline->points); + writestruct(wd, DATA, MaskSpline, 1, spline); + writestruct(wd, DATA, MaskSplinePoint, spline->tot_point, spline->points); - spline->points_deform = points_deform; + spline->points_deform = points_deform; - for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; - if (point->tot_uw) { - writestruct(wd, DATA, MaskSplinePointUW, point->tot_uw, point->uw); - } + if (point->tot_uw) { + writestruct(wd, DATA, MaskSplinePointUW, point->tot_uw, point->uw); } } + } - for (masklay_shape = masklay->splines_shapes.first; - masklay_shape; - masklay_shape = masklay_shape->next) - { - writestruct(wd, DATA, MaskLayerShape, 1, masklay_shape); - writedata(wd, DATA, - masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, - masklay_shape->data); - } + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + writestruct(wd, DATA, MaskLayerShape, 1, masklay_shape); + writedata(wd, DATA, + masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, + masklay_shape->data); } } - - mask = mask->id.next; } - - mywrite_flush(wd); } static void write_linestyle_color_modifiers(WriteData *wd, ListBase *modifiers) @@ -3856,48 +3625,39 @@ static void write_linestyle_geometry_modifiers(WriteData *wd, ListBase *modifier } } -static void write_linestyles(WriteData *wd, ListBase *idbase) +static void write_linestyle(WriteData *wd, FreestyleLineStyle *linestyle) { - FreestyleLineStyle *linestyle; - int a; - - for (linestyle = idbase->first; linestyle; linestyle = linestyle->id.next) { - if (linestyle->id.us > 0 || wd->current) { - writestruct(wd, ID_LS, FreestyleLineStyle, 1, linestyle); - write_iddata(wd, &linestyle->id); + if (linestyle->id.us > 0 || wd->current) { + writestruct(wd, ID_LS, FreestyleLineStyle, 1, linestyle); + write_iddata(wd, &linestyle->id); - if (linestyle->adt) { - write_animdata(wd, linestyle->adt); - } + if (linestyle->adt) { + write_animdata(wd, linestyle->adt); + } - write_linestyle_color_modifiers(wd, &linestyle->color_modifiers); - write_linestyle_alpha_modifiers(wd, &linestyle->alpha_modifiers); - write_linestyle_thickness_modifiers(wd, &linestyle->thickness_modifiers); - write_linestyle_geometry_modifiers(wd, &linestyle->geometry_modifiers); - for (a = 0; a < MAX_MTEX; a++) { - if (linestyle->mtex[a]) { - writestruct(wd, DATA, MTex, 1, linestyle->mtex[a]); - } - } - if (linestyle->nodetree) { - writestruct(wd, DATA, bNodeTree, 1, linestyle->nodetree); - write_nodetree(wd, linestyle->nodetree); + write_linestyle_color_modifiers(wd, &linestyle->color_modifiers); + write_linestyle_alpha_modifiers(wd, &linestyle->alpha_modifiers); + write_linestyle_thickness_modifiers(wd, &linestyle->thickness_modifiers); + write_linestyle_geometry_modifiers(wd, &linestyle->geometry_modifiers); + for (int a = 0; a < MAX_MTEX; a++) { + if (linestyle->mtex[a]) { + writestruct(wd, DATA, MTex, 1, linestyle->mtex[a]); } } + if (linestyle->nodetree) { + writestruct(wd, DATA, bNodeTree, 1, linestyle->nodetree); + write_nodetree_nolib(wd, linestyle->nodetree); + } } } -static void write_cachefiles(WriteData *wd, ListBase *idbase) +static void write_cachefile(WriteData *wd, CacheFile *cache_file) { - CacheFile *cache_file; - - for (cache_file = idbase->first; cache_file; cache_file = cache_file->id.next) { - if (cache_file->id.us > 0 || wd->current) { - writestruct(wd, ID_CF, CacheFile, 1, cache_file); + if (cache_file->id.us > 0 || wd->current) { + writestruct(wd, ID_CF, CacheFile, 1, cache_file); - if (cache_file->adt) { - write_animdata(wd, cache_file->adt); - } + if (cache_file->adt) { + write_animdata(wd, cache_file->adt); } } } @@ -3911,7 +3671,6 @@ static void write_libraries(WriteData *wd, Main *main) bool found_one; for (; main; main = main->next) { - a = tot = set_listbasepointers(main, lbarray); /* test: is lib being used */ @@ -3920,16 +3679,13 @@ static void write_libraries(WriteData *wd, Main *main) } else { found_one = false; - while (tot--) { + while (!found_one && tot--) { for (id = lbarray[tot]->first; id; id = id->next) { if (id->us > 0 && (id->tag & LIB_TAG_EXTERN)) { found_one = true; break; } } - if (found_one) { - break; - } } } @@ -4068,38 +3824,134 @@ static bool write_file_handle( * avoid thumbnail detecting changes because of this. */ mywrite_flush(wd); - write_windowmanagers(wd, &mainvar->wm); - write_screens(wd, &mainvar->screen); - write_movieclips(wd, &mainvar->movieclip); - write_masks(wd, &mainvar->mask); - write_scenes(wd, &mainvar->scene); - write_curves(wd, &mainvar->curve); - write_mballs(wd, &mainvar->mball); - write_images(wd, &mainvar->image); - write_cameras(wd, &mainvar->camera); - write_lamps(wd, &mainvar->lamp); - write_lattices(wd, &mainvar->latt); - write_vfonts(wd, &mainvar->vfont); - write_keys(wd, &mainvar->key); - write_worlds(wd, &mainvar->world); - write_texts(wd, &mainvar->text); - write_speakers(wd, &mainvar->speaker); - write_sounds(wd, &mainvar->sound); - write_groups(wd, &mainvar->group); - write_armatures(wd, &mainvar->armature); - write_actions(wd, &mainvar->action); - write_objects(wd, &mainvar->object); - write_materials(wd, &mainvar->mat); - write_textures(wd, &mainvar->tex); - write_meshes(wd, &mainvar->mesh); - write_particlesettings(wd, &mainvar->particle); - write_nodetrees(wd, &mainvar->nodetree); - write_brushes(wd, &mainvar->brush); - write_palettes(wd, &mainvar->palettes); - write_paintcurves(wd, &mainvar->paintcurves); - write_gpencils(wd, &mainvar->gpencil); - write_linestyles(wd, &mainvar->linestyle); - write_cachefiles(wd, &mainvar->cachefiles); + ListBase *lbarray[MAX_LIBARRAY]; + int a = set_listbasepointers(mainvar, lbarray); + while (a--) { + ID *id = lbarray[a]->first; + + if (id && GS(id->name) == ID_LI) { + continue; /* Libraries are handled separately below. */ + } + + for (; id; id = id->next) { + /* We should never attempt to write non-regular IDs (i.e. all kind of temp/runtime ones). */ + BLI_assert((id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT | LIB_TAG_NOT_ALLOCATED)) == 0); + + switch ((ID_Type)GS(id->name)) { + case ID_WM: + write_windowmanager(wd, (wmWindowManager *)id); + break; + case ID_SCR: + write_screen(wd, (bScreen *)id); + break; + case ID_MC: + write_movieclip(wd, (MovieClip *)id); + break; + case ID_MSK: + write_mask(wd, (Mask *)id); + break; + case ID_SCE: + write_scene(wd, (Scene *)id); + break; + case ID_CU: + write_curve(wd, (Curve *)id); + break; + case ID_MB: + write_mball(wd, (MetaBall *)id); + break; + case ID_IM: + write_image(wd, (Image *)id); + break; + case ID_CA: + write_camera(wd, (Camera *)id); + break; + case ID_LA: + write_lamp(wd, (Lamp *)id); + break; + case ID_LT: + write_lattice(wd, (Lattice *)id); + break; + case ID_VF: + write_vfont(wd, (VFont *)id); + break; + case ID_KE: + write_key(wd, (Key *)id); + break; + case ID_WO: + write_world(wd, (World *)id); + break; + case ID_TXT: + write_text(wd, (Text *)id); + break; + case ID_SPK: + write_speaker(wd, (Speaker *)id); + break; + case ID_SO: + write_sound(wd, (bSound *)id); + break; + case ID_GR: + write_group(wd, (Group *)id); + break; + case ID_AR: + write_armature(wd, (bArmature *)id); + break; + case ID_AC: + write_action(wd, (bAction *)id); + break; + case ID_OB: + write_object(wd, (Object *)id); + break; + case ID_MA: + write_material(wd, (Material *)id); + break; + case ID_TE: + write_texture(wd, (Tex *)id); + break; + case ID_ME: + write_mesh(wd, (Mesh *)id); + break; + case ID_PA: + write_particlesettings(wd, (ParticleSettings *)id); + break; + case ID_NT: + write_nodetree(wd, (bNodeTree *)id); + break; + case ID_BR: + write_brush(wd, (Brush *)id); + break; + case ID_PAL: + write_palette(wd, (Palette *)id); + break; + case ID_PC: + write_paintcurve(wd, (PaintCurve *)id); + break; + case ID_GD: + write_gpencil(wd, (bGPdata *)id); + break; + case ID_LS: + write_linestyle(wd, (FreestyleLineStyle *)id); + break; + case ID_CF: + write_cachefile(wd, (CacheFile *)id); + break; + case ID_LI: + /* Do nothing, handled below - and should never be reached. */ + BLI_assert(0); + break; + case ID_IP: + /* Do nothing, deprecated. */ + break; + default: + /* Should never be reached. */ + BLI_assert(0); + break; + } + } + + mywrite_flush(wd); + } + + /* Special handling, operating over split Mains... */ write_libraries(wd, mainvar->next); /* So changes above don't cause a 'DNA1' to be detected as changed on undo. */ |