[Bf-blender-cvs] [9d85e32] master: BMesh: calc normals, use area weighted center
Campbell Barton
noreply at git.blender.org
Mon Mar 2 05:57:02 CET 2015
Commit: 9d85e32ee3201654ec15e994b023650fd1834d29
Author: Campbell Barton
Date: Mon Mar 2 13:04:46 2015 +1100
Branches: master
https://developer.blender.org/rB9d85e32ee3201654ec15e994b023650fd1834d29
BMesh: calc normals, use area weighted center
Prevents many small faces skewing center calculation.
===================================================================
M source/blender/bmesh/operators/bmo_normals.c
===================================================================
diff --git a/source/blender/bmesh/operators/bmo_normals.c b/source/blender/bmesh/operators/bmo_normals.c
index d0f0887..ed49d07 100644
--- a/source/blender/bmesh/operators/bmo_normals.c
+++ b/source/blender/bmesh/operators/bmo_normals.c
@@ -59,10 +59,12 @@ static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int f
{
float cent[3], tvec[3];
float (*faces_center)[3] = MEM_mallocN(sizeof(*faces_center) * faces_len, __func__);
+ float *faces_area = MEM_mallocN(sizeof(*faces_area) * faces_len, __func__);
const float cent_fac = 1.0f / (float)faces_len;
int i, f_start_index;
const short oflag_flip = oflag | FACE_FLIP;
+ float cent_area_accum = 0.0f;
float f_len_best_sq;
BMFace *f;
@@ -73,13 +75,20 @@ static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int f
/* first calculate the center */
for (i = 0; i < faces_len; i++) {
float *f_cent = faces_center[i];
+ const float f_area = BM_face_calc_area(faces[i]);
BM_face_calc_center_mean_weighted(faces[i], f_cent);
- madd_v3_v3fl(cent, f_cent, cent_fac);
+ madd_v3_v3fl(cent, f_cent, cent_fac * f_area);
+ cent_area_accum += f_area;
+ faces_area[i] = f_area;
BLI_assert(BMO_elem_flag_test(bm, faces[i], FACE_TEMP) == 0);
BLI_assert(BM_face_is_normal_valid(faces[i]));
}
+ if (cent_area_accum != 0.0f) {
+ mul_v3_fl(cent, 1.0f / cent_area_accum);
+ }
+
f_len_best_sq = -FLT_MAX;
/* used in degenerate cases only */
f_start_index = 0;
@@ -87,20 +96,24 @@ static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int f
for (i = 0; i < faces_len; i++) {
float f_len_test_sq;
- if ((f_len_test_sq = len_squared_v3v3(faces_center[i], cent)) > f_len_best_sq) {
- f_len_best_sq = f_len_test_sq;
- f_start_index = i;
+ if (faces_area[i] > FLT_EPSILON) {
+ if ((f_len_test_sq = len_squared_v3v3(faces_center[i], cent)) > f_len_best_sq) {
+ f_len_best_sq = f_len_test_sq;
+ f_start_index = i;
+ }
}
}
+
/* make sure the starting face has the correct winding */
sub_v3_v3v3(tvec, faces_center[f_start_index], cent);
+ MEM_freeN(faces_center);
+ MEM_freeN(faces_area);
+
if (dot_v3v3(tvec, faces[f_start_index]->no) < 0.0f) {
BMO_elem_flag_enable(bm, faces[f_start_index], FACE_FLIP);
}
- MEM_freeN(faces_center);
-
/* now that we've found our starting face, make all connected faces
* have the same winding. this is done recursively, using a manual
* stack (if we use simple function recursion, we'd end up overloading
More information about the Bf-blender-cvs
mailing list