Salome HOME
abb5b6aacef9645611fac42ee8c775083dc665b0
[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,
44                                                   SMESH_Gen * gen)
45
46   : SMESH_Hypothesis(hypId, gen),
47     _maxSize            (GetDefaultMaxSize()),
48     _minSize            (0),
49     _growthRate         (GetDefaultGrowthRate()),
50     _nbSegPerEdge       (GetDefaultNbSegPerEdge()),
51     _nbSegPerRadius     (GetDefaultNbSegPerRadius()),
52     _fineness           (GetDefaultFineness()),
53     _chordalErrorEnabled(GetDefaultChordalError() > 0),
54     _chordalError       (GetDefaultChordalError() ),
55     _secondOrder        (GetDefaultSecondOrder()),
56     _optimize           (GetDefaultOptimize()),
57     _localSize          (GetDefaultLocalSize()),
58     _quadAllowed        (GetDefaultQuadAllowed()),
59     _surfaceCurvature   (GetDefaultSurfaceCurvature()),
60     _fuseEdges          (GetDefaultFuseEdges())
61 {
62   _name = "NETGEN_Parameters";
63   _param_algo_dim = 3;
64   _localSize.clear();
65 }
66
67 //=============================================================================
68 /*!
69  *  
70  */
71 //=============================================================================
72 void NETGENPlugin_Hypothesis::SetMaxSize(double theSize)
73 {
74   if (theSize != _maxSize)
75   {
76     _maxSize = theSize;
77     NotifySubMeshesHypothesisModification();
78   }
79 }
80
81 //=============================================================================
82 /*!
83  *  
84  */
85 //=============================================================================
86 void NETGENPlugin_Hypothesis::SetMinSize(double theSize)
87 {
88   if (theSize != _minSize)
89   {
90     _minSize = theSize;
91     NotifySubMeshesHypothesisModification();
92   }
93 }
94
95 //=============================================================================
96 /*!
97  *  
98  */
99 //=============================================================================
100 void NETGENPlugin_Hypothesis::SetSecondOrder(bool theVal)
101 {
102   if (theVal != _secondOrder)
103   {
104     _secondOrder = theVal;
105     NotifySubMeshesHypothesisModification();
106   }
107 }
108
109 //=============================================================================
110 /*!
111  *  
112  */
113 //=============================================================================
114 void NETGENPlugin_Hypothesis::SetOptimize(bool theVal)
115 {
116   if (theVal != _optimize)
117   {
118     _optimize = theVal;
119     NotifySubMeshesHypothesisModification();
120   }
121 }
122
123 //=============================================================================
124 /*!
125  *  
126  */
127 //=============================================================================
128 void NETGENPlugin_Hypothesis::SetFineness(Fineness theFineness)
129 {
130   if (theFineness != _fineness)
131   {
132     _fineness = theFineness;
133     // the predefined values are taken from NETGEN 4.5 sources
134     switch (_fineness)
135     {
136     case VeryCoarse:
137       _growthRate = 0.7;
138       _nbSegPerEdge = 0.3;
139       _nbSegPerRadius = 1;
140       break;
141     case Coarse:
142       _growthRate = 0.5;
143       _nbSegPerEdge = 0.5;
144       _nbSegPerRadius = 1.5;
145       break;
146     case Fine:
147       _growthRate = 0.2;
148       _nbSegPerEdge = 2;
149       _nbSegPerRadius = 3;
150       break;
151     case VeryFine:
152       _growthRate = 0.1;
153       _nbSegPerEdge = 3;
154       _nbSegPerRadius = 5;
155       break;
156     case UserDefined:
157       break;
158     case Moderate:
159     default:
160       _growthRate = 0.3;
161       _nbSegPerEdge = 1;
162       _nbSegPerRadius = 2;
163       break;
164     }
165     NotifySubMeshesHypothesisModification();
166   }
167 }
168
169 //=============================================================================
170 /*!
171  *  
172  */
173 //=============================================================================
174 void NETGENPlugin_Hypothesis::SetGrowthRate(double theRate)
175 {
176   if (theRate != _growthRate)
177   {
178     _growthRate = theRate;
179     _fineness = UserDefined;
180     NotifySubMeshesHypothesisModification();
181   }
182 }
183
184 //=============================================================================
185 /*!
186  *  
187  */
188 //=============================================================================
189 void NETGENPlugin_Hypothesis::SetNbSegPerEdge(double theVal)
190 {
191   if (theVal != _nbSegPerEdge)
192   {
193     _nbSegPerEdge = theVal;
194     _fineness = UserDefined;
195     NotifySubMeshesHypothesisModification();
196   }
197 }
198
199 //=============================================================================
200 /*!
201  *  
202  */
203 //=============================================================================
204 void NETGENPlugin_Hypothesis::SetNbSegPerRadius(double theVal)
205 {
206   if (theVal != _nbSegPerRadius)
207   {
208     _nbSegPerRadius = theVal;
209     _fineness = UserDefined;
210     NotifySubMeshesHypothesisModification();
211   }
212 }
213
214 //=============================================================================
215 /*!
216  *  
217  */
218 //=============================================================================
219 void NETGENPlugin_Hypothesis::SetChordalErrorEnabled(bool theVal)
220 {
221   if (theVal != _chordalErrorEnabled)
222   {
223     _chordalErrorEnabled = theVal;
224     NotifySubMeshesHypothesisModification();
225   }
226 }
227
228 //=============================================================================
229 /*!
230  *  
231  */
232 //=============================================================================
233 void NETGENPlugin_Hypothesis::SetChordalError(double theVal)
234 {
235   if (theVal != _chordalError)
236   {
237     _chordalError = theVal;
238     NotifySubMeshesHypothesisModification();
239   }
240 }
241
242 //=============================================================================
243 /*!
244  *  
245  */
246 //=============================================================================
247 void NETGENPlugin_Hypothesis::SetLocalSizeOnEntry(const std::string& entry, double localSize)
248 {
249   if(_localSize[entry] != localSize)
250   {
251     _localSize[entry] = localSize;
252     NotifySubMeshesHypothesisModification();
253   }
254 }
255
256 //=============================================================================
257 /*!
258  *
259  */
260 //=============================================================================
261 double NETGENPlugin_Hypothesis::GetLocalSizeOnEntry(const std::string& entry)
262 {
263   TLocalSize::iterator it  = _localSize.find( entry );
264   if ( it != _localSize.end() )
265     return it->second;
266   else
267     return -1.0;
268 }
269
270 //=============================================================================
271 /*!
272  *  
273  */
274 //=============================================================================
275 void NETGENPlugin_Hypothesis::UnsetLocalSizeOnEntry(const std::string& entry)
276 {
277   _localSize.erase(entry);
278   NotifySubMeshesHypothesisModification();
279 }
280
281 //=============================================================================
282 /*!
283  *  
284  */
285 //=============================================================================
286 void NETGENPlugin_Hypothesis::SetMeshSizeFile(const std::string& fileName)
287 {
288   if ( fileName != _meshSizeFile )
289   {
290     _meshSizeFile = fileName;
291     NotifySubMeshesHypothesisModification();
292   }
293 }
294
295 //=============================================================================
296 /*!
297  *  
298  */
299 //=============================================================================
300 void NETGENPlugin_Hypothesis::SetQuadAllowed(bool theVal)
301 {
302   if (theVal != _quadAllowed)
303   {
304     _quadAllowed = theVal;
305     NotifySubMeshesHypothesisModification();
306   }
307 }
308
309 //=============================================================================
310 /*!
311  *  
312  */
313 //=============================================================================
314 bool NETGENPlugin_Hypothesis::GetDefaultQuadAllowed()
315 {
316   return false;
317 }
318
319 //=============================================================================
320 /*!
321  *  
322  */
323 //=============================================================================
324 void NETGENPlugin_Hypothesis::SetSurfaceCurvature(bool theVal)
325 {
326   if (theVal != _surfaceCurvature)
327   {
328     _surfaceCurvature = theVal;
329     NotifySubMeshesHypothesisModification();
330   }
331 }
332
333 //=============================================================================
334 /*!
335  *
336  */
337 //=============================================================================
338 bool NETGENPlugin_Hypothesis::GetDefaultSurfaceCurvature()
339 {
340   return true;
341 }
342
343 //=============================================================================
344 /*!
345  *
346  */
347 //=============================================================================
348 void NETGENPlugin_Hypothesis::SetFuseEdges(bool theVal)
349 {
350   if (theVal != _fuseEdges)
351   {
352     _fuseEdges = theVal;
353     NotifySubMeshesHypothesisModification();
354   }
355 }
356
357 //=============================================================================
358 /*!
359  *
360  */
361 //=============================================================================
362 bool NETGENPlugin_Hypothesis::GetDefaultFuseEdges()
363 {
364   return true; // false; -- for SALOME_TESTS/Grids/smesh/3D_mesh_NETGEN_05/F6
365 }
366
367 //=============================================================================
368 /*!
369  *
370  */
371 //=============================================================================
372 ostream & NETGENPlugin_Hypothesis::SaveTo(ostream & save)
373 {
374   save << _maxSize << " " << _fineness;
375
376   if (_fineness == UserDefined)
377     save << " " << _growthRate << " " << _nbSegPerEdge << " " << _nbSegPerRadius;
378
379   save << " " << (int)_secondOrder << " " << (int)_optimize;
380
381   TLocalSize::iterator it_sm  = _localSize.begin();
382   if (it_sm != _localSize.end()) {
383     save << " " << "__LOCALSIZE_BEGIN__";
384     for ( ; it_sm != _localSize.end(); ++it_sm ) {
385       save << " " << it_sm->first
386            << " " << it_sm->second << "%#"; // "%#" is a mark of value end
387     }
388     save << " " << "__LOCALSIZE_END__";
389   }
390   save << " " << _minSize;
391   save << " " << _quadAllowed;
392   save << " " << _surfaceCurvature;
393   save << " " << _fuseEdges;
394
395   save << " " << _meshSizeFile.size() << " " << _meshSizeFile;
396
397   save << " " << ( _chordalErrorEnabled ? _chordalError : 0. );
398
399   return save;
400 }
401
402 //=============================================================================
403 /*!
404  *  
405  */
406 //=============================================================================
407 istream & NETGENPlugin_Hypothesis::LoadFrom(istream & load)
408 {
409   bool isOK = true;
410   int is;
411   double val;
412
413   isOK = static_cast<bool>(load >> val);
414   if (isOK)
415     _maxSize = val;
416   else
417     load.clear(ios::badbit | load.rdstate());
418
419   isOK = static_cast<bool>(load >> is);
420   if (isOK)
421     SetFineness((Fineness) is);
422   else
423     load.clear(ios::badbit | load.rdstate());
424
425   if (_fineness == UserDefined)
426   {
427     isOK = static_cast<bool>(load >> val);
428     if (isOK)
429       _growthRate = val;
430     else
431       load.clear(ios::badbit | load.rdstate());
432
433     isOK = static_cast<bool>(load >> val);
434     if (isOK)
435       _nbSegPerEdge = val;
436     else
437       load.clear(ios::badbit | load.rdstate());
438
439     isOK = static_cast<bool>(load >> val);
440     if (isOK)
441       _nbSegPerRadius = val;
442     else
443       load.clear(ios::badbit | load.rdstate());
444   }
445
446   isOK = static_cast<bool>(load >> is);
447   if (isOK)
448     _secondOrder = (bool) is;
449   else
450     load.clear(ios::badbit | load.rdstate());
451
452   isOK = static_cast<bool>(load >> is);
453   if (isOK)
454     _optimize = (bool) is;
455   else
456     load.clear(ios::badbit | load.rdstate());
457
458   std::string option_or_sm;
459   bool hasLocalSize = false;
460
461   isOK = static_cast<bool>(load >> option_or_sm);
462   if (isOK)
463     if (option_or_sm == "__LOCALSIZE_BEGIN__")
464       hasLocalSize = true;
465
466   std::string smEntry, smValue;
467   while (isOK && hasLocalSize) {
468     isOK = static_cast<bool>(load >> smEntry);
469     if (isOK) {
470       if (smEntry == "__LOCALSIZE_END__")
471         break;
472       isOK = static_cast<bool>(load >> smValue);
473     }
474     if (isOK) {
475       std::istringstream tmp(smValue);
476       double val;
477       tmp >> val;
478       _localSize[ smEntry ] = val;
479     }
480   }
481
482   if ( !hasLocalSize && !option_or_sm.empty() )
483     _minSize = atof( option_or_sm.c_str() );
484   else
485     load >> _minSize;
486
487   isOK = static_cast<bool>( load >> is );
488   if ( isOK )
489     _quadAllowed = (bool) is;
490   else
491     _quadAllowed = GetDefaultQuadAllowed();
492
493   isOK = static_cast<bool>( load >> is );
494   if ( isOK )
495     _surfaceCurvature = (bool) is;
496   else
497     _surfaceCurvature = GetDefaultSurfaceCurvature();
498
499   isOK = static_cast<bool>( load >> is );
500   if ( isOK )
501     _fuseEdges = (bool) is;
502   else
503     _fuseEdges = GetDefaultFuseEdges();
504
505   isOK = static_cast<bool>( load >> is >> std::ws ); // size of meshSizeFile
506   if ( isOK && is > 0 )
507   {
508     _meshSizeFile.resize( is );
509     load.get( &_meshSizeFile[0], is+1 );
510   }
511
512   isOK = static_cast<bool>(load >> val);
513   if (isOK)
514     _chordalError = val;
515   else
516     load.clear(ios::badbit | load.rdstate());
517   _chordalErrorEnabled = ( _chordalError > 0 );
518
519   return load;
520 }
521
522 //=============================================================================
523 /*!
524  *
525  */
526 //=============================================================================
527 ostream & operator <<(ostream & save, NETGENPlugin_Hypothesis & hyp)
528 {
529   return hyp.SaveTo( save );
530 }
531
532 //=============================================================================
533 /*!
534  *
535  */
536 //=============================================================================
537 istream & operator >>(istream & load, NETGENPlugin_Hypothesis & hyp)
538 {
539   return hyp.LoadFrom( load );
540 }
541
542
543 //================================================================================
544 /*!
545  * \brief Does nothing
546  * \param theMesh - the built mesh
547  * \param theShape - the geometry of interest
548  * \retval bool - always false
549  */
550 //================================================================================
551 bool NETGENPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh*   theMesh,
552                                                   const TopoDS_Shape& theShape)
553 {
554   return false;
555 }
556
557 //================================================================================
558 /*!
559  * \brief Initialize my parameter values by default parameters.
560  *  \retval bool - true if parameter values have been successfully defined
561  */
562 //================================================================================
563
564 bool NETGENPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  dflts,
565                                                       const SMESH_Mesh* theMesh)
566 {
567   _nbSegPerEdge = dflts._nbSegments;
568   _maxSize      = dflts._elemLength;
569
570   if ( dflts._shape && !dflts._shape->IsNull() )
571     _minSize    = NETGENPlugin_Mesher::GetDefaultMinSize( *dflts._shape, _maxSize );
572   else if ( theMesh && theMesh->HasShapeToMesh() )
573     _minSize    = NETGENPlugin_Mesher::GetDefaultMinSize( theMesh->GetShapeToMesh(), _maxSize );
574
575   return _nbSegPerEdge && _maxSize > 0;
576 }
577
578 //=============================================================================
579 /*!
580  *  
581  */
582 //=============================================================================
583 double NETGENPlugin_Hypothesis::GetDefaultMaxSize()
584 {
585   return 1000;
586 }
587
588 //=============================================================================
589 /*!
590  *  
591  */
592 //=============================================================================
593 NETGENPlugin_Hypothesis::Fineness NETGENPlugin_Hypothesis::GetDefaultFineness()
594 {
595   return Moderate;
596 }
597
598 //=============================================================================
599 /*!
600  *  
601  */
602 //=============================================================================
603 double NETGENPlugin_Hypothesis::GetDefaultGrowthRate()
604 {
605   return 0.3;
606 }
607
608 //=============================================================================
609 /*!
610  *  
611  */
612 //=============================================================================
613 double NETGENPlugin_Hypothesis::GetDefaultNbSegPerEdge()
614 {
615   return 1;
616 }
617
618 //=============================================================================
619 /*!
620  *  
621  */
622 //=============================================================================
623 double NETGENPlugin_Hypothesis::GetDefaultNbSegPerRadius()
624 {
625   return 2;
626 }
627 //=============================================================================
628 /*!
629  *  
630  */
631 //=============================================================================
632 double NETGENPlugin_Hypothesis::GetDefaultChordalError()
633 {
634   return -1; // disabled by default
635 }
636
637 //=============================================================================
638 /*!
639  *  
640  */
641 //=============================================================================
642 bool NETGENPlugin_Hypothesis::GetDefaultSecondOrder()
643 {
644   return false;
645 }
646
647 //=============================================================================
648 /*!
649  *  
650  */
651 //=============================================================================
652 bool NETGENPlugin_Hypothesis::GetDefaultOptimize()
653 {
654   return true;
655 }