84 return ((i_a + 1 == i_b) ||
UNLIKELY((i_a == 0) && (i_b == coord_last)));
90 const bool lock_degenerate,
96 const float eps_zero_area = 1e-12f;
104 (
ELEM(v3, v1,
v2, v4) ==
false) && (
ELEM(v4, v1,
v2, v3) ==
false));
107 *r_area = (
fabsf(area_2x_234) +
fabsf(area_2x_241) +
118 if ((area_2x_123 >= 0.0f) != (area_2x_134 >= 0.0f)) {
121 if ((
fabsf(area_2x_123) <= eps_zero_area) || (
fabsf(area_2x_134) <= eps_zero_area)) {
126 if ((area_2x_234 >= 0.0f) != (area_2x_241 >= 0.0f)) {
127 if (lock_degenerate) {
133 if ((
fabsf(area_2x_234) <= eps_zero_area) || (
fabsf(area_2x_241) <= eps_zero_area)) {
140 float area_a, area_b;
141 float prim_a, prim_b;
142 float fac_24, fac_13;
144 float len_12, len_23, len_34, len_41, len_24, len_13;
159 area_a =
fabsf(area_2x_234);
160 area_b =
fabsf(area_2x_241);
161 prim_a = len_23 + len_34 + len_24;
162 prim_b = len_41 + len_12 + len_24;
163 fac_24 = (area_a / prim_a) + (area_b / prim_b);
166 area_a =
fabsf(area_2x_123);
167 area_b =
fabsf(area_2x_134);
168 prim_a = len_12 + len_23 + len_13;
169 prim_b = len_34 + len_41 + len_13;
170 fac_13 = (area_a / prim_a) + (area_b / prim_b);
173 return fac_24 - fac_13;
184 const bool lock_degenerate)
188 float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2];
192 const float eps = 1e-5f;
193 float no_a[3], no_b[3];
195 float axis_mat[3][3];
202 (
ELEM(v3, v1,
v2, v4) ==
false) && (
ELEM(v4, v1,
v2, v3) ==
false));
244 v1_xy, v2_xy, v3_xy, v4_xy, lock_degenerate,
nullptr);
260 const float *v1, *
v2, *v3, *v4;
262 v1 = coords[e_a_other->
v];
264 v3 = coords[e_b_other->
v];
276 const uint i =
e->base_index;
289 if (cost < -1e-6f *
max_ff(area, 1.0f)) {
293 if (eheap_table[
i]) {
295 eheap_table[
i] =
nullptr;
304 e_arr[0] = &edges[
e->e_next];
305 e_arr[1] = &edges[e_arr[0]->
e_next];
307 e = &edges[
e->e_radial];
308 e_arr[2] = &edges[
e->e_next];
309 e_arr[3] = &edges[e_arr[2]->
e_next];
312 if (e_arr[
i] && e_arr[
i]->base_index !=
UINT_MAX) {
338 ed_index[0] =
uint(
e - edges);
339 ed[0] = &edges[ed_index[0]];
340 ed_index[1] = ed[0]->
e_next;
341 ed[1] = &edges[ed_index[1]];
342 ed_index[2] = ed[1]->
e_next;
343 ed[2] = &edges[ed_index[2]];
345 ed_index[3] =
e->e_radial;
346 ed[3] = &edges[ed_index[3]];
347 ed_index[4] = ed[3]->
e_next;
348 ed[4] = &edges[ed_index[4]];
349 ed_index[5] = ed[4]->
e_next;
350 ed[5] = &edges[ed_index[5]];
352 ed[0]->
e_next = ed_index[2];
353 ed[1]->
e_next = ed_index[3];
354 ed[2]->
e_next = ed_index[4];
355 ed[3]->
e_next = ed_index[5];
356 ed[4]->
e_next = ed_index[0];
357 ed[5]->
e_next = ed_index[1];
364 const uint coords_num,
371 const uint coord_last = coords_num - 1;
372 const uint tris_len = coords_num - 2;
374 const uint edges_len = tris_len - 1;
378 const uint half_edges_len = 3 * tris_len;
383 uint order_edges_len = 0;
386 for (
uint i = 0;
i < tris_len;
i++) {
387 for (
uint j_curr = 0, j_prev = 2; j_curr < 3; j_prev = j_curr++) {
388 const uint e_index_prev = (
i * 3) + j_prev;
389 const uint e_index_curr = (
i * 3) + j_curr;
391 half_edges[e_index_prev].
v = tris[
i][j_prev];
392 half_edges[e_index_prev].
e_next = e_index_curr;
396 uint e_pair[2] = {tris[
i][j_prev], tris[
i][j_curr]};
397 if (e_pair[0] > e_pair[1]) {
403 order_edges[order_edges_len].
verts[0] = e_pair[0];
404 order_edges[order_edges_len].
verts[1] = e_pair[1];
405 order_edges[order_edges_len].
e_half = e_index_prev;
406 order_edges_len += 1;
414 for (
uint i = 0, base_index = 0;
i < order_edges_len; base_index++) {
430 eheap_table = (
HeapNode **)order_edges;
431 order_edges =
nullptr;
437 for (
uint i = 0;
i < half_edges_len;
i++,
e++) {
439 if (
e->e_radial <
i) {
445 eheap_table[
e->base_index] =
nullptr;
453 eheap_table[
e->base_index] =
nullptr;
467 for (
uint i = 0;
i < half_edges_len;
i++) {
470 uint *tri = tris[tri_index++];
475 e = &half_edges[
e->e_next];
479 e = &half_edges[
e->e_next];
A min-heap / priority queue ADT.
void BLI_heap_insert_or_update(Heap *heap, HeapNode **node_p, float value, void *ptr) ATTR_NONNULL(1
void void bool BLI_heap_is_empty(const Heap *heap) ATTR_NONNULL(1)
void BLI_heap_clear(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1)
void * BLI_heap_pop_min(Heap *heap) 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 float max_ff(float a, float b)
MINLINE int signum_i_ex(float a, float eps)
MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2])
void cross_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
MINLINE float len_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3(float n[3])
void * BLI_memarena_alloc(MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
float BLI_polyfill_beautify_quad_rotate_calc_ex(const float v1[2], const float v2[2], const float v3[2], const float v4[2], const bool lock_degenerate, float *r_area)
static float polyedge_rotate_beauty_calc(const float(*coords)[2], const HalfEdge *edges, const HalfEdge *e_a, float *r_area)
float BLI_polyfill_edge_calc_rotate_beauty__area(const float v1[3], const float v2[3], const float v3[3], const float v4[3], const bool lock_degenerate)
static void polyedge_rotate(HalfEdge *edges, const HalfEdge *e)
static void polyedge_beauty_cost_update_single(const float(*coords)[2], const HalfEdge *edges, HalfEdge *e, Heap *eheap, HeapNode **eheap_table)
static int oedge_cmp(const void *a1, const void *a2)
void BLI_polyfill_beautify(const float(*coords)[2], const uint coords_num, uint(*tris)[3], MemArena *arena, Heap *eheap)
BLI_INLINE bool is_boundary_edge(uint i_a, uint i_b, const uint coord_last)
static void polyedge_beauty_cost_update(const float(*coords)[2], HalfEdge *edges, HalfEdge *e, Heap *eheap, HeapNode **eheap_table)