42 float min_xy[2], max_xy[2];
47struct ScanFillVertLink {
56#define SF_EPSILON 0.00003f
57#define SF_EPSILON_SQ (SF_EPSILON * SF_EPSILON)
61#define SF_VERT_AVAILABLE 1
62#define SF_VERT_ZERO_LEN 2
69#define SF_EDGE_INTERNAL 2
73#define SF_POLY_VALID 1
79 const ScanFillVertLink *x1 =
static_cast<const ScanFillVertLink *
>(a1);
80 const ScanFillVertLink *x2 =
static_cast<const ScanFillVertLink *
>(a2);
82 if (x1->vert->
xy[1] < x2->vert->
xy[1]) {
85 if (x1->vert->
xy[1] > x2->vert->
xy[1]) {
88 if (x1->vert->
xy[0] > x2->vert->
xy[0]) {
91 if (x1->vert->
xy[0] < x2->vert->
xy[0]) {
108 sf_v->
tmp.
p =
nullptr;
162 if (pf1->edges == 0 ||
pf2->edges == 0) {
166 if (
pf2->max_xy[0] < pf1->min_xy[0]) {
169 if (
pf2->max_xy[1] < pf1->min_xy[1]) {
173 if (
pf2->min_xy[0] > pf1->max_xy[0]) {
176 if (
pf2->min_xy[1] > pf1->max_xy[1]) {
185 const uint pf_target,
187 uint *__restrict target_map)
189 const PolyFill *pf_a = pf_list + pf_test;
190 for (
uint pf_b_index = pf_target + 1; pf_b_index < pf_len; pf_b_index++) {
191 if (target_map[pf_b_index] != pf_b_index) {
196 const PolyFill *pf_b = pf_list + pf_b_index;
198 target_map[pf_b_index] = pf_target;
209 if (eve->poly_nr ==
pf2->nr) {
210 eve->poly_nr = pf1->nr;
215 if (eed->poly_nr ==
pf2->nr) {
216 eed->poly_nr = pf1->nr;
221 pf1->verts +=
pf2->verts;
222 pf1->edges +=
pf2->edges;
224 pf1->max_xy[0] = std::max(pf1->max_xy[0],
pf2->max_xy[0]);
225 pf1->max_xy[1] = std::max(pf1->max_xy[1],
pf2->max_xy[1]);
227 pf1->min_xy[0] = std::min(pf1->min_xy[0],
pf2->min_xy[0]);
228 pf1->min_xy[1] = std::min(pf1->min_xy[1],
pf2->min_xy[1]);
230 pf1->f = (pf1->f |
pf2->f);
233 pf2->verts =
pf2->edges = 0;
241 inp = (
v2[0] - v1[0]) * (v1[1] - v3[1]) + (v1[1] -
v2[1]) * (v1[0] - v3[0]);
247 if (v1[0] == v3[0] && v1[1] == v3[1]) {
250 if (
v2[0] == v3[0] &&
v2[1] == v3[1]) {
261 float fac, fac1,
x,
y;
263 if (sc->edge_first ==
nullptr) {
264 sc->edge_first = sc->edge_last = eed;
272 fac1 = eed->
v2->
xy[1] -
y;
274 fac1 = 1.0e10f * (eed->
v2->
xy[0] -
x);
277 fac1 = (
x - eed->
v2->
xy[0]) / fac1;
280 for (ed = sc->edge_first; ed; ed = ed->
next) {
282 if (ed->
v2 == eed->
v2) {
286 fac = ed->
v2->
xy[1] -
y;
288 fac = 1.0e10f * (ed->
v2->
xy[0] -
x);
291 fac = (
x - ed->
v2->
xy[0]) / fac;
312 ScanFillVertLink *sc, scsearch;
316 if (eed->
v1->
xy[1] == eed->
v2->
xy[1]) {
317 if (eed->
v1->
xy[0] > eed->
v2->
xy[0]) {
323 else if (eed->
v1->
xy[1] < eed->
v2->
xy[1]) {
329 scsearch.vert = eed->
v1;
330 sc = (ScanFillVertLink *)bsearch(&scsearch, scdata,
len,
sizeof(ScanFillVertLink),
vergscdata);
333 printf(
"Error in search edge: %p\n", (
void *)eed);
347 float minx, maxx, miny, maxy;
349 if (eed->
v1->
xy[0] < eed->
v2->
xy[0]) {
350 minx = eed->
v1->
xy[0];
351 maxx = eed->
v2->
xy[0];
354 minx = eed->
v2->
xy[0];
355 maxx = eed->
v1->
xy[0];
357 if (eve->
xy[0] >= minx && eve->
xy[0] <= maxx) {
358 if (eed->
v1->
xy[1] < eed->
v2->
xy[1]) {
359 miny = eed->
v1->
xy[1];
360 maxy = eed->
v2->
xy[1];
363 miny = eed->
v2->
xy[1];
364 maxy = eed->
v1->
xy[1];
366 if (eve->
xy[1] >= miny && eve->
xy[1] <= maxy) {
379 if (eve->edge_count == 1) {
384 for (; !(ed1->
v1 == eve || ed1->
v2 == eve); ed1 = ed1->
next) {
388 if (ed1->
v1 == eve) {
394 if (eve != eed->v1 && eve != eed->v2 && eve->poly_nr == eed->poly_nr) {
434 if (eve->poly_nr == nr) {
441 if (eed->poly_nr == nr) {
450 ScanFillVertLink *scdata;
451 ScanFillVertLink *sc =
nullptr, *sc1;
455 bool twoconnected =
false;
461 printf(
"vert: %x co: %f %f\n", eve, eve->xy[0], eve->xy[1]);
465 printf(
"edge: %x verts: %x %x\n", eed, eed->v1, eed->v2);
475 eed->v2->tmp.v = eed->v1->tmp.v;
479 eed->v1->tmp.v = eed->v2->tmp.v;
482 eed->v1->tmp.v = eed->v2->tmp.v;
486 eed->v2->tmp.v = eed->v1;
498 if (eve->poly_nr == nr) {
503 sc->edge_first = sc->edge_last =
nullptr;
506 if (even->tmp.v ==
nullptr) {
532 (eed->v1 != eed->v1->tmp.v))
534 eed->v1 = eed->v1->tmp.v;
540 (eed->v2 != eed->v2->tmp.v))
542 eed->v2 = eed->v2->tmp.v;
545 if (eed->v1 != eed->v2) {
553 if (eed->v1 != eed->v2) {
559 sc = sf_ctx->_scdata;
560 for (a = 0; a <
verts; a++) {
561 printf(
"\nscvert: %x\n", sc->vert);
562 for (eed = sc->edge_first; eed; eed = eed->
next) {
563 printf(
" ed %x %x %x\n", eed, eed->v1, eed->v2);
586 for (a = 0; a <
verts; a++) {
590 for (ed1 = sc->edge_first; ed1; ed1 = eed_next) {
591 eed_next = ed1->
next;
606 while (sc->edge_first) {
607 ed1 = sc->edge_first;
613 if (callLocalInterruptCallBack()){
617 if (totface >= maxface) {
622 if (ed2 ==
nullptr) {
623 sc->edge_first = sc->edge_last =
nullptr;
632 ScanFillVertLink *best_sc =
nullptr;
633 float angle_best_cos = -1.0f;
635 bool firsttime =
false;
642 if (v1 ==
v2 ||
v2 == v3) {
650 for (
b = a + 1;
b <
verts;
b++, sc1++) {
652 if (sc1->vert->xy[1] <= miny) {
663 if (best_sc ==
nullptr) {
670 if (firsttime ==
false) {
675 const float angle_test_cos =
cos_v2v2v2(
v2->xy, v1->
xy, sc1->vert->xy);
676 if (angle_test_cos > angle_best_cos) {
678 angle_best_cos = angle_test_cos;
733 for (ed3 = sc1->edge_first; ed3; ed3 = ed3->
next) {
734 if ((ed3->
v1 == v1 && ed3->
v2 == v3) || (ed3->
v1 == v3 && ed3->
v2 == v1)) {
749 for (ed1 = sc->edge_first; ed1; ed1 = eed_next) {
750 eed_next = ed1->
next;
777 memset(sf_ctx, 0,
sizeof(*sf_ctx));
784 memset(sf_ctx, 0,
sizeof(*sf_ctx));
786 sf_ctx->
arena = arena;
792 sf_ctx->
arena =
nullptr;
820 PolyFill *pflist, *
pf;
821 float *min_xy_p, *max_xy_p;
847 bool vert_available =
false;
850 vert_available =
true;
915 for (; eed; eed = (toggle & 1) ? eed->
next : eed->
prev) {
963 if ((eed->v1->edge_count++ > 250) || (eed->v2->edge_count++ > 250)) {
966 printf(
"No vertices with 250 edges allowed!\n");
984 for (; eed; eed = eed_next) {
985 eed_next = (toggle & 1) ? eed->
next : eed->
prev;
1008 eed->v1->edge_count++;
1009 eed->v2->edge_count++;
1033 for (a = 0; a < poly; a++) {
1034 pf->edges =
pf->verts = 0;
1035 pf->min_xy[0] =
pf->min_xy[1] = 1.0e20f;
1036 pf->max_xy[0] =
pf->max_xy[1] = -1.0e20f;
1042 pflist[eed->poly_nr].edges++;
1046 pflist[eve->poly_nr].verts++;
1047 min_xy_p = pflist[eve->poly_nr].min_xy;
1048 max_xy_p = pflist[eve->poly_nr].max_xy;
1050 min_xy_p[0] = (min_xy_p[0]) < (eve->xy[0]) ? (min_xy_p[0]) : (eve->xy[0]);
1051 min_xy_p[1] = (min_xy_p[1]) < (eve->xy[1]) ? (min_xy_p[1]) : (eve->xy[1]);
1052 max_xy_p[0] = (max_xy_p[0]) > (eve->xy[0]) ? (max_xy_p[0]) : (eve->xy[0]);
1053 max_xy_p[1] = (max_xy_p[1]) > (eve->xy[1]) ? (max_xy_p[1]) : (eve->xy[1]);
1054 if (eve->edge_count > 2) {
1066 for (a = 0; a < poly; a++) {
1067 printf(
"poly:%d edges:%d verts:%d flag: %d\n", a,
pf->edges,
pf->verts,
pf->f);
1068 PRINT2(f, f,
pf->min[0],
pf->min[1]);
1076 for (a = 0; a < poly; a++) {
1077 if (target_map[a] != a) {
1084 for (a = 0; a < poly; a++) {
1085 if (target_map[a] != a) {
1086 PolyFill *pf_src = pflist + a;
1087 PolyFill *pf_dst = pflist + target_map[a];
1098 for (a = 0; a < poly; a++) {
1099 printf(
"poly:%d edges:%d verts:%d flag: %d\n", a,
pf->edges,
pf->verts,
pf->f);
1114 for (a = 0; a < poly; a++) {
1115 if (
pf->edges > 1) {
void void void BLI_movelisttolist(ListBase *dst, ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_insertlinkbefore(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])
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)
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
struct ScanFillEdge ScanFillEdge
struct ScanFillVert ScanFillVert
#define BLI_SCANFILL_ARENA_SIZE
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
#define pf2(_x, _i)
Prefetch 128.
#define pf(_x, _i)
Prefetch 64.
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, 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)
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::@026355123305312163137370333220125272167065274016 tmp
struct ScanFillEdge * next
union ScanFillVert::@316106002035155215355067045167356240017116022023 tmp