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:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-04-29 12:00:07 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-04-29 12:00:07 +0300
commitadf4d0e3e307bef203104d49a92d7b0833be2856 (patch)
tree396221f8576eae889689a2581d45212612bd712e /source/blender/blenloader/intern
parentb4e5161b02a6522c6fd0a37369f37f5c9e47a73f (diff)
parent029bd44bbd0fc6c1c59c6cb37f9e70c4dd23f91d (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.c8
-rw-r--r--source/blender/blenloader/intern/writefile.c73
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 = &copy_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 */