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