Select Git revision
Eigenvectors.h
-
Christophe Geuzaine authored
upgraded all plugins to work with the new post-pro. This is done "cheaply" for now, by only using old-style list-based datasets. Taking advantage of the abstraction (so that we can use the plugins on all datasets) will require more work. The hooks for transparent data translation are in place, but the actual translation has not been implemented yet.
Christophe Geuzaine authoredupgraded all plugins to work with the new post-pro. This is done "cheaply" for now, by only using old-style list-based datasets. Taking advantage of the abstraction (so that we can use the plugins on all datasets) will require more work. The hooks for transparent data translation are in place, but the actual translation has not been implemented yet.
Callbacks.cpp 133.15 KiB
// $Id: Callbacks.cpp,v 1.508 2007-01-25 08:56:13 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>.
#include <signal.h>
#include <time.h>
#include <map>
#include "Gmsh.h"
#include "GmshUI.h"
#include "Geo.h"
#include "GeoStringInterface.h"
#include "GeoExtractContour.h"
#include "Generator.h"
#include "SecondOrder.h"
#include "Draw.h"
#include "SelectBuffer.h"
#include "Views.h"
#include "CreateFile.h"
#include "OpenFile.h"
#include "CommandLine.h"
#include "Context.h"
#include "Options.h"
#include "GUI.h"
#include "GUI_Extras.h"
#include "Callbacks.h"
#include "Plugin.h"
#include "PluginManager.h"
#include "Visibility.h"
#include "Numeric.h"
#include "Solvers.h"
#include "OS.h"
#include "GModel.h"
extern Context_T CTX;
extern GUI *WID;
extern GModel *GMODEL;
// Helper routines
void UpdateViewsInGUI()
{
if(WID) {
WID->check_anim_buttons();
if(WID->get_context() == 3)
WID->set_context(menu_post, 0);
WID->reset_option_browser();
WID->reset_clip_browser();
WID->reset_external_view_list();
}
}
int SetGlobalShortcut(int event)
{
return WID->global_shortcuts(event);
}
int SelectContour(int type, int num, List_T * List)
{
int k = 0, ip;
switch (type) {
case ENT_LINE:
k = allEdgesLinked(num, List);
for(int i = 0; i < List_Nbr(List); i++) {
List_Read(List, i, &ip);
HighlightEntityNum(0, abs(ip), 0, 0);
}
break;
case ENT_SURFACE:
k = allFacesLinked(num, List);
for(int i = 0; i < List_Nbr(List); i++) {
List_Read(List, i, &ip);
HighlightEntityNum(0, 0, abs(ip), 0);
}
break;
}
Draw();
return k;
}
// Common callbacks
void cancel_cb(CALLBACK_ARGS)
{
if(data)
((Fl_Window *) data)->hide();
}
void color_cb(CALLBACK_ARGS)
{
unsigned int (*fct) (int, int, unsigned int);
fct = (unsigned int (*)(int, int, unsigned int))data;
uchar r = CTX.UNPACK_RED(fct(0, GMSH_GET, 0));
uchar g = CTX.UNPACK_GREEN(fct(0, GMSH_GET, 0));
uchar b = CTX.UNPACK_BLUE(fct(0, GMSH_GET, 0));
if(fl_color_chooser("Color Chooser", r, g, b))
fct(0, GMSH_SET | GMSH_GUI, CTX.PACK_COLOR(r, g, b, 255));
Draw();
}
void view_color_cb(CALLBACK_ARGS)
{
unsigned int (*fct) (int, int, unsigned int);
fct = (unsigned int (*)(int, int, unsigned int))data;
uchar r = CTX.UNPACK_RED(fct(WID->view_number, GMSH_GET, 0));
uchar g = CTX.UNPACK_GREEN(fct(WID->view_number, GMSH_GET, 0));
uchar b = CTX.UNPACK_BLUE(fct(WID->view_number, GMSH_GET, 0));
if(fl_color_chooser("Color Chooser", r, g, b))
fct(WID->view_number, GMSH_SET | GMSH_GUI, CTX.PACK_COLOR(r, g, b, 255));
Draw();
}
void redraw_cb(CALLBACK_ARGS)
{
Draw();
}
void window_cb(CALLBACK_ARGS)
{
static int oldx = 0, oldy = 0, oldw = 0, oldh = 0, zoom = 1;
char *str = (char*)data;
if(!strcmp(str, "minimize")){
WID->g_window->iconize();
if(WID->opt_window->shown()) WID->opt_window->iconize();
if(WID->vis_window->shown()) WID->vis_window->iconize();
if(WID->clip_window->shown()) WID->clip_window->iconize();
if(WID->manip_window->shown()) WID->manip_window->iconize();
if(WID->stat_window->shown()) WID->stat_window->iconize();
if(WID->msg_window->shown()) WID->msg_window->iconize();
WID->m_window->iconize();
}
else if(!strcmp(str, "zoom")){
if(zoom){
oldx = WID->g_window->x();
oldy = WID->g_window->y();
oldw = WID->g_window->w();
oldh = WID->g_window->h();
WID->g_window->resize(Fl::x(), Fl::y(), Fl::w(), Fl::h());
zoom = 0;
}
else{
WID->g_window->resize(oldx, oldy, oldw, oldh);
zoom = 1;
}
WID->g_window->show();
WID->m_window->show();
}
else if(!strcmp(str, "front")){
// the order is important!
WID->g_window->show();
if(WID->opt_window->shown()) WID->opt_window->show();
if(WID->context_geometry_window->shown()) WID->context_geometry_window->show();
if(WID->context_mesh_window->shown()) WID->context_mesh_window->show();
for(int i = 0; i < MAXSOLVERS; i++) {
if(WID->solver[i].window->shown()) WID->solver[i].window->show();
}
if(WID->vis_window->shown()) WID->vis_window->show();
if(WID->clip_window->shown()) WID->clip_window->show();
if(WID->manip_window->shown()) WID->manip_window->show();
if(WID->stat_window->shown()) WID->stat_window->show();
if(WID->msg_window->shown()) WID->msg_window->show();
WID->m_window->show();
}
}
void activate_cb(CALLBACK_ARGS)
{
// this is a central callback to activate/deactivate parts of the
// GUI depending on the user's choices (or the option settings)
if(!data) return;
char *str = (char*)data;
if(!strcmp(str, "fast_redraw")){
if(WID->gen_butt[2]->value())
WID->opt_redraw->show();
else
WID->opt_redraw->hide();
}
else if(!strcmp(str, "rotation_center")){
if(WID->gen_butt[15]->value()) {
WID->gen_push_butt[0]->deactivate();
WID->gen_value[8]->deactivate();
WID->gen_value[9]->deactivate();
WID->gen_value[10]->deactivate();
}
else {
WID->gen_push_butt[0]->activate();
WID->gen_value[8]->activate();
WID->gen_value[9]->activate();
WID->gen_value[10]->activate();
}
}
else if(!strcmp(str, "general_axes")){
if(WID->gen_choice[4]->value()){
WID->gen_value[17]->activate();
WID->gen_value[18]->activate();
WID->gen_value[19]->activate();
WID->gen_input[3]->activate();
WID->gen_input[4]->activate();
WID->gen_input[5]->activate();
WID->gen_input[6]->activate();
WID->gen_input[7]->activate();
WID->gen_input[8]->activate();
}
else{
WID->gen_value[17]->deactivate();
WID->gen_value[18]->deactivate();
WID->gen_value[19]->deactivate();
WID->gen_input[3]->deactivate();
WID->gen_input[4]->deactivate();
WID->gen_input[5]->deactivate();
WID->gen_input[6]->deactivate();
WID->gen_input[7]->deactivate();
WID->gen_input[8]->deactivate();
}
}
else if(!strcmp(str, "general_axes_auto")){
if(WID->gen_butt[0]->value()){
WID->gen_value[20]->deactivate();
WID->gen_value[21]->deactivate();
WID->gen_value[22]->deactivate();
WID->gen_value[23]->deactivate();
WID->gen_value[24]->deactivate();
WID->gen_value[25]->deactivate();
}
else{
WID->gen_value[20]->activate();
WID->gen_value[21]->activate();
WID->gen_value[22]->activate();
WID->gen_value[23]->activate();
WID->gen_value[24]->activate();
WID->gen_value[25]->activate();
}
}
else if(!strcmp(str, "general_small_axes")){
if(WID->gen_butt[1]->value()){
WID->gen_value[26]->activate();
WID->gen_value[27]->activate();
}
else{
WID->gen_value[26]->deactivate();
WID->gen_value[27]->deactivate();
}
}
else if(!strcmp(str, "custom_range")){
if(WID->view_choice[7]->value() == 2){
WID->view_value[31]->activate();
WID->view_value[32]->activate();
WID->view_push_butt[1]->activate();
WID->view_push_butt[2]->activate();
}
else {
WID->view_value[31]->deactivate();
WID->view_value[32]->deactivate();
WID->view_push_butt[1]->deactivate();
WID->view_push_butt[2]->deactivate();
}
}
else if(!strcmp(str, "general_transform")){
if(WID->view_butt[6]->value()){
WID->view_choice[11]->activate();
WID->view_value[2]->activate();
WID->view_input[4]->activate();
WID->view_input[5]->activate();
WID->view_input[6]->activate();
}
else{
WID->view_choice[11]->deactivate();
WID->view_value[2]->deactivate();
WID->view_input[4]->deactivate();
WID->view_input[5]->deactivate();
WID->view_input[6]->deactivate();
}
}
else if(!strcmp(str, "mesh_cut_plane")){
if(WID->mesh_butt[16]->value()){
WID->mesh_cut_plane->activate();
}
else{
WID->mesh_cut_plane->deactivate();
}
}
else if(!strcmp(str, "mesh_light")){
if(WID->mesh_butt[17]->value()){
WID->mesh_butt[18]->activate();
WID->mesh_butt[19]->activate();
WID->mesh_butt[20]->activate();
WID->mesh_butt[0]->activate();
WID->mesh_value[18]->activate();
}
else{
WID->mesh_butt[18]->deactivate();
WID->mesh_butt[19]->deactivate();
WID->mesh_butt[20]->deactivate();
WID->mesh_butt[0]->deactivate();
WID->mesh_value[18]->deactivate();
}
}
else if(!strcmp(str, "view_light")){
if(WID->view_butt[11]->value()){
WID->view_butt[8]->activate();
WID->view_butt[9]->activate();
WID->view_butt[12]->activate();
WID->view_value[10]->activate();
}
else{
WID->view_butt[8]->deactivate();
WID->view_butt[9]->deactivate();
WID->view_butt[12]->deactivate();
WID->view_value[10]->deactivate();
}
}
else if(!strcmp(str, "view_axes")){
if(WID->view_choice[8]->value()){
WID->view_value[3]->activate();
WID->view_value[4]->activate();
WID->view_value[5]->activate();
WID->view_input[7]->activate();
WID->view_input[8]->activate();
WID->view_input[9]->activate();
WID->view_input[10]->activate();
WID->view_input[11]->activate();
WID->view_input[12]->activate();
}
else{
WID->view_value[3]->deactivate();
WID->view_value[4]->deactivate();
WID->view_value[5]->deactivate();
WID->view_input[7]->deactivate();
WID->view_input[8]->deactivate();
WID->view_input[9]->deactivate();
WID->view_input[10]->deactivate();
WID->view_input[11]->deactivate();
WID->view_input[12]->deactivate();
}
}
else if(!strcmp(str, "view_axes_auto_3d")){
if(WID->view_butt[25]->value()){
WID->view_value[13]->deactivate();
WID->view_value[14]->deactivate();
WID->view_value[15]->deactivate();
WID->view_value[16]->deactivate();
WID->view_value[17]->deactivate();
WID->view_value[18]->deactivate();
}
else{
WID->view_value[13]->activate();
WID->view_value[14]->activate();
WID->view_value[15]->activate();
WID->view_value[16]->activate();
WID->view_value[17]->activate();
WID->view_value[18]->activate();
}
}
else if(!strcmp(str, "view_axes_auto_2d")){
if(WID->view_butt[7]->value()){
WID->view_value[20]->deactivate();
WID->view_value[21]->deactivate();
WID->view_value[22]->deactivate();
WID->view_value[23]->deactivate();
}
else{
WID->view_value[20]->activate();
WID->view_value[21]->activate();
WID->view_value[22]->activate();
WID->view_value[23]->activate();
}
}
}
// Graphical window
void status_xyz1p_cb(CALLBACK_ARGS)
{
char *str = (char*)data;
if(!strcmp(str, "r")){ // rotate 90 degress around axis perp to the screen
double axis[3] = {0., 0., 1.};
if(!Fl::event_state(FL_SHIFT))
CTX.addQuaternionFromAxisAndAngle(axis, -90.);
else
CTX.addQuaternionFromAxisAndAngle(axis, 90.);
Draw();
}
else if(!strcmp(str, "x")){ // X pointing out or into the screen
if(!Fl::event_state(FL_SHIFT)){
CTX.r[0] = -90.;
CTX.r[1] = 0.;
CTX.r[2] = -90.;
}
else{
CTX.r[0] = -90.;
CTX.r[1] = 0.;
CTX.r[2] = 90.;
}
CTX.setQuaternionFromEulerAngles();
Draw();
}
else if(!strcmp(str, "y")){ // Y pointing out or into the screen
if(!Fl::event_state(FL_SHIFT)){
CTX.r[0] = -90.;
CTX.r[1] = 0.;
CTX.r[2] = 180.;
}
else{
CTX.r[0] = -90.;
CTX.r[1] = 0.;
CTX.r[2] = 0.;
}
CTX.setQuaternionFromEulerAngles();
Draw();
}
else if(!strcmp(str, "z")){ // Z pointing out or into the screen
if(!Fl::event_state(FL_SHIFT)){
CTX.r[0] = 0.;
CTX.r[1] = 0.;
CTX.r[2] = 0.;
}
else{
CTX.r[0] = 0.;
CTX.r[1] = 180.;
CTX.r[2] = 0.;
}
CTX.setQuaternionFromEulerAngles();
Draw();
}
else if(!strcmp(str, "1:1")){ // reset translation and scaling
CTX.t[0] = CTX.t[1] = CTX.t[2] = 0.;
CTX.s[0] = CTX.s[1] = CTX.s[2] = 1.;
Draw();
}
else if(!strcmp(str, "reset")){ // reset everything
CTX.t[0] = CTX.t[1] = CTX.t[2] = 0.;
CTX.s[0] = CTX.s[1] = CTX.s[2] = 1.;
CTX.r[0] = 0.;
CTX.r[1] = 0.;
CTX.r[2] = 0.;
CTX.setQuaternionFromEulerAngles();
Draw();
}
else if(!strcmp(str, "p")){ // toggle projection mode
if(!Fl::event_state(FL_SHIFT)){
opt_general_orthographic(0, GMSH_SET | GMSH_GUI,
!opt_general_orthographic(0, GMSH_GET, 0));
}
else{
perspective_editor();
}
Draw();
}
else if(!strcmp(str, "?")){ // display options
Print_Options(0, GMSH_FULLRC, 0, 1, NULL);
WID->create_message_window();
}
else if(!strcmp(str, "S")){ // mouse selection
if(Fl::event_state(FL_SHIFT)){
// mouse hover and select for geometry and mesh
opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 2);
}
else if(CTX.enable_mouse_selection){
// mouse does nothing
opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 0);
WID->g_opengl_window->cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
}
else{
// mouse hover and select for geometry, but mouse select only
// for mesh (default, for performance reasons)
opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 1);
}
}
WID->update_manip_window();
}
static int stop_anim, view_in_cycle = -1, busy = 0;
void ManualPlay(int time, int step)
{
// avoid firing ManualPlay recursively (can happen e.g when keeping
// the finger down on the arrow key: if the system generates too
// many events, we can overflow the stack--that happened on my
// powerbook with the new, optimzed FLTK event handler)
if(busy) return;
busy = 1;
if(time) {
for(int i = 0; i < List_Nbr(CTX.post.list); i++)
if(opt_view_visible(i, GMSH_GET, 0))
opt_view_timestep(i, GMSH_SET | GMSH_GUI,
opt_view_timestep(i, GMSH_GET, 0) + step);
}
else { // hide all views except view_in_cycle
if(step > 0) {
if((view_in_cycle += step) >= List_Nbr(CTX.post.list))
view_in_cycle = 0;
for(int i = 0; i < List_Nbr(CTX.post.list); i += step)
opt_view_visible(i, GMSH_SET | GMSH_GUI, (i == view_in_cycle));
}
else {
if((view_in_cycle += step) < 0)
view_in_cycle = List_Nbr(CTX.post.list) - 1;
for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i += step)
opt_view_visible(i, GMSH_SET | GMSH_GUI, (i == view_in_cycle));
}
}
Draw();
busy = 0;
}
void status_play_cb(CALLBACK_ARGS)
{
static double anim_time;
WID->set_anim_buttons(0);
stop_anim = 0;
anim_time = GetTimeInSeconds();
while(1) {
if(stop_anim)
break;
if(GetTimeInSeconds() - anim_time > CTX.post.anim_delay) {
anim_time = GetTimeInSeconds();
ManualPlay(!CTX.post.anim_cycle, 1);
}
WID->check();
}
}
void status_pause_cb(CALLBACK_ARGS)
{
stop_anim = 1;
WID->set_anim_buttons(1);
}
void status_rewind_cb(CALLBACK_ARGS)
{
int i;
if(!CTX.post.anim_cycle) {
for(i = 0; i < List_Nbr(CTX.post.list); i++)
opt_view_timestep(i, GMSH_SET | GMSH_GUI, 0);
}
else {
view_in_cycle = 0;
for(i = 0; i < List_Nbr(CTX.post.list); i++)
opt_view_visible(i, GMSH_SET | GMSH_GUI, !i);
}
Draw();
}
// File Menu
void file_new_cb(CALLBACK_ARGS)
{
test:
if(file_chooser(0, 1, "New", "*")) {
char *name = file_chooser_get_name(1);
if(!StatFile(name)){
if(fl_choice("File '%s' already exists.\n\nDo you want to erase it?",
"Cancel", "Erase", NULL, name))
UnlinkFile(name);
else
goto test;
}
FILE *fp = fopen(name, "w");
if(!fp){
Msg(GERROR, "Unable to open file '%s'", name);
return;
}
time_t now;
time(&now);
fprintf(fp, "// Gmsh project created on %s", ctime(&now));
fclose(fp);
OpenProject(name);
Draw();
}
}
void file_open_cb(CALLBACK_ARGS)
{
int n = List_Nbr(CTX.post.list);
if(file_chooser(0, 0, "Open", "*")) {
OpenProject(file_chooser_get_name(1));
Draw();
}
if(n != List_Nbr(CTX.post.list))
WID->set_context(menu_post, 0);
}
void file_merge_cb(CALLBACK_ARGS)
{
int n = List_Nbr(CTX.post.list);
int f = file_chooser(1, 0, "Merge", "*");
if(f) {
for(int i = 1; i <= f; i++)
MergeFile(file_chooser_get_name(i));
Draw();
}
if(n != List_Nbr(CTX.post.list))
WID->set_context(menu_post, 0);
}
int _save_msh(char *name){ return msh_dialog(name); }
int _save_pos(char *name){ return generic_mesh_dialog(name, "POS Options", FORMAT_POS); }
int _save_options(char *name){ return options_dialog(name); }
int _save_geo(char *name){ CreateOutputFile(name, FORMAT_GEO); return 1; }
int _save_unv(char *name){ return generic_mesh_dialog(name, "UNV Options", FORMAT_UNV); }
int _save_mesh(char *name){ return generic_mesh_dialog(name, "MESH Options", FORMAT_MESH); }
int _save_bdf(char *name){ return bdf_dialog(name); }
int _save_stl(char *name){ return stl_dialog(name); }
int _save_vrml(char *name){ return generic_mesh_dialog(name, "VRML Options", FORMAT_VRML); }
int _save_cgns(char *name){ CreateOutputFile(name, FORMAT_CGNS); return 1; }
int _save_eps(char *name){ return gl2ps_dialog(name, "EPS Options", FORMAT_EPS); }
int _save_gif(char *name){ return gif_dialog(name); }
int _save_jpeg(char *name){ return jpeg_dialog(name); }
int _save_tex(char *name){ CreateOutputFile(name, FORMAT_TEX); return 1; }
int _save_pdf(char *name){ return gl2ps_dialog(name, "PDF Options", FORMAT_PDF); }
int _save_png(char *name){ return generic_bitmap_dialog(name, "PNG Options", FORMAT_PNG); }
int _save_ps(char *name){ return gl2ps_dialog(name, "PS Options", FORMAT_PS); }
int _save_ppm(char *name){ return generic_bitmap_dialog(name, "PPM Options", FORMAT_PPM); }
int _save_svg(char *name){ return gl2ps_dialog(name, "SVG Options", FORMAT_SVG); }
int _save_yuv(char *name){ return generic_bitmap_dialog(name, "YUV Options", FORMAT_YUV); }
int _save_auto(char *name)
{
switch(GuessFileFormatFromFileName(name)){
case FORMAT_MSH : return _save_msh(name);
case FORMAT_POS : return _save_pos(name);
case FORMAT_OPT : return _save_options(name);
case FORMAT_GEO : return _save_geo(name);
case FORMAT_UNV : return _save_unv(name);
case FORMAT_MESH : return _save_mesh(name);
case FORMAT_BDF : return _save_bdf(name);
case FORMAT_STL : return _save_stl(name);
case FORMAT_VRML : return _save_vrml(name);
case FORMAT_CGNS : return _save_cgns(name);
case FORMAT_EPS : return _save_eps(name);
case FORMAT_GIF : return _save_gif(name);
case FORMAT_JPEG : return _save_jpeg(name);
case FORMAT_TEX : return _save_tex(name);
case FORMAT_PDF : return _save_pdf(name);
case FORMAT_PNG : return _save_png(name);
case FORMAT_PS : return _save_ps(name);
case FORMAT_PPM : return _save_ppm(name);
case FORMAT_SVG : return _save_svg(name);
case FORMAT_YUV : return _save_yuv(name);
default :
CreateOutputFile(name, FORMAT_AUTO);
return 1;
}
}
typedef struct{
char *pat;
int (*func) (char *name);
} patXfunc;
void file_save_as_cb(CALLBACK_ARGS)
{
int i, nbformats;
static char *pat = NULL;
static patXfunc formats[] = {
{"Guess from extension (*.*)", _save_auto},
{" ", _save_auto},
{"Gmsh mesh (*.msh)", _save_msh},
{"Gmsh mesh statistics (*.pos)", _save_pos},
{"Gmsh options (*.opt)", _save_options},
{"Gmsh unrolled geometry (*.geo)", _save_geo},
{" ", _save_auto},
{"I-deas universal mesh (*.unv)", _save_unv},
{"Medit mesh (*.mesh)", _save_mesh},
{"Nastran bulk data file (*.bdf)", _save_bdf},
{"STL surface mesh (*.stl)", _save_stl},
{"VRML surface mesh (*.wrl)", _save_vrml},
#if defined(HAVE_LIBCGNS)
{"CGNS (*.cgns)", _save_cgns},
#endif
{" ", _save_auto},
{"Encapsulated PostScript (*.eps)", _save_eps},
{"GIF (*.gif)", _save_gif},
#if defined(HAVE_LIBJPEG)
{"JPEG (*.jpg)", _save_jpeg},
#endif
{"LaTeX (*.tex)", _save_tex},
{"PDF (*.pdf)", _save_pdf},
#if defined(HAVE_LIBPNG)
{"PNG (*.png)", _save_png},
#endif
{"PostScript (*.ps)", _save_ps},
{"PPM (*.ppm)", _save_ppm},
{"SVG (*.svg)", _save_svg},
{"YUV (*.yuv)", _save_yuv},
{" ", _save_auto},
};
nbformats = sizeof(formats) / sizeof(formats[0]);
if(!pat) {
pat = (char *)Malloc(nbformats * 256 * sizeof(char));
strcpy(pat, formats[0].pat);
for(i = 1; i < nbformats; i++) {
strcat(pat, "\t");
strcat(pat, formats[i].pat);
}
}
test:
if(file_chooser(0, 1, "Save As", pat)) {
char *name = file_chooser_get_name(1);
if(CTX.confirm_overwrite) {
if(!StatFile(name))
if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
"Cancel", "Replace", NULL, name))
goto test;
}
i = file_chooser_get_filter();
if(i >= 0 && i < nbformats){
if(!formats[i].func(name))
goto test;
}
else // handle any additional automatic fltk filter
_save_auto(name);
}
}
void file_rename_cb(CALLBACK_ARGS)
{
test:
if(file_chooser(0, 1, "Rename", "*", CTX.filename)) {
char *name = file_chooser_get_name(1);
if(CTX.confirm_overwrite) {
if(!StatFile(name))
if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
"Cancel", "Replace", NULL, name))
goto test;
}
rename(CTX.filename, name);
OpenProject(name);
Draw();
}
}
void file_quit_cb(CALLBACK_ARGS)
{
Exit(0);
}
// Option Menu
void options_cb(CALLBACK_ARGS)
{
WID->create_option_window();
}
void options_browser_cb(CALLBACK_ARGS)
{
switch (WID->opt_browser->value()) {
case 0:
break;
case 1:
WID->create_general_options_window();
break;
case 2:
WID->create_geometry_options_window();
break;
case 3:
WID->create_mesh_options_window();
break;
case 4:
WID->create_solver_options_window();
break;
case 5:
WID->create_post_options_window();
break;
default:
WID->create_view_options_window(WID->opt_browser->value() - 6);
break;
}
}
void options_save_cb(CALLBACK_ARGS)
{
Msg(STATUS2, "Writing '%s'", CTX.options_filename_fullpath);
Print_Options(0, GMSH_OPTIONSRC, 1, 1, CTX.options_filename_fullpath);
Msg(STATUS2, "Wrote '%s'", CTX.options_filename_fullpath);
}
void options_restore_defaults_cb(CALLBACK_ARGS)
{
// not sure if we have to remove the file...
UnlinkFile(CTX.session_filename_fullpath);
UnlinkFile(CTX.options_filename_fullpath);
ReInit_Options(0);
Init_Options_GUI(0);
if(WID && WID->get_context() == 3) // hack to refresh the buttons
WID->set_context(menu_post, 0);
Draw();
}
// General options
void general_options_cb(CALLBACK_ARGS)
{
WID->create_general_options_window();
}
void general_options_color_scheme_cb(CALLBACK_ARGS)
{
opt_general_color_scheme(0, GMSH_SET, WID->gen_choice[3]->value());
Draw();
}
void general_options_rotation_center_select_cb(CALLBACK_ARGS)
{
std::vector<GVertex*> vertices;
std::vector<GEdge*> edges;
std::vector<GFace*> faces;
std::vector<GRegion*> regions;
std::vector<MElement*> elements;
Msg(ONSCREEN, "Select entity\n[Press 'q' to abort]");
char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements);
if(ib == 'l') {
SPoint3 pc(0., 0., 0.);
if(vertices.size())
pc.setPosition(vertices[0]->x(), vertices[0]->y(), vertices[0]->z());
else if(edges.size())
pc = edges[0]->bounds().center();
else if(faces.size())
pc = faces[0]->bounds().center();
else if(regions.size())
pc = regions[0]->bounds().center();
else if(elements.size())
pc = elements[0]->barycenter();
opt_general_rotation_center_cg(0, GMSH_SET, WID->gen_butt[15]->value());
opt_general_rotation_center0(0, GMSH_SET|GMSH_GUI, pc.x());
opt_general_rotation_center1(0, GMSH_SET|GMSH_GUI, pc.y());
opt_general_rotation_center2(0, GMSH_SET|GMSH_GUI, pc.z());
}
ZeroHighlight();
Draw();
Msg(ONSCREEN, "");
}
void general_options_ok_cb(CALLBACK_ARGS)
{
activate_cb(NULL, data);
static double lc = 0.;
if(lc != CTX.lc){
lc = CTX.lc;
for(int i = 2; i < 5; i++){
WID->gen_value[i]->minimum(-5*CTX.lc);
WID->gen_value[i]->maximum(5*CTX.lc);
}
}
if(data){
char *name = (char*)data;
if(!strcmp(name, "rotation_center_coord")){
CTX.draw_rotation_center = 1;
}
else if(!strcmp(name, "light_value")){
double x, y, z;
x = WID->gen_value[2]->value();
y = WID->gen_value[3]->value();
z = WID->gen_value[4]->value();
WID->gen_sphere->setValue(x, y, z);
}
else if(!strcmp(name, "light_sphere")){
double x, y, z;
WID->gen_sphere->getValue(x, y, z);
WID->gen_value[2]->value(x);
WID->gen_value[3]->value(y);
WID->gen_value[4]->value(z);
}
}
opt_general_axes_auto_position(0, GMSH_SET, WID->gen_butt[0]->value());
opt_general_small_axes(0, GMSH_SET, WID->gen_butt[1]->value());
opt_general_fast_redraw(0, GMSH_SET, WID->gen_butt[2]->value());
if(opt_general_double_buffer(0, GMSH_GET, 0) != WID->gen_butt[3]->value())
opt_general_double_buffer(0, GMSH_SET, WID->gen_butt[3]->value());
if(opt_general_antialiasing(0, GMSH_GET, 0) != WID->gen_butt[12]->value())
opt_general_antialiasing(0, GMSH_SET, WID->gen_butt[12]->value());
opt_general_trackball(0, GMSH_SET, WID->gen_butt[5]->value());
opt_general_terminal(0, GMSH_SET, WID->gen_butt[7]->value());
double sessionrc = opt_general_session_save(0, GMSH_GET, 0);
opt_general_session_save(0, GMSH_SET, WID->gen_butt[8]->value());
if(sessionrc && !opt_general_session_save(0, GMSH_GET, 0))
Print_Options(0, GMSH_SESSIONRC, 1, 1, CTX.session_filename_fullpath);
opt_general_options_save(0, GMSH_SET, WID->gen_butt[9]->value());
opt_general_expert_mode(0, GMSH_SET, WID->gen_butt[10]->value());
opt_general_tooltips(0, GMSH_SET, WID->gen_butt[13]->value());
opt_general_confirm_overwrite(0, GMSH_SET, WID->gen_butt[14]->value());
opt_general_rotation_center_cg(0, GMSH_SET, WID->gen_butt[15]->value());
opt_general_draw_bounding_box(0, GMSH_SET, WID->gen_butt[6]->value());
opt_general_polygon_offset_always(0, GMSH_SET, WID->gen_butt[4]->value());
opt_general_shine_exponent(0, GMSH_SET, WID->gen_value[0]->value());
opt_general_shine(0, GMSH_SET, WID->gen_value[1]->value());
opt_general_light00(0, GMSH_SET, WID->gen_value[2]->value());
opt_general_light01(0, GMSH_SET, WID->gen_value[3]->value());
opt_general_light02(0, GMSH_SET, WID->gen_value[4]->value());
opt_general_light03(0, GMSH_SET, WID->gen_value[13]->value());
opt_general_verbosity(0, GMSH_SET, WID->gen_value[5]->value());
opt_general_point_size(0, GMSH_SET, WID->gen_value[6]->value());
opt_general_line_width(0, GMSH_SET, WID->gen_value[7]->value());
opt_general_rotation_center0(0, GMSH_SET, WID->gen_value[8]->value());
opt_general_rotation_center1(0, GMSH_SET, WID->gen_value[9]->value());
opt_general_rotation_center2(0, GMSH_SET, WID->gen_value[10]->value());
opt_general_quadric_subdivisions(0, GMSH_SET, WID->gen_value[11]->value());
opt_general_graphics_fontsize(0, GMSH_SET, WID->gen_value[12]->value());
opt_general_clip_factor(0, GMSH_SET, WID->gen_value[14]->value());
opt_general_polygon_offset_factor(0, GMSH_SET, WID->gen_value[15]->value());
opt_general_polygon_offset_units(0, GMSH_SET, WID->gen_value[16]->value());
opt_general_axes_tics0(0, GMSH_SET, WID->gen_value[17]->value());
opt_general_axes_tics1(0, GMSH_SET, WID->gen_value[18]->value());
opt_general_axes_tics2(0, GMSH_SET, WID->gen_value[19]->value());
opt_general_axes_xmin(0, GMSH_SET, WID->gen_value[20]->value());
opt_general_axes_ymin(0, GMSH_SET, WID->gen_value[21]->value());
opt_general_axes_zmin(0, GMSH_SET, WID->gen_value[22]->value());
opt_general_axes_xmax(0, GMSH_SET, WID->gen_value[23]->value());
opt_general_axes_ymax(0, GMSH_SET, WID->gen_value[24]->value());
opt_general_axes_zmax(0, GMSH_SET, WID->gen_value[25]->value());
opt_general_small_axes_position0(0, GMSH_SET, WID->gen_value[26]->value());
opt_general_small_axes_position1(0, GMSH_SET, WID->gen_value[27]->value());
opt_general_default_filename(0, GMSH_SET, (char *)WID->gen_input[0]->value());
opt_general_editor(0, GMSH_SET, (char *)WID->gen_input[1]->value());
opt_general_web_browser(0, GMSH_SET, (char *)WID->gen_input[2]->value());
opt_general_axes_format0(0, GMSH_SET, (char *)WID->gen_input[3]->value());
opt_general_axes_format1(0, GMSH_SET, (char *)WID->gen_input[4]->value());
opt_general_axes_format2(0, GMSH_SET, (char *)WID->gen_input[5]->value());
opt_general_axes_label0(0, GMSH_SET, (char *)WID->gen_input[6]->value());
opt_general_axes_label1(0, GMSH_SET, (char *)WID->gen_input[7]->value());
opt_general_axes_label2(0, GMSH_SET, (char *)WID->gen_input[8]->value());
int val;
switch (WID->gen_choice[0]->value()) {
case 0: val = DRAW_POST_SEGMENT; break;
case 1: val = DRAW_POST_ARROW; break;
case 2: val = DRAW_POST_PYRAMID; break;
default: val = DRAW_POST_ARROW3D; break;
}
opt_general_vector_type(0, GMSH_SET, val);
opt_general_graphics_font(0, GMSH_SET, (char *)WID->gen_choice[1]->text());
opt_general_orthographic(0, GMSH_SET, !WID->gen_choice[2]->value());
opt_general_axes(0, GMSH_SET, WID->gen_choice[4]->value());
opt_general_background_gradient(0, GMSH_SET, WID->gen_choice[5]->value());
if(CTX.fast_redraw)
CTX.post.draw = CTX.mesh.draw = 0;
Draw();
CTX.post.draw = CTX.mesh.draw = 1;
CTX.draw_rotation_center = 0;
}
void general_arrow_param_cb(CALLBACK_ARGS)
{
double a = opt_general_arrow_head_radius(0, GMSH_GET, 0);
double b = opt_general_arrow_stem_length(0, GMSH_GET, 0);
double c = opt_general_arrow_stem_radius(0, GMSH_GET, 0);
while(arrow_editor("Arrow Editor", a, b, c)){
opt_general_arrow_head_radius(0, GMSH_SET, a);
opt_general_arrow_stem_length(0, GMSH_SET, b);
opt_general_arrow_stem_radius(0, GMSH_SET, c);
Draw();
}
}
// Geometry options
void geometry_options_cb(CALLBACK_ARGS)
{
WID->create_geometry_options_window();
}
void geometry_options_ok_cb(CALLBACK_ARGS)
{
activate_cb(NULL, data);
opt_geometry_points(0, GMSH_SET, WID->geo_butt[0]->value());
opt_geometry_lines(0, GMSH_SET, WID->geo_butt[1]->value());
opt_geometry_surfaces(0, GMSH_SET, WID->geo_butt[2]->value());
opt_geometry_volumes(0, GMSH_SET, WID->geo_butt[3]->value());
opt_geometry_points_num(0, GMSH_SET, WID->geo_butt[4]->value());
opt_geometry_lines_num(0, GMSH_SET, WID->geo_butt[5]->value());
opt_geometry_surfaces_num(0, GMSH_SET, WID->geo_butt[6]->value());
opt_geometry_volumes_num(0, GMSH_SET, WID->geo_butt[7]->value());
opt_geometry_auto_coherence(0, GMSH_SET, WID->geo_butt[8]->value());
opt_geometry_light(0, GMSH_SET, WID->geo_butt[9]->value());
opt_geometry_highlight_orphans(0, GMSH_SET, WID->geo_butt[10]->value());
opt_geometry_occ_fix_small_edges(0, GMSH_SET, WID->geo_butt[11]->value());
opt_geometry_occ_fix_small_faces(0, GMSH_SET, WID->geo_butt[12]->value());
opt_geometry_occ_sew_faces(0, GMSH_SET, WID->geo_butt[13]->value());
opt_geometry_normals(0, GMSH_SET, WID->geo_value[0]->value());
opt_geometry_tangents(0, GMSH_SET, WID->geo_value[1]->value());
opt_geometry_tolerance(0, GMSH_SET, WID->geo_value[2]->value());
opt_geometry_point_size(0, GMSH_SET, WID->geo_value[3]->value());
opt_geometry_line_width(0, GMSH_SET, WID->geo_value[4]->value());
opt_geometry_point_sel_size(0, GMSH_SET, WID->geo_value[5]->value());
opt_geometry_line_sel_width(0, GMSH_SET, WID->geo_value[6]->value());
opt_geometry_point_type(0, GMSH_SET, WID->geo_choice[0]->value());
opt_geometry_line_type(0, GMSH_SET, WID->geo_choice[1]->value());
if(CTX.fast_redraw)
CTX.post.draw = CTX.mesh.draw = 0;
Draw();
CTX.post.draw = CTX.mesh.draw = 1;
}
// Mesh options
void mesh_options_cb(CALLBACK_ARGS)
{
WID->create_mesh_options_window();
}
void mesh_options_ok_cb(CALLBACK_ARGS)
{
activate_cb(NULL, data);
if(data){
char *name = (char*)data;
if(!strcmp(name, "cut_plane_invert")){
WID->mesh_value[14]->value(-WID->mesh_value[14]->value());
WID->mesh_value[15]->value(-WID->mesh_value[15]->value());
WID->mesh_value[16]->value(-WID->mesh_value[16]->value());
WID->mesh_value[17]->value(-WID->mesh_value[17]->value());
}
}
opt_mesh_reverse_all_normals(0, GMSH_SET, WID->mesh_butt[0]->value());
opt_mesh_lc_from_curvature(0, GMSH_SET, WID->mesh_butt[1]->value());
opt_mesh_optimize(0, GMSH_SET, WID->mesh_butt[2]->value());
opt_mesh_order(0, GMSH_SET, WID->mesh_butt[3]->value()? 2 : 1);
opt_mesh_second_order_incomplete(0, GMSH_SET, WID->mesh_butt[4]->value());
opt_mesh_constrained_bgmesh(0, GMSH_SET, WID->mesh_butt[5]->value());
opt_mesh_points(0, GMSH_SET, WID->mesh_butt[6]->value());
opt_mesh_lines(0, GMSH_SET, WID->mesh_butt[7]->value());
opt_mesh_triangles(0, GMSH_SET, WID->mesh_menu_butt->menu()[0].value() ? 1 : 0);
opt_mesh_quadrangles(0, GMSH_SET, WID->mesh_menu_butt->menu()[1].value() ? 1 : 0);
opt_mesh_tetrahedra(0, GMSH_SET, WID->mesh_menu_butt->menu()[2].value() ? 1 : 0);
opt_mesh_hexahedra(0, GMSH_SET, WID->mesh_menu_butt->menu()[3].value() ? 1 : 0);
opt_mesh_prisms(0, GMSH_SET, WID->mesh_menu_butt->menu()[4].value() ? 1 : 0);
opt_mesh_pyramids(0, GMSH_SET, WID->mesh_menu_butt->menu()[5].value() ? 1 : 0);
opt_mesh_surfaces_edges(0, GMSH_SET, WID->mesh_butt[8]->value());
opt_mesh_surfaces_faces(0, GMSH_SET, WID->mesh_butt[9]->value());
opt_mesh_volumes_edges(0, GMSH_SET, WID->mesh_butt[10]->value());
opt_mesh_volumes_faces(0, GMSH_SET, WID->mesh_butt[11]->value());
opt_mesh_points_num(0, GMSH_SET, WID->mesh_butt[12]->value());
opt_mesh_lines_num(0, GMSH_SET, WID->mesh_butt[13]->value());
opt_mesh_surfaces_num(0, GMSH_SET, WID->mesh_butt[14]->value());
opt_mesh_volumes_num(0, GMSH_SET, WID->mesh_butt[15]->value());
opt_mesh_use_cut_plane(0, GMSH_SET, WID->mesh_butt[16]->value());
opt_mesh_cut_plane_draw_intersect(0, GMSH_SET, WID->mesh_butt[22]->value());
opt_mesh_cut_plane_only_volume(0, GMSH_SET, WID->mesh_butt[23]->value());
opt_mesh_light(0, GMSH_SET, WID->mesh_butt[17]->value());
opt_mesh_light_two_side(0, GMSH_SET, WID->mesh_butt[18]->value());
opt_mesh_smooth_normals(0, GMSH_SET, WID->mesh_butt[19]->value());
opt_mesh_light_lines(0, GMSH_SET, WID->mesh_butt[20]->value());
opt_mesh_nb_smoothing(0, GMSH_SET, WID->mesh_value[0]->value());
opt_mesh_lc_factor(0, GMSH_SET, WID->mesh_value[2]->value());
opt_mesh_quality_inf(0, GMSH_SET, WID->mesh_value[4]->value());
opt_mesh_quality_sup(0, GMSH_SET, WID->mesh_value[5]->value());
opt_mesh_radius_inf(0, GMSH_SET, WID->mesh_value[6]->value());
opt_mesh_radius_sup(0, GMSH_SET, WID->mesh_value[7]->value());
opt_mesh_normals(0, GMSH_SET, WID->mesh_value[8]->value());
opt_mesh_explode(0, GMSH_SET, WID->mesh_value[9]->value());
opt_mesh_tangents(0, GMSH_SET, WID->mesh_value[13]->value());
opt_mesh_point_size(0, GMSH_SET, WID->mesh_value[10]->value());
opt_mesh_line_width(0, GMSH_SET, WID->mesh_value[11]->value());
opt_mesh_label_frequency(0, GMSH_SET, WID->mesh_value[12]->value());
opt_mesh_cut_planea(0, GMSH_SET, WID->mesh_value[14]->value());
opt_mesh_cut_planeb(0, GMSH_SET, WID->mesh_value[15]->value());
opt_mesh_cut_planec(0, GMSH_SET, WID->mesh_value[16]->value());
opt_mesh_cut_planed(0, GMSH_SET, WID->mesh_value[17]->value());
opt_mesh_angle_smooth_normals(0, GMSH_SET, WID->mesh_value[18]->value());
opt_mesh_point_type(0, GMSH_SET, WID->mesh_choice[0]->value());
opt_mesh_algo2d(0, GMSH_SET,
(WID->mesh_choice[2]->value() == 0) ? ALGO_2D_MESHADAPT :
ALGO_2D_DELAUNAY);
opt_mesh_algo3d(0, GMSH_SET,
(WID->mesh_choice[3]->value() == 0) ? ALGO_3D_DELAUNAY :
ALGO_3D_NETGEN);
opt_mesh_recombine_algo(0, GMSH_SET,
(WID->mesh_choice[5]->value() == 0) ? 1 : 2);
opt_mesh_color_carousel(0, GMSH_SET, WID->mesh_choice[4]->value());
opt_mesh_quality_type(0, GMSH_SET, WID->mesh_choice[6]->value());
opt_mesh_label_type(0, GMSH_SET, WID->mesh_choice[7]->value());
if(CTX.fast_redraw)
CTX.post.draw = CTX.mesh.draw = 0;
Draw();
CTX.post.draw = CTX.mesh.draw = 1;
}
// Solver options
void solver_options_cb(CALLBACK_ARGS)
{
WID->create_solver_options_window();
}
void solver_options_ok_cb(CALLBACK_ARGS)
{
activate_cb(NULL, data);
int old_listen = (int)opt_solver_listen(0, GMSH_GET, WID->solver_butt[0]->value());
opt_solver_listen(0, GMSH_SET, WID->solver_butt[0]->value());
if(!old_listen && WID->solver_butt[0]->value())
Solver(-1, NULL);
opt_solver_max_delay(0, GMSH_SET, WID->solver_value[0]->value());
opt_solver_socket_name(0, GMSH_SET, (char *)WID->solver_input[0]->value());
if(CTX.fast_redraw)
CTX.post.draw = CTX.mesh.draw = 0;
Draw();
CTX.post.draw = CTX.mesh.draw = 1;
}
// Post options
void post_options_cb(CALLBACK_ARGS)
{
WID->create_post_options_window();
}
void post_options_ok_cb(CALLBACK_ARGS)
{
activate_cb(NULL, data);
opt_post_anim_cycle(0, GMSH_SET, WID->post_butt[0]->value());
opt_post_combine_remove_orig(0, GMSH_SET, WID->post_butt[1]->value());
opt_post_horizontal_scales(0, GMSH_SET, WID->post_butt[2]->value());
opt_post_anim_delay(0, GMSH_SET, WID->post_value[0]->value());
opt_post_link(0, GMSH_SET, WID->post_choice[0]->value());
if(CTX.fast_redraw)
CTX.post.draw = CTX.mesh.draw = 0;
Draw();
CTX.post.draw = CTX.mesh.draw = 1;
}
// View options
void view_options_cb(CALLBACK_ARGS)
{
WID->create_view_options_window((int)(long)data);
}
void view_options_timestep_cb(CALLBACK_ARGS)
{
int links = (int)opt_post_link(0, GMSH_GET, 0);
for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
if((links == 2 || links == 4) ||
((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
(links == 0 && i == WID->view_number)) {
opt_view_timestep(i, GMSH_SET, ((Fl_Value_Input *) w)->value());
}
}
Draw();
}
void view_options_timestep_decr_cb(CALLBACK_ARGS)
{
int links = (int)opt_post_link(0, GMSH_GET, 0);
for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
if((links == 2 || links == 4) ||
((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
(links == 0 && i == WID->view_number)) {
opt_view_timestep(i, GMSH_SET | GMSH_GUI,
opt_view_timestep(i, GMSH_GET, 0) - 1);
}
}
Draw();
}
void view_options_timestep_incr_cb(CALLBACK_ARGS)
{
int links = (int)opt_post_link(0, GMSH_GET, 0);
for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
if((links == 2 || links == 4) ||
((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
(links == 0 && i == WID->view_number)) {
opt_view_timestep(i, GMSH_SET | GMSH_GUI,
opt_view_timestep(i, GMSH_GET, 0) + 1);
}
}
Draw();
}
void view_arrow_param_cb(CALLBACK_ARGS)
{
double a = opt_view_arrow_head_radius(WID->view_number, GMSH_GET, 0);
double b = opt_view_arrow_stem_length(WID->view_number, GMSH_GET, 0);
double c = opt_view_arrow_stem_radius(WID->view_number, GMSH_GET, 0);
while(arrow_editor("Arrow Editor", a, b, c)){
opt_view_arrow_head_radius(WID->view_number, GMSH_SET, a);
opt_view_arrow_stem_length(WID->view_number, GMSH_SET, b);
opt_view_arrow_stem_radius(WID->view_number, GMSH_SET, c);
Draw();
}
}
void view_options_ok_cb(CALLBACK_ARGS)
{
int current = WID->view_number;
if(current < 0)
return;
activate_cb(NULL, data);
if(data){
char *str = (char*)data;
if(!strcmp(str, "range_min")){
WID->view_value[31]->value(opt_view_min(WID->view_number, GMSH_GET, 0));
}
else if(!strcmp(str, "range_max")){
WID->view_value[32]->value(opt_view_max(WID->view_number, GMSH_GET, 0));
}
}
int force = 0, links = (int)opt_post_link(0, GMSH_GET, 0);
// get the old values for the current view
double scale_type = opt_view_scale_type(current, GMSH_GET, 0);
double intervals_type = opt_view_intervals_type(current, GMSH_GET, 0);
double point_type = opt_view_point_type(current, GMSH_GET, 0);
double line_type = opt_view_line_type(current, GMSH_GET, 0);
double vector_type = opt_view_vector_type(current, GMSH_GET, 0);
double glyph_location = opt_view_glyph_location(current, GMSH_GET, 0);
double tensor_type = opt_view_tensor_type(current, GMSH_GET, 0);
double range_type = opt_view_range_type(current, GMSH_GET, 0);
double axes = opt_view_axes(current, GMSH_GET, 0);
double boundary = opt_view_boundary(current, GMSH_GET, 0);
double external_view = opt_view_external_view(current, GMSH_GET, 0);
double gen_raise_view = opt_view_gen_raise_view(current, GMSH_GET, 0);
double show_time = opt_view_show_time(current, GMSH_GET, 0);
double type = opt_view_type(current, GMSH_GET, 0);
double saturate_values = opt_view_saturate_values(current, GMSH_GET, 0);
double max_recursion_level = opt_view_max_recursion_level(current, GMSH_GET, 0);
double target_error = opt_view_target_error(current, GMSH_GET, 0);
double show_element = opt_view_show_element(current, GMSH_GET, 0);
double show_scale = opt_view_show_scale(current, GMSH_GET, 0);
double auto_position = opt_view_auto_position(current, GMSH_GET, 0);
double axes_auto_position = opt_view_axes_auto_position(current, GMSH_GET, 0);
double draw_strings = opt_view_draw_strings(current, GMSH_GET, 0);
double light = opt_view_light(current, GMSH_GET, 0);
double light_two_side = opt_view_light_two_side(current, GMSH_GET, 0);
double light_lines = opt_view_light_lines(current, GMSH_GET, 0);
double smooth_normals = opt_view_smooth_normals(current, GMSH_GET, 0);
double draw_points = opt_view_draw_points(current, GMSH_GET, 0);
double draw_lines = opt_view_draw_lines(current, GMSH_GET, 0);
double draw_triangles = opt_view_draw_triangles(current, GMSH_GET, 0);
double draw_quadrangles = opt_view_draw_quadrangles(current, GMSH_GET, 0);
double draw_tetrahedra = opt_view_draw_tetrahedra(current, GMSH_GET, 0);
double draw_hexahedra = opt_view_draw_hexahedra(current, GMSH_GET, 0);
double draw_prisms = opt_view_draw_prisms(current, GMSH_GET, 0);
double draw_pyramids = opt_view_draw_pyramids(current, GMSH_GET, 0);
double draw_scalars = opt_view_draw_scalars(current, GMSH_GET, 0);
double draw_vectors = opt_view_draw_vectors(current, GMSH_GET, 0);
double draw_tensors = opt_view_draw_tensors(current, GMSH_GET, 0);
double use_gen_raise = opt_view_use_gen_raise(current, GMSH_GET, 0);
double fake_transparency = opt_view_fake_transparency(current, GMSH_GET, 0);
double use_stipple = opt_view_use_stipple(current, GMSH_GET, 0);
double normals = opt_view_normals(current, GMSH_GET, 0);
double tangents = opt_view_tangents(current, GMSH_GET, 0);
double custom_min = opt_view_custom_min(current, GMSH_GET, 0);
double custom_max = opt_view_custom_max(current, GMSH_GET, 0);
double nb_iso = opt_view_nb_iso(current, GMSH_GET, 0);
double offset0 = opt_view_offset0(current, GMSH_GET, 0);
double offset1 = opt_view_offset1(current, GMSH_GET, 0);
double offset2 = opt_view_offset2(current, GMSH_GET, 0);
double transform00 = opt_view_transform00(current, GMSH_GET, 0);
double transform01 = opt_view_transform01(current, GMSH_GET, 0);
double transform02 = opt_view_transform02(current, GMSH_GET, 0);
double transform10 = opt_view_transform10(current, GMSH_GET, 0);
double transform11 = opt_view_transform11(current, GMSH_GET, 0);
double transform12 = opt_view_transform12(current, GMSH_GET, 0);
double transform20 = opt_view_transform20(current, GMSH_GET, 0);
double transform21 = opt_view_transform21(current, GMSH_GET, 0);
double transform22 = opt_view_transform22(current, GMSH_GET, 0);
double raise0 = opt_view_raise0(current, GMSH_GET, 0);
double raise1 = opt_view_raise1(current, GMSH_GET, 0);
double raise2 = opt_view_raise2(current, GMSH_GET, 0);
double timestep = opt_view_timestep(current, GMSH_GET, 0);
double arrow_size = opt_view_arrow_size(current, GMSH_GET, 0);
double arrow_size_proportional = opt_view_arrow_size_proportional(current, GMSH_GET, 0);
double displacement_factor = opt_view_displacement_factor(current, GMSH_GET, 0);
double point_size = opt_view_point_size(current, GMSH_GET, 0);
double line_width = opt_view_line_width(current, GMSH_GET, 0);
double explode = opt_view_explode(current, GMSH_GET, 0);
double angle_smooth_normals = opt_view_angle_smooth_normals(current, GMSH_GET, 0);
double position0 = opt_view_position0(current, GMSH_GET, 0);
double position1 = opt_view_position1(current, GMSH_GET, 0);
double size0 = opt_view_size0(current, GMSH_GET, 0);
double size1 = opt_view_size1(current, GMSH_GET, 0);
double axes_tics0 = opt_view_axes_tics0(current, GMSH_GET, 0);
double axes_tics1 = opt_view_axes_tics1(current, GMSH_GET, 0);
double axes_tics2 = opt_view_axes_tics2(current, GMSH_GET, 0);
double axes_xmin = opt_view_axes_xmin(current, GMSH_GET, 0);
double axes_ymin = opt_view_axes_ymin(current, GMSH_GET, 0);
double axes_zmin = opt_view_axes_zmin(current, GMSH_GET, 0);
double axes_xmax = opt_view_axes_xmax(current, GMSH_GET, 0);
double axes_ymax = opt_view_axes_ymax(current, GMSH_GET, 0);
double axes_zmax = opt_view_axes_zmax(current, GMSH_GET, 0);
double gen_raise_factor = opt_view_gen_raise_factor(current, GMSH_GET, 0);
char name[256]; strcpy(name, opt_view_name(current, GMSH_GET, NULL));
char format[256]; strcpy(format, opt_view_format(current, GMSH_GET, NULL));
char axes_label0[256]; strcpy(axes_label0, opt_view_axes_label0(current, GMSH_GET, NULL));
char axes_label1[256]; strcpy(axes_label1, opt_view_axes_label1(current, GMSH_GET, NULL));
char axes_label2[256]; strcpy(axes_label2, opt_view_axes_label2(current, GMSH_GET, NULL));
char axes_format0[256]; strcpy(axes_format0, opt_view_axes_format0(current, GMSH_GET, NULL));
char axes_format1[256]; strcpy(axes_format1, opt_view_axes_format1(current, GMSH_GET, NULL));
char axes_format2[256]; strcpy(axes_format2, opt_view_axes_format2(current, GMSH_GET, NULL));
char gen_raise0[256]; strcpy(gen_raise0, opt_view_gen_raise0(current, GMSH_GET, NULL));
char gen_raise1[256]; strcpy(gen_raise1, opt_view_gen_raise1(current, GMSH_GET, NULL));
char gen_raise2[256]; strcpy(gen_raise2, opt_view_gen_raise2(current, GMSH_GET, NULL));
// modify only the views that need to be updated
for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
if((links == 2 || links == 4) ||
((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
(links == 0 && i == current)) {
if(links == 3 || links == 4)
force = 1;
double val;
// view_choice
switch (WID->view_choice[1]->value()) {
case 0: val = DRAW_POST_LINEAR; break;
case 1: val = DRAW_POST_LOGARITHMIC; break;
default: val = DRAW_POST_DOUBLELOGARITHMIC; break; // 2
}
if(force || (val != scale_type))
opt_view_scale_type(i, GMSH_SET, val);
switch (WID->view_choice[0]->value()) {
case 0: val = DRAW_POST_ISO; break;
case 1: val = DRAW_POST_DISCRETE; break;
case 2: val = DRAW_POST_CONTINUOUS; break;
default: val = DRAW_POST_NUMERIC; break; // 3
}
if(force || (val != intervals_type))
opt_view_intervals_type(i, GMSH_SET, val);
val = WID->view_choice[5]->value();
if(force || (val != point_type))
opt_view_point_type(i, GMSH_SET, val);
val = WID->view_choice[6]->value();
if(force || (val != line_type))
opt_view_line_type(i, GMSH_SET, val);
switch (WID->view_choice[2]->value()) {
case 0: val = DRAW_POST_SEGMENT; break;
case 1: val = DRAW_POST_ARROW; break;
case 2: val = DRAW_POST_PYRAMID; break;
case 4: val = DRAW_POST_DISPLACEMENT; break;
default: val = DRAW_POST_ARROW3D; break; // 3
}
if(force || (val != vector_type))
opt_view_vector_type(i, GMSH_SET, val);
switch (WID->view_choice[3]->value()) {
case 0: val = DRAW_POST_LOCATE_COG; break;
default: val = DRAW_POST_LOCATE_VERTEX; break;
}
if(force || (val != glyph_location))
opt_view_glyph_location(i, GMSH_SET, val);
switch (WID->view_choice[4]->value()) {
case 0: val = DRAW_POST_VONMISES; break;
case 2: val = DRAW_POST_LMGC90_TYPE; break;
case 3: val = DRAW_POST_LMGC90_COORD; break;
case 4: val = DRAW_POST_LMGC90_PRES; break;
case 5: val = DRAW_POST_LMGC90_SN; break;
case 6: val = DRAW_POST_LMGC90_DEPX; break;
case 7: val = DRAW_POST_LMGC90_DEPY; break;
case 8: val = DRAW_POST_LMGC90_DEPZ; break;
case 9: val = DRAW_POST_LMGC90_DEPAV; break;
case 10: val = DRAW_POST_LMGC90_DEPNORM; break;
default: val = DRAW_POST_LMGC90; break; // 1
}
if(force || (val != tensor_type))
opt_view_tensor_type(i, GMSH_SET, val);
switch (WID->view_choice[7]->value()) {
case 0: val = DRAW_POST_RANGE_DEFAULT; break;
case 1: val = DRAW_POST_RANGE_PER_STEP; break;
default: val = DRAW_POST_RANGE_CUSTOM; break; // 2
}
if(force || (val != range_type))
opt_view_range_type(i, GMSH_SET, val);
val = WID->view_choice[8]->value();
if(force || (val != axes))
opt_view_axes(i, GMSH_SET, val);
val = WID->view_choice[9]->value();
if(force || (val != boundary))
opt_view_boundary(i, GMSH_SET, val);
val = WID->view_choice[10]->value() - 1;
if(force || (val != external_view))
opt_view_external_view(i, GMSH_SET, val);
val = WID->view_choice[11]->value() - 1;
if(force || (val != gen_raise_view))
opt_view_gen_raise_view(i, GMSH_SET, val);
val = WID->view_choice[12]->value();
if(force || (val != show_time))
opt_view_show_time(i, GMSH_SET, val);
switch(WID->view_choice[13]->value()){
case 0: val = DRAW_POST_3D; break;
case 1: val = DRAW_POST_2D_SPACE; break;
default: val = DRAW_POST_2D_TIME; break; // 2
}
if(force || (val != type))
opt_view_type(i, GMSH_SET, val);
// view_butts
val = WID->view_butt[0]->value();
if(force || (val != arrow_size_proportional))
opt_view_arrow_size_proportional(i, GMSH_SET, val);
val = WID->view_butt[38]->value();
if(force || (val != saturate_values))
opt_view_saturate_values(i, GMSH_SET, val);
val = WID->view_butt[10]->value();
if(force || (val != show_element))
opt_view_show_element(i, GMSH_SET, val);
val = WID->view_butt[4]->value();
if(force || (val != show_scale))
opt_view_show_scale(i, GMSH_SET, val);
val = WID->view_butt[7]->value();
if(force || (val != auto_position))
opt_view_auto_position(i, GMSH_SET, val);
val = WID->view_butt[25]->value();
if(force || (val != axes_auto_position))
opt_view_axes_auto_position(i, GMSH_SET, val);
val = WID->view_butt[5]->value();
if(force || (val != draw_strings))
opt_view_draw_strings(i, GMSH_SET, val);
val = WID->view_butt[11]->value();
if(force || (val != light))
opt_view_light(i, GMSH_SET, val);
val = WID->view_butt[8]->value();
if(force || (val != light_lines))
opt_view_light_lines(i, GMSH_SET, val);
val = WID->view_butt[9]->value();
if(force || (val != light_two_side))
opt_view_light_two_side(i, GMSH_SET, val);
val = WID->view_butt[12]->value();
if(force || (val != smooth_normals))
opt_view_smooth_normals(i, GMSH_SET, val);
val = WID->view_menu_butt[0]->menu()[0].value() ? 1 : 0;
if(force || (val != draw_scalars))
opt_view_draw_scalars(i, GMSH_SET, val);
val = WID->view_menu_butt[0]->menu()[1].value() ? 1 : 0;
if(force || (val != draw_vectors))
opt_view_draw_vectors(i, GMSH_SET, val);
val = WID->view_menu_butt[0]->menu()[2].value() ? 1 : 0;
if(force || (val != draw_tensors))
opt_view_draw_tensors(i, GMSH_SET, val);
val = WID->view_menu_butt[1]->menu()[0].value() ? 1 : 0;
if(force || (val != draw_points))
opt_view_draw_points(i, GMSH_SET, val);
val = WID->view_menu_butt[1]->menu()[1].value() ? 1 : 0;
if(force || (val != draw_lines))
opt_view_draw_lines(i, GMSH_SET, val);
val = WID->view_menu_butt[1]->menu()[2].value() ? 1 : 0;
if(force || (val != draw_triangles))
opt_view_draw_triangles(i, GMSH_SET, val);
val = WID->view_menu_butt[1]->menu()[3].value() ? 1 : 0;
if(force || (val != draw_quadrangles))
opt_view_draw_quadrangles(i, GMSH_SET, val);
val = WID->view_menu_butt[1]->menu()[4].value() ? 1 : 0;
if(force || (val != draw_tetrahedra))
opt_view_draw_tetrahedra(i, GMSH_SET, val);
val = WID->view_menu_butt[1]->menu()[5].value() ? 1 : 0;
if(force || (val != draw_hexahedra))
opt_view_draw_hexahedra(i, GMSH_SET, val);
val = WID->view_menu_butt[1]->menu()[6].value() ? 1 : 0;
if(force || (val != draw_prisms))
opt_view_draw_prisms(i, GMSH_SET, val);
val = WID->view_menu_butt[1]->menu()[7].value() ? 1 : 0;
if(force || (val != draw_pyramids))
opt_view_draw_pyramids(i, GMSH_SET, val);
val = WID->view_butt[6]->value();
if(force || (val != use_gen_raise))
opt_view_use_gen_raise(i, GMSH_SET, val);
val = WID->view_butt[24]->value();
if(force || (val != fake_transparency))
opt_view_fake_transparency(i, GMSH_SET, val);
val = WID->view_butt[26]->value();
if(force || (val != use_stipple))
opt_view_use_stipple(i, GMSH_SET, val);
// view_values
val = WID->view_value[0]->value();
if(force || (val != normals))
opt_view_normals(i, GMSH_SET, val);
val = WID->view_value[1]->value();
if(force || (val != tangents))
opt_view_tangents(i, GMSH_SET, val);
val = WID->view_value[31]->value();
if(force || (val != custom_min))
opt_view_custom_min(i, GMSH_SET, val);
val = WID->view_value[32]->value();
if(force || (val != custom_max))
opt_view_custom_max(i, GMSH_SET, val);
val = WID->view_value[33]->value();
if(force || (val != max_recursion_level))
opt_view_max_recursion_level(i, GMSH_SET, val);
val = WID->view_value[34]->value();
if(force || (val != target_error))
opt_view_target_error(i, GMSH_SET, val);
val = WID->view_value[30]->value();
if(force || (val != nb_iso))
opt_view_nb_iso(i, GMSH_SET, val);
val = WID->view_value[40]->value();
if(force || (val != offset0))
opt_view_offset0(i, GMSH_SET, val);
val = WID->view_value[41]->value();
if(force || (val != offset1))
opt_view_offset1(i, GMSH_SET, val);
val = WID->view_value[42]->value();
if(force || (val != offset2))
opt_view_offset2(i, GMSH_SET, val);
val = WID->view_value[51]->value();
if(force || (val != transform00))
opt_view_transform00(i, GMSH_SET, val);
val = WID->view_value[52]->value();
if(force || (val != transform01))
opt_view_transform01(i, GMSH_SET, val);
val = WID->view_value[53]->value();
if(force || (val != transform02))
opt_view_transform02(i, GMSH_SET, val);
val = WID->view_value[54]->value();
if(force || (val != transform10))
opt_view_transform10(i, GMSH_SET, val);
val = WID->view_value[55]->value();
if(force || (val != transform11))
opt_view_transform11(i, GMSH_SET, val);
val = WID->view_value[56]->value();
if(force || (val != transform12))
opt_view_transform12(i, GMSH_SET, val);
val = WID->view_value[57]->value();
if(force || (val != transform20))
opt_view_transform20(i, GMSH_SET, val);
val = WID->view_value[58]->value();
if(force || (val != transform21))
opt_view_transform21(i, GMSH_SET, val);
val = WID->view_value[59]->value();
if(force || (val != transform22))
opt_view_transform22(i, GMSH_SET, val);
val = WID->view_value[43]->value();
if(force || (val != raise0))
opt_view_raise0(i, GMSH_SET, val);
val = WID->view_value[44]->value();
if(force || (val != raise1))
opt_view_raise1(i, GMSH_SET, val);
val = WID->view_value[45]->value();
if(force || (val != raise2))
opt_view_raise2(i, GMSH_SET, val);
val = WID->view_value[50]->value();
if(force || (val != timestep))
opt_view_timestep(i, GMSH_SET, val);
val = WID->view_value[60]->value();
if(force || (val != arrow_size))
opt_view_arrow_size(i, GMSH_SET, val);
val = WID->view_value[63]->value();
if(force || (val != displacement_factor))
opt_view_displacement_factor(i, GMSH_SET, val);
val = WID->view_value[61]->value();
if(force || (val != point_size))
opt_view_point_size(i, GMSH_SET, val);
val = WID->view_value[62]->value();
if(force || (val != line_width))
opt_view_line_width(i, GMSH_SET, val);
val = WID->view_value[12]->value();
if(force || (val != explode))
opt_view_explode(i, GMSH_SET, val);
val = WID->view_value[10]->value();
if(force || (val != angle_smooth_normals))
opt_view_angle_smooth_normals(i, GMSH_SET, val);
val = WID->view_value[20]->value();
if(force || (val != position0))
opt_view_position0(i, GMSH_SET, val);
val = WID->view_value[21]->value();
if(force || (val != position1))
opt_view_position1(i, GMSH_SET, val);
val = WID->view_value[22]->value();
if(force || (val != size0))
opt_view_size0(i, GMSH_SET, val);
val = WID->view_value[23]->value();
if(force || (val != size1))
opt_view_size1(i, GMSH_SET, val);
val = WID->view_value[13]->value();
if(force || (val != axes_xmin))
opt_view_axes_xmin(i, GMSH_SET, val);
val = WID->view_value[14]->value();
if(force || (val != axes_ymin))
opt_view_axes_ymin(i, GMSH_SET, val);
val = WID->view_value[15]->value();
if(force || (val != axes_zmin))
opt_view_axes_zmin(i, GMSH_SET, val);
val = WID->view_value[16]->value();
if(force || (val != axes_xmax))
opt_view_axes_xmax(i, GMSH_SET, val);
val = WID->view_value[17]->value();
if(force || (val != axes_ymax))
opt_view_axes_ymax(i, GMSH_SET, val);
val = WID->view_value[18]->value();
if(force || (val != axes_zmax))
opt_view_axes_zmax(i, GMSH_SET, val);
val = WID->view_value[2]->value();
if(force || (val != gen_raise_factor))
opt_view_gen_raise_factor(i, GMSH_SET, val);
val = WID->view_value[3]->value();
if(force || (val != axes_tics0))
opt_view_axes_tics0(i, GMSH_SET, val);
val = WID->view_value[4]->value();
if(force || (val != axes_tics1))
opt_view_axes_tics1(i, GMSH_SET, val);
val = WID->view_value[5]->value();
if(force || (val != axes_tics2))
opt_view_axes_tics2(i, GMSH_SET, val);
// view_inputs
char *str;
str = (char *)WID->view_input[0]->value();
if(force || strcmp(str, name))
opt_view_name(i, GMSH_SET, str);
str = (char *)WID->view_input[1]->value();
if(force || strcmp(str, format))
opt_view_format(i, GMSH_SET, str);
str = (char *)WID->view_input[10]->value();
if(force || strcmp(str, axes_label0))
opt_view_axes_label0(i, GMSH_SET, str);
str = (char *)WID->view_input[11]->value();
if(force || strcmp(str, axes_label1))
opt_view_axes_label1(i, GMSH_SET, str);
str = (char *)WID->view_input[12]->value();
if(force || strcmp(str, axes_label2))
opt_view_axes_label2(i, GMSH_SET, str);
str = (char *)WID->view_input[7]->value();
if(force || strcmp(str, axes_format0))
opt_view_axes_format0(i, GMSH_SET, str);
str = (char *)WID->view_input[8]->value();
if(force || strcmp(str, axes_format1))
opt_view_axes_format1(i, GMSH_SET, str);
str = (char *)WID->view_input[9]->value();
if(force || strcmp(str, axes_format2))
opt_view_axes_format2(i, GMSH_SET, str);
str = (char *)WID->view_input[4]->value();
if(force || strcmp(str, gen_raise0))
opt_view_gen_raise0(i, GMSH_SET, str);
str = (char *)WID->view_input[5]->value();
if(force || strcmp(str, gen_raise1))
opt_view_gen_raise1(i, GMSH_SET, str);
str = (char *)WID->view_input[6]->value();
if(force || strcmp(str, gen_raise2))
opt_view_gen_raise2(i, GMSH_SET, str);
// colors (since the color buttons modify the values directly
// through callbacks, we can use the opt_XXX routines directly)
if(force || (i != current)){
opt_view_color_points(i, GMSH_SET, opt_view_color_points(current, GMSH_GET, 0));
opt_view_color_lines(i, GMSH_SET, opt_view_color_lines(current, GMSH_GET, 0));
opt_view_color_triangles(i, GMSH_SET, opt_view_color_triangles(current, GMSH_GET, 0));
opt_view_color_quadrangles(i, GMSH_SET, opt_view_color_quadrangles(current, GMSH_GET, 0));
opt_view_color_tetrahedra(i, GMSH_SET, opt_view_color_tetrahedra(current, GMSH_GET, 0));
opt_view_color_hexahedra(i, GMSH_SET, opt_view_color_hexahedra(current, GMSH_GET, 0));
opt_view_color_prisms(i, GMSH_SET, opt_view_color_prisms(current, GMSH_GET, 0));
opt_view_color_pyramids(i, GMSH_SET, opt_view_color_pyramids(current, GMSH_GET, 0));
opt_view_color_tangents(i, GMSH_SET, opt_view_color_tangents(current, GMSH_GET, 0));
opt_view_color_normals(i, GMSH_SET, opt_view_color_normals(current, GMSH_GET, 0));
opt_view_color_text2d(i, GMSH_SET, opt_view_color_text2d(current, GMSH_GET, 0));
opt_view_color_text3d(i, GMSH_SET, opt_view_color_text3d(current, GMSH_GET, 0));
opt_view_color_axes(i, GMSH_SET, opt_view_color_axes(current, GMSH_GET, 0));
}
// colorbar window
if(force || (i != current)) {
Post_View *src = *(Post_View **)List_Pointer(CTX.post.list, current);
Post_View *dest = *(Post_View **)List_Pointer(CTX.post.list, i);
ColorTable_Copy(&src->CT);
ColorTable_Paste(&dest->CT);
dest->Changed = 1;
}
}
}
if(CTX.fast_redraw)
CTX.post.draw = CTX.mesh.draw = 0;
Draw();
CTX.post.draw = CTX.mesh.draw = 1;
}
// Statistics Menu
void statistics_cb(CALLBACK_ARGS)
{
WID->create_statistics_window();
}
void statistics_update_cb(CALLBACK_ARGS)
{
WID->set_statistics(true);
}
void statistics_histogram_cb(CALLBACK_ARGS)
{
char *name = (char*)data;
int type;
if(!strcmp(name, "Gamma"))
type = 0;
else if(!strcmp(name, "Eta"))
type = 1;
else
type = 2;
Create2DGraph(name, "# Elements", 100, 0, WID->quality[type]);
Draw();
}
// Messages Menu
void message_cb(CALLBACK_ARGS)
{
WID->create_message_window();
}
void message_copy_cb(CALLBACK_ARGS)
{
#define BUFFL 50000
static char buff[BUFFL];
strcpy(buff, "");
for(int i = 1; i <= WID->msg_browser->size(); i++) {
if(WID->msg_browser->selected(i)) {
const char *c = WID->msg_browser->text(i);
if(strlen(buff) + strlen(c) > BUFFL - 2) {
Msg(GERROR, "Text selection too large to copy");
break;
}
if(c[0] == '@')
strcat(buff, &c[5]);
else
strcat(buff, c);
strcat(buff, "\n");
}
}
// bof bof bof
Fl::copy(buff, strlen(buff), 0);
Fl::copy(buff, strlen(buff), 1);
}
void message_clear_cb(CALLBACK_ARGS)
{
WID->msg_browser->clear();
}
void message_save_cb(CALLBACK_ARGS)
{
test:
if(file_chooser(0, 1, "Save", "*")) {
char *name = file_chooser_get_name(1);
if(CTX.confirm_overwrite) {
if(!StatFile(name))
if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
"Cancel", "Replace", NULL, name))
goto test;
}
WID->save_message(name);
}
}
// Visibility Menu
void visibility_cb(CALLBACK_ARGS)
{
// get the visibility info from the model, and update the browser accordingly
char *str = (char*)data;
if(str && !strcmp(str, "redraw_only"))
WID->create_visibility_window(true);
else
WID->create_visibility_window();
WID->vis_browser->clear();
int type = WID->vis_type->value();
VisibilityManager::instance()->update(type);
for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){
WID->vis_browser->add(VisibilityManager::instance()->getBrowserLine(i).c_str());
if(VisibilityManager::instance()->getVisibility(i))
WID->vis_browser->select(i + 1);
}
// active the delete button for physicals only!
if(type == 1)
WID->vis_push_butt[0]->activate();
else
WID->vis_push_butt[0]->deactivate();
// disable numeric and interactive selection for partitions
if(type == 2){
WID->vis_group[1]->deactivate();
WID->vis_group[2]->deactivate();
}
else{
WID->vis_group[1]->activate();
WID->vis_group[2]->activate();
}
}
void visibility_ok_cb(CALLBACK_ARGS)
{
// if the browser is not empty, get the selections made in the
// browser and apply them into the model
if(VisibilityManager::instance()->getNumEntities()){
CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
bool recursive = WID->vis_butt[0]->value() ? true : false;
int type = WID->vis_type->value();
VisibilityManager::instance()->setAllInvisible(type);
for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++)
if(WID->vis_browser->selected(i + 1))
VisibilityManager::instance()->setVisibility(i, 1, recursive);
// then refresh the browser to account for recursive selections
for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++)
if(VisibilityManager::instance()->getVisibility(i))
WID->vis_browser->select(i + 1);
Draw();
}
}
void visibility_save_cb(CALLBACK_ARGS)
{
std::string str = VisibilityManager::instance()->getStringForGEO();
add_infile((char*)str.c_str(), CTX.filename);
}
void visibility_delete_cb(CALLBACK_ARGS)
{
int type = WID->vis_type->value();
if(type != 1) return; // delete only available for physicals
bool all = true;
for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){
if(!WID->vis_browser->selected(i + 1)){
all = false;
break;
}
}
if(all){
GMODEL->deletePhysicalGroups();
}
else{
for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){
if(WID->vis_browser->selected(i + 1)){
Vis *v = VisibilityManager::instance()->getEntity(i);
GMODEL->deletePhysicalGroup(v->getDim(), v->getTag());
}
}
}
visibility_cb(NULL, (void*)"redraw_only");
}
void visibility_sort_cb(CALLBACK_ARGS)
{
char *str = (char*)data;
int val;
if(!strcmp(str, "type"))
val = 1;
else if(!strcmp(str, "number"))
val = 2;
else if(!strcmp(str, "name"))
val = 3;
else if(!strcmp(str, "-"))
val = -1;
else if(!strcmp(str, "+"))
val = -2;
else
val = 0;
if(val == 0) { // select or deselect everything
int selectall = 0;
for(int i = 0; i < WID->vis_browser->size(); i++)
if(!WID->vis_browser->selected(i + 1)) {
selectall = 1;
break;
}
if(selectall)
for(int i = 0; i < WID->vis_browser->size(); i++)
WID->vis_browser->select(i + 1);
else
WID->vis_browser->deselect();
}
else if(val == -1){ // invert the selection
int *state = new int[WID->vis_browser->size()];
for(int i = 0; i < WID->vis_browser->size(); i++)
state[i] = WID->vis_browser->selected(i + 1);
WID->vis_browser->deselect();
for(int i = 0; i < WID->vis_browser->size(); i++)
if(!state[i]) WID->vis_browser->select(i + 1);
delete [] state;
}
else if(val == -2){ // create new parameter name for selection
for(int i = 0; i < WID->vis_browser->size(); i++){
if(WID->vis_browser->selected(i + 1)){
static char tmpstr[256];
sprintf(tmpstr, "%d", VisibilityManager::instance()->getTag(i));
WID->context_geometry_input[1]->value(tmpstr);
break;
}
}
WID->context_geometry_input[0]->value("NewName");
WID->create_geometry_context_window(0);
}
else { // set new sorting mode
VisibilityManager::instance()->setSortMode(val);
visibility_cb(NULL, (void*)"redraw_only");
}
}
void visibility_number_cb(CALLBACK_ARGS)
{
CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
// type = 0 for elementary, 1 for physical and 2 for partitions
int type = WID->vis_type->value();
if(type != 0 && type != 1) return;
// what = 0 for nodes, 1 for elements, 2 for points, 3 for lines, 4
// for surfaces, 5 for volumes, 6 for physical points, 7 for
// physical lines, 8 for physical surfaces and 9 for physical
// volumes
int what = (int)(long)data;
char val;
if(what >= 100){ // show
val = 1;
what -= 100;
}
else{ // hide
val = 0;
}
char *str = (char *)WID->vis_input[what]->value();
if(type == 1 && what >= 2 && what <= 5) what += 4;
int num = (!strcmp(str, "all") || !strcmp(str, "*")) ? -1 : atoi(str);
bool recursive = WID->vis_butt[0]->value() ? true : false;
VisibilityManager::instance()->setVisibilityByNumber(what, num, val, recursive);
int pos = WID->vis_browser->position();
visibility_cb(NULL, (void*)"redraw_only");
WID->vis_browser->position(pos);
Draw();
}
static void _apply_visibility(char mode,
std::vector<GVertex*> &vertices,
std::vector<GEdge*> &edges,
std::vector<GFace*> &faces,
std::vector<GRegion*> ®ions,
std::vector<MElement*> &elements)
{
// type = 0 for elementary, 1 for physical and 2 for partitions
int type = WID->vis_type->value();
if(type != 0 && type != 1) return;
bool recursive = WID->vis_butt[0]->value() ? true : false;
if(mode == 1){ // when showing a single entity, first hide everything
if(CTX.pick_elements)
VisibilityManager::instance()->setVisibilityByNumber(1, -1, 0, false);
else
for(int i = 2; i <= 5; i++)
VisibilityManager::instance()->setVisibilityByNumber(i, -1, 0, false);
}
if(mode == 2) mode = 1;
if(CTX.pick_elements){
for(unsigned int i = 0; i < elements.size(); i++)
elements[i]->setVisibility(mode);
}
else{
for(unsigned int i = 0; i < vertices.size(); i++){
if(type == 0)
vertices[i]->setVisibility(mode, recursive);
else
for(unsigned int j = 0; j < vertices[i]->physicals.size(); j++)
VisibilityManager::instance()->setVisibilityByNumber
(6, vertices[i]->physicals[j], mode, recursive);
}
for(unsigned int i = 0; i < edges.size(); i++){
if(type == 0)
edges[i]->setVisibility(mode, recursive);
else
for(unsigned int j = 0; j < edges[i]->physicals.size(); j++)
VisibilityManager::instance()->setVisibilityByNumber
(7, edges[i]->physicals[j], mode, recursive);
}
for(unsigned int i = 0; i < faces.size(); i++){
if(type == 0)
faces[i]->setVisibility(mode, recursive);
else
for(unsigned int j = 0; j < faces[i]->physicals.size(); j++)
VisibilityManager::instance()->setVisibilityByNumber
(8, faces[i]->physicals[j], mode, recursive);
}
for(unsigned int i = 0; i < regions.size(); i++){
if(type == 0)
regions[i]->setVisibility(mode, recursive);
else
for(unsigned int j = 0; j < regions[i]->physicals.size(); j++)
VisibilityManager::instance()->setVisibilityByNumber
(9, regions[i]->physicals[j], mode, recursive);
}
}
int pos = WID->vis_browser->position();
visibility_cb(NULL, (void*)"redraw_only");
WID->vis_browser->position(pos);
}
void visibility_interactive_cb(CALLBACK_ARGS)
{
char *str = (char*)data, *help;
int what;
char mode;
if(!strcmp(str, "hide_elements")){
CTX.pick_elements = 1;
what = ENT_ALL;
mode = 0;
help = "elements to hide";
}
else if(!strcmp(str, "hide_points")){
CTX.pick_elements = 0;
what = ENT_POINT;
mode = 0;
help = "points to hide";
opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
}
else if(!strcmp(str, "hide_lines")){
CTX.pick_elements = 0;
what = ENT_LINE;
mode = 0;
help = "lines to hide";
opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
}
else if(!strcmp(str, "hide_surfaces")){
CTX.pick_elements = 0;
what = ENT_SURFACE;
mode = 0;
help = "surfaces to hide";
opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
}
else if(!strcmp(str, "hide_volumes")){
CTX.pick_elements = 0;
what = ENT_VOLUME;
mode = 0;
help = "volumes to hide";
opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
}
else if(!strcmp(str, "show_elements")){
CTX.pick_elements = 1;
what = ENT_ALL;
mode = 1;
help = "elements to show";
}
else if(!strcmp(str, "show_points")){
CTX.pick_elements = 0;
what = ENT_POINT;
mode = 1;
help = "points to show";
opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
}
else if(!strcmp(str, "show_lines")){
CTX.pick_elements = 0;
what = ENT_LINE;
mode = 1;
help = "lines to show";
opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
}
else if(!strcmp(str, "show_surfaces")){
CTX.pick_elements = 0;
what = ENT_SURFACE;
mode = 1;
help = "surfaces to show";
opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
}
else if(!strcmp(str, "show_volumes")){
CTX.pick_elements = 0;
what = ENT_VOLUME;
mode = 1;
help = "volumes to show";
opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
}
else if(!strcmp(str, "show_all")){
for(int i = 1; i <= 5; i++) // elements, points, lines, surfaces, volumes
VisibilityManager::instance()->setVisibilityByNumber(i, -1, 1, false);
CTX.mesh.changed = ENT_ALL;
Draw();
return;
}
else
return;
std::vector<GVertex*> vertices, vertices_old;
std::vector<GEdge*> edges, edges_old;
std::vector<GFace*> faces, faces_old;
std::vector<GRegion*> regions, regions_old;
std::vector<MElement*> elements, elements_old;
while(1) {
CTX.mesh.changed = ENT_ALL;
Draw();
Msg(ONSCREEN, "Select %s\n[Press %s'q' to abort]",
help, mode ? "" : "'u' to undo or ");
char ib = SelectEntity(what, vertices, edges, faces, regions, elements);
if(ib == 'l') {
_apply_visibility(mode, vertices, edges, faces, regions, elements);
// store for possible undo later
vertices_old = vertices;
edges_old = edges;
faces_old = faces;
regions_old = regions;
elements_old = elements;
}
if(ib == 'u' && !mode){ // undo only in hide mode
_apply_visibility(2, vertices_old, edges_old, faces_old,
regions_old, elements_old);
}
if(ib == 'q'){
break;
}
}
CTX.mesh.changed = ENT_ALL;
CTX.pick_elements = 0;
Draw();
Msg(ONSCREEN, "");
}
// Clipping planes menu
void clip_cb(CALLBACK_ARGS)
{
WID->create_clip_window();
}
void clip_num_cb(CALLBACK_ARGS)
{
WID->reset_clip_browser();
}
void clip_update_cb(CALLBACK_ARGS)
{
if(WID->clip_group[0]->visible()){ // clipping planes
int idx = WID->clip_choice->value();
CTX.clip[idx] = 0;
for(int i = 0; i < WID->clip_browser->size(); i++)
if(WID->clip_browser->selected(i+1))
CTX.clip[idx] += (1<<i);
for(int i = 0; i < 4; i++)
CTX.clip_plane[idx][i] = WID->clip_value[i]->value();
}
else{ // clipping box
for(int idx = 0; idx < 6; idx++){
CTX.clip[idx] = 0;
for(int i = 0; i < WID->clip_browser->size(); i++)
if(WID->clip_browser->selected(i+1))
CTX.clip[idx] += (1<<i);
}
double c[3] = {WID->clip_value[4]->value(),
WID->clip_value[5]->value(),
WID->clip_value[6]->value()};
double d[3] = {WID->clip_value[7]->value(),
WID->clip_value[8]->value(),
WID->clip_value[9]->value()};
// left
CTX.clip_plane[0][0] = 1.; CTX.clip_plane[0][1] = 0.; CTX.clip_plane[0][2] = 0.;
CTX.clip_plane[0][3] = -(c[0] - d[0] / 2.);
// right
CTX.clip_plane[1][0] = -1.; CTX.clip_plane[1][1] = 0.; CTX.clip_plane[1][2] = 0.;
CTX.clip_plane[1][3] = (c[0] + d[0] / 2.);
// top
CTX.clip_plane[2][0] = 0.; CTX.clip_plane[2][1] = 1.; CTX.clip_plane[2][2] = 0.;
CTX.clip_plane[2][3] = -(c[1] - d[1] / 2.);
// bottom
CTX.clip_plane[3][0] = 0.; CTX.clip_plane[3][1] = -1.; CTX.clip_plane[3][2] = 0.;
CTX.clip_plane[3][3] = (c[1] + d[1] / 2.);
// near
CTX.clip_plane[4][0] = 0.; CTX.clip_plane[4][1] = 0.; CTX.clip_plane[4][2] = 1.;
CTX.clip_plane[4][3] = -(c[2] - d[2] / 2.);
// far
CTX.clip_plane[5][0] = 0.; CTX.clip_plane[5][1] = 0.; CTX.clip_plane[5][2] = -1.;
CTX.clip_plane[5][3] = (c[2] + d[2] / 2.);
}
int old = CTX.draw_bbox;
CTX.draw_bbox = 1;
if(CTX.fast_redraw)
CTX.post.draw = CTX.mesh.draw = 0;
Draw();
CTX.draw_bbox = old;
CTX.post.draw = CTX.mesh.draw = 1;
}
void clip_invert_cb(CALLBACK_ARGS)
{
for(int i = 0; i < 4; i++)
WID->clip_value[i]->value(-WID->clip_value[i]->value());
clip_update_cb(NULL, NULL);
}
void clip_reset_cb(CALLBACK_ARGS)
{
for(int i = 0; i < 6; i++){
CTX.clip[i] = 0;
CTX.clip_plane[i][0] = 1.;
for(int j = 1; j < 4; j++)
CTX.clip_plane[i][j] = 0.;
}
WID->reset_clip_browser();
Draw();
}
// Manipulator menu
void manip_cb(CALLBACK_ARGS)
{
WID->create_manip_window();
}
void manip_update_cb(CALLBACK_ARGS)
{
CTX.r[0] = WID->manip_value[0]->value();
CTX.r[1] = WID->manip_value[1]->value();
CTX.r[2] = WID->manip_value[2]->value();
CTX.t[0] = WID->manip_value[3]->value();
CTX.t[1] = WID->manip_value[4]->value();
CTX.t[2] = WID->manip_value[5]->value();
CTX.s[0] = WID->manip_value[6]->value();
CTX.s[1] = WID->manip_value[7]->value();
CTX.s[2] = WID->manip_value[8]->value();
CTX.setQuaternionFromEulerAngles();
Draw();
}
// Help Menu (if you change the following, please also change the
// texinfo documentation in doc/texinfo/shortcuts.texi)
#if defined(__APPLE__)
# define CC(str) "Cmd+" str " "
#else
# define CC(str) "Ctrl+" str
#endif
void help_short_cb(CALLBACK_ARGS)
{
Msg(DIRECT, " ");
Msg(DIRECT, "Keyboard shortcuts:");
Msg(DIRECT, " ");
Msg(DIRECT, " Left arrow Go to previous time step");
Msg(DIRECT, " Right arrow Go to next time step");
Msg(DIRECT, " Up arrow Make previous view visible");
Msg(DIRECT, " Down arrow Make next view visible");
Msg(DIRECT, " ");
Msg(DIRECT, " < Go back to previous context");
Msg(DIRECT, " > Go forward to next context");
Msg(DIRECT, " 0 Reload project file");
Msg(DIRECT, " 1 or F1 Mesh lines");
Msg(DIRECT, " 2 or F2 Mesh surfaces");
Msg(DIRECT, " 3 or F3 Mesh volumes");
Msg(DIRECT, " Escape Cancel lasso zoom/selection, toggle mouse selection ON/OFF");
Msg(DIRECT, " ");
Msg(DIRECT, " g Go to geometry module");
Msg(DIRECT, " m Go to mesh module");
Msg(DIRECT, " p Go to post-processing module");
Msg(DIRECT, " s Go to solver module");
Msg(DIRECT, " ");
Msg(DIRECT, " Shift+a Bring all windows to front");
Msg(DIRECT, " Shift+g Show geometry options");
Msg(DIRECT, " Shift+m Show mesh options");
Msg(DIRECT, " Shift+o Show general options");
Msg(DIRECT, " Shift+p Show post-processing options");
Msg(DIRECT, " Shift+s Show solver options");
Msg(DIRECT, " Shift+w Show post-processing view options");
Msg(DIRECT, " Shift+Escape Enable full mouse selection");
Msg(DIRECT, " ");
Msg(DIRECT, " " CC("i") " Show statistics window");
Msg(DIRECT, " " CC("l") " Show message console");
#if defined(__APPLE__)
Msg(DIRECT, " " CC("m") " Minimize window");
#endif
Msg(DIRECT, " " CC("n") " Create new project file");
Msg(DIRECT, " " CC("o") " Open project file");
Msg(DIRECT, " " CC("q") " Quit");
Msg(DIRECT, " " CC("r") " Rename project file");
Msg(DIRECT, " " CC("s") " Save file as");
Msg(DIRECT, " ");
Msg(DIRECT, " Shift+" CC("c") " Show clipping plane window");
Msg(DIRECT, " Shift+" CC("m") " Show manipulator window");
Msg(DIRECT, " Shift+" CC("n") " Show option window");
Msg(DIRECT, " Shift+" CC("o") " Merge file(s)");
Msg(DIRECT, " Shift+" CC("s") " Save mesh in default format");
Msg(DIRECT, " Shift+" CC("v") " Show visibility window");
Msg(DIRECT, " ");
Msg(DIRECT, " Alt+a Loop through axes modes");
Msg(DIRECT, " Alt+b Hide/show bounding boxes");
Msg(DIRECT, " Alt+c Loop through predefined color schemes");
Msg(DIRECT, " Alt+f Change redraw mode (fast/full)");
Msg(DIRECT, " Alt+h Hide/show all post-processing views");
Msg(DIRECT, " Alt+i Hide/show all post-processing view scales");
Msg(DIRECT, " Alt+l Hide/show geometry lines");
Msg(DIRECT, " Alt+m Toggle visibility of all mesh entities");
Msg(DIRECT, " Alt+n Hide/show all post-processing view annotations");
Msg(DIRECT, " Alt+o Change projection mode (orthographic/perspective)");
Msg(DIRECT, " Alt+p Hide/show geometry points");
Msg(DIRECT, " Alt+s Hide/show geometry surfaces");
Msg(DIRECT, " Alt+t Loop through interval modes for visible post-processing views");
Msg(DIRECT, " Alt+v Hide/show geometry volumes");
Msg(DIRECT, " Alt+w Enable/disable all lighting");
Msg(DIRECT, " Alt+x Set X view");
Msg(DIRECT, " Alt+y Set Y view");
Msg(DIRECT, " Alt+z Set Z view");
Msg(DIRECT, " ");
Msg(DIRECT, " Alt+Shift+a Hide/show small axes");
Msg(DIRECT, " Alt+Shift+b Hide/show mesh volume faces");
Msg(DIRECT, " Alt+Shift+d Hide/show mesh surface faces");
Msg(DIRECT, " Alt+Shift+l Hide/show mesh lines");
Msg(DIRECT, " Alt+Shift+o Adjust projection parameters");
Msg(DIRECT, " Alt+Shift+p Hide/show mesh points");
Msg(DIRECT, " Alt+Shift+s Hide/show mesh surface edges");
Msg(DIRECT, " Alt+Shift+v Hide/show mesh volume edges");
Msg(DIRECT, " Alt+Shift+w Reverse all mesh normals");
Msg(DIRECT, " Alt+Shift+x Set -X view");
Msg(DIRECT, " Alt+Shift+y Set -Y view");
Msg(DIRECT, " Alt+Shift+z Set -Z view");
Msg(DIRECT, " ");
WID->create_message_window();
}
void help_mouse_cb(CALLBACK_ARGS)
{
Msg(DIRECT, " ");
Msg(DIRECT, "Mouse actions:");
Msg(DIRECT, " ");
Msg(DIRECT, " Move - Highlight the elementary geometrical entity");
Msg(DIRECT, " currently under the mouse pointer and display");
Msg(DIRECT, " its properties in the status bar");
Msg(DIRECT, " - Resize a lasso zoom/(un)selection");
Msg(DIRECT, " Left button - Rotate");
Msg(DIRECT, " - Select an entity");
Msg(DIRECT, " - Accept a lasso zoom/selection");
Msg(DIRECT, " Ctrl+Left button Start a lasso zoom/(un)selection");
Msg(DIRECT, " Middle button - Zoom");
Msg(DIRECT, " - Unselect an entity");
Msg(DIRECT, " - Accept a lasso zoom/unselection");
Msg(DIRECT, " Ctrl+Middle button Orthogonalize display");
Msg(DIRECT, " Right button - Pan");
Msg(DIRECT, " - Cancel a lasso zoom/(un)selection");
Msg(DIRECT, " - Pop-up menu on post-processing view button");
Msg(DIRECT, " Ctrl+Right button Reset to default viewpoint");
Msg(DIRECT, " ");
Msg(DIRECT, " For a 2 button mouse, Middle button = Shift+Left button");
Msg(DIRECT, " For a 1 button mouse, Middle button = Shift+Left button, Right button = Alt+Left button");
Msg(DIRECT, " ");
WID->create_message_window();
}
void help_command_line_cb(CALLBACK_ARGS)
{
Msg(DIRECT, " ");
Print_Usage("gmsh");
WID->create_message_window();
}
void help_license_cb(CALLBACK_ARGS)
{
extern void print_license();
Msg(DIRECT, " ");
print_license();
WID->create_message_window();
}
void help_about_cb(CALLBACK_ARGS)
{
WID->create_about_window();
}
void _replace_multi_format(char *in, char *val, char *out){
unsigned int i = 0, j = 0;
out[0] = '\0';
while(i < strlen(in)){
if(in[i] == '%' && i != strlen(in)-1){
if(in[i+1] == 's'){
strcat(out, val);
i += 2;
j += strlen(val);
}
else{
Msg(WARNING, "Skipping unknown format '%%%c' in '%s'", in[i+1], in);
i += 2;
}
}
else{
out[j] = in[i];
out[j+1] = '\0';
i++;
j++;
}
}
out[j] = '\0';
}
void help_online_cb(CALLBACK_ARGS)
{
char prog[1024], cmd[1024];
FixWindowsPath(CTX.web_browser, prog);
_replace_multi_format(prog, "http://www.geuz.org/gmsh/doc/texinfo/", cmd);
SystemCall(cmd);
}
void help_credits_cb(CALLBACK_ARGS)
{
char prog[1024], cmd[1024];
FixWindowsPath(CTX.web_browser, prog);
_replace_multi_format(prog, "http://www.geuz.org/gmsh/doc/CREDITS", cmd);
SystemCall(cmd);
}
// Module Menu
void mod_geometry_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry, 0);
}
void mod_mesh_cb(CALLBACK_ARGS)
{
WID->set_context(menu_mesh, 0);
}
void mod_solver_cb(CALLBACK_ARGS)
{
WID->set_context(menu_solver, 0);
}
void mod_post_cb(CALLBACK_ARGS)
{
WID->set_context(menu_post, 0);
}
void mod_back_cb(CALLBACK_ARGS)
{
WID->set_context(NULL, -1);
}
void mod_forward_cb(CALLBACK_ARGS)
{
WID->set_context(NULL, 1);
}
// Dynamic Geomtry Menus
void geometry_elementary_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary, 0);
}
void geometry_physical_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_physical, 0);
}
void geometry_edit_cb(CALLBACK_ARGS)
{
char prog[1024], file[1024], cmd[1024];
FixWindowsPath(CTX.editor, prog);
FixWindowsPath(CTX.filename, file);
_replace_multi_format(prog, file, cmd);
SystemCall(cmd);
}
void geometry_reload_cb(CALLBACK_ARGS)
{
OpenProject(CTX.filename);
Draw();
}
void geometry_elementary_add_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_add, 0);
}
void geometry_elementary_add_new_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_add_new, 0);
}
void geometry_elementary_add_new_parameter_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(0);
}
void geometry_elementary_add_new_point_cb(CALLBACK_ARGS)
{
opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
Draw();
WID->create_geometry_context_window(1);
while(1) {
WID->g_opengl_window->AddPointMode = true;
Msg(ONSCREEN, "Move mouse and/or enter coordinates\n"
"[Press 'Shift' to hold position, 'e' to add point or 'q' to abort]");
std::vector<GVertex*> vertices;
std::vector<GEdge*> edges;
std::vector<GFace*> faces;
std::vector<GRegion*> regions;
std::vector<MElement*> elements;
char ib = SelectEntity(ENT_NONE, vertices, edges, faces, regions, elements);
if(ib == 'e'){
add_point(CTX.filename,
(char*)WID->context_geometry_input[2]->value(),
(char*)WID->context_geometry_input[3]->value(),
(char*)WID->context_geometry_input[4]->value(),
(char*)WID->context_geometry_input[5]->value());
WID->reset_visibility();
Draw();
}
if(ib == 'q'){
WID->g_opengl_window->AddPointMode = false;
break;
}
}
Msg(ONSCREEN, "");
}
static void _new_multiline(int type)
{
std::vector<GVertex*> vertices;
std::vector<GEdge*> edges;
std::vector<GFace*> faces;
std::vector<GRegion*> regions;
std::vector<MElement*> elements;
int p[100];
opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
Draw();
int n = 0;
while(1) {
if(n == 0)
Msg(ONSCREEN, "Select control points\n"
"[Press 'e' to end selection or 'q' to abort]");
else
Msg(ONSCREEN, "Select control points\n"
"[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
if(ib == 'l') {
for(unsigned int i = 0; i < vertices.size(); i++){
HighlightEntity(vertices[i]);
p[n++] = vertices[i]->tag();
}
Draw();
}
if(ib == 'r') {
Msg(WARNING, "Entity de-selection not supported yet during multi-line creation");
}
if(ib == 'e') {
if(n >= 2) {
switch (type) {
case 0:
add_multline(n, p, CTX.filename);
break;
case 1:
add_spline(n, p, CTX.filename);
break;
case 2:
add_bspline(n, p, CTX.filename);
break;
case 3:
add_bezier(n, p, CTX.filename);
break;
}
}
WID->reset_visibility();
ZeroHighlight();
Draw();
n = 0;
}
if(ib == 'u') {
if(n > 0){
ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
Draw();
n--;
}
}
if(ib == 'q') {
ZeroHighlight();
Draw();
break;
}
}
Msg(ONSCREEN, "");
}
void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
{
// Disallow multiline selection at the moment, since multilines
// dont't work so well...
//
//_new_multiline(0);
//
std::vector<GVertex*> vertices;
std::vector<GEdge*> edges;
std::vector<GFace*> faces;
std::vector<GRegion*> regions;
std::vector<MElement*> elements;
int p[100];
opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
Draw();
int n = 0;
while(1) {
if(n == 0)
Msg(ONSCREEN, "Select start point\n"
"[Press 'q' to abort]");
if(n == 1)
Msg(ONSCREEN, "Select end point\n"
"[Press 'u' to undo last selection or 'q' to abort]");
char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
if(ib == 'l') {
HighlightEntity(vertices[0]);
Draw();
p[n++] = vertices[0]->tag();
}
if(ib == 'r') {
Msg(WARNING, "Entity de-selection not supported yet during line creation");
}
if(ib == 'u') {
if(n > 0){
ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
Draw();
n--;
}
}
if(ib == 'q') {
ZeroHighlight();
Draw();
break;
}
if(n == 2) {
add_multline(2, p, CTX.filename);
WID->reset_visibility();
ZeroHighlight();
Draw();
n = 0;
}
}
Msg(ONSCREEN, "");
}
void geometry_elementary_add_new_spline_cb(CALLBACK_ARGS)
{
_new_multiline(1);
}
void geometry_elementary_add_new_bspline_cb(CALLBACK_ARGS)
{
_new_multiline(2);
}
void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS)
{
std::vector<GVertex*> vertices;
std::vector<GEdge*> edges;
std::vector<GFace*> faces;
std::vector<GRegion*> regions;
std::vector<MElement*> elements;
int p[100];
opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
Draw();
int n = 0;
while(1) {
if(n == 0)
Msg(ONSCREEN, "Select start point\n"
"[Press 'q' to abort]");
if(n == 1)
Msg(ONSCREEN, "Select center point\n"
"[Press 'u' to undo last selection or 'q' to abort]");
if(n == 2)
Msg(ONSCREEN, "Select end point\n"
"[Press 'u' to undo last selection or 'q' to abort]");
char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
if(ib == 'l') {
HighlightEntity(vertices[0]);
Draw();
p[n++] = vertices[0]->tag();
}
if(ib == 'r') {
Msg(WARNING, "Entity de-selection not supported yet during circle creation");
}
if(ib == 'u') {
if(n > 0){
ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
Draw();
n--;
}
}
if(ib == 'q') {
ZeroHighlight();
Draw();
break;
}
if(n == 3) {
add_circ(p[0], p[1], p[2], CTX.filename); // begin, center, end
WID->reset_visibility();
ZeroHighlight();
Draw();
n = 0;
}
}
Msg(ONSCREEN, "");
}
void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
{
std::vector<GVertex*> vertices;
std::vector<GEdge*> edges;
std::vector<GFace*> faces;
std::vector<GRegion*> regions;
std::vector<MElement*> elements;
int p[100];
opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
Draw();
int n = 0;
while(1) {
if(n == 0)
Msg(ONSCREEN, "Select start point\n"
"[Press 'q' to abort]");
if(n == 1)
Msg(ONSCREEN, "Select center point\n"
"[Press 'u' to undo last selection or 'q' to abort]");
if(n == 2)
Msg(ONSCREEN, "Select major axis point\n"
"[Press 'u' to undo last selection or 'q' to abort]");
if(n == 3)
Msg(ONSCREEN, "Select end point\n"
"[Press 'u' to undo last selection or 'q' to abort]");
char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
if(ib == 'l') {
HighlightEntity(vertices[0]);
Draw();
p[n++] = vertices[0]->tag();
}
if(ib == 'r') {
Msg(WARNING, "Entity de-selection not supported yet during ellipse creation");
}
if(ib == 'u') {
if(n > 0){
ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
Draw();
n--;
}
}
if(ib == 'q') {
ZeroHighlight();
Draw();
break;
}
if(n == 4) {
add_ell(p[0], p[1], p[2], p[3], CTX.filename);
WID->reset_visibility();
ZeroHighlight();
Draw();
n = 0;
}
}
Msg(ONSCREEN, "");
}
static void _new_surface_volume(int mode)
{
std::vector<GVertex*> vertices;
std::vector<GEdge*> edges;
std::vector<GFace*> faces;
std::vector<GRegion*> regions;
std::vector<MElement*> elements;
int type, num;
List_T *List1 = List_Create(10, 10, sizeof(int));
List_T *List2 = List_Create(10, 10, sizeof(int));
if(mode == 2) {
type = ENT_SURFACE;
opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
}
else {
type = ENT_LINE;
opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
}
Draw();
while(1) {
List_Reset(List1);
List_Reset(List2);
while(1) {
if(type == ENT_LINE){
if(!List_Nbr(List1))
Msg(ONSCREEN, "Select surface boundary\n"
"[Press 'q' to abort]");
else
Msg(ONSCREEN, "Select surface boundary\n"
"[Press 'u' to undo last selection or 'q' to abort]");
}
else{
if(!List_Nbr(List1))
Msg(ONSCREEN, "Select volume boundary\n"
"[Press 'q' to abort]");
else
Msg(ONSCREEN, "Select volume boundary\n"
"[Press 'u' to undo last selection or 'q' to abort]");
}
char ib = SelectEntity(type, vertices, edges, faces, regions, elements);
if(ib == 'q') {
ZeroHighlight();
Draw();
goto stopall;
}
if(ib == 'u') {
if(List_Nbr(List1) > 0){
List_Read(List1, List_Nbr(List1)-1, &num);
ZeroHighlightEntityNum(0,
(type == ENT_LINE) ? abs(num) : 0,
(type != ENT_LINE) ? abs(num) : 0,
0);
List_Pop(List1);
Draw();
}
}
if(ib == 'r') {
Msg(WARNING, "Entity de-selection not supported yet during surface/volume creation");
}
if(ib == 'l') {
int num = (type == ENT_LINE) ? edges[0]->tag() : faces[0]->tag();
if(SelectContour(type, num, List1)) {
if(type == ENT_LINE)
add_lineloop(List1, CTX.filename, &num);
else
add_surfloop(List1, CTX.filename, &num);
List_Reset(List1);
List_Add(List2, &num);
while(1) {
if(!List_Nbr(List1))
Msg(ONSCREEN, "Select hole boundaries (if none, press 'e')\n"
"[Press 'e' to end selection or 'q' to abort]");
else
Msg(ONSCREEN, "Select hole boundaries\n"
"[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
ib = SelectEntity(type, vertices, edges, faces, regions, elements);
if(ib == 'q') {
ZeroHighlight();
Draw();
goto stopall;
}
if(ib == 'e') {
ZeroHighlight();
Draw();
List_Reset(List1);
break;
}
if(ib == 'u') {
if(List_Nbr(List1) > 0){
List_Read(List1, List_Nbr(List1)-1, &num);
ZeroHighlightEntityNum(0,
(type == ENT_LINE) ? abs(num) : 0,
(type != ENT_LINE) ? abs(num) : 0,
0);
List_Pop(List1);
Draw();
}
}
if(ib == 'l') {
num = (type == ENT_LINE) ? edges[0]->tag() : faces[0]->tag();
if(SelectContour(type, num, List1)) {
if(type == ENT_LINE)
add_lineloop(List1, CTX.filename, &num);
else
add_surfloop(List1, CTX.filename, &num);
List_Reset(List1);
List_Add(List2, &num);
}
}
if(ib == 'r') {
Msg(WARNING, "Entity de-selection not supported yet during surface/volume creation");
}
}
if(List_Nbr(List2)) {
switch (mode) {
case 0: add_surf(List2, CTX.filename, 0, 2); break;
case 1: add_surf(List2, CTX.filename, 0, 1); break;
case 2: add_vol(List2, CTX.filename); break;
}
WID->reset_visibility();
ZeroHighlight();
Draw();
break;
}
} // if SelectContour
}
}
}
stopall:;
List_Delete(List1);
List_Delete(List2);
Msg(ONSCREEN, "");
}
void geometry_elementary_add_new_planesurface_cb(CALLBACK_ARGS)
{
_new_surface_volume(0);
}
void geometry_elementary_add_new_ruledsurface_cb(CALLBACK_ARGS)
{
_new_surface_volume(1);
}
void geometry_elementary_add_new_volume_cb(CALLBACK_ARGS)
{
_new_surface_volume(2);
}
static void _action_point_line_surface_volume(int action, int mode, char *what)
{
std::vector<GVertex*> vertices;
std::vector<GEdge*> edges;
std::vector<GFace*> faces;
std::vector<GRegion*> regions;
std::vector<MElement*> elements;
int type;
char *str;
if(!strcmp(what, "Point")) {
type = ENT_POINT;
str = "points";
opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
}
else if(!strcmp(what, "Line")) {
type = ENT_LINE;
str = "lines";
opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
}
else if(!strcmp(what, "Surface")) {
type = ENT_SURFACE;
str = "surfaces";
opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
}
else if(!strcmp(what, "Volume")) {
type = ENT_VOLUME;
str = "volumes";
opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
}
else{
Msg(GERROR, "Unknown entity to select");
return;
}
if(action == 8){
WID->create_mesh_context_window(0);
}
Draw();
List_T *List1 = List_Create(5, 5, sizeof(int));
while(1) {
if(!List_Nbr(List1))
Msg(ONSCREEN, "Select %s\n"
"[Press 'e' to end selection or 'q' to abort]", str);
else
Msg(ONSCREEN, "Select %s\n"
"[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]", str);
char ib = SelectEntity(type, vertices, edges, faces, regions, elements);
if(ib == 'l') {
// we don't use List_Insert in order to keep the original
// ordering (this is slower, but this way undo works as
// expected)
int tag;
switch (type) {
case ENT_POINT:
for(unsigned int i = 0; i < vertices.size(); i++){
HighlightEntity(vertices[i]);
tag = vertices[i]->tag();
if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
List_Add(List1, &tag);
}
break;
case ENT_LINE:
for(unsigned int i = 0; i < edges.size(); i++){
HighlightEntity(edges[i]);
tag = edges[i]->tag();
if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
List_Add(List1, &tag);
}
break;
case ENT_SURFACE:
for(unsigned int i = 0; i < faces.size(); i++){
HighlightEntity(faces[i]);
tag = faces[i]->tag();
if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
List_Add(List1, &tag);
}
break;
case ENT_VOLUME:
for(unsigned int i = 0; i < regions.size(); i++){
HighlightEntity(regions[i]);
tag = regions[i]->tag();
if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
List_Add(List1, &tag);
}
break;
}
Draw();
}
if(ib == 'r') {
// we don't use List_Suppress in order to keep the original
// ordering (this is slower, but this way undo works as
// expected)
int index, tag;
switch (type) {
case ENT_POINT:
for(unsigned int i = 0; i < vertices.size(); i++){
tag = vertices[i]->tag();
index = List_ISearchSeq(List1, &tag, fcmp_int);
if(index >= 0) List_PSuppress(List1, index);
ZeroHighlightEntityNum(tag, 0, 0, 0);
}
break;
case ENT_LINE:
for(unsigned int i = 0; i < edges.size(); i++){
tag = edges[i]->tag();
index = List_ISearchSeq(List1, &tag, fcmp_int);
if(index >= 0) List_PSuppress(List1, index);
ZeroHighlightEntityNum(0, tag, 0, 0);
}
break;
case ENT_SURFACE:
for(unsigned int i = 0; i < faces.size(); i++){
tag = faces[i]->tag();
index = List_ISearchSeq(List1, &tag, fcmp_int);
if(index >= 0) List_PSuppress(List1, index);
ZeroHighlightEntityNum(0, 0, tag, 0);
}
break;
case ENT_VOLUME:
for(unsigned int i = 0; i < regions.size(); i++){
tag = regions[i]->tag();
index = List_ISearchSeq(List1, &tag, fcmp_int);
if(index >= 0) List_PSuppress(List1, index);
ZeroHighlightEntityNum(0, 0, 0, tag);
}
break;
}
Draw();
}
if(ib == 'u') {
if(List_Nbr(List1)) {
int num;
List_Read(List1, List_Nbr(List1) - 1, &num);
ZeroHighlightEntityNum((type == ENT_POINT) ? num : 0,
(type == ENT_LINE) ? num : 0,
(type == ENT_SURFACE) ? num : 0,
(type == ENT_VOLUME) ? num : 0);
Draw();
List_Pop(List1);
}
}
if(ib == 'e') {
if(List_Nbr(List1)){
switch (action) {
case 0:
translate(mode, List1, CTX.filename, what,
(char*)WID->context_geometry_input[6]->value(),
(char*)WID->context_geometry_input[7]->value(),
(char*)WID->context_geometry_input[8]->value());
break;
case 1:
rotate(mode, List1, CTX.filename, what,
(char*)WID->context_geometry_input[12]->value(),
(char*)WID->context_geometry_input[13]->value(),
(char*)WID->context_geometry_input[14]->value(),
(char*)WID->context_geometry_input[9]->value(),
(char*)WID->context_geometry_input[10]->value(),
(char*)WID->context_geometry_input[11]->value(),
(char*)WID->context_geometry_input[15]->value());
break;
case 2:
dilate(mode, List1, CTX.filename, what,
(char*)WID->context_geometry_input[16]->value(),
(char*)WID->context_geometry_input[17]->value(),
(char*)WID->context_geometry_input[18]->value(),
(char*)WID->context_geometry_input[19]->value());
break;
case 3:
symmetry(mode, List1, CTX.filename, what,
(char*)WID->context_geometry_input[20]->value(),
(char*)WID->context_geometry_input[21]->value(),
(char*)WID->context_geometry_input[22]->value(),
(char*)WID->context_geometry_input[23]->value());
break;
case 4:
extrude(List1, CTX.filename, what,
(char*)WID->context_geometry_input[6]->value(),
(char*)WID->context_geometry_input[7]->value(),
(char*)WID->context_geometry_input[8]->value());
break;
case 5:
protude(List1, CTX.filename, what,
(char*)WID->context_geometry_input[12]->value(),
(char*)WID->context_geometry_input[13]->value(),
(char*)WID->context_geometry_input[14]->value(),
(char*)WID->context_geometry_input[9]->value(),
(char*)WID->context_geometry_input[10]->value(),
(char*)WID->context_geometry_input[11]->value(),
(char*)WID->context_geometry_input[15]->value());
break;
case 6:
delet(List1, CTX.filename, what);
break;
case 7:
add_physical(List1, CTX.filename, type);
break;
case 8:
add_charlength(List1, CTX.filename, (char*)WID->context_mesh_input[0]->value());
break;
case 9:
add_recosurf(List1, CTX.filename);
break;
default:
Msg(GERROR, "Unknown action on selected entities");
break;
}
List_Reset(List1);
WID->reset_visibility();
ZeroHighlight();
if(action <= 6) SetBoundingBox();
Draw();
}
}
if(ib == 'q') {
ZeroHighlight();
Draw();
break;
}
}
List_Delete(List1);
Msg(ONSCREEN, "");
}
void geometry_elementary_add_translate_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_add_translate, 0);
}
void geometry_elementary_add_translate_point_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(2);
_action_point_line_surface_volume(0, 1, "Point");
}
void geometry_elementary_add_translate_line_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(2);
_action_point_line_surface_volume(0, 1, "Line");
}
void geometry_elementary_add_translate_surface_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(2);
_action_point_line_surface_volume(0, 1, "Surface");
}
void geometry_elementary_translate_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_translate, 0);
}
void geometry_elementary_translate_point_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(2);
_action_point_line_surface_volume(0, 0, "Point");
}
void geometry_elementary_translate_line_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(2);
_action_point_line_surface_volume(0, 0, "Line");
}
void geometry_elementary_translate_surface_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(2);
_action_point_line_surface_volume(0, 0, "Surface");
}
void geometry_elementary_add_rotate_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_add_rotate, 0);
}
void geometry_elementary_add_rotate_point_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(3);
_action_point_line_surface_volume(1, 1, "Point");
}
void geometry_elementary_add_rotate_line_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(3);
_action_point_line_surface_volume(1, 1, "Line");
}
void geometry_elementary_add_rotate_surface_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(3);
_action_point_line_surface_volume(1, 1, "Surface");
}
void geometry_elementary_rotate_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_rotate, 0);
}
void geometry_elementary_rotate_point_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(3);
_action_point_line_surface_volume(1, 0, "Point");
}
void geometry_elementary_rotate_line_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(3);
_action_point_line_surface_volume(1, 0, "Line");
}
void geometry_elementary_rotate_surface_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(3);
_action_point_line_surface_volume(1, 0, "Surface");
}
void geometry_elementary_add_scale_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_add_scale, 0);
}
void geometry_elementary_add_scale_point_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(4);
_action_point_line_surface_volume(2, 1, "Point");
}
void geometry_elementary_add_scale_line_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(4);
_action_point_line_surface_volume(2, 1, "Line");
}
void geometry_elementary_add_scale_surface_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(4);
_action_point_line_surface_volume(2, 1, "Surface");
}
void geometry_elementary_scale_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_scale, 0);
}
void geometry_elementary_scale_point_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(4);
_action_point_line_surface_volume(2, 0, "Point");
}
void geometry_elementary_scale_line_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(4);
_action_point_line_surface_volume(2, 0, "Line");
}
void geometry_elementary_scale_surface_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(4);
_action_point_line_surface_volume(2, 0, "Surface");
}
void geometry_elementary_add_symmetry_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_add_symmetry, 0);
}
void geometry_elementary_add_symmetry_point_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(5);
_action_point_line_surface_volume(3, 1, "Point");
}
void geometry_elementary_add_symmetry_line_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(5);
_action_point_line_surface_volume(3, 1, "Line");
}
void geometry_elementary_add_symmetry_surface_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(5);
_action_point_line_surface_volume(3, 1, "Surface");
}
void geometry_elementary_symmetry_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_symmetry, 0);
}
void geometry_elementary_symmetry_point_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(5);
_action_point_line_surface_volume(3, 0, "Point");
}
void geometry_elementary_symmetry_line_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(5);
_action_point_line_surface_volume(3, 0, "Line");
}
void geometry_elementary_symmetry_surface_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(5);
_action_point_line_surface_volume(3, 0, "Surface");
}
void geometry_elementary_extrude_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_extrude, 0);
}
void geometry_elementary_extrude_translate_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_extrude_translate, 0);
}
void geometry_elementary_extrude_translate_point_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(2);
_action_point_line_surface_volume(4, 0, "Point");
}
void geometry_elementary_extrude_translate_line_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(2);
_action_point_line_surface_volume(4, 0, "Line");
}
void geometry_elementary_extrude_translate_surface_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(2);
_action_point_line_surface_volume(4, 0, "Surface");
}
void geometry_elementary_extrude_rotate_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_extrude_rotate, 0);
}
void geometry_elementary_extrude_rotate_point_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(3);
_action_point_line_surface_volume(5, 0, "Point");
}
void geometry_elementary_extrude_rotate_line_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(3);
_action_point_line_surface_volume(5, 0, "Line");
}
void geometry_elementary_extrude_rotate_surface_cb(CALLBACK_ARGS)
{
WID->create_geometry_context_window(3);
_action_point_line_surface_volume(5, 0, "Surface");
}
void geometry_elementary_coherence_cb(CALLBACK_ARGS)
{
coherence(CTX.filename);
}
void geometry_elementary_delete_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_elementary_delete, 0);
}
void geometry_elementary_delete_point_cb(CALLBACK_ARGS)
{
_action_point_line_surface_volume(6, 0, "Point");
}
void geometry_elementary_delete_line_cb(CALLBACK_ARGS)
{
_action_point_line_surface_volume(6, 0, "Line");
}
void geometry_elementary_delete_surface_cb(CALLBACK_ARGS)
{
_action_point_line_surface_volume(6, 0, "Surface");
}
void geometry_physical_add_cb(CALLBACK_ARGS)
{
WID->set_context(menu_geometry_physical_add, 0);
}
void geometry_physical_add_point_cb(CALLBACK_ARGS)
{
WID->call_for_solver_plugin(0);
_action_point_line_surface_volume(7, 0, "Point");
}
void geometry_physical_add_line_cb(CALLBACK_ARGS)
{
WID->call_for_solver_plugin(1);
_action_point_line_surface_volume(7, 0, "Line");
}
void geometry_physical_add_surface_cb(CALLBACK_ARGS)
{
_action_point_line_surface_volume(7, 0, "Surface");
}
void geometry_physical_add_volume_cb(CALLBACK_ARGS)
{
_action_point_line_surface_volume(7, 0, "Volume");
}
// Dynamic Mesh Menus
void mesh_save_cb(CALLBACK_ARGS)
{
char name[256];
if(CTX.output_filename)
strcpy(name, CTX.output_filename);
else
GetDefaultFileName(CTX.mesh.format, name);
if(CTX.confirm_overwrite) {
if(!StatFile(name))
if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
"Cancel", "Replace", NULL, name))
return;
}
CreateOutputFile(name, CTX.mesh.format);
}
void mesh_define_cb(CALLBACK_ARGS)
{
WID->set_context(menu_mesh_define, 0);
}
void mesh_1d_cb(CALLBACK_ARGS)
{
GenerateMesh(1);
Draw();
Msg(STATUS2N, " ");
}
void mesh_2d_cb(CALLBACK_ARGS)
{
GenerateMesh(2);
Draw();
Msg(STATUS2N, " ");
}
void mesh_3d_cb(CALLBACK_ARGS)
{
GenerateMesh(3);
Draw();
Msg(STATUS2N, " ");
}
void mesh_edit_cb(CALLBACK_ARGS)
{
WID->set_context(menu_mesh_edit, 0);
}
void mesh_delete_cb(CALLBACK_ARGS)
{
WID->set_context(menu_mesh_delete, 0);
}
void mesh_delete_parts_cb(CALLBACK_ARGS)
{
char *str = (char*)data;
int what;
if(!strcmp(str, "elements")){
CTX.pick_elements = 1;
what = ENT_ALL;
}
else if(!strcmp(str, "lines")){
CTX.pick_elements = 0;
what = ENT_LINE;
}
else if(!strcmp(str, "surfaces")){
CTX.pick_elements = 0;
what = ENT_SURFACE;
}
else if(!strcmp(str, "volumes")){
CTX.pick_elements = 0;
what = ENT_VOLUME;
}
else
return;
std::vector<GVertex*> vertices;
std::vector<GEdge*> edges;
std::vector<GFace*> faces;
std::vector<GRegion*> regions;
std::vector<MElement*> elements;
std::vector<MElement*> ele;
std::vector<GEntity*> ent;
while(1) {
CTX.mesh.changed = ENT_ALL;
Draw();
if(ele.size() || ent.size())
Msg(ONSCREEN, "Select %s\n"
"[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]", str);
else
Msg(ONSCREEN, "Select %s\n"
"[Press 'e' to end selection or 'q' to abort]", str);
char ib = SelectEntity(what, vertices, edges, faces, regions, elements);
if(ib == 'l') {
if(CTX.pick_elements){
for(unsigned int i = 0; i < elements.size(); i++){
if(elements[i]->getVisibility() != 2){
elements[i]->setVisibility(2); ele.push_back(elements[i]);
}
}
}
else{
for(unsigned int i = 0; i < edges.size(); i++){
if(edges[i]->getSelection() != 1){
edges[i]->setSelection(1); ent.push_back(edges[i]);
}
}
for(unsigned int i = 0; i < faces.size(); i++){
if(faces[i]->getSelection() != 1){
faces[i]->setSelection(1); ent.push_back(faces[i]);
}
}
for(unsigned int i = 0; i < regions.size(); i++){
if(regions[i]->getSelection() != 1){
regions[i]->setSelection(1); ent.push_back(regions[i]);
}
}
}
}
if(ib == 'r') {
if(CTX.pick_elements){
for(unsigned int i = 0; i < elements.size(); i++)
elements[i]->setVisibility(1);
}
else{
for(unsigned int i = 0; i < edges.size(); i++)
edges[i]->setSelection(0);
for(unsigned int i = 0; i < faces.size(); i++)
faces[i]->setSelection(0);
for(unsigned int i = 0; i < regions.size(); i++)
regions[i]->setSelection(0);
}
}
if(ib == 'u') {
if(CTX.pick_elements){
if(ele.size()){
ele[ele.size() - 1]->setVisibility(1);
ele.pop_back();
}
}
else{
if(ent.size()){
ent[ent.size() - 1]->setSelection(0);
ent.pop_back();
}
}
}
if(ib == 'e') {
if(CTX.pick_elements){
for(unsigned int i = 0; i < ele.size(); i++)
if(ele[i]->getVisibility() == 2) ele[i]->setVisibility(0);
}
else{
for(unsigned int i = 0; i < ent.size(); i++)
if(ent[i]->getSelection() == 1) ent[i]->setVisibility(0);
}
GMODEL->removeInvisibleElements();
ele.clear();
ent.clear();
}
if(ib == 'q') {
ZeroHighlight();
break;
}
}
CTX.mesh.changed = ENT_ALL;
CTX.pick_elements = 0;
Draw();
Msg(ONSCREEN, "");
}
void mesh_update_edges_cb(CALLBACK_ARGS)
{
Msg(GERROR, "Update edges not implemented yet");
}
void mesh_remesh_cb(CALLBACK_ARGS)
{
Msg(GERROR, "Remesh not implemented yet");
}
void mesh_inspect_cb(CALLBACK_ARGS)
{
std::vector<GVertex*> vertices;
std::vector<GEdge*> edges;
std::vector<GFace*> faces;
std::vector<GRegion*> regions;
std::vector<MElement*> elements;
CTX.pick_elements = 1;
CTX.mesh.changed = ENT_ALL;
Draw();
while(1) {
Msg(ONSCREEN, "Select element\n[Press 'q' to abort]");
char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements);
if(ib == 'l') {
if(elements.size()){
ZeroHighlight();
elements[0]->setVisibility(2);
Msg(DIRECT, "Element %d:", elements[0]->getNum());
Msg(DIRECT, " Type: %d", elements[0]->getTypeForMSH());
Msg(DIRECT, " Dimension: %d", elements[0]->getDim());
Msg(DIRECT, " Order: %d", elements[0]->getPolynomialOrder());
Msg(DIRECT, " Partition: %d", elements[0]->getPartition());
char tmp1[32], tmp2[512];
sprintf(tmp2, " Vertices:");
for(int i = 0; i < elements[0]->getNumVertices(); i++){
sprintf(tmp1, " %d", elements[0]->getVertex(i)->getNum());
strcat(tmp2, tmp1);
}
Msg(DIRECT, tmp2);
SPoint3 pt = elements[0]->barycenter();
Msg(DIRECT, " Barycenter: (%g,%g,%g)", pt[0], pt[1], pt[2]);
Msg(DIRECT, " Rho: %g", elements[0]->rhoShapeMeasure());
Msg(DIRECT, " Gamma: %g", elements[0]->gammaShapeMeasure());
Msg(DIRECT, " Eta: %g", elements[0]->etaShapeMeasure());
CTX.mesh.changed = ENT_ALL;
Draw();
WID->create_message_window();
}
}
if(ib == 'q') {
ZeroHighlight();
break;
}
}
CTX.pick_elements = 0;
CTX.mesh.changed = ENT_ALL;
Draw();
Msg(ONSCREEN, "");
}
void mesh_degree_cb(CALLBACK_ARGS)
{
if((long)data == 2)
Degre2(CTX.mesh.second_order_linear, CTX.mesh.second_order_incomplete);
else
Degre1();
CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
Draw();
Msg(STATUS2N, " ");
}
void mesh_optimize_cb(CALLBACK_ARGS)
{
if(CTX.threads_lock) {
Msg(INFO, "I'm busy! Ask me that later...");
return;
}
CTX.threads_lock = 1;
OptimizeMesh();
CTX.threads_lock = 0;
CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
Draw();
Msg(STATUS2N, " ");
}
void mesh_define_length_cb(CALLBACK_ARGS)
{
_action_point_line_surface_volume(8, 0, "Point");
}
void mesh_define_recombine_cb(CALLBACK_ARGS)
{
_action_point_line_surface_volume(9, 0, "Surface");
}
void mesh_define_transfinite_cb(CALLBACK_ARGS)
{
WID->set_context(menu_mesh_define_transfinite, 0);
}
static void _add_transfinite(int dim)
{
std::vector<GVertex*> vertices;
std::vector<GEdge*> edges;
std::vector<GFace*> faces;
std::vector<GRegion*> regions;
std::vector<MElement*> elements;
char ib;
int p[100];
opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
switch (dim) {
case 1: opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); break;
case 2: opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); break;
case 3: opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1); break;
}
Draw();
int n = 0;
while(1) {
switch (dim) {
case 1:
if(n == 0)
Msg(ONSCREEN, "Select lines\n"
"[Press 'e' to end selection or 'q' to abort]");
else
Msg(ONSCREEN, "Select lines\n"
"[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
ib = SelectEntity(ENT_LINE, vertices, edges, faces, regions, elements);
break;
case 2:
Msg(ONSCREEN, "Select surface\n[Press 'q' to abort]");
ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions, elements);
break;
case 3:
Msg(ONSCREEN, "Select volume\n[Press 'q' to abort]");
ib = SelectEntity(ENT_VOLUME, vertices, edges, faces, regions, elements);
break;
default:
ib = 'l';
break;
}
if(ib == 'e') {
if(dim == 1) {
if(n > 0)
add_trsfline(n, p, CTX.filename,
(char*)WID->context_mesh_choice[0]->text(),
(char*)WID->context_mesh_input[2]->value(),
(char*)WID->context_mesh_input[1]->value());
}
ZeroHighlight();
Draw();
n = 0;
}
if(ib == 'u') {
if(dim == 1) {
if(n > 0){
ZeroHighlightEntityNum(0, p[n-1], 0, 0);
Draw();
n--;
}
}
}
if(ib == 'q') {
ZeroHighlight();
Draw();
break;
}
if(ib == 'r') {
Msg(WARNING, "Entity de-selection not supported yet during transfinite definition");
}
if(ib == 'l') {
switch (dim) {
case 1:
for(unsigned int i = 0; i < edges.size(); i++){
HighlightEntity(edges[i]);
p[n++] = edges[i]->tag();
}
Draw();
break;
case 2:
case 3:
if(dim == 2){
HighlightEntity(faces[0]);
Draw();
p[n++] = faces[0]->tag();
}
else{
HighlightEntity(regions[0]);
Draw();
p[n++] = regions[0]->tag();
}
while(1) {
if(n == 1)
Msg(ONSCREEN, "Select (ordered) boundary points\n"
"[Press 'e' to end selection or 'q' to abort]");
else
Msg(ONSCREEN, "Select (ordered) boundary points\n"
"[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
if(ib == 'l') {
HighlightEntity(vertices[0]);
Draw();
p[n++] = vertices[0]->tag();
}
if(ib == 'u') {
if(n > 1){
ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
Draw();
n--;
}
}
if(ib == 'r') {
Msg(WARNING, "Entity de-selection not supported yet during transfinite definition");
}
if(ib == 'e') {
switch (dim) {
case 2:
if(n == 3 + 1 || n == 4 + 1)
add_trsfsurf(n, p, CTX.filename,
(char*)WID->context_mesh_choice[1]->text());
else
Msg(GERROR, "Wrong number of points for transfinite surface");
break;
case 3:
if(n == 6 + 1 || n == 8 + 1)
add_trsfvol(n, p, CTX.filename);
else
Msg(GERROR, "Wrong number of points for transfinite volume");
break;
}
ZeroHighlight();
Draw();
n = 0;
break;
}
if(ib == 'q') {
ZeroHighlight();
Draw();
goto stopall;
}
}
break;
}
}
}
stopall:
Msg(ONSCREEN, "");
}
void mesh_define_transfinite_line_cb(CALLBACK_ARGS)
{
WID->create_mesh_context_window(1);
_add_transfinite(1);
}
void mesh_define_transfinite_surface_cb(CALLBACK_ARGS)
{
WID->create_mesh_context_window(2);
_add_transfinite(2);
}
void mesh_define_transfinite_volume_cb(CALLBACK_ARGS)
{
_add_transfinite(3);
}
// Dynamic Solver Menus
void solver_cb(CALLBACK_ARGS)
{
static int init = 0, first[MAXSOLVERS];
int num = (int)(long)data;
if(!init) {
for(int i = 0; i < MAXSOLVERS; i++)
first[i] = 1;
init = 1;
}
if(first[num]) {
char file[256];
first[num] = 0;
strcpy(file, CTX.base_filename);
strcat(file, SINFO[num].extension);
WID->solver[num].input[0]->value(file);
}
if(SINFO[num].nboptions) {
char file[256], tmp[256];
FixWindowsPath((char*)WID->solver[num].input[0]->value(), file);
sprintf(tmp, "\"%s\"", file);
sprintf(file, SINFO[num].name_command, tmp);
sprintf(tmp, "%s %s", SINFO[num].option_command, file);
Solver(num, tmp);
}
WID->create_solver_window(num);
}
void solver_file_open_cb(CALLBACK_ARGS)
{
char tmp[256];
int num = (int)(long)data;
sprintf(tmp, "*%s", SINFO[num].extension);
// We allow to create the .pro file... Or should we add a "New file"
// button?
if(file_chooser(0, 1, "Choose", tmp)) {
WID->solver[num].input[0]->value(file_chooser_get_name(1));
if(SINFO[num].nboptions) {
char file[1024];
FixWindowsPath(file_chooser_get_name(1), file);
sprintf(tmp, "\"%s\"", file);
sprintf(file, SINFO[num].name_command, tmp);
sprintf(tmp, "%s %s", SINFO[num].option_command, file);
Solver(num, tmp);
}
}
}
void solver_file_edit_cb(CALLBACK_ARGS)
{
char prog[1024], file[1024], cmd[1024];
int num = (int)(long)data;
FixWindowsPath(CTX.editor, prog);
FixWindowsPath((char*)WID->solver[num].input[0]->value(), file);
_replace_multi_format(prog, file, cmd);
SystemCall(cmd);
}
void solver_choose_mesh_cb(CALLBACK_ARGS)
{
int num = (int)(long)data;
if(file_chooser(0, 0, "Choose", "*.msh"))
WID->solver[num].input[1]->value(file_chooser_get_name(1));
}
int nbs(char *str)
{
int i, nb = 0;
for(i = 0; i < (int)strlen(str) - 1; i++) {
if(str[i] == '%' && str[i + 1] == 's') {
nb++;
i++;
}
}
return nb;
}
void solver_command_cb(CALLBACK_ARGS)
{
char tmp[256], arg[512], mesh[256], command[256];
int num = ((int *)data)[0];
int idx = ((int *)data)[1];
int i, usedopts = 0;
if(SINFO[num].popup_messages)
WID->create_message_window(true);
if(strlen(WID->solver[num].input[1]->value())) {
FixWindowsPath((char*)WID->solver[num].input[1]->value(), mesh);
sprintf(tmp, "\"%s\"", mesh);
sprintf(mesh, SINFO[num].mesh_command, tmp);
}
else {
strcpy(mesh, "");
}
if(nbs(SINFO[num].button_command[idx])) {
for(i = 0; i < idx; i++)
usedopts += nbs(SINFO[num].button_command[i]);
if(usedopts > SINFO[num].nboptions) {
Msg(GERROR, "Missing options to execute command");
return;
}
sprintf(command, SINFO[num].button_command[idx],
SINFO[num].option[usedopts][WID->solver[num].choice[usedopts]->value()]);
}
else {
strcpy(command, SINFO[num].button_command[idx]);
}
FixWindowsPath((char*)WID->solver[num].input[0]->value(), tmp);
sprintf(arg, "\"%s\"", tmp);
sprintf(tmp, SINFO[num].name_command, arg);
sprintf(arg, "%s %s %s", tmp, mesh, command);
Solver(num, arg);
}
void solver_kill_cb(CALLBACK_ARGS)
{
int num = (int)(long)data;
if(SINFO[num].pid > 0) {
if(KillProcess(SINFO[num].pid))
Msg(INFO, "Killed %s pid %d", SINFO[num].name, SINFO[num].pid);
}
SINFO[num].pid = -1;
}
void solver_choose_executable_cb(CALLBACK_ARGS)
{
int num = (int)(long)data;
if(file_chooser(0, 0, "Choose",
#if defined(WIN32)
"*.exe"
#else
"*"
#endif
))
WID->solver[num].input[2]->value(file_chooser_get_name(1));
}
void solver_ok_cb(CALLBACK_ARGS)
{
int retry = 0, num = (int)(long)data;
opt_solver_popup_messages(num, GMSH_SET, WID->solver[num].butt[0]->value());
opt_solver_merge_views(num, GMSH_SET, WID->solver[num].butt[1]->value());
opt_solver_client_server(num, GMSH_SET, WID->solver[num].butt[2]->value());
if(strcmp(opt_solver_executable(num, GMSH_GET, NULL),
WID->solver[num].input[2]->value()))
retry = 1;
opt_solver_executable(num, GMSH_SET,
(char *)WID->solver[num].input[2]->value());
if(retry)
solver_cb(NULL, data);
}
// Dynamic Post Menus
void view_toggle_cb(CALLBACK_ARGS)
{
int num = (int)(long)data;
opt_view_visible(num, GMSH_SET,
WID->m_toggle_butt[num]->value());
Draw();
}
static void _view_reload(int num)
{
if(!CTX.post.list)
return;
Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, num);
if(StatFile(v->FileName)){
Msg(GERROR, "File '%s' does not exist", v->FileName);
return;
}
CTX.post.force_num = v->Num;
MergeFile(v->FileName);
CTX.post.force_num = 0;
Post_View *v2 = *(Post_View **) List_Pointer(CTX.post.list, num);
CopyViewOptions(v, v2);
// In case the reloaded view has a different number of time steps
if(v2->TimeStep > v2->NbTimeStep - 1)
v2->TimeStep = 0;
FreeView(v);
}
void view_reload_cb(CALLBACK_ARGS)
{
_view_reload((int)(long)data);
Draw();
}
void view_reload_all_cb(CALLBACK_ARGS)
{
for(int i = 0; i < List_Nbr(CTX.post.list); i++)
_view_reload(i);
Draw();
}
void view_reload_visible_cb(CALLBACK_ARGS)
{
for(int i = 0; i < List_Nbr(CTX.post.list); i++)
if(opt_view_visible(i, GMSH_GET, 0))
_view_reload(i);
Draw();
}
void view_remove_other_cb(CALLBACK_ARGS)
{
if(!CTX.post.list) return;
for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--)
if(i != (long)data)
RemoveViewByIndex(i);
UpdateViewsInGUI();
Draw();
}
void view_remove_all_cb(CALLBACK_ARGS)
{
if(!CTX.post.list) return;
while(List_Nbr(CTX.post.list))
RemoveViewByIndex(0);
UpdateViewsInGUI();
Draw();
}
void view_remove_visible_cb(CALLBACK_ARGS)
{
if(!CTX.post.list) return;
for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--)
if(opt_view_visible(i, GMSH_GET, 0))
RemoveViewByIndex(i);
UpdateViewsInGUI();
Draw();
}
void view_remove_invisible_cb(CALLBACK_ARGS)
{
if(!CTX.post.list) return;
for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--)
if(!opt_view_visible(i, GMSH_GET, 0))
RemoveViewByIndex(i);
UpdateViewsInGUI();
Draw();
}
void view_remove_empty_cb(CALLBACK_ARGS)
{
if(!CTX.post.list) return;
for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--){
Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, i);
if(v->empty())
RemoveViewByIndex(i);
}
UpdateViewsInGUI();
Draw();
}
void view_remove_cb(CALLBACK_ARGS)
{
RemoveViewByIndex((int)(long)data);
UpdateViewsInGUI();
Draw();
}
static void _view_save_as(int view_num, char *title, int type)
{
Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, view_num);
test:
if(file_chooser(0, 1, title, "*", v->FileName)) {
char *name = file_chooser_get_name(1);
if(CTX.confirm_overwrite) {
if(!StatFile(name))
if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
"Cancel", "Replace", NULL, name))
goto test;
}
WriteView(v, name, type, 0);
}
}
void view_save_ascii_cb(CALLBACK_ARGS)
{
_view_save_as((int)(long)data, "Save As ASCII View", 0);
}
void view_save_binary_cb(CALLBACK_ARGS)
{
_view_save_as((int)(long)data, "Save As Binary View", 1);
}
void view_save_parsed_cb(CALLBACK_ARGS)
{
_view_save_as((int)(long)data, "Save As Parsed View", 2);
}
void view_save_stl_cb(CALLBACK_ARGS)
{
_view_save_as((int)(long)data, "Save As STL Triangulation", 3);
}
void view_save_txt_cb(CALLBACK_ARGS)
{
_view_save_as((int)(long)data, "Save As Text", 4);
}
void view_save_msh_cb(CALLBACK_ARGS)
{
_view_save_as((int)(long)data, "Save As Mesh", 5);
}
void view_alias_cb(CALLBACK_ARGS)
{
AliasView((int)(long)data, 0);
Draw();
}
void view_alias_with_options_cb(CALLBACK_ARGS)
{
AliasView((int)(long)data, 1);
Draw();
}
void view_combine_space_all_cb(CALLBACK_ARGS)
{
CombineViews(0, 1, CTX.post.combine_remove_orig);
Draw();
}
void view_combine_space_visible_cb(CALLBACK_ARGS)
{
CombineViews(0, 0, CTX.post.combine_remove_orig);
Draw();
}
void view_combine_space_by_name_cb(CALLBACK_ARGS)
{
CombineViews(0, 2, CTX.post.combine_remove_orig);
Draw();
}
void view_combine_time_all_cb(CALLBACK_ARGS)
{
CombineViews(1, 1, CTX.post.combine_remove_orig);
Draw();
}
void view_combine_time_visible_cb(CALLBACK_ARGS)
{
CombineViews(1, 0, CTX.post.combine_remove_orig);
Draw();
}
void view_combine_time_by_name_cb(CALLBACK_ARGS)
{
CombineViews(1, 2, CTX.post.combine_remove_orig);
Draw();
}
void view_all_visible_cb(CALLBACK_ARGS)
{
for(int i = 0; i < List_Nbr(CTX.post.list); i ++)
opt_view_visible(i, GMSH_SET | GMSH_GUI,
(long)data < 0 ? !opt_view_visible(i, GMSH_GET, 0) :
(long)data > 0 ? 1 : 0);
Draw();
}
void view_applybgmesh_cb(CALLBACK_ARGS)
{
Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, (int)(long)data);
if(!v->ScalarOnly || v->TextOnly) {
Msg(GERROR, "Background mesh generation impossible with non-scalar view");
return;
}
BGMWithView(v);
}
void view_plugin_cancel_cb(CALLBACK_ARGS)
{
if(data)
((Fl_Window *) data)->hide();
if(CTX.post.plugin_draw_function){
CTX.post.plugin_draw_function = NULL;
Draw();
}
}
void view_plugin_run_cb(CALLBACK_ARGS)
{
GMSH_Post_Plugin *p = (GMSH_Post_Plugin *) data;
char name[256];
p->getName(name);
int iView;
if(p->dialogBox) { // get the values from the GUI
iView = p->dialogBox->current_view_index;
int m = p->getNbOptionsStr();
int n = p->getNbOptions();
if(m > MAX_PLUGIN_OPTIONS) m = MAX_PLUGIN_OPTIONS;
if(n > MAX_PLUGIN_OPTIONS) n = MAX_PLUGIN_OPTIONS;
for(int i = 0; i < m; i++) {
StringXString *sxs = p->getOptionStr(i);
sxs->def = (char*)p->dialogBox->input[i]->value();
}
for(int i = 0; i < n; i++) {
StringXNumber *sxn = p->getOption(i);
sxn->def = p->dialogBox->value[i]->value();
}
}
else
iView = 0;
try {
Post_View **vv = (Post_View **) List_Pointer_Test(CTX.post.list, iView);
if(!vv)
p->execute(0);
else
p->execute(*vv);
CTX.post.plugin_draw_function = NULL;
Draw();
}
catch(GMSH_Plugin * err) {
p->catchErrorMessage(name);
Msg(WARNING, "%s", name);
}
}
void view_plugin_input_value_cb(CALLBACK_ARGS)
{
double (*f)(int, int, double) = (double (*)(int, int, double)) data;
Fl_Value_Input *input = (Fl_Value_Input*) w;
f(-1, 0, input->value());
}
void view_plugin_input_cb(CALLBACK_ARGS)
{
char* (*f)(int, int, char*) = (char* (*)(int, int, char*)) data;
Fl_Input *input = (Fl_Input*) w;
f(-1, 0, (char*)input->value());
}
void view_plugin_options_cb(CALLBACK_ARGS)
{
std::pair<int, GMSH_Plugin *> *pair = (std::pair<int, GMSH_Plugin *>*) data;
int iView = pair->first;
GMSH_Plugin *p = pair->second;
if(!p->dialogBox)
p->dialogBox = WID->create_plugin_window(p);
p->dialogBox->current_view_index = iView;
p->dialogBox->run_button->callback(view_plugin_run_cb, (void *)p);
// configure the input value fields (we get step, min and max by
// calling the option function with action==1, 2 and 3,
// respectively) and set the Fl_Value_Input callbacks
int n = p->getNbOptions();
if(n > MAX_PLUGIN_OPTIONS) n = MAX_PLUGIN_OPTIONS;
for(int i = 0; i < n; i++) {
StringXNumber *sxn = p->getOption(i);
if(sxn->function){
p->dialogBox->value[i]->callback(view_plugin_input_value_cb, (void*)sxn->function);
p->dialogBox->value[i]->step(sxn->function(iView, 1, 0.));
p->dialogBox->value[i]->minimum(sxn->function(iView, 2, 0.));
p->dialogBox->value[i]->maximum(sxn->function(iView, 3, 0.));
}
}
// set the Fl_Input callbacks
int m = p->getNbOptionsStr();
if(m > MAX_PLUGIN_OPTIONS) m = MAX_PLUGIN_OPTIONS;
for(int i = 0; i < m; i++) {
StringXString *sxs = p->getOptionStr(i);
if(sxs->function){
p->dialogBox->input[i]->callback(view_plugin_input_cb, (void*)sxs->function);
}
}
p->dialogBox->main_window->show();
}
// Contextual windows for geometry
void con_geometry_define_parameter_cb(CALLBACK_ARGS)
{
add_param((char *)WID->context_geometry_input[0]->value(),
(char *)WID->context_geometry_input[1]->value(), CTX.filename);
WID->reset_visibility();
}
void con_geometry_define_point_cb(CALLBACK_ARGS)
{
add_point(CTX.filename,
(char*)WID->context_geometry_input[2]->value(),
(char*)WID->context_geometry_input[3]->value(),
(char*)WID->context_geometry_input[4]->value(),
(char*)WID->context_geometry_input[5]->value());
WID->reset_visibility();
ZeroHighlight();
SetBoundingBox();
Draw();
}
void con_geometry_snap_cb(CALLBACK_ARGS)
{
CTX.geom.snap[0] = WID->context_geometry_value[0]->value();
CTX.geom.snap[1] = WID->context_geometry_value[1]->value();
CTX.geom.snap[2] = WID->context_geometry_value[2]->value();
}