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