3 /*----------------------------------------------------------*/
7 /*----------------------------------------------------------*/
9 /* Description: handle .meshb file format I/O */
10 /* Author: Loic MARECHAL */
11 /* Creation date: feb 16 2007 */
12 /* Last modification: apr 03 2012 */
14 /*----------------------------------------------------------*/
17 /*----------------------------------------------------------*/
19 /*----------------------------------------------------------*/
33 /*----------------------------------------------------------*/
35 /*----------------------------------------------------------*/
49 /*----------------------------------------------------------*/
51 /*----------------------------------------------------------*/
55 int typ, SolSiz, NmbWrd, NmbLin, NmbTyp, TypTab[ GmfMaxTyp ];
57 char fmt[ GmfMaxTyp*9 ];
62 int dim, ver, mod, typ, cod, pos;
64 KwdSct KwdTab[ GmfMaxKwd + 1 ];
69 char FilNam[ GmfStrSiz ];
70 double DblBuf[1000/8];
71 unsigned char blk[ BufSiz + 1000 ];
75 /*----------------------------------------------------------*/
76 /* Global variables */
77 /*----------------------------------------------------------*/
79 static int GmfIniFlg=0;
80 static GmfMshSct *GmfMshTab[ MaxMsh + 1 ];
81 /* see MeshGems/Docs/meshgems_formats_description.pdf */
82 static const char *GmfKwdFmt[ GmfMaxKwd + 1 ][4] =
83 { {"Reserved", "", "", ""},
84 {"MeshVersionFormatted", "", "", "i"},
85 {"Reserved", "", "", ""},
86 {"Dimension", "", "", "i"},
87 {"Vertices", "Vertex", "i", "dri"},
88 {"Edges", "Edge", "i", "iii"},
89 {"Triangles", "Triangle", "i", "iiii"},
90 {"Quadrilaterals", "Quadrilateral", "i", "iiiii"},
91 {"Tetrahedra", "Tetrahedron", "i", "iiiii"},
92 {"Prisms", "Prism", "i", "iiiiiii"},
93 {"Hexahedra", "Hexahedron", "i", "iiiiiiiii"},
94 {"IterationsAll", "IterationAll","","i"},
95 {"TimesAll", "TimeAll","","r"},
96 {"Corners", "Corner", "i", "i"},
97 {"Ridges", "Ridge", "i", "i"},
98 {"RequiredVertices", "RequiredVertex", "i", "i"},
99 {"RequiredEdges", "RequiredEdge", "i", "i"},
100 {"RequiredTriangles", "RequiredTriangle", "i", "i"},
101 {"RequiredQuadrilaterals", "RequiredQuadrilateral", "i", "i"},
102 {"TangentAtEdgeVertices", "TangentAtEdgeVertex", "i", "iii"},
103 {"NormalAtVertices", "NormalAtVertex", "i", "ii"},
104 {"NormalAtTriangleVertices", "NormalAtTriangleVertex", "i", "iii"},
105 {"NormalAtQuadrilateralVertices", "NormalAtQuadrilateralVertex", "i", "iiii"},
106 {"AngleOfCornerBound", "", "", "r"},
107 {"TrianglesP2", "TriangleP2", "i", "iiiiiii"},
108 {"EdgesP2", "EdgeP2", "i", "iiii"},
109 {"SolAtPyramids", "SolAtPyramid", "i", "sr"},
110 {"QuadrilateralsQ2", "QuadrilateralQ2", "i", "iiiiiiiiii"},
111 {"ISolAtPyramids", "ISolAtPyramid", "i", "iiiii"},
112 {"SubDomainFromGeom", "SubDomainFromGeom", "i", "iiii"},
113 {"TetrahedraP2", "TetrahedronP2", "i", "iiiiiiiiiii"},
114 {"Fault_NearTri", "Fault_NearTri", "i", "i"},
115 {"Fault_Inter", "Fault_Inter", "i", "i"},
116 {"HexahedraQ2", "HexahedronQ2", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiii"},
117 {"ExtraVerticesAtEdges", "ExtraVerticesAtEdge", "i", "in"},
118 {"ExtraVerticesAtTriangles", "ExtraVerticesAtTriangle", "i", "in"},
119 {"ExtraVerticesAtQuadrilaterals", "ExtraVerticesAtQuadrilateral", "i", "in"},
120 {"ExtraVerticesAtTetrahedra", "ExtraVerticesAtTetrahedron", "i", "in"},
121 {"ExtraVerticesAtPrisms", "ExtraVerticesAtPrism", "i", "in"},
122 {"ExtraVerticesAtHexahedra", "ExtraVerticesAtHexahedron", "i", "in"},
123 {"VerticesOnGeometricVertices", "VertexOnGeometricVertex", "i", "iir"},
124 {"VerticesOnGeometricEdges", "VertexOnGeometricEdge", "i", "iirr"},
125 {"VerticesOnGeometricTriangles", "VertexOnGeometricTriangle", "i", "iirrr"},
126 {"VerticesOnGeometricQuadrilaterals", "VertexOnGeometricQuadrilateral", "i", "iirrr"},
127 {"EdgesOnGeometricEdges", "EdgeOnGeometricEdge", "i", "iir"},
128 {"Fault_FreeEdge", "Fault_FreeEdge", "i", "i"},
129 {"Polyhedra", "Polyhedron", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
130 {"Polygons", "Polygon", "", "iiiiiiiii"},
131 {"Fault_Overlap", "Fault_Overlap", "i", "i"},
132 {"Pyramids", "Pyramid", "i", "iiiiii"},
133 {"BoundingBox", "", "", "drdr"},
134 {"Body","i", "drdrdrdr"},
135 {"PrivateTable", "PrivateTable", "i", "i"},
136 {"Fault_BadShape", "Fault_BadShape", "i", "i"},
138 {"TrianglesOnGeometricTriangles", "TriangleOnGeometricTriangle", "i", "iir"},
139 {"TrianglesOnGeometricQuadrilaterals", "TriangleOnGeometricQuadrilateral", "i", "iir"},
140 {"QuadrilateralsOnGeometricTriangles", "QuadrilateralOnGeometricTriangle", "i", "iir"},
141 {"QuadrilateralsOnGeometricQuadrilaterals", "QuadrilateralOnGeometricQuadrilateral", "i", "iir"},
142 {"Tangents", "Tangent", "i", "dr"},
143 {"Normals", "Normal", "i", "dr"},
144 {"TangentAtVertices", "TangentAtVertex", "i", "ii"},
145 {"SolAtVertices", "SolAtVertex", "i", "sr"},
146 {"SolAtEdges", "SolAtEdge", "i", "sr"},
147 {"SolAtTriangles", "SolAtTriangle", "i", "sr"},
148 {"SolAtQuadrilaterals", "SolAtQuadrilateral", "i", "sr"},
149 {"SolAtTetrahedra", "SolAtTetrahedron", "i", "sr"},
150 {"SolAtPrisms", "SolAtPrism", "i", "sr"},
151 {"SolAtHexahedra", "SolAtHexahedron", "i", "sr"},
152 {"DSolAtVertices", "DSolAtVertex", "i", "sr"},
153 {"ISolAtVertices", "ISolAtVertex", "i", "i"},
154 {"ISolAtEdges", "ISolAtEdge", "i", "ii"},
155 {"ISolAtTriangles", "ISolAtTriangle", "i", "iii"},
156 {"ISolAtQuadrilaterals", "ISolAtQuadrilateral", "i", "iiii"},
157 {"ISolAtTetrahedra", "ISolAtTetrahedron", "i", "iiii"},
158 {"ISolAtPrisms", "ISolAtPrism", "i", "iiiiii"},
159 {"ISolAtHexahedra", "ISolAtHexahedron", "i", "iiiiiiii"},
160 {"Iterations", "","","i"},
162 {"Fault_SmallTri", "Fault_SmallTri","i","i"},
163 {"CoarseHexahedra", "CoarseHexahedron", "i", "i"},
164 {"Fault_MultipleEdge", "Fault_MultipleEdge", "i", "i"}
168 /*----------------------------------------------------------*/
169 /* Prototypes of local procedures */
170 /*----------------------------------------------------------*/
172 static void ScaWrd(GmfMshSct *, unsigned char *);
173 static void ScaDblWrd(GmfMshSct *, unsigned char *);
174 static void ScaBlk(GmfMshSct *, unsigned char *, int);
175 static long GetPos(GmfMshSct *);
176 static void RecWrd(GmfMshSct *, unsigned char *);
177 static void RecDblWrd(GmfMshSct *, unsigned char *);
178 static void RecBlk(GmfMshSct *, unsigned char *, int);
179 static void SetPos(GmfMshSct *, long);
180 static int ScaKwdTab(GmfMshSct *);
181 static void ExpFmt(GmfMshSct *, int);
182 static void ScaKwdHdr(GmfMshSct *, int);
185 /*----------------------------------------------------------*/
186 /* Open a mesh file in read or write mod */
187 /*----------------------------------------------------------*/
189 int GmfOpenMesh(const char *FilNam, int mod, ...)
191 int i, KwdCod, res, *PtrVer, *PtrDim, MshIdx=0;
192 char str[ GmfStrSiz ];
197 #if defined(WIN32) && defined(UNICODE)
198 wchar_t* encoded = 0;
203 for(i=0;i<=MaxMsh;i++)
209 /*---------------------*/
210 /* MESH STRUCTURE INIT */
211 /*---------------------*/
213 for(i=1;i<=MaxMsh;i++)
220 if( !MshIdx || !(msh = calloc(1, sizeof(GmfMshSct))) )
223 /* Copy the FilNam into the structure */
225 if(strlen(FilNam) + 7 >= GmfStrSiz)
231 strcpy(msh->FilNam, FilNam);
233 /* Store the opening mod (read or write) and guess the filetype (binary or ascii) depending on the extension */
236 msh->buf = (unsigned char *)msh->DblBuf;
237 msh->FltBuf = (float *)msh->DblBuf;
238 msh->IntBuf = (int *)msh->DblBuf;
240 k = strlen(msh->FilNam) - 6;
244 if(strstr(ptr, ".meshb"))
245 msh->typ |= (Bin | MshFil);
246 else if(strstr(ptr, ".mesh"))
247 msh->typ |= (Asc | MshFil);
248 else if(strstr(ptr, ".solb"))
249 msh->typ |= (Bin | SolFil);
250 else if(strstr(ptr, ".sol"))
251 msh->typ |= (Asc | SolFil);
257 /* Open the file in the required mod and initialise the mesh structure */
259 if(msh->mod == GmfRead)
262 /*-----------------------*/
263 /* OPEN FILE FOR READING */
264 /*-----------------------*/
266 va_start(VarArg, mod);
267 PtrVer = va_arg(VarArg, int *);
268 PtrDim = va_arg(VarArg, int *);
271 /* Create the name string and open the file */
272 #if defined(WIN32) && defined(UNICODE)
273 size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
274 encoded = malloc((size_needed + 1)*sizeof(wchar_t));
275 MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
276 encoded[size_needed] = '\0';
277 if (!(msh->hdl = _wfopen(encoded, L"rb")))
279 if (!(msh->hdl = fopen(msh->FilNam, "rb")))
283 #if defined(WIN32) && defined(UNICODE)
289 #if defined(WIN32) && defined(UNICODE)
293 /* Read the endian coding tag, the mesh version and the mesh dimension (mandatory kwd) */
297 fread((unsigned char *)&msh->cod, WrdSiz, 1, msh->hdl);
299 if( (msh->cod != 1) && (msh->cod != 16777216) )
305 ScaWrd(msh, (unsigned char *)&msh->ver);
307 if( (msh->ver < 1) || (msh->ver > 3) )
313 if( (msh->ver == 3) && (sizeof(long) == 4) )
319 ScaWrd(msh, (unsigned char *)&KwdCod);
321 if(KwdCod != GmfDimension)
328 ScaWrd(msh, (unsigned char *)&msh->dim);
334 res = fscanf(msh->hdl, "%s", str);
335 }while( (res != EOF) && strcmp(str, "MeshVersionFormatted") );
343 fscanf(msh->hdl, "%d", &msh->ver);
345 if( (msh->ver < 1) || (msh->ver > 3) )
353 res = fscanf(msh->hdl, "%s", str);
354 }while( (res != EOF) && strcmp(str, "Dimension") );
362 fscanf(msh->hdl, "%d", &msh->dim);
365 if( (msh->dim != 2) && (msh->dim != 3) )
371 (*PtrVer) = msh->ver;
372 (*PtrDim) = msh->dim;
378 /* Read the list of kw present in the file */
386 GmfMshTab[ MshIdx ] = msh;
390 else if(msh->mod == GmfWrite)
393 /*-----------------------*/
394 /* OPEN FILE FOR WRITING */
395 /*-----------------------*/
399 /* Check if the user provided a valid version number and dimension */
401 va_start(VarArg, mod);
402 msh->ver = va_arg(VarArg, int);
403 msh->dim = va_arg(VarArg, int);
406 if( (msh->ver < 1) || (msh->ver > 3) )
412 if( (msh->ver == 3) && (sizeof(long) == 4) )
418 if( (msh->dim != 2) && (msh->dim != 3) )
424 /* Create the mesh file */
425 #if defined(WIN32) && defined(UNICODE)
426 size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
427 encoded = malloc((size_needed + 1) * sizeof(wchar_t));
428 MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
429 encoded[size_needed] = '\0';
430 if (!(msh->hdl = _wfopen(encoded, L"wb")))
432 if(!(msh->hdl = fopen(msh->FilNam, "wb")))
436 #if defined(WIN32) && defined(UNICODE)
442 #if defined(WIN32) && defined(UNICODE)
445 GmfMshTab[ MshIdx ] = msh;
452 /* Write the mesh version and dimension */
456 fprintf(msh->hdl, "%s %d\n\n", GmfKwdFmt[ GmfVersionFormatted ][0], msh->ver);
457 fprintf(msh->hdl, "%s %d\n", GmfKwdFmt[ GmfDimension ][0], msh->dim);
461 RecWrd(msh, (unsigned char *)&msh->cod);
462 RecWrd(msh, (unsigned char *)&msh->ver);
463 GmfSetKwd(MshIdx, GmfDimension, 0);
464 RecWrd(msh, (unsigned char *)&msh->dim);
477 /*----------------------------------------------------------*/
478 /* Close a meshfile in the right way */
479 /*----------------------------------------------------------*/
481 int GmfCloseMesh(int MshIdx)
486 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
489 msh = GmfMshTab[ MshIdx ];
490 RecBlk(msh, msh->buf, 0);
492 /* In write down the "End" kw in write mode */
494 if(msh->mod == GmfWrite){
496 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ GmfEnd ][0]);
498 GmfSetKwd(MshIdx, GmfEnd, 0);
500 /* Close the file and free the mesh structure */
506 GmfMshTab[ MshIdx ] = NULL;
512 /*----------------------------------------------------------*/
513 /* Read the number of lines and set the position to this kwd*/
514 /*----------------------------------------------------------*/
516 int GmfStatKwd(int MshIdx, int KwdCod, ...)
518 int i, *PtrNmbTyp, *PtrSolSiz, *TypTab;
523 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
526 msh = GmfMshTab[ MshIdx ];
528 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
531 kwd = &msh->KwdTab[ KwdCod ];
536 /* Read further arguments if this kw is a sol */
538 if(kwd->typ == SolKwd)
540 va_start(VarArg, KwdCod);
542 PtrNmbTyp = va_arg(VarArg, int *);
543 *PtrNmbTyp = kwd->NmbTyp;
545 PtrSolSiz = va_arg(VarArg, int *);
546 *PtrSolSiz = kwd->SolSiz;
548 TypTab = va_arg(VarArg, int *);
550 for(i=0;i<kwd->NmbTyp;i++)
551 TypTab[i] = kwd->TypTab[i];
560 /*----------------------------------------------------------*/
561 /* Set the current file position to a given kwd */
562 /*----------------------------------------------------------*/
564 int GmfGotoKwd(int MshIdx, int KwdCod)
569 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
572 msh = GmfMshTab[ MshIdx ];
574 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
577 kwd = &msh->KwdTab[ KwdCod ];
582 return(fseek(msh->hdl, kwd->pos, SEEK_SET));
586 /*----------------------------------------------------------*/
587 /* Write the kwd and set the number of lines */
588 /*----------------------------------------------------------*/
590 int GmfSetKwd(int MshIdx, int KwdCod, ...)
592 int i, NmbLin=0, *TypTab;
598 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
601 msh = GmfMshTab[ MshIdx ];
602 RecBlk(msh, msh->buf, 0);
604 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
607 kwd = &msh->KwdTab[ KwdCod ];
609 /* Read further arguments if this kw has a header */
611 if(strlen(GmfKwdFmt[ KwdCod ][2]))
613 va_start(VarArg, KwdCod);
614 NmbLin = va_arg(VarArg, int);
616 if(!strcmp(GmfKwdFmt[ KwdCod ][3], "sr"))
618 kwd->NmbTyp = va_arg(VarArg, int);
619 TypTab = va_arg(VarArg, int *);
621 for(i=0;i<kwd->NmbTyp;i++)
622 kwd->TypTab[i] = TypTab[i];
628 /* Setup the kwd info */
634 else if(kwd->typ == InfKwd)
637 kwd->NmbLin = NmbLin;
639 /* Store the next kwd position in binary file */
641 if( (msh->typ & Bin) && msh->NexKwdPos )
643 CurPos = ftell(msh->hdl);
644 fseek(msh->hdl, msh->NexKwdPos, SEEK_SET);
646 fseek(msh->hdl, CurPos, SEEK_SET);
649 /* Write the header */
653 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ KwdCod ][0]);
655 if(kwd->typ != InfKwd)
656 fprintf(msh->hdl, "%d\n", kwd->NmbLin);
658 /* In case of solution field, write the extended header */
660 if(kwd->typ == SolKwd)
662 fprintf(msh->hdl, "%d ", kwd->NmbTyp);
664 for(i=0;i<kwd->NmbTyp;i++)
665 fprintf(msh->hdl, "%d ", kwd->TypTab[i]);
667 fprintf(msh->hdl, "\n\n");
672 RecWrd(msh, (unsigned char *)&KwdCod);
673 msh->NexKwdPos = ftell(msh->hdl);
676 if(kwd->typ != InfKwd)
677 RecWrd(msh, (unsigned char *)&kwd->NmbLin);
679 /* In case of solution field, write the extended header at once */
681 if(kwd->typ == SolKwd)
683 RecWrd(msh, (unsigned char *)&kwd->NmbTyp);
685 for(i=0;i<kwd->NmbTyp;i++)
686 RecWrd(msh, (unsigned char *)&kwd->TypTab[i]);
690 /* Reset write buffer position */
693 /* Estimate the total file size and check whether it crosses the 2GB threshold */
695 msh->siz += kwd->NmbLin * kwd->NmbWrd * WrdSiz;
704 /*----------------------------------------------------------*/
705 /* Read a full line from the current kwd */
706 /*----------------------------------------------------------*/
708 void GmfGetLin(int MshIdx, int KwdCod, ...)
714 GmfMshSct *msh = GmfMshTab[ MshIdx ];
715 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
717 /* Start decoding the arguments */
719 va_start(VarArg, KwdCod);
721 if(kwd->typ != SolKwd)
723 int k, nb_repeat = 0;
729 for(i=0;i<kwd->SolSiz;i++)
730 if(kwd->fmt[i] == 'r')
731 fscanf(msh->hdl, "%f", va_arg(VarArg, float *));
732 else if(kwd->fmt[i] == 'n') {
733 fscanf(msh->hdl, "%d", &nb_repeat);
734 *(va_arg(VarArg, int *)) = nb_repeat;
735 for(k=0;k<nb_repeat;k++)
736 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
739 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
743 for(i=0;i<kwd->SolSiz;i++)
744 if(kwd->fmt[i] == 'r')
745 ScaWrd(msh, (unsigned char *)va_arg(VarArg, float *));
746 else if(kwd->fmt[i] == 'n') {
747 ScaWrd(msh, (unsigned char *)&nb_repeat);
748 *(va_arg(VarArg, int *)) = nb_repeat;
749 for(k=0;k<nb_repeat;k++)
750 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
753 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
760 for(i=0;i<kwd->SolSiz;i++)
761 if(kwd->fmt[i] == 'r')
762 fscanf(msh->hdl, "%lf", va_arg(VarArg, double *));
763 else if(kwd->fmt[i] == 'n') {
764 fscanf(msh->hdl, "%d", &nb_repeat);
765 *(va_arg(VarArg, int *)) = nb_repeat;
766 for(k=0;k<nb_repeat;k++)
767 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
770 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
773 for(i=0;i<kwd->SolSiz;i++)
774 if(kwd->fmt[i] == 'r')
775 ScaDblWrd(msh, (unsigned char *)va_arg(VarArg, double *));
776 else if(kwd->fmt[i] == 'n') {
777 ScaWrd(msh, (unsigned char *)&nb_repeat);
778 *(va_arg(VarArg, int *)) = nb_repeat;
779 for(k=0;k<nb_repeat;k++)
780 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
783 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
790 FltSolTab = va_arg(VarArg, float *);
793 for(j=0;j<kwd->SolSiz;j++)
794 fscanf(msh->hdl, "%f", &FltSolTab[j]);
796 ScaBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
800 DblSolTab = va_arg(VarArg, double *);
803 for(j=0;j<kwd->SolSiz;j++)
804 fscanf(msh->hdl, "%lf", &DblSolTab[j]);
806 for(j=0;j<kwd->SolSiz;j++)
807 ScaDblWrd(msh, (unsigned char *)&DblSolTab[j]);
815 /*----------------------------------------------------------*/
816 /* Write a full line from the current kwd */
817 /*----------------------------------------------------------*/
819 void GmfSetLin(int MshIdx, int KwdCod, ...)
821 int i, j, pos, *IntBuf;
823 double *DblSolTab, *DblBuf;
825 GmfMshSct *msh = GmfMshTab[ MshIdx ];
826 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
828 /* Start decoding the arguments */
830 va_start(VarArg, KwdCod);
832 if(kwd->typ != SolKwd)
834 int k, nb_repeat = 0;
840 for(i=0;i<kwd->SolSiz;i++)
841 if(kwd->fmt[i] == 'r')
842 fprintf(msh->hdl, "%g ", (float)va_arg(VarArg, double));
843 else if(kwd->fmt[i] == 'n') {
844 nb_repeat = va_arg(VarArg, int);
845 fprintf(msh->hdl, "%d ", nb_repeat);
846 for(k=0;k<nb_repeat;k++)
847 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
850 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
854 int size_of_block = kwd->SolSiz;
855 for(i=0;i<kwd->SolSiz;i++)
856 if(kwd->fmt[i] == 'r')
857 msh->FltBuf[i] = va_arg(VarArg, double);
858 else if(kwd->fmt[i] == 'n') {
859 nb_repeat = va_arg(VarArg, int);
860 msh->FltBuf[i] = nb_repeat;
861 for(k=0;k<nb_repeat;k++) {
862 msh->IntBuf[i+1+k] = va_arg(VarArg, int);
867 msh->IntBuf[i] = va_arg(VarArg, int);
869 RecBlk(msh, msh->buf, size_of_block);
876 for(i=0;i<kwd->SolSiz;i++)
877 if(kwd->fmt[i] == 'r')
878 fprintf(msh->hdl, "%.15g ", va_arg(VarArg, double)); /* was "%.15lg and warning "ISO C90 does not support the '%lg' gnu_printf format"*/
879 else if(kwd->fmt[i] == 'n') {
880 nb_repeat = va_arg(VarArg, int);
881 fprintf(msh->hdl, "%d ", nb_repeat);
882 for(k=0;k<nb_repeat;k++)
883 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
886 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
892 for(i=0;i<kwd->SolSiz;i++)
893 if(kwd->fmt[i] == 'r')
895 DblBuf = (double *)&msh->buf[ pos ];
896 *DblBuf = va_arg(VarArg, double);
899 else if(kwd->fmt[i] == 'n')
901 IntBuf = (int *)&msh->buf[ pos ];
902 nb_repeat = va_arg(VarArg, int);
905 for(k=0;k<nb_repeat;k++) {
906 IntBuf = (int *)&msh->buf[ pos ];
907 *IntBuf = va_arg(VarArg, int);
913 IntBuf = (int *)&msh->buf[ pos ];
914 *IntBuf = va_arg(VarArg, int);
917 RecBlk(msh, msh->buf, pos/4);
925 FltSolTab = va_arg(VarArg, float *);
928 for(j=0;j<kwd->SolSiz;j++)
929 fprintf(msh->hdl, "%g ", FltSolTab[j]);
931 RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
935 DblSolTab = va_arg(VarArg, double *);
938 for(j=0;j<kwd->SolSiz;j++)
939 fprintf(msh->hdl, "%.15g ", DblSolTab[j]); /* was " %.15lg " and warning "ISO C90 does not support the '%lg' gnu_printf format" */
941 RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd);
948 fprintf(msh->hdl, "\n");
952 /*----------------------------------------------------------*/
953 /* Private procedure for transmesh : copy a whole line */
954 /*----------------------------------------------------------*/
956 void GmfCpyLin(int InpIdx, int OutIdx, int KwdCod)
961 GmfMshSct *InpMsh = GmfMshTab[ InpIdx ], *OutMsh = GmfMshTab[ OutIdx ];
962 KwdSct *kwd = &InpMsh->KwdTab[ KwdCod ];
964 for(i=0;i<kwd->SolSiz;i++)
966 if(kwd->fmt[i] == 'r')
970 if(InpMsh->typ & Asc)
971 fscanf(InpMsh->hdl, "%f", &f);
973 ScaWrd(InpMsh, (unsigned char *)&f);
979 if(InpMsh->typ & Asc)
980 fscanf(InpMsh->hdl, "%lf", &d);
982 ScaDblWrd(InpMsh, (unsigned char *)&d);
988 if(OutMsh->typ & Asc)
989 fprintf(OutMsh->hdl, "%g ", f);
991 RecWrd(OutMsh, (unsigned char *)&f);
993 if(OutMsh->typ & Asc)
994 fprintf(OutMsh->hdl, "%.15g ", d);
996 RecDblWrd(OutMsh, (unsigned char *)&d);
998 else if(kwd->fmt[i] == 'n')
1000 int k, nb_repeat = 0;
1002 if(InpMsh->typ & Asc)
1003 fscanf(InpMsh->hdl, "%d", &a);
1005 ScaWrd(InpMsh, (unsigned char *)&a);
1009 if(OutMsh->typ & Asc)
1010 fprintf(OutMsh->hdl, "%d ", a);
1012 RecWrd(OutMsh, (unsigned char *)&a);
1014 for(k=0;k<nb_repeat;k++) {
1015 if(InpMsh->typ & Asc)
1016 fscanf(InpMsh->hdl, "%d", &a);
1018 ScaWrd(InpMsh, (unsigned char *)&a);
1020 if(OutMsh->typ & Asc)
1021 fprintf(OutMsh->hdl, "%d ", a);
1023 RecWrd(OutMsh, (unsigned char *)&a);
1028 if(InpMsh->typ & Asc)
1029 fscanf(InpMsh->hdl, "%d", &a);
1031 ScaWrd(InpMsh, (unsigned char *)&a);
1033 if(OutMsh->typ & Asc)
1034 fprintf(OutMsh->hdl, "%d ", a);
1036 RecWrd(OutMsh, (unsigned char *)&a);
1040 if(OutMsh->typ & Asc)
1041 fprintf(OutMsh->hdl, "\n");
1045 /*----------------------------------------------------------*/
1046 /* Find every kw present in a meshfile */
1047 /*----------------------------------------------------------*/
1049 static int ScaKwdTab(GmfMshSct *msh)
1052 long NexPos, CurPos, EndPos;
1053 char str[ GmfStrSiz ];
1057 /* Scan each string in the file until the end */
1059 while(fscanf(msh->hdl, "%s", str) != EOF)
1061 /* Fast test in order to reject quickly the numeric values */
1065 /* Search which kwd code this string is associated with,
1066 then get its header and save the current position in file (just before the data) */
1067 /* printf("libmesh ScaKwdTab %s\n", str); */
1068 for(KwdCod=1; KwdCod<= GmfMaxKwd; KwdCod++)
1069 if(!strcmp(str, GmfKwdFmt[ KwdCod ][0]))
1071 ScaKwdHdr(msh, KwdCod);
1075 else if(str[0] == '#')
1076 while(fgetc(msh->hdl) != '\n');
1083 CurPos = ftell(msh->hdl);
1084 fseek(msh->hdl, 0, SEEK_END);
1085 EndPos = ftell(msh->hdl);
1086 fseek(msh->hdl, CurPos, SEEK_SET);
1088 /* Jump through kwd positions in the file */
1092 /* Get the kwd code and the next kwd position */
1094 ScaWrd(msh, (unsigned char *)&KwdCod);
1095 NexPos = GetPos(msh);
1100 /* Check if this kwd belongs to this mesh version */
1102 if( (KwdCod >= 1) && (KwdCod <= GmfMaxKwd) )
1103 ScaKwdHdr(msh, KwdCod);
1105 /* Go to the next kwd */
1108 fseek(msh->hdl, NexPos, SEEK_SET);
1109 }while(NexPos && (KwdCod != GmfEnd));
1116 /*----------------------------------------------------------*/
1117 /* Read and setup the keyword's header */
1118 /*----------------------------------------------------------*/
1120 static void ScaKwdHdr(GmfMshSct *msh, int KwdCod)
1123 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1125 if(!strcmp("i", GmfKwdFmt[ KwdCod ][2]))
1128 fscanf(msh->hdl, "%d", &kwd->NmbLin);
1130 ScaWrd(msh, (unsigned char *)&kwd->NmbLin);
1135 if(!strcmp("sr", GmfKwdFmt[ KwdCod ][3]))
1139 fscanf(msh->hdl, "%d", &kwd->NmbTyp);
1141 for(i=0;i<kwd->NmbTyp;i++)
1142 fscanf(msh->hdl, "%d", &kwd->TypTab[i]);
1146 ScaWrd(msh, (unsigned char *)&kwd->NmbTyp);
1148 for(i=0;i<kwd->NmbTyp;i++)
1149 ScaWrd(msh, (unsigned char *)&kwd->TypTab[i]);
1153 ExpFmt(msh, KwdCod);
1154 kwd->pos = ftell(msh->hdl);
1158 /*----------------------------------------------------------*/
1159 /* Expand the compacted format and compute the line size */
1160 /*----------------------------------------------------------*/
1162 static void ExpFmt(GmfMshSct *msh, int KwdCod)
1166 const char *InpFmt = GmfKwdFmt[ KwdCod ][3];
1167 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1169 /* Set the kwd's type */
1171 if(!strlen(GmfKwdFmt[ KwdCod ][2]))
1173 else if(!strcmp(InpFmt, "sr"))
1178 /* Get the solution-field's size */
1180 if(kwd->typ == SolKwd)
1181 for(i=0;i<kwd->NmbTyp;i++)
1182 switch(kwd->TypTab[i])
1184 case GmfSca : TmpSiz += 1; break;
1185 case GmfVec : TmpSiz += msh->dim; break;
1186 case GmfSymMat : TmpSiz += (msh->dim * (msh->dim+1)) / 2; break;
1187 case GmfMat : TmpSiz += msh->dim * msh->dim; break;
1190 /* Scan each character from the format string */
1192 i = kwd->SolSiz = kwd->NmbWrd = 0;
1194 while(i < (int)strlen(InpFmt))
1196 chr = InpFmt[ i++ ];
1202 for(j=0;j<msh->dim;j++)
1203 kwd->fmt[ kwd->SolSiz++ ] = chr;
1209 for(j=0;j<TmpSiz;j++)
1210 kwd->fmt[ kwd->SolSiz++ ] = chr;
1213 kwd->fmt[ kwd->SolSiz++ ] = chr;
1216 for(i=0;i<kwd->SolSiz;i++)
1217 if(kwd->fmt[i] == 'i')
1219 else if(msh->ver >= 2)
1226 /*----------------------------------------------------------*/
1227 /* Read a four bytes word from a mesh file */
1228 /*----------------------------------------------------------*/
1230 static void ScaWrd(GmfMshSct *msh, unsigned char *wrd)
1234 fread(wrd, WrdSiz, 1, msh->hdl);
1249 /*----------------------------------------------------------*/
1250 /* Read an eight bytes word from a mesh file */
1251 /*----------------------------------------------------------*/
1253 static void ScaDblWrd(GmfMshSct *msh, unsigned char *wrd)
1258 fread(wrd, WrdSiz, 2, msh->hdl);
1272 /*----------------------------------------------------------*/
1273 /* Read ablock of four bytes word from a mesh file */
1274 /*----------------------------------------------------------*/
1276 static void ScaBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1279 unsigned char swp, *wrd;
1281 fread(blk, WrdSiz, siz, msh->hdl);
1288 wrd = &blk[ i * 4 ];
1293 wrd[ 3-j ] = wrd[j];
1300 /*----------------------------------------------------------*/
1301 /* Read a 4 or 8 bytes position in mesh file */
1302 /*----------------------------------------------------------*/
1304 static long GetPos(GmfMshSct *msh)
1310 ScaDblWrd(msh, (unsigned char*)&pos);
1313 ScaWrd(msh, (unsigned char*)&IntVal);
1321 /*----------------------------------------------------------*/
1322 /* Write a four bytes word to a mesh file */
1323 /*----------------------------------------------------------*/
1325 static void RecWrd(GmfMshSct *msh, unsigned char *wrd)
1327 fwrite(wrd, WrdSiz, 1, msh->hdl);
1331 /*----------------------------------------------------------*/
1332 /* Write an eight bytes word to a mesh file */
1333 /*----------------------------------------------------------*/
1335 static void RecDblWrd(GmfMshSct *msh, unsigned char *wrd)
1337 fwrite(wrd, WrdSiz, 2, msh->hdl);
1341 /*----------------------------------------------------------*/
1342 /* Write a block of four bytes word to a mesh file */
1343 /*----------------------------------------------------------*/
1345 static void RecBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1347 /* Copy this line-block into the main mesh buffer */
1351 memcpy(&msh->blk[ msh->pos ], blk, siz * WrdSiz);
1352 msh->pos += siz * WrdSiz;
1355 /* When the buffer is full or this procedure is called with a 0 size, flush the cache on disk */
1357 if( (msh->pos > BufSiz) || (!siz && msh->pos) )
1359 fwrite(msh->blk, 1, msh->pos, msh->hdl);
1365 /*----------------------------------------------------------*/
1366 /* Write a 4 or 8 bytes position in a mesh file */
1367 /*----------------------------------------------------------*/
1369 static void SetPos(GmfMshSct *msh, long pos)
1374 RecDblWrd(msh, (unsigned char*)&pos);
1378 RecWrd(msh, (unsigned char*)&IntVal);