Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Wed, 12 Jul 2017 13:18:11 +0000 (23:18 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 12 Jul 2017 13:18:11 +0000 (23:18 +1000)
source/blender/blenkernel/intern/editderivedmesh.c
source/blender/bmesh/intern/bmesh_queries.c
source/blender/bmesh/intern/bmesh_queries.h

index c8ae35980978e0e0cc365c85fdfe46d2e68c81f1..baf91b638b9239c7dc38cf00467daa0b33c1e453 100644 (file)
@@ -2018,7 +2018,7 @@ static void statvis_calc_distort(
                                                      vertexCos[BM_elem_index_get(l_iter->next->v)]);
                                }
                                else {
-                                       BM_loop_calc_face_normal(l_iter, no_corner);
+                                       BM_loop_calc_face_normal_safe(l_iter, no_corner);
                                }
                                /* simple way to detect (what is most likely) concave */
                                if (dot_v3v3(f_no, no_corner) < 0.0f) {
index f5c14304ea33275f43f8fdf2459c06b84ef90029..5e8ae696db2a132835136ff809052f9395385f90 100644 (file)
@@ -1511,12 +1511,11 @@ float BM_loop_calc_face_angle(const BMLoop *l)
  * Calculate the normal at this loop corner or fallback to the face normal on straight lines.
  *
  * \param l The loop to calculate the normal at
+ * \param epsilon: Value to avoid numeric errors (1e-5f works well).
  * \param r_normal Resulting normal
  */
-void BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3])
+float BM_loop_calc_face_normal_safe_ex(const BMLoop *l, float epsilon_sq, float r_normal[3])
 {
-#define FEPSILON 1e-5f
-
        /* Note: we cannot use result of normal_tri_v3 here to detect colinear vectors (vertex on a straight line)
         * from zero value, because it does not normalize both vectors before making crossproduct.
         * Instead of adding two costly normalize computations, just check ourselves for colinear case. */
@@ -1525,20 +1524,55 @@ void BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3])
        sub_v3_v3v3(v1, l->prev->v->co, l->v->co);
        sub_v3_v3v3(v2, l->next->v->co, l->v->co);
 
-       const float fac = (v2[0] == 0.0f) ? ((v2[1] == 0.0f) ? ((v2[2] == 0.0f) ? 0.0f : v1[2] / v2[2]) : v1[1] / v2[1]) : v1[0] / v2[0];
+       const float fac =
+               ((v2[0] == 0.0f) ?
+               ((v2[1] == 0.0f) ?
+               ((v2[2] == 0.0f) ?  0.0f : v1[2] / v2[2]) : v1[1] / v2[1]) : v1[0] / v2[0]);
 
        mul_v3_v3fl(v_tmp, v2, fac);
        sub_v3_v3(v_tmp, v1);
-       if (fac != 0.0f && !is_zero_v3(v1) && len_manhattan_v3(v_tmp) > FEPSILON) {
+       if (fac != 0.0f && !is_zero_v3(v1) && len_squared_v3(v_tmp) > epsilon_sq) {
                /* Not co-linear, we can compute crossproduct and normalize it into normal. */
                cross_v3_v3v3(r_normal, v1, v2);
-               normalize_v3(r_normal);
+               return normalize_v3(r_normal);
        }
        else {
                copy_v3_v3(r_normal, l->f->no);
+               return 0.0f;
        }
+}
+
+/**
+ * #BM_loop_calc_face_normal_safe_ex with pre-defined sane epsilon.
+ *
+ * Since this doesn't scale baed on triangle size, fixed value works well.
+ */
+float BM_loop_calc_face_normal_safe(const BMLoop *l, float r_normal[3])
+{
+       return BM_loop_calc_face_normal_safe_ex(l, 1e-5f, r_normal);
+}
 
-#undef FEPSILON
+/**
+ * \brief BM_loop_calc_face_normal
+ *
+ * Calculate the normal at this loop corner or fallback to the face normal on straight lines.
+ *
+ * \param l The loop to calculate the normal at
+ * \param r_normal Resulting normal
+ * \return The length of the cross product (double the area).
+ */
+float BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3])
+{
+       float v1[3], v2[3];
+       sub_v3_v3v3(v1, l->prev->v->co, l->v->co);
+       sub_v3_v3v3(v2, l->next->v->co, l->v->co);
+
+       cross_v3_v3v3(r_normal, v1, v2);
+       const float len = normalize_v3(r_normal);
+       if (UNLIKELY(len == 0.0f)) {
+               copy_v3_v3(r_normal, l->f->no);
+       }
+       return len;
 }
 
 /**
index 903fdc59cb8d6b1406d6da64ba21efecf5973b24..83977fa8be03138e4dbc3668a353ff5e2d0e549c 100644 (file)
@@ -113,7 +113,9 @@ BMLoop *BM_loop_find_prev_nodouble(BMLoop *l, BMLoop *l_stop, const float eps_sq
 BMLoop *BM_loop_find_next_nodouble(BMLoop *l, BMLoop *l_stop, const float eps_sq);
 
 float   BM_loop_calc_face_angle(const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void    BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3]) ATTR_NONNULL();
+float   BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3]) ATTR_NONNULL();
+float   BM_loop_calc_face_normal_safe(const BMLoop *l, float r_normal[3]) ATTR_NONNULL();
+float   BM_loop_calc_face_normal_safe_ex(const BMLoop *l, const float epsilon, float r_normal[3]) ATTR_NONNULL();
 void    BM_loop_calc_face_direction(const BMLoop *l, float r_normal[3]);
 void    BM_loop_calc_face_tangent(const BMLoop *l, float r_tangent[3]);