From 5897f45db7bbcd79601c2b2a1c6464f3a5691cf3 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Mon, 1 Dec 2008 23:25:28 +0000 Subject: [PATCH] Third phase of code refactoring: move callbacks where they belong & drastically reduce namespace pollution. There's no new functionality for now: PLEASE TEST THAT EVERYTHING WORKS AS IT USED TO BEFORE. --- Common/Makefile | 2 +- Common/Options.cpp | 27 +- Common/StringUtils.cpp | 28 + Common/StringUtils.h | 1 + Fltk/Callbacks.cpp | 4728 --------------------------------- Fltk/Callbacks.h | 258 -- Fltk/GUI.cpp | 94 +- Fltk/GUI.h | 5 + Fltk/Makefile | 211 +- Fltk/aboutWindow.cpp | 20 +- Fltk/classificationEditor.cpp | 551 ++-- Fltk/classificationEditor.h | 10 +- Fltk/clippingWindow.cpp | 133 +- Fltk/clippingWindow.h | 2 + Fltk/contextWindow.cpp | 36 +- Fltk/extraDialogs.cpp | 8 +- Fltk/fieldWindow.cpp | 120 +- Fltk/fieldWindow.h | 2 + Fltk/fileDialogs.cpp | 159 +- Fltk/graphicWindow.cpp | 175 +- Fltk/graphicWindow.h | 3 + Fltk/manipWindow.cpp | 26 +- Fltk/manipWindow.h | 2 + Fltk/menuWindow.cpp | 2120 ++++++++++++++- Fltk/menuWindow.h | 12 + Fltk/messageWindow.cpp | 60 +- Fltk/messageWindow.h | 2 + Fltk/optionWindow.cpp | 1254 ++++++++- Fltk/optionWindow.h | 10 + Fltk/pluginWindow.cpp | 148 +- Fltk/pluginWindow.h | 2 + Fltk/projectionEditor.cpp | 1030 +++---- Fltk/projectionEditor.h | 23 +- Fltk/solverWindow.cpp | 173 +- Fltk/solverWindow.h | 2 + Fltk/statisticsWindow.cpp | 63 +- Fltk/statisticsWindow.h | 2 + Fltk/visibilityWindow.cpp | 391 ++- Fltk/visibilityWindow.h | 2 + doc/texinfo/gmsh.texi | 6 +- 40 files changed, 5851 insertions(+), 6050 deletions(-) delete mode 100644 Fltk/Callbacks.cpp delete mode 100644 Fltk/Callbacks.h diff --git a/Common/Makefile b/Common/Makefile index cfe0ca46aa..fc4082844c 100644 --- a/Common/Makefile +++ b/Common/Makefile @@ -167,7 +167,7 @@ SmoothData${OBJEXT}: SmoothData.cpp SmoothData.h ../Numeric/Numeric.h \ ../Numeric/NumericEmbedded.h Octree${OBJEXT}: Octree.cpp Octree.h OctreeInternals.h OctreeInternals${OBJEXT}: OctreeInternals.cpp GmshMessage.h OctreeInternals.h -StringUtils${OBJEXT}: StringUtils.cpp StringUtils.h +StringUtils${OBJEXT}: StringUtils.cpp StringUtils.h GmshMessage.h ListUtils${OBJEXT}: ListUtils.cpp MallocUtils.h ListUtils.h TreeUtils.h avl.h \ GmshMessage.h TreeUtils${OBJEXT}: TreeUtils.cpp MallocUtils.h TreeUtils.h avl.h ListUtils.h diff --git a/Common/Options.cpp b/Common/Options.cpp index f126f5b3f8..c732125712 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -37,7 +37,6 @@ #include "messageWindow.h" #include "contextWindow.h" #include "clippingWindow.h" -extern void activate_cb(Fl_Widget* w, void* data); #endif // the single static option context @@ -3156,7 +3155,7 @@ double opt_general_fast_redraw(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(GUI::available() && (action & GMSH_GUI)){ GUI::instance()->options->general.butt[2]->value(CTX.fast_redraw); - activate_cb(NULL, (void*)"fast_redraw"); + GUI::instance()->options->activate("fast_redraw"); } #endif return CTX.fast_redraw; @@ -3220,7 +3219,7 @@ double opt_general_axes(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(GUI::available() && (action & GMSH_GUI)){ GUI::instance()->options->general.choice[4]->value(CTX.axes); - activate_cb(NULL, (void*)"general_axes"); + GUI::instance()->options->activate("general_axes"); } #endif return CTX.axes; @@ -3245,7 +3244,7 @@ double opt_general_axes_auto_position(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(GUI::available() && (action & GMSH_GUI)){ GUI::instance()->options->general.butt[0]->value(CTX.axes_auto_position); - activate_cb(NULL, (void*)"general_axes_auto"); + GUI::instance()->options->activate("general_axes_auto"); } #endif return CTX.axes_auto_position; @@ -3357,7 +3356,7 @@ double opt_general_small_axes(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(GUI::available() && (action & GMSH_GUI)){ GUI::instance()->options->general.butt[1]->value(CTX.small_axes); - activate_cb(NULL, (void*)"general_small_axes"); + GUI::instance()->options->activate("general_small_axes"); } #endif return CTX.small_axes; @@ -3568,7 +3567,7 @@ double opt_general_rotation_center_cg(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(GUI::available() && (action & GMSH_GUI)){ GUI::instance()->options->general.butt[15]->value(CTX.rotation_center_cg); - activate_cb(NULL, (void*)"rotation_center"); + GUI::instance()->options->activate("rotation_center"); } #endif return CTX.rotation_center_cg; @@ -3863,7 +3862,7 @@ double opt_general_clip_whole_elements(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(GUI::available() && (action & GMSH_GUI)){ GUI::instance()->clipping->butt[0]->value(CTX.clip_whole_elements); - activate_cb(NULL, (void*)"clip_whole_elements"); + GUI::instance()->options->activate("clip_whole_elements"); } #endif return CTX.clip_whole_elements; @@ -5097,7 +5096,7 @@ double opt_mesh_light(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(GUI::available() && (action & GMSH_GUI)){ GUI::instance()->options->mesh.butt[17]->value(CTX.mesh.light); - activate_cb(NULL, (void*)"mesh_light"); + GUI::instance()->options->activate("mesh_light"); } #endif return CTX.mesh.light; @@ -6675,7 +6674,7 @@ double opt_view_auto_position(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(_gui_action_valid(action, num)) { GUI::instance()->options->view.butt[7]->value(opt->AutoPosition); - activate_cb(NULL, (void*)"view_axes_auto_2d"); + GUI::instance()->options->activate("view_axes_auto_2d"); } #endif return opt->AutoPosition; @@ -6764,7 +6763,7 @@ double opt_view_axes(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(_gui_action_valid(action, num)) { GUI::instance()->options->view.choice[8]->value(opt->Axes); - activate_cb(NULL, (void*)"view_axes"); + GUI::instance()->options->activate("view_axes"); } #endif return opt->Axes; @@ -6800,7 +6799,7 @@ double opt_view_axes_auto_position(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(_gui_action_valid(action, num)) { GUI::instance()->options->view.butt[25]->value(opt->AxesAutoPosition); - activate_cb(NULL, (void*)"view_axes_auto_3d"); + GUI::instance()->options->activate("view_axes_auto_3d"); } #endif return opt->AxesAutoPosition; @@ -7021,7 +7020,7 @@ double opt_view_light(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(_gui_action_valid(action, num)){ GUI::instance()->options->view.butt[11]->value(opt->Light); - activate_cb(NULL, (void*)"view_light"); + GUI::instance()->options->activate("view_light"); } #endif return opt->Light; @@ -7465,7 +7464,7 @@ double opt_view_range_type(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(_gui_action_valid(action, num)){ GUI::instance()->options->view.choice[7]->value(opt->RangeType - 1); - activate_cb(NULL, (void*)"custom_range"); + GUI::instance()->options->activate("custom_range"); } #endif return opt->RangeType; @@ -7889,7 +7888,7 @@ double opt_view_use_gen_raise(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(_gui_action_valid(action, num)){ GUI::instance()->options->view.butt[6]->value(opt->UseGenRaise); - activate_cb(NULL, (void*)"general_transform"); + GUI::instance()->options->activate("general_transform"); } #endif return opt->UseGenRaise; diff --git a/Common/StringUtils.cpp b/Common/StringUtils.cpp index eb11528d6e..eaa3769be7 100644 --- a/Common/StringUtils.cpp +++ b/Common/StringUtils.cpp @@ -8,6 +8,7 @@ #endif #include "StringUtils.h" +#include "GmshMessage.h" void SwapBytes(char *array, int size, int n) { @@ -101,3 +102,30 @@ std::vector<std::string> SplitWhiteSpace(std::string in, unsigned int len) } return out; } + +void ReplaceMultiFormat(const char *in, const 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'; +} diff --git a/Common/StringUtils.h b/Common/StringUtils.h index 3883bbafec..e09f15553a 100644 --- a/Common/StringUtils.h +++ b/Common/StringUtils.h @@ -16,5 +16,6 @@ std::string SanitizeTeXString(const char *in, int equation); std::string FixWindowsPath(const char *in); void SplitFileName(const char *name, char *no_ext, char *ext, char *base); std::vector<std::string> SplitWhiteSpace(std::string in, unsigned int len); +void ReplaceMultiFormat(const char *in, const char *val, char *out); #endif diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp deleted file mode 100644 index b9a6249f3c..0000000000 --- a/Fltk/Callbacks.cpp +++ /dev/null @@ -1,4728 +0,0 @@ -// Gmsh - Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle -// -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. - -#include <string.h> -#include <signal.h> -#include <time.h> -#include <map> -#include <string> -#include <sstream> -#include <FL/fl_ask.H> -#include <FL/Fl_Color_Chooser.H> -#include "GUI.h" -#include "menuWindow.h" -#include "graphicWindow.h" -#include "optionWindow.h" -#include "visibilityWindow.h" -#include "clippingWindow.h" -#include "statisticsWindow.h" -#include "solverWindow.h" -#include "manipWindow.h" -#include "messageWindow.h" -#include "fieldWindow.h" -#include "pluginWindow.h" -#include "contextWindow.h" -#include "aboutWindow.h" -#include "partitionDialog.h" -#include "extraDialogs.h" -#include "fileDialogs.h" -#include "GmshMessage.h" -#include "MallocUtils.h" -#include "ListUtils.h" -#include "StringUtils.h" -#include "GModel.h" -#include "MElement.h" -#include "GeoStringInterface.h" -#include "findLinks.h" -#include "Generator.h" -#include "HighOrder.h" -#include "Draw.h" -#include "SelectBuffer.h" -#include "PView.h" -#include "PViewOptions.h" -#include "PViewData.h" -#include "CreateFile.h" -#include "OpenFile.h" -#include "CommandLine.h" -#include "Context.h" -#include "Options.h" -#include "Callbacks.h" -#include "Plugin.h" -#include "PluginManager.h" -#include "Visibility.h" -#include "Numeric.h" -#include "Solvers.h" -#include "OS.h" -#include "Field.h" -#include "BackgroundMesh.h" - -extern Context_T CTX; - -// Helper routines - -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(GUI::instance()->options->view.index, GMSH_GET, 0)); - uchar g = CTX.UNPACK_GREEN(fct(GUI::instance()->options->view.index, GMSH_GET, 0)); - uchar b = CTX.UNPACK_BLUE(fct(GUI::instance()->options->view.index, GMSH_GET, 0)); - if(fl_color_chooser("Color Chooser", r, g, b)) - fct(GUI::instance()->options->view.index, 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; - const char *str = (const char*)data; - - if(!strcmp(str, "minimize")){ - GUI::instance()->graph[0]->win->iconize(); - if(GUI::instance()->options->win->shown()) GUI::instance()->options->win->iconize(); - if(GUI::instance()->plugins->win->shown()) GUI::instance()->plugins->win->iconize(); - if(GUI::instance()->fields->win->shown()) GUI::instance()->fields->win->iconize(); - if(GUI::instance()->visibility->win->shown()) GUI::instance()->visibility->win->iconize(); - if(GUI::instance()->clipping->win->shown()) GUI::instance()->clipping->win->iconize(); - if(GUI::instance()->manip->win->shown()) GUI::instance()->manip->win->iconize(); - if(GUI::instance()->stats->win->shown()) GUI::instance()->stats->win->iconize(); - if(GUI::instance()->messages->win->shown()) GUI::instance()->messages->win->iconize(); - GUI::instance()->menu->win->iconize(); - } - else if(!strcmp(str, "zoom")){ - if(zoom){ - oldx = GUI::instance()->graph[0]->win->x(); - oldy = GUI::instance()->graph[0]->win->y(); - oldw = GUI::instance()->graph[0]->win->w(); - oldh = GUI::instance()->graph[0]->win->h(); - GUI::instance()->graph[0]->win->resize(Fl::x(), Fl::y(), Fl::w(), Fl::h()); - zoom = 0; - } - else{ - GUI::instance()->graph[0]->win->resize(oldx, oldy, oldw, oldh); - zoom = 1; - } - GUI::instance()->graph[0]->win->show(); - GUI::instance()->menu->win->show(); - } - else if(!strcmp(str, "front")){ - // the order is important! - GUI::instance()->graph[0]->win->show(); - if(GUI::instance()->options->win->shown()) GUI::instance()->options->win->show(); - if(GUI::instance()->plugins->win->shown()) GUI::instance()->plugins->win->show(); - if(GUI::instance()->fields->win->shown()) GUI::instance()->fields->win->show(); - if(GUI::instance()->geoContext->win->shown()) GUI::instance()->geoContext->win->show(); - if(GUI::instance()->meshContext->win->shown()) GUI::instance()->meshContext->win->show(); - for(unsigned int i = 0; i < GUI::instance()->solver.size(); i++) { - if(GUI::instance()->solver[i]->win->shown()) GUI::instance()->solver[i]->win->show(); - } - if(GUI::instance()->visibility->win->shown()) GUI::instance()->visibility->win->show(); - if(GUI::instance()->clipping->win->shown()) GUI::instance()->clipping->win->show(); - if(GUI::instance()->manip->win->shown()) GUI::instance()->manip->win->show(); - if(GUI::instance()->stats->win->shown()) GUI::instance()->stats->win->show(); - if(GUI::instance()->messages->win->shown()) GUI::instance()->messages->win->show(); - GUI::instance()->menu->win->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; - - optionWindow *o = GUI::instance()->options; - - const char *str = (const char*)data; - - if(!strcmp(str, "fast_redraw")){ - if(o->general.butt[2]->value()) - GUI::instance()->options->redraw->show(); - else - GUI::instance()->options->redraw->hide(); - } - else if(!strcmp(str, "rotation_center")){ - if(o->general.butt[15]->value()) { - o->general.push[0]->deactivate(); - o->general.value[8]->deactivate(); - o->general.value[9]->deactivate(); - o->general.value[10]->deactivate(); - } - else { - o->general.push[0]->activate(); - o->general.value[8]->activate(); - o->general.value[9]->activate(); - o->general.value[10]->activate(); - } - } - else if(!strcmp(str, "general_axes")){ - if(o->general.choice[4]->value()){ - o->general.value[17]->activate(); - o->general.value[18]->activate(); - o->general.value[19]->activate(); - o->general.input[3]->activate(); - o->general.input[4]->activate(); - o->general.input[5]->activate(); - o->general.input[6]->activate(); - o->general.input[7]->activate(); - o->general.input[8]->activate(); - } - else{ - o->general.value[17]->deactivate(); - o->general.value[18]->deactivate(); - o->general.value[19]->deactivate(); - o->general.input[3]->deactivate(); - o->general.input[4]->deactivate(); - o->general.input[5]->deactivate(); - o->general.input[6]->deactivate(); - o->general.input[7]->deactivate(); - o->general.input[8]->deactivate(); - } - } - else if(!strcmp(str, "general_axes_auto")){ - if(o->general.butt[0]->value()){ - o->general.value[20]->deactivate(); - o->general.value[21]->deactivate(); - o->general.value[22]->deactivate(); - o->general.value[23]->deactivate(); - o->general.value[24]->deactivate(); - o->general.value[25]->deactivate(); - } - else{ - o->general.value[20]->activate(); - o->general.value[21]->activate(); - o->general.value[22]->activate(); - o->general.value[23]->activate(); - o->general.value[24]->activate(); - o->general.value[25]->activate(); - } - } - else if(!strcmp(str, "general_small_axes")){ - if(o->general.butt[1]->value()){ - o->general.value[26]->activate(); - o->general.value[27]->activate(); - } - else{ - o->general.value[26]->deactivate(); - o->general.value[27]->deactivate(); - } - } - else if(!strcmp(str, "custom_range")){ - if(o->view.choice[7]->value() == 1){ - o->view.value[31]->activate(); - o->view.value[32]->activate(); - o->view.push[1]->activate(); - o->view.push[2]->activate(); - } - else { - o->view.value[31]->deactivate(); - o->view.value[32]->deactivate(); - o->view.push[1]->deactivate(); - o->view.push[2]->deactivate(); - } - } - else if(!strcmp(str, "general_transform")){ - if(o->view.butt[6]->value()){ - o->view.choice[11]->activate(); - o->view.value[2]->activate(); - o->view.input[4]->activate(); - o->view.input[5]->activate(); - o->view.input[6]->activate(); - } - else{ - o->view.choice[11]->deactivate(); - o->view.value[2]->deactivate(); - o->view.input[4]->deactivate(); - o->view.input[5]->deactivate(); - o->view.input[6]->deactivate(); - } - } - else if(!strcmp(str, "mesh_light")){ - if(o->mesh.butt[17]->value()){ - o->mesh.butt[18]->activate(); - o->mesh.butt[19]->activate(); - o->mesh.butt[20]->activate(); - o->mesh.butt[0]->activate(); - o->mesh.value[18]->activate(); - } - else{ - o->mesh.butt[18]->deactivate(); - o->mesh.butt[19]->deactivate(); - o->mesh.butt[20]->deactivate(); - o->mesh.butt[0]->deactivate(); - o->mesh.value[18]->deactivate(); - } - } - else if(!strcmp(str, "view_light")){ - if(o->view.butt[11]->value()){ - o->view.butt[8]->activate(); - o->view.butt[9]->activate(); - o->view.butt[12]->activate(); - o->view.value[10]->activate(); - } - else{ - o->view.butt[8]->deactivate(); - o->view.butt[9]->deactivate(); - o->view.butt[12]->deactivate(); - o->view.value[10]->deactivate(); - } - } - else if(!strcmp(str, "view_axes")){ - if(o->view.choice[8]->value()){ - o->view.value[3]->activate(); - o->view.value[4]->activate(); - o->view.value[5]->activate(); - o->view.input[7]->activate(); - o->view.input[8]->activate(); - o->view.input[9]->activate(); - o->view.input[10]->activate(); - o->view.input[11]->activate(); - o->view.input[12]->activate(); - } - else{ - o->view.value[3]->deactivate(); - o->view.value[4]->deactivate(); - o->view.value[5]->deactivate(); - o->view.input[7]->deactivate(); - o->view.input[8]->deactivate(); - o->view.input[9]->deactivate(); - o->view.input[10]->deactivate(); - o->view.input[11]->deactivate(); - o->view.input[12]->deactivate(); - } - } - else if(!strcmp(str, "view_axes_auto_3d")){ - if(o->view.butt[25]->value()){ - o->view.value[13]->deactivate(); - o->view.value[14]->deactivate(); - o->view.value[15]->deactivate(); - o->view.value[16]->deactivate(); - o->view.value[17]->deactivate(); - o->view.value[18]->deactivate(); - } - else{ - o->view.value[13]->activate(); - o->view.value[14]->activate(); - o->view.value[15]->activate(); - o->view.value[16]->activate(); - o->view.value[17]->activate(); - o->view.value[18]->activate(); - } - } - else if(!strcmp(str, "view_axes_auto_2d")){ - if(o->view.butt[7]->value()){ - o->view.value[20]->deactivate(); - o->view.value[21]->deactivate(); - o->view.value[22]->deactivate(); - o->view.value[23]->deactivate(); - } - else{ - o->view.value[20]->activate(); - o->view.value[21]->activate(); - o->view.value[22]->activate(); - o->view.value[23]->activate(); - } - } -} - -// Graphical window - -void status_xyz1p_cb(CALLBACK_ARGS) -{ - const char *str = (const char*)data; - - drawContext *ctx = GUI::instance()->graph[0]->gl->getDrawContext(); - - 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, "model")){ // toggle projection mode - model_chooser(); - } - else if(!strcmp(str, "?")){ // display options - Print_Options(0, GMSH_FULLRC, 0, 1, NULL); - GUI::instance()->messages->show(); - } - else if(!strcmp(str, "S")){ // mouse selection - if(CTX.mouse_selection){ - opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 0); - GUI::instance()->graph[0]->gl->cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE); - } - else - opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 1); - } - GUI::instance()->manip->update(); -} - -static int stop_anim, view_in_cycle = -1; - -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) - static bool busy = false; - if(busy) return; - busy = true; - if(time) { - for(unsigned int i = 0; i < PView::list.size(); 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) >= (int)PView::list.size()) - view_in_cycle = 0; - for(int i = 0; i < (int)PView::list.size(); i += step) - opt_view_visible(i, GMSH_SET | GMSH_GUI, (i == view_in_cycle)); - } - else { - if((view_in_cycle += step) < 0) - view_in_cycle = PView::list.size() - 1; - for(int i = PView::list.size() - 1; i >= 0; i += step) - opt_view_visible(i, GMSH_SET | GMSH_GUI, (i == view_in_cycle)); - } - } - Draw(); - busy = false; -} - -void status_play_cb(CALLBACK_ARGS) -{ - static double anim_time; - GUI::instance()->graph[0]->setAnimButtons(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); - } - GUI::instance()->check(); - } -} - -void status_pause_cb(CALLBACK_ARGS) -{ - stop_anim = 1; - GUI::instance()->graph[0]->setAnimButtons(1); -} - -void status_rewind_cb(CALLBACK_ARGS) -{ - if(!CTX.post.anim_cycle) { - for(unsigned int i = 0; i < PView::list.size(); i++) - opt_view_timestep(i, GMSH_SET | GMSH_GUI, 0); - } - else { - view_in_cycle = 0; - for(unsigned int i = 0; i < PView::list.size(); i++) - opt_view_visible(i, GMSH_SET | GMSH_GUI, !i); - } - Draw(); -} - -void status_stepbackward_cb(CALLBACK_ARGS) -{ - ManualPlay(!CTX.post.anim_cycle, -1); -} - -void status_stepforward_cb(CALLBACK_ARGS) -{ - ManualPlay(!CTX.post.anim_cycle, 1); -} - -// File Menu - -void file_new_cb(CALLBACK_ARGS) -{ - test: - if(file_chooser(0, 1, "New", "*")) { - std::string name = file_chooser_get_name(1); - if(!StatFile(name.c_str())){ - if(fl_choice("File '%s' already exists.\n\nDo you want to erase it?", - "Cancel", "Erase", NULL, name.c_str())) - UnlinkFile(name.c_str()); - else - goto test; - } - FILE *fp = fopen(name.c_str(), "w"); - if(!fp){ - Msg::Error("Unable to open file '%s'", name.c_str()); - return; - } - time_t now; - time(&now); - fprintf(fp, "// Gmsh project created on %s", ctime(&now)); - fclose(fp); - OpenProject(name.c_str()); - Draw(); - } -} - -#if defined(HAVE_NATIVE_FILE_CHOOSER) -# define TT "\t" -# define NN "\n" -#else -# define TT " (" -# define NN ")\t" -#endif - -static const char *input_formats = - "All files" TT "*" NN - "Gmsh geometry" TT "*.geo" NN - "Gmsh mesh" TT "*.msh" NN - "Gmsh post-processing view" TT "*.pos" NN -#if defined(HAVE_OCC) - "STEP model" TT "*.{stp,step}" NN - "IGES model" TT "*.{igs,iges}" NN - "BRep model" TT "*.brep" NN -#endif - "I-deas universal mesh" TT "*.unv" NN - "Diffpack 3D mesh" TT "*.diff" NN - "VTK mesh" TT "*.vtk" NN -#if defined(HAVE_MED) - "MED file" TT "*.{med,mmed,rmed}" NN -#endif - "Medit mesh" TT "*.mesh" NN - "Nastran bulk data file" TT "*.{bdf,nas}" NN - "Plot3D structured mesh" TT "*.p3d" NN - "STL surface mesh" TT "*.stl" NN - "VRML surface mesh" TT "*.{wrl,vrml}" NN -#if defined(HAVE_LIBJPEG) - "JPEG" TT "*.{jpg,jpeg}" NN -#endif -#if defined(HAVE_LIBPNG) - "PNG" TT "*.png" NN -#endif - "BMP" TT "*.bmp" NN - "PPM" TT "*.ppm" NN - "PGM" TT "*.pgm" NN - "PBM" TT "*.pbm" NN - "PNM" TT "*.pnm" NN; - -#undef TT -#undef NN - - -void file_open_cb(CALLBACK_ARGS) -{ - int n = PView::list.size(); - if(file_chooser(0, 0, "Open", input_formats)) { - OpenProject(file_chooser_get_name(1).c_str()); - Draw(); - } - if(n != (int)PView::list.size()) - GUI::instance()->menu->setContext(menu_post, 0); -} - -void file_merge_cb(CALLBACK_ARGS) -{ - int n = PView::list.size(); - int f = file_chooser(1, 0, "Merge", input_formats); - if(f) { - for(int i = 1; i <= f; i++) - MergeFile(file_chooser_get_name(i).c_str()); - Draw(); - } - if(n != (int)PView::list.size()) - GUI::instance()->menu->setContext(menu_post, 0); -} - -int _save_msh(const char *name){ return msh_dialog(name); } -int _save_pos(const char *name){ return pos_dialog(name); } -int _save_options(const char *name){ return options_dialog(name); } -int _save_geo(const char *name){ return geo_dialog(name); } -int _save_cgns(const char *name){ return cgns_write_dialog(name); } -int _save_unv(const char *name){ return unv_dialog(name); } -int _save_vtk(const char *name){ return generic_mesh_dialog(name, "VTK Options", FORMAT_VTK, true); } -int _save_diff(const char *name){ return generic_mesh_dialog(name, "Diffpack Options", FORMAT_DIFF, true); } -int _save_med(const char *name){ return generic_mesh_dialog(name, "MED Options", FORMAT_MED, false); } -int _save_mesh(const char *name){ return generic_mesh_dialog(name, "MESH Options", FORMAT_MESH, false); } -int _save_bdf(const char *name){ return bdf_dialog(name); } -int _save_p3d(const char *name){ return generic_mesh_dialog(name, "P3D Options", FORMAT_P3D, false); } -int _save_stl(const char *name){ return generic_mesh_dialog(name, "STL Options", FORMAT_STL, true); } -int _save_vrml(const char *name){ return generic_mesh_dialog(name, "VRML Options", FORMAT_VRML, false); } -int _save_eps(const char *name){ return gl2ps_dialog(name, "EPS Options", FORMAT_EPS); } -int _save_gif(const char *name){ return gif_dialog(name); } -int _save_jpeg(const char *name){ return jpeg_dialog(name); } -int _save_tex(const char *name){ return latex_dialog(name); } -int _save_pdf(const char *name){ return gl2ps_dialog(name, "PDF Options", FORMAT_PDF); } -int _save_png(const char *name){ return generic_bitmap_dialog(name, "PNG Options", FORMAT_PNG); } -int _save_ps(const char *name){ return gl2ps_dialog(name, "PS Options", FORMAT_PS); } -int _save_ppm(const char *name){ return generic_bitmap_dialog(name, "PPM Options", FORMAT_PPM); } -int _save_svg(const char *name){ return gl2ps_dialog(name, "SVG Options", FORMAT_SVG); } -int _save_yuv(const char *name){ return generic_bitmap_dialog(name, "YUV Options", FORMAT_YUV); } - -int _save_auto(const 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_CGNS : return _save_cgns(name); - case FORMAT_UNV : return _save_unv(name); - case FORMAT_VTK : return _save_vtk(name); - case FORMAT_MED : return _save_med(name); - case FORMAT_MESH : return _save_mesh(name); - case FORMAT_BDF : return _save_bdf(name); - case FORMAT_DIFF : return _save_diff(name); - case FORMAT_P3D : return _save_p3d(name); - case FORMAT_STL : return _save_stl(name); - case FORMAT_VRML : return _save_vrml(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{ - const char *pat; - int (*func) (const char *name); -} patXfunc; - -void file_save_as_cb(CALLBACK_ARGS) -{ -#if defined(HAVE_NATIVE_FILE_CHOOSER) -# define TT "\t" -# define NN "\n" -#else -# define TT " (" -# define NN ")\t" -#endif - - static patXfunc formats[] = { - {"Guess from extension" TT "*.*", _save_auto}, - {"Gmsh mesh" TT "*.msh", _save_msh}, - {"Gmsh mesh statistics" TT "*.pos", _save_pos}, - {"Gmsh options" TT "*.opt", _save_options}, - {"Gmsh unrolled geometry" TT "*.geo", _save_geo}, -#if defined(HAVE_LIBCGNS) - {"CGNS" TT "*.cgns", _save_cgns}, -#endif - {"I-deas universal mesh" TT "*.unv", _save_unv}, - {"Diffpack 3D mesh" TT "*.diff", _save_diff}, - {"VTK mesh" TT "*.vtk", _save_vtk}, -#if defined(HAVE_MED) - {"MED file" TT "*.med", _save_med}, -#endif - {"Medit mesh" TT "*.mesh", _save_mesh}, - {"Nastran bulk data file" TT "*.bdf", _save_bdf}, - {"Plot3D structured mesh" TT "*.p3d", _save_p3d}, - {"STL surface mesh" TT "*.stl", _save_stl}, - {"VRML surface mesh" TT "*.wrl", _save_vrml}, - {"Encapsulated PostScript" TT "*.eps", _save_eps}, - {"GIF" TT "*.gif", _save_gif}, -#if defined(HAVE_LIBJPEG) - {"JPEG" TT "*.jpg", _save_jpeg}, -#endif - {"LaTeX" TT "*.tex", _save_tex}, - {"PDF" TT "*.pdf", _save_pdf}, -#if defined(HAVE_LIBPNG) - {"PNG" TT "*.png", _save_png}, -#endif - {"PostScript" TT "*.ps", _save_ps}, - {"PPM" TT "*.ppm", _save_ppm}, - {"SVG" TT "*.svg", _save_svg}, - {"YUV" TT "*.yuv", _save_yuv}, - }; - - int nbformats = sizeof(formats) / sizeof(formats[0]); - static char *pat = NULL; - if(!pat) { - pat = (char *)Malloc(nbformats * 256 * sizeof(char)); - strcpy(pat, formats[0].pat); - for(int i = 1; i < nbformats; i++) { - strcat(pat, NN); - strcat(pat, formats[i].pat); - } - } - -#undef TT -#undef NN - - test: - if(file_chooser(0, 1, "Save As", pat)) { - std::string name = file_chooser_get_name(1); - if(CTX.confirm_overwrite) { - if(!StatFile(name.c_str())) - if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", - "Cancel", "Replace", NULL, name.c_str())) - goto test; - } - int i = file_chooser_get_filter(); - if(i >= 0 && i < nbformats){ - if(!formats[i].func(name.c_str())) goto test; - } - else{ // handle any additional automatic fltk filter - if(!_save_auto(name.c_str())) goto test; - } - } -} - -void file_rename_cb(CALLBACK_ARGS) -{ - test: - if(file_chooser(0, 1, "Rename", "*", CTX.filename)) { - std::string name = file_chooser_get_name(1); - if(CTX.confirm_overwrite) { - if(!StatFile(name.c_str())) - if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", - "Cancel", "Replace", NULL, name.c_str())) - goto test; - } - rename(CTX.filename, name.c_str()); - OpenProject(name.c_str()); - Draw(); - } -} - -void file_quit_cb(CALLBACK_ARGS) -{ - Msg::Exit(0); -} - -// Option Menu - -void options_cb(CALLBACK_ARGS) -{ - GUI::instance()->options->win->show(); -} - -void options_browser_cb(CALLBACK_ARGS) -{ - GUI::instance()->options->showGroup(GUI::instance()->options->browser->value()); -} - -void options_save_cb(CALLBACK_ARGS) -{ - Msg::StatusBar(2, true, "Writing '%s'", CTX.options_filename_fullpath); - Print_Options(0, GMSH_OPTIONSRC, 1, 1, CTX.options_filename_fullpath); - Msg::StatusBar(2, true, "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(GUI::instance()->menu->module->value() == 3) // hack to refresh the buttons - GUI::instance()->menu->setContext(menu_post, 0); - Draw(); -} - -// General options - -void general_options_cb(CALLBACK_ARGS) -{ - GUI::instance()->options->showGroup(1); -} - -void general_options_color_scheme_cb(CALLBACK_ARGS) -{ - opt_general_color_scheme(0, GMSH_SET, GUI::instance()->options->general.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::StatusBar(3, false, "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, GUI::instance()->options->general.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::StatusBar(3, false, ""); -} - -void general_options_ok_cb(CALLBACK_ARGS) -{ - activate_cb(NULL, data); - - optionWindow *o = GUI::instance()->options; - - static double lc = 0.; - if(lc != CTX.lc){ - lc = CTX.lc; - for(int i = 2; i < 5; i++){ - o->general.value[i]->minimum(-5 * CTX.lc); - o->general.value[i]->maximum(5 * CTX.lc); - } - } - if(data){ - const char *name = (const char*)data; - if(!strcmp(name, "rotation_center_coord")){ - CTX.draw_rotation_center = 1; - } - else if(!strcmp(name, "light_value")){ - double x, y, z; - x = o->general.value[2]->value(); - y = o->general.value[3]->value(); - z = o->general.value[4]->value(); - o->general.sphere->setValue(x, y, z); - } - else if(!strcmp(name, "light_sphere")){ - double x, y, z; - o->general.sphere->getValue(x, y, z); - o->general.value[2]->value(x); - o->general.value[3]->value(y); - o->general.value[4]->value(z); - } - } - - opt_general_axes_auto_position(0, GMSH_SET, o->general.butt[0]->value()); - opt_general_small_axes(0, GMSH_SET, o->general.butt[1]->value()); - opt_general_fast_redraw(0, GMSH_SET, o->general.butt[2]->value()); - opt_general_mouse_hover_meshes(0, GMSH_SET, o->general.butt[11]->value()); - if(opt_general_double_buffer(0, GMSH_GET, 0) != o->general.butt[3]->value()) - opt_general_double_buffer(0, GMSH_SET, o->general.butt[3]->value()); - if(opt_general_antialiasing(0, GMSH_GET, 0) != o->general.butt[12]->value()) - opt_general_antialiasing(0, GMSH_SET, o->general.butt[12]->value()); - opt_general_trackball(0, GMSH_SET, o->general.butt[5]->value()); - opt_general_terminal(0, GMSH_SET, o->general.butt[7]->value()); - double sessionrc = opt_general_session_save(0, GMSH_GET, 0); - opt_general_session_save(0, GMSH_SET, o->general.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, o->general.butt[9]->value()); - opt_general_expert_mode(0, GMSH_SET, o->general.butt[10]->value()); - opt_general_tooltips(0, GMSH_SET, o->general.butt[13]->value()); - opt_general_confirm_overwrite(0, GMSH_SET, o->general.butt[14]->value()); - opt_general_rotation_center_cg(0, GMSH_SET, o->general.butt[15]->value()); - opt_general_draw_bounding_box(0, GMSH_SET, o->general.butt[6]->value()); - opt_general_polygon_offset_always(0, GMSH_SET, o->general.butt[4]->value()); - opt_general_axes_mikado(0, GMSH_SET, o->general.butt[16]->value()); - - opt_general_shine_exponent(0, GMSH_SET, o->general.value[0]->value()); - opt_general_shine(0, GMSH_SET, o->general.value[1]->value()); - opt_general_light00(0, GMSH_SET, o->general.value[2]->value()); - opt_general_light01(0, GMSH_SET, o->general.value[3]->value()); - opt_general_light02(0, GMSH_SET, o->general.value[4]->value()); - opt_general_light03(0, GMSH_SET, o->general.value[13]->value()); - opt_general_verbosity(0, GMSH_SET, o->general.value[5]->value()); - opt_general_point_size(0, GMSH_SET, o->general.value[6]->value()); - opt_general_line_width(0, GMSH_SET, o->general.value[7]->value()); - opt_general_rotation_center0(0, GMSH_SET, o->general.value[8]->value()); - opt_general_rotation_center1(0, GMSH_SET, o->general.value[9]->value()); - opt_general_rotation_center2(0, GMSH_SET, o->general.value[10]->value()); - opt_general_quadric_subdivisions(0, GMSH_SET, o->general.value[11]->value()); - opt_general_graphics_fontsize(0, GMSH_SET, o->general.value[12]->value()); - opt_general_clip_factor(0, GMSH_SET, o->general.value[14]->value()); - opt_general_polygon_offset_factor(0, GMSH_SET, o->general.value[15]->value()); - opt_general_polygon_offset_units(0, GMSH_SET, o->general.value[16]->value()); - opt_general_axes_tics0(0, GMSH_SET, o->general.value[17]->value()); - opt_general_axes_tics1(0, GMSH_SET, o->general.value[18]->value()); - opt_general_axes_tics2(0, GMSH_SET, o->general.value[19]->value()); - opt_general_axes_xmin(0, GMSH_SET, o->general.value[20]->value()); - opt_general_axes_ymin(0, GMSH_SET, o->general.value[21]->value()); - opt_general_axes_zmin(0, GMSH_SET, o->general.value[22]->value()); - opt_general_axes_xmax(0, GMSH_SET, o->general.value[23]->value()); - opt_general_axes_ymax(0, GMSH_SET, o->general.value[24]->value()); - opt_general_axes_zmax(0, GMSH_SET, o->general.value[25]->value()); - opt_general_small_axes_position0(0, GMSH_SET, o->general.value[26]->value()); - opt_general_small_axes_position1(0, GMSH_SET, o->general.value[27]->value()); - - opt_general_default_filename(0, GMSH_SET, o->general.input[0]->value()); - opt_general_editor(0, GMSH_SET, o->general.input[1]->value()); - opt_general_web_browser(0, GMSH_SET, o->general.input[2]->value()); - opt_general_axes_format0(0, GMSH_SET, o->general.input[3]->value()); - opt_general_axes_format1(0, GMSH_SET, o->general.input[4]->value()); - opt_general_axes_format2(0, GMSH_SET, o->general.input[5]->value()); - opt_general_axes_label0(0, GMSH_SET, o->general.input[6]->value()); - opt_general_axes_label1(0, GMSH_SET, o->general.input[7]->value()); - opt_general_axes_label2(0, GMSH_SET, o->general.input[8]->value()); - - opt_general_vector_type(0, GMSH_SET, o->general.choice[0]->value() + 1); - opt_general_graphics_font(0, GMSH_SET, o->general.choice[1]->text()); - opt_general_orthographic(0, GMSH_SET, !o->general.choice[2]->value()); - opt_general_axes(0, GMSH_SET, o->general.choice[4]->value()); - opt_general_background_gradient(0, GMSH_SET, o->general.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) -{ - GUI::instance()->options->showGroup(2); -} - -void geometry_options_ok_cb(CALLBACK_ARGS) -{ - activate_cb(NULL, data); - - optionWindow *o = GUI::instance()->options; - - opt_geometry_points(0, GMSH_SET, o->geo.butt[0]->value()); - opt_geometry_lines(0, GMSH_SET, o->geo.butt[1]->value()); - opt_geometry_surfaces(0, GMSH_SET, o->geo.butt[2]->value()); - opt_geometry_volumes(0, GMSH_SET, o->geo.butt[3]->value()); - opt_geometry_points_num(0, GMSH_SET, o->geo.butt[4]->value()); - opt_geometry_lines_num(0, GMSH_SET, o->geo.butt[5]->value()); - opt_geometry_surfaces_num(0, GMSH_SET, o->geo.butt[6]->value()); - opt_geometry_volumes_num(0, GMSH_SET, o->geo.butt[7]->value()); - opt_geometry_auto_coherence(0, GMSH_SET, o->geo.butt[8]->value()); - opt_geometry_light(0, GMSH_SET, o->geo.butt[9]->value()); - opt_geometry_highlight_orphans(0, GMSH_SET, o->geo.butt[10]->value()); - opt_geometry_occ_fix_small_edges(0, GMSH_SET, o->geo.butt[11]->value()); - opt_geometry_occ_fix_small_faces(0, GMSH_SET, o->geo.butt[12]->value()); - opt_geometry_occ_sew_faces(0, GMSH_SET, o->geo.butt[13]->value()); - opt_geometry_light_two_side(0, GMSH_SET, o->geo.butt[14]->value()); - - opt_geometry_normals(0, GMSH_SET, o->geo.value[0]->value()); - opt_geometry_tangents(0, GMSH_SET, o->geo.value[1]->value()); - opt_geometry_tolerance(0, GMSH_SET, o->geo.value[2]->value()); - opt_geometry_point_size(0, GMSH_SET, o->geo.value[3]->value()); - opt_geometry_line_width(0, GMSH_SET, o->geo.value[4]->value()); - opt_geometry_point_sel_size(0, GMSH_SET, o->geo.value[5]->value()); - opt_geometry_line_sel_width(0, GMSH_SET, o->geo.value[6]->value()); - - opt_geometry_point_type(0, GMSH_SET, o->geo.choice[0]->value()); - opt_geometry_line_type(0, GMSH_SET, o->geo.choice[1]->value()); - opt_geometry_surface_type(0, GMSH_SET, o->geo.choice[2]->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) -{ - GUI::instance()->options->showGroup(3); -} - -void mesh_options_ok_cb(CALLBACK_ARGS) -{ - activate_cb(NULL, data); - - optionWindow *o = GUI::instance()->options; - - opt_mesh_reverse_all_normals(0, GMSH_SET, o->mesh.butt[0]->value()); - opt_mesh_lc_from_curvature(0, GMSH_SET, o->mesh.butt[1]->value()); - opt_mesh_lc_from_points(0, GMSH_SET, o->mesh.butt[5]->value()); - opt_mesh_lc_extend_from_boundary(0, GMSH_SET, o->mesh.butt[16]->value()); - opt_mesh_optimize(0, GMSH_SET, o->mesh.butt[2]->value()); - opt_mesh_optimize_netgen(0, GMSH_SET, o->mesh.butt[24]->value()); - opt_mesh_order(0, GMSH_SET, o->mesh.value[3]->value()); - opt_mesh_smooth_internal_edges(0, GMSH_SET, o->mesh.butt[3]->value()); - opt_mesh_second_order_incomplete(0, GMSH_SET, o->mesh.butt[4]->value()); - opt_mesh_c1(0, GMSH_SET, o->mesh.butt[21]->value()); - opt_mesh_points(0, GMSH_SET, o->mesh.butt[6]->value()); - opt_mesh_lines(0, GMSH_SET, o->mesh.butt[7]->value()); - opt_mesh_triangles(0, GMSH_SET, o->mesh.menu->menu()[0].value() ? 1 : 0); - opt_mesh_quadrangles(0, GMSH_SET, o->mesh.menu->menu()[1].value() ? 1 : 0); - opt_mesh_tetrahedra(0, GMSH_SET, o->mesh.menu->menu()[2].value() ? 1 : 0); - opt_mesh_hexahedra(0, GMSH_SET, o->mesh.menu->menu()[3].value() ? 1 : 0); - opt_mesh_prisms(0, GMSH_SET, o->mesh.menu->menu()[4].value() ? 1 : 0); - opt_mesh_pyramids(0, GMSH_SET, o->mesh.menu->menu()[5].value() ? 1 : 0); - opt_mesh_surfaces_edges(0, GMSH_SET, o->mesh.butt[8]->value()); - opt_mesh_surfaces_faces(0, GMSH_SET, o->mesh.butt[9]->value()); - opt_mesh_volumes_edges(0, GMSH_SET, o->mesh.butt[10]->value()); - opt_mesh_volumes_faces(0, GMSH_SET, o->mesh.butt[11]->value()); - opt_mesh_points_num(0, GMSH_SET, o->mesh.butt[12]->value()); - opt_mesh_lines_num(0, GMSH_SET, o->mesh.butt[13]->value()); - opt_mesh_surfaces_num(0, GMSH_SET, o->mesh.butt[14]->value()); - opt_mesh_volumes_num(0, GMSH_SET, o->mesh.butt[15]->value()); - opt_mesh_light(0, GMSH_SET, o->mesh.butt[17]->value()); - opt_mesh_light_two_side(0, GMSH_SET, o->mesh.butt[18]->value()); - opt_mesh_smooth_normals(0, GMSH_SET, o->mesh.butt[19]->value()); - opt_mesh_light_lines(0, GMSH_SET, o->mesh.butt[20]->value()); - opt_mesh_nb_smoothing(0, GMSH_SET, o->mesh.value[0]->value()); - opt_mesh_lc_factor(0, GMSH_SET, o->mesh.value[2]->value()); - opt_mesh_lc_min(0, GMSH_SET, o->mesh.value[25]->value()); - opt_mesh_lc_max(0, GMSH_SET, o->mesh.value[26]->value()); - opt_mesh_quality_inf(0, GMSH_SET, o->mesh.value[4]->value()); - opt_mesh_quality_sup(0, GMSH_SET, o->mesh.value[5]->value()); - opt_mesh_radius_inf(0, GMSH_SET, o->mesh.value[6]->value()); - opt_mesh_radius_sup(0, GMSH_SET, o->mesh.value[7]->value()); - opt_mesh_normals(0, GMSH_SET, o->mesh.value[8]->value()); - opt_mesh_explode(0, GMSH_SET, o->mesh.value[9]->value()); - opt_mesh_tangents(0, GMSH_SET, o->mesh.value[13]->value()); - opt_mesh_point_size(0, GMSH_SET, o->mesh.value[10]->value()); - opt_mesh_line_width(0, GMSH_SET, o->mesh.value[11]->value()); - opt_mesh_label_frequency(0, GMSH_SET, o->mesh.value[12]->value()); - opt_mesh_angle_smooth_normals(0, GMSH_SET, o->mesh.value[18]->value()); - - opt_mesh_point_type(0, GMSH_SET, o->mesh.choice[0]->value()); - opt_mesh_algo2d(0, GMSH_SET, - (o->mesh.choice[2]->value() == 0) ? ALGO_2D_FRONTAL : - (o->mesh.choice[2]->value() == 1) ? ALGO_2D_DELAUNAY : - ALGO_2D_MESHADAPT_DELAUNAY); - opt_mesh_algo3d(0, GMSH_SET, - (o->mesh.choice[3]->value() == 0) ? ALGO_3D_TETGEN_DELAUNAY : - ALGO_3D_NETGEN); - opt_mesh_recombine_algo(0, GMSH_SET, - (o->mesh.choice[5]->value() == 0) ? 1 : 2); - opt_mesh_color_carousel(0, GMSH_SET, o->mesh.choice[4]->value()); - opt_mesh_quality_type(0, GMSH_SET, o->mesh.choice[6]->value()); - opt_mesh_label_type(0, GMSH_SET, o->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) -{ - GUI::instance()->options->showGroup(4); -} - -void solver_options_ok_cb(CALLBACK_ARGS) -{ - activate_cb(NULL, data); - - optionWindow *o = GUI::instance()->options; - - int old_listen = (int)opt_solver_listen(0, GMSH_GET, o->solver.butt[0]->value()); - opt_solver_listen(0, GMSH_SET, o->solver.butt[0]->value()); - if(!old_listen && o->solver.butt[0]->value()) - Solver(-1, NULL); - - opt_solver_max_delay(0, GMSH_SET, o->solver.value[0]->value()); - - opt_solver_socket_name(0, GMSH_SET, o->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) -{ - GUI::instance()->options->showGroup(5); -} - -void post_options_ok_cb(CALLBACK_ARGS) -{ - activate_cb(NULL, data); - - optionWindow *o = GUI::instance()->options; - - opt_post_anim_cycle(0, GMSH_SET, o->post.butt[0]->value()); - opt_post_combine_remove_orig(0, GMSH_SET, o->post.butt[1]->value()); - opt_post_horizontal_scales(0, GMSH_SET, o->post.butt[2]->value()); - - opt_post_anim_delay(0, GMSH_SET, o->post.value[0]->value()); - - opt_post_link(0, GMSH_SET, o->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) -{ - GUI::instance()->options->showGroup((int)(long)data + 6); -} - -void view_options_timestep_cb(CALLBACK_ARGS) -{ - int links = (int)opt_post_link(0, GMSH_GET, 0); - for(int i = 0; i < (int)PView::list.size(); i++) { - if((links == 2 || links == 4) || - ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) || - (links == 0 && i == GUI::instance()->options->view.index)) { - 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 < (int)PView::list.size(); i++) { - if((links == 2 || links == 4) || - ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) || - (links == 0 && i == GUI::instance()->options->view.index)) { - 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 < (int)PView::list.size(); i++) { - if((links == 2 || links == 4) || - ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) || - (links == 0 && i == GUI::instance()->options->view.index)) { - 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(GUI::instance()->options->view.index, GMSH_GET, 0); - double b = opt_view_arrow_stem_length(GUI::instance()->options->view.index, GMSH_GET, 0); - double c = opt_view_arrow_stem_radius(GUI::instance()->options->view.index, GMSH_GET, 0); - while(arrow_editor("Arrow Editor", a, b, c)){ - opt_view_arrow_head_radius(GUI::instance()->options->view.index, GMSH_SET, a); - opt_view_arrow_stem_length(GUI::instance()->options->view.index, GMSH_SET, b); - opt_view_arrow_stem_radius(GUI::instance()->options->view.index, GMSH_SET, c); - Draw(); - } -} - -void view_options_ok_cb(CALLBACK_ARGS) -{ - int current = GUI::instance()->options->view.index; - - if(current < 0) - return; - - activate_cb(NULL, data); - - optionWindow *o = GUI::instance()->options; - - if(data){ - const char *str = (const char*)data; - if(!strcmp(str, "range_min")){ - o->view.value[31]->value(opt_view_min(o->view.index, GMSH_GET, 0)); - } - else if(!strcmp(str, "range_max")){ - o->view.value[32]->value(opt_view_max(o->view.index, 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 mikado = opt_view_axes_mikado(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 draw_skin_only = opt_view_draw_skin_only(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 center_glyphs = opt_view_center_glyphs(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 normal_raise = opt_view_normal_raise(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 < (int)PView::list.size(); 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 - - val = o->view.choice[1]->value() + 1; - if(force || (val != scale_type)) - opt_view_scale_type(i, GMSH_SET, val); - - val = o->view.choice[0]->value() + 1; - if(force || (val != intervals_type)) - opt_view_intervals_type(i, GMSH_SET, val); - - val = o->view.choice[5]->value(); - if(force || (val != point_type)) - opt_view_point_type(i, GMSH_SET, val); - - val = o->view.choice[6]->value(); - if(force || (val != line_type)) - opt_view_line_type(i, GMSH_SET, val); - - val = o->view.choice[2]->value() + 1; - if(force || (val != vector_type)) - opt_view_vector_type(i, GMSH_SET, val); - - val = o->view.choice[3]->value() + 1; - if(force || (val != glyph_location)) - opt_view_glyph_location(i, GMSH_SET, val); - - val = o->view.choice[4]->value() + 1; - if(force || (val != tensor_type)) - opt_view_tensor_type(i, GMSH_SET, val); - - val = o->view.choice[7]->value() + 1; - if(force || (val != range_type)) - opt_view_range_type(i, GMSH_SET, val); - - val = o->view.choice[8]->value(); - if(force || (val != axes)) - opt_view_axes(i, GMSH_SET, val); - - val = o->view.choice[9]->value(); - if(force || (val != boundary)) - opt_view_boundary(i, GMSH_SET, val); - - val = o->view.choice[10]->value() - 1; - if(force || (val != external_view)) - opt_view_external_view(i, GMSH_SET, val); - - val = o->view.choice[11]->value() - 1; - if(force || (val != gen_raise_view)) - opt_view_gen_raise_view(i, GMSH_SET, val); - - val = o->view.choice[12]->value(); - if(force || (val != show_time)) - opt_view_show_time(i, GMSH_SET, val); - - val = o->view.choice[13]->value() + 1; - if(force || (val != type)) - opt_view_type(i, GMSH_SET, val); - - // view_butts - - val = o->view.butt[0]->value(); - if(force || (val != arrow_size_proportional)) - opt_view_arrow_size_proportional(i, GMSH_SET, val); - - val = o->view.butt[38]->value(); - if(force || (val != saturate_values)) - opt_view_saturate_values(i, GMSH_SET, val); - - val = o->view.butt[10]->value(); - if(force || (val != show_element)) - opt_view_show_element(i, GMSH_SET, val); - - val = o->view.butt[2]->value(); - if(force || (val != draw_skin_only)) - opt_view_draw_skin_only(i, GMSH_SET, val); - - val = o->view.butt[4]->value(); - if(force || (val != show_scale)) - opt_view_show_scale(i, GMSH_SET, val); - - val = o->view.butt[3]->value(); - if(force || (val != mikado)) - opt_view_axes_mikado(i, GMSH_SET, val); - - val = o->view.butt[7]->value(); - if(force || (val != auto_position)) - opt_view_auto_position(i, GMSH_SET, val); - - val = o->view.butt[25]->value(); - if(force || (val != axes_auto_position)) - opt_view_axes_auto_position(i, GMSH_SET, val); - - val = o->view.butt[5]->value(); - if(force || (val != draw_strings)) - opt_view_draw_strings(i, GMSH_SET, val); - - val = o->view.butt[11]->value(); - if(force || (val != light)) - opt_view_light(i, GMSH_SET, val); - - val = o->view.butt[8]->value(); - if(force || (val != light_lines)) - opt_view_light_lines(i, GMSH_SET, val); - - val = o->view.butt[9]->value(); - if(force || (val != light_two_side)) - opt_view_light_two_side(i, GMSH_SET, val); - - val = o->view.butt[12]->value(); - if(force || (val != smooth_normals)) - opt_view_smooth_normals(i, GMSH_SET, val); - - val = o->view.menu[0]->menu()[0].value() ? 1 : 0; - if(force || (val != draw_scalars)) - opt_view_draw_scalars(i, GMSH_SET, val); - - val = o->view.menu[0]->menu()[1].value() ? 1 : 0; - if(force || (val != draw_vectors)) - opt_view_draw_vectors(i, GMSH_SET, val); - - val = o->view.menu[0]->menu()[2].value() ? 1 : 0; - if(force || (val != draw_tensors)) - opt_view_draw_tensors(i, GMSH_SET, val); - - val = o->view.menu[1]->menu()[0].value() ? 1 : 0; - if(force || (val != draw_points)) - opt_view_draw_points(i, GMSH_SET, val); - - val = o->view.menu[1]->menu()[1].value() ? 1 : 0; - if(force || (val != draw_lines)) - opt_view_draw_lines(i, GMSH_SET, val); - - val = o->view.menu[1]->menu()[2].value() ? 1 : 0; - if(force || (val != draw_triangles)) - opt_view_draw_triangles(i, GMSH_SET, val); - - val = o->view.menu[1]->menu()[3].value() ? 1 : 0; - if(force || (val != draw_quadrangles)) - opt_view_draw_quadrangles(i, GMSH_SET, val); - - val = o->view.menu[1]->menu()[4].value() ? 1 : 0; - if(force || (val != draw_tetrahedra)) - opt_view_draw_tetrahedra(i, GMSH_SET, val); - - val = o->view.menu[1]->menu()[5].value() ? 1 : 0; - if(force || (val != draw_hexahedra)) - opt_view_draw_hexahedra(i, GMSH_SET, val); - - val = o->view.menu[1]->menu()[6].value() ? 1 : 0; - if(force || (val != draw_prisms)) - opt_view_draw_prisms(i, GMSH_SET, val); - - val = o->view.menu[1]->menu()[7].value() ? 1 : 0; - if(force || (val != draw_pyramids)) - opt_view_draw_pyramids(i, GMSH_SET, val); - - val = o->view.butt[6]->value(); - if(force || (val != use_gen_raise)) - opt_view_use_gen_raise(i, GMSH_SET, val); - - val = o->view.butt[24]->value(); - if(force || (val != fake_transparency)) - opt_view_fake_transparency(i, GMSH_SET, val); - - val = o->view.butt[26]->value(); - if(force || (val != use_stipple)) - opt_view_use_stipple(i, GMSH_SET, val); - - val = o->view.butt[1]->value(); - if(force || (val != center_glyphs)) - opt_view_center_glyphs(i, GMSH_SET, val); - - // view_values - - val = o->view.value[0]->value(); - if(force || (val != normals)) - opt_view_normals(i, GMSH_SET, val); - - val = o->view.value[1]->value(); - if(force || (val != tangents)) - opt_view_tangents(i, GMSH_SET, val); - - val = o->view.value[31]->value(); - if(force || (val != custom_min)) - opt_view_custom_min(i, GMSH_SET, val); - - val = o->view.value[32]->value(); - if(force || (val != custom_max)) - opt_view_custom_max(i, GMSH_SET, val); - - val = o->view.value[33]->value(); - if(force || (val != max_recursion_level)) - opt_view_max_recursion_level(i, GMSH_SET, val); - - val = o->view.value[34]->value(); - if(force || (val != target_error)) - opt_view_target_error(i, GMSH_SET, val); - - val = o->view.value[30]->value(); - if(force || (val != nb_iso)) - opt_view_nb_iso(i, GMSH_SET, val); - - val = o->view.value[40]->value(); - if(force || (val != offset0)) - opt_view_offset0(i, GMSH_SET, val); - - val = o->view.value[41]->value(); - if(force || (val != offset1)) - opt_view_offset1(i, GMSH_SET, val); - - val = o->view.value[42]->value(); - if(force || (val != offset2)) - opt_view_offset2(i, GMSH_SET, val); - - val = o->view.value[51]->value(); - if(force || (val != transform00)) - opt_view_transform00(i, GMSH_SET, val); - - val = o->view.value[52]->value(); - if(force || (val != transform01)) - opt_view_transform01(i, GMSH_SET, val); - - val = o->view.value[53]->value(); - if(force || (val != transform02)) - opt_view_transform02(i, GMSH_SET, val); - - val = o->view.value[54]->value(); - if(force || (val != transform10)) - opt_view_transform10(i, GMSH_SET, val); - - val = o->view.value[55]->value(); - if(force || (val != transform11)) - opt_view_transform11(i, GMSH_SET, val); - - val = o->view.value[56]->value(); - if(force || (val != transform12)) - opt_view_transform12(i, GMSH_SET, val); - - val = o->view.value[57]->value(); - if(force || (val != transform20)) - opt_view_transform20(i, GMSH_SET, val); - - val = o->view.value[58]->value(); - if(force || (val != transform21)) - opt_view_transform21(i, GMSH_SET, val); - - val = o->view.value[59]->value(); - if(force || (val != transform22)) - opt_view_transform22(i, GMSH_SET, val); - - val = o->view.value[43]->value(); - if(force || (val != raise0)) - opt_view_raise0(i, GMSH_SET, val); - - val = o->view.value[44]->value(); - if(force || (val != raise1)) - opt_view_raise1(i, GMSH_SET, val); - - val = o->view.value[45]->value(); - if(force || (val != raise2)) - opt_view_raise2(i, GMSH_SET, val); - - val = o->view.value[46]->value(); - if(force || (val != normal_raise)) - opt_view_normal_raise(i, GMSH_SET, val); - - val = o->view.value[50]->value(); - if(force || (val != timestep)) - opt_view_timestep(i, GMSH_SET, val); - - val = o->view.value[60]->value(); - if(force || (val != arrow_size)) - opt_view_arrow_size(i, GMSH_SET, val); - - val = o->view.value[63]->value(); - if(force || (val != displacement_factor)) - opt_view_displacement_factor(i, GMSH_SET, val); - - val = o->view.value[61]->value(); - if(force || (val != point_size)) - opt_view_point_size(i, GMSH_SET, val); - - val = o->view.value[62]->value(); - if(force || (val != line_width)) - opt_view_line_width(i, GMSH_SET, val); - - val = o->view.value[12]->value(); - if(force || (val != explode)) - opt_view_explode(i, GMSH_SET, val); - - val = o->view.value[10]->value(); - if(force || (val != angle_smooth_normals)) - opt_view_angle_smooth_normals(i, GMSH_SET, val); - - val = o->view.value[20]->value(); - if(force || (val != position0)) - opt_view_position0(i, GMSH_SET, val); - - val = o->view.value[21]->value(); - if(force || (val != position1)) - opt_view_position1(i, GMSH_SET, val); - - val = o->view.value[22]->value(); - if(force || (val != size0)) - opt_view_size0(i, GMSH_SET, val); - - val = o->view.value[23]->value(); - if(force || (val != size1)) - opt_view_size1(i, GMSH_SET, val); - - val = o->view.value[13]->value(); - if(force || (val != axes_xmin)) - opt_view_axes_xmin(i, GMSH_SET, val); - - val = o->view.value[14]->value(); - if(force || (val != axes_ymin)) - opt_view_axes_ymin(i, GMSH_SET, val); - - val = o->view.value[15]->value(); - if(force || (val != axes_zmin)) - opt_view_axes_zmin(i, GMSH_SET, val); - - val = o->view.value[16]->value(); - if(force || (val != axes_xmax)) - opt_view_axes_xmax(i, GMSH_SET, val); - - val = o->view.value[17]->value(); - if(force || (val != axes_ymax)) - opt_view_axes_ymax(i, GMSH_SET, val); - - val = o->view.value[18]->value(); - if(force || (val != axes_zmax)) - opt_view_axes_zmax(i, GMSH_SET, val); - - val = o->view.value[2]->value(); - if(force || (val != gen_raise_factor)) - opt_view_gen_raise_factor(i, GMSH_SET, val); - - val = o->view.value[3]->value(); - if(force || (val != axes_tics0)) - opt_view_axes_tics0(i, GMSH_SET, val); - - val = o->view.value[4]->value(); - if(force || (val != axes_tics1)) - opt_view_axes_tics1(i, GMSH_SET, val); - - val = o->view.value[5]->value(); - if(force || (val != axes_tics2)) - opt_view_axes_tics2(i, GMSH_SET, val); - - // view_inputs - - const char *str; - - str = o->view.input[0]->value(); - if(force || strcmp(str, name)) - opt_view_name(i, GMSH_SET, str); - - str = o->view.input[1]->value(); - if(force || strcmp(str, format)) - opt_view_format(i, GMSH_SET, str); - - str = o->view.input[10]->value(); - if(force || strcmp(str, axes_label0)) - opt_view_axes_label0(i, GMSH_SET, str); - - str = o->view.input[11]->value(); - if(force || strcmp(str, axes_label1)) - opt_view_axes_label1(i, GMSH_SET, str); - - str = o->view.input[12]->value(); - if(force || strcmp(str, axes_label2)) - opt_view_axes_label2(i, GMSH_SET, str); - - str = o->view.input[7]->value(); - if(force || strcmp(str, axes_format0)) - opt_view_axes_format0(i, GMSH_SET, str); - - str = o->view.input[8]->value(); - if(force || strcmp(str, axes_format1)) - opt_view_axes_format1(i, GMSH_SET, str); - - str = o->view.input[9]->value(); - if(force || strcmp(str, axes_format2)) - opt_view_axes_format2(i, GMSH_SET, str); - - str = o->view.input[4]->value(); - if(force || strcmp(str, gen_raise0)) - opt_view_gen_raise0(i, GMSH_SET, str); - - str = o->view.input[5]->value(); - if(force || strcmp(str, gen_raise1)) - opt_view_gen_raise1(i, GMSH_SET, str); - - str = o->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)) { - ColorTable_Copy(&PView::list[current]->getOptions()->CT); - ColorTable_Paste(&PView::list[i]->getOptions()->CT); - PView::list[i]->setChanged(true); - } - } - } - - 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) -{ - GUI::instance()->stats->show(); -} - -void statistics_update_cb(CALLBACK_ARGS) -{ - GUI::instance()->stats->compute(true); -} - -void statistics_histogram_cb(CALLBACK_ARGS) -{ - std::string name((const char*)data); - - std::vector<double> x, y; - - if(name == "Gamma2D"){ - for(int i = 0; i < 100; i++) y.push_back(GUI::instance()->stats->quality[0][i]); - new PView("Gamma", "# Elements", x, y); - } - else if(name == "Eta2D"){ - for(int i = 0; i < 100; i++) y.push_back(GUI::instance()->stats->quality[1][i]); - new PView("Eta", "# Elements", x, y); - } - else if(name == "Rho2D"){ - for(int i = 0; i < 100; i++) y.push_back(GUI::instance()->stats->quality[2][i]); - new PView("Rho", "# Elements", x, y); - } - else if(name == "Disto2D"){ - for(int i = 0; i < 100; i++) y.push_back(GUI::instance()->stats->quality[3][i]); - new PView("Disto", "# Elements", x, y); - } - else{ - std::vector<GEntity*> entities; - GModel::current()->getEntities(entities); - std::map<int, std::vector<double> > d; - for(unsigned int i = 0; i < entities.size(); i++){ - if(entities[i]->dim() < 2) continue; - for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){ - MElement *e = entities[i]->getMeshElement(j); - if(name == "Gamma3D") - d[e->getNum()].push_back(e->gammaShapeMeasure()); - else if(name == "Eta3D") - d[e->getNum()].push_back(e->etaShapeMeasure()); - else if(name == "Rho3D") - d[e->getNum()].push_back(e->rhoShapeMeasure()); - else - d[e->getNum()].push_back(e->distoShapeMeasure()); - } - } - name.resize(name.size() - 2); - new PView(name, "ElementData", GModel::current(), d); - } - - GUI::instance()->updateViews(); - Draw(); -} - -// Messages Menu - -void message_cb(CALLBACK_ARGS) -{ - GUI::instance()->messages->show(); -} - -void message_auto_scroll_cb(CALLBACK_ARGS) -{ - CTX.msg_auto_scroll = GUI::instance()->messages->butt->value(); -} - -void message_copy_cb(CALLBACK_ARGS) -{ -#define BUFFL 50000 - static char buff[BUFFL]; - strcpy(buff, ""); - for(int i = 1; i <= GUI::instance()->messages->browser->size(); i++) { - if(GUI::instance()->messages->browser->selected(i)) { - const char *c = GUI::instance()->messages->browser->text(i); - if(strlen(buff) + strlen(c) > BUFFL - 2) { - Msg::Error("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) -{ - GUI::instance()->messages->browser->clear(); -} - -void message_save_cb(CALLBACK_ARGS) -{ - test: - if(file_chooser(0, 1, "Save", "*")) { - std::string name = file_chooser_get_name(1); - if(CTX.confirm_overwrite) { - if(!StatFile(name.c_str())) - if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", - "Cancel", "Replace", NULL, name.c_str())) - goto test; - } - GUI::instance()->messages->save(name.c_str()); - } -} - -// Visibility Menu - -void visibility_cb(CALLBACK_ARGS) -{ - // get the visibility info from the model, and update the browser accordingly - - const char *str = (const char*)data; - if(str && !strcmp(str, "redraw_only")) - GUI::instance()->visibility->show(true); - else - GUI::instance()->visibility->show(false); - - GUI::instance()->visibility->browser->clear(); - - int type = GUI::instance()->visibility->type->value(); - - VisibilityManager::instance()->update(type); - for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){ - GUI::instance()->visibility->browser->add(VisibilityManager::instance()->getBrowserLine(i).c_str()); - if(VisibilityManager::instance()->getVisibility(i)) - GUI::instance()->visibility->browser->select(i + 1); - } - - // activate the delete button for physicals only! - if(type == 1) - GUI::instance()->visibility->push[0]->activate(); - else - GUI::instance()->visibility->push[0]->deactivate(); - - // disable numeric and interactive selection for partitions - if(type == 2){ - GUI::instance()->visibility->group[1]->deactivate(); - GUI::instance()->visibility->group[2]->deactivate(); - } - else{ - GUI::instance()->visibility->group[1]->activate(); - GUI::instance()->visibility->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 = GUI::instance()->visibility->butt[0]->value() ? true : false; - int type = GUI::instance()->visibility->type->value(); - VisibilityManager::instance()->setAllInvisible(type); - for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++) - if(GUI::instance()->visibility->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)) - GUI::instance()->visibility->browser->select(i + 1); - Draw(); - } -} - -void visibility_save_cb(CALLBACK_ARGS) -{ - std::string str = VisibilityManager::instance()->getStringForGEO(); - add_infile(str.c_str(), CTX.filename); -} - -void visibility_delete_cb(CALLBACK_ARGS) -{ - int type = GUI::instance()->visibility->type->value(); - if(type != 1) return; // delete only available for physicals - - bool all = true; - for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){ - if(!GUI::instance()->visibility->browser->selected(i + 1)){ - all = false; - break; - } - } - if(all){ - GModel::current()->deletePhysicalGroups(); - } - else{ - for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){ - if(GUI::instance()->visibility->browser->selected(i + 1)){ - Vis *v = VisibilityManager::instance()->getEntity(i); - GModel::current()->deletePhysicalGroup(v->getDim(), v->getTag()); - } - } - } - - visibility_cb(NULL, (void*)"redraw_only"); -} - -void visibility_sort_cb(CALLBACK_ARGS) -{ - const char *str = (const 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 < GUI::instance()->visibility->browser->size(); i++) - if(!GUI::instance()->visibility->browser->selected(i + 1)) { - selectall = 1; - break; - } - if(selectall) - for(int i = 0; i < GUI::instance()->visibility->browser->size(); i++) - GUI::instance()->visibility->browser->select(i + 1); - else - GUI::instance()->visibility->browser->deselect(); - } - else if(val == -1){ // invert the selection - int *state = new int[GUI::instance()->visibility->browser->size()]; - for(int i = 0; i < GUI::instance()->visibility->browser->size(); i++) - state[i] = GUI::instance()->visibility->browser->selected(i + 1); - GUI::instance()->visibility->browser->deselect(); - for(int i = 0; i < GUI::instance()->visibility->browser->size(); i++) - if(!state[i]) GUI::instance()->visibility->browser->select(i + 1); - delete [] state; - } - else if(val == -2){ // create new parameter name for selection - for(int i = 0; i < GUI::instance()->visibility->browser->size(); i++){ - if(GUI::instance()->visibility->browser->selected(i + 1)){ - static char tmpstr[256]; - sprintf(tmpstr, "%d", VisibilityManager::instance()->getTag(i)); - GUI::instance()->geoContext->input[1]->value(tmpstr); - break; - } - } - GUI::instance()->geoContext->input[0]->value("NewName"); - GUI::instance()->geoContext->show(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 = GUI::instance()->visibility->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; - } - const char *str = GUI::instance()->visibility->input[what]->value(); - if(type == 1 && what >= 2 && what <= 5) what += 4; - - int num = (!strcmp(str, "all") || !strcmp(str, "*")) ? -1 : atoi(str); - bool recursive = GUI::instance()->visibility->butt[0]->value() ? true : false; - - VisibilityManager::instance()->setVisibilityByNumber(what, num, val, recursive); - - int pos = GUI::instance()->visibility->browser->position(); - visibility_cb(NULL, (void*)"redraw_only"); - GUI::instance()->visibility->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 = GUI::instance()->visibility->type->value(); - if(type != 0 && type != 1) return; - bool recursive = GUI::instance()->visibility->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 = GUI::instance()->visibility->browser->position(); - visibility_cb(NULL, (void*)"redraw_only"); - GUI::instance()->visibility->browser->position(pos); -} - -void visibility_interactive_cb(CALLBACK_ARGS) -{ - const char *str = (const char*)data; - const char *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"; - if(GModel::current()->getMeshStatus() < 2) - 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"; - if(GModel::current()->getMeshStatus() < 3) - 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"; - if(GModel::current()->getMeshStatus() < 2) - 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"; - if(GModel::current()->getMeshStatus() < 3) - 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) { - if(what == ENT_ALL) - CTX.mesh.changed = ENT_ALL; - Draw(); - Msg::StatusBar(3, false, "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::StatusBar(3, false, ""); -} - -// Clipping planes menu - -void clip_cb(CALLBACK_ARGS) -{ - GUI::instance()->clipping->show(); -} - -void clip_num_cb(CALLBACK_ARGS) -{ - GUI::instance()->clipping->resetBrowser(); -} - -void clip_update_cb(CALLBACK_ARGS) -{ - if(GUI::instance()->clipping->group[0]->visible()){ // clipping planes - int idx = GUI::instance()->clipping->choice->value(); - CTX.geom.clip &= ~(1 << idx); - CTX.mesh.clip &= ~(1 << idx); - for(unsigned int i = 0; i < PView::list.size(); i++) - PView::list[i]->getOptions()->Clip &= ~(1 << idx); - for(int i = 0; i < GUI::instance()->clipping->browser->size(); i++){ - if(GUI::instance()->clipping->browser->selected(i + 1)){ - if(i == 0) - CTX.geom.clip |= (1 << idx); - else if(i == 1) - CTX.mesh.clip |= (1 << idx); - else if(i - 2 < PView::list.size()) - PView::list[i - 2]->getOptions()->Clip |= (1 << idx); - } - } - for(int i = 0; i < 4; i++) - CTX.clip_plane[idx][i] = GUI::instance()->clipping->value[i]->value(); - } - else{ // clipping box - CTX.geom.clip = 0; - CTX.mesh.clip = 0; - for(unsigned int i = 0; i < PView::list.size(); i++) - PView::list[i]->getOptions()->Clip = 0; - for(int i = 0; i < GUI::instance()->clipping->browser->size(); i++){ - if(GUI::instance()->clipping->browser->selected(i + 1)){ - for(int idx = 0; idx < 6; idx++){ - if(i == 0) - CTX.geom.clip |= (1 << idx); - else if(i == 1) - CTX.mesh.clip |= (1 << idx); - else if(i - 2 < PView::list.size()) - PView::list[i - 2]->getOptions()->Clip |= (1 << idx); - } - } - } - double c[3] = {GUI::instance()->clipping->value[4]->value(), - GUI::instance()->clipping->value[5]->value(), - GUI::instance()->clipping->value[6]->value()}; - double d[3] = {GUI::instance()->clipping->value[7]->value(), - GUI::instance()->clipping->value[8]->value(), - GUI::instance()->clipping->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.); - } - - if(CTX.clip_whole_elements || - CTX.clip_whole_elements != GUI::instance()->clipping->butt[0]->value()){ - for(int clip = 0; clip < 6; clip++){ - if(CTX.mesh.clip) - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - for(unsigned int index = 0; index < PView::list.size(); index++) - if(PView::list[index]->getOptions()->Clip) - PView::list[index]->setChanged(true); - } - } - - CTX.clip_whole_elements = GUI::instance()->clipping->butt[0]->value(); - CTX.clip_only_draw_intersecting_volume = GUI::instance()->clipping->butt[1]->value(); - CTX.clip_only_volume = GUI::instance()->clipping->butt[2]->value(); - - 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++) - GUI::instance()->clipping->value[i]->value(-GUI::instance()->clipping->value[i]->value()); - clip_update_cb(NULL, NULL); -} - -void clip_reset_cb(CALLBACK_ARGS) -{ - CTX.geom.clip = 0; - CTX.mesh.clip = 0; - for(unsigned int index = 0; index < PView::list.size(); index++) - PView::list[index]->getOptions()->Clip = 0; - - for(int i = 0; i < 6; i++){ - CTX.clip_plane[i][0] = 1.; - for(int j = 1; j < 4; j++) - CTX.clip_plane[i][j] = 0.; - } - - if(CTX.clip_whole_elements){ - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - for(unsigned int index = 0; index < PView::list.size(); index++) - PView::list[index]->setChanged(true); - } - - GUI::instance()->clipping->resetBrowser(); - Draw(); -} - -// Manipulator menu - -void manip_cb(CALLBACK_ARGS) -{ - GUI::instance()->manip->show(); -} - -void manip_update_cb(CALLBACK_ARGS) -{ - drawContext *ctx = GUI::instance()->graph[0]->gl->getDrawContext(); - ctx->r[0] = GUI::instance()->manip->value[0]->value(); - ctx->r[1] = GUI::instance()->manip->value[1]->value(); - ctx->r[2] = GUI::instance()->manip->value[2]->value(); - ctx->t[0] = GUI::instance()->manip->value[3]->value(); - ctx->t[1] = GUI::instance()->manip->value[4]->value(); - ctx->t[2] = GUI::instance()->manip->value[5]->value(); - ctx->s[0] = GUI::instance()->manip->value[6]->value(); - ctx->s[1] = GUI::instance()->manip->value[7]->value(); - ctx->s[2] = GUI::instance()->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+u Show post-processing view plugins"); - 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("u") " Show plugin window"); - 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+e Hide/Show element outlines for visible post-processing views"); - 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+r Loop through range modes for visible post-processing views"); - 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(" "); - GUI::instance()->messages->show(); -} - -void help_mouse_cb(CALLBACK_ARGS) -{ - Msg::Direct(" "); - Msg::Direct("Mouse actions:"); - Msg::Direct(" "); - Msg::Direct(" Move - Highlight the entity under the mouse pointer"); - Msg::Direct(" and display its properties in the status bar"); - Msg::Direct(" - Resize a lasso zoom or a lasso (un)selection"); - Msg::Direct(" Left button - Rotate"); - Msg::Direct(" - Select an entity"); - Msg::Direct(" - Accept a lasso zoom or a lasso selection"); - Msg::Direct(" Ctrl+Left button Start a lasso zoom or a lasso (un)selection"); - Msg::Direct(" Middle button - Zoom"); - Msg::Direct(" - Unselect an entity"); - Msg::Direct(" - Accept a lasso zoom or a lasso unselection"); - Msg::Direct(" Ctrl+Middle button Orthogonalize display"); - Msg::Direct(" Right button - Pan"); - Msg::Direct(" - Cancel a lasso zoom or a lasso (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(" "); - GUI::instance()->messages->show(); -} - -void help_command_line_cb(CALLBACK_ARGS) -{ - Msg::Direct(" "); - Print_Usage("gmsh"); - GUI::instance()->messages->show(); -} - -void _replace_multi_format(const char *in, const 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) -{ - std::string prog = FixWindowsPath(CTX.web_browser); - char cmd[1024]; - _replace_multi_format(prog.c_str(), "http://geuz.org/gmsh/doc/texinfo/", cmd); - SystemCall(cmd); -} - -void help_license_cb(CALLBACK_ARGS) -{ - std::string prog = FixWindowsPath(CTX.web_browser); - char cmd[1024]; - _replace_multi_format(prog.c_str(), "http://geuz.org/gmsh/doc/LICENSE.txt", cmd); - SystemCall(cmd); -} - -void help_credits_cb(CALLBACK_ARGS) -{ - std::string prog = FixWindowsPath(CTX.web_browser); - char cmd[1024]; - _replace_multi_format(prog.c_str(), "http://geuz.org/gmsh/doc/CREDITS.txt", cmd); - SystemCall(cmd); -} - -void help_about_cb(CALLBACK_ARGS) -{ - GUI::instance()->about->win->show(); -} - -// Module Menu - -void mod_geometry_cb(CALLBACK_ARGS) -{ - GUI::instance()->menu->setContext(menu_geometry, 0); -} - -void mod_mesh_cb(CALLBACK_ARGS) -{ - GUI::instance()->menu->setContext(menu_mesh, 0); -} - -void mod_solver_cb(CALLBACK_ARGS) -{ - GUI::instance()->menu->setContext(menu_solver, 0); -} - -void mod_post_cb(CALLBACK_ARGS) -{ - GUI::instance()->menu->setContext(menu_post, 0); -} - -void mod_back_cb(CALLBACK_ARGS) -{ - GUI::instance()->menu->setContext(NULL, -1); -} - -void mod_forward_cb(CALLBACK_ARGS) -{ - GUI::instance()->menu->setContext(NULL, 1); -} - -// Dynamic Geomtry Menus - -void geometry_elementary_cb(CALLBACK_ARGS) -{ - GUI::instance()->menu->setContext(menu_geometry_elementary, 0); -} - -void geometry_physical_cb(CALLBACK_ARGS) -{ - GUI::instance()->menu->setContext(menu_geometry_physical, 0); -} - -void geometry_edit_cb(CALLBACK_ARGS) -{ - std::string prog = FixWindowsPath(CTX.editor); - std::string file = FixWindowsPath(CTX.filename); - char cmd[1024]; - _replace_multi_format(prog.c_str(), file.c_str(), cmd); - SystemCall(cmd); -} - -void geometry_reload_cb(CALLBACK_ARGS) -{ - OpenProject(CTX.filename); - Draw(); -} - -void geometry_elementary_add_cb(CALLBACK_ARGS) -{ - GUI::instance()->menu->setContext(menu_geometry_elementary_add, 0); -} - -static void _add_new_point() -{ - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - Draw(); - - GUI::instance()->geoContext->show(1); - - while(1) { - GUI::instance()->graph[0]->gl->addPointMode = true; - Msg::StatusBar(3, false, "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, - GUI::instance()->geoContext->input[2]->value(), - GUI::instance()->geoContext->input[3]->value(), - GUI::instance()->geoContext->input[4]->value(), - GUI::instance()->geoContext->input[5]->value()); - GUI::instance()->resetVisibility(); - Draw(); - } - if(ib == 'q'){ - GUI::instance()->graph[0]->gl->addPointMode = false; - break; - } - } - - Msg::StatusBar(3, false, ""); -} - -static void _add_new_multiline(std::string type) -{ - std::vector<GVertex*> vertices; - std::vector<GEdge*> edges; - std::vector<GFace*> faces; - std::vector<GRegion*> regions; - std::vector<MElement*> elements; - std::vector<int> p; - - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - Draw(); - - while(1) { - if(p.empty()) - Msg::StatusBar(3, false, "Select control points\n" - "[Press 'e' to end selection or 'q' to abort]"); - else - Msg::StatusBar(3, false, "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.push_back(vertices[i]->tag()); - } - Draw(); - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during multi-line creation"); - } - if(ib == 'e') { - if(p.size() >= 2) - add_multline(type, p, CTX.filename); - GUI::instance()->resetVisibility(); - ZeroHighlight(); - Draw(); - p.clear(); - } - if(ib == 'u') { - if(p.size()){ - ZeroHighlightEntityNum(p.back(), 0, 0, 0); - Draw(); - p.pop_back(); - } - } - if(ib == 'q') { - ZeroHighlight(); - Draw(); - break; - } - } - - Msg::StatusBar(3, false, ""); -} - -static void _add_new_line() -{ - std::vector<GVertex*> vertices; - std::vector<GEdge*> edges; - std::vector<GFace*> faces; - std::vector<GRegion*> regions; - std::vector<MElement*> elements; - std::vector<int> p; - - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - Draw(); - - while(1) { - if(p.empty()) - Msg::StatusBar(3, false, "Select start point\n" - "[Press 'q' to abort]"); - if(p.size() == 1) - Msg::StatusBar(3, false, "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.push_back(vertices[0]->tag()); - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during line creation"); - } - if(ib == 'u') { - if(p.size()){ - ZeroHighlightEntityNum(p.back(), 0, 0, 0); - Draw(); - p.pop_back(); - } - } - if(ib == 'q') { - ZeroHighlight(); - Draw(); - break; - } - if(p.size() == 2) { - add_multline("Line", p, CTX.filename); - GUI::instance()->resetVisibility(); - ZeroHighlight(); - Draw(); - p.clear(); - } - } - - Msg::StatusBar(3, false, ""); -} - -static void _add_new_circle() -{ - std::vector<GVertex*> vertices; - std::vector<GEdge*> edges; - std::vector<GFace*> faces; - std::vector<GRegion*> regions; - std::vector<MElement*> elements; - std::vector<int> p; - - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - Draw(); - - while(1) { - if(p.empty()) - Msg::StatusBar(3, false, "Select start point\n" - "[Press 'q' to abort]"); - if(p.size() == 1) - Msg::StatusBar(3, false, "Select center point\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - if(p.size() == 2) - Msg::StatusBar(3, false, "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.push_back(vertices[0]->tag()); - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during circle creation"); - } - if(ib == 'u') { - if(p.size()){ - ZeroHighlightEntityNum(p.back(), 0, 0, 0); - Draw(); - p.pop_back(); - } - } - if(ib == 'q') { - ZeroHighlight(); - Draw(); - break; - } - if(p.size() == 3) { - add_circ(p[0], p[1], p[2], CTX.filename); // begin, center, end - GUI::instance()->resetVisibility(); - ZeroHighlight(); - Draw(); - p.clear(); - } - } - - Msg::StatusBar(3, false, ""); -} - -static void _add_new_ellipse() -{ - std::vector<GVertex*> vertices; - std::vector<GEdge*> edges; - std::vector<GFace*> faces; - std::vector<GRegion*> regions; - std::vector<MElement*> elements; - std::vector<int> p; - - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - Draw(); - - while(1) { - if(p.empty()) - Msg::StatusBar(3, false, "Select start point\n" - "[Press 'q' to abort]"); - if(p.size() == 1) - Msg::StatusBar(3, false, "Select center point\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - if(p.size() == 2) - Msg::StatusBar(3, false, "Select major axis point\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - if(p.size() == 3) - Msg::StatusBar(3, false, "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.push_back(vertices[0]->tag()); - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during ellipse creation"); - } - if(ib == 'u') { - if(p.size()){ - ZeroHighlightEntityNum(p.back(), 0, 0, 0); - Draw(); - p.pop_back(); - } - } - if(ib == 'q') { - ZeroHighlight(); - Draw(); - break; - } - if(p.size() == 4) { - add_ell(p[0], p[1], p[2], p[3], CTX.filename); - GUI::instance()->resetVisibility(); - ZeroHighlight(); - Draw(); - p.clear(); - } - } - - Msg::StatusBar(3, false, ""); -} - -static void _add_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::StatusBar(3, false, "Select surface boundary\n" - "[Press 'q' to abort]"); - else - Msg::StatusBar(3, false, "Select surface boundary\n" - "[Press 'u' to undo last selection or 'q' to abort]"); - } - else{ - if(!List_Nbr(List1)) - Msg::StatusBar(3, false, "Select volume boundary\n" - "[Press 'q' to abort]"); - else - Msg::StatusBar(3, false, "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::StatusBar(3, false, "Select hole boundaries (if none, press 'e')\n" - "[Press 'e' to end selection or 'q' to abort]"); - else - Msg::StatusBar(3, false, "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("Plane Surface", List2, CTX.filename); break; - case 1: add_surf("Ruled Surface", List2, CTX.filename); break; - case 2: add_vol(List2, CTX.filename); break; - } - GUI::instance()->resetVisibility(); - ZeroHighlight(); - Draw(); - break; - } - } // if SelectContour - } - } - } - -stopall:; - List_Delete(List1); - List_Delete(List2); - - Msg::StatusBar(3, false, ""); -} - -void geometry_elementary_add_new_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_add_new, 0); - return; - } - - std::string str((const char*)data); - if(str == "Parameter") - GUI::instance()->geoContext->show(0); - else if(str == "Point") - _add_new_point(); - else if(str == "Line") - _add_new_line(); - else if(str == "Spline") - _add_new_multiline(str); - else if(str == "BSpline") - _add_new_multiline(str); - else if(str == "Circle") - _add_new_circle(); - else if(str == "Ellipse") - _add_new_ellipse(); - else if(str == "Plane Surface") - _add_new_surface_volume(0); - else if(str == "Ruled Surface") - _add_new_surface_volume(1); - else if(str == "Volume") - _add_new_surface_volume(2); - else - Msg::Error("Unknown entity to create: %s", str.c_str()); -} - -static void _split_selection() -{ - opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); - Draw(); - Msg::StatusBar(3, false, "Select a line to split\n" - "[Press 'q' to abort]"); - std::vector<GVertex*> vertices; - std::vector<GEdge*> edges; - std::vector<GFace*> faces; - std::vector<GRegion*> regions; - std::vector<MElement*> elements; - GEdge* edge_to_split = NULL; - while(1){ - char ib = SelectEntity(2, vertices, edges, faces, regions, elements); - if(ib == 'q') - break; - if(!edges.empty()){ - edge_to_split = edges[0]; - HighlightEntity(edges[0]); - break; - } - } - Msg::StatusBar(3, false, ""); - if(edges.empty()) - return; - List_T *List1 = List_Create(5, 5, sizeof(int)); - Msg::StatusBar(3, false, "Select break points\n" - "[Press 'e' to end selection or 'q' to abort]"); - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - Draw(); - while(1){ - char ib = SelectEntity(1, vertices, edges, faces, regions, elements); - if(ib == 'q') - break; - if(ib == 'e'){ - split_edge(edge_to_split->tag(), List1, CTX.filename); - break; - } - if(!vertices.empty()){ - for(unsigned int i = 0; i < vertices.size(); i++){ - int tag = vertices[i]->tag(); - int index = List_ISearchSeq(List1, &tag, fcmp_int); - if(index < 0) List_Add(List1, &tag); - HighlightEntity(vertices[i]); - } - } - } - Msg::StatusBar(3, false, ""); - GUI::instance()->resetVisibility(); - ZeroHighlight(); - Draw(); -} - -static void _action_point_line_surface_volume(int action, int mode, const char *what) -{ - std::vector<GVertex*> vertices; - std::vector<GEdge*> edges; - std::vector<GFace*> faces; - std::vector<GRegion*> regions; - std::vector<MElement*> elements; - int type; - const 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::Error("Unknown entity to select"); - return; - } - - if(action == 8){ - GUI::instance()->meshContext->show(0); - } - - Draw(); - - List_T *List1 = List_Create(5, 5, sizeof(int)); - while(1) { - if(!List_Nbr(List1)) - Msg::StatusBar(3, false, "Select %s\n" - "[Press 'e' to end selection or 'q' to abort]", str); - else - Msg::StatusBar(3, false, "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 == 'i') { - Msg::Error("Inverting selection!"); - } - if(ib == 'e') { - if(List_Nbr(List1)){ - switch (action) { - case 0: - translate(mode, List1, CTX.filename, what, - GUI::instance()->geoContext->input[6]->value(), - GUI::instance()->geoContext->input[7]->value(), - GUI::instance()->geoContext->input[8]->value()); - break; - case 1: - rotate(mode, List1, CTX.filename, what, - GUI::instance()->geoContext->input[12]->value(), - GUI::instance()->geoContext->input[13]->value(), - GUI::instance()->geoContext->input[14]->value(), - GUI::instance()->geoContext->input[9]->value(), - GUI::instance()->geoContext->input[10]->value(), - GUI::instance()->geoContext->input[11]->value(), - GUI::instance()->geoContext->input[15]->value()); - break; - case 2: - dilate(mode, List1, CTX.filename, what, - GUI::instance()->geoContext->input[16]->value(), - GUI::instance()->geoContext->input[17]->value(), - GUI::instance()->geoContext->input[18]->value(), - GUI::instance()->geoContext->input[19]->value()); - break; - case 3: - symmetry(mode, List1, CTX.filename, what, - GUI::instance()->geoContext->input[20]->value(), - GUI::instance()->geoContext->input[21]->value(), - GUI::instance()->geoContext->input[22]->value(), - GUI::instance()->geoContext->input[23]->value()); - break; - case 4: - extrude(List1, CTX.filename, what, - GUI::instance()->geoContext->input[6]->value(), - GUI::instance()->geoContext->input[7]->value(), - GUI::instance()->geoContext->input[8]->value()); - break; - case 5: - protude(List1, CTX.filename, what, - GUI::instance()->geoContext->input[12]->value(), - GUI::instance()->geoContext->input[13]->value(), - GUI::instance()->geoContext->input[14]->value(), - GUI::instance()->geoContext->input[9]->value(), - GUI::instance()->geoContext->input[10]->value(), - GUI::instance()->geoContext->input[11]->value(), - GUI::instance()->geoContext->input[15]->value()); - break; - case 6: - delet(List1, CTX.filename, what); - break; - case 7: - add_physical(what, List1, CTX.filename); - break; - case 8: - add_charlength(List1, CTX.filename, GUI::instance()->meshContext->input[0]->value()); - break; - case 9: - add_recosurf(List1, CTX.filename); - break; - - default: - Msg::Error("Unknown action on selected entities"); - break; - } - List_Reset(List1); - GUI::instance()->resetVisibility(); - ZeroHighlight(); - if(action <= 6) SetBoundingBox(); - Draw(); - } - } - if(ib == 'q') { - ZeroHighlight(); - Draw(); - break; - } - } - List_Delete(List1); - - Msg::StatusBar(3, false, ""); -} - -void geometry_elementary_add_translate_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_add_translate, 0); - return; - } - GUI::instance()->geoContext->show(2); - _action_point_line_surface_volume(0, 1, (const char*)data); -} - -void geometry_elementary_add_rotate_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_add_rotate, 0); - return; - } - GUI::instance()->geoContext->show(3); - _action_point_line_surface_volume(1, 1, (const char*)data); -} - -void geometry_elementary_add_scale_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_add_scale, 0); - return; - } - GUI::instance()->geoContext->show(4); - _action_point_line_surface_volume(2, 1, (const char*)data); -} - -void geometry_elementary_add_symmetry_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_add_symmetry, 0); - return; - } - GUI::instance()->geoContext->show(5); - _action_point_line_surface_volume(3, 1, (const char*)data); -} - -void geometry_elementary_translate_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_translate, 0); - return; - } - GUI::instance()->geoContext->show(2); - _action_point_line_surface_volume(0, 0, (const char*)data); -} - -void geometry_elementary_rotate_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_rotate, 0); - return; - } - GUI::instance()->geoContext->show(3); - _action_point_line_surface_volume(1, 0, (const char*)data); -} - -void geometry_elementary_scale_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_scale, 0); - return; - } - GUI::instance()->geoContext->show(4); - _action_point_line_surface_volume(2, 0, (const char*)data); -} - -void geometry_elementary_symmetry_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_symmetry, 0); - return; - } - GUI::instance()->geoContext->show(5); - _action_point_line_surface_volume(3, 0, (const char*)data); -} - -void geometry_elementary_extrude_cb(CALLBACK_ARGS) -{ - GUI::instance()->menu->setContext(menu_geometry_elementary_extrude, 0); -} - -void geometry_elementary_extrude_translate_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_extrude_translate, 0); - return; - } - GUI::instance()->geoContext->show(2); - _action_point_line_surface_volume(4, 0, (const char*)data); -} - -void geometry_elementary_extrude_rotate_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_extrude_rotate, 0); - return; - } - GUI::instance()->geoContext->show(3); - _action_point_line_surface_volume(5, 0, (const char*)data); -} - -void geometry_elementary_delete_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_delete, 0); - return; - } - _action_point_line_surface_volume(6, 0, (const char*)data); -} - -void geometry_elementary_split_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_elementary_split, 0); - return; - } - _split_selection(); -} - -void geometry_elementary_coherence_cb(CALLBACK_ARGS) -{ - coherence(CTX.filename); -} - -void geometry_physical_add_cb(CALLBACK_ARGS) -{ - if(!data){ - GUI::instance()->menu->setContext(menu_geometry_physical_add, 0); - return; - } - std::string str((const char*)data); - if(str == "Point") - GUI::instance()->callForSolverPlugin(0); - else if(str == "Line") - GUI::instance()->callForSolverPlugin(1); - - _action_point_line_surface_volume(7, 0, str.c_str()); -} - -// 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) -{ - GUI::instance()->menu->setContext(menu_mesh_define, 0); -} - -void mesh_1d_cb(CALLBACK_ARGS) -{ - GModel::current()->mesh(1); - Draw(); - Msg::StatusBar(2, false, " "); -} - -void mesh_2d_cb(CALLBACK_ARGS) -{ - GModel::current()->mesh(2); - Draw(); - Msg::StatusBar(2, false, " "); -} - -void mesh_3d_cb(CALLBACK_ARGS) -{ - GModel::current()->mesh(3); - Draw(); - Msg::StatusBar(2, false, " "); -} - -void mesh_delete_cb(CALLBACK_ARGS) -{ - GUI::instance()->menu->setContext(menu_mesh_delete, 0); -} - -void mesh_delete_parts_cb(CALLBACK_ARGS) -{ - const char *str = (const 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::StatusBar(3, false, "Select %s\n" - "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]", str); - else - Msg::StatusBar(3, false, "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::current()->removeInvisibleElements(); - ele.clear(); - ent.clear(); - } - if(ib == 'q') { - ZeroHighlight(); - break; - } - } - - CTX.mesh.changed = ENT_ALL; - CTX.pick_elements = 0; - Draw(); - Msg::StatusBar(3, false, ""); -} - -void mesh_update_edges_cb(CALLBACK_ARGS) -{ - Msg::Error("Update edges not implemented yet"); -} - -void mesh_remesh_cb(CALLBACK_ARGS) -{ - Msg::Error("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::StatusBar(3, false, "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()); - int type = elements[0]->getTypeForMSH(); - const char *name; - MElement::getInfoMSH(type, &name); - Msg::Direct(" Type: %d ('%s')", type, name); - 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()); - Msg::Direct(" Disto: %g", elements[0]->distoShapeMeasure()); - CTX.mesh.changed = ENT_ALL; - Draw(); - GUI::instance()->messages->show(); - } - } - if(ib == 'q') { - ZeroHighlight(); - break; - } - } - - CTX.pick_elements = 0; - CTX.mesh.changed = ENT_ALL; - Draw(); - Msg::StatusBar(3, false, ""); -} - -void mesh_degree_cb(CALLBACK_ARGS) -{ - if((long)data == 2) - SetOrderN(GModel::current(), 2, CTX.mesh.second_order_linear, - CTX.mesh.second_order_incomplete); - else - SetOrder1(GModel::current()); - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - Draw(); - Msg::StatusBar(2, false, " "); -} - -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(GModel::current()); - CTX.threads_lock = 0; - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - Draw(); - Msg::StatusBar(2, false, " "); -} - -void mesh_refine_cb(CALLBACK_ARGS) -{ - RefineMesh(GModel::current(), CTX.mesh.second_order_linear); - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - Draw(); - Msg::StatusBar(2, false, " "); -} - -void mesh_optimize_netgen_cb(CALLBACK_ARGS) -{ - if(CTX.threads_lock) { - Msg::Info("I'm busy! Ask me that later..."); - return; - } - CTX.threads_lock = 1; - OptimizeMeshNetgen(GModel::current()); - CTX.threads_lock = 0; - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - Draw(); - Msg::StatusBar(2, false, " "); -} - -void mesh_partition_cb(CALLBACK_ARGS) -{ - partition_dialog(); -} - -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) -{ - GUI::instance()->menu->setContext(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; - std::vector<int> p; - char ib; - - 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(); - - while(1) { - switch (dim) { - case 1: - if(p.empty()) - Msg::StatusBar(3, false, "Select lines\n" - "[Press 'e' to end selection or 'q' to abort]"); - else - Msg::StatusBar(3, false, "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::StatusBar(3, false, "Select surface\n[Press 'q' to abort]"); - ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions, elements); - break; - case 3: - Msg::StatusBar(3, false, "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(p.size()) - add_trsfline(p, CTX.filename, - GUI::instance()->meshContext->choice[0]->text(), - GUI::instance()->meshContext->input[2]->value(), - GUI::instance()->meshContext->input[1]->value()); - } - ZeroHighlight(); - Draw(); - p.clear(); - } - if(ib == 'u') { - if(dim == 1) { - if(p.size()){ - ZeroHighlightEntityNum(0, p.back(), 0, 0); - Draw(); - p.pop_back(); - } - } - } - 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.push_back(edges[i]->tag()); - } - Draw(); - break; - case 2: - case 3: - if(dim == 2){ - HighlightEntity(faces[0]); - Draw(); - p.push_back(faces[0]->tag()); - } - else{ - HighlightEntity(regions[0]); - Draw(); - p.push_back(regions[0]->tag()); - } - while(1) { - if(p.size() == 1) - Msg::StatusBar(3, false, "Select (ordered) boundary points\n" - "[Press 'e' to end selection or 'q' to abort]"); - else - Msg::StatusBar(3, false, "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.push_back(vertices[0]->tag()); - } - if(ib == 'u') { - if(p.size() > 1){ - ZeroHighlightEntityNum(p.back(), 0, 0, 0); - Draw(); - p.pop_back(); - } - } - if(ib == 'r') { - Msg::Warning("Entity de-selection not supported yet during transfinite definition"); - } - if(ib == 'e') { - switch (dim) { - case 2: - if(p.size() == 0 + 1 || p.size() == 3 + 1 || p.size() == 4 + 1) - add_trsfsurf(p, CTX.filename, - GUI::instance()->meshContext->choice[1]->text()); - else - Msg::Error("Wrong number of points for transfinite surface"); - break; - case 3: - if(p.size() == 6 + 1 || p.size() == 8 + 1) - add_trsfvol(p, CTX.filename); - else - Msg::Error("Wrong number of points for transfinite volume"); - break; - } - ZeroHighlight(); - Draw(); - p.clear(); - break; - } - if(ib == 'q') { - ZeroHighlight(); - Draw(); - goto stopall; - } - } - break; - } - } - } - -stopall: - Msg::StatusBar(3, false, ""); -} - -void mesh_define_transfinite_line_cb(CALLBACK_ARGS) -{ - GUI::instance()->meshContext->show(1); - _add_transfinite(1); -} - -void mesh_define_transfinite_surface_cb(CALLBACK_ARGS) -{ - GUI::instance()->meshContext->show(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[MAX_NUM_SOLVERS]; - int num = (int)(long)data; - - if(!init) { - for(int i = 0; i < MAX_NUM_SOLVERS; i++) - first[i] = 1; - init = 1; - } - - if(first[num]) { - char file[256]; - first[num] = 0; - strcpy(file, CTX.no_ext_filename); - strcat(file, SINFO[num].extension); - GUI::instance()->solver[num]->input[0]->value(file); - } - if(SINFO[num].nboptions) { - std::string file = FixWindowsPath(GUI::instance()->solver[num]->input[0]->value()); - char tmp[256], tmp2[256]; - sprintf(tmp, "\"%s\"", file.c_str()); - sprintf(tmp2, SINFO[num].name_command, tmp); - sprintf(tmp, "%s %s", SINFO[num].option_command, tmp2); - Solver(num, tmp); - } - GUI::instance()->solver[num]->win->show(); -} - -void solver_file_open_cb(CALLBACK_ARGS) -{ - char tmp[256], tmp2[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, 0, "Choose", tmp)) { - GUI::instance()->solver[num]->input[0]->value(file_chooser_get_name(1).c_str()); - if(SINFO[num].nboptions) { - std::string file = FixWindowsPath(file_chooser_get_name(1).c_str()); - sprintf(tmp, "\"%s\"", file.c_str()); - sprintf(tmp2, SINFO[num].name_command, tmp); - sprintf(tmp, "%s %s", SINFO[num].option_command, tmp2); - Solver(num, tmp); - } - } -} - -void solver_file_edit_cb(CALLBACK_ARGS) -{ - int num = (int)(long)data; - std::string prog = FixWindowsPath(CTX.editor); - std::string file = FixWindowsPath(GUI::instance()->solver[num]->input[0]->value()); - char cmd[1024]; - _replace_multi_format(prog.c_str(), file.c_str(), cmd); - SystemCall(cmd); -} - -void solver_choose_mesh_cb(CALLBACK_ARGS) -{ - int num = (int)(long)data; - if(file_chooser(0, 0, "Choose", "*")) - GUI::instance()->solver[num]->input[1]->value(file_chooser_get_name(1).c_str()); -} - -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], mesh[256], arg[512], command[256]; - int num = ((int *)data)[0]; - int idx = ((int *)data)[1]; - int i, usedopts = 0; - - if(SINFO[num].popup_messages) - GUI::instance()->messages->show(true); - - if(strlen(GUI::instance()->solver[num]->input[1]->value())) { - std::string m = FixWindowsPath(GUI::instance()->solver[num]->input[1]->value()); - sprintf(tmp, "\"%s\"", m.c_str()); - 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::Error("Missing options to execute command"); - return; - } - sprintf(command, SINFO[num].button_command[idx], - SINFO[num].option[usedopts][GUI::instance()->solver[num]->choice[usedopts]->value()]); - } - else { - strcpy(command, SINFO[num].button_command[idx]); - } - - std::string c = FixWindowsPath(GUI::instance()->solver[num]->input[0]->value()); - sprintf(arg, "\"%s\"", c.c_str()); - 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 - )){ - GUI::instance()->solver[num]->input[2]->value(file_chooser_get_name(1).c_str()); - solver_ok_cb(w, data); - } -} - -void solver_ok_cb(CALLBACK_ARGS) -{ - int retry = 0, num = (int)(long)data; - opt_solver_popup_messages(num, GMSH_SET, GUI::instance()->solver[num]->butt[0]->value()); - opt_solver_merge_views(num, GMSH_SET, GUI::instance()->solver[num]->butt[1]->value()); - opt_solver_client_server(num, GMSH_SET, GUI::instance()->solver[num]->butt[2]->value()); - if(strcmp(opt_solver_executable(num, GMSH_GET, NULL), GUI::instance()->solver[num]->input[2]->value())) - retry = 1; - opt_solver_executable(num, GMSH_SET, GUI::instance()->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, - GUI::instance()->menu->toggle[num]->value()); - Draw(); -} - -static void _view_reload(int index) -{ - if(index >= 0 && index < (int)PView::list.size()){ - PView *p = PView::list[index]; - - if(StatFile(p->getData()->getFileName().c_str())){ - Msg::Error("File '%s' does not exist", p->getData()->getFileName().c_str()); - return; - } - - int n = PView::list.size(); - - // FIXME: use fileIndex - MergeFile(p->getData()->getFileName().c_str()); - - if((int)PView::list.size() > n){ // we loaded a new view - // delete old data and replace with new - delete p->getData(); - p->setData(PView::list.back()->getData()); - PView::list.back()->setData(0); - // delete new view - delete PView::list.back(); - // in case the reloaded view has a different number of time steps - if(p->getOptions()->TimeStep > p->getData()->getNumTimeSteps() - 1) - p->getOptions()->TimeStep = 0; - p->setChanged(true); - GUI::instance()->updateViews(); - } - } -} - -void view_reload_cb(CALLBACK_ARGS) -{ - _view_reload((int)(long)data); - Draw(); -} - -void view_reload_all_cb(CALLBACK_ARGS) -{ - for(unsigned int i = 0; i < PView::list.size(); i++) - _view_reload(i); - Draw(); -} - -void view_reload_visible_cb(CALLBACK_ARGS) -{ - for(unsigned int i = 0; i < PView::list.size(); i++) - if(opt_view_visible(i, GMSH_GET, 0)) - _view_reload(i); - Draw(); -} - -void view_remove_other_cb(CALLBACK_ARGS) -{ - if(PView::list.empty()) return; - for(int i = PView::list.size() - 1; i >= 0; i--) - if(i != (long)data) delete PView::list[i]; - GUI::instance()->updateViews(); - Draw(); -} - -void view_remove_all_cb(CALLBACK_ARGS) -{ - if(PView::list.empty()) return; - while(PView::list.size()) delete PView::list[0]; - GUI::instance()->updateViews(); - Draw(); -} - -void view_remove_visible_cb(CALLBACK_ARGS) -{ - if(PView::list.empty()) return; - for(int i = PView::list.size() - 1; i >= 0; i--) - if(opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i]; - GUI::instance()->updateViews(); - Draw(); -} - -void view_remove_invisible_cb(CALLBACK_ARGS) -{ - if(PView::list.empty()) return; - for(int i = PView::list.size() - 1; i >= 0; i--) - if(!opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i]; - GUI::instance()->updateViews(); - Draw(); -} - -void view_remove_empty_cb(CALLBACK_ARGS) -{ - if(PView::list.empty()) return; - for(int i = PView::list.size() - 1; i >= 0; i--) - if(PView::list[i]->getData()->empty()) delete PView::list[i]; - GUI::instance()->updateViews(); - Draw(); -} - -void view_remove_cb(CALLBACK_ARGS) -{ - delete PView::list[(int)(long)data]; - GUI::instance()->updateViews(); - Draw(); -} - -static void _view_save_as(int index, const char *title, int format) -{ - PView *view = PView::list[index]; - - test: - if(file_chooser(0, 1, title, "*", view->getData()->getFileName().c_str())){ - std::string name = file_chooser_get_name(1); - if(CTX.confirm_overwrite) { - if(!StatFile(name.c_str())) - if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", - "Cancel", "Replace", NULL, name.c_str())) - goto test; - } - view->write(name.c_str(), format); - } -} - -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 Raw Text", 4); -} - -void view_save_msh_cb(CALLBACK_ARGS) -{ - _view_save_as((int)(long)data, "Save As Gmsh Mesh", 5); -} - -void view_save_med_cb(CALLBACK_ARGS) -{ - _view_save_as((int)(long)data, "Save As MED file", 6); -} - -void view_alias_cb(CALLBACK_ARGS) -{ - new PView(PView::list[(int)(long)data], false); - GUI::instance()->updateViews(); - Draw(); -} - -void view_alias_with_options_cb(CALLBACK_ARGS) -{ - new PView(PView::list[(int)(long)data], true); - GUI::instance()->updateViews(); - Draw(); -} - -void view_combine_space_all_cb(CALLBACK_ARGS) -{ - PView::combine(false, 1, CTX.post.combine_remove_orig); - GUI::instance()->updateViews(); - Draw(); -} - -void view_combine_space_visible_cb(CALLBACK_ARGS) -{ - PView::combine(false, 0, CTX.post.combine_remove_orig); - GUI::instance()->updateViews(); - Draw(); -} - -void view_combine_space_by_name_cb(CALLBACK_ARGS) -{ - PView::combine(false, 2, CTX.post.combine_remove_orig); - GUI::instance()->updateViews(); - Draw(); -} - -void view_combine_time_all_cb(CALLBACK_ARGS) -{ - PView::combine(true, 1, CTX.post.combine_remove_orig); - GUI::instance()->updateViews(); - Draw(); -} - -void view_combine_time_visible_cb(CALLBACK_ARGS) -{ - PView::combine(true, 0, CTX.post.combine_remove_orig); - GUI::instance()->updateViews(); - Draw(); -} - -void view_combine_time_by_name_cb(CALLBACK_ARGS) -{ - PView::combine(true, 2, CTX.post.combine_remove_orig); - GUI::instance()->updateViews(); - Draw(); -} - -void view_all_visible_cb(CALLBACK_ARGS) -{ - for(unsigned int i = 0; i < PView::list.size(); 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) -{ - int index = (int)(long)data; - if(index >= 0 && index < (int)PView::list.size()){ - GModel::current()->getFields()->set_background_mesh(index); - } -} - -void view_plugin_cb(CALLBACK_ARGS) -{ - GUI::instance()->plugins->show((int)(long)data); -} - -void view_field_cb(CALLBACK_ARGS) -{ - GUI::instance()->fields->win->show(); - GUI::instance()->fields->editField(NULL); -} - -void view_field_delete_cb(CALLBACK_ARGS) -{ - Field *f = (Field*)GUI::instance()->fields->editor_group->user_data(); - delete_field(f->id, CTX.filename); - GUI::instance()->fields->editField(NULL); -} - -void view_field_new_cb(CALLBACK_ARGS) -{ - Fl_Menu_Button* mb = ((Fl_Menu_Button*)w); - FieldManager *fields = GModel::current()->getFields(); - int id = fields->new_id(); - add_field(id, mb->text(), CTX.filename); - GUI::instance()->fields->editField((*fields)[id]); -} - -void view_field_apply_cb(CALLBACK_ARGS) -{ - GUI::instance()->fields->saveFieldOptions(); -} - -void view_field_revert_cb(CALLBACK_ARGS) -{ - GUI::instance()->fields->loadFieldOptions(); -} - -void view_field_browser_cb(CALLBACK_ARGS) -{ - int selected = GUI::instance()->fields->browser->value(); - if(!selected){ - GUI::instance()->fields->editField(NULL); - } - Field *f = (Field*)GUI::instance()->fields->browser->data(selected); - GUI::instance()->fields->editField(f); -} - -void view_field_put_on_view_cb(CALLBACK_ARGS) -{ - Fl_Menu_Button* mb = ((Fl_Menu_Button*)w); - Field *field = (Field*)GUI::instance()->fields->editor_group->user_data(); - int iView; - if(sscanf(mb->text(), "View [%i]", &iView)){ - if(iView < (int)PView::list.size()){ - field->put_on_view(PView::list[iView]); - } - } - else{ - field->put_on_new_view(); - GUI::instance()->updateViews(); - } - Draw(); -} - -void view_field_select_file_cb(CALLBACK_ARGS) -{ - Fl_Input *input = (Fl_Input*)data; - int ret = file_chooser(0, 0, "File selection", "", input->value()); - if(ret){ - input->value(file_chooser_get_name(0).c_str()); - input->set_changed(); - } -} - -void view_field_select_node_cb(CALLBACK_ARGS) -{ - const char *mode = "select"; - const char *help = "vertices"; - CTX.pick_elements = 1; - Draw(); - 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; - opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); - while(1) { - Msg::StatusBar(3, false, "Select %s\n[Press %s'q' to abort]", - help, mode ? "" : "'u' to undo or "); - - char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements); - printf("char = %c\n", ib); - if(ib == 'q'){ - for(std::vector<GVertex*>::iterator it = vertices.begin(); it != vertices.end(); it++){ - printf("%p\n", *it); - } - break; - } - } - CTX.mesh.changed = ENT_ALL; - CTX.pick_elements = 0; - Msg::StatusBar(3, false, ""); - Draw(); -} - -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) -{ - const char* (*f)(int, int, const char*) = (const char* (*)(int, int, const char*)) data; - Fl_Input *input = (Fl_Input*) w; - f(-1, 0, input->value()); -} - -void view_plugin_browser_cb(CALLBACK_ARGS) -{ - // get selected plugin - GMSH_Plugin *p = 0; - for(int i = 1; i <= GUI::instance()->plugins->browser->size(); i++) { - if(GUI::instance()->plugins->browser->selected(i)) { - p = (GMSH_Plugin*)GUI::instance()->plugins->browser->data(i); - break; - } - } - if(!p) return; - - // get first first selected view - int iView = -1; - for(int i = 1; i <= GUI::instance()->plugins->view_browser->size(); i++) { - if(GUI::instance()->plugins->view_browser->selected(i)) { - iView = i - 1; - break; - } - } - - // set the Fl_Value_Input callbacks and configure the input value - // fields (we get step, min and max by calling the option function - // with action==1, 2 and 3, respectively) - 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); - if(iView >= 0){ - 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); - } - } - - // hide all plugin groups except the selected one - for(int i = 1; i <= GUI::instance()->plugins->browser->size(); i++) - ((GMSH_Plugin*)GUI::instance()->plugins->browser->data(i))->dialogBox->group->hide(); - p->dialogBox->group->show(); -} - -void view_plugin_run_cb(CALLBACK_ARGS) -{ - // get selected plugin - GMSH_Post_Plugin *p = 0; - for(int i = 1; i <= GUI::instance()->plugins->browser->size(); i++) { - if(GUI::instance()->plugins->browser->selected(i)) { - p = (GMSH_Post_Plugin*)GUI::instance()->plugins->browser->data(i); - break; - } - } - if(!p) return; - - if(p->dialogBox) { // get the values from the GUI - 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 = p->dialogBox->input[i]->value(); - } - for(int i = 0; i < n; i++) { - StringXNumber *sxn = p->getOption(i); - sxn->def = p->dialogBox->value[i]->value(); - } - } - - // run on all selected views - bool no_view_selected = true; - for(int i = 1; i <= GUI::instance()->plugins->view_browser->size(); i++) { - if(GUI::instance()->plugins->view_browser->selected(i)) { - no_view_selected = false; - try{ - if(i - 1 >= 0 && i - 1 < (int)PView::list.size()) - p->execute(PView::list[i - 1]); - else - p->execute(0); - } - catch(GMSH_Plugin * err) { - char tmp[256]; - p->catchErrorMessage(tmp); - Msg::Warning("%s", tmp); - } - } - } - if(no_view_selected){ - p->execute(0); - } - - GUI::instance()->updateViews(); - CTX.post.plugin_draw_function = NULL; - Draw(); -} - -void view_plugin_cancel_cb(CALLBACK_ARGS) -{ - GUI::instance()->plugins->win->hide(); - CTX.post.plugin_draw_function = NULL; - Draw(); -} - -// Contextual windows for geometry - -void con_geometry_define_parameter_cb(CALLBACK_ARGS) -{ - add_param(GUI::instance()->geoContext->input[0]->value(), - GUI::instance()->geoContext->input[1]->value(), CTX.filename); - GUI::instance()->resetVisibility(); -} - -void con_geometry_define_point_cb(CALLBACK_ARGS) -{ - add_point(CTX.filename, - GUI::instance()->geoContext->input[2]->value(), - GUI::instance()->geoContext->input[3]->value(), - GUI::instance()->geoContext->input[4]->value(), - GUI::instance()->geoContext->input[5]->value()); - GUI::instance()->resetVisibility(); - ZeroHighlight(); - SetBoundingBox(); - Draw(); -} - -void con_geometry_snap_cb(CALLBACK_ARGS) -{ - CTX.geom.snap[0] = GUI::instance()->geoContext->value[0]->value(); - CTX.geom.snap[1] = GUI::instance()->geoContext->value[1]->value(); - CTX.geom.snap[2] = GUI::instance()->geoContext->value[2]->value(); -} diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h deleted file mode 100644 index 4dcd312614..0000000000 --- a/Fltk/Callbacks.h +++ /dev/null @@ -1,258 +0,0 @@ -// Gmsh - Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle -// -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. - -#ifndef _CALLBACKS_H_ -#define _CALLBACKS_H_ - -#include <FL/Fl_Widget.H> - -#define CALLBACK_ARGS Fl_Widget* w, void* data - -void ManualPlay(int time, int step); - -// Common callbacks - -void cancel_cb(CALLBACK_ARGS); -void color_cb(CALLBACK_ARGS); -void view_color_cb(CALLBACK_ARGS); -void redraw_cb(CALLBACK_ARGS); -void window_cb(CALLBACK_ARGS); -void activate_cb(CALLBACK_ARGS); - -// Graphical window - -void status_xyz1p_cb(CALLBACK_ARGS); -void status_play_cb(CALLBACK_ARGS); -void status_pause_cb(CALLBACK_ARGS); -void status_rewind_cb(CALLBACK_ARGS); -void status_stepbackward_cb(CALLBACK_ARGS); -void status_stepforward_cb(CALLBACK_ARGS); - -// File Menu - -void file_new_cb(CALLBACK_ARGS); -void file_open_cb(CALLBACK_ARGS); -void file_merge_cb(CALLBACK_ARGS); -void file_rename_cb(CALLBACK_ARGS); -void file_save_as_cb(CALLBACK_ARGS); -void file_save_as_auto_cb(CALLBACK_ARGS); -void file_save_as_geo_cb(CALLBACK_ARGS); -void file_save_as_geo_options_cb(CALLBACK_ARGS); -void file_save_as_msh_cb(CALLBACK_ARGS); -void file_save_as_msh_all_cb(CALLBACK_ARGS); -void file_save_as_unv_cb(CALLBACK_ARGS); -void file_save_as_gref_cb(CALLBACK_ARGS); -void file_save_as_vrml_cb(CALLBACK_ARGS); -void file_save_as_ps_simple_cb(CALLBACK_ARGS); -void file_save_as_ps_accurate_cb(CALLBACK_ARGS); -void file_save_as_epstex_simple_cb(CALLBACK_ARGS); -void file_save_as_epstex_accurate_cb(CALLBACK_ARGS); -void file_save_as_jpegtex_cb(CALLBACK_ARGS); -void file_save_as_pngtex_cb(CALLBACK_ARGS); -void file_save_as_tex_cb(CALLBACK_ARGS); -void file_save_as_jpeg_cb(CALLBACK_ARGS); -void file_save_as_png_cb(CALLBACK_ARGS); -void file_save_as_gif_cb(CALLBACK_ARGS); -void file_save_as_gif_dithered_cb(CALLBACK_ARGS); -void file_save_as_gif_transparent_cb(CALLBACK_ARGS); -void file_save_as_ppm_cb(CALLBACK_ARGS); -void file_save_as_yuv_cb(CALLBACK_ARGS); -void file_quit_cb(CALLBACK_ARGS); - -// Option Menu - -void options_cb(CALLBACK_ARGS); -void options_browser_cb(CALLBACK_ARGS); -void options_save_cb(CALLBACK_ARGS); -void options_restore_defaults_cb(CALLBACK_ARGS); - -void general_options_cb(CALLBACK_ARGS); -void general_options_ok_cb(CALLBACK_ARGS); -void general_options_color_scheme_cb(CALLBACK_ARGS); -void general_options_rotation_center_select_cb(CALLBACK_ARGS); -void general_arrow_param_cb(CALLBACK_ARGS); - -void geometry_options_cb(CALLBACK_ARGS); -void geometry_options_ok_cb(CALLBACK_ARGS); - -void mesh_options_cb(CALLBACK_ARGS); -void mesh_options_ok_cb(CALLBACK_ARGS); - -void solver_options_cb(CALLBACK_ARGS); -void solver_options_ok_cb(CALLBACK_ARGS); - -void post_options_cb(CALLBACK_ARGS); -void post_options_ok_cb(CALLBACK_ARGS); - -void view_options_cb(CALLBACK_ARGS); -void view_options_ok_cb(CALLBACK_ARGS); -void view_options_timestep_cb(CALLBACK_ARGS); -void view_options_timestep_decr_cb(CALLBACK_ARGS); -void view_options_timestep_incr_cb(CALLBACK_ARGS); -void view_arrow_param_cb(CALLBACK_ARGS); -void view_toggle_cb(CALLBACK_ARGS); -void view_reload_cb(CALLBACK_ARGS); -void view_reload_all_cb(CALLBACK_ARGS); -void view_reload_visible_cb(CALLBACK_ARGS); -void view_remove_cb(CALLBACK_ARGS); -void view_remove_other_cb(CALLBACK_ARGS); -void view_remove_all_cb(CALLBACK_ARGS); -void view_remove_visible_cb(CALLBACK_ARGS); -void view_remove_invisible_cb(CALLBACK_ARGS); -void view_remove_empty_cb(CALLBACK_ARGS); -void view_save_ascii_cb(CALLBACK_ARGS); -void view_save_binary_cb(CALLBACK_ARGS); -void view_save_parsed_cb(CALLBACK_ARGS); -void view_save_stl_cb(CALLBACK_ARGS); -void view_save_txt_cb(CALLBACK_ARGS); -void view_save_msh_cb(CALLBACK_ARGS); -void view_save_med_cb(CALLBACK_ARGS); -void view_alias_cb(CALLBACK_ARGS); -void view_alias_with_options_cb(CALLBACK_ARGS); -void view_combine_space_all_cb(CALLBACK_ARGS); -void view_combine_space_visible_cb(CALLBACK_ARGS); -void view_combine_space_by_name_cb(CALLBACK_ARGS); -void view_combine_time_all_cb(CALLBACK_ARGS); -void view_combine_time_visible_cb(CALLBACK_ARGS); -void view_combine_time_by_name_cb(CALLBACK_ARGS); -void view_all_visible_cb(CALLBACK_ARGS); -void view_applybgmesh_cb(CALLBACK_ARGS); -void view_field_cb(CALLBACK_ARGS); -void view_field_new_cb(CALLBACK_ARGS); -void view_field_apply_cb(CALLBACK_ARGS); -void view_field_revert_cb(CALLBACK_ARGS); -void view_field_browser_cb(CALLBACK_ARGS); -void view_field_delete_cb(CALLBACK_ARGS); -void view_field_select_file_cb(CALLBACK_ARGS); -void view_field_put_on_view_cb(CALLBACK_ARGS); -void view_field_select_node_cb(CALLBACK_ARGS); -void view_plugin_cb(CALLBACK_ARGS); -void view_plugin_browser_cb(CALLBACK_ARGS); -void view_plugin_run_cb(CALLBACK_ARGS); -void view_plugin_cancel_cb(CALLBACK_ARGS); - -// Statistics Menu - -void statistics_cb(CALLBACK_ARGS); -void statistics_update_cb(CALLBACK_ARGS); -void statistics_histogram_cb(CALLBACK_ARGS); - -// Message Menu - -void message_cb(CALLBACK_ARGS); -void message_auto_scroll_cb(CALLBACK_ARGS); -void message_copy_cb(CALLBACK_ARGS); -void message_clear_cb(CALLBACK_ARGS); -void message_save_cb(CALLBACK_ARGS); - -// Visibility Menu - -void visibility_cb(CALLBACK_ARGS); -void visibility_sort_cb(CALLBACK_ARGS); -void visibility_number_cb(CALLBACK_ARGS); -void visibility_interactive_cb(CALLBACK_ARGS); -void visibility_ok_cb(CALLBACK_ARGS); -void visibility_save_cb(CALLBACK_ARGS); -void visibility_delete_cb(CALLBACK_ARGS); - -// Clipping planes Menu - -void clip_cb(CALLBACK_ARGS); -void clip_update_cb(CALLBACK_ARGS); -void clip_invert_cb(CALLBACK_ARGS); -void clip_num_cb(CALLBACK_ARGS); -void clip_reset_cb(CALLBACK_ARGS); - -// Manipulator Menu - -void manip_cb(CALLBACK_ARGS); -void manip_update_cb(CALLBACK_ARGS); - -// Help Menu - -void help_short_cb(CALLBACK_ARGS); -void help_mouse_cb(CALLBACK_ARGS); -void help_command_line_cb(CALLBACK_ARGS); -void help_online_cb(CALLBACK_ARGS); -void help_license_cb(CALLBACK_ARGS); -void help_credits_cb(CALLBACK_ARGS); -void help_about_cb(CALLBACK_ARGS); - -// Module Menu - -void mod_geometry_cb(CALLBACK_ARGS); -void mod_mesh_cb(CALLBACK_ARGS); -void mod_solver_cb(CALLBACK_ARGS); -void mod_post_cb(CALLBACK_ARGS); -void mod_back_cb(CALLBACK_ARGS); -void mod_forward_cb(CALLBACK_ARGS); - -// Dynamic Geometry Menus - -void geometry_elementary_cb(CALLBACK_ARGS); -void geometry_elementary_add_cb(CALLBACK_ARGS); -void geometry_elementary_add_new_cb(CALLBACK_ARGS); -void geometry_elementary_add_translate_cb(CALLBACK_ARGS); -void geometry_elementary_add_rotate_cb(CALLBACK_ARGS); -void geometry_elementary_add_scale_cb(CALLBACK_ARGS); -void geometry_elementary_add_symmetry_cb(CALLBACK_ARGS); -void geometry_elementary_delete_cb(CALLBACK_ARGS); -void geometry_elementary_split_cb(CALLBACK_ARGS); -void geometry_elementary_translate_cb(CALLBACK_ARGS); -void geometry_elementary_rotate_cb(CALLBACK_ARGS); -void geometry_elementary_scale_cb(CALLBACK_ARGS); -void geometry_elementary_symmetry_cb(CALLBACK_ARGS); -void geometry_elementary_extrude_cb(CALLBACK_ARGS); -void geometry_elementary_extrude_translate_cb(CALLBACK_ARGS); -void geometry_elementary_extrude_rotate_cb(CALLBACK_ARGS); -void geometry_elementary_coherence_cb(CALLBACK_ARGS); -void geometry_physical_cb(CALLBACK_ARGS); -void geometry_physical_add_cb(CALLBACK_ARGS); -void geometry_edit_cb(CALLBACK_ARGS); -void geometry_reload_cb(CALLBACK_ARGS); - -void con_geometry_define_parameter_cb(CALLBACK_ARGS); -void con_geometry_define_point_cb(CALLBACK_ARGS); -void con_geometry_snap_cb(CALLBACK_ARGS); - -// Dynamic Mesh Menus - -void mesh_save_cb(CALLBACK_ARGS); -void mesh_define_cb(CALLBACK_ARGS); -void mesh_1d_cb(CALLBACK_ARGS); -void mesh_2d_cb(CALLBACK_ARGS); -void mesh_3d_cb(CALLBACK_ARGS); -void mesh_delete_cb(CALLBACK_ARGS); -void mesh_delete_parts_cb(CALLBACK_ARGS); -void mesh_inspect_cb(CALLBACK_ARGS); -void mesh_remesh_cb(CALLBACK_ARGS); -void mesh_update_edges_cb(CALLBACK_ARGS); -void mesh_parameterize_cb(CALLBACK_ARGS); -void mesh_degree_cb(CALLBACK_ARGS); -void mesh_refine_cb(CALLBACK_ARGS); -void mesh_optimize_cb(CALLBACK_ARGS); -void mesh_optimize_netgen_cb(CALLBACK_ARGS); -void mesh_partition_cb(CALLBACK_ARGS); -void mesh_classify_cb(CALLBACK_ARGS); -void mesh_define_length_cb (CALLBACK_ARGS); -void mesh_define_recombine_cb (CALLBACK_ARGS); -void mesh_define_transfinite_cb (CALLBACK_ARGS); -void mesh_define_transfinite_line_cb(CALLBACK_ARGS); -void mesh_define_transfinite_surface_cb(CALLBACK_ARGS); -void mesh_define_transfinite_volume_cb(CALLBACK_ARGS); - -// Dynamic Solver Menus - -void solver_cb(CALLBACK_ARGS); -void solver_file_open_cb(CALLBACK_ARGS); -void solver_file_edit_cb(CALLBACK_ARGS); -void solver_choose_mesh_cb(CALLBACK_ARGS); -void solver_command_cb(CALLBACK_ARGS); -void solver_kill_cb(CALLBACK_ARGS); -void solver_choose_executable_cb(CALLBACK_ARGS); -void solver_ok_cb(CALLBACK_ARGS); - -#endif - diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp index cf329f4093..f016763178 100644 --- a/Fltk/GUI.cpp +++ b/Fltk/GUI.cpp @@ -25,6 +25,7 @@ #include "colorbarWindow.h" #include "popupButton.h" #include "fileDialogs.h" +#include "Draw.h" #include "GmshDefines.h" #include "GmshMessage.h" #include "GModel.h" @@ -33,7 +34,6 @@ #include "Field.h" #include "Plugin.h" #include "PluginManager.h" -#include "Callbacks.h" #include "OpenFile.h" #include "Options.h" #include "Context.h" @@ -474,9 +474,7 @@ int GUI::testGlobalShortcuts(int event) } if(status == 2){ - graph[0]->gl->make_current(); - graph[0]->gl->redraw(); - check(); + Draw(); return 1; } else if(status == 1) @@ -488,19 +486,19 @@ int GUI::testGlobalShortcuts(int event) int GUI::testArrowShortcuts() { if(Fl::test_shortcut(FL_Left)) { - ManualPlay(1, -1); + status_play_manual(1, -1); return 1; } else if(Fl::test_shortcut(FL_Right)) { - ManualPlay(1, 1); + status_play_manual(1, 1); return 1; } else if(Fl::test_shortcut(FL_Up)) { - ManualPlay(0, -1); + status_play_manual(0, -1); return 1; } else if(Fl::test_shortcut(FL_Down)) { - ManualPlay(0, 1); + status_play_manual(0, 1); return 1; } return 0; @@ -561,9 +559,7 @@ void GUI::setStatus(const char *msg, int num) else onscreen_buffer[1][0] = '\0'; onscreen_buffer[0][i-1] = '\0'; - graph[0]->gl->make_current(); - graph[0]->gl->redraw(); - check(); + Draw(); } } @@ -609,6 +605,82 @@ void GUI::callForSolverPlugin(int dim) if(sp) sp->popupPropertiesForPhysicalEntity(dim); } +// Callbacks + +void hide_cb(Fl_Widget *w, void *data) +{ + if(data) ((Fl_Widget *)data)->hide(); +} + +void redraw_cb(Fl_Widget *w, void *data) +{ + Draw(); +} + +void window_cb(Fl_Widget *w, void *data) +{ + static int oldx = 0, oldy = 0, oldw = 0, oldh = 0, zoom = 1; + const char *str = (const char*)data; + + if(!strcmp(str, "minimize")){ + GUI::instance()->graph[0]->win->iconize(); + GUI::instance()->options->win->iconize(); + GUI::instance()->plugins->win->iconize(); + GUI::instance()->fields->win->iconize(); + GUI::instance()->visibility->win->iconize(); + GUI::instance()->clipping->win->iconize(); + GUI::instance()->manip->win->iconize(); + GUI::instance()->stats->win->iconize(); + GUI::instance()->messages->win->iconize(); + GUI::instance()->menu->win->iconize(); + } + else if(!strcmp(str, "zoom")){ + if(zoom){ + oldx = GUI::instance()->graph[0]->win->x(); + oldy = GUI::instance()->graph[0]->win->y(); + oldw = GUI::instance()->graph[0]->win->w(); + oldh = GUI::instance()->graph[0]->win->h(); + GUI::instance()->graph[0]->win->resize(Fl::x(), Fl::y(), Fl::w(), Fl::h()); + zoom = 0; + } + else{ + GUI::instance()->graph[0]->win->resize(oldx, oldy, oldw, oldh); + zoom = 1; + } + GUI::instance()->graph[0]->win->show(); + GUI::instance()->menu->win->show(); + } + else if(!strcmp(str, "front")){ + // the order is important! + GUI::instance()->graph[0]->win->show(); + if(GUI::instance()->options->win->shown()) + GUI::instance()->options->win->show(); + if(GUI::instance()->plugins->win->shown()) + GUI::instance()->plugins->win->show(); + if(GUI::instance()->fields->win->shown()) + GUI::instance()->fields->win->show(); + if(GUI::instance()->geoContext->win->shown()) + GUI::instance()->geoContext->win->show(); + if(GUI::instance()->meshContext->win->shown()) + GUI::instance()->meshContext->win->show(); + for(unsigned int i = 0; i < GUI::instance()->solver.size(); i++) { + if(GUI::instance()->solver[i]->win->shown()) + GUI::instance()->solver[i]->win->show(); + } + if(GUI::instance()->visibility->win->shown()) + GUI::instance()->visibility->win->show(); + if(GUI::instance()->clipping->win->shown()) + GUI::instance()->clipping->win->show(); + if(GUI::instance()->manip->win->shown()) + GUI::instance()->manip->win->show(); + if(GUI::instance()->stats->win->shown()) + GUI::instance()->stats->win->show(); + if(GUI::instance()->messages->win->shown()) + GUI::instance()->messages->win->show(); + GUI::instance()->menu->win->show(); + } +} + // Utility routines int GetFontIndex(const char *fontname) diff --git a/Fltk/GUI.h b/Fltk/GUI.h index 7cb7958dd7..5e67852a33 100644 --- a/Fltk/GUI.h +++ b/Fltk/GUI.h @@ -95,6 +95,11 @@ class GUI{ void callForSolverPlugin(int dim); }; +// callbacks +void hide_cb(Fl_Widget *w, void *data); +void redraw_cb(Fl_Widget *w, void *data); +void window_cb(Fl_Widget *w, void *data); + // utility functions int GetFontIndex(const char *fontname); int GetFontEnum(int index); diff --git a/Fltk/Makefile b/Fltk/Makefile index 1d8dc146d2..a0bb89684d 100644 --- a/Fltk/Makefile +++ b/Fltk/Makefile @@ -36,7 +36,6 @@ SRC = Main.cpp \ projectionEditor.cpp\ classificationEditor.cpp\ partitionDialog.cpp\ - Callbacks.cpp\ Draw.cpp\ Solvers.cpp @@ -89,7 +88,7 @@ GUI${OBJEXT}: GUI.cpp GUI.h graphicWindow.h openglWindow.h \ colorbarWindow.h ../Post/ColorTable.h fieldWindow.h pluginWindow.h \ statisticsWindow.h visibilityWindow.h clippingWindow.h messageWindow.h \ manipWindow.h contextWindow.h solverWindow.h aboutWindow.h \ - fileDialogs.h ../Common/GmshDefines.h ../Common/GmshMessage.h \ + fileDialogs.h Draw.h ../Common/GmshDefines.h ../Common/GmshMessage.h \ ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \ ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/GPoint.h \ ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \ @@ -100,11 +99,13 @@ GUI${OBJEXT}: GUI.cpp GUI.h graphicWindow.h openglWindow.h \ ../Geo/SBoundingBox3d.h ../Post/PView.h Solvers.h ../Mesh/Field.h \ ../Plugin/Plugin.h ../Common/Options.h ../Post/PViewDataList.h \ ../Post/PViewData.h ../Common/ListUtils.h ../Numeric/GmshMatrix.h \ - ../Plugin/PluginManager.h Callbacks.h ../Common/OpenFile.h \ - ../Common/Context.h ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h -graphicWindow${OBJEXT}: graphicWindow.cpp graphicWindow.h openglWindow.h \ + ../Plugin/PluginManager.h ../Common/OpenFile.h ../Common/Context.h \ + ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h +graphicWindow${OBJEXT}: graphicWindow.cpp GUI.h graphicWindow.h openglWindow.h \ ../Graphics/drawContext.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \ - shortcutWindow.h ../Post/PView.h ../Post/PViewData.h Callbacks.h \ + shortcutWindow.h menuWindow.h popupButton.h messageWindow.h \ + manipWindow.h extraDialogs.h Draw.h ../Post/PView.h ../Post/PViewData.h \ + ../Common/OS.h ../Common/Options.h ../Post/ColorTable.h \ ../Common/Context.h ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h openglWindow${OBJEXT}: openglWindow.cpp openglWindow.h ../Graphics/drawContext.h \ ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h graphicWindow.h manipWindow.h \ @@ -122,42 +123,80 @@ openglWindow${OBJEXT}: openglWindow.cpp openglWindow.h ../Graphics/drawContext.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h ../Geo/MFace.h \ ../Geo/MVertex.h ../Geo/SVector3.h ../Numeric/FunctionSpace.h \ ../Numeric/GmshMatrix.h -menuWindow${OBJEXT}: menuWindow.cpp GUI.h menuWindow.h popupButton.h \ - shortcutWindow.h Callbacks.h ../Common/Options.h ../Post/ColorTable.h \ - Solvers.h ../Common/GmshMessage.h ../Post/PView.h ../Geo/SPoint3.h \ - ../Post/PViewData.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \ - ../Post/PViewOptions.h ../Post/ColorTable.h ../Common/Context.h \ - ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h +menuWindow${OBJEXT}: menuWindow.cpp GUI.h Draw.h menuWindow.h popupButton.h \ + shortcutWindow.h graphicWindow.h openglWindow.h \ + ../Graphics/drawContext.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \ + optionWindow.h spherePositionWidget.h colorbarWindow.h \ + ../Post/ColorTable.h statisticsWindow.h messageWindow.h contextWindow.h \ + visibilityWindow.h clippingWindow.h manipWindow.h fieldWindow.h \ + pluginWindow.h solverWindow.h aboutWindow.h fileDialogs.h \ + partitionDialog.h projectionEditor.h ../Geo/fourierProjectionFace.h \ + ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \ + ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/GPoint.h \ + ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \ + ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \ + ../Geo/GFace.h ../Geo/GEntity.h ../Geo/GPoint.h ../Geo/GEdgeLoop.h \ + ../Geo/GEdge.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \ + ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/SPoint3.h \ + ../Geo/SBoundingBox3d.h ../Geo/Range.h classificationEditor.h \ + ../Geo/MElement.h ../Common/GmshDefines.h ../Geo/MVertex.h \ + ../Geo/SPoint2.h ../Geo/SPoint3.h ../Geo/MEdge.h ../Geo/MVertex.h \ + ../Geo/SVector3.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \ + ../Common/GmshMessage.h ../Numeric/FunctionSpace.h \ + ../Numeric/GmshMatrix.h ../Common/Options.h Solvers.h \ + ../Common/CommandLine.h ../Mesh/Generator.h ../Mesh/HighOrder.h \ + ../Post/PView.h ../Post/PViewData.h ../Post/PViewOptions.h \ + ../Post/ColorTable.h ../Mesh/Field.h ../Common/OS.h \ + ../Common/StringUtils.h ../Graphics/SelectBuffer.h \ + ../Graphics/drawContext.h ../Common/OpenFile.h ../Common/CreateFile.h \ + ../Geo/findLinks.h ../Common/ListUtils.h ../Geo/GeoStringInterface.h \ + ../Common/Context.h ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h optionWindow${OBJEXT}: optionWindow.cpp GUI.h optionWindow.h \ spherePositionWidget.h colorbarWindow.h ../Post/ColorTable.h \ - shortcutWindow.h ../Common/GmshMessage.h ../Common/Options.h \ - Callbacks.h ../Post/PView.h ../Geo/SPoint3.h ../Post/PViewData.h \ - ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Post/PViewOptions.h \ - ../Post/ColorTable.h ../Common/Context.h ../Geo/CGNSOptions.h \ + shortcutWindow.h menuWindow.h popupButton.h extraDialogs.h Draw.h \ + ../Graphics/SelectBuffer.h ../Graphics/drawContext.h \ + ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/GVertex.h \ + ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \ + ../Geo/SBoundingBox3d.h ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h \ + ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \ + ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/GFace.h ../Geo/GEntity.h \ + ../Geo/GPoint.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/SPoint2.h \ + ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h \ + ../Common/GmshDefines.h ../Common/GmshMessage.h ../Common/Options.h \ + Solvers.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEdge.h \ + ../Geo/GFace.h ../Geo/GRegion.h ../Geo/SPoint3.h \ + ../Geo/SBoundingBox3d.h ../Geo/MElement.h ../Geo/MVertex.h \ + ../Geo/SPoint2.h ../Geo/SPoint3.h ../Geo/MEdge.h ../Geo/MVertex.h \ + ../Geo/SVector3.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \ + ../Numeric/FunctionSpace.h ../Numeric/GmshMatrix.h ../Post/PView.h \ + ../Post/PViewData.h ../Post/PViewOptions.h ../Post/ColorTable.h \ + ../Common/OS.h ../Common/Context.h ../Geo/CGNSOptions.h \ ../Mesh/PartitionOptions.h colorbarWindow${OBJEXT}: colorbarWindow.cpp colorbarWindow.h \ ../Post/ColorTable.h GUI.h ../Common/Context.h ../Geo/CGNSOptions.h \ ../Mesh/PartitionOptions.h -fieldWindow${OBJEXT}: fieldWindow.cpp GUI.h fieldWindow.h shortcutWindow.h \ - ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \ - ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \ - ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h \ - ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \ - ../Geo/SPoint2.h ../Geo/GFace.h ../Geo/GEntity.h ../Geo/GPoint.h \ - ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/SPoint2.h ../Geo/SVector3.h \ - ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/SPoint3.h \ - ../Geo/SBoundingBox3d.h ../Post/PView.h Callbacks.h \ - ../Common/GmshMessage.h ../Mesh/Field.h ../Geo/GeoStringInterface.h \ - ../Common/ListUtils.h ../Common/Context.h ../Geo/CGNSOptions.h \ - ../Mesh/PartitionOptions.h -pluginWindow${OBJEXT}: pluginWindow.cpp GUI.h pluginWindow.h shortcutWindow.h \ - ../Post/PView.h ../Geo/SPoint3.h ../Plugin/PluginManager.h \ - ../Plugin/Plugin.h ../Common/Options.h ../Post/ColorTable.h \ - ../Common/GmshMessage.h ../Post/PViewDataList.h ../Post/PViewData.h \ - ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/ListUtils.h \ - ../Numeric/GmshMatrix.h Callbacks.h ../Common/Context.h \ +fieldWindow${OBJEXT}: fieldWindow.cpp GUI.h Draw.h fieldWindow.h \ + shortcutWindow.h fileDialogs.h ../Common/GmshDefines.h ../Geo/GModel.h \ + ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \ + ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/GPoint.h \ + ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \ + ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \ + ../Geo/GFace.h ../Geo/GEntity.h ../Geo/GPoint.h ../Geo/GEdgeLoop.h \ + ../Geo/GEdge.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \ + ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/SPoint3.h \ + ../Geo/SBoundingBox3d.h ../Post/PView.h ../Common/GmshMessage.h \ + ../Mesh/Field.h ../Geo/GeoStringInterface.h ../Common/ListUtils.h \ + ../Graphics/SelectBuffer.h ../Graphics/drawContext.h \ + ../Common/Options.h ../Post/ColorTable.h ../Common/Context.h \ ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h -statisticsWindow${OBJEXT}: statisticsWindow.cpp GUI.h statisticsWindow.h \ +pluginWindow${OBJEXT}: pluginWindow.cpp GUI.h Draw.h pluginWindow.h \ + shortcutWindow.h ../Post/PView.h ../Geo/SPoint3.h \ + ../Plugin/PluginManager.h ../Plugin/Plugin.h ../Common/Options.h \ + ../Post/ColorTable.h ../Common/GmshMessage.h ../Post/PViewDataList.h \ + ../Post/PViewData.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \ + ../Common/ListUtils.h ../Numeric/GmshMatrix.h ../Common/Context.h \ + ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h +statisticsWindow${OBJEXT}: statisticsWindow.cpp GUI.h Draw.h statisticsWindow.h \ shortcutWindow.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h \ ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \ ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h \ @@ -165,31 +204,64 @@ statisticsWindow${OBJEXT}: statisticsWindow.cpp GUI.h statisticsWindow.h \ ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/GFace.h ../Geo/GEntity.h \ ../Geo/GPoint.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/SPoint2.h \ ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h \ - ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Post/PView.h Callbacks.h \ - ../Mesh/Generator.h ../Common/Context.h ../Geo/CGNSOptions.h \ - ../Mesh/PartitionOptions.h -visibilityWindow${OBJEXT}: visibilityWindow.cpp GUI.h visibilityWindow.h \ - shortcutWindow.h Callbacks.h ../Common/Context.h ../Geo/CGNSOptions.h \ - ../Mesh/PartitionOptions.h -clippingWindow${OBJEXT}: clippingWindow.cpp GUI.h clippingWindow.h \ - shortcutWindow.h ../Post/PView.h ../Geo/SPoint3.h \ - ../Post/PViewOptions.h ../Post/ColorTable.h ../Geo/SBoundingBox3d.h \ - ../Geo/SPoint3.h Callbacks.h ../Common/Context.h ../Geo/CGNSOptions.h \ + ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/MElement.h \ + ../Common/GmshDefines.h ../Geo/MVertex.h ../Geo/SPoint2.h \ + ../Geo/SPoint3.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \ + ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \ + ../Common/GmshMessage.h ../Numeric/FunctionSpace.h \ + ../Numeric/GmshMatrix.h ../Post/PView.h ../Mesh/Generator.h \ + ../Common/Context.h ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h +visibilityWindow${OBJEXT}: visibilityWindow.cpp GUI.h Draw.h visibilityWindow.h \ + shortcutWindow.h contextWindow.h ../Common/GmshDefines.h \ + ../Common/GmshMessage.h ../Geo/GModel.h ../Geo/GVertex.h \ + ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \ + ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/GPoint.h \ + ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \ + ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \ + ../Geo/GFace.h ../Geo/GEntity.h ../Geo/GPoint.h ../Geo/GEdgeLoop.h \ + ../Geo/GEdge.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \ + ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/SPoint3.h \ + ../Geo/SBoundingBox3d.h ../Geo/MElement.h ../Geo/MVertex.h \ + ../Geo/SPoint2.h ../Geo/SPoint3.h ../Geo/MEdge.h ../Geo/MVertex.h \ + ../Geo/SVector3.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \ + ../Numeric/FunctionSpace.h ../Numeric/GmshMatrix.h \ + ../Common/Visibility.h ../Common/GmshDefines.h \ + ../Graphics/SelectBuffer.h ../Graphics/drawContext.h \ + ../Geo/GeoStringInterface.h ../Common/ListUtils.h ../Common/Options.h \ + ../Post/ColorTable.h ../Common/Context.h ../Geo/CGNSOptions.h \ ../Mesh/PartitionOptions.h +clippingWindow${OBJEXT}: clippingWindow.cpp GUI.h Draw.h clippingWindow.h \ + shortcutWindow.h ../Common/GmshDefines.h ../Post/PView.h \ + ../Geo/SPoint3.h ../Post/PViewOptions.h ../Post/ColorTable.h \ + ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/Context.h \ + ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h messageWindow${OBJEXT}: messageWindow.cpp GUI.h messageWindow.h shortcutWindow.h \ - Callbacks.h ../Common/GmshMessage.h ../Common/Context.h \ + fileDialogs.h ../Common/GmshMessage.h ../Common/OS.h \ + ../Common/Context.h ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h +manipWindow${OBJEXT}: manipWindow.cpp GUI.h Draw.h manipWindow.h \ + shortcutWindow.h graphicWindow.h openglWindow.h \ + ../Graphics/drawContext.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \ + ../Common/Options.h ../Post/ColorTable.h ../Common/Context.h \ ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h -manipWindow${OBJEXT}: manipWindow.cpp GUI.h manipWindow.h shortcutWindow.h \ - Callbacks.h ../Common/Options.h ../Post/ColorTable.h \ +contextWindow${OBJEXT}: contextWindow.cpp GUI.h Draw.h contextWindow.h \ + shortcutWindow.h ../Geo/GeoStringInterface.h ../Common/ListUtils.h \ + ../Common/OpenFile.h ../Graphics/SelectBuffer.h \ + ../Graphics/drawContext.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \ + ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \ + ../Geo/SBoundingBox3d.h ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h \ + ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \ + ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/GFace.h ../Geo/GEntity.h \ + ../Geo/GPoint.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/SPoint2.h \ + ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h \ ../Common/Context.h ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h -contextWindow${OBJEXT}: contextWindow.cpp GUI.h contextWindow.h shortcutWindow.h \ - Callbacks.h ../Common/Context.h ../Geo/CGNSOptions.h \ - ../Mesh/PartitionOptions.h solverWindow${OBJEXT}: solverWindow.cpp GUI.h solverWindow.h shortcutWindow.h \ - Solvers.h Callbacks.h ../Common/Context.h ../Geo/CGNSOptions.h \ - ../Mesh/PartitionOptions.h + optionWindow.h spherePositionWidget.h colorbarWindow.h \ + ../Post/ColorTable.h messageWindow.h fileDialogs.h \ + ../Common/GmshMessage.h Solvers.h ../Common/StringUtils.h \ + ../Common/Options.h ../Common/OS.h ../Common/Context.h \ + ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h aboutWindow${OBJEXT}: aboutWindow.cpp GUI.h aboutWindow.h shortcutWindow.h \ - ../Common/CommandLine.h ../Common/StringUtils.h Callbacks.h \ + ../Common/CommandLine.h ../Common/StringUtils.h ../Common/OS.h \ ../Common/Context.h ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h fileDialogs${OBJEXT}: fileDialogs.cpp GUI.h shortcutWindow.h \ ../Common/GmshDefines.h ../Common/CreateFile.h ../Common/Options.h \ @@ -270,37 +342,6 @@ partitionDialog${OBJEXT}: partitionDialog.cpp GUI.h shortcutWindow.h \ ../Geo/SBoundingBox3d.h Draw.h ../Common/Options.h ../Post/ColorTable.h \ ../Mesh/Partition.h ../Common/Context.h ../Geo/CGNSOptions.h \ ../Mesh/PartitionOptions.h -Callbacks${OBJEXT}: Callbacks.cpp GUI.h menuWindow.h popupButton.h \ - graphicWindow.h openglWindow.h ../Graphics/drawContext.h \ - ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h optionWindow.h \ - spherePositionWidget.h colorbarWindow.h ../Post/ColorTable.h \ - visibilityWindow.h clippingWindow.h statisticsWindow.h solverWindow.h \ - manipWindow.h messageWindow.h fieldWindow.h pluginWindow.h \ - contextWindow.h aboutWindow.h partitionDialog.h extraDialogs.h \ - fileDialogs.h ../Common/GmshMessage.h ../Common/MallocUtils.h \ - ../Common/ListUtils.h ../Common/StringUtils.h ../Geo/GModel.h \ - ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \ - ../Geo/SBoundingBox3d.h ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h \ - ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \ - ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/GFace.h ../Geo/GEntity.h \ - ../Geo/GPoint.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/SPoint2.h \ - ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h \ - ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/MElement.h \ - ../Common/GmshDefines.h ../Geo/MVertex.h ../Geo/SPoint2.h \ - ../Geo/SPoint3.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \ - ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \ - ../Numeric/FunctionSpace.h ../Numeric/GmshMatrix.h \ - ../Geo/GeoStringInterface.h ../Geo/findLinks.h ../Mesh/Generator.h \ - ../Mesh/HighOrder.h Draw.h ../Graphics/SelectBuffer.h \ - ../Graphics/drawContext.h ../Post/PView.h ../Post/PViewOptions.h \ - ../Post/ColorTable.h ../Post/PViewData.h ../Common/CreateFile.h \ - ../Common/OpenFile.h ../Common/CommandLine.h ../Common/Context.h \ - ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h ../Common/Options.h \ - Callbacks.h ../Plugin/Plugin.h ../Post/PViewDataList.h \ - ../Post/PViewData.h ../Plugin/PluginManager.h ../Common/Visibility.h \ - ../Common/GmshDefines.h ../Numeric/Numeric.h \ - ../Numeric/NumericEmbedded.h Solvers.h ../Common/OS.h ../Mesh/Field.h \ - ../Mesh/BackgroundMesh.h Draw${OBJEXT}: Draw.cpp GUI.h graphicWindow.h openglWindow.h \ ../Graphics/drawContext.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \ ../Common/GmshDefines.h Draw.h ../Common/StringUtils.h \ diff --git a/Fltk/aboutWindow.cpp b/Fltk/aboutWindow.cpp index db95e0a991..7a568280c8 100644 --- a/Fltk/aboutWindow.cpp +++ b/Fltk/aboutWindow.cpp @@ -11,11 +11,27 @@ #include "shortcutWindow.h" #include "CommandLine.h" #include "StringUtils.h" -#include "Callbacks.h" +#include "OS.h" #include "Context.h" extern Context_T CTX; +static void help_license_cb(Fl_Widget *w, void *data) +{ + std::string prog = FixWindowsPath(CTX.web_browser); + char cmd[1024]; + ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/LICENSE.txt", cmd); + SystemCall(cmd); +} + +static void help_credits_cb(Fl_Widget *w, void *data) +{ + std::string prog = FixWindowsPath(CTX.web_browser); + char cmd[1024]; + ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/CREDITS.txt", cmd); + SystemCall(cmd); +} + aboutWindow::aboutWindow(int fontsize) : _fontsize(fontsize) { @@ -71,7 +87,7 @@ aboutWindow::aboutWindow(int fontsize) o->add(" "); o->add("@c@.Visit http://www.geuz.org/gmsh/ for more information"); o->add(" "); - o->callback(cancel_cb, (void *)win); + o->callback(hide_cb, (void *)win); } { diff --git a/Fltk/classificationEditor.cpp b/Fltk/classificationEditor.cpp index 92bfa09f48..1b84e89bbd 100644 --- a/Fltk/classificationEditor.cpp +++ b/Fltk/classificationEditor.cpp @@ -20,10 +20,7 @@ extern Context_T CTX; -void buildListOfEdgeAngle(e2t_cont adj,std::vector<edge_angle> &edges_detected, - std::vector<edge_angle> &edges_lonly); - -void NoElementsSelectedMode (classificationEditor *e) +static void NoElementsSelectedMode (classificationEditor *e) { e->_buttons[CLASSBUTTON_DEL]->deactivate(); e->_buttons[CLASSBUTTON_ADD]->deactivate(); @@ -36,7 +33,7 @@ void NoElementsSelectedMode (classificationEditor *e) e->_togbuttons[CLASSTOGBUTTON_HIDE]->activate(); } -void ElementsSelectedMode(classificationEditor *e) +static void ElementsSelectedMode(classificationEditor *e) { e->_buttons[CLASSBUTTON_DEL]->activate(); e->_buttons[CLASSBUTTON_ADD]->activate(); @@ -49,7 +46,179 @@ void ElementsSelectedMode(classificationEditor *e) e->_togbuttons[CLASSTOGBUTTON_HIDE]->deactivate(); } -int maxEdgeNum() +static void class_selectgface_cb(Fl_Widget *w, void *data) +{ + classificationEditor *e = (classificationEditor*)data; + std::vector<GVertex*> vertices; + std::vector<GEdge*> edges; + std::vector<GFace*> faces; + std::vector<GFace*> temp; + std::vector<GRegion*> regions; + std::vector<MElement*> elements; + + opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); + + while(1) { + CTX.mesh.changed = ENT_ALL; + Draw(); + + Msg::StatusBar(3, false, "Select Model Face\n" + "[Press 'e' to end selection or 'q' to abort]"); + + char ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions, elements); + if(ib == 'l') { + for(unsigned int i = 0; i < faces.size(); i++){ + HighlightEntity(faces[i]); + temp.push_back(faces[i]); + } + } + // ok store the list of gfaces ! + if(ib == 'e') { + ZeroHighlight(); + for(unsigned int i = 0; i < temp.size(); i++){ + e->_faces.insert (temp[i]); + } + break; + } + // do nothing + if(ib == 'q') { + ZeroHighlight(); + break; + } + } + CTX.mesh.changed = ENT_ALL; + Draw(); + Msg::StatusBar(3, false, ""); +} + +static void class_deleteedge_cb(Fl_Widget *w, void *data) +{ + classificationEditor *e = (classificationEditor*)data; + std::vector<GVertex*> vertices; + std::vector<GEdge*> edges; + std::vector<GFace*> faces; + std::vector<GRegion*> regions; + std::vector<MElement*> elements; + std::vector<MLine*> ele; + + CTX.pick_elements = 1; + + while(1) { + CTX.mesh.changed = ENT_ALL; + Draw(); + + Msg::StatusBar(3, false, "Select Elements\n" + "[Press 'e' to end selection or 'q' to abort]"); + + char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements); + if(ib == 'l') { + if(CTX.pick_elements){ + for(unsigned int i = 0; i < elements.size(); i++){ + if(elements[i]->getNumEdges() == 1 && elements[i]->getVisibility() != 2){ + elements[i]->setVisibility(2); ele.push_back((MLine*)elements[i]); + } + } + } + } + if(ib == 'r') { + for(unsigned int i = 0; i < elements.size(); i++) + elements[i]->setVisibility(1); + } + // ok, we compute edges ! + if(ib == 'e') { + ZeroHighlight(); + break; + } + // do nothing + if(ib == 'q') { + ZeroHighlight(); + ele.clear(); + break; + } + } + + std::sort (ele.begin(),ele.end()); + // look in all temporary edges if a deleted one is present and delete it ! + std::vector<MLine*> temp = e->temporary->lines; + e->temporary->lines.clear(); + + for(unsigned int i=0;i<temp.size();i++) + { + std::vector<MLine*>::iterator it = std::find (ele.begin(),ele.end(),temp[i]); + if (it != ele.end()) + { + delete temp[i]; + } + else e->temporary->lines.push_back(temp[i]); + } + + CTX.mesh.changed = ENT_ALL; + CTX.pick_elements = 0; + Draw(); + Msg::StatusBar(3, false, ""); +} + +static void class_save_cb(Fl_Widget *w, void *data) +{ + classificationEditor *e = (classificationEditor*)data; + + e->saved->lines.insert(e->saved->lines.end(), e->temporary->lines.begin(), + e->temporary->lines.end()); + e->temporary->lines.clear(); + e->_elements.clear(); + e->edges_detected.clear(); + + CTX.mesh.changed = ENT_ALL; + CTX.pick_elements = 0; + NoElementsSelectedMode (e); + Draw(); + Msg::StatusBar(3, false, ""); +} + +static void class_clear_cb(Fl_Widget *w, void *data) +{ + classificationEditor *e = (classificationEditor*)data; + + for(unsigned int i = 0; i < e->temporary->lines.size(); i++){ + delete e->temporary->lines[i]; + } + e->temporary->lines.clear(); + + CTX.mesh.changed = ENT_ALL; + CTX.pick_elements = 0; + NoElementsSelectedMode (e); + Draw(); + Msg::StatusBar(3, false, ""); +} + +static void class_ok_cb(Fl_Widget *w, void *data) +{ + classificationEditor *e = (classificationEditor*)data; + e->edge_detec->deactivate(); + e->edge_detec->hide(); + e->face_color->activate(); + e->face_color->show(); + class_save_cb(w,data); + opt_mesh_lines(0, GMSH_SET | GMSH_GUI, e->op[0]); + opt_mesh_surfaces_edges(0, GMSH_SET | GMSH_GUI, e->op[1]); + opt_mesh_surfaces_faces(0, GMSH_SET | GMSH_GUI, e->op[2]); + opt_mesh_line_width(0, GMSH_SET | GMSH_GUI, e->op[3]); + + Msg::StatusBar(3, false, ""); +} + +static void class_okcolor_cb(Fl_Widget *w, void *data) +{ + classificationEditor *e = (classificationEditor*)data; + e->edge_detec->deactivate(); + e->edge_detec->show(); + e->face_color->deactivate(); + e->face_color->hide(); + // class_save_cb(w,data); + Msg::StatusBar(3, false, ""); +} + +static int maxEdgeNum() { GModel::eiter it = GModel::current()->firstEdge(); GModel::eiter ite = GModel::current()->lastEdge(); @@ -62,7 +231,7 @@ int maxEdgeNum() return MAXX; } -int maxFaceNum() +static int maxFaceNum() { GModel::fiter it = GModel::current()->firstFace(); GModel::fiter ite = GModel::current()->lastFace(); @@ -84,9 +253,9 @@ struct compareMLinePtr } }; -void recurClassify(MTri3 *t, GFace *gf, - std::map<MLine*, GEdge*, compareMLinePtr> &lines, - std::map<MTriangle*, GFace*> &reverse) +static void recurClassify(MTri3 *t, GFace *gf, + std::map<MLine*, GEdge*, compareMLinePtr> &lines, + std::map<MTriangle*, GFace*> &reverse) { if (!t->isDeleted()){ gf->triangles.push_back(t->tri()); @@ -105,8 +274,8 @@ void recurClassify(MTri3 *t, GFace *gf, } } -GEdge *getNewModelEdge(GFace *gf1, GFace *gf2, - std::map<std::pair<int, int>, GEdge* > &newEdges) +static GEdge *getNewModelEdge(GFace *gf1, GFace *gf2, + std::map<std::pair<int, int>, GEdge* > &newEdges) { int t1 = gf1 ? gf1->tag() : -1; int t2 = gf2 ? gf2->tag() : -1; @@ -127,11 +296,11 @@ GEdge *getNewModelEdge(GFace *gf1, GFace *gf2, return it->second; } -void recurClassifyEdges(MTri3 *t , - std::map<MTriangle*, GFace*> &reverse, - std::map<MLine*, GEdge*, compareMLinePtr> &lines, - std::set<MLine*> &touched, - std::map<std::pair<int, int>, GEdge*> &newEdges) +static void recurClassifyEdges(MTri3 *t , + std::map<MTriangle*, GFace*> &reverse, + std::map<MLine*, GEdge*, compareMLinePtr> &lines, + std::set<MLine*> &touched, + std::map<std::pair<int, int>, GEdge*> &newEdges) { if (!t->isDeleted()){ t->setDeleted(true); @@ -157,7 +326,7 @@ void recurClassifyEdges(MTri3 *t , } } -void class_color_cb(Fl_Widget* w, void* data) +static void class_color_cb(Fl_Widget* w, void* data) { classificationEditor *e = (classificationEditor*)data; std::map<MLine*, GEdge*, compareMLinePtr> lines; @@ -224,7 +393,7 @@ void class_color_cb(Fl_Widget* w, void* data) Msg::StatusBar(3, false, ""); } -void updateedges_cb(Fl_Widget* w, void* data) +static void updateedges_cb(Fl_Widget* w, void* data) { classificationEditor *e = (classificationEditor*)data; @@ -254,6 +423,88 @@ void updateedges_cb(Fl_Widget* w, void* data) Draw(); } +static void class_hide_cb(Fl_Widget *w, void *data) +{ + CTX.hide_unselected = !CTX.hide_unselected; + CTX.mesh.changed = ENT_ALL; + Draw(); +} + +static void buildListOfEdgeAngle(e2t_cont adj, std::vector<edge_angle> &edges_detected, + std::vector<edge_angle> &edges_lonly) +{ + e2t_cont::iterator it = adj.begin(); + for( ; it != adj.end(); ++it){ + if(it->second.second) + edges_detected.push_back(edge_angle(it->first.getVertex(0), + it->first.getVertex(1), + it->second.first, it->second.second)); + else + edges_lonly.push_back(edge_angle(it->first.getVertex(0), + it->first.getVertex(1), + it->second.first, it->second.second)); + } + std::sort(edges_detected.begin(), edges_detected.end()); +} + +static void class_select_cb(Fl_Widget *w, void *data) +{ + classificationEditor *e = (classificationEditor*)data; + std::vector<GVertex*> vertices; + std::vector<GEdge*> edges; + std::vector<GFace*> faces; + std::vector<GRegion*> regions; + std::vector<MElement*> elements; + std::vector<MTriangle*> &ele(e->getElements()); + + CTX.pick_elements = 1; + + while(1) { + CTX.mesh.changed = ENT_ALL; + Draw(); + + Msg::StatusBar(3, false, "Select Elements\n" + "[Press 'e' to end selection or 'q' to abort]"); + + char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements); + if(ib == 'l') { + if(CTX.pick_elements){ + for(unsigned int i = 0; i < elements.size(); i++){ + if(elements[i]->getNumEdges() == 3 && elements[i]->getVisibility() != 2){ + elements[i]->setVisibility(2); ele.push_back((MTriangle*)elements[i]); + } + } + } + } + if(ib == 'r') { + for(unsigned int i = 0; i < elements.size(); i++) + elements[i]->setVisibility(1); + } + // ok, we compute edges ! + if(ib == 'e') { + ZeroHighlight(); + e2t_cont adj; + buildEdgeToTriangle (ele , adj ); + buildListOfEdgeAngle ( adj,e->edges_detected,e->edges_lonly); + ElementsSelectedMode (e); + break; + } + // do nothing + if(ib == 'q') { + ZeroHighlight(); + ele.clear(); + break; + } + } + + updateedges_cb(0, data); + + CTX.mesh.changed = ENT_ALL; + CTX.pick_elements = 0; + Draw(); + Msg::StatusBar(3, false, ""); +} + edge_angle::edge_angle(MVertex *_v1, MVertex *_v2, MElement *t1, MElement *t2) : v1(_v1), v2(_v2) { @@ -284,30 +535,13 @@ edge_angle::edge_angle(MVertex *_v1, MVertex *_v2, MElement *t1, MElement *t2) } norme(c1); norme(c2); - prodve(c1,c2,c3); - double cosa ; prosca(c1,c2,&cosa); - double sina = norme (c3); - angle = atan2(sina,cosa); + prodve(c1, c2, c3); + double cosa; prosca(c1, c2, &cosa); + double sina = norme(c3); + angle = atan2(sina, cosa); } } -void buildListOfEdgeAngle(e2t_cont adj, std::vector<edge_angle> &edges_detected, - std::vector<edge_angle> &edges_lonly) -{ - e2t_cont::iterator it = adj.begin(); - for( ; it != adj.end(); ++it){ - if(it->second.second) - edges_detected.push_back(edge_angle(it->first.getVertex(0), - it->first.getVertex(1), - it->second.first, it->second.second)); - else - edges_lonly.push_back(edge_angle(it->first.getVertex(0), - it->first.getVertex(1), - it->second.first, it->second.second)); - } - std::sort(edges_detected.begin(), edges_detected.end()); -} - classificationEditor::classificationEditor() { op[0] = opt_mesh_lines(0, GMSH_GET, 0.); @@ -413,243 +647,6 @@ classificationEditor::classificationEditor() _window->size_range(width, (int)(0.85 * height)); } -void class_hide_cb(Fl_Widget *w, void *data) -{ - CTX.hide_unselected = !CTX.hide_unselected; - CTX.mesh.changed = ENT_ALL; - Draw(); -} - -void class_select_cb(Fl_Widget *w, void *data) -{ - classificationEditor *e = (classificationEditor*)data; - std::vector<GVertex*> vertices; - std::vector<GEdge*> edges; - std::vector<GFace*> faces; - std::vector<GRegion*> regions; - std::vector<MElement*> elements; - std::vector<MTriangle*> &ele(e->getElements()); - - CTX.pick_elements = 1; - - while(1) { - CTX.mesh.changed = ENT_ALL; - Draw(); - - Msg::StatusBar(3, false, "Select Elements\n" - "[Press 'e' to end selection or 'q' to abort]"); - - char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements); - if(ib == 'l') { - if(CTX.pick_elements){ - for(unsigned int i = 0; i < elements.size(); i++){ - if(elements[i]->getNumEdges() == 3 && elements[i]->getVisibility() != 2){ - elements[i]->setVisibility(2); ele.push_back((MTriangle*)elements[i]); - } - } - } - } - if(ib == 'r') { - for(unsigned int i = 0; i < elements.size(); i++) - elements[i]->setVisibility(1); - } - // ok, we compute edges ! - if(ib == 'e') { - ZeroHighlight(); - e2t_cont adj; - buildEdgeToTriangle (ele , adj ); - buildListOfEdgeAngle ( adj,e->edges_detected,e->edges_lonly); - ElementsSelectedMode (e); - break; - } - // do nothing - if(ib == 'q') { - ZeroHighlight(); - ele.clear(); - break; - } - } - - updateedges_cb(0, data); - - CTX.mesh.changed = ENT_ALL; - CTX.pick_elements = 0; - Draw(); - Msg::StatusBar(3, false, ""); -} - -void class_selectgface_cb(Fl_Widget *w, void *data) -{ - classificationEditor *e = (classificationEditor*)data; - std::vector<GVertex*> vertices; - std::vector<GEdge*> edges; - std::vector<GFace*> faces; - std::vector<GFace*> temp; - std::vector<GRegion*> regions; - std::vector<MElement*> elements; - - opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); - - while(1) { - CTX.mesh.changed = ENT_ALL; - Draw(); - - Msg::StatusBar(3, false, "Select Model Face\n" - "[Press 'e' to end selection or 'q' to abort]"); - - char ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions, elements); - if(ib == 'l') { - for(unsigned int i = 0; i < faces.size(); i++){ - HighlightEntity(faces[i]); - temp.push_back(faces[i]); - } - } - // ok store the list of gfaces ! - if(ib == 'e') { - ZeroHighlight(); - for(unsigned int i = 0; i < temp.size(); i++){ - e->_faces.insert (temp[i]); - } - break; - } - // do nothing - if(ib == 'q') { - ZeroHighlight(); - break; - } - } - CTX.mesh.changed = ENT_ALL; - Draw(); - Msg::StatusBar(3, false, ""); -} - -void class_deleteedge_cb(Fl_Widget *w, void *data) -{ - classificationEditor *e = (classificationEditor*)data; - std::vector<GVertex*> vertices; - std::vector<GEdge*> edges; - std::vector<GFace*> faces; - std::vector<GRegion*> regions; - std::vector<MElement*> elements; - std::vector<MLine*> ele; - - CTX.pick_elements = 1; - - while(1) { - CTX.mesh.changed = ENT_ALL; - Draw(); - - Msg::StatusBar(3, false, "Select Elements\n" - "[Press 'e' to end selection or 'q' to abort]"); - - char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements); - if(ib == 'l') { - if(CTX.pick_elements){ - for(unsigned int i = 0; i < elements.size(); i++){ - if(elements[i]->getNumEdges() == 1 && elements[i]->getVisibility() != 2){ - elements[i]->setVisibility(2); ele.push_back((MLine*)elements[i]); - } - } - } - } - if(ib == 'r') { - for(unsigned int i = 0; i < elements.size(); i++) - elements[i]->setVisibility(1); - } - // ok, we compute edges ! - if(ib == 'e') { - ZeroHighlight(); - break; - } - // do nothing - if(ib == 'q') { - ZeroHighlight(); - ele.clear(); - break; - } - } - - std::sort (ele.begin(),ele.end()); - // look in all temporary edges if a deleted one is present and delete it ! - std::vector<MLine*> temp = e->temporary->lines; - e->temporary->lines.clear(); - - for(unsigned int i=0;i<temp.size();i++) - { - std::vector<MLine*>::iterator it = std::find (ele.begin(),ele.end(),temp[i]); - if (it != ele.end()) - { - delete temp[i]; - } - else e->temporary->lines.push_back(temp[i]); - } - - CTX.mesh.changed = ENT_ALL; - CTX.pick_elements = 0; - Draw(); - Msg::StatusBar(3, false, ""); -} - -void class_save_cb(Fl_Widget *w, void *data) -{ - classificationEditor *e = (classificationEditor*)data; - - e->saved->lines.insert(e->saved->lines.end(), e->temporary->lines.begin(), - e->temporary->lines.end()); - e->temporary->lines.clear(); - e->_elements.clear(); - e->edges_detected.clear(); - - CTX.mesh.changed = ENT_ALL; - CTX.pick_elements = 0; - NoElementsSelectedMode (e); - Draw(); - Msg::StatusBar(3, false, ""); -} - -void class_clear_cb(Fl_Widget *w, void *data) -{ - classificationEditor *e = (classificationEditor*)data; - - for(unsigned int i = 0; i < e->temporary->lines.size(); i++){ - delete e->temporary->lines[i]; - } - e->temporary->lines.clear(); - - CTX.mesh.changed = ENT_ALL; - CTX.pick_elements = 0; - NoElementsSelectedMode (e); - Draw(); - Msg::StatusBar(3, false, ""); -} - -void class_ok_cb(Fl_Widget *w, void *data) -{ - classificationEditor *e = (classificationEditor*)data; - e->edge_detec->deactivate(); - e->edge_detec->hide(); - e->face_color->activate(); - e->face_color->show(); - class_save_cb(w,data); - opt_mesh_lines(0, GMSH_SET | GMSH_GUI, e->op[0]); - opt_mesh_surfaces_edges(0, GMSH_SET | GMSH_GUI, e->op[1]); - opt_mesh_surfaces_faces(0, GMSH_SET | GMSH_GUI, e->op[2]); - opt_mesh_line_width(0, GMSH_SET | GMSH_GUI, e->op[3]); - - Msg::StatusBar(3, false, ""); -} - -void class_okcolor_cb(Fl_Widget *w, void *data) -{ - classificationEditor *e = (classificationEditor*)data; - e->edge_detec->deactivate(); - e->edge_detec->show(); - e->face_color->deactivate(); - e->face_color->hide(); - // class_save_cb(w,data); - Msg::StatusBar(3, false, ""); -} - void mesh_classify_cb(Fl_Widget* w, void* data) { // create the (static) editor diff --git a/Fltk/classificationEditor.h b/Fltk/classificationEditor.h index 86b3daeb33..29443dd961 100644 --- a/Fltk/classificationEditor.h +++ b/Fltk/classificationEditor.h @@ -57,14 +57,6 @@ class classificationEditor { Fl_Group *edge_detec, *face_color, *reverse_eng; }; -void class_select_cb(Fl_Widget *w, void *data); -void class_hide_cb(Fl_Widget *w, void *data); -void class_selectgface_cb(Fl_Widget *w, void *data); -void class_save_cb(Fl_Widget *w, void *data); -void class_clear_cb(Fl_Widget *w, void *data); -void class_deleteedge_cb(Fl_Widget *w, void *data); -void class_color_cb(Fl_Widget *w, void *data); -void class_ok_cb(Fl_Widget *w, void *data); -void class_okcolor_cb(Fl_Widget *w, void *data); +void mesh_classify_cb(Fl_Widget* w, void* data); #endif diff --git a/Fltk/clippingWindow.cpp b/Fltk/clippingWindow.cpp index 85f795f853..ecfa93dc2c 100644 --- a/Fltk/clippingWindow.cpp +++ b/Fltk/clippingWindow.cpp @@ -6,15 +6,144 @@ #include <FL/Fl_Tabs.H> #include <FL/Fl_Return_Button.H> #include "GUI.h" +#include "Draw.h" #include "clippingWindow.h" #include "shortcutWindow.h" +#include "GmshDefines.h" #include "PView.h" #include "PViewOptions.h" -#include "Callbacks.h" #include "Context.h" extern Context_T CTX; +void clip_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->clipping->show(); +} + +static void clip_num_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->clipping->resetBrowser(); +} + +static void clip_update_cb(Fl_Widget *w, void *data) +{ + if(GUI::instance()->clipping->group[0]->visible()){ // clipping planes + int idx = GUI::instance()->clipping->choice->value(); + CTX.geom.clip &= ~(1 << idx); + CTX.mesh.clip &= ~(1 << idx); + for(unsigned int i = 0; i < PView::list.size(); i++) + PView::list[i]->getOptions()->Clip &= ~(1 << idx); + for(int i = 0; i < GUI::instance()->clipping->browser->size(); i++){ + if(GUI::instance()->clipping->browser->selected(i + 1)){ + if(i == 0) + CTX.geom.clip |= (1 << idx); + else if(i == 1) + CTX.mesh.clip |= (1 << idx); + else if(i - 2 < PView::list.size()) + PView::list[i - 2]->getOptions()->Clip |= (1 << idx); + } + } + for(int i = 0; i < 4; i++) + CTX.clip_plane[idx][i] = GUI::instance()->clipping->value[i]->value(); + } + else{ // clipping box + CTX.geom.clip = 0; + CTX.mesh.clip = 0; + for(unsigned int i = 0; i < PView::list.size(); i++) + PView::list[i]->getOptions()->Clip = 0; + for(int i = 0; i < GUI::instance()->clipping->browser->size(); i++){ + if(GUI::instance()->clipping->browser->selected(i + 1)){ + for(int idx = 0; idx < 6; idx++){ + if(i == 0) + CTX.geom.clip |= (1 << idx); + else if(i == 1) + CTX.mesh.clip |= (1 << idx); + else if(i - 2 < PView::list.size()) + PView::list[i - 2]->getOptions()->Clip |= (1 << idx); + } + } + } + double c[3] = {GUI::instance()->clipping->value[4]->value(), + GUI::instance()->clipping->value[5]->value(), + GUI::instance()->clipping->value[6]->value()}; + double d[3] = {GUI::instance()->clipping->value[7]->value(), + GUI::instance()->clipping->value[8]->value(), + GUI::instance()->clipping->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.); + } + + if(CTX.clip_whole_elements || + CTX.clip_whole_elements != GUI::instance()->clipping->butt[0]->value()){ + for(int clip = 0; clip < 6; clip++){ + if(CTX.mesh.clip) + CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + for(unsigned int index = 0; index < PView::list.size(); index++) + if(PView::list[index]->getOptions()->Clip) + PView::list[index]->setChanged(true); + } + } + + CTX.clip_whole_elements = GUI::instance()->clipping->butt[0]->value(); + CTX.clip_only_draw_intersecting_volume = GUI::instance()->clipping->butt[1]->value(); + CTX.clip_only_volume = GUI::instance()->clipping->butt[2]->value(); + + 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; +} + +static void clip_invert_cb(Fl_Widget *w, void *data) +{ + for(int i = 0; i < 4; i++) + GUI::instance()->clipping->value[i]->value(-GUI::instance()->clipping->value[i]->value()); + clip_update_cb(NULL, NULL); +} + +static void clip_reset_cb(Fl_Widget *w, void *data) +{ + CTX.geom.clip = 0; + CTX.mesh.clip = 0; + for(unsigned int index = 0; index < PView::list.size(); index++) + PView::list[index]->getOptions()->Clip = 0; + + for(int i = 0; i < 6; i++){ + CTX.clip_plane[i][0] = 1.; + for(int j = 1; j < 4; j++) + CTX.clip_plane[i][j] = 0.; + } + + if(CTX.clip_whole_elements){ + CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + for(unsigned int index = 0; index < PView::list.size(); index++) + PView::list[index]->setChanged(true); + } + + GUI::instance()->clipping->resetBrowser(); + Draw(); +} + clippingWindow::clippingWindow(int fontsize) : _fontsize(fontsize) { @@ -119,7 +248,7 @@ clippingWindow::clippingWindow(int fontsize) { Fl_Button *o = new Fl_Button (width - BB - WB, height - BH - WB, BB, BH, "Cancel"); - o->callback(cancel_cb, (void *)win); + o->callback(hide_cb, (void *)win); } win->position(CTX.clip_position[0], CTX.clip_position[1]); diff --git a/Fltk/clippingWindow.h b/Fltk/clippingWindow.h index de6678b19d..1b1c6bba51 100644 --- a/Fltk/clippingWindow.h +++ b/Fltk/clippingWindow.h @@ -29,4 +29,6 @@ class clippingWindow{ void show(); }; +void clip_cb(Fl_Widget *w, void *data); + #endif diff --git a/Fltk/contextWindow.cpp b/Fltk/contextWindow.cpp index a84ff337fa..dece09ba31 100644 --- a/Fltk/contextWindow.cpp +++ b/Fltk/contextWindow.cpp @@ -6,13 +6,43 @@ #include <FL/Fl_Tabs.H> #include <FL/Fl_Return_Button.H> #include "GUI.h" +#include "Draw.h" #include "contextWindow.h" #include "shortcutWindow.h" -#include "Callbacks.h" +#include "GeoStringInterface.h" +#include "OpenFile.h" +#include "SelectBuffer.h" #include "Context.h" extern Context_T CTX; +static void con_geometry_define_parameter_cb(Fl_Widget *w, void *data) +{ + add_param(GUI::instance()->geoContext->input[0]->value(), + GUI::instance()->geoContext->input[1]->value(), CTX.filename); + GUI::instance()->resetVisibility(); +} + +static void con_geometry_define_point_cb(Fl_Widget *w, void *data) +{ + add_point(CTX.filename, + GUI::instance()->geoContext->input[2]->value(), + GUI::instance()->geoContext->input[3]->value(), + GUI::instance()->geoContext->input[4]->value(), + GUI::instance()->geoContext->input[5]->value()); + GUI::instance()->resetVisibility(); + ZeroHighlight(); + SetBoundingBox(); + Draw(); +} + +static void con_geometry_snap_cb(Fl_Widget *w, void *data) +{ + CTX.geom.snap[0] = GUI::instance()->geoContext->value[0]->value(); + CTX.geom.snap[1] = GUI::instance()->geoContext->value[1]->value(); + CTX.geom.snap[2] = GUI::instance()->geoContext->value[2]->value(); +} + geometryContextWindow::geometryContextWindow(int fontsize) : _fontsize(fontsize) { @@ -161,7 +191,7 @@ geometryContextWindow::geometryContextWindow(int fontsize) { Fl_Button *o = new Fl_Button (width - BB - WB, height - BH - WB, BB, BH, "Cancel"); - o->callback(cancel_cb, (void *)win); + o->callback(hide_cb, (void *)win); } win->position(CTX.ctx_position[0], CTX.ctx_position[1]); @@ -243,7 +273,7 @@ meshContextWindow::meshContextWindow(int fontsize) { Fl_Button *o = new Fl_Button (width - BB - WB, height - BH - WB, BB, BH, "Cancel"); - o->callback(cancel_cb, (void *)win); + o->callback(hide_cb, (void *)win); } win->position(CTX.ctx_position[0], CTX.ctx_position[1]); diff --git a/Fltk/extraDialogs.cpp b/Fltk/extraDialogs.cpp index ac9186aa28..475f761c34 100644 --- a/Fltk/extraDialogs.cpp +++ b/Fltk/extraDialogs.cpp @@ -141,7 +141,7 @@ int perspective_editor() // Model chooser -static void model_switch(Fl_Widget* w, void *data) +static void model_switch_cb(Fl_Widget* w, void *data) { Fl_Select_Browser *b = (Fl_Select_Browser *)w; if(b->value()) GModel::current(b->value() - 1); @@ -151,7 +151,7 @@ static void model_switch(Fl_Widget* w, void *data) Draw(); } -static void model_draw_all(Fl_Widget* w, void *data) +static void model_draw_all_cb(Fl_Widget* w, void *data) { Fl_Check_Button *b = (Fl_Check_Button*)w; opt_general_draw_all_models(0, GMSH_SET | GMSH_GUI, (int)b->value()); @@ -178,10 +178,10 @@ int model_chooser() Fl_Box *l = new Fl_Box(0, 0, WW, BH, "Choose current model:"); l->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); menu->browser = new Fl_Hold_Browser(0, BH, WW, 4 * BH); - menu->browser->callback(model_switch); + menu->browser->callback(model_switch_cb); menu->browser->when(FL_WHEN_RELEASE_ALWAYS); menu->butt = new Fl_Check_Button(0, 5 * BH, WW, BH, "Draw all models"); - menu->butt->callback(model_draw_all); + menu->butt->callback(model_draw_all_cb); menu->window->end(); } diff --git a/Fltk/fieldWindow.cpp b/Fltk/fieldWindow.cpp index e4095aad98..f9472332f5 100644 --- a/Fltk/fieldWindow.cpp +++ b/Fltk/fieldWindow.cpp @@ -9,18 +9,122 @@ #include <FL/Fl_Return_Button.H> #include <FL/Fl_Value_Input.H> #include "GUI.h" +#include "Draw.h" #include "fieldWindow.h" #include "shortcutWindow.h" +#include "fileDialogs.h" +#include "GmshDefines.h" #include "GModel.h" #include "PView.h" -#include "Callbacks.h" #include "GmshMessage.h" #include "Field.h" #include "GeoStringInterface.h" +#include "SelectBuffer.h" +#include "Options.h" #include "Context.h" extern Context_T CTX; +void field_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->fields->win->show(); + GUI::instance()->fields->editField(NULL); +} + +static void field_delete_cb(Fl_Widget *w, void *data) +{ + Field *f = (Field*)GUI::instance()->fields->editor_group->user_data(); + delete_field(f->id, CTX.filename); + GUI::instance()->fields->editField(NULL); +} + +static void field_new_cb(Fl_Widget *w, void *data) +{ + Fl_Menu_Button* mb = ((Fl_Menu_Button*)w); + FieldManager *fields = GModel::current()->getFields(); + int id = fields->new_id(); + add_field(id, mb->text(), CTX.filename); + GUI::instance()->fields->editField((*fields)[id]); +} + +static void field_apply_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->fields->saveFieldOptions(); +} + +static void field_revert_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->fields->loadFieldOptions(); +} + +static void field_browser_cb(Fl_Widget *w, void *data) +{ + int selected = GUI::instance()->fields->browser->value(); + if(!selected){ + GUI::instance()->fields->editField(NULL); + } + Field *f = (Field*)GUI::instance()->fields->browser->data(selected); + GUI::instance()->fields->editField(f); +} + +static void field_put_on_view_cb(Fl_Widget *w, void *data) +{ + Fl_Menu_Button* mb = ((Fl_Menu_Button*)w); + Field *field = (Field*)GUI::instance()->fields->editor_group->user_data(); + int iView; + if(sscanf(mb->text(), "View [%i]", &iView)){ + if(iView < (int)PView::list.size()){ + field->put_on_view(PView::list[iView]); + } + } + else{ + field->put_on_new_view(); + GUI::instance()->updateViews(); + } + Draw(); +} + +static void field_select_file_cb(Fl_Widget *w, void *data) +{ + Fl_Input *input = (Fl_Input*)data; + int ret = file_chooser(0, 0, "File selection", "", input->value()); + if(ret){ + input->value(file_chooser_get_name(0).c_str()); + input->set_changed(); + } +} + +static void field_select_node_cb(Fl_Widget *w, void *data) +{ + const char *mode = "select"; + const char *help = "vertices"; + CTX.pick_elements = 1; + Draw(); + 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; + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + while(1) { + Msg::StatusBar(3, false, "Select %s\n[Press %s'q' to abort]", + help, mode ? "" : "'u' to undo or "); + + char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements); + printf("char = %c\n", ib); + if(ib == 'q'){ + for(std::vector<GVertex*>::iterator it = vertices.begin(); it != vertices.end(); it++){ + printf("%p\n", *it); + } + break; + } + } + CTX.mesh.changed = ENT_ALL; + CTX.pick_elements = 0; + Msg::StatusBar(3, false, ""); + Draw(); +} + fieldWindow::fieldWindow(int fontsize) : _fontsize(fontsize) { int width0 = 34 * _fontsize + WB; @@ -39,19 +143,19 @@ fieldWindow::fieldWindow(int fontsize) : _fontsize(fontsize) std::map<std::string, FieldFactory*>::iterator it; for(it = fields.map_type_name.begin(); it != fields.map_type_name.end(); it++) new_btn->add(it->first.c_str()); - new_btn->callback(view_field_new_cb); + new_btn->callback(field_new_cb); y += BH; browser = new Fl_Hold_Browser(x, y + WB, w, h - 2 * WB); - browser->callback(view_field_browser_cb); + browser->callback(field_browser_cb); y += h; delete_btn = new Fl_Button(x, y, w, BH, "Delete"); - delete_btn->callback(view_field_delete_cb, this); + delete_btn->callback(field_delete_cb, this); y += BH; put_on_view_btn = new Fl_Menu_Button(x, y, w, BH, "Put on view"); - put_on_view_btn->callback(view_field_put_on_view_cb, this); + put_on_view_btn->callback(field_put_on_view_cb, this); x += w + WB; y = WB; @@ -78,11 +182,11 @@ fieldWindow::fieldWindow(int fontsize) : _fontsize(fontsize) Fl_Button *apply_btn = new Fl_Return_Button (x + w - BB, y + h - BH - WB, BB, BH, "Apply"); - apply_btn->callback(view_field_apply_cb, this); + apply_btn->callback(field_apply_cb, this); Fl_Button *revert_btn = new Fl_Button (x + w - 2 * BB - WB, y + h - BH - WB, BB, BH, "Revert"); - revert_btn->callback(view_field_revert_cb, this); + revert_btn->callback(field_revert_cb, this); background_btn = new Fl_Check_Button (x, y + h - BH - WB, (int)(1.5 * BB), BH, "Background mesh size"); @@ -286,7 +390,7 @@ void fieldWindow::editField(Field *f) { Fl_Button *b = new Fl_Button(x, yy, BH, BH, "S"); input = new Fl_Input(x + WB + BH, yy, IW - WB - BH, BH, it->first.c_str()); - b->callback(view_field_select_file_cb, input); + b->callback(field_select_file_cb, input); } break; case FIELD_OPTION_STRING: diff --git a/Fltk/fieldWindow.h b/Fltk/fieldWindow.h index 349007d8eb..97e69bc2b4 100644 --- a/Fltk/fieldWindow.h +++ b/Fltk/fieldWindow.h @@ -44,4 +44,6 @@ class fieldWindow{ void editField(Field *f); }; +void field_cb(Fl_Widget *w, void *data); + #endif diff --git a/Fltk/fileDialogs.cpp b/Fltk/fileDialogs.cpp index e23fdc805c..1ab0198643 100644 --- a/Fltk/fileDialogs.cpp +++ b/Fltk/fileDialogs.cpp @@ -952,79 +952,9 @@ int generic_mesh_dialog(const char *name, const char *title, int format, #if defined(HAVE_LIBCGNS) -// Forward declarations of some callbacks -void cgnsw_gc_location_cb(Fl_Widget *widget, void *data); -void cgnsw_write_dummy_bc_cb(Fl_Widget *widget, void *data); -void cgnsw_bc_location_cb(Fl_Widget *widget, void *data); -void cgnsw_write_normals_cb(Fl_Widget *widget, void *data); -void cgnsw_normal_source_cb(Fl_Widget *widget, void *data); +struct CGNSWriteDialog; -// Pointers to required widgets -struct CGNSWriteDialog -{ - Fl_Window *window; - Fl_Choice *choiceZoneDef; - Fl_Input *inputBaseName; - Fl_Input *inputZoneName; - Fl_Input *inputInterfaceName; - Fl_Input *inputPatchName; - Fl_Round_Button *roundButton0GCatVertex; - Fl_Round_Button *roundButton1GCatFace; - Fl_Check_Button *checkButtonWriteBC; - Fl_Round_Button *roundButton0BCatVertex; - Fl_Round_Button *roundButton1BCatFace; - Fl_Check_Button *checkButtonWriteNormals; - Fl_Round_Button *roundButton0NormalGeo; - Fl_Round_Button *roundButton1NormalElem; - Fl_Choice *choiceVecDim; - Fl_Check_Button *checkButtonUnknownUserDef; - const char *filename; - int status; - void write_all_options() - { - opt_mesh_zone_definition(0, GMSH_SET | GMSH_GUI, choiceZoneDef->value()); - CTX.mesh.cgns_options.baseName = inputBaseName->value(); - CTX.mesh.cgns_options.zoneName = inputZoneName->value(); - CTX.mesh.cgns_options.interfaceName = inputInterfaceName->value(); - CTX.mesh.cgns_options.patchName = inputPatchName->value(); - CTX.mesh.cgns_options.gridConnectivityLocation = - roundButton1GCatFace->value(); - CTX.mesh.cgns_options.writeBC = checkButtonWriteBC->value(); - CTX.mesh.cgns_options.bocoLocation = roundButton1BCatFace->value(); - CTX.mesh.cgns_options.normalSource = (checkButtonWriteNormals->value()) ? - roundButton1NormalElem->value() + 1 : 0; - CTX.mesh.cgns_options.vectorDim = choiceVecDim->value() + 2; - CTX.mesh.cgns_options.writeUserDef = checkButtonUnknownUserDef->value(); - } - void read_all_options() - { - choiceZoneDef->value(CTX.mesh.zone_definition); - inputBaseName->value(CTX.mesh.cgns_options.baseName.c_str()); - inputZoneName->value(CTX.mesh.cgns_options.zoneName.c_str()); - inputInterfaceName->value(CTX.mesh.cgns_options.interfaceName.c_str()); - inputPatchName->value(CTX.mesh.cgns_options.patchName.c_str()); - checkButtonWriteBC->value(CTX.mesh.cgns_options.writeBC); - checkButtonWriteNormals->value(CTX.mesh.cgns_options.normalSource); - choiceVecDim->value(CTX.mesh.cgns_options.vectorDim - 2); - checkButtonUnknownUserDef->value(CTX.mesh.cgns_options.writeUserDef); - - // Call all callbacks to ensure consistent options - cgnsw_gc_location_cb - ((CTX.mesh.cgns_options.gridConnectivityLocation) ? - roundButton1GCatFace : roundButton0GCatVertex, this); - // The order of the next 4 is important - cgnsw_normal_source_cb - ((CTX.mesh.cgns_options.normalSource == 2) ? - roundButton1NormalElem : roundButton0NormalGeo, this); - cgnsw_write_normals_cb(checkButtonWriteNormals, this); - cgnsw_bc_location_cb - ((CTX.mesh.cgns_options.bocoLocation) ? - roundButton1BCatFace : roundButton0BCatVertex, this); - cgnsw_write_dummy_bc_cb(checkButtonWriteBC, this); - } -}; - -void cgnsw_gc_location_cb(Fl_Widget *widget, void *data) +static void cgnsw_gc_location_cb(Fl_Widget *widget, void *data) { CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog*>(data); if(widget == dlg->roundButton0GCatVertex) { @@ -1037,12 +967,12 @@ void cgnsw_gc_location_cb(Fl_Widget *widget, void *data) } } -void cgnsw_write_dummy_bc_cb(Fl_Widget *widget, void *data) +static void cgnsw_write_dummy_bc_cb(Fl_Widget *widget, void *data) { CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog*>(data); if(dlg->checkButtonWriteBC->value()) { dlg->roundButton0BCatVertex->activate(); -// dlg->roundButton1BCatFace->activate(); //**Tmp + // dlg->roundButton1BCatFace->activate(); //**Tmp dlg->checkButtonWriteNormals->activate(); if(dlg->checkButtonWriteNormals->value()) { if(dlg->roundButton0BCatVertex->value()) @@ -1059,7 +989,7 @@ void cgnsw_write_dummy_bc_cb(Fl_Widget *widget, void *data) } } -void cgnsw_bc_location_cb(Fl_Widget *widget, void *data) +static void cgnsw_bc_location_cb(Fl_Widget *widget, void *data) { CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog*>(data); if(widget == dlg->roundButton0BCatVertex) { @@ -1077,7 +1007,7 @@ void cgnsw_bc_location_cb(Fl_Widget *widget, void *data) } } -void cgnsw_write_normals_cb(Fl_Widget *widget, void *data) +static void cgnsw_write_normals_cb(Fl_Widget *widget, void *data) { CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog*>(data); if(dlg->checkButtonWriteNormals->value()) { @@ -1091,7 +1021,7 @@ void cgnsw_write_normals_cb(Fl_Widget *widget, void *data) } } -void cgnsw_normal_source_cb(Fl_Widget *widget, void *data) +static void cgnsw_normal_source_cb(Fl_Widget *widget, void *data) { CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog*>(data); if(widget == dlg->roundButton0NormalGeo) { @@ -1104,14 +1034,14 @@ void cgnsw_normal_source_cb(Fl_Widget *widget, void *data) } } -void cgnsw_defaults_cb(Fl_Widget *widget, void *data) +static void cgnsw_defaults_cb(Fl_Widget *widget, void *data) { CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog*>(data); CTX.mesh.cgns_options.setDefaults(); dlg->read_all_options(); } -void cgnsw_write_cb(Fl_Widget *widget, void *data) +static void cgnsw_write_cb(Fl_Widget *widget, void *data) { CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog*>(data); @@ -1124,13 +1054,78 @@ void cgnsw_write_cb(Fl_Widget *widget, void *data) dlg->status = 1; } -void cgnsw_cancel_cb(Fl_Widget *widget, void *data) +static void cgnsw_cancel_cb(Fl_Widget *widget, void *data) { CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog*>(data); dlg->window->hide(); dlg->status = 0; } +// Pointers to required widgets +struct CGNSWriteDialog +{ + Fl_Window *window; + Fl_Choice *choiceZoneDef; + Fl_Input *inputBaseName; + Fl_Input *inputZoneName; + Fl_Input *inputInterfaceName; + Fl_Input *inputPatchName; + Fl_Round_Button *roundButton0GCatVertex; + Fl_Round_Button *roundButton1GCatFace; + Fl_Check_Button *checkButtonWriteBC; + Fl_Round_Button *roundButton0BCatVertex; + Fl_Round_Button *roundButton1BCatFace; + Fl_Check_Button *checkButtonWriteNormals; + Fl_Round_Button *roundButton0NormalGeo; + Fl_Round_Button *roundButton1NormalElem; + Fl_Choice *choiceVecDim; + Fl_Check_Button *checkButtonUnknownUserDef; + const char *filename; + int status; + void write_all_options() + { + opt_mesh_zone_definition(0, GMSH_SET | GMSH_GUI, choiceZoneDef->value()); + CTX.mesh.cgns_options.baseName = inputBaseName->value(); + CTX.mesh.cgns_options.zoneName = inputZoneName->value(); + CTX.mesh.cgns_options.interfaceName = inputInterfaceName->value(); + CTX.mesh.cgns_options.patchName = inputPatchName->value(); + CTX.mesh.cgns_options.gridConnectivityLocation = + roundButton1GCatFace->value(); + CTX.mesh.cgns_options.writeBC = checkButtonWriteBC->value(); + CTX.mesh.cgns_options.bocoLocation = roundButton1BCatFace->value(); + CTX.mesh.cgns_options.normalSource = (checkButtonWriteNormals->value()) ? + roundButton1NormalElem->value() + 1 : 0; + CTX.mesh.cgns_options.vectorDim = choiceVecDim->value() + 2; + CTX.mesh.cgns_options.writeUserDef = checkButtonUnknownUserDef->value(); + } + void read_all_options() + { + choiceZoneDef->value(CTX.mesh.zone_definition); + inputBaseName->value(CTX.mesh.cgns_options.baseName.c_str()); + inputZoneName->value(CTX.mesh.cgns_options.zoneName.c_str()); + inputInterfaceName->value(CTX.mesh.cgns_options.interfaceName.c_str()); + inputPatchName->value(CTX.mesh.cgns_options.patchName.c_str()); + checkButtonWriteBC->value(CTX.mesh.cgns_options.writeBC); + checkButtonWriteNormals->value(CTX.mesh.cgns_options.normalSource); + choiceVecDim->value(CTX.mesh.cgns_options.vectorDim - 2); + checkButtonUnknownUserDef->value(CTX.mesh.cgns_options.writeUserDef); + + // Call all callbacks to ensure consistent options + cgnsw_gc_location_cb + ((CTX.mesh.cgns_options.gridConnectivityLocation) ? + roundButton1GCatFace : roundButton0GCatVertex, this); + // The order of the next 4 is important + cgnsw_normal_source_cb + ((CTX.mesh.cgns_options.normalSource == 2) ? + roundButton1NormalElem : roundButton0NormalGeo, this); + cgnsw_write_normals_cb(checkButtonWriteNormals, this); + cgnsw_bc_location_cb + ((CTX.mesh.cgns_options.bocoLocation) ? + roundButton1BCatFace : roundButton0BCatVertex, this); + cgnsw_write_dummy_bc_cb(checkButtonWriteBC, this); + } +}; + int cgns_write_dialog(const char *filename) { static CGNSWriteDialog dlg; @@ -1197,7 +1192,7 @@ int cgns_write_dialog(const char *filename) dlg.inputPatchName->align(FL_ALIGN_RIGHT); y += BH + WB; -//--Left column + //--Left column int yl = y; { @@ -1245,7 +1240,7 @@ int cgns_write_dialog(const char *filename) yl += BH + WB; } -//--Right column + //--Right column int yr = y; diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp index ee56a7cfef..686669215b 100644 --- a/Fltk/graphicWindow.cpp +++ b/Fltk/graphicWindow.cpp @@ -4,11 +4,18 @@ // bugs and problems to <gmsh@geuz.org>. #include <FL/fl_draw.H> +#include "GUI.h" #include "graphicWindow.h" #include "shortcutWindow.h" +#include "menuWindow.h" +#include "messageWindow.h" +#include "manipWindow.h" +#include "extraDialogs.h" +#include "Draw.h" #include "PView.h" #include "PViewData.h" -#include "Callbacks.h" +#include "OS.h" +#include "Options.h" #include "Context.h" extern Context_T CTX; @@ -93,6 +100,172 @@ static void gmsh_models(Fl_Color c) #undef bl #undef el +void status_xyz1p_cb(Fl_Widget *w, void *data) +{ + const char *str = (const char*)data; + + drawContext *ctx = GUI::instance()->graph[0]->gl->getDrawContext(); + + 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] = ctx->r[1] = 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, "model")){ // toggle projection mode + model_chooser(); + } + else if(!strcmp(str, "?")){ // display options + Print_Options(0, GMSH_FULLRC, 0, 1, NULL); + GUI::instance()->messages->show(); + } + else if(!strcmp(str, "S")){ // mouse selection + if(CTX.mouse_selection){ + opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 0); + GUI::instance()->graph[0]->gl->cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE); + } + else + opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 1); + } + GUI::instance()->manip->update(); +} + +static int stop_anim, view_in_cycle = -1; + +void status_play_manual(int time, int step) +{ + // avoid firing this routine 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) + static bool busy = false; + if(busy) return; + busy = true; + if(time) { + for(unsigned int i = 0; i < PView::list.size(); 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) >= (int)PView::list.size()) + view_in_cycle = 0; + for(int i = 0; i < (int)PView::list.size(); i += step) + opt_view_visible(i, GMSH_SET | GMSH_GUI, (i == view_in_cycle)); + } + else { + if((view_in_cycle += step) < 0) + view_in_cycle = PView::list.size() - 1; + for(int i = PView::list.size() - 1; i >= 0; i += step) + opt_view_visible(i, GMSH_SET | GMSH_GUI, (i == view_in_cycle)); + } + } + Draw(); + busy = false; +} + +static void status_play_cb(Fl_Widget *w, void *data) +{ + static double anim_time; + GUI::instance()->graph[0]->setAnimButtons(0); + stop_anim = 0; + anim_time = GetTimeInSeconds(); + while(1) { + if(stop_anim) + break; + if(GetTimeInSeconds() - anim_time > CTX.post.anim_delay) { + anim_time = GetTimeInSeconds(); + status_play_manual(!CTX.post.anim_cycle, 1); + } + GUI::instance()->check(); + } +} + +static void status_pause_cb(Fl_Widget *w, void *data) +{ + stop_anim = 1; + GUI::instance()->graph[0]->setAnimButtons(1); +} + +static void status_rewind_cb(Fl_Widget *w, void *data) +{ + if(!CTX.post.anim_cycle) { + for(unsigned int i = 0; i < PView::list.size(); i++) + opt_view_timestep(i, GMSH_SET | GMSH_GUI, 0); + } + else { + view_in_cycle = 0; + for(unsigned int i = 0; i < PView::list.size(); i++) + opt_view_visible(i, GMSH_SET | GMSH_GUI, !i); + } + Draw(); +} + +static void status_stepbackward_cb(Fl_Widget *w, void *data) +{ + status_play_manual(!CTX.post.anim_cycle, -1); +} + +static void status_stepforward_cb(Fl_Widget *w, void *data) +{ + status_play_manual(!CTX.post.anim_cycle, 1); +} + graphicWindow::graphicWindow(int fontsize) { static bool first = true; diff --git a/Fltk/graphicWindow.h b/Fltk/graphicWindow.h index 0610cfa0f7..266412126e 100644 --- a/Fltk/graphicWindow.h +++ b/Fltk/graphicWindow.h @@ -23,4 +23,7 @@ class graphicWindow{ void checkAnimButtons(); }; +void status_xyz1p_cb(Fl_Widget *w, void *data); +void status_play_manual(int time, int step); + #endif diff --git a/Fltk/manipWindow.cpp b/Fltk/manipWindow.cpp index c83feddb27..2155d54da4 100644 --- a/Fltk/manipWindow.cpp +++ b/Fltk/manipWindow.cpp @@ -6,14 +6,36 @@ #include <FL/Fl_Box.H> #include <FL/Fl_Return_Button.H> #include "GUI.h" +#include "Draw.h" #include "manipWindow.h" #include "shortcutWindow.h" -#include "Callbacks.h" +#include "graphicWindow.h" #include "Options.h" #include "Context.h" extern Context_T CTX; +void manip_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->manip->show(); +} + +static void manip_update_cb(Fl_Widget *w, void *data) +{ + drawContext *ctx = GUI::instance()->graph[0]->gl->getDrawContext(); + ctx->r[0] = GUI::instance()->manip->value[0]->value(); + ctx->r[1] = GUI::instance()->manip->value[1]->value(); + ctx->r[2] = GUI::instance()->manip->value[2]->value(); + ctx->t[0] = GUI::instance()->manip->value[3]->value(); + ctx->t[1] = GUI::instance()->manip->value[4]->value(); + ctx->t[2] = GUI::instance()->manip->value[5]->value(); + ctx->s[0] = GUI::instance()->manip->value[6]->value(); + ctx->s[1] = GUI::instance()->manip->value[7]->value(); + ctx->s[2] = GUI::instance()->manip->value[8]->value(); + ctx->setQuaternionFromEulerAngles(); + Draw(); +} + manipWindow::manipWindow(int fontsize) : _fontsize(fontsize) { @@ -69,7 +91,7 @@ manipWindow::manipWindow(int fontsize) { Fl_Button *o = new Fl_Button (width - BB - WB, height - BH - WB, BB, BH, "Cancel"); - o->callback(cancel_cb, (void *)win); + o->callback(hide_cb, (void *)win); } win->position(CTX.manip_position[0], CTX.manip_position[1]); diff --git a/Fltk/manipWindow.h b/Fltk/manipWindow.h index 043923bae7..0ddfb7d59c 100644 --- a/Fltk/manipWindow.h +++ b/Fltk/manipWindow.h @@ -21,4 +21,6 @@ class manipWindow{ void show(); }; +void manip_cb(Fl_Widget *w, void *data); + #endif diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp index 2e9bf4f05a..13b59f15cd 100644 --- a/Fltk/menuWindow.cpp +++ b/Fltk/menuWindow.cpp @@ -4,21 +4,2131 @@ // bugs and problems to <gmsh@geuz.org>. #include <string.h> +#include <stdio.h> +#include <time.h> #include <FL/Fl_Box.H> +#include <FL/fl_ask.H> #include "GUI.h" +#include "Draw.h" #include "menuWindow.h" #include "shortcutWindow.h" -#include "Callbacks.h" +#include "graphicWindow.h" +#include "optionWindow.h" +#include "statisticsWindow.h" +#include "messageWindow.h" +#include "contextWindow.h" +#include "visibilityWindow.h" +#include "clippingWindow.h" +#include "manipWindow.h" +#include "fieldWindow.h" +#include "pluginWindow.h" +#include "solverWindow.h" +#include "aboutWindow.h" +#include "fileDialogs.h" +#include "partitionDialog.h" +#include "projectionEditor.h" +#include "classificationEditor.h" #include "Options.h" #include "Solvers.h" #include "GmshMessage.h" +#include "CommandLine.h" +#include "Generator.h" +#include "HighOrder.h" +#include "GModel.h" #include "PView.h" #include "PViewData.h" #include "PViewOptions.h" +#include "Field.h" +#include "OS.h" +#include "StringUtils.h" +#include "SelectBuffer.h" +#include "OpenFile.h" +#include "CreateFile.h" +#include "findLinks.h" +#include "GeoStringInterface.h" +#include "Options.h" #include "Context.h" extern Context_T CTX; +static void file_new_cb(Fl_Widget *w, void *data) +{ + test: + if(file_chooser(0, 1, "New", "*")) { + std::string name = file_chooser_get_name(1); + if(!StatFile(name.c_str())){ + if(fl_choice("File '%s' already exists.\n\nDo you want to erase it?", + "Cancel", "Erase", NULL, name.c_str())) + UnlinkFile(name.c_str()); + else + goto test; + } + FILE *fp = fopen(name.c_str(), "w"); + if(!fp){ + Msg::Error("Unable to open file '%s'", name.c_str()); + return; + } + time_t now; + time(&now); + fprintf(fp, "// Gmsh project created on %s", ctime(&now)); + fclose(fp); + OpenProject(name.c_str()); + Draw(); + } +} + +#if defined(HAVE_NATIVE_FILE_CHOOSER) +# define TT "\t" +# define NN "\n" +#else +# define TT " (" +# define NN ")\t" +#endif + +static const char *input_formats = + "All files" TT "*" NN + "Gmsh geometry" TT "*.geo" NN + "Gmsh mesh" TT "*.msh" NN + "Gmsh post-processing view" TT "*.pos" NN +#if defined(HAVE_OCC) + "STEP model" TT "*.{stp,step}" NN + "IGES model" TT "*.{igs,iges}" NN + "BRep model" TT "*.brep" NN +#endif + "I-deas universal mesh" TT "*.unv" NN + "Diffpack 3D mesh" TT "*.diff" NN + "VTK mesh" TT "*.vtk" NN +#if defined(HAVE_MED) + "MED file" TT "*.{med,mmed,rmed}" NN +#endif + "Medit mesh" TT "*.mesh" NN + "Nastran bulk data file" TT "*.{bdf,nas}" NN + "Plot3D structured mesh" TT "*.p3d" NN + "STL surface mesh" TT "*.stl" NN + "VRML surface mesh" TT "*.{wrl,vrml}" NN +#if defined(HAVE_LIBJPEG) + "JPEG" TT "*.{jpg,jpeg}" NN +#endif +#if defined(HAVE_LIBPNG) + "PNG" TT "*.png" NN +#endif + "BMP" TT "*.bmp" NN + "PPM" TT "*.ppm" NN + "PGM" TT "*.pgm" NN + "PBM" TT "*.pbm" NN + "PNM" TT "*.pnm" NN; + +#undef TT +#undef NN + +static void file_open_cb(Fl_Widget *w, void *data) +{ + int n = PView::list.size(); + if(file_chooser(0, 0, "Open", input_formats)) { + OpenProject(file_chooser_get_name(1).c_str()); + Draw(); + } + if(n != (int)PView::list.size()) + GUI::instance()->menu->setContext(menu_post, 0); +} + +static void file_merge_cb(Fl_Widget *w, void *data) +{ + int n = PView::list.size(); + int f = file_chooser(1, 0, "Merge", input_formats); + if(f) { + for(int i = 1; i <= f; i++) + MergeFile(file_chooser_get_name(i).c_str()); + Draw(); + } + if(n != (int)PView::list.size()) + GUI::instance()->menu->setContext(menu_post, 0); +} + +static int _save_msh(const char *name){ return msh_dialog(name); } +static int _save_pos(const char *name){ return pos_dialog(name); } +static int _save_options(const char *name){ return options_dialog(name); } +static int _save_geo(const char *name){ return geo_dialog(name); } +static int _save_cgns(const char *name){ return cgns_write_dialog(name); } +static int _save_unv(const char *name){ return unv_dialog(name); } +static int _save_vtk(const char *name){ return generic_mesh_dialog + (name, "VTK Options", FORMAT_VTK, true); } +static int _save_diff(const char *name){ return generic_mesh_dialog + (name, "Diffpack Options", FORMAT_DIFF, true); } +static int _save_med(const char *name){ return generic_mesh_dialog + (name, "MED Options", FORMAT_MED, false); } +static int _save_mesh(const char *name){ return generic_mesh_dialog + (name, "MESH Options", FORMAT_MESH, false); } +static int _save_bdf(const char *name){ return bdf_dialog(name); } +static int _save_p3d(const char *name){ return generic_mesh_dialog + (name, "P3D Options", FORMAT_P3D, false); } +static int _save_stl(const char *name){ return generic_mesh_dialog + (name, "STL Options", FORMAT_STL, true); } +static int _save_vrml(const char *name){ return generic_mesh_dialog + (name, "VRML Options", FORMAT_VRML, false); } +static int _save_eps(const char *name){ return gl2ps_dialog + (name, "EPS Options", FORMAT_EPS); } +static int _save_gif(const char *name){ return gif_dialog(name); } +static int _save_jpeg(const char *name){ return jpeg_dialog(name); } +static int _save_tex(const char *name){ return latex_dialog(name); } +static int _save_pdf(const char *name){ return gl2ps_dialog + (name, "PDF Options", FORMAT_PDF); } +static int _save_png(const char *name){ return generic_bitmap_dialog + (name, "PNG Options", FORMAT_PNG); } +static int _save_ps(const char *name){ return gl2ps_dialog + (name, "PS Options", FORMAT_PS); } +static int _save_ppm(const char *name){ return generic_bitmap_dialog + (name, "PPM Options", FORMAT_PPM); } +static int _save_svg(const char *name){ return gl2ps_dialog + (name, "SVG Options", FORMAT_SVG); } +static int _save_yuv(const char *name){ return generic_bitmap_dialog + (name, "YUV Options", FORMAT_YUV); } + +static int _save_auto(const 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_CGNS : return _save_cgns(name); + case FORMAT_UNV : return _save_unv(name); + case FORMAT_VTK : return _save_vtk(name); + case FORMAT_MED : return _save_med(name); + case FORMAT_MESH : return _save_mesh(name); + case FORMAT_BDF : return _save_bdf(name); + case FORMAT_DIFF : return _save_diff(name); + case FORMAT_P3D : return _save_p3d(name); + case FORMAT_STL : return _save_stl(name); + case FORMAT_VRML : return _save_vrml(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{ + const char *pat; + int (*func) (const char *name); +} patXfunc; + +static void file_save_as_cb(Fl_Widget *w, void *data) +{ +#if defined(HAVE_NATIVE_FILE_CHOOSER) +# define TT "\t" +# define NN "\n" +#else +# define TT " (" +# define NN ")\t" +#endif + static patXfunc formats[] = { + {"Guess from extension" TT "*.*", _save_auto}, + {"Gmsh mesh" TT "*.msh", _save_msh}, + {"Gmsh mesh statistics" TT "*.pos", _save_pos}, + {"Gmsh options" TT "*.opt", _save_options}, + {"Gmsh unrolled geometry" TT "*.geo", _save_geo}, +#if defined(HAVE_LIBCGNS) + {"CGNS" TT "*.cgns", _save_cgns}, +#endif + {"I-deas universal mesh" TT "*.unv", _save_unv}, + {"Diffpack 3D mesh" TT "*.diff", _save_diff}, + {"VTK mesh" TT "*.vtk", _save_vtk}, +#if defined(HAVE_MED) + {"MED file" TT "*.med", _save_med}, +#endif + {"Medit mesh" TT "*.mesh", _save_mesh}, + {"Nastran bulk data file" TT "*.bdf", _save_bdf}, + {"Plot3D structured mesh" TT "*.p3d", _save_p3d}, + {"STL surface mesh" TT "*.stl", _save_stl}, + {"VRML surface mesh" TT "*.wrl", _save_vrml}, + {"Encapsulated PostScript" TT "*.eps", _save_eps}, + {"GIF" TT "*.gif", _save_gif}, +#if defined(HAVE_LIBJPEG) + {"JPEG" TT "*.jpg", _save_jpeg}, +#endif + {"LaTeX" TT "*.tex", _save_tex}, + {"PDF" TT "*.pdf", _save_pdf}, +#if defined(HAVE_LIBPNG) + {"PNG" TT "*.png", _save_png}, +#endif + {"PostScript" TT "*.ps", _save_ps}, + {"PPM" TT "*.ppm", _save_ppm}, + {"SVG" TT "*.svg", _save_svg}, + {"YUV" TT "*.yuv", _save_yuv}, + }; + int nbformats = sizeof(formats) / sizeof(formats[0]); + static char *pat = 0; + if(!pat) { + pat = new char[nbformats * 256]; + strcpy(pat, formats[0].pat); + for(int i = 1; i < nbformats; i++) { + strcat(pat, NN); + strcat(pat, formats[i].pat); + } + } +#undef TT +#undef NN + + test: + if(file_chooser(0, 1, "Save As", pat)) { + std::string name = file_chooser_get_name(1); + if(CTX.confirm_overwrite) { + if(!StatFile(name.c_str())) + if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", + "Cancel", "Replace", NULL, name.c_str())) + goto test; + } + int i = file_chooser_get_filter(); + if(i >= 0 && i < nbformats){ + if(!formats[i].func(name.c_str())) goto test; + } + else{ // handle any additional automatic fltk filter + if(!_save_auto(name.c_str())) goto test; + } + } +} + +static void file_rename_cb(Fl_Widget *w, void *data) +{ + test: + if(file_chooser(0, 1, "Rename", "*", CTX.filename)) { + std::string name = file_chooser_get_name(1); + if(CTX.confirm_overwrite) { + if(!StatFile(name.c_str())) + if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", + "Cancel", "Replace", NULL, name.c_str())) + goto test; + } + rename(CTX.filename, name.c_str()); + OpenProject(name.c_str()); + Draw(); + } +} + +void file_quit_cb(Fl_Widget *w, void *data) +{ + Msg::Exit(0); +} + +#if defined(__APPLE__) +# define CC(str) "Cmd+" str " " +#else +# define CC(str) "Ctrl+" str +#endif + +static void help_short_cb(Fl_Widget *w, void *data) +{ + 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+u Show post-processing view plugins"); + 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("u") " Show plugin window"); + 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+e Hide/Show element outlines for visible post-pro views"); + 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+r Loop through range modes for visible post-pro views"); + Msg::Direct(" Alt+s Hide/show geometry surfaces"); + Msg::Direct(" Alt+t Loop through interval modes for visible post-pro 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(" "); + GUI::instance()->messages->show(); +} + +static void help_mouse_cb(Fl_Widget *w, void *data) +{ + Msg::Direct(" "); + Msg::Direct("Mouse actions:"); + Msg::Direct(" "); + Msg::Direct(" Move - Highlight the entity under the mouse pointer"); + Msg::Direct(" and display its properties in the status bar"); + Msg::Direct(" - Resize a lasso zoom or a lasso (un)selection"); + Msg::Direct(" Left button - Rotate"); + Msg::Direct(" - Select an entity"); + Msg::Direct(" - Accept a lasso zoom or a lasso selection"); + Msg::Direct(" Ctrl+Left button Start a lasso zoom or a lasso (un)selection"); + Msg::Direct(" Middle button - Zoom"); + Msg::Direct(" - Unselect an entity"); + Msg::Direct(" - Accept a lasso zoom or a lasso unselection"); + Msg::Direct(" Ctrl+Middle button Orthogonalize display"); + Msg::Direct(" Right button - Pan"); + Msg::Direct(" - Cancel a lasso zoom or a lasso (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(" "); + GUI::instance()->messages->show(); +} + +static void help_command_line_cb(Fl_Widget *w, void *data) +{ + Msg::Direct(" "); + Print_Usage("gmsh"); + GUI::instance()->messages->show(); +} + +static void help_online_cb(Fl_Widget *w, void *data) +{ + std::string prog = FixWindowsPath(CTX.web_browser); + char cmd[1024]; + ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/texinfo/", cmd); + SystemCall(cmd); +} + +static void help_about_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->about->win->show(); +} + +void mod_geometry_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(menu_geometry, 0); +} + +void mod_mesh_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(menu_mesh, 0); +} + +void mod_solver_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(menu_solver, 0); +} + +void mod_post_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(menu_post, 0); +} + +void mod_back_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(NULL, -1); +} + +void mod_forward_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(NULL, 1); +} + +static void geometry_elementary_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(menu_geometry_elementary, 0); +} + +static void geometry_physical_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(menu_geometry_physical, 0); +} + +static void geometry_edit_cb(Fl_Widget *w, void *data) +{ + std::string prog = FixWindowsPath(CTX.editor); + std::string file = FixWindowsPath(CTX.filename); + char cmd[1024]; + ReplaceMultiFormat(prog.c_str(), file.c_str(), cmd); + SystemCall(cmd); +} + +void geometry_reload_cb(Fl_Widget *w, void *data) +{ + OpenProject(CTX.filename); + Draw(); +} + +static void geometry_elementary_add_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(menu_geometry_elementary_add, 0); +} + +static void add_new_point() +{ + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + Draw(); + + GUI::instance()->geoContext->show(1); + + while(1) { + GUI::instance()->graph[0]->gl->addPointMode = true; + Msg::StatusBar(3, false, "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, + GUI::instance()->geoContext->input[2]->value(), + GUI::instance()->geoContext->input[3]->value(), + GUI::instance()->geoContext->input[4]->value(), + GUI::instance()->geoContext->input[5]->value()); + GUI::instance()->resetVisibility(); + Draw(); + } + if(ib == 'q'){ + GUI::instance()->graph[0]->gl->addPointMode = false; + break; + } + } + + Msg::StatusBar(3, false, ""); +} + +static void add_new_multiline(std::string type) +{ + std::vector<GVertex*> vertices; + std::vector<GEdge*> edges; + std::vector<GFace*> faces; + std::vector<GRegion*> regions; + std::vector<MElement*> elements; + std::vector<int> p; + + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + Draw(); + + while(1) { + if(p.empty()) + Msg::StatusBar(3, false, "Select control points\n" + "[Press 'e' to end selection or 'q' to abort]"); + else + Msg::StatusBar(3, false, "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.push_back(vertices[i]->tag()); + } + Draw(); + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during multi-line creation"); + } + if(ib == 'e') { + if(p.size() >= 2) + add_multline(type, p, CTX.filename); + GUI::instance()->resetVisibility(); + ZeroHighlight(); + Draw(); + p.clear(); + } + if(ib == 'u') { + if(p.size()){ + ZeroHighlightEntityNum(p.back(), 0, 0, 0); + Draw(); + p.pop_back(); + } + } + if(ib == 'q') { + ZeroHighlight(); + Draw(); + break; + } + } + + Msg::StatusBar(3, false, ""); +} + +static void add_new_line() +{ + std::vector<GVertex*> vertices; + std::vector<GEdge*> edges; + std::vector<GFace*> faces; + std::vector<GRegion*> regions; + std::vector<MElement*> elements; + std::vector<int> p; + + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + Draw(); + + while(1) { + if(p.empty()) + Msg::StatusBar(3, false, "Select start point\n" + "[Press 'q' to abort]"); + if(p.size() == 1) + Msg::StatusBar(3, false, "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.push_back(vertices[0]->tag()); + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during line creation"); + } + if(ib == 'u') { + if(p.size()){ + ZeroHighlightEntityNum(p.back(), 0, 0, 0); + Draw(); + p.pop_back(); + } + } + if(ib == 'q') { + ZeroHighlight(); + Draw(); + break; + } + if(p.size() == 2) { + add_multline("Line", p, CTX.filename); + GUI::instance()->resetVisibility(); + ZeroHighlight(); + Draw(); + p.clear(); + } + } + + Msg::StatusBar(3, false, ""); +} + +static void add_new_circle() +{ + std::vector<GVertex*> vertices; + std::vector<GEdge*> edges; + std::vector<GFace*> faces; + std::vector<GRegion*> regions; + std::vector<MElement*> elements; + std::vector<int> p; + + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + Draw(); + + while(1) { + if(p.empty()) + Msg::StatusBar(3, false, "Select start point\n" + "[Press 'q' to abort]"); + if(p.size() == 1) + Msg::StatusBar(3, false, "Select center point\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + if(p.size() == 2) + Msg::StatusBar(3, false, "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.push_back(vertices[0]->tag()); + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during circle creation"); + } + if(ib == 'u') { + if(p.size()){ + ZeroHighlightEntityNum(p.back(), 0, 0, 0); + Draw(); + p.pop_back(); + } + } + if(ib == 'q') { + ZeroHighlight(); + Draw(); + break; + } + if(p.size() == 3) { + add_circ(p[0], p[1], p[2], CTX.filename); // begin, center, end + GUI::instance()->resetVisibility(); + ZeroHighlight(); + Draw(); + p.clear(); + } + } + + Msg::StatusBar(3, false, ""); +} + +static void add_new_ellipse() +{ + std::vector<GVertex*> vertices; + std::vector<GEdge*> edges; + std::vector<GFace*> faces; + std::vector<GRegion*> regions; + std::vector<MElement*> elements; + std::vector<int> p; + + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + Draw(); + + while(1) { + if(p.empty()) + Msg::StatusBar(3, false, "Select start point\n" + "[Press 'q' to abort]"); + if(p.size() == 1) + Msg::StatusBar(3, false, "Select center point\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + if(p.size() == 2) + Msg::StatusBar(3, false, "Select major axis point\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + if(p.size() == 3) + Msg::StatusBar(3, false, "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.push_back(vertices[0]->tag()); + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during ellipse creation"); + } + if(ib == 'u') { + if(p.size()){ + ZeroHighlightEntityNum(p.back(), 0, 0, 0); + Draw(); + p.pop_back(); + } + } + if(ib == 'q') { + ZeroHighlight(); + Draw(); + break; + } + if(p.size() == 4) { + add_ell(p[0], p[1], p[2], p[3], CTX.filename); + GUI::instance()->resetVisibility(); + ZeroHighlight(); + Draw(); + p.clear(); + } + } + + Msg::StatusBar(3, false, ""); +} + +static int select_contour(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; +} + +static void add_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::StatusBar(3, false, "Select surface boundary\n" + "[Press 'q' to abort]"); + else + Msg::StatusBar(3, false, "Select surface boundary\n" + "[Press 'u' to undo last selection or 'q' to abort]"); + } + else{ + if(!List_Nbr(List1)) + Msg::StatusBar(3, false, "Select volume boundary\n" + "[Press 'q' to abort]"); + else + Msg::StatusBar(3, false, "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(select_contour(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::StatusBar + (3, false, "Select hole boundaries (if none, press 'e')\n" + "[Press 'e' to end selection or 'q' to abort]"); + else + Msg::StatusBar + (3, false, "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(select_contour(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("Plane Surface", List2, CTX.filename); break; + case 1: add_surf("Ruled Surface", List2, CTX.filename); break; + case 2: add_vol(List2, CTX.filename); break; + } + GUI::instance()->resetVisibility(); + ZeroHighlight(); + Draw(); + break; + } + } // if select_contour + } + } + } + + stopall: + List_Delete(List1); + List_Delete(List2); + + Msg::StatusBar(3, false, ""); +} + +static void geometry_elementary_add_new_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_add_new, 0); + return; + } + + std::string str((const char*)data); + if(str == "Parameter") + GUI::instance()->geoContext->show(0); + else if(str == "Point") + add_new_point(); + else if(str == "Line") + add_new_line(); + else if(str == "Spline") + add_new_multiline(str); + else if(str == "BSpline") + add_new_multiline(str); + else if(str == "Circle") + add_new_circle(); + else if(str == "Ellipse") + add_new_ellipse(); + else if(str == "Plane Surface") + add_new_surface_volume(0); + else if(str == "Ruled Surface") + add_new_surface_volume(1); + else if(str == "Volume") + add_new_surface_volume(2); + else + Msg::Error("Unknown entity to create: %s", str.c_str()); +} + +static void split_selection() +{ + opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); + Draw(); + Msg::StatusBar(3, false, "Select a line to split\n" + "[Press 'q' to abort]"); + std::vector<GVertex*> vertices; + std::vector<GEdge*> edges; + std::vector<GFace*> faces; + std::vector<GRegion*> regions; + std::vector<MElement*> elements; + GEdge* edge_to_split = NULL; + while(1){ + char ib = SelectEntity(2, vertices, edges, faces, regions, elements); + if(ib == 'q') + break; + if(!edges.empty()){ + edge_to_split = edges[0]; + HighlightEntity(edges[0]); + break; + } + } + Msg::StatusBar(3, false, ""); + if(edges.empty()) + return; + List_T *List1 = List_Create(5, 5, sizeof(int)); + Msg::StatusBar(3, false, "Select break points\n" + "[Press 'e' to end selection or 'q' to abort]"); + opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); + Draw(); + while(1){ + char ib = SelectEntity(1, vertices, edges, faces, regions, elements); + if(ib == 'q') + break; + if(ib == 'e'){ + split_edge(edge_to_split->tag(), List1, CTX.filename); + break; + } + if(!vertices.empty()){ + for(unsigned int i = 0; i < vertices.size(); i++){ + int tag = vertices[i]->tag(); + int index = List_ISearchSeq(List1, &tag, fcmp_int); + if(index < 0) List_Add(List1, &tag); + HighlightEntity(vertices[i]); + } + } + } + Msg::StatusBar(3, false, ""); + GUI::instance()->resetVisibility(); + ZeroHighlight(); + Draw(); +} + +static void action_point_line_surface_volume(int action, int mode, const char *what) +{ + std::vector<GVertex*> vertices; + std::vector<GEdge*> edges; + std::vector<GFace*> faces; + std::vector<GRegion*> regions; + std::vector<MElement*> elements; + int type; + const 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::Error("Unknown entity to select"); + return; + } + + if(action == 8){ + GUI::instance()->meshContext->show(0); + } + + Draw(); + + List_T *List1 = List_Create(5, 5, sizeof(int)); + while(1) { + if(!List_Nbr(List1)) + Msg::StatusBar(3, false, "Select %s\n" + "[Press 'e' to end selection or 'q' to abort]", str); + else + Msg::StatusBar(3, false, "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 == 'i') { + Msg::Error("Inverting selection!"); + } + if(ib == 'e') { + if(List_Nbr(List1)){ + switch (action) { + case 0: + translate(mode, List1, CTX.filename, what, + GUI::instance()->geoContext->input[6]->value(), + GUI::instance()->geoContext->input[7]->value(), + GUI::instance()->geoContext->input[8]->value()); + break; + case 1: + rotate(mode, List1, CTX.filename, what, + GUI::instance()->geoContext->input[12]->value(), + GUI::instance()->geoContext->input[13]->value(), + GUI::instance()->geoContext->input[14]->value(), + GUI::instance()->geoContext->input[9]->value(), + GUI::instance()->geoContext->input[10]->value(), + GUI::instance()->geoContext->input[11]->value(), + GUI::instance()->geoContext->input[15]->value()); + break; + case 2: + dilate(mode, List1, CTX.filename, what, + GUI::instance()->geoContext->input[16]->value(), + GUI::instance()->geoContext->input[17]->value(), + GUI::instance()->geoContext->input[18]->value(), + GUI::instance()->geoContext->input[19]->value()); + break; + case 3: + symmetry(mode, List1, CTX.filename, what, + GUI::instance()->geoContext->input[20]->value(), + GUI::instance()->geoContext->input[21]->value(), + GUI::instance()->geoContext->input[22]->value(), + GUI::instance()->geoContext->input[23]->value()); + break; + case 4: + extrude(List1, CTX.filename, what, + GUI::instance()->geoContext->input[6]->value(), + GUI::instance()->geoContext->input[7]->value(), + GUI::instance()->geoContext->input[8]->value()); + break; + case 5: + protude(List1, CTX.filename, what, + GUI::instance()->geoContext->input[12]->value(), + GUI::instance()->geoContext->input[13]->value(), + GUI::instance()->geoContext->input[14]->value(), + GUI::instance()->geoContext->input[9]->value(), + GUI::instance()->geoContext->input[10]->value(), + GUI::instance()->geoContext->input[11]->value(), + GUI::instance()->geoContext->input[15]->value()); + break; + case 6: + delet(List1, CTX.filename, what); + break; + case 7: + add_physical(what, List1, CTX.filename); + break; + case 8: + add_charlength(List1, CTX.filename, GUI::instance()->meshContext->input[0]->value()); + break; + case 9: + add_recosurf(List1, CTX.filename); + break; + + default: + Msg::Error("Unknown action on selected entities"); + break; + } + List_Reset(List1); + GUI::instance()->resetVisibility(); + ZeroHighlight(); + if(action <= 6) SetBoundingBox(); + Draw(); + } + } + if(ib == 'q') { + ZeroHighlight(); + Draw(); + break; + } + } + List_Delete(List1); + + Msg::StatusBar(3, false, ""); +} + +static void geometry_elementary_add_translate_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_add_translate, 0); + return; + } + GUI::instance()->geoContext->show(2); + action_point_line_surface_volume(0, 1, (const char*)data); +} + +static void geometry_elementary_add_rotate_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_add_rotate, 0); + return; + } + GUI::instance()->geoContext->show(3); + action_point_line_surface_volume(1, 1, (const char*)data); +} + +static void geometry_elementary_add_scale_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_add_scale, 0); + return; + } + GUI::instance()->geoContext->show(4); + action_point_line_surface_volume(2, 1, (const char*)data); +} + +static void geometry_elementary_add_symmetry_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_add_symmetry, 0); + return; + } + GUI::instance()->geoContext->show(5); + action_point_line_surface_volume(3, 1, (const char*)data); +} + +static void geometry_elementary_translate_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_translate, 0); + return; + } + GUI::instance()->geoContext->show(2); + action_point_line_surface_volume(0, 0, (const char*)data); +} + +static void geometry_elementary_rotate_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_rotate, 0); + return; + } + GUI::instance()->geoContext->show(3); + action_point_line_surface_volume(1, 0, (const char*)data); +} + +static void geometry_elementary_scale_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_scale, 0); + return; + } + GUI::instance()->geoContext->show(4); + action_point_line_surface_volume(2, 0, (const char*)data); +} + +static void geometry_elementary_symmetry_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_symmetry, 0); + return; + } + GUI::instance()->geoContext->show(5); + action_point_line_surface_volume(3, 0, (const char*)data); +} + +static void geometry_elementary_extrude_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(menu_geometry_elementary_extrude, 0); +} + +static void geometry_elementary_extrude_translate_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_extrude_translate, 0); + return; + } + GUI::instance()->geoContext->show(2); + action_point_line_surface_volume(4, 0, (const char*)data); +} + +static void geometry_elementary_extrude_rotate_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_extrude_rotate, 0); + return; + } + GUI::instance()->geoContext->show(3); + action_point_line_surface_volume(5, 0, (const char*)data); +} + +static void geometry_elementary_delete_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_delete, 0); + return; + } + action_point_line_surface_volume(6, 0, (const char*)data); +} + +static void geometry_elementary_split_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_elementary_split, 0); + return; + } + split_selection(); +} + +static void geometry_elementary_coherence_cb(Fl_Widget *w, void *data) +{ + coherence(CTX.filename); +} + +static void geometry_physical_add_cb(Fl_Widget *w, void *data) +{ + if(!data){ + GUI::instance()->menu->setContext(menu_geometry_physical_add, 0); + return; + } + std::string str((const char*)data); + if(str == "Point") + GUI::instance()->callForSolverPlugin(0); + else if(str == "Line") + GUI::instance()->callForSolverPlugin(1); + + action_point_line_surface_volume(7, 0, str.c_str()); +} + +static void mesh_save_cb(Fl_Widget *w, void *data) +{ + 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); +} + +static void mesh_define_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(menu_mesh_define, 0); +} + +void mesh_1d_cb(Fl_Widget *w, void *data) +{ + GModel::current()->mesh(1); + Draw(); + Msg::StatusBar(2, false, " "); +} + +void mesh_2d_cb(Fl_Widget *w, void *data) +{ + GModel::current()->mesh(2); + Draw(); + Msg::StatusBar(2, false, " "); +} + +void mesh_3d_cb(Fl_Widget *w, void *data) +{ + GModel::current()->mesh(3); + Draw(); + Msg::StatusBar(2, false, " "); +} + +static void mesh_delete_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(menu_mesh_delete, 0); +} + +static void mesh_delete_parts_cb(Fl_Widget *w, void *data) +{ + const char *str = (const 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::StatusBar(3, false, "Select %s\n" + "[Press 'e' to end selection, 'u' to undo last selection or " + "'q' to abort]", str); + else + Msg::StatusBar(3, false, "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::current()->removeInvisibleElements(); + ele.clear(); + ent.clear(); + } + if(ib == 'q') { + ZeroHighlight(); + break; + } + } + + CTX.mesh.changed = ENT_ALL; + CTX.pick_elements = 0; + Draw(); + Msg::StatusBar(3, false, ""); +} + +static void mesh_update_edges_cb(Fl_Widget *w, void *data) +{ + Msg::Error("Update edges not implemented yet"); +} + +static void mesh_remesh_cb(Fl_Widget *w, void *data) +{ + Msg::Error("Remesh not implemented yet"); +} + +static void mesh_inspect_cb(Fl_Widget *w, void *data) +{ + 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::StatusBar(3, false, "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()); + int type = elements[0]->getTypeForMSH(); + const char *name; + MElement::getInfoMSH(type, &name); + Msg::Direct(" Type: %d ('%s')", type, name); + 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()); + Msg::Direct(" Disto: %g", elements[0]->distoShapeMeasure()); + CTX.mesh.changed = ENT_ALL; + Draw(); + GUI::instance()->messages->show(); + } + } + if(ib == 'q') { + ZeroHighlight(); + break; + } + } + + CTX.pick_elements = 0; + CTX.mesh.changed = ENT_ALL; + Draw(); + Msg::StatusBar(3, false, ""); +} + +static void mesh_degree_cb(Fl_Widget *w, void *data) +{ + if((long)data == 2) + SetOrderN(GModel::current(), 2, CTX.mesh.second_order_linear, + CTX.mesh.second_order_incomplete); + else + SetOrder1(GModel::current()); + CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + Draw(); + Msg::StatusBar(2, false, " "); +} + +static void mesh_optimize_cb(Fl_Widget *w, void *data) +{ + if(CTX.threads_lock) { + Msg::Info("I'm busy! Ask me that later..."); + return; + } + CTX.threads_lock = 1; + OptimizeMesh(GModel::current()); + CTX.threads_lock = 0; + CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + Draw(); + Msg::StatusBar(2, false, " "); +} + +static void mesh_refine_cb(Fl_Widget *w, void *data) +{ + RefineMesh(GModel::current(), CTX.mesh.second_order_linear); + CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + Draw(); + Msg::StatusBar(2, false, " "); +} + +static void mesh_optimize_netgen_cb(Fl_Widget *w, void *data) +{ + if(CTX.threads_lock) { + Msg::Info("I'm busy! Ask me that later..."); + return; + } + CTX.threads_lock = 1; + OptimizeMeshNetgen(GModel::current()); + CTX.threads_lock = 0; + CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + Draw(); + Msg::StatusBar(2, false, " "); +} + +static void mesh_partition_cb(Fl_Widget *w, void *data) +{ + partition_dialog(); +} + +static void mesh_define_length_cb(Fl_Widget *w, void *data) +{ + action_point_line_surface_volume(8, 0, "Point"); +} + +static void mesh_define_recombine_cb(Fl_Widget *w, void *data) +{ + action_point_line_surface_volume(9, 0, "Surface"); +} + +static void mesh_define_transfinite_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->menu->setContext(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; + std::vector<int> p; + char ib; + + 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(); + + while(1) { + switch (dim) { + case 1: + if(p.empty()) + Msg::StatusBar(3, false, "Select lines\n" + "[Press 'e' to end selection or 'q' to abort]"); + else + Msg::StatusBar(3, false, "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::StatusBar(3, false, "Select surface\n[Press 'q' to abort]"); + ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions, elements); + break; + case 3: + Msg::StatusBar(3, false, "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(p.size()) + add_trsfline(p, CTX.filename, + GUI::instance()->meshContext->choice[0]->text(), + GUI::instance()->meshContext->input[2]->value(), + GUI::instance()->meshContext->input[1]->value()); + } + ZeroHighlight(); + Draw(); + p.clear(); + } + if(ib == 'u') { + if(dim == 1) { + if(p.size()){ + ZeroHighlightEntityNum(0, p.back(), 0, 0); + Draw(); + p.pop_back(); + } + } + } + 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.push_back(edges[i]->tag()); + } + Draw(); + break; + case 2: + case 3: + if(dim == 2){ + HighlightEntity(faces[0]); + Draw(); + p.push_back(faces[0]->tag()); + } + else{ + HighlightEntity(regions[0]); + Draw(); + p.push_back(regions[0]->tag()); + } + while(1) { + if(p.size() == 1) + Msg::StatusBar(3, false, "Select (ordered) boundary points\n" + "[Press 'e' to end selection or 'q' to abort]"); + else + Msg::StatusBar(3, false, "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.push_back(vertices[0]->tag()); + } + if(ib == 'u') { + if(p.size() > 1){ + ZeroHighlightEntityNum(p.back(), 0, 0, 0); + Draw(); + p.pop_back(); + } + } + if(ib == 'r') { + Msg::Warning("Entity de-selection not supported yet during " + "transfinite definition"); + } + if(ib == 'e') { + switch (dim) { + case 2: + if(p.size() == 0 + 1 || p.size() == 3 + 1 || p.size() == 4 + 1) + add_trsfsurf(p, CTX.filename, + GUI::instance()->meshContext->choice[1]->text()); + else + Msg::Error("Wrong number of points for transfinite surface"); + break; + case 3: + if(p.size() == 6 + 1 || p.size() == 8 + 1) + add_trsfvol(p, CTX.filename); + else + Msg::Error("Wrong number of points for transfinite volume"); + break; + } + ZeroHighlight(); + Draw(); + p.clear(); + break; + } + if(ib == 'q') { + ZeroHighlight(); + Draw(); + goto stopall; + } + } + break; + } + } + } + + stopall: + Msg::StatusBar(3, false, ""); +} + +static void mesh_define_transfinite_line_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->meshContext->show(1); + add_transfinite(1); +} + +static void mesh_define_transfinite_surface_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->meshContext->show(2); + add_transfinite(2); +} + +static void mesh_define_transfinite_volume_cb(Fl_Widget *w, void *data) +{ + add_transfinite(3); +} + +static void view_toggle_cb(Fl_Widget *w, void *data) +{ + int num = (int)(long)data; + opt_view_visible(num, GMSH_SET, + GUI::instance()->menu->toggle[num]->value()); + Draw(); +} + +static void view_reload(int index) +{ + if(index >= 0 && index < (int)PView::list.size()){ + PView *p = PView::list[index]; + + if(StatFile(p->getData()->getFileName().c_str())){ + Msg::Error("File '%s' does not exist", p->getData()->getFileName().c_str()); + return; + } + + int n = PView::list.size(); + + // FIXME: use fileIndex + MergeFile(p->getData()->getFileName().c_str()); + + if((int)PView::list.size() > n){ // we loaded a new view + // delete old data and replace with new + delete p->getData(); + p->setData(PView::list.back()->getData()); + PView::list.back()->setData(0); + // delete new view + delete PView::list.back(); + // in case the reloaded view has a different number of time steps + if(p->getOptions()->TimeStep > p->getData()->getNumTimeSteps() - 1) + p->getOptions()->TimeStep = 0; + p->setChanged(true); + GUI::instance()->updateViews(); + } + } +} + +static void view_reload_cb(Fl_Widget *w, void *data) +{ + view_reload((int)(long)data); + Draw(); +} + +static void view_reload_all_cb(Fl_Widget *w, void *data) +{ + for(unsigned int i = 0; i < PView::list.size(); i++) + view_reload(i); + Draw(); +} + +static void view_reload_visible_cb(Fl_Widget *w, void *data) +{ + for(unsigned int i = 0; i < PView::list.size(); i++) + if(opt_view_visible(i, GMSH_GET, 0)) + view_reload(i); + Draw(); +} + +static void view_remove_other_cb(Fl_Widget *w, void *data) +{ + if(PView::list.empty()) return; + for(int i = PView::list.size() - 1; i >= 0; i--) + if(i != (long)data) delete PView::list[i]; + GUI::instance()->updateViews(); + Draw(); +} + +static void view_remove_all_cb(Fl_Widget *w, void *data) +{ + if(PView::list.empty()) return; + while(PView::list.size()) delete PView::list[0]; + GUI::instance()->updateViews(); + Draw(); +} + +static void view_remove_visible_cb(Fl_Widget *w, void *data) +{ + if(PView::list.empty()) return; + for(int i = PView::list.size() - 1; i >= 0; i--) + if(opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i]; + GUI::instance()->updateViews(); + Draw(); +} + +static void view_remove_invisible_cb(Fl_Widget *w, void *data) +{ + if(PView::list.empty()) return; + for(int i = PView::list.size() - 1; i >= 0; i--) + if(!opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i]; + GUI::instance()->updateViews(); + Draw(); +} + +static void view_remove_empty_cb(Fl_Widget *w, void *data) +{ + if(PView::list.empty()) return; + for(int i = PView::list.size() - 1; i >= 0; i--) + if(PView::list[i]->getData()->empty()) delete PView::list[i]; + GUI::instance()->updateViews(); + Draw(); +} + +static void view_remove_cb(Fl_Widget *w, void *data) +{ + delete PView::list[(int)(long)data]; + GUI::instance()->updateViews(); + Draw(); +} + +static void view_save_as(int index, const char *title, int format) +{ + PView *view = PView::list[index]; + + test: + if(file_chooser(0, 1, title, "*", view->getData()->getFileName().c_str())){ + std::string name = file_chooser_get_name(1); + if(CTX.confirm_overwrite) { + if(!StatFile(name.c_str())) + if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", + "Cancel", "Replace", NULL, name.c_str())) + goto test; + } + view->write(name.c_str(), format); + } +} + +static void view_save_ascii_cb(Fl_Widget *w, void *data) +{ + view_save_as((int)(long)data, "Save As ASCII View", 0); +} + +static void view_save_binary_cb(Fl_Widget *w, void *data) +{ + view_save_as((int)(long)data, "Save As Binary View", 1); +} + +static void view_save_parsed_cb(Fl_Widget *w, void *data) +{ + view_save_as((int)(long)data, "Save As Parsed View", 2); +} + +static void view_save_stl_cb(Fl_Widget *w, void *data) +{ + view_save_as((int)(long)data, "Save As STL Triangulation", 3); +} + +static void view_save_txt_cb(Fl_Widget *w, void *data) +{ + view_save_as((int)(long)data, "Save As Raw Text", 4); +} + +static void view_save_msh_cb(Fl_Widget *w, void *data) +{ + view_save_as((int)(long)data, "Save As Gmsh Mesh", 5); +} + +static void view_save_med_cb(Fl_Widget *w, void *data) +{ + view_save_as((int)(long)data, "Save As MED file", 6); +} + +static void view_alias_cb(Fl_Widget *w, void *data) +{ + new PView(PView::list[(int)(long)data], false); + GUI::instance()->updateViews(); + Draw(); +} + +static void view_alias_with_options_cb(Fl_Widget *w, void *data) +{ + new PView(PView::list[(int)(long)data], true); + GUI::instance()->updateViews(); + Draw(); +} + +static void view_combine_space_all_cb(Fl_Widget *w, void *data) +{ + PView::combine(false, 1, CTX.post.combine_remove_orig); + GUI::instance()->updateViews(); + Draw(); +} + +static void view_combine_space_visible_cb(Fl_Widget *w, void *data) +{ + PView::combine(false, 0, CTX.post.combine_remove_orig); + GUI::instance()->updateViews(); + Draw(); +} + +static void view_combine_space_by_name_cb(Fl_Widget *w, void *data) +{ + PView::combine(false, 2, CTX.post.combine_remove_orig); + GUI::instance()->updateViews(); + Draw(); +} + +static void view_combine_time_all_cb(Fl_Widget *w, void *data) +{ + PView::combine(true, 1, CTX.post.combine_remove_orig); + GUI::instance()->updateViews(); + Draw(); +} + +static void view_combine_time_visible_cb(Fl_Widget *w, void *data) +{ + PView::combine(true, 0, CTX.post.combine_remove_orig); + GUI::instance()->updateViews(); + Draw(); +} + +static void view_combine_time_by_name_cb(Fl_Widget *w, void *data) +{ + PView::combine(true, 2, CTX.post.combine_remove_orig); + GUI::instance()->updateViews(); + Draw(); +} + +static void view_all_visible_cb(Fl_Widget *w, void *data) +{ + for(unsigned int i = 0; i < PView::list.size(); 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(); +} + +static void view_applybgmesh_cb(Fl_Widget *w, void *data) +{ + int index = (int)(long)data; + if(index >= 0 && index < (int)PView::list.size()){ + GModel::current()->getFields()->set_background_mesh(index); + } +} + // The static menus (we cannot use the 'g', 'm' 's' and 'p' mnemonics // since they are already defined as global shortcuts) static Fl_Menu_Item bar_table[] = { @@ -33,7 +2143,7 @@ static Fl_Menu_Item bar_table[] = { {0}, {"&Tools", 0, 0, 0, FL_SUBMENU}, {"&Options...", FL_CTRL+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0}, - {"Pl&ugins...", FL_CTRL+FL_SHIFT+'u', (Fl_Callback *)view_plugin_cb, (void*)(-1)}, + {"Pl&ugins...", FL_CTRL+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)}, {"&Visibility", FL_CTRL+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0}, {"&Clipping", FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0}, {"&Manipulator", FL_CTRL+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0, FL_MENU_DIVIDER}, @@ -72,7 +2182,7 @@ static Fl_Menu_Item sysbar_table[] = { {0}, {"Tools", 0, 0, 0, FL_SUBMENU}, {"Options...", FL_META+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0}, - {"Plugins...", FL_META+FL_SHIFT+'u', (Fl_Callback *)view_plugin_cb, (void*)(-1)}, + {"Plugins...", FL_META+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)}, {"Visibility", FL_META+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0}, {"Clipping", FL_META+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0}, {"Manipulator", FL_META+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0, FL_MENU_DIVIDER}, @@ -288,7 +2398,7 @@ contextItem menu_mesh[] = { }; contextItem menu_mesh_define[] = { {"1Mesh>Define", NULL} , - {"Fields", (Fl_Callback *)view_field_cb}, + {"Fields", (Fl_Callback *)field_cb}, {"Characteristic length", (Fl_Callback *)mesh_define_length_cb } , {"Recombine", (Fl_Callback *)mesh_define_recombine_cb } , {"Transfinite", (Fl_Callback *)mesh_define_transfinite_cb } , @@ -601,7 +2711,7 @@ void menuWindow::setContext(contextItem *menu_asked, int flag) p[j]->add("Options...", 'o', (Fl_Callback *) view_options_cb, (void *)nb, 0); p[j]->add("Plugins...", 'p', - (Fl_Callback *) view_plugin_cb, (void *)nb, 0); + (Fl_Callback *) plugin_cb, (void *)nb, 0); } toggle.push_back(b1); diff --git a/Fltk/menuWindow.h b/Fltk/menuWindow.h index 1953ea97a1..304e2277a0 100644 --- a/Fltk/menuWindow.h +++ b/Fltk/menuWindow.h @@ -76,4 +76,16 @@ class menuWindow{ void setContext(contextItem *menu_asked, int flag); }; +void file_quit_cb(Fl_Widget *w, void *data); +void mod_geometry_cb(Fl_Widget *w, void *data); +void mod_mesh_cb(Fl_Widget *w, void *data); +void mod_solver_cb(Fl_Widget *w, void *data); +void mod_post_cb(Fl_Widget *w, void *data); +void mod_back_cb(Fl_Widget *w, void *data); +void mod_forward_cb(Fl_Widget *w, void *data); +void geometry_reload_cb(Fl_Widget *w, void *data); +void mesh_1d_cb(Fl_Widget *w, void *data); +void mesh_2d_cb(Fl_Widget *w, void *data); +void mesh_3d_cb(Fl_Widget *w, void *data); + #endif diff --git a/Fltk/messageWindow.cpp b/Fltk/messageWindow.cpp index 5c01de08a1..7c387e064a 100644 --- a/Fltk/messageWindow.cpp +++ b/Fltk/messageWindow.cpp @@ -5,15 +5,71 @@ #include <FL/Fl_Box.H> #include <FL/Fl_Return_Button.H> +#include <FL/fl_ask.H> #include "GUI.h" #include "messageWindow.h" #include "shortcutWindow.h" -#include "Callbacks.h" +#include "fileDialogs.h" #include "GmshMessage.h" +#include "OS.h" #include "Context.h" extern Context_T CTX; +void message_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->messages->show(); +} + +static void message_auto_scroll_cb(Fl_Widget *w, void *data) +{ + CTX.msg_auto_scroll = GUI::instance()->messages->butt->value(); +} + +static void message_copy_cb(Fl_Widget *w, void *data) +{ +#define BUFFL 50000 + static char buff[BUFFL]; + strcpy(buff, ""); + for(int i = 1; i <= GUI::instance()->messages->browser->size(); i++) { + if(GUI::instance()->messages->browser->selected(i)) { + const char *c = GUI::instance()->messages->browser->text(i); + if(strlen(buff) + strlen(c) > BUFFL - 2) { + Msg::Error("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); +} + +static void message_clear_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->messages->browser->clear(); +} + +static void message_save_cb(Fl_Widget *w, void *data) +{ + test: + if(file_chooser(0, 1, "Save", "*")) { + std::string name = file_chooser_get_name(1); + if(CTX.confirm_overwrite) { + if(!StatFile(name.c_str())) + if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", + "Cancel", "Replace", NULL, name.c_str())) + goto test; + } + GUI::instance()->messages->save(name.c_str()); + } +} + messageWindow::messageWindow(int fontsize) : _fontsize(fontsize) { @@ -50,7 +106,7 @@ messageWindow::messageWindow(int fontsize) { Fl_Button *o = new Fl_Button (width - BB - WB, height - BH - WB, BB, BH, "Cancel"); - o->callback(cancel_cb, (void *)win); + o->callback(hide_cb, (void *)win); } win->resizable(new Fl_Box(1, 1, 4, 4)); diff --git a/Fltk/messageWindow.h b/Fltk/messageWindow.h index 2d1b2140e4..1cf53836fa 100644 --- a/Fltk/messageWindow.h +++ b/Fltk/messageWindow.h @@ -24,4 +24,6 @@ class messageWindow{ void save(const char *filename); }; +void message_cb(Fl_Widget *w, void *data); + #endif diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp index 114adb6671..fd3b470223 100644 --- a/Fltk/optionWindow.cpp +++ b/Fltk/optionWindow.cpp @@ -7,15 +7,24 @@ #include <FL/Fl_Tabs.H> #include <FL/Fl_Box.H> #include <FL/Fl_Scroll.H> +#include <FL/Fl_Color_Chooser.H> #include "GUI.h" #include "optionWindow.h" #include "shortcutWindow.h" +#include "menuWindow.h" +#include "extraDialogs.h" +#include "Draw.h" +#include "SelectBuffer.h" +#include "GmshDefines.h" #include "GmshMessage.h" #include "Options.h" -#include "Callbacks.h" +#include "Solvers.h" +#include "GModel.h" +#include "MElement.h" #include "PView.h" #include "PViewData.h" #include "PViewOptions.h" +#include "OS.h" #include "Context.h" extern Context_T CTX; @@ -90,6 +99,1051 @@ Fl_Menu_Item menu_font_names[] = { {0} }; +static void color_cb(Fl_Widget *w, void *data) +{ + 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(); +} + +static void view_color_cb(Fl_Widget *w, void *data) +{ + unsigned int (*fct) (int, int, unsigned int); + fct = (unsigned int (*)(int, int, unsigned int))data; + uchar r = CTX.UNPACK_RED(fct(GUI::instance()->options->view.index, GMSH_GET, 0)); + uchar g = CTX.UNPACK_GREEN(fct(GUI::instance()->options->view.index, GMSH_GET, 0)); + uchar b = CTX.UNPACK_BLUE(fct(GUI::instance()->options->view.index, GMSH_GET, 0)); + if(fl_color_chooser("Color Chooser", r, g, b)) + fct(GUI::instance()->options->view.index, + GMSH_SET | GMSH_GUI, CTX.PACK_COLOR(r, g, b, 255)); + Draw(); +} + +void options_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->options->win->show(); +} + +static void options_browser_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->options->showGroup(GUI::instance()->options->browser->value()); +} + +void options_save_cb(Fl_Widget *w, void *data) +{ + Msg::StatusBar(2, true, "Writing '%s'", CTX.options_filename_fullpath); + Print_Options(0, GMSH_OPTIONSRC, 1, 1, CTX.options_filename_fullpath); + Msg::StatusBar(2, true, "Wrote '%s'", CTX.options_filename_fullpath); +} + +static void options_restore_defaults_cb(Fl_Widget *w, void *data) +{ + // 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(GUI::instance()->menu->module->value() == 3) // hack to refresh the buttons + GUI::instance()->menu->setContext(menu_post, 0); + Draw(); +} + +void general_options_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->options->showGroup(1); +} + +static void general_options_color_scheme_cb(Fl_Widget *w, void *data) +{ + opt_general_color_scheme + (0, GMSH_SET, GUI::instance()->options->general.choice[3]->value()); + Draw(); +} + +static void general_options_rotation_center_select_cb(Fl_Widget *w, void *data) +{ + std::vector<GVertex*> vertices; + std::vector<GEdge*> edges; + std::vector<GFace*> faces; + std::vector<GRegion*> regions; + std::vector<MElement*> elements; + + Msg::StatusBar(3, false, "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, GUI::instance()->options->general.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::StatusBar(3, false, ""); +} + +static void general_options_ok_cb(Fl_Widget *w, void *data) +{ + optionWindow *o = GUI::instance()->options; + o->activate((const char*)data); + + static double lc = 0.; + if(lc != CTX.lc){ + lc = CTX.lc; + for(int i = 2; i < 5; i++){ + o->general.value[i]->minimum(-5 * CTX.lc); + o->general.value[i]->maximum(5 * CTX.lc); + } + } + if(data){ + const char *name = (const char*)data; + if(!strcmp(name, "rotation_center_coord")){ + CTX.draw_rotation_center = 1; + } + else if(!strcmp(name, "light_value")){ + double x, y, z; + x = o->general.value[2]->value(); + y = o->general.value[3]->value(); + z = o->general.value[4]->value(); + o->general.sphere->setValue(x, y, z); + } + else if(!strcmp(name, "light_sphere")){ + double x, y, z; + o->general.sphere->getValue(x, y, z); + o->general.value[2]->value(x); + o->general.value[3]->value(y); + o->general.value[4]->value(z); + } + } + + opt_general_axes_auto_position(0, GMSH_SET, o->general.butt[0]->value()); + opt_general_small_axes(0, GMSH_SET, o->general.butt[1]->value()); + opt_general_fast_redraw(0, GMSH_SET, o->general.butt[2]->value()); + opt_general_mouse_hover_meshes(0, GMSH_SET, o->general.butt[11]->value()); + if(opt_general_double_buffer(0, GMSH_GET, 0) != o->general.butt[3]->value()) + opt_general_double_buffer(0, GMSH_SET, o->general.butt[3]->value()); + if(opt_general_antialiasing(0, GMSH_GET, 0) != o->general.butt[12]->value()) + opt_general_antialiasing(0, GMSH_SET, o->general.butt[12]->value()); + opt_general_trackball(0, GMSH_SET, o->general.butt[5]->value()); + opt_general_terminal(0, GMSH_SET, o->general.butt[7]->value()); + double sessionrc = opt_general_session_save(0, GMSH_GET, 0); + opt_general_session_save(0, GMSH_SET, o->general.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, o->general.butt[9]->value()); + opt_general_expert_mode(0, GMSH_SET, o->general.butt[10]->value()); + opt_general_tooltips(0, GMSH_SET, o->general.butt[13]->value()); + opt_general_confirm_overwrite(0, GMSH_SET, o->general.butt[14]->value()); + opt_general_rotation_center_cg(0, GMSH_SET, o->general.butt[15]->value()); + opt_general_draw_bounding_box(0, GMSH_SET, o->general.butt[6]->value()); + opt_general_polygon_offset_always(0, GMSH_SET, o->general.butt[4]->value()); + opt_general_axes_mikado(0, GMSH_SET, o->general.butt[16]->value()); + + opt_general_shine_exponent(0, GMSH_SET, o->general.value[0]->value()); + opt_general_shine(0, GMSH_SET, o->general.value[1]->value()); + opt_general_light00(0, GMSH_SET, o->general.value[2]->value()); + opt_general_light01(0, GMSH_SET, o->general.value[3]->value()); + opt_general_light02(0, GMSH_SET, o->general.value[4]->value()); + opt_general_light03(0, GMSH_SET, o->general.value[13]->value()); + opt_general_verbosity(0, GMSH_SET, o->general.value[5]->value()); + opt_general_point_size(0, GMSH_SET, o->general.value[6]->value()); + opt_general_line_width(0, GMSH_SET, o->general.value[7]->value()); + opt_general_rotation_center0(0, GMSH_SET, o->general.value[8]->value()); + opt_general_rotation_center1(0, GMSH_SET, o->general.value[9]->value()); + opt_general_rotation_center2(0, GMSH_SET, o->general.value[10]->value()); + opt_general_quadric_subdivisions(0, GMSH_SET, o->general.value[11]->value()); + opt_general_graphics_fontsize(0, GMSH_SET, o->general.value[12]->value()); + opt_general_clip_factor(0, GMSH_SET, o->general.value[14]->value()); + opt_general_polygon_offset_factor(0, GMSH_SET, o->general.value[15]->value()); + opt_general_polygon_offset_units(0, GMSH_SET, o->general.value[16]->value()); + opt_general_axes_tics0(0, GMSH_SET, o->general.value[17]->value()); + opt_general_axes_tics1(0, GMSH_SET, o->general.value[18]->value()); + opt_general_axes_tics2(0, GMSH_SET, o->general.value[19]->value()); + opt_general_axes_xmin(0, GMSH_SET, o->general.value[20]->value()); + opt_general_axes_ymin(0, GMSH_SET, o->general.value[21]->value()); + opt_general_axes_zmin(0, GMSH_SET, o->general.value[22]->value()); + opt_general_axes_xmax(0, GMSH_SET, o->general.value[23]->value()); + opt_general_axes_ymax(0, GMSH_SET, o->general.value[24]->value()); + opt_general_axes_zmax(0, GMSH_SET, o->general.value[25]->value()); + opt_general_small_axes_position0(0, GMSH_SET, o->general.value[26]->value()); + opt_general_small_axes_position1(0, GMSH_SET, o->general.value[27]->value()); + + opt_general_default_filename(0, GMSH_SET, o->general.input[0]->value()); + opt_general_editor(0, GMSH_SET, o->general.input[1]->value()); + opt_general_web_browser(0, GMSH_SET, o->general.input[2]->value()); + opt_general_axes_format0(0, GMSH_SET, o->general.input[3]->value()); + opt_general_axes_format1(0, GMSH_SET, o->general.input[4]->value()); + opt_general_axes_format2(0, GMSH_SET, o->general.input[5]->value()); + opt_general_axes_label0(0, GMSH_SET, o->general.input[6]->value()); + opt_general_axes_label1(0, GMSH_SET, o->general.input[7]->value()); + opt_general_axes_label2(0, GMSH_SET, o->general.input[8]->value()); + + opt_general_vector_type(0, GMSH_SET, o->general.choice[0]->value() + 1); + opt_general_graphics_font(0, GMSH_SET, o->general.choice[1]->text()); + opt_general_orthographic(0, GMSH_SET, !o->general.choice[2]->value()); + opt_general_axes(0, GMSH_SET, o->general.choice[4]->value()); + opt_general_background_gradient(0, GMSH_SET, o->general.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; +} + +static void general_arrow_param_cb(Fl_Widget *w, void *data) +{ + 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(); + } +} + +void geometry_options_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->options->showGroup(2); +} + +static void geometry_options_ok_cb(Fl_Widget *w, void *data) +{ + optionWindow *o = GUI::instance()->options; + o->activate((const char*)data); + + opt_geometry_points(0, GMSH_SET, o->geo.butt[0]->value()); + opt_geometry_lines(0, GMSH_SET, o->geo.butt[1]->value()); + opt_geometry_surfaces(0, GMSH_SET, o->geo.butt[2]->value()); + opt_geometry_volumes(0, GMSH_SET, o->geo.butt[3]->value()); + opt_geometry_points_num(0, GMSH_SET, o->geo.butt[4]->value()); + opt_geometry_lines_num(0, GMSH_SET, o->geo.butt[5]->value()); + opt_geometry_surfaces_num(0, GMSH_SET, o->geo.butt[6]->value()); + opt_geometry_volumes_num(0, GMSH_SET, o->geo.butt[7]->value()); + opt_geometry_auto_coherence(0, GMSH_SET, o->geo.butt[8]->value()); + opt_geometry_light(0, GMSH_SET, o->geo.butt[9]->value()); + opt_geometry_highlight_orphans(0, GMSH_SET, o->geo.butt[10]->value()); + opt_geometry_occ_fix_small_edges(0, GMSH_SET, o->geo.butt[11]->value()); + opt_geometry_occ_fix_small_faces(0, GMSH_SET, o->geo.butt[12]->value()); + opt_geometry_occ_sew_faces(0, GMSH_SET, o->geo.butt[13]->value()); + opt_geometry_light_two_side(0, GMSH_SET, o->geo.butt[14]->value()); + + opt_geometry_normals(0, GMSH_SET, o->geo.value[0]->value()); + opt_geometry_tangents(0, GMSH_SET, o->geo.value[1]->value()); + opt_geometry_tolerance(0, GMSH_SET, o->geo.value[2]->value()); + opt_geometry_point_size(0, GMSH_SET, o->geo.value[3]->value()); + opt_geometry_line_width(0, GMSH_SET, o->geo.value[4]->value()); + opt_geometry_point_sel_size(0, GMSH_SET, o->geo.value[5]->value()); + opt_geometry_line_sel_width(0, GMSH_SET, o->geo.value[6]->value()); + + opt_geometry_point_type(0, GMSH_SET, o->geo.choice[0]->value()); + opt_geometry_line_type(0, GMSH_SET, o->geo.choice[1]->value()); + opt_geometry_surface_type(0, GMSH_SET, o->geo.choice[2]->value()); + + if(CTX.fast_redraw) + CTX.post.draw = CTX.mesh.draw = 0; + Draw(); + CTX.post.draw = CTX.mesh.draw = 1; +} + +void mesh_options_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->options->showGroup(3); +} + +static void mesh_options_ok_cb(Fl_Widget *w, void *data) +{ + optionWindow *o = GUI::instance()->options; + o->activate((const char*)data); + + opt_mesh_reverse_all_normals(0, GMSH_SET, o->mesh.butt[0]->value()); + opt_mesh_lc_from_curvature(0, GMSH_SET, o->mesh.butt[1]->value()); + opt_mesh_lc_from_points(0, GMSH_SET, o->mesh.butt[5]->value()); + opt_mesh_lc_extend_from_boundary(0, GMSH_SET, o->mesh.butt[16]->value()); + opt_mesh_optimize(0, GMSH_SET, o->mesh.butt[2]->value()); + opt_mesh_optimize_netgen(0, GMSH_SET, o->mesh.butt[24]->value()); + opt_mesh_order(0, GMSH_SET, o->mesh.value[3]->value()); + opt_mesh_smooth_internal_edges(0, GMSH_SET, o->mesh.butt[3]->value()); + opt_mesh_second_order_incomplete(0, GMSH_SET, o->mesh.butt[4]->value()); + opt_mesh_c1(0, GMSH_SET, o->mesh.butt[21]->value()); + opt_mesh_points(0, GMSH_SET, o->mesh.butt[6]->value()); + opt_mesh_lines(0, GMSH_SET, o->mesh.butt[7]->value()); + opt_mesh_triangles(0, GMSH_SET, o->mesh.menu->menu()[0].value() ? 1 : 0); + opt_mesh_quadrangles(0, GMSH_SET, o->mesh.menu->menu()[1].value() ? 1 : 0); + opt_mesh_tetrahedra(0, GMSH_SET, o->mesh.menu->menu()[2].value() ? 1 : 0); + opt_mesh_hexahedra(0, GMSH_SET, o->mesh.menu->menu()[3].value() ? 1 : 0); + opt_mesh_prisms(0, GMSH_SET, o->mesh.menu->menu()[4].value() ? 1 : 0); + opt_mesh_pyramids(0, GMSH_SET, o->mesh.menu->menu()[5].value() ? 1 : 0); + opt_mesh_surfaces_edges(0, GMSH_SET, o->mesh.butt[8]->value()); + opt_mesh_surfaces_faces(0, GMSH_SET, o->mesh.butt[9]->value()); + opt_mesh_volumes_edges(0, GMSH_SET, o->mesh.butt[10]->value()); + opt_mesh_volumes_faces(0, GMSH_SET, o->mesh.butt[11]->value()); + opt_mesh_points_num(0, GMSH_SET, o->mesh.butt[12]->value()); + opt_mesh_lines_num(0, GMSH_SET, o->mesh.butt[13]->value()); + opt_mesh_surfaces_num(0, GMSH_SET, o->mesh.butt[14]->value()); + opt_mesh_volumes_num(0, GMSH_SET, o->mesh.butt[15]->value()); + opt_mesh_light(0, GMSH_SET, o->mesh.butt[17]->value()); + opt_mesh_light_two_side(0, GMSH_SET, o->mesh.butt[18]->value()); + opt_mesh_smooth_normals(0, GMSH_SET, o->mesh.butt[19]->value()); + opt_mesh_light_lines(0, GMSH_SET, o->mesh.butt[20]->value()); + opt_mesh_nb_smoothing(0, GMSH_SET, o->mesh.value[0]->value()); + opt_mesh_lc_factor(0, GMSH_SET, o->mesh.value[2]->value()); + opt_mesh_lc_min(0, GMSH_SET, o->mesh.value[25]->value()); + opt_mesh_lc_max(0, GMSH_SET, o->mesh.value[26]->value()); + opt_mesh_quality_inf(0, GMSH_SET, o->mesh.value[4]->value()); + opt_mesh_quality_sup(0, GMSH_SET, o->mesh.value[5]->value()); + opt_mesh_radius_inf(0, GMSH_SET, o->mesh.value[6]->value()); + opt_mesh_radius_sup(0, GMSH_SET, o->mesh.value[7]->value()); + opt_mesh_normals(0, GMSH_SET, o->mesh.value[8]->value()); + opt_mesh_explode(0, GMSH_SET, o->mesh.value[9]->value()); + opt_mesh_tangents(0, GMSH_SET, o->mesh.value[13]->value()); + opt_mesh_point_size(0, GMSH_SET, o->mesh.value[10]->value()); + opt_mesh_line_width(0, GMSH_SET, o->mesh.value[11]->value()); + opt_mesh_label_frequency(0, GMSH_SET, o->mesh.value[12]->value()); + opt_mesh_angle_smooth_normals(0, GMSH_SET, o->mesh.value[18]->value()); + + opt_mesh_point_type(0, GMSH_SET, o->mesh.choice[0]->value()); + opt_mesh_algo2d(0, GMSH_SET, + (o->mesh.choice[2]->value() == 0) ? ALGO_2D_FRONTAL : + (o->mesh.choice[2]->value() == 1) ? ALGO_2D_DELAUNAY : + ALGO_2D_MESHADAPT_DELAUNAY); + opt_mesh_algo3d(0, GMSH_SET, + (o->mesh.choice[3]->value() == 0) ? ALGO_3D_TETGEN_DELAUNAY : + ALGO_3D_NETGEN); + opt_mesh_recombine_algo(0, GMSH_SET, + (o->mesh.choice[5]->value() == 0) ? 1 : 2); + opt_mesh_color_carousel(0, GMSH_SET, o->mesh.choice[4]->value()); + opt_mesh_quality_type(0, GMSH_SET, o->mesh.choice[6]->value()); + opt_mesh_label_type(0, GMSH_SET, o->mesh.choice[7]->value()); + + if(CTX.fast_redraw) + CTX.post.draw = CTX.mesh.draw = 0; + Draw(); + CTX.post.draw = CTX.mesh.draw = 1; +} + +void solver_options_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->options->showGroup(4); +} + +static void solver_options_ok_cb(Fl_Widget *w, void *data) +{ + optionWindow *o = GUI::instance()->options; + o->activate((const char*)data); + + int old_listen = (int)opt_solver_listen(0, GMSH_GET, o->solver.butt[0]->value()); + opt_solver_listen(0, GMSH_SET, o->solver.butt[0]->value()); + if(!old_listen && o->solver.butt[0]->value()) + Solver(-1, NULL); + + opt_solver_max_delay(0, GMSH_SET, o->solver.value[0]->value()); + + opt_solver_socket_name(0, GMSH_SET, o->solver.input[0]->value()); + + if(CTX.fast_redraw) + CTX.post.draw = CTX.mesh.draw = 0; + Draw(); + CTX.post.draw = CTX.mesh.draw = 1; +} + +void post_options_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->options->showGroup(5); +} + +static void post_options_ok_cb(Fl_Widget *w, void *data) +{ + optionWindow *o = GUI::instance()->options; + o->activate((const char*)data); + + opt_post_anim_cycle(0, GMSH_SET, o->post.butt[0]->value()); + opt_post_combine_remove_orig(0, GMSH_SET, o->post.butt[1]->value()); + opt_post_horizontal_scales(0, GMSH_SET, o->post.butt[2]->value()); + + opt_post_anim_delay(0, GMSH_SET, o->post.value[0]->value()); + + opt_post_link(0, GMSH_SET, o->post.choice[0]->value()); + + if(CTX.fast_redraw) + CTX.post.draw = CTX.mesh.draw = 0; + Draw(); + CTX.post.draw = CTX.mesh.draw = 1; +} + +void view_options_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->options->showGroup((int)(long)data + 6); +} + +static void view_options_timestep_cb(Fl_Widget *w, void *data) +{ + int links = (int)opt_post_link(0, GMSH_GET, 0); + for(int i = 0; i < (int)PView::list.size(); i++) { + if((links == 2 || links == 4) || + ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) || + (links == 0 && i == GUI::instance()->options->view.index)) { + opt_view_timestep(i, GMSH_SET, ((Fl_Value_Input *) w)->value()); + } + } + Draw(); +} + +static void view_options_timestep_decr_cb(Fl_Widget *w, void *data) +{ + int links = (int)opt_post_link(0, GMSH_GET, 0); + for(int i = 0; i < (int)PView::list.size(); i++) { + if((links == 2 || links == 4) || + ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) || + (links == 0 && i == GUI::instance()->options->view.index)) { + opt_view_timestep(i, GMSH_SET | GMSH_GUI, + opt_view_timestep(i, GMSH_GET, 0) - 1); + } + } + Draw(); +} + +static void view_options_timestep_incr_cb(Fl_Widget *w, void *data) +{ + int links = (int)opt_post_link(0, GMSH_GET, 0); + for(int i = 0; i < (int)PView::list.size(); i++) { + if((links == 2 || links == 4) || + ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) || + (links == 0 && i == GUI::instance()->options->view.index)) { + opt_view_timestep(i, GMSH_SET | GMSH_GUI, + opt_view_timestep(i, GMSH_GET, 0) + 1); + } + } + Draw(); +} + +static void view_arrow_param_cb(Fl_Widget *w, void *data) +{ + double a = opt_view_arrow_head_radius + (GUI::instance()->options->view.index, GMSH_GET, 0); + double b = opt_view_arrow_stem_length + (GUI::instance()->options->view.index, GMSH_GET, 0); + double c = opt_view_arrow_stem_radius + (GUI::instance()->options->view.index, GMSH_GET, 0); + while(arrow_editor("Arrow Editor", a, b, c)){ + opt_view_arrow_head_radius + (GUI::instance()->options->view.index, GMSH_SET, a); + opt_view_arrow_stem_length + (GUI::instance()->options->view.index, GMSH_SET, b); + opt_view_arrow_stem_radius + (GUI::instance()->options->view.index, GMSH_SET, c); + Draw(); + } +} + +static void view_options_ok_cb(Fl_Widget *w, void *data) +{ + int current = GUI::instance()->options->view.index; + + if(current < 0) return; + + optionWindow *o = GUI::instance()->options; + o->activate((const char*)data); + + if(data){ + const char *str = (const char*)data; + if(!strcmp(str, "range_min")){ + o->view.value[31]->value(opt_view_min(o->view.index, GMSH_GET, 0)); + } + else if(!strcmp(str, "range_max")){ + o->view.value[32]->value(opt_view_max(o->view.index, 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 mikado = opt_view_axes_mikado(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 draw_skin_only = opt_view_draw_skin_only(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 center_glyphs = opt_view_center_glyphs(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 normal_raise = opt_view_normal_raise(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 < (int)PView::list.size(); 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 + + val = o->view.choice[1]->value() + 1; + if(force || (val != scale_type)) + opt_view_scale_type(i, GMSH_SET, val); + + val = o->view.choice[0]->value() + 1; + if(force || (val != intervals_type)) + opt_view_intervals_type(i, GMSH_SET, val); + + val = o->view.choice[5]->value(); + if(force || (val != point_type)) + opt_view_point_type(i, GMSH_SET, val); + + val = o->view.choice[6]->value(); + if(force || (val != line_type)) + opt_view_line_type(i, GMSH_SET, val); + + val = o->view.choice[2]->value() + 1; + if(force || (val != vector_type)) + opt_view_vector_type(i, GMSH_SET, val); + + val = o->view.choice[3]->value() + 1; + if(force || (val != glyph_location)) + opt_view_glyph_location(i, GMSH_SET, val); + + val = o->view.choice[4]->value() + 1; + if(force || (val != tensor_type)) + opt_view_tensor_type(i, GMSH_SET, val); + + val = o->view.choice[7]->value() + 1; + if(force || (val != range_type)) + opt_view_range_type(i, GMSH_SET, val); + + val = o->view.choice[8]->value(); + if(force || (val != axes)) + opt_view_axes(i, GMSH_SET, val); + + val = o->view.choice[9]->value(); + if(force || (val != boundary)) + opt_view_boundary(i, GMSH_SET, val); + + val = o->view.choice[10]->value() - 1; + if(force || (val != external_view)) + opt_view_external_view(i, GMSH_SET, val); + + val = o->view.choice[11]->value() - 1; + if(force || (val != gen_raise_view)) + opt_view_gen_raise_view(i, GMSH_SET, val); + + val = o->view.choice[12]->value(); + if(force || (val != show_time)) + opt_view_show_time(i, GMSH_SET, val); + + val = o->view.choice[13]->value() + 1; + if(force || (val != type)) + opt_view_type(i, GMSH_SET, val); + + // view_butts + + val = o->view.butt[0]->value(); + if(force || (val != arrow_size_proportional)) + opt_view_arrow_size_proportional(i, GMSH_SET, val); + + val = o->view.butt[38]->value(); + if(force || (val != saturate_values)) + opt_view_saturate_values(i, GMSH_SET, val); + + val = o->view.butt[10]->value(); + if(force || (val != show_element)) + opt_view_show_element(i, GMSH_SET, val); + + val = o->view.butt[2]->value(); + if(force || (val != draw_skin_only)) + opt_view_draw_skin_only(i, GMSH_SET, val); + + val = o->view.butt[4]->value(); + if(force || (val != show_scale)) + opt_view_show_scale(i, GMSH_SET, val); + + val = o->view.butt[3]->value(); + if(force || (val != mikado)) + opt_view_axes_mikado(i, GMSH_SET, val); + + val = o->view.butt[7]->value(); + if(force || (val != auto_position)) + opt_view_auto_position(i, GMSH_SET, val); + + val = o->view.butt[25]->value(); + if(force || (val != axes_auto_position)) + opt_view_axes_auto_position(i, GMSH_SET, val); + + val = o->view.butt[5]->value(); + if(force || (val != draw_strings)) + opt_view_draw_strings(i, GMSH_SET, val); + + val = o->view.butt[11]->value(); + if(force || (val != light)) + opt_view_light(i, GMSH_SET, val); + + val = o->view.butt[8]->value(); + if(force || (val != light_lines)) + opt_view_light_lines(i, GMSH_SET, val); + + val = o->view.butt[9]->value(); + if(force || (val != light_two_side)) + opt_view_light_two_side(i, GMSH_SET, val); + + val = o->view.butt[12]->value(); + if(force || (val != smooth_normals)) + opt_view_smooth_normals(i, GMSH_SET, val); + + val = o->view.menu[0]->menu()[0].value() ? 1 : 0; + if(force || (val != draw_scalars)) + opt_view_draw_scalars(i, GMSH_SET, val); + + val = o->view.menu[0]->menu()[1].value() ? 1 : 0; + if(force || (val != draw_vectors)) + opt_view_draw_vectors(i, GMSH_SET, val); + + val = o->view.menu[0]->menu()[2].value() ? 1 : 0; + if(force || (val != draw_tensors)) + opt_view_draw_tensors(i, GMSH_SET, val); + + val = o->view.menu[1]->menu()[0].value() ? 1 : 0; + if(force || (val != draw_points)) + opt_view_draw_points(i, GMSH_SET, val); + + val = o->view.menu[1]->menu()[1].value() ? 1 : 0; + if(force || (val != draw_lines)) + opt_view_draw_lines(i, GMSH_SET, val); + + val = o->view.menu[1]->menu()[2].value() ? 1 : 0; + if(force || (val != draw_triangles)) + opt_view_draw_triangles(i, GMSH_SET, val); + + val = o->view.menu[1]->menu()[3].value() ? 1 : 0; + if(force || (val != draw_quadrangles)) + opt_view_draw_quadrangles(i, GMSH_SET, val); + + val = o->view.menu[1]->menu()[4].value() ? 1 : 0; + if(force || (val != draw_tetrahedra)) + opt_view_draw_tetrahedra(i, GMSH_SET, val); + + val = o->view.menu[1]->menu()[5].value() ? 1 : 0; + if(force || (val != draw_hexahedra)) + opt_view_draw_hexahedra(i, GMSH_SET, val); + + val = o->view.menu[1]->menu()[6].value() ? 1 : 0; + if(force || (val != draw_prisms)) + opt_view_draw_prisms(i, GMSH_SET, val); + + val = o->view.menu[1]->menu()[7].value() ? 1 : 0; + if(force || (val != draw_pyramids)) + opt_view_draw_pyramids(i, GMSH_SET, val); + + val = o->view.butt[6]->value(); + if(force || (val != use_gen_raise)) + opt_view_use_gen_raise(i, GMSH_SET, val); + + val = o->view.butt[24]->value(); + if(force || (val != fake_transparency)) + opt_view_fake_transparency(i, GMSH_SET, val); + + val = o->view.butt[26]->value(); + if(force || (val != use_stipple)) + opt_view_use_stipple(i, GMSH_SET, val); + + val = o->view.butt[1]->value(); + if(force || (val != center_glyphs)) + opt_view_center_glyphs(i, GMSH_SET, val); + + // view_values + + val = o->view.value[0]->value(); + if(force || (val != normals)) + opt_view_normals(i, GMSH_SET, val); + + val = o->view.value[1]->value(); + if(force || (val != tangents)) + opt_view_tangents(i, GMSH_SET, val); + + val = o->view.value[31]->value(); + if(force || (val != custom_min)) + opt_view_custom_min(i, GMSH_SET, val); + + val = o->view.value[32]->value(); + if(force || (val != custom_max)) + opt_view_custom_max(i, GMSH_SET, val); + + val = o->view.value[33]->value(); + if(force || (val != max_recursion_level)) + opt_view_max_recursion_level(i, GMSH_SET, val); + + val = o->view.value[34]->value(); + if(force || (val != target_error)) + opt_view_target_error(i, GMSH_SET, val); + + val = o->view.value[30]->value(); + if(force || (val != nb_iso)) + opt_view_nb_iso(i, GMSH_SET, val); + + val = o->view.value[40]->value(); + if(force || (val != offset0)) + opt_view_offset0(i, GMSH_SET, val); + + val = o->view.value[41]->value(); + if(force || (val != offset1)) + opt_view_offset1(i, GMSH_SET, val); + + val = o->view.value[42]->value(); + if(force || (val != offset2)) + opt_view_offset2(i, GMSH_SET, val); + + val = o->view.value[51]->value(); + if(force || (val != transform00)) + opt_view_transform00(i, GMSH_SET, val); + + val = o->view.value[52]->value(); + if(force || (val != transform01)) + opt_view_transform01(i, GMSH_SET, val); + + val = o->view.value[53]->value(); + if(force || (val != transform02)) + opt_view_transform02(i, GMSH_SET, val); + + val = o->view.value[54]->value(); + if(force || (val != transform10)) + opt_view_transform10(i, GMSH_SET, val); + + val = o->view.value[55]->value(); + if(force || (val != transform11)) + opt_view_transform11(i, GMSH_SET, val); + + val = o->view.value[56]->value(); + if(force || (val != transform12)) + opt_view_transform12(i, GMSH_SET, val); + + val = o->view.value[57]->value(); + if(force || (val != transform20)) + opt_view_transform20(i, GMSH_SET, val); + + val = o->view.value[58]->value(); + if(force || (val != transform21)) + opt_view_transform21(i, GMSH_SET, val); + + val = o->view.value[59]->value(); + if(force || (val != transform22)) + opt_view_transform22(i, GMSH_SET, val); + + val = o->view.value[43]->value(); + if(force || (val != raise0)) + opt_view_raise0(i, GMSH_SET, val); + + val = o->view.value[44]->value(); + if(force || (val != raise1)) + opt_view_raise1(i, GMSH_SET, val); + + val = o->view.value[45]->value(); + if(force || (val != raise2)) + opt_view_raise2(i, GMSH_SET, val); + + val = o->view.value[46]->value(); + if(force || (val != normal_raise)) + opt_view_normal_raise(i, GMSH_SET, val); + + val = o->view.value[50]->value(); + if(force || (val != timestep)) + opt_view_timestep(i, GMSH_SET, val); + + val = o->view.value[60]->value(); + if(force || (val != arrow_size)) + opt_view_arrow_size(i, GMSH_SET, val); + + val = o->view.value[63]->value(); + if(force || (val != displacement_factor)) + opt_view_displacement_factor(i, GMSH_SET, val); + + val = o->view.value[61]->value(); + if(force || (val != point_size)) + opt_view_point_size(i, GMSH_SET, val); + + val = o->view.value[62]->value(); + if(force || (val != line_width)) + opt_view_line_width(i, GMSH_SET, val); + + val = o->view.value[12]->value(); + if(force || (val != explode)) + opt_view_explode(i, GMSH_SET, val); + + val = o->view.value[10]->value(); + if(force || (val != angle_smooth_normals)) + opt_view_angle_smooth_normals(i, GMSH_SET, val); + + val = o->view.value[20]->value(); + if(force || (val != position0)) + opt_view_position0(i, GMSH_SET, val); + + val = o->view.value[21]->value(); + if(force || (val != position1)) + opt_view_position1(i, GMSH_SET, val); + + val = o->view.value[22]->value(); + if(force || (val != size0)) + opt_view_size0(i, GMSH_SET, val); + + val = o->view.value[23]->value(); + if(force || (val != size1)) + opt_view_size1(i, GMSH_SET, val); + + val = o->view.value[13]->value(); + if(force || (val != axes_xmin)) + opt_view_axes_xmin(i, GMSH_SET, val); + + val = o->view.value[14]->value(); + if(force || (val != axes_ymin)) + opt_view_axes_ymin(i, GMSH_SET, val); + + val = o->view.value[15]->value(); + if(force || (val != axes_zmin)) + opt_view_axes_zmin(i, GMSH_SET, val); + + val = o->view.value[16]->value(); + if(force || (val != axes_xmax)) + opt_view_axes_xmax(i, GMSH_SET, val); + + val = o->view.value[17]->value(); + if(force || (val != axes_ymax)) + opt_view_axes_ymax(i, GMSH_SET, val); + + val = o->view.value[18]->value(); + if(force || (val != axes_zmax)) + opt_view_axes_zmax(i, GMSH_SET, val); + + val = o->view.value[2]->value(); + if(force || (val != gen_raise_factor)) + opt_view_gen_raise_factor(i, GMSH_SET, val); + + val = o->view.value[3]->value(); + if(force || (val != axes_tics0)) + opt_view_axes_tics0(i, GMSH_SET, val); + + val = o->view.value[4]->value(); + if(force || (val != axes_tics1)) + opt_view_axes_tics1(i, GMSH_SET, val); + + val = o->view.value[5]->value(); + if(force || (val != axes_tics2)) + opt_view_axes_tics2(i, GMSH_SET, val); + + // view_inputs + + const char *str; + + str = o->view.input[0]->value(); + if(force || strcmp(str, name)) + opt_view_name(i, GMSH_SET, str); + + str = o->view.input[1]->value(); + if(force || strcmp(str, format)) + opt_view_format(i, GMSH_SET, str); + + str = o->view.input[10]->value(); + if(force || strcmp(str, axes_label0)) + opt_view_axes_label0(i, GMSH_SET, str); + + str = o->view.input[11]->value(); + if(force || strcmp(str, axes_label1)) + opt_view_axes_label1(i, GMSH_SET, str); + + str = o->view.input[12]->value(); + if(force || strcmp(str, axes_label2)) + opt_view_axes_label2(i, GMSH_SET, str); + + str = o->view.input[7]->value(); + if(force || strcmp(str, axes_format0)) + opt_view_axes_format0(i, GMSH_SET, str); + + str = o->view.input[8]->value(); + if(force || strcmp(str, axes_format1)) + opt_view_axes_format1(i, GMSH_SET, str); + + str = o->view.input[9]->value(); + if(force || strcmp(str, axes_format2)) + opt_view_axes_format2(i, GMSH_SET, str); + + str = o->view.input[4]->value(); + if(force || strcmp(str, gen_raise0)) + opt_view_gen_raise0(i, GMSH_SET, str); + + str = o->view.input[5]->value(); + if(force || strcmp(str, gen_raise1)) + opt_view_gen_raise1(i, GMSH_SET, str); + + str = o->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)) { + ColorTable_Copy(&PView::list[current]->getOptions()->CT); + ColorTable_Paste(&PView::list[i]->getOptions()->CT); + PView::list[i]->setChanged(true); + } + } + } + + if(CTX.fast_redraw) + CTX.post.draw = CTX.mesh.draw = 0; + Draw(); + CTX.post.draw = CTX.mesh.draw = 1; +} + optionWindow::optionWindow(int fontsize) : _fontsize(fontsize) { int width = 34 * _fontsize + WB; @@ -104,7 +1158,7 @@ optionWindow::optionWindow(int fontsize) : _fontsize(fontsize) { Fl_Button *o = new Fl_Button (width - BB - WB, height - BH - WB, BB, BH, "Cancel"); - o->callback(cancel_cb, (void *)win); + o->callback(hide_cb, (void *)win); } { Fl_Button *o = new Fl_Button @@ -2221,3 +3275,199 @@ void optionWindow::updateViewGroup(int index) view.colorbar->update(data->getName().c_str(), data->getMin(), data->getMax(), &opt->CT, &v->getChanged()); } + +void optionWindow::activate(const char *what) +{ + if(!what) return; + + // activate/deactivate parts of the option window depending on the + // user's choices (or the option settings) + if(!strcmp(what, "fast_redraw")){ + if(general.butt[2]->value()) + redraw->show(); + else + redraw->hide(); + } + else if(!strcmp(what, "rotation_center")){ + if(general.butt[15]->value()) { + general.push[0]->deactivate(); + general.value[8]->deactivate(); + general.value[9]->deactivate(); + general.value[10]->deactivate(); + } + else { + general.push[0]->activate(); + general.value[8]->activate(); + general.value[9]->activate(); + general.value[10]->activate(); + } + } + else if(!strcmp(what, "general_axes")){ + if(general.choice[4]->value()){ + general.value[17]->activate(); + general.value[18]->activate(); + general.value[19]->activate(); + general.input[3]->activate(); + general.input[4]->activate(); + general.input[5]->activate(); + general.input[6]->activate(); + general.input[7]->activate(); + general.input[8]->activate(); + } + else{ + general.value[17]->deactivate(); + general.value[18]->deactivate(); + general.value[19]->deactivate(); + general.input[3]->deactivate(); + general.input[4]->deactivate(); + general.input[5]->deactivate(); + general.input[6]->deactivate(); + general.input[7]->deactivate(); + general.input[8]->deactivate(); + } + } + else if(!strcmp(what, "general_axes_auto")){ + if(general.butt[0]->value()){ + general.value[20]->deactivate(); + general.value[21]->deactivate(); + general.value[22]->deactivate(); + general.value[23]->deactivate(); + general.value[24]->deactivate(); + general.value[25]->deactivate(); + } + else{ + general.value[20]->activate(); + general.value[21]->activate(); + general.value[22]->activate(); + general.value[23]->activate(); + general.value[24]->activate(); + general.value[25]->activate(); + } + } + else if(!strcmp(what, "general_small_axes")){ + if(general.butt[1]->value()){ + general.value[26]->activate(); + general.value[27]->activate(); + } + else{ + general.value[26]->deactivate(); + general.value[27]->deactivate(); + } + } + else if(!strcmp(what, "custom_range")){ + if(view.choice[7]->value() == 1){ + view.value[31]->activate(); + view.value[32]->activate(); + view.push[1]->activate(); + view.push[2]->activate(); + } + else { + view.value[31]->deactivate(); + view.value[32]->deactivate(); + view.push[1]->deactivate(); + view.push[2]->deactivate(); + } + } + else if(!strcmp(what, "general_transform")){ + if(view.butt[6]->value()){ + view.choice[11]->activate(); + view.value[2]->activate(); + view.input[4]->activate(); + view.input[5]->activate(); + view.input[6]->activate(); + } + else{ + view.choice[11]->deactivate(); + view.value[2]->deactivate(); + view.input[4]->deactivate(); + view.input[5]->deactivate(); + view.input[6]->deactivate(); + } + } + else if(!strcmp(what, "mesh_light")){ + if(mesh.butt[17]->value()){ + mesh.butt[18]->activate(); + mesh.butt[19]->activate(); + mesh.butt[20]->activate(); + mesh.butt[0]->activate(); + mesh.value[18]->activate(); + } + else{ + mesh.butt[18]->deactivate(); + mesh.butt[19]->deactivate(); + mesh.butt[20]->deactivate(); + mesh.butt[0]->deactivate(); + mesh.value[18]->deactivate(); + } + } + else if(!strcmp(what, "view_light")){ + if(view.butt[11]->value()){ + view.butt[8]->activate(); + view.butt[9]->activate(); + view.butt[12]->activate(); + view.value[10]->activate(); + } + else{ + view.butt[8]->deactivate(); + view.butt[9]->deactivate(); + view.butt[12]->deactivate(); + view.value[10]->deactivate(); + } + } + else if(!strcmp(what, "view_axes")){ + if(view.choice[8]->value()){ + view.value[3]->activate(); + view.value[4]->activate(); + view.value[5]->activate(); + view.input[7]->activate(); + view.input[8]->activate(); + view.input[9]->activate(); + view.input[10]->activate(); + view.input[11]->activate(); + view.input[12]->activate(); + } + else{ + view.value[3]->deactivate(); + view.value[4]->deactivate(); + view.value[5]->deactivate(); + view.input[7]->deactivate(); + view.input[8]->deactivate(); + view.input[9]->deactivate(); + view.input[10]->deactivate(); + view.input[11]->deactivate(); + view.input[12]->deactivate(); + } + } + else if(!strcmp(what, "view_axes_auto_3d")){ + if(view.butt[25]->value()){ + view.value[13]->deactivate(); + view.value[14]->deactivate(); + view.value[15]->deactivate(); + view.value[16]->deactivate(); + view.value[17]->deactivate(); + view.value[18]->deactivate(); + } + else{ + view.value[13]->activate(); + view.value[14]->activate(); + view.value[15]->activate(); + view.value[16]->activate(); + view.value[17]->activate(); + view.value[18]->activate(); + } + } + else if(!strcmp(what, "view_axes_auto_2d")){ + if(view.butt[7]->value()){ + view.value[20]->deactivate(); + view.value[21]->deactivate(); + view.value[22]->deactivate(); + view.value[23]->deactivate(); + } + else{ + view.value[20]->activate(); + view.value[21]->activate(); + view.value[22]->activate(); + view.value[23]->activate(); + } + } +} diff --git a/Fltk/optionWindow.h b/Fltk/optionWindow.h index b103a78b90..e182003554 100644 --- a/Fltk/optionWindow.h +++ b/Fltk/optionWindow.h @@ -90,6 +90,16 @@ class optionWindow{ void resetBrowser(); void resetExternalViewList(); void updateViewGroup(int index); + void activate(const char *what); }; +void options_cb(Fl_Widget *w, void *data); +void options_save_cb(Fl_Widget *w, void *data); +void general_options_cb(Fl_Widget *w, void *data); +void geometry_options_cb(Fl_Widget *w, void *data); +void mesh_options_cb(Fl_Widget *w, void *data); +void solver_options_cb(Fl_Widget *w, void *data); +void post_options_cb(Fl_Widget *w, void *data); +void view_options_cb(Fl_Widget *w, void *data); + #endif diff --git a/Fltk/pluginWindow.cpp b/Fltk/pluginWindow.cpp index 6aac712470..b66a65ed2c 100644 --- a/Fltk/pluginWindow.cpp +++ b/Fltk/pluginWindow.cpp @@ -8,16 +8,150 @@ #include <FL/Fl_Tabs.H> #include <FL/Fl_Scroll.H> #include "GUI.h" +#include "Draw.h" #include "pluginWindow.h" #include "shortcutWindow.h" #include "PView.h" #include "PluginManager.h" #include "Plugin.h" -#include "Callbacks.h" #include "Context.h" extern Context_T CTX; +void plugin_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->plugins->show((int)(long)data); +} + +static void plugin_input_value_cb(Fl_Widget *w, void *data) +{ + double (*f)(int, int, double) = (double (*)(int, int, double)) data; + Fl_Value_Input *input = (Fl_Value_Input*) w; + f(-1, 0, input->value()); +} + +static void plugin_input_cb(Fl_Widget *w, void *data) +{ + const char* (*f)(int, int, const char*) = (const char* (*)(int, int, const char*)) data; + Fl_Input *input = (Fl_Input*) w; + f(-1, 0, input->value()); +} + +static void plugin_browser_cb(Fl_Widget *w, void *data) +{ + // get selected plugin + GMSH_Plugin *p = 0; + for(int i = 1; i <= GUI::instance()->plugins->browser->size(); i++) { + if(GUI::instance()->plugins->browser->selected(i)) { + p = (GMSH_Plugin*)GUI::instance()->plugins->browser->data(i); + break; + } + } + if(!p) return; + + // get first first selected view + int iView = -1; + for(int i = 1; i <= GUI::instance()->plugins->view_browser->size(); i++) { + if(GUI::instance()->plugins->view_browser->selected(i)) { + iView = i - 1; + break; + } + } + + // set the Fl_Value_Input callbacks and configure the input value + // fields (we get step, min and max by calling the option function + // with action==1, 2 and 3, respectively) + 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(plugin_input_value_cb, (void*)sxn->function); + if(iView >= 0){ + 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(plugin_input_cb, (void*)sxs->function); + } + } + + // hide all plugin groups except the selected one + for(int i = 1; i <= GUI::instance()->plugins->browser->size(); i++) + ((GMSH_Plugin*)GUI::instance()->plugins->browser->data(i))->dialogBox->group->hide(); + p->dialogBox->group->show(); +} + +static void plugin_run_cb(Fl_Widget *w, void *data) +{ + // get selected plugin + GMSH_Post_Plugin *p = 0; + for(int i = 1; i <= GUI::instance()->plugins->browser->size(); i++) { + if(GUI::instance()->plugins->browser->selected(i)) { + p = (GMSH_Post_Plugin*)GUI::instance()->plugins->browser->data(i); + break; + } + } + if(!p) return; + + if(p->dialogBox) { // get the values from the GUI + 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 = p->dialogBox->input[i]->value(); + } + for(int i = 0; i < n; i++) { + StringXNumber *sxn = p->getOption(i); + sxn->def = p->dialogBox->value[i]->value(); + } + } + + // run on all selected views + bool no_view_selected = true; + for(int i = 1; i <= GUI::instance()->plugins->view_browser->size(); i++) { + if(GUI::instance()->plugins->view_browser->selected(i)) { + no_view_selected = false; + try{ + if(i - 1 >= 0 && i - 1 < (int)PView::list.size()) + p->execute(PView::list[i - 1]); + else + p->execute(0); + } + catch(GMSH_Plugin * err) { + char tmp[256]; + p->catchErrorMessage(tmp); + Msg::Warning("%s", tmp); + } + } + } + if(no_view_selected){ + p->execute(0); + } + + GUI::instance()->updateViews(); + CTX.post.plugin_draw_function = NULL; + Draw(); +} + +static void plugin_cancel_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->plugins->win->hide(); + CTX.post.plugin_draw_function = NULL; + Draw(); +} + pluginWindow::pluginWindow(int fontsize) : _fontsize(fontsize) { int width0 = 34 * _fontsize + WB; @@ -32,21 +166,21 @@ pluginWindow::pluginWindow(int fontsize) : _fontsize(fontsize) { Fl_Button *o = new Fl_Button (width - BB - WB, height - BH - WB, BB, BH, "Cancel"); - o->callback(view_plugin_cancel_cb); + o->callback(plugin_cancel_cb); } { run = new Fl_Return_Button (width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Run"); - run->callback(view_plugin_run_cb); + run->callback(plugin_run_cb); } int L1 = (int)(0.3 * width), L2 = (int)(0.6 * L1); browser = new Fl_Hold_Browser(WB, WB, L1, height - 3 * WB - BH); - browser->callback(view_plugin_browser_cb); + browser->callback(plugin_browser_cb); view_browser = new Fl_Multi_Browser(WB + L1, WB, L2, height - 3 * WB - BH); view_browser->has_scrollbar(Fl_Browser_::VERTICAL); - view_browser->callback(view_plugin_browser_cb); + view_browser->callback(plugin_browser_cb); for(GMSH_PluginManager::iter it = GMSH_PluginManager::instance()->begin(); it != GMSH_PluginManager::instance()->end(); ++it) { @@ -79,7 +213,7 @@ void pluginWindow::show(int viewIndex) if(viewIndex >= 0 && viewIndex < (int)PView::list.size()){ view_browser->deselect(); view_browser->select(viewIndex + 1); - view_plugin_browser_cb(NULL, NULL); + plugin_browser_cb(NULL, NULL); } win->show(); } @@ -183,5 +317,5 @@ void pluginWindow::resetViewBrowser() view_browser->deactivate(); } - view_plugin_browser_cb(NULL, NULL); + plugin_browser_cb(NULL, NULL); } diff --git a/Fltk/pluginWindow.h b/Fltk/pluginWindow.h index 697a4eae10..3f06646628 100644 --- a/Fltk/pluginWindow.h +++ b/Fltk/pluginWindow.h @@ -38,4 +38,6 @@ class pluginWindow{ void resetViewBrowser(); }; +void plugin_cb(Fl_Widget *w, void *data); + #endif diff --git a/Fltk/projectionEditor.cpp b/Fltk/projectionEditor.cpp index 55f1ea5c10..5067b8e204 100644 --- a/Fltk/projectionEditor.cpp +++ b/Fltk/projectionEditor.cpp @@ -62,439 +62,128 @@ static fourierProjectionFace *createProjectionFaceFromName(const char *name) return f; } -uvPlot::uvPlot(int x, int y, int w, int h, const char *l) - : Fl_Window(x, y, w, h, l), _dmin(0.), _dmax(0.) -{ - ColorTable_InitParam(2, &_colorTable); - ColorTable_Recompute(&_colorTable); -} - -void uvPlot::set(std::vector<double> &u, std::vector<double> &v, - std::vector<double> &dist, std::vector<std::complex<double> > &f) -{ - _u = u; - _v = v; - _dist = dist; - _f = f; - if(dist.empty()){ - _dmin = _dmax = 0.; - } - else{ - _dmin = _dmax = dist[0]; - for(unsigned int i = 1; i < dist.size(); i++){ - _dmin = std::min(_dmin, dist[i]); - _dmax = std::max(_dmax, dist[i]); - } +static void project_point(FM::ProjectionSurface *ps, double x, double y, double z, + std::vector<double> &u, std::vector<double> &v, + std::vector<double> &dist, + std::vector<std::complex<double> > &f) +{ + double uu, vv, p[3], n[3]; + ps->OrthoProjectionOnSurface(x, y, z, uu, vv); + if(uu >= 0. && uu <= 1. && vv >= 0. && vv <= 1.){ + ps->F(uu, vv, p[0], p[1], p[2]); + ps->GetUnitNormal(uu, vv, n[0], n[1], n[2]); + double dx = x - p[0], dy = y - p[1], dz = z - p[2]; + u.push_back(uu); + v.push_back(vv); + dist.push_back(sqrt(dx * dx + dy * dy + dz * dz)); + f.push_back(dx * n[0] + dy * n[1] + dz * n[2]); } - redraw(); } -void uvPlot::color(double d) +static void getTangents(const SVector3 n, SVector3 &t1, SVector3 &t2, const double angle) { - int index; - if(_dmin == _dmax) - index = _colorTable.size / 2; + SVector3 ex(0., 0., 0.); + if(n[0] == 0.) + ex[0] = 1.; + else if(n[1] == 0.) + ex[1] = 1.; else - index = (int)((d - _dmin) * (_colorTable.size - 1) / (_dmax - _dmin)); - unsigned int color = _colorTable.table[index]; - int r = CTX.UNPACK_RED(color); - int g = CTX.UNPACK_GREEN(color); - int b = CTX.UNPACK_BLUE(color); - fl_color(r, g, b); + ex[2] = 1.; + SVector3 a = crossprod(n, ex); + a.normalize(); + SVector3 b = crossprod(n, a); + b.normalize(); + double x = n[0], y = n[1], z = n[2]; + double c = cos(angle * M_PI / 180.), s = sin(angle * M_PI / 180.); + double rot[3][3] = + {{x * x * (1-c) + c , x * y * (1-c) - z * s, x * z * (1-c) + y * s}, + {y * x * (1-c) + z * s, y * y * (1-c) + c , y * z * (1-c) - x * s}, + {x * z * (1-c) - y * s, y * z * (1-c) + x * s, z * z * (1-c) + c }}; + for(int i = 0; i < 3; i++){ + t1[i] = t2[i] = 0.; + for(int j = 0; j < 3; j++){ + t1[i] += rot[i][j] * a[j]; + t2[i] += rot[i][j] * b[j]; + } + } } -void uvPlot::draw() +static void update_cb(Fl_Widget *w, void *data) { - // draw background - fl_color(FL_WHITE); - fl_rectf(0, 0, w(), h()); + projectionEditor *e = (projectionEditor*)data; - // draw points in u,v space, colored by their distance to the - // projection surface - int pw = w(); - int ph = h() - (2 * GetFontSize() + 5); - for(unsigned int i = 0; i < _u.size(); i++){ - int x = (int)(_u[i] * pw); - int y = (int)(_v[i] * ph); - color(_dist[i]); - fl_rect(x, y, 3, 3); - } + // get all parameters from GUI and modify projection surface accordingly - // draw color bar - for(int i = 0; i < w(); i++){ - int index = (int)(i * (_colorTable.size - 1) / w()); - unsigned int color = _colorTable.table[index]; - int r = CTX.UNPACK_RED(color); - int g = CTX.UNPACK_GREEN(color); - int b = CTX.UNPACK_BLUE(color); - fl_color(r, g, b); - fl_line(i, ph, i, ph + 10); + projection *p = e->getCurrentProjection(); + if(p){ + FM::ProjectionSurface *ps = (FM::ProjectionSurface*)p->face->getNativePtr(); + ps->SetOrigin(p->parameters[0]->value(), + p->parameters[1]->value(), + p->parameters[2]->value()); + SVector3 n(p->parameters[3]->value(), + p->parameters[4]->value(), + p->parameters[5]->value()); + if(!n.normalize()) n[2] = 1.; + SVector3 t1, t2; + getTangents(n, t1, t2, p->parameters[6]->value()); + ps->SetE0(n[0], n[1], n[2]); + ps->SetE1(t1[0], t1[1], t1[2]); + ps->SetE2(t2[0], t2[1], t2[2]); + ps->SetScale(p->parameters[7]->value(), + p->parameters[8]->value(), + p->parameters[9]->value()); + for (int i = 0; i < ps->GetNumParameters(); i++) + ps->SetParameter(i, p->parameters[i + 10]->value()); + + p->face->buildSTLTriangulation(); + + // project selected points and elements and update u,v display + std::vector<double> u, v, dist; + std::vector<std::complex<double> > f; + std::vector<GEntity*> &ent(e->getEntities()); + for(unsigned int i = 0; i < ent.size(); i++){ + if(ent[i]->getSelection()){ + GVertex *gv = dynamic_cast<GVertex*>(ent[i]); + if(!gv) + Msg::Error("Problem in point selection processing"); + else + project_point(ps, gv->x(), gv->y(), gv->z(), u, v, dist, f); + } + } + std::vector<MElement*> &ele(e->getElements()); + std::set<MVertex*> verts; + for(unsigned int i = 0; i < ele.size(); i++) + if(ele[i]->getVisibility() == 2) + for(int j = 0; j < ele[i]->getNumVertices(); j++) + verts.insert(ele[i]->getVertex(j)); + for(std::set<MVertex*>::iterator it = verts.begin(); it != verts.end(); it++) + project_point(ps, (*it)->x(), (*it)->y(), (*it)->z(), u, v, dist, f); + e->uv()->set(u, v, dist, f); } - // draw labels - fl_color(FL_BLACK); - fl_font(FL_HELVETICA, GetFontSize()); - static char min[256], max[256], pts[256]; - sprintf(min, "%g", _dmin); - sprintf(max, "%g", _dmax); - sprintf(pts, "[%d pts]", (int)_u.size()); - fl_draw(min, 5, h() - 5); - fl_draw(pts, pw / 2 - (int)fl_width(pts) / 2, h() - 5); - fl_draw(max, pw - (int)fl_width(max) - 5, h() - 5); + Draw(); } -projection::projection(fourierProjectionFace *f, int x, int y, int w, int h, - int bb, int bh, projectionEditor *e) - : face(f) +static void browse_cb(Fl_Widget *w, void *data) { - group = new Fl_Scroll(x, y, w, h); - SBoundingBox3d bounds = GModel::current()->bounds(); - FM::ProjectionSurface *ps = (FM::ProjectionSurface*)f->getNativePtr(); - - Fl_Toggle_Button *b = new Fl_Toggle_Button(x, y, bb, bh, "Set position"); - b->callback(set_position_cb, e); - - { // origin is stored in parameters[0,1,2] - SPoint3 pc = bounds.center(); - for(int i = 0; i < 3; i++){ - Fl_Value_Input *v = new Fl_Value_Input(x, y + (1 + i) * bh, bb, bh); - parameters.push_back(v); - v->maximum(bounds.max()[i] + 10. * CTX.lc); - v->minimum(bounds.min()[i] - 10. * CTX.lc); - v->step(CTX.lc / 100.); - v->value(pc[i]); - v->label((i == 0) ? "X" : (i == 1) ? "Y" : "Z"); - } - ps->SetOrigin(pc[0], pc[1], pc[2]); - Fl_Repeat_Button *bm[3], *bp[3]; - for(int i = 0; i < 3; i++){ - new Fl_Box(x + w - bb / 3 - bb / 6, y + (1 + i) * bh, bb / 8, bh, - (i == 0) ? "E0" : (i == 1) ? "E1" : "E2"); - bp[i] = new Fl_Repeat_Button(x + w - bb / 3, y + (1 + i) * bh, - bb / 8, bh / 2, "+"); - bm[i] = new Fl_Repeat_Button(x + w - bb / 3, y + (1 + i) * bh + bh / 2, - bb / 8, bh / 2, "-"); - } - bp[0]->callback(translate_p0_cb, e); - bp[1]->callback(translate_p1_cb, e); - bp[2]->callback(translate_p2_cb, e); - bm[0]->callback(translate_m0_cb, e); - bm[1]->callback(translate_m1_cb, e); - bm[2]->callback(translate_m2_cb, e); - } - { // normal is stored in parameters[3,4,5] - Fl_Value_Input *v1 = new Fl_Value_Input(x, y + 4 * bh, bb / 3, bh); - parameters.push_back(v1); - v1->maximum(1.); v1->minimum(-1.); v1->step(0.01); v1->value(0.); - Fl_Value_Input *v2 = new Fl_Value_Input(x + bb / 3, y + 4 * bh, bb / 3, bh); - parameters.push_back(v2); - v2->maximum(1.); v2->minimum(-1.); v2->step(0.01); v2->value(0.); - Fl_Value_Input *v3 = new Fl_Value_Input(x + 2 * bb / 3, y + 4 * bh, bb - 2 * bb / 3, bh); - parameters.push_back(v3); - v3->maximum(1.); v3->minimum(-1.); v3->step(0.01); v3->value(1.); - v3->label("Normal"); - Fl_Button *b = new Fl_Button(x + w - bb / 3, y + 4 * bh + bh / 4, bb / 8, bh / 2, "-"); - b->callback(invert_normal_cb, e); - b->tooltip("Invert normal"); - } - { // rotation is stored in parameters[6] - Fl_Value_Input *v = new Fl_Value_Input(x, y + 5 * bh, bb, bh, "Rotation"); - v->maximum(-180.); - v->minimum(180.); - v->step(0.1); - v->value(0.); - parameters.push_back(v); - } - { // scale is stored in parameters[7,8,9] - for(int i = 0; i < 3; i++){ - Fl_Value_Input *v = new Fl_Value_Input(x, y + (6 + i) * bh, bb, bh); - parameters.push_back(v); - v->maximum(CTX.lc * 10.); - v->minimum(CTX.lc / 100.); - v->step(CTX.lc / 100.); - v->value(CTX.lc / 10.); - v->label((i == 0) ? "Scale0" : (i == 1) ? "Scale1" : "Scale2"); - } - } + projectionEditor *e = (projectionEditor*)data; - // other parameters are stored in parameters[10,...] - for(int i = 0; i < ps->GetNumParameters(); i++){ - Fl_Value_Input *v = new Fl_Value_Input(x, y + (9 + i) * bh, bb, bh); - v->maximum(10. * CTX.lc); - v->minimum(-10. * CTX.lc); - v->step(CTX.lc / 100.); - v->label(strdup(ps->GetLabel(i).c_str())); - v->value(ps->GetParameter(i)); - parameters.push_back(v); + std::vector<projection*> &projections(e->getProjections()); + for(unsigned int i = 0; i < projections.size(); i++){ + projections[i]->face->setVisibility(false); + projections[i]->group->hide(); } - - for(unsigned int i = 0; i < parameters.size(); i++){ - parameters[i]->align(FL_ALIGN_RIGHT); - parameters[i]->callback(update_cb, e); + + projection *p = e->getCurrentProjection(); + if(p){ + p->face->setVisibility(true); + p->group->show(); } - group->end(); - group->hide(); + update_cb(0, data); } -projectionEditor::projectionEditor() -{ - GModel *m = GModel::current(); - - // construct FM_Internals - m->readFourier(); - printf("readerSize = %d\n",m->getFMInternals()->getSize()); - printf("currentSize = %d\n",m->getFMInternals()->current()->GetNumGroups()); - - // construct GUI in terms of standard sizes - int _fontsize = GetFontSize(); - const int width = (int)(3.75 * BB), height = 25 * BH; - - // create all widgets (we construct this once, we never deallocate!) - _window = new dialogWindow(width, height, CTX.non_modal_windows, "Reparameterize"); - - new Fl_Box(WB, WB + BH / 2, BB / 2, BH, "Select:"); - - Fl_Group *o = new Fl_Group(WB, WB, 2 * BB, 3 * BH); - _select[0] = new Fl_Round_Button(2 * WB + BB / 2, WB, BB, BH, "Points"); - _select[1] = new Fl_Round_Button(2 * WB + BB / 2, WB + BH, BB, BH, "Elements"); - if(m->getNumMeshElements()) - _select[1]->value(1); - else - _select[0]->value(1); - for(int i = 0; i < 2; i++){ - _select[i]->callback(select_cb, this); - _select[i]->type(FL_RADIO_BUTTON); - } - o->end(); - - { - Fl_Toggle_Button *b1 = new Fl_Toggle_Button - (width - WB - 3 * BB / 2, WB, 3 * BB / 2, BH, "Hide unselected"); - b1->callback(hide_cb); - Fl_Button *b2 = new Fl_Button - (width - WB - 3 * BB / 2, WB + BH, 3 * BB / 2, BH, "Save selection"); - b2->callback(save_selection_cb, this); - } - - const int brw = (int)(1.3 * BB); - - _browser = new Fl_Hold_Browser(WB, 2 * WB + 2 * BH, brw, 6 * BH); - _browser->callback(browse_cb, this); - - _paramWin[0] = 2 * WB + brw; - _paramWin[1] = 2 * WB + 2 * BH; - _paramWin[2] = width - 3 * WB - brw; - _paramWin[3] = 7 * BH; - _paramWin[4] = (int)(1.25 * BB); - _paramWin[5] = BH; - - { - Fl_Button *b1 = new Fl_Button(WB, 2 * WB + 8 * BH, brw / 2, BH, "Load"); - b1->callback(load_projection_cb, this); - Fl_Button *b2 = new Fl_Button(WB + brw / 2, 2 * WB + 8 * BH, brw / 2, BH, "Save"); - b2->callback(save_projection_cb, this); - } - - int hard = 8; - int uvw = width - 2 * WB - 2 * hard - 3 * WB; - int uvh = height - 8 * WB - 15 * BH - 2 * hard; - - _hardEdges[0] = new Fl_Toggle_Button(WB, 3 * WB + 9 * BH + hard, - hard, uvh); - _hardEdges[1] = new Fl_Toggle_Button(width - 4 * WB - hard, 3 * WB + 9 * BH + hard, - hard, uvh); - _hardEdges[2] = new Fl_Toggle_Button(WB + hard, 3 * WB + 9 * BH, - uvw, hard); - _hardEdges[3] = new Fl_Toggle_Button(WB + hard, height - 5 * WB - 6 * BH - hard, - uvw, hard); - for(int i = 0; i < 4; i++) - _hardEdges[i]->tooltip("Push to mark edge as `hard'"); - - _uvPlot = new uvPlot(WB + hard, 3 * WB + 9 * BH + hard, uvw, uvh); - _uvPlot->end(); - - _slider = new Fl_Slider(width - 3 * WB, 3 * WB + 9 * BH + hard, 2 * WB, uvh); - _slider->minimum(1.); - _slider->maximum(0.); - _slider->value(1.); - _slider->callback(filter_cb, this); - _slider->tooltip("Filter selection by distance to projection surface"); - - _orientation = new Fl_Toggle_Button(width - 3 * WB, height - 5 * WB - 6 * BH - hard, - 2 * WB, hard); - _orientation->callback(filter_cb, this); - _orientation->tooltip("Filter elements using orientation"); - - new Fl_Box(WB, height - 4 * WB - 6 * BH, BB, BH, "Patch Type:"); - Fl_Group *oo = new Fl_Group( WB, height - 4 * WB - 6 * BH, 3 * BB, BH); - _pselect[0] = new Fl_Round_Button(2 * WB + BB, height - 4 * WB - 6 * BH, - BB, BH, "Continuation"); - _pselect[1] = new Fl_Round_Button(3 * WB + 2 * BB, height - 4 * WB - - 6 * BH, BB, BH, "Windowing"); - - for(int i = 0; i < 2; i++) - _pselect[i]->type(FL_RADIO_BUTTON); - - _pselect[0]->value(1); - - oo->end(); - - _modes[0] = new Fl_Value_Input(WB, height - 4 * WB - 5 * BH, BB / 2, BH); - _modes[0]->tooltip("Number of Fourier modes along u"); - _modes[1] = new Fl_Value_Input(WB + BB / 2, height - 4 * WB - 5 * BH, BB / 2, BH, - "Fourier modes"); - _modes[1]->tooltip("Number of Fourier modes along v"); - _modes[2] = new Fl_Value_Input(WB, height - 4 * WB - 4 * BH, BB / 2, BH); - _modes[2]->tooltip("Number of Chebyshev modes along u"); - _modes[3] = new Fl_Value_Input(WB + BB / 2, height - 4 * WB - 4 * BH, BB / 2, BH, - "Chebyshev modes"); - _modes[3]->tooltip("Number of Chebyshev modes along v"); - for(int i = 0; i < 4; i++){ - _modes[i]->value(8); - _modes[i]->maximum(128); - _modes[i]->minimum(1); - _modes[i]->step(1); - _modes[i]->align(FL_ALIGN_RIGHT); - } - - { - Fl_Button *b = new Fl_Button(width - WB - BB, height - 4 * WB - 5 * BH, - BB, 2 * BH, "Generate\nPatch"); - b->callback(compute_cb, this); - } - - { - int bb = (int)(0.37 * BB); - new Fl_Box(WB, height - 3 * WB - 3 * BH, BB / 2, BH, "Delete:"); - Fl_Button *b1 = new Fl_Button(WB + BB / 2, height - 3 * WB - 3 * BH, - bb, BH, "last"); - b1->callback(action_cb, (void*)"delete_last"); - Fl_Button *b2 = new Fl_Button(WB + BB / 2 + bb, height - 3 * WB - 3 * BH, - bb, BH, "all"); - b2->callback(action_cb, (void*)"delete_all"); - Fl_Button *b3 = new Fl_Button(WB + BB / 2 + 2 * bb, height - 3 * WB - 3 * BH, - bb, BH, "sel."); - b3->callback(action_cb, (void*)"delete_select"); - } - - { - int bb = (int)(0.37 * BB); - int s = width - WB - BB / 2 - 3 * bb; - new Fl_Box(s, height - 3 * WB - 3 * BH, BB / 2, BH, "Save:"); - Fl_Button *b1 = new Fl_Button(s + BB / 2, height - 3 * WB - 3 * BH, - bb, BH, "last"); - b1->callback(action_cb, (void*)"save_last"); - Fl_Button *b2 = new Fl_Button(s + BB / 2 + bb, height - 3 * WB - 3 * BH, - bb, BH, "all"); - b2->callback(action_cb, (void*)"save_all"); - Fl_Button *b3 = new Fl_Button(s + BB / 2 + 2 * bb, height - 3 * WB - 3 * BH, - bb, BH, "sel."); - b3->callback(action_cb, (void*)"save_select"); - } - - { - Fl_Button *b1 = new Fl_Button(WB, height - 2 * WB - 2 * BH, BB, BH, - "Blend"); - b1->callback(blend_cb, this); - - Fl_Button *b2 = new Fl_Button(2 * WB + BB, height - 2 * WB - 2 * BH, BB, - BH, "Intersect"); - } - - Fl_Button *b = new Fl_Button(width - WB - BB, height - WB - BH, BB, BH, "Cancel"); - b->callback(close_cb, _window); - - _window->end(); - _window->hotspot(_window); - _window->resizable(_uvPlot); - _window->size_range(width, (int)(0.85 * height)); - - // create -} - -void projectionEditor::load(fourierProjectionFace *face, std::string tag) -{ - FM::ProjectionSurface *ps = (FM::ProjectionSurface*)face->getNativePtr(); - _browser->add(tag.size() ? tag.c_str() : ps->GetName().c_str()); - projection *p = new projection(face, _paramWin[0], _paramWin[1], _paramWin[2], - _paramWin[3], _paramWin[4], _paramWin[5], this); - _projections.push_back(p); - _window->add(p->group); -} - -void projectionEditor::show() -{ - _window->show(); - select_cb(0, this); -} - -int projectionEditor::getSelectionMode() -{ - if(_select[0]->value()) - return ENT_POINT; - else - return ENT_ALL; -} - -int projectionEditor::getPatchType() -{ - if (_pselect[0]->value()) - return 0; - else - return 1; -} - -projection *projectionEditor::getCurrentProjection() -{ - for(int i = 1; i <= _browser->size(); i++) - if(_browser->selected(i)) return _projections[i - 1]; - return 0; -} - -projection *projectionEditor::getLastProjection() -{ - return _projections[_projections.size() - 1]; -} - -void browse_cb(Fl_Widget *w, void *data) -{ - projectionEditor *e = (projectionEditor*)data; - - std::vector<projection*> &projections(e->getProjections()); - for(unsigned int i = 0; i < projections.size(); i++){ - projections[i]->face->setVisibility(false); - projections[i]->group->hide(); - } - - projection *p = e->getCurrentProjection(); - if(p){ - p->face->setVisibility(true); - p->group->show(); - } - - update_cb(0, data); -} - -void project_point(FM::ProjectionSurface *ps, double x, double y, double z, - std::vector<double> &u, std::vector<double> &v, - std::vector<double> &dist, - std::vector<std::complex<double> > &f) -{ - double uu, vv, p[3], n[3]; - ps->OrthoProjectionOnSurface(x, y, z, uu, vv); - if(uu >= 0. && uu <= 1. && vv >= 0. && vv <= 1.){ - ps->F(uu, vv, p[0], p[1], p[2]); - ps->GetUnitNormal(uu, vv, n[0], n[1], n[2]); - double dx = x - p[0], dy = y - p[1], dz = z - p[2]; - u.push_back(uu); - v.push_back(vv); - dist.push_back(sqrt(dx * dx + dy * dy + dz * dz)); - f.push_back(dx * n[0] + dy * n[1] + dz * n[2]); - } -} - -void invert_normal_cb(Fl_Widget *w, void *data) +static void invert_normal_cb(Fl_Widget *w, void *data) { projectionEditor *e = (projectionEditor*)data; projection *p = e->getCurrentProjection(); @@ -506,7 +195,7 @@ void invert_normal_cb(Fl_Widget *w, void *data) } } -void translate(void *data, int axis, bool plus) +static void translate(void *data, int axis, bool plus) { projectionEditor *e = (projectionEditor*)data; projection *p = e->getCurrentProjection(); @@ -533,14 +222,14 @@ void translate(void *data, int axis, bool plus) } } -void translate_p0_cb(Fl_Widget *w, void *data){ translate(data, 0, true); } -void translate_p1_cb(Fl_Widget *w, void *data){ translate(data, 1, true); } -void translate_p2_cb(Fl_Widget *w, void *data){ translate(data, 2, true); } -void translate_m0_cb(Fl_Widget *w, void *data){ translate(data, 0, false); } -void translate_m1_cb(Fl_Widget *w, void *data){ translate(data, 1, false); } -void translate_m2_cb(Fl_Widget *w, void *data){ translate(data, 2, false); } +static void translate_p0_cb(Fl_Widget *w, void *data){ translate(data, 0, true); } +static void translate_p1_cb(Fl_Widget *w, void *data){ translate(data, 1, true); } +static void translate_p2_cb(Fl_Widget *w, void *data){ translate(data, 2, true); } +static void translate_m0_cb(Fl_Widget *w, void *data){ translate(data, 0, false); } +static void translate_m1_cb(Fl_Widget *w, void *data){ translate(data, 1, false); } +static void translate_m2_cb(Fl_Widget *w, void *data){ translate(data, 2, false); } -void set_position_cb(Fl_Widget *w, void *data) +static void set_position_cb(Fl_Widget *w, void *data) { projectionEditor *e = (projectionEditor*)data; projection *p = e->getCurrentProjection(); @@ -576,91 +265,7 @@ void set_position_cb(Fl_Widget *w, void *data) } } -void getTangents(const SVector3 n, SVector3 &t1, SVector3 &t2, const double angle) -{ - SVector3 ex(0., 0., 0.); - if(n[0] == 0.) - ex[0] = 1.; - else if(n[1] == 0.) - ex[1] = 1.; - else - ex[2] = 1.; - SVector3 a = crossprod(n, ex); - a.normalize(); - SVector3 b = crossprod(n, a); - b.normalize(); - double x = n[0], y = n[1], z = n[2]; - double c = cos(angle * M_PI / 180.), s = sin(angle * M_PI / 180.); - double rot[3][3] = - {{x * x * (1-c) + c , x * y * (1-c) - z * s, x * z * (1-c) + y * s}, - {y * x * (1-c) + z * s, y * y * (1-c) + c , y * z * (1-c) - x * s}, - {x * z * (1-c) - y * s, y * z * (1-c) + x * s, z * z * (1-c) + c }}; - for(int i = 0; i < 3; i++){ - t1[i] = t2[i] = 0.; - for(int j = 0; j < 3; j++){ - t1[i] += rot[i][j] * a[j]; - t2[i] += rot[i][j] * b[j]; - } - } -} - -void update_cb(Fl_Widget *w, void *data) -{ - projectionEditor *e = (projectionEditor*)data; - - // get all parameters from GUI and modify projection surface accordingly - - projection *p = e->getCurrentProjection(); - if(p){ - FM::ProjectionSurface *ps = (FM::ProjectionSurface*)p->face->getNativePtr(); - ps->SetOrigin(p->parameters[0]->value(), - p->parameters[1]->value(), - p->parameters[2]->value()); - SVector3 n(p->parameters[3]->value(), - p->parameters[4]->value(), - p->parameters[5]->value()); - if(!n.normalize()) n[2] = 1.; - SVector3 t1, t2; - getTangents(n, t1, t2, p->parameters[6]->value()); - ps->SetE0(n[0], n[1], n[2]); - ps->SetE1(t1[0], t1[1], t1[2]); - ps->SetE2(t2[0], t2[1], t2[2]); - ps->SetScale(p->parameters[7]->value(), - p->parameters[8]->value(), - p->parameters[9]->value()); - for (int i = 0; i < ps->GetNumParameters(); i++) - ps->SetParameter(i, p->parameters[i + 10]->value()); - - p->face->buildSTLTriangulation(); - - // project selected points and elements and update u,v display - std::vector<double> u, v, dist; - std::vector<std::complex<double> > f; - std::vector<GEntity*> &ent(e->getEntities()); - for(unsigned int i = 0; i < ent.size(); i++){ - if(ent[i]->getSelection()){ - GVertex *gv = dynamic_cast<GVertex*>(ent[i]); - if(!gv) - Msg::Error("Problem in point selection processing"); - else - project_point(ps, gv->x(), gv->y(), gv->z(), u, v, dist, f); - } - } - std::vector<MElement*> &ele(e->getElements()); - std::set<MVertex*> verts; - for(unsigned int i = 0; i < ele.size(); i++) - if(ele[i]->getVisibility() == 2) - for(int j = 0; j < ele[i]->getNumVertices(); j++) - verts.insert(ele[i]->getVertex(j)); - for(std::set<MVertex*>::iterator it = verts.begin(); it != verts.end(); it++) - project_point(ps, (*it)->x(), (*it)->y(), (*it)->z(), u, v, dist, f); - e->uv()->set(u, v, dist, f); - } - - Draw(); -} - -void select_cb(Fl_Widget *w, void *data) +static void select_cb(Fl_Widget *w, void *data) { projectionEditor *e = (projectionEditor*)data; @@ -760,7 +365,7 @@ void select_cb(Fl_Widget *w, void *data) Msg::StatusBar(3, false, ""); } -void filter_cb(Fl_Widget *w, void *data) +static void filter_cb(Fl_Widget *w, void *data) { projectionEditor *e = (projectionEditor*)data; projection *p = e->getCurrentProjection(); @@ -811,19 +416,19 @@ void filter_cb(Fl_Widget *w, void *data) update_cb(0, data); } -void close_cb(Fl_Widget *w, void *data) +static void close_cb(Fl_Widget *w, void *data) { if(data) ((Fl_Window *) data)->hide(); } -void hide_cb(Fl_Widget *w, void *data) +static void proj_hide_cb(Fl_Widget *w, void *data) { CTX.hide_unselected = !CTX.hide_unselected; CTX.mesh.changed = ENT_ALL; Draw(); } -void save_selection_cb(Fl_Widget *w, void *data) +static void save_selection_cb(Fl_Widget *w, void *data) { projectionEditor *e = (projectionEditor*)data; if(file_chooser(0, 1, "Save Selection", "*.{geo,msh}")){ @@ -863,7 +468,7 @@ void save_selection_cb(Fl_Widget *w, void *data) } } -void load_projection_cb(Fl_Widget *w, void *data) +static void load_projection_cb(Fl_Widget *w, void *data) { projectionEditor *e = (projectionEditor*)data; if(file_chooser(0, 0, "Load Projection", "*.pro")){ @@ -904,7 +509,7 @@ void load_projection_cb(Fl_Widget *w, void *data) } } -void save_projection_cb(Fl_Widget *w, void *data) +static void save_projection_cb(Fl_Widget *w, void *data) { projectionEditor *e = (projectionEditor*)data; projection *p = e->getCurrentProjection(); @@ -927,7 +532,7 @@ void save_projection_cb(Fl_Widget *w, void *data) } } -void compute_cb(Fl_Widget *w, void *data) +static void compute_cb(Fl_Widget *w, void *data) { GModel* m = GModel::current(); @@ -1026,7 +631,7 @@ void compute_cb(Fl_Widget *w, void *data) Draw(); } -void delete_fourier(GFace *gf) +static void delete_fourier(GFace *gf) { if(gf->getNativeType() != GEntity::FourierModel) return; @@ -1044,7 +649,7 @@ void delete_fourier(GFace *gf) m->remove(gf); } -void blend_cb(Fl_Widget *w, void *data) +static void blend_cb(Fl_Widget *w, void *data) { GModel *m = GModel::current(); @@ -1065,7 +670,7 @@ void blend_cb(Fl_Widget *w, void *data) } } -void action_cb(Fl_Widget *w, void *data) +static void action_cb(Fl_Widget *w, void *data) { std::string what((char*)data); std::vector<GFace*> faces; @@ -1119,6 +724,401 @@ void action_cb(Fl_Widget *w, void *data) Draw(); } +uvPlot::uvPlot(int x, int y, int w, int h, const char *l) + : Fl_Window(x, y, w, h, l), _dmin(0.), _dmax(0.) +{ + ColorTable_InitParam(2, &_colorTable); + ColorTable_Recompute(&_colorTable); +} + +void uvPlot::set(std::vector<double> &u, std::vector<double> &v, + std::vector<double> &dist, std::vector<std::complex<double> > &f) +{ + _u = u; + _v = v; + _dist = dist; + _f = f; + if(dist.empty()){ + _dmin = _dmax = 0.; + } + else{ + _dmin = _dmax = dist[0]; + for(unsigned int i = 1; i < dist.size(); i++){ + _dmin = std::min(_dmin, dist[i]); + _dmax = std::max(_dmax, dist[i]); + } + } + redraw(); +} + +void uvPlot::color(double d) +{ + int index; + if(_dmin == _dmax) + index = _colorTable.size / 2; + else + index = (int)((d - _dmin) * (_colorTable.size - 1) / (_dmax - _dmin)); + unsigned int color = _colorTable.table[index]; + int r = CTX.UNPACK_RED(color); + int g = CTX.UNPACK_GREEN(color); + int b = CTX.UNPACK_BLUE(color); + fl_color(r, g, b); +} + +void uvPlot::draw() +{ + // draw background + fl_color(FL_WHITE); + fl_rectf(0, 0, w(), h()); + + // draw points in u,v space, colored by their distance to the + // projection surface + int pw = w(); + int ph = h() - (2 * GetFontSize() + 5); + for(unsigned int i = 0; i < _u.size(); i++){ + int x = (int)(_u[i] * pw); + int y = (int)(_v[i] * ph); + color(_dist[i]); + fl_rect(x, y, 3, 3); + } + + // draw color bar + for(int i = 0; i < w(); i++){ + int index = (int)(i * (_colorTable.size - 1) / w()); + unsigned int color = _colorTable.table[index]; + int r = CTX.UNPACK_RED(color); + int g = CTX.UNPACK_GREEN(color); + int b = CTX.UNPACK_BLUE(color); + fl_color(r, g, b); + fl_line(i, ph, i, ph + 10); + } + + // draw labels + fl_color(FL_BLACK); + fl_font(FL_HELVETICA, GetFontSize()); + static char min[256], max[256], pts[256]; + sprintf(min, "%g", _dmin); + sprintf(max, "%g", _dmax); + sprintf(pts, "[%d pts]", (int)_u.size()); + fl_draw(min, 5, h() - 5); + fl_draw(pts, pw / 2 - (int)fl_width(pts) / 2, h() - 5); + fl_draw(max, pw - (int)fl_width(max) - 5, h() - 5); +} + +projection::projection(fourierProjectionFace *f, int x, int y, int w, int h, + int bb, int bh, projectionEditor *e) + : face(f) +{ + group = new Fl_Scroll(x, y, w, h); + SBoundingBox3d bounds = GModel::current()->bounds(); + FM::ProjectionSurface *ps = (FM::ProjectionSurface*)f->getNativePtr(); + + Fl_Toggle_Button *b = new Fl_Toggle_Button(x, y, bb, bh, "Set position"); + b->callback(set_position_cb, e); + + { // origin is stored in parameters[0,1,2] + SPoint3 pc = bounds.center(); + for(int i = 0; i < 3; i++){ + Fl_Value_Input *v = new Fl_Value_Input(x, y + (1 + i) * bh, bb, bh); + parameters.push_back(v); + v->maximum(bounds.max()[i] + 10. * CTX.lc); + v->minimum(bounds.min()[i] - 10. * CTX.lc); + v->step(CTX.lc / 100.); + v->value(pc[i]); + v->label((i == 0) ? "X" : (i == 1) ? "Y" : "Z"); + } + ps->SetOrigin(pc[0], pc[1], pc[2]); + Fl_Repeat_Button *bm[3], *bp[3]; + for(int i = 0; i < 3; i++){ + new Fl_Box(x + w - bb / 3 - bb / 6, y + (1 + i) * bh, bb / 8, bh, + (i == 0) ? "E0" : (i == 1) ? "E1" : "E2"); + bp[i] = new Fl_Repeat_Button(x + w - bb / 3, y + (1 + i) * bh, + bb / 8, bh / 2, "+"); + bm[i] = new Fl_Repeat_Button(x + w - bb / 3, y + (1 + i) * bh + bh / 2, + bb / 8, bh / 2, "-"); + } + bp[0]->callback(translate_p0_cb, e); + bp[1]->callback(translate_p1_cb, e); + bp[2]->callback(translate_p2_cb, e); + bm[0]->callback(translate_m0_cb, e); + bm[1]->callback(translate_m1_cb, e); + bm[2]->callback(translate_m2_cb, e); + } + { // normal is stored in parameters[3,4,5] + Fl_Value_Input *v1 = new Fl_Value_Input(x, y + 4 * bh, bb / 3, bh); + parameters.push_back(v1); + v1->maximum(1.); v1->minimum(-1.); v1->step(0.01); v1->value(0.); + Fl_Value_Input *v2 = new Fl_Value_Input(x + bb / 3, y + 4 * bh, bb / 3, bh); + parameters.push_back(v2); + v2->maximum(1.); v2->minimum(-1.); v2->step(0.01); v2->value(0.); + Fl_Value_Input *v3 = new Fl_Value_Input(x + 2 * bb / 3, y + 4 * bh, bb - 2 * bb / 3, bh); + parameters.push_back(v3); + v3->maximum(1.); v3->minimum(-1.); v3->step(0.01); v3->value(1.); + v3->label("Normal"); + Fl_Button *b = new Fl_Button(x + w - bb / 3, y + 4 * bh + bh / 4, bb / 8, bh / 2, "-"); + b->callback(invert_normal_cb, e); + b->tooltip("Invert normal"); + } + { // rotation is stored in parameters[6] + Fl_Value_Input *v = new Fl_Value_Input(x, y + 5 * bh, bb, bh, "Rotation"); + v->maximum(-180.); + v->minimum(180.); + v->step(0.1); + v->value(0.); + parameters.push_back(v); + } + { // scale is stored in parameters[7,8,9] + for(int i = 0; i < 3; i++){ + Fl_Value_Input *v = new Fl_Value_Input(x, y + (6 + i) * bh, bb, bh); + parameters.push_back(v); + v->maximum(CTX.lc * 10.); + v->minimum(CTX.lc / 100.); + v->step(CTX.lc / 100.); + v->value(CTX.lc / 10.); + v->label((i == 0) ? "Scale0" : (i == 1) ? "Scale1" : "Scale2"); + } + } + + // other parameters are stored in parameters[10,...] + for(int i = 0; i < ps->GetNumParameters(); i++){ + Fl_Value_Input *v = new Fl_Value_Input(x, y + (9 + i) * bh, bb, bh); + v->maximum(10. * CTX.lc); + v->minimum(-10. * CTX.lc); + v->step(CTX.lc / 100.); + v->label(strdup(ps->GetLabel(i).c_str())); + v->value(ps->GetParameter(i)); + parameters.push_back(v); + } + + for(unsigned int i = 0; i < parameters.size(); i++){ + parameters[i]->align(FL_ALIGN_RIGHT); + parameters[i]->callback(update_cb, e); + } + + group->end(); + group->hide(); +} + +projectionEditor::projectionEditor() +{ + GModel *m = GModel::current(); + + // construct FM_Internals + m->readFourier(); + printf("readerSize = %d\n",m->getFMInternals()->getSize()); + printf("currentSize = %d\n",m->getFMInternals()->current()->GetNumGroups()); + + // construct GUI in terms of standard sizes + int _fontsize = GetFontSize(); + const int width = (int)(3.75 * BB), height = 25 * BH; + + // create all widgets (we construct this once, we never deallocate!) + _window = new dialogWindow(width, height, CTX.non_modal_windows, "Reparameterize"); + + new Fl_Box(WB, WB + BH / 2, BB / 2, BH, "Select:"); + + Fl_Group *o = new Fl_Group(WB, WB, 2 * BB, 3 * BH); + _select[0] = new Fl_Round_Button(2 * WB + BB / 2, WB, BB, BH, "Points"); + _select[1] = new Fl_Round_Button(2 * WB + BB / 2, WB + BH, BB, BH, "Elements"); + if(m->getNumMeshElements()) + _select[1]->value(1); + else + _select[0]->value(1); + for(int i = 0; i < 2; i++){ + _select[i]->callback(select_cb, this); + _select[i]->type(FL_RADIO_BUTTON); + } + o->end(); + + { + Fl_Toggle_Button *b1 = new Fl_Toggle_Button + (width - WB - 3 * BB / 2, WB, 3 * BB / 2, BH, "Hide unselected"); + b1->callback(proj_hide_cb); + Fl_Button *b2 = new Fl_Button + (width - WB - 3 * BB / 2, WB + BH, 3 * BB / 2, BH, "Save selection"); + b2->callback(save_selection_cb, this); + } + + const int brw = (int)(1.3 * BB); + + _browser = new Fl_Hold_Browser(WB, 2 * WB + 2 * BH, brw, 6 * BH); + _browser->callback(browse_cb, this); + + _paramWin[0] = 2 * WB + brw; + _paramWin[1] = 2 * WB + 2 * BH; + _paramWin[2] = width - 3 * WB - brw; + _paramWin[3] = 7 * BH; + _paramWin[4] = (int)(1.25 * BB); + _paramWin[5] = BH; + + { + Fl_Button *b1 = new Fl_Button(WB, 2 * WB + 8 * BH, brw / 2, BH, "Load"); + b1->callback(load_projection_cb, this); + Fl_Button *b2 = new Fl_Button(WB + brw / 2, 2 * WB + 8 * BH, brw / 2, BH, "Save"); + b2->callback(save_projection_cb, this); + } + + int hard = 8; + int uvw = width - 2 * WB - 2 * hard - 3 * WB; + int uvh = height - 8 * WB - 15 * BH - 2 * hard; + + _hardEdges[0] = new Fl_Toggle_Button(WB, 3 * WB + 9 * BH + hard, + hard, uvh); + _hardEdges[1] = new Fl_Toggle_Button(width - 4 * WB - hard, 3 * WB + 9 * BH + hard, + hard, uvh); + _hardEdges[2] = new Fl_Toggle_Button(WB + hard, 3 * WB + 9 * BH, + uvw, hard); + _hardEdges[3] = new Fl_Toggle_Button(WB + hard, height - 5 * WB - 6 * BH - hard, + uvw, hard); + for(int i = 0; i < 4; i++) + _hardEdges[i]->tooltip("Push to mark edge as `hard'"); + + _uvPlot = new uvPlot(WB + hard, 3 * WB + 9 * BH + hard, uvw, uvh); + _uvPlot->end(); + + _slider = new Fl_Slider(width - 3 * WB, 3 * WB + 9 * BH + hard, 2 * WB, uvh); + _slider->minimum(1.); + _slider->maximum(0.); + _slider->value(1.); + _slider->callback(filter_cb, this); + _slider->tooltip("Filter selection by distance to projection surface"); + + _orientation = new Fl_Toggle_Button(width - 3 * WB, height - 5 * WB - 6 * BH - hard, + 2 * WB, hard); + _orientation->callback(filter_cb, this); + _orientation->tooltip("Filter elements using orientation"); + + new Fl_Box(WB, height - 4 * WB - 6 * BH, BB, BH, "Patch Type:"); + Fl_Group *oo = new Fl_Group( WB, height - 4 * WB - 6 * BH, 3 * BB, BH); + _pselect[0] = new Fl_Round_Button(2 * WB + BB, height - 4 * WB - 6 * BH, + BB, BH, "Continuation"); + _pselect[1] = new Fl_Round_Button(3 * WB + 2 * BB, height - 4 * WB - + 6 * BH, BB, BH, "Windowing"); + + for(int i = 0; i < 2; i++) + _pselect[i]->type(FL_RADIO_BUTTON); + + _pselect[0]->value(1); + + oo->end(); + + _modes[0] = new Fl_Value_Input(WB, height - 4 * WB - 5 * BH, BB / 2, BH); + _modes[0]->tooltip("Number of Fourier modes along u"); + _modes[1] = new Fl_Value_Input(WB + BB / 2, height - 4 * WB - 5 * BH, BB / 2, BH, + "Fourier modes"); + _modes[1]->tooltip("Number of Fourier modes along v"); + _modes[2] = new Fl_Value_Input(WB, height - 4 * WB - 4 * BH, BB / 2, BH); + _modes[2]->tooltip("Number of Chebyshev modes along u"); + _modes[3] = new Fl_Value_Input(WB + BB / 2, height - 4 * WB - 4 * BH, BB / 2, BH, + "Chebyshev modes"); + _modes[3]->tooltip("Number of Chebyshev modes along v"); + for(int i = 0; i < 4; i++){ + _modes[i]->value(8); + _modes[i]->maximum(128); + _modes[i]->minimum(1); + _modes[i]->step(1); + _modes[i]->align(FL_ALIGN_RIGHT); + } + + { + Fl_Button *b = new Fl_Button(width - WB - BB, height - 4 * WB - 5 * BH, + BB, 2 * BH, "Generate\nPatch"); + b->callback(compute_cb, this); + } + + { + int bb = (int)(0.37 * BB); + new Fl_Box(WB, height - 3 * WB - 3 * BH, BB / 2, BH, "Delete:"); + Fl_Button *b1 = new Fl_Button(WB + BB / 2, height - 3 * WB - 3 * BH, + bb, BH, "last"); + b1->callback(action_cb, (void*)"delete_last"); + Fl_Button *b2 = new Fl_Button(WB + BB / 2 + bb, height - 3 * WB - 3 * BH, + bb, BH, "all"); + b2->callback(action_cb, (void*)"delete_all"); + Fl_Button *b3 = new Fl_Button(WB + BB / 2 + 2 * bb, height - 3 * WB - 3 * BH, + bb, BH, "sel."); + b3->callback(action_cb, (void*)"delete_select"); + } + + { + int bb = (int)(0.37 * BB); + int s = width - WB - BB / 2 - 3 * bb; + new Fl_Box(s, height - 3 * WB - 3 * BH, BB / 2, BH, "Save:"); + Fl_Button *b1 = new Fl_Button(s + BB / 2, height - 3 * WB - 3 * BH, + bb, BH, "last"); + b1->callback(action_cb, (void*)"save_last"); + Fl_Button *b2 = new Fl_Button(s + BB / 2 + bb, height - 3 * WB - 3 * BH, + bb, BH, "all"); + b2->callback(action_cb, (void*)"save_all"); + Fl_Button *b3 = new Fl_Button(s + BB / 2 + 2 * bb, height - 3 * WB - 3 * BH, + bb, BH, "sel."); + b3->callback(action_cb, (void*)"save_select"); + } + + { + Fl_Button *b1 = new Fl_Button(WB, height - 2 * WB - 2 * BH, BB, BH, + "Blend"); + b1->callback(blend_cb, this); + + Fl_Button *b2 = new Fl_Button(2 * WB + BB, height - 2 * WB - 2 * BH, BB, + BH, "Intersect"); + } + + Fl_Button *b = new Fl_Button(width - WB - BB, height - WB - BH, BB, BH, "Cancel"); + b->callback(close_cb, _window); + + _window->end(); + _window->hotspot(_window); + _window->resizable(_uvPlot); + _window->size_range(width, (int)(0.85 * height)); + + // create +} + +void projectionEditor::load(fourierProjectionFace *face, std::string tag) +{ + FM::ProjectionSurface *ps = (FM::ProjectionSurface*)face->getNativePtr(); + _browser->add(tag.size() ? tag.c_str() : ps->GetName().c_str()); + projection *p = new projection(face, _paramWin[0], _paramWin[1], _paramWin[2], + _paramWin[3], _paramWin[4], _paramWin[5], this); + _projections.push_back(p); + _window->add(p->group); +} + +void projectionEditor::show() +{ + _window->show(); + select_cb(0, this); +} + +int projectionEditor::getSelectionMode() +{ + if(_select[0]->value()) + return ENT_POINT; + else + return ENT_ALL; +} + +int projectionEditor::getPatchType() +{ + if (_pselect[0]->value()) + return 0; + else + return 1; +} + +projection *projectionEditor::getCurrentProjection() +{ + for(int i = 1; i <= _browser->size(); i++) + if(_browser->selected(i)) return _projections[i - 1]; + return 0; +} + +projection *projectionEditor::getLastProjection() +{ + return _projections[_projections.size() - 1]; +} + void mesh_parameterize_cb(Fl_Widget* w, void* data) { // display geometry surfaces diff --git a/Fltk/projectionEditor.h b/Fltk/projectionEditor.h index 95392bd2c3..8dffb1cc9f 100644 --- a/Fltk/projectionEditor.h +++ b/Fltk/projectionEditor.h @@ -81,27 +81,8 @@ class projectionEditor { double getThreshold(){ return _slider->value(); } }; -void select_cb(Fl_Widget *w, void *data); -void filter_cb(Fl_Widget *w, void *data); -void browse_cb(Fl_Widget *w, void *data); -void set_position_cb(Fl_Widget *w, void *data); -void invert_normal_cb(Fl_Widget *w, void *data); -void translate_p0_cb(Fl_Widget *w, void *data); -void translate_p1_cb(Fl_Widget *w, void *data); -void translate_p2_cb(Fl_Widget *w, void *data); -void translate_m0_cb(Fl_Widget *w, void *data); -void translate_m1_cb(Fl_Widget *w, void *data); -void translate_m2_cb(Fl_Widget *w, void *data); -void update_cb(Fl_Widget *w, void *data); -void close_cb(Fl_Widget *w, void *data); -void hide_cb(Fl_Widget *w, void *data); -void save_selection_cb(Fl_Widget *w, void *data); -void load_projection_cb(Fl_Widget *w, void *data); -void save_projection_cb(Fl_Widget *w, void *data); -void blend_cb(Fl_Widget *w, void *data); -void compute_cb(Fl_Widget *w, void *data); -void action_cb(Fl_Widget *w, void *data); - #endif +void mesh_parameterize_cb(Fl_Widget* w, void* data); + #endif diff --git a/Fltk/solverWindow.cpp b/Fltk/solverWindow.cpp index 644de28021..72b16444bb 100644 --- a/Fltk/solverWindow.cpp +++ b/Fltk/solverWindow.cpp @@ -3,6 +3,7 @@ // See the LICENSE.txt file for license information. Please report all // bugs and problems to <gmsh@geuz.org>. +#include <string.h> #include <FL/Fl_Tabs.H> #include <FL/Fl_Box.H> #include <FL/Fl_Return_Button.H> @@ -10,12 +11,180 @@ #include "GUI.h" #include "solverWindow.h" #include "shortcutWindow.h" +#include "optionWindow.h" +#include "messageWindow.h" +#include "fileDialogs.h" +#include "GmshMessage.h" #include "Solvers.h" -#include "Callbacks.h" +#include "StringUtils.h" +#include "Options.h" +#include "OS.h" #include "Context.h" extern Context_T CTX; +void solver_cb(Fl_Widget *w, void *data) +{ + static int init = 0, first[MAX_NUM_SOLVERS]; + int num = (int)(long)data; + + if(!init) { + for(int i = 0; i < MAX_NUM_SOLVERS; i++) + first[i] = 1; + init = 1; + } + + if(first[num]) { + char file[256]; + first[num] = 0; + strcpy(file, CTX.no_ext_filename); + strcat(file, SINFO[num].extension); + GUI::instance()->solver[num]->input[0]->value(file); + } + if(SINFO[num].nboptions) { + std::string file = FixWindowsPath + (GUI::instance()->solver[num]->input[0]->value()); + char tmp[256], tmp2[256]; + sprintf(tmp, "\"%s\"", file.c_str()); + sprintf(tmp2, SINFO[num].name_command, tmp); + sprintf(tmp, "%s %s", SINFO[num].option_command, tmp2); + Solver(num, tmp); + } + GUI::instance()->solver[num]->win->show(); +} + +static void solver_file_open_cb(Fl_Widget *w, void *data) +{ + char tmp[256], tmp2[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, 0, "Choose", tmp)) { + GUI::instance()->solver[num]->input[0]->value(file_chooser_get_name(1).c_str()); + if(SINFO[num].nboptions) { + std::string file = FixWindowsPath(file_chooser_get_name(1).c_str()); + sprintf(tmp, "\"%s\"", file.c_str()); + sprintf(tmp2, SINFO[num].name_command, tmp); + sprintf(tmp, "%s %s", SINFO[num].option_command, tmp2); + Solver(num, tmp); + } + } +} + +static void solver_file_edit_cb(Fl_Widget *w, void *data) +{ + int num = (int)(long)data; + std::string prog = FixWindowsPath(CTX.editor); + std::string file = FixWindowsPath(GUI::instance()->solver[num]->input[0]->value()); + char cmd[1024]; + ReplaceMultiFormat(prog.c_str(), file.c_str(), cmd); + SystemCall(cmd); +} + +static void solver_choose_mesh_cb(Fl_Widget *w, void *data) +{ + int num = (int)(long)data; + if(file_chooser(0, 0, "Choose", "*")) + GUI::instance()->solver[num]->input[1]->value(file_chooser_get_name(1).c_str()); +} + +static 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; +} + +static void solver_command_cb(Fl_Widget *w, void *data) +{ + char tmp[256], mesh[256], arg[512], command[256]; + int num = ((int *)data)[0]; + int idx = ((int *)data)[1]; + int i, usedopts = 0; + + if(SINFO[num].popup_messages) + GUI::instance()->messages->show(true); + + if(strlen(GUI::instance()->solver[num]->input[1]->value())) { + std::string m = FixWindowsPath(GUI::instance()->solver[num]->input[1]->value()); + sprintf(tmp, "\"%s\"", m.c_str()); + 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::Error("Missing options to execute command"); + return; + } + sprintf(command, SINFO[num].button_command[idx], SINFO[num].option + [usedopts][GUI::instance()->solver[num]->choice[usedopts]->value()]); + } + else { + strcpy(command, SINFO[num].button_command[idx]); + } + + std::string c = FixWindowsPath(GUI::instance()->solver[num]->input[0]->value()); + sprintf(arg, "\"%s\"", c.c_str()); + sprintf(tmp, SINFO[num].name_command, arg); + sprintf(arg, "%s %s %s", tmp, mesh, command); + Solver(num, arg); +} + +static void solver_kill_cb(Fl_Widget *w, void *data) +{ + 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; +} + +static void solver_ok_cb(Fl_Widget *w, void *data) +{ + int retry = 0, num = (int)(long)data; + opt_solver_popup_messages + (num, GMSH_SET, GUI::instance()->solver[num]->butt[0]->value()); + opt_solver_merge_views + (num, GMSH_SET, GUI::instance()->solver[num]->butt[1]->value()); + opt_solver_client_server + (num, GMSH_SET, GUI::instance()->solver[num]->butt[2]->value()); + if(strcmp(opt_solver_executable(num, GMSH_GET, NULL), + GUI::instance()->solver[num]->input[2]->value())) + retry = 1; + opt_solver_executable + (num, GMSH_SET, GUI::instance()->solver[num]->input[2]->value()); + if(retry) + solver_cb(NULL, data); +} + +static void solver_choose_executable_cb(Fl_Widget *w, void *data) +{ + int num = (int)(long)data; + if(file_chooser(0, 0, "Choose", +#if defined(WIN32) + "*.exe" +#else + "*" +#endif + )){ + GUI::instance()->solver[num]->input[2]->value(file_chooser_get_name(1).c_str()); + solver_ok_cb(w, data); + } +} + solverWindow::solverWindow(int solverIndex, int fontsize) : _fontsize(fontsize) { @@ -125,7 +294,7 @@ solverWindow::solverWindow(int solverIndex, int fontsize) b1->callback(solver_kill_cb, (void *)solverIndex); Fl_Button *b2 = new Fl_Button (width - BB - WB, height - BH - WB, BB, BH, "Cancel"); - b2->callback(cancel_cb, (void*)win); + b2->callback(hide_cb, (void*)win); } win->position(CTX.solver_position[0], CTX.solver_position[1]); diff --git a/Fltk/solverWindow.h b/Fltk/solverWindow.h index ebc5fbfd9d..940a0fbacc 100644 --- a/Fltk/solverWindow.h +++ b/Fltk/solverWindow.h @@ -25,4 +25,6 @@ class solverWindow{ solverWindow(int solverIndex, int fontsize); }; +void solver_cb(Fl_Widget *w, void *data); + #endif diff --git a/Fltk/statisticsWindow.cpp b/Fltk/statisticsWindow.cpp index 074af9e76d..c3385d91f9 100644 --- a/Fltk/statisticsWindow.cpp +++ b/Fltk/statisticsWindow.cpp @@ -7,16 +7,75 @@ #include <FL/Fl_Box.H> #include <FL/Fl_Return_Button.H> #include "GUI.h" +#include "Draw.h" #include "statisticsWindow.h" #include "shortcutWindow.h" #include "GModel.h" +#include "MElement.h" #include "PView.h" -#include "Callbacks.h" #include "Generator.h" #include "Context.h" extern Context_T CTX; +void statistics_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->stats->show(); +} + +static void statistics_update_cb(Fl_Widget *w, void *data) +{ + GUI::instance()->stats->compute(true); +} + +static void statistics_histogram_cb(Fl_Widget *w, void *data) +{ + std::string name((const char*)data); + + std::vector<double> x, y; + + if(name == "Gamma2D"){ + for(int i = 0; i < 100; i++) y.push_back(GUI::instance()->stats->quality[0][i]); + new PView("Gamma", "# Elements", x, y); + } + else if(name == "Eta2D"){ + for(int i = 0; i < 100; i++) y.push_back(GUI::instance()->stats->quality[1][i]); + new PView("Eta", "# Elements", x, y); + } + else if(name == "Rho2D"){ + for(int i = 0; i < 100; i++) y.push_back(GUI::instance()->stats->quality[2][i]); + new PView("Rho", "# Elements", x, y); + } + else if(name == "Disto2D"){ + for(int i = 0; i < 100; i++) y.push_back(GUI::instance()->stats->quality[3][i]); + new PView("Disto", "# Elements", x, y); + } + else{ + std::vector<GEntity*> entities; + GModel::current()->getEntities(entities); + std::map<int, std::vector<double> > d; + for(unsigned int i = 0; i < entities.size(); i++){ + if(entities[i]->dim() < 2) continue; + for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){ + MElement *e = entities[i]->getMeshElement(j); + if(name == "Gamma3D") + d[e->getNum()].push_back(e->gammaShapeMeasure()); + else if(name == "Eta3D") + d[e->getNum()].push_back(e->etaShapeMeasure()); + else if(name == "Rho3D") + d[e->getNum()].push_back(e->rhoShapeMeasure()); + else + d[e->getNum()].push_back(e->distoShapeMeasure()); + } + } + name.resize(name.size() - 2); + new PView(name, "ElementData", GModel::current(), d); + } + + GUI::instance()->updateViews(); + Draw(); +} + statisticsWindow::statisticsWindow(int fontsize) : _fontsize(fontsize) { @@ -114,7 +173,7 @@ statisticsWindow::statisticsWindow(int fontsize) } { Fl_Button *o = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel"); - o->callback(cancel_cb, (void *)win); + o->callback(hide_cb, (void *)win); } win->position(CTX.stat_position[0], CTX.stat_position[1]); diff --git a/Fltk/statisticsWindow.h b/Fltk/statisticsWindow.h index 304a38783c..680623bd7b 100644 --- a/Fltk/statisticsWindow.h +++ b/Fltk/statisticsWindow.h @@ -26,4 +26,6 @@ class statisticsWindow{ void show(); }; +void statistics_cb(Fl_Widget *w, void *data); + #endif diff --git a/Fltk/visibilityWindow.cpp b/Fltk/visibilityWindow.cpp index 9733b5e7f5..74e52858c6 100644 --- a/Fltk/visibilityWindow.cpp +++ b/Fltk/visibilityWindow.cpp @@ -7,13 +7,400 @@ #include <FL/Fl_Box.H> #include <FL/Fl_Return_Button.H> #include "GUI.h" +#include "Draw.h" #include "visibilityWindow.h" #include "shortcutWindow.h" -#include "Callbacks.h" +#include "contextWindow.h" +#include "GmshDefines.h" +#include "GmshMessage.h" +#include "GModel.h"' +#include "MElement.h" +#include "Visibility.h" +#include "SelectBuffer.h" +#include "GeoStringInterface.h" +#include "Options.h" #include "Context.h" extern Context_T CTX; +// Visibility Menu + +void visibility_cb(Fl_Widget *w, void *data) +{ + // get the visibility info from the model, and update the browser + // accordingly + const char *str = (const char*)data; + if(str && !strcmp(str, "redraw_only")) + GUI::instance()->visibility->show(true); + else + GUI::instance()->visibility->show(false); + + GUI::instance()->visibility->browser->clear(); + + int type = GUI::instance()->visibility->type->value(); + + VisibilityManager::instance()->update(type); + for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){ + GUI::instance()->visibility->browser->add + (VisibilityManager::instance()->getBrowserLine(i).c_str()); + if(VisibilityManager::instance()->getVisibility(i)) + GUI::instance()->visibility->browser->select(i + 1); + } + + // activate the delete button for physicals only! + if(type == 1) + GUI::instance()->visibility->push[0]->activate(); + else + GUI::instance()->visibility->push[0]->deactivate(); + + // disable numeric and interactive selection for partitions + if(type == 2){ + GUI::instance()->visibility->group[1]->deactivate(); + GUI::instance()->visibility->group[2]->deactivate(); + } + else{ + GUI::instance()->visibility->group[1]->activate(); + GUI::instance()->visibility->group[2]->activate(); + } +} + +static void visibility_ok_cb(Fl_Widget *w, void *data) +{ + // 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 = GUI::instance()->visibility->butt[0]->value() ? true : false; + int type = GUI::instance()->visibility->type->value(); + VisibilityManager::instance()->setAllInvisible(type); + for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++) + if(GUI::instance()->visibility->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)) + GUI::instance()->visibility->browser->select(i + 1); + Draw(); + } +} + +static void visibility_save_cb(Fl_Widget *w, void *data) +{ + std::string str = VisibilityManager::instance()->getStringForGEO(); + add_infile(str.c_str(), CTX.filename); +} + +static void visibility_delete_cb(Fl_Widget *w, void *data) +{ + int type = GUI::instance()->visibility->type->value(); + if(type != 1) return; // delete only available for physicals + + bool all = true; + for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){ + if(!GUI::instance()->visibility->browser->selected(i + 1)){ + all = false; + break; + } + } + if(all){ + GModel::current()->deletePhysicalGroups(); + } + else{ + for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){ + if(GUI::instance()->visibility->browser->selected(i + 1)){ + Vis *v = VisibilityManager::instance()->getEntity(i); + GModel::current()->deletePhysicalGroup(v->getDim(), v->getTag()); + } + } + } + + visibility_cb(NULL, (void*)"redraw_only"); +} + +static void visibility_sort_cb(Fl_Widget *w, void *data) +{ + const char *str = (const 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 < GUI::instance()->visibility->browser->size(); i++) + if(!GUI::instance()->visibility->browser->selected(i + 1)) { + selectall = 1; + break; + } + if(selectall) + for(int i = 0; i < GUI::instance()->visibility->browser->size(); i++) + GUI::instance()->visibility->browser->select(i + 1); + else + GUI::instance()->visibility->browser->deselect(); + } + else if(val == -1){ // invert the selection + int *state = new int[GUI::instance()->visibility->browser->size()]; + for(int i = 0; i < GUI::instance()->visibility->browser->size(); i++) + state[i] = GUI::instance()->visibility->browser->selected(i + 1); + GUI::instance()->visibility->browser->deselect(); + for(int i = 0; i < GUI::instance()->visibility->browser->size(); i++) + if(!state[i]) GUI::instance()->visibility->browser->select(i + 1); + delete [] state; + } + else if(val == -2){ // create new parameter name for selection + for(int i = 0; i < GUI::instance()->visibility->browser->size(); i++){ + if(GUI::instance()->visibility->browser->selected(i + 1)){ + static char tmpstr[256]; + sprintf(tmpstr, "%d", VisibilityManager::instance()->getTag(i)); + GUI::instance()->geoContext->input[1]->value(tmpstr); + break; + } + } + GUI::instance()->geoContext->input[0]->value("NewName"); + GUI::instance()->geoContext->show(0); + } + else { // set new sorting mode + VisibilityManager::instance()->setSortMode(val); + visibility_cb(NULL, (void*)"redraw_only"); + } +} + +static void visibility_number_cb(Fl_Widget *w, void *data) +{ + CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + + // type = 0 for elementary, 1 for physical and 2 for partitions + int type = GUI::instance()->visibility->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; + } + const char *str = GUI::instance()->visibility->input[what]->value(); + if(type == 1 && what >= 2 && what <= 5) what += 4; + + int num = (!strcmp(str, "all") || !strcmp(str, "*")) ? -1 : atoi(str); + bool recursive = GUI::instance()->visibility->butt[0]->value() ? true : false; + + VisibilityManager::instance()->setVisibilityByNumber(what, num, val, recursive); + + int pos = GUI::instance()->visibility->browser->position(); + visibility_cb(NULL, (void*)"redraw_only"); + GUI::instance()->visibility->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 = GUI::instance()->visibility->type->value(); + if(type != 0 && type != 1) return; + bool recursive = GUI::instance()->visibility->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 = GUI::instance()->visibility->browser->position(); + visibility_cb(NULL, (void*)"redraw_only"); + GUI::instance()->visibility->browser->position(pos); +} + +static void visibility_interactive_cb(Fl_Widget *w, void *data) +{ + const char *str = (const char*)data; + const char *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"; + if(GModel::current()->getMeshStatus() < 2) + 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"; + if(GModel::current()->getMeshStatus() < 3) + 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"; + if(GModel::current()->getMeshStatus() < 2) + 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"; + if(GModel::current()->getMeshStatus() < 3) + 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) { + if(what == ENT_ALL) + CTX.mesh.changed = ENT_ALL; + Draw(); + Msg::StatusBar(3, false, "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::StatusBar(3, false, ""); +} + // derive our own browser, that reacts differently to the Enter key class visBrowser : public Fl_Browser{ int handle(int event) @@ -222,7 +609,7 @@ visibilityWindow::visibilityWindow(int fontsize) Fl_Button *o2 = new Fl_Button (width - BB - WB, height - BH - WB, BB, BH, "Cancel"); - o2->callback(cancel_cb, (void *)win); + o2->callback(hide_cb, (void *)win); } win->position(CTX.vis_position[0], CTX.vis_position[1]); diff --git a/Fltk/visibilityWindow.h b/Fltk/visibilityWindow.h index cc78e570a0..d9af15ca22 100644 --- a/Fltk/visibilityWindow.h +++ b/Fltk/visibilityWindow.h @@ -30,4 +30,6 @@ class visibilityWindow{ void show(bool redrawOnly); }; +void visibility_cb(Fl_Widget *w, void *data); + #endif diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi index 46479213dc..a05a9ae89e 100644 --- a/doc/texinfo/gmsh.texi +++ b/doc/texinfo/gmsh.texi @@ -3994,11 +3994,7 @@ default value for this option; create the handling routine @code{opt_XXX} in @file{Common/Options.cpp} (and add the prototype in @file{Common/Options.h}); @item -optional: create the associated widget in @file{Fltk/GUI.cpp}; -@item -optional: if no special callback is to be associated with the widget, add the -handling routine @code{opt_XXX} to the OK callback for the corresponding -option panel (in @file{Fltk/Callbacks.cpp}). +optional: create the associated widget in @file{Fltk/optionWindow.cpp}; @end enumerate @c todo: -- GitLab