int advectParticle(pScene sc,pMesh mesh) { pParticle pp; pStream st; pTetra pt1; pPoint ppt; double v[4]; int i,j,k,l,base; if ( ddebug ) printf("advect particles\n"); if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); if ( !sc->stream ) return(0); st = sc->stream; if ( mesh->ntet && !hashTetra(mesh) ) return(0); st->xmin = mesh->xmin - mesh->xtra; st->ymin = mesh->ymin - mesh->ytra; st->zmin = mesh->zmin - mesh->ztra; st->xmax = mesh->xmax - mesh->xtra; st->ymax = mesh->ymax - mesh->ytra; st->zmax = mesh->zmax - mesh->ztra; sc->par.cumpertime = 0.0; sc->par.advtim = 0; /* init list */ sc->slist = (GLuint*)calloc(MAX_LST,sizeof(GLuint)); if ( !sc->slist ) return(0); /* point positions */ base = ++mesh->mark; for (i=1; i<=mesh->np; i++) { ppt = &mesh->point[i]; ppt->mark = base; } for (k=1; k<=mesh->ntet; k++) mesh->tetra[k].cpt = 0; l = 1; for (k=1; k<=st->nbstl; k++) { pp = &tp[k]; pp->ct = 0.0; st->listp[l++] = pp->pos[pp->cur][0]; st->listp[l++] = pp->pos[pp->cur][1]; st->listp[l++] = pp->pos[pp->cur][2]; pp->cur = 1; } ++base; l = 1; for (k=1; k<=st->nbstl; k++) { pp = &tp[k]; pp->pos[1][0] = st->listp[l++]; pp->pos[1][1] = st->listp[l++]; pp->pos[1][2] = st->listp[l++]; tp[k].nsdep = locateTetra(mesh,pp->nsdep,++mesh->mark,pp->pos[1],pp->cb); if ( !pp->nsdep ) { for (j=1; j<=mesh->ntet; j++) { pt1 = &mesh->tetra[j]; if ( pt1->mark != mesh->mark && inTetra(mesh,j,pp->pos[1],pp->cb) ) break; } if ( j > mesh->ntet ) continue; else pp->nsdep = j; } pp->norm = field3DInterp(mesh,tp[k].nsdep,tp[k].cb,v); pp->size = sizeTetra(mesh,tp[k].nsdep); if ( pp->size == 0.0 ) pp->step = EPS*sc->dmax; else pp->step = HSIZ * min(pp->size,pp->norm); pp->step = min(0.05*sc->par.dt,pp->step); pp->flag = 1; pp->cur = 1; colorParticle(sc,pp); for (i=2; i<=sc->par.nbpart; i++) { pp->pos[i][0] = pp->pos[1][0]; pp->pos[i][1] = pp->pos[1][1]; pp->pos[i][2] = pp->pos[1][2]; } } return(1); }
/** * \brief Find eigenvalues and vectors of a 2x2 matrix. * \param mm pointer toward the matrix. * \param lambda pointer toward the output eigenvalues. * \param vp eigenvectors. * \return 1. * * \warning not used for now */ int _MMG5_eigen2(double *mm,double *lambda,double vp[2][2]) { double m[3],dd,a1,xn,ddeltb,rr1,rr2,ux,uy; /* init */ ux = 1.0; uy = 0.0; /* normalize */ memcpy(m,mm,3*sizeof(double)); xn = fabs(m[0]); if ( fabs(m[1]) > xn ) xn = fabs(m[1]); if ( fabs(m[2]) > xn ) xn = fabs(m[2]); if ( xn < _MG_EPSD2 ) { lambda[0] = lambda[1] = 0.0; vp[0][0] = 1.0; vp[0][1] = 0.0; vp[1][0] = 0.0; vp[1][1] = 1.0; return(1); } xn = 1.0 / xn; m[0] *= xn; m[1] *= xn; m[2] *= xn; if ( egal(m[1],0.0) ) { rr1 = m[0]; rr2 = m[2]; goto vect; } /* eigenvalues of jacobian */ a1 = -(m[0] + m[2]); ddeltb = a1*a1 - 4.0 * (m[0]*m[2] - m[1]*m[1]); if ( ddeltb < 0.0 ) { fprintf(stderr," Delta: %f\n",ddeltb); ddeltb = 0.0; } ddeltb = sqrt(ddeltb); if ( fabs(a1) < _MG_EPS ) { rr1 = 0.5 * sqrt(ddeltb); rr2 = -rr1; } else if ( a1 < 0.0 ) { rr1 = 0.5 * (-a1 + ddeltb); rr2 = (-m[1]*m[1] + m[0]*m[2]) / rr1; } else if ( a1 > 0.0 ) { rr1 = 0.5 * (-a1 - ddeltb); rr2 = (-m[1]*m[1] + m[0]*m[2]) / rr1; } else { rr1 = 0.5 * ddeltb; rr2 = -rr1; } vect: xn = 1.0 / xn; lambda[0] = rr1 * xn; lambda[1] = rr2 * xn; /* eigenvectors */ a1 = m[0] - rr1; if ( fabs(a1)+fabs(m[1]) < _MG_EPS ) { if (fabs(lambda[1]) < fabs(lambda[0]) ) { ux = 1.0; uy = 0.0; } else { ux = 0.0; uy = 1.0; } } else if ( fabs(a1) < fabs(m[1]) ) { ux = 1.0; uy = -a1 / m[1]; } else if ( fabs(a1) > fabs(m[1]) ) { ux = -m[1] / a1; uy = 1.0; } else if ( fabs(lambda[1]) > fabs(lambda[0]) ) { ux = 0.0; uy = 1.0; } else { ux = 1.0; uy = 0.0; } dd = sqrt(ux*ux + uy*uy); dd = 1.0 / dd; if ( fabs(lambda[0]) > fabs(lambda[1]) ) { vp[0][0] = ux * dd; vp[0][1] = uy * dd; } else { vp[0][0] = uy * dd; vp[0][1] = -ux * dd; } /* orthogonal vector */ vp[1][0] = -vp[0][1]; vp[1][1] = vp[0][0]; return(1); }
GLuint alt2dList(pScene sc,pMesh mesh,int geomtype,float shrink,float altcoef) { pTriangle pt,pt1; pMaterial pm; pQuad pq; pPoint p0,p1,p2,p3; pSolution ps0,ps1,ps2,ps3; GLuint dlist; double ax,ay,az,bx,by,bz,dd,kc,rgb[4]; float cx,cy,cz,n[3]; int *adj,k,m,ia,iadr; ubyte *voy; triangle t,t1,t2; static double hsv[3] = { 0.0, 1.0, 0.80 }; static float nn[3] = {1.0, 0.0, 0.0 }; /* default */ if ( ddebug ) printf("create 2d elevation map list\n"); if ( geomtype == LTria && !mesh->nt ) return(0); if ( geomtype == LQuad && !mesh->nq ) return(0); if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); /* build display list */ dlist = glGenLists(1); glNewList(dlist,GL_COMPILE); if ( glGetError() ) return(0); mesh->zmin = altcoef*mesh->bbmin; mesh->zmax = altcoef*mesh->bbmax; if ( mesh->bbmin*mesh->bbmax < 0.0 ) { mesh->ztra = mesh->zmin; } else { mesh->ztra = 0.95 * mesh->zmin; } switch (geomtype) { case LTria: if ( ddebug ) printf("create triangle list %d\n",mesh->nt); if ( mesh->typage == 1 ) { if ( mesh->nt && !hashTria(mesh) ) return(0); } 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] ) { k = pt->nxt; continue; } p0 = &mesh->point[pt->v[0]]; p1 = &mesh->point[pt->v[1]]; p2 = &mesh->point[pt->v[2]]; if ( mesh->typage == 1 ) ps0 = ps1 = ps2 = &mesh->sol[k]; else { ps0 = &mesh->sol[pt->v[0]]; ps1 = &mesh->sol[pt->v[1]]; ps2 = &mesh->sol[pt->v[2]]; } 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 = (ps0->bb + ps1->bb + ps2->bb) / 3.0; t.a[0] = shrink*(p0->c[0]-cx) + cx; t.a[1] = shrink*(p0->c[1]-cy) + cy; t.a[2] = shrink*(altcoef*ps0->bb-cz) + cz - 0.25*mesh->ztra; t.b[0] = shrink*(p1->c[0]-cx) + cx; t.b[1] = shrink*(p1->c[1]-cy) + cy; t.b[2] = shrink*(altcoef*ps1->bb-cz) + cz - 0.25*mesh->ztra; t.c[0] = shrink*(p2->c[0]-cx) + cx; t.c[1] = shrink*(p2->c[1]-cy) + cy; t.c[2] = shrink*(altcoef*ps2->bb-cz) + cz - 0.25*mesh->ztra; /* 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.0 ) { dd = 1.0 / 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)); t.va = ps0->bb; t.vb = ps1->bb; t.vc = ps2->bb; if ( mesh->typage == 2 ) cutTriangle(sc,t); else { 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]; for (ia=0; ia<MAXISO-1; ia++) if ( t.va < sc->iso.val[ia] ) break; 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); glVertex3fv(t.b); glVertex3fv(t.c); /* add quads to sides (thanks to F. Lagoutiere) */ iadr = 3*(k-1)+1; adj = &mesh->adja[iadr]; voy = &mesh->voy[iadr]; if ( adj[0] && adj[0] < k ) { pt1 = &mesh->tria[ adj[0] ]; p3 = &mesh->point[ pt1->v[voy[0]] ]; ps1 = &mesh->sol[ adj[0] ]; cx = (p1->c[0] + p2->c[0] + p3->c[0]) / 3.0; cy = (p1->c[1] + p2->c[1] + p3->c[1]) / 3.0; cz = ps1->bb; memcpy(t1.a,t.b,3*sizeof(float)); memcpy(t1.b,t.c,3*sizeof(float)); memcpy(t1.c,t.b,3*sizeof(float)); t1.c[2] = shrink*(altcoef*ps1->bb-cz) + cz - 0.25*mesh->ztra; t1.va = ps0->bb; t1.vb = ps0->bb; t1.vc = ps1->bb; memcpy(t1.na,nn,3*sizeof(float)); memcpy(t1.nb,nn,3*sizeof(float)); memcpy(t1.nc,nn,3*sizeof(float)); cutTriangle(sc,t1); memcpy(t1.a,t.c,3*sizeof(float)); memcpy(t1.b,t.c,3*sizeof(float)); memcpy(t1.c,t.b,3*sizeof(float)); t1.b[2] = shrink*(altcoef*ps1->bb-cz) + cz - 0.25*mesh->ztra; t1.c[2] = shrink*(altcoef*ps1->bb-cz) + cz - 0.25*mesh->ztra; t1.va = ps0->bb; t1.vb = ps1->bb; t1.vc = ps1->bb; memcpy(t1.na,nn,3*sizeof(float)); memcpy(t1.nb,nn,3*sizeof(float)); memcpy(t1.nc,nn,3*sizeof(float)); cutTriangle(sc,t1); } if ( adj[1] && adj[1] < k ) { pt1 = &mesh->tria[ adj[1] ]; p3 = &mesh->point[ pt1->v[voy[1]] ]; ps1 = &mesh->sol[ adj[1] ]; cx = (p0->c[0] + p2->c[0] + p3->c[0]) / 3.0; cy = (p0->c[1] + p2->c[1] + p3->c[1]) / 3.0; cz = ps1->bb; memcpy(t1.a,t.a,3*sizeof(float)); memcpy(t1.b,t.c,3*sizeof(float)); memcpy(t1.c,t.a,3*sizeof(float)); t1.c[2] = shrink*(altcoef*ps1->bb-cz) + cz - 0.25*mesh->ztra; t1.va = ps0->bb; t1.vb = ps0->bb; t1.vc = ps1->bb; memcpy(t1.na,nn,3*sizeof(float)); memcpy(t1.nb,nn,3*sizeof(float)); memcpy(t1.nc,nn,3*sizeof(float)); cutTriangle(sc,t1); memcpy(t1.a,t.c,3*sizeof(float)); memcpy(t1.b,t.c,3*sizeof(float)); memcpy(t1.c,t.a,3*sizeof(float)); t1.b[2] = shrink*(altcoef*ps1->bb-cz) + cz - 0.25*mesh->ztra; t1.c[2] = shrink*(altcoef*ps1->bb-cz) + cz - 0.25*mesh->ztra; t1.va = ps0->bb; t1.vb = ps1->bb; t1.vc = ps1->bb; memcpy(t1.na,nn,3*sizeof(float)); memcpy(t1.nb,nn,3*sizeof(float)); memcpy(t1.nc,nn,3*sizeof(float)); cutTriangle(sc,t1); } if ( adj[2] && adj[2] < k ) { pt1 = &mesh->tria[ adj[2] ]; p3 = &mesh->point[ pt1->v[voy[2]] ]; ps1 = &mesh->sol[ adj[2] ]; cx = (p0->c[0] + p1->c[0] + p3->c[0]) / 3.0; cy = (p0->c[1] + p1->c[1] + p3->c[1]) / 3.0; cz = ps1->bb; memcpy(t1.a,t.a,3*sizeof(float)); memcpy(t1.b,t.b,3*sizeof(float)); memcpy(t1.c,t.a,3*sizeof(float)); t1.c[2] = shrink*(altcoef*ps1->bb-cz) + cz - 0.25*mesh->ztra; t1.va = ps0->bb; t1.vb = ps0->bb; t1.vc = ps1->bb; memcpy(t1.na,nn,3*sizeof(float)); memcpy(t1.nb,nn,3*sizeof(float)); memcpy(t1.nc,nn,3*sizeof(float)); cutTriangle(sc,t1); memcpy(t1.a,t.b,3*sizeof(float)); memcpy(t1.b,t.b,3*sizeof(float)); memcpy(t1.c,t.a,3*sizeof(float)); t1.b[2] = shrink*(altcoef*ps1->bb-cz) + cz - 0.25*mesh->ztra; t1.c[2] = shrink*(altcoef*ps1->bb-cz) + cz - 0.25*mesh->ztra; t1.va = ps0->bb; t1.vb = ps1->bb; t1.vc = ps1->bb; memcpy(t1.na,nn,3*sizeof(float)); memcpy(t1.nb,nn,3*sizeof(float)); memcpy(t1.nc,nn,3*sizeof(float)); cutTriangle(sc,t1); } } k = pt->nxt; } } glEnd(); break; case LQuad: if ( ddebug ) printf("create quadrilateral list %d\n",mesh->nq); glBegin(GL_TRIANGLES); 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] ) { 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]]; if ( mesh->typage == 1 ) ps0 = ps1 = ps2 = ps3 = &mesh->sol[k]; else { ps0 = &mesh->sol[pq->v[0]]; ps1 = &mesh->sol[pq->v[1]]; ps2 = &mesh->sol[pq->v[2]]; ps3 = &mesh->sol[pq->v[3]]; } 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 * (ps0->bb + ps1->bb + ps2->bb + ps3->bb); t.a[0] = t2.a[0] = shrink*(p0->c[0]-cx) + cx; t.a[1] = t2.a[1] = shrink*(p0->c[1]-cy) + cy; t.a[2] = t2.a[2] = shrink*(altcoef*ps0->bb-cz) + cz - 0.25*mesh->ztra; t.b[0] = shrink*(p1->c[0]-cx) + cx; t.b[1] = shrink*(p1->c[1]-cy) + cy; t.b[2] = shrink*(altcoef*ps1->bb-cz) + cz - 0.25*mesh->ztra; t.c[0] = t2.b[0] = shrink*(p2->c[0]-cx) + cx; t.c[1] = t2.b[1] = shrink*(p2->c[1]-cy) + cy; t.c[2] = t2.b[2] = shrink*(altcoef*ps2->bb-cz) + cz - 0.25*mesh->ztra; t2.c[0] = shrink*(p3->c[0]-cx) + cx; t2.c[1] = shrink*(p3->c[1]-cy) + cy; t2.c[2] = shrink*(altcoef*ps3->bb-cz) + cz - 0.25*mesh->ztra; /* 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)); memcpy(t2.na,n,3*sizeof(float)); memcpy(t2.nb,n,3*sizeof(float)); memcpy(t2.nc,n,3*sizeof(float)); t.va = t2.va = ps0->bb; t.vb = ps1->bb; t.vc = t2.vb = ps2->bb; t2.vc = ps3->bb; cutTriangle(sc,t); cutTriangle(sc,t2); k = pq->nxt; } } glEnd(); break; } glEndList(); return(dlist); }
int createParticle(pScene sc,pMesh mesh) { pParticle pp; pStream st; pMaterial pm; pTetra pt1; pTriangle pt; pPoint ppt; double v[4],cx,cy,cz; int i,j,k,l,nmat,nbp,base; if ( ddebug ) printf("create particles\n"); if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); if ( sc->stream ) { st = sc->stream; if ( st->listp ) free(st->listp); free(sc->stream); } sc->stream = createStream(sc,mesh); sc->par.cumtim = 0.0; sc->par.advtim = 0; assert(sc->stream); st = sc->stream; fprintf(stdout," Creating particles :"); fflush(stdout); st->nbstl = 0; base = ++mesh->mark; pt = &mesh->tria[refitem]; nmat = matRef(sc,pt->ref); pm = &sc->material[nmat]; k = pm->depmat[LTria]; if ( !k || pm->flag ) return(0); /* point positions */ for (i=1; i<=mesh->np; i++) { ppt = &mesh->point[i]; ppt->mark = base; } if ( sc->par.nbpart >= MAX_PRT ) sc->par.nbpart = MAX_PRT; ++base; l = 1; nbp = 0; while ( k != 0 && st->nbstl < MAX_LST-1 ) { pt = &mesh->tria[k]; if ( pt->v[0] ) { cx = cy = cz = 0.0; for (i=0; i<3; i++) { ppt = &mesh->point[pt->v[i]]; cx += 0.33 * ppt->c[0]; cy += 0.33 * ppt->c[1]; cz += 0.33 * ppt->c[2]; ppt->flag = 1; } st->listp[l++] = cx; st->listp[l++] = cy; st->listp[l++] = cz; ++st->nbstl; if ( st->nbstl > MAX_LST-1 ) break; k = pt->nxt; } } fprintf(stdout,"%d\n",st->nbstl); if ( !st->nbstl ) return(0); /* init positions */ tp = calloc((st->nbstl+1),sizeof(Particle)); assert(tp); for (k=1; k<=st->nbstl; k++) tp[k].nsdep = mesh->ntet / 2; for (k=1; k<=mesh->ntet; k++) mesh->tetra[k].cpt = 0; l = 1; for (k=1; k<=st->nbstl; k++) { pp = &tp[k]; pp->pos[1][0] = st->listp[l++]; pp->pos[1][1] = st->listp[l++]; pp->pos[1][2] = st->listp[l++]; tp[k].nsdep = locateTetra(mesh,pp->nsdep,++mesh->mark,pp->pos[1],pp->cb); if ( !pp->nsdep ) { for (j=1; j<=mesh->ntet; j++) { pt1 = &mesh->tetra[j]; if ( pt1->mark != mesh->mark && inTetra(mesh,j,pp->pos[1],pp->cb) ) break; } if ( j > mesh->ntet ) return(0); else pp->nsdep = j; } pp->norm = field3DInterp(mesh,tp[k].nsdep,tp[k].cb,v); pp->size = sizeTetra(mesh,tp[k].nsdep); if ( pp->size == 0.0 ) pp->step = EPS*sc->dmax; else pp->step = HSIZ * min(pp->size,pp->norm); pp->step = min(0.05*sc->par.dt,pp->step); pp->flag = 1; pp->cur = 1; colorParticle(sc,pp); for (i=2; i<=sc->par.nbpart; i++) { pp->pos[i][0] = pp->pos[1][0]; pp->pos[i][1] = pp->pos[1][1]; pp->pos[i][2] = pp->pos[1][2]; } } return(1); }
/* build list of tetrahedra */ GLuint listTetraMap(pScene sc,pMesh mesh,ubyte clip) { pMaterial pm; pTetra pt; pPoint p0,p1,p2; pSolution ps0,ps1,ps2; GLint dlist = 0; float cx,cy,cz,ax,ay,az,bx,by,bz,d,n[3]; int k,l,m; triangle t; /* default */ if ( !mesh->ntet ) return(0); if ( ddebug ) printf("create display list map / TETRA\n"); if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); // By Leo: get number of triangles to render tet colors correctly int boundary_faces = mesh->nt; /* build display list */ dlist = glGenLists(1); glNewList(dlist,GL_COMPILE); if ( glGetError() ) return(0); #ifdef IGL bool transp = sc->igl_params->tet_color[3] < 0.999; int old_depth_func =0; glGetIntegerv(GL_DEPTH_FUNC,&old_depth_func); if ( transp ) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDepthFunc(GL_ALWAYS); sc->igl_params->alpha_holder = sc->igl_params->tet_color[3]; }else { sc->igl_params->alpha_holder = 1.0; } #endif /* build list */ for (m=0; m<sc->par.nbmat; m++) { pm = &sc->material[m]; k = pm->depmat[LTets]; if ( !k || pm->flag ) continue; glBegin(GL_TRIANGLES); while ( k != 0 ) { pt = &mesh->tetra[k]; if ( !pt->v[0] || (clip && !pt->clip) ) { k = pt->nxt; continue; } /* build 4 faces */ cx = cy = cz = 0.0f; for (l=0; l<4; l++) { p0 = &mesh->point[pt->v[l]]; cx += p0->c[0]; cy += p0->c[1]; cz += p0->c[2]; } cx /= 4.; cy /= 4.; cz /= 4.; for (l=0; l<4; l++) { p0 = &mesh->point[pt->v[ct[l][0]]]; p1 = &mesh->point[pt->v[ct[l][1]]]; p2 = &mesh->point[pt->v[ct[l][2]]]; /* compute face 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; d = n[0]*n[0] + n[1]*n[1] + n[2]*n[2]; if ( d > 0.0f ) { d = 1.0f / sqrt(d); n[0] *= d; n[1] *= d; n[2] *= d; } /* store triangle */ 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; /* store normals */ memcpy(t.na,n,3*sizeof(float)); memcpy(t.nb,n,3*sizeof(float)); memcpy(t.nc,n,3*sizeof(float)); if ( mesh->typage == 2 ) { /* solutions at vertices */ ps0 = &mesh->sol[pt->v[ct[l][0]]]; ps1 = &mesh->sol[pt->v[ct[l][1]]]; ps2 = &mesh->sol[pt->v[ct[l][2]]]; t.va = ps0->bb; t.vb = ps1->bb; t.vc = ps2->bb; } else { /* solution at element */ ps0 = &mesh->sol[k+boundary_faces]; t.va = t.vb = t.vc = ps0->bb; } /* color interpolation */ cutTriangle(sc,t); } k = pt->nxt; } glEnd(); } #ifdef IGL if(transp) { glDepthFunc(old_depth_func); glDisable(GL_BLEND); } #endif glEndList(); return(dlist); }
/* build list of hexahedra */ GLuint listHexaMap(pScene sc,pMesh mesh,ubyte clip) { pMaterial pm; pHexa ph; pPoint p0,p1,p2,p3; pSolution ps0,ps1,ps2,ps3; GLint dlist = 0; double ax,ay,az,bx,by,bz,d; float n[3],cx,cy,cz; int k,l,m; triangle t1,t2; if ( !mesh->nhex ) return(0); if ( ddebug ) printf("create display list map / HEXA\n"); if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); /* 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[LHexa]; if ( !k || pm->flag ) continue; glBegin(GL_TRIANGLES); while ( k != 0 ) { ph = &mesh->hexa[k]; if ( !ph->v[0] || (clip && !ph->clip) ) { k = ph->nxt; continue; } cx = cy = cz = 0.0f; for (l=0; l<8; l++) { p0 = &mesh->point[ph->v[l]]; cx += p0->c[0]; cy += p0->c[1]; cz += p0->c[2]; } cx /= 8.; cy /= 8.; cz /= 8.; 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]]]; /* compute face 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; d = n[0]*n[0] + n[1]*n[1] + n[2]*n[2]; if ( d > 0.0f ) { d = 1.0f / sqrt(d); n[0] *= d; n[1] *= d; n[2] *= d; } /* store triangles */ 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; t1.c[1] = t2.b[1] = sc->shrink*(p2->c[1]-cy)+cy; t1.c[2] = t2.b[2] = sc->shrink*(p2->c[2]-cz)+cz; t2.c[0] = sc->shrink*(p3->c[0]-cx)+cx; t2.c[1] = sc->shrink*(p3->c[1]-cy)+cy; t2.c[2] = sc->shrink*(p3->c[2]-cz)+cz; /* store normals */ memcpy(t1.na,n,3*sizeof(float)); memcpy(t1.nb,n,3*sizeof(float)); memcpy(t1.nc,n,3*sizeof(float)); memcpy(t2.na,n,3*sizeof(float)); memcpy(t2.nb,n,3*sizeof(float)); memcpy(t2.nc,n,3*sizeof(float)); if ( mesh->typage == 2 ) { /* solutions at vertices */ ps0 = &mesh->sol[ph->v[ch[l][0]]]; ps1 = &mesh->sol[ph->v[ch[l][1]]]; ps2 = &mesh->sol[ph->v[ch[l][2]]]; ps3 = &mesh->sol[ph->v[ch[l][3]]]; t1.va = t2.va = ps0->bb; t1.vb = ps1->bb; t1.vc = t2.vb = ps2->bb; t2.vc = ps3->bb; } else { /* solution at element */ ps0 = &mesh->sol[k]; t1.va = t1.vb = t1.vc = ps0->bb; t2.va = t2.vb = t2.vc = ps0->bb; } /* color interpolation */ cutTriangle(sc,t1); cutTriangle(sc,t2); } k = ph->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; t1.c[1] = t2.b[1] = sc->shrink*(p2->c[1]-cy)+cy; t1.c[2] = t2.b[2] = sc->shrink*(p2->c[2]-cz)+cz; t2.c[0] = sc->shrink*(p3->c[0]-cx)+cx; t2.c[1] = sc->shrink*(p3->c[1]-cy)+cy; t2.c[2] = sc->shrink*(p3->c[2]-cz)+cz; } else { t1.a[0] = t2.a[0] = p0->c[0]; t1.a[1] = t2.a[1] = p0->c[1]; t1.a[2] = t2.a[2] = p0->c[2]; t1.b[0] = p1->c[0]; t1.b[1] = p1->c[1]; t1.b[2] = p1->c[2]; t1.c[0] = t2.b[0] = p2->c[0]; t1.c[1] = t2.b[1] = p2->c[1]; t1.c[2] = t2.b[2] = p2->c[2]; t2.c[0] = p3->c[0]; t2.c[1] = p3->c[1]; t2.c[2] = p3->c[2]; } if ( sc->type & S_FLAT ) { memcpy(t1.na,n,3*sizeof(float)); memcpy(t1.nb,n,3*sizeof(float)); memcpy(t1.nc,n,3*sizeof(float)); memcpy(t2.na,n,3*sizeof(float)); memcpy(t2.nb,n,3*sizeof(float)); memcpy(t2.nc,n,3*sizeof(float)); } else { is0 = is1 = is2 = is3 = 0; if ( mesh->extra->iv ) { if ( pq->v[0] <= mesh->nvn ) is0 = mesh->extra->nv[pq->v[0]]; if ( pq->v[1] <= mesh->nvn ) is1 = mesh->extra->nv[pq->v[1]]; if ( pq->v[2] <= mesh->nvn ) is2 = mesh->extra->nv[pq->v[2]]; if ( pq->v[3] <= mesh->nvn ) is3 = mesh->extra->nv[pq->v[3]]; } if ( !is0 && pq->v[0] <= mesh->extra->iq ) is0 = mesh->extra->nq[4*(k-1)+1]; if ( !is1 && pq->v[1] <= mesh->extra->iq ) is1 = mesh->extra->nq[4*(k-1)+2]; if ( !is2 && pq->v[2] <= mesh->extra->iq ) is2 = mesh->extra->nq[4*(k-1)+3]; if ( !is3 && pq->v[3] <= mesh->extra->iq ) is3 = mesh->extra->nq[4*(k-1)+4]; if ( !is0 ) memcpy(t1.na,n,3*sizeof(float)); else { t1.na[0] = t2.na[0] = mesh->extra->n[3*(is0-1)+1]; t1.na[1] = t2.na[1] = mesh->extra->n[3*(is0-1)+2]; t1.na[2] = t2.na[2] = mesh->extra->n[3*(is0-1)+3]; } if ( !is1 ) memcpy(t1.nb,n,3*sizeof(float)); else { t1.nb[0] = mesh->extra->n[3*(is1-1)+1]; t1.nb[1] = mesh->extra->n[3*(is1-1)+2]; t1.nb[2] = mesh->extra->n[3*(is1-1)+3]; } if ( !is2 ) memcpy(t1.nc,n,3*sizeof(float)); else { t1.nc[0] = t2.nb[0] = mesh->extra->n[3*(is2-1)+1]; t1.nc[1] = t2.nb[1] = mesh->extra->n[3*(is2-1)+2]; t1.nc[2] = t2.nb[2] = mesh->extra->n[3*(is2-1)+3]; } if ( !is3 ) memcpy(t1.nc,n,3*sizeof(float)); else { t2.nc[0] = mesh->extra->n[3*(is3-1)+1]; t2.nc[1] = mesh->extra->n[3*(is3-1)+2]; t2.nc[2] = mesh->extra->n[3*(is3-1)+3]; } } if ( mesh->typage == 2 ) { /* solutions at vertices */ ps0 = &mesh->sol[pq->v[0]]; ps1 = &mesh->sol[pq->v[1]]; ps2 = &mesh->sol[pq->v[2]]; ps3 = &mesh->sol[pq->v[3]]; t1.va = t2.va = ps0->bb; t1.vb = ps1->bb; t1.vc = t2.vb = ps2->bb; t2.vc = ps3->bb; } else { /* solution at element */ ps0 = &mesh->sol[k]; t1.va = t1.vb = t1.vc = ps0->bb; t2.va = t2.vb = t2.vc = ps0->bb; } /* color interpolation */ cutTriangle(sc,t1); cutTriangle(sc,t2); k = pq->nxt; } glEnd(); } glEndList(); return(dlist); }
/* 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); #ifdef IGL bool transp = sc->material->dif[3] < 0.999; int old_depth_func =0; glGetIntegerv(GL_DEPTH_FUNC,&old_depth_func); if ( transp ) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDepthFunc(GL_ALWAYS); sc->igl_params->alpha_holder = sc->material->dif[3]; }else { sc->igl_params->alpha_holder = 1.0; } #endif /* 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; } #ifdef IGL if(pt->ref == 1) { // Self-intersection float red[4] = {1.0, 0.0, 0.0, 1.0}; red[3] = sc->material->dif[3]; glColor4fv(red); glNormal3fv(n); glVertex3fv(t.a); glColor4fv(red); glNormal3fv(n); glVertex3fv(t.b); glColor4fv(red); glNormal3fv(n); glVertex3fv(t.c); }else{ #endif cutTriangle(sc,t); #ifdef IGL } #endif 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(); } } #ifdef IGL if(transp) { glDepthFunc(old_depth_func); glDisable(GL_BLEND); } #endif glEndList(); return(dlist); }
/* build lists for iso-surfaces */ GLuint listTriaIso(pScene sc,pMesh mesh) { GLuint dlist = 0; pTriangle pt; pPoint p0,p1; pMaterial pm; pSolution ps0,ps1; double rgb[3]; float iso,cx,cy,cz,cc,kc; int m,k,i,l,l1,nc,ncol; static double hsv[3] = { 0.0, 1.0, 0.9 }; static int idir[5] = {0,1,2,0,1}; /* default */ if ( !mesh->nt || !mesh->nbb || mesh->typage == 1 ) return(0); if ( ddebug ) printf("create iso-values map list / TRIA\n"); if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); /* create display list */ dlist = glGenLists(1); glNewList(dlist,GL_COMPILE); if ( glGetError() ) return(0); /* build list */ glBegin(GL_LINES); ncol = NBCOL; for (i=0; i<=ncol*(MAXISO-1); i++) { if ( i < ncol*(MAXISO-1) ) { l = i / ncol; kc = (i % ncol) / (float)ncol; iso = sc->iso.val[l]*(1.0-kc)+sc->iso.val[l+1]*kc; hsv[0] = sc->iso.col[l]*(1.0-kc)+sc->iso.col[l+1]*kc; } else { iso = sc->iso.val[MAXISO-1]; hsv[0] = sc->iso.col[MAXISO-1]; } hsvrgb(hsv,rgb); glColor3dv(rgb); 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] ) { k = pt->nxt; continue; } /* analyze edges */ nc = 0; cx = cy = cz = 0.0; for (l=0; l<3; l++) { l1 = idir[l+1]; p0 = &mesh->point[pt->v[l]]; p1 = &mesh->point[pt->v[l1]]; ps0 = &mesh->sol[pt->v[l]]; ps1 = &mesh->sol[pt->v[l1]]; if ( (ps0->bb > iso && ps1->bb <= iso) || (ps0->bb < iso && ps1->bb >= iso) ) { cc = 0.0; if ( fabs(ps1->bb-ps0->bb) > 0.0 ) cc = (iso-ps0->bb) / (ps1->bb-ps0->bb); if ( cc == 0.0 || cc == 1.0 ) continue; cx = p0->c[0]+cc*(p1->c[0]-p0->c[0]); cy = p0->c[1]+cc*(p1->c[1]-p0->c[1]); nc++; if ( mesh->dim == 2 ) glVertex2f(cx,cy); else { cz = p0->c[2]+cc*(p1->c[2]-p0->c[2]); glVertex3f(cx,cy,cz); } } else if ( ps0->bb == iso && ps1->bb == iso ) { nc = 2; if ( mesh->dim == 2 ) { glVertex2f(p0->c[0],p0->c[1]); glVertex2f(p1->c[0],p1->c[1]); break; } else { glVertex3f(p0->c[0],p0->c[1],p0->c[2]); glVertex3f(p1->c[0],p1->c[1],p1->c[2]); break; } } } if ( nc > 0 && nc != 2 ) { if ( mesh->dim ==2 ) glVertex2f(cx,cy); else glVertex3f(cx,cy,cz); } k = pt->nxt; } } } glEnd(); glEndList(); return(dlist); }
int tetraIsoPOVray(pScene sc,pMesh mesh) { FILE *isofil; pTetra pt; pPoint p0,p1; pMaterial pm; pSolution ps0,ps1; double delta; float iso,cx[4],cy[4],cz[4],cc; int m,k,k1,k2,i,l,pos[4],neg[4],nbpos,nbneg,nbnul; char *ptr,data[128]; static int tn[4] = {0,0,1,1}; static int tp[4] = {0,1,1,0}; /* default */ if ( !mesh->ntet || !mesh->nbb || mesh->typage == 1 ) return(0); if ( ddebug ) printf("create isosurfaces POVray\n"); if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); delta = sc->iso.val[MAXISO-1] - sc->iso.val[0]; strcpy(data,mesh->name); ptr = strstr(data,".mesh"); if ( ptr ) ptr = '\0'; strcat(data,".pov"); if ( ddebug ) fprintf(stdout," Writing POVRay file %s\n",data); isofil = fopen(data,"w"); if ( !isofil ) return(0); for (i=MAXISO-1; i>=0; i--) { iso = sc->iso.val[i]; if ( i == MAXISO-1 ) iso -= 0.001*fabs(iso)/delta; else if ( i == 0 ) iso += 0.001*fabs(iso)/delta; fprintf(isofil,"\n#declare isosurf%d = mesh {\n",i); for (m=0; m<sc->par.nbmat; m++) { pm = &sc->material[m]; k = pm->depmat[LTets]; if ( !k || pm->flag ) continue; while ( k != 0 ) { pt = &mesh->tetra[k]; if ( !pt->v[0] ) { k = pt->nxt; continue; } /* analyze vertices */ nbpos = nbneg = nbnul = 0; for (l=0; l<4; l++) { p0 = &mesh->point[pt->v[l]]; ps0 = &mesh->sol[pt->v[l]]; if ( ps0->bb > iso ) pos[nbpos++] = l; else if ( ps0->bb < iso ) neg[nbneg++] = l; else nbnul++; } if ( nbneg == 4 || nbpos == 4 ) { k = pt->nxt; continue; } if ( nbneg == 2 && nbpos == 2 ) { for (l=0; l<4; l++) { k1 = neg[tn[l]]; k2 = pos[tp[l]]; p0 = &mesh->point[pt->v[k1]]; p1 = &mesh->point[pt->v[k2]]; ps0 = &mesh->sol[pt->v[k1]]; ps1 = &mesh->sol[pt->v[k2]]; cc = 0.0f; if ( fabs(ps1->bb-ps0->bb) > 0.0f ) cc = (iso-ps0->bb) / (ps1->bb-ps0->bb); cx[l] = p0->c[0]+cc*(p1->c[0]-p0->c[0]); cy[l] = p0->c[1]+cc*(p1->c[1]-p0->c[1]); cz[l] = p0->c[2]+cc*(p1->c[2]-p0->c[2]); } fprintf(isofil,"triangle {\n"); fprintf(isofil," <%f,%f,%f>,\n", cx[0]+mesh->xtra,cy[0]+mesh->ytra,cz[0]+mesh->ztra); fprintf(isofil," <%f,%f,%f>,\n", cx[1]+mesh->xtra,cy[1]+mesh->ytra,cz[1]+mesh->ztra); fprintf(isofil," <%f,%f,%f>\n" , cx[2]+mesh->xtra,cy[2]+mesh->ytra,cz[2]+mesh->ztra); fprintf(isofil,"}\n"); fprintf(isofil,"triangle {\n"); fprintf(isofil," <%f,%f,%f>,\n", cx[0]+mesh->xtra,cy[0]+mesh->ytra,cz[0]+mesh->ztra); fprintf(isofil," <%f,%f,%f>,\n", cx[2]+mesh->xtra,cy[2]+mesh->ytra,cz[2]+mesh->ztra); fprintf(isofil," <%f,%f,%f>\n" , cx[3]+mesh->xtra,cy[3]+mesh->ytra,cz[3]+mesh->ztra); fprintf(isofil,"}\n"); } else if ( !nbnul ) { for (l=0; l<3; l++) { k1 = nbneg == 3 ? neg[l] : pos[l]; k2 = nbneg == 3 ? pos[0] : neg[0]; p0 = &mesh->point[pt->v[k1]]; p1 = &mesh->point[pt->v[k2]]; ps0 = &mesh->sol[pt->v[k1]]; ps1 = &mesh->sol[pt->v[k2]]; cc = 0.0f; if ( fabs(ps1->bb-ps0->bb) > 0.0f ) cc = (iso-ps0->bb) / (ps1->bb-ps0->bb); cx[l] = p0->c[0]+cc*(p1->c[0]-p0->c[0]); cy[l] = p0->c[1]+cc*(p1->c[1]-p0->c[1]); cz[l] = p0->c[2]+cc*(p1->c[2]-p0->c[2]); } fprintf(isofil,"triangle {\n"); fprintf(isofil," <%f,%f,%f>,\n", cx[0]+mesh->xtra,cy[0]+mesh->ytra,cz[0]+mesh->ztra); fprintf(isofil," <%f,%f,%f>,\n", cx[1]+mesh->xtra,cy[1]+mesh->ytra,cz[1]+mesh->ztra); fprintf(isofil," <%f,%f,%f>\n", cx[2]+mesh->xtra,cy[2]+mesh->ytra,cz[2]+mesh->ztra); fprintf(isofil,"}\n"); } k = pt->nxt; } } fprintf(isofil,"}\n"); } fclose(isofil); return(1); }
/* build lists for iso-surfaces */ GLuint listTetraIso(pScene sc,pMesh mesh) { FILE *outv,*outf; GLuint dlist = 0; pTetra pt; pPoint p0,p1; pMaterial pm; pSolution ps0,ps1; double delta,rgb[4],d,ax,ay,az,bx,by,bz; float iso,n[3],cx[4],cy[4],cz[4],cc; int m,k,k1,k2,i,l,pos[4],neg[4],nbpos,nbneg,nbnul,nv,nf; static double hsv[3] = { 0.0f, 1.0f, 0.80f }; static int tn[4] = {0,0,1,1}; static int tp[4] = {0,1,1,0}; /* default */ if ( !mesh->ntet || !mesh->nbb || mesh->typage == 1 ) return(0); if ( ddebug ) printf("create iso-values map list / TETRA\n"); if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); delta = sc->iso.val[MAXISO-1] - sc->iso.val[0]; /* build display list */ dlist = glGenLists(1); glNewList(dlist,GL_COMPILE); if ( glGetError() ) return(0); /* build list */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_FALSE); if (ddebug) { outv = fopen("vertex.mesh","w"); fprintf(outv,"MeshVersionFormatted 1\n Dimension\n 3\n\nVertices\n \n"); outf = fopen("faces.mesh2","w"); fprintf(outv,"Triangles\n \n"); } nv = nf = 0; glBegin(GL_TRIANGLES); for (i=MAXISO-1; i>=0; i--) { iso = sc->iso.val[i]; /* base color */ /*hsv[0] = 240.0f*(1.0f - (iso-sc->iso.val[0])/delta);*/ hsv[0] = sc->iso.col[i]; hsvrgb(hsv,rgb); rgb[0] = min(1.0,rgb[0]+BASETR); rgb[1] = min(1.0,rgb[1]+BASETR); rgb[2] = min(1.0,rgb[2]+BASETR); rgb[3] = BASETR + (float)(i-1)/(float)MAXISO*(1.0-BASETR); /*rgb[3] = 0.5; */ glColor4dv(rgb); if ( i == MAXISO-1 ) iso -= 0.001*fabs(iso)/delta; else if ( i == 0 ) iso += 0.001*fabs(iso)/delta; for (m=0; m<sc->par.nbmat; m++) { pm = &sc->material[m]; k = pm->depmat[LTets]; if ( !k || pm->flag ) continue; while ( k != 0 ) { pt = &mesh->tetra[k]; if ( !pt->v[0] ) { k = pt->nxt; continue; } /* analyze vertices */ nbpos = nbneg = nbnul = 0; for (l=0; l<4; l++) { p0 = &mesh->point[pt->v[l]]; ps0 = &mesh->sol[pt->v[l]]; /*if ( ps0->bb < sc->iso.val[0] ) ps0->bb = sc->iso.val[0];*/ if ( ps0->bb > iso ) pos[nbpos++] = l; else if ( ps0->bb < iso ) neg[nbneg++] = l; else nbnul++; } if ( nbneg == 4 || nbpos == 4 ) { k = pt->nxt; continue; } if ( nbneg == 2 && nbpos == 2 ) { for (l=0; l<4; l++) { k1 = neg[tn[l]]; k2 = pos[tp[l]]; p0 = &mesh->point[pt->v[k1]]; p1 = &mesh->point[pt->v[k2]]; ps0 = &mesh->sol[pt->v[k1]]; ps1 = &mesh->sol[pt->v[k2]]; cc = 0.0f; if ( fabs(ps1->bb-ps0->bb) > 0.0f ) cc = (iso-ps0->bb) / (ps1->bb-ps0->bb); cx[l] = p0->c[0]+cc*(p1->c[0]-p0->c[0]); cy[l] = p0->c[1]+cc*(p1->c[1]-p0->c[1]); cz[l] = p0->c[2]+cc*(p1->c[2]-p0->c[2]); } /* compute face normal */ ax = cx[1]-cx[0]; ay = cy[1]-cy[0]; az = cz[1]-cz[0]; bx = cx[2]-cx[0]; by = cy[2]-cy[0]; bz = cz[2]-cz[0]; n[0] = ay*bz - az*by; n[1] = az*bx - ax*bz; n[2] = ax*by - ay*bx; d = n[0]*n[0] + n[1]*n[1] + n[2]*n[2]; if ( d > 0.0f ) { d = 1.0f / sqrt(d); n[0] *= d; n[1] *= d; n[2] *= d; } glNormal3fv(n); glVertex3f(cx[0],cy[0],cz[0]); glVertex3f(cx[1],cy[1],cz[1]); glVertex3f(cx[2],cy[2],cz[2]); glNormal3fv(n); glVertex3f(cx[0],cy[0],cz[0]); glVertex3f(cx[2],cy[2],cz[2]); glVertex3f(cx[3],cy[3],cz[3]); if ( ddebug ) { fprintf(outv,"%f %f %f 0\n",cx[0],cy[0],cz[0]); fprintf(outv,"%f %f %f 0\n",cx[1],cy[1],cz[1]); fprintf(outv,"%f %f %f 0\n",cx[2],cy[2],cz[2]); fprintf(outv,"%f %f %f 0\n",cx[3],cy[3],cz[3]); fprintf(outf,"%d %d %d 0\n",nv+1,nv+2,nv+3); fprintf(outf,"%d %d %d 0\n",nv+1,nv+3,nv+4); } nv+= 4; nf+= 2; } else if ( !nbnul ) { for (l=0; l<3; l++) { k1 = nbneg == 3 ? neg[l] : pos[l]; k2 = nbneg == 3 ? pos[0] : neg[0]; p0 = &mesh->point[pt->v[k1]]; p1 = &mesh->point[pt->v[k2]]; ps0 = &mesh->sol[pt->v[k1]]; ps1 = &mesh->sol[pt->v[k2]]; cc = 0.0f; if ( fabs(ps1->bb-ps0->bb) > 0.0f ) cc = (iso-ps0->bb) / (ps1->bb-ps0->bb); cx[l] = p0->c[0]+cc*(p1->c[0]-p0->c[0]); cy[l] = p0->c[1]+cc*(p1->c[1]-p0->c[1]); cz[l] = p0->c[2]+cc*(p1->c[2]-p0->c[2]); } /* compute face normal */ ax = cx[1]-cx[0]; ay = cy[1]-cy[0]; az = cz[1]-cz[0]; bx = cx[2]-cx[0]; by = cy[2]-cy[0]; bz = cz[2]-cz[0]; n[0] = ay*bz - az*by; n[1] = az*bx - ax*bz; n[2] = ax*by - ay*bx; d = n[0]*n[0] + n[1]*n[1] + n[2]*n[2]; if ( d > 0.0f ) { d = 1.0f / sqrt(d); n[0] *= d; n[1] *= d; n[2] *= d; } glNormal3fv(n); glVertex3f(cx[0],cy[0],cz[0]); glVertex3f(cx[1],cy[1],cz[1]); glVertex3f(cx[2],cy[2],cz[2]); if ( ddebug ) { fprintf(outv,"%f %f %f 0\n",cx[0],cy[0],cz[0]); fprintf(outv,"%f %f %f 0\n",cx[1],cy[1],cz[1]); fprintf(outv,"%f %f %f 0\n",cx[2],cy[2],cz[2]); fprintf(outf,"%d %d %d 0\n",nv+1,nv+2,nv+3); } nv += 3; nf += 1; } k = pt->nxt; } } } glEnd(); glDepthMask(GL_TRUE); glDisable(GL_BLEND); if ( ddebug ) { fclose(outv); fclose(outf); } printf(" Vertices %d Triangles %d\n",nv,nf); glEndList(); return(dlist); }