diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e23a30c2523842675b3a12680fbc5f97125fea61 --- /dev/null +++ b/Common/CreateFile.cpp @@ -0,0 +1,378 @@ +// $Id: CreateFile.cpp,v 1.1 2008-07-04 15:02:47 geuzaine Exp $ +// +// Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to <gmsh@geuz.org>. + +#include <string.h> +#include "Message.h" +#include "GModel.h" +#include "GmshDefines.h" +#include "StringUtils.h" +#include "Context.h" +#include "Options.h" + +#if defined(HAVE_FLTK) +#include "GmshUI.h" +#include "gl2ps.h" +#include "gl2gif.h" +#include "gl2jpeg.h" +#include "gl2png.h" +#include "gl2ppm.h" +#include "gl2yuv.h" +#endif + +extern Context_T CTX; + +int GuessFileFormatFromFileName(const char *name) +{ + int len; + char ext[256]; + + for(len = strlen(name) - 1; len >= 0; len--) { + if(name[len] == '.') { + strcpy(ext, &name[len]); + break; + } + } + if(len <= 0) + strcpy(ext, ""); + + if (!strcmp(ext, ".geo")) return FORMAT_GEO; + else if(!strcmp(ext, ".msh")) return FORMAT_MSH; + else if(!strcmp(ext, ".pos")) return FORMAT_POS; + else if(!strcmp(ext, ".opt")) return FORMAT_OPT; + else if(!strcmp(ext, ".unv")) return FORMAT_UNV; + else if(!strcmp(ext, ".vtk")) return FORMAT_VTK; + else if(!strcmp(ext, ".stl")) return FORMAT_STL; + else if(!strcmp(ext, ".cgns")) return FORMAT_CGNS; + else if(!strcmp(ext, ".med")) return FORMAT_MED; + else if(!strcmp(ext, ".mesh")) return FORMAT_MESH; + else if(!strcmp(ext, ".bdf")) return FORMAT_BDF; + else if(!strcmp(ext, ".nas")) return FORMAT_BDF; + else if(!strcmp(ext, ".p3d")) return FORMAT_P3D; + else if(!strcmp(ext, ".wrl")) return FORMAT_VRML; + else if(!strcmp(ext, ".vrml")) return FORMAT_VRML; + else if(!strcmp(ext, ".gif")) return FORMAT_GIF; + else if(!strcmp(ext, ".jpg")) return FORMAT_JPEG; + else if(!strcmp(ext, ".jpeg")) return FORMAT_JPEG; + else if(!strcmp(ext, ".png")) return FORMAT_PNG; + else if(!strcmp(ext, ".ps")) return FORMAT_PS; + else if(!strcmp(ext, ".eps")) return FORMAT_EPS; + else if(!strcmp(ext, ".pdf")) return FORMAT_PDF; + else if(!strcmp(ext, ".tex")) return FORMAT_TEX; + else if(!strcmp(ext, ".svg")) return FORMAT_SVG; + else if(!strcmp(ext, ".ppm")) return FORMAT_PPM; + else if(!strcmp(ext, ".yuv")) return FORMAT_YUV; + else return -1; +} + +void GetDefaultFileName(int format, char *name) +{ + char ext[32] = ""; + strcpy(name, CTX.no_ext_filename); + switch(format){ + case FORMAT_GEO: strcpy(ext, ".geo_unrolled"); break; + case FORMAT_MSH: strcpy(ext, ".msh"); break; + case FORMAT_POS: strcpy(ext, ".pos"); break; + case FORMAT_OPT: strcpy(ext, ".opt"); break; + case FORMAT_UNV: strcpy(ext, ".unv"); break; + case FORMAT_VTK: strcpy(ext, ".vtk"); break; + case FORMAT_STL: strcpy(ext, ".stl"); break; + case FORMAT_CGNS: strcpy(ext, ".cgns"); break; + case FORMAT_MED: strcpy(ext, ".med"); break; + case FORMAT_MESH: strcpy(ext, ".mesh"); break; + case FORMAT_BDF: strcpy(ext, ".bdf"); break; + case FORMAT_P3D: strcpy(ext, ".p3d"); break; + case FORMAT_VRML: strcpy(ext, ".wrl"); break; + case FORMAT_GIF: strcpy(ext, ".gif"); break; + case FORMAT_JPEG: strcpy(ext, ".jpg"); break; + case FORMAT_PNG: strcpy(ext, ".png"); break; + case FORMAT_PS: strcpy(ext, ".ps"); break; + case FORMAT_EPS: strcpy(ext, ".eps"); break; + case FORMAT_PDF: strcpy(ext, ".pdf"); break; + case FORMAT_TEX: strcpy(ext, ".tex"); break; + case FORMAT_SVG: strcpy(ext, ".svg"); break; + case FORMAT_PPM: strcpy(ext, ".ppm"); break; + case FORMAT_YUV: strcpy(ext, ".yuv"); break; + default: break; + } + strcat(name, ext); +} + +void CreateOutputFile(const char *filename, int format) +{ + char name[256], no_ext[256], ext[256], base[256]; + + if(!filename || !strlen(filename)) + GetDefaultFileName(format, name); + else + strcpy(name, filename); + + splitFileName(name, no_ext, ext, base); + + int oldformat = CTX.print.format; + CTX.print.format = format; + CTX.printing = 1; + +#if defined(HAVE_FLTK) + GLint viewport[4]; + for(int i = 0; i < 4; i++) viewport[i] = CTX.viewport[i]; + GLint width = viewport[2] - viewport[0]; + GLint height = viewport[3] - viewport[1]; +#endif + + bool printEndMessage = true; + if(format != FORMAT_AUTO) Msg::StatusBar(2, true, "Writing '%s'", name); + + switch (format) { + + case FORMAT_AUTO: + CreateOutputFile(name, GuessFileFormatFromFileName(name)); + printEndMessage = false; + break; + + case FORMAT_OPT: + Print_Options(0, GMSH_FULLRC, 1, 1, name); + break; + + case FORMAT_MSH: + GModel::current()->writeMSH(name, CTX.mesh.msh_file_version, CTX.mesh.msh_binary, + CTX.mesh.save_all, CTX.mesh.scaling_factor); + break; + + case FORMAT_STL: + GModel::current()->writeSTL(name, CTX.mesh.stl_binary, + CTX.mesh.save_all, CTX.mesh.scaling_factor); + break; + + case FORMAT_VRML: + GModel::current()->writeVRML(name, CTX.mesh.save_all, CTX.mesh.scaling_factor); + break; + + case FORMAT_UNV: + GModel::current()->writeUNV(name, CTX.mesh.save_all, CTX.mesh.save_groups_of_nodes, + CTX.mesh.scaling_factor); + break; + + case FORMAT_VTK: + GModel::current()->writeVTK(name, CTX.mesh.msh_binary, CTX.mesh.save_all, + CTX.mesh.scaling_factor); + break; + + case FORMAT_MESH: + GModel::current()->writeMESH(name, CTX.mesh.save_all, CTX.mesh.scaling_factor); + break; + + case FORMAT_BDF: + GModel::current()->writeBDF(name, CTX.mesh.bdf_field_format, + CTX.mesh.save_all, CTX.mesh.scaling_factor); + break; + + case FORMAT_P3D: + GModel::current()->writeP3D(name, CTX.mesh.save_all, CTX.mesh.scaling_factor); + break; + + case FORMAT_CGNS: + GModel::current()->writeCGNS(name, CTX.mesh.scaling_factor); + break; + + case FORMAT_MED: + GModel::current()->writeMED(name, CTX.mesh.save_all, CTX.mesh.scaling_factor); + break; + + case FORMAT_POS: + GModel::current()->writePOS(name, CTX.print.pos_elementary, CTX.print.pos_element, + CTX.print.pos_gamma, CTX.print.pos_eta, CTX.print.pos_rho, + CTX.mesh.save_all, CTX.mesh.scaling_factor); + break; + + case FORMAT_GEO: + GModel::current()->writeGEO(name, CTX.print.geo_labels); + break; + +#if defined(HAVE_FLTK) + case FORMAT_PPM: + case FORMAT_YUV: + case FORMAT_GIF: + case FORMAT_JPEG: + case FORMAT_PNG: + { + FILE *fp; + if(!(fp = fopen(name, "wb"))) { + Msg::Error("Unable to open file '%s'", name); + break; + } + + PixelBuffer buffer(width, height, GL_RGB, GL_UNSIGNED_BYTE); + + int old_bg_gradient = CTX.bg_gradient; + if(format == FORMAT_GIF && CTX.print.gif_transparent) + CTX.bg_gradient = 0; + buffer.Fill(CTX.batch); + CTX.bg_gradient = old_bg_gradient; + + if(format == FORMAT_PPM){ + create_ppm(fp, &buffer); + } + else if(format == FORMAT_YUV){ + create_yuv(fp, &buffer); + } + else if(format == FORMAT_GIF){ + create_gif(fp, &buffer, + CTX.print.gif_dither, + CTX.print.gif_sort, + CTX.print.gif_interlace, + CTX.print.gif_transparent, + CTX.UNPACK_RED(CTX.color.bg), + CTX.UNPACK_GREEN(CTX.color.bg), + CTX.UNPACK_BLUE(CTX.color.bg)); + } + else if(format == FORMAT_JPEG){ + create_jpeg(fp, &buffer, CTX.print.jpeg_quality, CTX.print.jpeg_smoothing); + } + else{ + create_png(fp, &buffer, 100); + } + fclose(fp); + } + break; + + case FORMAT_PS: + case FORMAT_EPS: + case FORMAT_PDF: + case FORMAT_SVG: + { + FILE *fp; + if(!(fp = fopen(name, "wb"))) { + Msg::Error("Unable to open file '%s'", name); + break; + } + + int psformat; + switch(format){ + case FORMAT_PDF: + psformat = GL2PS_PDF; + break; + case FORMAT_PS: + psformat = GL2PS_PS; + break; + case FORMAT_SVG: + psformat = GL2PS_SVG; + break; + default: + psformat = GL2PS_EPS; + break; + } + + int old_bg_gradient = CTX.bg_gradient; + if(!CTX.print.eps_background) CTX.bg_gradient = 0; + + PixelBuffer buffer(width, height, GL_RGB, GL_FLOAT); + + if(CTX.print.eps_quality == 0) + buffer.Fill(CTX.batch); + + int pssort = + (CTX.print.eps_quality == 3) ? GL2PS_NO_SORT : + (CTX.print.eps_quality == 2) ? GL2PS_BSP_SORT : + GL2PS_SIMPLE_SORT; + int psoptions = + GL2PS_SIMPLE_LINE_OFFSET | GL2PS_SILENT | + (CTX.print.eps_occlusion_culling ? GL2PS_OCCLUSION_CULL : 0) | + (CTX.print.eps_best_root ? GL2PS_BEST_ROOT : 0) | + (CTX.print.eps_background ? GL2PS_DRAW_BACKGROUND : 0) | + (CTX.print.eps_compress ? GL2PS_COMPRESS : 0) | + (CTX.print.eps_ps3shading ? 0 : GL2PS_NO_PS3_SHADING); + + GLint buffsize = 0; + int res = GL2PS_OVERFLOW; + while(res == GL2PS_OVERFLOW) { + buffsize += 2048 * 2048; + gl2psBeginPage(CTX.base_filename, "Gmsh", viewport, + psformat, pssort, psoptions, GL_RGBA, 0, NULL, + 15, 20, 10, buffsize, fp, base); + if(CTX.print.eps_quality == 0){ + double modelview[16], projection[16]; + glGetDoublev(GL_PROJECTION_MATRIX, projection); + glGetDoublev(GL_MODELVIEW_MATRIX, modelview); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho((double)CTX.viewport[0], (double)CTX.viewport[2], + (double)CTX.viewport[1], (double)CTX.viewport[3], -1., 1.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glRasterPos2d(0, 0); + gl2psDrawPixels(width, height, 0, 0, GL_RGB, GL_FLOAT, buffer.GetPixels()); + glMatrixMode(GL_PROJECTION); + glLoadMatrixd(projection); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixd(modelview); + } + else{ + buffer.Fill(CTX.batch); + } + res = gl2psEndPage(); + } + + CTX.bg_gradient = old_bg_gradient; + fclose(fp); + } + break; + + case FORMAT_TEX: + { + FILE *fp; + if(!(fp = fopen(name, "w"))) { + Msg::Error("Unable to open file '%s'", name); + break; + } + GLint buffsize = 0; + int res = GL2PS_OVERFLOW; + while(res == GL2PS_OVERFLOW) { + buffsize += 2048 * 2048; + gl2psBeginPage(CTX.base_filename, "Gmsh", viewport, + GL2PS_TEX, GL2PS_NO_SORT, GL2PS_NONE, GL_RGBA, 0, NULL, + 0, 0, 0, buffsize, fp, base); + PixelBuffer buffer(width, height, GL_RGB, GL_UNSIGNED_BYTE); + int oldtext = CTX.print.text; + CTX.print.text = 1; + buffer.Fill(CTX.batch); + CTX.print.text = oldtext; + res = gl2psEndPage(); + } + fclose(fp); + } + break; +#endif + + default: + Msg::Error("Unknown output file format"); + printEndMessage = false; + break; + } + + if(printEndMessage) Msg::StatusBar(2, true, "Wrote '%s'", name); + + CTX.print.format = oldformat; + CTX.printing = 0; + +#if defined(HAVE_FLTK) + Draw(); +#endif +} diff --git a/Common/CreateFile.h b/Common/CreateFile.h new file mode 100644 index 0000000000000000000000000000000000000000..c7cc7f791aa3679d7c848a3c2c51dc9d340da7c8 --- /dev/null +++ b/Common/CreateFile.h @@ -0,0 +1,27 @@ +#ifndef _CREATE_FILE_H_ +#define _CREATE_FILE_H_ + +// Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to <gmsh@geuz.org>. + +int GuessFileFormatFromFileName(const char *name); +void GetDefaultFileName(int format, char *name); +void CreateOutputFile(const char *name, int format); + +#endif diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3f027395fb0735a23a4bb20bb64144a5b0da2cd1 --- /dev/null +++ b/Common/OpenFile.cpp @@ -0,0 +1,456 @@ +// $Id: OpenFile.cpp,v 1.1 2008-07-04 15:02:47 geuzaine Exp $ +// +// Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to <gmsh@geuz.org>. + +#include <string.h> +#include "Message.h" +#include "Geo.h" +#include "GModel.h" +#include "Numeric.h" +#include "Context.h" +#include "OpenFile.h" +#include "CommandLine.h" +#include "ReadImg.h" +#include "OS.h" +#include "StringUtils.h" + +#if !defined(HAVE_NO_PARSER) +#include "Parser.h" +#endif + +#if !defined(HAVE_NO_POST) +#include "PView.h" +#include "PViewData.h" +#endif + +#if defined(HAVE_FLTK) +#include "GmshUI.h" +#include "Draw.h" +#include "SelectBuffer.h" +#include "GUI.h" +extern GUI *WID; +#endif + +extern Context_T CTX; + +static void FinishUpBoundingBox() +{ + double range[3]; + + for(int i = 0; i < 3; i++){ + CTX.cg[i] = 0.5 * (CTX.min[i] + CTX.max[i]); + range[i] = CTX.max[i] - CTX.min[i]; + } + + if(range[0] < CTX.geom.tolerance && + range[1] < CTX.geom.tolerance && + range[2] < CTX.geom.tolerance) { + CTX.min[0] -= 1.; CTX.min[1] -= 1.; + CTX.max[0] += 1.; CTX.max[1] += 1.; + CTX.lc = 1.; + } + else if(range[0] < CTX.geom.tolerance && + range[1] < CTX.geom.tolerance) { + CTX.lc = range[2]; + CTX.min[0] -= CTX.lc; CTX.min[1] -= CTX.lc; + CTX.max[0] += CTX.lc; CTX.max[1] += CTX.lc; + } + else if(range[0] < CTX.geom.tolerance && + range[2] < CTX.geom.tolerance) { + CTX.lc = range[1]; + CTX.min[0] -= CTX.lc; CTX.max[0] += CTX.lc; + } + else if(range[1] < CTX.geom.tolerance && + range[2] < CTX.geom.tolerance) { + CTX.lc = range[0]; + CTX.min[1] -= CTX.lc; CTX.max[1] += CTX.lc; + } + else if(range[0] < CTX.geom.tolerance) { + CTX.lc = sqrt(DSQR(range[1]) + DSQR(range[2])); + CTX.min[0] -= CTX.lc; CTX.max[0] += CTX.lc; + } + else if(range[1] < CTX.geom.tolerance) { + CTX.lc = sqrt(DSQR(range[0]) + DSQR(range[2])); + CTX.min[1] -= CTX.lc; CTX.max[1] += CTX.lc; + } + else if(range[2] < CTX.geom.tolerance) { + CTX.lc = sqrt(DSQR(range[0]) + DSQR(range[1])); + } + else { + CTX.lc = sqrt(DSQR(range[0]) + DSQR(range[1]) + DSQR(range[2])); + } +} + +void SetBoundingBox(double xmin, double xmax, + double ymin, double ymax, + double zmin, double zmax) +{ + CTX.min[0] = xmin; CTX.max[0] = xmax; + CTX.min[1] = ymin; CTX.max[1] = ymax; + CTX.min[2] = zmin; CTX.max[2] = zmax; + FinishUpBoundingBox(); +} + +void SetBoundingBox() +{ + if(CTX.forced_bbox) return; + + SBoundingBox3d bb = GModel::current()->bounds(); + +#if !defined(HAVE_NO_POST) + if(bb.empty()) { + for(unsigned int i = 0; i < PView::list.size(); i++) + if(!PView::list[i]->getData()->getBoundingBox().empty()) + bb += PView::list[i]->getData()->getBoundingBox(); + } +#endif + + if(bb.empty()){ + bb += SPoint3(-1., -1., -1.); + bb += SPoint3(1., 1., 1.); + } + + CTX.min[0] = bb.min().x(); CTX.max[0] = bb.max().x(); + CTX.min[1] = bb.min().y(); CTX.max[1] = bb.max().y(); + CTX.min[2] = bb.min().z(); CTX.max[2] = bb.max().z(); + FinishUpBoundingBox(); +} + +// FIXME: this is necessary for now to have an approximate CTX.lc +// *while* parsing input files (it's important since some of the +// geometrical operations use a tolerance that depends on +// CTX.lc). This will be removed once the new database is filled +// directly during the parsing step +static SBoundingBox3d temp_bb; + +void ResetTemporaryBoundingBox() +{ + temp_bb.reset(); +} + +void AddToTemporaryBoundingBox(double x, double y, double z) +{ + temp_bb += SPoint3(x, y, z); + CTX.min[0] = temp_bb.min().x(); CTX.max[0] = temp_bb.max().x(); + CTX.min[1] = temp_bb.min().y(); CTX.max[1] = temp_bb.max().y(); + CTX.min[2] = temp_bb.min().z(); CTX.max[2] = temp_bb.max().z(); + FinishUpBoundingBox(); +} + +int ParseFile(const char *f, int close, int warn_if_missing) +{ +#if defined(HAVE_NO_PARSER) + Msg::Error("Gmsh parser is not compiled in this version"); + return 0; +#else + char yyname_old[256], tmp[256]; + FILE *yyin_old, *fp; + int yylineno_old, yyerrorstate_old, yyviewindex_old; + + // add 'b' for pure Windows programs: opening in text mode messes up + // fsetpos/fgetpos (used e.g. for user-defined functions) + if(!(fp = fopen(f, "rb"))){ + if(warn_if_missing) Msg::Warning("Unable to open file '%s'", f); + return 0; + } + +#if !defined(HAVE_NO_POST) + int numViewsBefore = PView::list.size(); +#endif + + strncpy(yyname_old, gmsh_yyname, 255); + yyin_old = gmsh_yyin; + yyerrorstate_old = gmsh_yyerrorstate; + yylineno_old = gmsh_yylineno; + yyviewindex_old = gmsh_yyviewindex; + + strncpy(gmsh_yyname, f, 255); + gmsh_yyin = fp; + gmsh_yyerrorstate = 0; + gmsh_yylineno = 1; + gmsh_yyviewindex = 0; + + fpos_t position; + fgetpos(gmsh_yyin, &position); + fgets(tmp, sizeof(tmp), gmsh_yyin); + fsetpos(gmsh_yyin, &position); + + while(!feof(gmsh_yyin)){ + gmsh_yyparse(); + if(gmsh_yyerrorstate > 20){ + Msg::Error("Too many errors: aborting..."); + force_yyflush(); + break; + } + } + + if(close) fclose(gmsh_yyin); + + strncpy(gmsh_yyname, yyname_old, 255); + gmsh_yyin = yyin_old; + gmsh_yyerrorstate = yyerrorstate_old; + gmsh_yylineno = yylineno_old; + gmsh_yyviewindex = yyviewindex_old; + +#if defined(HAVE_FLTK) && !defined(HAVE_NO_POST) + if(!CTX.batch && numViewsBefore != (int)PView::list.size()) + WID->update_views(); +#endif + + return 1; +#endif +} + +void ParseString(const char *str) +{ + if(!str) return; + FILE *fp; + if((fp = fopen(CTX.tmp_filename_fullpath, "w"))) { + fprintf(fp, str); + fprintf(fp, "\n"); + fclose(fp); + ParseFile(CTX.tmp_filename_fullpath, 1); + GModel::current()->importGEOInternals(); + } +} + +void SetProjectName(const char *name) +{ + char no_ext[256], ext[256], base[256]; + splitFileName(name, no_ext, ext, base); + + if(CTX.filename != name) // yes, we mean to compare the pointers + strncpy(CTX.filename, name, 255); + strncpy(CTX.no_ext_filename, no_ext, 255); + strncpy(CTX.base_filename, base, 255); + + GModel::current()->setName(base); + +#if defined(HAVE_FLTK) + if(!CTX.batch) WID->set_title(CTX.filename); +#endif +} + +int MergeFile(const char *name, int warn_if_missing) +{ + // added 'b' for pure Windows programs, since some of these files + // contain binary data + FILE *fp = fopen(name, "rb"); + if(!fp){ + if(warn_if_missing) Msg::Warning("Unable to open file '%s'", name); + return 0; + } + + char header[256]; + fgets(header, sizeof(header), fp); + fclose(fp); + + Msg::StatusBar(2, true, "Reading '%s'", name); + + char no_ext[256], ext[256], base[256]; + splitFileName(name, no_ext, ext, base); + +#if defined(HAVE_FLTK) + if(!CTX.batch) { + if(!strcmp(ext, ".gz")) { + // the real solution would be to rewrite all our I/O functions in + // terms of gzFile, but until then, this is better than nothing + if(fl_choice("File '%s' is in gzip format.\n\nDo you want to uncompress it?", + "Cancel", "Uncompress", NULL, name)){ + char tmp[256]; + sprintf(tmp, "gunzip -c %s > %s", name, no_ext); + if(SystemCall(tmp)) + Msg::Error("Failed to uncompress `%s': check directory permissions", name); + if(!strcmp(CTX.filename, name)) // this is the project file + SetProjectName(no_ext); + return MergeFile(no_ext); + } + } + } +#endif + + CTX.geom.draw = 0; // don't try to draw the model while reading + + GModel *m = GModel::current(); + + // FIXME: We need to decide what do do for CAD entities, meshes, + // etc. For meshes we should definitely create one new model per + // merge (and reset current() to the previous value after the + // merge). This will make multi-step multi-meshes post-pro views + // work out of the box. + // GModel *m = new GModel; + +#if !defined(HAVE_NO_POST) + int numViewsBefore = PView::list.size(); +#endif + + int status = 0; + if(!strcmp(ext, ".stl") || !strcmp(ext, ".STL")){ + status = m->readSTL(name, CTX.geom.tolerance); + } + else if(!strcmp(ext, ".brep") || !strcmp(ext, ".rle") || + !strcmp(ext, ".brp") || !strcmp(ext, ".BRP")){ + status = m->readOCCBREP(std::string(name)); + } + else if(!strcmp(ext, ".iges") || !strcmp(ext, ".IGES") || + !strcmp(ext, ".igs") || !strcmp(ext, ".IGS")){ + status = m->readOCCIGES(std::string(name)); + } + else if(!strcmp(ext, ".step") || !strcmp(ext, ".STEP") || + !strcmp(ext, ".stp") || !strcmp(ext, ".STP")){ + status = m->readOCCSTEP(std::string(name)); + } + else if(!strcmp(ext, ".unv") || !strcmp(ext, ".UNV")){ + status = m->readUNV(name); + } + else if(!strcmp(ext, ".wrl") || !strcmp(ext, ".WRL") || + !strcmp(ext, ".vrml") || !strcmp(ext, ".VRML") || + !strcmp(ext, ".iv") || !strcmp(ext, ".IV")){ + status = m->readVRML(name); + } + else if(!strcmp(ext, ".mesh") || !strcmp(ext, ".MESH")){ + status = m->readMESH(name); + } +#if !defined(HAVE_NO_POST) + else if(!strcmp(ext, ".med") || !strcmp(ext, ".MED") || + !strcmp(ext, ".mmed") || !strcmp(ext, ".MMED") || + !strcmp(ext, ".rmed") || !strcmp(ext, ".RMED")){ + status = GModel::readMED(name); + if(status > 1) status = PView::readMED(name); + } +#endif + else if(!strcmp(ext, ".bdf") || !strcmp(ext, ".BDF") || + !strcmp(ext, ".nas") || !strcmp(ext, ".NAS")){ + status = m->readBDF(name); + } + else if(!strcmp(ext, ".p3d") || !strcmp(ext, ".P3D")){ + status = m->readP3D(name); + } + else if(!strcmp(ext, ".fm") || !strcmp(ext, ".FM")) { + status = m->readFourier(name); + } +#if defined(HAVE_FLTK) + else if(!strcmp(ext, ".pnm") || !strcmp(ext, ".PNM") || + !strcmp(ext, ".pbm") || !strcmp(ext, ".PBM") || + !strcmp(ext, ".pgm") || !strcmp(ext, ".PGM") || + !strcmp(ext, ".ppm") || !strcmp(ext, ".PPM")) { + status = read_pnm(name); + } + else if(!strcmp(ext, ".bmp") || !strcmp(ext, ".BMP")) { + status = read_bmp(name); + } +#if defined(HAVE_LIBJPEG) + else if(!strcmp(ext, ".jpg") || !strcmp(ext, ".JPG") || + !strcmp(ext, ".jpeg") || !strcmp(ext, ".JPEG")) { + status = read_jpeg(name); + } +#endif +#if defined(HAVE_LIBPNG) + else if(!strcmp(ext, ".png") || !strcmp(ext, ".PNG")) { + status = read_png(name); + } +#endif +#endif + else { + CTX.geom.draw = 1; + if(!strncmp(header, "$PTS", 4) || !strncmp(header, "$NO", 3) || + !strncmp(header, "$PARA", 5) || !strncmp(header, "$ELM", 4) || + !strncmp(header, "$MeshFormat", 11)) { + status = m->readMSH(name); +#if !defined(HAVE_NO_POST) + if(status > 1) status = PView::readMSH(name); +#endif + } +#if !defined(HAVE_NO_POST) + else if(!strncmp(header, "$PostFormat", 11) || + !strncmp(header, "$View", 5)) { + status = PView::readPOS(name); + } +#endif + else { + status = m->readGEO(name); + } + } + + SetBoundingBox(); + + CTX.geom.draw = 1; + CTX.mesh.changed = ENT_ALL; + +#if defined(HAVE_FLTK) && !defined(HAVE_NO_POST) + if(!CTX.batch && numViewsBefore != (int)PView::list.size()) + WID->update_views(); +#endif + + Msg::StatusBar(2, true, "Read '%s'", name); + return status; +} + +void OpenProject(const char *name) +{ + if(CTX.threads_lock) { + Msg::Info("I'm busy! Ask me that later..."); + return; + } + CTX.threads_lock = 1; + + // FIXME: this will change once we clarify Open/Merge/Clear +#if !defined(HAVE_NO_POST) + for(int i = PView::list.size() - 1; i >= 0; i--) + if(PView::list[i]->getData()->hasModel(GModel::current())) + delete PView::list[i]; +#endif + GModel::current()->destroy(); + GModel::current()->getGEOInternals()->destroy(); + + // temporary hack until we fill the current GModel on the fly during + // parsing + ResetTemporaryBoundingBox(); + + SetProjectName(name); + MergeFile(name); + + CTX.threads_lock = 0; + +#if defined(HAVE_FLTK) + if(!CTX.batch){ + WID->reset_visibility(); + WID->update_views(); + } + ZeroHighlight(); +#endif +} + +void OpenProjectMacFinder(const char *filename) +{ + static int first = 1; + if(first || CTX.batch){ + // just copy the filename: it will be opened when the GUI is ready + // in main() + strncpy(CTX.filename, filename, 255); + first = 0; + } + else{ + OpenProject(filename); +#if defined(HAVE_FLTK) + Draw(); +#endif + } +} diff --git a/Common/OpenFile.h b/Common/OpenFile.h new file mode 100644 index 0000000000000000000000000000000000000000..e2407e763c4aa58043fd6e2e3f78a6ce1dbf8361 --- /dev/null +++ b/Common/OpenFile.h @@ -0,0 +1,34 @@ +#ifndef _OPENFILE_H_ +#define _OPENFILE_H_ + +// Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to <gmsh@geuz.org>. + +int ParseFile(const char *filename, int close, int warn_if_missing=0); +void ParseString(const char *str); +void OpenProject(const char *filename); +void OpenProjectMacFinder(const char *filename); +int MergeFile(const char *filename, int warn_if_missing=0); +void SetBoundingBox(double xmin, double xmax, + double ymin, double ymax, + double zmin, double zmax); +void SetBoundingBox(); +void AddToTemporaryBoundingBox(double x, double y, double z); + +#endif