Salome HOME
Add possibility to define Local Size via a file
[plugins/netgenplugin.git] / src / NETGENPlugin / NETGENPlugin_Hypothesis.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  NETGENPlugin : C++ implementation
24 // File      : NETGENPlugin_Hypothesis.cxx
25 // Author    : Michael Sazonov (OCN)
26 // Date      : 28/03/2006
27 // Project   : SALOME
28 //
29 #include "NETGENPlugin_Hypothesis.hxx"
30
31 #include "NETGENPlugin_Mesher.hxx"
32 #include "SMESH_Mesh.hxx"
33
34 #include <utilities.h>
35
36 using namespace std;
37
38 //=============================================================================
39 /*!
40  *  
41  */
42 //=============================================================================
43 NETGENPlugin_Hypothesis::NETGENPlugin_Hypothesis (int hypId, int studyId,
44                                                   SMESH_Gen * gen)
45   : SMESH_Hypothesis(hypId, studyId, gen),
46     _maxSize         (GetDefaultMaxSize()),
47     _minSize         (0),
48     _growthRate      (GetDefaultGrowthRate()),
49     _nbSegPerEdge    (GetDefaultNbSegPerEdge()),
50     _nbSegPerRadius  (GetDefaultNbSegPerRadius()),
51     _fineness        (GetDefaultFineness()),
52     _secondOrder     (GetDefaultSecondOrder()),
53     _optimize        (GetDefaultOptimize()),
54     _localSize       (GetDefaultLocalSize()),
55     _quadAllowed     (GetDefaultQuadAllowed()),
56     _surfaceCurvature(GetDefaultSurfaceCurvature()),
57     _fuseEdges       (GetDefaultFuseEdges())
58 {
59   _name = "NETGEN_Parameters";
60   _param_algo_dim = 3;
61   _localSize.clear();
62 }
63
64 //=============================================================================
65 /*!
66  *  
67  */
68 //=============================================================================
69 void NETGENPlugin_Hypothesis::SetMaxSize(double theSize)
70 {
71   if (theSize != _maxSize)
72   {
73     _maxSize = theSize;
74     NotifySubMeshesHypothesisModification();
75   }
76 }
77
78 //=============================================================================
79 /*!
80  *  
81  */
82 //=============================================================================
83 void NETGENPlugin_Hypothesis::SetMinSize(double theSize)
84 {
85   if (theSize != _minSize)
86   {
87     _minSize = theSize;
88     NotifySubMeshesHypothesisModification();
89   }
90 }
91
92 //=============================================================================
93 /*!
94  *  
95  */
96 //=============================================================================
97 void NETGENPlugin_Hypothesis::SetSecondOrder(bool theVal)
98 {
99   if (theVal != _secondOrder)
100   {
101     _secondOrder = theVal;
102     NotifySubMeshesHypothesisModification();
103   }
104 }
105
106 //=============================================================================
107 /*!
108  *  
109  */
110 //=============================================================================
111 void NETGENPlugin_Hypothesis::SetOptimize(bool theVal)
112 {
113   if (theVal != _optimize)
114   {
115     _optimize = theVal;
116     NotifySubMeshesHypothesisModification();
117   }
118 }
119
120 //=============================================================================
121 /*!
122  *  
123  */
124 //=============================================================================
125 void NETGENPlugin_Hypothesis::SetFineness(Fineness theFineness)
126 {
127   if (theFineness != _fineness)
128   {
129     _fineness = theFineness;
130     // the predefined values are taken from NETGEN 4.5 sources
131     switch (_fineness)
132     {
133     case VeryCoarse:
134       _growthRate = 0.7;
135       _nbSegPerEdge = 0.3;
136       _nbSegPerRadius = 1;
137       break;
138     case Coarse:
139       _growthRate = 0.5;
140       _nbSegPerEdge = 0.5;
141       _nbSegPerRadius = 1.5;
142       break;
143     case Fine:
144       _growthRate = 0.2;
145       _nbSegPerEdge = 2;
146       _nbSegPerRadius = 3;
147       break;
148     case VeryFine:
149       _growthRate = 0.1;
150       _nbSegPerEdge = 3;
151       _nbSegPerRadius = 5;
152       break;
153     case UserDefined:
154       break;
155     case Moderate:
156     default:
157       _growthRate = 0.3;
158       _nbSegPerEdge = 1;
159       _nbSegPerRadius = 2;
160       break;
161     }
162     NotifySubMeshesHypothesisModification();
163   }
164 }
165
166 //=============================================================================
167 /*!
168  *  
169  */
170 //=============================================================================
171 void NETGENPlugin_Hypothesis::SetGrowthRate(double theRate)
172 {
173   if (theRate != _growthRate)
174   {
175     _growthRate = theRate;
176     _fineness = UserDefined;
177     NotifySubMeshesHypothesisModification();
178   }
179 }
180
181 //=============================================================================
182 /*!
183  *  
184  */
185 //=============================================================================
186 void NETGENPlugin_Hypothesis::SetNbSegPerEdge(double theVal)
187 {
188   if (theVal != _nbSegPerEdge)
189   {
190     _nbSegPerEdge = theVal;
191     _fineness = UserDefined;
192     NotifySubMeshesHypothesisModification();
193   }
194 }
195
196 //=============================================================================
197 /*!
198  *  
199  */
200 //=============================================================================
201 void NETGENPlugin_Hypothesis::SetNbSegPerRadius(double theVal)
202 {
203   if (theVal != _nbSegPerRadius)
204   {
205     _nbSegPerRadius = theVal;
206     _fineness = UserDefined;
207     NotifySubMeshesHypothesisModification();
208   }
209 }
210
211 //=============================================================================
212 /*!
213  *  
214  */
215 //=============================================================================
216 void NETGENPlugin_Hypothesis::SetLocalSizeOnEntry(const std::string& entry, double localSize)
217 {
218   if(_localSize[entry] != localSize)
219   {
220     _localSize[entry] = localSize;
221     NotifySubMeshesHypothesisModification();
222   }
223 }
224
225 //=============================================================================
226 /*!
227  *
228  */
229 //=============================================================================
230 double NETGENPlugin_Hypothesis::GetLocalSizeOnEntry(const std::string& entry)
231 {
232   TLocalSize::iterator it  = _localSize.find( entry );
233   if ( it != _localSize.end() )
234     return it->second;
235   else
236     return -1.0;
237 }
238
239 //=============================================================================
240 /*!
241  *  
242  */
243 //=============================================================================
244 void NETGENPlugin_Hypothesis::UnsetLocalSizeOnEntry(const std::string& entry)
245 {
246   _localSize.erase(entry);
247   NotifySubMeshesHypothesisModification();
248 }
249
250 //=============================================================================
251 /*!
252  *  
253  */
254 //=============================================================================
255 void NETGENPlugin_Hypothesis::SetMeshSizeFile(const std::string& fileName)
256 {
257   if ( fileName != _meshSizeFile )
258   {
259     _meshSizeFile = fileName;
260     NotifySubMeshesHypothesisModification();
261   }
262 }
263
264 //=============================================================================
265 /*!
266  *  
267  */
268 //=============================================================================
269 void NETGENPlugin_Hypothesis::SetQuadAllowed(bool theVal)
270 {
271   if (theVal != _quadAllowed)
272   {
273     _quadAllowed = theVal;
274     NotifySubMeshesHypothesisModification();
275   }
276 }
277
278 //=============================================================================
279 /*!
280  *  
281  */
282 //=============================================================================
283 bool NETGENPlugin_Hypothesis::GetDefaultQuadAllowed()
284 {
285   return false;
286 }
287
288 //=============================================================================
289 /*!
290  *  
291  */
292 //=============================================================================
293 void NETGENPlugin_Hypothesis::SetSurfaceCurvature(bool theVal)
294 {
295   if (theVal != _surfaceCurvature)
296   {
297     _surfaceCurvature = theVal;
298     NotifySubMeshesHypothesisModification();
299   }
300 }
301
302 //=============================================================================
303 /*!
304  *
305  */
306 //=============================================================================
307 bool NETGENPlugin_Hypothesis::GetDefaultSurfaceCurvature()
308 {
309   return true;
310 }
311
312 //=============================================================================
313 /*!
314  *
315  */
316 //=============================================================================
317 void NETGENPlugin_Hypothesis::SetFuseEdges(bool theVal)
318 {
319   if (theVal != _fuseEdges)
320   {
321     _fuseEdges = theVal;
322     NotifySubMeshesHypothesisModification();
323   }
324 }
325
326 //=============================================================================
327 /*!
328  *
329  */
330 //=============================================================================
331 bool NETGENPlugin_Hypothesis::GetDefaultFuseEdges()
332 {
333   return true; // false; -- for SALOME_TESTS/Grids/smesh/3D_mesh_NETGEN_05/F6
334 }
335
336 //=============================================================================
337 /*!
338  *
339  */
340 //=============================================================================
341 ostream & NETGENPlugin_Hypothesis::SaveTo(ostream & save)
342 {
343   save << _maxSize << " " << _fineness;
344
345   if (_fineness == UserDefined)
346     save << " " << _growthRate << " " << _nbSegPerEdge << " " << _nbSegPerRadius;
347
348   save << " " << (int)_secondOrder << " " << (int)_optimize;
349
350   TLocalSize::iterator it_sm  = _localSize.begin();
351   if (it_sm != _localSize.end()) {
352     save << " " << "__LOCALSIZE_BEGIN__";
353     for ( ; it_sm != _localSize.end(); ++it_sm ) {
354         save << " " << it_sm->first
355              << " " << it_sm->second << "%#"; // "%#" is a mark of value end
356     }
357     save << " " << "__LOCALSIZE_END__";
358   }
359   save << " " << _minSize;
360   save << " " << _quadAllowed;
361   save << " " << _surfaceCurvature;
362   save << " " << _fuseEdges;
363
364   save << " " << _meshSizeFile.size() << " " << _meshSizeFile;
365
366   return save;
367 }
368
369 //=============================================================================
370 /*!
371  *  
372  */
373 //=============================================================================
374 istream & NETGENPlugin_Hypothesis::LoadFrom(istream & load)
375 {
376   bool isOK = true;
377   int is;
378   double val;
379
380   isOK = static_cast<bool>(load >> val);
381   if (isOK)
382     _maxSize = val;
383   else
384     load.clear(ios::badbit | load.rdstate());
385
386   isOK = static_cast<bool>(load >> is);
387   if (isOK)
388     SetFineness((Fineness) is);
389   else
390     load.clear(ios::badbit | load.rdstate());
391
392   if (_fineness == UserDefined)
393   {
394     isOK = static_cast<bool>(load >> val);
395     if (isOK)
396       _growthRate = val;
397     else
398       load.clear(ios::badbit | load.rdstate());
399
400     isOK = static_cast<bool>(load >> val);
401     if (isOK)
402       _nbSegPerEdge = val;
403     else
404       load.clear(ios::badbit | load.rdstate());
405
406     isOK = static_cast<bool>(load >> val);
407     if (isOK)
408       _nbSegPerRadius = val;
409     else
410       load.clear(ios::badbit | load.rdstate());
411   }
412
413   isOK = static_cast<bool>(load >> is);
414   if (isOK)
415     _secondOrder = (bool) is;
416   else
417     load.clear(ios::badbit | load.rdstate());
418
419   isOK = static_cast<bool>(load >> is);
420   if (isOK)
421     _optimize = (bool) is;
422   else
423     load.clear(ios::badbit | load.rdstate());
424
425   std::string option_or_sm;
426   bool hasLocalSize = false;
427
428   isOK = static_cast<bool>(load >> option_or_sm);
429   if (isOK)
430     if (option_or_sm == "__LOCALSIZE_BEGIN__")
431       hasLocalSize = true;
432
433   std::string smEntry, smValue;
434   while (isOK && hasLocalSize) {
435     isOK = static_cast<bool>(load >> smEntry);
436     if (isOK) {
437       if (smEntry == "__LOCALSIZE_END__")
438         break;
439       isOK = static_cast<bool>(load >> smValue);
440     }
441     if (isOK) {
442       std::istringstream tmp(smValue);
443       double val;
444       tmp >> val;
445       _localSize[ smEntry ] = val;
446     }
447   }
448
449   if ( !hasLocalSize && !option_or_sm.empty() )
450     _minSize = atof( option_or_sm.c_str() );
451   else
452     load >> _minSize;
453
454   isOK = static_cast<bool>( load >> is );
455   if ( isOK )
456     _quadAllowed = (bool) is;
457   else
458     _quadAllowed = GetDefaultQuadAllowed();
459
460   isOK = static_cast<bool>( load >> is );
461   if ( isOK )
462     _surfaceCurvature = (bool) is;
463   else
464     _surfaceCurvature = GetDefaultSurfaceCurvature();
465
466   isOK = static_cast<bool>( load >> is );
467   if ( isOK )
468     _fuseEdges = (bool) is;
469   else
470     _fuseEdges = GetDefaultFuseEdges();
471
472   isOK = static_cast<bool>( load >> is >> std::ws ); // size of meshSizeFile
473   if ( isOK && is > 0 )
474   {
475     _meshSizeFile.resize( is );
476     load.get( &_meshSizeFile[0], is+1 );
477   }
478
479   return load;
480 }
481
482 //=============================================================================
483 /*!
484  *  
485  */
486 //=============================================================================
487 ostream & operator <<(ostream & save, NETGENPlugin_Hypothesis & hyp)
488 {
489   return hyp.SaveTo( save );
490 }
491
492 //=============================================================================
493 /*!
494  *  
495  */
496 //=============================================================================
497 istream & operator >>(istream & load, NETGENPlugin_Hypothesis & hyp)
498 {
499   return hyp.LoadFrom( load );
500 }
501
502
503 //================================================================================
504 /*!
505  * \brief Does nothing
506  * \param theMesh - the built mesh
507  * \param theShape - the geometry of interest
508  * \retval bool - always false
509  */
510 //================================================================================
511 bool NETGENPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh*   theMesh,
512                                                   const TopoDS_Shape& theShape)
513 {
514   return false;
515 }
516
517 //================================================================================
518 /*!
519  * \brief Initialize my parameter values by default parameters.
520  *  \retval bool - true if parameter values have been successfully defined
521  */
522 //================================================================================
523
524 bool NETGENPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  dflts,
525                                                       const SMESH_Mesh* theMesh)
526 {
527   _nbSegPerEdge = dflts._nbSegments;
528   _maxSize      = dflts._elemLength;
529
530   if ( dflts._shape && !dflts._shape->IsNull() )
531     _minSize    = NETGENPlugin_Mesher::GetDefaultMinSize( *dflts._shape, _maxSize );
532   else if ( theMesh && theMesh->HasShapeToMesh() )
533     _minSize    = NETGENPlugin_Mesher::GetDefaultMinSize( theMesh->GetShapeToMesh(), _maxSize );
534
535   return _nbSegPerEdge && _maxSize > 0;
536 }
537
538 //=============================================================================
539 /*!
540  *  
541  */
542 //=============================================================================
543 double NETGENPlugin_Hypothesis::GetDefaultMaxSize()
544 {
545   return 1000;
546 }
547
548 //=============================================================================
549 /*!
550  *  
551  */
552 //=============================================================================
553 NETGENPlugin_Hypothesis::Fineness NETGENPlugin_Hypothesis::GetDefaultFineness()
554 {
555   return Moderate;
556 }
557
558 //=============================================================================
559 /*!
560  *  
561  */
562 //=============================================================================
563 double NETGENPlugin_Hypothesis::GetDefaultGrowthRate()
564 {
565   return 0.3;
566 }
567
568 //=============================================================================
569 /*!
570  *  
571  */
572 //=============================================================================
573 double NETGENPlugin_Hypothesis::GetDefaultNbSegPerEdge()
574 {
575   return 1;
576 }
577
578 //=============================================================================
579 /*!
580  *  
581  */
582 //=============================================================================
583 double NETGENPlugin_Hypothesis::GetDefaultNbSegPerRadius()
584 {
585   return 2;
586 }
587
588 //=============================================================================
589 /*!
590  *  
591  */
592 //=============================================================================
593 bool NETGENPlugin_Hypothesis::GetDefaultSecondOrder()
594 {
595   return false;
596 }
597
598 //=============================================================================
599 /*!
600  *  
601  */
602 //=============================================================================
603 bool NETGENPlugin_Hypothesis::GetDefaultOptimize()
604 {
605   return true;
606 }