From ed11f34e0addfb9cdff7c2202208c8ffda11aebb Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Sun, 20 Mar 2016 09:06:59 +0000 Subject: [PATCH] Onelab "changed" flag is now multi-level (not just true/false). This allows finer granularity for complex clients. For example, Gmsh now responds to 4 levels of "changed" - changed == 0: nothing to do - changed == 1: only save the mesh (useful if we only chanaged some physical groups) - changed == 2: only remesh and save the mesh (useful if we only changed some meshing paramaters) - changed >= 3: reload geometry, remesh and save the mesh --- Common/GmshMessage.cpp | 18 +++-- Common/GmshMessage.h | 6 +- Common/OpenFile.cpp | 5 +- Common/Options.cpp | 50 ++++++------- Common/gmshLocalNetworkClient.cpp | 7 +- Common/onelab.h | 112 +++++++++++++++++++----------- Common/onelabUtils.cpp | 38 +++++----- Fltk/graphicWindow.cpp | 1 + Geo/GModel.cpp | 4 +- Geo/GeoStringInterface.cpp | 19 +++-- 10 files changed, 157 insertions(+), 103 deletions(-) diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp index d700ef9e09..22e0d5b4ca 100644 --- a/Common/GmshMessage.cpp +++ b/Common/GmshMessage.cpp @@ -742,7 +742,7 @@ bool Msg::UseOnelab() } void Msg::SetOnelabNumber(std::string name, double val, bool visible, - bool persistent, bool readOnly, bool neverChanged) + bool persistent, bool readOnly, int changedValue) { #if defined(HAVE_ONELAB) if(_onelabClient){ @@ -756,14 +756,14 @@ void Msg::SetOnelabNumber(std::string name, double val, bool visible, numbers[0].setVisible(visible); if(persistent) numbers[0].setAttribute("Persistent", "1"); numbers[0].setReadOnly(readOnly); - numbers[0].setNeverChanged(neverChanged); + numbers[0].setChangedValue(changedValue); _onelabClient->set(numbers[0]); } #endif } void Msg::SetOnelabString(std::string name, std::string val, bool visible, - bool persistent, bool readOnly, bool neverChanged, + bool persistent, bool readOnly, int changedValue, const std::string &kind) { #if defined(HAVE_ONELAB) @@ -778,7 +778,7 @@ void Msg::SetOnelabString(std::string name, std::string val, bool visible, strings[0].setVisible(visible); if(persistent) strings[0].setAttribute("Persistent", "1"); strings[0].setReadOnly(readOnly); - strings[0].setNeverChanged(neverChanged); + strings[0].setChangedValue(changedValue); if(kind.size()) strings[0].setKind(kind); _onelabClient->set(strings[0]); } @@ -897,7 +897,7 @@ void Msg::SetOnelabAction(const std::string &action) if(_onelabClient){ onelab::string o(_onelabClient->getName() + "/Action", action); o.setVisible(false); - o.setNeverChanged(true); + o.setChangedValue(0); _onelabClient->set(o); } #endif @@ -970,6 +970,7 @@ static void _setStandardOptions(onelab::parameter *p, if(fopt.count("Visible")) p->setVisible(fopt["Visible"][0] ? true : false); if(fopt.count("ReadOnly")) p->setReadOnly(fopt["ReadOnly"][0] ? true : false); if(fopt.count("NeverChanged")) p->setNeverChanged(fopt["NeverChanged"][0] ? true : false); + if(fopt.count("ChangedValue")) p->setChangedValue(fopt["ChangedValue"][0]); if(fopt.count("ReadOnlyRange")) p->setAttribute("ReadOnlyRange", fopt["ReadOnlyRange"][0] ? "1" : "0"); if(fopt.count("AutoCheck")) @@ -1177,12 +1178,14 @@ void Msg::ImportPhysicalGroupsInOnelab() size += groups[dim].size(); onelab::number n("Gmsh/Number of physical groups", size); n.setReadOnly(true); + n.setChangedValue(1); n.setVisible(false); n.setAttribute("Closed", "1"); _onelabClient->set(n); onelab::number nd("Gmsh/Model dimension", GModel::current()->getDim()); nd.setReadOnly(true); + nd.setChangedValue(1); nd.setVisible(false); nd.setAttribute("Closed", "1"); _onelabClient->set(nd); @@ -1203,14 +1206,17 @@ void Msg::ImportPhysicalGroupsInOnelab() std::string str = tmp; onelab::number n1(str + "Dimension", dim); n1.setReadOnly(true); + n1.setChangedValue(1); n1.setVisible(false); _onelabClient->set(n1); onelab::number n2(str + "Number", num); n2.setReadOnly(true); + n2.setChangedValue(1); n2.setVisible(false); _onelabClient->set(n2); onelab::string s(str + "Name", name); s.setReadOnly(true); + s.setChangedValue(1); s.setVisible(false); _onelabClient->set(s); index++; @@ -1235,7 +1241,7 @@ void Msg::RunOnelabClient(const std::string &name, const std::string &command) #endif } -void Msg::SetOnelabChanged(bool value, const std::string &client) +void Msg::SetOnelabChanged(int value, const std::string &client) { #if defined(HAVE_ONELAB) onelab::server::instance()->setChanged(value, client); diff --git a/Common/GmshMessage.h b/Common/GmshMessage.h index a7582c2764..3829b14c29 100644 --- a/Common/GmshMessage.h +++ b/Common/GmshMessage.h @@ -118,10 +118,10 @@ class Msg { static bool UseOnelab(); static void SetOnelabNumber(std::string name, double val, bool visible=true, bool persistent=false, bool readOnly=false, - bool neverChanged=false); + int changedValue=3); static void SetOnelabString(std::string name, std::string val, bool visible=true, bool persistent=false, bool readOnly=false, - bool neverChanged=false, const std::string &kind=""); + int changedValue=3, const std::string &kind=""); static double GetOnelabNumber(std::string name, double defaultValue=0., bool errorIfMissing=false); static std::string GetOnelabString(std::string name, const std::string &defaultValue="", @@ -138,7 +138,7 @@ class Msg { std::map<std::string, std::vector<std::string> > &copt); static void UndefineOnelabParameter(const std::string &name); static void RunOnelabClient(const std::string &name, const std::string &exe=""); - static void SetOnelabChanged(bool value=true, const std::string &client="Gmsh"); + static void SetOnelabChanged(int value, const std::string &client="Gmsh"); static void ImportPhysicalGroupsInOnelab(); }; diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp index c5c06c45e0..831c60639f 100644 --- a/Common/OpenFile.cpp +++ b/Common/OpenFile.cpp @@ -344,11 +344,12 @@ int MergeFile(const std::string &fileName, bool warnIfMissing, bool setBoundingB if(solver.size()){ int num = defineSolver(solver); Msg::SetOnelabString(solver + "/Model name", fileName, true, true, - false, false, "file"); + false, 3, "file"); if(GModel::current()->getName() == "" || Msg::GetOnelabString("Gmsh/Model name").empty()){ GModel::current()->setFileName(split[0] + split[1] + ".geo"); GModel::current()->setName(split[1] + ".geo"); + Msg::SetOnelabChanged(3); } CTX::instance()->launchSolverAtStartup = num; CTX::instance()->geom.draw = 1; @@ -579,7 +580,7 @@ int MergePostProcessingFile(const std::string &fileName, int showViews, GModel::setCurrent(m); } // FIXME: disabled onelab physical group import for now, as the number of - // groups in mesh-bases post-pro files can be different from the # in the + // groups in mesh-based post-pro files can be different from the # in the // model, which will trigger setChanged(Gmsh), leading undesirable remeshing int ret = MergeFile(fileName, warnIfMissing, old->bounds().empty() ? true : false, false); GModel::setCurrent(old); diff --git a/Common/Options.cpp b/Common/Options.cpp index 1681ea9a63..5d61e8d0fc 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -4868,7 +4868,7 @@ double opt_mesh_optimize(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.optimize) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.optimize = (int)val; } #if defined(HAVE_FLTK) @@ -4883,7 +4883,7 @@ double opt_mesh_optimize_netgen(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.optimizeNetgen) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.optimizeNetgen = (int)val; } #if defined(HAVE_FLTK) @@ -4905,7 +4905,7 @@ double opt_mesh_refine_steps(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.refineSteps) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.refineSteps = (int)val; } return CTX::instance()->mesh.refineSteps; @@ -4973,7 +4973,7 @@ double opt_mesh_scaling_factor(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && val != CTX::instance()->mesh.scalingFactor) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.scalingFactor = val; } return CTX::instance()->mesh.scalingFactor; @@ -4984,7 +4984,7 @@ double opt_mesh_lc_factor(OPT_ARGS_NUM) if(action & GMSH_SET){ if(val > 0){ if(!(action & GMSH_SET_DEFAULT) && val != CTX::instance()->mesh.lcFactor) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.lcFactor = val; } } @@ -5000,7 +5000,7 @@ double opt_mesh_lc_min(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && val != CTX::instance()->mesh.lcMin) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.lcMin = val; } #if defined(HAVE_FLTK) @@ -5015,7 +5015,7 @@ double opt_mesh_lc_max(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && val != CTX::instance()->mesh.lcMax) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.lcMax = val; } #if defined(HAVE_FLTK) @@ -5030,7 +5030,7 @@ double opt_mesh_tolerance_edge_length(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && val != CTX::instance()->mesh.toleranceEdgeLength) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.toleranceEdgeLength = val; } return CTX::instance()->mesh.toleranceEdgeLength; @@ -5040,7 +5040,7 @@ double opt_mesh_tolerance_initial_delaunay(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && val != CTX::instance()->mesh.toleranceInitialDelaunay) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.toleranceInitialDelaunay = val; } return CTX::instance()->mesh.toleranceInitialDelaunay; @@ -5050,7 +5050,7 @@ double opt_mesh_lc_from_curvature(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.lcFromCurvature) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.lcFromCurvature = (int)val; } #if defined(HAVE_FLTK) @@ -5065,7 +5065,7 @@ double opt_mesh_lc_from_points(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.lcFromPoints) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.lcFromPoints = (int)val; } #if defined(HAVE_FLTK) @@ -5080,7 +5080,7 @@ double opt_mesh_lc_extend_from_boundary(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.lcExtendFromBoundary) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.lcExtendFromBoundary = (int)val; } #if defined(HAVE_FLTK) @@ -5095,7 +5095,7 @@ double opt_mesh_lc_integration_precision(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && val != CTX::instance()->mesh.lcIntegrationPrecision) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.lcIntegrationPrecision = val; } return CTX::instance()->mesh.lcIntegrationPrecision; @@ -5105,7 +5105,7 @@ double opt_mesh_rand_factor(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && val != CTX::instance()->mesh.randFactor) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.randFactor = val; } return CTX::instance()->mesh.randFactor; @@ -5751,7 +5751,7 @@ double opt_mesh_algo2d(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.algo2d) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.algo2d = (int)val; } #if defined(HAVE_FLTK) @@ -5786,7 +5786,7 @@ double opt_mesh_algo_recombine(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.algoRecombine) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.algoRecombine = (int)val; if(CTX::instance()->mesh.algoRecombine < 0 && CTX::instance()->mesh.algoRecombine > 1) @@ -5805,7 +5805,7 @@ double opt_mesh_recombine_all(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.recombineAll) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.recombineAll = (int)val; } #if defined(HAVE_FLTK) @@ -5820,7 +5820,7 @@ double opt_mesh_recombine3d_all(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.recombine3DAll) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.recombine3DAll = (int)val; } #if defined(HAVE_FLTK) @@ -5930,7 +5930,7 @@ double opt_mesh_algo_subdivide(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.algoSubdivide) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.algoSubdivide = (int)val; if(CTX::instance()->mesh.algoSubdivide < 0 && CTX::instance()->mesh.algoSubdivide > 2) @@ -5949,7 +5949,7 @@ double opt_mesh_algo3d(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.algo3d) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.algo3d = (int)val; } #if defined(HAVE_FLTK) @@ -5984,7 +5984,7 @@ double opt_mesh_mesh_only_visible(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.meshOnlyVisible) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.meshOnlyVisible = (int)val; } return CTX::instance()->mesh.meshOnlyVisible; @@ -5994,7 +5994,7 @@ double opt_mesh_min_circ_points(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.minCircPoints) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.minCircPoints = (int)val; } return CTX::instance()->mesh.minCircPoints; @@ -6018,7 +6018,7 @@ double opt_mesh_order(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.order) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.order = (int)val; } #if defined(HAVE_FLTK) @@ -6093,7 +6093,7 @@ double opt_mesh_second_order_linear(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.secondOrderLinear) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.secondOrderLinear = (int)val; } return CTX::instance()->mesh.secondOrderLinear; @@ -6103,7 +6103,7 @@ double opt_mesh_second_order_incomplete(OPT_ARGS_NUM) { if(action & GMSH_SET){ if(!(action & GMSH_SET_DEFAULT) && (int)val != CTX::instance()->mesh.secondOrderIncomplete) - Msg::SetOnelabChanged(); + Msg::SetOnelabChanged(2); CTX::instance()->mesh.secondOrderIncomplete = (int)val; } #if defined(HAVE_FLTK) diff --git a/Common/gmshLocalNetworkClient.cpp b/Common/gmshLocalNetworkClient.cpp index e2d5136e4f..21a3ad0758 100644 --- a/Common/gmshLocalNetworkClient.cpp +++ b/Common/gmshLocalNetworkClient.cpp @@ -399,7 +399,7 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master) } else if(command == "set"){ std::string changed = onelab::parameter::getNextToken(message, first); - onelab::server::instance()->setChanged(changed=="true"?true:false,name); + onelab::server::instance()->setChanged(changed == "true" ? 31 : 0, name); } } break; @@ -767,6 +767,9 @@ void resetDb(bool runGmshClient) persistentStrings[i].getName().c_str()); onelab::server::instance()->set(persistentStrings[i]); } + + // mark all parameters as changed + onelab::server::instance()->setChanged(3); } void solver_batch_cb(void *data) @@ -842,7 +845,7 @@ void solver_batch_cb(void *data) o.setValue("compute"); onelab::server::instance()->set(o); c->run(); - onelab::server::instance()->setChanged(false, c->getName()); + onelab::server::instance()->setChanged(0, c->getName()); } } while(incrementLoops()); diff --git a/Common/onelab.h b/Common/onelab.h index 025e605c85..49b4e724c0 100644 --- a/Common/onelab.h +++ b/Common/onelab.h @@ -54,12 +54,16 @@ namespace onelab{ // a help string std::string _help; // map of clients that use this parameter, associated with a "changed" flag - // (set to false if the client has already been run with the current value of - // the parameter) - std::map<std::string, bool> _clients; - // flag indicating that the "changed" flags of this parameter will always be - // reset to false when the parameter is updated - bool _neverChanged; + // (set to 0 if the client has already been run with the current value of + // the parameter; set to defaultChangedValue() when the value of a parameter + // has been changed; values between 1 and defaultChangedValue() can be used + // to "modulate" the degree of change, e.g. to change the action to be + // performed depending on the "severity" of the change) + std::map<std::string, int> _clients; + // flag indicating what the "changed" value should be set to when a + // parameter is updated to a different value (if set to 0, the parameter + // will appear as never being changed) + int _changedValue; // should the parameter be visible in the interface? bool _visible; // sould the paramete be "read-only" (not settable by the user) @@ -70,25 +74,32 @@ namespace onelab{ public: parameter(const std::string &name="", const std::string &label="", const std::string &help="") - : _name(name), _label(label), _help(help), _neverChanged(false), - _visible(true), _readOnly(false) {} + : _name(name), _label(label), _help(help), _visible(true), + _readOnly(false) + { + _changedValue = defaultChangedValue(); + } virtual ~parameter(){} void setName(const std::string &name){ _name = name; } void setLabel(const std::string &label){ _label = label; } void setHelp(const std::string &help){ _help = help; } - void setChanged(bool changed, const std::string &client="") + void setChanged(int changed, const std::string &client="") { if(client.size()){ - std::map<std::string, bool>::iterator it = _clients.find(client); + std::map<std::string, int>::iterator it = _clients.find(client); if(it != _clients.end()) it->second = changed; } else{ - for(std::map<std::string, bool>::iterator it = _clients.begin(); + for(std::map<std::string, int>::iterator it = _clients.begin(); it != _clients.end(); it++) it->second = changed; } } - void setNeverChanged(bool never){ _neverChanged = never; } + void setChangedValue(int value){ _changedValue = value; } + void setNeverChanged(bool never) + { + _changedValue = never ? 0 : defaultChangedValue(); + } void setVisible(bool visible){ _visible = visible; } void setReadOnly(bool readOnly){ _readOnly = readOnly; } void setAttribute(const std::string &key, const std::string &value) @@ -99,13 +110,13 @@ namespace onelab{ { _attributes = attributes; } - void setClients(const std::map<std::string, bool> &clients){ _clients = clients; } - void addClient(const std::string &client, bool changed) + void setClients(const std::map<std::string, int> &clients){ _clients = clients; } + void addClient(const std::string &client, int changed) { if(_clients.find(client) == _clients.end()) _clients[client] = changed; } - void addClients(const std::map<std::string, bool> &clients) + void addClients(const std::map<std::string, int> &clients) { _clients.insert(clients.begin(), clients.end()); } @@ -144,22 +155,24 @@ namespace onelab{ s = s.substr(1); return s; } - bool getChanged(const std::string &client="") const + int getChanged(const std::string &client="") const { if(client.size()){ - std::map<std::string, bool>::const_iterator it = _clients.find(client); + std::map<std::string, int>::const_iterator it = _clients.find(client); if(it != _clients.end()) return it->second; - else return false; + else return 0; } else{ - for(std::map<std::string, bool>::const_iterator it = _clients.begin(); + int changed = 0; + for(std::map<std::string, int>::const_iterator it = _clients.begin(); it != _clients.end(); it++){ - if(it->second) return true; + changed = std::max(changed, it->second); } - return false; + return changed; } } - bool getNeverChanged() const { return _neverChanged; } + int getChangedValue() const { return _changedValue; } + bool getNeverChanged() const { return _changedValue ? false : true; } bool getVisible() const { return _visible; } bool getReadOnly() const { return _readOnly; } std::string getAttribute(const std::string &key) const @@ -172,10 +185,11 @@ namespace onelab{ { return _attributes; } - const std::map<std::string, bool> &getClients() const { return _clients; } + const std::map<std::string, int> &getClients() const { return _clients; } static char charSep() { return '\0'; } static double maxNumber() { return 1e200; } static std::string version() { return "1.1"; } + static int defaultChangedValue() { return 31; } static std::string getNextToken(const std::string &msg, std::string::size_type &first, char separator=charSep()) @@ -220,7 +234,7 @@ namespace onelab{ << sanitize(getName()) << charSep() << sanitize(getLabel()) << charSep() << sanitize(getHelp()) << charSep() - << (getNeverChanged() ? 1 : 0) << charSep() + << getChangedValue() << charSep() << (getVisible() ? 1 : 0) << charSep() << (getReadOnly() ? 1 : 0) << charSep() << _attributes.size() << charSep(); @@ -229,7 +243,7 @@ namespace onelab{ sstream << sanitize(it->first) << charSep() << sanitize(it->second) << charSep(); sstream << getClients().size() << charSep(); - for(std::map<std::string, bool>::const_iterator it = getClients().begin(); + for(std::map<std::string, int>::const_iterator it = getClients().begin(); it != getClients().end(); it++) sstream << sanitize(it->first) << charSep() << (it->second ? 1 : 0) << charSep(); @@ -243,7 +257,7 @@ namespace onelab{ setName(getNextToken(msg, pos)); setLabel(getNextToken(msg, pos)); setHelp(getNextToken(msg, pos)); - setNeverChanged(atoi(getNextToken(msg, pos).c_str())); + setChangedValue(atoi(getNextToken(msg, pos).c_str())); setVisible(atoi(getNextToken(msg, pos).c_str())); setReadOnly(atoi(getNextToken(msg, pos).c_str())); int numAttributes = atoi(getNextToken(msg, pos).c_str()); @@ -255,7 +269,7 @@ namespace onelab{ for(int i = 0; i < numClients; i++){ std::string client(getNextToken(msg, pos)); int changed = atoi(getNextToken(msg, pos).c_str()); - addClient(client, changed ? true : false); + addClient(client, changed); } return pos; } @@ -307,7 +321,7 @@ namespace onelab{ << ", \"name\":\"" << sanitize(getName()) << "\"" << ", \"label\":\"" << sanitize(getLabel()) << "\"" << ", \"help\":\"" << sanitize(getHelp()) << "\"" - << ", \"neverChanged\":" << (getNeverChanged() ? "true" : "false") + << ", \"changedValue\":" << getChangedValue() << "\"" << ", \"visible\":" << (getVisible() ? "true" : "false") << ", \"readOnly\":" << (getReadOnly() ? "true" : "false"); sstream << ", \"attributes\":{ "; @@ -319,7 +333,7 @@ namespace onelab{ } sstream << " }"; sstream << ", \"clients\":{ "; - for(std::map<std::string, bool>::const_iterator it = getClients().begin(); + for(std::map<std::string, int>::const_iterator it = getClients().begin(); it != getClients().end(); it++){ if(it != getClients().begin()) sstream << ", "; sstream << "\"" << sanitize(it->first) << "\":" @@ -401,7 +415,7 @@ namespace onelab{ setAttributes(p.getAttributes()); if(p.getValue() != getValue()){ setValue(p.getValue()); - setChanged(true); + setChanged(getChangedValue()); } setMin(p.getMin()); setMax(p.getMax()); @@ -409,7 +423,7 @@ namespace onelab{ setIndex(p.getIndex()); setChoices(p.getChoices()); setValueLabels(p.getValueLabels()); - if(getNeverChanged()) setChanged(false); + if(getNeverChanged()) setChanged(0); } std::string toChar() const { @@ -508,14 +522,14 @@ namespace onelab{ setAttributes(p.getAttributes()); if(p.getValue() != getValue()){ setValue(p.getValue()); - setChanged(true); + setChanged(getChangedValue()); } if(p.getKind() != getKind()){ setKind(p.getKind()); - setChanged(true); + setChanged(getChangedValue()); } setChoices(p.getChoices()); - if(getNeverChanged()) setChanged(false); + if(getNeverChanged()) setChanged(0); } std::string toChar() const { @@ -709,21 +723,20 @@ namespace onelab{ } // check if some parameters have changed (optionnally only check the // parameters that depend on a given client) - bool getChanged(const std::string &client="") const + int getChanged(const std::string &client="") const { std::set<parameter*, parameterLessThan> ps; _getAllParameters(ps); + int changed = 0; for(std::set<parameter*, parameterLessThan>::iterator it = ps.begin(); it != ps.end(); it++){ - if((*it)->getChanged(client)){ - return true; - } + changed = std::max(changed, (*it)->getChanged(client)); } - return false; + return changed; } // set the changed flag for all the parameters that depend on the given // client (or for all parameters if no client name is provided) - void setChanged(bool changed, const std::string &client="") + void setChanged(int changed, const std::string &client="") { std::set<parameter*, parameterLessThan> ps; _getAllParameters(ps); @@ -731,6 +744,17 @@ namespace onelab{ it != ps.end(); it++) (*it)->setChanged(changed, client); } + void thresholdChanged(int threshold, const std::string &client="") + { + std::set<parameter*, parameterLessThan> ps; + _getAllParameters(ps); + for(std::set<parameter*, parameterLessThan>::iterator it = ps.begin(); + it != ps.end(); it++){ + int changed = (*it)->getChanged(client); + if(changed > threshold) + (*it)->setChanged(threshold, client); + } + } // serialize the parameter space (optionally only serialize those parameters // that depend on the given client) std::vector<std::string> toChar(const std::string &client="") const @@ -911,14 +935,18 @@ namespace onelab{ c->setId(_clients.size()); } void unregisterClient(client *c){ _clients.erase(c); } - void setChanged(bool changed, const std::string &client="") + void setChanged(int changed, const std::string &client="") { _parameterSpace.setChanged(changed, client); } - bool getChanged(const std::string &client="") + int getChanged(const std::string &client="") { return _parameterSpace.getChanged(client); } + void thresholdChanged(int value, const std::string &client="") + { + _parameterSpace.thresholdChanged(value, client); + } unsigned int getNumParameters(){ return _parameterSpace.getNumParameters(); } std::vector<std::string> toChar(const std::string &client="") { diff --git a/Common/onelabUtils.cpp b/Common/onelabUtils.cpp index 6b808fd7e9..ac89154ea5 100644 --- a/Common/onelabUtils.cpp +++ b/Common/onelabUtils.cpp @@ -337,9 +337,13 @@ namespace onelabUtils { onelab::client *c = *it; std::string mshFileName = onelabUtils::getMshFileName(c); - Msg::SetOnelabAction(action); + int changed = onelab::server::instance()->getChanged("Gmsh"); + // if = 0: do nothing + // = 1: only save mesh (e.g. if physiscals changed) + // = 2: mesh and save mesh (e.g. if char length changed) + // > 2: reload geometry, mesh and save mesh (other things have changed) - static std::string modelName = GModel::current()->getName(); + Msg::SetOnelabAction(action); if(action == "initialize"){ // nothing to do @@ -349,30 +353,29 @@ namespace onelabUtils { // nothing more to do: "check" will be called right afterwards } else 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(); + if(changed > 2){ redraw = true; OpenProject(GModel::current()->getFileName()); + onelab::server::instance()->thresholdChanged(2, "Gmsh"); } } 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(); + if(changed){ redraw = true; - OpenProject(GModel::current()->getFileName()); + if(changed > 2){ + OpenProject(GModel::current()->getFileName()); + } if(getFirstComputationFlag() && !StatFile(mshFileName) && meshAuto != 2){ Msg::Info("Skipping mesh generation: assuming '%s' is up-to-date " "(use Solver.AutoMesh=2 to force mesh generation)", mshFileName.c_str()); } else if(!GModel::current()->empty() && meshAuto){ - GModel::current()->mesh(3); + if(changed > 1 || StatFile(mshFileName) || + (!StatFile(mshFileName) && + GModel::current()->getMeshStatus() < GModel::current()->getDim())){ + GModel::current()->mesh(3); + } CreateOutputFile(mshFileName, CTX::instance()->mesh.fileFormat); } } @@ -380,12 +383,15 @@ namespace onelabUtils { // mesh+save if the mesh file does not exist if(meshAuto){ redraw = true; - GModel::current()->mesh(3); + if(changed > 1 || + GModel::current()->getMeshStatus() < GModel::current()->getDim()){ + GModel::current()->mesh(3); + } CreateOutputFile(mshFileName, CTX::instance()->mesh.fileFormat); } } setFirstComputationFlag(false); - onelab::server::instance()->setChanged(false, "Gmsh"); + onelab::server::instance()->setChanged(0, "Gmsh"); } Msg::SetOnelabAction(""); diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp index 4f3d8f32db..c55f76908b 100644 --- a/Fltk/graphicWindow.cpp +++ b/Fltk/graphicWindow.cpp @@ -505,6 +505,7 @@ static void file_rename_cb(Fl_Widget *w, void *data) rename(GModel::current()->getFileName().c_str(), name.c_str()); GModel::current()->setFileName(name); GModel::current()->setName(SplitFileName(name)[1]); + Msg::SetOnelabChanged(3); if(onelabUtils::haveSolverToRun()) onelab_cb(0, (void*)"check"); drawContext::global()->draw(); diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 8e8a5eafe6..4157e80cfd 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -123,10 +123,10 @@ void GModel::setFileName(std::string fileName) { _fileName = fileName; _fileNames.insert(fileName); - Msg::SetOnelabString("Gmsh/Model name", fileName, false, false, true, true); + Msg::SetOnelabString("Gmsh/Model name", fileName, false, false, true, 0); Msg::SetOnelabString ("Gmsh/Model absolute path", SplitFileName(GetAbsolutePath(fileName))[0], - false, false, true, true); + false, false, true, 0); Msg::SetWindowTitle(fileName); } diff --git a/Geo/GeoStringInterface.cpp b/Geo/GeoStringInterface.cpp index 3da2542988..885079b694 100644 --- a/Geo/GeoStringInterface.cpp +++ b/Geo/GeoStringInterface.cpp @@ -139,11 +139,20 @@ void add_infile(const std::string &text, const std::string &fileName, bool force Msg::Error("GEO file creation not available without Gmsh parser"); #endif - // mark all Gmsh data as changed in onelab (will force e.g. a reload and a - // remesh) -#if defined(HAVE_ONELAB) - onelab::server::instance()->setChanged(true, "Gmsh"); -#endif + // mark Gmsh data as changed in onelab + if(text.find("Physical") != std::string::npos){ + // re-import the physical groups in onelab, and only ask to re-save the mesh + Msg::ImportPhysicalGroupsInOnelab(); + Msg::SetOnelabChanged(1); + } + else if(text.find("Characteristic") != std::string::npos){ + // only ask to remesh and re-save + Msg::SetOnelabChanged(2); + } + else{ + // ask to reload the geometry, remesh and re-save + Msg::SetOnelabChanged(3); + } } void coherence(const std::string &fileName) -- GitLab