Salome HOME
Merge branch 'master' into V9_dev
[plugins/blsurfplugin.git] / src / BLSURFPlugin / BLSURFPlugin_Hypothesis.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // ---
21 // File    : BLSURFPlugin_Hypothesis.cxx
22 // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA)
23 //           & Aurelien ALLEAUME (DISTENE)
24 //           Size maps development: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE)
25 // ---
26 //
27 #include "BLSURFPlugin_Hypothesis.hxx"
28 #include "BLSURFPlugin_Attractor.hxx"
29 #include "SMESH_Gen_i.hxx"
30 #include <utilities.h>
31 #include <cstring>
32 #include <iostream>
33 #include <sstream>
34
35 // cascade include
36 #include "ShapeAnalysis.hxx"
37
38 // CORBA includes
39 #include CORBA_CLIENT_HEADER(SALOMEDS)
40 #include CORBA_CLIENT_HEADER(GEOM_Gen)
41
42 namespace
43 {
44   struct GET_DEFAULT // struct used to get default value from GetOptionValue()
45   {
46     bool isDefault;
47     operator bool* () { return &isDefault; }
48   };
49 }
50
51 //=============================================================================
52 BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis(int hypId, 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   _quadAllowed(GetDefaultQuadAllowed()),
67   _angleMesh(GetDefaultAngleMesh()),
68   _chordalError(GetDefaultChordalError()), 
69   _anisotropic(GetDefaultAnisotropic()),
70   _anisotropicRatio(GetDefaultAnisotropicRatio()),
71   _removeTinyEdges(GetDefaultRemoveTinyEdges()),
72   _tinyEdgeLength(GetDefaultTinyEdgeLength()),
73   _optimiseTinyEdges(GetDefaultOptimiseTinyEdges()),
74   _tinyEdgeOptimisationLength(GetDefaultTinyEdgeOptimisationLength()),
75   _correctSurfaceIntersec(GetDefaultCorrectSurfaceIntersection()),
76   _corrSurfaceIntersCost(GetDefaultCorrectSurfaceIntersectionMaxCost()),
77   _badElementRemoval(GetDefaultBadElementRemoval()),
78   _badElementAspectRatio(GetDefaultBadElementAspectRatio()),
79   _optimizeMesh(GetDefaultOptimizeMesh()),
80   _quadraticMesh(GetDefaultQuadraticMesh()),
81   _verb(GetDefaultVerbosity()),
82   _topology(GetDefaultTopology()),
83   _preCADMergeEdges(GetDefaultPreCADMergeEdges()),
84   _preCADRemoveDuplicateCADFaces(GetDefaultPreCADRemoveDuplicateCADFaces()),
85   _preCADProcess3DTopology(GetDefaultPreCADProcess3DTopology()),
86   _preCADDiscardInput(GetDefaultPreCADDiscardInput()),
87   _sizeMap(GetDefaultSizeMap()),
88   _attractors(GetDefaultSizeMap()),
89   _classAttractors(GetDefaultAttractorMap()),
90   _faceEntryEnfVertexListMap(GetDefaultFaceEntryEnfVertexListMap()),
91   _enfVertexList(GetDefaultEnfVertexList()),
92   _faceEntryCoordsListMap(GetDefaultFaceEntryCoordsListMap()),
93   _coordsEnfVertexMap(GetDefaultCoordsEnfVertexMap()),
94   _faceEntryEnfVertexEntryListMap(GetDefaultFaceEntryEnfVertexEntryListMap()),
95   _enfVertexEntryEnfVertexMap(GetDefaultEnfVertexEntryEnfVertexMap()),
96   _groupNameNodeIDMap(GetDefaultGroupNameNodeIDMap()),
97   _enforcedInternalVerticesAllFaces(GetDefaultInternalEnforcedVertex()),
98   _preCadFacesPeriodicityVector(GetDefaultPreCadFacesPeriodicityVector()),
99   _preCadEdgesPeriodicityVector(GetDefaultPreCadEdgesPeriodicityVector()),
100   _GMFFileName(GetDefaultGMFFile())
101 {
102   _name = GetHypType(hasgeom);
103   _param_algo_dim = 2;
104   
105 //   _GMFFileMode = false; // GMF ascii mode
106
107   // Advanced options with their defaults according to MG User Manual
108
109   const char* boolOptionNames[] = {         "enforce_cad_edge_sizes",                   // default = 0
110                                             // "correct_surface_intersections",            // default = 1
111                                             // "create_tag_on_collision",                  // default = 1
112                                             "jacobian_rectification_respect_geometry",  // default = 1
113                                             "rectify_jacobian",                         // default = 1
114                                             "respect_geometry",                         // default = 1
115                                             // "optimise_tiny_edges",                      // default = 0
116                                             // "remove_duplicate_cad_faces",               // default = 1
117                                             "tiny_edge_avoid_surface_intersections",    // default = 1
118                                             "debug",                                    // default = 0 
119                                             "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::SetQuadAllowed(bool theVal) {
362   if (theVal != _quadAllowed) {
363     _quadAllowed = theVal;
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     _faceEntryEnfVertexListMap[theFaceEntry].insert(newEnfVertex);
1448     _enfVertexList.insert(newEnfVertex);
1449     if (theVertexEntry == "") {
1450       _faceEntryCoordsListMap[theFaceEntry].insert(newEnfVertex->coords);
1451       _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex;
1452     }
1453     else {
1454       _faceEntryEnfVertexEntryListMap[theFaceEntry].insert(newEnfVertex->geomEntry);
1455       _enfVertexEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex;
1456     }
1457   }
1458
1459   if (toNotify)
1460     NotifySubMeshesHypothesisModification();
1461
1462   return toNotify;
1463 }
1464
1465
1466 //=======================================================================
1467 //function : GetEnforcedVertices
1468 //=======================================================================
1469
1470 BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetEnfVertexList(const TEntry& theFaceEntry)
1471     throw (std::invalid_argument) {
1472
1473   if (_faceEntryEnfVertexListMap.count(theFaceEntry) > 0)
1474     return _faceEntryEnfVertexListMap[theFaceEntry];
1475   else
1476     return GetDefaultEnfVertexList();
1477
1478   std::ostringstream msg;
1479   msg << "No enforced vertex for face entry " << theFaceEntry;
1480   throw std::invalid_argument(msg.str());
1481 }
1482
1483 //=======================================================================
1484 //function : GetEnfVertexCoordsList
1485 //=======================================================================
1486
1487 BLSURFPlugin_Hypothesis::TEnfVertexCoordsList BLSURFPlugin_Hypothesis::GetEnfVertexCoordsList(
1488     const TEntry& theFaceEntry) throw (std::invalid_argument) {
1489
1490   if (_faceEntryCoordsListMap.count(theFaceEntry) > 0)
1491     return _faceEntryCoordsListMap[theFaceEntry];
1492
1493   std::ostringstream msg;
1494   msg << "No enforced vertex coords for face entry " << theFaceEntry;
1495   throw std::invalid_argument(msg.str());
1496 }
1497
1498 //=======================================================================
1499 //function : GetEnfVertexEntryList
1500 //=======================================================================
1501
1502 BLSURFPlugin_Hypothesis::TEntryList BLSURFPlugin_Hypothesis::GetEnfVertexEntryList(const TEntry& theFaceEntry)
1503     throw (std::invalid_argument) {
1504
1505   if (_faceEntryEnfVertexEntryListMap.count(theFaceEntry) > 0)
1506     return _faceEntryEnfVertexEntryListMap[theFaceEntry];
1507
1508   std::ostringstream msg;
1509   msg << "No enforced vertex entry for face entry " << theFaceEntry;
1510   throw std::invalid_argument(msg.str());
1511 }
1512
1513 //=======================================================================
1514 //function : GetEnfVertex(TEnfVertexCoords coords)
1515 //=======================================================================
1516
1517 BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(TEnfVertexCoords coords)
1518     throw (std::invalid_argument) {
1519
1520   if (_coordsEnfVertexMap.count(coords) > 0)
1521     return _coordsEnfVertexMap[coords];
1522
1523   std::ostringstream msg;
1524   msg << "No enforced vertex with coords (" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")";
1525   throw std::invalid_argument(msg.str());
1526 }
1527
1528 //=======================================================================
1529 //function : GetEnfVertex(const TEntry& theEnfVertexEntry)
1530 //=======================================================================
1531
1532 BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(const TEntry& theEnfVertexEntry)
1533     throw (std::invalid_argument) {
1534
1535   if (_enfVertexEntryEnfVertexMap.count(theEnfVertexEntry) > 0)
1536     return _enfVertexEntryEnfVertexMap[theEnfVertexEntry];
1537
1538   std::ostringstream msg;
1539   msg << "No enforced vertex with entry " << theEnfVertexEntry;
1540   throw std::invalid_argument(msg.str());
1541 }
1542
1543 //Enable internal enforced vertices on specific face if requested by user
1544 ////=======================================================================
1545 ////function : GetInternalEnforcedVertex
1546 ////=======================================================================
1547
1548 //bool BLSURFPlugin_Hypothesis::GetInternalEnforcedVertex(const TEntry& theFaceEntry)
1549 //{
1550 //  if (_faceEntryInternalVerticesList.count(theFaceEntry) > 0)
1551 //    return true;
1552 //  return false;
1553 //}
1554
1555 //=======================================================================
1556 //function : ClearEnforcedVertex
1557 //=======================================================================
1558
1559 bool BLSURFPlugin_Hypothesis::ClearEnforcedVertex(const TEntry& theFaceEntry, double x, double y, double z,
1560     const TEntry& theVertexEntry) throw (std::invalid_argument) {
1561
1562   bool toNotify = false;
1563   std::ostringstream msg;
1564   TEnfVertex *oldEnfVertex;
1565   TEnfVertexCoords coords;
1566   coords.clear();
1567   coords.push_back(x);
1568   coords.push_back(y);
1569   coords.push_back(z);
1570
1571   // check that enf vertex with given enf vertex entry exists
1572   TEnfVertexEntryEnfVertexMap::iterator it_enfVertexEntry = _enfVertexEntryEnfVertexMap.find(theVertexEntry);
1573   if (it_enfVertexEntry != _enfVertexEntryEnfVertexMap.end()) {
1574     // Success
1575     oldEnfVertex = it_enfVertexEntry->second;
1576
1577     _enfVertexEntryEnfVertexMap.erase(it_enfVertexEntry);
1578
1579     TEntryList& enfVertexEntryList = _faceEntryEnfVertexEntryListMap[theFaceEntry];
1580     enfVertexEntryList.erase(theVertexEntry);
1581     if (enfVertexEntryList.size() == 0)
1582       _faceEntryEnfVertexEntryListMap.erase(theFaceEntry);
1583     //    TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry);
1584     //    TEntryList::iterator it_entryList = it_entry_entry->second.find(theVertexEntry);
1585     //    it_entry_entry->second.erase(it_entryList);
1586     //    if (it_entry_entry->second.size() == 0)
1587     //      _faceEntryEnfVertexEntryListMap.erase(it_entry_entry);
1588   } else {
1589     // Fail
1590     MESSAGE("Enforced vertex with geom entry " << theVertexEntry << " not found");
1591     msg << "No enforced vertex with geom entry " << theVertexEntry;
1592     // check that enf vertex with given coords exists
1593     TCoordsEnfVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
1594     if (it_coords_enf != _coordsEnfVertexMap.end()) {
1595       // Success
1596       oldEnfVertex = it_coords_enf->second;
1597
1598       _coordsEnfVertexMap.erase(it_coords_enf);
1599
1600       TEnfVertexCoordsList& enfVertexCoordsList = _faceEntryCoordsListMap[theFaceEntry];
1601       enfVertexCoordsList.erase(coords);
1602       if (enfVertexCoordsList.size() == 0)
1603         _faceEntryCoordsListMap.erase(theFaceEntry);
1604       //      TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry);
1605       //      TEnfVertexCoordsList::iterator it_coordsList = it_entry_coords->second.find(coords);
1606       //      it_entry_coords->second.erase(it_coordsList);
1607       //      if (it_entry_coords->second.size() == 0)
1608       //        _faceEntryCoordsListMap.erase(it_entry_coords);
1609     } else {
1610       // Fail
1611       MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found");
1612       msg << std::endl;
1613       msg << "No enforced vertex at " << x << ", " << y << ", " << z;
1614       throw std::invalid_argument(msg.str());
1615     }
1616   }
1617
1618   // update _enfVertexList
1619   TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1620   if (it != _enfVertexList.end()) {
1621     (*it)->faceEntries.erase(theFaceEntry);
1622     if ((*it)->faceEntries.size() == 0){
1623       _enfVertexList.erase(it);
1624       toNotify = true;
1625     }
1626   }
1627
1628   // update _faceEntryEnfVertexListMap
1629   TEnfVertexList& currentEnfVertexList = _faceEntryEnfVertexListMap[theFaceEntry];
1630   currentEnfVertexList.erase(oldEnfVertex);
1631
1632   if (currentEnfVertexList.size() == 0) {
1633     _faceEntryEnfVertexListMap.erase(theFaceEntry);
1634   }
1635
1636   if (toNotify)
1637     NotifySubMeshesHypothesisModification();
1638
1639   return toNotify;
1640 }
1641
1642 //=======================================================================
1643 //function : ClearEnforcedVertices
1644 //=======================================================================
1645
1646 bool BLSURFPlugin_Hypothesis::ClearEnforcedVertices(const TEntry& theFaceEntry) throw (std::invalid_argument) {
1647
1648   bool toNotify = false;
1649   TEnfVertex *oldEnfVertex;
1650
1651   TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry);
1652   if (it_entry_coords != _faceEntryCoordsListMap.end()) {
1653     toNotify = true;
1654     TEnfVertexCoordsList coordsList = it_entry_coords->second;
1655     TEnfVertexCoordsList::iterator it_coordsList = coordsList.begin();
1656     for (; it_coordsList != coordsList.end(); ++it_coordsList) {
1657       TEnfVertexCoords coords = (*it_coordsList);
1658       oldEnfVertex = _coordsEnfVertexMap[coords];
1659       _coordsEnfVertexMap.erase(coords);
1660       // update _enfVertexList
1661       TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1662       if (it != _enfVertexList.end()) {
1663         (*it)->faceEntries.erase(theFaceEntry);
1664         if ((*it)->faceEntries.size() == 0){
1665           _enfVertexList.erase(it);
1666           toNotify = true;
1667         }
1668       }
1669     }
1670     _faceEntryCoordsListMap.erase(it_entry_coords);
1671     _faceEntryEnfVertexListMap.erase(theFaceEntry);
1672   }
1673
1674   TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry);
1675   if (it_entry_entry != _faceEntryEnfVertexEntryListMap.end()) {
1676     toNotify = true;
1677     TEntryList enfVertexEntryList = it_entry_entry->second;
1678     TEntryList::iterator it_enfVertexEntryList = enfVertexEntryList.begin();
1679     for (; it_enfVertexEntryList != enfVertexEntryList.end(); ++it_enfVertexEntryList) {
1680       TEntry enfVertexEntry = (*it_enfVertexEntryList);
1681       oldEnfVertex = _enfVertexEntryEnfVertexMap[enfVertexEntry];
1682       _enfVertexEntryEnfVertexMap.erase(enfVertexEntry);
1683       // update _enfVertexList
1684       TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1685       if (it != _enfVertexList.end()) {
1686         (*it)->faceEntries.erase(theFaceEntry);
1687         if ((*it)->faceEntries.size() == 0){
1688           _enfVertexList.erase(it);
1689           toNotify = true;
1690         }
1691       }
1692     }
1693     _faceEntryEnfVertexEntryListMap.erase(it_entry_entry);
1694     _faceEntryEnfVertexListMap.erase(theFaceEntry);
1695   }
1696
1697   if (toNotify)
1698     NotifySubMeshesHypothesisModification();
1699
1700   return toNotify;
1701   //  std::ostringstream msg;
1702   //  msg << "No enforced vertex for " << theFaceEntry;
1703   //  throw std::invalid_argument(msg.str());
1704 }
1705
1706 //=======================================================================
1707 //function : ClearAllEnforcedVertices
1708 //=======================================================================
1709 void BLSURFPlugin_Hypothesis::ClearAllEnforcedVertices() {
1710   _faceEntryEnfVertexListMap.clear();
1711   _enfVertexList.clear();
1712   _faceEntryCoordsListMap.clear();
1713   _coordsEnfVertexMap.clear();
1714   _faceEntryEnfVertexEntryListMap.clear();
1715   _enfVertexEntryEnfVertexMap.clear();
1716 //  Enable internal enforced vertices on specific face if requested by user
1717 //  _faceEntryInternalVerticesList.clear();
1718   NotifySubMeshesHypothesisModification();
1719 }
1720
1721 //================================================================================
1722 /*!
1723  * \brief Return the enforced vertices
1724  */
1725 //================================================================================
1726
1727
1728 BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByFace(
1729     const BLSURFPlugin_Hypothesis* hyp) {
1730   return hyp ? hyp->_GetAllEnforcedVerticesByFace() : GetDefaultFaceEntryEnfVertexListMap();
1731 }
1732
1733 //Enable internal enforced vertices on specific face if requested by user
1734 //BLSURFPlugin_Hypothesis::TFaceEntryInternalVerticesList BLSURFPlugin_Hypothesis::GetAllInternalEnforcedVerticesByFace(
1735 //    const BLSURFPlugin_Hypothesis* hyp) {
1736 //  return hyp ? hyp->_GetAllInternalEnforcedVerticesByFace() : GetDefaultFaceEntryInternalVerticesMap();
1737 //}
1738
1739 bool BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFaces(const BLSURFPlugin_Hypothesis* hyp)
1740 {
1741   return hyp ? hyp->_GetInternalEnforcedVertexAllFaces() : GetDefaultInternalEnforcedVertex();
1742 }
1743
1744 BLSURFPlugin_Hypothesis::TEnfGroupName BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFacesGroup(const BLSURFPlugin_Hypothesis* hyp)
1745 {
1746   return hyp ? hyp->_GetInternalEnforcedVertexAllFacesGroup() : BLSURFPlugin_Hypothesis::TEnfGroupName();
1747 }
1748
1749 BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetAllEnforcedVertices(
1750     const BLSURFPlugin_Hypothesis* hyp) {
1751   return hyp ? hyp->_GetAllEnforcedVertices() : GetDefaultEnfVertexList();
1752 }
1753
1754 BLSURFPlugin_Hypothesis::TFaceEntryCoordsListMap BLSURFPlugin_Hypothesis::GetAllCoordsByFace(
1755     const BLSURFPlugin_Hypothesis* hyp) {
1756   return hyp ? hyp->_GetAllCoordsByFace() : GetDefaultFaceEntryCoordsListMap();
1757 }
1758
1759 BLSURFPlugin_Hypothesis::TCoordsEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByCoords(
1760     const BLSURFPlugin_Hypothesis* hyp) {
1761   return hyp ? hyp->_GetAllEnforcedVerticesByCoords() : GetDefaultCoordsEnfVertexMap();
1762 }
1763
1764 BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexEntryListMap BLSURFPlugin_Hypothesis::GetAllEnfVertexEntriesByFace(
1765     const BLSURFPlugin_Hypothesis* hyp) {
1766   return hyp ? hyp->_GetAllEnfVertexEntriesByFace() : GetDefaultFaceEntryEnfVertexEntryListMap();
1767 }
1768
1769 BLSURFPlugin_Hypothesis::TEnfVertexEntryEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByEnfVertexEntry(
1770     const BLSURFPlugin_Hypothesis* hyp) {
1771   return hyp ? hyp->_GetAllEnforcedVerticesByEnfVertexEntry() : GetDefaultEnfVertexEntryEnfVertexMap();
1772 }
1773
1774 std::set<int> BLSURFPlugin_Hypothesis::GetEnfVertexNodeIDs(TEnfGroupName theGroupName) throw (std::invalid_argument)
1775 {
1776   TGroupNameNodeIDMap::const_iterator it = _groupNameNodeIDMap.find(theGroupName);
1777   if (it != _groupNameNodeIDMap.end()) {
1778     return it->second;
1779   }
1780   std::ostringstream msg;
1781   msg << "No group " << theGroupName;
1782   throw std::invalid_argument(msg.str());
1783 }
1784
1785 void BLSURFPlugin_Hypothesis::AddEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID)
1786 {
1787   _groupNameNodeIDMap[theGroupName].insert(theNodeID);
1788 }
1789
1790 void BLSURFPlugin_Hypothesis::RemoveEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID) throw (std::invalid_argument)
1791 {
1792   TGroupNameNodeIDMap::iterator it = _groupNameNodeIDMap.find(theGroupName);
1793   if (it != _groupNameNodeIDMap.end()) {
1794     std::set<int>::iterator IDit = it->second.find(theNodeID);
1795     if (IDit != it->second.end())
1796       it->second.erase(IDit);
1797     std::ostringstream msg;
1798     msg << "No node IDs " << theNodeID << " for group " << theGroupName;
1799     throw std::invalid_argument(msg.str());
1800   }
1801   std::ostringstream msg;
1802   msg << "No group " << theGroupName;
1803   throw std::invalid_argument(msg.str());
1804 }
1805
1806
1807 //=============================================================================
1808 void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertexAllFaces(bool toEnforceInternalVertices) {
1809   if (toEnforceInternalVertices != _enforcedInternalVerticesAllFaces) {
1810     _enforcedInternalVerticesAllFaces = toEnforceInternalVertices;
1811     if (toEnforceInternalVertices)
1812       SetPhysicalMesh(PhysicalLocalSize);
1813     NotifySubMeshesHypothesisModification();
1814   }
1815 }
1816
1817
1818 //=============================================================================
1819 void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertexAllFacesGroup(BLSURFPlugin_Hypothesis::TEnfGroupName theGroupName) {
1820   if (std::string(theGroupName) != std::string(_enforcedInternalVerticesAllFacesGroup)) {
1821     _enforcedInternalVerticesAllFacesGroup = theGroupName;
1822     NotifySubMeshesHypothesisModification();
1823   }
1824 }
1825
1826 //=============================================================================
1827 BLSURFPlugin_Hypothesis::TPreCadPeriodicityVector BLSURFPlugin_Hypothesis::GetPreCadFacesPeriodicityVector(
1828     const BLSURFPlugin_Hypothesis* hyp) {
1829   return hyp ? hyp->_GetPreCadFacesPeriodicityVector() : GetDefaultPreCadFacesPeriodicityVector();
1830 }
1831
1832 //=============================================================================
1833 BLSURFPlugin_Hypothesis::TPreCadPeriodicityVector BLSURFPlugin_Hypothesis::GetPreCadEdgesPeriodicityVector(
1834     const BLSURFPlugin_Hypothesis* hyp) {
1835   return hyp ? hyp->_GetPreCadEdgesPeriodicityVector() : GetDefaultPreCadEdgesPeriodicityVector();
1836 }
1837
1838 //=============================================================================
1839 BLSURFPlugin_Hypothesis::TFacesPeriodicityVector BLSURFPlugin_Hypothesis::GetFacesPeriodicityVector(
1840     const BLSURFPlugin_Hypothesis* hyp) {
1841   return hyp ? hyp->_GetFacesPeriodicityVector() : GetDefaultFacesPeriodicityVector();
1842 }
1843
1844 //=============================================================================
1845 BLSURFPlugin_Hypothesis::TEdgesPeriodicityVector BLSURFPlugin_Hypothesis::GetEdgesPeriodicityVector(
1846     const BLSURFPlugin_Hypothesis* hyp){
1847   return hyp ? hyp->_GetEdgesPeriodicityVector() : GetDefaultEdgesPeriodicityVector();
1848 }
1849
1850 //=============================================================================
1851 BLSURFPlugin_Hypothesis::TVerticesPeriodicityVector BLSURFPlugin_Hypothesis::GetVerticesPeriodicityVector(
1852     const BLSURFPlugin_Hypothesis* hyp){
1853   return hyp ? hyp->_GetVerticesPeriodicityVector() : GetDefaultVerticesPeriodicityVector();
1854 }
1855
1856 //=======================================================================
1857 //function : ClearAllEnforcedVertices
1858 //=======================================================================
1859 void BLSURFPlugin_Hypothesis::ClearPreCadPeriodicityVectors() {
1860   _preCadFacesPeriodicityVector.clear();
1861   _preCadEdgesPeriodicityVector.clear();
1862   NotifySubMeshesHypothesisModification();
1863 }
1864
1865 //=======================================================================
1866 //function : AddPreCadFacesPeriodicity
1867 //=======================================================================
1868 void BLSURFPlugin_Hypothesis::AddPreCadFacesPeriodicity(TEntry theFace1Entry, TEntry theFace2Entry,
1869                                                         std::vector<std::string> &theSourceVerticesEntries, std::vector<std::string> &theTargetVerticesEntries) {
1870
1871   TPreCadPeriodicity preCadFacesPeriodicity;
1872   preCadFacesPeriodicity.shape1Entry = theFace1Entry;
1873   preCadFacesPeriodicity.shape2Entry = theFace2Entry;
1874   preCadFacesPeriodicity.theSourceVerticesEntries = theSourceVerticesEntries;
1875   preCadFacesPeriodicity.theTargetVerticesEntries = theTargetVerticesEntries;
1876
1877   _preCadFacesPeriodicityVector.push_back(preCadFacesPeriodicity);
1878
1879   NotifySubMeshesHypothesisModification();
1880 }
1881
1882 //=======================================================================
1883 //function : AddPreCadEdgesPeriodicity
1884 //=======================================================================
1885 void BLSURFPlugin_Hypothesis::AddPreCadEdgesPeriodicity(TEntry theEdge1Entry, TEntry theEdge2Entry,
1886     std::vector<std::string> &theSourceVerticesEntries, std::vector<std::string> &theTargetVerticesEntries) {
1887
1888   TPreCadPeriodicity preCadEdgesPeriodicity;
1889   preCadEdgesPeriodicity.shape1Entry = theEdge1Entry;
1890   preCadEdgesPeriodicity.shape2Entry = theEdge2Entry;
1891   preCadEdgesPeriodicity.theSourceVerticesEntries = theSourceVerticesEntries;
1892   preCadEdgesPeriodicity.theTargetVerticesEntries = theTargetVerticesEntries;
1893
1894   _preCadEdgesPeriodicityVector.push_back(preCadEdgesPeriodicity);
1895
1896   NotifySubMeshesHypothesisModification();
1897 }
1898
1899 //=============================================================================
1900 std::ostream & BLSURFPlugin_Hypothesis::SaveTo(std::ostream & save)
1901 {
1902   // We must keep at least the same number of arguments when increasing the SALOME version
1903   // When MG-CADSurf becomes CADMESH, some parameters were fused into a single one. Thus the same
1904   // parameter can be written several times to keep the old global number of parameters.
1905
1906   // Treat old options which are now in the advanced options
1907   TOptionValues::iterator op_val;
1908   int _decimesh = -1;
1909   int _preCADRemoveNanoEdges = -1;
1910   double _preCADEpsNano = -1.0;
1911   op_val = _option2value.find("respect_geometry");
1912   if (op_val != _option2value.end()) {
1913     std::string value = op_val->second;
1914     if (!value.empty())
1915       _decimesh = value.compare("1") == 0 ? 1 : 0;
1916   }
1917   op_val = _preCADoption2value.find("remove_tiny_edges");
1918   if (op_val != _preCADoption2value.end()) {
1919     std::string value = op_val->second;
1920     if (!value.empty())
1921       _preCADRemoveNanoEdges = value.compare("1") == 0 ? 1 : 0;
1922   }
1923   op_val = _preCADoption2value.find("tiny_edge_length");
1924   if (op_val != _preCADoption2value.end()) {
1925     std::string value = op_val->second;
1926     if (!value.empty())
1927       _preCADEpsNano = strtod(value.c_str(), NULL);
1928   }
1929
1930   save << " " << (int) _topology << " " << (int) _physicalMesh << " " << (int) _geometricMesh << " " << _phySize << " "
1931        << _angleMesh << " " << _gradation << " " << (int) _quadAllowed << " " << _decimesh;
1932   save << " " << _minSize << " " << _maxSize << " " << _angleMesh << " " << _minSize << " " << _maxSize << " " << _verb;
1933   save << " " << (int) _preCADMergeEdges << " " << _preCADRemoveNanoEdges << " " << (int) _preCADDiscardInput << " " << _preCADEpsNano ;
1934   save << " " << (int) _enforcedInternalVerticesAllFaces;
1935   save << " " << (int) _phySizeRel << " " << (int) _minSizeRel << " " << (int) _maxSizeRel << " " << _chordalError ;
1936   save << " " << (int) _anisotropic << " " << _anisotropicRatio << " " << (int) _removeTinyEdges << " " << _tinyEdgeLength ;
1937   save << " " << (int) _badElementRemoval << " " << _badElementAspectRatio << " " << (int) _optimizeMesh << " " << (int) _quadraticMesh ;
1938   save << " " << (int) _preCADProcess3DTopology << " " << (int) _preCADRemoveDuplicateCADFaces;
1939   save << " " << (int)_optimiseTinyEdges << " " << _tinyEdgeOptimisationLength;
1940   save << " " << (int)_correctSurfaceIntersec << " " << _corrSurfaceIntersCost;
1941   save << " " << (int)_useGradation << " " << (int)_useVolumeGradation << " " << _volumeGradation;
1942
1943   op_val = _option2value.begin();
1944   if (op_val != _option2value.end()) {
1945     save << " " << "__OPTIONS_BEGIN__";
1946     for (; op_val != _option2value.end(); ++op_val) {
1947       if (!op_val->second.empty())
1948         save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
1949     }
1950     save << " " << "__OPTIONS_END__";
1951   }
1952   
1953   op_val = _customOption2value.begin();
1954   if (op_val != _customOption2value.end()) {
1955     save << " " << "__CUSTOM_OPTIONS_BEGIN__";
1956     for (; op_val != _customOption2value.end(); ++op_val) {
1957       if (!op_val->second.empty())
1958         save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
1959     }
1960     save << " " << "__CUSTOM_OPTIONS_END__";
1961   }
1962
1963   op_val = _preCADoption2value.begin();
1964   if (op_val != _preCADoption2value.end()) {
1965     save << " " << "__PRECAD_OPTIONS_BEGIN__";
1966     for (; op_val != _preCADoption2value.end(); ++op_val) {
1967       if (!op_val->second.empty())
1968         save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
1969     }
1970     save << " " << "__PRECAD_OPTIONS_END__";
1971   }
1972
1973   TSizeMap::iterator it_sm = _sizeMap.begin();
1974   if (it_sm != _sizeMap.end()) {
1975     save << " " << "__SIZEMAP_BEGIN__";
1976     for (; it_sm != _sizeMap.end(); ++it_sm) {
1977       save << " " << it_sm->first << " " << it_sm->second << "%#"; // "%#" is a mark of value end
1978     }
1979     save << " " << "__SIZEMAP_END__";
1980   }
1981
1982   TSizeMap::iterator it_at = _attractors.begin();
1983   if (it_at != _attractors.end()) {
1984     save << " " << "__ATTRACTORS_BEGIN__";
1985     for (; it_at != _attractors.end(); ++it_at) {
1986       save << " " << it_at->first << " " << it_at->second << "%#"; // "%#" is a mark of value end
1987     }
1988     save << " " << "__ATTRACTORS_END__";
1989   }
1990   
1991   TAttractorMap::iterator it_At = _classAttractors.begin();
1992   if (it_At != _classAttractors.end()) {
1993     std::ostringstream test;
1994     save << " " << "__NEW_ATTRACTORS_BEGIN__";
1995     test << " " << "__NEW_ATTRACTORS_BEGIN__";
1996     for (; it_At != _classAttractors.end(); ++it_At) {
1997       std::vector<double> attParams;
1998       attParams   = it_At->second->GetParameters();
1999 //       double step = it_At->second->GetStep();
2000       save << " " << it_At->first;
2001       save << " " << it_At->second->GetAttractorEntry();
2002       save << " " << attParams[0]  << " " <<  attParams[1] << " " <<  attParams[2] << " " <<  attParams[3];
2003 //       save << " " << step;
2004       test << " " << it_At->first;
2005       test << " " << it_At->second->GetAttractorEntry();
2006       test << " " << attParams[0]  << " " <<  attParams[1] << " " <<  attParams[2] << " " <<  attParams[3];
2007 //       test << " " << step;
2008     }
2009     save << " " << "__NEW_ATTRACTORS_END__";
2010     test << " " << "__NEW_ATTRACTORS_END__";
2011   }
2012
2013   TEnfVertexList::const_iterator it_enf = _enfVertexList.begin();
2014   if (it_enf != _enfVertexList.end()) {
2015     save << " " << "__ENFORCED_VERTICES_BEGIN__";
2016     for (; it_enf != _enfVertexList.end(); ++it_enf) {
2017       TEnfVertex *enfVertex = (*it_enf);
2018       save << " " << "__BEGIN_VERTEX__";
2019       if (!enfVertex->name.empty()) {
2020         save << " " << "__BEGIN_NAME__";
2021         save << " " << enfVertex->name;
2022         save << " " << "__END_NAME__";
2023       }
2024       if (!enfVertex->geomEntry.empty()) {
2025         save << " " << "__BEGIN_ENTRY__";
2026         save << " " << enfVertex->geomEntry;
2027         save << " " << "__END_ENTRY__";
2028       }
2029       if (!enfVertex->grpName.empty()) {
2030         save << " " << "__BEGIN_GROUP__";
2031         save << " " << enfVertex->grpName;
2032         save << " " << "__END_GROUP__";
2033       }
2034       if (enfVertex->coords.size()) {
2035         save << " " << "__BEGIN_COORDS__";
2036         for ( size_t i = 0; i < enfVertex->coords.size(); i++ )
2037           save << " " << enfVertex->coords[i];
2038         save << " " << "__END_COORDS__";
2039       }
2040       TEntryList::const_iterator faceEntriesIt = enfVertex->faceEntries.begin();
2041       bool hasFaces = false;
2042       if (faceEntriesIt != enfVertex->faceEntries.end()) {
2043         hasFaces = true;
2044         save << " " << "__BEGIN_FACELIST__";
2045       }
2046       for (; faceEntriesIt != enfVertex->faceEntries.end(); ++faceEntriesIt)
2047         if ( faceEntriesIt->empty() )
2048           save << " _no_face_";
2049         else
2050           save << " " << (*faceEntriesIt);
2051       if (hasFaces)
2052         save << " " << "__END_FACELIST__";
2053       save << " " << "__END_VERTEX__";
2054     }
2055     save << " " << "__ENFORCED_VERTICES_END__";
2056   }
2057
2058   //PERIODICITY
2059
2060   SavePreCADPeriodicity(save, "FACES");
2061   SavePreCADPeriodicity(save, "EDGES");
2062
2063   SaveFacesPeriodicity(save);
2064   SaveEdgesPeriodicity(save);
2065   SaveVerticesPeriodicity(save);
2066
2067   // HYPER-PATCHES
2068   save << " " << _hyperPatchList.size() << " ";
2069   for ( size_t i = 0; i < _hyperPatchList.size(); ++i )
2070   {
2071     THyperPatchTags& patch = _hyperPatchList[i];
2072     save << patch.size() << " ";
2073     THyperPatchTags::iterator tag = patch.begin();
2074     for ( ; tag != patch.end(); ++tag )
2075       save << *tag << " ";
2076   }
2077
2078   return save;
2079 }
2080
2081 void BLSURFPlugin_Hypothesis::SaveFacesPeriodicity(std::ostream & save){
2082
2083   TFacesPeriodicityVector::const_iterator it_faces_periodicity = _facesPeriodicityVector.begin();
2084   if (it_faces_periodicity != _facesPeriodicityVector.end()) {
2085     save << " " << "__FACES_PERIODICITY_BEGIN__";
2086     for (; it_faces_periodicity != _facesPeriodicityVector.end(); ++it_faces_periodicity) {
2087       TFacesPeriodicity periodicity_i = (*it_faces_periodicity);
2088       save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2089       save << " " << "__BEGIN_ENTRY1__";
2090       save << " " << periodicity_i.first;
2091       save << " " << "__END_ENTRY1__";
2092       save << " " << "__BEGIN_ENTRY2__";
2093       save << " " << periodicity_i.second;
2094       save << " " << "__END_ENTRY2__";
2095       save << " " << "__END_PERIODICITY_DESCRIPTION__";
2096     }
2097     save << " " << "__FACES_PERIODICITY_END__";
2098   }
2099 }
2100
2101 void BLSURFPlugin_Hypothesis::SaveEdgesPeriodicity(std::ostream & save){
2102
2103   TEdgesPeriodicityVector::const_iterator it_edges_periodicity = _edgesPeriodicityVector.begin();
2104   if (it_edges_periodicity != _edgesPeriodicityVector.end()) {
2105     save << " " << "__EDGES_PERIODICITY_BEGIN__";
2106     for (; it_edges_periodicity != _edgesPeriodicityVector.end(); ++it_edges_periodicity) {
2107       TEdgePeriodicity periodicity_i = (*it_edges_periodicity);
2108       save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2109       if (! periodicity_i.theFace1Entry.empty()){
2110         save << " " << "__BEGIN_FACE1__";
2111         save << " " << periodicity_i.theFace1Entry;
2112         save << " " << "__END_FACE1__";
2113       }
2114       save << " " << "__BEGIN_EDGE1__";
2115       save << " " << periodicity_i.theEdge1Entry;
2116       save << " " << "__END_EDGE1__";
2117       if (! periodicity_i.theFace2Entry.empty()){
2118         save << " " << "__BEGIN_FACE2__";
2119         save << " " << periodicity_i.theFace2Entry;
2120         save << " " << "__END_FACE2__";
2121       }
2122       save << " " << "__BEGIN_EDGE2__";
2123       save << " " << periodicity_i.theEdge2Entry;
2124       save << " " << "__END_EDGE2__";
2125       save << " " << "__BEGIN_EDGE_ORIENTATION__";
2126       save << " " << periodicity_i.edge_orientation;
2127       save << " " << "__END_EDGE_ORIENTATION__";
2128       save << " " << "__END_PERIODICITY_DESCRIPTION__";
2129     }
2130     save << " " << "__EDGES_PERIODICITY_END__";
2131   }
2132 }
2133
2134 void BLSURFPlugin_Hypothesis::SaveVerticesPeriodicity(std::ostream & save){
2135
2136   TVerticesPeriodicityVector::const_iterator it_vertices_periodicity = _verticesPeriodicityVector.begin();
2137   if (it_vertices_periodicity != _verticesPeriodicityVector.end()) {
2138     save << " " << "__VERTICES_PERIODICITY_BEGIN__";
2139     for (; it_vertices_periodicity != _verticesPeriodicityVector.end(); ++it_vertices_periodicity) {
2140       TVertexPeriodicity periodicity_i = (*it_vertices_periodicity);
2141       save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2142       save << " " << "__BEGIN_EDGE1__";
2143       save << " " << periodicity_i.theEdge1Entry;
2144       save << " " << "__END_EDGE1__";
2145       save << " " << "__BEGIN_VERTEX1__";
2146       save << " " << periodicity_i.theVertex1Entry;
2147       save << " " << "__END_VERTEX1__";
2148       save << " " << "__BEGIN_EDGE2__";
2149       save << " " << periodicity_i.theEdge2Entry;
2150       save << " " << "__END_EDGE2__";
2151       save << " " << "__BEGIN_VERTEX2__";
2152       save << " " << periodicity_i.theVertex2Entry;
2153       save << " " << "__END_VERTEX2__";
2154       save << " " << "__END_PERIODICITY_DESCRIPTION__";
2155     }
2156     save << " " << "__VERTICES_PERIODICITY_END__";
2157   }
2158 }
2159
2160 void BLSURFPlugin_Hypothesis::SavePreCADPeriodicity(std::ostream & save, const char* shapeType) {
2161   TPreCadPeriodicityVector precad_periodicity;
2162   if ( shapeType  &&  strcmp( shapeType, "FACES" ) == 0 )
2163     precad_periodicity = _preCadFacesPeriodicityVector;
2164   else
2165     precad_periodicity = _preCadEdgesPeriodicityVector;
2166   TPreCadPeriodicityVector::const_iterator it_precad_periodicity = precad_periodicity.begin();
2167   if (it_precad_periodicity != precad_periodicity.end()) {
2168     save << " " << "__PRECAD_" << shapeType << "_PERIODICITY_BEGIN__";
2169     for (; it_precad_periodicity != precad_periodicity.end(); ++it_precad_periodicity) {
2170       TPreCadPeriodicity periodicity_i = (*it_precad_periodicity);
2171       save << " " << "__BEGIN_PERIODICITY_DESCRIPTION__";
2172       if (!periodicity_i.shape1Entry.empty()) {
2173         save << " " << "__BEGIN_ENTRY1__";
2174         save << " " << periodicity_i.shape1Entry;
2175         save << " " << "__END_ENTRY1__";
2176       }
2177       if (!periodicity_i.shape2Entry.empty()) {
2178         save << " " << "__BEGIN_ENTRY2__";
2179         save << " " << periodicity_i.shape2Entry;
2180         save << " " << "__END_ENTRY2__";
2181       }
2182
2183       std::vector<std::string>::const_iterator sourceVerticesEntriesIt = periodicity_i.theSourceVerticesEntries.begin();
2184       bool hasSourceVertices = false;
2185       if (sourceVerticesEntriesIt != periodicity_i.theSourceVerticesEntries.end()) {
2186         hasSourceVertices = true;
2187         save << " " << "__BEGIN_SOURCE_VERTICES_LIST__";
2188       }
2189       for (; sourceVerticesEntriesIt != periodicity_i.theSourceVerticesEntries.end(); ++sourceVerticesEntriesIt)
2190         save << " " << (*sourceVerticesEntriesIt);
2191       if (hasSourceVertices)
2192         save << " " << "__END_SOURCE_VERTICES_LIST__";
2193
2194       std::vector<std::string>::const_iterator targetVerticesEntriesIt = periodicity_i.theTargetVerticesEntries.begin();
2195       bool hasTargetVertices = false;
2196       if (targetVerticesEntriesIt != periodicity_i.theTargetVerticesEntries.end()) {
2197         hasTargetVertices = true;
2198         save << " " << "__BEGIN_TARGET_VERTICES_LIST__";
2199       }
2200       for (; targetVerticesEntriesIt != periodicity_i.theTargetVerticesEntries.end(); ++targetVerticesEntriesIt)
2201         save << " " << (*targetVerticesEntriesIt);
2202       if (hasTargetVertices)
2203         save << " " << "__END_TARGET_VERTICES_LIST__";
2204
2205       save << " " << "__END_PERIODICITY_DESCRIPTION__";
2206     }
2207     save << " " << "__PRECAD_" << shapeType << "_PERIODICITY_END__";
2208   }
2209
2210 }
2211
2212 //=============================================================================
2213 std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load)
2214 {
2215   bool isOK = true;
2216   int i;
2217   double val;
2218   std::string option_or_sm;
2219
2220   isOK = static_cast<bool>(load >> i);
2221   if (isOK)
2222     _topology = (Topology) i;
2223   else
2224     load.clear(std::ios::badbit | load.rdstate());
2225
2226   isOK = static_cast<bool>(load >> i);
2227   if (isOK)
2228     _physicalMesh = (PhysicalMesh) i;
2229   else
2230     load.clear(std::ios::badbit | load.rdstate());
2231
2232   isOK = static_cast<bool>(load >> i);
2233   if (isOK)
2234     _geometricMesh = (GeometricMesh) i;
2235   else
2236     load.clear(std::ios::badbit | load.rdstate());
2237
2238   isOK = static_cast<bool>(load >> val);
2239   if (isOK)
2240     _phySize = val;
2241   else
2242     load.clear(std::ios::badbit | load.rdstate());
2243
2244   isOK = static_cast<bool>(load >> val);
2245   if (isOK)
2246     _angleMesh = val;
2247   else
2248     load.clear(std::ios::badbit | load.rdstate());
2249
2250   isOK = static_cast<bool>(load >> val);
2251   if (isOK)
2252     _gradation = val;
2253   else
2254     load.clear(std::ios::badbit | load.rdstate());
2255
2256   isOK = static_cast<bool>(load >> i);
2257   if (isOK)
2258     _quadAllowed = (bool) i;
2259   else
2260     load.clear(std::ios::badbit | load.rdstate());
2261
2262   isOK = static_cast<bool>(load >> i);
2263   if (isOK) {
2264     if ( i != -1) { // if value is -1, then this is no longer a standard option
2265       std::string & value = _option2value["respect_geometry"];
2266       bool _decimesh = (bool) i;
2267       value = _decimesh ? "1" : "0";
2268     }
2269   }
2270   else
2271     load.clear(std::ios::badbit | load.rdstate());
2272
2273   isOK = static_cast<bool>(load >> val);
2274   if (isOK)
2275     _minSize = val;
2276   else
2277     load.clear(std::ios::badbit | load.rdstate());
2278
2279   isOK = static_cast<bool>(load >> val);
2280   if (isOK)
2281     _maxSize = val;
2282   else
2283     load.clear(std::ios::badbit | load.rdstate());
2284
2285   isOK = static_cast<bool>(load >> val);
2286   if (isOK)
2287     // former parameter: get min value
2288     _angleMesh = std::min(val,_angleMesh);
2289   else
2290     load.clear(std::ios::badbit | load.rdstate());
2291
2292   isOK = static_cast<bool>(load >> val);
2293   if (isOK)
2294     // former parameter: get min value
2295     _minSize = std::min(val,_minSize);
2296   else
2297     load.clear(std::ios::badbit | load.rdstate());
2298
2299   isOK = static_cast<bool>(load >> val);
2300   if (isOK)
2301     // former parameter: get max value
2302     _maxSize = std::max(val,_maxSize);
2303   else
2304     load.clear(std::ios::badbit | load.rdstate());
2305
2306   isOK = static_cast<bool>(load >> i);
2307   if (isOK)
2308     _verb = i;
2309   else
2310     load.clear(std::ios::badbit | load.rdstate());
2311
2312   isOK = static_cast<bool>(load >> i);
2313   if (isOK)
2314     _preCADMergeEdges = (bool) i;
2315   else
2316     load.clear(std::ios::badbit | load.rdstate());
2317
2318   isOK = static_cast<bool>(load >> i);
2319   if (isOK) {
2320     if ( i != -1) { // if value is -1, then this is no longer a standard option
2321       std::string & value = _preCADoption2value["remove_tiny_edges"];
2322       bool _preCADRemoveNanoEdges = (bool) i;
2323       value = _preCADRemoveNanoEdges ? "1" : "0";
2324     }
2325   }
2326   else
2327     load.clear(std::ios::badbit | load.rdstate());
2328
2329   isOK = static_cast<bool>(load >> i);
2330   if (isOK)
2331     _preCADDiscardInput = (bool) i;
2332   else
2333     load.clear(std::ios::badbit | load.rdstate());
2334
2335   isOK = static_cast<bool>(load >> val);
2336   if (isOK) { // _preCADEpsNano
2337     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
2338       std::string & value = _preCADoption2value["tiny_edge_length"];
2339       std::ostringstream oss;
2340       oss << i;
2341       value = oss.str();
2342     }
2343   }
2344   else
2345     load.clear(std::ios::badbit | load.rdstate());
2346
2347   isOK = static_cast<bool>(load >> i);
2348   if (isOK)
2349     _enforcedInternalVerticesAllFaces = (bool) i;
2350   else
2351     load.clear(std::ios::badbit | load.rdstate());
2352
2353   // New options with MeshGems-CADSurf
2354
2355   bool hasCADSurfOptions = false;
2356   bool hasOptions = false;
2357   bool hasCustomOptions = false;
2358   bool hasPreCADOptions = false;
2359   bool hasSizeMap = false;
2360   bool hasAttractor = false;
2361   bool hasNewAttractor = false;
2362   bool hasEnforcedVertex = false;
2363   bool hasPreCADFacesPeriodicity = false;
2364   bool hasPreCADEdgesPeriodicity = false;
2365   bool hasFacesPeriodicity = false;
2366   bool hasEdgesPeriodicity = false;
2367   bool hasVerticesPeriodicity = false;
2368
2369   isOK = static_cast<bool>(load >> option_or_sm);
2370   if (isOK)
2371     if ( (option_or_sm == "1")||(option_or_sm == "0") ) {
2372       i = atoi(option_or_sm.c_str());
2373       hasCADSurfOptions = true;
2374       _phySizeRel = (bool) i;
2375     }
2376     if (option_or_sm == "__OPTIONS_BEGIN__")
2377       hasOptions = true;
2378     else if (option_or_sm == "__CUSTOM_OPTIONS_BEGIN__")
2379       hasCustomOptions = true;
2380     else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2381       hasPreCADOptions = true;
2382     else if (option_or_sm == "__SIZEMAP_BEGIN__")
2383       hasSizeMap = true;
2384     else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2385       hasAttractor = true;
2386     else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2387       hasNewAttractor = true;
2388     else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2389       hasEnforcedVertex = true;
2390     else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2391       hasPreCADFacesPeriodicity = true;
2392     else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2393       hasPreCADEdgesPeriodicity = true;
2394     else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2395       hasFacesPeriodicity = true;
2396     else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2397       hasEdgesPeriodicity = true;
2398     else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2399       hasVerticesPeriodicity = true;
2400
2401   if (isOK && hasCADSurfOptions) {
2402     isOK = static_cast<bool>(load >> i);
2403     if (isOK)
2404       _minSizeRel = (bool) i;
2405     else
2406       load.clear(std::ios::badbit | load.rdstate());
2407
2408     isOK = static_cast<bool>(load >> i);
2409     if (isOK)
2410       _maxSizeRel = (bool) i;
2411     else
2412       load.clear(std::ios::badbit | load.rdstate());
2413
2414     isOK = static_cast<bool>(load >> val);
2415     if (isOK)
2416       _chordalError = val;
2417     else
2418       load.clear(std::ios::badbit | load.rdstate());
2419
2420     isOK = static_cast<bool>(load >> i);
2421     if (isOK)
2422       _anisotropic = (bool) i;
2423     else
2424       load.clear(std::ios::badbit | load.rdstate());
2425
2426     isOK = static_cast<bool>(load >> val);
2427     if (isOK)
2428       _anisotropicRatio = val;
2429     else
2430       load.clear(std::ios::badbit | load.rdstate());
2431
2432     isOK = static_cast<bool>(load >> i);
2433     if (isOK)
2434       _removeTinyEdges = (bool) i;
2435     else
2436       load.clear(std::ios::badbit | load.rdstate());
2437
2438     isOK = static_cast<bool>(load >> val);
2439     if (isOK)
2440       _tinyEdgeLength = val;
2441     else
2442       load.clear(std::ios::badbit | load.rdstate());
2443
2444     isOK = static_cast<bool>(load >> i);
2445     if (isOK)
2446       _badElementRemoval = (bool) i;
2447     else
2448       load.clear(std::ios::badbit | load.rdstate());
2449
2450     isOK = static_cast<bool>(load >> val);
2451     if (isOK)
2452       _badElementAspectRatio = val;
2453     else
2454       load.clear(std::ios::badbit | load.rdstate());
2455
2456     isOK = static_cast<bool>(load >> i);
2457     if (isOK)
2458       _optimizeMesh = (bool) i;
2459     else
2460       load.clear(std::ios::badbit | load.rdstate());
2461
2462     isOK = static_cast<bool>(load >> i);
2463     if (isOK)
2464       _quadraticMesh = (bool) i;
2465     else
2466       load.clear(std::ios::badbit | load.rdstate());
2467
2468     isOK = static_cast<bool>(load >> i);
2469     if (isOK)
2470       _preCADProcess3DTopology = (bool) i;
2471     else
2472       load.clear(std::ios::badbit | load.rdstate());
2473
2474     if (( load >> std::ws).peek() != '_' )
2475     {
2476       isOK = static_cast<bool>(load >> i);
2477       if (isOK)
2478         _preCADRemoveDuplicateCADFaces = (bool) i;
2479       else
2480         load.clear(std::ios::badbit | load.rdstate());
2481
2482       isOK = static_cast<bool>(load >> i);
2483       if (isOK)
2484         _optimiseTinyEdges = (bool) i;
2485       else
2486         load.clear(std::ios::badbit | load.rdstate());
2487
2488       isOK = static_cast<bool>(load >> val);
2489       if (isOK)
2490         _tinyEdgeOptimisationLength = val;
2491       else
2492         load.clear(std::ios::badbit | load.rdstate());
2493
2494       isOK = static_cast<bool>(load >> i);
2495       if (isOK)
2496         _correctSurfaceIntersec = (bool) i;
2497       else
2498         load.clear(std::ios::badbit | load.rdstate());
2499
2500       isOK = static_cast<bool>(load >> val);
2501       if (isOK)
2502         _corrSurfaceIntersCost = val;
2503       else
2504         load.clear(std::ios::badbit | load.rdstate());
2505
2506       isOK = static_cast<bool>(load >> i);
2507       if (isOK)
2508         _useGradation = (bool) i;
2509       else
2510         load.clear(std::ios::badbit | load.rdstate());
2511
2512       isOK = static_cast<bool>(load >> i);
2513       if (isOK)
2514         _useVolumeGradation = (bool) i;
2515       else
2516         load.clear(std::ios::badbit | load.rdstate());
2517
2518       isOK = static_cast<bool>(load >> val);
2519       if (isOK)
2520         _volumeGradation = val;
2521       else
2522         load.clear(std::ios::badbit | load.rdstate());
2523     }
2524   }
2525
2526
2527   if (hasCADSurfOptions) {
2528     isOK = static_cast<bool>(load >> option_or_sm);
2529     if (isOK) {
2530       if (option_or_sm == "__OPTIONS_BEGIN__")
2531         hasOptions = true;
2532       else if (option_or_sm == "__CUSTOM_OPTIONS_BEGIN__")
2533         hasCustomOptions = true;
2534       else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2535         hasPreCADOptions = true;
2536       else if (option_or_sm == "__SIZEMAP_BEGIN__")
2537         hasSizeMap = true;
2538       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2539         hasAttractor = true;
2540       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2541         hasNewAttractor = true;
2542       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2543         hasEnforcedVertex = true;
2544       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2545         hasPreCADFacesPeriodicity = true;
2546       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2547         hasPreCADEdgesPeriodicity = true;
2548       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2549         hasFacesPeriodicity = true;
2550       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2551         hasEdgesPeriodicity = true;
2552       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2553         hasVerticesPeriodicity = true;
2554     }
2555   }
2556   
2557   std::string optName, optValue;
2558   while (isOK && hasOptions) {
2559     isOK = static_cast<bool>(load >> optName);
2560     if (isOK) {
2561       if (optName == "__OPTIONS_END__")
2562         break;
2563       isOK = static_cast<bool>(load >> optValue);
2564     }
2565     if (isOK) {
2566       std::string & value = _option2value[optName];
2567       value = optValue;
2568       int len = value.size();
2569       // continue reading until "%#" encountered
2570       while (value[len - 1] != '#' || value[len - 2] != '%') {
2571         isOK = static_cast<bool>(load >> optValue);
2572         if (isOK) {
2573           value += " ";
2574           value += optValue;
2575           len = value.size();
2576         } else {
2577           break;
2578         }
2579       }
2580       if ( value[ len - 1] == '#' )
2581         value.resize(len - 2); //cut off "%#"
2582     }
2583   }
2584
2585   if (hasOptions) {
2586     isOK = static_cast<bool>(load >> option_or_sm);
2587     if (isOK) {
2588       if (option_or_sm == "__CUSTOM_OPTIONS_BEGIN__")
2589         hasCustomOptions = true;
2590       else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2591         hasPreCADOptions = true;
2592       else if (option_or_sm == "__SIZEMAP_BEGIN__")
2593         hasSizeMap = true;
2594       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2595         hasAttractor = true;
2596       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2597         hasNewAttractor = true;
2598       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2599         hasEnforcedVertex = true;
2600       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2601         hasPreCADFacesPeriodicity = true;
2602       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2603         hasPreCADEdgesPeriodicity = true;
2604       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2605         hasFacesPeriodicity = true;
2606       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2607         hasEdgesPeriodicity = true;
2608       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2609         hasVerticesPeriodicity = true;
2610     }
2611   }
2612
2613   while (isOK && hasCustomOptions) {
2614     isOK = static_cast<bool>(load >> optName);
2615     if (isOK) {
2616       if (optName == "__CUSTOM_OPTIONS_END__")
2617         break;
2618       isOK = static_cast<bool>(load >> optValue);
2619     }
2620     if (isOK) {
2621       std::string& value = optValue;
2622       int len = value.size();
2623       // continue reading until "%#" encountered
2624       while (value[len - 1] != '#' || value[len - 2] != '%') {
2625         isOK = static_cast<bool>(load >> optValue);
2626         if (isOK) {
2627           value += " ";
2628           value += optValue;
2629           len = value.size();
2630         } else {
2631           break;
2632         }
2633       }
2634       if ( value[ len - 1] == '#' )
2635         value.resize(len - 2); //cut off "%#"
2636       _customOption2value[optName] = value;
2637     }
2638   }
2639
2640   if (hasCustomOptions) {
2641     isOK = static_cast<bool>(load >> option_or_sm);
2642     if (isOK) {
2643       if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
2644         hasPreCADOptions = true;
2645       else if (option_or_sm == "__SIZEMAP_BEGIN__")
2646         hasSizeMap = true;
2647       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2648         hasAttractor = true;
2649       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2650         hasNewAttractor = true;
2651       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2652         hasEnforcedVertex = true;
2653       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2654         hasPreCADFacesPeriodicity = true;
2655       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2656         hasPreCADEdgesPeriodicity = true;
2657       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2658         hasFacesPeriodicity = true;
2659       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2660         hasEdgesPeriodicity = true;
2661       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2662         hasVerticesPeriodicity = true;
2663     }
2664   }
2665
2666   while (isOK && hasPreCADOptions) {
2667     isOK = static_cast<bool>(load >> optName);
2668     if (isOK) {
2669       if (optName == "__PRECAD_OPTIONS_END__")
2670         break;
2671       isOK = static_cast<bool>(load >> optValue);
2672     }
2673     if (isOK) {
2674       std::string & value = _preCADoption2value[optName];
2675       value = optValue;
2676       int len = value.size();
2677       // continue reading until "%#" encountered
2678       while (value[len - 1] != '#' || value[len - 2] != '%') {
2679         isOK = static_cast<bool>(load >> optValue);
2680         if (isOK) {
2681           value += " ";
2682           value += optValue;
2683           len = value.size();
2684         } else {
2685           break;
2686         }
2687       }
2688       if ( value[ len - 1] == '#' )
2689         value.resize(len - 2); //cut off "%#"
2690     }
2691   }
2692
2693   if (hasPreCADOptions) {
2694     isOK = static_cast<bool>(load >> option_or_sm);
2695     if (isOK) {
2696       if (option_or_sm == "__SIZEMAP_BEGIN__")
2697         hasSizeMap = true;
2698       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
2699         hasAttractor = true;
2700       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2701         hasNewAttractor = true;
2702       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2703         hasEnforcedVertex = true;
2704       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2705         hasPreCADFacesPeriodicity = true;
2706       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2707         hasPreCADEdgesPeriodicity = true;
2708       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2709         hasFacesPeriodicity = true;
2710       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2711         hasEdgesPeriodicity = true;
2712       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2713         hasVerticesPeriodicity = true;
2714     }
2715   }
2716  
2717   std::string smEntry, smValue;
2718   while (isOK && hasSizeMap) {
2719     isOK = static_cast<bool>(load >> smEntry);
2720     if (isOK) {
2721       if (smEntry == "__SIZEMAP_END__")
2722         break;
2723       isOK = static_cast<bool>(load >> smValue);
2724     }
2725     if (isOK) {
2726       std::string & value2 = _sizeMap[smEntry];
2727       value2 = smValue;
2728       int len2 = value2.size();
2729       // continue reading until "%#" encountered
2730       while (value2[len2 - 1] != '#' || value2[len2 - 2] != '%') {
2731         isOK = static_cast<bool>(load >> smValue);
2732         if (isOK) {
2733           value2 += " ";
2734           value2 += smValue;
2735           len2 = value2.size();
2736         } else {
2737           break;
2738         }
2739       }
2740       value2.resize(len2 - 2); //cut off "%#"
2741     }
2742   }
2743
2744   if (hasSizeMap) {
2745     isOK = static_cast<bool>(load >> option_or_sm);
2746     if (isOK)
2747       if (option_or_sm == "__ATTRACTORS_BEGIN__")
2748         hasAttractor = true;
2749       if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2750         hasNewAttractor = true;
2751       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2752         hasEnforcedVertex = true;
2753       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2754         hasPreCADFacesPeriodicity = true;
2755       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2756         hasPreCADEdgesPeriodicity = true;
2757       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2758         hasFacesPeriodicity = true;
2759       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2760         hasEdgesPeriodicity = true;
2761       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2762         hasVerticesPeriodicity = true;
2763   }
2764
2765   std::string atEntry, atValue;
2766   while (isOK && hasAttractor) {
2767     isOK = static_cast<bool>(load >> atEntry);
2768     if (isOK) {
2769       if (atEntry == "__ATTRACTORS_END__")
2770         break;
2771       isOK = static_cast<bool>(load >> atValue);
2772     }
2773     if (isOK) {
2774       std::string & value3 = _attractors[atEntry];
2775       value3 = atValue;
2776       int len3 = value3.size();
2777       // continue reading until "%#" encountered
2778       while (value3[len3 - 1] != '#' || value3[len3 - 2] != '%') {
2779         isOK = static_cast<bool>(load >> atValue);
2780         if (isOK) {
2781           value3 += " ";
2782           value3 += atValue;
2783           len3 = value3.size();
2784         } else {
2785           break;
2786         }
2787       }
2788       value3.resize(len3 - 2); //cut off "%#"
2789     }
2790   }
2791
2792   if (hasAttractor) {
2793     isOK = static_cast<bool>(load >> option_or_sm);
2794     if (isOK) {
2795       if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
2796         hasNewAttractor = true;
2797       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2798         hasEnforcedVertex = true;
2799       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2800         hasPreCADFacesPeriodicity = true;
2801       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2802         hasPreCADEdgesPeriodicity = true;
2803       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2804         hasFacesPeriodicity = true;
2805       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2806         hasEdgesPeriodicity = true;
2807       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2808         hasVerticesPeriodicity = true;
2809     }
2810   }
2811
2812   std::string newAtFaceEntry, atTestString;
2813   std::string newAtShapeEntry;
2814   double attParams[4];
2815   //double step;
2816   while (isOK && hasNewAttractor) {
2817     //std::cout<<"Load new attractor"<<std::endl;
2818     isOK = static_cast<bool>(load >> newAtFaceEntry);
2819     if (isOK) {
2820       if (newAtFaceEntry == "__NEW_ATTRACTORS_END__")
2821         break;
2822       isOK = static_cast<bool>(load >> newAtShapeEntry);
2823       if (!isOK)
2824     break;
2825       isOK = static_cast<bool>(load >> attParams[0]>>attParams[1]>>attParams[2]>>attParams[3]); //>>step);
2826     }
2827     if (isOK) {
2828       const TopoDS_Shape attractorShape = BLSURFPlugin_Hypothesis::entryToShape(newAtShapeEntry);
2829       const TopoDS_Face faceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(newAtFaceEntry));
2830       BLSURFPlugin_Attractor* attractor = new BLSURFPlugin_Attractor(faceShape, attractorShape, newAtShapeEntry);//, step);
2831       attractor->SetParameters(attParams[0], attParams[1], attParams[2], attParams[3]);
2832       //attractor->BuildMap();                     
2833       _classAttractors.insert( make_pair( newAtFaceEntry, attractor ));
2834     }
2835   }
2836   
2837   
2838   if (hasNewAttractor) {
2839     isOK = static_cast<bool>(load >> option_or_sm);
2840     if (isOK) {
2841       if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
2842         hasEnforcedVertex = true;
2843       else if (option_or_sm == "__PRECAD_FACES_PERIODICITY_BEGIN__")
2844         hasPreCADFacesPeriodicity = true;
2845       else if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2846         hasPreCADEdgesPeriodicity = true;
2847       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2848         hasFacesPeriodicity = true;
2849       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2850         hasEdgesPeriodicity = true;
2851       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2852         hasVerticesPeriodicity = true;
2853     }
2854   }
2855
2856
2857 // 
2858 // Here is a example of the saved stream:
2859 // __ENFORCED_VERTICES_BEGIN__ 
2860 // __BEGIN_VERTEX__  => no name, no entry
2861 // __BEGIN_GROUP__ mon groupe __END_GROUP__
2862 // __BEGIN_COORDS__ 10 10 10 __END_COORDS__
2863 // __BEGIN_FACELIST__ 0:1:1:1:1 __END_FACELIST__
2864 // __END_VERTEX__
2865 // __BEGIN_VERTEX__ => no coords
2866 // __BEGIN_NAME__ mes points __END_NAME__
2867 // __BEGIN_ENTRY__ 0:1:1:4 __END_ENTRY__
2868 // __BEGIN_GROUP__ mon groupe __END_GROUP__
2869 // __BEGIN_FACELIST__ 0:1:1:1:3 __END_FACELIST__
2870 // __END_VERTEX__
2871 // __ENFORCED_VERTICES_END__
2872 //
2873
2874   std::string enfSeparator;
2875   std::string enfName;
2876   std::string enfGeomEntry;
2877   std::string enfGroup;
2878   TEntryList enfFaceEntryList;
2879   double enfCoords[3];
2880   bool hasCoords = false;
2881
2882   _faceEntryEnfVertexListMap.clear();
2883   _enfVertexList.clear();
2884   _faceEntryCoordsListMap.clear();
2885   _coordsEnfVertexMap.clear();
2886   _faceEntryEnfVertexEntryListMap.clear();
2887   _enfVertexEntryEnfVertexMap.clear();
2888
2889
2890   while (isOK && hasEnforcedVertex)
2891   {
2892     isOK = static_cast<bool>(load >> enfSeparator); // __BEGIN_VERTEX__
2893     TEnfVertex *enfVertex = new TEnfVertex();
2894     if (enfSeparator == "__ENFORCED_VERTICES_END__")
2895       break; // __ENFORCED_VERTICES_END__
2896     if (enfSeparator != "__BEGIN_VERTEX__")
2897       throw std::exception();
2898
2899     while (isOK) {
2900       isOK = static_cast<bool>(load >> enfSeparator);
2901       if (enfSeparator == "__END_VERTEX__") {
2902
2903         enfVertex->name = enfName;
2904         enfVertex->geomEntry = enfGeomEntry;
2905         enfVertex->grpName = enfGroup;
2906         enfVertex->coords.clear();
2907         if (hasCoords)
2908           enfVertex->coords.assign(enfCoords,enfCoords+3);
2909         enfVertex->faceEntries = enfFaceEntryList;
2910
2911         _enfVertexList.insert(enfVertex);
2912
2913         if (enfVertex->coords.size()) {
2914           _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
2915           for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) {
2916             _faceEntryCoordsListMap[(*it)].insert(enfVertex->coords);
2917             _faceEntryEnfVertexListMap[(*it)].insert(enfVertex);
2918           }
2919         }
2920         if (!enfVertex->geomEntry.empty()) {
2921           _enfVertexEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
2922           for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) {
2923             _faceEntryEnfVertexEntryListMap[(*it)].insert(enfVertex->geomEntry);
2924             _faceEntryEnfVertexListMap[(*it)].insert(enfVertex);
2925           }
2926         }
2927
2928         enfName.clear();
2929         enfGeomEntry.clear();
2930         enfGroup.clear();
2931         enfFaceEntryList.clear();
2932         hasCoords = false;
2933         break; // __END_VERTEX__
2934       }
2935
2936       if (enfSeparator == "__BEGIN_NAME__") {  // __BEGIN_NAME__
2937         while (isOK && (enfSeparator != "__END_NAME__")) {
2938           isOK = static_cast<bool>(load >> enfSeparator);
2939           if (enfSeparator != "__END_NAME__") {
2940             if (!enfName.empty())
2941               enfName += " ";
2942             enfName += enfSeparator;
2943           }
2944         }
2945       }
2946
2947       if (enfSeparator == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
2948         isOK = static_cast<bool>(load >> enfGeomEntry);
2949         isOK = static_cast<bool>(load >> enfSeparator); // __END_ENTRY__
2950         if (enfSeparator != "__END_ENTRY__")
2951           throw std::exception();
2952       }
2953
2954       if (enfSeparator == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
2955         while (isOK && (enfSeparator != "__END_GROUP__")) {
2956           isOK = static_cast<bool>(load >> enfSeparator);
2957           if (enfSeparator != "__END_GROUP__") {
2958             if (!enfGroup.empty())
2959               enfGroup += " ";
2960             enfGroup += enfSeparator;
2961           }
2962         }
2963       }
2964
2965       if (enfSeparator == "__BEGIN_COORDS__") {  // __BEGIN_COORDS__
2966         hasCoords = true;
2967         isOK = static_cast<bool>(load >> enfCoords[0] >> enfCoords[1] >> enfCoords[2]);
2968         isOK = static_cast<bool>(load >> enfSeparator); // __END_COORDS__
2969         if (enfSeparator != "__END_COORDS__")
2970           throw std::exception();
2971       }
2972
2973       if (enfSeparator == "__BEGIN_FACELIST__") {  // __BEGIN_FACELIST__
2974         while (isOK && (enfSeparator != "__END_FACELIST__")) {
2975           isOK = static_cast<bool>(load >> enfSeparator);
2976           if (enfSeparator != "__END_FACELIST__") {
2977             enfFaceEntryList.insert(enfSeparator);
2978           }
2979         }
2980       }
2981     }
2982   }
2983
2984   // PERIODICITY
2985
2986   if (hasPreCADFacesPeriodicity)
2987   {
2988     LoadPreCADPeriodicity(load, "FACES");
2989
2990     isOK = static_cast<bool>(load >> option_or_sm);
2991     if (isOK) {
2992       if (option_or_sm == "__PRECAD_EDGES_PERIODICITY_BEGIN__")
2993         hasPreCADEdgesPeriodicity = true;
2994       else if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
2995         hasFacesPeriodicity = true;
2996       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
2997         hasEdgesPeriodicity = true;
2998       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
2999         hasVerticesPeriodicity = true;
3000     }
3001   }
3002
3003   if (hasPreCADEdgesPeriodicity)
3004   {
3005     LoadPreCADPeriodicity(load, "EDGES");
3006
3007     isOK = static_cast<bool>(load >> option_or_sm);
3008     if (isOK) {
3009       if (option_or_sm == "__FACES_PERIODICITY_BEGIN__")
3010         hasFacesPeriodicity = true;
3011       else if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3012         hasEdgesPeriodicity = true;
3013       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3014         hasVerticesPeriodicity = true;
3015     }
3016   }
3017
3018   if (hasFacesPeriodicity)
3019   {
3020     LoadFacesPeriodicity(load);
3021
3022     isOK = static_cast<bool>(load >> option_or_sm);
3023     if (isOK) {
3024       if (option_or_sm == "__EDGES_PERIODICITY_BEGIN__")
3025         hasEdgesPeriodicity = true;
3026       else if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3027         hasVerticesPeriodicity = true;
3028     }
3029   }
3030
3031   if (hasEdgesPeriodicity)
3032   {
3033     LoadEdgesPeriodicity(load);
3034
3035     isOK = static_cast<bool>(load >> option_or_sm);
3036     if (isOK)
3037       if (option_or_sm == "__VERTICES_PERIODICITY_BEGIN__")
3038         hasVerticesPeriodicity = true;
3039   }
3040
3041   if (hasVerticesPeriodicity)
3042     LoadVerticesPeriodicity(load);
3043
3044   // HYPER-PATCHES
3045   if ( !option_or_sm.empty() && option_or_sm[0] == '_' )
3046     isOK = static_cast<bool>(load >> option_or_sm);
3047   if ( isOK && !option_or_sm.empty() )
3048   {
3049     int nbPatches = atoi( option_or_sm.c_str() );
3050     if ( nbPatches >= 0 )
3051     {
3052       _hyperPatchList.resize( nbPatches );
3053       for ( int iP = 0; iP < nbPatches && isOK; ++iP )
3054       {
3055         isOK = static_cast<bool>(load >> i) && i >= 2;
3056         if ( !isOK ) break;
3057         int nbTags = i;
3058         for ( int iT = 0; iT < nbTags; ++iT )
3059         {
3060           if (( isOK = static_cast<bool>(load >> i)))
3061             _hyperPatchList[ iP ].insert( i );
3062           else
3063             break;
3064         }
3065       }
3066       if ( !isOK ) // remove invalid patches
3067       {
3068         for ( i = nbPatches - 1; i >= 0; i-- )
3069           if ( _hyperPatchList[i].size() < 2 )
3070             _hyperPatchList.resize( i );
3071       }
3072     }
3073   }
3074
3075   return load;
3076 }
3077
3078 void BLSURFPlugin_Hypothesis::LoadFacesPeriodicity(std::istream & load){
3079
3080   bool isOK = true;
3081
3082   std::string periodicitySeparator;
3083   TEntry shape1Entry;
3084   TEntry shape2Entry;
3085
3086   _facesPeriodicityVector.clear();
3087
3088   while (isOK) {
3089     isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3090     TFacesPeriodicity *periodicity_i = new TFacesPeriodicity();
3091     if (periodicitySeparator == "__FACES_PERIODICITY_END__")
3092       break; // __FACES_PERIODICITY_END__
3093     if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3094       throw std::exception();
3095     }
3096
3097     while (isOK) {
3098       isOK = static_cast<bool>(load >> periodicitySeparator);
3099       if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3100
3101         periodicity_i->first = shape1Entry;
3102         periodicity_i->second = shape2Entry;
3103
3104         _facesPeriodicityVector.push_back(*periodicity_i);
3105
3106         break; // __END_PERIODICITY_DESCRIPTION__
3107       }
3108
3109       if (periodicitySeparator == "__BEGIN_ENTRY1__") {  // __BEGIN_ENTRY1__
3110         isOK = static_cast<bool>(load >> shape1Entry);
3111         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY1__
3112         if (periodicitySeparator != "__END_ENTRY1__")
3113           throw std::exception();
3114       }
3115
3116       if (periodicitySeparator == "__BEGIN_ENTRY2__") {  // __BEGIN_ENTRY2__
3117         isOK = static_cast<bool>(load >> shape2Entry);
3118         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY2__
3119         if (periodicitySeparator != "__END_ENTRY2__")
3120           throw std::exception();
3121       }
3122     }
3123   }
3124 }
3125
3126
3127 void BLSURFPlugin_Hypothesis::LoadEdgesPeriodicity(std::istream & load){
3128
3129   bool isOK = true;
3130
3131   std::string periodicitySeparator;
3132   TEntry theFace1Entry;
3133   TEntry theEdge1Entry;
3134   TEntry theFace2Entry;
3135   TEntry theEdge2Entry;
3136   int edge_orientation = 0;
3137
3138   _edgesPeriodicityVector.clear();
3139
3140   while (isOK) {
3141     isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3142     TEdgePeriodicity *periodicity_i = new TEdgePeriodicity();
3143     if (periodicitySeparator == "__EDGES_PERIODICITY_END__")
3144       break; // __EDGES_PERIODICITY_END__
3145     if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3146       throw std::exception();
3147     }
3148
3149     while (isOK) {
3150       isOK = static_cast<bool>(load >> periodicitySeparator);
3151       if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3152
3153         periodicity_i->theFace1Entry = theFace1Entry;
3154         periodicity_i->theEdge1Entry = theEdge1Entry;
3155         periodicity_i->theFace2Entry = theFace2Entry;
3156         periodicity_i->theEdge2Entry = theEdge2Entry;
3157         periodicity_i->edge_orientation = edge_orientation;
3158
3159         _edgesPeriodicityVector.push_back(*periodicity_i);
3160
3161         break; // __END_PERIODICITY_DESCRIPTION__
3162       }
3163
3164       if (periodicitySeparator == "__BEGIN_FACE1__") {  // __BEGIN_FACE1__
3165         isOK = static_cast<bool>(load >> theFace1Entry);
3166         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_FACE1__
3167         if (periodicitySeparator != "__END_FACE1__"){
3168           throw std::exception();
3169         }
3170       }
3171
3172       if (periodicitySeparator == "__BEGIN_EDGE1__") {  // __BEGIN_EDGE1__
3173         isOK = static_cast<bool>(load >> theEdge1Entry);
3174         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE1__
3175         if (periodicitySeparator != "__END_EDGE1__")
3176           throw std::exception();
3177       }
3178
3179       if (periodicitySeparator == "__BEGIN_FACE2__") {  // __BEGIN_FACE2__
3180         isOK = static_cast<bool>(load >> theFace2Entry);
3181         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_FACE2__
3182         if (periodicitySeparator != "__END_FACE2__")
3183           throw std::exception();
3184       }
3185
3186       if (periodicitySeparator == "__BEGIN_EDGE2__") {  // __BEGIN_EDGE2__
3187         isOK = static_cast<bool>(load >> theEdge2Entry);
3188         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE2__
3189         if (periodicitySeparator != "__END_EDGE2__")
3190           throw std::exception();
3191       }
3192
3193       if (periodicitySeparator == "__BEGIN_EDGE_ORIENTATION__") {  // __BEGIN_EDGE_ORIENTATION__
3194         isOK = static_cast<bool>(load >> edge_orientation);
3195         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE_ORIENTATION__
3196         if (periodicitySeparator != "__END_EDGE_ORIENTATION__")
3197           throw std::exception();
3198       }
3199     }
3200   }
3201 }
3202
3203 void BLSURFPlugin_Hypothesis::LoadVerticesPeriodicity(std::istream & load)
3204 {
3205   bool isOK = true;
3206
3207   std::string periodicitySeparator;
3208   TEntry theEdge1Entry;
3209   TEntry theVertex1Entry;
3210   TEntry theEdge2Entry;
3211   TEntry theVertex2Entry;
3212
3213   _verticesPeriodicityVector.clear();
3214
3215   while (isOK) {
3216     isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3217     TVertexPeriodicity *periodicity_i = new TVertexPeriodicity();
3218     if (periodicitySeparator == "__VERTICES_PERIODICITY_END__")
3219       break; // __VERTICES_PERIODICITY_END__
3220     if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3221       throw std::exception();
3222     }
3223
3224     while (isOK) {
3225       isOK = static_cast<bool>(load >> periodicitySeparator);
3226       if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3227
3228         periodicity_i->theEdge1Entry = theEdge1Entry;
3229         periodicity_i->theVertex1Entry = theVertex1Entry;
3230         periodicity_i->theEdge2Entry = theEdge2Entry;
3231         periodicity_i->theVertex2Entry = theVertex2Entry;
3232
3233         _verticesPeriodicityVector.push_back(*periodicity_i);
3234
3235         break; // __END_PERIODICITY_DESCRIPTION__
3236       }
3237
3238       if (periodicitySeparator == "__BEGIN_EDGE1__") {  // __BEGIN_EDGE1__
3239         isOK = static_cast<bool>(load >> theEdge1Entry);
3240         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE1__
3241         if (periodicitySeparator != "__END_EDGE1__")
3242           throw std::exception();
3243       }
3244
3245       if (periodicitySeparator == "__BEGIN_VERTEX1__") {  // __BEGIN_VERTEX1__
3246         isOK = static_cast<bool>(load >> theVertex1Entry);
3247         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_VERTEX1__
3248         if (periodicitySeparator != "__END_VERTEX1__")
3249           throw std::exception();
3250       }
3251
3252       if (periodicitySeparator == "__BEGIN_EDGE2__") {  // __BEGIN_EDGE2__
3253         isOK = static_cast<bool>(load >> theEdge2Entry);
3254         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_EDGE2__
3255         if (periodicitySeparator != "__END_EDGE2__")
3256           throw std::exception();
3257       }
3258
3259       if (periodicitySeparator == "__BEGIN_VERTEX2__") {  // __BEGIN_VERTEX2__
3260         isOK = static_cast<bool>(load >> theVertex2Entry);
3261         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_VERTEX2__
3262         if (periodicitySeparator != "__END_VERTEX2__")
3263           throw std::exception();
3264       }
3265     }
3266   }
3267 }
3268
3269 void BLSURFPlugin_Hypothesis::LoadPreCADPeriodicity(std::istream & load, const char* shapeType) {
3270
3271   bool isOK = true;
3272
3273   std::string periodicitySeparator;
3274   TEntry shape1Entry;
3275   TEntry shape2Entry;
3276   std::vector<std::string> theSourceVerticesEntries;
3277   std::vector<std::string> theTargetVerticesEntries;
3278
3279   bool hasSourceVertices = false;
3280   bool hasTargetVertices = false;
3281
3282   if ( shapeType  &&  strcmp( shapeType, "FACES") == 0 )
3283     _preCadFacesPeriodicityVector.clear();
3284   else
3285     _preCadEdgesPeriodicityVector.clear();
3286
3287
3288   while (isOK) {
3289     isOK = static_cast<bool>(load >> periodicitySeparator); // __BEGIN_PERIODICITY_DESCRIPTION__
3290     TPreCadPeriodicity *periodicity_i = new TPreCadPeriodicity();
3291     std::string endSeparator = "__PRECAD_" + std::string(shapeType) + "_PERIODICITY_END__";
3292     if (periodicitySeparator == endSeparator)
3293       break; // __PRECAD_FACES_PERIODICITY_END__
3294     if (periodicitySeparator != "__BEGIN_PERIODICITY_DESCRIPTION__"){
3295       throw std::exception();
3296     }
3297
3298     while (isOK) {
3299       isOK = static_cast<bool>(load >> periodicitySeparator);
3300       if (periodicitySeparator == "__END_PERIODICITY_DESCRIPTION__") {
3301
3302         periodicity_i->shape1Entry = shape1Entry;
3303         periodicity_i->shape2Entry = shape2Entry;
3304
3305         if (hasSourceVertices)
3306           periodicity_i->theSourceVerticesEntries = theSourceVerticesEntries;
3307         if (hasTargetVertices)
3308           periodicity_i->theTargetVerticesEntries = theTargetVerticesEntries;
3309
3310         if ( shapeType  &&  strcmp( shapeType, "FACES" ) == 0 )
3311           _preCadFacesPeriodicityVector.push_back(*periodicity_i);
3312         else
3313           _preCadEdgesPeriodicityVector.push_back(*periodicity_i);
3314
3315         theSourceVerticesEntries.clear();
3316         theTargetVerticesEntries.clear();
3317         hasSourceVertices = false;
3318         hasTargetVertices = false;
3319         break; // __END_PERIODICITY_DESCRIPTION__
3320       }
3321
3322       if (periodicitySeparator == "__BEGIN_ENTRY1__") {  // __BEGIN_ENTRY1__
3323         isOK = static_cast<bool>(load >> shape1Entry);
3324         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY1__
3325         if (periodicitySeparator != "__END_ENTRY1__")
3326           throw std::exception();
3327       }
3328
3329       if (periodicitySeparator == "__BEGIN_ENTRY2__") {  // __BEGIN_ENTRY2__
3330         isOK = static_cast<bool>(load >> shape2Entry);
3331         isOK = static_cast<bool>(load >> periodicitySeparator); // __END_ENTRY2__
3332         if (periodicitySeparator != "__END_ENTRY2__")
3333           throw std::exception();
3334       }
3335
3336       if (periodicitySeparator == "__BEGIN_SOURCE_VERTICES_LIST__") {  // __BEGIN_SOURCE_VERTICES_LIST__
3337         hasSourceVertices = true;
3338         while (isOK && (periodicitySeparator != "__END_SOURCE_VERTICES_LIST__")) {
3339           isOK = static_cast<bool>(load >> periodicitySeparator);
3340           if (periodicitySeparator != "__END_SOURCE_VERTICES_LIST__") {
3341             theSourceVerticesEntries.push_back(periodicitySeparator);
3342           }
3343         }
3344       }
3345
3346       if (periodicitySeparator == "__BEGIN_TARGET_VERTICES_LIST__") {  // __BEGIN_TARGET_VERTICES_LIST__
3347         hasTargetVertices = true;
3348         while (isOK && (periodicitySeparator != "__END_TARGET_VERTICES_LIST__")) {
3349           isOK = static_cast<bool>(load >> periodicitySeparator);
3350           if (periodicitySeparator != "__END_TARGET_VERTICES_LIST__") {
3351             theTargetVerticesEntries.push_back(periodicitySeparator);
3352           }
3353         }
3354       }
3355     }
3356   }
3357 }
3358
3359 //=============================================================================
3360 std::ostream & operator <<(std::ostream & save, BLSURFPlugin_Hypothesis & hyp) {
3361   return hyp.SaveTo(save);
3362 }
3363
3364 //=============================================================================
3365 std::istream & operator >>(std::istream & load, BLSURFPlugin_Hypothesis & hyp) {
3366   return hyp.LoadFrom(load);
3367 }
3368
3369 //================================================================================
3370 /*!
3371  * \brief Does nothing
3372  */
3373 //================================================================================
3374
3375 bool BLSURFPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape) {
3376   return false;
3377 }
3378
3379 //================================================================================
3380 /*!
3381  * \brief Returns default global constant physical size given a default value of element length ratio
3382  */
3383 //================================================================================
3384
3385 double BLSURFPlugin_Hypothesis::GetDefaultPhySize(double diagonal, double bbSegmentation) {
3386   if (bbSegmentation != 0 && diagonal != 0)
3387     return diagonal / bbSegmentation ;
3388   return 10;
3389 }
3390
3391 //================================================================================
3392 /*!
3393  * \brief Returns default min size given a default value of element length ratio
3394  */
3395 //================================================================================
3396
3397 double BLSURFPlugin_Hypothesis::GetDefaultMinSize(double diagonal) {
3398   if (diagonal != 0)
3399     return diagonal / 1000.0 ;
3400   return undefinedDouble();
3401 }
3402
3403 //================================================================================
3404 /*!
3405  * \brief Returns default max size given a default value of element length ratio
3406  */
3407 //================================================================================
3408
3409 double BLSURFPlugin_Hypothesis::GetDefaultMaxSize(double diagonal) {
3410   if (diagonal != 0)
3411     return diagonal / 5.0 ;
3412   return undefinedDouble();
3413 }
3414
3415 //================================================================================
3416 /*!
3417  * \brief Returns default chordal error given a default value of element length ratio
3418  */
3419 //================================================================================
3420
3421 double BLSURFPlugin_Hypothesis::GetDefaultChordalError(double diagonal) {
3422   if (diagonal != 0)
3423     return diagonal;
3424   return undefinedDouble();
3425 }
3426
3427 //================================================================================
3428 /*!
3429  * \brief Returns default tiny edge length given a default value of element length ratio
3430  */
3431 //================================================================================
3432
3433 double BLSURFPlugin_Hypothesis::GetDefaultTinyEdgeLength(double diagonal) {
3434   if (diagonal != 0)
3435     return diagonal * 1e-6 ;
3436   return undefinedDouble();
3437 }
3438
3439 //================================================================================
3440 /*!
3441  * \brief Returns default tiny edge optimisation length given a default value of element length ratio
3442  */
3443 //================================================================================
3444
3445 double BLSURFPlugin_Hypothesis::GetDefaultTinyEdgeOptimisationLength(double diagonal) {
3446   if (diagonal != 0)
3447     return diagonal * 1e-6 ;
3448   return undefinedDouble();
3449 }
3450
3451 //=============================================================================
3452 /*!
3453  * \brief Initialize my parameter values by default parameters.
3454  *  \retval bool - true if parameter values have been successfully defined
3455  */
3456 //=============================================================================
3457
3458 bool BLSURFPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh) {
3459   double diagonal = dflts._elemLength*_gen->GetBoundaryBoxSegmentation();
3460   _phySize = GetDefaultPhySize(diagonal, _gen->GetBoundaryBoxSegmentation());
3461   _minSize = GetDefaultMinSize(diagonal);
3462   _maxSize = GetDefaultMaxSize(diagonal);
3463   _chordalError = 0.5 * _phySize; //GetDefaultChordalError(diagonal); IMP 0023307
3464   _tinyEdgeLength = GetDefaultTinyEdgeLength(diagonal);
3465   _tinyEdgeOptimisationLength = GetDefaultTinyEdgeOptimisationLength(diagonal);
3466
3467   return true;
3468 }
3469
3470 //================================================================================
3471 /*!
3472  * \brief Converts a string to a bool
3473  */
3474 //================================================================================
3475
3476 bool BLSURFPlugin_Hypothesis::ToBool(const std::string& str, bool* isOk )
3477   throw (std::invalid_argument)
3478 {
3479   std::string s = str;
3480   if ( isOk ) *isOk = true;
3481
3482   for ( size_t i = 0; i <= s.size(); ++i )
3483     s[i] = tolower( s[i] );
3484
3485   if ( s == "1" || s == "true" || s == "active" || s == "yes" )
3486     return true;
3487
3488   if ( s == "0" || s == "false" || s == "inactive" || s == "no" )
3489     return false;
3490
3491   if ( isOk )
3492     *isOk = false;
3493   else {
3494     std::string msg = "Not a Boolean value:'" + str + "'";
3495     throw std::invalid_argument(msg);
3496   }
3497   return false;
3498 }
3499
3500 //================================================================================
3501 /*!
3502  * \brief Converts a string to a real value
3503  */
3504 //================================================================================
3505
3506 double BLSURFPlugin_Hypothesis::ToDbl(const std::string& str, bool* isOk )
3507   throw (std::invalid_argument)
3508 {
3509   if ( str.empty() ) throw std::invalid_argument("Empty value provided");
3510
3511   char * endPtr;
3512   double val = strtod(&str[0], &endPtr);
3513   bool ok = (&str[0] != endPtr);
3514
3515   if ( isOk ) *isOk = ok;
3516
3517   if ( !ok )
3518   {
3519     std::string msg = "Not a real value:'" + str + "'";
3520     throw std::invalid_argument(msg);
3521   }
3522   return val;
3523 }
3524
3525 //================================================================================
3526 /*!
3527  * \brief Converts a string to a integer value
3528  */
3529 //================================================================================
3530
3531 int BLSURFPlugin_Hypothesis::ToInt(const std::string& str, bool* isOk )
3532   throw (std::invalid_argument)
3533 {
3534   if ( str.empty() ) throw std::invalid_argument("Empty value provided");
3535
3536   char * endPtr;
3537   int val = (int)strtol( &str[0], &endPtr, 10);
3538   bool ok = (&str[0] != endPtr);
3539
3540   if ( isOk ) *isOk = ok;
3541
3542   if ( !ok )
3543   {
3544     std::string msg = "Not an integer value:'" + str + "'";
3545     throw std::invalid_argument(msg);
3546   }
3547   return val;
3548 }
3549