27#define KDOP_TREE_TYPE 4
28#define KDOP_AXIS_LEN 14
29#define BLI_STACK_PAIR_LEN (2 * KDOP_TREE_TYPE)
66 BMEdge **e_iter = &data->edgenet[0];
67 BMEdge *e_next = data->edgenet[1];
68 BMVert *v_test =
ELEM((*e_iter)->v1, e_next->
v1, e_next->
v2) ? (*e_iter)->v2 : (*e_iter)->v1;
70 int verts_len = data->edgenet_len - 1;
71 for (
int i = verts_len; i--; e_iter++) {
86 const float test_edgenet_range_on_face_normal = max -
min;
87 if (test_edgenet_range_on_face_normal < data->best_edgenet_range_on_face_normal) {
88 data->best_edgenet_range_on_face_normal = test_edgenet_range_on_face_normal;
89 data->r_best_face = f;
101 float(*data)[3] =
static_cast<float(*)[3]
>(userdata);
102 float *v_a_co = data[0];
103 float *v_a_b_dir = data[1];
104 const float range_min = -FLT_EPSILON;
105 const float range_max = 1.0f + FLT_EPSILON;
114 if (
IN_RANGE(lambda_b, range_min, range_max)) {
120 return IN_RANGE(lambda_b, range_min, range_max);
127 BMVert *v_a,
BMVert *v_b,
BMEdge **edgenet,
const int edgenet_len,
const float epsilon)
129 BMFace *r_best_face =
nullptr;
134 if (edgenet_len == 1) {
145 data.edgenet_len = edgenet_len;
146 data.best_edgenet_range_on_face_normal =
FLT_MAX;
147 data.r_best_face =
nullptr;
152 if (data.r_best_face) {
167 float face_range_on_normal = max -
min + 2 * epsilon;
168 if (face_range_on_normal < data.best_edgenet_range_on_face_normal) {
169 data.r_best_face =
nullptr;
172 r_best_face = data.r_best_face;
212 r_pair_elem->
vert =
v;
217 int *r_data_cut_edges_len,
220 r_pair_elem->
edge =
e;
221 r_pair_elem->
lambda = lambda;
240 int *data_cut_edges_len,
244 float dist_sq_vert_factor;
253 dist_sq_vert_factor = lambda;
257 dist_sq_vert_factor = 1.0f - lambda;
262 if (dist_sq_vert < data_dist_sq) {
271 if (dist_sq < data_dist_sq) {
299 if (index_a < index_b) {
313 float co[3], dir[3], lambda;
320 v,
e, co, dir, lambda, data->dist_sq, &data->cut_edges_len, pair_tmp))
323 pair[0] = pair_tmp[0];
324 pair[1] = pair_tmp[1];
337 const float dir_a[3],
339 const float dir_b[3],
344 float dist_sq_va_factor, dist_sq_vb_factor;
346 if (lambda_a < 0.5f) {
348 dist_sq_va_factor = lambda_a;
352 dist_sq_va_factor = 1.0f - lambda_a;
355 if (lambda_b < 0.5f) {
357 dist_sq_vb_factor = lambda_b;
361 dist_sq_vb_factor = 1.0f - lambda_b;
364 if (e_a_v != e_b_v) {
373 if (dist_sq_va < data->dist_sq || dist_sq_vb < data->dist_sq) {
378 float near_a[3], near_b[3];
383 if (dist_sq < data->dist_sq) {
403 float co_a[3], dir_a[3], co_b[3], dir_b[3];
410 float lambda_a, lambda_b;
415 data, e_a, e_b, co_a, dir_a, co_b, dir_b, lambda_a, lambda_b, pair_tmp))
419 pair[0] = pair_tmp[0];
420 pair[1] = pair_tmp[1];
430 if (index_a < index_b) {
446 for (
int i = 0; i < parallel_tasks_num; i++) {
447 if (pair_stack[i] ==
nullptr) {
451 data->pair_stack = pair_stack;
461 const int index1 = *(
int *)index1_v;
462 const int index2 = *(
int *)index2_v;
464 if (pair_flat[index1].lambda > pair_flat[index2].lambda) {
473#define INTERSECT_EDGES
476 BMesh *
bm,
const char hflag,
const float dist,
const bool split_faces,
GHash *r_targetmap)
490 BLI_Stack **pair_stack_vertxvert = pair_stack;
493 const float dist_sq =
square_f(dist);
494 const float dist_half = dist / 2;
498 data.pair_stack = pair_stack;
499 data.cut_edges_len = 0;
500 data.dist_sq = dist_sq;
501 data.dist_sq_sq =
square_f(dist_sq);
506 int verts_act_len = 0, verts_remain_len = 0;
525 BVHTree *tree_verts_act =
nullptr, *tree_verts_remain =
nullptr;
529 if (verts_remain_len) {
534 if (tree_verts_act || tree_verts_remain) {
537 if (tree_verts_act) {
546 if (tree_verts_act) {
553 if (tree_verts_remain) {
557 if (tree_verts_act && tree_verts_remain) {
564 if (pair_stack_vertxvert[i]) {
569#ifdef INTERSECT_EDGES
570 uint vertxvert_pair_len = pair_len;
572# define EDGE_ACT_TO_TEST 1
573# define EDGE_REMAIN_TO_TEST 2
575 int edges_act_len = 0, edges_remain_len = 0;
603 BVHTree *tree_edges_act =
nullptr, *tree_edges_remain =
nullptr;
608 if (edges_remain_len && (tree_edges_act || tree_verts_act)) {
613 if (tree_edges_act || tree_edges_remain) {
631# ifdef INTERSECT_EDGES_DEBUG
639# undef EDGE_ACT_TO_TEST
640# undef EDGE_REMAIN_TO_TEST
645 if (tree_edges_act) {
649 if (tree_edges_remain) {
653 int edgexedge_pair_len = 0;
654 if (tree_edges_act) {
659 if (tree_edges_remain) {
665 if (pair_stack_edgexelem[i]) {
670 if (tree_verts_act) {
676 if (tree_verts_remain) {
685 if (tree_verts_act && tree_edges_remain) {
693 int edgexelem_pair_len = 0;
695 if (pair_stack_edgexelem[i]) {
700 pair_len += edgexelem_pair_len;
701 int edgexvert_pair_len = edgexelem_pair_len - edgexedge_pair_len;
703 if (edgexelem_pair_len) {
705 MEM_mallocN(
sizeof(*pair_array) * pair_len, __func__));
707 pair_iter = pair_array;
717 union EdgeIntersectionsMap {
723 } *e_map_iter, *e_map;
725# ifdef INTERSECT_EDGES_DEBUG
726 int cut_edges_len = 0;
732 BLI_assert(cut_edges_len == data.cut_edges_len);
735 size_t e_map_size = (data.cut_edges_len *
sizeof(*e_map)) +
736 ((
size_t(2) * edgexedge_pair_len + edgexvert_pair_len) *
737 sizeof(*(e_map->cuts_index)));
739 e_map =
static_cast<EdgeIntersectionsMap *
>(
MEM_mallocN(e_map_size, __func__));
748 pair_flat = (
EDBMSplitElem *)&pair_array[vertxvert_pair_len];
749 pair_flat_iter = &pair_flat[0];
750 uint pair_flat_len = 2 * edgexelem_pair_len;
751 for (i = 0; i < pair_flat_len; i++, pair_flat_iter++) {
756 e = pair_flat_iter->
edge;
761 e_map_iter = (EdgeIntersectionsMap *)&e_map->as_int[map_len];
762 e_map_iter->cuts_len = e_cuts_len;
763 e_map_iter->cuts_index[0] = i;
767 map_len += 1 + e_cuts_len;
775 for (i = 0; i < map_len;
776 e_map_iter = (EdgeIntersectionsMap *)&e_map->as_int[i], i += 1 + e_map_iter->cuts_len)
781 e_map_iter->cuts_len,
782 sizeof(*(e_map->cuts_index)),
786 float lambda, lambda_prev = 0.0f;
787 for (
int j = 0; j < e_map_iter->cuts_len; j++) {
788 uint index = e_map_iter->cuts_index[j];
791 lambda = (pair_elem->
lambda - lambda_prev) / (1.0f - lambda_prev);
792 lambda_prev = pair_elem->
lambda;
801 pair_elem->
vert = v_new;
814 if (pair_len && pair_array ==
nullptr) {
816 MEM_mallocN(
sizeof(*pair_array) * pair_len, __func__));
817 pair_iter = pair_array;
829 pair_iter = &pair_array[0];
830 for (i = 0; i < pair_len; i++, pair_iter++) {
833 BLI_assert((*pair_iter)[0].elem != (*pair_iter)[1].elem);
834 v_key = (*pair_iter)[0].vert;
835 v_val = (*pair_iter)[1].vert;
847 pair_iter = &pair_array[0];
848 for (i = 0; i < pair_len; i++, pair_iter++) {
849 v_key = (*pair_iter)[0].vert;
850 v_val = (*pair_iter)[1].vert;
855 if (v_val != (*pair_iter)[1].vert) {
857 *v_val_p = (*pair_iter)[1].vert = v_val;
867 BMEdge **edgenet =
nullptr;
868 int edgenet_alloc_len = 0;
877 BMVert *va, *vb, *va_dest =
nullptr;
883 if (v_cut == -1 && v_cut_other == -1) {
901 v_cut += v_cut % 2 ? -1 : 1;
902 va_dest = pair_flat[v_cut].
vert;
911 BMFace *best_face =
nullptr;
912 BMVert *v_other_dest, *v_other = vb;
916 if (v_cut_other != -1) {
917 v_cut_other += v_cut_other % 2 ? -1 : 1;
918 v_other_dest = pair_flat[v_cut_other].
vert;
929 v_other_dest = v_other;
932 if (va_dest == v_other_dest) {
941 if (edgenet_alloc_len == edgenet_len) {
942 edgenet_alloc_len = (edgenet_alloc_len + 1) * 2;
943 edgenet =
static_cast<BMEdge **
>(
944 MEM_reallocN(edgenet, (edgenet_alloc_len) *
sizeof(*edgenet)));
946 edgenet[edgenet_len++] = e_net;
949 va_dest, v_other_dest, edgenet, edgenet_len, dist);
961 if (edgenet_len > 1) {
969 if ((edgenet_len > 1) && (v_other_dest != v_other) &&
979 e_net = edgenet[edgenet_len - 1];
986 BMEdge *e_test = e_net, *e_next =
nullptr;
1007 if (e_next ==
nullptr) {
1013 if (v_other == va) {
1025 for (
BMFace *face : face_arr) {
1040 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)
@ 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)
bool(* BVHTree_OverlapCallback)(void *userdata, int index_a, int index_b, int thread)
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)
ATTR_WARN_UNUSED_RESULT BMesh * bm
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
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
DEGForeachIDComponentCallback callback
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
float best_edgenet_range_on_face_normal
ccl_device_inline int as_int(uint i)