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