cgal/Mesh_3/applications/nb2mesh.c

2018 lines
48 KiB
C

/* nb2mesh.c
* conversion from xxx.noboite to xxx.mesh(b) or xxx.amdba3
* or xxx.(no)boite(b)
* to compile use gcc nb2mesh.c libmesh.c -o nb2mesh -lm -O
*
* Authored by Pascal J. Frey, Inria-Rocquencourt
* Copyright (c) Inria, 2000-2003. All rights reserved.
* Permission is granted to reproduce, use and distribute
* this code for any and all purposes, provided that this
* notice appears in all copies.
*/
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "libmesh.h"
#define min(a,b) ( ((a) < (b)) ? (a) : (b) )
#define max(a,b) ( ((b) > (a)) ? (b) : (a) )
#define KA 31
#define KB 57
#define KC 79
static int idir[7] = {0,1,2,3,0,1,2};
#ifndef ubyte
typedef unsigned char ubyte;
#endif
/* hash table structure for tetras */
typedef struct shtable {
int nxt,elt,ind;
} Htable;
typedef Htable * pHtable;
typedef struct stetra {
int v[4],ref;
int adj[4];
ubyte voy[4];
} Tetra;
typedef Tetra * pTetra;
typedef struct spoint {
float c[3];
int new;
} Point;
typedef Point * pPoint;
pHtable hash;
int nhmax,hnext;
pTetra tets;
pPoint points;
double coefs[10];
int *tri,*ref,*refv,np,ne,nf,npf,npinit;
short quiet,surf,dosurf = 0,split4 = 0,ddebug = 0,mtype = 0,addref;
short tonb = 0;
char namesurf[256];
/* build hash table */
int hcodeTetra(unsigned int key,int mins,int maxs,int sum,int elt,int ind) {
pHtable pht;
pTetra pt,pt1;
pPoint ppt;
int mins1,maxs1,sum1;
ubyte i1,i2,i3;
if ( key >= nhmax ) {
fprintf(stderr," ## hcodeTetra error %d\n",elt);
return(0);
}
pht = &hash[key];
/* empty bucket */
if ( !pht->elt ) {
pht->elt = elt;
pht->ind = ind;
pht->nxt = 0;
return(1);
}
/* search linked elts */
pt = &tets[elt];
do {
pt1 = &tets[pht->elt];
/* compute key */
i1 = idir[pht->ind+1];
i2 = idir[pht->ind+2];
i3 = idir[pht->ind+3];
mins1 = min(pt1->v[i1],pt1->v[i2]);
mins1 = min(mins1,pt1->v[i3]);
maxs1 = max(pt1->v[i1],pt1->v[i2]);
maxs1 = max(maxs1,pt1->v[i3]);
if ( pt1->v[i1] != mins1 && pt1->v[i1] != maxs1 )
sum1 = KB*pt1->v[i1];
else if ( pt1->v[i2] != mins1 && pt1->v[i2] != maxs1 )
sum1 = KB*pt1->v[i2];
else
sum1 = KB*pt1->v[i3];
sum1 += KA*mins1 + KC*maxs1;
/* corresponding face */
if ( mins1 == mins && maxs1 == maxs && sum1 == sum ) {
if ( pt1->adj[pht->ind] || pt->adj[ind] ) {
fprintf(stderr," ## adjacency problem. exit.\n");
fprintf(stderr," sum %d key %d min %d max %d elt %d ind %d\n",
sum,key,mins,maxs,elt,ind+1);
fprintf(stderr," elt %d: %d %d %d %d\n",
elt,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
fprintf(stderr," vois %d: %d %d %d %d\n",
pht->elt,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]);
fprintf(stderr," elt: vois[%d] = %d\n",
ind,pt->adj[ind]);
fprintf(stderr," vois: vois[%d] = %d\n",
pht->ind,pt1->adj[pht->ind]);
{
FILE *fp;
int k;
fprintf(stderr,"Saving debug.mesh\n");
fp = fopen("debug.mesh","w");
fprintf(fp,"MeshVersionFormatted 1\n");
fprintf(fp,"Dimension\n3\n");
fprintf(fp,"\nVertices\n%d\n",np);
for (k=1; k<=np; k++) {
ppt = &points[k];
fprintf(fp,"%f %f %f 0\n",
ppt->c[0],ppt->c[1],ppt->c[2]);
}
fprintf(fp,"\nTetrahedra\n3\n");
fprintf(fp,"%d %d %d %d 1\n",
pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
fprintf(fp,"%d %d %d %d 2\n",
pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]);
pt = &tets[pt1->adj[pht->ind]];
fprintf(fp,"%d %d %d %d 3\n",
pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
fprintf(fp,"\nEnd\n");
fclose(fp);
}
exit(2);
}
/* update neighbor */
pt->adj[ind] = pht->elt;
pt->voy[ind] = (ubyte)pht->ind;
pt1->adj[pht->ind] = elt;
pt1->voy[pht->ind] = (ubyte)ind;
return(1);
}
/* link element */
else if ( !pht->nxt ) {
pht->nxt = hnext;
pht = &hash[hnext];
if ( !pht ) {
puts(" ## hash table problem. Exit");
return(0);
}
pht->elt = elt;
pht->ind = ind;
hnext = pht->nxt;
pht->nxt = 0;
/* check for size overflow */
if ( !hnext ) {
puts(" ## overflow in hash table!");
return(0);
}
return(1);
}
pht = &hash[pht->nxt];
}
while (1);
return(0);
}
int hfaceTetra(unsigned int key,int mins,int maxs,int sum) {
pHtable pht;
pTetra pt1;
int mins1,maxs1,sum1;
ubyte i1,i2,i3;
if ( key >= nhmax ) return(0);
pht = &hash[key];
if ( !pht->elt ) return(0);
do {
pt1 = &tets[pht->elt];
/* compute key */
i1 = idir[pht->ind+1];
i2 = idir[pht->ind+2];
i3 = idir[pht->ind+3];
mins1 = min(pt1->v[i1],pt1->v[i2]);
mins1 = min(mins1,pt1->v[i3]);
maxs1 = max(pt1->v[i1],pt1->v[i2]);
maxs1 = max(maxs1,pt1->v[i3]);
if ( pt1->v[i1] != mins1 && pt1->v[i1] != maxs1 )
sum1 = KB*pt1->v[i1];
else if ( pt1->v[i2] != mins1 && pt1->v[i2] != maxs1 )
sum1 = KB*pt1->v[i2];
else
sum1 = KB*pt1->v[i3];
sum1 += KA*mins1 + KC*maxs1;
/* corresponding face */
if ( mins1 == mins && maxs1 == maxs && sum1 == sum )
return(1);
else if ( !pht->nxt ) return(0);
pht = &hash[pht->nxt];
}
while (1);
return(0);
}
/* read noboite file */
int loadNoboite(char *name) {
FILE *in;
pTetra pt;
pPoint ppt;
int deb,fin,j,no,icube,npbli,npfixe;
int nbele,loele,loelef,nbelef,nbpoi,lopoi,lopoif,nbpoif;
int nbsub,losub,nbsubf,losubf,nsde,ideb[1024];
int nn,bin,t,k,i;
char data[256];
/* attempt to open file */
if ( strstr(name,".noboiteb") || strstr(name,".boiteb") ) {
in = fopen(name,"r");
if ( !in ) {
fprintf(stderr," File %s not found. Bye.\n",name);
return(0);
}
bin = 1;
fprintf(stdout," Loading file %s\n",name);
if ( strstr(name,".boiteb") ) dosurf = 1;
}
else if ( strstr(name,".noboite") || strstr(name,".boite") ) {
in = fopen(name,"r");
if ( !in ) {
fprintf(stderr," File %s not found. Bye.\n",name);
return(0);
}
bin = 0;
fprintf(stdout," Loading file %s\n",name);
if ( strstr(name,".boite") ) dosurf = 1;
}
else {
sprintf(data,"%s.noboiteb",name);
if ( !quiet ) fprintf(stdout," Checking %s\n",data);
in = fopen(data,"r");
bin = 1;
if ( !in ) {
sprintf(data,"%s.noboite",name);
in = fopen(data,"r");
bin = 0;
if ( ! quiet ) fprintf(stdout," Checking %s\n",data);
if ( !in ) {
sprintf(data,"%s.boiteb",name);
in = fopen(data,"r");
bin = 1;
if ( ! quiet ) fprintf(stdout," Checking %s\n",data);
if ( !in ) {
sprintf(data,"%s.boite",name);
in = fopen(data,"r");
bin = 0;
if ( !quiet ) fprintf(stdout," Checking %s\n",data);
}
dosurf = 1;
}
}
if ( !in ) {
fprintf(stderr," File %s not found. Bye.\n",data);
return(0);
}
fprintf(stdout," Loading file %s\n",data);
}
/* read binary file */
if ( bin == 1 ) {
fread(&no,sizeof(int),1,in);
fread(&ne,sizeof(int),1,in);
fread(&np,sizeof(int),1,in);
fread(&npfixe,sizeof(int),1,in);
fread(&icube,sizeof(int),1,in);
fread(&npbli,sizeof(int),1,in);
fread(&nbele,sizeof(int),1,in);
fread(&loele,sizeof(int),1,in);
fread(&nbelef,sizeof(int),1,in);
fread(&loelef,sizeof(int),1,in);
fread(&nbpoi,sizeof(int),1,in);
fread(&lopoi,sizeof(int),1,in);
fread(&nbpoif,sizeof(int),1,in);
fread(&lopoif,sizeof(int),1,in);
fread(&nbsub,sizeof(int),1,in);
fread(&losub,sizeof(int),1,in);
fread(&nbsubf,sizeof(int),1,in);
fread(&losubf,sizeof(int),1,in);
fread(&no,sizeof(int),1,in);
if ( !quiet )
fprintf(stdout," Header: %d %d %d %d\n",ne,np,npfixe,npbli);
if ( ne+np == 0 ) {
fclose(in);
fprintf(stderr," Sorry, no element found. Bye\n");
return(0);
}
/* second record: read tetrahedra */
tets = (Tetra*)calloc(max(1000,(ne+1)),sizeof(Tetra));
if ( !tets ) {
fprintf(stderr," ## Not enough memory. Bye.\n");
exit(2);
}
if ( !quiet ) fprintf(stdout," Read tetras\n");
deb = 1;
fin = loele;
k = 1;
for (j=1; j<=nbele; j++) {
fread(&no,sizeof(int),1,in);
for (t=deb; t<=fin; t+=4) {
pt = &tets[k++];
nn = fread(&pt->v[0],sizeof(int),4,in);
}
fread(&no,sizeof(int),1,in);
deb += loele;
fin += loele;
}
if ( nbelef != 0 ) {
fin = deb + loelef - 1;
fread(&no,sizeof(int),1,in);
for (t=deb; t<=fin; t+=4) {
pt = &tets[k++];
nn = fread(&pt->v[0],sizeof(int),4,in);
}
fread(&no,sizeof(int),1,in);
}
/* third record: read vertices */
if ( !quiet ) fprintf(stdout," Read vertices\n");
points = (Point*)malloc(max(1000,np+1)*sizeof(Point));
assert(points);
deb = 1;
fin = lopoi;
k = 1;
for (j=1; j<=nbpoi; j++) {
fread(&no,sizeof(int),1,in);
for (t=deb; t<=fin; t+=3) {
ppt = &points[k++];
nn = fread(&ppt->c[0],sizeof(float),3,in);
ppt->new = -1;
}
fread(&no,sizeof(int),1,in);
deb += lopoi;
fin += lopoi;
}
if ( nbpoif != 0 ) {
fin = deb + lopoif - 1;
fread(&no,sizeof(int),1,in);
for (t=deb; t<=fin; t+=3) {
ppt = &points[k++];
nn = fread(&ppt->c[0],sizeof(float),3,in);
ppt->new = -1;
}
fread(&no,sizeof(int),1,in);
}
/* 4th : sub-domains */
fread(&no,sizeof(int),1,in);
fread(&nsde,sizeof(int),1,in);
fread(&no,sizeof(int),1,in);
/* 5th+ 6th : sub-domains */
fread(&no,sizeof(int),1,in);
if ( nsde == 1 )
fread(&ideb,sizeof(int),3,in);
else
fread(&ideb,sizeof(int),3*nsde,in);
fread(&no,sizeof(int),1,in);
fread(&no,sizeof(int),1,in);
if ( nsde == 1 )
for (t=1; t<=3; t++)
fread(&ideb,sizeof(int),1,in);
else {
deb = 1;
fin = losub;
for (t=1; t<=fin; t+=3) {
}
}
fread(&no,sizeof(int),1,in);
}
/* read ascii file */
else {
fscanf(in,"%d %d %d %d %d",&ne,&np,&npfixe,&icube,&npbli);
fscanf(in,"%d %d %d %d",&nbele,&loele,&nbelef,&loelef);
fscanf(in,"%d %d %d %d",&nbpoi,&lopoi,&nbpoif,&lopoif);
fscanf(in,"%d %d %d %d",&nbsub,&losub,&nbsubf,&losubf);
if ( !quiet )
fprintf(stdout," Header: %d %d %d %d\n",ne,np,npfixe,npbli);
if ( ne+np == 0 ) {
fclose(in);
fprintf(stderr," Sorry, no element found. Bye\n");
return(0);
}
/* second record: read tetrahedra */
if ( !quiet ) fprintf(stdout," Read tetras\n");
tets = (Tetra *)calloc(max(1000,ne+1),sizeof(Tetra));
if ( !tets ) {
fprintf(stderr," ## Not enough memory. Bye.\n");
exit(2);
}
for (j=1; j<=ne; j++) {
pt = &tets[j];
fscanf(in,"%d %d %d %d",&pt->v[0],&pt->v[1],&pt->v[2],&pt->v[3]);
}
/* third record: read vertices */
if ( !quiet ) fprintf(stdout," Read vertices\n");
points = (Point*)malloc(max(1000,np+1)*sizeof(Point));
assert(points);
for (j=1; j<=np; j++) {
ppt = &points[j];
fscanf(in,"%f %f %f",&ppt->c[0],&ppt->c[1],&ppt->c[2]);
ppt->new = -1;
}
/* 4th : nb subdomains */
fscanf(in,"%d",&nsde);
/* 5th : sub-domains */
if ( nsde == 1 )
for (k=deb; k<=3; k++)
fscanf(in,"%d ",&deb);
else
for (k=1; k<=3*nsde; k++) {
fscanf(in,"%d ",&deb);
}
for (k=1; k<=ne; k++) {
pt = &tets[k];
fscanf(in,"%d",&pt->ref);
}
if ( nsde == 1 )
for (t=1; t<=3; t++)
fscanf(in,"%d",&ideb);
else {
deb = 1;
fin = losub;
for (t=1; t<=nbsub; t++) {
for (i=deb; i<=fin; i++) {
fscanf(in,"%d",&k);
pt = &tets[k];
pt->ref = t;
}
}
}
}
fclose(in);
return(1);
}
int saveNoboite(char *name) {
FILE *out;
pTetra pt;
pPoint ppt;
int deb,fin,j,no,icube,npbli,npfixe;
int nbele,loele,loelef,nbelef,nbpoi,lopoi,lopoif,nbpoif,
nerema,isrec;
int nbhlo,nbhlof,lohlo,lohlof;
int bin,k,l;
/* attempt to open file */
if ( strstr(name,".noboiteb") || strstr(name,".boiteb") ) {
out = fopen(name,"w");
if ( !out ) {
fprintf(stderr," Unable to open file %s. Bye.\n",name);
return(0);
}
bin = 1;
fprintf(stdout," Writing file %s\n",name);
}
else if ( strstr(name,".noboite") || strstr(name,".boite") ) {
out = fopen(name,"w");
if ( !out ) {
fprintf(stderr," Unable to open file %s. Bye.\n",name);
return(0);
}
bin = 0;
fprintf(stdout," Writing file %s\n",name);
}
else return(0);
/* write binary file */
nerema = 12 * 16384;
isrec = 0;
/* split record or not */
if (ne <= nerema) {
nbele = 1; loele = 4*ne; nbelef = loelef = 0;
nbpoi = 1; lopoi = 3*np; nbpoif = lopoif = 0;
nbhlo = 1; lohlo = np; nbhlof = lohlof = 0;
}
else {
if ( !quiet ) fprintf(stdout," splitting records %d",nerema);
/* nbpoi records with nerema values */
nbpoi = 3*np / nerema; lopoi = nerema;
nbpoif = 1; lopoif = 3*np - nerema*nbpoi;
nbhlo = np/nerema; lohlo = nerema;
nbhlof = 1; lohlof = np - nerema*nbhlo;
if ( np <= nerema ) {
nbhlo = 1; lohlo = np;
nbhlof = 0; lohlof = 0;
}
nbele = 4*ne/nerema; loele = nerema;
nbelef = 1; loelef = 4*ne - nerema*nbele;
}
npfixe= npf;
icube = 0;
npbli = 0;
if ( bin ) {
no = 68;
fwrite(&no,sizeof(int),1,out);
fwrite(&ne,sizeof(int),1,out);
fwrite(&np,sizeof(int),1,out);
fwrite(&npfixe,sizeof(int),1,out);
fwrite(&icube,sizeof(int),1,out);
fwrite(&npbli,sizeof(int),1,out);
fwrite(&nbele,sizeof(int),1,out); fwrite(&loele,sizeof(int),1,out);
fwrite(&nbelef,sizeof(int),1,out); fwrite(&loelef,sizeof(int),1,out);
fwrite(&nbpoi,sizeof(int),1,out); fwrite(&lopoi,sizeof(int),1,out);
fwrite(&nbpoif,sizeof(int),1,out); fwrite(&lopoif,sizeof(int),1,out);
fwrite(&nbhlo,sizeof(int),1,out); fwrite(&lohlo,sizeof(int),1,out);
fwrite(&nbhlof,sizeof(int),1,out); fwrite(&lohlof,sizeof(int),1,out);
fwrite(&no,sizeof(int),1,out);
isrec++;
/* write simplices */
if ( !quiet ) fprintf(stdout," Writing simplices\n");
deb = 1;
fin = loele;
l = 1;
for (j=1; j<=nbele; j++) {
no = (fin-deb+1)*sizeof(int);
fwrite(&no,sizeof(int),1,out);
for (k=deb; k<=fin; k+=4) {
pt = &tets[l++];
fwrite(&pt->v,sizeof(int),4,out);
}
deb += loele;
fin += loele;
isrec++;
fwrite(&no,sizeof(int),1,out);
}
if ( deb < 4*ne ) {
no = (4*ne-deb+1)*sizeof(int);
fwrite(&no,sizeof(int),1,out);
for (k=deb; k<=4*ne; k+=4) {
pt = &tets[l++];
fwrite(&pt->v,sizeof(int),4,out);
}
fwrite(&no,sizeof(int),1,out);
}
/* write coordinates */
if ( !quiet ) fprintf(stdout," Writing coords\n");
deb = 1;
fin = lopoi;
l = 1;
for (j=1; j<=nbpoi; j++) {
no = (fin-deb+1)*sizeof(float);
fwrite(&no,sizeof(int),1,out);
for (k=deb; k<=fin; k+=3) {
ppt = &points[l++];
fwrite(&ppt->c,3*sizeof(float),1,out);
}
deb += lopoi;
fin += lopoi;
isrec++;
fwrite(&no,sizeof(int),1,out);
}
if ( deb < 3*np ) {
no = (3*np-deb+1)*sizeof(float);
fwrite(&no,sizeof(int),1,out);
for (k=deb; k<=3*np; k+=3) {
ppt = &points[l++];
fwrite(&ppt->c,3*sizeof(float),1,out);
}
isrec++;
fwrite(&no,sizeof(int),1,out);
}
/* write coefficients */
no = 6*sizeof(double);
fwrite(&no,sizeof(int),1,out);
fwrite(&coefs,sizeof(double),6,out);
fwrite(&no,sizeof(int),1,out);
isrec++;
}
/* write ASCII file */
else {
fprintf(out,"%d %d ",ne,np);
fprintf(out,"%d %d %d ",npfixe,icube,npbli);
fprintf(out,"%d %d %d %d ",nbele,loele,nbelef,loelef);
fprintf(out,"%d %d %d %d ",nbpoi,lopoi,nbpoif,lopoif);
fprintf(out,"%d %d %d %d\n",nbhlo,lohlo,nbhlof,lohlof);
/* write simplices */
if ( !quiet ) fprintf(stdout," Writing simplices\n");
deb = 1;
fin = loele;
l = 1;
for (j=1; j<=nbele; j++) {
for (k=deb; k<=fin; k+=4) {
pt = &tets[l++];
fprintf(out,"%d %d %d %d",pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
if ( k % 12 == 0 ) fprintf(out,"\n");
}
if ( k % 12 != 0 ) fprintf(out,"\n");
deb += loele;
fin += loele;
}
if ( nbelef ) {
fin = deb + loelef - 1;
for (k=deb; k<=fin; k+=4) {
pt = &tets[l++];
fprintf(out,"%d %d %d %d",pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
if (k % 12 == 0) fprintf(out,"\n");
}
if (k % 12 != 0) fprintf(out,"\n");
}
/* write coordinates */
if ( !quiet ) fprintf(stdout," Writing coords\n");
deb = 1;
fin = lopoi;
l = 1;
for (j=1; j<=nbpoi; j++) {
for (k=deb; k<=fin; k+=3) {
ppt = &points[l++];
fprintf(out,"%f %f %f",ppt->c[0],ppt->c[1],ppt->c[2]);
if (k % 9 == 0) fprintf(out,"\n");
}
if (k % 9 != 0) fprintf(out,"\n");
deb += lopoi;
fin += lopoi;
}
if ( nbpoif ) {
fin = deb + lopoif - 1;
for (k=deb; k<=fin; k+=3) {
ppt = &points[l++];
fprintf(out,"%f %f %f",ppt->c[0],ppt->c[1],ppt->c[2]);
if (k % 9 == 0) fprintf(out,"\n");
}
if (k %9 != 0) fprintf(out,"\n");
}
/* write coefficients */
for (k=1; k<=6; k++) {
fprintf(out,"%g ",coefs[k]);
}
fprintf(out,"\n");
}
fclose(out);
return(1);
}
/* load surface description */
int loadSurf(char *name) {
FILE *in;
float dummyf;
int ver,k,msh,degre,nef,nt,nr;
int a,b,c,d,e,rf,post,posq,posp;
char *ptr,data[256],buf[256];
strcpy(data,name);
ptr = strstr(data,".noboite");
if ( ptr ) *ptr = '\0';
ptr = strstr(data,".boite");
if ( ptr ) *ptr = '\0';
strcpy(buf,data);
ptr = strstr(data,".mesh");
if ( ptr ) *ptr = '\0';
strcpy(buf,data);
msh = 0;
nf = nr = npf = 0;
strcat(data,".faces");
if ( !quiet ) fprintf(stdout," Checking %s\n",data);
in = fopen(data,"r");
if ( in )
fprintf(stdout," Loading file %s\n",data);
else {
strcpy(data,buf);
strcat(data,".meshb");
if ( !quiet ) fprintf(stdout," Checking %s\n",data);
in = ouvrir_mesh(data,"r",&ver);
msh = 1;
if ( !in ) {
strcpy(data,buf);
strcat(data,".mesh");
if ( !quiet ) fprintf(stdout," Checking %s\n",data);
in = ouvrir_mesh(data,"r",&ver);
if ( !in ) {
fprintf(stdout," No surface file found\n");
return(0);
}
}
else
fprintf(stdout," Loading file %s\n",name);
}
/* read .faces */
if ( !msh ) {
fgets(data,255,in);
sscanf(data,"%d",&nef);
if ( !nef ) {
fprintf(stderr," Sorry, no triangles found.\n");
return(0);
}
surf = 1;
/* read once */
for (k=1; k<=nef; k++) {
fscanf(in,"%d",&degre);
if ( degre < 3 || degre > 4 ) {
fprintf(stderr," Wrong degree %d\n",degre);
return(0);
}
else if ( degre == 3 )
nf++;
else if ( degre == 4 )
nf += 2;
fgets(data,80,in);
}
/* alloc memory */
if ( !quiet ) fprintf(stdout," Triangles %d\n",nf);
tri = malloc(max(1000,nf+1)*3*sizeof(int));
if ( ! tri ) {
fprintf(stderr," Sorry, not enough memory. Bye\n");
return(0);
}
ref = malloc(max(1000,nf+1)*sizeof(int));
if ( !ref ) {
fprintf(stderr," Sorry, not enough memory. Bye\n");
return(0);
}
/* read faces */
nf = 0;
nt = 0;
rewind(in);
fscanf(in,"%d",&nef);
for (k=1; k<=nef; k++) {
fscanf(in,"%d",&degre);
if ( degre == 3 ) {
fscanf(in,"%d %d %d %d %d %d %d\n",&a,&b,&c,&rf,&d,&d,&d);
tri[++nt] = a;
tri[++nt] = b;
tri[++nt] = c;
ref[++nf] = rf;
}
else if ( degre == 4 ) {
fscanf(in,"%d %d %d %d %d %d %d %d %d",&a,&b,&c,&d,&rf,&e,&e,&e,&e);
tri[++nt] = a;
tri[++nt] = b;
tri[++nt] = c;
ref[++nf] = rf;
tri[++nt] = a;
tri[++nt] = c;
tri[++nt] = d;
ref[++nf] = rf;
}
else
fgets(data,80,in);
}
fclose(in);
/* read points */
if ( split4) {
strcpy(data,name);
ptr = strstr(data,".noboite");
if ( ptr ) *ptr = '\0';
ptr = strstr(data,".boite");
if ( ptr ) *ptr = '\0';
strcpy(buf,data);
strcat(buf,".points");
in = fopen(buf,"r");
fscanf(in,"%d",&npf);
fclose(in);
}
}
/* read .mesh */
else {
mtype = 1;
strcpy(namesurf,name);
posp = chercher_mot_clef(in,Vertices,0);
fseek(in,posp,SEEK_SET);
npf = lire_int(in);
npinit = npf;
refv = malloc((npf+1)*sizeof(int));
if ( !refv ) {
fprintf(stderr," Sorry, not enough memory. Bye\n");
return(0);
}
for (k=1; k<=npf; k++) {
dummyf = lire_reel(in);
dummyf = lire_reel(in);
dummyf = lire_reel(in);
refv[k] = lire_int(in);
}
post = chercher_mot_clef(in,Triangles,0);
if ( post ) {
fseek(in,post,SEEK_SET);
nf = lire_int(in);
}
posq = chercher_mot_clef(in,Quadrilaterals,0);
if ( posq ) {
fseek(in,posq,SEEK_SET);
nf += 2*lire_int(in);
}
if ( !nf ) {
fprintf(stderr," Sorry, no triangles found.\n");
return(0);
}
/* alloc memory */
if ( !quiet ) fprintf(stdout," Triangles %d\n",nf);
tri = malloc(max(1000,nf+1)*3*sizeof(int));
if ( ! tri ) {
fprintf(stderr," Sorry, not enough memory. Bye\n");
return(0);
}
ref = malloc(max(1000,nf+1)*sizeof(int));
if ( !ref ) {
fprintf(stderr," Sorry, not enough memory. Bye\n");
return(0);
}
surf = 1;
/* read mesh */
nt = nf = 0;
if ( post ) {
fseek(in,post,SEEK_SET);
nef = lire_int(in);
for (k=1; k<=nef; k++) {
tri[++nt] = lire_int(in);
tri[++nt] = lire_int(in);
tri[++nt] = lire_int(in);
ref[++nf] = lire_int(in);
}
}
if ( posq ) {
fseek(in,posq,SEEK_SET);
nef = lire_int(in);
for (k=1; k<=nef; k++) {
a = lire_int(in);
b = lire_int(in);
c = lire_int(in);
d = lire_int(in);
rf = lire_int(in);
tri[++nt] = a;
tri[++nt] = b;
tri[++nt] = c;
ref[++nf] = rf;
tri[++nt] = a;
tri[++nt] = c;
tri[++nt] = d;
ref[++nf] = rf;
}
}
fclose(in);
}
return(1);
}
/* hash tetras faces */
int hashFaces() {
pTetra pt;
int i,i1,i2,i3,k,nt,nbel,mins,maxs;
int sum;
unsigned int key;
if ( hash ) return(1);
if ( !quiet ) fprintf(stdout,"\n Hashing bdry faces\n");
/* alloc mem */
nbel = 1*ne;
nhmax = 3*ne;
hash = (Htable*)calloc(nhmax+1,sizeof(Htable));
if ( !hash ) {
fprintf(stderr," ## Not enough memory to build hash table.\n");
return(0);
}
/* init hash table */
hnext = nbel;
for (k=hnext; k<nhmax; k++)
hash[k].nxt = k+1;
/* build hash table */
for (k=1; k<=ne; k++) {
pt = &tets[k];
if ( !pt->v[0] ) continue;
for (i=0; i<4; i++) {
i1 = idir[i+1];
i2 = idir[i+2];
i3 = idir[i+3];
mins = min(pt->v[i1],pt->v[i2]);
mins = min(mins,pt->v[i3]);
maxs = max(pt->v[i1],pt->v[i2]);
maxs = max(maxs,pt->v[i3]);
/* compute key */
if ( pt->v[i1] != mins && pt->v[i1] != maxs )
sum = KB*pt->v[i1];
else if ( pt->v[i2] != mins && pt->v[i2] != maxs )
sum = KB*pt->v[i2];
else
sum = KB*pt->v[i3];
sum += KA*mins + KC*maxs;
key = sum % nbel;
pt->adj[i] = pt->voy[i] = 0;
if ( !hcodeTetra(key,mins,maxs,sum,k,i) ) {
fprintf(stderr," ## hashTetra problem %d / %d. Exit.\n",k,ne);
free(hash);
return(0);
}
}
}
nf = nt = 0;
for (k=1; k<=ne; k++) {
pt = &tets[k];
for (i=0; i<4; i++)
if ( !pt->adj[i] ) nf++;
}
if ( !quiet ) printf(" allocate %d faces\n",nf);
tri = (int*)calloc((nf+1)*3,sizeof(int));
if ( !tri ) return(0);
nf = nt = 0;
for (k=1; k<=ne; k++) {
pt = &tets[k];
for (i=0; i<4; i++) {
if ( !pt->adj[i] ) {
tri[++nt] = pt->v[idir[i+1]];
tri[++nt] = pt->v[idir[i+2]];
tri[++nt] = pt->v[idir[i+3]];
nf++;
}
}
}
if ( !quiet ) fprintf(stdout," Total bdry faces %d\n",nf);
return(1);
}
/* hash tetras faces */
int hashTrias() {
pTetra pt;
int i,i1,i2,i3,k,nbel,mins,maxs;
int sum;
unsigned int key;
if ( hash ) return(1);
if ( !quiet ) fprintf(stdout,"\n Hashing bdry faces\n");
/* alloc mem */
nbel = 1*ne;
nhmax = 3*ne;
hash = (Htable*)calloc(nhmax+1,sizeof(Htable));
if ( !hash ) {
fprintf(stderr," ## Not enough memory to build hash table.\n");
return(0);
}
/* init hash table */
hnext = nbel;
for (k=hnext; k<nhmax; k++)
hash[k].nxt = k+1;
/* build hash table */
for (k=1; k<=ne; k++) {
pt = &tets[k];
if ( !pt->v[0] ) continue;
for (i=0; i<4; i++) {
if ( pt->adj[i] ) continue;
i1 = idir[i+1];
i2 = idir[i+2];
i3 = idir[i+3];
mins = min(pt->v[i1],pt->v[i2]);
mins = min(mins,pt->v[i3]);
maxs = max(pt->v[i1],pt->v[i2]);
maxs = max(maxs,pt->v[i3]);
/* compute key */
if ( pt->v[i1] != mins && pt->v[i1] != maxs )
sum = KB*pt->v[i1];
else if ( pt->v[i2] != mins && pt->v[i2] != maxs )
sum = KB*pt->v[i2];
else
sum = KB*pt->v[i3];
sum += KA*mins + KC*maxs;
key = sum % nbel;
pt->adj[i] = pt->voy[i] = 0;
if ( !hcodeTetra(key,mins,maxs,sum,k,i) ) {
fprintf(stderr," ## hashTetra problem %d / %d. Exit.\n",k,ne);
free(hash);
return(0);
}
}
}
return(1);
}
#define EPS 0.0f
/* compute tet quality */
int qualtet(int k) {
pTetra pt;
pPoint p0,p1,p2,p3;
double ax,ay,az,bx,by,bz,cx,cy,cz,dx,dy,dz;
double vx,vy,vz,vol;
pt = &tets[k];
p0 = &points[pt->v[0]];
p1 = &points[pt->v[1]];
p2 = &points[pt->v[2]];
p3 = &points[pt->v[3]];
ax = p0->c[0];
ay = p0->c[1];
az = p0->c[2];
bx = p1->c[0] - ax;
by = p1->c[1] - ay;
bz = p1->c[2] - az;
cx = p2->c[0] - ax;
cy = p2->c[1] - ay;
cz = p2->c[2] - az;
dx = p3->c[0] - ax;
dy = p3->c[1] - ay;
dz = p3->c[2] - az;
vx = cy*dz - dy*cz;
vy = cz*dx - dz*cx;
vz = cx*dy - dx*cy;
vol = bx*vx + by*vy + bz*vz;
if ( vol <= EPS ) {
fprintf(stdout," tet %d: %d %d %d %d, vol %E\n",
k,pt->v[0],pt->v[1],pt->v[2],pt->v[3],vol);
return(1);
}
return(0);
}
void splitTetra() {
pTetra pt,pt1;
pPoint ppt;
float ax,ay,az;
int neinit,npc,nnpf,j,k;
/* peculiar treatment */
npc = 0;
for (k=1; k<=ne; k++) {
pt = &tets[k];
nnpf = pt->v[0] <= npf;
nnpf += pt->v[1] <= npf;
nnpf += pt->v[2] <= npf;
nnpf += pt->v[3] <= npf;
if ( nnpf == 4 ) npc++;
}
if ( !npc ) return;
points = (Point*)realloc(points,(np+npc+10)*sizeof(Point));
assert(points);
tets = (Tetra*)realloc(tets,(ne+4*npc+10)*sizeof(Tetra));
if ( !tets ) exit(2);
neinit = ne;
npc = 0;
for (k=1; k<=neinit; k++) {
pt = &tets[k];
nnpf = pt->v[0] <= npf;
nnpf += pt->v[1] <= npf;
nnpf += pt->v[2] <= npf;
nnpf += pt->v[3] <= npf;
if ( nnpf < 4 ) continue;
npc++;
ax = ay = az = 0.0f;
for (j=0; j<4; j++) {
ppt = &points[pt->v[j]];
ax += ppt->c[0];
ay += ppt->c[1];
az += ppt->c[2];
}
ppt = &points[++np];
ppt->c[0] = ax * 0.25;
ppt->c[1] = ay * 0.25;
ppt->c[2] = az * 0.25;
pt1 = &tets[++ne];
pt1->v[0] = pt->v[1];
pt1->v[1] = pt->v[3];
pt1->v[2] = pt->v[2];
pt1->v[3] = np;
pt1 = &tets[++ne];
pt1->v[0] = pt->v[0];
pt1->v[1] = pt->v[2];
pt1->v[2] = pt->v[3];
pt1->v[3] = np;
pt1 = &tets[++ne];
pt1->v[0] = pt->v[0];
pt1->v[1] = pt->v[3];
pt1->v[2] = pt->v[1];
pt1->v[3] = np;
pt->v[3] = np;
}
if ( npc ) fprintf(stdout," %d corrected\n",npc);
}
/* load mesh file */
int loadMesh(char *name) {
FILE *in;
pTetra pt;
pPoint ppt;
int k,dim,ver,reff,pos[NbMc],key;
in = ouvrir_mesh(name,"r",&ver);
if ( !in ) {
fprintf(stderr,"\n File %s not found. Bye.\n",name);
return(0);
}
fprintf(stdout," Loading file %s\n",name);
dosurf = 0;
/* parse keywords */
dim = 3;
for (k=0; k<NbMc; k++) pos[k] = 0;
do {
key = mot_clef_suivant(in);
if ( key == End ) break;
pos[key] = ftell(in);
switch(key) {
case MeshDimension:
dim = lire_int(in);
break;
case Vertices:
np = lire_int(in);
break;
case Tetrahedra:
ne = lire_int(in);
break;
}
}
while (key != End);
if ( dim != 3 || !np || !ne ) {
fprintf(stderr," Wrong data type.\n");
return(0);
}
/* allocation */
tets = (Tetra*)calloc(max(1000,(ne+1)),sizeof(Tetra));
assert(tets);
points = (Point*)malloc(max(1000,np+1)*sizeof(Point));
assert(points);
fseek(in,pos[Vertices],SEEK_SET);
np = lire_int(in);
refv = malloc((np+1)*sizeof(int));
if ( !refv ) {
fprintf(stderr,"Sorry not enough memory. Bye\n");
return(0);
}
for(k=1; k<=np; k++) {
ppt = &points[k];
ppt->c[0] = (float)lire_reel(in);
ppt->c[1] = (float)lire_reel(in);
ppt->c[2] = (float)lire_reel(in);
refv[k] = lire_int(in);
}
fseek(in,pos[Tetrahedra],SEEK_SET);
ne = lire_int(in);
for(k=1; k<=ne; k++) {
pt = &tets[k];
pt->v[0] = lire_int(in);
pt->v[1] = lire_int(in);
pt->v[2] = lire_int(in);
pt->v[3] = lire_int(in);
reff = lire_int(in);
}
coefs[0] = coefs[2] = coefs[4] = 0.0;
coefs[1] = coefs[3] = coefs[5] = 1.0;
return(1);
}
/* remove dangling faces */
int delDangling() {
int f,k,kk,a,b,c,mins,maxs,sum,nfdeb;
unsigned int key;
if ( !nf || hash ) return(1);
fprintf(stdout,"\n Remove dangling faces\n");
hashTrias();
nfdeb = nf;
k = f = 1;
do {
a = tri[k+0];
b = tri[k+1];
c = tri[k+2];
mins = min(a,b);
mins = min(mins,c);
maxs = max(a,b);
maxs = max(maxs,c);
if ( a != mins && a != maxs )
sum = KB*a;
else if ( b != mins && b != maxs )
sum = KB*b;
else
sum = KB*c;
sum += KA*mins + KC*maxs;
key = sum % ne;
if ( !hfaceTetra(key,mins,maxs,sum) ) {
kk = 3*(nf-1) + 1;
tri[k+0] = tri[kk+0];
tri[k+1] = tri[kk+1];
tri[k+2] = tri[kk+2];
ref[f] = ref[nf];
nf--;
}
else {
k += 3;
f++;
}
}
while ( k <=3*nf );
if ( !quiet ) fprintf(stdout," %d faces deleted\n",nfdeb-nf);
free(hash);
hash = 0;
return(1);
}
/* write mesh file */
int saveMesh(char *name) {
FILE *out,*in;
pTetra pt;
pPoint ppt,p1,p2,p3;
float nx,ny,nz;
int i,k,l,ver,nnp,nnf,nn,nv,nnv,ntv;
int *edg,pos,posnv,nc,ncc,na,naa,cc,aa,bb,rr;
char *ptr,namein[256];
/* output file */
out = ouvrir_mesh(name,"w",&ver);
if ( !out ) {
fprintf(stderr,"\n Unable to open %s. Bye.\n",name);
return(0);
}
fprintf(stdout,"\n Writing %s\n",name);
/* write mesh header */
ecrire_commentaire(out,"Mesh generated by nb2mesh (INRIA)");
formater(out);
ecrire_mot_clef(out,MeshDimension);
ecrire_int(out,3);
formater(out);
formater(out);
/* tassage */
nnp = nnf = 0;
for (k=1; k<=ne; k++) {
pt = &tets[k];
for (i=0; i<4; i++) {
ppt = &points[pt->v[i]];
ppt->new = 0;
}
}
for(k=1; k<=np; k++) {
ppt = &points[k];
if ( !ppt->new ) ppt->new = ++nnp;
}
for (k=1; k<=3*nf; k+=3) {
p1 = &points[tri[k]];
p2 = &points[tri[k+1]];
p3 = &points[tri[k+2]];
if ( p1->new < 0 || p2->new < 0 || p3->new < 0 ) continue;
++nnf;
}
/* vertices */
if ( !quiet && np > 10000 )
fprintf(stdout," Vertices %8d / %8d\n",nnp,np);
ecrire_commentaire(out,"Set of mesh vertices");
ecrire_mot_clef(out,Vertices);
ecrire_int(out,nnp);
formater(out);
for (k=1; k<=np; k++) {
ppt = &points[k];
if ( ppt->new < 0 ) continue;
ecrire_reel(out,ppt->c[0]);
ecrire_reel(out,ppt->c[1]);
ecrire_reel(out,ppt->c[2]);
if ( k <= npinit )
ecrire_int(out,refv[k]);
else
ecrire_int(out,0);
formater(out);
}
formater(out);
/* triangles */
if ( nnf ) {
if ( !quiet && np > 10000 )
fprintf(stdout," Triangles %8d / %8d\n",nnf,nf);
ecrire_commentaire(out,"Set of Triangles");
ecrire_mot_clef(out,Triangles);
ecrire_int(out,nnf);
formater(out);
if ( surf ) {
l = 0;
for (k=1; k<=3*nf; k+=3) {
p1 = &points[tri[k+0]];
p2 = &points[tri[k+1]];
p3 = &points[tri[k+2]];
++l;
if ( p1->new < 0 || p2->new < 0 || p3->new < 0 ) continue;
ecrire_int(out,p1->new);
ecrire_int(out,p2->new);
ecrire_int(out,p3->new);
ecrire_int(out,ref[l]);
formater(out);
}
}
else {
for (k=1; k<=3*nf; k+=3) {
p1 = &points[tri[k+0]];
p2 = &points[tri[k+1]];
p3 = &points[tri[k+2]];
if ( p1->new < 0 || p2->new < 0 || p3->new < 0 ) continue;
ecrire_int(out,p1->new);
ecrire_int(out,p2->new);
ecrire_int(out,p3->new);
ecrire_int(out,0);
formater(out);
}
}
formater(out);
}
/* specific entities */
if ( !dosurf && mtype ) {
strcpy(namein,namesurf);
ptr = strstr(namein,".noboite");
if ( ptr ) *ptr = '\0';
ptr = strstr(namein,".boite");
if ( ptr ) *ptr = '\0';
in = ouvrir_mesh(namein,"r",&ver);
if ( in ) {
/* corners */
pos = chercher_mot_clef(in,Corners,0);
if ( pos ) {
fseek(in,pos,SEEK_SET);
nc = lire_int(in);
if ( !quiet ) fprintf(stdout," corners %6d ",nc);
ncc = 0;
for (k=1; k<=nc; k++) {
cc = lire_int(in);
p1 = &points[cc];
if ( p1->new > 0 ) ncc++;
}
if ( !quiet ) fprintf(stdout,"%d\n",ncc);
ecrire_commentaire(out,"Set of corners");
ecrire_mot_clef(out,Corners);
ecrire_int(out,ncc);
formater(out);
fseek(in,pos,SEEK_SET);
nc = lire_int(in);
for (k=1; k<=nc; k++) {
cc = lire_int(in);
p1 = &points[cc];
if ( p1->new > 0 ) {
ecrire_int(out,p1->new);
formater(out);
}
}
formater(out);
}
/* required points */
pos = chercher_mot_clef(in,RequiredVertices,pos);
if ( pos ) {
fseek(in,pos,SEEK_SET);
nc = lire_int(in);
if ( !quiet ) fprintf(stdout," required %6d ",nc);
ncc = 0;
for (k=1; k<=nc; k++) {
cc = lire_int(in);
p1 = &points[cc];
if ( p1->new > 0 ) ncc++;
}
if ( !quiet ) fprintf(stdout,"%d ",ncc);
fseek(in,pos,SEEK_SET);
nc = lire_int(in);
ecrire_commentaire(out,"Set of required vertices");
ecrire_mot_clef(out,RequiredVertices);
ecrire_int(out,ncc);
formater(out);
for (k=1; k<=nc; k++) {
cc = lire_int(in);
p1 = &points[cc];
if ( p1->new > 0 ) {
ecrire_int(out,p1->new);
formater(out);
}
}
formater(out);
}
/* edges */
pos = chercher_mot_clef(in,Edges,0);
if ( pos ) {
fseek(in,pos,SEEK_SET);
na = lire_int(in);
naa = 0;
for (k=1; k<=na; k++) {
aa = lire_int(in);
bb = lire_int(in);
rr = lire_int(in);
p1 = &points[aa];
p2 = &points[bb];
if ( p1->new > 0 && p2->new > 0 ) naa++;
}
if ( naa > 0 ) {
if ( !quiet ) fprintf(stdout," edges %6d",naa);
edg = (int*)calloc(na+1,sizeof(int));
assert(edg);
fseek(in,pos,SEEK_SET);
na = lire_int(in);
ecrire_commentaire(out,"Set of edges");
ecrire_mot_clef(out,Edges);
ecrire_int(out,naa);
formater(out);
naa = 0;
for (k=1; k<=na; k++) {
aa = lire_int(in);
bb = lire_int(in);
rr = lire_int(in);
p1 = &points[aa];
p2 = &points[bb];
if ( p1->new > 0 && p2->new > 0 ) {
ecrire_int(out,p1->new);
ecrire_int(out,p2->new);
ecrire_int(out,rr);
formater(out);
edg[k] = ++naa;
}
}
formater(out);
/* ridges */
pos = chercher_mot_clef(in,Ridges,pos);
if ( pos ) {
fseek(in,pos,SEEK_SET);
na = lire_int(in);
naa = 0;
for (k=1; k<=na; k++) {
aa = lire_int(in);
if ( edg[aa] > 0 ) naa++;
}
if ( naa > 0 ) {
if ( !quiet ) fprintf(stdout," ridges %6d / %6d",naa,na);
fseek(in,pos,SEEK_SET);
na = lire_int(in);
ecrire_commentaire(out,"Set of ridges");
ecrire_mot_clef(out,Ridges);
ecrire_int(out,naa);
formater(out);
for (k=1; k<=na; k++) {
aa = lire_int(in);
if ( edg[aa] > 0 ) {
ecrire_int(out,edg[aa]);
formater(out);
}
}
formater(out);
}
}
pos = chercher_mot_clef(in,RequiredEdges,pos);
if ( pos ) {
fseek(in,pos,SEEK_SET);
na = lire_int(in);
naa = 0;
for (k=1; k<=na; k++) {
aa = lire_int(in);
if ( edg[aa] > 0 ) naa++;
}
if ( naa > 0 ) {
if ( !quiet ) fprintf(stdout," req.edges %6d / %6d",naa,na);
fseek(in,pos,SEEK_SET);
na = lire_int(in);
ecrire_commentaire(out,"Set of required edges");
ecrire_mot_clef(out,RequiredEdges);
ecrire_int(out,naa);
formater(out);
for (k=1; k<=na; k++) {
aa = lire_int(in);
if ( edg[aa] > 0 ) {
ecrire_int(out,edg[aa]);
formater(out);
}
}
formater(out);
}
}
fprintf(stdout,"\n");
}
}
pos = chercher_mot_clef(in,Normals,0);
if ( pos ) {
fseek(in,pos,SEEK_SET);
nn = lire_int(in);
if ( !quiet ) fprintf(stdout," normals %6d\n",nn);
ecrire_commentaire(out,"Set of normals");
ecrire_mot_clef(out,Normals);
ecrire_int(out,nn);
formater(out);
for (k=1; k<=nn; k++) {
nx = lire_reel(in);
ny = lire_reel(in);
nz = lire_reel(in);
ecrire_reel(out,nx);
ecrire_reel(out,ny);
ecrire_reel(out,nz);
formater(out);
}
formater(out);
posnv = chercher_mot_clef(in,NormalAtVertices,pos);
if ( posnv ) {
fseek(in,posnv,SEEK_SET);
nnv = lire_int(in);
if ( !quiet ) fprintf(stdout," normal at vertices %6d\n",nnv);
ecrire_commentaire(out,"Normals at vertices");
ecrire_mot_clef(out,NormalAtVertices);
ecrire_int(out,nnv);
formater(out);
for (k=1; k<=nnv; k++) {
nv = lire_int(in);
ecrire_int(out,nv);
nv = lire_int(in);
ecrire_int(out,nv);
formater(out);
}
formater(out);
}
posnv = chercher_mot_clef(in,NormalAtTriangleVertices,pos);
if ( posnv ) {
fseek(in,posnv,SEEK_SET);
ntv = lire_int(in);
if ( !quiet ) fprintf(stdout," normal at triangle vertices %6d\n",ntv);
ecrire_commentaire(out,"Normals at triangle vertices");
ecrire_mot_clef(out,NormalAtTriangleVertices);
ecrire_int(out,ntv);
formater(out);
for (k=1; k<=ntv; k++) {
nv = lire_int(in);
ecrire_int(out,nv);
nv = lire_int(in);
ecrire_int(out,nv);
nv = lire_int(in);
ecrire_int(out,nv);
formater(out);
}
formater(out);
}
}
}
fclose(in);
}
/* tets */
if ( !quiet && np > 10000 )
fprintf(stdout," Tetrahedra %8d\n",ne);
ecrire_commentaire(out,"Set of tetrahedra");
ecrire_mot_clef(out,Tetrahedra);
ecrire_int(out,ne);
formater(out);
for (k=1; k<=ne; k++) {
pt = &tets[k];
for (i=0; i<4; i++) {
ppt = &points[pt->v[i]];
ecrire_int(out,ppt->new);
}
/*reft = qualtet(k);
ecrire_int(out,reft);*/
ecrire_int(out,pt->ref);
formater(out);
}
ecrire_mot_clef(out,End);
fclose(out);
return(1);
}
/* save .amdba3 file */
int saveAmdba(char *name) {
FILE *out;
pTetra pt;
pPoint ppt,p1,p2,p3;
int k,l,i,nnp,nnf;
out = fopen(name,"w");
if ( !out ) {
fprintf(stderr," Unable to open %s\n",name);
exit(1);
}
fprintf(stdout,"\n Writing %s\n",name);
/* tassage */
nnp = nnf = 0;
for (k=1; k<=ne; k++) {
pt = &tets[k];
for (i=0; i<4; i++) {
ppt = &points[pt->v[i]];
ppt->new = 0;
}
}
for(k=1; k<=np; k++) {
ppt = &points[k];
if ( !ppt->new ) ppt->new = ++nnp;
}
for (k=1; k<=3*nf; k+=3) {
p1 = &points[tri[k]];
p2 = &points[tri[k+1]];
p3 = &points[tri[k+2]];
if ( p1->new < 0 || p2->new < 0 || p3->new < 0 ) continue;
++nnf;
}
fprintf(out,"%d %d %d\n",nnp,ne,nnf);
for (k=1; k<=np; k++) {
ppt = &points[k];
if ( ppt->new < 0 ) continue;
fprintf(out,"%f %f %f\n",ppt->c[0],ppt->c[1],ppt->c[2]);
if ( np > 10000 && (k % 1000 == 0) )
fprintf(stdout,"%10\r",k);
}
for (k=1; k<=ne; k++) {
pt = &tets[k];
for (i=0; i<4; i++) {
ppt = &points[pt->v[i]];
fprintf(out,"%d ",ppt->new);
}
fprintf(out,"\n");
if ( np > 10000 && (k % 1000 == 0) )
fprintf(stdout,"%10\r",k);
}
if ( surf ) {
l = 0;
for (k=1; k<=3*nf; k+=3) {
p1 = &points[tri[k]];
p2 = &points[tri[k+1]];
p3 = &points[tri[k+2]];
++l;
if ( p1->new < 0 || p2->new < 0 || p3->new < 0 ) continue;
fprintf(out,"%d\n",ref[l]);
}
}
else {
for (k=1; k<=nnf; k++)
fprintf(out,"0\n");
}
for (k=1; k<=3*nf; k+=3) {
p1 = &points[tri[k]];
p2 = &points[tri[k+1]];
p3 = &points[tri[k+2]];
if ( p1->new < 0 || p2->new < 0 || p3->new < 0 ) continue;
fprintf(out,"%d %d %d\n",p1->new,p2->new,p3->new);
if ( np > 10000 && (k % 1000 == 0) )
fprintf(stdout,"%10\r",k/3);
}
fclose(out);
return(1);
}
/* save .amdba3 file */
int saveAmFmt(char *name) {
FILE *out;
pTetra pt;
pPoint ppt,p1,p2,p3;
int k,i,nnp,nnf;
out = fopen(name,"w");
if ( !out ) {
fprintf(stderr," Unable to open %s\n",name);
exit(1);
}
fprintf(stdout,"\n Writing %s\n",name);
/* tassage */
nnp = nnf = 0;
for (k=1; k<=ne; k++) {
pt = &tets[k];
for (i=0; i<4; i++) {
ppt = &points[pt->v[i]];
ppt->new = 0;
}
}
for(k=1; k<=np; k++) {
ppt = &points[k];
if ( !ppt->new ) ppt->new = ++nnp;
}
for (k=1; k<=nf; k++) {
refv[tri[k+0]] = 1;
refv[tri[k+1]] = 1;
refv[tri[k+2]] = 1;
++nnf;
}
/* header */
fprintf(out,"%d %d\n",nnp,ne);
for (k=1; k<=ne; k++) {
pt = &tets[k];
for (i=0; i<4; i++) {
ppt = &points[pt->v[i]];
fprintf(out,"%5d ",ppt->new);
}
if ( k % 3 == 0 ) fprintf(out,"\n");
}
fprintf(out,"\n");
for (k=1; k<=np; k++) {
ppt = &points[k];
if ( ppt->new < 0 ) continue;
fprintf(out,"%E %E %E\n",ppt->c[0],ppt->c[1],ppt->c[2]);
}
fprintf(out,"\n");
/* refs elements */
for (k=1; k<=ne; k++) {
pt = &tets[k];
fprintf(out,"%5d ",pt->ref);
if ( k % 10 == 0 ) fprintf(out,"\n");
}
fprintf(out,"\n");
if ( refv ) {
for (k=1; k<=np; k++) {
fprintf(out,"%5d ",refv[k]);
if ( k % 10 == 0 ) fprintf(out,"\n");
}
}
else {
for (k=1; k<=np; k++) {
fprintf(out," 1 ",refv[k]);
if ( k % 10 == 0 ) fprintf(out,"\n");
}
}
fprintf(out,"\n");
/* refs points */
fclose(out);
return(1);
}
int addRefTetra() {
pTetra pt;
int *pile,base,k;
/*
base = 0;
dep = 1;
pile = (int*)malloc((ne+1)*sizeof(int));
assert(pile);
do {
for (k=dep; k<=ne; k++) {
pt = &tets[k];
if ( !pt->ref ) break;
}
if ( k > ne ) break;
dep = k + 1;
base++;
ipil = 1;
pile[ipil] = k;
while ( ipil ) {
pt = &tets[ pile[ipil] ];
pt->ref = base;
for (i=0; i<4; i++) {
if ( pt->adj[i] ) continue;
}
}
do {
}
while ();
}
while ( dep <= ne );
free(pile);
return(1);
*/
}
int main(int argc,char *argv[]) {
long i;
int ret;
char src[256],dest[256],dangfa;
clock_t ct0,ct1,ct2,ct3;
/* defaults */
ct0 = clock();
quiet = 1;
surf = 0;
dosurf = 1;
dangfa = 0;
tonb = 0;
addref = 0;
src[0] = dest[0] = '\0';
ref = 0;
refv = 0;
npinit = 0;
/* parse args */
if ( argc < 3 ) {
fprintf(stdout,"usage: nb2mesh filein fileout [-v] [-s]\n");
fprintf(stdout," filein : xxx.[no]boite[b]\n");
fprintf(stdout," fileout: yyy.mesh[b] or zzz.amdba3\n");
fprintf(stdout," -v : verbose mode\n");
fprintf(stdout," -s : do not create boundary (surface)\n");
fprintf(stdout," -x : split constrained tetras\n");
fprintf(stdout," -df : remove dangling faces\n");
fprintf(stdout," -ref : add reference to sub-domains\n");
exit(1);
}
else {
i = 1;
while ( i < argc ) {
if ( !strcmp(argv[i],"-v") )
quiet = 0;
else if ( !strcmp(argv[i],"-s") )
dosurf = 0;
else if ( !strcmp(argv[i],"-x") )
split4 = 1;
else if ( !strcmp(argv[i],"-df") )
dangfa = 1;
else if ( !strcmp(argv[i],"-ref") )
addref = 1;
else if ( !src[0] )
strcpy(src,argv[i]);
else if ( !dest[0] ) {
strcpy(dest,argv[i]);
if ( !strstr(dest,".mesh") && !strstr(dest,".amdba3") &&
!strstr(dest,".noboite") && !strstr(dest,".am_fmt") )
strcat(dest,".meshb");
if ( strstr(dest,".noboite") ) tonb = 1;
}
i++;
}
}
/* load 3D file */
ct1 = clock();
if ( strstr(src,".mesh") )
ret = loadMesh(src);
else
ret = loadNoboite(src);
if ( !ret ) exit(1);
/* load surface */
if ( !nf || dosurf ) {
nf = 0;
dosurf = 1 - loadSurf(src);
}
if ( split4 ) splitTetra();
ct1 = difftime(clock(),ct1);
fprintf(stdout," Input seconds: %.2f\n",
(double)ct1/(double)CLOCKS_PER_SEC);
/* hash faces */
if ( dosurf ) {
ct2 = clock();
hashFaces();
ct2 = difftime(clock(),ct2);
fprintf(stdout," Hash seconds: %.2f\n",
(double)ct2/(double)CLOCKS_PER_SEC);
}
if ( dangfa ) {
ct2 = clock();
delDangling();
ct2 = difftime(clock(),ct2);
fprintf(stdout," Dangling seconds: %.2f\n",
(double)ct2/(double)CLOCKS_PER_SEC);
}
/*
if ( addref ) {
hashTrias();
addRefTetra();
}
*/
/* save file */
ct3 = clock();
if ( strstr(dest,".mesh") )
ret = saveMesh(dest);
else if ( strstr(dest,".amdba3") )
ret = saveAmdba(dest);
else if ( strstr(dest,".am_fmt") )
ret = saveAmFmt(dest);
else if ( strstr(dest,".noboite") || strstr(dest,".boite") )
ret = saveNoboite(dest);
if ( !ret ) exit(1);
if ( hash ) free(hash);
free(points);
free(tets);
ct3 = difftime(clock(),ct3);
fprintf(stdout," Output seconds: %.2f\n",
(double)ct3/(double)CLOCKS_PER_SEC);
if ( !quiet ) {
fprintf(stdout,"\n Statistics\n");
if ( nf > 0 ) {
fprintf(stdout," Mesh vertices %8d\n",np);
fprintf(stdout," Mesh triangles %8d\n",nf);
fprintf(stdout," Mesh tetrahedra %8d\n",ne);
}
else {
fprintf(stdout," Mesh vertices %8d\n",np);
fprintf(stdout," Mesh tetrahedra %8d\n",ne);
}
}
ct0 = difftime(clock(),ct0);
fprintf(stdout,"\n Total running seconds: %.2f\n",
(double)ct0/(double)CLOCKS_PER_SEC);
return(0);
}