43#define CONNECT_EPS 0.0001f
53#define FACE_WALK_TEST(f) \
54 (CHECK_TYPE_INLINE(f, BMFace *), BMO_face_flag_test(pc->bm_bmoflag, f, FACE_EXCLUDE) == 0)
55#define VERT_WALK_TEST(v) \
56 (CHECK_TYPE_INLINE(v, BMVert *), BMO_vert_flag_test(pc->bm_bmoflag, v, VERT_EXCLUDE) == 0)
59# define ELE_TOUCH_TEST(e) \
60 (CHECK_TYPE_ANY(e, BMVert *, BMEdge *, BMElem *, BMElemF *), \
61 BMO_elem_flag_test(pc->bm_bmoflag, (BMElemF *)e, ELE_TOUCHED))
63#define ELE_TOUCH_MARK(e) \
65 CHECK_TYPE_ANY(e, BMVert *, BMEdge *, BMElem *, BMElemF *); \
66 BMO_elem_flag_enable(pc->bm_bmoflag, (BMElemF *)e, ELE_TOUCHED); \
70#define ELE_TOUCH_TEST_VERT(v) BMO_vert_flag_test(pc->bm_bmoflag, v, ELE_TOUCHED)
73#define ELE_TOUCH_TEST_EDGE(e) BMO_edge_flag_test(pc->bm_bmoflag, e, ELE_TOUCHED)
133#define MIN_DIST_DIR_INIT \
147 if (dist_sq < mddir->dist_min[0]) {
152 if (dist_sq < mddir->dist_min[1]) {
174 const int test_a = (
fabsf(diff_a) <
CONNECT_EPS) ? 0 : (diff_a < 0.0f) ? -1 : 1;
175 const int test_b = (
fabsf(diff_b) <
CONNECT_EPS) ? 0 : (diff_b < 0.0f) ? -1 : 1;
177 if ((test_a && test_b) && (test_a != test_b)) {
193 float diff_a, diff_b, diff_tot;
197 diff_tot = (diff_a + diff_b);
198 return (diff_tot > FLT_EPSILON) ? (diff_a / diff_tot) : 0.5f;
221 if (link->
ele == ele) {
224 }
while ((link = link->
next));
251 if (ele_from ==
nullptr) {
288 state->link_last = step_new;
294 *
state = *state_orig;
328 BMLoop *l_iter_best[2] = {
nullptr,
nullptr};
351 l_iter_best[index] = l_iter;
355 }
while ((l_iter = l_iter->
next) != l_last);
357 for (i = 0; i < 2; i++) {
358 if ((l_iter = l_iter_best[i])) {
376 BMLoop *l_iter_best[2] = {
nullptr,
nullptr};
382 const float *co_isect = l_iter->
v->
co;
397 l_iter_best[index] = l_iter;
401 }
while ((l_iter = l_iter->
next) != l_last);
403 for (i = 0; i < 2; i++) {
404 if ((l_iter = l_iter_best[i])) {
418 const void *ele_from =
state->link_last->ele_from;
432 pc,
state, &state_orig, l_start->
next->
next, l_start, &mddir);
449 pc,
state, &state_orig, l_start->
next, l_start->
prev, &mddir);
450 if (l_start->
f->
len > 3) {
488 const float eps = 1e-8f;
494 sub_v3_v3v3(basis_dir, v_pair[0]->co, v_pair[1]->co);
498 add_v3_v3v3(basis_nor, v_pair[0]->no, v_pair[1]->no);
504 float basis_nor_a[3];
505 float basis_nor_b[3];
516 if (
dot_v3v3(basis_nor_a, basis_nor_b) < 0.0f) {
538 for (i = 0; i < 2; i++) {
543 axis_pair[i].angle_cos = -
FLT_MAX;
546 float basis_dir_proj[3];
547 float angle_cos_test;
553 angle_cos_test =
dot_v3v3(basis_dir_proj, basis_dir);
555 if (angle_cos_test > axis_pair[i].angle_cos) {
556 axis_pair[i].angle_cos = angle_cos_test;
566 copy_v3_v3(basis_nor, axis_pair[axis_pair[0].angle_cos < axis_pair[1].angle_cos].
nor);
595 if (op_verts_slot->
len != 2) {
648 bool continue_search;
659 continue_search =
false;
662 continue_search =
true;
671 continue_search =
false;
674 if (continue_search) {
703 }
while ((link = link->
next));
719 "connect_verts verts=%fv faces_exclude=%s check_degenerate=%b",
A min-heap / priority queue ADT.
HeapSimple * BLI_heapsimple_new(void) ATTR_WARN_UNUSED_RESULT
void BLI_heapsimple_clear(HeapSimple *heap, HeapSimpleFreeFP ptrfreefp) ATTR_NONNULL(1)
void BLI_heapsimple_free(HeapSimple *heap, HeapSimpleFreeFP ptrfreefp) ATTR_NONNULL(1)
void * BLI_heapsimple_pop_min(HeapSimple *heap) ATTR_NONNULL(1)
bool BLI_heapsimple_is_empty(const HeapSimple *heap) ATTR_NONNULL(1)
uint BLI_heapsimple_len(const HeapSimple *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_heapsimple_insert(HeapSimple *heap, float value, void *ptr) ATTR_NONNULL(1)
void unit_m3(float m[3][3])
bool invert_m3(float mat[3][3])
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_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 float dot_m3_v3_row_x(const float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
void ortho_v3_v3(float out[3], const float v[3])
MINLINE void negate_v3(float r[3])
MINLINE void zero_v2(float r[2])
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)
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)
Read Guarded memory(de)allocation.
#define BM_elem_index_get(ele)
#define BM_ITER_ELEM(ele, iter, data, itype)
ATTR_WARN_UNUSED_RESULT BMesh * bm
BMVert * BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
Edge Split.
void BMO_slot_buffer_flag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, short oflag)
BMO_FLAG_BUFFER.
#define BMO_vert_flag_enable(bm, e, oflag)
BMOpSlot * BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
BMESH OPSTACK GET SLOT.
void BMO_op_exec(BMesh *bm, BMOperator *op)
BMESH OPSTACK EXEC OP.
#define BMO_slot_copy(op_src, slots_src, slot_name_src, op_dst, slots_dst, slot_name_dst)
bool BMO_op_initf(BMesh *bm, BMOperator *op, int flag, const char *fmt,...)
void BMO_op_finish(BMesh *bm, BMOperator *op)
BMESH OPSTACK FINISH OP.
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define ELE_TOUCH_TEST_VERT(v)
static int state_isect_co_exact(const PathContext *pc, const float co[3])
#define FACE_WALK_TEST(f)
static int min_dist_dir_test(MinDistDir *mddir, const float dist_dir[3], const float dist_sq)
#define VERT_WALK_TEST(v)
static bool state_step(PathContext *pc, PathLinkState *state)
void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op)
static PathLinkState * state_step__face_edges(PathContext *pc, PathLinkState *state, const PathLinkState *state_orig, BMLoop *l_iter, BMLoop *l_last, MinDistDir *mddir)
static float state_calc_co_pair_fac(const PathContext *pc, const float co_a[3], const float co_b[3])
static void min_dist_dir_update(MinDistDir *dist, const float dist_dir[3])
static PathLinkState * state_dupe_add(PathLinkState *state, const PathLinkState *state_orig)
static bool state_link_find(const PathLinkState *state, BMElem *ele)
#define ELE_TOUCH_MARK(e)
#define ELE_TOUCH_TEST_EDGE(e)
static int state_isect_co_pair(const PathContext *pc, const float co_a[3], const float co_b[3])
static PathLinkState * state_step__face_verts(PathContext *pc, PathLinkState *state, const PathLinkState *state_orig, BMLoop *l_iter, BMLoop *l_last, MinDistDir *mddir)
static void state_link_add(PathContext *pc, PathLinkState *state, BMElem *ele, BMElem *ele_from)
static void bm_vert_pair_to_matrix(BMVert *v_pair[2], float r_unit_mat[3][3])
static PathLinkState * state_link_add_test(PathContext *pc, PathLinkState *state, const PathLinkState *state_orig, BMElem *ele, BMElem *ele_from)
#define MIN_DIST_DIR_INIT
static void state_calc_co_pair(const PathContext *pc, const float co_a[3], const float co_b[3], float r_co[3])
static double op_sub(double a, double b)
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt)
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
Frequency::GEOMETRY nor[]
union BMOpSlot::@139 data
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]