2.5
authorTon Roosendaal <ton@blender.org>
Thu, 1 Jan 2009 19:18:03 +0000 (19:18 +0000)
committerTon Roosendaal <ton@blender.org>
Thu, 1 Jan 2009 19:18:03 +0000 (19:18 +0000)
- View3D backbuffer select is back ("occlusion select").
  It doesn't use the old 'afterqueue' yet, which ensured backbuffers
  to draw immediate after swapbuffers. Will with that.

source/blender/editors/include/ED_mesh.h
source/blender/editors/include/ED_view3d.h
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_select.c

index 17ef2c1d1cd0fd1e237064fce807097aef38aa3c..b210ce82acbb2b9883a4642debf1f93320891247 100644 (file)
@@ -123,10 +123,10 @@ extern unsigned int em_vertoffs, em_solidoffs, em_wireoffs;
 
 void           mouse_mesh(struct bContext *C, short mval[2], short extend);
 int                    EM_check_backbuf(unsigned int index);
-int                    EM_mask_init_backbuf_border(struct View3D *v3d, short mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax);
+int                    EM_mask_init_backbuf_border(struct ViewContext *vc, short mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax);
 void           EM_free_backbuf(void);
-int                    EM_init_backbuf_border(struct View3D *v3d, short xmin, short ymin, short xmax, short ymax);
-int                    EM_init_backbuf_circle(struct View3D *v3d, short xs, short ys, short rads);
+int                    EM_init_backbuf_border(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax);
+int                    EM_init_backbuf_circle(struct ViewContext *vc, short xs, short ys, short rads);
 
 
 #endif /* ED_MESH_H */
index 50ec1956425d683933edfd6139e9307f74487091..e2fae03ac2989b3fb8a024acb0db21f7f28da962 100644 (file)
@@ -38,6 +38,7 @@ struct BezTriple;
 struct EditVert;
 struct EditEdge;
 struct EditFace;
+struct ImBuf;
 
 float *give_cursor(Scene *scene, View3D *v3d);
 
@@ -68,7 +69,10 @@ void lattice_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userDa
 int view3d_test_clipping(struct View3D *v3d, float *vec);
 void view3d_align_axis_to_vector(struct View3D *v3d, int axisidx, float vec[3]);
 
-
+/* backbuffer select and draw support */
+struct ImBuf *view3d_read_backbuf(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax);
+unsigned int view3d_sample_backbuf_rect(struct ViewContext *vc, short mval[2], int size, unsigned int min, unsigned int max, int *dist, short strict, unsigned int (*indextest)(unsigned int index));
+unsigned int view3d_sample_backbuf(struct ViewContext *vc, int x, int y);
 
 #endif /* ED_VIEW3D_H */
 
index c62c64564f48da5ec70e1bd6b081ffc328c59e4c..fb7bb46982a8a39f73ae9cdbc8c62d1a17c134e8 100644 (file)
@@ -91,9 +91,6 @@ editmesh_mods.c, UI level access, no geometry changes
 
 #include "BLO_sys_types.h" // for intptr_t support
 
-static void *read_backbuf() {return NULL;}
-static int sample_backbuf_rect() {return 0;}
-static int sample_backbuf() {return 0;}
 static void BIF_undo_push() {}
 static void waitcursor() {}
 static void error() {}
@@ -191,17 +188,17 @@ static void draw_triangulated(short mcords[][2], short tot)
 
 /* reads rect, and builds selection array for quick lookup */
 /* returns if all is OK */
-int EM_init_backbuf_border(View3D *v3d, short xmin, short ymin, short xmax, short ymax)
+int EM_init_backbuf_border(ViewContext *vc, short xmin, short ymin, short xmax, short ymax)
 {
        struct ImBuf *buf;
        unsigned int *dr;
        int a;
        
-       if(G.obedit==NULL || v3d->drawtype<OB_SOLID || (v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
-       if(em_vertoffs==0) return 0;
+       if(G.obedit==NULL || vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
        
-       buf= read_backbuf(xmin, ymin, xmax, ymax);
+       buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
        if(buf==NULL) return 0;
+       if(em_vertoffs==0) return 0;
 
        dr = buf->rect;
        
@@ -238,7 +235,7 @@ void EM_free_backbuf(void)
    - grab again and compare
    returns 'OK' 
 */
-int EM_mask_init_backbuf_border(View3D *v3d, short mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax)
+int EM_mask_init_backbuf_border(ViewContext *vc, short mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax)
 {
        unsigned int *dr, *drm;
        struct ImBuf *buf, *bufmask;
@@ -249,11 +246,11 @@ int EM_mask_init_backbuf_border(View3D *v3d, short mcords[][2], short tot, short
                if(FACESEL_PAINT_TEST);
                else return 0;
        }
-       else if(v3d->drawtype<OB_SOLID || (v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
+       else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
 
        if(em_vertoffs==0) return 0;
        
-       buf= read_backbuf(xmin, ymin, xmax, ymax);
+       buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
        if(buf==NULL) return 0;
 
        dr = buf->rect;
@@ -280,7 +277,7 @@ int EM_mask_init_backbuf_border(View3D *v3d, short mcords[][2], short tot, short
        glDrawBuffer(GL_BACK);
        
        /* grab mask */
-       bufmask= read_backbuf(xmin, ymin, xmax, ymax);
+       bufmask= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
        drm = bufmask->rect;
        if(bufmask==NULL) return 0; /* only when mem alloc fails, go crash somewhere else! */
        
@@ -299,7 +296,7 @@ int EM_mask_init_backbuf_border(View3D *v3d, short mcords[][2], short tot, short
 }
 
 /* circle shaped sample area */
-int EM_init_backbuf_circle(View3D *v3d, short xs, short ys, short rads)
+int EM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads)
 {
        struct ImBuf *buf;
        unsigned int *dr;
@@ -311,12 +308,12 @@ int EM_init_backbuf_circle(View3D *v3d, short xs, short ys, short rads)
                if(FACESEL_PAINT_TEST);
                else return 0;
        }
-       else if(v3d->drawtype<OB_SOLID || (v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
+       else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
        if(em_vertoffs==0) return 0;
        
        xmin= xs-rads; xmax= xs+rads;
        ymin= ys-rads; ymax= ys+rads;
-       buf= read_backbuf(xmin, ymin, xmax, ymax);
+       buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
        if(buf==NULL) return 0;
 
        dr = buf->rect;
@@ -393,8 +390,8 @@ EditVert *findnearestvert(ViewContext *vc, int *dist, short sel, short strict)
                unsigned int index;
                EditVert *eve;
                
-               if(strict) index = sample_backbuf_rect(vc->mval, 50, em_wireoffs, 0xFFFFFF, &distance, strict, findnearestvert__backbufIndextest); 
-               else index = sample_backbuf_rect(vc->mval, 50, em_wireoffs, 0xFFFFFF, &distance, 0, NULL); 
+               if(strict) index = view3d_sample_backbuf_rect(vc, vc->mval, 50, em_wireoffs, 0xFFFFFF, &distance, strict, findnearestvert__backbufIndextest); 
+               else index = view3d_sample_backbuf_rect(vc, vc->mval, 50, em_wireoffs, 0xFFFFFF, &distance, 0, NULL); 
                
                eve = BLI_findlink(&vc->em->verts, index-1);
                
@@ -496,7 +493,7 @@ EditEdge *findnearestedge(ViewContext *vc, int *dist)
 
        if(vc->v3d->drawtype>OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) {
                int distance;
-               unsigned int index = sample_backbuf_rect(vc->mval, 50, em_solidoffs, em_wireoffs, &distance,0, NULL);
+               unsigned int index = view3d_sample_backbuf_rect(vc, vc->mval, 50, em_solidoffs, em_wireoffs, &distance,0, NULL);
                EditEdge *eed = BLI_findlink(&vc->em->edges, index-1);
 
                if (eed && distance<*dist) {
@@ -559,7 +556,7 @@ static EditFace *findnearestface(ViewContext *vc, int *dist)
 {
 
        if(vc->v3d->drawtype>OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) {
-               unsigned int index = sample_backbuf(vc->mval[0], vc->mval[1]);
+               unsigned int index = view3d_sample_backbuf(vc, vc->mval[0], vc->mval[1]);
                EditFace *efa = BLI_findlink(&vc->em->faces, index-1);
 
                if (efa) {
index 04fb9a65cef530532e5a68768d7de263ed3a3d28..70435e54e9da3aeb0a904e1f7038595be639c050 100644 (file)
@@ -5363,7 +5363,7 @@ static void bbs_mesh_solid(Object *ob)
        dm->release(dm);
 }
 
-void draw_object_backbufsel(Scene *scene, View3D *v3d, EditMesh *em, Object *ob)
+void draw_object_backbufsel(Scene *scene, View3D *v3d, Object *ob)
 {
 
        wmMultMatrix(ob->obmat);
@@ -5374,6 +5374,8 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, EditMesh *em, Object *ob)
        switch( ob->type) {
        case OB_MESH:
                if(ob==G.obedit) {
+                       Mesh *me= ob->data;
+                       EditMesh *em= me->edit_mesh;
                        DerivedMesh *dm = editmesh_get_derived_cage(em, CD_MASK_BAREMESH);
 
                        EM_init_index_arrays(em, 1, 1, 1);
index d2f9831ec6e0431c49b0b458ba2f23dc701d1e2a..ad18f6675a38b75999a6c28f2bb6d8c467367159 100644 (file)
@@ -71,6 +71,7 @@
 #include "WM_api.h"
 
 #include "ED_keyframing.h"
+#include "ED_mesh.h"
 #include "ED_screen.h"
 #include "ED_util.h"
 #include "ED_types.h"
@@ -1037,6 +1038,239 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
        
 }
 
+/* *********************** backdraw for selection *************** */
+
+void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
+{
+       struct Base *base;
+
+/*for 2.43 release, don't use glext and just define the constant.
+  this to avoid possibly breaking platforms before release.*/
+#ifndef GL_MULTISAMPLE_ARB
+       #define GL_MULTISAMPLE_ARB      0x809D
+#endif
+
+#ifdef GL_MULTISAMPLE_ARB
+       int m;
+#endif
+
+       if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT || G.f & G_TEXTUREPAINT);
+       else if(G.obedit && v3d->drawtype>OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT));
+       else {
+               v3d->flag &= ~V3D_NEEDBACKBUFDRAW;
+               return;
+       }
+
+       if( !(v3d->flag & V3D_NEEDBACKBUFDRAW) ) return;
+
+//     if(test) {
+//             if(qtest()) {
+//                     addafterqueue(ar->win, BACKBUFDRAW, 1);
+//                     return;
+//             }
+//     }
+
+       /* Disable FSAA for backbuffer selection.  
+       
+       Only works if GL_MULTISAMPLE_ARB is defined by the header
+       file, which is should be for every OS that supports FSAA.*/
+
+#ifdef GL_MULTISAMPLE_ARB
+       m = glIsEnabled(GL_MULTISAMPLE_ARB);
+       if (m) glDisable(GL_MULTISAMPLE_ARB);
+#endif
+
+       if(v3d->drawtype > OB_WIRE) v3d->zbuf= TRUE;
+//     ar->win_swap &= ~WIN_BACK_OK;
+       
+       glDisable(GL_DITHER);
+
+       glClearColor(0.0, 0.0, 0.0, 0.0); 
+       if(v3d->zbuf) {
+               glEnable(GL_DEPTH_TEST);
+               glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+       }
+       else {
+               glClear(GL_COLOR_BUFFER_BIT);
+               glDisable(GL_DEPTH_TEST);
+       }
+       
+       if(v3d->flag & V3D_CLIPPING)
+               view3d_set_clipping(v3d);
+       
+       G.f |= G_BACKBUFSEL;
+       
+       base= (G.scene->basact);
+       if(base && (base->lay & v3d->lay)) {
+               draw_object_backbufsel(scene, v3d, base->object);
+       }
+
+       v3d->flag &= ~V3D_NEEDBACKBUFDRAW;
+
+       G.f &= ~G_BACKBUFSEL;
+       v3d->zbuf= FALSE; 
+       glDisable(GL_DEPTH_TEST);
+       glEnable(GL_DITHER);
+
+       if(v3d->flag & V3D_CLIPPING)
+               view3d_clr_clipping();
+
+#ifdef GL_MULTISAMPLE_ARB
+       if (m) glEnable(GL_MULTISAMPLE_ARB);
+#endif
+
+       /* it is important to end a view in a transform compatible with buttons */
+//     persp(PERSP_WIN);  // set ortho
+
+}
+
+void check_backbuf(ViewContext *vc)
+{
+       if(vc->v3d->flag & V3D_NEEDBACKBUFDRAW)
+               backdrawview3d(vc->scene, vc->ar, vc->v3d);
+}
+
+/* samples a single pixel (copied from vpaint) */
+unsigned int view3d_sample_backbuf(ViewContext *vc, int x, int y)
+{
+       unsigned int col;
+       
+       if(x >= vc->ar->winx || y >= vc->ar->winy) return 0;
+       x+= vc->ar->winrct.xmin;
+       y+= vc->ar->winrct.ymin;
+       
+       check_backbuf(vc);
+
+       glReadPixels(x,  y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,  &col);
+       glReadBuffer(GL_BACK);  
+       
+       if(ENDIAN_ORDER==B_ENDIAN) SWITCH_INT(col);
+       
+       return WM_framebuffer_to_index(col);
+}
+
+/* reads full rect, converts indices */
+ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, short ymax)
+{
+       unsigned int *dr, *rd;
+       struct ImBuf *ibuf, *ibuf1;
+       int a;
+       short xminc, yminc, xmaxc, ymaxc, xs, ys;
+       
+       /* clip */
+       if(xmin<0) xminc= 0; else xminc= xmin;
+       if(xmax >= vc->ar->winx) xmaxc= vc->ar->winx-1; else xmaxc= xmax;
+       if(xminc > xmaxc) return NULL;
+
+       if(ymin<0) yminc= 0; else yminc= ymin;
+       if(ymax >= vc->ar->winy) ymaxc= vc->ar->winy-1; else ymaxc= ymax;
+       if(yminc > ymaxc) return NULL;
+       
+       ibuf= IMB_allocImBuf((xmaxc-xminc+1), (ymaxc-yminc+1), 32, IB_rect,0);
+
+       check_backbuf(vc); 
+       
+       glReadPixels(vc->ar->winrct.xmin+xminc, vc->ar->winrct.ymin+yminc, (xmaxc-xminc+1), (ymaxc-yminc+1), GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+       glReadBuffer(GL_BACK);  
+
+       if(ENDIAN_ORDER==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
+
+       a= (xmaxc-xminc+1)*(ymaxc-yminc+1);
+       dr= ibuf->rect;
+       while(a--) {
+               if(*dr) *dr= WM_framebuffer_to_index(*dr);
+               dr++;
+       }
+       
+       /* put clipped result back, if needed */
+       if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) 
+               return ibuf;
+       
+       ibuf1= IMB_allocImBuf( (xmax-xmin+1),(ymax-ymin+1),32,IB_rect,0);
+       rd= ibuf->rect;
+       dr= ibuf1->rect;
+               
+       for(ys= ymin; ys<=ymax; ys++) {
+               for(xs= xmin; xs<=xmax; xs++, dr++) {
+                       if( xs>=xminc && xs<=xmaxc && ys>=yminc && ys<=ymaxc) {
+                               *dr= *rd;
+                               rd++;
+                       }
+               }
+       }
+       IMB_freeImBuf(ibuf);
+       return ibuf1;
+}
+
+/* smart function to sample a rect spiralling outside, nice for backbuf selection */
+unsigned int view3d_sample_backbuf_rect(ViewContext *vc, short mval[2], int size, unsigned int min, unsigned int max, int *dist, short strict, unsigned int (*indextest)(unsigned int index))
+{
+       struct ImBuf *buf;
+       unsigned int *bufmin, *bufmax, *tbuf;
+       int minx, miny;
+       int a, b, rc, nr, amount, dirvec[4][2];
+       int distance=0;
+       unsigned int index = 0;
+       short indexok = 0;      
+
+       amount= (size-1)/2;
+
+       minx = mval[0]-(amount+1);
+       miny = mval[1]-(amount+1);
+       buf = view3d_read_backbuf(vc, minx, miny, minx+size-1, miny+size-1);
+       if (!buf) return 0;
+
+       rc= 0;
+       
+       dirvec[0][0]= 1; dirvec[0][1]= 0;
+       dirvec[1][0]= 0; dirvec[1][1]= -size;
+       dirvec[2][0]= -1; dirvec[2][1]= 0;
+       dirvec[3][0]= 0; dirvec[3][1]= size;
+       
+       bufmin = buf->rect;
+       tbuf = buf->rect;
+       bufmax = buf->rect + size*size;
+       tbuf+= amount*size+ amount;
+       
+       for(nr=1; nr<=size; nr++) {
+               
+               for(a=0; a<2; a++) {
+                       for(b=0; b<nr; b++, distance++) {
+                               if (*tbuf && *tbuf>=min && *tbuf<max) { //we got a hit
+                                       if(strict){
+                                               indexok =  indextest(*tbuf - min+1);
+                                               if(indexok){
+                                                       *dist= (short) sqrt( (float)distance   );
+                                                       index = *tbuf - min+1;
+                                                       goto exit; 
+                                               }                                               
+                                       }
+                                       else{
+                                               *dist= (short) sqrt( (float)distance ); // XXX, this distance is wrong - 
+                                               index = *tbuf - min+1; // messy yah, but indices start at 1
+                                               goto exit;
+                                       }                       
+                               }
+                               
+                               tbuf+= (dirvec[rc][0]+dirvec[rc][1]);
+                               
+                               if(tbuf<bufmin || tbuf>=bufmax) {
+                                       goto exit;
+                               }
+                       }
+                       rc++;
+                       rc &= 3;
+               }
+       }
+
+exit:
+       IMB_freeImBuf(buf);
+       return index;
+}
+
+
+/* ************************************************************* */
+
 static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
 {
        BGpic *bgpic;
@@ -1146,8 +1380,6 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
        
        glDisable(GL_BLEND);
        if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
-       
-       // XXX  areawinset(ar->win);    // restore viewport / scissor
 }
 
 /* ****************** View3d afterdraw *************** */
@@ -1786,8 +2018,6 @@ void drawview3dspace(Scene *scene, ARegion *ar, View3D *v3d)
        if(U.uiflag & USER_DRAWVIEWINFO) 
                draw_selected_name(scene, ob, v3d);
        
-//     draw_area_emboss(ar);
-       
        /* XXX here was the blockhandlers for floating panels */
 
        if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT || G.f & G_TEXTUREPAINT) {
index 60bc89304a163cdf660d5bd41cf8a1e695b3d53c..e68f0bd360ec081953ea5babce115640c94eb1ee 100644 (file)
@@ -85,6 +85,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag);
 int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt);
 void drawcircball(int mode, float *cent, float rad, float tmat[][4]);
 void draw_object_instance(Scene *scene, View3D *v3d, Object *ob, int dt, int outline);
+void draw_object_backbufsel(Scene *scene, View3D *v3d, Object *ob);
 void drawaxes(float size, int flag, char drawtype);
 
 /* drawarmature.c */
index 7a5442be2a8005830f1eb8c7fa12dc7ba65e6944..2359a5d35e464d845202252856bae9cf2c3b2568 100644 (file)
@@ -398,7 +398,7 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves
        data.done = 0;
        data.pass = 0;
 
-       bbsel= EM_mask_init_backbuf_border(vc->v3d, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+       bbsel= EM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
        
        if(vc->scene->selectmode & SCE_SELECT_VERTEX) {
                if (bbsel) {
@@ -589,7 +589,7 @@ static void do_lasso_select_facemode(ViewContext *vc, short mcords[][2], short m
        em_vertoffs= me->totface+1;     /* max index array */
        
        lasso_select_boundbox(&rect, mcords, moves);
-       EM_mask_init_backbuf_border(vc->v3d, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+       EM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
        
        EM_backbuf_checkAndSelectTFaces(me, select);
        
@@ -1174,7 +1174,7 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select)
        data.pass = 0;
        data.done = 0;
 
-       bbsel= EM_init_backbuf_border(vc->v3d, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+       bbsel= EM_init_backbuf_border(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
 
        if(vc->scene->selectmode & SCE_SELECT_VERTEX) {
                if (bbsel) {
@@ -1222,6 +1222,8 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
        int a, index;
        short hits, val;
 
+       view3d_operator_needs_opengl(C);
+       
        /* setup view context for argument to callbacks */
        memset(&vc, 0, sizeof(ViewContext));
        vc.ar= ar;
@@ -1547,7 +1549,7 @@ static void mesh_selectionCB(ViewContext *vc, int selecting, Object *editobj, sh
                if (me) {
                        em_vertoffs= me->totface+1;     /* max index array */
 
-                       bbsel= EM_init_backbuf_circle(vc->v3d, mval[0], mval[1], (short)(rad+1.0));
+                       bbsel= EM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0));
                        EM_backbuf_checkAndSelectTFaces(me, selecting==LEFTMOUSE);
                        EM_free_backbuf();
 
@@ -1557,7 +1559,7 @@ static void mesh_selectionCB(ViewContext *vc, int selecting, Object *editobj, sh
                return;
        }
 
-       bbsel= EM_init_backbuf_circle(vc->v3d, mval[0], mval[1], (short)(rad+1.0));
+       bbsel= EM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0));
        
        data.select = (selecting==LEFTMOUSE);
        data.mval[0] = mval[0];