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