Newer
Older
// Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
#include "GmshConfig.h"
#include "GmshDefines.h"
#include "GmshVersion.h"
#include "GmshMessage.h"
#include "OpenFile.h"
#include "CommandLine.h"
#include "Context.h"
#include "Options.h"
#include "GModel.h"
#include "CreateFile.h"
#include "OS.h"

Christophe Geuzaine
committed
#if defined(HAVE_FLTK)
#include <FL/Fl.H>
#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 1) && (FL_PATCH_VERSION > 6)
// OK
#elif (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
// also OK
#else
#error "Gmsh requires FLTK >= 1.1.7 or FLTK 1.3.x"

Christophe Geuzaine
committed
#endif
#endif

Christophe Geuzaine
committed
#include "PView.h"
#endif
int GetGmshMajorVersion(){ return GMSH_MAJOR_VERSION; }
int GetGmshMinorVersion(){ return GMSH_MINOR_VERSION; }
int GetGmshPatchVersion(){ return GMSH_PATCH_VERSION; }
const char *GetGmshExtraVersion(){ return GMSH_EXTRA_VERSION; }
const char *GetGmshVersion(){ return GMSH_VERSION; }
const char *GetGmshBuildDate(){ return GMSH_DATE; }
const char *GetGmshBuildHost(){ return GMSH_HOST; }
const char *GetGmshPackager(){ return GMSH_PACKAGER; }
const char *GetGmshBuildOS(){ return GMSH_OS; }
const char *GetGmshShortLicense(){ return GMSH_SHORT_LICENSE; }
const char *GetGmshBuildOptions(){ return GMSH_CONFIG_OPTIONS; }
// texinfo documentation (doc/texinfo/gmsh.texi) and the man page
// (doc/gmsh.1)
Msg::Direct("Usage: %s [options] [files]", name);
Msg::Direct("Geometry options:");
Msg::Direct(" -0 Output unrolled geometry, then exit");
Msg::Direct(" -tol float Set geometrical tolerance");
Msg::Direct(" -match Match geometries and meshes");
Msg::Direct("Mesh options:");
Msg::Direct(" -1, -2, -3 Perform 1D, 2D or 3D mesh generation, then exit");
Msg::Direct(" -refine Perform uniform mesh refinement, then exit");
Msg::Direct(" -renumber Renumber the mesh elements after batch mesh generation");
Msg::Direct(" -saveall Save all elements (discard physical group definitions)");
Msg::Direct(" -o file Specify mesh output file name");
Msg::Direct(" -format string Set output mesh format (msh, msh1, msh2, unv, vrml, stl, mesh,");
Msg::Direct(" bdf, p3d, cgns, med, ir3)");
Msg::Direct(" -bin Use binary format when available");
Msg::Direct(" -parametric Save vertices with their parametric coordinates");

Jean-François Remacle
committed
Msg::Direct(" -numsubedges Set the number of subdivisions when displaying high order elements");

Christophe Geuzaine
committed
Msg::Direct(" -algo string Select mesh algorithm (meshadapt, del2d, front2d, del3d, front3d)");
Msg::Direct(" -smooth int Set number of mesh smoothing steps");
Msg::Direct(" -order int Set mesh order (1, ..., 5)");

Christophe Geuzaine
committed
Msg::Direct(" -optimize[_netgen] Optimize quality of tetrahedral elements");
Msg::Direct(" -optimize_hom Optimize higher order meshes (in 2D)");

Christophe Geuzaine
committed
Msg::Direct(" -optimize_lloyd Optimize 2D meshes using Lloyd algorithm");

Christophe Geuzaine
committed
Msg::Direct(" -clscale float Set global mesh element size scaling factor");
Msg::Direct(" -clmin float Set minimum mesh element size");
Msg::Direct(" -clmax float Set maximum mesh element size");
Msg::Direct(" -clcurv Automatically compute element sizes from curvatures");
Msg::Direct(" -epslc1d Set the accuracy of the evaluation of the LCFIELD for 1D mesh");
Msg::Direct(" -swapangle Set the treshold angle (in degree) between two adjacent faces");
Msg::Direct(" below which a swap is allowed");
Msg::Direct(" -rand float Set random perturbation factor");
Msg::Direct(" -bgm file Load background mesh from file");
Msg::Direct(" -check Perform various consistency checks on mesh");
Msg::Direct("Post-processing options:");
Msg::Direct(" -noview Hide all views on startup");
Msg::Direct(" -link int Select link mode between views (0, 1, 2, 3, 4)");
Msg::Direct(" -combine Combine views having identical names into multi-time-step views");
Msg::Direct("Display options:");
Msg::Direct(" -nodb Disable double buffering");
Msg::Direct(" -fontsize int Specify the font size for the GUI");
Msg::Direct(" -theme string Specify FLTK GUI theme");
Msg::Direct(" -display string Specify display");
Msg::Direct("Other options:");
Msg::Direct(" - Parse input files, then exit");
Msg::Direct(" -a, -g, -m, -s, -p Start in automatic, geometry, mesh, solver or post-processing mode");
#endif
#if defined(HAVE_LUA)
Msg::Direct(" -lua Start an interactive lua session");
Msg::Direct(" -pid Print process id on stdout");
Msg::Direct(" -listen Always listen to incoming connection requests");
Msg::Direct(" -watch pattern Pattern of files to merge as they become available");
Msg::Direct(" -v int Set verbosity level");
Msg::Direct(" -nopopup Don't popup dialog windows in scripts");
Msg::Direct(" -string \"string\" Parse option string at startup");
Msg::Direct(" -option file Parse option file at startup");
Msg::Direct(" -convert files Convert files into latest binary formats, then exit");
Msg::Direct(" -version Show version number");
Msg::Direct(" -info Show detailed version information");
Msg::Direct(" -help Show this message");
void GetOptions(int argc, char *argv[])
// print messages on terminal
int terminal = CTX::instance()->terminal;
CTX::instance()->terminal = 1;
ParseFile(CTX::instance()->homeDir + CTX::instance()->sessionFileName, true);
ParseFile(CTX::instance()->homeDir + CTX::instance()->optionsFileName, true);

Christophe Geuzaine
committed
if(!strcmp(argv[i] + 1, "")) {
CTX::instance()->batch = -99;
i++;
}
else if(!strcmp(argv[i] + 1, "socket")) {
Msg::Fatal("Missing string");
CTX::instance()->batch = -3;

Christophe Geuzaine
committed
else if(!strcmp(argv[i] + 1, "check")) {
CTX::instance()->batch = -2;
i++;
}
else if(!strcmp(argv[i] + 1, "0")) {
CTX::instance()->batch = -1;
i++;
}
else if(!strcmp(argv[i] + 1, "1")) {
CTX::instance()->batch = 1;
i++;
}
else if(!strcmp(argv[i] + 1, "2")) {
CTX::instance()->batch = 2;
i++;
}
else if(!strcmp(argv[i] + 1, "3")) {
CTX::instance()->batch = 3;
CTX::instance()->batch = 4;
else if(!strcmp(argv[i] + 1, "refine")) {
CTX::instance()->batch = 5;
else if(!strcmp(argv[i] + 1, "renumber")) {
CTX::instance()->batchAfterMesh = 1;
opt_mesh_partition_num(0, GMSH_SET, atoi(argv[i++]));
}
else
Msg::Fatal("Missing number");
}
else if(!strcmp(argv[i] + 1, "new")) {
CTX::instance()->files.push_back("-new");
CTX::instance()->initialContext = 0;
CTX::instance()->initialContext = 1;
CTX::instance()->initialContext = 2;
CTX::instance()->initialContext = 3;
CTX::instance()->initialContext = 4;
CTX::instance()->mesh.saveAll = 1;
CTX::instance()->mesh.optimize = 1;
else if(!strcmp(argv[i] + 1, "optimize_netgen")) {
CTX::instance()->mesh.optimizeNetgen = 1;

Christophe Geuzaine
committed
else if(!strcmp(argv[i] + 1, "optimize_hom")) {
i++;
opt_mesh_smooth_internal_edges(0, GMSH_SET, 1);
}
else if(!strcmp(argv[i] + 1, "optimize_lloyd")) {
i++;
CTX::instance()->mesh.optimizeLloyd = 1;
}
CTX::instance()->noPopup = 1;

Christophe Geuzaine
committed
if(argv[i]){
std::string tmp = argv[i++];
if(tmp.size() > 2 && tmp[0] == '"' && tmp[tmp.size() - 1] == '"')
CTX::instance()->watchFilePattern = tmp.substr(1, tmp.size() - 2);
else
CTX::instance()->watchFilePattern = tmp;
}
else
Msg::Fatal("Missing string");
ParseFile(argv[i++], true);
else
Msg::Fatal("Missing file name");
CTX::instance()->outputFileName = argv[i++];
else
Msg::Fatal("Missing file name");
CTX::instance()->bgmFileName = argv[i++];
else
Msg::Fatal("Missing file name");
else if(!strcmp(argv[i] + 1, "nw")) {
i++;
CTX::instance()->numWindows = atoi(argv[i++]);
else
Msg::Fatal("Missing number");
}
else if(!strcmp(argv[i] + 1, "nt")) {
i++;
CTX::instance()->numTiles = atoi(argv[i++]);
Msg::Fatal("Missing number");
CTX::instance()->batch = 1;
std::string fileName = std::string(argv[i]) + "_new";

Christophe Geuzaine
committed
#endif
PView::list[j]->write(fileName, 1, (j == n) ? false : true);

Christophe Geuzaine
committed
#endif
// convert mesh to latest binary format
if(GModel::current()->getMeshStatus() > 0){
CTX::instance()->mesh.mshFileVersion = 2.0;
CTX::instance()->mesh.binary = 1;
Msg::Exit(0);
CTX::instance()->geom.tolerance = atof(argv[i++]);
else
Msg::Fatal("Missing number");

Jean-François Remacle
committed
else if(!strcmp(argv[i] + 1, "match")) {
CTX::instance()->geom.matchGeomAndMesh = 1;

Jean-François Remacle
committed
}
CTX::instance()->geom.scalingFactor = atof(argv[i++]);
else
Msg::Fatal("Missing number");
CTX::instance()->mesh.scalingFactor = atof(argv[i++]);
else
Msg::Fatal("Missing number");
CTX::instance()->mesh.randFactor = atof(argv[i++]);
else
Msg::Fatal("Missing number");
CTX::instance()->mesh.lcFactor = atof(argv[i++]);
if(CTX::instance()->mesh.lcFactor <= 0.0)

Christophe Geuzaine
committed
Msg::Fatal("Mesh element size factor must be > 0");
else
Msg::Fatal("Missing number");
}
else if(!strcmp(argv[i] + 1, "clmin")) {
i++;
CTX::instance()->mesh.lcMin = atof(argv[i++]);
if(CTX::instance()->mesh.lcMin <= 0.0)
Msg::Fatal("Minimum length size must be > 0");
else
Msg::Fatal("Missing number");
else if(!strcmp(argv[i] + 1, "clmax")) {
i++;
CTX::instance()->mesh.lcMax = atof(argv[i++]);
if(CTX::instance()->mesh.lcMax <= 0.0)
Msg::Fatal("Maximum length size must be > 0");
else
Msg::Fatal("Missing number");
else if(!strcmp(argv[i] + 1, "edgelmin")) {
i++;
CTX::instance()->mesh.toleranceEdgeLength = atof(argv[i++]);
if(CTX::instance()->mesh.toleranceEdgeLength <= 0.0)
Msg::Fatal("Tolerance for model edge length must be > 0 (here %g)",
CTX::instance()->mesh.toleranceEdgeLength);
}
else
Msg::Fatal("Missing number");
}
else if(!strcmp(argv[i] + 1, "epslc1d")) {
i++;
CTX::instance()->mesh.lcIntegrationPrecision = atof(argv[i++]);
if(CTX::instance()->mesh.lcIntegrationPrecision <= 0.0)
Msg::Fatal("Integration accuracy must be > 0");
else
Msg::Fatal("Missing number");
}
else if(!strcmp(argv[i] + 1, "swapangle")) {
i++;
CTX::instance()->mesh.allowSwapEdgeAngle = atof(argv[i++]);
if(CTX::instance()->mesh.allowSwapEdgeAngle <= 0.0)
Msg::Fatal("Treshold angle for edge swap must be > 0");
else
Msg::Fatal("Missing number");
CTX::instance()->mesh.lcFromCurvature = 1;
CTX::instance()->mesh.nbSmoothing = atoi(argv[i++]);
else
Msg::Fatal("Missing number");
else if(!strcmp(argv[i] + 1, "order") || !strcmp(argv[i] + 1, "degree")) {
else
Msg::Fatal("Missing number");

Jean-François Remacle
committed
else if(!strcmp(argv[i] + 1, "numsubedges")) {
i++;

Jean-François Remacle
committed
opt_mesh_num_sub_edges(0, GMSH_SET, atof(argv[i++]));
else
Msg::Fatal("Missing number");

Jean-François Remacle
committed
}
else if(!strcmp(argv[i] + 1, "statreport")) {
i++;
CTX::instance()->createAppendMeshStatReport = 1;
CTX::instance()->meshStatReportFileName = argv[i++];
else
Msg::Fatal("Missing argument");
}
else if(!strcmp(argv[i] + 1, "append_statreport")) {
i++;
CTX::instance()->createAppendMeshStatReport = 2;
CTX::instance()->meshStatReportFileName = argv[i++];
else
Msg::Fatal("Missing argument");
else if(!strcmp(argv[i] + 1, "format") || !strcmp(argv[i] + 1, "f")) {
CTX::instance()->mesh.format = FORMAT_MSH;
CTX::instance()->mesh.mshFileVersion = 1.0;
CTX::instance()->mesh.format = FORMAT_MSH;
CTX::instance()->mesh.mshFileVersion = 2.0;
CTX::instance()->mesh.format = FORMAT_MSH;
CTX::instance()->mesh.format = FORMAT_UNV;
CTX::instance()->mesh.format = FORMAT_VRML;
CTX::instance()->mesh.format = FORMAT_STL;
CTX::instance()->mesh.format = FORMAT_MESH;
CTX::instance()->mesh.format = FORMAT_BDF;
CTX::instance()->mesh.format = FORMAT_P3D;
CTX::instance()->mesh.format = FORMAT_CGNS;
CTX::instance()->mesh.format = FORMAT_DIFF;
CTX::instance()->mesh.format = FORMAT_MED;
else if(!strcmp(argv[i], "ir3"))
CTX::instance()->mesh.format = FORMAT_IR3;
Msg::Fatal("Unknown mesh format");
else
Msg::Fatal("Missing format");
else if(!strcmp(argv[i] + 1, "bin")) {
i++;
CTX::instance()->mesh.binary = 1;
else if(!strcmp(argv[i] + 1, "parametric")) {
i++;
CTX::instance()->mesh.saveParametric = 1;
}

Christophe Geuzaine
committed
if(!strncmp(argv[i], "meshadapt", 9) || !strncmp(argv[i], "iso", 3))
CTX::instance()->mesh.algo2d = ALGO_2D_MESHADAPT;
else if(!strncmp(argv[i], "bds", 3))
CTX::instance()->mesh.algo2d = ALGO_2D_MESHADAPT_OLD;
else if(!strncmp(argv[i], "del2d", 5) || !strncmp(argv[i], "tri", 3))
CTX::instance()->mesh.algo2d = ALGO_2D_DELAUNAY;

Christophe Geuzaine
committed
else if(!strncmp(argv[i], "front2d", 7) || !strncmp(argv[i], "frontal", 7))
CTX::instance()->mesh.algo2d = ALGO_2D_FRONTAL;
else if(!strncmp(argv[i], "del3d", 5) || !strncmp(argv[i], "tetgen", 6))
CTX::instance()->mesh.algo2d = ALGO_3D_DELAUNAY;
else if(!strncmp(argv[i], "front3d", 7) || !strncmp(argv[i], "netgen", 6))
CTX::instance()->mesh.algo3d = ALGO_3D_FRONTAL;
else
Msg::Fatal("Unknown mesh algorithm");
else
Msg::Fatal("Missing algorithm");
CTX::instance()->solver.listen = 1;
else if(!strcmp(argv[i] + 1, "version") || !strcmp(argv[i] + 1, "-version")) {
Msg::Exit(0);
else if(!strcmp(argv[i] + 1, "info") || !strcmp(argv[i] + 1, "-info")) {
fprintf(stderr, "Version : %s\n", GMSH_VERSION);
fprintf(stderr, "GUI toolkit : FLTK %d.%d.%d\n", FL_MAJOR_VERSION,
fprintf(stderr, "GUI toolkit : none\n");
fprintf(stderr, "License : %s\n", GMSH_SHORT_LICENSE);
fprintf(stderr, "Build OS : %s\n", GMSH_OS);
fprintf(stderr, "Build options :%s\n", GMSH_CONFIG_OPTIONS);
fprintf(stderr, "Build date : %s\n", GMSH_DATE);
fprintf(stderr, "Build host : %s\n", GMSH_HOST);
fprintf(stderr, "Packager : %s\n", GMSH_PACKAGER);
fprintf(stderr, "Web site : http://www.geuz.org/gmsh/\n");
fprintf(stderr, "Mailing list : gmsh@geuz.org\n");
Msg::Exit(0);
else if(!strcmp(argv[i] + 1, "help") || !strcmp(argv[i] + 1, "-help")) {
fprintf(stderr, "Gmsh, a 3D mesh generator with pre- and post-processing facilities\n");
fprintf(stderr, "Copyright (C) 1997-2010 Christophe Geuzaine and Jean-Francois Remacle\n");
Msg::Exit(0);
Msg::SetVerbosity(atoi(argv[i++]));
else
Msg::Fatal("Missing number");
terminal = 1;
CTX::instance()->mesh.dual = 1;
else if(!strcmp(argv[i] + 1, "voronoi")) {
CTX::instance()->mesh.voronoi = 1;
else if(!strcmp(argv[i] + 1, "noview")) {
opt_view_visible(0, GMSH_SET, 0);
i++;
CTX::instance()->post.link = atoi(argv[i++]);
else
Msg::Fatal("Missing number");
CTX::instance()->post.smooth = 1;
CTX::instance()->post.combineTime = 1;
CTX::instance()->db = 0;
CTX::instance()->fontSize = atoi(argv[i++]);
else
Msg::Fatal("Missing number");
else if(!strcmp(argv[i] + 1, "deltafontsize")) {
i++;
CTX::instance()->deltaFontSize = atoi(argv[i++]);
Msg::Fatal("Missing number");
else if(!strcmp(argv[i] + 1, "theme") || !strcmp(argv[i] + 1, "scheme")) {
CTX::instance()->guiTheme = argv[i++];
else
Msg::Fatal("Missing argument");
CTX::instance()->display = argv[i++];
else
Msg::Fatal("Missing argument");
#if defined (HAVE_LUA)
else if(!strcmp(argv[i] + 1, "lua")) {
i++;
CTX::instance()->batch = -4;
}
#endif
else if(!strncmp(argv[i] + 1, "psn", 3)) {
// The Mac Finder launches programs with a special command
// line argument of the form -psn_XXX: just ignore it silently
// (and don't exit!)
Msg::Error("Unknown option '%s'", argv[i]);
Msg::Exit(1);
CTX::instance()->files.push_back(argv[i++]);
if(CTX::instance()->files.empty()){
std::string base = (getenv("PWD") ? "" : CTX::instance()->homeDir);
GModel::current()->setFileName(base + CTX::instance()->defaultFileName);
GModel::current()->setFileName(CTX::instance()->files[0]);
CTX::instance()->terminal = terminal;