From 0c1934f3c2d3dff3bce65e2e8169866bafea04e0 Mon Sep 17 00:00:00 2001 From: Habib Gahbiche Date: Fri, 9 Nov 2018 17:03:41 -0200 Subject: Multi-Objects: MESH_OT_select_similar worldspace completion This makes the operator to work 100% with worldspace similarity: * SIMFACE_PERIMETER * SIMFACE_AREA * SIMEDGE_FACE_ANGLE Note from revisor (Dalai Felinto): I'm not sure we want to pass Object * to the bmesh api, though I personally don't see why not. Either way I group the patches together so we can more easily roll them back if needs be. Maniphest Tasks: T56948 Differential Revision: D3908, D3899, D3896 --- source/blender/bmesh/intern/bmesh_polygon.c | 48 +++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'source/blender/bmesh/intern/bmesh_polygon.c') diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 8c96c938cef..8374fd8f51f 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -30,6 +30,7 @@ #include "DNA_listBase.h" #include "DNA_modifier_types.h" +#include "DNA_object_types.h" #include "MEM_guardedalloc.h" @@ -239,6 +240,30 @@ float BM_face_calc_area(const BMFace *f) return len_v3(n) * 0.5f; } +/** + * Get the area of the face in world space. + */ +float BM_face_calc_area_worldspace(Object *ob, const BMFace *f) +{ + /* inline 'area_poly_v3' logic, avoid creating a temp array */ + const BMLoop *l_iter, *l_first; + 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); + 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); + add_newell_cross_v3_v3v3(n, co, co_next); + } while ((l_iter = l_iter->next) != l_first); + return len_v3(n) * 0.5f; +} + /** * compute the perimeter of an ngon */ @@ -255,6 +280,29 @@ float BM_face_calc_perimeter(const BMFace *f) return perimeter; } +/** + * Calculate the perimeter of a ngon in world space. + */ +float BM_face_calc_perimeter_worldspace(Object *ob, const BMFace *f) +{ + const BMLoop *l_iter, *l_first; + float perimeter = 0.0f; + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + float rsmat[3][3]; + copy_m3_m4(rsmat, ob->obmat); + 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); + perimeter += len_v3v3(co, co_next); + } while ((l_iter = l_iter->next) != l_first); + + return perimeter; +} + /** * Utility function to calculate the edge which is most different from the other two. * -- cgit v1.2.3