51#define USE_CONVEX_SKIP
95struct KDTreeNode2D_head {
110 const float (*coords)[2];
129 PolyIndex *
next, *prev;
137 const float (*coords)[2];
139#ifdef USE_CONVEX_SKIP
140 uint32_t coords_num_concave;
161 PolyIndex *pi_ear_init
169static bool pf_ear_tip_check(PolyFill *
pf, PolyIndex *pi_ear_tip,
const eSign sign_accept);
194 return (d2[0] * d3[1]) - (d3[0] * d2[1]);
203# define KDNODE_UNSET (uint32_t(-1))
213 tree->coords = coords;
215 tree->node_num = tot;
226 for (
i = 0, node =
tree->nodes;
i < coords_num;
i++) {
242 const float (*coords)[2],
246 uint32_t neg,
pos, median,
i, j;
258 median = node_num / 2;
261 const float co = coords[nodes[
pos].index][axis];
266 while (coords[nodes[++
i].index][axis] < co) {
268 while (coords[nodes[--j].index][axis] > co && j > neg) {
274 SWAP(KDTreeNode2D_head, *(KDTreeNode2D_head *)&nodes[
i], *(KDTreeNode2D_head *)&nodes[j]);
277 SWAP(KDTreeNode2D_head, *(KDTreeNode2D_head *)&nodes[
i], *(KDTreeNode2D_head *)&nodes[
pos]);
287 node = &nodes[median];
292 &nodes[median + 1], (node_num - (median + 1)), axis, coords, (median + 1) + ofs);
309 tree->nodes[node->neg].parent =
i;
312 tree->nodes[node->pos].parent =
i;
317 tree->nodes_map[node->index] =
i;
325 uint32_t node_index =
tree->nodes_map[index];
334 node = &
tree->nodes[node_index];
343 KDTreeNode2D *node_parent = &
tree->nodes[node->parent];
346 if (node_parent->neg == node_index) {
355 node_index = node->parent;
365 const uint32_t tri_index[3],
366 const float *tri_coords[3],
367 const float tri_center[2],
368 const KDRange2D
bounds[2],
369 const KDTreeNode2D *node)
371 const float *co =
tree->coords[node->index];
383 if (!
ELEM(node->index, tri_index[0], tri_index[1], tri_index[2])) {
390# define KDTREE2D_ISECT_TRI_RECURSE_NEG \
391 (((node->neg != KDNODE_UNSET) && (co[node->axis] >= bounds[node->axis].min)) && \
392 kdtree2d_isect_tri_recursive( \
393 tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->neg]))
394# define KDTREE2D_ISECT_TRI_RECURSE_POS \
395 (((node->pos != KDNODE_UNSET) && (co[node->axis] <= bounds[node->axis].max)) && \
396 kdtree2d_isect_tri_recursive( \
397 tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->pos]))
399 if (tri_center[node->axis] > co[node->axis]) {
416# undef KDTREE2D_ISECT_TRI_RECURSE_NEG
417# undef KDTREE2D_ISECT_TRI_RECURSE_POS
432 float tri_center[2] = {0.0f, 0.0f};
434 for (
i = 0;
i < 3;
i++) {
435 vs[
i] =
tree->coords[ind[
i]];
454 return pf->tris[
pf->tris_num++];
461 if (
pf->kdtree.node_num) {
466 pi->next->prev = pi->prev;
467 pi->prev->next = pi->next;
470 pf->indices = pi->next;
473 pi->index = uint32_t(-1);
474 pi->next = pi->prev =
nullptr;
486 PolyIndex *pi_ear_init =
pf->indices;
489 bool reverse =
false;
492 while (
pf->coords_num > 3) {
493 PolyIndex *pi_prev, *pi_next;
494 eSign sign_orig_prev, sign_orig_next;
507#ifdef USE_CONVEX_SKIP
508 if (pi_ear->sign != CONVEX) {
509 pf->coords_num_concave -= 1;
513 pi_prev = pi_ear->prev;
514 pi_next = pi_ear->next;
519 sign_orig_prev = pi_prev->sign;
520 sign_orig_next = pi_next->sign;
524 if (sign_orig_prev != CONVEX) {
526#ifdef USE_CONVEX_SKIP
527 if (pi_prev->sign == CONVEX) {
528 pf->coords_num_concave -= 1;
535 if (sign_orig_next != CONVEX) {
537#ifdef USE_CONVEX_SKIP
538 if (pi_next->sign == CONVEX) {
539 pf->coords_num_concave -= 1;
548# ifdef USE_CLIP_SWEEP
549 pi_ear_init = reverse ? pi_prev->prev : pi_next->next;
551 pi_ear_init = pi_next->next;
556# ifdef USE_CLIP_SWEEP
557 if (pi_ear_init->sign != CONVEX) {
559 pi_ear_init = reverse ? pi_ear_init->prev : pi_ear_init->next;
564# ifdef USE_CLIP_SWEEP
565 if ((reverse ? pi_prev->prev : pi_next->next)->sign != CONVEX) {
572 if (
pf->coords_num == 3) {
574 pi_ear =
pf->indices;
575 tri[0] = pi_ear->index;
576 pi_ear = pi_ear->next;
577 tri[1] = pi_ear->index;
578 pi_ear = pi_ear->next;
579 tri[2] = pi_ear->index;
589 const float (*coords)[2] =
pf->coords;
591 pi->sign =
span_tri_v2_sign(coords[pi->prev->index], coords[pi->index], coords[pi->next->index]);
597 PolyIndex *pi_ear_init
606 const uint32_t coords_num =
pf->coords_num;
632 for (eSign sign_accept = CONVEX; sign_accept >= TANGENTIAL; sign_accept--) {
634 pi_ear = pi_ear_init;
636 pi_ear =
pf->indices;
644 pi_ear = reverse ? pi_ear->prev : pi_ear->next;
646 pi_ear = pi_ear->next;
664 pi_ear = pi_ear_init;
666 pi_ear =
pf->indices;
671 if (pi_ear->sign != CONCAVE) {
674 pi_ear = pi_ear->next;
685 const float (*coords)[2] =
pf->coords;
688 const float *v1, *
v2, *v3;
691#if defined(USE_CONVEX_SKIP) && !defined(USE_KDTREE)
692 uint32_t coords_num_concave_checked = 0;
695#ifdef USE_CONVEX_SKIP
697# ifdef USE_CONVEX_SKIP_TEST
700 uint32_t coords_num_concave_test = 0;
701 PolyIndex *pi_iter = pi_ear_tip;
703 if (pi_iter->sign != CONVEX) {
704 coords_num_concave_test += 1;
706 }
while ((pi_iter = pi_iter->next) != pi_ear_tip);
707 BLI_assert(coords_num_concave_test ==
pf->coords_num_concave);
712 if (
pf->coords_num_concave == 0) {
717 if (
UNLIKELY(pi_ear_tip->sign != sign_accept)) {
723 const uint32_t ind[3] = {pi_ear_tip->index, pi_ear_tip->next->index, pi_ear_tip->prev->index};
731 v1 = coords[pi_ear_tip->prev->index];
732 v2 = coords[pi_ear_tip->index];
733 v3 = coords[pi_ear_tip->next->index];
739 for (pi_curr = pi_ear_tip->next->next; pi_curr != pi_ear_tip->prev; pi_curr = pi_curr->next) {
742 if (pi_curr->sign != CONVEX) {
743 const float *
v = coords[pi_curr->index];
758# ifdef USE_CONVEX_SKIP
759 coords_num_concave_checked += 1;
760 if (coords_num_concave_checked ==
pf->coords_num_concave) {
775 tri[0] = pi_ear_tip->prev->index;
776 tri[1] = pi_ear_tip->index;
777 tri[2] = pi_ear_tip->next->index;
786 const float (*coords)[2],
787 const uint32_t coords_num,
789 uint32_t (*r_tris)[3],
790 PolyIndex *r_indices)
793 PolyIndex *
indices = r_indices;
798 pf->indices = r_indices;
800 pf->coords_num = coords_num;
801#ifdef USE_CONVEX_SKIP
802 pf->coords_num_concave = 0;
807 if (coords_sign == 0) {
808 coords_sign = (
cross_poly_v2(coords, coords_num) <= 0.0f) ? 1 : -1;
812#ifdef USE_STRICT_ASSERT
814 if (coords_sign == 1) {
824 if (coords_sign == 1) {
825 for (
i = 0;
i < coords_num;
i++) {
833 uint32_t n = coords_num - 1;
834 for (
i = 0;
i < coords_num;
i++) {
843 for (
i = 0;
i < coords_num;
i++) {
846#ifdef USE_CONVEX_SKIP
847 if (pi->sign != CONVEX) {
848 pf->coords_num_concave += 1;
857# ifdef USE_CONVEX_SKIP
858 if (
pf->coords_num_concave)
872 const uint32_t coords_num,
873 const int coords_sign,
874 uint32_t (*r_tris)[3],
879 PolyIndex *
indices =
static_cast<PolyIndex *
>(
895 if (
pf.coords_num_concave) {
896 pf.kdtree.nodes =
static_cast<KDTreeNode2D *
>(
898 pf.kdtree.nodes_map =
static_cast<uint32_t *
>(
901 sizeof(*
pf.kdtree.nodes_map) * coords_num));
904 pf.kdtree.node_num = 0;
919 const uint32_t coords_num,
920 const int coords_sign,
921 uint32_t (*r_tris)[3])
952 if (
pf.coords_num_concave) {
953 pf.kdtree.nodes =
static_cast<KDTreeNode2D *
>(
955 pf.kdtree.nodes_map =
static_cast<uint32_t *
>(
958 sizeof(*
pf.kdtree.nodes_map) * coords_num));
961 pf.kdtree.node_num = 0;
#define BLI_array_alloca(arr, realsize)
float cross_poly_v2(const float verts[][2], unsigned int nr)
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])
MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void BLI_memarena_free(MemArena *ma) ATTR_NONNULL(1)
void * BLI_memarena_alloc(MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
Utility defines for timing/benchmarks.
#define TIMEIT_START(var)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
#define pf(_x, _i)
Prefetch 64.
static void kdtree2d_node_remove(KDTree2D *tree, uint32_t index)
static void pf_coord_sign_calc(const PolyFill *pf, PolyIndex *pi)
static PolyIndex * pf_ear_tip_find(PolyFill *pf, PolyIndex *pi_ear_init, bool reverse)
void BLI_polyfill_calc_arena(const float(*coords)[2], const uint32_t coords_num, const int coords_sign, uint32_t(*r_tris)[3], MemArena *arena)
static uint32_t kdtree2d_balance_recursive(KDTreeNode2D *nodes, uint32_t node_num, axis_t axis, const float(*coords)[2], const uint32_t ofs)
static void kdtree2d_balance(KDTree2D *tree)
void BLI_polyfill_calc(const float(*coords)[2], const uint32_t coords_num, const int coords_sign, uint32_t(*r_tris)[3])
static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip, const eSign sign_accept)
BLI_INLINE eSign signum_enum(float a)
static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip)
#define KDTREE2D_ISECT_TRI_RECURSE_NEG
static bool kdtree2d_isect_tri(KDTree2D *tree, const uint32_t ind[3])
static bool kdtree2d_isect_tri_recursive(const KDTree2D *tree, const uint32_t tri_index[3], const float *tri_coords[3], const float tri_center[2], const KDRange2D bounds[2], const KDTreeNode2D *node)
static uint32_t * pf_tri_add(PolyFill *pf)
BLI_INLINE float area_tri_signed_v2_alt_2x(const float v1[2], const float v2[2], const float v3[2])
static void polyfill_prepare(PolyFill *pf, const float(*coords)[2], const uint32_t coords_num, int coords_sign, uint32_t(*r_tris)[3], PolyIndex *r_indices)
static eSign span_tri_v2_sign(const float v1[2], const float v2[2], const float v3[2])
static void kdtree2d_init_mapping(KDTree2D *tree)
static void kdtree2d_new(KDTree2D *tree, uint32_t tot, const float(*coords)[2])
#define KDTREE2D_ISECT_TRI_RECURSE_POS
static void kdtree2d_init(KDTree2D *tree, const uint32_t coords_num, const PolyIndex *indices)
static void polyfill_calc(PolyFill *pf)
static void pf_coord_remove(PolyFill *pf, PolyIndex *pi)
static void pf_triangulate(PolyFill *pf)