52 const struct OrderEdge *x1 = a1, *x2 = a2;
53 if (x1->
verts[0] > x2->verts[0]) {
56 if (x1->
verts[0] < x2->verts[0]) {
60 if (x1->
verts[1] > x2->verts[1]) {
63 if (x1->
verts[1] < x2->verts[1]) {
68 if (x1->
e_half > x2->e_half) {
71 if (x1->
e_half < x2->e_half) {
82 return ((i_a + 1 == i_b) ||
UNLIKELY((i_a == 0) && (i_b == coord_last)));
88 const bool lock_degenerate,
94 const float eps_zero_area = 1e-12f;
102 (
ELEM(v3, v1,
v2, v4) ==
false) && (
ELEM(v4, v1,
v2, v3) ==
false));
105 *r_area = (
fabsf(area_2x_234) +
fabsf(area_2x_241) +
116 if ((area_2x_123 >= 0.0f) != (area_2x_134 >= 0.0f)) {
119 if ((
fabsf(area_2x_123) <= eps_zero_area) || (
fabsf(area_2x_134) <= eps_zero_area)) {
124 if ((area_2x_234 >= 0.0f) != (area_2x_241 >= 0.0f)) {
125 if (lock_degenerate) {
131 if ((
fabsf(area_2x_234) <= eps_zero_area) || (
fabsf(area_2x_241) <= eps_zero_area)) {
138 float area_a, area_b;
139 float prim_a, prim_b;
140 float fac_24, fac_13;
142 float len_12, len_23, len_34, len_41, len_24, len_13;
157 area_a =
fabsf(area_2x_234);
158 area_b =
fabsf(area_2x_241);
159 prim_a = len_23 + len_34 + len_24;
160 prim_b = len_41 + len_12 + len_24;
161 fac_24 = (area_a / prim_a) + (area_b / prim_b);
164 area_a =
fabsf(area_2x_123);
165 area_b =
fabsf(area_2x_134);
166 prim_a = len_12 + len_23 + len_13;
167 prim_b = len_34 + len_41 + len_13;
168 fac_13 = (area_a / prim_a) + (area_b / prim_b);
171 return fac_24 - fac_13;
185 const struct HalfEdge *e_a_other = &edges[edges[e_a->
e_next].e_next];
186 const struct HalfEdge *e_b_other = &edges[edges[e_b->
e_next].e_next];
188 const float *v1, *
v2, *v3, *v4;
190 v1 = coords[e_a_other->
v];
192 v3 = coords[e_b_other->
v];
204 const uint i =
e->base_index;
217 if (cost < -1e-6f *
max_ff(area, 1.0f)) {
221 if (eheap_table[i]) {
223 eheap_table[i] =
NULL;
235 e_arr[0] = &edges[
e->e_next];
236 e_arr[1] = &edges[e_arr[0]->
e_next];
238 e = &edges[
e->e_radial];
239 e_arr[2] = &edges[
e->e_next];
240 e_arr[3] = &edges[e_arr[2]->
e_next];
242 for (
uint i = 0; i < 4; i++) {
269 ed_index[0] = (
uint)(
e - edges);
270 ed[0] = &edges[ed_index[0]];
271 ed_index[1] = ed[0]->
e_next;
272 ed[1] = &edges[ed_index[1]];
273 ed_index[2] = ed[1]->
e_next;
274 ed[2] = &edges[ed_index[2]];
276 ed_index[3] =
e->e_radial;
277 ed[3] = &edges[ed_index[3]];
278 ed_index[4] = ed[3]->
e_next;
279 ed[4] = &edges[ed_index[4]];
280 ed_index[5] = ed[4]->
e_next;
281 ed[5] = &edges[ed_index[5]];
283 ed[0]->
e_next = ed_index[2];
284 ed[1]->
e_next = ed_index[3];
285 ed[2]->
e_next = ed_index[4];
286 ed[3]->
e_next = ed_index[5];
287 ed[4]->
e_next = ed_index[0];
288 ed[5]->
e_next = ed_index[1];
295 const uint coords_num,
302 const uint coord_last = coords_num - 1;
303 const uint tris_len = coords_num - 2;
305 const uint edges_len = tris_len - 1;
309 const uint half_edges_len = 3 * tris_len;
312 sizeof(
struct OrderEdge) * 2 * edges_len);
313 uint order_edges_len = 0;
316 for (
uint i = 0; i < tris_len; i++) {
317 for (
uint j_curr = 0, j_prev = 2; j_curr < 3; j_prev = j_curr++) {
318 const uint e_index_prev = (i * 3) + j_prev;
319 const uint e_index_curr = (i * 3) + j_curr;
321 half_edges[e_index_prev].
v = tris[i][j_prev];
322 half_edges[e_index_prev].
e_next = e_index_curr;
326 uint e_pair[2] = {tris[i][j_prev], tris[i][j_curr]};
327 if (e_pair[0] > e_pair[1]) {
333 order_edges[order_edges_len].
verts[0] = e_pair[0];
334 order_edges[order_edges_len].
verts[1] = e_pair[1];
335 order_edges[order_edges_len].
e_half = e_index_prev;
336 order_edges_len += 1;
344 for (
uint i = 0, base_index = 0; i < order_edges_len; base_index++) {
345 const struct OrderEdge *oe_a = &order_edges[i++];
346 const struct OrderEdge *oe_b = &order_edges[i++];
360 eheap_table = (
void *)order_edges;
367 for (
uint i = 0; i < half_edges_len; i++,
e++) {
369 if (
e->e_radial < i) {
375 eheap_table[
e->base_index] =
NULL;
383 eheap_table[
e->base_index] =
NULL;
397 for (
uint i = 0; i < half_edges_len; i++) {
400 uint *tri = tris[tri_index++];
405 e = &half_edges[
e->e_next];
409 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 float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2])
MINLINE float len_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
void * BLI_memarena_alloc(struct 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 struct HalfEdge *edges, const struct HalfEdge *e_a, float *r_area)
static void polyedge_rotate(struct HalfEdge *edges, const struct HalfEdge *e)
static void polyedge_beauty_cost_update_single(const float(*coords)[2], const struct HalfEdge *edges, struct HalfEdge *e, Heap *eheap, HeapNode **eheap_table)
static void polyedge_beauty_cost_update(const float(*coords)[2], struct HalfEdge *edges, struct 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)