Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
inout_3d.c
Go to the documentation of this file.
1/* =============================================================================
2** This file is part of the mmg software package for the tetrahedral
3** mesh modification.
4** Copyright (c) Bx INP/CNRS/Inria/UBordeaux/UPMC, 2004-
5**
6** mmg is free software: you can redistribute it and/or modify it
7** under the terms of the GNU Lesser General Public License as published
8** by the Free Software Foundation, either version 3 of the License, or
9** (at your option) any later version.
10**
11** mmg is distributed in the hope that it will be useful, but WITHOUT
12** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13** FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14** License for more details.
15**
16** You should have received a copy of the GNU Lesser General Public
17** License and of the GNU General Public License along with mmg (in
18** files COPYING.LESSER and COPYING). If not, see
19** <http://www.gnu.org/licenses/>. Please read their terms carefully and
20** use this copy of the mmg distribution only if you accept them.
21** =============================================================================
22*/
23
36#include "libmmg3d.h"
37#include "libmmg3d_private.h"
38
53int MMG3D_openMesh(int imprim,const char *filename,FILE **inm,int *bin,
54 char *modeASCII, char* modeBIN) {
55 char *ptr,*data;
56 int out,ier;
57
58 out = (strchr(modeASCII,'w') != NULL) ? 1 : 0;
59 ier = out ? 0 : -1;
60
61 *bin = 0;
62 MMG5_SAFE_CALLOC(data,strlen(filename)+7,char,return ier);
63
64 strcpy(data,filename);
65 ptr = strstr(data,".mesh");
66
67 if ( !ptr ) {
68 /* data contains the filename without extension */
69 strcat(data,".meshb");
70 if( !(*inm = fopen(data,modeBIN)) ) {
71 /* our file is not a .meshb file, try with .mesh ext */
72 ptr = strstr(data,".mesh");
73 *ptr = '\0';
74 strcat(data,".mesh");
75 if( !(*inm = fopen(data,modeASCII)) ) {
76 MMG5_SAFE_FREE(data);
77 return 0;
78 }
79 }
80 else *bin = 1;
81 }
82 else {
83 ptr = strstr(data,".meshb");
84 if ( ptr ) {
85 *bin = 1;
86 if( !(*inm = fopen(data,modeBIN)) ) {
87 if ( out ) {
88 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data);
89 }
90 MMG5_SAFE_FREE(data);
91 return 0;
92 }
93 }
94 else {
95 if( !(*inm = fopen(data,modeASCII)) ) {
96 if ( out ) {
97 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data);
98 }
99 MMG5_SAFE_FREE(data);
100 return 0;
101 }
102 }
103 }
104
105 if ( imprim >= 0 ) {
106 fprintf(stdout," %%%% %s OPENED\n",data);
107 }
108 MMG5_SAFE_FREE(data);
109
110 return 1;
111}
112
113int MMG3D_loadMesh_opened(MMG5_pMesh mesh,FILE *inm,int bin) {
114 MMG5_pTetra pt;
115 MMG5_pPrism pp;
116 MMG5_pTria pt1;
117 MMG5_pQuad pq1;
118 MMG5_pEdge pa;
119 MMG5_pPoint ppt;
120 double *norm,*n,dd;
121 float fc;
122 long posnp,posnt,posne,posned,posncor,posnpreq,posntreq,posnereq,posnedreq;
123 long posnr,posnprism,posnormal,posnc1,posnq,posnqreq;
124 long posnppar,posntpar,posnepar,posnedpar,posnqpar;
125 MMG5_int npreq,ntreq,nereq,nedreq,nqreq,ncor,ned,ng;
126 MMG5_int nppar,nedpar,ntpar,nqpar,nepar;
127 MMG5_int k,ip,idn;
128 int i,bdim,binch,iswp,bpos;
129 MMG5_int na,nr,ia,aux,nref,ref;
130 char chaine[MMG5_FILESTR_LGTH],strskip[MMG5_FILESTR_LGTH];
131
132 posnp = posnt = posne = posncor = 0;
133 posnpreq = posntreq = posnereq = posnqreq = posned = posnedreq = posnr = 0;
134 posnprism = posnormal= posnc1 = posnq = 0;
135 posnppar = posnedpar = posntpar = posnqpar = posnepar = 0;
136 ncor = ned = npreq = ntreq = nqreq = nereq = nedreq = nr = ng = 0;
137 nppar = nedpar = ntpar = nqpar = nepar = 0;
138 iswp = 0;
139 mesh->np = mesh->nt = mesh->ne = 0;
140 nref = 0;
141
142
143 if (!bin) {
144 strcpy(chaine,"D");
145 while(fscanf(inm,"%127s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) {
146 if ( chaine[0] == '#' ) {
147 fgets(strskip,MMG5_FILESTR_LGTH,inm);
148 continue;
149 }
150
151 if(!strncmp(chaine,"MeshVersionFormatted",strlen("MeshVersionFormatted"))) {
152 MMG_FSCANF(inm,"%d",&mesh->ver);
153 continue;
154 } else if(!strncmp(chaine,"Dimension",strlen("Dimension"))) {
155 MMG_FSCANF(inm,"%d",&mesh->dim);
156 if(mesh->dim!=3) {
157 fprintf(stderr,"BAD DIMENSION : %d\n",mesh->dim);
158 return -1;
159 }
160 continue;
161 } else if(!strncmp(chaine,"Vertices",strlen("Vertices"))) {
162 MMG_FSCANF(inm,"%" MMG5_PRId "",&mesh->npi);
163 posnp = ftell(inm);
164 continue;
165 } else if(!strncmp(chaine,"RequiredVertices",strlen("RequiredVertices"))) {
166 MMG_FSCANF(inm,"%" MMG5_PRId "",&npreq);
167 posnpreq = ftell(inm);
168 continue;
169 } else if(!strncmp(chaine,"ParallelVertices",strlen("ParallelVertices"))) {
170 MMG_FSCANF(inm,"%" MMG5_PRId "",&nppar);
171 posnppar = ftell(inm);
172 continue;
173 } else if(!strncmp(chaine,"Triangles",strlen("Triangles"))) {
174 if ( !strncmp(chaine,"TrianglesP",strlen("TrianglesP")) ) continue;
175 MMG_FSCANF(inm,"%" MMG5_PRId "",&mesh->nti);
176 posnt = ftell(inm);
177 continue;
178 } else if(!strncmp(chaine,"RequiredTriangles",strlen("RequiredTriangles"))) {
179 MMG_FSCANF(inm,"%" MMG5_PRId "",&ntreq);
180 posntreq = ftell(inm);
181 continue;
182 } else if(!strncmp(chaine,"ParallelTriangles",strlen("ParallelTriangles"))) {
183 MMG_FSCANF(inm,"%" MMG5_PRId "",&ntpar);
184 posntpar = ftell(inm);
185 continue;
186 }
187 else if(!strncmp(chaine,"Quadrilaterals",strlen("Quadrilaterals"))) {
188 MMG_FSCANF(inm,"%" MMG5_PRId "",&mesh->nquad);
189 posnq = ftell(inm);
190 continue;
191 } else if(!strncmp(chaine,"RequiredQuadrilaterals",strlen("RequiredQuadrilaterals"))) {
192 MMG_FSCANF(inm,"%" MMG5_PRId "",&nqreq);
193 posnqreq = ftell(inm);
194 continue;
195 } else if(!strncmp(chaine,"ParallelQuadrilaterals",strlen("ParallelQuadrilaterals"))) {
196 MMG_FSCANF(inm,"%" MMG5_PRId "",&nqpar);
197 posnqpar = ftell(inm);
198 continue;
199 } else if(!strncmp(chaine,"Tetrahedra",strlen("Tetrahedra"))) {
200 if ( !strncmp(chaine,"TetrahedraP",strlen("TetrahedraP")) ) continue;
201 MMG_FSCANF(inm,"%" MMG5_PRId "",&mesh->nei);
202 posne = ftell(inm);
203 continue;
204 } else if((!strncmp(chaine,"Prisms",strlen("Prisms")))||
205 (!strncmp(chaine,"Pentahedra",strlen("Pentahedra")))) {
206 MMG_FSCANF(inm,"%" MMG5_PRId "",&mesh->nprism);
207 posnprism = ftell(inm);
208 continue;
209 } else if(!strncmp(chaine,"RequiredTetrahedra",strlen("RequiredTetrahedra"))) {
210 MMG_FSCANF(inm,"%" MMG5_PRId "",&nereq);
211 posnereq = ftell(inm);
212 continue;
213 } else if(!strncmp(chaine,"ParallelTetrahedra",strlen("ParallelTetrahedra"))) {
214 MMG_FSCANF(inm,"%" MMG5_PRId "",&nepar);
215 posnepar = ftell(inm);
216 continue;
217 } else if(!strncmp(chaine,"Corners",strlen("Corners"))) {
218 MMG_FSCANF(inm,"%" MMG5_PRId "",&ncor);
219 posncor = ftell(inm);
220 continue;
221 } else if(!strncmp(chaine,"Edges",strlen("Edges"))) {
222 MMG_FSCANF(inm,"%" MMG5_PRId "",&mesh->nai);
223 posned = ftell(inm);
224 continue;
225 } else if(!strncmp(chaine,"RequiredEdges",strlen("RequiredEdges"))) {
226 MMG_FSCANF(inm,"%" MMG5_PRId "",&nedreq);
227 posnedreq = ftell(inm);
228 continue;
229 } else if(!strncmp(chaine,"ParallelEdges",strlen("ParallelEdges"))) {
230 MMG_FSCANF(inm,"%" MMG5_PRId "",&nedpar);
231 posnedpar = ftell(inm);
232 continue;
233 } else if(!strncmp(chaine,"Ridges",strlen("Ridges"))) {
234 MMG_FSCANF(inm,"%" MMG5_PRId "",&nr);
235 posnr = ftell(inm);
236 continue;
237 } else if(!ng && !strncmp(chaine,"Normals",strlen("Normals"))) {
238 MMG_FSCANF(inm,"%" MMG5_PRId "",&ng);
239 posnormal = ftell(inm);
240 continue;
241 } else if(!strncmp(chaine,"NormalAtVertices",strlen("NormalAtVertices"))) {
242 MMG_FSCANF(inm,"%" MMG5_PRId "",&mesh->nc1);
243 posnc1 = ftell(inm);
244 continue;
245 }
246 }
247 } else { //binary file
248 bdim = 0;
249 MMG_FREAD(&mesh->ver,MMG5_SW,1,inm);
250 iswp=0;
251 if(mesh->ver==16777216)
252 iswp=1;
253 else if(mesh->ver!=1) {
254 fprintf(stderr,"BAD FILE ENCODING\n");
255 }
256 MMG_FREAD(&mesh->ver,MMG5_SW,1,inm);
257 if(iswp) mesh->ver = MMG5_swapbin(mesh->ver);
258 while(fread(&binch,MMG5_SW,1,inm)!=0 && binch!=54 ) {
259 if(iswp) binch=MMG5_swapbin(binch);
260 if(binch==54) break;
261 if(!bdim && binch==3) { //Dimension
262 MMG_FREAD(&bdim,MMG5_SW,1,inm); //NulPos=>20
263 if(iswp) bdim=MMG5_swapbin(bdim);
264 MMG_FREAD(&bdim,MMG5_SW,1,inm);
265 if(iswp) bdim=MMG5_swapbin(bdim);
266 mesh->dim = bdim;
267 if(bdim!=3) {
268 fprintf(stderr,"BAD MESH DIMENSION : %d\n",mesh->dim);
269 fprintf(stderr," Exit program.\n");
270 return -1;
271 }
272 continue;
273 } else if(!mesh->npi && binch==4) { //Vertices
274 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
275 if(iswp) bpos=MMG5_swapbin(bpos);
276 MMG_FREAD(&mesh->npi,MMG5_SW,1,inm);
277 if(iswp) mesh->npi=MMG5_SWAPBIN(mesh->npi);
278 posnp = ftell(inm);
279 rewind(inm);
280 fseek(inm,bpos,SEEK_SET);
281 continue;
282 } else if(binch==15) { //RequiredVertices
283 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
284 if(iswp) bpos=MMG5_swapbin(bpos);
285 MMG_FREAD(&npreq,MMG5_SW,1,inm);
286 if(iswp) npreq=MMG5_SWAPBIN(npreq);
287 posnpreq = ftell(inm);
288 rewind(inm);
289 fseek(inm,bpos,SEEK_SET);
290 continue;
291 } else if(!mesh->nti && binch==6) {//Triangles
292 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
293 if(iswp) bpos=MMG5_swapbin(bpos);
294 MMG_FREAD(&mesh->nti,MMG5_SW,1,inm);
295 if(iswp) mesh->nti=MMG5_SWAPBIN(mesh->nti);
296 posnt = ftell(inm);
297 rewind(inm);
298 fseek(inm,bpos,SEEK_SET);
299 continue;
300 } else if(binch==17) { //RequiredTriangles
301 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
302 if(iswp) bpos=MMG5_swapbin(bpos);
303 MMG_FREAD(&ntreq,MMG5_SW,1,inm);
304 if(iswp) ntreq=MMG5_SWAPBIN(ntreq);
305 posntreq = ftell(inm);
306 rewind(inm);
307 fseek(inm,bpos,SEEK_SET);
308 continue;
309 }
310 else if(!mesh->nquad && binch==7) {//Quadrilaterals
311 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
312 if(iswp) bpos=MMG5_swapbin(bpos);
313 MMG_FREAD(&mesh->nquad,MMG5_SW,1,inm);
314 if(iswp) mesh->nquad=MMG5_SWAPBIN(mesh->nquad);
315 posnq = ftell(inm);
316 rewind(inm);
317 fseek(inm,bpos,SEEK_SET);
318 continue;
319 } else if(binch==18) { //RequiredQuadrilaterals
320 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
321 if(iswp) bpos=MMG5_swapbin(bpos);
322 MMG_FREAD(&nqreq,MMG5_SW,1,inm);
323 if(iswp) nqreq=MMG5_SWAPBIN(nqreq);
324 posnqreq = ftell(inm);
325 rewind(inm);
326 fseek(inm,bpos,SEEK_SET);
327 continue;
328 } else if(!mesh->nei && binch==8) {//Tetra
329 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
330 if(iswp) bpos=MMG5_swapbin(bpos);
331 MMG_FREAD(&mesh->nei,MMG5_SW,1,inm);
332 if(iswp) mesh->nei=MMG5_SWAPBIN(mesh->nei);
333 posne = ftell(inm);
334 rewind(inm);
335 fseek(inm,bpos,SEEK_SET);
336 continue;
337 } else if(!mesh->nprism && binch==9) {//Prism
338 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
339 if(iswp) bpos=MMG5_swapbin(bpos);
340 MMG_FREAD(&mesh->nprism,MMG5_SW,1,inm);
341 if(iswp) mesh->nprism=MMG5_SWAPBIN(mesh->nprism);
342 posnprism = ftell(inm);
343 rewind(inm);
344 fseek(inm,bpos,SEEK_SET);
345 continue;
346 } else if(binch==12) { //RequiredTetra
347 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
348 if(iswp) bpos=MMG5_swapbin(bpos);
349 MMG_FREAD(&nereq,MMG5_SW,1,inm);
350 if(iswp) nereq=MMG5_SWAPBIN(nereq);
351 posnereq = ftell(inm);
352 rewind(inm);
353 fseek(inm,bpos,SEEK_SET);
354 continue;
355 } else if(!ncor && binch==13) { //Corners
356 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
357 if(iswp) bpos=MMG5_swapbin(bpos);
358 MMG_FREAD(&ncor,MMG5_SW,1,inm);
359 if(iswp) ncor=MMG5_SWAPBIN(ncor);
360 posncor = ftell(inm);
361 rewind(inm);
362 fseek(inm,bpos,SEEK_SET);
363 continue;
364 } else if(!mesh->nai && binch==5) { //Edges
365 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
366 if(iswp) bpos=MMG5_swapbin(bpos);
367 MMG_FREAD(&mesh->nai,MMG5_SW,1,inm);
368 if(iswp) mesh->nai=MMG5_SWAPBIN(mesh->nai);
369 posned = ftell(inm);
370 rewind(inm);
371 fseek(inm,bpos,SEEK_SET);
372 continue;
373 } else if(binch==16) { //RequiredEdges
374 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
375 if(iswp) bpos=MMG5_swapbin(bpos);
376 MMG_FREAD(&nedreq,MMG5_SW,1,inm);
377 if(iswp) nedreq=MMG5_SWAPBIN(nedreq);
378 posnedreq = ftell(inm);
379 rewind(inm);
380 fseek(inm,bpos,SEEK_SET);
381 continue;
382 } else if(binch==14) { //Ridges
383 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
384 if(iswp) bpos=MMG5_swapbin(bpos);
385 MMG_FREAD(&nr,MMG5_SW,1,inm);
386 if(iswp) nr=MMG5_SWAPBIN(nr);
387 posnr = ftell(inm);
388 rewind(inm);
389 fseek(inm,bpos,SEEK_SET);
390 continue;
391 } else if(!ng && binch==60) { //Normals
392 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
393 if(iswp) bpos=MMG5_swapbin(bpos);
394 MMG_FREAD(&ng,MMG5_SW,1,inm);
395 if(iswp) ng=MMG5_SWAPBIN(ng);
396 posnormal = ftell(inm);
397 rewind(inm);
398 fseek(inm,bpos,SEEK_SET);
399 continue;
400 } else if(binch==20) { //NormalAtVertices
401 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
402 if(iswp) bpos=MMG5_swapbin(bpos);
403 MMG_FREAD(&mesh->nc1,MMG5_SW,1,inm);
404 if(iswp) mesh->nc1=MMG5_SWAPBIN(mesh->nc1);
405 posnc1 = ftell(inm);
406 rewind(inm);
407 fseek(inm,bpos,SEEK_SET);
408 continue;
409 } else {
410 MMG_FREAD(&bpos,MMG5_SW,1,inm); //NulPos
411 if(iswp) bpos=MMG5_swapbin(bpos);
412
413 rewind(inm);
414 fseek(inm,bpos,SEEK_SET);
415 }
416 }
417 }
418
419 if ( !mesh->npi || !mesh->nei ) {
420 fprintf(stderr," ** MISSING DATA.\n");
421 fprintf(stderr," Check that your mesh contains points and tetrahedra.\n");
422 fprintf(stderr," Exit program.\n");
423 return -1;
424 }
425 /* memory allocation */
426 mesh->np = mesh->npi;
427 mesh->nt = mesh->nti;
428 mesh->ne = mesh->nei;
429 mesh->na = mesh->nai;
430 if ( !MMG3D_zaldy(mesh) ) return 0;
431 if (mesh->npmax < mesh->np || mesh->ntmax < mesh->nt || mesh->nemax < mesh->ne) {
432 return -1;
433 }
434
435 rewind(inm);
436 fseek(inm,posnp,SEEK_SET);
437 for (k=1; k<=mesh->np; k++) {
438 ppt = &mesh->point[k];
439 if (mesh->ver < 2) { /*float*/
440 if (!bin) {
441 for (i=0 ; i<3 ; i++) {
442 MMG_FSCANF(inm,"%f",&fc);
443 ppt->c[i] = (double) fc;
444 }
445 MMG_FSCANF(inm,"%" MMG5_PRId "",&ppt->ref);
446 } else {
447 for (i=0 ; i<3 ; i++) {
448 MMG_FREAD(&fc,MMG5_SW,1,inm);
449 if(iswp) fc=MMG5_swapf(fc);
450 ppt->c[i] = (double) fc;
451 }
452 MMG_FREAD(&ppt->ref,MMG5_SW,1,inm);
453 if(iswp) ppt->ref=MMG5_SWAPBIN(ppt->ref);
454 }
455 } else {
456 if (!bin) {
457 MMG_FSCANF(inm,"%lf %lf %lf %" MMG5_PRId "",&ppt->c[0],&ppt->c[1],&ppt->c[2],&ppt->ref);
458 }
459 else {
460 for (i=0 ; i<3 ; i++) {
461 MMG_FREAD(&ppt->c[i],MMG5_SD,1,inm);
462 if(iswp) ppt->c[i]=MMG5_swapd(ppt->c[i]);
463 }
464 MMG_FREAD(&ppt->ref,MMG5_SW,1,inm);
465 if(iswp) ppt->ref=MMG5_SWAPBIN(ppt->ref);
466 }
467 }
468
469 if ( ppt->ref < 0 ) {
470 ppt->ref = -ppt->ref;
471 ++nref;
472 }
473
474 ppt->tag = MG_NUL;
475 ppt->tmp = 0;
476 }
477 /* get required vertices */
478 if(npreq) {
479 rewind(inm);
480 fseek(inm,posnpreq,SEEK_SET);
481 for (k=1; k<=npreq; k++) {
482 if(!bin) {
483 MMG_FSCANF(inm,"%d",&i);
484 }
485 else {
486 MMG_FREAD(&i,MMG5_SW,1,inm);
487 if(iswp) i=MMG5_swapbin(i);
488 }
489 if(i>mesh->np) {
490 fprintf(stderr,"\n ## Warning: %s: required Vertices number %8d"
491 " ignored.\n",__func__,i);
492 } else {
493 ppt = &mesh->point[i];
494 ppt->tag |= MG_REQ;
495 ppt->tag &= ~MG_NUL;
496 }
497 }
498 }
499 /* get parallel vertices */
500 if(nppar) {
501 rewind(inm);
502 fseek(inm,posnppar,SEEK_SET);
503 for (k=1; k<=nppar; k++) {
504 if(!bin) {
505 MMG_FSCANF(inm,"%d",&i);
506 }
507 else {
508 MMG_FREAD(&i,MMG5_SW,1,inm);
509 if(iswp) i=MMG5_swapbin(i);
510 }
511 if(i>mesh->np) {
512 fprintf(stderr,"\n ## Warning: %s: parallel Vertices number %8d"
513 " ignored.\n",__func__,i);
514 } else {
515 ppt = &mesh->point[i];
516 ppt->tag |= MG_PARBDY;
517 }
518 }
519 }
520
521
522 /* get corners */
523 if(ncor) {
524 rewind(inm);
525 fseek(inm,posncor,SEEK_SET);
526 for (k=1; k<=ncor; k++) {
527 if(!bin) {
528 MMG_FSCANF(inm,"%d",&i);
529 }
530 else {
531 MMG_FREAD(&i,MMG5_SW,1,inm);
532 if(iswp) i=MMG5_swapbin(i);
533 }
534 if(i>mesh->np) {
535 fprintf(stderr,"\n ## Warning: %s: corner number %8d ignored.\n",
536 __func__,i);
537 } else {
538 ppt = &mesh->point[i];
539 ppt->tag |= MG_CRN;
540 }
541 }
542 }
543
544 /* read mesh triangles */
545 if ( mesh->nt ) {
546 rewind(inm);
547 fseek(inm,posnt,SEEK_SET);
548 /* Skip triangles with mesh->info.isoref refs */
549 for (k=1; k<=mesh->nt; k++) {
550 pt1 = &mesh->tria[k];
551 if (!bin) {
552 MMG_FSCANF(inm,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "",&pt1->v[0],&pt1->v[1],&pt1->v[2],&pt1->ref);
553 }
554 else {
555 for (i=0 ; i<3 ; i++) {
556 MMG_FREAD(&pt1->v[i],MMG5_SW,1,inm);
557 if(iswp) pt1->v[i]=MMG5_SWAPBIN(pt1->v[i]);
558 }
559 MMG_FREAD(&pt1->ref,MMG5_SW,1,inm);
560 if(iswp) pt1->ref=MMG5_SWAPBIN(pt1->ref);
561 }
562 if ( pt1->ref < 0 ) {
563 pt1->ref = -pt1->ref;
564 ++nref;
565 }
566 }
567 /* get required triangles */
568 if(ntreq) {
569 rewind(inm);
570 fseek(inm,posntreq,SEEK_SET);
571 for (k=1; k<=ntreq; k++) {
572 if(!bin) {
573 MMG_FSCANF(inm,"%d",&i);
574 }
575 else {
576 MMG_FREAD(&i,MMG5_SW,1,inm);
577 if(iswp) i=MMG5_swapbin(i);
578 }
579 if ( i>mesh->nt ) {
580 fprintf(stderr,"\n ## Warning: %s: required triangle number %8d"
581 " ignored.\n",__func__,i);
582 } else {
583 pt1 = &mesh->tria[i];
584 pt1->tag[0] |= MG_REQ;
585 pt1->tag[1] |= MG_REQ;
586 pt1->tag[2] |= MG_REQ;
587 }
588 }
589 }
590 /* get parallel triangles */
591 if(ntpar) {
592 rewind(inm);
593 fseek(inm,posntpar,SEEK_SET);
594 for (k=1; k<=ntpar; k++) {
595 if(!bin) {
596 MMG_FSCANF(inm,"%d",&i);
597 }
598 else {
599 MMG_FREAD(&i,MMG5_SW,1,inm);
600 if(iswp) i=MMG5_swapbin(i);
601 }
602 if ( i>mesh->nt ) {
603 fprintf(stderr,"\n ## Warning: %s: parallel triangle number %8d"
604 " ignored.\n",__func__,i);
605 } else {
606 pt1 = &mesh->tria[i];
607 pt1->tag[0] |= MG_PARBDY;
608 pt1->tag[1] |= MG_PARBDY;
609 pt1->tag[2] |= MG_PARBDY;
610 }
611 }
612 }
613 } //end if mesh->nt
614
615 /* read mesh quadrilaterals */
616 if ( mesh->nquad ) {
617 rewind(inm);
618 fseek(inm,posnq,SEEK_SET);
619
620 for (k=1; k<=mesh->nquad; k++) {
621 pq1 = &mesh->quadra[k];
622 if (!bin) {
623 MMG_FSCANF(inm,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "",&pq1->v[0],&pq1->v[1],&pq1->v[2],
624 &pq1->v[3],&pq1->ref);
625 }
626 else {
627 for (i=0 ; i<4 ; i++) {
628 MMG_FREAD(&pq1->v[i],MMG5_SW,1,inm);
629 if(iswp) pq1->v[i]=MMG5_SWAPBIN(pq1->v[i]);
630 }
631 MMG_FREAD(&pq1->ref,MMG5_SW,1,inm);
632 if(iswp) pq1->ref=MMG5_SWAPBIN(pq1->ref);
633 }
634 if ( pq1->ref < 0 ) {
635 pq1->ref = -pq1->ref;
636 ++nref;
637 }
638 }
639
640 /* get required quadrilaterals */
641 if(nqreq) {
642 rewind(inm);
643 fseek(inm,posnqreq,SEEK_SET);
644 for (k=1; k<=nqreq; k++) {
645 if(!bin) {
646 MMG_FSCANF(inm,"%d",&i);
647 }
648 else {
649 MMG_FREAD(&i,MMG5_SW,1,inm);
650 if(iswp) i=MMG5_swapbin(i);
651 }
652 if ( i>mesh->nquad ) {
653 fprintf(stderr,"\n ## Warning: %s: required quadrilaterals number"
654 " %8d ignored.\n",__func__,i);
655 } else {
656 pq1 = &mesh->quadra[i];
657 pq1->tag[0] |= MG_REQ;
658 pq1->tag[1] |= MG_REQ;
659 pq1->tag[2] |= MG_REQ;
660 pq1->tag[3] |= MG_REQ;
661 }
662 }
663 }
664
665 /* get parallel quadrilaterals */
666 if(nqpar) {
667 rewind(inm);
668 fseek(inm,posnqpar,SEEK_SET);
669 for (k=1; k<=nqpar; k++) {
670 if(!bin) {
671 MMG_FSCANF(inm,"%d",&i);
672 }
673 else {
674 MMG_FREAD(&i,MMG5_SW,1,inm);
675 if(iswp) i=MMG5_swapbin(i);
676 }
677 if ( i>mesh->nquad ) {
678 fprintf(stderr,"\n ## Warning: %s: parallel quadrilaterals number"
679 " %8d ignored.\n",__func__,i);
680 } else {
681 pq1 = &mesh->quadra[i];
682 pq1->tag[0] |= MG_PARBDY;
683 pq1->tag[1] |= MG_PARBDY;
684 pq1->tag[2] |= MG_PARBDY;
685 pq1->tag[3] |= MG_PARBDY;
686 }
687 }
688 }
689 } //end if mesh->nquad
690
691 /* read mesh edges */
692 if ( mesh->na ) {
693 na = mesh->na;
694
695 rewind(inm);
696 fseek(inm,posned,SEEK_SET);
697
698 for (k=1; k<=na; k++) {
699 pa = &mesh->edge[k];
700 if (!bin) {
701 MMG_FSCANF(inm,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "",&pa->a,&pa->b,&pa->ref);
702 }
703 else {
704 MMG_FREAD(&pa->a,MMG5_SW,1,inm);
705 if(iswp) pa->a=MMG5_SWAPBIN(pa->a);
706 MMG_FREAD(&pa->b,MMG5_SW,1,inm);
707 if(iswp) pa->b=MMG5_SWAPBIN(pa->b);
708 MMG_FREAD(&pa->ref,MMG5_SW,1,inm);
709 if(iswp) pa->ref=MMG5_SWAPBIN(pa->ref);
710 }
711 pa->tag |= MG_REF;
712 if ( pa->ref < 0 ) {
713 pa->ref = -pa->ref;
714 ++nref;
715 }
716 }
717
718 /* get ridges */
719 if ( nr ) {
720 rewind(inm);
721 fseek(inm,posnr,SEEK_SET);
722 for (k=1; k<=nr; k++) {
723 if(!bin) {
724 MMG_FSCANF(inm,"%" MMG5_PRId "",&ia);
725 }
726 else {
727 MMG_FREAD(&ia,MMG5_SW,1,inm);
728 if(iswp) ia=MMG5_SWAPBIN(ia);
729 }
730 if(ia>na) {
731 fprintf(stderr,"\n ## Warning: %s: ridge number %8" MMG5_PRId " ignored.\n",
732 __func__,ia);
733 continue;
734 }
735 pa = &mesh->edge[ia];
736 pa->tag |= MG_GEO;
737 }
738 }
739 /* get required edges */
740 if ( nedreq ) {
741 rewind(inm);
742 fseek(inm,posnedreq,SEEK_SET);
743 for (k=1; k<=nedreq; k++) {
744 if(!bin) {
745 MMG_FSCANF(inm,"%" MMG5_PRId "",&ia);
746 }
747 else {
748 MMG_FREAD(&ia,MMG5_SW,1,inm);
749 if(iswp) ia=MMG5_SWAPBIN(ia);
750 }
751 if(ia>na) {
752 fprintf(stderr,"\n ## Warning: %s: required Edges number %8" MMG5_PRId "/%8" MMG5_PRId ""
753 " ignored.\n",__func__,ia,na);
754 continue;
755 }
756 pa = &mesh->edge[ia];
757 pa->tag |= MG_REQ;
758 }
759 }
760 /* get parallel edges */
761 if ( nedpar ) {
762 rewind(inm);
763 fseek(inm,posnedpar,SEEK_SET);
764 for (k=1; k<=nedpar; k++) {
765 if(!bin) {
766 MMG_FSCANF(inm,"%" MMG5_PRId "",&ia);
767 }
768 else {
769 MMG_FREAD(&ia,MMG5_SW,1,inm);
770 if(iswp) ia=MMG5_SWAPBIN(ia);
771 }
772 if(ia>na) {
773 fprintf(stderr,"\n ## Warning: %s: parallel Edges number %8" MMG5_PRId "/%8" MMG5_PRId ""
774 " ignored.\n",__func__,ia,na);
775 continue;
776 }
777 pa = &mesh->edge[ia];
778 pa->tag |= MG_PARBDY;
779 }
780 }
781 }
782
783 /* read mesh tetrahedra */
784 rewind(inm);
785 fseek(inm,posne,SEEK_SET);
786 mesh->xt = 0;
787 for (k=1; k<=mesh->ne; k++) {
788 pt = &mesh->tetra[k];
789 if (!bin) {
790 MMG_FSCANF(inm,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "",&pt->v[0],&pt->v[1],&pt->v[2],&pt->v[3],&ref);
791 }
792 else {
793 for (i=0 ; i<4 ; i++) {
794 MMG_FREAD(&pt->v[i],MMG5_SW,1,inm);
795 if(iswp) pt->v[i]=MMG5_SWAPBIN(pt->v[i]);
796 }
797 MMG_FREAD(&ref,MMG5_SW,1,inm);
798 if(iswp) ref=MMG5_SWAPBIN(ref);
799 }
800 if(ref < 0) {
801 nref++;
802 }
803 pt->ref = MMG5_abs(ref);//0;//ref ;
804 for (i=0; i<4; i++) {
805 ppt = &mesh->point[pt->v[i]];
806 ppt->tag &= ~MG_NUL;
807 }
808
809 /* Possibly switch 2 vertices number so that each tet is positively oriented */
810 if ( MMG5_orvol(mesh->point,pt->v) < 0.0 ) {
811 /* mesh->xt temporary used to count reoriented tetra */
812 mesh->xt++;
813 aux = pt->v[2];
814 pt->v[2] = pt->v[3];
815 pt->v[3] = aux;
816 }
817 }
818 if(mesh->xt) {
819 fprintf(stderr,"\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n");
820 fprintf(stderr," BAD ORIENTATION : vol < 0 -- %8" MMG5_PRId " tetra reoriented\n",mesh->xt);
821 fprintf(stderr," $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n\n");
822 }
823 mesh->xt = 0;
824 /* get required tetrahedra */
825 if(nereq) {
826 rewind(inm);
827 fseek(inm,posnereq,SEEK_SET);
828 for (k=1; k<=nereq; k++) {
829 if(!bin) {
830 MMG_FSCANF(inm,"%d",&i);
831 }
832 else {
833 MMG_FREAD(&i,MMG5_SW,1,inm);
834 if(iswp) i=MMG5_swapbin(i);
835 }
836 if(i>mesh->ne) {
837 fprintf(stderr,"\n ## Warning: %s: required Tetra number %8d"
838 " ignored.\n",__func__,i);
839 continue;
840 }
841 pt = &mesh->tetra[i];
842 pt->tag |= MG_REQ;
843 }
844 }
845 /* get parallel tetrahedra */
846 if(nepar) {
847 rewind(inm);
848 fseek(inm,posnepar,SEEK_SET);
849 for (k=1; k<=nepar; k++) {
850 if(!bin) {
851 MMG_FSCANF(inm,"%d",&i);
852 }
853 else {
854 MMG_FREAD(&i,MMG5_SW,1,inm);
855 if(iswp) i=MMG5_swapbin(i);
856 }
857 if(i>mesh->ne) {
858 fprintf(stderr,"\n ## Warning: %s: parallel Tetra number %8d"
859 " ignored.\n",__func__,i);
860 continue;
861 }
862 pt = &mesh->tetra[i];
863 pt->tag |= MG_PARBDY;
864 }
865 }
866 /* read mesh prisms */
867 rewind(inm);
868 fseek(inm,posnprism,SEEK_SET);
869 for (k=1; k<=mesh->nprism; k++) {
870 pp = &mesh->prism[k];
871 if (!bin) {
872 MMG_FSCANF(inm,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "",&pp->v[0],&pp->v[1],&pp->v[2],
873 &pp->v[3],&pp->v[4],&pp->v[5],&ref);
874 }
875 else {
876 for (i=0 ; i<6 ; i++) {
877 MMG_FREAD(&pp->v[i],MMG5_SW,1,inm);
878 if(iswp) pp->v[i]=MMG5_SWAPBIN(pp->v[i]);
879 }
880 MMG_FREAD(&ref,MMG5_SW,1,inm);
881 if(iswp) ref=MMG5_SWAPBIN(ref);
882 }
883 pp->ref = ref;
884 if ( pp-> ref < 0 ) {
885 pp->ref = -pp->ref;
886 ++nref;
887 }
888 for (i=0; i<6; i++) {
889 ppt = &mesh->point[pp->v[i]];
890 ppt->tag &= ~MG_NUL;
891 }
892 }
893
894 if ( nref ) {
895 fprintf(stdout,"\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n");
896 fprintf(stdout," WARNING : %" MMG5_PRId " entities with unexpected refs (ref< 0).\n",nref);
897 fprintf(stdout," We take their absolute values.\n");
898 fprintf(stdout," $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n\n");
899 }
900
901 if ( !mesh->info.iso ) {
902 /* read geometric entities */
903 if ( mesh->nc1 && !ng ) {
904 fprintf(stderr,"\n ## Warning: %s: your mesh don't contains Normals but contains"
905 " NormalAtVertices. The NormalAtVertices are deleted. \n",__func__);
906 mesh->nc1 = 0;
907 }
908
909 if ( ng > 0 ) {
910 MMG5_SAFE_CALLOC(norm,3*ng+1,double,return -1);
911
912 rewind(inm);
913 fseek(inm,posnormal,SEEK_SET);
914 for (k=1; k<=ng; k++) {
915 n = &norm[3*(k-1)+1];
916 if ( mesh->ver == 1 ) {
917 if (!bin) {
918 for (i=0 ; i<3 ; i++) {
919 MMG_FSCANF(inm,"%f",&fc);
920 n[i] = (double) fc;
921 }
922 } else {
923 for (i=0 ; i<3 ; i++) {
924 MMG_FREAD(&fc,MMG5_SW,1,inm);
925 if(iswp) fc=MMG5_swapf(fc);
926 n[i] = (double) fc;
927 }
928 }
929 }
930 else {
931 if (!bin) {
932 MMG_FSCANF(inm,"%lf %lf %lf",&n[0],&n[1],&n[2]);
933 }
934 else {
935 for (i=0 ; i<3 ; i++) {
936 MMG_FREAD(&n[i],MMG5_SD,1,inm);
937 if(iswp) n[i]=MMG5_swapd(n[i]);
938 }
939 }
940 }
941 dd = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
942 if ( dd > MMG5_EPSD2 ) {
943 dd = 1.0 / sqrt(dd);
944 n[0] *= dd;
945 n[1] *= dd;
946 n[2] *= dd;
947 }
948 }
949
950 rewind(inm);
951 fseek(inm,posnc1,SEEK_SET);
952
953 for (k=1; k<=mesh->nc1; k++) {
954 if (!bin) {
955 MMG_FSCANF(inm,"%" MMG5_PRId " %" MMG5_PRId "",&ip,&idn);
956 }
957 else {
958 MMG_FREAD(&ip,MMG5_SW,1,inm);
959 if(iswp) ip=MMG5_SWAPBIN(ip);
960 MMG_FREAD(&idn,MMG5_SW,1,inm);
961 if(iswp) idn=MMG5_SWAPBIN(idn);
962 }
963 if ( idn > 0 && ip < mesh->np+1 ) {
964 if ( (mesh->info.iso ) && mesh->point[ip].xp == -1 ) {
965 /* Do not store the normals at mesh->info.isoref points (ls mode) */
966 continue;
967 }
968 memcpy(&mesh->point[ip].n,&norm[3*(idn-1)+1],3*sizeof(double));
969 }
970 }
971 MMG5_SAFE_FREE(norm);
972 }
973
974 /* Delete the mark added iso mode */
975 if ( (mesh->info.iso ) && mesh->nc1 ) {
976 for (k=1; k<=mesh->np; k++) {
977 mesh->point[k].xp = 0;
978 }
979 }
980 }
981
982 /* stats */
983 if ( abs(mesh->info.imprim) > 3 ) {
984 fprintf(stdout," NUMBER OF VERTICES %8" MMG5_PRId "\n",mesh->np);
985 fprintf(stdout," NUMBER OF TETRAHEDRA %8" MMG5_PRId "\n",mesh->ne);
986 if ( mesh->nprism )
987 fprintf(stdout," NUMBER OF PRISMS %8" MMG5_PRId "\n",mesh->nprism);
988
989 if ( mesh->na ) {
990 fprintf(stdout," NUMBER OF EDGES %8" MMG5_PRId "\n",mesh->na);
991 if ( nr )
992 fprintf(stdout," NUMBER OF RIDGES %8" MMG5_PRId "\n",nr);
993 }
994 if ( mesh->nt )
995 fprintf(stdout," NUMBER OF TRIANGLES %8" MMG5_PRId "\n",mesh->nt);
996 if ( mesh->nquad )
997 fprintf(stdout," NUMBER OF QUADRILATERALS %8" MMG5_PRId "\n",mesh->nquad);
998
999
1000 if ( npreq || nedreq || ntreq || nereq || nqreq ) {
1001 fprintf(stdout," NUMBER OF REQUIRED ENTITIES: \n");
1002 if ( npreq )
1003 fprintf(stdout," VERTICES %8" MMG5_PRId " \n",npreq);
1004 if ( nedreq )
1005 fprintf(stdout," EDGES %8" MMG5_PRId " \n",nedreq);
1006 if ( ntreq )
1007 fprintf(stdout," TRIANGLES %8" MMG5_PRId " \n",ntreq);
1008 if ( nqreq )
1009 fprintf(stdout," QUADRILATERALS %8" MMG5_PRId " \n",nqreq);
1010 if ( nereq )
1011 fprintf(stdout," TETRAHEDRA %8" MMG5_PRId " \n",nereq);
1012 }
1013 if(ncor)
1014 fprintf(stdout," NUMBER OF CORNERS %8" MMG5_PRId " \n",ncor);
1015
1016 if ( nppar || nedpar || ntpar || nepar || nqpar ) {
1017 fprintf(stdout," NUMBER OF PARALLEL ENTITIES: \n");
1018 if ( nppar )
1019 fprintf(stdout," VERTICES %8" MMG5_PRId " \n",nppar);
1020 if ( nedpar )
1021 fprintf(stdout," EDGES %8" MMG5_PRId " \n",nedpar);
1022 if ( ntpar )
1023 fprintf(stdout," TRIANGLES %8" MMG5_PRId " \n",ntpar);
1024 if ( nqpar )
1025 fprintf(stdout," QUADRILATERALS %8" MMG5_PRId " \n",nqpar);
1026 if ( nepar )
1027 fprintf(stdout," TETRAHEDRA %8" MMG5_PRId " \n",nepar);
1028 }
1029 }
1030
1031 return 1;
1032}
1033
1045 FILE* inm;
1046 int bin,ier;
1047
1048 ier = MMG3D_openMesh(mesh->info.imprim,filename,&inm,&bin,"rb","rb");
1049 if( ier < 1 ) return ier;
1050 ier = MMG3D_loadMesh_opened(mesh,inm,bin);
1051 if( ier < 1 ) return ier;
1052
1053 fclose(inm);
1054 return 1;
1055}
1056
1057
1059 FILE* inm;
1060 int ier;
1061 long posNodes,posElts,*posNodeData;
1062 int bin,iswp;
1063 MMG5_int nelts;
1064 int nsols;
1065
1066 mesh->dim = 3;
1067
1069 &posNodes,&posElts,&posNodeData,
1070 &bin,&iswp,&nelts,&nsols);
1071 if ( ier < 1 ) return (ier);
1072
1073 if ( nsols>1 ) {
1074 fprintf(stderr,"Error: SEVERAL SOLUTIONS FOUND (%d)\n",nsols);
1075 fclose(inm);
1076 MMG5_SAFE_FREE(posNodeData);
1077 return -1;
1078 }
1079
1080 if ( !MMG3D_zaldy(mesh) ) {
1081 fclose(inm);
1082 MMG5_SAFE_FREE(posNodeData);
1083 return -1;
1084 }
1085
1086 if (mesh->npmax < mesh->np || mesh->ntmax < mesh->nt || mesh->nemax < mesh->ne) {
1087 fclose(inm);
1088 MMG5_SAFE_FREE(posNodeData);
1089 return -1;
1090 }
1091
1092 if ( !mesh->ne ) {
1093 fprintf(stderr," ** MISSING DATA.\n");
1094 fprintf(stderr," Check that your mesh contains tetrahedra.\n");
1095 fprintf(stderr," Exit program.\n");
1096 fclose(inm);
1097 MMG5_SAFE_FREE(posNodeData);
1098 return -1;
1099 }
1100
1102 posNodes,posElts,posNodeData,
1103 bin,iswp,nelts,nsols);
1104 MMG5_SAFE_FREE(posNodeData);
1105 if ( ier < 1 ) {
1106 fprintf(stderr," ** ERROR WHEN PARSING THE INPUT FILE\n");
1107 return ier;
1108 }
1109
1110 /* Check the metric type */
1111 if ( sol ) {
1112 ier = MMG5_chkMetricType(mesh,&sol->type,&sol->entities,inm);
1113 }
1114
1115 return ier;
1116}
1117
1119 FILE* inm;
1120 int ier;
1121 long posNodes,posElts,*posNodeData;
1122 int bin,iswp;
1123 MMG5_int nelts;
1124 int nsols;
1125
1126 mesh->dim = 3;
1127
1129 &posNodes,&posElts,&posNodeData,
1130 &bin,&iswp,&nelts,&nsols);
1131 if ( ier < 1 ) return (ier);
1132
1133 mesh->nsols = nsols;
1134 if ( *sol ) MMG5_DEL_MEM(mesh,*sol);
1135
1136 MMG5_ADD_MEM(mesh,nsols*sizeof(MMG5_Sol),"solutions array",
1137 printf(" Exit program.\n"); fclose(inm);
1138 MMG5_SAFE_FREE(posNodeData);
1139 return -1);
1140 MMG5_SAFE_CALLOC(*sol,nsols,MMG5_Sol,return -1);
1141
1142 if ( !MMG3D_zaldy(mesh) ) {
1143 fclose(inm);
1144 MMG5_SAFE_FREE(posNodeData);
1145 return -1;
1146 }
1147
1148 if (mesh->npmax < mesh->np || mesh->ntmax < mesh->nt || mesh->nemax < mesh->ne) {
1149 fclose(inm);
1150 MMG5_SAFE_FREE(posNodeData);
1151 return -1;
1152 }
1153
1154 if ( !mesh->ne ) {
1155 fprintf(stderr," ** MISSING DATA.\n");
1156 fprintf(stderr," Check that your mesh contains tetrahedra.\n");
1157 fprintf(stderr," Exit program.\n");
1158 fclose(inm);
1159 MMG5_SAFE_FREE(posNodeData);
1160 return -1;
1161 }
1162
1164 posNodes,posElts,posNodeData,
1165 bin,iswp,nelts,nsols);
1166
1167 if ( ier < 1 ) {
1168 fprintf(stderr," ** ERROR WHEN PARSING THE INPUT FILE\n");
1169 }
1170
1171 MMG5_SAFE_FREE(posNodeData);
1172
1173 return ier;
1174}
1175
1177 int ier=0;
1178 const char *filenameptr,*solnameptr;
1179 char *tmp,*soltmp;
1180
1181 if ( filename && strlen(filename) ) {
1182 filenameptr = filename;
1183 solnameptr = filename;
1184 }
1185 else if (mesh->namein && strlen(mesh->namein) ) {
1186 filenameptr = mesh->namein;
1187 if ( sol && strlen(sol->namein) ) {
1188 solnameptr = sol->namein;
1189 }
1190 else {
1191 solnameptr = mesh->namein;
1192 }
1193 }
1194 else {
1195 fprintf(stderr," ## Error: %s: please provide input file name"
1196 " (either in the mesh structure or as function argument).\n",
1197 __func__);
1198 return -1;
1199 }
1200
1201 MMG5_SAFE_MALLOC(tmp,strlen(filenameptr)+1,char,return -1);
1202 strcpy(tmp,filenameptr);
1203
1204 /* read mesh/sol files */
1205 char *ptr = MMG5_Get_filenameExt(tmp);
1206 int fmt = MMG5_Get_format(ptr,MMG5_FMT_MeditASCII);
1207
1208 switch ( fmt ) {
1209
1210 case ( MMG5_FMT_GmshASCII ): case ( MMG5_FMT_GmshBinary ):
1212 break;
1213
1214 case ( MMG5_FMT_VtkVtu ):
1216 break;
1217
1218 case ( MMG5_FMT_VtkVtk ):
1220 break;
1221
1222 case ( MMG5_FMT_MeditASCII ): case ( MMG5_FMT_MeditBinary ):
1224 if ( ier < 1 ) { break; }
1225
1226 /* Facultative metric */
1227 if ( sol ) {
1228 MMG5_SAFE_MALLOC(soltmp,strlen(solnameptr)+1,char,return -1);
1229 strcpy(soltmp,solnameptr);
1230
1231 if ( MMG3D_loadSol(mesh,sol,soltmp) == -1) {
1232 fprintf(stderr,"\n ## ERROR: WRONG DATA TYPE OR WRONG SOLUTION NUMBER.\n");
1233 ier = 0;
1234 }
1235 MMG5_SAFE_FREE(soltmp);
1236 }
1237 break;
1238
1239 default:
1240 fprintf(stderr," ** I/O AT FORMAT %s NOT IMPLEMENTED.\n",MMG5_Get_formatName(fmt) );
1241 ier= -1;
1242 }
1243
1245
1246 return ier;
1247}
1248
1260 FILE* inm;
1261 MMG5_pPoint ppt;
1262 MMG5_pTetra pt;
1263 MMG5_pPrism pp;
1264 MMG5_pTria ptt;
1265 MMG5_pQuad pq;
1266 MMG5_xPoint *pxp;
1267 MMG5_int k,na,nc,np,ne,nn,nr,nre,npar,nedreq,nedpar,ntreq,ntpar,nt,nereq,nepar;
1268 MMG5_int npr,nq,nqreq,nqpar,bpos;
1269 int bin,binch;
1270 char chaine[MMG5_FILESTR_LGTH];
1271 static int8_t parWarn = 0;
1272
1273 mesh->ver = 2;
1274
1275 if ( !MMG3D_openMesh(mesh->info.imprim,filename,&inm,&bin,"w","wb") ) {
1276 return 0;
1277 }
1278
1279 /*entete fichier*/
1280 binch=0; bpos=10;
1281 if(!bin) {
1282 strcpy(&chaine[0],"MeshVersionFormatted 2\n");
1283 fprintf(inm,"%s",chaine);
1284 strcpy(&chaine[0],"\n\nDimension 3\n");
1285 fprintf(inm,"%s ",chaine);
1286 } else {
1287 binch = 1; //MeshVersionFormatted
1288 fwrite(&binch,MMG5_SW,1,inm);
1289 binch = 2; //version
1290 fwrite(&binch,MMG5_SW,1,inm);
1291 binch = 3; //Dimension
1292 fwrite(&binch,MMG5_SW,1,inm);
1293 bpos = 20; //Pos
1294 fwrite(&bpos,MMG5_SW,1,inm);
1295 binch = 3;
1296 fwrite(&binch,MMG5_SW,1,inm);
1297
1298 }
1299 /* vertices */
1300 np = nc = na = nr = nre = npar = 0;
1301
1302 if ( !mesh->point ) {
1303 fprintf(stderr, "\n ## Error: %s: points array not allocated.\n",
1304 __func__);
1305 fclose(inm);
1306 return 0;
1307 }
1308
1309
1310 for (k=1; k<=mesh->np; k++) {
1311 ppt = &mesh->point[k];
1312 if ( MG_VOK(ppt) ) {
1313 ppt->tmp = ++np;
1314 ppt->flag = 0;
1315 if ( ppt->tag & MG_CRN ) nc++;
1316 if ( ppt->tag & MG_REQ ) nre++;
1317 if ( ppt->tag & MG_PARBDY ) npar++;
1318 }
1319 }
1320
1321 if(!bin) {
1322 strcpy(&chaine[0],"\n\nVertices\n");
1323 fprintf(inm,"%s",chaine);
1324 fprintf(inm,"%" MMG5_PRId "\n",np);
1325 } else {
1326 binch = 4; //Vertices
1327 fwrite(&binch,MMG5_SW,1,inm);
1328 bpos += (3+(1+3*mesh->ver)*np)*MMG5_SW; //NullPos
1329 fwrite(&bpos,MMG5_SW,1,inm);
1330 fwrite(&np,MMG5_SW,1,inm);
1331 }
1332 for (k=1; k<=mesh->np; k++) {
1333 ppt = &mesh->point[k];
1334 if ( MG_VOK(ppt) ) {
1335 if(!bin) {
1336 fprintf(inm,"%.15lg %.15lg %.15lg %" MMG5_PRId "\n",
1337 ppt->c[0],ppt->c[1],ppt->c[2],MMG5_abs(ppt->ref));
1338 } else {
1339 fwrite((unsigned char*)&ppt->c[0],MMG5_SD,1,inm);
1340 fwrite((unsigned char*)&ppt->c[1],MMG5_SD,1,inm);
1341 fwrite((unsigned char*)&ppt->c[2],MMG5_SD,1,inm);
1342 ppt->ref = MMG5_abs(ppt->ref);
1343 fwrite((unsigned char*)&ppt->ref,MMG5_SW,1,inm);
1344 }
1345 }
1346 }
1347
1348 /* corners+required */
1349 if ( nc ) {
1350 if(!bin) {
1351 strcpy(&chaine[0],"\n\nCorners\n");
1352 fprintf(inm,"%s",chaine);
1353 fprintf(inm,"%" MMG5_PRId "\n",nc);
1354 } else {
1355 binch = 13; //
1356 fwrite(&binch,MMG5_SW,1,inm);
1357 bpos += (3+nc)*MMG5_SW; //NullPos
1358 fwrite(&bpos,MMG5_SW,1,inm);
1359 fwrite(&nc,MMG5_SW,1,inm);
1360 }
1361
1362 for (k=1; k<=mesh->np; k++) {
1363 ppt = &mesh->point[k];
1364 if ( MG_VOK(ppt) && ppt->tag & MG_CRN ) {
1365 if(!bin) {
1366 fprintf(inm,"%" MMG5_PRId "\n",ppt->tmp);
1367 } else {
1368 fwrite(&ppt->tmp,MMG5_SW,1,inm);
1369 }
1370 }
1371 }
1372 }
1373 if ( nre ) {
1374 if(!bin) {
1375 strcpy(&chaine[0],"\n\nRequiredVertices\n");
1376 fprintf(inm,"%s",chaine);
1377 fprintf(inm,"%" MMG5_PRId "\n",nre);
1378 } else {
1379 binch = 15; //
1380 fwrite(&binch,MMG5_SW,1,inm);
1381 bpos += (3+nre)*MMG5_SW; //NullPos
1382 fwrite(&bpos,MMG5_SW,1,inm);
1383 fwrite(&nre,MMG5_SW,1,inm);
1384 }
1385 for (k=1; k<=mesh->np; k++) {
1386 ppt = &mesh->point[k];
1387 if ( MG_VOK(ppt) && ppt->tag & MG_REQ ) {
1388 if(!bin) {
1389 fprintf(inm,"%" MMG5_PRId "\n",ppt->tmp);
1390 } else {
1391 fwrite(&ppt->tmp,MMG5_SW,1,inm);
1392 }
1393 }
1394 }
1395 }
1396 if ( npar ) {
1397 if(!bin) {
1398 strcpy(&chaine[0],"\n\nParallelVertices\n");
1399 fprintf(inm,"%s",chaine);
1400 fprintf(inm,"%" MMG5_PRId "\n",npar);
1401 }
1402 else {
1403 if ( !parWarn ) {
1404 parWarn = 1;
1405 fprintf(stderr, "\n ## Warning: %s: parallel entities can't be"
1406 " saved at binary format. Ignored.\n",
1407 __func__);
1408
1409 }
1410 }
1411 for (k=1; k<=mesh->np; k++) {
1412 ppt = &mesh->point[k];
1413 if ( MG_VOK(ppt) && ppt->tag & MG_PARBDY ) {
1414 if(!bin) {
1415 fprintf(inm,"%" MMG5_PRId "\n",ppt->tmp);
1416 }
1417 }
1418 }
1419 }
1420
1421 /* tetrahedra */
1422 ne = nereq = nepar = 0;
1423 if ( mesh->tetra ) {
1424 for (k=1; k<=mesh->ne; k++) {
1425 pt = &mesh->tetra[k];
1426 if ( !MG_EOK(pt) ) {
1427 continue;
1428 }
1429 ne++;
1430 if ( pt->tag & MG_REQ ){
1431 nereq++;
1432 }
1433 if ( pt->tag & MG_PARBDY ){
1434 nepar++;
1435 }
1436 }
1437 }
1438 else {
1439 fprintf(stderr, "\n ## Warning: %s: tetra array not allocated.\n",
1440 __func__);
1441 }
1442
1443 if(!bin) {
1444 strcpy(&chaine[0],"\n\nTetrahedra\n");
1445 fprintf(inm,"%s",chaine);
1446 fprintf(inm,"%" MMG5_PRId "\n",ne);
1447 } else {
1448 binch = 8; //Tetra
1449 fwrite(&binch,MMG5_SW,1,inm);
1450 bpos += (3 + 5*ne)*MMG5_SW;//Pos
1451 fwrite(&bpos,MMG5_SW,1,inm);
1452 fwrite((unsigned char*)&ne,MMG5_SW,1,inm);
1453 }
1454 for (k=1; k<=mesh->ne; k++) {
1455 pt = &mesh->tetra[k];
1456
1457 if ( !MG_EOK(pt) ) { continue; }
1458
1459 /* Tag the tetra vertices to detect points belonging to prisms only (because
1460 * we don't know the normals/tangents at this points, thus we don't want to
1461 * save it). */
1462 mesh->point[pt->v[0]].flag = 1;
1463 mesh->point[pt->v[1]].flag = 1;
1464 mesh->point[pt->v[2]].flag = 1;
1465 mesh->point[pt->v[3]].flag = 1;
1466
1467 if(!bin) {
1468 fprintf(inm,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",mesh->point[pt->v[0]].tmp,mesh->point[pt->v[1]].tmp
1469 ,mesh->point[pt->v[2]].tmp,mesh->point[pt->v[3]].tmp,pt->ref);
1470 } else {
1471 fwrite(&mesh->point[pt->v[0]].tmp,MMG5_SW,1,inm);
1472 fwrite(&mesh->point[pt->v[1]].tmp,MMG5_SW,1,inm);
1473 fwrite(&mesh->point[pt->v[2]].tmp,MMG5_SW,1,inm);
1474 fwrite(&mesh->point[pt->v[3]].tmp,MMG5_SW,1,inm);
1475 fwrite(&pt->ref,MMG5_SW,1,inm);
1476 }
1477 }
1478
1479 if ( nereq ) {
1480 if(!bin) {
1481 strcpy(&chaine[0],"\n\nRequiredTetrahedra\n");
1482 fprintf(inm,"%s",chaine);
1483 fprintf(inm,"%" MMG5_PRId "\n",nereq);
1484 } else {
1485 binch = 12; //RequiredTetra
1486 fwrite(&binch,MMG5_SW,1,inm);
1487 bpos += (3 + nereq)*MMG5_SW;//Pos
1488 fwrite(&bpos,MMG5_SW,1,inm);
1489 fwrite(&nereq,MMG5_SW,1,inm);
1490 }
1491 ne = 0;
1492 for (k=1; k<=mesh->ne; k++) {
1493 pt = &mesh->tetra[k];
1494 if ( !MG_EOK(pt) ) continue;
1495 ne++;
1496 if ( pt->tag & MG_REQ ) {
1497 if(!bin) {
1498 fprintf(inm,"%" MMG5_PRId "\n",ne);
1499 } else {
1500 fwrite(&ne,MMG5_SW,1,inm);
1501 }
1502 }
1503 }
1504 }
1505
1506 if ( nepar ) {
1507 if(!bin) {
1508 strcpy(&chaine[0],"\n\nParallelTetrahedra\n");
1509 fprintf(inm,"%s",chaine);
1510 fprintf(inm,"%" MMG5_PRId "\n",nepar);
1511 } else {
1512 if ( !parWarn ) {
1513 parWarn = 1;
1514 fprintf(stderr, "\n ## Warning: %s: parallel entities can't be"
1515 " saved at binary format. Ignored.\n",
1516 __func__);
1517
1518 }
1519 }
1520 ne = 0;
1521 for (k=1; k<=mesh->ne; k++) {
1522 pt = &mesh->tetra[k];
1523 if ( !MG_EOK(pt) ) continue;
1524 ne++;
1525 if ( pt->tag & MG_PARBDY ) {
1526 if(!bin) {
1527 fprintf(inm,"%" MMG5_PRId "\n",ne);
1528 }
1529 }
1530 }
1531 }
1532
1533 /* prisms */
1534 npr = 0;
1535 for (k=1; k<=mesh->nprism; k++) {
1536 pp = &mesh->prism[k];
1537 if ( !MG_EOK(pp) ) continue;
1538 npr++;
1539 }
1540
1541 if ( npr ) {
1542 if(!bin) {
1543 strcpy(&chaine[0],"\n\nPrisms\n");
1544 fprintf(inm,"%s",chaine);
1545 fprintf(inm,"%" MMG5_PRId "\n",npr);
1546 } else {
1547 binch = 9; //Prism
1548 fwrite(&binch,MMG5_SW,1,inm);
1549 bpos += (3 + 7*npr)*MMG5_SW;//Pos
1550 fwrite(&bpos,MMG5_SW,1,inm);
1551 fwrite((unsigned char*)&npr,MMG5_SW,1,inm);
1552 }
1553 for (k=1; k<=mesh->nprism; k++) {
1554 pp = &mesh->prism[k];
1555 if ( !MG_EOK(pp) ) continue;
1556
1557 if(!bin) {
1558 fprintf(inm,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n"
1559 ,mesh->point[pp->v[0]].tmp,mesh->point[pp->v[1]].tmp
1560 ,mesh->point[pp->v[2]].tmp,mesh->point[pp->v[3]].tmp
1561 ,mesh->point[pp->v[4]].tmp,mesh->point[pp->v[5]].tmp,pp->ref);
1562 } else {
1563 fwrite(&mesh->point[pp->v[0]].tmp,MMG5_SW,1,inm);
1564 fwrite(&mesh->point[pp->v[1]].tmp,MMG5_SW,1,inm);
1565 fwrite(&mesh->point[pp->v[2]].tmp,MMG5_SW,1,inm);
1566 fwrite(&mesh->point[pp->v[3]].tmp,MMG5_SW,1,inm);
1567 fwrite(&mesh->point[pp->v[4]].tmp,MMG5_SW,1,inm);
1568 fwrite(&mesh->point[pp->v[5]].tmp,MMG5_SW,1,inm);
1569 fwrite(&pp->ref,MMG5_SW,1,inm);
1570 }
1571 }
1572 }
1573
1574
1575 nn = nt = 0;
1576 if ( mesh->xp && mesh->xpoint ) {
1577 /* Count tangents and normals */
1578 for (k=1; k<=mesh->np; k++) {
1579 ppt = &mesh->point[k];
1580 if ( !MG_VOK(ppt) || (!ppt->flag) || MG_SIN(ppt->tag) ) {
1581 /* We compute normals at some required points but not all of them in analysis
1582 * thus it don't works to save it at the end of the process */
1583 continue;
1584 }
1585 else if ( (ppt->tag & MG_BDY)
1586 && (!(ppt->tag & MG_GEO) || (ppt->tag & MG_NOM)) ) {
1587 /* Indeed non-manifold point along connected mesh have a unique normal if
1588 * pxp->nnor==0 but saving it gives a weird visualization and keeping the
1589 * normal info is useless. */
1590 nn++;
1591 }
1592 if ( MG_EDG_OR_NOM(ppt->tag) ) {
1593 nt++;
1594 }
1595 }
1596
1597 /* write normals */
1598 if(!bin) {
1599 strcpy(&chaine[0],"\n\nNormals\n");
1600 fprintf(inm,"%s",chaine);
1601 fprintf(inm,"%" MMG5_PRId "\n",nn);
1602 } else { binch = 60; //normals
1603 fwrite(&binch,MMG5_SW,1,inm);
1604 bpos += (3+(3*mesh->ver)*nn)*MMG5_SW; //Pos
1605 fwrite(&bpos,MMG5_SW,1,inm);
1606 fwrite(&nn,MMG5_SW,1,inm);
1607 }
1608
1609 for (k=1; k<=mesh->np; k++) {
1610 ppt = &mesh->point[k];
1611 if ( !MG_VOK(ppt) || (!ppt->flag) || MG_SIN(ppt->tag) ) {
1612 continue;
1613 }
1614 else if ( (ppt->tag & MG_BDY)
1615 && (!(ppt->tag & MG_GEO) || (ppt->tag & MG_NOM)) ) {
1616 pxp = &mesh->xpoint[ppt->xp];
1617 if(!bin) {
1618 fprintf(inm,"%.15lg %.15lg %.15lg \n",pxp->n1[0],pxp->n1[1],pxp->n1[2]);
1619 } else {
1620 fwrite((unsigned char*)&pxp->n1[0],MMG5_SD,1,inm);
1621 fwrite((unsigned char*)&pxp->n1[1],MMG5_SD,1,inm);
1622 fwrite((unsigned char*)&pxp->n1[2],MMG5_SD,1,inm);
1623 }
1624 }
1625 }
1626
1627 if(!bin) {
1628 strcpy(&chaine[0],"\n\nNormalAtVertices\n");
1629 fprintf(inm,"%s",chaine);
1630 fprintf(inm,"%" MMG5_PRId "\n",nn);
1631 } else {
1632 binch = 20; //normalatvertices
1633 fwrite(&binch,MMG5_SW,1,inm);
1634 bpos += (3 + 2*nn)*MMG5_SW;//Pos
1635 fwrite(&bpos,MMG5_SW,1,inm);
1636 fwrite(&nn,MMG5_SW,1,inm);
1637 }
1638 nn = 0;
1639 for (k=1; k<=mesh->np; k++) {
1640 ppt = &mesh->point[k];
1641 if ( !MG_VOK(ppt) || (!ppt->flag) || MG_SIN(ppt->tag) ) {
1642 continue;
1643 }
1644 else if ( (ppt->tag & MG_BDY)
1645 && (!(ppt->tag & MG_GEO) || (ppt->tag & MG_NOM) ) ) {
1646 if(!bin) {
1647 fprintf(inm,"%" MMG5_PRId " %" MMG5_PRId "\n",ppt->tmp,++nn);
1648 } else {
1649 fwrite(&ppt->tmp,MMG5_SW,1,inm);
1650 ++nn;
1651 fwrite(&nn,MMG5_SW,1,inm);
1652 }
1653 }
1654 }
1655
1656 if ( nt ) {
1657 /* Write tangents */
1658 if(!bin) {
1659 strcpy(&chaine[0],"\n\nTangents\n");
1660 fprintf(inm,"%s",chaine);
1661 fprintf(inm,"%" MMG5_PRId "\n",nt);
1662 } else {
1663 binch = 59; //tangent
1664 fwrite(&binch,MMG5_SW,1,inm);
1665 bpos += (3+(3*mesh->ver)*nt)*MMG5_SW; //Pos
1666 fwrite(&bpos,MMG5_SW,1,inm);
1667 fwrite(&nt,MMG5_SW,1,inm);
1668 }
1669
1670 for (k=1; k<=mesh->np; k++) {
1671 ppt = &mesh->point[k];
1672 if ( !MG_VOK(ppt) || (!ppt->flag) || MG_SIN(ppt->tag) ) {
1673 continue;
1674 }
1675 else if ( MG_EDG_OR_NOM(ppt->tag) ) {
1676 if(!bin) {
1677 fprintf(inm,"%.15lg %.15lg %.15lg \n",ppt->n[0],ppt->n[1],ppt->n[2]);
1678 } else {
1679 fwrite((unsigned char*)&ppt->n[0],MMG5_SD,1,inm);
1680 fwrite((unsigned char*)&ppt->n[1],MMG5_SD,1,inm);
1681 fwrite((unsigned char*)&ppt->n[2],MMG5_SD,1,inm);
1682 }
1683 }
1684 }
1685
1686
1687 if(!bin) {
1688 strcpy(&chaine[0],"\n\nTangentAtVertices\n");
1689 fprintf(inm,"%s",chaine);
1690 fprintf(inm,"%" MMG5_PRId "\n",nt);
1691 } else {
1692 binch = 61; //tangentatvertices
1693 fwrite(&binch,MMG5_SW,1,inm);
1694 bpos += (3 + 2*nt)*MMG5_SW;//Pos
1695 fwrite(&bpos,MMG5_SW,1,inm);
1696 fwrite(&nt,MMG5_SW,1,inm);
1697 }
1698 nt = 0;
1699 for (k=1; k<=mesh->np; k++) {
1700 ppt = &mesh->point[k];
1701 if ( !MG_VOK(ppt) || (!ppt->flag) || MG_SIN(ppt->tag) ) {
1702 continue;
1703 }
1704 else if ( MG_EDG_OR_NOM(ppt->tag) ) {
1705 if(!bin) {
1706 fprintf(inm,"%" MMG5_PRId " %" MMG5_PRId "\n",ppt->tmp,++nt);
1707 } else {
1708 fwrite(&ppt->tmp,MMG5_SW,1,inm);
1709 ++nt;
1710 fwrite(&(nn),MMG5_SW,1,inm);
1711 }
1712 }
1713 }
1714 }
1715 }
1716
1717 /* boundary mesh */
1718 /* tria + required tria */
1719 ntreq = ntpar = 0;
1720
1721 if ( mesh->nt ) {
1722 if(!bin) {
1723 strcpy(&chaine[0],"\n\nTriangles\n");
1724 fprintf(inm,"%s",chaine);
1725 fprintf(inm,"%" MMG5_PRId "\n",mesh->nt);
1726 } else {
1727 binch = 6; //Triangles
1728 fwrite(&binch,MMG5_SW,1,inm);
1729 bpos += (3+4*mesh->nt)*MMG5_SW; //Pos
1730 fwrite(&bpos,MMG5_SW,1,inm);
1731 fwrite(&mesh->nt,MMG5_SW,1,inm);
1732 }
1733 for (k=1; k<=mesh->nt; k++) {
1734 ptt = &mesh->tria[k];
1735 if ( ptt->tag[0] & MG_REQ && ptt->tag[1] & MG_REQ && ptt->tag[2] & MG_REQ ) {
1736 ntreq++;
1737 }
1738 if ( ptt->tag[0] & MG_PARBDY && ptt->tag[1] & MG_PARBDY && ptt->tag[2] & MG_PARBDY ) {
1739 ntpar++;
1740 }
1741 if(!bin) {
1742 fprintf(inm,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",mesh->point[ptt->v[0]].tmp,mesh->point[ptt->v[1]].tmp
1743 ,mesh->point[ptt->v[2]].tmp,ptt->ref);
1744 } else {
1745 fwrite(&mesh->point[ptt->v[0]].tmp,MMG5_SW,1,inm);
1746 fwrite(&mesh->point[ptt->v[1]].tmp,MMG5_SW,1,inm);
1747 fwrite(&mesh->point[ptt->v[2]].tmp,MMG5_SW,1,inm);
1748 fwrite(&ptt->ref,MMG5_SW,1,inm);
1749 }
1750 }
1751 if ( ntreq ) {
1752 if(!bin) {
1753 strcpy(&chaine[0],"\n\nRequiredTriangles\n");
1754 fprintf(inm,"%s",chaine);
1755 fprintf(inm,"%" MMG5_PRId "\n",ntreq);
1756 } else {
1757 binch = 17; //ReqTriangles
1758 fwrite(&binch,MMG5_SW,1,inm);
1759 bpos += (3+ntreq)*MMG5_SW; //Pos
1760 fwrite(&bpos,MMG5_SW,1,inm);
1761 fwrite(&ntreq,MMG5_SW,1,inm);
1762 }
1763 for (k=0; k<=mesh->nt; k++) {
1764 ptt = &mesh->tria[k];
1765 if ( (ptt->tag[0] & MG_REQ) && (ptt->tag[1] & MG_REQ)
1766 && ptt->tag[2] & MG_REQ ) {
1767 if(!bin) {
1768 fprintf(inm,"%" MMG5_PRId "\n",k);
1769 } else {
1770 fwrite(&k,MMG5_SW,1,inm);
1771 }
1772 }
1773 }
1774 }
1775 if ( ntpar ) {
1776 if(!bin) {
1777 strcpy(&chaine[0],"\n\nParallelTriangles\n");
1778 fprintf(inm,"%s",chaine);
1779 fprintf(inm,"%" MMG5_PRId "\n",ntpar);
1780 } else {
1781 if ( !parWarn ) {
1782 parWarn = 1;
1783 fprintf(stderr, "\n ## Warning: %s: parallel entities can't be"
1784 " saved at binary format. Ignored.\n",
1785 __func__);
1786 }
1787 }
1788 for (k=0; k<=mesh->nt; k++) {
1789 ptt = &mesh->tria[k];
1790 if ( (ptt->tag[0] & MG_PARBDY) && (ptt->tag[1] & MG_PARBDY)
1791 && ptt->tag[2] & MG_PARBDY ) {
1792 if(!bin) {
1793 fprintf(inm,"%" MMG5_PRId "\n",k);
1794 }
1795 }
1796 }
1797 }
1798 }
1799
1800 /* quad + required quad */
1801 nq = nqreq = nqpar = 0;
1802
1803 if ( mesh->nquad ) {
1804
1805 for (k=1; k<=mesh->nquad; k++) {
1806 pq = &mesh->quadra[k];
1807 if ( !MG_EOK(pq) ) {
1808 continue;
1809 }
1810 nq++;
1811 if ( pq->tag[0] & MG_REQ && pq->tag[1] & MG_REQ &&
1812 pq->tag[2] & MG_REQ && pq->tag[3] & MG_REQ ) {
1813 nqreq++;
1814 }
1815 if ( pq->tag[0] & MG_PARBDY && pq->tag[1] & MG_PARBDY &&
1816 pq->tag[2] & MG_PARBDY && pq->tag[3] & MG_PARBDY ) {
1817 nqpar++;
1818 }
1819 }
1820 }
1821
1822 if ( nq ) {
1823 if(!bin) {
1824 strcpy(&chaine[0],"\n\nQuadrilaterals\n");
1825 fprintf(inm,"%s",chaine);
1826 fprintf(inm,"%" MMG5_PRId "\n",nq);
1827 } else {
1828 binch = 7; //Quadrilaterals
1829 fwrite(&binch,MMG5_SW,1,inm);
1830 bpos += (3+5*nq)*MMG5_SW; //Pos
1831 fwrite(&bpos,MMG5_SW,1,inm);
1832 fwrite(&nq,MMG5_SW,1,inm);
1833 }
1834 for (k=1; k<=mesh->nquad; k++) {
1835 pq = &mesh->quadra[k];
1836 if ( !MG_EOK(pq) ) continue;
1837
1838 if(!bin) {
1839 fprintf(inm,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",mesh->point[pq->v[0]].tmp,
1840 mesh->point[pq->v[1]].tmp,mesh->point[pq->v[2]].tmp,
1841 mesh->point[pq->v[3]].tmp, pq->ref);
1842 } else {
1843 fwrite(&mesh->point[pq->v[0]].tmp,MMG5_SW,1,inm);
1844 fwrite(&mesh->point[pq->v[1]].tmp,MMG5_SW,1,inm);
1845 fwrite(&mesh->point[pq->v[2]].tmp,MMG5_SW,1,inm);
1846 fwrite(&mesh->point[pq->v[3]].tmp,MMG5_SW,1,inm);
1847 fwrite(&pq->ref,MMG5_SW,1,inm);
1848 }
1849 }
1850 if ( nqreq ) {
1851 if(!bin) {
1852 strcpy(&chaine[0],"\n\nRequiredQuadrilaterals\n");
1853 fprintf(inm,"%s",chaine);
1854 fprintf(inm,"%" MMG5_PRId "\n",nqreq);
1855 } else {
1856 binch = 18; //ReqQuad
1857 fwrite(&binch,MMG5_SW,1,inm);
1858 bpos += (3+nqreq)*MMG5_SW; //Pos
1859 fwrite(&bpos,MMG5_SW,1,inm);
1860 fwrite(&nqreq,MMG5_SW,1,inm);
1861 }
1862 for (k=0; k<=mesh->nquad; k++) {
1863 pq = &mesh->quadra[k];
1864 if ( (pq->tag[0] & MG_REQ) && (pq->tag[1] & MG_REQ)
1865 && pq->tag[2] & MG_REQ && pq->tag[3] & MG_REQ ) {
1866 if(!bin) {
1867 fprintf(inm,"%" MMG5_PRId "\n",k);
1868 } else {
1869 fwrite(&k,MMG5_SW,1,inm);
1870 }
1871 }
1872 }
1873 }
1874 if ( nqpar ) {
1875 if(!bin) {
1876 strcpy(&chaine[0],"\n\nParallelQuadrilaterals\n");
1877 fprintf(inm,"%s",chaine);
1878 fprintf(inm,"%" MMG5_PRId "\n",nqpar);
1879 } else {
1880 if ( !parWarn ) {
1881 parWarn = 1;
1882 fprintf(stderr, "\n ## Warning: %s: parallel entities can't be"
1883 " saved at binary format. Ignored.\n",
1884 __func__);
1885 }
1886 }
1887 for (k=0; k<=mesh->nquad; k++) {
1888 pq = &mesh->quadra[k];
1889 if ( (pq->tag[0] & MG_PARBDY) && (pq->tag[1] & MG_PARBDY) &&
1890 pq->tag[2] & MG_PARBDY && pq->tag[3] & MG_PARBDY ) {
1891 if(!bin) {
1892 fprintf(inm,"%" MMG5_PRId "\n",k);
1893 }
1894 }
1895 }
1896 }
1897 }
1898
1899 nr = nedreq = nedpar = 0;
1900 if ( mesh->na ) {
1901 if(!bin) {
1902 strcpy(&chaine[0],"\n\nEdges\n");
1903 fprintf(inm,"%s",chaine);
1904 fprintf(inm,"%" MMG5_PRId "\n",mesh->na);
1905 } else {
1906 binch = 5; //Edges
1907 fwrite(&binch,MMG5_SW,1,inm);
1908 bpos += (3 + 3*mesh->na)*MMG5_SW;//Pos
1909 fwrite(&bpos,MMG5_SW,1,inm);
1910 fwrite(&mesh->na,MMG5_SW,1,inm);
1911 }
1912 for (k=1; k<=mesh->na; k++) {
1913 if(!bin) {
1914 fprintf(inm,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",mesh->point[mesh->edge[k].a].tmp,
1915 mesh->point[mesh->edge[k].b].tmp,mesh->edge[k].ref);
1916 } else {
1917 fwrite(&mesh->point[mesh->edge[k].a].tmp,MMG5_SW,1,inm);
1918 fwrite(&mesh->point[mesh->edge[k].b].tmp,MMG5_SW,1,inm);
1919 fwrite(&mesh->edge[k].ref,MMG5_SW,1,inm);
1920 }
1921 if ( mesh->edge[k].tag & MG_GEO ) nr++;
1922 if ( mesh->edge[k].tag & MG_REQ ) nedreq++;
1923 if ( mesh->edge[k].tag & MG_PARBDY ) nedpar++;
1924 }
1925
1926 if ( nr ) {
1927 if(!bin) {
1928 strcpy(&chaine[0],"\n\nRidges\n");
1929 fprintf(inm,"%s",chaine);
1930 fprintf(inm,"%" MMG5_PRId "\n",nr);
1931 } else {
1932 binch = 14; //Ridges
1933 fwrite(&binch,MMG5_SW,1,inm);
1934 bpos += (3 + nr)*MMG5_SW;//Pos
1935 fwrite(&bpos,MMG5_SW,1,inm);
1936 fwrite(&nr,MMG5_SW,1,inm);
1937 }
1938 na = 0;
1939 for (k=1; k<=mesh->na; k++) {
1940 na++;
1941 if ( mesh->edge[k].tag & MG_GEO ) {
1942 if(!bin) {
1943 fprintf(inm,"%" MMG5_PRId "\n",na);
1944 } else {
1945 fwrite(&na,MMG5_SW,1,inm);
1946 }
1947 }
1948 }
1949 }
1950
1951 if ( nedreq ) {
1952 if(!bin) {
1953 strcpy(&chaine[0],"\n\nRequiredEdges\n");
1954 fprintf(inm,"%s",chaine);
1955 fprintf(inm,"%" MMG5_PRId "\n",nedreq);
1956 } else {
1957 binch = 16; //RequiredEdges
1958 fwrite(&binch,MMG5_SW,1,inm);
1959 bpos += (3 + nedreq)*MMG5_SW;//Pos
1960 fwrite(&bpos,MMG5_SW,1,inm);
1961 fwrite(&nedreq,MMG5_SW,1,inm);
1962 }
1963 na = 0;
1964 for (k=1; k<=mesh->na; k++) {
1965 na++;
1966 if ( mesh->edge[k].tag & MG_REQ ) {
1967 if(!bin) {
1968 fprintf(inm,"%" MMG5_PRId "\n",na);
1969 } else {
1970 fwrite(&na,MMG5_SW,1,inm);
1971 }
1972 }
1973 }
1974 }
1975 if ( nedpar ) {
1976 if(!bin) {
1977 strcpy(&chaine[0],"\n\nParallelEdges\n");
1978 fprintf(inm,"%s",chaine);
1979 fprintf(inm,"%" MMG5_PRId "\n",nedpar);
1980 } else {
1981 if ( !parWarn ) {
1982 parWarn = 1;
1983 fprintf(stderr, "\n ## Warning: %s: parallel entities can't be"
1984 " saved at binary format. Ignored.\n",
1985 __func__);
1986 }
1987 }
1988 na = 0;
1989 for (k=1; k<=mesh->na; k++) {
1990 na++;
1991 if ( mesh->edge[k].tag & MG_PARBDY ) {
1992 if(!bin) {
1993 fprintf(inm,"%" MMG5_PRId "\n",na);
1994 }
1995 }
1996 }
1997 }
1998 }
1999
2000
2001 if ( mesh->info.imprim > 4 ) {
2002 fprintf(stdout," NUMBER OF VERTICES %8" MMG5_PRId " CORNERS %8" MMG5_PRId ""
2003 " REQUIRED %8" MMG5_PRId "\n",np,nc,nre);
2004 fprintf(stdout," NUMBER OF TETRAHEDRA %8" MMG5_PRId " REQUIRED %8" MMG5_PRId "\n",
2005 ne,nereq);
2006 if ( npr )
2007 fprintf(stdout," NUMBER OF PRISMS %8" MMG5_PRId "\n",npr);
2008
2009 if ( na )
2010 fprintf(stdout," NUMBER OF EDGES %8" MMG5_PRId " RIDGES %8" MMG5_PRId ""
2011 " REQUIRED %8" MMG5_PRId "\n",na,nr,nedreq);
2012 if ( mesh->nt )
2013 fprintf(stdout," NUMBER OF TRIANGLES %8" MMG5_PRId " REQUIRED %8" MMG5_PRId "\n",
2014 mesh->nt, ntreq);
2015 if ( nq )
2016 fprintf(stdout," NUMBER OF QUADRILATERALS %8" MMG5_PRId " REQUIRED %8" MMG5_PRId "\n",
2017 nq,nqreq);
2018
2019 if ( npar || nedpar || ntpar || nepar || nqpar ) {
2020 fprintf(stdout," NUMBER OF PARALLEL ENTITIES: \n");
2021 if ( npar )
2022 fprintf(stdout," VERTICES %8" MMG5_PRId " \n",npar);
2023 if ( nedpar )
2024 fprintf(stdout," EDGES %8" MMG5_PRId " \n",nedpar);
2025 if ( ntpar )
2026 fprintf(stdout," TRIANGLES %8" MMG5_PRId " \n",ntpar);
2027 if ( nqpar )
2028 fprintf(stdout," QUADRILATERALS %8" MMG5_PRId " \n",nqpar);
2029 if ( nepar )
2030 fprintf(stdout," TETRAHEDRA %8" MMG5_PRId " \n",nepar);
2031 }
2032 }
2033
2034 /*fin fichier*/
2035 if(!bin) {
2036 strcpy(&chaine[0],"\n\nEnd\n");
2037 fprintf(inm,"%s",chaine);
2038 } else {
2039 binch = 54; //End
2040 fwrite(&binch,MMG5_SW,1,inm);
2041 bpos += 2*MMG5_SW; //bpos + End key
2042 fwrite(&bpos,MMG5_SW,1,inm);
2043 }
2044 fclose(inm);
2045 return 1;
2046}
2047
2049 int ier=0;
2050 const char *filenameptr,*solnameptr;
2051 char *tmp,*soltmp;
2052
2053 if ( filename && strlen(filename) ) {
2054 filenameptr = filename;
2055 solnameptr = filename;
2056 }
2057 else if (mesh->namein && strlen(mesh->namein) ) {
2058 filenameptr = mesh->namein;
2059 if ( sol && strlen(sol->namein) ) {
2060 solnameptr = sol->namein;
2061 }
2062 else {
2063 solnameptr = mesh->namein;
2064 }
2065 }
2066 else {
2067 fprintf(stderr," ## Error: %s: please provide input file name"
2068 " (either in the mesh structure or as function argument).\n",
2069 __func__);
2070 return 0;
2071 }
2072
2073 MMG5_SAFE_MALLOC(tmp,strlen(filenameptr)+1,char,return 0);
2074 strcpy(tmp,filenameptr);
2075
2076 /* read mesh/sol files */
2077 char *ptr = MMG5_Get_filenameExt(tmp);
2078 int fmt = MMG5_Get_format(ptr,MMG5_FMT_MeditASCII);
2079
2080 int8_t savesolFile = 0;
2081
2082 switch ( fmt ) {
2083 case ( MMG5_FMT_GmshASCII ): case ( MMG5_FMT_GmshBinary ):
2085 break;
2086 case ( MMG5_FMT_VtkVtu ):
2088 break;
2089 case ( MMG5_FMT_VtkVtk ):
2091 break;
2092 case ( MMG5_FMT_Tetgen ):
2094 savesolFile = 1;
2095 break;
2096 default:
2098 savesolFile = 1;
2099 break;
2100 }
2101
2102 if ( ier && savesolFile ) {
2103 /* Medit or tetgen output: save the solution in a .sol file */
2104 if ( sol && sol->np ) {
2105 MMG5_SAFE_MALLOC(soltmp,strlen(solnameptr)+1,char,return 0);
2106 strcpy(soltmp,solnameptr);
2107
2108 if ( MMG3D_saveSol(mesh,sol,soltmp) == -1) {
2109 fprintf(stderr,"\n ## ERROR: WRONG DATA TYPE OR WRONG SOLUTION NUMBER.\n");
2110 ier = 0;
2111 }
2112 MMG5_SAFE_FREE(soltmp);
2113 }
2114 }
2115
2116 return ier;
2117}
2118
2120
2121 return MMG5_saveMshMesh(mesh,&sol,filename,1);
2122}
2123
2125
2127}
2128
2130 FILE *inm;
2131 long posnp;
2132 int iswp,ier,ver,bin,*type,nsols,dim;
2133 MMG5_int k,np;
2134
2136 ier = MMG5_loadSolHeader(filename,3,&inm,&ver,&bin,&iswp,&np,&dim,&nsols,
2137 &type,&posnp,mesh->info.imprim);
2138 if ( ier < 1 ) return ier;
2139
2140 if ( nsols!=1 ) {
2141 fprintf(stderr,"Error: SEVERAL SOLUTIONS FOUND (%d)\n",nsols);
2142 fclose(inm);
2143 MMG5_SAFE_FREE(type);
2144 return -1;
2145 }
2146
2147 if ( mesh->np != np ) {
2148 fprintf(stderr," ** MISMATCHES DATA: THE NUMBER OF VERTICES IN "
2149 "THE MESH (%" MMG5_PRId ") DIFFERS FROM THE NUMBER OF VERTICES IN "
2150 "THE SOLUTION (%" MMG5_PRId ") \n",mesh->np,np);
2151 fclose(inm);
2152 MMG5_SAFE_FREE(type);
2153 return -1;
2154 }
2155
2156 /* #MMG5_loadSolHeader function reads only solution at vertices so we don't
2157 have to check the entites on which the metric applies */
2158 int entities = MMG5_Vertex;
2159 ier = MMG5_chkMetricType(mesh,type,&entities,inm);
2160
2161 if ( ier < 1 ) {
2162 MMG5_SAFE_FREE(type);
2163 return ier;
2164 }
2165
2166 /* Allocate and store the header informations for each solution */
2167 if ( !MMG3D_Set_solSize(mesh,met,MMG5_Vertex,mesh->np,type[0]) ) {
2168 fclose(inm);
2169 MMG5_SAFE_FREE(type);
2170 return -1;
2171 }
2172 /* For binary file, we read the verson inside the file */
2173 if ( ver ) met->ver = ver;
2174
2175 MMG5_SAFE_FREE(type);
2176
2177 /* Read mesh solutions */
2178 rewind(inm);
2179 fseek(inm,posnp,SEEK_SET);
2180
2181 if ( met->ver == 1 ) {
2182 /* Simple precision */
2183 for (k=1; k<=mesh->np; k++) {
2184 if ( MMG5_readFloatSol3D(met,inm,bin,iswp,k) < 0 ) return -1;
2185 }
2186 }
2187 else {
2188 /* Double precision */
2189 for (k=1; k<=mesh->np; k++) {
2190 if ( MMG5_readDoubleSol3D(met,inm,bin,iswp,k) < 0 ) return -1;
2191 }
2192 }
2193
2194 fclose(inm);
2195
2196 /* stats */
2198
2199 return 1;
2200}
2201
2203 MMG5_pSol psl;
2204 FILE *inm;
2205 long posnp;
2206 int iswp,ier,ver,bin,*type,nsols,dim;
2207 MMG5_int j,k,np;
2208 char data[16];
2209 static char mmgWarn = 0;
2210
2212 ier = MMG5_loadSolHeader(filename,3,&inm,&ver,&bin,&iswp,&np,&dim,&nsols,
2213 &type,&posnp,mesh->info.imprim);
2214 if ( ier < 1 ) return ier;
2215
2216 if ( mesh->np != np ) {
2217 fprintf(stderr," ** MISMATCHES DATA: THE NUMBER OF VERTICES IN "
2218 "THE MESH (%" MMG5_PRId ") DIFFERS FROM THE NUMBER OF VERTICES IN "
2219 "THE SOLUTION (%" MMG5_PRId ") \n",mesh->np,np);
2220 fclose(inm);
2221 MMG5_SAFE_FREE(type);
2222 return -1;
2223 }
2224
2226 mesh->nsols = nsols;
2227
2228 if ( nsols > MMG5_NSOLS_MAX ) {
2229 fprintf(stderr,"\n ## Error: %s: unexpected number of data (%d).\n",
2230 __func__,nsols);
2231 MMG5_SAFE_FREE(type);
2232 fclose(inm);
2233 return -1;
2234 }
2235
2236 if ( *sol ) MMG5_DEL_MEM(mesh,*sol);
2237
2238 MMG5_ADD_MEM(mesh,nsols*sizeof(MMG5_Sol),"solutions array",
2239 printf(" Exit program.\n"); fclose(inm);
2240 MMG5_SAFE_FREE(type);
2241 return -1);
2242 MMG5_SAFE_CALLOC(*sol,nsols,MMG5_Sol,return -1);
2243
2244 for ( j=0; j<nsols; ++j ) {
2245 psl = *sol + j;
2246
2247 /* Give an arbitrary name to the solution because the Medit format has non
2248 * name field */
2249 sprintf(data,"sol_%" MMG5_PRId "",j);
2250 if ( !MMG3D_Set_inputSolName(mesh,psl,data) ) {
2251 if ( !mmgWarn ) {
2252 mmgWarn = 1;
2253 fprintf(stderr,"\n ## Warning: %s: unable to set solution name for"
2254 " at least 1 solution.\n",__func__);
2255 }
2256 }
2257
2258 /* Allocate and store the header informations for each solution */
2259 if ( !MMG3D_Set_solSize(mesh,psl,MMG5_Vertex,mesh->np,type[j]) ) {
2260 MMG5_SAFE_FREE(type);
2261 fclose(inm);
2262 return -1;
2263 }
2264
2265 /* For binary file, we read the verson inside the file */
2266 if ( ver ) psl->ver = ver;
2267 }
2268 MMG5_SAFE_FREE(type);
2269
2270 /* read mesh solutions */
2271 rewind(inm);
2272 fseek(inm,posnp,SEEK_SET);
2273
2274 if ( (*sol)[0].ver == 1 ) {
2275 /* Simple precision */
2276 for (k=1; k<=mesh->np; k++) {
2277 for ( j=0; j<nsols; ++j ) {
2278 psl = *sol + j;
2279 if ( MMG5_readFloatSol3D(psl,inm,bin,iswp,k) < 0 ) return -1;
2280 }
2281 }
2282 }
2283 else {
2284 /* Double precision */
2285 for (k=1; k<=mesh->np; k++) {
2286 for ( j=0; j<nsols; ++j ) {
2287 psl = *sol + j;
2288 if ( MMG5_readDoubleSol3D(psl,inm,bin,iswp,k) < 0 ) return -1;
2289 }
2290 }
2291 }
2292 fclose(inm);
2293
2294 /* stats */
2296
2297 return 1;
2298}
2299
2301 FILE* inm;
2302 MMG5_pPoint ppt;
2303 int binch,bin,ier;
2304 MMG5_int k,bpos;
2305
2306 if ( !met->m ) {
2307 fprintf(stderr,"\n ## Warning: %s: no metric data to save.\n",__func__);
2308 return 1;
2309 }
2310
2311 met->ver = 2;
2312
2313 bpos = 0;
2314 ier = MMG5_saveSolHeader( mesh,filename,&inm,met->ver,&bin,&bpos,mesh->np,
2315 met->dim,1,&met->entities,&met->type,&met->size);
2316
2317 if ( ier < 1 ) return ier;
2318
2319 for (k=1; k<=mesh->np; k++) {
2320 ppt = &mesh->point[k];
2321 if ( !MG_VOK(ppt) ) continue;
2322
2323 MMG5_writeDoubleSol3D(mesh,met,inm,bin,k,1);
2324 fprintf(inm,"\n");
2325 }
2326
2327 /* End file */
2328 if(!bin) {
2329 fprintf(inm,"\n\nEnd\n");
2330 } else {
2331 binch = 54; //End
2332 fwrite(&binch,MMG5_SW,1,inm);
2333 }
2334 fclose(inm);
2335 return 1;
2336}
2337
2339 MMG5_pSol psl;
2340 FILE* inm;
2341 MMG5_pPoint ppt;
2342 MMG5_pTetra pt;
2343 int binch,bin,ier,npointSols,ncellSols;
2344 MMG5_int j,k,bpos;
2345 int *type,*entities,*size;
2346
2347 if ( !(*sol)[0].m ) return -1;
2348
2349 (*sol)[0].ver = 2;
2350
2351 MMG5_SAFE_CALLOC(type,mesh->nsols,int,return 0);
2352 MMG5_SAFE_CALLOC(size,mesh->nsols,int,MMG5_SAFE_FREE(type);return 0);
2353 MMG5_SAFE_CALLOC(entities,mesh->nsols,int,
2354 MMG5_SAFE_FREE(type);MMG5_SAFE_FREE(size);return 0);
2355
2356 npointSols = 0;
2357 ncellSols = 0;
2358 for (k=0; k<mesh->nsols; ++k ) {
2359 if ( ((*sol)[k].entities==MMG5_Noentity) || ((*sol)[k].entities==MMG5_Vertex) ) {
2360 ++npointSols;
2361 }
2362 else if ( (*sol)[k].entities == MMG5_Tetrahedron ) {
2363 ++ncellSols;
2364 }
2365 else {
2366 printf("\n ## Warning: %s: unexpected entity type for solution %" MMG5_PRId ": %s."
2367 "\n Ignored.\n",
2368 __func__,k,MMG5_Get_entitiesName((*sol)[k].entities));
2369 }
2370 type[k] = (*sol)[k].type;
2371 size[k] = (*sol)[k].size;
2372 entities[k] = (*sol)[k].entities;
2373 }
2374
2375 bpos = 0;
2376 ier = MMG5_saveSolHeader( mesh,filename,&inm,(*sol)[0].ver,&bin,&bpos,mesh->np,
2377 (*sol)[0].dim,mesh->nsols,entities,type,size);
2378
2379 if ( ier < 1 ) return ier;
2380
2381 for (k=1; k<=mesh->np; k++) {
2382 ppt = &mesh->point[k];
2383 if ( !MG_VOK(ppt) ) continue;
2384
2385 for ( j=0; j<mesh->nsols; ++j ) {
2386 psl = *sol+j;
2387
2388 if ( (psl->entities==MMG5_Noentity) || (psl->entities==MMG5_Vertex) ) {
2389 MMG5_writeDoubleSol3D(mesh,psl,inm,bin,k,0);
2390 }
2391 }
2392 fprintf(inm,"\n");
2393 }
2394
2395 MMG5_saveSolAtTetrahedraHeader( mesh,inm,(*sol)[0].ver,bin,&bpos,mesh->nsols,
2396 ncellSols,entities,type,size );
2397
2398 for (k=1; k<=mesh->ne; k++) {
2399 pt = &mesh->tetra[k];
2400 if ( !MG_EOK(pt) ) continue;
2401
2402 for ( j=0; j<mesh->nsols; ++j ) {
2403 psl = *sol+j;
2404 if ( psl->entities==MMG5_Tetrahedron ) {
2405 MMG5_writeDoubleSol3D(mesh,psl,inm,bin,k,0);
2406 }
2407 }
2408 fprintf(inm,"\n");
2409 }
2410
2411
2412 MMG5_SAFE_FREE(type);
2413 MMG5_SAFE_FREE(size);
2414 MMG5_SAFE_FREE(entities);
2415
2416 /* End file */
2417 if(!bin) {
2418 fprintf(inm,"\n\nEnd\n");
2419 } else {
2420 binch = 54; //End
2421 fwrite(&binch,MMG5_SW,1,inm);
2422 }
2423 fclose(inm);
2424 return 1;
2425}
2426
2427static inline
2429 FILE* inm;
2430 MMG5_pTetra pt;
2431 MMG5_int k,i,ne;
2432 char *ptr,*data;
2433
2434 if ( !mesh->ne ) {
2435 return 1;
2436 }
2437
2438 if ( (!filename) || !(*filename) ) {
2440 }
2441 if ( (!filename) || !(*filename) ) {
2442 printf("\n ## Error: %s: unable to save a file without a valid filename\n.",
2443 __func__);
2444 return 0;
2445 }
2446
2447 /* Name of file */
2448 MMG5_SAFE_CALLOC(data,strlen(filename)+5,char,return 0);
2449 strcpy(data,filename);
2450 ptr = strstr(data,".node");
2451 if ( ptr ) {
2452 *ptr = '\0';
2453 }
2454
2455 /* Add .node ext */
2456 strcat(data,".ele");
2457 if( !(inm = fopen(data,"wb")) ) {
2458 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data);
2459 MMG5_SAFE_FREE(data);
2460 return 0;
2461 }
2462
2463 fprintf(stdout," %%%% %s OPENED\n",data);
2464 MMG5_SAFE_FREE(data);
2465
2466 ne = 0;
2467 for (k=1; k<=mesh->ne; k++) {
2468 pt = &mesh->tetra[k];
2469 if ( !MG_EOK(pt) ) continue;
2470 ne++;
2471 }
2472
2473 /* Save elt number, node number per elt, 1 bdy marker */
2474 fprintf(inm, "%" MMG5_PRId " %d %d\n\n",ne,mesh->dim+1,1);
2475
2476 ne = 0;
2477 for ( k=1; k<=mesh->ne; ++k ) {
2478 pt = &mesh->tetra[k];
2479 if ( MG_EOK(pt) ) {
2480 /* Save elt idx */
2481 fprintf(inm, "%" MMG5_PRId " ",++ne);
2482
2483 /* Save connectivity */
2484 for ( i=0; i<=mesh->dim; ++i ) {
2485 fprintf(inm, "%" MMG5_PRId " ",mesh->point[pt->v[i]].tmp);
2486 }
2487
2488 /* Save bdy marker */
2489 fprintf(inm, "%" MMG5_PRId "\n",pt->ref);
2490 }
2491 }
2492 fprintf(stdout," NUMBER OF ELEMENT %8" MMG5_PRId "\n",ne);
2493
2494 fclose(inm);
2495
2496 return 1;
2497}
2498
2499static inline
2501 FILE* inm;
2502 MMG5_pTetra pt;
2503 MMG5_int k,i,ne;
2504 MMG5_int idx;
2505 char *ptr,*data;
2506
2507 if ( !mesh->na ) {
2508 return 1;
2509 }
2510
2511 if ( (!filename) || !(*filename) ) {
2513 }
2514 if ( (!filename) || !(*filename) ) {
2515 printf("\n ## Error: %s: unable to save a file without a valid filename\n.",
2516 __func__);
2517 return 0;
2518 }
2519
2520 /* Name of file */
2521 MMG5_SAFE_CALLOC(data,strlen(filename)+7,char,return 0);
2522 strcpy(data,filename);
2523 ptr = strstr(data,".node");
2524 if ( ptr ) {
2525 *ptr = '\0';
2526 }
2527
2528 /* Add .node ext */
2529 strcat(data,".neigh");
2530 if( !(inm = fopen(data,"wb")) ) {
2531 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data);
2532 MMG5_SAFE_FREE(data);
2533 return 0;
2534 }
2535
2536 fprintf(stdout," %%%% %s OPENED\n",data);
2537 MMG5_SAFE_FREE(data);
2538
2539 if ( ! mesh->adja ) {
2540 if ( !MMG3D_hashTetra(mesh,1) ) {
2541 printf("\n ## Error: %s: unable to compute triangle adjacencies\n.",__func__);
2542 return 0;
2543 }
2544 }
2545
2546 ne = 0;
2547 for (k=1; k<=mesh->ne; k++) {
2548 pt = &mesh->tetra[k];
2549 if ( !MG_EOK(pt) ) continue;
2550 ne++;
2551 }
2552
2553 /* Save elt number, number of neighbors per elt */
2554 fprintf(inm, "%" MMG5_PRId " %d\n\n",ne,mesh->dim+1);
2555
2556 ne = 0;
2557 for ( k=1; k<=mesh->ne; ++k ) {
2558 pt = &mesh->tetra[k];
2559 if ( MG_EOK(pt) ) {
2560 /* Save elt idx */
2561 fprintf(inm, "%" MMG5_PRId " ",++ne);
2562
2563 /* Save neighbors */
2564 for ( i=1; i<=mesh->dim+1; ++i ) {
2565 /* The triangle conventions is that no neighbors <=> -1 */
2566 idx = ( mesh->adja[4*(k-1)+i] > 0 ) ? mesh->adja[4*(k-1)+i]/4 : -1;
2567 fprintf(inm, "%"MMG5_PRId" ",idx);
2568 }
2569 /* Save bdy marker */
2570 fprintf(inm, "\n");
2571 }
2572 }
2573
2574 fclose(inm);
2575
2576 return 1;
2577}
2578
2579static inline
2581 FILE* inm;
2582 MMG5_pTria pt;
2583 MMG5_int k,i;
2584 char *ptr,*data;
2585
2586 if ( !mesh->nt ) {
2587 return 1;
2588 }
2589
2590 if ( (!filename) || !(*filename) ) {
2592 }
2593 if ( (!filename) || !(*filename) ) {
2594 printf("\n ## Error: %s: unable to save a file without a valid filename\n.",
2595 __func__);
2596 return 0;
2597 }
2598
2599 /* Name of file */
2600 MMG5_SAFE_CALLOC(data,strlen(filename)+6,char,return 0);
2601 strcpy(data,filename);
2602 ptr = strstr(data,".node");
2603 if ( ptr ) {
2604 *ptr = '\0';
2605 }
2606
2607 /* Add .node ext */
2608 strcat(data,".face");
2609 if( !(inm = fopen(data,"wb")) ) {
2610 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data);
2611 MMG5_SAFE_FREE(data);
2612 return 0;
2613 }
2614
2615 fprintf(stdout," %%%% %s OPENED\n",data);
2616 MMG5_SAFE_FREE(data);
2617
2618 /* Save tria number, 1 bdy marker */
2619 fprintf(inm, "%" MMG5_PRId " %d\n\n",mesh->nt,1);
2620
2621 for ( k=1; k<=mesh->nt; ++k ) {
2622 pt = &mesh->tria[k];
2623 if ( MG_EOK(pt) ) {
2624 /* Save elt idx */
2625 fprintf(inm, "%" MMG5_PRId " ",k);
2626
2627 /* Save connectivity */
2628 for ( i=0; i<mesh->dim; ++i ) {
2629 fprintf(inm, "%" MMG5_PRId " ",mesh->point[pt->v[i]].tmp);
2630 }
2631
2632 /* Save bdy marker */
2633 fprintf(inm, "%" MMG5_PRId "\n",pt->ref);
2634 }
2635 }
2636 fprintf(stdout," NUMBER OF TRIANGLES %8" MMG5_PRId "\n",mesh->nt);
2637
2638 fclose(inm);
2639
2640 return 1;
2641}
2642
2643
2645
2646 if ( !MMG5_saveNode(mesh,filename) ) {
2647 return 0;
2648 }
2649
2650 if ( !MMG3D_saveEle(mesh,filename) ) {
2651 return 0;
2652 }
2653
2654 if ( !MMG3D_saveFace(mesh,filename) ) {
2655 return 0;
2656 }
2657
2658 if ( !MMG5_saveEdge(mesh,filename,".edge") ) {
2659 return 0;
2660 }
2661
2662 if ( !MMG3D_saveNeigh(mesh,filename) ) {
2663 return 0;
2664 }
2665
2666 return 1;
2667}
const char * MMG5_Get_formatName(enum MMG5_Format fmt)
const char * MMG5_Get_entitiesName(enum MMG5_entities ent)
int MMG5_Get_format(char *ptr, int fmt)
char * MMG5_Get_filenameExt(char *filename)
int MMG3D_Set_inputSolName(MMG5_pMesh mesh, MMG5_pSol sol, const char *solin)
int MMG3D_Set_solSize(MMG5_pMesh mesh, MMG5_pSol sol, int typEntity, MMG5_int np, int typSol)
int ier
tmp[*strlen0]
MMG5_pMesh MMG5_pSol * sol
MMG5_pMesh * mesh
MMG5_pMesh char * filename
int MMG3D_hashTetra(MMG5_pMesh mesh, int pack)
Definition: hash_3d.c:122
int MMG5_readDoubleSol3D(MMG5_pSol sol, FILE *inm, int bin, int iswp, MMG5_int pos)
Definition: inout.c:2269
int MMG5_chkMetricType(MMG5_pMesh mesh, int *type, int *entities, FILE *inm)
Definition: inout.c:2661
void MMG5_printSolStats(MMG5_pMesh mesh, MMG5_pSol *sol)
Definition: inout.c:2723
float MMG5_swapf(float sbin)
Definition: inout.c:80
int MMG5_saveNode(MMG5_pMesh mesh, const char *filename)
Definition: inout.c:2741
int MMG5_saveEdge(MMG5_pMesh mesh, const char *filename, const char *ext)
Definition: inout.c:2816
int MMG5_saveSolHeader(MMG5_pMesh mesh, const char *filename, FILE **inm, int ver, int *bin, MMG5_int *bpos, MMG5_int np, int dim, int nsols, int *entities, int *type, int *size)
Definition: inout.c:2387
int MMG5_loadMshMesh_part1(MMG5_pMesh mesh, const char *filename, FILE **inm, long *posNodes, long *posElts, long **posNodeData, int *bin, int *iswp, MMG5_int *nelts, int *nsols)
Definition: inout.c:278
void MMG5_writeDoubleSol3D(MMG5_pMesh mesh, MMG5_pSol sol, FILE *inm, int bin, MMG5_int pos, int metricData)
Definition: inout.c:2318
int MMG5_saveSolAtTetrahedraHeader(MMG5_pMesh mesh, FILE *inm, int ver, int bin, MMG5_int *bpos, int nsols, int nsolsAtTetra, int *entities, int *type, int *size)
Definition: inout.c:2593
int MMG5_readFloatSol3D(MMG5_pSol sol, FILE *inm, int bin, int iswp, int pos)
Definition: inout.c:2220
double MMG5_swapd(double sbin)
Definition: inout.c:97
int MMG5_loadMshMesh_part2(MMG5_pMesh mesh, MMG5_pSol *sol, FILE **inm, const long posNodes, const long posElts, const long *posNodeData, const int bin, const int iswp, const MMG5_int nelts, const int nsols)
Definition: inout.c:668
int MMG5_saveMshMesh(MMG5_pMesh mesh, MMG5_pSol *sol, const char *filename, int metricData)
Definition: inout.c:1587
void MMG5_printMetStats(MMG5_pMesh mesh, MMG5_pSol met)
Definition: inout.c:2705
int MMG5_loadSolHeader(const char *filename, int meshDim, FILE **inm, int *ver, int *bin, int *iswp, MMG5_int *np, int *dim, int *nsols, int **type, long *posnp, int imprim)
Definition: inout.c:2080
int MMG5_swapbin(int sbin)
Definition: inout.c:42
int MMG3D_saveMshMesh_and_allData(MMG5_pMesh mesh, MMG5_pSol *sol, const char *filename)
Definition: inout_3d.c:2124
int MMG3D_openMesh(int imprim, const char *filename, FILE **inm, int *bin, char *modeASCII, char *modeBIN)
Definition: inout_3d.c:53
int MMG3D_saveMesh(MMG5_pMesh mesh, const char *filename)
Definition: inout_3d.c:1259
int MMG3D_loadGenericMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
Definition: inout_3d.c:1176
int MMG3D_saveGenericMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
Definition: inout_3d.c:2048
int MMG3D_loadSol(MMG5_pMesh mesh, MMG5_pSol met, const char *filename)
Definition: inout_3d.c:2129
int MMG3D_loadMesh(MMG5_pMesh mesh, const char *filename)
Definition: inout_3d.c:1044
int MMG3D_loadAllSols(MMG5_pMesh mesh, MMG5_pSol *sol, const char *filename)
Definition: inout_3d.c:2202
int MMG3D_loadMshMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
Definition: inout_3d.c:1058
int MMG3D_saveTetgenMesh(MMG5_pMesh mesh, const char *filename)
Definition: inout_3d.c:2644
static int MMG3D_saveEle(MMG5_pMesh mesh, const char *filename)
Definition: inout_3d.c:2428
static int MMG3D_saveNeigh(MMG5_pMesh mesh, const char *filename)
Definition: inout_3d.c:2500
int MMG3D_loadMshMesh_and_allData(MMG5_pMesh mesh, MMG5_pSol *sol, const char *filename)
Definition: inout_3d.c:1118
static int MMG3D_saveFace(MMG5_pMesh mesh, const char *filename)
Definition: inout_3d.c:2580
int MMG3D_saveSol(MMG5_pMesh mesh, MMG5_pSol met, const char *filename)
Definition: inout_3d.c:2300
int MMG3D_saveMshMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
Definition: inout_3d.c:2119
int MMG3D_loadMesh_opened(MMG5_pMesh mesh, FILE *inm, int bin)
Definition: inout_3d.c:113
int MMG3D_saveAllSols(MMG5_pMesh mesh, MMG5_pSol *sol, const char *filename)
Definition: inout_3d.c:2338
int MMG3D_loadVtkMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
int MMG3D_loadVtuMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
Definition: inoutcpp_3d.cpp:73
int MMG3D_saveVtkMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
int MMG3D_saveVtuMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
API headers for the mmg3d library.
int MMG3D_zaldy(MMG5_pMesh mesh)
Definition: zaldy_3d.c:346
@ MMG5_FMT_MeditBinary
Definition: libmmgtypes.h:236
@ MMG5_FMT_Tetgen
Definition: libmmgtypes.h:244
@ MMG5_FMT_VtkVtk
Definition: libmmgtypes.h:243
@ MMG5_FMT_GmshBinary
Definition: libmmgtypes.h:238
@ MMG5_FMT_GmshASCII
Definition: libmmgtypes.h:237
@ MMG5_FMT_MeditASCII
Definition: libmmgtypes.h:235
@ MMG5_FMT_VtkVtu
Definition: libmmgtypes.h:241
#define MMG5_NSOLS_MAX
Definition: libmmgtypes.h:181
@ MMG5_Noentity
Definition: libmmgtypes.h:223
@ MMG5_Vertex
Definition: libmmgtypes.h:224
@ MMG5_Tetrahedron
Definition: libmmgtypes.h:227
#define MG_REQ
#define MG_GEO
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
#define MG_EOK(pt)
#define MG_NUL
#define MG_PARBDY
#define MMG5_SD
#define MMG5_ADD_MEM(mesh, size, message, law)
#define MG_EDG_OR_NOM(tag)
#define MG_SIN(tag)
#define MMG_FREAD(ptr, size, count, stream)
#define MMG5_SW
#define MG_VOK(ppt)
#define MG_CRN
double MMG5_orvol(MMG5_pPoint point, MMG5_int *v)
Definition: tools.c:951
#define MG_BDY
#define MMG5_SAFE_MALLOC(ptr, size, type, law)
#define MG_NOM
#define MMG5_FILESTR_LGTH
#define MMG5_EPSD2
#define MG_REF
#define MMG5_SAFE_FREE(ptr)
#define MMG_FSCANF(stream, format,...)
#define MMG5_DEL_MEM(mesh, ptr)
Structure to store edges of a MMG mesh.
Definition: libmmgtypes.h:305
MMG5_int b
Definition: libmmgtypes.h:306
MMG5_int ref
Definition: libmmgtypes.h:307
int16_t tag
Definition: libmmgtypes.h:310
MMG5_int a
Definition: libmmgtypes.h:306
int8_t iso
Definition: libmmgtypes.h:534
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_int ntmax
Definition: libmmgtypes.h:612
MMG5_pQuad quadra
Definition: libmmgtypes.h:648
MMG5_int nc1
Definition: libmmgtypes.h:615
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_int xt
Definition: libmmgtypes.h:620
MMG5_int ne
Definition: libmmgtypes.h:612
MMG5_pPoint point
Definition: libmmgtypes.h:641
char * nameout
Definition: libmmgtypes.h:653
MMG5_int * adja
Definition: libmmgtypes.h:624
MMG5_pPrism prism
Definition: libmmgtypes.h:645
MMG5_int nquad
Definition: libmmgtypes.h:613
MMG5_int nemax
Definition: libmmgtypes.h:612
MMG5_int npmax
Definition: libmmgtypes.h:612
MMG5_pxPoint xpoint
Definition: libmmgtypes.h:642
MMG5_int xp
Definition: libmmgtypes.h:620
MMG5_int nei
Definition: libmmgtypes.h:612
MMG5_pTetra tetra
Definition: libmmgtypes.h:643
MMG5_int nt
Definition: libmmgtypes.h:612
MMG5_pTria tria
Definition: libmmgtypes.h:647
MMG5_int np
Definition: libmmgtypes.h:612
MMG5_pEdge edge
Definition: libmmgtypes.h:649
MMG5_int nti
Definition: libmmgtypes.h:612
MMG5_int npi
Definition: libmmgtypes.h:612
MMG5_int nai
Definition: libmmgtypes.h:612
MMG5_int nprism
Definition: libmmgtypes.h:613
MMG5_int na
Definition: libmmgtypes.h:612
char * namein
Definition: libmmgtypes.h:652
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
double n[3]
Definition: libmmgtypes.h:272
int16_t tag
Definition: libmmgtypes.h:284
MMG5_int tmp
Definition: libmmgtypes.h:280
double c[3]
Definition: libmmgtypes.h:271
MMG5_int xp
Definition: libmmgtypes.h:279
MMG5_int ref
Definition: libmmgtypes.h:278
MMG5_int flag
Definition: libmmgtypes.h:282
MMG5_int v[6]
Definition: libmmgtypes.h:463
MMG5_int ref
Definition: libmmgtypes.h:464
MMG5_int ref
Definition: libmmgtypes.h:368
int16_t tag[4]
Definition: libmmgtypes.h:372
MMG5_int v[4]
Definition: libmmgtypes.h:367
int entities
Definition: libmmgtypes.h:670
double * m
Definition: libmmgtypes.h:671
MMG5_int v[4]
Definition: libmmgtypes.h:403
MMG5_int ref
Definition: libmmgtypes.h:404
int16_t tag
Definition: libmmgtypes.h:410
int16_t tag[3]
Definition: libmmgtypes.h:342
MMG5_int ref
Definition: libmmgtypes.h:335
MMG5_int v[3]
Definition: libmmgtypes.h:334
Structure to store surface points of a MMG mesh.
Definition: libmmgtypes.h:294
double n1[3]
Definition: libmmgtypes.h:295