52#define SF_EPSILON 0.00003f
53#define SF_EPSILON_SQ (SF_EPSILON * SF_EPSILON)
57#define SF_VERT_AVAILABLE 1
58#define SF_VERT_ZERO_LEN 2
65#define SF_EDGE_INTERNAL 2
69#define SF_POLY_VALID 1
77 if (x1->
vert->
xy[1] < x2->vert->xy[1]) {
80 if (x1->
vert->
xy[1] > x2->vert->xy[1]) {
83 if (x1->
vert->
xy[0] > x2->vert->xy[0]) {
86 if (x1->
vert->
xy[0] < x2->vert->xy[0]) {
157 if (pf1->
edges == 0 ||
pf2->edges == 0) {
180 const uint pf_target,
182 uint *__restrict target_map)
184 const PolyFill *pf_a = pf_list + pf_test;
185 for (
uint pf_b_index = pf_target + 1; pf_b_index < pf_len; pf_b_index++) {
186 if (target_map[pf_b_index] != pf_b_index) {
191 const PolyFill *pf_b = pf_list + pf_b_index;
193 target_map[pf_b_index] = pf_target;
236 pf1->
f = (pf1->
f |
pf2->f);
239 pf2->verts =
pf2->edges = 0;
247 inp = (
v2[0] - v1[0]) * (v1[1] - v3[1]) + (v1[1] -
v2[1]) * (v1[0] - v3[0]);
253 if (v1[0] == v3[0] && v1[1] == v3[1]) {
256 if (
v2[0] == v3[0] &&
v2[1] == v3[1]) {
267 float fac, fac1,
x,
y;
278 fac1 = eed->
v2->
xy[1] -
y;
280 fac1 = 1.0e10f * (eed->
v2->
xy[0] -
x);
283 fac1 = (x - eed->
v2->
xy[0]) / fac1;
288 if (ed->
v2 == eed->
v2) {
292 fac = ed->
v2->
xy[1] -
y;
294 fac = 1.0e10f * (ed->
v2->
xy[0] -
x);
297 fac = (x - ed->
v2->
xy[0]) / fac;
322 if (eed->
v1->
xy[1] == eed->
v2->
xy[1]) {
323 if (eed->
v1->
xy[0] > eed->
v2->
xy[0]) {
329 else if (eed->
v1->
xy[1] < eed->
v2->
xy[1]) {
339 printf(
"Error in search edge: %p\n", (
void *)eed);
353 float minx, maxx, miny, maxy;
355 if (eed->
v1->
xy[0] < eed->
v2->
xy[0]) {
356 minx = eed->
v1->
xy[0];
357 maxx = eed->
v2->
xy[0];
360 minx = eed->
v2->
xy[0];
361 maxx = eed->
v1->
xy[0];
363 if (eve->
xy[0] >= minx && eve->
xy[0] <= maxx) {
364 if (eed->
v1->
xy[1] < eed->
v2->
xy[1]) {
365 miny = eed->
v1->
xy[1];
366 maxy = eed->
v2->
xy[1];
369 miny = eed->
v2->
xy[1];
370 maxy = eed->
v1->
xy[1];
372 if (eve->
xy[1] >= miny && eve->
xy[1] <= maxy) {
397 if (ed1->
v1 == eve) {
445 for (eve = tempve->
first; eve; eve = eve_next) {
446 eve_next = eve->
next;
453 for (eed = temped->
first; eed; eed = eed_next) {
454 eed_next = eed->
next;
470 bool twoconnected =
false;
476 printf(
"vert: %x co: %f %f\n", eve, eve->
xy[0], eve->
xy[1]);
480 printf(
"edge: %x verts: %x %x\n", eed, eed->
v1, eed->
v2);
510 sc = scdata =
MEM_mallocN(
sizeof(*scdata) *
pf->verts,
"Scanfill1");
521 if (even->tmp.v ==
NULL) {
534 eed_next = eed->
next;
561 if (eed->
v1 != eed->
v2) {
568 eed_next = eed->
next;
570 if (eed->
v1 != eed->
v2) {
576 sc = sf_ctx->_scdata;
577 for (a = 0; a <
verts; a++) {
580 printf(
" ed %x %x %x\n", eed, eed->
v1, eed->
v2);
603 for (a = 0; a <
verts; a++) {
606 for (ed1 = sc->
edge_first; ed1; ed1 = eed_next) {
607 eed_next = ed1->
next;
629 if (callLocalInterruptCallBack()){
633 if (totface >= maxface) {
649 float angle_best_cos = -1.0f;
651 bool firsttime =
false;
658 if (v1 ==
v2 ||
v2 == v3) {
666 for (
b = a + 1;
b <
verts;
b++, sc1++) {
668 if (sc1->vert->xy[1] <= miny) {
679 if (best_sc ==
NULL) {
686 if (firsttime ==
false) {
691 const float angle_test_cos =
cos_v2v2v2(
v2->xy, v1->
xy, sc1->vert->xy);
692 if (angle_test_cos > angle_best_cos) {
694 angle_best_cos = angle_test_cos;
749 for (ed3 = sc1->edge_first; ed3; ed3 = ed3->
next) {
750 if ((ed3->
v1 == v1 && ed3->
v2 == v3) || (ed3->
v1 == v3 && ed3->
v2 == v1)) {
765 for (ed1 = sc->
edge_first; ed1; ed1 = eed_next) {
766 eed_next = ed1->
next;
793 memset(sf_ctx, 0,
sizeof(*sf_ctx));
800 memset(sf_ctx, 0,
sizeof(*sf_ctx));
802 sf_ctx->
arena = arena;
839 float *min_xy_p, *max_xy_p;
931 eed = (toggle & 1) ? eed->
next : eed->
prev)
990 printf(
"No vertices with 250 edges allowed!\n");
1006 eed_next = (toggle & 1) ? eed->
next : eed->
prev;
1052 pflist =
MEM_mallocN(
sizeof(*pflist) * (
size_t)poly,
"edgefill");
1054 for (a = 0; a < poly; a++) {
1056 pf->min_xy[0] =
pf->min_xy[1] = 1.0e20f;
1057 pf->max_xy[0] =
pf->max_xy[1] = -1.0e20f;
1071 min_xy_p[0] = (min_xy_p[0]) < (eve->
xy[0]) ? (min_xy_p[0]) : (eve->
xy[0]);
1072 min_xy_p[1] = (min_xy_p[1]) < (eve->
xy[1]) ? (min_xy_p[1]) : (eve->
xy[1]);
1073 max_xy_p[0] = (max_xy_p[0]) > (eve->
xy[0]) ? (max_xy_p[0]) : (eve->
xy[0]);
1074 max_xy_p[1] = (max_xy_p[1]) > (eve->
xy[1]) ? (max_xy_p[1]) : (eve->
xy[1]);
1087 for (a = 0; a < poly; a++) {
1088 printf(
"poly:%d edges:%d verts:%d flag: %d\n", a,
pf->edges,
pf->verts,
pf->f);
1089 PRINT2(f, f,
pf->min[0],
pf->min[1]);
1094 uint *target_map =
MEM_mallocN(
sizeof(*target_map) * (
size_t)poly,
"polycache");
1097 for (a = 0; a < poly; a++) {
1098 if (target_map[a] != a) {
1105 for (a = 0; a < poly; a++) {
1106 if (target_map[a] != a) {
1108 PolyFill *pf_dst = pflist + target_map[a];
1119 for (a = 0; a < poly; a++) {
1120 printf(
"poly:%d edges:%d verts:%d flag: %d\n", a,
pf->edges,
pf->verts,
pf->f);
1135 for (a = 0; a < poly; a++) {
1136 if (
pf->edges > 1) {
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
MINLINE float min_ff(float a, float b)
void axis_dominant_v3_to_m3_negate(float r_mat[3][3], const float normal[3])
float dist_squared_to_line_v2(const float p[2], const float l1[2], const float l2[2])
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2]) ATTR_WARN_UNUSED_RESULT
MINLINE bool equals_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE bool compare_v2v2(const float v1[2], const float v2[2], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE bool compare_v3v3(const float v1[3], const float v2[3], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v2(float r[2])
void range_vn_u(unsigned int *array_tar, int size, unsigned int start)
MINLINE void zero_v3(float r[3])
MINLINE float normalize_v3(float n[3])
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
@ BLI_SCANFILL_CALC_LOOSE
@ BLI_SCANFILL_CALC_POLYS
@ BLI_SCANFILL_CALC_HOLES
@ BLI_SCANFILL_CALC_REMOVE_DOUBLES
#define BLI_SCANFILL_ARENA_SIZE
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
local_group_size(16, 16) .push_constant(Type b
#define pf2(_x, _i)
Prefetch 128.
#define pf(_x, _i)
Prefetch 64.
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
static void addfillface(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert *v2, ScanFillVert *v3)
static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *temped, ushort nr)
static bool testedgeside(const float v1[2], const float v2[2], const float v3[2])
void BLI_scanfill_begin(ScanFillContext *sf_ctx)
struct ScanFillVertLink ScanFillVertLink
void BLI_scanfill_end_arena(ScanFillContext *sf_ctx, MemArena *arena)
void BLI_scanfill_end(ScanFillContext *sf_ctx)
static void mergepolysSimp(ScanFillContext *sf_ctx, PolyFill *pf1, PolyFill *pf2)
static bool boundinsideEV(const ScanFillEdge *eed, const ScanFillVert *eve)
static int vergscdata(const void *a1, const void *a2)
uint BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3])
void BLI_scanfill_begin_arena(ScanFillContext *sf_ctx, MemArena *arena)
static void fill_target_map_recursive(const PolyFill *__restrict pf_list, const uint pf_len, const uint pf_target, const uint pf_test, uint *__restrict target_map)
static uint scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
static bool boundisect(const PolyFill *pf2, const PolyFill *pf1)
ScanFillVert * BLI_scanfill_vert_add(ScanFillContext *sf_ctx, const float vec[3])
static ScanFillVertLink * addedgetoscanlist(ScanFillVertLink *scdata, ScanFillEdge *eed, uint len)
static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed)
ScanFillEdge * BLI_scanfill_edge_add(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert *v2)
uint BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag)
#define SF_VERT_AVAILABLE
static void testvertexnearedge(ScanFillContext *sf_ctx)
struct ScanFillEdge * prev
union ScanFillEdge::@115 tmp
struct ScanFillEdge * next
ScanFillEdge * edge_first
struct ScanFillVert * next
union ScanFillVert::@114 tmp