Salome HOME
23643: EDF 18321 - Max_memory : wrong argument
[plugins/ghs3dplugin.git] / src / GHS3DPlugin / GHS3DPlugin_Hypothesis.cxx
1 // Copyright (C) 2004-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //=============================================================================
21 // File      : GHS3DPlugin_Hypothesis.cxx
22 // Created   : Wed Apr  2 12:36:29 2008
23 // Author    : Edward AGAPOV (eap)
24 //=============================================================================
25 //
26 #include "GHS3DPlugin_Hypothesis.hxx"
27
28 #include <SMESHDS_Mesh.hxx>
29
30 #include <TCollection_AsciiString.hxx>
31
32 #ifdef WIN32
33 #include <process.h>
34 #define getpid _getpid
35 #endif
36
37 using namespace std;
38
39 //=======================================================================
40 //function : GHS3DPlugin_Hypothesis
41 //=======================================================================
42
43 GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, SMESH_Gen * gen)
44   : SMESH_Hypothesis(hypId, gen),
45     myToMeshHoles(DefaultMeshHoles()),
46     myToMakeGroupsOfDomains(DefaultToMakeGroupsOfDomains()),
47     myMaximumMemory(-1),
48     myInitialMemory(-1),
49     myOptimizationLevel(DefaultOptimizationLevel()),
50     myKeepFiles(DefaultKeepFiles()),
51     myWorkingDirectory(DefaultWorkingDirectory()),
52     myVerboseLevel(DefaultVerboseLevel()),
53     myToCreateNewNodes(DefaultToCreateNewNodes()),
54     myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()),
55     myToUseFemCorrection(DefaultToUseFEMCorrection()),
56     myToRemoveCentralPoint(DefaultToRemoveCentralPoint()),
57     myLogInStandardOutput(DefaultStandardOutputLog()),
58     myRemoveLogOnSuccess( DefaultRemoveLogOnSuccess() ),
59     myGradation(DefaultGradation()),
60     _enfVertexList(DefaultGHS3DEnforcedVertexList()),
61     _enfVertexCoordsSizeList(DefaultGHS3DEnforcedVertexCoordsValues()),
62     _enfVertexEntrySizeList(DefaultGHS3DEnforcedVertexEntryValues()),
63     _coordsEnfVertexMap(DefaultCoordsGHS3DEnforcedVertexMap()),
64     _geomEntryEnfVertexMap(DefaultGeomEntryGHS3DEnforcedVertexMap()),
65     _enfMeshList(DefaultGHS3DEnforcedMeshList()),
66     _entryEnfMeshMap(DefaultEntryGHS3DEnforcedMeshListMap()),
67     _enfNodes(TIDSortedNodeGroupMap()),
68     _enfEdges(TIDSortedElemGroupMap()),
69     _enfTriangles(TIDSortedElemGroupMap()),
70     _nodeIDToSizeMap(DefaultID2SizeMap()),
71     _groupsToRemove(DefaultGroupsToRemove())
72 {
73   _name = GetHypType();
74   _param_algo_dim = 3;
75 }
76
77 //=======================================================================
78 //function : SetToMeshHoles
79 //=======================================================================
80
81 void GHS3DPlugin_Hypothesis::SetToMeshHoles(bool toMesh)
82 {
83   if ( myToMeshHoles != toMesh ) {
84     myToMeshHoles = toMesh;
85     NotifySubMeshesHypothesisModification();
86   }
87 }
88
89 //=======================================================================
90 //function : GetToMeshHoles
91 //=======================================================================
92
93 bool GHS3DPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const
94 {
95   if (checkFreeOption && !myTextOption.empty()) {
96     if ( myTextOption.find("--components all"))
97       return true;
98     if ( myTextOption.find("--components outside_components"))
99       return false;
100   }
101   return myToMeshHoles;
102 }
103
104 //=======================================================================
105 //function : SetToMakeGroupsOfDomains
106 //=======================================================================
107
108 void GHS3DPlugin_Hypothesis::SetToMakeGroupsOfDomains(bool toMakeGroups)
109 {
110   if ( myToMakeGroupsOfDomains != toMakeGroups ) {
111     myToMakeGroupsOfDomains = toMakeGroups;
112     NotifySubMeshesHypothesisModification();
113   }
114 }
115
116 //=======================================================================
117 //function : GetToMakeGroupsOfDomains
118 //=======================================================================
119
120 bool GHS3DPlugin_Hypothesis::GetToMakeGroupsOfDomains() const
121 {
122   return myToMakeGroupsOfDomains;
123 }
124
125 //=======================================================================
126 //function : GetToMakeGroupsOfDomains
127 //=======================================================================
128
129 bool GHS3DPlugin_Hypothesis::GetToMakeGroupsOfDomains(const GHS3DPlugin_Hypothesis* hyp)
130 {
131   bool res;
132   if ( hyp ) res = /*hyp->GetToMeshHoles(true) &&*/ hyp->GetToMakeGroupsOfDomains();
133   else       res = /*DefaultMeshHoles()        &&*/ DefaultToMakeGroupsOfDomains();
134   return res;
135 }
136
137 //=======================================================================
138 //function : SetMaximumMemory
139 //=======================================================================
140
141 void GHS3DPlugin_Hypothesis::SetMaximumMemory(float MB)
142 {
143   if ( myMaximumMemory != MB ) {
144     myMaximumMemory = MB;
145     NotifySubMeshesHypothesisModification();
146   }
147 }
148
149 //=======================================================================
150 //function : GetMaximumMemory
151 //           * automatic memory adjustment mode. Default is zero
152 //=======================================================================
153
154 float GHS3DPlugin_Hypothesis::GetMaximumMemory() const
155 {
156   return myMaximumMemory;
157 }
158
159 //=======================================================================
160 //function : SetInitialMemory
161 //=======================================================================
162
163 void GHS3DPlugin_Hypothesis::SetInitialMemory(float MB)
164 {
165   if ( myInitialMemory != MB ) {
166     myInitialMemory = MB;
167     NotifySubMeshesHypothesisModification();
168   }
169 }
170
171 //=======================================================================
172 //function : GetInitialMemory
173 //=======================================================================
174
175 float GHS3DPlugin_Hypothesis::GetInitialMemory() const
176 {
177   return myInitialMemory;
178 }
179
180 //=======================================================================
181 //function : SetOptimizationLevel
182 //=======================================================================
183
184 void GHS3DPlugin_Hypothesis::SetOptimizationLevel(OptimizationLevel level)
185 {
186   if ( myOptimizationLevel != level ) {
187     myOptimizationLevel = level;
188     NotifySubMeshesHypothesisModification();
189   }
190 }
191
192 //=======================================================================
193 //function : GetOptimizationLevel
194 //=======================================================================
195
196 GHS3DPlugin_Hypothesis::OptimizationLevel GHS3DPlugin_Hypothesis::GetOptimizationLevel() const
197 {
198   return (OptimizationLevel) myOptimizationLevel;
199 }
200
201 //=======================================================================
202 //function : SetWorkingDirectory
203 //=======================================================================
204
205 void GHS3DPlugin_Hypothesis::SetWorkingDirectory(const std::string& path)
206 {
207   if ( myWorkingDirectory != path ) {
208     myWorkingDirectory = path;
209     NotifySubMeshesHypothesisModification();
210   }
211 }
212
213 //=======================================================================
214 //function : GetWorkingDirectory
215 //=======================================================================
216
217 std::string GHS3DPlugin_Hypothesis::GetWorkingDirectory() const
218 {
219   return myWorkingDirectory;
220 }
221
222 //=======================================================================
223 //function : SetKeepFiles
224 //=======================================================================
225
226 void GHS3DPlugin_Hypothesis::SetKeepFiles(bool toKeep)
227 {
228   if ( myKeepFiles != toKeep ) {
229     myKeepFiles = toKeep;
230     NotifySubMeshesHypothesisModification();
231   }
232 }
233
234 //=======================================================================
235 //function : GetKeepFiles
236 //=======================================================================
237
238 bool GHS3DPlugin_Hypothesis::GetKeepFiles() const
239 {
240   return myKeepFiles;
241 }
242
243 //=======================================================================
244 //function : SetVerboseLevel
245 //=======================================================================
246
247 void GHS3DPlugin_Hypothesis::SetVerboseLevel(short level)
248 {
249   if ( myVerboseLevel != level ) {
250     myVerboseLevel = level;
251     NotifySubMeshesHypothesisModification();
252   }
253 }
254
255 //=======================================================================
256 //function : GetVerboseLevel
257 //=======================================================================
258
259 short GHS3DPlugin_Hypothesis::GetVerboseLevel() const
260 {
261   return myVerboseLevel;
262 }
263
264 //=======================================================================
265 //function : SetToCreateNewNodes
266 //=======================================================================
267
268 void GHS3DPlugin_Hypothesis::SetToCreateNewNodes(bool toCreate)
269 {
270   if ( myToCreateNewNodes != toCreate ) {
271     myToCreateNewNodes = toCreate;
272     NotifySubMeshesHypothesisModification();
273   }
274 }
275
276 //=======================================================================
277 //function : GetToCreateNewNodes
278 //=======================================================================
279
280 bool GHS3DPlugin_Hypothesis::GetToCreateNewNodes() const
281 {
282   return myToCreateNewNodes;
283 }
284
285 //=======================================================================
286 //function : SetToUseBoundaryRecoveryVersion
287 //=======================================================================
288
289 void GHS3DPlugin_Hypothesis::SetToUseBoundaryRecoveryVersion(bool toUse)
290 {
291   if ( myToUseBoundaryRecoveryVersion != toUse ) {
292     myToUseBoundaryRecoveryVersion = toUse;
293     NotifySubMeshesHypothesisModification();
294   }
295 }
296
297 //=======================================================================
298 //function : GetToUseBoundaryRecoveryVersion
299 //=======================================================================
300
301 bool GHS3DPlugin_Hypothesis::GetToUseBoundaryRecoveryVersion() const
302 {
303   return myToUseBoundaryRecoveryVersion;
304 }
305
306 //=======================================================================
307 //function : SetFEMCorrection
308 //=======================================================================
309
310 void GHS3DPlugin_Hypothesis::SetFEMCorrection(bool toUseFem)
311 {
312   if ( myToUseFemCorrection != toUseFem ) {
313     myToUseFemCorrection = toUseFem;
314     NotifySubMeshesHypothesisModification();
315   }
316 }
317
318 //=======================================================================
319 //function : GetFEMCorrection
320 //=======================================================================
321
322 bool GHS3DPlugin_Hypothesis::GetFEMCorrection() const
323 {
324   return myToUseFemCorrection;
325 }
326
327 //=======================================================================
328 //function : SetToRemoveCentralPoint
329 //=======================================================================
330
331 void GHS3DPlugin_Hypothesis::SetToRemoveCentralPoint(bool toRemove)
332 {
333   if ( myToRemoveCentralPoint != toRemove ) {
334     myToRemoveCentralPoint = toRemove;
335     NotifySubMeshesHypothesisModification();
336   }
337 }
338
339 //=======================================================================
340 //function : GetToRemoveCentralPoint
341 //=======================================================================
342
343 bool GHS3DPlugin_Hypothesis::GetToRemoveCentralPoint() const
344 {
345   return myToRemoveCentralPoint;
346 }
347
348 //=======================================================================
349 //function : SetAdvancedOption
350 //=======================================================================
351
352 void GHS3DPlugin_Hypothesis::SetAdvancedOption(const std::string& option)
353 {
354   if ( myTextOption != option ) {
355     myTextOption = option;
356     NotifySubMeshesHypothesisModification();
357   }
358 }
359
360 //=======================================================================
361 //function : GetAdvancedOption
362 //=======================================================================
363
364 std::string GHS3DPlugin_Hypothesis::GetAdvancedOption() const
365 {
366   return myTextOption;
367 }
368
369 //=======================================================================
370 //function : SetGradation
371 //=======================================================================
372
373 void GHS3DPlugin_Hypothesis::SetGradation(double gradation)
374 {
375   if ( myGradation != gradation ) {
376     myGradation = gradation;
377     NotifySubMeshesHypothesisModification();
378   }
379 }
380
381 //=======================================================================
382 //function : GetGradation
383 //=======================================================================
384
385 double GHS3DPlugin_Hypothesis::GetGradation() const
386 {
387   return myGradation;
388 }
389
390 //=======================================================================
391 //function : SetStandardOutputLog
392 //=======================================================================
393
394 void GHS3DPlugin_Hypothesis::SetStandardOutputLog(bool logInStandardOutput)
395 {
396   if ( myLogInStandardOutput != logInStandardOutput ) {
397     myLogInStandardOutput = logInStandardOutput;
398     NotifySubMeshesHypothesisModification();
399   }
400 }
401
402 //=======================================================================
403 //function : GetStandardOutputLog
404 //=======================================================================
405
406 bool GHS3DPlugin_Hypothesis::GetStandardOutputLog() const
407 {
408   return myLogInStandardOutput;
409 }
410
411 //=======================================================================
412 //function : SetRemoveLogOnSuccess
413 //=======================================================================
414
415 void GHS3DPlugin_Hypothesis::SetRemoveLogOnSuccess(bool removeLogOnSuccess)
416 {
417   if ( myRemoveLogOnSuccess != removeLogOnSuccess ) {
418     myRemoveLogOnSuccess = removeLogOnSuccess;
419     NotifySubMeshesHypothesisModification();
420   }
421 }
422
423 //=======================================================================
424 //function : GetRemoveLogOnSuccess
425 //=======================================================================
426
427 bool GHS3DPlugin_Hypothesis::GetRemoveLogOnSuccess() const
428 {
429   return myRemoveLogOnSuccess;
430 }
431
432 //=======================================================================
433 //function : SetEnforcedVertex
434 //=======================================================================
435
436 bool GHS3DPlugin_Hypothesis::SetEnforcedVertex(std::string theName,
437                                                std::string theEntry,
438                                                std::string theGroupName,
439                                                double      size,
440                                                double x, double y, double z,
441                                                bool        isCompound)
442 {
443   MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedVertex(\""<< theName << "\", \""<< theEntry << "\", \"" << theGroupName << "\", "
444                                                       << size << ", " << x << ", " << y << ", " << z  << ", "<< isCompound << ")");
445
446   bool toNotify = false;
447   bool toCreate = true;
448
449   TGHS3DEnforcedVertex *oldEnVertex;
450   TGHS3DEnforcedVertex *newEnfVertex = new TGHS3DEnforcedVertex();
451   newEnfVertex->name = theName;
452   newEnfVertex->geomEntry = theEntry;
453   newEnfVertex->coords.clear();
454   if (!isCompound) {
455     newEnfVertex->coords.push_back(x);
456     newEnfVertex->coords.push_back(y);
457     newEnfVertex->coords.push_back(z);
458   }
459   newEnfVertex->groupName = theGroupName;
460   newEnfVertex->size = size;
461   newEnfVertex->isCompound = isCompound;
462   
463   
464   // update _enfVertexList
465   TGHS3DEnforcedVertexList::iterator it = _enfVertexList.find(newEnfVertex);
466   if (it != _enfVertexList.end()) {
467     toCreate = false;
468     oldEnVertex = (*it);
469     MESSAGE("Enforced Vertex was found => Update");
470     if (oldEnVertex->name != theName) {
471       MESSAGE("Update name from \"" << oldEnVertex->name << "\" to \"" << theName << "\"");
472       oldEnVertex->name = theName;
473       toNotify = true;
474     }
475     if (oldEnVertex->groupName != theGroupName) {
476       MESSAGE("Update group name from \"" << oldEnVertex->groupName << "\" to \"" << theGroupName << "\"");
477       oldEnVertex->groupName = theGroupName;
478       toNotify = true;
479     }
480     if (oldEnVertex->size != size) {
481       MESSAGE("Update size from \"" << oldEnVertex->size << "\" to \"" << size << "\"");
482       oldEnVertex->size = size;
483       toNotify = true;
484     }
485     if (toNotify) {
486       // update map coords / enf vertex if needed
487       if (oldEnVertex->coords.size()) {
488         _coordsEnfVertexMap[oldEnVertex->coords] = oldEnVertex;
489         _enfVertexCoordsSizeList[oldEnVertex->coords] = size;
490       }
491
492       // update map geom entry / enf vertex if needed
493       if (oldEnVertex->geomEntry != "") {
494         _geomEntryEnfVertexMap[oldEnVertex->geomEntry] = oldEnVertex;
495         _enfVertexEntrySizeList[oldEnVertex->geomEntry] = size;
496       }
497     }
498   }
499
500 //   //////// CREATE ////////////
501   if (toCreate) {
502     toNotify = true;
503     MESSAGE("Creating new enforced vertex");
504     _enfVertexList.insert(newEnfVertex);
505     if (theEntry == "") {
506       _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex;
507       _enfVertexCoordsSizeList[newEnfVertex->coords] = size;
508     }
509     else {
510       _geomEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex;
511       _enfVertexEntrySizeList[newEnfVertex->geomEntry] = size;
512     }
513   }
514
515   if (toNotify)
516     NotifySubMeshesHypothesisModification();
517
518   MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedVertex END");
519   return toNotify;
520 }
521
522
523 //=======================================================================
524 //function : SetEnforcedMesh
525 //=======================================================================
526 bool GHS3DPlugin_Hypothesis::SetEnforcedMesh(SMESH_Mesh& theMesh, SMESH::ElementType elementType, std::string name, std::string entry, std::string groupName)
527 {
528   TIDSortedElemSet theElemSet;
529   SMDS_ElemIteratorPtr eIt = theMesh.GetMeshDS()->elementsIterator(SMDSAbs_ElementType(elementType));
530   while ( eIt->more() )
531     theElemSet.insert( eIt->next() );
532   MESSAGE("Add "<<theElemSet.size()<<" types["<<elementType<<"] from source mesh");
533   bool added = SetEnforcedElements( theElemSet, elementType, groupName);
534   if (added) {
535     TGHS3DEnforcedMesh* newEnfMesh = new TGHS3DEnforcedMesh();
536     newEnfMesh->persistID   = theMesh.GetMeshDS()->GetPersistentId();
537     newEnfMesh->name        = name;
538     newEnfMesh->entry       = entry;
539     newEnfMesh->elementType = elementType;
540     newEnfMesh->groupName   = groupName;
541     
542     TGHS3DEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
543     if (it == _enfMeshList.end()) {
544       _entryEnfMeshMap[entry].insert(newEnfMesh);
545       _enfMeshList.insert(newEnfMesh);
546     }
547     else {
548       delete newEnfMesh;
549     }
550   }
551   return added;
552 }
553
554 //=======================================================================
555 //function : SetEnforcedGroup
556 //=======================================================================
557 bool GHS3DPlugin_Hypothesis::SetEnforcedGroup(const SMESHDS_Mesh* theMeshDS, SMESH::long_array_var theIDs, SMESH::ElementType elementType, std::string name, std::string entry, std::string groupName)
558 {
559   MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedGroup");
560   TIDSortedElemSet theElemSet;
561     if ( theIDs->length() == 0 ){MESSAGE("The source group is empty");}
562     for ( CORBA::ULong i=0; i < theIDs->length(); i++) {
563       CORBA::Long ind = theIDs[i];
564       if (elementType == SMESH::NODE)
565       {
566         const SMDS_MeshNode * node = theMeshDS->FindNode(ind);
567         if (node)
568           theElemSet.insert( node );
569       }
570       else
571       {
572         const SMDS_MeshElement * elem = theMeshDS->FindElement(ind);
573         if (elem)
574           theElemSet.insert( elem );
575       }
576     }
577
578 //   SMDS_ElemIteratorPtr it = theGroup->GetGroupDS()->GetElements();
579 //   while ( it->more() ) 
580 //     theElemSet.insert( it->next() );
581
582   MESSAGE("Add "<<theElemSet.size()<<" types["<<elementType<<"] from source group ");
583   bool added = SetEnforcedElements( theElemSet, elementType, groupName);
584   if (added) {
585     TGHS3DEnforcedMesh* newEnfMesh = new TGHS3DEnforcedMesh();
586     newEnfMesh->name = name;
587     newEnfMesh->entry = entry;
588     newEnfMesh->elementType = elementType;
589     newEnfMesh->groupName = groupName;
590     
591     TGHS3DEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
592     if (it == _enfMeshList.end()) {
593       _entryEnfMeshMap[entry].insert(newEnfMesh);
594       _enfMeshList.insert(newEnfMesh);
595     }
596   }
597   return added;
598 }
599
600 //=======================================================================
601 //function : SetEnforcedElements
602 //=======================================================================
603 bool GHS3DPlugin_Hypothesis::SetEnforcedElements(TIDSortedElemSet theElemSet, SMESH::ElementType elementType, std::string groupName)
604 {
605   MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedElements");
606   TIDSortedElemSet::const_iterator it = theElemSet.begin();
607   const SMDS_MeshElement* elem;
608   const SMDS_MeshNode* node;
609   bool added = true;
610   pair<TIDSortedNodeGroupMap::iterator,bool> nodeRet;
611   pair<TIDSortedElemGroupMap::iterator,bool> elemRet;
612
613   for (;it != theElemSet.end();++it)
614   {
615     elem = (*it);
616     switch (elementType) {
617       case SMESH::NODE:
618         node = dynamic_cast<const SMDS_MeshNode*>(elem);
619         if (node) {
620           nodeRet = _enfNodes.insert(make_pair(node,groupName));
621           added = added && nodeRet.second;
622           string msg = added ? "yes":"no";
623           MESSAGE( "Node (" <<node->X()<<","<<node->Y()<<","<<node->Z()<< ") with ID " << node->GetID() <<" added ? " << msg);
624         }
625         else {
626           SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
627           for (;nodeIt->more();) {
628             node = dynamic_cast<const SMDS_MeshNode*>(nodeIt->next());
629             nodeRet = _enfNodes.insert(make_pair(node,groupName));
630             added = added && nodeRet.second;
631           }
632         }
633         break;
634       case SMESH::EDGE:
635         if (elem->GetType() == SMDSAbs_Edge) {
636           elemRet = _enfEdges.insert(make_pair(elem,groupName));
637           added = added && elemRet.second;
638         }
639         else if (elem->GetType() > SMDSAbs_Edge) {
640           // SMDS_ElemIteratorPtr it = elem->edgesIterator();
641           // for (;it->more();) {
642           //   const SMDS_MeshElement* anEdge = it->next();
643           //   elemRet = _enfEdges.insert(make_pair(anEdge,groupName));
644           //   added = added && elemRet.second;
645           // }
646         }
647         break;
648       case SMESH::FACE:
649         if (elem->GetType() == SMDSAbs_Face)
650         {
651           if (elem->NbCornerNodes() == 3) {
652             elemRet = _enfTriangles.insert(make_pair(elem,groupName));
653             added = added && elemRet.second;
654           }
655         }
656         else if (elem->GetType() > SMDSAbs_Face) { // Group of faces
657           // SMDS_ElemIteratorPtr it = elem->facesIterator();
658           // for (;it->more();) {
659           //   const SMDS_MeshElement* aFace = it->next();
660           //   if (aFace->NbCornerNodes() == 3) {
661           //     elemRet = _enfTriangles.insert(make_pair(aFace,groupName));
662           //     added = added && elemRet.second;
663           //   }
664           // }
665         }
666         break;
667       default:
668         break;
669     };
670   }
671   if (added)
672     NotifySubMeshesHypothesisModification();
673   return added;
674 }
675
676
677 //=======================================================================
678 //function : GetEnforcedVertex
679 //=======================================================================
680
681 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(double x, double y, double z)
682   throw (std::invalid_argument)
683 {
684   std::vector<double> coord(3);
685   coord[0] = x;
686   coord[1] = y;
687   coord[2] = z;
688   if (_coordsEnfVertexMap.count(coord)>0)
689     return _coordsEnfVertexMap[coord];
690   std::ostringstream msg ;
691   msg << "No enforced vertex at " << x << ", " << y << ", " << z;
692   throw std::invalid_argument(msg.str());
693 }
694
695 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(const std::string theEntry)
696   throw (std::invalid_argument)
697 {
698   if (_geomEntryEnfVertexMap.count(theEntry)>0)
699     return _geomEntryEnfVertexMap[theEntry];
700   
701   std::ostringstream msg ;
702   msg << "No enforced vertex with entry " << theEntry;
703   throw std::invalid_argument(msg.str());
704 }
705
706 //=======================================================================
707 //function : RemoveEnforcedVertex
708 //=======================================================================
709
710 bool GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z, const std::string theEntry)
711   throw (std::invalid_argument)
712 {
713   bool toNotify = false;
714   std::ostringstream msg;
715   TGHS3DEnforcedVertex *oldEnfVertex;
716   std::vector<double> coords(3);
717   coords[0] = x;
718   coords[1] = y;
719   coords[2] = z;
720   
721   // check that enf vertex with given enf vertex entry exists
722   TGeomEntryGHS3DEnforcedVertexMap::iterator it_enfVertexEntry = _geomEntryEnfVertexMap.find(theEntry);
723   if (it_enfVertexEntry != _geomEntryEnfVertexMap.end()) {
724     // Success
725     MESSAGE("Found enforced vertex with geom entry " << theEntry);
726     oldEnfVertex = it_enfVertexEntry->second;
727     _geomEntryEnfVertexMap.erase(it_enfVertexEntry);
728   } else {
729     // Fail
730     MESSAGE("Enforced vertex with geom entry " << theEntry << " not found");
731     // check that enf vertex with given coords exists
732     TCoordsGHS3DEnforcedVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
733     if (it_coords_enf != _coordsEnfVertexMap.end()) {
734       // Success
735       MESSAGE("Found enforced vertex with coords " << x << ", " << y << ", " << z);
736       oldEnfVertex = it_coords_enf->second;
737       _coordsEnfVertexMap.erase(it_coords_enf);
738       _enfVertexCoordsSizeList.erase(_enfVertexCoordsSizeList.find(coords));
739     } else {
740       // Fail
741       MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found");
742       throw std::invalid_argument(msg.str());
743     }
744   }
745
746   MESSAGE("Remove enf vertex from _enfVertexList");
747
748   // update _enfVertexList
749   TGHS3DEnforcedVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
750   if (it != _enfVertexList.end()) {
751     if ((*it)->groupName != "")
752       _groupsToRemove.insert((*it)->groupName);
753     _enfVertexList.erase(it);
754     toNotify = true;
755     MESSAGE("Done");
756   }
757
758   if (toNotify)
759     NotifySubMeshesHypothesisModification();
760
761   return toNotify;
762 }
763
764 //=======================================================================
765 //function : ClearEnforcedVertices
766 //=======================================================================
767 void GHS3DPlugin_Hypothesis::ClearEnforcedVertices()
768 {
769   TGHS3DEnforcedVertexList::const_iterator it = _enfVertexList.begin();
770   for(;it != _enfVertexList.end();++it) {
771     if ((*it)->groupName != "")
772       _groupsToRemove.insert((*it)->groupName);
773   }
774   _enfVertexList.clear();
775   _coordsEnfVertexMap.clear();
776   _geomEntryEnfVertexMap.clear();
777   _enfVertexCoordsSizeList.clear();
778   _enfVertexEntrySizeList.clear();
779   NotifySubMeshesHypothesisModification();
780 }
781
782 //=======================================================================
783 //function : ClearEnforcedMeshes
784 //=======================================================================
785 void GHS3DPlugin_Hypothesis::ClearEnforcedMeshes()
786 {
787   TGHS3DEnforcedMeshList::const_iterator it = _enfMeshList.begin();
788   for(;it != _enfMeshList.end();++it) {
789     if ((*it)->groupName != "")
790       _groupsToRemove.insert((*it)->groupName);
791   }
792   _enfNodes.clear();
793   _enfEdges.clear();
794   _enfTriangles.clear();
795   _nodeIDToSizeMap.clear();
796   _enfMeshList.clear();
797   _entryEnfMeshMap.clear();
798   NotifySubMeshesHypothesisModification();
799 }
800
801 //================================================================================
802 /*!
803  * \brief At mesh loading, restore enforced elements by just loaded enforced meshes
804  */
805 //================================================================================
806
807 void GHS3DPlugin_Hypothesis::RestoreEnfElemsByMeshes()
808 {
809   TGHS3DEnforcedMeshList::const_iterator it = _enfMeshList.begin();
810   for(;it != _enfMeshList.end();++it) {
811     TGHS3DEnforcedMesh* enfMesh = *it;
812     if ( SMESH_Mesh* mesh = GetMeshByPersistentID( enfMesh->persistID ))
813       SetEnforcedMesh( *mesh,
814                        enfMesh->elementType,
815                        enfMesh->name,
816                        enfMesh->entry,
817                        enfMesh->groupName );
818     enfMesh->persistID = -1; // not to restore again
819   }
820 }
821
822 //=======================================================================
823 //function : SetGroupsToRemove
824 //=======================================================================
825
826 void GHS3DPlugin_Hypothesis::ClearGroupsToRemove()
827 {
828   _groupsToRemove.clear();
829 }
830
831
832 //=======================================================================
833 //function : DefaultMeshHoles
834 //=======================================================================
835
836 bool GHS3DPlugin_Hypothesis::DefaultMeshHoles()
837 {
838   return false; // PAL19680
839 }
840
841 //=======================================================================
842 //function : DefaultToMakeGroupsOfDomains
843 //=======================================================================
844
845 bool GHS3DPlugin_Hypothesis::DefaultToMakeGroupsOfDomains()
846 {
847   return false; // issue 0022172
848 }
849
850 //=======================================================================
851 //function : DefaultMaximumMemory
852 //=======================================================================
853
854 #if defined(WIN32)
855 #include <windows.h>
856 #elif !defined(__APPLE__)
857 #include <sys/sysinfo.h>
858 #endif
859
860 float GHS3DPlugin_Hypothesis::DefaultMaximumMemory()
861 {
862 #if defined(WIN32)
863   // See http://msdn.microsoft.com/en-us/library/aa366589.aspx
864   MEMORYSTATUSEX statex;
865   statex.dwLength = sizeof (statex);
866   long err = GlobalMemoryStatusEx (&statex);
867   if (err != 0) {
868     double totMB = (double)statex.ullAvailPhys / 1024. / 1024.;
869     return (float)( 0.7 * totMB );
870   }
871 #elif !defined(__APPLE__)
872   struct sysinfo si;
873   long err = sysinfo( &si );
874   if ( err == 0 ) {
875     long ramMB = si.totalram * si.mem_unit / 1024 / 1024;
876     return ( 0.7 * ramMB );
877   }
878 #endif
879   return 1024;
880 }
881
882 //=======================================================================
883 //function : DefaultInitialMemory
884 //=======================================================================
885
886 float GHS3DPlugin_Hypothesis::DefaultInitialMemory()
887 {
888   return DefaultMaximumMemory();
889 }
890
891 //=======================================================================
892 //function : DefaultOptimizationLevel
893 //=======================================================================
894
895 short GHS3DPlugin_Hypothesis::DefaultOptimizationLevel()
896 {
897   return Medium;
898 }
899
900 //=======================================================================
901 //function : DefaultWorkingDirectory
902 //=======================================================================
903
904 std::string GHS3DPlugin_Hypothesis::DefaultWorkingDirectory()
905 {
906   TCollection_AsciiString aTmpDir;
907
908   char *Tmp_dir = getenv("SALOME_TMP_DIR");
909   if(Tmp_dir != NULL) {
910     aTmpDir = Tmp_dir;
911   }
912   else {
913 #ifdef WIN32
914     aTmpDir = TCollection_AsciiString("C:\\");
915 #else
916     aTmpDir = TCollection_AsciiString("/tmp/");
917 #endif
918   }
919   return aTmpDir.ToCString();
920 }
921
922 //=======================================================================
923 //function : DefaultKeepFiles
924 //=======================================================================
925
926 bool   GHS3DPlugin_Hypothesis::DefaultKeepFiles()
927 {
928   return false;
929 }
930
931 //=======================================================================
932 //function : DefaultRemoveLogOnSuccess
933 //=======================================================================
934
935 bool   GHS3DPlugin_Hypothesis::DefaultRemoveLogOnSuccess()
936 {
937   return false;
938 }
939
940
941 //=======================================================================
942 //function : DefaultVerboseLevel
943 //=======================================================================
944
945 short  GHS3DPlugin_Hypothesis::DefaultVerboseLevel()
946 {
947   return 10;
948 }
949
950 //=======================================================================
951 //function : DefaultToCreateNewNodes
952 //=======================================================================
953
954 bool GHS3DPlugin_Hypothesis::DefaultToCreateNewNodes()
955 {
956   return true;
957 }
958
959 //=======================================================================
960 //function : DefaultToUseBoundaryRecoveryVersion
961 //=======================================================================
962
963 bool GHS3DPlugin_Hypothesis::DefaultToUseBoundaryRecoveryVersion()
964 {
965   return false;
966 }
967
968 //=======================================================================
969 //function : DefaultToUseFEMCorrection
970 //=======================================================================
971
972 bool GHS3DPlugin_Hypothesis::DefaultToUseFEMCorrection()
973 {
974   return false;
975 }
976
977 //=======================================================================
978 //function : DefaultToRemoveCentralPoint
979 //=======================================================================
980
981 bool GHS3DPlugin_Hypothesis::DefaultToRemoveCentralPoint()
982 {
983   return false;
984 }
985
986 //=======================================================================
987 //function : DefaultGradation
988 //=======================================================================
989
990 double GHS3DPlugin_Hypothesis::DefaultGradation()
991 {
992   return 1.05;
993 }
994
995 //=======================================================================
996 //function : DefaultStandardOutputLog
997 //=======================================================================
998
999 bool GHS3DPlugin_Hypothesis::DefaultStandardOutputLog()
1000 {
1001   return false;
1002 }
1003
1004 // //=======================================================================
1005 // //function : DefaultID2SizeMap
1006 // //=======================================================================
1007 // 
1008 // GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::DefaultID2SizeMap()
1009 // {
1010 //   return GHS3DPlugin_Hypothesis::TID2SizeMap();
1011 // }
1012
1013
1014 //=======================================================================
1015 //function : SaveTo
1016 //=======================================================================
1017
1018 std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save)
1019 {
1020   save << (int) myToMeshHoles                 << " ";
1021   save << myMaximumMemory                     << " ";
1022   save << myInitialMemory                     << " ";
1023   save << myOptimizationLevel                 << " ";
1024   save << myWorkingDirectory                  << " ";
1025   save << (int)myKeepFiles                    << " ";
1026   save << myVerboseLevel                      << " ";
1027   save << (int)myToCreateNewNodes             << " ";
1028   save << (int)myToUseBoundaryRecoveryVersion << " ";
1029   save << (int)myToUseFemCorrection           << " ";
1030   save << (int)myToRemoveCentralPoint         << " ";
1031   save << myGradation                         << " ";
1032   save << myToMakeGroupsOfDomains             << " ";
1033   if (!myTextOption.empty()) {
1034     save << "__OPTIONS_BEGIN__ ";
1035     save << myTextOption                      << " ";
1036     save << "__OPTIONS_END__ ";
1037   }
1038   
1039
1040   TGHS3DEnforcedVertexList::iterator it  = _enfVertexList.begin();
1041   if (it != _enfVertexList.end()) {
1042     save << " " << "__ENFORCED_VERTICES_BEGIN__ ";
1043     for ( ; it != _enfVertexList.end(); ++it ) {
1044       TGHS3DEnforcedVertex *enfVertex = (*it);
1045       save << " " << "__BEGIN_VERTEX__";
1046       if (!enfVertex->name.empty()) {
1047         save << " " << "__BEGIN_NAME__";
1048         save << " " << enfVertex->name;
1049         save << " " << "__END_NAME__";
1050       }
1051       if (!enfVertex->geomEntry.empty()) {
1052         save << " " << "__BEGIN_ENTRY__";
1053         save << " " << enfVertex->geomEntry;
1054         save << " " << enfVertex->isCompound;
1055         save << " " << "__END_ENTRY__";
1056       }
1057       if (!enfVertex->groupName.empty()) {
1058         save << " " << "__BEGIN_GROUP__";
1059         save << " " << enfVertex->groupName;
1060         save << " " << "__END_GROUP__";
1061       }
1062       if (enfVertex->coords.size()) {
1063         save << " " << "__BEGIN_COORDS__";
1064         for ( size_t i = 0; i < enfVertex->coords.size(); i++ )
1065           save << " " << enfVertex->coords[i];
1066         save << " " << "__END_COORDS__";
1067       }
1068       save << " " << "__BEGIN_SIZE__";
1069       save << " " << enfVertex->size;
1070       save << " " << "__END_SIZE__";
1071       save << " " << "__END_VERTEX__";
1072     }
1073     save << " " << "__ENFORCED_VERTICES_END__ ";
1074   }
1075
1076   TGHS3DEnforcedMeshList::iterator it_mesh  = _enfMeshList.begin();
1077   if (it_mesh != _enfMeshList.end()) {
1078     save << " " << "__ENFORCED_MESHES_BEGIN__ ";
1079     for ( ; it_mesh != _enfMeshList.end(); ++it_mesh ) {
1080       TGHS3DEnforcedMesh *enfMesh = (*it_mesh);
1081       save << " " << "__BEGIN_ENF_MESH__";
1082
1083       save << " " << "__BEGIN_NAME__";
1084       save << " " << enfMesh->name;
1085       save << " " << "__END_NAME__";
1086
1087       save << " " << "__BEGIN_ENTRY__";
1088       save << " " << enfMesh->entry;
1089       save << " " << "__END_ENTRY__";
1090
1091       save << " " << "__BEGIN_ELEM_TYPE__";
1092       save << " " << (int)enfMesh->elementType;
1093       save << " " << "__END_ELEM_TYPE__";
1094
1095       if (!enfMesh->groupName.empty()) {
1096         save << " " << "__BEGIN_GROUP__";
1097         save << " " << enfMesh->groupName;
1098         save << " " << "__END_GROUP__";
1099       }
1100       save << " " << "__PERSIST_ID__";
1101       save << " " << enfMesh->persistID;
1102       save << " " << "__END_ENF_MESH__";
1103       std::cout << "Saving of enforced mesh " << enfMesh->name.c_str() << " done" << std::endl;
1104     }
1105     save << " "  << "__ENFORCED_MESHES_END__ ";
1106   }
1107   return save;
1108 }
1109
1110 //=======================================================================
1111 //function : LoadFrom
1112 //=======================================================================
1113
1114 std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load)
1115 {
1116   bool isOK = true;
1117   int i;
1118   double d;
1119
1120   isOK = static_cast<bool>(load >> i);
1121   if (isOK)
1122     myToMeshHoles = i;
1123   else
1124     load.clear(ios::badbit | load.rdstate());
1125
1126   isOK = static_cast<bool>(load >> d);
1127   if (isOK)
1128     myMaximumMemory = d;
1129   else
1130     load.clear(ios::badbit | load.rdstate());
1131
1132   isOK = static_cast<bool>(load >> d);
1133   if (isOK)
1134     myInitialMemory = d;
1135   else
1136     load.clear(ios::badbit | load.rdstate());
1137
1138   isOK = static_cast<bool>(load >> i);
1139   if (isOK)
1140     myOptimizationLevel = i;
1141   else
1142     load.clear(ios::badbit | load.rdstate());
1143
1144   isOK = static_cast<bool>(load >> myWorkingDirectory);
1145   if (isOK) {
1146     if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty
1147       myKeepFiles = false;
1148       myWorkingDirectory.clear();
1149     }
1150     else if ( myWorkingDirectory == "1" ) {
1151       myKeepFiles = true;
1152       myWorkingDirectory.clear();
1153     }
1154   }
1155   else
1156     load.clear(ios::badbit | load.rdstate());
1157
1158   if ( !myWorkingDirectory.empty() ) {
1159     isOK = static_cast<bool>(load >> i);
1160     if (isOK)
1161       myKeepFiles = i;
1162     else
1163       load.clear(ios::badbit | load.rdstate());
1164   }
1165
1166   isOK = static_cast<bool>(load >> i);
1167   if (isOK)
1168     myVerboseLevel = (short) i;
1169   else
1170     load.clear(ios::badbit | load.rdstate());
1171
1172   isOK = static_cast<bool>(load >> i);
1173   if (isOK)
1174     myToCreateNewNodes = (bool) i;
1175   else
1176     load.clear(ios::badbit | load.rdstate());
1177
1178   isOK = static_cast<bool>(load >> i);
1179   if (isOK)
1180     myToUseBoundaryRecoveryVersion = (bool) i;
1181   else
1182     load.clear(ios::badbit | load.rdstate());
1183
1184   isOK = static_cast<bool>(load >> i);
1185   if (isOK)
1186     myToUseFemCorrection = (bool) i;
1187   else
1188     load.clear(ios::badbit | load.rdstate());
1189
1190   isOK = static_cast<bool>(load >> i);
1191   if (isOK)
1192     myToRemoveCentralPoint = (bool) i;
1193   else
1194     load.clear(ios::badbit | load.rdstate());
1195
1196   isOK = static_cast<bool>(load >> d);
1197   if (isOK)
1198     myGradation = d;
1199   else
1200     load.clear(ios::badbit | load.rdstate());
1201
1202   std::string separator;
1203   bool hasOptions = false;
1204   bool hasEnforcedVertices = false;
1205   bool hasEnforcedMeshes = false;
1206   isOK = static_cast<bool>(load >> separator);
1207
1208   if ( isOK && ( separator == "0" || separator == "1" ))
1209   {
1210     myToMakeGroupsOfDomains = ( separator == "1" );
1211     isOK = static_cast<bool>(load >> separator);
1212   }
1213
1214   if (isOK) {
1215     if (separator == "__OPTIONS_BEGIN__")
1216       hasOptions = true;
1217     else if (separator == "__ENFORCED_VERTICES_BEGIN__")
1218       hasEnforcedVertices = true;
1219     else if (separator == "__ENFORCED_MESHES_BEGIN__")
1220       hasEnforcedMeshes = true;
1221   }
1222
1223   if (hasOptions) {
1224     std::string txt;
1225     while (isOK) {
1226       isOK = static_cast<bool>(load >> txt);
1227       if (isOK) {
1228         if (txt == "__OPTIONS_END__") {
1229           if (!myTextOption.empty()) {
1230             // Remove last space
1231             myTextOption.erase(myTextOption.end()-1);
1232           }
1233           isOK = false;
1234           break;
1235         }
1236         myTextOption += txt;
1237         myTextOption += " ";
1238       }
1239     }
1240   }
1241
1242   if (hasOptions) {
1243     isOK = static_cast<bool>(load >> separator);
1244     if (isOK && separator == "__ENFORCED_VERTICES_BEGIN__")
1245       hasEnforcedVertices = true;
1246     if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1247       hasEnforcedMeshes = true;
1248   }
1249
1250   if (hasEnforcedVertices) {
1251     std::string txt, name, entry, groupName;
1252     double size, coords[3];
1253     bool isCompound;
1254     bool hasCoords = false;
1255     isOK = static_cast<bool>(load >> txt);  // __BEGIN_VERTEX__
1256     while (isOK) {
1257       if (txt == "__ENFORCED_VERTICES_END__") {
1258         //isOK = false;
1259         break;
1260       }
1261       
1262       TGHS3DEnforcedVertex *enfVertex = new TGHS3DEnforcedVertex();
1263       while (isOK) {
1264         isOK = static_cast<bool>(load >> txt);
1265         if (txt == "__END_VERTEX__") {
1266           enfVertex->name = name;
1267           enfVertex->geomEntry = entry;
1268           enfVertex->isCompound = isCompound;
1269           enfVertex->groupName = groupName;
1270           enfVertex->coords.clear();
1271           if (hasCoords)
1272             enfVertex->coords.assign(coords,coords+3);
1273
1274           _enfVertexList.insert(enfVertex);
1275
1276           if (enfVertex->coords.size())
1277             _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
1278           if (!enfVertex->geomEntry.empty())
1279             _geomEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
1280
1281           name.clear();
1282           entry.clear();
1283           groupName.clear();
1284           hasCoords = false;
1285           isOK = false;
1286         }
1287
1288         if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
1289           while (isOK && (txt != "__END_NAME__")) {
1290             isOK = static_cast<bool>(load >> txt);
1291             if (txt != "__END_NAME__") {
1292               if (!name.empty())
1293                 name += " ";
1294               name += txt;
1295             }
1296           }
1297           MESSAGE("name: " <<name);
1298         }
1299
1300         if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
1301           isOK = static_cast<bool>(load >> entry);
1302           isOK = static_cast<bool>(load >> isCompound);
1303           isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1304           if (txt != "__END_ENTRY__")
1305             throw std::exception();
1306           MESSAGE("entry: " << entry);
1307         }
1308
1309         if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
1310           while (isOK && (txt != "__END_GROUP__")) {
1311             isOK = static_cast<bool>(load >> txt);
1312             if (txt != "__END_GROUP__") {
1313               if (!groupName.empty())
1314                 groupName += " ";
1315               groupName += txt;
1316             }
1317           }
1318           MESSAGE("groupName: " << groupName);
1319         }
1320
1321         if (txt == "__BEGIN_COORDS__") {  // __BEGIN_COORDS__
1322           hasCoords = true;
1323           isOK = static_cast<bool>(load >> coords[0] >> coords[1] >> coords[2]);
1324           isOK = static_cast<bool>(load >> txt); // __END_COORDS__
1325           if (txt != "__END_COORDS__")
1326             throw std::exception();
1327           MESSAGE("coords: " << coords[0] <<","<< coords[1] <<","<< coords[2]);
1328         }
1329
1330         if (txt == "__BEGIN_SIZE__") {  // __BEGIN_ENTRY__
1331           isOK = static_cast<bool>(load >> size);
1332           isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1333           if (txt != "__END_SIZE__") {
1334             throw std::exception();
1335           }
1336           MESSAGE("size: " << size);
1337         }
1338       }
1339       isOK = static_cast<bool>(load >> txt);  // __BEGIN_VERTEX__
1340     }
1341   }
1342
1343   if (hasEnforcedVertices) {
1344     isOK = static_cast<bool>(load >> separator);
1345     if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1346       hasEnforcedMeshes = true;
1347   }
1348
1349   if (hasEnforcedMeshes) {
1350     std::string txt, name, entry, groupName;
1351     int elementType = -1, persistID = -1;
1352     isOK = static_cast<bool>(load >> txt);  // __BEGIN_ENF_MESH__
1353     while (isOK) {
1354       //                if (isOK) {
1355       if (txt == "__ENFORCED_MESHES_END__")
1356         isOK = false;
1357
1358       TGHS3DEnforcedMesh *enfMesh = new TGHS3DEnforcedMesh();
1359       while (isOK) {
1360         isOK = static_cast<bool>(load >> txt);
1361         if (txt == "__END_ENF_MESH__") {
1362           enfMesh->name = name;
1363           enfMesh->entry = entry;
1364           enfMesh->elementType = (SMESH::ElementType)elementType;
1365           enfMesh->groupName = groupName;
1366           enfMesh->persistID = persistID;
1367
1368           _enfMeshList.insert(enfMesh);
1369           //std::cout << "Restoring of enforced mesh " <<name  << " done" << std::endl;
1370
1371           name.clear();
1372           entry.clear();
1373           elementType = -1;
1374           groupName.clear();
1375           persistID = -1;
1376           isOK = false;
1377         }
1378
1379         if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
1380           while (isOK && (txt != "__END_NAME__")) {
1381             isOK = static_cast<bool>(load >> txt);
1382             if (txt != "__END_NAME__") {
1383               if (!name.empty())
1384                 name += " ";
1385               name += txt;
1386             }
1387           }
1388           MESSAGE("name: " <<name);
1389         }
1390
1391         if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
1392           isOK = static_cast<bool>(load >> entry);
1393           isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1394           if (txt != "__END_ENTRY__")
1395             throw std::exception();
1396           MESSAGE("entry: " << entry);
1397         }
1398
1399         if (txt == "__BEGIN_ELEM_TYPE__") {  // __BEGIN_ELEM_TYPE__
1400           isOK = static_cast<bool>(load >> elementType);
1401           isOK = static_cast<bool>(load >> txt); // __END_ELEM_TYPE__
1402           if (txt != "__END_ELEM_TYPE__")
1403             throw std::exception();
1404           MESSAGE("elementType: " << elementType);
1405         }
1406
1407         if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
1408           while (isOK && (txt != "__END_GROUP__")) {
1409             isOK = static_cast<bool>(load >> txt);
1410             if (txt != "__END_GROUP__") {
1411               if (!groupName.empty())
1412                 groupName += " ";
1413               groupName += txt;
1414             }
1415           } // while
1416           MESSAGE("groupName: " << groupName);
1417         } // if
1418
1419         if (txt == "__PERSIST_ID__") {
1420           isOK = static_cast<bool>(load >> persistID);
1421           MESSAGE("persistID: " << persistID);
1422         }
1423         //std::cout << "isOK: " << isOK << std::endl;
1424       } // while
1425       //                } // if
1426       isOK = static_cast<bool>(load >> txt);  // __BEGIN_ENF_MESH__
1427     } // while
1428   } // if
1429
1430   return load;
1431 }
1432
1433 //=======================================================================
1434 //function : SetParametersByMesh
1435 //=======================================================================
1436
1437 bool GHS3DPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoDS_Shape&)
1438 {
1439   return false;
1440 }
1441
1442
1443 //================================================================================
1444 /*!
1445  * \brief Sets myToMakeGroupsOfDomains depending on whether theMesh is on shape or not
1446  */
1447 //================================================================================
1448
1449 bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  dflts,
1450                                                      const SMESH_Mesh* /*theMesh*/)
1451 {
1452   myToMakeGroupsOfDomains = ( !dflts._shape || dflts._shape->IsNull() );
1453   return true;
1454 }
1455
1456 //================================================================================
1457 /*!
1458  * \brief Return command to run MG-Tetra mesher excluding file prefix (-f)
1459  */
1460 //================================================================================
1461
1462 std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp,
1463                                                  const bool                    hasShapeToMesh,
1464                                                  const bool                    forExecutable)
1465 {
1466   std::string cmd = GetExeName();
1467   // check if any option is overridden by hyp->myTextOption
1468   bool max_memory   = hyp ? ( hyp->myTextOption.find("--max_memory")  == std::string::npos ) : true;
1469   bool auto_memory   = hyp ? ( hyp->myTextOption.find("--automatic_memory")  == std::string::npos ) : true;
1470   bool comp   = hyp ? ( hyp->myTextOption.find("--components")  == std::string::npos ) : true;
1471   bool optim_level   = hyp ? ( hyp->myTextOption.find("--optimisation_level")  == std::string::npos ) : true;
1472   bool no_int_points  = hyp ? ( hyp->myTextOption.find("--no_internal_points") == std::string::npos ) : true;
1473   bool C   = hyp ? ( hyp->myTextOption.find("-C")  == std::string::npos ) : true;
1474   bool verbose   = hyp ? ( hyp->myTextOption.find("--verbose")  == std::string::npos ) : true;
1475   bool fem = hyp ? ( hyp->myTextOption.find("-FEM")== std::string::npos ) : true;
1476   bool rem = hyp ? ( hyp->myTextOption.find("--no_initial_central_point")== std::string::npos ) : true;
1477   bool gra = hyp ? ( hyp->myTextOption.find("-Dcpropa")== std::string::npos ) : true;
1478
1479   // if use boundary recovery version, few options are allowed
1480   bool useBndRecovery = !C;
1481   if ( !useBndRecovery && hyp )
1482     useBndRecovery = hyp->myToUseBoundaryRecoveryVersion;
1483
1484   // MG-Tetra needs to know amount of memory it may use (MB).
1485   // Default memory is defined at MG-Tetra installation but it may be not enough,
1486   // so allow to use about all available memory
1487   if ( max_memory ) {
1488     float aMaximumMemory = hyp ? hyp->myMaximumMemory : -1;
1489     cmd += " --max_memory ";
1490     if ( aMaximumMemory < 0 ) cmd += SMESH_Comment( int( DefaultMaximumMemory() ));
1491     else                      cmd += SMESH_Comment( int( aMaximumMemory ));
1492   }
1493   if ( auto_memory && !useBndRecovery ) {
1494     float aInitialMemory = hyp ? hyp->myInitialMemory : -1;
1495     cmd += " --automatic_memory ";
1496     if ( aInitialMemory > 0 ) cmd += SMESH_Comment( int( aInitialMemory ));
1497     else                      cmd += "100";
1498   }
1499   // component to mesh
1500   if ( comp && !useBndRecovery ) {
1501     // We always run MG-Tetra with "to mesh holes'==TRUE (see PAL19680)
1502     if ( hasShapeToMesh )
1503       cmd += " --components all";
1504     else {
1505       bool aToMeshHoles = hyp ? hyp->myToMeshHoles : DefaultMeshHoles();
1506       if ( aToMeshHoles ) cmd += " --components all";
1507       else                cmd += " --components outside_components";
1508     }
1509   }
1510   const bool toCreateNewNodes = ( no_int_points && ( !hyp || hyp->myToCreateNewNodes ));
1511
1512   // optimization level
1513   if ( !toCreateNewNodes ) {
1514     cmd += " --optimisation_level none"; // issue 22608
1515   }
1516   else if ( optim_level && hyp && !useBndRecovery ) {
1517     if ( hyp->myOptimizationLevel >= 0 && hyp->myOptimizationLevel < 5 ) {
1518       const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" };
1519       cmd += " --optimisation_level ";
1520       cmd += level[ hyp->myOptimizationLevel ];
1521     }
1522   }
1523
1524   // to create internal nodes
1525   if ( no_int_points && !toCreateNewNodes ) {
1526     if ( forExecutable )
1527       cmd += " --no_internal_points";
1528     else
1529       cmd += " --internalpoints no";
1530   }
1531
1532   // verbose mode
1533   if ( verbose && hyp ) {
1534     cmd += " --verbose " + SMESH_Comment( hyp->myVerboseLevel );
1535   }
1536
1537   // boundary recovery version
1538   if ( useBndRecovery ) {
1539     cmd += " -C";
1540   }
1541
1542   // to use FEM correction
1543   if ( fem && hyp && hyp->myToUseFemCorrection) {
1544     cmd += " -FEM";
1545   }
1546
1547   // to remove initial central point.
1548   if ( rem && hyp && hyp->myToRemoveCentralPoint) {
1549     if ( forExecutable )
1550       cmd += " --no_initial_central_point";
1551     else
1552       cmd += " --centralpoint no";
1553   }
1554
1555   // options as text
1556   if ( hyp && !hyp->myTextOption.empty() ) {
1557     cmd += " " + hyp->myTextOption;
1558   }
1559
1560   // to define volumic gradation.
1561   if ( gra && hyp ) {
1562     if ( forExecutable )
1563       cmd += " -Dcpropa=" + SMESH_Comment( hyp->myGradation );
1564     else
1565       cmd += " --gradation " + SMESH_Comment( hyp->myGradation );
1566   }
1567
1568 #ifdef WIN32
1569   cmd += " < NUL";
1570 #endif
1571
1572   return cmd;
1573 }
1574
1575 //================================================================================
1576 /*!
1577  * \brief Return a unique file name
1578  */
1579 //================================================================================
1580
1581 std::string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hyp)
1582 {
1583   std::string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory();
1584   const char lastChar = *aTmpDir.rbegin();
1585 #ifdef WIN32
1586     if(lastChar != '\\') aTmpDir+='\\';
1587 #else
1588     if(lastChar != '/') aTmpDir+='/';
1589 #endif      
1590
1591   TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str();
1592   aGenericName += "GHS3D_";
1593   aGenericName += getpid();
1594   aGenericName += "_";
1595   aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString());
1596
1597   return aGenericName.ToCString();
1598 }
1599
1600 //================================================================================
1601 /*
1602  * Return the name of executable
1603  */
1604 //================================================================================
1605
1606 std::string GHS3DPlugin_Hypothesis::GetExeName()
1607 {
1608   return "mg-tetra.exe";
1609 }
1610
1611 //================================================================================
1612 /*!
1613 * \brief Return the enforced vertices
1614 */
1615 //================================================================================
1616
1617 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexList GHS3DPlugin_Hypothesis::GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp)
1618 {
1619   return hyp ? hyp->_GetEnforcedVertices():DefaultGHS3DEnforcedVertexList();
1620 }
1621
1622 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesCoordsSize (const GHS3DPlugin_Hypothesis* hyp)
1623 {  
1624   return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): DefaultGHS3DEnforcedVertexCoordsValues();
1625 }
1626
1627 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexEntryValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesEntrySize (const GHS3DPlugin_Hypothesis* hyp)
1628 {  
1629   return hyp ? hyp->_GetEnforcedVerticesEntrySize(): DefaultGHS3DEnforcedVertexEntryValues();
1630 }
1631
1632 GHS3DPlugin_Hypothesis::TCoordsGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByCoords (const GHS3DPlugin_Hypothesis* hyp)
1633 {  
1634   return hyp ? hyp->_GetEnforcedVerticesByCoords(): DefaultCoordsGHS3DEnforcedVertexMap();
1635 }
1636
1637 GHS3DPlugin_Hypothesis::TGeomEntryGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByEntry (const GHS3DPlugin_Hypothesis* hyp)
1638 {  
1639   return hyp ? hyp->_GetEnforcedVerticesByEntry(): DefaultGeomEntryGHS3DEnforcedVertexMap();
1640 }
1641
1642 GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap GHS3DPlugin_Hypothesis::GetEnforcedNodes(const GHS3DPlugin_Hypothesis* hyp)
1643 {
1644   return hyp ? hyp->_GetEnforcedNodes():DefaultIDSortedNodeGroupMap();
1645 }
1646
1647 GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedEdges(const GHS3DPlugin_Hypothesis* hyp)
1648 {
1649   return hyp ? hyp->_GetEnforcedEdges():DefaultIDSortedElemGroupMap();
1650 }
1651
1652 GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedTriangles(const GHS3DPlugin_Hypothesis* hyp)
1653 {
1654   return hyp ? hyp->_GetEnforcedTriangles():DefaultIDSortedElemGroupMap();
1655 }
1656
1657 GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::GetNodeIDToSizeMap(const GHS3DPlugin_Hypothesis* hyp)
1658 {
1659   return hyp ? hyp->_GetNodeIDToSizeMap(): DefaultID2SizeMap();
1660 }
1661
1662 GHS3DPlugin_Hypothesis::TSetStrings GHS3DPlugin_Hypothesis::GetGroupsToRemove(const GHS3DPlugin_Hypothesis* hyp)
1663 {
1664   return hyp ? hyp->_GetGroupsToRemove(): DefaultGroupsToRemove();
1665 }