58 #define USE_CONVEX_SKIP
60 #define USE_CLIP_SWEEP
63 #ifdef USE_CONVEX_SKIP
137 #ifdef USE_CONVEX_SKIP
198 return (d2[0] * d3[1]) - (d3[0] * d2[1]);
207 # define KDNODE_UNSET ((uint)-1)
217 tree->coords = coords;
230 for (i = 0,
node =
tree->nodes; i < coords_tot; i++) {
259 median = totnode / 2;
262 const float co = coords[nodes[
pos].
index][axis];
267 while (coords[nodes[++i].
index][axis] < co) {
269 while (coords[nodes[--j].
index][axis] > co && j > neg) {
288 node = &nodes[median];
293 &nodes[median + 1], (totnode - (median + 1)), axis, coords, (median + 1) + ofs);
308 for (i = 0,
node =
tree->nodes; i < tree->totnode; i++,
node++) {
346 if (node_parent->
neg == node_index) {
355 node_index =
node->parent;
365 const uint tri_index[3],
366 const float *tri_coords[3],
367 const float tri_center[2],
371 const float *co =
tree->coords[
node->index];
381 if (!
ELEM(
node->index, tri_index[0], tri_index[1], tri_index[2])) {
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])))
397 if (tri_center[
node->axis] > co[
node->axis]) {
414 # undef KDTREE2D_ISECT_TRI_RECURSE_NEG
415 # undef KDTREE2D_ISECT_TRI_RECURSE_POS
430 float tri_center[2] = {0.0f, 0.0f};
432 for (i = 0; i < 3; i++) {
433 vs[i] =
tree->coords[ind[i]];
452 return pf->tris[
pf->tris_tot++];
459 if (
pf->kdtree.totnode) {
486 #ifdef USE_CLIP_SWEEP
487 bool reverse =
false;
490 while (
pf->coords_tot > 3) {
492 eSign sign_orig_prev, sign_orig_next;
505 #ifdef USE_CONVEX_SKIP
507 pf->coords_tot_concave -= 1;
511 pi_prev = pi_ear->
prev;
512 pi_next = pi_ear->
next;
517 sign_orig_prev = pi_prev->
sign;
518 sign_orig_next = pi_next->
sign;
522 if (sign_orig_prev !=
CONVEX) {
524 #ifdef USE_CONVEX_SKIP
526 pf->coords_tot_concave -= 1;
533 if (sign_orig_next !=
CONVEX) {
535 #ifdef USE_CONVEX_SKIP
537 pf->coords_tot_concave -= 1;
546 # ifdef USE_CLIP_SWEEP
547 pi_ear_init = reverse ? pi_prev->
prev : pi_next->
next;
549 pi_ear_init = pi_next->
next;
554 # ifdef USE_CLIP_SWEEP
557 pi_ear_init = reverse ? pi_ear_init->
prev : pi_ear_init->
next;
568 if (
pf->coords_tot == 3) {
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;
585 const float(*coords)[2] =
pf->coords;
602 const uint coords_tot =
pf->coords_tot;
608 pi_ear = pi_ear_init;
610 pi_ear =
pf->indices;
618 #ifdef USE_CLIP_SWEEP
619 pi_ear = reverse ? pi_ear->
prev : pi_ear->
next;
621 pi_ear = pi_ear->
next;
638 pi_ear = pi_ear_init;
640 pi_ear =
pf->indices;
648 pi_ear = pi_ear->
next;
659 const float(*coords)[2] =
pf->coords;
662 const float *
v1, *
v2, *v3;
665 #if defined(USE_CONVEX_SKIP) && !defined(USE_KDTREE)
666 uint coords_tot_concave_checked = 0;
669 #ifdef USE_CONVEX_SKIP
671 # ifdef USE_CONVEX_SKIP_TEST
674 uint coords_tot_concave_test = 0;
678 coords_tot_concave_test += 1;
680 }
while ((pi_iter = pi_iter->
next) != pi_ear_tip);
681 BLI_assert(coords_tot_concave_test ==
pf->coords_tot_concave);
686 if (
pf->coords_tot_concave == 0) {
706 v2 = coords[pi_ear_tip->
index];
713 for (pi_curr = pi_ear_tip->
next->
next; pi_curr != pi_ear_tip->
prev; pi_curr = pi_curr->
next) {
717 const float *
v = coords[pi_curr->
index];
731 # ifdef USE_CONVEX_SKIP
732 coords_tot_concave_checked += 1;
733 if (coords_tot_concave_checked ==
pf->coords_tot_concave) {
749 tri[1] = pi_ear_tip->
index;
759 const float (*coords)[2],
760 const uint coords_tot,
771 pf->indices = r_indices;
773 pf->coords_tot = coords_tot;
774 #ifdef USE_CONVEX_SKIP
775 pf->coords_tot_concave = 0;
780 if (coords_sign == 0) {
781 coords_sign = (
cross_poly_v2(coords, coords_tot) >= 0.0f) ? 1 : -1;
785 #ifdef USE_STRICT_ASSERT
787 if (coords_sign == 1) {
797 if (coords_sign == 1) {
798 for (i = 0; i < coords_tot; i++) {
806 uint n = coords_tot - 1;
807 for (i = 0; i < coords_tot; i++) {
816 for (i = 0; i < coords_tot; i++) {
819 #ifdef USE_CONVEX_SKIP
821 pf->coords_tot_concave += 1;
830 # ifdef USE_CONVEX_SKIP
831 if (
pf->coords_tot_concave)
848 const uint coords_tot,
849 const int coords_sign,
870 if (
pf.coords_tot_concave) {
872 pf.kdtree.nodes_map = memset(
875 sizeof(*
pf.kdtree.nodes_map) * coords_tot);
878 pf.kdtree.totnode = 0;
906 const uint coords_tot,
907 const int coords_sign,
939 if (
pf.coords_tot_concave) {
943 sizeof(*
pf.kdtree.nodes_map) * coords_tot);
946 pf.kdtree.totnode = 0;
typedef float(TangentPoint)[2]
#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])
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
struct MemArena * BLI_memarena_new(const size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2) ATTR_MALLOC
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
_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)
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 bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip)
static void kdtree2d_init(struct KDTree2D *tree, const uint coords_tot, const PolyIndex *indices)
static PolyIndex * pf_ear_tip_find(PolyFill *pf, PolyIndex *pi_ear_init, bool reverse)
static bool kdtree2d_isect_tri(struct KDTree2D *tree, const uint ind[3])
struct KDTreeNode2D KDTreeNode2D
static void kdtree2d_init_mapping(struct KDTree2D *tree)
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)
BLI_INLINE eSign signum_enum(float a)
struct PolyIndex PolyIndex
static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip)
#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)
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)
BLI_INLINE float area_tri_signed_v2_alt_2x(const float v1[2], const float v2[2], const float v3[2])
static void kdtree2d_node_remove(struct KDTree2D *tree, uint index)
static void pf_coord_sign_calc(PolyFill *pf, PolyIndex *pi)
static eSign span_tri_v2_sign(const float v1[2], const float v2[2], const float v3[2])
void BLI_polyfill_calc_arena(const float(*coords)[2], const uint coords_tot, const int coords_sign, uint(*r_tris)[3], struct MemArena *arena)
static void kdtree2d_balance(struct KDTree2D *tree)
static uint * pf_tri_add(PolyFill *pf)
#define KDTREE2D_ISECT_TRI_RECURSE_POS
static void kdtree2d_new(struct KDTree2D *tree, uint tot, const float(*coords)[2])
static void polyfill_calc(PolyFill *pf)
static void pf_coord_remove(PolyFill *pf, PolyIndex *pi)
static void pf_triangulate(PolyFill *pf)
void BLI_polyfill_calc(const float(*coords)[2], const uint coords_tot, const int coords_sign, uint(*r_tris)[3])
struct PolyIndex * indices