Salome HOME
Copyrights update 2013
[plugins/ghs3dplugin.git] / src / GHS3DPlugin / GHS3DPlugin_Hypothesis.cxx
1 // Copyright (C) 2004-2013  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->persistID   = theMesh.GetMeshDS()->GetPersistentId();
454     newEnfMesh->name        = name;
455     newEnfMesh->entry       = entry;
456     newEnfMesh->elementType = elementType;
457     newEnfMesh->groupName   = groupName;
458     
459     TGHS3DEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
460     if (it == _enfMeshList.end()) {
461       _entryEnfMeshMap[entry].insert(newEnfMesh);
462       _enfMeshList.insert(newEnfMesh);
463     }
464     else {
465       delete newEnfMesh;
466     }
467   }
468   return added;
469 }
470
471 //=======================================================================
472 //function : SetEnforcedGroup
473 //=======================================================================
474 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)
475 {
476   MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedGroup");
477   TIDSortedElemSet theElemSet;
478     if ( theIDs->length() == 0 ){MESSAGE("The source group is empty");}
479     for (int i=0; i < theIDs->length(); i++) {
480       CORBA::Long ind = theIDs[i];
481       if (elementType == SMESH::NODE)
482       {
483         const SMDS_MeshNode * node = theMeshDS->FindNode(ind);
484         if (node)
485           theElemSet.insert( node );
486       }
487       else
488       {
489         const SMDS_MeshElement * elem = theMeshDS->FindElement(ind);
490         if (elem)
491           theElemSet.insert( elem );
492       }
493     }
494
495 //   SMDS_ElemIteratorPtr it = theGroup->GetGroupDS()->GetElements();
496 //   while ( it->more() ) 
497 //     theElemSet.insert( it->next() );
498
499   MESSAGE("Add "<<theElemSet.size()<<" types["<<elementType<<"] from source group ");
500   bool added = SetEnforcedElements( theElemSet, elementType, groupName);
501   if (added) {
502     TGHS3DEnforcedMesh* newEnfMesh = new TGHS3DEnforcedMesh();
503     newEnfMesh->name = name;
504     newEnfMesh->entry = entry;
505     newEnfMesh->elementType = elementType;
506     newEnfMesh->groupName = groupName;
507     
508     TGHS3DEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
509     if (it == _enfMeshList.end()) {
510       _entryEnfMeshMap[entry].insert(newEnfMesh);
511       _enfMeshList.insert(newEnfMesh);
512     }
513   }
514   return added;
515 }
516
517 //=======================================================================
518 //function : SetEnforcedElements
519 //=======================================================================
520 bool GHS3DPlugin_Hypothesis::SetEnforcedElements(TIDSortedElemSet theElemSet, SMESH::ElementType elementType, std::string groupName)
521 {
522   MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedElements");
523   TIDSortedElemSet::const_iterator it = theElemSet.begin();
524   const SMDS_MeshElement* elem;
525   const SMDS_MeshNode* node;
526   bool added = true;
527   pair<TIDSortedNodeGroupMap::iterator,bool> nodeRet;
528   pair<TIDSortedElemGroupMap::iterator,bool> elemRet;
529
530   for (;it != theElemSet.end();++it)
531   {
532     elem = (*it);
533     switch (elementType) {
534       case SMESH::NODE:
535         node = dynamic_cast<const SMDS_MeshNode*>(elem);
536         if (node) {
537           nodeRet = _enfNodes.insert(make_pair(node,groupName));
538           added = added && nodeRet.second;
539           string msg = added ? "yes":"no";
540           MESSAGE( "Node (" <<node->X()<<","<<node->Y()<<","<<node->Z()<< ") with ID " << node->GetID() <<" added ? " << msg);
541         }
542         else {
543           SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
544           for (;nodeIt->more();) {
545             node = dynamic_cast<const SMDS_MeshNode*>(nodeIt->next());
546             nodeRet = _enfNodes.insert(make_pair(node,groupName));
547             added = added && nodeRet.second;
548           }
549 //          added = true;s
550         }
551         break;
552       case SMESH::EDGE:
553         if (elem->GetType() == SMDSAbs_Edge) {
554           elemRet = _enfEdges.insert(make_pair(elem,groupName));
555           added = added && elemRet.second;
556         }
557         else if (elem->GetType() > SMDSAbs_Edge) {
558           SMDS_ElemIteratorPtr it = elem->edgesIterator();
559           for (;it->more();) {
560             const SMDS_MeshElement* anEdge = it->next();
561             elemRet = _enfEdges.insert(make_pair(anEdge,groupName));
562             added = added && elemRet.second;
563           }
564         }
565         break;
566       case SMESH::FACE:
567         if (elem->GetType() == SMDSAbs_Face)
568         {
569           if (elem->NbCornerNodes() == 3) {
570             elemRet = _enfTriangles.insert(make_pair(elem,groupName));
571             added = added && elemRet.second;
572           }
573         }
574         else if (elem->GetType() > SMDSAbs_Face) { // Group of faces
575           SMDS_ElemIteratorPtr it = elem->facesIterator();
576           for (;it->more();) {
577             const SMDS_MeshElement* aFace = it->next();
578             if (aFace->NbCornerNodes() == 3) {
579               elemRet = _enfTriangles.insert(make_pair(aFace,groupName));
580               added = added && elemRet.second;
581             }
582           }
583         }
584         break;
585       default:
586         break;
587     };
588   }
589   if (added)
590     NotifySubMeshesHypothesisModification();
591   return added;
592 }
593
594
595 //=======================================================================
596 //function : GetEnforcedVertex
597 //=======================================================================
598
599 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(double x, double y, double z)
600   throw (std::invalid_argument)
601 {
602   std::vector<double> coord(3);
603   coord[0] = x;
604   coord[1] = y;
605   coord[2] = z;
606   if (_coordsEnfVertexMap.count(coord)>0)
607     return _coordsEnfVertexMap[coord];
608   std::ostringstream msg ;
609   msg << "No enforced vertex at " << x << ", " << y << ", " << z;
610   throw std::invalid_argument(msg.str());
611 }
612
613 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(const std::string theEntry)
614   throw (std::invalid_argument)
615 {
616   if (_geomEntryEnfVertexMap.count(theEntry)>0)
617     return _geomEntryEnfVertexMap[theEntry];
618   
619   std::ostringstream msg ;
620   msg << "No enforced vertex with entry " << theEntry;
621   throw std::invalid_argument(msg.str());
622 }
623
624 //=======================================================================
625 //function : RemoveEnforcedVertex
626 //=======================================================================
627
628 bool GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z, const std::string theEntry)
629   throw (std::invalid_argument)
630 {
631   bool toNotify = false;
632   std::ostringstream msg;
633   TGHS3DEnforcedVertex *oldEnfVertex;
634   std::vector<double> coords(3);
635   coords[0] = x;
636   coords[1] = y;
637   coords[2] = z;
638   
639   // check that enf vertex with given enf vertex entry exists
640   TGeomEntryGHS3DEnforcedVertexMap::iterator it_enfVertexEntry = _geomEntryEnfVertexMap.find(theEntry);
641   if (it_enfVertexEntry != _geomEntryEnfVertexMap.end()) {
642     // Success
643     MESSAGE("Found enforced vertex with geom entry " << theEntry);
644     oldEnfVertex = it_enfVertexEntry->second;
645     _geomEntryEnfVertexMap.erase(it_enfVertexEntry);
646   } else {
647     // Fail
648     MESSAGE("Enforced vertex with geom entry " << theEntry << " not found");
649     // check that enf vertex with given coords exists
650     TCoordsGHS3DEnforcedVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
651     if (it_coords_enf != _coordsEnfVertexMap.end()) {
652       // Success
653       MESSAGE("Found enforced vertex with coords " << x << ", " << y << ", " << z);
654       oldEnfVertex = it_coords_enf->second;
655       _coordsEnfVertexMap.erase(it_coords_enf);
656       _enfVertexCoordsSizeList.erase(_enfVertexCoordsSizeList.find(coords));
657     } else {
658       // Fail
659       MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found");
660       throw std::invalid_argument(msg.str());
661     }
662   }
663
664   MESSAGE("Remove enf vertex from _enfVertexList");
665
666   // update _enfVertexList
667   TGHS3DEnforcedVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
668   if (it != _enfVertexList.end()) {
669     if ((*it)->groupName != "")
670       _groupsToRemove.insert((*it)->groupName);
671     _enfVertexList.erase(it);
672     toNotify = true;
673     MESSAGE("Done");
674   }
675
676   if (toNotify)
677     NotifySubMeshesHypothesisModification();
678
679   return toNotify;
680 }
681
682 //=======================================================================
683 //function : ClearEnforcedVertices
684 //=======================================================================
685 void GHS3DPlugin_Hypothesis::ClearEnforcedVertices()
686 {
687   TGHS3DEnforcedVertexList::const_iterator it = _enfVertexList.begin();
688   for(;it != _enfVertexList.end();++it) {
689     if ((*it)->groupName != "")
690       _groupsToRemove.insert((*it)->groupName);
691   }
692   _enfVertexList.clear();
693   _coordsEnfVertexMap.clear();
694   _geomEntryEnfVertexMap.clear();
695   _enfVertexCoordsSizeList.clear();
696   _enfVertexEntrySizeList.clear();
697   NotifySubMeshesHypothesisModification();
698 }
699
700 //=======================================================================
701 //function : ClearEnforcedMeshes
702 //=======================================================================
703 void GHS3DPlugin_Hypothesis::ClearEnforcedMeshes()
704 {
705   TGHS3DEnforcedMeshList::const_iterator it = _enfMeshList.begin();
706   for(;it != _enfMeshList.end();++it) {
707     if ((*it)->groupName != "")
708       _groupsToRemove.insert((*it)->groupName);
709   }
710   _enfNodes.clear();
711   _enfEdges.clear();
712   _enfTriangles.clear();
713   _nodeIDToSizeMap.clear();
714   _enfMeshList.clear();
715   _entryEnfMeshMap.clear();
716   NotifySubMeshesHypothesisModification();
717 }
718
719 //================================================================================
720 /*!
721  * \brief At mesh loading, restore enforced elements by just loaded enforced meshes
722  */
723 //================================================================================
724
725 void GHS3DPlugin_Hypothesis::RestoreEnfElemsByMeshes()
726 {
727   TGHS3DEnforcedMeshList::const_iterator it = _enfMeshList.begin();
728   for(;it != _enfMeshList.end();++it) {
729     TGHS3DEnforcedMesh* enfMesh = *it;
730     if ( SMESH_Mesh* mesh = GetMeshByPersistentID( enfMesh->persistID ))
731       SetEnforcedMesh( *mesh,
732                        enfMesh->elementType,
733                        enfMesh->name,
734                        enfMesh->entry,
735                        enfMesh->groupName );
736     enfMesh->persistID = -1; // not to restore again
737   }
738 }
739
740 //=======================================================================
741 //function : SetGroupsToRemove
742 //=======================================================================
743
744 void GHS3DPlugin_Hypothesis::ClearGroupsToRemove()
745 {
746   _groupsToRemove.clear();
747 }
748
749
750 //=======================================================================
751 //function : DefaultMeshHoles
752 //=======================================================================
753
754 bool GHS3DPlugin_Hypothesis::DefaultMeshHoles()
755 {
756   return false; // PAL19680
757 }
758
759 //=======================================================================
760 //function : DefaultMaximumMemory
761 //=======================================================================
762
763 #ifndef WIN32
764 #include <sys/sysinfo.h>
765 #else
766 #include <windows.h>
767 #endif
768
769 short  GHS3DPlugin_Hypothesis::DefaultMaximumMemory()
770 {
771 #ifndef WIN32
772   struct sysinfo si;
773   int err = sysinfo( &si );
774   if ( err == 0 ) {
775     int ramMB = si.totalram * si.mem_unit / 1024 / 1024;
776     return (int) ( 0.7 * ramMB );
777   }
778 #else
779   // See http://msdn.microsoft.com/en-us/library/aa366589.aspx
780   MEMORYSTATUSEX statex;
781   statex.dwLength = sizeof (statex);
782   int err = GlobalMemoryStatusEx (&statex);
783   if (err != 0) {
784     int totMB = 
785       statex.ullTotalPhys / 1024 / 1024 +
786       statex.ullTotalPageFile / 1024 / 1024 +
787       statex.ullTotalVirtual / 1024 / 1024;
788     return (int) ( 0.7 * totMB );
789   }
790 #endif
791   return 1024;
792 }
793
794 //=======================================================================
795 //function : DefaultInitialMemory
796 //=======================================================================
797
798 short  GHS3DPlugin_Hypothesis::DefaultInitialMemory()
799 {
800   return DefaultMaximumMemory();
801 }
802
803 //=======================================================================
804 //function : DefaultOptimizationLevel
805 //=======================================================================
806
807 short  GHS3DPlugin_Hypothesis::DefaultOptimizationLevel()
808 {
809   return Medium;
810 }
811
812 //=======================================================================
813 //function : DefaultWorkingDirectory
814 //=======================================================================
815
816 std::string GHS3DPlugin_Hypothesis::DefaultWorkingDirectory()
817 {
818   TCollection_AsciiString aTmpDir;
819
820   char *Tmp_dir = getenv("SALOME_TMP_DIR");
821   if(Tmp_dir != NULL) {
822     aTmpDir = Tmp_dir;
823   }
824   else {
825 #ifdef WIN32
826     aTmpDir = TCollection_AsciiString("C:\\");
827 #else
828     aTmpDir = TCollection_AsciiString("/tmp/");
829 #endif
830   }
831   return aTmpDir.ToCString();
832 }
833
834 //=======================================================================
835 //function : DefaultKeepFiles
836 //=======================================================================
837
838 bool   GHS3DPlugin_Hypothesis::DefaultKeepFiles()
839 {
840   return false;
841 }
842
843 //=======================================================================
844 //function : DefaultVerboseLevel
845 //=======================================================================
846
847 short  GHS3DPlugin_Hypothesis::DefaultVerboseLevel()
848 {
849   return 10;
850 }
851
852 //=======================================================================
853 //function : DefaultToCreateNewNodes
854 //=======================================================================
855
856 bool GHS3DPlugin_Hypothesis::DefaultToCreateNewNodes()
857 {
858   return true;
859 }
860
861 //=======================================================================
862 //function : DefaultToUseBoundaryRecoveryVersion
863 //=======================================================================
864
865 bool GHS3DPlugin_Hypothesis::DefaultToUseBoundaryRecoveryVersion()
866 {
867   return false;
868 }
869
870 //=======================================================================
871 //function : DefaultToUseFEMCorrection
872 //=======================================================================
873
874 bool GHS3DPlugin_Hypothesis::DefaultToUseFEMCorrection()
875 {
876   return false;
877 }
878
879 //=======================================================================
880 //function : DefaultToRemoveCentralPoint
881 //=======================================================================
882
883 bool GHS3DPlugin_Hypothesis::DefaultToRemoveCentralPoint()
884 {
885   return false;
886 }
887
888 //=======================================================================
889 //function : DefaultGradation
890 //=======================================================================
891
892 double GHS3DPlugin_Hypothesis::DefaultGradation()
893 {
894   return 1.05;
895 }
896
897 // //=======================================================================
898 // //function : DefaultID2SizeMap
899 // //=======================================================================
900 // 
901 // GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::DefaultID2SizeMap()
902 // {
903 //   return GHS3DPlugin_Hypothesis::TID2SizeMap();
904 // }
905
906
907 //=======================================================================
908 //function : SaveTo
909 //=======================================================================
910
911 std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save)
912 {
913   save << (int) myToMeshHoles                 << " ";
914   save << myMaximumMemory                     << " ";
915   save << myInitialMemory                     << " ";
916   save << myOptimizationLevel                 << " ";
917   save << myWorkingDirectory                  << " ";
918   save << (int)myKeepFiles                    << " ";
919   save << myVerboseLevel                      << " ";
920   save << (int)myToCreateNewNodes             << " ";
921   save << (int)myToUseBoundaryRecoveryVersion << " ";
922   save << (int)myToUseFemCorrection           << " ";
923   save << (int)myToRemoveCentralPoint         << " ";
924   save << myGradation                         << " ";
925   if (!myTextOption.empty()) {
926     save << "__OPTIONS_BEGIN__ ";
927     save << myTextOption                      << " ";
928     save << "__OPTIONS_END__ ";
929   }
930   
931
932   TGHS3DEnforcedVertexList::iterator it  = _enfVertexList.begin();
933   if (it != _enfVertexList.end()) {
934     save << " " << "__ENFORCED_VERTICES_BEGIN__ ";
935     for ( ; it != _enfVertexList.end(); ++it ) {
936       TGHS3DEnforcedVertex *enfVertex = (*it);
937       save << " " << "__BEGIN_VERTEX__";
938       if (!enfVertex->name.empty()) {
939         save << " " << "__BEGIN_NAME__";
940         save << " " << enfVertex->name;
941         save << " " << "__END_NAME__";
942       }
943       if (!enfVertex->geomEntry.empty()) {
944         save << " " << "__BEGIN_ENTRY__";
945         save << " " << enfVertex->geomEntry;
946         save << " " << enfVertex->isCompound;
947         save << " " << "__END_ENTRY__";
948       }
949       if (!enfVertex->groupName.empty()) {
950         save << " " << "__BEGIN_GROUP__";
951         save << " " << enfVertex->groupName;
952         save << " " << "__END_GROUP__";
953       }
954       if (enfVertex->coords.size()) {
955         save << " " << "__BEGIN_COORDS__";
956         for (int i=0;i<enfVertex->coords.size();i++)
957           save << " " << enfVertex->coords[i];
958         save << " " << "__END_COORDS__";
959       }
960       save << " " << "__BEGIN_SIZE__";
961       save << " " << enfVertex->size;
962       save << " " << "__END_SIZE__";
963       save << " " << "__END_VERTEX__";
964     }
965     save << " " << "__ENFORCED_VERTICES_END__ ";
966   }
967
968   TGHS3DEnforcedMeshList::iterator it_mesh  = _enfMeshList.begin();
969   if (it_mesh != _enfMeshList.end()) {
970     save << " " << "__ENFORCED_MESHES_BEGIN__ ";
971     for ( ; it_mesh != _enfMeshList.end(); ++it_mesh ) {
972       TGHS3DEnforcedMesh *enfMesh = (*it_mesh);
973       save << " " << "__BEGIN_ENF_MESH__";
974
975       save << " " << "__BEGIN_NAME__";
976       save << " " << enfMesh->name;
977       save << " " << "__END_NAME__";
978
979       save << " " << "__BEGIN_ENTRY__";
980       save << " " << enfMesh->entry;
981       save << " " << "__END_ENTRY__";
982
983       save << " " << "__BEGIN_ELEM_TYPE__";
984       save << " " << (int)enfMesh->elementType;
985       save << " " << "__END_ELEM_TYPE__";
986
987       if (!enfMesh->groupName.empty()) {
988         save << " " << "__BEGIN_GROUP__";
989         save << " " << enfMesh->groupName;
990         save << " " << "__END_GROUP__";
991       }
992       save << " " << "__PERSIST_ID__";
993       save << " " << enfMesh->persistID;
994       save << " " << "__END_ENF_MESH__";
995       std::cout << "Saving of enforced mesh " << enfMesh->name.c_str() << " done" << std::endl;
996     }
997     save << " "  << "__ENFORCED_MESHES_END__ ";
998   }
999   return save;
1000 }
1001
1002 //=======================================================================
1003 //function : LoadFrom
1004 //=======================================================================
1005
1006 std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load)
1007 {
1008   bool isOK = true;
1009   int i;
1010   double d;
1011
1012   isOK = (load >> i);
1013   if (isOK)
1014     myToMeshHoles = i;
1015   else
1016     load.clear(ios::badbit | load.rdstate());
1017
1018   isOK = (load >> i);
1019   if (isOK)
1020     myMaximumMemory = i;
1021   else
1022     load.clear(ios::badbit | load.rdstate());
1023
1024   isOK = (load >> i);
1025   if (isOK)
1026     myInitialMemory = i;
1027   else
1028     load.clear(ios::badbit | load.rdstate());
1029
1030   isOK = (load >> i);
1031   if (isOK)
1032     myOptimizationLevel = i;
1033   else
1034     load.clear(ios::badbit | load.rdstate());
1035
1036   isOK = (load >> myWorkingDirectory);
1037   if (isOK) {
1038     if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty
1039       myKeepFiles = false;
1040       myWorkingDirectory.clear();
1041     }
1042     else if ( myWorkingDirectory == "1" ) {
1043       myKeepFiles = true;
1044       myWorkingDirectory.clear();
1045     }
1046   }
1047   else
1048     load.clear(ios::badbit | load.rdstate());
1049
1050   if ( !myWorkingDirectory.empty() ) {
1051     isOK = (load >> i);
1052     if (isOK)
1053       myKeepFiles = i;
1054     else
1055       load.clear(ios::badbit | load.rdstate());
1056   }
1057
1058   isOK = (load >> i);
1059   if (isOK)
1060     myVerboseLevel = (short) i;
1061   else
1062     load.clear(ios::badbit | load.rdstate());
1063
1064   isOK = (load >> i);
1065   if (isOK)
1066     myToCreateNewNodes = (bool) i;
1067   else
1068     load.clear(ios::badbit | load.rdstate());
1069
1070   isOK = (load >> i);
1071   if (isOK)
1072     myToUseBoundaryRecoveryVersion = (bool) i;
1073   else
1074     load.clear(ios::badbit | load.rdstate());
1075
1076   isOK = (load >> i);
1077   if (isOK)
1078     myToUseFemCorrection = (bool) i;
1079   else
1080     load.clear(ios::badbit | load.rdstate());
1081
1082   isOK = (load >> i);
1083   if (isOK)
1084     myToRemoveCentralPoint = (bool) i;
1085   else
1086     load.clear(ios::badbit | load.rdstate());
1087
1088   isOK = (load >> d);
1089   if (isOK)
1090     myGradation = d;
1091   else
1092     load.clear(ios::badbit | load.rdstate());
1093
1094   std::string separator;
1095   bool hasOptions = false;
1096   bool hasEnforcedVertices = false;
1097   bool hasEnforcedMeshes = false;
1098   isOK = (load >> separator);
1099
1100   if (isOK) {
1101     if (separator == "__OPTIONS_BEGIN__")
1102       hasOptions = true;
1103     else if (separator == "__ENFORCED_VERTICES_BEGIN__")
1104       hasEnforcedVertices = true;
1105     else if (separator == "__ENFORCED_MESHES_BEGIN__")
1106       hasEnforcedMeshes = true;
1107   }
1108
1109   if (hasOptions) {
1110     std::string txt;
1111     while (isOK) {
1112       isOK = (load >> txt);
1113       if (isOK) {
1114         if (txt == "__OPTIONS_END__") {
1115           if (!myTextOption.empty()) {
1116             // Remove last space
1117             myTextOption.erase(myTextOption.end()-1);
1118           }
1119           isOK = false;
1120           break;
1121         }
1122         myTextOption += txt;
1123         myTextOption += " ";
1124       }
1125     }
1126   }
1127
1128   if (hasOptions) {
1129     isOK = (load >> separator);
1130     if (isOK && separator == "__ENFORCED_VERTICES_BEGIN__")
1131       hasEnforcedVertices = true;
1132     if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1133       hasEnforcedMeshes = true;
1134   }
1135
1136   if (hasEnforcedVertices) {
1137     std::string txt, name, entry, groupName;
1138     double size, coords[3];
1139     bool isCompound;
1140     bool hasCoords = false;
1141     isOK = (load >> txt);  // __BEGIN_VERTEX__
1142     while (isOK) {
1143       if (txt == "__ENFORCED_VERTICES_END__")
1144         isOK = false;
1145
1146       TGHS3DEnforcedVertex *enfVertex = new TGHS3DEnforcedVertex();
1147       while (isOK) {
1148         isOK = (load >> txt);
1149         if (txt == "__END_VERTEX__") {
1150           enfVertex->name = name;
1151           enfVertex->geomEntry = entry;
1152           enfVertex->isCompound = isCompound;
1153           enfVertex->groupName = groupName;
1154           enfVertex->coords.clear();
1155           if (hasCoords)
1156             enfVertex->coords.assign(coords,coords+3);
1157
1158           _enfVertexList.insert(enfVertex);
1159
1160           if (enfVertex->coords.size())
1161             _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
1162           if (!enfVertex->geomEntry.empty())
1163             _geomEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
1164
1165           name.clear();
1166           entry.clear();
1167           groupName.clear();
1168           hasCoords = false;
1169           isOK = false;
1170         }
1171
1172         if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
1173           while (isOK && (txt != "__END_NAME__")) {
1174             isOK = (load >> txt);
1175             if (txt != "__END_NAME__") {
1176               if (!name.empty())
1177                 name += " ";
1178               name += txt;
1179             }
1180           }
1181           MESSAGE("name: " <<name);
1182         }
1183
1184         if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
1185           isOK = (load >> entry);
1186           isOK = (load >> isCompound);
1187           isOK = (load >> txt); // __END_ENTRY__
1188           if (txt != "__END_ENTRY__")
1189             throw std::exception();
1190           MESSAGE("entry: " << entry);
1191         }
1192
1193         if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
1194           while (isOK && (txt != "__END_GROUP__")) {
1195             isOK = (load >> txt);
1196             if (txt != "__END_GROUP__") {
1197               if (!groupName.empty())
1198                 groupName += " ";
1199               groupName += txt;
1200             }
1201           }
1202           MESSAGE("groupName: " << groupName);
1203         }
1204
1205         if (txt == "__BEGIN_COORDS__") {  // __BEGIN_COORDS__
1206           hasCoords = true;
1207           isOK = (load >> coords[0] >> coords[1] >> coords[2]);
1208           isOK = (load >> txt); // __END_COORDS__
1209           if (txt != "__END_COORDS__")
1210             throw std::exception();
1211           MESSAGE("coords: " << coords[0] <<","<< coords[1] <<","<< coords[2]);
1212         }
1213
1214         if (txt == "__BEGIN_SIZE__") {  // __BEGIN_ENTRY__
1215           isOK = (load >> size);
1216           isOK = (load >> txt); // __END_ENTRY__
1217           if (txt != "__END_SIZE__") {
1218             throw std::exception();
1219           }
1220           MESSAGE("size: " << size);
1221         }
1222       }
1223       isOK = (load >> txt);  // __BEGIN_VERTEX__
1224     }
1225   }
1226
1227   if (hasEnforcedVertices) {
1228     isOK = (load >> separator);
1229     if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1230       hasEnforcedMeshes = true;
1231   }
1232
1233   if (hasEnforcedMeshes) {
1234     std::string txt, name, entry, groupName;
1235     int elementType = -1, persistID = -1;
1236     isOK = (load >> txt);  // __BEGIN_ENF_MESH__
1237     while (isOK) {
1238       //                if (isOK) {
1239       if (txt == "__ENFORCED_MESHES_END__")
1240         isOK = false;
1241
1242       TGHS3DEnforcedMesh *enfMesh = new TGHS3DEnforcedMesh();
1243       while (isOK) {
1244         isOK = (load >> txt);
1245         if (txt == "__END_ENF_MESH__") {
1246           enfMesh->name = name;
1247           enfMesh->entry = entry;
1248           enfMesh->elementType = (SMESH::ElementType)elementType;
1249           enfMesh->groupName = groupName;
1250           enfMesh->persistID = persistID;
1251
1252           _enfMeshList.insert(enfMesh);
1253           std::cout << "Restoring of enforced mesh " <<name  << " done" << std::endl;
1254
1255           name.clear();
1256           entry.clear();
1257           elementType = -1;
1258           groupName.clear();
1259           persistID = -1;
1260           isOK = false;
1261         }
1262
1263         if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
1264           while (isOK && (txt != "__END_NAME__")) {
1265             isOK = (load >> txt);
1266             if (txt != "__END_NAME__") {
1267               if (!name.empty())
1268                 name += " ";
1269               name += txt;
1270             }
1271           }
1272           MESSAGE("name: " <<name);
1273         }
1274
1275         if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
1276           isOK = (load >> entry);
1277           isOK = (load >> txt); // __END_ENTRY__
1278           if (txt != "__END_ENTRY__")
1279             throw std::exception();
1280           MESSAGE("entry: " << entry);
1281         }
1282
1283         if (txt == "__BEGIN_ELEM_TYPE__") {  // __BEGIN_ELEM_TYPE__
1284           isOK = (load >> elementType);
1285           isOK = (load >> txt); // __END_ELEM_TYPE__
1286           if (txt != "__END_ELEM_TYPE__")
1287             throw std::exception();
1288           MESSAGE("elementType: " << elementType);
1289         }
1290
1291         if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
1292           while (isOK && (txt != "__END_GROUP__")) {
1293             isOK = (load >> txt);
1294             if (txt != "__END_GROUP__") {
1295               if (!groupName.empty())
1296                 groupName += " ";
1297               groupName += txt;
1298             }
1299           } // while
1300           MESSAGE("groupName: " << groupName);
1301         } // if
1302
1303         if (txt == "__PERSIST_ID__") {
1304           isOK = (load >> persistID);
1305           MESSAGE("persistID: " << persistID);
1306         }
1307         std::cout << "isOK: " << isOK << std::endl;
1308       } // while
1309       //                } // if
1310       isOK = (load >> txt);  // __BEGIN_ENF_MESH__
1311     } // while
1312   } // if
1313
1314   return load;
1315 }
1316
1317 //=======================================================================
1318 //function : SetParametersByMesh
1319 //=======================================================================
1320
1321 bool GHS3DPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoDS_Shape&)
1322 {
1323   return false;
1324 }
1325
1326
1327 //================================================================================
1328 /*!
1329  * \brief Return false
1330  */
1331 //================================================================================
1332
1333 bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  /*dflts*/,
1334                                                      const SMESH_Mesh* /*theMesh*/)
1335 {
1336   return false;
1337 }
1338
1339 //================================================================================
1340 /*!
1341  * \brief Return command to run ghs3d mesher excluding file prefix (-f)
1342  */
1343 //================================================================================
1344
1345 std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp,
1346                                                  const bool         hasShapeToMesh)
1347 {
1348   TCollection_AsciiString cmd;
1349   cmd = "mg-tetra.exe";
1350   // check if any option is overridden by hyp->myTextOption
1351   bool m   = hyp ? ( hyp->myTextOption.find("-m")  == std::string::npos ) : true;
1352   bool M   = hyp ? ( hyp->myTextOption.find("-M")  == std::string::npos ) : true;
1353   bool c   = hyp ? ( hyp->myTextOption.find("-c")  == std::string::npos ) : true;
1354   bool o   = hyp ? ( hyp->myTextOption.find("-o")  == std::string::npos ) : true;
1355   bool p0  = hyp ? ( hyp->myTextOption.find("-p0") == std::string::npos ) : true;
1356   bool C   = hyp ? ( hyp->myTextOption.find("-C")  == std::string::npos ) : true;
1357   bool v   = hyp ? ( hyp->myTextOption.find("-v")  == std::string::npos ) : true;
1358   bool fem = hyp ? ( hyp->myTextOption.find("-FEM")== std::string::npos ) : true;
1359   bool rem = hyp ? ( hyp->myTextOption.find("-no_initial_central_point")== std::string::npos ) : true;
1360   bool gra = hyp ? ( hyp->myTextOption.find("-Dcpropa")== std::string::npos ) : true;
1361
1362   // if use boundary recovery version, few options are allowed
1363   bool useBndRecovery = !C;
1364   if ( !useBndRecovery && hyp )
1365     useBndRecovery = hyp->myToUseBoundaryRecoveryVersion;
1366
1367   // ghs3d needs to know amount of memory it may use (MB).
1368   // Default memory is defined at ghs3d installation but it may be not enough,
1369   // so allow to use about all available memory
1370   if ( m ) {
1371     short aMaximumMemory = hyp ? hyp->myMaximumMemory : -1;
1372     cmd += " -m ";
1373     if ( aMaximumMemory < 0 )
1374       cmd += DefaultMaximumMemory();
1375     else
1376       cmd += aMaximumMemory;
1377   }
1378   if ( M && !useBndRecovery ) {
1379     short aInitialMemory = hyp ? hyp->myInitialMemory : -1;
1380     cmd += " -M ";
1381     if ( aInitialMemory > 0 )
1382       cmd += aInitialMemory;
1383     else
1384       cmd += "100";
1385   }
1386   // component to mesh
1387   // 0 , all components to be meshed
1388   // 1 , only the main ( outermost ) component to be meshed
1389   if ( c && !useBndRecovery ) {
1390     // We always run GHS3D with "to mesh holes'==TRUE (see PAL19680)
1391     if ( hasShapeToMesh )
1392       cmd += " -c 0";
1393     else {
1394       bool aToMeshHoles = hyp ? hyp->myToMeshHoles : DefaultMeshHoles();
1395       if ( aToMeshHoles )
1396         cmd += " -c 0";
1397       else
1398         cmd += " -c 1";
1399     }
1400   }
1401
1402   // optimization level
1403   if ( o && hyp && !useBndRecovery ) {
1404     if ( hyp->myOptimizationLevel >= 0 && hyp->myOptimizationLevel < 5 ) {
1405       const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" };
1406       cmd += " -o ";
1407       cmd += level[ hyp->myOptimizationLevel ];
1408     }
1409   }
1410
1411   // to create internal nodes
1412   if ( p0 && hyp && !hyp->myToCreateNewNodes ) {
1413     cmd += " -p0";
1414   }
1415
1416   // verbose mode
1417   if ( v && hyp ) {
1418     cmd += " -v ";
1419     cmd += hyp->myVerboseLevel;
1420   }
1421
1422   // boundary recovery version
1423   if ( useBndRecovery ) {
1424     cmd += " -C";
1425   }
1426
1427   // to use FEM correction
1428   if ( fem && hyp && hyp->myToUseFemCorrection) {
1429     cmd += " -FEM";
1430   }
1431
1432   // to remove initial central point.
1433   if ( rem && hyp && hyp->myToRemoveCentralPoint) {
1434     cmd += " -no_initial_central_point";
1435   }
1436
1437   // options as text
1438   if ( hyp && !hyp->myTextOption.empty() ) {
1439     cmd += " ";
1440     cmd += (char*) hyp->myTextOption.c_str();
1441   }
1442
1443   // to define volumic gradation.
1444   if ( gra && hyp) {
1445     cmd += " -Dcpropa=";
1446     cmd += hyp->myGradation;
1447   }
1448
1449 #ifdef WNT
1450   cmd += " < NUL";
1451 #endif
1452
1453   return cmd.ToCString();
1454 }
1455
1456 //================================================================================
1457 /*!
1458  * \brief Return a unique file name
1459  */
1460 //================================================================================
1461
1462 std::string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hyp)
1463 {
1464   std::string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory();
1465   const char lastChar = *aTmpDir.rbegin();
1466 #ifdef WIN32
1467     if(lastChar != '\\') aTmpDir+='\\';
1468 #else
1469     if(lastChar != '/') aTmpDir+='/';
1470 #endif      
1471
1472   TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str();
1473   aGenericName += "GHS3D_";
1474   aGenericName += getpid();
1475   aGenericName += "_";
1476   aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString());
1477
1478   return aGenericName.ToCString();
1479 }
1480
1481
1482 //================================================================================
1483 /*!
1484 * \brief Return the enforced vertices
1485 */
1486 //================================================================================
1487
1488 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexList GHS3DPlugin_Hypothesis::GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp)
1489 {
1490   return hyp ? hyp->_GetEnforcedVertices():DefaultGHS3DEnforcedVertexList();
1491 }
1492
1493 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesCoordsSize (const GHS3DPlugin_Hypothesis* hyp)
1494 {  
1495   return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): DefaultGHS3DEnforcedVertexCoordsValues();
1496 }
1497
1498 GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexEntryValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesEntrySize (const GHS3DPlugin_Hypothesis* hyp)
1499 {  
1500   return hyp ? hyp->_GetEnforcedVerticesEntrySize(): DefaultGHS3DEnforcedVertexEntryValues();
1501 }
1502
1503 GHS3DPlugin_Hypothesis::TCoordsGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByCoords (const GHS3DPlugin_Hypothesis* hyp)
1504 {  
1505   return hyp ? hyp->_GetEnforcedVerticesByCoords(): DefaultCoordsGHS3DEnforcedVertexMap();
1506 }
1507
1508 GHS3DPlugin_Hypothesis::TGeomEntryGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByEntry (const GHS3DPlugin_Hypothesis* hyp)
1509 {  
1510   return hyp ? hyp->_GetEnforcedVerticesByEntry(): DefaultGeomEntryGHS3DEnforcedVertexMap();
1511 }
1512
1513 GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap GHS3DPlugin_Hypothesis::GetEnforcedNodes(const GHS3DPlugin_Hypothesis* hyp)
1514 {
1515   return hyp ? hyp->_GetEnforcedNodes():DefaultIDSortedNodeGroupMap();
1516 }
1517
1518 GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedEdges(const GHS3DPlugin_Hypothesis* hyp)
1519 {
1520   return hyp ? hyp->_GetEnforcedEdges():DefaultIDSortedElemGroupMap();
1521 }
1522
1523 GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedTriangles(const GHS3DPlugin_Hypothesis* hyp)
1524 {
1525   return hyp ? hyp->_GetEnforcedTriangles():DefaultIDSortedElemGroupMap();
1526 }
1527
1528 GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::GetNodeIDToSizeMap(const GHS3DPlugin_Hypothesis* hyp)
1529 {
1530   return hyp ? hyp->_GetNodeIDToSizeMap(): DefaultID2SizeMap();
1531 }
1532
1533 GHS3DPlugin_Hypothesis::TSetStrings GHS3DPlugin_Hypothesis::GetGroupsToRemove(const GHS3DPlugin_Hypothesis* hyp)
1534 {
1535   return hyp ? hyp->_GetGroupsToRemove(): DefaultGroupsToRemove();
1536 }