Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergej Reich <sergej.reich@googlemail.com>2013-02-14 21:35:46 +0400
committerSergej Reich <sergej.reich@googlemail.com>2013-02-14 21:35:46 +0400
commit10305de3ac27ec7d247120a62d5ef7508e7a165e (patch)
tree6ee060b677aa28ad84ddc66a6afaef4fffe54306 /source/blender
parente3944f5bfaffebe0f55df47db76515dd0ac7426b (diff)
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/mesh.c35
-rw-r--r--source/blender/blenlib/BLI_math_geom.h1
-rw-r--r--source/blender/blenlib/intern/math_geom.c16
3 files changed, 49 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 21641e77b0b..c9c86e6739f 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -2999,6 +2999,36 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
}
}
+/* 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 @@ int BKE_mesh_center_centroid(Mesh *me, float cent[3])
/* 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;
}
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index a822bdb9414..c4e17b1ed48 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -51,6 +51,7 @@ float normal_quad_v3(float r[3], const float a[3], const float b[3], const float
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]);
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 7337718bd3c..810c15437dc 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -129,6 +129,22 @@ float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
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;