PageRenderTime 83ms CodeModel.GetById 2ms app.highlight 74ms RepoModel.GetById 1ms app.codeStats 0ms

/Common/CommandLine.cpp

https://bitbucket.org/lge/gmsh
C++ | 826 lines | 796 code | 15 blank | 15 comment | 308 complexity | 8d18c362b367536d0eb7e94cf0ccb286 MD5 | raw file
  1// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle
  2//
  3// See the LICENSE.txt file for license information. Please report all
  4// bugs and problems to <gmsh@geuz.org>.
  5
  6#include <string>
  7#include <string.h>
  8#include <stdlib.h>
  9#include "GmshConfig.h"
 10#include "GmshDefines.h"
 11#include "GmshVersion.h"
 12#include "GmshMessage.h"
 13#include "OpenFile.h"
 14#include "CommandLine.h"
 15#include "Context.h"
 16#include "Options.h"
 17#include "GModel.h"
 18#include "CreateFile.h"
 19#include "OS.h"
 20
 21#if defined(HAVE_FLTK)
 22#include <FL/Fl.H>
 23#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION >= 3)
 24// OK
 25#else
 26#error "Gmsh requires FLTK >= 1.3"
 27#endif
 28#endif
 29
 30#if defined(HAVE_POST)
 31#include "PView.h"
 32#endif
 33
 34int GetGmshMajorVersion(){ return GMSH_MAJOR_VERSION; }
 35int GetGmshMinorVersion(){ return GMSH_MINOR_VERSION; }
 36int GetGmshPatchVersion(){ return GMSH_PATCH_VERSION; }
 37const char *GetGmshExtraVersion(){ return GMSH_EXTRA_VERSION; }
 38const char *GetGmshVersion(){ return GMSH_VERSION; }
 39const char *GetGmshBuildDate(){ return GMSH_DATE; }
 40const char *GetGmshBuildHost(){ return GMSH_HOST; }
 41const char *GetGmshPackager(){ return GMSH_PACKAGER; }
 42const char *GetGmshBuildOS(){ return GMSH_OS; }
 43const char *GetGmshShortLicense(){ return GMSH_SHORT_LICENSE; }
 44const char *GetGmshBuildOptions(){ return GMSH_CONFIG_OPTIONS; }
 45
 46void PrintUsage(const char *name)
 47{
 48  // If you make changes in this routine, please also change the texinfo
 49  // documentation (doc/texinfo/gmsh.texi) and the man page (doc/gmsh.1)
 50  Msg::Direct("Usage: %s [options] [files]", name);
 51  Msg::Direct("Geometry options:");
 52  Msg::Direct("  -0                    Output unrolled geometry, then exit");
 53  Msg::Direct("  -tol float            Set geometrical tolerance");
 54  Msg::Direct("  -match                Match geometries and meshes");
 55  Msg::Direct("Mesh options:");
 56  Msg::Direct("  -1, -2, -3            Perform 1D, 2D or 3D mesh generation, then exit");
 57  Msg::Direct("  -format string        Select output mesh format (auto (default), msh, msh1, msh2,");
 58  Msg::Direct("                          unv, vrml, ply2, stl, mesh, bdf, cgns, p3d, diff, med, ...)");
 59  Msg::Direct("  -refine               Perform uniform mesh refinement, then exit");
 60  Msg::Direct("  -part int             Partition after batch mesh generation");
 61  Msg::Direct("  -partWeight <tri|quad|tet|prism|hex> int");
 62  Msg::Direct("                          Weight of a triangle/quad/etc. during partitioning");
 63  Msg::Direct("  -renumber             Renumber the mesh elements after batch mesh generation");
 64  Msg::Direct("  -saveall              Save all elements (discard physical group definitions)");
 65  Msg::Direct("  -o file               Specify output file name");
 66  Msg::Direct("  -bin                  Use binary format when available");
 67  Msg::Direct("  -parametric           Save vertices with their parametric coordinates");
 68  Msg::Direct("  -numsubedges          Set the number of subdivisions when displaying high order elements");
 69  Msg::Direct("  -algo string          Select mesh algorithm (meshadapt, del2d, front2d, delquad, ");
 70  Msg::Direct("                          del3d, front3d, mmg3d)");
 71  Msg::Direct("  -smooth int           Set number of mesh smoothing steps");
 72  Msg::Direct("  -order int            Set mesh order (1, ..., 5)");
 73  Msg::Direct("  -hoOptimize           Optimize high order meshes");
 74  Msg::Direct("  -hoMindisto float     Minimum quality for high-order elements before optimization (0.0->1.0)");
 75  Msg::Direct("  -hoNLayers int        Number of high order element layers to optimize");
 76  Msg::Direct("  -hoElasticity float   Poisson ration for the elasticity analogy (-1.0 < nu < 0.5)");
 77  Msg::Direct("  -optimize[_netgen]    Optimize quality of tetrahedral elements");
 78  Msg::Direct("  -optimize_lloyd       Optimize 2D meshes using Lloyd algorithm");
 79  Msg::Direct("  -clscale float        Set global mesh element size scaling factor");
 80  Msg::Direct("  -clmin float          Set minimum mesh element size");
 81  Msg::Direct("  -clmax float          Set maximum mesh element size");
 82  Msg::Direct("  -anisoMax float       Set maximum anisotropy (only used in bamg for now)");
 83  Msg::Direct("  -smoothRatio float    Set smoothing ration between mesh sizes at nodes of a same edge");
 84  Msg::Direct("                          (only used in bamg)");
 85  Msg::Direct("  -clcurv               Automatically compute element sizes from curvatures");
 86  Msg::Direct("  -epslc1d              Set the accuracy of the evaluation of the LCFIELD for 1D mesh");
 87  Msg::Direct("  -swapangle            Set the threshold angle (in degree) between two adjacent faces");
 88  Msg::Direct("                          below which a swap is allowed");
 89  Msg::Direct("  -rand float           Set random perturbation factor");
 90  Msg::Direct("  -bgm file             Load background mesh from file");
 91  Msg::Direct("  -check                Perform various consistency checks on mesh");
 92  Msg::Direct("  -mpass int            Do several passes on the mesh for complex backround fields");
 93  Msg::Direct("  -ignorePartBound      Ignore partitions boundaries");
 94#if defined(HAVE_FLTK)
 95  Msg::Direct("Post-processing options:");
 96  Msg::Direct("  -link int             Select link mode between views (0, 1, 2, 3, 4)");
 97  Msg::Direct("  -combine              Combine views having identical names into multi-time-step views");
 98  Msg::Direct("Display options:");
 99  Msg::Direct("  -n                    Hide all meshes and post-processing views on startup");
100  Msg::Direct("  -nodb                 Disable double buffering");
101  Msg::Direct("  -fontsize int         Specify the font size for the GUI");
102  Msg::Direct("  -theme string         Specify FLTK GUI theme");
103  Msg::Direct("  -display string       Specify display");
104#endif
105  Msg::Direct("Other options:");
106  Msg::Direct("  -                     Parse input files, then exit");
107#if defined(HAVE_FLTK)
108  Msg::Direct("  -a, -g, -m, -s, -p    Start in automatic, geometry, mesh, solver or post-processing mode");
109#endif
110  Msg::Direct("  -pid                  Print process id on stdout");
111  Msg::Direct("  -listen               Always listen to incoming connection requests");
112  Msg::Direct("  -watch pattern        Pattern of files to merge as they become available");
113  Msg::Direct("  -v int                Set verbosity level");
114  Msg::Direct("  -nopopup              Don't popup dialog windows in scripts");
115  Msg::Direct("  -string \"string\"      Parse option string at startup");
116  Msg::Direct("  -option file          Parse option file at startup");
117  Msg::Direct("  -convert files        Convert files into latest binary formats, then exit");
118  Msg::Direct("  -vmsh float           Select msh file version");
119  Msg::Direct("  -version              Show version number");
120  Msg::Direct("  -info                 Show detailed version information");
121  Msg::Direct("  -help                 Show this message");
122}
123
124void GetOptions(int argc, char *argv[])
125{
126  // print messages on terminal
127  int terminal = CTX::instance()->terminal;
128  CTX::instance()->terminal = 1;
129
130#if defined(HAVE_PARSER)
131  if(argc && argv){
132    // parse session and option file (if argc/argv is not provided skip this
133    // step: this is usually what is expected when using Gmsh as a library)
134    ParseFile(CTX::instance()->homeDir + CTX::instance()->sessionFileName, true);
135    ParseFile(CTX::instance()->homeDir + CTX::instance()->optionsFileName, true);
136  }
137#endif
138
139  if(argc) Msg::SetExecutableName(argv[0]);
140
141  // get command line options
142  int i = 1;
143  while(i < argc) {
144
145    if(argv[i][0] == '-') {
146
147      if(!strcmp(argv[i] + 1, "")) {
148        CTX::instance()->batch = -99;
149        i++;
150      }
151      else if(!strcmp(argv[i] + 1, "onelab")) {
152        i++;
153        if(argv[i] && argv[i + 1] && argv[i + 1][0] != '-'){
154          Msg::InitializeOnelab(argv[i], argv[i + 1]);
155          i += 2;
156        }
157        else if(argv[i]){
158          Msg::InitializeOnelab(argv[i]);
159          i += 1;
160        }
161        else
162          Msg::Fatal("Missing client name and/or address of OneLab server");
163      }
164      else if(!strcmp(argv[i] + 1, "lol")) {
165        i++;
166        if(argv[i] && argv[i + 1] && argv[i + 1][0] != '-'){
167          Msg::LoadOnelabClient(argv[i], argv[i + 1]);
168          i += 2;
169        }
170        else
171          Msg::Fatal("Missing client name and/or address of OneLab server");
172      }
173      else if(!strcmp(argv[i] + 1, "socket")) {
174        i++;
175        if(argv[i])
176          Msg::InitializeOnelab("GmshRemote", argv[i++]);
177        else
178          Msg::Fatal("Missing string");
179        CTX::instance()->batch = -3;
180      }
181      else if(!strcmp(argv[i] + 1, "check")) {
182        CTX::instance()->batch = -2;
183        i++;
184      }
185      else if(!strcmp(argv[i] + 1, "0")) {
186        CTX::instance()->batch = -1;
187        i++;
188      }
189      else if(!strcmp(argv[i] + 1, "1")) {
190        CTX::instance()->batch = 1;
191        i++;
192      }
193      else if(!strcmp(argv[i] + 1, "2")) {
194        CTX::instance()->batch = 2;
195        i++;
196      }
197      else if(!strcmp(argv[i] + 1, "3")) {
198        CTX::instance()->batch = 3;
199        i++;
200      }
201      else if(!strcmp(argv[i] + 1, "4")) {
202        CTX::instance()->batch = 4;
203        i++;
204      }
205      else if(!strcmp(argv[i] + 1, "refine")) {
206        CTX::instance()->batch = 5;
207        i++;
208      }
209      else if(!strcmp(argv[i] + 1, "renumber")) {
210        CTX::instance()->batchAfterMesh = 1;
211        CTX::instance()->partitionOptions.renumber = 1;
212        i++;
213      }
214      else if(!strcmp(argv[i] + 1, "part")) {
215        i++;
216        if(argv[i]){
217          CTX::instance()->batchAfterMesh = 1 ;
218          opt_mesh_partition_num(0, GMSH_SET, atoi(argv[i++]));
219        }
220        else
221          Msg::Fatal("Missing number");
222      }
223      else if (!strcmp(argv[i] + 1,"partWeight")) {
224        i++;
225        bool check = true;
226        opt_mesh_partition_partitioner(0, GMSH_SET, 2); // Metis partitioner
227        opt_mesh_partition_metis_algorithm(0, GMSH_SET, 3); // partGraphKWay w/ weights
228        while (check) {
229          if (argv[i]) {
230            if (!strcmp(argv[i],"triangle")) {
231              i++;
232              opt_mesh_partition_tri_weight(0,GMSH_SET,atoi(argv[i]));
233            }
234            else if (!strcmp(argv[i],"quad")) {
235              i++;
236              opt_mesh_partition_qua_weight(0,GMSH_SET,atoi(argv[i]));
237            }
238            else if (!strcmp(argv[i],"tet")) {
239              i++;
240              opt_mesh_partition_tet_weight(0,GMSH_SET,atoi(argv[i]));
241            }
242            else if (!strcmp(argv[i],"prism")) {
243              i++;
244              opt_mesh_partition_pri_weight(0,GMSH_SET,atoi(argv[i]));
245            }
246            else if (!strcmp(argv[i],"pyramid")) {
247              i++;
248              opt_mesh_partition_pyr_weight(0,GMSH_SET,atoi(argv[i]));
249            }
250            else if (!strcmp(argv[i],"hex")) {
251              i++;
252              opt_mesh_partition_hex_weight(0,GMSH_SET,atoi(argv[i]));
253            }
254            else check = false;
255            i++;
256          }
257          else check = false;
258        }
259      }
260      else if(!strcmp(argv[i] + 1, "new")) {
261        CTX::instance()->files.push_back("-new");
262        i++;
263      }
264      else if(!strcmp(argv[i] + 1, "pid")) {
265        fprintf(stdout, "%d\n", GetProcessId());
266        fflush(stdout);
267        i++;
268      }
269      else if(!strcmp(argv[i] + 1, "a")) {
270        CTX::instance()->initialContext = 0;
271        i++;
272      }
273      else if(!strcmp(argv[i] + 1, "g")) {
274        CTX::instance()->initialContext = 1;
275        i++;
276      }
277      else if(!strcmp(argv[i] + 1, "m")) {
278        CTX::instance()->initialContext = 2;
279        i++;
280      }
281      else if(!strcmp(argv[i] + 1, "s")) {
282        CTX::instance()->initialContext = 3;
283        i++;
284      }
285      else if(!strcmp(argv[i] + 1, "p")) {
286        CTX::instance()->initialContext = 4;
287        i++;
288      }
289      else if(!strcmp(argv[i] + 1, "saveall")) {
290        CTX::instance()->mesh.saveAll = 1;
291        i++;
292      }
293      else if(!strcmp(argv[i] + 1, "switch_tags")) {
294        CTX::instance()->mesh.switchElementTags = 1;
295        i++;
296      }
297      else if(!strcmp(argv[i] + 1, "optimize")) {
298        CTX::instance()->mesh.optimize = 1;
299        i++;
300      }
301      else if(!strcmp(argv[i] + 1, "bunin")) {
302        i++;
303        if(argv[i])
304          CTX::instance()->mesh.bunin = atoi(argv[i++]);
305        else
306          Msg::Fatal("Missing cavity size in bunin optimization");
307      }
308      else if(!strcmp(argv[i] + 1, "optimize_netgen")) {
309        CTX::instance()->mesh.optimizeNetgen = 1;
310        i++;
311      }
312      else if(!strcmp(argv[i] + 1, "hoOptimize")) {
313        i++;
314        opt_mesh_smooth_internal_edges(0, GMSH_SET, 1);
315      }
316      else if(!strcmp(argv[i] + 1, "hoMindisto")) {
317        i++;
318        if(argv[i])
319          opt_mesh_ho_mindisto(0, GMSH_SET, atof(argv[i++]));
320        else
321          Msg::Fatal("Missing number");
322      }
323      else if(!strcmp(argv[i] + 1, "hoElasticity")) {
324        i++;
325        if(argv[i])
326          opt_mesh_ho_poisson(0, GMSH_SET, atof(argv[i++]));
327        else
328          Msg::Fatal("Missing number");
329      }
330      else if(!strcmp(argv[i] + 1, "hoNlayers")) {
331        i++;
332        if(argv[i])
333          opt_mesh_ho_nlayers(0, GMSH_SET, atoi(argv[i++]));
334        else
335          Msg::Fatal("Missing number");
336      }
337      else if(!strcmp(argv[i] + 1, "optimize_lloyd")) {
338        i++;
339        if(argv[i])
340          CTX::instance()->mesh.optimizeLloyd = atoi(argv[i++]);
341        else
342          Msg::Fatal("Missing number of lloyd iterations");
343      }
344      else if(!strcmp(argv[i] + 1, "nopopup")) {
345        CTX::instance()->noPopup = 1;
346        i++;
347      }
348      else if(!strcmp(argv[i] + 1, "watch")) {
349        i++;
350        if(argv[i]){
351          std::string tmp = argv[i++];
352          if(tmp.size() > 2 && tmp[0] == '"' && tmp[tmp.size() - 1] == '"')
353            CTX::instance()->watchFilePattern = tmp.substr(1, tmp.size() - 2);
354          else
355            CTX::instance()->watchFilePattern = tmp;
356        }
357        else
358          Msg::Fatal("Missing string");
359      }
360      else if(!strcmp(argv[i] + 1, "string")) {
361        i++;
362        if(argv[i])
363          ParseString(argv[i++]);
364        else
365          Msg::Fatal("Missing string");
366      }
367      else if(!strcmp(argv[i] + 1, "option")) {
368        i++;
369        if(argv[i])
370          ParseFile(argv[i++], true);
371        else
372          Msg::Fatal("Missing file name");
373      }
374      else if(!strcmp(argv[i] + 1, "o")) {
375        i++;
376        if(argv[i])
377          CTX::instance()->outputFileName = argv[i++];
378        else
379          Msg::Fatal("Missing file name");
380      }
381      else if(!strcmp(argv[i] + 1, "anisoMax")) {
382        i++;
383        if(argv[i])
384          CTX::instance()->mesh.anisoMax = atof(argv[i++]);
385        else
386          Msg::Fatal("Missing anisotropy ratio");
387      }
388      else if(!strcmp(argv[i] + 1, "smoothRatio")) {
389        i++;
390        if(argv[i])
391          CTX::instance()->mesh.smoothRatio = atof(argv[i++]);
392        else
393          Msg::Fatal("Missing smooth ratio");
394      }
395      else if(!strcmp(argv[i] + 1, "bgm")) {
396        i++;
397        if(argv[i])
398          CTX::instance()->bgmFileName = argv[i++];
399        else
400          Msg::Fatal("Missing file name");
401      }
402      else if(!strcmp(argv[i] + 1, "nw")) {
403        i++;
404        if(argv[i])
405          CTX::instance()->numWindows = atoi(argv[i++]);
406        else
407          Msg::Fatal("Missing number");
408      }
409      else if(!strcmp(argv[i] + 1, "nt")) {
410        i++;
411        if(argv[i])
412          CTX::instance()->numTiles = atoi(argv[i++]);
413        else
414          Msg::Fatal("Missing number");
415      }
416      else if(!strcmp(argv[i] + 1, "vmsh")) {
417        i++;
418        if(argv[i]){
419          CTX::instance()->mesh.mshFileVersion = atof(argv[i++]);
420        }
421        else
422          Msg::Fatal("Missing number");
423      }
424      else if(!strcmp(argv[i] + 1, "convert")) {
425        i++;
426        CTX::instance()->batch = 1;
427        while(i < argc) {
428          std::string fileName = std::string(argv[i]) + "_new";
429#if defined(HAVE_POST)
430          unsigned int n = PView::list.size();
431#endif
432          OpenProject(argv[i]);
433#if defined(HAVE_POST)
434          // convert post-processing views to latest binary format
435          for(unsigned int j = n; j < PView::list.size(); j++)
436            PView::list[j]->write(fileName, 1, (j == n) ? false : true);
437#endif
438          // convert mesh to latest binary format
439          if(GModel::current()->getMeshStatus() > 0){
440            CTX::instance()->mesh.mshFileVersion = 2.0;
441            CTX::instance()->mesh.binary = 1;
442            CreateOutputFile(fileName, FORMAT_MSH);
443          }
444          i++;
445        }
446        Msg::Exit(0);
447      }
448      else if(!strcmp(argv[i] + 1, "tol")) {
449        i++;
450        if(argv[i])
451          CTX::instance()->geom.tolerance = atof(argv[i++]);
452        else
453          Msg::Fatal("Missing number");
454      }
455      else if(!strcmp(argv[i] + 1, "match")) {
456        i++;
457        CTX::instance()->geom.matchGeomAndMesh = 1;
458      }
459      else if(!strcmp(argv[i] + 1, "scale")) {
460        i++;
461        if(argv[i])
462          CTX::instance()->geom.scalingFactor = atof(argv[i++]);
463        else
464          Msg::Fatal("Missing number");
465      }
466      else if(!strcmp(argv[i] + 1, "meshscale")) {
467        i++;
468        if(argv[i])
469          CTX::instance()->mesh.scalingFactor = atof(argv[i++]);
470        else
471          Msg::Fatal("Missing number");
472      }
473      else if(!strcmp(argv[i] + 1, "rand")) {
474        i++;
475        if(argv[i])
476          CTX::instance()->mesh.randFactor = atof(argv[i++]);
477        else
478          Msg::Fatal("Missing number");
479      }
480      else if(!strcmp(argv[i] + 1, "clscale")) {
481        i++;
482        if(argv[i]) {
483          CTX::instance()->mesh.lcFactor = atof(argv[i++]);
484          if(CTX::instance()->mesh.lcFactor <= 0.0)
485            Msg::Fatal("Mesh element size factor must be > 0");
486        }
487        else
488          Msg::Fatal("Missing number");
489      }
490      else if(!strcmp(argv[i] + 1, "clmin")) {
491        i++;
492        if(argv[i]) {
493          CTX::instance()->mesh.lcMin = atof(argv[i++]);
494          if(CTX::instance()->mesh.lcMin <= 0.0)
495            Msg::Fatal("Minimum length size must be > 0");
496        }
497        else
498          Msg::Fatal("Missing number");
499      }
500      else if(!strcmp(argv[i] + 1, "clmax")) {
501        i++;
502        if(argv[i]) {
503          CTX::instance()->mesh.lcMax = atof(argv[i++]);
504          if(CTX::instance()->mesh.lcMax <= 0.0)
505            Msg::Fatal("Maximum length size must be > 0");
506        }
507        else
508          Msg::Fatal("Missing number");
509      }
510      else if(!strcmp(argv[i] + 1, "mpass")) {
511        i++;
512        if(argv[i]) {
513          CTX::instance()->mesh.multiplePasses = atoi(argv[i++]);
514          if(CTX::instance()->mesh.multiplePasses <= 0)
515            Msg::Fatal("Number of Mesh Passes must be > 0");
516        }
517        else
518          Msg::Fatal("Missing number");
519      }
520      else if(!strcmp(argv[i] + 1, "ignorePartBound")) {
521        i++;
522        opt_mesh_ignore_part_bound(0, GMSH_SET, 1);
523      }
524      else if(!strcmp(argv[i] + 1, "edgelmin")) {
525        i++;
526        if(argv[i]) {
527          CTX::instance()->mesh.toleranceEdgeLength = atof(argv[i++]);
528          if(CTX::instance()->mesh.toleranceEdgeLength <= 0.0)
529            Msg::Fatal("Tolerance for model edge length must be > 0 (here %g)",
530                       CTX::instance()->mesh.toleranceEdgeLength);
531        }
532        else
533          Msg::Fatal("Missing number");
534      }
535      else if(!strcmp(argv[i] + 1, "epslc1d")) {
536        i++;
537        if(argv[i]) {
538          CTX::instance()->mesh.lcIntegrationPrecision = atof(argv[i++]);
539          if(CTX::instance()->mesh.lcIntegrationPrecision <= 0.0)
540            Msg::Fatal("Integration accuracy must be > 0");
541        }
542        else
543          Msg::Fatal("Missing number");
544      }
545      else if(!strcmp(argv[i] + 1, "swapangle")) {
546        i++;
547        if(argv[i]) {
548          CTX::instance()->mesh.allowSwapEdgeAngle = atof(argv[i++]);
549          if(CTX::instance()->mesh.allowSwapEdgeAngle <= 0.0)
550            Msg::Fatal("Threshold angle for edge swap must be > 0");
551        }
552        else
553          Msg::Fatal("Missing number");
554      }
555      else if(!strcmp(argv[i] + 1, "clcurv")) {
556        CTX::instance()->mesh.lcFromCurvature = 1;
557        i++;
558      }
559      else if(!strcmp(argv[i] + 1, "clcurviso")) {
560        CTX::instance()->mesh.lcFromCurvature = 2;
561        i++;
562      }
563      else if(!strcmp(argv[i] + 1, "smooth")) {
564        i++;
565        if(argv[i])
566          CTX::instance()->mesh.nbSmoothing = atoi(argv[i++]);
567        else
568          Msg::Fatal("Missing number");
569      }
570      else if(!strcmp(argv[i] + 1, "order") || !strcmp(argv[i] + 1, "degree")) {
571        i++;
572        if(argv[i])
573          opt_mesh_order(0, GMSH_SET, atof(argv[i++]));
574        else
575          Msg::Fatal("Missing number");
576      }
577      else if(!strcmp(argv[i] + 1, "numsubedges")) {
578        i++;
579        if(argv[i])
580          opt_mesh_num_sub_edges(0, GMSH_SET, atof(argv[i++]));
581        else
582          Msg::Fatal("Missing number");
583      }
584      else if(!strcmp(argv[i] + 1, "statreport")) {
585        i++;
586        CTX::instance()->createAppendMeshStatReport = 1;
587        if(argv[i])
588          CTX::instance()->meshStatReportFileName = argv[i++];
589        else
590          Msg::Fatal("Missing argument");
591      }
592      else if(!strcmp(argv[i] + 1, "append_statreport")) {
593        i++;
594        CTX::instance()->createAppendMeshStatReport = 2;
595        if(argv[i])
596          CTX::instance()->meshStatReportFileName = argv[i++];
597        else
598          Msg::Fatal("Missing argument");
599      }
600      else if(!strcmp(argv[i] + 1, "bin")) {
601        i++;
602        CTX::instance()->mesh.binary = 1;
603      }
604      else if(!strcmp(argv[i] + 1, "parametric")) {
605        i++;
606        CTX::instance()->mesh.saveParametric = 1;
607      }
608      else if(!strcmp(argv[i] + 1, "algo")) {
609        i++;
610        if(argv[i]) {
611          if(!strncmp(argv[i], "auto", 4))
612            CTX::instance()->mesh.algo2d = ALGO_2D_AUTO;
613          else if(!strncmp(argv[i], "meshadapt", 9) || !strncmp(argv[i], "iso", 3))
614            CTX::instance()->mesh.algo2d = ALGO_2D_MESHADAPT;
615          else if(!strncmp(argv[i], "bds", 3))
616            CTX::instance()->mesh.algo2d = ALGO_2D_MESHADAPT_OLD;
617          else if(!strncmp(argv[i], "del2d", 5) || !strncmp(argv[i], "tri", 3))
618            CTX::instance()->mesh.algo2d = ALGO_2D_DELAUNAY;
619          else if(!strncmp(argv[i], "delquad", 5) || !strncmp(argv[i], "tri", 3))
620            CTX::instance()->mesh.algo2d = ALGO_2D_FRONTAL_QUAD;
621          else if(!strncmp(argv[i], "front2d", 7) || !strncmp(argv[i], "frontal", 7))
622            CTX::instance()->mesh.algo2d = ALGO_2D_FRONTAL;
623          else if(!strncmp(argv[i], "bamg",4))
624            CTX::instance()->mesh.algo2d = ALGO_2D_BAMG;
625          else if(!strncmp(argv[i], "del3d", 5) || !strncmp(argv[i], "tetgen", 6))
626            CTX::instance()->mesh.algo3d = ALGO_3D_DELAUNAY;
627          else if(!strncmp(argv[i], "front3d", 7) || !strncmp(argv[i], "netgen", 6))
628            CTX::instance()->mesh.algo3d = ALGO_3D_FRONTAL;
629          else if(!strncmp(argv[i], "mmg3d", 5))
630            CTX::instance()->mesh.algo3d = ALGO_3D_MMG3D;
631          else if(!strncmp(argv[i], "delfr3d", 7))
632            CTX::instance()->mesh.algo3d = ALGO_3D_FRONTAL_DEL;
633          else if(!strncmp(argv[i], "delhex3d", 8))
634            CTX::instance()->mesh.algo3d = ALGO_3D_FRONTAL_HEX;
635          else if(!strncmp(argv[i], "rtree3d", 9))
636            CTX::instance()->mesh.algo3d = ALGO_3D_RTREE;
637          else
638            Msg::Fatal("Unknown mesh algorithm");
639          i++;
640        }
641        else
642          Msg::Fatal("Missing algorithm");
643      }
644      else if(!strcmp(argv[i] + 1, "format") || !strcmp(argv[i] + 1, "f")) {
645        i++;
646        if(argv[i]) {
647          if(!strcmp(argv[i], "auto")){
648            CTX::instance()->mesh.fileFormat = FORMAT_AUTO;
649          }
650          else if(!strcmp(argv[i], "msh1")){
651            CTX::instance()->mesh.fileFormat = FORMAT_MSH;
652            CTX::instance()->mesh.mshFileVersion = 1.0;
653          }
654          else if(!strcmp(argv[i], "msh2")){
655            CTX::instance()->mesh.fileFormat = FORMAT_MSH;
656            CTX::instance()->mesh.mshFileVersion = 2.0;
657          }
658          else{
659            int format = GetFileFormatFromExtension(std::string(".") + argv[i]);
660            if(format < 0){
661              Msg::Error("Unknown mesh format `%s', using `msh' instead", argv[i]);
662              format = FORMAT_MSH;
663            }
664            CTX::instance()->mesh.fileFormat = format;
665          }
666          i++;
667        }
668        else
669          Msg::Fatal("Missing format");
670      }
671      else if(!strcmp(argv[i] + 1, "listen")) {
672        CTX::instance()->solver.listen = 1;
673        i++;
674      }
675      else if(!strcmp(argv[i] + 1, "version") || !strcmp(argv[i] + 1, "-version")) {
676        fprintf(stderr, "%s\n", GMSH_VERSION);
677        Msg::Exit(0);
678      }
679      else if(!strcmp(argv[i] + 1, "info") || !strcmp(argv[i] + 1, "-info")) {
680        fprintf(stderr, "Version        : %s\n", GMSH_VERSION);
681#if defined(HAVE_FLTK)
682        fprintf(stderr, "GUI toolkit    : FLTK %d.%d.%d\n", FL_MAJOR_VERSION,
683                FL_MINOR_VERSION, FL_PATCH_VERSION);
684#else
685        fprintf(stderr, "GUI toolkit    : none\n");
686#endif
687        fprintf(stderr, "License        : %s\n", GMSH_SHORT_LICENSE);
688        fprintf(stderr, "Build OS       : %s\n", GMSH_OS);
689        fprintf(stderr, "Build options  :%s\n", GMSH_CONFIG_OPTIONS);
690        fprintf(stderr, "Build date     : %s\n", GMSH_DATE);
691        fprintf(stderr, "Build host     : %s\n", GMSH_HOST);
692        fprintf(stderr, "Packager       : %s\n", GMSH_PACKAGER);
693        fprintf(stderr, "Web site       : http://www.geuz.org/gmsh/\n");
694        fprintf(stderr, "Mailing list   : gmsh@geuz.org\n");
695        Msg::Exit(0);
696      }
697      else if(!strcmp(argv[i] + 1, "help") || !strcmp(argv[i] + 1, "-help")) {
698        fprintf(stderr, "Gmsh, a 3D mesh generator with pre- and post-processing facilities\n");
699        fprintf(stderr, "Copyright (C) 1997-2012 Christophe Geuzaine and Jean-Francois Remacle\n");
700        PrintUsage(argv[0]);
701        Msg::Exit(0);
702      }
703      else if(!strcmp(argv[i] + 1, "v") || !strcmp(argv[i] + 1, "verbose")) {
704        i++;
705        if(argv[i])
706          Msg::SetVerbosity(atoi(argv[i++]));
707        else
708          Msg::Fatal("Missing number");
709      }
710#if defined(HAVE_FLTK)
711      else if(!strcmp(argv[i] + 1, "term")) {
712        terminal = 1;
713        i++;
714      }
715      else if(!strcmp(argv[i] + 1, "dual")) {
716        CTX::instance()->mesh.dual = 1;
717        i++;
718      }
719      else if(!strcmp(argv[i] + 1, "voronoi")) {
720        CTX::instance()->mesh.voronoi = 1;
721        i++;
722      }
723      else if(!strcmp(argv[i] + 1, "noview")) {
724        opt_view_visible(0, GMSH_SET, 0);
725        i++;
726      }
727      else if(!strcmp(argv[i] + 1, "nomesh")) {
728        opt_mesh_points(0, GMSH_SET, 0.);
729        opt_mesh_lines(0, GMSH_SET, 0.);
730        opt_mesh_surfaces_edges(0, GMSH_SET, 0.);
731        opt_mesh_surfaces_faces(0, GMSH_SET, 0.);
732        opt_mesh_volumes_edges(0, GMSH_SET, 0.);
733        opt_mesh_volumes_faces(0, GMSH_SET, 0.);
734        i++;
735      }
736      else if(!strcmp(argv[i] + 1, "n")) {
737        opt_view_visible(0, GMSH_SET, 0);
738        opt_mesh_points(0, GMSH_SET, 0.);
739        opt_mesh_lines(0, GMSH_SET, 0.);
740        opt_mesh_surfaces_edges(0, GMSH_SET, 0.);
741        opt_mesh_surfaces_faces(0, GMSH_SET, 0.);
742        opt_mesh_volumes_edges(0, GMSH_SET, 0.);
743        opt_mesh_volumes_faces(0, GMSH_SET, 0.);
744        i++;
745      }
746      else if(!strcmp(argv[i] + 1, "link")) {
747        i++;
748        if(argv[i])
749          CTX::instance()->post.link = atoi(argv[i++]);
750        else
751          Msg::Fatal("Missing number");
752      }
753      else if(!strcmp(argv[i] + 1, "smoothview")) {
754        CTX::instance()->post.smooth = 1;
755        i++;
756      }
757      else if(!strcmp(argv[i] + 1, "combine")) {
758        CTX::instance()->post.combineTime = 1;
759        i++;
760      }
761      else if(!strcmp(argv[i] + 1, "nodb")) {
762        CTX::instance()->db = 0;
763        i++;
764      }
765      else if(!strcmp(argv[i] + 1, "fontsize")) {
766        i++;
767        if(argv[i])
768          CTX::instance()->fontSize = atoi(argv[i++]);
769        else
770          Msg::Fatal("Missing number");
771      }
772      else if(!strcmp(argv[i] + 1, "deltafontsize")) {
773        i++;
774        if(argv[i])
775          CTX::instance()->deltaFontSize = atoi(argv[i++]);
776        else
777          Msg::Fatal("Missing number");
778      }
779      else if(!strcmp(argv[i] + 1, "theme") || !strcmp(argv[i] + 1, "scheme")) {
780        i++;
781        if(argv[i])
782          CTX::instance()->guiTheme = argv[i++];
783        else
784          Msg::Fatal("Missing argument");
785      }
786      else if(!strcmp(argv[i] + 1, "display")) {
787        i++;
788        if(argv[i])
789          CTX::instance()->display = argv[i++];
790        else
791          Msg::Fatal("Missing argument");
792      }
793      else if(!strcmp(argv[i] + 1, "showCompounds")) {
794        CTX::instance()->geom.hideCompounds = 0;
795        i++;
796      }
797#endif
798#if defined(__APPLE__)
799      else if(!strncmp(argv[i] + 1, "psn", 3)) {
800        // the Mac Finder launches programs with a special command line argument
801        // of the form -psn_XXX: just ignore it silently (and don't exit!)
802        i++;
803      }
804#endif
805      else {
806        Msg::Error("Unknown option '%s'", argv[i]);
807        PrintUsage(argv[0]);
808        Msg::Exit(1);
809      }
810
811    }
812    else {
813      CTX::instance()->files.push_back(argv[i++]);
814    }
815
816  }
817
818  if(CTX::instance()->files.empty()){
819    std::string base = (getenv("PWD") ? "" : CTX::instance()->homeDir);
820    GModel::current()->setFileName(base + CTX::instance()->defaultFileName);
821  }
822  else
823    GModel::current()->setFileName(CTX::instance()->files[0]);
824
825  CTX::instance()->terminal = terminal;
826}