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

ranges and choices now work the same

parent f6c523d6
No related branches found
No related tags found
No related merge requests found
......@@ -18,50 +18,94 @@ class inputRange : public Fl_Group {
Fl_Input *_range;
Fl_Toggle_Button *_range_butt, *_loop_butt;
double _min, _max, _step, _max_number;
std::vector<double> _choices;
void _values2string()
{
// construct range string from min/max/step
std::ostringstream tmp;
if(_min != -_max_number){
tmp << _min;
_input->minimum(_min);
if(_choices.size()){
// construct range string using choices
for(unsigned int i = 0; i < _choices.size(); i++){
if(i) tmp << ", ";
tmp << _choices[i];
}
if(_choices.size() > 1){
_input->minimum(_choices[0]);
_input->maximum(_choices[_choices.size() - 1]);
_input->step(_choices[1] - _choices[0]);
}
_step = 0.;
}
tmp << ":";
if(_max != _max_number){
tmp << _max;
_input->maximum(_max);
}
if(_step){
else{
// construct range string from min/max/step
if(_min != -_max_number){
tmp << _min;
_input->minimum(_min);
}
tmp << ":";
if(_max != _max_number){
tmp << _max;
_input->maximum(_max);
}
if(_step == 0.) _step = 1.;
if(_step != 1.) tmp << ":" << _step;
_input->step(_step);
_choices.clear();
}
_range->value(tmp.str().c_str());
}
void _string2values()
{
// parse range string and affect min/max/step
std::string str(_range->value()), min, max, step;
std::string::size_type first = 0, last;
last = str.find_first_of(':', first);
min = str.substr(first, last - first);
if(last != std::string::npos){
first = last + 1;
last = str.find_first_of(':', first);
max = str.substr(first, last - first);
if(last != std::string::npos)
step = str.substr(last + 1, str.size());
}
if(min.size()){
_min = atof(min.c_str());
_input->minimum(_min);
std::string str(_range->value());
if(str.find_first_of(',') != std::string::npos){
// parse list of values
std::string::size_type first = 0;
while(1){
std::string::size_type last = str.find_first_of(',', first);
std::string val = str.substr(first, last - first);
_choices.push_back(atof(val.c_str()));
if(last == std::string::npos)
break;
else
first = last + 1;
}
if(_choices.size() > 1){
_input->minimum(_choices[0]);
_input->maximum(_choices[_choices.size() - 1]);
_input->step(_choices[1] - _choices[0]);
}
_step = 0.;
}
if(max.size()){
_max = atof(max.c_str());
_input->maximum(_max);
}
if(step.size()){
_step = atof(step.c_str());
else{
// parse min/max/step
std::string min, max, step;
std::string::size_type first = 0;
std::string::size_type last = str.find_first_of(':', first);
min = str.substr(first, last - first);
if(last != std::string::npos){
first = last + 1;
last = str.find_first_of(':', first);
max = str.substr(first, last - first);
if(last != std::string::npos)
step = str.substr(last + 1, str.size());
}
if(min.size()){
_min = atof(min.c_str());
_input->minimum(_min);
}
else
_min = -_max_number;
if(max.size()){
_max = atof(max.c_str());
_input->maximum(_max);
}
else
_max = _max_number;
if(step.size())
_step = atof(step.c_str());
else
_step = 1.;
_input->step(_step);
_choices.clear();
}
}
void _show_range()
......@@ -126,6 +170,8 @@ class inputRange : public Fl_Group {
}
double value() { return _input->value(); }
void value(double val) { _input->value(val); }
void choices(const std::vector<double> &val) { _choices = val; _values2string(); }
std::vector<double> choices() { return _choices; }
void minimum(double val) { _min = val; _values2string(); }
double minimum() { return _min; }
void maximum(double val) { _max = val; _values2string(); }
......
......@@ -320,6 +320,30 @@ static std::string getModelName(onelab::client *c)
}
}
static void initCompute()
{
bool changed = false;
std::vector<onelab::number> numbers;
onelab::server::instance()->get(numbers);
for(unsigned int i = 0; i < numbers.size(); i++){
if(numbers[i].getAttribute("loop") == "true"){
if(numbers[i].getChoices().size() > 1){
numbers[i].setValue(numbers[i].getChoices()[0]);
onelab::server::instance()->set(numbers[i]);
changed = true;
}
else if(numbers[i].getMin() != -onelab::parameter::maxNumber() &&
numbers[i].getStep()){
numbers[i].setValue(numbers[i].getMin());
onelab::server::instance()->set(numbers[i]);
changed = true;
}
}
}
if(changed)
FlGui::instance()->onelab->rebuildTree();
}
static bool shouldRecompute()
{
bool recompute = false;
......@@ -327,13 +351,25 @@ static bool shouldRecompute()
onelab::server::instance()->get(numbers);
for(unsigned int i = 0; i < numbers.size(); i++){
if(numbers[i].getAttribute("loop") == "true"){
if(numbers[i].getMax() != onelab::parameter::maxNumber() &&
numbers[i].getValue() < numbers[i].getMax() &&
numbers[i].getStep()){
if(numbers[i].getChoices().size() > 1){
std::vector<double> choices(numbers[i].getChoices());
for(unsigned int j = 0; j < choices.size() - 1; j++){
if(numbers[i].getValue() == choices[j]){
numbers[i].setValue(choices[j + 1]);
onelab::server::instance()->set(numbers[i]);
Msg::Info("Recomputing with new choice %s=%g",
numbers[i].getName().c_str(), numbers[i].getValue());
recompute = true;
}
}
}
else if(numbers[i].getMax() != onelab::parameter::maxNumber() &&
numbers[i].getValue() < numbers[i].getMax() &&
numbers[i].getStep()){
numbers[i].setValue(numbers[i].getValue() + numbers[i].getStep());
onelab::server::instance()->set(numbers[i]);
Msg::Info("Recomputing with %s=%g", numbers[i].getName().c_str(),
numbers[i].getValue());
Msg::Info("Recomputing with new step %s=%g",
numbers[i].getName().c_str(), numbers[i].getValue());
recompute = true;
}
}
......@@ -370,77 +406,79 @@ void onelab_cb(Fl_Widget *w, void *data)
}
FlGui::instance()->onelab->deactivate();
recompute:
// the Gmsh client is special: it always gets executed first. (The
// meta-model will allow more flexibility: but in the simple GUI we
// can assume this)
onelab::server::citer it = onelab::server::instance()->findClient("Gmsh");
if(it != onelab::server::instance()->lastClient()){
onelab::client *c = it->second;
std::string mshFileName = getMshFileName(c);
static std::string modelName = GModel::current()->getName();
if(action == "check"){
if(onelab::server::instance()->getChanged("Gmsh") ||
modelName != GModel::current()->getName()){
// reload geometry if Gmsh parameters have been modified or if
// the model name has changed
modelName = GModel::current()->getName();
geometry_reload_cb(0, 0);
}
}
else if(action == "compute"){
if(onelab::server::instance()->getChanged("Gmsh") ||
modelName != GModel::current()->getName()){
// reload the geometry, mesh it and save the mesh if Gmsh
// parameters have been modified or if the model name has
// changed
modelName = GModel::current()->getName();
geometry_reload_cb(0, 0);
if(FlGui::instance()->onelab->meshAuto()){
mesh_3d_cb(0, 0);
CreateOutputFile(mshFileName, CTX::instance()->mesh.fileFormat);
if(action == "compute") initCompute();
do{ // enter computation loop
// the Gmsh client is special: it always gets executed first. (The
// meta-model will allow more flexibility: but in the simple GUI we
// can assume this)
onelab::server::citer it = onelab::server::instance()->findClient("Gmsh");
if(it != onelab::server::instance()->lastClient()){
onelab::client *c = it->second;
std::string mshFileName = getMshFileName(c);
static std::string modelName = GModel::current()->getName();
if(action == "check"){
if(onelab::server::instance()->getChanged("Gmsh") ||
modelName != GModel::current()->getName()){
// reload geometry if Gmsh parameters have been modified or if
// the model name has changed
modelName = GModel::current()->getName();
geometry_reload_cb(0, 0);
}
}
else if(StatFile(mshFileName)){
// mesh+save if the mesh file does not exist
if(FlGui::instance()->onelab->meshAuto()){
mesh_3d_cb(0, 0);
CreateOutputFile(mshFileName, CTX::instance()->mesh.fileFormat);
else if(action == "compute"){
if(onelab::server::instance()->getChanged("Gmsh") ||
modelName != GModel::current()->getName()){
// reload the geometry, mesh it and save the mesh if Gmsh
// parameters have been modified or if the model name has
// changed
modelName = GModel::current()->getName();
geometry_reload_cb(0, 0);
if(FlGui::instance()->onelab->meshAuto()){
mesh_3d_cb(0, 0);
CreateOutputFile(mshFileName, CTX::instance()->mesh.fileFormat);
}
}
else if(StatFile(mshFileName)){
// mesh+save if the mesh file does not exist
if(FlGui::instance()->onelab->meshAuto()){
mesh_3d_cb(0, 0);
CreateOutputFile(mshFileName, CTX::instance()->mesh.fileFormat);
}
}
onelab::server::instance()->setChanged(false, "Gmsh");
}
onelab::server::instance()->setChanged(false, "Gmsh");
}
}
// Iterate over all other clients
for(onelab::server::citer it = onelab::server::instance()->firstClient();
it != onelab::server::instance()->lastClient(); it++){
onelab::client *c = it->second;
if(c->getName() == "Gmsh" || // local Gmsh client
c->getName() == "Listen" || // unknown client connecting through "-listen"
c->getName() == "GmshRemote") // distant post-processing Gmsh client
continue;
std::string what = getModelName(c);
if(action == "initial check" || action == "check"){
c->run(what);
}
else if(action == "compute"){
// get command line from the server
std::vector<onelab::string> ps;
onelab::server::instance()->get(ps, c->getName() + "/9Compute");
if(ps.size()) what += " " + ps[0].getValue();
c->run(what);
}
else if(action == "kill"){
c->kill();
// Iterate over all other clients
for(onelab::server::citer it = onelab::server::instance()->firstClient();
it != onelab::server::instance()->lastClient(); it++){
onelab::client *c = it->second;
if(c->getName() == "Gmsh" || // local Gmsh client
c->getName() == "Listen" || // unknown client connecting through "-listen"
c->getName() == "GmshRemote") // distant post-processing Gmsh client
continue;
std::string what = getModelName(c);
if(action == "initial check" || action == "check"){
c->run(what);
}
else if(action == "compute"){
// get command line from the server
std::vector<onelab::string> ps;
onelab::server::instance()->get(ps, c->getName() + "/9Compute");
if(ps.size()) what += " " + ps[0].getValue();
c->run(what);
}
else if(action == "kill"){
c->kill();
}
}
}
printf("Gmsh ONELAB db:\n%s\n", onelab::server::instance()->toChar().c_str());
printf("Gmsh ONELAB db:\n%s\n", onelab::server::instance()->toChar().c_str());
if(action == "compute" && shouldRecompute()) goto recompute;
} while(action == "compute" && shouldRecompute());
FlGui::instance()->onelab->activate();
FlGui::instance()->onelab->rebuildTree();
......@@ -472,6 +510,7 @@ static void onelab_input_range_cb(Fl_Widget *w, void *data)
numbers[0].setMin(o->minimum());
numbers[0].setMax(o->maximum());
numbers[0].setStep(o->step());
numbers[0].setChoices(o->choices());
numbers[0].setAttribute("loop", o->loop() ? "true" : "false");
onelab::server::instance()->set(numbers[0]);
}
......@@ -614,6 +653,7 @@ void onelabWindow::rebuildTree()
but->minimum(numbers[i].getMin());
but->maximum(numbers[i].getMax());
but->step(numbers[i].getStep());
but->choices(numbers[i].getChoices());
but->loop(numbers[i].getAttribute("loop") == "true");
but->align(FL_ALIGN_RIGHT);
but->callback(onelab_input_range_cb, (void*)n);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment