diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp index 0024d2836bbd69ce7736df1e0f811dbc26e30e9a..c555fd4c0971e3c10ae6f30c120d2f1b60c41ce0 100644 --- a/Parser/OpenFile.cpp +++ b/Parser/OpenFile.cpp @@ -1,454 +1,454 @@ -// $Id: OpenFile.cpp,v 1.146 2007-05-03 08:50:02 geuzaine Exp $ -// -// Copyright (C) 1997-2007 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>. - -#if defined(__CYGWIN__) -#include <sys/cygwin.h> -#endif - -#include "Gmsh.h" -#include "Geo.h" -#include "GModel.h" -#include "Numeric.h" -#include "Context.h" -#include "Parser.h" -#include "OpenFile.h" -#include "CommandLine.h" -#include "Views.h" -#include "ReadImg.h" -#include "OS.h" -#include "HighOrder.h" - -#if defined(HAVE_FLTK) -#include "GmshUI.h" -#include "Draw.h" -#include "SelectBuffer.h" -#include "GUI.h" -extern GUI *WID; -void UpdateViewsInGUI(); -#endif - -extern Mesh *THEM; -extern GModel *GMODEL; -extern Context_T CTX; - -void FixRelativePath(char *in, char *out){ - if(in[0] == '/' || in[0] == '\\' || (strlen(in)>2 && in[1] == ':')){ - // do nothing: 'in' is an absolute path - strcpy(out, in); - } - else{ - // append 'in' to the path of the parent file - strcpy(out, yyname); - int i = strlen(out)-1 ; - while(i >= 0 && yyname[i] != '/' && yyname[i] != '\\') i-- ; - out[i+1] = '\0'; - strcat(out, in); - } -} - -void FixWindowsPath(char *in, char *out){ -#if defined(__CYGWIN__) - cygwin_conv_to_win32_path(in, out); -#else - strcpy(out, in); -#endif -} - -void SplitFileName(char *name, char *base, char *ext) -{ - strcpy(base, name); - strcpy(ext, ""); - for(int i = strlen(name)-1; i >= 0; i--){ - if(name[i] == '.'){ - strcpy(ext, &name[i]); - base[i] = '\0'; - break; - } - } -} - -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] == 0. && range[1] == 0. && range[2] == 0.) { - CTX.min[0] -= 1.; CTX.min[1] -= 1.; - CTX.max[0] += 1.; CTX.max[1] += 1.; - CTX.lc = 1.; - } - else if(range[0] == 0. && range[1] == 0.) { - 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] == 0. && range[2] == 0.) { - CTX.lc = range[1]; - CTX.min[0] -= CTX.lc; CTX.max[0] += CTX.lc; - } - else if(range[1] == 0. && range[2] == 0.) { - CTX.lc = range[0]; - CTX.min[1] -= CTX.lc; CTX.max[1] += CTX.lc; - } - else if(range[0] == 0.) { - CTX.lc = sqrt(DSQR(range[1]) + DSQR(range[2])); - CTX.min[0] -= CTX.lc; CTX.max[0] += CTX.lc; - } - else if(range[1] == 0.) { - CTX.lc = sqrt(DSQR(range[0]) + DSQR(range[2])); - CTX.min[1] -= CTX.lc; CTX.max[1] += CTX.lc; - } - else if(range[2] == 0.) { - 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(void) -{ - if(CTX.forced_bbox) return; - - SBoundingBox3d bb; - - bb = GMODEL->bounds(); - - if(bb.empty() && List_Nbr(CTX.post.list)) { - for(int i = 0; i < List_Nbr(CTX.post.list); i++){ - Post_View *v = *(Post_View **)List_Pointer(CTX.post.list, i); - if(fabs(v->BBox[0]) != VAL_INF && - fabs(v->BBox[2]) != VAL_INF && - fabs(v->BBox[4]) != VAL_INF) - bb += SPoint3(v->BBox[0], v->BBox[2], v->BBox[4]); - if(fabs(v->BBox[1]) != VAL_INF && - fabs(v->BBox[3]) != VAL_INF && - fabs(v->BBox[5]) != VAL_INF) - bb += SPoint3(v->BBox[1], v->BBox[3], v->BBox[5]); - } - } - - 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(char *f, int close, int warn_if_missing) -{ - char yyname_old[256], tmp[256]; - FILE *yyin_old, *fp; - int yylineno_old, yyerrorstate_old, numviews_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; - } - - strncpy(yyname_old, yyname, 255); - yyin_old = yyin; - yyerrorstate_old = yyerrorstate; - yylineno_old = yylineno; - numviews_old = List_Nbr(CTX.post.list); - - strncpy(yyname, f, 255); - yyin = fp; - yyerrorstate = 0; - yylineno = 1; - - fpos_t position; - fgetpos(yyin, &position); - fgets(tmp, sizeof(tmp), yyin); - fsetpos(yyin, &position); - - while(!feof(yyin)){ - yyparse(); - if(yyerrorstate > 20){ - Msg(GERROR, "Too many errors: aborting..."); - force_yyflush(); - break; - } - } - - if(close) - fclose(yyin); - - strncpy(yyname, yyname_old, 255); - yyin = yyin_old; - yyerrorstate = yyerrorstate_old; - yylineno = yylineno_old; - - if(List_Nbr(CTX.post.list) != numviews_old){ -#if defined(HAVE_FLTK) - UpdateViewsInGUI(); -#endif - } - - return 1; -} - -void ParseString(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); - if(GMODEL) GMODEL->importTHEM(); - } -} - -void SetProjectName(char *name) -{ - char base[356], ext[256]; - SplitFileName(name, base, ext); - - strncpy(CTX.filename, name, 255); - strncpy(CTX.base_filename, base, 255); - -#if defined(HAVE_FLTK) - if(!CTX.batch) WID->set_title(CTX.filename); -#endif -} - -int MergeFile(char *name, int warn_if_missing) -{ - // FIXME: to be removed - // #if defined(HAVE_FOURIER_MODEL) - // if(!strcmp(name, "falcon") || !strcmp(name, "ship")){ - // GMODEL->readFourier(name); - // SetBoundingBox(); - // CTX.mesh.changed = ENT_ALL; - // return 1; - // } - // #endif - - // 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(STATUS2, "Reading '%s'", name); - - char ext[256], base[256]; - SplitFileName(name, base, ext); - -#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, base); - SystemCall(tmp); - if(!strcmp(CTX.filename, name)) // this is the project file - SetProjectName(base); - return MergeFile(base); - } - } - } -#endif - - CTX.geom.draw = 0; // don't try to draw the model while reading - int status = 0; - if(!strcmp(ext, ".stl") || !strcmp(ext, ".STL")){ - status = GMODEL->readSTL(name, CTX.geom.tolerance); - } - else if(!strcmp(ext, ".brep") || !strcmp(ext, ".rle") || - !strcmp(ext, ".brp") || !strcmp(ext, ".BRP")){ - GMODEL->readOCCBREP(std::string(name)); - } - else if(!strcmp(ext, ".iges") || !strcmp(ext, ".IGES") || - !strcmp(ext, ".igs") || !strcmp(ext, ".IGS")){ - GMODEL->readOCCIGES(std::string(name)); - } - else if(!strcmp(ext, ".step") || !strcmp(ext, ".STEP") || - !strcmp(ext, ".stp") || !strcmp(ext, ".STP")){ - GMODEL->readOCCSTEP(std::string(name)); - } - else if(!strcmp(ext, ".unv") || !strcmp(ext, ".UNV")){ - status = GMODEL->readUNV(name); - } - else if(!strcmp(ext, ".wrl") || !strcmp(ext, ".WRL") || - !strcmp(ext, ".vrml") || !strcmp(ext, ".VRML") || - !strcmp(ext, ".iv") || !strcmp(ext, ".IV")){ - status = GMODEL->readVRML(name); - } - else if(!strcmp(ext, ".mesh") || !strcmp(ext, ".MESH")){ - status = GMODEL->readMESH(name); - } - else if(!strcmp(ext, ".bdf") || !strcmp(ext, ".BDF") || - !strcmp(ext, ".nas") || !strcmp(ext, ".NAS")){ - status = GMODEL->readBDF(name); - } - else if(!strcmp(ext, ".p3d") || !strcmp(ext, ".P3D")){ - status = GMODEL->readP3D(name); - } - else if(!strcmp(ext, ".fm") || !strcmp(ext, ".FM")) { - status = GMODEL->readF(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 = GMODEL->readMSH(name); - } - else if(!strncmp(header, "$PostFormat", 11) || - !strncmp(header, "$View", 5)) { - status = ReadView(name); - } - else { - status = GMODEL->readGEO(name); - } - } - - SetBoundingBox(); - - CTX.geom.draw = 1; - CTX.mesh.changed = ENT_ALL; - - checkHighOrderTriangles ( GMODEL ); - - Msg(STATUS2, "Read '%s'", name); - return status; -} - -void OpenProject(char *name) -{ - if(CTX.threads_lock) { - Msg(INFO, "I'm busy! Ask me that later..."); - return; - } - CTX.threads_lock = 1; - - GMODEL->destroy(); - THEM->destroy(); - - // Initialize pseudo random mesh generator to the same seed - srand(1); - - // temporary hack until we fill 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(); - 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((char*)filename); -#if defined(HAVE_FLTK) - Draw(); -#endif - } -} - +// $Id: OpenFile.cpp,v 1.147 2007-05-05 12:35:19 geuzaine Exp $ +// +// Copyright (C) 1997-2007 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>. + +#if defined(__CYGWIN__) +#include <sys/cygwin.h> +#endif + +#include "Gmsh.h" +#include "Geo.h" +#include "GModel.h" +#include "Numeric.h" +#include "Context.h" +#include "Parser.h" +#include "OpenFile.h" +#include "CommandLine.h" +#include "Views.h" +#include "ReadImg.h" +#include "OS.h" +#include "HighOrder.h" + +#if defined(HAVE_FLTK) +#include "GmshUI.h" +#include "Draw.h" +#include "SelectBuffer.h" +#include "GUI.h" +extern GUI *WID; +void UpdateViewsInGUI(); +#endif + +extern Mesh *THEM; +extern GModel *GMODEL; +extern Context_T CTX; + +void FixRelativePath(char *in, char *out){ + if(in[0] == '/' || in[0] == '\\' || (strlen(in)>2 && in[1] == ':')){ + // do nothing: 'in' is an absolute path + strcpy(out, in); + } + else{ + // append 'in' to the path of the parent file + strcpy(out, yyname); + int i = strlen(out)-1 ; + while(i >= 0 && yyname[i] != '/' && yyname[i] != '\\') i-- ; + out[i+1] = '\0'; + strcat(out, in); + } +} + +void FixWindowsPath(char *in, char *out){ +#if defined(__CYGWIN__) + cygwin_conv_to_win32_path(in, out); +#else + strcpy(out, in); +#endif +} + +void SplitFileName(char *name, char *base, char *ext) +{ + strcpy(base, name); + strcpy(ext, ""); + for(int i = strlen(name)-1; i >= 0; i--){ + if(name[i] == '.'){ + strcpy(ext, &name[i]); + base[i] = '\0'; + break; + } + } +} + +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] == 0. && range[1] == 0. && range[2] == 0.) { + CTX.min[0] -= 1.; CTX.min[1] -= 1.; + CTX.max[0] += 1.; CTX.max[1] += 1.; + CTX.lc = 1.; + } + else if(range[0] == 0. && range[1] == 0.) { + 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] == 0. && range[2] == 0.) { + CTX.lc = range[1]; + CTX.min[0] -= CTX.lc; CTX.max[0] += CTX.lc; + } + else if(range[1] == 0. && range[2] == 0.) { + CTX.lc = range[0]; + CTX.min[1] -= CTX.lc; CTX.max[1] += CTX.lc; + } + else if(range[0] == 0.) { + CTX.lc = sqrt(DSQR(range[1]) + DSQR(range[2])); + CTX.min[0] -= CTX.lc; CTX.max[0] += CTX.lc; + } + else if(range[1] == 0.) { + CTX.lc = sqrt(DSQR(range[0]) + DSQR(range[2])); + CTX.min[1] -= CTX.lc; CTX.max[1] += CTX.lc; + } + else if(range[2] == 0.) { + 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(void) +{ + if(CTX.forced_bbox) return; + + SBoundingBox3d bb; + + bb = GMODEL->bounds(); + + if(bb.empty() && List_Nbr(CTX.post.list)) { + for(int i = 0; i < List_Nbr(CTX.post.list); i++){ + Post_View *v = *(Post_View **)List_Pointer(CTX.post.list, i); + if(fabs(v->BBox[0]) != VAL_INF && + fabs(v->BBox[2]) != VAL_INF && + fabs(v->BBox[4]) != VAL_INF) + bb += SPoint3(v->BBox[0], v->BBox[2], v->BBox[4]); + if(fabs(v->BBox[1]) != VAL_INF && + fabs(v->BBox[3]) != VAL_INF && + fabs(v->BBox[5]) != VAL_INF) + bb += SPoint3(v->BBox[1], v->BBox[3], v->BBox[5]); + } + } + + 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(char *f, int close, int warn_if_missing) +{ + char yyname_old[256], tmp[256]; + FILE *yyin_old, *fp; + int yylineno_old, yyerrorstate_old, numviews_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; + } + + strncpy(yyname_old, yyname, 255); + yyin_old = yyin; + yyerrorstate_old = yyerrorstate; + yylineno_old = yylineno; + numviews_old = List_Nbr(CTX.post.list); + + strncpy(yyname, f, 255); + yyin = fp; + yyerrorstate = 0; + yylineno = 1; + + fpos_t position; + fgetpos(yyin, &position); + fgets(tmp, sizeof(tmp), yyin); + fsetpos(yyin, &position); + + while(!feof(yyin)){ + yyparse(); + if(yyerrorstate > 20){ + Msg(GERROR, "Too many errors: aborting..."); + force_yyflush(); + break; + } + } + + if(close) + fclose(yyin); + + strncpy(yyname, yyname_old, 255); + yyin = yyin_old; + yyerrorstate = yyerrorstate_old; + yylineno = yylineno_old; + + if(List_Nbr(CTX.post.list) != numviews_old){ +#if defined(HAVE_FLTK) + UpdateViewsInGUI(); +#endif + } + + return 1; +} + +void ParseString(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); + if(GMODEL) GMODEL->importTHEM(); + } +} + +void SetProjectName(char *name) +{ + char base[356], ext[256]; + SplitFileName(name, base, ext); + + strncpy(CTX.filename, name, 255); + strncpy(CTX.base_filename, base, 255); + +#if defined(HAVE_FLTK) + if(!CTX.batch) WID->set_title(CTX.filename); +#endif +} + +int MergeFile(char *name, int warn_if_missing) +{ + // FIXME: to be removed + // #if defined(HAVE_FOURIER_MODEL) + // if(!strcmp(name, "falcon") || !strcmp(name, "ship")){ + // GMODEL->readFourier(name); + // SetBoundingBox(); + // CTX.mesh.changed = ENT_ALL; + // return 1; + // } + // #endif + + // 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(STATUS2, "Reading '%s'", name); + + char ext[256], base[256]; + SplitFileName(name, base, ext); + +#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, base); + SystemCall(tmp); + if(!strcmp(CTX.filename, name)) // this is the project file + SetProjectName(base); + return MergeFile(base); + } + } + } +#endif + + CTX.geom.draw = 0; // don't try to draw the model while reading + int status = 0; + if(!strcmp(ext, ".stl") || !strcmp(ext, ".STL")){ + status = GMODEL->readSTL(name, CTX.geom.tolerance); + } + else if(!strcmp(ext, ".brep") || !strcmp(ext, ".rle") || + !strcmp(ext, ".brp") || !strcmp(ext, ".BRP")){ + GMODEL->readOCCBREP(std::string(name)); + } + else if(!strcmp(ext, ".iges") || !strcmp(ext, ".IGES") || + !strcmp(ext, ".igs") || !strcmp(ext, ".IGS")){ + GMODEL->readOCCIGES(std::string(name)); + } + else if(!strcmp(ext, ".step") || !strcmp(ext, ".STEP") || + !strcmp(ext, ".stp") || !strcmp(ext, ".STP")){ + GMODEL->readOCCSTEP(std::string(name)); + } + else if(!strcmp(ext, ".unv") || !strcmp(ext, ".UNV")){ + status = GMODEL->readUNV(name); + } + else if(!strcmp(ext, ".wrl") || !strcmp(ext, ".WRL") || + !strcmp(ext, ".vrml") || !strcmp(ext, ".VRML") || + !strcmp(ext, ".iv") || !strcmp(ext, ".IV")){ + status = GMODEL->readVRML(name); + } + else if(!strcmp(ext, ".mesh") || !strcmp(ext, ".MESH")){ + status = GMODEL->readMESH(name); + } + else if(!strcmp(ext, ".bdf") || !strcmp(ext, ".BDF") || + !strcmp(ext, ".nas") || !strcmp(ext, ".NAS")){ + status = GMODEL->readBDF(name); + } + else if(!strcmp(ext, ".p3d") || !strcmp(ext, ".P3D")){ + status = GMODEL->readP3D(name); + } + else if(!strcmp(ext, ".fm") || !strcmp(ext, ".FM")) { + status = GMODEL->readF(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 = GMODEL->readMSH(name); + } + else if(!strncmp(header, "$PostFormat", 11) || + !strncmp(header, "$View", 5)) { + status = ReadView(name); + } + else { + status = GMODEL->readGEO(name); + } + } + + SetBoundingBox(); + + CTX.geom.draw = 1; + CTX.mesh.changed = ENT_ALL; + + checkHighOrderTriangles ( GMODEL ); + + Msg(STATUS2, "Read '%s'", name); + return status; +} + +void OpenProject(char *name) +{ + if(CTX.threads_lock) { + Msg(INFO, "I'm busy! Ask me that later..."); + return; + } + CTX.threads_lock = 1; + + GMODEL->destroy(); + THEM->destroy(); + + // Initialize pseudo random mesh generator to the same seed + srand(1); + + // temporary hack until we fill 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(); + 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((char*)filename); +#if defined(HAVE_FLTK) + Draw(); +#endif + } +} +