32#define BM_EDGELOOP_IS_CLOSED (1 << 0)
35#define EDGELOOP_EPS 1e-10f
49 if (v_other != v_prev) {
80 add_fn(&el_store->
verts, node);
93 else if (
count == 0) {
111 bool (*test_fn)(
BMEdge *,
void *user_data),
127 if (test_fn(
e, user_data)) {
143 for (
uint i = 0; i < edges_len; i += 1) {
162 for (
uint i = 0; i < edges_len; i += 1) {
208 ListBase lb_tmp = {
nullptr,
nullptr};
212 for (vs =
static_cast<VertStep *
>(lb->
first); vs; vs = vs_next) {
217 const int vs_iter_next = vs_iter_tot + dir;
227 if (v_next_index == 0) {
228 vs_add(vs_pool, &lb_tmp, v_next,
e, vs_iter_next);
230 else if ((dir < 0) == (v_next_index < 0)) {
264 bool (*test_fn)(
BMEdge *,
void *user_data),
291 if (test_fn(
e, user_data)) {
302 edges =
static_cast<BMEdge **
>(
MEM_mallocN(
sizeof(*edges) * edges_len, __func__));
309 edges =
static_cast<BMEdge **
>(
MEM_mallocN(
sizeof(*edges) * edges_len, __func__));
321 BMVert *v_match[2] = {
nullptr,
nullptr};
322 ListBase lb_src = {
nullptr,
nullptr};
323 ListBase lb_dst = {
nullptr,
nullptr};
327 vs_add(vs_pool, &lb_src, v_src, v_src->
e, 1);
328 vs_add(vs_pool, &lb_dst, v_dst, v_dst->
e, -1);
378 for (
uint i = 0; i < edges_len; i += 1) {
422 ListBase eloops_ordered = {
nullptr};
429 el_store = el_store->
next, tot++)
438 float len_best_sq = -1.0f;
441 if (len_sq > len_best_sq) {
442 len_best_sq = len_sq;
443 el_store_best = el_store;
452 while (eloops->
first) {
476 if (len_sq < len_best_sq) {
477 len_best_sq = len_sq;
478 el_store_best = el_store;
486 *eloops = eloops_ordered;
496 *el_store_copy = *el_store;
498 return el_store_copy;
506 for (i = 0; i < v_arr_tot; i++) {
508 node->
data = v_arr[i];
511 el_store->
len = v_arr_tot;
531 return &el_store->
verts;
536 return el_store->
len;
549#define NODE_AS_V(n) ((BMVert *)((LinkData *)n)->data)
550#define NODE_AS_CO(n) ((BMVert *)((LinkData *)n)->data)->co
588 const float w_curr =
len_v3v3(v_curr, v_next);
589 const float w = (w_curr + w_prev);
594 node_prev = node_curr;
595 node_curr = node_next;
596 node_next = node_next->
next;
598 if (node_next ==
nullptr) {
623 if ((node_curr = node_curr->
next)) {
633 el_store->
no[2] = 1.0f;
641 const float no_align[3])
651 float cross[3], no[3], dir[3];
657 if ((node_curr = node_curr->
next)) {
667 el_store->
no[2] = 1.0f;
682 bool split_swap =
true;
684#define EDGE_SPLIT(node_copy, node_other) \
686 BMVert *v_split, *v_other = static_cast<BMVert *>((node_other)->data); \
688 *e_other = BM_edge_exists(static_cast<BMVert *>((node_copy)->data), v_other); \
689 v_split = BM_edge_split(bm, \
691 static_cast<BMVert *>(split_swap ? (node_copy)->data : v_other), \
694 v_split->e = e_split; \
695 BLI_assert(v_split == e_split->v2); \
696 BLI_gset_insert(split_edges, e_split); \
697 (node_copy)->data = v_split; \
702 while ((el_store->
len * 2) < el_store_len) {
706 if (split ==
false) {
708 node_curr = node_curr_copy->
next;
715 node_curr = node_curr_copy->
next;
720 node_curr = node_curr->
next;
722 split_swap = !split_swap;
726 split_swap = !split_swap;
729 if (el_store->
len < el_store_len) {
734 while (iter_prev < iter) {
735 node_curr = node_curr->
next;
741 if (split ==
false) {
743 node_curr = node_curr_copy->
next;
750 node_curr = node_curr_copy->
next;
755 node_curr = node_curr->
next;
757 split_swap = !split_swap;
764#undef BKE_FOREACH_SUBSET_OF_RANGE
773 if (el_store_a->
len > el_store_b->
len) {
774 std::swap(el_store_a, el_store_b);
789 while ((node = node->next)) {
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
void void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
void void void void void void void BLI_listbase_reverse(struct ListBase *lb) ATTR_NONNULL(1)
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
#define BLI_ASSERT_UNIT_V3(v)
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
void * BLI_mempool_alloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
void BLI_mempool_free(BLI_mempool *pool, void *addr) ATTR_NONNULL(1
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int elem_num, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
void BLI_stack_pop_n_reverse(BLI_Stack *stack, void *dst, unsigned int n) ATTR_NONNULL()
size_t BLI_stack_count(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_stack_push(BLI_Stack *stack, const void *src) ATTR_NONNULL()
void BLI_stack_free(BLI_Stack *stack) ATTR_NONNULL()
#define BLI_stack_new(esize, descr)
#define BLI_FOREACH_SPARSE_RANGE(src, dst, i)
Read Guarded memory(de)allocation.
#define BM_EDGELOOP_IS_CLOSED
void BM_mesh_edgeloops_calc_order(BMesh *, ListBase *eloops, const bool use_normals)
static bool bm_loop_path_build_step(BLI_mempool *vs_pool, ListBase *lb, const int dir, BMVert *v_match[2])
void BM_edgeloop_expand(BMesh *bm, BMEdgeLoopStore *el_store, int el_store_len, bool split, GSet *split_edges)
void BM_mesh_edgeloops_free(ListBase *eloops)
void BM_edgeloop_free(BMEdgeLoopStore *el_store)
bool BM_edgeloop_overlap_check(BMEdgeLoopStore *el_store_a, BMEdgeLoopStore *el_store_b)
void BM_edgeloop_flip(BMesh *, BMEdgeLoopStore *el_store)
BMEdgeLoopStore * BM_edgeloop_copy(BMEdgeLoopStore *el_store)
bool BM_edgeloop_calc_normal(BMesh *, BMEdgeLoopStore *el_store)
int BM_mesh_edgeloops_find(BMesh *bm, ListBase *r_eloops, bool(*test_fn)(BMEdge *, void *user_data), void *user_data)
void BM_edgeloop_calc_center(BMesh *, BMEdgeLoopStore *el_store)
BMEdgeLoopStore * BM_edgeloop_from_verts(BMVert **v_arr, const int v_arr_tot, bool is_closed)
bool BM_mesh_edgeloops_find_path(BMesh *bm, ListBase *r_eloops, bool(*test_fn)(BMEdge *, void *user_data), void *user_data, BMVert *v_src, BMVert *v_dst)
int BM_edgeloop_length_get(BMEdgeLoopStore *el_store)
const float * BM_edgeloop_normal_get(BMEdgeLoopStore *el_store)
bool BM_edgeloop_calc_normal_aligned(BMesh *, BMEdgeLoopStore *el_store, const float no_align[3])
static bool bm_loop_build(BMEdgeLoopStore *el_store, BMVert *v_prev, BMVert *v, int dir)
bool BM_edgeloop_is_closed(BMEdgeLoopStore *el_store)
void BM_mesh_edgeloops_calc_normal_aligned(BMesh *bm, ListBase *eloops, const float no_align[3])
void BM_edgeloop_edges_get(BMEdgeLoopStore *el_store, BMEdge **e_arr)
static int bm_vert_other_tag(BMVert *v, BMVert *v_prev, BMEdge **r_e)
const float * BM_edgeloop_center_get(BMEdgeLoopStore *el_store)
static void vs_add(BLI_mempool *vs_pool, ListBase *lb, BMVert *v, BMEdge *e_prev, const int iter_tot)
void BM_mesh_edgeloops_calc_normal(BMesh *bm, ListBase *eloops)
ListBase * BM_edgeloop_verts_get(BMEdgeLoopStore *el_store)
#define EDGE_SPLIT(node_copy, node_other)
void BM_mesh_edgeloops_calc_center(BMesh *bm, ListBase *eloops)
#define BM_elem_index_get(ele)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_index_set(ele, index)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
ATTR_WARN_UNUSED_RESULT BMesh * bm
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_vert_in_edge(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_dupallocN)(const void *vmemh)
ccl_device_inline float cross(const float2 a, const float2 b)
ccl_device_inline int abs(int x)