From 098cf9095675b46ea9860aab2014495b3a8a2af8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 1 Sep 2013 03:37:45 +0000 Subject: [PATCH] use strict flags for scanfill, also replace shorts with unsigned shorts and ints/bools in some cases. --- source/blender/blenlib/BLI_scanfill.h | 8 +- source/blender/blenlib/intern/scanfill.c | 126 ++++++++++++----------- 2 files changed, 70 insertions(+), 64 deletions(-) diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h index 40658095fd9..e7d2130e473 100644 --- a/source/blender/blenlib/BLI_scanfill.h +++ b/source/blender/blenlib/BLI_scanfill.h @@ -64,7 +64,7 @@ typedef struct ScanFillVert { float co[3]; /* vertex location */ float xy[2]; /* 2D projection of vertex location */ unsigned int keyindex; /* index, caller can use how it likes to match the scanfill result with own data */ - short poly_nr; + unsigned short poly_nr; unsigned char edge_tot; /* number of edges using this vertex */ unsigned char f; } ScanFillVert; @@ -72,7 +72,7 @@ typedef struct ScanFillVert { typedef struct ScanFillEdge { struct ScanFillEdge *next, *prev; struct ScanFillVert *v1, *v2; - short poly_nr; + unsigned short poly_nr; unsigned char f; union { unsigned char c; @@ -101,8 +101,8 @@ enum { BLI_SCANFILL_CALC_HOLES = (1 << 2) }; void BLI_scanfill_begin(ScanFillContext *sf_ctx); -int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag); -int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, +unsigned int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag); +unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3]); void BLI_scanfill_end(ScanFillContext *sf_ctx); diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index 39d1378afdd..a292c2275c9 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -41,14 +41,16 @@ #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_memarena.h" -#include "BLI_scanfill.h" #include "BLI_utildefines.h" +#include "BLI_strict_flags.h" + +#include "BLI_scanfill.h" /* own include */ /* local types */ typedef struct PolyFill { - int edges, verts; + unsigned int edges, verts; float min_xy[2], max_xy[2]; - short f, nr; + unsigned short f, nr; } PolyFill; typedef struct ScanFillVertLink { @@ -152,7 +154,7 @@ static void addfillface(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert sf_tri->v3 = v3; } -static int boundisect(PolyFill *pf2, PolyFill *pf1) +static bool boundisect(PolyFill *pf2, PolyFill *pf1) { /* has pf2 been touched (intersected) by pf1 ? with bounding box */ /* test first if polys exist */ @@ -199,7 +201,7 @@ static void mergepolysSimp(ScanFillContext *sf_ctx, PolyFill *pf1, PolyFill *pf2 pf1->f = (pf1->f | pf2->f); } -static short testedgeside(const float v1[2], const float v2[2], const float v3[2]) +static bool testedgeside(const float v1[2], const float v2[2], const float v3[2]) /* is v3 to the right of v1-v2 ? With exception: v3 == v1 || v3 == v2 */ { float inp; @@ -210,14 +212,14 @@ static short testedgeside(const float v1[2], const float v2[2], const float v3[2 if (inp < 0.0f) { return 0; } - else if (inp == 0) { + else if (inp == 0.0f) { if (v1[0] == v3[0] && v1[1] == v3[1]) return 0; if (v2[0] == v3[0] && v2[1] == v3[1]) return 0; } return 1; } -static short addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed) +static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed) { /* find first edge to the right of eed, and insert eed before that */ ScanFillEdge *ed; @@ -266,7 +268,7 @@ static short addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed) } -static ScanFillVertLink *addedgetoscanlist(ScanFillContext *sf_ctx, ScanFillEdge *eed, int len) +static ScanFillVertLink *addedgetoscanlist(ScanFillContext *sf_ctx, ScanFillEdge *eed, unsigned int len) { /* inserts edge at correct location in ScanFillVertLink list */ /* returns sc when edge already exists */ @@ -291,13 +293,17 @@ static ScanFillVertLink *addedgetoscanlist(ScanFillContext *sf_ctx, ScanFillEdge sc = (ScanFillVertLink *)bsearch(&scsearch, sf_ctx->_scdata, len, sizeof(ScanFillVertLink), vergscdata); - if (sc == NULL) printf("Error in search edge: %p\n", (void *)eed); - else if (addedgetoscanvert(sc, eed) == 0) return sc; + if (UNLIKELY(sc == NULL)) { + printf("Error in search edge: %p\n", (void *)eed); + } + else if (addedgetoscanvert(sc, eed) == false) { + return sc; + } return NULL; } -static short boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve) +static bool boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve) /* is eve inside boundbox eed */ { float minx, maxx, miny, maxy; @@ -388,7 +394,7 @@ static void testvertexnearedge(ScanFillContext *sf_ctx) } } -static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *temped, short nr) +static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *temped, unsigned short nr) { /* everything is in templist, write only poly nr to fillist */ ScanFillVert *eve, *nextve; @@ -417,15 +423,14 @@ static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *tempe } } -static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) +static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) { ScanFillVertLink *sc = NULL, *sc1; ScanFillVert *eve, *v1, *v2, *v3; ScanFillEdge *eed, *nexted, *ed1, *ed2, *ed3; - int a, b, verts, maxface, totface; - short nr, twoconnected = 0; - - nr = pf->nr; + unsigned int a, b, verts, maxface, totface; + const unsigned short nr = pf->nr; + bool twoconnected = false; /* PRINTS */ #if 0 @@ -541,7 +546,8 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) /* STEP 2: FILL LOOP */ - if (pf->f == 0) twoconnected = 1; + if (pf->f == 0) + twoconnected = true; /* (temporal) security: never much more faces than vertices */ totface = 0; @@ -767,7 +773,7 @@ void BLI_scanfill_end_arena(ScanFillContext *sf_ctx, MemArena *arena) sf_ctx->fillfacebase.first = sf_ctx->fillfacebase.last = NULL; } -int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3]) +unsigned 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!) @@ -779,34 +785,36 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no */ ListBase tempve, temped; ScanFillVert *eve; - ScanFillEdge *eed, *nexted; + ScanFillEdge *eed, *eed_next; PolyFill *pflist, *pf; float *min_xy_p, *max_xy_p; - short a, c, poly = 0, ok = 0, toggle = 0; - int totfaces = 0; /* total faces added */ + unsigned int totverts = 0, toggle = 0; + unsigned int totfaces = 0; /* total faces added */ + unsigned short a, c, poly = 0; + bool ok; float mat_2d[3][3]; BLI_assert(!nor_proj || len_squared_v3(nor_proj) > FLT_EPSILON); - /* reset variables */ eve = sf_ctx->fillvertbase.first; - a = 0; while (eve) { - eve->f = 0; - eve->poly_nr = 0; - eve->edge_tot = 0; + /* these values used to be set, + * however they should always be zero'd so check instead */ + BLI_assert(eve->f == 0); + BLI_assert(eve->poly_nr == 0); + BLI_assert(eve->edge_tot == 0); + totverts++; eve = eve->next; - a += 1; } if (flag & BLI_SCANFILL_CALC_QUADTRI_FASTPATH) { - if (a == 3) { + if (totverts == 3) { eve = sf_ctx->fillvertbase.first; addfillface(sf_ctx, eve, eve->next, eve->next->next); return 1; } - else if (a == 4) { + else if (totverts == 4) { float vec1[3], vec2[3]; eve = sf_ctx->fillvertbase.first; @@ -831,23 +839,24 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no /* including resetting of flags */ eed = sf_ctx->filledgebase.first; while (eed) { - eed->poly_nr = 0; + BLI_assert(eed->poly_nr == 0); eed->v1->f = SF_VERT_AVAILABLE; eed->v2->f = SF_VERT_AVAILABLE; eed = eed->next; } + ok = false; eve = sf_ctx->fillvertbase.first; while (eve) { if (eve->f & SF_VERT_AVAILABLE) { - ok = 1; + ok = true; break; } eve = eve->next; } - if (ok == 0) { + if (UNLIKELY(ok == false)) { return 0; } else { @@ -893,35 +902,33 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no if (eve->poly_nr == 0) { poly++; /* now a sort of select connected */ - ok = 1; + ok = true; eve->poly_nr = poly; while (ok) { - ok = 0; - toggle++; - if (toggle & 1) eed = sf_ctx->filledgebase.first; - else eed = sf_ctx->filledgebase.last; + ok = false; + toggle++; + eed = (toggle & 1) ? sf_ctx->filledgebase.first : 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; + ok = true; } else if (eed->v2->poly_nr == 0 && eed->v1->poly_nr == poly) { eed->v2->poly_nr = poly; eed->poly_nr = poly; - ok = 1; + ok = true; } else if (eed->poly_nr == 0) { if (eed->v1->poly_nr == poly && eed->v2->poly_nr == poly) { eed->poly_nr = poly; - ok = 1; + ok = true; } } - if (toggle & 1) eed = eed->next; - else eed = eed->prev; + eed = (toggle & 1) ? eed->next : eed->prev; } } } @@ -963,28 +970,27 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no /* does it only for vertices with (->h == 1) */ testvertexnearedge(sf_ctx); - ok = 1; + ok = true; while (ok) { - ok = 0; + ok = false; + toggle++; - if (toggle & 1) eed = sf_ctx->filledgebase.first; - else eed = sf_ctx->filledgebase.last; + eed = (toggle & 1) ? sf_ctx->filledgebase.first : sf_ctx->filledgebase.last; while (eed) { - if (toggle & 1) nexted = eed->next; - else nexted = eed->prev; + eed_next = (toggle & 1) ? eed->next : eed->prev; if (eed->v1->edge_tot == 1) { eed->v2->edge_tot--; BLI_remlink(&sf_ctx->fillvertbase, eed->v1); BLI_remlink(&sf_ctx->filledgebase, eed); - ok = 1; + ok = true; } else if (eed->v2->edge_tot == 1) { eed->v1->edge_tot--; BLI_remlink(&sf_ctx->fillvertbase, eed->v2); BLI_remlink(&sf_ctx->filledgebase, eed); - ok = 1; + ok = true; } - eed = nexted; + eed = eed_next; } } if (sf_ctx->filledgebase.first == NULL) { @@ -1005,12 +1011,12 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no /* STEP 3: MAKE POLYFILL STRUCT */ - pflist = (PolyFill *)MEM_callocN(poly * sizeof(PolyFill), "edgefill"); + pflist = (PolyFill *)MEM_callocN((size_t)poly * sizeof(PolyFill), "edgefill"); pf = pflist; for (a = 1; a <= poly; a++) { pf->nr = a; - pf->min_xy[0] = pf->min_xy[1] = 1.0e20; - pf->max_xy[0] = pf->max_xy[1] = -1.0e20; + pf->min_xy[0] = pf->min_xy[1] = 1.0e20f; + pf->max_xy[0] = pf->max_xy[1] = -1.0e20f; pf++; } eed = sf_ctx->filledgebase.first; @@ -1040,10 +1046,10 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no * WATCH IT: ONLY WORKS WITH SORTED POLYS!!! */ if (poly > 1) { - short *polycache, *pc; + unsigned short *polycache, *pc; /* so, sort first */ - qsort(pflist, poly, sizeof(PolyFill), vergpoly); + qsort(pflist, (size_t)poly, sizeof(PolyFill), vergpoly); #if 0 pf = pflist; @@ -1054,10 +1060,10 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no } #endif - polycache = pc = MEM_callocN(sizeof(short) * poly, "polycache"); + polycache = pc = MEM_callocN(sizeof(short) * (size_t)poly, "polycache"); pf = pflist; for (a = 0; a < poly; a++, pf++) { - for (c = a + 1; c < poly; c++) { + for (c = (unsigned short)(a + 1); c < poly; c++) { /* if 'a' inside 'c': join (bbox too) * Careful: 'a' can also be inside another poly. @@ -1114,7 +1120,7 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no return totfaces; } -int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag) +unsigned int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag) { return BLI_scanfill_calc_ex(sf_ctx, flag, NULL); }