Salome HOME
Porting to MeshGems 2.10: additional correction to avoid crash
[plugins/blsurfplugin.git] / src / BLSURFPlugin / BLSURFPlugin_Hypothesis.cxx
1 // Copyright (C) 2007-2019  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    : BLSURFPlugin_Hypothesis.cxx
22 // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA)
23 //           & Aurelien ALLEAUME (DISTENE)
24 //           Size maps development: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE)
25 // ---
26 //
27 #include "BLSURFPlugin_Hypothesis.hxx"
28 #include "BLSURFPlugin_Attractor.hxx"
29 #include "SMESH_Gen_i.hxx"
30 #include <utilities.h>
31 #include <cstring>
32 #include <iostream>
33 #include <sstream>
34
35 // cascade include
36 #include "ShapeAnalysis.hxx"
37
38 // CORBA includes
39 #include CORBA_CLIENT_HEADER(SALOMEDS)
40 #include CORBA_CLIENT_HEADER(GEOM_Gen)
41
42 #include <meshgems/meshgems.h>
43
44 namespace
45 {
46   struct GET_DEFAULT // struct used to get default value from GetOptionValue()
47   {
48     bool isDefault;
49     operator bool* () { return &isDefault; }
50   };
51 }
52
53 //=============================================================================
54 BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis(int hypId, SMESH_Gen * gen, bool hasgeom) :
55   SMESH_Hypothesis(hypId, gen),
56   _physicalMesh(GetDefaultPhysicalMesh()),
57   _geometricMesh(GetDefaultGeometricMesh()),
58   _phySize(GetDefaultPhySize()),
59   _phySizeRel(GetDefaultPhySizeRel()),
60   _minSize(GetDefaultMinSize()),
61   _maxSize(GetDefaultMaxSize()),
62   _minSizeRel(GetDefaultMinSizeRel()),
63   _maxSizeRel(GetDefaultMaxSizeRel()),
64   _useGradation(GetDefaultUseGradation()),
65   _gradation(GetDefaultGradation()),
66   _useVolumeGradation(GetDefaultUseVolumeGradation()),
67   _volumeGradation(GetDefaultVolumeGradation()),
68   _elementType(GetDefaultElementType()),
69   _angleMesh(GetDefaultAngleMesh()),
70   _chordalError(GetDefaultChordalError()),
71   _anisotropic(GetDefaultAnisotropic()),
72   _anisotropicRatio(GetDefaultAnisotropicRatio()),
73   _removeTinyEdges(GetDefaultRemoveTinyEdges()),
74   _tinyEdgeLength(GetDefaultTinyEdgeLength()),
75   _optimiseTinyEdges(GetDefaultOptimiseTinyEdges()),
76   _tinyEdgeOptimisationLength(GetDefaultTinyEdgeOptimisationLength()),
77   _correctSurfaceIntersec(GetDefaultCorrectSurfaceIntersection()),
78   _corrSurfaceIntersCost(GetDefaultCorrectSurfaceIntersectionMaxCost()),
79   _badElementRemoval(GetDefaultBadElementRemoval()),
80   _badElementAspectRatio(GetDefaultBadElementAspectRatio()),
81   _optimizeMesh(GetDefaultOptimizeMesh()),
82   _quadraticMesh(GetDefaultQuadraticMesh()),
83   _verb(GetDefaultVerbosity()),
84   _topology(GetDefaultTopology()),
85   _useSurfaceProximity(GetDefaultUseSurfaceProximity()),
86   _nbSurfaceProximityLayers(GetDefaultNbSurfaceProximityLayers()),
87   _surfaceProximityRatio(GetDefaultSurfaceProximityRatio()),
88   _useVolumeProximity(GetDefaultUseVolumeProximity()),
89   _nbVolumeProximityLayers(GetDefaultNbVolumeProximityLayers()),
90   _volumeProximityRatio(GetDefaultVolumeProximityRatio()),
91   _preCADMergeEdges(GetDefaultPreCADMergeEdges()),
92   _preCADRemoveDuplicateCADFaces(GetDefaultPreCADRemoveDuplicateCADFaces()),
93   _preCADProcess3DTopology(GetDefaultPreCADProcess3DTopology()),
94   _preCADDiscardInput(GetDefaultPreCADDiscardInput()),
95   _sizeMap(GetDefaultSizeMap()),
96   _attractors(GetDefaultSizeMap()),
97   _classAttractors(GetDefaultAttractorMap()),
98   _faceEntryEnfVertexListMap(GetDefaultFaceEntryEnfVertexListMap()),
99   _enfVertexList(GetDefaultEnfVertexList()),
100   _faceEntryCoordsListMap(GetDefaultFaceEntryCoordsListMap()),
101   _coordsEnfVertexMap(GetDefaultCoordsEnfVertexMap()),
102   _faceEntryEnfVertexEntryListMap(GetDefaultFaceEntryEnfVertexEntryListMap()),
103   _enfVertexEntryEnfVertexMap(GetDefaultEnfVertexEntryEnfVertexMap()),
104   _groupNameNodeIDMap(GetDefaultGroupNameNodeIDMap()),
105   _enforcedInternalVerticesAllFaces(GetDefaultInternalEnforcedVertex()),
106   _preCadFacesPeriodicityVector(GetDefaultPreCadFacesPeriodicityVector()),
107   _preCadEdgesPeriodicityVector(GetDefaultPreCadEdgesPeriodicityVector()),
108   _GMFFileName(GetDefaultGMFFile())
109 {
110   _name = GetHypType(hasgeom);
111   _param_algo_dim = 2;
112
113   // Advanced options with their defaults according to MG User Manual
114
115   const char* boolOptionNames[] = {
116     //"enforce_cad_edge_sizes",                 // default = 0 // Deprecated since MeshGems 2.10
117     "jacobian_rectification_respect_geometry",  // default = 1
118     "rectify_jacobian",                         // default = 1
119     "respect_geometry",                         // default = 1
120     "tiny_edge_avoid_surface_intersections",    // default = 1
121     "debug",                                    // default = 0
122     "allow_patch_independent",                   // false
123     "" // mark of end
124   };
125
126   const char* intOptionNames[] = {
127     //"max_number_of_points_per_patch",         // default = 100000 // Deprecated since MeshGems 2.10
128     "max_number_of_threads",                    // default = 4
129     "" // mark of end
130   };
131   const char* doubleOptionNames[] = {       // "surface_intersections_processing_max_cost",// default = 15
132                                             // "periodic_tolerance",                       // default = diag/100
133                                             // "volume_gradation",
134                                             // "tiny_edge_optimisation_length",            // default = diag * 1e-6
135     "" // mark of end
136   };
137   const char* charOptionNames[] = {         // "required_entities",                        // default = "respect"
138                                             // "tags",                                     // default = "respect"
139     "" // mark of end
140   };
141
142   // PreCAD advanced options
143   const char* preCADboolOptionNames[] = {   "closed_geometry",                          // default = 0
144                                             "discard_input_topology",                   // default = 0
145                                             "merge_edges",                              // default =  = 1
146                                             "remove_duplicate_cad_faces",               // default = 1
147                                             // "create_tag_on_collision",                  // default = 1
148                                             "process_3d_topology",                      // default = 1
149                                             // "remove_tiny_edges",                        // default = 0
150                                             // remove_tiny_uv_edges option is not documented
151                                             // but it is useful that the user can change it to disable all preprocessing options
152                                             "remove_tiny_uv_edges",                        // default = 1
153                                             "compute_ridges",                             // true
154                                             "" // mark of end
155       };
156   const char* preCADintOptionNames[] = {    // "manifold_geometry",                        // default = 0
157                                             "" // mark of end
158       };
159   const char* preCADdoubleOptionNames[] = { "periodic_tolerance",                       // default = diag * 1e-5
160                                             "sewing_tolerance",                         // default = diag * 5e-4
161                                             // "tiny_edge_length",                         // default = diag * 1e-5
162                                             "" // mark of end
163       };
164   const char* preCADcharOptionNames[] = {   "required_entities",                        // default = "respect"
165                                             "tags",                                     // default = "respect"
166                                             "" // mark of end
167       };
168   
169   int i = 0;
170   while (boolOptionNames[i][0])
171   {
172     _boolOptions.insert( boolOptionNames[i] );
173     _option2value[boolOptionNames[i++]].clear();
174   }
175   i = 0;
176   while (preCADboolOptionNames[i][0] && hasgeom)
177   {
178     _boolOptions.insert( preCADboolOptionNames[i] );
179     _preCADoption2value[preCADboolOptionNames[i++]].clear();
180   }
181   i = 0;
182   while (intOptionNames[i][0])
183     _option2value[intOptionNames[i++]].clear();
184   
185   i = 0;
186   while (preCADintOptionNames[i][0] && hasgeom)
187     _preCADoption2value[preCADintOptionNames[i++]].clear();
188
189   i = 0;
190   while (doubleOptionNames[i][0]) {
191     _doubleOptions.insert(doubleOptionNames[i]);
192     _option2value[doubleOptionNames[i++]].clear();
193   }
194   i = 0;
195   while (preCADdoubleOptionNames[i][0] && hasgeom) {
196     _preCADdoubleOptions.insert(preCADdoubleOptionNames[i]);
197     _preCADoption2value[preCADdoubleOptionNames[i++]].clear();
198   }
199   i = 0;
200   while (charOptionNames[i][0]) {
201     _charOptions.insert(charOptionNames[i]);
202     _option2value[charOptionNames[i++]].clear();
203   }
204   i = 0;
205   while (preCADcharOptionNames[i][0] && hasgeom) {
206     _preCADcharOptions.insert(preCADcharOptionNames[i]);
207     _preCADoption2value[preCADcharOptionNames[i++]].clear();
208   }
209
210   // default values to be used while MG meshing
211
212   // _defaultOptionValues["enforce_cad_edge_sizes"                 ] = "no";  // Deprecated since MeshGems 2.10
213   _defaultOptionValues["jacobian_rectification_respect_geometry"] = "yes";
214   // _defaultOptionValues["max_number_of_points_per_patch"         ] = "0";   // Deprecated since MeshGems 2.10
215   _defaultOptionValues["max_number_of_threads"                  ] = "4";
216   _defaultOptionValues["rectify_jacobian"                       ] = "yes";
217   _defaultOptionValues["respect_geometry"                       ] = "yes";
218   _defaultOptionValues["tiny_edge_avoid_surface_intersections"  ] = "yes";
219   //_defaultOptionValues["use_deprecated_patch_mesher"          ] = "no";
220   _defaultOptionValues["debug"                                  ] = "no";
221   _defaultOptionValues["allow_patch_independent"                ] = "no";
222   if ( hasgeom )
223   {
224     _defaultOptionValues["closed_geometry"                        ] = "no";
225     _defaultOptionValues["discard_input_topology"                 ] = "no";
226     _defaultOptionValues["merge_edges"                            ] = "no";
227     _defaultOptionValues["periodic_tolerance"                     ] = "1e-5*D";
228     _defaultOptionValues["process_3d_topology"                    ] = "no";
229     _defaultOptionValues["remove_duplicate_cad_faces"             ] = "no";
230     _defaultOptionValues["remove_tiny_uv_edges"                   ] = "no";
231     _defaultOptionValues["required_entities"                      ] = "respect";
232     _defaultOptionValues["sewing_tolerance"                       ] = "5e-4*D";
233     _defaultOptionValues["tags"                                   ] = "respect";
234     _defaultOptionValues["compute_ridges"                         ] = "yes";
235   }
236
237   if ( strcmp( MESHGEMS_VERSION_LONG, "2.9-6" ) < 0 )
238   {
239     std::string missingOption = "allow_patch_independent";
240     _defaultOptionValues.erase( missingOption );
241     _boolOptions.erase( missingOption );
242     _option2value.erase( missingOption );
243   }
244
245 #ifdef _DEBUG_
246   // check validity of option names of _defaultOptionValues
247   TOptionValues::iterator n2v = _defaultOptionValues.begin();
248   for ( ; n2v != _defaultOptionValues.end(); ++n2v )
249     ASSERT( _option2value.count( n2v->first ) || _preCADoption2value.count( n2v->first ));
250   ASSERT( _option2value.size() + _preCADoption2value.size() == _defaultOptionValues.size() );
251 #endif
252
253 }
254
255 TopoDS_Shape BLSURFPlugin_Hypothesis::entryToShape(std::string entry)
256 {
257   GEOM::GEOM_Object_var aGeomObj;
258   
259   TopoDS_Shape S = TopoDS_Shape();
260   SALOMEDS::SObject_var aSObj = SMESH_Gen_i::getStudyServant()->FindObjectID( entry.c_str() );
261   if (!aSObj->_is_nil() ) {
262     CORBA::Object_var obj = aSObj->GetObject();
263     aGeomObj = GEOM::GEOM_Object::_narrow(obj);
264     aSObj->UnRegister();
265   }
266   if ( !aGeomObj->_is_nil() )
267     S = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( aGeomObj.in() );
268   return S;
269 }
270
271 //=============================================================================
272 void BLSURFPlugin_Hypothesis::SetPhysicalMesh(PhysicalMesh thePhysicalMesh) {
273   if (thePhysicalMesh != _physicalMesh) {
274     _physicalMesh = thePhysicalMesh;
275     NotifySubMeshesHypothesisModification();
276   }
277 }
278
279 //=============================================================================
280 void BLSURFPlugin_Hypothesis::SetGeometricMesh(GeometricMesh theGeometricMesh) {
281   if (theGeometricMesh != _geometricMesh) {
282     _geometricMesh = theGeometricMesh;
283 //     switch (_geometricMesh) {
284 //       case DefaultGeom:
285 //       default:
286 //         _angleMesh = GetDefaultAngleMesh();
287 //         _gradation = GetDefaultGradation();
288 //         break;
289 //     }
290     NotifySubMeshesHypothesisModification();
291   }
292 }
293
294 //=============================================================================
295 void BLSURFPlugin_Hypothesis::SetPhySize(double theVal, bool isRelative) {
296   if ((theVal != _phySize) || (isRelative != _phySizeRel)) {
297     _phySizeRel = isRelative;
298     if (theVal == 0) {
299       _phySize = GetMaxSize();
300     }
301     else
302       _phySize = theVal;
303     NotifySubMeshesHypothesisModification();
304   }
305 }
306
307 //=============================================================================
308 void BLSURFPlugin_Hypothesis::SetMinSize(double theMinSize, bool isRelative) {
309   if ((theMinSize != _minSize) || (isRelative != _minSizeRel)) {
310     _minSizeRel = isRelative;
311     _minSize = theMinSize;
312     NotifySubMeshesHypothesisModification();
313   }
314 }
315
316 //=============================================================================
317 void BLSURFPlugin_Hypothesis::SetMaxSize(double theMaxSize, bool isRelative) {
318   if ((theMaxSize != _maxSize) || (isRelative != _maxSizeRel)) {
319     _maxSizeRel = isRelative;
320     _maxSize = theMaxSize;
321     NotifySubMeshesHypothesisModification();
322   }
323 }
324
325 //=============================================================================
326 void BLSURFPlugin_Hypothesis::SetUseGradation(bool theVal) {
327   if (theVal != _useGradation) {
328     _useGradation = theVal;
329     NotifySubMeshesHypothesisModification();
330   }
331 }
332
333 //=============================================================================
334 void BLSURFPlugin_Hypothesis::SetGradation(double theVal) {
335   _useGradation = ( theVal > 0 );
336   if (theVal != _gradation) {
337     _gradation = theVal;
338     NotifySubMeshesHypothesisModification();
339   }
340 }
341
342 //=============================================================================
343 void BLSURFPlugin_Hypothesis::SetUseVolumeGradation(bool theVal) {
344   if (theVal != _useVolumeGradation) {
345     _useVolumeGradation = theVal;
346     NotifySubMeshesHypothesisModification();
347   }
348 }
349
350 //=============================================================================
351 void BLSURFPlugin_Hypothesis::SetVolumeGradation(double theVal) {
352   _useVolumeGradation = ( theVal > 0 );
353   if (theVal != _volumeGradation) {
354     _volumeGradation = theVal;
355     NotifySubMeshesHypothesisModification();
356   }
357 }
358
359 //=============================================================================
360 void BLSURFPlugin_Hypothesis::SetElementType(ElementType theElementType) {
361   if (theElementType != _elementType) {
362     _elementType = theElementType;
363     NotifySubMeshesHypothesisModification();
364   }
365 }
366
367 //=============================================================================
368 void BLSURFPlugin_Hypothesis::SetAngleMesh(double theVal) {
369   if (theVal != _angleMesh) {
370     _angleMesh = theVal;
371     NotifySubMeshesHypothesisModification();
372   }
373 }
374
375 //=============================================================================
376 void BLSURFPlugin_Hypothesis::SetChordalError(double theDistance) {
377   if (theDistance != _chordalError) {
378     _chordalError = theDistance;
379     NotifySubMeshesHypothesisModification();
380   }
381 }
382
383 //=============================================================================
384 void BLSURFPlugin_Hypothesis::SetAnisotropic(bool theVal) {
385   if (theVal != _anisotropic) {
386     _anisotropic = theVal;
387     NotifySubMeshesHypothesisModification();
388   }
389 }
390
391 //=============================================================================
392 void BLSURFPlugin_Hypothesis::SetAnisotropicRatio(double theVal) {
393   if (theVal != _anisotropicRatio) {
394     _anisotropicRatio = theVal;
395     NotifySubMeshesHypothesisModification();
396   }
397 }
398
399 //=============================================================================
400 void BLSURFPlugin_Hypothesis::SetRemoveTinyEdges(bool theVal) {
401   if (theVal != _removeTinyEdges) {
402     _removeTinyEdges = theVal;
403     NotifySubMeshesHypothesisModification();
404   }
405 }
406
407 //=============================================================================
408 void BLSURFPlugin_Hypothesis::SetTinyEdgeLength(double theVal) {
409   if (theVal != _tinyEdgeLength) {
410     _tinyEdgeLength = theVal;
411     NotifySubMeshesHypothesisModification();
412   }
413 }
414
415 //=============================================================================
416 void BLSURFPlugin_Hypothesis::SetOptimiseTinyEdges(bool theVal) {
417   if (theVal != _optimiseTinyEdges) {
418     _optimiseTinyEdges = theVal;
419     NotifySubMeshesHypothesisModification();
420   }
421 }
422
423 //=============================================================================
424 void BLSURFPlugin_Hypothesis::SetTinyEdgeOptimisationLength(double theVal) {
425   if (theVal != _tinyEdgeOptimisationLength) {
426     _tinyEdgeOptimisationLength = theVal;
427     NotifySubMeshesHypothesisModification();
428   }
429 }
430
431 //=============================================================================
432 void BLSURFPlugin_Hypothesis::SetCorrectSurfaceIntersection(bool theVal) {
433   if (theVal != _correctSurfaceIntersec) {
434     _correctSurfaceIntersec = theVal;
435     NotifySubMeshesHypothesisModification();
436   }
437 }
438
439 //=============================================================================
440 void BLSURFPlugin_Hypothesis::SetCorrectSurfaceIntersectionMaxCost(double theVal) {
441   if (theVal != _corrSurfaceIntersCost) {
442     _corrSurfaceIntersCost = theVal;
443     NotifySubMeshesHypothesisModification();
444   }
445 }
446
447 //=============================================================================
448 void BLSURFPlugin_Hypothesis::SetBadElementRemoval(bool theVal) {
449   if (theVal != _badElementRemoval) {
450     _badElementRemoval = theVal;
451     NotifySubMeshesHypothesisModification();
452   }
453 }
454
455 //=============================================================================
456 void BLSURFPlugin_Hypothesis::SetBadElementAspectRatio(double theVal) {
457   if (theVal != _badElementAspectRatio) {
458     _badElementAspectRatio = theVal;
459     NotifySubMeshesHypothesisModification();
460   }
461 }
462
463 //=============================================================================
464 void BLSURFPlugin_Hypothesis::SetOptimizeMesh(bool theVal) {
465   if (theVal != _optimizeMesh) {
466     _optimizeMesh = theVal;
467     NotifySubMeshesHypothesisModification();
468   }
469 }
470
471 //=============================================================================
472 void BLSURFPlugin_Hypothesis::SetQuadraticMesh(bool theVal) {
473   if (theVal != _quadraticMesh) {
474     _quadraticMesh = theVal;
475     NotifySubMeshesHypothesisModification();
476   }
477 }
478
479 //=============================================================================
480 void BLSURFPlugin_Hypothesis::SetTopology(Topology theTopology) {
481   if (theTopology != _topology) {
482     _topology = theTopology;
483     NotifySubMeshesHypothesisModification();
484   }
485 }
486
487 //=============================================================================
488 void BLSURFPlugin_Hypothesis::SetUseSurfaceProximity( bool toUse )
489 {
490   if ( _useSurfaceProximity != toUse )
491   {
492     _useSurfaceProximity = toUse;
493     NotifySubMeshesHypothesisModification();
494   }
495 }
496
497 //=============================================================================
498 void BLSURFPlugin_Hypothesis::SetNbSurfaceProximityLayers( int nbLayers )
499 {
500   if ( _nbSurfaceProximityLayers != nbLayers )
501   {
502     _nbSurfaceProximityLayers = nbLayers;
503     NotifySubMeshesHypothesisModification();
504   }
505 }
506
507 //=============================================================================
508 void BLSURFPlugin_Hypothesis::SetSurfaceProximityRatio( double ratio )
509 {
510   if ( _surfaceProximityRatio != ratio )
511   {
512     _surfaceProximityRatio = ratio;
513     NotifySubMeshesHypothesisModification();
514   }
515 }
516
517 //=============================================================================
518 void BLSURFPlugin_Hypothesis::SetUseVolumeProximity( bool toUse )
519 {
520   if ( _useVolumeProximity != toUse )
521   {
522     _useVolumeProximity = toUse;
523     NotifySubMeshesHypothesisModification();
524   }
525 }
526
527 //=============================================================================
528 void BLSURFPlugin_Hypothesis::SetNbVolumeProximityLayers( int nbLayers )
529 {
530   if ( _nbVolumeProximityLayers != nbLayers )
531   {
532     _nbVolumeProximityLayers = nbLayers;
533     NotifySubMeshesHypothesisModification();
534   }
535 }
536
537 //=============================================================================
538 void BLSURFPlugin_Hypothesis::SetVolumeProximityRatio( double ratio )
539 {
540   if ( _volumeProximityRatio != ratio )
541   {
542     _volumeProximityRatio = ratio;
543     NotifySubMeshesHypothesisModification();
544   }
545 }
546
547 //=============================================================================
548 void BLSURFPlugin_Hypothesis::SetVerbosity(int theVal) {
549   if (theVal != _verb) {
550     _verb = theVal;
551     NotifySubMeshesHypothesisModification();
552   }
553 }
554
555 //=============================================================================
556 void BLSURFPlugin_Hypothesis::SetEnforceCadEdgesSize( bool toEnforce )
557 {
558   /* Deprecated since MeshGems 2.10
559   if ( GetEnforceCadEdgesSize() != toEnforce )
560   {
561     SetOptionValue( "enforce_cad_edge_sizes", toEnforce ? "yes" : "no" );
562     NotifySubMeshesHypothesisModification();
563   }
564   */
565 }
566 //=============================================================================
567 bool BLSURFPlugin_Hypothesis::GetEnforceCadEdgesSize()
568 {
569   /* Deprecated since MeshGems 2.10
570   return ToBool( GetOptionValue( "enforce_cad_edge_sizes" ), GET_DEFAULT() );
571  */
572   return false;
573 }
574 //=============================================================================
575
576 void BLSURFPlugin_Hypothesis::SetJacobianRectificationRespectGeometry( bool allowRectification )
577 {
578   if ( GetJacobianRectificationRespectGeometry() != allowRectification )
579   {
580     SetOptionValue("jacobian_rectification_respect_geometry", allowRectification ? "yes" : "no" );
581     NotifySubMeshesHypothesisModification();
582   }
583 }
584 //=============================================================================
585 bool BLSURFPlugin_Hypothesis::GetJacobianRectificationRespectGeometry()
586 {
587   return ToBool( GetOptionValue("jacobian_rectification_respect_geometry", GET_DEFAULT()));
588 }
589 //=============================================================================
590
591 void BLSURFPlugin_Hypothesis::SetJacobianRectification( bool allowRectification )
592 {
593   if ( GetJacobianRectification() != allowRectification )
594   {
595     SetOptionValue( "rectify_jacobian", allowRectification ? "yes" : "no" );
596     NotifySubMeshesHypothesisModification();
597   }
598 }
599 //=============================================================================
600 bool BLSURFPlugin_Hypothesis::GetJacobianRectification()
601 {
602   return ToBool( GetOptionValue("rectify_jacobian", GET_DEFAULT()));
603 }
604 //=============================================================================
605
606 void BLSURFPlugin_Hypothesis::SetUseDeprecatedPatchMesher( bool useDeprecatedPatchMesher )
607 {
608   // if ( GetUseDeprecatedPatchMesher() != useDeprecatedPatchMesher )
609   // {
610   //   SetOptionValue( "use_deprecated_patch_mesher", useDeprecatedPatchMesher ? "yes" : "no" );
611   //   NotifySubMeshesHypothesisModification();
612   // }
613 }
614 //=============================================================================
615 bool BLSURFPlugin_Hypothesis::GetUseDeprecatedPatchMesher()
616 {
617   return false;//ToBool( GetOptionValue("use_deprecated_patch_mesher", GET_DEFAULT()));
618 }
619 //=============================================================================
620
621 void BLSURFPlugin_Hypothesis::SetMaxNumberOfPointsPerPatch( int nb )
622   throw (std::invalid_argument)
623 {
624   /* Deprecated since MeshGems 2.10
625   if ( nb < 0 )
626     throw std::invalid_argument( SMESH_Comment("Invalid number of points: ") << nb );
627
628   if ( GetMaxNumberOfPointsPerPatch() != nb )
629   {
630     SetOptionValue("max_number_of_points_per_patch", SMESH_Comment( nb ));
631     NotifySubMeshesHypothesisModification();
632   }
633   */
634 }
635 //=============================================================================
636 int BLSURFPlugin_Hypothesis::GetMaxNumberOfPointsPerPatch()
637 {
638   /* Deprecated since MeshGems 2.10
639   return ToInt( GetOptionValue("max_number_of_points_per_patch", GET_DEFAULT()));
640   */
641   return 0;
642 }
643 //=============================================================================
644
645 void BLSURFPlugin_Hypothesis::SetMaxNumberOfThreads( int nb )
646   throw (std::invalid_argument)
647 {
648   if ( nb < 0 )
649     throw std::invalid_argument( SMESH_Comment("Invalid number of threads: ") << nb );
650
651   if ( GetMaxNumberOfThreads() != nb )
652   {
653     SetOptionValue("max_number_of_threads", SMESH_Comment( nb ));
654     NotifySubMeshesHypothesisModification();
655   }
656 }
657 //=============================================================================
658 int BLSURFPlugin_Hypothesis::GetMaxNumberOfThreads()
659 {
660   return ToInt( GetOptionValue("max_number_of_threads", GET_DEFAULT()));
661 }
662 //=============================================================================
663
664 void BLSURFPlugin_Hypothesis::SetRespectGeometry( bool toRespect )
665 {
666   if ( GetRespectGeometry() != toRespect )
667   {
668     SetOptionValue("respect_geometry", toRespect ? "yes" : "no" );
669     NotifySubMeshesHypothesisModification();
670   }
671 }
672 //=============================================================================
673 bool BLSURFPlugin_Hypothesis::GetRespectGeometry()
674 {
675   return ToBool( GetOptionValue( "respect_geometry", GET_DEFAULT()));
676 }
677 //=============================================================================
678
679 void BLSURFPlugin_Hypothesis::SetTinyEdgesAvoidSurfaceIntersections( bool toAvoidIntersection )
680 {
681   if ( GetTinyEdgesAvoidSurfaceIntersections() != toAvoidIntersection )
682   {
683     SetOptionValue("tiny_edge_avoid_surface_intersections", toAvoidIntersection ? "yes" : "no" );
684     NotifySubMeshesHypothesisModification();
685   }
686 }
687 //=============================================================================
688 bool BLSURFPlugin_Hypothesis::GetTinyEdgesAvoidSurfaceIntersections()
689 {
690   return ToBool( GetOptionValue("tiny_edge_avoid_surface_intersections", GET_DEFAULT()));
691 }
692 //=============================================================================
693
694 void BLSURFPlugin_Hypothesis::SetClosedGeometry( bool isClosed )
695 {
696   if ( GetClosedGeometry() != isClosed )
697   {
698     SetPreCADOptionValue("closed_geometry", isClosed ? "yes" : "no" );
699     NotifySubMeshesHypothesisModification();
700   }
701 }
702 //=============================================================================
703 bool BLSURFPlugin_Hypothesis::GetClosedGeometry()
704 {
705   return ToBool( GetPreCADOptionValue( "closed_geometry", GET_DEFAULT()));
706 }
707 //=============================================================================
708
709 void BLSURFPlugin_Hypothesis::SetDebug( bool isDebug )
710 {
711   if ( GetDebug() != isDebug )
712   {
713     SetPreCADOptionValue("debug", isDebug ? "yes" : "no" );
714     NotifySubMeshesHypothesisModification();
715   }
716 }
717 //=============================================================================
718 bool BLSURFPlugin_Hypothesis::GetDebug()
719 {
720   return ToBool( GetPreCADOptionValue("debug", GET_DEFAULT()));
721 }
722 //=============================================================================
723
724 void BLSURFPlugin_Hypothesis::SetPeriodicTolerance( CORBA::Double tol )
725   throw (std::invalid_argument)
726 {
727   if ( tol <= 0 )
728     throw std::invalid_argument( SMESH_Comment("Invalid tolerance: ") << tol );
729   if ( GetPeriodicTolerance() != tol )
730   {
731     SetPreCADOptionValue("periodic_tolerance", SMESH_Comment( tol ) );
732     NotifySubMeshesHypothesisModification();
733   }
734 }
735 //=============================================================================
736 double BLSURFPlugin_Hypothesis::GetPeriodicTolerance()
737 {
738   return ToDbl( GetPreCADOptionValue( "periodic_tolerance", GET_DEFAULT()));
739 }
740 //=============================================================================
741
742 void BLSURFPlugin_Hypothesis::SetRequiredEntities( const std::string& howToTreat )
743   throw (std::invalid_argument)
744 {
745   if ( howToTreat != "respect" && howToTreat != "ignore" && howToTreat != "clear"  )
746     throw std::invalid_argument
747       ( SMESH_Comment("required_entities must be in ['respect','ignore','clear'] "));
748
749   if ( GetRequiredEntities() != howToTreat )
750   {
751     SetPreCADOptionValue("required_entities", howToTreat );
752     NotifySubMeshesHypothesisModification();
753   }
754 }
755 //=============================================================================
756 std::string BLSURFPlugin_Hypothesis::GetRequiredEntities()
757 {
758   return GetPreCADOptionValue("required_entities", GET_DEFAULT());
759 }
760 //=============================================================================
761
762 void BLSURFPlugin_Hypothesis::SetSewingTolerance( CORBA::Double tol )
763   throw (std::invalid_argument)
764 {
765   if ( tol <= 0 )
766     throw std::invalid_argument( SMESH_Comment("Invalid tolerance: ") << tol );
767   if ( GetSewingTolerance() != tol )
768   {
769     SetPreCADOptionValue("sewing_tolerance", SMESH_Comment( tol ) );
770     NotifySubMeshesHypothesisModification();
771   }
772 }
773 //=============================================================================
774 CORBA::Double BLSURFPlugin_Hypothesis::GetSewingTolerance()
775 {
776   return ToDbl( GetPreCADOptionValue("sewing_tolerance", GET_DEFAULT()));
777 }
778 //=============================================================================
779
780 void BLSURFPlugin_Hypothesis::SetTags( const std::string& howToTreat )
781   throw (std::invalid_argument)
782 {
783   if ( howToTreat != "respect" && howToTreat != "ignore" && howToTreat != "clear"  )
784     throw std::invalid_argument
785       ( SMESH_Comment("'tags' must be in ['respect','ignore','clear'] "));
786
787   if ( GetTags() != howToTreat )
788   {
789     SetPreCADOptionValue("tags", howToTreat );
790     NotifySubMeshesHypothesisModification();
791   }
792 }
793 //=============================================================================
794 std::string BLSURFPlugin_Hypothesis::GetTags()
795 {
796   return GetPreCADOptionValue("tags", GET_DEFAULT());
797 }
798 //=============================================================================
799 void BLSURFPlugin_Hypothesis::SetHyperPatches(const THyperPatchList& hpl)
800 {
801   if ( hpl != _hyperPatchList )
802   {
803     // join patches sharing tags
804     _hyperPatchList.clear();
805     for ( size_t i = 0; i < hpl.size(); ++i )
806     {
807       const THyperPatchTags& tags = hpl[i];
808       if ( tags.size() < 2 ) continue;
809
810       std::set<int> iPatches;
811       if ( !_hyperPatchList.empty() )
812       {
813         THyperPatchTags::iterator t = tags.begin();
814         for ( ; t != tags.end(); ++t )
815         {
816           int iPatch = -1;
817           GetHyperPatchTag( *t, this, &iPatch );
818           if ( iPatch >= 0 )
819             iPatches.insert( iPatch );
820         }
821       }
822
823       if ( iPatches.empty() )
824       {
825         _hyperPatchList.push_back( tags );
826       }
827       else
828       {
829         std::set<int>::iterator iPatch = iPatches.begin();
830         THyperPatchTags&     mainPatch = _hyperPatchList[ *iPatch ];
831         mainPatch.insert( tags.begin(), tags.end() );
832
833         for ( ++iPatch; iPatch != iPatches.end(); ++iPatch )
834         {
835           mainPatch.insert( _hyperPatchList[ *iPatch ].begin(), _hyperPatchList[ *iPatch ].end() );
836           _hyperPatchList[ *iPatch ].clear();
837         }
838         if ( iPatches.size() > 1 )
839           for ( int j = _hyperPatchList.size()-1; j > 0; --j )
840             if ( _hyperPatchList[j].empty() )
841               _hyperPatchList.erase( _hyperPatchList.begin() + j );
842       }
843     }
844     NotifySubMeshesHypothesisModification();
845   }
846 }
847 //=============================================================================
848 /*!
849  * \brief Return a tag of a face taking into account the hyper-patches. Optionally
850  *        return an index of a patch including the face
851  */
852 //================================================================================
853
854 int BLSURFPlugin_Hypothesis::GetHyperPatchTag( const int                      faceTag,
855                                                const BLSURFPlugin_Hypothesis* hyp,
856                                                int*                           iPatch)
857 {
858   if ( hyp )
859   {
860     const THyperPatchList& hpl = hyp->_hyperPatchList;
861     for ( size_t i = 0; i < hpl.size(); ++i )
862       if ( hpl[i].count( faceTag ))
863       {
864         if ( iPatch ) *iPatch = i;
865         return *( hpl[i].begin() );
866       }
867   }
868   return faceTag;
869 }
870 //=============================================================================
871 void BLSURFPlugin_Hypothesis::SetPreCADMergeEdges(bool theVal)
872 {
873   if (theVal != ToBool( GetPreCADOptionValue("merge_edges", GET_DEFAULT()))) {
874     _preCADMergeEdges = theVal;
875     SetPreCADOptionValue("merge_edges", theVal ? "yes" : "no" );
876     NotifySubMeshesHypothesisModification();
877   }
878 }
879
880 //=============================================================================
881 void BLSURFPlugin_Hypothesis::SetPreCADRemoveDuplicateCADFaces(bool theVal)
882 {
883   if (theVal != ToBool( GetPreCADOptionValue("remove_duplicate_cad_faces", GET_DEFAULT()))) {
884     _preCADRemoveDuplicateCADFaces = theVal;
885     SetPreCADOptionValue("remove_duplicate_cad_faces", theVal ? "yes" : "no" );
886     NotifySubMeshesHypothesisModification();
887   }
888 }
889
890 //=============================================================================
891 void BLSURFPlugin_Hypothesis::SetPreCADProcess3DTopology(bool theVal)
892 {
893   if (theVal != ToBool( GetPreCADOptionValue("process_3d_topology", GET_DEFAULT()))) {
894     _preCADProcess3DTopology = theVal;
895     SetPreCADOptionValue("process_3d_topology", theVal ? "yes" : "no" );
896     NotifySubMeshesHypothesisModification();
897   }
898 }
899
900 //=============================================================================
901 void BLSURFPlugin_Hypothesis::SetPreCADDiscardInput(bool theVal)
902 {
903   if (theVal != ToBool( GetPreCADOptionValue("discard_input_topology", GET_DEFAULT()))) {
904     _preCADDiscardInput = theVal;
905     SetPreCADOptionValue("discard_input_topology", theVal ? "yes" : "no" );
906     NotifySubMeshesHypothesisModification();
907   }
908 }
909
910 //=============================================================================
911 // Return true if any PreCAD option is activated
912 bool BLSURFPlugin_Hypothesis::HasPreCADOptions(const BLSURFPlugin_Hypothesis* hyp)
913 {
914   if ( !hyp || hyp->_name == GetHypType(/*hasgeom=*/false))
915   {
916     return false;
917   }
918   bool orDefault, isOk;
919   return ( ToBool( hyp->GetPreCADOptionValue("closed_geometry"           , &orDefault )) ||
920            ToBool( hyp->GetPreCADOptionValue("discard_input_topology"    , &orDefault )) ||
921            ToBool( hyp->GetPreCADOptionValue("merge_edges"               , &orDefault )) ||
922            ToBool( hyp->GetPreCADOptionValue("remove_duplicate_cad_faces", &orDefault )) ||
923            ToBool( hyp->GetPreCADOptionValue("process_3d_topology"       , &orDefault )) ||
924            ToBool( hyp->GetPreCADOption     ("manifold_geometry")        , &isOk       ) ||
925            hyp->GetPreCADOptionValue("sewing_tolerance", &orDefault ) != "5e-4*D"        ||
926            !hyp->_preCadFacesPeriodicityVector.empty()                                   ||
927            !hyp->_preCadEdgesPeriodicityVector.empty()                                   ||
928            !hyp->_facesPeriodicityVector.empty()                                         ||
929            !hyp->_edgesPeriodicityVector.empty()                                         ||
930            !hyp->_verticesPeriodicityVector.empty()                                      ||
931            !hyp->GetHyperPatches().empty()                                               ||
932            hyp->GetTopology() != FromCAD );
933 }
934
935 //=============================================================================
936 // void BLSURFPlugin_Hypothesis::SetGMFFile(const std::string& theFileName, bool isBinary)
937 void BLSURFPlugin_Hypothesis::SetGMFFile(const std::string& theFileName)
938 {
939   _GMFFileName = theFileName;
940   //   _GMFFileMode = isBinary;
941   NotifySubMeshesHypothesisModification();
942 }
943
944 //=============================================================================
945 void BLSURFPlugin_Hypothesis::SetOptionValue(const std::string& optionName, const std::string& optionValue)
946   throw (std::invalid_argument) {
947
948   TOptionValues::iterator op_val = _option2value.find(optionName);
949   if (op_val == _option2value.end())
950   {
951     op_val = _preCADoption2value.find(optionName);
952     if (op_val == _preCADoption2value.end())
953     {
954       std::string msg = "Unknown MG-CADSurf option: '" + optionName + "'. Try SetAdvancedOption()";
955       throw std::invalid_argument(msg);
956     }
957   }
958   if (op_val->second != optionValue)
959   {
960     const char* ptr = optionValue.c_str();
961     // strip white spaces
962     while (ptr[0] == ' ')
963       ptr++;
964     int i = strlen(ptr);
965     while (i != 0 && ptr[i - 1] == ' ')
966       i--;
967     // check value type
968     bool typeOk = true;
969     std::string typeName;
970     if (i == 0) {
971       // empty string
972     } else if (_charOptions.count(optionName)) {
973       // do not check strings
974     } else if (_doubleOptions.count(optionName)) {
975       // check if value is double
976       ToDbl(ptr, &typeOk);
977       typeName = "real";
978     } else if (_boolOptions.count(optionName)) {
979       // check if value is bool
980       ToBool(ptr, &typeOk);
981       typeName = "bool";
982     } else {
983       // check if value is int
984       ToInt(ptr, &typeOk);
985       typeName = "integer";
986     }
987     if (!typeOk) {
988       std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
989       throw std::invalid_argument(msg);
990     }
991     std::string value( ptr, i );
992     if ( _defaultOptionValues[ optionName ] == value )
993       value.clear();
994
995     op_val->second = value;
996
997     NotifySubMeshesHypothesisModification();
998   }
999 }
1000
1001 //=============================================================================
1002 void BLSURFPlugin_Hypothesis::SetPreCADOptionValue(const std::string& optionName, const std::string& optionValue)
1003   throw (std::invalid_argument) {
1004
1005   TOptionValues::iterator op_val = _preCADoption2value.find(optionName);
1006   if (op_val == _preCADoption2value.end()) {
1007     op_val = _option2value.find(optionName);
1008     if (op_val == _option2value.end()) {
1009       std::string msg = "Unknown MG-PreCAD option: '" + optionName + "'. Try SetAdvancedOption()";
1010       throw std::invalid_argument(msg);
1011     }
1012   }
1013   if (op_val->second != optionValue)
1014   {
1015     const char* ptr = optionValue.c_str();
1016     // strip white spaces
1017     while (ptr[0] == ' ')
1018       ptr++;
1019     int i = strlen(ptr);
1020     while (i != 0 && ptr[i - 1] == ' ')
1021       i--;
1022     // check value type
1023     bool typeOk = true;
1024     std::string typeName;
1025     if (i == 0) {
1026       // empty string
1027     } else if (_preCADcharOptions.find(optionName) != _preCADcharOptions.end()) {
1028       // do not check strings
1029     } else if (_preCADdoubleOptions.find(optionName) != _preCADdoubleOptions.end()) {
1030       // check if value is double
1031       char * endPtr;
1032       strtod(ptr, &endPtr);
1033       typeOk = (ptr != endPtr);
1034       typeName = "real";
1035     } else if (_boolOptions.count(optionName)) {
1036       // check if value is bool
1037       ToBool(ptr, &typeOk);
1038       typeName = "bool";
1039     } else {
1040       // check if value is int
1041       char * endPtr;
1042       strtol(ptr, &endPtr, 10);
1043       typeOk = (ptr != endPtr);
1044       typeName = "integer";
1045     }
1046     if (!typeOk) {
1047       std::string msg = "PreCAD advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
1048       throw std::invalid_argument(msg);
1049     }
1050     std::string value( ptr, i );
1051     if ( _defaultOptionValues[ optionName ] == value )
1052       value.clear();
1053
1054     op_val->second = value;
1055
1056     NotifySubMeshesHypothesisModification();
1057   }
1058 }
1059
1060 //=============================================================================
1061 std::string BLSURFPlugin_Hypothesis::GetOptionValue(const std::string& optionName,
1062                                                     bool*              isDefault) const
1063   throw (std::invalid_argument)
1064 {
1065   TOptionValues::const_iterator op_val = _option2value.find(optionName);
1066   if (op_val == _option2value.end())
1067   {
1068     op_val = _preCADoption2value.find(optionName);
1069     if (op_val == _preCADoption2value.end())
1070     {
1071       op_val = _customOption2value.find(optionName);
1072       if (op_val == _customOption2value.end())
1073       {
1074         std::string msg = "Unknown MG-CADSurf option: <" + optionName + ">";
1075         throw std::invalid_argument(msg);
1076       }
1077     }
1078   }
1079   std::string val = op_val->second;
1080   if ( isDefault ) *isDefault = ( val.empty() );
1081
1082   if ( val.empty() && isDefault )
1083   {
1084     op_val = _defaultOptionValues.find( optionName );
1085     if (op_val != _defaultOptionValues.end())
1086       val = op_val->second;
1087   }
1088   return val;
1089 }
1090
1091 //=============================================================================
1092 std::string BLSURFPlugin_Hypothesis::GetPreCADOptionValue(const std::string& optionName,
1093                                                           bool*              isDefault) const
1094   throw (std::invalid_argument)
1095 {
1096   TOptionValues::const_iterator op_val = _preCADoption2value.find(optionName);
1097   if (op_val == _preCADoption2value.end())
1098   {
1099     op_val = _option2value.find(optionName);
1100     if (op_val == _option2value.end())
1101     {
1102       op_val = _customOption2value.find(optionName);
1103       if (op_val == _customOption2value.end())
1104       {
1105         std::string msg = "Unknown MG-CADSurf option: <" + optionName + ">";
1106         throw std::invalid_argument(msg);
1107       }
1108     }
1109   }
1110   std::string val = op_val->second;
1111   if ( isDefault ) *isDefault = ( val.empty() );
1112
1113   if ( val.empty() && isDefault )
1114   {
1115     op_val = _defaultOptionValues.find( optionName );
1116     if (op_val != _option2value.end())
1117       val = op_val->second;
1118   }
1119   return val;
1120 }
1121
1122 //=============================================================================
1123 void BLSURFPlugin_Hypothesis::ClearOption(const std::string& optionName)
1124 {
1125   TOptionValues::iterator op_val = _customOption2value.find(optionName);
1126   if (op_val != _customOption2value.end())
1127    _customOption2value.erase(op_val);
1128   else {
1129     op_val = _option2value.find(optionName);
1130     if (op_val != _option2value.end())
1131       op_val->second.clear();
1132     else {
1133       op_val = _preCADoption2value.find(optionName);
1134       if (op_val != _preCADoption2value.end())
1135         op_val->second.clear();
1136     }
1137   }
1138 }
1139
1140 //=============================================================================
1141 void BLSURFPlugin_Hypothesis::ClearPreCADOption(const std::string& optionName)
1142 {
1143   TOptionValues::iterator op_val = _preCADoption2value.find(optionName);
1144   if (op_val != _preCADoption2value.end())
1145     op_val->second.clear();
1146 }
1147
1148 //=============================================================================
1149 void BLSURFPlugin_Hypothesis::AddOption(const std::string& optionName, const std::string& optionValue)
1150 {
1151   bool modif = true;
1152   TOptionValues::iterator op_val = _option2value.find(optionName);
1153   if (op_val != _option2value.end())
1154   {
1155     if (op_val->second != optionValue)
1156       op_val->second = optionValue;
1157     else
1158       modif = false;
1159   }
1160   else
1161   {
1162     op_val = _preCADoption2value.find(optionName);
1163     if (op_val != _preCADoption2value.end())
1164     {
1165       if (op_val->second != optionValue)
1166         op_val->second = optionValue;
1167       else
1168         modif = false;
1169     }
1170     else if ( optionValue.empty() )
1171     {
1172       _customOption2value.erase( optionName );
1173     }
1174     else
1175     {
1176       op_val = _customOption2value.find(optionName);
1177       if (op_val == _customOption2value.end())
1178         _customOption2value[optionName] = optionValue;
1179       else if (op_val->second != optionValue)
1180         op_val->second = optionValue;
1181       else
1182         modif = false;
1183     }
1184   }
1185   if ( modif )
1186     NotifySubMeshesHypothesisModification();
1187 }
1188
1189 //=============================================================================
1190 void BLSURFPlugin_Hypothesis::AddPreCADOption(const std::string& optionName, const std::string& optionValue)
1191 {
1192   AddOption( optionName, optionValue );
1193 }
1194
1195 //=============================================================================
1196 std::string BLSURFPlugin_Hypothesis::GetOption(const std::string& optionName) const
1197 {
1198   TOptionValues::const_iterator op_val = _customOption2value.find(optionName);
1199   if (op_val != _customOption2value.end())
1200     return op_val->second;
1201   else
1202     return "";
1203 }
1204
1205 //=============================================================================
1206 std::string BLSURFPlugin_Hypothesis::GetPreCADOption(const std::string& optionName) const
1207 {
1208   TOptionValues::const_iterator op_val = _customOption2value.find(optionName);
1209   if (op_val != _customOption2value.end())
1210     return op_val->second;
1211   else
1212     return "";
1213 }
1214
1215 //=============================================================================
1216 BLSURFPlugin_Hypothesis::TOptionValues BLSURFPlugin_Hypothesis::GetOptionValues() const
1217 {
1218   TOptionValues vals;
1219   TOptionValues::const_iterator op_val = _option2value.begin();
1220   for ( ; op_val != _option2value.end(); ++op_val )
1221     vals.insert( make_pair( op_val->first, GetOptionValue( op_val->first, GET_DEFAULT() )));
1222
1223   return vals;
1224 }
1225
1226 //=============================================================================
1227 BLSURFPlugin_Hypothesis::TOptionValues BLSURFPlugin_Hypothesis::GetPreCADOptionValues() const
1228 {
1229   TOptionValues vals;
1230   TOptionValues::const_iterator op_val = _preCADoption2value.begin();
1231   for ( ; op_val != _preCADoption2value.end(); ++op_val )
1232     vals.insert( make_pair( op_val->first, GetPreCADOptionValue( op_val->first, GET_DEFAULT() )));
1233
1234   return vals;
1235 }
1236
1237 //=======================================================================
1238 //function : SetSizeMapEntry
1239 //=======================================================================
1240 void BLSURFPlugin_Hypothesis::SetSizeMapEntry(const std::string& entry, const std::string& sizeMap) {
1241   if (_sizeMap[entry].compare(sizeMap) != 0) {
1242     SetPhysicalMesh(PhysicalLocalSize);
1243     _sizeMap[entry] = sizeMap;
1244     NotifySubMeshesHypothesisModification();
1245   }
1246 }
1247
1248 //=======================================================================
1249 //function : GetSizeMapEntry
1250 //=======================================================================
1251 std::string BLSURFPlugin_Hypothesis::GetSizeMapEntry(const std::string& entry) {
1252   TSizeMap::iterator it = _sizeMap.find(entry);
1253   if (it != _sizeMap.end())
1254     return it->second;
1255   else
1256     return "No_Such_Entry";
1257 }
1258
1259 /*!
1260  * \brief Return the size maps
1261  */
1262 BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetSizeMapEntries(const BLSURFPlugin_Hypothesis* hyp) {
1263   return hyp ? hyp->_GetSizeMapEntries() : GetDefaultSizeMap();
1264 }
1265
1266 //=======================================================================
1267 //function : SetAttractorEntry
1268 //=======================================================================
1269 void BLSURFPlugin_Hypothesis::SetAttractorEntry(const std::string& entry, const std::string& attractor) {
1270   if (_attractors[entry].compare(attractor) != 0) {
1271     SetPhysicalMesh(PhysicalLocalSize);
1272     _attractors[entry] = attractor;
1273     NotifySubMeshesHypothesisModification();
1274   }
1275 }
1276
1277 //=======================================================================
1278 //function : GetAttractorEntry
1279 //=======================================================================
1280 std::string BLSURFPlugin_Hypothesis::GetAttractorEntry(const std::string& entry) {
1281   TSizeMap::iterator it = _attractors.find(entry);
1282   if (it != _attractors.end())
1283     return it->second;
1284   else
1285     return "No_Such_Entry";
1286 }
1287
1288 /*!
1289  * \brief Return the attractors
1290  */
1291 BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetAttractorEntries(const BLSURFPlugin_Hypothesis* hyp) {
1292   return hyp ? hyp->_GetAttractorEntries() : GetDefaultSizeMap();
1293 }
1294
1295 //=======================================================================
1296 //function : SetClassAttractorEntry
1297 //=======================================================================
1298 void BLSURFPlugin_Hypothesis::SetClassAttractorEntry(const std::string& entry, const std::string& attEntry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius)
1299 {
1300   SetPhysicalMesh(PhysicalLocalSize);
1301
1302   // The new attractor can't be defined on the same face as another sizemap
1303   TSizeMap::iterator it  = _sizeMap.find( entry );
1304   if ( it != _sizeMap.end() ) {
1305     _sizeMap.erase(it);
1306     NotifySubMeshesHypothesisModification();
1307   }
1308   else {
1309     TSizeMap::iterator itAt  = _attractors.find( entry );
1310     if ( itAt != _attractors.end() ) {
1311       _attractors.erase(itAt);
1312       NotifySubMeshesHypothesisModification();
1313     }
1314   }
1315   
1316   const TopoDS_Shape AttractorShape = BLSURFPlugin_Hypothesis::entryToShape(attEntry);
1317   const TopoDS_Face FaceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(entry));
1318   TAttractorMap::iterator attIt = _classAttractors.find(entry);
1319   for ( ; attIt != _classAttractors.end(); ++attIt )
1320     if ( attIt->first == entry && 
1321          attIt->second->GetAttractorEntry() == attEntry )
1322       break;
1323   bool attExists = (attIt != _classAttractors.end());
1324
1325   BLSURFPlugin_Attractor* myAttractor;
1326   if ( !attExists ) {
1327     myAttractor = new BLSURFPlugin_Attractor(FaceShape, AttractorShape, attEntry);//, 0.1 );
1328     _classAttractors.insert( make_pair( entry, myAttractor ));
1329   }
1330   else {
1331     myAttractor = attIt->second;
1332   }
1333   // if (!myAttractor->IsMapBuilt())
1334   //   myAttractor->BuildMap();
1335   myAttractor->SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius);
1336
1337   NotifySubMeshesHypothesisModification();
1338 }
1339
1340 //=======================================================================
1341 //function : SetConstantSizeOnAdjacentFaces
1342 //=======================================================================
1343 // TODO uncomment and test (include the needed .hxx)
1344 // SetConstantSizeOnAdjacentFaces(myShape, att_entry, startSize, endSize = user_size, const_dist  ) {
1345 //   TopTools_IndexedMapOfShapListOdShape anEdge2FaceMap;
1346 //   TopExp::MapShapesAnAncestors(myShape,TopAbs_EDGE, TopAbs_FACE, anEdge2FaceMap);
1347 //   TopTools_IndexedMapOfShapListOdShape::iterator it;
1348 //   for (it = anEdge2FaceMap.begin();it != anEdge2FaceMap.end();it++){
1349 //       SetClassAttractorEntry((*it).first, att_entry, startSize, endSize, 0, const_dist)
1350 //   }
1351
1352
1353
1354
1355
1356
1357 //=======================================================================
1358 //function : GetClassAttractorEntry
1359 //=======================================================================
1360 // BLSURFPlugin_Attractor&  BLSURFPlugin_Hypothesis::GetClassAttractorEntry(const std::string& entry)
1361 // {
1362 //  TAttractorMap::iterator it  = _classAttractors.find( entry );
1363 //  if ( it != _classAttractors.end() )
1364 //    return it->second;
1365 //  else
1366 //    return "No_Such_Entry";
1367 // }
1368 // 
1369   /*!
1370    * \brief Return the map of attractor instances
1371    */
1372 BLSURFPlugin_Hypothesis::TAttractorMap BLSURFPlugin_Hypothesis::GetClassAttractorEntries(const BLSURFPlugin_Hypothesis* hyp)
1373 {
1374     return hyp ? hyp->_GetClassAttractorEntries():GetDefaultAttractorMap();
1375 }
1376
1377 //=======================================================================
1378 //function : ClearEntry
1379 //=======================================================================
1380 void BLSURFPlugin_Hypothesis::ClearEntry(const std::string& entry,
1381                                          const char * attEntry/*=0*/)
1382 {
1383  TSizeMap::iterator it  = _sizeMap.find( entry );
1384  
1385  if ( it != _sizeMap.end() ) {
1386    _sizeMap.erase(it);
1387    NotifySubMeshesHypothesisModification();
1388  }
1389  else {
1390    TSizeMap::iterator itAt  = _attractors.find( entry );
1391    if ( itAt != _attractors.end() ) {
1392      _attractors.erase(itAt);
1393      NotifySubMeshesHypothesisModification();
1394    }
1395    else {
1396      TAttractorMap::iterator it_clAt = _classAttractors.find( entry );
1397      if ( it_clAt != _classAttractors.end() ) {
1398        do {
1399          if ( !attEntry || it_clAt->second->GetAttractorEntry() == attEntry )
1400            _classAttractors.erase( it_clAt++ );
1401          else
1402            ++it_clAt;
1403        }
1404        while ( it_clAt != _classAttractors.end() );
1405        NotifySubMeshesHypothesisModification();
1406      }
1407      else
1408        std::cout<<"No_Such_Entry"<<std::endl;
1409    }
1410  }
1411 }
1412
1413 //=======================================================================
1414 //function : ClearSizeMaps
1415 //=======================================================================
1416 void BLSURFPlugin_Hypothesis::ClearSizeMaps() {
1417   _sizeMap.clear();
1418   _attractors.clear();
1419   _classAttractors.clear();
1420 }
1421
1422 // Enable internal enforced vertices on specific face if requested by user
1423
1424 ////=======================================================================
1425 ////function : SetInternalEnforcedVertex
1426 ////=======================================================================
1427 //void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertex(TEntry theFaceEntry,
1428 //                                                        bool toEnforceInternalVertices,
1429 //                                                        TEnfGroupName theGroupName) {
1430
1431 //      << toEnforceInternalVertices << ", " << theGroupName << ")");
1432   
1433 //  TFaceEntryInternalVerticesList::iterator it = _faceEntryInternalVerticesList.find(theFaceEntry);
1434 //  if (it != _faceEntryInternalVerticesList.end()) {
1435 //    if (!toEnforceInternalVertices) {
1436 //      _faceEntryInternalVerticesList.erase(it);
1437 //    }
1438 //  }
1439 //  else {
1440 //    if (toEnforceInternalVertices) {
1441 //      _faceEntryInternalVerticesList.insert(theFaceEntry);
1442 //    }
1443 //  }
1444   
1445 //  // TODO
1446 //  // Take care of groups
1447 //}
1448
1449
1450 //=======================================================================
1451 //function : SetEnforcedVertex
1452 //=======================================================================
1453 bool BLSURFPlugin_Hypothesis::SetEnforcedVertex(TEntry        theFaceEntry,
1454                                                 TEnfName      theVertexName,
1455                                                 TEntry        theVertexEntry,
1456                                                 TEnfGroupName theGroupName,
1457                                                 double x, double y, double z)
1458 {
1459   SetPhysicalMesh(PhysicalLocalSize);
1460
1461   bool toNotify = false;
1462   bool toCreate = true;
1463
1464   TEnfVertex *oldEnVertex;
1465   TEnfVertex *newEnfVertex = new TEnfVertex();
1466   newEnfVertex->name = theVertexName;
1467   newEnfVertex->geomEntry = theVertexEntry;
1468   newEnfVertex->coords.clear();
1469   if (theVertexEntry == "") {
1470     newEnfVertex->coords.push_back(x);
1471     newEnfVertex->coords.push_back(y);
1472     newEnfVertex->coords.push_back(z);
1473   }
1474   newEnfVertex->grpName = theGroupName;
1475   newEnfVertex->faceEntries.clear();
1476   newEnfVertex->faceEntries.insert(theFaceEntry);
1477
1478
1479   // update _enfVertexList
1480   TEnfVertexList::iterator it = _enfVertexList.find(newEnfVertex);
1481   if (it != _enfVertexList.end()) {
1482     toCreate = false;
1483     oldEnVertex = (*it);
1484     if (oldEnVertex->name != theVertexName) {
1485       oldEnVertex->name = theVertexName;
1486       toNotify = true;
1487     }
1488     if (oldEnVertex->grpName != theGroupName) {
1489       oldEnVertex->grpName = theGroupName;
1490       toNotify = true;
1491     }
1492     TEntryList::iterator it_faceEntries = oldEnVertex->faceEntries.find(theFaceEntry);
1493     if (it_faceEntries == oldEnVertex->faceEntries.end()) {
1494       oldEnVertex->faceEntries.insert(theFaceEntry);
1495       _faceEntryEnfVertexListMap[theFaceEntry].insert(oldEnVertex);
1496       toNotify = true;
1497     }
1498     if (toNotify) {
1499       // update map coords / enf vertex if needed
1500       if (oldEnVertex->coords.size()) {
1501         _coordsEnfVertexMap[oldEnVertex->coords] = oldEnVertex;
1502         _faceEntryCoordsListMap[theFaceEntry].insert(oldEnVertex->coords);
1503       }
1504
1505       // update map geom entry / enf vertex if needed
1506       if (oldEnVertex->geomEntry != "") {
1507         _enfVertexEntryEnfVertexMap[oldEnVertex->geomEntry] = oldEnVertex;
1508         _faceEntryEnfVertexEntryListMap[theFaceEntry].insert(oldEnVertex->geomEntry);
1509       }
1510     }
1511   }
1512
1513 //   //////// CREATE ////////////
1514   if (toCreate) {
1515     toNotify = true;
1516     AddEnforcedVertex( theFaceEntry, newEnfVertex );
1517   }
1518   else {
1519     delete newEnfVertex;
1520   }
1521
1522   if (toNotify)
1523     NotifySubMeshesHypothesisModification();
1524
1525   return toNotify;
1526 }
1527
1528 //=======================================================================
1529 //function : AddEnforcedVertex
1530 //=======================================================================
1531
1532 void BLSURFPlugin_Hypothesis::AddEnforcedVertex( const TEntry& faceEntry,
1533                                                  TEnfVertex *  newEnfVertex )
1534 {
1535   if ( newEnfVertex )
1536   {
1537     _faceEntryEnfVertexListMap[faceEntry].insert(newEnfVertex);
1538     _enfVertexList.insert(newEnfVertex);
1539     if ( newEnfVertex->geomEntry.empty() ) {
1540       _faceEntryCoordsListMap[faceEntry].insert(newEnfVertex->coords);
1541       _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex;
1542     }
1543     else {
1544       _faceEntryEnfVertexEntryListMap[faceEntry].insert(newEnfVertex->geomEntry);
1545       _enfVertexEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex;
1546     }
1547   }
1548 }
1549
1550 //=======================================================================
1551 //function : GetEnforcedVertices
1552 //=======================================================================
1553
1554 BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetEnfVertexList(const TEntry& theFaceEntry)
1555     throw (std::invalid_argument) {
1556
1557   if (_faceEntryEnfVertexListMap.count(theFaceEntry) > 0)
1558     return _faceEntryEnfVertexListMap[theFaceEntry];
1559   else
1560     return GetDefaultEnfVertexList();
1561
1562   std::ostringstream msg;
1563   msg << "No enforced vertex for face entry " << theFaceEntry;
1564   throw std::invalid_argument(msg.str());
1565 }
1566
1567 //=======================================================================
1568 //function : GetEnfVertexCoordsList
1569 //=======================================================================
1570
1571 BLSURFPlugin_Hypothesis::TEnfVertexCoordsList BLSURFPlugin_Hypothesis::GetEnfVertexCoordsList(
1572     const TEntry& theFaceEntry) throw (std::invalid_argument) {
1573
1574   if (_faceEntryCoordsListMap.count(theFaceEntry) > 0)
1575     return _faceEntryCoordsListMap[theFaceEntry];
1576
1577   std::ostringstream msg;
1578   msg << "No enforced vertex coords for face entry " << theFaceEntry;
1579   throw std::invalid_argument(msg.str());
1580 }
1581
1582 //=======================================================================
1583 //function : GetEnfVertexEntryList
1584 //=======================================================================
1585
1586 BLSURFPlugin_Hypothesis::TEntryList BLSURFPlugin_Hypothesis::GetEnfVertexEntryList(const TEntry& theFaceEntry)
1587     throw (std::invalid_argument) {
1588
1589   if (_faceEntryEnfVertexEntryListMap.count(theFaceEntry) > 0)
1590     return _faceEntryEnfVertexEntryListMap[theFaceEntry];
1591
1592   std::ostringstream msg;
1593   msg << "No enforced vertex entry for face entry " << theFaceEntry;
1594   throw std::invalid_argument(msg.str());
1595 }
1596
1597 //=======================================================================
1598 //function : GetEnfVertex(TEnfVertexCoords coords)
1599 //=======================================================================
1600
1601 BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(TEnfVertexCoords coords)
1602     throw (std::invalid_argument) {
1603
1604   if (_coordsEnfVertexMap.count(coords) > 0)
1605     return _coordsEnfVertexMap[coords];
1606
1607   std::ostringstream msg;
1608   msg << "No enforced vertex with coords (" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")";
1609   throw std::invalid_argument(msg.str());
1610 }
1611
1612 //=======================================================================
1613 //function : GetEnfVertex(const TEntry& theEnfVertexEntry)
1614 //=======================================================================
1615
1616 BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(const TEntry& theEnfVertexEntry)
1617     throw (std::invalid_argument) {
1618
1619   if (_enfVertexEntryEnfVertexMap.count(theEnfVertexEntry) > 0)
1620     return _enfVertexEntryEnfVertexMap[theEnfVertexEntry];
1621
1622   std::ostringstream msg;
1623   msg << "No enforced vertex with entry " << theEnfVertexEntry;
1624   throw std::invalid_argument(msg.str());
1625 }
1626
1627 //Enable internal enforced vertices on specific face if requested by user
1628 ////=======================================================================
1629 ////function : GetInternalEnforcedVertex
1630 ////=======================================================================
1631
1632 //bool BLSURFPlugin_Hypothesis::GetInternalEnforcedVertex(const TEntry& theFaceEntry)
1633 //{
1634 //  if (_faceEntryInternalVerticesList.count(theFaceEntry) > 0)
1635 //    return true;
1636 //  return false;
1637 //}
1638
1639 //=======================================================================
1640 //function : ClearEnforcedVertex
1641 //=======================================================================
1642
1643 bool BLSURFPlugin_Hypothesis::ClearEnforcedVertex(const TEntry& theFaceEntry, double x, double y, double z,
1644     const TEntry& theVertexEntry) throw (std::invalid_argument) {
1645
1646   bool toNotify = false;
1647   std::ostringstream msg;
1648   TEnfVertex *oldEnfVertex;
1649   TEnfVertexCoords coords;
1650   coords.clear();
1651   coords.push_back(x);
1652   coords.push_back(y);
1653   coords.push_back(z);
1654
1655   // check that enf vertex with given enf vertex entry exists
1656   TEnfVertexEntryEnfVertexMap::iterator it_enfVertexEntry = _enfVertexEntryEnfVertexMap.find(theVertexEntry);
1657   if (it_enfVertexEntry != _enfVertexEntryEnfVertexMap.end()) {
1658     // Success
1659     oldEnfVertex = it_enfVertexEntry->second;
1660
1661     _enfVertexEntryEnfVertexMap.erase(it_enfVertexEntry);
1662
1663     TEntryList& enfVertexEntryList = _faceEntryEnfVertexEntryListMap[theFaceEntry];
1664     enfVertexEntryList.erase(theVertexEntry);
1665     if (enfVertexEntryList.size() == 0)
1666       _faceEntryEnfVertexEntryListMap.erase(theFaceEntry);
1667     //    TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry);
1668     //    TEntryList::iterator it_entryList = it_entry_entry->second.find(theVertexEntry);
1669     //    it_entry_entry->second.erase(it_entryList);
1670     //    if (it_entry_entry->second.size() == 0)
1671     //      _faceEntryEnfVertexEntryListMap.erase(it_entry_entry);
1672   } else {
1673     // Fail
1674     MESSAGE("Enforced vertex with geom entry " << theVertexEntry << " not found");
1675     msg << "No enforced vertex with geom entry " << theVertexEntry;
1676     // check that enf vertex with given coords exists
1677     TCoordsEnfVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
1678     if (it_coords_enf != _coordsEnfVertexMap.end()) {
1679       // Success
1680       oldEnfVertex = it_coords_enf->second;
1681
1682       _coordsEnfVertexMap.erase(it_coords_enf);
1683
1684       TEnfVertexCoordsList& enfVertexCoordsList = _faceEntryCoordsListMap[theFaceEntry];
1685       enfVertexCoordsList.erase(coords);
1686       if (enfVertexCoordsList.size() == 0)
1687         _faceEntryCoordsListMap.erase(theFaceEntry);
1688       //      TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry);
1689       //      TEnfVertexCoordsList::iterator it_coordsList = it_entry_coords->second.find(coords);
1690       //      it_entry_coords->second.erase(it_coordsList);
1691       //      if (it_entry_coords->second.size() == 0)
1692       //        _faceEntryCoordsListMap.erase(it_entry_coords);
1693     } else {
1694       // Fail
1695       MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found");
1696       msg << std::endl;
1697       msg << "No enforced vertex at " << x << ", " << y << ", " << z;
1698       throw std::invalid_argument(msg.str());
1699     }
1700   }
1701
1702   // update _enfVertexList
1703   TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1704   if (it != _enfVertexList.end()) {
1705     (*it)->faceEntries.erase(theFaceEntry);
1706     if ((*it)->faceEntries.size() == 0){
1707       _enfVertexList.erase(it);
1708       toNotify = true;
1709     }
1710   }
1711
1712   // update _faceEntryEnfVertexListMap
1713   TEnfVertexList& currentEnfVertexList = _faceEntryEnfVertexListMap[theFaceEntry];
1714   currentEnfVertexList.erase(oldEnfVertex);
1715
1716   if (currentEnfVertexList.size() == 0) {
1717     _faceEntryEnfVertexListMap.erase(theFaceEntry);
1718   }
1719
1720   if (toNotify)
1721     NotifySubMeshesHypothesisModification();
1722
1723   return toNotify;
1724 }
1725
1726 //=======================================================================
1727 //function : ClearEnforcedVertices
1728 //=======================================================================
1729
1730 bool BLSURFPlugin_Hypothesis::ClearEnforcedVertices(const TEntry& theFaceEntry) throw (std::invalid_argument) {
1731
1732   bool toNotify = false;
1733   TEnfVertex *oldEnfVertex;
1734
1735   TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry);
1736   if (it_entry_coords != _faceEntryCoordsListMap.end()) {
1737     toNotify = true;
1738     TEnfVertexCoordsList coordsList = it_entry_coords->second;
1739     TEnfVertexCoordsList::iterator it_coordsList = coordsList.begin();
1740     for (; it_coordsList != coordsList.end(); ++it_coordsList) {
1741       TEnfVertexCoords coords = (*it_coordsList);
1742       oldEnfVertex = _coordsEnfVertexMap[coords];
1743       _coordsEnfVertexMap.erase(coords);
1744       // update _enfVertexList
1745       TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1746       if (it != _enfVertexList.end()) {
1747         (*it)->faceEntries.erase(theFaceEntry);
1748         if ((*it)->faceEntries.size() == 0){
1749           _enfVertexList.erase(it);
1750           toNotify = true;
1751         }
1752       }
1753     }
1754     _faceEntryCoordsListMap.erase(it_entry_coords);
1755     _faceEntryEnfVertexListMap.erase(theFaceEntry);
1756   }
1757
1758   TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry);
1759   if (it_entry_entry != _faceEntryEnfVertexEntryListMap.end()) {
1760     toNotify = true;
1761     TEntryList enfVertexEntryList = it_entry_entry->second;
1762     TEntryList::iterator it_enfVertexEntryList = enfVertexEntryList.begin();
1763     for (; it_enfVertexEntryList != enfVertexEntryList.end(); ++it_enfVertexEntryList) {
1764       TEntry enfVertexEntry = (*it_enfVertexEntryList);
1765       oldEnfVertex = _enfVertexEntryEnfVertexMap[enfVertexEntry];
1766       _enfVertexEntryEnfVertexMap.erase(enfVertexEntry);
1767       // update _enfVertexList
1768       TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1769       if (it != _enfVertexList.end()) {
1770         (*it)->faceEntries.erase(theFaceEntry);
1771         if ((*it)->faceEntries.size() == 0){
1772           _enfVertexList.erase(it);
1773           toNotify = true;
1774         }
1775       }
1776     }
1777     _faceEntryEnfVertexEntryListMap.erase(it_entry_entry);
1778     _faceEntryEnfVertexListMap.erase(theFaceEntry);
1779   }
1780
1781   if (toNotify)
1782     NotifySubMeshesHypothesisModification();
1783
1784   return toNotify;
1785   //  std::ostringstream msg;
1786   //  msg << "No enforced vertex for " << theFaceEntry;
1787   //  throw std::invalid_argument(msg.str());
1788 }
1789
1790 //=======================================================================
1791 //function : ClearAllEnforcedVertices
1792 //=======================================================================
1793 void BLSURFPlugin_Hypothesis::ClearAllEnforcedVertices()
1794 {
1795   _faceEntryEnfVertexListMap.clear();
1796   _faceEntryCoordsListMap.clear();
1797   _coordsEnfVertexMap.clear();
1798   _faceEntryEnfVertexEntryListMap.clear();
1799   _enfVertexEntryEnfVertexMap.clear();
1800   
1801   TEnfVertexList::iterator it_enfVertex = _enfVertexList.begin();
1802   for ( ; it_enfVertex != _enfVertexList.end(); ++it_enfVertex )
1803     delete *it_enfVertex;
1804   _enfVertexList.clear();
1805
1806 //  Enable internal enforced vertices on specific face if requested by user
1807 //  _faceEntryInternalVerticesList.clear();
1808   NotifySubMeshesHypothesisModification();
1809 }
1810
1811
1812 //================================================================================
1813 /*!
1814  * \brief Return the enforced vertices
1815  */
1816 //================================================================================
1817
1818
1819 BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByFace(
1820     const BLSURFPlugin_Hypothesis* hyp) {
1821   return hyp ? hyp->_GetAllEnforcedVerticesByFace() : GetDefaultFaceEntryEnfVertexListMap();
1822 }
1823
1824 //Enable internal enforced vertices on specific face if requested by user
1825 //BLSURFPlugin_Hypothesis::TFaceEntryInternalVerticesList BLSURFPlugin_Hypothesis::GetAllInternalEnforcedVerticesByFace(
1826 //    const BLSURFPlugin_Hypothesis* hyp) {
1827 //  return hyp ? hyp->_GetAllInternalEnforcedVerticesByFace() : GetDefaultFaceEntryInternalVerticesMap();
1828 //}
1829
1830 bool BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFaces(const BLSURFPlugin_Hypothesis* hyp)
1831 {
1832   return hyp ? hyp->_GetInternalEnforcedVertexAllFaces() : GetDefaultInternalEnforcedVertex();
1833 }
1834
1835 BLSURFPlugin_Hypothesis::TEnfGroupName BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFacesGroup(const BLSURFPlugin_Hypothesis* hyp)
1836 {
1837   return hyp ? hyp->_GetInternalEnforcedVertexAllFacesGroup() : BLSURFPlugin_Hypothesis::TEnfGroupName();
1838 }
1839
1840 BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetAllEnforcedVertices(
1841     const BLSURFPlugin_Hypothesis* hyp) {
1842   return hyp ? hyp->_GetAllEnforcedVertices() : GetDefaultEnfVertexList();
1843 }
1844
1845 BLSURFPlugin_Hypothesis::TFaceEntryCoordsListMap BLSURFPlugin_Hypothesis::GetAllCoordsByFace(
1846     const BLSURFPlugin_Hypothesis* hyp) {
1847   return hyp ? hyp->_GetAllCoordsByFace() : GetDefaultFaceEntryCoordsListMap();
1848 }
1849
1850 BLSURFPlugin_Hypothesis::TCoordsEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByCoords(
1851     const BLSURFPlugin_Hypothesis* hyp) {
1852   return hyp ? hyp->_GetAllEnforcedVerticesByCoords() : GetDefaultCoordsEnfVertexMap();
1853 }
1854
1855 BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexEntryListMap BLSURFPlugin_Hypothesis::GetAllEnfVertexEntriesByFace(
1856     const BLSURFPlugin_Hypothesis* hyp) {
1857   return hyp ? hyp->_GetAllEnfVertexEntriesByFace() : GetDefaultFaceEntryEnfVertexEntryListMap();
1858 }
1859
1860 BLSURFPlugin_Hypothesis::TEnfVertexEntryEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByEnfVertexEntry(
1861     const BLSURFPlugin_Hypothesis* hyp) {
1862   return hyp ? hyp->_GetAllEnforcedVerticesByEnfVertexEntry() : GetDefaultEnfVertexEntryEnfVertexMap();
1863 }
1864
1865 std::set<int> BLSURFPlugin_Hypothesis::GetEnfVertexNodeIDs(TEnfGroupName theGroupName) throw (std::invalid_argument)
1866 {
1867   TGroupNameNodeIDMap::const_iterator it = _groupNameNodeIDMap.find(theGroupName);
1868   if (it != _groupNameNodeIDMap.end()) {
1869     return it->second;
1870   }
1871   std::ostringstream msg;
1872   msg << "No group " << theGroupName;
1873   throw std::invalid_argument(msg.str());
1874 }
1875
1876 void BLSURFPlugin_Hypothesis::AddEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID)
1877 {
1878   _groupNameNodeIDMap[theGroupName].insert(theNodeID);
1879 }
1880
1881 void BLSURFPlugin_Hypothesis::RemoveEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID) throw (std::invalid_argument)
1882 {
1883   TGroupNameNodeIDMap::iterator it = _groupNameNodeIDMap.find(theGroupName);
1884   if (it != _groupNameNodeIDMap.end()) {
1885     std::set<int>::iterator IDit = it->second.find(theNodeID);
1886     if (IDit != it->second.end())
1887       it->second.erase(IDit);
1888     std::ostringstream msg;
1889     msg << "No node IDs " << theNodeID << " for group " << theGroupName;
1890     throw std::invalid_argument(msg.str());
1891   }
1892   std::ostringstream msg;
1893   msg << "No group " << theGroupName;
1894   throw std::invalid_argument(msg.str());
1895 }
1896
1897
1898 //=============================================================================
1899 void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertexAllFaces(bool toEnforceInternalVertices) {
1900   if (toEnforceInternalVertices != _enforcedInternalVerticesAllFaces) {
1901     _enforcedInternalVerticesAllFaces = toEnforceInternalVertices;
1902     if (toEnforceInternalVertices)
1903       SetPhysicalMesh(PhysicalLocalSize);
1904     NotifySubMeshesHypothesisModification();
1905   }
1906 }
1907
1908
1909 //=============================================================================
1910 void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertexAllFacesGroup(BLSURFPlugin_Hypothesis::TEnfGroupName theGroupName) {
1911   if (std::string(theGroupName) != std::string(_enforcedInternalVerticesAllFacesGroup)) {
1912     _enforcedInternalVerticesAllFacesGroup = theGroupName;
1913     NotifySubMeshesHypothesisModification();
1914   }
1915 }
1916
1917 //=============================================================================
1918 BLSURFPlugin_Hypothesis::TPreCadPeriodicityVector BLSURFPlugin_Hypothesis::GetPreCadFacesPeriodicityVector(
1919     const BLSURFPlugin_Hypothesis* hyp) {
1920   return hyp ? hyp->_GetPreCadFacesPeriodicityVector() : GetDefaultPreCadFacesPeriodicityVector();
1921 }
1922
1923 //=============================================================================
1924 BLSURFPlugin_Hypothesis::TPreCadPeriodicityVector BLSURFPlugin_Hypothesis::GetPreCadEdgesPeriodicityVector(
1925     const BLSURFPlugin_Hypothesis* hyp) {
1926   return hyp ? hyp->_GetPreCadEdgesPeriodicityVector() : GetDefaultPreCadEdgesPeriodicityVector();
1927 }
1928
1929 //=============================================================================
1930 BLSURFPlugin_Hypothesis::TFacesPeriodicityVector BLSURFPlugin_Hypothesis::GetFacesPeriodicityVector(
1931     const BLSURFPlugin_Hypothesis* hyp) {
1932   return hyp ? hyp->_GetFacesPeriodicityVector() : GetDefaultFacesPeriodicityVector();
1933 }
1934
1935 //=============================================================================
1936 BLSURFPlugin_Hypothesis::TEdgesPeriodicityVector BLSURFPlugin_Hypothesis::GetEdgesPeriodicityVector(
1937     const BLSURFPlugin_Hypothesis* hyp){
1938   return hyp ? hyp->_GetEdgesPeriodicityVector() : GetDefaultEdgesPeriodicityVector();
1939 }
1940
1941 //=============================================================================
1942 BLSURFPlugin_Hypothesis::TVerticesPeriodicityVector BLSURFPlugin_Hypothesis::GetVerticesPeriodicityVector(
1943     const BLSURFPlugin_Hypothesis* hyp){
1944   return hyp ? hyp->_GetVerticesPeriodicityVector() : GetDefaultVerticesPeriodicityVector();
1945 }
1946
1947 //=======================================================================
1948 //function : ClearAllEnforcedVertices
1949 //=======================================================================
1950 void BLSURFPlugin_Hypothesis::ClearPreCadPeriodicityVectors() {
1951   _preCadFacesPeriodicityVector.clear();
1952   _preCadEdgesPeriodicityVector.clear();
1953   NotifySubMeshesHypothesisModification();
1954 }
1955
1956 //=======================================================================
1957 //function : AddPreCadFacesPeriodicity
1958 //=======================================================================
1959 void BLSURFPlugin_Hypothesis::AddPreCadFacesPeriodicity(TEntry theFace1Entry, TEntry theFace2Entry,
1960                                                         std::vector<std::string> &theSourceVerticesEntries, std::vector<std::string> &theTargetVerticesEntries) {
1961
1962   TPreCadPeriodicity preCadFacesPeriodicity;
1963   preCadFacesPeriodicity.shape1Entry = theFace1Entry;
1964   preCadFacesPeriodicity.shape2Entry = theFace2Entry;
1965   preCadFacesPeriodicity.theSourceVerticesEntries = theSourceVerticesEntries;
1966   preCadFacesPeriodicity.theTargetVerticesEntries = theTargetVerticesEntries;
1967
1968   _preCadFacesPeriodicityVector.push_back(preCadFacesPeriodicity);
1969
1970   NotifySubMeshesHypothesisModification();
1971 }
1972
1973 //=======================================================================
1974 //function : AddPreCadEdgesPeriodicity
1975 //=======================================================================
1976 void BLSURFPlugin_Hypothesis::AddPreCadEdgesPeriodicity(TEntry theEdge1Entry, TEntry theEdge2Entry,
1977     std::vector<std::string> &theSourceVerticesEntries, std::vector<std::string> &theTargetVerticesEntries) {
1978
1979   TPreCadPeriodicity preCadEdgesPeriodicity;
1980   preCadEdgesPeriodicity.shape1Entry = theEdge1Entry;
1981   preCadEdgesPeriodicity.shape2Entry = theEdge2Entry;
1982   preCadEdgesPeriodicity.theSourceVerticesEntries = theSourceVerticesEntries;
1983   preCadEdgesPeriodicity.theTargetVerticesEntries = theTargetVerticesEntries;
1984
1985   _preCadEdgesPeriodicityVector.push_back(preCadEdgesPeriodicity);
1986
1987   NotifySubMeshesHypothesisModification();
1988 }
1989
1990 //=============================================================================
1991 std::ostream & BLSURFPlugin_Hypothesis::SaveTo(std::ostream & save)
1992 {
1993   // We must keep at least the same number of arguments when increasing the SALOME version
1994   // When MG-CADSurf becomes CADMESH, some parameters were fused into a single one. Thus the same
1995   // parameter can be written several times to keep the old global number of parameters.
1996
1997   // Treat old options which are now in the advanced options
1998   TOptionValues::iterator op_val;
1999   int _decimesh = -1;
2000   int _preCADRemoveNanoEdges = -1;
2001   double _preCADEpsNano = -1.0;
2002   op_val = _option2value.find("respect_geometry");
2003   if (op_val != _option2value.end()) {
2004     std::string value = op_val->second;
2005     if (!value.empty())
2006       _decimesh = value.compare("1") == 0 ? 1 : 0;
2007   }
2008   op_val = _preCADoption2value.find("remove_tiny_edges");
2009   if (op_val != _preCADoption2value.end()) {
2010     std::string value = op_val->second;
2011     if (!value.empty())
2012       _preCADRemoveNanoEdges = value.compare("1") == 0 ? 1 : 0;
2013   }
2014   op_val = _preCADoption2value.find("tiny_edge_length");
2015   if (op_val != _preCADoption2value.end()) {
2016     std::string value = op_val->second;
2017     if (!value.empty())
2018       _preCADEpsNano = strtod(value.c_str(), NULL);
2019   }
2020
2021   save << " " << (int) _topology << " " << (int) _physicalMesh << " " << (int) _geometricMesh << " " << _phySize << " "
2022        << _angleMesh << " " << _gradation << " " << (int) _elementType << " " << _decimesh;
2023   save << " " << _minSize << " " << _maxSize << " " << _angleMesh << " " << _minSize << " " << _maxSize << " " << _verb;
2024   save << " " << (int) _preCADMergeEdges << " " << _preCADRemoveNanoEdges << " " << (int) _preCADDiscardInput << " " << _preCADEpsNano ;
2025   save << " " << (int) _enforcedInternalVerticesAllFaces;
2026   save << " " << (int) _phySizeRel << " " << (int) _minSizeRel << " " << (int) _maxSizeRel << " " << _chordalError ;
2027   save << " " << (int) _anisotropic << " " << _anisotropicRatio << " " << (int) _removeTinyEdges << " " << _tinyEdgeLength ;
2028   save << " " << (int) _badElementRemoval << " " << _badElementAspectRatio << " " << (int) _optimizeMesh << " " << (int) _quadraticMesh ;
2029   save << " " << (int) _preCADProcess3DTopology << " " << (int) _preCADRemoveDuplicateCADFaces;
2030   save << " " << (int)_optimiseTinyEdges << " " << _tinyEdgeOptimisationLength;
2031   save << " " << (int)_correctSurfaceIntersec << " " << _corrSurfaceIntersCost;
2032   save << " " << (int)_useGradation << " " << (int)_useVolumeGradation << " " << _volumeGradation;
2033
2034   op_val = _option2value.begin();
2035   if (op_val != _option2value.end()) {
2036     save << " " << "__OPTIONS_BEGIN__";
2037     for (; op_val != _option2value.end(); ++op_val) {
2038       if (!op_val->second.empty())
2039         save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
2040     }
2041     save << " " << "__OPTIONS_END__";
2042   }
2043   
2044   op_val = _customOption2value.begin();
2045   if (op_val != _customOption2value.end()) {
2046     save << " " << "__CUSTOM_OPTIONS_BEGIN__";
2047     for (; op_val != _customOption2value.end(); ++op_val) {
2048       if (!op_val->second.empty())
2049         save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
2050     }
2051     save << " " << "__CUSTOM_OPTIONS_END__";
2052   }
2053
2054   op_val = _preCADoption2value.begin();
2055   if (op_val != _preCADoption2value.end()) {
2056     save << " " << "__PRECAD_OPTIONS_BEGIN__";
2057     for (; op_val != _preCADoption2value.end(); ++op_val) {
2058       if (!op_val->second.empty())
2059         save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
2060     }
2061     save << " " << "__PRECAD_OPTIONS_END__";
2062   }
2063
2064   TSizeMap::iterator it_sm = _sizeMap.begin();
2065   if (it_sm != _sizeMap.end()) {
2066     save << " " << "__SIZEMAP_BEGIN__";
2067     for (; it_sm != _sizeMap.end(); ++it_sm) {
2068       save << " " << it_sm->first << " " << it_sm->second << "%#"; // "%#" is a mark of value end
2069     }
2070     save << " " << "__SIZEMAP_END__";
2071   }
2072
2073   TSizeMap::iterator it_at = _attractors.begin();
2074   if (it_at != _attractors.end()) {
2075     save << " " << "__ATTRACTORS_BEGIN__";
2076     for (; it_at != _attractors.end(); ++it_at) {
2077       save << " " << it_at->first << " " << it_at->second << "%#"; // "%#" is a mark of value end
2078     }
2079     save << " " << "__ATTRACTORS_END__";
2080   }
2081   
2082   TAttractorMap::iterator it_At = _classAttractors.begin();
2083   if (it_At != _classAttractors.end()) {
2084     std::ostringstream test;
2085     save << " " << "__NEW_ATTRACTORS_BEGIN__";
2086     test << " " << "__NEW_ATTRACTORS_BEGIN__";
2087     for (; it_At != _classAttractors.end(); ++it_At) {
2088       std::vector<double> attParams;
2089       attParams   = it_At->second->GetParameters();
2090 //       double step = it_At->second->GetStep();
2091       save << " " << it_At->first;
2092       save << " " << it_At->second->GetAttractorEntry();
2093       save << " " << attParams[0]  << " " <<  attParams[1] << " " <<  attParams[2] << " " <<  attParams[3];
2094 //       save << " " << step;
2095       test << " " << it_At->first;
2096       test << " " << it_At->second->GetAttractorEntry();
2097       test << " " << attParams[0]  << " " <<  attParams[1] << " " <<  attParams[2] << " " <<  attParams[3];
2098 //       test << " " << step;
2099     }
2100     save << " " << "__NEW_ATTRACTORS_END__";
2101     test << " " << "__NEW_ATTRACTORS_END__";
2102   }
2103
2104   TEnfVertexList::const_iterator it_enf = _enfVertexList.begin();
2105   if (it_enf != _enfVertexList.end()) {
2106     save << " " << "__ENFORCED_VERTICES_BEGIN__";
2107     for (; it_enf != _enfVertexList.end(); ++it_enf) {
2108       TEnfVertex *enfVertex = (*it_enf);
2109       save << " " << "__BEGIN_VERTEX__";
2110       if (!enfVertex->name.empty()) {
2111         save << " " << "__BEGIN_NAME__";
2112         save << " " << enfVertex->name;
2113         save << " " << "__END_NAME__";
2114       }
2115       if (!enfVertex->geomEntry.empty()) {
2116         save << " " << "__BEGIN_ENTRY__";
2117         save << " " << enfVertex->geomEntry;
2118         save << " " << "__END_ENTRY__";
2119       }
2120       if (!enfVertex->grpName.empty()) {
2121         save << " " << "__BEGIN_GROUP__";
2122         save << " " << enfVertex->grpName;
2123         save << " " << "__END_GROUP__";
2124       }
2125       if (enfVertex->coords.size()) {
2126         save << " " << "__BEGIN_COORDS__";
2127         for ( size_t i = 0; i < enfVertex->coords.size(); i++ )
2128           save << " " << enfVertex->coords[i];
2129         save << " " << "__END_COORDS__";
2130       }
2131       TEntryList::const_iterator faceEntriesIt = enfVertex->faceEntries.begin();
2132       bool hasFaces = false;
2133       if (faceEntriesIt != enfVertex->faceEntries.end()) {
2134         hasFaces = true;
2135         save << " " << "__BEGIN_FACELIST__";
2136       }
2137       for (; faceEntriesIt != enfVertex->faceEntries.end(); ++faceEntriesIt)
2138         if ( faceEntriesIt->empty() )
2139           save << " _no_face_";
2140         else
2141           save << " " << (*faceEntriesIt);
2142       if (hasFaces)
2143         save << " " << "__END_FACELIST__";
2144       save << " " << "__END_VERTEX__";
2145     }
2146     save << " " << "__ENFORCED_VERTICES_END__";
2147   }
2148
2149   //PERIODICITY
2150
2151   SavePreCADPeriodicity(save, "FACES");
2152   SavePreCADPeriodicity(save, "EDGES");
2153
2154   SaveFacesPeriodicity(save);
2155   SaveEdgesPeriodicity(save);
2156   SaveVerticesPeriodicity(save);
2157
2158   // HYPER-PATCHES
2159   save << " " << _hyperPatchList.size() << " ";
2160   for ( size_t i = 0; i < _hyperPatchList.size(); ++i )
2161   {
2162     THyperPatchTags& patch = _hyperPatchList[i];
2163     save << patch.size() << " ";
2164     THyperPatchTags::iterator tag = patch.begin();
2165     for ( ; tag != patch.end(); ++tag )
2166       save << *tag << " ";
2167   }
2168
2169   // New options in 2.9.6 (issue #17784)
2170   save << " " << _useSurfaceProximity;
2171   save << " " << _nbSurfaceProximityLayers;
2172   save << " " << _surfaceProximityRatio;
2173   save << " " << _useVolumeProximity;
2174   save << " " << _nbVolumeProximityLayers;
2175   save << " " << _volumeProximityRatio;
2176
2177   return save;
2178 }
2179
2180 void BLSURFPlugin_Hypothesis::SaveFacesPeriodicity(std::ostream & save){
2181
2182   TFacesPeriodicityVector::const_iterator it_faces_periodicity = _facesPeriodicityVector.begin();
2183   if (it_faces_periodicity != _facesPeriodicityVector.end()) {
2184     save << " " << "__FACES_PERIODICITY_BEGIN__";
2185     for (; it_faces_periodicity != _facesPeriodicityVector.end(); ++it_faces_periodicity) {
2186       TFacesPeriodicity periodicity_i = (*it_faces_periodicity);
2187       save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2188       save << " " << "__BEGIN_ENTRY1__";
2189       save << " " << periodicity_i.first;
2190       save << " " << "__END_ENTRY1__";
2191       save << " " << "__BEGIN_ENTRY2__";
2192       save << " " << periodicity_i.second;
2193       save << " " << "__END_ENTRY2__";
2194       save << " " << "__END_PERIODICITY_DESCRIPTION__";
2195     }
2196     save << " " << "__FACES_PERIODICITY_END__";
2197   }
2198 }
2199
2200 void BLSURFPlugin_Hypothesis::SaveEdgesPeriodicity(std::ostream & save){
2201
2202   TEdgesPeriodicityVector::const_iterator it_edges_periodicity = _edgesPeriodicityVector.begin();
2203   if (it_edges_periodicity != _edgesPeriodicityVector.end()) {
2204     save << " " << "__EDGES_PERIODICITY_BEGIN__";
2205     for (; it_edges_periodicity != _edgesPeriodicityVector.end(); ++it_edges_periodicity) {
2206       TEdgePeriodicity periodicity_i = (*it_edges_periodicity);
2207       save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2208       if (! periodicity_i.theFace1Entry.empty()){
2209         save << " " << "__BEGIN_FACE1__";
2210         save << " " << periodicity_i.theFace1Entry;
2211         save << " " << "__END_FACE1__";
2212       }
2213       save << " " << "__BEGIN_EDGE1__";
2214       save << " " << periodicity_i.theEdge1Entry;
2215       save << " " << "__END_EDGE1__";
2216       if (! periodicity_i.theFace2Entry.empty()){
2217         save << " " << "__BEGIN_FACE2__";
2218         save << " " << periodicity_i.theFace2Entry;
2219         save << " " << "__END_FACE2__";
2220       }
2221       save << " " << "__BEGIN_EDGE2__";
2222       save << " " << periodicity_i.theEdge2Entry;
2223       save << " " << "__END_EDGE2__";
2224       save << " " << "__BEGIN_EDGE_ORIENTATION__";
2225       save << " " << periodicity_i.edge_orientation;
2226       save << " " << "__END_EDGE_ORIENTATION__";
2227       save << " " << "__END_PERIODICITY_DESCRIPTION__";
2228     }
2229     save << " " << "__EDGES_PERIODICITY_END__";
2230   }
2231 }
2232
2233 void BLSURFPlugin_Hypothesis::SaveVerticesPeriodicity(std::ostream & save){
2234
2235   TVerticesPeriodicityVector::const_iterator it_vertices_periodicity = _verticesPeriodicityVector.begin();
2236   if (it_vertices_periodicity != _verticesPeriodicityVector.end()) {
2237     save << " " << "__VERTICES_PERIODICITY_BEGIN__";
2238     for (; it_vertices_periodicity != _verticesPeriodicityVector.end(); ++it_vertices_periodicity) {
2239       TVertexPeriodicity periodicity_i = (*it_vertices_periodicity);
2240       save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2241       save << " " << "__BEGIN_EDGE1__";
2242       save << " " << periodicity_i.theEdge1Entry;
2243       save << " " << "__END_EDGE1__";
2244       save << " " << "__BEGIN_VERTEX1__";
2245       save << " " << periodicity_i.theVertex1Entry;
2246       save << " " << "__END_VERTEX1__";
2247       save << " " << "__BEGIN_EDGE2__";
2248       save << " " << periodicity_i.theEdge2Entry;
2249       save << " " << "__END_EDGE2__";
2250       save << " " << "__BEGIN_VERTEX2__";
2251       save << " " << periodicity_i.theVertex2Entry;
2252       save << " " << "__END_VERTEX2__";
2253       save << " " << "__END_PERIODICITY_DESCRIPTION__";
2254     }
2255     save << " " << "__VERTICES_PERIODICITY_END__";
2256   }
2257 }
2258
2259 void BLSURFPlugin_Hypothesis::SavePreCADPeriodicity(std::ostream & save, const char* shapeType) {
2260   TPreCadPeriodicityVector precad_periodicity;
2261   if ( shapeType  &&  strcmp( shapeType, "FACES" ) == 0 )
2262     precad_periodicity = _preCadFacesPeriodicityVector;
2263   else
2264     precad_periodicity = _preCadEdgesPeriodicityVector;
2265   TPreCadPeriodicityVector::const_iterator it_precad_periodicity = precad_periodicity.begin();
2266   if (it_precad_periodicity != precad_periodicity.end()) {
2267     save << " " << "__PRECAD_" << shapeType << "_PERIODICITY_BEGIN__";
2268     for (; it_precad_periodicity != precad_periodicity.end(); ++it_precad_periodicity) {
2269       TPreCadPeriodicity periodicity_i = (*it_precad_periodicity);
2270       save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2271       if (!periodicity_i.shape1Entry.empty()) {
2272         save << " " << "__BEGIN_ENTRY1__";
2273         save << " " << periodicity_i.shape1Entry;
2274         save << " " << "__END_ENTRY1__";
2275       }
2276       if (!periodicity_i.shape2Entry.empty()) {
2277         save << " " << "__BEGIN_ENTRY2__";
2278         save << " " << periodicity_i.shape2Entry;
2279         save << " " << "__END_ENTRY2__";
2280       }
2281
2282       std::vector<std::string>::const_iterator sourceVerticesEntriesIt = periodicity_i.theSourceVerticesEntries.begin();
2283       bool hasSourceVertices = false;
2284       if (sourceVerticesEntriesIt != periodicity_i.theSourceVerticesEntries.end()) {
2285         hasSourceVertices = true;
2286         save << " " << "__BEGIN_SOURCE_VERTICES_LIST__";
2287       }
2288       for (; sourceVerticesEntriesIt != periodicity_i.theSourceVerticesEntries.end(); ++sourceVerticesEntriesIt)
2289         save << " " << (*sourceVerticesEntriesIt);
2290       if (hasSourceVertices)
2291         save << " " << "__END_SOURCE_VERTICES_LIST__";
2292
2293       std::vector<std::string>::const_iterator targetVerticesEntriesIt = periodicity_i.theTargetVerticesEntries.begin();
2294       bool hasTargetVertices = false;
2295       if (targetVerticesEntriesIt != periodicity_i.theTargetVerticesEntries.end()) {
2296         hasTargetVertices = true;
2297         save << " " << "__BEGIN_TARGET_VERTICES_LIST__";
2298       }
2299       for (; targetVerticesEntriesIt != periodicity_i.theTargetVerticesEntries.end(); ++targetVerticesEntriesIt)
2300         save << " " << (*targetVerticesEntriesIt);
2301       if (hasTargetVertices)
2302         save << " " << "__END_TARGET_VERTICES_LIST__";
2303
2304       save << " " << "__END_PERIODICITY_DESCRIPTION__";
2305     }
2306     save << " " << "__PRECAD_" << shapeType << "_PERIODICITY_END__";
2307   }
2308
2309 }
2310
2311 //=============================================================================
2312 std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load)
2313 {
2314   bool isOK = true;
2315   int i;
2316   double val;
2317   std::string option_or_sm;
2318
2319   isOK = static_cast<bool>(load >> i);
2320   if (isOK)
2321     _topology = (Topology) i;
2322   else
2323     load.clear(std::ios::badbit | load.rdstate());
2324
2325   isOK = static_cast<bool>(load >> i);
2326   if (isOK)
2327     _physicalMesh = (PhysicalMesh) i;
2328   else
2329     load.clear(std::ios::badbit | load.rdstate());
2330
2331   isOK = static_cast<bool>(load >> i);
2332   if (isOK)
2333     _geometricMesh = (GeometricMesh) i;
2334   else
2335     load.clear(std::ios::badbit | load.rdstate());
2336
2337   isOK = static_cast<bool>(load >> val);
2338   if (isOK)
2339     _phySize = val;
2340   else
2341     load.clear(std::ios::badbit | load.rdstate());
2342
2343   isOK = static_cast<bool>(load >> val);
2344   if (isOK)
2345     _angleMesh = val;
2346   else
2347     load.clear(std::ios::badbit | load.rdstate());
2348
2349   isOK = static_cast<bool>(load >> val);
2350   if (isOK)
2351     _gradation = val;
2352   else
2353     load.clear(std::ios::badbit | load.rdstate());
2354
2355   isOK = static_cast<bool>(load >> i);
2356   if (isOK)
2357     _elementType = (ElementType) i;
2358   else
2359     load.clear(std::ios::badbit | load.rdstate());
2360
2361   isOK = static_cast<bool>(load >> i);
2362   if (isOK) {
2363     if ( i != -1) { // if value is -1, then this is no longer a standard option
2364       std::string & value = _option2value["respect_geometry"];
2365       bool _decimesh = (bool) i;
2366       value = _decimesh ? "1" : "0";
2367     }
2368   }
2369   else
2370     load.clear(std::ios::badbit | load.rdstate());
2371
2372   isOK = static_cast<bool>(load >> val);
2373   if (isOK)
2374     _minSize = val;
2375   else
2376     load.clear(std::ios::badbit | load.rdstate());
2377
2378   isOK = static_cast<bool>(load >> val);
2379   if (isOK)
2380     _maxSize = val;
2381   else
2382     load.clear(std::ios::badbit | load.rdstate());
2383
2384   isOK = static_cast<bool>(load >> val);
2385   if (isOK)
2386     // former parameter: get min value
2387     _angleMesh = std::min(val,_angleMesh);
2388   else
2389     load.clear(std::ios::badbit | load.rdstate());
2390
2391   isOK = static_cast<bool>(load >> val);
2392   if (isOK)
2393     // former parameter: get min value
2394     _minSize = std::min(val,_minSize);
2395   else
2396     load.clear(std::ios::badbit | load.rdstate());
2397
2398   isOK = static_cast<bool>(load >> val);
2399   if (isOK)
2400     // former parameter: get max value
2401     _maxSize = std::max(val,_maxSize);
2402   else
2403     load.clear(std::ios::badbit | load.rdstate());
2404
2405   isOK = static_cast<bool>(load >> i);
2406   if (isOK)
2407     _verb = i;
2408   else
2409     load.clear(std::ios::badbit | load.rdstate());
2410
2411   isOK = static_cast<bool>(load >> i);
2412   if (isOK)
2413     _preCADMergeEdges = (bool) i;
2414   else
2415     load.clear(std::ios::badbit | load.rdstate());
2416
2417   isOK = static_cast<bool>(load >> i);
2418   if (isOK) {
2419     if ( i != -1) { // if value is -1, then this is no longer a standard option
2420       std::string & value = _preCADoption2value["remove_tiny_edges"];
2421       bool _preCADRemoveNanoEdges = (bool) i;
2422       value = _preCADRemoveNanoEdges ? "1" : "0";
2423     }
2424   }
2425   else
2426     load.clear(std::ios::badbit | load.rdstate());
2427
2428   isOK = static_cast<bool>(load >> i);
2429   if (isOK)
2430     _preCADDiscardInput = (bool) i;
2431   else
2432     load.clear(std::ios::badbit | load.rdstate());
2433
2434   isOK = static_cast<bool>(load >> val);
2435   if (isOK) { // _preCADEpsNano
2436     if ( (i + 1.0) < 1e-6 ) { // if value is -1, then this is no longer a standard option: get optional value "tiny_edge_length" instead
2437       std::string & value = _preCADoption2value["tiny_edge_length"];
2438       std::ostringstream oss;
2439       oss << i;
2440       value = oss.str();
2441     }
2442   }
2443   else
2444     load.clear(std::ios::badbit | load.rdstate());
2445
2446   isOK = static_cast<bool>(load >> i);
2447   if (isOK)
2448     _enforcedInternalVerticesAllFaces = (bool) i;
2449   else
2450     load.clear(std::ios::badbit | load.rdstate());
2451
2452   // New options with MeshGems-CADSurf
2453
2454   bool hasCADSurfOptions = false;
2455   bool hasOptions = false;
2456   bool hasCustomOptions = false;
2457   bool hasPreCADOptions = false;
2458   bool hasSizeMap = false;
2459   bool hasAttractor = false;
2460   bool hasNewAttractor = false;
2461   bool hasEnforcedVertex = false;
2462   bool hasPreCADFacesPeriodicity = false;
2463   bool hasPreCADEdgesPeriodicity = false;
2464   bool hasFacesPeriodicity = false;
2465   bool hasEdgesPeriodicity = false;
2466   bool hasVerticesPeriodicity = false;
2467
2468   isOK = static_cast<bool>(load >> option_or_sm);
2469   if (isOK)
2470     if ( (option_or_sm == "1")||(option_or_sm == "0") ) {
2471       i = atoi(option_or_sm.c_str());
2472       hasCADSurfOptions = true;
2473       _phySizeRel = (bool) i;
2474     }
2475     if (option_or_sm == "__OPTIONS_BEGIN__")
2476       hasOptions = true;
2477     else if (option_or_sm == "__CUSTOM_OPTIONS_BEGIN__")
2478       hasCustomOptions = true;
2479     else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2480       hasPreCADOptions = true;
2481     else if (option_or_sm == "__SIZEMAP_BEGIN__")
2482       hasSizeMap = true;
2483     else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2484       hasAttractor = true;
2485     else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2486       hasNewAttractor = true;
2487     else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2488       hasEnforcedVertex = true;
2489     else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2490       hasPreCADFacesPeriodicity = true;
2491     else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2492       hasPreCADEdgesPeriodicity = true;
2493     else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2494       hasFacesPeriodicity = true;
2495     else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2496       hasEdgesPeriodicity = true;
2497     else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2498       hasVerticesPeriodicity = true;
2499
2500   if (isOK && hasCADSurfOptions) {
2501     isOK = static_cast<bool>(load >> i);
2502     if (isOK)
2503       _minSizeRel = (bool) i;
2504     else
2505       load.clear(std::ios::badbit | load.rdstate());
2506
2507     isOK = static_cast<bool>(load >> i);
2508     if (isOK)
2509       _maxSizeRel = (bool) i;
2510     else
2511       load.clear(std::ios::badbit | load.rdstate());
2512
2513     isOK = static_cast<bool>(load >> val);
2514     if (isOK)
2515       _chordalError = val;
2516     else
2517       load.clear(std::ios::badbit | load.rdstate());
2518
2519     isOK = static_cast<bool>(load >> i);
2520     if (isOK)
2521       _anisotropic = (bool) i;
2522     else
2523       load.clear(std::ios::badbit | load.rdstate());
2524
2525     isOK = static_cast<bool>(load >> val);
2526     if (isOK)
2527       _anisotropicRatio = val;
2528     else
2529       load.clear(std::ios::badbit | load.rdstate());
2530
2531     isOK = static_cast<bool>(load >> i);
2532     if (isOK)
2533       _removeTinyEdges = (bool) i;
2534     else
2535       load.clear(std::ios::badbit | load.rdstate());
2536
2537     isOK = static_cast<bool>(load >> val);
2538     if (isOK)
2539       _tinyEdgeLength = val;
2540     else
2541       load.clear(std::ios::badbit | load.rdstate());
2542
2543     isOK = static_cast<bool>(load >> i);
2544     if (isOK)
2545       _badElementRemoval = (bool) i;
2546     else
2547       load.clear(std::ios::badbit | load.rdstate());
2548
2549     isOK = static_cast<bool>(load >> val);
2550     if (isOK)
2551       _badElementAspectRatio = val;
2552     else
2553       load.clear(std::ios::badbit | load.rdstate());
2554
2555     isOK = static_cast<bool>(load >> i);
2556     if (isOK)
2557       _optimizeMesh = (bool) i;
2558     else
2559       load.clear(std::ios::badbit | load.rdstate());
2560
2561     isOK = static_cast<bool>(load >> i);
2562     if (isOK)
2563       _quadraticMesh = (bool) i;
2564     else
2565       load.clear(std::ios::badbit | load.rdstate());
2566
2567     isOK = static_cast<bool>(load >> i);
2568     if (isOK)
2569       _preCADProcess3DTopology = (bool) i;
2570     else
2571       load.clear(std::ios::badbit | load.rdstate());
2572
2573     if (( load >> std::ws).peek() != '_' )
2574     {
2575       isOK = static_cast<bool>(load >> i);
2576       if (isOK)
2577         _preCADRemoveDuplicateCADFaces = (bool) i;
2578       else
2579         load.clear(std::ios::badbit | load.rdstate());
2580
2581       isOK = static_cast<bool>(load >> i);
2582       if (isOK)
2583         _optimiseTinyEdges = (bool) i;
2584       else
2585         load.clear(std::ios::badbit | load.rdstate());
2586
2587       isOK = static_cast<bool>(load >> val);
2588       if (isOK)
2589         _tinyEdgeOptimisationLength = val;
2590       else
2591         load.clear(std::ios::badbit | load.rdstate());
2592
2593       isOK = static_cast<bool>(load >> i);
2594       if (isOK)
2595         _correctSurfaceIntersec = (bool) i;
2596       else
2597         load.clear(std::ios::badbit | load.rdstate());
2598
2599       isOK = static_cast<bool>(load >> val);
2600       if (isOK)
2601         _corrSurfaceIntersCost = val;
2602       else
2603         load.clear(std::ios::badbit | load.rdstate());
2604
2605       isOK = static_cast<bool>(load >> i);
2606       if (isOK)
2607         _useGradation = (bool) i;
2608       else
2609         load.clear(std::ios::badbit | load.rdstate());
2610
2611       isOK = static_cast<bool>(load >> i);
2612       if (isOK)
2613         _useVolumeGradation = (bool) i;
2614       else
2615         load.clear(std::ios::badbit | load.rdstate());
2616
2617       isOK = static_cast<bool>(load >> val);
2618       if (isOK)
2619         _volumeGradation = val;
2620       else
2621         load.clear(std::ios::badbit | load.rdstate());
2622     }
2623   }
2624
2625
2626   if (hasCADSurfOptions) {
2627     isOK = static_cast<bool>(load >> option_or_sm);
2628     if (isOK) {
2629       if (option_or_sm == "__OPTIONS_BEGIN__")
2630         hasOptions = true;
2631       else if (option_or_sm == "__CUSTOM_OPTIONS_BEGIN__")
2632         hasCustomOptions = true;
2633       else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2634         hasPreCADOptions = true;
2635       else if (option_or_sm == "__SIZEMAP_BEGIN__")
2636         hasSizeMap = true;
2637       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2638         hasAttractor = true;
2639       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2640         hasNewAttractor = true;
2641       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2642         hasEnforcedVertex = true;
2643       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2644         hasPreCADFacesPeriodicity = true;
2645       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2646         hasPreCADEdgesPeriodicity = true;
2647       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2648         hasFacesPeriodicity = true;
2649       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2650         hasEdgesPeriodicity = true;
2651       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2652         hasVerticesPeriodicity = true;
2653     }
2654   }
2655   
2656   std::string optName, optValue;
2657   while (isOK && hasOptions) {
2658     isOK = static_cast<bool>(load >> optName);
2659     if (isOK) {
2660       if (optName == "__OPTIONS_END__")
2661         break;
2662       isOK = static_cast<bool>(load >> optValue);
2663     }
2664     // read the value of the advanced option
2665     // unless this option is no more used
2666     if (isOK && optName != "enforce_cad_edge_sizes" && optName != "max_number_of_points_per_patch") {
2667       std::string & value = _option2value[optName];
2668       value = optValue;
2669       int len = value.size();
2670       // continue reading until "%#" encountered
2671       while (value[len - 1] != '#' || value[len - 2] != '%') {
2672         isOK = static_cast<bool>(load >> optValue);
2673         if (isOK) {
2674           value += " ";
2675           value += optValue;
2676           len = value.size();
2677         } else {
2678           break;
2679         }
2680       }
2681       if ( value[ len - 1] == '#' )
2682         value.resize(len - 2); //cut off "%#"
2683     }
2684   }
2685
2686   if (hasOptions) {
2687     isOK = static_cast<bool>(load >> option_or_sm);
2688     if (isOK) {
2689       if (option_or_sm == "__CUSTOM_OPTIONS_BEGIN__")
2690         hasCustomOptions = true;
2691       else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2692         hasPreCADOptions = true;
2693       else if (option_or_sm == "__SIZEMAP_BEGIN__")
2694         hasSizeMap = true;
2695       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2696         hasAttractor = true;
2697       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2698         hasNewAttractor = true;
2699       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2700         hasEnforcedVertex = true;
2701       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2702         hasPreCADFacesPeriodicity = true;
2703       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2704         hasPreCADEdgesPeriodicity = true;
2705       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2706         hasFacesPeriodicity = true;
2707       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2708         hasEdgesPeriodicity = true;
2709       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2710         hasVerticesPeriodicity = true;
2711     }
2712   }
2713
2714   while (isOK && hasCustomOptions) {
2715     isOK = static_cast<bool>(load >> optName);
2716     if (isOK) {
2717       if (optName == "__CUSTOM_OPTIONS_END__")
2718         break;
2719       isOK = static_cast<bool>(load >> optValue);
2720     }
2721     if (isOK) {
2722       std::string& value = optValue;
2723       int len = value.size();
2724       // continue reading until "%#" encountered
2725       while (value[len - 1] != '#' || value[len - 2] != '%') {
2726         isOK = static_cast<bool>(load >> optValue);
2727         if (isOK) {
2728           value += " ";
2729           value += optValue;
2730           len = value.size();
2731         } else {
2732           break;
2733         }
2734       }
2735       if ( value[ len - 1] == '#' )
2736         value.resize(len - 2); //cut off "%#"
2737       _customOption2value[optName] = value;
2738     }
2739   }
2740
2741   if (hasCustomOptions) {
2742     isOK = static_cast<bool>(load >> option_or_sm);
2743     if (isOK) {
2744       if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2745         hasPreCADOptions = true;
2746       else if (option_or_sm == "__SIZEMAP_BEGIN__")
2747         hasSizeMap = true;
2748       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2749         hasAttractor = true;
2750       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2751         hasNewAttractor = true;
2752       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2753         hasEnforcedVertex = true;
2754       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2755         hasPreCADFacesPeriodicity = true;
2756       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2757         hasPreCADEdgesPeriodicity = true;
2758       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2759         hasFacesPeriodicity = true;
2760       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2761         hasEdgesPeriodicity = true;
2762       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2763         hasVerticesPeriodicity = true;
2764     }
2765   }
2766
2767   while (isOK && hasPreCADOptions) {
2768     isOK = static_cast<bool>(load >> optName);
2769     if (isOK) {
2770       if (optName == "__PRECAD_OPTIONS_END__")
2771         break;
2772       isOK = static_cast<bool>(load >> optValue);
2773     }
2774     if (isOK) {
2775       std::string & value = _preCADoption2value[optName];
2776       value = optValue;
2777       int len = value.size();
2778       // continue reading until "%#" encountered
2779       while (value[len - 1] != '#' || value[len - 2] != '%') {
2780         isOK = static_cast<bool>(load >> optValue);
2781         if (isOK) {
2782           value += " ";
2783           value += optValue;
2784           len = value.size();
2785         } else {
2786           break;
2787         }
2788       }
2789       if ( value[ len - 1] == '#' )
2790         value.resize(len - 2); //cut off "%#"
2791     }
2792   }
2793
2794   if (hasPreCADOptions) {
2795     isOK = static_cast<bool>(load >> option_or_sm);
2796     if (isOK) {
2797       if (option_or_sm == "__SIZEMAP_BEGIN__")
2798         hasSizeMap = true;
2799       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2800         hasAttractor = true;
2801       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2802         hasNewAttractor = true;
2803       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2804         hasEnforcedVertex = true;
2805       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2806         hasPreCADFacesPeriodicity = true;
2807       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2808         hasPreCADEdgesPeriodicity = true;
2809       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2810         hasFacesPeriodicity = true;
2811       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2812         hasEdgesPeriodicity = true;
2813       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2814         hasVerticesPeriodicity = true;
2815     }
2816   }
2817  
2818   std::string smEntry, smValue;
2819   while (isOK && hasSizeMap) {
2820     isOK = static_cast<bool>(load >> smEntry);
2821     if (isOK) {
2822       if (smEntry == "__SIZEMAP_END__")
2823         break;
2824       isOK = static_cast<bool>(load >> smValue);
2825     }
2826     if (isOK) {
2827       std::string & value2 = _sizeMap[smEntry];
2828       value2 = smValue;
2829       int len2 = value2.size();
2830       // continue reading until "%#" encountered
2831       while (value2[len2 - 1] != '#' || value2[len2 - 2] != '%') {
2832         isOK = static_cast<bool>(load >> smValue);
2833         if (isOK) {
2834           value2 += " ";
2835           value2 += smValue;
2836           len2 = value2.size();
2837         } else {
2838           break;
2839         }
2840       }
2841       value2.resize(len2 - 2); //cut off "%#"
2842     }
2843   }
2844
2845   if (hasSizeMap) {
2846     isOK = static_cast<bool>(load >> option_or_sm);
2847     if (isOK)
2848       if (option_or_sm == "__ATTRACTORS_BEGIN__")
2849         hasAttractor = true;
2850       if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2851         hasNewAttractor = true;
2852       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2853         hasEnforcedVertex = true;
2854       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2855         hasPreCADFacesPeriodicity = true;
2856       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2857         hasPreCADEdgesPeriodicity = true;
2858       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2859         hasFacesPeriodicity = true;
2860       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2861         hasEdgesPeriodicity = true;
2862       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2863         hasVerticesPeriodicity = true;
2864   }
2865
2866   std::string atEntry, atValue;
2867   while (isOK && hasAttractor) {
2868     isOK = static_cast<bool>(load >> atEntry);
2869     if (isOK) {
2870       if (atEntry == "__ATTRACTORS_END__")
2871         break;
2872       isOK = static_cast<bool>(load >> atValue);
2873     }
2874     if (isOK) {
2875       std::string & value3 = _attractors[atEntry];
2876       value3 = atValue;
2877       int len3 = value3.size();
2878       // continue reading until "%#" encountered
2879       while (value3[len3 - 1] != '#' || value3[len3 - 2] != '%') {
2880         isOK = static_cast<bool>(load >> atValue);
2881         if (isOK) {
2882           value3 += " ";
2883           value3 += atValue;
2884           len3 = value3.size();
2885         } else {
2886           break;
2887         }
2888       }
2889       value3.resize(len3 - 2); //cut off "%#"
2890     }
2891   }
2892
2893   if (hasAttractor) {
2894     isOK = static_cast<bool>(load >> option_or_sm);
2895     if (isOK) {
2896       if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2897         hasNewAttractor = true;
2898       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2899         hasEnforcedVertex = true;
2900       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2901         hasPreCADFacesPeriodicity = true;
2902       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2903         hasPreCADEdgesPeriodicity = true;
2904       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2905         hasFacesPeriodicity = true;
2906       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2907         hasEdgesPeriodicity = true;
2908       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2909         hasVerticesPeriodicity = true;
2910     }
2911   }
2912
2913   std::string newAtFaceEntry, atTestString;
2914   std::string newAtShapeEntry;
2915   double attParams[4];
2916   //double step;
2917   while (isOK && hasNewAttractor) {
2918     //std::cout<<"Load new attractor"<<std::endl;
2919     isOK = static_cast<bool>(load >> newAtFaceEntry);
2920     if (isOK) {
2921       if (newAtFaceEntry == "__NEW_ATTRACTORS_END__")
2922         break;
2923       isOK = static_cast<bool>(load >> newAtShapeEntry);
2924       if (!isOK)
2925         break;
2926       isOK = static_cast<bool>(load >> attParams[0]>>attParams[1]>>attParams[2]>>attParams[3]); //>>step);
2927     }
2928     if (isOK) {
2929       const TopoDS_Shape attractorShape = BLSURFPlugin_Hypothesis::entryToShape(newAtShapeEntry);
2930       const TopoDS_Face faceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(newAtFaceEntry));
2931       BLSURFPlugin_Attractor* attractor = new BLSURFPlugin_Attractor(faceShape, attractorShape, newAtShapeEntry);//, step);
2932       attractor->SetParameters(attParams[0], attParams[1], attParams[2], attParams[3]);
2933       //attractor->BuildMap();                     
2934       _classAttractors.insert( make_pair( newAtFaceEntry, attractor ));
2935     }
2936   }
2937   
2938   
2939   if (hasNewAttractor) {
2940     isOK = static_cast<bool>(load >> option_or_sm);
2941     if (isOK) {
2942       if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2943         hasEnforcedVertex = true;
2944       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2945         hasPreCADFacesPeriodicity = true;
2946       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2947         hasPreCADEdgesPeriodicity = true;
2948       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2949         hasFacesPeriodicity = true;
2950       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2951         hasEdgesPeriodicity = true;
2952       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2953         hasVerticesPeriodicity = true;
2954     }
2955   }
2956
2957
2958 // 
2959 // Here is a example of the saved stream:
2960 // __ENFORCED_VERTICES_BEGIN__ 
2961 // __BEGIN_VERTEX__  => no name, no entry
2962 // __BEGIN_GROUP__ mon groupe __END_GROUP__
2963 // __BEGIN_COORDS__ 10 10 10 __END_COORDS__
2964 // __BEGIN_FACELIST__ 0:1:1:1:1 __END_FACELIST__
2965 // __END_VERTEX__
2966 // __BEGIN_VERTEX__ => no coords
2967 // __BEGIN_NAME__ mes points __END_NAME__
2968 // __BEGIN_ENTRY__ 0:1:1:4 __END_ENTRY__
2969 // __BEGIN_GROUP__ mon groupe __END_GROUP__
2970 // __BEGIN_FACELIST__ 0:1:1:1:3 __END_FACELIST__
2971 // __END_VERTEX__
2972 // __ENFORCED_VERTICES_END__
2973 //
2974
2975   std::string enfSeparator;
2976   std::string enfName;
2977   std::string enfGeomEntry;
2978   std::string enfGroup;
2979   TEntryList enfFaceEntryList;
2980   double enfCoords[3];
2981   bool hasCoords = false;
2982
2983   _faceEntryEnfVertexListMap.clear();
2984   _enfVertexList.clear();
2985   _faceEntryCoordsListMap.clear();
2986   _coordsEnfVertexMap.clear();
2987   _faceEntryEnfVertexEntryListMap.clear();
2988   _enfVertexEntryEnfVertexMap.clear();
2989
2990
2991   while (isOK && hasEnforcedVertex)
2992   {
2993     isOK = static_cast<bool>(load >> enfSeparator); // __BEGIN_VERTEX__
2994     TEnfVertex *enfVertex = new TEnfVertex();
2995     if (enfSeparator == "__ENFORCED_VERTICES_END__")
2996       break; // __ENFORCED_VERTICES_END__
2997     if (enfSeparator != "__BEGIN_VERTEX__")
2998       throw std::exception();
2999
3000     while (isOK) {
3001       isOK = static_cast<bool>(load >> enfSeparator);
3002       if (enfSeparator == "__END_VERTEX__") {
3003
3004         enfVertex->name = enfName;
3005         enfVertex->geomEntry = enfGeomEntry;
3006         enfVertex->grpName = enfGroup;
3007         enfVertex->coords.clear();
3008         if (hasCoords)
3009           enfVertex->coords.assign(enfCoords,enfCoords+3);
3010         enfVertex->faceEntries = enfFaceEntryList;
3011
3012         _enfVertexList.insert(enfVertex);
3013
3014         if (enfVertex->coords.size()) {
3015           _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
3016           for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) {
3017             _faceEntryCoordsListMap[(*it)].insert(enfVertex->coords);
3018             _faceEntryEnfVertexListMap[(*it)].insert(enfVertex);
3019           }
3020         }
3021         if (!enfVertex->geomEntry.empty()) {
3022           _enfVertexEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
3023           for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) {
3024             _faceEntryEnfVertexEntryListMap[(*it)].insert(enfVertex->geomEntry);
3025             _faceEntryEnfVertexListMap[(*it)].insert(enfVertex);
3026           }
3027         }
3028
3029         enfName.clear();
3030         enfGeomEntry.clear();
3031         enfGroup.clear();
3032         enfFaceEntryList.clear();
3033         hasCoords = false;
3034         break; // __END_VERTEX__
3035       }
3036
3037       if (enfSeparator == "__BEGIN_NAME__") {  // __BEGIN_NAME__
3038         while (isOK && (enfSeparator != "__END_NAME__")) {
3039           isOK = static_cast<bool>(load >> enfSeparator);
3040           if (enfSeparator != "__END_NAME__") {
3041             if (!enfName.empty())
3042               enfName += " ";
3043             enfName += enfSeparator;
3044           }
3045         }
3046       }
3047
3048       if (enfSeparator == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
3049         isOK = static_cast<bool>(load >> enfGeomEntry);
3050         isOK = static_cast<bool>(load >> enfSeparator); // __END_ENTRY__
3051         if (enfSeparator != "__END_ENTRY__")
3052           throw std::exception();
3053       }
3054
3055       if (enfSeparator == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
3056         while (isOK && (enfSeparator != "__END_GROUP__")) {
3057           isOK = static_cast<bool>(load >> enfSeparator);
3058           if (enfSeparator != "__END_GROUP__") {
3059             if (!enfGroup.empty())
3060               enfGroup += " ";
3061             enfGroup += enfSeparator;
3062           }
3063         }
3064       }
3065
3066       if (enfSeparator == "__BEGIN_COORDS__") {  // __BEGIN_COORDS__
3067         hasCoords = true;
3068         isOK = static_cast<bool>(load >> enfCoords[0] >> enfCoords[1] >> enfCoords[2]);
3069         isOK = static_cast<bool>(load >> enfSeparator); // __END_COORDS__
3070         if (enfSeparator != "__END_COORDS__")
3071           throw std::exception();
3072       }
3073
3074       if (enfSeparator == "__BEGIN_FACELIST__") {  // __BEGIN_FACELIST__
3075         while (isOK && (enfSeparator != "__END_FACELIST__")) {
3076           isOK = static_cast<bool>(load >> enfSeparator);
3077           if (enfSeparator != "__END_FACELIST__") {
3078             enfFaceEntryList.insert(enfSeparator);
3079           }
3080         }
3081       }
3082     }
3083   }
3084
3085   if ( hasEnforcedVertex ) {
3086     isOK = static_cast<bool>(load >> option_or_sm);
3087     if (isOK) {
3088       if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
3089         hasPreCADFacesPeriodicity = true;
3090       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
3091         hasPreCADEdgesPeriodicity = true;
3092       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
3093         hasFacesPeriodicity = true;
3094       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3095         hasEdgesPeriodicity = true;
3096       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3097         hasVerticesPeriodicity = true;
3098     }
3099   }
3100
3101   // PERIODICITY
3102
3103   if (hasPreCADFacesPeriodicity)
3104   {
3105     LoadPreCADPeriodicity(load, "FACES");
3106
3107     isOK = static_cast<bool>(load >> option_or_sm);
3108     if (isOK) {
3109       if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
3110         hasPreCADEdgesPeriodicity = true;
3111       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
3112         hasFacesPeriodicity = true;
3113       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3114         hasEdgesPeriodicity = true;
3115       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3116         hasVerticesPeriodicity = true;
3117     }
3118   }
3119
3120   if (hasPreCADEdgesPeriodicity)
3121   {
3122     LoadPreCADPeriodicity(load, "EDGES");
3123
3124     isOK = static_cast<bool>(load >> option_or_sm);
3125     if (isOK) {
3126       if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
3127         hasFacesPeriodicity = true;
3128       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3129         hasEdgesPeriodicity = true;
3130       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3131         hasVerticesPeriodicity = true;
3132     }
3133   }
3134
3135   if (hasFacesPeriodicity)
3136   {
3137     LoadFacesPeriodicity(load);
3138
3139     isOK = static_cast<bool>(load >> option_or_sm);
3140     if (isOK) {
3141       if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3142         hasEdgesPeriodicity = true;
3143       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3144         hasVerticesPeriodicity = true;
3145     }
3146   }
3147
3148   if (hasEdgesPeriodicity)
3149   {
3150     LoadEdgesPeriodicity(load);
3151
3152     isOK = static_cast<bool>(load >> option_or_sm);
3153     if (isOK)
3154       if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3155         hasVerticesPeriodicity = true;
3156   }
3157
3158   if (hasVerticesPeriodicity)
3159     LoadVerticesPeriodicity(load);
3160
3161   // HYPER-PATCHES
3162   if ( !option_or_sm.empty() && option_or_sm[0] == '_' )
3163     isOK = static_cast<bool>(load >> option_or_sm);
3164   if ( isOK && !option_or_sm.empty() )
3165   {
3166     int nbPatches = atoi( option_or_sm.c_str() );
3167     if ( nbPatches >= 0 )
3168     {
3169       _hyperPatchList.resize( nbPatches );
3170       for ( int iP = 0; iP < nbPatches && isOK; ++iP )
3171       {
3172         isOK = static_cast<bool>(load >> i) && i >= 2;
3173         if ( !isOK ) break;
3174         int nbTags = i;
3175         for ( int iT = 0; iT < nbTags; ++iT )
3176         {
3177           if (( isOK = static_cast<bool>(load >> i)))
3178             _hyperPatchList[ iP ].insert( i );
3179           else
3180             break;
3181         }
3182       }
3183       if ( !isOK ) // remove invalid patches
3184       {
3185         for ( i = nbPatches - 1; i >= 0; i-- )
3186           if ( _hyperPatchList[i].size() < 2 )
3187             _hyperPatchList.resize( i );
3188       }
3189     }
3190   }
3191
3192   // New options in 2.9.6 (issue #17784)
3193   if ( static_cast<bool>( load >> _useSurfaceProximity ));
3194   {
3195     load >> _nbSurfaceProximityLayers;
3196     load >> _surfaceProximityRatio;
3197     load >> _useVolumeProximity;
3198     load >> _nbVolumeProximityLayers;
3199     isOK = static_cast<bool>( load >> _volumeProximityRatio );
3200   }
3201
3202   return load;
3203 }
3204
3205 void BLSURFPlugin_Hypothesis::LoadFacesPeriodicity(std::istream & load){
3206
3207   bool isOK = true;
3208
3209   std::string periodicitySeparator;
3210   TEntry shape1Entry;
3211   TEntry shape2Entry;
3212
3213   _facesPeriodicityVector.clear();
3214
3215   while (isOK) {
3216     isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3217     TFacesPeriodicity *periodicity_i = new TFacesPeriodicity();
3218     if (periodicitySeparator == "__FACES_PERIODICITY_END__")
3219       break; // __FACES_PERIODICITY_END__
3220     if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3221       throw std::exception();
3222     }
3223
3224     while (isOK) {
3225       isOK = static_cast<bool>(load >> periodicitySeparator);
3226       if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3227
3228         periodicity_i->first = shape1Entry;
3229         periodicity_i->second = shape2Entry;
3230
3231         _facesPeriodicityVector.push_back(*periodicity_i);
3232
3233         break; // __END_PERIODICITY_DESCRIPTION__
3234       }
3235
3236       if (periodicitySeparator == "__BEGIN_ENTRY1__") {  // __BEGIN_ENTRY1__
3237         isOK = static_cast<bool>(load >> shape1Entry);
3238         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY1__
3239         if (periodicitySeparator != "__END_ENTRY1__")
3240           throw std::exception();
3241       }
3242
3243       if (periodicitySeparator == "__BEGIN_ENTRY2__") {  // __BEGIN_ENTRY2__
3244         isOK = static_cast<bool>(load >> shape2Entry);
3245         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY2__
3246         if (periodicitySeparator != "__END_ENTRY2__")
3247           throw std::exception();
3248       }
3249     }
3250   }
3251 }
3252
3253
3254 void BLSURFPlugin_Hypothesis::LoadEdgesPeriodicity(std::istream & load){
3255
3256   bool isOK = true;
3257
3258   std::string periodicitySeparator;
3259   TEntry theFace1Entry;
3260   TEntry theEdge1Entry;
3261   TEntry theFace2Entry;
3262   TEntry theEdge2Entry;
3263   int edge_orientation = 0;
3264
3265   _edgesPeriodicityVector.clear();
3266
3267   while (isOK) {
3268     isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3269     TEdgePeriodicity *periodicity_i = new TEdgePeriodicity();
3270     if (periodicitySeparator == "__EDGES_PERIODICITY_END__")
3271       break; // __EDGES_PERIODICITY_END__
3272     if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3273       throw std::exception();
3274     }
3275
3276     while (isOK) {
3277       isOK = static_cast<bool>(load >> periodicitySeparator);
3278       if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3279
3280         periodicity_i->theFace1Entry = theFace1Entry;
3281         periodicity_i->theEdge1Entry = theEdge1Entry;
3282         periodicity_i->theFace2Entry = theFace2Entry;
3283         periodicity_i->theEdge2Entry = theEdge2Entry;
3284         periodicity_i->edge_orientation = edge_orientation;
3285
3286         _edgesPeriodicityVector.push_back(*periodicity_i);
3287
3288         break; // __END_PERIODICITY_DESCRIPTION__
3289       }
3290
3291       if (periodicitySeparator == "__BEGIN_FACE1__") {  // __BEGIN_FACE1__
3292         isOK = static_cast<bool>(load >> theFace1Entry);
3293         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_FACE1__
3294         if (periodicitySeparator != "__END_FACE1__"){
3295           throw std::exception();
3296         }
3297       }
3298
3299       if (periodicitySeparator == "__BEGIN_EDGE1__") {  // __BEGIN_EDGE1__
3300         isOK = static_cast<bool>(load >> theEdge1Entry);
3301         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE1__
3302         if (periodicitySeparator != "__END_EDGE1__")
3303           throw std::exception();
3304       }
3305
3306       if (periodicitySeparator == "__BEGIN_FACE2__") {  // __BEGIN_FACE2__
3307         isOK = static_cast<bool>(load >> theFace2Entry);
3308         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_FACE2__
3309         if (periodicitySeparator != "__END_FACE2__")
3310           throw std::exception();
3311       }
3312
3313       if (periodicitySeparator == "__BEGIN_EDGE2__") {  // __BEGIN_EDGE2__
3314         isOK = static_cast<bool>(load >> theEdge2Entry);
3315         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE2__
3316         if (periodicitySeparator != "__END_EDGE2__")
3317           throw std::exception();
3318       }
3319
3320       if (periodicitySeparator == "__BEGIN_EDGE_ORIENTATION__") {  // __BEGIN_EDGE_ORIENTATION__
3321         isOK = static_cast<bool>(load >> edge_orientation);
3322         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE_ORIENTATION__
3323         if (periodicitySeparator != "__END_EDGE_ORIENTATION__")
3324           throw std::exception();
3325       }
3326     }
3327   }
3328 }
3329
3330 void BLSURFPlugin_Hypothesis::LoadVerticesPeriodicity(std::istream & load)
3331 {
3332   bool isOK = true;
3333
3334   std::string periodicitySeparator;
3335   TEntry theEdge1Entry;
3336   TEntry theVertex1Entry;
3337   TEntry theEdge2Entry;
3338   TEntry theVertex2Entry;
3339
3340   _verticesPeriodicityVector.clear();
3341
3342   while (isOK) {
3343     isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3344     TVertexPeriodicity *periodicity_i = new TVertexPeriodicity();
3345     if (periodicitySeparator == "__VERTICES_PERIODICITY_END__")
3346       break; // __VERTICES_PERIODICITY_END__
3347     if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3348       throw std::exception();
3349     }
3350
3351     while (isOK) {
3352       isOK = static_cast<bool>(load >> periodicitySeparator);
3353       if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3354
3355         periodicity_i->theEdge1Entry = theEdge1Entry;
3356         periodicity_i->theVertex1Entry = theVertex1Entry;
3357         periodicity_i->theEdge2Entry = theEdge2Entry;
3358         periodicity_i->theVertex2Entry = theVertex2Entry;
3359
3360         _verticesPeriodicityVector.push_back(*periodicity_i);
3361
3362         break; // __END_PERIODICITY_DESCRIPTION__
3363       }
3364
3365       if (periodicitySeparator == "__BEGIN_EDGE1__") {  // __BEGIN_EDGE1__
3366         isOK = static_cast<bool>(load >> theEdge1Entry);
3367         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE1__
3368         if (periodicitySeparator != "__END_EDGE1__")
3369           throw std::exception();
3370       }
3371
3372       if (periodicitySeparator == "__BEGIN_VERTEX1__") {  // __BEGIN_VERTEX1__
3373         isOK = static_cast<bool>(load >> theVertex1Entry);
3374         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_VERTEX1__
3375         if (periodicitySeparator != "__END_VERTEX1__")
3376           throw std::exception();
3377       }
3378
3379       if (periodicitySeparator == "__BEGIN_EDGE2__") {  // __BEGIN_EDGE2__
3380         isOK = static_cast<bool>(load >> theEdge2Entry);
3381         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE2__
3382         if (periodicitySeparator != "__END_EDGE2__")
3383           throw std::exception();
3384       }
3385
3386       if (periodicitySeparator == "__BEGIN_VERTEX2__") {  // __BEGIN_VERTEX2__
3387         isOK = static_cast<bool>(load >> theVertex2Entry);
3388         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_VERTEX2__
3389         if (periodicitySeparator != "__END_VERTEX2__")
3390           throw std::exception();
3391       }
3392     }
3393   }
3394 }
3395
3396 void BLSURFPlugin_Hypothesis::LoadPreCADPeriodicity(std::istream & load, const char* shapeType) {
3397
3398   bool isOK = true;
3399
3400   std::string periodicitySeparator;
3401   TEntry shape1Entry;
3402   TEntry shape2Entry;
3403   std::vector<std::string> theSourceVerticesEntries;
3404   std::vector<std::string> theTargetVerticesEntries;
3405
3406   bool hasSourceVertices = false;
3407   bool hasTargetVertices = false;
3408
3409   if ( shapeType  &&  strcmp( shapeType, "FACES") == 0 )
3410     _preCadFacesPeriodicityVector.clear();
3411   else
3412     _preCadEdgesPeriodicityVector.clear();
3413
3414
3415   while (isOK) {
3416     isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3417     TPreCadPeriodicity *periodicity_i = new TPreCadPeriodicity();
3418     std::string endSeparator = "__PRECAD_" + std::string(shapeType) + "_PERIODICITY_END__";
3419     if (periodicitySeparator == endSeparator)
3420       break; // __PRECAD_FACES_PERIODICITY_END__
3421     if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3422       throw std::exception();
3423     }
3424
3425     while (isOK) {
3426       isOK = static_cast<bool>(load >> periodicitySeparator);
3427       if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3428
3429         periodicity_i->shape1Entry = shape1Entry;
3430         periodicity_i->shape2Entry = shape2Entry;
3431
3432         if (hasSourceVertices)
3433           periodicity_i->theSourceVerticesEntries = theSourceVerticesEntries;
3434         if (hasTargetVertices)
3435           periodicity_i->theTargetVerticesEntries = theTargetVerticesEntries;
3436
3437         if ( shapeType  &&  strcmp( shapeType, "FACES" ) == 0 )
3438           _preCadFacesPeriodicityVector.push_back(*periodicity_i);
3439         else
3440           _preCadEdgesPeriodicityVector.push_back(*periodicity_i);
3441
3442         theSourceVerticesEntries.clear();
3443         theTargetVerticesEntries.clear();
3444         hasSourceVertices = false;
3445         hasTargetVertices = false;
3446         break; // __END_PERIODICITY_DESCRIPTION__
3447       }
3448
3449       if (periodicitySeparator == "__BEGIN_ENTRY1__") {  // __BEGIN_ENTRY1__
3450         isOK = static_cast<bool>(load >> shape1Entry);
3451         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY1__
3452         if (periodicitySeparator != "__END_ENTRY1__")
3453           throw std::exception();
3454       }
3455
3456       if (periodicitySeparator == "__BEGIN_ENTRY2__") {  // __BEGIN_ENTRY2__
3457         isOK = static_cast<bool>(load >> shape2Entry);
3458         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY2__
3459         if (periodicitySeparator != "__END_ENTRY2__")
3460           throw std::exception();
3461       }
3462
3463       if (periodicitySeparator == "__BEGIN_SOURCE_VERTICES_LIST__") {  // __BEGIN_SOURCE_VERTICES_LIST__
3464         hasSourceVertices = true;
3465         while (isOK && (periodicitySeparator != "__END_SOURCE_VERTICES_LIST__")) {
3466           isOK = static_cast<bool>(load >> periodicitySeparator);
3467           if (periodicitySeparator != "__END_SOURCE_VERTICES_LIST__") {
3468             theSourceVerticesEntries.push_back(periodicitySeparator);
3469           }
3470         }
3471       }
3472
3473       if (periodicitySeparator == "__BEGIN_TARGET_VERTICES_LIST__") {  // __BEGIN_TARGET_VERTICES_LIST__
3474         hasTargetVertices = true;
3475         while (isOK && (periodicitySeparator != "__END_TARGET_VERTICES_LIST__")) {
3476           isOK = static_cast<bool>(load >> periodicitySeparator);
3477           if (periodicitySeparator != "__END_TARGET_VERTICES_LIST__") {
3478             theTargetVerticesEntries.push_back(periodicitySeparator);
3479           }
3480         }
3481       }
3482     }
3483   }
3484 }
3485
3486 //=============================================================================
3487 std::ostream & operator <<(std::ostream & save, BLSURFPlugin_Hypothesis & hyp) {
3488   return hyp.SaveTo(save);
3489 }
3490
3491 //=============================================================================
3492 std::istream & operator >>(std::istream & load, BLSURFPlugin_Hypothesis & hyp) {
3493   return hyp.LoadFrom(load);
3494 }
3495
3496 //================================================================================
3497 /*!
3498  * \brief Does nothing
3499  */
3500 //================================================================================
3501
3502 bool BLSURFPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape) {
3503   return false;
3504 }
3505
3506 //================================================================================
3507 /*!
3508  * \brief Returns default global constant physical size given a default value of element length ratio
3509  */
3510 //================================================================================
3511
3512 double BLSURFPlugin_Hypothesis::GetDefaultPhySize(double diagonal, double bbSegmentation) {
3513   if (bbSegmentation != 0 && diagonal != 0)
3514     return diagonal / bbSegmentation ;
3515   return 10;
3516 }
3517
3518 //================================================================================
3519 /*!
3520  * \brief Returns default min size given a default value of element length ratio
3521  */
3522 //================================================================================
3523
3524 double BLSURFPlugin_Hypothesis::GetDefaultMinSize(double diagonal) {
3525   if (diagonal != 0)
3526     return diagonal / 1000.0 ;
3527   return undefinedDouble();
3528 }
3529
3530 //================================================================================
3531 /*!
3532  * \brief Returns default max size given a default value of element length ratio
3533  */
3534 //================================================================================
3535
3536 double BLSURFPlugin_Hypothesis::GetDefaultMaxSize(double diagonal) {
3537   if (diagonal != 0)
3538     return diagonal / 5.0 ;
3539   return undefinedDouble();
3540 }
3541
3542 //================================================================================
3543 /*!
3544  * \brief Returns default chordal error given a default value of element length ratio
3545  */
3546 //================================================================================
3547
3548 double BLSURFPlugin_Hypothesis::GetDefaultChordalError(double diagonal) {
3549   if (diagonal != 0)
3550     return diagonal;
3551   return undefinedDouble();
3552 }
3553
3554 //================================================================================
3555 /*!
3556  * \brief Returns default tiny edge length given a default value of element length ratio
3557  */
3558 //================================================================================
3559
3560 double BLSURFPlugin_Hypothesis::GetDefaultTinyEdgeLength(double diagonal) {
3561   if (diagonal != 0)
3562     return diagonal * 1e-6 ;
3563   return undefinedDouble();
3564 }
3565
3566 //================================================================================
3567 /*!
3568  * \brief Returns default tiny edge optimisation length given a default value of element length ratio
3569  */
3570 //================================================================================
3571
3572 double BLSURFPlugin_Hypothesis::GetDefaultTinyEdgeOptimisationLength(double diagonal) {
3573   if (diagonal != 0)
3574     return diagonal * 1e-6 ;
3575   return undefinedDouble();
3576 }
3577
3578 //=============================================================================
3579 /*!
3580  * \brief Initialize my parameter values by default parameters.
3581  *  \retval bool - true if parameter values have been successfully defined
3582  */
3583 //=============================================================================
3584
3585 bool BLSURFPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  dflts,
3586                                                       const SMESH_Mesh* theMesh)
3587 {
3588   _phySize = GetDefaultPhySize(dflts._diagonal, _gen->GetBoundaryBoxSegmentation());
3589   _minSize = GetDefaultMinSize(dflts._diagonal);
3590   _maxSize = GetDefaultMaxSize(dflts._diagonal);
3591   _chordalError = 0.5 * _phySize; //GetDefaultChordalError(diagonal); IMP 0023307
3592
3593   if ( dflts._way == SMESH_Hypothesis::BY_AVERAGE_LENGTH )
3594   {
3595     _phySize      = dflts._elemLength;
3596     _minSize      = dflts._elemLength / 100.;
3597     _maxSize      = dflts._elemLength * 2.;
3598     _chordalError = dflts._elemLength / 2.;
3599     _elementType  = dflts._quadDominated ? Quadrangles : Triangles;
3600     _physicalMesh = PhysicalLocalSize; // to activate _enforcedInternalVerticesAllFaces
3601     _enforcedInternalVerticesAllFaces = true;
3602   }
3603   else
3604   {
3605     _tinyEdgeLength = GetDefaultTinyEdgeLength(dflts._diagonal);
3606     _tinyEdgeOptimisationLength = GetDefaultTinyEdgeOptimisationLength(dflts._diagonal);
3607   }
3608
3609   return true;
3610 }
3611
3612 //================================================================================
3613 /*!
3614  * \brief Converts a string to a bool
3615  */
3616 //================================================================================
3617
3618 bool BLSURFPlugin_Hypothesis::ToBool(const std::string& str, bool* isOk )
3619   throw (std::invalid_argument)
3620 {
3621   std::string s = str;
3622   if ( isOk ) *isOk = true;
3623
3624   for ( size_t i = 0; i <= s.size(); ++i )
3625     s[i] = tolower( s[i] );
3626
3627   if ( s == "1" || s == "true" || s == "active" || s == "yes" )
3628     return true;
3629
3630   if ( s == "0" || s == "false" || s == "inactive" || s == "no" )
3631     return false;
3632
3633   if ( isOk )
3634     *isOk = false;
3635   else {
3636     std::string msg = "Not a Boolean value:'" + str + "'";
3637     throw std::invalid_argument(msg);
3638   }
3639   return false;
3640 }
3641
3642 //================================================================================
3643 /*!
3644  * \brief Converts a string to a real value
3645  */
3646 //================================================================================
3647
3648 double BLSURFPlugin_Hypothesis::ToDbl(const std::string& str, bool* isOk )
3649   throw (std::invalid_argument)
3650 {
3651   if ( str.empty() ) throw std::invalid_argument("Empty value provided");
3652
3653   char * endPtr;
3654   double val = strtod(&str[0], &endPtr);
3655   bool ok = (&str[0] != endPtr);
3656
3657   if ( isOk ) *isOk = ok;
3658
3659   if ( !ok )
3660   {
3661     std::string msg = "Not a real value:'" + str + "'";
3662     throw std::invalid_argument(msg);
3663   }
3664   return val;
3665 }
3666
3667 //================================================================================
3668 /*!
3669  * \brief Converts a string to a integer value
3670  */
3671 //================================================================================
3672
3673 int BLSURFPlugin_Hypothesis::ToInt(const std::string& str, bool* isOk )
3674   throw (std::invalid_argument)
3675 {
3676   if ( str.empty() ) throw std::invalid_argument("Empty value provided");
3677
3678   char * endPtr;
3679   int val = (int)strtol( &str[0], &endPtr, 10);
3680   bool ok = (&str[0] != endPtr);
3681
3682   if ( isOk ) *isOk = ok;
3683
3684   if ( !ok )
3685   {
3686     std::string msg = "Not an integer value:'" + str + "'";
3687     throw std::invalid_argument(msg);
3688   }
3689   return val;
3690 }
3691