38#define USE_WALKER_REUSE
43#define USE_PIVOT_FASTMATCH
46#define USE_PIVOT_SEARCH
62#define PRIME_VERT_INIT 100003
188 const uint faces_src_region_len,
189 const uint verts_src_region_len)
261#define PRIME_VERT_SMALL 7
262#define PRIME_VERT_MID 43
263#define PRIME_VERT_LARGE 1031
265#define PRIME_FACE_SMALL 13
266#define PRIME_FACE_MID 53
306#undef PRIME_VERT_SMALL
308#undef PRIME_VERT_LARGE
310#undef PRIME_FACE_SMALL
316#define PRIME_VERT_SMALL 11
318#define PRIME_FACE_SMALL 17
319#define PRIME_FACE_LARGE 1013
335 }
while ((l_iter = l_iter->
next) != l_first);
351 }
while ((l_iter_radial = l_iter_radial->
radial_next) != l_iter);
353 }
while ((l_iter = l_iter->
next) != l_first);
358#undef PRIME_VERT_SMALL
360#undef PRIME_FACE_SMALL
361#undef PRIME_FACE_LARGE
368 rehash_store_len_new *= 2;
399 *((
UID_Int *)uid_p) = uid_store[
i++];
411 *((
UID_Int *)uid_p) = uid_store[
i++];
417 const uint faces_len,
428 for (f_link =
faces; f_link; f_link = f_link->
next) {
435 for (f_link =
faces; f_link; f_link = f_link->
next) {
441 for (f_link =
faces; f_link; f_link = f_link->
next) {
444 *((
UID_Int *)uid_p) = uid_store[
i++];
466 GHash *verts_uid_pass;
467 GSet *faces_step_next;
487 fstep->
faces =
nullptr;
490 for (f_link = faces_pass; f_link; f_link = f_link->
next) {
503 *val_p = (
void *)uid;
519 }
while ((l_iter_radial = l_iter_radial->
radial_next) != l_iter);
521 }
while ((l_iter = l_iter->
next) != l_first);
559 uint fstep_num = 0,
i = 0;
582 for (
i = 0;
i < f_arr_len;) {
584 const uint i_init =
i;
585 const int f_len = f_arr[
i]->
len;
589 }
while (
i < f_arr_len && (f_len == f_arr[
i]->
len));
599#undef PRIME_VERT_INIT
611 return (fstep_a->
uid > fstep_b->
uid) ? 1 : 0;
620 LinkNode *f_link, *f_link_next, **f_link_prev_p;
626 f_link_prev_p = &fstep->
faces;
627 for (f_link = fstep->
faces; f_link; f_link = f_link_next) {
629 f_link_next = f_link->
next;
648 fstep_item->
uid = uid;
649 fstep_item->
list =
nullptr;
656 f_link_prev_p = &f_link->
next;
659 *f_link_prev_p = f_link->
next;
688 for (f_link = fstep->
faces; f_link; f_link = f_link_next) {
689 f_link_next = f_link->
next;
713 const uint faces_src_region_len,
714 const uint verts_src_region_len,
715 uint *r_faces_result_len)
717#ifndef USE_WALKER_REUSE
719 UIDWalk *w_src = &w_src_, *w_dst = &w_dst_;
721 BMFace **faces_result =
nullptr;
726#ifndef USE_WALKER_REUSE
731 w_src->use_face_isolate =
true;
755 if (fstep_src->
faces ==
nullptr) {
760 fstep_src = fstep_src_next;
761 fstep_dst = fstep_dst_next;
775 fstep_item_src && fstep_item_dst;
776 fstep_item_src = fstep_item_src->
next, fstep_item_dst = fstep_item_dst->
next)
778 while ((fstep_item_dst !=
nullptr) && (fstep_item_dst->
uid < fstep_item_src->
uid)) {
779 fstep_item_dst = fstep_item_dst->
next;
782 if ((fstep_item_dst ==
nullptr) || (fstep_item_src->
uid != fstep_item_dst->
uid) ||
799 fstep_item_src->
list =
nullptr;
802 fstep_item_dst->
list =
nullptr;
814 fstep_src = fstep_src->
next;
815 fstep_dst = fstep_dst->
next;
838 faces_result =
static_cast<BMFace **
>(
839 MEM_mallocN(
sizeof(*faces_result) * (faces_result_len + 1), __func__));
844 faces_result[faces_result_len] =
nullptr;
845 *r_faces_result_len = faces_result_len;
848 *r_faces_result_len = 0;
853#ifdef USE_WALKER_REUSE
868 const uint faces_len,
874 for (
i = 0;
i < faces_len;
i++) {
887 }
while ((l_iter = l_iter->
next) != l_first);
895 *r_verts_len = verts_len;
899#ifdef USE_PIVOT_SEARCH
910 return (a < 0) ? -a : a;
915 if (
e->l->radial_next !=
e->l) {
937 if (e_pivot_test_id[0] > e_pivot_test_id[1]) {
938 std::swap(e_pivot_test_id[0], e_pivot_test_id[1]);
941 if ((*r_e_pivot_best ==
nullptr) ||
942 ((e_pivot_best_id[0] != e_pivot_test_id[0]) ? (e_pivot_best_id[0] < e_pivot_test_id[0]) :
943 (e_pivot_best_id[1] < e_pivot_test_id[1])))
945 e_pivot_best_id[0] = e_pivot_test_id[0];
946 e_pivot_best_id[1] = e_pivot_test_id[1];
949 *r_e_pivot_best = e_test;
956# define PRIME_VERT_SMALL_A 7
957# define PRIME_VERT_SMALL_B 13
958# define PRIME_VERT_MID_A 103
959# define PRIME_VERT_MID_B 131
977# undef PRIME_VERT_SMALL_A
978# undef PRIME_VERT_SMALL_B
979# undef PRIME_VERT_MID_A
980# undef PRIME_VERT_MID_B
996# define PRIME_VERT_MID_A 23
997# define PRIME_VERT_MID_B 31
1005 if (v_other_id > 0) {
1006 v_sum_id += v_other_id;
1014 v_sum_face_len += l_iter->
f->
len;
1032# undef PRIME_VERT_MID_A
1033# undef PRIME_VERT_MID_B
1044 uint faces_region_len,
1045 uint verts_region_len,
1057 BMEdge *e_pivot =
nullptr;
1059 BMEdge *e_pivot_fallback =
nullptr;
1064 uint vert_queue_used = 0;
1070 for (
i = 0;
i < faces_region_len;
i++) {
1073 BMLoop *l_iter, *l_first;
1079 for (j = 0; j < 2; j++) {
1083 *val_p = (
void *)v_id;
1085 vert_queue_used += 1;
1091 e_pivot_fallback =
e;
1093 }
while ((l_iter = l_iter->
next) != l_first);
1111 *val_p = (
void *)v_id_other;
1113 vert_queue_used += 1;
1123 for (v_link = vert_queue_next; v_link; v_link = v_link->
next) {
1125 *v_id_p = -(*v_id_p);
1133 if (vert_queue_used == verts_region_len) {
1141 BMEdge *e_pivot_best =
nullptr;
1142 SUID_Int e_pivot_best_id[2] = {0, 0};
1145 for (v_link = vert_queue_prev; v_link; v_link = v_link->
next) {
1151 for (v_link = vert_queue_prev; v_link; v_link = v_link->
next) {
1168 e_pivot = e_pivot_best;
1173 BMEdge *e_pivot_best =
nullptr;
1174 SUID_Int e_pivot_best_id[2] = {0, 0};
1183 for (v_link = vert_queue_prev; v_link; v_link = v_link->
next) {
1198 e_pivot = e_pivot_best;
1206 if (e_pivot ==
nullptr) {
1208 printf(
"%s: using fallback edge!\n", __func__);
1210 e_pivot = e_pivot_fallback;
1214 *r_depth =
uint(pass);
1225#ifdef USE_PIVOT_FASTMATCH
1239# define PRIME_EDGE 7
1240# define PRIME_FACE 31
1241# define PRIME_LOOP 61
1276 for (pass = 0; pass < depth; pass++) {
1279 memcpy(id_curr, id_prev,
sizeof(*id_prev) *
uint(
bm->totvert));
1286 id_curr[i1] += id_prev[i2];
1287 id_curr[i2] += id_prev[i1];
1303 if (e_fm[0] > e_fm[1]) {
1304 std::swap(e_fm[0], e_fm[1]);
1316 return ((e_a_fm[0] == e_b_fm[0]) && (e_a_fm[1] == e_b_fm[1]));
1330 uint faces_region_len,
1336 uint verts_region_len = 0;
1337 uint faces_result_len = 0;
1341#ifdef USE_WALKER_REUSE
1345#ifdef USE_PIVOT_FASTMATCH
1364#ifdef USE_PIVOT_SEARCH
1380 if (e_src ==
nullptr) {
1382 printf(
"Couldn't find 'e_src'");
1389#ifdef USE_PIVOT_FASTMATCH
1398#ifdef USE_WALKER_REUSE
1405 uint faces_result_len_out;
1411#ifdef USE_PIVOT_FASTMATCH
1430 &faces_result_len_out);
1440 faces_result_len += 1;
1444#ifdef USE_WALKER_REUSE
1451#ifdef USE_PIVOT_FASTMATCH
1458 printf(
"%s: search: %d, found %d\n", __func__, search_num, faces_result_len);
1465 return int(faces_result_len);
#define BLI_array_alloca(arr, realsize)
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_haskey(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
bool BLI_gset_haskey(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
BLI_INLINE void ** BLI_ghashIterator_getValue_p(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
#define GHASH_ITER(gh_iter_, ghash_)
GSet * BLI_gset_new_ex(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_gset_clear(GSet *gs, GSetKeyFreeFP keyfreefp)
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
unsigned int BLI_gset_len(const GSet *gs) ATTR_WARN_UNUSED_RESULT
void BLI_gset_insert(GSet *gs, void *key)
GHash * BLI_ghash_new_ex(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
unsigned int BLI_ghash_len(const GHash *gh) ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
GHash * BLI_ghash_int_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
#define GHASH_ITER_INDEX(gh_iter_, ghash_, i_)
void BLI_linklist_free_pool(LinkNode *list, LinkNodeFreeFP freefunc, struct BLI_mempool *mempool)
int BLI_linklist_count(const LinkNode *list) ATTR_WARN_UNUSED_RESULT
void void BLI_linklist_prepend_pool(LinkNode **listp, void *ptr, struct BLI_mempool *mempool) ATTR_NONNULL(1
BLI_LINKSTACK_*** wrapper macros for using a LinkNode to store a stack of pointers,...
#define BLI_LINKSTACK_PUSH(var, ptr)
#define BLI_LINKSTACK_DECLARE(var, type)
#define BLI_LINKSTACK_SIZE(var)
#define BLI_LINKSTACK_FREE(var)
#define BLI_LINKSTACK_INIT(var)
#define BLI_LINKSTACK_POP(var)
#define BLI_LINKSTACK_SWAP(var_a, var_b)
LinkData * BLI_genericNodeN(void *data)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_addhead(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void void BLI_listbase_sort(ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
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_mempool_clear(BLI_mempool *pool) ATTR_NONNULL(1)
Platform independent time functions.
Utility defines for timing/benchmarks.
#define TIMEIT_START(var)
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
#define BM_FACE_FIRST_LOOP(p)
#define BM_elem_index_get(ele)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_test_bool(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)
void BM_select_history_clear(BMesh *bm)
BMEdge * BM_mesh_active_edge_get(BMesh *bm)
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
#define BM_select_history_store(bm, ele)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
int BM_edge_face_count(const BMEdge *e)
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static GSet * gset_bmelem_new_ex(const char *info, const uint nentries_reserve)
static void bm_face_region_pivot_edge_use_best(GHash *gh, BMEdge *e_test, BMEdge **r_e_pivot_best, SUID_Int e_pivot_best_id[2])
BLI_INLINE bool bm_uidwalk_face_lookup(UIDWalk *uidwalk, BMFace *f, UID_Int *r_uid)
static bool bm_vert_is_uid_connect(UIDWalk *uidwalk, BMVert *v)
static bool bm_uidwalk_facestep_begin(UIDWalk *uidwalk, UIDFaceStep *fstep)
static int bm_face_len_cmp(const void *v1, const void *v2)
static bool ghashutil_bmelem_indexcmp(const void *a, const void *b)
static UIDFashMatch * bm_vert_fasthash_create(BMesh *bm, const uint depth)
BLI_INLINE bool bm_uidwalk_vert_lookup(UIDWalk *uidwalk, BMVert *v, UID_Int *r_uid)
static UID_Int bm_uidwalk_calc_face_uid(UIDWalk *uidwalk, BMFace *f)
BLI_INLINE bool bm_uidwalk_face_test(UIDWalk *uidwalk, BMFace *f)
static void bm_uidwalk_free(UIDWalk *uidwalk)
static UIDFashMatch bm_vert_fasthash_single(BMVert *v)
static void bm_uidwalk_pass_add(UIDWalk *uidwalk, LinkNode *faces_pass, const uint faces_pass_len)
static UID_Int bm_uidwalk_calc_vert_uid(UIDWalk *uidwalk, BMVert *v)
static void bm_uidwalk_clear(UIDWalk *uidwalk)
static GSet * gset_bmelem_new(const char *info)
BLI_INLINE intptr_t abs_intptr(intptr_t a)
static void bm_uidwalk_init(UIDWalk *uidwalk, const uint faces_src_region_len, const uint verts_src_region_len)
static uint bm_uidwalk_init_from_edge(UIDWalk *uidwalk, BMEdge *e)
static void bm_uidwalk_rehash_reserve(UIDWalk *uidwalk, uint rehash_store_len_new)
static void bm_uidwalk_facestep_free(UIDWalk *uidwalk, UIDFaceStep *fstep)
static SUID_Int bm_face_region_vert_pass_id(GHash *gh, BMVert *v)
static bool bm_vert_fasthash_edge_is_match(UIDFashMatch *fm, const BMEdge *e_a, const BMEdge *e_b)
static int facestep_sort(const void *a, const void *b)
static BMEdge * bm_face_region_pivot_edge_find(BMFace **faces_region, uint faces_region_len, uint verts_region_len, uint *r_depth)
static void bm_vert_fasthash_destroy(UIDFashMatch *fm)
static uint ghashutil_bmelem_indexhash(const void *key)
static void bm_uidwalk_rehash(UIDWalk *uidwalk)
static void bm_uidwalk_facestep_end(UIDWalk *uidwalk, UIDFaceStep *fstep)
static GHash * ghash_bmelem_new(const char *info)
static void bm_vert_fasthash_edge_order(const UIDFashMatch *fm, const BMEdge *e, UIDFashMatch e_fm[2])
#define PRIME_VERT_SMALL_A
static void bm_uidwalk_rehash_facelinks(UIDWalk *uidwalk, LinkNode *faces, const uint faces_len, const bool is_init)
static SUID_Int bm_face_region_vert_boundary_id(BMVert *v)
static bool bm_edge_is_region_boundary(BMEdge *e)
static GHash * ghash_bmelem_new_ex(const char *info, const uint nentries_reserve)
static BMFace ** bm_mesh_region_match_pair(UIDWalk *w_src, UIDWalk *w_dst, BMEdge *e_src, BMEdge *e_dst, const uint faces_src_region_len, const uint verts_src_region_len, uint *r_faces_result_len)
#define PRIME_VERT_SMALL_B
int BM_mesh_region_match(BMesh *bm, BMFace **faces_region, uint faces_region_len, ListBase *r_face_regions)
static void bm_face_array_visit(BMFace **faces, const uint faces_len, uint *r_verts_len, bool visit_faces)
void * MEM_mallocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
struct BMLoop * radial_next
BLI_mempool * step_pool_items
struct UIDWalk::@346311361144173360357226056011362263241042353241 cache