diff options
Diffstat (limited to 'source/blender/blenlib/intern/scanfill.c')
-rw-r--r-- | source/blender/blenlib/intern/scanfill.c | 123 |
1 files changed, 75 insertions, 48 deletions
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index defe500cb21..771295b4b78 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -459,7 +459,7 @@ static void testvertexnearedge(ScanFillContext *sf_ctx) /* new edge */ ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve); - /* printf("fill: vertex near edge %x\n",eve); */ + /* printf("fill: vertex near edge %x\n", eve); */ ed1->f = 0; ed1->poly_nr = eed->poly_nr; eed->v1 = eve; @@ -630,11 +630,16 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) /* (temporal) security: never much more faces than vertices */ totface = 0; - maxface = 2 * verts; /* 2*verts: based at a filled circle within a triangle */ + if (flag & BLI_SCANFILL_CALC_HOLES) { + maxface = 2 * verts; /* 2*verts: based at a filled circle within a triangle */ + } + else { + maxface = verts - 2; /* when we don't calc any holes, we assume face is a non overlapping loop */ + } sc = sf_ctx->_scdata; for (a = 0; a < verts; a++) { - /* printf("VERTEX %d %x\n",a,sc->v1); */ + /* printf("VERTEX %d %x\n", a, sc->v1); */ ed1 = sc->edge_first; while (ed1) { /* set connectflags */ nexted = ed1->next; @@ -654,7 +659,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) /* commented out... the ESC here delivers corrupted memory (and doesnt work during grab) */ /* if (callLocalInterruptCallBack()) break; */ - if (totface > maxface) { + if (totface >= maxface) { /* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */ a = verts; break; @@ -675,30 +680,31 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) v3 = ed2->v2; /* this happens with a serial of overlapping edges */ if (v1 == v2 || v2 == v3) break; - /* printf("test verts %x %x %x\n",v1,v2,v3); */ + /* printf("test verts %x %x %x\n", v1, v2, v3); */ miny = min_ff(v1->xy[1], v3->xy[1]); - /* miny = min_ff(v1->xy[1],v3->xy[1]); */ + /* miny = min_ff(v1->xy[1], v3->xy[1]); */ sc1 = sc + 1; test = 0; for (b = a + 1; b < verts; b++) { if (sc1->vert->f == 0) { if (sc1->vert->xy[1] <= miny) break; - - if (testedgeside(v1->xy, v2->xy, sc1->vert->xy)) - if (testedgeside(v2->xy, v3->xy, sc1->vert->xy)) + if (testedgeside(v1->xy, v2->xy, sc1->vert->xy)) { + if (testedgeside(v2->xy, v3->xy, sc1->vert->xy)) { if (testedgeside(v3->xy, v1->xy, sc1->vert->xy)) { /* point in triangle */ - + test = 1; break; } + } + } } sc1++; } if (test) { /* make new edge, and start over */ - /* printf("add new edge %x %x and start again\n",v2,sc1->vert); */ + /* printf("add new edge %x %x and start again\n", v2, sc1->vert); */ ed3 = BLI_scanfill_edge_add(sf_ctx, v2, sc1->vert); BLI_remlink(&sf_ctx->filledgebase, ed3); @@ -710,7 +716,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) } else { /* new triangle */ - /* printf("add face %x %x %x\n",v1,v2,v3); */ + /* printf("add face %x %x %x\n", v1, v2, v3); */ addfillface(sf_ctx, v1, v2, v3); totface++; BLI_remlink((ListBase *)&(sc->edge_first), ed1); @@ -734,7 +740,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) ed3->v1->h++; ed3->v2->h++; - /* printf("add new edge %x %x\n",v1,v3); */ + /* printf("add new edge %x %x\n", v1, v3); */ sc1 = addedgetoscanlist(sf_ctx, ed3, verts); if (sc1) { /* ed3 already exists: remove if a boundary */ @@ -773,12 +779,15 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) ed1 = nexted; } } + sc++; } MEM_freeN(sf_ctx->_scdata); sf_ctx->_scdata = NULL; + BLI_assert(totface <= maxface); + return totface; } @@ -910,50 +919,68 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no /* STEP 1: COUNT POLYS */ - eve = sf_ctx->fillvertbase.first; - while (eve) { - eve->xy[0] = eve->co[co_x]; - eve->xy[1] = eve->co[co_y]; + if (flag & BLI_SCANFILL_CALC_HOLES) { + eve = sf_ctx->fillvertbase.first; + while (eve) { + eve->xy[0] = eve->co[co_x]; + eve->xy[1] = eve->co[co_y]; + + /* get first vertex with no poly number */ + if (eve->poly_nr == 0) { + poly++; + /* now a sort of select connected */ + ok = 1; + eve->poly_nr = poly; - /* get first vertex with no poly number */ - if (eve->poly_nr == 0) { - poly++; - /* now a sort of select connected */ - ok = 1; - eve->poly_nr = poly; - - while (ok) { - - ok = 0; - toggle++; - if (toggle & 1) eed = sf_ctx->filledgebase.first; - else eed = sf_ctx->filledgebase.last; - - while (eed) { - if (eed->v1->poly_nr == 0 && eed->v2->poly_nr == poly) { - eed->v1->poly_nr = poly; - eed->poly_nr = poly; - ok = 1; - } - else if (eed->v2->poly_nr == 0 && eed->v1->poly_nr == poly) { - eed->v2->poly_nr = poly; - eed->poly_nr = poly; - ok = 1; - } - else if (eed->poly_nr == 0) { - if (eed->v1->poly_nr == poly && eed->v2->poly_nr == poly) { + while (ok) { + + ok = 0; + toggle++; + if (toggle & 1) eed = sf_ctx->filledgebase.first; + else eed = sf_ctx->filledgebase.last; + + while (eed) { + if (eed->v1->poly_nr == 0 && eed->v2->poly_nr == poly) { + eed->v1->poly_nr = poly; eed->poly_nr = poly; ok = 1; } + else if (eed->v2->poly_nr == 0 && eed->v1->poly_nr == poly) { + eed->v2->poly_nr = poly; + eed->poly_nr = poly; + ok = 1; + } + else if (eed->poly_nr == 0) { + if (eed->v1->poly_nr == poly && eed->v2->poly_nr == poly) { + eed->poly_nr = poly; + ok = 1; + } + } + if (toggle & 1) eed = eed->next; + else eed = eed->prev; } - if (toggle & 1) eed = eed->next; - else eed = eed->prev; } } + eve = eve->next; + } + /* printf("amount of poly's: %d\n", poly); */ + } + else { + poly = 1; + + eve = sf_ctx->fillvertbase.first; + while (eve) { + eve->xy[0] = eve->co[co_x]; + eve->xy[1] = eve->co[co_y]; + eve->poly_nr = poly; + eve = eve->next; + } + eed = sf_ctx->filledgebase.first; + while (eed) { + eed->poly_nr = poly; + eed = eed->next; } - eve = eve->next; } - /* printf("amount of poly's: %d\n",poly); */ /* STEP 2: remove loose edges and strings of edges */ eed = sf_ctx->filledgebase.first; |