diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2015-06-29 18:10:42 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2015-06-29 18:10:42 +0300 |
commit | 58d6cbba6da31db8dc8a2b42d528b9a353081904 (patch) | |
tree | 04b57a2f809c6f08d84a082edf061f3ece631860 /source/blender/blenloader/intern/writefile.c | |
parent | 94549adec4b6857fb6ec4cf77606da51ff7c26b7 (diff) | |
parent | 295d0c52a26730edc6d4ed1276e4051cce006be5 (diff) |
Merge branch 'master' into temp-ghash-setopstemp-ghash-setops
Diffstat (limited to 'source/blender/blenloader/intern/writefile.c')
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 146 |
1 files changed, 107 insertions, 39 deletions
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 1156d3f30f0..f5954ab75a7 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -333,7 +333,7 @@ static void writedata_do_write(WriteData *wd, const void *mem, int memlen) /* memory based save */ if (wd->current) { - add_memfilechunk(NULL, wd->current, mem, memlen); + memfile_chunk_add(NULL, wd->current, mem, memlen); } else { if (wd->ww->write(wd->ww, mem, memlen) != memlen) { @@ -407,7 +407,7 @@ static void mywrite(WriteData *wd, const void *adr, int len) /** * BeGiN initializer for mywrite - * \param file File descriptor + * \param ww: File write wrapper. * \param compare Previous memory file (can be NULL). * \param current The current memory file (can be NULL). * \warning Talks to other functions with global parameters @@ -421,7 +421,7 @@ static WriteData *bgnwrite(WriteWrap *ww, MemFile *compare, MemFile *current) wd->compare= compare; wd->current= current; /* this inits comparing */ - add_memfilechunk(compare, NULL, NULL, 0); + memfile_chunk_add(compare, NULL, NULL, 0); return wd; } @@ -597,7 +597,7 @@ static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers) /* Modifiers */ for (fcm= fmodifiers->first; fcm; fcm= fcm->next) { - FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm); + const FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm); /* Write the specific data */ if (fmi && fcm->data) { @@ -1096,7 +1096,7 @@ static void write_pointcaches(WriteData *wd, ListBase *ptcaches) for (i=0; i<BPHYS_TOT_DATA; i++) { if (pm->data[i] && pm->data_types & (1<<i)) { - if (ptcache_data_struct[i][0]=='\0') + if (ptcache_data_struct[i][0] == '\0') writedata(wd, DATA, MEM_allocN_len(pm->data[i]), pm->data[i]); else writestruct(wd, DATA, ptcache_data_struct[i], pm->totpoint, pm->data[i]); @@ -1104,7 +1104,7 @@ static void write_pointcaches(WriteData *wd, ListBase *ptcaches) } for (; extra; extra=extra->next) { - if (ptcache_extra_struct[extra->type][0]=='\0') + if (ptcache_extra_struct[extra->type][0] == '\0') continue; writestruct(wd, DATA, "PTCacheExtra", 1, extra); writestruct(wd, DATA, ptcache_extra_struct[extra->type], extra->totdata, extra->data); @@ -1404,7 +1404,7 @@ static void write_constraints(WriteData *wd, ListBase *conlist) bConstraint *con; for (con=conlist->first; con; con=con->next) { - bConstraintTypeInfo *cti= BKE_constraint_typeinfo_get(con); + const bConstraintTypeInfo *cti= BKE_constraint_typeinfo_get(con); /* Write the specific data */ if (cti && con->data) { @@ -1500,7 +1500,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) if (modbase == NULL) return; for (md=modbase->first; md; md= md->next) { - ModifierTypeInfo *mti = modifierType_getInfo(md->type); + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (mti == NULL) return; writestruct(wd, DATA, mti->structName, 1, md); @@ -1620,6 +1620,13 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) writedata(wd, DATA, sizeof(float)*lmd->total_verts * 3, lmd->vertexco); } + else if (md->type == eModifierType_CorrectiveSmooth) { + CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md; + + if (csmd->bind_coords) { + writedata(wd, DATA, sizeof(float[3]) * csmd->bind_coords_num, csmd->bind_coords); + } + } } } @@ -1896,26 +1903,35 @@ static void write_grid_paint_mask(WriteData *wd, int count, GridPaintMask *grid_ static void write_customdata(WriteData *wd, ID *id, int count, CustomData *data, int partial_type, int partial_count) { - CustomData data_tmp; int i; - /* This copy will automatically ignore/remove layers set as NO_COPY (and TEMPORARY). */ - CustomData_copy(data, &data_tmp, CD_MASK_EVERYTHING, CD_REFERENCE, count); + int nofree_buff[128]; + int *nofree; /* write external customdata (not for undo) */ - if (data_tmp.external && !wd->current) - CustomData_external_write(&data_tmp, id, CD_MASK_MESH, count, 0); + if (data->external && !wd->current) + CustomData_external_write(data, id, CD_MASK_MESH, count, 0); + + if (data->totlayer > ARRAY_SIZE(nofree_buff)) { + nofree = MEM_mallocN(sizeof(*nofree) * (size_t)data->totlayer, __func__); + } + else { + nofree = nofree_buff; + } - for (i = 0; i < data_tmp.totlayer; i++) - data_tmp.layers[i].flag &= ~CD_FLAG_NOFREE; + for (i = 0; i < data->totlayer; i++) { + nofree[i] = (data->layers[i].flag & CD_FLAG_NOFREE); + data->layers[i].flag &= ~CD_FLAG_NOFREE; + } - writestruct_at_address(wd, DATA, "CustomDataLayer", data_tmp.maxlayer, data->layers, data_tmp.layers); + writestruct(wd, DATA, "CustomDataLayer", data->maxlayer, data->layers); - for (i = 0; i < data_tmp.totlayer; i++) - data_tmp.layers[i].flag |= CD_FLAG_NOFREE; + for (i = 0; i < data->totlayer; i++) { + data->layers[i].flag |= nofree[i]; + } - for (i = 0; i < data_tmp.totlayer; i++) { - CustomDataLayer *layer= &data_tmp.layers[i]; + for (i = 0; i < data->totlayer; i++) { + CustomDataLayer *layer= &data->layers[i]; const char *structname; int structnum, datasize; @@ -1951,10 +1967,12 @@ static void write_customdata(WriteData *wd, ID *id, int count, CustomData *data, } } - if (data_tmp.external) - writestruct_at_address(wd, DATA, "CustomDataExternal", 1, data->external, data_tmp.external); + if (data->external) + writestruct(wd, DATA, "CustomDataExternal", 1, data->external); - CustomData_free(&data_tmp, count); + if (nofree != nofree_buff) { + MEM_freeN(nofree); + } } static void write_meshes(WriteData *wd, ListBase *idbase) @@ -1971,23 +1989,32 @@ static void write_meshes(WriteData *wd, ListBase *idbase) if (mesh->id.us>0 || wd->current) { /* write LibData */ if (!save_for_old_blender) { - -#ifdef USE_BMESH_SAVE_WITHOUT_MFACE /* 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)); +#endif /* USE_BMESH_SAVE_WITHOUT_MFACE */ + + /* Bummer! We need to do the copy *before* writing mesh's struct itself, + * because we eliminate NO_COPY & TEMPORARY layers here, which means + * **number of layers (data.totlayer) may be smaller!** + * If we do not do that, we can get crash by buffer-overflow on reading, see T44461. */ + CustomData_copy(&old_mesh->vdata, &mesh->vdata, CD_MASK_EVERYTHING, CD_REFERENCE, mesh->totvert); + CustomData_copy(&old_mesh->edata, &mesh->edata, CD_MASK_EVERYTHING, CD_REFERENCE, mesh->totedge); +#ifndef USE_BMESH_SAVE_WITHOUT_MFACE /* Do not copy org fdata in this case!!! */ + CustomData_copy(&old_mesh->fdata, &mesh->fdata, CD_MASK_EVERYTHING, CD_REFERENCE, mesh->totface); +#endif + CustomData_copy(&old_mesh->ldata, &mesh->ldata, CD_MASK_EVERYTHING, CD_REFERENCE, mesh->totloop); + CustomData_copy(&old_mesh->pdata, &mesh->pdata, CD_MASK_EVERYTHING, CD_REFERENCE, mesh->totpoly); writestruct_at_address(wd, ID_ME, "Mesh", 1, old_mesh, mesh); -#else - writestruct(wd, ID_ME, "Mesh", 1, mesh); -#endif /* USE_BMESH_SAVE_WITHOUT_MFACE */ /* direct data */ if (mesh->id.properties) IDP_WriteProperty(mesh->id.properties, wd); @@ -2003,11 +2030,16 @@ static void write_meshes(WriteData *wd, ListBase *idbase) write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, -1, 0); write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, -1, 0); -#ifdef USE_BMESH_SAVE_WITHOUT_MFACE + CustomData_free(&mesh->vdata, mesh->totvert); + CustomData_free(&mesh->edata, mesh->totedge); +#ifndef USE_BMESH_SAVE_WITHOUT_MFACE + CustomData_free(&mesh->fdata, mesh->totface); +#endif + CustomData_free(&mesh->ldata, mesh->totloop); + CustomData_free(&mesh->pdata, mesh->totpoly); + /* restore pointer */ mesh = old_mesh; -#endif /* USE_BMESH_SAVE_WITHOUT_MFACE */ - } else { @@ -2034,6 +2066,10 @@ static void write_meshes(WriteData *wd, ListBase *idbase) BKE_mesh_update_customdata_pointers(mesh, false); + /* See comment above. Note that loop/poly data are ignored here, and face ones are already handled. */ + CustomData_copy(&old_mesh->vdata, &mesh->vdata, CD_MASK_EVERYTHING, CD_REFERENCE, mesh->totvert); + CustomData_copy(&old_mesh->edata, &mesh->edata, CD_MASK_EVERYTHING, CD_REFERENCE, mesh->totedge); + writestruct_at_address(wd, ID_ME, "Mesh", 1, old_mesh, mesh); /* direct data */ @@ -2052,6 +2088,8 @@ static void write_meshes(WriteData *wd, ListBase *idbase) write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, -1, 0); #endif + CustomData_free(&mesh->vdata, mesh->totvert); + CustomData_free(&mesh->edata, mesh->totedge); CustomData_free(&mesh->fdata, mesh->totface); /* restore pointer */ @@ -2117,22 +2155,39 @@ static void write_images(WriteData *wd, ListBase *idbase) { 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); if (ima->id.properties) IDP_WriteProperty(ima->id.properties, wd); - if (ima->packedfile) { - pf = ima->packedfile; - writestruct(wd, DATA, "PackedFile", 1, pf); - writedata(wd, DATA, pf->size, pf->data); + 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); + } } write_previews(wd, ima->preview); + + for (iv = ima->views.first; iv; iv = iv->next) + writestruct(wd, DATA, "ImageView", 1, iv); + writestruct(wd, DATA, "Stereo3dFormat", 1, ima->stereo3d_format); + + ima->packedfile = NULL; } ima= ima->id.next; } @@ -2287,7 +2342,7 @@ static void write_sequence_modifiers(WriteData *wd, ListBase *modbase) SequenceModifierData *smd; for (smd = modbase->first; smd; smd = smd->next) { - SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type); + const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type); if (smti) { writestruct(wd, DATA, smti->struct_name, 1, smd); @@ -2333,6 +2388,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase) TimeMarker *marker; TransformOrientation *ts; SceneRenderLayer *srl; + SceneRenderView *srv; ToolSettings *tos; FreestyleModuleConfig *fmc; FreestyleLineSet *fls; @@ -2414,7 +2470,9 @@ static void write_scenes(WriteData *wd, ListBase *scebase) break; } } - + + writestruct(wd, DATA, "Stereo3dFormat", 1, seq->stereo3d_format); + strip= seq->strip; writestruct(wd, DATA, "Strip", 1, strip); if (seq->flag & SEQ_USE_CROP && strip->crop) { @@ -2434,6 +2492,10 @@ static void write_scenes(WriteData *wd, ListBase *scebase) strip->done = true; } + if (seq->prop) { + IDP_WriteProperty(seq->prop, wd); + } + write_sequence_modifiers(wd, &seq->modifiers); } SEQ_END @@ -2475,6 +2537,10 @@ static void write_scenes(WriteData *wd, ListBase *scebase) writestruct(wd, DATA, "FreestyleLineSet", 1, fls); } } + + /* 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); @@ -2537,8 +2603,10 @@ static void write_windowmanagers(WriteData *wd, ListBase *lb) for (wm= lb->first; wm; wm= wm->id.next) { writestruct(wd, ID_WM, "wmWindowManager", 1, wm); - for (win= wm->windows.first; win; win= win->next) + for (win= wm->windows.first; win; win= win->next) { writestruct(wd, DATA, "wmWindow", 1, win); + writestruct(wd, DATA, "Stereo3dFormat", 1, win->stereo3d_format); + } } } |