Salome HOME
select faces group for layer ok
[plugins/hybridplugin.git] / src / HYBRIDPlugin / HYBRIDPlugin_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      : HYBRIDPlugin_Hypothesis.cxx
22 // Created   : Wed Apr  2 12:36:29 2008
23 // Author    : Edward AGAPOV (eap)
24 //=============================================================================
25 //
26 #include "HYBRIDPlugin_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 WIN32
34 #include <process.h>
35 #define getpid _getpid
36 #endif
37
38 //=======================================================================
39 //function : HYBRIDPlugin_Hypothesis
40 //=======================================================================
41
42 HYBRIDPlugin_Hypothesis::HYBRIDPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen)
43   : SMESH_Hypothesis(hypId, studyId, gen),
44   myToMeshHoles(DefaultMeshHoles()),
45   myToMakeGroupsOfDomains(DefaultToMakeGroupsOfDomains()),
46   myMaximumMemory(-1),
47   myInitialMemory(-1),
48   myOptimizationLevel(DefaultOptimizationLevel()),
49   myCollisionMode(DefaultCollisionMode()),
50   myBoundaryLayersGrowth(DefaultBoundaryLayersGrowth()),
51   myElementGeneration(DefaultElementGeneration()),
52   myAddMultinormals(DefaultAddMultinormals()),
53   mySmoothNormals(DefaultSmoothNormals()),
54   myHeightFirstLayer(DefaultHeightFirstLayer()),
55   myBoundaryLayersProgression(DefaultBoundaryLayersProgression()),
56   myMultinormalsAngle(DefaultMultinormalsAngle()),
57   myNbOfBoundaryLayers(DefaultNbOfBoundaryLayers()),
58   myWorkingDirectory(DefaultWorkingDirectory()),
59   myKeepFiles(DefaultKeepFiles()),
60   myVerboseLevel(DefaultVerboseLevel()),
61   myToCreateNewNodes(DefaultToCreateNewNodes()),
62   myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()),
63   myToUseFemCorrection(DefaultToUseFEMCorrection()),
64   myToRemoveCentralPoint(DefaultToRemoveCentralPoint()),
65   myGradation(DefaultGradation()),
66   myLogInStandardOutput(DefaultStandardOutputLog()),
67   _enfVertexList(DefaultHYBRIDEnforcedVertexList()),
68   _enfVertexCoordsSizeList(DefaultHYBRIDEnforcedVertexCoordsValues()),
69   _enfVertexEntrySizeList(DefaultHYBRIDEnforcedVertexEntryValues()),
70   _coordsEnfVertexMap(DefaultCoordsHYBRIDEnforcedVertexMap()),
71   _geomEntryEnfVertexMap(DefaultGeomEntryHYBRIDEnforcedVertexMap()),
72   _enfMeshList(DefaultHYBRIDEnforcedMeshList()),
73   _entryEnfMeshMap(DefaultEntryHYBRIDEnforcedMeshListMap()),
74   _enfNodes(TIDSortedNodeGroupMap()),
75   _enfEdges(TIDSortedElemGroupMap()),
76   _enfTriangles(TIDSortedElemGroupMap()),
77   _nodeIDToSizeMap(DefaultID2SizeMap()),
78   _groupsToRemove(DefaultGroupsToRemove())
79 {
80   _name = "HYBRID_Parameters";
81   _param_algo_dim = 3;
82 }
83
84 //=======================================================================
85 //function : SetToMeshHoles
86 //=======================================================================
87
88 void HYBRIDPlugin_Hypothesis::SetToMeshHoles(bool toMesh)
89 {
90   if ( myToMeshHoles != toMesh ) {
91     myToMeshHoles = toMesh;
92     NotifySubMeshesHypothesisModification();
93   }
94 }
95
96 //=======================================================================
97 //function : GetToMeshHoles
98 //=======================================================================
99
100 bool HYBRIDPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const
101 {
102   if (checkFreeOption && !myTextOption.empty()) {
103     if ( myTextOption.find("-c 0"))
104       return true;
105     if ( myTextOption.find("-c 1"))
106       return false;
107   }
108   return myToMeshHoles;
109 }
110
111 //=======================================================================
112 //function : SetToMakeGroupsOfDomains
113 //=======================================================================
114
115 void HYBRIDPlugin_Hypothesis::SetToMakeGroupsOfDomains(bool toMakeGroups)
116 {
117   if ( myToMakeGroupsOfDomains != toMakeGroups ) {
118     myToMakeGroupsOfDomains = toMakeGroups;
119     NotifySubMeshesHypothesisModification();
120   }
121 }
122
123 //=======================================================================
124 //function : GetToMakeGroupsOfDomains
125 //=======================================================================
126
127 bool HYBRIDPlugin_Hypothesis::GetToMakeGroupsOfDomains() const
128 {
129   return myToMakeGroupsOfDomains;
130 }
131
132 //=======================================================================
133 //function : GetToMakeGroupsOfDomains
134 //=======================================================================
135
136 bool HYBRIDPlugin_Hypothesis::GetToMakeGroupsOfDomains(const HYBRIDPlugin_Hypothesis* hyp)
137 {
138   bool res;
139   if ( hyp ) res = /*hyp->GetToMeshHoles(true) &&*/ hyp->GetToMakeGroupsOfDomains();
140   else       res = /*DefaultMeshHoles()        &&*/ DefaultToMakeGroupsOfDomains();
141   return res;
142 }
143
144 //=======================================================================
145 //function : SetMaximumMemory
146 //=======================================================================
147
148 void HYBRIDPlugin_Hypothesis::SetMaximumMemory(double MB)
149 {
150   if ( myMaximumMemory != MB ) {
151     myMaximumMemory = MB;
152     NotifySubMeshesHypothesisModification();
153   }
154 }
155
156 //=======================================================================
157 //function : GetMaximumMemory
158 //           * automatic memory adjustment mode. Default is zero
159 //=======================================================================
160
161 double HYBRIDPlugin_Hypothesis::GetMaximumMemory() const
162 {
163   return myMaximumMemory;
164 }
165
166 //=======================================================================
167 //function : SetInitialMemory
168 //=======================================================================
169
170 void HYBRIDPlugin_Hypothesis::SetInitialMemory(double MB)
171 {
172   if ( myInitialMemory != MB ) {
173     myInitialMemory = MB;
174     NotifySubMeshesHypothesisModification();
175   }
176 }
177
178 //=======================================================================
179 //function : GetInitialMemory
180 //=======================================================================
181
182 double HYBRIDPlugin_Hypothesis::GetInitialMemory() const
183 {
184   return myInitialMemory;
185 }
186
187 //=======================================================================
188 //function : SetOptimizationLevel
189 //=======================================================================
190
191 void HYBRIDPlugin_Hypothesis::SetOptimizationLevel(OptimizationLevel level)
192 {
193   if ( myOptimizationLevel != level ) {
194     myOptimizationLevel = level;
195     NotifySubMeshesHypothesisModification();
196   }
197 }
198
199 //=======================================================================
200 //function : GetOptimizationLevel
201 //=======================================================================
202 HYBRIDPlugin_Hypothesis::OptimizationLevel HYBRIDPlugin_Hypothesis::GetOptimizationLevel() const
203 {
204   return (OptimizationLevel) myOptimizationLevel;
205 }
206
207 //=======================================================================
208 //function : SetCollisionMode
209 //=======================================================================
210 void HYBRIDPlugin_Hypothesis::SetCollisionMode(CollisionMode mode)
211 {
212   if ( myCollisionMode != mode ) {
213     myCollisionMode = mode;
214     NotifySubMeshesHypothesisModification();
215   }
216 }
217
218 //=======================================================================
219 //function : GetCollisionMode
220 //=======================================================================
221 HYBRIDPlugin_Hypothesis::CollisionMode HYBRIDPlugin_Hypothesis::GetCollisionMode() const
222 {
223   return (CollisionMode) myCollisionMode;
224 }
225
226 //=======================================================================
227 //function : SetBoundaryLayersGrowth
228 //=======================================================================
229 void HYBRIDPlugin_Hypothesis::SetBoundaryLayersGrowth(BoundaryLayersGrowth mode)
230 {
231   if ( myBoundaryLayersGrowth != mode ) {
232     myBoundaryLayersGrowth = mode;
233     NotifySubMeshesHypothesisModification();
234   }
235 }
236
237 //=======================================================================
238 //function : GetBoundaryLayersGrowth
239 //=======================================================================
240 HYBRIDPlugin_Hypothesis::BoundaryLayersGrowth HYBRIDPlugin_Hypothesis::GetBoundaryLayersGrowth() const
241 {
242   return (BoundaryLayersGrowth) myBoundaryLayersGrowth;
243 }
244
245 //=======================================================================
246 //function : SetElementGeneration
247 //=======================================================================
248 void HYBRIDPlugin_Hypothesis::SetElementGeneration(ElementGeneration mode)
249 {
250   if ( myElementGeneration != mode ) {
251     myElementGeneration = mode;
252     NotifySubMeshesHypothesisModification();
253   }
254 }
255
256 //=======================================================================
257 //function : GetElementGeneration
258 //=======================================================================
259 HYBRIDPlugin_Hypothesis::ElementGeneration HYBRIDPlugin_Hypothesis::GetElementGeneration() const
260 {
261   return (ElementGeneration) myElementGeneration;
262 }
263
264 //=======================================================================
265 //function : SetAddMultinormals
266 //=======================================================================
267 void HYBRIDPlugin_Hypothesis::SetAddMultinormals(bool toAddMultinormals)
268 {
269   if ( myAddMultinormals != toAddMultinormals ) {
270     myAddMultinormals = toAddMultinormals;
271     NotifySubMeshesHypothesisModification();
272   }
273 }
274
275 //=======================================================================
276 //function : GetAddMultinormals
277 //=======================================================================
278
279 bool HYBRIDPlugin_Hypothesis::GetAddMultinormals() const
280 {
281   return myAddMultinormals;
282 }
283
284 //=======================================================================
285 //function : SetSmoothNormals
286 //=======================================================================
287
288 void HYBRIDPlugin_Hypothesis::SetSmoothNormals(bool toSmoothNormals)
289 {
290   if ( mySmoothNormals != toSmoothNormals ) {
291     mySmoothNormals = toSmoothNormals;
292     NotifySubMeshesHypothesisModification();
293   }
294 }
295
296 //=======================================================================
297 //function : GetSmoothNormals
298 //=======================================================================
299
300 bool HYBRIDPlugin_Hypothesis::GetSmoothNormals() const
301 {
302   return mySmoothNormals;
303 }
304
305 //=======================================================================
306 //function : SetHeightFirstLayer
307 //=======================================================================
308
309 void HYBRIDPlugin_Hypothesis::SetHeightFirstLayer(double toHeightFirstLayer)
310 {
311   if ( myHeightFirstLayer != toHeightFirstLayer ) {
312     myHeightFirstLayer = toHeightFirstLayer;
313     NotifySubMeshesHypothesisModification();
314   }
315 }
316
317 //=======================================================================
318 //function : GetHeightFirstLayer
319 //=======================================================================
320
321 double HYBRIDPlugin_Hypothesis::GetHeightFirstLayer() const
322 {
323   return myHeightFirstLayer;
324 }
325
326 //=======================================================================
327 //function : SetBoundaryLayersProgression
328 //=======================================================================
329
330 void HYBRIDPlugin_Hypothesis::SetBoundaryLayersProgression(double toBoundaryLayersProgression)
331 {
332   if ( myBoundaryLayersProgression != toBoundaryLayersProgression ) {
333     myBoundaryLayersProgression = toBoundaryLayersProgression;
334     NotifySubMeshesHypothesisModification();
335   }
336 }
337
338 //=======================================================================
339 //function : GetBoundaryLayersProgression
340 //=======================================================================
341
342 double HYBRIDPlugin_Hypothesis::GetBoundaryLayersProgression() const
343 {
344   return myBoundaryLayersProgression;
345 }
346
347 //=======================================================================
348 //function : SetMultinormalsAngle
349 //=======================================================================
350
351 void HYBRIDPlugin_Hypothesis::SetMultinormalsAngle(double toMultinormalsAngle)
352 {
353   if ( myMultinormalsAngle != toMultinormalsAngle ) {
354     myMultinormalsAngle = toMultinormalsAngle;
355     NotifySubMeshesHypothesisModification();
356   }
357 }
358
359 //=======================================================================
360 //function : GetMultinormalsAngle
361 //=======================================================================
362
363 double HYBRIDPlugin_Hypothesis::GetMultinormalsAngle() const
364 {
365   return myMultinormalsAngle;
366 }
367
368 //=======================================================================
369 //function : SetNbOfBoundaryLayers
370 //=======================================================================
371
372 void HYBRIDPlugin_Hypothesis::SetNbOfBoundaryLayers(short toNbOfBoundaryLayers)
373 {
374   if ( myNbOfBoundaryLayers != toNbOfBoundaryLayers ) {
375     myNbOfBoundaryLayers = toNbOfBoundaryLayers;
376     NotifySubMeshesHypothesisModification();
377   }
378 }
379
380 //=======================================================================
381 //function : GetMultinormalsAngle
382 //=======================================================================
383
384 short HYBRIDPlugin_Hypothesis::GetNbOfBoundaryLayers() const
385 {
386   return myNbOfBoundaryLayers;
387 }
388
389
390 /////////////////////////////////////////////////////////////////////////
391
392
393 //=======================================================================
394 //function : SetWorkingDirectory
395 //=======================================================================
396
397 void HYBRIDPlugin_Hypothesis::SetWorkingDirectory(const std::string& path)
398 {
399   if ( myWorkingDirectory != path ) {
400     myWorkingDirectory = path;
401     NotifySubMeshesHypothesisModification();
402   }
403 }
404
405 //=======================================================================
406 //function : GetWorkingDirectory
407 //=======================================================================
408
409 std::string HYBRIDPlugin_Hypothesis::GetWorkingDirectory() const
410 {
411   return myWorkingDirectory;
412 }
413
414 //=======================================================================
415 //function : SetKeepFiles
416 //=======================================================================
417
418 void HYBRIDPlugin_Hypothesis::SetKeepFiles(bool toKeep)
419 {
420   if ( myKeepFiles != toKeep ) {
421     myKeepFiles = toKeep;
422     NotifySubMeshesHypothesisModification();
423   }
424 }
425
426 //=======================================================================
427 //function : GetKeepFiles
428 //=======================================================================
429
430 bool HYBRIDPlugin_Hypothesis::GetKeepFiles() const
431 {
432   return myKeepFiles;
433 }
434
435 //=======================================================================
436 //function : SetVerboseLevel
437 //=======================================================================
438
439 void HYBRIDPlugin_Hypothesis::SetVerboseLevel(short level)
440 {
441   if ( myVerboseLevel != level ) {
442     myVerboseLevel = level;
443     NotifySubMeshesHypothesisModification();
444   }
445 }
446
447 //=======================================================================
448 //function : GetVerboseLevel
449 //=======================================================================
450
451 short HYBRIDPlugin_Hypothesis::GetVerboseLevel() const
452 {
453   return myVerboseLevel;
454 }
455
456 //=======================================================================
457 //function : SetToCreateNewNodes
458 //=======================================================================
459
460 void HYBRIDPlugin_Hypothesis::SetToCreateNewNodes(bool toCreate)
461 {
462   if ( myToCreateNewNodes != toCreate ) {
463     myToCreateNewNodes = toCreate;
464     NotifySubMeshesHypothesisModification();
465   }
466 }
467
468 //=======================================================================
469 //function : GetToCreateNewNodes
470 //=======================================================================
471
472 bool HYBRIDPlugin_Hypothesis::GetToCreateNewNodes() const
473 {
474   return myToCreateNewNodes;
475 }
476
477 //=======================================================================
478 //function : SetToUseBoundaryRecoveryVersion
479 //=======================================================================
480
481 void HYBRIDPlugin_Hypothesis::SetToUseBoundaryRecoveryVersion(bool toUse)
482 {
483   if ( myToUseBoundaryRecoveryVersion != toUse ) {
484     myToUseBoundaryRecoveryVersion = toUse;
485     NotifySubMeshesHypothesisModification();
486   }
487 }
488
489 //=======================================================================
490 //function : GetToUseBoundaryRecoveryVersion
491 //=======================================================================
492
493 bool HYBRIDPlugin_Hypothesis::GetToUseBoundaryRecoveryVersion() const
494 {
495   return myToUseBoundaryRecoveryVersion;
496 }
497
498 //=======================================================================
499 //function : SetFEMCorrection
500 //=======================================================================
501
502 void HYBRIDPlugin_Hypothesis::SetFEMCorrection(bool toUseFem)
503 {
504   if ( myToUseFemCorrection != toUseFem ) {
505     myToUseFemCorrection = toUseFem;
506     NotifySubMeshesHypothesisModification();
507   }
508 }
509
510 //=======================================================================
511 //function : GetFEMCorrection
512 //=======================================================================
513
514 bool HYBRIDPlugin_Hypothesis::GetFEMCorrection() const
515 {
516   return myToUseFemCorrection;
517 }
518
519 //=======================================================================
520 //function : SetToRemoveCentralPoint
521 //=======================================================================
522
523 void HYBRIDPlugin_Hypothesis::SetToRemoveCentralPoint(bool toRemove)
524 {
525   if ( myToRemoveCentralPoint != toRemove ) {
526     myToRemoveCentralPoint = toRemove;
527     NotifySubMeshesHypothesisModification();
528   }
529 }
530
531 //=======================================================================
532 //function : GetToRemoveCentralPoint
533 //=======================================================================
534
535 bool HYBRIDPlugin_Hypothesis::GetToRemoveCentralPoint() const
536 {
537   return myToRemoveCentralPoint;
538 }
539
540 //=======================================================================
541 //function : SetTextOption
542 //=======================================================================
543
544 void HYBRIDPlugin_Hypothesis::SetTextOption(const std::string& option)
545 {
546   if ( myTextOption != option ) {
547     myTextOption = option;
548     NotifySubMeshesHypothesisModification();
549   }
550 }
551
552 //=======================================================================
553 //function : GetTextOption
554 //=======================================================================
555
556 std::string HYBRIDPlugin_Hypothesis::GetTextOption() const
557 {
558   return myTextOption;
559 }
560
561 //=======================================================================
562 //function : SetGradation
563 //=======================================================================
564
565 void HYBRIDPlugin_Hypothesis::SetGradation(double gradation)
566 {
567   if ( myGradation != gradation ) {
568     myGradation = gradation;
569     NotifySubMeshesHypothesisModification();
570   }
571 }
572
573 //=======================================================================
574 //function : GetGradation
575 //=======================================================================
576
577 double HYBRIDPlugin_Hypothesis::GetGradation() const
578 {
579   return myGradation;
580 }
581
582 //=======================================================================
583 //function : SetStandardOutputLog
584 //=======================================================================
585
586 void HYBRIDPlugin_Hypothesis::SetStandardOutputLog(bool logInStandardOutput)
587 {
588   if ( myLogInStandardOutput != logInStandardOutput ) {
589     myLogInStandardOutput = logInStandardOutput;
590     NotifySubMeshesHypothesisModification();
591   }
592 }
593
594 //=======================================================================
595 //function : GetStandardOutputLog
596 //=======================================================================
597
598 bool HYBRIDPlugin_Hypothesis::GetStandardOutputLog() const
599 {
600   return myLogInStandardOutput;
601 }
602
603 //=======================================================================
604 //function : SetRemoveLogOnSuccess
605 //=======================================================================
606
607 void HYBRIDPlugin_Hypothesis::SetRemoveLogOnSuccess(bool removeLogOnSuccess)
608 {
609   if ( myRemoveLogOnSuccess != removeLogOnSuccess ) {
610     myRemoveLogOnSuccess = removeLogOnSuccess;
611     NotifySubMeshesHypothesisModification();
612   }
613 }
614
615 //=======================================================================
616 //function : GetRemoveLogOnSuccess
617 //=======================================================================
618
619 bool HYBRIDPlugin_Hypothesis::GetRemoveLogOnSuccess() const
620 {
621   return myRemoveLogOnSuccess;
622 }
623
624 //=======================================================================
625 //function : SetEnforcedVertex
626 //=======================================================================
627
628 bool HYBRIDPlugin_Hypothesis::SetEnforcedVertex(std::string theName, std::string theEntry, std::string theGroupName,
629                                                double size, double x, double y, double z, bool isCompound)
630 {
631   MESSAGE("HYBRIDPlugin_Hypothesis::SetEnforcedVertex(\""<< theName << "\", \""<< theEntry << "\", \"" << theGroupName << "\", "
632                                                       << size << ", " << x << ", " << y << ", " << z  << ", "<< isCompound << ")");
633
634   bool toNotify = false;
635   bool toCreate = true;
636
637   THYBRIDEnforcedVertex *oldEnVertex;
638   THYBRIDEnforcedVertex *newEnfVertex = new THYBRIDEnforcedVertex();
639   newEnfVertex->name = theName;
640   newEnfVertex->geomEntry = theEntry;
641   newEnfVertex->coords.clear();
642   if (!isCompound) {
643     newEnfVertex->coords.push_back(x);
644     newEnfVertex->coords.push_back(y);
645     newEnfVertex->coords.push_back(z);
646   }
647   newEnfVertex->groupName = theGroupName;
648   newEnfVertex->size = size;
649   newEnfVertex->isCompound = isCompound;
650   
651   
652   // update _enfVertexList
653   THYBRIDEnforcedVertexList::iterator it = _enfVertexList.find(newEnfVertex);
654   if (it != _enfVertexList.end()) {
655     toCreate = false;
656     oldEnVertex = (*it);
657     MESSAGE("Enforced Vertex was found => Update");
658     if (oldEnVertex->name != theName) {
659       MESSAGE("Update name from \"" << oldEnVertex->name << "\" to \"" << theName << "\"");
660       oldEnVertex->name = theName;
661       toNotify = true;
662     }
663     if (oldEnVertex->groupName != theGroupName) {
664       MESSAGE("Update group name from \"" << oldEnVertex->groupName << "\" to \"" << theGroupName << "\"");
665       oldEnVertex->groupName = theGroupName;
666       toNotify = true;
667     }
668     if (oldEnVertex->size != size) {
669       MESSAGE("Update size from \"" << oldEnVertex->size << "\" to \"" << size << "\"");
670       oldEnVertex->size = size;
671       toNotify = true;
672     }
673     if (toNotify) {
674       // update map coords / enf vertex if needed
675       if (oldEnVertex->coords.size()) {
676         _coordsEnfVertexMap[oldEnVertex->coords] = oldEnVertex;
677         _enfVertexCoordsSizeList[oldEnVertex->coords] = size;
678       }
679
680       // update map geom entry / enf vertex if needed
681       if (oldEnVertex->geomEntry != "") {
682         _geomEntryEnfVertexMap[oldEnVertex->geomEntry] = oldEnVertex;
683         _enfVertexEntrySizeList[oldEnVertex->geomEntry] = size;
684       }
685     }
686   }
687
688 //   //////// CREATE ////////////
689   if (toCreate) {
690     toNotify = true;
691     MESSAGE("Creating new enforced vertex");
692     _enfVertexList.insert(newEnfVertex);
693     if (theEntry == "") {
694       _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex;
695       _enfVertexCoordsSizeList[newEnfVertex->coords] = size;
696     }
697     else {
698       _geomEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex;
699       _enfVertexEntrySizeList[newEnfVertex->geomEntry] = size;
700     }
701   }
702
703   if (toNotify)
704     NotifySubMeshesHypothesisModification();
705
706   MESSAGE("HYBRIDPlugin_Hypothesis::SetEnforcedVertex END");
707   return toNotify;
708 }
709
710
711 //=======================================================================
712 //function : SetEnforcedMesh
713 //=======================================================================
714 bool HYBRIDPlugin_Hypothesis::SetEnforcedMesh(SMESH_Mesh& theMesh, SMESH::ElementType elementType, std::string name, std::string entry, std::string groupName)
715 {
716   TIDSortedElemSet theElemSet;
717   SMDS_ElemIteratorPtr eIt = theMesh.GetMeshDS()->elementsIterator(SMDSAbs_ElementType(elementType));
718   while ( eIt->more() )
719     theElemSet.insert( eIt->next() );
720   MESSAGE("Add "<<theElemSet.size()<<" types["<<elementType<<"] from source mesh");
721   bool added = SetEnforcedElements( theElemSet, elementType, groupName);
722   if (added) {
723     THYBRIDEnforcedMesh* newEnfMesh = new THYBRIDEnforcedMesh();
724     newEnfMesh->persistID   = theMesh.GetMeshDS()->GetPersistentId();
725     newEnfMesh->name        = name;
726     newEnfMesh->entry       = entry;
727     newEnfMesh->elementType = elementType;
728     newEnfMesh->groupName   = groupName;
729     
730     THYBRIDEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
731     if (it == _enfMeshList.end()) {
732       _entryEnfMeshMap[entry].insert(newEnfMesh);
733       _enfMeshList.insert(newEnfMesh);
734     }
735     else {
736       delete newEnfMesh;
737     }
738   }
739   return added;
740 }
741
742 //=======================================================================
743 //function : SetEnforcedGroup
744 //=======================================================================
745 bool HYBRIDPlugin_Hypothesis::SetEnforcedGroup(const SMESHDS_Mesh* theMeshDS, SMESH::long_array_var theIDs, SMESH::ElementType elementType, std::string name, std::string entry, std::string groupName)
746 {
747   MESSAGE("HYBRIDPlugin_Hypothesis::SetEnforcedGroup");
748   TIDSortedElemSet theElemSet;
749     if ( theIDs->length() == 0 ){MESSAGE("The source group is empty");}
750     for (int i=0; i < theIDs->length(); i++) {
751       CORBA::Long ind = theIDs[i];
752       if (elementType == SMESH::NODE)
753       {
754         const SMDS_MeshNode * node = theMeshDS->FindNode(ind);
755         if (node)
756           theElemSet.insert( node );
757       }
758       else
759       {
760         const SMDS_MeshElement * elem = theMeshDS->FindElement(ind);
761         if (elem)
762           theElemSet.insert( elem );
763       }
764     }
765
766 //   SMDS_ElemIteratorPtr it = theGroup->GetGroupDS()->GetElements();
767 //   while ( it->more() ) 
768 //     theElemSet.insert( it->next() );
769
770   MESSAGE("Add "<<theElemSet.size()<<" types["<<elementType<<"] from source group ");
771   bool added = SetEnforcedElements( theElemSet, elementType, groupName);
772   if (added) {
773     THYBRIDEnforcedMesh* newEnfMesh = new THYBRIDEnforcedMesh();
774     newEnfMesh->name = name;
775     newEnfMesh->entry = entry;
776     newEnfMesh->elementType = elementType;
777     newEnfMesh->groupName = groupName;
778     
779     THYBRIDEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
780     if (it == _enfMeshList.end()) {
781       _entryEnfMeshMap[entry].insert(newEnfMesh);
782       _enfMeshList.insert(newEnfMesh);
783     }
784   }
785   return added;
786 }
787
788 //=======================================================================
789 //function : SetEnforcedElements
790 //=======================================================================
791 bool HYBRIDPlugin_Hypothesis::SetEnforcedElements(TIDSortedElemSet theElemSet, SMESH::ElementType elementType, std::string groupName)
792 {
793   MESSAGE("HYBRIDPlugin_Hypothesis::SetEnforcedElements");
794   TIDSortedElemSet::const_iterator it = theElemSet.begin();
795   const SMDS_MeshElement* elem;
796   const SMDS_MeshNode* node;
797   bool added = true;
798   pair<TIDSortedNodeGroupMap::iterator,bool> nodeRet;
799   pair<TIDSortedElemGroupMap::iterator,bool> elemRet;
800
801   for (;it != theElemSet.end();++it)
802   {
803     elem = (*it);
804     switch (elementType) {
805       case SMESH::NODE:
806         node = dynamic_cast<const SMDS_MeshNode*>(elem);
807         if (node) {
808           nodeRet = _enfNodes.insert(make_pair(node,groupName));
809           added = added && nodeRet.second;
810           string msg = added ? "yes":"no";
811           MESSAGE( "Node (" <<node->X()<<","<<node->Y()<<","<<node->Z()<< ") with ID " << node->GetID() <<" added ? " << msg);
812         }
813         else {
814           SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
815           for (;nodeIt->more();) {
816             node = dynamic_cast<const SMDS_MeshNode*>(nodeIt->next());
817             nodeRet = _enfNodes.insert(make_pair(node,groupName));
818             added = added && nodeRet.second;
819           }
820 //          added = true;s
821         }
822         break;
823       case SMESH::EDGE:
824         if (elem->GetType() == SMDSAbs_Edge) {
825           elemRet = _enfEdges.insert(make_pair(elem,groupName));
826           added = added && elemRet.second;
827         }
828         else if (elem->GetType() > SMDSAbs_Edge) {
829           SMDS_ElemIteratorPtr it = elem->edgesIterator();
830           for (;it->more();) {
831             const SMDS_MeshElement* anEdge = it->next();
832             elemRet = _enfEdges.insert(make_pair(anEdge,groupName));
833             added = added && elemRet.second;
834           }
835         }
836         break;
837       case SMESH::FACE:
838         if (elem->GetType() == SMDSAbs_Face)
839         {
840           if (elem->NbCornerNodes() == 3) {
841             elemRet = _enfTriangles.insert(make_pair(elem,groupName));
842             added = added && elemRet.second;
843           }
844         }
845         else if (elem->GetType() > SMDSAbs_Face) { // Group of faces
846           SMDS_ElemIteratorPtr it = elem->facesIterator();
847           for (;it->more();) {
848             const SMDS_MeshElement* aFace = it->next();
849             if (aFace->NbCornerNodes() == 3) {
850               elemRet = _enfTriangles.insert(make_pair(aFace,groupName));
851               added = added && elemRet.second;
852             }
853           }
854         }
855         break;
856       default:
857         break;
858     };
859   }
860   if (added)
861     NotifySubMeshesHypothesisModification();
862   return added;
863 }
864
865
866 //=======================================================================
867 //function : GetEnforcedVertex
868 //=======================================================================
869
870 HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertex* HYBRIDPlugin_Hypothesis::GetEnforcedVertex(double x, double y, double z)
871   throw (std::invalid_argument)
872 {
873   std::vector<double> coord(3);
874   coord[0] = x;
875   coord[1] = y;
876   coord[2] = z;
877   if (_coordsEnfVertexMap.count(coord)>0)
878     return _coordsEnfVertexMap[coord];
879   std::ostringstream msg ;
880   msg << "No enforced vertex at " << x << ", " << y << ", " << z;
881   throw std::invalid_argument(msg.str());
882 }
883
884 HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertex* HYBRIDPlugin_Hypothesis::GetEnforcedVertex(const std::string theEntry)
885   throw (std::invalid_argument)
886 {
887   if (_geomEntryEnfVertexMap.count(theEntry)>0)
888     return _geomEntryEnfVertexMap[theEntry];
889   
890   std::ostringstream msg ;
891   msg << "No enforced vertex with entry " << theEntry;
892   throw std::invalid_argument(msg.str());
893 }
894
895 //=======================================================================
896 //function : RemoveEnforcedVertex
897 //=======================================================================
898
899 bool HYBRIDPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z, const std::string theEntry)
900   throw (std::invalid_argument)
901 {
902   bool toNotify = false;
903   std::ostringstream msg;
904   THYBRIDEnforcedVertex *oldEnfVertex;
905   std::vector<double> coords(3);
906   coords[0] = x;
907   coords[1] = y;
908   coords[2] = z;
909   
910   // check that enf vertex with given enf vertex entry exists
911   TGeomEntryHYBRIDEnforcedVertexMap::iterator it_enfVertexEntry = _geomEntryEnfVertexMap.find(theEntry);
912   if (it_enfVertexEntry != _geomEntryEnfVertexMap.end()) {
913     // Success
914     MESSAGE("Found enforced vertex with geom entry " << theEntry);
915     oldEnfVertex = it_enfVertexEntry->second;
916     _geomEntryEnfVertexMap.erase(it_enfVertexEntry);
917   } else {
918     // Fail
919     MESSAGE("Enforced vertex with geom entry " << theEntry << " not found");
920     // check that enf vertex with given coords exists
921     TCoordsHYBRIDEnforcedVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
922     if (it_coords_enf != _coordsEnfVertexMap.end()) {
923       // Success
924       MESSAGE("Found enforced vertex with coords " << x << ", " << y << ", " << z);
925       oldEnfVertex = it_coords_enf->second;
926       _coordsEnfVertexMap.erase(it_coords_enf);
927       _enfVertexCoordsSizeList.erase(_enfVertexCoordsSizeList.find(coords));
928     } else {
929       // Fail
930       MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found");
931       throw std::invalid_argument(msg.str());
932     }
933   }
934
935   MESSAGE("Remove enf vertex from _enfVertexList");
936
937   // update _enfVertexList
938   THYBRIDEnforcedVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
939   if (it != _enfVertexList.end()) {
940     if ((*it)->groupName != "")
941       _groupsToRemove.insert((*it)->groupName);
942     _enfVertexList.erase(it);
943     toNotify = true;
944     MESSAGE("Done");
945   }
946
947   if (toNotify)
948     NotifySubMeshesHypothesisModification();
949
950   return toNotify;
951 }
952
953 //=======================================================================
954 //function : ClearEnforcedVertices
955 //=======================================================================
956 void HYBRIDPlugin_Hypothesis::ClearEnforcedVertices()
957 {
958   THYBRIDEnforcedVertexList::const_iterator it = _enfVertexList.begin();
959   for(;it != _enfVertexList.end();++it) {
960     if ((*it)->groupName != "")
961       _groupsToRemove.insert((*it)->groupName);
962   }
963   _enfVertexList.clear();
964   _coordsEnfVertexMap.clear();
965   _geomEntryEnfVertexMap.clear();
966   _enfVertexCoordsSizeList.clear();
967   _enfVertexEntrySizeList.clear();
968   NotifySubMeshesHypothesisModification();
969 }
970
971 //=======================================================================
972 //function : ClearEnforcedMeshes
973 //=======================================================================
974 void HYBRIDPlugin_Hypothesis::ClearEnforcedMeshes()
975 {
976   THYBRIDEnforcedMeshList::const_iterator it = _enfMeshList.begin();
977   for(;it != _enfMeshList.end();++it) {
978     if ((*it)->groupName != "")
979       _groupsToRemove.insert((*it)->groupName);
980   }
981   _enfNodes.clear();
982   _enfEdges.clear();
983   _enfTriangles.clear();
984   _nodeIDToSizeMap.clear();
985   _enfMeshList.clear();
986   _entryEnfMeshMap.clear();
987   NotifySubMeshesHypothesisModification();
988 }
989
990 //================================================================================
991 /*!
992  * \brief At mesh loading, restore enforced elements by just loaded enforced meshes
993  */
994 //================================================================================
995
996 void HYBRIDPlugin_Hypothesis::RestoreEnfElemsByMeshes()
997 {
998   THYBRIDEnforcedMeshList::const_iterator it = _enfMeshList.begin();
999   for(;it != _enfMeshList.end();++it) {
1000     THYBRIDEnforcedMesh* enfMesh = *it;
1001     if ( SMESH_Mesh* mesh = GetMeshByPersistentID( enfMesh->persistID ))
1002       SetEnforcedMesh( *mesh,
1003                        enfMesh->elementType,
1004                        enfMesh->name,
1005                        enfMesh->entry,
1006                        enfMesh->groupName );
1007     enfMesh->persistID = -1; // not to restore again
1008   }
1009 }
1010
1011 //=======================================================================
1012 //function : SetGroupsToRemove
1013 //=======================================================================
1014
1015 void HYBRIDPlugin_Hypothesis::ClearGroupsToRemove()
1016 {
1017   _groupsToRemove.clear();
1018 }
1019
1020
1021 //=======================================================================
1022 //function : DefaultMeshHoles
1023 //=======================================================================
1024
1025 bool HYBRIDPlugin_Hypothesis::DefaultMeshHoles()
1026 {
1027   return false; // PAL19680
1028 }
1029
1030 //=======================================================================
1031 //function : DefaultToMakeGroupsOfDomains
1032 //=======================================================================
1033
1034 bool HYBRIDPlugin_Hypothesis::DefaultToMakeGroupsOfDomains()
1035 {
1036   return false; // issue 0022172
1037 }
1038
1039 //=======================================================================
1040 //function : DefaultMaximumMemory
1041 //=======================================================================
1042
1043 #ifndef WIN32
1044 #include <sys/sysinfo.h>
1045 #else
1046 #include <windows.h>
1047 #endif
1048
1049 double  HYBRIDPlugin_Hypothesis::DefaultMaximumMemory()
1050 {
1051 #ifndef WIN32
1052   struct sysinfo si;
1053   int err = sysinfo( &si );
1054   if ( err == 0 ) {
1055     int ramMB = si.totalram * si.mem_unit / 1024 / 1024;
1056     return ( 0.7 * ramMB );
1057   }
1058 #else
1059   // See http://msdn.microsoft.com/en-us/library/aa366589.aspx
1060   MEMORYSTATUSEX statex;
1061   statex.dwLength = sizeof (statex);
1062   int err = GlobalMemoryStatusEx (&statex);
1063   if (err != 0) {
1064     int totMB = 
1065       statex.ullTotalPhys / 1024 / 1024 +
1066       statex.ullTotalPageFile / 1024 / 1024 +
1067       statex.ullTotalVirtual / 1024 / 1024;
1068     return ( 0.7 * totMB );
1069   }
1070 #endif
1071   return 1024;
1072 }
1073
1074 //=======================================================================
1075 //function : DefaultInitialMemory
1076 //=======================================================================
1077
1078 double  HYBRIDPlugin_Hypothesis::DefaultInitialMemory()
1079 {
1080   return DefaultMaximumMemory();
1081 }
1082
1083 //=======================================================================
1084 //function : DefaultCollisionMode
1085 //=======================================================================
1086 short  HYBRIDPlugin_Hypothesis::DefaultCollisionMode()
1087 {
1088   return Decrease;
1089 }
1090
1091 //=======================================================================
1092 //function : DefaultBoundaryLayersGrowth
1093 //=======================================================================
1094 short  HYBRIDPlugin_Hypothesis::DefaultBoundaryLayersGrowth()
1095 {
1096   return Layer_Growth_Inward;
1097 }
1098
1099 //=======================================================================
1100 //function : DefaultElementGeneration
1101 //=======================================================================
1102 short  HYBRIDPlugin_Hypothesis::DefaultElementGeneration()
1103 {
1104   return Generation_Tetra_Dominant;
1105 }
1106
1107 //=======================================================================
1108 //function : DefaultOptimizationLevel
1109 //=======================================================================
1110 short  HYBRIDPlugin_Hypothesis::DefaultOptimizationLevel()
1111 {
1112   return Medium;
1113 }
1114
1115 //=======================================================================
1116 //function : DefaultWorkingDirectory
1117 //=======================================================================
1118
1119 std::string HYBRIDPlugin_Hypothesis::DefaultWorkingDirectory()
1120 {
1121   TCollection_AsciiString aTmpDir;
1122
1123   char *Tmp_dir = getenv("SALOME_TMP_DIR");
1124   if(Tmp_dir != NULL) {
1125     aTmpDir = Tmp_dir;
1126   }
1127   else {
1128 #ifdef WIN32
1129     aTmpDir = TCollection_AsciiString("C:\\");
1130 #else
1131     aTmpDir = TCollection_AsciiString("/tmp/");
1132 #endif
1133   }
1134   return aTmpDir.ToCString();
1135 }
1136
1137 //=======================================================================
1138 //function : DefaultKeepFiles
1139 //=======================================================================
1140
1141 bool   HYBRIDPlugin_Hypothesis::DefaultKeepFiles()
1142 {
1143   return false;
1144 }
1145
1146 //=======================================================================
1147 //function : DefaultRemoveLogOnSuccess
1148 //=======================================================================
1149
1150 bool   HYBRIDPlugin_Hypothesis::DefaultRemoveLogOnSuccess()
1151 {
1152   return false;
1153 }
1154
1155
1156 //=======================================================================
1157 //function : DefaultVerboseLevel
1158 //=======================================================================
1159
1160 short  HYBRIDPlugin_Hypothesis::DefaultVerboseLevel()
1161 {
1162   return 10;
1163 }
1164
1165 //=======================================================================
1166 //function : DefaultToCreateNewNodes
1167 //=======================================================================
1168
1169 bool HYBRIDPlugin_Hypothesis::DefaultToCreateNewNodes()
1170 {
1171   return true;
1172 }
1173
1174 //=======================================================================
1175 //function : DefaultToUseBoundaryRecoveryVersion
1176 //=======================================================================
1177
1178 bool HYBRIDPlugin_Hypothesis::DefaultToUseBoundaryRecoveryVersion()
1179 {
1180   return false;
1181 }
1182
1183 //=======================================================================
1184 //function : DefaultToUseFEMCorrection
1185 //=======================================================================
1186
1187 bool HYBRIDPlugin_Hypothesis::DefaultToUseFEMCorrection()
1188 {
1189   return false;
1190 }
1191
1192 //=======================================================================
1193 //function : DefaultToRemoveCentralPoint
1194 //=======================================================================
1195
1196 bool HYBRIDPlugin_Hypothesis::DefaultToRemoveCentralPoint()
1197 {
1198   return false;
1199 }
1200
1201 //=======================================================================
1202 //function : DefaultGradation
1203 //=======================================================================
1204
1205 double HYBRIDPlugin_Hypothesis::DefaultGradation()
1206 {
1207   return 1.05;
1208 }
1209
1210 //=======================================================================
1211 //function : DefaultStandardOutputLog
1212 //=======================================================================
1213
1214 bool HYBRIDPlugin_Hypothesis::DefaultStandardOutputLog()
1215 {
1216   return false;
1217 }
1218
1219 // //=======================================================================
1220 // //function : DefaultID2SizeMap
1221 // //=======================================================================
1222 // 
1223 // HYBRIDPlugin_Hypothesis::TID2SizeMap HYBRIDPlugin_Hypothesis::DefaultID2SizeMap()
1224 // {
1225 //   return HYBRIDPlugin_Hypothesis::TID2SizeMap();
1226 // }
1227
1228 //=======================================================================
1229 //function : DefaultAddMultinormals
1230 //=======================================================================
1231 bool HYBRIDPlugin_Hypothesis::DefaultAddMultinormals()
1232 {
1233   return false;
1234 }
1235
1236 //=======================================================================
1237 //function : DefaultSmoothNormals
1238 //=======================================================================
1239 bool HYBRIDPlugin_Hypothesis::DefaultSmoothNormals()
1240 {
1241   return false;
1242 }
1243
1244 //=======================================================================
1245 //function : DefaultHeightFirstLayer
1246 //=======================================================================
1247 double HYBRIDPlugin_Hypothesis::DefaultHeightFirstLayer()
1248 {
1249   return 0.0; //or epsilon?
1250 }
1251
1252 //=======================================================================
1253 //function : DefaultBoundaryLayersProgression
1254 //=======================================================================
1255 double HYBRIDPlugin_Hypothesis::DefaultBoundaryLayersProgression()
1256 {
1257   return 1.0;
1258 }
1259
1260 //=======================================================================
1261 //function : DefaultMultinormalsAngle
1262 //=======================================================================
1263 double HYBRIDPlugin_Hypothesis::DefaultMultinormalsAngle()
1264 {
1265   return 30.0;
1266 }
1267
1268 //=======================================================================
1269 //function : DefaultNbOfBoundaryLayers
1270 //=======================================================================
1271 short HYBRIDPlugin_Hypothesis::DefaultNbOfBoundaryLayers()
1272 {
1273   return 1;
1274 }
1275
1276 //=======================================================================
1277 //function : SaveTo
1278 //=======================================================================
1279
1280 std::ostream & HYBRIDPlugin_Hypothesis::SaveTo(std::ostream & save)
1281 {
1282   save << (int) myBoundaryLayersGrowth << " ";
1283   save << (int) myElementGeneration << " ";
1284   save << (int) myAddMultinormals << " ";
1285   save << (int) mySmoothNormals << " ";
1286
1287   save << myNbOfBoundaryLayers << " ";
1288   save << myHeightFirstLayer << " ";
1289   save << myBoundaryLayersProgression << " ";
1290   save << myMultinormalsAngle << " ";
1291
1292   save << (int) myKeepFiles << " ";
1293   save << myWorkingDirectory << " ";
1294   save << myVerboseLevel << " ";
1295   if (!myTextOption.empty()) {
1296     save << "__OPTIONS_BEGIN__ ";
1297     save << myTextOption << " ";
1298     save << "__OPTIONS_END__ ";
1299   }
1300   
1301
1302   THYBRIDEnforcedVertexList::iterator it  = _enfVertexList.begin();
1303   if (it != _enfVertexList.end()) {
1304     save << " " << "__ENFORCED_VERTICES_BEGIN__ ";
1305     for ( ; it != _enfVertexList.end(); ++it ) {
1306       THYBRIDEnforcedVertex *enfVertex = (*it);
1307       save << " " << "__BEGIN_VERTEX__";
1308       if (!enfVertex->name.empty()) {
1309         save << " " << "__BEGIN_NAME__";
1310         save << " " << enfVertex->name;
1311         save << " " << "__END_NAME__";
1312       }
1313       if (!enfVertex->geomEntry.empty()) {
1314         save << " " << "__BEGIN_ENTRY__";
1315         save << " " << enfVertex->geomEntry;
1316         save << " " << enfVertex->isCompound;
1317         save << " " << "__END_ENTRY__";
1318       }
1319       if (!enfVertex->groupName.empty()) {
1320         save << " " << "__BEGIN_GROUP__";
1321         save << " " << enfVertex->groupName;
1322         save << " " << "__END_GROUP__";
1323       }
1324       if (enfVertex->coords.size()) {
1325         save << " " << "__BEGIN_COORDS__";
1326         for (int i=0;i<enfVertex->coords.size();i++)
1327           save << " " << enfVertex->coords[i];
1328         save << " " << "__END_COORDS__";
1329       }
1330       save << " " << "__BEGIN_SIZE__";
1331       save << " " << enfVertex->size;
1332       save << " " << "__END_SIZE__";
1333       save << " " << "__END_VERTEX__";
1334     }
1335     save << " " << "__ENFORCED_VERTICES_END__ ";
1336   }
1337
1338   THYBRIDEnforcedMeshList::iterator it_mesh  = _enfMeshList.begin();
1339   if (it_mesh != _enfMeshList.end()) {
1340     save << " " << "__ENFORCED_MESHES_BEGIN__ ";
1341     for ( ; it_mesh != _enfMeshList.end(); ++it_mesh ) {
1342       THYBRIDEnforcedMesh *enfMesh = (*it_mesh);
1343       save << " " << "__BEGIN_ENF_MESH__";
1344
1345       save << " " << "__BEGIN_NAME__";
1346       save << " " << enfMesh->name;
1347       save << " " << "__END_NAME__";
1348
1349       save << " " << "__BEGIN_ENTRY__";
1350       save << " " << enfMesh->entry;
1351       save << " " << "__END_ENTRY__";
1352
1353       save << " " << "__BEGIN_ELEM_TYPE__";
1354       save << " " << (int)enfMesh->elementType;
1355       save << " " << "__END_ELEM_TYPE__";
1356
1357       if (!enfMesh->groupName.empty()) {
1358         save << " " << "__BEGIN_GROUP__";
1359         save << " " << enfMesh->groupName;
1360         save << " " << "__END_GROUP__";
1361       }
1362       save << " " << "__PERSIST_ID__";
1363       save << " " << enfMesh->persistID;
1364       save << " " << "__END_ENF_MESH__";
1365       std::cout << "Saving of enforced mesh " << enfMesh->name.c_str() << " done" << std::endl;
1366     }
1367     save << " "  << "__ENFORCED_MESHES_END__ ";
1368   }
1369   return save;
1370 }
1371
1372 //=======================================================================
1373 //function : LoadFrom
1374 //=======================================================================
1375
1376 std::istream & HYBRIDPlugin_Hypothesis::LoadFrom(std::istream & load)
1377 {
1378   bool isOK = true;
1379   int i;
1380   double d;
1381
1382   isOK = (load >> i);
1383   if (isOK)
1384     myBoundaryLayersGrowth = (short) i;
1385   else
1386     load.clear(ios::badbit | load.rdstate());
1387
1388   isOK = (load >> i);
1389   if (isOK)
1390     myElementGeneration = (short) i;
1391   else
1392     load.clear(ios::badbit | load.rdstate());
1393
1394   isOK = (load >> i);
1395   if (isOK)
1396     myAddMultinormals = (bool) i;
1397   else
1398     load.clear(ios::badbit | load.rdstate());
1399
1400   isOK = (load >> i);
1401   if (isOK)
1402     mySmoothNormals = (bool) i;
1403   else
1404     load.clear(ios::badbit | load.rdstate());
1405
1406   isOK = (load >> i);
1407   if (isOK)
1408     myNbOfBoundaryLayers = (short) i;
1409   else
1410     load.clear(ios::badbit | load.rdstate());
1411
1412   isOK = (load >> d);
1413   if (isOK)
1414     myHeightFirstLayer = d;
1415   else
1416     load.clear(ios::badbit | load.rdstate());
1417
1418   isOK = (load >> d);
1419   if (isOK)
1420     myBoundaryLayersProgression = d;
1421   else
1422     load.clear(ios::badbit | load.rdstate());
1423
1424   isOK = (load >> d);
1425   if (isOK)
1426     myMultinormalsAngle = d;
1427   else
1428     load.clear(ios::badbit | load.rdstate());
1429
1430   isOK = (load >> i);
1431   if (isOK)
1432     myKeepFiles = (bool) i;
1433   else
1434     load.clear(ios::badbit | load.rdstate());
1435
1436   isOK = (load >> myWorkingDirectory);
1437   if (isOK) {
1438     if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty
1439       myKeepFiles = false;
1440       myWorkingDirectory.clear();
1441     }
1442     else if ( myWorkingDirectory == "1" ) {
1443       myKeepFiles = true;
1444       myWorkingDirectory.clear();
1445     }
1446   }
1447   else
1448     load.clear(ios::badbit | load.rdstate());
1449
1450   if ( !myWorkingDirectory.empty() ) {
1451     isOK = (load >> i);
1452     if (isOK)
1453       myKeepFiles = i;
1454     else
1455       load.clear(ios::badbit | load.rdstate());
1456   }
1457
1458   isOK = (load >> i);
1459   if (isOK)
1460     myVerboseLevel = (short) i;
1461   else
1462     load.clear(ios::badbit | load.rdstate());
1463
1464
1465   std::string separator;
1466   bool hasOptions = false;
1467   bool hasEnforcedVertices = false;
1468   bool hasEnforcedMeshes = false;
1469   isOK = (load >> separator);
1470
1471   if ( isOK && ( separator == "0" || separator == "1" ))
1472   {
1473     myToMakeGroupsOfDomains = ( separator == "1" );
1474     isOK = (load >> separator);
1475   }
1476
1477   if (isOK) {
1478     if (separator == "__OPTIONS_BEGIN__")
1479       hasOptions = true;
1480     else if (separator == "__ENFORCED_VERTICES_BEGIN__")
1481       hasEnforcedVertices = true;
1482     else if (separator == "__ENFORCED_MESHES_BEGIN__")
1483       hasEnforcedMeshes = true;
1484   }
1485
1486   if (hasOptions) {
1487     std::string txt;
1488     while (isOK) {
1489       isOK = (load >> txt);
1490       if (isOK) {
1491         if (txt == "__OPTIONS_END__") {
1492           if (!myTextOption.empty()) {
1493             // Remove last space
1494             myTextOption.erase(myTextOption.end()-1);
1495           }
1496           isOK = false;
1497           break;
1498         }
1499         myTextOption += txt;
1500         myTextOption += " ";
1501       }
1502     }
1503   }
1504
1505   if (hasOptions) {
1506     isOK = (load >> separator);
1507     if (isOK && separator == "__ENFORCED_VERTICES_BEGIN__")
1508       hasEnforcedVertices = true;
1509     if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1510       hasEnforcedMeshes = true;
1511   }
1512
1513   if (hasEnforcedVertices) {
1514     std::string txt, name, entry, groupName;
1515     double size, coords[3];
1516     bool isCompound;
1517     bool hasCoords = false;
1518     isOK = (load >> txt);  // __BEGIN_VERTEX__
1519     while (isOK) {
1520       if (txt == "__ENFORCED_VERTICES_END__")
1521         isOK = false;
1522
1523       THYBRIDEnforcedVertex *enfVertex = new THYBRIDEnforcedVertex();
1524       while (isOK) {
1525         isOK = (load >> txt);
1526         if (txt == "__END_VERTEX__") {
1527           enfVertex->name = name;
1528           enfVertex->geomEntry = entry;
1529           enfVertex->isCompound = isCompound;
1530           enfVertex->groupName = groupName;
1531           enfVertex->coords.clear();
1532           if (hasCoords)
1533             enfVertex->coords.assign(coords,coords+3);
1534
1535           _enfVertexList.insert(enfVertex);
1536
1537           if (enfVertex->coords.size())
1538             _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
1539           if (!enfVertex->geomEntry.empty())
1540             _geomEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
1541
1542           name.clear();
1543           entry.clear();
1544           groupName.clear();
1545           hasCoords = false;
1546           isOK = false;
1547         }
1548
1549         if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
1550           while (isOK && (txt != "__END_NAME__")) {
1551             isOK = (load >> txt);
1552             if (txt != "__END_NAME__") {
1553               if (!name.empty())
1554                 name += " ";
1555               name += txt;
1556             }
1557           }
1558           MESSAGE("name: " <<name);
1559         }
1560
1561         if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
1562           isOK = (load >> entry);
1563           isOK = (load >> isCompound);
1564           isOK = (load >> txt); // __END_ENTRY__
1565           if (txt != "__END_ENTRY__")
1566             throw std::exception();
1567           MESSAGE("entry: " << entry);
1568         }
1569
1570         if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
1571           while (isOK && (txt != "__END_GROUP__")) {
1572             isOK = (load >> txt);
1573             if (txt != "__END_GROUP__") {
1574               if (!groupName.empty())
1575                 groupName += " ";
1576               groupName += txt;
1577             }
1578           }
1579           MESSAGE("groupName: " << groupName);
1580         }
1581
1582         if (txt == "__BEGIN_COORDS__") {  // __BEGIN_COORDS__
1583           hasCoords = true;
1584           isOK = (load >> coords[0] >> coords[1] >> coords[2]);
1585           isOK = (load >> txt); // __END_COORDS__
1586           if (txt != "__END_COORDS__")
1587             throw std::exception();
1588           MESSAGE("coords: " << coords[0] <<","<< coords[1] <<","<< coords[2]);
1589         }
1590
1591         if (txt == "__BEGIN_SIZE__") {  // __BEGIN_ENTRY__
1592           isOK = (load >> size);
1593           isOK = (load >> txt); // __END_ENTRY__
1594           if (txt != "__END_SIZE__") {
1595             throw std::exception();
1596           }
1597           MESSAGE("size: " << size);
1598         }
1599       }
1600       isOK = (load >> txt);  // __BEGIN_VERTEX__
1601     }
1602   }
1603
1604   if (hasEnforcedVertices) {
1605     isOK = (load >> separator);
1606     if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1607       hasEnforcedMeshes = true;
1608   }
1609
1610   if (hasEnforcedMeshes) {
1611     std::string txt, name, entry, groupName;
1612     int elementType = -1, persistID = -1;
1613     isOK = (load >> txt);  // __BEGIN_ENF_MESH__
1614     while (isOK) {
1615       //                if (isOK) {
1616       if (txt == "__ENFORCED_MESHES_END__")
1617         isOK = false;
1618
1619       THYBRIDEnforcedMesh *enfMesh = new THYBRIDEnforcedMesh();
1620       while (isOK) {
1621         isOK = (load >> txt);
1622         if (txt == "__END_ENF_MESH__") {
1623           enfMesh->name = name;
1624           enfMesh->entry = entry;
1625           enfMesh->elementType = (SMESH::ElementType)elementType;
1626           enfMesh->groupName = groupName;
1627           enfMesh->persistID = persistID;
1628
1629           _enfMeshList.insert(enfMesh);
1630           std::cout << "Restoring of enforced mesh " <<name  << " done" << std::endl;
1631
1632           name.clear();
1633           entry.clear();
1634           elementType = -1;
1635           groupName.clear();
1636           persistID = -1;
1637           isOK = false;
1638         }
1639
1640         if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
1641           while (isOK && (txt != "__END_NAME__")) {
1642             isOK = (load >> txt);
1643             if (txt != "__END_NAME__") {
1644               if (!name.empty())
1645                 name += " ";
1646               name += txt;
1647             }
1648           }
1649           MESSAGE("name: " <<name);
1650         }
1651
1652         if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
1653           isOK = (load >> entry);
1654           isOK = (load >> txt); // __END_ENTRY__
1655           if (txt != "__END_ENTRY__")
1656             throw std::exception();
1657           MESSAGE("entry: " << entry);
1658         }
1659
1660         if (txt == "__BEGIN_ELEM_TYPE__") {  // __BEGIN_ELEM_TYPE__
1661           isOK = (load >> elementType);
1662           isOK = (load >> txt); // __END_ELEM_TYPE__
1663           if (txt != "__END_ELEM_TYPE__")
1664             throw std::exception();
1665           MESSAGE("elementType: " << elementType);
1666         }
1667
1668         if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
1669           while (isOK && (txt != "__END_GROUP__")) {
1670             isOK = (load >> txt);
1671             if (txt != "__END_GROUP__") {
1672               if (!groupName.empty())
1673                 groupName += " ";
1674               groupName += txt;
1675             }
1676           } // while
1677           MESSAGE("groupName: " << groupName);
1678         } // if
1679
1680         if (txt == "__PERSIST_ID__") {
1681           isOK = (load >> persistID);
1682           MESSAGE("persistID: " << persistID);
1683         }
1684         std::cout << "isOK: " << isOK << std::endl;
1685       } // while
1686       //                } // if
1687       isOK = (load >> txt);  // __BEGIN_ENF_MESH__
1688     } // while
1689   } // if
1690
1691   return load;
1692 }
1693
1694 //=======================================================================
1695 //function : SetParametersByMesh
1696 //=======================================================================
1697
1698 bool HYBRIDPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoDS_Shape&)
1699 {
1700   return false;
1701 }
1702
1703
1704 //================================================================================
1705 /*!
1706  * \brief Sets myToMakeGroupsOfDomains depending on whether theMesh is on shape or not
1707  */
1708 //================================================================================
1709
1710 bool HYBRIDPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  dflts,
1711                                                      const SMESH_Mesh* /*theMesh*/)
1712 {
1713   myToMakeGroupsOfDomains = ( !dflts._shape || dflts._shape->IsNull() );
1714   return true;
1715 }
1716
1717 //================================================================================
1718 /*!
1719  * \brief Return command to run hybrid mesher excluding file prefix (-f)
1720  */
1721 //================================================================================
1722
1723 std::string HYBRIDPlugin_Hypothesis::CommandToRun(const HYBRIDPlugin_Hypothesis* hyp,
1724                                                   const bool         hasShapeToMesh)
1725 {
1726   TCollection_AsciiString cmd = GetExeName().c_str();
1727   // check if any option is overridden by hyp->myTextOption
1728   bool p_h     = ( hyp->myTextOption.find("-h")  != std::string::npos );
1729   bool p_v     = ( hyp->myTextOption.find("-v ")  != std::string::npos );
1730   //bool p_i     = ( hyp->myTextOption.find("-i")  != std::string::npos );
1731   //bool p_o     = ( hyp->myTextOption.find("-o")  != std::string::npos );
1732   bool p_mnot  = ( hyp->myTextOption.find("--max_number_of_threads ")  != std::string::npos );
1733   bool p_blsi  = ( hyp->myTextOption.find("--boundary_layers_surface_ids ")  != std::string::npos );
1734   bool p_blii  = ( hyp->myTextOption.find("--boundary_layers_imprint_ids ")  != std::string::npos );
1735   bool p_blsd  = ( hyp->myTextOption.find("--boundary_layers_subdomain_direction ")  != std::string::npos );
1736   bool p_hotfl = ( hyp->myTextOption.find("--height_of_the_first_layer ")  != std::string::npos );
1737   bool p_nobl  = ( hyp->myTextOption.find("--number_of_boundary_layers ")  != std::string::npos );
1738   bool p_blgp  = ( hyp->myTextOption.find("--boundary_layers_geometric_progression ")  != std::string::npos );
1739   bool p_eg    = ( hyp->myTextOption.find("--element_generation ")  != std::string::npos );
1740   bool p_cm    = ( hyp->myTextOption.find("--collision_mode ")  != std::string::npos );
1741   bool p_am    = ( hyp->myTextOption.find("--add_multinormals ")  != std::string::npos );
1742   bool p_mat   = ( hyp->myTextOption.find("--multinormals_angle_threshold ")  != std::string::npos );
1743   bool p_sn    = ( hyp->myTextOption.find("--smooth_normals ")  != std::string::npos );
1744
1745   //help mode
1746   if ( p_h ) {
1747     cmd += " --help ";
1748 #ifdef WIN32
1749     cmd += " < NUL";
1750 #endif
1751     std::cout << "!!!!! CommandToRun help only !!!! " << cmd.ToCString() << std::endl;
1752     return cmd.ToCString();
1753   }
1754   
1755   if ( !p_v && hyp ) {
1756     cmd += " --verbose ";
1757     cmd += hyp->myVerboseLevel;
1758   }
1759
1760   if ( !p_mnot && hyp ) {
1761     cmd += " --max_number_of_threads ";
1762     cmd += 8; //TODO getenv NB CPU
1763   }
1764   
1765   //if ( !p_blsi && hyp ) {
1766   //  cmd += " --boundary_layers_surface_ids ";
1767   //  cmd += 0; //TODO hyp->my;
1768   //}
1769   
1770   //if ( !p_blii && hyp ) {
1771   //  cmd += " --boundary_layers_imprint_ids ";
1772   //  cmd += 0; //TODO hyp->my;
1773   //}
1774   
1775   cmd += " --boundary_layers_surface_ids 6 "; //as triangles of enforced mesh
1776   
1777   if ( !p_blsd && hyp ) {
1778     if ( hyp->myBoundaryLayersGrowth >= 0 && hyp->myBoundaryLayersGrowth <= 1 ) {
1779       const char* value[] = { "1" , "-1" };
1780       cmd += " --boundary_layers_subdomain_direction ";
1781       cmd += value[ hyp->myBoundaryLayersGrowth ];
1782     }
1783   }
1784   
1785   if ( !p_hotfl && hyp ) {
1786     cmd += " --height_of_the_first_layer ";
1787     cmd += hyp->myHeightFirstLayer;
1788   }
1789   
1790   if ( !p_nobl && hyp ) {
1791     cmd += " --number_of_boundary_layers ";
1792     cmd += hyp->myNbOfBoundaryLayers;
1793   }
1794   
1795   if ( !p_blgp && hyp ) {
1796     cmd += " --boundary_layers_geometric_progression ";
1797     cmd += hyp->myBoundaryLayersProgression;
1798   }
1799   
1800   if ( !p_eg && hyp ) {
1801     if ( hyp->myElementGeneration >= 0 && hyp->myElementGeneration <= 1 ) {
1802       const char* value[] = { "tetra-dominant" , "hexa-dominant" };
1803       cmd += " --element_generation ";
1804       cmd += value[ hyp->myElementGeneration ];
1805     }
1806   }
1807   
1808   if ( !p_cm && hyp ) {
1809     if ( hyp->myCollisionMode >= 0 && hyp->myCollisionMode <= 1 ) {
1810       const char* value[] = { "decrease" , "stop" };
1811       cmd += " --collision_mode ";
1812       cmd += value[ hyp->myCollisionMode ];
1813     }
1814   }
1815   
1816   if ( !p_am && hyp ) {
1817     int res = hyp->myAddMultinormals ? 0 : 1 ;
1818     const char* value[] = { "yes" , "no" };
1819     cmd += " --add_multinormals ";
1820     cmd += value[ res ];
1821   }
1822   
1823   if ( !p_mat && hyp ) {
1824     cmd += " --multinormals_angle_threshold ";
1825     cmd += hyp->myMultinormalsAngle;
1826   }
1827   
1828   if ( !p_sn && hyp ) {
1829     int res = hyp->mySmoothNormals ? 0 : 1 ;
1830     const char* value[] = { "yes" , "no" };
1831     cmd += " --smooth_normals ";
1832     cmd += value[ res ];
1833   }
1834   
1835 #ifdef WIN32
1836   cmd += " < NUL";
1837 #endif
1838   //std::cout << "!!!!!CommandToRun end " << cmd.ToCString() << std::endl;
1839     
1840   return cmd.ToCString();
1841 }
1842
1843 //================================================================================
1844 /*!
1845  * \brief Return a unique file name
1846  */
1847 //================================================================================
1848
1849 std::string HYBRIDPlugin_Hypothesis::GetFileName(const HYBRIDPlugin_Hypothesis* hyp)
1850 {
1851   std::string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory();
1852   const char lastChar = *aTmpDir.rbegin();
1853 #ifdef WIN32
1854     if(lastChar != '\\') aTmpDir+='\\';
1855 #else
1856     if(lastChar != '/') aTmpDir+='/';
1857 #endif
1858
1859   TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str();
1860   aGenericName += "HYBRID_";
1861   aGenericName += getpid();
1862   aGenericName += "_";
1863   aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString());
1864
1865   return aGenericName.ToCString();
1866 }
1867
1868 //================================================================================
1869 /*
1870  * Return the name of executable
1871  */
1872 //================================================================================
1873
1874 std::string HYBRIDPlugin_Hypothesis::GetExeName()
1875 {
1876   return "mg-hybrid.exe";
1877 }
1878
1879 //================================================================================
1880 /*!
1881 * \brief Return the enforced vertices
1882 */
1883 //================================================================================
1884
1885 HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertexList HYBRIDPlugin_Hypothesis::GetEnforcedVertices(const HYBRIDPlugin_Hypothesis* hyp)
1886 {
1887   return hyp ? hyp->_GetEnforcedVertices():DefaultHYBRIDEnforcedVertexList();
1888 }
1889
1890 HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertexCoordsValues HYBRIDPlugin_Hypothesis::GetEnforcedVerticesCoordsSize (const HYBRIDPlugin_Hypothesis* hyp)
1891 {  
1892   return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): DefaultHYBRIDEnforcedVertexCoordsValues();
1893 }
1894
1895 HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertexEntryValues HYBRIDPlugin_Hypothesis::GetEnforcedVerticesEntrySize (const HYBRIDPlugin_Hypothesis* hyp)
1896 {  
1897   return hyp ? hyp->_GetEnforcedVerticesEntrySize(): DefaultHYBRIDEnforcedVertexEntryValues();
1898 }
1899
1900 HYBRIDPlugin_Hypothesis::TCoordsHYBRIDEnforcedVertexMap HYBRIDPlugin_Hypothesis::GetEnforcedVerticesByCoords (const HYBRIDPlugin_Hypothesis* hyp)
1901 {  
1902   return hyp ? hyp->_GetEnforcedVerticesByCoords(): DefaultCoordsHYBRIDEnforcedVertexMap();
1903 }
1904
1905 HYBRIDPlugin_Hypothesis::TGeomEntryHYBRIDEnforcedVertexMap HYBRIDPlugin_Hypothesis::GetEnforcedVerticesByEntry (const HYBRIDPlugin_Hypothesis* hyp)
1906 {  
1907   return hyp ? hyp->_GetEnforcedVerticesByEntry(): DefaultGeomEntryHYBRIDEnforcedVertexMap();
1908 }
1909
1910 HYBRIDPlugin_Hypothesis::TIDSortedNodeGroupMap HYBRIDPlugin_Hypothesis::GetEnforcedNodes(const HYBRIDPlugin_Hypothesis* hyp)
1911 {
1912   return hyp ? hyp->_GetEnforcedNodes():DefaultIDSortedNodeGroupMap();
1913 }
1914
1915 HYBRIDPlugin_Hypothesis::TIDSortedElemGroupMap HYBRIDPlugin_Hypothesis::GetEnforcedEdges(const HYBRIDPlugin_Hypothesis* hyp)
1916 {
1917   return hyp ? hyp->_GetEnforcedEdges():DefaultIDSortedElemGroupMap();
1918 }
1919
1920 HYBRIDPlugin_Hypothesis::TIDSortedElemGroupMap HYBRIDPlugin_Hypothesis::GetEnforcedTriangles(const HYBRIDPlugin_Hypothesis* hyp)
1921 {
1922   return hyp ? hyp->_GetEnforcedTriangles():DefaultIDSortedElemGroupMap();
1923 }
1924
1925 HYBRIDPlugin_Hypothesis::TID2SizeMap HYBRIDPlugin_Hypothesis::GetNodeIDToSizeMap(const HYBRIDPlugin_Hypothesis* hyp)
1926 {
1927   return hyp ? hyp->_GetNodeIDToSizeMap(): DefaultID2SizeMap();
1928 }
1929
1930 HYBRIDPlugin_Hypothesis::TSetStrings HYBRIDPlugin_Hypothesis::GetGroupsToRemove(const HYBRIDPlugin_Hypothesis* hyp)
1931 {
1932   return hyp ? hyp->_GetGroupsToRemove(): DefaultGroupsToRemove();
1933 }