gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
OpenFile.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include <sstream>
7 #include <string.h>
8 #include "GmshConfig.h"
9 #if !defined(HAVE_NO_STDINT_H)
10 #include <stdint.h>
11 #elif defined(HAVE_NO_INTPTR_T)
12 typedef unsigned long intptr_t;
13 #endif
14 #include "GmshMessage.h"
15 #include "GModelIO_GEO.h"
16 #include "Options.h"
17 #include "GModel.h"
18 #include "Numeric.h"
19 #include "Context.h"
20 #include "OpenFile.h"
21 #include "CommandLine.h"
22 #include "OS.h"
23 #include "StringUtils.h"
24 #include "GeomMeshMatcher.h"
25 
26 #if defined(HAVE_MESH)
27 #include "Field.h"
28 #endif
29 
30 #if defined(HAVE_POPPLER)
31 #include "gmshPopplerWrapper.h"
32 #endif
33 
34 #if defined(HAVE_PARSER)
35 #include "Parser.h"
36 #include "FunctionManager.h"
37 #endif
38 
39 #if defined(HAVE_MESH)
40 #include "HighOrder.h"
41 #endif
42 
43 #if defined(HAVE_POST)
44 #include "PView.h"
45 #include "PViewData.h"
46 #include "PViewOptions.h"
47 #endif
48 
49 #if defined(HAVE_FLTK)
50 #include <FL/fl_ask.H>
51 #include "FlGui.h"
52 #include "onelabGroup.h"
53 #include "graphicWindow.h"
54 #include "drawContext.h"
55 #include "ReadImg.h"
56 #endif
57 
58 #if defined(HAVE_3M)
59 #include "3M.h"
60 #endif
61 
62 #define SQU(a) ((a) * (a))
63 
64 static void FinishUpBoundingBox()
65 {
66  double range[3];
67  for(int i = 0; i < 3; i++)
68  range[i] = CTX::instance()->max[i] - CTX::instance()->min[i];
69 
70  if(range[0] < CTX::instance()->geom.tolerance &&
71  range[1] < CTX::instance()->geom.tolerance &&
72  range[2] < CTX::instance()->geom.tolerance) {
73  CTX::instance()->min[0] -= 1.;
74  CTX::instance()->min[1] -= 1.;
75  CTX::instance()->max[0] += 1.;
76  CTX::instance()->max[1] += 1.;
77  }
78  else if(range[0] < CTX::instance()->geom.tolerance &&
79  range[1] < CTX::instance()->geom.tolerance) {
80  CTX::instance()->min[0] -= range[2];
81  CTX::instance()->min[1] -= range[2];
82  CTX::instance()->max[0] += range[2];
83  CTX::instance()->max[1] += range[2];
84  }
85  else if(range[0] < CTX::instance()->geom.tolerance &&
86  range[2] < CTX::instance()->geom.tolerance) {
87  CTX::instance()->min[0] -= range[1];
88  CTX::instance()->max[0] += range[1];
89  }
90  else if(range[1] < CTX::instance()->geom.tolerance &&
91  range[2] < CTX::instance()->geom.tolerance) {
92  CTX::instance()->min[1] -= range[0];
93  CTX::instance()->max[1] += range[0];
94  }
95  else if(range[0] < CTX::instance()->geom.tolerance) {
96  double l = sqrt(SQU(range[1]) + SQU(range[2]));
97  CTX::instance()->min[0] -= l;
98  CTX::instance()->max[0] += l;
99  }
100  else if(range[1] < CTX::instance()->geom.tolerance) {
101  double l = sqrt(SQU(range[0]) + SQU(range[2]));
102  CTX::instance()->min[1] -= l;
103  CTX::instance()->max[1] += l;
104  }
105 
106  CTX::instance()->lc =
107  sqrt(SQU(CTX::instance()->max[0] - CTX::instance()->min[0]) +
108  SQU(CTX::instance()->max[1] - CTX::instance()->min[1]) +
109  SQU(CTX::instance()->max[2] - CTX::instance()->min[2]));
110  for(int i = 0; i < 3; i++)
111  CTX::instance()->cg[i] =
112  0.5 * (CTX::instance()->min[i] + CTX::instance()->max[i]);
113 }
114 
115 void SetBoundingBox(double xmin, double xmax, double ymin, double ymax,
116  double zmin, double zmax)
117 {
118  CTX::instance()->min[0] = xmin;
119  CTX::instance()->max[0] = xmax;
120  CTX::instance()->min[1] = ymin;
121  CTX::instance()->max[1] = ymax;
122  CTX::instance()->min[2] = zmin;
123  CTX::instance()->max[2] = zmax;
125 }
126 
127 void SetBoundingBox(bool aroundVisible)
128 {
129  if(CTX::instance()->forcedBBox) return;
130 
131  SBoundingBox3d bb = GModel::current()->bounds(aroundVisible);
132 
133 #if defined(HAVE_POST)
134  if(bb.empty()) {
135  for(std::size_t i = 0; i < PView::list.size(); i++)
136  if(!PView::list[i]->getData()->getBoundingBox().empty())
137  if(!aroundVisible || PView::list[i]->getOptions()->visible)
138  bb += PView::list[i]->getData()->getBoundingBox();
139  }
140 #endif
141  if(bb.empty()) {
142  bb += SPoint3(-1., -1., -1.);
143  bb += SPoint3(1., 1., 1.);
144  }
145 
146  CTX::instance()->min[0] = bb.min().x();
147  CTX::instance()->max[0] = bb.max().x();
148  CTX::instance()->min[1] = bb.min().y();
149  CTX::instance()->max[1] = bb.max().y();
150  CTX::instance()->min[2] = bb.min().z();
151  CTX::instance()->max[2] = bb.max().z();
153 }
154 
155 // FIXME: this is necessary for now to have an approximate CTX::instance()->lc
156 // *while* parsing input files (it's important since some of the geometrical
157 // operations use a tolerance that depends on CTX::instance()->lc). This will be
158 // removed once the new database is filled directly during the parsing step
160 
162 
163 void AddToTemporaryBoundingBox(double x, double y, double z)
164 {
165  temp_bb += SPoint3(x, y, z);
166  if(temp_bb.empty()) return;
167  CTX::instance()->lc = sqrt(SQU(temp_bb.max().x() - temp_bb.min().x()) +
168  SQU(temp_bb.max().y() - temp_bb.min().y()) +
169  SQU(temp_bb.max().z() - temp_bb.min().z()));
170  if(CTX::instance()->lc == 0) CTX::instance()->lc = 1.;
171  // to get correct cg during interactive point creation
172  for(int i = 0; i < 3; i++) CTX::instance()->cg[i] = temp_bb.center()[i];
173 }
174 
175 static std::vector<FILE *> openedFiles;
176 
177 int ParseFile(const std::string &fileName, bool close, bool errorIfMissing)
178 {
179 #if !defined(HAVE_PARSER)
180  Msg::Error("Gmsh parser is not compiled in this version");
181  return 0;
182 #else
183 
184  // add 'b' for pure Windows programs: opening in text mode messes up
185  // fsetpos/fgetpos (used e.g. for user-defined functions)
186  FILE *fp;
187  if(!(fp = Fopen(fileName.c_str(), "rb"))) {
188  if(errorIfMissing)
189  Msg::Error("Unable to open file '%s'", fileName.c_str());
190  return 0;
191  }
192 
193  Msg::AddOnelabStringChoice("Gmsh/}Input files", "file", fileName, true, true,
195 
196  std::string old_yyname = gmsh_yyname;
197  FILE *old_yyin = gmsh_yyin;
198  int old_yyerrorstate = gmsh_yyerrorstate;
199  int old_yylineno = gmsh_yylineno;
200  int old_yyviewindex = gmsh_yyviewindex;
201 
202  gmsh_yyname = fileName;
203  gmsh_yyin = fp;
204  gmsh_yyerrorstate = 0;
205  gmsh_yylineno = 1;
206  gmsh_yyviewindex = 0;
207 
208  while(!feof(gmsh_yyin)) {
209  gmsh_yyparse();
210  if(gmsh_yyerrorstate > 20) {
211  if(gmsh_yyerrorstate != 999) // 999 is a voluntary exit
212  Msg::Error("Too many errors: aborting parser...");
213  gmsh_yyflush();
214  break;
215  }
216  }
217 
218  if(close) {
219  fclose(gmsh_yyin);
220  gmsh_yyflush();
221  }
222  else {
223  openedFiles.push_back(gmsh_yyin);
224  }
225 
226  gmsh_yyname = old_yyname;
227  gmsh_yyin = old_yyin;
228  gmsh_yyerrorstate = old_yyerrorstate;
229  gmsh_yylineno = old_yylineno;
230  gmsh_yyviewindex = old_yyviewindex;
231 
232 #if defined(HAVE_FLTK) && defined(HAVE_POST)
233  if(FlGui::available()) {
234  FlGui::instance()->updateViews(true, false);
235  }
236 #endif
237 
238  return 1;
239 #endif
240 }
241 
242 static bool DoSystemUncompress(const std::string &fileName,
243  const std::string &noExt)
244 {
245  std::ostringstream sstream;
246  sstream << "File '" << fileName << "' is in gzip format.\n\n"
247  << "Do you want to uncompress it?";
248  if(Msg::GetAnswer(sstream.str().c_str(), 0, "Cancel", "Uncompress")) {
249  if(SystemCall(std::string("gunzip -c ") + fileName + " > " + noExt, true))
250  Msg::Warning(
251  "Potentially failed to uncompress `%s': check directory permissions",
252  fileName.c_str());
253  GModel::current()->setFileName(noExt);
254  return true;
255  }
256  return false;
257 }
258 
259 void ParseString(const std::string &str, bool inCurrentModelDir)
260 {
261  if(str.empty()) return;
262  std::string fileName;
263  if(inCurrentModelDir)
264  fileName = FixRelativePath(GModel::current()->getFileName(),
265  CTX::instance()->tmpFileName);
266  else
267  fileName = CTX::instance()->homeDir + CTX::instance()->tmpFileName;
268  FILE *fp = Fopen(fileName.c_str(), "w");
269  if(fp) {
270  fprintf(fp, "%s\n", str.c_str());
271  fclose(fp);
272  GModel::readGEO(fileName);
273  UnlinkFile(fileName);
274  }
275 }
276 
277 #if defined(HAVE_ONELAB)
278 static std::string GetSolverForExtension(const std::string &ext)
279 {
280  for(int i = 0; i < NUM_SOLVERS; i++) {
281  if(opt_solver_extension(i, GMSH_GET, "") == ext)
282  return opt_solver_name(i, GMSH_GET, "");
283  }
284  return "";
285 }
286 
287 static int DefineSolver(const std::string &name)
288 {
289  int i;
290  for(i = 0; i < NUM_SOLVERS; i++) {
291  if(opt_solver_name(i, GMSH_GET, "") == name) return i;
292  }
293  opt_solver_name(i - 1, GMSH_SET | GMSH_GUI, name);
294  return i - 1;
295 }
296 #endif
297 
298 int MergeFile(const std::string &fileName, bool errorIfMissing,
299  bool setBoundingBox, bool importPhysicalsInOnelab,
300  int partitionToRead)
301 {
302  // added 'b' for pure Windows programs, since some of these files
303  // contain binary data
304  FILE *fp = Fopen(fileName.c_str(), "rb");
305  if(!fp) {
306  if(errorIfMissing)
307  Msg::Error("Unable to open file '%s'", fileName.c_str());
308  return 0;
309  }
310 
311  char header[256];
312  if(!fgets(header, sizeof(header), fp)) {
313  fclose(fp);
314  return 0;
315  }
316  fclose(fp);
317 
318  Msg::StatusBar(true, "Reading '%s'...", fileName.c_str());
319 
320  Msg::AddOnelabStringChoice("Gmsh/}Input files", "file", fileName, true, true,
322 
323  std::vector<std::string> split = SplitFileName(fileName);
324  std::string noExt = split[0] + split[1], ext = split[2];
325 
326  if(ext == ".gz") {
327  if(DoSystemUncompress(fileName, noExt)) return MergeFile(noExt, false);
328  }
329 
330  CTX::instance()->geom.draw = 0; // don't try to draw the model while reading
331 
332 #if defined(HAVE_FLTK) && defined(HAVE_POST)
333  int numViewsBefore = PView::list.size();
334 #endif
335  int status = 0;
336 
337 #if defined(HAVE_ONELAB)
338  std::string solver = GetSolverForExtension(ext);
339  if(solver.size()) {
340  int num = DefineSolver(solver);
341  Msg::SetOnelabString(solver + "/Model name", fileName, true, true, false, 3,
342  "file");
343  if(GModel::current()->getName() == "" ||
344  Msg::GetOnelabString("Gmsh/Model name").empty()) {
345  GModel::current()->setFileName(split[0] + split[1] + ".geo");
346  GModel::current()->setName(split[1] + ".geo");
348  }
350  CTX::instance()->geom.draw = 1;
351  return 1;
352  }
353  else if(ext == ".py" || ext == ".PY" || ext == ".m" || ext == ".M" ||
354  ext == ".exe" || ext == ".EXE") {
355  int num = DefineSolver(split[1]);
356  opt_solver_executable(num, GMSH_SET, fileName);
358  CTX::instance()->geom.draw = 1;
359  return 1;
360  }
361 #endif
362 
363  if(GModel::current()->getName() == "") {
364  GModel::current()->setFileName(fileName);
365  GModel::current()->setName(SplitFileName(fileName)[1]);
366  }
367 
368  if(ext == ".stl" || ext == ".STL") {
369  status =
370  GModel::current()->readSTL(fileName, CTX::instance()->geom.tolerance);
371  }
372  else if(ext == ".brep" || ext == ".rle" || ext == ".brp" || ext == ".BRP") {
373  status = GModel::current()->readOCCBREP(fileName);
374  }
375  else if(ext == ".iges" || ext == ".IGES" || ext == ".igs" || ext == ".IGS") {
376  status = GModel::current()->readOCCIGES(fileName);
377  }
378  else if(ext == ".step" || ext == ".STEP" || ext == ".stp" || ext == ".STP") {
379  status = GModel::current()->readOCCSTEP(fileName);
380  //status = GModel::current()->readParasolidSTEP(fileName);
381  }
382  else if(ext == ".sat" || ext == ".SAT") {
383  status = GModel::current()->readACISSAT(fileName);
384  }
385  else if(ext == ".x_t" || ext == ".xmt_txt" ||
386  ext == ".x_b" || ext == ".xmt_bin") {
387  status = GModel::current()->readParasolidXMT(fileName);
388  }
389  else if(ext == ".unv" || ext == ".UNV") {
390  status = GModel::current()->readUNV
391  (fileName, CTX::instance()->mesh.readGroupsOfElements);
392  }
393  else if(ext == ".vtk" || ext == ".VTK") {
394  status = GModel::current()->readVTK(fileName, CTX::instance()->bigEndian);
395  }
396  else if(ext == ".wrl" || ext == ".WRL" || ext == ".vrml" || ext == ".VRML" ||
397  ext == ".iv" || ext == ".IV") {
398  status = GModel::current()->readVRML(fileName);
399  }
400  else if(ext == ".mesh" || ext == ".MESH") {
401  status = GModel::current()->readMESH(fileName);
402  }
403  else if(ext == ".off" || ext == ".OFF") {
404  status = GModel::current()->readOFF(fileName);
405  }
406  else if(ext == ".diff" || ext == ".DIFF") {
407  status = GModel::current()->readDIFF(fileName);
408  }
409  else if(ext == ".med" || ext == ".MED" || ext == ".mmed" || ext == ".MMED" ||
410  ext == ".rmed" || ext == ".RMED") {
411  if(CTX::instance()->mesh.medSingleModel)
412  status = GModel::current()->readMED(fileName, 0);
413  else
414  status = GModel::readMED(fileName);
415 #if defined(HAVE_POST)
416  if(status > 1) status = PView::readMED(fileName);
417 #endif
418  }
419  else if(ext == ".bdf" || ext == ".BDF" || ext == ".nas" || ext == ".NAS") {
420  status = GModel::current()->readBDF(fileName);
421  }
422  else if(ext == ".dat" || ext == ".DAT") {
423  if(!strncmp(header, "BEGIN ACTRAN", 12))
424  status = GModel::current()->readACTRAN(fileName);
425  else if(!strncmp(header, "!", 1) || !strncmp(header, ";ECHO", 5) ||
426  !strncmp(header, ".NOE", 4))
427  status = GModel::current()->readSAMCEF(fileName);
428  else
429  status = GModel::current()->readBDF(fileName);
430  }
431  else if(ext == ".p3d" || ext == ".P3D") {
432  status = GModel::current()->readP3D(fileName);
433  }
434 #if defined(HAVE_FLTK)
435  else if(ext == ".pnm" || ext == ".PNM" || ext == ".pbm" || ext == ".PBM" ||
436  ext == ".pgm" || ext == ".PGM" || ext == ".ppm" || ext == ".PPM") {
437  status = read_pnm(fileName);
438  }
439  else if(ext == ".bmp" || ext == ".BMP") {
440  status = read_bmp(fileName);
441  }
442 #if defined(HAVE_LIBJPEG)
443  else if(ext == ".jpg" || ext == ".JPG" || ext == ".jpeg" || ext == ".JPEG") {
444  status = read_jpeg(fileName);
445  }
446 #endif
447 #if defined(HAVE_LIBPNG)
448  else if(ext == ".png" || ext == ".PNG") {
449  status = read_png(fileName);
450  }
451 #endif
452 #endif
453  else if(ext == ".ply2" || ext == ".PLY2") {
454  status = GModel::current()->readPLY2(fileName);
455  }
456  else if(ext == ".ply" || ext == ".PLY") {
457  status = GModel::current()->readPLY(fileName);
458  }
459  else if(ext == ".geom" || ext == ".GEOM") {
460  status = GModel::current()->readGEOM(fileName);
461  }
462 #if defined(HAVE_LIBCGNS)
463  else if(ext == ".cgns" || ext == ".CGNS") {
464  std::vector<std::vector<MVertex *> > vertPerZone;
465  std::vector<std::vector<MElement *> > eltPerZone;
466  if(CTX::instance()->geom.matchGeomAndMesh && !GModel::current()->empty()) {
467  GModel *tmp2 = GModel::current();
468  GModel *tmp = new GModel();
469  tmp->readCGNS(fileName, vertPerZone, eltPerZone);
470  tmp->scaleMesh(CTX::instance()->geom.matchMeshScaleFactor);
471  status = GeomMeshMatcher::instance()->match(tmp2, tmp);
472  delete tmp;
473  GModel::setCurrent(tmp2);
474  tmp2->setVisibility(1);
475  }
476  else {
478  status = GModel::current()->readCGNS(fileName, vertPerZone, eltPerZone);
479  }
480 #if defined(HAVE_POST)
481  if((status > 1) && (CTX::instance()->mesh.cgnsImportIgnoreSolution == 0)) {
482  status = PView::readCGNS(vertPerZone, eltPerZone, fileName);
483  }
484 #endif
485  }
486 #endif
487 #if defined(HAVE_3M)
488  else if(ext == ".csv") {
489  status = readFile3M(fileName);
490  }
491 #endif
492  else {
493  CTX::instance()->geom.draw = 1;
494  if(!strncmp(header, "$PTS", 4) || !strncmp(header, "$NO", 3) ||
495  !strncmp(header, "$PARA", 5) || !strncmp(header, "$ELM", 4) ||
496  !strncmp(header, "$MeshFormat", 11) ||
497  !strncmp(header, "$Comments", 9)) {
498  // mesh matcher
499  if(CTX::instance()->geom.matchGeomAndMesh &&
500  !GModel::current()->empty()) {
501  GModel *tmp2 = GModel::current();
502  GModel *tmp = new GModel();
503  tmp->readMSH(fileName);
504  tmp->scaleMesh(CTX::instance()->geom.matchMeshScaleFactor);
505  status = GeomMeshMatcher::instance()->match(tmp2, tmp);
506  delete tmp;
507  GModel::setCurrent(tmp2);
508  tmp2->setVisibility(1);
509  }
510  else {
512  status = GModel::current()->readMSH(fileName);
513  }
514 #if defined(HAVE_POST)
515  if(status > 1) status = PView::readMSH(fileName, -1, partitionToRead);
516 #endif
517  }
518 #if defined(HAVE_POST)
519  else if(ext == ".pch") {
520  status = PView::readPCH(fileName);
521  }
522  else if(!strncmp(header, "$PostFormat", 11) ||
523  !strncmp(header, "$View", 5)) {
524  status = PView::readPOS(fileName);
525  }
526 #endif
527  else {
528  status = GModel::readGEO(fileName);
529  }
530  }
531 
533  0, std::max(GModel::current()->getGEOInternals()->getMaxTag(0),
534  GModel::current()->getMaxElementaryNumber(0)));
536  1, std::max(GModel::current()->getGEOInternals()->getMaxTag(1),
537  GModel::current()->getMaxElementaryNumber(1)));
539  2, std::max(GModel::current()->getGEOInternals()->getMaxTag(2),
540  GModel::current()->getMaxElementaryNumber(2)));
542  3, std::max(GModel::current()->getGEOInternals()->getMaxTag(3),
543  GModel::current()->getMaxElementaryNumber(3)));
544 
545  if(setBoundingBox) SetBoundingBox();
546 
547  CTX::instance()->geom.draw = 1;
549 
550  if(importPhysicalsInOnelab) Msg::ImportPhysicalGroupsInOnelab();
551 
552 #if defined(HAVE_FLTK) && defined(HAVE_POST)
553  if(FlGui::available()) {
554  // go directly to the first non-empty step after the one that is requested
555  for(std::size_t i = numViewsBefore; i < PView::list.size(); i++)
557  PView::list[i]->getData()->getFirstNonEmptyTimeStep(
558  opt_view_timestep(i, GMSH_GET, 0)));
559  FlGui::instance()->updateViews(numViewsBefore != (int)PView::list.size(),
560  false);
561  }
562 #endif
563 
564  if(!status) Msg::Error("Error loading '%s'", fileName.c_str());
565  Msg::StatusBar(true, "Done reading '%s'", fileName.c_str());
566 
567  CTX::instance()->fileread = true;
568 
569  // merge the associated option file if there is one
570  if(!StatFile(fileName + ".opt")) MergeFile(fileName + ".opt");
571  return status;
572 }
573 
574 int MergePostProcessingFile(const std::string &fileName, int showViews,
575  bool showLastStep, bool errorIfMissing)
576 {
577 #if defined(HAVE_POST)
578  // check if there is a mesh in the file
579  FILE *fp = Fopen(fileName.c_str(), "rb");
580  if(!fp) {
581  if(errorIfMissing)
582  Msg::Error("Unable to open file '%s'", fileName.c_str());
583  return 0;
584  }
585  char header[256];
586  if(!fgets(header, sizeof(header), fp)) {
587  fclose(fp);
588  return 0;
589  }
590  bool haveMesh = false;
591  if(!strncmp(header, "$MeshFormat", 11)) {
592  while(!feof(fp) && fgets(header, sizeof(header), fp)) {
593  if(!strncmp(header, "$Nodes", 6)) {
594  haveMesh = true;
595  break;
596  }
597  else if(!strncmp(header, "$NodeData", 9) ||
598  !strncmp(header, "$ElementData", 12) ||
599  !strncmp(header, "$ElementNodeData", 16)) {
600  break;
601  }
602  }
603  }
604  fclose(fp);
605 
606  // store old step values
607  std::size_t n = PView::list.size();
608  std::vector<int> steps(n, 0);
609  if(showLastStep) {
610  for(std::size_t i = 0; i < PView::list.size(); i++)
611  steps[i] = (int)opt_view_nb_timestep(i, GMSH_GET, 0);
612  }
613 
614  // if there is a mesh, create a new model to store it (don't merge elements in
615  // the current mesh!)
616  GModel *old = GModel::current();
617  if(haveMesh) {
618  GModel *m = new GModel();
620  }
621  int ret =
622  MergeFile(fileName, errorIfMissing, old->bounds().empty() ? true : false);
623  GModel::setCurrent(old);
624  old->setVisibility(1);
625 
626  // hide everything except onelab X-Y graphs and views with attribute
627  // "AlwaysVisible"
628  if(showViews == 0) {
629  for(std::size_t i = 0; i < PView::list.size(); i++) {
630  if(PView::list[i]->getData()->getFileName().substr(0, 6) != "ONELAB" &&
631  PView::list[i]->getOptions()->attributes.find("AlwaysVisible") ==
632  std::string::npos)
633  PView::list[i]->getOptions()->visible = 0;
634  }
635  }
636  else if(showViews == 2 && n < PView::list.size()) {
637  // if we created new views, assume we only want to see those (and the
638  // onelab X-Y graphs)
639  for(std::size_t i = 0; i < n; i++) {
640  if(PView::list[i]->getData()->getFileName().substr(0, 6) != "ONELAB" &&
641  PView::list[i]->getOptions()->attributes.find("AlwaysVisible") ==
642  std::string::npos)
643  PView::list[i]->getOptions()->visible = 0;
644  }
645  }
646 
647  // if we added steps, and we have more than 2 (to avoid always showing the
648  // imaginary part for complex fields), go to the last one
649  if(showLastStep) {
650  steps.resize(PView::list.size(), 0);
651  for(std::size_t i = 0; i < PView::list.size(); i++) {
652  int step = (int)opt_view_nb_timestep(i, GMSH_GET, 0);
653  if(step > steps[i] && steps[i] > 1)
654  opt_view_timestep(i, GMSH_SET | GMSH_GUI, step - 1);
655  }
656  }
657 
658  return ret;
659 #else
660  return 0;
661 #endif
662 }
663 
665 {
666 #if defined(HAVE_POST)
667  // delete all views
668  while(PView::list.size() > 0) delete PView::list[PView::list.size() - 1];
669  std::vector<PView *>().swap(PView::list);
672 #endif
673 
674 #if defined(HAVE_PARSER)
675  // clear parser data
676  gmsh_yysymbols.clear();
677  gmsh_yystringsymbols.clear();
678  gmsh_yyfactory.clear();
680 #endif
681 
682  // delete the temp file
683  if(!Msg::GetCommRank())
684  UnlinkFile(CTX::instance()->homeDir + CTX::instance()->tmpFileName);
685 
686  // delete all models
687  while(GModel::list.size() > 0) delete GModel::list[GModel::list.size() - 1];
688  std::vector<GModel *>().swap(GModel::list);
689 
690  // close the files that might have been left open by ParseFile
691  if(openedFiles.size()) {
692  for(std::size_t i = 0; i < openedFiles.size(); i++) fclose(openedFiles[i]);
693  openedFiles.clear();
694  }
695 }
696 
698 {
699  Msg::Info("Clearing all models and views...");
701  Msg::Info("Done clearing all models and views");
702 
703  new GModel();
704  std::string base = (getenv("PWD") ? "" : CTX::instance()->homeDir);
705  GModel::current()->setFileName(base + CTX::instance()->defaultFileName);
706  GModel::current()->setName("");
707 #if defined(HAVE_FLTK)
708  if(FlGui::available()) {
709  FlGui::instance()->resetVisibility();
710  FlGui::instance()->updateViews(true, true);
711  FlGui::instance()->updateFields();
713  }
714 #endif
716 }
717 
718 void OpenProject(const std::string &fileName, bool errorIfMissing)
719 {
720  if(CTX::instance()->lock) {
721  Msg::Info("I'm busy! Ask me that later...");
722  return;
723  }
724  CTX::instance()->lock = 1;
725 
727 
728  if(GModel::current()->empty()) {
729  // if the current model is empty, make sure it's reaaally cleaned-up, and
730  // reuse it
733  }
734  else {
735  // if the current model is not empty make it invisible and add a new model
736  new GModel();
737  GModel::current(GModel::list.size() - 1);
738  }
739 
740  // clear parser variables, but keep -setnumber/-setstrings command line
741  // definitions
742 #if defined(HAVE_PARSER)
743  gmsh_yysymbols.clear();
744  gmsh_yystringsymbols.clear();
745  std::map<std::string, std::vector<double> > cln(Msg::GetCommandLineNumbers());
746  for(auto it = cln.begin();
747  it != cln.end(); it++)
748  gmsh_yysymbols[it->first].value = it->second;
749  std::map<std::string, std::string> cls(Msg::GetCommandLineStrings());
750  for(auto it = cls.begin();
751  it != cls.end(); it++)
752  gmsh_yystringsymbols[it->first] = std::vector<std::string>(1, it->second);
753  gmsh_yyfactory.clear();
756 #endif
757 
758  // temporary hack until we fill the current GModel on the fly during parsing
760 
761  // merge the file
762  MergeFile(fileName, errorIfMissing);
763 
764  // fill recent opened file list
765  std::vector<std::string> tmp = CTX::instance()->recentFiles;
766  CTX::instance()->recentFiles.clear();
767  CTX::instance()->recentFiles.push_back(fileName);
768  for(std::size_t i = 0; i < tmp.size(); i++) {
769  if(tmp[i] != fileName) CTX::instance()->recentFiles.push_back(tmp[i]);
770  }
771  CTX::instance()->recentFiles.resize(10);
772 #if defined(HAVE_FLTK)
773  if(FlGui::available()) FlGui::instance()->graph[0]->fillRecentHistoryMenu();
774 #endif
775 
776  // close the files that might have been left open by ParseFile
777  if(openedFiles.size()) {
778  for(std::size_t i = 0; i < openedFiles.size(); i++) fclose(openedFiles[i]);
779  openedFiles.clear();
780  }
781 
782  CTX::instance()->lock = 0;
783 
784  // FIXME: temporary for auto-extrude testing
785  if(CTX::instance()->geom.autoExtrude)
786  GModel::current()->addAutomaticExtrusionConstraints({10}, {1}, true, {});
787 
788 #if defined(HAVE_FLTK)
789  if(FlGui::available()) {
790  file_watch_cb(nullptr, nullptr);
791  FlGui::instance()->resetVisibility();
792  FlGui::instance()->updateViews(true, false);
793  FlGui::instance()->updateFields();
795  }
796 #endif
797 }
798 
799 void OpenProjectMacFinder(const char *fileName)
800 {
801  if(!fileName) return;
802  std::string name(fileName);
803  if(name == Msg::GetExecutableName()) {
804  Msg::Debug("Ignoring macOS file open callback, as the given file name "
805  "is the executable name '%s'", name.c_str());
806  return;
807  }
808 #if defined(HAVE_FLTK)
809  if(!FlGui::available() || !FlGui::getFinishedProcessingCommandLine()) {
810  // Gmsh is not ready: will open the file later
811  FlGui::setOpenedThroughMacFinder(name);
812  }
813  else {
814  // Gmsh is running
815  OpenProject(name);
817  if(CTX::instance()->launchSolverAtStartup >= 0)
818  solver_cb(nullptr, (void *)(intptr_t)CTX::instance()->launchSolverAtStartup);
819  }
820 #endif
821 }
opt_solver_name
std::string opt_solver_name(OPT_ARGS_STR)
Definition: Options.cpp:1450
GModel::setVisibility
void setVisibility(char val)
Definition: GModel.h:341
CTX::fileread
bool fileread
Definition: Context.h:237
contextGeometryOptions::tolerance
double tolerance
Definition: Context.h:99
SystemCall
int SystemCall(const std::string &command, bool blocking)
Definition: OS.cpp:637
SplitFileName
std::vector< std::string > SplitFileName(const std::string &fileName)
Definition: StringUtils.cpp:93
GModel::readParasolidXMT
int readParasolidXMT(const std::string &name)
Definition: GModel.cpp:3623
Field.h
GeomMeshMatcher.h
GMSH_GET
#define GMSH_GET
Definition: Options.h:13
GMSH_SET
#define GMSH_SET
Definition: Options.h:12
Msg::GetCommandLineStrings
static std::map< std::string, std::string > & GetCommandLineStrings()
Definition: GmshMessage.cpp:297
gmsh_yyerrorstate
int gmsh_yyerrorstate
Definition: Gmsh.tab.cpp:641
MergeFile
int MergeFile(const std::string &fileName, bool errorIfMissing, bool setBoundingBox, bool importPhysicalsInOnelab, int partitionToRead)
Definition: OpenFile.cpp:298
GModel::readUNV
int readUNV(const std::string &name, bool readGroupsOfElements=true)
Definition: GModelIO_UNV.cpp:36
read_pnm
int read_pnm(std::string fileName)
Definition: ReadImg.cpp:164
CTX::homeDir
std::string homeDir
Definition: Context.h:147
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
GEO_Internals::setMaxTag
void setMaxTag(int dim, int val)
Definition: GModelIO_GEO.cpp:87
OS.h
contextGeometryOptions::matchMeshScaleFactor
double matchMeshScaleFactor
Definition: Context.h:109
GModel::addAutomaticExtrusionConstraints
bool addAutomaticExtrusionConstraints(const std::vector< int > &numElements, const std::vector< double > &heights, const bool recombine, const std::vector< int > &regionTag)
Definition: GModelAutoExtrude.cpp:322
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
DeleteAllModelsAndViews
void DeleteAllModelsAndViews()
Definition: OpenFile.cpp:664
GeomMeshMatcher::instance
static GeomMeshMatcher * instance()
Definition: GeomMeshMatcher.cpp:397
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
gmshPopplerWrapper.h
Msg::StatusBar
static void StatusBar(bool log, const char *fmt,...)
Definition: GmshMessage.cpp:686
ReadImg.h
SPoint3
Definition: SPoint3.h:14
FunctionManager::Instance
static FunctionManager * Instance()
Definition: FunctionManager.cpp:40
GModel::readGEOM
int readGEOM(const std::string &name)
Definition: GModelIO_GEOM.cpp:24
SBoundingBox3d::min
SPoint3 min() const
Definition: SBoundingBox3d.h:90
GModel::readOCCSTEP
int readOCCSTEP(const std::string &name)
Definition: GModelIO_OCC.cpp:5902
PView::readPOS
static bool readPOS(const std::string &fileName, int fileIndex=-1)
Definition: PViewIO.cpp:19
Msg::ImportPhysicalGroupsInOnelab
static void ImportPhysicalGroupsInOnelab()
Definition: GmshMessage.cpp:1523
GModel::empty
bool empty() const
Definition: GModel.cpp:311
gmsh_yynamespaces
NameSpaces gmsh_yynamespaces
Definition: Gmsh.tab.cpp:646
gmsh_yyname
std::string gmsh_yyname
Definition: Gmsh.tab.cpp:640
opt_solver_extension
std::string opt_solver_extension(OPT_ARGS_STR)
Definition: Options.cpp:1507
PView.h
GModelIO_GEO.h
FunctionManager.h
GmshMessage.h
UnlinkFile
int UnlinkFile(const std::string &fileName)
Definition: OS.cpp:479
PViewData.h
GModel::readDIFF
int readDIFF(const std::string &name)
Definition: GModelIO_DIFF.cpp:42
SetBoundingBox
void SetBoundingBox(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax)
Definition: OpenFile.cpp:115
Msg::AddOnelabStringChoice
static void AddOnelabStringChoice(const std::string &name, const std::string &kind, const std::string &value, bool updateValue=true, bool readOnly=false, bool visible=true)
Definition: GmshMessage.cpp:1045
drawContext::global
static drawContextGlobal * global()
Definition: drawContext.cpp:85
getBoundingBox
void getBoundingBox(int dim, List_T *in, List_T *out)
Definition: Gmsh.tab.cpp:15533
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
GModel::readMSH
int readMSH(const std::string &name)
Definition: GModelIO_MSH.cpp:12
temp_bb
static SBoundingBox3d temp_bb
Definition: OpenFile.cpp:159
drawContextGlobal::draw
virtual void draw(bool rateLimited=true)
Definition: drawContext.h:97
contextGeometryOptions::draw
int draw
Definition: Context.h:114
ParseString
void ParseString(const std::string &str, bool inCurrentModelDir)
Definition: OpenFile.cpp:259
opt_view_nb_timestep
double opt_view_nb_timestep(OPT_ARGS_NUM)
Definition: Options.cpp:6960
Msg::SetOnelabString
static void SetOnelabString(const std::string &name, const std::string &val, bool visible=true, bool persistent=false, bool readOnly=false, int changedValue=3, const std::string &kind="")
Definition: GmshMessage.cpp:1021
SBoundingBox3d::center
SPoint3 center() const
Definition: SBoundingBox3d.h:92
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
FunctionManager::clear
void clear()
Definition: FunctionManager.cpp:48
GModel::readCGNS
int readCGNS(const std::string &name, std::vector< std::vector< MVertex * > > &vertPerZone, std::vector< std::vector< MElement * > > &eltPerZone)
Definition: GModelIO_CGNS.cpp:244
MergePostProcessingFile
int MergePostProcessingFile(const std::string &fileName, int showViews, bool showLastStep, bool errorIfMissing)
Definition: OpenFile.cpp:574
SPoint3::x
double x(void) const
Definition: SPoint3.h:125
GModel::readMED
static int readMED(const std::string &name)
Definition: GModelIO_MED.cpp:879
DoSystemUncompress
static bool DoSystemUncompress(const std::string &fileName, const std::string &noExt)
Definition: OpenFile.cpp:242
GModel::readVTK
int readVTK(const std::string &name, bool bigEndian=false)
Definition: GModelIO_VTK.cpp:131
GModel::readSTL
int readSTL(const std::string &name, double tolerance=1.e-3)
Definition: GModelIO_STL.cpp:22
GModel::bounds
SBoundingBox3d bounds(bool aroundVisible=false)
Definition: GModel.cpp:1043
FixRelativePath
std::string FixRelativePath(const std::string &reference, const std::string &in)
Definition: StringUtils.cpp:77
GModel::scaleMesh
void scaleMesh(double factor)
Definition: GModel.cpp:2189
GModel::setName
void setName(const std::string &name)
Definition: GModel.h:328
GModel::setFileName
void setFileName(const std::string &fileName)
Definition: GModel.cpp:123
read_bmp
int read_bmp(std::string fileName)
Definition: ReadImg.cpp:167
gmsh_yyin
FILE * gmsh_yyin
HighOrder.h
gmsh_yysymbols
std::map< std::string, gmsh_yysymbol > gmsh_yysymbols
Definition: Gmsh.tab.cpp:643
OpenProject
void OpenProject(const std::string &fileName, bool errorIfMissing)
Definition: OpenFile.cpp:718
Msg::GetCommRank
static int GetCommRank()
Definition: GmshMessage.cpp:219
GModel::readVRML
int readVRML(const std::string &name)
Definition: GModelIO_VRML.cpp:118
CTX::lc
double lc
Definition: Context.h:234
SBoundingBox3d::empty
bool empty()
Definition: SBoundingBox3d.h:36
PView::readCGNS
static bool readCGNS(const std::vector< std::vector< MVertex * > > &vertPerZone, const std::vector< std::vector< MElement * > > &eltPerZone, const std::string &fileName)
Definition: PViewIO_CGNS.cpp:179
CTX::min
double min[3]
Definition: Context.h:229
Numeric.h
GModel
Definition: GModel.h:44
GModel::readP3D
int readP3D(const std::string &name)
Definition: GModelIO_P3D.cpp:13
Msg::SetOnelabChanged
static void SetOnelabChanged(int value, const std::string &client="Gmsh")
Definition: GmshMessage.cpp:1612
gmsh_yyviewindex
int gmsh_yyviewindex
Definition: Gmsh.tab.cpp:642
PViewData::removeAllInterpolationSchemes
static void removeAllInterpolationSchemes()
Definition: PViewData.cpp:209
CTX::max
double max[3]
Definition: Context.h:229
GModel::readPLY2
int readPLY2(const std::string &name)
Definition: GModelIO_PLY.cpp:216
PViewOptions.h
AddToTemporaryBoundingBox
void AddToTemporaryBoundingBox(double x, double y, double z)
Definition: OpenFile.cpp:163
GMSH_GUI
#define GMSH_GUI
Definition: Options.h:14
NUM_SOLVERS
#define NUM_SOLVERS
Definition: Context.h:13
SPoint3::y
double y(void) const
Definition: SPoint3.h:127
CTX::cg
double cg[3]
Definition: Context.h:231
CTX::mesh
contextMeshOptions mesh
Definition: Context.h:313
Parser.h
read_png
int read_png(std::string fileName)
Definition: ReadImg.cpp:166
gmsh_yylineno
int gmsh_yylineno
GModel::destroy
void destroy(bool keepName=false)
Definition: GModel.cpp:168
read_jpeg
int read_jpeg(std::string fileName)
Definition: ReadImg.cpp:165
GModel::list
static std::vector< GModel * > list
Definition: GModel.h:202
opt_view_timestep
double opt_view_timestep(OPT_ARGS_NUM)
Definition: Options.cpp:6993
GModel::readPLY
int readPLY(const std::string &name)
Definition: GModelIO_PLY.cpp:49
GModel::readBDF
int readBDF(const std::string &name)
Definition: GModelIO_BDF.cpp:218
SQU
#define SQU(a)
Definition: OpenFile.cpp:62
CTX::geom
contextGeometryOptions geom
Definition: Context.h:311
GModel::readACTRAN
int readACTRAN(const std::string &name)
Definition: GModelIO_ACTRAN.cpp:32
GModel::readOFF
int readOFF(const std::string &name)
Definition: GModelIO_OFF.cpp:14
StatFile
int StatFile(const std::string &fileName)
Definition: OS.cpp:489
GModel::readGEO
static int readGEO(const std::string &name)
Definition: GModel.cpp:3440
GEO_Internals::destroy
void destroy()
Definition: GModelIO_GEO.h:43
StringUtils.h
GModel::readACISSAT
int readACISSAT(const std::string &name)
Definition: GModel.cpp:3608
contextMeshOptions::changed
int changed
Definition: Context.h:82
GModel::setCurrent
static int setCurrent(GModel *m)
Definition: GModel.cpp:147
Msg::GetNumOnelabClients
static int GetNumOnelabClients()
Definition: GmshMessage.cpp:1277
Msg::ResetErrorCounter
static void ResetErrorCounter()
Definition: GmshMessage.cpp:850
Map::clear
void clear()
Definition: Parser.h:211
CTX::recentFiles
std::vector< std::string > recentFiles
Definition: Context.h:149
Msg::GetCommandLineNumbers
static std::map< std::string, std::vector< double > > & GetCommandLineNumbers()
Definition: GmshMessage.cpp:292
ENT_ALL
#define ENT_ALL
Definition: GmshDefines.h:235
GModel::readSAMCEF
int readSAMCEF(const std::string &name)
Definition: GModelIO_SAMCEF.cpp:33
Context.h
SBoundingBox3d::reset
void reset()
Definition: SBoundingBox3d.h:43
ClearProject
void ClearProject()
Definition: OpenFile.cpp:697
GModel::readOCCBREP
int readOCCBREP(const std::string &name)
Definition: GModelIO_OCC.cpp:5892
PView::readMED
static bool readMED(const std::string &fileName, int fileIndex=-1)
Definition: PViewIO.cpp:357
Msg::GetAnswer
static int GetAnswer(const char *question, int defaultval, const char *zero, const char *one, const char *two=nullptr)
Definition: GmshMessage.cpp:952
PView::readMSH
static bool readMSH(const std::string &fileName, int fileIndex=-1, int partitionToRead=-1)
Definition: PViewIO.cpp:84
z
const double z
Definition: GaussQuadratureQuad.cpp:56
gmsh_yyflush
void gmsh_yyflush()
PView::readPCH
static bool readPCH(const std::string &fileName, int fileIndex=-1)
Definition: PViewIO.cpp:366
gmsh_yystringsymbols
std::map< std::string, std::vector< std::string > > gmsh_yystringsymbols
Definition: Gmsh.tab.cpp:644
ResetTemporaryBoundingBox
void ResetTemporaryBoundingBox()
Definition: OpenFile.cpp:161
gmsh_yyparse
int gmsh_yyparse()
GModel::readMESH
int readMESH(const std::string &name)
Definition: GModelIO_MESH.cpp:31
SPoint3::z
double z(void) const
Definition: SPoint3.h:129
Options.h
CTX::launchSolverAtStartup
int launchSolverAtStartup
Definition: Context.h:155
GModel.h
CommandLine.h
GModel::readOCCIGES
int readOCCIGES(const std::string &name)
Definition: GModelIO_OCC.cpp:5911
FinishUpBoundingBox
static void FinishUpBoundingBox()
Definition: OpenFile.cpp:64
PView::setGlobalTag
static void setGlobalTag(int tag)
Definition: PView.cpp:208
gmsh_yyfactory
std::string gmsh_yyfactory
Definition: Gmsh.tab.cpp:645
CTX::tmpFileName
std::string tmpFileName
Definition: Context.h:141
PView::list
static std::vector< PView * > list
Definition: PView.h:112
SBoundingBox3d::max
SPoint3 max() const
Definition: SBoundingBox3d.h:91
GeomMeshMatcher::match
int match(GModel *geom, GModel *mesh)
Definition: GeomMeshMatcher.cpp:850
GModel::setSelection
void setSelection(int val)
Definition: GModel.cpp:1026
GModel::getGEOInternals
GEO_Internals * getGEOInternals()
Definition: GModel.h:315
ParseFile
int ParseFile(const std::string &fileName, bool close, bool errorIfMissing)
Definition: OpenFile.cpp:177
Msg::GetOnelabString
static std::string GetOnelabString(const std::string &name, const std::string &defaultValue="", bool errorIfMissing=false)
Definition: GmshMessage.cpp:1105
openedFiles
static std::vector< FILE * > openedFiles
Definition: OpenFile.cpp:175
CTX::lock
int lock
Definition: Context.h:252
SBoundingBox3d
Definition: SBoundingBox3d.h:21
OpenFile.h
Msg::GetExecutableName
static std::string GetExecutableName()
Definition: GmshMessage.cpp:372
GModel::current
static GModel * current(int index=-1)
Definition: GModel.cpp:136
opt_solver_executable
std::string opt_solver_executable(OPT_ARGS_STR)
Definition: Options.cpp:1564
OpenProjectMacFinder
void OpenProjectMacFinder(const char *fileName)
Definition: OpenFile.cpp:799
drawContext.h