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