diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2018-04-15 13:16:55 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2018-04-15 13:16:55 +0300 |
commit | 7e1832c8d546ec13e752b7bd42ce13e3fc10ae86 (patch) | |
tree | 0fff9d878db69b288f909ff9a0f8aefe31ab8d80 /source/blender/bmesh | |
parent | c0c8df3f2cf3ab03cec1f660619b0fe2290caf2a (diff) | |
parent | 94959dba1b53640e2a36cf9b5ca46aaf49c5c74a (diff) |
Merge branch 'blender2.8' into hair_guides
Diffstat (limited to 'source/blender/bmesh')
38 files changed, 790 insertions, 367 deletions
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 36b2f9cadf7..7e35866887d 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -685,7 +685,7 @@ int bmesh_elem_check(void *element, const char htype) err |= IS_FACE_LOOP_WRONG_RADIAL_LENGTH; } - if (bmesh_disk_count_ex(l_iter->v, 2) < 2) { + if (bmesh_disk_count_at_most(l_iter->v, 2) < 2) { err |= IS_FACE_LOOP_WRONG_DISK_LENGTH; } } @@ -1282,8 +1282,8 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del) } /* create region face */ - f_new = BLI_array_count(edges) ? - BM_face_create_ngon(bm, v1, v2, edges, BLI_array_count(edges), faces[0], BM_CREATE_NOP) : NULL; + f_new = BLI_array_len(edges) ? + BM_face_create_ngon(bm, v1, v2, edges, BLI_array_len(edges), faces[0], BM_CREATE_NOP) : NULL; if (UNLIKELY(f_new == NULL)) { /* Invalid boundary region to join faces */ goto error; @@ -1347,11 +1347,11 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del) /* delete old geometry */ if (do_del) { - for (i = 0; i < BLI_array_count(deledges); i++) { + for (i = 0; i < BLI_array_len(deledges); i++) { BM_edge_kill(bm, deledges[i]); } - for (i = 0; i < BLI_array_count(delverts); i++) { + for (i = 0; i < BLI_array_len(delverts); i++) { BM_vert_kill(bm, delverts[i]); } } @@ -1785,7 +1785,7 @@ BMEdge *bmesh_kernel_join_edge_kill_vert( return NULL; } - if (bmesh_disk_count_ex(v_kill, 3) == 2) { + if (bmesh_disk_count_at_most(v_kill, 3) == 2) { #ifndef NDEBUG int valence1, valence2; BMLoop *l; @@ -2423,9 +2423,10 @@ static void bmesh_kernel_vert_separate__cleanup(BMesh *bm, LinkNode *edges_separ /* don't visit again */ n_prev->next = n_step->next; } - } while ((void) - (n_prev = n_step), - (n_step = n_step->next)); + else { + n_prev = n_step; + } + } while ((n_step = n_step->next)); } while ((n_orig = n_orig->next) && n_orig->next); } while ((edges_separate = edges_separate->next)); diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index 96154f051f9..9fe28561b93 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -430,7 +430,7 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const void bmiter__elem_of_mesh_begin(struct BMIter__elem_of_mesh *iter) { #ifdef USE_IMMUTABLE_ASSERT - ((BMIter *)iter)->count = BLI_mempool_count(iter->pooliter.pool); + ((BMIter *)iter)->count = BLI_mempool_len(iter->pooliter.pool); #endif BLI_mempool_iternew(iter->pooliter.pool, &iter->pooliter); } @@ -438,7 +438,7 @@ void bmiter__elem_of_mesh_begin(struct BMIter__elem_of_mesh *iter) void *bmiter__elem_of_mesh_step(struct BMIter__elem_of_mesh *iter) { #ifdef USE_IMMUTABLE_ASSERT - BLI_assert(((BMIter *)iter)->count <= BLI_mempool_count(iter->pooliter.pool)); + BLI_assert(((BMIter *)iter)->count <= BLI_mempool_len(iter->pooliter.pool)); #endif return BLI_mempool_iterstep(&iter->pooliter); } diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index 1d16dbc1836..5ae72851c7e 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -990,11 +990,11 @@ void BM_log_all_added(BMesh *bm, BMLog *log) BMFace *f; /* avoid unnecessary resizing on initialization */ - if (BLI_ghash_size(log->current_entry->added_verts) == 0) { + if (BLI_ghash_len(log->current_entry->added_verts) == 0) { BLI_ghash_reserve(log->current_entry->added_verts, (uint)bm->totvert); } - if (BLI_ghash_size(log->current_entry->added_faces) == 0) { + if (BLI_ghash_len(log->current_entry->added_faces) == 0) { BLI_ghash_reserve(log->current_entry->added_faces, (uint)bm->totface); } diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 67db51446df..9e03c28ba1b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -521,21 +521,19 @@ void BM_verts_calc_normal_vcos(BMesh *bm, const float (*fnos)[3], const float (* } /** - * Helpers for #BM_mesh_loop_normals_update and #BM_loops_calc_normals_vnos + * Helpers for #BM_mesh_loop_normals_update and #BM_loops_calc_normal_vcos */ static void bm_mesh_edges_sharp_tag( - BMesh *bm, const float (*vnos)[3], const float (*fnos)[3], float split_angle, - float (*r_lnos)[3]) + BMesh *bm, + const float (*vnos)[3], const float (*fnos)[3], float (*r_lnos)[3], + const float split_angle, const bool do_sharp_edges_tag) { BMIter eiter; BMEdge *e; int i; const bool check_angle = (split_angle < (float)M_PI); - - if (check_angle) { - split_angle = cosf(split_angle); - } + const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f; { char htype = BM_VERT | BM_LOOP; @@ -560,7 +558,7 @@ static void bm_mesh_edges_sharp_tag( if (check_angle) { const float *no_a = fnos ? fnos[BM_elem_index_get(l_a->f)] : l_a->f->no; const float *no_b = fnos ? fnos[BM_elem_index_get(l_b->f)] : l_b->f->no; - is_angle_smooth = (dot_v3v3(no_a, no_b) >= split_angle); + is_angle_smooth = (dot_v3v3(no_a, no_b) >= split_angle_cos); } /* We only tag edges that are *really* smooth: @@ -570,20 +568,28 @@ static void bm_mesh_edges_sharp_tag( * and both its faces have compatible (non-flipped) normals, * i.e. both loops on the same edge do not share the same vertex. */ - if (is_angle_smooth && - BM_elem_flag_test(e, BM_ELEM_SMOOTH) && + if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && BM_elem_flag_test(l_a->f, BM_ELEM_SMOOTH) && BM_elem_flag_test(l_b->f, BM_ELEM_SMOOTH) && l_a->v != l_b->v) { - const float *no; - BM_elem_flag_enable(e, BM_ELEM_TAG); - - /* linked vertices might be fully smooth, copy their normals to loop ones. */ - no = vnos ? vnos[BM_elem_index_get(l_a->v)] : l_a->v->no; - copy_v3_v3(r_lnos[BM_elem_index_get(l_a)], no); - no = vnos ? vnos[BM_elem_index_get(l_b->v)] : l_b->v->no; - copy_v3_v3(r_lnos[BM_elem_index_get(l_b)], no); + if (is_angle_smooth) { + const float *no; + BM_elem_flag_enable(e, BM_ELEM_TAG); + + /* linked vertices might be fully smooth, copy their normals to loop ones. */ + if (r_lnos) { + no = vnos ? vnos[BM_elem_index_get(l_a->v)] : l_a->v->no; + copy_v3_v3(r_lnos[BM_elem_index_get(l_a)], no); + no = vnos ? vnos[BM_elem_index_get(l_b->v)] : l_b->v->no; + copy_v3_v3(r_lnos[BM_elem_index_get(l_b)], no); + } + } + else if (do_sharp_edges_tag) { + /* Note that we do not care about the other sharp-edge cases (sharp poly, non-manifold edge, etc.), + * only tag edge as sharp when it is due to angle threashold. */ + BM_elem_flag_disable(e, BM_ELEM_SMOOTH); + } } } } @@ -591,9 +597,11 @@ static void bm_mesh_edges_sharp_tag( bm->elem_index_dirty &= ~BM_EDGE; } -/* Check whether gievn loop is part of an unknown-so-far cyclic smooth fan, or not. - * Needed because cyclic smooth fans have no obvious 'entry point', and yet we need to walk them once, and only once. */ -static bool bm_mesh_loop_check_cyclic_smooth_fan(BMLoop *l_curr) +/** + * Check whether given loop is part of an unknown-so-far cyclic smooth fan, or not. + * Needed because cyclic smooth fans have no obvious 'entry point', and yet we need to walk them once, and only once. + */ +bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr) { BMLoop *lfan_pivot_next = l_curr; BMEdge *e_next = l_curr->e; @@ -659,7 +667,7 @@ static void bm_mesh_loops_calc_normals( r_lnors_spacearr = &_lnors_spacearr; } if (r_lnors_spacearr) { - BKE_lnor_spacearr_init(r_lnors_spacearr, bm->totloop); + BKE_lnor_spacearr_init(r_lnors_spacearr, bm->totloop, MLNOR_SPACEARR_BMLOOP_PTR); edge_vectors = BLI_stack_new(sizeof(float[3]), __func__); } @@ -694,7 +702,7 @@ static void bm_mesh_loops_calc_normals( * However, this would complicate the code, add more memory usage, and BM_vert_step_fan_loop() * is quite cheap in term of CPU cycles, so really think it's not worth it. */ if (BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) && - (BM_elem_flag_test(l_curr, BM_ELEM_TAG) || !bm_mesh_loop_check_cyclic_smooth_fan(l_curr))) + (BM_elem_flag_test(l_curr, BM_ELEM_TAG) || !BM_loop_check_cyclic_smooth_fan(l_curr))) { } else if (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) && @@ -728,7 +736,7 @@ static void bm_mesh_loops_calc_normals( BKE_lnor_space_define(lnor_space, r_lnos[l_curr_index], vec_curr, vec_prev, NULL); /* We know there is only one loop in this space, no need to create a linklist in this case... */ - BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, l_curr_index, false); + BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, l_curr_index, l_curr, true); if (has_clnors) { short (*clnor)[2] = clnors_data ? &clnors_data[l_curr_index] : @@ -847,7 +855,7 @@ static void bm_mesh_loops_calc_normals( if (r_lnors_spacearr) { /* Assign current lnor space to current 'vertex' loop. */ - BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, lfan_pivot_index, true); + BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, lfan_pivot_index, lfan_pivot, false); if (e_next != e_org) { /* We store here all edges-normalized vectors processed. */ BLI_stack_push(edge_vectors, vec_next); @@ -1008,7 +1016,7 @@ void BM_loops_calc_normal_vcos( if (use_split_normals) { /* Tag smooth edges and set lnos from vnos when they might be completely smooth... * When using custom loop normals, disable the angle feature! */ - bm_mesh_edges_sharp_tag(bm, vnos, fnos, has_clnors ? (float)M_PI : split_angle, r_lnos); + bm_mesh_edges_sharp_tag(bm, vnos, fnos, r_lnos, has_clnors ? (float)M_PI : split_angle, false); /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */ bm_mesh_loops_calc_normals(bm, vcos, fnos, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset); @@ -1019,7 +1027,22 @@ void BM_loops_calc_normal_vcos( } } -static void UNUSED_FUNCTION(bm_mdisps_space_set)(Object *ob, BMesh *bm, int from, int to) +/** Define sharp edges as needed to mimic 'autosmooth' from angle threshold. + * + * Used when defining an empty custom loop normals data layer, to keep same shading as with autosmooth! + */ +void BM_edges_sharp_from_angle_set(BMesh *bm, const float split_angle) +{ + if (split_angle >= (float)M_PI) { + /* Nothing to do! */ + return; + } + + bm_mesh_edges_sharp_tag(bm, NULL, NULL, NULL, split_angle, true); +} + +static void UNUSED_FUNCTION(bm_mdisps_space_set)( + Object *ob, BMesh *bm, int from, int to) { /* switch multires data out of tangent space */ if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) { diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h index 01f11f6f942..10f024423aa 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.h +++ b/source/blender/bmesh/intern/bmesh_mesh.h @@ -52,6 +52,11 @@ void BM_loops_calc_normal_vcos( const bool use_split_normals, const float split_angle, float (*r_lnos)[3], struct MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset); +bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr); + + +void BM_edges_sharp_from_angle_set(BMesh *bm, const float split_angle); + void bmesh_edit_begin(BMesh *bm, const BMOpTypeFlag type_flag); void bmesh_edit_end(BMesh *bm, const BMOpTypeFlag type_flag); diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 6cc1f37db43..fd32119cb5f 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -708,7 +708,7 @@ void BM_mesh_bm_to_me( } /* patch hook indices and vertex parents */ - if (ototvert > 0) { + if (params->calc_object_remap && (ototvert > 0)) { Object *ob; ModifierData *md; BMVert **vertMap = NULL; @@ -765,11 +765,7 @@ void BM_mesh_bm_to_me( if (vertMap) MEM_freeN(vertMap); } - if (params->calc_tessface) { - BKE_mesh_tessface_calc(me); - } - - BKE_mesh_update_customdata_pointers(me, params->calc_tessface); + BKE_mesh_update_customdata_pointers(me, false); { BMEditSelection *selected; diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h index 1974d364171..6e9d62349ea 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.h +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h @@ -55,7 +55,8 @@ void BM_mesh_bm_from_me( ATTR_NONNULL(1, 3); struct BMeshToMeshParams { - uint calc_tessface : 1; + /** Update object hook indices & vertex parents. */ + uint calc_object_remap : 1; int64_t cd_mask_extra; }; void BM_mesh_bm_to_me( diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 1cd51528e06..4290f94bba1 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -65,7 +65,7 @@ bool BM_vert_dissolve(BMesh *bm, BMVert *v) { /* logic for 3 or more is identical */ - const int len = BM_vert_edge_count_ex(v, 3); + const int len = BM_vert_edge_count_at_most(v, 3); if (len == 1) { BM_vert_kill(bm, v); /* will kill edges too */ @@ -482,8 +482,8 @@ BMEdge *BM_vert_collapse_faces( BLI_array_append(faces, f); } - if (BLI_array_count(faces) >= 2) { - BMFace *f2 = BM_faces_join(bm, faces, BLI_array_count(faces), true); + if (BLI_array_len(faces) >= 2) { + BMFace *f2 = BM_faces_join(bm, faces, BLI_array_len(faces), true); if (f2) { BMLoop *l_a, *l_b; @@ -499,7 +499,7 @@ BMEdge *BM_vert_collapse_faces( } } - BLI_assert(BLI_array_count(faces) < 8); + BLI_assert(BLI_array_len(faces) < 8); BLI_array_free(faces); } @@ -608,7 +608,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac) } while (l != e->l); /* flag existing faces so we can differentiate oldfaces from new faces */ - for (i = 0; i < BLI_array_count(oldfaces); i++) { + for (i = 0; i < BLI_array_len(oldfaces); i++) { BM_ELEM_API_FLAG_ENABLE(oldfaces[i], _FLAG_OVERLAP); oldfaces[i] = BM_face_copy(bm, bm, oldfaces[i], true, true); BM_ELEM_API_FLAG_DISABLE(oldfaces[i], _FLAG_OVERLAP); @@ -639,7 +639,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac) int i, j; /* interpolate new/changed loop data from copied old faces */ - for (i = 0; i < BLI_array_count(oldfaces); i++) { + for (i = 0; i < BLI_array_len(oldfaces); i++) { float f_center_old[3]; BM_face_calc_center_mean(oldfaces[i], f_center_old); @@ -671,7 +671,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac) } /* destroy the old faces */ - for (i = 0; i < BLI_array_count(oldfaces); i++) { + for (i = 0; i < BLI_array_len(oldfaces); i++) { BM_face_verts_kill(bm, oldfaces[i]); } diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index ddc2b26417c..37a4fb5c29c 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -843,7 +843,6 @@ static BMOpDefine bmo_bmesh_to_mesh_def = { {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}}, /* pointer to an object structure */ {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}}, - {"skip_tessface", BMO_OP_SLOT_BOOL}, /* don't calculate mfaces */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 0f672a9ff2a..f814767a200 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -673,7 +673,7 @@ int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_na { BMOpSlot *slot = BMO_slot_get(slot_args, slot_name); BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING); - return BLI_ghash_size(slot->data.ghash); + return BLI_ghash_len(slot->data.ghash); } /* inserts a key/value mapping into a mapping slot. note that it copies the diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 66fcd739839..bcb940f8b96 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -36,8 +36,8 @@ #include "BLI_alloca.h" #include "BLI_math.h" #include "BLI_memarena.h" -#include "BLI_polyfill2d.h" -#include "BLI_polyfill2d_beautify.h" +#include "BLI_polyfill_2d.h" +#include "BLI_polyfill_2d_beautify.h" #include "BLI_linklist.h" #include "BLI_edgehash.h" #include "BLI_heap.h" @@ -1426,6 +1426,17 @@ void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptri (l_ptr_a[2] = l_ptr_b[1] = l = l->next); ( l_ptr_b[2] = l->next); #endif + + if (UNLIKELY(is_quad_flip_v3_first_third_fast( + l_ptr_a[0]->v->co, + l_ptr_a[1]->v->co, + l_ptr_a[2]->v->co, + l_ptr_b[2]->v->co))) + { + /* flip out of degenerate 0-2 state. */ + l_ptr_a[2] = l_ptr_b[2]; + l_ptr_b[0] = l_ptr_a[1]; + } } #endif /* USE_TESSFACE_SPEEDUP */ diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c index 41775bdf2d0..85dfd3f58e2 100644 --- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c +++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c @@ -665,7 +665,7 @@ bool BM_face_split_edgenet( BM_ELEM_API_FLAG_DISABLE(l_iter->v, VERT_VISIT); } while ((l_iter = l_iter->next) != l_first); - if (BLI_array_count(face_arr)) { + if (BLI_array_len(face_arr)) { bmesh_face_swap_data(f, face_arr[0]); BM_face_kill(bm, face_arr[0]); face_arr[0] = f; @@ -674,13 +674,13 @@ bool BM_face_split_edgenet( BM_ELEM_API_FLAG_DISABLE(f, FACE_NET); } - for (i = 0; i < BLI_array_count(face_arr); i++) { + for (i = 0; i < BLI_array_len(face_arr); i++) { BM_ELEM_API_FLAG_DISABLE(face_arr[i], FACE_NET); } if (r_face_arr) { *r_face_arr = face_arr; - *r_face_arr_len = BLI_array_count(face_arr); + *r_face_arr_len = BLI_array_len(face_arr); } else { if (face_arr) { @@ -860,7 +860,7 @@ static void bvhtree_test_edges_isect_2d_ray_cb( /** * Store values for: * - #bm_face_split_edgenet_find_connection - * - #test_edges_isect_2d + * - #test_edges_isect_2d_vert * ... which don't change each call. */ struct EdgeGroup_FindConnection_Args { diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h index 4dcf97e3f35..daee22ffe76 100644 --- a/source/blender/bmesh/intern/bmesh_private.h +++ b/source/blender/bmesh/intern/bmesh_private.h @@ -55,7 +55,7 @@ int bmesh_elem_check(void *element, const char htype); #endif int bmesh_radial_length(const BMLoop *l); -int bmesh_disk_count_ex(const BMVert *v, const int count_max); +int bmesh_disk_count_at_most(const BMVert *v, const int count_max); int bmesh_disk_count(const BMVert *v); /** diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 32f726df01d..ab2f017d103 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -799,9 +799,9 @@ int BM_vert_edge_count(const BMVert *v) return bmesh_disk_count(v); } -int BM_vert_edge_count_ex(const BMVert *v, const int count_max) +int BM_vert_edge_count_at_most(const BMVert *v, const int count_max) { - return bmesh_disk_count_ex(v, count_max); + return bmesh_disk_count_at_most(v, count_max); } int BM_vert_edge_count_nonwire(const BMVert *v) @@ -835,7 +835,7 @@ int BM_edge_face_count(const BMEdge *e) return count; } -int BM_edge_face_count_ex(const BMEdge *e, const int count_max) +int BM_edge_face_count_at_most(const BMEdge *e, const int count_max) { int count = 0; @@ -863,9 +863,9 @@ int BM_vert_face_count(const BMVert *v) return bmesh_disk_facevert_count(v); } -int BM_vert_face_count_ex(const BMVert *v, int count_max) +int BM_vert_face_count_at_most(const BMVert *v, int count_max) { - return bmesh_disk_facevert_count_ex(v, count_max); + return bmesh_disk_facevert_count_at_most(v, count_max); } /** @@ -1044,7 +1044,7 @@ static int bm_loop_region_count__clear(BMLoop *l) /** * The number of loops connected to this loop (not including disconnected regions). */ -int BM_loop_region_loops_count_ex(BMLoop *l, int *r_loop_total) +int BM_loop_region_loops_count_at_most(BMLoop *l, int *r_loop_total) { const int count = bm_loop_region_count__recursive(l->e, l->v); const int count_total = bm_loop_region_count__clear(l); @@ -1059,7 +1059,7 @@ int BM_loop_region_loops_count_ex(BMLoop *l, int *r_loop_total) int BM_loop_region_loops_count(BMLoop *l) { - return BM_loop_region_loops_count_ex(l, NULL); + return BM_loop_region_loops_count_at_most(l, NULL); } /** @@ -1071,7 +1071,7 @@ bool BM_vert_is_manifold_region(const BMVert *v) BMLoop *l_first = BM_vert_find_first_loop((BMVert *)v); if (l_first) { int count, count_total; - count = BM_loop_region_loops_count_ex(l_first, &count_total); + count = BM_loop_region_loops_count_at_most(l_first, &count_total); return (count == count_total); } return true; @@ -1526,9 +1526,9 @@ 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 + * \param l: The loop to calculate the normal at. + * \param epsilon_sq: Value to avoid numeric errors (1e-5f works well). + * \param r_normal: Resulting normal. */ float BM_loop_calc_face_normal_safe_ex(const BMLoop *l, const float epsilon_sq, float r_normal[3]) { diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index c9fce96c798..e602c63da94 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -70,17 +70,17 @@ BMFace *BM_edge_pair_share_face_by_len( const bool allow_adjacent) ATTR_NONNULL(); int BM_vert_edge_count_nonwire(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -#define BM_vert_edge_count_is_equal(v, n) (BM_vert_edge_count_ex(v, (n) + 1) == n) -#define BM_vert_edge_count_is_over(v, n) (BM_vert_edge_count_ex(v, (n) + 1) == (n) + 1) -int BM_vert_edge_count_ex(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +#define BM_vert_edge_count_is_equal(v, n) (BM_vert_edge_count_at_most(v, (n) + 1) == n) +#define BM_vert_edge_count_is_over(v, n) (BM_vert_edge_count_at_most(v, (n) + 1) == (n) + 1) +int BM_vert_edge_count_at_most(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BM_vert_edge_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -#define BM_edge_face_count_is_equal(e, n) (BM_edge_face_count_ex(e, (n) + 1) == n) -#define BM_edge_face_count_is_over(e, n) (BM_edge_face_count_ex(e, (n) + 1) == (n) + 1) -int BM_edge_face_count_ex(const BMEdge *e, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +#define BM_edge_face_count_is_equal(e, n) (BM_edge_face_count_at_most(e, (n) + 1) == n) +#define BM_edge_face_count_is_over(e, n) (BM_edge_face_count_at_most(e, (n) + 1) == (n) + 1) +int BM_edge_face_count_at_most(const BMEdge *e, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BM_edge_face_count(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -#define BM_vert_face_count_is_equal(v, n) (BM_vert_face_count_ex(v, (n) + 1) == n) -#define BM_vert_face_count_is_over(v, n) (BM_vert_face_count_ex(v, (n) + 1) == (n) + 1) -int BM_vert_face_count_ex(const BMVert *v, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +#define BM_vert_face_count_is_equal(v, n) (BM_vert_face_count_at_most(v, (n) + 1) == n) +#define BM_vert_face_count_is_over(v, n) (BM_vert_face_count_at_most(v, (n) + 1) == (n) + 1) +int BM_vert_face_count_at_most(const BMVert *v, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BM_vert_face_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); @@ -103,7 +103,7 @@ bool BM_edge_is_contiguous_loop_cd( const int cd_loop_type, const int cd_loop_offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -int BM_loop_region_loops_count_ex(BMLoop *l, int *r_loop_total) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +int BM_loop_region_loops_count_at_most(BMLoop *l, int *r_loop_total) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); int BM_loop_region_loops_count(BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); bool BM_loop_is_convex(const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BLI_INLINE bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c index 8e484841568..8aa9502c0f7 100644 --- a/source/blender/bmesh/intern/bmesh_structure.c +++ b/source/blender/bmesh/intern/bmesh_structure.c @@ -244,7 +244,7 @@ int bmesh_disk_count(const BMVert *v) return count; } -int bmesh_disk_count_ex(const BMVert *v, const int count_max) +int bmesh_disk_count_at_most(const BMVert *v, const int count_max) { int count = 0; if (v->e) { @@ -267,7 +267,7 @@ bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v) if (!BM_vert_in_edge(e, v)) { return false; } - if (len == 0 || bmesh_disk_count_ex(v, len + 1) != len) { + if (len == 0 || bmesh_disk_count_at_most(v, len + 1) != len) { return false; } @@ -307,7 +307,7 @@ int bmesh_disk_facevert_count(const BMVert *v) return count; } -int bmesh_disk_facevert_count_ex(const BMVert *v, const int count_max) +int bmesh_disk_facevert_count_at_most(const BMVert *v, const int count_max) { /* is there an edge on this vert at all */ int count = 0; @@ -318,7 +318,7 @@ int bmesh_disk_facevert_count_ex(const BMVert *v, const int count_max) e_first = e_iter = v->e; do { if (e_iter->l) { - count += bmesh_radial_facevert_count_ex(e_iter->l, v, count_max - count); + count += bmesh_radial_facevert_count_at_most(e_iter->l, v, count_max - count); if (count == count_max) { break; } @@ -560,7 +560,7 @@ int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v) return count; } -int bmesh_radial_facevert_count_ex(const BMLoop *l, const BMVert *v, const int count_max) +int bmesh_radial_facevert_count_at_most(const BMLoop *l, const BMVert *v, const int count_max) { const BMLoop *l_iter; int count = 0; diff --git a/source/blender/bmesh/intern/bmesh_structure.h b/source/blender/bmesh/intern/bmesh_structure.h index 0efb25da37c..974b276f8b3 100644 --- a/source/blender/bmesh/intern/bmesh_structure.h +++ b/source/blender/bmesh/intern/bmesh_structure.h @@ -49,7 +49,7 @@ BLI_INLINE BMEdge *bmesh_disk_edge_next_safe(const BMEdge *e, const BMVert *v) A BLI_INLINE BMEdge *bmesh_disk_edge_prev_safe(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BLI_INLINE BMEdge *bmesh_disk_edge_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BLI_INLINE BMEdge *bmesh_disk_edge_prev(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -int bmesh_disk_facevert_count_ex(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +int bmesh_disk_facevert_count_at_most(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int bmesh_disk_facevert_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMLoop *bmesh_disk_faceloop_find_first(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); @@ -63,7 +63,7 @@ void bmesh_radial_loop_unlink(BMLoop *l) ATTR_NONNULL(); * bmesh_radial_loop_next(BMLoop *l) / prev. * just use member access l->radial_next, l->radial_prev now */ -int bmesh_radial_facevert_count_ex(const BMLoop *l, const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +int bmesh_radial_facevert_count_at_most(const BMLoop *l, const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); bool bmesh_radial_facevert_check(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMLoop *bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/bmesh/operators/bmo_connect_concave.c b/source/blender/bmesh/operators/bmo_connect_concave.c index 80774323d31..d1811ac6a83 100644 --- a/source/blender/bmesh/operators/bmo_connect_concave.c +++ b/source/blender/bmesh/operators/bmo_connect_concave.c @@ -39,8 +39,8 @@ #include "BLI_alloca.h" #include "BLI_memarena.h" #include "BLI_heap.h" -#include "BLI_polyfill2d.h" -#include "BLI_polyfill2d_beautify.h" +#include "BLI_polyfill_2d.h" +#include "BLI_polyfill_2d_beautify.h" #include "BLI_linklist.h" #include "bmesh.h" diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c index 60fd9808fcb..b9e5cd927c3 100644 --- a/source/blender/bmesh/operators/bmo_connect_pair.c +++ b/source/blender/bmesh/operators/bmo_connect_pair.c @@ -662,11 +662,11 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op) while (!BLI_heap_is_empty(pc.states)) { #ifdef DEBUG_PRINT - printf("\n%s: stepping %u\n", __func__, BLI_heap_size(pc.states)); + printf("\n%s: stepping %u\n", __func__, BLI_heap_len(pc.states)); #endif while (!BLI_heap_is_empty(pc.states)) { - PathLinkState *state = BLI_heap_popmin(pc.states); + PathLinkState *state = BLI_heap_pop_min(pc.states); /* either we insert this into 'pc.states' or its freed */ bool continue_search; diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index 2df8e73c2b8..816d2e8d009 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -166,7 +166,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) continue; } - BLI_array_empty(faces); + BLI_array_clear(faces); faces = NULL; /* forces different allocatio */ BMW_init(®walker, bm, BMW_ISLAND_MANIFOLD, @@ -179,7 +179,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) } BMW_end(®walker); - for (i = 0; i < BLI_array_count(faces); i++) { + for (i = 0; i < BLI_array_len(faces); i++) { f_iter = faces[i]; BMO_face_flag_disable(bm, f_iter, FACE_TAG); BMO_face_flag_enable(bm, f_iter, FACE_ORIG); @@ -198,7 +198,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) /* track how many faces we should end up with */ int totface_target = bm->totface; - for (i = 0; i < BLI_array_count(regions); i++) { + for (i = 0; i < BLI_array_len(regions); i++) { BMFace *f_new; int tot = 0; @@ -259,7 +259,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) cleanup: /* free/cleanup */ - for (i = 0; i < BLI_array_count(regions); i++) { + for (i = 0; i < BLI_array_len(regions); i++) { if (regions[i]) MEM_freeN(regions[i]); } diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c index 64b092da5c8..931ac684b07 100644 --- a/source/blender/bmesh/operators/bmo_edgenet.c +++ b/source/blender/bmesh/operators/bmo_edgenet.c @@ -179,22 +179,22 @@ void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op) if (!count) { edges1 = edges; - BLI_array_count_set(edges1, BLI_array_count(edges)); + BLI_array_len_set(edges1, BLI_array_len(edges)); } else { edges2 = edges; - BLI_array_count_set(edges2, BLI_array_count(edges)); + BLI_array_len_set(edges2, BLI_array_len(edges)); } - BLI_array_empty(edges); + BLI_array_clear(edges); count++; } - if (edges1 && BLI_array_count(edges1) > 2 && - BM_edge_share_vert_check(edges1[0], edges1[BLI_array_count(edges1) - 1])) + if (edges1 && BLI_array_len(edges1) > 2 && + BM_edge_share_vert_check(edges1[0], edges1[BLI_array_len(edges1) - 1])) { - if (edges2 && BLI_array_count(edges2) > 2 && - BM_edge_share_vert_check(edges2[0], edges2[BLI_array_count(edges2) - 1])) + if (edges2 && BLI_array_len(edges2) > 2 && + BM_edge_share_vert_check(edges2[0], edges2[BLI_array_len(edges2) - 1])) { BLI_array_free(edges1); BLI_array_free(edges2); @@ -206,8 +206,8 @@ void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op) } } - if (edges2 && BLI_array_count(edges2) > 2 && - BM_edge_share_vert_check(edges2[0], edges2[BLI_array_count(edges2) - 1])) + if (edges2 && BLI_array_len(edges2) > 2 && + BM_edge_share_vert_check(edges2[0], edges2[BLI_array_len(edges2) - 1])) { edges2 = NULL; } @@ -218,23 +218,23 @@ void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op) float dvec1[3]; float dvec2[3]; - if (BLI_array_count(edges1) == 1) { + if (BLI_array_len(edges1) == 1) { v1 = edges1[0]->v1; v2 = edges1[0]->v2; } else { v1 = BM_vert_in_edge(edges1[1], edges1[0]->v1) ? edges1[0]->v2 : edges1[0]->v1; - i = BLI_array_count(edges1) - 1; + i = BLI_array_len(edges1) - 1; v2 = BM_vert_in_edge(edges1[i - 1], edges1[i]->v1) ? edges1[i]->v2 : edges1[i]->v1; } - if (BLI_array_count(edges2) == 1) { + if (BLI_array_len(edges2) == 1) { v3 = edges2[0]->v1; v4 = edges2[0]->v2; } else { v3 = BM_vert_in_edge(edges2[1], edges2[0]->v1) ? edges2[0]->v2 : edges2[0]->v1; - i = BLI_array_count(edges2) - 1; + i = BLI_array_len(edges2) - 1; v4 = BM_vert_in_edge(edges2[i - 1], edges2[i]->v1) ? edges2[i]->v2 : edges2[i]->v1; } @@ -265,9 +265,9 @@ void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op) else if (edges1) { BMVert *v1, *v2; - if (BLI_array_count(edges1) > 1) { + if (BLI_array_len(edges1) > 1) { v1 = BM_vert_in_edge(edges1[1], edges1[0]->v1) ? edges1[0]->v2 : edges1[0]->v1; - i = BLI_array_count(edges1) - 1; + i = BLI_array_len(edges1) - 1; v2 = BM_vert_in_edge(edges1[i - 1], edges1[i]->v1) ? edges1[i]->v2 : edges1[i]->v1; e = BM_edge_create(bm, v1, v2, NULL, BM_CREATE_NO_DOUBLE); BMO_edge_flag_enable(bm, e, ELE_NEW); diff --git a/source/blender/bmesh/operators/bmo_face_island.c b/source/blender/bmesh/operators/bmo_face_island.c index 77b28f2f29c..e52052a28d3 100644 --- a/source/blender/bmesh/operators/bmo_face_island.c +++ b/source/blender/bmesh/operators/bmo_face_island.c @@ -99,7 +99,7 @@ void bmo_face_island_boundary_exec(BMesh *bm, BMOperator *op) { BMOpSlot *slot = BMO_slot_get(op->slots_out, "boundary"); - BMO_slot_buffer_from_array(op, slot, (BMHeader **)boundary, BLI_array_count(boundary)); + BMO_slot_buffer_from_array(op, slot, (BMHeader **)boundary, BLI_array_len(boundary)); BLI_array_free(boundary); } diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c index 81ec2860cf7..d52cb00e172 100644 --- a/source/blender/bmesh/operators/bmo_hull.c +++ b/source/blender/bmesh/operators/bmo_hull.c @@ -521,7 +521,7 @@ static void hull_from_bullet( int j; /* Get face vertex indices */ - BLI_array_empty(fvi); + BLI_array_clear(fvi); BLI_array_grow_items(fvi, len); plConvexHullGetFaceVertices(hull, i, fvi); diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index 69198ff35ab..b1053e6d8c2 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -270,7 +270,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) BMFace *f; BMEdge *e; /* data: edge-to-join, sort_value: error weight */ - struct SortPointerByFloat *jedges; + struct SortPtrByFloat *jedges; unsigned i, totedge; uint totedge_tag = 0; diff --git a/source/blender/bmesh/operators/bmo_mesh_conv.c b/source/blender/bmesh/operators/bmo_mesh_conv.c index 0eb9bf90ca8..7311ed5ce64 100644 --- a/source/blender/bmesh/operators/bmo_mesh_conv.c +++ b/source/blender/bmesh/operators/bmo_mesh_conv.c @@ -62,15 +62,18 @@ void bmo_object_load_bmesh_exec(BMesh *bm, BMOperator *op) Mesh *me = ob->data; BMO_op_callf(bm, op->flag, - "bmesh_to_mesh mesh=%p object=%p skip_tessface=%b", - me, ob, true); + "bmesh_to_mesh mesh=%p object=%p", + me, ob); } void bmo_bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { Mesh *me = BMO_slot_ptr_get(op->slots_in, "mesh"); /* Object *ob = BMO_slot_ptr_get(op, "object"); */ - const bool dotess = !BMO_slot_bool_get(op->slots_in, "skip_tessface"); - BM_mesh_bm_to_me(bm, me, (&(struct BMeshToMeshParams){ .calc_tessface = dotess, })); + BM_mesh_bm_to_me( + bm, me, + (&(struct BMeshToMeshParams){ + .calc_object_remap = true, + })); } diff --git a/source/blender/bmesh/operators/bmo_rotate_edges.c b/source/blender/bmesh/operators/bmo_rotate_edges.c index 9832fdb57d3..75e31c68dae 100644 --- a/source/blender/bmesh/operators/bmo_rotate_edges.c +++ b/source/blender/bmesh/operators/bmo_rotate_edges.c @@ -180,7 +180,7 @@ static void bm_rotate_edges_shared( const int edges_len_rotate_prev = edges_len_rotate; while (!BLI_heap_is_empty(heap)) { - BMEdge *e_best = BLI_heap_popmin(heap); + BMEdge *e_best = BLI_heap_pop_min(heap); eheap_table[BM_elem_index_get(e_best)] = NULL; /* No problem if this fails, re-evaluate if faces connected to this edge are touched. */ diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 894129b4a33..8f998797a16 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -1011,8 +1011,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) /* figure out which pattern to use */ - BLI_array_empty(edges); - BLI_array_empty(verts); + BLI_array_clear(edges); + BLI_array_clear(verts); BLI_array_grow_items(edges, face->len); BLI_array_grow_items(verts, face->len); @@ -1140,7 +1140,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) face = fd->face; /* figure out which pattern to use */ - BLI_array_empty(verts); + BLI_array_clear(verts); pat = fd->pat; @@ -1148,8 +1148,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) int vlen; /* ok, no pattern. we still may be able to do something */ - BLI_array_empty(loops); - BLI_array_empty(loops_split); + BLI_array_clear(loops); + BLI_array_clear(loops_split); /* for case of two edges, connecting them shouldn't be too hard */ BLI_array_grow_items(loops, face->len); @@ -1157,7 +1157,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) loops[a] = l; } - vlen = BLI_array_count(loops); + vlen = BLI_array_len(loops); /* find the boundary of one of the split edges */ for (a = 1; a < vlen; a++) { @@ -1236,9 +1236,9 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) * - concave corner of an ngon. * - 2 edges being used in 2+ ngons. */ -// BM_face_splits_check_legal(bm, face, loops_split, BLI_array_count(loops_split)); +// BM_face_splits_check_legal(bm, face, loops_split, BLI_array_len(loops_split)); - for (j = 0; j < BLI_array_count(loops_split); j++) { + for (j = 0; j < BLI_array_len(loops_split); j++) { if (loops_split[j][0]) { BMFace *f_new; BLI_assert(BM_edge_exists(loops_split[j][0]->v, loops_split[j][1]->v) == NULL); diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c index adcc0c71629..e6881f6d8b1 100644 --- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c +++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c @@ -269,7 +269,7 @@ static GSet *bm_edgering_pair_calc(BMesh *bm, ListBase *eloops_rim) BLI_ghash_free(vert_eloop_gh, NULL, NULL); - if (BLI_gset_size(eloop_pair_gs) == 0) { + if (BLI_gset_len(eloop_pair_gs) == 0) { BLI_gset_free(eloop_pair_gs, NULL); eloop_pair_gs = NULL; } @@ -1193,7 +1193,7 @@ void bmo_subdivide_edgering_exec(BMesh *bm, BMOperator *op) goto cleanup; } - lpair_arr = BLI_array_alloca(lpair_arr, BLI_gset_size(eloop_pairs_gs)); + lpair_arr = BLI_array_alloca(lpair_arr, BLI_gset_len(eloop_pairs_gs)); /* first cache pairs */ GSET_ITER_INDEX (gs_iter, eloop_pairs_gs, i) { diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index 4e8bace59e0..2cdc2646649 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -106,7 +106,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) /* sf_edge = */ BLI_scanfill_edge_add(&sf_ctx, UNPACK2(sf_verts)); /* sf_edge->tmp.p = e; */ /* UNUSED */ } - nors_tot = BLI_ghash_size(sf_vert_map); + nors_tot = BLI_ghash_len(sf_vert_map); BLI_ghash_free(sf_vert_map, NULL, NULL); diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c index 6e6242fc9f9..d3972363bb4 100644 --- a/source/blender/bmesh/tools/bmesh_beautify.c +++ b/source/blender/bmesh/tools/bmesh_beautify.c @@ -37,7 +37,7 @@ #include "BLI_math.h" #include "BLI_heap.h" -#include "BLI_polyfill2d_beautify.h" +#include "BLI_polyfill_2d_beautify.h" #include "MEM_guardedalloc.h" @@ -392,7 +392,7 @@ void BM_mesh_beautify_fill( bm->elem_index_dirty |= BM_EDGE; while (BLI_heap_is_empty(eheap) == false) { - BMEdge *e = BLI_heap_popmin(eheap); + BMEdge *e = BLI_heap_pop_min(eheap); i = BM_elem_index_get(e); eheap_table[i] = NULL; diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 18b2b4db2bf..457e74ce1aa 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -44,6 +44,8 @@ #include "BKE_customdata.h" #include "BKE_deform.h" +#include "eigen_capi.h" + #include "bmesh.h" #include "bmesh_bevel.h" /* own include */ @@ -58,6 +60,7 @@ #define BEVEL_SMALL_ANG DEG2RADF(10.0f) #define BEVEL_MAX_ADJUST_PCT 10.0f #define BEVEL_MAX_AUTO_ADJUST_PCT 300.0f +#define BEVEL_MATCH_SPEC_WEIGHT 0.2 /* happens far too often, uncomment for development */ // #define BEVEL_ASSERT_PROJECT @@ -139,10 +142,14 @@ typedef struct BoundVert { NewVert nv; EdgeHalf *efirst; /* first of edges attached here: in CCW order */ EdgeHalf *elast; + EdgeHalf *eon; /* the "edge between" that this is on, in offset_on_edge_between case */ EdgeHalf *ebev; /* beveled edge whose left side is attached here, if any */ int index; /* used for vmesh indexing */ + float sinratio; /* when eon set, ratio of sines of angles to eon edge */ + struct BoundVert *adjchain; /* adjustment chain or cycle link pointer */ Profile profile; /* edge profile between this and next BoundVert */ bool any_seam; /* are any of the edges attached here seams? */ + bool visited; /* used during delta adjust pass */ // int _pad; } BoundVert; @@ -192,6 +199,7 @@ typedef struct BevelParams { bool use_weights; /* bevel amount affected by weights on edges or verts */ bool loop_slide; /* should bevel prefer to slide along edges rather than keep widths spec? */ bool limit_offset; /* should offsets be limited by collisions? */ + bool offset_adjust; /* should offsets be adjusted to try to get even widths? */ const struct MDeformVert *dvert; /* vertex group array, maybe set if vertex_only */ int vertex_group; /* vertex group index, maybe set if vertex_only */ int mat_nr; /* if >= 0, material number for bevel; else material comes from adjacent faces */ @@ -207,6 +215,7 @@ static int bev_debug_flags = 0; #define DEBUG_OLD_PROJ_TO_PERP_PLANE (bev_debug_flags & 2) #define DEBUG_OLD_FLAT_MID (bev_debug_flags & 4) + /* this flag values will get set on geom we want to return in 'out' slots for edges and verts */ #define EDGE_OUT 4 #define VERT_OUT 8 @@ -260,6 +269,9 @@ static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float vm->boundstart->prev = ans; } ans->profile.super_r = PRO_LINE_R; + ans->adjchain = NULL; + ans->sinratio = 1.0f; + ans->visited = false; vm->count++; return ans; } @@ -342,52 +354,6 @@ static EdgeHalf *find_other_end_edge_half(BevelParams *bp, EdgeHalf *e, BevVert return NULL; } -static bool other_edge_half_visited(BevelParams *bp, EdgeHalf *e) -{ - BevVert *bvo; - - bvo = find_bevvert(bp, e->is_rev ? e->e->v1 : e->e->v2); - if (bvo) - return bvo->visited; - else - return false; -} - -static bool edge_half_offset_changed(EdgeHalf *e) -{ - return e->offset_l != e->offset_l_spec || - e->offset_r != e->offset_r_spec; -} - -static float adjusted_rel_change(float val, float spec) -{ - float relchg; - - relchg = 0.0f; - if (val != spec) { - if (spec == 0) - relchg = 1000.0f; /* arbitrary large value */ - else - relchg = fabsf((val - spec) / spec); - } - return relchg; -} - -static float max_edge_half_offset_rel_change(BevVert *bv) -{ - int i; - float max_rel_change; - EdgeHalf *e; - - max_rel_change = 0.0f; - for (i = 0; i < bv->edgecount; i++) { - e = &bv->edges[i]; - max_rel_change = max_ff(max_rel_change, adjusted_rel_change(e->offset_l, e->offset_l_spec)); - max_rel_change = max_ff(max_rel_change, adjusted_rel_change(e->offset_r, e->offset_r_spec)); - } - return max_rel_change; -} - /* Return the next EdgeHalf after from_e that is beveled. * If from_e is NULL, find the first beveled edge. */ static EdgeHalf *next_bev(BevVert *bv, EdgeHalf *from_e) @@ -818,10 +784,6 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, bool e copy_v3_v3(off1a, v->co); d = max_ff(e1->offset_r, e2->offset_l); madd_v3_v3fl(off1a, norm_perp1, d); - if (e1->offset_r != d) - e1->offset_r = d; - else if (e2->offset_l != d) - e2->offset_l = d; copy_v3_v3(meetco, off1a); } else if (fabsf(ang - (float)M_PI) < BEVEL_EPSILON_ANG) { @@ -830,10 +792,6 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, bool e * common line, at offset distance from v. */ d = max_ff(e1->offset_r, e2->offset_l); slide_dist(e2, v, d, meetco); - if (e1->offset_r != d) - e1->offset_r = d; - else if (e2->offset_l != d) - e2->offset_l = d; } else { /* Get normal to plane where meet point should be, @@ -871,7 +829,6 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, bool e negate_v3(norm_v2); } - /* get vectors perp to each edge, perp to norm_v, and pointing into face */ cross_v3_v3v3(norm_perp1, dir1, norm_v1); cross_v3_v3v3(norm_perp2, dir2, norm_v2); @@ -891,9 +848,6 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, bool e if (isect_kind == 0) { /* lines are collinear: we already tested for this, but this used a different epsilon */ copy_v3_v3(meetco, off1a); /* just to do something */ - d = dist_to_line_v3(meetco, v->co, BM_edge_other_vert(e2->e, v)->co); - if (fabsf(d - e2->offset_l) > BEVEL_EPSILON) - e2->offset_l = d; } else { /* The lines intersect, but is it at a reasonable place? @@ -903,11 +857,9 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, bool e * or if the offset amount is > the edge length*/ if (e1->offset_r == 0.0f && is_outside_edge(e1, meetco, &closer_v)) { copy_v3_v3(meetco, closer_v->co); - e2->offset_l = len_v3v3(meetco, v->co); } if (e2->offset_l == 0.0f && is_outside_edge(e2, meetco, &closer_v)) { copy_v3_v3(meetco, closer_v->co); - e1->offset_r = len_v3v3(meetco, v->co); } if (edges_between && e1->offset_r > 0.0f && e2->offset_l > 0.0f) { /* Try to drop meetco to a face between e1 and e2 */ @@ -926,8 +878,6 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, bool e break; } } - e1->offset_r = dist_to_line_v3(meetco, v->co, BM_edge_other_vert(e1->e, v)->co); - e2->offset_l = dist_to_line_v3(meetco, v->co, BM_edge_other_vert(e2->e, v)->co); } } } @@ -994,40 +944,27 @@ static bool good_offset_on_edge_between(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *em /* Calculate the best place for a meeting point for the offsets from edges e1 and e2 * on the in-between edge emid. Viewed from the vertex normal side, the CCW * order of these edges is e1, emid, e2. - * The offsets probably do not meet at a common point on emid, so need to pick - * one that causes the least problems. If the other end of one of e1 or e2 has been visited - * already, prefer to keep the offset the same on this end. - * Otherwise, pick a point between the two intersection points on emid that minimizes - * the sum of squares of errors from desired offset. */ -static void offset_on_edge_between( - BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, - BMVert *v, float meetco[3]) + * Return true if we placed meetco as compromise between where two edges met. + * If we did, put ration of sines of angles in *r_sinratio too */ +static bool offset_on_edge_between( + EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, + BMVert *v, float meetco[3], float *r_sinratio) { - float d, ang1, ang2, sina1, sina2, lambda; + float ang1, ang2; float meet1[3], meet2[3]; - bool visited1, visited2, ok1, ok2; + bool ok1, ok2; + bool retval = false; BLI_assert(e1->is_bev && e2->is_bev && !emid->is_bev); - visited1 = other_edge_half_visited(bp, e1); - visited2 = other_edge_half_visited(bp, e2); - ok1 = offset_meet_edge(e1, emid, v, meet1, &ang1); ok2 = offset_meet_edge(emid, e2, v, meet2, &ang2); if (ok1 && ok2) { - if (visited1 && !visited2) { - copy_v3_v3(meetco, meet1); - } - else if (!visited1 && visited2) { - copy_v3_v3(meetco, meet2); - } - else { - /* find best compromise meet point */ - sina1 = sinf(ang1); - sina2 = sinf(ang2); - lambda = sina2 * sina2 / (sina1 * sina1 + sina2 * sina2); - interp_v3_v3v3(meetco, meet1, meet2, lambda); - } + mid_v3_v3v3(meetco, meet1, meet2); + if (r_sinratio) + /* ang1 should not be 0, but be paranoid */ + *r_sinratio = (ang1 == 0.0f) ? 1.0f : sinf(ang2) / sinf(ang1); + retval = true; } else if (ok1 && !ok2) { copy_v3_v3(meetco, meet1); @@ -1041,13 +978,7 @@ static void offset_on_edge_between( slide_dist(emid, v, e1->offset_r, meetco); } - /* offsets may have changed now */ - d = dist_to_line_v3(meetco, v->co, BM_edge_other_vert(e1->e, v)->co); - if (fabsf(d - e1->offset_r) > BEVEL_EPSILON) - e1->offset_r = d; - d = dist_to_line_v3(meetco, v->co, BM_edge_other_vert(e2->e, v)->co); - if (fabsf(d - e2->offset_l) > BEVEL_EPSILON) - e2->offset_l = d; + return retval; } /* Offset by e->offset in plane with normal plane_no, on left if left==true, @@ -1806,6 +1737,7 @@ static void build_boundary_terminal_edge(BevelParams *bp, BevVert *bv, EdgeHalf } } +#if 0 /* Return a value that is v if v is within BEVEL_MAX_ADJUST_PCT of the spec (assumed positive), * else clamp to make it at most that far away from spec */ static float clamp_adjust(float v, float spec) @@ -1819,6 +1751,7 @@ static float clamp_adjust(float v, float spec) else return v; } +#endif /* Make a circular list of BoundVerts for bv, each of which has the coordinates * of a vertex on the boundary of the beveled vertex bv->v. @@ -1835,11 +1768,10 @@ static float clamp_adjust(float v, float spec) static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) { MemArena *mem_arena = bp->mem_arena; - EdgeHalf *efirst, *e, *e2, *e3, *enip, *eip, *eother; + EdgeHalf *efirst, *e, *e2, *e3, *enip, *eip, *eon; BoundVert *v; - BevVert *bvother; VMesh *vm; - float co[3]; + float co[3], r; int nip, nnip; /* Current bevel does nothing if only one edge into a vertex */ @@ -1853,30 +1785,9 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) vm = bv->vmesh; - /* Find a beveled edge to be efirst. Then for each edge, try matching widths to other end. */ + /* Find a beveled edge to be efirst */ e = efirst = next_bev(bv, NULL); BLI_assert(e->is_bev); - do { - eother = find_other_end_edge_half(bp, e, &bvother); - if (eother && bvother->visited && bp->offset_type != BEVEL_AMT_PERCENT) { - /* try to keep bevel even by matching other end offsets */ - /* sometimes, adjustment can accumulate errors so use the bp->limit_offset to - * let user limit the adjustment to within a reasonable range around spec */ - if (bp->limit_offset) { - e->offset_l = clamp_adjust(eother->offset_r, e->offset_l_spec); - e->offset_r = clamp_adjust(eother->offset_l, e->offset_r_spec); - } - else { - e->offset_l = eother->offset_r; - e->offset_r = eother->offset_l; - } - } - else { - /* reset to user spec */ - e->offset_l = e->offset_l_spec; - e->offset_r = e->offset_r_spec; - } - } while ((e = e->next) != efirst); if (bv->selcount == 1) { /* special case: only one beveled edge in */ @@ -1890,6 +1801,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) e = efirst; do { BLI_assert(e->is_bev); + eon = NULL; /* Make the BoundVert for the right side of e; other side will be made * when the beveled edge to the left of e is handled. * Analyze edges until next beveled edge. @@ -1913,7 +1825,8 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) } else if (nnip > 0) { if (bp->loop_slide && nnip == 1 && good_offset_on_edge_between(e, e2, enip, bv->v)) { - offset_on_edge_between(bp, e, e2, enip, bv->v, co); + if (offset_on_edge_between(e, e2, enip, bv->v, co, &r)) + eon = enip; } else { offset_meet(e, e2, bv->v, NULL, true, co); @@ -1922,7 +1835,8 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) else { /* nip > 0 and nnip == 0 */ if (bp->loop_slide && nip == 1 && good_offset_on_edge_between(e, e2, eip, bv->v)) { - offset_on_edge_between(bp, e, e2, eip, bv->v, co); + if (offset_on_edge_between(e, e2, eip, bv->v, co, &r)) + eon = eip; } else { offset_meet(e, e2, bv->v, e->fnext, true, co); @@ -1933,6 +1847,9 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) v->efirst = e; v->elast = e2; v->ebev = e2; + v->eon = eon; + if (eon) + v->sinratio = r; e->rightv = v; e2->leftv = v; for (e3 = e->next; e3 != e2; e3 = e3->next) { @@ -1962,98 +1879,393 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) } } -/* Do a global pass to try to make offsets as even as possible. - * Consider this graph: - * nodes = BevVerts - * edges = { (u,v) } where u and v are nodes such that u and v - * are connected by a mesh edge that has at least one end - * whose offset does not match the user spec. - * - * Do a breadth-first search on this graph, starting from nodes - * that have any_adjust=true, and changing all - * not-already-changed offsets on EdgeHalfs to match the - * corresponding ones that changed on the other end. - * The graph is dynamic in the sense that having an offset that - * doesn't meet the user spec can be added as the search proceeds. - * We want this search to be deterministic (not dependent - * on order of processing through hash table), so as to avoid - * flicker to to different decisions made if search is different - * while dragging the offset number in the UI. So look for the - * lower vertex number when there is a choice of where to start. - * - * Note that this might not process all BevVerts, only the ones - * that need adjustment. - */ -static void adjust_offsets(BevelParams *bp) +#ifdef DEBUG_ADJUST +static void print_adjust_stats(BoundVert *vstart) { - BevVert *bv, *searchbv, *bvother; - int i, searchi; - GHashIterator giter; - EdgeHalf *e, *efirst, *eother; - GSQueue *q; - float max_rel_adj; + BoundVert *v; + EdgeHalf *eleft, *eright; + double even_residual2, spec_residual2; + double max_even_r, max_even_r_pct; + double max_spec_r, max_spec_r_pct; + double delta, delta_pct; + + printf("\nSolution analysis\n"); + even_residual2 = 0.0; + spec_residual2 = 0.0; + max_even_r = 0.0; + max_even_r_pct = 0.0; + max_spec_r = 0.0; + max_spec_r_pct = 0.0; + printf("width matching\n"); + v = vstart; + do { + if (v->adjchain != NULL) { + eright = v->efirst; + eleft = v->adjchain->elast; + delta = fabs(eright->offset_r - eleft->offset_l); + delta_pct = 100.0 * delta / eright->offset_r_spec; + printf("e%d r(%f) vs l(%f): abs(delta)=%f, delta_pct=%f\n", + BM_elem_index_get(eright->e), eright->offset_r, eleft->offset_l, delta, delta_pct); + even_residual2 += delta * delta; + if (delta > max_even_r) + max_even_r = delta; + if (delta_pct > max_even_r_pct) + max_even_r_pct = delta_pct; + } + v = v->adjchain; + } while (v && v != vstart); + + printf("spec matching\n"); + v = vstart; + do { + if (v->adjchain != NULL) { + eright = v->efirst; + eleft = v->adjchain->elast; + delta = eright->offset_r - eright->offset_r_spec; + delta_pct = 100.0 * delta / eright->offset_r_spec; + printf("e%d r(%f) vs r spec(%f): delta=%f, delta_pct=%f\n", + BM_elem_index_get(eright->e), eright->offset_r, eright->offset_r_spec, delta, delta_pct); + spec_residual2 += delta * delta; + delta = fabs(delta); + delta_pct = fabs(delta_pct); + if (delta > max_spec_r) + max_spec_r = delta; + if (delta_pct > max_spec_r_pct) + max_spec_r_pct = delta_pct; + + delta = eleft->offset_l - eleft->offset_l_spec; + delta_pct = 100.0 * delta / eright->offset_l_spec; + printf("e%d l(%f) vs l spec(%f): delta=%f, delta_pct=%f\n", + BM_elem_index_get(eright->e), eleft->offset_l, eleft->offset_l_spec, delta, delta_pct); + spec_residual2 += delta * delta; + delta = fabs(delta); + delta_pct = fabs(delta_pct); + if (delta > max_spec_r) + max_spec_r = delta; + if (delta_pct > max_spec_r_pct) + max_spec_r_pct = delta_pct; + } + v = v->adjchain; + } while (v && v != vstart); + + printf("Analysis Result:\n"); + printf("even residual2 = %f, spec residual2 = %f\n", even_residual2, spec_residual2); + printf("max even delta = %f, max as percent of spec = %f\n", max_even_r, max_even_r_pct); + printf("max spec delta = %f, max as percent of spec = %f\n", max_spec_r, max_spec_r_pct); +} +#endif - BLI_assert(!bp->vertex_only); - GHASH_ITER(giter, bp->vert_hash) { - bv = BLI_ghashIterator_getValue(&giter); - bv->visited = false; +#ifdef FAST_ADJUST_CODE +/* This code uses a direct solution to the adjustment problem for chains and certain cycles. + * It is a two-step approach: first solve for the exact solution of the 'match widths' constraints + * using the one degree of freedom that allows for expressing all other widths in terms of that. + * And then minimize the spec-matching constraints using the derivative of the least squares + * residual in terms of that one degree of freedom. + * Unfortunately, the results are in some cases worse than the general least squares solution + * for the combined (with weights) problem, so this code is not used. + * But keep it here for a while in case peformance issues demand that it be used sometimes. */ +static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscycle) +{ + BoundVert *v; + EdgeHalf *eleft, *eright; + float *g; + float *g_prod; + float gprod, gprod_sum, spec_sum, p; + int i; + + g = MEM_mallocN(np * sizeof(float), "beveladjust"); + g_prod = MEM_mallocN(np * sizeof(float), "beveladjust"); + + v = vstart; + spec_sum = 0.0f; + i = 0; + do { + g[i] = v->sinratio; + if (iscycle || v->adjchain != NULL) { + spec_sum += v->efirst->offset_r; + } + else { + spec_sum += v->elast->offset_l; + } + i++; + v = v->adjchain; + } while (v && v != vstart); + + gprod = 1.00f; + gprod_sum = 1.0f; + for (i = np - 1; i > 0; i--) { + gprod *= g[i]; + g_prod[i] = gprod; + gprod_sum += gprod; + } + g_prod[0] = 1.0f; + if (iscycle) { + gprod *= g[0]; + if (fabs(gprod - 1.0f) > BEVEL_EPSILON) { + /* fast cycle calc only works if total product is 1 */ + MEM_freeN(g); + MEM_freeN(g_prod); + return false; + } } + if (gprod_sum == 0.0f) { + MEM_freeN(g); + MEM_freeN(g_prod); + return false; + } + p = spec_sum / gprod_sum; - q = BLI_gsqueue_new(sizeof(BevVert *)); - /* the following loop terminates because at least one node is visited each time */ - for (;;) { - /* look for root of a connected component in search graph */ - searchbv = NULL; - searchi = -1; - GHASH_ITER(giter, bp->vert_hash) { - bv = BLI_ghashIterator_getValue(&giter); - if (!bv->visited && max_edge_half_offset_rel_change(bv) > 0.0f) { - i = BM_elem_index_get(bv->v); - if (!searchbv || i < searchi) { - searchbv = bv; - searchi = i; - } + /* apply the new offsets */ + v = vstart; + i = 0; + do { + if (iscycle || v->adjchain != NULL) { + eright = v->efirst; + eleft = v->elast; + eright->offset_r = g_prod[(i + 1) % np] * p; + if (iscycle || v != vstart) { + eleft->offset_l = v->sinratio * eright->offset_r; } } - if (searchbv == NULL) - break; + else { + /* not a cycle, and last of chain */ + eleft = v->elast; + eleft->offset_l = p; + } + i++; + v = v->adjchain; + } while (v && v != vstart); - BLI_gsqueue_push(q, &searchbv); - while (!BLI_gsqueue_is_empty(q)) { - BLI_gsqueue_pop(q, &bv); - /* If do this check, don't have to check for already-on-queue before push, below */ - if (bv->visited) - continue; - bv->visited = true; - build_boundary(bp, bv, false); - - e = efirst = &bv->edges[0]; - do { - eother = find_other_end_edge_half(bp, e, &bvother); - if (eother && !bvother->visited && edge_half_offset_changed(e)) { - BLI_gsqueue_push(q, &bvother); + MEM_freeN(g); + MEM_freeN(g_prod); + return true; +} +#endif + +/* Adjust the offsets for a single cycle or chain. + * For chains and some cycles, a fast solution exists. + * Otherwise, we set up and solve a linear least squares problem + * that tries to minimize the squared differences of lengths + * at each end of an edge, and (with smaller weight) the + * squared differences of the offsets from their specs. + */ +static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle) +{ + BoundVert *v; + EdgeHalf *eleft, *eright, *enextleft; + LinearSolver *solver; + double weight, val; + int i, np, nrows, row; + + np = 0; +#ifdef DEBUG_ADJUST + printf("\nadjust the %s (with eigen)\n", iscycle ? "cycle" : "chain"); +#endif + v = vstart; + do { +#ifdef DEBUG_ADJUST + eleft = v->elast; + eright = v->efirst; + printf(" (left=e%d, right=e%d)", BM_elem_index_get(eleft->e), BM_elem_index_get(eright->e)); +#endif + np++; + v = v->adjchain; + } while (v && v != vstart); +#ifdef DEBUG_ADJUST + printf(" -> %d parms\n", np); +#endif + +#ifdef FAST_ADJUST_CODE + if (adjust_the_cycle_or_chain_fast(vstart, np, iscycle)) + return; +#endif + + nrows = iscycle ? 3 * np : 3 * np - 3; + + solver = EIG_linear_least_squares_solver_new(nrows, np, 1); + + v = vstart; + i = 0; + weight = BEVEL_MATCH_SPEC_WEIGHT; /* sqrt of factor to weight down importance of spec match */ + do { + /* except at end of chain, v's indep variable is offset_r of v->efirst */ + if (iscycle || i < np - 1) { + eright = v->efirst; + eleft = v->elast; + enextleft = v->adjchain->elast; +#ifdef DEBUG_ADJUST + printf("p%d: e%d->offset_r = %f\n", i, BM_elem_index_get(eright->e), eright->offset_r); + if (iscycle || v != vstart) + printf(" dependent: e%d->offset_l = %f * p%d\n", BM_elem_index_get(eleft->e), v->sinratio, i); +#endif + + /* residue i: width difference between eright and eleft of next */ + EIG_linear_solver_matrix_add(solver, i, i, 1.0); + EIG_linear_solver_right_hand_side_add(solver, 0, i, 0.0); + if (iscycle) { + EIG_linear_solver_matrix_add(solver, i > 0 ? i - 1 : np - 1, i, -v->sinratio); + } + else { + if (i > 0) { + EIG_linear_solver_matrix_add(solver, i - 1, i, -v->sinratio); } - } while ((e = e->next) != efirst); + } + + /* residue np + 2*i (if cycle) else np - 1 + 2*i: + * right offset for parm i matches its spec; weighted */ + row = iscycle ? np + 2 * i : np - 1 + 2 * i; + EIG_linear_solver_matrix_add(solver, row, i, weight); + EIG_linear_solver_right_hand_side_add(solver, 0, row, weight * eright->offset_r); +#ifdef DEBUG_ADJUST + printf("b[%d]=%f * %f, for e%d->offset_r\n", row, weight, eright->offset_r, BM_elem_index_get(eright->e)); +#endif + + /* residue np + 2*i + 1 (if cycle) else np - 1 + 2*i + 1: + * left offset for parm i matches its spec; weighted */ + row = row + 1; + EIG_linear_solver_matrix_add(solver, row, (i == np - 1) ? 0 : i + 1, weight * v->adjchain->sinratio); + EIG_linear_solver_right_hand_side_add(solver, 0, row, weight * enextleft->offset_l); +#ifdef DEBUG_ADJUST + printf("b[%d]=%f * %f, for e%d->offset_l\n", row, weight, enextleft->offset_l, + BM_elem_index_get(enextleft->e)); +#endif } - } - BLI_gsqueue_free(q); + else { + /* not a cycle, and last of chain */ + eleft = v->elast; +#ifdef DEBUG_ADJUST + printf("p%d: e%d->offset_l = %f\n", i, BM_elem_index_get(eleft->e), eleft->offset_l); +#endif + /* second part of residue i for last i */ + EIG_linear_solver_matrix_add(solver, i - 1, i, -1.0); + } + i++; + v = v->adjchain; + } while (v && v != vstart); + EIG_linear_solver_solve(solver); +#ifdef DEBUG_ADJUST + /* Note: this print only works after solve, but by that time b has been cleared */ + EIG_linear_solver_print_matrix(solver); + printf("\nSolution:\n"); + for (i = 0; i < np; i++) + printf("p%d = %f\n", i, EIG_linear_solver_variable_get(solver, 0, i)); +#endif - /* Should we auto-limit the error accumulation? Typically, spirals can lead to 100x relative adjustments, - * and somewhat hacky mechanism of using bp->limit_offset to indicate "clamp the adjustments" is not - * obvious to users, who almost certainly want clamping in this situation. - * The reason not to clamp always is that some models work better without it (e.g., Bent_test in regression - * suite, where relative adjust maximum is about .6). */ - if (!bp->limit_offset) { - max_rel_adj = 0.0f; - GHASH_ITER(giter, bp->vert_hash) { - bv = BLI_ghashIterator_getValue(&giter); - max_rel_adj = max_ff(max_rel_adj, max_edge_half_offset_rel_change(bv)); + /* Use the solution to set new widths */ + v = vstart; + i = 0; + do { + val = EIG_linear_solver_variable_get(solver, 0, i); + if (iscycle || i < np - 1) { + eright = v->efirst; + eleft = v->elast; + eright->offset_r = (float)val; +#ifdef DEBUG_ADJUST + printf("e%d->offset_r = %f\n", BM_elem_index_get(eright->e), eright->offset_r); +#endif + if (iscycle || v != vstart) { + eleft->offset_l = (float)(v->sinratio * val); +#ifdef DEBUG_ADJUST + printf("e%d->offset_l = %f\n", BM_elem_index_get(eleft->e), eleft->offset_l); +#endif + } } - if (max_rel_adj > BEVEL_MAX_AUTO_ADJUST_PCT / 100.0f) { - bp->limit_offset = true; - adjust_offsets(bp); - bp->limit_offset = false; + else { + /* not a cycle, and last of chain */ + eleft = v->elast; + eleft->offset_l = (float)val; +#ifdef DEBUG_ADJUST + printf("e%d->offset_l = %f\n", BM_elem_index_get(eleft->e), eleft->offset_l); +#endif } + i++; + v = v->adjchain; + } while (v && v != vstart); + +#ifdef DEBUG_ADJUST + print_adjust_stats(vstart); + EIG_linear_solver_print_matrix(solver); +#endif + + EIG_linear_solver_delete(solver); +} + +/* Adjust the offsets to try to make them, as much as possible, + * have even-width bevels with offsets that match their specs. + * The problem that we can try to amelieroate is that when loop slide + * is active, the meet point will probably not be the one that makes + * both sides have their specified width. And because both ends may be + * on loop slide edges, the widths at each end could be different. + * + * It turns out that the dependent offsets either form chains or + * cycles, and we can process each of those separatey. + */ +static void adjust_offsets(BevelParams *bp) +{ + BevVert *bv, *bvcur; + BoundVert *v, *vanchor, *vchainstart, *vnext; + EdgeHalf *enext; + GHashIterator giter; + bool iscycle; + + /* find and process chains and cycles of unvisited BoundVerts that have eon set */ + GHASH_ITER(giter, bp->vert_hash) { + bv = bvcur = BLI_ghashIterator_getValue(&giter); + vanchor = bv->vmesh->boundstart; + do { + if (vanchor->visited || !vanchor->eon) + continue; + + /* Find one of (1) a cycle that starts and ends at v + * where each v has v->eon set and had not been visited before; + * or (2) a chain of v's where the start and end of the chain do not have + * v->eon set but all else do. + * It is OK for the first and last elements to + * have been visited before, but not any of the inner ones. + * We chain the v's together through v->adjchain, and are following + * them in left->right direction, meaning that the left side of one edge + * pairs with the right side of the next edge in the cycle or chain. */ + + /* first follow paired edges in left->right direction */ + v = vchainstart = vanchor; + iscycle = false; + while (v->eon && !v->visited && !iscycle) { + enext = find_other_end_edge_half(bp, v->efirst, &bvcur); + BLI_assert(enext != NULL); + vnext = enext->leftv; + v->adjchain = vnext; + v->visited = true; + if (vnext->visited) { + if (vnext != vchainstart) { + break; + } + adjust_the_cycle_or_chain(vchainstart, true); + iscycle = true; + } + v = vnext; + } + if (!iscycle) { + /* right->left direction, changing vchainstart at each step */ + v = vchainstart; + bvcur = bv; + do { + enext = find_other_end_edge_half(bp, v->elast, &bvcur); + BLI_assert(enext != NULL); + vnext = enext->rightv; + vnext->adjchain = v; + vchainstart = vnext; + v->visited = true; + v = vnext; + } while (!v->visited && v->eon); + adjust_the_cycle_or_chain(vchainstart, false); + } + } while ((vanchor = vanchor->next) != bv->vmesh->boundstart); + } + + /* Rebuild boundaries with new width specs */ + GHASH_ITER(giter, bp->vert_hash) { + bv = BLI_ghashIterator_getValue(&giter); + build_boundary(bp, bv, false); } } @@ -2997,7 +3209,7 @@ static void build_center_ngon(BMesh *bm, BevVert *bv, int mat_nr) BLI_array_append(ve, NULL); } } while ((v = v->next) != vm->boundstart); - bev_create_ngon(bm, vv, BLI_array_count(vv), vf, frep, ve, mat_nr, true); + bev_create_ngon(bm, vv, BLI_array_len(vv), vf, frep, ve, mat_nr, true); BLI_array_free(vv); BLI_array_free(vf); @@ -3041,6 +3253,173 @@ static void build_square_in_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv, VMesh } } +/* copy whichever of a and b is closer to v into r */ +static void closer_v3_v3v3v3(float r[3], float a[3], float b[3], float v[3]) +{ + if (len_squared_v3v3(a, v) <= len_squared_v3v3(b, v)) + copy_v3_v3(r, a); + else + copy_v3_v3(r, b); +} + +/* Special case of VMesh when profile == 1 and there are 3 or more beveled edges. + * We want the effect of parallel offset lines (n/2 of them) on each side of the center, for even n. + * Wherever they intersect with each other between two successive beveled edges, those intersections + * are part of the vmesh rings. + * We have to move the boundary edges too -- the usual method is to make one profile plane between + * successive BoundVerts, but for the effect we want here, there will be two planes, one on each side + * of the original edge. + */ +static VMesh *square_out_adj_vmesh(BevelParams *bp, BevVert *bv) +{ + int n, ns, ns2, odd, i, j, k, ikind, im1, clstride; + float bndco[3], dir1[3], dir2[3], co1[3], co2[3], meet1[3], meet2[3], v1co[3], v2co[3]; + float *on_edge_cur, *on_edge_prev, *p; + float ns2inv, finalfrac, ang; + BoundVert *bndv; + EdgeHalf *e1, *e2; + VMesh *vm; + float *centerline; + + n = bv->vmesh->count; + ns = bv->vmesh->seg; + ns2 = ns / 2; + odd = ns % 2; + ns2inv = 1.0f / (float) ns2; + vm = new_adj_vmesh(bp->mem_arena, n, ns, bv->vmesh->boundstart); + clstride = 3 * (ns2 + 1); + centerline = MEM_mallocN(clstride * n * sizeof(float), "bevel"); + + /* find on_edge, place on bndv[i]'s elast where offset line would meet, + * averaging with position where next sector's offset line would meet */ + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + copy_v3_v3(bndco, bndv->nv.co); + e1 = bndv->efirst; + e2 = bndv->elast; + sub_v3_v3v3(dir1, e1->e->v1->co, e1->e->v2->co); + sub_v3_v3v3(dir2, e2->e->v1->co, e2->e->v2->co); + add_v3_v3v3(co1, bndco, dir1); + add_v3_v3v3(co2, bndco, dir2); + /* intersect e1 with line through bndv parallel to e2 to get v1co */ + ikind = isect_line_line_v3(e1->e->v1->co, e1->e->v2->co, bndco, co2, meet1, meet2); + + if (ikind == 0) { + /* Placeholder: this should get eliminated by min dist test with adjacent edge */ + mid_v3_v3v3(v1co, e1->e->v1->co, e1->e->v2->co); + } + else { + /* if the lines are skew (ikind == 2), want meet1 which is on e1 */ + copy_v3_v3(v1co, meet1); + } + /* intersect e2 with line through bndv parallel to e1 to get v2co */ + ikind = isect_line_line_v3(e2->e->v1->co, e2->e->v2->co, bndco, co1, meet1, meet2); + if (ikind == 0) { + mid_v3_v3v3(v2co, e2->e->v1->co, e2->e->v2->co); + } + else { + copy_v3_v3(v2co, meet1); + } + + /* want on_edge[i] to be min dist to bv->v of v2co and the v1co of next iteration */ + on_edge_cur = centerline + clstride * i; + on_edge_prev = centerline + clstride * ((i == 0) ? n - 1 : i - 1); + if (i == 0) { + copy_v3_v3(on_edge_cur, v2co); + copy_v3_v3(on_edge_prev, v1co); + } + else if (i == n - 1) { + closer_v3_v3v3v3(on_edge_cur, on_edge_cur, v2co, bv->v->co); + closer_v3_v3v3v3(on_edge_prev, on_edge_prev, v1co, bv->v->co); + } + else { + copy_v3_v3(on_edge_cur, v2co); + closer_v3_v3v3v3(on_edge_prev, on_edge_prev, v1co, bv->v->co); + } + bndv = bndv->next; + } + + /* fill in rest of centerlines by interpolation */ + copy_v3_v3(co2, bv->v->co); + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + if (odd) { + ang = 0.5f * angle_v3v3v3(bndv->nv.co, co1, bndv->next->nv.co); + if (ang > BEVEL_SMALL_ANG) { + /* finalfrac is length along arms of isoceles triangle with top angle 2*ang + * such that the base of the triangle is 1. + * This is used in interpolation along centerline in odd case. + * To avoid too big a drop from bv, cap finalfrac a 0.8 arbitrarily */ + finalfrac = 0.5f / sin(ang); + if (finalfrac > 0.8f) + finalfrac = 0.8f; + } + else { + finalfrac = 0.8f; + } + ns2inv = 1.0f / (ns2 + finalfrac); + } + + p = centerline + clstride * i; + copy_v3_v3(co1, p); + p += 3; + for (j = 1; j <= ns2; j++) { + interp_v3_v3v3(p, co1, co2, j * ns2inv); + p += 3; + } + bndv = bndv->next; + } + + /* coords of edges and mid or near-mid line */ + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + copy_v3_v3(co1, bndv->nv.co); + copy_v3_v3(co2, centerline + clstride * (i == 0 ? n - 1 : i - 1)); + for (j = 0; j < ns2 + odd; j++) { + interp_v3_v3v3(mesh_vert(vm, i, j, 0)->co, co1, co2, j * ns2inv); + } + copy_v3_v3(co2, centerline + clstride * i); + for (k = 1; k <= ns2; k++) { + interp_v3_v3v3(mesh_vert(vm, i, 0, k)->co, co1, co2, k * ns2inv); + } + bndv = bndv->next; + } + if (!odd) + copy_v3_v3(mesh_vert(vm, 0, ns2, ns2)->co, bv->v->co); + vmesh_copy_equiv_verts(vm); + + /* fill in interior points by interpolation from edges to centerlines */ + bndv = vm->boundstart; + for (i = 0; i < n; i++) { + im1 = (i == 0) ? n - 1 : i - 1; + for (j = 1; j < ns2 + odd; j++) { + for (k = 1; k <= ns2; k++) { + ikind = isect_line_line_v3( + mesh_vert(vm, i, 0, k)->co, centerline + clstride * im1 + 3 * k, + mesh_vert(vm, i, j, 0)->co, centerline + clstride * i + 3 * j, + meet1, meet2); + if (ikind == 0) { + /* how can this happen? fall back on interpolation in one direction if it does */ + interp_v3_v3v3(mesh_vert(vm, i, j, k)->co, + mesh_vert(vm, i, 0, k)->co, centerline + clstride * im1 + 3 * k, j * ns2inv); + } + else if (ikind == 1) { + copy_v3_v3(mesh_vert(vm, i, j, k)->co, meet1); + } + else { + mid_v3_v3v3(mesh_vert(vm, i, j, k)->co, meet1, meet2); + } + } + } + bndv = bndv->next; + } + + vmesh_copy_equiv_verts(vm); + + MEM_freeN(centerline); + return vm; +} + /* * Given that the boundary is built and the boundary BMVerts have been made, * calculate the positions of the interior mesh points for the M_ADJ pattern, @@ -3063,9 +3442,13 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv) odd = ns % 2; BLI_assert(n >= 3 && ns > 1); + vpipe = pipe_test(bv); - if (vpipe) { + if (bp->pro_super_r == PRO_SQUARE_R && bv->selcount >= 3 && !odd) { + vm1 = square_out_adj_vmesh(bp, bv); + } + else if (vpipe) { vm1 = pipe_adj_vmesh(bp, bv, vpipe); } else if (tri_corner_test(bp, bv)) { @@ -3577,7 +3960,7 @@ static int bevel_edge_order_extend(BMesh *bm, BevVert *bv, int i) BLI_array_append(sucs, bme2); } } - nsucs = BLI_array_count(sucs); + nsucs = BLI_array_len(sucs); bestj = j = i; for (sucindex = 0; sucindex < nsucs; sucindex++) { @@ -3590,7 +3973,7 @@ static int bevel_edge_order_extend(BMesh *bm, BevVert *bv, int i) tryj = bevel_edge_order_extend(bm, bv, j + 1); if (tryj > bestj || (tryj == bestj && edges_face_connected_at_vert(bv->edges[tryj].e, bv->edges[0].e))) { bestj = tryj; - BLI_array_empty(save_path); + BLI_array_clear(save_path); for (k = j + 1; k <= bestj; k++) { BLI_array_append(save_path, bv->edges[k].e); } @@ -4117,15 +4500,15 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f) } } if (do_rebuild) { - n = BLI_array_count(vv); + n = BLI_array_len(vv); f_new = bev_create_ngon(bm, vv, n, NULL, f, NULL, -1, true); - for (k = 0; k < BLI_array_count(vv_fix); k++) { + for (k = 0; k < BLI_array_len(vv_fix); k++) { bev_merge_uvs(bm, vv_fix[k]); } /* copy attributes from old edges */ - BLI_assert(n == BLI_array_count(ee)); + BLI_assert(n == BLI_array_len(ee)); bme_prev = ee[n - 1]; for (k = 0; k < n; k++) { bme_new = BM_edge_exists(vv[k], vv[(k + 1) % n]); @@ -4983,6 +5366,7 @@ void BM_mesh_bevel( bp.use_weights = use_weights; bp.loop_slide = loop_slide; bp.limit_offset = limit_offset; + bp.offset_adjust = true; bp.dvert = dvert; bp.vertex_group = vertex_group; bp.mat_nr = mat; @@ -5019,7 +5403,7 @@ void BM_mesh_bevel( } /* Perhaps do a pass to try to even out widths */ - if (!bp.vertex_only) { + if (!bp.vertex_only && bp.offset_adjust) { adjust_offsets(&bp); } diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index 0a1271c2aa9..c1b2bc2625b 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -38,8 +38,8 @@ #include "BLI_alloca.h" #include "BLI_memarena.h" #include "BLI_edgehash.h" -#include "BLI_polyfill2d.h" -#include "BLI_polyfill2d_beautify.h" +#include "BLI_polyfill_2d.h" +#include "BLI_polyfill_2d_beautify.h" #include "BLI_utildefines_stack.h" @@ -1357,7 +1357,7 @@ void BM_mesh_decimate_collapse( (BLI_heap_node_value(BLI_heap_top(eheap)) != COST_INVALID)) { // const float value = BLI_heap_node_value(BLI_heap_top(eheap)); - BMEdge *e = BLI_heap_popmin(eheap); + BMEdge *e = BLI_heap_pop_min(eheap); float optimize_co[3]; BLI_assert(BM_elem_index_get(e) < tot_edge_orig); /* handy to detect corruptions elsewhere */ @@ -1388,7 +1388,7 @@ void BM_mesh_decimate_collapse( * - edges sharing a vertex are ignored, so the pivot vertex isnt moved to one side. */ - BMEdge *e = BLI_heap_popmin(eheap); + BMEdge *e = BLI_heap_pop_min(eheap); const int e_index = BM_elem_index_get(e); const int e_index_mirr = edge_symmetry_map[e_index]; BMEdge *e_mirr = NULL; diff --git a/source/blender/bmesh/tools/bmesh_edgenet.c b/source/blender/bmesh/tools/bmesh_edgenet.c index 193a032b46e..df9d07036af 100644 --- a/source/blender/bmesh/tools/bmesh_edgenet.c +++ b/source/blender/bmesh/tools/bmesh_edgenet.c @@ -335,7 +335,7 @@ static LinkNode *bm_edgenet_path_calc( BLI_linklist_free_pool(v_ls_next, NULL, path_pool); BLI_linklist_free_pool(v_ls_prev, NULL, path_pool); - // BLI_assert(BLI_mempool_count(path_pool) == 0); + // BLI_assert(BLI_mempool_len(path_pool) == 0); path_len = bm_edgenet_path_from_pass(e_found->v1, &path, vnet_info, path_pool); BLI_linklist_reverse(&path); @@ -505,7 +505,7 @@ void BM_mesh_edgenet( } BLI_linklist_free_pool(path, NULL, path_pool); - BLI_assert(BLI_mempool_count(path_pool) == 0); + BLI_assert(BLI_mempool_len(path_pool) == 0); } bm->elem_index_dirty |= BM_FACE | BM_LOOP; diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c index 82545a5e011..cc8511c65f1 100644 --- a/source/blender/bmesh/tools/bmesh_intersect.c +++ b/source/blender/bmesh/tools/bmesh_intersect.c @@ -1265,8 +1265,8 @@ bool BM_mesh_intersect( } } - splice_ls = MEM_mallocN(BLI_gset_size(s.wire_edges) * sizeof(*splice_ls), __func__); - STACK_INIT(splice_ls, BLI_gset_size(s.wire_edges)); + splice_ls = MEM_mallocN(BLI_gset_len(s.wire_edges) * sizeof(*splice_ls), __func__); + STACK_INIT(splice_ls, BLI_gset_len(s.wire_edges)); for (node = s.vert_dissolve; node; node = node->next) { BMEdge *e_pair[2]; @@ -1669,7 +1669,7 @@ bool BM_mesh_intersect( } } - has_edit_isect = (BLI_ghash_size(s.face_edges) != 0); + has_edit_isect = (BLI_ghash_len(s.face_edges) != 0); /* cleanup */ BLI_ghash_free(s.edgetri_cache, NULL, NULL); diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c index 85c591b6684..cc5ac6dd8ce 100644 --- a/source/blender/bmesh/tools/bmesh_path.c +++ b/source/blender/bmesh/tools/bmesh_path.c @@ -174,7 +174,7 @@ LinkNode *BM_mesh_calc_path_vert( cost[BM_elem_index_get(v_src)] = 0.0f; while (!BLI_heap_is_empty(heap)) { - v = BLI_heap_popmin(heap); + v = BLI_heap_pop_min(heap); if (v == v_dst) break; @@ -346,7 +346,7 @@ LinkNode *BM_mesh_calc_path_edge( cost[BM_elem_index_get(e_src)] = 0.0f; while (!BLI_heap_is_empty(heap)) { - e = BLI_heap_popmin(heap); + e = BLI_heap_pop_min(heap); if (e == e_dst) break; @@ -532,7 +532,7 @@ LinkNode *BM_mesh_calc_path_face( cost[BM_elem_index_get(f_src)] = 0.0f; while (!BLI_heap_is_empty(heap)) { - f = BLI_heap_popmin(heap); + f = BLI_heap_pop_min(heap); if (f == f_dst) break; diff --git a/source/blender/bmesh/tools/bmesh_region_match.c b/source/blender/bmesh/tools/bmesh_region_match.c index 2abf8f2c46e..e83ba73ad01 100644 --- a/source/blender/bmesh/tools/bmesh_region_match.c +++ b/source/blender/bmesh/tools/bmesh_region_match.c @@ -421,8 +421,8 @@ static void bm_uuidwalk_rehash( UUID_Int *uuid_store; uint i; - uint rehash_store_len_new = MAX2(BLI_ghash_size(uuidwalk->verts_uuid), - BLI_ghash_size(uuidwalk->faces_uuid)); + uint rehash_store_len_new = MAX2(BLI_ghash_len(uuidwalk->verts_uuid), + BLI_ghash_len(uuidwalk->faces_uuid)); bm_uuidwalk_rehash_reserve(uuidwalk, rehash_store_len_new); uuid_store = uuidwalk->cache.rehash_store; @@ -520,8 +520,8 @@ static void bm_uuidwalk_pass_add( verts_uuid_pass = uuidwalk->cache.verts_uuid; faces_step_next = uuidwalk->cache.faces_step; - BLI_assert(BLI_ghash_size(verts_uuid_pass) == 0); - BLI_assert(BLI_gset_size(faces_step_next) == 0); + BLI_assert(BLI_ghash_len(verts_uuid_pass) == 0); + BLI_assert(BLI_gset_len(faces_step_next) == 0); /* Add the face_step data from connected faces, creating new passes */ fstep = BLI_mempool_alloc(uuidwalk->step_pool); @@ -659,7 +659,7 @@ static bool bm_uuidwalk_facestep_begin( LinkNode *f_link, *f_link_next, **f_link_prev_p; bool ok = false; - BLI_assert(BLI_ghash_size(uuidwalk->cache.faces_from_uuid) == 0); + BLI_assert(BLI_ghash_len(uuidwalk->cache.faces_from_uuid) == 0); BLI_assert(BLI_listbase_is_empty(&fstep->items)); f_link_prev_p = &fstep->faces; @@ -864,7 +864,7 @@ static BMFace **bm_mesh_region_match_pair( break; } - found = (BLI_ghash_size(w_dst->faces_uuid) == faces_src_region_len); + found = (BLI_ghash_len(w_dst->faces_uuid) == faces_src_region_len); if (found) { break; } @@ -877,7 +877,7 @@ static BMFace **bm_mesh_region_match_pair( if (found) { GHashIterator gh_iter; - const uint faces_result_len = BLI_ghash_size(w_dst->faces_uuid); + const uint faces_result_len = BLI_ghash_len(w_dst->faces_uuid); uint i; faces_result = MEM_mallocN(sizeof(*faces_result) * (faces_result_len + 1), __func__); diff --git a/source/blender/bmesh/tools/bmesh_separate.c b/source/blender/bmesh/tools/bmesh_separate.c index 287b4125330..b3d0c339885 100644 --- a/source/blender/bmesh/tools/bmesh_separate.c +++ b/source/blender/bmesh/tools/bmesh_separate.c @@ -122,7 +122,7 @@ void BM_mesh_separate_faces( /* Perform the split */ BM_face_loop_separate_multi(bm, loop_split.data, loop_split.count); - BLI_buffer_empty(&loop_split); + BLI_buffer_clear(&loop_split); } } while ((l_iter = l_iter->next) != l_first); } diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c index bd201fa89bf..a3a3355d20f 100644 --- a/source/blender/bmesh/tools/bmesh_triangulate.c +++ b/source/blender/bmesh/tools/bmesh_triangulate.c @@ -38,8 +38,8 @@ #include "BLI_linklist.h" /* only for defines */ -#include "BLI_polyfill2d.h" -#include "BLI_polyfill2d_beautify.h" +#include "BLI_polyfill_2d.h" +#include "BLI_polyfill_2d_beautify.h" #include "bmesh.h" |