From 88321527c28d65831448887c9e6ade3611307ee2 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Sun, 7 Dec 2003 05:37:00 +0000 Subject: [PATCH] New MSH file format, version 2.0. ******************************************************** ************ Please send me your comments ************** ******************************************************** --- Common/Context.h | 1 + Common/DefaultOptions.h | 2 + Common/Options.cpp | 9 ++- Common/Options.h | 1 + Fltk/Callbacks.cpp | 22 ++++++- Mesh/Print_Mesh.cpp | 73 +++++++++++---------- Mesh/Read_Mesh.cpp | 48 ++++++++++++-- doc/VERSIONS | 3 +- doc/texinfo/gmsh.texi | 141 +++++++++++++++++++++++++++++++++++++--- 9 files changed, 244 insertions(+), 56 deletions(-) diff --git a/Common/Context.h b/Common/Context.h index a4f2afafde..3fb143eb4d 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -150,6 +150,7 @@ public : // mesh options struct { + double msh_file_version; int vis_type, changed, display_lists; int draw; int points, lines, surfaces, volumes; diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index 891a6d366a..b40e9a9fc1 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -746,6 +746,8 @@ StringXNumber MeshOptions_Number[] = { { F|O, "MinimumCirclePoints" , opt_mesh_min_circ_points, 7. , "Minimum number of points used to mesh a circle" }, + { F|O, "MshFileVersion" , opt_mesh_msh_file_version , 1.0 , + "MSH mesh file version to generate" }, { F, "NbHexahedra" , opt_mesh_nb_hexahedra , 0. , "Number of hexahedra in the current mesh" }, diff --git a/Common/Options.cpp b/Common/Options.cpp index 3095d2e9bb..c9927ccc09 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.127 2003-12-07 00:23:06 geuzaine Exp $ +// $Id: Options.cpp,v 1.128 2003-12-07 05:37:00 geuzaine Exp $ // // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle // @@ -3243,6 +3243,13 @@ double opt_mesh_format(OPT_ARGS_NUM) return CTX.mesh.format; } +double opt_mesh_msh_file_version(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX.mesh.msh_file_version = val; + return CTX.mesh.msh_file_version; +} + double opt_mesh_nb_smoothing(OPT_ARGS_NUM) { if(action & GMSH_SET) diff --git a/Common/Options.h b/Common/Options.h index c7e6c56317..a6344fff1d 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -354,6 +354,7 @@ double opt_mesh_line_width(OPT_ARGS_NUM); double opt_mesh_line_type(OPT_ARGS_NUM); double opt_mesh_aspect(OPT_ARGS_NUM); double opt_mesh_format(OPT_ARGS_NUM); +double opt_mesh_msh_file_version(OPT_ARGS_NUM); double opt_mesh_nb_smoothing(OPT_ARGS_NUM); double opt_mesh_algo(OPT_ARGS_NUM); double opt_mesh_point_insertion(OPT_ARGS_NUM); diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index 1422f978f9..c715f14ac7 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.196 2003-12-07 00:23:07 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.197 2003-12-07 05:37:00 geuzaine Exp $ // // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle // @@ -439,6 +439,20 @@ void _save_msh_all(char *name) CreateOutputFile(name, CTX.mesh.format = FORMAT_MSH); CTX.mesh.save_all = all; } +void _save_msh_v2(char *name) +{ + double ver = CTX.mesh.msh_file_version; + CTX.mesh.msh_file_version = 2.0; + _save_msh(name); + CTX.mesh.msh_file_version = ver; +} +void _save_msh_all_v2(char *name) +{ + double ver = CTX.mesh.msh_file_version; + CTX.mesh.msh_file_version = 2.0; + _save_msh_all(name); + CTX.mesh.msh_file_version = ver; +} void _save_gref(char *name) { CreateOutputFile(name, CTX.mesh.format = FORMAT_GREF); @@ -608,8 +622,10 @@ void file_save_as_cb(CALLBACK_ARGS) {"By extension (*)", _save_auto}, {"Gmsh options (*.opt)", _save_geo_options}, {"Gmsh unrolled geometry (*.geo)", _save_geo}, - {"Gmsh mesh (*.msh)", _save_msh}, - {"Gmsh mesh without physicals (*.msh)", _save_msh_all}, + {"Gmsh mesh v1.0 (*.msh)", _save_msh}, + {"Gmsh mesh v1.0 without physicals (*.msh)", _save_msh_all}, + {"Gmsh mesh v2.0 (*.msh)", _save_msh_v2}, + {"Gmsh mesh v2.0 without physicals (*.msh)", _save_msh_all_v2}, {"GREF mesh (*.gref)", _save_gref}, {"I-DEAS universal mesh format (*.unv)", _save_unv}, {"VRML surface mesh (*.wrl)", _save_vrml}, diff --git a/Mesh/Print_Mesh.cpp b/Mesh/Print_Mesh.cpp index 511770ca99..44e9af5b81 100644 --- a/Mesh/Print_Mesh.cpp +++ b/Mesh/Print_Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: Print_Mesh.cpp,v 1.45 2003-12-07 02:56:34 geuzaine Exp $ +// $Id: Print_Mesh.cpp,v 1.46 2003-12-07 05:37:00 geuzaine Exp $ // // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle // @@ -49,7 +49,6 @@ static FILE *meshfile; #define PYRAMID_2 14 #define POINT 15 -static double MSH_VERSION = 1.0; static int MSH_VOL_NUM, MSH_SUR_NUM, MSH_LIN_NUM; static int MSH_NODE_NUM, MSH_ELEMENT_NUM, MSH_3D, MSH_ADD; static int MSH_PHYSICAL_NUM, MSH_PHYSICAL_ORI; @@ -90,16 +89,16 @@ void process_msh_nodes(Mesh * M) MSH_NODE_NUM = Tree_Nbr(M->Vertices); - if(MSH_VERSION > 1.0) + if(CTX.mesh.msh_file_version == 2.0) fprintf(meshfile, "$Nodes\n"); else fprintf(meshfile, "$NOD\n"); fprintf(meshfile, "%d\n", MSH_NODE_NUM); Tree_Action(M->Vertices, print_msh_node); - if(MSH_VERSION > 1.0) - fprintf(meshfile, "$ENDNOD\n"); - else + if(CTX.mesh.msh_file_version == 2.0) fprintf(meshfile, "$EndNodes\n"); + else + fprintf(meshfile, "$ENDNOD\n"); } void print_msh_simplex(void *a, void *b) @@ -168,11 +167,10 @@ void print_msh_simplex(void *a, void *b) } } - if(MSH_VERSION > 1.0) - fprintf(meshfile, "%d %d %d %d 0 %d", - MSH_ELEMENT_NUM++, type, - MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*S)->iEnt, (*S)->iEnt, - nbn + nbs); + if(CTX.mesh.msh_file_version == 2.0) + fprintf(meshfile, "%d %d 2 %d %d", + MSH_ELEMENT_NUM++, type, MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*S)->iEnt, + (*S)->iEnt); else fprintf(meshfile, "%d %d %d %d %d", MSH_ELEMENT_NUM++, type, @@ -218,11 +216,10 @@ void print_msh_hexahedron(void *a, void *b) else type = HEXAHEDRON; - if(MSH_VERSION > 1.0) - fprintf(meshfile, "%d %d %d %d 0 %d", - MSH_ELEMENT_NUM++, type, - MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*H)->iEnt, (*H)->iEnt, - nbn + nbs); + if(CTX.mesh.msh_file_version == 2.0) + fprintf(meshfile, "%d %d 2 %d %d", + MSH_ELEMENT_NUM++, type, MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*H)->iEnt, + (*H)->iEnt); else fprintf(meshfile, "%d %d %d %d %d", MSH_ELEMENT_NUM++, type, @@ -261,11 +258,10 @@ void print_msh_prism(void *a, void *b) type = PRISM; } - if(MSH_VERSION > 1.0) - fprintf(meshfile, "%d %d %d %d 0 %d", - MSH_ELEMENT_NUM++, type, - MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*P)->iEnt, (*P)->iEnt, - nbn + nbs); + if(CTX.mesh.msh_file_version == 2.0) + fprintf(meshfile, "%d %d 2 %d %d", + MSH_ELEMENT_NUM++, type, MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*P)->iEnt, + (*P)->iEnt); else fprintf(meshfile, "%d %d %d %d %d", MSH_ELEMENT_NUM++, type, @@ -304,11 +300,10 @@ void print_msh_pyramid(void *a, void *b) type = PYRAMID; } - if(MSH_VERSION > 1.0) - fprintf(meshfile, "%d %d %d %d 0 %d", - MSH_ELEMENT_NUM++, type, - MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*P)->iEnt, (*P)->iEnt, - nbn + nbs); + if(CTX.mesh.msh_file_version == 2.0) + fprintf(meshfile, "%d %d 2 %d %d", + MSH_ELEMENT_NUM++, type, MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*P)->iEnt, + (*P)->iEnt); else fprintf(meshfile, "%d %d %d %d %d", MSH_ELEMENT_NUM++, type, @@ -330,10 +325,10 @@ void print_msh_point(Vertex * V) return; } - if(MSH_VERSION > 1.0) - fprintf(meshfile, "%d %d %d %d 0 1 %d\n", - MSH_ELEMENT_NUM++, POINT, - MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : V->Num, V->Num, V->Num); + if(CTX.mesh.msh_file_version == 2.0) + fprintf(meshfile, "%d %d 2 %d %d %d\n", + MSH_ELEMENT_NUM++, POINT, MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : V->Num, V->Num, + V->Num); else fprintf(meshfile, "%d %d %d %d 1 %d\n", MSH_ELEMENT_NUM++, POINT, @@ -502,7 +497,7 @@ void process_msh_elements(Mesh * M) else print_msh_elements(M); - if(MSH_VERSION > 1.0) + if(CTX.mesh.msh_file_version == 2.0) fprintf(meshfile, "$Elements\n"); else fprintf(meshfile, "$ELM\n"); @@ -519,7 +514,7 @@ void process_msh_elements(Mesh * M) else print_msh_elements(M); - if(MSH_VERSION > 1.0) + if(CTX.mesh.msh_file_version == 2.0) fprintf(meshfile, "$EndElements\n"); else fprintf(meshfile, "$ENDELM\n"); @@ -1399,12 +1394,20 @@ void Print_Mesh(Mesh * M, char *c, int Type) switch(Type){ case FORMAT_MSH: - MSH_VERSION = 0.0; - if(MSH_VERSION > 1.0){ + if(CTX.mesh.msh_file_version == 1.0){ + // OK, no header + } + else if(CTX.mesh.msh_file_version == 2.0){ fprintf(meshfile, "$MeshFormat\n"); - fprintf(meshfile, "%g %d %d\n", MSH_VERSION, LIST_FORMAT_ASCII, sizeof(double)); + fprintf(meshfile, "%g %d %d\n", CTX.mesh.msh_file_version, + LIST_FORMAT_ASCII, sizeof(double)); fprintf(meshfile, "$EndMeshFormat\n"); } + else{ + Msg(GERROR, "Unknown MSH file version to generate (%g)", + CTX.mesh.msh_file_version); + return; + } process_msh_nodes(M); process_msh_elements(M); Msg(INFO, "%d nodes", MSH_NODE_NUM); diff --git a/Mesh/Read_Mesh.cpp b/Mesh/Read_Mesh.cpp index 002cde66aa..6dcdd86787 100644 --- a/Mesh/Read_Mesh.cpp +++ b/Mesh/Read_Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: Read_Mesh.cpp,v 1.61 2003-12-07 02:56:34 geuzaine Exp $ +// $Id: Read_Mesh.cpp,v 1.62 2003-12-07 05:37:00 geuzaine Exp $ // // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle // @@ -93,6 +93,7 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp) int format = LIST_FORMAT_ASCII, size = sizeof(double); int Nbr_Nodes, Nbr_Elements, i_Node, i_Element; int Num, Type, Physical, Elementary, Partition, i, j; + int NbTags, Tag; double x, y, z, lc1, lc2; Vertex *vert, verts[NB_NOD_MAX_ELM], *vertsp[NB_NOD_MAX_ELM], **vertspp; Simplex *simp; @@ -118,7 +119,15 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp) if(!strncmp(&String[1], "MeshFormat", 10)) { fscanf(fp, "%lf %d %d\n", &version, &format, &size); - Msg(INFO, "Detected mesh file format %g", version); + + if(version == 2.0){ + Msg(INFO, "Detected mesh file format %g", version); + } + else{ + Msg(GERROR, "Unknown MSH file version to read (%g)", version); + return; + } + if(format == 0) format = LIST_FORMAT_ASCII; else if(format == 1) @@ -129,7 +138,7 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp) } } - /* P T S */ + /* POINTS -- this field is deprecated, and will eventually disappear */ if(!strncmp(&String[1], "PTS", 3) || !strncmp(&String[1], "Points", 6)) { @@ -148,7 +157,7 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp) } } - /* N O E */ + /* NODES */ if(!strncmp(&String[1], "NOD", 3) || !strncmp(&String[1], "NOE", 3) || @@ -197,8 +206,35 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp) Partition = Physical; } else{ - fscanf(fp, "%d %d %d %d %d %d", - &Num, &Type, &Physical, &Elementary, &Partition, &Nbr_Nodes); + fscanf(fp, "%d %d %d", &Num, &Type, &NbTags); + Elementary = Physical = Partition = 1; + for(j = 0; j < NbTags; j++){ + fscanf(fp, "%d", &Tag); + if(j == 0) + Physical = Tag; + else if(j == 1) + Elementary = Tag; + else if(j == 2) + Partition = Tag; + // ignore any other tags for now + } + switch (Type) { + case PNT : Nbr_Nodes = 1; break; + case LGN1: Nbr_Nodes = 2; break; + case LGN2: Nbr_Nodes = 3; break; + case TRI1: Nbr_Nodes = 3; break; + case TRI2: Nbr_Nodes = 6; break; + case QUA1: Nbr_Nodes = 4; break; + case QUA2: Nbr_Nodes = 8; break; + case TET1: Nbr_Nodes = 4; break; + case TET2: Nbr_Nodes = 10; break; + case HEX1: Nbr_Nodes = 8; break; + case HEX2: Nbr_Nodes = 20; break; + case PRI1: Nbr_Nodes = 6; break; + case PRI2: Nbr_Nodes = 15; break; + case PYR1: Nbr_Nodes = 5; break; + case PYR2: Nbr_Nodes = 13; break; + } } for(j = 0; j < Nbr_Nodes; j++) diff --git a/doc/VERSIONS b/doc/VERSIONS index b5bb0c9ad0..6247816d16 100644 --- a/doc/VERSIONS +++ b/doc/VERSIONS @@ -1,6 +1,7 @@ -$Id: VERSIONS,v 1.176 2003-12-07 00:29:47 geuzaine Exp $ +$Id: VERSIONS,v 1.177 2003-12-07 05:37:00 geuzaine Exp $ New in 1.51: initial support for visualizing mesh partitions; +integrated version 2.0 of the MSH mesh file format; New in 1.50: small changes to the visibility browser + made visibility scriptable (new Show/Hide commands); fixed (rare) crash when deleting diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi index 395027a640..8d5c443129 100644 --- a/doc/texinfo/gmsh.texi +++ b/doc/texinfo/gmsh.texi @@ -1,5 +1,5 @@ \input texinfo.tex @c -*-texinfo-*- -@c $Id: gmsh.texi,v 1.91 2003-12-04 18:24:50 geuzaine Exp $ +@c $Id: gmsh.texi,v 1.92 2003-12-07 05:37:00 geuzaine Exp $ @c @c Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle @c @@ -235,6 +235,11 @@ File formats * Gmsh parsed post-processing file format:: * Gmsh node ordering:: +Gmsh mesh file format + +* Version 1.0:: +* Version 2.0:: + Bugs, versions and credits * Bugs:: @@ -2605,9 +2610,24 @@ All non-parsed file formats have sections enclosed between @code{$KEY} and @cindex File format, mesh @cindex @file{.msh} file -The @file{.msh} file format is Gmsh's native mesh file format. The file is -divided in two sections, defining the nodes (@code{$NOD}-@code{$ENDNOD}) and -the elements (@code{$ELM}-@code{$ENDELM}) in the mesh: +@menu +* Version 1.0:: +* Version 2.0:: +@end menu + +@c ......................................................................... +@c Version 1.0 +@c ......................................................................... + +@node Version 1.0, Version 2.0, Gmsh mesh file format, Gmsh mesh file format +@subsection Version 1.0 + +The @file{.msh} file format, version 1.0, is Gmsh's old native mesh file +format, now superseeded by the format described in @ref{Version 2.0}. + +In the @file{.msh} file format, version 1.0, the file is divided in two +sections, defining the nodes (@code{$NOD}-@code{$ENDNOD}) and the elements +(@code{$ELM}-@code{$ENDELM}) in the mesh: @example $NOD @@ -2626,7 +2646,7 @@ $ENDELM where @table @code @item @var{number-of-nodes} -is the number of nodes in the mesh +is the number of nodes in the mesh. @item @var{node-number} is the number (index) of the @var{n}-th node in the mesh. Note that the @@ -2638,7 +2658,7 @@ are the floating point values giving the X, Y and Z coordinates of the @var{n}-th node. @item @var{number-of-elements} -is the number of elements in the mesh +is the number of elements in the mesh. @item @var{elm-number} is the number (index) of the @var{n}-th element in the mesh. Note that the @@ -2674,15 +2694,116 @@ is the number of the elementary entity to which the element belongs. @item @var{number-of-nodes} is the number of nodes for the @var{n}-th element. This is redundant, but -kept for backward compatibility. The redundancy may disappear in the future -if higher order elements are implemented using the same @w{@var{elm-type}s} -as the current ones. +kept for backward compatibility. @item @var{node-number-list} is the list of the @var{number-of-nodes} node numbers of the @var{n}-th element (separated by white space, without commas). @end table +@c ......................................................................... +@c Version 2.0 +@c ......................................................................... + +@node Version 2.0, , Version 1.0, Gmsh mesh file format +@subsection Version 2.0 + +The version 2.0 of the @file{.msh} file format is the Gmsh's new native mesh +file format. It will eventually become the new default mesh format generated +by Gmsh. This new format is very similar to the old one, but is more +general: it contains information about itself and allows to attach an +arbitrary number of tags to each element. + +The @file{.msh} file format, version 2.0, is divided in three sections, +defining the file format (@code{$MeshFormat}-@code{$EndMeshFormat}), the +nodes (@code{$Nodes}-@code{$EndNodes}) and the elements +(@code{$Elements}-@code{$EndElements}) in the mesh: + +@example +$MeshFormat +2.0 @var{file-type} @var{data-size} +$EndMeshFormat +$Nodes +@var{number-of-nodes} +@var{node-number} @var{x-coord} @var{y-coord} @var{z-coord} +@dots{} +$EndNodes +$Elements +@var{number-of-elements} +@var{elm-number} @var{elm-type} @var{number-of-tags} < @var{tag} > @dots{} @var{node-number-list} +@dots{} +$EndElements +@end example + +@noindent +where +@table @code +@item @var{file-type} +is an integer equal to 0 in the ASCII file format. + +@item @var{data-size} +is an integer equal to the size of the floating point numbers used in the +file (usually, @var{data-size} = sizeof(double)). + +@item @var{number-of-nodes} +is the number of nodes in the mesh. + +@item @var{node-number} +is the number (index) of the @var{n}-th node in the mesh. Note that the +@w{@var{node-number}s} do not have to be given in a consecutive (or even an +ordered) way. + +@item @var{x-coord} @var{y-coord} @var{z-coord} +are the floating point values giving the X, Y and Z coordinates of the +@var{n}-th node. + +@item @var{number-of-elements} +is the number of elements in the mesh. + +@item @var{elm-number} +is the number (index) of the @var{n}-th element in the mesh. Note that the +@w{@var{elm-number}s} do not have to be given in a consecutive (or even an +ordered) way. + +@item @var{elm-type} +defines the geometrical type of the @var{n}-th element: +@table @code +@item 1 +Line (2 nodes, 1 edge). +@item 2 +Triangle (3 nodes, 3 edges). +@item 3 +Quadrangle (4 nodes, 4 edges). +@item 4 +Tetrahedron (4 nodes, 6 edges, 4 faces). +@item 5 +Hexahedron (8 nodes, 12 edges, 6 faces). +@item 6 +Prism (6 nodes, 9 edges, 5 faces). +@item 7 +Pyramid (5 nodes, 8 edges, 5 faces). +@item 15 +Point (1 node). +@end table + +@item @var{number-of-tags} +gives the number of (integer) tags for the @var{n}-th element. By default, +Gmsh generates meshes with two tags, but can read files with an arbitrary +number of tags (and currently only interprets the three first ones: see +below). + +@item @var{tag} +is an integer tag associated with the @var{n}-th element. By default, the +first tag is the number of the physical entity to which the element belongs; +the second tag is the number of the elementary geometrical entity to which +the element belongs; the third tag is the number of a mesh partition to +which the element belongs. + +@item @var{node-number-list} +is the list of the node numbers of the @var{n}-th element (separated by +white space, without commas). +@end table + @c ------------------------------------------------------------------------- @c Gmsh ASCII post-processing file format @c ------------------------------------------------------------------------- @@ -2752,7 +2873,7 @@ is an integer equal to 0 in the ASCII file format. @item @var{data-size} is an integer equal to the size of the floating point numbers used in the -file (usually, data-size = sizeof(double)). +file (usually, @var{data-size} = sizeof(double)). @item @var{view-name} is a string containing the name of the view (max. 256 characters). -- GitLab