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