Salome HOME
Update copyright
[plugins/blsurfplugin.git] / src / BLSURFPlugin / BLSURFPlugin_Hypothesis.cxx
1 // Copyright (C) 2007-2011  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), _topology(GetDefaultTopology()),
45   _physicalMesh(GetDefaultPhysicalMesh()),
46   _phySize(GetDefaultPhySize()),
47   _phyMax(GetDefaultMaxSize()),
48   _phyMin(GetDefaultMinSize()),
49   _hgeoMax(GetDefaultMaxSize()),
50   _hgeoMin(GetDefaultMinSize()), 
51   _geometricMesh(GetDefaultGeometricMesh()),
52   _angleMeshS(GetDefaultAngleMeshS()),
53   _angleMeshC(GetDefaultAngleMeshC()),
54   _gradation(GetDefaultGradation()),
55   _quadAllowed(GetDefaultQuadAllowed()),
56   _decimesh(GetDefaultDecimesh()),
57   _verb(GetDefaultVerbosity()),
58   _sizeMap(GetDefaultSizeMap()),
59   _attractors(GetDefaultSizeMap()),
60   _classAttractors(GetDefaultAttractorMap()),
61   _faceEntryEnfVertexListMap(GetDefaultFaceEntryEnfVertexListMap()),
62   _enfVertexList(GetDefaultEnfVertexList()),
63   _faceEntryCoordsListMap(GetDefaultFaceEntryCoordsListMap()),
64   _coordsEnfVertexMap(GetDefaultCoordsEnfVertexMap()),
65   _faceEntryEnfVertexEntryListMap(GetDefaultFaceEntryEnfVertexEntryListMap()),
66   _enfVertexEntryEnfVertexMap(GetDefaultEnfVertexEntryEnfVertexMap()),
67   _groupNameNodeIDMap(GetDefaultGroupNameNodeIDMap())
68 /* TODO GROUPS
69  _groupNameEnfVertexListMap(GetDefaultGroupNameEnfVertexListMap()),
70  _enfVertexGroupNameMap(GetDefaultEnfVertexGroupNameMap())
71  */
72 {
73   _name = "BLSURF_Parameters";
74   _param_algo_dim = 2;
75
76   // to disable writing boundaries
77   //_phyMin = _phyMax = _hgeoMin = _hgeoMax = undefinedDouble();
78
79
80   const char* intOptionNames[] = { "addsurf_ivertex", "background", "CheckAdjacentEdges", "CheckCloseEdges",
81       "CheckWellDefined", "coiter", "communication", "decim", "export_flag", "file_h", "frontal", "gridnu", "gridnv",
82       "hinterpol_flag", "hmean_flag", "intermedfile", "memory", "normals", "optim", "pardom_flag", "pinch", "refs",
83       "rigid", "surforient", "tconf", "topo_collapse", "" // mark of end
84       };
85   const char* doubleOptionNames[] = { "addsurf_angle", "addsurf_R", "addsurf_H", "addsurf_FG", "addsurf_r",
86       "addsurf_PA", "angle_compcurv", "angle_ridge", "CoefRectangle", "eps_collapse", "eps_ends", "eps_pardom", "LSS",
87       "topo_eps1", "topo_eps2", "" // mark of end
88       };
89   const char* charOptionNames[] = { "export_format", "export_option", "import_option", "prefix", "" // mark of end
90       };
91
92   int i = 0;
93   while (intOptionNames[i][0])
94     _option2value[intOptionNames[i++]].clear();
95
96   i = 0;
97   while (doubleOptionNames[i][0]) {
98     _doubleOptions.insert(doubleOptionNames[i]);
99     _option2value[doubleOptionNames[i++]].clear();
100   }
101   i = 0;
102   while (charOptionNames[i][0]) {
103     _charOptions.insert(charOptionNames[i]);
104     _option2value[charOptionNames[i++]].clear();
105   }
106
107   _sizeMap.clear();
108   _attractors.clear();
109   _faceEntryEnfVertexListMap.clear();
110   _enfVertexList.clear();
111   _faceEntryCoordsListMap.clear();
112   _coordsEnfVertexMap.clear();
113   _faceEntryEnfVertexEntryListMap.clear();
114   _enfVertexEntryEnfVertexMap.clear();
115   _groupNameNodeIDMap.clear();
116
117   /* TODO GROUPS
118    _groupNameEnfVertexListMap.clear();
119    _enfVertexGroupNameMap.clear();
120    */
121 }
122
123 TopoDS_Shape BLSURFPlugin_Hypothesis::entryToShape(std::string entry)
124 {
125   MESSAGE("BLSURFPlugin_Hypothesis::entryToShape "<<entry );
126   GEOM::GEOM_Object_var aGeomObj;
127   SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen();
128   SALOMEDS::Study_ptr myStudy = smeshGen_i->GetCurrentStudy();
129   
130   TopoDS_Shape S = TopoDS_Shape();
131   SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() );
132   SALOMEDS::GenericAttribute_var anAttr;
133
134   if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
135     SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
136     CORBA::String_var aVal = anIOR->Value();
137     CORBA::Object_var obj = myStudy->ConvertIORToObject(aVal);
138     aGeomObj = GEOM::GEOM_Object::_narrow(obj);
139   }
140   if ( !aGeomObj->_is_nil() )
141     S = smeshGen_i->GeomObjectToShape( aGeomObj.in() );
142   return S;
143 }
144
145 //=============================================================================
146 void BLSURFPlugin_Hypothesis::SetTopology(Topology theTopology) {
147   if (theTopology != _topology) {
148     _topology = theTopology;
149     NotifySubMeshesHypothesisModification();
150   }
151 }
152
153 //=============================================================================
154 void BLSURFPlugin_Hypothesis::SetPhysicalMesh(PhysicalMesh thePhysicalMesh) {
155   if (thePhysicalMesh != _physicalMesh) {
156     _physicalMesh = thePhysicalMesh;
157     switch (_physicalMesh) {
158       case DefaultSize:
159       default:
160         _phySize = GetDefaultPhySize();
161         _gradation = GetDefaultGradation();
162         break;
163     }
164     NotifySubMeshesHypothesisModification();
165   }
166 }
167
168 //=============================================================================
169 void BLSURFPlugin_Hypothesis::SetPhySize(double theVal) {
170   if (theVal != _phySize) {
171     _phySize = theVal;
172     NotifySubMeshesHypothesisModification();
173   }
174 }
175
176 //=============================================================================
177 void BLSURFPlugin_Hypothesis::SetPhyMin(double theMinSize) {
178   if (theMinSize != _phyMin) {
179     _phyMin = theMinSize;
180     NotifySubMeshesHypothesisModification();
181   }
182 }
183
184 //=============================================================================
185 void BLSURFPlugin_Hypothesis::SetPhyMax(double theMaxSize) {
186   if (theMaxSize != _phyMax) {
187     _phyMax = theMaxSize;
188     NotifySubMeshesHypothesisModification();
189   }
190 }
191
192 //=============================================================================
193 void BLSURFPlugin_Hypothesis::SetGeoMin(double theMinSize) {
194   if (theMinSize != _hgeoMin) {
195     _hgeoMin = theMinSize;
196     NotifySubMeshesHypothesisModification();
197   }
198 }
199
200 //=============================================================================
201 void BLSURFPlugin_Hypothesis::SetGeoMax(double theMaxSize) {
202   if (theMaxSize != _hgeoMax) {
203     _hgeoMax = theMaxSize;
204     NotifySubMeshesHypothesisModification();
205   }
206 }
207
208 //=============================================================================
209 void BLSURFPlugin_Hypothesis::SetGeometricMesh(GeometricMesh theGeometricMesh) {
210   if (theGeometricMesh != _geometricMesh) {
211     _geometricMesh = theGeometricMesh;
212     switch (_geometricMesh) {
213       case DefaultGeom:
214       default:
215         _angleMeshS = GetDefaultAngleMeshS();
216         _gradation = GetDefaultGradation();
217         break;
218     }
219     NotifySubMeshesHypothesisModification();
220   }
221 }
222
223 //=============================================================================
224 void BLSURFPlugin_Hypothesis::SetAngleMeshS(double theVal) {
225   if (theVal != _angleMeshS) {
226     _angleMeshS = theVal;
227     NotifySubMeshesHypothesisModification();
228   }
229 }
230
231 //=============================================================================
232 void BLSURFPlugin_Hypothesis::SetAngleMeshC(double theVal) {
233   if (theVal != _angleMeshC) {
234     _angleMeshC = theVal;
235     NotifySubMeshesHypothesisModification();
236   }
237 }
238
239 //=============================================================================
240 void BLSURFPlugin_Hypothesis::SetGradation(double theVal) {
241   if (theVal != _gradation) {
242     _gradation = theVal;
243     NotifySubMeshesHypothesisModification();
244   }
245 }
246
247 //=============================================================================
248 void BLSURFPlugin_Hypothesis::SetQuadAllowed(bool theVal) {
249   if (theVal != _quadAllowed) {
250     _quadAllowed = theVal;
251     NotifySubMeshesHypothesisModification();
252   }
253 }
254
255 //=============================================================================
256 void BLSURFPlugin_Hypothesis::SetDecimesh(bool theVal) {
257   if (theVal != _decimesh) {
258     _decimesh = theVal;
259     NotifySubMeshesHypothesisModification();
260   }
261 }
262
263 //=============================================================================
264 void BLSURFPlugin_Hypothesis::SetVerbosity(int theVal) {
265   if (theVal != _verb) {
266     _verb = theVal;
267     NotifySubMeshesHypothesisModification();
268   }
269 }
270 //=============================================================================
271 void BLSURFPlugin_Hypothesis::SetOptionValue(const std::string& optionName, const std::string& optionValue)
272     throw (std::invalid_argument) {
273   TOptionValues::iterator op_val = _option2value.find(optionName);
274   if (op_val == _option2value.end()) {
275     std::string msg = "Unknown BLSURF option: '" + optionName + "'";
276     throw std::invalid_argument(msg);
277   }
278   if (op_val->second != optionValue) {
279     const char* ptr = optionValue.c_str();
280     // strip white spaces
281     while (ptr[0] == ' ')
282       ptr++;
283     int i = strlen(ptr);
284     while (i != 0 && ptr[i - 1] == ' ')
285       i--;
286     // check value type
287     bool typeOk = true;
288     std::string typeName;
289     if (i == 0) {
290       // empty string
291     } else if (_charOptions.find(optionName) != _charOptions.end()) {
292       // do not check strings
293     } else if (_doubleOptions.find(optionName) != _doubleOptions.end()) {
294       // check if value is double
295       char * endPtr;
296       strtod(ptr, &endPtr);
297       typeOk = (ptr != endPtr);
298       typeName = "real";
299     } else {
300       // check if value is int
301       char * endPtr;
302       strtol(ptr, &endPtr, 10);
303       typeOk = (ptr != endPtr);
304       typeName = "integer";
305     }
306     if (!typeOk) {
307       std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName;
308       throw std::invalid_argument(msg);
309     }
310     op_val->second = optionValue;
311     NotifySubMeshesHypothesisModification();
312   }
313 }
314
315 //=============================================================================
316 std::string BLSURFPlugin_Hypothesis::GetOptionValue(const std::string& optionName) throw (std::invalid_argument) {
317   TOptionValues::iterator op_val = _option2value.find(optionName);
318   if (op_val == _option2value.end()) {
319     std::string msg = "Unknown BLSURF option: <";
320     msg += optionName + ">";
321     throw std::invalid_argument(msg);
322   }
323   return op_val->second;
324 }
325
326 //=============================================================================
327 void BLSURFPlugin_Hypothesis::ClearOption(const std::string& optionName) {
328   TOptionValues::iterator op_val = _option2value.find(optionName);
329   if (op_val != _option2value.end())
330     op_val->second.clear();
331 }
332
333 //=======================================================================
334 //function : SetSizeMapEntry
335 //=======================================================================
336 void BLSURFPlugin_Hypothesis::SetSizeMapEntry(const std::string& entry, const std::string& sizeMap) {
337   if (_sizeMap[entry].compare(sizeMap) != 0) {
338     _sizeMap[entry] = sizeMap;
339     NotifySubMeshesHypothesisModification();
340   }
341 }
342
343 //=======================================================================
344 //function : GetSizeMapEntry
345 //=======================================================================
346 std::string BLSURFPlugin_Hypothesis::GetSizeMapEntry(const std::string& entry) {
347   TSizeMap::iterator it = _sizeMap.find(entry);
348   if (it != _sizeMap.end())
349     return it->second;
350   else
351     return "No_Such_Entry";
352 }
353
354 /*!
355  * \brief Return the size maps
356  */
357 BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetSizeMapEntries(const BLSURFPlugin_Hypothesis* hyp) {
358   return hyp ? hyp->_GetSizeMapEntries() : GetDefaultSizeMap();
359 }
360
361 //=======================================================================
362 //function : SetAttractorEntry
363 //=======================================================================
364 void BLSURFPlugin_Hypothesis::SetAttractorEntry(const std::string& entry, const std::string& attractor) {
365   if (_attractors[entry].compare(attractor) != 0) {
366     _attractors[entry] = attractor;
367     NotifySubMeshesHypothesisModification();
368   }
369 }
370
371 //=======================================================================
372 //function : GetAttractorEntry
373 //=======================================================================
374 std::string BLSURFPlugin_Hypothesis::GetAttractorEntry(const std::string& entry) {
375   TSizeMap::iterator it = _attractors.find(entry);
376   if (it != _attractors.end())
377     return it->second;
378   else
379     return "No_Such_Entry";
380 }
381
382 /*!
383  * \brief Return the attractors
384  */
385 BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetAttractorEntries(const BLSURFPlugin_Hypothesis* hyp) {
386   return hyp ? hyp->_GetAttractorEntries() : GetDefaultSizeMap();
387 }
388
389 //=======================================================================
390 //function : SetClassAttractorEntry
391 //=======================================================================
392 void BLSURFPlugin_Hypothesis::SetClassAttractorEntry(const std::string& entry, const std::string& attEntry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius)
393 {
394   // The new attractor can't be defined on the same face as another sizemap
395   TSizeMap::iterator it  = _sizeMap.find( entry );
396   if ( it != _sizeMap.end() ) {
397     _sizeMap.erase(it);
398     NotifySubMeshesHypothesisModification();
399   }
400   else {
401     TSizeMap::iterator itAt  = _attractors.find( entry );
402     if ( itAt != _attractors.end() ) {
403       _attractors.erase(itAt);
404       NotifySubMeshesHypothesisModification();
405     }
406   }
407   
408   const TopoDS_Shape AttractorShape = BLSURFPlugin_Hypothesis::entryToShape(attEntry);
409   const TopoDS_Face FaceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(entry));
410   bool attExists = (_classAttractors.find(entry) != _classAttractors.end());
411   double u1,u2,v1,v2, diag;
412   
413   if ( !attExists || (attExists && _classAttractors[entry]->GetAttractorEntry().compare(attEntry) != 0)){ 
414     ShapeAnalysis::GetFaceUVBounds(FaceShape,u1,u2,v1,v2);
415 //     diag = sqrt((u2 - u1) * (u2 - u1) + (v2 - v1) * (v2 - v1));  
416     BLSURFPlugin_Attractor* myAttractor = new BLSURFPlugin_Attractor(FaceShape, AttractorShape, attEntry);//, 0.1 ); // test 0.002 * diag); 
417     myAttractor->BuildMap();
418     myAttractor->SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius);
419     _classAttractors[entry] = myAttractor;
420     NotifySubMeshesHypothesisModification();
421   }
422   else {
423     _classAttractors[entry]->SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius);
424     if (!_classAttractors[entry]->IsMapBuilt()){
425       _classAttractors[entry]->BuildMap();
426     }
427     NotifySubMeshesHypothesisModification();
428   }
429     
430 }
431
432 //=======================================================================
433 //function : SetConstantSizeOnAdjacentFaces
434 //=======================================================================
435 // TODO uncomment and test (include the needed .hxx)
436 // SetConstantSizeOnAdjacentFaces(myShape, att_entry, startSize, endSize = user_size, const_dist  ) {
437 //   TopTools_IndexedMapOfShapListOdShape anEdge2FaceMap;
438 //   TopExp::MapShapesAnAncestors(myShape,TopAbs_EDGE, TopAbs_FACE, anEdge2FaceMap);
439 //   TopTools_IndexedMapOfShapListOdShape::iterator it;
440 //   for (it = anEdge2FaceMap.begin();it != anEdge2FaceMap.end();it++){
441 //       SetClassAttractorEntry((*it).first, att_entry, startSize, endSize, 0, const_dist)
442 //   }
443
444
445
446
447
448
449 //=======================================================================
450 //function : GetClassAttractorEntry
451 //=======================================================================
452 // BLSURFPlugin_Attractor&  BLSURFPlugin_Hypothesis::GetClassAttractorEntry(const std::string& entry)
453 // {
454 //  TAttractorMap::iterator it  = _classAttractors.find( entry );
455 //  if ( it != _classAttractors.end() )
456 //    return it->second;
457 //  else
458 //    return "No_Such_Entry";
459 // }
460 // 
461   /*!
462    * \brief Return the map of attractor instances
463    */
464 BLSURFPlugin_Hypothesis::TAttractorMap BLSURFPlugin_Hypothesis::GetClassAttractorEntries(const BLSURFPlugin_Hypothesis* hyp)
465 {
466     return hyp ? hyp->_GetClassAttractorEntries():GetDefaultAttractorMap();
467 }
468
469 //=======================================================================
470 //function : ClearEntry
471 //=======================================================================
472 void BLSURFPlugin_Hypothesis::ClearEntry(const std::string& entry)
473 {
474  TSizeMap::iterator it  = _sizeMap.find( entry );
475  
476  if ( it != _sizeMap.end() ) {
477    _sizeMap.erase(it);
478    NotifySubMeshesHypothesisModification();
479  }
480  else {
481    TSizeMap::iterator itAt  = _attractors.find( entry );
482    if ( itAt != _attractors.end() ) {
483      _attractors.erase(itAt);
484      NotifySubMeshesHypothesisModification();
485    }
486    else {
487      TAttractorMap::iterator it_clAt = _classAttractors.find( entry );
488      if ( it_clAt != _classAttractors.end() ) {
489        _classAttractors.erase(it_clAt);
490        MESSAGE("_classAttractors.size() = "<<_classAttractors.size())
491        NotifySubMeshesHypothesisModification();
492      }
493      else
494        std::cout<<"No_Such_Entry"<<std::endl;
495    }
496  }
497 }
498
499 //=======================================================================
500 //function : ClearSizeMaps
501 //=======================================================================
502 void BLSURFPlugin_Hypothesis::ClearSizeMaps() {
503   _sizeMap.clear();
504   _attractors.clear();
505   _classAttractors.clear();
506 }
507
508 //=======================================================================
509 //function : SetEnforcedVertex
510 //=======================================================================
511 bool BLSURFPlugin_Hypothesis::SetEnforcedVertex(TEntry theFaceEntry, TEnfName theVertexName, TEntry theVertexEntry,
512                                                 TEnfGroupName theGroupName, double x, double y, double z) {
513
514   MESSAGE("BLSURFPlugin_Hypothesis::SetEnforcedVertex("<< theFaceEntry << ", "
515       << x << ", " << y << ", " << z << ", " << theVertexName << ", " << theVertexEntry << ", " << theGroupName << ")");
516
517   //  TEnfVertexList::iterator it;
518   bool toNotify = false;
519   bool toCreate = true;
520
521   TEnfVertex *oldEnVertex;
522   TEnfVertex *newEnfVertex = new TEnfVertex();
523   newEnfVertex->name = theVertexName;
524   newEnfVertex->geomEntry = theVertexEntry;
525   newEnfVertex->coords.clear();
526   if (theVertexEntry == "") {
527     newEnfVertex->coords.push_back(x);
528     newEnfVertex->coords.push_back(y);
529     newEnfVertex->coords.push_back(z);
530   }
531   newEnfVertex->grpName = theGroupName;
532   newEnfVertex->faceEntries.clear();
533   newEnfVertex->faceEntries.insert(theFaceEntry);
534   
535   
536   // update _enfVertexList
537   TEnfVertexList::iterator it = _enfVertexList.find(newEnfVertex);
538   if (it != _enfVertexList.end()) {
539     toCreate = false;
540     oldEnVertex = (*it);
541     MESSAGE("Enforced Vertex was found => Update");
542     if (oldEnVertex->name != theVertexName) {
543       MESSAGE("Update name from \"" << oldEnVertex->name << "\" to \"" << theVertexName << "\"");
544       oldEnVertex->name = theVertexName;
545       toNotify = true;
546     }
547     if (oldEnVertex->grpName != theGroupName) {
548       MESSAGE("Update group name from \"" << oldEnVertex->grpName << "\" to \"" << theGroupName << "\"");
549       oldEnVertex->grpName = theGroupName;
550       toNotify = true;
551     }
552     TEntryList::iterator it_faceEntries = oldEnVertex->faceEntries.find(theFaceEntry);
553     if (it_faceEntries == oldEnVertex->faceEntries.end()) {
554       MESSAGE("Update face list by adding \"" << theFaceEntry << "\"");
555       oldEnVertex->faceEntries.insert(theFaceEntry);
556       _faceEntryEnfVertexListMap[theFaceEntry].insert(oldEnVertex);
557       toNotify = true;
558     }
559     if (toNotify) {
560       // update map coords / enf vertex if needed
561       if (oldEnVertex->coords.size()) {
562         _coordsEnfVertexMap[oldEnVertex->coords] = oldEnVertex;
563         _faceEntryCoordsListMap[theFaceEntry].insert(oldEnVertex->coords);
564       }
565
566       // update map geom entry / enf vertex if needed
567       if (oldEnVertex->geomEntry != "") {
568         _enfVertexEntryEnfVertexMap[oldEnVertex->geomEntry] = oldEnVertex;
569         _faceEntryEnfVertexEntryListMap[theFaceEntry].insert(oldEnVertex->geomEntry);
570       }
571     }
572   }
573
574 //   //////// CREATE ////////////
575   if (toCreate) {
576     toNotify = true;
577     MESSAGE("Creating new enforced vertex");
578     _faceEntryEnfVertexListMap[theFaceEntry].insert(newEnfVertex);
579     _enfVertexList.insert(newEnfVertex);
580     if (theVertexEntry == "") {
581       _faceEntryCoordsListMap[theFaceEntry].insert(newEnfVertex->coords);
582       _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex;
583     }
584     else {
585       _faceEntryEnfVertexEntryListMap[theFaceEntry].insert(newEnfVertex->geomEntry);
586       _enfVertexEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex;
587     }
588   }
589
590   if (toNotify)
591     NotifySubMeshesHypothesisModification();
592
593   MESSAGE("BLSURFPlugin_Hypothesis::SetEnforcedVertex END");
594   return toNotify;
595 }
596
597
598 //=======================================================================
599 //function : GetEnforcedVertices
600 //=======================================================================
601
602 BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetEnfVertexList(const TEntry& theFaceEntry)
603     throw (std::invalid_argument) {
604
605   if (_faceEntryEnfVertexListMap.count(theFaceEntry) > 0)
606     return _faceEntryEnfVertexListMap[theFaceEntry];
607   else
608     return GetDefaultEnfVertexList();
609
610   std::ostringstream msg;
611   msg << "No enforced vertex for face entry " << theFaceEntry;
612   throw std::invalid_argument(msg.str());
613 }
614
615 //=======================================================================
616 //function : GetEnfVertexCoordsList
617 //=======================================================================
618
619 BLSURFPlugin_Hypothesis::TEnfVertexCoordsList BLSURFPlugin_Hypothesis::GetEnfVertexCoordsList(
620     const TEntry& theFaceEntry) throw (std::invalid_argument) {
621
622   if (_faceEntryCoordsListMap.count(theFaceEntry) > 0)
623     return _faceEntryCoordsListMap[theFaceEntry];
624
625   std::ostringstream msg;
626   msg << "No enforced vertex coords for face entry " << theFaceEntry;
627   throw std::invalid_argument(msg.str());
628 }
629
630 //=======================================================================
631 //function : GetEnfVertexEntryList
632 //=======================================================================
633
634 BLSURFPlugin_Hypothesis::TEntryList BLSURFPlugin_Hypothesis::GetEnfVertexEntryList(const TEntry& theFaceEntry)
635     throw (std::invalid_argument) {
636
637   if (_faceEntryEnfVertexEntryListMap.count(theFaceEntry) > 0)
638     return _faceEntryEnfVertexEntryListMap[theFaceEntry];
639
640   std::ostringstream msg;
641   msg << "No enforced vertex entry for face entry " << theFaceEntry;
642   throw std::invalid_argument(msg.str());
643 }
644
645 //=======================================================================
646 //function : GetEnfVertex(TEnfVertexCoords coords)
647 //=======================================================================
648
649 BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(TEnfVertexCoords coords)
650     throw (std::invalid_argument) {
651
652   if (_coordsEnfVertexMap.count(coords) > 0)
653     return _coordsEnfVertexMap[coords];
654
655   std::ostringstream msg;
656   msg << "No enforced vertex with coords (" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")";
657   throw std::invalid_argument(msg.str());
658 }
659
660 //=======================================================================
661 //function : GetEnfVertex(const TEntry& theEnfVertexEntry)
662 //=======================================================================
663
664 BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(const TEntry& theEnfVertexEntry)
665     throw (std::invalid_argument) {
666
667   if (_enfVertexEntryEnfVertexMap.count(theEnfVertexEntry) > 0)
668     return _enfVertexEntryEnfVertexMap[theEnfVertexEntry];
669
670   std::ostringstream msg;
671   msg << "No enforced vertex with entry " << theEnfVertexEntry;
672   throw std::invalid_argument(msg.str());
673 }
674
675 //=======================================================================
676 //function : ClearEnforcedVertex
677 //=======================================================================
678
679 bool BLSURFPlugin_Hypothesis::ClearEnforcedVertex(const TEntry& theFaceEntry, double x, double y, double z,
680     const TEntry& theVertexEntry) throw (std::invalid_argument) {
681
682   bool toNotify = false;
683   std::ostringstream msg;
684   TEnfVertex *oldEnfVertex;
685   TEnfVertexCoords coords;
686   coords.clear();
687   coords.push_back(x);
688   coords.push_back(y);
689   coords.push_back(z);
690
691   // check that enf vertex with given enf vertex entry exists
692   TEnfVertexEntryEnfVertexMap::iterator it_enfVertexEntry = _enfVertexEntryEnfVertexMap.find(theVertexEntry);
693   if (it_enfVertexEntry != _enfVertexEntryEnfVertexMap.end()) {
694     // Success
695     MESSAGE("Found enforced vertex with geom entry " << theVertexEntry);
696     oldEnfVertex = it_enfVertexEntry->second;
697
698     _enfVertexEntryEnfVertexMap.erase(it_enfVertexEntry);
699
700     TEntryList& enfVertexEntryList = _faceEntryEnfVertexEntryListMap[theFaceEntry];
701     enfVertexEntryList.erase(theVertexEntry);
702     if (enfVertexEntryList.size() == 0)
703       _faceEntryEnfVertexEntryListMap.erase(theFaceEntry);
704     //    TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry);
705     //    TEntryList::iterator it_entryList = it_entry_entry->second.find(theVertexEntry);
706     //    it_entry_entry->second.erase(it_entryList);
707     //    if (it_entry_entry->second.size() == 0)
708     //      _faceEntryEnfVertexEntryListMap.erase(it_entry_entry);
709   } else {
710     // Fail
711     MESSAGE("Enforced vertex with geom entry " << theVertexEntry << " not found");
712     msg << "No enforced vertex with geom entry " << theVertexEntry;
713     // check that enf vertex with given coords exists
714     TCoordsEnfVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
715     if (it_coords_enf != _coordsEnfVertexMap.end()) {
716       // Success
717       MESSAGE("Found enforced vertex with coords " << x << ", " << y << ", " << z);
718       oldEnfVertex = it_coords_enf->second;
719
720       _coordsEnfVertexMap.erase(it_coords_enf);
721
722       TEnfVertexCoordsList& enfVertexCoordsList = _faceEntryCoordsListMap[theFaceEntry];
723       enfVertexCoordsList.erase(coords);
724       if (enfVertexCoordsList.size() == 0)
725         _faceEntryCoordsListMap.erase(theFaceEntry);
726       //      TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry);
727       //      TEnfVertexCoordsList::iterator it_coordsList = it_entry_coords->second.find(coords);
728       //      it_entry_coords->second.erase(it_coordsList);
729       //      if (it_entry_coords->second.size() == 0)
730       //        _faceEntryCoordsListMap.erase(it_entry_coords);
731     } else {
732       // Fail
733       MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found");
734       msg << std::endl;
735       msg << "No enforced vertex at " << x << ", " << y << ", " << z;
736       throw std::invalid_argument(msg.str());
737     }
738   }
739
740   MESSAGE("Remove enf vertex from _enfVertexList");
741
742   // update _enfVertexList
743   TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
744   if (it != _enfVertexList.end()) {
745     (*it)->faceEntries.erase(theFaceEntry);
746     if ((*it)->faceEntries.size() == 0){
747       _enfVertexList.erase(it);
748       toNotify = true;
749     }
750     MESSAGE("Done");
751   }
752
753   // update _faceEntryEnfVertexListMap
754   TEnfVertexList& currentEnfVertexList = _faceEntryEnfVertexListMap[theFaceEntry];
755   currentEnfVertexList.erase(oldEnfVertex);
756
757   if (currentEnfVertexList.size() == 0) {
758     MESSAGE("Remove _faceEntryEnfVertexListMap[" << theFaceEntry <<"]");
759     _faceEntryEnfVertexListMap.erase(theFaceEntry);
760     MESSAGE("Done");
761   }
762
763   if (toNotify)
764     NotifySubMeshesHypothesisModification();
765
766   return toNotify;
767 }
768
769 //=======================================================================
770 //function : ClearEnforcedVertices
771 //=======================================================================
772
773 bool BLSURFPlugin_Hypothesis::ClearEnforcedVertices(const TEntry& theFaceEntry) throw (std::invalid_argument) {
774
775   bool toNotify = false;
776   TEnfVertex *oldEnfVertex;
777
778   TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry);
779   if (it_entry_coords != _faceEntryCoordsListMap.end()) {
780     toNotify = true;
781     TEnfVertexCoordsList coordsList = it_entry_coords->second;
782     TEnfVertexCoordsList::iterator it_coordsList = coordsList.begin();
783     for (; it_coordsList != coordsList.end(); ++it_coordsList) {
784       TEnfVertexCoords coords = (*it_coordsList);
785       oldEnfVertex = _coordsEnfVertexMap[coords];
786       _coordsEnfVertexMap.erase(coords);
787       // update _enfVertexList
788       TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
789       if (it != _enfVertexList.end()) {
790         (*it)->faceEntries.erase(theFaceEntry);
791         if ((*it)->faceEntries.size() == 0){
792           _enfVertexList.erase(it);
793           toNotify = true;
794         }
795         MESSAGE("Done");
796       }
797     }
798     _faceEntryCoordsListMap.erase(it_entry_coords);
799     _faceEntryEnfVertexListMap.erase(theFaceEntry);
800   }
801
802   TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry);
803   if (it_entry_entry != _faceEntryEnfVertexEntryListMap.end()) {
804     toNotify = true;
805     TEntryList enfVertexEntryList = it_entry_entry->second;
806     TEntryList::iterator it_enfVertexEntryList = enfVertexEntryList.begin();
807     for (; it_enfVertexEntryList != enfVertexEntryList.end(); ++it_enfVertexEntryList) {
808       TEntry enfVertexEntry = (*it_enfVertexEntryList);
809       oldEnfVertex = _enfVertexEntryEnfVertexMap[enfVertexEntry];
810       _enfVertexEntryEnfVertexMap.erase(enfVertexEntry);
811       // update _enfVertexList
812       TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
813       if (it != _enfVertexList.end()) {
814         (*it)->faceEntries.erase(theFaceEntry);
815         if ((*it)->faceEntries.size() == 0){
816           _enfVertexList.erase(it);
817           toNotify = true;
818         }
819         MESSAGE("Done");
820       }
821     }
822     _faceEntryEnfVertexEntryListMap.erase(it_entry_entry);
823     _faceEntryEnfVertexListMap.erase(theFaceEntry);
824   }
825
826   if (toNotify)
827     NotifySubMeshesHypothesisModification();
828
829   return toNotify;
830   //  std::ostringstream msg;
831   //  msg << "No enforced vertex for " << theFaceEntry;
832   //  throw std::invalid_argument(msg.str());
833 }
834
835 //=======================================================================
836 //function : ClearAllEnforcedVertices
837 //=======================================================================
838 void BLSURFPlugin_Hypothesis::ClearAllEnforcedVertices() {
839   _faceEntryEnfVertexListMap.clear();
840   _enfVertexList.clear();
841   _faceEntryCoordsListMap.clear();
842   _coordsEnfVertexMap.clear();
843   _faceEntryEnfVertexEntryListMap.clear();
844   _enfVertexEntryEnfVertexMap.clear();
845   NotifySubMeshesHypothesisModification();
846 }
847
848 //================================================================================
849 /*!
850  * \brief Return the enforced vertices
851  */
852 //================================================================================
853
854
855 BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByFace(
856     const BLSURFPlugin_Hypothesis* hyp) {
857   return hyp ? hyp->_GetAllEnforcedVerticesByFace() : GetDefaultFaceEntryEnfVertexListMap();
858 }
859
860 BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetAllEnforcedVertices(
861     const BLSURFPlugin_Hypothesis* hyp) {
862   return hyp ? hyp->_GetAllEnforcedVertices() : GetDefaultEnfVertexList();
863 }
864
865 BLSURFPlugin_Hypothesis::TFaceEntryCoordsListMap BLSURFPlugin_Hypothesis::GetAllCoordsByFace(
866     const BLSURFPlugin_Hypothesis* hyp) {
867   return hyp ? hyp->_GetAllCoordsByFace() : GetDefaultFaceEntryCoordsListMap();
868 }
869
870 BLSURFPlugin_Hypothesis::TCoordsEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByCoords(
871     const BLSURFPlugin_Hypothesis* hyp) {
872   return hyp ? hyp->_GetAllEnforcedVerticesByCoords() : GetDefaultCoordsEnfVertexMap();
873 }
874
875 BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexEntryListMap BLSURFPlugin_Hypothesis::GetAllEnfVertexEntriesByFace(
876     const BLSURFPlugin_Hypothesis* hyp) {
877   return hyp ? hyp->_GetAllEnfVertexEntriesByFace() : GetDefaultFaceEntryEnfVertexEntryListMap();
878 }
879
880 BLSURFPlugin_Hypothesis::TEnfVertexEntryEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByEnfVertexEntry(
881     const BLSURFPlugin_Hypothesis* hyp) {
882   return hyp ? hyp->_GetAllEnforcedVerticesByEnfVertexEntry() : GetDefaultEnfVertexEntryEnfVertexMap();
883 }
884
885 std::set<int> BLSURFPlugin_Hypothesis::GetEnfVertexNodeIDs(TEnfGroupName theGroupName) throw (std::invalid_argument)
886 {
887   TGroupNameNodeIDMap::const_iterator it = _groupNameNodeIDMap.find(theGroupName);
888   if (it != _groupNameNodeIDMap.end()) {
889     return it->second;
890   }
891   std::ostringstream msg;
892   msg << "No group " << theGroupName;
893   throw std::invalid_argument(msg.str());
894 }
895
896 void BLSURFPlugin_Hypothesis::AddEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID)
897 {
898   _groupNameNodeIDMap[theGroupName].insert(theNodeID);
899 }
900
901 void BLSURFPlugin_Hypothesis::RemoveEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID) throw (std::invalid_argument)
902 {
903   TGroupNameNodeIDMap::iterator it = _groupNameNodeIDMap.find(theGroupName);
904   if (it != _groupNameNodeIDMap.end()) {
905     std::set<int>::iterator IDit = it->second.find(theNodeID);
906     if (IDit != it->second.end())
907       it->second.erase(IDit);
908     std::ostringstream msg;
909     msg << "No node IDs " << theNodeID << " for group " << theGroupName;
910     throw std::invalid_argument(msg.str());
911   }
912   std::ostringstream msg;
913   msg << "No group " << theGroupName;
914   throw std::invalid_argument(msg.str());
915 }
916
917 //=============================================================================
918 std::ostream & BLSURFPlugin_Hypothesis::SaveTo(std::ostream & save) {
919   save << " " << (int) _topology << " " << (int) _physicalMesh << " " << (int) _geometricMesh << " " << _phySize << " "
920       << _angleMeshS << " " << _gradation << " " << (int) _quadAllowed << " " << (int) _decimesh;
921   save << " " << _phyMin << " " << _phyMax << " " << _angleMeshC << " " << _hgeoMin << " " << _hgeoMax << " " << _verb;
922
923   TOptionValues::iterator op_val = _option2value.begin();
924   if (op_val != _option2value.end()) {
925     save << " " << "__OPTIONS_BEGIN__";
926     for (; op_val != _option2value.end(); ++op_val) {
927       if (!op_val->second.empty())
928         save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end
929     }
930     save << " " << "__OPTIONS_END__";
931   }
932
933   TSizeMap::iterator it_sm = _sizeMap.begin();
934   if (it_sm != _sizeMap.end()) {
935     save << " " << "__SIZEMAP_BEGIN__";
936     for (; it_sm != _sizeMap.end(); ++it_sm) {
937       save << " " << it_sm->first << " " << it_sm->second << "%#"; // "%#" is a mark of value end
938     }
939     save << " " << "__SIZEMAP_END__";
940   }
941
942   TSizeMap::iterator it_at = _attractors.begin();
943   if (it_at != _attractors.end()) {
944     save << " " << "__ATTRACTORS_BEGIN__";
945     for (; it_at != _attractors.end(); ++it_at) {
946       save << " " << it_at->first << " " << it_at->second << "%#"; // "%#" is a mark of value end
947     }
948     save << " " << "__ATTRACTORS_END__";
949   }
950   
951   TAttractorMap::iterator it_At = _classAttractors.begin();
952   if (it_At != _classAttractors.end()) {
953     std::ostringstream test;
954     save << " " << "__NEW_ATTRACTORS_BEGIN__";
955     test << " " << "__NEW_ATTRACTORS_BEGIN__";
956     for (; it_At != _classAttractors.end(); ++it_At) {
957       std::vector<double> attParams;
958       attParams   = it_At->second->GetParameters();
959 //       double step = it_At->second->GetStep();
960       save << " " << it_At->first;
961       save << " " << it_At->second->GetAttractorEntry();
962       save << " " << attParams[0]  << " " <<  attParams[1] << " " <<  attParams[2] << " " <<  attParams[3];
963 //       save << " " << step;
964       test << " " << it_At->first;
965       test << " " << it_At->second->GetAttractorEntry();
966       test << " " << attParams[0]  << " " <<  attParams[1] << " " <<  attParams[2] << " " <<  attParams[3];
967 //       test << " " << step;
968     }
969     save << " " << "__NEW_ATTRACTORS_END__";
970     test << " " << "__NEW_ATTRACTORS_END__";
971     MESSAGE(" Attractor hypothesis saved as "<<test.str())
972   }
973
974   TEnfVertexList::const_iterator it_enf = _enfVertexList.begin();
975   if (it_enf != _enfVertexList.end()) {
976     save << " " << "__ENFORCED_VERTICES_BEGIN__";
977     for (; it_enf != _enfVertexList.end(); ++it_enf) {
978       TEnfVertex *enfVertex = (*it_enf);
979       save << " " << "__BEGIN_VERTEX__";
980       if (!enfVertex->name.empty()) {
981         save << " " << "__BEGIN_NAME__";
982         save << " " << enfVertex->name;
983         save << " " << "__END_NAME__";
984       }
985       if (!enfVertex->geomEntry.empty()) {
986         save << " " << "__BEGIN_ENTRY__";
987         save << " " << enfVertex->geomEntry;
988         save << " " << "__END_ENTRY__";
989       }
990       if (!enfVertex->grpName.empty()) {
991         save << " " << "__BEGIN_GROUP__";
992         save << " " << enfVertex->grpName;
993         save << " " << "__END_GROUP__";
994       }
995       if (enfVertex->coords.size()) {
996         save << " " << "__BEGIN_COORDS__";
997         for (int i=0;i<enfVertex->coords.size();i++)
998           save << " " << enfVertex->coords[i];
999         save << " " << "__END_COORDS__";
1000       }
1001       TEntryList::const_iterator faceEntriesIt = enfVertex->faceEntries.begin();
1002       bool hasFaces = false;
1003       if (faceEntriesIt != enfVertex->faceEntries.end()) {
1004         hasFaces = true;
1005         save << " " << "__BEGIN_FACELIST__";
1006       }
1007       for (; faceEntriesIt != enfVertex->faceEntries.end(); ++faceEntriesIt)
1008         save << " " << (*faceEntriesIt);
1009       if (hasFaces)
1010         save << " " << "__END_FACELIST__";
1011       save << " " << "__END_VERTEX__";
1012     }
1013     save << " " << "__ENFORCED_VERTICES_END__";
1014   }
1015
1016   return save;
1017 }
1018
1019 //=============================================================================
1020 std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load) {
1021   bool isOK = true;
1022   int i;
1023   double val;
1024
1025   isOK = (load >> i);
1026   if (isOK)
1027     _topology = (Topology) i;
1028   else
1029     load.clear(std::ios::badbit | load.rdstate());
1030
1031   isOK = (load >> i);
1032   if (isOK)
1033     _physicalMesh = (PhysicalMesh) i;
1034   else
1035     load.clear(std::ios::badbit | load.rdstate());
1036
1037   isOK = (load >> i);
1038   if (isOK)
1039     _geometricMesh = (GeometricMesh) i;
1040   else
1041     load.clear(std::ios::badbit | load.rdstate());
1042
1043   isOK = (load >> val);
1044   if (isOK)
1045     _phySize = val;
1046   else
1047     load.clear(std::ios::badbit | load.rdstate());
1048
1049   isOK = (load >> val);
1050   if (isOK)
1051     _angleMeshS = val;
1052   else
1053     load.clear(std::ios::badbit | load.rdstate());
1054
1055   isOK = (load >> val);
1056   if (isOK)
1057     _gradation = val;
1058   else
1059     load.clear(std::ios::badbit | load.rdstate());
1060
1061   isOK = (load >> i);
1062   if (isOK)
1063     _quadAllowed = (bool) i;
1064   else
1065     load.clear(std::ios::badbit | load.rdstate());
1066
1067   isOK = (load >> i);
1068   if (isOK)
1069     _decimesh = (bool) i;
1070   else
1071     load.clear(std::ios::badbit | load.rdstate());
1072
1073   isOK = (load >> val);
1074   if (isOK)
1075     _phyMin = val;
1076   else
1077     load.clear(std::ios::badbit | load.rdstate());
1078
1079   isOK = (load >> val);
1080   if (isOK)
1081     _phyMax = val;
1082   else
1083     load.clear(std::ios::badbit | load.rdstate());
1084
1085   isOK = (load >> val);
1086   if (isOK)
1087     _angleMeshC = val;
1088   else
1089     load.clear(std::ios::badbit | load.rdstate());
1090
1091   isOK = (load >> val);
1092   if (isOK)
1093     _hgeoMin = val;
1094   else
1095     load.clear(std::ios::badbit | load.rdstate());
1096
1097   isOK = (load >> val);
1098   if (isOK)
1099     _hgeoMax = val;
1100   else
1101     load.clear(std::ios::badbit | load.rdstate());
1102
1103   isOK = (load >> i);
1104   if (isOK)
1105     _verb = i;
1106   else
1107     load.clear(std::ios::badbit | load.rdstate());
1108
1109   std::string option_or_sm;
1110   bool hasOptions = false;
1111   bool hasSizeMap = false;
1112   bool hasAttractor = false;
1113   bool hasNewAttractor = false;
1114   bool hasEnforcedVertex = false;
1115
1116   isOK = (load >> option_or_sm);
1117   if (isOK)
1118     if (option_or_sm == "__OPTIONS_BEGIN__")
1119       hasOptions = true;
1120     else if (option_or_sm == "__SIZEMAP_BEGIN__")
1121       hasSizeMap = true;
1122     else if (option_or_sm == "__ATTRACTORS_BEGIN__")
1123       hasAttractor = true;
1124     else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
1125       hasNewAttractor = true;
1126     else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1127       hasEnforcedVertex = true;
1128
1129   std::string optName, optValue;
1130   while (isOK && hasOptions) {
1131     isOK = (load >> optName);
1132     if (isOK) {
1133       if (optName == "__OPTIONS_END__")
1134         break;
1135       isOK = (load >> optValue);
1136     }
1137     if (isOK) {
1138       std::string & value = _option2value[optName];
1139       value = optValue;
1140       int len = value.size();
1141       // continue reading until "%#" encountered
1142       while (value[len - 1] != '#' || value[len - 2] != '%') {
1143         isOK = (load >> optValue);
1144         if (isOK) {
1145           value += " ";
1146           value += optValue;
1147           len = value.size();
1148         } else {
1149           break;
1150         }
1151       }
1152       value[len - 2] = '\0'; //cut off "%#"
1153     }
1154   }
1155
1156   if (hasOptions) {
1157     isOK = (load >> option_or_sm);
1158     if (isOK)
1159       if (option_or_sm == "__SIZEMAP_BEGIN__")
1160         hasSizeMap = true;
1161       else if (option_or_sm == "__ATTRACTORS_BEGIN__")
1162         hasAttractor = true;
1163       else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
1164         hasNewAttractor = true;
1165       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1166         hasEnforcedVertex = true;
1167   }
1168
1169   std::string smEntry, smValue;
1170   while (isOK && hasSizeMap) {
1171     isOK = (load >> smEntry);
1172     if (isOK) {
1173       if (smEntry == "__SIZEMAP_END__")
1174         break;
1175       isOK = (load >> smValue);
1176     }
1177     if (isOK) {
1178       std::string & value2 = _sizeMap[smEntry];
1179       value2 = smValue;
1180       int len2 = value2.size();
1181       // continue reading until "%#" encountered
1182       while (value2[len2 - 1] != '#' || value2[len2 - 2] != '%') {
1183         isOK = (load >> smValue);
1184         if (isOK) {
1185           value2 += " ";
1186           value2 += smValue;
1187           len2 = value2.size();
1188         } else {
1189           break;
1190         }
1191       }
1192       value2[len2 - 2] = '\0'; //cut off "%#"
1193     }
1194   }
1195
1196   if (hasSizeMap) {
1197     isOK = (load >> option_or_sm);
1198     if (isOK)
1199       if (option_or_sm == "__ATTRACTORS_BEGIN__")
1200         hasAttractor = true;
1201       if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
1202         hasNewAttractor = true;
1203       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1204         hasEnforcedVertex = true;
1205   }
1206
1207   std::string atEntry, atValue;
1208   while (isOK && hasAttractor) {
1209     isOK = (load >> atEntry);
1210     if (isOK) {
1211       if (atEntry == "__ATTRACTORS_END__")
1212         break;
1213       isOK = (load >> atValue);
1214     }
1215     if (isOK) {
1216       std::string & value3 = _attractors[atEntry];
1217       value3 = atValue;
1218       int len3 = value3.size();
1219       // continue reading until "%#" encountered
1220       while (value3[len3 - 1] != '#' || value3[len3 - 2] != '%') {
1221         isOK = (load >> atValue);
1222         if (isOK) {
1223           value3 += " ";
1224           value3 += atValue;
1225           len3 = value3.size();
1226         } else {
1227           break;
1228         }
1229       }
1230       value3[len3 - 2] = '\0'; //cut off "%#"
1231     }
1232   }
1233
1234   if (hasAttractor) {
1235     isOK = (load >> option_or_sm);
1236     if (isOK)
1237       if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__")
1238         hasNewAttractor = true;
1239       else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1240         hasEnforcedVertex = true;
1241   }
1242
1243   std::string newAtFaceEntry, atTestString;
1244   std::string newAtShapeEntry;
1245   double attParams[4];
1246   double step;
1247   while (isOK && hasNewAttractor) {
1248     std::cout<<"Load new attractor"<<std::endl;
1249     isOK = (load >> newAtFaceEntry);
1250     if (isOK) {
1251       if (newAtFaceEntry == "__NEW_ATTRACTORS_END__")
1252         break;
1253       isOK = (load >> newAtShapeEntry);
1254       if (!isOK)
1255     break;
1256       isOK = (load >> attParams[0]>>attParams[1]>>attParams[2]>>attParams[3]); //>>step);
1257     }
1258     if (isOK) {
1259       MESSAGE(" LOADING ATTRACTOR HYPOTHESIS ")
1260       const TopoDS_Shape attractorShape = BLSURFPlugin_Hypothesis::entryToShape(newAtShapeEntry);
1261       const TopoDS_Face faceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(newAtFaceEntry));
1262       BLSURFPlugin_Attractor* attractor = new BLSURFPlugin_Attractor(faceShape, attractorShape, newAtShapeEntry);//, step);
1263       attractor->SetParameters(attParams[0], attParams[1], attParams[2], attParams[3]);
1264       attractor->BuildMap();                     
1265       _classAttractors[newAtFaceEntry]=attractor;
1266     }
1267   }
1268   
1269   
1270   if (hasNewAttractor) {
1271     isOK = (load >> option_or_sm);
1272     if (isOK)
1273       if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__")
1274         hasEnforcedVertex = true;
1275   }
1276
1277
1278 // 
1279 // Here is a example of the saved stream:
1280 // __ENFORCED_VERTICES_BEGIN__ 
1281 // __BEGIN_VERTEX__  => no name, no entry
1282 // __BEGIN_GROUP__ mon groupe __END_GROUP__
1283 // __BEGIN_COORDS__ 10 10 10 __END_COORDS__ 
1284 // __BEGIN_FACELIST__ 0:1:1:1:1 __END_FACELIST__ 
1285 // __END_VERTEX__ 
1286 // __BEGIN_VERTEX__ => no coords
1287 // __BEGIN_NAME__ mes points __END_NAME__ 
1288 // __BEGIN_ENTRY__ 0:1:1:4 __END_ENTRY__
1289 // __BEGIN_GROUP__ mon groupe __END_GROUP__
1290 // __BEGIN_FACELIST__ 0:1:1:1:3 __END_FACELIST__
1291 // __END_VERTEX__ 
1292 // __ENFORCED_VERTICES_END__
1293 // 
1294
1295   std::string enfSeparator;
1296   std::string enfName;
1297   std::string enfGeomEntry;
1298   std::string enfGroup;
1299   TEntryList enfFaceEntryList;
1300   double enfCoords[3];
1301   bool hasCoords = false;
1302   
1303   _faceEntryEnfVertexListMap.clear();
1304   _enfVertexList.clear();
1305   _faceEntryCoordsListMap.clear();
1306   _coordsEnfVertexMap.clear();
1307   _faceEntryEnfVertexEntryListMap.clear();
1308   _enfVertexEntryEnfVertexMap.clear();
1309   
1310   
1311   while (isOK && hasEnforcedVertex) {
1312     isOK = (load >> enfSeparator); // __BEGIN_VERTEX__
1313     TEnfVertex *enfVertex = new TEnfVertex();
1314 //     MESSAGE("enfSeparator: " <<enfSeparator);
1315     if (enfSeparator == "__ENFORCED_VERTICES_END__")
1316       break; // __ENFORCED_VERTICES_END__
1317     if (enfSeparator != "__BEGIN_VERTEX__")
1318       throw std::exception();
1319     
1320     while (isOK) {
1321       isOK = (load >> enfSeparator);
1322       MESSAGE("enfSeparator: " <<enfSeparator);
1323       if (enfSeparator == "__END_VERTEX__") {
1324         
1325         enfVertex->name = enfName;
1326         enfVertex->geomEntry = enfGeomEntry;
1327         enfVertex->grpName = enfGroup;
1328         enfVertex->coords.clear();
1329         if (hasCoords)
1330           enfVertex->coords.assign(enfCoords,enfCoords+3);
1331         enfVertex->faceEntries = enfFaceEntryList;
1332         
1333         _enfVertexList.insert(enfVertex);
1334         
1335         if (enfVertex->coords.size()) {
1336           _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
1337           for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) {
1338             _faceEntryCoordsListMap[(*it)].insert(enfVertex->coords);
1339             _faceEntryEnfVertexListMap[(*it)].insert(enfVertex);
1340           }
1341         }
1342         if (!enfVertex->geomEntry.empty()) {
1343           _enfVertexEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
1344           for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) {
1345             _faceEntryEnfVertexEntryListMap[(*it)].insert(enfVertex->geomEntry);
1346             _faceEntryEnfVertexListMap[(*it)].insert(enfVertex);
1347           }
1348         }
1349         
1350         enfName.clear();
1351         enfGeomEntry.clear();
1352         enfGroup.clear();
1353         enfFaceEntryList.clear();
1354         hasCoords = false;
1355         break; // __END_VERTEX__
1356       }
1357         
1358       if (enfSeparator == "__BEGIN_NAME__") {  // __BEGIN_NAME__
1359         while (isOK && (enfSeparator != "__END_NAME__")) {
1360           isOK = (load >> enfSeparator);
1361           if (enfSeparator != "__END_NAME__") {
1362             if (!enfName.empty())
1363               enfName += " ";
1364             enfName += enfSeparator;
1365           }
1366         }
1367         MESSAGE("enfName: " <<enfName);
1368       }
1369         
1370       if (enfSeparator == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
1371         isOK = (load >> enfGeomEntry);
1372         isOK = (load >> enfSeparator); // __END_ENTRY__
1373         if (enfSeparator != "__END_ENTRY__")
1374           throw std::exception();
1375         MESSAGE("enfGeomEntry: " <<enfGeomEntry);
1376       }
1377         
1378       if (enfSeparator == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
1379         while (isOK && (enfSeparator != "__END_GROUP__")) {
1380           isOK = (load >> enfSeparator);
1381           if (enfSeparator != "__END_GROUP__") {
1382             if (!enfGroup.empty())
1383               enfGroup += " ";
1384             enfGroup += enfSeparator;
1385           }
1386         }
1387         MESSAGE("enfGroup: " <<enfGroup);
1388       }
1389         
1390       if (enfSeparator == "__BEGIN_COORDS__") {  // __BEGIN_COORDS__
1391         hasCoords = true;
1392         isOK = (load >> enfCoords[0] >> enfCoords[1] >> enfCoords[2]);
1393         isOK = (load >> enfSeparator); // __END_COORDS__
1394         if (enfSeparator != "__END_COORDS__")
1395           throw std::exception();
1396         MESSAGE("enfCoords: " << enfCoords[0] <<","<< enfCoords[1] <<","<< enfCoords[2]);
1397       } 
1398         
1399       if (enfSeparator == "__BEGIN_FACELIST__") {  // __BEGIN_FACELIST__
1400         while (isOK && (enfSeparator != "__END_FACELIST__")) {
1401           isOK = (load >> enfSeparator);
1402           if (enfSeparator != "__END_FACELIST__") {
1403             enfFaceEntryList.insert(enfSeparator);
1404             MESSAGE(enfSeparator << " was inserted into enfFaceEntryList");
1405           }
1406         }
1407       } 
1408     }
1409   }
1410
1411   return load;
1412 }
1413
1414 //=============================================================================
1415 std::ostream & operator <<(std::ostream & save, BLSURFPlugin_Hypothesis & hyp) {
1416   return hyp.SaveTo(save);
1417 }
1418
1419 //=============================================================================
1420 std::istream & operator >>(std::istream & load, BLSURFPlugin_Hypothesis & hyp) {
1421   return hyp.LoadFrom(load);
1422 }
1423
1424 //================================================================================
1425 /*!
1426  * \brief Does nothing
1427  */
1428 //================================================================================
1429
1430 bool BLSURFPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape) {
1431   return false;
1432 }
1433
1434 //=============================================================================
1435 /*!
1436  * \brief Initialize my parameter values by default parameters.
1437  *  \retval bool - true if parameter values have been successfully defined
1438  */
1439 //=============================================================================
1440
1441 bool BLSURFPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh) {
1442   return bool(_phySize = dflts._elemLength);
1443 }
1444
1445 //=============================================================================
1446 BLSURFPlugin_Hypothesis::Topology BLSURFPlugin_Hypothesis::GetDefaultTopology() {
1447   return FromCAD;
1448 }
1449
1450 //=============================================================================
1451 BLSURFPlugin_Hypothesis::PhysicalMesh BLSURFPlugin_Hypothesis::GetDefaultPhysicalMesh() {
1452   return PhysicalUserDefined;
1453 }
1454
1455 //=============================================================================
1456 double BLSURFPlugin_Hypothesis::GetDefaultPhySize() {
1457   return 10;
1458 }
1459
1460 //======================================================================
1461 double BLSURFPlugin_Hypothesis::GetDefaultMaxSize() {
1462   return undefinedDouble(); // 1e+4;
1463 }
1464
1465 //======================================================================
1466 double BLSURFPlugin_Hypothesis::GetDefaultMinSize() {
1467   return undefinedDouble(); //1e-4;
1468 }
1469
1470 //======================================================================
1471 BLSURFPlugin_Hypothesis::GeometricMesh BLSURFPlugin_Hypothesis::GetDefaultGeometricMesh() {
1472   return DefaultGeom;
1473 }
1474
1475 //=============================================================================
1476 double BLSURFPlugin_Hypothesis::GetDefaultAngleMeshS() {
1477   return 8;
1478 }
1479
1480 //=============================================================================
1481 double BLSURFPlugin_Hypothesis::GetDefaultGradation() {
1482   return 1.1;
1483 }
1484
1485 //=============================================================================
1486 bool BLSURFPlugin_Hypothesis::GetDefaultQuadAllowed() {
1487   return false;
1488 }
1489
1490 //=============================================================================
1491 bool BLSURFPlugin_Hypothesis::GetDefaultDecimesh() {
1492   return false;
1493 }