diff options
author | Ton Roosendaal <ton@blender.org> | 2004-09-25 17:42:31 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2004-09-25 17:42:31 +0400 |
commit | 6f074f6f461066777f5d7546882c44d8ba0288db (patch) | |
tree | 895be0ba83b83da3e1a8aee7c228dcb29ba121b2 /source | |
parent | cfe9a9575526458412d50cc6122fdde1d66dd4d2 (diff) |
Two nice workflow improvements;
- Zbuffer clipped selection
Based on same algos as for drawing (blender polygon offset) vertices, edges
and faces now are clipped for draw and selection when Zbuffer is used.
Note that it works for endpoint vertices of edges, and for facecenters.
Also works for border and circle-select
- Optimal draw subsurfs
This now draws optimal with faces and edges selected/unselected, hiding the
original 'cage' (mesh) completely.
TODO: edge select, which still uses original (invisible) edge.
http://www.blender3d.org/cms/Mesh_editing_rewrite.425.0.html
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_displist.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf.c | 41 | ||||
-rw-r--r-- | source/blender/include/BIF_editmesh.h | 1 | ||||
-rw-r--r-- | source/blender/include/BIF_glutil.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_view3d_types.h | 1 | ||||
-rw-r--r-- | source/blender/src/drawmesh.c | 10 | ||||
-rw-r--r-- | source/blender/src/drawobject.c | 342 | ||||
-rw-r--r-- | source/blender/src/drawview.c | 2 | ||||
-rw-r--r-- | source/blender/src/editmesh.c | 3 | ||||
-rw-r--r-- | source/blender/src/editmesh_mods.c | 95 | ||||
-rw-r--r-- | source/blender/src/editview.c | 47 | ||||
-rw-r--r-- | source/blender/src/glutil.c | 38 | ||||
-rw-r--r-- | source/blender/src/header_view3d.c | 7 | ||||
-rw-r--r-- | source/blender/src/mywindow.c | 8 | ||||
-rw-r--r-- | source/blender/src/view.c | 8 |
16 files changed, 408 insertions, 207 deletions
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 9fc9cd3e004..e12bcbdf1b4 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -61,6 +61,8 @@ struct Bone; struct Mesh; struct TFace; struct EditMesh; +struct EditEdge; +struct EditFace; typedef struct DispListMesh DispListMesh; struct DispListMesh { @@ -70,6 +72,8 @@ struct DispListMesh { struct MCol *mcol; struct MFace *mface; struct TFace *tface; + struct EditEdge **editedge; // added for subsurf, drawobject.c + struct EditFace **editface; // added for subsurf, drawobject.c int flag; }; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 63f344077cb..a9e2e879c51 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -211,11 +211,13 @@ DispListMesh *displistmesh_from_mesh(Mesh *me, float *extverts) void displistmesh_free(DispListMesh *dlm) { // also check on mvert and mface, can be NULL after decimator (ton) - if( dlm->mvert) MEM_freeN(dlm->mvert); - if( dlm->medge) MEM_freeN(dlm->medge); + if (dlm->mvert) MEM_freeN(dlm->mvert); + if (dlm->medge) MEM_freeN(dlm->medge); if (dlm->mface) MEM_freeN(dlm->mface); if (dlm->mcol) MEM_freeN(dlm->mcol); if (dlm->tface) MEM_freeN(dlm->tface); + if (dlm->editedge) MEM_freeN(dlm->editedge); + if (dlm->editface) MEM_freeN(dlm->editface); MEM_freeN(dlm); } diff --git a/source/blender/blenkernel/intern/subsurf.c b/source/blender/blenkernel/intern/subsurf.c index 93ef1fa870c..ca911d9ff6b 100644 --- a/source/blender/blenkernel/intern/subsurf.c +++ b/source/blender/blenkernel/intern/subsurf.c @@ -187,6 +187,7 @@ struct _HyperEdge { HyperVert *ep; int flag; // added for drawing optimal float sharp; // sharpness weight + EditEdge *ee; // for selection state LinkNode *faces; }; @@ -270,7 +271,8 @@ static HyperVert *hypermesh_add_vert(HyperMesh *hme, float *co, float *orig) { return hv; } -static HyperEdge *hypermesh_add_edge(HyperMesh *hme, HyperVert *v1, HyperVert *v2, int flag, float sharp) { +static HyperEdge *hypermesh_add_edge(HyperMesh *hme, + HyperVert *v1, HyperVert *v2, int flag, float sharp, EditEdge *ee) { HyperEdge *he= BLI_memarena_alloc(hme->arena, sizeof(*he)); BLI_linklist_prepend_arena(&v1->edges, he, hme->arena); @@ -282,6 +284,7 @@ static HyperEdge *hypermesh_add_edge(HyperMesh *hme, HyperVert *v1, HyperVert *v he->faces= NULL; he->sharp = sharp; he->flag= flag; + he->ee= ee; he->next= hme->edges; hme->edges= he; @@ -308,7 +311,7 @@ static HyperFace *hypermesh_add_face(HyperMesh *hme, HyperVert **verts, int nver HyperEdge *e= hypervert_find_edge(v, last); if (!e) - e= hypermesh_add_edge(hme, v, last, flag, 0); + e= hypermesh_add_edge(hme, v, last, flag, 0, NULL); f->verts[j]= v; f->edges[j]= e; @@ -369,7 +372,7 @@ static HyperMesh *hypermesh_from_mesh(Mesh *me, float *extverts, int subdivLevel if(med->flag & ME_SEAM) flag |= HE_SEAM; hypermesh_add_edge(hme, vert_tbl[med->v1], vert_tbl[med->v2], flag, - creasefac*((float)med->crease) ); + creasefac*((float)med->crease), NULL); } } @@ -410,7 +413,7 @@ static HyperMesh *hypermesh_from_mesh(Mesh *me, float *extverts, int subdivLevel *((unsigned int*) f->vcol[j])= *((unsigned int*) &mcol[j]); } } else if(medge==NULL) { - hypermesh_add_edge(hme, vert_tbl[mf->v1], vert_tbl[mf->v2], DR_OPTIM, 0.0); + hypermesh_add_edge(hme, vert_tbl[mf->v1], vert_tbl[mf->v2], DR_OPTIM, 0.0, NULL); } } @@ -436,7 +439,7 @@ static HyperMesh *hypermesh_from_editmesh(EditMesh *em, int subdivLevels) { * then restore real prev links later. */ for (ee= em->edges.first; ee; ee= ee->next) { - if(ee->v1->h==0 && ee->v2->h==0) { + if(ee->h==0) { if(ee->v1->f1) { ee->v1->prev= (EditVert*) hypermesh_add_vert(hme, ee->v1->co, ee->v1->co); ee->v1->f1= 0; @@ -448,14 +451,13 @@ static HyperMesh *hypermesh_from_editmesh(EditMesh *em, int subdivLevels) { flag= DR_OPTIM; if(ee->seam) flag |= HE_SEAM; + hypermesh_add_edge(hme, (HyperVert*) ee->v1->prev, (HyperVert*) ee->v2->prev, flag, - creasefac*ee->crease); + creasefac*ee->crease, ee); } } for (ef= em->faces.first; ef; ef= ef->next) { - if(ef->v1->h || ef->v2->h || ef->v3->h); - else if(ef->v4 && ef->v4->h); - else { + if(ef->h==0) { int nverts= ef->v4?4:3; HyperVert *verts[4]; HyperFace *f; @@ -685,8 +687,8 @@ static void hypermesh_subdivide(HyperMesh *me, HyperMesh *nme) { } for (e= me->edges; e; e= e->next) { - hypermesh_add_edge(nme, e->v[0]->nmv, e->ep, e->flag, e->sharp>1.0?e->sharp-1.0:0.0); - hypermesh_add_edge(nme, e->v[1]->nmv, e->ep, e->flag, e->sharp>1.0?e->sharp-1.0:0.0); + hypermesh_add_edge(nme, e->v[0]->nmv, e->ep, e->flag, e->sharp>1.0?e->sharp-1.0:0.0, e->ee); + hypermesh_add_edge(nme, e->v[1]->nmv, e->ep, e->flag, e->sharp>1.0?e->sharp-1.0:0.0, e->ee); } for (f= me->faces; f; f= f->next) { @@ -791,8 +793,8 @@ static void hypermesh_simple_subdivide(HyperMesh *me, HyperMesh *nme) { } for (e= me->edges; e; e= e->next) { /* Add original edges */ - hypermesh_add_edge(nme, e->v[0]->nmv, e->ep, e->flag, 0.0); - hypermesh_add_edge(nme, e->v[1]->nmv, e->ep, e->flag, 0.0); + hypermesh_add_edge(nme, e->v[0]->nmv, e->ep, e->flag, 0.0, e->ee); + hypermesh_add_edge(nme, e->v[1]->nmv, e->ep, e->flag, 0.0, e->ee); } for (f= me->faces; f; f= f->next) { @@ -949,7 +951,11 @@ static DispListMesh *hypermesh_to_displistmesh(HyperMesh *hme, short flag) { dlm->mvert= MEM_callocN(dlm->totvert*sizeof(*dlm->mvert), "dlm->mvert"); dlm->medge= MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "dlm->medge"); dlm->mface= MEM_mallocN(dlm->totface*sizeof(*dlm->mface), "dlm->mface"); - + /* these two blocks for live update of selection in editmode */ + if (hme->orig_me==NULL) { + dlm->editedge= MEM_callocN(dlm->totedge*sizeof(EditEdge *), "dlm->editface"); + dlm->editface= MEM_mallocN(dlm->totface*sizeof(EditFace *), "dlm->editedge"); + } if (hme->orig_me) { dlm->flag= hme->orig_me->flag; } else { @@ -969,9 +975,11 @@ static DispListMesh *hypermesh_to_displistmesh(HyperMesh *hme, short flag) { /* we use by default edges for displistmesh now */ med= dlm->medge; - for (e= hme->edges; e; e= e->next, med++) { + for (i=0, e= hme->edges; e; e= e->next, med++, i++) { med->v1= (int) e->v[0]->nmv; med->v2= (int) e->v[1]->nmv; + + if (hme->orig_me==NULL) dlm->editedge[i]= e->ee; if(e->flag & DR_OPTIM) med->flag |= ME_EDGEDRAW; if(e->flag & HE_SEAM) med->flag |= ME_SEAM; @@ -1026,6 +1034,9 @@ static DispListMesh *hypermesh_to_displistmesh(HyperMesh *hme, short flag) { mf->mat_nr= origef->mat_nr; mf->flag= origef->flag; mf->puno= 0; + + // for subsurf draw in editmode + dlm->editface[i]= origef; } /* although not used by 3d display, still needed for wire-render */ diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h index 2b9a305ff86..2e63026a91d 100644 --- a/source/blender/include/BIF_editmesh.h +++ b/source/blender/include/BIF_editmesh.h @@ -91,6 +91,7 @@ extern void vertexnormals(int testflip); /* ******************* editmesh_mods.c */ extern void EM_select_face_fgon(struct EditFace *efa, int sel); +extern int EM_zbuffer_visible(float *co, short xs, short ys); extern void vertexnoise(void); extern void vertexsmooth(void); diff --git a/source/blender/include/BIF_glutil.h b/source/blender/include/BIF_glutil.h index b04705c7b02..d776a9003f9 100644 --- a/source/blender/include/BIF_glutil.h +++ b/source/blender/include/BIF_glutil.h @@ -193,6 +193,8 @@ void bglEnd(void); void bglVertex3fv(float *vec); void bglVertex2fv(float *vec); +/* own working polygon offset */ +void bglPolygonOffset(float dist); #endif /* BIF_GLUTIL_H */ diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 8ac7420ac22..f776d6df2fb 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -122,6 +122,7 @@ typedef struct View3D { #define V3D_WEIGHTPAINT 512 #define V3D_ALIGN 1024 #define V3D_SELECT_OUTLINE 2048 +#define V3D_ZBUF_SELECT 4096 /* View3D->around */ #define V3D_CENTRE 0 diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c index a4041dc6d4b..e45a288f9ff 100644 --- a/source/blender/src/drawmesh.c +++ b/source/blender/src/drawmesh.c @@ -499,7 +499,6 @@ void draw_tfaces3D(Object *ob, Mesh *me) float *v1, *v2, *v3, *v4; float *av1= NULL, *av2= NULL, *av3= NULL, *av4= NULL, *extverts= NULL; int a, activeFaceInSelection= 0; - extern void bPolygonOffset(short val); if(me==0 || me->tface==0) return; @@ -508,7 +507,7 @@ void draw_tfaces3D(Object *ob, Mesh *me) glEnable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); - bPolygonOffset(1); + bglPolygonOffset(G.vd->dist); /* Draw (Hidden) Edges */ if(G.f & G_DRAWEDGES || G.f & G_HIDDENEDGES){ @@ -632,7 +631,7 @@ void draw_tfaces3D(Object *ob, Mesh *me) /* Draw Stippled Outline for selected faces */ mface= me->mface; tface= me->tface; - bPolygonOffset(1); + bglPolygonOffset(G.vd->dist); for(a=me->totface; a>0; a--, mface++, tface++) { if(mface->v3==0) continue; if(tface->flag & TF_HIDE) continue; @@ -705,10 +704,7 @@ void draw_tfaces3D(Object *ob, Mesh *me) setlinestyle(0); } - /* We added 2 offsets, so go back 2, and disable */ - bPolygonOffset(-1); - bPolygonOffset(-1); - bPolygonOffset(0); + bglPolygonOffset(0.0); // resets correctly now, even after calling accumulated offsets } static int set_gl_light(Object *ob) diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 51a8ed3b81d..c8f7dc66239 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -1115,6 +1115,7 @@ static void draw_vertices(short sel) float size, fsize; char col[3], fcol[3]; + /* if not V3D_ZBUF_SELECT: */ /* draws in zbuffer mode twice, to show invisible vertices transparent */ size= BIF_GetThemeValuef(TH_VERTEX_SIZE); @@ -1129,52 +1130,86 @@ static void draw_vertices(short sel) } if(G.zbuf) { - - glDisable(GL_DEPTH_TEST); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - if(G.scene->selectmode & SCE_SELECT_VERTEX) { - glPointSize(size>2.1?size/2.0: size); - glColor4ub(col[0], col[1], col[2], 100); + if(G.vd->flag & V3D_ZBUF_SELECT); + else { + glDisable(GL_DEPTH_TEST); - bglBegin(GL_POINTS); - for(eve= em->verts.first; eve; eve= eve->next) { - if(eve->h==0 && (eve->f & SELECT)==sel ) bglVertex3fv(eve->co); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + if(G.scene->selectmode & SCE_SELECT_VERTEX) { + glPointSize(size>2.1?size/2.0: size); + glColor4ub(col[0], col[1], col[2], 100); + + bglBegin(GL_POINTS); + for(eve= em->verts.first; eve; eve= eve->next) { + if(eve->h==0 && (eve->f & SELECT)==sel ) bglVertex3fv(eve->co); + } + bglEnd(); } - bglEnd(); - } - - if(G.scene->selectmode & SCE_SELECT_FACE) { - glPointSize(fsize>2.1?fsize/2.0: fsize); - glColor4ub(fcol[0], fcol[1], fcol[2], 100); - bglBegin(GL_POINTS); - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->h==0) { - if(efa->fgonf==EM_FGON); - else if(sel == (efa->f & SELECT)) { - bglVertex3fv(efa->cent); + if(G.scene->selectmode & SCE_SELECT_FACE) { + glPointSize(fsize>2.1?fsize/2.0: fsize); + glColor4ub(fcol[0], fcol[1], fcol[2], 100); + + bglBegin(GL_POINTS); + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->h==0) { + if(efa->fgonf==EM_FGON); + else if(sel == (efa->f & SELECT)) { + bglVertex3fv(efa->cent); + } } } + bglEnd(); } - bglEnd(); + + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); } - - glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); } if(G.scene->selectmode & SCE_SELECT_VERTEX) { + + if(0) {// test + float mat[4][4], persmat[4][4], vec4[4]; + float zval; + + glFinish(); // maybe for pending polygons + + // remake because of polygon offs + glMatrixMode(GL_PROJECTION); + glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat); + glMatrixMode(GL_MODELVIEW); + Mat4MulMat4(persmat, G.vd->viewmat, mat); + + for(eve= em->verts.first; eve; eve= eve->next) { + if(eve->h==0 && (eve->f & SELECT) ) { + + VECCOPY(vec4, eve->co); + vec4[3]= 1.0; + Mat4MulVec4fl(persmat, vec4); + vec4[2]/= vec4[3]; + vec4[2]= 0.5 + vec4[2]/2; + // test; read 9 pixels + glReadPixels(curarea->winrct.xmin+eve->xs, curarea->winrct.ymin+eve->ys, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &zval); + + //printf("my proj %f zbuf %f mydiff %f\n", vec4[2], zval, vec4[2]-zval); + if( vec4[2]-zval > 0.0) eve->xs= 3200; + } + } + } + glPointSize(size); glColor3ub(col[0], col[1], col[2]); bglBegin(GL_POINTS); for(eve= em->verts.first; eve; eve= eve->next) { + if(eve->xs!=3200) if(eve->h==0 && (eve->f & SELECT)==sel ) bglVertex3fv(eve->co); } bglEnd(); + } if(G.scene->selectmode & SCE_SELECT_FACE) { @@ -2444,6 +2479,26 @@ static void draw_static_particle_system(Object *ob, PartEff *paf) } +static void glVertex_efa_edges(EditFace *efa) +{ + if(efa->e1->h==0) { + glVertex3fv(efa->v1->co); + glVertex3fv(efa->v2->co); + } + if(efa->e2->h==0) { + glVertex3fv(efa->v2->co); + glVertex3fv(efa->v3->co); + } + if(efa->e3->h==0) { + glVertex3fv(efa->e3->v1->co); + glVertex3fv(efa->e3->v2->co); + } + if(efa->e4 && efa->e4->h==0) { + glVertex3fv(efa->e4->v1->co); + glVertex3fv(efa->e4->v2->co); + } +} + static void drawmeshwire(Object *ob) { EditMesh *em = G.editMesh; @@ -2461,10 +2516,13 @@ static void drawmeshwire(Object *ob) me= get_mesh(ob); if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) { + DispList *dl= find_displist(&me->disp, DL_MESH); + DispListMesh *dlm= NULL; + if(dl) dlm= dl->mesh; if( (me->flag & ME_OPT_EDGES) && (me->flag & ME_SUBSURF) && me->subdiv) handles= 1; - if(handles==0 && (G.f & (G_FACESELECT+G_DRAWFACES))) { /* transp faces */ + if( (G.f & (G_FACESELECT+G_DRAWFACES))) { /* transp faces */ char col1[4], col2[4]; BIF_GetThemeColor4ubv(TH_FACE, col1); @@ -2474,95 +2532,102 @@ static void drawmeshwire(Object *ob) glEnable(GL_BLEND); glDepthMask(0); // disable write in zbuffer, needed for nice transp - efa= em->faces.first; - while(efa) { - if(efa->h==0) { - - if(efa->f & SELECT) glColor4ub(col2[0], col2[1], col2[2], col2[3]); - else glColor4ub(col1[0], col1[1], col1[2], col1[3]); - - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - glVertex3fv(efa->v1->co); - glVertex3fv(efa->v2->co); - glVertex3fv(efa->v3->co); - if(efa->v4) glVertex3fv(efa->v4->co); - glEnd(); + if(dlm && handles) { + for(a=0, mface= dlm->mface; a<dlm->totface; a++, mface++) { + if(mface->v3) { + efa= dlm->editface[a]; + if(efa->f & SELECT) glColor4ub(col2[0], col2[1], col2[2], col2[3]); + else glColor4ub(col1[0], col1[1], col1[2], col1[3]); + + glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); + glVertex3fv(dlm->mvert[mface->v1].co); + glVertex3fv(dlm->mvert[mface->v2].co); + glVertex3fv(dlm->mvert[mface->v3].co); + if (mface->v4) glVertex3fv(dlm->mvert[mface->v4].co); + glEnd(); + } } - efa= efa->next; } + else { + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->h==0) { + + if(efa->f & SELECT) glColor4ub(col2[0], col2[1], col2[2], col2[3]); + else glColor4ub(col1[0], col1[1], col1[2], col1[3]); + + glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); + glVertex3fv(efa->v1->co); + glVertex3fv(efa->v2->co); + glVertex3fv(efa->v3->co); + if(efa->v4) glVertex3fv(efa->v4->co); + glEnd(); + } + } + } + glDisable(GL_BLEND); glDepthMask(1); // restore write in zbuffer } - + + // in editmode it now draws the greyed out part, or optimized if(mesh_uses_displist(me)) { + /* dont draw the subsurf when solid... then this is a 'drawextra' */ if(handles==0 && ob->dt>OB_WIRE && G.vd->drawtype>OB_WIRE); else { - if(handles) BIF_ThemeColor(TH_WIRE); - else BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7); - - drawDispListwire(&me->disp); + /* don't draw in edge/face mode */ + if(handles && (G.scene->selectmode & SCE_SELECT_VERTEX)==0); + else { + if(handles) BIF_ThemeColor(TH_WIRE); + else BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7); + + drawDispListwire(&me->disp); + } } } - if(handles); // then no edges draw - else if(G.f & G_DRAWCREASES) { /* Use crease edge Highlighting */ - - eed= em->edges.first; + if(G.f & G_DRAWCREASES) { /* Use crease edge Highlighting */ glBegin(GL_LINES); - while(eed) { + for(eed= em->edges.first; eed; eed= eed->next) { if(eed->h==0) { BIF_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, eed->crease); glVertex3fv(eed->v1->co); glVertex3fv(eed->v2->co); } - eed= eed->next; } glEnd(); } else if(G.scene->selectmode == SCE_SELECT_FACE) { - /* draw faces twice, to have selected ones on top */ - BIF_ThemeColor(TH_WIRE); + glBegin(GL_LINES); - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->h==0 && (efa->f & SELECT)==0) { - if(efa->e1->h==0) { - glVertex3fv(efa->v1->co); - glVertex3fv(efa->v2->co); - } - if(efa->e2->h==0) { - glVertex3fv(efa->v2->co); - glVertex3fv(efa->v3->co); - } - if(efa->e3->h==0) { - glVertex3fv(efa->e3->v1->co); - glVertex3fv(efa->e3->v2->co); - } - if(efa->e4 && efa->e4->h==0) { - glVertex3fv(efa->e4->v1->co); - glVertex3fv(efa->e4->v2->co); + if(dlm && handles) { + MEdge *medge= dlm->medge; + MVert *mvert= dlm->mvert; + + for (a=0; a<dlm->totedge; a++, medge++) { + if(medge->flag & ME_EDGEDRAW) { + eed= dlm->editedge[a]; + if(eed) { + if(eed->f & SELECT) BIF_ThemeColor(TH_EDGE_SELECT); + else BIF_ThemeColor(TH_WIRE); + glVertex3fv(mvert[medge->v1].co); + glVertex3fv(mvert[medge->v2].co); + } } } } - - BIF_ThemeColor(TH_EDGE_SELECT); - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->h==0 && (efa->f & SELECT)) { - if(efa->e1->h==0) { - glVertex3fv(efa->v1->co); - glVertex3fv(efa->v2->co); - } - if(efa->e2->h==0) { - glVertex3fv(efa->v2->co); - glVertex3fv(efa->v3->co); - } - if(efa->e3->h==0) { - glVertex3fv(efa->e3->v1->co); - glVertex3fv(efa->e3->v2->co); + else { + /* draw faces twice, to have selected ones on top */ + BIF_ThemeColor(TH_WIRE); + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->h==0 && (efa->f & SELECT)==0) { + glVertex_efa_edges(efa); } - if(efa->e4 && efa->e4->h==0) { - glVertex3fv(efa->e4->v1->co); - glVertex3fv(efa->e4->v2->co); + } + BIF_ThemeColor(TH_EDGE_SELECT); + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->h==0 && (efa->f & SELECT)) { + glVertex_efa_edges(efa); } } } @@ -2575,54 +2640,65 @@ static void drawmeshwire(Object *ob) BIF_GetThemeColor3ubv(TH_EDGE_SELECT, colhi); BIF_GetThemeColor3ubv(TH_WIRE, col); - eed= em->edges.first; /* (bleeding edges) to illustrate selection is defined on vertex basis */ - if(G.scene->selectmode & SCE_SELECT_VERTEX) { + /* but cannot do with subdivided edges... */ + if(dlm==NULL && (G.scene->selectmode & SCE_SELECT_VERTEX)) { glShadeModel(GL_SMOOTH); - glBegin(GL_LINES); - while(eed) { + + for(eed= em->edges.first; eed; eed= eed->next) { if(eed->h==0) { - if(eed->v1->f & SELECT) glColor3ub(colhi[0], colhi[1], colhi[2]); else glColor3ub(col[0], col[1], col[2]); - glVertex3fv(eed->v1->co); - if(eed->v2->f & SELECT) glColor3ub(colhi[0], colhi[1], colhi[2]); else glColor3ub(col[0], col[1], col[2]); - glVertex3fv(eed->v2->co); } - eed= eed->next; } + glEnd(); + glShadeModel(GL_FLAT); } else { glBegin(GL_LINES); - while(eed) { - if(eed->h==0) { - if(eed->f & SELECT) glColor3ub(colhi[0], colhi[1], colhi[2]); - else glColor3ub(col[0], col[1], col[2]); + if(dlm && handles) { + MEdge *medge= dlm->medge; + MVert *mvert= dlm->mvert; - glVertex3fv(eed->v1->co); - glVertex3fv(eed->v2->co); + for (a=0; a<dlm->totedge; a++, medge++) { + if(medge->flag & ME_EDGEDRAW) { + eed= dlm->editedge[a]; + if(eed && eed->h==0) { + if(eed->f & SELECT) glColor3ub(colhi[0], colhi[1], colhi[2]); + else glColor3ub(col[0], col[1], col[2]); + glVertex3fv(mvert[medge->v1].co); + glVertex3fv(mvert[medge->v2].co); + } + } } - eed= eed->next; } + else { + glBegin(GL_LINES); + for(eed= em->edges.first; eed; eed= eed->next) { + if(eed->h==0) { + if(eed->f & SELECT) glColor3ub(colhi[0], colhi[1], colhi[2]); + else glColor3ub(col[0], col[1], col[2]); + glVertex3fv(eed->v1->co); + glVertex3fv(eed->v2->co); + } + } + } + glEnd(); } - glEnd(); - glShadeModel(GL_FLAT); } - else { + else if(handles==0) { BIF_ThemeColor(TH_WIRE); - eed= em->edges.first; glBegin(GL_LINES); - while(eed) { + for(eed= em->edges.first; eed; eed= eed->next) { if(eed->h==0) { glVertex3fv(eed->v1->co); glVertex3fv(eed->v2->co); } - eed= eed->next; } glEnd(); } @@ -2632,13 +2708,11 @@ static void drawmeshwire(Object *ob) glLineWidth(2); glBegin(GL_LINES); - eed= em->edges.first; - while(eed) { + for(eed= em->edges.first; eed; eed= eed->next) { if(eed->h==0 && eed->seam) { glVertex3fv(eed->v1->co); glVertex3fv(eed->v2->co); } - eed= eed->next; } glEnd(); @@ -3708,38 +3782,6 @@ static int ob_from_decimator(Object *ob) return 0; } -/* true or false */ -void bPolygonOffset(short val) -{ - static float winmat[16], ofs=0.0; - - if(val) { - // glEnable(GL_POLYGON_OFFSET_FILL); - // glPolygonOffset(-1.0, -1.0); - - /* hack below is to mimic polygon offset */ - glMatrixMode(GL_PROJECTION); - glGetFloatv(GL_PROJECTION_MATRIX, (float *)winmat); - - if(winmat[15]>0.5) ofs= 0.00005*G.vd->dist; // ortho tweaking - else ofs= 0.001; - if(val== -1) ofs= -ofs; - - winmat[14]-= ofs; - glLoadMatrixf(winmat); - glMatrixMode(GL_MODELVIEW); - } - else { - - glMatrixMode(GL_PROJECTION); - winmat[14]+= ofs; - glLoadMatrixf(winmat); - glMatrixMode(GL_MODELVIEW); - } -} - - - /* draws wire outline */ static void drawSolidSelect(Object *ob, ListBase *lb) { @@ -3789,14 +3831,14 @@ static void drawWireExtra(Object *ob, ListBase *lb) } else BIF_ThemeColor(TH_WIRE); - bPolygonOffset(1); + bglPolygonOffset(1); glDepthMask(0); // disable write in zbuffer, selected edge wires show better if(ob->type==OB_MESH) drawmeshwire(ob); else drawDispListwire(lb); glDepthMask(1); - bPolygonOffset(0); + bglPolygonOffset(0); } static void draw_extra_wire(Object *ob) diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 330c32330e5..952ca35b5d9 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -270,6 +270,8 @@ void init_gl_stuff(void) glPixelTransferi(GL_BLUE_BIAS, 0); glPixelTransferi(GL_ALPHA_SCALE, 1); glPixelTransferi(GL_ALPHA_BIAS, 0); + glPixelTransferi(GL_DEPTH_BIAS, 0); + glPixelTransferi(GL_DEPTH_SCALE, 1); a= 0; for(x=0; x<32; x++) { diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index a6d75cf21be..90f1ac894c7 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -749,7 +749,7 @@ void make_editMesh() } efa->mat_nr= mface->mat_nr; - efa->flag= mface->flag; + efa->flag= mface->flag & ~ME_HIDE; /* select face flag, if no edges we flush down */ if(mface->flag & ME_FACE_SEL) { @@ -757,6 +757,7 @@ void make_editMesh() if(me->medge==NULL) EM_select_face(efa, 1); } if(mface->flag & ME_HIDE) efa->h= 1; + } if(me->tface) tface++; diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index 5cea6971aa5..00924a30f67 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -99,6 +99,47 @@ editmesh_mods.c, UI level access, no geometry changes /* ****************************** SELECTION ROUTINES **************** */ +/* return 1 if visible */ +int EM_zbuffer_visible(float *co, short xs, short ys) +{ + static float persmat[4][4]; + float zval, vec4[4]; + + if(G.vd->drawtype<OB_SOLID && (G.vd->flag & V3D_ZBUF_SELECT)==0) return 1; + + if(co==NULL) { // init + float pmat[4][4], vmat[4][4]; + areawinset(curarea->win); + persp(PERSP_VIEW); + mymultmatrix(G.obedit->obmat); + + bglPolygonOffset(G.vd->dist); // sets proj matrix + glGetFloatv(GL_PROJECTION_MATRIX, (float *)pmat); + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)vmat); + Mat4MulMat4(persmat, vmat, pmat); + bglPolygonOffset(0.0); // restores proj matrix + + myloadmatrix(G.vd->viewmat); + + return 0; + } + + // clip on window edge */ + if(xs<0 || ys<0 || xs>=curarea->winx || ys>= curarea->winy) return 0; + + VECCOPY(vec4, co); + vec4[3]= 1.0; + Mat4MulVec4fl(persmat, vec4); + vec4[2]/= vec4[3]; + vec4[2]= 0.5 + vec4[2]/2; + + glReadPixels(curarea->winrct.xmin+xs, curarea->winrct.ymin+ys, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &zval); + + //printf("my proj %f zbuf %f mydiff %f\n", vec4[2], zval, vec4[2]-zval); + if( vec4[2] > zval) return 0; + return 1; +} + static EditVert *findnearestvert(short *dist, short sel) { @@ -112,6 +153,7 @@ static EditVert *findnearestvert(short *dist, short sel) /* do projection */ calc_meshverts_ext(); /* drawobject.c */ + EM_zbuffer_visible(NULL, 0, 0); /* NULL = init */ /* we count from acto->next to last, and from first to acto */ /* does acto exist? */ @@ -130,9 +172,11 @@ static EditVert *findnearestvert(short *dist, short sel) temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys); if( (eve->f & 1)==sel ) temp+=5; if(temp< *dist) { - act= eve; - *dist= temp; - if(*dist<4) break; + if(EM_zbuffer_visible(eve->co, eve->xs, eve->ys)) { + act= eve; + *dist= temp; + if(*dist<4) break; + } } } eve= eve->next; @@ -145,9 +189,11 @@ static EditVert *findnearestvert(short *dist, short sel) temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys); if( (eve->f & 1)==sel ) temp+=5; if(temp< *dist) { - act= eve; - if(temp<4) break; - *dist= temp; + if(EM_zbuffer_visible(eve->co, eve->xs, eve->ys)) { + act= eve; + if(temp<4) break; + *dist= temp; + } } if(eve== acto) break; } @@ -177,6 +223,8 @@ EditEdge *findnearestedge(short *dist) } calc_meshverts_ext_f2(); /*sets (eve->f & 2) for vertices that aren't visible*/ + EM_zbuffer_visible(NULL, 0, 0); /* NULL = init */ + getmouseco_areawin(mval); closest=NULL; @@ -196,8 +244,12 @@ EditEdge *findnearestedge(short *dist) distance= (short)PdistVL2Dfl(mval2, v1, v2); if(distance < *dist) { - *dist= distance; - closest= eed; + 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; + } + } } } eed= eed->next; @@ -224,6 +276,7 @@ static EditFace *findnearestface(short *dist) /* do projection */ calc_mesh_facedots_ext(); + EM_zbuffer_visible(NULL, 0, 0); /* NULL = init */ /* we count from acto->next to last, and from first to acto */ /* does acto exist? */ @@ -241,8 +294,10 @@ static EditFace *findnearestface(short *dist) if(efa->h==0 && efa->fgonf!=EM_FGON) { temp= abs(mval[0]- efa->xs)+ abs(mval[1]- efa->ys); if(temp< *dist) { - act= efa; - *dist= temp; + if(EM_zbuffer_visible(efa->cent, efa->xs, efa->ys)) { + act= efa; + *dist= temp; + } } } efa= efa->next; @@ -254,8 +309,10 @@ static EditFace *findnearestface(short *dist) if(efa->h==0 && efa->fgonf!=EM_FGON) { temp= abs(mval[0]- efa->xs)+ abs(mval[1]- efa->ys); if(temp< *dist) { - act= efa; - *dist= temp; + if(EM_zbuffer_visible(efa->cent, efa->xs, efa->ys)) { + act= efa; + *dist= temp; + } } if(efa== acto) break; } @@ -294,7 +351,7 @@ static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa) } if(G.scene->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE)) { - if(efa->fgonf==0) { + if(0) {//efa->fgonf==0) { if(efa->f & SELECT) BIF_ThemeColor(TH_EDGE_SELECT); else BIF_ThemeColor(TH_WIRE); @@ -637,6 +694,7 @@ void hide_mesh(int swap) for(eed= em->edges.first; eed; eed= eed->next) { if((eed->f & SELECT)!=swap) { eed->h |= 1; + eed->v1->h= eed->v2->h= 1; EM_select_edge(eed, 0); } } @@ -654,6 +712,15 @@ void hide_mesh(int swap) for(efa= em->faces.first; efa; efa= efa->next) { if((efa->f & SELECT)!=swap) { efa->h= 1; + + efa->e1->h |= 1; + efa->e2->h |= 1; + efa->e3->h |= 1; + if(efa->e4) efa->e4->h |= 1; + + efa->v1->h= efa->v2->h= efa->v3->h= 1; + if(efa->v4) efa->v4->h= 1; + EM_select_face(efa, 0); } } @@ -682,7 +749,7 @@ void reveal_mesh(void) } for(eed= em->edges.first; eed; eed= eed->next) { - if(eed->h) { + if(eed->h & 1) { eed->h &= ~1; eed->f |= SELECT; } diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c index 499f4fc018b..567c11d8c7f 100644 --- a/source/blender/src/editview.c +++ b/source/blender/src/editview.c @@ -793,13 +793,17 @@ void borderselect(void) EditEdge *eed; EditFace *efa; + EM_zbuffer_visible(NULL, 0, 0); // init + if(G.scene->selectmode & SCE_SELECT_VERTEX) { calc_meshverts_ext(); /* clips, drawobject.c */ for(eve= em->verts.first; eve; eve= eve->next) { if(eve->h==0 && eve->xs>rect.xmin && eve->xs<rect.xmax) { if(eve->ys>rect.ymin && eve->ys<rect.ymax) { - if(val==LEFTMOUSE) eve->f|= 1; - else eve->f&= 254; + if(EM_zbuffer_visible(eve->co, eve->xs, eve->ys)) { + if(val==LEFTMOUSE) eve->f|= 1; + else eve->f&= 254; + } } } } @@ -812,8 +816,12 @@ void borderselect(void) 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)) { - EM_select_edge(eed, val==LEFTMOUSE); - done = 1; + 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; + } + } } } } @@ -821,8 +829,13 @@ void borderselect(void) if(done==0) { 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)) - EM_select_edge(eed, val==LEFTMOUSE); + 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); + } + } + } } } } @@ -833,7 +846,9 @@ void borderselect(void) for(efa= em->faces.first; efa; efa= efa->next) { if(efa->h==0 && efa->xs>rect.xmin && efa->xs<rect.xmax) { if(efa->ys>rect.ymin && efa->ys<rect.ymax) { - EM_select_face_fgon(efa, val==LEFTMOUSE); + if(EM_zbuffer_visible(efa->cent, efa->xs, efa->ys)) { + EM_select_face_fgon(efa, val==LEFTMOUSE); + } } } } @@ -1039,6 +1054,8 @@ void mesh_selectionCB(int selecting, Object *editobj, short *mval, float rad) EditEdge *eed; EditFace *efa; float x, y, r; + + EM_zbuffer_visible(NULL, 0, 0); // init if(G.scene->selectmode & SCE_SELECT_VERTEX) { calc_meshverts_ext(); /* drawobject.c */ @@ -1049,8 +1066,10 @@ void mesh_selectionCB(int selecting, Object *editobj, short *mval, float rad) y= eve->ys-mval[1]; r= sqrt(x*x+y*y); if(r<=rad) { - if(selecting==LEFTMOUSE) eve->f|= 1; - else eve->f&= 254; + if(EM_zbuffer_visible(eve->co, eve->xs, eve->ys)) { + if(selecting==LEFTMOUSE) eve->f|= 1; + else eve->f&= 254; + } } } eve= eve->next; @@ -1064,7 +1083,11 @@ void mesh_selectionCB(int selecting, Object *editobj, short *mval, float rad) 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)) { - EM_select_edge(eed, selecting==LEFTMOUSE); + 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, selecting==LEFTMOUSE); + } + } } } } @@ -1078,7 +1101,9 @@ void mesh_selectionCB(int selecting, Object *editobj, short *mval, float rad) y= efa->ys-mval[1]; r= sqrt(x*x+y*y); if(r<=rad) { - EM_select_face_fgon(efa, selecting==LEFTMOUSE); + if(EM_zbuffer_visible(efa->cent, efa->xs, efa->ys)) { + EM_select_face_fgon(efa, selecting==LEFTMOUSE); + } } } } diff --git a/source/blender/src/glutil.c b/source/blender/src/glutil.c index 568c660208c..2bf802f0fcc 100644 --- a/source/blender/src/glutil.c +++ b/source/blender/src/glutil.c @@ -477,4 +477,42 @@ void bglEnd(void) } +/* *************** glPolygonOffset hack ************* */ + +/* dist is only for ortho now... */ +void bglPolygonOffset(float dist) +{ + static float winmat[16], offset=0.0; + + if(dist!=0.0) { + float offs; + + // glEnable(GL_POLYGON_OFFSET_FILL); + // glPolygonOffset(-1.0, -1.0); + + /* hack below is to mimic polygon offset */ + 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... + + winmat[14]-= offs; + offset+= offs; + + glLoadMatrixf(winmat); + glMatrixMode(GL_MODELVIEW); + } + else { + + glMatrixMode(GL_PROJECTION); + winmat[14]+= offset; + offset= 0.0; + glLoadMatrixf(winmat); + glMatrixMode(GL_MODELVIEW); + } +} + + + diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 771b5114d0c..39e1920089a 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -3925,8 +3925,13 @@ void view3d_buttons(void) uiDefIconButS(block, TOG|BIT|1, B_SEL_EDGE, ICON_EDGESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode"); xco+= XIC; uiDefIconButS(block, TOG|BIT|2, B_SEL_FACE, ICON_FACESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode"); - xco+= XIC+20; + xco+= XIC; uiBlockEndAlign(block); + if(G.vd->drawtype > OB_WIRE) { + uiDefIconButS(block, TOG|BIT|12, B_REDR, ICON_ORTHO, xco,0,XIC,YIC, &G.vd->flag, 1.0, 0.0, 0, 0, "Clip selection with Z buffer"); + xco+= XIC; + } + xco+= 20; } uiDefIconBut(block, BUT, B_VIEWRENDER, ICON_SCENE_DEHLT, xco,0,XIC,YIC, NULL, 0, 1.0, 0, 0, "Render this window (hold CTRL for anim)"); diff --git a/source/blender/src/mywindow.c b/source/blender/src/mywindow.c index 3e0909eb99e..9071d5e919d 100644 --- a/source/blender/src/mywindow.c +++ b/source/blender/src/mywindow.c @@ -107,10 +107,14 @@ void mywindow_init_mainwin(Window *win, int orx, int ory, int sizex, int sizey) glGetIntegerv(GL_BLUE_BITS, &b); mainwin_color_depth= r + g + b; - + if(G.f & G_DEBUG) { + printf("Color depth r %d g %d b %d\n", (int)r, (int)g, (int)b); + glGetIntegerv(GL_AUX_BUFFERS, &r); + printf("Aux buffers: %d\n", (int)r); + } } -/* XXXXXXXXXXXXXXXX very hacky, not allowed to release +/* XXXXXXXXXXXXXXXX very hacky, not allowed to release again after 2.24 * again after 2.24 */ void mywindow_build_and_set_renderwin(void) diff --git a/source/blender/src/view.c b/source/blender/src/view.c index d495736905f..9f8e65da670 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -181,8 +181,8 @@ void project_short(float *vec, short *adr) /* clips */ fy= (curarea->winy/2)+(curarea->winy/2)*vec4[1]/vec4[3]; if(fy>0.0 && fy< (float)curarea->winy) { - adr[0]= floor(fx+0.5); - adr[1]= floor(fy+0.5); + adr[0]= floor(fx); + adr[1]= floor(fy); } } } @@ -206,8 +206,8 @@ void project_short_noclip(float *vec, short *adr) fy= (curarea->winy/2)+(curarea->winy/2)*vec4[1]/vec4[3]; if(fy>-32700.0 && fy<32700.0) { - adr[0]= floor(fx+0.5); - adr[1]= floor(fy+0.5); + adr[0]= floor(fx); + adr[1]= floor(fy); } } } |