Salome HOME
PAL19680: Meshers: BLSURF, GHS3D and holed shapes
[plugins/ghs3dplugin.git] / src / GHS3DPlugin_Hypothesis.cxx
1 // Copyright (C) 2005  CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA 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 // File      : GHS3DPlugin_Hypothesis.cxx
21 // Created   : Wed Apr  2 12:36:29 2008
22 // Author    : Edward AGAPOV (eap)
23 //=============================================================================
24
25
26 #include "GHS3DPlugin_Hypothesis.hxx"
27
28 #include <TCollection_AsciiString.hxx>
29
30 //=======================================================================
31 //function : GHS3DPlugin_Hypothesis
32 //=======================================================================
33
34 GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen)
35   : SMESH_Hypothesis(hypId, studyId, gen)
36 {
37   _name = "GHS3D_Parameters";
38   _param_algo_dim = 3;
39
40   myToMeshHoles                  = DefaultMeshHoles();        
41   myMaximumMemory                = -1;//DefaultMaximumMemory();    
42   myInitialMemory                = -1;//DefaultInitialMemory();    
43   myOptimizationLevel            = DefaultOptimizationLevel();
44   myWorkingDirectory             = DefaultWorkingDirectory(); 
45   myKeepFiles                    = DefaultKeepFiles();
46   myVerboseLevel                 = DefaultVerboseLevel();
47   myToCreateNewNodes             = DefaultToCreateNewNodes();
48   myToUseBoundaryRecoveryVersion = DefaultToUseBoundaryRecoveryVersion();
49 }
50
51 //=======================================================================
52 //function : SetToMeshHoles
53 //=======================================================================
54
55 void GHS3DPlugin_Hypothesis::SetToMeshHoles(bool toMesh)
56 {
57   if ( myToMeshHoles != toMesh ) {
58     myToMeshHoles = toMesh;
59     NotifySubMeshesHypothesisModification();
60   }
61 }
62
63 //=======================================================================
64 //function : GetToMeshHoles
65 //=======================================================================
66
67 bool GHS3DPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const
68 {
69   if (checkFreeOption && !myTextOption.empty()) {
70     if ( myTextOption.find("-c 0"))
71       return true;
72     if ( myTextOption.find("-c 1"))
73       return false;
74   }
75   return myToMeshHoles;
76 }
77
78 //=======================================================================
79 //function : SetMaximumMemory
80 //=======================================================================
81
82 void GHS3DPlugin_Hypothesis::SetMaximumMemory(short MB)
83 {
84   if ( myMaximumMemory != MB ) {
85     myMaximumMemory = MB;
86     NotifySubMeshesHypothesisModification();
87   }
88 }
89
90 //=======================================================================
91 //function : GetMaximumMemory
92 //           * automatic memory adjustment mode. Default is zero
93 //=======================================================================
94
95 short GHS3DPlugin_Hypothesis::GetMaximumMemory() const
96 {
97   return myMaximumMemory;
98 }
99
100 //=======================================================================
101 //function : SetInitialMemory
102 //=======================================================================
103
104 void GHS3DPlugin_Hypothesis::SetInitialMemory(short MB)
105 {
106   if ( myInitialMemory != MB ) {
107     myInitialMemory = MB;
108     NotifySubMeshesHypothesisModification();
109   }
110 }
111
112 //=======================================================================
113 //function : GetInitialMemory
114 //=======================================================================
115
116 short GHS3DPlugin_Hypothesis::GetInitialMemory() const
117 {
118   return myInitialMemory;
119 }
120
121 //=======================================================================
122 //function : SetOptimizationLevel
123 //=======================================================================
124
125 void GHS3DPlugin_Hypothesis::SetOptimizationLevel(OptimizationLevel level)
126 {
127   if ( myOptimizationLevel != level ) {
128     myOptimizationLevel = level;
129     NotifySubMeshesHypothesisModification();
130   }
131 }
132
133 //=======================================================================
134 //function : GetOptimizationLevel
135 //=======================================================================
136
137 GHS3DPlugin_Hypothesis::OptimizationLevel GHS3DPlugin_Hypothesis::GetOptimizationLevel() const
138 {
139   return (OptimizationLevel) myOptimizationLevel;
140 }
141
142 //=======================================================================
143 //function : SetWorkingDirectory
144 //=======================================================================
145
146 void GHS3DPlugin_Hypothesis::SetWorkingDirectory(const string& path)
147 {
148   if ( myWorkingDirectory != path ) {
149     myWorkingDirectory = path;
150     NotifySubMeshesHypothesisModification();
151   }
152 }
153
154 //=======================================================================
155 //function : GetWorkingDirectory
156 //=======================================================================
157
158 string GHS3DPlugin_Hypothesis::GetWorkingDirectory() const
159 {
160   return myWorkingDirectory;
161 }
162
163 //=======================================================================
164 //function : SetKeepFiles
165 //=======================================================================
166
167 void GHS3DPlugin_Hypothesis::SetKeepFiles(bool toKeep)
168 {
169   if ( myKeepFiles != toKeep ) {
170     myKeepFiles = toKeep;
171     NotifySubMeshesHypothesisModification();
172   }
173 }
174
175 //=======================================================================
176 //function : GetKeepFiles
177 //=======================================================================
178
179 bool GHS3DPlugin_Hypothesis::GetKeepFiles() const
180 {
181   return myKeepFiles;
182 }
183
184 //=======================================================================
185 //function : SetVerboseLevel
186 //=======================================================================
187
188 void GHS3DPlugin_Hypothesis::SetVerboseLevel(short level)
189 {
190   if ( myVerboseLevel != level ) {
191     myVerboseLevel = level;
192     NotifySubMeshesHypothesisModification();
193   }
194 }
195
196 //=======================================================================
197 //function : GetVerboseLevel
198 //=======================================================================
199
200 short GHS3DPlugin_Hypothesis::GetVerboseLevel() const
201 {
202   return myVerboseLevel;
203 }
204
205 //=======================================================================
206 //function : SetToCreateNewNodes
207 //=======================================================================
208
209 void GHS3DPlugin_Hypothesis::SetToCreateNewNodes(bool toCreate)
210 {
211   if ( myToCreateNewNodes != toCreate ) {
212     myToCreateNewNodes = toCreate;
213     NotifySubMeshesHypothesisModification();
214   }
215 }
216
217 //=======================================================================
218 //function : GetToCreateNewNodes
219 //=======================================================================
220
221 bool GHS3DPlugin_Hypothesis::GetToCreateNewNodes() const
222 {
223   return myToCreateNewNodes;
224 }
225
226 //=======================================================================
227 //function : SetToUseBoundaryRecoveryVersion
228 //=======================================================================
229
230 void GHS3DPlugin_Hypothesis::SetToUseBoundaryRecoveryVersion(bool toUse)
231 {
232   if ( myToUseBoundaryRecoveryVersion != toUse ) {
233     myToUseBoundaryRecoveryVersion = toUse;
234     NotifySubMeshesHypothesisModification();
235   }
236 }
237
238 //=======================================================================
239 //function : GetToUseBoundaryRecoveryVersion
240 //=======================================================================
241
242 bool GHS3DPlugin_Hypothesis::GetToUseBoundaryRecoveryVersion() const
243 {
244   return myToUseBoundaryRecoveryVersion;
245 }
246
247 //=======================================================================
248 //function : SetTextOption
249 //=======================================================================
250
251 void GHS3DPlugin_Hypothesis::SetTextOption(const string& option)
252 {
253   if ( myTextOption != option ) {
254     myTextOption = option;
255     NotifySubMeshesHypothesisModification();
256   }
257 }
258
259 //=======================================================================
260 //function : GetTextOption
261 //=======================================================================
262
263 string GHS3DPlugin_Hypothesis::GetTextOption() const
264 {
265   return myTextOption;
266 }
267
268
269 //=======================================================================
270 //function : DefaultMeshHoles
271 //=======================================================================
272
273 bool GHS3DPlugin_Hypothesis::DefaultMeshHoles()
274 {
275   return false; // PAL19680
276 }
277
278 //=======================================================================
279 //function : DefaultMaximumMemory
280 //=======================================================================
281
282 #ifndef WIN32
283 #include <sys/sysinfo.h>
284 #endif
285
286 short  GHS3DPlugin_Hypothesis::DefaultMaximumMemory()
287 {
288 #ifndef WIN32
289   struct sysinfo si;
290   int err = sysinfo( &si );
291   if ( err == 0 ) {
292     int ramMB = si.totalram * si.mem_unit / 1024 / 1024;
293     return (short) ( 0.7 * ramMB );
294   }
295 #endif
296   return -1;
297 }
298
299 //=======================================================================
300 //function : DefaultInitialMemory
301 //=======================================================================
302
303 short  GHS3DPlugin_Hypothesis::DefaultInitialMemory()
304 {
305   return DefaultMaximumMemory();
306 }
307
308 //=======================================================================
309 //function : DefaultOptimizationLevel
310 //=======================================================================
311
312 short  GHS3DPlugin_Hypothesis::DefaultOptimizationLevel()
313 {
314   return Medium;
315 }
316
317 //=======================================================================
318 //function : DefaultWorkingDirectory
319 //=======================================================================
320
321 string GHS3DPlugin_Hypothesis::DefaultWorkingDirectory()
322 {
323   TCollection_AsciiString aTmpDir;
324
325   char *Tmp_dir = getenv("SALOME_TMP_DIR");
326   if(Tmp_dir != NULL) {
327     aTmpDir = Tmp_dir;
328   }
329   else {
330 #ifdef WIN32
331     aTmpDir = TCollection_AsciiString("C:\\");
332 #else
333     aTmpDir = TCollection_AsciiString("/tmp/");
334 #endif
335   }
336   return aTmpDir.ToCString();
337 }
338
339 //=======================================================================
340 //function : DefaultKeepFiles
341 //=======================================================================
342
343 bool   GHS3DPlugin_Hypothesis::DefaultKeepFiles()
344 {
345   return false;
346 }
347
348 //=======================================================================
349 //function : DefaultVerboseLevel
350 //=======================================================================
351
352 short  GHS3DPlugin_Hypothesis::DefaultVerboseLevel()
353 {
354   return 10;
355 }
356
357 //=======================================================================
358 //function : DefaultToCreateNewNodes
359 //=======================================================================
360
361 bool GHS3DPlugin_Hypothesis::DefaultToCreateNewNodes()
362 {
363   return true;
364 }
365
366 //=======================================================================
367 //function : DefaultToUseBoundaryRecoveryVersion
368 //=======================================================================
369
370 bool GHS3DPlugin_Hypothesis::DefaultToUseBoundaryRecoveryVersion()
371 {
372   return false;
373 }
374
375 //=======================================================================
376 //function : SaveTo
377 //=======================================================================
378
379 ostream & GHS3DPlugin_Hypothesis::SaveTo(ostream & save)
380 {
381   save << (int) myToMeshHoles                 << " ";
382   save << myMaximumMemory                     << " ";
383   save << myInitialMemory                     << " ";
384   save << myOptimizationLevel                 << " ";
385   save << myWorkingDirectory                  << " ";
386   save << (int)myKeepFiles                    << " ";
387   save << myVerboseLevel                      << " ";
388   save << (int)myToCreateNewNodes             << " ";
389   save << (int)myToUseBoundaryRecoveryVersion << " ";
390   save << myTextOption                        << " ";
391   return save;
392 }
393
394 //=======================================================================
395 //function : LoadFrom
396 //=======================================================================
397
398 istream & GHS3DPlugin_Hypothesis::LoadFrom(istream & load)
399 {
400   bool isOK = true;
401   int i;
402
403   isOK = (load >> i);
404   if (isOK)
405     myToMeshHoles = i;
406   else
407     load.clear(ios::badbit | load.rdstate());
408
409   isOK = (load >> i);
410   if (isOK)
411     myMaximumMemory = i;
412   else
413     load.clear(ios::badbit | load.rdstate());
414
415   isOK = (load >> i);
416   if (isOK)
417     myInitialMemory = i;
418   else
419     load.clear(ios::badbit | load.rdstate());
420
421   isOK = (load >> i);
422   if (isOK)
423     myOptimizationLevel = i;
424   else
425     load.clear(ios::badbit | load.rdstate());
426
427   isOK = (load >> myWorkingDirectory);
428   if (isOK) {
429     if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty
430       myKeepFiles = false;
431       myWorkingDirectory.clear();
432     }
433     else if ( myWorkingDirectory == "1" ) {
434       myKeepFiles = true;
435       myWorkingDirectory.clear();
436     }
437   }
438   else
439     load.clear(ios::badbit | load.rdstate());
440
441   if ( !myWorkingDirectory.empty() ) {
442     isOK = (load >> i);
443     if (isOK)
444       myKeepFiles = i;
445     else
446       load.clear(ios::badbit | load.rdstate());
447   }
448
449   isOK = (load >> i);
450   if (isOK)
451     myVerboseLevel = (short) i;
452   else
453     load.clear(ios::badbit | load.rdstate());
454
455   isOK = (load >> i);
456   if (isOK)
457     myToCreateNewNodes = (bool) i;
458   else
459     load.clear(ios::badbit | load.rdstate());
460
461   isOK = (load >> i);
462   if (isOK)
463     myToUseBoundaryRecoveryVersion = (bool) i;
464   else
465     load.clear(ios::badbit | load.rdstate());
466
467   isOK = (load >> myTextOption);
468   while (isOK) {
469     string txt;
470     if (load >> txt) {
471       myTextOption += " ";
472       myTextOption += txt;
473     }
474     else
475       isOK = false;
476   }
477 //   else
478 //     load.clear(ios::badbit | load.rdstate());
479
480   return load;
481 }
482
483 //=======================================================================
484 //function : SetParametersByMesh
485 //=======================================================================
486
487 bool GHS3DPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoDS_Shape&)
488 {
489   return false;
490 }
491
492 //================================================================================
493 /*!
494  * \brief Return command to run ghs3d mesher excluding file prefix (-f)
495  */
496 //================================================================================
497
498 string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp,
499                                             const bool                    hasShapeToMesh)
500 {
501 #ifndef WIN32
502   TCollection_AsciiString cmd( "ghs3d" );
503 #else
504   TCollection_AsciiString cmd( "ghs3d.exe" );
505 #endif
506   // check if any option is overridden by hyp->myTextOption
507   bool m = hyp ? ( hyp->myTextOption.find("-m") == string::npos ) : true;
508   bool M = hyp ? ( hyp->myTextOption.find("-M") == string::npos ) : true;
509   bool c = hyp ? ( hyp->myTextOption.find("-c") == string::npos ) : true;
510   bool o = hyp ? ( hyp->myTextOption.find("-o") == string::npos ) : true;
511   bool p0= hyp ? ( hyp->myTextOption.find("-p0")== string::npos ) : true;
512   bool C = hyp ? ( hyp->myTextOption.find("-C") == string::npos ) : true;
513   bool v = hyp ? ( hyp->myTextOption.find("-v") == string::npos ) : true;
514
515   // if use boundary recovery version, few options are allowed
516   bool useBndRecovery = !C;
517   if ( !useBndRecovery && hyp )
518     useBndRecovery = hyp->myToUseBoundaryRecoveryVersion;
519
520   // ghs3d needs to know amount of memory it may use (MB).
521   // Default memory is defined at ghs3d installation but it may be not enough,
522   // so allow to use about all available memory
523   if ( m ) {
524     short aMaximumMemory = hyp ? hyp->myMaximumMemory : -1;
525     cmd += " -m ";
526     if ( aMaximumMemory < 0 )
527       cmd += DefaultMaximumMemory();
528     else
529       cmd += aMaximumMemory;
530   }
531   if ( M && !useBndRecovery ) {
532     short aInitialMemory = hyp ? hyp->myInitialMemory : -1;
533     cmd += " -M ";
534     if ( aInitialMemory > 0 )
535       cmd += aInitialMemory;
536     else
537       cmd += "100";
538   }
539   // component to mesh
540   // 0 , all components to be meshed
541   // 1 , only the main ( outermost ) component to be meshed
542   if ( c && !useBndRecovery ) {
543     // We always run GHS3D with "to mesh holes'==TRUE (see PAL19680)
544     if ( hasShapeToMesh )
545       cmd += " -c 0";
546     else {
547       bool aToMeshHoles = hyp ? hyp->myToMeshHoles : DefaultMeshHoles();
548       if ( aToMeshHoles )
549         cmd += " -c 0";
550       else
551         cmd += " -c 1";
552     }
553   }
554
555   // optimization level
556   if ( o && hyp && !useBndRecovery ) {
557     if ( hyp->myOptimizationLevel >= 0 && hyp->myOptimizationLevel < 4 ) {
558       char* level[] = { "none" , "light" , "standard" , "strong" };
559       cmd += " -o ";
560       cmd += level[ hyp->myOptimizationLevel ];
561     }
562   }
563
564   // to create internal nodes
565   if ( p0 && hyp && !hyp->myToCreateNewNodes ) {
566     cmd += " -p0";
567   }
568
569   // verbose mode
570   if ( v && hyp ) {
571     cmd += " -v ";
572     cmd += hyp->myVerboseLevel;
573   }
574
575   // boundary recovery version
576   if ( useBndRecovery ) {
577     cmd += " -C";
578   }
579
580   // options as text
581   if ( hyp && !hyp->myTextOption.empty() ) {
582     cmd += " ";
583     cmd += (char*) hyp->myTextOption.c_str();
584   }
585
586   return cmd.ToCString();
587 }
588
589 //================================================================================
590 /*!
591  * \brief Return a unique file name
592  */
593 //================================================================================
594
595 string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hyp)
596 {
597   string aTmpDir = hyp ? hyp->GetWorkingDirectory() : DefaultWorkingDirectory();
598   const char lastChar = *aTmpDir.rbegin();
599 #ifdef WIN32
600     if(lastChar != '\\') aTmpDir+='\\';
601 #else
602     if(lastChar != '/') aTmpDir+='/';
603 #endif      
604
605   TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str();
606   aGenericName += "GHS3D_";
607 #ifdef WIN32
608   aGenericName += GetCurrentProcessId();
609 #else
610   aGenericName += getpid();
611 #endif
612   aGenericName += "_";
613   aGenericName += Abs((Standard_Integer)(long) & aGenericName);
614
615   return aGenericName.ToCString();
616 }