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