mlists.c

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

C
1,310
字号
#include "medit.h"#include "extern.h"#include "sproto.h"static int ct[4][3] = { {0,1,2}, {0,3,1}, {1,3,2}, {0,2,3} };static int ch[6][4] = { {0,1,2,3}, {4,5,6,7}, {0,1,5,4},             {1,2,6,5}, {2,3,7,6}, {0,3,7,4} };/* recursively subdivide a triangle */void cutTriangle(pScene sc,triangle t) {  triangle      t1,t2;  double        kc,x,dd,rgb[4],maxe;  int           i,ia,ib,ic,iedge;  static double hsv[3] = { 0.0f, 1.0f, 0.80f };  /* analyze triangle edges */  if ( t.va < sc->iso.val[0] )      t.va = sc->iso.val[0];  else if ( t.va > sc->iso.val[MAXISO-1] )    t.va = sc->iso.val[MAXISO-1];  if ( t.vb < sc->iso.val[0] )      t.vb = sc->iso.val[0];  else if ( t.vb > sc->iso.val[MAXISO-1] )    t.vb = sc->iso.val[MAXISO-1];  if ( t.vc < sc->iso.val[0] )      t.vc = sc->iso.val[0];  else if ( t.vc > sc->iso.val[MAXISO-1] )    t.vc = sc->iso.val[MAXISO-1];  for (ia=0; ia<MAXISO-1; ia++)    if ( t.va < sc->iso.val[ia] )  break;  for (ib=0; ib<MAXISO-1; ib++)    if ( t.vb < sc->iso.val[ib] )  break;  for (ic=0; ic<MAXISO-1; ic++)    if ( t.vc < sc->iso.val[ic] )  break;  /* search longest edge */  maxe  = fabs(t.va-t.vb);  iedge = 1;  if ( maxe < fabs(t.vb-t.vc) ) {    maxe  = fabs(t.vb-t.vc);    iedge = 2;  }  if ( maxe < fabs(t.va-t.vc) ) {    maxe = fabs(t.va-t.vc);    iedge = 3;  }  /* split longest edge */  if ( maxe > 0.0 ) {    switch( iedge ) {    case 1:  /* edge a-b */      x  = ia < ib ? sc->iso.val[ia] : sc->iso.val[ib];      dd = (x-t.va) / (t.vb-t.va);      if ( dd > 0.001 && dd < 0.999 ) {        memcpy(&t1,&t,sizeof(struct triangle));        memcpy(&t2,&t,sizeof(struct triangle));        for (i=0; i<3; i++) {          t1.b[i]  = t2.a[i]  = t.a[i]  + dd*(t.b[i] -t.a[i]);          t1.nb[i] = t2.na[i] = t.na[i] + dd*(t.nb[i]-t.na[i]);        }        t1.vb = t2.va = x;        cutTriangle(sc,t1);        cutTriangle(sc,t2);        return;      }      break;    case 2:  /* edge b-c */      x  = ib < ic ? sc->iso.val[ib] : sc->iso.val[ic];      dd = (x-t.vb) / (t.vc-t.vb);      if ( dd > 0.001f && dd < 0.999f ) {        memcpy(&t1,&t,sizeof(struct triangle));        memcpy(&t2,&t,sizeof(struct triangle));        for (i=0; i<3; i++) {          t1.c[i]  = t2.b[i]  = t.b[i]  + dd*(t.c[i] -t.b[i]);          t1.nc[i] = t2.nb[i] = t.nb[i] + dd*(t.nc[i]-t.nb[i]);        }        t1.vc = t2.vb = x;        cutTriangle(sc,t1);        cutTriangle(sc,t2);        return;      }      break;    case 3:  /* edge c-a */      x  = ia < ic ? sc->iso.val[ia] : sc->iso.val[ic];      dd = (x-t.va) / (t.vc-t.va);      if ( dd > 0.001f && dd < 0.999f ) {        memcpy(&t1,&t,sizeof(struct triangle));        memcpy(&t2,&t,sizeof(struct triangle));        for (i=0; i<3; i++) {          t1.c[i]  = t2.a[i]  = t.a[i]  + dd*(t.c[i] -t.a[i]);          t1.nc[i] = t2.na[i] = t.na[i] + dd*(t.nc[i]-t.na[i]);        }        t1.vc = t2.va = x;        cutTriangle(sc,t1);        cutTriangle(sc,t2);        return;      }      break;    }  }  /* draw triangle */  if ( t.va < sc->iso.val[0] )     t.va = sc->iso.val[0];    else if ( t.va > sc->iso.val[MAXISO-1] )    t.va = sc->iso.val[MAXISO-1];  kc = (t.va-sc->iso.val[ia-1]) / (sc->iso.val[ia] - sc->iso.val[ia-1]);  hsv[0] = sc->iso.col[ia-1]*(1.0-kc)+sc->iso.col[ia]*kc;  hsvrgb(hsv,rgb);  glColor4dv(rgb);  glNormal3fv(t.na);  glVertex3fv(t.a);  if ( t.vb < sc->iso.val[0] )     t.vb = sc->iso.val[0];  else if ( t.vb > sc->iso.val[MAXISO-1] )    t.vb = sc->iso.val[MAXISO-1];  kc = (t.vb-sc->iso.val[ib-1]) / (sc->iso.val[ib] - sc->iso.val[ib-1]);  hsv[0] = sc->iso.col[ib-1]*(1.0-kc)+sc->iso.col[ib]*kc;  hsvrgb(hsv,rgb);  glColor4dv(rgb);  glNormal3fv(t.nb);  glVertex3fv(t.b);  if ( t.vc < sc->iso.val[0] )     t.vc = sc->iso.val[0];  else if ( t.vc > sc->iso.val[MAXISO-1] )    t.vc = sc->iso.val[MAXISO-1];  kc = (t.vc-sc->iso.val[ic-1]) / (sc->iso.val[ic] - sc->iso.val[ic-1]);  hsv[0] = sc->iso.col[ic-1]*(1.0-kc)+sc->iso.col[ic]*kc;  hsvrgb(hsv,rgb);  glColor4dv(rgb);  glNormal3fv(t.nc);  glVertex3fv(t.c);}/* metric map: use linear interpolation on values   rather than color interpolation ! */GLuint listTriaMap(pScene sc,pMesh mesh) {  pMaterial  pm;  pTriangle  pt;  pPoint     p0,p1,p2;  pSolution  ps0,ps1,ps2;  GLint      dlist;  double     ax,ay,az,bx,by,bz,dd;  float      cx,cy,cz,n[3];  int        k,m,is0,is1,is2;  triangle   t;  /* default */  if ( !mesh->nt )  return(0);  if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) )  return(0);  if ( ddebug ) printf("create display list map / TRIA\n");  /* build display list */  dlist = glGenLists(1);  glNewList(dlist,GL_COMPILE);  if ( glGetError() )  return(0);  /* build list */  for (m=0; m<sc->par.nbmat; m++) {    pm = &sc->material[m];    k  = pm->depmat[LTria];    if ( !k || pm->flag )  continue;    if ( sc->type & S_FLAT ) {      glBegin(GL_TRIANGLES);      while ( k != 0 ) {        pt = &mesh->tria[k];        if ( !pt->v[0] ) {          k = pt->nxt;          continue;        }        p0 = &mesh->point[pt->v[0]];        p1 = &mesh->point[pt->v[1]];        p2 = &mesh->point[pt->v[2]];          /* compute normal */        ax = p1->c[0] - p0->c[0];        ay = p1->c[1] - p0->c[1];        az = p1->c[2] - p0->c[2];        bx = p2->c[0] - p0->c[0];        by = p2->c[1] - p0->c[1];        bz = p2->c[2] - p0->c[2];        n[0] = ay*bz - az*by;        n[1] = az*bx - ax*bz;        n[2] = ax*by - ay*bx;        dd = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];        if ( dd > 0.0f ) {          dd = 1.0f / sqrt(dd);          n[0] *= dd;          n[1] *= dd;          n[2] *= dd;        }        memcpy(t.na,n,3*sizeof(float));        memcpy(t.nb,n,3*sizeof(float));        memcpy(t.nc,n,3*sizeof(float));        if ( sc->shrink < 1.0 ) {          cx = (p0->c[0] + p1->c[0] + p2->c[0]) / 3.0;          cy = (p0->c[1] + p1->c[1] + p2->c[1]) / 3.0;          cz = (p0->c[2] + p1->c[2] + p2->c[2]) / 3.0;          t.a[0] = sc->shrink*(p0->c[0]-cx)+cx;          t.a[1] = sc->shrink*(p0->c[1]-cy)+cy;          t.a[2] = sc->shrink*(p0->c[2]-cz)+cz;          t.b[0] = sc->shrink*(p1->c[0]-cx)+cx;          t.b[1] = sc->shrink*(p1->c[1]-cy)+cy;          t.b[2] = sc->shrink*(p1->c[2]-cz)+cz;          t.c[0] = sc->shrink*(p2->c[0]-cx)+cx;          t.c[1] = sc->shrink*(p2->c[1]-cy)+cy;          t.c[2] = sc->shrink*(p2->c[2]-cz)+cz;        }        else {          t.a[0] = p0->c[0];          t.a[1] = p0->c[1];          t.a[2] = p0->c[2];          t.b[0] = p1->c[0];          t.b[1] = p1->c[1];          t.b[2] = p1->c[2];          t.c[0] = p2->c[0];          t.c[1] = p2->c[1];          t.c[2] = p2->c[2];        }        if ( mesh->typage == 2 ) {          ps0  = &mesh->sol[pt->v[0]];          ps1  = &mesh->sol[pt->v[1]];          ps2  = &mesh->sol[pt->v[2]];          t.va = ps0->bb;          t.vb = ps1->bb;          t.vc = ps2->bb;        }        else {          ps0 = &mesh->sol[k];          t.va = t.vb = t.vc = ps0->bb;        }        cutTriangle(sc,t);        k = pt->nxt;      }      glEnd();    }    else {      glBegin(GL_TRIANGLES);      while ( k != 0 ) {        pt = &mesh->tria[k];        if ( !pt->v[0] ) {          k = pt->nxt;          continue;        }        p0 = &mesh->point[pt->v[0]];        p1 = &mesh->point[pt->v[1]];        p2 = &mesh->point[pt->v[2]];        /* compute normal */        ax = p1->c[0] - p0->c[0];        ay = p1->c[1] - p0->c[1];        az = p1->c[2] - p0->c[2];        bx = p2->c[0] - p0->c[0];        by = p2->c[1] - p0->c[1];        bz = p2->c[2] - p0->c[2];        n[0] = ay*bz - az*by;        n[1] = az*bx - ax*bz;        n[2] = ax*by - ay*bx;        dd = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];        if ( dd > 0.0f ) {      dd = 1.0f / sqrt(dd);      n[0] *= dd;      n[1] *= dd;      n[2] *= dd;        }        is0 = is1 = is2 = 0;        if ( mesh->extra->iv ) {          if ( pt->v[0] <= mesh->nvn )            is0 = mesh->extra->nv[pt->v[0]];          if ( pt->v[1] <= mesh->nvn )            is1 = mesh->extra->nv[pt->v[1]];          if ( pt->v[2] <= mesh->nvn )            is2 = mesh->extra->nv[pt->v[2]];        }        if ( !is0 && pt->v[0] <= mesh->extra->it )          is0 = mesh->extra->nt[3*(k-1)+1];        if ( !is1 && pt->v[1] <= mesh->extra->it )            is1 = mesh->extra->nt[3*(k-1)+2];        if ( !is2 && pt->v[2] <= mesh->extra->it )          is2 = mesh->extra->nt[3*(k-1)+3];        if ( sc->shrink < 1.0 ) {          cx = (p0->c[0] + p1->c[0] + p2->c[0]) / 3.;          cy = (p0->c[1] + p1->c[1] + p2->c[1]) / 3.;          cz = (p0->c[2] + p1->c[2] + p2->c[2]) / 3.;          t.a[0] = sc->shrink*(p0->c[0]-cx)+cx;          t.a[1] = sc->shrink*(p0->c[1]-cy)+cy;          t.a[2] = sc->shrink*(p0->c[2]-cz)+cz;          t.b[0] = sc->shrink*(p1->c[0]-cx)+cx;          t.b[1] = sc->shrink*(p1->c[1]-cy)+cy;          t.b[2] = sc->shrink*(p1->c[2]-cz)+cz;          t.c[0] = sc->shrink*(p2->c[0]-cx)+cx;          t.c[1] = sc->shrink*(p2->c[1]-cy)+cy;          t.c[2] = sc->shrink*(p2->c[2]-cz)+cz;        }        else {          t.a[0] = p0->c[0];          t.a[1] = p0->c[1];          t.a[2] = p0->c[2];          t.b[0] = p1->c[0];          t.b[1] = p1->c[1];          t.b[2] = p1->c[2];          t.c[0] = p2->c[0];          t.c[1] = p2->c[1];          t.c[2] = p2->c[2];        }        if ( !is0 )          memcpy(t.na,n,3*sizeof(float));        else {          t.na[0] = mesh->extra->n[3*(is0-1)+1];          t.na[1] = mesh->extra->n[3*(is0-1)+2];          t.na[2] = mesh->extra->n[3*(is0-1)+3];        }        if ( !is1 )          memcpy(t.nb,n,3*sizeof(float));        else {          t.nb[0] = mesh->extra->n[3*(is1-1)+1];          t.nb[1] = mesh->extra->n[3*(is1-1)+2];          t.nb[2] = mesh->extra->n[3*(is1-1)+3];        }        if ( !is2 )          memcpy(t.nc,n,3*sizeof(float));        else {          t.nc[0] = mesh->extra->n[3*(is2-1)+1];          t.nc[1] = mesh->extra->n[3*(is2-1)+2];          t.nc[2] = mesh->extra->n[3*(is2-1)+3];        }        if ( mesh->typage == 2 ) {      ps0  = &mesh->sol[pt->v[0]];      ps1  = &mesh->sol[pt->v[1]];      ps2  = &mesh->sol[pt->v[2]];      t.va = ps0->bb;      t.vb = ps1->bb;      t.vc = ps2->bb;        }        else {      ps0 = &mesh->sol[k];      t.va = t.vb = t.vc = ps0->bb;        }        cutTriangle(sc,t);        k = pt->nxt;      }      glEnd();    }  }  glEndList();  return(dlist);}/* build list of quadrilaterals */GLuint listQuadMap(pScene sc,pMesh mesh) {  pMaterial  pm;  pQuad      pq;  pPoint     p0,p1,p2,p3;  pSolution  ps0,ps1,ps2,ps3;  GLint      dlist = 0;  double     ax,ay,az,bx,by,bz,dd;  float      cx,cy,cz,n[3];  int        k,m,is0,is1,is2,is3;  triangle   t1,t2;  /* default */  if ( !mesh->nq ) return(0);  if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) )  return(0);  if ( ddebug ) printf("create display list map / QUADS\n");  /* build display list */  dlist = glGenLists(1);  glNewList(dlist,GL_COMPILE);  if ( glGetError() )  return(0);  /* build list */  for (m=0; m<sc->par.nbmat; m++) {    pm = &sc->material[m];    k  = pm->depmat[LQuad];    if ( !k || pm->flag )  continue;    glBegin(GL_TRIANGLES);    while ( k != 0 ) {      pq = &mesh->quad[k];      if ( pq->v[0] == 0 ) {        k = pq->nxt;        continue;      }      p0 = &mesh->point[pq->v[0]];      p1 = &mesh->point[pq->v[1]];      p2 = &mesh->point[pq->v[2]];      p3 = &mesh->point[pq->v[3]];            /* compute normal */      ax = p1->c[0] - p0->c[0];      ay = p1->c[1] - p0->c[1];      az = p1->c[2] - p0->c[2];      bx = p2->c[0] - p0->c[0];      by = p2->c[1] - p0->c[1];      bz = p2->c[2] - p0->c[2];      n[0] = ay*bz - az*by;      n[1] = az*bx - ax*bz;      n[2] = ax*by - ay*bx;      dd = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];      if ( dd > 0.0f ) {        dd = 1.0f / sqrt(dd);        n[0] *= dd;        n[1] *= dd;        n[2] *= dd;      }      if ( sc->shrink < 1.0 ) {        cx = 0.25 * (p0->c[0] + p1->c[0] + p2->c[0] + p3->c[0]);        cy = 0.25 * (p0->c[1] + p1->c[1] + p2->c[1] + p3->c[1]);        cz = 0.25 * (p0->c[2] + p1->c[2] + p2->c[2] + p3->c[2]);        t1.a[0] = t2.a[0] = sc->shrink*(p0->c[0]-cx)+cx;        t1.a[1] = t2.a[1] = sc->shrink*(p0->c[1]-cy)+cy;        t1.a[2] = t2.a[2] = sc->shrink*(p0->c[2]-cz)+cz;        t1.b[0] = sc->shrink*(p1->c[0]-cx)+cx;        t1.b[1] = sc->shrink*(p1->c[1]-cy)+cy;        t1.b[2] = sc->shrink*(p1->c[2]-cz)+cz;        t1.c[0] = t2.b[0] = sc->shrink*(p2->c[0]-cx)+cx; 

⌨️ 快捷键说明

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