Salome HOME
COTECH: Update names of DISTENE products
[plugins/ghs3dplugin.git] / src / GHS3DPlugin / GHS3DPlugin_Hypothesis.cxx
index 4deccaa92c86ecd15d1385f6092c4cec6cbed7a5..f9f4e4d65aa9b5301905b488cb12eff37a23ea0d 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2004-2012  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2014  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -30,7 +30,7 @@
 
 #include <TCollection_AsciiString.hxx>
 
-#ifdef WNT
+#ifdef WIN32
 #include <process.h>
 #define getpid _getpid
 #endif
@@ -42,6 +42,7 @@
 GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen)
   : SMESH_Hypothesis(hypId, studyId, gen),
   myToMeshHoles(DefaultMeshHoles()),
+  myToMakeGroupsOfDomains(DefaultToMakeGroupsOfDomains()),
   myMaximumMemory(-1),
   myInitialMemory(-1),
   myOptimizationLevel(DefaultOptimizationLevel()),
@@ -53,6 +54,7 @@ GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen
   myToUseFemCorrection(DefaultToUseFEMCorrection()),
   myToRemoveCentralPoint(DefaultToRemoveCentralPoint()),
   myGradation(DefaultGradation()),
+  myLogInStandardOutput(DefaultStandardOutputLog()),
   _enfVertexList(DefaultGHS3DEnforcedVertexList()),
   _enfVertexCoordsSizeList(DefaultGHS3DEnforcedVertexCoordsValues()),
   _enfVertexEntrySizeList(DefaultGHS3DEnforcedVertexEntryValues()),
@@ -66,7 +68,7 @@ GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen
   _nodeIDToSizeMap(DefaultID2SizeMap()),
   _groupsToRemove(DefaultGroupsToRemove())
 {
-  _name = "GHS3D_Parameters";
+  _name = GetHypType();
   _param_algo_dim = 3;
 }
 
@@ -97,11 +99,44 @@ bool GHS3DPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const
   return myToMeshHoles;
 }
 
+//=======================================================================
+//function : SetToMakeGroupsOfDomains
+//=======================================================================
+
+void GHS3DPlugin_Hypothesis::SetToMakeGroupsOfDomains(bool toMakeGroups)
+{
+  if ( myToMakeGroupsOfDomains != toMakeGroups ) {
+    myToMakeGroupsOfDomains = toMakeGroups;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+//=======================================================================
+//function : GetToMakeGroupsOfDomains
+//=======================================================================
+
+bool GHS3DPlugin_Hypothesis::GetToMakeGroupsOfDomains() const
+{
+  return myToMakeGroupsOfDomains;
+}
+
+//=======================================================================
+//function : GetToMakeGroupsOfDomains
+//=======================================================================
+
+bool GHS3DPlugin_Hypothesis::GetToMakeGroupsOfDomains(const GHS3DPlugin_Hypothesis* hyp)
+{
+  bool res;
+  if ( hyp ) res = /*hyp->GetToMeshHoles(true) &&*/ hyp->GetToMakeGroupsOfDomains();
+  else       res = /*DefaultMeshHoles()        &&*/ DefaultToMakeGroupsOfDomains();
+  return res;
+}
+
 //=======================================================================
 //function : SetMaximumMemory
 //=======================================================================
 
-void GHS3DPlugin_Hypothesis::SetMaximumMemory(short MB)
+void GHS3DPlugin_Hypothesis::SetMaximumMemory(double MB)
 {
   if ( myMaximumMemory != MB ) {
     myMaximumMemory = MB;
@@ -114,7 +149,7 @@ void GHS3DPlugin_Hypothesis::SetMaximumMemory(short MB)
 //           * automatic memory adjustment mode. Default is zero
 //=======================================================================
 
-short GHS3DPlugin_Hypothesis::GetMaximumMemory() const
+double GHS3DPlugin_Hypothesis::GetMaximumMemory() const
 {
   return myMaximumMemory;
 }
@@ -123,7 +158,7 @@ short GHS3DPlugin_Hypothesis::GetMaximumMemory() const
 //function : SetInitialMemory
 //=======================================================================
 
-void GHS3DPlugin_Hypothesis::SetInitialMemory(short MB)
+void GHS3DPlugin_Hypothesis::SetInitialMemory(double MB)
 {
   if ( myInitialMemory != MB ) {
     myInitialMemory = MB;
@@ -135,7 +170,7 @@ void GHS3DPlugin_Hypothesis::SetInitialMemory(short MB)
 //function : GetInitialMemory
 //=======================================================================
 
-short GHS3DPlugin_Hypothesis::GetInitialMemory() const
+double GHS3DPlugin_Hypothesis::GetInitialMemory() const
 {
   return myInitialMemory;
 }
@@ -350,6 +385,48 @@ double GHS3DPlugin_Hypothesis::GetGradation() const
   return myGradation;
 }
 
+//=======================================================================
+//function : SetStandardOutputLog
+//=======================================================================
+
+void GHS3DPlugin_Hypothesis::SetStandardOutputLog(bool logInStandardOutput)
+{
+  if ( myLogInStandardOutput != logInStandardOutput ) {
+    myLogInStandardOutput = logInStandardOutput;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+//=======================================================================
+//function : GetStandardOutputLog
+//=======================================================================
+
+bool GHS3DPlugin_Hypothesis::GetStandardOutputLog() const
+{
+  return myLogInStandardOutput;
+}
+
+//=======================================================================
+//function : SetRemoveLogOnSuccess
+//=======================================================================
+
+void GHS3DPlugin_Hypothesis::SetRemoveLogOnSuccess(bool removeLogOnSuccess)
+{
+  if ( myRemoveLogOnSuccess != removeLogOnSuccess ) {
+    myRemoveLogOnSuccess = removeLogOnSuccess;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+//=======================================================================
+//function : GetRemoveLogOnSuccess
+//=======================================================================
+
+bool GHS3DPlugin_Hypothesis::GetRemoveLogOnSuccess() const
+{
+  return myRemoveLogOnSuccess;
+}
+
 //=======================================================================
 //function : SetEnforcedVertex
 //=======================================================================
@@ -450,16 +527,20 @@ bool GHS3DPlugin_Hypothesis::SetEnforcedMesh(SMESH_Mesh& theMesh, SMESH::Element
   bool added = SetEnforcedElements( theElemSet, elementType, groupName);
   if (added) {
     TGHS3DEnforcedMesh* newEnfMesh = new TGHS3DEnforcedMesh();
-    newEnfMesh->name = name;
-    newEnfMesh->entry = entry;
+    newEnfMesh->persistID   = theMesh.GetMeshDS()->GetPersistentId();
+    newEnfMesh->name        = name;
+    newEnfMesh->entry       = entry;
     newEnfMesh->elementType = elementType;
-    newEnfMesh->groupName = groupName;
+    newEnfMesh->groupName   = groupName;
     
     TGHS3DEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
     if (it == _enfMeshList.end()) {
       _entryEnfMeshMap[entry].insert(newEnfMesh);
       _enfMeshList.insert(newEnfMesh);
     }
+    else {
+      delete newEnfMesh;
+    }
   }
   return added;
 }
@@ -712,6 +793,26 @@ void GHS3DPlugin_Hypothesis::ClearEnforcedMeshes()
   NotifySubMeshesHypothesisModification();
 }
 
+//================================================================================
+/*!
+ * \brief At mesh loading, restore enforced elements by just loaded enforced meshes
+ */
+//================================================================================
+
+void GHS3DPlugin_Hypothesis::RestoreEnfElemsByMeshes()
+{
+  TGHS3DEnforcedMeshList::const_iterator it = _enfMeshList.begin();
+  for(;it != _enfMeshList.end();++it) {
+    TGHS3DEnforcedMesh* enfMesh = *it;
+    if ( SMESH_Mesh* mesh = GetMeshByPersistentID( enfMesh->persistID ))
+      SetEnforcedMesh( *mesh,
+                       enfMesh->elementType,
+                       enfMesh->name,
+                       enfMesh->entry,
+                       enfMesh->groupName );
+    enfMesh->persistID = -1; // not to restore again
+  }
+}
 
 //=======================================================================
 //function : SetGroupsToRemove
@@ -732,6 +833,15 @@ bool GHS3DPlugin_Hypothesis::DefaultMeshHoles()
   return false; // PAL19680
 }
 
+//=======================================================================
+//function : DefaultToMakeGroupsOfDomains
+//=======================================================================
+
+bool GHS3DPlugin_Hypothesis::DefaultToMakeGroupsOfDomains()
+{
+  return false; // issue 0022172
+}
+
 //=======================================================================
 //function : DefaultMaximumMemory
 //=======================================================================
@@ -742,14 +852,14 @@ bool GHS3DPlugin_Hypothesis::DefaultMeshHoles()
 #include <windows.h>
 #endif
 
-short  GHS3DPlugin_Hypothesis::DefaultMaximumMemory()
+double  GHS3DPlugin_Hypothesis::DefaultMaximumMemory()
 {
 #ifndef WIN32
   struct sysinfo si;
   int err = sysinfo( &si );
   if ( err == 0 ) {
     int ramMB = si.totalram * si.mem_unit / 1024 / 1024;
-    return (int) ( 0.7 * ramMB );
+    return ( 0.7 * ramMB );
   }
 #else
   // See http://msdn.microsoft.com/en-us/library/aa366589.aspx
@@ -761,7 +871,7 @@ short  GHS3DPlugin_Hypothesis::DefaultMaximumMemory()
       statex.ullTotalPhys / 1024 / 1024 +
       statex.ullTotalPageFile / 1024 / 1024 +
       statex.ullTotalVirtual / 1024 / 1024;
-    return (int) ( 0.7 * totMB );
+    return ( 0.7 * totMB );
   }
 #endif
   return 1024;
@@ -771,7 +881,7 @@ short  GHS3DPlugin_Hypothesis::DefaultMaximumMemory()
 //function : DefaultInitialMemory
 //=======================================================================
 
-short  GHS3DPlugin_Hypothesis::DefaultInitialMemory()
+double  GHS3DPlugin_Hypothesis::DefaultInitialMemory()
 {
   return DefaultMaximumMemory();
 }
@@ -816,6 +926,16 @@ bool   GHS3DPlugin_Hypothesis::DefaultKeepFiles()
   return false;
 }
 
+//=======================================================================
+//function : DefaultRemoveLogOnSuccess
+//=======================================================================
+
+bool   GHS3DPlugin_Hypothesis::DefaultRemoveLogOnSuccess()
+{
+  return false;
+}
+
+
 //=======================================================================
 //function : DefaultVerboseLevel
 //=======================================================================
@@ -870,6 +990,15 @@ double GHS3DPlugin_Hypothesis::DefaultGradation()
   return 1.05;
 }
 
+//=======================================================================
+//function : DefaultStandardOutputLog
+//=======================================================================
+
+bool GHS3DPlugin_Hypothesis::DefaultStandardOutputLog()
+{
+  return false;
+}
+
 // //=======================================================================
 // //function : DefaultID2SizeMap
 // //=======================================================================
@@ -898,6 +1027,7 @@ std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save)
   save << (int)myToUseFemCorrection           << " ";
   save << (int)myToRemoveCentralPoint         << " ";
   save << myGradation                         << " ";
+  save << myToMakeGroupsOfDomains             << " ";
   if (!myTextOption.empty()) {
     save << "__OPTIONS_BEGIN__ ";
     save << myTextOption                      << " ";
@@ -965,6 +1095,8 @@ std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save)
         save << " " << enfMesh->groupName;
         save << " " << "__END_GROUP__";
       }
+      save << " " << "__PERSIST_ID__";
+      save << " " << enfMesh->persistID;
       save << " " << "__END_ENF_MESH__";
       std::cout << "Saving of enforced mesh " << enfMesh->name.c_str() << " done" << std::endl;
     }
@@ -979,303 +1111,316 @@ std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save)
 
 std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load)
 {
-       bool isOK = true;
-       int i;
-    double d;
-
-       isOK = (load >> i);
-       if (isOK)
-               myToMeshHoles = i;
-       else
-               load.clear(ios::badbit | load.rdstate());
-
-       isOK = (load >> i);
-       if (isOK)
-               myMaximumMemory = i;
-       else
-               load.clear(ios::badbit | load.rdstate());
-
-       isOK = (load >> i);
-       if (isOK)
-               myInitialMemory = i;
-       else
-               load.clear(ios::badbit | load.rdstate());
-
-       isOK = (load >> i);
-       if (isOK)
-               myOptimizationLevel = i;
-       else
-               load.clear(ios::badbit | load.rdstate());
-
-       isOK = (load >> myWorkingDirectory);
-       if (isOK) {
-               if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty
-                       myKeepFiles = false;
-                       myWorkingDirectory.clear();
-               }
-               else if ( myWorkingDirectory == "1" ) {
-                       myKeepFiles = true;
-                       myWorkingDirectory.clear();
-               }
-       }
-       else
-               load.clear(ios::badbit | load.rdstate());
-
-       if ( !myWorkingDirectory.empty() ) {
-               isOK = (load >> i);
-               if (isOK)
-                       myKeepFiles = i;
-               else
-                       load.clear(ios::badbit | load.rdstate());
-       }
-
-       isOK = (load >> i);
-       if (isOK)
-               myVerboseLevel = (short) i;
-       else
-               load.clear(ios::badbit | load.rdstate());
-
-       isOK = (load >> i);
-       if (isOK)
-               myToCreateNewNodes = (bool) i;
-       else
-               load.clear(ios::badbit | load.rdstate());
-
-       isOK = (load >> i);
-       if (isOK)
-               myToUseBoundaryRecoveryVersion = (bool) i;
-       else
-               load.clear(ios::badbit | load.rdstate());
-
-       isOK = (load >> i);
-       if (isOK)
-               myToUseFemCorrection = (bool) i;
-       else
-               load.clear(ios::badbit | load.rdstate());
-
-       isOK = (load >> i);
-       if (isOK)
-               myToRemoveCentralPoint = (bool) i;
-       else
-               load.clear(ios::badbit | load.rdstate());
-
-    isOK = (load >> d);
+  bool isOK = true;
+  int i;
+  double d;
+
+  isOK = (load >> i);
+  if (isOK)
+    myToMeshHoles = i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+
+  isOK = (load >> d);
+  if (isOK)
+    myMaximumMemory = d;
+  else
+    load.clear(ios::badbit | load.rdstate());
+
+  isOK = (load >> d);
+  if (isOK)
+    myInitialMemory = d;
+  else
+    load.clear(ios::badbit | load.rdstate());
+
+  isOK = (load >> i);
+  if (isOK)
+    myOptimizationLevel = i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+
+  isOK = (load >> myWorkingDirectory);
+  if (isOK) {
+    if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty
+      myKeepFiles = false;
+      myWorkingDirectory.clear();
+    }
+    else if ( myWorkingDirectory == "1" ) {
+      myKeepFiles = true;
+      myWorkingDirectory.clear();
+    }
+  }
+  else
+    load.clear(ios::badbit | load.rdstate());
+
+  if ( !myWorkingDirectory.empty() ) {
+    isOK = (load >> i);
     if (isOK)
-        myGradation = d;
+      myKeepFiles = i;
     else
-        load.clear(ios::badbit | load.rdstate());
-
-       std::string separator;
-       bool hasOptions = false;
-       bool hasEnforcedVertices = false;
-       bool hasEnforcedMeshes = false;
-       isOK = (load >> separator);
-
-       if (isOK) {
-               if (separator == "__OPTIONS_BEGIN__")
-                       hasOptions = true;
-               else if (separator == "__ENFORCED_VERTICES_BEGIN__")
-                       hasEnforcedVertices = true;
-               else if (separator == "__ENFORCED_MESHES_BEGIN__")
-                       hasEnforcedMeshes = true;
-       }
-
-       if (hasOptions) {
-               std::string txt;
-               while (isOK) {
-                       isOK = (load >> txt);
-                       if (isOK) {
-                               if (txt == "__OPTIONS_END__") {
-                                       if (!myTextOption.empty()) {
-                                               // Remove last space
-                                               myTextOption.erase(myTextOption.end()-1);
-                                       }
-                                       isOK = false;
-                                       break;
-                               }
-                               myTextOption += txt;
-                               myTextOption += " ";
-                       }
-               }
-       }
-
-       if (hasOptions) {
-               isOK = (load >> separator);
-               if (isOK && separator == "__ENFORCED_VERTICES_BEGIN__")
-                       hasEnforcedVertices = true;
-               if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
-                       hasEnforcedMeshes = true;
-       }
+      load.clear(ios::badbit | load.rdstate());
+  }
+
+  isOK = (load >> i);
+  if (isOK)
+    myVerboseLevel = (short) i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+
+  isOK = (load >> i);
+  if (isOK)
+    myToCreateNewNodes = (bool) i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+
+  isOK = (load >> i);
+  if (isOK)
+    myToUseBoundaryRecoveryVersion = (bool) i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+
+  isOK = (load >> i);
+  if (isOK)
+    myToUseFemCorrection = (bool) i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+
+  isOK = (load >> i);
+  if (isOK)
+    myToRemoveCentralPoint = (bool) i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+
+  isOK = (load >> d);
+  if (isOK)
+    myGradation = d;
+  else
+    load.clear(ios::badbit | load.rdstate());
+
+  std::string separator;
+  bool hasOptions = false;
+  bool hasEnforcedVertices = false;
+  bool hasEnforcedMeshes = false;
+  isOK = (load >> separator);
+
+  if ( isOK && ( separator == "0" || separator == "1" ))
+  {
+    myToMakeGroupsOfDomains = ( separator == "1" );
+    isOK = (load >> separator);
+  }
+
+  if (isOK) {
+    if (separator == "__OPTIONS_BEGIN__")
+      hasOptions = true;
+    else if (separator == "__ENFORCED_VERTICES_BEGIN__")
+      hasEnforcedVertices = true;
+    else if (separator == "__ENFORCED_MESHES_BEGIN__")
+      hasEnforcedMeshes = true;
+  }
+
+  if (hasOptions) {
+    std::string txt;
+    while (isOK) {
+      isOK = (load >> txt);
+      if (isOK) {
+        if (txt == "__OPTIONS_END__") {
+          if (!myTextOption.empty()) {
+            // Remove last space
+            myTextOption.erase(myTextOption.end()-1);
+          }
+          isOK = false;
+          break;
+        }
+        myTextOption += txt;
+        myTextOption += " ";
+      }
+    }
+  }
+
+  if (hasOptions) {
+    isOK = (load >> separator);
+    if (isOK && separator == "__ENFORCED_VERTICES_BEGIN__")
+      hasEnforcedVertices = true;
+    if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
+      hasEnforcedMeshes = true;
+  }
 
   if (hasEnforcedVertices) {
-         std::string txt, name, entry, groupName;
-         double size, coords[3];
-         bool isCompound;
-         bool hasCoords = false;
-         isOK = (load >> txt);  // __BEGIN_VERTEX__
-         while (isOK) {
-           if (txt == "__ENFORCED_VERTICES_END__")
-             isOK = false;
-
-           TGHS3DEnforcedVertex *enfVertex = new TGHS3DEnforcedVertex();
-           while (isOK) {
-             isOK = (load >> txt);
-             if (txt == "__END_VERTEX__") {
-               enfVertex->name = name;
-               enfVertex->geomEntry = entry;
-               enfVertex->isCompound = isCompound;
-               enfVertex->groupName = groupName;
-               enfVertex->coords.clear();
-               if (hasCoords)
-                 enfVertex->coords.assign(coords,coords+3);
-
-               _enfVertexList.insert(enfVertex);
-
-               if (enfVertex->coords.size())
-                 _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
-               if (!enfVertex->geomEntry.empty())
-                 _geomEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
-
-               name.clear();
-               entry.clear();
-               groupName.clear();
-               hasCoords = false;
-               isOK = false;
-             }
-
-             if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
-               while (isOK && (txt != "__END_NAME__")) {
-                 isOK = (load >> txt);
-                 if (txt != "__END_NAME__") {
-                   if (!name.empty())
-                     name += " ";
-                   name += txt;
-                 }
-               }
-               MESSAGE("name: " <<name);
-             }
-
-             if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
-               isOK = (load >> entry);
-               isOK = (load >> isCompound);
-               isOK = (load >> txt); // __END_ENTRY__
-               if (txt != "__END_ENTRY__")
-                 throw std::exception();
-               MESSAGE("entry: " << entry);
-             }
-
-             if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
-               while (isOK && (txt != "__END_GROUP__")) {
-                 isOK = (load >> txt);
-                 if (txt != "__END_GROUP__") {
-                   if (!groupName.empty())
-                     groupName += " ";
-                   groupName += txt;
-                 }
-               }
-               MESSAGE("groupName: " << groupName);
-             }
-
-             if (txt == "__BEGIN_COORDS__") {  // __BEGIN_COORDS__
-               hasCoords = true;
-               isOK = (load >> coords[0] >> coords[1] >> coords[2]);
-               isOK = (load >> txt); // __END_COORDS__
-               if (txt != "__END_COORDS__")
-                 throw std::exception();
-               MESSAGE("coords: " << coords[0] <<","<< coords[1] <<","<< coords[2]);
-             }
-
-             if (txt == "__BEGIN_SIZE__") {  // __BEGIN_ENTRY__
-               isOK = (load >> size);
-               isOK = (load >> txt); // __END_ENTRY__
-               if (txt != "__END_SIZE__") {
-                 throw std::exception();
-               }
-               MESSAGE("size: " << size);
-             }
-           }
-           isOK = (load >> txt);  // __BEGIN_VERTEX__
-         }
+    std::string txt, name, entry, groupName;
+    double size, coords[3];
+    bool isCompound;
+    bool hasCoords = false;
+    isOK = (load >> txt);  // __BEGIN_VERTEX__
+    while (isOK) {
+      if (txt == "__ENFORCED_VERTICES_END__")
+        isOK = false;
+
+      TGHS3DEnforcedVertex *enfVertex = new TGHS3DEnforcedVertex();
+      while (isOK) {
+        isOK = (load >> txt);
+        if (txt == "__END_VERTEX__") {
+          enfVertex->name = name;
+          enfVertex->geomEntry = entry;
+          enfVertex->isCompound = isCompound;
+          enfVertex->groupName = groupName;
+          enfVertex->coords.clear();
+          if (hasCoords)
+            enfVertex->coords.assign(coords,coords+3);
+
+          _enfVertexList.insert(enfVertex);
+
+          if (enfVertex->coords.size())
+            _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
+          if (!enfVertex->geomEntry.empty())
+            _geomEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
+
+          name.clear();
+          entry.clear();
+          groupName.clear();
+          hasCoords = false;
+          isOK = false;
+        }
+
+        if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
+          while (isOK && (txt != "__END_NAME__")) {
+            isOK = (load >> txt);
+            if (txt != "__END_NAME__") {
+              if (!name.empty())
+                name += " ";
+              name += txt;
+            }
+          }
+          MESSAGE("name: " <<name);
+        }
+
+        if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
+          isOK = (load >> entry);
+          isOK = (load >> isCompound);
+          isOK = (load >> txt); // __END_ENTRY__
+          if (txt != "__END_ENTRY__")
+            throw std::exception();
+          MESSAGE("entry: " << entry);
+        }
+
+        if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
+          while (isOK && (txt != "__END_GROUP__")) {
+            isOK = (load >> txt);
+            if (txt != "__END_GROUP__") {
+              if (!groupName.empty())
+                groupName += " ";
+              groupName += txt;
+            }
+          }
+          MESSAGE("groupName: " << groupName);
+        }
+
+        if (txt == "__BEGIN_COORDS__") {  // __BEGIN_COORDS__
+          hasCoords = true;
+          isOK = (load >> coords[0] >> coords[1] >> coords[2]);
+          isOK = (load >> txt); // __END_COORDS__
+          if (txt != "__END_COORDS__")
+            throw std::exception();
+          MESSAGE("coords: " << coords[0] <<","<< coords[1] <<","<< coords[2]);
+        }
+
+        if (txt == "__BEGIN_SIZE__") {  // __BEGIN_ENTRY__
+          isOK = (load >> size);
+          isOK = (load >> txt); // __END_ENTRY__
+          if (txt != "__END_SIZE__") {
+            throw std::exception();
+          }
+          MESSAGE("size: " << size);
+        }
+      }
+      isOK = (load >> txt);  // __BEGIN_VERTEX__
+    }
   }
 
   if (hasEnforcedVertices) {
-         isOK = (load >> separator);
-         if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
-                 hasEnforcedMeshes = true;
+    isOK = (load >> separator);
+    if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
+      hasEnforcedMeshes = true;
   }
 
   if (hasEnforcedMeshes) {
-         std::string txt, name, entry, groupName;
-         int elementType = -1;
-         isOK = (load >> txt);  // __BEGIN_ENF_MESH__
-         while (isOK) {
-//               if (isOK) {
-                         if (txt == "__ENFORCED_MESHES_END__")
-                                 isOK = false;
-
-                         TGHS3DEnforcedMesh *enfMesh = new TGHS3DEnforcedMesh();
-                         while (isOK) {
-                                 isOK = (load >> txt);
-                                 if (txt == "__END_ENF_MESH__") {
-                                         enfMesh->name = name;
-                                         enfMesh->entry = entry;
-                                         enfMesh->elementType = (SMESH::ElementType)elementType;
-                                         enfMesh->groupName = groupName;
-
-                                         _enfMeshList.insert(enfMesh);
-                                         std::cout << "Restoring of enforced mesh " <<name  << " done" << std::endl;
-
-                                         name.clear();
-                                         entry.clear();
-                                         elementType = -1;
-                                         groupName.clear();
-                                         isOK = false;
-                                 }
-
-                                 if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
-                                         while (isOK && (txt != "__END_NAME__")) {
-                                                 isOK = (load >> txt);
-                                                 if (txt != "__END_NAME__") {
-                                                         if (!name.empty())
-                                                                 name += " ";
-                                                         name += txt;
-                                                 }
-                                         }
-                                         MESSAGE("name: " <<name);
-                                 }
-
-                                 if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
-                                         isOK = (load >> entry);
-                                         isOK = (load >> txt); // __END_ENTRY__
-                                         if (txt != "__END_ENTRY__")
-                                                 throw std::exception();
-                                         MESSAGE("entry: " << entry);
-                                 }
-
-                                 if (txt == "__BEGIN_ELEM_TYPE__") {  // __BEGIN_ELEM_TYPE__
-                                         isOK = (load >> elementType);
-                                         isOK = (load >> txt); // __END_ELEM_TYPE__
-                                         if (txt != "__END_ELEM_TYPE__")
-                                                 throw std::exception();
-                                         MESSAGE("elementType: " << elementType);
-                                 }
-
-                                 if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
-                                         while (isOK && (txt != "__END_GROUP__")) {
-                                                 isOK = (load >> txt);
-                                                 if (txt != "__END_GROUP__") {
-                                                         if (!groupName.empty())
-                                                                 groupName += " ";
-                                                         groupName += txt;
-                                                 }
-                                         } // while
-                                         MESSAGE("groupName: " << groupName);
-                                 } // if
-                                 std::cout << "isOK: " << isOK << std::endl;
-                         } // while
-//               } // if
-                 isOK = (load >> txt);  // __BEGIN_ENF_MESH__
-         } // while
+    std::string txt, name, entry, groupName;
+    int elementType = -1, persistID = -1;
+    isOK = (load >> txt);  // __BEGIN_ENF_MESH__
+    while (isOK) {
+      //                if (isOK) {
+      if (txt == "__ENFORCED_MESHES_END__")
+        isOK = false;
+
+      TGHS3DEnforcedMesh *enfMesh = new TGHS3DEnforcedMesh();
+      while (isOK) {
+        isOK = (load >> txt);
+        if (txt == "__END_ENF_MESH__") {
+          enfMesh->name = name;
+          enfMesh->entry = entry;
+          enfMesh->elementType = (SMESH::ElementType)elementType;
+          enfMesh->groupName = groupName;
+          enfMesh->persistID = persistID;
+
+          _enfMeshList.insert(enfMesh);
+          std::cout << "Restoring of enforced mesh " <<name  << " done" << std::endl;
+
+          name.clear();
+          entry.clear();
+          elementType = -1;
+          groupName.clear();
+          persistID = -1;
+          isOK = false;
+        }
+
+        if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
+          while (isOK && (txt != "__END_NAME__")) {
+            isOK = (load >> txt);
+            if (txt != "__END_NAME__") {
+              if (!name.empty())
+                name += " ";
+              name += txt;
+            }
+          }
+          MESSAGE("name: " <<name);
+        }
+
+        if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
+          isOK = (load >> entry);
+          isOK = (load >> txt); // __END_ENTRY__
+          if (txt != "__END_ENTRY__")
+            throw std::exception();
+          MESSAGE("entry: " << entry);
+        }
+
+        if (txt == "__BEGIN_ELEM_TYPE__") {  // __BEGIN_ELEM_TYPE__
+          isOK = (load >> elementType);
+          isOK = (load >> txt); // __END_ELEM_TYPE__
+          if (txt != "__END_ELEM_TYPE__")
+            throw std::exception();
+          MESSAGE("elementType: " << elementType);
+        }
+
+        if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
+          while (isOK && (txt != "__END_GROUP__")) {
+            isOK = (load >> txt);
+            if (txt != "__END_GROUP__") {
+              if (!groupName.empty())
+                groupName += " ";
+              groupName += txt;
+            }
+          } // while
+          MESSAGE("groupName: " << groupName);
+        } // if
+
+        if (txt == "__PERSIST_ID__") {
+          isOK = (load >> persistID);
+          MESSAGE("persistID: " << persistID);
+        }
+        std::cout << "isOK: " << isOK << std::endl;
+      } // while
+      //                } // if
+      isOK = (load >> txt);  // __BEGIN_ENF_MESH__
+    } // while
   } // if
 
   return load;
@@ -1293,14 +1438,15 @@ bool GHS3DPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoDS
 
 //================================================================================
 /*!
- * \brief Return false
+ * \brief Sets myToMakeGroupsOfDomains depending on whether theMesh is on shape or not
  */
 //================================================================================
 
-bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  /*dflts*/,
+bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  dflts,
                                                      const SMESH_Mesh* /*theMesh*/)
 {
-  return false;
+  myToMakeGroupsOfDomains = ( !dflts._shape || dflts._shape->IsNull() );
+  return true;
 }
 
 //================================================================================
@@ -1312,11 +1458,7 @@ bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  /*dflts*/
 std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp,
                                                  const bool         hasShapeToMesh)
 {
-  TCollection_AsciiString cmd;
-  if (hasShapeToMesh)
-    cmd = "ghs3d-41"; // to use old mesh2 format
-  else
-    cmd = "ghs3d"; // to use new mesh format
+  TCollection_AsciiString cmd = GetExeName().c_str();
   // check if any option is overridden by hyp->myTextOption
   bool m   = hyp ? ( hyp->myTextOption.find("-m")  == std::string::npos ) : true;
   bool M   = hyp ? ( hyp->myTextOption.find("-M")  == std::string::npos ) : true;
@@ -1338,7 +1480,7 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h
   // Default memory is defined at ghs3d installation but it may be not enough,
   // so allow to use about all available memory
   if ( m ) {
-    short aMaximumMemory = hyp ? hyp->myMaximumMemory : -1;
+    double aMaximumMemory = hyp ? hyp->myMaximumMemory : -1;
     cmd += " -m ";
     if ( aMaximumMemory < 0 )
       cmd += DefaultMaximumMemory();
@@ -1346,7 +1488,7 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h
       cmd += aMaximumMemory;
   }
   if ( M && !useBndRecovery ) {
-    short aInitialMemory = hyp ? hyp->myInitialMemory : -1;
+    double aInitialMemory = hyp ? hyp->myInitialMemory : -1;
     cmd += " -M ";
     if ( aInitialMemory > 0 )
       cmd += aInitialMemory;
@@ -1368,18 +1510,22 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h
         cmd += " -c 1";
     }
   }
+  const bool toCreateNewNodes = ( p0 && ( !hyp || hyp->myToCreateNewNodes ));
 
   // optimization level
-  if ( o && hyp && !useBndRecovery ) {
+  if ( o && hyp && !useBndRecovery && toCreateNewNodes ) {
     if ( hyp->myOptimizationLevel >= 0 && hyp->myOptimizationLevel < 5 ) {
       const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" };
       cmd += " -o ";
       cmd += level[ hyp->myOptimizationLevel ];
     }
   }
+  if ( !toCreateNewNodes ) {
+    cmd += " -o none"; // issue 22608
+  }
 
   // to create internal nodes
-  if ( p0 && hyp && !hyp->myToCreateNewNodes ) {
+  if ( p0 && !toCreateNewNodes ) {
     cmd += " -p0";
   }
 
@@ -1416,7 +1562,7 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h
     cmd += hyp->myGradation;
   }
 
-#ifdef WNT
+#ifdef WIN32
   cmd += " < NUL";
 #endif
 
@@ -1448,6 +1594,16 @@ std::string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hy
   return aGenericName.ToCString();
 }
 
+//================================================================================
+/*
+ * Return the name of executable
+ */
+//================================================================================
+
+std::string GHS3DPlugin_Hypothesis::GetExeName()
+{
+  return "mg-tetra.exe";
+}
 
 //================================================================================
 /*!