[Bf-blender-cvs] [18e4224] master: Split Normals I (1/5): basis for split normals (nearly nothing user-visible here):

Bastien Montagne noreply at git.blender.org
Sun Apr 13 15:39:02 CEST 2014


Commit: 18e4224142261cd8a1086c5872efb406b82f8330
Author: Bastien Montagne
Date:   Sun Apr 13 12:18:51 2014 +0200
https://developer.blender.org/rB18e4224142261cd8a1086c5872efb406b82f8330

Split Normals I (1/5): basis for split normals (nearly nothing user-visible here):

* Add a new calcLoopNormals function to DerivedMesh struct, and implement it for CDDM and CCGDM (subsurf).
  EditDerivedBMesh (edit mode DM) only gets a dummy one in this commit.
* Add a tessellated version of CD_LOOPNORMAL layer (CD_TESSLOOPNORMAL), with relevant code to handle it
  (tessellation, rna access, etc.).
* Change auto_smooth options of Mesh (angle now in radian internaly, and toggle is now used to enable/disable
  split normals in DM creation process). Note BI render code is not touched here, hence its behavior regarding
  this option is now incoherent, will be addressed in a separate commit.

Reviewers: campbellbarton

CC: brecht

Differential Revision: https://developer.blender.org/D365

===================================================================

M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/blenkernel/BKE_DerivedMesh.h
M	source/blender/blenkernel/BKE_blender.h
M	source/blender/blenkernel/BKE_cdderivedmesh.h
M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/intern/DerivedMesh.c
M	source/blender/blenkernel/intern/cdderivedmesh.c
M	source/blender/blenkernel/intern/customdata.c
M	source/blender/blenkernel/intern/editderivedmesh.c
M	source/blender/blenkernel/intern/mesh_evaluate.c
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/blenloader/intern/versioning_270.c
M	source/blender/blenloader/intern/versioning_defaults.c
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/makesdna/DNA_customdata_types.h
M	source/blender/makesdna/DNA_mesh_types.h
M	source/blender/makesrna/intern/rna_mesh.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index d43e6d1..56f612a 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2760,6 +2760,15 @@ class VIEW3D_PT_view3d_name(Panel):
                 row.label(text="", icon='BONE_DATA')
                 row.prop(bone, "name", text="")
 
+        elif ob.type == 'MESH':
+            me = ob.data
+            row = layout.row()
+            row.prop(me, "use_auto_smooth")
+            row = row.row()
+            if not me.use_auto_smooth:
+                row.active = False
+            row.prop(me, "auto_smooth_angle", text="")
+
 
 class VIEW3D_PT_view3d_display(Panel):
     bl_space_type = 'VIEW_3D'
@@ -2936,14 +2945,14 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
 
         col.separator()
         col.label(text="Normals:")
-        row = col.row()
+        row = col.row(align=True)
 
-        sub = row.row(align=True)
-        sub.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL')
-        sub.prop(mesh, "show_normal_face", text="", icon='FACESEL')
+        row.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL')
+        row.prop(mesh, "show_normal_loop", text="", icon='VERTEXSEL')
+        row.prop(mesh, "show_normal_face", text="", icon='FACESEL')
 
         sub = row.row(align=True)
-        sub.active = mesh.show_normal_vertex or mesh.show_normal_face
+        sub.active = mesh.show_normal_vertex or mesh.show_normal_face or mesh.show_normal_loop
         sub.prop(context.scene.tool_settings, "normal_size", text="Size")
 
         col.separator()
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 3afd7d8..5206f8b 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -193,6 +193,9 @@ struct DerivedMesh {
 	/** Calculate vert and face normals */
 	void (*calcNormals)(DerivedMesh *dm);
 
+	/** Calculate loop (split) normals */
+	void (*calcLoopNormals)(DerivedMesh *dm, const float split_angle);
+
 	/** Recalculates mesh tessellation */
 	void (*recalcTessellation)(DerivedMesh *dm);
 
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 3eb2fab..9a67284 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -42,7 +42,7 @@ extern "C" {
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION         270
-#define BLENDER_SUBVERSION      1
+#define BLENDER_SUBVERSION      2
 /* 262 was the last editmesh release but it has compatibility code for bmesh data */
 #define BLENDER_MINVERSION      262
 #define BLENDER_MINSUBVERSION   0
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h
index 4e6d695..dffc2b6 100644
--- a/source/blender/blenkernel/BKE_cdderivedmesh.h
+++ b/source/blender/blenkernel/BKE_cdderivedmesh.h
@@ -100,6 +100,8 @@ void CDDM_calc_normals_mapping(struct DerivedMesh *dm);
 void CDDM_calc_normals(struct DerivedMesh *dm);
 void CDDM_calc_normals_tessface(struct DerivedMesh *dm);
 
+void CDDM_calc_loop_normals(struct DerivedMesh *dm, const float split_angle);
+
 /* calculates edges for a CDDerivedMesh (from face data)
  * this completely replaces the current edge data in the DerivedMesh
  * builds edges from the tessellated face data.
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 9c57b7c..d6c3734 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -215,7 +215,7 @@ void BKE_mesh_loops_to_mface_corners(
         struct CustomData *pdata, unsigned 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);
 void BKE_mesh_loops_to_tessdata(
         struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata, struct MFace *mface,
         int *polyindices, unsigned int (*loopindices)[4], const int num_faces);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 84b54ff..0c4e714 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -399,6 +399,11 @@ void DM_ensure_normals(DerivedMesh *dm)
 	BLI_assert((dm->dirty & DM_DIRTY_NORMALS) == 0);
 }
 
+static void DM_calc_loop_normals(DerivedMesh *dm, float split_angle)
+{
+	dm->calcLoopNormals(dm, split_angle);
+}
+
 /* note: until all modifiers can take MPoly's as input,
  * use this at the start of modifiers  */
 void DM_ensure_tessface(DerivedMesh *dm)
@@ -453,7 +458,8 @@ void DM_update_tessface_data(DerivedMesh *dm)
 	if (CustomData_has_layer(fdata, CD_MTFACE) ||
 	    CustomData_has_layer(fdata, CD_MCOL) ||
 	    CustomData_has_layer(fdata, CD_PREVIEW_MCOL) ||
-	    CustomData_has_layer(fdata, CD_ORIGSPACE))
+	    CustomData_has_layer(fdata, CD_ORIGSPACE) ||
+	    CustomData_has_layer(fdata, CD_TESSLOOPNORMAL))
 	{
 		loopindex = MEM_mallocN(sizeof(*loopindex) * totface, __func__);
 
@@ -1471,6 +1477,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
 	/* XXX Same as above... For now, only weights preview in WPaint mode. */
 	const bool do_mod_wmcol = do_init_wmcol;
 
+	const bool do_loop_normals = (me->flag & ME_AUTOSMOOTH);
+	const float loop_normals_split_angle = me->smoothresh;
+
 	VirtualModifierData virtualModifierData;
 
 	ModifierApplyFlag app_flags = useRenderParams ? MOD_APPLY_RENDER : 0;
@@ -1865,7 +1874,21 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
 			add_orco_dm(ob, NULL, *deform_r, NULL, CD_ORCO);
 	}
 
-	{
+	if (do_loop_normals) {
+		/* Compute loop normals (note: will compute poly and vert normals as well, if needed!) */
+		DM_calc_loop_normals(finaldm, loop_normals_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);
@@ -1982,7 +2005,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
 	ModifierData *md, *previewmd = NULL;
 	float (*deformedVerts)[3] = NULL;
 	CustomDataMask mask, previewmask = 0, append_mask = 0;
-	DerivedMesh *dm, *orcodm = NULL;
+	DerivedMesh *dm = NULL, *orcodm = NULL;
 	int i, numVerts = 0, cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
 	CDMaskLink *datamasks, *curr;
 	int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
@@ -1998,13 +2021,15 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
 	const bool do_mod_wmcol = do_init_wmcol;
 	VirtualModifierData virtualModifierData;
 
+	const bool do_loop_normals = (((Mesh *)(ob->data))->flag & ME_AUTOSMOOTH);
+	const float loop_normals_split_angle = ((Mesh *)(ob->data))->smoothresh;
+
 	modifiers_clearErrors(ob);
 
 	if (cage_r && cageIndex == -1) {
 		*cage_r = getEditDerivedBMesh(em, ob, NULL);
 	}
 
-	dm = NULL;
 	md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
 
 	/* copied from mesh_calc_modifiers */
@@ -2212,6 +2237,14 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
 			DM_update_statvis_color(scene, ob, *final_r);
 	}
 
+	if (do_loop_normals) {
+		/* Compute loop normals */
+		DM_calc_loop_normals(*final_r, loop_normals_split_angle);
+		if (cage_r && *cage_r && (*cage_r != *final_r)) {
+			DM_calc_loop_normals(*cage_r, loop_normals_split_angle);
+		}
+	}
+
 	/* --- */
 	/* BMESH_ONLY, ensure tessface's used for drawing,
 	 * but don't recalculate if the last modifier in the stack gives us tessfaces
@@ -2229,8 +2262,10 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
 	}
 	/* --- */
 
-	/* same as mesh_calc_modifiers */
-	dm_ensure_display_normals(*final_r);
+	/* same as mesh_calc_modifiers (if using loop normals, poly nors have already been computed). */
+	if (!do_loop_normals) {
+		dm_ensure_display_normals(*final_r);
+	}
 
 	/* add an orco layer if needed */
 	if (dataMask & CD_MASK_ORCO)
@@ -2542,7 +2577,8 @@ DMCoNo *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
 /* ******************* GLSL ******************** */
 
 typedef struct {
-	float *precomputedFaceNormals;
+	float (*precomputedFaceNormals)[3];
+	short (*precomputedLoopNormals)[4][3];
 	MTFace *mtface;     /* texture coordinates */
 	MFace *mface;       /* indices */
 	MVert *mvert;       /* vertices & normals */
@@ -2594,11 +2630,14 @@ static void GetNormal(const SMikkTSpaceContext *pContext, float r_no[3], const i
 {
 	//assert(vert_index >= 0 && vert_index < 4);
 	SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
+	const bool smoothnormal = (pMesh->mface[face_num].flag & ME_SMOOTH) != 0;
 
-	const int smoothnormal = (pMesh->mface[face_num].flag & ME_SMOOTH);
-	if (!smoothnormal) {    // flat
+	if (pMesh->precomputedLoopNormals) {
+		normal_short_to_float_v3(r_no, pMesh->precomputedLoopNormals[face_num][vert_index]);
+	}
+	else if (!smoothnormal) {    // flat
 		if (pMesh->precomputedFaceNormals) {
-			copy_v3_v3(r_no, &pMesh->precomputedFaceNormals[3 * face_num]);
+			copy_v3_v3(r_no, pMesh->precomputedFaceNormals[face_num]);
 		}
 		else {
 			MFace *mf = &pMesh->mface[face_num];
@@ -2638,12 +2677,17 @@ void DM_add_tangent_layer(DerivedMesh *dm)
 	MFace *mface;
 	float (*orco)[3] = NULL, (*tangent)[4];
 	int /* totvert, */ totface;
-	float *nors;
+	float (*fnors)[3];
+	short (*tlnors)[4][3];
 
 	if (CustomData_get_layer_index(&dm->faceData,

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list