From 061442cbd1e69ad494eb22a69a2ae89e72e9d978 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 27 Sep 2004 10:12:45 +0000 Subject: [PATCH] - improvement for edge/face select - edges now sample on three locationsm gives more hits - own version of glPolygonOffset remains cumbersome... but for select now the selection routine gets more offset than draw. - first attempt to clean drawobject.c and displists - generic call for draw object in backbuf for select purposes, cleans up a lot in the other calls. - also to verify if we can (in future) use this for vertex/edge/face select, but the whole drawobject code works against me... this is for another refactory (incl. displist) and out of the focus for now - subsurf.c: now creates new faces in order of original. Not used yet, but is handy to recover the original order for selection/paint purposes. --- source/blender/blenkernel/intern/subsurf.c | 12 +- source/blender/include/BDR_drawobject.h | 1 + source/blender/src/drawmesh.c | 4 +- source/blender/src/drawobject.c | 582 +++++++++++---------- source/blender/src/drawview.c | 2 +- source/blender/src/editmesh_mods.c | 47 +- source/blender/src/editview.c | 20 +- source/blender/src/glutil.c | 10 +- 8 files changed, 389 insertions(+), 289 deletions(-) diff --git a/source/blender/blenkernel/intern/subsurf.c b/source/blender/blenkernel/intern/subsurf.c index 280af7c4a53..00070fef72c 100644 --- a/source/blender/blenkernel/intern/subsurf.c +++ b/source/blender/blenkernel/intern/subsurf.c @@ -215,6 +215,7 @@ struct _HyperMesh { HyperVert *verts; HyperEdge *edges; HyperFace *faces; + HyperFace *lastface; // we add faces in same order they get delivered now (ton) Mesh *orig_me; short hasuvco, hasvcol; @@ -322,9 +323,12 @@ static HyperFace *hypermesh_add_face(HyperMesh *hme, HyperVert **verts, int nver last= v; } - f->next= hme->faces; - hme->faces= f; - + // less elegant, but for many reasons i prefer the order of faces to remain same (vpaint etc) (ton) + f->next= NULL; + if(hme->lastface) hme->lastface->next= f; + else hme->faces= f; + hme->lastface= f; + return f; } @@ -333,7 +337,7 @@ static HyperMesh *hypermesh_new(void) { hme->verts= NULL; hme->edges= NULL; - hme->faces= NULL; + hme->faces= hme->lastface= NULL; hme->orig_me= NULL; hme->hasuvco= hme->hasvcol= 0; hme->arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); diff --git a/source/blender/include/BDR_drawobject.h b/source/blender/include/BDR_drawobject.h index 6cdcefd23ce..77afe41e73b 100644 --- a/source/blender/include/BDR_drawobject.h +++ b/source/blender/include/BDR_drawobject.h @@ -60,6 +60,7 @@ void drawcircball(float *cent, float rad, float tmat[][4]); void get_local_bounds(struct Object *ob, float *centre, float *size); void draw_object(struct Base *base); void draw_object_ext(struct Base *base); +extern void draw_object_backbufsel(struct Object *ob); #ifdef __cplusplus } diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c index e45a288f9ff..c3d9ce0fdf4 100644 --- a/source/blender/src/drawmesh.c +++ b/source/blender/src/drawmesh.c @@ -507,7 +507,7 @@ void draw_tfaces3D(Object *ob, Mesh *me) glEnable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); - bglPolygonOffset(G.vd->dist); + bglPolygonOffset(1.0); /* Draw (Hidden) Edges */ if(G.f & G_DRAWEDGES || G.f & G_HIDDENEDGES){ @@ -631,7 +631,7 @@ void draw_tfaces3D(Object *ob, Mesh *me) /* Draw Stippled Outline for selected faces */ mface= me->mface; tface= me->tface; - bglPolygonOffset(G.vd->dist); + bglPolygonOffset(1.0); for(a=me->totface; a>0; a--, mface++, tface++) { if(mface->v3==0) continue; if(tface->flag & TF_HIDE) continue; diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 75a6062ed3e..412f8be3f5c 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -705,7 +705,6 @@ void drawcamera(Object *ob) glEnd(); if(G.vd->persp>=2) return; - if(G.f & G_BACKBUFSEL) return; /* arrow on top */ vec[0][2]= depth; @@ -1276,13 +1275,13 @@ static void displistmesh_draw_wire(DispListMesh *dlm) } } -static void displistmesh_draw_solid(DispListMesh *dlm, int drawsmooth, float *nors) +static void displistmesh_draw_solid(DispListMesh *dlm, float *nors) { int lmode, lshademodel= -1, lmat_nr= -1; int i; #define PASSVERT(ind) { \ - if (drawsmooth && lshademodel==GL_SMOOTH) \ + if (lshademodel==GL_SMOOTH) \ glNormal3sv(dlm->mvert[(ind)].no); \ glVertex3fv(dlm->mvert[(ind)].co); \ } @@ -1293,29 +1292,26 @@ static void displistmesh_draw_solid(DispListMesh *dlm, int drawsmooth, float *no if (mf->v3) { int nmode= mf->v4?GL_QUADS:GL_TRIANGLES; + int nshademodel= (mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT; if (nmode!=lmode) { glEnd(); glBegin(lmode= nmode); } - if (drawsmooth) { - int nshademodel= (mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT; - - if (nshademodel!=lshademodel) { - glEnd(); - glShadeModel(lshademodel= nshademodel); - glBegin(lmode); - } - - if (mf->mat_nr!=lmat_nr) { - glEnd(); - set_gl_material((lmat_nr= mf->mat_nr)+1); - glBegin(lmode); - } + if (nshademodel!=lshademodel) { + glEnd(); + glShadeModel(lshademodel= nshademodel); + glBegin(lmode); } - if (drawsmooth && lshademodel==GL_FLAT) + if (mf->mat_nr!=lmat_nr) { + glEnd(); + set_gl_material((lmat_nr= mf->mat_nr)+1); + glBegin(lmode); + } + + if (lshademodel==GL_FLAT) glNormal3fv(&nors[i*3]); PASSVERT(mf->v1); @@ -1502,18 +1498,14 @@ static void drawDispListsolid(ListBase *lb, Object *ob) int parts, ofs, p1, p2, p3, p4, a, b, *index; float *data, *v1, *v2, *v3, *v4; float *ndata, *n1, *n2, *n3, *n4; - int drawsmooth= !(G.f & G_BACKBUFSEL); if(lb==0) return; - /* drawsmooth abused here, except for Mesh this draws with smooth default */ - if (drawsmooth) { - glShadeModel(GL_SMOOTH); - glEnable(GL_LIGHTING); - - if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW); - else glFrontFace(GL_CCW); - } + glShadeModel(GL_SMOOTH); + glEnable(GL_LIGHTING); + + if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW); + else glFrontFace(GL_CCW); dl= lb->first; while(dl) { @@ -1522,70 +1514,40 @@ static void drawDispListsolid(ListBase *lb, Object *ob) switch(dl->type) { case DL_SURF: - if(!drawsmooth) { - for(a=0; aparts; a++) { - - DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts); - - v1= data+ 3*p1; - v2= data+ 3*p2; - v3= data+ 3*p3; - v4= data+ 3*p4; - - glBegin(GL_QUAD_STRIP); - - glVertex3fv(v2); - glVertex3fv(v4); - for(; bnr; b++) { - - glVertex3fv(v1); - glVertex3fv(v3); + set_gl_material(dl->col+1); - v2= v1; v1+= 3; - v4= v3; v3+= 3; - } + for(a=0; aparts; a++) { + + DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts); + + v1= data+ 3*p1; + v2= data+ 3*p2; + v3= data+ 3*p3; + v4= data+ 3*p4; + n1= ndata+ 3*p1; + n2= ndata+ 3*p2; + n3= ndata+ 3*p3; + n4= ndata+ 3*p4; + + glBegin(GL_QUAD_STRIP); + + glNormal3fv(n2); glVertex3fv(v2); + glNormal3fv(n4); glVertex3fv(v4); + + for(; bnr; b++) { - - glEnd(); - } - } - else { - - set_gl_material(dl->col+1); - - for(a=0; aparts; a++) { - - DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts); - - v1= data+ 3*p1; - v2= data+ 3*p2; - v3= data+ 3*p3; - v4= data+ 3*p4; - n1= ndata+ 3*p1; - n2= ndata+ 3*p2; - n3= ndata+ 3*p3; - n4= ndata+ 3*p4; - - glBegin(GL_QUAD_STRIP); - - glNormal3fv(n2); glVertex3fv(v2); - glNormal3fv(n4); glVertex3fv(v4); - - for(; bnr; b++) { - - glNormal3fv(n1); glVertex3fv(v1); - glNormal3fv(n3); glVertex3fv(v3); - - v2= v1; v1+= 3; - v4= v3; v3+= 3; - n2= n1; n1+= 3; - n4= n3; n3+= 3; - } - - - glEnd(); + glNormal3fv(n1); glVertex3fv(v1); + glNormal3fv(n3); glVertex3fv(v3); + + v2= v1; v1+= 3; + v4= v3; v3+= 3; + n2= n1; n1+= 3; + n4= n3; n3+= 3; } + + + glEnd(); } break; @@ -1595,11 +1557,15 @@ static void drawDispListsolid(ListBase *lb, Object *ob) data= dl->verts; ndata= dl->nors; index= dl->index; - - if(!drawsmooth) { + + set_gl_material(dl->col+1); + + /* voor polys only one normal needed */ + if(index3_nors_incr==0) { while(parts--) { glBegin(GL_TRIANGLES); + glNormal3fv(ndata); glVertex3fv(data+3*index[0]); glVertex3fv(data+3*index[1]); glVertex3fv(data+3*index[2]); @@ -1608,35 +1574,17 @@ static void drawDispListsolid(ListBase *lb, Object *ob) } } else { + while(parts--) { - set_gl_material(dl->col+1); - - /* voor polys only one normal needed */ - if(index3_nors_incr==0) { - while(parts--) { - - glBegin(GL_TRIANGLES); - glNormal3fv(ndata); - glVertex3fv(data+3*index[0]); - glVertex3fv(data+3*index[1]); - glVertex3fv(data+3*index[2]); - glEnd(); - index+= 3; - } - } - else { - while(parts--) { - - glBegin(GL_TRIANGLES); - ofs= 3*index[0]; - glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); - ofs= 3*index[1]; - glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); - ofs= 3*index[2]; - glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); - glEnd(); - index+= 3; - } + glBegin(GL_TRIANGLES); + ofs= 3*index[0]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + ofs= 3*index[1]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + ofs= 3*index[2]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + glEnd(); + index+= 3; } } break; @@ -1648,56 +1596,39 @@ static void drawDispListsolid(ListBase *lb, Object *ob) ndata= dl->nors; index= dl->index; - if(!drawsmooth) { - while(parts--) { + set_gl_material(dl->col+1); + + while(parts--) { - glBegin(index[3]?GL_QUADS:GL_TRIANGLES); - glVertex3fv(data+3*index[0]); - glVertex3fv(data+3*index[1]); - glVertex3fv(data+3*index[2]); - if(index[3]) glVertex3fv(data+3*index[3]); - glEnd(); - index+= 4; - } - } - else { - - set_gl_material(dl->col+1); - - while(parts--) { - - glBegin(index[3]?GL_QUADS:GL_TRIANGLES); - ofs= 3*index[0]; + glBegin(index[3]?GL_QUADS:GL_TRIANGLES); + ofs= 3*index[0]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + ofs= 3*index[1]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + ofs= 3*index[2]; + glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); + if(index[3]) { + ofs= 3*index[3]; glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); - ofs= 3*index[1]; - glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); - ofs= 3*index[2]; - glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); - if(index[3]) { - ofs= 3*index[3]; - glNormal3fv(ndata+ofs); glVertex3fv(data+ofs); - } - glEnd(); - index+= 4; - } + } + glEnd(); + index+= 4; } break; case DL_MESH: if (!dl->nors) addnormalsDispList(ob, lb); - displistmesh_draw_solid(dl->mesh, drawsmooth, dl->nors); + displistmesh_draw_solid(dl->mesh, dl->nors); break; } dl= dl->next; } - if(drawsmooth) { - glShadeModel(GL_FLAT); - glDisable(GL_LIGHTING); - glFrontFace(GL_CCW); - } + glShadeModel(GL_FLAT); + glDisable(GL_LIGHTING); + glFrontFace(GL_CCW); } static void drawDispListshaded(ListBase *lb, Object *ob) @@ -1838,7 +1769,7 @@ static void drawmeshsolid(Object *ob, float *nors) MFace *mface; EditFace *efa; float *extverts=0, *v1, *v2, *v3, *v4; - int glmode, setsmooth=0, a, start, end, matnr= -1, vertexpaint, i; + int glmode, setsmooth=0, a, start, end, matnr= -1, vertexpaint; short no[3], *n1, *n2, *n3, *n4 = NULL; vertexpaint= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0)); @@ -1848,15 +1779,13 @@ static void drawmeshsolid(Object *ob, float *nors) glShadeModel(GL_FLAT); - if( (G.f & G_BACKBUFSEL)==0 ) { - glEnable(GL_LIGHTING); - init_gl_materials(ob); + glEnable(GL_LIGHTING); + init_gl_materials(ob); - two_sided( me->flag & ME_TWOSIDED ); + two_sided( me->flag & ME_TWOSIDED ); - if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW); - else glFrontFace(GL_CCW); - } + if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW); + else glFrontFace(GL_CCW); mface= me->mface; if( (G.f & G_FACESELECT) && ob==((G.scene->basact) ? (G.scene->basact->object) : 0)) tface= me->tface; @@ -1926,15 +1855,13 @@ static void drawmeshsolid(Object *ob, float *nors) for(a=start; av3) { if(tface && (tface->flag & TF_HIDE)) { - if( (G.f & G_BACKBUFSEL)==0) { - glBegin(GL_LINE_LOOP); - glVertex3fv( (mvert+mface->v1)->co); - glVertex3fv( (mvert+mface->v2)->co); - glVertex3fv( (mvert+mface->v3)->co); - if(mface->v4) glVertex3fv( (mvert+mface->v1)->co); - glEnd(); - tface++; - } + glBegin(GL_LINE_LOOP); + glVertex3fv( (mvert+mface->v1)->co); + glVertex3fv( (mvert+mface->v2)->co); + glVertex3fv( (mvert+mface->v3)->co); + if(mface->v4) glVertex3fv( (mvert+mface->v1)->co); + glEnd(); + tface++; } else { if(extverts) { @@ -1964,84 +1891,69 @@ static void drawmeshsolid(Object *ob, float *nors) if(v4) {if(glmode==GL_TRIANGLES) {glmode= GL_QUADS; glEnd(); glBegin(GL_QUADS);}} else {if(glmode==GL_QUADS) {glmode= GL_TRIANGLES; glEnd(); glBegin(GL_TRIANGLES);}} - if(G.f & G_BACKBUFSEL) { - if(vertexpaint) { - i= index_to_framebuffer(a+1); - cpack(i); + if(mface->mat_nr!=matnr) { + glEnd(); + + matnr= mface->mat_nr; + set_gl_material(matnr+1); + + glBegin(glmode); + } + + if( (me->flag & ME_AUTOSMOOTH)==0 && (mface->flag & ME_SMOOTH)) { + if(setsmooth==0) { + glEnd(); + glShadeModel(GL_SMOOTH); + glBegin(glmode); + setsmooth= 1; } - + n1= (mvert+mface->v1)->no; + n2= (mvert+mface->v2)->no; + n3= (mvert+mface->v3)->no; + if(v4) n4= (mvert+mface->v4)->no; + + if(mface->puno & ME_FLIPV1) { + no[0]= -n1[0]; no[1]= -n1[1]; no[2]= -n1[2]; + glNormal3sv(no); + } + else glNormal3sv(n1); + glVertex3fv( v1 ); + + if(mface->puno & ME_FLIPV2) { + no[0]= -n2[0]; no[1]= -n2[1]; no[2]= -n2[2]; + glNormal3sv(no); + } + else glNormal3sv(n2); + glVertex3fv( v2 ); + + if(mface->puno & ME_FLIPV3) { + no[0]= -n3[0]; no[1]= -n3[1]; no[2]= -n3[2]; + glNormal3sv(no); + } + else glNormal3sv(n3); + glVertex3fv( v3 ); + + if(v4) { + if(mface->puno & ME_FLIPV4) { + no[0]= -n4[0]; no[1]= -n4[1]; no[2]= -n4[2]; + glNormal3sv(no); + } + else glNormal3sv(n4); + glVertex3fv( v4 ); + } + } + else { + if(setsmooth==1) { + glEnd(); + glShadeModel(GL_FLAT); + glBegin(glmode); + setsmooth= 0; + } + glNormal3fv(nors); glVertex3fv( v1 ); glVertex3fv( v2 ); glVertex3fv( v3 ); if(v4) glVertex3fv( v4 ); - - } - else { - - if(mface->mat_nr!=matnr) { - glEnd(); - - matnr= mface->mat_nr; - set_gl_material(matnr+1); - - glBegin(glmode); - } - - if( (me->flag & ME_AUTOSMOOTH)==0 && (mface->flag & ME_SMOOTH)) { - if(setsmooth==0) { - glEnd(); - glShadeModel(GL_SMOOTH); - glBegin(glmode); - setsmooth= 1; - } - n1= (mvert+mface->v1)->no; - n2= (mvert+mface->v2)->no; - n3= (mvert+mface->v3)->no; - if(v4) n4= (mvert+mface->v4)->no; - - if(mface->puno & ME_FLIPV1) { - no[0]= -n1[0]; no[1]= -n1[1]; no[2]= -n1[2]; - glNormal3sv(no); - } - else glNormal3sv(n1); - glVertex3fv( v1 ); - - if(mface->puno & ME_FLIPV2) { - no[0]= -n2[0]; no[1]= -n2[1]; no[2]= -n2[2]; - glNormal3sv(no); - } - else glNormal3sv(n2); - glVertex3fv( v2 ); - - if(mface->puno & ME_FLIPV3) { - no[0]= -n3[0]; no[1]= -n3[1]; no[2]= -n3[2]; - glNormal3sv(no); - } - else glNormal3sv(n3); - glVertex3fv( v3 ); - - if(v4) { - if(mface->puno & ME_FLIPV4) { - no[0]= -n4[0]; no[1]= -n4[1]; no[2]= -n4[2]; - glNormal3sv(no); - } - else glNormal3sv(n4); - glVertex3fv( v4 ); - } - } - else { - if(setsmooth==1) { - glEnd(); - glShadeModel(GL_FLAT); - glBegin(glmode); - setsmooth= 0; - } - glNormal3fv(nors); - glVertex3fv( v1 ); - glVertex3fv( v2 ); - glVertex3fv( v3 ); - if(v4) glVertex3fv( v4 ); - } } } if(tface) tface++; @@ -2051,16 +1963,81 @@ static void drawmeshsolid(Object *ob, float *nors) glEnd(); } - /* SOLVE */ -/* if ELEM(ob->type, OB_SECTOR, OB_LIFE) glDisable(GL_CULL_FACE); */ - - if(G.f & G_BACKBUFSEL) { - glDisable(GL_CULL_FACE); - } glDisable(GL_LIGHTING); glFrontFace(GL_CCW); } +#if 0 +// WIP: experiment with cleaner draw, but cant make it for this release (ton) +static void drawmesh_vpaint(Object *ob) +{ + Mesh *me= ob->data; + MVert *mvert; + MFace *mface; + TFace *tface; + int totface, a, glmode; + char *mcol; + + if(mesh_uses_displist(me)) { + DispList *dl= find_displist(&me->disp, DL_MESH); + DispListMesh *dlm= dl->mesh; + + if(dlm==NULL) return; + if(dlm->tface==NULL && dlm->mcol==NULL) return; + + mvert= dlm->mvert; + mface= dlm->mface; + totface= dlm->totface; + mcol= (char *)dlm->mcol; + tface= dlm->tface; + } + else { + + if(me->tface==NULL && me->mcol==NULL) return; + + mvert= me->mvert; + mface= me->mface; + totface= me->totface; + mcol= (char *)me->mcol; + tface= me->tface; + } + + glShadeModel(GL_SMOOTH); + glBegin(GL_QUADS); + glmode= GL_QUADS; + + for(a=0; av3) { + + if(mface->v4) {if(glmode==GL_TRIANGLES) {glmode= GL_QUADS; glEnd(); glBegin(GL_QUADS);}} + else {if(glmode==GL_QUADS) {glmode= GL_TRIANGLES; glEnd(); glBegin(GL_TRIANGLES);}} + + glColor3ub(mcol[3], mcol[2], mcol[1]); + glVertex3fv( (mvert+mface->v1)->co ); + glColor3ub(mcol[7], mcol[6], mcol[5]); + glVertex3fv( (mvert+mface->v2)->co ); + glColor3ub(mcol[11], mcol[10], mcol[9]); + glVertex3fv( (mvert+mface->v3)->co ); + if(mface->v4) { + glColor3ub(mcol[15], mcol[14], mcol[13]); + glVertex3fv( (mvert+mface->v4)->co ); + } + } + mcol+=16; + } + } + else { + + tface++; + } + } + glEnd(); + glShadeModel(GL_FLAT); +} +#endif + static void drawmeshshaded(Object *ob, unsigned int *col1, unsigned int *col2) { Mesh *me; @@ -3849,14 +3826,14 @@ static void drawWireExtra(Object *ob, ListBase *lb) } else BIF_ThemeColor(TH_WIRE); - bglPolygonOffset(1); + bglPolygonOffset(1.0); glDepthMask(0); // disable write in zbuffer, selected edge wires show better if(ob->type==OB_MESH) drawmeshwire(ob); else drawDispListwire(lb); glDepthMask(1); - bglPolygonOffset(0); + bglPolygonOffset(0.0); } static void draw_extra_wire(Object *ob) @@ -3999,7 +3976,7 @@ void draw_object(Base *base) mymultmatrix(ob->obmat); /* which wire color */ - if((G.f & (G_BACKBUFSEL+G_PICKSEL)) == 0) { + if((G.f & G_PICKSEL) == 0) { project_short(ob->obmat[3], &base->sx); if(G.moving==1 && (base->flag & (SELECT+BA_PARSEL))) BIF_ThemeColor(TH_TRANSFORM); @@ -4042,8 +4019,7 @@ void draw_object(Base *base) if(ob==G.obedit) dt= OB_WIRE; else { - if(G.f & G_BACKBUFSEL) dt= OB_SOLID; - else dt= OB_SHADED; + dt= OB_SHADED; glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); @@ -4061,8 +4037,6 @@ void draw_object(Base *base) } if(dt>=OB_WIRE ) { - if(dt>OB_SOLID) if(G.f & G_BACKBUFSEL) dt= OB_SOLID; - dtx= ob->dtx; if(G.obedit==ob) { // the only 2 extra drawtypes alowed in editmode @@ -4092,7 +4066,7 @@ void draw_object(Base *base) /* draw outline for selected solid objects */ if(G.vd->flag & V3D_SELECT_OUTLINE) { - if(dt>OB_WIRE && dtOB_WIRE && dtdisp); else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob); else if(dt==OB_WIRE) drawmeshwire(ob); else if(ma && (ma->mode & MA_HALO)) drawmeshwire(ob); else if(me->tface) { - if(G.f & G_BACKBUFSEL) drawmeshsolid(ob, 0); - else if(G.f & G_FACESELECT || G.vd->drawtype==OB_TEXTURE) { + if(G.f & G_FACESELECT || G.vd->drawtype==OB_TEXTURE) { draw_tface_mesh(ob, ob->data, dt); } else drawDispList(ob, dt); @@ -4136,7 +4109,7 @@ void draw_object(Base *base) else drawDispList(ob, dt); } - if( (ob!=G.obedit) && ((G.f & (G_BACKBUFSEL+G_PICKSEL)) == 0) ) { + if( (ob!=G.obedit) && ((G.f & (G_PICKSEL)) == 0) ) { paf = give_parteff(ob); if( paf ) { if(col) cpack(0xFFFFFF); /* for visibility */ @@ -4243,7 +4216,7 @@ void draw_object(Base *base) if(base->flag & OB_RADIO) return; if(G.f & G_SIMULATION) return; - if((G.f & (G_BACKBUFSEL+G_PICKSEL))==0) { + if((G.f & (G_PICKSEL))==0) { ListBase *list; /* draw hook center and offset line */ @@ -4356,3 +4329,88 @@ void draw_object_ext(Base *base) } curarea->win_swap= WIN_FRONT_OK; } + +/* ***************** BACKBUF SEL (BBS) ********* */ + +/* two options, facecolors or black */ +static void bbs_mesh_solid(Object *ob, int facecol) +{ + + if(ob==G.obedit) { + + } + else { + Mesh *me= ob->data; + MVert *mvert; + MFace *mface; + int a, glmode, totface, div; + + /* experiment with drawing subsurf while painting, but this whole displist system works against me (ton) */ +/* if(mesh_uses_displist(me)) { + DispList *dl= find_displist(&me->disp, DL_MESH); + DispListMesh *dlm= dl->mesh; + + if(dlm==NULL) return; + + mvert= dlm->mvert; + mface= dlm->mface; + totface= dlm->totface; + + div= me->subdiv; // restore original indices + } + else { +*/ + mvert= me->mvert; + mface= me->mface; + totface= me->totface; + + div= 0; +/* } */ + + cpack(0); + glBegin(GL_QUADS); + glmode= GL_QUADS; + + for(a=0; av3) { + + if(mface->v4) {if(glmode==GL_TRIANGLES) {glmode= GL_QUADS; glEnd(); glBegin(GL_QUADS);}} + else {if(glmode==GL_QUADS) {glmode= GL_TRIANGLES; glEnd(); glBegin(GL_TRIANGLES);}} + + if(facecol) { + int i= index_to_framebuffer( (a>>div)+1); + cpack(i); + } + + glVertex3fv( (mvert+mface->v1)->co ); + glVertex3fv( (mvert+mface->v2)->co ); + glVertex3fv( (mvert+mface->v3)->co ); + if(mface->v4) glVertex3fv( (mvert+mface->v4)->co ); + } + } + glEnd(); + } +} + +void draw_object_backbufsel(Object *ob) +{ + Mesh *me; + + mymultmatrix(ob->obmat); + + glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + + switch( ob->type) { + case OB_MESH: + me= ob->data; + bbs_mesh_solid(ob, 1); // 1= facecol + break; + case OB_CURVE: + case OB_SURF: + break; + } + + myloadmatrix(G.vd->viewmat); + +} \ No newline at end of file diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 0d5aef42cb5..88d04c80978 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -933,7 +933,7 @@ void backdrawview3d(int test) if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) { base= (G.scene->basact); if(base && (base->lay & G.vd->lay)) { - draw_object(base); + draw_object_backbufsel(base->object); } } else { diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index 4b776e7fbaf..4a38cbeeacb 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -155,7 +155,7 @@ int EM_zbuffer_visible(float *co, short xs, short ys) persp(PERSP_VIEW); mymultmatrix(G.obedit->obmat); - bglPolygonOffset(G.vd->dist); // sets proj matrix + bglPolygonOffset(2.0); // sets proj matrix glGetFloatv(GL_PROJECTION_MATRIX, (float *)pmat); glGetFloatv(GL_MODELVIEW_MATRIX, (float *)vmat); Mat4MulMat4(persmat, vmat, pmat); @@ -178,8 +178,25 @@ int EM_zbuffer_visible(float *co, short xs, short ys) unsigned int zvali; myglReadPixels(xs, ys, &zvali); - // glReadPixels(curarea->winrct.xmin+xs, curarea->winrct.ymin+ys, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &zvali); zval= ((float)zvali)/((float)0xFFFFFFFF); + if( vec4[2] <= zval) return 1; +/* + myglReadPixels(xs+1, ys, &zvali); + zval= ((float)zvali)/((float)0xFFFFFFFF); + if( vec4[2] <= zval) return 1; + + myglReadPixels(xs, ys+1, &zvali); + zval= ((float)zvali)/((float)0xFFFFFFFF); + if( vec4[2] <= zval) return 1; + + myglReadPixels(xs-1, ys, &zvali); + zval= ((float)zvali)/((float)0xFFFFFFFF); + if( vec4[2] <= zval) return 1; + + myglReadPixels(xs, ys-1, &zvali); + zval= ((float)zvali)/((float)0xFFFFFFFF); + if( vec4[2] <= zval) return 1; +*/ // printf("my proj %f zbuf %x %f mydiff %f\n", vec4[2], zvali, zval, vec4[2]-zval); } else { @@ -256,14 +273,30 @@ static EditVert *findnearestvert(short *dist, short sel) return act; } +/* more samples */ +int EM_zbuffer_edge_visible(float *v1, float *v2, short *val1, short *val2) +{ + float cent[3]; + + /* midpoints work bad in persp mode... */ + VecMidf(cent, v1, v2); + if(EM_zbuffer_visible(cent, (val1[0]+val2[0])/2, (val1[1]+val2[1])/2)) return 1; + + // endpoints; should be both visible + if(EM_zbuffer_visible(v1, val1[0], val1[1])) + if(EM_zbuffer_visible(v1, val2[0], val2[1])) + return 1; + + return 0; +} EditEdge *findnearestedge(short *dist) { EditMesh *em = G.editMesh; EditEdge *closest, *eed; EditVert *eve; - short mval[2], distance; float v1[2], v2[2], mval2[2]; + short mval[2], distance; if(em->edges.first==NULL) return NULL; else eed= em->edges.first; @@ -295,11 +328,9 @@ EditEdge *findnearestedge(short *dist) distance= (short)PdistVL2Dfl(mval2, v1, v2); if(distance < *dist) { - if(EM_zbuffer_visible(eed->v1->co, eed->v1->xs, eed->v1->ys)) { - if(EM_zbuffer_visible(eed->v2->co, eed->v2->xs, eed->v2->ys)) { - *dist= distance; - closest= eed; - } + if(EM_zbuffer_edge_visible(eed->v1->co, eed->v2->co, &eed->v1->xs, &eed->v2->xs)) { + *dist= distance; + closest= eed; } } } diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c index 64b4201e15b..907da8f8a5d 100644 --- a/source/blender/src/editview.c +++ b/source/blender/src/editview.c @@ -810,18 +810,19 @@ void borderselect(void) } } if(G.scene->selectmode & SCE_SELECT_EDGE) { + float cent[3]; short done= 0; + calc_meshverts_ext_f2(); /* doesnt clip, drawobject.c */ /* two stages, for nice edge select first do 'both points in rect' */ for(eed= em->edges.first; eed; eed= eed->next) { if(eed->h==0) { if( edge_fully_inside_rect(rect, eed->v1->xs, eed->v1->ys, eed->v2->xs, eed->v2->ys)) { - if(EM_zbuffer_visible(eed->v1->co, eed->v1->xs, eed->v1->ys)) { - if(EM_zbuffer_visible(eed->v2->co, eed->v2->xs, eed->v2->ys)) { - EM_select_edge(eed, val==LEFTMOUSE); - done = 1; - } + VecMidf(cent, eed->v1->co, eed->v2->co); + if(EM_zbuffer_visible(cent, (eed->v1->xs+eed->v2->xs)/2, (eed->v1->ys+eed->v2->ys)/2)) { + EM_select_edge(eed, val==LEFTMOUSE); + done = 1; } } } @@ -831,10 +832,10 @@ void borderselect(void) for(eed= em->edges.first; eed; eed= eed->next) { if(eed->h==0) { if( edge_inside_rect(rect, eed->v1->xs, eed->v1->ys, eed->v2->xs, eed->v2->ys)) { - if(EM_zbuffer_visible(eed->v1->co, eed->v1->xs, eed->v1->ys)) { - if(EM_zbuffer_visible(eed->v2->co, eed->v2->xs, eed->v2->ys)) { - EM_select_edge(eed, val==LEFTMOUSE); - } + VecMidf(cent, eed->v1->co, eed->v2->co); + if(EM_zbuffer_visible(cent, (eed->v1->xs+eed->v2->xs)/2, (eed->v1->ys+eed->v2->ys)/2)) { + EM_select_edge(eed, val==LEFTMOUSE); + done = 1; } } } @@ -1084,7 +1085,6 @@ void mesh_selectionCB(int selecting, Object *editobj, short *mval, float rad) if(G.scene->selectmode & SCE_SELECT_EDGE) { calc_meshverts_ext_f2(); /* doesnt clip, drawobject.c */ - /* two stages, for nice edge select first do 'both points in rect' */ for(eed= em->edges.first; eed; eed= eed->next) { if(eed->h==0) { if( edge_inside_circle(mval[0], mval[1], (short)rad, eed->v1->xs, eed->v1->ys, eed->v2->xs, eed->v2->ys)) { diff --git a/source/blender/src/glutil.c b/source/blender/src/glutil.c index 2bf802f0fcc..c989b13f64d 100644 --- a/source/blender/src/glutil.c +++ b/source/blender/src/glutil.c @@ -479,6 +479,10 @@ void bglEnd(void) /* *************** glPolygonOffset hack ************* */ +// both temporal, so here for now (ton) +#include "BKE_global.h" +#include "DNA_view3d_types.h" + /* dist is only for ortho now... */ void bglPolygonOffset(float dist) { @@ -494,8 +498,10 @@ void bglPolygonOffset(float dist) glMatrixMode(GL_PROJECTION); glGetFloatv(GL_PROJECTION_MATRIX, (float *)winmat); - if(winmat[15]>0.5) offs= 0.00005*dist; // ortho tweaking - else offs= 0.001; // should be clipping value or so... + /* dist is from camera to center point */ + + if(winmat[15]>0.5) offs= 0.00005*dist*G.vd->dist; // ortho tweaking + else offs= 0.001*dist; // should be clipping value or so... winmat[14]-= offs; offset+= offs;