static void scanfill(PolyFill *pf, int mat_nr) { ScFillVert *sc = NULL, *sc1; EditVert *eve,*v1,*v2,*v3; EditEdge *eed,*nexted,*ed1,*ed2,*ed3; float miny = 0.0; int a,b,verts, maxface, totface; short nr, test, twoconnected=0; nr= pf->nr; /* PRINTS verts= pf->verts; eve= fillvertbase.first; while(eve) { printf("vert: %x co: %f %f\n",eve,eve->co[cox],eve->co[coy]); eve= eve->next; } eed= filledgebase.first; while(eed) { printf("edge: %x verts: %x %x\n",eed,eed->v1,eed->v2); eed= eed->next; } */ /* STEP 0: remove zero sized edges */ eed= filledgebase.first; while(eed) { if(eed->v1->co[cox]==eed->v2->co[cox]) { if(eed->v1->co[coy]==eed->v2->co[coy]) { if(eed->v1->f==255 && eed->v2->f!=255) { eed->v2->f= 255; eed->v2->tmp.v= eed->v1->tmp.v; } else if(eed->v2->f==255 && eed->v1->f!=255) { eed->v1->f= 255; eed->v1->tmp.v= eed->v2->tmp.v; } else if(eed->v2->f==255 && eed->v1->f==255) { eed->v1->tmp.v= eed->v2->tmp.v; } else { eed->v2->f= 255; eed->v2->tmp.v = eed->v1->tmp.v; } } } eed= eed->next; } /* STEP 1: make using FillVert and FillEdge lists a sorted ScFillVert list */ sc= scdata= (ScFillVert *)MEM_callocN(pf->verts*sizeof(ScFillVert),"Scanfill1"); eve= fillvertbase.first; verts= 0; while(eve) { if(eve->xs==nr) { if(eve->f!= 255) { verts++; eve->f= 0; /* flag for connectedges later on */ sc->v1= eve; sc++; } } eve= eve->next; } qsort(scdata, verts, sizeof(ScFillVert), vergscdata); eed= filledgebase.first; while(eed) { nexted= eed->next; eed->f= 0; BLI_remlink(&filledgebase,eed); /* commented all of this out, this I have no idea for what it is for, probably from ancient past */ /* it does crash blender, since it uses mixed original and new vertices (ton) */ // if(eed->v1->f==255) { // v1= eed->v1; // while((eed->v1->f == 255) && (eed->v1->tmp.v != v1)) // eed->v1 = eed->v1->tmp.v; // } // if(eed->v2->f==255) { // v2= eed->v2; // while((eed->v2->f == 255) && (eed->v2->tmp.v != v2)) // eed->v2 = eed->v2->tmp.v; // } if(eed->v1!=eed->v2) addedgetoscanlist(eed,verts); eed= nexted; } /* sc= scdata; for(a=0;a<verts;a++) { printf("\nscvert: %x\n",sc->v1); eed= sc->first; while(eed) { printf(" ed %x %x %x\n",eed,eed->v1,eed->v2); eed= eed->next; } sc++; }*/ /* STEP 2: FILL LOOP */ if(pf->f==0) twoconnected= 1; /* (temporal) security: never much more faces than vertices */ totface= 0; maxface= 2*verts; /* 2*verts: based at a filled circle within a triangle */ sc= scdata; for(a=0;a<verts;a++) { /* printf("VERTEX %d %x\n",a,sc->v1); */ ed1= sc->first; while(ed1) { /* set connectflags */ nexted= ed1->next; if(ed1->v1->h==1 || ed1->v2->h==1) { BLI_remlink((ListBase *)&(sc->first),ed1); BLI_addtail(&filledgebase,ed1); if(ed1->v1->h>1) ed1->v1->h--; if(ed1->v2->h>1) ed1->v2->h--; } else ed1->v2->f= 1; ed1= nexted; } while(sc->first) { /* for as long there are edges */ ed1= sc->first; ed2= ed1->next; /* commented out... the ESC here delivers corrupted memory (and doesnt work during grab) */ /* if(callLocalInterruptCallBack()) break; */ if(totface>maxface) { /* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */ a= verts; break; } if(ed2==0) { sc->first=sc->last= 0; /* printf("just 1 edge to vert\n"); */ BLI_addtail(&filledgebase,ed1); ed1->v2->f= 0; ed1->v1->h--; ed1->v2->h--; } else { /* test rest of vertices */ v1= ed1->v2; v2= ed1->v1; 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); */ miny = ( (v1->co[coy])<(v3->co[coy]) ? (v1->co[coy]) : (v3->co[coy]) ); /* miny= MIN2(v1->co[coy],v3->co[coy]); */ sc1= sc+1; test= 0; for(b=a+1;b<verts;b++) { if(sc1->v1->f==0) { if(sc1->v1->co[coy] <= miny) break; if(testedgeside(v1->co,v2->co,sc1->v1->co)) if(testedgeside(v2->co,v3->co,sc1->v1->co)) if(testedgeside(v3->co,v1->co,sc1->v1->co)) { /* 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->v1); */ ed3= BLI_addfilledge(v2, sc1->v1); BLI_remlink(&filledgebase, ed3); BLI_insertlinkbefore((ListBase *)&(sc->first), ed2, ed3); ed3->v2->f= 1; ed3->f= 2; ed3->v1->h++; ed3->v2->h++; } else { /* new triangle */ /* printf("add face %x %x %x\n",v1,v2,v3); */ addfillface(v1, v2, v3, mat_nr); totface++; BLI_remlink((ListBase *)&(sc->first),ed1); BLI_addtail(&filledgebase,ed1); ed1->v2->f= 0; ed1->v1->h--; ed1->v2->h--; /* ed2 can be removed when it's an old one */ if(ed2->f==0 && twoconnected) { BLI_remlink((ListBase *)&(sc->first),ed2); BLI_addtail(&filledgebase,ed2); ed2->v2->f= 0; ed2->v1->h--; ed2->v2->h--; } /* new edge */ ed3= BLI_addfilledge(v1, v3); BLI_remlink(&filledgebase, ed3); ed3->f= 2; ed3->v1->h++; ed3->v2->h++; /* printf("add new edge %x %x\n",v1,v3); */ sc1= addedgetoscanlist(ed3, verts); if(sc1) { /* ed3 already exists: remove */ /* printf("Edge exists\n"); */ ed3->v1->h--; ed3->v2->h--; if(twoconnected) ed3= sc1->first; else ed3= 0; while(ed3) { if( (ed3->v1==v1 && ed3->v2==v3) || (ed3->v1==v3 && ed3->v2==v1) ) { BLI_remlink((ListBase *)&(sc1->first),ed3); BLI_addtail(&filledgebase,ed3); ed3->v1->h--; ed3->v2->h--; break; } ed3= ed3->next; } } } } /* test for loose edges */ ed1= sc->first; while(ed1) { nexted= ed1->next; if(ed1->v1->h<2 || ed1->v2->h<2) { BLI_remlink((ListBase *)&(sc->first),ed1); BLI_addtail(&filledgebase,ed1); if(ed1->v1->h>1) ed1->v1->h--; if(ed1->v2->h>1) ed1->v2->h--; } ed1= nexted; } } sc++; } MEM_freeN(scdata); }
static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) { ScanFillVertLink *scdata; ScanFillVertLink *sc = NULL, *sc1; ScanFillVert *eve, *v1, *v2, *v3; ScanFillEdge *eed, *eed_next, *ed1, *ed2, *ed3; unsigned int a, b, verts, maxface, totface; const unsigned short nr = pf->nr; bool twoconnected = false; /* PRINTS */ #if 0 verts = pf->verts; for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) { printf("vert: %x co: %f %f\n", eve, eve->xy[0], eve->xy[1]); } for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) { printf("edge: %x verts: %x %x\n", eed, eed->v1, eed->v2); } #endif /* STEP 0: remove zero sized edges */ if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) { for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) { if (equals_v2v2(eed->v1->xy, eed->v2->xy)) { if (eed->v1->f == SF_VERT_ZERO_LEN && eed->v2->f != SF_VERT_ZERO_LEN) { eed->v2->f = SF_VERT_ZERO_LEN; eed->v2->tmp.v = eed->v1->tmp.v; } else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f != SF_VERT_ZERO_LEN) { eed->v1->f = SF_VERT_ZERO_LEN; eed->v1->tmp.v = eed->v2->tmp.v; } else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f == SF_VERT_ZERO_LEN) { eed->v1->tmp.v = eed->v2->tmp.v; } else { eed->v2->f = SF_VERT_ZERO_LEN; eed->v2->tmp.v = eed->v1; } } } } /* STEP 1: make using FillVert and FillEdge lists a sorted * ScanFillVertLink list */ sc = scdata = MEM_mallocN(sizeof(*scdata) * pf->verts, "Scanfill1"); verts = 0; for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) { if (eve->poly_nr == nr) { if (eve->f != SF_VERT_ZERO_LEN) { verts++; eve->f = SF_VERT_NEW; /* flag for connectedges later on */ sc->vert = eve; sc->edge_first = sc->edge_last = NULL; /* if (even->tmp.v == NULL) eve->tmp.u = verts; */ /* Note, debug print only will work for curve polyfill, union is in use for mesh */ sc++; } } } qsort(scdata, verts, sizeof(ScanFillVertLink), vergscdata); if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) { for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) { eed_next = eed->next; BLI_remlink(&sf_ctx->filledgebase, eed); /* This code is for handling zero-length edges that get * collapsed in step 0. It was removed for some time to * fix trunk bug #4544, so if that comes back, this code * may need some work, or there will have to be a better * fix to #4544. * * warning, this can hang on un-ordered edges, see: [#33281] * for now disable 'BLI_SCANFILL_CALC_REMOVE_DOUBLES' for ngons. */ if (eed->v1->f == SF_VERT_ZERO_LEN) { v1 = eed->v1; while ((eed->v1->f == SF_VERT_ZERO_LEN) && (eed->v1->tmp.v != v1) && (eed->v1 != eed->v1->tmp.v)) eed->v1 = eed->v1->tmp.v; } if (eed->v2->f == SF_VERT_ZERO_LEN) { v2 = eed->v2; while ((eed->v2->f == SF_VERT_ZERO_LEN) && (eed->v2->tmp.v != v2) && (eed->v2 != eed->v2->tmp.v)) eed->v2 = eed->v2->tmp.v; } if (eed->v1 != eed->v2) { addedgetoscanlist(scdata, eed, verts); } } } else { for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) { eed_next = eed->next; BLI_remlink(&sf_ctx->filledgebase, eed); if (eed->v1 != eed->v2) { addedgetoscanlist(scdata, eed, verts); } } } #if 0 sc = sf_ctx->_scdata; for (a = 0; a < verts; a++) { printf("\nscvert: %x\n", sc->vert); for (eed = sc->edge_first; eed; eed = eed->next) { printf(" ed %x %x %x\n", eed, eed->v1, eed->v2); } sc++; } #endif /* STEP 2: FILL LOOP */ if (pf->f == SF_POLY_NEW) twoconnected = true; /* (temporal) security: never much more faces than vertices */ totface = 0; 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 = scdata; for (a = 0; a < verts; a++) { /* printf("VERTEX %d index %d\n", a, sc->vert->tmp.u); */ /* set connectflags */ for (ed1 = sc->edge_first; ed1; ed1 = eed_next) { eed_next = ed1->next; if (ed1->v1->edge_tot == 1 || ed1->v2->edge_tot == 1) { BLI_remlink((ListBase *)&(sc->edge_first), ed1); BLI_addtail(&sf_ctx->filledgebase, ed1); if (ed1->v1->edge_tot > 1) ed1->v1->edge_tot--; if (ed1->v2->edge_tot > 1) ed1->v2->edge_tot--; } else { ed1->v2->f = SF_VERT_AVAILABLE; } } while (sc->edge_first) { /* for as long there are edges */ ed1 = sc->edge_first; ed2 = ed1->next; /* commented out... the ESC here delivers corrupted memory (and doesnt work during grab) */ /* if (callLocalInterruptCallBack()) break; */ if (totface >= maxface) { /* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */ a = verts; break; } if (ed2 == NULL) { sc->edge_first = sc->edge_last = NULL; /* printf("just 1 edge to vert\n"); */ BLI_addtail(&sf_ctx->filledgebase, ed1); ed1->v2->f = SF_VERT_NEW; ed1->v1->edge_tot--; ed1->v2->edge_tot--; } else { /* test rest of vertices */ ScanFillVertLink *best_sc = NULL; float best_angle = 3.14f; float miny; bool firsttime = false; v1 = ed1->v2; v2 = ed1->v1; v3 = ed2->v2; /* this happens with a serial of overlapping edges */ if (v1 == v2 || v2 == v3) break; /* printf("test verts %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */ miny = min_ff(v1->xy[1], v3->xy[1]); sc1 = sc + 1; for (b = a + 1; b < verts; b++, sc1++) { if (sc1->vert->f == SF_VERT_NEW) { 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(v3->xy, v1->xy, sc1->vert->xy)) { /* point is in triangle */ /* because multiple points can be inside triangle (concave holes) */ /* we continue searching and pick the one with sharpest corner */ if (best_sc == NULL) { /* even without holes we need to keep checking [#35861] */ best_sc = sc1; } else { float angle; /* prevent angle calc for the simple cases only 1 vertex is found */ if (firsttime == false) { best_angle = angle_v2v2v2(v2->xy, v1->xy, best_sc->vert->xy); firsttime = true; } angle = angle_v2v2v2(v2->xy, v1->xy, sc1->vert->xy); if (angle < best_angle) { best_sc = sc1; best_angle = angle; } } } } } } } if (best_sc) { /* make new edge, and start over */ /* printf("add new edge %d %d and start again\n", v2->tmp.u, best_sc->vert->tmp.u); */ ed3 = BLI_scanfill_edge_add(sf_ctx, v2, best_sc->vert); BLI_remlink(&sf_ctx->filledgebase, ed3); BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed2, ed3); ed3->v2->f = SF_VERT_AVAILABLE; ed3->f = SF_EDGE_INTERNAL; ed3->v1->edge_tot++; ed3->v2->edge_tot++; } else { /* new triangle */ /* printf("add face %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */ addfillface(sf_ctx, v1, v2, v3); totface++; BLI_remlink((ListBase *)&(sc->edge_first), ed1); BLI_addtail(&sf_ctx->filledgebase, ed1); ed1->v2->f = SF_VERT_NEW; ed1->v1->edge_tot--; ed1->v2->edge_tot--; /* ed2 can be removed when it's a boundary edge */ if (((ed2->f == SF_EDGE_NEW) && twoconnected) /* || (ed2->f == SF_EDGE_BOUNDARY) */) { BLI_remlink((ListBase *)&(sc->edge_first), ed2); BLI_addtail(&sf_ctx->filledgebase, ed2); ed2->v2->f = SF_VERT_NEW; ed2->v1->edge_tot--; ed2->v2->edge_tot--; } /* new edge */ ed3 = BLI_scanfill_edge_add(sf_ctx, v1, v3); BLI_remlink(&sf_ctx->filledgebase, ed3); ed3->f = SF_EDGE_INTERNAL; ed3->v1->edge_tot++; ed3->v2->edge_tot++; /* printf("add new edge %x %x\n", v1, v3); */ sc1 = addedgetoscanlist(scdata, ed3, verts); if (sc1) { /* ed3 already exists: remove if a boundary */ /* printf("Edge exists\n"); */ ed3->v1->edge_tot--; ed3->v2->edge_tot--; for (ed3 = sc1->edge_first; ed3; ed3 = ed3->next) { if ((ed3->v1 == v1 && ed3->v2 == v3) || (ed3->v1 == v3 && ed3->v2 == v1)) { if (twoconnected /* || (ed3->f == SF_EDGE_BOUNDARY) */) { BLI_remlink((ListBase *)&(sc1->edge_first), ed3); BLI_addtail(&sf_ctx->filledgebase, ed3); ed3->v1->edge_tot--; ed3->v2->edge_tot--; } break; } } } } } /* test for loose edges */ for (ed1 = sc->edge_first; ed1; ed1 = eed_next) { eed_next = ed1->next; if (ed1->v1->edge_tot < 2 || ed1->v2->edge_tot < 2) { BLI_remlink((ListBase *)&(sc->edge_first), ed1); BLI_addtail(&sf_ctx->filledgebase, ed1); if (ed1->v1->edge_tot > 1) ed1->v1->edge_tot--; if (ed1->v2->edge_tot > 1) ed1->v2->edge_tot--; } } /* done with loose edges */ } sc++; } MEM_freeN(scdata); BLI_assert(totface <= maxface); return totface; }
static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf) { ScanFillVertLink *sc = NULL, *sc1; ScanFillVert *eve, *v1, *v2, *v3; ScanFillEdge *eed, *nexted, *ed1, *ed2, *ed3; int a, b, verts, maxface, totface; short nr, test, twoconnected = 0; nr = pf->nr; /* PRINTS */ #if 0 verts = pf->verts; eve = sf_ctx->fillvertbase.first; while (eve) { printf("vert: %x co: %f %f\n", eve, eve->xy[0], eve->xy[1]); eve = eve->next; } eed = sf_ctx->filledgebase.first; while (eed) { printf("edge: %x verts: %x %x\n", eed, eed->v1, eed->v2); eed = eed->next; } #endif /* STEP 0: remove zero sized edges */ eed = sf_ctx->filledgebase.first; while (eed) { if (equals_v2v2(eed->v1->xy, eed->v2->xy)) { if (eed->v1->f == SF_VERT_ZERO_LEN && eed->v2->f != SF_VERT_ZERO_LEN) { eed->v2->f = SF_VERT_ZERO_LEN; eed->v2->tmp.v = eed->v1->tmp.v; } else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f != SF_VERT_ZERO_LEN) { eed->v1->f = SF_VERT_ZERO_LEN; eed->v1->tmp.v = eed->v2->tmp.v; } else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f == SF_VERT_ZERO_LEN) { eed->v1->tmp.v = eed->v2->tmp.v; } else { eed->v2->f = SF_VERT_ZERO_LEN; eed->v2->tmp.v = eed->v1; } } eed = eed->next; } /* STEP 1: make using FillVert and FillEdge lists a sorted * ScanFillVertLink list */ sc = sf_ctx->_scdata = (ScanFillVertLink *)MEM_callocN(pf->verts * sizeof(ScanFillVertLink), "Scanfill1"); eve = sf_ctx->fillvertbase.first; verts = 0; while (eve) { if (eve->poly_nr == nr) { if (eve->f != SF_VERT_ZERO_LEN) { verts++; eve->f = 0; /* flag for connectedges later on */ sc->v1 = eve; sc++; } } eve = eve->next; } qsort(sf_ctx->_scdata, verts, sizeof(ScanFillVertLink), vergscdata); eed = sf_ctx->filledgebase.first; while (eed) { nexted = eed->next; BLI_remlink(&sf_ctx->filledgebase, eed); /* This code is for handling zero-length edges that get * collapsed in step 0. It was removed for some time to * fix trunk bug #4544, so if that comes back, this code * may need some work, or there will have to be a better * fix to #4544. */ if (eed->v1->f == SF_VERT_ZERO_LEN) { v1 = eed->v1; while ((eed->v1->f == SF_VERT_ZERO_LEN) && (eed->v1->tmp.v != v1) && (eed->v1 != eed->v1->tmp.v)) eed->v1 = eed->v1->tmp.v; } if (eed->v2->f == SF_VERT_ZERO_LEN) { v2 = eed->v2; while ((eed->v2->f == SF_VERT_ZERO_LEN) && (eed->v2->tmp.v != v2) && (eed->v2 != eed->v2->tmp.v)) eed->v2 = eed->v2->tmp.v; } if (eed->v1 != eed->v2) addedgetoscanlist(sf_ctx, eed, verts); eed = nexted; } #if 0 sc = scdata; for (a = 0; a < verts; a++) { printf("\nscvert: %x\n", sc->v1); eed = sc->first; while (eed) { printf(" ed %x %x %x\n", eed, eed->v1, eed->v2); eed = eed->next; } sc++; } #endif /* STEP 2: FILL LOOP */ if (pf->f == 0) twoconnected = 1; /* (temporal) security: never much more faces than vertices */ totface = 0; maxface = 2 * verts; /* 2*verts: based at a filled circle within a triangle */ sc = sf_ctx->_scdata; for (a = 0; a < verts; a++) { /* printf("VERTEX %d %x\n",a,sc->v1); */ ed1 = sc->first; while (ed1) { /* set connectflags */ nexted = ed1->next; if (ed1->v1->h == 1 || ed1->v2->h == 1) { BLI_remlink((ListBase *)&(sc->first), ed1); BLI_addtail(&sf_ctx->filledgebase, ed1); if (ed1->v1->h > 1) ed1->v1->h--; if (ed1->v2->h > 1) ed1->v2->h--; } else ed1->v2->f = SF_VERT_UNKNOWN; ed1 = nexted; } while (sc->first) { /* for as long there are edges */ ed1 = sc->first; ed2 = ed1->next; /* commented out... the ESC here delivers corrupted memory (and doesnt work during grab) */ /* if (callLocalInterruptCallBack()) break; */ if (totface > maxface) { /* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */ a = verts; break; } if (ed2 == 0) { sc->first = sc->last = NULL; /* printf("just 1 edge to vert\n"); */ BLI_addtail(&sf_ctx->filledgebase, ed1); ed1->v2->f = 0; ed1->v1->h--; ed1->v2->h--; } else { /* test rest of vertices */ float miny; v1 = ed1->v2; v2 = ed1->v1; 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); */ miny = minf(v1->xy[1], v3->xy[1]); /* miny= MIN2(v1->xy[1],v3->xy[1]); */ sc1 = sc + 1; test = 0; for (b = a + 1; b < verts; b++) { if (sc1->v1->f == 0) { if (sc1->v1->xy[1] <= miny) break; if (testedgeside(v1->xy, v2->xy, sc1->v1->xy)) if (testedgeside(v2->xy, v3->xy, sc1->v1->xy)) if (testedgeside(v3->xy, v1->xy, sc1->v1->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->v1); */ ed3 = BLI_addfilledge(sf_ctx, v2, sc1->v1); BLI_remlink(&sf_ctx->filledgebase, ed3); BLI_insertlinkbefore((ListBase *)&(sc->first), ed2, ed3); ed3->v2->f = SF_VERT_UNKNOWN; ed3->f = SF_EDGE_UNKNOWN; ed3->v1->h++; ed3->v2->h++; } else { /* new triangle */ /* printf("add face %x %x %x\n",v1,v2,v3); */ addfillface(sf_ctx, v1, v2, v3); totface++; BLI_remlink((ListBase *)&(sc->first), ed1); BLI_addtail(&sf_ctx->filledgebase, ed1); ed1->v2->f = 0; ed1->v1->h--; ed1->v2->h--; /* ed2 can be removed when it's a boundary edge */ if ((ed2->f == 0 && twoconnected) || (ed2->f == SF_EDGE_BOUNDARY)) { BLI_remlink((ListBase *)&(sc->first), ed2); BLI_addtail(&sf_ctx->filledgebase, ed2); ed2->v2->f = 0; ed2->v1->h--; ed2->v2->h--; } /* new edge */ ed3 = BLI_addfilledge(sf_ctx, v1, v3); BLI_remlink(&sf_ctx->filledgebase, ed3); ed3->f = SF_EDGE_UNKNOWN; ed3->v1->h++; ed3->v2->h++; /* printf("add new edge %x %x\n",v1,v3); */ sc1 = addedgetoscanlist(sf_ctx, ed3, verts); if (sc1) { /* ed3 already exists: remove if a boundary */ /* printf("Edge exists\n"); */ ed3->v1->h--; ed3->v2->h--; ed3 = sc1->first; while (ed3) { if ( (ed3->v1 == v1 && ed3->v2 == v3) || (ed3->v1 == v3 && ed3->v2 == v1) ) { if (twoconnected || ed3->f == SF_EDGE_BOUNDARY) { BLI_remlink((ListBase *)&(sc1->first), ed3); BLI_addtail(&sf_ctx->filledgebase, ed3); ed3->v1->h--; ed3->v2->h--; } break; } ed3 = ed3->next; } } } } /* test for loose edges */ ed1 = sc->first; while (ed1) { nexted = ed1->next; if (ed1->v1->h < 2 || ed1->v2->h < 2) { BLI_remlink((ListBase *)&(sc->first), ed1); BLI_addtail(&sf_ctx->filledgebase, ed1); if (ed1->v1->h > 1) ed1->v1->h--; if (ed1->v2->h > 1) ed1->v2->h--; } ed1 = nexted; } } sc++; } MEM_freeN(sf_ctx->_scdata); sf_ctx->_scdata = NULL; return totface; }