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:
authorHabib Gahbiche <habibgahbiche@gmail.com>2018-11-09 22:03:41 +0300
committerDalai Felinto <dfelinto@gmail.com>2018-11-09 22:19:04 +0300
commit0c1934f3c2d3dff3bce65e2e8169866bafea04e0 (patch)
tree4b5e8baf24fe1946bcf6eb1ce76286025e8eb67d /source/blender/bmesh
parentdc346c05fe32c7d90be261a2e970ef976b13c1fc (diff)
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
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c48
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h3
-rw-r--r--source/blender/bmesh/intern/bmesh_query.c40
-rw-r--r--source/blender/bmesh/intern/bmesh_query.h4
4 files changed, 95 insertions, 0 deletions
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"
@@ -240,6 +241,30 @@ 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)
+{
+ /* 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
*/
float BM_face_calc_perimeter(const BMFace *f)
@@ -256,6 +281,29 @@ 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)
+{
+ 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.
*
* \return The first edge index, where the second vertex is ``(index + 1) % 3``.
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index a40da2bfbfa..29bb49a8e40 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -28,6 +28,7 @@
*/
struct Heap;
+struct Object;
#include "BLI_compiler_attrs.h"
@@ -44,7 +45,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_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();
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 540888ac0b9..c51c6322136 100644
--- a/source/blender/bmesh/intern/bmesh_query.c
+++ b/source/blender/bmesh/intern/bmesh_query.c
@@ -31,6 +31,8 @@
* of inspecting the mesh structure directly.
*/
+#include "DNA_object_types.h"
+
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
@@ -39,6 +41,7 @@
#include "BLI_utildefines_stack.h"
#include "BKE_customdata.h"
+#include "BKE_object.h"
#include "bmesh.h"
#include "intern/bmesh_private.h"
@@ -1678,6 +1681,43 @@ float BM_edge_calc_face_angle(const BMEdge *e)
}
/**
+* \brief BMESH EDGE/FACE ANGLE
+*
+* Calculates the angle between two faces in world space.
+* Assumes the face normals are correct.
+*
+* \return angle in radians
+*/
+float BM_edge_calc_face_angle_worldspace_ex(Object *ob, const BMEdge *e, const float fallback)
+{
+ if (BM_edge_is_manifold(e)) {
+ const BMLoop *l1 = e->l;
+ const BMLoop *l2 = e->l->radial_next;
+ float no1[3], no2[3];
+ 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_m3_v3(smat, no1);
+ mul_m3_v3(smat, no2);
+ normalize_v3(no1);
+ normalize_v3(no2);
+
+ return angle_normalized_v3v3(no1, no2);
+ }
+ else {
+ return fallback;
+ }
+}
+float BM_edge_calc_face_angle_worldspace(Object *ob, const BMEdge *e)
+{
+ return BM_edge_calc_face_angle_worldspace_ex(ob, e, DEG2RADF(90.0f));
+}
+
+/**
* \brief BMESH EDGE/FACE ANGLE
*
* Calculates the angle between two faces.
diff --git a/source/blender/bmesh/intern/bmesh_query.h b/source/blender/bmesh/intern/bmesh_query.h
index 51956761d8f..1cfd6cc07a3 100644
--- a/source/blender/bmesh/intern/bmesh_query.h
+++ b/source/blender/bmesh/intern/bmesh_query.h
@@ -27,6 +27,8 @@
* \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();
@@ -123,6 +125,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_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();