Salome HOME
Merge changes from 'master' branch.
[plugins/netgenplugin.git] / src / GUI / NETGENPluginGUI_HypothesisCreator.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 GUI: GUI for plugged-in mesher NETGENPlugin
24 //  File   : NETGENPluginGUI_HypothesisCreator.cxx
25 //  Author : Michael Zorin
26 //  Module : NETGENPlugin
27 //
28 #include "NETGENPluginGUI_HypothesisCreator.h"
29
30 #include <SMESHGUI_Utils.h>
31 #include <SMESHGUI_HypothesesUtils.h>
32 #include <SMESHGUI_SpinBox.h>
33 #include <GeomSelectionTools.h>
34
35 #include CORBA_SERVER_HEADER(NETGENPlugin_Algorithm)
36
37 #include <SUIT_FileDlg.h>
38 #include <SUIT_ResourceMgr.h>
39 #include <SUIT_Session.h>
40
41 #include <SalomeApp_Tools.h>
42 #include <LightApp_SelectionMgr.h>
43 #include <SALOME_ListIO.hxx>
44
45 #include <QComboBox>
46 #include <QLabel>
47 #include <QGroupBox>
48 #include <QFrame>
49 #include <QLayout>
50 #include <QLineEdit>
51 #include <QCheckBox>
52 #include <QPixmap>
53 #include <QTableWidget>
54 #include <QHeaderView>
55 #include <QPushButton>
56
57 enum Fineness
58   {
59     VeryCoarse,
60     Coarse,
61     Moderate,
62     Fine,
63     VeryFine,
64     UserDefined
65   };
66
67 enum {
68   STD_TAB = 0,
69   LSZ_TAB
70 };
71
72 enum {
73   LSZ_ENTRY_COLUMN = 0,
74   LSZ_NAME_COLUMN,
75   LSZ_LOCALSIZE_COLUMN,
76   LSZ_NB_COLUMNS
77 };
78
79 enum {
80   LSZ_BTNS = 0,
81   LSZ_VERTEX_BTN,
82   LSZ_EDGE_BTN,
83   LSZ_FACE_BTN,
84   LSZ_SOLID_BTN,
85   LSZ_SEPARATOR2,
86   LSZ_REMOVE_BTN,
87   LSZ_FILE_LE = 9
88 };
89
90 NETGENPluginGUI_HypothesisCreator::NETGENPluginGUI_HypothesisCreator( const QString& theHypType )
91   : SMESHGUI_GenericHypothesisCreator( theHypType )
92 {
93   myGeomSelectionTools = NULL;
94   myLocalSizeMap.clear();
95   myIs2D   = ( theHypType.startsWith("NETGEN_Parameters_2D") ||
96                theHypType == "NETGEN_RemesherParameters_2D");
97   myIsONLY = ( theHypType == "NETGEN_Parameters_2D_ONLY" ||
98                theHypType == "NETGEN_Parameters_3D" ||
99                theHypType == "NETGEN_RemesherParameters_2D");
100 }
101
102 NETGENPluginGUI_HypothesisCreator::~NETGENPluginGUI_HypothesisCreator()
103 {
104 }
105
106 bool NETGENPluginGUI_HypothesisCreator::checkParams(QString& msg) const
107 {
108   NetgenHypothesisData data_old, data_new;
109   readParamsFromHypo( data_old );
110   readParamsFromWidgets( data_new );
111   bool res = storeParamsToHypo( data_new );
112   //storeParamsToHypo( data_old ); -- issue 0021364: Dump of netgen parameters has duplicate lines
113   
114   res = myMaxSize->isValid(msg,true) && res;
115   res = myMinSize->isValid(msg,true) && res;
116   res = myGrowthRate->isValid(msg,true) && res; ;
117   if ( myNbSegPerEdge )
118     res = myNbSegPerEdge->isValid(msg,true) && res;
119   if ( myNbSegPerRadius )
120     res = myNbSegPerRadius->isValid(msg,true) && res;
121   if ( myRidgeAngle )
122     res = myRidgeAngle->isValid(msg,true) && res;
123
124   if ( !res ) //  -- issue 0021364: Dump of netgen parameters has duplicate lines
125     storeParamsToHypo( data_old );
126
127   return res;
128 }
129
130 QFrame* NETGENPluginGUI_HypothesisCreator::buildFrame()
131 {
132   const bool isRemesher = ( hypType() == "NETGEN_RemesherParameters_2D" );
133
134   QFrame* fr = new QFrame( 0 );
135   fr->setObjectName( "myframe" );
136   QVBoxLayout* lay = new QVBoxLayout( fr );
137   lay->setMargin( 5 );
138   lay->setSpacing( 0 );
139
140   QTabWidget* tab = new QTabWidget( fr );
141   tab->setTabShape( QTabWidget::Rounded );
142   tab->setTabPosition( QTabWidget::North );
143   lay->addWidget( tab );
144   QWidget* GroupC1 = new QWidget();
145   tab->insertTab( STD_TAB, GroupC1, tr( "SMESH_ARGUMENTS" ) );
146   
147   QGridLayout* aGroupLayout = new QGridLayout( GroupC1 );
148   aGroupLayout->setSpacing( 6 );
149   aGroupLayout->setMargin( 11 );
150   
151   int row = 0;
152   myName = 0;
153   if( isCreation() )
154   {
155     aGroupLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), GroupC1 ), row, 0 );
156     myName = new QLineEdit( GroupC1 );
157     myName->setMinimumWidth(160);
158     aGroupLayout->addWidget( myName, row, 1 );
159     row++;
160   }
161
162   aGroupLayout->addWidget( new QLabel( tr( "NETGEN_MAX_SIZE" ), GroupC1 ), row, 0 );
163   myMaxSize = new SMESHGUI_SpinBox( GroupC1 );
164   myMaxSize->RangeStepAndValidator( 1e-07, 1e+06, 10., "length_precision" );
165   aGroupLayout->addWidget( myMaxSize, row, 1 );
166   row++;
167
168   aGroupLayout->addWidget( new QLabel( tr( "NETGEN_MIN_SIZE" ), GroupC1 ), row, 0 );
169   myMinSize = new SMESHGUI_SpinBox( GroupC1 );
170   myMinSize->RangeStepAndValidator( 0.0, 1e+06, 10., "length_precision" );
171   aGroupLayout->addWidget( myMinSize, row, 1 );
172   row++;
173
174   mySecondOrder = 0;
175   if ( !myIsONLY )
176   {
177     mySecondOrder = new QCheckBox( tr( "NETGEN_SECOND_ORDER" ), GroupC1 );
178     aGroupLayout->addWidget( mySecondOrder, row, 0, 1, 2 );
179     row++;
180   }
181
182   aGroupLayout->addWidget( new QLabel( tr( "NETGEN_FINENESS" ), GroupC1 ), row, 0 );
183   myFineness = new QComboBox( GroupC1 );
184   QStringList types;
185   types << tr( "NETGEN_VERYCOARSE" ) << tr( "NETGEN_COARSE" )   << tr( "NETGEN_MODERATE" ) <<
186     tr( "NETGEN_FINE" )       << tr( "NETGEN_VERYFINE" ) << tr( "NETGEN_CUSTOM" );
187   myFineness->addItems( types );
188   aGroupLayout->addWidget( myFineness, row, 1 );
189   connect( myFineness, SIGNAL( activated( int ) ), this, SLOT( onFinenessChanged() ) );
190   row++;
191
192   aGroupLayout->addWidget( new QLabel( tr( "NETGEN_GROWTH_RATE" ), GroupC1 ), row, 0 );
193   myGrowthRate = new SMESHGUI_SpinBox( GroupC1 );
194   myGrowthRate->RangeStepAndValidator( .0001, 10., .1, "parametric_precision" );
195   aGroupLayout->addWidget( myGrowthRate, row, 1 );
196   row++;
197
198   myNbSegPerEdge = 0;
199   myNbSegPerRadius = 0;
200   if ( !myIsONLY )
201   {
202     const double VALUE_MAX = 1.0e+6;
203
204     aGroupLayout->addWidget( new QLabel( tr( "NETGEN_SEG_PER_EDGE" ), GroupC1 ), row, 0 );
205     myNbSegPerEdge = new SMESHGUI_SpinBox( GroupC1 );
206     myNbSegPerEdge->RangeStepAndValidator( .2, VALUE_MAX, .1, "parametric_precision" );
207     aGroupLayout->addWidget( myNbSegPerEdge, row, 1 );
208     row++;
209
210     aGroupLayout->addWidget( new QLabel( tr( "NETGEN_SEG_PER_RADIUS" ), GroupC1 ), row, 0 );
211     myNbSegPerRadius = new SMESHGUI_SpinBox( GroupC1 );
212     myNbSegPerRadius->RangeStepAndValidator( .2, VALUE_MAX, .1, "parametric_precision" );
213     aGroupLayout->addWidget( myNbSegPerRadius, row, 1 );
214     row++;
215   }
216
217   myChordalErrorEnabled = 0;
218   myChordalError = 0;
219   if (( myIs2D && !isRemesher ) || !myIsONLY )
220   {
221     myChordalErrorEnabled = new QCheckBox( tr( "NETGEN_CHORDAL_ERROR" ), GroupC1 );
222     aGroupLayout->addWidget( myChordalErrorEnabled, row, 0 );
223     myChordalError = new SMESHGUI_SpinBox( GroupC1 );
224     myChordalError->RangeStepAndValidator( COORD_MIN, COORD_MAX, .1, "length_precision" );
225     aGroupLayout->addWidget( myChordalError, row, 1 );
226     connect( myChordalErrorEnabled, SIGNAL( stateChanged(int)), SLOT( onChordalErrorEnabled()));
227     row++;
228   }
229
230   myRidgeAngle = 0;
231   if ( isRemesher )
232   {
233     aGroupLayout->addWidget( new QLabel( tr( "NETGEN_RIDGE_ANGLE" ), GroupC1 ), row, 0 );
234     myRidgeAngle = new SMESHGUI_SpinBox( GroupC1 );
235     myRidgeAngle->RangeStepAndValidator( 0, 90, 10, "angle_precision" );
236     aGroupLayout->addWidget( myRidgeAngle, row, 1 );
237     row++;
238   }
239
240   mySurfaceCurvature = 0;
241   if (( myIs2D && !isRemesher ) || !myIsONLY )
242   {
243     mySurfaceCurvature = new QCheckBox( tr( "NETGEN_SURFACE_CURVATURE" ), GroupC1 );
244     aGroupLayout->addWidget( mySurfaceCurvature, row, 0, 1, 2 );
245     connect( mySurfaceCurvature, SIGNAL( stateChanged( int ) ), this, SLOT( onSurfaceCurvatureChanged() ) );
246     row++;
247   }
248
249   myAllowQuadrangles = 0;
250   if ( myIs2D || !myIsONLY ) // disable only for NETGEN 3D
251   {
252     myAllowQuadrangles = new QCheckBox( tr( "NETGEN_ALLOW_QUADRANGLES" ), GroupC1 );
253     aGroupLayout->addWidget( myAllowQuadrangles, row, 0, 1, 2 );
254     row++;
255   }
256
257   myOptimize = 0;
258   if ( !isRemesher )
259   {
260     myOptimize = new QCheckBox( tr( "NETGEN_OPTIMIZE" ), GroupC1 );
261     aGroupLayout->addWidget( myOptimize, row, 0, 1, 2 );
262     row++;
263   }
264
265   myFuseEdges = 0;
266   if ( !myIsONLY )
267   {
268     myFuseEdges = new QCheckBox( tr( "NETGEN_FUSE_EDGES" ), GroupC1 );
269     aGroupLayout->addWidget( myFuseEdges, row, 0, 1, 2 );
270     row++;
271   }
272
273   myLocalSizeTable = 0;
274   //if ( !myIsONLY )
275   {
276     QWidget* localSizeGroup = new QWidget();
277     QGridLayout* localSizeLayout = new QGridLayout(localSizeGroup);
278
279     myLocalSizeTable = new QTableWidget(0, LSZ_NB_COLUMNS, localSizeGroup);
280     localSizeLayout->addWidget(myLocalSizeTable, 1, 0, 8, 2);
281     QStringList localSizeHeaders;
282     localSizeHeaders << tr( "LSZ_ENTRY_COLUMN" )<< tr( "LSZ_NAME_COLUMN" ) << tr( "LSZ_LOCALSIZE_COLUMN" );
283     myLocalSizeTable->setHorizontalHeaderLabels(localSizeHeaders);
284     myLocalSizeTable->horizontalHeader()->hideSection(LSZ_ENTRY_COLUMN);
285 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
286     myLocalSizeTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
287 #else
288     myLocalSizeTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
289 #endif
290     myLocalSizeTable->resizeColumnToContents(LSZ_NAME_COLUMN);
291     myLocalSizeTable->resizeColumnToContents(LSZ_LOCALSIZE_COLUMN);
292     myLocalSizeTable->setAlternatingRowColors(true);
293     myLocalSizeTable->verticalHeader()->hide();
294
295     QPushButton* addVertexButton = new QPushButton(tr("NETGEN_LSZ_VERTEX"), localSizeGroup);
296     localSizeLayout->addWidget(addVertexButton, LSZ_VERTEX_BTN, 2, 1, 1);
297     QPushButton* addEdgeButton = new QPushButton(tr("NETGEN_LSZ_EDGE"), localSizeGroup);
298     localSizeLayout->addWidget(addEdgeButton, LSZ_EDGE_BTN, 2, 1, 1);
299     QPushButton* addFaceButton = new QPushButton(tr("NETGEN_LSZ_FACE"), localSizeGroup);
300     localSizeLayout->addWidget(addFaceButton, LSZ_FACE_BTN, 2, 1, 1);
301     QPushButton* addSolidButton = new QPushButton(tr("NETGEN_LSZ_SOLID"), localSizeGroup);
302     localSizeLayout->addWidget(addSolidButton, LSZ_SOLID_BTN, 2, 1, 1);
303
304     QFrame *line2 = new QFrame(localSizeGroup);
305     line2->setFrameShape(QFrame::HLine);
306     line2->setFrameShadow(QFrame::Sunken);
307     localSizeLayout->addWidget(line2, LSZ_SEPARATOR2, 2, 1, 1);
308
309     QPushButton* removeButton = new QPushButton(tr("NETGEN_LSZ_REMOVE"), localSizeGroup);
310     localSizeLayout->addWidget(removeButton, LSZ_REMOVE_BTN, 2, 1, 1);
311
312     QPushButton* fileBtn = new QPushButton(tr("NETGEN_LSZ_FILE"), localSizeGroup);
313     myMeshSizeFile = new QLineEdit(localSizeGroup);
314     myMeshSizeFile->setReadOnly( true );
315     localSizeLayout->addWidget( fileBtn, LSZ_FILE_LE, 0, 1, 1);
316     localSizeLayout->addWidget( myMeshSizeFile, LSZ_FILE_LE, 1, 1, 2);
317
318     connect( addVertexButton, SIGNAL(clicked()), this, SLOT(onAddLocalSizeOnVertex()));
319     connect( addEdgeButton, SIGNAL(clicked()), this, SLOT(onAddLocalSizeOnEdge()));
320     connect( addFaceButton, SIGNAL(clicked()), this, SLOT(onAddLocalSizeOnFace()));
321     connect( addSolidButton, SIGNAL(clicked()), this, SLOT(onAddLocalSizeOnSolid()));
322     connect( removeButton, SIGNAL(clicked()), this, SLOT(onRemoveLocalSizeOnShape()));
323     connect( myLocalSizeTable, SIGNAL(cellChanged(int, int)), this, SLOT(onSetLocalSize(int, int)));
324     connect( fileBtn, SIGNAL(clicked()), this, SLOT(onSetSizeFile()));
325
326     tab->insertTab(LSZ_TAB, localSizeGroup, tr("NETGEN_LOCAL_SIZE"));
327   }
328   return fr;
329 }
330
331 void NETGENPluginGUI_HypothesisCreator::retrieveParams() const
332 {
333   NetgenHypothesisData data;
334   readParamsFromHypo( data );
335
336   if( myName )
337     myName->setText( data.myName );
338   if(data.myMaxSizeVar.isEmpty())
339     myMaxSize->setValue( data.myMaxSize );
340   else
341     myMaxSize->setText( data.myMaxSizeVar );
342
343   if(data.myMinSizeVar.isEmpty())
344     myMinSize->setValue( data.myMinSize );
345   else
346     myMinSize->setText( data.myMinSizeVar );
347
348   if ( mySecondOrder )
349     mySecondOrder->setChecked( data.mySecondOrder );
350   if ( myOptimize )
351     myOptimize->setChecked( data.myOptimize );
352   myFineness->setCurrentIndex( data.myFineness );
353
354   if(data.myGrowthRateVar.isEmpty())
355     myGrowthRate->setValue( data.myGrowthRate );
356   else
357     myGrowthRate->setText( data.myGrowthRateVar );
358
359   if ( myNbSegPerEdge )
360   {
361     if(data.myNbSegPerEdgeVar.isEmpty())
362       myNbSegPerEdge->setValue( data.myNbSegPerEdge );
363     else
364       myNbSegPerEdge->setText( data.myNbSegPerEdgeVar );
365   }
366   if ( myNbSegPerRadius )
367   {
368     if(data.myNbSegPerRadiusVar.isEmpty())
369       myNbSegPerRadius->setValue( data.myNbSegPerRadius );
370     else
371       myNbSegPerRadius->setText( data.myNbSegPerRadiusVar );
372   }
373   if ( myChordalError )
374   {
375     myChordalErrorEnabled->setChecked( data.myChordalErrorEnabled && data.myChordalError > 0 );
376     if(data.myChordalErrorVar.isEmpty())
377       myChordalError->setValue( data.myChordalError > 0 ? data.myChordalError : 0.1 );
378     else
379       myChordalError->setText( data.myChordalErrorVar );
380     myChordalError->setEnabled( myChordalErrorEnabled->isChecked() );
381   }
382   if ( myRidgeAngle )
383   {
384     if ( data.myRidgeAngleVar.isEmpty() )
385       myRidgeAngle->setValue( data.myRidgeAngle );
386     else
387       myRidgeAngle->setText( data.myRidgeAngleVar );
388   }
389   if (myAllowQuadrangles)
390     myAllowQuadrangles->setChecked( data.myAllowQuadrangles );
391
392   if (mySurfaceCurvature)
393     mySurfaceCurvature->setChecked( data.mySurfaceCurvature );
394
395   if (myFuseEdges)
396     myFuseEdges->setChecked( data.myFuseEdges );
397
398   // update widgets
399   ((NETGENPluginGUI_HypothesisCreator*) this )-> onSurfaceCurvatureChanged();
400
401   if ( myLocalSizeTable )
402   {
403     NETGENPluginGUI_HypothesisCreator* that = (NETGENPluginGUI_HypothesisCreator*)this;
404     QMapIterator<QString, QString> i(myLocalSizeMap);
405     GeomSelectionTools* geomSelectionTools = that->getGeomSelectionTools();
406     while (i.hasNext()) {
407       i.next();
408       const QString entry = i.key();
409       std::string shapeName = geomSelectionTools->getNameFromEntry(entry.toStdString());
410       const QString localSize = i.value();
411       int row = myLocalSizeTable->rowCount();
412       myLocalSizeTable->setRowCount(row+1);
413       myLocalSizeTable->setItem(row, LSZ_ENTRY_COLUMN, new QTableWidgetItem(entry));
414       myLocalSizeTable->item(row, LSZ_ENTRY_COLUMN)->setFlags(0);
415       myLocalSizeTable->setItem(row, LSZ_NAME_COLUMN, new QTableWidgetItem(QString::fromStdString(shapeName)));
416       myLocalSizeTable->item(row, LSZ_NAME_COLUMN)->setFlags(0);
417       myLocalSizeTable->setItem(row, LSZ_LOCALSIZE_COLUMN, new QTableWidgetItem(localSize));
418       myLocalSizeTable->item(row, LSZ_LOCALSIZE_COLUMN)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsEnabled);
419     }
420     myLocalSizeTable->resizeColumnToContents(LSZ_NAME_COLUMN);
421     myLocalSizeTable->resizeColumnToContents(LSZ_LOCALSIZE_COLUMN);
422
423     myMeshSizeFile->setText( data.myMeshSizeFile );
424   }
425 }
426
427 QString NETGENPluginGUI_HypothesisCreator::storeParams() const
428 {
429   NetgenHypothesisData data;
430   readParamsFromWidgets( data );
431   storeParamsToHypo( data );
432
433   // QString valStr = tr("NETGEN_MAX_SIZE") + " = " + QString::number( data.myMaxSize ) + "; ";
434   // valStr += tr("NETGEN_MIN_SIZE") + " = " + QString::number( data.myMinSize ) + "; ";
435   // if ( data.mySecondOrder )
436   //   valStr +=  tr("NETGEN_SECOND_ORDER") + "; ";
437   // if ( data.myOptimize )
438   //   valStr +=  tr("NETGEN_OPTIMIZE") + "; ";
439   // valStr += myFineness->currentText() + "(" +  QString::number( data.myGrowthRate )     + ", " +
440   //   QString::number( data.myNbSegPerEdge )   + ", " +
441   //   QString::number( data.myNbSegPerRadius ) + ")";
442
443   // if ( myIs2D && data.myAllowQuadrangles )
444   //   valStr += "; " + tr("NETGEN_ALLOW_QUADRANGLES");
445
446   // if ( data.mySurfaceCurvature )
447   //   valStr += "; " + tr("NETGEN_SURFACE_CURVATURE");
448
449   // if ( data.myFuseEdges )
450   //   valStr += "; " + tr("NETGEN_FUSE_EDGES");
451
452   return QString();
453 }
454
455 bool NETGENPluginGUI_HypothesisCreator::readParamsFromHypo( NetgenHypothesisData& h_data ) const
456 {
457   NETGENPlugin::NETGENPlugin_Hypothesis_var h =
458     NETGENPlugin::NETGENPlugin_Hypothesis::_narrow( initParamsHypothesis() );
459
460   h_data.myName = isCreation() ? hypName() : "";
461
462   h_data.myMaxSize     = h->GetMaxSize();
463   h_data.myMaxSizeVar  = getVariableName("SetMaxSize");
464   h_data.mySecondOrder = h->GetSecondOrder();
465   h_data.myOptimize    = h->GetOptimize();
466
467   h_data.myFineness            = (int) h->GetFineness();
468   h_data.myGrowthRate          = h->GetGrowthRate();
469   h_data.myGrowthRateVar       = getVariableName("SetGrowthRate");
470   h_data.myNbSegPerEdge        = h->GetNbSegPerEdge();
471   h_data.myNbSegPerEdgeVar     = getVariableName("SetNbSegPerEdge");
472   h_data.myNbSegPerRadius      = h->GetNbSegPerRadius();
473   h_data.myNbSegPerRadiusVar   = getVariableName("SetNbSegPerRadius");
474   h_data.myChordalError        = h->GetChordalError();
475   h_data.myChordalErrorVar     = getVariableName("SetChordalError");
476   h_data.myChordalErrorEnabled = h->GetChordalErrorEnabled();
477   h_data.myMinSize             = h->GetMinSize();
478   h_data.myMinSizeVar          = getVariableName("SetMinSize");
479   h_data.mySurfaceCurvature    = h->GetUseSurfaceCurvature();
480   h_data.myFuseEdges           = h->GetFuseEdges();
481   h_data.myMeshSizeFile        = h->GetMeshSizeFile();
482
483   //if ( myIs2D )
484   {
485     // NETGENPlugin::NETGENPlugin_Hypothesis_var h =
486     //   NETGENPlugin::NETGENPlugin_Hypothesis::_narrow( initParamsHypothesis() );
487
488     if ( !h->_is_nil() )
489       h_data.myAllowQuadrangles = h->GetQuadAllowed();
490   }
491   if ( myIs2D )
492   {
493     NETGENPlugin::NETGENPlugin_RemesherHypothesis_2D_var rh =
494       NETGENPlugin::NETGENPlugin_RemesherHypothesis_2D::_narrow( h );
495
496     if ( !rh->_is_nil() )
497       h_data.myRidgeAngle = rh->GetRidgeAngle();
498   }
499
500   NETGENPluginGUI_HypothesisCreator*  that = (NETGENPluginGUI_HypothesisCreator*)this;
501   NETGENPlugin::string_array_var myEntries = h->GetLocalSizeEntries();
502   for ( size_t i = 0; i < myEntries->length(); i++ )
503   {
504     QString entry = myEntries[i].in();
505     double val = h->GetLocalSizeOnEntry(entry.toStdString().c_str());
506     std::ostringstream tmp;
507     tmp << val;
508     QString valstring = QString::fromStdString(tmp.str());
509     if (myLocalSizeMap.contains(entry))
510     {
511       if (myLocalSizeMap[entry] == "__TO_DELETE__")
512       {
513         continue;
514       }
515     }
516     that->myLocalSizeMap[entry] = valstring;
517   }
518
519   return true;
520 }
521
522 bool NETGENPluginGUI_HypothesisCreator::storeParamsToHypo( const NetgenHypothesisData& h_data ) const
523 {
524   NETGENPlugin::NETGENPlugin_Hypothesis_var h =
525     NETGENPlugin::NETGENPlugin_Hypothesis::_narrow( hypothesis() );
526
527   bool ok = true;
528   try
529   {
530     if( isCreation() )
531       SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().data() );
532     h->SetVarParameter( h_data.myMaxSizeVar.toLatin1().constData(), "SetMaxSize");
533     h->SetMaxSize     ( h_data.myMaxSize );
534     if ( mySecondOrder )
535       h->SetSecondOrder ( h_data.mySecondOrder );
536     if ( myOptimize )
537       h->SetOptimize    ( h_data.myOptimize );
538     int fineness = h_data.myFineness;
539     h->SetFineness    ( fineness );
540
541     if( fineness==UserDefined )
542     {
543       h->SetVarParameter  ( h_data.myGrowthRateVar.toLatin1().constData(), "SetGrowthRate");
544       h->SetGrowthRate    ( h_data.myGrowthRate );
545       if ( myNbSegPerEdge )
546       {
547         h->SetVarParameter  ( h_data.myNbSegPerEdgeVar.toLatin1().constData(), "SetNbSegPerEdge");
548         h->SetNbSegPerEdge  ( h_data.myNbSegPerEdge );
549       }
550       if ( myNbSegPerRadius )
551       {
552         h->SetVarParameter  ( h_data.myNbSegPerRadiusVar.toLatin1().constData(), "SetNbSegPerRadius");
553         h->SetNbSegPerRadius( h_data.myNbSegPerRadius );
554       }
555     }
556     if ( myChordalError )
557     {
558       h->SetVarParameter       ( h_data.myChordalErrorVar.toLatin1().constData(), "SetChordalError");
559       h->SetChordalError       ( h_data.myChordalError );
560       h->SetChordalErrorEnabled( h_data.myChordalErrorEnabled );
561     }
562     h->SetVarParameter       ( h_data.myMinSizeVar.toLatin1().constData(), "SetMinSize");
563     h->SetMinSize            ( h_data.myMinSize );
564     if ( mySurfaceCurvature )
565       h->SetUseSurfaceCurvature( h_data.mySurfaceCurvature );
566     if ( myFuseEdges )
567       h->SetFuseEdges          ( h_data.myFuseEdges );
568     h->SetMeshSizeFile       ( h_data.myMeshSizeFile.toUtf8().constData() );
569
570     //if ( myIs2D )
571     {
572       // NETGENPlugin::NETGENPlugin_Hypothesis_2D_var h_2d =
573       //   NETGENPlugin::NETGENPlugin_Hypothesis_2D::_narrow( h );
574       // if ( !h_2d->_is_nil() )
575       //   h_2d->SetQuadAllowed( h_data.myAllowQuadrangles );
576       if ( myAllowQuadrangles )
577         h->SetQuadAllowed( h_data.myAllowQuadrangles );
578     }
579     if ( myIs2D )
580     {
581       NETGENPlugin::NETGENPlugin_RemesherHypothesis_2D_var rh =
582         NETGENPlugin::NETGENPlugin_RemesherHypothesis_2D::_narrow( h );
583       if ( !rh->_is_nil() )
584       {
585         rh->SetVarParameter( h_data.myRidgeAngleVar.toLatin1().constData(), "SetRidgeAngle");
586         rh->SetRidgeAngle  ( h_data.myRidgeAngle );
587       }
588     }
589     for ( QMapIterator<QString,QString> i(myLocalSizeMap); i.hasNext(); i.next() )
590     {
591       const QString     entry = i.key();
592       const QString localSize = i.value();
593       if (localSize == "__TO_DELETE__")
594       {
595         h->UnsetLocalSizeOnEntry(entry.toLatin1().constData());
596       }
597       else
598       {
599         h->SetLocalSizeOnEntry(entry.toLatin1().constData(), localSize.toDouble());
600       }
601     }
602   }
603   catch(const SALOME::SALOME_Exception& ex)
604   {
605     SalomeApp_Tools::QtCatchCorbaException(ex);
606     ok = false;
607   }
608   return ok;
609 }
610
611 bool NETGENPluginGUI_HypothesisCreator::readParamsFromWidgets( NetgenHypothesisData& h_data ) const
612 {
613   h_data.myName           = myName ? myName->text() : "";
614   h_data.myMaxSize        = myMaxSize->value();
615   h_data.myMaxSizeVar     = myMaxSize->text();
616   h_data.myMinSize        = myMinSize->value();
617   h_data.myMinSizeVar     = myMinSize->text();
618   if ( mySecondOrder )
619     h_data.mySecondOrder  = mySecondOrder->isChecked();
620   if ( myOptimize )
621     h_data.myOptimize     = myOptimize->isChecked();
622   h_data.myFineness       = myFineness->currentIndex();
623   h_data.myGrowthRate     = myGrowthRate->value();
624   if ( myNbSegPerEdge )
625     h_data.myNbSegPerEdge = myNbSegPerEdge->value();
626   if ( myNbSegPerRadius )
627     h_data.myNbSegPerRadius = myNbSegPerRadius->value();
628
629   h_data.myGrowthRateVar  = myGrowthRate->text();
630   if ( myNbSegPerEdge )
631     h_data.myNbSegPerEdgeVar = myNbSegPerEdge->text();
632   if ( myNbSegPerRadius )
633     h_data.myNbSegPerRadiusVar = myNbSegPerRadius->text();
634   if ( myChordalError )
635   {
636     h_data.myChordalErrorVar = myChordalError->text();
637     h_data.myChordalError    = myChordalError->value();
638     h_data.myChordalErrorEnabled = myChordalError->isEnabled();
639   }
640   if ( myRidgeAngle )
641   {
642     h_data.myRidgeAngleVar = myRidgeAngle->text();
643     h_data.myRidgeAngle    = myRidgeAngle->value();
644   }
645
646   if ( myAllowQuadrangles )
647     h_data.myAllowQuadrangles = myAllowQuadrangles->isChecked();
648
649   if ( mySurfaceCurvature )
650     h_data.mySurfaceCurvature = mySurfaceCurvature->isChecked();
651
652   if ( myFuseEdges )
653     h_data.myFuseEdges = myFuseEdges->isChecked();
654
655   if ( myLocalSizeTable )
656   {
657     NETGENPluginGUI_HypothesisCreator* that = (NETGENPluginGUI_HypothesisCreator*)this;
658     int nbRows = myLocalSizeTable->rowCount();
659     for(int row=0 ; row < nbRows ; row++)
660     {
661       QString entry = myLocalSizeTable->item(row, LSZ_ENTRY_COLUMN)->text();
662       QString localSize = myLocalSizeTable->item(row, LSZ_LOCALSIZE_COLUMN)->text().trimmed();
663       that->myLocalSizeMap[entry] = localSize;
664     }
665     h_data.myMeshSizeFile = myMeshSizeFile->text();
666   }
667   return true;
668 }
669
670 void NETGENPluginGUI_HypothesisCreator::onChordalErrorEnabled()
671 {
672   myChordalError->setEnabled( myChordalErrorEnabled->isChecked() );
673 }
674
675 void NETGENPluginGUI_HypothesisCreator::onSurfaceCurvatureChanged()
676 {
677   bool isSurfaceCurvature = (mySurfaceCurvature ? mySurfaceCurvature->isChecked() : true);
678   bool isCustom           = (myFineness->currentIndex() == UserDefined);
679   //myFineness->setEnabled(isSurfaceCurvature);
680   myGrowthRate->setEnabled(isCustom);
681   if ( myNbSegPerEdge )
682     myNbSegPerEdge->setEnabled(isCustom && isSurfaceCurvature);
683   if ( myNbSegPerRadius )
684     myNbSegPerRadius->setEnabled(isCustom && isSurfaceCurvature);
685   // if ( myChordalError )
686   // {
687   //   myChordalError->setEnabled( isSurfaceCurvature );
688   //   myChordalErrorEnabled->setEnabled( isSurfaceCurvature );
689   // }
690 }
691
692 void NETGENPluginGUI_HypothesisCreator::onFinenessChanged()
693 {
694   bool isCustom = (myFineness->currentIndex() == UserDefined);
695
696   myGrowthRate->setEnabled(isCustom);
697   if ( myNbSegPerEdge )
698     myNbSegPerEdge->setEnabled(isCustom);
699   if ( myNbSegPerRadius )
700     myNbSegPerRadius->setEnabled(isCustom);
701
702   if (!isCustom)
703   {
704     double aGrowthRate, aNbSegPerEdge, aNbSegPerRadius;
705
706     switch ( myFineness->currentIndex() )
707     {
708     case VeryCoarse:
709       aGrowthRate     = 0.7;
710       aNbSegPerEdge   = 0.3;
711       aNbSegPerRadius = 1;
712       break;
713     case Coarse:
714       aGrowthRate     = 0.5;
715       aNbSegPerEdge   = 0.5;
716       aNbSegPerRadius = 1.5;
717       break;
718     case Fine:
719       aGrowthRate     = 0.2;
720       aNbSegPerEdge   = 2;
721       aNbSegPerRadius = 3;
722       break;
723     case VeryFine:
724       aGrowthRate     = 0.1;
725       aNbSegPerEdge   = 3;
726       aNbSegPerRadius = 5;
727       break;
728     case Moderate:
729     default:
730       aGrowthRate     = 0.3;
731       aNbSegPerEdge   = 1;
732       aNbSegPerRadius = 2;
733       break;
734     }
735
736     myGrowthRate->setValue( aGrowthRate );
737     if ( myNbSegPerEdge )
738       myNbSegPerEdge->setValue( aNbSegPerEdge );
739     if ( myNbSegPerRadius )
740       myNbSegPerRadius->setValue( aNbSegPerRadius );
741   }
742 }
743
744 void NETGENPluginGUI_HypothesisCreator::onAddLocalSizeOnVertex()
745 {
746   addLocalSizeOnShape(TopAbs_VERTEX);
747 }
748
749 void NETGENPluginGUI_HypothesisCreator::onAddLocalSizeOnEdge()
750 {
751   addLocalSizeOnShape(TopAbs_EDGE);
752 }
753
754 void NETGENPluginGUI_HypothesisCreator::onAddLocalSizeOnFace()
755 {
756   addLocalSizeOnShape(TopAbs_FACE);
757 }
758
759 void NETGENPluginGUI_HypothesisCreator::onAddLocalSizeOnSolid()
760 {
761   addLocalSizeOnShape(TopAbs_SOLID);
762 }
763
764 void NETGENPluginGUI_HypothesisCreator::addLocalSizeOnShape(TopAbs_ShapeEnum typeShapeAsked)
765 {
766   NETGENPlugin::NETGENPlugin_Hypothesis_var h = NETGENPlugin::NETGENPlugin_Hypothesis::_narrow(initParamsHypothesis());
767   GeomSelectionTools* geomSelectionTools = getGeomSelectionTools();
768   LightApp_SelectionMgr* mySel = geomSelectionTools->selectionMgr();
769   SALOME_ListIO ListSelectedObjects;
770   mySel->selectedObjects(ListSelectedObjects, NULL, false );
771   SALOME_ListIteratorOfListIO Object_It(ListSelectedObjects);
772   for ( ; Object_It.More() ; Object_It.Next())
773   {
774     Handle(SALOME_InteractiveObject) anObject = Object_It.Value();
775     std::string entry, shapeName;
776     entry = geomSelectionTools->getEntryOfObject(anObject);
777     shapeName = anObject->getName();
778     TopAbs_ShapeEnum shapeType;
779     shapeType = geomSelectionTools->entryToShapeType(entry);
780     if (shapeType == TopAbs_SHAPE)
781     {
782       // E.A. if shapeType == TopAbs_SHAPE, it is NOT a TopoDS_Shape !!!
783       continue;
784     }
785     // --
786     if(shapeType != typeShapeAsked)
787     {
788       continue;
789     }
790     // --
791     myLocalSizeTable->setFocus();
792     QString shapeEntry;
793     shapeEntry = QString::fromStdString(entry);
794     if (myLocalSizeMap.contains(shapeEntry))
795     {
796       if (myLocalSizeMap[shapeEntry] != "__TO_DELETE__")
797       {
798         continue;
799       }
800     }
801     double phySize = h->GetMaxSize();
802     std::ostringstream oss;
803     oss << phySize;
804     QString localSize;
805     localSize  = QString::fromStdString(oss.str());
806     // --
807     int row = myLocalSizeTable->rowCount() ;
808     myLocalSizeTable->setRowCount(row+1);
809     myLocalSizeTable->setItem(row, LSZ_ENTRY_COLUMN, new QTableWidgetItem(shapeEntry));
810     myLocalSizeTable->item(row, LSZ_ENTRY_COLUMN )->setFlags(0);
811     myLocalSizeTable->setItem(row, LSZ_NAME_COLUMN, new QTableWidgetItem(QString::fromStdString(shapeName)));
812     myLocalSizeTable->item(row, LSZ_NAME_COLUMN )->setFlags(0);
813     myLocalSizeTable->setItem(row, LSZ_LOCALSIZE_COLUMN, new QTableWidgetItem(localSize));
814     myLocalSizeTable->item(row, LSZ_LOCALSIZE_COLUMN )->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsEnabled);
815     myLocalSizeTable->resizeColumnToContents(LSZ_NAME_COLUMN);
816     myLocalSizeTable->resizeColumnToContents(LSZ_LOCALSIZE_COLUMN);
817     myLocalSizeTable->clearSelection();
818     myLocalSizeTable->scrollToItem( myLocalSizeTable->item( row, LSZ_LOCALSIZE_COLUMN ) );
819     // --
820   }
821 }
822
823 void NETGENPluginGUI_HypothesisCreator::onRemoveLocalSizeOnShape()
824 {
825   QList<int> selectedRows;
826   QList<QTableWidgetItem*> selected = myLocalSizeTable->selectedItems();
827   QTableWidgetItem* item;
828   int row;
829   foreach(item, selected) {
830     row = item->row();
831     if (!selectedRows.contains(row))
832       selectedRows.append( row );
833   }
834   qSort( selectedRows );
835   QListIterator<int> it( selectedRows );
836   it.toBack();
837   while (it.hasPrevious())
838   {
839     row = it.previous();
840     QString entry = myLocalSizeTable->item(row,LSZ_ENTRY_COLUMN)->text();
841     if (myLocalSizeMap.contains(entry))
842     {
843       myLocalSizeMap[entry] = "__TO_DELETE__";
844     }
845     myLocalSizeTable->removeRow(row );
846   }
847   myLocalSizeTable->resizeColumnToContents(LSZ_NAME_COLUMN);
848   myLocalSizeTable->resizeColumnToContents(LSZ_LOCALSIZE_COLUMN);
849 }
850
851 void NETGENPluginGUI_HypothesisCreator::onSetLocalSize(int row,int col)
852 {
853   if (col == LSZ_LOCALSIZE_COLUMN) {
854     QString entry = myLocalSizeTable->item(row, LSZ_ENTRY_COLUMN)->text();
855     QString localSize = myLocalSizeTable->item(row, LSZ_LOCALSIZE_COLUMN)->text().trimmed();
856     myLocalSizeMap[entry] = localSize;
857     myLocalSizeTable->resizeColumnToContents(LSZ_LOCALSIZE_COLUMN);
858   }
859 }
860
861 void NETGENPluginGUI_HypothesisCreator::onSetSizeFile()
862 {
863   QString dir = SUIT_FileDlg::getFileName( dlg(), QString(),
864                                            QStringList() << tr( "ALL_FILES_FILTER" ) + "  (*)");
865   myMeshSizeFile->setText( dir );
866 }
867
868 GeomSelectionTools* NETGENPluginGUI_HypothesisCreator::getGeomSelectionTools()
869 {
870   if (myGeomSelectionTools == NULL) {
871     delete myGeomSelectionTools;
872     myGeomSelectionTools = new GeomSelectionTools();
873   }
874   return myGeomSelectionTools;
875 }
876
877 QString NETGENPluginGUI_HypothesisCreator::caption() const
878 {
879   return tr( myIs2D ? "NETGEN_2D_TITLE" : "NETGEN_3D_TITLE");
880 }
881
882 QPixmap NETGENPluginGUI_HypothesisCreator::icon() const
883 {
884   QString hypIconName = tr( myIs2D ?
885                             "ICON_DLG_NETGEN_PARAMETERS_2D" :
886                             "ICON_DLG_NETGEN_PARAMETERS");
887   return SUIT_Session::session()->resourceMgr()->loadPixmap( "NETGENPlugin", hypIconName );
888 }
889
890 QString NETGENPluginGUI_HypothesisCreator::type() const
891 {
892   return tr( myIs2D ? "NETGEN_2D_HYPOTHESIS" : "NETGEN_3D_HYPOTHESIS");
893 }
894
895 QString NETGENPluginGUI_HypothesisCreator::helpPage() const
896 {
897   return "netgen_2d_3d_hypo_page.html";
898 }