[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [54560] trunk/blender/source/blender: Fix "Origin to Center of Mass" not working well with ngons

Sergej Reich sergej.reich at googlemail.com
Thu Feb 14 18:35:46 CET 2013


Revision: 54560
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54560
Author:   sergof
Date:     2013-02-14 17:35:46 +0000 (Thu, 14 Feb 2013)
Log Message:
-----------
Fix "Origin to Center of Mass" not working well with ngons

Now we do simple triangulation and calculate signed area of triangles to
account for concave polygons.

This only works correct for planar polygons but gives better results
overall.

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

Modified: trunk/blender/source/blender/blenkernel/intern/mesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/mesh.c	2013-02-14 17:35:43 UTC (rev 54559)
+++ trunk/blender/source/blender/blenkernel/intern/mesh.c	2013-02-14 17:35:46 UTC (rev 54560)
@@ -2999,6 +2999,36 @@
 	}
 }
 
+/* note, results won't be correct if polygon is non-planar */
+static float mesh_calc_poly_planar_area_centroid(MPoly *mpoly, MLoop *loopstart, MVert *mvarray, float cent[3])
+{
+	int i;
+	float tri_area;
+	float total_area = 0.0f;
+	float v1[3], v2[3], v3[3], normal[3], tri_cent[3];
+
+	BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, normal);
+	copy_v3_v3(v1, mvarray[loopstart[0].v].co);
+	copy_v3_v3(v2, mvarray[loopstart[1].v].co);
+	zero_v3(cent);
+
+	for (i = 2; i < mpoly->totloop; i++) {
+		copy_v3_v3(v3, mvarray[loopstart[i].v].co);
+
+		tri_area = area_tri_signed_v3(v1, v2, v3, normal);
+		total_area += tri_area;
+
+		cent_tri_v3(tri_cent, v1, v2, v3);
+		madd_v3_v3fl(cent, tri_cent, tri_area);
+
+		copy_v3_v3(v2, v3);
+	}
+
+	mul_v3_fl(cent, 1.0f / total_area);
+
+	return total_area;
+}
+
 /**
  * This function takes the difference between 2 vertex-coord-arrays
  * (\a vert_cos_src, \a vert_cos_dst),
@@ -3292,9 +3322,8 @@
 	
 	/* calculate a weighted average of polygon centroids */
 	for (mpoly = me->mpoly; i--; mpoly++) {
-		BKE_mesh_calc_poly_center(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent);
-		poly_area = BKE_mesh_calc_poly_area(mpoly, me->mloop + mpoly->loopstart, me->mvert, NULL);
-		
+		poly_area = mesh_calc_poly_planar_area_centroid(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent);
+
 		madd_v3_v3fl(cent, poly_cent, poly_area);
 		total_area += poly_area;
 	}

Modified: trunk/blender/source/blender/blenlib/BLI_math_geom.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_geom.h	2013-02-14 17:35:43 UTC (rev 54559)
+++ trunk/blender/source/blender/blenlib/BLI_math_geom.h	2013-02-14 17:35:46 UTC (rev 54560)
@@ -51,6 +51,7 @@
 float area_tri_v2(const float a[2], const float b[2], const float c[2]);
 float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2]);
 float area_tri_v3(const float a[3], const float b[3], const float c[3]);
+float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3]);
 float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]);
 float area_poly_v3(int nr, float verts[][3], const float normal[3]);
 float area_poly_v2(int nr, float verts[][2]);

Modified: trunk/blender/source/blender/blenlib/intern/math_geom.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_geom.c	2013-02-14 17:35:43 UTC (rev 54559)
+++ trunk/blender/source/blender/blenlib/intern/math_geom.c	2013-02-14 17:35:46 UTC (rev 54560)
@@ -129,6 +129,22 @@
 	return (len / 2.0f);
 }
 
+float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3])
+{
+	float area, vec1[3], vec2[3], n[3];
+
+	sub_v3_v3v3(vec1, v3, v2);
+	sub_v3_v3v3(vec2, v1, v2);
+	cross_v3_v3v3(n, vec1, vec2);
+	area = len_v3(n) / 2.0f;
+
+	/* negate area for flipped triangles */
+	if (dot_v3v3(n, normal) < 0.0f)
+		area = -area;
+
+	return area;
+}
+
 float area_poly_v3(int nr, float verts[][3], const float normal[3])
 {
 	int a, px, py;




More information about the Bf-blender-cvs mailing list