Skip to content
Snippets Groups Projects
Commit 8d9a85f5 authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

automagic 2D graphs with onelab

parent 9c77a95a
Branches
Tags
No related merge requests found
......@@ -110,6 +110,22 @@ static void gmsh_gear(Fl_Color c)
fl_line_style(FL_SOLID);
}
static void gmsh_graph_x(Fl_Color c)
{
fl_color(c);
fl_begin_line(); vv(-0.8,0.8); vv(0.8,0.8); fl_end_line();
fl_begin_polygon(); vv(0.8,0.8); vv(0.2,1.1); vv(0.2,0.5); fl_end_polygon();
fl_begin_line(); vv(-0.8,0.3); vv(-0.2,-0.2); vv(0.3,0.1); vv(0.8,-0.4); fl_end_line();
}
static void gmsh_graph_y(Fl_Color c)
{
fl_color(c);
fl_begin_line(); vv(-0.8,-0.8); vv(-0.8,0.8); fl_end_line();
fl_begin_polygon(); vv(-0.8,-1.1); vv(-1.1, -0.5); vv(-0.5, -0.5); fl_end_polygon();
fl_begin_line(); vv(-0.8,0.3); vv(-0.2,-0.2); vv(0.3,0.1); vv(0.8,-0.4); fl_end_line();
}
#undef vv
#undef bl
#undef el
......@@ -487,6 +503,8 @@ graphicWindow::graphicWindow(bool main, int numTiles)
fl_add_symbol("gmsh_models", gmsh_models, 1);
fl_add_symbol("gmsh_clscale", gmsh_clscale, 1);
fl_add_symbol("gmsh_gear", gmsh_gear, 1);
fl_add_symbol("gmsh_graph_x", gmsh_graph_x, 1);
fl_add_symbol("gmsh_graph_y", gmsh_graph_y, 1);
first = false;
}
......
......@@ -16,7 +16,8 @@ class inputRange : public Fl_Group {
private:
Fl_Value_Input *_input;
Fl_Input *_range;
Fl_Toggle_Button *_range_butt, *_loop_butt;
Fl_Toggle_Button *_range_butt, *_loop_butt, *_graph_butt[2];
std::string _loop_val, _graph_val[2];
double _min, _max, _step, _max_number;
std::vector<double> _choices;
void _values2string()
......@@ -123,60 +124,104 @@ class inputRange : public Fl_Group {
}
void _set_loop_value(const std::string &val)
{
_loop_val = val;
if(val == "1"){
_loop_butt->label("1");
//_loop_butt->label("1");
_loop_butt->selection_color(FL_GREEN);
_loop_butt->value(1);
}
else if(val == "2"){
_loop_butt->label("2");
//_loop_butt->label("2");
_loop_butt->selection_color(FL_BLUE);
_loop_butt->value(1);
}
else if(val == "3"){
_loop_butt->label("3");
//_loop_butt->label("3");
_loop_butt->selection_color(FL_RED);
_loop_butt->value(1);
}
else{
_loop_butt->label("@-1gmsh_rotate");
//_loop_butt->label("@-1gmsh_rotate");
_loop_butt->selection_color(_loop_butt->color());
_loop_butt->value(0);
}
_loop_butt->redraw();
}
void _set_graph_value(int axis, const std::string &val)
{
_graph_val[axis] = val;
if(val == "1"){
//_graph_butt[axis]->label("1");
_graph_butt[axis]->selection_color(FL_GREEN);
_graph_butt[axis]->value(1);
}
else if(val == "2"){
//_graph_butt[axis]->label("2");
_graph_butt[axis]->selection_color(FL_BLUE);
_graph_butt[axis]->value(1);
}
else if(val == "3"){
//_graph_butt[axis]->label("3");
_graph_butt[axis]->selection_color(FL_RED);
_graph_butt[axis]->value(1);
}
else{
//_graph_butt[axis]->label(axis == 0 ? "@-1gmsh_graph_x" : "@-1gmsh_graph_y");
_graph_butt[axis]->selection_color(_graph_butt[axis]->color());
_graph_butt[axis]->value(0);
}
_graph_butt[axis]->redraw();
}
static void _input_cb(Fl_Widget *w, void *data)
{
((inputRange*)data)->do_callback();
inputRange *b = (inputRange*)data;
b->do_callback();
}
static void _range_cb(Fl_Widget *w, void *data)
{
((inputRange*)data)->_string2values();
((inputRange*)data)->do_callback();
inputRange *b = (inputRange*)data;
b->_string2values();
b->do_callback();
}
static void _range_butt_cb(Fl_Widget *w, void *data)
{
((inputRange*)data)->_show_range();
inputRange *b = (inputRange*)data;
b->_show_range();
}
static void _loop_butt_cb(Fl_Widget *w, void *data)
{
Fl_Toggle_Button *b = (Fl_Toggle_Button*)w;
if(std::string(b->label()) == "1")
((inputRange*)data)->_set_loop_value("2");
else if(std::string(b->label()) == "2")
((inputRange*)data)->_set_loop_value("3");
else if(std::string(b->label()) == "3")
((inputRange*)data)->_set_loop_value("0");
else
((inputRange*)data)->_set_loop_value("1");
((inputRange*)data)->do_callback();
inputRange *b = (inputRange*)data;
if(b->_loop_val == "1") b->_set_loop_value("2");
else if(b->_loop_val == "2") b->_set_loop_value("3");
else if(b->_loop_val == "3") b->_set_loop_value("0");
else b->_set_loop_value("1");
b->do_callback();
}
static void _graph_butt_x_cb(Fl_Widget *w, void *data)
{
inputRange *b = (inputRange*)data;
if(b->_graph_val[0] == "1") b->_set_graph_value(0, "2");
else if(b->_graph_val[0] == "2") b->_set_graph_value(0, "3");
else if(b->_graph_val[0] == "3") b->_set_graph_value(0, "0");
else b->_set_graph_value(0, "1");
b->do_callback();
}
static void _graph_butt_y_cb(Fl_Widget *w, void *data)
{
inputRange *b = (inputRange*)data;
if(b->_graph_val[1] == "1") b->_set_graph_value(1, "2");
else if(b->_graph_val[1] == "2") b->_set_graph_value(1, "3");
else if(b->_graph_val[1] == "3") b->_set_graph_value(1, "0");
else b->_set_graph_value(1, "1");
b->do_callback();
}
public:
inputRange(int x, int y, int w, int h, double max_number, const char *l=0)
: Fl_Group(x,y,w,h,l), _min(-max_number), _max(max_number), _step(1.),
_max_number(max_number)
{
int dot_w = FL_NORMAL_SIZE - 2, loop_w = FL_NORMAL_SIZE + 6;
int input_w = w - dot_w - loop_w;
int dot_w = FL_NORMAL_SIZE - 2, loop_w = FL_NORMAL_SIZE + 6, graph_w = loop_w;
int input_w = w - dot_w - loop_w - 2 * graph_w;
int range_w = input_w / 2;
_input = new Fl_Value_Input(x, y, input_w, h);
......@@ -198,6 +243,20 @@ class inputRange : public Fl_Group {
_loop_butt->callback(_loop_butt_cb, this);
_loop_butt->tooltip("Loop over range when computing");
_graph_butt[0] = new Fl_Toggle_Button
(x + input_w + dot_w + loop_w, y, graph_w, h);
_graph_butt[0]->label("@-1gmsh_graph_x");
_graph_butt[0]->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE);
_graph_butt[0]->callback(_graph_butt_x_cb, this);
_graph_butt[0]->tooltip("Use range as abscissa of X-Y graph");
_graph_butt[1] = new Fl_Toggle_Button
(x + input_w + dot_w + loop_w + graph_w, y, graph_w, h);
_graph_butt[1]->label("@-1gmsh_graph_y");
_graph_butt[1]->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE);
_graph_butt[1]->callback(_graph_butt_y_cb, this);
_graph_butt[1]->tooltip("Use range as ordinate of X-Y graph");
end(); // close the group
resizable(_input);
}
......@@ -211,13 +270,10 @@ class inputRange : public Fl_Group {
double maximum() { return _max; }
void step(double val) { _step = val; _values2string(); }
double step() { return _step; }
void loop(const std::string &val)
{
_set_loop_value(val);
}
std::string loop()
{
if(!_loop_butt->value()) return "0";
else return _loop_butt->label();
}
void loop(const std::string &val){ _set_loop_value(val); }
std::string loop(){ return _loop_val; }
void graph_x(const std::string &val){ _set_graph_value(0, val); }
std::string graph_x(){ return _graph_val[0]; }
void graph_y(const std::string &val){ _set_graph_value(1, val); }
std::string graph_y(){ return _graph_val[1]; }
};
......@@ -23,6 +23,7 @@
#include "CreateFile.h"
#include "drawContext.h"
#include "PView.h"
#include "PViewData.h"
#include "PViewOptions.h"
#include "FlGui.h"
#include "paletteWindow.h"
......@@ -181,34 +182,27 @@ bool onelab::localNetworkClient::run(const std::string &what)
break;
case GmshSocket::GMSH_PARAMETER_QUERY:
{
std::string type, name;
std::string type, name, reply;
onelab::parameter::getTypeAndNameFromChar(message, type, name);
if(type == "number"){
std::vector<onelab::number> par;
get(par, name);
if(par.size() == 1){
std::string reply = par[0].toChar();
server->SendMessage(GmshSocket::GMSH_PARAMETER, reply.size(), &reply[0]);
}
else{
std::string reply = "Parameter (number) " + name + " not found";
server->SendMessage(GmshSocket::GMSH_INFO, reply.size(), &reply[0]);
}
if(par.size() == 1) reply = par[0].toChar();
}
else if(type == "string"){
std::vector<onelab::string> par;
get(par, name);
if(par.size() == 1){
std::string reply = par[0].toChar();
server->SendMessage(GmshSocket::GMSH_PARAMETER, reply.size(), &reply[0]);
}
else{
std::string reply = "Parameter (string) " + name + " not found";
server->SendMessage(GmshSocket::GMSH_INFO, reply.size(), &reply[0]);
}
if(par.size() == 1) reply = par[0].toChar();
}
else
Msg::Error("FIXME query not done for this parameter type");
if(reply.size()){
server->SendMessage(GmshSocket::GMSH_PARAMETER, reply.size(), &reply[0]);
}
else{
reply = "Parameter '" + name + "' not found";
server->SendMessage(GmshSocket::GMSH_INFO, reply.size(), &reply[0]);
}
}
break;
case GmshSocket::GMSH_PROGRESS:
......@@ -429,6 +423,83 @@ static bool stopOnError(const std::string &client)
return false;
}
static std::vector<double> getRange(onelab::number &p)
{
std::vector<double> v;
if(p.getChoices().size()){
v = p.getChoices();
}
else if(p.getMin() != -onelab::parameter::maxNumber() &&
p.getMax() != onelab::parameter::maxNumber() && p.getStep()){
for(double d = p.getMin(); d <= p.getMax(); d += p.getStep())
v.push_back(d);
}
return v;
}
static std::string getShortName(const std::string &name, const std::string &ok="")
{
if(ok.size()) return ok;
std::string s = name;
// remove path
std::string::size_type last = name.find_last_of('/');
if(last != std::string::npos)
s = name.substr(last + 1);
// remove starting numbers
while(s.size() && s[0] >= '0' && s[0] <= '9')
s = s.substr(1);
return s;
}
static void updateOnelabGraph(std::string num)
{
bool changed = false;
for(unsigned int i = 0; i < PView::list.size(); i++){
if(PView::list[i]->getData()->getFileName() == "ONELAB" + num){
delete PView::list[i];
changed = true;
break;
}
}
std::vector<double> x, y;
std::string xName, yName;
std::vector<onelab::number> numbers;
onelab::server::instance()->get(numbers);
for(unsigned int i = 0; i < numbers.size(); i++){
if(numbers[i].getAttribute("graph_x") == num){
x = getRange(numbers[i]);
xName = getShortName(numbers[i].getName(), numbers[i].getShortHelp());
}
if(numbers[i].getAttribute("graph_y") == num){
y = getRange(numbers[i]);
yName = getShortName(numbers[i].getName(), numbers[i].getShortHelp());
}
}
if(x.size() != y.size()){
x.clear(); xName.clear();
for(unsigned int i = 0; i < y.size(); i++) x.push_back(i);
}
if(y.size()){
PView *v = new PView(xName, yName, x, y);
v->getData()->setFileName("ONELAB" + num);
v->getOptions()->intervalsType = PViewOptions::Discrete;
changed = true;
}
if(changed){
FlGui::instance()->updateViews();
drawContext::global()->draw();
}
}
static void updateOnelabGraphs()
{
updateOnelabGraph("1");
updateOnelabGraph("2");
updateOnelabGraph("3");
}
void onelab_cb(Fl_Widget *w, void *data)
{
if(!data) return;
......@@ -538,6 +609,7 @@ void onelab_cb(Fl_Widget *w, void *data)
if(stop) break;
}
updateOnelabGraphs();
FlGui::instance()->onelab->rebuildTree();
} while(action == "compute" && incrementLoop() && !stop);
......@@ -573,7 +645,10 @@ static void onelab_input_range_cb(Fl_Widget *w, void *data)
numbers[0].setStep(o->step());
numbers[0].setChoices(o->choices());
numbers[0].setAttribute("loop", o->loop());
numbers[0].setAttribute("graph_x", o->graph_x());
numbers[0].setAttribute("graph_y", o->graph_y());
onelab::server::instance()->set(numbers[0]);
updateOnelabGraphs();
}
}
......@@ -658,7 +733,7 @@ onelabWindow::onelabWindow(int deltaFontSize)
_gear->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
_gear->add("Reset database", 0, onelab_cb, (void*)"reset");
_gear->add("Print database", 0, onelab_dump_cb);
_gear->add("Remesh automatically", 0, 0, 0, FL_MENU_TOGGLE);
_gear->add("_Remesh automatically", 0, 0, 0, FL_MENU_TOGGLE);
((Fl_Menu_Item*)_gear->menu())[2].set();
_gearFrozenMenuSize = _gear->menu()->size();
......@@ -675,19 +750,6 @@ onelabWindow::onelabWindow(int deltaFontSize)
FL_NORMAL_SIZE += deltaFontSize;
}
static std::string getShortName(const std::string &name)
{
std::string s = name;
// remove path
std::string::size_type last = name.find_last_of('/');
if(last != std::string::npos)
s = name.substr(last + 1);
// remove starting numbers
while(s.size() && s[0] >= '0' && s[0] <= '9')
s = s.substr(1);
return s;
}
void onelabWindow::rebuildTree()
{
int width = (int)(0.5 * _tree->w());
......@@ -705,8 +767,7 @@ void onelabWindow::rebuildTree()
for(unsigned int i = 0; i < numbers.size(); i++){
Fl_Tree_Item *n = _tree->add(numbers[i].getName().c_str());
n->labelsize(FL_NORMAL_SIZE + 5);
std::string label = numbers[i].getShortHelp();
if(label.empty()) label = getShortName(numbers[i].getName());
std::string label = getShortName(numbers[i].getName(), numbers[i].getShortHelp());
_tree->begin();
if(numbers[i].getChoices().size() == 2 &&
numbers[i].getChoices()[0] == 0 && numbers[i].getChoices()[1] == 1){
......@@ -728,6 +789,8 @@ void onelabWindow::rebuildTree()
but->step(numbers[i].getStep());
but->choices(numbers[i].getChoices());
but->loop(numbers[i].getAttribute("loop"));
but->graph_x(numbers[i].getAttribute("graph_x"));
but->graph_y(numbers[i].getAttribute("graph_y"));
but->align(FL_ALIGN_RIGHT);
but->callback(onelab_input_range_cb, (void*)n);
but->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY);
......@@ -741,8 +804,7 @@ void onelabWindow::rebuildTree()
for(unsigned int i = 0; i < strings.size(); i++){
Fl_Tree_Item *n = _tree->add(strings[i].getName().c_str());
n->labelsize(FL_NORMAL_SIZE + 5);
std::string label = strings[i].getShortHelp();
if(label.empty()) label = getShortName(strings[i].getName());
std::string label = getShortName(strings[i].getName(), strings[i].getShortHelp());
_tree->begin();
Fl_Input_Choice *but = new Fl_Input_Choice(1, 1, width, 1);
_treeWidgets.push_back(but);
......
......@@ -86,17 +86,15 @@ PView::PView(std::string xname, std::string yname,
_init();
PViewDataList *data = new PViewDataList();
for(unsigned int i = 0; i < y.size(); i++){
double d;
if(x.size() == y.size()){
data->SP.push_back(x[i]);
}
else{
d = y.size() > 1 ? (double)i / (double)(y.size() - 1) : 0.;
double d = y.size() > 1 ? (double)i / (double)(y.size() - 1) : 0.;
data->SP.push_back(d);
}
d = 0.;
data->SP.push_back(d);
data->SP.push_back(d);
data->SP.push_back(0.);
data->SP.push_back(0.);
data->SP.push_back(y[i]);
data->NbSP++;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment