1#include <stdio.h>
2#include <stdlib.h>
3#include <assert.h>
4#include <string.h>
5
6#include "libmesh3.h"
7#include "medit.h"
8#include "extern.h"
9#include "sproto.h"
10
11
12/* save mesh to disk */
13int outmsh(pScene sc,pMesh mesh,char *fileout,ubyte clipon) {
14  LM_mesh_struct  ms;
15  pPoint     ppt,p1,p2,p3,p4;
16  pTetra     ptt;
17  pTriangle  pt1;
18  pQuad      pq1;
19  pEdge      pr;
20  pMaterial  pm;
21  float     *tv;
22  int       *te,*tmp,i,k,l,bin,np,ne,nn,nt,nq,nav,ver;
23  int        m,nridge,nrequis;
24  int        ncorner,prequis,nbpos,nbneg,nbnul,nedge;
25  char       vers[128];
26
27  if ( !LM_open_mesh(fileout, LM_WRITE, &ms, sm->dim) ) {
28    fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
29    return(0);
30  }
31  fprintf(stdout,"  %%%% %s OPENED\n",fileout);
32
33  /* compact vertices */
34  tabi = (int*)malloc(NPMAX * 4 * sizeof(int));
35  assert(tabi);
36  tabf = (float*)tabi;
37
38  if ( clipon )  markPt(mesh);
39
40  nbl = 0;
41  for(k=1; k<=mesh->np; k++) {
42    ppt = &mesh->point[k];
43    if ( ppt->tag & M_UNUSED )  continue;
44    iadr = nbl * 4;
45    tabf[ iadr + 0 ] = ppt->c[0];
46    tabf[ iadr + 1 ] = ppt->c[1];
47    tabf[ iadr + 2 ] = ppt->c[2];
48    tabi[ iadr + 3 ] = ppt->ref;
49    ++nbl;
50    if ( nbl == NPMAX ) {
51      LM_write_field(&ms, LM_Vertices, nbl, tabf);
52      nbl = 0;
53    }
54  }
55  LM_write_field(&ms, LM_Vertices, nbl, tabf);
56
57
58
59  for (k=1; k<=mesh->np; k++) {
60    ppt = &mesh->point[k];
61    if ( ppt->ttmp )
62    ppt->tmp = ++np;
63  }
64
65
66  /* mark used faces */
67  if ( clipon ) {
68    for (k=1; k<=sm->nt; k++) {
69      pt1 = & sm->tria[k];
70      if ( !pt1->v[0] )  continue;
71      nbpos = nbneg = nbnul = 0;
72      for (l=0; l<3; l++) {
73        ppt = &sm->point[pt1->v[l]];
74        if ( ppt->clip == 2 )       nbpos++;
75        else if ( ppt->clip == 1 )  nbneg++;
76        else                        nbnul++;
77      }
78      if ( nbpos && nbpos+nbnul < 4 ) {
79        ++ne;
80        ++nt;
81        for (l=0; l<3; l++) {
82          ppt = &sm->point[pt1->v[l]];
83          tmp[pt1->v[l]] = 1;
84        }
85      }
86      else
87        pt1->v[0] = 0;
88    }
89    for (k=1; k<=sm->nq; k++) {
90      pq1 = & sm->quad[k];
91      if ( !pq1->v[0] )  continue;
92      nbpos = nbneg = nbnul = 0;
93      for (l=0; l<4; l++) {
94        ppt = &sm->point[pq1->v[l]];
95        if ( ppt->clip == 2 )       nbpos++;
96        else if ( ppt->clip == 1 )  nbneg++;
97        else                        nbnul++;
98      }
99      if ( nbpos && nbpos+nbnul < 5 ) {
100        ++ne;
101        ++nq;
102        for (l=0; l<4; l++) {
103          ppt = &sm->point[pq1->v[l]];
104          tmp[pq1->v[l]] = 1;
105        }
106      }
107      else
108        pq1->v[0] = 0;
109    }
110  }
111
112  else {
113    for (k=1; k<=sm->nt; k++) {
114      pt1 = &sm->tria[k];
115      if ( !pt1->v[0] )  continue;
116      m = matRef(sc,pt1->ref);
117      pm = &sc->material[m];
118      if ( pm->flag )  continue;
119      ++ne;
120      ++nt;
121      for (i=0; i<3; i++)  tmp[pt1->v[i]] = 1;
122    }
123    for (k=1; k<=sm->nq; k++) {
124      pq1 = &sm->quad[k];
125      if ( !pq1->v[0] )  continue;
126      m = matRef(sc,pq1->ref);
127      pm = &sc->material[m];
128      if ( pm->flag )  continue;
129      ++ne;
130      ++nq;
131      for (i=0; i<4; i++)  tmp[pq1->v[i]] = 1;
132    }
133    for (k=1; k<=sm->ntet; k++) {
134      ptt = &sm->tetra[k];
135      if ( !ptt->v[0] )  continue;
136      m = matRef(sc,ptt->ref);
137      pm = &sc->material[m];
138      if ( pm->flag )  continue;
139      ++ne;
140      for (i=0; i<4; i++)  tmp[ptt->v[i]] = 1;
141    }
142  }
143  if ( !ne ) {
144    fclose(out);
145    free(tmp);
146    return(1);
147  }
148
149  /* mark used vertices */
150  np = nav = 0;
151  ncorner = prequis = 0;
152  for (k=1; k<=sm->np; k++) {
153    ppt = &sm->point[k];
154    if ( !tmp[k] )  continue;
155    tmp[k] = ++np;
156    if ( ppt->tag == M_NOTAG )  nav++;
157  }
158
159  /* mesh vertices */
160  np = 0;
161  if ( sm->dim == 3 ) {
162    te = (int*)malloc(4*(sm->np+1)*sizeof(int));
163    tv = (float*)te;
164    if ( te ) {
165      for (k=1; k<=sm->np; k++) {
166        if ( !tmp[k] )  continue;
167        ppt = & sm->point[k];
168        tv[np*4+0] = ppt->x + sm->xtra;
169        tv[np*4+1] = ppt->y + sm->ytra;
170        tv[np*4+2] = ppt->z + sm->ztra;
171        te[np*4+3] = (int)ppt->ref;
172        np++;
173        if ( ppt->tag & M_CORNER )   ncorner++;
174        if ( ppt->tag & M_REQUIRED ) prequis++;
175      }
176      ecrire_bloc(out,te,np,Vertices,4,"%g %g %g %d\n");
177      free(te);
178    }
179    else {
180      if ( !bin )  formater(out);
181      ecrire_commentaire(out,"Set of mesh vertices");
182      ecrire_mot_clef(out,Vertices);
183      ecrire_int(out,np);
184      if ( !bin )  formater(out);
185      for (k=1; k<=sm->np; k++) {
186        if ( !tmp[k] )  continue;
187        ppt = & sm->point[k];
188        np++;
189        ecrire_reel(out,ppt->x);
190        ecrire_reel(out,ppt->y);
191        ecrire_reel(out,ppt->z);
192        ecrire_int(out,(int)ppt->ref);
193        if ( !bin )  formater(out);
194        if ( ppt->tag & M_CORNER )   ncorner++;
195        if ( ppt->tag & M_REQUIRED ) prequis++;
196      }
197    }
198  }
199  else {
200    te = (int*)malloc(3*sm->np*sizeof(int));
201    tv = (float*)te;
202    if ( tv ) {
203      for (k=1; k<=sm->np; k++) {
204        if ( !tmp[k] )  continue;
205        ppt = & sm->point[k];
206        tv[np*3+0] = ppt->x;
207        tv[np*3+1] = ppt->y;
208        te[np*3+2] = (int)ppt->ref;
209        if ( ppt->tag & M_CORNER )   ncorner++;
210        if ( ppt->tag & M_REQUIRED ) prequis++;
211        np++;
212      }
213      ecrire_bloc(out,te,np,Vertices,3,"%g %g %d\n");
214      free(te);
215    }
216    else {
217      if ( !bin )  formater(out);
218      ecrire_commentaire(out,"Set of mesh vertices");
219      ecrire_mot_clef(out,Vertices);
220      ecrire_int(out,np);
221      if ( !bin )  formater(out);
222      for (k=1; k<=sm->np; k++) {
223        if ( !tmp[k] )  continue;
224        ppt = & sm->point[k];
225        ecrire_reel(out,ppt->x);
226        ecrire_reel(out,ppt->y);
227        ecrire_int(out,(int)ppt->ref);
228        if ( !bin )  formater(out);
229        if ( ppt->tag & M_CORNER )   ncorner++;
230        if ( ppt->tag & M_REQUIRED ) prequis++;
231      }
232    }
233  }
234
235  /* mesh triangles */
236  if ( !bin )  formater(out);
237  nridge = nrequis = nn = 0;
238  te = (int*)malloc((4*sm->nt+1)*sizeof(int));
239  if ( te ) {
240    ne = 0;
241    for (k=1; k<=sm->nt; k++) {
242      pt1 = &sm->tria[k];
243      if ( !pt1->v[0] ) continue;
244      m = matRef(sc,pt1->ref);
245      /*m  = !pt1->ref ? DEFAULT_MAT : 1+(pt1->ref-1)%(sc->par.nbmat-1);*/
246      pm = &sc->material[m];
247      if ( pm->flag )  continue;
248      te[ne++] = tmp[pt1->v[0]];
249      te[ne++] = tmp[pt1->v[1]];
250      te[ne++] = tmp[pt1->v[2]];
251      te[ne++] = (int)pt1->ref;
252    }
253    ne /= 4;
254    ecrire_bloc(out,te,ne,Triangles,4,"%d %d %d %d\n");
255    free(te);
256  }
257  else {
258    if ( !bin )  formater(out);
259    ecrire_commentaire(out,"Set of mesh triangles (v1,v2,v3,tag)");
260    ecrire_mot_clef(out,Triangles);
261    ecrire_int(out,nt);
262    if ( !bin )  formater(out);
263    for (k=1; k<=sm->nt; k++) {
264      pt1 = &sm->tria[k];
265      if ( !pt1->v[0] ) continue;
266      m = matRef(sc,pt1->ref);
267      /*m  = !pt1->ref ? DEFAULT_MAT : 1+(pt1->ref-1)%(sc->par.nbmat-1);*/
268      pm = &sc->material[m];
269      if ( pm->flag )  continue;
270      if ( !tmp[pt1->v[0]] || !tmp[pt1->v[1]] || !tmp[pt1->v[2]] )
271        continue;
272      ecrire_int(out,tmp[pt1->v[0]]);
273      ecrire_int(out,tmp[pt1->v[1]]);
274      ecrire_int(out,tmp[pt1->v[2]]);
275      ecrire_int(out,(int)pt1->ref);
276      if ( !bin )  formater(out);
277    }
278  }
279
280  /* mesh quads */
281  if ( !bin )  formater(out);
282  te = (int*)malloc((5*sm->nq+1)*sizeof(int));
283  if ( te ) {
284    ne = 0;
285    for (k=1; k<=sm->nq; k++) {
286      pq1 = &sm->quad[k];
287      if ( !pq1->v[0] ) continue;
288      m = matRef(sc,pq1->ref);
289      /*m  = !pt1->ref ? DEFAULT_MAT : 1+(pt1->ref-1)%(sc->par.nbmat-1);*/
290      pm = &sc->material[m];
291      if ( pm->flag )  continue;
292      p1 = &sm->point[pq1->v[0]];
293      p2 = &sm->point[pq1->v[1]];
294      p3 = &sm->point[pq1->v[2]];
295      p4 = &sm->point[pq1->v[3]];
296      if ( !tmp[pq1->v[0]] || !tmp[pq1->v[1]] || !tmp[pq1->v[2]] || !tmp[pq1->v[3]] )
297        continue;
298
299      te[ne++] = tmp[pq1->v[0]];
300      te[ne++] = tmp[pq1->v[1]];
301      te[ne++] = tmp[pq1->v[2]];
302      te[ne++] = tmp[pq1->v[3]];
303      te[ne++] = (int)pq1->ref;
304    }
305    ne /= 5;
306    ecrire_bloc(out,te,ne,Quadrilaterals,5,"%d %d %d %d %d\n");
307    free(te);
308  }
309  else {
310    if ( !bin )  formater(out);
311    ecrire_commentaire(out,"Set of mesh quads (v1,v2,v3,v4,tag)");
312    ecrire_mot_clef(out,Quadrilaterals);
313    ecrire_int(out,nq);
314    if ( !bin )  formater(out);
315    for (k=1; k<=sm->nq; k++) {
316      pq1 = &sm->quad[k];
317      if ( !pq1->v[0] ) continue;
318      m = matRef(sc,pq1->ref);
319      /*m  = !pt1->ref ? DEFAULT_MAT : 1+(pt1->ref-1)%(sc->par.nbmat-1);*/
320      pm = &sc->material[m];
321      if ( pm->flag )  continue;
322      p1 = &sm->point[pq1->v[0]];
323      p2 = &sm->point[pq1->v[1]];
324      p3 = &sm->point[pq1->v[2]];
325      p4 = &sm->point[pq1->v[3]];
326      if ( !tmp[pq1->v[0]] || !tmp[pq1->v[1]] || !tmp[pq1->v[2]] || !tmp[pq1->v[3]] )
327        continue;
328      ecrire_int(out,tmp[pq1->v[0]]);
329      ecrire_int(out,tmp[pq1->v[1]]);
330      ecrire_int(out,tmp[pq1->v[2]]);
331      ecrire_int(out,tmp[pq1->v[3]]);
332      ecrire_int(out,(int)pq1->ref);
333      if ( !bin )  formater(out);
334    }
335  }
336
337  /* corners */
338  te = (int*)malloc(3*(sm->np+1)*sizeof(int));
339  if ( ncorner ) {
340    if ( te ) {
341      ncorner = 0;
342      for (k=1; k<=sm->np; k++) {
343        ppt = &sm->point[k];
344        if ( !tmp[k] )  continue;
345        else if ( ppt->tag & M_CORNER )
346          te[ncorner++] = tmp[k];
347      }
348      ecrire_bloc(out,te,ncorner,Corners,1,"%d\n");
349    }
350    else {
351      if ( !bin )  formater(out);
352      ecrire_commentaire(out,"Set of corners");
353      ecrire_mot_clef(out,Corners);
354      ecrire_int(out,ncorner);
355      if ( !bin )  formater(out);
356      for (k=1; k<=sm->np; k++) {
357        ppt = &sm->point[k];
358        if ( !tmp[k] )  continue;
359        else if ( ppt->tag & M_CORNER ) {
360	  ecrire_int(out,tmp[k]);
361	  if ( !bin )  formater(out);
362        }
363      }
364    }
365  }
366
367  /* required vertices */
368  if ( prequis ) {
369    if ( te ) {
370      prequis = 0;
371      for (k=1; k<=sm->np; k++) {
372        ppt = &sm->point[k];
373        if ( !tmp[k] )  continue;
374        else if ( ppt->tag & M_REQUIRED )
375	  te[prequis++] = tmp[k];
376      }
377      ecrire_bloc(out,te,prequis,RequiredVertices,1,"%d\n");
378    }
379    else {
380      if ( !bin )  formater(out);
381      ecrire_commentaire(out,"Set of required vertices");
382      ecrire_mot_clef(out,RequiredVertices);
383      ecrire_int(out,prequis);
384      if ( !bin )  formater(out);
385      for (k=1; k<=sm->np; k++) {
386        ppt = &sm->point[k];
387        if ( !tmp[k] )  continue;
388        else if ( ppt->tag & M_REQUIRED ) {
389	  ecrire_int(out,tmp[k]);
390	  if ( !bin )  formater(out);
391        }
392      }
393    }
394  }
395  if ( te )  free(te);
396
397  /* edges */
398  nedge = 0;
399  for (k=1; k<=sm->na; k++) {
400    pr = &sm->edge[k];
401    p1 = &sm->point[pr->v[0]];
402    p2 = &sm->point[pr->v[1]];
403    if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] )  continue;
404    ++nedge;
405  }
406  if ( nedge ) {
407    te = (int*)malloc(3*(sm->na+1)*sizeof(int));
408    nridge = nrequis = 0;
409    if ( te ) {
410      nedge = 0;
411      for (k=1; k<=sm->na; k++) {
412        pr = &sm->edge[k];
413        p1 = &sm->point[pr->v[0]];
414        p2 = &sm->point[pr->v[1]];
415        if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] )  continue;
416
417        te[nedge++] = tmp[pr->v[0]];
418        te[nedge++] = tmp[pr->v[1]];
419        te[nedge++] = pr->tag;
420        if ( pr->tag & M_RIDGE )    nridge++;
421        if ( pr->tag & M_REQUIRED)  nrequis++;
422      }
423      nedge /= 3;
424      ecrire_bloc(out,te,nedge,Edges,3,"%d %d %d\n");
425    }
426    else {
427      if ( !bin )  formater(out);
428      ecrire_commentaire(out,"Set of mesh edges (v1,v2,tag)");
429      ecrire_mot_clef(out,Edges);
430      ecrire_int(out,nedge);
431      if ( !bin )  formater(out);
432      for (k=1; k<=sm->na; k++) {
433        pr = &sm->edge[k];
434        p1 = &sm->point[pr->v[0]];
435        p2 = &sm->point[pr->v[1]];
436        if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] )  continue;
437	ecrire_int(out,tmp[pr->v[0]]);
438	ecrire_int(out,tmp[pr->v[1]]);
439	ecrire_int(out,pr->tag);
440	if ( !bin )  formater(out);
441      }
442    }
443
444    /* ridges */
445    if ( nridge ) {
446      if ( te ) {
447        nridge = nedge = 0;
448        for (k=1; k<=sm->na; k++) {
449          pr = &sm->edge[k];
450          p1 = &sm->point[pr->v[0]];
451          p2 = &sm->point[pr->v[1]];
452          if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] )  continue;
453          ++nedge;
454          if ( pr->tag & M_RIDGE )
455            te[nridge++] = nedge;
456        }
457        ecrire_bloc(out,te,nridge,Ridges,1,"%d\n");
458      }
459      else {
460	if ( !bin )  formater(out);
461	ecrire_commentaire(out,"Set of ridges (iv,tag)");
462	ecrire_mot_clef(out,Ridges);
463	ecrire_int(out,nridge);
464	if ( !bin )  formater(out);
465	nridge = nedge = 0;
466	for (k=1; k<=sm->na; k++) {
467          pr = &sm->edge[k];
468          p1 = &sm->point[pr->v[0]];
469          p2 = &sm->point[pr->v[1]];
470          if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] )  continue;
471          ++nedge;
472          if ( pr->tag & M_RIDGE ) {
473	    ecrire_int(out,nedge);
474	    if ( !bin )  formater(out);
475	  }
476        }
477      }
478    }
479
480    /* required edges */
481    if ( nrequis ) {
482      if ( te ) {
483        nrequis = nedge = 0;
484        for (k=1; k<=sm->na; k++) {
485          pr = &sm->edge[k];
486          p1 = &sm->point[pr->v[0]];
487          p2 = &sm->point[pr->v[1]];
488          if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] )  continue;
489          ++nedge;
490          if ( pr->tag & M_REQUIRED )
491            te[nrequis++] = nedge;
492        }
493        ecrire_bloc(out,te,nrequis,RequiredEdges,1,"%d\n");
494      }
495      else {
496	if ( !bin )  formater(out);
497	ecrire_commentaire(out,"Set of required edges (iv,tag)");
498	ecrire_mot_clef(out,RequiredEdges);
499	ecrire_int(out,nrequis);
500	if ( !bin )  formater(out);
501	nridge = nedge = 0;
502	for (k=1; k<=sm->na; k++) {
503          pr = &sm->edge[k];
504          p1 = &sm->point[pr->v[0]];
505          p2 = &sm->point[pr->v[1]];
506          if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] )  continue;
507          ++nedge;
508          if ( pr->tag & M_REQUIRED ) {
509	    ecrire_int(out,nedge);
510	    if ( !bin )  formater(out);
511	  }
512        }
513      }
514    }
515    if ( te )  free(te);
516  }
517  ecrire_mot_clef(out,End);
518  fclose(out);
519  free(tmp);
520
521  if ( !quiet ) {
522    fprintf(stdout,"    Vertices   %8d",sm->np);
523    fprintf(stdout,"  Corners  %d",ncorner);
524    fprintf(stdout,"  Required %d\n",prequis);
525    fprintf(stdout,"    Edges      %8d",nedge);
526    fprintf(stdout,"  Ridges   %d",nridge);
527    fprintf(stdout,"  Required %d\n",nrequis);
528    if ( sm->ne )  fprintf(stdout,"    Triangles  %8d  Quads   %8d\n",nt,nq);
529  }
530
531  return(1);
532}
533