picking.c
来自「FreeFem++可以生成高质量的有限元网格。可以用于流体力学」· C语言 代码 · 共 944 行 · 第 1/2 页
C
944 行
glPointSize(5); glBegin(GL_POINTS); for (k=1; k<=mesh->np; k++) { ppt = &mesh->point[k]; kk = 2*k+1; glColor4ub((kk & c->rMask) >> c->rShift << c->rBits, (kk & c->gMask) >> c->gShift << c->gBits, (kk & c->bMask) >> c->bShift << c->bBits, (kk & c->aMask) << c->aBits); if ( mesh->dim == 2 ) glVertex2dv(ppt->c); else glVertex3dv(ppt->c); } glEnd(); glPointSize(1);}static void displayTria(pScene sc,pMesh mesh,Color *c) { pTriangle pt; pPoint p0,p1,p2; pMaterial pm; int m; unsigned int k,kk; glBegin(GL_TRIANGLES); for (m=0; m<sc->par.nbmat; m++) { pm = &sc->material[m]; k = pm->depmat[LTria]; if ( !k || pm->flag ) continue; while ( k != 0 ) { pt = &mesh->tria[k]; if ( pt->v[0] ) { p0 = &mesh->point[pt->v[0]]; p1 = &mesh->point[pt->v[1]]; p2 = &mesh->point[pt->v[2]]; kk = 2*k+1; glColor4ub((kk & c->rMask) >> c->rShift << c->rBits, (kk & c->gMask) >> c->gShift << c->gBits, (kk & c->bMask) >> c->bShift << c->bBits, (kk & c->aMask) << c->aBits); glVertex3dv(p0->c); glVertex3dv(p1->c); glVertex3dv(p2->c); } k = pt->nxt; } } glEnd();}static int displayQuad(pScene sc,pMesh mesh,Color *c) { pQuad pq; pPoint p0,p1,p2,p3; pMaterial pm; int k,m,base; unsigned int kk; base = mesh->nt; glBegin(GL_QUADS); for (m=0; m<sc->par.nbmat; m++) { pm = &sc->material[m]; k = pm->depmat[LQuad]; if ( !k || pm->flag ) continue; while ( k != 0 ) { pq = &mesh->quad[k]; if ( pq->v[0] ) { p0 = &mesh->point[pq->v[0]]; p1 = &mesh->point[pq->v[1]]; p2 = &mesh->point[pq->v[2]]; p3 = &mesh->point[pq->v[3]]; kk = base + k; kk = 2*kk + 1; glColor4ub((kk & c->rMask) >> c->rShift << c->rBits, (kk & c->gMask) >> c->gShift << c->gBits, (kk & c->bMask) >> c->bShift << c->bBits, (kk & c->aMask) << c->aBits); glVertex3f(p0->c[0],p0->c[1],p0->c[2]); glVertex3f(p1->c[0],p1->c[1],p1->c[2]); glVertex3f(p2->c[0],p2->c[1],p2->c[2]); glVertex3f(p3->c[0],p3->c[1],p3->c[2]); } k = pq->nxt; } } glEnd();}static int displayTets(pScene sc,pMesh mesh,Color *c) { pTetra ptt; pPoint p0,p1,p2; pMaterial pm; pClip clip; int k,l,m,base; unsigned int kk; clip = sc->clip; base = mesh->nt + mesh->nq; glBegin(GL_TRIANGLES); for (m=0; m<sc->par.nbmat; m++) { pm = &sc->material[m]; k = pm->depmat[LTets]; if ( !k || pm->flag ) continue; while ( k != 0 ) { ptt = &mesh->tetra[k]; if ( ptt->v[0] ) { if ( (clip->active & C_ON && ptt->clip) || !(clip->active & C_ON) ) { kk = base + k; kk = 2*kk + 1; for (l=0; l<4; l++) { p0 = &mesh->point[ptt->v[ct[l][0]]]; p1 = &mesh->point[ptt->v[ct[l][1]]]; p2 = &mesh->point[ptt->v[ct[l][2]]]; glColor4ub((kk & c->rMask) >> c->rShift << c->rBits, (kk & c->gMask) >> c->gShift << c->gBits, (kk & c->bMask) >> c->bShift << c->bBits, (kk & c->aMask) << c->aBits); glVertex3f(p0->c[0],p0->c[1],p0->c[2]); glVertex3f(p1->c[0],p1->c[1],p1->c[2]); glVertex3f(p2->c[0],p2->c[1],p2->c[2]); } } } k = ptt->nxt; } } glEnd();}static int displayHexa(pScene sc,pMesh mesh,Color *c) { pHexa ph; pPoint p0,p1,p2,p3; pMaterial pm; pClip clip; int k,l,m,base; unsigned int kk; clip = sc->clip; base = mesh->nt + mesh->nq + mesh->ntet; glBegin(GL_QUADS); for (m=0; m<sc->par.nbmat; m++) { pm = &sc->material[m]; k = pm->depmat[LHexa]; if ( !k || pm->flag ) continue; while ( k != 0 ) { ph = &mesh->hexa[k]; if ( ph->v[0] ) { if ( (clip->active & C_ON && ph->clip) || !(clip->active & C_ON) ) { kk = base + k; kk = 2*kk + 1; for (l=0; l<6; l++) { p0 = &mesh->point[ph->v[ch[l][0]]]; p1 = &mesh->point[ph->v[ch[l][1]]]; p2 = &mesh->point[ph->v[ch[l][2]]]; p3 = &mesh->point[ph->v[ch[l][3]]]; glColor4ub((kk & c->rMask) >> c->rShift << c->rBits, (kk & c->gMask) >> c->gShift << c->gBits, (kk & c->bMask) >> c->bShift << c->bBits, (kk & c->aMask) << c->aBits); glVertex3f(p0->c[0],p0->c[1],p0->c[2]); glVertex3f(p1->c[0],p1->c[1],p1->c[2]); glVertex3f(p2->c[0],p2->c[1],p2->c[2]); glVertex3f(p3->c[0],p3->c[1],p3->c[2]); } } } k = ph->nxt; } } glEnd();}void drawModelSimple(pScene sc,pMesh mesh,Color *c) { glDisable(GL_BLEND); glDisable(GL_LIGHTING); glShadeModel(GL_FLAT); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); if ( sc->clip->active & C_ON ) { glClipPlane(GL_CLIP_PLANE0,sc->clip->eqn); glEnable(GL_CLIP_PLANE0); if ( mesh->nt ) displayTria(sc,mesh,c); if ( mesh->nq ) displayQuad(sc,mesh,c); glDisable(GL_CLIP_PLANE0); if ( sc->clip->active & C_VOL ) { if ( mesh->ntet ) displayTets(sc,mesh,c); if ( mesh->nhex ) displayHexa(sc,mesh,c); } } else { if ( mesh->nt ) displayTria(sc,mesh,c); if ( mesh->nq ) displayQuad(sc,mesh,c); if ( mesh->dim == 3 ) { if ( !mesh->nt ) displayTets(sc,mesh,c); if ( !mesh->nq ) displayHexa(sc,mesh,c); } } if ( !mesh->ne ) displayPoint(sc,mesh,c); glEnable(GL_LIGHTING); glShadeModel(GL_SMOOTH); glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);}static int closestPoint(pScene sc,pMesh mesh,int x,int y,int item,int type) { pTriangle pt; pQuad pq; pTetra pte; pHexa ph; pPoint ppt; GLdouble projmat[16],winx,winy,winz,matrix[16]; GLint viewport[4]; double dd,dmin; int i,id; glGetDoublev(GL_PROJECTION_MATRIX,projmat); glGetIntegerv(GL_VIEWPORT,viewport); glGetDoublev(GL_MODELVIEW_MATRIX,matrix); y = viewport[3] - y; id = -1; dmin = 1.e20; switch(type) { case LTria: pt = &mesh->tria[item]; for (i=0; i<3; i++) { ppt = &mesh->point[pt->v[i]]; gluProject(ppt->c[0],ppt->c[1],ppt->c[2], matrix,projmat,viewport, &winx,&winy,&winz); dd = (winx - x)*(winx - x) + (winy - y)*(winy - y); if ( dd < dmin ) { dmin = dd; id = i; } } return(pt->v[id]); case LQuad: pq = &mesh->quad[item]; for (i=0; i<4; i++) { ppt = &mesh->point[pq->v[i]]; gluProject(ppt->c[0]-sc->cx,ppt->c[1]-sc->cy,ppt->c[2]-sc->cz, matrix,projmat,viewport, &winx,&winy,&winz); dd = (winx - x)*(winx - x) + (winy - y)*(winy - y); if ( dd < dmin ) { dmin = dd; id = i; } } return(pq->v[id]); case LTets: pte = &mesh->tetra[item]; for (i=0; i<4; i++) { ppt = &mesh->point[pte->v[i]]; gluProject(ppt->c[0]-sc->cx,ppt->c[1]-sc->cy,ppt->c[2]-sc->cz, matrix,projmat,viewport, &winx,&winy,&winz); dd = (winx - x)*(winx - x) + (winy - y)*(winy - y); if ( dd < dmin ) { dmin = dd; id = i; } } return(pte->v[id]); case LHexa: ph = &mesh->hexa[item]; for (i=0; i<8; i++) { ppt = &mesh->point[ph->v[i]]; gluProject(ppt->c[0]-sc->cx,ppt->c[1]-sc->cy,ppt->c[2]-sc->cz, matrix,projmat,viewport, &winx,&winy,&winz); dd = (winx - x)*(winx - x) + (winy - y)*(winy - y); if ( dd < dmin ) { dmin = dd; id = i; } } return(ph->v[id]); } return(0);}GLuint pickingScene(pScene sc,int x,int y,int ident) { pMesh mesh; pClip clip; GLint viewport[4]; GLubyte pixel[4]; GLuint dlist; Color c; int k; unsigned int item; dlist = 0; refitem = 0; refmat = -1; mesh = cv.mesh[sc->idmesh]; clip = sc->clip; if ( !getColorRange(&c,mesh) ) return(dlist); glGetIntegerv(GL_VIEWPORT,viewport); glDrawBuffer(GL_BACK_LEFT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.,0.,-sc->persp->depth, 0.,0.,0., 0.0,1.0,0.0); setupView(sc); glMultMatrixf(sc->view->matrix); glTranslatef(sc->cx,sc->cy,sc->cz); drawModelSimple(sc,mesh,&c); glFlush(); /* process color */ glReadBuffer(GL_BACK_LEFT); glReadPixels(x,viewport[3]-y,1,1, GL_RGBA,GL_UNSIGNED_BYTE,(void *)pixel); glDrawBuffer(GL_BACK_LEFT); if ( ddebug ) printf("pixel %d %d %d %d\n",pixel[0],pixel[1],pixel[2],pixel[3]); item = pixel[0] >> c.rBits << c.rShift & c.rMask; item += pixel[1] >> c.gBits << c.gShift & c.gMask; item += pixel[2] >> c.bBits << c.bShift & c.bMask; item += pixel[3] >> c.aBits & c.aMask; item /= 2; if ( !item ) return(dlist); if ( ddebug ) printf("item %d\n",item); if ( !mesh->ne ) { if ( item <= mesh->np ) { refitem = item; reftype = LPoint; } } else if ( item <= mesh->nt ) { refitem = item; reftype = LTria; } else if ( item <= mesh->nt+mesh->nq ) { refitem = item - mesh->nt; reftype = LQuad; } else if ( item <= mesh->nt+mesh->nq+mesh->ntet ) { refitem = item - (mesh->nt+mesh->nq); reftype = LTets; } else if ( item <= mesh->nt+mesh->nq+mesh->ntet+mesh->nhex ) { refitem = item - (mesh->nt+mesh->nq+mesh->ntet); reftype = LHexa; } /* peculiar case: vertex */ if ( refitem > 0 && ident == LPoint ) { if ( mesh->ne ) { refitem = closestPoint(sc,mesh,x,y,refitem,reftype); reftype = LPoint; } } if ( refitem > 0 ) { dlist = glGenLists(1); glNewList(dlist,GL_COMPILE); if ( glGetError() ) return(0); switch(reftype) { case LPoint: if ( refitem <= mesh->np && !mesh->ne ) { for (k=1; k<=mesh->np; k++) { /*drawPoint(sc,mesh,k);*/ infoEntity(sc,mesh,k,LPoint); } } else { drawPoint(sc,mesh,refitem); infoEntity(sc,mesh,refitem,LPoint); } break; case LTria: drawTria(sc,mesh,refitem); infoEntity(sc,mesh,refitem,LTria); break; case LQuad: drawQuad(sc,mesh,refitem); infoEntity(sc,mesh,refitem,LQuad); break; case LTets: drawTets(sc,mesh,refitem); infoEntity(sc,mesh,refitem,LTets); break; case LHexa: drawHexa(sc,mesh,refitem); infoEntity(sc,mesh,refitem,LHexa); break; } glEndList(); return(dlist); } else refmat = -1; return(dlist); }GLuint pickItem(pMesh mesh,pScene sc,int numit) { pMaterial pm; pPoint ppt; GLuint dlist; int nm; /* default */ if ( ddebug ) printf("create pickitem list\n"); dlist = glGenLists(1); glNewList(dlist,GL_COMPILE); if ( glGetError() ) return(0); if ( numit <= mesh->np && mesh->ne ) { ppt = &mesh->point[numit]; pm = &sc->material[DEFAULT_MAT]; if ( ppt->tag != M_UNUSED ) { if ( ppt->ref ) { nm = matRef(sc,ppt->ref); /*nm = 1+(ppt->ref-1) % (sc->par.nbmat-1);*/ pm = &sc->material[nm]; } glPointSize(3.0); glColor3f(pm->dif[0],pm->dif[1],pm->dif[2]); output3(ppt->c[0],ppt->c[1],ppt->c[2],"%d",numit); } } if ( numit <= mesh->nt ) drawTria(sc,mesh,numit); if ( numit <= mesh->nq ) drawQuad(sc,mesh,numit); if ( numit <= mesh->ntet ) drawTets(sc,mesh,numit); if ( numit <= mesh->nhex ) drawHexa(sc,mesh,numit); glEndList(); return(dlist);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?