diff options
Diffstat (limited to 'source/blender/bmesh/intern')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_construct.c | 88 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_edgeloop.c | 4 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_interp.c | 6 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_marking.c | 4 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mods.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_opdefines.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_operator_api.h | 6 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 107 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.h | 5 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon_edgenet.c | 10 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_structure.h | 4 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_walkers_impl.c | 2 |
14 files changed, 146 insertions, 98 deletions
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 224f6ad1e5c..c8eab9c4b8c 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -390,79 +390,13 @@ void BM_verts_sort_radial_plane(BMVert **vert_arr, int len) struct SortIntByFloat *vang = BLI_array_alloca(vang, len); BMVert **vert_arr_map = BLI_array_alloca(vert_arr_map, len); - float totv_inv = 1.0f / (float)len; - int i = 0; + float nor[3], cent[3]; + int index_tangent = 0; + BM_verts_calc_normal_from_cloud_ex(vert_arr, len, nor, cent, &index_tangent); + const float *far = vert_arr[index_tangent]->co; - float cent[3], nor[3]; - - const float *far = NULL, *far_cross = NULL; - - float far_vec[3]; - float far_cross_vec[3]; - float sign_vec[3]; /* work out if we are pos/neg angle */ - - float far_dist_sq, far_dist_max_sq; - float far_cross_dist, far_cross_best = 0.0f; - - /* get the center point and collect vector array since we loop over these a lot */ - zero_v3(cent); - for (i = 0; i < len; i++) { - madd_v3_v3fl(cent, vert_arr[i]->co, totv_inv); - } - - /* find the far point from cent */ - far_dist_max_sq = 0.0f; - for (i = 0; i < len; i++) { - far_dist_sq = len_squared_v3v3(vert_arr[i]->co, cent); - if (far_dist_sq > far_dist_max_sq || far == NULL) { - far = vert_arr[i]->co; - far_dist_max_sq = far_dist_sq; - } - } - - sub_v3_v3v3(far_vec, far, cent); - // far_dist = len_v3(far_vec); /* real dist */ /* UNUSED */ - - /* --- */ - - /* find a point 90deg about to compare with */ - far_cross_best = 0.0f; - for (i = 0; i < len; i++) { - - if (far == vert_arr[i]->co) { - continue; - } - - sub_v3_v3v3(far_cross_vec, vert_arr[i]->co, cent); - far_cross_dist = normalize_v3(far_cross_vec); - - /* more of a weight then a distance */ - far_cross_dist = ( - /* First we want to have a value close to zero mapped to 1. */ - 1.0f - fabsf(dot_v3v3(far_vec, far_cross_vec)) * - /* Second we multiply by the distance - * so points close to the center are not preferred. */ - far_cross_dist); - - if (far_cross_dist > far_cross_best || far_cross == NULL) { - far_cross = vert_arr[i]->co; - far_cross_best = far_cross_dist; - } - } - - sub_v3_v3v3(far_cross_vec, far_cross, cent); - - /* --- */ - - /* now we have 2 vectors we can have a cross product */ - cross_v3_v3v3(nor, far_vec, far_cross_vec); - normalize_v3(nor); - cross_v3_v3v3(sign_vec, far_vec, nor); /* this vector should match 'far_cross_vec' closely */ - - /* --- */ - - /* now calculate every points angle around the normal (signed) */ - for (i = 0; i < len; i++) { + /* Now calculate every points angle around the normal (signed). */ + for (int i = 0; i < len; i++) { vang[i].sort_value = angle_signed_on_axis_v3v3v3_v3(far, cent, vert_arr[i]->co, nor); vang[i].data = i; vert_arr_map[i] = vert_arr[i]; @@ -473,7 +407,7 @@ void BM_verts_sort_radial_plane(BMVert **vert_arr, int len) /* --- */ - for (i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { vert_arr[i] = vert_arr_map[vang[i].data]; } } @@ -487,7 +421,7 @@ static void bm_vert_attrs_copy(BMesh *source_mesh, uint64_t cd_mask) { if ((source_mesh == target_mesh) && (source_vertex == target_vertex)) { - BLI_assert(!"BMVert: source and targer match"); + BLI_assert(!"BMVert: source and target match"); return; } if ((cd_mask & CD_MASK_NORMAL) == 0) { @@ -507,7 +441,7 @@ static void bm_edge_attrs_copy(BMesh *source_mesh, uint64_t UNUSED(cd_mask)) { if ((source_mesh == target_mesh) && (source_edge == target_edge)) { - BLI_assert(!"BMEdge: source and targer match"); + BLI_assert(!"BMEdge: source and target match"); return; } CustomData_bmesh_free_block_data(&target_mesh->edata, target_edge->head.data); @@ -522,7 +456,7 @@ static void bm_loop_attrs_copy(BMesh *source_mesh, uint64_t UNUSED(cd_mask)) { if ((source_mesh == target_mesh) && (source_loop == target_loop)) { - BLI_assert(!"BMLoop: source and targer match"); + BLI_assert(!"BMLoop: source and target match"); return; } CustomData_bmesh_free_block_data(&target_mesh->ldata, target_loop->head.data); @@ -537,7 +471,7 @@ static void bm_face_attrs_copy(BMesh *source_mesh, uint64_t cd_mask) { if ((source_mesh == target_mesh) && (source_face == target_face)) { - BLI_assert(!"BMFace: source and targer match"); + BLI_assert(!"BMFace: source and target match"); return; } if ((cd_mask & CD_MASK_NORMAL) == 0) { diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 6ece32e57e8..68b30912041 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -209,7 +209,7 @@ BMEdge *BM_edge_create( /** * \note In most cases a \a l_example should be NULL, - * since this is a low level API and we shouldn't attempt to be clever and guess whats intended. + * since this is a low level API and we shouldn't attempt to be clever and guess what's intended. * In cases where copying adjacent loop-data is useful, see #BM_face_copy_shared. */ static BMLoop *bm_loop_create(BMesh *bm, diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c index 2ca9c7e6340..49c71bf8298 100644 --- a/source/blender/bmesh/intern/bmesh_edgeloop.c +++ b/source/blender/bmesh/intern/bmesh_edgeloop.c @@ -45,7 +45,9 @@ typedef struct BMEdgeLoopStore { } BMEdgeLoopStore; #define BM_EDGELOOP_IS_CLOSED (1 << 0) -#define EDGELOOP_EPS 0.00001f + +/* Use a small value since we need normals even for very small loops. */ +#define EDGELOOP_EPS 1e-10f /* -------------------------------------------------------------------- */ /* BM_mesh_edgeloops_find & Util Functions */ diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index c58521297dd..48d6bcd7b03 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -39,7 +39,7 @@ #include "bmesh.h" #include "intern/bmesh_private.h" -/* edge and vertex share, currently theres no need to have different logic */ +/* edge and vertex share, currently there's no need to have different logic */ static void bm_data_interp_from_elem(CustomData *data_layer, const BMElem *ele_src_1, const BMElem *ele_src_2, @@ -461,7 +461,7 @@ typedef struct BMLoopInterpMultiresData { static void loop_interp_multires_cb(void *__restrict userdata, const int ix, - const ParallelRangeTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict UNUSED(tls)) { BMLoopInterpMultiresData *data = userdata; @@ -561,7 +561,7 @@ void BM_loop_interp_multires_ex(BMesh *UNUSED(bm), .res = res, .d = 1.0f / (float)(res - 1), }; - ParallelRangeSettings settings; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (res > 5); BLI_task_parallel_range(0, res, &data, loop_interp_multires_cb, &settings); diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index bb55365f619..5aec59ccd5d 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -884,8 +884,8 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3]) sub_v3_v3v3(r_plane, vec, eve->co); } else { - /* make a fake plane thats at rightangles to the normal - * we cant make a crossvec from a vec thats the same as the vec + /* make a fake plane that's at rightangles to the normal + * we can't make a crossvec from a vec that's the same as the vec * unlikely but possible, so make sure if the normal is (0, 0, 1) * that vec isn't the same or in the same direction even. */ if (eve->no[0] < 0.5f) { diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index c796bdea688..f44b758ef6b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -1345,7 +1345,7 @@ void BM_normals_loops_edges_tag(BMesh *bm, const bool do_edges) } /** - * Auxillary function only used by rebuild to detect if any spaces were not marked as invalid. + * Auxiliary function only used by rebuild to detect if any spaces were not marked as invalid. * Reports error if any of the lnor spaces change after rebuilding, meaning that all the possible * lnor spaces to be rebuilt were not correctly marked. */ diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index c28d748b2eb..53f68804bd3 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -1029,7 +1029,7 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_f /* Rotate The Edge */ /* first create the new edge, this is so we can copy the customdata from the old one - * if splice if disabled, always add in a new edge even if theres one there. */ + * if splice if disabled, always add in a new edge even if there's one there. */ e_new = BM_edge_create( bm, v1, v2, e, (check_flag & BM_EDGEROT_CHECK_SPLICE) ? BM_CREATE_NO_DOUBLE : BM_CREATE_NOP); diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 2114f9ebd3d..e8b35afdcb1 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1545,7 +1545,7 @@ static BMOpDefine bmo_split_edges_def = { "split_edges", /* slots_in */ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ - /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */ + /* needed for vertex rip so we can rip only half an edge at a boundary which would otherwise split off */ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* optional tag verts, use to have greater control of splits */ {"use_verts", BMO_OP_SLOT_BOOL}, /* use 'verts' for splitting, else just find verts to split from edges */ {{'\0'}}, diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index f06a5fb8b13..2039289dcd7 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -100,7 +100,7 @@ BLI_INLINE BMFlagLayer *BMO_elem_flag_from_header(BMHeader *ele_head) _bmo_elem_flag_toggle( \ bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag) -/* take care not to instansiate args multiple times */ +/* take care not to instantiate args multiple times */ #ifdef __GNUC___ # define _BMO_CAST_V_CONST(e) \ ({ \ @@ -203,7 +203,7 @@ typedef enum eBMOpSlotType { /* normally store pointers to object, scene, * _never_ store arrays corresponding to mesh elements with this */ - BMO_OP_SLOT_PTR = 4, /* requres subtype BMO_OP_SLOT_SUBTYPE_PTR_xxx */ + BMO_OP_SLOT_PTR = 4, /* requires subtype BMO_OP_SLOT_SUBTYPE_PTR_xxx */ BMO_OP_SLOT_MAT = 5, BMO_OP_SLOT_VEC = 8, @@ -212,7 +212,7 @@ typedef enum eBMOpSlotType { * * it's very important this remain a power of two */ BMO_OP_SLOT_ELEMENT_BUF = 9, /* list of verts/edges/faces */ - BMO_OP_SLOT_MAPPING = 10 /* simple hash map, requres subtype BMO_OP_SLOT_SUBTYPE_MAP_xxx */ + BMO_OP_SLOT_MAPPING = 10 /* simple hash map, requires subtype BMO_OP_SLOT_SUBTYPE_MAP_xxx */ } eBMOpSlotType; #define BMO_OP_SLOT_TOTAL_TYPES 11 diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 172f7050aa0..dc839054987 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -865,6 +865,113 @@ float BM_face_calc_normal_vcos(const BMesh *bm, } /** + * Calculate a normal from a vertex cloud. + * + * \note We could make a higher quality version that takes all vertices into account. + * Currently it finds 4 outer most points returning it's normal. + */ +void BM_verts_calc_normal_from_cloud_ex( + BMVert **varr, int varr_len, float r_normal[3], float r_center[3], int *r_index_tangent) +{ + const float varr_len_inv = 1.0f / (float)varr_len; + + /* Get the center point and collect vector array since we loop over these a lot. */ + float center[3] = {0.0f, 0.0f, 0.0f}; + for (int i = 0; i < varr_len; i++) { + madd_v3_v3fl(center, varr[i]->co, varr_len_inv); + } + + /* Find the 'co_a' point from center. */ + int co_a_index = 0; + const float *co_a = NULL; + { + float dist_sq_max = -1.0f; + for (int i = 0; i < varr_len; i++) { + const float dist_sq_test = len_squared_v3v3(varr[i]->co, center); + if (!(dist_sq_test <= dist_sq_max)) { + co_a = varr[i]->co; + co_a_index = i; + dist_sq_max = dist_sq_test; + } + } + } + + float dir_a[3]; + sub_v3_v3v3(dir_a, co_a, center); + normalize_v3(dir_a); + + const float *co_b = NULL; + float dir_b[3] = {0.0f, 0.0f, 0.0f}; + { + float dist_sq_max = -1.0f; + for (int i = 0; i < varr_len; i++) { + if (varr[i]->co == co_a) { + continue; + } + float dir_test[3]; + sub_v3_v3v3(dir_test, varr[i]->co, center); + project_plane_normalized_v3_v3v3(dir_test, dir_test, dir_a); + const float dist_sq_test = len_squared_v3(dir_test); + if (!(dist_sq_test <= dist_sq_max)) { + co_b = varr[i]->co; + dist_sq_max = dist_sq_test; + copy_v3_v3(dir_b, dir_test); + } + } + } + + if (varr_len <= 3) { + normal_tri_v3(r_normal, center, co_a, co_b); + goto finally; + } + + normalize_v3(dir_b); + + const float *co_a_opposite = NULL; + const float *co_b_opposite = NULL; + + { + float dot_a_min = FLT_MAX; + float dot_b_min = FLT_MAX; + for (int i = 0; i < varr_len; i++) { + const float *co_test = varr[i]->co; + float dot_test; + + if (co_test != co_a) { + dot_test = dot_v3v3(dir_a, co_test); + if (dot_test < dot_a_min) { + dot_a_min = dot_test; + co_a_opposite = co_test; + } + } + + if (co_test != co_b) { + dot_test = dot_v3v3(dir_b, co_test); + if (dot_test < dot_b_min) { + dot_b_min = dot_test; + co_b_opposite = co_test; + } + } + } + } + + normal_quad_v3(r_normal, co_a, co_b, co_a_opposite, co_b_opposite); + +finally: + if (r_center != NULL) { + copy_v3_v3(r_center, center); + } + if (r_index_tangent != NULL) { + *r_index_tangent = co_a_index; + } +} + +void BM_verts_calc_normal_from_cloud(BMVert **varr, int varr_len, float r_normal[3]) +{ + BM_verts_calc_normal_from_cloud_ex(varr, varr_len, r_normal, NULL, NULL); +} + +/** * Calculates the face subset normal. */ float BM_face_calc_normal_subset(const BMLoop *l_first, const BMLoop *l_last, float r_no[3]) diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index 191ebd86f4a..2ae32777a7d 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -38,6 +38,11 @@ float BM_face_calc_normal_vcos(const BMesh *bm, const BMFace *f, float r_no[3], float const (*vertexCos)[3]) ATTR_NONNULL(); + +void BM_verts_calc_normal_from_cloud_ex( + BMVert **varr, int varr_len, float r_normal[3], float r_center[3], int *r_index_tangent); +void BM_verts_calc_normal_from_cloud(BMVert **varr, int varr_len, float r_normal[3]); + float BM_face_calc_normal_subset(const BMLoop *l_first, const BMLoop *l_last, float r_no[3]) ATTR_NONNULL(); float BM_face_calc_area(const BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c index 64768474765..83ac7df058a 100644 --- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c +++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c @@ -496,7 +496,7 @@ bool BM_face_split_edgenet(BMesh *bm, } /* These arrays used to be stack memory, however they can be - * large for singe faces with complex edgenets, see: T65980. */ + * large for single faces with complex edgenets, see: T65980. */ /* over-alloc (probably 2-4 is only used in most cases), for the biggest-fan */ edge_order = MEM_mallocN(sizeof(*edge_order) * edge_order_len, __func__); @@ -765,8 +765,8 @@ struct EdgeGroupIsland { /* Set the following vars once we have >1 groups */ - /* when when an edge in a previous group connects to this one, - * so theres no need to create one pointing back. */ + /* when an edge in a previous group connects to this one, + * so there's no need to create one pointing back. */ uint has_prev_edge : 1; /* verts in the group which has the lowest & highest values, @@ -1000,7 +1000,7 @@ static int bm_face_split_edgenet_find_connection(const struct EdgeGroup_FindConn * until a vertex is found which isn't blocked by an edge. * * \note It's possible none of the verts can be accessed (with self-intersecting lines). - * In that case theres no right answer (without subdividing edges), + * In that case there's no right answer (without subdividing edges), * so return a fall-back vertex in that case. */ @@ -1481,7 +1481,7 @@ bool BM_face_split_edgenet_connect_islands(BMesh *bm, if (!BM_elem_flag_test(v_iter, VERT_IN_ARRAY)) { BM_elem_flag_enable(v_iter, VERT_IN_ARRAY); - /* not nice, but alternatives arent much better :S */ + /* not nice, but alternatives aren't much better :S */ { copy_v3_v3(vert_coords_backup[v_index], v_iter->co); diff --git a/source/blender/bmesh/intern/bmesh_structure.h b/source/blender/bmesh/intern/bmesh_structure.h index 7ae55a5fa6f..38c75dec354 100644 --- a/source/blender/bmesh/intern/bmesh_structure.h +++ b/source/blender/bmesh/intern/bmesh_structure.h @@ -34,7 +34,7 @@ /* LOOP CYCLE MANAGEMENT */ bool bmesh_loop_validate(BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -/* DISK CYCLE MANAGMENT */ +/* DISK CYCLE MANAGEMENT */ void bmesh_disk_edge_append(BMEdge *e, BMVert *v) ATTR_NONNULL(); void bmesh_disk_edge_remove(BMEdge *e, BMVert *v) ATTR_NONNULL(); BLI_INLINE BMEdge *bmesh_disk_edge_next_safe(const BMEdge *e, @@ -60,7 +60,7 @@ BMLoop *bmesh_disk_faceloop_find_first_visible(const BMEdge *e, BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -/* RADIAL CYCLE MANAGMENT */ +/* RADIAL CYCLE MANAGEMENT */ void bmesh_radial_loop_append(BMEdge *e, BMLoop *l) ATTR_NONNULL(); void bmesh_radial_loop_remove(BMEdge *e, BMLoop *l) ATTR_NONNULL(); void bmesh_radial_loop_unlink(BMLoop *l) ATTR_NONNULL(); diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index 20042e65287..ade6fdfcbed 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -805,7 +805,7 @@ static void *bmw_IslandWalker_step_ex(BMWalker *walker, bool only_manifold) continue; } - /* saves checking BLI_gset_haskey below (manifold edges theres a 50% chance) */ + /* saves checking BLI_gset_haskey below (manifold edges there's a 50% chance) */ if (f == iwalk->cur) { continue; } |