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