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 static const char *GmfKwdFmt[ GmfMaxKwd + 1 ][4] =
82 { {"Reserved", "", "", ""},
83 {"MeshVersionFormatted", "", "", "i"},
84 {"Reserved", "", "", ""},
85 {"Dimension", "", "", "i"},
86 {"Vertices", "Vertex", "i", "dri"},
87 {"Edges", "Edge", "i", "iii"},
88 {"Triangles", "Triangle", "i", "iiii"},
89 {"Quadrilaterals", "Quadrilateral", "i", "iiiii"},
90 {"Tetrahedra", "Tetrahedron", "i", "iiiii"},
91 {"Prisms", "Prism", "i", "iiiiiii"},
92 {"Hexahedra", "Hexahedron", "i", "iiiiiiiii"},
93 {"IterationsAll", "IterationAll","","i"},
94 {"TimesAll", "TimeAll","","r"},
95 {"Corners", "Corner", "i", "i"},
96 {"Ridges", "Ridge", "i", "i"},
97 {"RequiredVertices", "RequiredVertex", "i", "i"},
98 {"RequiredEdges", "RequiredEdge", "i", "i"},
99 {"RequiredTriangles", "RequiredTriangle", "i", "i"},
100 {"RequiredQuadrilaterals", "RequiredQuadrilateral", "i", "i"},
101 {"TangentAtEdgeVertices", "TangentAtEdgeVertex", "i", "iii"},
102 {"NormalAtVertices", "NormalAtVertex", "i", "ii"},
103 {"NormalAtTriangleVertices", "NormalAtTriangleVertex", "i", "iii"},
104 {"NormalAtQuadrilateralVertices", "NormalAtQuadrilateralVertex", "i", "iiii"},
105 {"AngleOfCornerBound", "", "", "r"},
106 {"TrianglesP2", "TriangleP2", "i", "iiiiiii"},
107 {"EdgesP2", "EdgeP2", "i", "iiii"},
108 {"SolAtPyramids", "SolAtPyramid", "i", "sr"},
109 {"QuadrilateralsQ2", "QuadrilateralQ2", "i", "iiiiiiiiii"},
110 {"ISolAtPyramids", "ISolAtPyramid", "i", "iiiii"},
111 {"SubDomainFromGeom", "SubDomainFromGeom", "i", "iiii"},
112 {"TetrahedraP2", "TetrahedronP2", "i", "iiiiiiiiiii"},
113 {"Fault_NearTri", "Fault_NearTri", "i", "i"},
114 {"Fault_Inter", "Fault_Inter", "i", "i"},
115 {"HexahedraQ2", "HexahedronQ2", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiii"},
116 {"ExtraVerticesAtEdges", "ExtraVerticesAtEdge", "i", "in"},
117 {"ExtraVerticesAtTriangles", "ExtraVerticesAtTriangle", "i", "in"},
118 {"ExtraVerticesAtQuadrilaterals", "ExtraVerticesAtQuadrilateral", "i", "in"},
119 {"ExtraVerticesAtTetrahedra", "ExtraVerticesAtTetrahedron", "i", "in"},
120 {"ExtraVerticesAtPrisms", "ExtraVerticesAtPrism", "i", "in"},
121 {"ExtraVerticesAtHexahedra", "ExtraVerticesAtHexahedron", "i", "in"},
122 {"VerticesOnGeometricVertices", "VertexOnGeometricVertex", "i", "iir"},
123 {"VerticesOnGeometricEdges", "VertexOnGeometricEdge", "i", "iirr"},
124 {"VerticesOnGeometricTriangles", "VertexOnGeometricTriangle", "i", "iirrr"},
125 {"VerticesOnGeometricQuadrilaterals", "VertexOnGeometricQuadrilateral", "i", "iirrr"},
126 {"EdgesOnGeometricEdges", "EdgeOnGeometricEdge", "i", "iir"},
127 {"Fault_FreeEdge", "Fault_FreeEdge", "i", "i"},
128 {"Polyhedra", "Polyhedron", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
129 {"Polygons", "Polygon", "", "iiiiiiiii"},
130 {"Fault_Overlap", "Fault_Overlap", "i", "i"},
131 {"Pyramids", "Pyramid", "i", "iiiiii"},
132 {"BoundingBox", "", "", "drdr"},
133 {"Body","i", "drdrdrdr"},
134 {"PrivateTable", "PrivateTable", "i", "i"},
135 {"Fault_BadShape", "Fault_BadShape", "i", "i"},
137 {"TrianglesOnGeometricTriangles", "TriangleOnGeometricTriangle", "i", "iir"},
138 {"TrianglesOnGeometricQuadrilaterals", "TriangleOnGeometricQuadrilateral", "i", "iir"},
139 {"QuadrilateralsOnGeometricTriangles", "QuadrilateralOnGeometricTriangle", "i", "iir"},
140 {"QuadrilateralsOnGeometricQuadrilaterals", "QuadrilateralOnGeometricQuadrilateral", "i", "iir"},
141 {"Tangents", "Tangent", "i", "dr"},
142 {"Normals", "Normal", "i", "dr"},
143 {"TangentAtVertices", "TangentAtVertex", "i", "ii"},
144 {"SolAtVertices", "SolAtVertex", "i", "sr"},
145 {"SolAtEdges", "SolAtEdge", "i", "sr"},
146 {"SolAtTriangles", "SolAtTriangle", "i", "sr"},
147 {"SolAtQuadrilaterals", "SolAtQuadrilateral", "i", "sr"},
148 {"SolAtTetrahedra", "SolAtTetrahedron", "i", "sr"},
149 {"SolAtPrisms", "SolAtPrism", "i", "sr"},
150 {"SolAtHexahedra", "SolAtHexahedron", "i", "sr"},
151 {"DSolAtVertices", "DSolAtVertex", "i", "sr"},
152 {"ISolAtVertices", "ISolAtVertex", "i", "i"},
153 {"ISolAtEdges", "ISolAtEdge", "i", "ii"},
154 {"ISolAtTriangles", "ISolAtTriangle", "i", "iii"},
155 {"ISolAtQuadrilaterals", "ISolAtQuadrilateral", "i", "iiii"},
156 {"ISolAtTetrahedra", "ISolAtTetrahedron", "i", "iiii"},
157 {"ISolAtPrisms", "ISolAtPrism", "i", "iiiiii"},
158 {"ISolAtHexahedra", "ISolAtHexahedron", "i", "iiiiiiii"},
159 {"Iterations", "","","i"},
161 {"Fault_SmallTri", "Fault_SmallTri","i","i"},
162 {"CoarseHexahedra", "CoarseHexahedron", "i", "i"}
166 /*----------------------------------------------------------*/
167 /* Prototypes of local procedures */
168 /*----------------------------------------------------------*/
170 static void ScaWrd(GmfMshSct *, unsigned char *);
171 static void ScaDblWrd(GmfMshSct *, unsigned char *);
172 static void ScaBlk(GmfMshSct *, unsigned char *, int);
173 static long GetPos(GmfMshSct *);
174 static void RecWrd(GmfMshSct *, unsigned char *);
175 static void RecDblWrd(GmfMshSct *, unsigned char *);
176 static void RecBlk(GmfMshSct *, unsigned char *, int);
177 static void SetPos(GmfMshSct *, long);
178 static int ScaKwdTab(GmfMshSct *);
179 static void ExpFmt(GmfMshSct *, int);
180 static void ScaKwdHdr(GmfMshSct *, int);
183 /*----------------------------------------------------------*/
184 /* Open a mesh file in read or write mod */
185 /*----------------------------------------------------------*/
187 int GmfOpenMesh(const char *FilNam, int mod, ...)
189 int i, KwdCod, res, *PtrVer, *PtrDim, MshIdx=0;
190 char str[ GmfStrSiz ];
195 #if defined(WIN32) && defined(UNICODE)
196 wchar_t* encoded = 0;
201 for(i=0;i<=MaxMsh;i++)
207 /*---------------------*/
208 /* MESH STRUCTURE INIT */
209 /*---------------------*/
211 for(i=1;i<=MaxMsh;i++)
218 if( !MshIdx || !(msh = calloc(1, sizeof(GmfMshSct))) )
221 /* Copy the FilNam into the structure */
223 if(strlen(FilNam) + 7 >= GmfStrSiz)
229 strcpy(msh->FilNam, FilNam);
231 /* Store the opening mod (read or write) and guess the filetype (binary or ascii) depending on the extension */
234 msh->buf = (unsigned char *)msh->DblBuf;
235 msh->FltBuf = (float *)msh->DblBuf;
236 msh->IntBuf = (int *)msh->DblBuf;
238 k = strlen(msh->FilNam) - 6;
242 if(strstr(ptr, ".meshb"))
243 msh->typ |= (Bin | MshFil);
244 else if(strstr(ptr, ".mesh"))
245 msh->typ |= (Asc | MshFil);
246 else if(strstr(ptr, ".solb"))
247 msh->typ |= (Bin | SolFil);
248 else if(strstr(ptr, ".sol"))
249 msh->typ |= (Asc | SolFil);
255 /* Open the file in the required mod and initialise the mesh structure */
257 if(msh->mod == GmfRead)
260 /*-----------------------*/
261 /* OPEN FILE FOR READING */
262 /*-----------------------*/
264 va_start(VarArg, mod);
265 PtrVer = va_arg(VarArg, int *);
266 PtrDim = va_arg(VarArg, int *);
269 /* Create the name string and open the file */
270 #if defined(WIN32) && defined(UNICODE)
271 size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
272 encoded = malloc((size_needed + 1)*sizeof(wchar_t));
273 MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
274 encoded[size_needed] = '\0';
275 if (!(msh->hdl = _wfopen(encoded, L"rb")))
277 if (!(msh->hdl = fopen(msh->FilNam, "rb")))
281 #if defined(WIN32) && defined(UNICODE)
287 #if defined(WIN32) && defined(UNICODE)
291 /* Read the endian coding tag, the mesh version and the mesh dimension (mandatory kwd) */
295 fread((unsigned char *)&msh->cod, WrdSiz, 1, msh->hdl);
297 if( (msh->cod != 1) && (msh->cod != 16777216) )
303 ScaWrd(msh, (unsigned char *)&msh->ver);
305 if( (msh->ver < 1) || (msh->ver > 3) )
311 if( (msh->ver == 3) && (sizeof(long) == 4) )
317 ScaWrd(msh, (unsigned char *)&KwdCod);
319 if(KwdCod != GmfDimension)
326 ScaWrd(msh, (unsigned char *)&msh->dim);
332 res = fscanf(msh->hdl, "%s", str);
333 }while( (res != EOF) && strcmp(str, "MeshVersionFormatted") );
341 fscanf(msh->hdl, "%d", &msh->ver);
343 if( (msh->ver < 1) || (msh->ver > 3) )
351 res = fscanf(msh->hdl, "%s", str);
352 }while( (res != EOF) && strcmp(str, "Dimension") );
360 fscanf(msh->hdl, "%d", &msh->dim);
363 if( (msh->dim != 2) && (msh->dim != 3) )
369 (*PtrVer) = msh->ver;
370 (*PtrDim) = msh->dim;
376 /* Read the list of kw present in the file */
384 GmfMshTab[ MshIdx ] = msh;
388 else if(msh->mod == GmfWrite)
391 /*-----------------------*/
392 /* OPEN FILE FOR WRITING */
393 /*-----------------------*/
397 /* Check if the user provided a valid version number and dimension */
399 va_start(VarArg, mod);
400 msh->ver = va_arg(VarArg, int);
401 msh->dim = va_arg(VarArg, int);
404 if( (msh->ver < 1) || (msh->ver > 3) )
410 if( (msh->ver == 3) && (sizeof(long) == 4) )
416 if( (msh->dim != 2) && (msh->dim != 3) )
422 /* Create the mesh file */
423 #if defined(WIN32) && defined(UNICODE)
424 size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
425 encoded = malloc((size_needed + 1) * sizeof(wchar_t));
426 MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
427 encoded[size_needed] = '\0';
428 if (!(msh->hdl = _wfopen(encoded, L"wb")))
430 if(!(msh->hdl = fopen(msh->FilNam, "wb")))
434 #if defined(WIN32) && defined(UNICODE)
440 #if defined(WIN32) && defined(UNICODE)
443 GmfMshTab[ MshIdx ] = msh;
450 /* Write the mesh version and dimension */
454 fprintf(msh->hdl, "%s %d\n\n", GmfKwdFmt[ GmfVersionFormatted ][0], msh->ver);
455 fprintf(msh->hdl, "%s %d\n", GmfKwdFmt[ GmfDimension ][0], msh->dim);
459 RecWrd(msh, (unsigned char *)&msh->cod);
460 RecWrd(msh, (unsigned char *)&msh->ver);
461 GmfSetKwd(MshIdx, GmfDimension, 0);
462 RecWrd(msh, (unsigned char *)&msh->dim);
475 /*----------------------------------------------------------*/
476 /* Close a meshfile in the right way */
477 /*----------------------------------------------------------*/
479 int GmfCloseMesh(int MshIdx)
484 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
487 msh = GmfMshTab[ MshIdx ];
488 RecBlk(msh, msh->buf, 0);
490 /* In write down the "End" kw in write mode */
492 if(msh->mod == GmfWrite){
494 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ GmfEnd ][0]);
496 GmfSetKwd(MshIdx, GmfEnd, 0);
498 /* Close the file and free the mesh structure */
504 GmfMshTab[ MshIdx ] = NULL;
510 /*----------------------------------------------------------*/
511 /* Read the number of lines and set the position to this kwd*/
512 /*----------------------------------------------------------*/
514 int GmfStatKwd(int MshIdx, int KwdCod, ...)
516 int i, *PtrNmbTyp, *PtrSolSiz, *TypTab;
521 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
524 msh = GmfMshTab[ MshIdx ];
526 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
529 kwd = &msh->KwdTab[ KwdCod ];
534 /* Read further arguments if this kw is a sol */
536 if(kwd->typ == SolKwd)
538 va_start(VarArg, KwdCod);
540 PtrNmbTyp = va_arg(VarArg, int *);
541 *PtrNmbTyp = kwd->NmbTyp;
543 PtrSolSiz = va_arg(VarArg, int *);
544 *PtrSolSiz = kwd->SolSiz;
546 TypTab = va_arg(VarArg, int *);
548 for(i=0;i<kwd->NmbTyp;i++)
549 TypTab[i] = kwd->TypTab[i];
558 /*----------------------------------------------------------*/
559 /* Set the current file position to a given kwd */
560 /*----------------------------------------------------------*/
562 int GmfGotoKwd(int MshIdx, int KwdCod)
567 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
570 msh = GmfMshTab[ MshIdx ];
572 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
575 kwd = &msh->KwdTab[ KwdCod ];
580 return(fseek(msh->hdl, kwd->pos, SEEK_SET));
584 /*----------------------------------------------------------*/
585 /* Write the kwd and set the number of lines */
586 /*----------------------------------------------------------*/
588 int GmfSetKwd(int MshIdx, int KwdCod, ...)
590 int i, NmbLin=0, *TypTab;
596 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
599 msh = GmfMshTab[ MshIdx ];
600 RecBlk(msh, msh->buf, 0);
602 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
605 kwd = &msh->KwdTab[ KwdCod ];
607 /* Read further arguments if this kw has a header */
609 if(strlen(GmfKwdFmt[ KwdCod ][2]))
611 va_start(VarArg, KwdCod);
612 NmbLin = va_arg(VarArg, int);
614 if(!strcmp(GmfKwdFmt[ KwdCod ][3], "sr"))
616 kwd->NmbTyp = va_arg(VarArg, int);
617 TypTab = va_arg(VarArg, int *);
619 for(i=0;i<kwd->NmbTyp;i++)
620 kwd->TypTab[i] = TypTab[i];
626 /* Setup the kwd info */
632 else if(kwd->typ == InfKwd)
635 kwd->NmbLin = NmbLin;
637 /* Store the next kwd position in binary file */
639 if( (msh->typ & Bin) && msh->NexKwdPos )
641 CurPos = ftell(msh->hdl);
642 fseek(msh->hdl, msh->NexKwdPos, SEEK_SET);
644 fseek(msh->hdl, CurPos, SEEK_SET);
647 /* Write the header */
651 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ KwdCod ][0]);
653 if(kwd->typ != InfKwd)
654 fprintf(msh->hdl, "%d\n", kwd->NmbLin);
656 /* In case of solution field, write the extended header */
658 if(kwd->typ == SolKwd)
660 fprintf(msh->hdl, "%d ", kwd->NmbTyp);
662 for(i=0;i<kwd->NmbTyp;i++)
663 fprintf(msh->hdl, "%d ", kwd->TypTab[i]);
665 fprintf(msh->hdl, "\n\n");
670 RecWrd(msh, (unsigned char *)&KwdCod);
671 msh->NexKwdPos = ftell(msh->hdl);
674 if(kwd->typ != InfKwd)
675 RecWrd(msh, (unsigned char *)&kwd->NmbLin);
677 /* In case of solution field, write the extended header at once */
679 if(kwd->typ == SolKwd)
681 RecWrd(msh, (unsigned char *)&kwd->NmbTyp);
683 for(i=0;i<kwd->NmbTyp;i++)
684 RecWrd(msh, (unsigned char *)&kwd->TypTab[i]);
688 /* Reset write buffer position */
691 /* Estimate the total file size and check whether it crosses the 2GB threshold */
693 msh->siz += kwd->NmbLin * kwd->NmbWrd * WrdSiz;
702 /*----------------------------------------------------------*/
703 /* Read a full line from the current kwd */
704 /*----------------------------------------------------------*/
706 void GmfGetLin(int MshIdx, int KwdCod, ...)
712 GmfMshSct *msh = GmfMshTab[ MshIdx ];
713 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
715 /* Start decoding the arguments */
717 va_start(VarArg, KwdCod);
719 if(kwd->typ != SolKwd)
721 int k, nb_repeat = 0;
727 for(i=0;i<kwd->SolSiz;i++)
728 if(kwd->fmt[i] == 'r')
729 fscanf(msh->hdl, "%f", va_arg(VarArg, float *));
730 else if(kwd->fmt[i] == 'n') {
731 fscanf(msh->hdl, "%d", &nb_repeat);
732 *(va_arg(VarArg, int *)) = nb_repeat;
733 for(k=0;k<nb_repeat;k++)
734 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
737 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
741 for(i=0;i<kwd->SolSiz;i++)
742 if(kwd->fmt[i] == 'r')
743 ScaWrd(msh, (unsigned char *)va_arg(VarArg, float *));
744 else if(kwd->fmt[i] == 'n') {
745 ScaWrd(msh, (unsigned char *)&nb_repeat);
746 *(va_arg(VarArg, int *)) = nb_repeat;
747 for(k=0;k<nb_repeat;k++)
748 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
751 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
758 for(i=0;i<kwd->SolSiz;i++)
759 if(kwd->fmt[i] == 'r')
760 fscanf(msh->hdl, "%lf", va_arg(VarArg, double *));
761 else if(kwd->fmt[i] == 'n') {
762 fscanf(msh->hdl, "%d", &nb_repeat);
763 *(va_arg(VarArg, int *)) = nb_repeat;
764 for(k=0;k<nb_repeat;k++)
765 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
768 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
771 for(i=0;i<kwd->SolSiz;i++)
772 if(kwd->fmt[i] == 'r')
773 ScaDblWrd(msh, (unsigned char *)va_arg(VarArg, double *));
774 else if(kwd->fmt[i] == 'n') {
775 ScaWrd(msh, (unsigned char *)&nb_repeat);
776 *(va_arg(VarArg, int *)) = nb_repeat;
777 for(k=0;k<nb_repeat;k++)
778 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
781 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
788 FltSolTab = va_arg(VarArg, float *);
791 for(j=0;j<kwd->SolSiz;j++)
792 fscanf(msh->hdl, "%f", &FltSolTab[j]);
794 ScaBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
798 DblSolTab = va_arg(VarArg, double *);
801 for(j=0;j<kwd->SolSiz;j++)
802 fscanf(msh->hdl, "%lf", &DblSolTab[j]);
804 for(j=0;j<kwd->SolSiz;j++)
805 ScaDblWrd(msh, (unsigned char *)&DblSolTab[j]);
813 /*----------------------------------------------------------*/
814 /* Write a full line from the current kwd */
815 /*----------------------------------------------------------*/
817 void GmfSetLin(int MshIdx, int KwdCod, ...)
819 int i, j, pos, *IntBuf;
821 double *DblSolTab, *DblBuf;
823 GmfMshSct *msh = GmfMshTab[ MshIdx ];
824 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
826 /* Start decoding the arguments */
828 va_start(VarArg, KwdCod);
830 if(kwd->typ != SolKwd)
832 int k, nb_repeat = 0;
838 for(i=0;i<kwd->SolSiz;i++)
839 if(kwd->fmt[i] == 'r')
840 fprintf(msh->hdl, "%g ", (float)va_arg(VarArg, double));
841 else if(kwd->fmt[i] == 'n') {
842 nb_repeat = va_arg(VarArg, int);
843 fprintf(msh->hdl, "%d ", nb_repeat);
844 for(k=0;k<nb_repeat;k++)
845 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
848 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
852 int size_of_block = kwd->SolSiz;
853 for(i=0;i<kwd->SolSiz;i++)
854 if(kwd->fmt[i] == 'r')
855 msh->FltBuf[i] = va_arg(VarArg, double);
856 else if(kwd->fmt[i] == 'n') {
857 nb_repeat = va_arg(VarArg, int);
858 msh->FltBuf[i] = nb_repeat;
859 for(k=0;k<nb_repeat;k++) {
860 msh->IntBuf[i+1+k] = va_arg(VarArg, int);
865 msh->IntBuf[i] = va_arg(VarArg, int);
867 RecBlk(msh, msh->buf, size_of_block);
874 for(i=0;i<kwd->SolSiz;i++)
875 if(kwd->fmt[i] == 'r')
876 fprintf(msh->hdl, "%.15lg ", va_arg(VarArg, double));
877 else if(kwd->fmt[i] == 'n') {
878 nb_repeat = va_arg(VarArg, int);
879 fprintf(msh->hdl, "%d ", nb_repeat);
880 for(k=0;k<nb_repeat;k++)
881 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
884 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
890 for(i=0;i<kwd->SolSiz;i++)
891 if(kwd->fmt[i] == 'r')
893 DblBuf = (double *)&msh->buf[ pos ];
894 *DblBuf = va_arg(VarArg, double);
897 else if(kwd->fmt[i] == 'n')
899 IntBuf = (int *)&msh->buf[ pos ];
900 nb_repeat = va_arg(VarArg, int);
903 for(k=0;k<nb_repeat;k++) {
904 IntBuf = (int *)&msh->buf[ pos ];
905 *IntBuf = va_arg(VarArg, int);
911 IntBuf = (int *)&msh->buf[ pos ];
912 *IntBuf = va_arg(VarArg, int);
915 RecBlk(msh, msh->buf, pos/4);
923 FltSolTab = va_arg(VarArg, float *);
926 for(j=0;j<kwd->SolSiz;j++)
927 fprintf(msh->hdl, "%g ", FltSolTab[j]);
929 RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
933 DblSolTab = va_arg(VarArg, double *);
936 for(j=0;j<kwd->SolSiz;j++)
937 fprintf(msh->hdl, "%.15lg ", DblSolTab[j]);
939 RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd);
946 fprintf(msh->hdl, "\n");
950 /*----------------------------------------------------------*/
951 /* Private procedure for transmesh : copy a whole line */
952 /*----------------------------------------------------------*/
954 void GmfCpyLin(int InpIdx, int OutIdx, int KwdCod)
959 GmfMshSct *InpMsh = GmfMshTab[ InpIdx ], *OutMsh = GmfMshTab[ OutIdx ];
960 KwdSct *kwd = &InpMsh->KwdTab[ KwdCod ];
962 for(i=0;i<kwd->SolSiz;i++)
964 if(kwd->fmt[i] == 'r')
968 if(InpMsh->typ & Asc)
969 fscanf(InpMsh->hdl, "%f", &f);
971 ScaWrd(InpMsh, (unsigned char *)&f);
977 if(InpMsh->typ & Asc)
978 fscanf(InpMsh->hdl, "%lf", &d);
980 ScaDblWrd(InpMsh, (unsigned char *)&d);
986 if(OutMsh->typ & Asc)
987 fprintf(OutMsh->hdl, "%g ", f);
989 RecWrd(OutMsh, (unsigned char *)&f);
991 if(OutMsh->typ & Asc)
992 fprintf(OutMsh->hdl, "%.15g ", d);
994 RecDblWrd(OutMsh, (unsigned char *)&d);
996 else if(kwd->fmt[i] == 'n')
998 int k, nb_repeat = 0;
1000 if(InpMsh->typ & Asc)
1001 fscanf(InpMsh->hdl, "%d", &a);
1003 ScaWrd(InpMsh, (unsigned char *)&a);
1007 if(OutMsh->typ & Asc)
1008 fprintf(OutMsh->hdl, "%d ", a);
1010 RecWrd(OutMsh, (unsigned char *)&a);
1012 for(k=0;k<nb_repeat;k++) {
1013 if(InpMsh->typ & Asc)
1014 fscanf(InpMsh->hdl, "%d", &a);
1016 ScaWrd(InpMsh, (unsigned char *)&a);
1018 if(OutMsh->typ & Asc)
1019 fprintf(OutMsh->hdl, "%d ", a);
1021 RecWrd(OutMsh, (unsigned char *)&a);
1026 if(InpMsh->typ & Asc)
1027 fscanf(InpMsh->hdl, "%d", &a);
1029 ScaWrd(InpMsh, (unsigned char *)&a);
1031 if(OutMsh->typ & Asc)
1032 fprintf(OutMsh->hdl, "%d ", a);
1034 RecWrd(OutMsh, (unsigned char *)&a);
1038 if(OutMsh->typ & Asc)
1039 fprintf(OutMsh->hdl, "\n");
1043 /*----------------------------------------------------------*/
1044 /* Find every kw present in a meshfile */
1045 /*----------------------------------------------------------*/
1047 static int ScaKwdTab(GmfMshSct *msh)
1050 long NexPos, CurPos, EndPos;
1051 char str[ GmfStrSiz ];
1055 /* Scan each string in the file until the end */
1057 while(fscanf(msh->hdl, "%s", str) != EOF)
1059 /* Fast test in order to reject quickly the numeric values */
1063 /* Search which kwd code this string is associated with,
1064 then get its header and save the current position in file (just before the data) */
1066 for(KwdCod=1; KwdCod<= GmfMaxKwd; KwdCod++)
1067 if(!strcmp(str, GmfKwdFmt[ KwdCod ][0]))
1069 ScaKwdHdr(msh, KwdCod);
1073 else if(str[0] == '#')
1074 while(fgetc(msh->hdl) != '\n');
1081 CurPos = ftell(msh->hdl);
1082 fseek(msh->hdl, 0, SEEK_END);
1083 EndPos = ftell(msh->hdl);
1084 fseek(msh->hdl, CurPos, SEEK_SET);
1086 /* Jump through kwd positions in the file */
1090 /* Get the kwd code and the next kwd position */
1092 ScaWrd(msh, (unsigned char *)&KwdCod);
1093 NexPos = GetPos(msh);
1098 /* Check if this kwd belongs to this mesh version */
1100 if( (KwdCod >= 1) && (KwdCod <= GmfMaxKwd) )
1101 ScaKwdHdr(msh, KwdCod);
1103 /* Go to the next kwd */
1106 fseek(msh->hdl, NexPos, SEEK_SET);
1107 }while(NexPos && (KwdCod != GmfEnd));
1114 /*----------------------------------------------------------*/
1115 /* Read and setup the keyword's header */
1116 /*----------------------------------------------------------*/
1118 static void ScaKwdHdr(GmfMshSct *msh, int KwdCod)
1121 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1123 if(!strcmp("i", GmfKwdFmt[ KwdCod ][2]))
1126 fscanf(msh->hdl, "%d", &kwd->NmbLin);
1128 ScaWrd(msh, (unsigned char *)&kwd->NmbLin);
1133 if(!strcmp("sr", GmfKwdFmt[ KwdCod ][3]))
1137 fscanf(msh->hdl, "%d", &kwd->NmbTyp);
1139 for(i=0;i<kwd->NmbTyp;i++)
1140 fscanf(msh->hdl, "%d", &kwd->TypTab[i]);
1144 ScaWrd(msh, (unsigned char *)&kwd->NmbTyp);
1146 for(i=0;i<kwd->NmbTyp;i++)
1147 ScaWrd(msh, (unsigned char *)&kwd->TypTab[i]);
1151 ExpFmt(msh, KwdCod);
1152 kwd->pos = ftell(msh->hdl);
1156 /*----------------------------------------------------------*/
1157 /* Expand the compacted format and compute the line size */
1158 /*----------------------------------------------------------*/
1160 static void ExpFmt(GmfMshSct *msh, int KwdCod)
1164 const char *InpFmt = GmfKwdFmt[ KwdCod ][3];
1165 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1167 /* Set the kwd's type */
1169 if(!strlen(GmfKwdFmt[ KwdCod ][2]))
1171 else if(!strcmp(InpFmt, "sr"))
1176 /* Get the solution-field's size */
1178 if(kwd->typ == SolKwd)
1179 for(i=0;i<kwd->NmbTyp;i++)
1180 switch(kwd->TypTab[i])
1182 case GmfSca : TmpSiz += 1; break;
1183 case GmfVec : TmpSiz += msh->dim; break;
1184 case GmfSymMat : TmpSiz += (msh->dim * (msh->dim+1)) / 2; break;
1185 case GmfMat : TmpSiz += msh->dim * msh->dim; break;
1188 /* Scan each character from the format string */
1190 i = kwd->SolSiz = kwd->NmbWrd = 0;
1192 while(i < strlen(InpFmt))
1194 chr = InpFmt[ i++ ];
1200 for(j=0;j<msh->dim;j++)
1201 kwd->fmt[ kwd->SolSiz++ ] = chr;
1207 for(j=0;j<TmpSiz;j++)
1208 kwd->fmt[ kwd->SolSiz++ ] = chr;
1211 kwd->fmt[ kwd->SolSiz++ ] = chr;
1214 for(i=0;i<kwd->SolSiz;i++)
1215 if(kwd->fmt[i] == 'i')
1217 else if(msh->ver >= 2)
1224 /*----------------------------------------------------------*/
1225 /* Read a four bytes word from a mesh file */
1226 /*----------------------------------------------------------*/
1228 static void ScaWrd(GmfMshSct *msh, unsigned char *wrd)
1232 fread(wrd, WrdSiz, 1, msh->hdl);
1247 /*----------------------------------------------------------*/
1248 /* Read an eight bytes word from a mesh file */
1249 /*----------------------------------------------------------*/
1251 static void ScaDblWrd(GmfMshSct *msh, unsigned char *wrd)
1256 fread(wrd, WrdSiz, 2, msh->hdl);
1270 /*----------------------------------------------------------*/
1271 /* Read ablock of four bytes word from a mesh file */
1272 /*----------------------------------------------------------*/
1274 static void ScaBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1277 unsigned char swp, *wrd;
1279 fread(blk, WrdSiz, siz, msh->hdl);
1286 wrd = &blk[ i * 4 ];
1291 wrd[ 3-j ] = wrd[j];
1298 /*----------------------------------------------------------*/
1299 /* Read a 4 or 8 bytes position in mesh file */
1300 /*----------------------------------------------------------*/
1302 static long GetPos(GmfMshSct *msh)
1308 ScaDblWrd(msh, (unsigned char*)&pos);
1311 ScaWrd(msh, (unsigned char*)&IntVal);
1319 /*----------------------------------------------------------*/
1320 /* Write a four bytes word to a mesh file */
1321 /*----------------------------------------------------------*/
1323 static void RecWrd(GmfMshSct *msh, unsigned char *wrd)
1325 fwrite(wrd, WrdSiz, 1, msh->hdl);
1329 /*----------------------------------------------------------*/
1330 /* Write an eight bytes word to a mesh file */
1331 /*----------------------------------------------------------*/
1333 static void RecDblWrd(GmfMshSct *msh, unsigned char *wrd)
1335 fwrite(wrd, WrdSiz, 2, msh->hdl);
1339 /*----------------------------------------------------------*/
1340 /* Write a block of four bytes word to a mesh file */
1341 /*----------------------------------------------------------*/
1343 static void RecBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1345 /* Copy this line-block into the main mesh buffer */
1349 memcpy(&msh->blk[ msh->pos ], blk, siz * WrdSiz);
1350 msh->pos += siz * WrdSiz;
1353 /* When the buffer is full or this procedure is called with a 0 size, flush the cache on disk */
1355 if( (msh->pos > BufSiz) || (!siz && msh->pos) )
1357 fwrite(msh->blk, 1, msh->pos, msh->hdl);
1363 /*----------------------------------------------------------*/
1364 /* Write a 4 or 8 bytes position in a mesh file */
1365 /*----------------------------------------------------------*/
1367 static void SetPos(GmfMshSct *msh, long pos)
1372 RecDblWrd(msh, (unsigned char*)&pos);
1376 RecWrd(msh, (unsigned char*)&IntVal);