1 // Copyright (C) 2021 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 /*----------------------------------------------------------*/
24 /*----------------------------------------------------------*/
26 /* Description: handle .meshb file format I/O */
27 /* Author: Loic MARECHAL */
28 /* Creation date: feb 16 2007 */
29 /* Last modification: apr 03 2012 */
31 /*----------------------------------------------------------*/
34 /*----------------------------------------------------------*/
36 /*----------------------------------------------------------*/
45 #include "libmesh5.hxx"
50 using namespace MeshFormat;
54 /*----------------------------------------------------------*/
55 /* Global variables */
56 /*----------------------------------------------------------*/
58 // see MeshGems/Docs/meshgems_formats_description.pdf
59 const char *GmfKwdFmt[ GmfMaxKwd + 1 ][4] =
60 { {"Reserved", "", "", ""},
61 {"MeshVersionFormatted", "", "", "i"},
62 {"Reserved", "", "", ""},
63 {"Dimension", "", "", "i"},
64 {"Vertices", "Vertex", "i", "dri"},
65 {"Edges", "Edge", "i", "iii"},
66 {"Triangles", "Triangle", "i", "iiii"},
67 {"Quadrilaterals", "Quadrilateral", "i", "iiiii"},
68 {"Tetrahedra", "Tetrahedron", "i", "iiiii"},
69 {"Prisms", "Prism", "i", "iiiiiii"},
70 {"Hexahedra", "Hexahedron", "i", "iiiiiiiii"},
71 {"IterationsAll", "IterationAll","","i"},
72 {"TimesAll", "TimeAll","","r"},
73 {"Corners", "Corner", "i", "i"},
74 {"Ridges", "Ridge", "i", "i"},
75 {"RequiredVertices", "RequiredVertex", "i", "i"},
76 {"RequiredEdges", "RequiredEdge", "i", "i"},
77 {"RequiredTriangles", "RequiredTriangle", "i", "i"},
78 {"RequiredQuadrilaterals", "RequiredQuadrilateral", "i", "i"},
79 {"TangentAtEdgeVertices", "TangentAtEdgeVertex", "i", "iii"},
80 {"NormalAtVertices", "NormalAtVertex", "i", "ii"},
81 {"NormalAtTriangleVertices", "NormalAtTriangleVertex", "i", "iii"},
82 {"NormalAtQuadrilateralVertices", "NormalAtQuadrilateralVertex", "i", "iiii"},
83 {"AngleOfCornerBound", "", "", "r"},
84 {"TrianglesP2", "TriangleP2", "i", "iiiiiii"},
85 {"EdgesP2", "EdgeP2", "i", "iiii"},
86 {"SolAtPyramids", "SolAtPyramid", "i", "sr"},
87 {"QuadrilateralsQ2", "QuadrilateralQ2", "i", "iiiiiiiiii"},
88 {"ISolAtPyramids", "ISolAtPyramid", "i", "iiiii"},
89 {"SubDomainFromGeom", "SubDomainFromGeom", "i", "iiii"},
90 {"TetrahedraP2", "TetrahedronP2", "i", "iiiiiiiiiii"},
91 {"Fault_NearTri", "Fault_NearTri", "i", "i"},
92 {"Fault_Inter", "Fault_Inter", "i", "i"},
93 {"HexahedraQ2", "HexahedronQ2", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiii"},
94 {"ExtraVerticesAtEdges", "ExtraVerticesAtEdge", "i", "in"},
95 {"ExtraVerticesAtTriangles", "ExtraVerticesAtTriangle", "i", "in"},
96 {"ExtraVerticesAtQuadrilaterals", "ExtraVerticesAtQuadrilateral", "i", "in"},
97 {"ExtraVerticesAtTetrahedra", "ExtraVerticesAtTetrahedron", "i", "in"},
98 {"ExtraVerticesAtPrisms", "ExtraVerticesAtPrism", "i", "in"},
99 {"ExtraVerticesAtHexahedra", "ExtraVerticesAtHexahedron", "i", "in"},
100 {"VerticesOnGeometricVertices", "VertexOnGeometricVertex", "i", "iir"},
101 {"VerticesOnGeometricEdges", "VertexOnGeometricEdge", "i", "iirr"},
102 {"VerticesOnGeometricTriangles", "VertexOnGeometricTriangle", "i", "iirrr"},
103 {"VerticesOnGeometricQuadrilaterals", "VertexOnGeometricQuadrilateral", "i", "iirrr"},
104 {"EdgesOnGeometricEdges", "EdgeOnGeometricEdge", "i", "iir"},
105 {"Fault_FreeEdge", "Fault_FreeEdge", "i", "i"},
106 {"Polyhedra", "Polyhedron", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
107 {"Polygons", "Polygon", "", "iiiiiiiii"},
108 {"Fault_Overlap", "Fault_Overlap", "i", "i"},
109 {"Pyramids", "Pyramid", "i", "iiiiii"},
110 {"BoundingBox", "", "", "drdr"},
111 {"Body","i", "drdrdrdr"},
112 {"PrivateTable", "PrivateTable", "i", "i"},
113 {"Fault_BadShape", "Fault_BadShape", "i", "i"},
115 {"TrianglesOnGeometricTriangles", "TriangleOnGeometricTriangle", "i", "iir"},
116 {"TrianglesOnGeometricQuadrilaterals", "TriangleOnGeometricQuadrilateral", "i", "iir"},
117 {"QuadrilateralsOnGeometricTriangles", "QuadrilateralOnGeometricTriangle", "i", "iir"},
118 {"QuadrilateralsOnGeometricQuadrilaterals", "QuadrilateralOnGeometricQuadrilateral", "i", "iir"},
119 {"Tangents", "Tangent", "i", "dr"},
120 {"Normals", "Normal", "i", "dr"},
121 {"TangentAtVertices", "TangentAtVertex", "i", "ii"},
122 {"SolAtVertices", "SolAtVertex", "i", "sr"},
123 {"SolAtEdges", "SolAtEdge", "i", "sr"},
124 {"SolAtTriangles", "SolAtTriangle", "i", "sr"},
125 {"SolAtQuadrilaterals", "SolAtQuadrilateral", "i", "sr"},
126 {"SolAtTetrahedra", "SolAtTetrahedron", "i", "sr"},
127 {"SolAtPrisms", "SolAtPrism", "i", "sr"},
128 {"SolAtHexahedra", "SolAtHexahedron", "i", "sr"},
129 {"DSolAtVertices", "DSolAtVertex", "i", "sr"},
130 {"ISolAtVertices", "ISolAtVertex", "i", "i"},
131 {"ISolAtEdges", "ISolAtEdge", "i", "ii"},
132 {"ISolAtTriangles", "ISolAtTriangle", "i", "iii"},
133 {"ISolAtQuadrilaterals", "ISolAtQuadrilateral", "i", "iiii"},
134 {"ISolAtTetrahedra", "ISolAtTetrahedron", "i", "iiii"},
135 {"ISolAtPrisms", "ISolAtPrism", "i", "iiiiii"},
136 {"ISolAtHexahedra", "ISolAtHexahedron", "i", "iiiiiiii"},
137 {"Iterations", "","","i"},
139 {"Fault_SmallTri", "Fault_SmallTri","i","i"},
140 {"CoarseHexahedra", "CoarseHexahedron", "i", "i"},
141 {"Fault_MultipleEdge", "Fault_MultipleEdge", "i", "i"}
146 MeshFormatParser::MeshFormatParser():GmfIniFlg(0)
151 /*----------------------------------------------------------*/
152 /* Open a mesh file in read or write mod */
153 /*----------------------------------------------------------*/
155 int MeshFormatParser::GmfOpenMesh(const char *FilNam, int mod, ...)
157 int i, KwdCod, res, *PtrVer, *PtrDim, MshIdx=0;
158 char str[ GmfStrSiz ];
163 #if defined(WIN32) && defined(UNICODE)
164 wchar_t* encoded = 0;
169 for(i=0; i<=MaxMsh; i++)
170 //~GmfMshTab[i] = NULL;
171 GmfMshTab[i] = nullptr;
176 /*---------------------*/
177 /* MESH STRUCTURE INIT */
178 /*---------------------*/
180 for(i=1; i<=MaxMsh; i++)
188 if( !MshIdx || !(msh = new GmfMshSct() ) )
191 /* Copy the FilNam into the structure */
193 if(strlen(FilNam) + 7 >= GmfStrSiz)
200 strcpy(msh->FilNam, FilNam);
202 /* Store the opening mod (read or write) and guess the filetype (binary or ascii) depending on the extension */
205 msh->buf = (unsigned char *)msh->DblBuf;
206 msh->FltBuf = (float *)msh->DblBuf;
207 msh->IntBuf = (int *)msh->DblBuf;
209 k = static_cast<int>(strlen(msh->FilNam)) - 6;
213 if(strstr(ptr, ".meshb"))
214 msh->typ |= (Bin | MshFil);
215 else if(strstr(ptr, ".mesh"))
216 msh->typ |= (Asc | MshFil);
217 else if(strstr(ptr, ".solb"))
218 msh->typ |= (Bin | SolFil);
219 else if(strstr(ptr, ".sol"))
220 msh->typ |= (Asc | SolFil);
227 /* Open the file in the required mod and initialise the mesh structure */
229 if(msh->mod == GmfRead)
232 /*-----------------------*/
233 /* OPEN FILE FOR READING */
234 /*-----------------------*/
236 va_start(VarArg, mod);
237 PtrVer = va_arg(VarArg, int *);
238 PtrDim = va_arg(VarArg, int *);
241 /* Create the name string and open the file */
242 #if defined(WIN32) && defined(UNICODE)
243 size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
244 //~encoded = malloc((size_needed + 1)*sizeof(wchar_t));
245 encoded = new wchar_t[size_needed + 1] ;
246 MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
247 encoded[size_needed] = '\0';
248 if (!(msh->hdl = _wfopen(encoded, L"rb")))
250 if (!(msh->hdl = fopen(msh->FilNam, "rb")))
255 #if defined(WIN32) && defined(UNICODE)
262 #if defined(WIN32) && defined(UNICODE)
267 /* Read the endian coding tag, the mesh version and the mesh dimension (mandatory kwd) */
271 fread((unsigned char *)&msh->cod, WrdSiz, 1, msh->hdl);
273 if( (msh->cod != 1) && (msh->cod != 16777216) )
280 ScaWrd(msh, (unsigned char *)&msh->ver);
282 if( (msh->ver < 1) || (msh->ver > 3) )
289 if( (msh->ver == 3) && (sizeof(long) == 4) )
296 ScaWrd(msh, (unsigned char *)&KwdCod);
298 if(KwdCod != GmfDimension)
306 ScaWrd(msh, (unsigned char *)&msh->dim);
312 res = fscanf(msh->hdl, "%s", str);
313 } while( (res != EOF) && strcmp(str, "MeshVersionFormatted") );
322 fscanf(msh->hdl, "%d", &msh->ver);
324 if( (msh->ver < 1) || (msh->ver > 3) )
333 res = fscanf(msh->hdl, "%s", str);
334 } while( (res != EOF) && strcmp(str, "Dimension") );
343 fscanf(msh->hdl, "%d", &msh->dim);
346 if( (msh->dim != 2) && (msh->dim != 3) )
353 (*PtrVer) = msh->ver;
354 (*PtrDim) = msh->dim;
360 /* Read the list of kw present in the file */
369 GmfMshTab[ MshIdx ] = msh;
373 else if(msh->mod == GmfWrite)
376 /*-----------------------*/
377 /* OPEN FILE FOR WRITING */
378 /*-----------------------*/
382 /* Check if the user provided a valid version number and dimension */
384 va_start(VarArg, mod);
385 msh->ver = va_arg(VarArg, int);
386 msh->dim = va_arg(VarArg, int);
389 if( (msh->ver < 1) || (msh->ver > 3) )
396 if( (msh->ver == 3) && (sizeof(long) == 4) )
403 if( (msh->dim != 2) && (msh->dim != 3) )
410 /* Create the mesh file */
411 #if defined(WIN32) && defined(UNICODE)
412 size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
414 encoded = new wchar_t[size_needed + 1];
415 MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
416 encoded[size_needed] = '\0';
417 if (!(msh->hdl = _wfopen(encoded, L"wb")))
419 if(!(msh->hdl = fopen(msh->FilNam, "wb")))
424 #if defined(WIN32) && defined(UNICODE)
431 #if defined(WIN32) && defined(UNICODE)
435 GmfMshTab[ MshIdx ] = msh;
442 /* Write the mesh version and dimension */
446 fprintf(msh->hdl, "%s %d\n\n", GmfKwdFmt[ GmfVersionFormatted ][0], msh->ver);
447 fprintf(msh->hdl, "%s %d\n", GmfKwdFmt[ GmfDimension ][0], msh->dim);
451 RecWrd(msh, (unsigned char *)&msh->cod);
452 RecWrd(msh, (unsigned char *)&msh->ver);
453 GmfSetKwd(MshIdx, GmfDimension, 0);
454 RecWrd(msh, (unsigned char *)&msh->dim);
468 /*----------------------------------------------------------*/
469 /* Close a meshfile in the right way */
470 /*----------------------------------------------------------*/
472 int MeshFormatParser::GmfCloseMesh(int MshIdx)
477 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
480 msh = GmfMshTab[ MshIdx ];
481 RecBlk(msh, msh->buf, 0);
483 /* In write down the "End" kw in write mode */
485 if(msh->mod == GmfWrite) {
487 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ GmfEnd ][0]);
489 GmfSetKwd(MshIdx, GmfEnd, 0);
491 /* Close the file and free the mesh structure */
499 GmfMshTab[ MshIdx ] = nullptr;
505 /*----------------------------------------------------------*/
506 /* Read the number of lines and set the position to this kwd*/
507 /*----------------------------------------------------------*/
509 int MeshFormatParser::GmfStatKwd(int MshIdx, int KwdCod, ...)
511 int i, *PtrNmbTyp, *PtrSolSiz, *TypTab;
516 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
519 msh = GmfMshTab[ MshIdx ];
521 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
524 kwd = &msh->KwdTab[ KwdCod ];
529 /* Read further arguments if this kw is a sol */
531 if(kwd->typ == SolKwd)
533 va_start(VarArg, KwdCod);
535 PtrNmbTyp = va_arg(VarArg, int *);
536 *PtrNmbTyp = kwd->NmbTyp;
538 PtrSolSiz = va_arg(VarArg, int *);
539 *PtrSolSiz = kwd->SolSiz;
541 TypTab = va_arg(VarArg, int *);
543 for(i=0; i<kwd->NmbTyp; i++)
544 TypTab[i] = kwd->TypTab[i];
553 /*----------------------------------------------------------*/
554 /* Set the current file position to a given kwd */
555 /*----------------------------------------------------------*/
557 int MeshFormatParser::GmfGotoKwd(int MshIdx, int KwdCod)
562 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
565 msh = GmfMshTab[ MshIdx ];
567 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
570 kwd = &msh->KwdTab[ KwdCod ];
575 return(fseek(msh->hdl, kwd->pos, SEEK_SET));
579 /*----------------------------------------------------------*/
580 /* Write the kwd and set the number of lines */
581 /*----------------------------------------------------------*/
583 int MeshFormatParser::GmfSetKwd(int MshIdx, int KwdCod, ...)
585 int i, NmbLin=0, *TypTab;
591 if( (MshIdx < 1) || (MshIdx > MaxMsh) )
594 msh = GmfMshTab[ MshIdx ];
595 RecBlk(msh, msh->buf, 0);
597 if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
600 kwd = &msh->KwdTab[ KwdCod ];
602 /* Read further arguments if this kw has a header */
604 if(strlen(GmfKwdFmt[ KwdCod ][2]))
606 va_start(VarArg, KwdCod);
607 NmbLin = va_arg(VarArg, int);
609 if(!strcmp(GmfKwdFmt[ KwdCod ][3], "sr"))
611 kwd->NmbTyp = va_arg(VarArg, int);
612 TypTab = va_arg(VarArg, int *);
614 for(i=0; i<kwd->NmbTyp; i++)
615 kwd->TypTab[i] = TypTab[i];
621 /* Setup the kwd info */
627 else if(kwd->typ == InfKwd)
630 kwd->NmbLin = NmbLin;
632 /* Store the next kwd position in binary file */
634 if( (msh->typ & Bin) && msh->NexKwdPos )
636 CurPos = ftell(msh->hdl);
637 fseek(msh->hdl, msh->NexKwdPos, SEEK_SET);
639 fseek(msh->hdl, CurPos, SEEK_SET);
642 /* Write the header */
646 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ KwdCod ][0]);
648 if(kwd->typ != InfKwd)
649 fprintf(msh->hdl, "%d\n", kwd->NmbLin);
651 /* In case of solution field, write the extended header */
653 if(kwd->typ == SolKwd)
655 fprintf(msh->hdl, "%d ", kwd->NmbTyp);
657 for(i=0; i<kwd->NmbTyp; i++)
658 fprintf(msh->hdl, "%d ", kwd->TypTab[i]);
660 fprintf(msh->hdl, "\n\n");
665 RecWrd(msh, (unsigned char *)&KwdCod);
666 msh->NexKwdPos = ftell(msh->hdl);
669 if(kwd->typ != InfKwd)
670 RecWrd(msh, (unsigned char *)&kwd->NmbLin);
672 /* In case of solution field, write the extended header at once */
674 if(kwd->typ == SolKwd)
676 RecWrd(msh, (unsigned char *)&kwd->NmbTyp);
678 for(i=0; i<kwd->NmbTyp; i++)
679 RecWrd(msh, (unsigned char *)&kwd->TypTab[i]);
683 /* Reset write buffer position */
686 /* Estimate the total file size and check whether it crosses the 2GB threshold */
688 msh->siz += kwd->NmbLin * kwd->NmbWrd * WrdSiz;
690 if(msh->siz > static_cast<long>(2E9))
697 /*----------------------------------------------------------*/
698 /* Read a full line from the current kwd */
699 /*----------------------------------------------------------*/
701 void MeshFormatParser::GmfGetLin(int MshIdx, int KwdCod, ...)
707 GmfMshSct *msh = GmfMshTab[ MshIdx ];
708 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
710 /* Start decoding the arguments */
712 va_start(VarArg, KwdCod);
714 if(kwd->typ != SolKwd)
716 int k, nb_repeat = 0;
722 for(i=0; i<kwd->SolSiz; i++)
723 if(kwd->fmt[i] == 'r')
724 fscanf(msh->hdl, "%f", va_arg(VarArg, float *));
725 else if(kwd->fmt[i] == 'n') {
726 fscanf(msh->hdl, "%d", &nb_repeat);
727 *(va_arg(VarArg, int *)) = nb_repeat;
728 for(k=0; k<nb_repeat; k++)
729 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
732 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
736 for(i=0; i<kwd->SolSiz; i++)
737 if(kwd->fmt[i] == 'r')
738 ScaWrd(msh, (unsigned char *)va_arg(VarArg, float *));
739 else if(kwd->fmt[i] == 'n') {
740 ScaWrd(msh, (unsigned char *)&nb_repeat);
741 *(va_arg(VarArg, int *)) = nb_repeat;
742 for(k=0; k<nb_repeat; k++)
743 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
746 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
753 for(i=0; i<kwd->SolSiz; i++)
754 if(kwd->fmt[i] == 'r')
755 fscanf(msh->hdl, "%lf", va_arg(VarArg, double *));
756 else if(kwd->fmt[i] == 'n') {
757 fscanf(msh->hdl, "%d", &nb_repeat);
758 *(va_arg(VarArg, int *)) = nb_repeat;
759 for(k=0; k<nb_repeat; k++)
760 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
763 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
766 for(i=0; i<kwd->SolSiz; i++)
767 if(kwd->fmt[i] == 'r')
768 ScaDblWrd(msh, (unsigned char *)va_arg(VarArg, double *));
769 else if(kwd->fmt[i] == 'n') {
770 ScaWrd(msh, (unsigned char *)&nb_repeat);
771 *(va_arg(VarArg, int *)) = nb_repeat;
772 for(k=0; k<nb_repeat; k++)
773 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
776 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
783 FltSolTab = va_arg(VarArg, float *);
786 for(j=0; j<kwd->SolSiz; j++)
787 fscanf(msh->hdl, "%f", &FltSolTab[j]);
789 ScaBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
793 DblSolTab = va_arg(VarArg, double *);
796 for(j=0; j<kwd->SolSiz; j++)
797 fscanf(msh->hdl, "%lf", &DblSolTab[j]);
799 for(j=0; j<kwd->SolSiz; j++)
800 ScaDblWrd(msh, (unsigned char *)&DblSolTab[j]);
808 /*----------------------------------------------------------*/
809 /* Write a full line from the current kwd */
810 /*----------------------------------------------------------*/
812 void MeshFormatParser::GmfSetLin(int MshIdx, int KwdCod, ...)
814 int i, j, pos, *IntBuf;
816 double *DblSolTab, *DblBuf;
818 GmfMshSct *msh = GmfMshTab[ MshIdx ];
819 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
821 /* Start decoding the arguments */
823 va_start(VarArg, KwdCod);
825 if(kwd->typ != SolKwd)
827 int k, nb_repeat = 0;
833 for(i=0; i<kwd->SolSiz; i++)
834 if(kwd->fmt[i] == 'r')
835 fprintf(msh->hdl, "%g ", (float)va_arg(VarArg, double));
836 else if(kwd->fmt[i] == 'n') {
837 nb_repeat = va_arg(VarArg, int);
838 fprintf(msh->hdl, "%d ", nb_repeat);
839 for(k=0; k<nb_repeat; k++)
840 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
843 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
847 int size_of_block = kwd->SolSiz;
848 for(i=0; i<kwd->SolSiz; i++)
849 if(kwd->fmt[i] == 'r')
850 msh->FltBuf[i] = static_cast<float>(va_arg(VarArg, double));
851 else if(kwd->fmt[i] == 'n') {
852 nb_repeat = va_arg(VarArg, int);
853 msh->FltBuf[i] = static_cast<float> (nb_repeat);
854 for(k=0; k<nb_repeat; k++) {
855 msh->IntBuf[i+1+k] = va_arg(VarArg, int);
860 msh->IntBuf[i] = va_arg(VarArg, int);
862 RecBlk(msh, msh->buf, size_of_block);
869 for(i=0; i<kwd->SolSiz; i++)
870 if(kwd->fmt[i] == 'r')
871 fprintf(msh->hdl, "%.15lg ", va_arg(VarArg, double));
872 else if(kwd->fmt[i] == 'n') {
873 nb_repeat = va_arg(VarArg, int);
874 fprintf(msh->hdl, "%d ", nb_repeat);
875 for(k=0; k<nb_repeat; k++)
876 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
879 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
885 for(i=0; i<kwd->SolSiz; i++)
886 if(kwd->fmt[i] == 'r')
888 DblBuf = (double *)&msh->buf[ pos ];
889 *DblBuf = va_arg(VarArg, double);
892 else if(kwd->fmt[i] == 'n')
894 IntBuf = (int *)&msh->buf[ pos ];
895 nb_repeat = va_arg(VarArg, int);
898 for(k=0; k<nb_repeat; k++) {
899 IntBuf = (int *)&msh->buf[ pos ];
900 *IntBuf = va_arg(VarArg, int);
906 IntBuf = (int *)&msh->buf[ pos ];
907 *IntBuf = va_arg(VarArg, int);
910 RecBlk(msh, msh->buf, pos/4);
918 FltSolTab = va_arg(VarArg, float *);
921 for(j=0; j<kwd->SolSiz; j++)
922 fprintf(msh->hdl, "%g ", FltSolTab[j]);
924 RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
928 DblSolTab = va_arg(VarArg, double *);
931 for(j=0; j<kwd->SolSiz; j++)
932 fprintf(msh->hdl, "%.15lg ", DblSolTab[j]);
934 RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd);
941 fprintf(msh->hdl, "\n");
945 /*----------------------------------------------------------*/
946 /* Private procedure for transmesh : copy a whole line */
947 /*----------------------------------------------------------*/
949 void MeshFormatParser::GmfCpyLin(int InpIdx, int OutIdx, int KwdCod)
954 GmfMshSct *InpMsh = GmfMshTab[ InpIdx ], *OutMsh = GmfMshTab[ OutIdx ];
955 KwdSct *kwd = &InpMsh->KwdTab[ KwdCod ];
957 for(i=0; i<kwd->SolSiz; i++)
959 if(kwd->fmt[i] == 'r')
963 if(InpMsh->typ & Asc)
964 fscanf(InpMsh->hdl, "%f", &f);
966 ScaWrd(InpMsh, (unsigned char *)&f);
972 if(InpMsh->typ & Asc)
973 fscanf(InpMsh->hdl, "%lf", &d);
975 ScaDblWrd(InpMsh, (unsigned char *)&d);
981 if(OutMsh->typ & Asc)
982 fprintf(OutMsh->hdl, "%g ", f);
984 RecWrd(OutMsh, (unsigned char *)&f);
985 else if(OutMsh->typ & Asc)
986 fprintf(OutMsh->hdl, "%.15g ", d);
988 RecDblWrd(OutMsh, (unsigned char *)&d);
990 else if(kwd->fmt[i] == 'n')
992 int k, nb_repeat = 0;
994 if(InpMsh->typ & Asc)
995 fscanf(InpMsh->hdl, "%d", &a);
997 ScaWrd(InpMsh, (unsigned char *)&a);
1001 if(OutMsh->typ & Asc)
1002 fprintf(OutMsh->hdl, "%d ", a);
1004 RecWrd(OutMsh, (unsigned char *)&a);
1006 for(k=0; k<nb_repeat; k++) {
1007 if(InpMsh->typ & Asc)
1008 fscanf(InpMsh->hdl, "%d", &a);
1010 ScaWrd(InpMsh, (unsigned char *)&a);
1012 if(OutMsh->typ & Asc)
1013 fprintf(OutMsh->hdl, "%d ", a);
1015 RecWrd(OutMsh, (unsigned char *)&a);
1020 if(InpMsh->typ & Asc)
1021 fscanf(InpMsh->hdl, "%d", &a);
1023 ScaWrd(InpMsh, (unsigned char *)&a);
1025 if(OutMsh->typ & Asc)
1026 fprintf(OutMsh->hdl, "%d ", a);
1028 RecWrd(OutMsh, (unsigned char *)&a);
1032 if(OutMsh->typ & Asc)
1033 fprintf(OutMsh->hdl, "\n");
1037 /*----------------------------------------------------------*/
1038 /* Find every kw present in a meshfile */
1039 /*----------------------------------------------------------*/
1041 int MeshFormatParser::ScaKwdTab(GmfMshSct *msh)
1044 long NexPos, CurPos, EndPos;
1045 char str[ GmfStrSiz ];
1049 /* Scan each string in the file until the end */
1051 while(fscanf(msh->hdl, "%s", str) != EOF)
1053 /* Fast test in order to reject quickly the numeric values */
1057 /* Search which kwd code this string is associated with,
1058 then get its header and save the current position in file (just before the data) */
1059 // printf("libmesh ScaKwdTab %s\n", str);
1060 for(KwdCod=1; KwdCod<= GmfMaxKwd; KwdCod++)
1061 if(!strcmp(str, GmfKwdFmt[ KwdCod ][0]))
1063 ScaKwdHdr(msh, KwdCod);
1067 else if(str[0] == '#')
1068 while(fgetc(msh->hdl) != '\n');
1075 CurPos = ftell(msh->hdl);
1076 fseek(msh->hdl, 0, SEEK_END);
1077 EndPos = ftell(msh->hdl);
1078 fseek(msh->hdl, CurPos, SEEK_SET);
1080 /* Jump through kwd positions in the file */
1084 /* Get the kwd code and the next kwd position */
1086 ScaWrd(msh, (unsigned char *)&KwdCod);
1087 NexPos = GetPos(msh);
1092 /* Check if this kwd belongs to this mesh version */
1094 if( (KwdCod >= 1) && (KwdCod <= GmfMaxKwd) )
1095 ScaKwdHdr(msh, KwdCod);
1097 /* Go to the next kwd */
1100 fseek(msh->hdl, NexPos, SEEK_SET);
1101 } while(NexPos && (KwdCod != GmfEnd));
1108 /*----------------------------------------------------------*/
1109 /* Read and setup the keyword's header */
1110 /*----------------------------------------------------------*/
1112 void MeshFormatParser::ScaKwdHdr(GmfMshSct *msh, int KwdCod)
1115 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1117 if(!strcmp("i", GmfKwdFmt[ KwdCod ][2]))
1120 fscanf(msh->hdl, "%d", &kwd->NmbLin);
1122 ScaWrd(msh, (unsigned char *)&kwd->NmbLin);
1127 if(!strcmp("sr", GmfKwdFmt[ KwdCod ][3]))
1131 fscanf(msh->hdl, "%d", &kwd->NmbTyp);
1133 for(i=0; i<kwd->NmbTyp; i++)
1134 fscanf(msh->hdl, "%d", &kwd->TypTab[i]);
1138 ScaWrd(msh, (unsigned char *)&kwd->NmbTyp);
1140 for(i=0; i<kwd->NmbTyp; i++)
1141 ScaWrd(msh, (unsigned char *)&kwd->TypTab[i]);
1145 ExpFmt(msh, KwdCod);
1146 kwd->pos = ftell(msh->hdl);
1150 /*----------------------------------------------------------*/
1151 /* Expand the compacted format and compute the line size */
1152 /*----------------------------------------------------------*/
1154 void MeshFormatParser::ExpFmt(GmfMshSct *msh, int KwdCod)
1158 const char *InpFmt = GmfKwdFmt[ KwdCod ][3];
1159 KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1161 /* Set the kwd's type */
1163 if(!strlen(GmfKwdFmt[ KwdCod ][2]))
1165 else if(!strcmp(InpFmt, "sr"))
1170 /* Get the solution-field's size */
1172 if(kwd->typ == SolKwd)
1173 for(i=0; i<kwd->NmbTyp; i++)
1174 switch(kwd->TypTab[i])
1183 TmpSiz += (msh->dim * (msh->dim+1)) / 2;
1186 TmpSiz += msh->dim * msh->dim;
1190 /* Scan each character from the format string */
1192 i = kwd->SolSiz = kwd->NmbWrd = 0;
1194 while(i < static_cast<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 void MeshFormatParser::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 void MeshFormatParser::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 void MeshFormatParser::ScaBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1279 unsigned char swp, *wrd;
1281 fread(blk, WrdSiz, siz, msh->hdl);
1286 for(i=0; i<siz; i++)
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 long MeshFormatParser::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 void MeshFormatParser::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 void MeshFormatParser::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 void MeshFormatParser::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 void MeshFormatParser::SetPos(GmfMshSct *msh, long pos)
1374 RecDblWrd(msh, (unsigned char*)&pos);
1377 IntVal = static_cast<int>(pos);
1378 RecWrd(msh, (unsigned char*)&IntVal);