diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-04-29 12:00:07 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-04-29 12:00:07 +0300 |
commit | adf4d0e3e307bef203104d49a92d7b0833be2856 (patch) | |
tree | 396221f8576eae889689a2581d45212612bd712e /source/blender/blenloader/intern | |
parent | b4e5161b02a6522c6fd0a37369f37f5c9e47a73f (diff) | |
parent | 029bd44bbd0fc6c1c59c6cb37f9e70c4dd23f91d (diff) |
Merge branch 'master' into alembic
Conflicts:
intern/cycles/blender/blender_sync.h
Diffstat (limited to 'source/blender/blenloader/intern')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 8 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 73 |
2 files changed, 57 insertions, 24 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 22f24ecf1ed..62ac46166d1 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3600,7 +3600,7 @@ static void direct_link_curve(FileData *fd, Curve *cu) nu->bp = newdataadr(fd, nu->bp); nu->knotsu = newdataadr(fd, nu->knotsu); nu->knotsv = newdataadr(fd, nu->knotsv); - if (cu->vfont == NULL) nu->charidx= nu->mat_nr; + if (cu->vfont == NULL) nu->charidx = 0; if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) { switch_endian_knots(nu); @@ -5890,6 +5890,12 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) win->lastcursor = 0; win->modalcursor = 0; win->stereo3d_format = newdataadr(fd, win->stereo3d_format); + + /* multiview always fallback to anaglyph at file opening + * otherwise quadbuffer saved files can break Blender */ + if (win->stereo3d_format) { + win->stereo3d_format->display_mode = S3D_DISPLAY_ANAGLYPH; + } } BLI_listbase_clear(&wm->timers); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 65c39c95a7c..6210eee919a 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1905,26 +1905,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); - for (i = 0; i < data_tmp.totlayer; i++) - data_tmp.layers[i].flag &= ~CD_FLAG_NOFREE; + 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->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; @@ -1960,10 +1969,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) @@ -1980,23 +1991,30 @@ 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); + CustomData_copy(&old_mesh->fdata, &mesh->fdata, CD_MASK_EVERYTHING, CD_REFERENCE, mesh->totface); + 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); @@ -2012,11 +2030,14 @@ 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); + CustomData_free(&mesh->fdata, mesh->totface); + CustomData_free(&mesh->ldata, mesh->totloop); + CustomData_free(&mesh->pdata, mesh->totpoly); + /* restore pointer */ mesh = old_mesh; -#endif /* USE_BMESH_SAVE_WITHOUT_MFACE */ - } else { @@ -2043,6 +2064,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 */ @@ -2061,6 +2086,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 */ |