diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2016-06-14 16:47:54 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2016-06-14 16:47:54 +0300 |
commit | c6d3f76e69fbd213e6076071da67dd700e522c4f (patch) | |
tree | 1c00a19260914c5e8d20f64b5cd16ee4e2ccec9a /source/blender/blenloader/intern/writefile.c | |
parent | 69ae86193c31160cd501c18cfac661ea4afb23c3 (diff) |
Fix save/load issues with new virtual-lib assets.
Diffstat (limited to 'source/blender/blenloader/intern/writefile.c')
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 371 |
1 files changed, 203 insertions, 168 deletions
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 97f6d3c2675..6d0b6ccdc7e 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -294,7 +294,7 @@ typedef struct { unsigned char *buf; MemFile *compare, *current; - + int tot, count, error; /* Wrap writing, so we can use zlib or @@ -358,7 +358,7 @@ static void writedata_free(WriteData *wd) * \param len Length of new chunk of data * \warning Talks to other functions with global parameters */ - + #define MYWRITE_FLUSH NULL static void mywrite(WriteData *wd, const void *adr, int len) @@ -375,7 +375,7 @@ static void mywrite(WriteData *wd, const void *adr, int len) } wd->tot+= len; - + /* if we have a single big chunk, write existing data in * buffer and write out big chunk in smaller pieces */ if (len>MYWRITE_MAX_CHUNK) { @@ -422,7 +422,7 @@ static WriteData *bgnwrite(WriteWrap *ww, MemFile *compare, MemFile *current) wd->current= current; /* this inits comparing */ memfile_chunk_add(compare, NULL, NULL, 0); - + return wd; } @@ -440,7 +440,7 @@ static int endwrite(WriteData *wd) writedata_do_write(wd, wd->buf, wd->count); wd->count= 0; } - + err= wd->error; writedata_free(wd); @@ -506,7 +506,7 @@ static void writedata(WriteData *wd, int filecode, int len, const void *adr) /* static void writelist(WriteData *wd, int filecode, const char *structname, ListBase *lb) { Link *link = lb->first; - + while (link) { writestruct(wd, filecode, structname, 1, link); link = link->next; @@ -592,7 +592,14 @@ static void write_iddata(void *wd, ID *id) { /* ID_WM's id->properties are considered runtime only, and never written in .blend file. */ if (id->properties && !ELEM(GS(id->name), ID_WM)) { - IDP_WriteProperty(id->properties, wd); + /* We want to write IDProps from 'virtual' libraries too, but not from 'real' linked datablocks... */ + if (!id->uuid || (id->lib && (id->lib->flag & LIBRARY_FLAG_VIRTUAL))) { + IDP_WriteProperty(id->properties, wd); + } + } + if (id->uuid) { + BLI_assert(id->lib && id->lib->asset_repository); + writestruct(wd, DATA, "AssetUUID", 1, id->uuid); } } @@ -626,25 +633,25 @@ static void write_previews(WriteData *wd, PreviewImage *prv) static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers) { FModifier *fcm; - + /* Write all modifiers first (for faster reloading) */ writelist(wd, DATA, "FModifier", fmodifiers); - + /* Modifiers */ for (fcm= fmodifiers->first; fcm; fcm= fcm->next) { const FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm); - + /* Write the specific data */ if (fmi && fcm->data) { /* firstly, just write the plain fmi->data struct */ writestruct(wd, DATA, fmi->structName, 1, fcm->data); - + /* do any modifier specific stuff */ switch (fcm->type) { case FMODIFIER_TYPE_GENERATOR: { FMod_Generator *data= (FMod_Generator *)fcm->data; - + /* write coefficients array */ if (data->coefficients) writedata(wd, DATA, sizeof(float)*(data->arraysize), data->coefficients); @@ -654,7 +661,7 @@ static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers) case FMODIFIER_TYPE_ENVELOPE: { FMod_Envelope *data= (FMod_Envelope *)fcm->data; - + /* write envelope data */ if (data->data) writestruct(wd, DATA, "FCM_EnvelopeData", data->totvert, data->data); @@ -664,7 +671,7 @@ static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers) case FMODIFIER_TYPE_PYTHON: { FMod_Python *data = (FMod_Python *)fcm->data; - + /* Write ID Properties -- and copy this comment EXACTLY for easy finding * of library blocks that implement this.*/ IDP_WriteProperty(data->prop, wd); @@ -679,7 +686,7 @@ static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers) static void write_fcurves(WriteData *wd, ListBase *fcurves) { FCurve *fcu; - + writelist(wd, DATA, "FCurve", fcurves); for (fcu=fcurves->first; fcu; fcu=fcu->next) { /* curve data */ @@ -687,20 +694,20 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves) writestruct(wd, DATA, "BezTriple", fcu->totvert, fcu->bezt); if (fcu->fpt) writestruct(wd, DATA, "FPoint", fcu->totvert, fcu->fpt); - + if (fcu->rna_path) writedata(wd, DATA, strlen(fcu->rna_path)+1, fcu->rna_path); - + /* driver data */ if (fcu->driver) { ChannelDriver *driver= fcu->driver; DriverVar *dvar; - + writestruct(wd, DATA, "ChannelDriver", 1, driver); - + /* variables */ writelist(wd, DATA, "DriverVar", &driver->variables); - for (dvar= driver->variables.first; dvar; dvar= dvar->next) { + for (dvar= driver->variables.first; dvar; dvar= dvar->next) { DRIVER_TARGETS_USED_LOOPER(dvar) { if (dtar->rna_path) @@ -709,7 +716,7 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves) DRIVER_TARGETS_LOOPER_END } } - + /* write F-Modifiers */ write_fmodifiers(wd, &fcu->modifiers); } @@ -720,24 +727,24 @@ static void write_actions(WriteData *wd, ListBase *idbase) 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); write_fcurves(wd, &act->curves); - + for (grp=act->groups.first; grp; grp=grp->next) { writestruct(wd, DATA, "bActionGroup", 1, grp); } - + for (marker=act->markers.first; marker; marker=marker->next) { writestruct(wd, DATA, "TimeMarker", 1, marker); } } } - + /* flush helps the compression for undo-save */ mywrite(wd, MYWRITE_FLUSH, 0); } @@ -746,16 +753,16 @@ static void write_keyingsets(WriteData *wd, ListBase *list) { KeyingSet *ks; KS_Path *ksp; - + for (ks= list->first; ks; ks= ks->next) { /* KeyingSet */ writestruct(wd, DATA, "KeyingSet", 1, ks); - + /* Paths */ for (ksp= ks->paths.first; ksp; ksp= ksp->next) { /* Path */ writestruct(wd, DATA, "KS_Path", 1, ksp); - + if (ksp->rna_path) writedata(wd, DATA, strlen(ksp->rna_path)+1, ksp->rna_path); } @@ -765,13 +772,13 @@ static void write_keyingsets(WriteData *wd, ListBase *list) static void write_nlastrips(WriteData *wd, ListBase *strips) { NlaStrip *strip; - + writelist(wd, DATA, "NlaStrip", strips); for (strip= strips->first; strip; strip= strip->next) { /* write the strip's F-Curves and modifiers */ write_fcurves(wd, &strip->fcurves); write_fmodifiers(wd, &strip->modifiers); - + /* write the strip's children */ write_nlastrips(wd, &strip->strips); } @@ -780,12 +787,12 @@ static void write_nlastrips(WriteData *wd, ListBase *strips) static void write_nladata(WriteData *wd, ListBase *nlabase) { NlaTrack *nlt; - + /* write all the tracks */ for (nlt= nlabase->first; nlt; nlt= nlt->next) { /* write the track first */ writestruct(wd, DATA, "NlaTrack", 1, nlt); - + /* write the track's strips */ write_nlastrips(wd, &nlt->strips); } @@ -794,13 +801,13 @@ static void write_nladata(WriteData *wd, ListBase *nlabase) static void write_animdata(WriteData *wd, AnimData *adt) { AnimOverride *aor; - + /* firstly, just write the AnimData block */ writestruct(wd, DATA, "AnimData", 1, adt); - + /* write drivers */ write_fcurves(wd, &adt->drivers); - + /* write overrides */ // FIXME: are these needed? for (aor= adt->overrides.first; aor; aor= aor->next) { @@ -808,9 +815,9 @@ static void write_animdata(WriteData *wd, AnimData *adt) writestruct(wd, DATA, "AnimOverride", 1, aor); writedata(wd, DATA, strlen(aor->rna_path)+1, aor->rna_path); } - + // TODO write the remaps (if they are needed) - + /* write NLA data */ write_nladata(wd, &adt->nla_tracks); } @@ -835,14 +842,14 @@ static void write_node_socket(WriteData *wd, bNodeTree *UNUSED(ntree), bNode *no #ifdef USE_NODE_COMPAT_CUSTOMNODES /* forward compatibility code, so older blenders still open */ sock->stack_type = 1; - + if (node->type == NODE_GROUP) { bNodeTree *ngroup = (bNodeTree *)node->id; if (ngroup) { /* for node groups: look up the deprecated groupsock pointer */ sock->groupsock = ntreeFindSocketInterface(ngroup, sock->in_out, sock->identifier); BLI_assert(sock->groupsock != NULL); - + /* node group sockets now use the generic identifier string to verify group nodes, * old blender uses the own_index. */ @@ -856,7 +863,7 @@ static void write_node_socket(WriteData *wd, bNodeTree *UNUSED(ntree), bNode *no if (sock->prop) IDP_WriteProperty(sock->prop, wd); - + if (sock->default_value) writedata(wd, DATA, MEM_allocN_len(sock->default_value), sock->default_value); } @@ -865,7 +872,7 @@ static void write_node_socket_interface(WriteData *wd, bNodeTree *UNUSED(ntree), #ifdef USE_NODE_COMPAT_CUSTOMNODES /* forward compatibility code, so older blenders still open */ sock->stack_type = 1; - + /* Reconstruct the deprecated default_value structs in socket interface DNA. */ if (sock->default_value == NULL && sock->typeinfo) { node_socket_init_default_value(sock); @@ -877,7 +884,7 @@ static void write_node_socket_interface(WriteData *wd, bNodeTree *UNUSED(ntree), if (sock->prop) IDP_WriteProperty(sock->prop, wd); - + if (sock->default_value) writedata(wd, DATA, MEM_allocN_len(sock->default_value), sock->default_value); } @@ -887,11 +894,11 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) bNode *node; bNodeSocket *sock; bNodeLink *link; - + /* for link_list() speed, we write per list */ - + if (ntree->adt) write_animdata(wd, ntree->adt); - + for (node = ntree->nodes.first; node; node = node->next) { writestruct(wd, DATA, "bNode", 1, node); @@ -902,7 +909,7 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) write_node_socket(wd, ntree, node, sock); for (sock= node->outputs.first; sock; sock= sock->next) write_node_socket(wd, ntree, node, sock); - + for (link = node->internal_links.first; link; link = link->next) writestruct(wd, DATA, "bNodeLink", 1, link); if (node->storage) { @@ -925,7 +932,7 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) else writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage); } - + if (node->type==CMP_NODE_OUTPUT_FILE) { /* inputs have own storage data */ for (sock = node->inputs.first; sock; sock = sock->next) @@ -937,10 +944,10 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) writestruct(wd, DATA, "NodeImageLayer", 1, sock->storage); } } - + for (link= ntree->links.first; link; link= link->next) writestruct(wd, DATA, "bNodeLink", 1, link); - + for (sock = ntree->inputs.first; sock; sock = sock->next) write_node_socket_interface(wd, ntree, sock); for (sock = ntree->outputs.first; sock; sock = sock->next) @@ -1000,7 +1007,7 @@ static void write_renderinfo(WriteData *wd, Main *mainvar) /* XXX in future, handle multiple windows with multiple screens? */ current_screen_compat(mainvar, &curscreen, false); if (curscreen) curscene = curscreen->scene; - + for (sce= mainvar->scene.first; sce; sce= sce->id.next) { if (sce->id.lib == NULL && (sce == curscene || (sce->r.scemode & R_BG_RENDER))) { data.sfra = sce->r.sfra; @@ -1030,7 +1037,7 @@ static void write_userdef(WriteData *wd) bAddon *bext; bPathCompare *path_cmp; uiStyle *style; - + writestruct(wd, USER, "UserDef", 1, &U); for (btheme= U.themes.first; btheme; btheme=btheme->next) @@ -1061,7 +1068,7 @@ static void write_userdef(WriteData *wd) for (path_cmp = U.autoexec_paths.first; path_cmp; path_cmp = path_cmp->next) { writestruct(wd, DATA, "bPathCompare", 1, path_cmp); } - + for (style= U.uistyles.first; style; style= style->next) { writestruct(wd, DATA, "uiStyle", 1, style); } @@ -1131,7 +1138,7 @@ static void write_pointcaches(WriteData *wd, ListBase *ptcaches) PTCacheExtra *extra = pm->extradata.first; writestruct(wd, DATA, "PTCacheMem", 1, pm); - + for (i=0; i<BPHYS_TOT_DATA; i++) { if (pm->data[i] && pm->data_types & (1<<i)) { if (ptcache_data_struct[i][0] == '\0') @@ -1174,7 +1181,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase) write_curvemapping(wd, part->clumpcurve); if (part->roughcurve) write_curvemapping(wd, part->roughcurve); - + dw = part->dupliweights.first; for (; dw; dw=dw->next) { /* update indices */ @@ -1198,7 +1205,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase) write_boid_state(wd, state); } if (part->fluid && part->phystype == PART_PHYS_FLUID) { - writestruct(wd, DATA, "SPHFluidSettings", 1, part->fluid); + writestruct(wd, DATA, "SPHFluidSettings", 1, part->fluid); } for (a=0; a<MAX_MTEX; a++) { @@ -1427,10 +1434,10 @@ static void write_motionpath(WriteData *wd, bMotionPath *mpath) /* sanity checks */ if (mpath == NULL) return; - + /* firstly, just write the motionpath struct */ writestruct(wd, DATA, "bMotionPath", 1, mpath); - + /* now write the array of data */ writestruct(wd, DATA, "bMotionPathVert", mpath->length, mpath->points); } @@ -1441,33 +1448,33 @@ static void write_constraints(WriteData *wd, ListBase *conlist) for (con=conlist->first; con; con=con->next) { const bConstraintTypeInfo *cti= BKE_constraint_typeinfo_get(con); - + /* Write the specific data */ if (cti && con->data) { /* firstly, just write the plain con->data struct */ writestruct(wd, DATA, cti->structName, 1, con->data); - + /* do any constraint specific stuff */ switch (con->type) { case CONSTRAINT_TYPE_PYTHON: { bPythonConstraint *data = (bPythonConstraint *)con->data; bConstraintTarget *ct; - + /* write targets */ for (ct= data->targets.first; ct; ct= ct->next) writestruct(wd, DATA, "bConstraintTarget", 1, ct); - + /* Write ID Properties -- and copy this comment EXACTLY for easy finding * of library blocks that implement this.*/ IDP_WriteProperty(data->prop, wd); break; } - case CONSTRAINT_TYPE_SPLINEIK: + case CONSTRAINT_TYPE_SPLINEIK: { bSplineIKConstraint *data = (bSplineIKConstraint *)con->data; - + /* write points array */ writedata(wd, DATA, sizeof(float)*(data->numpoints), data->points); @@ -1475,7 +1482,7 @@ static void write_constraints(WriteData *wd, ListBase *conlist) } } } - + /* Write the constraint */ writestruct(wd, DATA, "bConstraint", 1, con); } @@ -1496,20 +1503,20 @@ static void write_pose(WriteData *wd, bPose *pose) * of library blocks that implement this.*/ if (chan->prop) IDP_WriteProperty(chan->prop, wd); - + write_constraints(wd, &chan->constraints); - + write_motionpath(wd, chan->mpath); - + /* prevent crashes with autosave, when a bone duplicated in editmode has not yet been assigned to its posechannel */ - if (chan->bone) + if (chan->bone) chan->selectflag= chan->bone->flag & BONE_SELECTED; /* gets restored on read, for library armatures */ - + writestruct(wd, DATA, "bPoseChannel", 1, chan); } - + /* Write groups */ - for (grp=pose->agroups.first; grp; grp=grp->next) + for (grp=pose->agroups.first; grp; grp=grp->next) writestruct(wd, DATA, "bActionGroup", 1, grp); /* write IK param */ @@ -1540,12 +1547,12 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) for (md=modbase->first; md; md= md->next) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (mti == NULL) return; - + writestruct(wd, DATA, mti->structName, 1, md); - + if (md->type==eModifierType_Hook) { HookModifierData *hmd = (HookModifierData*) md; - + if (hmd->curfalloff) { write_curvemapping(wd, hmd->curfalloff); } @@ -1554,7 +1561,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) } else if (md->type==eModifierType_Cloth) { ClothModifierData *clmd = (ClothModifierData*) md; - + writestruct(wd, DATA, "ClothSimSettings", 1, clmd->sim_parms); writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms); writestruct(wd, DATA, "EffectorWeights", 1, clmd->sim_parms->effector_weights); @@ -1562,7 +1569,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) } else if (md->type==eModifierType_Smoke) { SmokeModifierData *smd = (SmokeModifierData*) md; - + if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { if (smd->domain) { write_pointcaches(wd, &(smd->domain->ptcaches[0])); @@ -1574,14 +1581,14 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) write_pointcaches(wd, &(smd->domain->ptcaches[1])); } - + writestruct(wd, DATA, "SmokeDomainSettings", 1, smd->domain); if (smd->domain) { /* cleanup the fake pointcache */ BKE_ptcache_free_list(&smd->domain->ptcaches[1]); smd->domain->point_cache[1] = NULL; - + writestruct(wd, DATA, "EffectorWeights", 1, smd->domain->effector_weights); } } @@ -1592,16 +1599,16 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) } else if (md->type==eModifierType_Fluidsim) { FluidsimModifierData *fluidmd = (FluidsimModifierData*) md; - + writestruct(wd, DATA, "FluidsimSettings", 1, fluidmd->fss); } else if (md->type==eModifierType_DynamicPaint) { DynamicPaintModifierData *pmd = (DynamicPaintModifierData*) md; - + if (pmd->canvas) { DynamicPaintSurface *surface; writestruct(wd, DATA, "DynamicPaintCanvasSettings", 1, pmd->canvas); - + /* write surfaces */ for (surface=pmd->canvas->surfaces.first; surface; surface=surface->next) writestruct(wd, DATA, "DynamicPaintSurface", 1, surface); @@ -1619,10 +1626,10 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) } } else if (md->type==eModifierType_Collision) { - + #if 0 CollisionModifierData *collmd = (CollisionModifierData*) md; - // TODO: CollisionModifier should use pointcache + // TODO: CollisionModifier should use pointcache // + have proper reset events before enabling this writestruct(wd, DATA, "MVert", collmd->numverts, collmd->x); writestruct(wd, DATA, "MVert", collmd->numverts, collmd->xnew); @@ -1671,7 +1678,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) static void write_objects(WriteData *wd, ListBase *idbase) { Object *ob; - + ob= idbase->first; while (ob) { if (ob->id.us>0 || wd->current) { @@ -1680,7 +1687,7 @@ static void write_objects(WriteData *wd, ListBase *idbase) write_iddata(wd, &ob->id); if (ob->adt) write_animdata(wd, ob->adt); - + /* direct data */ writedata(wd, DATA, sizeof(void *)*ob->totcol, ob->mat); writedata(wd, DATA, sizeof(char)*ob->totcol, ob->matbits); @@ -1701,7 +1708,7 @@ static void write_objects(WriteData *wd, ListBase *idbase) write_defgroups(wd, &ob->defbase); write_constraints(wd, &ob->constraints); write_motionpath(wd, ob->mpath); - + writestruct(wd, DATA, "PartDeflect", 1, ob->pd); writestruct(wd, DATA, "SoftBody", 1, ob->soft); if (ob->soft) { @@ -1709,7 +1716,7 @@ static void write_objects(WriteData *wd, ListBase *idbase) writestruct(wd, DATA, "EffectorWeights", 1, ob->soft->effector_weights); } writestruct(wd, DATA, "BulletSoftBody", 1, ob->bsoft); - + 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); @@ -1778,7 +1785,7 @@ static void write_keys(WriteData *wd, ListBase *idbase) write_iddata(wd, &key->id); if (key->adt) write_animdata(wd, key->adt); - + /* direct data */ kb= key->block.first; while (kb) { @@ -1853,7 +1860,7 @@ static void write_curves(WriteData *wd, ListBase *idbase) /* 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); @@ -1890,10 +1897,10 @@ static void write_dverts(WriteData *wd, int count, MDeformVert *dvlist) { if (dvlist) { int i; - + /* Write the dvert list */ writestruct(wd, DATA, "MDeformVert", count, dvlist); - + /* Write deformation data for each dvert */ for (i=0; i<count; i++) { if (dvlist[i].dw) @@ -1906,7 +1913,7 @@ static void write_mdisps(WriteData *wd, int count, MDisps *mdlist, int external) { if (mdlist) { int i; - + writestruct(wd, DATA, "MDisps", count, mdlist); for (i = 0; i < count; ++i) { MDisps *md = &mdlist[i]; @@ -1914,7 +1921,7 @@ static void write_mdisps(WriteData *wd, int count, MDisps *mdlist, int external) if (!external) writedata(wd, DATA, sizeof(float) * 3 * md->totdisp, md->disps); } - + if (md->hidden) writedata(wd, DATA, BLI_BITMAP_SIZE(md->totdisp), md->hidden); } @@ -1925,7 +1932,7 @@ static void write_grid_paint_mask(WriteData *wd, int count, GridPaintMask *grid_ { if (grid_paint_mask) { int i; - + writestruct(wd, DATA, "GridPaintMask", count, grid_paint_mask); for (i = 0; i < count; ++i) { GridPaintMask *gpm = &grid_paint_mask[i]; @@ -1950,7 +1957,7 @@ static void write_customdata( CustomData_external_write(data, id, CD_MASK_MESH, count, 0); writestruct_at_address(wd, DATA, "CustomDataLayer", data->totlayer, data->layers, layers); - + for (i = 0; i < data->totlayer; i++) { CustomDataLayer *layer = &layers[i]; const char *structname; @@ -2150,7 +2157,7 @@ static void write_meshes(WriteData *wd, ListBase *idbase) static void write_lattices(WriteData *wd, ListBase *idbase) { Lattice *lt; - + lt= idbase->first; while (lt) { if (lt->id.us>0 || wd->current) { @@ -2160,12 +2167,12 @@ static void write_lattices(WriteData *wd, ListBase *idbase) /* write animdata */ if (lt->adt) write_animdata(wd, lt->adt); - + /* direct data */ writestruct(wd, DATA, "BPoint", lt->pntsu*lt->pntsv*lt->pntsw, lt->def); - + write_dverts(wd, lt->pntsu*lt->pntsv*lt->pntsw, lt->dvert); - + } lt= lt->id.next; } @@ -2238,13 +2245,13 @@ static void write_textures(WriteData *wd, ListBase *idbase) } 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); - + /* nodetree is integral part of texture, no libdata */ if (tex->nodetree) { writestruct(wd, DATA, "bNodeTree", 1, tex->nodetree); write_nodetree(wd, tex->nodetree); } - + write_previews(wd, tex->preview); } tex= tex->id.next; @@ -2271,10 +2278,10 @@ static void write_materials(WriteData *wd, ListBase *idbase) for (a=0; a<MAX_MTEX; a++) { if (ma->mtex[a]) writestruct(wd, DATA, "MTex", 1, ma->mtex[a]); } - + if (ma->ramp_col) writestruct(wd, DATA, "ColorBand", 1, ma->ramp_col); if (ma->ramp_spec) writestruct(wd, DATA, "ColorBand", 1, ma->ramp_spec); - + /* nodetree is integral part of material, no libdata */ if (ma->nodetree) { writestruct(wd, DATA, "bNodeTree", 1, ma->nodetree); @@ -2300,7 +2307,7 @@ static void write_worlds(WriteData *wd, ListBase *idbase) write_iddata(wd, &wrld->id); if (wrld->adt) write_animdata(wd, wrld->adt); - + for (a=0; a<MAX_MTEX; a++) { if (wrld->mtex[a]) writestruct(wd, DATA, "MTex", 1, wrld->mtex[a]); } @@ -2310,7 +2317,7 @@ static void write_worlds(WriteData *wd, ListBase *idbase) writestruct(wd, DATA, "bNodeTree", 1, wrld->nodetree); write_nodetree(wd, wrld->nodetree); } - + write_previews(wd, wrld->preview); } wrld= wrld->id.next; @@ -2330,15 +2337,15 @@ static void write_lamps(WriteData *wd, ListBase *idbase) 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->curfalloff) write_curvemapping(wd, la->curfalloff); - + /* nodetree is integral part of lamps, no libdata */ if (la->nodetree) { writestruct(wd, DATA, "bNodeTree", 1, la->nodetree); @@ -2346,7 +2353,7 @@ static void write_lamps(WriteData *wd, ListBase *idbase) } write_previews(wd, la->preview); - + } la= la->id.next; } @@ -2407,7 +2414,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase) ToolSettings *tos; FreestyleModuleConfig *fmc; FreestyleLineSet *fls; - + sce= scebase->first; while (sce) { /* write LibData */ @@ -2416,14 +2423,14 @@ static void write_scenes(WriteData *wd, ListBase *scebase) 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) { @@ -2448,21 +2455,21 @@ static void write_scenes(WriteData *wd, ListBase *scebase) ed= sce->ed; if (ed) { writestruct(wd, DATA, "Editing", 1, ed); - + /* reset write flags too */ - + SEQ_BEGIN (ed, seq) { if (seq->strip) seq->strip->done = false; writestruct(wd, DATA, "Sequence", 1, seq); } SEQ_END - + 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: @@ -2506,7 +2513,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase) writestruct(wd, DATA, "StripElem", MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem), strip->stripdata); else if (seq->type==SEQ_TYPE_MOVIE || seq->type==SEQ_TYPE_SOUND_RAM || seq->type == SEQ_TYPE_SOUND_HD) writestruct(wd, DATA, "StripElem", 1, strip->stripdata); - + strip->done = true; } @@ -2517,13 +2524,13 @@ static void write_scenes(WriteData *wd, ListBase *scebase) write_sequence_modifiers(wd, &seq->modifiers); } 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 (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); @@ -2541,11 +2548,11 @@ static void write_scenes(WriteData *wd, ListBase *scebase) /* writing dynamic list of TimeMarkers to the blend file */ for (marker= sce->markers.first; marker; marker= marker->next) writestruct(wd, DATA, "TimeMarker", 1, marker); - + /* writing dynamic list of TransformOrientations to the blend file */ for (ts = sce->transform_spaces.first; ts; ts = ts->next) writestruct(wd, DATA, "TransformOrientation", 1, ts); - + for (srl = sce->r.layers.first; srl; srl = srl->next) { writestruct(wd, DATA, "SceneRenderLayer", 1, srl); for (fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) { @@ -2559,21 +2566,21 @@ static void write_scenes(WriteData *wd, ListBase *scebase) /* writing MultiView to the blend file */ for (srv = sce->r.views.first; srv; srv = srv->next) writestruct(wd, DATA, "SceneRenderView", 1, srv); - + if (sce->nodetree) { writestruct(wd, DATA, "bNodeTree", 1, sce->nodetree); write_nodetree(wd, sce->nodetree); } write_view_settings(wd, &sce->view_settings); - + /* 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)); } - + write_previews(wd, sce->preview); write_curvemapping_curves(wd, &sce->r.mblur_shutter_curve); @@ -2589,7 +2596,7 @@ static void write_gpencils(WriteData *wd, ListBase *lb) bGPDlayer *gpl; bGPDframe *gpf; bGPDstroke *gps; - + for (gpd= lb->first; gpd; gpd= gpd->id.next) { if (gpd->id.us>0 || wd->current) { /* write gpd data block to file */ @@ -2597,15 +2604,15 @@ static void write_gpencils(WriteData *wd, ListBase *lb) 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) { @@ -2621,7 +2628,7 @@ static void write_windowmanagers(WriteData *wd, ListBase *lb) { 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); @@ -2634,16 +2641,16 @@ static void write_windowmanagers(WriteData *wd, ListBase *lb) } static void write_region(WriteData *wd, ARegion *ar, int spacetype) -{ +{ writestruct(wd, DATA, "ARegion", 1, ar); - + if (ar->regiondata) { switch (spacetype) { case SPACE_VIEW3D: if (ar->regiontype==RGN_TYPE_WINDOW) { RegionView3D *rv3d= ar->regiondata; writestruct(wd, DATA, "RegionView3D", 1, rv3d); - + if (rv3d->localvd) writestruct(wd, DATA, "RegionView3D", 1, rv3d->localvd); if (rv3d->clipbb) @@ -2671,7 +2678,7 @@ static void write_uilist(WriteData *wd, uiList *ui_list) static void write_soops(WriteData *wd, SpaceOops *so, LinkNode **tmp_mem_list) { BLI_mempool *ts = so->treestore; - + if (ts) { int elems = BLI_mempool_count(ts); /* linearize mempool to array */ @@ -2683,7 +2690,7 @@ static void write_soops(WriteData *wd, SpaceOops *so, LinkNode **tmp_mem_list) ts_flat->usedelem = elems; ts_flat->totelem = elems; ts_flat->data = data; - + /* temporarily replace mempool-treestore by flat-treestore */ so->treestore = (BLI_mempool *)ts_flat; writestruct(wd, DATA, "SpaceOops", 1, so); @@ -2721,7 +2728,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase) sc= scrbase->first; while (sc) { - + /* write LibData */ /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */ writestruct(wd, ID_SCRN, "Screen", 1, sc); @@ -2730,10 +2737,10 @@ static void write_screens(WriteData *wd, ListBase *scrbase) /* direct data */ for (sv= sc->vertbase.first; sv; sv= sv->next) writestruct(wd, DATA, "ScrVert", 1, sv); - + for (se= sc->edgebase.first; se; se= se->next) writestruct(wd, DATA, "ScrEdge", 1, se); - + for (sa= sc->areabase.first; sa; sa= sa->next) { SpaceLink *sl; Panel *pa; @@ -2741,15 +2748,15 @@ static void write_screens(WriteData *wd, ListBase *scrbase) uiPreview *ui_preview; PanelCategoryStack *pc_act; ARegion *ar; - + writestruct(wd, DATA, "ScrArea", 1, sa); - + 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 (pc_act = ar->panels_category_active.first; pc_act; pc_act = pc_act->next) writestruct(wd, DATA, "PanelCategoryStack", 1, pc_act); @@ -2759,12 +2766,12 @@ static void write_screens(WriteData *wd, ListBase *scrbase) for (ui_preview = ar->ui_previews.first; ui_preview; ui_preview = ui_preview->next) writestruct(wd, DATA, "uiPreview", 1, ui_preview); } - + 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; @@ -2781,13 +2788,13 @@ static void write_screens(WriteData *wd, ListBase *scrbase) 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; } @@ -2810,7 +2817,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase) } else if (sl->spacetype==SPACE_IMAGE) { SpaceImage *sima= (SpaceImage *)sl; - + writestruct(wd, DATA, "SpaceImage", 1, sl); if (sima->cumap) write_curvemapping(wd, sima->cumap); @@ -2828,7 +2835,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase) } 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); } @@ -2839,7 +2846,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase) 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); } @@ -2876,7 +2883,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase) } BLI_linklist_freeN(tmp_mem_list); - + /* flush helps the compression for undo-save */ mywrite(wd, MYWRITE_FLUSH, 0); } @@ -2887,7 +2894,7 @@ static void write_bone(WriteData *wd, Bone *bone) // PATCH for upward compatibility after 2.37+ armature recode bone->size[0] = bone->size[1] = bone->size[2] = 1.0f; - + // Write this bone writestruct(wd, DATA, "Bone", 1, bone); @@ -2895,7 +2902,7 @@ static void write_bone(WriteData *wd, Bone *bone) * of library blocks that implement this.*/ if (bone->prop) IDP_WriteProperty(bone->prop, wd); - + // Write Children cbone= bone->childbase.first; while (cbone) { @@ -3037,7 +3044,7 @@ static void write_groups(WriteData *wd, ListBase *idbase) static void write_nodetrees(WriteData *wd, ListBase *idbase) { 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); @@ -3055,11 +3062,11 @@ static void customnodes_add_deprecated_data(Main *mainvar) { FOREACH_NODETREE(mainvar, ntree, id) { bNodeLink *link, *last_link = ntree->links.last; - + /* only do this for node groups */ if (id != &ntree->id) continue; - + /* Forward compatibility for group nodes: add links to node tree interface sockets. * These links are invalid by new rules (missing node pointer)! * They will be removed again in customnodes_free_deprecated_data, @@ -3070,7 +3077,7 @@ static void customnodes_add_deprecated_data(Main *mainvar) for (link = ntree->links.first; link; link = link->next) { bNode *fromnode = link->fromnode, *tonode = link->tonode; bNodeSocket *fromsock = link->fromsock, *tosock = link->tosock; - + /* check both sides of the link, to handle direct input-to-output links */ if (fromnode->type == NODE_GROUP_INPUT) { fromnode = NULL; @@ -3081,7 +3088,7 @@ static void customnodes_add_deprecated_data(Main *mainvar) tonode = NULL; tosock = ntreeFindSocketInterface(ntree, SOCK_OUT, tosock->identifier); } - + if (!fromnode || !tonode) { /* Note: not using nodeAddLink here, it asserts existing node pointers */ bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "group node link"); @@ -3093,7 +3100,7 @@ static void customnodes_add_deprecated_data(Main *mainvar) tlink->flag |= NODE_LINK_VALID; BLI_addtail(&ntree->links, tlink); } - + /* don't check newly created compatibility links */ if (link == last_link) break; @@ -3106,7 +3113,7 @@ static void customnodes_free_deprecated_data(Main *mainvar) { FOREACH_NODETREE(mainvar, ntree, id) { bNodeLink *link, *next_link; - + for (link = ntree->links.first; link; link = next_link) { next_link = link->next; if (link->fromnode == NULL || link->tonode == NULL) @@ -3120,7 +3127,7 @@ static void customnodes_free_deprecated_data(Main *mainvar) static void write_brushes(WriteData *wd, ListBase *idbase) { 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); @@ -3582,7 +3589,9 @@ static void write_libraries(WriteData *wd, Main *main) int a, tot; bool found_one; - for (; main; main= main->next) { + for (; main; main = main->next) { + BLI_assert(BLI_listbase_is_empty(&main->library)); + a = tot = set_listbasepointers(main, lbarray); /* test: is lib being used */ @@ -3629,6 +3638,34 @@ static void write_libraries(WriteData *wd, Main *main) write_vfonts (wd, &main->vfont); write_texts (wd, &main->text); write_sounds (wd, &main->sound); + + BLI_assert(BLI_listbase_is_empty(&main->wm)); + BLI_assert(BLI_listbase_is_empty(&main->screen)); + BLI_assert(BLI_listbase_is_empty(&main->movieclip)); + BLI_assert(BLI_listbase_is_empty(&main->mask)); + BLI_assert(BLI_listbase_is_empty(&main->scene)); + BLI_assert(BLI_listbase_is_empty(&main->curve)); + BLI_assert(BLI_listbase_is_empty(&main->mball)); + BLI_assert(BLI_listbase_is_empty(&main->camera)); + BLI_assert(BLI_listbase_is_empty(&main->lamp)); + BLI_assert(BLI_listbase_is_empty(&main->latt)); + BLI_assert(BLI_listbase_is_empty(&main->key)); + BLI_assert(BLI_listbase_is_empty(&main->world)); + BLI_assert(BLI_listbase_is_empty(&main->speaker)); + BLI_assert(BLI_listbase_is_empty(&main->group)); + BLI_assert(BLI_listbase_is_empty(&main->armature)); + BLI_assert(BLI_listbase_is_empty(&main->action)); + BLI_assert(BLI_listbase_is_empty(&main->object)); + BLI_assert(BLI_listbase_is_empty(&main->mat)); + BLI_assert(BLI_listbase_is_empty(&main->tex)); + BLI_assert(BLI_listbase_is_empty(&main->mesh)); + BLI_assert(BLI_listbase_is_empty(&main->particle)); + BLI_assert(BLI_listbase_is_empty(&main->nodetree)); + BLI_assert(BLI_listbase_is_empty(&main->brush)); + BLI_assert(BLI_listbase_is_empty(&main->palettes)); + BLI_assert(BLI_listbase_is_empty(&main->paintcurves)); + BLI_assert(BLI_listbase_is_empty(&main->gpencil)); + BLI_assert(BLI_listbase_is_empty(&main->linestyle)); } else { while (a--) { @@ -3640,9 +3677,7 @@ static void write_libraries(WriteData *wd, Main *main) BLI_assert(0); } writestruct(wd, ID_ID, "ID", 1, id); - if (id->uuid) { - writestruct(wd, DATA, "AssetUUID", 1, id->uuid); - } + write_iddata(wd, id); } } } @@ -3660,7 +3695,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) FileGlobal fg; bScreen *screen; char subvstr[8]; - + /* prevent mem checkers from complaining */ memset(fg.pad, 0, sizeof(fg.pad)); memset(fg.filename, 0, sizeof(fg.filename)); @@ -3679,7 +3714,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename)); sprintf(subvstr, "%4d", BLENDER_SUBVERSION); memcpy(fg.subvstr, subvstr, 4); - + fg.subversion= BLENDER_SUBVERSION; fg.minversion= BLENDER_MINVERSION; fg.minsubversion= BLENDER_MINSUBVERSION; @@ -3784,7 +3819,7 @@ static int write_file_handle( if (write_user_block) { write_userdef(wd); } - + /* dna as last, because (to be implemented) test for which structs are written */ writedata(wd, DNA1, wd->sdna->datalen, wd->sdna->data); @@ -3815,7 +3850,7 @@ static bool do_history(const char *name, ReportList *reports) { char tempname1[FILE_MAX], tempname2[FILE_MAX]; int hisnr= U.versions; - + if (U.versions==0) return 0; if (strlen(name)<2) { BKE_report(reports, RPT_ERROR, "Unable to make version backup: filename too short"); |