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