[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [46143] trunk/blender/source/blender: Fix #31193: Normals don't have any Z component

Sergey Sharybin sergey.vfx at gmail.com
Tue May 1 13:01:25 CEST 2012


Revision: 46143
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46143
Author:   nazgul
Date:     2012-05-01 11:01:24 +0000 (Tue, 01 May 2012)
Log Message:
-----------
Fix #31193: Normals don't have any Z component

Issue was caused by heavily non-uniform scale applied on object.
Run scale correction on face and vertex normals draw if there's non-uniform scale.

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/BLI_math_matrix.h
    trunk/blender/source/blender/blenlib/intern/math_matrix.c
    trunk/blender/source/blender/editors/space_view3d/drawobject.c

Modified: trunk/blender/source/blender/blenlib/BLI_math_matrix.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_matrix.h	2012-05-01 10:28:50 UTC (rev 46142)
+++ trunk/blender/source/blender/blenlib/BLI_math_matrix.h	2012-05-01 11:01:24 UTC (rev 46143)
@@ -126,6 +126,8 @@
 int is_orthonormal_m3(float mat[3][3]);
 int is_orthonormal_m4(float mat[4][4]);
 
+int is_uniform_scaled_m3(float mat[3][3]);
+
 void adjoint_m3_m3(float R[3][3], float A[3][3]);
 void adjoint_m4_m4(float R[4][4], float A[4][4]);
 

Modified: trunk/blender/source/blender/blenlib/intern/math_matrix.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_matrix.c	2012-05-01 10:28:50 UTC (rev 46142)
+++ trunk/blender/source/blender/blenlib/intern/math_matrix.c	2012-05-01 11:01:24 UTC (rev 46143)
@@ -866,6 +866,35 @@
 	return 0;
 }
 
+int is_uniform_scaled_m3(float m[][3])
+{
+	const float eps = 1e-7;
+	float t[3][3];
+	float l1, l2, l3, l4, l5, l6;
+
+	copy_m3_m3(t, m);
+	transpose_m3(t);
+
+	l1 = len_squared_v3(m[0]);
+	l2 = len_squared_v3(m[1]);
+	l3 = len_squared_v3(m[2]);
+
+	l4 = len_squared_v3(t[0]);
+	l5 = len_squared_v3(t[1]);
+	l6 = len_squared_v3(t[2]);
+
+	if (fabsf(l2 - l1) <= eps &&
+	    fabsf(l3 - l1) <= eps &&
+	    fabsf(l4 - l1) <= eps &&
+	    fabsf(l5 - l1) <= eps &&
+	    fabsf(l6 - l1) <= eps)
+	{
+		return 1;
+	}
+
+	return 0;
+}
+
 void normalize_m3(float mat[][3])
 {
 	normalize_v3(mat[0]);

Modified: trunk/blender/source/blender/editors/space_view3d/drawobject.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/drawobject.c	2012-05-01 10:28:50 UTC (rev 46142)
+++ trunk/blender/source/blender/editors/space_view3d/drawobject.c	2012-05-01 11:01:24 UTC (rev 46143)
@@ -164,7 +164,10 @@
 
 typedef struct drawDMNormal_userData {
 	BMEditMesh *em;
+	int uniform_scale;
 	float normalsize;
+	float tmat[3][3];
+	float imat[3][3];
 } drawDMNormal_userData;
 
 typedef struct bbsObmodeMeshVerts_userData {
@@ -2269,25 +2272,56 @@
  * logic!!!
  */
 
+static void calcDrawDMNormalScale(Object *ob, drawDMNormal_userData *data)
+{
+	float obmat[3][3];
+
+	copy_m3_m4(obmat, ob->obmat);
+
+	data->uniform_scale = is_uniform_scaled_m3(obmat);
+
+	if (!data->uniform_scale) {
+		/* inverted matrix */
+		invert_m3_m3(data->imat, obmat);
+
+		/* transposed inverted matrix */
+		copy_m3_m3(data->tmat, data->imat);
+		transpose_m3(data->tmat);
+	}
+}
+
 static void draw_dm_face_normals__mapFunc(void *userData, int index, const float cent[3], const float no[3])
 {
 	drawDMNormal_userData *data = userData;
 	BMFace *efa = EDBM_face_at_index(data->em, index);
+	float n[3];
 
 	if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+		if (!data->uniform_scale) {
+			mul_v3_m3v3(n, data->tmat, (float *) no);
+			normalize_v3(n);
+			mul_m3_v3(data->imat, n);
+		}
+		else {
+			copy_v3_v3(n, no);
+		}
+
 		glVertex3fv(cent);
-		glVertex3f(cent[0] + no[0] * data->normalsize,
-		           cent[1] + no[1] * data->normalsize,
-		           cent[2] + no[2] * data->normalsize);
+		glVertex3f(cent[0] + n[0] * data->normalsize,
+		           cent[1] + n[1] * data->normalsize,
+		           cent[2] + n[2] * data->normalsize);
 	}
 }
-static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, DerivedMesh *dm) 
+
+static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
 {
 	drawDMNormal_userData data;
 
 	data.em = em;
 	data.normalsize = scene->toolsettings->normalsize;
 
+	calcDrawDMNormalScale(ob, &data);
+
 	glBegin(GL_LINES);
 	dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data);
 	glEnd();
@@ -2317,27 +2351,42 @@
 	BMVert *eve = EDBM_vert_at_index(data->em, index);
 
 	if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
-		glVertex3fv(co);
+		float no[3], n[3];
 
 		if (no_f) {
-			glVertex3f(co[0] + no_f[0] * data->normalsize,
-			           co[1] + no_f[1] * data->normalsize,
-			           co[2] + no_f[2] * data->normalsize);
+			copy_v3_v3(no, no_f);
 		}
 		else {
-			glVertex3f(co[0] + no_s[0] * (data->normalsize / 32767.0f),
-			           co[1] + no_s[1] * (data->normalsize / 32767.0f),
-			           co[2] + no_s[2] * (data->normalsize / 32767.0f));
+			no[0] = no_s[0] / 32767.0f;
+			no[1] = no_s[1] / 32767.0f;
+			no[2] = no_s[2] / 32767.0f;
 		}
+
+		if (!data->uniform_scale) {
+			mul_v3_m3v3(n, data->tmat, (float *) no);
+			normalize_v3(n);
+			mul_m3_v3(data->imat, n);
+		}
+		else {
+			copy_v3_v3(n, no);
+		}
+
+		glVertex3fv(co);
+		glVertex3f(co[0] + n[0] * data->normalsize,
+		           co[1] + n[1] * data->normalsize,
+		           co[2] + n[2] * data->normalsize);
 	}
 }
-static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, DerivedMesh *dm) 
+
+static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm)
 {
 	drawDMNormal_userData data;
 
 	data.em = em;
 	data.normalsize = scene->toolsettings->normalsize;
 
+	calcDrawDMNormalScale(ob, &data);
+
 	glBegin(GL_LINES);
 	dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data);
 	glEnd();
@@ -3167,11 +3216,11 @@
 
 		if (me->drawflag & ME_DRAWNORMALS) {
 			UI_ThemeColor(TH_NORMAL);
-			draw_dm_face_normals(em, scene, cageDM);
+			draw_dm_face_normals(em, scene, ob, cageDM);
 		}
 		if (me->drawflag & ME_DRAW_VNORMALS) {
 			UI_ThemeColor(TH_VNORMAL);
-			draw_dm_vert_normals(em, scene, cageDM);
+			draw_dm_vert_normals(em, scene, ob, cageDM);
 		}
 
 		if ( (me->drawflag & (ME_DRAWEXTRA_EDGELEN | ME_DRAWEXTRA_FACEAREA | ME_DRAWEXTRA_FACEANG)) &&




More information about the Bf-blender-cvs mailing list