3 /*----------------------------------------------------------*/
7 /*----------------------------------------------------------*/
9 /* Description: handle .meshb file format I/O */
10 /* Author: Loic MARECHAL */
11 /* Creation date: feb 16 2007 */
12 /* Last modification: feb 08 2011 */
14 /*----------------------------------------------------------*/
17 /*----------------------------------------------------------*/
19 /*----------------------------------------------------------*/
31 /*----------------------------------------------------------*/
33 /*----------------------------------------------------------*/
47 /*----------------------------------------------------------*/
49 /*----------------------------------------------------------*/
53 int typ, SolSiz, NmbWrd, NmbLin, NmbTyp, TypTab[ GmfMaxTyp ];
55 char fmt[ GmfMaxTyp*9 ];
60 int dim, ver, mod, typ, cod, pos;
62 KwdSct KwdTab[ GmfMaxKwd + 1 ];
67 char FilNam[ GmfStrSiz ];
68 double DblBuf[1000/8];
69 unsigned char blk[ BufSiz + 1000 ];
73 /*----------------------------------------------------------*/
74 /* Global variables */
75 /*----------------------------------------------------------*/
78 GmfMshSct *GmfMshTab[ MaxMsh + 1 ];
79 char *GmfKwdFmt[ GmfMaxKwd + 1 ][4] =
80 { {"Reserved", "", "", ""},
81 {"MeshVersionFormatted", "", "", "i"},
82 {"Reserved", "", "", ""},
83 {"Dimension", "", "", "i"},
84 {"Vertices", "Vertex", "i", "dri"},
85 {"Edges", "Edge", "i", "iii"},
86 {"Triangles", "Triangle", "i", "iiii"},
87 {"Quadrilaterals", "Quadrilateral", "i", "iiiii"},
88 {"Tetrahedra", "Tetrahedron", "i", "iiiii"},
89 {"Prisms", "Prism", "i", "iiiiiii"},
90 {"Hexahedra", "Hexahedron", "i", "iiiiiiiii"},
91 {"IterationsAll", "IterationAll","","i"},
92 {"TimesAll", "TimeAll","","r"},
93 {"Corners", "Corner", "i", "i"},
94 {"Ridges", "Ridge", "i", "i"},
95 {"RequiredVertices", "RequiredVertex", "i", "i"},
96 {"RequiredEdges", "RequiredEdge", "i", "i"},
97 {"RequiredTriangles", "RequiredTriangle", "i", "i"},
98 {"RequiredQuadrilaterals", "RequiredQuadrilateral", "i", "i"},
99 {"TangentAtEdgeVertices", "TangentAtEdgeVertex", "i", "iii"},
100 {"NormalAtVertices", "NormalAtVertex", "i", "ii"},
101 {"NormalAtTriangleVertices", "NormalAtTriangleVertex", "i", "iii"},
102 {"NormalAtQuadrilateralVertices", "NormalAtQuadrilateralVertex", "i", "iiii"},
103 {"AngleOfCornerBound", "", "", "r"},
104 {"TrianglesP2", "TriangleP2", "i", "iiiiiii"},
105 {"EdgesP2", "EdgeP2", "i", "iiii"},
106 {"SolAtPyramids", "SolAtPyramid", "i", "sr"},
107 {"QuadrilateralsQ2", "QuadrilateralQ2", "i", "iiiiiiiiii"},
108 {"ISolAtPyramids", "ISolAtPyramid", "i", "iiiii"},
109 {"Reserved", "", "", ""},
110 {"TetrahedraP2", "TetrahedronP2", "i", "iiiiiiiiiii"},
111 {"Reserved", "", "", ""},
112 {"Reserved", "", "", ""},
113 {"HexahedraQ2", "HexahedronQ2", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiii"},
114 {"Reserved", "", "", ""},
115 {"Reserved", "", "", ""},
116 {"Reserved", "", "", ""},
117 {"Reserved", "", "", ""},
118 {"Reserved", "", "", ""},
119 {"Reserved", "", "", ""},
120 {"Reserved", "", "", ""},
121 {"Reserved", "", "", ""},
122 {"Reserved", "", "", ""},
123 {"Reserved", "", "", ""},
124 {"Reserved", "", "", ""},
125 {"Reserved", "", "", ""},
126 {"Polyhedra", "Polyhedron", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
127 {"Polygons", "Polygon", "", "iiiiiiiii"},
128 {"Reserved", "", "", ""},
129 {"Pyramids", "Pyramid", "i", "iiiiii"},
130 {"BoundingBox", "", "", "drdr"},
131 {"Body","i", "drdrdrdr"},
132 {"PrivateTable", "PrivateTable", "i", "i"},
133 {"Reserved", "", "", ""},
135 {"Reserved", "", "", ""},
136 {"Reserved", "", "", ""},
137 {"Reserved", "", "", ""},
138 {"Reserved", "", "", ""},
139 {"Tangents", "Tangent", "i", "dr"},
140 {"Normals", "Normal", "i", "dr"},
141 {"TangentAtVertices", "TangentAtVertex", "i", "ii"},
142 {"SolAtVertices", "SolAtVertex", "i", "sr"},
143 {"SolAtEdges", "SolAtEdge", "i", "sr"},
144 {"SolAtTriangles", "SolAtTriangle", "i", "sr"},
145 {"SolAtQuadrilaterals", "SolAtQuadrilateral", "i", "sr"},
146 {"SolAtTetrahedra", "SolAtTetrahedron", "i", "sr"},
147 {"SolAtPrisms", "SolAtPrism", "i", "sr"},
148 {"SolAtHexahedra", "SolAtHexahedron", "i", "sr"},
149 {"DSolAtVertices", "DSolAtVertex", "i", "sr"},
150 {"ISolAtVertices", "ISolAtVertex", "i", "i"},
151 {"ISolAtEdges", "ISolAtEdge", "i", "ii"},
152 {"ISolAtTriangles", "ISolAtTriangle", "i", "iii"},
153 {"ISolAtQuadrilaterals", "ISolAtQuadrilateral", "i", "iiii"},
154 {"ISolAtTetrahedra", "ISolAtTetrahedron", "i", "iiii"},
155 {"ISolAtPrisms", "ISolAtPrism", "i", "iiiiii"},
156 {"ISolAtHexahedra", "ISolAtHexahedron", "i", "iiiiiiii"},
157 {"Iterations", "","","i"},
159 {"Reserved", "","",""}
163 /*----------------------------------------------------------*/
164 /* Prototypes of local procedures */
165 /*----------------------------------------------------------*/
167 static void ScaWrd(GmfMshSct *, unsigned char *);
168 static void ScaDblWrd(GmfMshSct *, unsigned char *);
169 static void ScaBlk(GmfMshSct *, unsigned char *, int);
170 static long GetPos(GmfMshSct *);
171 static void RecWrd(GmfMshSct *, unsigned char *);
172 static void RecDblWrd(GmfMshSct *, unsigned char *);
173 static void RecBlk(GmfMshSct *, unsigned char *, int);
174 static void SetPos(GmfMshSct *, long);
175 static int ScaKwdTab(GmfMshSct *);
176 static void ExpFmt(GmfMshSct *, int);
177 static void ScaKwdHdr(GmfMshSct *, int);
180 /*----------------------------------------------------------*/
181 /* Open a mesh file in read or write mod */
182 /*----------------------------------------------------------*/
184 int GmfOpenMesh(const char *FilNam, int mod, ...)
186 int i, KwdCod, res, *PtrVer, *PtrDim, MshIdx=0;
187 char str[ GmfStrSiz ];
193 for(i=0;i<=MaxMsh;i++)
199 /*---------------------*/
200 /* MESH STRUCTURE INIT */
201 /*---------------------*/
203 for(i=1;i<=MaxMsh;i++)
210 if( !MshIdx || !(msh = calloc(1, sizeof(GmfMshSct))) )
213 /* Copy the FilNam into the structure */
215 if(strlen(FilNam) + 7 >= GmfStrSiz)
218 strcpy(msh->FilNam, FilNam);
220 /* Store the opening mod (read or write) and guess the filetype (binary or ascii) depending on the extension */
223 msh->buf = (void *)msh->DblBuf;
224 msh->FltBuf = (void *)msh->DblBuf;
225 msh->IntBuf = (void *)msh->DblBuf;
227 if(strstr(msh->FilNam, ".meshb"))
228 msh->typ |= (Bin | MshFil);
229 else if(strstr(msh->FilNam, ".mesh"))
230 msh->typ |= (Asc | MshFil);
231 else if(strstr(msh->FilNam, ".solb"))
232 msh->typ |= (Bin | SolFil);
233 else if(strstr(msh->FilNam, ".sol"))
234 msh->typ |= (Asc | SolFil);
238 /* Open the file in the required mod and initialyse the mesh structure */
240 if(msh->mod == GmfRead)
243 /*-----------------------*/
244 /* OPEN FILE FOR READING */
245 /*-----------------------*/
247 va_start(VarArg, mod);
248 PtrVer = va_arg(VarArg, int *);
249 PtrDim = va_arg(VarArg, int *);
252 /* Create the name string and open the file */
254 if(!(msh->hdl = fopen(msh->FilNam, "rb")))
257 /* Read the endian coding tag, the mesh version and the mesh dimension (mandatory kwd) */
261 fread((unsigned char *)&msh->cod, WrdSiz, 1, msh->hdl);
263 if( (msh->cod != 1) && (msh->cod != 16777216) )
266 ScaWrd(msh, (unsigned char *)&msh->ver);
268 if( (msh->ver < 1) || (msh->ver > 3) )
271 if( (msh->ver == 3) && (sizeof(long) == 4) )
274 ScaWrd(msh, (unsigned char *)&KwdCod);
276 if(KwdCod != GmfDimension)
280 ScaWrd(msh, (unsigned char *)&msh->dim);
286 res = fscanf(msh->hdl, "%s", str);
287 }while( (res != EOF) && strcmp(str, "MeshVersionFormatted") );
292 fscanf(msh->hdl, "%d", &msh->ver);
294 if( (msh->ver < 1) || (msh->ver > 3) )
299 res = fscanf(msh->hdl, "%s", str);
300 }while( (res != EOF) && strcmp(str, "Dimension") );
305 fscanf(msh->hdl, "%d", &msh->dim);
308 if( (msh->dim != 2) && (msh->dim != 3) )
311 (*PtrVer) = msh->ver;
312 (*PtrDim) = msh->dim;
318 /* Read the list of kw present in the file */
323 GmfMshTab[ MshIdx ] = msh;
327 else if(msh->mod == GmfWrite)
330 /*-----------------------*/
331 /* OPEN FILE FOR WRITING */
332 /*-----------------------*/
336 /* Check if the user provided a valid version number and dimension */
338 va_start(VarArg, mod);
339 msh->ver = va_arg(VarArg, int);
340 msh->dim = va_arg(VarArg, int);
343 if( (msh->ver < 1) || (msh->ver > 3) )
346 if( (msh->ver == 3) && (sizeof(long) == 4) )
349 if( (msh->dim != 2) && (msh->dim != 3) )
352 /* Create the mesh file */
354 if(!(msh->hdl = fopen(msh->FilNam, "wb")))
357 GmfMshTab[ MshIdx ] = msh;
364 /* Write the mesh version and dimension */
368 fprintf(msh->hdl, "%s %d\n\n", GmfKwdFmt[ GmfVersionFormatted ][0], msh->ver);
369 fprintf(msh->hdl, "%s %d\n", GmfKwdFmt[ GmfDimension ][0], msh->dim);
373 RecWrd(msh, (unsigned char *)&msh->cod);
374 RecWrd(msh, (unsigned char *)&msh->ver);
375 GmfSetKwd(MshIdx, GmfDimension, 0);
376 RecWrd(msh, (unsigned char *)&msh->dim);
386 /*----------------------------------------------------------*/
387 /* Close a meshfile in the right way */
388 /*----------------------------------------------------------*/
390 int GmfCloseMesh(int MshIdx)
395 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
398 msh = GmfMshTab[ MshIdx ];
399 RecBlk(msh, msh->buf, 0);
401 /* In write down the "End" kw in write mode */
403 if(msh->mod == GmfWrite) {
405 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ GmfEnd ][0]);
407 GmfSetKwd(MshIdx, GmfEnd, 0);
410 /* Close the file and free the mesh structure */
416 GmfMshTab[ MshIdx ] = NULL;
422 /*----------------------------------------------------------*/
423 /* Read the number of lines and set the position to this kwd*/
424 /*----------------------------------------------------------*/
426 int GmfStatKwd(int MshIdx, int KwdCod, ...)
428 int i, *PtrNmbTyp, *PtrSolSiz, *TypTab;
433 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
436 msh = GmfMshTab[ MshIdx ];
438 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
441 kwd = &msh->KwdTab[ KwdCod ];
446 /* Read further arguments if this kw is a sol */
448 if(kwd->typ == SolKwd)
450 va_start(VarArg, KwdCod);
452 PtrNmbTyp = va_arg(VarArg, int *);
453 *PtrNmbTyp = kwd->NmbTyp;
455 PtrSolSiz = va_arg(VarArg, int *);
456 *PtrSolSiz = kwd->SolSiz;
458 TypTab = va_arg(VarArg, int *);
460 for(i=0;i<kwd->NmbTyp;i++)
461 TypTab[i] = kwd->TypTab[i];
470 /*----------------------------------------------------------*/
471 /* Set the current file position to a given kwd */
472 /*----------------------------------------------------------*/
474 int GmfGotoKwd(int MshIdx, int KwdCod)
479 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
482 msh = GmfMshTab[ MshIdx ];
484 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
487 kwd = &msh->KwdTab[ KwdCod ];
492 return(fseek(msh->hdl, kwd->pos, SEEK_SET));
496 /*----------------------------------------------------------*/
497 /* Write the kwd and set the number of lines */
498 /*----------------------------------------------------------*/
500 int GmfSetKwd(int MshIdx, int KwdCod, ...)
502 int i, NmbLin=0, *TypTab;
508 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
511 msh = GmfMshTab[ MshIdx ];
512 RecBlk(msh, msh->buf, 0);
514 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
517 kwd = &msh->KwdTab[ KwdCod ];
519 /* Read further arguments if this kw has a header */
521 if(strlen(GmfKwdFmt[ KwdCod ][2]))
523 va_start(VarArg, KwdCod);
524 NmbLin = va_arg(VarArg, int);
526 if(!strcmp(GmfKwdFmt[ KwdCod ][3], "sr"))
528 kwd->NmbTyp = va_arg(VarArg, int);
529 TypTab = va_arg(VarArg, int *);
531 for(i=0;i<kwd->NmbTyp;i++)
532 kwd->TypTab[i] = TypTab[i];
538 /* Setup the kwd info */
544 else if(kwd->typ == InfKwd)
547 kwd->NmbLin = NmbLin;
549 /* Store the next kwd position in binary file */
551 if( (msh->typ & Bin) && msh->NexKwdPos )
553 CurPos = ftell(msh->hdl);
554 fseek(msh->hdl, msh->NexKwdPos, SEEK_SET);
556 fseek(msh->hdl, CurPos, SEEK_SET);
559 /* Write the header */
563 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ KwdCod ][0]);
565 if(kwd->typ != InfKwd)
566 fprintf(msh->hdl, "%d\n", kwd->NmbLin);
568 /* In case of solution field, write the extended header */
570 if(kwd->typ == SolKwd)
572 fprintf(msh->hdl, "%d ", kwd->NmbTyp);
574 for(i=0;i<kwd->NmbTyp;i++)
575 fprintf(msh->hdl, "%d ", kwd->TypTab[i]);
577 fprintf(msh->hdl, "\n\n");
582 RecWrd(msh, (unsigned char *)&KwdCod);
583 msh->NexKwdPos = ftell(msh->hdl);
586 if(kwd->typ != InfKwd)
587 RecWrd(msh, (unsigned char *)&kwd->NmbLin);
589 /* In case of solution field, write the extended header at once */
591 if(kwd->typ == SolKwd)
593 RecWrd(msh, (unsigned char *)&kwd->NmbTyp);
595 for(i=0;i<kwd->NmbTyp;i++)
596 RecWrd(msh, (unsigned char *)&kwd->TypTab[i]);
604 /*----------------------------------------------------------*/
605 /* Read a full line from the current kwd */
606 /*----------------------------------------------------------*/
608 void GmfGetLin(int MshIdx, int KwdCod, ...)
614 GmfMshSct *msh = GmfMshTab[ MshIdx ];
615 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
617 /* Start decoding the arguments */
619 va_start(VarArg, KwdCod);
621 if(kwd->typ != SolKwd)
627 for(i=0;i<kwd->SolSiz;i++)
628 if(kwd->fmt[i] == 'r')
629 fscanf(msh->hdl, "%f", va_arg(VarArg, float *));
631 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
635 ScaBlk(msh, msh->buf, kwd->SolSiz);
637 for(i=0;i<kwd->SolSiz;i++)
638 if(kwd->fmt[i] == 'r')
639 *(va_arg(VarArg, float *)) = msh->FltBuf[i];
641 *(va_arg(VarArg, int *)) = msh->IntBuf[i];
648 for(i=0;i<kwd->SolSiz;i++)
649 if(kwd->fmt[i] == 'r')
650 fscanf(msh->hdl, "%lf", va_arg(VarArg, double *));
652 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
655 for(i=0;i<kwd->SolSiz;i++)
656 if(kwd->fmt[i] == 'r')
657 ScaDblWrd(msh, (unsigned char *)va_arg(VarArg, double *));
659 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
666 FltSolTab = va_arg(VarArg, float *);
669 for(j=0;j<kwd->SolSiz;j++)
670 fscanf(msh->hdl, "%f", &FltSolTab[j]);
672 ScaBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
676 DblSolTab = va_arg(VarArg, double *);
679 for(j=0;j<kwd->SolSiz;j++)
680 fscanf(msh->hdl, "%lf", &DblSolTab[j]);
682 for(j=0;j<kwd->SolSiz;j++)
683 ScaDblWrd(msh, (unsigned char *)&DblSolTab[j]);
691 /*----------------------------------------------------------*/
692 /* Write a full line from the current kwd */
693 /*----------------------------------------------------------*/
695 void GmfSetLin(int MshIdx, int KwdCod, ...)
697 int i, j, pos, *IntBuf;
699 double *DblSolTab, *DblBuf;
701 GmfMshSct *msh = GmfMshTab[ MshIdx ];
702 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
704 /* Start decoding the arguments */
706 va_start(VarArg, KwdCod);
708 if(kwd->typ != SolKwd)
714 for(i=0;i<kwd->SolSiz;i++)
715 if(kwd->fmt[i] == 'r')
716 fprintf(msh->hdl, "%g ", (float)va_arg(VarArg, double));
718 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
722 for(i=0;i<kwd->SolSiz;i++)
723 if(kwd->fmt[i] == 'r')
724 msh->FltBuf[i] = va_arg(VarArg, double);
726 msh->IntBuf[i] = va_arg(VarArg, int);
728 RecBlk(msh, msh->buf, kwd->SolSiz);
735 for(i=0;i<kwd->SolSiz;i++)
736 if(kwd->fmt[i] == 'r')
737 fprintf(msh->hdl, "%.15lg ", va_arg(VarArg, double));
739 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
745 for(i=0;i<kwd->SolSiz;i++)
746 if(kwd->fmt[i] == 'r')
748 DblBuf = (void *)&msh->buf[ pos ];
749 *DblBuf = va_arg(VarArg, double);
754 IntBuf = (void *)&msh->buf[ pos ];
755 *IntBuf = va_arg(VarArg, int);
758 RecBlk(msh, msh->buf, kwd->NmbWrd);
766 FltSolTab = va_arg(VarArg, float *);
769 for(j=0;j<kwd->SolSiz;j++)
770 fprintf(msh->hdl, "%g ", FltSolTab[j]);
772 RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
776 DblSolTab = va_arg(VarArg, double *);
779 for(j=0;j<kwd->SolSiz;j++)
780 fprintf(msh->hdl, "%.15lg ", DblSolTab[j]);
782 RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd);
789 fprintf(msh->hdl, "\n");
793 /*----------------------------------------------------------*/
794 /* Private procedure for transmesh : copy a whole line */
795 /*----------------------------------------------------------*/
797 void GmfCpyLin(int InpIdx, int OutIdx, int KwdCod)
802 GmfMshSct *InpMsh = GmfMshTab[ InpIdx ], *OutMsh = GmfMshTab[ OutIdx ];
803 KwdSct *kwd = &InpMsh->KwdTab[ KwdCod ];
805 for(i=0;i<kwd->SolSiz;i++)
807 if(kwd->fmt[i] == 'r')
811 if(InpMsh->typ & Asc)
812 fscanf(InpMsh->hdl, "%f", &f);
814 ScaWrd(InpMsh, (unsigned char *)&f);
820 if(InpMsh->typ & Asc)
821 fscanf(InpMsh->hdl, "%lf", &d);
823 ScaDblWrd(InpMsh, (unsigned char *)&d);
829 if(OutMsh->typ & Asc)
830 fprintf(OutMsh->hdl, "%g ", f);
832 RecWrd(OutMsh, (unsigned char *)&f);
834 if(OutMsh->typ & Asc)
835 fprintf(OutMsh->hdl, "%.15g ", d);
837 RecDblWrd(OutMsh, (unsigned char *)&d);
841 if(InpMsh->typ & Asc)
842 fscanf(InpMsh->hdl, "%d", &a);
844 ScaWrd(InpMsh, (unsigned char *)&a);
846 if(OutMsh->typ & Asc)
847 fprintf(OutMsh->hdl, "%d ", a);
849 RecWrd(OutMsh, (unsigned char *)&a);
853 if(OutMsh->typ & Asc)
854 fprintf(OutMsh->hdl, "\n");
858 /*----------------------------------------------------------*/
859 /* Find every kw present in a meshfile */
860 /*----------------------------------------------------------*/
862 static int ScaKwdTab(GmfMshSct *msh)
865 long NexPos, CurPos, EndPos;
866 char str[ GmfStrSiz ];
870 /* Scan each string in the file until the end */
872 while(fscanf(msh->hdl, "%s", str) != EOF)
874 /* Fast test in order to reject quickly the numeric values */
878 /* Search which kwd code this string is associated with,
879 then get its header and save the curent position in file (just before the data) */
881 for(KwdCod=1; KwdCod<= GmfMaxKwd; KwdCod++)
882 if(!strcmp(str, GmfKwdFmt[ KwdCod ][0]))
884 ScaKwdHdr(msh, KwdCod);
888 else if(str[0] == '#')
889 while(fgetc(msh->hdl) != '\n');
896 CurPos = ftell(msh->hdl);
897 fseek(msh->hdl, 0, SEEK_END);
898 EndPos = ftell(msh->hdl);
899 fseek(msh->hdl, CurPos, SEEK_SET);
901 /* Jump through kwd positions in the file */
905 /* Get the kwd code and the next kwd position */
907 ScaWrd(msh, (unsigned char *)&KwdCod);
908 NexPos = GetPos(msh);
913 /* Check if this kwd belongs to this mesh version */
915 if( (KwdCod >= 1) && (KwdCod <= GmfMaxKwd) )
916 ScaKwdHdr(msh, KwdCod);
918 /* Go to the next kwd */
921 fseek(msh->hdl, NexPos, SEEK_SET);
922 }while(NexPos && (KwdCod != GmfEnd));
929 /*----------------------------------------------------------*/
930 /* Read and setup the keyword's header */
931 /*----------------------------------------------------------*/
933 static void ScaKwdHdr(GmfMshSct *msh, int KwdCod)
936 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
938 if(!strcmp("i", GmfKwdFmt[ KwdCod ][2]))
941 fscanf(msh->hdl, "%d", &kwd->NmbLin);
943 ScaWrd(msh, (unsigned char *)&kwd->NmbLin);
948 if(!strcmp("sr", GmfKwdFmt[ KwdCod ][3]))
952 fscanf(msh->hdl, "%d", &kwd->NmbTyp);
954 for(i=0;i<kwd->NmbTyp;i++)
955 fscanf(msh->hdl, "%d", &kwd->TypTab[i]);
959 ScaWrd(msh, (unsigned char *)&kwd->NmbTyp);
961 for(i=0;i<kwd->NmbTyp;i++)
962 ScaWrd(msh, (unsigned char *)&kwd->TypTab[i]);
967 kwd->pos = ftell(msh->hdl);
971 /*----------------------------------------------------------*/
972 /* Expand the compacted format and compute the line size */
973 /*----------------------------------------------------------*/
975 static void ExpFmt(GmfMshSct *msh, int KwdCod)
978 char chr, *InpFmt = GmfKwdFmt[ KwdCod ][3];
979 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
981 /* Set the kwd's type */
983 if(!strlen(GmfKwdFmt[ KwdCod ][2]))
985 else if(!strcmp(InpFmt, "sr"))
990 /* Get the solution-field's size */
992 if(kwd->typ == SolKwd)
993 for(i=0;i<kwd->NmbTyp;i++)
994 switch(kwd->TypTab[i])
996 case GmfSca : TmpSiz += 1; break;
997 case GmfVec : TmpSiz += msh->dim; break;
998 case GmfSymMat : TmpSiz += (msh->dim * (msh->dim+1)) / 2; break;
999 case GmfMat : TmpSiz += msh->dim * msh->dim; break;
1002 /* Scan each character from the format string */
1004 i = kwd->SolSiz = kwd->NmbWrd = 0;
1006 while(i < strlen(InpFmt))
1008 chr = InpFmt[ i++ ];
1014 for(j=0;j<msh->dim;j++)
1015 kwd->fmt[ kwd->SolSiz++ ] = chr;
1021 for(j=0;j<TmpSiz;j++)
1022 kwd->fmt[ kwd->SolSiz++ ] = chr;
1025 kwd->fmt[ kwd->SolSiz++ ] = chr;
1028 for(i=0;i<kwd->SolSiz;i++)
1029 if(kwd->fmt[i] == 'i')
1031 else if(msh->ver >= 2)
1038 /*----------------------------------------------------------*/
1039 /* Read a four bytes word from a mesh file */
1040 /*----------------------------------------------------------*/
1042 static void ScaWrd(GmfMshSct *msh, unsigned char *wrd)
1046 fread(wrd, WrdSiz, 1, msh->hdl);
1061 /*----------------------------------------------------------*/
1062 /* Read an eight bytes word from a mesh file */
1063 /*----------------------------------------------------------*/
1065 static void ScaDblWrd(GmfMshSct *msh, unsigned char *wrd)
1070 fread(wrd, WrdSiz, 2, msh->hdl);
1084 /*----------------------------------------------------------*/
1085 /* Read ablock of four bytes word from a mesh file */
1086 /*----------------------------------------------------------*/
1088 static void ScaBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1091 unsigned char swp, *wrd;
1093 fread(blk, WrdSiz, siz, msh->hdl);
1100 wrd = &blk[ i * 4 ];
1105 wrd[ 3-j ] = wrd[j];
1112 /*----------------------------------------------------------*/
1113 /* Read a 4 or 8 bytes position in mesh file */
1114 /*----------------------------------------------------------*/
1116 static long GetPos(GmfMshSct *msh)
1122 ScaDblWrd(msh, (unsigned char*)&pos);
1125 ScaWrd(msh, (unsigned char*)&IntVal);
1133 /*----------------------------------------------------------*/
1134 /* Write a four bytes word to a mesh file */
1135 /*----------------------------------------------------------*/
1137 static void RecWrd(GmfMshSct *msh, unsigned char *wrd)
1139 fwrite(wrd, WrdSiz, 1, msh->hdl);
1143 /*----------------------------------------------------------*/
1144 /* Write an eight bytes word to a mesh file */
1145 /*----------------------------------------------------------*/
1147 static void RecDblWrd(GmfMshSct *msh, unsigned char *wrd)
1149 fwrite(wrd, WrdSiz, 2, msh->hdl);
1153 /*----------------------------------------------------------*/
1154 /* Write a block of four bytes word to a mesh file */
1155 /*----------------------------------------------------------*/
1157 static void RecBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1159 /* Copy this line-block into the main mesh buffer */
1163 memcpy(&msh->blk[ msh->pos ], blk, siz * WrdSiz);
1164 msh->pos += siz * WrdSiz;
1167 /* When the buffer is full or this procedure is called with a 0 size, flush the cache on disk */
1169 if( (msh->pos > BufSiz) || (!siz && msh->pos) )
1171 fwrite(msh->blk, 1, msh->pos, msh->hdl);
1177 /*----------------------------------------------------------*/
1178 /* Read a 4 or 8 bytes position in mesh file */
1179 /*----------------------------------------------------------*/
1181 static void SetPos(GmfMshSct *msh, long pos)
1186 RecDblWrd(msh, (unsigned char*)&pos);
1190 RecWrd(msh, (unsigned char*)&IntVal);