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