]> SALOME platform Git repositories - plugins/hybridplugin.git/blob - src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis.cxx
Salome HOME
Copyright update 2020
[plugins/hybridplugin.git] / src / HYBRIDPlugin / HYBRIDPlugin_Hypothesis.cxx
1 // Copyright (C) 2007-2020  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      : 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
28 #include <SMESHDS_Mesh.hxx>
29
30 #include <TopExp_Explorer.hxx>
31
32 #ifdef WIN32
33 #include <process.h>
34 #define getpid _getpid
35 #endif
36
37 namespace
38 {
39   struct GET_DEFAULT // struct used to get default value from GetOptionValue()
40   {
41     bool isDefault;
42     operator bool* () { return &isDefault; }
43   };
44 }
45
46 //=======================================================================
47 //function : HYBRIDPlugin_Hypothesis
48 //=======================================================================
49
50 HYBRIDPlugin_Hypothesis::HYBRIDPlugin_Hypothesis(int hypId, SMESH_Gen * gen)
51   : SMESH_Hypothesis(hypId, gen),
52     myNbOfBoundaryLayers(DefaultNbOfBoundaryLayers()),
53     myHeightFirstLayer(DefaultHeightFirstLayer()),
54     myHeightIsRelative(DefaultHeightIsRelative()),
55     myBoundaryLayersGrowth(DefaultBoundaryLayersGrowth()),
56     myBoundaryLayersMaxElemAngle(DefaultBoundaryLayersMaxElemAngle()),
57     myBoundaryLayersProgression(DefaultBoundaryLayersProgression()),
58     myElementGeneration(DefaultElementGeneration()),
59     myCoreSize(DefaultCoreSize()),
60     myLayersOnAllWrap(DefaultLayersOnAllWrap()),
61     myCollisionMode(DefaultCollisionMode()),
62     myAddMultinormals(DefaultAddMultinormals()),
63     mySmoothNormals(DefaultSmoothNormals()),
64     myMultinormalsAngle(DefaultMultinormalsAngle()),
65     myGradation(DefaultGradation()),
66     myWorkingDirectory(DefaultWorkingDirectory()),
67     myVerboseLevel(DefaultVerboseLevel()),
68     myLogInStandardOutput(DefaultStandardOutputLog()),
69     myRemoveLogOnSuccess(DefaultRemoveLogOnSuccess()),
70     myKeepFiles(DefaultKeepFiles()),
71     myOptimizationLevel(DefaultOptimizationLevel()),
72     myToMakeGroupsOfDomains(DefaultToMakeGroupsOfDomains()),
73     myToMeshHoles(DefaultMeshHoles()),
74     myMaximumMemory(-1),
75     myInitialMemory(-1),
76     myToCreateNewNodes(DefaultToCreateNewNodes()),
77     myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()),
78     myToUseFemCorrection(DefaultToUseFEMCorrection()),
79     myToRemoveCentralPoint(DefaultToRemoveCentralPoint())
80 {
81   _name = "HYBRID_Parameters";
82   _param_algo_dim = 3;
83
84   const char* boolOptionNames[] = { "add_multinormals", // no
85                                     "smooth_normals",   // no
86                                     "" // mark of end
87   };
88   const char* intOptionNames[] = { "max_number_of_threads", // 4
89                                    "" // mark of end
90   };
91   const char* doubleOptionNames[] = { //"global_physical_size",  // 0.0 = not set -- myCoreSize
92                                       "gradation",    // 2.0
93                                       //"boundary_layer_max_element_angle", // 165.0 -- myBoundaryLayersMaxElemAngle
94                                       "multinormal_angle_threshold", // 30.0
95                                       "" // mark of end
96   };
97   const char* charOptionNames[] = { "collision_mode",                   // stop/decrease
98                                     "" // mark of end
99   };
100
101   int i = 0;
102   while (boolOptionNames[i][0])
103   {
104     _boolOptions.insert( boolOptionNames[i] );
105     _option2value[boolOptionNames[i++]].clear();
106   }
107   i = 0;
108   while (intOptionNames[i][0])
109     _option2value[intOptionNames[i++]].clear();
110
111   i = 0;
112   while (doubleOptionNames[i][0]) {
113     _doubleOptions.insert(doubleOptionNames[i]);
114     _option2value[doubleOptionNames[i++]].clear();
115   }
116   i = 0;
117   while (charOptionNames[i][0]) {
118     _charOptions.insert(charOptionNames[i]);
119     _option2value[charOptionNames[i++]].clear();
120   }
121
122   // default values to be used while MG meshing
123
124   _defaultOptionValues["add_multinormals"                ] = "no";
125   _defaultOptionValues["smooth_normals"                  ] = "no";
126   _defaultOptionValues["max_number_of_threads"           ] = "4";
127   //_defaultOptionValues["global_physical_size"            ] = "0";
128   _defaultOptionValues["gradation"                       ] = "2";
129   //_defaultOptionValues["boundary_layer_max_element_angle"] = "165";
130   _defaultOptionValues["multinormal_angle_threshold"     ] = "30";
131   _defaultOptionValues["collision_mode"                  ] = "stop";
132
133 #ifdef _DEBUG_
134   // check validity of option names of _defaultOptionValues
135   TOptionValues::iterator n2v = _defaultOptionValues.begin();
136   for ( ; n2v != _defaultOptionValues.end(); ++n2v )
137     ASSERT( _option2value.count( n2v->first ));
138   ASSERT( _option2value.size() == _defaultOptionValues.size() );
139 #endif
140 }
141
142 //=======================================================================
143 //function : SetHeightIsRelative
144 //=======================================================================
145
146 void HYBRIDPlugin_Hypothesis::SetHeightIsRelative(bool isRelative)
147 {
148   if ( myHeightIsRelative != isRelative ) {
149     myHeightIsRelative = isRelative;
150     NotifySubMeshesHypothesisModification();
151   }
152 }
153
154 //=======================================================================
155 //function : SetBoundaryLayersMaxElemAngle
156 //=======================================================================
157
158 void HYBRIDPlugin_Hypothesis::SetBoundaryLayersMaxElemAngle( double angle )
159 {
160   if ( myBoundaryLayersMaxElemAngle != angle ) {
161     myBoundaryLayersMaxElemAngle = angle;
162     NotifySubMeshesHypothesisModification();
163   }
164 }
165
166
167 //=======================================================================
168 //function : SetLayersOnAllWrap
169 //=======================================================================
170
171 void HYBRIDPlugin_Hypothesis::SetLayersOnAllWrap(bool toMesh)
172 {
173   if ( myLayersOnAllWrap != toMesh ) {
174     myLayersOnAllWrap = toMesh;
175     NotifySubMeshesHypothesisModification();
176   }
177 }
178
179 //=======================================================================
180 //function : GetLayersOnAllWrap
181 //=======================================================================
182
183 bool HYBRIDPlugin_Hypothesis::GetLayersOnAllWrap(bool checkFreeOption) const
184 {
185   return myLayersOnAllWrap;
186 }
187
188 //=======================================================================
189 //function : SetFacesWithLayers
190 //purpose  : Set IDs of faces to grow the layers on
191 //=======================================================================
192
193 bool HYBRIDPlugin_Hypothesis::SetFacesWithLayers(const std::vector<int>& theVal)
194 {
195   if ( myFacesWithLayers != theVal )
196   {
197     myFacesWithLayers = theVal;
198     NotifySubMeshesHypothesisModification();
199     return true;
200   }
201   return false;
202 }
203
204 //=======================================================================
205 //function : GetFacesWithLayers
206 //purpose  : Return IDs of faces to grow the layers on
207 //=======================================================================
208
209 const std::vector<int>& HYBRIDPlugin_Hypothesis::GetFacesWithLayers() const
210 {
211   return myFacesWithLayers;
212 }
213
214 //=======================================================================
215 //function : SetFacesWithImprinting
216 //purpose  : Set IDs of faces to grow the layers on
217 //=======================================================================
218
219 bool HYBRIDPlugin_Hypothesis::SetFacesWithImprinting(const std::vector<int>& theVal)
220 {
221   if ( myFacesWithImprinting != theVal )
222   {
223     myFacesWithImprinting = theVal;
224     NotifySubMeshesHypothesisModification();
225     return true;
226   }
227   return false;
228 }
229
230 //=======================================================================
231 //function : GetFacesWithImprinting
232 //purpose  : Return IDs of faces to grow the layers on
233 //=======================================================================
234
235 const std::vector<int>& HYBRIDPlugin_Hypothesis::GetFacesWithImprinting() const
236 {
237   return myFacesWithImprinting;
238 }
239
240 //=======================================================================
241 //function : SetFacesWithSnapping
242 //purpose  : Set IDs of faces that already have surface layers
243 //=======================================================================
244
245 bool HYBRIDPlugin_Hypothesis::SetFacesWithSnapping(const std::vector<int>& theVal)
246 {
247   if ( myFacesWithSnapping != theVal )
248   {
249     myFacesWithSnapping = theVal;
250     NotifySubMeshesHypothesisModification();
251     return true;
252   }
253   return false;
254 }
255
256 //=======================================================================
257 //function : GetFacesWithSnapping
258 //purpose  : Return IDs of faces that already have surface layers
259 //=======================================================================
260
261 const std::vector<int>& HYBRIDPlugin_Hypothesis::GetFacesWithSnapping() const
262 {
263   return myFacesWithSnapping;
264 }
265
266 //=======================================================================
267 //function : SetToMeshHoles
268 //=======================================================================
269
270 void HYBRIDPlugin_Hypothesis::SetToMeshHoles(bool toMesh)
271 {
272   if ( myToMeshHoles != toMesh ) {
273     myToMeshHoles = toMesh;
274     NotifySubMeshesHypothesisModification();
275   }
276 }
277
278 //=======================================================================
279 //function : GetToMeshHoles
280 //=======================================================================
281
282 bool HYBRIDPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const
283 {
284   return myToMeshHoles;
285 }
286
287 //=======================================================================
288 //function : SetToMakeGroupsOfDomains
289 //=======================================================================
290
291 void HYBRIDPlugin_Hypothesis::SetToMakeGroupsOfDomains(bool toMakeGroups)
292 {
293   if ( myToMakeGroupsOfDomains != toMakeGroups ) {
294     myToMakeGroupsOfDomains = toMakeGroups;
295     NotifySubMeshesHypothesisModification();
296   }
297 }
298
299 //=======================================================================
300 //function : GetToMakeGroupsOfDomains
301 //=======================================================================
302
303 bool HYBRIDPlugin_Hypothesis::GetToMakeGroupsOfDomains() const
304 {
305   return myToMakeGroupsOfDomains;
306 }
307
308 //=======================================================================
309 //function : GetToMakeGroupsOfDomains
310 //=======================================================================
311
312 bool HYBRIDPlugin_Hypothesis::GetToMakeGroupsOfDomains(const HYBRIDPlugin_Hypothesis* hyp)
313 {
314   bool res;
315   if ( hyp ) res = /*hyp->GetToMeshHoles(true) &&*/ hyp->GetToMakeGroupsOfDomains();
316   else       res = /*DefaultMeshHoles()        &&*/ DefaultToMakeGroupsOfDomains();
317   return res;
318 }
319
320 //=======================================================================
321 //function : SetMaximumMemory
322 //=======================================================================
323
324 void HYBRIDPlugin_Hypothesis::SetMaximumMemory(double MB)
325 {
326   if ( myMaximumMemory != MB ) {
327     myMaximumMemory = MB;
328     NotifySubMeshesHypothesisModification();
329   }
330 }
331
332 //=======================================================================
333 //function : GetMaximumMemory
334 //           * automatic memory adjustment mode. Default is zero
335 //=======================================================================
336
337 double HYBRIDPlugin_Hypothesis::GetMaximumMemory() const
338 {
339   return myMaximumMemory;
340 }
341
342 //=======================================================================
343 //function : SetInitialMemory
344 //=======================================================================
345
346 void HYBRIDPlugin_Hypothesis::SetInitialMemory(double MB)
347 {
348   if ( myInitialMemory != MB ) {
349     myInitialMemory = MB;
350     NotifySubMeshesHypothesisModification();
351   }
352 }
353
354 //=======================================================================
355 //function : GetInitialMemory
356 //=======================================================================
357
358 double HYBRIDPlugin_Hypothesis::GetInitialMemory() const
359 {
360   return myInitialMemory;
361 }
362
363 //=======================================================================
364 //function : SetOptimizationLevel
365 //=======================================================================
366
367 void HYBRIDPlugin_Hypothesis::SetOptimizationLevel(OptimizationLevel level)
368 {
369   if ( myOptimizationLevel != level ) {
370     myOptimizationLevel = level;
371     NotifySubMeshesHypothesisModification();
372   }
373 }
374
375 //=======================================================================
376 //function : GetOptimizationLevel
377 //=======================================================================
378 HYBRIDPlugin_Hypothesis::OptimizationLevel HYBRIDPlugin_Hypothesis::GetOptimizationLevel() const
379 {
380   return (OptimizationLevel) myOptimizationLevel;
381 }
382
383 //=======================================================================
384 //function : SetCollisionMode
385 //=======================================================================
386 void HYBRIDPlugin_Hypothesis::SetCollisionMode(CollisionMode mode)
387 {
388   SetOptionValue( "collision_mode", mode == Decrease ? "decrease" : "stop" );
389   myCollisionMode = mode;
390 }
391
392 //=======================================================================
393 //function : GetCollisionMode
394 //=======================================================================
395 HYBRIDPlugin_Hypothesis::CollisionMode HYBRIDPlugin_Hypothesis::GetCollisionMode() const
396 {
397   return (CollisionMode) myCollisionMode;
398 }
399
400 //=======================================================================
401 //function : SetBoundaryLayersGrowth
402 //=======================================================================
403 void HYBRIDPlugin_Hypothesis::SetBoundaryLayersGrowth(BoundaryLayersGrowth mode)
404 {
405   if ( myBoundaryLayersGrowth != mode ) {
406     myBoundaryLayersGrowth = mode;
407     NotifySubMeshesHypothesisModification();
408   }
409 }
410
411 //=======================================================================
412 //function : GetBoundaryLayersGrowth
413 //=======================================================================
414 HYBRIDPlugin_Hypothesis::BoundaryLayersGrowth HYBRIDPlugin_Hypothesis::GetBoundaryLayersGrowth() const
415 {
416   return (BoundaryLayersGrowth) myBoundaryLayersGrowth;
417 }
418
419 //=======================================================================
420 //function : SetElementGeneration
421 //=======================================================================
422 void HYBRIDPlugin_Hypothesis::SetElementGeneration(ElementGeneration mode)
423 {
424   if ( myElementGeneration != mode ) {
425     myElementGeneration = mode;
426     NotifySubMeshesHypothesisModification();
427   }
428 }
429
430 //=======================================================================
431 //function : GetElementGeneration
432 //=======================================================================
433 HYBRIDPlugin_Hypothesis::ElementGeneration HYBRIDPlugin_Hypothesis::GetElementGeneration() const
434 {
435   return (ElementGeneration) myElementGeneration;
436 }
437
438 //=======================================================================
439 //function : SetAddMultinormals
440 //=======================================================================
441 void HYBRIDPlugin_Hypothesis::SetAddMultinormals(bool toAddMultinormals)
442 {
443   SetOptionValue( "add_multinormals", toAddMultinormals ? "yes" : "no" );
444   myAddMultinormals = toAddMultinormals;
445 }
446
447 //=======================================================================
448 //function : GetAddMultinormals
449 //=======================================================================
450
451 bool HYBRIDPlugin_Hypothesis::GetAddMultinormals() const
452 {
453   return myAddMultinormals;
454 }
455
456 //=======================================================================
457 //function : SetSmoothNormals
458 //=======================================================================
459
460 void HYBRIDPlugin_Hypothesis::SetSmoothNormals(bool toSmoothNormals)
461 {
462   SetOptionValue( "smooth_normals", toSmoothNormals ? "yes" : "no" );
463   mySmoothNormals = toSmoothNormals;
464 }
465
466 //=======================================================================
467 //function : GetSmoothNormals
468 //=======================================================================
469
470 bool HYBRIDPlugin_Hypothesis::GetSmoothNormals() const
471 {
472   return mySmoothNormals;
473 }
474
475 //=======================================================================
476 //function : SetHeightFirstLayer
477 //=======================================================================
478
479 void HYBRIDPlugin_Hypothesis::SetHeightFirstLayer(double toHeightFirstLayer)
480 {
481   if ( myHeightFirstLayer != toHeightFirstLayer ) {
482     myHeightFirstLayer = toHeightFirstLayer;
483     NotifySubMeshesHypothesisModification();
484   }
485 }
486
487 //=======================================================================
488 //function : GetHeightFirstLayer
489 //=======================================================================
490
491 double HYBRIDPlugin_Hypothesis::GetHeightFirstLayer() const
492 {
493   return myHeightFirstLayer;
494 }
495
496 //=======================================================================
497 //function : SetBoundaryLayersProgression
498 //=======================================================================
499
500 void HYBRIDPlugin_Hypothesis::SetBoundaryLayersProgression(double toBoundaryLayersProgression)
501 {
502   if ( myBoundaryLayersProgression != toBoundaryLayersProgression ) {
503     myBoundaryLayersProgression = toBoundaryLayersProgression;
504     NotifySubMeshesHypothesisModification();
505   }
506 }
507
508 //=======================================================================
509 //function : GetBoundaryLayersProgression
510 //=======================================================================
511
512 double HYBRIDPlugin_Hypothesis::GetBoundaryLayersProgression() const
513 {
514   return myBoundaryLayersProgression;
515 }
516
517 //=======================================================================
518 //function : SetCoreSize
519 //=======================================================================
520
521 void HYBRIDPlugin_Hypothesis::SetCoreSize(double toCoreSize)
522 {
523   if ( myCoreSize != toCoreSize ) {
524     myCoreSize = toCoreSize;
525     NotifySubMeshesHypothesisModification();
526   }
527 }
528
529 //=======================================================================
530 //function : GetCoreSize
531 //=======================================================================
532
533 double HYBRIDPlugin_Hypothesis::GetCoreSize() const
534 {
535   return myCoreSize;
536 }
537
538 //=======================================================================
539 //function : SetMultinormalsAngle
540 //=======================================================================
541
542 void HYBRIDPlugin_Hypothesis::SetMultinormalsAngle(double toMultinormalsAngle)
543 {
544   SetOptionValue( "multinormal_angle_threshold", SMESH_Comment( toMultinormalsAngle ));
545   myMultinormalsAngle = toMultinormalsAngle;
546 }
547
548 //=======================================================================
549 //function : GetMultinormalsAngle
550 //=======================================================================
551
552 double HYBRIDPlugin_Hypothesis::GetMultinormalsAngle() const
553 {
554   return myMultinormalsAngle;
555 }
556
557 //=======================================================================
558 //function : SetNbOfBoundaryLayers
559 //=======================================================================
560
561 void HYBRIDPlugin_Hypothesis::SetNbOfBoundaryLayers(short toNbOfBoundaryLayers)
562 {
563   if ( myNbOfBoundaryLayers != toNbOfBoundaryLayers ) {
564     myNbOfBoundaryLayers = toNbOfBoundaryLayers;
565     NotifySubMeshesHypothesisModification();
566   }
567 }
568
569 //=======================================================================
570 //function : GetCoreSize
571 //=======================================================================
572
573 short HYBRIDPlugin_Hypothesis::GetNbOfBoundaryLayers() const
574 {
575   return myNbOfBoundaryLayers;
576 }
577
578
579 /////////////////////////////////////////////////////////////////////////
580
581
582 //=======================================================================
583 //function : SetWorkingDirectory
584 //=======================================================================
585
586 void HYBRIDPlugin_Hypothesis::SetWorkingDirectory(const std::string& path)
587 {
588   if ( myWorkingDirectory != path ) {
589     myWorkingDirectory = path;
590     NotifySubMeshesHypothesisModification();
591   }
592 }
593
594 //=======================================================================
595 //function : GetWorkingDirectory
596 //=======================================================================
597
598 std::string HYBRIDPlugin_Hypothesis::GetWorkingDirectory() const
599 {
600   return myWorkingDirectory;
601 }
602
603 //=======================================================================
604 //function : SetKeepFiles
605 //=======================================================================
606
607 void HYBRIDPlugin_Hypothesis::SetKeepFiles(bool toKeep)
608 {
609   if ( myKeepFiles != toKeep ) {
610     myKeepFiles = toKeep;
611     NotifySubMeshesHypothesisModification();
612   }
613 }
614
615 //=======================================================================
616 //function : GetKeepFiles
617 //=======================================================================
618
619 bool HYBRIDPlugin_Hypothesis::GetKeepFiles() const
620 {
621   return myKeepFiles;
622 }
623
624 //=======================================================================
625 //function : SetVerboseLevel
626 //=======================================================================
627
628 void HYBRIDPlugin_Hypothesis::SetVerboseLevel(short level)
629 {
630   if ( myVerboseLevel != level ) {
631     myVerboseLevel = level;
632     NotifySubMeshesHypothesisModification();
633   }
634 }
635
636 //=======================================================================
637 //function : GetVerboseLevel
638 //=======================================================================
639
640 short HYBRIDPlugin_Hypothesis::GetVerboseLevel() const
641 {
642   return myVerboseLevel;
643 }
644
645 //=======================================================================
646 //function : SetToCreateNewNodes
647 //=======================================================================
648
649 void HYBRIDPlugin_Hypothesis::SetToCreateNewNodes(bool toCreate)
650 {
651   if ( myToCreateNewNodes != toCreate ) {
652     myToCreateNewNodes = toCreate;
653     NotifySubMeshesHypothesisModification();
654   }
655 }
656
657 //=======================================================================
658 //function : GetToCreateNewNodes
659 //=======================================================================
660
661 bool HYBRIDPlugin_Hypothesis::GetToCreateNewNodes() const
662 {
663   return myToCreateNewNodes;
664 }
665
666 //=======================================================================
667 //function : SetToUseBoundaryRecoveryVersion
668 //=======================================================================
669
670 void HYBRIDPlugin_Hypothesis::SetToUseBoundaryRecoveryVersion(bool toUse)
671 {
672   if ( myToUseBoundaryRecoveryVersion != toUse ) {
673     myToUseBoundaryRecoveryVersion = toUse;
674     NotifySubMeshesHypothesisModification();
675   }
676 }
677
678 //=======================================================================
679 //function : GetToUseBoundaryRecoveryVersion
680 //=======================================================================
681
682 bool HYBRIDPlugin_Hypothesis::GetToUseBoundaryRecoveryVersion() const
683 {
684   return myToUseBoundaryRecoveryVersion;
685 }
686
687 //=======================================================================
688 //function : SetFEMCorrection
689 //=======================================================================
690
691 void HYBRIDPlugin_Hypothesis::SetFEMCorrection(bool toUseFem)
692 {
693   if ( myToUseFemCorrection != toUseFem ) {
694     myToUseFemCorrection = toUseFem;
695     NotifySubMeshesHypothesisModification();
696   }
697 }
698
699 //=======================================================================
700 //function : GetFEMCorrection
701 //=======================================================================
702
703 bool HYBRIDPlugin_Hypothesis::GetFEMCorrection() const
704 {
705   return myToUseFemCorrection;
706 }
707
708 //=======================================================================
709 //function : SetToRemoveCentralPoint
710 //=======================================================================
711
712 void HYBRIDPlugin_Hypothesis::SetToRemoveCentralPoint(bool toRemove)
713 {
714   if ( myToRemoveCentralPoint != toRemove ) {
715     myToRemoveCentralPoint = toRemove;
716     NotifySubMeshesHypothesisModification();
717   }
718 }
719
720 //=======================================================================
721 //function : GetToRemoveCentralPoint
722 //=======================================================================
723
724 bool HYBRIDPlugin_Hypothesis::GetToRemoveCentralPoint() const
725 {
726   return myToRemoveCentralPoint;
727 }
728
729 //=======================================================================
730 //function : SetAdvancedOption
731 //=======================================================================
732
733 void HYBRIDPlugin_Hypothesis::SetAdvancedOption(const std::string& option)
734 {
735   size_t wsPos = option.find(' ');
736   if ( wsPos == std::string::npos )
737   {
738     SetOptionValue( option, "" );
739   }
740   else
741   {
742     std::string opt( option, 0, wsPos );
743     std::string val( option, wsPos + 1 );
744     SetOptionValue( opt, val );
745   }
746 }
747
748 //=======================================================================
749 //function : GetAdvancedOption
750 //=======================================================================
751
752 std::string HYBRIDPlugin_Hypothesis::GetAdvancedOption() const
753 {
754   SMESH_Comment txt;
755
756   TOptionValues::const_iterator o2v = _option2value.begin();
757   for ( ; o2v != _option2value.end(); ++o2v )
758     if ( !o2v->second.empty() )
759     {
760       if ( !txt.empty() )
761         txt << " ";
762       txt << o2v->first << " " << o2v->second;
763     }
764   for ( o2v = _customOption2value.begin(); o2v != _customOption2value.end(); ++o2v )
765   {
766     if ( !txt.empty() )
767       txt << " ";
768     txt << o2v->first << " " << o2v->second;
769   }
770   return txt;
771 }
772
773 //=======================================================================
774 //function : SetGradation
775 //=======================================================================
776
777 void HYBRIDPlugin_Hypothesis::SetGradation(double gradation)
778 {
779   SetOptionValue( "gradation", SMESH_Comment( gradation ));
780   myGradation = gradation;
781 }
782
783 //=======================================================================
784 //function : GetGradation
785 //=======================================================================
786
787 double HYBRIDPlugin_Hypothesis::GetGradation() const
788 {
789   return myGradation;
790 }
791
792 //=======================================================================
793 //function : SetStandardOutputLog
794 //=======================================================================
795
796 void HYBRIDPlugin_Hypothesis::SetStandardOutputLog(bool logInStandardOutput)
797 {
798   if ( myLogInStandardOutput != logInStandardOutput ) {
799     myLogInStandardOutput = logInStandardOutput;
800     NotifySubMeshesHypothesisModification();
801   }
802 }
803
804 //=======================================================================
805 //function : GetStandardOutputLog
806 //=======================================================================
807
808 bool HYBRIDPlugin_Hypothesis::GetStandardOutputLog() const
809 {
810   return myLogInStandardOutput;
811 }
812
813 //=======================================================================
814 //function : SetRemoveLogOnSuccess
815 //=======================================================================
816
817 void HYBRIDPlugin_Hypothesis::SetRemoveLogOnSuccess(bool removeLogOnSuccess)
818 {
819   if ( myRemoveLogOnSuccess != removeLogOnSuccess ) {
820     myRemoveLogOnSuccess = removeLogOnSuccess;
821     NotifySubMeshesHypothesisModification();
822   }
823 }
824
825 //=======================================================================
826 //function : GetRemoveLogOnSuccess
827 //=======================================================================
828
829 bool HYBRIDPlugin_Hypothesis::GetRemoveLogOnSuccess() const
830 {
831   return myRemoveLogOnSuccess;
832 }
833
834 //=======================================================================
835 //function : SetEnforcedVertex
836 //=======================================================================
837
838 bool HYBRIDPlugin_Hypothesis::SetEnforcedVertex(std::string theName, std::string theEntry, std::string theGroupName,
839                                                double size, double x, double y, double z, bool isCompound)
840 {
841   bool toNotify = false;
842   bool toCreate = true;
843
844   THYBRIDEnforcedVertex *oldEnVertex;
845   THYBRIDEnforcedVertex *newEnfVertex = new THYBRIDEnforcedVertex();
846   newEnfVertex->name = theName;
847   newEnfVertex->geomEntry = theEntry;
848   newEnfVertex->coords.clear();
849   if (!isCompound) {
850     newEnfVertex->coords.push_back(x);
851     newEnfVertex->coords.push_back(y);
852     newEnfVertex->coords.push_back(z);
853   }
854   newEnfVertex->groupName = theGroupName;
855   newEnfVertex->size = size;
856   newEnfVertex->isCompound = isCompound;
857   
858   
859   // update _enfVertexList
860   THYBRIDEnforcedVertexList::iterator it = _enfVertexList.find(newEnfVertex);
861   if (it != _enfVertexList.end()) {
862     toCreate = false;
863     oldEnVertex = (*it);
864     if (oldEnVertex->name != theName) {
865       oldEnVertex->name = theName;
866       toNotify = true;
867     }
868     if (oldEnVertex->groupName != theGroupName) {
869       oldEnVertex->groupName = theGroupName;
870       toNotify = true;
871     }
872     if (oldEnVertex->size != size) {
873       oldEnVertex->size = size;
874       toNotify = true;
875     }
876     if (toNotify) {
877       // update map coords / enf vertex if needed
878       if (oldEnVertex->coords.size()) {
879         _coordsEnfVertexMap[oldEnVertex->coords] = oldEnVertex;
880         _enfVertexCoordsSizeList[oldEnVertex->coords] = size;
881       }
882
883       // update map geom entry / enf vertex if needed
884       if (oldEnVertex->geomEntry != "") {
885         _geomEntryEnfVertexMap[oldEnVertex->geomEntry] = oldEnVertex;
886         _enfVertexEntrySizeList[oldEnVertex->geomEntry] = size;
887       }
888     }
889   }
890
891 //   //////// CREATE ////////////
892   if (toCreate) {
893     toNotify = true;
894     _enfVertexList.insert(newEnfVertex);
895     if (theEntry == "") {
896       _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex;
897       _enfVertexCoordsSizeList[newEnfVertex->coords] = size;
898     }
899     else {
900       _geomEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex;
901       _enfVertexEntrySizeList[newEnfVertex->geomEntry] = size;
902     }
903   }
904
905   if (toNotify)
906     NotifySubMeshesHypothesisModification();
907
908   return toNotify;
909 }
910
911
912 //=======================================================================
913 //function : SetEnforcedMesh
914 //=======================================================================
915 bool HYBRIDPlugin_Hypothesis::SetEnforcedMesh(SMESH_Mesh& theMesh, SMESH::ElementType elementType, std::string name, std::string entry, std::string groupName)
916 {
917   TIDSortedElemSet theElemSet;
918   SMDS_ElemIteratorPtr eIt = theMesh.GetMeshDS()->elementsIterator(SMDSAbs_ElementType(elementType));
919   while ( eIt->more() )
920     theElemSet.insert( eIt->next() );
921   bool added = SetEnforcedElements( theElemSet, elementType, groupName);
922   if (added) {
923     THYBRIDEnforcedMesh* newEnfMesh = new THYBRIDEnforcedMesh();
924     newEnfMesh->persistID   = theMesh.GetMeshDS()->GetPersistentId();
925     newEnfMesh->name        = name;
926     newEnfMesh->entry       = entry;
927     newEnfMesh->elementType = elementType;
928     newEnfMesh->groupName   = groupName;
929     
930     THYBRIDEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
931     if (it == _enfMeshList.end()) {
932       _entryEnfMeshMap[entry].insert(newEnfMesh);
933       _enfMeshList.insert(newEnfMesh);
934     }
935     else {
936       delete newEnfMesh;
937     }
938   }
939   return added;
940 }
941
942 //=======================================================================
943 //function : SetEnforcedGroup
944 //=======================================================================
945 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)
946 {
947   TIDSortedElemSet theElemSet;
948     if ( theIDs->length() == 0 ){MESSAGE("The source group is empty");}
949     for ( CORBA::ULong i = 0; i < theIDs->length(); i++) {
950       CORBA::Long ind = theIDs[i];
951       if (elementType == SMESH::NODE)
952       {
953         const SMDS_MeshNode * node = theMeshDS->FindNode(ind);
954         if (node)
955           theElemSet.insert( node );
956       }
957       else
958       {
959         const SMDS_MeshElement * elem = theMeshDS->FindElement(ind);
960         if (elem)
961           theElemSet.insert( elem );
962       }
963     }
964
965 //   SMDS_ElemIteratorPtr it = theGroup->GetGroupDS()->GetElements();
966 //   while ( it->more() ) 
967 //     theElemSet.insert( it->next() );
968
969   bool added = SetEnforcedElements( theElemSet, elementType, groupName);
970   if (added) {
971     THYBRIDEnforcedMesh* newEnfMesh = new THYBRIDEnforcedMesh();
972     newEnfMesh->name = name;
973     newEnfMesh->entry = entry;
974     newEnfMesh->elementType = elementType;
975     newEnfMesh->groupName = groupName;
976     
977     THYBRIDEnforcedMeshList::iterator it = _enfMeshList.find(newEnfMesh);
978     if (it == _enfMeshList.end()) {
979       _entryEnfMeshMap[entry].insert(newEnfMesh);
980       _enfMeshList.insert(newEnfMesh);
981     }
982   }
983   return added;
984 }
985
986 //=======================================================================
987 //function : SetEnforcedElements
988 //=======================================================================
989 bool HYBRIDPlugin_Hypothesis::SetEnforcedElements(TIDSortedElemSet theElemSet, SMESH::ElementType elementType, std::string groupName)
990 {
991   TIDSortedElemSet::const_iterator it = theElemSet.begin();
992   const SMDS_MeshElement* elem;
993   const SMDS_MeshNode* node;
994   bool added = true;
995   std::pair<TIDSortedNodeGroupMap::iterator,bool> nodeRet;
996   std::pair<TIDSortedElemGroupMap::iterator,bool> elemRet;
997
998   for (;it != theElemSet.end();++it)
999   {
1000     elem = (*it);
1001     switch (elementType) {
1002       case SMESH::NODE:
1003         node = dynamic_cast<const SMDS_MeshNode*>(elem);
1004         if (node) {
1005           nodeRet = _enfNodes.insert(make_pair(node,groupName));
1006           added = added && nodeRet.second;
1007           std::string msg = added ? "yes":"no";
1008         }
1009         else {
1010           SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
1011           for (;nodeIt->more();) {
1012             node = dynamic_cast<const SMDS_MeshNode*>(nodeIt->next());
1013             nodeRet = _enfNodes.insert(make_pair(node,groupName));
1014             added = added && nodeRet.second;
1015           }
1016 //          added = true;s
1017         }
1018         break;
1019       case SMESH::EDGE:
1020         if (elem->GetType() == SMDSAbs_Edge) {
1021           elemRet = _enfEdges.insert(make_pair(elem,groupName));
1022           added = added && elemRet.second;
1023         }
1024         break;
1025       case SMESH::FACE:
1026         if (elem->GetType() == SMDSAbs_Face)
1027         {
1028           if (elem->NbCornerNodes() == 3) {
1029             elemRet = _enfTriangles.insert(make_pair(elem,groupName));
1030             added = added && elemRet.second;
1031           }
1032         }
1033         break;
1034       default:
1035         break;
1036     };
1037   }
1038   if (added)
1039     NotifySubMeshesHypothesisModification();
1040   return added;
1041 }
1042
1043
1044 //=======================================================================
1045 //function : GetEnforcedVertex
1046 //=======================================================================
1047
1048 HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertex* HYBRIDPlugin_Hypothesis::GetEnforcedVertex(double x, double y, double z)
1049   throw (std::invalid_argument)
1050 {
1051   std::vector<double> coord(3);
1052   coord[0] = x;
1053   coord[1] = y;
1054   coord[2] = z;
1055   if (_coordsEnfVertexMap.count(coord)>0)
1056     return _coordsEnfVertexMap[coord];
1057   std::ostringstream msg ;
1058   msg << "No enforced vertex at " << x << ", " << y << ", " << z;
1059   throw std::invalid_argument(msg.str());
1060 }
1061
1062 HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertex* HYBRIDPlugin_Hypothesis::GetEnforcedVertex(const std::string theEntry)
1063   throw (std::invalid_argument)
1064 {
1065   if (_geomEntryEnfVertexMap.count(theEntry)>0)
1066     return _geomEntryEnfVertexMap[theEntry];
1067   
1068   std::ostringstream msg ;
1069   msg << "No enforced vertex with entry " << theEntry;
1070   throw std::invalid_argument(msg.str());
1071 }
1072
1073 //=======================================================================
1074 //function : RemoveEnforcedVertex
1075 //=======================================================================
1076
1077 bool HYBRIDPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z, const std::string theEntry)
1078   throw (std::invalid_argument)
1079 {
1080   bool toNotify = false;
1081   std::ostringstream msg;
1082   THYBRIDEnforcedVertex *oldEnfVertex;
1083   std::vector<double> coords(3);
1084   coords[0] = x;
1085   coords[1] = y;
1086   coords[2] = z;
1087   
1088   // check that enf vertex with given enf vertex entry exists
1089   TGeomEntryHYBRIDEnforcedVertexMap::iterator it_enfVertexEntry = _geomEntryEnfVertexMap.find(theEntry);
1090   if (it_enfVertexEntry != _geomEntryEnfVertexMap.end()) {
1091     // Success
1092     oldEnfVertex = it_enfVertexEntry->second;
1093     _geomEntryEnfVertexMap.erase(it_enfVertexEntry);
1094   } else {
1095     // Fail
1096     // check that enf vertex with given coords exists
1097     TCoordsHYBRIDEnforcedVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
1098     if (it_coords_enf != _coordsEnfVertexMap.end()) {
1099       // Success
1100       oldEnfVertex = it_coords_enf->second;
1101       _coordsEnfVertexMap.erase(it_coords_enf);
1102       _enfVertexCoordsSizeList.erase(_enfVertexCoordsSizeList.find(coords));
1103     } else {
1104       // Fail
1105       throw std::invalid_argument(msg.str());
1106     }
1107   }
1108
1109
1110   // update _enfVertexList
1111   THYBRIDEnforcedVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1112   if (it != _enfVertexList.end()) {
1113     if ((*it)->groupName != "")
1114       _groupsToRemove.insert((*it)->groupName);
1115     _enfVertexList.erase(it);
1116     toNotify = true;
1117   }
1118
1119   if (toNotify)
1120     NotifySubMeshesHypothesisModification();
1121
1122   return toNotify;
1123 }
1124
1125 //=======================================================================
1126 //function : ClearEnforcedVertices
1127 //=======================================================================
1128 void HYBRIDPlugin_Hypothesis::ClearEnforcedVertices()
1129 {
1130   THYBRIDEnforcedVertexList::const_iterator it = _enfVertexList.begin();
1131   for(;it != _enfVertexList.end();++it) {
1132     if ((*it)->groupName != "")
1133       _groupsToRemove.insert((*it)->groupName);
1134   }
1135   _enfVertexList.clear();
1136   _coordsEnfVertexMap.clear();
1137   _geomEntryEnfVertexMap.clear();
1138   _enfVertexCoordsSizeList.clear();
1139   _enfVertexEntrySizeList.clear();
1140   NotifySubMeshesHypothesisModification();
1141 }
1142
1143 //=======================================================================
1144 //function : ClearEnforcedMeshes
1145 //=======================================================================
1146 void HYBRIDPlugin_Hypothesis::ClearEnforcedMeshes()
1147 {
1148   THYBRIDEnforcedMeshList::const_iterator it = _enfMeshList.begin();
1149   for(;it != _enfMeshList.end();++it) {
1150     if ((*it)->groupName != "")
1151       _groupsToRemove.insert((*it)->groupName);
1152   }
1153   _enfNodes.clear();
1154   _enfEdges.clear();
1155   _enfTriangles.clear();
1156   _nodeIDToSizeMap.clear();
1157   _enfMeshList.clear();
1158   _entryEnfMeshMap.clear();
1159   NotifySubMeshesHypothesisModification();
1160 }
1161
1162 //================================================================================
1163 /*!
1164  * \brief At mesh loading, restore enforced elements by just loaded enforced meshes
1165  */
1166 //================================================================================
1167
1168 void HYBRIDPlugin_Hypothesis::RestoreEnfElemsByMeshes()
1169 {
1170   THYBRIDEnforcedMeshList::const_iterator it = _enfMeshList.begin();
1171   for(;it != _enfMeshList.end();++it) {
1172     THYBRIDEnforcedMesh* enfMesh = *it;
1173     if ( SMESH_Mesh* mesh = GetMeshByPersistentID( enfMesh->persistID ))
1174       SetEnforcedMesh( *mesh,
1175                        enfMesh->elementType,
1176                        enfMesh->name,
1177                        enfMesh->entry,
1178                        enfMesh->groupName );
1179     enfMesh->persistID = -1; // not to restore again
1180   }
1181 }
1182
1183 //=======================================================================
1184 //function : SetGroupsToRemove
1185 //=======================================================================
1186
1187 void HYBRIDPlugin_Hypothesis::ClearGroupsToRemove()
1188 {
1189   _groupsToRemove.clear();
1190 }
1191
1192
1193 //=======================================================================
1194 //function : DefaultLayersOnAllWrap
1195 //=======================================================================
1196
1197 bool HYBRIDPlugin_Hypothesis::DefaultLayersOnAllWrap()
1198 {
1199   return true;
1200 }
1201
1202 //=======================================================================
1203 //function : DefaultMeshHoles
1204 //=======================================================================
1205
1206 bool HYBRIDPlugin_Hypothesis::DefaultMeshHoles()
1207 {
1208   return false; // PAL19680
1209 }
1210
1211 //=======================================================================
1212 //function : DefaultToMakeGroupsOfDomains
1213 //=======================================================================
1214
1215 bool HYBRIDPlugin_Hypothesis::DefaultToMakeGroupsOfDomains()
1216 {
1217   return false; // issue 0022172
1218 }
1219
1220 //=======================================================================
1221 //function : DefaultMaximumMemory
1222 //=======================================================================
1223
1224 #if defined(WIN32)
1225 #include <windows.h>
1226 #elif !defined(__APPLE__)
1227 #include <sys/sysinfo.h>
1228 #endif
1229
1230 double  HYBRIDPlugin_Hypothesis::DefaultMaximumMemory()
1231 {
1232 #if defined(WIN32)
1233   // See http://msdn.microsoft.com/en-us/library/aa366589.aspx
1234   MEMORYSTATUSEX statex;
1235   statex.dwLength = sizeof (statex);
1236   int err = GlobalMemoryStatusEx (&statex);
1237   if (err != 0) {
1238     int totMB = 
1239       statex.ullTotalPhys / 1024 / 1024 +
1240       statex.ullTotalPageFile / 1024 / 1024 +
1241       statex.ullTotalVirtual / 1024 / 1024;
1242     return ( 0.7 * totMB );
1243   }
1244 #elif !defined(__APPLE__)
1245   struct sysinfo si;
1246   int err = sysinfo( &si );
1247   if ( err == 0 ) {
1248     int ramMB = si.totalram * si.mem_unit / 1024 / 1024;
1249     return ( 0.7 * ramMB );
1250   }
1251 #endif
1252   return 1024;
1253 }
1254
1255 //=======================================================================
1256 //function : DefaultInitialMemory
1257 //=======================================================================
1258
1259 double  HYBRIDPlugin_Hypothesis::DefaultInitialMemory()
1260 {
1261   return DefaultMaximumMemory();
1262 }
1263
1264 //=======================================================================
1265 //function : DefaultCollisionMode
1266 //=======================================================================
1267 short  HYBRIDPlugin_Hypothesis::DefaultCollisionMode()
1268 {
1269   return Decrease;
1270 }
1271
1272 //=======================================================================
1273 //function : DefaultBoundaryLayersGrowth
1274 //=======================================================================
1275 short  HYBRIDPlugin_Hypothesis::DefaultBoundaryLayersGrowth()
1276 {
1277   return Layer_Growth_Inward;
1278 }
1279
1280 //=======================================================================
1281 //function : DefaultElementGeneration
1282 //=======================================================================
1283 short  HYBRIDPlugin_Hypothesis::DefaultElementGeneration()
1284 {
1285   return Generation_Tetra_Dominant;
1286 }
1287
1288 //=======================================================================
1289 //function : DefaultOptimizationLevel
1290 //=======================================================================
1291 short  HYBRIDPlugin_Hypothesis::DefaultOptimizationLevel()
1292 {
1293   return Medium;
1294 }
1295
1296 //=======================================================================
1297 //function : DefaultWorkingDirectory
1298 //=======================================================================
1299
1300 std::string HYBRIDPlugin_Hypothesis::DefaultWorkingDirectory()
1301 {
1302   std::string aTmpDir;
1303
1304   char *Tmp_dir = getenv("SALOME_TMP_DIR");
1305   if(Tmp_dir != NULL) {
1306     aTmpDir = Tmp_dir;
1307   }
1308   else {
1309 #ifdef WIN32
1310     aTmpDir = "C:\\";
1311 #else
1312     aTmpDir = "/tmp/";
1313 #endif
1314   }
1315   return aTmpDir;
1316 }
1317
1318 //=======================================================================
1319 //function : DefaultKeepFiles
1320 //=======================================================================
1321
1322 bool   HYBRIDPlugin_Hypothesis::DefaultKeepFiles()
1323 {
1324   return false;
1325 }
1326
1327 //=======================================================================
1328 //function : DefaultRemoveLogOnSuccess
1329 //=======================================================================
1330
1331 bool   HYBRIDPlugin_Hypothesis::DefaultRemoveLogOnSuccess()
1332 {
1333   return false;
1334 }
1335
1336
1337 //=======================================================================
1338 //function : DefaultVerboseLevel
1339 //=======================================================================
1340
1341 short  HYBRIDPlugin_Hypothesis::DefaultVerboseLevel()
1342 {
1343   return 10;
1344 }
1345
1346 //=======================================================================
1347 //function : DefaultToCreateNewNodes
1348 //=======================================================================
1349
1350 bool HYBRIDPlugin_Hypothesis::DefaultToCreateNewNodes()
1351 {
1352   return true;
1353 }
1354
1355 //=======================================================================
1356 //function : DefaultToUseBoundaryRecoveryVersion
1357 //=======================================================================
1358
1359 bool HYBRIDPlugin_Hypothesis::DefaultToUseBoundaryRecoveryVersion()
1360 {
1361   return false;
1362 }
1363
1364 //=======================================================================
1365 //function : DefaultToUseFEMCorrection
1366 //=======================================================================
1367
1368 bool HYBRIDPlugin_Hypothesis::DefaultToUseFEMCorrection()
1369 {
1370   return false;
1371 }
1372
1373 //=======================================================================
1374 //function : DefaultToRemoveCentralPoint
1375 //=======================================================================
1376
1377 bool HYBRIDPlugin_Hypothesis::DefaultToRemoveCentralPoint()
1378 {
1379   return false;
1380 }
1381
1382 //=======================================================================
1383 //function : DefaultGradation
1384 //=======================================================================
1385
1386 double HYBRIDPlugin_Hypothesis::DefaultGradation()
1387 {
1388   return 1.05;
1389 }
1390
1391 //=======================================================================
1392 //function : DefaultStandardOutputLog
1393 //=======================================================================
1394
1395 bool HYBRIDPlugin_Hypothesis::DefaultStandardOutputLog()
1396 {
1397   return false;
1398 }
1399
1400 // //=======================================================================
1401 // //function : DefaultID2SizeMap
1402 // //=======================================================================
1403 // 
1404 // HYBRIDPlugin_Hypothesis::TID2SizeMap HYBRIDPlugin_Hypothesis::DefaultID2SizeMap()
1405 // {
1406 //   return HYBRIDPlugin_Hypothesis::TID2SizeMap();
1407 // }
1408
1409 //=======================================================================
1410 //function : DefaultAddMultinormals
1411 //=======================================================================
1412 bool HYBRIDPlugin_Hypothesis::DefaultAddMultinormals()
1413 {
1414   return false;
1415 }
1416
1417 //=======================================================================
1418 //function : DefaultSmoothNormals
1419 //=======================================================================
1420 bool HYBRIDPlugin_Hypothesis::DefaultSmoothNormals()
1421 {
1422   return false;
1423 }
1424
1425 //=======================================================================
1426 //function : DefaultHeightFirstLayer
1427 //=======================================================================
1428 double HYBRIDPlugin_Hypothesis::DefaultHeightFirstLayer()
1429 {
1430   return 0.0; //or epsilon?
1431 }
1432
1433 //=======================================================================
1434 //function : DefaultBoundaryLayersProgression
1435 //=======================================================================
1436 double HYBRIDPlugin_Hypothesis::DefaultBoundaryLayersProgression()
1437 {
1438   return 1.0;
1439 }
1440
1441 //=======================================================================
1442 //function : DefaultCoreSize
1443 //=======================================================================
1444 double HYBRIDPlugin_Hypothesis::DefaultCoreSize()
1445 {
1446   return 0.0;
1447 }
1448
1449 //=======================================================================
1450 //function : DefaultMultinormalsAngle
1451 //=======================================================================
1452 double HYBRIDPlugin_Hypothesis::DefaultMultinormalsAngle()
1453 {
1454   return 30.0;
1455 }
1456
1457 //=======================================================================
1458 //function : DefaultNbOfBoundaryLayers
1459 //=======================================================================
1460 short HYBRIDPlugin_Hypothesis::DefaultNbOfBoundaryLayers()
1461 {
1462   return 1;
1463 }
1464
1465 //=======================================================================
1466 //function : SaveTo
1467 //=======================================================================
1468
1469 std::ostream & HYBRIDPlugin_Hypothesis::SaveTo(std::ostream & save)
1470 {
1471   save << (int) myBoundaryLayersGrowth << " ";
1472   save << (int) myElementGeneration << " ";
1473   save << (int) myAddMultinormals << " ";
1474   save << (int) mySmoothNormals << " ";
1475   save << (int) myLayersOnAllWrap << " ";
1476
1477   save << myNbOfBoundaryLayers << " ";
1478   save << myHeightFirstLayer << " ";
1479   save << myBoundaryLayersProgression << " ";
1480   save << myMultinormalsAngle << " ";
1481
1482   save << (int) myKeepFiles << " ";
1483   save << myWorkingDirectory << " ";
1484   save << myVerboseLevel << " ";
1485   save << myCoreSize << " ";
1486
1487   // if (!myTextOption.empty()) {
1488   //   save << "__OPTIONS_BEGIN__ ";
1489   //   save << myTextOption << " ";
1490   //   save << "__OPTIONS_END__ ";
1491   // }
1492
1493
1494   THYBRIDEnforcedVertexList::iterator it  = _enfVertexList.begin();
1495   if (it != _enfVertexList.end()) {
1496     save << " " << "__ENFORCED_VERTICES_BEGIN__ ";
1497     for ( ; it != _enfVertexList.end(); ++it ) {
1498       THYBRIDEnforcedVertex *enfVertex = (*it);
1499       save << " " << "__BEGIN_VERTEX__";
1500       if (!enfVertex->name.empty()) {
1501         save << " " << "__BEGIN_NAME__";
1502         save << " " << enfVertex->name;
1503         save << " " << "__END_NAME__";
1504       }
1505       if (!enfVertex->geomEntry.empty()) {
1506         save << " " << "__BEGIN_ENTRY__";
1507         save << " " << enfVertex->geomEntry;
1508         save << " " << enfVertex->isCompound;
1509         save << " " << "__END_ENTRY__";
1510       }
1511       if (!enfVertex->groupName.empty()) {
1512         save << " " << "__BEGIN_GROUP__";
1513         save << " " << enfVertex->groupName;
1514         save << " " << "__END_GROUP__";
1515       }
1516       if (enfVertex->coords.size()) {
1517         save << " " << "__BEGIN_COORDS__";
1518         for ( size_t i = 0; i < enfVertex->coords.size(); i++ )
1519           save << " " << enfVertex->coords[i];
1520         save << " " << "__END_COORDS__";
1521       }
1522       save << " " << "__BEGIN_SIZE__";
1523       save << " " << enfVertex->size;
1524       save << " " << "__END_SIZE__";
1525       save << " " << "__END_VERTEX__";
1526     }
1527     save << " " << "__ENFORCED_VERTICES_END__ ";
1528   }
1529
1530   THYBRIDEnforcedMeshList::iterator it_mesh  = _enfMeshList.begin();
1531   if (it_mesh != _enfMeshList.end()) {
1532     save << " " << "__ENFORCED_MESHES_BEGIN__ ";
1533     for ( ; it_mesh != _enfMeshList.end(); ++it_mesh ) {
1534       THYBRIDEnforcedMesh *enfMesh = (*it_mesh);
1535       save << " " << "__BEGIN_ENF_MESH__";
1536
1537       save << " " << "__BEGIN_NAME__";
1538       save << " " << enfMesh->name;
1539       save << " " << "__END_NAME__";
1540
1541       save << " " << "__BEGIN_ENTRY__";
1542       save << " " << enfMesh->entry;
1543       save << " " << "__END_ENTRY__";
1544
1545       save << " " << "__BEGIN_ELEM_TYPE__";
1546       save << " " << (int)enfMesh->elementType;
1547       save << " " << "__END_ELEM_TYPE__";
1548
1549       if (!enfMesh->groupName.empty()) {
1550         save << " " << "__BEGIN_GROUP__";
1551         save << " " << enfMesh->groupName;
1552         save << " " << "__END_GROUP__";
1553       }
1554       save << " " << "__PERSIST_ID__";
1555       save << " " << enfMesh->persistID;
1556       save << " " << "__END_ENF_MESH__";
1557       std::cout << "Saving of enforced mesh " << enfMesh->name.c_str() << " done" << std::endl;
1558     }
1559     save << " "  << "__ENFORCED_MESHES_END__ ";
1560   }
1561
1562   save << " " << myFacesWithLayers.size();
1563   for ( size_t i = 0; i < myFacesWithLayers.size(); ++i )
1564     save << " " << myFacesWithLayers[i];
1565
1566   save << " " << myFacesWithImprinting.size();
1567   for ( size_t i = 0; i < myFacesWithImprinting.size(); ++i )
1568     save << " " << myFacesWithImprinting[i];
1569
1570   save << " " << myFacesWithSnapping.size();
1571   for ( size_t i = 0; i < myFacesWithSnapping.size(); ++i )
1572     save << " " << myFacesWithSnapping[i];
1573
1574   // New options in 2.9.6 (issue #17784)
1575
1576   save << " " << myHeightIsRelative;
1577   save << " " << myBoundaryLayersMaxElemAngle;
1578   save << " " << myCollisionMode;
1579   save << " " << myGradation;
1580   save << " " << myOptimizationLevel;
1581
1582   save << " " << _option2value.size();
1583   TOptionValues::iterator o2v = _option2value.begin();
1584   for ( ; o2v != _option2value.end(); ++o2v )
1585     save << " -" << o2v->first << " -" << o2v->second;
1586
1587   save << " " << _customOption2value.size();
1588   for ( o2v = _customOption2value.begin(); o2v != _customOption2value.end(); ++o2v )
1589     save << " -" << o2v->first << " -" << o2v->second;
1590
1591   return save;
1592 }
1593
1594 //=======================================================================
1595 //function : LoadFrom
1596 //=======================================================================
1597
1598 std::istream & HYBRIDPlugin_Hypothesis::LoadFrom(std::istream & load)
1599 {
1600   bool isOK = true;
1601   int i;
1602   double d;
1603
1604   isOK = static_cast<bool>(load >> i);
1605   if (isOK)
1606     myBoundaryLayersGrowth = (short) i;
1607   else
1608     load.clear(ios::badbit | load.rdstate());
1609
1610   isOK = static_cast<bool>(load >> i);
1611   if (isOK)
1612     myElementGeneration = (short) i;
1613   else
1614     load.clear(ios::badbit | load.rdstate());
1615
1616   isOK = static_cast<bool>(load >> i);
1617   if (isOK)
1618     myAddMultinormals = (bool) i;
1619   else
1620     load.clear(ios::badbit | load.rdstate());
1621
1622   isOK = static_cast<bool>(load >> i);
1623   if (isOK)
1624     mySmoothNormals = (bool) i;
1625   else
1626     load.clear(ios::badbit | load.rdstate());
1627
1628   isOK = static_cast<bool>(load >> i);
1629   if (isOK)
1630     myLayersOnAllWrap = (bool) i;
1631   else
1632     load.clear(ios::badbit | load.rdstate());
1633
1634   isOK = static_cast<bool>(load >> i);
1635   if (isOK)
1636     myNbOfBoundaryLayers = (short) i;
1637   else
1638     load.clear(ios::badbit | load.rdstate());
1639
1640   isOK = static_cast<bool>(load >> d);
1641   if (isOK)
1642     myHeightFirstLayer = d;
1643   else
1644     load.clear(ios::badbit | load.rdstate());
1645
1646   isOK = static_cast<bool>(load >> d);
1647   if (isOK)
1648     myBoundaryLayersProgression = d;
1649   else
1650     load.clear(ios::badbit | load.rdstate());
1651
1652   isOK = static_cast<bool>(load >> d);
1653   if (isOK)
1654     myMultinormalsAngle = d;
1655   else
1656     load.clear(ios::badbit | load.rdstate());
1657
1658   isOK = static_cast<bool>(load >> i);
1659   if (isOK)
1660     myKeepFiles = (bool) i;
1661   else
1662     load.clear(ios::badbit | load.rdstate());
1663
1664   isOK = static_cast<bool>(load >> myWorkingDirectory);
1665   if (isOK) {
1666     if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty
1667       myKeepFiles = false;
1668       myWorkingDirectory.clear();
1669     }
1670     else if ( myWorkingDirectory == "1" ) {
1671       myKeepFiles = true;
1672       myWorkingDirectory.clear();
1673     }
1674   }
1675   else
1676     load.clear(ios::badbit | load.rdstate());
1677
1678   isOK = static_cast<bool>(load >> i);
1679   if (isOK)
1680     myVerboseLevel = (short) i;
1681   else
1682     load.clear(ios::badbit | load.rdstate());
1683
1684   isOK = static_cast<bool>(load >> d);
1685   if (isOK)
1686     myCoreSize = d;
1687   else
1688     load.clear(ios::badbit | load.rdstate());
1689
1690   std::string separator;
1691   bool hasOptions = false;
1692   bool hasEnforcedVertices = false;
1693   bool hasEnforcedMeshes = false;
1694   isOK = static_cast<bool>(load >> separator);
1695
1696   if (isOK) {
1697     if (separator == "__OPTIONS_BEGIN__")
1698       hasOptions = true;
1699     else if (separator == "__ENFORCED_VERTICES_BEGIN__")
1700       hasEnforcedVertices = true;
1701     else if (separator == "__ENFORCED_MESHES_BEGIN__")
1702       hasEnforcedMeshes = true;
1703   }
1704
1705   if (hasOptions) {
1706     std::string txt;
1707     while (isOK) {
1708       isOK = static_cast<bool>(load >> txt);
1709       if (isOK) {
1710         if (txt == "__OPTIONS_END__") {
1711           isOK = false;
1712           break;
1713         }
1714         // myTextOption += txt;
1715       }
1716     }
1717   }
1718
1719   if (hasOptions) {
1720     isOK = static_cast<bool>(load >> separator);
1721     if (isOK && separator == "__ENFORCED_VERTICES_BEGIN__")
1722       hasEnforcedVertices = true;
1723     if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1724       hasEnforcedMeshes = true;
1725   }
1726
1727   if (hasEnforcedVertices) {
1728     std::string txt, name, entry, groupName;
1729     double size, coords[3];
1730     bool isCompound;
1731     bool hasCoords = false;
1732     isOK = static_cast<bool>(load >> txt);  // __BEGIN_VERTEX__
1733     while (isOK) {
1734       if (txt == "__ENFORCED_VERTICES_END__")
1735         isOK = false;
1736
1737       THYBRIDEnforcedVertex *enfVertex = new THYBRIDEnforcedVertex();
1738       while (isOK) {
1739         isOK = static_cast<bool>(load >> txt);
1740         if (txt == "__END_VERTEX__") {
1741           enfVertex->name = name;
1742           enfVertex->geomEntry = entry;
1743           enfVertex->isCompound = isCompound;
1744           enfVertex->groupName = groupName;
1745           enfVertex->coords.clear();
1746           if (hasCoords)
1747             enfVertex->coords.assign(coords,coords+3);
1748
1749           _enfVertexList.insert(enfVertex);
1750
1751           if (enfVertex->coords.size())
1752             _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
1753           if (!enfVertex->geomEntry.empty())
1754             _geomEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
1755
1756           name.clear();
1757           entry.clear();
1758           groupName.clear();
1759           hasCoords = false;
1760           isOK = false;
1761         }
1762
1763         if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
1764           while (isOK && (txt != "__END_NAME__")) {
1765             isOK = static_cast<bool>(load >> txt);
1766             if (txt != "__END_NAME__") {
1767               if (!name.empty())
1768                 name += " ";
1769               name += txt;
1770             }
1771           }
1772         }
1773
1774         if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
1775           isOK = static_cast<bool>(load >> entry);
1776           isOK = static_cast<bool>(load >> isCompound);
1777           isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1778           if (txt != "__END_ENTRY__")
1779             throw std::exception();
1780         }
1781
1782         if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
1783           while (isOK && (txt != "__END_GROUP__")) {
1784             isOK = static_cast<bool>(load >> txt);
1785             if (txt != "__END_GROUP__") {
1786               if (!groupName.empty())
1787                 groupName += " ";
1788               groupName += txt;
1789             }
1790           }
1791         }
1792
1793         if (txt == "__BEGIN_COORDS__") {  // __BEGIN_COORDS__
1794           hasCoords = true;
1795           isOK = static_cast<bool>(load >> coords[0] >> coords[1] >> coords[2]);
1796           isOK = static_cast<bool>(load >> txt); // __END_COORDS__
1797           if (txt != "__END_COORDS__")
1798             throw std::exception();
1799         }
1800
1801         if (txt == "__BEGIN_SIZE__") {  // __BEGIN_ENTRY__
1802           isOK = static_cast<bool>(load >> size);
1803           isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1804           if (txt != "__END_SIZE__") {
1805             throw std::exception();
1806           }
1807         }
1808       }
1809       isOK = static_cast<bool>(load >> txt);  // __BEGIN_VERTEX__
1810     }
1811   }
1812
1813   if (hasEnforcedVertices) {
1814     isOK = static_cast<bool>(load >> separator);
1815     if (isOK && separator == "__ENFORCED_MESHES_BEGIN__")
1816       hasEnforcedMeshes = true;
1817   }
1818
1819   if (hasEnforcedMeshes) {
1820     std::string txt, name, entry, groupName;
1821     int elementType = -1, persistID = -1;
1822     isOK = static_cast<bool>(load >> txt);  // __BEGIN_ENF_MESH__
1823     while (isOK) {
1824       //                if (isOK) {
1825       if (txt == "__ENFORCED_MESHES_END__")
1826         isOK = false;
1827
1828       THYBRIDEnforcedMesh *enfMesh = new THYBRIDEnforcedMesh();
1829       while (isOK) {
1830         isOK = static_cast<bool>(load >> txt);
1831         if (txt == "__END_ENF_MESH__") {
1832           enfMesh->name = name;
1833           enfMesh->entry = entry;
1834           enfMesh->elementType = (SMESH::ElementType)elementType;
1835           enfMesh->groupName = groupName;
1836           enfMesh->persistID = persistID;
1837
1838           _enfMeshList.insert(enfMesh);
1839           std::cout << "Restoring of enforced mesh " <<name  << " done" << std::endl;
1840
1841           name.clear();
1842           entry.clear();
1843           elementType = -1;
1844           groupName.clear();
1845           persistID = -1;
1846           isOK = false;
1847         }
1848
1849         if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
1850           while (isOK && (txt != "__END_NAME__")) {
1851             isOK = static_cast<bool>(load >> txt);
1852             if (txt != "__END_NAME__") {
1853               if (!name.empty())
1854                 name += " ";
1855               name += txt;
1856             }
1857           }
1858         }
1859
1860         if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
1861           isOK = static_cast<bool>(load >> entry);
1862           isOK = static_cast<bool>(load >> txt); // __END_ENTRY__
1863           if (txt != "__END_ENTRY__")
1864             throw std::exception();
1865         }
1866
1867         if (txt == "__BEGIN_ELEM_TYPE__") {  // __BEGIN_ELEM_TYPE__
1868           isOK = static_cast<bool>(load >> elementType);
1869           isOK = static_cast<bool>(load >> txt); // __END_ELEM_TYPE__
1870           if (txt != "__END_ELEM_TYPE__")
1871             throw std::exception();
1872         }
1873
1874         if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
1875           while (isOK && (txt != "__END_GROUP__")) {
1876             isOK = static_cast<bool>(load >> txt);
1877             if (txt != "__END_GROUP__") {
1878               if (!groupName.empty())
1879                 groupName += " ";
1880               groupName += txt;
1881             }
1882           } // while
1883         } // if
1884
1885         if (txt == "__PERSIST_ID__") {
1886           isOK = static_cast<bool>(load >> persistID);
1887         }
1888         std::cout << "isOK: " << isOK << std::endl;
1889       } // while
1890       //                } // if
1891       isOK = static_cast<bool>(load >> txt);  // __BEGIN_ENF_MESH__
1892     } // while
1893   } // if
1894
1895   if ( hasEnforcedMeshes )
1896     isOK = static_cast<bool>(load >> separator);
1897
1898   if ( isOK )
1899   {
1900     i = atoi( separator.c_str() );
1901     isOK = ( i >= 0 );
1902     if ( isOK )
1903     {
1904       myFacesWithLayers.reserve( i );
1905       while (( myFacesWithLayers.size() < myFacesWithLayers.capacity() ) &&
1906              ( isOK = static_cast<bool>(load >> i)) )
1907         myFacesWithLayers.push_back( i );
1908     }
1909   }
1910
1911   isOK = static_cast<bool>(load >> separator);
1912   if ( isOK )
1913   {
1914     i = atoi( separator.c_str() );
1915     isOK = ( i >= 0 );
1916     if ( isOK )
1917     {
1918       myFacesWithImprinting.reserve( i );
1919       while (( myFacesWithImprinting.size() < myFacesWithImprinting.capacity() ) &&
1920              ( isOK = static_cast<bool>(load >> i)) )
1921         myFacesWithImprinting.push_back( i );
1922     }
1923   }
1924
1925   isOK = static_cast<bool>(load >> separator);
1926   if ( isOK )
1927   {
1928     i = atoi( separator.c_str() );
1929     isOK = ( i >= 0 );
1930     if ( isOK )
1931     {
1932       myFacesWithSnapping.reserve( i );
1933       while (( myFacesWithSnapping.size() < myFacesWithSnapping.capacity() ) &&
1934              ( isOK = static_cast<bool>(load >> i)) )
1935         myFacesWithSnapping.push_back( i );
1936     }
1937   }
1938
1939   // New options in 2.9.6 (issue #17784)
1940
1941   if ( static_cast<bool>(load >> i))
1942   {
1943     myHeightIsRelative = (bool) i;
1944     load >> myBoundaryLayersMaxElemAngle;
1945     load >> myCollisionMode;
1946     load >> myGradation;
1947     load >> myOptimizationLevel;
1948
1949     std::string option, value;
1950     if ( static_cast<bool>( load >> i ) && i >= 0 )
1951     {
1952       for ( int nbRead = 0; nbRead < i; ++nbRead )
1953       {
1954         load >> option >> value;
1955         _option2value[ std::string( option, 1 )] = std::string( value, 1 );
1956       }
1957     }
1958     if ( static_cast<bool>( load >> i ) && i >= 0 )
1959     {
1960       for ( int nbRead = 0; nbRead < i; ++nbRead )
1961       {
1962         load >> option >> value;
1963         _customOption2value[ std::string( option, 1 )] = std::string( value, 1 );
1964       }
1965     }
1966   }
1967
1968   return load;
1969 }
1970
1971 //=======================================================================
1972 //function : SetParametersByMesh
1973 //=======================================================================
1974
1975 bool HYBRIDPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoDS_Shape&)
1976 {
1977   return false;
1978 }
1979
1980 //================================================================================
1981 /*!
1982  * \brief Sets myToMakeGroupsOfDomains depending on whether theMesh is on shape or not
1983  */
1984 //================================================================================
1985
1986 bool HYBRIDPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  dflts,
1987                                                      const SMESH_Mesh* /*theMesh*/)
1988 {
1989   myToMakeGroupsOfDomains = ( !dflts._shape || dflts._shape->IsNull() );
1990   return true;
1991 }
1992
1993 //================================================================================
1994 /*!
1995  * \brief Return command to run hybrid mesher excluding file prefix (-f)
1996  */
1997 //================================================================================
1998
1999 std::string HYBRIDPlugin_Hypothesis::CommandToRun(const HYBRIDPlugin_Hypothesis* hyp)
2000 {
2001   SMESH_Comment cmd = GetExeName();
2002   // check if any option is overridden by hyp->_option2value
2003   bool p_h     = ( hyp && hyp->HasOptionDefined("-h"));
2004   bool p_v     = ( hyp && hyp->HasOptionDefined("-v"));
2005   bool p_blsd  = ( hyp && hyp->HasOptionDefined("--normal_direction"));
2006   bool p_hotfl = ( hyp && hyp->HasOptionDefined("--boundary_layer_global_initial_height"));
2007   bool p_nobl  = ( hyp && hyp->HasOptionDefined("--number_of_boundary_layers"));
2008   bool p_blgp  = ( hyp && hyp->HasOptionDefined("--boundary_layer_geometric_progression"));
2009   bool p_eg    = ( hyp && hyp->HasOptionDefined("--element_generation"));
2010   bool p_cs    = ( hyp && hyp->HasOptionDefined("--global_physical_size"));
2011
2012   bool nolayers = false;
2013   bool layersOnAllWrap = hyp ? hyp->myLayersOnAllWrap : DefaultLayersOnAllWrap();
2014
2015   //help mode
2016   if ( p_h ) {
2017     cmd << " --help ";
2018 #ifdef WIN32
2019     cmd << " < NUL";
2020 #endif
2021     std::cout << "!!!!! CommandToRun help only !!!! " << cmd << std::endl;
2022     return cmd;
2023   }
2024
2025   if ( !p_v && hyp )
2026     cmd << " --verbose " << hyp->myVerboseLevel;
2027
2028   //no layers?
2029   if ( !p_nobl && hyp ) {
2030     if ( hyp->myNbOfBoundaryLayers < 1 ) nolayers = true;
2031   }
2032   if ( !p_hotfl && hyp ) {
2033     if ( hyp->myHeightFirstLayer < 1e-50 ) nolayers = true;
2034   }
2035
2036   if ( !p_blsd && hyp ) {
2037     if ( hyp->myBoundaryLayersGrowth >= 0 && hyp->myBoundaryLayersGrowth <= 1 ) {
2038       const char* value[] = { "-1" , "1" }; // -1 == inside
2039       cmd << " --normal_direction " << value[ hyp->myBoundaryLayersGrowth ];
2040     }
2041   }
2042
2043   if ( !p_hotfl && hyp ) {
2044     cmd << " --boundary_layer_global_initial_height " << hyp->myHeightFirstLayer;
2045   }
2046   if ( hyp && hyp->GetHeightIsRelative() )
2047     cmd << " --boundary_layer_height_relative_to_local_surface_size yes";
2048
2049   if ( !p_nobl && hyp ) {
2050     cmd << " --number_of_boundary_layers " << ( nolayers ? 0 :  hyp->myNbOfBoundaryLayers );
2051   }
2052
2053   if ( !p_blgp && hyp ) {
2054     cmd << " --boundary_layer_geometric_progression " << hyp->myBoundaryLayersProgression;
2055   }
2056
2057   if ( !nolayers && hyp )
2058   {
2059     cmd << " --boundary_layer_size_mode " << ( layersOnAllWrap ? "global" : "local" );
2060
2061     if ( hyp->GetBoundaryLayersMaxElemAngle() != hyp->DefaultBoundaryLayersMaxElemAngle() )
2062       cmd << " --boundary_layer_max_element_angle "
2063           << SMESH_Comment( hyp->GetBoundaryLayersMaxElemAngle() );
2064
2065     if ( !layersOnAllWrap )
2066     {
2067       // faces with layers
2068       const std::vector<int>& faceLayersIDs = hyp->GetFacesWithLayers();
2069       if ( !faceLayersIDs.empty() )
2070         cmd << " --boundary_layer_surface_tags ";
2071       for ( size_t i = 0; i < faceLayersIDs.size(); ++i )
2072         cmd << faceLayersIDs[i] << ",";
2073       if ( !faceLayersIDs.empty() )
2074         cmd << " --boundary_layer_initial_height_on_surface_tags ";
2075       for ( size_t i = 0; i < faceLayersIDs.size(); ++i )
2076         cmd << hyp->myHeightFirstLayer << ",";
2077
2078       // faces with imprinting
2079       const std::vector<int>& faceImprintingIDs = hyp->GetFacesWithImprinting();
2080       if ( !faceImprintingIDs.empty() )
2081         cmd << " --boundary_layer_imprinting yes --boundary_layer_imprinting_tags ";
2082       for ( size_t i = 0; i < faceImprintingIDs.size(); ++i )
2083         cmd << faceImprintingIDs[i] << ",";
2084
2085       // faces with snapping
2086       const std::vector<int>& faceSnappingIDs = hyp->GetFacesWithSnapping();
2087       if ( !faceSnappingIDs.empty() )
2088         cmd << " --boundary_layer_snapping yes --boundary_layer_snapping_tags ";
2089       for ( size_t i = 0; i < faceSnappingIDs.size(); ++i )
2090         cmd << faceSnappingIDs[i] << ",";
2091     }
2092   }
2093
2094   if ( !p_eg && hyp ) {
2095     if ( hyp->myElementGeneration >= 0 && hyp->myElementGeneration <= 3 ) {
2096       const char* value[] = { "tetra_dominant" , "hexa_dominant", "cartesian_core", "extrusion_only" };
2097       cmd << " --element_generation " << value[ hyp->myElementGeneration ];
2098     }
2099   }
2100
2101   if ( !p_cs && hyp ) {
2102     if ( hyp->myCoreSize > 0 ) {
2103       cmd << " --global_physical_size " << hyp->myCoreSize;
2104     }
2105   }
2106
2107   if ( hyp )
2108   {
2109     // options as text
2110     std::string option, value;
2111     bool isDefault;
2112     const TOptionValues* options[] = { & hyp->_option2value, & hyp->_customOption2value };
2113     for ( int iOp = 0; iOp < 2; ++iOp )
2114     {
2115       TOptionValues::const_iterator o2v = options[iOp]->begin();
2116       for ( ; o2v != options[iOp]->end(); ++o2v )
2117       {
2118         option = o2v->first;
2119         value = hyp->GetOptionValue( option, &isDefault );
2120
2121         if ( isDefault )
2122           continue;
2123         if ( value.empty() )
2124         {
2125           if ( hyp->_defaultOptionValues.count( option ))
2126             continue; // non-custom option with no value
2127         }
2128         if ( option[0] != '-' )
2129           cmd << " --";
2130         else
2131           cmd << " ";
2132         cmd << option << " " << value;
2133       }
2134     }
2135   }
2136
2137 #ifdef WIN32
2138   cmd << " < NUL";
2139 #endif
2140   //std::cout << "!!!!!CommandToRun end " << cmd << std::endl;
2141
2142   return cmd;
2143 }
2144
2145 //================================================================================
2146 /*!
2147  * \brief Return a unique file name
2148  */
2149 //================================================================================
2150
2151 std::string HYBRIDPlugin_Hypothesis::GetFileName(const HYBRIDPlugin_Hypothesis* hyp)
2152 {
2153   std::string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory();
2154   const char lastChar = *aTmpDir.rbegin();
2155 #ifdef WIN32
2156   if(lastChar != '\\') aTmpDir+='\\';
2157 #else
2158   if(lastChar != '/') aTmpDir+='/';
2159 #endif
2160
2161   SMESH_Comment aGenericName = aTmpDir;
2162   aGenericName << "HYBRID_";
2163   aGenericName << getpid();
2164   aGenericName << "_";
2165   aGenericName << Abs((Standard_Integer)(long) aGenericName.c_str());
2166
2167   return aGenericName;
2168 }
2169
2170 //================================================================================
2171 /*
2172  * Return the name of executable
2173  */
2174 //================================================================================
2175
2176 std::string HYBRIDPlugin_Hypothesis::GetExeName()
2177 {
2178   //call mg-hybrid.bash is script which assumes new project version(s) mg-hybrid.exe in the prerequisite base and special? licence.
2179 #ifdef WIN32
2180   return "mg-hybrid.exe";
2181 #else
2182   return "mg-hybrid.bash";
2183 #endif
2184 }
2185
2186 //=============================================================================
2187 void HYBRIDPlugin_Hypothesis::SetOptionValue(const std::string& optionName,
2188                                              const std::string& optionValue)
2189   throw (std::invalid_argument)
2190 {
2191   TOptionValues::iterator op_val = _option2value.find(optionName);
2192   if (op_val == _option2value.end())
2193   {
2194     op_val = _customOption2value.find( optionName );
2195     if ( op_val == _customOption2value.end() || op_val->second != optionValue )
2196       NotifySubMeshesHypothesisModification();
2197     _customOption2value[ optionName ] = optionValue;
2198     return;
2199   }
2200
2201   if (op_val->second != optionValue)
2202   {
2203     const char* ptr = optionValue.c_str();
2204     // strip white spaces
2205     while (ptr[0] == ' ')
2206       ptr++;
2207     int i = strlen(ptr);
2208     while (i != 0 && ptr[i - 1] == ' ')
2209       i--;
2210     // check value type
2211     bool typeOk = true;
2212     std::string typeName;
2213     if (i == 0) {
2214       // empty string
2215     } else if (_charOptions.count(optionName)) {
2216       // do not check strings
2217     } else if (_doubleOptions.count(optionName)) {
2218       // check if value is double
2219       ToDbl(ptr, &typeOk);
2220       typeName = "real";
2221     } else if (_boolOptions.count(optionName)) {
2222       // check if value is bool
2223       ToBool(ptr, &typeOk);
2224       typeName = "bool";
2225     } else {
2226       // check if value is int
2227       ToInt(ptr, &typeOk);
2228       typeName = "integer";
2229     }
2230     if ( typeOk ) // check some specific values ?
2231     {
2232     }
2233     if ( !typeOk )
2234     {
2235       std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
2236       throw std::invalid_argument(msg);
2237     }
2238     std::string value( ptr, i );
2239     if ( _defaultOptionValues[ optionName ] == value )
2240       value.clear();
2241
2242     op_val->second = value;
2243
2244     NotifySubMeshesHypothesisModification();
2245   }
2246 }
2247
2248 //=============================================================================
2249 //! Return option value. If isDefault provided, it can be a default value,
2250 //  then *isDefault == true. If isDefault is not provided, the value will be
2251 //  empty if it equals a default one.
2252 std::string HYBRIDPlugin_Hypothesis::GetOptionValue(const std::string& optionName,
2253                                                     bool*              isDefault) const
2254   throw (std::invalid_argument)
2255 {
2256   TOptionValues::const_iterator op_val = _option2value.find(optionName);
2257   if (op_val == _option2value.end())
2258   {
2259     op_val = _customOption2value.find(optionName);
2260     if (op_val == _customOption2value.end())
2261     {
2262       std::string msg = "Unknown MG-Tetra option: <" + optionName + ">";
2263       throw std::invalid_argument(msg);
2264     }
2265   }
2266   std::string val = op_val->second;
2267   if ( isDefault ) *isDefault = ( val.empty() );
2268
2269   if ( val.empty() && isDefault )
2270   {
2271     op_val = _defaultOptionValues.find( optionName );
2272     if (op_val != _defaultOptionValues.end())
2273       val = op_val->second;
2274   }
2275   return val;
2276 }
2277
2278
2279 //=============================================================================
2280 bool HYBRIDPlugin_Hypothesis::HasOptionDefined( const std::string& optionName ) const
2281 {
2282   bool isDefault = false;
2283   try
2284   {
2285     GetOptionValue( optionName, &isDefault );
2286   }
2287   catch ( std::invalid_argument )
2288   {
2289     return false;
2290   }
2291   return !isDefault;
2292 }
2293
2294 //=============================================================================
2295 void HYBRIDPlugin_Hypothesis::ClearOption(const std::string& optionName)
2296 {
2297   TOptionValues::iterator op_val = _customOption2value.find(optionName);
2298   if (op_val != _customOption2value.end())
2299     _customOption2value.erase(op_val);
2300   else {
2301     op_val = _option2value.find(optionName);
2302     if (op_val != _option2value.end())
2303       op_val->second.clear();
2304   }
2305 }
2306
2307 //=============================================================================
2308 HYBRIDPlugin_Hypothesis::TOptionValues HYBRIDPlugin_Hypothesis::GetOptionValues() const
2309 {
2310   TOptionValues vals;
2311   TOptionValues::const_iterator op_val = _option2value.begin();
2312   for ( ; op_val != _option2value.end(); ++op_val )
2313     vals.insert( make_pair( op_val->first, GetOptionValue( op_val->first, GET_DEFAULT() )));
2314
2315   return vals;
2316 }
2317
2318 //================================================================================
2319 /*!
2320  * \brief Converts a string to a bool
2321  */
2322 //================================================================================
2323
2324 bool HYBRIDPlugin_Hypothesis::ToBool(const std::string& str, bool* isOk )
2325   throw (std::invalid_argument)
2326 {
2327   std::string s = str;
2328   if ( isOk ) *isOk = true;
2329
2330   for ( size_t i = 0; i <= s.size(); ++i )
2331     s[i] = tolower( s[i] );
2332
2333   if ( s == "1" || s == "true" || s == "active" || s == "yes" )
2334     return true;
2335
2336   if ( s == "0" || s == "false" || s == "inactive" || s == "no" )
2337     return false;
2338
2339   if ( isOk )
2340     *isOk = false;
2341   else {
2342     std::string msg = "Not a Boolean value:'" + str + "'";
2343     throw std::invalid_argument(msg);
2344   }
2345   return false;
2346 }
2347
2348 //================================================================================
2349 /*!
2350  * \brief Converts a string to a real value
2351  */
2352 //================================================================================
2353
2354 double HYBRIDPlugin_Hypothesis::ToDbl(const std::string& str, bool* isOk )
2355   throw (std::invalid_argument)
2356 {
2357   if ( str.empty() ) throw std::invalid_argument("Empty value provided");
2358
2359   char * endPtr;
2360   double val = strtod(&str[0], &endPtr);
2361   bool ok = (&str[0] != endPtr);
2362
2363   if ( isOk ) *isOk = ok;
2364
2365   if ( !ok )
2366   {
2367     std::string msg = "Not a real value:'" + str + "'";
2368     throw std::invalid_argument(msg);
2369   }
2370   return val;
2371 }
2372
2373 //================================================================================
2374 /*!
2375  * \brief Converts a string to a integer value
2376  */
2377 //================================================================================
2378
2379 int HYBRIDPlugin_Hypothesis::ToInt(const std::string& str, bool* isOk )
2380   throw (std::invalid_argument)
2381 {
2382   if ( str.empty() ) throw std::invalid_argument("Empty value provided");
2383
2384   char * endPtr;
2385   int val = (int)strtol( &str[0], &endPtr, 10);
2386   bool ok = (&str[0] != endPtr);
2387
2388   if ( isOk ) *isOk = ok;
2389
2390   if ( !ok )
2391   {
2392     std::string msg = "Not an integer value:'" + str + "'";
2393     throw std::invalid_argument(msg);
2394   }
2395   return val;
2396 }
2397
2398
2399 HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertexList HYBRIDPlugin_Hypothesis::GetEnforcedVertices(const HYBRIDPlugin_Hypothesis* hyp)
2400 {
2401   return hyp ? hyp->_GetEnforcedVertices():THYBRIDEnforcedVertexList();
2402 }
2403
2404 HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertexCoordsValues HYBRIDPlugin_Hypothesis::GetEnforcedVerticesCoordsSize (const HYBRIDPlugin_Hypothesis* hyp)
2405 {  
2406   return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): THYBRIDEnforcedVertexCoordsValues();
2407 }
2408
2409 HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertexEntryValues HYBRIDPlugin_Hypothesis::GetEnforcedVerticesEntrySize (const HYBRIDPlugin_Hypothesis* hyp)
2410 {  
2411   return hyp ? hyp->_GetEnforcedVerticesEntrySize():THYBRIDEnforcedVertexEntryValues();
2412 }
2413
2414 HYBRIDPlugin_Hypothesis::TCoordsHYBRIDEnforcedVertexMap HYBRIDPlugin_Hypothesis::GetEnforcedVerticesByCoords (const HYBRIDPlugin_Hypothesis* hyp)
2415 {  
2416   return hyp ? hyp->_GetEnforcedVerticesByCoords():TCoordsHYBRIDEnforcedVertexMap();
2417 }
2418
2419 HYBRIDPlugin_Hypothesis::TGeomEntryHYBRIDEnforcedVertexMap HYBRIDPlugin_Hypothesis::GetEnforcedVerticesByEntry (const HYBRIDPlugin_Hypothesis* hyp)
2420 {  
2421   return hyp ? hyp->_GetEnforcedVerticesByEntry():TGeomEntryHYBRIDEnforcedVertexMap();
2422 }
2423
2424 HYBRIDPlugin_Hypothesis::TIDSortedNodeGroupMap HYBRIDPlugin_Hypothesis::GetEnforcedNodes(const HYBRIDPlugin_Hypothesis* hyp)
2425 {
2426   return hyp ? hyp->_GetEnforcedNodes():TIDSortedNodeGroupMap();
2427 }
2428
2429 HYBRIDPlugin_Hypothesis::TIDSortedElemGroupMap HYBRIDPlugin_Hypothesis::GetEnforcedEdges(const HYBRIDPlugin_Hypothesis* hyp)
2430 {
2431   return hyp ? hyp->_GetEnforcedEdges():TIDSortedElemGroupMap();
2432 }
2433
2434 HYBRIDPlugin_Hypothesis::TIDSortedElemGroupMap HYBRIDPlugin_Hypothesis::GetEnforcedTriangles(const HYBRIDPlugin_Hypothesis* hyp)
2435 {
2436   return hyp ? hyp->_GetEnforcedTriangles():TIDSortedElemGroupMap();
2437 }
2438
2439 HYBRIDPlugin_Hypothesis::TID2SizeMap HYBRIDPlugin_Hypothesis::GetNodeIDToSizeMap(const HYBRIDPlugin_Hypothesis* hyp)
2440 {
2441   return hyp ? hyp->_GetNodeIDToSizeMap():TID2SizeMap();
2442 }
2443
2444 HYBRIDPlugin_Hypothesis::TSetStrings HYBRIDPlugin_Hypothesis::GetGroupsToRemove(const HYBRIDPlugin_Hypothesis* hyp)
2445 {
2446   return hyp ? hyp->_GetGroupsToRemove():TSetStrings();
2447 }