24#define USE_DEGENERATE_CHECK
26#define COST_INVALID FLT_MAX
34 int cd_loop_offset_end;
41 const DelimitData *delimit_data);
44 const DelimitData *delimit_data);
51 const DelimitData *delimit_data)
53#define UNIT_TO_ANGLE DEG2RADF(90.0f)
54#define ANGLE_TO_UNIT (1.0f / UNIT_TO_ANGLE)
79 for (cd_loop_offset = delimit_data->cd_loop_offset;
80 cd_loop_offset < delimit_data->cd_loop_offset_end;
81 cd_loop_offset += delimit_data->cd_loop_size)
93 const DelimitData *delimit_data)
110 if (
e->l->f->mat_nr !=
e->l->radial_next->f->mat_nr) {
131 const DelimitData *delimit_data)
151 const DelimitData *delimit_data)
154 float angle_cos_neg =
dot_v3v3(
e->l->f->no,
e->l->radial_next->f->no);
158 return angle_cos_neg;
164#ifdef USE_DEGENERATE_CHECK
169 const float center[3])
177 r[0] = m[0][0] * co[0] + m[1][0] * co[1] + m[2][0] * co[2];
178 r[1] = m[0][1] * co[0] + m[1][1] * co[1] + m[2][1] * co[2];
184 const float *center = l_ear->
v->
co;
187 float axis_mat[3][3];
203 float adjacent_2d[2];
235 l_first = l_ear->
prev;
242 }
while ((l_iter = l_iter->
next) != l_first);
265 l_iter = l_first = e_pair[1]->
l;
267 if (l_iter->
f->
len > 3) {
268 BMLoop *l_pivot = (l_iter->
v ==
v ? l_iter : l_iter->
next);
274 }
while ((l_iter = l_iter->
radial_next) != l_first);
283 const float angle_limit,
284 const bool do_dissolve_boundaries,
287 const int vinput_len,
289 const int einput_len,
290 const short oflag_out)
292 const float angle_limit_cos_neg = -
cosf(angle_limit);
293 DelimitData delimit_data = {0};
294 const int eheap_table_len = do_dissolve_boundaries ? einput_len :
max_ii(einput_len, vinput_len);
301 if (layer_len == 0) {
308 delimit_data.cd_loop_offset_end = delimit_data.cd_loop_offset +
309 delimit_data.cd_loop_size * layer_len;
319 int *vert_reverse_lookup;
334 for (
i = 0;
i < einput_len;
i++) {
360 eheap_table[
i] =
nullptr;
372 if (j != -1 && eheap_table[j]) {
376 }
while ((l_iter = l_iter->
next) != l_first);
389 for (
i = 0;
i < vinput_len;
i++) {
401 for (
i =
bm->totedge - 1;
i != -1;
i--) {
410 if (v1->
e ==
nullptr) {
412 if (vidx_reverse != -1) {
413 vinput_arr[vidx_reverse] =
nullptr;
417 if (
v2->e ==
nullptr) {
419 if (vidx_reverse != -1) {
420 vinput_arr[vidx_reverse] =
nullptr;
433 if (do_dissolve_boundaries) {
435 for (
i = 0;
i < vinput_len;
i++) {
457 for (
i = 0;
i < vinput_len;
i++) {
488 vheap_table[
i] =
nullptr;
493 l_iter = l_first = e_new->
l;
496 }
while ((l_iter = l_iter->
radial_next) != l_first);
502 if (j != -1 && vheap_table[j]) {
508#ifdef USE_DEGENERATE_CHECK
513 l_iter = l_first = e_new->
l;
516 BMLoop *l_cycle_first, *l_cycle_iter;
518 l_cycle_first = l_iter->
prev;
521 if (j != -1 && vheap_table[j] &&
525 l_cycle_iter->
v, delimit, &delimit_data);
528 }
while ((l_cycle_iter = l_cycle_iter->
next) != l_cycle_first);
530 }
while ((l_iter = l_iter->
radial_next) != l_first);
548 const float angle_limit,
549 const bool do_dissolve_boundaries,
562 do_dissolve_boundaries,
CustomData interface, see also DNA_customdata_types.h.
int CustomData_sizeof(eCustomDataType type)
int CustomData_get_n_offset(const CustomData *data, eCustomDataType type, int n)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
A min-heap / priority queue ADT.
HeapNode * BLI_heap_top(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1)
void void float BLI_heap_node_value(const HeapNode *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Heap * BLI_heap_new_ex(unsigned int reserve_num) ATTR_WARN_UNUSED_RESULT
void void bool BLI_heap_is_empty(const Heap *heap) ATTR_NONNULL(1)
void BLI_heap_node_value_update(Heap *heap, HeapNode *node, float value) ATTR_NONNULL(1
void * BLI_heap_node_ptr(const HeapNode *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
HeapNode * BLI_heap_insert(Heap *heap, float value, void *ptr) ATTR_NONNULL(1)
void void BLI_heap_remove(Heap *heap, HeapNode *node) ATTR_NONNULL(1
MINLINE int max_ii(int a, int b)
MINLINE int signum_i(float a)
MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2])
bool isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
MINLINE void swap_v2_v2(float a[2], float b[2])
float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[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 copy_vn_i(int *array_tar, int size, int val)
MINLINE void zero_v2(float r[2])
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)
void BM_vert_kill(BMesh *bm, BMVert *v)
void BM_edge_kill(BMesh *bm, BMEdge *e)
static bool bm_vert_is_delimiter(const BMVert *v, const BMO_Delimit delimit, const DelimitData *delimit_data)
void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries, const BMO_Delimit delimit)
static float bm_edge_calc_dissolve_error(const BMEdge *e, const BMO_Delimit delimit, const DelimitData *delimit_data)
static bool bm_edge_is_delimiter(const BMEdge *e, const BMO_Delimit delimit, const DelimitData *delimit_data)
static bool bm_loop_collapse_is_degenerate(BMLoop *l_ear)
static void mul_v2_m3v3_center(float r[2], const float m[3][3], const float a[3], const float center[3])
static float bm_vert_edge_face_angle(BMVert *v, const BMO_Delimit delimit, const DelimitData *delimit_data)
static bool bm_vert_collapse_is_degenerate(BMVert *v)
static bool bm_edge_is_contiguous_loop_cd_all(const BMEdge *e, const DelimitData *delimit_data)
void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries, BMO_Delimit delimit, BMVert **vinput_arr, const int vinput_len, BMEdge **einput_arr, const int einput_len, const short oflag_out)
#define USE_DEGENERATE_CHECK
#define BM_elem_index_get(ele)
#define BM_elem_flag_set(ele, hflag, val)
#define BM_elem_index_set(ele, index)
#define BM_elem_flag_test(ele, hflag)
void * BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len, void **stack_array, int stack_array_size)
Iterator as Array.
#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)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
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.
#define BMO_face_flag_enable(bm, e, oflag)
void BM_face_normal_update(BMFace *f)
float BM_vert_calc_edge_angle(const BMVert *v)
bool BM_edge_is_contiguous_loop_cd(const BMEdge *e, const int cd_loop_type, const int cd_loop_offset)
float BM_edge_calc_face_angle(const BMEdge *e)
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_contiguous(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_manifold(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 BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
struct BMLoop * radial_next