Commit: 0feeea1bd5fa6833bb9fc300db7b715ae5d94148
Author: Campbell Barton
Date:   Sat Nov 10 18:52:14 2018 +1100
Branches: blender2.8
https://developer.blender.org/rB0feeea1bd5fa6833bb9fc300db7b715ae5d94148

BMesh: avoid incorrect/invalid matrix calculation

- `BKE_object_scale_to_mat3` was used to get the worldspace scale,
  without taking constraints, parenting etc into account.
- Don't pass object's into BMesh API, (prefer matrices instead).
- Avoid matrix invert for each edge-angle calculation.
- Avoid 2x matrix multiplies when looping over edge pairs.

===================================================================

M       source/blender/bmesh/intern/bmesh_polygon.c
M       source/blender/bmesh/intern/bmesh_polygon.h
M       source/blender/bmesh/intern/bmesh_query.c
M       source/blender/bmesh/intern/bmesh_query.h
M       source/blender/editors/mesh/editmesh_select_similar.c

===================================================================

diff --git a/source/blender/bmesh/intern/bmesh_polygon.c 
b/source/blender/bmesh/intern/bmesh_polygon.c
index 8374fd8f51f..9baae8e8a93 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -30,7 +30,6 @@
 
 #include "DNA_listBase.h"
 #include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -243,23 +242,21 @@ float BM_face_calc_area(const BMFace *f)
 /**
  * Get the area of the face in world space.
  */
-float BM_face_calc_area_worldspace(Object *ob, const BMFace *f)
+float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3])
 {
        /* inline 'area_poly_v3' logic, avoid creating a temp array */
        const BMLoop *l_iter, *l_first;
+       float co[3];
        float n[3];
 
        zero_v3(n);
        l_iter = l_first = BM_FACE_FIRST_LOOP(f);
-       float rsmat[3][3];
-       copy_m3_m4(rsmat, ob->obmat);
+       mul_v3_m3v3(co, mat3, l_iter->v->co);
        do {
-               float co[3], co_next[3];
-               copy_v3_v3(co, l_iter->v->co);
-               copy_v3_v3(co_next, l_iter->next->v->co);
-               mul_m3_v3(rsmat, co);
-               mul_m3_v3(rsmat, co_next);
+               float co_next[3];
+               mul_v3_m3v3(co_next, mat3, l_iter->next->v->co);
                add_newell_cross_v3_v3v3(n, co, co_next);
+               copy_v3_v3(co, co_next);
        } while ((l_iter = l_iter->next) != l_first);
        return len_v3(n) * 0.5f;
 }
@@ -283,21 +280,19 @@ float BM_face_calc_perimeter(const BMFace *f)
 /**
  * Calculate the perimeter of a ngon in world space.
  */
-float BM_face_calc_perimeter_worldspace(Object *ob, const BMFace *f)
+float BM_face_calc_perimeter_with_mat3(const BMFace *f, const float mat3[3][3])
 {
        const BMLoop *l_iter, *l_first;
+       float co[3];
        float perimeter = 0.0f;
 
        l_iter = l_first = BM_FACE_FIRST_LOOP(f);
-       float rsmat[3][3];
-       copy_m3_m4(rsmat, ob->obmat);
+       mul_v3_m3v3(co, mat3, l_iter->v->co);
        do {
-               float co[3], co_next[3];
-               copy_v3_v3(co, l_iter->v->co);
-               copy_v3_v3(co_next, l_iter->next->v->co);
-               mul_m3_v3(rsmat, co);
-               mul_m3_v3(rsmat, co_next);
+               float co_next[3];
+               mul_v3_m3v3(co_next, mat3, l_iter->next->v->co);
                perimeter += len_v3v3(co, co_next);
+               copy_v3_v3(co, co_next);
        } while ((l_iter = l_iter->next) != l_first);
 
        return perimeter;
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h 
b/source/blender/bmesh/intern/bmesh_polygon.h
index 29bb49a8e40..2edfdaa8c03 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -28,7 +28,6 @@
  */
 
 struct Heap;
-struct Object;
 
 #include "BLI_compiler_attrs.h"
 
@@ -45,9 +44,9 @@ float BM_face_calc_normal_vcos(
         float const (*vertexCos)[3]) ATTR_NONNULL();
 float BM_face_calc_normal_subset(const BMLoop *l_first, const BMLoop *l_last, 
float r_no[3]) ATTR_NONNULL();
 float BM_face_calc_area(const BMFace *f) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL();
-float BM_face_calc_area_worldspace(struct Object *ob, const BMFace *f) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3]) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 float BM_face_calc_perimeter(const BMFace *f) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL();
-float BM_face_calc_perimeter_worldspace(struct Object *ob, const BMFace *f) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_face_calc_perimeter_with_mat3(const BMFace *f, const float 
mat3[3][3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 void  BM_face_calc_tangent_edge(const BMFace *f, float r_plane[3]) 
ATTR_NONNULL();
 void  BM_face_calc_tangent_edge_pair(const BMFace *f, float r_plane[3]) 
ATTR_NONNULL();
 void  BM_face_calc_tangent_edge_diagonal(const BMFace *f, float r_plane[3]) 
ATTR_NONNULL();
diff --git a/source/blender/bmesh/intern/bmesh_query.c 
b/source/blender/bmesh/intern/bmesh_query.c
index c51c6322136..59711670334 100644
--- a/source/blender/bmesh/intern/bmesh_query.c
+++ b/source/blender/bmesh/intern/bmesh_query.c
@@ -31,8 +31,6 @@
  * of inspecting the mesh structure directly.
  */
 
-#include "DNA_object_types.h"
-
 #include "MEM_guardedalloc.h"
 
 #include "BLI_math.h"
@@ -41,7 +39,6 @@
 #include "BLI_utildefines_stack.h"
 
 #include "BKE_customdata.h"
-#include "BKE_object.h"
 
 #include "bmesh.h"
 #include "intern/bmesh_private.h"
@@ -1688,7 +1685,7 @@ float BM_edge_calc_face_angle(const BMEdge *e)
 *
 * \return angle in radians
 */
-float BM_edge_calc_face_angle_worldspace_ex(Object *ob, const BMEdge *e, const 
float fallback)
+float BM_edge_calc_face_angle_with_imat3_ex(const BMEdge *e, const float 
imat3[3][3], const float fallback)
 {
        if (BM_edge_is_manifold(e)) {
                const BMLoop *l1 = e->l;
@@ -1697,12 +1694,9 @@ float BM_edge_calc_face_angle_worldspace_ex(Object *ob, 
const BMEdge *e, const f
                copy_v3_v3(no1, l1->f->no);
                copy_v3_v3(no2, l2->f->no);
 
-               float smat[3][3];
-               BKE_object_scale_to_mat3(ob, smat);
-               invert_m3(smat);
+               mul_transposed_m3_v3(imat3, no1);
+               mul_transposed_m3_v3(imat3, no2);
 
-               mul_m3_v3(smat, no1);
-               mul_m3_v3(smat, no2);
                normalize_v3(no1);
                normalize_v3(no2);
 
@@ -1712,9 +1706,9 @@ float BM_edge_calc_face_angle_worldspace_ex(Object *ob, 
const BMEdge *e, const f
                return fallback;
        }
 }
-float BM_edge_calc_face_angle_worldspace(Object *ob, const BMEdge *e)
+float BM_edge_calc_face_angle_with_imat3(const BMEdge *e, const float 
imat3[3][3])
 {
-       return BM_edge_calc_face_angle_worldspace_ex(ob, e, DEG2RADF(90.0f));
+       return BM_edge_calc_face_angle_with_imat3_ex(e, imat3, DEG2RADF(90.0f));
 }
 
 /**
diff --git a/source/blender/bmesh/intern/bmesh_query.h 
b/source/blender/bmesh/intern/bmesh_query.h
index 1cfd6cc07a3..7c087a5150f 100644
--- a/source/blender/bmesh/intern/bmesh_query.h
+++ b/source/blender/bmesh/intern/bmesh_query.h
@@ -27,8 +27,6 @@
  *  \ingroup bmesh
  */
 
-struct Object;
-
 bool    BM_vert_in_face(BMVert *v, BMFace *f) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL();
 int     BM_verts_in_face_count(BMVert **varr, int len, BMFace *f) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 bool    BM_verts_in_face(BMVert **varr, int len, BMFace *f) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -125,8 +123,8 @@ void    BM_loop_calc_face_tangent(const BMLoop *l, float 
r_tangent[3]);
 float   BM_edge_calc_face_angle_ex(const BMEdge *e, const float fallback) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 float   BM_edge_calc_face_angle(const BMEdge *e) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL();
 float   BM_edge_calc_face_angle_signed_ex(const BMEdge *e, const float 
fallback) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float   BM_edge_calc_face_angle_worldspace_ex(struct Object *ob, const BMEdge 
*e, const float fallback) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float   BM_edge_calc_face_angle_worldspace(struct Object *ob, const BMEdge *e) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float   BM_edge_calc_face_angle_with_imat3_ex(const BMEdge *e, const float 
imat3[3][3], const float fallback) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float   BM_edge_calc_face_angle_with_imat3(const BMEdge *e, const float 
imat3[3][3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 float   BM_edge_calc_face_angle_signed(const BMEdge *e) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 void    BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float 
r_tangent[3]) ATTR_NONNULL();
 
diff --git a/source/blender/editors/mesh/editmesh_select_similar.c 
b/source/blender/editors/mesh/editmesh_select_similar.c
index 85b59cb78c3..1124b58e116 100644
--- a/source/blender/editors/mesh/editmesh_select_similar.c
+++ b/source/blender/editors/mesh/editmesh_select_similar.c
@@ -245,6 +245,9 @@ static int similar_face_select_exec(bContext *C, wmOperator 
*op)
                        continue;
                }
 
+               float ob_m3[3][3];
+               copy_m3_m4(ob_m3, ob->obmat);
+
                switch (type) {
                        case SIMFACE_MATERIAL:
                        {
@@ -293,14 +296,14 @@ static int similar_face_select_exec(bContext *C, 
wmOperator *op)
                                        }
                                        case SIMFACE_AREA:
                                        {
-                                               float area = 
BM_face_calc_area_worldspace(ob, face);
+                                               float area = 
BM_face_calc_area_with_mat3(face, ob_m3);
                                                float dummy[3] = {area, 0.0f, 
0.0f};
                                                BLI_kdtree_insert(tree, 
tree_index++, dummy);
                                                break;
                                        }
                                        case SIMFACE_PERIMETER:
                                        {
-                                               float perimeter = 
BM_face_calc_perimeter_worldspace(ob, face);
+                                               float perimeter = 
BM_face_calc_perimeter_with_mat3(face, ob_m3);
                                                float dummy[3] = {perimeter, 
0.0f, 0.0f};
                                                BLI_kdtree_insert(tree, 
tree_index++, dummy);
                                                break;
@@ -371,6 +374,9 @@ static int similar_face_select_exec(bContext *C, wmOperator 
*op)
                Material ***material_array = NULL;
                int custom_data_offset;
 
+               float ob_m3[3][3];
+               copy_m3_m4(ob_m3, ob->obmat);
+
                bool has_custom_data_layer = false;
                switch (type) {
                        case SIMFACE_MATERIAL:
@@ -440,7 +446,7 @@ static int similar_face_select_exec(bContext *C, wmOperator 
*op)
                                        }
                                        case SIMFACE_AREA:
                                        {
-                                               float area = 
BM_face_calc_area_worldspace(ob, face);
+                                               float area = 
BM_face_calc_area_with_mat3(face, ob_m3);
                                                if 
(ED_select_similar_compare_float_tree(tree, area, thresh, compare)) {
                                                        select = true;
                                                }
@@ -448,7 +454,7 @@ static int similar_face_select_exec(bContext *C, wmOperator 
*op)
                                        }
                                        case SIMFACE_PERIMETER:
                                        {
-                                               float perimeter = 
BM_face_calc_perimeter_worldspace(ob, face);
+                                               float perimeter = 
BM_face_calc_perimeter_with_mat3(face, ob_m3);
                                                if 
(ED_select_similar_compare_float_tree(tree, perimeter, thresh, compare)) {
                                                        select = true;
                                                }
@@ -748,6 +754,10 @@ static int similar_edge_select_exec(bContext *C, 
wmOperator *op)
                        }
                }
 
+               float ob_m3[3][3], ob_m3_inv[3][3];
+               copy_m3_m4(ob_m3, ob->obmat);
+               invert_m3_m3(ob_m3_inv, ob_m3);
+
                BMEdge *edge; /* Mesh edge. */
                BMIter iter; /* Selected edges iterator. */
 
@@ -774,7 +784,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator 
*op)
                                        case SIMEDGE_FACE_ANGLE:
                                        {
                                                if 
(BM_edge_face_count_at_most(edge, 2) == 2) {
-                                                       float angle = 
BM_edge_calc_face_angle_worldspace(ob, edge);
+                                                       float angle = 
BM_edge_calc_face_angle_with_imat3(edge, ob_m3_inv);
                                                        float dummy[3] = 
{angle, 0.0f, 0.0f};
                                                        BLI_kdtree_insert(tree, 
tree_index++, dummy);
                                                }
@@ -855,6 +865,10 @@ static int similar_edge_select_exec(bContext *C, 
wmOperator *op)
                        }
                }
 
+               fl

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to