[Bf-blender-cvs] [a42553f] master: Fix T43579: FBX Export shading issue (Broken normals?)

Bastien Montagne noreply at git.blender.org
Fri Feb 6 20:16:44 CET 2015


Commit: a42553f986baa8f457b2b9db0b97d8e86bfca1cf
Author: Bastien Montagne
Date:   Fri Feb 6 20:14:18 2015 +0100
Branches: master
https://developer.blender.org/rBa42553f986baa8f457b2b9db0b97d8e86bfca1cf

Fix T43579: FBX Export shading issue (Broken normals?)

Error in custom split normals work, non-autosmooth normals != vertex normals!
Loops from flat faces shall take normal of their face, not their vertex.

Tsst...

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

M	source/blender/blenkernel/intern/mesh_evaluate.c
M	source/blender/bmesh/intern/bmesh_mesh.c
M	source/blender/modifiers/intern/MOD_normal_edit.c

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

diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index f12fdeb..5520653 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -1062,18 +1062,33 @@ void BKE_mesh_normals_loop_split(
 {
 
 	/* For now this is not supported. If we do not use split normals, we do not generate anything fancy! */
-	BLI_assert(use_split_normals || !(r_lnors_spacearr || r_loop_to_poly));
+	BLI_assert(use_split_normals || !(r_lnors_spacearr));
 
 	if (!use_split_normals) {
-		/* In this case, we simply fill lnors with vnors, quite simple!
+		/* In this case, we simply fill lnors with vnors (or fnors for flat faces), quite simple!
 		 * Note this is done here to keep some logic and consistency in this quite complex code,
 		 * since we may want to use lnors even when mesh's 'autosmooth' is disabled (see e.g. mesh mapping code).
 		 * As usual, we could handle that on case-by-case basis, but simpler to keep it well confined here.
 		 */
-		int i;
+		int mp_index;
 
-		for (i = 0; i < numLoops; i++) {
-			normal_short_to_float_v3(r_loopnors[i], mverts[mloops[i].v].no);
+		for (mp_index = 0; mp_index < numPolys; mp_index++) {
+			MPoly *mp = &mpolys[mp_index];
+			int ml_index = mp->loopstart;
+			const int ml_index_end = ml_index + mp->totloop;
+			const bool is_poly_flat = ((mp->flag & ME_SMOOTH) == 0);
+
+			for (; ml_index < ml_index_end; ml_index++) {
+				if (r_loop_to_poly) {
+					r_loop_to_poly[ml_index] = mp_index;
+				}
+				if (is_poly_flat) {
+					copy_v3_v3(r_loopnors[ml_index], polynors[mp_index]);
+				}
+				else {
+					normal_short_to_float_v3(r_loopnors[ml_index], mverts[mloops[ml_index].v].no);
+				}
+			}
 		}
 		return;
 	}
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 6700ffe..9a2869b 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -815,7 +815,8 @@ static void bm_mesh_loops_calc_normals(
 	}
 }
 
-static void bm_mesh_loops_from_vert_normals(BMesh *bm, const float (*vnos)[3], float (*r_lnos)[3])
+static void bm_mesh_loops_calc_normals_no_autosmooth(
+        BMesh *bm, const float (*vnos)[3], const float (*fnos)[3], float (*r_lnos)[3])
 {
 	BMIter fiter;
 	BMFace *f_curr;
@@ -825,15 +826,20 @@ static void bm_mesh_loops_from_vert_normals(BMesh *bm, const float (*vnos)[3], f
 		if (vnos) {
 			htype |= BM_VERT;
 		}
+		if (fnos) {
+			htype |= BM_FACE;
+		}
 		BM_mesh_elem_index_ensure(bm, htype);
 	}
 
 	BM_ITER_MESH (f_curr, &fiter, bm, BM_FACES_OF_MESH) {
 		BMLoop *l_curr, *l_first;
+		const bool is_face_flat = !BM_elem_flag_test(f_curr, BM_ELEM_SMOOTH);
 
 		l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr);
 		do {
-			const float *no = vnos ? vnos[BM_elem_index_get(l_curr->v)] : l_curr->v->no;
+			const float *no = is_face_flat ? (fnos ? fnos[BM_elem_index_get(f_curr)] : f_curr->no) :
+			                                 (vnos ? vnos[BM_elem_index_get(l_curr->v)] : l_curr->v->no);
 			copy_v3_v3(r_lnos[BM_elem_index_get(l_curr)], no);
 
 		} while ((l_curr = l_curr->next) != l_first);
@@ -863,7 +869,7 @@ void BM_mesh_loop_normals_update(
 	}
 	else {
 		BLI_assert(!r_lnors_spacearr);
-		bm_mesh_loops_from_vert_normals(bm, NULL, r_lnos);
+		bm_mesh_loops_calc_normals_no_autosmooth(bm, NULL, NULL, r_lnos);
 	}
 }
 #endif
@@ -891,7 +897,7 @@ void BM_loops_calc_normal_vcos(
 	}
 	else {
 		BLI_assert(!r_lnors_spacearr);
-		bm_mesh_loops_from_vert_normals(bm, vnos, r_lnos);
+		bm_mesh_loops_calc_normals_no_autosmooth(bm, vnos, fnos, r_lnos);
 	}
 }
 
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
index 3bf6051..58ef850 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.c
+++ b/source/blender/modifiers/intern/MOD_normal_edit.c
@@ -362,7 +362,7 @@ static void normalEditModifier_do(NormalEditModifierData *smd, Object *ob, Deriv
 
 
 	if (use_current_clnors) {
-		dm->calcLoopNormals(dm, (me->flag & ME_AUTOSMOOTH) != 0, me->smoothresh);
+		dm->calcLoopNormals(dm, true, me->smoothresh);
 		loopnors = dm->getLoopDataArray(dm, CD_NORMAL);
 	}




More information about the Bf-blender-cvs mailing list