/* analyze tetrahedra and split if needed */ static int anatri(pMesh mesh,pSol met,char typchk) { int nc,ns,nf,nnc,nns,nnf,it,maxit; /* analyze tetras : initial splitting */ nns = nnc = nnf = it = 0; maxit = 5; do { /* memory free */ free(mesh->adja); mesh->adja = 0; /* analyze surface */ ns = anaelt(mesh,met,typchk); if ( ns < 0 ) { fprintf(stdout," ## Unable to complete surface mesh. Exit program.\n"); return(0); } if ( !hashTria(mesh) ) { fprintf(stdout," ## Hashing problem. Exit program.\n"); return(0); } /* collapse short edges */ nc = colelt(mesh,met,typchk); if ( nc < 0 ) { fprintf(stdout," ## Unable to collapse mesh. Exiting.\n"); return(0); } /* attempt to swap */ nf = swpmsh(mesh,met,typchk); if ( nf < 0 ) { fprintf(stdout," ## Unable to improve mesh. Exiting.\n"); return(0); } nnc += nc; nns += ns; nnf += nf; if ( (abs(info.imprim) > 4 || info.ddebug) && ns+nc > 0 ) fprintf(stdout," %8d splitted, %8d collapsed, %8d swapped\n",ns,nc,nf); if ( it > 3 && abs(nc-ns) < 0.1 * MS_MAX(nc,ns) ) break; } while ( ++it < maxit && ns+nc+nf > 0 ); if ( (abs(info.imprim) < 5 || info.ddebug ) && nns+nnc > 0 ) fprintf(stdout," %8d splitted, %8d collapsed, %8d swapped, %d iter.\n",nns,nnc,nnf,it); 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); }