24#define USE_DUPLICATE_FACE_VERT_CHECK
34 const float merge_factor)
49 }
while ((
void)(el_b = el_b->
next), (el_a = el_a->
next));
90 }
while ((
void)(el_b = el_b->
next ? el_b->
next : el_b_first),
91 (el_a = el_a->
next) && (
len < len_max));
106 for (; el_b; el_b = el_b->
next) {
108 if (
len < len_best) {
125 }
while ((l_iter = l_iter->
next) != l_first);
136 const bool use_merge,
137 const float merge_factor,
138 const int twist_offset)
140 const float eps = 0.00001f;
143 int el_store_a_len, el_store_b_len;
144 bool el_store_b_free =
false;
147 const bool use_edgeout =
true;
152 if (el_store_a_len < el_store_b_len) {
153 std::swap(el_store_a_len, el_store_b_len);
154 std::swap(el_store_a, el_store_b);
161 if (el_store_a_len != el_store_b_len) {
178 float dir_a_orig[3], dir_b_orig[3];
179 float dir_a[3], dir_b[3];
180 const float *test_a, *test_b;
218 if (
dot_v3v3(test_a, test_b) < 0.0f) {
238 else if ((dot_a < 0.0f) != (dot_b < 0.0f)) {
243 if (use_merge ==
false) {
257 int winding_votes[2] = {0, 0};
259 for (i = 0; i < 2; i++, winding_dir = -winding_dir) {
266 winding_votes[i] += ((
e->l->v == el->data) ? winding_dir : -winding_dir);
272 if (winding_votes[0] || winding_votes[1]) {
273 bool flip[2] = {
false,
false};
278 if (winding_votes[0] < 0) {
280 winding_votes[0] *= -1;
284 if (winding_votes[1] < 0) {
286 winding_votes[1] *= -1;
291 if ((winding_votes[0] + winding_votes[1]) < 0) {
297 winding_votes[0] *= -1;
298 winding_votes[1] *= -1;
312 if (el_store_a_len > el_store_b_len) {
315 el_store_b_free =
true;
322 if (twist_offset != 0) {
347 BMVert *v_a, *v_b, *v_a_next, *v_b_next;
351 BMLoop *l_a_next =
nullptr;
352 BMLoop *l_b_next =
nullptr;
359 el_a_next = el_a->
next;
360 el_b_next = el_b->
next;
361 if (
ELEM(
nullptr, el_a_next, el_b_next)) {
368 v_a_next =
static_cast<BMVert *
>(el_a_next->
data);
369 v_b_next =
static_cast<BMVert *
>(el_b_next->
data);
372 if (v_b != v_b_next) {
382 if (l_a && l_a_next ==
nullptr) {
385 if (l_a_next && l_a ==
nullptr) {
388 if (
l_b && l_b_next ==
nullptr) {
391 if (l_b_next &&
l_b ==
nullptr) {
394 f_example = l_a ? l_a->
f : (
l_b ?
l_b->
f :
nullptr);
396 if (v_b != v_b_next) {
397#ifdef USE_DUPLICATE_FACE_VERT_CHECK
398 BLI_assert((v_b != v_b_next) && (v_a_next != v_a));
405 BMVert *v_arr[4] = {v_b, v_b_next, v_a_next, v_a};
415 l_iter = l_iter->
next;
419 l_iter = l_iter->
next;
423 l_iter = l_iter->
next;
431#ifdef USE_DUPLICATE_FACE_VERT_CHECK
439 BMVert *v_arr[3] = {v_b, v_a_next, v_a};
449 l_iter = l_iter->
next;
453 l_iter = l_iter->
next;
461#ifdef USE_DUPLICATE_FACE_VERT_CHECK
465 if (f_example && (f_example != f)) {
477 if (el_a_next == el_a_first) {
486 if (el_store_a_len != el_store_b_len) {
510 for (i = 0; i < 2; i++) {
519 "beautify_fill faces=%hf edges=ae use_restrict_tag=%b method=%i",
551 if (use_edgeout && use_merge ==
false) {
555 for (i = 0; i < 2; i++) {
559 if (el->data != el_next->
data) {
569 if (el_store_b_free) {
585 bool changed =
false;
598 if (use_pairs && (
count % 2)) {
628 if (el_store_next ==
nullptr) {
629 if (use_cyclic && (
count > 2)) {
644 el_store = el_store->
next;
653 if (use_merge ==
false) {
void * BLI_rfindlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
void BLI_listbase_rotate_first(struct ListBase *lb, void *vlink) ATTR_NONNULL(1
MINLINE int mod_i(int i, int n)
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_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])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
#define BM_FACE_FIRST_LOOP(p)
void BM_elem_attrs_copy(BMesh *bm, const BMCustomDataCopyMap &map, const BMVert *src, BMVert *dst)
BMFace * BM_face_create_verts(BMesh *bm, BMVert **vert_arr, const int len, const BMFace *f_example, const eBMCreateFlag create_flag, const bool create_edges)
void BM_mesh_edgeloops_calc_order(BMesh *, ListBase *eloops, const bool use_normals)
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)
void BM_edgeloop_flip(BMesh *, BMEdgeLoopStore *el_store)
BMEdgeLoopStore * BM_edgeloop_copy(BMEdgeLoopStore *el_store)
bool BM_edgeloop_calc_normal(BMesh *, BMEdgeLoopStore *el_store)
int BM_mesh_edgeloops_find(BMesh *bm, ListBase *r_eloops, bool(*test_fn)(BMEdge *, void *user_data), void *user_data)
int BM_edgeloop_length_get(BMEdgeLoopStore *el_store)
const float * BM_edgeloop_normal_get(BMEdgeLoopStore *el_store)
bool BM_edgeloop_calc_normal_aligned(BMesh *, BMEdgeLoopStore *el_store, const float no_align[3])
bool BM_edgeloop_is_closed(BMEdgeLoopStore *el_store)
const float * BM_edgeloop_center_get(BMEdgeLoopStore *el_store)
void BM_mesh_edgeloops_calc_normal(BMesh *bm, ListBase *eloops)
ListBase * BM_edgeloop_verts_get(BMEdgeLoopStore *el_store)
void BM_mesh_edgeloops_calc_center(BMesh *bm, ListBase *eloops)
#define BM_EDGELINK_NEXT(el_store, elink)
void BMO_error_raise(BMesh *bm, BMOperator *owner, eBMOpErrorLevel level, const char *msg) ATTR_NONNULL(1
#define BM_elem_flag_set(ele, hflag, val)
#define BM_elem_flag_enable(ele, hflag)
void BM_data_interp_from_verts(BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v_dst, const float fac)
Data, Interpolate From Verts.
void * BM_iter_at_index(BMesh *bm, const char itype, void *data, int index)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
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.
void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, char hflag, bool do_flush)
BMO_FLAG_BUFFER.
#define BMO_edge_flag_test(bm, e, oflag)
#define BMO_edge_flag_enable(bm, e, oflag)
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
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.
void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, short oflag)
#define BMO_face_flag_enable(bm, e, oflag)
void BMO_op_init(BMesh *bm, BMOperator *op, int flag, const char *opname)
BMESH OPSTACK INIT OP.
#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag)
bool BMO_op_initf(BMesh *bm, BMOperator *op, int flag, const char *fmt,...)
int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
void BMO_op_finish(BMesh *bm, BMOperator *op)
BMESH OPSTACK FINISH OP.
#define BMO_edge_flag_disable(bm, e, oflag)
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
BLI_INLINE void BMO_slot_map_elem_insert(BMOperator *op, BMOpSlot *slot, const void *element, void *val)
void BM_face_normal_update(BMFace *f)
BMFace * BM_face_exists(BMVert *const *varr, int len)
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
BLI_INLINE bool BM_edge_is_boundary(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 BMLoop * l_b
static void bm_bridge_splice_loops(BMesh *bm, LinkData *el_a, LinkData *el_b, const float merge_factor)
void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
static void bm_vert_loop_pair(BMesh *bm, BMVert *v1, BMVert *v2, BMLoop **l1, BMLoop **l2)
static void bm_bridge_best_rotation(BMEdgeLoopStore *el_store_a, BMEdgeLoopStore *el_store_b)
static void bridge_loop_pair(BMesh *bm, BMEdgeLoopStore *el_store_a, BMEdgeLoopStore *el_store_b, const bool use_merge, const float merge_factor, const int twist_offset)
static float bm_edgeloop_offset_length(LinkData *el_a, LinkData *el_b, LinkData *el_b_first, const float len_max)
static bool bm_edge_test_cb(BMEdge *e, void *bm_v)
static void bm_face_edges_tag_out(BMesh *bm, BMFace *f)
static double op_sub(double a, double b)
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]