Select Git revision
Lambda2.cpp
-
Christophe Geuzaine authored
- removed all the crappy STL code and rewrote it using JF's POLY_rep class - generalized POLY_rep so that we can use the polygonal discretization as a surface mesh, and mesh in 3D afterwards. I.e., we can now take an input triangulation (a single surface in STL format, multiple surfaces in STL format, one or more surfaces defined using the new "Discrete Surface" commands), and generate a 3D mesh that uses it. We could in theory even mix triangulated and "normal" surfaces in the same geometry, but nothing is done at the moment to ensure that the mesh at the interfaces would match (if it does, it actually works very nicely) - new STL mesh output format to export a surface mesh as a STL file - added an option to the GEO output routine to save the surface mesh as discrete surfaces associated with the geometrical surfaces - added STL and Text output formats for post-processing views (the text output allows for example to exploit plugin-generated data in gnuplot) - generalized Plugin(Evaluate): * can loop automatically over all the timestep and/or components * can do operations using data from an external view - if the 2 views are based on the same grid, the plugin does the evaluation very efficiently - if the 2 views are based on differenet grids, the plugin automatically interpolates the external view data onto the grid of the current view - added new Rand() function in MathEval - default colormap is now # 2 (the Matlab "Jet" colormap)
Christophe Geuzaine authored- removed all the crappy STL code and rewrote it using JF's POLY_rep class - generalized POLY_rep so that we can use the polygonal discretization as a surface mesh, and mesh in 3D afterwards. I.e., we can now take an input triangulation (a single surface in STL format, multiple surfaces in STL format, one or more surfaces defined using the new "Discrete Surface" commands), and generate a 3D mesh that uses it. We could in theory even mix triangulated and "normal" surfaces in the same geometry, but nothing is done at the moment to ensure that the mesh at the interfaces would match (if it does, it actually works very nicely) - new STL mesh output format to export a surface mesh as a STL file - added an option to the GEO output routine to save the surface mesh as discrete surfaces associated with the geometrical surfaces - added STL and Text output formats for post-processing views (the text output allows for example to exploit plugin-generated data in gnuplot) - generalized Plugin(Evaluate): * can loop automatically over all the timestep and/or components * can do operations using data from an external view - if the 2 views are based on the same grid, the plugin does the evaluation very efficiently - if the 2 views are based on differenet grids, the plugin automatically interpolates the external view data onto the grid of the current view - added new Rand() function in MathEval - default colormap is now # 2 (the Matlab "Jet" colormap)
fileDialogs.cpp 79.68 KiB
// Gmsh - Copyright (C) 1997-2019 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
//
// Contributor(s):
// Stephen Guzik
// Sebastian Eiser
//
#include <limits>
#include <sstream>
#include <errno.h>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Check_Button.H>
#include <FL/Fl_Return_Button.H>
#include <FL/Fl_Value_Slider.H>
#include <FL/Fl_Value_Input.H>
#include <FL/Fl_Menu_Window.H>
#include <FL/Fl_Select_Browser.H>
#include <FL/Fl_Toggle_Button.H>
#include <FL/Fl_Round_Button.H>
#include <FL/Fl_Choice.H>
#include "GmshConfig.h"
#include "GmshMessage.h"
#include "GmshDefines.h"
#include "StringUtils.h"
#include "FlGui.h"
#include "optionWindow.h"
#include "fileDialogs.h"
#include "CreateFile.h"
#include "Options.h"
#include "Context.h"
#include "GModel.h"
#include "PView.h"
#include "PViewOptions.h"
#include <iostream>
// File chooser
#if defined(HAVE_NATIVE_FILE_CHOOSER)
#include <FL/Fl_Native_File_Chooser.H>
static Fl_Native_File_Chooser *fc = 0;
#else
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_File_Input.H>
class flFileChooser : public Fl_File_Chooser {
// we derive our own so we can set its position (The original file
// chooser doesn't expose its window to the world, so we need to use
// a cheap hack to get to it. Even worse is the hack used to get the
// focus on the file input widget.)
private:
Fl_Window *_win;
Fl_File_Input *_in;
public:
flFileChooser(const char *d, const char *p, int t, const char *title)
: Fl_File_Chooser(d, p, t, title)
{
_win = dynamic_cast<Fl_Window *>(newButton->parent()->parent());
_in = dynamic_cast<Fl_File_Input *>(
previewButton->parent()->parent()->resizable());
}
void show()
{
if(_win) {
_win->show();
rescan(); // necessary since fltk 1.1.7
if(_in)
_in->take_focus();
else
_win->take_focus();
}
else
Fl_File_Chooser::show();
}
void position(int x, int y)
{
if(_win) _win->position(x, y);
}
int x()
{
if(_win)
return _win->x();
else
return 100;
}
int y()
{
if(_win)
return _win->y();
else
return 100;
}
};
static flFileChooser *fc = 0;
#endif
int fileChooser(FILE_CHOOSER_TYPE type, const char *message, const char *filter,
const char *fname)
{
static char thefilter[1024] = "";
static int thefilterindex = 0;
// reset the filter and the selection if the filter has changed
if(strncmp(thefilter, filter, sizeof(thefilter) - 1)) {
strncpy(thefilter, filter, sizeof(thefilter) - 1);
thefilter[sizeof(thefilter) - 1] = '\0';
thefilterindex = 0;
}
// determine where to start
std::string thepath;
if(fname)
thepath = std::string(fname);
else {
std::vector<std::string> tmp =
SplitFileName(GModel::current()->getFileName());
thepath = tmp[0] + tmp[1]; // i.e., without the extension!
}
std::vector<std::string> split = SplitFileName(thepath);
if(split[0].empty()) thepath = std::string("./") + thepath;
#if defined(HAVE_NATIVE_FILE_CHOOSER)
if(!fc) fc = new Fl_Native_File_Chooser();
switch(type) {
case FILE_CHOOSER_MULTI:
fc->type(Fl_Native_File_Chooser::BROWSE_MULTI_FILE);
break;
case FILE_CHOOSER_CREATE:
fc->type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE);
break;
case FILE_CHOOSER_DIRECTORY:
fc->type(Fl_Native_File_Chooser::BROWSE_DIRECTORY);
break;
default: fc->type(Fl_Native_File_Chooser::BROWSE_FILE); break;
}
fc->title(message);
fc->filter(filter);
fc->filter_value(thefilterindex);
static bool first = true;
if(first) {
// preset the path and the file only the first time in a given
// session. Afterwards, always reuse the last directory
fc->preset_file(thepath.c_str());
first = false;
}
else {
std::string name = split[1] + split[2];
fc->preset_file(name.c_str());
}
int ret = 0;
switch(fc->show()) {
case -1: break; // error
case 1: break; // cancel
default:
if(fc->filename()) ret = fc->count();
break;
}
thefilterindex = fc->filter_value();
// hack to clear the KEYDOWN state that remains when calling the
// file chooser on Mac and Windows using a keyboard shortcut
Fl::e_state = 0;
return ret;
#else
Fl_File_Chooser::show_label = "Format:";
Fl_File_Chooser::all_files_label = "All files (*)";
if(!fc) {
fc =
new flFileChooser(getenv("PWD") ? "." : CTX::instance()->homeDir.c_str(),
thefilter, Fl_File_Chooser::SINGLE, message);
fc->position(CTX::instance()->fileChooserPosition[0],
CTX::instance()->fileChooserPosition[1]);
}
switch(type) {
case FILE_CHOOSER_MULTI: fc->type(Fl_File_Chooser::MULTI); break;
case FILE_CHOOSER_CREATE: fc->type(Fl_File_Chooser::CREATE); break;
case FILE_CHOOSER_DIRECTORY: fc->type(Fl_File_Chooser::DIRECTORY); break;
default: fc->type(Fl_File_Chooser::SINGLE); break;
}
fc->label(message);
fc->filter(thefilter);
fc->filter_value(thefilterindex);
static bool first = true;
if(first) {
// preset the path and the file only the first time in a given
// session. Afterwards, always reuse the last directory
fc->value(thepath.c_str());
first = false;
}
else {
std::string name = split[1] + split[2];
fc->value(name.c_str());
}
fc->show();
while(fc->shown()) Fl::wait();
thefilterindex = fc->filter_value();
if(fc->value())
return fc->count();
else
return 0;
#endif
}
std::string fileChooserGetName(int num)
{
if(!fc) return "";
#if defined(HAVE_NATIVE_FILE_CHOOSER)
return std::string(fc->filename(num - 1));
#else
return std::string(fc->value(num));
#endif
}
int fileChooserGetFilter()
{
if(!fc) return 0;
return fc->filter_value();
}
void fileChooserGetPosition(int *x, int *y)
{
if(!fc) return;
#if !defined(HAVE_NATIVE_FILE_CHOOSER)
*x = fc->x();
*y = fc->y();
#endif
}
// Generic save bitmap dialog
int genericBitmapFileDialog(const char *name, const char *title, int format)
{
struct _genericBitmapFileDialog {
Fl_Window *window;
Fl_Value_Slider *s[2];
Fl_Check_Button *b[3];
Fl_Value_Input *v[2];
Fl_Button *ok, *cancel;
};
static _genericBitmapFileDialog *dialog = NULL;
if(!dialog) {
dialog = new _genericBitmapFileDialog;
int h = 3 * WB + 7 * BH, w = 2 * BB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h);
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->b[0] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Print text strings");
y += BH;
dialog->b[0]->type(FL_TOGGLE_BUTTON);
dialog->b[1] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Print background");
y += BH;
dialog->b[1]->type(FL_TOGGLE_BUTTON);
dialog->b[2] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Composite all window tiles");
y += BH;
dialog->b[2]->type(FL_TOGGLE_BUTTON);
dialog->v[0] = new Fl_Value_Input(WB, y, BB / 2, BH);
dialog->v[0]->minimum(-1);
dialog->v[0]->maximum(5000);
dialog->v[0]->step(1);
dialog->v[1] =
new Fl_Value_Input(WB + BB / 2, y, BB - BB / 2, BH, "Dimensions");
y += BH;
dialog->v[1]->minimum(-1);
dialog->v[1]->maximum(5000);
dialog->v[1]->step(1);
dialog->v[1]->align(FL_ALIGN_RIGHT);
dialog->s[0] = new Fl_Value_Slider(WB, y, BB, BH, "Quality");
y += BH;
dialog->s[0]->type(FL_HOR_SLIDER);
dialog->s[0]->align(FL_ALIGN_RIGHT);
dialog->s[0]->minimum(1);
dialog->s[0]->maximum(100);
dialog->s[0]->step(1);
dialog->s[1] = new Fl_Value_Slider(WB, y, BB, BH, "Smoothing");
y += BH;
dialog->s[1]->type(FL_HOR_SLIDER);
dialog->s[1]->align(FL_ALIGN_RIGHT);
dialog->s[1]->minimum(0);
dialog->s[1]->maximum(100);
dialog->s[1]->step(1);
dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
if(format == FORMAT_JPEG) {
dialog->s[0]->activate();
dialog->s[1]->activate();
}
else {
dialog->s[0]->deactivate();
dialog->s[1]->deactivate();
}
dialog->window->label(title);
dialog->s[0]->value(CTX::instance()->print.jpegQuality);
dialog->s[1]->value(CTX::instance()->print.jpegSmoothing);
dialog->b[0]->value(CTX::instance()->print.text);
dialog->b[1]->value(CTX::instance()->print.background);
dialog->b[2]->value(CTX::instance()->print.compositeWindows);
dialog->v[0]->value(CTX::instance()->print.width);
dialog->v[1]->value(CTX::instance()->print.height);
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->ok) {
opt_print_jpeg_quality(0, GMSH_SET | GMSH_GUI,
(int)dialog->s[0]->value());
opt_print_jpeg_smoothing(0, GMSH_SET | GMSH_GUI,
(int)dialog->s[1]->value());
opt_print_text(0, GMSH_SET | GMSH_GUI, (int)dialog->b[0]->value());
opt_print_background(0, GMSH_SET | GMSH_GUI,
(int)dialog->b[1]->value());
opt_print_composite_windows(0, GMSH_SET | GMSH_GUI,
(int)dialog->b[2]->value());
opt_print_width(0, GMSH_SET | GMSH_GUI, (int)dialog->v[0]->value());
opt_print_height(0, GMSH_SET | GMSH_GUI, (int)dialog->v[1]->value());
CreateOutputFile(name, format);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// pgf dialog
int pgfBitmapFileDialog(const char *name, const char *title, int format)
{
struct _pgfBitmapFileDialog {
Fl_Window *window;
Fl_Value_Slider *s[2];
Fl_Check_Button *b[3];
Fl_Value_Input *v[2];
Fl_Button *ok, *cancel;
};
static _pgfBitmapFileDialog *dialog = NULL;
if(!dialog) {
dialog = new _pgfBitmapFileDialog;
int h = 3 * WB + 5 * BH, w = 2 * BB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h);
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->b[0] = new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Flat graphics");
y += BH;
dialog->b[0]->type(FL_TOGGLE_BUTTON);
dialog->b[1] = new Fl_Check_Button(WB, y, 2 * BB + WB, BH,
"Export axis (for entire fig)");
y += BH;
dialog->b[1]->type(FL_TOGGLE_BUTTON);
dialog->b[2] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Horizontal colorbar");
y += BH;
dialog->b[2]->type(FL_TOGGLE_BUTTON);
dialog->v[0] = new Fl_Value_Input(WB, y, BB / 2, BH);
dialog->v[0]->minimum(-1);
dialog->v[0]->maximum(5000);
dialog->v[0]->step(1);
dialog->v[1] =
new Fl_Value_Input(WB + BB / 2, y, BB - BB / 2, BH, "Dimensions");
y += BH;
dialog->v[1]->minimum(-1);
dialog->v[1]->maximum(5000);
dialog->v[1]->step(1);
dialog->v[1]->align(FL_ALIGN_RIGHT);
dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->window->label(title);
dialog->b[0]->value(CTX::instance()->print.pgfTwoDim);
dialog->b[1]->value(CTX::instance()->print.pgfExportAxis);
dialog->b[2]->value(CTX::instance()->print.pgfHorizBar);
dialog->v[0]->value(CTX::instance()->print.width);
dialog->v[1]->value(CTX::instance()->print.height);
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->ok) {
opt_print_text(0, GMSH_SET | GMSH_GUI, 0); // never print any text
opt_print_pgf_two_dim(0, GMSH_SET | GMSH_GUI,
(int)dialog->b[0]->value());
opt_print_background(0, GMSH_SET | GMSH_GUI,
0); // never print background
opt_print_pgf_export_axis(0, GMSH_SET | GMSH_GUI,
(int)dialog->b[1]->value());
opt_print_pgf_horiz_bar(0, GMSH_SET | GMSH_GUI,
(int)dialog->b[2]->value());
opt_print_composite_windows(0, GMSH_SET | GMSH_GUI,
0); // never do compositing print
opt_print_width(0, GMSH_SET | GMSH_GUI, (int)dialog->v[0]->value());
opt_print_height(0, GMSH_SET | GMSH_GUI, (int)dialog->v[1]->value());
CreateOutputFile(name, format);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// TeX dialog
int latexFileDialog(const char *name)
{
struct _latexFileDialog {
Fl_Window *window;
Fl_Check_Button *b;
Fl_Button *ok, *cancel;
};
static _latexFileDialog *dialog = NULL;
if(!dialog) {
dialog = new _latexFileDialog;
int h = 3 * WB + 2 * BH, w = 2 * BB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, "LaTeX Options");
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->b =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Print strings as equations");
y += BH;
dialog->b->type(FL_TOGGLE_BUTTON);
dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->b->value(CTX::instance()->print.texAsEquation);
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->ok) {
opt_print_tex_as_equation(0, GMSH_SET | GMSH_GUI,
(int)dialog->b->value());
CreateOutputFile(name, FORMAT_TEX);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// Save mpeg dialog
int mpegFileDialog(const char *name)
{
struct _mpegFileDialog {
Fl_Window *window;
Fl_Round_Button *b[3];
Fl_Group *param;
Fl_Check_Button *c[3];
Fl_Input *p;
Fl_Value_Input *v[5];
Fl_Group *buttons;
Fl_Button *ok, *preview, *cancel;
};
static _mpegFileDialog *dialog = NULL;
if(!dialog) {
dialog = new _mpegFileDialog;
int h = 4 * WB + 11 * BH, w = 3 * BB + 4 * WB, y = WB;
int ww = w - 2 * WB;
dialog->window = new Fl_Double_Window(w, h, "MPEG Options");
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_non_modal();
{
Fl_Group *o = new Fl_Group(WB, y, ww, 3 * BH);
dialog->b[0] =
new Fl_Round_Button(WB, y, ww, BH, "Cycle through time steps");
y += BH;
dialog->b[0]->type(FL_RADIO_BUTTON);
dialog->b[1] = new Fl_Round_Button(WB, y, ww, BH, "Cycle through views");
y += BH;
dialog->b[1]->type(FL_RADIO_BUTTON);
dialog->b[2] =
new Fl_Round_Button(WB, y, ww, BH, "Loop over print parameter value");
y += BH;
dialog->b[2]->type(FL_RADIO_BUTTON);
o->end();
}
int ww2 = (2 * BB + WB) / 4;
dialog->param = new Fl_Group(WB, y, ww, 2 * BH);
dialog->p = new Fl_Input(WB, y, ww, BH);
y += BH;
dialog->p->align(FL_ALIGN_RIGHT);
dialog->v[2] = new Fl_Value_Input(WB, y, ww2, BH);
dialog->v[3] = new Fl_Value_Input(WB + ww2, y, ww2, BH);
dialog->v[4] = new Fl_Value_Input(WB + 2 * ww2, y, 2 * BB + WB - 3 * ww2,
BH, "First / Last / Steps");
dialog->v[4]->align(FL_ALIGN_RIGHT);
dialog->v[4]->minimum(1);
dialog->v[4]->maximum(500);
dialog->v[4]->step(1);
y += BH;
dialog->param->end();
y += WB;
dialog->v[0] =
new Fl_Value_Input(WB, y, ww2, BH, "Frame duration (in seconds)");
y += BH;
dialog->v[0]->minimum(1. / 30.);
dialog->v[0]->maximum(2.);
dialog->v[0]->step(1. / 30.);
dialog->v[0]->precision(3);
dialog->v[0]->align(FL_ALIGN_RIGHT);
dialog->v[1] = new Fl_Value_Input(WB, y, ww2, BH, "Steps between frames");
y += BH;
dialog->v[1]->minimum(1);
dialog->v[1]->maximum(100);
dialog->v[1]->step(1);
dialog->v[1]->align(FL_ALIGN_RIGHT);
dialog->c[0] = new Fl_Check_Button(WB, y, ww, BH, "Print background");
y += BH;
dialog->c[0]->type(FL_TOGGLE_BUTTON);
dialog->c[1] =
new Fl_Check_Button(WB, y, ww, BH, "Composite all window tiles");
y += BH;
dialog->c[1]->type(FL_TOGGLE_BUTTON);
dialog->c[2] = new Fl_Check_Button(WB, y, ww, BH, "Delete temporary files");
y += BH;
dialog->c[2]->type(FL_TOGGLE_BUTTON);
dialog->buttons = new Fl_Group(WB, y + WB, ww, BH);
dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK");
dialog->preview = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Preview");
dialog->cancel = new Fl_Button(3 * WB + 2 * BB, y + WB, BB, BH, "Cancel");
dialog->buttons->end();
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->b[0]->value(CTX::instance()->post.animCycle == 0);
dialog->b[1]->value(CTX::instance()->post.animCycle == 1);
dialog->b[2]->value(CTX::instance()->post.animCycle == 2);
dialog->v[0]->value(CTX::instance()->post.animDelay);
dialog->v[1]->value(CTX::instance()->post.animStep);
dialog->c[0]->value(CTX::instance()->print.background);
dialog->c[1]->value(CTX::instance()->print.compositeWindows);
dialog->c[2]->value(CTX::instance()->print.deleteTmpFiles);
dialog->p->value(CTX::instance()->print.parameterCommand.c_str());
if(dialog->b[2]->value())
dialog->param->activate();
else
dialog->param->deactivate();
dialog->v[2]->value(CTX::instance()->print.parameterFirst);
dialog->v[3]->value(CTX::instance()->print.parameterLast);
dialog->v[4]->value(CTX::instance()->print.parameterSteps);
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->b[0] || o == dialog->b[1] || o == dialog->b[2]) {
if(dialog->b[2]->value())
dialog->param->activate();
else
dialog->param->deactivate();
}
if(o == dialog->ok || o == dialog->preview) {
opt_post_anim_cycle(
0, GMSH_SET | GMSH_GUI,
dialog->b[2]->value() ? 2 : dialog->b[1]->value() ? 1 : 0);
opt_print_parameter_command(0, GMSH_SET | GMSH_GUI, dialog->p->value());
opt_print_parameter_first(0, GMSH_SET | GMSH_GUI,
dialog->v[2]->value());
opt_print_parameter_last(0, GMSH_SET | GMSH_GUI, dialog->v[3]->value());
opt_print_parameter_steps(0, GMSH_SET | GMSH_GUI,
dialog->v[4]->value());
opt_post_anim_delay(0, GMSH_SET | GMSH_GUI, dialog->v[0]->value());
opt_post_anim_step(0, GMSH_SET | GMSH_GUI, (int)dialog->v[1]->value());
opt_print_background(0, GMSH_SET | GMSH_GUI,
(int)dialog->c[0]->value());
opt_print_composite_windows(0, GMSH_SET | GMSH_GUI,
(int)dialog->c[1]->value());
opt_print_delete_tmp_files(0, GMSH_SET | GMSH_GUI,
(int)dialog->c[2]->value());
int format = (o == dialog->preview) ? FORMAT_MPEG_PREVIEW : FORMAT_MPEG;
dialog->buttons->deactivate();
CreateOutputFile(name, format, o == dialog->ok, true);
dialog->buttons->activate();
if(o == dialog->ok) {
dialog->window->hide();
return 1;
}
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// Save gif dialog
int gifFileDialog(const char *name)
{
struct _gifFileDialog {
Fl_Window *window;
Fl_Check_Button *b[7];
Fl_Button *ok, *cancel;
};
static _gifFileDialog *dialog = NULL;
if(!dialog) {
dialog = new _gifFileDialog;
int h = 3 * WB + 8 * BH, w = 2 * BB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, "GIF Options");
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->b[0] = new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Dither");
y += BH;
dialog->b[1] = new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Interlace");
y += BH;
dialog->b[2] = new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Sort colormap");
y += BH;
dialog->b[3] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Transparent background");
y += BH;
dialog->b[4] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Print text strings");
y += BH;
dialog->b[5] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Print background");
y += BH;
dialog->b[6] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Composite all window tiles");
y += BH;
for(int i = 0; i < 7; i++) { dialog->b[i]->type(FL_TOGGLE_BUTTON); }
dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->b[0]->value(CTX::instance()->print.gifDither);
dialog->b[1]->value(CTX::instance()->print.gifInterlace);
dialog->b[2]->value(CTX::instance()->print.gifSort);
dialog->b[3]->value(CTX::instance()->print.gifTransparent);
dialog->b[4]->value(CTX::instance()->print.text);
dialog->b[5]->value(CTX::instance()->print.background);
dialog->b[6]->value(CTX::instance()->print.compositeWindows);
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->ok) {
opt_print_gif_dither(0, GMSH_SET | GMSH_GUI, dialog->b[0]->value());
opt_print_gif_interlace(0, GMSH_SET | GMSH_GUI, dialog->b[1]->value());
opt_print_gif_sort(0, GMSH_SET | GMSH_GUI, dialog->b[2]->value());
opt_print_gif_transparent(0, GMSH_SET | GMSH_GUI,
dialog->b[3]->value());
opt_print_text(0, GMSH_SET | GMSH_GUI, dialog->b[4]->value());
opt_print_background(0, GMSH_SET | GMSH_GUI, dialog->b[5]->value());
opt_print_composite_windows(0, GMSH_SET | GMSH_GUI,
dialog->b[6]->value());
CreateOutputFile(name, FORMAT_GIF);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// Save ps/eps/pdf dialog
static void activate_gl2ps_choices(int format, int quality,
Fl_Check_Button *b[5])
{
#if defined(HAVE_LIBZ)
b[0]->activate();
#else
b[0]->deactivate();
#endif
switch(quality) {
case 0: // raster
b[1]->deactivate();
b[2]->deactivate();
b[3]->deactivate();
break;
case 1: // simple sort
case 3: // unsorted
b[1]->activate();
b[2]->deactivate();
if(format == FORMAT_PS || format == FORMAT_EPS)
b[3]->activate();
else
b[3]->deactivate();
break;
case 2: // bsp sort
b[1]->activate();
b[2]->activate();
if(format == FORMAT_PS || format == FORMAT_EPS)
b[3]->activate();
else
b[3]->deactivate();
break;
}
}
int gl2psFileDialog(const char *name, const char *title, int format)
{
struct _gl2psFileDialog {
Fl_Window *window;
Fl_Check_Button *b[6];
Fl_Choice *c;
Fl_Button *ok, *cancel;
};
static _gl2psFileDialog *dialog = NULL;
static Fl_Menu_Item sortmenu[] = {{"Raster image", 0, 0, 0},
{"Vector simple sort", 0, 0, 0},
{"Vector accurate sort", 0, 0, 0},
{"Vector unsorted", 0, 0, 0},
{0}};
if(!dialog) {
dialog = new _gl2psFileDialog;
int h = 3 * WB + 8 * BH, w = 2 * BB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h);
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->c = new Fl_Choice(WB, y, BB + WB + BB / 2, BH, "Type");
y += BH;
dialog->c->menu(sortmenu);
dialog->c->align(FL_ALIGN_RIGHT);
dialog->b[0] = new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Compress");
y += BH;
dialog->b[1] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Remove hidden primitives");
y += BH;
dialog->b[2] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Optimize BSP tree");
y += BH;
dialog->b[3] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Use level 3 shading");
y += BH;
dialog->b[4] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Print text strings");
y += BH;
dialog->b[5] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Print background");
y += BH;
for(int i = 0; i < 6; i++) { dialog->b[i]->type(FL_TOGGLE_BUTTON); }
dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->window->label(title);
dialog->c->value(CTX::instance()->print.epsQuality);
dialog->b[0]->value(CTX::instance()->print.epsCompress);
dialog->b[1]->value(CTX::instance()->print.epsOcclusionCulling);
dialog->b[2]->value(CTX::instance()->print.epsBestRoot);
dialog->b[3]->value(CTX::instance()->print.epsPS3Shading);
dialog->b[4]->value(CTX::instance()->print.text);
dialog->b[5]->value(CTX::instance()->print.background);
activate_gl2ps_choices(format, CTX::instance()->print.epsQuality, dialog->b);
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->c) {
activate_gl2ps_choices(format, dialog->c->value(), dialog->b);
}
if(o == dialog->ok) {
opt_print_eps_quality(0, GMSH_SET | GMSH_GUI, dialog->c->value());
opt_print_eps_compress(0, GMSH_SET | GMSH_GUI, dialog->b[0]->value());
opt_print_eps_occlusion_culling(0, GMSH_SET | GMSH_GUI,
dialog->b[1]->value());
opt_print_eps_best_root(0, GMSH_SET | GMSH_GUI, dialog->b[2]->value());
opt_print_eps_ps3shading(0, GMSH_SET | GMSH_GUI, dialog->b[3]->value());
opt_print_text(0, GMSH_SET | GMSH_GUI, dialog->b[4]->value());
opt_print_background(0, GMSH_SET | GMSH_GUI, dialog->b[5]->value());
CreateOutputFile(name, format);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// Save options dialog
int optionsFileDialog(const char *name)
{
struct _optionsFileDialog {
Fl_Window *window;
Fl_Check_Button *b[2];
Fl_Button *ok, *cancel;
};
static _optionsFileDialog *dialog = NULL;
if(!dialog) {
dialog = new _optionsFileDialog;
int h = 3 * WB + 3 * BH, w = 2 * BB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, "Options");
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->b[0] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Save only modified options");
y += BH;
dialog->b[0]->value(1);
dialog->b[0]->type(FL_TOGGLE_BUTTON);
dialog->b[1] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Print help strings");
y += BH;
dialog->b[1]->value(0);
dialog->b[1]->type(FL_TOGGLE_BUTTON);
dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->ok) {
Msg::StatusBar(true, "Writing '%s'...", name);
PrintOptions(0, GMSH_FULLRC, dialog->b[0]->value(),
dialog->b[1]->value(), name);
Msg::StatusBar(true, "Done writing '%s'", name);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// geo dialog
int geoFileDialog(const char *name)
{
struct _geoFileDialog {
Fl_Window *window;
Fl_Check_Button *b[2];
Fl_Button *ok, *cancel;
};
static _geoFileDialog *dialog = NULL;
if(!dialog) {
dialog = new _geoFileDialog;
int h = 3 * WB + 3 * BH, w = 2 * BB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, "GEO Options");
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->b[0] =
new Fl_Check_Button(WB, y, 2 * BB + WB, BH, "Save physical group labels");
y += BH;
dialog->b[0]->type(FL_TOGGLE_BUTTON);
dialog->b[1] = new Fl_Check_Button(WB, y, 2 * BB + WB, BH,
"Only save physical entities");
y += BH;
dialog->b[1]->type(FL_TOGGLE_BUTTON);
dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->b[0]->value(CTX::instance()->print.geoLabels ? 1 : 0);
dialog->b[1]->value(CTX::instance()->print.geoOnlyPhysicals ? 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_print_geo_labels(0, GMSH_SET | GMSH_GUI,
dialog->b[0]->value() ? 1 : 0);
opt_print_geo_only_physicals(0, GMSH_SET | GMSH_GUI,
dialog->b[1]->value() ? 1 : 0);
CreateOutputFile(name, FORMAT_GEO);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
int meshStatFileDialog(const char *name)
{
struct _meshStatFileDialog {
Fl_Window *window;
Fl_Check_Button *b[8];
Fl_Button *ok, *cancel;
};
static _meshStatFileDialog *dialog = NULL;
int BBB = BB + 9; // labels too long
if(!dialog) {
dialog = new _meshStatFileDialog;
int h = 3 * WB + 9 * BH, w = 2 * BBB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, "POS Options");
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->b[0] =
new Fl_Check_Button(WB, y, 2 * BBB + WB, BH, "Save all elements");
y += BH;
dialog->b[1] =
new Fl_Check_Button(WB, y, 2 * BBB + WB, BH, "Print elementary tags");
y += BH;
dialog->b[2] =
new Fl_Check_Button(WB, y, 2 * BBB + WB, BH, "Print element numbers");
y += BH;
dialog->b[3] = new Fl_Check_Button(WB, y, 2 * BBB + WB, BH,
"Print SICN quality measure");
y += BH;
dialog->b[4] = new Fl_Check_Button(WB, y, 2 * BBB + WB, BH,
"Print SIGE quality measure");
y += BH;
dialog->b[5] = new Fl_Check_Button(WB, y, 2 * BBB + WB, BH,
"Print Gamma quality measure");
y += BH;
dialog->b[6] =
new Fl_Check_Button(WB, y, 2 * BBB + WB, BH, "Print Eta quality measure");
y += BH;
dialog->b[7] = new Fl_Check_Button(WB, y, 2 * BBB + WB, BH,
"Print Disto quality measure");
y += BH;
for(int i = 0; i < 6; i++) dialog->b[i]->type(FL_TOGGLE_BUTTON);
dialog->ok = new Fl_Return_Button(WB, y + WB, BBB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BBB, y + WB, BBB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->b[0]->value(CTX::instance()->mesh.saveAll ? 1 : 0);
dialog->b[1]->value(CTX::instance()->print.posElementary ? 1 : 0);
dialog->b[2]->value(CTX::instance()->print.posElement ? 1 : 0);
dialog->b[3]->value(CTX::instance()->print.posSICN ? 1 : 0);
dialog->b[4]->value(CTX::instance()->print.posSIGE ? 1 : 0);
dialog->b[5]->value(CTX::instance()->print.posGamma ? 1 : 0);
dialog->b[6]->value(CTX::instance()->print.posEta ? 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_save_all(0, GMSH_SET | GMSH_GUI,
dialog->b[0]->value() ? 1 : 0);
opt_print_pos_elementary(0, GMSH_SET | GMSH_GUI,
dialog->b[1]->value() ? 1 : 0);
opt_print_pos_element(0, GMSH_SET | GMSH_GUI,
dialog->b[2]->value() ? 1 : 0);
opt_print_pos_SICN(0, GMSH_SET | GMSH_GUI,
dialog->b[3]->value() ? 1 : 0);
opt_print_pos_SIGE(0, GMSH_SET | GMSH_GUI,
dialog->b[4]->value() ? 1 : 0);
opt_print_pos_gamma(0, GMSH_SET | GMSH_GUI,
dialog->b[5]->value() ? 1 : 0);
opt_print_pos_eta(0, GMSH_SET | GMSH_GUI,
dialog->b[6]->value() ? 1 : 0);
opt_print_pos_disto(0, GMSH_SET | GMSH_GUI,
dialog->b[7]->value() ? 1 : 0);
CreateOutputFile(name, FORMAT_POS);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// Save msh dialog
struct _mshFileDialog {
Fl_Window *window;
Fl_Check_Button *b[4];
Fl_Choice *c;
Fl_Button *ok, *cancel;
};
int mshFileDialog(const char *name)
{
static _mshFileDialog *dialog = NULL;
static Fl_Menu_Item formatmenu[] = {
{"Version 1", 0, 0, 0}, {"Version 2 ASCII", 0, 0, 0},
{"Version 2 Binary", 0, 0, 0}, {"Version 4 ASCII", 0, 0, 0},
{"Version 4 Binary", 0, 0, 0}, {0}};
int BBB = BB + 9; // labels too long
if(!dialog) {
dialog = new _mshFileDialog;
int h = 3 * WB + 6 * BH, w = 2 * BBB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, "MSH Options");
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->c = new Fl_Choice(WB, y, BBB + BBB / 2, BH, "Format");
y += BH;
dialog->c->menu(formatmenu);
dialog->c->align(FL_ALIGN_RIGHT);
dialog->c->callback((Fl_Callback *)format_cb, dialog);
dialog->b[0] =
new Fl_Check_Button(WB, y, 2 * BBB + WB, BH, "Save all elements");
y += BH;
dialog->b[0]->type(FL_TOGGLE_BUTTON);
dialog->b[1] = new Fl_Check_Button(WB, y, 2 * BBB + WB, BH,
"Save parametric coordinates");
y += BH;
dialog->b[1]->type(FL_TOGGLE_BUTTON);
dialog->b[2] = new Fl_Check_Button(WB, y, 2 * BBB + WB, BH,
"Save one file per partition");
y += BH;
dialog->b[2]->type(FL_TOGGLE_BUTTON);
dialog->b[3] = new Fl_Check_Button(WB, y, 2 * BBB + WB, BH,
"Save partition topology file");
y += BH;
dialog->b[3]->type(FL_TOGGLE_BUTTON);
dialog->ok = new Fl_Return_Button(WB, y + WB, BBB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BBB, y + WB, BBB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
if(CTX::instance()->mesh.mshFileVersion == 1.0)
dialog->c->value(0);
else if(CTX::instance()->mesh.mshFileVersion < 4.0)
dialog->c->value(!CTX::instance()->mesh.binary ? 1 : 2);
else
dialog->c->value(!CTX::instance()->mesh.binary ? 3 : 4);
dialog->b[0]->value(CTX::instance()->mesh.saveAll ? 1 : 0);
dialog->b[1]->value(CTX::instance()->mesh.saveParametric ? 1 : 0);
dialog->b[2]->value(CTX::instance()->mesh.partitionSplitMeshFiles ? 1 : 0);
dialog->b[3]->value(CTX::instance()->mesh.partitionSaveTopologyFile ? 1 : 0);
if(GModel::current()->getNumPartitions() == 0) {
dialog->b[2]->deactivate();
dialog->b[3]->deactivate();
}
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->ok) {
opt_mesh_msh_file_version(
0, GMSH_SET | GMSH_GUI,
(dialog->c->value() == 0) ?
1.0 :
(dialog->c->value() == 1 || dialog->c->value() == 2) ? 2.2 : 4.1);
opt_mesh_binary(
0, GMSH_SET | GMSH_GUI,
(dialog->c->value() == 2 || dialog->c->value() == 4) ? 1 : 0);
opt_mesh_save_all(0, GMSH_SET | GMSH_GUI,
dialog->b[0]->value() ? 1 : 0);
opt_mesh_save_parametric(0, GMSH_SET | GMSH_GUI,
dialog->b[1]->value() ? 1 : 0);
opt_mesh_partition_split_mesh_files(0, GMSH_SET | GMSH_GUI,
dialog->b[2]->value() ? 1 : 0);
opt_mesh_partition_save_topology_file(0, GMSH_SET | GMSH_GUI,
dialog->b[3]->value() ? 1 : 0);
CreateOutputFile(name, FORMAT_MSH);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
void format_cb(Fl_Widget *widget, void *data)
{
_mshFileDialog *dialog = static_cast<_mshFileDialog *>(data);
if((dialog->c->value() == 3 || dialog->c->value() == 4 ||
dialog->c->value() == 1 || dialog->c->value() == 2) &&
GModel::current()->getNumPartitions() > 0) {
dialog->b[2]->activate();
dialog->b[3]->activate();
}
else {
dialog->b[2]->deactivate();
dialog->b[3]->deactivate();
}
}
// unv/inp mesh dialog
int unvinpFileDialog(const char *name, const char *title, int format)
{
struct _unvFileDialog {
Fl_Window *window;
Fl_Check_Button *b[2];
Fl_Button *ok, *cancel;
};
static _unvFileDialog *dialog = NULL;
int BBB = BB + 9; // labels too long
if(!dialog) {
dialog = new _unvFileDialog;
int h = 3 * WB + 3 * BH, w = 2 * BBB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, title);
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->b[0] =
new Fl_Check_Button(WB, y, 2 * BBB + WB, BH, "Save all elements");
y += BH;
dialog->b[0]->type(FL_TOGGLE_BUTTON);
dialog->b[1] =
new Fl_Check_Button(WB, y, 2 * BBB + WB, BH, "Save groups of nodes");
y += BH;
dialog->b[1]->type(FL_TOGGLE_BUTTON);
dialog->ok = new Fl_Return_Button(WB, y + WB, BBB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BBB, y + WB, BBB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->b[0]->value(CTX::instance()->mesh.saveAll ? 1 : 0);
dialog->b[1]->value(CTX::instance()->mesh.saveGroupsOfNodes ? 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_save_all(0, GMSH_SET | GMSH_GUI,
dialog->b[0]->value() ? 1 : 0);
opt_mesh_save_groups_of_nodes(0, GMSH_SET | GMSH_GUI,
dialog->b[1]->value() ? 1 : 0);
CreateOutputFile(name, format);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// key mesh dialog
int keyFileDialog(const char *name, const char *title, int format)
{
struct _keyFileDialog {
Fl_Window *window;
Fl_Choice *c[3];
Fl_Check_Button *b[2];
Fl_Button *ok, *cancel;
};
static _keyFileDialog *dialog = NULL;
static Fl_Menu_Item beammenu[] = {{"Physical groups", 0, 0, 0},
{"Save all", 0, 0, 0},
{"Ignore", 0, 0, 0},
{0}};
static Fl_Menu_Item shellmenu[] = {{"Physical groups", 0, 0, 0},
{"Save all", 0, 0, 0},
{"Ignore", 0, 0, 0},
{0}};
static Fl_Menu_Item solidmenu[] = {{"Physical groups", 0, 0, 0},
{"Save all", 0, 0, 0},
{"Ignore", 0, 0, 0},
{0}};
int BBB = BB + 16; // labels too long
if(!dialog) {
dialog = new _keyFileDialog;
int h = 3 * WB + 6 * BH, w = 2 * BBB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, title);
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->c[0] = new Fl_Choice(WB, y, BBB + BBB / 4, BH, "Line");
y += BH;
dialog->c[0]->menu(beammenu);
dialog->c[0]->align(FL_ALIGN_RIGHT);
dialog->c[1] = new Fl_Choice(WB, y, BBB + BBB / 4, BH, "Surface");
y += BH;
dialog->c[1]->menu(shellmenu);
dialog->c[1]->align(FL_ALIGN_RIGHT);
dialog->c[2] = new Fl_Choice(WB, y, BBB + BBB / 4, BH, "Volume");
y += BH;
dialog->c[2]->menu(solidmenu);
dialog->c[2]->align(FL_ALIGN_RIGHT);
dialog->b[0] =
new Fl_Check_Button(WB, y, 2 * BBB + WB, BH, "Save groups of elements");
y += BH;
dialog->b[0]->type(FL_TOGGLE_BUTTON);
dialog->b[1] =
new Fl_Check_Button(WB, y, 2 * BBB + WB, BH, "Save groups of nodes");
y += BH;
dialog->b[1]->type(FL_TOGGLE_BUTTON);
dialog->ok = new Fl_Return_Button(WB, y + WB, BBB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BBB, y + WB, BBB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->c[0]->value((CTX::instance()->mesh.saveAll & 4) ?
1 :
(CTX::instance()->mesh.saveAll & 8) ? 2 : 0);
dialog->c[1]->value((CTX::instance()->mesh.saveAll & 16) ?
1 :
(CTX::instance()->mesh.saveAll & 32) ? 2 : 0);
dialog->c[2]->value((CTX::instance()->mesh.saveAll & 64) ?
1 :
(CTX::instance()->mesh.saveAll & 128) ? 2 : 0);
dialog->b[0]->value(CTX::instance()->mesh.saveGroupsOfNodes & 2 ? 1 : 0);
dialog->b[1]->value(CTX::instance()->mesh.saveGroupsOfNodes & 1 ? 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_save_all(0, GMSH_SET | GMSH_GUI,
dialog->c[0]->value() * 4 +
dialog->c[1]->value() * 16 +
dialog->c[2]->value() * 64);
opt_mesh_save_groups_of_nodes(0, GMSH_SET | GMSH_GUI,
(dialog->b[0]->value() ? 2 : 0) +
(dialog->b[1]->value() ? 1 : 0));
CreateOutputFile(name, format);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// Save bdf dialog
int bdfFileDialog(const char *name)
{
struct _bdfFileDialog {
Fl_Window *window;
Fl_Choice *c, *d;
Fl_Check_Button *b;
Fl_Button *ok, *cancel;
};
static _bdfFileDialog *dialog = NULL;
static Fl_Menu_Item formatmenu[] = {{"Free field", 0, 0, 0},
{"Small field", 0, 0, 0},
{"Long field", 0, 0, 0},
{0}};
static Fl_Menu_Item tagmenu[] = {{"Elementary entity", 0, 0, 0},
{"Physical entity", 0, 0, 0},
{"Partition", 0, 0, 0},
{0}};
int BBB = BB + 16; // labels too long
if(!dialog) {
dialog = new _bdfFileDialog;
int h = 3 * WB + 4 * BH, w = 2 * BBB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, "BDF Options");
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->c = new Fl_Choice(WB, y, BBB + BBB / 4, BH, "Format");
y += BH;
dialog->c->menu(formatmenu);
dialog->c->align(FL_ALIGN_RIGHT);
dialog->d = new Fl_Choice(WB, y, BBB + BBB / 4, BH, "Element tag");
y += BH;
dialog->d->menu(tagmenu);
dialog->d->align(FL_ALIGN_RIGHT);
dialog->b =
new Fl_Check_Button(WB, y, 2 * BBB + WB, BH, "Save all elements");
y += BH;
dialog->b->type(FL_TOGGLE_BUTTON);
dialog->ok = new Fl_Return_Button(WB, y + WB, BBB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BBB, y + WB, BBB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->c->value(CTX::instance()->mesh.bdfFieldFormat);
dialog->d->value((CTX::instance()->mesh.saveElementTagType == 3) ?
2 :
(CTX::instance()->mesh.saveElementTagType == 2) ? 1 : 0);
dialog->b->value(CTX::instance()->mesh.saveAll ? 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_bdf_field_format(0, GMSH_SET | GMSH_GUI, dialog->c->value());
opt_mesh_save_element_tag_type(0, GMSH_SET | GMSH_GUI,
dialog->d->value() + 1);
opt_mesh_save_all(0, GMSH_SET | GMSH_GUI, dialog->b->value() ? 1 : 0);
CreateOutputFile(name, FORMAT_BDF);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// Generic mesh dialog
int stlFileDialog(const char *name)
{
struct _stlFileDialog {
Fl_Window *window;
Fl_Choice *c[2];
Fl_Check_Button *b;
Fl_Button *ok, *cancel;
};
static _stlFileDialog *dialog = NULL;
static Fl_Menu_Item formatmenu[] = {
{"ASCII", 0, 0, 0},
{"Binary", 0, 0, 0},
{0}
};
static Fl_Menu_Item solidmenu[] = {
{"Single", 0, 0, 0},
{"Per surface", 0, 0, 0},
{"Per physical surface", 0, 0, 0},
{0}
};
int BBB = BB + 9; // labels too long
if(!dialog) {
dialog = new _stlFileDialog;
int h = 3 * WB + 4 * BH, w = 2 * BBB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, "STL Options");
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->c[0] = new Fl_Choice(WB, y, BBB + BBB / 4, BH, "Format");
y += BH;
dialog->c[0]->menu(formatmenu);
dialog->c[0]->align(FL_ALIGN_RIGHT);
dialog->b = new Fl_Check_Button
(WB, y, 2 * BBB + WB, BH, "Save all elements");
y += BH;
dialog->b->type(FL_TOGGLE_BUTTON);
dialog->c[1] = new Fl_Choice(WB, y, BBB + BBB / 4, BH, "Solid");
y += BH;
dialog->c[1]->menu(solidmenu);
dialog->c[1]->align(FL_ALIGN_RIGHT);
dialog->ok = new Fl_Return_Button(WB, y + WB, BBB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BBB, y + WB, BBB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->c[0]->value(CTX::instance()->mesh.binary ? 1 : 0);
dialog->b->value(CTX::instance()->mesh.saveAll ? 1 : 0);
dialog->c[1]->value(CTX::instance()->mesh.stlOneSolidPerSurface == 2 ? 2 :
CTX::instance()->mesh.stlOneSolidPerSurface == 1 ? 1 :0);
if(dialog->c[1]->value() == 2)
dialog->b->deactivate();
else
dialog->b->activate();
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->c[1]) {
if(dialog->c[1]->value() == 2)
dialog->b->deactivate();
else
dialog->b->activate();
}
if(o == dialog->ok) {
opt_mesh_binary(0, GMSH_SET | GMSH_GUI, dialog->c[0]->value());
opt_mesh_save_all(0, GMSH_SET | GMSH_GUI, dialog->b->value() ? 1 : 0);
opt_mesh_stl_one_solid_per_surface(0, GMSH_SET | GMSH_GUI,
dialog->c[1]->value());
CreateOutputFile(name, FORMAT_STL);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// Generic mesh dialog
int genericMeshFileDialog(const char *name, const char *title, int format,
bool binary_support, bool element_tag_support)
{
struct _genericMeshFileDialog {
Fl_Window *window;
Fl_Choice *c, *d;
Fl_Check_Button *b;
Fl_Button *ok, *cancel;
};
static _genericMeshFileDialog *dialog = NULL;
static Fl_Menu_Item formatmenu[] = {
{"ASCII", 0, 0, 0}, {"Binary", 0, 0, 0}, {0}};
static Fl_Menu_Item tagmenu[] = {{"Elementary entity", 0, 0, 0},
{"Physical entity", 0, 0, 0},
{"Partition", 0, 0, 0},
{0}};
int BBB = BB + 16; // labels too long
if(!dialog) {
dialog = new _genericMeshFileDialog;
int h = 3 * WB + 4 * BH, w = 2 * BBB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h);
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->c = new Fl_Choice(WB, y, BBB + BBB / 4, BH, "Format");
y += BH;
dialog->c->menu(formatmenu);
dialog->c->align(FL_ALIGN_RIGHT);
dialog->d = new Fl_Choice(WB, y, BBB + BBB / 4, BH, "Element tag");
y += BH;
dialog->d->menu(tagmenu);
dialog->d->align(FL_ALIGN_RIGHT);
dialog->b =
new Fl_Check_Button(WB, y, 2 * BBB + WB, BH, "Save all elements");
y += BH;
dialog->b->type(FL_TOGGLE_BUTTON);
dialog->ok = new Fl_Return_Button(WB, y + WB, BBB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BBB, y + WB, BBB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->window->label(title);
dialog->c->value(CTX::instance()->mesh.binary ? 1 : 0);
if(binary_support)
dialog->c->activate();
else
dialog->c->deactivate();
dialog->d->value((CTX::instance()->mesh.saveElementTagType == 3) ?
2 :
(CTX::instance()->mesh.saveElementTagType == 2) ? 1 : 0);
if(element_tag_support)
dialog->d->activate();
else
dialog->d->deactivate();
dialog->b->value(CTX::instance()->mesh.saveAll ? 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_binary(0, GMSH_SET | GMSH_GUI, dialog->c->value());
opt_mesh_save_element_tag_type(0, GMSH_SET | GMSH_GUI,
dialog->d->value() + 1);
opt_mesh_save_all(0, GMSH_SET | GMSH_GUI, dialog->b->value() ? 1 : 0);
CreateOutputFile(name, format);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
// POS format post-processing export dialog
static void _saveViews(const std::string &name, int which, int format,
bool canAppend)
{
if(PView::list.empty()) { Msg::Error("No views to save"); }
else if(which == 0) {
int iview = FlGui::instance()->options->view.index;
if(iview < 0 || iview >= (int)PView::list.size()) {
Msg::Info("No or invalid current view: saving View[0]");
iview = 0;
}
PView::list[iview]->write(name, format);
}
else if(which == 1) {
int numVisible = 0;
for(std::size_t i = 0; i < PView::list.size(); i++)
if(PView::list[i]->getOptions()->visible) numVisible++;
if(!numVisible) { Msg::Error("No visible view"); }
else {
bool first = true;
for(std::size_t i = 0; i < PView::list.size(); i++) {
if(PView::list[i]->getOptions()->visible) {
std::string fileName = name;
if(!canAppend && numVisible > 1) {
std::ostringstream os;
os << "_" << i;
fileName += os.str();
}
PView::list[i]->write(fileName, format, first ? false : canAppend);
first = false;
}
}
}
}
else {
for(std::size_t i = 0; i < PView::list.size(); i++) {
std::string fileName = name;
if(!canAppend && PView::list.size() > 1) {
std::ostringstream os;
os << "_" << i;
fileName += os.str();
}
PView::list[i]->write(fileName, format, i ? canAppend : false);
}
}
}
int posFileDialog(const char *name)
{
struct _posFileDialog {
Fl_Window *window;
Fl_Choice *c[2];
Fl_Button *ok, *cancel;
};
static _posFileDialog *dialog = NULL;
static Fl_Menu_Item viewmenu[] = {
{"Current", 0, 0, 0}, {"Visible", 0, 0, 0}, {"All", 0, 0, 0}, {0}};
static Fl_Menu_Item formatmenu[] = {{"Parsed", 0, 0, 0},
{"Mesh-based", 0, 0, 0},
{"Legacy ASCII", 0, 0, 0},
{"Legacy Binary", 0, 0, 0},
{0}};
int BBB = BB + 9; // labels too long
if(!dialog) {
dialog = new _posFileDialog;
int h = 3 * WB + 3 * BH, w = 2 * BBB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, "POS Options");
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->c[0] = new Fl_Choice(WB, y, BBB + BBB / 2, BH, "View(s)");
y += BH;
dialog->c[0]->menu(viewmenu);
dialog->c[0]->align(FL_ALIGN_RIGHT);
dialog->c[1] = new Fl_Choice(WB, y, BBB + BBB / 2, BH, "Format");
y += BH;
dialog->c[1]->menu(formatmenu);
dialog->c[1]->align(FL_ALIGN_RIGHT);
dialog->ok = new Fl_Return_Button(WB, y + WB, BBB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BBB, y + WB, BBB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->ok) {
int format = 2;
switch(dialog->c[1]->value()) {
case 0: format = 2; break;
case 1: format = 5; break;
case 2: format = 0; break;
case 3: format = 1; break;
}
bool canAppend = (format == 2) ? true : false;
_saveViews(name, dialog->c[0]->value(), format, canAppend);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
static void _saveAdaptedViews(const std::string &name, int useDefaultName,
int which, bool isBinary, int adaptLev,
double adaptErr, int npart, bool canAppend)
{
if(PView::list.empty()) { Msg::Error("No views to save"); }
else if(which == 0) {
int iview = FlGui::instance()->options->view.index;
if(iview < 0 || iview >= (int)PView::list.size()) {
Msg::Info("No or invalid current view: saving View[0]");
iview = 0;
}
PView::list[iview]->writeAdapt(name, useDefaultName, isBinary, adaptLev,
adaptErr, npart);
}
else if(which == 1) {
int numVisible = 0;
for(std::size_t i = 0; i < PView::list.size(); i++)
if(PView::list[i]->getOptions()->visible) numVisible++;
if(!numVisible) { Msg::Error("No visible view"); }
else {
bool first = true;
for(std::size_t i = 0; i < PView::list.size(); i++) {
if(PView::list[i]->getOptions()->visible) {
std::string fileName = name;
if(!canAppend && numVisible > 1) {
std::ostringstream os;
os << "_" << i;
fileName += os.str();
}
PView::list[i]->writeAdapt(fileName, useDefaultName, isBinary,
adaptLev, adaptErr, npart,
first ? false : canAppend);
first = false;
}
}
}
}
else {
for(std::size_t i = 0; i < PView::list.size(); i++) {
std::string fileName = name;
if(!canAppend && PView::list.size() > 1) {
std::ostringstream os;
os << "_" << i;
fileName += os.str();
}
PView::list[i]->writeAdapt(fileName, useDefaultName, isBinary, adaptLev,
adaptErr, npart, i ? canAppend : false);
}
}
}
int pvtuAdaptFileDialog(const char *name)
{
struct _pvtuAdaptFileDialog {
Fl_Window *window;
Fl_Choice *c[2];
Fl_Button *ok, *cancel, *push[2];
Fl_Value_Input *vi[3];
Fl_Check_Button *defautName;
};
static _pvtuAdaptFileDialog *dialog = NULL;
static Fl_Menu_Item viewmenu[] = {
{"Current", 0, 0, 0}, {"Visible", 0, 0, 0}, {"All", 0, 0, 0}, {0}};
static Fl_Menu_Item formatmenu[] = {
{"Binary", 0, 0, 0}, {"ASCII", 0, 0, 0}, {0}};
int BBB = BB + 9; // labels too long
if(!dialog) {
dialog = new _pvtuAdaptFileDialog;
int h = 7 * BH + 3 * WB, w = 2 * BBB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h, "Adaptive View Options");
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->c[0] = new Fl_Choice(WB, y, BB, BH, "View(s)");
y += BH;
dialog->c[0]->menu(viewmenu);
dialog->c[0]->align(FL_ALIGN_RIGHT);
dialog->c[1] = new Fl_Choice(WB, y, BB, BH, "Format");
y += BH;
dialog->c[1]->menu(formatmenu);
dialog->c[1]->align(FL_ALIGN_RIGHT);
dialog->vi[0] = new Fl_Value_Input(WB, y, BB, BH, "Recursion level");
y += BH;
dialog->vi[0]->align(FL_ALIGN_RIGHT);
dialog->vi[0]->minimum(0);
dialog->vi[0]->maximum(6);
dialog->vi[0]->step(1);
dialog->vi[0]->value(1);
dialog->vi[0]->when(FL_WHEN_RELEASE);
dialog->vi[1] = new Fl_Value_Input(WB, y, BB, BH, "Target error");
y += BH;
dialog->vi[1]->align(FL_ALIGN_RIGHT);
dialog->vi[1]->minimum(-1.e-4);
dialog->vi[1]->maximum(0.1);
dialog->vi[1]->step(1.e-4);
dialog->vi[1]->value(-1.e-4);
dialog->vi[1]->when(FL_WHEN_RELEASE);
dialog->vi[2] = new Fl_Value_Input(WB, y, BB, BH, "Number of parts");
y += BH;
dialog->vi[2]->align(FL_ALIGN_RIGHT);
dialog->vi[2]->minimum(1);
dialog->vi[2]->maximum(262144);
dialog->vi[2]->step(1);
dialog->vi[2]->value(4);
dialog->vi[2]->when(FL_WHEN_RELEASE);
dialog->defautName =
new Fl_Check_Button(WB, y, w - 2 * WB, BH, "Use default filename");
y += BH;
dialog->defautName->value(1);
dialog->ok = new Fl_Return_Button(WB, y + WB, BBB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BBB, y + WB, BBB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->ok) {
bool isBinary = true;
switch(dialog->c[1]->value()) {
case 0: isBinary = true; break;
case 1: isBinary = false; break;
}
// Only one view can currently be saved at a time in a pvtu file set,
// with a repetition of the topology structure. Views/Fields can then
// be appended in ParaView using the AppendAttributes filter bool
// canAppend = (format == 2) ? true : false;
int adaptLev = dialog->vi[0]->value();
double adaptErr = dialog->vi[1]->value();
int npart = dialog->vi[2]->value();
int useDefaultName = dialog->defautName->value();
bool canAppend =
false; // Not yet implemented for VTK format here due to a tradeoff
// to limit memory consumption for high levels of adaptation
_saveAdaptedViews(name, useDefaultName, dialog->c[0]->value(), isBinary,
adaptLev, adaptErr, npart, canAppend);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
int x3dViewFileDialog(const char *name, const char *title, int format)
{
struct _viewFileDialog {
Fl_Window *window;
Fl_Choice *c;
Fl_Value_Input *input[2];
Fl_Check_Button *e[2];
Fl_Button *ok, *cancel;
};
static _viewFileDialog *dialog = NULL;
static Fl_Menu_Item viewmenu[] = {
{"Current", 0, 0, 0}, {"Visible", 0, 0, 0}, {"All", 0, 0, 0}, {0}};
int BBB = BB + 9; // labels too long
if(!dialog) {
dialog = new _viewFileDialog;
int h = 6 * BH + 3 * WB, w = 2 * BBB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h);
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->c = new Fl_Choice(WB, y, BBB + BBB / 2, BH, "View(s)");
y += BH;
dialog->c->menu(viewmenu);
dialog->c->align(FL_ALIGN_RIGHT);
dialog->e[0] =
new Fl_Check_Button(WB, y, w - 2 * WB, BH, "Remove inner borders");
y += BH;
dialog->e[0]->type(FL_TOGGLE_BUTTON);
dialog->input[0] = new Fl_Value_Input(WB, y, BB, BH, "Log10(Precision)");
y += BH;
dialog->input[0]->align(FL_ALIGN_RIGHT);
dialog->input[0]->minimum(-16);
dialog->input[0]->maximum(16);
dialog->input[0]->step(.25);
dialog->input[1] = new Fl_Value_Input(WB, y, BB, BH, "Transparency");
y += BH;
dialog->input[1]->align(FL_ALIGN_RIGHT);
dialog->input[1]->minimum(0.);
dialog->input[1]->maximum(1.);
dialog->input[1]->step(0.05);
dialog->e[1] = new Fl_Check_Button(WB, y, w - 2 * WB, BH,
"High compatibility (no scale)");
y += BH;
dialog->e[1]->type(FL_TOGGLE_BUTTON);
dialog->ok = new Fl_Return_Button(WB, y + WB, BBB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BBB, y + WB, BBB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->window->label(title);
dialog->window->show();
dialog->input[0]->value(log10(opt_print_x3d_precision(0, GMSH_GET, 0)));
dialog->input[1]->value(opt_print_x3d_transparency(0, GMSH_GET, 0));
dialog->e[0]->value(opt_print_x3d_remove_inner_borders(0, GMSH_GET, 0));
dialog->e[1]->value(opt_print_x3d_compatibility(0, GMSH_GET, 0));
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->ok) {
opt_print_x3d_precision(0, GMSH_SET | GMSH_GUI,
pow(10., dialog->input[0]->value()));
opt_print_x3d_transparency(0, GMSH_SET | GMSH_GUI,
dialog->input[1]->value());
opt_print_x3d_remove_inner_borders(0, GMSH_SET | GMSH_GUI,
dialog->e[0]->value());
opt_print_x3d_compatibility(0, GMSH_SET | GMSH_GUI,
dialog->e[1]->value());
_saveViews(name, dialog->c->value(), format, false);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
int genericViewFileDialog(const char *name, const char *title, int format)
{
struct _viewFileDialog {
Fl_Window *window;
Fl_Choice *c[1];
Fl_Button *ok, *cancel;
};
static _viewFileDialog *dialog = NULL;
static Fl_Menu_Item viewmenu[] = {
{"Current", 0, 0, 0}, {"Visible", 0, 0, 0}, {"All", 0, 0, 0}, {0}};
int BBB = BB + 9; // labels too long
if(!dialog) {
dialog = new _viewFileDialog;
int h = 3 * WB + 2 * BH, w = 2 * BBB + 3 * WB, y = WB;
dialog->window = new Fl_Double_Window(w, h);
dialog->window->box(GMSH_WINDOW_BOX);
dialog->window->set_modal();
dialog->c[0] = new Fl_Choice(WB, y, BBB + BBB / 2, BH, "View(s)");
y += BH;
dialog->c[0]->menu(viewmenu);
dialog->c[0]->align(FL_ALIGN_RIGHT);
dialog->ok = new Fl_Return_Button(WB, y + WB, BBB, BH, "OK");
dialog->cancel = new Fl_Button(2 * WB + BBB, y + WB, BBB, BH, "Cancel");
dialog->window->end();
dialog->window->hotspot(dialog->window);
}
dialog->window->label(title);
dialog->window->show();
while(dialog->window->shown()) {
Fl::wait();
for(;;) {
Fl_Widget *o = Fl::readqueue();
if(!o) break;
if(o == dialog->ok) {
_saveViews(name, dialog->c[0]->value(), format, false);
dialog->window->hide();
return 1;
}
if(o == dialog->window || o == dialog->cancel) {
dialog->window->hide();
return 0;
}
}
}
return 0;
}
#if defined(HAVE_LIBCGNS)
// Forward declarations of some callbacks
void cgnsw_gc_location_cb(Fl_Widget *widget, void *data);
void cgnsw_write_dummy_bc_cb(Fl_Widget *widget, void *data);
void cgnsw_write_structured_mesh_cb(Fl_Widget *widget, void *data);
void cgnsw_bc_location_cb(Fl_Widget *widget, void *data);
void cgnsw_write_normals_cb(Fl_Widget *widget, void *data);
void cgnsw_normal_source_cb(Fl_Widget *widget, void *data);
// Pointers to required widgets
struct CGNSWriteDialog {
Fl_Window *window;
Fl_Choice *choiceZoneDef;
Fl_Input *inputBaseName;
Fl_Input *inputZoneName;
Fl_Input *inputInterfaceName;
Fl_Input *inputPatchName;
Fl_Round_Button *roundButton0GCatVertex;
Fl_Round_Button *roundButton1GCatFace;
Fl_Check_Button *checkButtonWriteBC;
Fl_Round_Button *roundButton0BCatVertex;
Fl_Round_Button *roundButton1BCatFace;
Fl_Check_Button *checkButtonWriteNormals;
Fl_Round_Button *roundButton0NormalGeo;
Fl_Round_Button *roundButton1NormalElem;
Fl_Check_Button *checkButtonWriteStructuredMesh;
Fl_Choice *choiceVecDim;
Fl_Check_Button *checkButtonUnknownUserDef;
const char *filename;
int status;
void write_all_options()
{
opt_mesh_zone_definition(0, GMSH_SET | GMSH_GUI, choiceZoneDef->value());
CTX::instance()->cgnsOptions.baseName = inputBaseName->value();
CTX::instance()->cgnsOptions.zoneName = inputZoneName->value();
CTX::instance()->cgnsOptions.interfaceName = inputInterfaceName->value();
CTX::instance()->cgnsOptions.patchName = inputPatchName->value();
CTX::instance()->cgnsOptions.gridConnectivityLocation =
roundButton1GCatFace->value();
CTX::instance()->cgnsOptions.writeBC = checkButtonWriteBC->value();
CTX::instance()->cgnsOptions.bocoLocation = roundButton1BCatFace->value();
CTX::instance()->cgnsOptions.normalSource =
(checkButtonWriteNormals->value()) ? roundButton1NormalElem->value() + 1 :
0;
CTX::instance()->cgnsOptions.vectorDim = choiceVecDim->value() + 2;
CTX::instance()->cgnsOptions.structuredMesh =
(checkButtonWriteStructuredMesh->value()) ? 1 : 0;
CTX::instance()->cgnsOptions.writeUserDef =
checkButtonUnknownUserDef->value();
}
void read_all_options()
{
choiceZoneDef->value(CTX::instance()->mesh.zoneDefinition);
inputBaseName->value(CTX::instance()->cgnsOptions.baseName.c_str());
inputZoneName->value(CTX::instance()->cgnsOptions.zoneName.c_str());
inputInterfaceName->value(
CTX::instance()->cgnsOptions.interfaceName.c_str());
inputPatchName->value(CTX::instance()->cgnsOptions.patchName.c_str());
checkButtonWriteBC->value(CTX::instance()->cgnsOptions.writeBC);
checkButtonWriteNormals->value(CTX::instance()->cgnsOptions.normalSource);
checkButtonWriteStructuredMesh->value(
CTX::instance()->cgnsOptions.structuredMesh);
choiceVecDim->value(CTX::instance()->cgnsOptions.vectorDim - 2);
checkButtonUnknownUserDef->value(CTX::instance()->cgnsOptions.writeUserDef);
// Call all callbacks to ensure consistent options
cgnsw_gc_location_cb(
(CTX::instance()->cgnsOptions.gridConnectivityLocation) ?
roundButton1GCatFace :
roundButton0GCatVertex,
this);
// The order of the next 4 is important
cgnsw_normal_source_cb((CTX::instance()->cgnsOptions.normalSource == 2) ?
roundButton1NormalElem :
roundButton0NormalGeo,
this);
cgnsw_write_normals_cb(checkButtonWriteNormals, this);
cgnsw_bc_location_cb((CTX::instance()->cgnsOptions.bocoLocation) ?
roundButton1BCatFace :
roundButton0BCatVertex,
this);
cgnsw_write_dummy_bc_cb(checkButtonWriteBC, this);
cgnsw_write_structured_mesh_cb(checkButtonWriteStructuredMesh, this);
}
};
void cgnsw_gc_location_cb(Fl_Widget *widget, void *data)
{
CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog *>(data);
if(widget == dlg->roundButton0GCatVertex) {
dlg->roundButton0GCatVertex->set();
dlg->roundButton1GCatFace->clear();
}
else {
dlg->roundButton0GCatVertex->clear();
dlg->roundButton1GCatFace->set();
}
}
void cgnsw_write_dummy_bc_cb(Fl_Widget *widget, void *data)
{
CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog *>(data);
if(dlg->checkButtonWriteBC->value()) {
dlg->roundButton0BCatVertex->activate();
// dlg->roundButton1BCatFace->activate(); //**Tmp
dlg->checkButtonWriteNormals->activate();
if(dlg->checkButtonWriteNormals->value()) {
if(dlg->roundButton0BCatVertex->value())
dlg->roundButton0NormalGeo->activate();
dlg->roundButton1NormalElem->activate();
}
}
else {
dlg->roundButton0BCatVertex->deactivate();
dlg->roundButton1BCatFace->deactivate();
dlg->checkButtonWriteNormals->deactivate();
dlg->roundButton0NormalGeo->deactivate();
dlg->roundButton1NormalElem->deactivate();
}
}
void cgnsw_write_structured_mesh_cb(Fl_Widget *widget, void *data)
{
CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog *>(data);
if(dlg->checkButtonWriteStructuredMesh->value()) {
dlg->checkButtonWriteBC->deactivate();
dlg->roundButton0BCatVertex->deactivate();
dlg->roundButton1BCatFace->deactivate();
dlg->checkButtonWriteNormals->deactivate();
dlg->roundButton0NormalGeo->deactivate();
dlg->roundButton1NormalElem->deactivate();
}
else {
if(dlg->checkButtonWriteBC->value()) {
dlg->checkButtonWriteBC->activate();
dlg->roundButton0BCatVertex->activate();
dlg->checkButtonWriteNormals->activate();
if(dlg->checkButtonWriteNormals->value()) {
if(dlg->roundButton0BCatVertex->value())
dlg->roundButton0NormalGeo->activate();
dlg->roundButton1NormalElem->activate();
}
}
}
}
void cgnsw_bc_location_cb(Fl_Widget *widget, void *data)
{
CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog *>(data);
if(widget == dlg->roundButton0BCatVertex) {
dlg->roundButton0BCatVertex->set();
dlg->roundButton1BCatFace->clear();
if(dlg->checkButtonWriteNormals->value())
dlg->roundButton0NormalGeo->activate();
}
else {
dlg->roundButton0BCatVertex->clear();
dlg->roundButton1BCatFace->set();
dlg->roundButton0NormalGeo->clear();
dlg->roundButton0NormalGeo->deactivate();
dlg->roundButton1NormalElem->set();
}
}
void cgnsw_write_normals_cb(Fl_Widget *widget, void *data)
{
CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog *>(data);
if(dlg->checkButtonWriteNormals->value()) {
if(dlg->roundButton0BCatVertex->value())
dlg->roundButton0NormalGeo->activate();
dlg->roundButton1NormalElem->activate();
}
else {
dlg->roundButton0NormalGeo->deactivate();
dlg->roundButton1NormalElem->deactivate();
}
}
void cgnsw_normal_source_cb(Fl_Widget *widget, void *data)
{
CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog *>(data);
if(widget == dlg->roundButton0NormalGeo) {
dlg->roundButton0NormalGeo->set();
dlg->roundButton1NormalElem->clear();
}
else {
dlg->roundButton0NormalGeo->clear();
dlg->roundButton1NormalElem->set();
}
}
void cgnsw_defaults_cb(Fl_Widget *widget, void *data)
{
CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog *>(data);
CTX::instance()->cgnsOptions.setDefaults();
dlg->read_all_options();
}
void cgnsw_write_cb(Fl_Widget *widget, void *data)
{
CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog *>(data);
// Write all options
dlg->write_all_options();
dlg->window->hide();
// Write the data
CreateOutputFile(dlg->filename, FORMAT_CGNS);
dlg->status = 1;
}
void cgnsw_cancel_cb(Fl_Widget *widget, void *data)
{
CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog *>(data);
dlg->window->hide();
dlg->status = 0;
}
int cgnsFileDialog(const char *filename)
{
static CGNSWriteDialog dlg;
dlg.filename = filename;
static Fl_Menu_Item zoneDefMenu[] = {{"Single zone", 0, 0, 0},
{"Partition", 0, 0, 0},
{"Physical", 0, 0, 0},
{0}};
static Fl_Menu_Item vectorDimMenu[] = {{"2", 0, 0, 0}, {"3", 0, 0, 0}, {0}};
const int RBH = 3 * FL_NORMAL_SIZE / 2; // radio button height
const int col1 = WB; // Start of left column
const int col2 = 2 * WB + 2 * BB; // Start of right column
const int hcol1 = 5 * WB + 2 * RBH + 4 * BH;
// Height of left column
const int hcol2 = 4 * WB + 4 * RBH + 2 * BH;
// Height of right column
const int h = 4 + 8 * WB + 5 * BH + std::max(hcol1, hcol2);
// Window height
const int w = 3 * WB + 4 * BB; // Window width
int y = WB;
dlg.window = new Fl_Double_Window(w, h, "CGNS Options");
dlg.window->box(GMSH_WINDOW_BOX);
dlg.window->set_modal();
dlg.window->callback((Fl_Callback *)cgnsw_cancel_cb, &dlg);
// Zone definition
dlg.choiceZoneDef = new Fl_Choice(col1, y, IW, BH, "Zone definition");
dlg.choiceZoneDef->menu(zoneDefMenu);
dlg.choiceZoneDef->align(FL_ALIGN_RIGHT);
y += BH + WB;
// Box (line) [0]
{
Fl_Box *const o = new Fl_Box(WB, y, w - 2 * WB, 2);
o->box(FL_ENGRAVED_FRAME);
o->labeltype(FL_NO_LABEL);
}
y += 2 + WB;
// Base name
dlg.inputBaseName = new Fl_Input(col1, y, BB, BH, "Base name");
dlg.inputBaseName->align(FL_ALIGN_RIGHT);
// Zone name
dlg.inputZoneName = new Fl_Input(col2, y, BB, BH, "Zone name");
dlg.inputZoneName->align(FL_ALIGN_RIGHT);
y += BH + WB;
// Interface name
dlg.inputInterfaceName = new Fl_Input(col1, y, BB, BH, "Interface name");
dlg.inputInterfaceName->align(FL_ALIGN_RIGHT);
// BC Patch name
dlg.inputPatchName = new Fl_Input(col2, y, BB, BH, "BC patch name");
dlg.inputPatchName->align(FL_ALIGN_RIGHT);
y += BH + WB;
//--Left column
int yl = y;
{
Fl_Box *const o = new Fl_Box(col1, yl, 0, BH, "Grid connectivity location");
o->align(FL_ALIGN_RIGHT);
yl += BH;
}
{
Fl_Box *const o = new Fl_Box(col1, yl, 2 * BB, 2 * WB + 2 * RBH);
o->box(FL_ENGRAVED_FRAME);
o->labeltype(FL_NO_LABEL);
yl += WB;
}
// Grid connectivity location
{
const int GH = 2 * RBH + 2 * WB;
Fl_Group *g = new Fl_Group(col1, yl, 2 * BB, GH);
dlg.roundButton0GCatVertex =
new Fl_Round_Button(col1 + WB, yl, RBH, RBH, "Vertex");
dlg.roundButton0GCatVertex->callback((Fl_Callback *)cgnsw_gc_location_cb,
&dlg);
dlg.roundButton0GCatVertex->align(FL_ALIGN_RIGHT);
yl += RBH;
dlg.roundButton1GCatFace =
new Fl_Round_Button(col1 + WB, yl, RBH, RBH, "Face");
dlg.roundButton1GCatFace->callback((Fl_Callback *)cgnsw_gc_location_cb,
&dlg);
dlg.roundButton1GCatFace->align(FL_ALIGN_RIGHT);
dlg.roundButton1GCatFace->deactivate(); //**Tmp
yl += RBH + 2 * WB;
g->end();
g->show();
}
// 2D Vector Dim
yl += WB;
dlg.choiceVecDim = new Fl_Choice(WB, yl, BB / 2, BH, "Vector Dimension");
dlg.choiceVecDim->menu(vectorDimMenu);
dlg.choiceVecDim->align(FL_ALIGN_RIGHT);
yl += BH;
{
Fl_Box *const o =
new Fl_Box(col1, yl, 0, BH, "(only affects 2-D mesh output)");
o->align(FL_ALIGN_RIGHT);
yl += BH + WB;
}
//--Right column
int yr = y;
// Write exterior BC
dlg.checkButtonWriteBC =
new Fl_Check_Button(col2, yr, RBH, BH, "Write dummy BC");
dlg.checkButtonWriteBC->callback((Fl_Callback *)cgnsw_write_dummy_bc_cb,
&dlg);
dlg.checkButtonWriteBC->align(FL_ALIGN_RIGHT);
yr += BH;
{
Fl_Box *const o = new Fl_Box(col2, yr, 2 * BB, BH + 4 * RBH + 3 * WB);
o->box(FL_ENGRAVED_FRAME);
o->labeltype(FL_NO_LABEL);
yr += WB;
}
// BC location
{
const int GH = 2 * RBH + WB;
Fl_Group *g = new Fl_Group(col2, yr, 2 * BB, GH);
dlg.roundButton0BCatVertex =
new Fl_Round_Button(col2 + WB, yr, RBH, RBH, "Vertex");
dlg.roundButton0BCatVertex->callback((Fl_Callback *)cgnsw_bc_location_cb,
&dlg);
dlg.roundButton0BCatVertex->align(FL_ALIGN_RIGHT);
yr += RBH;
dlg.roundButton1BCatFace =
new Fl_Round_Button(col2 + WB, yr, RBH, RBH, "Face");
dlg.roundButton1BCatFace->callback((Fl_Callback *)cgnsw_bc_location_cb,
&dlg);
dlg.roundButton1BCatFace->align(FL_ALIGN_RIGHT);
dlg.roundButton1BCatFace->deactivate(); //**Tmp
yr += RBH + WB;
g->end();
g->show();
}
// Write normals
dlg.checkButtonWriteNormals =
new Fl_Check_Button(col2 + WB, yr, RBH, BH, "Write normals");
dlg.checkButtonWriteNormals->callback((Fl_Callback *)cgnsw_write_normals_cb,
&dlg);
dlg.checkButtonWriteNormals->align(FL_ALIGN_RIGHT);
yr += BH;
// Normal source
{
const int GH = 2 * RBH + WB;
Fl_Group *g = new Fl_Group(col2, yr, 2 * BB, GH);
dlg.roundButton0NormalGeo =
new Fl_Round_Button(col2 + 2 * WB, yr, RBH, RBH, "From geometry");
dlg.roundButton0NormalGeo->callback((Fl_Callback *)cgnsw_normal_source_cb,
&dlg);
dlg.roundButton0NormalGeo->align(FL_ALIGN_RIGHT);
yr += RBH;
dlg.roundButton1NormalElem =
new Fl_Round_Button(col2 + 2 * WB, yr, RBH, RBH, "From elements");
dlg.roundButton1NormalElem->callback((Fl_Callback *)cgnsw_normal_source_cb,
&dlg);
dlg.roundButton1NormalElem->align(FL_ALIGN_RIGHT);
yr += RBH + 2 * WB;
g->end();
g->show();
}
// Structured or U-Structured Mesh option
dlg.checkButtonWriteStructuredMesh =
new Fl_Check_Button(col1, yl, RBH, BH, "Write Structured Mesh");
dlg.checkButtonWriteStructuredMesh->callback(
(Fl_Callback *)cgnsw_write_structured_mesh_cb, &dlg);
dlg.checkButtonWriteStructuredMesh->align(FL_ALIGN_RIGHT);
yl += BH;
y = std::max(yl, yr);
// User defined
dlg.checkButtonUnknownUserDef = new Fl_Check_Button(
col1, y, RBH, BH, "Write user-defined elements for unsupported types");
dlg.checkButtonUnknownUserDef->align(FL_ALIGN_RIGHT);
dlg.checkButtonUnknownUserDef->deactivate(); //**Tmp
y += BH + WB;
// Dialog termination group
{
const int GH = 2 + BH + 2 * WB;
Fl_Group *g = new Fl_Group(0, y, w, GH);
// Box (line) [0]
{
Fl_Box *const o = new Fl_Box(WB, y, w - 2 * WB, 2);
o->box(FL_ENGRAVED_FRAME);
o->labeltype(FL_NO_LABEL);
}
y += 2 + WB;
// Defaults Button [1]
{
Fl_Button *const o = new Fl_Button(WB, y, BB, BH, "Defaults");
o->callback((Fl_Callback *)cgnsw_defaults_cb, &dlg);
}
// Write Button [2]
{
Fl_Return_Button *const o =
new Fl_Return_Button(w - 2 * (WB + BB), y, BB, BH, "Write");
o->callback((Fl_Callback *)cgnsw_write_cb, &dlg);
}
// Cancel Button [3]
{
Fl_Button *const o = new Fl_Button(w - (WB + BB), y, BB, BH, "Cancel");
o->callback((Fl_Callback *)cgnsw_cancel_cb, &dlg);
}
y += BH + WB;
g->end();
g->show();
}
dlg.window->end();
dlg.window->hotspot(dlg.window);
dlg.read_all_options();
dlg.window->show();
// Wait here for status
while(dlg.window->shown()) Fl::wait();
delete dlg.window;
return dlg.status;
}
#else
int cgnsFileDialog(const char *filename)
{
CreateOutputFile(filename, FORMAT_CGNS);
return 1;
}
#endif // compiling CGNS write dialog