43#define VERT_MARK_PAIR 4
46#define VERT_MARK_TEAR 16
124 float no_a[3], no_b[3];
129 const float raw_factor = std::clamp(-
dot_v3v3(no_a, no_b), 0.0f, 1.0f);
180 if (use_edge_delete) {
199 if (use_edge_delete) {
206 if (use_edge_delete) {
266 if ((faces_init[0] =
static_cast<BMFace *
>(
BMW_begin(®walker, f))) &&
270 faces.append(faces_init[0]);
271 faces.append(faces_init[1]);
275 faces.append(f_iter);
290 int totface_target =
bm->totface;
302 totface_target -= faces_len - 1;
335 if (totface_target !=
bm->totface) {
430 const short edge_oflag,
464 const float angle_epsilon =
RAD2DEGF(0.0001f);
470 (angle_threshold > angle_epsilon);
473 const bool dissolve_all = (angle_threshold >
M_PI - angle_epsilon);
477 if (use_face_split || use_verts) {
498 for (j = 0; j < 2; j++) {
504 }
while ((l_iter = l_iter->
next) != l_first);
532 for (
int i = 0;
i < 2;
i++) {
544 if (f_pair[0]->
len == 3 && f_pair[1]->
len == 3 &&
558 if (v_edge ==
nullptr) {
587 if (use_face_split) {
598 if (untag_count <= 2) {
705 if (use_face_split) {
709 if (use_boundary_tear) {
727 BMEdge *e_first =
nullptr;
734 }
while ((l_iter = l_iter->
next) != l_first);
736 e_first = l_first->
e;
747 }
while ((
e = e_next) != e_first);
803 const float angle_max =
M_PI_2;
810 do_dissolve_boundaries,
822#define EDGE_COLLAPSE 2
832 const float dist_sq = dist * dist;
853 l_iter = l_first =
e->l;
856 }
while ((l_iter = l_iter->
radial_next) != l_first);
869 l_iter = l_first =
e->l;
884 float dir_prev[3], len_prev;
885 float dir_next[3], len_next;
893 if ((
len_v3v3(dir_prev, dir_next) *
min_ff(len_prev, len_next)) <= dist) {
896 if (
fabsf(len_prev - len_next) <= dist) {
898 if (l_iter->
f->
len == 3) {
907 bm, l_iter->
f, l_iter->
prev, l_iter->
next, &l_split,
nullptr,
true))
915 else if (len_prev < len_next) {
924 bm, l_iter->
f, l_iter->
prev, l_iter->
next, &l_split,
nullptr,
true))
931 else if (len_next < len_prev) {
940 bm, l_iter->
f, l_iter->
prev, l_iter->
next, &l_split,
nullptr,
true))
954 }
while ((l_iter = l_iter->
radial_next) != l_first);
MINLINE float min_ff(float a, float b)
MINLINE float interpf(float target, float origin, float t)
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
float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT
float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float n[3])
void BLI_stack_pop(BLI_Stack *stack, void *dst) ATTR_NONNULL()
void BLI_stack_push(BLI_Stack *stack, const void *src) ATTR_NONNULL()
bool BLI_stack_is_empty(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_stack_free(BLI_Stack *stack) ATTR_NONNULL()
#define BLI_stack_new(esize, descr)
#define UNUSED_FUNCTION(x)
#define UNUSED_VARS_NDEBUG(...)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Read Guarded memory(de)allocation.
#define BM_DISK_EDGE_NEXT(e, v)
#define BM_FACE_FIRST_LOOP(p)
BMFace * BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del, BMFace **r_double)
Join Connected Faces.
void BM_vert_kill(BMesh *bm, BMVert *v)
void BM_face_kill(BMesh *bm, BMFace *f)
void BM_edge_kill(BMesh *bm, BMEdge *e)
void BM_mesh_decimate_dissolve_ex(BMesh *bm, float angle_limit, bool do_dissolve_boundaries, BMO_Delimit delimit, BMVert **vinput_arr, int vinput_len, BMEdge **einput_arr, int einput_len, short oflag_out)
bool BMO_error_occurred_at_level(BMesh *bm, eBMOpErrorLevel level)
#define BM_elem_flag_merge_ex(ele_a, ele_b, hflag_and)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_test(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_MUTABLE(ele, ele_next, iter, bm, itype)
void BM_edge_select_set_noflush(BMesh *bm, BMEdge *e, const bool select)
BMVert * BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
Edge Split.
BMFace * BM_faces_join_pair(BMesh *bm, BMLoop *l_a, BMLoop *l_b, const bool do_del, BMFace **r_double)
Faces Join Pair.
BMEdge * BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool do_del, const bool kill_degenerate_faces, const bool kill_duplicate_faces)
Vert Collapse Faces.
BMFace * BM_face_split(BMesh *bm, BMFace *f, BMLoop *l_a, BMLoop *l_b, BMLoop **r_l, BMEdge *example, const bool no_double)
Face 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_disable(bm, e, oflag)
#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)
void BMO_slot_float_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float f)
#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.
#define BMO_vert_flag_set(bm, e, oflag, val)
#define BMO_SLOT_AS_BUFFER(slot)
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)
#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag)
#define BMO_vert_flag_test(bm, e, oflag)
int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
bool BMO_op_callf(BMesh *bm, int flag, const char *fmt,...)
#define BMO_face_flag_disable(bm, e, oflag)
#define BMO_face_flag_test(bm, e, oflag)
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
ATTR_WARN_UNUSED_RESULT const BMFlagLayer const short oflag
float BM_face_calc_normal(const BMFace *f, float r_no[3])
BMESH UPDATE FACE NORMAL.
BMLoop * BM_loop_other_edge_loop(BMLoop *l, BMVert *v)
bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
float BM_edge_calc_length_squared(const BMEdge *e)
bool BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb)
bool BM_vert_is_edge_pair(const BMVert *v)
bool BM_vert_edge_pair(const BMVert *v, BMEdge **r_e_a, BMEdge **r_e_b)
BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
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 BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMLoop * l_b
ATTR_WARN_UNUSED_RESULT const BMVert * v
void * BMW_begin(BMWalker *walker, void *start)
void BMW_init(BMWalker *walker, BMesh *bm, int type, short mask_vert, short mask_edge, short mask_face, BMWFlag flag, int layer)
Initialize Walker.
void BMW_end(BMWalker *walker)
End Walker.
void * BMW_step(BMWalker *walker)
Step Walker.
void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op)
static float bmo_vert_calc_edge_angle_blended(const BMVert *v)
static void bm_mesh_edge_collapse_flagged(BMesh *bm, const int flag, const short oflag)
static BMVert * bmo_find_end_of_chain(BMesh *bm, BMEdge *e, BMVert *v, const short edge_oflag=0)
static bool UNUSED_FUNCTION check_hole_in_region(BMesh *bm, BMFace *f)
void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op)
void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
static BMEdge * bm_vert_collapse_edge_and_merge(BMesh *bm, BMVert *v, const bool do_del)
static int bmo_vert_tagged_edges_count_at_most(BMesh *bm, BMVert *v, const short edge_oflag, const int max)
void bmo_dissolve_degenerate_exec(BMesh *bm, BMOperator *op)
static void bm_face_split(BMesh *bm, const short oflag, bool use_edge_delete)
static bool bmo_vert_touches_unselected_face(BMesh *bm, BMVert *v)
void bmo_dissolve_edges_init(BMOperator *op)
void reset()
clear internal cached data and reset random seed
void append_as(ForwardValue &&...value)
struct BMLoop * radial_next
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]