[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [40707] branches/bmesh/blender/source/ blender: More normal fixes, this time for object mode calculation of vertex normals

Andrew Wiggin ender79bl at gmail.com
Fri Sep 30 07:27:45 CEST 2011


Revision: 40707
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40707
Author:   ender79
Date:     2011-09-30 05:27:44 +0000 (Fri, 30 Sep 2011)
Log Message:
-----------
More normal fixes, this time for object mode calculation of vertex normals

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c
    branches/bmesh/blender/source/blender/blenlib/BLI_math_geom.h
    branches/bmesh/blender/source/blender/blenlib/intern/math_geom.c

Modified: branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c
===================================================================
--- branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c	2011-09-30 05:07:12 UTC (rev 40706)
+++ branches/bmesh/blender/source/blender/blenkernel/intern/mesh.c	2011-09-30 05:27:44 UTC (rev 40707)
@@ -1718,40 +1718,50 @@
 	int *origIndexFace, float (*faceNors_r)[3])
 {
 	float (*pnors)[3] = polyNors_r, (*fnors)[3] = faceNors_r;
-	float (*tnorms)[3] = NULL;
-	int i, j;
+	float (*tnorms)[3], (*edgevecbuf)[3];
+	float **vertcos = NULL, **vertnos = NULL;
+	BLI_array_declare(vertcos);
+	BLI_array_declare(vertnos);
+	int i, j, maxPolyVerts = 0;
 	MFace *mf;
 	MPoly *mp;
 	MLoop *ml;
-	
-	if(numPolys == 0) return;
-	
+
+	if (numPolys == 0) {
+		return;
+	}
+
+	mp = mpolys;
+	for (i=0; i<numPolys; i++, mp++) {
+		maxPolyVerts = MAX2(mp->totloop, maxPolyVerts);
+	}
+
+	if (maxPolyVerts == 0) {
+		return;
+	}
+
 	/*first go through and calculate normals for all the polys*/
-	tnorms = MEM_callocN(sizeof(float)*3*numVerts, "tnorms cdderivedmesh.c");
+	edgevecbuf = MEM_callocN(sizeof(float)*3*maxPolyVerts, "edgevecbuf mesh.c");
+	tnorms = MEM_callocN(sizeof(float)*3*numVerts, "tnorms mesh.c");
 	if (!pnors) 
-		pnors = MEM_callocN(sizeof(float)*3*numPolys, "poly_nors cdderivedmesh.c");
+		pnors = MEM_callocN(sizeof(float)*3*numPolys, "poly_nors mesh.c");
 	if (!fnors)
-		fnors = MEM_callocN(sizeof(float)*3*numFaces, "face nors cdderivedmesh.c");
+		fnors = MEM_callocN(sizeof(float)*3*numFaces, "face nors mesh.c");
 	
 	mp = mpolys;
 	for (i=0; i<numPolys; i++, mp++) {
 		mesh_calc_poly_normal(mp, mloop+mp->loopstart, mverts, pnors[i]);
-		
 		ml = mloop + mp->loopstart;
-		/*this is kindof hackish, probably need to calculate quads around face center for
-		  ngons, not this weird quad-fitting thing I've got going here*/
-		for (j=0; j<mp->totloop; j += 4, ml += 4) {
-			int v1, v2, v3, v4;
-			
-			v1 = ml->v; 
-			v2 = mloop[mp->loopstart+(j+1)%mp->totloop].v;
-			v3 = mloop[mp->loopstart+(j+2)%mp->totloop].v;
-			v4 = mloop[mp->loopstart+(j+3)%mp->totloop].v;
-					
-			accumulate_vertex_normals(tnorms[v1], tnorms[v2], tnorms[v3], v4 != v1 ? tnorms[v4] : NULL,
-									  pnors[i], mverts[v1].co, mverts[v2].co, mverts[v3].co, v4!=v1 ? mverts[v4].co : NULL);
-			
+
+		BLI_array_empty(vertcos);
+		BLI_array_empty(vertnos);
+		for (j=0; j<mp->totloop; j++) {
+			int vindex = ml[j].v;
+			BLI_array_append(vertcos, mverts[vindex].co);
+			BLI_array_append(vertnos, tnorms[vindex]);
 		}
+
+		accumulate_vertex_normals_poly(vertnos, pnors[i], vertcos, edgevecbuf, mp->totloop);
 	}
 	
 	/* following Mesh convention; we use vertex coordinate itself for normal in this case */
@@ -1776,7 +1786,10 @@
 			}
 		}
 	}
-	
+
+	BLI_array_free(vertcos);
+	BLI_array_free(vertnos);
+	MEM_freeN(edgevecbuf);
 	MEM_freeN(tnorms);
 	if (fnors != faceNors_r)
 		MEM_freeN(fnors);

Modified: branches/bmesh/blender/source/blender/blenlib/BLI_math_geom.h
===================================================================
--- branches/bmesh/blender/source/blender/blenlib/BLI_math_geom.h	2011-09-30 05:07:12 UTC (rev 40706)
+++ branches/bmesh/blender/source/blender/blenlib/BLI_math_geom.h	2011-09-30 05:27:44 UTC (rev 40707)
@@ -202,6 +202,9 @@
 	float n4[3], const float f_no[3], const float co1[3], const float co2[3],
 	const float co3[3], const float co4[3]);
 
+void accumulate_vertex_normals_poly(float **vertnos, float polyno[3],
+	float **vertcos, float vdiffs[][3], int nverts);
+
 /********************************* Tangents **********************************/
 
 typedef struct VertexTangent {

Modified: branches/bmesh/blender/source/blender/blenlib/intern/math_geom.c
===================================================================
--- branches/bmesh/blender/source/blender/blenlib/intern/math_geom.c	2011-09-30 05:07:12 UTC (rev 40706)
+++ branches/bmesh/blender/source/blender/blenlib/intern/math_geom.c	2011-09-30 05:27:44 UTC (rev 40707)
@@ -2297,6 +2297,39 @@
 	}
 }
 
+/* Add weighted face normal component into normals of the face vertices.
+   Caller must pass pre-allocated vdiffs of nverts length. */
+#define VERT_BUF_SIZE 100
+void accumulate_vertex_normals_poly(float **vertnos, float polyno[3],
+	float **vertcos, float vdiffs[][3], int nverts)
+{
+	int i;
+
+	/* calculate normalized edge directions for each edge in the poly */
+	for (i = 0; i < nverts; i++) {
+		sub_v3_v3v3(vdiffs[i], vertcos[(i+1) % nverts], vertcos[i]);
+		normalize_v3(vdiffs[i]);
+	}
+
+	/* accumulate angle weighted face normal */
+	{
+		const float *prev_edge = vdiffs[nverts-1];
+		int i;
+
+		for(i=0; i<nverts; i++) {
+			const float *cur_edge = vdiffs[i];
+			
+			/* calculate angle between the two poly edges incident on
+			   this vertex */
+			const float fac= saacos(-dot_v3v3(cur_edge, prev_edge));
+
+			/* accumulate */
+			madd_v3_v3fl(vertnos[i], polyno, fac);
+			prev_edge = cur_edge;
+		}
+	}
+}
+
 /********************************* Tangents **********************************/
 
 /* For normal map tangents we need to detect uv boundaries, and only average




More information about the Bf-blender-cvs mailing list