diff --git a/Common/Context.h b/Common/Context.h index 957e52fca9409626e8cab8b6aedd3f1db046b03a..e3f9716bd6c25a20a35e118167b5a5e7c5d4699b 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -182,7 +182,7 @@ public : return val; } int oldxtrude, oldxtrude_recombine; - int allow_degenerated_extrude, save_all; + int allow_degenerated_extrude, save_all, stl_binary; char *triangle_options; int smooth_normals, reverse_all_normals; double angle_smooth_normals; diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index c2c15e5050bea53a22275e74f132e65d7b4924c2..4e0b623307f6c55fbe41064cbf8837d268799ae6 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -993,6 +993,8 @@ StringXNumber MeshOptions_Number[] = { "Disable dubious point insertion tests" }, { F|O, "StlDistanceTol" , opt_mesh_stl_distance_tol, 5.e-7 , "Distance tolerance between two distinct vertices in STL meshes" }, + { F|O, "StlBinary" , opt_mesh_stl_binary , 0. , + "Save STL files in binary format?" }, { F|O, "SurfaceEdges" , opt_mesh_surfaces_edges , 1. , "Display edges of surface mesh?" }, { F|O, "SurfaceFaces" , opt_mesh_surfaces_faces , 0. , diff --git a/Common/Options.cpp b/Common/Options.cpp index 047b9a06f76e6f9ccb4a9e60dda10b6683bb7462..d327fdc2cca8734ec6c67fcb060ece184d989439 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.299 2006-08-18 21:11:42 geuzaine Exp $ +// $Id: Options.cpp,v 1.300 2006-08-19 04:24:02 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -4626,6 +4626,13 @@ double opt_mesh_msh_file_version(OPT_ARGS_NUM) return CTX.mesh.msh_file_version; } +double opt_mesh_stl_binary(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX.mesh.stl_binary = (int)val; + return CTX.mesh.stl_binary; +} + double opt_mesh_nb_smoothing(OPT_ARGS_NUM) { if(action & GMSH_SET) @@ -4641,10 +4648,6 @@ double opt_mesh_nb_partitions(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX.mesh.nbPartitions = (int)val; - //#if defined(HAVE_FLTK) - // if(WID && (action & GMSH_GUI)) - // WID->mesh_value[0]->value(CTX.mesh.nb_smoothing); - //#endif return CTX.mesh.nbPartitions; } diff --git a/Common/Options.h b/Common/Options.h index 0ed6ff759259f18b33c8c9cb457c4fa02eabc1b0..0cad7a65065914a6bedb4a0ce88b1b4f93b55311 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -447,6 +447,7 @@ double opt_mesh_light_lines(OPT_ARGS_NUM); double opt_mesh_light_two_side(OPT_ARGS_NUM); double opt_mesh_format(OPT_ARGS_NUM); double opt_mesh_msh_file_version(OPT_ARGS_NUM); +double opt_mesh_stl_binary(OPT_ARGS_NUM); double opt_mesh_nb_smoothing(OPT_ARGS_NUM); double opt_mesh_stl_distance_tol(OPT_ARGS_NUM); double opt_mesh_nb_elem_per_rc(OPT_ARGS_NUM); diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index c586e98c157e974d6717ce25b6df93bfbd56efdb..61043149c6dd5c7915ec440c42293f095df5dc40 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.442 2006-08-19 01:12:38 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.443 2006-08-19 04:24:03 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -650,26 +650,25 @@ int _save_pos(char *name) int _save_unv(char *name) { - CreateOutputFile(name, CTX.mesh.format = FORMAT_UNV); + CreateOutputFile(name, FORMAT_UNV); return 1; } int _save_mesh(char *name) { - CreateOutputFile(name, CTX.mesh.format = FORMAT_MESH); + CreateOutputFile(name, FORMAT_MESH); return 1; } int _save_vrml(char *name) { - CreateOutputFile(name, CTX.mesh.format = FORMAT_VRML); + CreateOutputFile(name, FORMAT_VRML); return 1; } int _save_stl(char *name) { - CreateOutputFile(name, CTX.mesh.format = FORMAT_STL); - return 1; + return stl_dialog(name); } int _save_ps(char *name) @@ -752,6 +751,7 @@ int _save_auto(char *name) switch(GuessFileFormatFromFileName(name)){ case FORMAT_OPT : return _save_options(name); case FORMAT_MSH : return _save_msh(name); + case FORMAT_STL : return _save_stl(name); case FORMAT_PS : return _save_ps(name); case FORMAT_EPS : return _save_eps(name); case FORMAT_EPSTEX : return _save_epstex(name); diff --git a/Fltk/GUI_Extras.cpp b/Fltk/GUI_Extras.cpp index 3bda8024a3b54c45b48d1921a0639fbe41a248d6..ba4b10c38c4827fc22989beec573e5698732ae7d 100644 --- a/Fltk/GUI_Extras.cpp +++ b/Fltk/GUI_Extras.cpp @@ -1,4 +1,4 @@ -// $Id: GUI_Extras.cpp,v 1.18 2006-08-08 04:42:43 geuzaine Exp $ +// $Id: GUI_Extras.cpp,v 1.19 2006-08-19 04:24:03 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -582,3 +582,58 @@ int msh_dialog(char *name) return 0; } +// save stl dialog + +int stl_dialog(char *name) +{ + struct _stl_dialog{ + Fl_Window *window; + Fl_Choice *c; + Fl_Button *ok, *cancel; + }; + static _stl_dialog *dialog = NULL; + + static Fl_Menu_Item formatmenu[] = { + {"ASCII", 0, 0, 0}, + {"Binary", 0, 0, 0}, + {0} + }; + + if(!dialog){ + dialog = new _stl_dialog; + int h = 3*10 + 25 + 1*25, y = 0; + // not a "Dialog_Window" since it is modal + dialog->window = new Fl_Double_Window(200, h, "STL Options"); y = 10; + dialog->window->box(GMSH_WINDOW_BOX); + dialog->c = new Fl_Choice(10, y, 130, 25, "Format"); y+= 25; + dialog->c->menu(formatmenu); + dialog->c->align(FL_ALIGN_RIGHT); + dialog->ok = new Fl_Return_Button(10, y+10, 85, 25, "OK"); + dialog->cancel = new Fl_Button(105, y+10, 85, 25, "Cancel"); + dialog->window->set_modal(); + dialog->window->end(); + dialog->window->hotspot(dialog->window); + } + + dialog->c->value(CTX.mesh.stl_binary ? 1 : 0); + dialog->window->show(); + + while(dialog->window->shown()){ + Fl::wait(); + for (;;) { + Fl_Widget* o = Fl::readqueue(); + if (!o) break; + if (o == dialog->ok) { + opt_mesh_stl_binary(0, GMSH_SET | GMSH_GUI, dialog->c->value()); + CreateOutputFile(name, FORMAT_STL); + dialog->window->hide(); + return 1; + } + if (o == dialog->window || o == dialog->cancel){ + dialog->window->hide(); + return 0; + } + } + } + return 0; +} diff --git a/Fltk/GUI_Extras.h b/Fltk/GUI_Extras.h index 798ba31cfb735c38c84d34be416d9eb779cc5092..22ec826fc5e5dc103aaa4702d1466e7e36a4d23e 100644 --- a/Fltk/GUI_Extras.h +++ b/Fltk/GUI_Extras.h @@ -34,6 +34,7 @@ int gif_dialog(char *filename); int gl2ps_dialog(char *filename, char *title, int format, int TeX); int options_dialog(char *filename); int msh_dialog(char *filename); +int stl_dialog(char *filename); #endif diff --git a/Geo/GModel.h b/Geo/GModel.h index 7af51784c1e3054c43b464b30460fcc855040f55..1eabb8aefd6199182fccd21ed180bec633515f0c 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -123,7 +123,7 @@ class GModel double scalingFactor=1.0); int writePOS(const std::string &name, double scalingFactor=1.0); int readSTL(const std::string &name, double tolerance=1.e-3); - int writeSTL(const std::string &name, double scalingFactor=1.0); + int writeSTL(const std::string &name, bool binary=false, double scalingFactor=1.0); int readVRML(const std::string &name); int writeVRML(const std::string &name, double scalingFactor=1.0); int writeUNV(const std::string &name, double scalingFactor=1.0); diff --git a/Geo/GModelIO.cpp b/Geo/GModelIO.cpp index 89e146b768061629b8e46cdc5f0ec798c39e65fe..2854347247b9d517d7a3b98c863373be5986288b 100644 --- a/Geo/GModelIO.cpp +++ b/Geo/GModelIO.cpp @@ -1,4 +1,4 @@ -// $Id: GModelIO.cpp,v 1.25 2006-08-18 17:21:39 geuzaine Exp $ +// $Id: GModelIO.cpp,v 1.26 2006-08-19 04:24:03 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -728,23 +728,36 @@ int GModel::readSTL(const std::string &name, double tolerance) return 1; } -int GModel::writeSTL(const std::string &name, double scalingFactor) +int GModel::writeSTL(const std::string &name, bool binary, double scalingFactor) { - FILE *fp = fopen(name.c_str(), "w"); + FILE *fp = fopen(name.c_str(), binary ? "wb" : "w"); if(!fp){ Msg(GERROR, "Unable to open file '%s'", name.c_str()); return 0; } - fprintf(fp, "solid Created by Gmsh\n"); + if(!binary) + fprintf(fp, "solid Created by Gmsh\n"); + else{ + char header[80]; + strncpy(header, "Created by Gmsh", 80); + fwrite(header, sizeof(char), 80, fp); + unsigned int nfacets = 0; + for(fiter it = firstFace(); it != lastFace(); ++it) + nfacets += (*it)->triangles.size() + 2 * (*it)->quadrangles.size(); + fwrite(&nfacets, sizeof(unsigned int), 1, fp); + } + for(fiter it = firstFace(); it != lastFace(); ++it) { for(unsigned int i = 0; i < (*it)->triangles.size(); i++) - (*it)->triangles[i]->writeSTL(fp, scalingFactor); + (*it)->triangles[i]->writeSTL(fp, binary, scalingFactor); for(unsigned int i = 0; i < (*it)->quadrangles.size(); i++) - (*it)->quadrangles[i]->writeSTL(fp, scalingFactor); + (*it)->quadrangles[i]->writeSTL(fp, binary, scalingFactor); } - fprintf(fp, "endsolid Created by Gmsh\n"); + if(!binary) + fprintf(fp, "endsolid Created by Gmsh\n"); + fclose(fp); return 1; } diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp index a38fd8916814916fba442a436e816ab414cbd120..23e1130251a39bb5682b19fdcd913a358ab67ddb 100644 --- a/Geo/MElement.cpp +++ b/Geo/MElement.cpp @@ -1,4 +1,4 @@ -// $Id: MElement.cpp,v 1.8 2006-08-15 06:26:52 geuzaine Exp $ +// $Id: MElement.cpp,v 1.9 2006-08-19 04:24:03 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -176,40 +176,53 @@ void MElement::writePOS(FILE *fp, double scalingFactor, int elementary) fprintf(fp, "};\n"); } -void MElement::writeSTL(FILE *fp, double scalingFactor) +void MElement::writeSTL(FILE *fp, bool binary, double scalingFactor) { - int n = getNumVertices(); - if(n < 3 || n > 4) return; - - MVertex *v0 = getVertex(0); - MVertex *v1 = getVertex(1); - MVertex *v2 = getVertex(2); - double N[3]; - normal3points(v0->x(), v0->y(), v0->z(), - v1->x(), v1->y(), v1->z(), - v2->x(), v2->y(), v2->z(), N); - fprintf(fp, "facet normal %g %g %g\n", N[0], N[1], N[2]); - fprintf(fp, " outer loop\n"); - fprintf(fp, " vertex %g %g %g\n", v0->x() * scalingFactor, - v0->y() * scalingFactor, v0->z() * scalingFactor); - fprintf(fp, " vertex %g %g %g\n", v1->x() * scalingFactor, - v1->y() * scalingFactor, v1->z() * scalingFactor); - fprintf(fp, " vertex %g %g %g\n", v2->x() * scalingFactor, - v2->y() * scalingFactor, v2->z() * scalingFactor); - fprintf(fp, " endloop\n"); - fprintf(fp, "endfacet\n"); - if(n == 4){ - MVertex *v3 = getVertex(3); - fprintf(fp, "facet normal %g %g %g\n", N[0], N[1], N[2]); + if(getNumEdges() != 3 && getNumEdges() != 4) return; + int qid[3] = {0, 2, 3}; + SVector3 n = getFace(0).normal(); + if(!binary){ + fprintf(fp, "facet normal %g %g %g\n", n[0], n[1], n[2]); fprintf(fp, " outer loop\n"); - fprintf(fp, " vertex %g %g %g\n", v0->x() * scalingFactor, - v0->y() * scalingFactor, v0->z() * scalingFactor); - fprintf(fp, " vertex %g %g %g\n", v2->x() * scalingFactor, - v2->y() * scalingFactor, v2->z() * scalingFactor); - fprintf(fp, " vertex %g %g %g\n", v3->x() * scalingFactor, - v3->y() * scalingFactor, v3->z() * scalingFactor); + for(int j = 0; j < 3; j++) + fprintf(fp, " vertex %g %g %g\n", + getVertex(j)->x() * scalingFactor, + getVertex(j)->y() * scalingFactor, + getVertex(j)->z() * scalingFactor); fprintf(fp, " endloop\n"); fprintf(fp, "endfacet\n"); + if(getNumVertices() == 4){ + fprintf(fp, "facet normal %g %g %g\n", n[0], n[1], n[2]); + fprintf(fp, " outer loop\n"); + for(int j = 0; j < 3; j++) + fprintf(fp, " vertex %g %g %g\n", + getVertex(qid[j])->x() * scalingFactor, + getVertex(qid[j])->y() * scalingFactor, + getVertex(qid[j])->z() * scalingFactor); + fprintf(fp, " endloop\n"); + fprintf(fp, "endfacet\n"); + } + } + else{ + char data[50]; + float *coords = (float*)data; + coords[0] = n[0]; + coords[1] = n[1]; + coords[2] = n[2]; + for(int j = 0; j < 3; j++){ + coords[3 + 3 * j] = getVertex(j)->x() * scalingFactor; + coords[3 + 3 * j + 1] = getVertex(j)->y() * scalingFactor; + coords[3 + 3 * j + 2] = getVertex(j)->z() * scalingFactor; + } + fwrite(data, sizeof(char), 50, fp); + if(getNumVertices() == 4){ + for(int j = 0; j < 3; j++){ + coords[3 + 3 * j] = getVertex(qid[j])->x() * scalingFactor; + coords[3 + 3 * j + 1] = getVertex(qid[j])->y() * scalingFactor; + coords[3 + 3 * j + 2] = getVertex(qid[j])->z() * scalingFactor; + } + fwrite(data, sizeof(char), 50, fp); + } } } diff --git a/Geo/MElement.h b/Geo/MElement.h index c7d21f6278434a7679ade77c340cf8b0d293627d..004784d7cac0c20c404b4af48eddb5c704d3d411 100644 --- a/Geo/MElement.h +++ b/Geo/MElement.h @@ -131,7 +131,7 @@ class MElement int elementary=1, int physical=1); virtual void writePOS(FILE *fp, double scalingFactor=1.0, int elementary=1); - virtual void writeSTL(FILE *fp, double scalingFactor=1.0); + virtual void writeSTL(FILE *fp, bool binary=false, double scalingFactor=1.0); virtual void writeVRML(FILE *fp); virtual void writeUNV(FILE *fp, int elementary); virtual void writeMESH(FILE *fp, int elementary); diff --git a/Parser/CreateFile.cpp b/Parser/CreateFile.cpp index d8462fc28028551a112b65d25a547db21fcee0e9..20e18f3b229eae9b419a8dbdcd3ee3f6d4ba6c89 100644 --- a/Parser/CreateFile.cpp +++ b/Parser/CreateFile.cpp @@ -1,4 +1,4 @@ -// $Id: CreateFile.cpp,v 1.1 2006-08-12 19:34:16 geuzaine Exp $ +// $Id: CreateFile.cpp,v 1.2 2006-08-19 04:24:03 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -150,7 +150,7 @@ void CreateOutputFile(char *filename, int format) break; case FORMAT_STL: - GMODEL->writeSTL(name, CTX.mesh.scaling_factor); + GMODEL->writeSTL(name, CTX.mesh.stl_binary, CTX.mesh.scaling_factor); break; case FORMAT_VRML: diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi index 8ec47fe0365411aefba4fff360c7f9254a9a2926..d9e39e8ce25823aabedd6022948d71ff8c139f82 100644 --- a/doc/texinfo/opt_general.texi +++ b/doc/texinfo/opt_general.texi @@ -615,8 +615,8 @@ Default value: @code{450}@* Saved in: @code{General.SessionFileName} @item General.MouseSelection -Mouse selection mode (0=none, 1=no hover, 2=full)@* -Default value: @code{2}@* +Mouse hover and selection mode (0=none, 1=hover and select geometry but only select mesh, 2=hover and select geometry and mesh)@* +Default value: @code{1}@* Saved in: @code{General.OptionsFileName} @item General.NoPopup diff --git a/doc/texinfo/opt_mesh.texi b/doc/texinfo/opt_mesh.texi index c5345a6bd3479bbf4f90d5a3bd278cae0554e10f..c67276ce96bb0c68e6f41a07fc6a57c499d2efd3 100644 --- a/doc/texinfo/opt_mesh.texi +++ b/doc/texinfo/opt_mesh.texi @@ -359,6 +359,11 @@ Distance tolerance between two distinct vertices in STL meshes@* Default value: @code{5e-07}@* Saved in: @code{General.OptionsFileName} +@item Mesh.StlBinary +Save STL files in binary format?@* +Default value: @code{0}@* +Saved in: @code{General.OptionsFileName} + @item Mesh.SurfaceEdges Display edges of surface mesh?@* Default value: @code{1}@*