Blender  V2.93
polyfill_2d.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
46 #include "BLI_math.h"
47 #include "BLI_utildefines.h"
48 
49 #include "BLI_alloca.h"
50 #include "BLI_memarena.h"
51 
52 #include "BLI_polyfill_2d.h" /* own include */
53 
54 #include "BLI_strict_flags.h"
55 
56 /* avoid fan-fill topology */
57 #define USE_CLIP_EVEN
58 #define USE_CONVEX_SKIP
59 /* sweep back-and-forth about convex ears (avoids lop-sided fans) */
60 #define USE_CLIP_SWEEP
61 // #define USE_CONVEX_SKIP_TEST
62 
63 #ifdef USE_CONVEX_SKIP
64 # define USE_KDTREE
65 #endif
66 
67 /* disable in production, it can fail on near zero area ngons */
68 // #define USE_STRICT_ASSERT
69 
70 // #define DEBUG_TIME
71 #ifdef DEBUG_TIME
72 # include "PIL_time_utildefines.h"
73 #endif
74 
75 typedef signed char eSign;
76 
77 #ifdef USE_KDTREE
97 typedef bool axis_t;
98 
99 /* use for sorting */
100 typedef struct KDTreeNode2D_head {
104 
105 typedef struct KDTreeNode2D {
108  axis_t axis; /* range is only (0-1) */
112 
113 struct KDTree2D {
115  const float (*coords)[2];
118  uint *nodes_map; /* index -> node lookup */
119 };
120 
121 struct KDRange2D {
122  float min, max;
123 };
124 #endif /* USE_KDTREE */
125 
126 enum {
127  CONCAVE = -1,
129  CONVEX = 1,
130 };
131 
132 typedef struct PolyFill {
133  struct PolyIndex *indices; /* vertex aligned */
134 
135  const float (*coords)[2];
137 #ifdef USE_CONVEX_SKIP
139 #endif
140 
141  /* A polygon with n vertices has a triangulation of n-2 triangles. */
142  uint (*tris)[3];
144 
145 #ifdef USE_KDTREE
146  struct KDTree2D kdtree;
147 #endif
149 
150 /* circular linklist */
151 typedef struct PolyIndex {
152  struct PolyIndex *next, *prev;
156 
157 /* based on libgdx 2013-11-28, apache 2.0 licensed */
158 
159 static void pf_coord_sign_calc(PolyFill *pf, PolyIndex *pi);
160 
162 #ifdef USE_CLIP_EVEN
163  ,
164  PolyIndex *pi_ear_init
165 #endif
166 #ifdef USE_CLIP_SWEEP
167  ,
168  bool reverse
169 #endif
170 );
171 
172 static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip);
173 static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip);
174 
176 {
177  if (UNLIKELY(a == 0.0f)) {
178  return 0;
179  }
180  if (a > 0.0f) {
181  return 1;
182  }
183 
184  return -1;
185 }
186 
193 BLI_INLINE float area_tri_signed_v2_alt_2x(const float v1[2], const float v2[2], const float v3[2])
194 {
195  float d2[2], d3[2];
196  sub_v2_v2v2(d2, v2, v1);
197  sub_v2_v2v2(d3, v3, v1);
198  return (d2[0] * d3[1]) - (d3[0] * d2[1]);
199 }
200 
201 static eSign span_tri_v2_sign(const float v1[2], const float v2[2], const float v3[2])
202 {
204 }
205 
206 #ifdef USE_KDTREE
207 # define KDNODE_UNSET ((uint)-1)
208 
209 enum {
211 };
212 
213 static void kdtree2d_new(struct KDTree2D *tree, uint tot, const float (*coords)[2])
214 {
215  /* set by caller */
216  // tree->nodes = nodes;
217  tree->coords = coords;
218  tree->root = KDNODE_UNSET;
219  tree->totnode = tot;
220 }
221 
225 static void kdtree2d_init(struct KDTree2D *tree, const uint coords_tot, const PolyIndex *indices)
226 {
228  uint i;
229 
230  for (i = 0, node = tree->nodes; i < coords_tot; i++) {
231  if (indices[i].sign != CONVEX) {
232  node->neg = node->pos = KDNODE_UNSET;
233  node->index = indices[i].index;
234  node->axis = 0;
235  node->flag = 0;
236  node++;
237  }
238  }
239 
240  BLI_assert(tree->totnode == (uint)(node - tree->nodes));
241 }
242 
244  KDTreeNode2D *nodes, uint totnode, axis_t axis, const float (*coords)[2], const uint ofs)
245 {
247  uint neg, pos, median, i, j;
248 
249  if (totnode <= 0) {
250  return KDNODE_UNSET;
251  }
252  if (totnode == 1) {
253  return 0 + ofs;
254  }
255 
256  /* Quick-sort style sorting around median. */
257  neg = 0;
258  pos = totnode - 1;
259  median = totnode / 2;
260 
261  while (pos > neg) {
262  const float co = coords[nodes[pos].index][axis];
263  i = neg - 1;
264  j = pos;
265 
266  while (1) {
267  while (coords[nodes[++i].index][axis] < co) { /* pass */
268  }
269  while (coords[nodes[--j].index][axis] > co && j > neg) { /* pass */
270  }
271 
272  if (i >= j) {
273  break;
274  }
275  SWAP(KDTreeNode2D_head, *(KDTreeNode2D_head *)&nodes[i], *(KDTreeNode2D_head *)&nodes[j]);
276  }
277 
278  SWAP(KDTreeNode2D_head, *(KDTreeNode2D_head *)&nodes[i], *(KDTreeNode2D_head *)&nodes[pos]);
279  if (i >= median) {
280  pos = i - 1;
281  }
282  if (i <= median) {
283  neg = i + 1;
284  }
285  }
286 
287  /* Set node and sort sub-nodes. */
288  node = &nodes[median];
289  node->axis = axis;
290  axis = !axis;
291  node->neg = kdtree2d_balance_recursive(nodes, median, axis, coords, ofs);
293  &nodes[median + 1], (totnode - (median + 1)), axis, coords, (median + 1) + ofs);
294 
295  return median + ofs;
296 }
297 
298 static void kdtree2d_balance(struct KDTree2D *tree)
299 {
300  tree->root = kdtree2d_balance_recursive(tree->nodes, tree->totnode, 0, tree->coords, 0);
301 }
302 
303 static void kdtree2d_init_mapping(struct KDTree2D *tree)
304 {
305  uint i;
307 
308  for (i = 0, node = tree->nodes; i < tree->totnode; i++, node++) {
309  if (node->neg != KDNODE_UNSET) {
310  tree->nodes[node->neg].parent = i;
311  }
312  if (node->pos != KDNODE_UNSET) {
313  tree->nodes[node->pos].parent = i;
314  }
315 
316  /* build map */
317  BLI_assert(tree->nodes_map[node->index] == KDNODE_UNSET);
318  tree->nodes_map[node->index] = i;
319  }
320 
321  tree->nodes[tree->root].parent = KDNODE_UNSET;
322 }
323 
325 {
326  uint node_index = tree->nodes_map[index];
328 
329  if (node_index == KDNODE_UNSET) {
330  return;
331  }
332 
333  tree->nodes_map[index] = KDNODE_UNSET;
334 
335  node = &tree->nodes[node_index];
336  tree->totnode -= 1;
337 
338  BLI_assert((node->flag & KDNODE_FLAG_REMOVED) == 0);
339  node->flag |= KDNODE_FLAG_REMOVED;
340 
341  while ((node->neg == KDNODE_UNSET) && (node->pos == KDNODE_UNSET) &&
342  (node->parent != KDNODE_UNSET)) {
343  KDTreeNode2D *node_parent = &tree->nodes[node->parent];
344 
345  BLI_assert((uint)(node - tree->nodes) == node_index);
346  if (node_parent->neg == node_index) {
347  node_parent->neg = KDNODE_UNSET;
348  }
349  else {
350  BLI_assert(node_parent->pos == node_index);
351  node_parent->pos = KDNODE_UNSET;
352  }
353 
354  if (node_parent->flag & KDNODE_FLAG_REMOVED) {
355  node_index = node->parent;
356  node = node_parent;
357  }
358  else {
359  break;
360  }
361  }
362 }
363 
364 static bool kdtree2d_isect_tri_recursive(const struct KDTree2D *tree,
365  const uint tri_index[3],
366  const float *tri_coords[3],
367  const float tri_center[2],
368  const struct KDRange2D bounds[2],
369  const KDTreeNode2D *node)
370 {
371  const float *co = tree->coords[node->index];
372 
373  /* bounds then triangle intersect */
374  if ((node->flag & KDNODE_FLAG_REMOVED) == 0) {
375  /* bounding box test first */
376  if ((co[0] >= bounds[0].min) && (co[0] <= bounds[0].max) && (co[1] >= bounds[1].min) &&
377  (co[1] <= bounds[1].max)) {
378  if ((span_tri_v2_sign(tri_coords[0], tri_coords[1], co) != CONCAVE) &&
379  (span_tri_v2_sign(tri_coords[1], tri_coords[2], co) != CONCAVE) &&
380  (span_tri_v2_sign(tri_coords[2], tri_coords[0], co) != CONCAVE)) {
381  if (!ELEM(node->index, tri_index[0], tri_index[1], tri_index[2])) {
382  return true;
383  }
384  }
385  }
386  }
387 
388 # define KDTREE2D_ISECT_TRI_RECURSE_NEG \
389  (((node->neg != KDNODE_UNSET) && (co[node->axis] >= bounds[node->axis].min)) && \
390  (kdtree2d_isect_tri_recursive( \
391  tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->neg])))
392 # define KDTREE2D_ISECT_TRI_RECURSE_POS \
393  (((node->pos != KDNODE_UNSET) && (co[node->axis] <= bounds[node->axis].max)) && \
394  (kdtree2d_isect_tri_recursive( \
395  tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->pos])))
396 
397  if (tri_center[node->axis] > co[node->axis]) {
399  return true;
400  }
402  return true;
403  }
404  }
405  else {
407  return true;
408  }
410  return true;
411  }
412  }
413 
414 # undef KDTREE2D_ISECT_TRI_RECURSE_NEG
415 # undef KDTREE2D_ISECT_TRI_RECURSE_POS
416 
417  BLI_assert(node->index != KDNODE_UNSET);
418 
419  return false;
420 }
421 
422 static bool kdtree2d_isect_tri(struct KDTree2D *tree, const uint ind[3])
423 {
424  const float *vs[3];
425  uint i;
426  struct KDRange2D bounds[2] = {
427  {FLT_MAX, -FLT_MAX},
428  {FLT_MAX, -FLT_MAX},
429  };
430  float tri_center[2] = {0.0f, 0.0f};
431 
432  for (i = 0; i < 3; i++) {
433  vs[i] = tree->coords[ind[i]];
434 
435  add_v2_v2(tri_center, vs[i]);
436 
437  CLAMP_MAX(bounds[0].min, vs[i][0]);
438  CLAMP_MIN(bounds[0].max, vs[i][0]);
439  CLAMP_MAX(bounds[1].min, vs[i][1]);
440  CLAMP_MIN(bounds[1].max, vs[i][1]);
441  }
442 
443  mul_v2_fl(tri_center, 1.0f / 3.0f);
444 
445  return kdtree2d_isect_tri_recursive(tree, ind, vs, tri_center, bounds, &tree->nodes[tree->root]);
446 }
447 
448 #endif /* USE_KDTREE */
449 
451 {
452  return pf->tris[pf->tris_tot++];
453 }
454 
456 {
457 #ifdef USE_KDTREE
458  /* avoid double lookups, since convex coords are ignored when testing intersections */
459  if (pf->kdtree.totnode) {
460  kdtree2d_node_remove(&pf->kdtree, pi->index);
461  }
462 #endif
463 
464  pi->next->prev = pi->prev;
465  pi->prev->next = pi->next;
466 
467  if (UNLIKELY(pf->indices == pi)) {
468  pf->indices = pi->next;
469  }
470 #ifdef DEBUG
471  pi->index = (uint)-1;
472  pi->next = pi->prev = NULL;
473 #endif
474 
475  pf->coords_tot -= 1;
476 }
477 
479 {
480  /* localize */
481  PolyIndex *pi_ear;
482 
483 #ifdef USE_CLIP_EVEN
484  PolyIndex *pi_ear_init = pf->indices;
485 #endif
486 #ifdef USE_CLIP_SWEEP
487  bool reverse = false;
488 #endif
489 
490  while (pf->coords_tot > 3) {
491  PolyIndex *pi_prev, *pi_next;
492  eSign sign_orig_prev, sign_orig_next;
493 
494  pi_ear = pf_ear_tip_find(pf
495 #ifdef USE_CLIP_EVEN
496  ,
497  pi_ear_init
498 #endif
499 #ifdef USE_CLIP_SWEEP
500  ,
501  reverse
502 #endif
503  );
504 
505 #ifdef USE_CONVEX_SKIP
506  if (pi_ear->sign != CONVEX) {
507  pf->coords_tot_concave -= 1;
508  }
509 #endif
510 
511  pi_prev = pi_ear->prev;
512  pi_next = pi_ear->next;
513 
514  pf_ear_tip_cut(pf, pi_ear);
515 
516  /* The type of the two vertices adjacent to the clipped vertex may have changed. */
517  sign_orig_prev = pi_prev->sign;
518  sign_orig_next = pi_next->sign;
519 
520  /* check if any verts became convex the (else if)
521  * case is highly unlikely but may happen with degenerate polygons */
522  if (sign_orig_prev != CONVEX) {
523  pf_coord_sign_calc(pf, pi_prev);
524 #ifdef USE_CONVEX_SKIP
525  if (pi_prev->sign == CONVEX) {
526  pf->coords_tot_concave -= 1;
527 # ifdef USE_KDTREE
528  kdtree2d_node_remove(&pf->kdtree, pi_prev->index);
529 # endif
530  }
531 #endif
532  }
533  if (sign_orig_next != CONVEX) {
534  pf_coord_sign_calc(pf, pi_next);
535 #ifdef USE_CONVEX_SKIP
536  if (pi_next->sign == CONVEX) {
537  pf->coords_tot_concave -= 1;
538 # ifdef USE_KDTREE
539  kdtree2d_node_remove(&pf->kdtree, pi_next->index);
540 # endif
541  }
542 #endif
543  }
544 
545 #ifdef USE_CLIP_EVEN
546 # ifdef USE_CLIP_SWEEP
547  pi_ear_init = reverse ? pi_prev->prev : pi_next->next;
548 # else
549  pi_ear_init = pi_next->next;
550 # endif
551 #endif
552 
553 #ifdef USE_CLIP_EVEN
554 # ifdef USE_CLIP_SWEEP
555  if (pi_ear_init->sign != CONVEX) {
556  /* take the extra step since this ear isn't a good candidate */
557  pi_ear_init = reverse ? pi_ear_init->prev : pi_ear_init->next;
558  reverse = !reverse;
559  }
560 # endif
561 #else
562  if ((reverse ? pi_prev->prev : pi_next->next)->sign != CONVEX) {
563  reverse = !reverse;
564  }
565 #endif
566  }
567 
568  if (pf->coords_tot == 3) {
569  uint *tri = pf_tri_add(pf);
570  pi_ear = pf->indices;
571  tri[0] = pi_ear->index;
572  pi_ear = pi_ear->next;
573  tri[1] = pi_ear->index;
574  pi_ear = pi_ear->next;
575  tri[2] = pi_ear->index;
576  }
577 }
578 
583 {
584  /* localize */
585  const float(*coords)[2] = pf->coords;
586 
587  pi->sign = span_tri_v2_sign(coords[pi->prev->index], coords[pi->index], coords[pi->next->index]);
588 }
589 
591 #ifdef USE_CLIP_EVEN
592  ,
593  PolyIndex *pi_ear_init
594 #endif
595 #ifdef USE_CLIP_SWEEP
596  ,
597  bool reverse
598 #endif
599 )
600 {
601  /* localize */
602  const uint coords_tot = pf->coords_tot;
603  PolyIndex *pi_ear;
604 
605  uint i;
606 
607 #ifdef USE_CLIP_EVEN
608  pi_ear = pi_ear_init;
609 #else
610  pi_ear = pf->indices;
611 #endif
612 
613  i = coords_tot;
614  while (i--) {
615  if (pf_ear_tip_check(pf, pi_ear)) {
616  return pi_ear;
617  }
618 #ifdef USE_CLIP_SWEEP
619  pi_ear = reverse ? pi_ear->prev : pi_ear->next;
620 #else
621  pi_ear = pi_ear->next;
622 #endif
623  }
624 
625  /* Desperate mode: if no vertex is an ear tip,
626  * we are dealing with a degenerate polygon (e.g. nearly collinear).
627  * Note that the input was not necessarily degenerate,
628  * but we could have made it so by clipping some valid ears.
629  *
630  * Idea taken from Martin Held, "FIST: Fast industrial-strength triangulation of polygons",
631  * Algorithmica (1998),
632  * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.115.291
633  *
634  * Return a convex or tangential vertex if one exists.
635  */
636 
637 #ifdef USE_CLIP_EVEN
638  pi_ear = pi_ear_init;
639 #else
640  pi_ear = pf->indices;
641 #endif
642 
643  i = coords_tot;
644  while (i--) {
645  if (pi_ear->sign != CONCAVE) {
646  return pi_ear;
647  }
648  pi_ear = pi_ear->next;
649  }
650 
651  /* If all vertices are concave, just return the last one. */
652  return pi_ear;
653 }
654 
655 static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip)
656 {
657 #ifndef USE_KDTREE
658  /* localize */
659  const float(*coords)[2] = pf->coords;
660  PolyIndex *pi_curr;
661 
662  const float *v1, *v2, *v3;
663 #endif
664 
665 #if defined(USE_CONVEX_SKIP) && !defined(USE_KDTREE)
666  uint coords_tot_concave_checked = 0;
667 #endif
668 
669 #ifdef USE_CONVEX_SKIP
670 
671 # ifdef USE_CONVEX_SKIP_TEST
672  /* check if counting is wrong */
673  {
674  uint coords_tot_concave_test = 0;
675  PolyIndex *pi_iter = pi_ear_tip;
676  do {
677  if (pi_iter->sign != CONVEX) {
678  coords_tot_concave_test += 1;
679  }
680  } while ((pi_iter = pi_iter->next) != pi_ear_tip);
681  BLI_assert(coords_tot_concave_test == pf->coords_tot_concave);
682  }
683 # endif
684 
685  /* fast-path for circles */
686  if (pf->coords_tot_concave == 0) {
687  return true;
688  }
689 #endif
690 
691  if (UNLIKELY(pi_ear_tip->sign == CONCAVE)) {
692  return false;
693  }
694 
695 #ifdef USE_KDTREE
696  {
697  const uint ind[3] = {pi_ear_tip->index, pi_ear_tip->next->index, pi_ear_tip->prev->index};
698 
699  if (kdtree2d_isect_tri(&pf->kdtree, ind)) {
700  return false;
701  }
702  }
703 #else
704 
705  v1 = coords[pi_ear_tip->prev->index];
706  v2 = coords[pi_ear_tip->index];
707  v3 = coords[pi_ear_tip->next->index];
708 
709  /* Check if any point is inside the triangle formed by previous, current and next vertices.
710  * Only consider vertices that are not part of this triangle,
711  * or else we'll always find one inside. */
712 
713  for (pi_curr = pi_ear_tip->next->next; pi_curr != pi_ear_tip->prev; pi_curr = pi_curr->next) {
714  /* Concave vertices can obviously be inside the candidate ear,
715  * but so can tangential vertices if they coincide with one of the triangle's vertices. */
716  if (pi_curr->sign != CONVEX) {
717  const float *v = coords[pi_curr->index];
718  /* Because the polygon has clockwise winding order,
719  * the area sign will be positive if the point is strictly inside.
720  * It will be 0 on the edge, which we want to include as well. */
721 
722  /* note: check (v3, v1) first since it fails _far_ more often than the other 2 checks
723  * (those fail equally).
724  * It's logical - the chance is low that points exist on the
725  * same side as the ear we're clipping off. */
726  if ((span_tri_v2_sign(v3, v1, v) != CONCAVE) && (span_tri_v2_sign(v1, v2, v) != CONCAVE) &&
727  (span_tri_v2_sign(v2, v3, v) != CONCAVE)) {
728  return false;
729  }
730 
731 # ifdef USE_CONVEX_SKIP
732  coords_tot_concave_checked += 1;
733  if (coords_tot_concave_checked == pf->coords_tot_concave) {
734  break;
735  }
736 # endif
737  }
738  }
739 #endif /* USE_KDTREE */
740 
741  return true;
742 }
743 
744 static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip)
745 {
746  uint *tri = pf_tri_add(pf);
747 
748  tri[0] = pi_ear_tip->prev->index;
749  tri[1] = pi_ear_tip->index;
750  tri[2] = pi_ear_tip->next->index;
751 
752  pf_coord_remove(pf, pi_ear_tip);
753 }
754 
759  const float (*coords)[2],
760  const uint coords_tot,
761  int coords_sign,
762  uint (*r_tris)[3],
763  PolyIndex *r_indices)
764 {
765  /* localize */
766  PolyIndex *indices = r_indices;
767 
768  uint i;
769 
770  /* assign all polyfill members here */
771  pf->indices = r_indices;
772  pf->coords = coords;
773  pf->coords_tot = coords_tot;
774 #ifdef USE_CONVEX_SKIP
775  pf->coords_tot_concave = 0;
776 #endif
777  pf->tris = r_tris;
778  pf->tris_tot = 0;
779 
780  if (coords_sign == 0) {
781  coords_sign = (cross_poly_v2(coords, coords_tot) >= 0.0f) ? 1 : -1;
782  }
783  else {
784  /* check we're passing in correct args */
785 #ifdef USE_STRICT_ASSERT
786 # ifndef NDEBUG
787  if (coords_sign == 1) {
788  BLI_assert(cross_poly_v2(coords, coords_tot) >= 0.0f);
789  }
790  else {
791  BLI_assert(cross_poly_v2(coords, coords_tot) <= 0.0f);
792  }
793 # endif
794 #endif
795  }
796 
797  if (coords_sign == 1) {
798  for (i = 0; i < coords_tot; i++) {
799  indices[i].next = &indices[i + 1];
800  indices[i].prev = &indices[i - 1];
801  indices[i].index = i;
802  }
803  }
804  else {
805  /* reversed */
806  uint n = coords_tot - 1;
807  for (i = 0; i < coords_tot; i++) {
808  indices[i].next = &indices[i + 1];
809  indices[i].prev = &indices[i - 1];
810  indices[i].index = (n - i);
811  }
812  }
813  indices[0].prev = &indices[coords_tot - 1];
814  indices[coords_tot - 1].next = &indices[0];
815 
816  for (i = 0; i < coords_tot; i++) {
817  PolyIndex *pi = &indices[i];
818  pf_coord_sign_calc(pf, pi);
819 #ifdef USE_CONVEX_SKIP
820  if (pi->sign != CONVEX) {
821  pf->coords_tot_concave += 1;
822  }
823 #endif
824  }
825 }
826 
827 static void polyfill_calc(PolyFill *pf)
828 {
829 #ifdef USE_KDTREE
830 # ifdef USE_CONVEX_SKIP
831  if (pf->coords_tot_concave)
832 # endif
833  {
834  kdtree2d_new(&pf->kdtree, pf->coords_tot_concave, pf->coords);
835  kdtree2d_init(&pf->kdtree, pf->coords_tot, pf->indices);
836  kdtree2d_balance(&pf->kdtree);
837  kdtree2d_init_mapping(&pf->kdtree);
838  }
839 #endif
840 
842 }
843 
847 void BLI_polyfill_calc_arena(const float (*coords)[2],
848  const uint coords_tot,
849  const int coords_sign,
850  uint (*r_tris)[3],
851 
852  struct MemArena *arena)
853 {
854  PolyFill pf;
855  PolyIndex *indices = BLI_memarena_alloc(arena, sizeof(*indices) * coords_tot);
856 
857 #ifdef DEBUG_TIME
858  TIMEIT_START(polyfill2d);
859 #endif
860 
862  coords,
863  coords_tot,
864  coords_sign,
865  r_tris,
866  /* cache */
867  indices);
868 
869 #ifdef USE_KDTREE
870  if (pf.coords_tot_concave) {
871  pf.kdtree.nodes = BLI_memarena_alloc(arena, sizeof(*pf.kdtree.nodes) * pf.coords_tot_concave);
872  pf.kdtree.nodes_map = memset(
873  BLI_memarena_alloc(arena, sizeof(*pf.kdtree.nodes_map) * coords_tot),
874  0xff,
875  sizeof(*pf.kdtree.nodes_map) * coords_tot);
876  }
877  else {
878  pf.kdtree.totnode = 0;
879  }
880 #endif
881 
882  polyfill_calc(&pf);
883 
884  /* indices are no longer needed,
885  * caller can clear arena */
886 
887 #ifdef DEBUG_TIME
888  TIMEIT_END(polyfill2d);
889 #endif
890 }
891 
905 void BLI_polyfill_calc(const float (*coords)[2],
906  const uint coords_tot,
907  const int coords_sign,
908  uint (*r_tris)[3])
909 {
910  /* Fallback to heap memory for large allocations.
911  * Avoid running out of stack memory on systems with 512kb stack (macOS).
912  * This happens at around 13,000 points, use a much lower value to be safe. */
913  if (UNLIKELY(coords_tot > 8192)) {
914  /* The buffer size only accounts for the index allocation,
915  * worst case we do two allocations when concave, while we should try to be efficient,
916  * any caller that relies on this frequently should use #BLI_polyfill_calc_arena directly. */
917  MemArena *arena = BLI_memarena_new(sizeof(PolyIndex) * coords_tot, __func__);
918  BLI_polyfill_calc_arena(coords, coords_tot, coords_sign, r_tris, arena);
919  BLI_memarena_free(arena);
920  return;
921  }
922 
923  PolyFill pf;
924  PolyIndex *indices = BLI_array_alloca(indices, coords_tot);
925 
926 #ifdef DEBUG_TIME
927  TIMEIT_START(polyfill2d);
928 #endif
929 
931  coords,
932  coords_tot,
933  coords_sign,
934  r_tris,
935  /* cache */
936  indices);
937 
938 #ifdef USE_KDTREE
939  if (pf.coords_tot_concave) {
940  pf.kdtree.nodes = BLI_array_alloca(pf.kdtree.nodes, pf.coords_tot_concave);
941  pf.kdtree.nodes_map = memset(BLI_array_alloca(pf.kdtree.nodes_map, coords_tot),
942  0xff,
943  sizeof(*pf.kdtree.nodes_map) * coords_tot);
944  }
945  else {
946  pf.kdtree.totnode = 0;
947  }
948 #endif
949 
950  polyfill_calc(&pf);
951 
952 #ifdef DEBUG_TIME
953  TIMEIT_END(polyfill2d);
954 #endif
955 }
typedef float(TangentPoint)[2]
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:36
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_INLINE
unsigned char axis_t
Definition: BLI_kdopbvh.c:77
float cross_poly_v2(const float verts[][2], unsigned int nr)
Definition: math_geom.c:171
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
Definition: BLI_memarena.c:109
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
Definition: BLI_memarena.c:131
struct MemArena * BLI_memarena_new(const size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2) ATTR_MALLOC
Definition: BLI_memarena.c:79
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
unsigned int uint
Definition: BLI_sys_types.h:83
unsigned short ushort
Definition: BLI_sys_types.h:84
#define CLAMP_MAX(a, c)
#define SWAP(type, a, b)
#define UNLIKELY(x)
#define ELEM(...)
#define CLAMP_MIN(a, b)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Utility defines for timing/benchmarks.
#define TIMEIT_START(var)
#define TIMEIT_END(var)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition: btDbvt.cpp:299
OperationNode * node
void * tree
static ushort indices[]
#define pf(_x, _i)
Prefetch 64.
Definition: gim_memory.h:48
uint pos
static unsigned a[3]
Definition: RandGen.cpp:92
double sign(double arg)
Definition: utility.h:250
static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip)
Definition: polyfill_2d.c:655
static void kdtree2d_init(struct KDTree2D *tree, const uint coords_tot, const PolyIndex *indices)
Definition: polyfill_2d.c:225
static PolyIndex * pf_ear_tip_find(PolyFill *pf, PolyIndex *pi_ear_init, bool reverse)
Definition: polyfill_2d.c:590
static bool kdtree2d_isect_tri(struct KDTree2D *tree, const uint ind[3])
Definition: polyfill_2d.c:422
struct KDTreeNode2D KDTreeNode2D
static void kdtree2d_init_mapping(struct KDTree2D *tree)
Definition: polyfill_2d.c:303
signed char eSign
Definition: polyfill_2d.c:75
struct KDTreeNode2D_head KDTreeNode2D_head
static void polyfill_prepare(PolyFill *pf, const float(*coords)[2], const uint coords_tot, int coords_sign, uint(*r_tris)[3], PolyIndex *r_indices)
Definition: polyfill_2d.c:758
BLI_INLINE eSign signum_enum(float a)
Definition: polyfill_2d.c:175
struct PolyIndex PolyIndex
static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip)
Definition: polyfill_2d.c:744
#define KDTREE2D_ISECT_TRI_RECURSE_NEG
static uint kdtree2d_balance_recursive(KDTreeNode2D *nodes, uint totnode, axis_t axis, const float(*coords)[2], const uint ofs)
Definition: polyfill_2d.c:243
static bool kdtree2d_isect_tri_recursive(const struct KDTree2D *tree, const uint tri_index[3], const float *tri_coords[3], const float tri_center[2], const struct KDRange2D bounds[2], const KDTreeNode2D *node)
Definition: polyfill_2d.c:364
BLI_INLINE float area_tri_signed_v2_alt_2x(const float v1[2], const float v2[2], const float v3[2])
Definition: polyfill_2d.c:193
struct PolyFill PolyFill
static void kdtree2d_node_remove(struct KDTree2D *tree, uint index)
Definition: polyfill_2d.c:324
@ TANGENTIAL
Definition: polyfill_2d.c:128
@ CONCAVE
Definition: polyfill_2d.c:127
@ CONVEX
Definition: polyfill_2d.c:129
static void pf_coord_sign_calc(PolyFill *pf, PolyIndex *pi)
Definition: polyfill_2d.c:582
#define USE_CLIP_EVEN
Definition: polyfill_2d.c:57
#define KDNODE_UNSET
Definition: polyfill_2d.c:207
#define USE_CLIP_SWEEP
Definition: polyfill_2d.c:60
static eSign span_tri_v2_sign(const float v1[2], const float v2[2], const float v3[2])
Definition: polyfill_2d.c:201
void BLI_polyfill_calc_arena(const float(*coords)[2], const uint coords_tot, const int coords_sign, uint(*r_tris)[3], struct MemArena *arena)
Definition: polyfill_2d.c:847
static void kdtree2d_balance(struct KDTree2D *tree)
Definition: polyfill_2d.c:298
static uint * pf_tri_add(PolyFill *pf)
Definition: polyfill_2d.c:450
bool axis_t
Definition: polyfill_2d.c:97
#define KDTREE2D_ISECT_TRI_RECURSE_POS
static void kdtree2d_new(struct KDTree2D *tree, uint tot, const float(*coords)[2])
Definition: polyfill_2d.c:213
static void polyfill_calc(PolyFill *pf)
Definition: polyfill_2d.c:827
static void pf_coord_remove(PolyFill *pf, PolyIndex *pi)
Definition: polyfill_2d.c:455
@ KDNODE_FLAG_REMOVED
Definition: polyfill_2d.c:210
static void pf_triangulate(PolyFill *pf)
Definition: polyfill_2d.c:478
void BLI_polyfill_calc(const float(*coords)[2], const uint coords_tot, const int coords_sign, uint(*r_tris)[3])
Definition: polyfill_2d.c:905
#define min(a, b)
Definition: sort.c:51
float max
Definition: polyfill_2d.c:122
float min
Definition: polyfill_2d.c:122
KDTreeNode2D * nodes
Definition: polyfill_2d.c:114
uint root
Definition: polyfill_2d.c:116
uint * nodes_map
Definition: polyfill_2d.c:118
const float(* coords)[2]
Definition: polyfill_2d.c:115
uint totnode
Definition: polyfill_2d.c:117
uint tris_tot
Definition: polyfill_2d.c:143
struct PolyIndex * indices
Definition: polyfill_2d.c:133
uint(* tris)[3]
Definition: polyfill_2d.c:142
const float(* coords)[2]
Definition: polyfill_2d.c:135
uint coords_tot
Definition: polyfill_2d.c:136
uint coords_tot_concave
Definition: polyfill_2d.c:138
struct KDTree2D kdtree
Definition: polyfill_2d.c:146
eSign sign
Definition: polyfill_2d.c:154
struct PolyIndex * prev
Definition: polyfill_2d.c:152
struct PolyIndex * next
Definition: polyfill_2d.c:152
uint index
Definition: polyfill_2d.c:153
float max