[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60744] branches/vgroup_modifiers/source/ blender: First step to support split normals in tessfaces:

Bastien Montagne montagne29 at wanadoo.fr
Mon Oct 14 10:20:12 CEST 2013


Revision: 60744
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60744
Author:   mont29
Date:     2013-10-14 08:20:12 +0000 (Mon, 14 Oct 2013)
Log Message:
-----------
First step to support split normals in tessfaces:
* Add a new CD layer (CD_TESSLOOPNORMAL), four vec3f per tessface.
* Add needed code in tesselation (esp. BKE_mesh_loops_to_mface_corners) to copy loop normals into CD_TESSLOOPNORMAL.

Also, separated more the with/without loopnors handling in modifiers evaluation, as we also need polynors to compute loopnors, no need to compute them twice, so store poly CD_NORMAL in this case for now. Note we may be able to avoid this ultimately (by only storing TESSLOOPNORMAL for finaldm), but would make such optimization in the end.

Also, current code segfaults easily in bmesh (at least one issue with mempool), have to investigate more CD layers handling here.

Modified Paths:
--------------
    branches/vgroup_modifiers/source/blender/blenkernel/BKE_mesh.h
    branches/vgroup_modifiers/source/blender/blenkernel/intern/DerivedMesh.c
    branches/vgroup_modifiers/source/blender/blenkernel/intern/customdata.c
    branches/vgroup_modifiers/source/blender/blenkernel/intern/mesh_evaluate.c
    branches/vgroup_modifiers/source/blender/makesdna/DNA_customdata_types.h

Modified: branches/vgroup_modifiers/source/blender/blenkernel/BKE_mesh.h
===================================================================
--- branches/vgroup_modifiers/source/blender/blenkernel/BKE_mesh.h	2013-10-14 08:03:55 UTC (rev 60743)
+++ branches/vgroup_modifiers/source/blender/blenkernel/BKE_mesh.h	2013-10-14 08:20:12 UTC (rev 60744)
@@ -294,7 +294,7 @@
         struct CustomData *pdata, int lindex[4], int findex,
         const int polyindex, const int mf_len,
         const int numTex, const int numCol,
-        const bool hasPCol, const bool hasOrigSpace);
+        const bool hasPCol, const bool hasOrigSpace, const bool hasLNor);
 int BKE_mesh_recalc_tessellation(
         struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata,
         struct MVert *mvert,

Modified: branches/vgroup_modifiers/source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- branches/vgroup_modifiers/source/blender/blenkernel/intern/DerivedMesh.c	2013-10-14 08:03:55 UTC (rev 60743)
+++ branches/vgroup_modifiers/source/blender/blenkernel/intern/DerivedMesh.c	2013-10-14 08:20:12 UTC (rev 60744)
@@ -403,7 +403,6 @@
 
 	float (*lnors)[3];
 	float (*pnors)[3];
-	bool free_pnors = false;
 
 	const int numVerts = dm->getNumVerts(dm);
 	const int numEdges = dm->getNumEdges(dm);
@@ -418,24 +417,25 @@
 		lnors = CustomData_add_layer(ldata, CD_NORMAL, CD_CALLOC, NULL, numLoops);
 	}
 
+	/* Vertex normals. */
 	DM_ensure_normals(dm);
 	/* Looks like poly normals are actually not computed/stored in dm, so pdata is of no use for us... */
+	/* XXX This is very sub-optimal, poly normals are computed here and then again in dm_ensure_display_normals...
+	 *     Simplest solution would probably to store them in a temp CD layer?
+	 *     Or maybe find a way to mix all compute in one, but I find things already rather complex. :/
+	 * For now, store poly normals...
+	 */
 	pdata = dm->getPolyDataLayout(dm);
 	if (CustomData_has_layer(pdata, CD_NORMAL)) {
 		pnors = CustomData_get_layer(pdata, CD_NORMAL);
 	}
 	else {
-		pnors = MEM_mallocN(sizeof(float[3]) * numPolys, __func__);
+		pnors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, numPolys);
 		BKE_mesh_calc_normals_poly(mverts, numVerts, mloops, mpolys, numLoops, numPolys, pnors, false);
-		free_pnors = true;
 	}
 
 	BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges, mloops, lnors, numLoops, mpolys, pnors, numPolys,
 	                            split_angle);
-
-	if (free_pnors) {
-		MEM_freeN(pnors);
-	}
 }
 
 /* note: until all modifiers can take MPoly's as input,
@@ -479,8 +479,9 @@
 
 	const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
 	const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
-	const int hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL);
-	const int hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
+	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);
 
 	int *polyindex = CustomData_get_layer(fdata, CD_ORIGINDEX);
 
@@ -523,7 +524,7 @@
 		BKE_mesh_loops_to_mface_corners(fdata, ldata, pdata,
 		                                ml_idx, mf_idx, polyindex[mf_idx],
 		                                mf_len,
-		                                numTex, numCol, hasPCol, hasOrigSpace);
+		                                numTex, numCol, hasPCol, hasOrigSpace, hasLNor);
 	}
 
 	if (G.debug & G_DEBUG)
@@ -1893,11 +1894,20 @@
 	}
 
 	if (ob->flag & OB_USE_LOOPNORMALS) {
-		/* Compute loop normals */
+		/* Compute loop normals (note: will compute poly and vert normals as well, if needed!) */
 		DM_calc_loop_normals(finaldm, ob->split_angle);
+
+		if (finaldm->getNumTessFaces(finaldm) == 0) {
+			finaldm->recalcTessellation(finaldm);
+		}
+		/* Even if tessellation is not needed, we have for sure modified loop normals layer! */
+		else {
+			/* A tessellation already exists, it should always have a CD_ORIGINDEX. */
+			BLI_assert(CustomData_has_layer(&finaldm->faceData, CD_ORIGINDEX));
+			DM_update_tessface_data(finaldm);
+		}
 	}
-
-	{
+	else {
 		/* calculating normals can re-calculate tessfaces in some cases */
 #if 0
 		int num_tessface = finaldm->getNumTessFaces(finaldm);
@@ -2269,8 +2279,10 @@
 	}
 	/* --- */
 
-	/* same as mesh_calc_modifiers */
-	dm_ensure_display_normals(*final_r);
+	/* same as mesh_calc_modifiers (if we use loop normals, vertex and poly ones have already been set). */
+	if (!(ob->flag & OB_USE_LOOPNORMALS)) {
+		dm_ensure_display_normals(*final_r);
+	}
 
 	/* add an orco layer if needed */
 	if (dataMask & CD_MASK_ORCO)

Modified: branches/vgroup_modifiers/source/blender/blenkernel/intern/customdata.c
===================================================================
--- branches/vgroup_modifiers/source/blender/blenkernel/intern/customdata.c	2013-10-14 08:03:55 UTC (rev 60743)
+++ branches/vgroup_modifiers/source/blender/blenkernel/intern/customdata.c	2013-10-14 08:20:12 UTC (rev 60744)
@@ -1171,7 +1171,9 @@
 	/* 38: CD_FREESTYLE_FACE */
 	{sizeof(FreestyleFace), "FreestyleFace", 1, NULL, NULL, NULL, NULL, NULL, NULL},
 	/* 39: CD_LOOPTANGENT */
-	{sizeof(float) * 4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+	{sizeof(float[4]), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+	/* 40: CD_TESSLOOPNORMAL */
+	{sizeof(float[4][3]), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
 };
 
 /* note, numbers are from trunk and need updating for bmesh */
@@ -2296,6 +2298,9 @@
 		else if (ldata->layers[i].type == CD_ORIGSPACE_MLOOP) {
 			CustomData_add_layer_named(fdata, CD_ORIGSPACE, CD_CALLOC, NULL, total, ldata->layers[i].name);
 		}
+		else if (ldata->layers[i].type == CD_NORMAL) {
+			CustomData_add_layer_named(fdata, CD_TESSLOOPNORMAL, CD_CALLOC, NULL, total, ldata->layers[i].name);
+		}
 	}
 
 	CustomData_bmesh_update_active_layers(fdata, pdata, ldata);

Modified: branches/vgroup_modifiers/source/blender/blenkernel/intern/mesh_evaluate.c
===================================================================
--- branches/vgroup_modifiers/source/blender/blenkernel/intern/mesh_evaluate.c	2013-10-14 08:03:55 UTC (rev 60743)
+++ branches/vgroup_modifiers/source/blender/blenkernel/intern/mesh_evaluate.c	2013-10-14 08:20:12 UTC (rev 60744)
@@ -1316,7 +1316,8 @@
         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 hasOrigSpace, /* CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP) */
+        const bool hasLNor /* CustomData_has_layer(ldata, CD_NORMAL) */
 )
 {
 	MTFace *texface;
@@ -1365,6 +1366,14 @@
 			copy_v2_v2(of->uv[j], lof->uv);
 		}
 	}
+
+	if (hasLNor) {
+		float (*tlnors)[3] = CustomData_get(fdata, findex, CD_TESSLOOPNORMAL);
+
+		for (j = 0; j < mf_len; j++) {
+			copy_v3_v3(tlnors[j], CustomData_get(ldata, lindex[j], CD_NORMAL));
+		}
+	}
 }
 
 /**
@@ -1415,6 +1424,7 @@
 	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);
 
 	mpoly = CustomData_get_layer(pdata, CD_MPOLY);
 	mloop = CustomData_get_layer(ldata, CD_MLOOP);
@@ -1637,7 +1647,7 @@
 #else
 		                                3,
 #endif
-		                                numTex, numCol, hasPCol, hasOrigSpace);
+		                                numTex, numCol, hasPCol, hasOrigSpace, hasLNor);
 
 
 #ifdef USE_TESSFACE_QUADS
@@ -1677,6 +1687,7 @@
 	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_mallocN(sizeof(*mface) * (size_t)totpoly, __func__);
@@ -1736,7 +1747,7 @@
 
 				BKE_mesh_loops_to_mface_corners(fdata, ldata, pdata,
 				                                lindex, k, i, 3,
-				                                numTex, numCol, hasPCol, hasOrigSpace);
+				                                numTex, numCol, hasPCol, hasOrigSpace, hasLNor);
 				test_index_face(mf, fdata, k, 3);
 			}
 			else {
@@ -1756,7 +1767,7 @@
 
 				BKE_mesh_loops_to_mface_corners(fdata, ldata, pdata,
 				                                lindex, k, i, 4,
-				                                numTex, numCol, hasPCol, hasOrigSpace);
+				                                numTex, numCol, hasPCol, hasOrigSpace, hasLNor);
 				test_index_face(mf, fdata, k, 4);
 			}
 

Modified: branches/vgroup_modifiers/source/blender/makesdna/DNA_customdata_types.h
===================================================================
--- branches/vgroup_modifiers/source/blender/makesdna/DNA_customdata_types.h	2013-10-14 08:03:55 UTC (rev 60743)
+++ branches/vgroup_modifiers/source/blender/makesdna/DNA_customdata_types.h	2013-10-14 08:20:12 UTC (rev 60744)
@@ -63,10 +63,9 @@
  * layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */
 typedef struct CustomData {
 	CustomDataLayer *layers;      /* CustomDataLayers, ordered by type */
-	int typemap[40];              /* runtime only! - maps types to indices of first layer of that type,
+	int typemap[41];              /* runtime only! - maps types to indices of first layer of that type,
 	                               * MUST be >= CD_NUMTYPES, but we cant use a define here.
 	                               * Correct size is ensured in CustomData_update_typemap assert() */
-	int pad_i0;
 	int totlayer, maxlayer;       /* number of layers, size of layers array */
 	int totsize;                  /* in editmode, total size of all data layers */
 	void *pool;                   /* Bmesh: Memory pool for allocation of blocks */
@@ -119,7 +118,8 @@
 	CD_FREESTYLE_EDGE   = 37,
 	CD_FREESTYLE_FACE   = 38,
 	CD_LOOPTANGENT      = 39,
-	CD_NUMTYPES         = 40,
+	CD_TESSLOOPNORMAL   = 40,
+	CD_NUMTYPES         = 41,
 };
 
 /* Bits for CustomDataMask */




More information about the Bf-blender-cvs mailing list