fix/workaround [#33281] script goes into not responding
scanfill remove-doubles pass assumes ordered edges (as with curves), otherwise it can hang. workaround this problem by skipping removing-doubles for mesh ngons, since this isnt such a common case as it is with curves and we can just not support it.
This commit is contained in:
parent
ceed3ef640
commit
f9e339ef00
|
@ -487,7 +487,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, int flipnormal)
|
|||
}
|
||||
|
||||
/* XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) { */
|
||||
if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, FALSE))) {
|
||||
if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES))) {
|
||||
if (tot) {
|
||||
dlnew = MEM_callocN(sizeof(DispList), "filldisplist");
|
||||
dlnew->type = DL_INDEX3;
|
||||
|
|
|
@ -215,7 +215,7 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
|
|||
/* complete the loop */
|
||||
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
|
||||
|
||||
totfilltri = BLI_scanfill_calc_ex(&sf_ctx, FALSE, efa->no);
|
||||
totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no);
|
||||
BLI_array_grow_items(looptris, totfilltri);
|
||||
|
||||
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
|
||||
|
|
|
@ -933,7 +933,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
|
|||
}
|
||||
|
||||
/* main scan-fill */
|
||||
sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, FALSE, zvec);
|
||||
sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, 0, zvec);
|
||||
|
||||
face_array = MEM_mallocN(sizeof(*face_array) * (sf_tri_tot + tot_feather_quads), "maskrast_face_index");
|
||||
face_index = 0;
|
||||
|
|
|
@ -2607,7 +2607,7 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
|
|||
}
|
||||
BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert_first);
|
||||
|
||||
totfilltri = BLI_scanfill_calc(&sf_ctx, FALSE);
|
||||
totfilltri = BLI_scanfill_calc(&sf_ctx, 0);
|
||||
if (totfilltri) {
|
||||
BLI_array_grow_items(mface_to_poly_map, totfilltri);
|
||||
BLI_array_grow_items(mface, totfilltri);
|
||||
|
|
|
@ -94,9 +94,18 @@ typedef struct ScanFillFace {
|
|||
struct ScanFillVert *BLI_scanfill_vert_add(ScanFillContext *sf_ctx, const float vec[3]);
|
||||
struct ScanFillEdge *BLI_scanfill_edge_add(ScanFillContext *sf_ctx, struct ScanFillVert *v1, struct ScanFillVert *v2);
|
||||
|
||||
enum {
|
||||
BLI_SCANFILL_CALC_QUADTRI_FASTPATH = (1 << 0),
|
||||
|
||||
/* note: using BLI_SCANFILL_CALC_REMOVE_DOUBLES
|
||||
* Assumes ordered edges, otherwise we risk an eternal loop
|
||||
* removing double verts. - campbell */
|
||||
BLI_SCANFILL_CALC_REMOVE_DOUBLES = (1 << 1),
|
||||
};
|
||||
|
||||
int BLI_scanfill_begin(ScanFillContext *sf_ctx);
|
||||
int BLI_scanfill_calc(ScanFillContext *sf_ctx, const short do_quad_tri_speedup);
|
||||
int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedup,
|
||||
int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag);
|
||||
int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag,
|
||||
const float nor_proj[3]);
|
||||
void BLI_scanfill_end(ScanFillContext *sf_ctx);
|
||||
|
||||
|
|
|
@ -503,8 +503,7 @@ static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *tempe
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf)
|
||||
static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
|
||||
{
|
||||
ScanFillVertLink *sc = NULL, *sc1;
|
||||
ScanFillVert *eve, *v1, *v2, *v3;
|
||||
|
@ -530,6 +529,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf)
|
|||
#endif
|
||||
|
||||
/* STEP 0: remove zero sized edges */
|
||||
if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) {
|
||||
eed = sf_ctx->filledgebase.first;
|
||||
while (eed) {
|
||||
if (equals_v2v2(eed->v1->xy, eed->v2->xy)) {
|
||||
|
@ -551,6 +551,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf)
|
|||
}
|
||||
eed = eed->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* STEP 1: make using FillVert and FillEdge lists a sorted
|
||||
* ScanFillVertLink list
|
||||
|
@ -572,15 +573,19 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf)
|
|||
|
||||
qsort(sf_ctx->_scdata, verts, sizeof(ScanFillVertLink), vergscdata);
|
||||
|
||||
eed = sf_ctx->filledgebase.first;
|
||||
while (eed) {
|
||||
if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) {
|
||||
for (eed = sf_ctx->filledgebase.first; eed; eed = nexted) {
|
||||
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. */
|
||||
* 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))
|
||||
|
@ -591,9 +596,19 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf)
|
|||
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 (eed->v1 != eed->v2) {
|
||||
addedgetoscanlist(sf_ctx, eed, verts);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (eed = sf_ctx->filledgebase.first; eed; eed = nexted) {
|
||||
nexted = eed->next;
|
||||
BLI_remlink(&sf_ctx->filledgebase, eed);
|
||||
if (eed->v1 != eed->v2) {
|
||||
addedgetoscanlist(sf_ctx, eed, verts);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
sc = scdata;
|
||||
|
@ -775,12 +790,12 @@ int BLI_scanfill_begin(ScanFillContext *sf_ctx)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int BLI_scanfill_calc(ScanFillContext *sf_ctx, const short do_quad_tri_speedup)
|
||||
int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag)
|
||||
{
|
||||
return BLI_scanfill_calc_ex(sf_ctx, do_quad_tri_speedup, NULL);
|
||||
return BLI_scanfill_calc_ex(sf_ctx, flag, NULL);
|
||||
}
|
||||
|
||||
int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedup, const float nor_proj[3])
|
||||
int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3])
|
||||
{
|
||||
/*
|
||||
* - fill works with its own lists, so create that first (no faces!)
|
||||
|
@ -810,13 +825,14 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedu
|
|||
a += 1;
|
||||
}
|
||||
|
||||
if (do_quad_tri_speedup && (a == 3)) {
|
||||
if (flag & BLI_SCANFILL_CALC_QUADTRI_FASTPATH) {
|
||||
if (a == 3) {
|
||||
eve = sf_ctx->fillvertbase.first;
|
||||
|
||||
addfillface(sf_ctx, eve, eve->next, eve->next->next);
|
||||
return 1;
|
||||
}
|
||||
else if (do_quad_tri_speedup && (a == 4)) {
|
||||
else if (a == 4) {
|
||||
float vec1[3], vec2[3];
|
||||
|
||||
eve = sf_ctx->fillvertbase.first;
|
||||
|
@ -835,6 +851,7 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedu
|
|||
}
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* first test vertices if they are in edges */
|
||||
/* including resetting of flags */
|
||||
|
@ -1091,7 +1108,7 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const short do_quad_tri_speedu
|
|||
for (a = 0; a < poly; a++) {
|
||||
if (pf->edges > 1) {
|
||||
splitlist(sf_ctx, &tempve, &temped, pf->nr);
|
||||
totfaces += scanfill(sf_ctx, pf);
|
||||
totfaces += scanfill(sf_ctx, pf, flag);
|
||||
}
|
||||
pf++;
|
||||
}
|
||||
|
|
|
@ -190,7 +190,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
|
|||
/* sf_edge->tmp.p = e; */ /* UNUSED */
|
||||
}
|
||||
|
||||
BLI_scanfill_calc(&sf_ctx, FALSE);
|
||||
BLI_scanfill_calc(&sf_ctx, 0);
|
||||
|
||||
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
|
||||
BMFace *f = BM_face_create_quad_tri(bm,
|
||||
|
|
|
@ -306,7 +306,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
|
|||
|
||||
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
|
||||
|
||||
BLI_scanfill_calc_ex(&sf_ctx, TRUE, efa->no);
|
||||
BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no);
|
||||
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
|
||||
int i;
|
||||
ls[0] = sf_tri->v1->tmp.p;
|
||||
|
|
|
@ -255,7 +255,7 @@ static void draw_filled_lasso(wmGesture *gt)
|
|||
if (sf_vert_first) {
|
||||
const float zvec[3] = {0.0f, 0.0f, 1.0f};
|
||||
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
|
||||
BLI_scanfill_calc_ex(&sf_ctx, FALSE, zvec);
|
||||
BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES, zvec);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glColor4f(1.0, 1.0, 1.0, 0.05);
|
||||
|
|
Loading…
Reference in New Issue