47 #define BM_EDGELOOP_IS_CLOSED (1 << 0)
50 #define EDGELOOP_EPS 1e-10f
64 if (v_other != v_prev) {
108 else if (
count == 0) {
161 for (
uint i = 0; i < edges_len; i += 1) {
178 for (
uint i = 0; i < edges_len; i += 1) {
229 for (vs = lb->
first; vs; vs = vs_next) {
234 const int vs_iter_next = vs_iter_tot + dir;
244 if (v_next_index == 0) {
245 vs_add(vs_pool, &lb_tmp, v_next,
e, vs_iter_next);
247 else if ((dir < 0) == (v_next_index < 0)) {
319 edges =
MEM_mallocN(
sizeof(*edges) * edges_len, __func__);
326 edges =
MEM_mallocN(
sizeof(*edges) * edges_len, __func__);
344 vs_add(vs_pool, &lb_src, v_src, v_src->
e, 1);
345 vs_add(vs_pool, &lb_dst, v_dst, v_dst->
e, -1);
394 for (
uint i = 0; i < edges_len; i += 1) {
419 for (el_store = eloops->
first; el_store; el_store = el_store->
next) {
427 for (el_store = eloops->
first; el_store; el_store = el_store->
next) {
435 for (el_store = eloops->
first; el_store; el_store = el_store->
next) {
448 for (el_store = eloops->
first; el_store; el_store = el_store->
next, tot++) {
456 float len_best_sq = -1.0f;
457 for (el_store = eloops->
first; el_store; el_store = el_store->
next) {
459 if (len_sq > len_best_sq) {
460 len_best_sq = len_sq;
461 el_store_best = el_store;
470 while (eloops->
first) {
474 float len_best_sq = FLT_MAX;
480 for (el_store = eloops->
first; el_store; el_store = el_store->
next) {
494 if (len_sq < len_best_sq) {
495 len_best_sq = len_sq;
496 el_store_best = el_store;
504 *eloops = eloops_ordered;
514 *el_store_copy = *el_store;
516 return el_store_copy;
523 for (i = 0; i < v_arr_tot; i++) {
525 node->data = v_arr[i];
528 el_store->
len = v_arr_tot;
548 return &el_store->
verts;
553 return el_store->
len;
566 #define NODE_AS_V(n) ((BMVert *)((LinkData *)n)->data)
567 #define NODE_AS_CO(n) ((BMVert *)((LinkData *)n)->data)->co
606 const float w_curr =
len_v3v3(v_curr, v_next);
607 const float w = (w_curr + w_prev);
612 node_prev = node_curr;
613 node_curr = node_next;
614 node_next = node_next->
next;
616 if (node_next ==
NULL) {
641 if ((node_curr = node_curr->
next)) {
651 el_store->
no[2] = 1.0f;
665 const float no_align[3])
675 float cross[3], no[3], dir[3];
681 if ((node_curr = node_curr->
next)) {
691 el_store->
no[2] = 1.0f;
706 bool split_swap =
true;
708 #define EDGE_SPLIT(node_copy, node_other) \
710 BMVert *v_split, *v_other = (node_other)->data; \
711 BMEdge *e_split, *e_other = BM_edge_exists((node_copy)->data, v_other); \
712 v_split = BM_edge_split( \
713 bm, e_other, split_swap ? (node_copy)->data : v_other, &e_split, 0.0f); \
714 v_split->e = e_split; \
715 BLI_assert(v_split == e_split->v2); \
716 BLI_gset_insert(split_edges, e_split); \
717 (node_copy)->data = v_split; \
722 while ((el_store->
len * 2) < el_store_len) {
726 if (
split ==
false) {
728 node_curr = node_curr_copy->
next;
735 node_curr = node_curr_copy->
next;
740 node_curr = node_curr->
next;
742 split_swap = !split_swap;
746 split_swap = !split_swap;
749 if (el_store->
len < el_store_len) {
754 while (iter_prev < iter) {
755 node_curr = node_curr->
next;
761 if (
split ==
false) {
763 node_curr = node_curr_copy->
next;
770 node_curr = node_curr_copy->
next;
775 node_curr = node_curr->
next;
777 split_swap = !split_swap;
784 #undef BKE_FOREACH_SUBSET_OF_RANGE
796 if (el_store_a->
len > el_store_b->
len) {
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
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 BLI_listbase_reverse(struct ListBase *lb) 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 normalize_v3(float r[3])
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])
void BLI_mempool_free(BLI_mempool *pool, void *addr) ATTR_NONNULL(1
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int totelem, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_mempool_alloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
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
BMEdgeLoopStore * BM_edgeloop_copy(BMEdgeLoopStore *el_store)
struct BMEdgeLoopStore BMEdgeLoopStore
const float * BM_edgeloop_center_get(struct BMEdgeLoopStore *el_store)
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)
BMEdgeLoopStore * BM_edgeloop_from_verts(BMVert **v_arr, const int v_arr_tot, bool is_closed)
int BM_mesh_edgeloops_find(BMesh *bm, ListBase *r_eloops, bool(*test_fn)(BMEdge *, void *user_data), void *user_data)
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)
void BM_mesh_edgeloops_calc_order(BMesh *UNUSED(bm), ListBase *eloops, const bool use_normals)
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_edgeloop_edges_get(struct BMEdgeLoopStore *el_store, BMEdge **e_arr)
ListBase * BM_edgeloop_verts_get(BMEdgeLoopStore *el_store)
void BM_mesh_edgeloops_calc_normal_aligned(BMesh *bm, ListBase *eloops, const float no_align[3])
static int bm_vert_other_tag(BMVert *v, BMVert *v_prev, BMEdge **r_e)
bool BM_edgeloop_calc_normal(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store)
bool BM_edgeloop_overlap_check(struct BMEdgeLoopStore *el_store_a, struct BMEdgeLoopStore *el_store_b)
bool BM_edgeloop_calc_normal_aligned(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store, const float no_align[3])
const float * BM_edgeloop_normal_get(struct BMEdgeLoopStore *el_store)
void BM_edgeloop_flip(BMesh *UNUSED(bm), 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)
#define EDGE_SPLIT(node_copy, node_other)
void BM_edgeloop_calc_center(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store)
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_freeN)(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
struct BMEdgeLoopStore * next
struct BMEdgeLoopStore * prev
__forceinline avxf cross(const avxf &a, const avxf &b)
__forceinline const avxi abs(const avxi &a)