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