29#define KDOP_TREE_TYPE 4
30#define KDOP_AXIS_LEN 14
31#define BLI_STACK_PAIR_LEN (2 * KDOP_TREE_TYPE)
70 BMVert *v_test =
ELEM((*e_iter)->v1, e_next->
v1, e_next->
v2) ? (*e_iter)->v2 : (*e_iter)->v1;
72 int verts_len =
data->edgenet_len - 1;
73 for (
int i = verts_len;
i--; e_iter++) {
84 const float test_edgenet_range_on_face_normal =
max -
min;
85 if (test_edgenet_range_on_face_normal < data->best_edgenet_range_on_face_normal) {
86 data->best_edgenet_range_on_face_normal = test_edgenet_range_on_face_normal;
87 data->r_best_face = f;
99 float (*
data)[3] =
static_cast<float (*)[3]
>(userdata);
100 float *v_a_co =
data[0];
101 float *v_a_b_dir =
data[1];
102 const float range_min = -FLT_EPSILON;
103 const float range_max = 1.0f + FLT_EPSILON;
112 if (
IN_RANGE(lambda_b, range_min, range_max)) {
118 return IN_RANGE(lambda_b, range_min, range_max);
125 BMVert *v_a,
BMVert *v_b,
BMEdge **edgenet,
const int edgenet_len,
const float epsilon)
127 BMFace *best_face =
nullptr;
132 if (edgenet_len == 1) {
142 data.edgenet = edgenet;
143 data.edgenet_len = edgenet_len;
145 data.r_best_face =
nullptr;
150 if (
data.r_best_face) {
161 float face_range_on_normal =
max -
min + 2 * epsilon;
162 if (face_range_on_normal <
data.best_edgenet_range_on_face_normal) {
163 data.r_best_face =
nullptr;
166 best_face =
data.r_best_face;
206 r_pair_elem->
vert =
v;
211 int *r_data_cut_edges_len,
214 r_pair_elem->
edge =
e;
215 r_pair_elem->
lambda = lambda;
234 int *data_cut_edges_len,
238 float dist_sq_vert_factor;
247 dist_sq_vert_factor = lambda;
251 dist_sq_vert_factor = 1.0f - lambda;
256 if (dist_sq_vert < data_dist_sq) {
265 if (dist_sq < data_dist_sq) {
293 if (index_a < index_b) {
307 float co[3], dir[3], lambda;
314 v,
e, co, dir, lambda,
data->dist_sq, &
data->cut_edges_len, pair_tmp))
317 pair[0] = pair_tmp[0];
318 pair[1] = pair_tmp[1];
331 const float dir_a[3],
333 const float dir_b[3],
338 float dist_sq_va_factor, dist_sq_vb_factor;
340 if (lambda_a < 0.5f) {
342 dist_sq_va_factor = lambda_a;
346 dist_sq_va_factor = 1.0f - lambda_a;
349 if (lambda_b < 0.5f) {
351 dist_sq_vb_factor = lambda_b;
355 dist_sq_vb_factor = 1.0f - lambda_b;
358 if (e_a_v != e_b_v) {
367 if (dist_sq_va < data->dist_sq || dist_sq_vb < data->dist_sq) {
372 float near_a[3], near_b[3];
377 if (dist_sq < data->dist_sq) {
397 float co_a[3], dir_a[3], co_b[3], dir_b[3];
404 float lambda_a, lambda_b;
409 data, e_a, e_b, co_a, dir_a, co_b, dir_b, lambda_a, lambda_b, pair_tmp))
413 pair[0] = pair_tmp[0];
414 pair[1] = pair_tmp[1];
424 if (index_a < index_b) {
440 for (
int i = 0;
i < parallel_tasks_num;
i++) {
441 if (pair_stack[
i] ==
nullptr) {
445 data->pair_stack = pair_stack;
455 const int index1 = *(
int *)index1_v;
456 const int index2 = *(
int *)index2_v;
458 if (pair_flat[index1].lambda > pair_flat[index2].lambda) {
467#define INTERSECT_EDGES
470 BMesh *
bm,
const char hflag,
const float dist,
const bool split_faces,
GHash *r_targetmap)
484 BLI_Stack **pair_stack_vertxvert = pair_stack;
487 const float dist_sq =
square_f(dist);
488 const float dist_half = dist / 2;
492 data.pair_stack = pair_stack;
493 data.cut_edges_len = 0;
494 data.dist_sq = dist_sq;
500 int verts_act_len = 0, verts_remain_len = 0;
519 BVHTree *tree_verts_act =
nullptr, *tree_verts_remain =
nullptr;
523 if (verts_remain_len) {
528 if (tree_verts_act || tree_verts_remain) {
531 if (tree_verts_act) {
540 if (tree_verts_act) {
547 if (tree_verts_remain) {
551 if (tree_verts_act && tree_verts_remain) {
558 if (pair_stack_vertxvert[
i]) {
563#ifdef INTERSECT_EDGES
564 uint vertxvert_pair_len = pair_len;
566# define EDGE_ACT_TO_TEST 1
567# define EDGE_REMAIN_TO_TEST 2
569 int edges_act_len = 0, edges_remain_len = 0;
597 BVHTree *tree_edges_act =
nullptr, *tree_edges_remain =
nullptr;
602 if (edges_remain_len && (tree_edges_act || tree_verts_act)) {
607 if (tree_edges_act || tree_edges_remain) {
625# ifdef INTERSECT_EDGES_DEBUG
633# undef EDGE_ACT_TO_TEST
634# undef EDGE_REMAIN_TO_TEST
639 if (tree_edges_act) {
643 if (tree_edges_remain) {
647 int edgexedge_pair_len = 0;
648 if (tree_edges_act) {
653 if (tree_edges_remain) {
659 if (pair_stack_edgexelem[
i]) {
664 if (tree_verts_act) {
670 if (tree_verts_remain) {
679 if (tree_verts_act && tree_edges_remain) {
687 int edgexelem_pair_len = 0;
689 if (pair_stack_edgexelem[
i]) {
694 pair_len += edgexelem_pair_len;
695 int edgexvert_pair_len = edgexelem_pair_len - edgexedge_pair_len;
697 if (edgexelem_pair_len) {
699 MEM_mallocN(
sizeof(*pair_array) * pair_len, __func__));
701 pair_iter = pair_array;
711 union EdgeIntersectionsMap {
717 } *e_map_iter, *e_map;
719# ifdef INTERSECT_EDGES_DEBUG
720 int cut_edges_len = 0;
722 if (
e->head.index != 0) {
729 size_t e_map_size = (
data.cut_edges_len *
sizeof(*e_map)) +
730 ((
size_t(2) * edgexedge_pair_len + edgexvert_pair_len) *
731 sizeof(*(e_map->cuts_index)));
733 e_map =
static_cast<EdgeIntersectionsMap *
>(
MEM_mallocN(e_map_size, __func__));
742 pair_flat = (
EDBMSplitElem *)&pair_array[vertxvert_pair_len];
743 pair_flat_iter = &pair_flat[0];
744 uint pair_flat_len = 2 * edgexelem_pair_len;
745 for (
i = 0;
i < pair_flat_len;
i++, pair_flat_iter++) {
750 e = pair_flat_iter->
edge;
753 int e_cuts_len =
e->head.index;
755 e_map_iter = (EdgeIntersectionsMap *)&e_map->as_int[map_len];
756 e_map_iter->cuts_len = e_cuts_len;
757 e_map_iter->cuts_index[0] =
i;
760 e->head.index = map_len + 1;
761 map_len += 1 + e_cuts_len;
764 e_map->as_int[++
e->head.index] =
i;
769 for (
i = 0;
i < map_len;
770 e_map_iter = (EdgeIntersectionsMap *)&e_map->as_int[
i],
i += 1 + e_map_iter->cuts_len)
775 e_map_iter->cuts_len,
776 sizeof(*(e_map->cuts_index)),
780 float lambda, lambda_prev = 0.0f;
781 for (
int j = 0; j < e_map_iter->cuts_len; j++) {
782 uint index = e_map_iter->cuts_index[j];
785 lambda = (pair_elem->
lambda - lambda_prev) / (1.0f - lambda_prev);
786 lambda_prev = pair_elem->
lambda;
795 pair_elem->
vert = v_new;
808 if (pair_len && pair_array ==
nullptr) {
810 MEM_mallocN(
sizeof(*pair_array) * pair_len, __func__));
811 pair_iter = pair_array;
823 pair_iter = &pair_array[0];
824 for (
i = 0;
i < pair_len;
i++, pair_iter++) {
827 BLI_assert((*pair_iter)[0].elem != (*pair_iter)[1].elem);
828 v_key = (*pair_iter)[0].vert;
829 v_val = (*pair_iter)[1].vert;
841 pair_iter = &pair_array[0];
842 for (
i = 0;
i < pair_len;
i++, pair_iter++) {
843 v_key = (*pair_iter)[0].vert;
844 v_val = (*pair_iter)[1].vert;
849 if (v_val != (*pair_iter)[1].vert) {
851 *v_val_p = (*pair_iter)[1].vert = v_val;
861 BMEdge **edgenet =
nullptr;
862 int edgenet_alloc_len = 0;
871 BMVert *va, *vb, *va_dest =
nullptr;
877 if (v_cut == -1 && v_cut_other == -1) {
895 v_cut += v_cut % 2 ? -1 : 1;
896 va_dest = pair_flat[v_cut].
vert;
905 BMFace *best_face =
nullptr;
906 BMVert *v_other_dest, *v_other = vb;
910 if (v_cut_other != -1) {
911 v_cut_other += v_cut_other % 2 ? -1 : 1;
912 v_other_dest = pair_flat[v_cut_other].
vert;
923 v_other_dest = v_other;
926 if (va_dest == v_other_dest) {
935 if (edgenet_alloc_len == edgenet_len) {
936 edgenet_alloc_len = (edgenet_alloc_len + 1) * 2;
937 edgenet =
static_cast<BMEdge **
>(
938 MEM_reallocN(edgenet, (edgenet_alloc_len) *
sizeof(*edgenet)));
940 edgenet[edgenet_len++] = e_net;
943 va_dest, v_other_dest, edgenet, edgenet_len, dist);
955 if (edgenet_len > 1) {
963 if ((edgenet_len > 1) && (v_other_dest != v_other) &&
973 e_net = edgenet[edgenet_len - 1];
980 BMEdge *e_test = e_net, *e_next =
nullptr;
1001 if (e_next ==
nullptr) {
1007 if (v_other == va) {
1019 for (
BMFace *face : face_arr) {
1034 if (pair_stack[
i]) {
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) 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)
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
bool(*)(void *userdata, int index_a, int index_b, int thread) BVHTree_OverlapCallback
@ BVH_OVERLAP_USE_THREADING
void BLI_bvhtree_balance(BVHTree *tree)
void BLI_bvhtree_free(BVHTree *tree)
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
BVHTreeOverlap * BLI_bvhtree_overlap_ex(const BVHTree *tree1, const BVHTree *tree2, uint *r_overlap_num, BVHTree_OverlapCallback callback, void *userdata, uint max_interactions, int flag)
int BLI_bvhtree_overlap_thread_num(const BVHTree *tree)
MINLINE float square_f(float a)
bool isect_ray_ray_v3(const float ray_origin_a[3], const float ray_direction_a[3], const float ray_origin_b[3], const float ray_direction_b[3], float *r_lambda_a, float *r_lambda_b)
float ray_point_factor_v3_ex(const float p[3], const float ray_origin[3], const float ray_direction[3], float epsilon, float fallback)
bool isect_ray_ray_epsilon_v3(const float ray_origin_a[3], const float ray_direction_a[3], const float ray_origin_b[3], const float ray_direction_b[3], float epsilon, float *r_lambda_a, float *r_lambda_b)
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
void BLI_qsort_r(void *a, size_t n, size_t es, BLI_sort_cmp_t cmp, void *thunk)
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_free(BLI_Stack *stack) ATTR_NONNULL()
void * BLI_stack_push_r(BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define BLI_stack_new(esize, descr)
#define IN_RANGE(a, b, c)
#define IN_RANGE_INCL(a, b, c)
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE int32_t atomic_fetch_and_add_int32(int32_t *p, int32_t x)
#define BM_DISK_EDGE_NEXT(e, v)
BMEdge * BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
Main function for creating a new edge.
#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)
bool BM_mesh_intersect_edges(BMesh *bm, const char hflag, const float dist, const bool split_faces, GHash *r_targetmap)
static bool bm_vertxvert_self_isect_cb(void *userdata, int index_a, int index_b, int thread)
static bool bm_vert_pair_share_best_splittable_face_cb(BMFace *f, BMLoop *l_a, BMLoop *l_b, void *userdata)
static bool bm_edgexvert_isect_impl(BMVert *v, BMEdge *e, const float co[3], const float dir[3], float lambda, float data_dist_sq, int *data_cut_edges_len, EDBMSplitElem r_pair[2])
static bool bm_edgexedge_isect_impl(EDBMSplitData *data, BMEdge *e_a, BMEdge *e_b, const float co_a[3], const float dir_a[3], const float co_b[3], const float dir_b[3], float lambda_a, float lambda_b, EDBMSplitElem r_pair[2])
static void bm_edge_pair_elem_setup(BMEdge *e, float lambda, int *r_data_cut_edges_len, EDBMSplitElem *r_pair_elem)
static void bm_elemxelem_bvhtree_overlap(const BVHTree *tree1, const BVHTree *tree2, BVHTree_OverlapCallback callback, EDBMSplitData *data, BLI_Stack **pair_stack)
static bool bm_edgexedge_self_isect_cb(void *userdata, int index_a, int index_b, int thread)
static BMFace * bm_vert_pair_best_face_get(BMVert *v_a, BMVert *v_b, BMEdge **edgenet, const int edgenet_len, const float epsilon)
static int sort_cmp_by_lambda_cb(const void *index1_v, const void *index2_v, void *keys_v)
#define EDGE_REMAIN_TO_TEST
#define BLI_STACK_PAIR_LEN
static bool bm_vertxvert_isect_cb(void *userdata, int index_a, int index_b, int thread)
static bool bm_vert_pair_share_splittable_face_cb(BMFace *, BMLoop *l_a, BMLoop *l_b, void *userdata)
static void bm_vert_pair_elem_setup_ex(BMVert *v, EDBMSplitElem *r_pair_elem)
static bool bm_edgexedge_isect_cb(void *userdata, int index_a, int index_b, int thread)
static bool bm_edgexvert_isect_cb(void *userdata, int index_a, int index_b, int thread)
#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)
BMesh const char void * data
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
BLI_INLINE BMEdge * BM_edge_at_index(BMesh *bm, const int index)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
BMVert * BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
Edge Split.
bool BM_face_point_inside_test(const BMFace *f, const float co[3])
void BM_face_normal_update(BMFace *f)
bool BM_face_split_edgenet(BMesh *bm, BMFace *f, BMEdge **edge_net, const int edge_net_len, blender::Vector< BMFace * > *r_face_arr)
bool BM_vert_pair_share_face_check(BMVert *v_a, BMVert *v_b)
bool BM_edge_in_face(const BMEdge *e, const BMFace *f)
bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2)
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
BMFace * BM_vert_pair_shared_face_cb(BMVert *v_a, BMVert *v_b, const bool allow_adjacent, bool(*callback)(BMFace *, BMLoop *, BMLoop *, void *userdata), void *user_data, BMLoop **r_l_a, BMLoop **r_l_b)
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 const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMLoop * l_b
ATTR_WARN_UNUSED_RESULT const BMVert * v
bool closest(btVector3 &v)
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
void * MEM_mallocN(size_t len, const char *str)
void MEM_freeN(void *vmemh)
ccl_device_inline int as_int(const uint i)
float best_edgenet_range_on_face_normal