clip.c

来自「FreeFem++可以生成高质量的有限元网格。可以用于流体力学」· C语言 代码 · 共 346 行

C
346
字号
#include "medit.h"#include "extern.h"#include "sproto.h"static pClip     cclip   = 0;static ubyte     curclip = 0;static GLfloat   plane[4]  = {-1.0, 0.0, 0.0, 0.0};static void drawCap(pScene sc,pClip clip,GLboolean docap) {  if ( !docap ) {      if ( clip->active & C_EDIT )        glColor3f(1.0,0.0,1.0);    else if ( clip->active & C_FREEZE ) glColor3f(0.0,0.6,0.9);    else                                glColor3f(0.0,1.0,0.0);    glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);    glLineWidth(3.);    glBegin(GL_QUADS);      glVertex3f(0.,-1.,-1.);      glVertex3f(0., 1.,-1.);      glVertex3f(0., 1.,1.);      glVertex3f(0.,-1.,1.);    glEnd();    glLineWidth(1.);    glColor3f(1.,0.7,0.);    glBegin(GL_LINES);      glVertex3f(0.,0.,-1.);      glVertex3f(0.,0.,1.);      glColor3f(1.,0.7,0.);      glVertex3f(0.,-1.,0.);      glVertex3f(0.,1.,0.);    glEnd();    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);  }  else {    glDisable(GL_LIGHTING);    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);        glColor4fv(sc->material[DEFAULT_MAT].dif);    glRecti(-100,-100,100,100);  }}/* display clipping plane */void updateClip(pClip clip,pMesh mesh) {  pScene      sc;  pTransform  cliptr,view;  GLfloat     dd,dmax,inv[16],axis[4],trans[4],matrix[16];  int         idw;  /* default */  if ( ddebug ) printf("updateClip\n");  /* retrieve context */  idw    = currentScene();  sc     = cv.scene[idw];  view   = sc->view;  cliptr = clip->cliptr;  /* compute clip transform */  if ( clip->active & C_EDIT ) {    invertMatrix(view->matrix,inv);    inv[3] = inv[7] = inv[11] = 0.0;  inv[15] = 1.0;        /* rotation cumulative */    if ( cliptr->angle != 0.0 ) {      transformVector(trans,cliptr->axis,inv);      glPushMatrix();      glLoadIdentity();      glRotatef(cliptr->angle,trans[0],trans[1],trans[2]);      glMultMatrixf(cliptr->rot);      glGetFloatv(GL_MODELVIEW_MATRIX,cliptr->rot);      glPopMatrix();    }    /* translation cumulative */    axis[0] = cliptr->panx;    axis[1] = cliptr->pany;    axis[2] = 0.0;    axis[3] = 1.0;    if ( cliptr->manim == GL_FALSE )      cliptr->panx = cliptr->pany = 0.0;    transformVector(trans,axis,inv);    dd = trans[0]*clip->eqn[0]+trans[1]*clip->eqn[1]+trans[2]*clip->eqn[2];    trans[0] = dd*clip->eqn[0];    trans[1] = dd*clip->eqn[1];    trans[2] = dd*clip->eqn[2];    cliptr->tra[12] += trans[0];    cliptr->tra[13] += trans[1];    cliptr->tra[14] += trans[2];    /* truncation */    dmax = mesh->xmax - mesh->xmin;    dmax = max(dmax,mesh->ymax - mesh->ymin);    dmax = max(dmax,mesh->zmax - mesh->zmin) / 1.8;    if ( fabs(cliptr->tra[12]) > dmax || fabs(cliptr->tra[13]) > dmax ||         fabs(cliptr->tra[14]) > dmax ) {      if ( cliptr->manim == GL_TRUE ) {        cliptr->panx = -cliptr->panx;        cliptr->pany = -cliptr->pany;      }      else {        cliptr->tra[12] = max(-dmax,min(dmax,cliptr->tra[12]));        cliptr->tra[13] = max(-dmax,min(dmax,cliptr->tra[13]));        cliptr->tra[14] = max(-dmax,min(dmax,cliptr->tra[14]));      }    }    /* final transformation */    glPushMatrix();    glLoadIdentity();    glMultMatrixf(cliptr->tra);    glMultMatrixf(cliptr->rot);    glGetFloatv(GL_MODELVIEW_MATRIX,cliptr->matrix);    glPopMatrix();    /* compute plane equation */    invertMatrix(cliptr->matrix,inv);    transformPoint(clip->eqn,plane,inv);    if ( clip->active & C_REDO )      clipVertices(mesh,sc,clip);   /* clip->active |= C_REDO;*/  }  else if ( clip->active & C_FREEZE ) {    glPushMatrix();    glLoadMatrixf(view->matrix);    glTranslatef(sc->cx,sc->cy,sc->cz);    glGetFloatv(GL_MODELVIEW_MATRIX,matrix);    glPopMatrix();    invertMatrix(matrix,inv);    inv[3] = inv[7] = inv[11] = 0.0;  inv[15] = 1.0;    glPushMatrix();    glLoadMatrixf(inv);    glMultMatrixf(view->oldmat);    glTranslatef(sc->cx,sc->cy,sc->cz);    glMultMatrixf(cliptr->matrix);    glGetFloatv(GL_MODELVIEW_MATRIX,cliptr->matrix);    glPopMatrix();    /* compute plane equation */    invertMatrix(cliptr->matrix,inv);    transformPoint(clip->eqn,plane,inv);    clip->active |= C_REDO;  }  if ( !cliptr->manim ) {    cliptr->angle = 0.0;    clip->active ^= C_UPDATE;  }}void clipVertices(pMesh mesh,pScene sc,pClip clip) {  pTetra     pt;  pHexa      ph;  pPoint     p0;  double     dd1,zero;  int        k,l,nbpos,nbneg,nbnul;  /* check points in plane */  zero = sc->dmax*1.e-13;  for (k=1; k<=mesh->np; k++) {    p0 = &mesh->point[k];    if ( p0->tag & M_UNUSED )  continue;    dd1 = p0->c[0]*clip->eqn[0] + p0->c[1]*clip->eqn[1] \        + p0->c[2]*clip->eqn[2] + clip->eqn[3];    if ( dd1 > zero )      p0->clip = 2;    else if ( dd1 < zero ) p0->clip = 1;    else                   p0->clip = 0;  }  /* update tetrahedra */  for (k=1; k<=mesh->ntet; k++) {    pt = &mesh->tetra[k];    pt->clip = 0;    nbpos = nbneg = nbnul = 0;    for (l=0; l<4; l++) {      p0  = &mesh->point[pt->v[l]];      if ( p0->clip == 2 )       nbpos++;      else if ( p0->clip == 1 )  nbneg++;      else                       nbnul++;    }    if ( nbpos && nbpos+nbnul < 4 )  pt->clip = 1;  }  /* update hexahedra */  for (k=1; k<=mesh->nhex; k++) {    ph = &mesh->hexa[k];    ph->clip = 0;    nbpos = nbneg = nbnul = 0;    for (l=0; l<8; l++) {      p0  = &mesh->point[ph->v[l]];      if ( p0->clip == 2 )       nbpos++;      else if ( p0->clip == 1 )  nbneg++;      else                       nbnul++;    }    if ( nbpos && nbpos+nbnul < 8 )  ph->clip = 1;  }}void drawClip(pScene sc,pClip clip,pMesh mesh,GLboolean docap) {  pTransform  cliptr,view;  GLfloat     scale;  /* default */  if ( ddebug ) printf("drawClip\n");  view   = sc->view;  cliptr = clip->cliptr;  if ( clip->active & C_UPDATE )  updateClip(clip,mesh);  if ( clip->active & C_REDO ) {    if ( !animate )  glutSetCursor(GLUT_CURSOR_WAIT);    /* update clip plane */    clipVertices(mesh,sc,clip);    /* build display lists */    if ( clip->active & C_VOL ) {      if ( sc->clist[LTets] )  glDeleteLists(sc->clist[LTets],1);      if ( sc->clist[LHexa] )  glDeleteLists(sc->clist[LHexa],1);      if ( sc->cmlist[LTets] ) glDeleteLists(sc->cmlist[LTets],1);      if ( sc->cmlist[LHexa] ) glDeleteLists(sc->cmlist[LHexa],1);      sc->clist[LTets] = sc->cmlist[LTets] = (GLuint)0;      sc->clist[LHexa] = sc->cmlist[LHexa] = (GLuint)0;      if ( clip->active & C_CAP ) {        sc->clist[LTets]  = capTetra(mesh);        if ( sc->mode & S_MAP )          sc->cmlist[LTets] = capTetraMap(mesh);        else if ( sc->isotyp & S_ISOLINE )          sc->ilist[LTets] = capTetraIso(mesh);      }      else {        sc->clist[LTets] = listTetra(sc,mesh,1);        sc->clist[LHexa] = listHexa(sc,mesh,1);        if ( sc->mode & S_MAP ) {          sc->cmlist[LTets] = listTetraMap(sc,mesh,1);          sc->cmlist[LHexa] = listHexaMap(sc,mesh,1);        }      }      if ( !animate )  clip->active ^= C_REDO;    }    else clip->active ^= C_REDO;        if ( sc->isotyp & S_VECTOR ) {      if ( sc->vlist[LTets] )  glDeleteLists(sc->vlist[LTets],1);        sc->vlist[LTets] = listClipTetraVector(mesh);      if ( sc->vlist[LHexa] )  glDeleteLists(sc->vlist[LHexa],1);        sc->vlist[LHexa] = listClipHexaVector(mesh);    }    if ( !animate )  glutSetCursor(GLUT_CURSOR_INHERIT);  }  /* display plane frame */  if ( clip->active & C_HIDE )  return;  glPushMatrix();  glMultMatrixf(cliptr->matrix);  scale = 0.3*(sc->dmax+sc->dmin);  glScalef(scale,scale,scale);  drawCap(sc,clip,docap);  glPopMatrix();}void copyClip(pClip clip) {  if ( !cclip ) {    cclip = (pClip)M_calloc(1,sizeof(struct clip),"clip");    if ( !clip )  exit(2);  }  cclip = (pClip)memcpy(cclip,clip,sizeof(struct clip));  if ( !cclip )  exit(2);  curclip = 1;}int pasteClip(pClip clip) {  if ( !curclip )  return(0);  clip = (pClip)memcpy(clip,cclip,sizeof(struct clip));  if ( !clip )  exit(2);  clip->active = 0;  curclip = 0;  return(1);}void tiltClip(pScene sc,pClip clip) {   float    axis[4];    axis[0] = clip->cliptr->axis[0];  axis[1] = clip->cliptr->axis[1];  axis[2] = clip->cliptr->axis[2];  transformVector(clip->cliptr->axis,axis,sc->view->matrix);  /*clip->cliptr->angle = 90.0;*/  clip->active |= C_REDO;}/* change clip orientation */void invertClip(pScene sc,pClip clip) {  clip->eqn[0] = -clip->eqn[0];  clip->eqn[1] = -clip->eqn[1];  clip->eqn[2] = -clip->eqn[2];  clip->eqn[3] = -clip->eqn[3];  plane[0]     = -plane[0];}void resetClip(pScene sc,pClip clip,pMesh mesh) {  double    dd;  resetTransform(clip->cliptr);  dd = sc->par.clip[0]*sc->par.clip[3] + sc->par.clip[1]*sc->par.clip[4] \     + sc->par.clip[2]*sc->par.clip[5];  clip->active |= C_REDO;  clip->eqn[0] = sc->par.clip[3];  clip->eqn[1] = sc->par.clip[4];  clip->eqn[2] = sc->par.clip[5];  clip->eqn[3] = -dd;  /*clip->active = C_ON + C_VOL;*/}/* create a clipping plane */pClip createClip(pScene sc,pMesh mesh) {  pClip    clip;  /* default */  clip = (pClip)M_calloc(1,sizeof(struct clip),"clip");  assert(clip);  clip->cliptr = (pTransform)M_calloc(1,sizeof(struct transform),"clip");  assert(clip->cliptr);  resetClip(sc,clip,mesh);  return(clip);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?