]> SALOME platform Git repositories - plugins/blsurfplugin.git/blob - src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx
Salome HOME
Compute Progress bar
[plugins/blsurfplugin.git] / src / BLSURFPlugin / BLSURFPlugin_Hypothesis.cxx
1 // Copyright (C) 2007-2013  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.
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 //=============================================================================
43 BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen) :
44   SMESH_Hypothesis(hypId, studyId, gen), 
45   _physicalMesh(GetDefaultPhysicalMesh()),
46   _geometricMesh(GetDefaultGeometricMesh()),
47   _phySize(GetDefaultPhySize()),
48   _phySizeRel(GetDefaultPhySizeRel()),
49   _minSize(GetDefaultMinSize()),
50   _minSizeRel(GetDefaultMinSizeRel()),
51   _maxSize(GetDefaultMaxSize()),
52   _maxSizeRel(GetDefaultMaxSizeRel()),
53   _gradation(GetDefaultGradation()),
54   _quadAllowed(GetDefaultQuadAllowed()),
55   _angleMesh(GetDefaultAngleMesh()),
56   _chordalError(GetDefaultChordalError()), 
57   _anisotropic(GetDefaultAnisotropic()),
58   _anisotropicRatio(GetDefaultAnisotropicRatio()),
59   _removeTinyEdges(GetDefaultRemoveTinyEdges()),
60   _tinyEdgeLength(GetDefaultTinyEdgeLength()),
61   _badElementRemoval(GetDefaultBadElementRemoval()),
62   _badElementAspectRatio(GetDefaultBadElementAspectRatio()),
63   _optimizeMesh(GetDefaultOptimizeMesh()),
64   _quadraticMesh(GetDefaultQuadraticMesh()),
65   _verb(GetDefaultVerbosity()),
66   _topology(GetDefaultTopology()),
67   _preCADMergeEdges(GetDefaultPreCADMergeEdges()),
68   _preCADProcess3DTopology(GetDefaultPreCADProcess3DTopology()),
69   _preCADDiscardInput(GetDefaultPreCADDiscardInput()),
70   _sizeMap(GetDefaultSizeMap()),
71   _attractors(GetDefaultSizeMap()),
72   _classAttractors(GetDefaultAttractorMap()),
73   _faceEntryEnfVertexListMap(GetDefaultFaceEntryEnfVertexListMap()),
74   _enfVertexList(GetDefaultEnfVertexList()),
75   _faceEntryCoordsListMap(GetDefaultFaceEntryCoordsListMap()),
76   _coordsEnfVertexMap(GetDefaultCoordsEnfVertexMap()),
77   _faceEntryEnfVertexEntryListMap(GetDefaultFaceEntryEnfVertexEntryListMap()),
78   _enfVertexEntryEnfVertexMap(GetDefaultEnfVertexEntryEnfVertexMap()),
79   _groupNameNodeIDMap(GetDefaultGroupNameNodeIDMap()),
80   _GMFFileName(GetDefaultGMFFile()),
81   _enforcedInternalVerticesAllFaces(GetDefaultInternalEnforcedVertex())
82 {
83   _name = "BLSURF_Parameters";
84   _param_algo_dim = 2;
85   
86 //   _GMFFileMode = false; // GMF ascii mode
87
88   const char* boolOptionNames[] = {         "correct_surface_intersections",            // default = 1
89                                             "create_tag_on_collision",                  // default = 1
90                                             "debug",                                    // default = 0
91                                             "enforce_cad_edge_sizes",                   // default = 0
92                                             "frontal",                                  // ok default = 1
93                                             "jacobian_rectification_respect_geometry",  // default = 1
94                                             "proximity",                                // default = 0
95                                             "rectify_jacobian",                         // default = 1
96                                             "respect_geometry",                         // default = 1
97                                             "" // mark of end
98       };
99
100   const char* intOptionNames[] = {          "hinterpol_flag",                           // ok default = 0
101                                             "hmean_flag",                               // ok default = 0
102                                             "max_number_of_points_per_patch",           // default = 100000
103                                             "prox_nb_layer",                            // detects the volumic proximity of surfaces
104                                             "" // mark of end
105       };
106   const char* doubleOptionNames[] = {       "surface_intersections_processing_max_cost",// default = 15
107                                             "periodic_tolerance",                       // default = diag/100
108                                             "prox_ratio",
109                                             "" // mark of end
110       };
111   const char* charOptionNames[] = {         "required_entities",                        // default = "respect"
112                                             "tags",                                     // default = "respect"
113                                             "" // mark of end
114       };
115
116   // PreCAD advanced options
117   const char* preCADboolOptionNames[] = {   "closed_geometry",                          // default = 0
118                                             "create_tag_on_collision",                  // default = 1
119                                             "debug",                                    // default = 0 
120                                             "remove_tiny_edges",                        // default = 0
121                                             "" // mark of end
122       };
123   const char* preCADintOptionNames[] = {    "manifold_geometry",                        // default = 0
124                                             "" // mark of end
125       };
126   const char* preCADdoubleOptionNames[] = { "periodic_tolerance",                       // default = diag * 1e-5
127                                             "sewing_tolerance",                         // default = diag * 5e-4
128                                             "tiny_edge_length",                         // default = diag * 1e-5
129                                             "" // mark of end
130       };
131   const char* preCADcharOptionNames[] = {   "required_entities",                        // default = "respect"
132                                             "tags",                                     // default = "respect"
133                                             "" // mark of end
134       };
135   
136   int i = 0;
137   while (boolOptionNames[i][0])
138     _option2value[boolOptionNames[i++]].clear();
139   
140   i = 0;
141   while (preCADboolOptionNames[i][0])
142     _preCADoption2value[preCADboolOptionNames[i++]].clear();
143   
144   i = 0;
145   while (intOptionNames[i][0])
146     _option2value[intOptionNames[i++]].clear();
147   
148   i = 0;
149   while (preCADintOptionNames[i][0])
150     _preCADoption2value[preCADintOptionNames[i++]].clear();
151
152   i = 0;
153   while (doubleOptionNames[i][0]) {
154     _doubleOptions.insert(doubleOptionNames[i]);
155     _option2value[doubleOptionNames[i++]].clear();
156   }
157   i = 0;
158   while (preCADdoubleOptionNames[i][0]) {
159     _preCADdoubleOptions.insert(preCADdoubleOptionNames[i]);
160     _preCADoption2value[preCADdoubleOptionNames[i++]].clear();
161   }
162   i = 0;
163   while (charOptionNames[i][0]) {
164     _charOptions.insert(charOptionNames[i]);
165     _option2value[charOptionNames[i++]].clear();
166   }
167   i = 0;
168   while (preCADcharOptionNames[i][0]) {
169     _preCADdoubleOptions.insert(preCADcharOptionNames[i]);
170     _preCADoption2value[preCADdoubleOptionNames[i++]].clear();
171   }
172   
173
174       
175   _sizeMap.clear();
176   _attractors.clear();
177   _faceEntryEnfVertexListMap.clear();
178   _enfVertexList.clear();
179   _faceEntryCoordsListMap.clear();
180   _coordsEnfVertexMap.clear();
181   _faceEntryEnfVertexEntryListMap.clear();
182   _enfVertexEntryEnfVertexMap.clear();
183   _groupNameNodeIDMap.clear();
184
185   /* TODO GROUPS
186    _groupNameEnfVertexListMap.clear();
187    _enfVertexGroupNameMap.clear();
188    */
189 }
190
191 TopoDS_Shape BLSURFPlugin_Hypothesis::entryToShape(std::string entry)
192 {
193   MESSAGE("BLSURFPlugin_Hypothesis::entryToShape "<<entry );
194   GEOM::GEOM_Object_var aGeomObj;
195   SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen();
196   SALOMEDS::Study_ptr myStudy = smeshGen_i->GetCurrentStudy();
197   
198   TopoDS_Shape S = TopoDS_Shape();
199   SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() );
200   if (!aSObj->_is_nil() ) {
201     CORBA::Object_var obj = aSObj->GetObject();
202     aGeomObj = GEOM::GEOM_Object::_narrow(obj);
203     aSObj->UnRegister();
204   }
205   if ( !aGeomObj->_is_nil() )
206     S = smeshGen_i->GeomObjectToShape( aGeomObj.in() );
207   return S;
208 }
209
210 //=============================================================================
211 void BLSURFPlugin_Hypothesis::SetPhysicalMesh(PhysicalMesh thePhysicalMesh) {
212   if (thePhysicalMesh != _physicalMesh) {
213     _physicalMesh = thePhysicalMesh;
214     NotifySubMeshesHypothesisModification();
215   }
216 }
217
218 //=============================================================================
219 void BLSURFPlugin_Hypothesis::SetGeometricMesh(GeometricMesh theGeometricMesh) {
220   if (theGeometricMesh != _geometricMesh) {
221     _geometricMesh = theGeometricMesh;
222 //     switch (_geometricMesh) {
223 //       case DefaultGeom:
224 //       default:
225 //         _angleMesh = GetDefaultAngleMesh();
226 //         _gradation = GetDefaultGradation();
227 //         break;
228 //     }
229     NotifySubMeshesHypothesisModification();
230   }
231 }
232
233 //=============================================================================
234 void BLSURFPlugin_Hypothesis::SetPhySize(double theVal, bool isRelative) {
235   if ((theVal != _phySize) || (isRelative != _phySizeRel)) {
236     _phySizeRel = isRelative;
237     if (theVal == 0) {
238       _phySize = GetMaxSize();
239       MESSAGE("Warning: nul physical size is not allowed");
240     }
241     else
242       _phySize = theVal;
243     NotifySubMeshesHypothesisModification();
244   }
245 }
246
247 //=============================================================================
248 void BLSURFPlugin_Hypothesis::SetMinSize(double theMinSize, bool isRelative) {
249   if ((theMinSize != _minSize) || (isRelative != _minSizeRel)) {
250     _minSizeRel = isRelative;
251     _minSize = theMinSize;
252     NotifySubMeshesHypothesisModification();
253   }
254 }
255
256 //=============================================================================
257 void BLSURFPlugin_Hypothesis::SetMaxSize(double theMaxSize, bool isRelative) {
258   if ((theMaxSize != _maxSize) || (isRelative != _maxSizeRel)) {
259     _maxSizeRel = isRelative;
260     _maxSize = theMaxSize;
261     NotifySubMeshesHypothesisModification();
262   }
263 }
264
265 //=============================================================================
266 void BLSURFPlugin_Hypothesis::SetGradation(double theVal) {
267   if (theVal != _gradation) {
268     _gradation = theVal;
269     NotifySubMeshesHypothesisModification();
270   }
271 }
272
273 //=============================================================================
274 void BLSURFPlugin_Hypothesis::SetQuadAllowed(bool theVal) {
275   if (theVal != _quadAllowed) {
276     _quadAllowed = theVal;
277     NotifySubMeshesHypothesisModification();
278   }
279 }
280
281 //=============================================================================
282 void BLSURFPlugin_Hypothesis::SetAngleMesh(double theVal) {
283   if (theVal != _angleMesh) {
284     _angleMesh = theVal;
285     NotifySubMeshesHypothesisModification();
286   }
287 }
288
289 //=============================================================================
290 void BLSURFPlugin_Hypothesis::SetChordalError(double theDistance) {
291   if (theDistance != _chordalError) {
292     _chordalError = theDistance;
293     NotifySubMeshesHypothesisModification();
294   }
295 }
296
297 //=============================================================================
298 void BLSURFPlugin_Hypothesis::SetAnisotropic(bool theVal) {
299   if (theVal != _anisotropic) {
300     _anisotropic = theVal;
301     NotifySubMeshesHypothesisModification();
302   }
303 }
304
305 //=============================================================================
306 void BLSURFPlugin_Hypothesis::SetAnisotropicRatio(double theVal) {
307   if (theVal != _anisotropicRatio) {
308     _anisotropicRatio = theVal;
309     NotifySubMeshesHypothesisModification();
310   }
311 }
312
313 //=============================================================================
314 void BLSURFPlugin_Hypothesis::SetRemoveTinyEdges(bool theVal) {
315   if (theVal != _removeTinyEdges) {
316     _removeTinyEdges = theVal;
317     NotifySubMeshesHypothesisModification();
318   }
319 }
320
321 //=============================================================================
322 void BLSURFPlugin_Hypothesis::SetTinyEdgeLength(double theVal) {
323   if (theVal != _tinyEdgeLength) {
324     _tinyEdgeLength = theVal;
325     NotifySubMeshesHypothesisModification();
326   }
327 }
328
329 //=============================================================================
330 void BLSURFPlugin_Hypothesis::SetBadElementRemoval(bool theVal) {
331   if (theVal != _badElementRemoval) {
332     _badElementRemoval = theVal;
333     NotifySubMeshesHypothesisModification();
334   }
335 }
336
337 //=============================================================================
338 void BLSURFPlugin_Hypothesis::SetBadElementAspectRatio(double theVal) {
339   if (theVal != _badElementAspectRatio) {
340     _badElementAspectRatio = theVal;
341     NotifySubMeshesHypothesisModification();
342   }
343 }
344
345 //=============================================================================
346 void BLSURFPlugin_Hypothesis::SetOptimizeMesh(bool theVal) {
347   if (theVal != _optimizeMesh) {
348     _optimizeMesh = theVal;
349     NotifySubMeshesHypothesisModification();
350   }
351 }
352
353 //=============================================================================
354 void BLSURFPlugin_Hypothesis::SetQuadraticMesh(bool theVal) {
355   if (theVal != _quadraticMesh) {
356     _quadraticMesh = theVal;
357     NotifySubMeshesHypothesisModification();
358   }
359 }
360
361 //=============================================================================
362 void BLSURFPlugin_Hypothesis::SetTopology(Topology theTopology) {
363   if (theTopology != _topology) {
364     _topology = theTopology;
365     NotifySubMeshesHypothesisModification();
366   }
367 }
368
369 //=============================================================================
370 void BLSURFPlugin_Hypothesis::SetVerbosity(int theVal) {
371   if (theVal != _verb) {
372     _verb = theVal;
373     NotifySubMeshesHypothesisModification();
374   }
375 }
376
377 //=============================================================================
378 void BLSURFPlugin_Hypothesis::SetPreCADMergeEdges(bool theVal) {
379   if (theVal != _preCADMergeEdges) {
380 //     SetTopology(PreCAD);
381     _preCADMergeEdges = theVal;
382     NotifySubMeshesHypothesisModification();
383   }
384 }
385
386 //=============================================================================
387 void BLSURFPlugin_Hypothesis::SetPreCADProcess3DTopology(bool theVal) {
388   if (theVal != _preCADProcess3DTopology) {
389 //     SetTopology(PreCAD);
390     _preCADProcess3DTopology = theVal;
391     NotifySubMeshesHypothesisModification();
392   }
393 }
394
395 //=============================================================================
396 void BLSURFPlugin_Hypothesis::SetPreCADDiscardInput(bool theVal) {
397   if (theVal != _preCADDiscardInput) {
398 //     SetTopology(PreCAD);
399     _preCADDiscardInput = theVal;
400     NotifySubMeshesHypothesisModification();
401   }
402 }
403
404 //=============================================================================
405 // void BLSURFPlugin_Hypothesis::SetGMFFile(const std::string& theFileName, bool isBinary)
406 void BLSURFPlugin_Hypothesis::SetGMFFile(const std::string& theFileName)
407 {
408   _GMFFileName = theFileName;
409 //   _GMFFileMode = isBinary;
410   NotifySubMeshesHypothesisModification();
411 }
412
413 //=============================================================================
414 void BLSURFPlugin_Hypothesis::SetOptionValue(const std::string& optionName, const std::string& optionValue)
415     throw (std::invalid_argument) {
416   TOptionValues::iterator op_val = _option2value.find(optionName);
417   if (op_val == _option2value.end()) {
418     std::string msg = "Unknown BLSURF option: '" + optionName + "'";
419     throw std::invalid_argument(msg);
420   }
421   if (op_val->second != optionValue) {
422     const char* ptr = optionValue.c_str();
423     // strip white spaces
424     while (ptr[0] == ' ')
425       ptr++;
426     int i = strlen(ptr);
427     while (i != 0 && ptr[i - 1] == ' ')
428       i--;
429     // check value type
430     bool typeOk = true;
431     std::string typeName;
432     if (i == 0) {
433       // empty string
434     } else if (_charOptions.find(optionName) != _charOptions.end()) {
435       // do not check strings
436     } else if (_doubleOptions.find(optionName) != _doubleOptions.end()) {
437       // check if value is double
438       char * endPtr;
439       strtod(ptr, &endPtr);
440       typeOk = (ptr != endPtr);
441       typeName = "real";
442     } else {
443       // check if value is int
444       char * endPtr;
445       strtol(ptr, &endPtr, 10);
446       typeOk = (ptr != endPtr);
447       typeName = "integer";
448     }
449     if (!typeOk) {
450       std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
451       throw std::invalid_argument(msg);
452     }
453     op_val->second = optionValue;
454     NotifySubMeshesHypothesisModification();
455   }
456 }
457
458 //=============================================================================
459 void BLSURFPlugin_Hypothesis::SetPreCADOptionValue(const std::string& optionName, const std::string& optionValue)
460     throw (std::invalid_argument) {
461   TOptionValues::iterator op_val = _preCADoption2value.find(optionName);
462   if (op_val == _preCADoption2value.end()) {
463     std::string msg = "Unknown BLSURF option: '" + optionName + "'";
464     throw std::invalid_argument(msg);
465   }
466   if (op_val->second != optionValue) {
467     const char* ptr = optionValue.c_str();
468     // strip white spaces
469     while (ptr[0] == ' ')
470       ptr++;
471     int i = strlen(ptr);
472     while (i != 0 && ptr[i - 1] == ' ')
473       i--;
474     // check value type
475     bool typeOk = true;
476     std::string typeName;
477     if (i == 0) {
478       // empty string
479     } else if (_preCADdoubleOptions.find(optionName) != _preCADdoubleOptions.end()) {
480       // check if value is double
481       char * endPtr;
482       strtod(ptr, &endPtr);
483       typeOk = (ptr != endPtr);
484       typeName = "real";
485     } else {
486       // check if value is int
487       char * endPtr;
488       strtol(ptr, &endPtr, 10);
489       typeOk = (ptr != endPtr);
490       typeName = "integer";
491     }
492     if (!typeOk) {
493       std::string msg = "PreCAD advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
494       throw std::invalid_argument(msg);
495     }
496     op_val->second = optionValue;
497     NotifySubMeshesHypothesisModification();
498   }
499 }
500
501 //=============================================================================
502 std::string BLSURFPlugin_Hypothesis::GetOptionValue(const std::string& optionName) throw (std::invalid_argument) {
503   TOptionValues::iterator op_val = _option2value.find(optionName);
504   if (op_val == _option2value.end()) {
505     std::string msg = "Unknown BLSURF option: <";
506     msg += optionName + ">";
507     throw std::invalid_argument(msg);
508   }
509   return op_val->second;
510 }
511
512 //=============================================================================
513 std::string BLSURFPlugin_Hypothesis::GetPreCADOptionValue(const std::string& optionName) throw (std::invalid_argument) {
514   TOptionValues::iterator op_val = _preCADoption2value.find(optionName);
515   if (op_val == _preCADoption2value.end()) {
516     std::string msg = "Unknown PRECAD option: <";
517     msg += optionName + ">";
518     throw std::invalid_argument(msg);
519   }
520   return op_val->second;
521 }
522
523 //=============================================================================
524 void BLSURFPlugin_Hypothesis::ClearOption(const std::string& optionName) {
525   TOptionValues::iterator op_val = _option2value.find(optionName);
526   if (op_val != _option2value.end())
527     op_val->second.clear();
528 }
529
530 //=============================================================================
531 void BLSURFPlugin_Hypothesis::ClearPreCADOption(const std::string& optionName) {
532   TOptionValues::iterator op_val = _preCADoption2value.find(optionName);
533   if (op_val != _preCADoption2value.end())
534     op_val->second.clear();
535 }
536
537 //=======================================================================
538 //function : SetSizeMapEntry
539 //=======================================================================
540 void BLSURFPlugin_Hypothesis::SetSizeMapEntry(const std::string& entry, const std::string& sizeMap) {
541   if (_sizeMap[entry].compare(sizeMap) != 0) {
542     SetPhysicalMesh(PhysicalLocalSize);
543     _sizeMap[entry] = sizeMap;
544     NotifySubMeshesHypothesisModification();
545   }
546 }
547
548 //=======================================================================
549 //function : GetSizeMapEntry
550 //=======================================================================
551 std::string BLSURFPlugin_Hypothesis::GetSizeMapEntry(const std::string& entry) {
552   TSizeMap::iterator it = _sizeMap.find(entry);
553   if (it != _sizeMap.end())
554     return it->second;
555   else
556     return "No_Such_Entry";
557 }
558
559 /*!
560  * \brief Return the size maps
561  */
562 BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetSizeMapEntries(const BLSURFPlugin_Hypothesis* hyp) {
563   return hyp ? hyp->_GetSizeMapEntries() : GetDefaultSizeMap();
564 }
565
566 //=======================================================================
567 //function : SetAttractorEntry
568 //=======================================================================
569 void BLSURFPlugin_Hypothesis::SetAttractorEntry(const std::string& entry, const std::string& attractor) {
570   if (_attractors[entry].compare(attractor) != 0) {
571     SetPhysicalMesh(PhysicalLocalSize);
572     _attractors[entry] = attractor;
573     NotifySubMeshesHypothesisModification();
574   }
575 }
576
577 //=======================================================================
578 //function : GetAttractorEntry
579 //=======================================================================
580 std::string BLSURFPlugin_Hypothesis::GetAttractorEntry(const std::string& entry) {
581   TSizeMap::iterator it = _attractors.find(entry);
582   if (it != _attractors.end())
583     return it->second;
584   else
585     return "No_Such_Entry";
586 }
587
588 /*!
589  * \brief Return the attractors
590  */
591 BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetAttractorEntries(const BLSURFPlugin_Hypothesis* hyp) {
592   return hyp ? hyp->_GetAttractorEntries() : GetDefaultSizeMap();
593 }
594
595 //=======================================================================
596 //function : SetClassAttractorEntry
597 //=======================================================================
598 void BLSURFPlugin_Hypothesis::SetClassAttractorEntry(const std::string& entry, const std::string& attEntry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius)
599 {
600   SetPhysicalMesh(PhysicalLocalSize);
601
602   // The new attractor can't be defined on the same face as another sizemap
603   TSizeMap::iterator it  = _sizeMap.find( entry );
604   if ( it != _sizeMap.end() ) {
605     _sizeMap.erase(it);
606     NotifySubMeshesHypothesisModification();
607   }
608   else {
609     TSizeMap::iterator itAt  = _attractors.find( entry );
610     if ( itAt != _attractors.end() ) {
611       _attractors.erase(itAt);
612       NotifySubMeshesHypothesisModification();
613     }
614   }
615   
616   const TopoDS_Shape AttractorShape = BLSURFPlugin_Hypothesis::entryToShape(attEntry);
617   const TopoDS_Face FaceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(entry));
618   bool attExists = (_classAttractors.find(entry) != _classAttractors.end());
619   double u1,u2,v1,v2, diag;
620   
621   if ( !attExists || (attExists && _classAttractors[entry]->GetAttractorEntry().compare(attEntry) != 0)){ 
622     ShapeAnalysis::GetFaceUVBounds(FaceShape,u1,u2,v1,v2);
623 //     diag = sqrt((u2 - u1) * (u2 - u1) + (v2 - v1) * (v2 - v1));  
624     BLSURFPlugin_Attractor* myAttractor = new BLSURFPlugin_Attractor(FaceShape, AttractorShape, attEntry);//, 0.1 ); // test 0.002 * diag); 
625     myAttractor->BuildMap();
626     myAttractor->SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius);
627     _classAttractors[entry] = myAttractor;
628     NotifySubMeshesHypothesisModification();
629   }
630   else {
631     _classAttractors[entry]->SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius);
632     if (!_classAttractors[entry]->IsMapBuilt()){
633       _classAttractors[entry]->BuildMap();
634     }
635     NotifySubMeshesHypothesisModification();
636   }
637     
638 }
639
640 //=======================================================================
641 //function : SetConstantSizeOnAdjacentFaces
642 //=======================================================================
643 // TODO uncomment and test (include the needed .hxx)
644 // SetConstantSizeOnAdjacentFaces(myShape, att_entry, startSize, endSize = user_size, const_dist  ) {
645 //   TopTools_IndexedMapOfShapListOdShape anEdge2FaceMap;
646 //   TopExp::MapShapesAnAncestors(myShape,TopAbs_EDGE, TopAbs_FACE, anEdge2FaceMap);
647 //   TopTools_IndexedMapOfShapListOdShape::iterator it;
648 //   for (it = anEdge2FaceMap.begin();it != anEdge2FaceMap.end();it++){
649 //       SetClassAttractorEntry((*it).first, att_entry, startSize, endSize, 0, const_dist)
650 //   }
651
652
653
654
655
656
657 //=======================================================================
658 //function : GetClassAttractorEntry
659 //=======================================================================
660 // BLSURFPlugin_Attractor&  BLSURFPlugin_Hypothesis::GetClassAttractorEntry(const std::string& entry)
661 // {
662 //  TAttractorMap::iterator it  = _classAttractors.find( entry );
663 //  if ( it != _classAttractors.end() )
664 //    return it->second;
665 //  else
666 //    return "No_Such_Entry";
667 // }
668 // 
669   /*!
670    * \brief Return the map of attractor instances
671    */
672 BLSURFPlugin_Hypothesis::TAttractorMap BLSURFPlugin_Hypothesis::GetClassAttractorEntries(const BLSURFPlugin_Hypothesis* hyp)
673 {
674     return hyp ? hyp->_GetClassAttractorEntries():GetDefaultAttractorMap();
675 }
676
677 //=======================================================================
678 //function : ClearEntry
679 //=======================================================================
680 void BLSURFPlugin_Hypothesis::ClearEntry(const std::string& entry)
681 {
682  TSizeMap::iterator it  = _sizeMap.find( entry );
683  
684  if ( it != _sizeMap.end() ) {
685    _sizeMap.erase(it);
686    NotifySubMeshesHypothesisModification();
687  }
688  else {
689    TSizeMap::iterator itAt  = _attractors.find( entry );
690    if ( itAt != _attractors.end() ) {
691      _attractors.erase(itAt);
692      NotifySubMeshesHypothesisModification();
693    }
694    else {
695      TAttractorMap::iterator it_clAt = _classAttractors.find( entry );
696      if ( it_clAt != _classAttractors.end() ) {
697        _classAttractors.erase(it_clAt);
698        MESSAGE("_classAttractors.size() = "<<_classAttractors.size())
699        NotifySubMeshesHypothesisModification();
700      }
701      else
702        std::cout<<"No_Such_Entry"<<std::endl;
703    }
704  }
705 }
706
707 //=======================================================================
708 //function : ClearSizeMaps
709 //=======================================================================
710 void BLSURFPlugin_Hypothesis::ClearSizeMaps() {
711   _sizeMap.clear();
712   _attractors.clear();
713   _classAttractors.clear();
714 }
715
716 // Enable internal enforced vertices on specific face if requested by user
717
718 ////=======================================================================
719 ////function : SetInternalEnforcedVertex
720 ////=======================================================================
721 //void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertex(TEntry theFaceEntry,
722 //                                                        bool toEnforceInternalVertices,
723 //                                                        TEnfGroupName theGroupName) {
724
725 //  MESSAGE("BLSURFPlugin_Hypothesis::SetInternalEnforcedVertex("<< theFaceEntry << ", "
726 //      << toEnforceInternalVertices << ", " << theGroupName << ")");
727   
728 //  TFaceEntryInternalVerticesList::iterator it = _faceEntryInternalVerticesList.find(theFaceEntry);
729 //  if (it != _faceEntryInternalVerticesList.end()) {
730 //    if (!toEnforceInternalVertices) {
731 //      _faceEntryInternalVerticesList.erase(it);
732 //    }
733 //  }
734 //  else {
735 //    if (toEnforceInternalVertices) {
736 //      _faceEntryInternalVerticesList.insert(theFaceEntry);
737 //    }
738 //  }
739   
740 //  // TODO
741 //  // Take care of groups
742 //}
743
744
745 //=======================================================================
746 //function : SetEnforcedVertex
747 //=======================================================================
748 bool BLSURFPlugin_Hypothesis::SetEnforcedVertex(TEntry theFaceEntry, TEnfName theVertexName, TEntry theVertexEntry,
749                                                 TEnfGroupName theGroupName, double x, double y, double z) {
750
751   MESSAGE("BLSURFPlugin_Hypothesis::SetEnforcedVertex("<< theFaceEntry << ", "
752       << x << ", " << y << ", " << z << ", " << theVertexName << ", " << theVertexEntry << ", " << theGroupName << ")");
753
754   SetPhysicalMesh(PhysicalLocalSize);
755
756   //  TEnfVertexList::iterator it;
757   bool toNotify = false;
758   bool toCreate = true;
759
760   TEnfVertex *oldEnVertex;
761   TEnfVertex *newEnfVertex = new TEnfVertex();
762   newEnfVertex->name = theVertexName;
763   newEnfVertex->geomEntry = theVertexEntry;
764   newEnfVertex->coords.clear();
765   if (theVertexEntry == "") {
766     newEnfVertex->coords.push_back(x);
767     newEnfVertex->coords.push_back(y);
768     newEnfVertex->coords.push_back(z);
769   }
770   newEnfVertex->grpName = theGroupName;
771   newEnfVertex->faceEntries.clear();
772   newEnfVertex->faceEntries.insert(theFaceEntry);
773   
774   
775   // update _enfVertexList
776   TEnfVertexList::iterator it = _enfVertexList.find(newEnfVertex);
777   if (it != _enfVertexList.end()) {
778     toCreate = false;
779     oldEnVertex = (*it);
780     MESSAGE("Enforced Vertex was found => Update");
781     if (oldEnVertex->name != theVertexName) {
782       MESSAGE("Update name from \"" << oldEnVertex->name << "\" to \"" << theVertexName << "\"");
783       oldEnVertex->name = theVertexName;
784       toNotify = true;
785     }
786     if (oldEnVertex->grpName != theGroupName) {
787       MESSAGE("Update group name from \"" << oldEnVertex->grpName << "\" to \"" << theGroupName << "\"");
788       oldEnVertex->grpName = theGroupName;
789       toNotify = true;
790     }
791     TEntryList::iterator it_faceEntries = oldEnVertex->faceEntries.find(theFaceEntry);
792     if (it_faceEntries == oldEnVertex->faceEntries.end()) {
793       MESSAGE("Update face list by adding \"" << theFaceEntry << "\"");
794       oldEnVertex->faceEntries.insert(theFaceEntry);
795       _faceEntryEnfVertexListMap[theFaceEntry].insert(oldEnVertex);
796       toNotify = true;
797     }
798     if (toNotify) {
799       // update map coords / enf vertex if needed
800       if (oldEnVertex->coords.size()) {
801         _coordsEnfVertexMap[oldEnVertex->coords] = oldEnVertex;
802         _faceEntryCoordsListMap[theFaceEntry].insert(oldEnVertex->coords);
803       }
804
805       // update map geom entry / enf vertex if needed
806       if (oldEnVertex->geomEntry != "") {
807         _enfVertexEntryEnfVertexMap[oldEnVertex->geomEntry] = oldEnVertex;
808         _faceEntryEnfVertexEntryListMap[theFaceEntry].insert(oldEnVertex->geomEntry);
809       }
810     }
811   }
812
813 //   //////// CREATE ////////////
814   if (toCreate) {
815     toNotify = true;
816     MESSAGE("Creating new enforced vertex");
817     _faceEntryEnfVertexListMap[theFaceEntry].insert(newEnfVertex);
818     _enfVertexList.insert(newEnfVertex);
819     if (theVertexEntry == "") {
820       _faceEntryCoordsListMap[theFaceEntry].insert(newEnfVertex->coords);
821       _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex;
822     }
823     else {
824       _faceEntryEnfVertexEntryListMap[theFaceEntry].insert(newEnfVertex->geomEntry);
825       _enfVertexEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex;
826     }
827   }
828
829   if (toNotify)
830     NotifySubMeshesHypothesisModification();
831
832   MESSAGE("BLSURFPlugin_Hypothesis::SetEnforcedVertex END");
833   return toNotify;
834 }
835
836
837 //=======================================================================
838 //function : GetEnforcedVertices
839 //=======================================================================
840
841 BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetEnfVertexList(const TEntry& theFaceEntry)
842     throw (std::invalid_argument) {
843
844   if (_faceEntryEnfVertexListMap.count(theFaceEntry) > 0)
845     return _faceEntryEnfVertexListMap[theFaceEntry];
846   else
847     return GetDefaultEnfVertexList();
848
849   std::ostringstream msg;
850   msg << "No enforced vertex for face entry " << theFaceEntry;
851   throw std::invalid_argument(msg.str());
852 }
853
854 //=======================================================================
855 //function : GetEnfVertexCoordsList
856 //=======================================================================
857
858 BLSURFPlugin_Hypothesis::TEnfVertexCoordsList BLSURFPlugin_Hypothesis::GetEnfVertexCoordsList(
859     const TEntry& theFaceEntry) throw (std::invalid_argument) {
860
861   if (_faceEntryCoordsListMap.count(theFaceEntry) > 0)
862     return _faceEntryCoordsListMap[theFaceEntry];
863
864   std::ostringstream msg;
865   msg << "No enforced vertex coords for face entry " << theFaceEntry;
866   throw std::invalid_argument(msg.str());
867 }
868
869 //=======================================================================
870 //function : GetEnfVertexEntryList
871 //=======================================================================
872
873 BLSURFPlugin_Hypothesis::TEntryList BLSURFPlugin_Hypothesis::GetEnfVertexEntryList(const TEntry& theFaceEntry)
874     throw (std::invalid_argument) {
875
876   if (_faceEntryEnfVertexEntryListMap.count(theFaceEntry) > 0)
877     return _faceEntryEnfVertexEntryListMap[theFaceEntry];
878
879   std::ostringstream msg;
880   msg << "No enforced vertex entry for face entry " << theFaceEntry;
881   throw std::invalid_argument(msg.str());
882 }
883
884 //=======================================================================
885 //function : GetEnfVertex(TEnfVertexCoords coords)
886 //=======================================================================
887
888 BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(TEnfVertexCoords coords)
889     throw (std::invalid_argument) {
890
891   if (_coordsEnfVertexMap.count(coords) > 0)
892     return _coordsEnfVertexMap[coords];
893
894   std::ostringstream msg;
895   msg << "No enforced vertex with coords (" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")";
896   throw std::invalid_argument(msg.str());
897 }
898
899 //=======================================================================
900 //function : GetEnfVertex(const TEntry& theEnfVertexEntry)
901 //=======================================================================
902
903 BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(const TEntry& theEnfVertexEntry)
904     throw (std::invalid_argument) {
905
906   if (_enfVertexEntryEnfVertexMap.count(theEnfVertexEntry) > 0)
907     return _enfVertexEntryEnfVertexMap[theEnfVertexEntry];
908
909   std::ostringstream msg;
910   msg << "No enforced vertex with entry " << theEnfVertexEntry;
911   throw std::invalid_argument(msg.str());
912 }
913
914 //Enable internal enforced vertices on specific face if requested by user
915 ////=======================================================================
916 ////function : GetInternalEnforcedVertex
917 ////=======================================================================
918
919 //bool BLSURFPlugin_Hypothesis::GetInternalEnforcedVertex(const TEntry& theFaceEntry)
920 //{
921 //  if (_faceEntryInternalVerticesList.count(theFaceEntry) > 0)
922 //    return true;
923 //  return false;
924 //}
925
926 //=======================================================================
927 //function : ClearEnforcedVertex
928 //=======================================================================
929
930 bool BLSURFPlugin_Hypothesis::ClearEnforcedVertex(const TEntry& theFaceEntry, double x, double y, double z,
931     const TEntry& theVertexEntry) throw (std::invalid_argument) {
932
933   bool toNotify = false;
934   std::ostringstream msg;
935   TEnfVertex *oldEnfVertex;
936   TEnfVertexCoords coords;
937   coords.clear();
938   coords.push_back(x);
939   coords.push_back(y);
940   coords.push_back(z);
941
942   // check that enf vertex with given enf vertex entry exists
943   TEnfVertexEntryEnfVertexMap::iterator it_enfVertexEntry = _enfVertexEntryEnfVertexMap.find(theVertexEntry);
944   if (it_enfVertexEntry != _enfVertexEntryEnfVertexMap.end()) {
945     // Success
946     MESSAGE("Found enforced vertex with geom entry " << theVertexEntry);
947     oldEnfVertex = it_enfVertexEntry->second;
948
949     _enfVertexEntryEnfVertexMap.erase(it_enfVertexEntry);
950
951     TEntryList& enfVertexEntryList = _faceEntryEnfVertexEntryListMap[theFaceEntry];
952     enfVertexEntryList.erase(theVertexEntry);
953     if (enfVertexEntryList.size() == 0)
954       _faceEntryEnfVertexEntryListMap.erase(theFaceEntry);
955     //    TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry);
956     //    TEntryList::iterator it_entryList = it_entry_entry->second.find(theVertexEntry);
957     //    it_entry_entry->second.erase(it_entryList);
958     //    if (it_entry_entry->second.size() == 0)
959     //      _faceEntryEnfVertexEntryListMap.erase(it_entry_entry);
960   } else {
961     // Fail
962     MESSAGE("Enforced vertex with geom entry " << theVertexEntry << " not found");
963     msg << "No enforced vertex with geom entry " << theVertexEntry;
964     // check that enf vertex with given coords exists
965     TCoordsEnfVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
966     if (it_coords_enf != _coordsEnfVertexMap.end()) {
967       // Success
968       MESSAGE("Found enforced vertex with coords " << x << ", " << y << ", " << z);
969       oldEnfVertex = it_coords_enf->second;
970
971       _coordsEnfVertexMap.erase(it_coords_enf);
972
973       TEnfVertexCoordsList& enfVertexCoordsList = _faceEntryCoordsListMap[theFaceEntry];
974       enfVertexCoordsList.erase(coords);
975       if (enfVertexCoordsList.size() == 0)
976         _faceEntryCoordsListMap.erase(theFaceEntry);
977       //      TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry);
978       //      TEnfVertexCoordsList::iterator it_coordsList = it_entry_coords->second.find(coords);
979       //      it_entry_coords->second.erase(it_coordsList);
980       //      if (it_entry_coords->second.size() == 0)
981       //        _faceEntryCoordsListMap.erase(it_entry_coords);
982     } else {
983       // Fail
984       MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found");
985       msg << std::endl;
986       msg << "No enforced vertex at " << x << ", " << y << ", " << z;
987       throw std::invalid_argument(msg.str());
988     }
989   }
990
991   MESSAGE("Remove enf vertex from _enfVertexList");
992
993   // update _enfVertexList
994   TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
995   if (it != _enfVertexList.end()) {
996     (*it)->faceEntries.erase(theFaceEntry);
997     if ((*it)->faceEntries.size() == 0){
998       _enfVertexList.erase(it);
999       toNotify = true;
1000     }
1001     MESSAGE("Done");
1002   }
1003
1004   // update _faceEntryEnfVertexListMap
1005   TEnfVertexList& currentEnfVertexList = _faceEntryEnfVertexListMap[theFaceEntry];
1006   currentEnfVertexList.erase(oldEnfVertex);
1007
1008   if (currentEnfVertexList.size() == 0) {
1009     MESSAGE("Remove _faceEntryEnfVertexListMap[" << theFaceEntry <<"]");
1010     _faceEntryEnfVertexListMap.erase(theFaceEntry);
1011     MESSAGE("Done");
1012   }
1013
1014   if (toNotify)
1015     NotifySubMeshesHypothesisModification();
1016
1017   return toNotify;
1018 }
1019
1020 //=======================================================================
1021 //function : ClearEnforcedVertices
1022 //=======================================================================
1023
1024 bool BLSURFPlugin_Hypothesis::ClearEnforcedVertices(const TEntry& theFaceEntry) throw (std::invalid_argument) {
1025
1026   bool toNotify = false;
1027   TEnfVertex *oldEnfVertex;
1028
1029   TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry);
1030   if (it_entry_coords != _faceEntryCoordsListMap.end()) {
1031     toNotify = true;
1032     TEnfVertexCoordsList coordsList = it_entry_coords->second;
1033     TEnfVertexCoordsList::iterator it_coordsList = coordsList.begin();
1034     for (; it_coordsList != coordsList.end(); ++it_coordsList) {
1035       TEnfVertexCoords coords = (*it_coordsList);
1036       oldEnfVertex = _coordsEnfVertexMap[coords];
1037       _coordsEnfVertexMap.erase(coords);
1038       // update _enfVertexList
1039       TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1040       if (it != _enfVertexList.end()) {
1041         (*it)->faceEntries.erase(theFaceEntry);
1042         if ((*it)->faceEntries.size() == 0){
1043           _enfVertexList.erase(it);
1044           toNotify = true;
1045         }
1046         MESSAGE("Done");
1047       }
1048     }
1049     _faceEntryCoordsListMap.erase(it_entry_coords);
1050     _faceEntryEnfVertexListMap.erase(theFaceEntry);
1051   }
1052
1053   TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry);
1054   if (it_entry_entry != _faceEntryEnfVertexEntryListMap.end()) {
1055     toNotify = true;
1056     TEntryList enfVertexEntryList = it_entry_entry->second;
1057     TEntryList::iterator it_enfVertexEntryList = enfVertexEntryList.begin();
1058     for (; it_enfVertexEntryList != enfVertexEntryList.end(); ++it_enfVertexEntryList) {
1059       TEntry enfVertexEntry = (*it_enfVertexEntryList);
1060       oldEnfVertex = _enfVertexEntryEnfVertexMap[enfVertexEntry];
1061       _enfVertexEntryEnfVertexMap.erase(enfVertexEntry);
1062       // update _enfVertexList
1063       TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
1064       if (it != _enfVertexList.end()) {
1065         (*it)->faceEntries.erase(theFaceEntry);
1066         if ((*it)->faceEntries.size() == 0){
1067           _enfVertexList.erase(it);
1068           toNotify = true;
1069         }
1070         MESSAGE("Done");
1071       }
1072     }
1073     _faceEntryEnfVertexEntryListMap.erase(it_entry_entry);
1074     _faceEntryEnfVertexListMap.erase(theFaceEntry);
1075   }
1076
1077   if (toNotify)
1078     NotifySubMeshesHypothesisModification();
1079
1080   return toNotify;
1081   //  std::ostringstream msg;
1082   //  msg << "No enforced vertex for " << theFaceEntry;
1083   //  throw std::invalid_argument(msg.str());
1084 }
1085
1086 //=======================================================================
1087 //function : ClearAllEnforcedVertices
1088 //=======================================================================
1089 void BLSURFPlugin_Hypothesis::ClearAllEnforcedVertices() {
1090   _faceEntryEnfVertexListMap.clear();
1091   _enfVertexList.clear();
1092   _faceEntryCoordsListMap.clear();
1093   _coordsEnfVertexMap.clear();
1094   _faceEntryEnfVertexEntryListMap.clear();
1095   _enfVertexEntryEnfVertexMap.clear();
1096 //  Enable internal enforced vertices on specific face if requested by user
1097 //  _faceEntryInternalVerticesList.clear();
1098   NotifySubMeshesHypothesisModification();
1099 }
1100
1101 //================================================================================
1102 /*!
1103  * \brief Return the enforced vertices
1104  */
1105 //================================================================================
1106
1107
1108 BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByFace(
1109     const BLSURFPlugin_Hypothesis* hyp) {
1110   return hyp ? hyp->_GetAllEnforcedVerticesByFace() : GetDefaultFaceEntryEnfVertexListMap();
1111 }
1112
1113 //Enable internal enforced vertices on specific face if requested by user
1114 //BLSURFPlugin_Hypothesis::TFaceEntryInternalVerticesList BLSURFPlugin_Hypothesis::GetAllInternalEnforcedVerticesByFace(
1115 //    const BLSURFPlugin_Hypothesis* hyp) {
1116 //  return hyp ? hyp->_GetAllInternalEnforcedVerticesByFace() : GetDefaultFaceEntryInternalVerticesMap();
1117 //}
1118
1119 bool BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFaces(const BLSURFPlugin_Hypothesis* hyp)
1120 {
1121   return hyp ? hyp->_GetInternalEnforcedVertexAllFaces() : GetDefaultInternalEnforcedVertex();
1122 }
1123
1124 BLSURFPlugin_Hypothesis::TEnfGroupName BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFacesGroup(const BLSURFPlugin_Hypothesis* hyp)
1125 {
1126   return hyp ? hyp->_GetInternalEnforcedVertexAllFacesGroup() : BLSURFPlugin_Hypothesis::TEnfGroupName();
1127 }
1128
1129 BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetAllEnforcedVertices(
1130     const BLSURFPlugin_Hypothesis* hyp) {
1131   return hyp ? hyp->_GetAllEnforcedVertices() : GetDefaultEnfVertexList();
1132 }
1133
1134 BLSURFPlugin_Hypothesis::TFaceEntryCoordsListMap BLSURFPlugin_Hypothesis::GetAllCoordsByFace(
1135     const BLSURFPlugin_Hypothesis* hyp) {
1136   return hyp ? hyp->_GetAllCoordsByFace() : GetDefaultFaceEntryCoordsListMap();
1137 }
1138
1139 BLSURFPlugin_Hypothesis::TCoordsEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByCoords(
1140     const BLSURFPlugin_Hypothesis* hyp) {
1141   return hyp ? hyp->_GetAllEnforcedVerticesByCoords() : GetDefaultCoordsEnfVertexMap();
1142 }
1143
1144 BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexEntryListMap BLSURFPlugin_Hypothesis::GetAllEnfVertexEntriesByFace(
1145     const BLSURFPlugin_Hypothesis* hyp) {
1146   return hyp ? hyp->_GetAllEnfVertexEntriesByFace() : GetDefaultFaceEntryEnfVertexEntryListMap();
1147 }
1148
1149 BLSURFPlugin_Hypothesis::TEnfVertexEntryEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByEnfVertexEntry(
1150     const BLSURFPlugin_Hypothesis* hyp) {
1151   return hyp ? hyp->_GetAllEnforcedVerticesByEnfVertexEntry() : GetDefaultEnfVertexEntryEnfVertexMap();
1152 }
1153
1154 std::set<int> BLSURFPlugin_Hypothesis::GetEnfVertexNodeIDs(TEnfGroupName theGroupName) throw (std::invalid_argument)
1155 {
1156   TGroupNameNodeIDMap::const_iterator it = _groupNameNodeIDMap.find(theGroupName);
1157   if (it != _groupNameNodeIDMap.end()) {
1158     return it->second;
1159   }
1160   std::ostringstream msg;
1161   msg << "No group " << theGroupName;
1162   throw std::invalid_argument(msg.str());
1163 }
1164
1165 void BLSURFPlugin_Hypothesis::AddEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID)
1166 {
1167   _groupNameNodeIDMap[theGroupName].insert(theNodeID);
1168 }
1169
1170 void BLSURFPlugin_Hypothesis::RemoveEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID) throw (std::invalid_argument)
1171 {
1172   TGroupNameNodeIDMap::iterator it = _groupNameNodeIDMap.find(theGroupName);
1173   if (it != _groupNameNodeIDMap.end()) {
1174     std::set<int>::iterator IDit = it->second.find(theNodeID);
1175     if (IDit != it->second.end())
1176       it->second.erase(IDit);
1177     std::ostringstream msg;
1178     msg << "No node IDs " << theNodeID << " for group " << theGroupName;
1179     throw std::invalid_argument(msg.str());
1180   }
1181   std::ostringstream msg;
1182   msg << "No group " << theGroupName;
1183   throw std::invalid_argument(msg.str());
1184 }
1185
1186
1187 //=============================================================================
1188 void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertexAllFaces(bool toEnforceInternalVertices) {
1189   if (toEnforceInternalVertices != _enforcedInternalVerticesAllFaces) {
1190     _enforcedInternalVerticesAllFaces = toEnforceInternalVertices;
1191     if (toEnforceInternalVertices)
1192       SetPhysicalMesh(PhysicalLocalSize);
1193     NotifySubMeshesHypothesisModification();
1194   }
1195 }
1196
1197
1198 //=============================================================================
1199 void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertexAllFacesGroup(BLSURFPlugin_Hypothesis::TEnfGroupName theGroupName) {
1200   if (string(theGroupName) != string(_enforcedInternalVerticesAllFacesGroup)) {
1201     _enforcedInternalVerticesAllFacesGroup = theGroupName;
1202     NotifySubMeshesHypothesisModification();
1203   }
1204 }
1205
1206 //=============================================================================
1207 std::ostream & BLSURFPlugin_Hypothesis::SaveTo(std::ostream & save) {
1208    // We must keep at least the same number of arguments when increasing the SALOME version
1209    // When BLSURF becomes CADMESH, some parameters were fused into a single one. Thus the same
1210    // parameter can be written several times to keep the old global number of parameters.
1211
1212    // Treat old options which are now in the advanced options
1213    TOptionValues::iterator op_val;
1214    int _decimesh = -1;
1215    int _preCADRemoveNanoEdges = -1;
1216    double _preCADEpsNano = -1.0;
1217    op_val = _option2value.find("respect_geometry");
1218    if (op_val != _option2value.end()) {
1219      std::string value = op_val->second;
1220      if (!value.empty())
1221        _decimesh = value.compare("1") == 0 ? 1 : 0;
1222    }
1223    op_val = _preCADoption2value.find("remove_tiny_edges");
1224    if (op_val != _preCADoption2value.end()) {
1225      std::string value = op_val->second;
1226      if (!value.empty())
1227        _preCADRemoveNanoEdges = value.compare("1") == 0 ? 1 : 0;
1228    }
1229    op_val = _preCADoption2value.find("tiny_edge_length");
1230    if (op_val != _preCADoption2value.end()) {
1231      std::string value = op_val->second;
1232      if (!value.empty())
1233        _preCADEpsNano = strtod(value.c_str(), NULL);
1234    }
1235    
1236   save << " " << (int) _topology << " " << (int) _physicalMesh << " " << (int) _geometricMesh << " " << _phySize << " "
1237       << _angleMesh << " " << _gradation << " " << (int) _quadAllowed << " " << _decimesh;
1238   save << " " << _minSize << " " << _maxSize << " " << _angleMesh << " " << _minSize << " " << _maxSize << " " << _verb;
1239   save << " " << (int) _preCADMergeEdges << " " << _preCADRemoveNanoEdges << " " << (int) _preCADDiscardInput << " " << _preCADEpsNano ;
1240   save << " " << (int) _enforcedInternalVerticesAllFaces;
1241   save << " " << (int) _phySizeRel << " " << (int) _minSizeRel << " " << (int) _maxSizeRel << " " << _chordalError ;
1242   save << " " << (int) _anisotropic << " " << _anisotropicRatio << " " << (int) _removeTinyEdges << " " << _tinyEdgeLength ;
1243   save << " " << (int) _badElementRemoval << " " << _badElementAspectRatio << " " << (int) _optimizeMesh << " " << (int) _quadraticMesh ;
1244   save << " " << (int) _preCADProcess3DTopology;
1245
1246   op_val = _option2value.begin();
1247   if (op_val != _option2value.end()) {
1248     save << " " << "__OPTIONS_BEGIN__";
1249     for (; op_val != _option2value.end(); ++op_val) {
1250       if (!op_val->second.empty())
1251         save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
1252     }
1253     save << " " << "__OPTIONS_END__";
1254   }
1255   
1256   op_val = _preCADoption2value.begin();
1257   if (op_val != _preCADoption2value.end()) {
1258     save << " " << "__PRECAD_OPTIONS_BEGIN__";
1259     for (; op_val != _preCADoption2value.end(); ++op_val) {
1260       if (!op_val->second.empty())
1261         save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
1262     }
1263     save << " " << "__PRECAD_OPTIONS_END__";
1264   }
1265
1266   TSizeMap::iterator it_sm = _sizeMap.begin();
1267   if (it_sm != _sizeMap.end()) {
1268     save << " " << "__SIZEMAP_BEGIN__";
1269     for (; it_sm != _sizeMap.end(); ++it_sm) {
1270       save << " " << it_sm->first << " " << it_sm->second << "%#"; // "%#" is a mark of value end
1271     }
1272     save << " " << "__SIZEMAP_END__";
1273   }
1274
1275   TSizeMap::iterator it_at = _attractors.begin();
1276   if (it_at != _attractors.end()) {
1277     save << " " << "__ATTRACTORS_BEGIN__";
1278     for (; it_at != _attractors.end(); ++it_at) {
1279       save << " " << it_at->first << " " << it_at->second << "%#"; // "%#" is a mark of value end
1280     }
1281     save << " " << "__ATTRACTORS_END__";
1282   }
1283   
1284   TAttractorMap::iterator it_At = _classAttractors.begin();
1285   if (it_At != _classAttractors.end()) {
1286     std::ostringstream test;
1287     save << " " << "__NEW_ATTRACTORS_BEGIN__";
1288     test << " " << "__NEW_ATTRACTORS_BEGIN__";
1289     for (; it_At != _classAttractors.end(); ++it_At) {
1290       std::vector<double> attParams;
1291       attParams   = it_At->second->GetParameters();
1292 //       double step = it_At->second->GetStep();
1293       save << " " << it_At->first;
1294       save << " " << it_At->second->GetAttractorEntry();
1295       save << " " << attParams[0]  << " " <<  attParams[1] << " " <<  attParams[2] << " " <<  attParams[3];
1296 //       save << " " << step;
1297       test << " " << it_At->first;
1298       test << " " << it_At->second->GetAttractorEntry();
1299       test << " " << attParams[0]  << " " <<  attParams[1] << " " <<  attParams[2] << " " <<  attParams[3];
1300 //       test << " " << step;
1301     }
1302     save << " " << "__NEW_ATTRACTORS_END__";
1303     test << " " << "__NEW_ATTRACTORS_END__";
1304     MESSAGE(" Attractor hypothesis saved as "<<test.str())
1305   }
1306
1307   TEnfVertexList::const_iterator it_enf = _enfVertexList.begin();
1308   if (it_enf != _enfVertexList.end()) {
1309     save << " " << "__ENFORCED_VERTICES_BEGIN__";
1310     for (; it_enf != _enfVertexList.end(); ++it_enf) {
1311       TEnfVertex *enfVertex = (*it_enf);
1312       save << " " << "__BEGIN_VERTEX__";
1313       if (!enfVertex->name.empty()) {
1314         save << " " << "__BEGIN_NAME__";
1315         save << " " << enfVertex->name;
1316         save << " " << "__END_NAME__";
1317       }
1318       if (!enfVertex->geomEntry.empty()) {
1319         save << " " << "__BEGIN_ENTRY__";
1320         save << " " << enfVertex->geomEntry;
1321         save << " " << "__END_ENTRY__";
1322       }
1323       if (!enfVertex->grpName.empty()) {
1324         save << " " << "__BEGIN_GROUP__";
1325         save << " " << enfVertex->grpName;
1326         save << " " << "__END_GROUP__";
1327       }
1328       if (enfVertex->coords.size()) {
1329         save << " " << "__BEGIN_COORDS__";
1330         for (int i=0;i<enfVertex->coords.size();i++)
1331           save << " " << enfVertex->coords[i];
1332         save << " " << "__END_COORDS__";
1333       }
1334       TEntryList::const_iterator faceEntriesIt = enfVertex->faceEntries.begin();
1335       bool hasFaces = false;
1336       if (faceEntriesIt != enfVertex->faceEntries.end()) {
1337         hasFaces = true;
1338         save << " " << "__BEGIN_FACELIST__";
1339       }
1340       for (; faceEntriesIt != enfVertex->faceEntries.end(); ++faceEntriesIt)
1341         save << " " << (*faceEntriesIt);
1342       if (hasFaces)
1343         save << " " << "__END_FACELIST__";
1344       save << " " << "__END_VERTEX__";
1345     }
1346     save << " " << "__ENFORCED_VERTICES_END__";
1347   }
1348
1349   return save;
1350 }
1351
1352 //=============================================================================
1353 std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load) {
1354   bool isOK = true;
1355   int i;
1356   double val;
1357   std::string option_or_sm;
1358
1359   isOK = (load >> i);
1360   if (isOK)
1361     _topology = (Topology) i;
1362   else
1363     load.clear(std::ios::badbit | load.rdstate());
1364
1365   isOK = (load >> i);
1366   if (isOK)
1367     _physicalMesh = (PhysicalMesh) i;
1368   else
1369     load.clear(std::ios::badbit | load.rdstate());
1370
1371   isOK = (load >> i);
1372   if (isOK)
1373     _geometricMesh = (GeometricMesh) i;
1374   else
1375     load.clear(std::ios::badbit | load.rdstate());
1376
1377   isOK = (load >> val);
1378   if (isOK)
1379     _phySize = val;
1380   else
1381     load.clear(std::ios::badbit | load.rdstate());
1382
1383   isOK = (load >> val);
1384   if (isOK)
1385     _angleMesh = val;
1386   else
1387     load.clear(std::ios::badbit | load.rdstate());
1388
1389   isOK = (load >> val);
1390   if (isOK)
1391     _gradation = val;
1392   else
1393     load.clear(std::ios::badbit | load.rdstate());
1394
1395   isOK = (load >> i);
1396   if (isOK)
1397     _quadAllowed = (bool) i;
1398   else
1399     load.clear(std::ios::badbit | load.rdstate());
1400
1401   isOK = (load >> i);
1402   if (isOK) {
1403     if ( i != -1) { // if value is -1, then this is no longer a standard option
1404       std::string & value = _option2value["respect_geometry"];
1405       bool _decimesh = (bool) i;
1406       value = _decimesh ? "1" : "0";
1407     }
1408   }
1409   else
1410     load.clear(std::ios::badbit | load.rdstate());
1411
1412   isOK = (load >> val);
1413   if (isOK)
1414     _minSize = val;
1415   else
1416     load.clear(std::ios::badbit | load.rdstate());
1417
1418   isOK = (load >> val);
1419   if (isOK)
1420     _maxSize = val;
1421   else
1422     load.clear(std::ios::badbit | load.rdstate());
1423
1424   isOK = (load >> val);
1425   if (isOK)
1426     // former parameter: get min value
1427     _angleMesh = min(val,_angleMesh);
1428   else
1429     load.clear(std::ios::badbit | load.rdstate());
1430
1431   isOK = (load >> val);
1432   if (isOK)
1433     // former parameter: get min value
1434     _minSize = min(val,_minSize);
1435   else
1436     load.clear(std::ios::badbit | load.rdstate());
1437
1438   isOK = (load >> val);
1439   if (isOK)
1440     // former parameter: get max value
1441     _maxSize = max(val,_maxSize);
1442   else
1443     load.clear(std::ios::badbit | load.rdstate());
1444
1445   isOK = (load >> i);
1446   if (isOK)
1447     _verb = i;
1448   else
1449     load.clear(std::ios::badbit | load.rdstate());
1450
1451   isOK = (load >> i);
1452   if (isOK)
1453     _preCADMergeEdges = (bool) i;
1454   else
1455     load.clear(std::ios::badbit | load.rdstate());
1456
1457   isOK = (load >> i);
1458   if (isOK) {
1459     if ( i != -1) { // if value is -1, then this is no longer a standard option
1460       std::string & value = _preCADoption2value["remove_tiny_edges"];
1461       bool _preCADRemoveNanoEdges = (bool) i;
1462       value = _preCADRemoveNanoEdges ? "1" : "0";
1463     }
1464   }
1465   else
1466     load.clear(std::ios::badbit | load.rdstate());
1467
1468   isOK = (load >> i);
1469   if (isOK)
1470     _preCADDiscardInput = (bool) i;
1471   else
1472     load.clear(std::ios::badbit | load.rdstate());
1473
1474   isOK = (load >> val);
1475   if (isOK) { // _preCADEpsNano
1476     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
1477       std::string & value = _preCADoption2value["tiny_edge_length"];
1478       std::ostringstream oss;
1479       oss << i;
1480       value = oss.str();
1481     }
1482   }
1483   else
1484     load.clear(std::ios::badbit | load.rdstate());
1485
1486   isOK = (load >> i);
1487   if (isOK)
1488     _enforcedInternalVerticesAllFaces = (bool) i;
1489   else
1490     load.clear(std::ios::badbit | load.rdstate());
1491
1492   // New options with MeshGems-CADSurf
1493
1494   bool hasCADSurfOptions = false;
1495   bool hasOptions = false;
1496   bool hasPreCADOptions = false;
1497   bool hasSizeMap = false;
1498   bool hasAttractor = false;
1499   bool hasNewAttractor = false;
1500   bool hasEnforcedVertex = false;
1501
1502   isOK = (load >> option_or_sm);
1503   if (isOK)
1504     if ( (option_or_sm == "1")||(option_or_sm == "0") ) {
1505       i = atoi(option_or_sm.c_str());
1506       hasCADSurfOptions = true;
1507       _phySizeRel = (bool) i;
1508     }
1509     if (option_or_sm == "__OPTIONS_BEGIN__")
1510       hasOptions = true;
1511     else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
1512       hasPreCADOptions = true;
1513     else if (option_or_sm == "__SIZEMAP_BEGIN__")
1514       hasSizeMap = true;
1515     else if (option_or_sm == "__ATTRACTORS_BEGIN__")
1516       hasAttractor = true;
1517     else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
1518       hasNewAttractor = true;
1519     else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1520       hasEnforcedVertex = true;
1521
1522   if (isOK && hasCADSurfOptions) {
1523     isOK = (load >> i);
1524     if (isOK)
1525       _minSizeRel = (bool) i;
1526     else
1527       load.clear(std::ios::badbit | load.rdstate());
1528
1529     isOK = (load >> i);
1530     if (isOK)
1531       _maxSizeRel = (bool) i;
1532     else
1533       load.clear(std::ios::badbit | load.rdstate());
1534
1535     isOK = (load >> val);
1536     if (isOK)
1537       _chordalError = val;
1538     else
1539       load.clear(std::ios::badbit | load.rdstate());
1540
1541     isOK = (load >> i);
1542     if (isOK)
1543       _anisotropic = (bool) i;
1544     else
1545       load.clear(std::ios::badbit | load.rdstate());
1546
1547     isOK = (load >> val);
1548     if (isOK)
1549       _anisotropicRatio = val;
1550     else
1551       load.clear(std::ios::badbit | load.rdstate());
1552
1553     isOK = (load >> i);
1554     if (isOK)
1555       _removeTinyEdges = (bool) i;
1556     else
1557       load.clear(std::ios::badbit | load.rdstate());
1558
1559     isOK = (load >> val);
1560     if (isOK)
1561       _tinyEdgeLength = val;
1562     else
1563       load.clear(std::ios::badbit | load.rdstate());
1564
1565     isOK = (load >> i);
1566     if (isOK)
1567       _badElementRemoval = (bool) i;
1568     else
1569       load.clear(std::ios::badbit | load.rdstate());
1570
1571     isOK = (load >> val);
1572     if (isOK)
1573       _badElementAspectRatio = val;
1574     else
1575       load.clear(std::ios::badbit | load.rdstate());
1576
1577     isOK = (load >> i);
1578     if (isOK)
1579       _optimizeMesh = (bool) i;
1580     else
1581       load.clear(std::ios::badbit | load.rdstate());
1582
1583     isOK = (load >> i);
1584     if (isOK)
1585       _quadraticMesh = (bool) i;
1586     else
1587       load.clear(std::ios::badbit | load.rdstate());
1588
1589     isOK = (load >> i);
1590     if (isOK)
1591       _preCADProcess3DTopology = (bool) i;
1592     else
1593       load.clear(std::ios::badbit | load.rdstate());
1594
1595   }
1596   
1597
1598   if (hasCADSurfOptions) {
1599     isOK = (load >> option_or_sm);
1600     if (isOK)
1601       if (option_or_sm == "__OPTIONS_BEGIN__")
1602         hasOptions = true;
1603       else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
1604         hasPreCADOptions = true;
1605       else if (option_or_sm == "__SIZEMAP_BEGIN__")
1606         hasSizeMap = true;
1607       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
1608         hasAttractor = true;
1609       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
1610         hasNewAttractor = true;
1611       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1612         hasEnforcedVertex = true;
1613   }
1614   
1615   std::string optName, optValue;
1616   while (isOK && hasOptions) {
1617     isOK = (load >> optName);
1618     if (isOK) {
1619       if (optName == "__OPTIONS_END__")
1620         break;
1621       isOK = (load >> optValue);
1622     }
1623     if (isOK) {
1624       std::string & value = _option2value[optName];
1625       value = optValue;
1626       int len = value.size();
1627       // continue reading until "%#" encountered
1628       while (value[len - 1] != '#' || value[len - 2] != '%') {
1629         isOK = (load >> optValue);
1630         if (isOK) {
1631           value += " ";
1632           value += optValue;
1633           len = value.size();
1634         } else {
1635           break;
1636         }
1637       }
1638       value[len - 2] = '\0'; //cut off "%#"
1639     }
1640   }
1641
1642   if (hasOptions) {
1643     isOK = (load >> option_or_sm);
1644     if (isOK)
1645       if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__")
1646         hasPreCADOptions = true;
1647       else if (option_or_sm == "__SIZEMAP_BEGIN__")
1648         hasSizeMap = true;
1649       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
1650         hasAttractor = true;
1651       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
1652         hasNewAttractor = true;
1653       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1654         hasEnforcedVertex = true;
1655   }
1656
1657   while (isOK && hasPreCADOptions) {
1658     isOK = (load >> optName);
1659     if (isOK) {
1660       if (optName == "__PRECAD_OPTIONS_END__")
1661         break;
1662       isOK = (load >> optValue);
1663     }
1664     if (isOK) {
1665       std::string & value = _preCADoption2value[optName];
1666       value = optValue;
1667       int len = value.size();
1668       // continue reading until "%#" encountered
1669       while (value[len - 1] != '#' || value[len - 2] != '%') {
1670         isOK = (load >> optValue);
1671         if (isOK) {
1672           value += " ";
1673           value += optValue;
1674           len = value.size();
1675         } else {
1676           break;
1677         }
1678       }
1679       value[len - 2] = '\0'; //cut off "%#"
1680     }
1681   }
1682
1683   if (hasPreCADOptions) {
1684     isOK = (load >> option_or_sm);
1685     if (isOK)
1686       if (option_or_sm == "__SIZEMAP_BEGIN__")
1687         hasSizeMap = true;
1688       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
1689         hasAttractor = true;
1690       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
1691         hasNewAttractor = true;
1692       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1693         hasEnforcedVertex = true;
1694   }
1695   
1696   std::string smEntry, smValue;
1697   while (isOK && hasSizeMap) {
1698     isOK = (load >> smEntry);
1699     if (isOK) {
1700       if (smEntry == "__SIZEMAP_END__")
1701         break;
1702       isOK = (load >> smValue);
1703     }
1704     if (isOK) {
1705       std::string & value2 = _sizeMap[smEntry];
1706       value2 = smValue;
1707       int len2 = value2.size();
1708       // continue reading until "%#" encountered
1709       while (value2[len2 - 1] != '#' || value2[len2 - 2] != '%') {
1710         isOK = (load >> smValue);
1711         if (isOK) {
1712           value2 += " ";
1713           value2 += smValue;
1714           len2 = value2.size();
1715         } else {
1716           break;
1717         }
1718       }
1719       value2[len2 - 2] = '\0'; //cut off "%#"
1720     }
1721   }
1722
1723   if (hasSizeMap) {
1724     isOK = (load >> option_or_sm);
1725     if (isOK)
1726       if (option_or_sm == "__ATTRACTORS_BEGIN__")
1727         hasAttractor = true;
1728       if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
1729         hasNewAttractor = true;
1730       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1731         hasEnforcedVertex = true;
1732   }
1733
1734   std::string atEntry, atValue;
1735   while (isOK && hasAttractor) {
1736     isOK = (load >> atEntry);
1737     if (isOK) {
1738       if (atEntry == "__ATTRACTORS_END__")
1739         break;
1740       isOK = (load >> atValue);
1741     }
1742     if (isOK) {
1743       std::string & value3 = _attractors[atEntry];
1744       value3 = atValue;
1745       int len3 = value3.size();
1746       // continue reading until "%#" encountered
1747       while (value3[len3 - 1] != '#' || value3[len3 - 2] != '%') {
1748         isOK = (load >> atValue);
1749         if (isOK) {
1750           value3 += " ";
1751           value3 += atValue;
1752           len3 = value3.size();
1753         } else {
1754           break;
1755         }
1756       }
1757       value3[len3 - 2] = '\0'; //cut off "%#"
1758     }
1759   }
1760
1761   if (hasAttractor) {
1762     isOK = (load >> option_or_sm);
1763     if (isOK)
1764       if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
1765         hasNewAttractor = true;
1766       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1767         hasEnforcedVertex = true;
1768   }
1769
1770   std::string newAtFaceEntry, atTestString;
1771   std::string newAtShapeEntry;
1772   double attParams[4];
1773   double step;
1774   while (isOK && hasNewAttractor) {
1775     std::cout<<"Load new attractor"<<std::endl;
1776     isOK = (load >> newAtFaceEntry);
1777     if (isOK) {
1778       if (newAtFaceEntry == "__NEW_ATTRACTORS_END__")
1779         break;
1780       isOK = (load >> newAtShapeEntry);
1781       if (!isOK)
1782     break;
1783       isOK = (load >> attParams[0]>>attParams[1]>>attParams[2]>>attParams[3]); //>>step);
1784     }
1785     if (isOK) {
1786       MESSAGE(" LOADING ATTRACTOR HYPOTHESIS ")
1787       const TopoDS_Shape attractorShape = BLSURFPlugin_Hypothesis::entryToShape(newAtShapeEntry);
1788       const TopoDS_Face faceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(newAtFaceEntry));
1789       BLSURFPlugin_Attractor* attractor = new BLSURFPlugin_Attractor(faceShape, attractorShape, newAtShapeEntry);//, step);
1790       attractor->SetParameters(attParams[0], attParams[1], attParams[2], attParams[3]);
1791       attractor->BuildMap();                     
1792       _classAttractors[newAtFaceEntry]=attractor;
1793     }
1794   }
1795   
1796   
1797   if (hasNewAttractor) {
1798     isOK = (load >> option_or_sm);
1799     if (isOK)
1800       if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1801         hasEnforcedVertex = true;
1802   }
1803
1804
1805 // 
1806 // Here is a example of the saved stream:
1807 // __ENFORCED_VERTICES_BEGIN__ 
1808 // __BEGIN_VERTEX__  => no name, no entry
1809 // __BEGIN_GROUP__ mon groupe __END_GROUP__
1810 // __BEGIN_COORDS__ 10 10 10 __END_COORDS__ 
1811 // __BEGIN_FACELIST__ 0:1:1:1:1 __END_FACELIST__ 
1812 // __END_VERTEX__ 
1813 // __BEGIN_VERTEX__ => no coords
1814 // __BEGIN_NAME__ mes points __END_NAME__ 
1815 // __BEGIN_ENTRY__ 0:1:1:4 __END_ENTRY__
1816 // __BEGIN_GROUP__ mon groupe __END_GROUP__
1817 // __BEGIN_FACELIST__ 0:1:1:1:3 __END_FACELIST__
1818 // __END_VERTEX__ 
1819 // __ENFORCED_VERTICES_END__
1820 // 
1821
1822   std::string enfSeparator;
1823   std::string enfName;
1824   std::string enfGeomEntry;
1825   std::string enfGroup;
1826   TEntryList enfFaceEntryList;
1827   double enfCoords[3];
1828   bool hasCoords = false;
1829   
1830   _faceEntryEnfVertexListMap.clear();
1831   _enfVertexList.clear();
1832   _faceEntryCoordsListMap.clear();
1833   _coordsEnfVertexMap.clear();
1834   _faceEntryEnfVertexEntryListMap.clear();
1835   _enfVertexEntryEnfVertexMap.clear();
1836   
1837   
1838   while (isOK && hasEnforcedVertex) {
1839     isOK = (load >> enfSeparator); // __BEGIN_VERTEX__
1840     TEnfVertex *enfVertex = new TEnfVertex();
1841 //     MESSAGE("enfSeparator: " <<enfSeparator);
1842     if (enfSeparator == "__ENFORCED_VERTICES_END__")
1843       break; // __ENFORCED_VERTICES_END__
1844     if (enfSeparator != "__BEGIN_VERTEX__")
1845       throw std::exception();
1846     
1847     while (isOK) {
1848       isOK = (load >> enfSeparator);
1849       MESSAGE("enfSeparator: " <<enfSeparator);
1850       if (enfSeparator == "__END_VERTEX__") {
1851         
1852         enfVertex->name = enfName;
1853         enfVertex->geomEntry = enfGeomEntry;
1854         enfVertex->grpName = enfGroup;
1855         enfVertex->coords.clear();
1856         if (hasCoords)
1857           enfVertex->coords.assign(enfCoords,enfCoords+3);
1858         enfVertex->faceEntries = enfFaceEntryList;
1859         
1860         _enfVertexList.insert(enfVertex);
1861         
1862         if (enfVertex->coords.size()) {
1863           _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
1864           for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) {
1865             _faceEntryCoordsListMap[(*it)].insert(enfVertex->coords);
1866             _faceEntryEnfVertexListMap[(*it)].insert(enfVertex);
1867           }
1868         }
1869         if (!enfVertex->geomEntry.empty()) {
1870           _enfVertexEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
1871           for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) {
1872             _faceEntryEnfVertexEntryListMap[(*it)].insert(enfVertex->geomEntry);
1873             _faceEntryEnfVertexListMap[(*it)].insert(enfVertex);
1874           }
1875         }
1876         
1877         enfName.clear();
1878         enfGeomEntry.clear();
1879         enfGroup.clear();
1880         enfFaceEntryList.clear();
1881         hasCoords = false;
1882         break; // __END_VERTEX__
1883       }
1884         
1885       if (enfSeparator == "__BEGIN_NAME__") {  // __BEGIN_NAME__
1886         while (isOK && (enfSeparator != "__END_NAME__")) {
1887           isOK = (load >> enfSeparator);
1888           if (enfSeparator != "__END_NAME__") {
1889             if (!enfName.empty())
1890               enfName += " ";
1891             enfName += enfSeparator;
1892           }
1893         }
1894         MESSAGE("enfName: " <<enfName);
1895       }
1896         
1897       if (enfSeparator == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
1898         isOK = (load >> enfGeomEntry);
1899         isOK = (load >> enfSeparator); // __END_ENTRY__
1900         if (enfSeparator != "__END_ENTRY__")
1901           throw std::exception();
1902         MESSAGE("enfGeomEntry: " <<enfGeomEntry);
1903       }
1904         
1905       if (enfSeparator == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
1906         while (isOK && (enfSeparator != "__END_GROUP__")) {
1907           isOK = (load >> enfSeparator);
1908           if (enfSeparator != "__END_GROUP__") {
1909             if (!enfGroup.empty())
1910               enfGroup += " ";
1911             enfGroup += enfSeparator;
1912           }
1913         }
1914         MESSAGE("enfGroup: " <<enfGroup);
1915       }
1916         
1917       if (enfSeparator == "__BEGIN_COORDS__") {  // __BEGIN_COORDS__
1918         hasCoords = true;
1919         isOK = (load >> enfCoords[0] >> enfCoords[1] >> enfCoords[2]);
1920         isOK = (load >> enfSeparator); // __END_COORDS__
1921         if (enfSeparator != "__END_COORDS__")
1922           throw std::exception();
1923         MESSAGE("enfCoords: " << enfCoords[0] <<","<< enfCoords[1] <<","<< enfCoords[2]);
1924       } 
1925         
1926       if (enfSeparator == "__BEGIN_FACELIST__") {  // __BEGIN_FACELIST__
1927         while (isOK && (enfSeparator != "__END_FACELIST__")) {
1928           isOK = (load >> enfSeparator);
1929           if (enfSeparator != "__END_FACELIST__") {
1930             enfFaceEntryList.insert(enfSeparator);
1931             MESSAGE(enfSeparator << " was inserted into enfFaceEntryList");
1932           }
1933         }
1934       } 
1935     }
1936   }
1937
1938   return load;
1939 }
1940
1941 //=============================================================================
1942 std::ostream & operator <<(std::ostream & save, BLSURFPlugin_Hypothesis & hyp) {
1943   return hyp.SaveTo(save);
1944 }
1945
1946 //=============================================================================
1947 std::istream & operator >>(std::istream & load, BLSURFPlugin_Hypothesis & hyp) {
1948   return hyp.LoadFrom(load);
1949 }
1950
1951 //================================================================================
1952 /*!
1953  * \brief Does nothing
1954  */
1955 //================================================================================
1956
1957 bool BLSURFPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape) {
1958   return false;
1959 }
1960
1961 //================================================================================
1962 /*!
1963  * \brief Returns default global constant physical size given a default value of element length ratio
1964  */
1965 //================================================================================
1966
1967 double BLSURFPlugin_Hypothesis::GetDefaultPhySize(double diagonal, double bbSegmentation) {
1968   if (bbSegmentation != 0 && diagonal != 0)
1969     return diagonal / bbSegmentation ;
1970   return 10;
1971 }
1972
1973 //================================================================================
1974 /*!
1975  * \brief Returns default min size given a default value of element length ratio
1976  */
1977 //================================================================================
1978
1979 double BLSURFPlugin_Hypothesis::GetDefaultMinSize(double diagonal) {
1980   if (diagonal != 0)
1981     return diagonal / 1000.0 ;
1982   return undefinedDouble();
1983 }
1984
1985 //================================================================================
1986 /*!
1987  * \brief Returns default max size given a default value of element length ratio
1988  */
1989 //================================================================================
1990
1991 double BLSURFPlugin_Hypothesis::GetDefaultMaxSize(double diagonal) {
1992   if (diagonal != 0)
1993     return diagonal / 5.0 ;
1994   return undefinedDouble();
1995 }
1996
1997 //================================================================================
1998 /*!
1999  * \brief Returns default chordal error given a default value of element length ratio
2000  */
2001 //================================================================================
2002
2003 double BLSURFPlugin_Hypothesis::GetDefaultChordalError(double diagonal) {
2004   if (diagonal != 0)
2005     return diagonal;
2006   return undefinedDouble();
2007 }
2008
2009 //================================================================================
2010 /*!
2011  * \brief Returns default tiny edge length given a default value of element length ratio
2012  */
2013 //================================================================================
2014
2015 double BLSURFPlugin_Hypothesis::GetDefaultTinyEdgeLength(double diagonal) {
2016   if (diagonal != 0)
2017     return diagonal * 1e-6 ;
2018   return undefinedDouble();
2019 }
2020
2021 //=============================================================================
2022 /*!
2023  * \brief Initialize my parameter values by default parameters.
2024  *  \retval bool - true if parameter values have been successfully defined
2025  */
2026 //=============================================================================
2027
2028 bool BLSURFPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh) {
2029   double diagonal = dflts._elemLength*_gen->GetBoundaryBoxSegmentation();
2030   _phySize = GetDefaultPhySize(diagonal, _gen->GetBoundaryBoxSegmentation());
2031   _minSize = GetDefaultMinSize(diagonal);
2032   _maxSize = GetDefaultMaxSize(diagonal);
2033   _chordalError = GetDefaultChordalError(diagonal);
2034   _tinyEdgeLength = GetDefaultTinyEdgeLength(diagonal);
2035
2036   return true;
2037 //   return bool(_phySize = dflts._elemLength);
2038 }