1 /*----------------------------------------------------------*/
5 /*----------------------------------------------------------*/
7 /* Description: handle .meshb file format I/O */
8 /* Author: Loic MARECHAL */
9 /* Creation date: feb 16 2007 */
10 /* Last modification: apr 03 2012 */
12 /*----------------------------------------------------------*/
15 /*----------------------------------------------------------*/
17 /*----------------------------------------------------------*/
26 #include "libmesh5.hxx"
31 using namespace MeshFormat;
35 /*----------------------------------------------------------*/
36 /* Global variables */
37 /*----------------------------------------------------------*/
39 // see MeshGems/Docs/meshgems_formats_description.pdf
40 const char *GmfKwdFmt[ GmfMaxKwd + 1 ][4] =
41 { {"Reserved", "", "", ""},
42 {"MeshVersionFormatted", "", "", "i"},
43 {"Reserved", "", "", ""},
44 {"Dimension", "", "", "i"},
45 {"Vertices", "Vertex", "i", "dri"},
46 {"Edges", "Edge", "i", "iii"},
47 {"Triangles", "Triangle", "i", "iiii"},
48 {"Quadrilaterals", "Quadrilateral", "i", "iiiii"},
49 {"Tetrahedra", "Tetrahedron", "i", "iiiii"},
50 {"Prisms", "Prism", "i", "iiiiiii"},
51 {"Hexahedra", "Hexahedron", "i", "iiiiiiiii"},
52 {"IterationsAll", "IterationAll","","i"},
53 {"TimesAll", "TimeAll","","r"},
54 {"Corners", "Corner", "i", "i"},
55 {"Ridges", "Ridge", "i", "i"},
56 {"RequiredVertices", "RequiredVertex", "i", "i"},
57 {"RequiredEdges", "RequiredEdge", "i", "i"},
58 {"RequiredTriangles", "RequiredTriangle", "i", "i"},
59 {"RequiredQuadrilaterals", "RequiredQuadrilateral", "i", "i"},
60 {"TangentAtEdgeVertices", "TangentAtEdgeVertex", "i", "iii"},
61 {"NormalAtVertices", "NormalAtVertex", "i", "ii"},
62 {"NormalAtTriangleVertices", "NormalAtTriangleVertex", "i", "iii"},
63 {"NormalAtQuadrilateralVertices", "NormalAtQuadrilateralVertex", "i", "iiii"},
64 {"AngleOfCornerBound", "", "", "r"},
65 {"TrianglesP2", "TriangleP2", "i", "iiiiiii"},
66 {"EdgesP2", "EdgeP2", "i", "iiii"},
67 {"SolAtPyramids", "SolAtPyramid", "i", "sr"},
68 {"QuadrilateralsQ2", "QuadrilateralQ2", "i", "iiiiiiiiii"},
69 {"ISolAtPyramids", "ISolAtPyramid", "i", "iiiii"},
70 {"SubDomainFromGeom", "SubDomainFromGeom", "i", "iiii"},
71 {"TetrahedraP2", "TetrahedronP2", "i", "iiiiiiiiiii"},
72 {"Fault_NearTri", "Fault_NearTri", "i", "i"},
73 {"Fault_Inter", "Fault_Inter", "i", "i"},
74 {"HexahedraQ2", "HexahedronQ2", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiii"},
75 {"ExtraVerticesAtEdges", "ExtraVerticesAtEdge", "i", "in"},
76 {"ExtraVerticesAtTriangles", "ExtraVerticesAtTriangle", "i", "in"},
77 {"ExtraVerticesAtQuadrilaterals", "ExtraVerticesAtQuadrilateral", "i", "in"},
78 {"ExtraVerticesAtTetrahedra", "ExtraVerticesAtTetrahedron", "i", "in"},
79 {"ExtraVerticesAtPrisms", "ExtraVerticesAtPrism", "i", "in"},
80 {"ExtraVerticesAtHexahedra", "ExtraVerticesAtHexahedron", "i", "in"},
81 {"VerticesOnGeometricVertices", "VertexOnGeometricVertex", "i", "iir"},
82 {"VerticesOnGeometricEdges", "VertexOnGeometricEdge", "i", "iirr"},
83 {"VerticesOnGeometricTriangles", "VertexOnGeometricTriangle", "i", "iirrr"},
84 {"VerticesOnGeometricQuadrilaterals", "VertexOnGeometricQuadrilateral", "i", "iirrr"},
85 {"EdgesOnGeometricEdges", "EdgeOnGeometricEdge", "i", "iir"},
86 {"Fault_FreeEdge", "Fault_FreeEdge", "i", "i"},
87 {"Polyhedra", "Polyhedron", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
88 {"Polygons", "Polygon", "", "iiiiiiiii"},
89 {"Fault_Overlap", "Fault_Overlap", "i", "i"},
90 {"Pyramids", "Pyramid", "i", "iiiiii"},
91 {"BoundingBox", "", "", "drdr"},
92 {"Body","i", "drdrdrdr"},
93 {"PrivateTable", "PrivateTable", "i", "i"},
94 {"Fault_BadShape", "Fault_BadShape", "i", "i"},
96 {"TrianglesOnGeometricTriangles", "TriangleOnGeometricTriangle", "i", "iir"},
97 {"TrianglesOnGeometricQuadrilaterals", "TriangleOnGeometricQuadrilateral", "i", "iir"},
98 {"QuadrilateralsOnGeometricTriangles", "QuadrilateralOnGeometricTriangle", "i", "iir"},
99 {"QuadrilateralsOnGeometricQuadrilaterals", "QuadrilateralOnGeometricQuadrilateral", "i", "iir"},
100 {"Tangents", "Tangent", "i", "dr"},
101 {"Normals", "Normal", "i", "dr"},
102 {"TangentAtVertices", "TangentAtVertex", "i", "ii"},
103 {"SolAtVertices", "SolAtVertex", "i", "sr"},
104 {"SolAtEdges", "SolAtEdge", "i", "sr"},
105 {"SolAtTriangles", "SolAtTriangle", "i", "sr"},
106 {"SolAtQuadrilaterals", "SolAtQuadrilateral", "i", "sr"},
107 {"SolAtTetrahedra", "SolAtTetrahedron", "i", "sr"},
108 {"SolAtPrisms", "SolAtPrism", "i", "sr"},
109 {"SolAtHexahedra", "SolAtHexahedron", "i", "sr"},
110 {"DSolAtVertices", "DSolAtVertex", "i", "sr"},
111 {"ISolAtVertices", "ISolAtVertex", "i", "i"},
112 {"ISolAtEdges", "ISolAtEdge", "i", "ii"},
113 {"ISolAtTriangles", "ISolAtTriangle", "i", "iii"},
114 {"ISolAtQuadrilaterals", "ISolAtQuadrilateral", "i", "iiii"},
115 {"ISolAtTetrahedra", "ISolAtTetrahedron", "i", "iiii"},
116 {"ISolAtPrisms", "ISolAtPrism", "i", "iiiiii"},
117 {"ISolAtHexahedra", "ISolAtHexahedron", "i", "iiiiiiii"},
118 {"Iterations", "","","i"},
120 {"Fault_SmallTri", "Fault_SmallTri","i","i"},
121 {"CoarseHexahedra", "CoarseHexahedron", "i", "i"},
122 {"Fault_MultipleEdge", "Fault_MultipleEdge", "i", "i"}
127 MeshFormatParser::MeshFormatParser():GmfIniFlg(0)
132 /*----------------------------------------------------------*/
133 /* Open a mesh file in read or write mod */
134 /*----------------------------------------------------------*/
136 int MeshFormatParser::GmfOpenMesh(const char *FilNam, int mod, ...)
138 int i, KwdCod, res, *PtrVer, *PtrDim, MshIdx=0;
139 char str[ GmfStrSiz ];
144 #if defined(WIN32) && defined(UNICODE)
145 wchar_t* encoded = 0;
150 for(i=0; i<=MaxMsh; i++)
151 //~GmfMshTab[i] = NULL;
152 GmfMshTab[i] = nullptr;
157 /*---------------------*/
158 /* MESH STRUCTURE INIT */
159 /*---------------------*/
161 for(i=1; i<=MaxMsh; i++)
169 if( !MshIdx || !(msh = new GmfMshSct() ) )
172 /* Copy the FilNam into the structure */
174 if(strlen(FilNam) + 7 >= GmfStrSiz)
181 strcpy(msh->FilNam, FilNam);
183 /* Store the opening mod (read or write) and guess the filetype (binary or ascii) depending on the extension */
186 msh->buf = (unsigned char *)msh->DblBuf;
187 msh->FltBuf = (float *)msh->DblBuf;
188 msh->IntBuf = (int *)msh->DblBuf;
190 k = static_cast<int>(strlen(msh->FilNam)) - 6;
194 if(strstr(ptr, ".meshb"))
195 msh->typ |= (Bin | MshFil);
196 else if(strstr(ptr, ".mesh"))
197 msh->typ |= (Asc | MshFil);
198 else if(strstr(ptr, ".solb"))
199 msh->typ |= (Bin | SolFil);
200 else if(strstr(ptr, ".sol"))
201 msh->typ |= (Asc | SolFil);
208 /* Open the file in the required mod and initialise the mesh structure */
210 if(msh->mod == GmfRead)
213 /*-----------------------*/
214 /* OPEN FILE FOR READING */
215 /*-----------------------*/
217 va_start(VarArg, mod);
218 PtrVer = va_arg(VarArg, int *);
219 PtrDim = va_arg(VarArg, int *);
222 /* Create the name string and open the file */
223 #if defined(WIN32) && defined(UNICODE)
224 size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
225 //~encoded = malloc((size_needed + 1)*sizeof(wchar_t));
226 encoded = new wchar_t[size_needed + 1] ;
227 MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
228 encoded[size_needed] = '\0';
229 if (!(msh->hdl = _wfopen(encoded, L"rb")))
231 if (!(msh->hdl = fopen(msh->FilNam, "rb")))
236 #if defined(WIN32) && defined(UNICODE)
243 #if defined(WIN32) && defined(UNICODE)
248 /* Read the endian coding tag, the mesh version and the mesh dimension (mandatory kwd) */
252 fread((unsigned char *)&msh->cod, WrdSiz, 1, msh->hdl);
254 if( (msh->cod != 1) && (msh->cod != 16777216) )
261 ScaWrd(msh, (unsigned char *)&msh->ver);
263 if( (msh->ver < 1) || (msh->ver > 3) )
270 if( (msh->ver == 3) && (sizeof(long) == 4) )
277 ScaWrd(msh, (unsigned char *)&KwdCod);
279 if(KwdCod != GmfDimension)
287 ScaWrd(msh, (unsigned char *)&msh->dim);
293 res = fscanf(msh->hdl, "%s", str);
294 } while( (res != EOF) && strcmp(str, "MeshVersionFormatted") );
303 fscanf(msh->hdl, "%d", &msh->ver);
305 if( (msh->ver < 1) || (msh->ver > 3) )
314 res = fscanf(msh->hdl, "%s", str);
315 } while( (res != EOF) && strcmp(str, "Dimension") );
324 fscanf(msh->hdl, "%d", &msh->dim);
327 if( (msh->dim != 2) && (msh->dim != 3) )
334 (*PtrVer) = msh->ver;
335 (*PtrDim) = msh->dim;
341 /* Read the list of kw present in the file */
350 GmfMshTab[ MshIdx ] = msh;
354 else if(msh->mod == GmfWrite)
357 /*-----------------------*/
358 /* OPEN FILE FOR WRITING */
359 /*-----------------------*/
363 /* Check if the user provided a valid version number and dimension */
365 va_start(VarArg, mod);
366 msh->ver = va_arg(VarArg, int);
367 msh->dim = va_arg(VarArg, int);
370 if( (msh->ver < 1) || (msh->ver > 3) )
377 if( (msh->ver == 3) && (sizeof(long) == 4) )
384 if( (msh->dim != 2) && (msh->dim != 3) )
391 /* Create the mesh file */
392 #if defined(WIN32) && defined(UNICODE)
393 size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
395 encoded = new wchar_t[size_needed + 1];
396 MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
397 encoded[size_needed] = '\0';
398 if (!(msh->hdl = _wfopen(encoded, L"wb")))
400 if(!(msh->hdl = fopen(msh->FilNam, "wb")))
405 #if defined(WIN32) && defined(UNICODE)
412 #if defined(WIN32) && defined(UNICODE)
416 GmfMshTab[ MshIdx ] = msh;
423 /* Write the mesh version and dimension */
427 fprintf(msh->hdl, "%s %d\n\n", GmfKwdFmt[ GmfVersionFormatted ][0], msh->ver);
428 fprintf(msh->hdl, "%s %d\n", GmfKwdFmt[ GmfDimension ][0], msh->dim);
432 RecWrd(msh, (unsigned char *)&msh->cod);
433 RecWrd(msh, (unsigned char *)&msh->ver);
434 GmfSetKwd(MshIdx, GmfDimension, 0);
435 RecWrd(msh, (unsigned char *)&msh->dim);
449 /*----------------------------------------------------------*/
450 /* Close a meshfile in the right way */
451 /*----------------------------------------------------------*/
453 int MeshFormatParser::GmfCloseMesh(int MshIdx)
458 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
461 msh = GmfMshTab[ MshIdx ];
462 RecBlk(msh, msh->buf, 0);
464 /* In write down the "End" kw in write mode */
466 if(msh->mod == GmfWrite) {
468 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ GmfEnd ][0]);
470 GmfSetKwd(MshIdx, GmfEnd, 0);
472 /* Close the file and free the mesh structure */
480 GmfMshTab[ MshIdx ] = nullptr;
486 /*----------------------------------------------------------*/
487 /* Read the number of lines and set the position to this kwd*/
488 /*----------------------------------------------------------*/
490 int MeshFormatParser::GmfStatKwd(int MshIdx, int KwdCod, ...)
492 int i, *PtrNmbTyp, *PtrSolSiz, *TypTab;
497 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
500 msh = GmfMshTab[ MshIdx ];
502 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
505 kwd = &msh->KwdTab[ KwdCod ];
510 /* Read further arguments if this kw is a sol */
512 if(kwd->typ == SolKwd)
514 va_start(VarArg, KwdCod);
516 PtrNmbTyp = va_arg(VarArg, int *);
517 *PtrNmbTyp = kwd->NmbTyp;
519 PtrSolSiz = va_arg(VarArg, int *);
520 *PtrSolSiz = kwd->SolSiz;
522 TypTab = va_arg(VarArg, int *);
524 for(i=0; i<kwd->NmbTyp; i++)
525 TypTab[i] = kwd->TypTab[i];
534 /*----------------------------------------------------------*/
535 /* Set the current file position to a given kwd */
536 /*----------------------------------------------------------*/
538 int MeshFormatParser::GmfGotoKwd(int MshIdx, int KwdCod)
543 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
546 msh = GmfMshTab[ MshIdx ];
548 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
551 kwd = &msh->KwdTab[ KwdCod ];
556 return(fseek(msh->hdl, kwd->pos, SEEK_SET));
560 /*----------------------------------------------------------*/
561 /* Write the kwd and set the number of lines */
562 /*----------------------------------------------------------*/
564 int MeshFormatParser::GmfSetKwd(int MshIdx, int KwdCod, ...)
566 int i, NmbLin=0, *TypTab;
572 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
575 msh = GmfMshTab[ MshIdx ];
576 RecBlk(msh, msh->buf, 0);
578 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
581 kwd = &msh->KwdTab[ KwdCod ];
583 /* Read further arguments if this kw has a header */
585 if(strlen(GmfKwdFmt[ KwdCod ][2]))
587 va_start(VarArg, KwdCod);
588 NmbLin = va_arg(VarArg, int);
590 if(!strcmp(GmfKwdFmt[ KwdCod ][3], "sr"))
592 kwd->NmbTyp = va_arg(VarArg, int);
593 TypTab = va_arg(VarArg, int *);
595 for(i=0; i<kwd->NmbTyp; i++)
596 kwd->TypTab[i] = TypTab[i];
602 /* Setup the kwd info */
608 else if(kwd->typ == InfKwd)
611 kwd->NmbLin = NmbLin;
613 /* Store the next kwd position in binary file */
615 if( (msh->typ & Bin) && msh->NexKwdPos )
617 CurPos = ftell(msh->hdl);
618 fseek(msh->hdl, msh->NexKwdPos, SEEK_SET);
620 fseek(msh->hdl, CurPos, SEEK_SET);
623 /* Write the header */
627 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ KwdCod ][0]);
629 if(kwd->typ != InfKwd)
630 fprintf(msh->hdl, "%d\n", kwd->NmbLin);
632 /* In case of solution field, write the extended header */
634 if(kwd->typ == SolKwd)
636 fprintf(msh->hdl, "%d ", kwd->NmbTyp);
638 for(i=0; i<kwd->NmbTyp; i++)
639 fprintf(msh->hdl, "%d ", kwd->TypTab[i]);
641 fprintf(msh->hdl, "\n\n");
646 RecWrd(msh, (unsigned char *)&KwdCod);
647 msh->NexKwdPos = ftell(msh->hdl);
650 if(kwd->typ != InfKwd)
651 RecWrd(msh, (unsigned char *)&kwd->NmbLin);
653 /* In case of solution field, write the extended header at once */
655 if(kwd->typ == SolKwd)
657 RecWrd(msh, (unsigned char *)&kwd->NmbTyp);
659 for(i=0; i<kwd->NmbTyp; i++)
660 RecWrd(msh, (unsigned char *)&kwd->TypTab[i]);
664 /* Reset write buffer position */
667 /* Estimate the total file size and check whether it crosses the 2GB threshold */
669 msh->siz += kwd->NmbLin * kwd->NmbWrd * WrdSiz;
671 if(msh->siz > static_cast<long>(2E9))
678 /*----------------------------------------------------------*/
679 /* Read a full line from the current kwd */
680 /*----------------------------------------------------------*/
682 void MeshFormatParser::GmfGetLin(int MshIdx, int KwdCod, ...)
688 GmfMshSct *msh = GmfMshTab[ MshIdx ];
689 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
691 /* Start decoding the arguments */
693 va_start(VarArg, KwdCod);
695 if(kwd->typ != SolKwd)
697 int k, nb_repeat = 0;
703 for(i=0; i<kwd->SolSiz; i++)
704 if(kwd->fmt[i] == 'r')
705 fscanf(msh->hdl, "%f", va_arg(VarArg, float *));
706 else if(kwd->fmt[i] == 'n') {
707 fscanf(msh->hdl, "%d", &nb_repeat);
708 *(va_arg(VarArg, int *)) = nb_repeat;
709 for(k=0; k<nb_repeat; k++)
710 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
713 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
717 for(i=0; i<kwd->SolSiz; i++)
718 if(kwd->fmt[i] == 'r')
719 ScaWrd(msh, (unsigned char *)va_arg(VarArg, float *));
720 else if(kwd->fmt[i] == 'n') {
721 ScaWrd(msh, (unsigned char *)&nb_repeat);
722 *(va_arg(VarArg, int *)) = nb_repeat;
723 for(k=0; k<nb_repeat; k++)
724 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
727 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
734 for(i=0; i<kwd->SolSiz; i++)
735 if(kwd->fmt[i] == 'r')
736 fscanf(msh->hdl, "%lf", va_arg(VarArg, double *));
737 else if(kwd->fmt[i] == 'n') {
738 fscanf(msh->hdl, "%d", &nb_repeat);
739 *(va_arg(VarArg, int *)) = nb_repeat;
740 for(k=0; k<nb_repeat; k++)
741 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
744 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
747 for(i=0; i<kwd->SolSiz; i++)
748 if(kwd->fmt[i] == 'r')
749 ScaDblWrd(msh, (unsigned char *)va_arg(VarArg, double *));
750 else if(kwd->fmt[i] == 'n') {
751 ScaWrd(msh, (unsigned char *)&nb_repeat);
752 *(va_arg(VarArg, int *)) = nb_repeat;
753 for(k=0; k<nb_repeat; k++)
754 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
757 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
764 FltSolTab = va_arg(VarArg, float *);
767 for(j=0; j<kwd->SolSiz; j++)
768 fscanf(msh->hdl, "%f", &FltSolTab[j]);
770 ScaBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
774 DblSolTab = va_arg(VarArg, double *);
777 for(j=0; j<kwd->SolSiz; j++)
778 fscanf(msh->hdl, "%lf", &DblSolTab[j]);
780 for(j=0; j<kwd->SolSiz; j++)
781 ScaDblWrd(msh, (unsigned char *)&DblSolTab[j]);
789 /*----------------------------------------------------------*/
790 /* Write a full line from the current kwd */
791 /*----------------------------------------------------------*/
793 void MeshFormatParser::GmfSetLin(int MshIdx, int KwdCod, ...)
795 int i, j, pos, *IntBuf;
797 double *DblSolTab, *DblBuf;
799 GmfMshSct *msh = GmfMshTab[ MshIdx ];
800 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
802 /* Start decoding the arguments */
804 va_start(VarArg, KwdCod);
806 if(kwd->typ != SolKwd)
808 int k, nb_repeat = 0;
814 for(i=0; i<kwd->SolSiz; i++)
815 if(kwd->fmt[i] == 'r')
816 fprintf(msh->hdl, "%g ", (float)va_arg(VarArg, double));
817 else if(kwd->fmt[i] == 'n') {
818 nb_repeat = va_arg(VarArg, int);
819 fprintf(msh->hdl, "%d ", nb_repeat);
820 for(k=0; k<nb_repeat; k++)
821 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
824 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
828 int size_of_block = kwd->SolSiz;
829 for(i=0; i<kwd->SolSiz; i++)
830 if(kwd->fmt[i] == 'r')
831 msh->FltBuf[i] = static_cast<float>(va_arg(VarArg, double));
832 else if(kwd->fmt[i] == 'n') {
833 nb_repeat = va_arg(VarArg, int);
834 msh->FltBuf[i] = static_cast<float> (nb_repeat);
835 for(k=0; k<nb_repeat; k++) {
836 msh->IntBuf[i+1+k] = va_arg(VarArg, int);
841 msh->IntBuf[i] = va_arg(VarArg, int);
843 RecBlk(msh, msh->buf, size_of_block);
850 for(i=0; i<kwd->SolSiz; i++)
851 if(kwd->fmt[i] == 'r')
852 fprintf(msh->hdl, "%.15lg ", va_arg(VarArg, double));
853 else if(kwd->fmt[i] == 'n') {
854 nb_repeat = va_arg(VarArg, int);
855 fprintf(msh->hdl, "%d ", nb_repeat);
856 for(k=0; k<nb_repeat; k++)
857 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
860 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
866 for(i=0; i<kwd->SolSiz; i++)
867 if(kwd->fmt[i] == 'r')
869 DblBuf = (double *)&msh->buf[ pos ];
870 *DblBuf = va_arg(VarArg, double);
873 else if(kwd->fmt[i] == 'n')
875 IntBuf = (int *)&msh->buf[ pos ];
876 nb_repeat = va_arg(VarArg, int);
879 for(k=0; k<nb_repeat; k++) {
880 IntBuf = (int *)&msh->buf[ pos ];
881 *IntBuf = va_arg(VarArg, int);
887 IntBuf = (int *)&msh->buf[ pos ];
888 *IntBuf = va_arg(VarArg, int);
891 RecBlk(msh, msh->buf, pos/4);
899 FltSolTab = va_arg(VarArg, float *);
902 for(j=0; j<kwd->SolSiz; j++)
903 fprintf(msh->hdl, "%g ", FltSolTab[j]);
905 RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
909 DblSolTab = va_arg(VarArg, double *);
912 for(j=0; j<kwd->SolSiz; j++)
913 fprintf(msh->hdl, "%.15lg ", DblSolTab[j]);
915 RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd);
922 fprintf(msh->hdl, "\n");
926 /*----------------------------------------------------------*/
927 /* Private procedure for transmesh : copy a whole line */
928 /*----------------------------------------------------------*/
930 void MeshFormatParser::GmfCpyLin(int InpIdx, int OutIdx, int KwdCod)
935 GmfMshSct *InpMsh = GmfMshTab[ InpIdx ], *OutMsh = GmfMshTab[ OutIdx ];
936 KwdSct *kwd = &InpMsh->KwdTab[ KwdCod ];
938 for(i=0; i<kwd->SolSiz; i++)
940 if(kwd->fmt[i] == 'r')
944 if(InpMsh->typ & Asc)
945 fscanf(InpMsh->hdl, "%f", &f);
947 ScaWrd(InpMsh, (unsigned char *)&f);
953 if(InpMsh->typ & Asc)
954 fscanf(InpMsh->hdl, "%lf", &d);
956 ScaDblWrd(InpMsh, (unsigned char *)&d);
962 if(OutMsh->typ & Asc)
963 fprintf(OutMsh->hdl, "%g ", f);
965 RecWrd(OutMsh, (unsigned char *)&f);
966 else if(OutMsh->typ & Asc)
967 fprintf(OutMsh->hdl, "%.15g ", d);
969 RecDblWrd(OutMsh, (unsigned char *)&d);
971 else if(kwd->fmt[i] == 'n')
973 int k, nb_repeat = 0;
975 if(InpMsh->typ & Asc)
976 fscanf(InpMsh->hdl, "%d", &a);
978 ScaWrd(InpMsh, (unsigned char *)&a);
982 if(OutMsh->typ & Asc)
983 fprintf(OutMsh->hdl, "%d ", a);
985 RecWrd(OutMsh, (unsigned char *)&a);
987 for(k=0; k<nb_repeat; k++) {
988 if(InpMsh->typ & Asc)
989 fscanf(InpMsh->hdl, "%d", &a);
991 ScaWrd(InpMsh, (unsigned char *)&a);
993 if(OutMsh->typ & Asc)
994 fprintf(OutMsh->hdl, "%d ", a);
996 RecWrd(OutMsh, (unsigned char *)&a);
1001 if(InpMsh->typ & Asc)
1002 fscanf(InpMsh->hdl, "%d", &a);
1004 ScaWrd(InpMsh, (unsigned char *)&a);
1006 if(OutMsh->typ & Asc)
1007 fprintf(OutMsh->hdl, "%d ", a);
1009 RecWrd(OutMsh, (unsigned char *)&a);
1013 if(OutMsh->typ & Asc)
1014 fprintf(OutMsh->hdl, "\n");
1018 /*----------------------------------------------------------*/
1019 /* Find every kw present in a meshfile */
1020 /*----------------------------------------------------------*/
1022 int MeshFormatParser::ScaKwdTab(GmfMshSct *msh)
1025 long NexPos, CurPos, EndPos;
1026 char str[ GmfStrSiz ];
1030 /* Scan each string in the file until the end */
1032 while(fscanf(msh->hdl, "%s", str) != EOF)
1034 /* Fast test in order to reject quickly the numeric values */
1038 /* Search which kwd code this string is associated with,
1039 then get its header and save the current position in file (just before the data) */
1040 // printf("libmesh ScaKwdTab %s\n", str);
1041 for(KwdCod=1; KwdCod<= GmfMaxKwd; KwdCod++)
1042 if(!strcmp(str, GmfKwdFmt[ KwdCod ][0]))
1044 ScaKwdHdr(msh, KwdCod);
1048 else if(str[0] == '#')
1049 while(fgetc(msh->hdl) != '\n');
1056 CurPos = ftell(msh->hdl);
1057 fseek(msh->hdl, 0, SEEK_END);
1058 EndPos = ftell(msh->hdl);
1059 fseek(msh->hdl, CurPos, SEEK_SET);
1061 /* Jump through kwd positions in the file */
1065 /* Get the kwd code and the next kwd position */
1067 ScaWrd(msh, (unsigned char *)&KwdCod);
1068 NexPos = GetPos(msh);
1073 /* Check if this kwd belongs to this mesh version */
1075 if( (KwdCod >= 1) && (KwdCod <= GmfMaxKwd) )
1076 ScaKwdHdr(msh, KwdCod);
1078 /* Go to the next kwd */
1081 fseek(msh->hdl, NexPos, SEEK_SET);
1082 } while(NexPos && (KwdCod != GmfEnd));
1089 /*----------------------------------------------------------*/
1090 /* Read and setup the keyword's header */
1091 /*----------------------------------------------------------*/
1093 void MeshFormatParser::ScaKwdHdr(GmfMshSct *msh, int KwdCod)
1096 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1098 if(!strcmp("i", GmfKwdFmt[ KwdCod ][2]))
1101 fscanf(msh->hdl, "%d", &kwd->NmbLin);
1103 ScaWrd(msh, (unsigned char *)&kwd->NmbLin);
1108 if(!strcmp("sr", GmfKwdFmt[ KwdCod ][3]))
1112 fscanf(msh->hdl, "%d", &kwd->NmbTyp);
1114 for(i=0; i<kwd->NmbTyp; i++)
1115 fscanf(msh->hdl, "%d", &kwd->TypTab[i]);
1119 ScaWrd(msh, (unsigned char *)&kwd->NmbTyp);
1121 for(i=0; i<kwd->NmbTyp; i++)
1122 ScaWrd(msh, (unsigned char *)&kwd->TypTab[i]);
1126 ExpFmt(msh, KwdCod);
1127 kwd->pos = ftell(msh->hdl);
1131 /*----------------------------------------------------------*/
1132 /* Expand the compacted format and compute the line size */
1133 /*----------------------------------------------------------*/
1135 void MeshFormatParser::ExpFmt(GmfMshSct *msh, int KwdCod)
1139 const char *InpFmt = GmfKwdFmt[ KwdCod ][3];
1140 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1142 /* Set the kwd's type */
1144 if(!strlen(GmfKwdFmt[ KwdCod ][2]))
1146 else if(!strcmp(InpFmt, "sr"))
1151 /* Get the solution-field's size */
1153 if(kwd->typ == SolKwd)
1154 for(i=0; i<kwd->NmbTyp; i++)
1155 switch(kwd->TypTab[i])
1164 TmpSiz += (msh->dim * (msh->dim+1)) / 2;
1167 TmpSiz += msh->dim * msh->dim;
1171 /* Scan each character from the format string */
1173 i = kwd->SolSiz = kwd->NmbWrd = 0;
1175 while(i < static_cast<int>(strlen(InpFmt)) )
1177 chr = InpFmt[ i++ ];
1183 for(j=0; j<msh->dim; j++)
1184 kwd->fmt[ kwd->SolSiz++ ] = chr;
1190 for(j=0; j<TmpSiz; j++)
1191 kwd->fmt[ kwd->SolSiz++ ] = chr;
1194 kwd->fmt[ kwd->SolSiz++ ] = chr;
1197 for(i=0; i<kwd->SolSiz; i++)
1198 if(kwd->fmt[i] == 'i')
1200 else if(msh->ver >= 2)
1207 /*----------------------------------------------------------*/
1208 /* Read a four bytes word from a mesh file */
1209 /*----------------------------------------------------------*/
1211 void MeshFormatParser::ScaWrd(GmfMshSct *msh, unsigned char *wrd)
1215 fread(wrd, WrdSiz, 1, msh->hdl);
1230 /*----------------------------------------------------------*/
1231 /* Read an eight bytes word from a mesh file */
1232 /*----------------------------------------------------------*/
1234 void MeshFormatParser::ScaDblWrd(GmfMshSct *msh, unsigned char *wrd)
1239 fread(wrd, WrdSiz, 2, msh->hdl);
1253 /*----------------------------------------------------------*/
1254 /* Read ablock of four bytes word from a mesh file */
1255 /*----------------------------------------------------------*/
1257 void MeshFormatParser::ScaBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1260 unsigned char swp, *wrd;
1262 fread(blk, WrdSiz, siz, msh->hdl);
1267 for(i=0; i<siz; i++)
1269 wrd = &blk[ i * 4 ];
1274 wrd[ 3-j ] = wrd[j];
1281 /*----------------------------------------------------------*/
1282 /* Read a 4 or 8 bytes position in mesh file */
1283 /*----------------------------------------------------------*/
1285 long MeshFormatParser::GetPos(GmfMshSct *msh)
1291 ScaDblWrd(msh, (unsigned char*)&pos);
1294 ScaWrd(msh, (unsigned char*)&IntVal);
1302 /*----------------------------------------------------------*/
1303 /* Write a four bytes word to a mesh file */
1304 /*----------------------------------------------------------*/
1306 void MeshFormatParser::RecWrd(GmfMshSct *msh, unsigned char *wrd)
1308 fwrite(wrd, WrdSiz, 1, msh->hdl);
1312 /*----------------------------------------------------------*/
1313 /* Write an eight bytes word to a mesh file */
1314 /*----------------------------------------------------------*/
1316 void MeshFormatParser::RecDblWrd(GmfMshSct *msh, unsigned char *wrd)
1318 fwrite(wrd, WrdSiz, 2, msh->hdl);
1322 /*----------------------------------------------------------*/
1323 /* Write a block of four bytes word to a mesh file */
1324 /*----------------------------------------------------------*/
1326 void MeshFormatParser::RecBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1328 /* Copy this line-block into the main mesh buffer */
1332 memcpy(&msh->blk[ msh->pos ], blk, siz * WrdSiz);
1333 msh->pos += siz * WrdSiz;
1336 /* When the buffer is full or this procedure is called with a 0 size, flush the cache on disk */
1338 if( (msh->pos > BufSiz) || (!siz && msh->pos) )
1340 fwrite(msh->blk, 1, msh->pos, msh->hdl);
1346 /*----------------------------------------------------------*/
1347 /* Write a 4 or 8 bytes position in a mesh file */
1348 /*----------------------------------------------------------*/
1350 void MeshFormatParser::SetPos(GmfMshSct *msh, long pos)
1355 RecDblWrd(msh, (unsigned char*)&pos);
1358 IntVal = static_cast<int>(pos);
1359 RecWrd(msh, (unsigned char*)&IntVal);