[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 = &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 */
 
 			/**
 			 * 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 = &copy_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