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; atotface; 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; atotedge; 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); + 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->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); + } + 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; atotedge; 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->drawtypeflag & 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->xsys>rect.ymin && eve->ysf|= 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->xsys>rect.ymin && efa->yscent, 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); } } }