[Bf-blender-cvs] [9e3e92a908d] blender2.7: Revert "Cleanup: remove legacy mesh save support"
Brecht Van Lommel
noreply at git.blender.org
Fri Mar 22 18:20:19 CET 2019
Commit: 9e3e92a908dfaff6a3dbaba8ae31b1bef0d1d557
Author: Brecht Van Lommel
Date: Fri Mar 22 18:16:46 2019 +0100
Branches: blender2.7
https://developer.blender.org/rB9e3e92a908dfaff6a3dbaba8ae31b1bef0d1d557
Revert "Cleanup: remove legacy mesh save support"
Fixes T62793. Leave this in the blender2.7 branch for those that still rely
on it, but it will remain removed in master.
===================================================================
M source/blender/blenkernel/BKE_global.h
M source/blender/blenkernel/BKE_mesh.h
M source/blender/blenkernel/intern/mesh_evaluate.c
M source/blender/blenloader/intern/writefile.c
M source/blender/makesdna/DNA_mesh_types.h
M source/blender/windowmanager/intern/wm_files.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 5bff5321e1a..35e808128bf 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -182,12 +182,12 @@ enum {
/* On write, make backup `.blend1`, `.blend2` ... files, when the users preference is enabled */
#define G_FILE_HISTORY (1 << 25)
/* BMesh option to save as older mesh format */
-// #define G_FILE_MESH_COMPAT (1 << 26)
+#define G_FILE_MESH_COMPAT (1 << 26)
/* On write, restore paths after editing them (G_FILE_RELATIVE_REMAP) */
#define G_FILE_SAVE_COPY (1 << 27)
#define G_FILE_GLSL_NO_ENV_LIGHTING (1 << 28)
-#define G_FILE_FLAGS_RUNTIME (G_FILE_NO_UI | G_FILE_RELATIVE_REMAP | G_FILE_SAVE_COPY)
+#define G_FILE_FLAGS_RUNTIME (G_FILE_NO_UI | G_FILE_RELATIVE_REMAP | G_FILE_MESH_COMPAT | G_FILE_SAVE_COPY)
/* ENDIAN_ORDER: indicates what endianness the platform where the file was
* written had. */
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index bd14fd79ff8..62625a96596 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -339,6 +339,9 @@ void BKE_mesh_recalc_looptri(
const struct MVert *mvert,
int totloop, int totpoly,
struct MLoopTri *mlooptri);
+int BKE_mesh_mpoly_to_mface(
+ struct CustomData *fdata, struct CustomData *ldata,
+ struct CustomData *pdata, int totface, int totloop, int totpoly);
void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
void BKE_mesh_do_versions_convert_mfaces_to_mpolys(struct Mesh *mesh);
void BKE_mesh_convert_mfaces_to_mpolys_ex(
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 54025690df5..707c462ea48 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -3165,9 +3165,130 @@ void BKE_mesh_recalc_looptri(
#undef ML_TO_MLT
}
-static void bm_corners_to_loops_ex(
- ID *id, CustomData *fdata, CustomData *ldata, CustomData *pdata,
- MFace *mface, int totloop, int findex, int loopstart, int numTex, int numCol)
+/* -------------------------------------------------------------------- */
+
+
+#ifdef USE_BMESH_SAVE_AS_COMPAT
+
+/**
+ * This function recreates a tessellation.
+ * returns number of tessellation faces.
+ *
+ * for forwards compat only quad->tri polys to mface, skip ngons.
+ */
+int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata,
+ struct CustomData *pdata, int totface, int UNUSED(totloop), int totpoly)
+{
+ MLoop *mloop;
+
+ unsigned int lindex[4];
+ int i;
+ int k;
+
+ MPoly *mp, *mpoly;
+ MFace *mface, *mf;
+
+ const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
+ const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
+ const bool hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL);
+ const bool hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
+ const bool hasLNor = CustomData_has_layer(ldata, CD_NORMAL);
+
+ /* over-alloc, ngons will be skipped */
+ mface = MEM_malloc_arrayN((size_t)totpoly, sizeof(*mface), __func__);
+
+ mpoly = CustomData_get_layer(pdata, CD_MPOLY);
+ mloop = CustomData_get_layer(ldata, CD_MLOOP);
+
+ mp = mpoly;
+ k = 0;
+ for (i = 0; i < totpoly; i++, mp++) {
+ if (ELEM(mp->totloop, 3, 4)) {
+ const unsigned int mp_loopstart = (unsigned int)mp->loopstart;
+ mf = &mface[k];
+
+ mf->mat_nr = mp->mat_nr;
+ mf->flag = mp->flag;
+
+ mf->v1 = mp_loopstart + 0;
+ mf->v2 = mp_loopstart + 1;
+ mf->v3 = mp_loopstart + 2;
+ mf->v4 = (mp->totloop == 4) ? (mp_loopstart + 3) : 0;
+
+ /* abuse edcode for temp storage and clear next loop */
+ mf->edcode = (char)mp->totloop; /* only ever 3 or 4 */
+
+ k++;
+ }
+ }
+
+ CustomData_free(fdata, totface);
+
+ totface = k;
+
+ CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mface, totface);
+
+ CustomData_from_bmeshpoly(fdata, pdata, ldata, totface);
+
+ mp = mpoly;
+ k = 0;
+ for (i = 0; i < totpoly; i++, mp++) {
+ if (ELEM(mp->totloop, 3, 4)) {
+ mf = &mface[k];
+
+ if (mf->edcode == 3) {
+ /* sort loop indices to ensure winding is correct */
+ /* NO SORT - looks like we can skip this */
+
+ lindex[0] = mf->v1;
+ lindex[1] = mf->v2;
+ lindex[2] = mf->v3;
+ lindex[3] = 0; /* unused */
+
+ /* transform loop indices to vert indices */
+ mf->v1 = mloop[mf->v1].v;
+ mf->v2 = mloop[mf->v2].v;
+ mf->v3 = mloop[mf->v3].v;
+
+ BKE_mesh_loops_to_mface_corners(fdata, ldata, pdata,
+ lindex, k, i, 3,
+ numTex, numCol, hasPCol, hasOrigSpace, hasLNor);
+ test_index_face(mf, fdata, k, 3);
+ }
+ else {
+ /* sort loop indices to ensure winding is correct */
+ /* NO SORT - looks like we can skip this */
+
+ lindex[0] = mf->v1;
+ lindex[1] = mf->v2;
+ lindex[2] = mf->v3;
+ lindex[3] = mf->v4;
+
+ /* transform loop indices to vert indices */
+ mf->v1 = mloop[mf->v1].v;
+ mf->v2 = mloop[mf->v2].v;
+ mf->v3 = mloop[mf->v3].v;
+ mf->v4 = mloop[mf->v4].v;
+
+ BKE_mesh_loops_to_mface_corners(fdata, ldata, pdata,
+ lindex, k, i, 4,
+ numTex, numCol, hasPCol, hasOrigSpace, hasLNor);
+ test_index_face(mf, fdata, k, 4);
+ }
+
+ mf->edcode = 0;
+
+ k++;
+ }
+ }
+
+ return k;
+}
+#endif /* USE_BMESH_SAVE_AS_COMPAT */
+
+
+static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata, CustomData *pdata,
+ MFace *mface, int totloop, int findex, int loopstart, int numTex, int numCol)
{
MTFace *texface;
MTexPoly *texpoly;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 0d064d557dc..1ee39a146f7 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -332,6 +332,10 @@ typedef struct {
* Will be NULL for UNDO.
*/
WriteWrap *ww;
+
+#ifdef USE_BMESH_SAVE_AS_COMPAT
+ bool use_mesh_compat; /* option to save with older mesh format */
+#endif
} WriteData;
static WriteData *writedata_new(WriteWrap *ww)
@@ -2181,6 +2185,12 @@ static void write_customdata(
static void write_mesh(WriteData *wd, Mesh *mesh)
{
+#ifdef USE_BMESH_SAVE_AS_COMPAT
+ const bool save_for_old_blender = wd->use_mesh_compat; /* option to save with older mesh format */
+#else
+ const bool save_for_old_blender = false;
+#endif
+
CustomDataLayer *vlayers = NULL, vlayers_buff[CD_TEMP_CHUNK_SIZE];
CustomDataLayer *elayers = NULL, elayers_buff[CD_TEMP_CHUNK_SIZE];
CustomDataLayer *flayers = NULL, flayers_buff[CD_TEMP_CHUNK_SIZE];
@@ -2189,17 +2199,19 @@ static void write_mesh(WriteData *wd, Mesh *mesh)
if (mesh->id.us > 0 || wd->use_memfile) {
/* write LibData */
- {
+ if (!save_for_old_blender) {
/* 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 */
/**
* Those calls:
@@ -2210,7 +2222,11 @@ static void write_mesh(WriteData *wd, Mesh *mesh)
*/
CustomData_file_write_prepare(&mesh->vdata, &vlayers, vlayers_buff, ARRAY_SIZE(vlayers_buff));
CustomData_file_write_prepare(&mesh->edata, &elayers, elayers_buff, ARRAY_SIZE(elayers_buff));
+#ifndef USE_BMESH_SAVE_WITHOUT_MFACE /* Do not copy org fdata in this case!!! */
+ CustomData_file_write_prepare(&mesh->fdata, &flayers, flayers_buff, ARRAY_SIZE(flayers_buff));
+#else
flayers = flayers_buff;
+#endif
CustomData_file_write_prepare(&mesh->ldata, &llayers, llayers_buff, ARRAY_SIZE(llayers_buff));
CustomData_file_write_prepare(&mesh->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
@@ -2235,6 +2251,73 @@ static void write_mesh(WriteData *wd, Mesh *mesh)
/* restore pointer */
mesh = old_mesh;
}
+ else {
+
+#ifdef USE_BMESH_SAVE_AS_COMPAT
+ /* 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;
+
+ mesh->mpoly = NULL;
+ mesh->mface = NULL;
+ mesh->totface = 0;
+ mesh->totpoly = 0;
+ mesh->totloop = 0;
+ CustomData_reset(&mesh->fdata);
+ CustomData_reset(&mesh->pdata);
+ CustomData_reset(&mesh->ldata);
+ mesh->edit_btmesh = NULL;
+
+ /* now fill in polys to mfaces */
+ /* XXX This breaks writing design, by using temp allocated memory, which will likely generate
+ * duplicates in stored 'old' addresses.
+ * This is very bad, but do not see easy way to avoid this, aside from generating those data
+ * outside of save process itself.
+ * Maybe we can live with this, though?
+ */
+ mesh->totface = BKE_mesh_mpoly_to_mface(
+ &mesh->fdata, &old_mesh->ldata, &old_mesh->pdata,
+ mesh->totface, old_mesh->totloop, old_mesh->totpoly);
+
+ BKE_mesh_update_customdata_pointers(mesh, false);
+
+ CustomData_file_write_prepare(&mesh->vdata, &vlayers, vlayers_buff, ARRAY_SIZE(vlayers_buff));
+ CustomData_file_write_prepare(&mesh->edata, &elayers, elayers_buff, ARRAY_SIZE(elayers_buff));
+ CustomData_file_write_prepare(&mesh->fdata, &flayers, flayers_buff, ARRAY_SIZE(flayers_buff));
+#if 0
+ CustomData_file_write_prepare(&mesh->ldata, &llayers, llayers_buff, ARRAY_SIZE(llayers_buff));
+ CustomData_file_write_prepare(&mesh->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
+#endif
+
+ writestruct_at_address(wd, ID_ME, Mesh, 1, old_mesh, mesh);
+ write_iddata(wd, &mesh->id);
+
+ /* direct data */
+ if (mesh->adt) {
+ write_animdata(wd, mesh->adt);
+ }
+
+ writedata(wd, DATA, sizeof(void *) * mesh->totco
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list