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 /*----------------------------------------------------------*/
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 /*----------------------------------------------------------*/
77 static int GmfIniFlg=0;
78 static GmfMshSct *GmfMshTab[ MaxMsh + 1 ];
79 static const 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 {"SubDomainFromGeom", "SubDomainFromGeom", "i", "iiii"},
110 {"TetrahedraP2", "TetrahedronP2", "i", "iiiiiiiiiii"},
111 {"Fault_NearTri", "Fault_NearTri", "i", "i"},
112 {"Fault_Inter", "Fault_Inter", "i", "i"},
113 {"HexahedraQ2", "HexahedronQ2", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiii"},
114 {"ExtraVerticesAtEdges", "ExtraVerticesAtEdge", "i", "in"},
115 {"ExtraVerticesAtTriangles", "ExtraVerticesAtTriangle", "i", "in"},
116 {"ExtraVerticesAtQuadrilaterals", "ExtraVerticesAtQuadrilateral", "i", "in"},
117 {"ExtraVerticesAtTetrahedra", "ExtraVerticesAtTetrahedron", "i", "in"},
118 {"ExtraVerticesAtPrisms", "ExtraVerticesAtPrism", "i", "in"},
119 {"ExtraVerticesAtHexahedra", "ExtraVerticesAtHexahedron", "i", "in"},
120 {"VerticesOnGeometricVertices", "VertexOnGeometricVertex", "i", "iir"},
121 {"VerticesOnGeometricEdges", "VertexOnGeometricEdge", "i", "iirr"},
122 {"VerticesOnGeometricTriangles", "VertexOnGeometricTriangle", "i", "iirrr"},
123 {"VerticesOnGeometricQuadrilaterals", "VertexOnGeometricQuadrilateral", "i", "iirrr"},
124 {"EdgesOnGeometricEdges", "EdgeOnGeometricEdge", "i", "iir"},
125 {"Fault_FreeEdge", "Fault_FreeEdge", "i", "i"},
126 {"Polyhedra", "Polyhedron", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
127 {"Polygons", "Polygon", "", "iiiiiiiii"},
128 {"Fault_Overlap", "Fault_Overlap", "i", "i"},
129 {"Pyramids", "Pyramid", "i", "iiiiii"},
130 {"BoundingBox", "", "", "drdr"},
131 {"Body","i", "drdrdrdr"},
132 {"PrivateTable", "PrivateTable", "i", "i"},
133 {"Fault_BadShape", "Fault_BadShape", "i", "i"},
135 {"TrianglesOnGeometricTriangles", "TriangleOnGeometricTriangle", "i", "iir"},
136 {"TrianglesOnGeometricQuadrilaterals", "TriangleOnGeometricQuadrilateral", "i", "iir"},
137 {"QuadrilateralsOnGeometricTriangles", "QuadrilateralOnGeometricTriangle", "i", "iir"},
138 {"QuadrilateralsOnGeometricQuadrilaterals", "QuadrilateralOnGeometricQuadrilateral", "i", "iir"},
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 {"Fault_SmallTri", "Fault_SmallTri","i","i"},
160 {"CoarseHexahedra", "CoarseHexahedron", "i", "i"}
164 /*----------------------------------------------------------*/
165 /* Prototypes of local procedures */
166 /*----------------------------------------------------------*/
168 static void ScaWrd(GmfMshSct *, unsigned char *);
169 static void ScaDblWrd(GmfMshSct *, unsigned char *);
170 static void ScaBlk(GmfMshSct *, unsigned char *, int);
171 static long GetPos(GmfMshSct *);
172 static void RecWrd(GmfMshSct *, unsigned char *);
173 static void RecDblWrd(GmfMshSct *, unsigned char *);
174 static void RecBlk(GmfMshSct *, unsigned char *, int);
175 static void SetPos(GmfMshSct *, long);
176 static int ScaKwdTab(GmfMshSct *);
177 static void ExpFmt(GmfMshSct *, int);
178 static void ScaKwdHdr(GmfMshSct *, int);
181 /*----------------------------------------------------------*/
182 /* Open a mesh file in read or write mod */
183 /*----------------------------------------------------------*/
185 int GmfOpenMesh(const char *FilNam, int mod, ...)
187 int i, KwdCod, res, *PtrVer, *PtrDim, MshIdx=0;
188 char str[ GmfStrSiz ];
196 for(i=0;i<=MaxMsh;i++)
202 /*---------------------*/
203 /* MESH STRUCTURE INIT */
204 /*---------------------*/
206 for(i=1;i<=MaxMsh;i++)
213 if( !MshIdx || !(msh = calloc(1, sizeof(GmfMshSct))) )
216 /* Copy the FilNam into the structure */
218 if(strlen(FilNam) + 7 >= GmfStrSiz)
224 strcpy(msh->FilNam, FilNam);
226 /* Store the opening mod (read or write) and guess the filetype (binary or ascii) depending on the extension */
229 msh->buf = (unsigned char *)msh->DblBuf;
230 msh->FltBuf = (float *)msh->DblBuf;
231 msh->IntBuf = (int *)msh->DblBuf;
233 k = strlen(msh->FilNam) - 6;
237 if(strstr(ptr, ".meshb"))
238 msh->typ |= (Bin | MshFil);
239 else if(strstr(ptr, ".mesh"))
240 msh->typ |= (Asc | MshFil);
241 else if(strstr(ptr, ".solb"))
242 msh->typ |= (Bin | SolFil);
243 else if(strstr(ptr, ".sol"))
244 msh->typ |= (Asc | SolFil);
250 /* Open the file in the required mod and initialyse the mesh structure */
252 if(msh->mod == GmfRead)
255 /*-----------------------*/
256 /* OPEN FILE FOR READING */
257 /*-----------------------*/
259 va_start(VarArg, mod);
260 PtrVer = va_arg(VarArg, int *);
261 PtrDim = va_arg(VarArg, int *);
264 /* Create the name string and open the file */
266 if(!(msh->hdl = fopen(msh->FilNam, "rb")))
272 /* Read the endian coding tag, the mesh version and the mesh dimension (mandatory kwd) */
276 fread((unsigned char *)&msh->cod, WrdSiz, 1, msh->hdl);
278 if( (msh->cod != 1) && (msh->cod != 16777216) )
284 ScaWrd(msh, (unsigned char *)&msh->ver);
286 if( (msh->ver < 1) || (msh->ver > 3) )
292 if( (msh->ver == 3) && (sizeof(long) == 4) )
298 ScaWrd(msh, (unsigned char *)&KwdCod);
300 if(KwdCod != GmfDimension)
307 ScaWrd(msh, (unsigned char *)&msh->dim);
313 res = fscanf(msh->hdl, "%s", str);
314 }while( (res != EOF) && strcmp(str, "MeshVersionFormatted") );
322 fscanf(msh->hdl, "%d", &msh->ver);
324 if( (msh->ver < 1) || (msh->ver > 3) )
332 res = fscanf(msh->hdl, "%s", str);
333 }while( (res != EOF) && strcmp(str, "Dimension") );
341 fscanf(msh->hdl, "%d", &msh->dim);
344 if( (msh->dim != 2) && (msh->dim != 3) )
350 (*PtrVer) = msh->ver;
351 (*PtrDim) = msh->dim;
357 /* Read the list of kw present in the file */
365 GmfMshTab[ MshIdx ] = msh;
369 else if(msh->mod == GmfWrite)
372 /*-----------------------*/
373 /* OPEN FILE FOR WRITING */
374 /*-----------------------*/
378 /* Check if the user provided a valid version number and dimension */
380 va_start(VarArg, mod);
381 msh->ver = va_arg(VarArg, int);
382 msh->dim = va_arg(VarArg, int);
385 if( (msh->ver < 1) || (msh->ver > 3) )
391 if( (msh->ver == 3) && (sizeof(long) == 4) )
397 if( (msh->dim != 2) && (msh->dim != 3) )
403 /* Create the mesh file */
405 if(!(msh->hdl = fopen(msh->FilNam, "wb")))
411 GmfMshTab[ MshIdx ] = msh;
418 /* Write the mesh version and dimension */
422 fprintf(msh->hdl, "%s %d\n\n", GmfKwdFmt[ GmfVersionFormatted ][0], msh->ver);
423 fprintf(msh->hdl, "%s %d\n", GmfKwdFmt[ GmfDimension ][0], msh->dim);
427 RecWrd(msh, (unsigned char *)&msh->cod);
428 RecWrd(msh, (unsigned char *)&msh->ver);
429 GmfSetKwd(MshIdx, GmfDimension, 0);
430 RecWrd(msh, (unsigned char *)&msh->dim);
443 /*----------------------------------------------------------*/
444 /* Close a meshfile in the right way */
445 /*----------------------------------------------------------*/
447 int GmfCloseMesh(int MshIdx)
452 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
455 msh = GmfMshTab[ MshIdx ];
456 RecBlk(msh, msh->buf, 0);
458 /* In write down the "End" kw in write mode */
460 if(msh->mod == GmfWrite){
462 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ GmfEnd ][0]);
464 GmfSetKwd(MshIdx, GmfEnd, 0);
466 /* Close the file and free the mesh structure */
472 GmfMshTab[ MshIdx ] = NULL;
478 /*----------------------------------------------------------*/
479 /* Read the number of lines and set the position to this kwd*/
480 /*----------------------------------------------------------*/
482 int GmfStatKwd(int MshIdx, int KwdCod, ...)
484 int i, *PtrNmbTyp, *PtrSolSiz, *TypTab;
489 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
492 msh = GmfMshTab[ MshIdx ];
494 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
497 kwd = &msh->KwdTab[ KwdCod ];
502 /* Read further arguments if this kw is a sol */
504 if(kwd->typ == SolKwd)
506 va_start(VarArg, KwdCod);
508 PtrNmbTyp = va_arg(VarArg, int *);
509 *PtrNmbTyp = kwd->NmbTyp;
511 PtrSolSiz = va_arg(VarArg, int *);
512 *PtrSolSiz = kwd->SolSiz;
514 TypTab = va_arg(VarArg, int *);
516 for(i=0;i<kwd->NmbTyp;i++)
517 TypTab[i] = kwd->TypTab[i];
526 /*----------------------------------------------------------*/
527 /* Set the current file position to a given kwd */
528 /*----------------------------------------------------------*/
530 int GmfGotoKwd(int MshIdx, int KwdCod)
535 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
538 msh = GmfMshTab[ MshIdx ];
540 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
543 kwd = &msh->KwdTab[ KwdCod ];
548 return(fseek(msh->hdl, kwd->pos, SEEK_SET));
552 /*----------------------------------------------------------*/
553 /* Write the kwd and set the number of lines */
554 /*----------------------------------------------------------*/
556 int GmfSetKwd(int MshIdx, int KwdCod, ...)
558 int i, NmbLin=0, *TypTab;
564 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
567 msh = GmfMshTab[ MshIdx ];
568 RecBlk(msh, msh->buf, 0);
570 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
573 kwd = &msh->KwdTab[ KwdCod ];
575 /* Read further arguments if this kw has a header */
577 if(strlen(GmfKwdFmt[ KwdCod ][2]))
579 va_start(VarArg, KwdCod);
580 NmbLin = va_arg(VarArg, int);
582 if(!strcmp(GmfKwdFmt[ KwdCod ][3], "sr"))
584 kwd->NmbTyp = va_arg(VarArg, int);
585 TypTab = va_arg(VarArg, int *);
587 for(i=0;i<kwd->NmbTyp;i++)
588 kwd->TypTab[i] = TypTab[i];
594 /* Setup the kwd info */
600 else if(kwd->typ == InfKwd)
603 kwd->NmbLin = NmbLin;
605 /* Store the next kwd position in binary file */
607 if( (msh->typ & Bin) && msh->NexKwdPos )
609 CurPos = ftell(msh->hdl);
610 fseek(msh->hdl, msh->NexKwdPos, SEEK_SET);
612 fseek(msh->hdl, CurPos, SEEK_SET);
615 /* Write the header */
619 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ KwdCod ][0]);
621 if(kwd->typ != InfKwd)
622 fprintf(msh->hdl, "%d\n", kwd->NmbLin);
624 /* In case of solution field, write the extended header */
626 if(kwd->typ == SolKwd)
628 fprintf(msh->hdl, "%d ", kwd->NmbTyp);
630 for(i=0;i<kwd->NmbTyp;i++)
631 fprintf(msh->hdl, "%d ", kwd->TypTab[i]);
633 fprintf(msh->hdl, "\n\n");
638 RecWrd(msh, (unsigned char *)&KwdCod);
639 msh->NexKwdPos = ftell(msh->hdl);
642 if(kwd->typ != InfKwd)
643 RecWrd(msh, (unsigned char *)&kwd->NmbLin);
645 /* In case of solution field, write the extended header at once */
647 if(kwd->typ == SolKwd)
649 RecWrd(msh, (unsigned char *)&kwd->NmbTyp);
651 for(i=0;i<kwd->NmbTyp;i++)
652 RecWrd(msh, (unsigned char *)&kwd->TypTab[i]);
656 /* Reset write buffer position */
659 /* Estimate the total file size and check whether it crosses the 2GB threshold */
661 msh->siz += kwd->NmbLin * kwd->NmbWrd * WrdSiz;
670 /*----------------------------------------------------------*/
671 /* Read a full line from the current kwd */
672 /*----------------------------------------------------------*/
674 void GmfGetLin(int MshIdx, int KwdCod, ...)
680 GmfMshSct *msh = GmfMshTab[ MshIdx ];
681 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
683 /* Start decoding the arguments */
685 va_start(VarArg, KwdCod);
687 if(kwd->typ != SolKwd)
689 int k, nb_repeat = 0;
695 for(i=0;i<kwd->SolSiz;i++)
696 if(kwd->fmt[i] == 'r')
697 fscanf(msh->hdl, "%f", va_arg(VarArg, float *));
698 else if(kwd->fmt[i] == 'n') {
699 fscanf(msh->hdl, "%d", &nb_repeat);
700 *(va_arg(VarArg, int *)) = nb_repeat;
701 for(k=0;k<nb_repeat;k++)
702 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
705 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
709 for(i=0;i<kwd->SolSiz;i++)
710 if(kwd->fmt[i] == 'r')
711 ScaWrd(msh, (unsigned char *)va_arg(VarArg, float *));
712 else if(kwd->fmt[i] == 'n') {
713 ScaWrd(msh, (unsigned char *)&nb_repeat);
714 *(va_arg(VarArg, int *)) = nb_repeat;
715 for(k=0;k<nb_repeat;k++)
716 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
719 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
726 for(i=0;i<kwd->SolSiz;i++)
727 if(kwd->fmt[i] == 'r')
728 fscanf(msh->hdl, "%lf", va_arg(VarArg, double *));
729 else if(kwd->fmt[i] == 'n') {
730 fscanf(msh->hdl, "%d", &nb_repeat);
731 *(va_arg(VarArg, int *)) = nb_repeat;
732 for(k=0;k<nb_repeat;k++)
733 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
736 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
739 for(i=0;i<kwd->SolSiz;i++)
740 if(kwd->fmt[i] == 'r')
741 ScaDblWrd(msh, (unsigned char *)va_arg(VarArg, double *));
742 else if(kwd->fmt[i] == 'n') {
743 ScaWrd(msh, (unsigned char *)&nb_repeat);
744 *(va_arg(VarArg, int *)) = nb_repeat;
745 for(k=0;k<nb_repeat;k++)
746 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
749 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
756 FltSolTab = va_arg(VarArg, float *);
759 for(j=0;j<kwd->SolSiz;j++)
760 fscanf(msh->hdl, "%f", &FltSolTab[j]);
762 ScaBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
766 DblSolTab = va_arg(VarArg, double *);
769 for(j=0;j<kwd->SolSiz;j++)
770 fscanf(msh->hdl, "%lf", &DblSolTab[j]);
772 for(j=0;j<kwd->SolSiz;j++)
773 ScaDblWrd(msh, (unsigned char *)&DblSolTab[j]);
781 /*----------------------------------------------------------*/
782 /* Write a full line from the current kwd */
783 /*----------------------------------------------------------*/
785 void GmfSetLin(int MshIdx, int KwdCod, ...)
787 int i, j, pos, *IntBuf;
789 double *DblSolTab, *DblBuf;
791 GmfMshSct *msh = GmfMshTab[ MshIdx ];
792 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
794 /* Start decoding the arguments */
796 va_start(VarArg, KwdCod);
798 if(kwd->typ != SolKwd)
800 int k, nb_repeat = 0;
806 for(i=0;i<kwd->SolSiz;i++)
807 if(kwd->fmt[i] == 'r')
808 fprintf(msh->hdl, "%g ", (float)va_arg(VarArg, double));
809 else if(kwd->fmt[i] == 'n') {
810 nb_repeat = va_arg(VarArg, int);
811 fprintf(msh->hdl, "%d ", nb_repeat);
812 for(k=0;k<nb_repeat;k++)
813 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
816 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
820 int size_of_block = kwd->SolSiz;
821 for(i=0;i<kwd->SolSiz;i++)
822 if(kwd->fmt[i] == 'r')
823 msh->FltBuf[i] = va_arg(VarArg, double);
824 else if(kwd->fmt[i] == 'n') {
825 nb_repeat = va_arg(VarArg, int);
826 msh->FltBuf[i] = nb_repeat;
827 for(k=0;k<nb_repeat;k++) {
828 msh->IntBuf[i+1+k] = va_arg(VarArg, int);
833 msh->IntBuf[i] = va_arg(VarArg, int);
835 RecBlk(msh, msh->buf, size_of_block);
842 for(i=0;i<kwd->SolSiz;i++)
843 if(kwd->fmt[i] == 'r')
844 fprintf(msh->hdl, "%.15lg ", va_arg(VarArg, double));
845 else if(kwd->fmt[i] == 'n') {
846 nb_repeat = va_arg(VarArg, int);
847 fprintf(msh->hdl, "%d ", nb_repeat);
848 for(k=0;k<nb_repeat;k++)
849 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
852 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
858 for(i=0;i<kwd->SolSiz;i++)
859 if(kwd->fmt[i] == 'r')
861 DblBuf = (double *)&msh->buf[ pos ];
862 *DblBuf = va_arg(VarArg, double);
865 else if(kwd->fmt[i] == 'n')
867 IntBuf = (int *)&msh->buf[ pos ];
868 nb_repeat = va_arg(VarArg, int);
871 for(k=0;k<nb_repeat;k++) {
872 IntBuf = (int *)&msh->buf[ pos ];
873 *IntBuf = va_arg(VarArg, int);
879 IntBuf = (int *)&msh->buf[ pos ];
880 *IntBuf = va_arg(VarArg, int);
883 RecBlk(msh, msh->buf, pos/4);
891 FltSolTab = va_arg(VarArg, float *);
894 for(j=0;j<kwd->SolSiz;j++)
895 fprintf(msh->hdl, "%g ", FltSolTab[j]);
897 RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
901 DblSolTab = va_arg(VarArg, double *);
904 for(j=0;j<kwd->SolSiz;j++)
905 fprintf(msh->hdl, "%.15lg ", DblSolTab[j]);
907 RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd);
914 fprintf(msh->hdl, "\n");
918 /*----------------------------------------------------------*/
919 /* Private procedure for transmesh : copy a whole line */
920 /*----------------------------------------------------------*/
922 void GmfCpyLin(int InpIdx, int OutIdx, int KwdCod)
927 GmfMshSct *InpMsh = GmfMshTab[ InpIdx ], *OutMsh = GmfMshTab[ OutIdx ];
928 KwdSct *kwd = &InpMsh->KwdTab[ KwdCod ];
930 for(i=0;i<kwd->SolSiz;i++)
932 if(kwd->fmt[i] == 'r')
936 if(InpMsh->typ & Asc)
937 fscanf(InpMsh->hdl, "%f", &f);
939 ScaWrd(InpMsh, (unsigned char *)&f);
945 if(InpMsh->typ & Asc)
946 fscanf(InpMsh->hdl, "%lf", &d);
948 ScaDblWrd(InpMsh, (unsigned char *)&d);
954 if(OutMsh->typ & Asc)
955 fprintf(OutMsh->hdl, "%g ", f);
957 RecWrd(OutMsh, (unsigned char *)&f);
959 if(OutMsh->typ & Asc)
960 fprintf(OutMsh->hdl, "%.15g ", d);
962 RecDblWrd(OutMsh, (unsigned char *)&d);
964 else if(kwd->fmt[i] == 'n')
966 int k, nb_repeat = 0;
968 if(InpMsh->typ & Asc)
969 fscanf(InpMsh->hdl, "%d", &a);
971 ScaWrd(InpMsh, (unsigned char *)&a);
975 if(OutMsh->typ & Asc)
976 fprintf(OutMsh->hdl, "%d ", a);
978 RecWrd(OutMsh, (unsigned char *)&a);
980 for(k=0;k<nb_repeat;k++) {
981 if(InpMsh->typ & Asc)
982 fscanf(InpMsh->hdl, "%d", &a);
984 ScaWrd(InpMsh, (unsigned char *)&a);
986 if(OutMsh->typ & Asc)
987 fprintf(OutMsh->hdl, "%d ", a);
989 RecWrd(OutMsh, (unsigned char *)&a);
994 if(InpMsh->typ & Asc)
995 fscanf(InpMsh->hdl, "%d", &a);
997 ScaWrd(InpMsh, (unsigned char *)&a);
999 if(OutMsh->typ & Asc)
1000 fprintf(OutMsh->hdl, "%d ", a);
1002 RecWrd(OutMsh, (unsigned char *)&a);
1006 if(OutMsh->typ & Asc)
1007 fprintf(OutMsh->hdl, "\n");
1011 /*----------------------------------------------------------*/
1012 /* Find every kw present in a meshfile */
1013 /*----------------------------------------------------------*/
1015 static int ScaKwdTab(GmfMshSct *msh)
1018 long NexPos, CurPos, EndPos;
1019 char str[ GmfStrSiz ];
1023 /* Scan each string in the file until the end */
1025 while(fscanf(msh->hdl, "%s", str) != EOF)
1027 /* Fast test in order to reject quickly the numeric values */
1031 /* Search which kwd code this string is associated with,
1032 then get its header and save the curent position in file (just before the data) */
1034 for(KwdCod=1; KwdCod<= GmfMaxKwd; KwdCod++)
1035 if(!strcmp(str, GmfKwdFmt[ KwdCod ][0]))
1037 ScaKwdHdr(msh, KwdCod);
1041 else if(str[0] == '#')
1042 while(fgetc(msh->hdl) != '\n');
1049 CurPos = ftell(msh->hdl);
1050 fseek(msh->hdl, 0, SEEK_END);
1051 EndPos = ftell(msh->hdl);
1052 fseek(msh->hdl, CurPos, SEEK_SET);
1054 /* Jump through kwd positions in the file */
1058 /* Get the kwd code and the next kwd position */
1060 ScaWrd(msh, (unsigned char *)&KwdCod);
1061 NexPos = GetPos(msh);
1066 /* Check if this kwd belongs to this mesh version */
1068 if( (KwdCod >= 1) && (KwdCod <= GmfMaxKwd) )
1069 ScaKwdHdr(msh, KwdCod);
1071 /* Go to the next kwd */
1074 fseek(msh->hdl, NexPos, SEEK_SET);
1075 }while(NexPos && (KwdCod != GmfEnd));
1082 /*----------------------------------------------------------*/
1083 /* Read and setup the keyword's header */
1084 /*----------------------------------------------------------*/
1086 static void ScaKwdHdr(GmfMshSct *msh, int KwdCod)
1089 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1091 if(!strcmp("i", GmfKwdFmt[ KwdCod ][2]))
1094 fscanf(msh->hdl, "%d", &kwd->NmbLin);
1096 ScaWrd(msh, (unsigned char *)&kwd->NmbLin);
1101 if(!strcmp("sr", GmfKwdFmt[ KwdCod ][3]))
1105 fscanf(msh->hdl, "%d", &kwd->NmbTyp);
1107 for(i=0;i<kwd->NmbTyp;i++)
1108 fscanf(msh->hdl, "%d", &kwd->TypTab[i]);
1112 ScaWrd(msh, (unsigned char *)&kwd->NmbTyp);
1114 for(i=0;i<kwd->NmbTyp;i++)
1115 ScaWrd(msh, (unsigned char *)&kwd->TypTab[i]);
1119 ExpFmt(msh, KwdCod);
1120 kwd->pos = ftell(msh->hdl);
1124 /*----------------------------------------------------------*/
1125 /* Expand the compacted format and compute the line size */
1126 /*----------------------------------------------------------*/
1128 static void ExpFmt(GmfMshSct *msh, int KwdCod)
1132 const char *InpFmt = GmfKwdFmt[ KwdCod ][3];
1133 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1135 /* Set the kwd's type */
1137 if(!strlen(GmfKwdFmt[ KwdCod ][2]))
1139 else if(!strcmp(InpFmt, "sr"))
1144 /* Get the solution-field's size */
1146 if(kwd->typ == SolKwd)
1147 for(i=0;i<kwd->NmbTyp;i++)
1148 switch(kwd->TypTab[i])
1150 case GmfSca : TmpSiz += 1; break;
1151 case GmfVec : TmpSiz += msh->dim; break;
1152 case GmfSymMat : TmpSiz += (msh->dim * (msh->dim+1)) / 2; break;
1153 case GmfMat : TmpSiz += msh->dim * msh->dim; break;
1156 /* Scan each character from the format string */
1158 i = kwd->SolSiz = kwd->NmbWrd = 0;
1160 while(i < strlen(InpFmt))
1162 chr = InpFmt[ i++ ];
1168 for(j=0;j<msh->dim;j++)
1169 kwd->fmt[ kwd->SolSiz++ ] = chr;
1175 for(j=0;j<TmpSiz;j++)
1176 kwd->fmt[ kwd->SolSiz++ ] = chr;
1179 kwd->fmt[ kwd->SolSiz++ ] = chr;
1182 for(i=0;i<kwd->SolSiz;i++)
1183 if(kwd->fmt[i] == 'i')
1185 else if(msh->ver >= 2)
1192 /*----------------------------------------------------------*/
1193 /* Read a four bytes word from a mesh file */
1194 /*----------------------------------------------------------*/
1196 static void ScaWrd(GmfMshSct *msh, unsigned char *wrd)
1200 fread(wrd, WrdSiz, 1, msh->hdl);
1215 /*----------------------------------------------------------*/
1216 /* Read an eight bytes word from a mesh file */
1217 /*----------------------------------------------------------*/
1219 static void ScaDblWrd(GmfMshSct *msh, unsigned char *wrd)
1224 fread(wrd, WrdSiz, 2, msh->hdl);
1238 /*----------------------------------------------------------*/
1239 /* Read ablock of four bytes word from a mesh file */
1240 /*----------------------------------------------------------*/
1242 static void ScaBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1245 unsigned char swp, *wrd;
1247 fread(blk, WrdSiz, siz, msh->hdl);
1254 wrd = &blk[ i * 4 ];
1259 wrd[ 3-j ] = wrd[j];
1266 /*----------------------------------------------------------*/
1267 /* Read a 4 or 8 bytes position in mesh file */
1268 /*----------------------------------------------------------*/
1270 static long GetPos(GmfMshSct *msh)
1276 ScaDblWrd(msh, (unsigned char*)&pos);
1279 ScaWrd(msh, (unsigned char*)&IntVal);
1287 /*----------------------------------------------------------*/
1288 /* Write a four bytes word to a mesh file */
1289 /*----------------------------------------------------------*/
1291 static void RecWrd(GmfMshSct *msh, unsigned char *wrd)
1293 fwrite(wrd, WrdSiz, 1, msh->hdl);
1297 /*----------------------------------------------------------*/
1298 /* Write an eight bytes word to a mesh file */
1299 /*----------------------------------------------------------*/
1301 static void RecDblWrd(GmfMshSct *msh, unsigned char *wrd)
1303 fwrite(wrd, WrdSiz, 2, msh->hdl);
1307 /*----------------------------------------------------------*/
1308 /* Write a block of four bytes word to a mesh file */
1309 /*----------------------------------------------------------*/
1311 static void RecBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1313 /* Copy this line-block into the main mesh buffer */
1317 memcpy(&msh->blk[ msh->pos ], blk, siz * WrdSiz);
1318 msh->pos += siz * WrdSiz;
1321 /* When the buffer is full or this procedure is called with a 0 size, flush the cache on disk */
1323 if( (msh->pos > BufSiz) || (!siz && msh->pos) )
1325 fwrite(msh->blk, 1, msh->pos, msh->hdl);
1331 /*----------------------------------------------------------*/
1332 /* Write a 4 or 8 bytes position in a mesh file */
1333 /*----------------------------------------------------------*/
1335 static void SetPos(GmfMshSct *msh, long pos)
1340 RecDblWrd(msh, (unsigned char*)&pos);
1344 RecWrd(msh, (unsigned char*)&IntVal);