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 + -
显示快捷键?