From 6521307dcd5b68137db5fbfed11f2d188d100869 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 13 Mar 2017 03:45:15 +1100 Subject: BMesh: rename cryptic functions Use expanded names for bmesh primitive operations (urmv jvke semv jfke). Use 'bmesh_kernel_' prefix, these functions aren't intended for wide use so favor readability. Remove BM_face_vert_separate, it wasn't used and only skipped step of finding correct loop of face. --- source/blender/bmesh/intern/bmesh_polygon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 6acd790fc0c..78ee7589d23 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -844,7 +844,7 @@ void BM_face_normal_flip_ex( BMesh *bm, BMFace *f, const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip) { - bmesh_loop_reverse(bm, f, cd_loop_mdisp_offset, use_loop_mdisp_flip); + bmesh_kernel_loop_reverse(bm, f, cd_loop_mdisp_offset, use_loop_mdisp_flip); negate_v3(f->no); } -- cgit v1.2.3 From 89120cd2417e2f6f39fa63ae18300bba0aefcfbd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 6 May 2017 14:18:31 +1000 Subject: bmesh: use 'uint' instead of 'unsigned int' no functional changes. --- source/blender/bmesh/intern/bmesh_polygon.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (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 78ee7589d23..a4621b45fe6 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -132,7 +132,7 @@ static void bm_face_calc_poly_center_mean_vertex_cos( */ void BM_face_calc_tessellation( const BMFace *f, const bool use_fixed_quad, - BMLoop **r_loops, unsigned int (*r_index)[3]) + BMLoop **r_loops, uint (*r_index)[3]) { BMLoop *l_first = BM_FACE_FIRST_LOOP(f); BMLoop *l_iter; @@ -196,7 +196,7 @@ void BM_face_calc_point_in_face(const BMFace *f, float r_co[3]) * but without this we can't be sure the point is inside a concave face. */ const int tottri = f->len - 2; BMLoop **loops = BLI_array_alloca(loops, f->len); - unsigned int (*index)[3] = BLI_array_alloca(index, tottri); + uint (*index)[3] = BLI_array_alloca(index, tottri); int j; int j_best = 0; /* use as fallback when unset */ float area_best = -1.0f; @@ -575,11 +575,11 @@ void BM_face_calc_center_mean_weighted(const BMFace *f, float r_cent[3]) * Rotates a polygon so that it's * normal is pointing towards the mesh Z axis */ -void poly_rotate_plane(const float normal[3], float (*verts)[3], const unsigned int nverts) +void poly_rotate_plane(const float normal[3], float (*verts)[3], const uint nverts) { float mat[3][3]; float co[3]; - unsigned int i; + uint i; co[2] = 0.0f; @@ -941,7 +941,7 @@ void BM_face_triangulate( { BMLoop **loops = BLI_array_alloca(loops, f->len); - unsigned int (*tris)[3] = BLI_array_alloca(tris, f->len); + uint (*tris)[3] = BLI_array_alloca(tris, f->len); const int totfilltri = f->len - 2; const int last_tri = f->len - 3; int i; @@ -1425,7 +1425,7 @@ void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptri float axis_mat[3][3]; float (*projverts)[2]; - unsigned int (*tris)[3]; + uint (*tris)[3]; const int totfilltri = efa->len - 2; @@ -1451,7 +1451,7 @@ void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptri for (j = 0; j < totfilltri; j++) { BMLoop **l_ptr = looptris[i++]; - unsigned int *tri = tris[j]; + uint *tri = tris[j]; l_ptr[0] = l_arr[tri[0]]; l_ptr[1] = l_arr[tri[1]]; -- cgit v1.2.3 From 892d304dedb60891d9e0b3091eceecb163644215 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Sep 2017 16:00:27 +1000 Subject: Fix T52291: Boolean fails w/ co-linear edged ngons This means boolean tessellation wont match viewport tessellation however it's needed to avoid zero area triangles causing problems. --- source/blender/bmesh/intern/bmesh_polygon.c | 128 ++++++++++++++++++++++++++++ 1 file changed, 128 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 a4621b45fe6..a839f92b9e9 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -39,6 +39,8 @@ #include "BLI_polyfill2d.h" #include "BLI_polyfill2d_beautify.h" #include "BLI_linklist.h" +#include "BLI_edgehash.h" +#include "BLI_heap.h" #include "bmesh.h" #include "bmesh_tools.h" @@ -1474,3 +1476,129 @@ void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptri #undef USE_TESSFACE_SPEEDUP } + + +/** + * A version of #BM_mesh_calc_tessellation that avoids degenerate triangles. + */ +void BM_mesh_calc_tessellation_beauty(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot) +{ + /* this assumes all faces can be scan-filled, which isn't always true, + * worst case we over alloc a little which is acceptable */ +#ifndef NDEBUG + const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop); +#endif + + BMIter iter; + BMFace *efa; + int i = 0; + + MemArena *pf_arena = NULL; + + /* use_beauty */ + Heap *pf_heap = NULL; + EdgeHash *pf_ehash = NULL; + + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + /* don't consider two-edged faces */ + if (UNLIKELY(efa->len < 3)) { + /* do nothing */ + } + else if (efa->len == 3) { + BMLoop *l; + BMLoop **l_ptr = looptris[i++]; + l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa); + l_ptr[1] = l = l->next; + l_ptr[2] = l->next; + } + else if (efa->len == 4) { + BMLoop *l_v1 = BM_FACE_FIRST_LOOP(efa); + BMLoop *l_v2 = l_v1->next; + BMLoop *l_v3 = l_v2->next; + BMLoop *l_v4 = l_v1->prev; + + const bool split_24 = (BM_verts_calc_rotate_beauty(l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) > 0.0f); + + BMLoop **l_ptr_a = looptris[i++]; + BMLoop **l_ptr_b = looptris[i++]; + if (split_24 == 0) { + l_ptr_a[0] = l_v1; + l_ptr_a[1] = l_v2; + l_ptr_a[2] = l_v3; + + l_ptr_b[0] = l_v1; + l_ptr_b[1] = l_v3; + l_ptr_b[2] = l_v4; + } + else { + l_ptr_a[0] = l_v1; + l_ptr_a[1] = l_v2; + l_ptr_a[2] = l_v4; + + l_ptr_b[0] = l_v2; + l_ptr_b[1] = l_v3; + l_ptr_b[2] = l_v4; + } + } + else { + int j; + + BMLoop *l_iter; + BMLoop *l_first; + BMLoop **l_arr; + + float axis_mat[3][3]; + float (*projverts)[2]; + unsigned int (*tris)[3]; + + const int totfilltri = efa->len - 2; + + if (UNLIKELY(pf_arena == NULL)) { + pf_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + pf_heap = BLI_heap_new_ex(BLI_POLYFILL_ALLOC_NGON_RESERVE); + pf_ehash = BLI_edgehash_new_ex(__func__, BLI_POLYFILL_ALLOC_NGON_RESERVE); + } + + tris = BLI_memarena_alloc(pf_arena, sizeof(*tris) * totfilltri); + l_arr = BLI_memarena_alloc(pf_arena, sizeof(*l_arr) * efa->len); + projverts = BLI_memarena_alloc(pf_arena, sizeof(*projverts) * efa->len); + + axis_dominant_v3_to_m3_negate(axis_mat, efa->no); + + j = 0; + l_iter = l_first = BM_FACE_FIRST_LOOP(efa); + do { + l_arr[j] = l_iter; + mul_v2_m3v3(projverts[j], axis_mat, l_iter->v->co); + j++; + } while ((l_iter = l_iter->next) != l_first); + + BLI_polyfill_calc_arena((const float (*)[2])projverts, efa->len, 1, tris, pf_arena); + + BLI_polyfill_beautify((const float (*)[2])projverts, efa->len, tris, pf_arena, pf_heap, pf_ehash); + + for (j = 0; j < totfilltri; j++) { + BMLoop **l_ptr = looptris[i++]; + unsigned int *tri = tris[j]; + + l_ptr[0] = l_arr[tri[0]]; + l_ptr[1] = l_arr[tri[1]]; + l_ptr[2] = l_arr[tri[2]]; + } + + BLI_memarena_clear(pf_arena); + } + } + + if (pf_arena) { + BLI_memarena_free(pf_arena); + + BLI_heap_free(pf_heap, NULL); + BLI_edgehash_free(pf_ehash, NULL); + } + + *r_looptris_tot = i; + + BLI_assert(i <= looptris_tot); + +} -- cgit v1.2.3 From fdb8e17936a0abfbb61b71ae9a0061405ab7e2c4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Sep 2017 18:07:00 +1000 Subject: Fix error in recent boolean changes w/ quad split --- source/blender/bmesh/intern/bmesh_polygon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 a839f92b9e9..316123159a7 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -1517,7 +1517,7 @@ void BM_mesh_calc_tessellation_beauty(BMesh *bm, BMLoop *(*looptris)[3], int *r_ BMLoop *l_v3 = l_v2->next; BMLoop *l_v4 = l_v1->prev; - const bool split_24 = (BM_verts_calc_rotate_beauty(l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) > 0.0f); + const bool split_24 = (BM_verts_calc_rotate_beauty(l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) < 0.0f); BMLoop **l_ptr_a = looptris[i++]; BMLoop **l_ptr_b = looptris[i++]; -- cgit v1.2.3 From d120780fed34b66cc4830afa79c1b5fe9ac006b7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 15 Sep 2017 18:19:04 +1000 Subject: BMesh: use less involved check for edge rotation Was using function for edge rotation which was doing unnecessary checks Use the face normal and BLI_polyfill_beautify_quad_rotate_calc directly. --- source/blender/bmesh/intern/bmesh_polygon.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (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 316123159a7..f0023470099 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -1517,7 +1517,25 @@ void BM_mesh_calc_tessellation_beauty(BMesh *bm, BMLoop *(*looptris)[3], int *r_ BMLoop *l_v3 = l_v2->next; BMLoop *l_v4 = l_v1->prev; - const bool split_24 = (BM_verts_calc_rotate_beauty(l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) < 0.0f); + /* #BM_verts_calc_rotate_beauty performs excessive checks we don't need! + * It's meant for rotating edges, it also calculates a new normal. + * + * Use #BLI_polyfill_beautify_quad_rotate_calc since we have the normal. + */ +#if 0 + const bool split_24 = (BM_verts_calc_rotate_beauty( + l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) < 0.0f); +#else + float axis_mat[3][3], v_quad[4][2]; + axis_dominant_v3_to_m3(axis_mat, efa->no); + mul_v2_m3v3(v_quad[0], axis_mat, l_v1->v->co); + mul_v2_m3v3(v_quad[1], axis_mat, l_v2->v->co); + mul_v2_m3v3(v_quad[2], axis_mat, l_v3->v->co); + mul_v2_m3v3(v_quad[3], axis_mat, l_v4->v->co); + + const bool split_24 = BLI_polyfill_beautify_quad_rotate_calc( + v_quad[0], v_quad[1], v_quad[2], v_quad[3]) < 0.0f; +#endif BMLoop **l_ptr_a = looptris[i++]; BMLoop **l_ptr_b = looptris[i++]; -- cgit v1.2.3 From 9a2f7dd77b38504d77b1b058072194496fdc91c9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 19 Sep 2017 14:25:37 +1000 Subject: Correct recent error in boolean quad split check --- source/blender/bmesh/intern/bmesh_polygon.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (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 f0023470099..7b9d17b27b5 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -1523,7 +1523,7 @@ void BM_mesh_calc_tessellation_beauty(BMesh *bm, BMLoop *(*looptris)[3], int *r_ * Use #BLI_polyfill_beautify_quad_rotate_calc since we have the normal. */ #if 0 - const bool split_24 = (BM_verts_calc_rotate_beauty( + const bool split_13 = (BM_verts_calc_rotate_beauty( l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) < 0.0f); #else float axis_mat[3][3], v_quad[4][2]; @@ -1533,13 +1533,13 @@ void BM_mesh_calc_tessellation_beauty(BMesh *bm, BMLoop *(*looptris)[3], int *r_ mul_v2_m3v3(v_quad[2], axis_mat, l_v3->v->co); mul_v2_m3v3(v_quad[3], axis_mat, l_v4->v->co); - const bool split_24 = BLI_polyfill_beautify_quad_rotate_calc( + const bool split_13 = BLI_polyfill_beautify_quad_rotate_calc( v_quad[0], v_quad[1], v_quad[2], v_quad[3]) < 0.0f; #endif BMLoop **l_ptr_a = looptris[i++]; BMLoop **l_ptr_b = looptris[i++]; - if (split_24 == 0) { + if (split_13) { l_ptr_a[0] = l_v1; l_ptr_a[1] = l_v2; l_ptr_a[2] = l_v3; -- cgit v1.2.3