make scanfill threadsafe (wasnt threadsafe before BMesh merge but before the merge...
authorCampbell Barton <ideasman42@gmail.com>
Mon, 16 Apr 2012 06:48:57 +0000 (06:48 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 16 Apr 2012 06:48:57 +0000 (06:48 +0000)
13 files changed:
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/editderivedmesh.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenlib/BLI_scanfill.h
source/blender/blenlib/BLI_threads.h
source/blender/blenlib/intern/scanfill.c
source/blender/blenlib/intern/threads.c
source/blender/bmesh/operators/bmo_triangulate.c
source/blender/editors/mesh/editmesh_knife.c
source/blender/editors/uvedit/uvedit_unwrap_ops.c
source/blender/windowmanager/intern/wm_gesture.c
source/blender/windowmanager/intern/wm_init_exit.c
source/creator/creator.c

index cefc0fba9cd79aa3ad2e8c315aa29b0c7eb1d0fa..01d5d6ef2adbd4d1044ac8bf1cf776fce174f08b 100644 (file)
@@ -416,6 +416,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, i
 
 void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
 {
+       ScanFillContext sf_ctx;
        ScanFillVert *eve, *v1, *vlast;
        ScanFillFace *efa;
        DispList *dlnew=NULL, *dl;
@@ -431,7 +432,7 @@ void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
                totvert= 0;
                nextcol= 0;
                
-               BLI_begin_edgefill();
+               BLI_begin_edgefill(&sf_ctx);
                
                dl= dispbase->first;
                while (dl) {
@@ -448,18 +449,18 @@ void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
                                                while (a--) {
                                                        vlast= eve;
 
-                                                       eve= BLI_addfillvert(f1);
+                                                       eve = BLI_addfillvert(&sf_ctx, f1);
                                                        totvert++;
 
                                                        if (vlast==NULL) v1= eve;
                                                        else {
-                                                               BLI_addfilledge(vlast, eve);
+                                                               BLI_addfilledge(&sf_ctx, vlast, eve);
                                                        }
                                                        f1+=3;
                                                }
 
                                                if (eve!=NULL && v1!=NULL) {
-                                                       BLI_addfilledge(eve, v1);
+                                                       BLI_addfilledge(&sf_ctx, eve, v1);
                                                }
                                        }
                                        else if (colnr<dl->col) {
@@ -472,7 +473,7 @@ void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
                        dl= dl->next;
                }
                
-               if (totvert && (tot= BLI_edgefill(FALSE))) { // XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) {
+               if (totvert && (tot= BLI_edgefill(&sf_ctx, FALSE))) { // XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) {
                        if (tot) {
                                dlnew= MEM_callocN(sizeof(DispList), "filldisplist");
                                dlnew->type= DL_INDEX3;
@@ -486,7 +487,7 @@ void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
                                /* vert data */
                                f1= dlnew->verts;
                                totvert= 0;
-                               eve= fillvertbase.first;
+                               eve= sf_ctx.fillvertbase.first;
                                while (eve) {
                                        copy_v3_v3(f1, eve->co);
                                        f1+= 3;
@@ -499,7 +500,7 @@ void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
                                }
                                
                                /* index data */
-                               efafillfacebase.first;
+                               efa = sf_ctx.fillfacebase.first;
                                index= dlnew->index;
                                while (efa) {
                                        index[0]= (intptr_t)efa->v1->tmp.l;
@@ -517,7 +518,7 @@ void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
                        BLI_addhead(to, dlnew);
                        
                }
-               BLI_end_edgefill();
+               BLI_end_edgefill(&sf_ctx);
 
                if (nextcol) {
                        /* stay at current char but fill polys with next material */
index 75f6abc6c74ab1b5f3f78a3dcf1441184a7cc8c0..07a43db8560aab080cc15199c0f9e1f5677eeb8c 100644 (file)
@@ -120,6 +120,8 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
        BMLoop *l;
        int i = 0, j;
 
+       ScanFillContext sf_ctx;
+
 #if 0
        /* note, we could be clever and re-use this array but would need to ensure
         * its realloced at some point, for now just free it */
@@ -195,18 +197,18 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
                        ScanFillFace *efa;
                        int totfilltri;
 
-                       BLI_begin_edgefill();
+                       BLI_begin_edgefill(&sf_ctx);
                        /*scanfill time*/
                        l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
                        for (j=0; l; l=BM_iter_step(&liter), j++) {
                                /*mark order*/
                                BM_elem_index_set(l, j); /* set_loop */
 
-                               v = BLI_addfillvert(l->v->co);
+                               v = BLI_addfillvert(&sf_ctx, l->v->co);
                                v->tmp.p = l;
 
                                if (lastv) {
-                                       /* e = */ BLI_addfilledge(lastv, v);
+                                       /* e = */ BLI_addfilledge(&sf_ctx, lastv, v);
                                }
 
                                lastv = v;
@@ -214,12 +216,12 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
                        }
 
                        /*complete the loop*/
-                       BLI_addfilledge(firstv, v);
+                       BLI_addfilledge(&sf_ctx, firstv, v);
 
-                       totfilltri = BLI_edgefill(FALSE);
+                       totfilltri = BLI_edgefill(&sf_ctx, FALSE);
                        BLI_array_growitems(looptris, totfilltri);
 
-                       for (efa = fillfacebase.first; efa; efa=efa->next) {
+                       for (efa = sf_ctx.fillfacebase.first; efa; efa=efa->next) {
                                BMLoop *l1= efa->v1->tmp.p;
                                BMLoop *l2= efa->v2->tmp.p;
                                BMLoop *l3= efa->v3->tmp.p;
@@ -234,7 +236,7 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
                                i += 1;
                        }
 
-                       BLI_end_edgefill();
+                       BLI_end_edgefill(&sf_ctx);
                }
        }
 
index 2a22324a0ab79b74d5368a46d1f1a16fee735d9b..b7b9f6b21f44d2c1dc02b3bc2f0380c0eed2a523 100644 (file)
@@ -2354,7 +2354,6 @@ int mesh_recalcTessellation(CustomData *fdata,
                             * we can skip copying here */
                            const int do_face_nor_cpy)
 {
-
        /* use this to avoid locking pthread for _every_ polygon
         * and calling the fill function */
 
@@ -2368,6 +2367,7 @@ int mesh_recalcTessellation(CustomData *fdata,
        MLoop *ml, *mloop;
        MFace *mface = NULL, *mf;
        BLI_array_declare(mface);
+       ScanFillContext sf_ctx;
        ScanFillVert *v, *lastv, *firstv;
        ScanFillFace *f;
        int *mface_orig_index = NULL;
@@ -2461,24 +2461,24 @@ int mesh_recalcTessellation(CustomData *fdata,
 
                        ml = mloop + mp->loopstart;
                        
-                       BLI_begin_edgefill();
+                       BLI_begin_edgefill(&sf_ctx);
                        firstv = NULL;
                        lastv = NULL;
                        for (j=0; j<mp->totloop; j++, ml++) {
-                               v = BLI_addfillvert(mvert[ml->v].co);
+                               v = BLI_addfillvert(&sf_ctx, mvert[ml->v].co);
        
                                v->keyindex = mp->loopstart + j;
        
                                if (lastv)
-                                       BLI_addfilledge(lastv, v);
+                                       BLI_addfilledge(&sf_ctx, lastv, v);
        
                                if (!firstv)
                                        firstv = v;
                                lastv = v;
                        }
-                       BLI_addfilledge(lastv, firstv);
+                       BLI_addfilledge(&sf_ctx, lastv, firstv);
                        
-                       totfilltri = BLI_edgefill(FALSE);
+                       totfilltri = BLI_edgefill(&sf_ctx, FALSE);
                        if (totfilltri) {
                                BLI_array_growitems(mface_to_poly_map, totfilltri);
                                BLI_array_growitems(mface, totfilltri);
@@ -2486,7 +2486,7 @@ int mesh_recalcTessellation(CustomData *fdata,
                                        BLI_array_growitems(mface_orig_index, totfilltri);
                                }
 
-                               for (f = fillfacebase.first; f; f = f->next, mf++) {
+                               for (f = sf_ctx.fillfacebase.first; f; f = f->next, mf++) {
                                        mface_to_poly_map[mface_index] = poly_index;
                                        mf= &mface[mface_index];
 
@@ -2511,7 +2511,7 @@ int mesh_recalcTessellation(CustomData *fdata,
                                }
                        }
        
-                       BLI_end_edgefill();
+                       BLI_end_edgefill(&sf_ctx);
                }
        }
 
index 6dcc1df41a3ec195778f348ac9afb2de560ff535..67ff9a88700e55c3d4d1fdccdc37fd09ce4ce5d7 100644 (file)
  *  \brief Filling meshes.
  */
 
-/**
- * \attention Defined in scanfill.c
- */
-extern struct ListBase fillvertbase;
-extern struct ListBase filledgebase;
-extern struct ListBase fillfacebase;
-
 struct ScanFillVert;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+typedef struct ScanFillContext
+{
+       ListBase fillvertbase;
+       ListBase filledgebase;
+       ListBase fillfacebase;
+
+       /* simple optimization for allocating thousands of small memory blocks
+        * only to be used within loops, and not by one function at a time
+        * free in the end, with argument '-1'
+        */
+       #define MEM_ELEM_BLOCKSIZE 16384
+       struct mem_elements *melem__cur;
+       int melem__offs;                   /* the current free address */
+       ListBase melem__lb;
+
+       /* private */
+       struct ScanFillVertLink *_scdata;
+} ScanFillContext;
+
 /* note; changing this also might affect the undo copy in editmesh.c */
 typedef struct ScanFillVert
 {
@@ -57,7 +69,8 @@ typedef struct ScanFillVert
                void            *p;
                intptr_t         l;
        } tmp;
-       float co[3]; /*vertex location */
+       float co[3]; /* vertex location */
+       float xy[2]; /* 2D copy of vertex location (using dominant axis) */
        int keyindex; /* original index #, for restoring  key information */
        short poly_nr;
        unsigned char f, h;
@@ -78,16 +91,16 @@ typedef struct ScanFillFace
 } ScanFillFace;
 
 /* scanfill.c: used in displist only... */
-struct ScanFillVert *BLI_addfillvert(const float vec[3]);
-struct ScanFillEdge *BLI_addfilledge(struct ScanFillVert *v1, struct ScanFillVert *v2);
+struct ScanFillVert *BLI_addfillvert(ScanFillContext *sf_ctx, const float vec[3]);
+struct ScanFillEdge *BLI_addfilledge(ScanFillContext *sf_ctx, struct ScanFillVert *v1, struct ScanFillVert *v2);
 
 /* Optionally set ScanFillEdge f to this to mark original boundary edges.
  * Only needed if there are internal diagonal edges passed to BLI_edgefill. */
 #define FILLBOUNDARY 1
 
-int BLI_begin_edgefill(void);
-int BLI_edgefill(const short do_quad_tri_speedup);
-void BLI_end_edgefill(void);
+int BLI_begin_edgefill(ScanFillContext *sf_ctx);
+int BLI_edgefill(ScanFillContext *sf_ctx, const short do_quad_tri_speedup);
+void BLI_end_edgefill(ScanFillContext *sf_ctx);
 
 /* These callbacks are needed to make the lib finction properly */
 
@@ -109,8 +122,6 @@ void BLI_setErrorCallBack(void (*f)(const char*));
  */
 void BLI_setInterruptCallBack(int (*f)(void));
 
-void BLI_scanfill_free(void);
-
 #ifdef __cplusplus
 }
 #endif
index 03bf375a8942f698ea5ff22ef46182ed0817dada..8e75a2db6290f02c6f366d1d0497e12339ecbc37 100644 (file)
@@ -76,7 +76,6 @@ int           BLI_system_thread_count(void); /* gets the number of threads the system can
 #define LOCK_OPENGL            5
 #define LOCK_NODES             6
 #define LOCK_MOVIECLIP 7
-#define LOCK_SCANFILL  8
 
 void   BLI_lock_thread(int type);
 void   BLI_unlock_thread(int type);
index 89ab192c9208fc668c612488edbf0421f92d4e43..69b8f3f3ee7abbbab323fcd4e81e9fb3a78a851d 100644 (file)
@@ -42,7 +42,6 @@
 #include "BLI_math.h"
 #include "BLI_scanfill.h"
 #include "BLI_utildefines.h"
-#include "BLI_threads.h"
 
 /* callbacks for errors and interrupts and some goo */
 static void (*BLI_localErrorCallBack)(const char *) = NULL;
@@ -82,7 +81,7 @@ static int callLocalInterruptCallBack(void)
 /* local types */
 typedef struct PolyFill {
        int edges, verts;
-       float min[3], max[3];
+       float min_xy[2], max_xy[2];
        short f, nr;
 } PolyFill;
 
@@ -96,14 +95,6 @@ typedef struct ScanFillVertLink {
 
 #define COMPLIMIT   0.00003f
 
-static ScanFillVertLink *scdata;
-
-ListBase fillvertbase = {NULL, NULL};
-ListBase filledgebase = {NULL, NULL};
-ListBase fillfacebase = {NULL, NULL};
-
-static int cox, coy;
-
 /* ****  FUNCTIONS FOR QSORT *************************** */
 
 
@@ -111,10 +102,10 @@ static int vergscdata(const void *a1, const void *a2)
 {
        const ScanFillVertLink *x1 = a1, *x2 = a2;
        
-       if      (x1->v1->co[coy] < x2->v1->co[coy]) return  1;
-       else if (x1->v1->co[coy] > x2->v1->co[coy]) return -1;
-       else if (x1->v1->co[cox] > x2->v1->co[cox]) return  1;
-       else if (x1->v1->co[cox] < x2->v1->co[cox]) return -1;
+       if      (x1->v1->xy[1] < x2->v1->xy[1]) return  1;
+       else if (x1->v1->xy[1] > x2->v1->xy[1]) return -1;
+       else if (x1->v1->xy[0] > x2->v1->xy[0]) return  1;
+       else if (x1->v1->xy[0] < x2->v1->xy[0]) return -1;
 
        return 0;
 }
@@ -123,70 +114,61 @@ static int vergpoly(const void *a1, const void *a2)
 {
        const PolyFill *x1 = a1, *x2 = a2;
 
-       if      (x1->min[cox] > x2->min[cox]) return  1;
-       else if (x1->min[cox] < x2->min[cox]) return -1;
-       else if (x1->min[coy] > x2->min[coy]) return  1;
-       else if (x1->min[coy] < x2->min[coy]) return -1;
+       if      (x1->min_xy[0] > x2->min_xy[0]) return  1;
+       else if (x1->min_xy[0] < x2->min_xy[0]) return -1;
+       else if (x1->min_xy[1] > x2->min_xy[1]) return  1;
+       else if (x1->min_xy[1] < x2->min_xy[1]) return -1;
        
        return 0;
 }
 
 /* ************* MEMORY MANAGEMENT ************* */
 
+/* memory management */
 struct mem_elements {
        struct mem_elements *next, *prev;
        char *data;
 };
 
-
-/* simple optimization for allocating thousands of small memory blocks
- * only to be used within loops, and not by one function at a time
- * free in the end, with argument '-1'
- */
-#define MEM_ELEM_BLOCKSIZE 16384
-static struct mem_elements *melem__cur = NULL;
-static int melem__offs = 0;                   /* the current free address */
-static ListBase melem__lb = {NULL, NULL};
-
-static void *mem_element_new(int size)
+static void *mem_element_new(ScanFillContext *sf_ctx, int size)
 {
        BLI_assert(!(size > 10000 || size == 0)); /* this is invalid use! */
 
        size = (size + 3) & ~3;     /* allocate in units of 4 */
        
-       if (melem__cur && (size + melem__offs < MEM_ELEM_BLOCKSIZE)) {
-               void *adr = (void *) (melem__cur->data + melem__offs);
-               melem__offs += size;
+       if (sf_ctx->melem__cur && (size + sf_ctx->melem__offs < MEM_ELEM_BLOCKSIZE)) {
+               void *adr = (void *) (sf_ctx->melem__cur->data + sf_ctx->melem__offs);
+               sf_ctx->melem__offs += size;
                return adr;
        }
        else {
-               melem__cur = MEM_callocN(sizeof(struct mem_elements), "newmem");
-               melem__cur->data = MEM_callocN(MEM_ELEM_BLOCKSIZE, "newmem");
-               BLI_addtail(&melem__lb, melem__cur);
+               sf_ctx->melem__cur = MEM_callocN(sizeof(struct mem_elements), "newmem");
+               sf_ctx->melem__cur->data = MEM_callocN(MEM_ELEM_BLOCKSIZE, "newmem");
+               BLI_addtail(&sf_ctx->melem__lb, sf_ctx->melem__cur);
 
-               melem__offs = size;
-               return melem__cur->data;
+               sf_ctx->melem__offs = size;
+               return sf_ctx->melem__cur->data;
        }
 }
-static void mem_element_reset(int keep_first)
+static void mem_element_reset(ScanFillContext *sf_ctx, int keep_first)
 {
        struct mem_elements *first;
 
-       if ((first = melem__lb.first)) { /* can be false if first fill fails */
+       if ((first = sf_ctx->melem__lb.first)) { /* can be false if first fill fails */
                if (keep_first) {
-                       BLI_remlink(&melem__lb, first);
+                       BLI_remlink(&sf_ctx->melem__lb, first);
                }
 
-               melem__cur = melem__lb.first;
-               while (melem__cur) {
-                       MEM_freeN(melem__cur->data);
-                       melem__cur = melem__cur->next;
+               sf_ctx->melem__cur = sf_ctx->melem__lb.first;
+               while (sf_ctx->melem__cur) {
+                       MEM_freeN(sf_ctx->melem__cur->data);
+                       sf_ctx->melem__cur = sf_ctx->melem__cur->next;
                }
-               BLI_freelistN(&melem__lb);
+               BLI_freelistN(&sf_ctx->melem__lb);
 
                /*reset the block we're keeping*/
                if (keep_first) {
-                       BLI_addtail(&melem__lb, first);
+                       BLI_addtail(&sf_ctx->melem__lb, first);
                        memset(first->data, 0, MEM_ELEM_BLOCKSIZE);
                }
                else {
@@ -195,34 +177,27 @@ static void mem_element_reset(int keep_first)
                }
        }
 
-       melem__cur = first;
-       melem__offs = 0;
+       sf_ctx->melem__cur = first;
+       sf_ctx->melem__offs = 0;
 }
 
-void BLI_end_edgefill(void)
+void BLI_end_edgefill(ScanFillContext *sf_ctx)
 {
-       mem_element_reset(TRUE);
+        mem_element_reset(sf_ctx, FALSE);
        
-       fillvertbase.first = fillvertbase.last = 0;
-       filledgebase.first = filledgebase.last = 0;
-       fillfacebase.first = fillfacebase.last = 0;
-       
-       BLI_unlock_thread(LOCK_SCANFILL);       
-}
-
-void BLI_scanfill_free(void)
-{
-       mem_element_reset(FALSE);
+       sf_ctx->fillvertbase.first = sf_ctx->fillvertbase.last = NULL;
+       sf_ctx->filledgebase.first = sf_ctx->filledgebase.last = NULL;
+       sf_ctx->fillfacebase.first = sf_ctx->fillfacebase.last = NULL;
 }
 
 /* ****  FILL ROUTINES *************************** */
 
-ScanFillVert *BLI_addfillvert(const float vec[3])
+ScanFillVert *BLI_addfillvert(ScanFillContext *sf_ctx, const float vec[3])
 {
        ScanFillVert *eve;
        
-       eve = mem_element_new(sizeof(ScanFillVert));
-       BLI_addtail(&fillvertbase, eve);
+       eve = mem_element_new(sf_ctx, sizeof(ScanFillVert));
+       BLI_addtail(&sf_ctx->fillvertbase, eve);
        
        eve->co[0] = vec[0];
        eve->co[1] = vec[1];
@@ -231,12 +206,12 @@ ScanFillVert *BLI_addfillvert(const float vec[3])
        return eve;     
 }
 
-ScanFillEdge *BLI_addfilledge(ScanFillVert *v1, ScanFillVert *v2)
+ScanFillEdge *BLI_addfilledge(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert *v2)
 {
        ScanFillEdge *newed;
 
-       newed = mem_element_new(sizeof(ScanFillEdge));
-       BLI_addtail(&filledgebase, newed);
+       newed = mem_element_new(sf_ctx, sizeof(ScanFillEdge));
+       BLI_addtail(&sf_ctx->filledgebase, newed);
        
        newed->v1 = v1;
        newed->v2 = v2;
@@ -244,13 +219,13 @@ ScanFillEdge *BLI_addfilledge(ScanFillVert *v1, ScanFillVert *v2)
        return newed;
 }
 
-static void addfillface(ScanFillVert *v1, ScanFillVert *v2, ScanFillVert *v3)
+static void addfillface(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert *v2, ScanFillVert *v3)
 {
        /* does not make edges */
        ScanFillFace *evl;
 
-       evl = mem_element_new(sizeof(ScanFillFace));
-       BLI_addtail(&fillfacebase, evl);
+       evl = mem_element_new(sf_ctx, sizeof(ScanFillFace));
+       BLI_addtail(&sf_ctx->fillfacebase, evl);
        
        evl->v1 = v1;
        evl->v2 = v2;
@@ -264,35 +239,35 @@ static int boundisect(PolyFill *pf2, PolyFill *pf1)
 
        if (pf1->edges == 0 || pf2->edges == 0) return 0;
 
-       if (pf2->max[cox] < pf1->min[cox]) return 0;
-       if (pf2->max[coy] < pf1->min[coy]) return 0;
+       if (pf2->max_xy[0] < pf1->min_xy[0]) return 0;
+       if (pf2->max_xy[1] < pf1->min_xy[1]) return 0;
 
-       if (pf2->min[cox] > pf1->max[cox]) return 0;
-       if (pf2->min[coy] > pf1->max[coy]) return 0;
+       if (pf2->min_xy[0] > pf1->max_xy[0]) return 0;
+       if (pf2->min_xy[1] > pf1->max_xy[1]) return 0;
 
        /* join */
-       if (pf2->max[cox] < pf1->max[cox]) pf2->max[cox] = pf1->max[cox];
-       if (pf2->max[coy] < pf1->max[coy]) pf2->max[coy] = pf1->max[coy];
+       if (pf2->max_xy[0] < pf1->max_xy[0]) pf2->max_xy[0] = pf1->max_xy[0];
+       if (pf2->max_xy[1] < pf1->max_xy[1]) pf2->max_xy[1] = pf1->max_xy[1];
 
-       if (pf2->min[cox] > pf1->min[cox]) pf2->min[cox] = pf1->min[cox];
-       if (pf2->min[coy] > pf1->min[coy]) pf2->min[coy] = pf1->min[coy];
+       if (pf2->min_xy[0] > pf1->min_xy[0]) pf2->min_xy[0] = pf1->min_xy[0];
+       if (pf2->min_xy[1] > pf1->min_xy[1]) pf2->min_xy[1] = pf1->min_xy[1];
 
        return 1;
 }
 
 
-static void mergepolysSimp(PolyFill *pf1, PolyFill *pf2)    /* add pf2 to pf1 */
+static void mergepolysSimp(ScanFillContext *sf_ctx, PolyFill *pf1, PolyFill *pf2)    /* add pf2 to pf1 */
 {
        ScanFillVert *eve;
        ScanFillEdge *eed;
 
        /* replace old poly numbers */
-       eve = fillvertbase.first;
+       eve = sf_ctx->fillvertbase.first;
        while (eve) {
                if (eve->poly_nr == pf2->nr) eve->poly_nr = pf1->nr;
                eve = eve->next;
        }
-       eed = filledgebase.first;
+       eed = sf_ctx->filledgebase.first;
        while (eed) {
                if (eed->poly_nr == pf2->nr) eed->poly_nr = pf1->nr;
                eed = eed->next;
@@ -304,20 +279,20 @@ static void mergepolysSimp(PolyFill *pf1, PolyFill *pf2)    /* add pf2 to pf1 */
        pf1->f = (pf1->f | pf2->f);
 }
 
-static short testedgeside(const float v1[3], const float v2[3], const float v3[3])
+static short 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;
 
-       inp = (v2[cox] - v1[cox]) * (v1[coy] - v3[coy]) +
-             (v1[coy] - v2[coy]) * (v1[cox] - v3[cox]);
+       inp = (v2[0] - v1[0]) * (v1[1] - v3[1]) +
+             (v1[1] - v2[1]) * (v1[0] - v3[0]);
 
        if (inp < 0.0f) {
                return 0;
        }
        else if (inp == 0) {
-               if (v1[cox] == v3[cox] && v1[coy] == v3[coy]) return 0;
-               if (v2[cox] == v3[cox] && v2[coy] == v3[coy]) return 0;
+               if (v1[0] == v3[0] && v1[1] == v3[1]) return 0;
+               if (v2[0] == v3[0] && v2[1] == v3[1]) return 0;
        }
        return 1;
 }
@@ -334,27 +309,27 @@ static short addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed)
                return 1;
        }
 
-       x = eed->v1->co[cox];
-       y = eed->v1->co[coy];
+       x = eed->v1->xy[0];
+       y = eed->v1->xy[1];
 
-       fac1 = eed->v2->co[coy] - y;
+       fac1 = eed->v2->xy[1] - y;
        if (fac1 == 0.0f) {
-               fac1 = 1.0e10f * (eed->v2->co[cox] - x);
+               fac1 = 1.0e10f * (eed->v2->xy[0] - x);
 
        }
-       else fac1 = (x - eed->v2->co[cox]) / fac1;
+       else fac1 = (x - eed->v2->xy[0]) / fac1;
 
        ed = sc->first;
        while (ed) {
 
                if (ed->v2 == eed->v2) return 0;
 
-               fac = ed->v2->co[coy] - y;
+               fac = ed->v2->xy[1] - y;
                if (fac == 0.0f) {
-                       fac = 1.0e10f * (ed->v2->co[cox] - x);
+                       fac = 1.0e10f * (ed->v2->xy[0] - x);
                }
                else {
-                       fac = (x - ed->v2->co[cox]) / fac;
+                       fac = (x - ed->v2->xy[0]) / fac;
                }
 
                if (fac > fac1) break;
@@ -368,7 +343,7 @@ static short addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed)
 }
 
 
-static ScanFillVertLink *addedgetoscanlist(ScanFillEdge *eed, int len)
+static ScanFillVertLink *addedgetoscanlist(ScanFillContext *sf_ctx, ScanFillEdge *eed, int len)
 {
        /* inserts edge at correct location in ScanFillVertLink list */
        /* returns sc when edge already exists */
@@ -376,21 +351,21 @@ static ScanFillVertLink *addedgetoscanlist(ScanFillEdge *eed, int len)
        ScanFillVert *eve;
 
        /* which vert is left-top? */
-       if (eed->v1->co[coy] == eed->v2->co[coy]) {
-               if (eed->v1->co[cox] > eed->v2->co[cox]) {
+       if (eed->v1->xy[1] == eed->v2->xy[1]) {
+               if (eed->v1->xy[0] > eed->v2->xy[0]) {
                        eve = eed->v1;
                        eed->v1 = eed->v2;
                        eed->v2 = eve;
                }
        }
-       else if (eed->v1->co[coy] < eed->v2->co[coy]) {
+       else if (eed->v1->xy[1] < eed->v2->xy[1]) {
                eve = eed->v1;
                eed->v1 = eed->v2;
                eed->v2 = eve;
        }
        /* find location in list */
        scsearch.v1 = eed->v1;
-       sc = (ScanFillVertLink *)bsearch(&scsearch, scdata, len,
+       sc = (ScanFillVertLink *)bsearch(&scsearch, sf_ctx->_scdata, len,
                                         sizeof(ScanFillVertLink), vergscdata);
 
        if (sc == 0) printf("Error in search edge: %p\n", (void *)eed);
@@ -404,30 +379,30 @@ static short boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve)
 {
        float minx, maxx, miny, maxy;
 
-       if (eed->v1->co[cox] < eed->v2->co[cox]) {
-               minx = eed->v1->co[cox];
-               maxx = eed->v2->co[cox];
+       if (eed->v1->xy[0] < eed->v2->xy[0]) {
+               minx = eed->v1->xy[0];
+               maxx = eed->v2->xy[0];
        }
        else {
-               minx = eed->v2->co[cox];
-               maxx = eed->v1->co[cox];
+               minx = eed->v2->xy[0];
+               maxx = eed->v1->xy[0];
        }
-       if (eve->co[cox] >= minx && eve->co[cox] <= maxx) {
-               if (eed->v1->co[coy] < eed->v2->co[coy]) {
-                       miny = eed->v1->co[coy];
-                       maxy = eed->v2->co[coy];
+       if (eve->xy[0] >= minx && eve->xy[0] <= maxx) {
+               if (eed->v1->xy[1] < eed->v2->xy[1]) {
+                       miny = eed->v1->xy[1];
+                       maxy = eed->v2->xy[1];
                }
                else {
-                       miny = eed->v2->co[coy];
-                       maxy = eed->v1->co[coy];
+                       miny = eed->v2->xy[1];
+                       maxy = eed->v1->xy[1];
                }
-               if (eve->co[coy] >= miny && eve->co[coy] <= maxy) return 1;
+               if (eve->xy[1] >= miny && eve->xy[1] <= maxy) return 1;
        }
        return 0;
 }
 
 
-static void testvertexnearedge(void)
+static void testvertexnearedge(ScanFillContext *sf_ctx)
 {
        /* only vertices with ->h==1 are being tested for
         * being close to an edge, if true insert */
@@ -436,13 +411,13 @@ static void testvertexnearedge(void)
        ScanFillEdge *eed, *ed1;
        float dist, vec1[2], vec2[2], vec3[2];
 
-       eve = fillvertbase.first;
+       eve = sf_ctx->fillvertbase.first;
        while (eve) {
                if (eve->h == 1) {
-                       vec3[0] = eve->co[cox];
-                       vec3[1] = eve->co[coy];
+                       vec3[0] = eve->xy[0];
+                       vec3[1] = eve->xy[1];
                        /* find the edge which has vertex eve */
-                       ed1 = filledgebase.first;
+                       ed1 = sf_ctx->filledgebase.first;
                        while (ed1) {
                                if (ed1->v1 == eve || ed1->v2 == eve) break;
                                ed1 = ed1->next;
@@ -451,7 +426,7 @@ static void testvertexnearedge(void)
                                ed1->v1 = ed1->v2;
                                ed1->v2 = eve;
                        }
-                       eed = filledgebase.first;
+                       eed = sf_ctx->filledgebase.first;
                        while (eed) {
                                if (eve != eed->v1 && eve != eed->v2 && eve->poly_nr == eed->poly_nr) {
                                        if (compare_v3v3(eve->co, eed->v1->co, COMPLIMIT)) {
@@ -467,15 +442,15 @@ static void testvertexnearedge(void)
                                                break;
                                        }
                                        else {
-                                               vec1[0] = eed->v1->co[cox];
-                                               vec1[1] = eed->v1->co[coy];
-                                               vec2[0] = eed->v2->co[cox];
-                                               vec2[1] = eed->v2->co[coy];
+                                               vec1[0] = eed->v1->xy[0];
+                                               vec1[1] = eed->v1->xy[1];
+                                               vec2[0] = eed->v2->xy[0];
+                                               vec2[1] = eed->v2->xy[1];
                                                if (boundinsideEV(eed, eve)) {
                                                        dist = dist_to_line_v2(vec1, vec2, vec3);
                                                        if (dist < COMPLIMIT) {
                                                                /* new edge */
-                                                               ed1 = BLI_addfilledge(eed->v1, eve);
+                                                               ed1 = BLI_addfilledge(sf_ctx, eed->v1, eve);
                                                                
                                                                /* printf("fill: vertex near edge %x\n",eve); */
                                                                ed1->f = 0;
@@ -494,21 +469,21 @@ static void testvertexnearedge(void)
        }
 }
 
-static void splitlist(ListBase *tempve, ListBase *temped, short nr)
+static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *temped, short nr)
 {
        /* everything is in templist, write only poly nr to fillist */
        ScanFillVert *eve, *nextve;
        ScanFillEdge *eed, *nexted;
 
-       BLI_movelisttolist(tempve, &fillvertbase);
-       BLI_movelisttolist(temped, &filledgebase);
+       BLI_movelisttolist(tempve, &sf_ctx->fillvertbase);
+       BLI_movelisttolist(temped, &sf_ctx->filledgebase);
 
        eve = tempve->first;
        while (eve) {
                nextve = eve->next;
                if (eve->poly_nr == nr) {
                        BLI_remlink(tempve, eve);
-                       BLI_addtail(&fillvertbase, eve);
+                       BLI_addtail(&sf_ctx->fillvertbase, eve);
                }
                eve = nextve;
        }
@@ -517,14 +492,14 @@ static void splitlist(ListBase *tempve, ListBase *temped, short nr)
                nexted = eed->next;
                if (eed->poly_nr == nr) {
                        BLI_remlink(temped, eed);
-                       BLI_addtail(&filledgebase, eed);
+                       BLI_addtail(&sf_ctx->filledgebase, eed);
                }
                eed = nexted;
        }
 }
 
 
-static int scanfill(PolyFill *pf)
+static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf)
 {
        ScanFillVertLink *sc = NULL, *sc1;
        ScanFillVert *eve, *v1, *v2, *v3;
@@ -538,12 +513,12 @@ static int scanfill(PolyFill *pf)
        /* PRINTS */
 #if 0
        verts = pf->verts;
-       eve = fillvertbase.first;
+       eve = sf_ctx->fillvertbase.first;
        while (eve) {
-               printf("vert: %x co: %f %f\n", eve, eve->co[cox], eve->co[coy]);
+               printf("vert: %x co: %f %f\n", eve, eve->xy[0], eve->xy[1]);
                eve = eve->next;
        }       
-       eed = filledgebase.first;
+       eed = sf_ctx->filledgebase.first;
        while (eed) {
                printf("edge: %x  verts: %x %x\n", eed, eed->v1, eed->v2);
                eed = eed->next;
@@ -551,10 +526,10 @@ static int scanfill(PolyFill *pf)
 #endif
 
        /* STEP 0: remove zero sized edges */
-       eed = filledgebase.first;
+       eed = sf_ctx->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->xy[0] == eed->v2->xy[0]) {
+                       if (eed->v1->xy[1] == eed->v2->xy[1]) {
                                if (eed->v1->f == 255 && eed->v2->f != 255) {
                                        eed->v2->f = 255;
                                        eed->v2->tmp.v = eed->v1->tmp.v;
@@ -578,8 +553,8 @@ static int scanfill(PolyFill *pf)
        /* STEP 1: make using FillVert and FillEdge lists a sorted
         * ScanFillVertLink list
         */
-       sc = scdata = (ScanFillVertLink *)MEM_callocN(pf->verts * sizeof(ScanFillVertLink), "Scanfill1");
-       eve = fillvertbase.first;
+       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) {
@@ -593,12 +568,12 @@ static int scanfill(PolyFill *pf)
                eve = eve->next;
        }
 
-       qsort(scdata, verts, sizeof(ScanFillVertLink), vergscdata);
+       qsort(sf_ctx->_scdata, verts, sizeof(ScanFillVertLink), vergscdata);
 
-       eed = filledgebase.first;
+       eed = sf_ctx->filledgebase.first;
        while (eed) {
                nexted = eed->next;
-               BLI_remlink(&filledgebase, eed);
+               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
@@ -614,7 +589,7 @@ static int scanfill(PolyFill *pf)
                        while ((eed->v2->f == 255) && (eed->v2->tmp.v != v2))
                                eed->v2 = eed->v2->tmp.v;
                }
-               if (eed->v1 != eed->v2) addedgetoscanlist(eed, verts);
+               if (eed->v1 != eed->v2) addedgetoscanlist(sf_ctx, eed, verts);
 
                eed = nexted;
        }
@@ -640,7 +615,7 @@ static int scanfill(PolyFill *pf)
        totface = 0;
        maxface = 2 * verts;       /* 2*verts: based at a filled circle within a triangle */
 
-       sc = scdata;
+       sc = sf_ctx->_scdata;
        for (a = 0; a < verts; a++) {
                /* printf("VERTEX %d %x\n",a,sc->v1); */
                ed1 = sc->first;
@@ -648,7 +623,7 @@ static int scanfill(PolyFill *pf)
                        nexted = ed1->next;
                        if (ed1->v1->h == 1 || ed1->v2->h == 1) {
                                BLI_remlink((ListBase *)&(sc->first), ed1);
-                               BLI_addtail(&filledgebase, ed1);
+                               BLI_addtail(&sf_ctx->filledgebase, ed1);
                                if (ed1->v1->h > 1) ed1->v1->h--;
                                if (ed1->v2->h > 1) ed1->v2->h--;
                        }
@@ -670,7 +645,7 @@ static int scanfill(PolyFill *pf)
                        if (ed2 == 0) {
                                sc->first = sc->last = NULL;
                                /* printf("just 1 edge to vert\n"); */
-                               BLI_addtail(&filledgebase, ed1);
+                               BLI_addtail(&sf_ctx->filledgebase, ed1);
                                ed1->v2->f = 0;
                                ed1->v1->h--; 
                                ed1->v2->h--;
@@ -683,18 +658,18 @@ static int scanfill(PolyFill *pf)
                                /* 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]); */
+                               miny = ( (v1->xy[1]) < (v3->xy[1]) ? (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->co[coy] <= miny) break;
+                                               if (sc1->v1->xy[1] <= 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)) {
+                                               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;
@@ -707,8 +682,8 @@ static int scanfill(PolyFill *pf)
                                        /* 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);
+                                       ed3 = BLI_addfilledge(sf_ctx, v2, sc1->v1);
+                                       BLI_remlink(&sf_ctx->filledgebase, ed3);
                                        BLI_insertlinkbefore((ListBase *)&(sc->first), ed2, ed3);
                                        ed3->v2->f = 1;
                                        ed3->f = 2;
@@ -718,31 +693,31 @@ static int scanfill(PolyFill *pf)
                                else {
                                        /* new triangle */
                                        /* printf("add face %x %x %x\n",v1,v2,v3); */
-                                       addfillface(v1, v2, v3);
+                                       addfillface(sf_ctx, v1, v2, v3);
                                        totface++;
                                        BLI_remlink((ListBase *)&(sc->first), ed1);
-                                       BLI_addtail(&filledgebase, 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 == FILLBOUNDARY)) {
                                                BLI_remlink((ListBase *)&(sc->first), ed2);
-                                               BLI_addtail(&filledgebase, ed2);
+                                               BLI_addtail(&sf_ctx->filledgebase, ed2);
                                                ed2->v2->f = 0;
                                                ed2->v1->h--; 
                                                ed2->v2->h--;
                                        }
 
                                        /* new edge */
-                                       ed3 = BLI_addfilledge(v1, v3);
-                                       BLI_remlink(&filledgebase, ed3);
+                                       ed3 = BLI_addfilledge(sf_ctx, v1, v3);
+                                       BLI_remlink(&sf_ctx->filledgebase, ed3);
                                        ed3->f = 2;
                                        ed3->v1->h++; 
                                        ed3->v2->h++;
                                        
                                        /* printf("add new edge %x %x\n",v1,v3); */
-                                       sc1 = addedgetoscanlist(ed3, verts);
+                                       sc1 = addedgetoscanlist(sf_ctx, ed3, verts);
                                        
                                        if (sc1) {  /* ed3 already exists: remove if a boundary */
                                                /* printf("Edge exists\n"); */
@@ -754,7 +729,7 @@ static int scanfill(PolyFill *pf)
                                                        if ( (ed3->v1 == v1 && ed3->v2 == v3) || (ed3->v1 == v3 && ed3->v2 == v1) ) {
                                                                if (twoconnected || ed3->f == FILLBOUNDARY) {
                                                                        BLI_remlink((ListBase *)&(sc1->first), ed3);
-                                                                       BLI_addtail(&filledgebase, ed3);
+                                                                       BLI_addtail(&sf_ctx->filledgebase, ed3);
                                                                        ed3->v1->h--; 
                                                                        ed3->v2->h--;
                                                                }
@@ -772,7 +747,7 @@ static int scanfill(PolyFill *pf)
                                nexted = ed1->next;
                                if (ed1->v1->h < 2 || ed1->v2->h < 2) {
                                        BLI_remlink((ListBase *)&(sc->first), ed1);
-                                       BLI_addtail(&filledgebase, ed1);
+                                       BLI_addtail(&sf_ctx->filledgebase, ed1);
                                        if (ed1->v1->h > 1) ed1->v1->h--;
                                        if (ed1->v2->h > 1) ed1->v2->h--;
                                }
@@ -783,20 +758,21 @@ static int scanfill(PolyFill *pf)
                sc++;
        }
 
-       MEM_freeN(scdata);
+       MEM_freeN(sf_ctx->_scdata);
+       sf_ctx->_scdata = NULL;
 
        return totface;
 }
 
 
-int BLI_begin_edgefill(void)
+int BLI_begin_edgefill(ScanFillContext *sf_ctx)
 {
-       BLI_lock_thread(LOCK_SCANFILL);
+       memset(sf_ctx, 0, sizeof(*sf_ctx));
 
        return 1;
 }
 
-int BLI_edgefill(const short do_quad_tri_speedup)
+int BLI_edgefill(ScanFillContext *sf_ctx, const short do_quad_tri_speedup)
 {
        /*
         * - fill works with its own lists, so create that first (no faces!)
@@ -810,12 +786,13 @@ int BLI_edgefill(const short do_quad_tri_speedup)
        ScanFillVert *eve;
        ScanFillEdge *eed, *nexted;
        PolyFill *pflist, *pf;
-       float limit, *minp, *maxp, *v1, *v2, norm[3], len;
+       float limit, *min_xy_p, *max_xy_p, *v1, *v2, norm[3], len;
        short a, c, poly = 0, ok = 0, toggle = 0;
        int totfaces = 0; /* total faces added */
+       int co_x, co_y;
 
        /* reset variables */
-       eve = fillvertbase.first;
+       eve = sf_ctx->fillvertbase.first;
        a = 0;
        while (eve) {
                eve->f = 0;
@@ -826,34 +803,34 @@ int BLI_edgefill(const short do_quad_tri_speedup)
        }
 
        if (do_quad_tri_speedup && (a == 3)) {
-               eve = fillvertbase.first;
+               eve = sf_ctx->fillvertbase.first;
 
-               addfillface(eve, eve->next, eve->next->next);
+               addfillface(sf_ctx, eve, eve->next, eve->next->next);
                return 1;
        }
        else if (do_quad_tri_speedup && (a == 4)) {
                float vec1[3], vec2[3];
 
-               eve = fillvertbase.first;
+               eve = sf_ctx->fillvertbase.first;
                /* no need to check 'eve->next->next->next' is valid, already counted */
                /*use shortest diagonal for quad*/
                sub_v3_v3v3(vec1, eve->co, eve->next->next->co);
                sub_v3_v3v3(vec2, eve->next->co, eve->next->next->next->co);
 
                if (dot_v3v3(vec1, vec1) < dot_v3v3(vec2, vec2)) {
-                       addfillface(eve, eve->next, eve->next->next);
-                       addfillface(eve->next->next, eve->next->next->next, eve);
+                       addfillface(sf_ctx, eve, eve->next, eve->next->next);
+                       addfillface(sf_ctx, eve->next->next, eve->next->next->next, eve);
                }
                else {
-                       addfillface(eve->next, eve->next->next, eve->next->next->next);
-                       addfillface(eve->next->next->next, eve, eve->next);
+                       addfillface(sf_ctx, eve->next, eve->next->next, eve->next->next->next);
+                       addfillface(sf_ctx, eve->next->next->next, eve, eve->next);
                }
                return 2;
        }
 
        /* first test vertices if they are in edges */
        /* including resetting of flags */
-       eed = filledgebase.first;
+       eed = sf_ctx->filledgebase.first;
        while (eed) {
                eed->poly_nr = 0;
                eed->v1->f = 1;
@@ -862,7 +839,7 @@ int BLI_edgefill(const short do_quad_tri_speedup)
                eed = eed->next;
        }
 
-       eve = fillvertbase.first;
+       eve = sf_ctx->fillvertbase.first;
        while (eve) {
                if (eve->f & 1) {
                        ok = 1;
@@ -878,11 +855,11 @@ int BLI_edgefill(const short do_quad_tri_speedup)
        
        /* THIS PART STILL IS PRETTY WEAK! (ton) */
 
-       eve = fillvertbase.last;
+       eve = sf_ctx->fillvertbase.last;
        len = 0.0;
        v1 = eve->co;
        v2 = 0;
-       eve = fillvertbase.first;
+       eve = sf_ctx->fillvertbase.first;
        limit = 1e-8f;
 
        while (eve) {
@@ -905,11 +882,14 @@ int BLI_edgefill(const short do_quad_tri_speedup)
 
        if (len == 0.0f) return 0;  /* no fill possible */
 
-       axis_dominant_v3(&cox, &coy, norm);
+       axis_dominant_v3(&co_x, &co_y, norm);
 
        /* STEP 1: COUNT POLYS */
-       eve = fillvertbase.first;
+       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++;
@@ -921,8 +901,8 @@ int BLI_edgefill(const short do_quad_tri_speedup)
                                
                                ok = 0;
                                toggle++;
-                               if (toggle & 1) eed = filledgebase.first;
-                               else eed = filledgebase.last;
+                               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) {
@@ -951,7 +931,7 @@ int BLI_edgefill(const short do_quad_tri_speedup)
        /* printf("amount of poly's: %d\n",poly); */
 
        /* STEP 2: remove loose edges and strings of edges */
-       eed = filledgebase.first;
+       eed = sf_ctx->filledgebase.first;
        while (eed) {
                if (eed->v1->h++ > 250) break;
                if (eed->v2->h++ > 250) break;
@@ -964,33 +944,33 @@ int BLI_edgefill(const short do_quad_tri_speedup)
        }
        
        /* does it only for vertices with ->h==1 */
-       testvertexnearedge();
+       testvertexnearedge(sf_ctx);
 
        ok = 1;
        while (ok) {
                ok = 0;
                toggle++;
-               if (toggle & 1) eed = filledgebase.first;
-               else eed = filledgebase.last;
+               if (toggle & 1) eed = sf_ctx->filledgebase.first;
+               else eed = sf_ctx->filledgebase.last;
                while (eed) {
                        if (toggle & 1) nexted = eed->next;
                        else nexted = eed->prev;
                        if (eed->v1->h == 1) {
                                eed->v2->h--;
-                               BLI_remlink(&fillvertbase, eed->v1);
-                               BLI_remlink(&filledgebase, eed);
+                               BLI_remlink(&sf_ctx->fillvertbase, eed->v1);
+                               BLI_remlink(&sf_ctx->filledgebase, eed);
                                ok = 1;
                        }
                        else if (eed->v2->h == 1) {
                                eed->v1->h--;
-                               BLI_remlink(&fillvertbase, eed->v2);
-                               BLI_remlink(&filledgebase, eed);
+                               BLI_remlink(&sf_ctx->fillvertbase, eed->v2);
+                               BLI_remlink(&sf_ctx->filledgebase, eed);
                                ok = 1;
                        }
                        eed = nexted;
                }
        }
-       if (filledgebase.first == 0) {
+       if (sf_ctx->filledgebase.first == 0) {
                /* printf("All edges removed\n"); */
                return 0;
        }
@@ -1012,26 +992,26 @@ int BLI_edgefill(const short do_quad_tri_speedup)
        pf = pflist;
        for (a = 1; a <= poly; a++) {
                pf->nr = a;
-               pf->min[0] = pf->min[1] = pf->min[2] = 1.0e20;
-               pf->max[0] = pf->max[1] = pf->max[2] = -1.0e20;
+               pf->min_xy[0] = pf->min_xy[1] =  1.0e20;
+               pf->max_xy[0] = pf->max_xy[1] = -1.0e20;
                pf++;
        }
-       eed = filledgebase.first;
+       eed = sf_ctx->filledgebase.first;
        while (eed) {
                pflist[eed->poly_nr - 1].edges++;
                eed = eed->next;
        }
 
-       eve = fillvertbase.first;
+       eve = sf_ctx->fillvertbase.first;
        while (eve) {
                pflist[eve->poly_nr - 1].verts++;
-               minp = pflist[eve->poly_nr - 1].min;
-               maxp = pflist[eve->poly_nr - 1].max;
+               min_xy_p = pflist[eve->poly_nr - 1].min_xy;
+               max_xy_p = pflist[eve->poly_nr - 1].max_xy;
 
-               minp[cox] = (minp[cox]) < (eve->co[cox]) ? (minp[cox]) : (eve->co[cox]);
-               minp[coy] = (minp[coy]) < (eve->co[coy]) ? (minp[coy]) : (eve->co[coy]);
-               maxp[cox] = (maxp[cox]) > (eve->co[cox]) ? (maxp[cox]) : (eve->co[cox]);
-               maxp[coy] = (maxp[coy]) > (eve->co[coy]) ? (maxp[coy]) : (eve->co[coy]);
+               min_xy_p[0] = (min_xy_p[0]) < (eve->xy[0]) ? (min_xy_p[0]) : (eve->xy[0]);
+               min_xy_p[1] = (min_xy_p[1]) < (eve->xy[1]) ? (min_xy_p[1]) : (eve->xy[1]);
+               max_xy_p[0] = (max_xy_p[0]) > (eve->xy[0]) ? (max_xy_p[0]) : (eve->xy[0]);
+               max_xy_p[1] = (max_xy_p[1]) > (eve->xy[1]) ? (max_xy_p[1]) : (eve->xy[1]);
                if (eve->h > 2) pflist[eve->poly_nr - 1].f = 1;
 
                eve = eve->next;
@@ -1070,12 +1050,12 @@ int BLI_edgefill(const short do_quad_tri_speedup)
                                        pc++;
                                }
                                /* only for optimize! */
-                               /* else if (pf->max[cox] < (pflist+c)->min[cox]) break; */
+                               /* else if (pf->max_xy[0] < (pflist+c)->min[cox]) break; */
                                
                        }
                        while (pc != polycache) {
                                pc--;
-                               mergepolysSimp(pf, pflist + *pc);
+                               mergepolysSimp(sf_ctx, pf, pflist + *pc);
                        }
                }
                MEM_freeN(polycache);
@@ -1092,23 +1072,23 @@ int BLI_edgefill(const short do_quad_tri_speedup)
 
        /* STEP 5: MAKE TRIANGLES */
 
-       tempve.first = fillvertbase.first;
-       tempve.last = fillvertbase.last;
-       temped.first = filledgebase.first;
-       temped.last = filledgebase.last;
-       fillvertbase.first = fillvertbase.last = 0;
-       filledgebase.first = filledgebase.last = 0;
+       tempve.first = sf_ctx->fillvertbase.first;
+       tempve.last = sf_ctx->fillvertbase.last;
+       temped.first = sf_ctx->filledgebase.first;
+       temped.last = sf_ctx->filledgebase.last;
+       sf_ctx->fillvertbase.first = sf_ctx->fillvertbase.last = NULL;
+       sf_ctx->filledgebase.first = sf_ctx->filledgebase.last = NULL;
 
        pf = pflist;
        for (a = 0; a < poly; a++) {
                if (pf->edges > 1) {
-                       splitlist(&tempve, &temped, pf->nr);
-                       totfaces += scanfill(pf);
+                       splitlist(sf_ctx, &tempve, &temped, pf->nr);
+                       totfaces += scanfill(sf_ctx, pf);
                }
                pf++;
        }
-       BLI_movelisttolist(&fillvertbase, &tempve);
-       BLI_movelisttolist(&filledgebase, &temped);
+       BLI_movelisttolist(&sf_ctx->fillvertbase, &tempve);
+       BLI_movelisttolist(&sf_ctx->filledgebase, &temped);
 
        /* FREE */
 
index 19d9c2a9c65e3d5fbba44db0e59f73b7b452526d..05d8ded7764467ae0e7afbf7ae5f18cb086b2f7c 100644 (file)
@@ -115,7 +115,6 @@ static pthread_mutex_t _rcache_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t _opengl_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t _nodes_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t _movieclip_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t _scanfill_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_t mainid;
 static int thread_levels= 0;   /* threads can be invoked inside threads */
 
@@ -354,8 +353,6 @@ void BLI_lock_thread(int type)
                pthread_mutex_lock(&_nodes_lock);
        else if (type==LOCK_MOVIECLIP)
                pthread_mutex_lock(&_movieclip_lock);
-       else if (type == LOCK_SCANFILL)
-               pthread_mutex_lock(&_scanfill_lock);
 }
 
 void BLI_unlock_thread(int type)
@@ -376,8 +373,6 @@ void BLI_unlock_thread(int type)
                pthread_mutex_unlock(&_nodes_lock);
        else if (type==LOCK_MOVIECLIP)
                pthread_mutex_unlock(&_movieclip_lock);
-       else if (type == LOCK_SCANFILL)
-               pthread_mutex_unlock(&_scanfill_lock);
 }
 
 /* Mutex Locks */
index 0f7c45470e9cd06ce1c5454fc8eca68219ffaf55..7d07dc075da7c4e1c9e40d1f289f72edd8de7004 100644 (file)
  */
 
 #include "MEM_guardedalloc.h"
+#include "DNA_listBase.h"
 
-#include "BLI_scanfill.h"
 #include "BLI_math.h"
 #include "BLI_array.h"
 #include "BLI_smallhash.h"
+#include "BLI_scanfill.h"
 
 #include "bmesh.h"
 #include "intern/bmesh_private.h"
@@ -164,6 +165,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
        BMOIter siter;
        BMEdge *e;
        BMOperator bmop;
+       ScanFillContext sf_ctx;
        /* ScanFillEdge *eed; */ /* UNUSED */
        ScanFillVert *eve, *v1, *v2;
        ScanFillFace *efa;
@@ -171,32 +173,32 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
 
        BLI_smallhash_init(&hash);
        
-       BLI_begin_edgefill();
+       BLI_begin_edgefill(&sf_ctx);
        
        BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
                BMO_elem_flag_enable(bm, e, EDGE_MARK);
                
                if (!BLI_smallhash_haskey(&hash, (uintptr_t)e->v1)) {
-                       eve = BLI_addfillvert(e->v1->co);
+                       eve = BLI_addfillvert(&sf_ctx, e->v1->co);
                        eve->tmp.p = e->v1;
                        BLI_smallhash_insert(&hash, (uintptr_t)e->v1, eve);
                }
                
                if (!BLI_smallhash_haskey(&hash, (uintptr_t)e->v2)) {
-                       eve = BLI_addfillvert(e->v2->co);
+                       eve = BLI_addfillvert(&sf_ctx, e->v2->co);
                        eve->tmp.p = e->v2;
                        BLI_smallhash_insert(&hash, (uintptr_t)e->v2, eve);
                }
                
                v1 = BLI_smallhash_lookup(&hash, (uintptr_t)e->v1);
                v2 = BLI_smallhash_lookup(&hash, (uintptr_t)e->v2);
-               /* eed = */ BLI_addfilledge(v1, v2);
+               /* eed = */ BLI_addfilledge(&sf_ctx, v1, v2);
                /* eed->tmp.p = e; */ /* UNUSED */
        }
        
-       BLI_edgefill(FALSE);
+       BLI_edgefill(&sf_ctx, FALSE);
        
-       for (efa = fillfacebase.first; efa; efa = efa->next) {
+       for (efa = sf_ctx.fillfacebase.first; efa; efa = efa->next) {
                BMFace *f = BM_face_create_quad_tri(bm,
                                                    efa->v1->tmp.p, efa->v2->tmp.p, efa->v3->tmp.p, NULL,
                                                    NULL, TRUE);
@@ -211,7 +213,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
                }
        }
        
-       BLI_end_edgefill();
+       BLI_end_edgefill(&sf_ctx);
        BLI_smallhash_release(&hash);
        
        /* clean up fill */
index 4ba8ff0492c88797e2c11e9a7b3c87f711d7ef97..bba5578ccc1e26c346eaaf2a0b4cb9fd172dd696 100644 (file)
@@ -1824,11 +1824,11 @@ static void knifenet_fill_faces(knifetool_opdata *kcd)
                if (face_nets[i].first)
                        BMO_elem_flag_enable(bm, f, DEL);
 
-               BLI_begin_edgefill();
+               BLI_begin_edgefill(&sf_ctx);
 
                for (entry = face_nets[i].first; entry; entry = entry->next) {
                        if (!BLI_smallhash_haskey(hash, (intptr_t)entry->kfe->v1)) {
-                               eve = BLI_addfillvert(entry->kfe->v1->v->co);
+                               eve = BLI_addfillvert(&sf_ctx, entry->kfe->v1->v->co);
                                eve->poly_nr = 0;
                                rnd_offset_co(eve->co, rndscale);
                                eve->tmp.p = entry->kfe->v1->v;
@@ -1836,7 +1836,7 @@ static void knifenet_fill_faces(knifetool_opdata *kcd)
                        }
 
                        if (!BLI_smallhash_haskey(hash, (intptr_t)entry->kfe->v2)) {
-                               eve = BLI_addfillvert(entry->kfe->v2->v->co);
+                               eve = BLI_addfillvert(&sf_ctx, entry->kfe->v2->v->co);
                                eve->poly_nr = 0;
                                rnd_offset_co(eve->co, rndscale);
                                eve->tmp.p = entry->kfe->v2->v;
@@ -1858,7 +1858,7 @@ static void knifenet_fill_faces(knifetool_opdata *kcd)
 
                        if (eve->poly_nr > 1 && lasteve->poly_nr > 1) {
                                ScanFillEdge *eed;
-                               eed = BLI_addfilledge(lasteve, eve);
+                               eed = BLI_addfilledge(&sf_ctx, lasteve, eve);
                                if (entry->kfe->oe)
                                        eed->f = FILLBOUNDARY;  /* mark as original boundary edge */
 
@@ -1873,7 +1873,7 @@ static void knifenet_fill_faces(knifetool_opdata *kcd)
                        }
                }
 
-               BLI_edgefill(FALSE);
+               BLI_edgefill(&sf_ctx, FALSE);
 
                for (efa = fillfacebase.first; efa; efa = efa->next) {
                        BMVert *v1 = efa->v3->tmp.p, *v2 = efa->v2->tmp.p, *v3 = efa->v1->tmp.p;
index e51b119253f30fad0a5444e328c383eeecd523f4..5b3c4f9cd97be9b75ac146bb8319c043eedc0984 100644 (file)
@@ -186,6 +186,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
                                            short implicit, short fill, short sel,
                                            short correct_aspect)
 {
+       ScanFillContext sf_ctx;
        ParamHandle *handle;
        BMFace *efa;
        BMLoop *l;
@@ -261,13 +262,13 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
                }
                else {
                        /* ngon - scanfill time! */
-                       BLI_begin_edgefill();
+                       BLI_begin_edgefill(&sf_ctx);
                        
                        firstv = lastv = NULL;
                        BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
                                int i;
                                
-                               v = BLI_addfillvert(l->v->co);
+                               v = BLI_addfillvert(&sf_ctx, l->v->co);
                                
                                /* add small random offset */
                                for (i = 0; i < 3; i++) {
@@ -277,7 +278,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
                                v->tmp.p = l;
 
                                if (lastv) {
-                                       BLI_addfilledge(lastv, v);
+                                       BLI_addfilledge(&sf_ctx, lastv, v);
                                }
 
                                lastv = v;
@@ -285,10 +286,10 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
                                        firstv = v;
                        }
 
-                       BLI_addfilledge(firstv, v);
+                       BLI_addfilledge(&sf_ctx, firstv, v);
 
-                       BLI_edgefill(TRUE);
-                       for (sefa = fillfacebase.first; sefa; sefa = sefa->next) {
+                       BLI_edgefill(&sf_ctx, TRUE);
+                       for (sefa = sf_ctx.fillfacebase.first; sefa; sefa = sefa->next) {
                                ls[0] = sefa->v1->tmp.p;
                                ls[1] = sefa->v2->tmp.p;
                                ls[2] = sefa->v3->tmp.p;
@@ -305,7 +306,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
                                param_face_add(handle, key, 3, vkeys, co, uv, pin, select);
                        }
 
-                       BLI_end_edgefill();
+                       BLI_end_edgefill(&sf_ctx);
                }
        }
 
index efc22f95cbc0bcf4775a3fdb51eaf6b77fc42d21..0add9106872af10daec75ead3ecddd0ec09485a3 100644 (file)
@@ -230,12 +230,13 @@ static void wm_gesture_draw_circle(wmGesture *gt)
 
 static void draw_filled_lasso(wmGesture *gt)
 {
+       ScanFillContext sf_ctx;
        ScanFillVert *v = NULL, *lastv = NULL, *firstv = NULL;
        ScanFillFace *efa;
        short *lasso = (short *)gt->customdata;
        int i;
        
-       BLI_begin_edgefill();
+       BLI_begin_edgefill(&sf_ctx);
        for (i = 0; i < gt->points; i++, lasso += 2) {
                float co[3];
 
@@ -243,22 +244,22 @@ static void draw_filled_lasso(wmGesture *gt)
                co[1] = (float)lasso[1];
                co[2] = 0.0f;
 
-               v = BLI_addfillvert(co);
+               v = BLI_addfillvert(&sf_ctx, co);
                if (lastv)
-                       /* e = */ /* UNUSED */ BLI_addfilledge(lastv, v);
+                       /* e = */ /* UNUSED */ BLI_addfilledge(&sf_ctx, lastv, v);
                lastv = v;
                if (firstv == NULL) firstv = v;
        }
        
        /* highly unlikely this will fail, but could crash if (gt->points == 0) */
        if (firstv) {
-               BLI_addfilledge(firstv, v);
-               BLI_edgefill(FALSE);
+               BLI_addfilledge(&sf_ctx, firstv, v);
+               BLI_edgefill(&sf_ctx, FALSE);
        
                glEnable(GL_BLEND);
                glColor4f(1.0, 1.0, 1.0, 0.05);
                glBegin(GL_TRIANGLES);
-               for (efa = fillfacebase.first; efa; efa = efa->next) {
+               for (efa = sf_ctx.fillfacebase.first; efa; efa = efa->next) {
                        glVertex2fv(efa->v1->co);
                        glVertex2fv(efa->v2->co);
                        glVertex2fv(efa->v3->co);
@@ -266,7 +267,7 @@ static void draw_filled_lasso(wmGesture *gt)
                glEnd();
                glDisable(GL_BLEND);
        
-               BLI_end_edgefill();
+               BLI_end_edgefill(&sf_ctx);
        }
 }
 
index 39651cea3ab4b094a56f5fe3b73db677ab851045..0c95ccea5d79f7003df5b370b9ea73a85592111e 100644 (file)
@@ -63,7 +63,7 @@
 #include "BKE_tracking.h" /* free tracking clipboard */
 
 #include "BLI_listbase.h"
-#include "BLI_scanfill.h"
+// #include "BLI_scanfill.h"
 #include "BLI_string.h"
 #include "BLI_utildefines.h"
 
@@ -383,8 +383,6 @@ void WM_exit_ext(bContext *C, const short do_python)
 
        BLF_exit();
 
-       BLI_scanfill_free(); /* the order this is called doesn't matter */
-
 #ifdef WITH_INTERNATIONAL
        BLF_free_unifont();
 #endif
index 140fdc7ff7ea8d99d5bf76808bae902e70bce48d..13daeec87befbd5f43661a4735e9b6b989215b4b 100644 (file)
@@ -59,7 +59,6 @@
 
 #include "BLI_args.h"
 #include "BLI_threads.h"
-#include "BLI_scanfill.h" /* for BLI_setErrorCallBack, TODO, move elsewhere */
 #include "BLI_utildefines.h"
 #include "BLI_callbacks.h"
 
 #include "GPU_draw.h"
 #include "GPU_extensions.h"
 
+#include "BLI_scanfill.h" /* for BLI_setErrorCallBack, TODO, move elsewhere */
+
 #ifdef WITH_BUILDINFO_HEADER
 #define BUILD_DATE
 #endif