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