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