[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [46422] trunk/blender/source/blender: optimize ngon angle calculation in solidify modifier (was doing prev/ next vector subtract and normalize for every vertex).

Campbell Barton ideasman42 at gmail.com
Tue May 8 16:58:38 CEST 2012


Revision: 46422
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46422
Author:   campbellbarton
Date:     2012-05-08 14:58:38 +0000 (Tue, 08 May 2012)
Log Message:
-----------
optimize ngon angle calculation in solidify modifier (was doing prev/next vector subtract and normalize for every vertex). now store the previous normalized vector for re-use.

also add BKE_mesh_poly_calc_angles() which is mostly a reference for now.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_mesh.h
    trunk/blender/source/blender/blenkernel/intern/mesh.c
    trunk/blender/source/blender/modifiers/intern/MOD_solidify.c

Modified: trunk/blender/source/blender/blenkernel/BKE_mesh.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_mesh.h	2012-05-08 13:01:16 UTC (rev 46421)
+++ trunk/blender/source/blender/blenkernel/BKE_mesh.h	2012-05-08 14:58:38 UTC (rev 46422)
@@ -304,6 +304,9 @@
                                      const int polyindex, const int mf_len,
                                      const int numTex, const int numCol, const int hasPCol, const int hasOrigSpace);
 
+void BKE_mesh_poly_calc_angles(struct MVert *mvert, struct MLoop *mloop,
+                               struct MPoly *mp, float angles[]);
+
 #ifdef __cplusplus
 }
 #endif

Modified: trunk/blender/source/blender/blenkernel/intern/mesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/mesh.c	2012-05-08 13:01:16 UTC (rev 46421)
+++ trunk/blender/source/blender/blenkernel/intern/mesh.c	2012-05-08 14:58:38 UTC (rev 46422)
@@ -3103,3 +3103,51 @@
 {
 	mesh_tessface_clear_intern(mesh, TRUE);
 }
+
+#if 0 /* slow version of the function below */
+void BKE_mesh_poly_calc_angles(MVert *mvert, MLoop *mloop,
+                                 MPoly *mp, float angles[])
+{
+	MLoop *ml;
+
+	int j;
+	for (j = 0, ml = mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
+		MLoop *ml_prev = ME_POLY_LOOP_PREV(mloop, mp, j);
+		MLoop *ml_next = ME_POLY_LOOP_NEXT(mloop, mp, j);
+
+		float e1[3], e2[3];
+
+		sub_v3_v3v3(e1, mvert[ml_next->v].co, mvert[ml->v].co);
+		sub_v3_v3v3(e2, mvert[ml_prev->v].co, mvert[ml->v].co);
+
+		angles[j] = (float)M_PI - angle_v3v3(e1, e2);
+	}
+}
+
+#else /* equivalent the function above but avoid multiple subtractions + normalize */
+
+void BKE_mesh_poly_calc_angles(MVert *mvert, MLoop *mloop,
+                                 MPoly *mp, float angles[])
+{
+	MLoop *ml = mloop + mp->loopstart;
+	float nor_prev[3];
+	float nor_next[3];
+
+	int i_this = mp->totloop - 1;
+	int i_next = 0;
+
+	sub_v3_v3v3(nor_prev, mvert[ml[i_this - 1].v].co, mvert[ml[i_this].v].co);
+	normalize_v3(nor_prev);
+
+	while (i_next < mp->totloop) {
+		sub_v3_v3v3(nor_next, mvert[ml[i_this].v].co, mvert[ml[i_next].v].co);
+		normalize_v3(nor_next);
+		angles[i_this] = angle_normalized_v3v3(nor_prev, nor_next);
+
+		/* step */
+		copy_v3_v3(nor_prev, nor_next);
+		i_this = i_next;
+		i_next++;
+	}
+}
+#endif

Modified: trunk/blender/source/blender/modifiers/intern/MOD_solidify.c
===================================================================
--- trunk/blender/source/blender/modifiers/intern/MOD_solidify.c	2012-05-08 13:01:16 UTC (rev 46421)
+++ trunk/blender/source/blender/modifiers/intern/MOD_solidify.c	2012-05-08 14:58:38 UTC (rev 46422)
@@ -451,7 +451,7 @@
 		/* same as EM_solidify() in editmesh_lib.c */
 		float *vert_angles = MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */
 		float *vert_accum = vert_angles + numVerts;
-		int j, vidx;
+		int vidx;
 
 		face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
 		if (!face_nors) {
@@ -467,30 +467,44 @@
 		}
 
 		for (i = 0, mp = mpoly; i < numFaces; i++, mp++) {
+			/* #BKE_mesh_poly_calc_angles logic is inlined here */
+			float nor_prev[3];
+			float nor_next[3];
+
+			int i_this = mp->totloop - 1;
+			int i_next = 0;
+
+			ml = &mloop[mp->loopstart];
+
+			/* --- not related to angle calc --- */
 			if (face_nors_calc)
-				mesh_calc_poly_normal(mp, &mloop[mp->loopstart], mvert, face_nors[i]);
-			
-			/* just added, calc the normal */
-			for (j = 0, ml = mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
-				MLoop *ml_prev = ME_POLY_LOOP_PREV(mloop, mp, j);
-				MLoop *ml_next = ME_POLY_LOOP_NEXT(mloop, mp, j);
+				mesh_calc_poly_normal(mp, ml, mvert, face_nors[i]);
+			/* --- end non-angle-calc section --- */
 
-				float e1[3], e2[3];
+			sub_v3_v3v3(nor_prev, mvert[ml[i_this - 1].v].co, mvert[ml[i_this].v].co);
+			normalize_v3(nor_prev);
+
+			while (i_next < mp->totloop) {
 				float angle;
+				sub_v3_v3v3(nor_next, mvert[ml[i_this].v].co, mvert[ml[i_next].v].co);
+				normalize_v3(nor_next);
+				angle = angle_normalized_v3v3(nor_prev, nor_next);
 
-				/* TODO - we could speed this up by _not_ normalizing both verts each time
-				 * and always re-usingthe last vector. */
-				sub_v3_v3v3(e1, mvert[ml_next->v].co, mvert[ml->v].co);
-				sub_v3_v3v3(e2, mvert[ml_prev->v].co, mvert[ml->v].co);
 
-				angle = (float)M_PI - angle_v3v3(e1, e2);
+				/* --- not related to angle calc --- */
 				if (angle < FLT_EPSILON) {
 					angle = FLT_EPSILON;
 				}
-
-				vidx = ml->v;
+				vidx = ml[i_this].v;
 				vert_accum[vidx] += angle;
 				vert_angles[vidx] += shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle;
+				/* --- end non-angle-calc section --- */
+
+
+				/* step */
+				copy_v3_v3(nor_prev, nor_next);
+				i_this = i_next;
+				i_next++;
 			}
 		}
 




More information about the Bf-blender-cvs mailing list