Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2016-06-14 16:47:54 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2016-06-14 16:47:54 +0300
commitc6d3f76e69fbd213e6076071da67dd700e522c4f (patch)
tree1c00a19260914c5e8d20f64b5cd16ee4e2ccec9a /source/blender/blenloader/intern/writefile.c
parent69ae86193c31160cd501c18cfac661ea4afb23c3 (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.c371
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");