Salome HOME
Merge from V6_main_20120808 08Aug12
[plugins/hexablockplugin.git] / src / GUI / HEXABLOCKPluginGUI_HypothesisCreator.cxx
1 // Copyright (C) 2009-2012  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //  HEXABLOCKPlugin GUI: GUI for plugged-in mesher HEXABLOCKPlugin
21 //  File   : HEXABLOCKPluginGUI_HypothesisCreator.cxx
22 //  Author : Lioka RAZAFINDRAZAKA (CEA)
23 //  Module : HEXABLOCKPlugin
24 //  $Header: 
25 //
26 #include "HEXABLOCKPluginGUI_HypothesisCreator.h"
27
28 #include <SMESHGUI_Utils.h>
29 #include <SMESHGUI_HypothesesUtils.h>
30
31 #include <SUIT_Session.h>
32 #include <SUIT_MessageBox.h>
33 #include <SUIT_ResourceMgr.h>
34 #include <SUIT_FileDlg.h>
35 #include <SalomeApp_Tools.h>
36 #include <SalomeApp_TypeFilter.h>
37
38 #include <QComboBox>
39 #include <QLabel>
40 #include <QFrame>
41 #include <QVBoxLayout>
42 #include <QGridLayout>
43 #include <QLineEdit>
44 #include <QCheckBox>
45 #include <QTabWidget>
46 #include <QSpinBox>
47 #include <QPushButton>
48 #include <QFileInfo>
49
50 #include <QTableWidget>
51 #include <QStandardItemModel>
52 #include <QStandardItem>
53 #include <QHeaderView>
54 #include <QModelIndexList>
55
56 #include <stdexcept>
57 #include <utilities.h>
58
59 #ifdef _DEBUG_
60 static int MYDEBUG = 1;
61 #else
62 static int MYDEBUG = 0;
63 #endif
64
65
66 // tabs
67 enum {
68   STD_TAB = 0,
69   ADV_TAB,
70   ENF_VER_TAB
71 };
72
73 // Enforced vertices array columns
74 enum {
75   ENF_VER_X_COLUMN = 0,
76   ENF_VER_Y_COLUMN,
77   ENF_VER_Z_COLUMN,
78   ENF_VER_SIZE_COLUMN,
79   ENF_VER_NB_COLUMNS
80 };
81
82 // Enforced vertices inputs
83 enum {
84   ENF_VER_BTNS = 0,
85   ENF_VER_X_COORD,
86   ENF_VER_Y_COORD,
87   ENF_VER_Z_COORD,
88   ENF_VER_SIZE,
89   ENF_VER_VERTEX_BTN,
90   ENF_VER_SEPARATOR,
91   ENF_VER_REMOVE_BTN,
92 };
93
94 namespace {
95
96 #ifdef WIN32
97 #include <windows.h>
98 #else
99 #include <sys/sysinfo.h>
100 #endif
101
102   int maxAvailableMemory()
103   {
104 #ifdef WIN32
105     // See http://msdn.microsoft.com/en-us/library/aa366589.aspx
106     MEMORYSTATUSEX statex;
107     statex.dwLength = sizeof (statex);
108     int err = GlobalMemoryStatusEx (&statex);
109     if (err != 0) {
110       int totMB = 
111         statex.ullTotalPhys / 1024 / 1024 +
112         statex.ullTotalPageFile / 1024 / 1024 +
113         statex.ullTotalVirtual / 1024 / 1024;
114       return (int) ( 0.7 * totMB );
115     }
116 #else
117     struct sysinfo si;
118     int err = sysinfo( &si );
119     if ( err == 0 ) {
120       int totMB =
121         si.totalram * si.mem_unit / 1024 / 1024 +
122         si.totalswap * si.mem_unit / 1024 / 1024 ;
123       return (int) ( 0.7 * totMB );
124     }
125 #endif
126     return 0;
127   }
128 }
129
130 class QDoubleValidator;
131
132 //
133 // BEGIN DoubleLineEditDelegate
134 //
135
136 DoubleLineEditDelegate::DoubleLineEditDelegate(QObject *parent)
137     : QItemDelegate(parent)
138 {
139 }
140
141 QWidget *DoubleLineEditDelegate::createEditor(QWidget *parent,
142     const QStyleOptionViewItem &/* option */,
143     const QModelIndex &/* index */) const
144 {
145     QLineEdit *editor = new QLineEdit(parent);
146     editor->setValidator(new QDoubleValidator(parent));
147
148     return editor;
149 }
150
151 void DoubleLineEditDelegate::setEditorData(QWidget *editor,
152                                     const QModelIndex &index) const
153 {
154     QString value = index.model()->data(index, Qt::EditRole).toString();
155
156     QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
157     lineEdit->setText(value);
158 }
159
160 void DoubleLineEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
161                                     const QModelIndex &index) const
162 {
163     QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
164     bool ok;
165     double value = lineEdit->text().toDouble(&ok);
166
167     if (ok) {
168         model->setData(index, value, Qt::EditRole);
169         if(MYDEBUG) MESSAGE("Value " << value << " was set at index(" << index.row() << "," << index.column() << ")");
170     }
171 }
172
173 void DoubleLineEditDelegate::updateEditorGeometry(QWidget *editor,
174     const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
175 {
176     editor->setGeometry(option.rect);
177 }
178
179 //
180 // END DoubleLineEditDelegate
181 //
182
183 HEXABLOCKPluginGUI_HypothesisCreator::HEXABLOCKPluginGUI_HypothesisCreator( const QString& theHypType )
184 : SMESHGUI_GenericHypothesisCreator( theHypType )
185 {
186 }
187
188 HEXABLOCKPluginGUI_HypothesisCreator::~HEXABLOCKPluginGUI_HypothesisCreator()
189 {
190 }
191
192 QFrame* HEXABLOCKPluginGUI_HypothesisCreator::buildFrame()
193 {
194   QFrame* fr = new QFrame( 0 );
195   QVBoxLayout* lay = new QVBoxLayout( fr );
196   lay->setMargin( 5 );
197   lay->setSpacing( 0 );
198
199   // tab
200   QTabWidget* tab = new QTabWidget( fr );
201   tab->setTabShape( QTabWidget::Rounded );
202   tab->setTabPosition( QTabWidget::North );
203   lay->addWidget( tab );
204
205   // basic parameters
206   myStdGroup = new QWidget();
207   QGridLayout* aStdLayout = new QGridLayout( myStdGroup );
208   aStdLayout->setSpacing( 6 );
209   aStdLayout->setMargin( 11 );
210
211   int row = 0;
212   myName = 0;
213   if( isCreation() )
214   {
215     aStdLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), myStdGroup ), row, 0, 1, 1 );
216     myName = new QLineEdit( myStdGroup );
217     aStdLayout->addWidget( myName, row++, 1, 1, 1 );
218   }
219
220   myToMeshHolesCheck = new QCheckBox( tr( "HEXABLOCK_TO_MESH_HOLES" ), myStdGroup );
221   aStdLayout->addWidget( myToMeshHolesCheck, row++, 0, 1, 2 );
222
223   aStdLayout->addWidget( new QLabel( tr( "HEXABLOCK_OPTIMIZATIOL_LEVEL" ), myStdGroup ), row, 0 );
224   myOptimizationLevelCombo = new QComboBox( myStdGroup );
225   aStdLayout->addWidget( myOptimizationLevelCombo, row++, 1, 1, 1 );
226
227   QStringList types;
228   types << tr( "LEVEL_NONE" ) << tr( "LEVEL_LIGHT" ) << tr( "LEVEL_MEDIUM" ) << tr( "LEVEL_STANDARDPLUS" ) << tr( "LEVEL_STRONG" );
229   myOptimizationLevelCombo->addItems( types );
230
231   aStdLayout->setRowStretch( row, 5 );
232
233   // advanced parameters
234   myAdvGroup = new QWidget();
235   QGridLayout* anAdvLayout = new QGridLayout( myAdvGroup );
236   anAdvLayout->setSpacing( 6 );
237   anAdvLayout->setMargin( 11 );
238   
239   myMaximumMemoryCheck = new QCheckBox( tr( "MAX_MEMORY_SIZE" ), myAdvGroup );
240   myMaximumMemorySpin = new QSpinBox( myAdvGroup );
241   myMaximumMemorySpin->setMinimum( 1 );
242   myMaximumMemorySpin->setMaximum( maxAvailableMemory() );
243   myMaximumMemorySpin->setSingleStep( 10 );
244   QLabel* aMegabyteLabel = new QLabel( tr( "MEGABYTE" ), myAdvGroup );
245
246   myInitialMemoryCheck = new QCheckBox( tr( "INIT_MEMORY_SIZE" ), myAdvGroup );
247   myInitialMemorySpin = new QSpinBox( myAdvGroup );
248   myInitialMemorySpin->setMinimum( 1 );
249   myInitialMemorySpin->setMaximum( maxAvailableMemory() );
250   myInitialMemorySpin->setSingleStep( 10 );
251   QLabel* aMegabyteLabel2 = new QLabel( tr( "MEGABYTE" ), myAdvGroup );
252
253   QLabel* aWorkinDirLabel = new QLabel( tr( "WORKING_DIR" ), myAdvGroup );
254   myWorkingDir = new QLineEdit( myAdvGroup );
255   //myWorkingDir->setReadOnly( true );
256   QPushButton* dirBtn = new QPushButton( tr( "SELECT_DIR" ), myAdvGroup );
257   dirBtn->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
258   
259   myKeepFiles = new QCheckBox( tr( "KEEP_WORKING_FILES" ), myAdvGroup );
260
261   QLabel* aVerboseLevelLabel = new QLabel( tr( "VERBOSE_LEVEL" ), myAdvGroup );
262   myVerboseLevelSpin = new QSpinBox( myAdvGroup );
263   myVerboseLevelSpin->setMinimum( 0 );
264   myVerboseLevelSpin->setMaximum( 10 );
265   myVerboseLevelSpin->setSingleStep( 1 );
266
267   myToCreateNewNodesCheck = new QCheckBox( tr( "TO_ADD_NODES" ), myAdvGroup );
268   
269   myRemoveInitialCentralPointCheck = new QCheckBox( tr( "NO_INITIAL_CENTRAL_POINT" ), myAdvGroup );
270   
271   myBoundaryRecoveryCheck = new QCheckBox( tr( "RECOVERY_VERSION" ), myAdvGroup );
272   
273   myFEMCorrectionCheck = new QCheckBox( tr( "FEM_CORRECTION" ), myAdvGroup );
274
275   QLabel* aTextOptionLabel = new QLabel( tr( "TEXT_OPTION" ), myAdvGroup );
276   myTextOption = new QLineEdit( myAdvGroup );
277
278   anAdvLayout->addWidget( myMaximumMemoryCheck,             0, 0, 1, 1 );
279   anAdvLayout->addWidget( myMaximumMemorySpin,              0, 1, 1, 1 );
280   anAdvLayout->addWidget( aMegabyteLabel,                   0, 2, 1, 1 );
281   anAdvLayout->addWidget( myInitialMemoryCheck,             1, 0, 1, 1 );
282   anAdvLayout->addWidget( myInitialMemorySpin,              1, 1, 1, 1 );
283   anAdvLayout->addWidget( aMegabyteLabel2,                  1, 2, 1, 1 );
284   anAdvLayout->addWidget( aWorkinDirLabel,                  2, 0, 1, 1 );
285   anAdvLayout->addWidget( myWorkingDir,                     2, 1, 1, 2 );
286   anAdvLayout->addWidget( dirBtn,                           2, 3, 1, 1 );
287   anAdvLayout->addWidget( myKeepFiles,                      3, 0, 1, 4 );
288   anAdvLayout->addWidget( aVerboseLevelLabel,               4, 0, 1, 1 );
289   anAdvLayout->addWidget( myVerboseLevelSpin,               4, 1, 1, 1 );
290   anAdvLayout->addWidget( myToCreateNewNodesCheck,          5, 0, 1, 4 );
291   anAdvLayout->addWidget( myRemoveInitialCentralPointCheck, 6, 0, 1, 4 );
292   anAdvLayout->addWidget( myBoundaryRecoveryCheck,          7, 0, 1, 4 );
293   anAdvLayout->addWidget( myFEMCorrectionCheck,             8, 0, 1, 4 );
294   anAdvLayout->addWidget( aTextOptionLabel,                 9, 0, 1, 1 );
295   anAdvLayout->addWidget( myTextOption,                     9, 1, 1, 2 );
296
297   // Size Maps parameters
298   myEnfGroup = new QWidget();
299   QGridLayout* anSmpLayout = new QGridLayout(myEnfGroup);
300   
301   mySmpModel = new QStandardItemModel(0, ENF_VER_NB_COLUMNS);
302   myEnforcedTableView = new QTableView(myEnfGroup);
303   myEnforcedTableView->setModel(mySmpModel);
304   myEnforcedTableView->setSortingEnabled(true);
305   myEnforcedTableView->setItemDelegateForColumn(ENF_VER_SIZE_COLUMN,new DoubleLineEditDelegate(this));
306   anSmpLayout->addWidget(myEnforcedTableView, 1, 0, 9, 1);
307   QStringList enforcedHeaders;
308   enforcedHeaders << tr( "HEXABLOCK_ENF_VER_X_COLUMN" )<< tr( "HEXABLOCK_ENF_VER_Y_COLUMN" ) << tr( "HEXABLOCK_ENF_VER_Z_COLUMN" ) << tr( "HEXABLOCK_ENF_VER_SIZE_COLUMN" ); 
309   mySmpModel->setHorizontalHeaderLabels(enforcedHeaders);
310   myEnforcedTableView->setAlternatingRowColors(true);
311   myEnforcedTableView->verticalHeader()->hide();
312   myEnforcedTableView->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
313   
314   QLabel* myXCoordLabel = new QLabel( tr( "HEXABLOCK_ENF_VER_X_LABEL" ), myEnfGroup );
315   anSmpLayout->addWidget(myXCoordLabel, ENF_VER_X_COORD, 1, 1, 1);
316   myXCoord = new QLineEdit(myEnfGroup);
317   myXCoord->setValidator(new QDoubleValidator(myEnfGroup));
318   anSmpLayout->addWidget(myXCoord, ENF_VER_X_COORD, 2, 1, 1);
319   QLabel* myYCoordLabel = new QLabel( tr( "HEXABLOCK_ENF_VER_Y_LABEL" ), myEnfGroup );
320   anSmpLayout->addWidget(myYCoordLabel, ENF_VER_Y_COORD, 1, 1, 1);
321   myYCoord = new QLineEdit(myEnfGroup);
322   myYCoord->setValidator(new QDoubleValidator(myEnfGroup));
323   anSmpLayout->addWidget(myYCoord, ENF_VER_Y_COORD, 2, 1, 1);
324   QLabel* myZCoordLabel = new QLabel( tr( "HEXABLOCK_ENF_VER_Z_LABEL" ), myEnfGroup );
325   anSmpLayout->addWidget(myZCoordLabel, ENF_VER_Z_COORD, 1, 1, 1);
326   myZCoord = new QLineEdit(myEnfGroup);
327   myZCoord->setValidator(new QDoubleValidator(myEnfGroup));
328   anSmpLayout->addWidget(myZCoord, ENF_VER_Z_COORD, 2, 1, 1);
329   QLabel* mySizeLabel = new QLabel( tr( "HEXABLOCK_ENF_VER_SIZE_LABEL" ), myEnfGroup );
330   anSmpLayout->addWidget(mySizeLabel, ENF_VER_SIZE, 1, 1, 1);
331   mySizeValue = new QLineEdit(myEnfGroup);
332   mySizeValue->setValidator(new QDoubleValidator(myEnfGroup));
333   anSmpLayout->addWidget(mySizeValue, ENF_VER_SIZE, 2, 1, 1);
334
335   addVertexButton = new QPushButton(tr("HEXABLOCK_ENF_VER_VERTEX"),myEnfGroup);
336   anSmpLayout->addWidget(addVertexButton, ENF_VER_VERTEX_BTN, 1, 1, 2);
337   addVertexButton->setEnabled(false);
338
339   QFrame *line = new QFrame(myEnfGroup);
340   line->setFrameShape(QFrame::HLine);
341   line->setFrameShadow(QFrame::Sunken);
342   anSmpLayout->addWidget(line, ENF_VER_SEPARATOR, 1, 1, 2);
343
344   removeVertexButton = new QPushButton(tr("HEXABLOCK_ENF_VER_REMOVE"),myEnfGroup);
345   anSmpLayout->addWidget(removeVertexButton, ENF_VER_REMOVE_BTN, 1, 1, 2);
346           
347   // add tabs
348   tab->insertTab( STD_TAB, myStdGroup, tr( "SMESH_ARGUMENTS" ) );
349   tab->insertTab( ADV_TAB, myAdvGroup, tr( "HEXABLOCK_ADV_ARGS" ) );
350   tab->insertTab( ENF_VER_TAB, myEnfGroup, tr( "HEXABLOCK_ENFORCED_VERTICES" ) );
351   tab->setCurrentIndex( STD_TAB );
352
353   // connections
354   connect( myMaximumMemoryCheck,    SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) );
355   connect( myInitialMemoryCheck,    SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) );
356   connect( myBoundaryRecoveryCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) );
357   connect( dirBtn,                  SIGNAL( clicked() ),       this, SLOT( onDirBtnClicked() ) );
358   connect( myXCoord,                SIGNAL( textChanged(const QString&) ),   this, SLOT( checkVertexIsDefined() ) );
359   connect( myYCoord,                SIGNAL( textChanged(const QString&) ),   this, SLOT( checkVertexIsDefined() ) );
360   connect( myZCoord,                SIGNAL( textChanged(const QString&) ),   this, SLOT( checkVertexIsDefined() ) );
361   connect( mySizeValue,             SIGNAL( textChanged(const QString&) ),   this, SLOT( checkVertexIsDefined() ) );
362   connect( this,                    SIGNAL( vertexDefined(bool) ), addVertexButton, SLOT( setEnabled(bool) ) );
363   connect( addVertexButton,         SIGNAL( clicked() ),       this, SLOT( onVertexBtnClicked() ) );
364   connect( removeVertexButton,      SIGNAL( clicked() ),       this, SLOT( onRemoveVertexBtnClicked() ) );
365   
366
367   
368   return fr;
369 }
370
371 bool HEXABLOCKPluginGUI_HypothesisCreator::smpVertexExists(double x, double y, double z) const
372 {
373     const int rowCount = mySmpModel->rowCount();
374     for (int i=0 ; i < rowCount ; i++) {
375       double myX = mySmpModel->data(mySmpModel->index(i, ENF_VER_X_COLUMN)).toDouble();
376       if (myX == x) {
377 //         MESSAGE("Found x value " << x << " at row " << i);
378         double myY = mySmpModel->data(mySmpModel->index(i, ENF_VER_Y_COLUMN)).toDouble();
379         if (myY == y) {
380 //           MESSAGE("Found y value " << y << " at row " << i);
381           double myZ = mySmpModel->data(mySmpModel->index(i, ENF_VER_Z_COLUMN)).toDouble();
382           if (myZ == z) {
383             if (MYDEBUG){
384               MESSAGE("Found x value " << x << " at row " << i);
385               MESSAGE("Found y value " << y << " at row " << i);
386               MESSAGE("Found z value " << z << " at row " << i);
387             }
388             return true;
389           }
390         }
391       }
392     }
393 //     MESSAGE("Not found x,y,z values: " << x << " " << y << " " << z);
394     return false;
395 }
396
397 bool HEXABLOCKPluginGUI_HypothesisCreator::checkVertexIsDefined()
398 {
399   bool val = (!myXCoord->text().isEmpty())&&(!myYCoord->text().isEmpty())&&(!myZCoord->text().isEmpty())&&(!mySizeValue->text().isEmpty());
400   bool isDefined = val;
401   if (val)
402     isDefined = ! smpVertexExists(myXCoord->text().toDouble(),myYCoord->text().toDouble(),myZCoord->text().toDouble());
403
404   emit vertexDefined(isDefined);
405   return isDefined;
406 }
407
408 void HEXABLOCKPluginGUI_HypothesisCreator::onVertexBtnClicked()
409 {
410     if (MYDEBUG) MESSAGE("HEXABLOCKPluginGUI_HypothesisCreator::onVertexBtnClicked()");
411     const int row = mySmpModel->rowCount() ;
412     double x = myXCoord->text().toDouble();
413     double y = myYCoord->text().toDouble();
414     double z = myZCoord->text().toDouble();
415     double size = mySizeValue->text().toDouble();
416     
417     if (smpVertexExists(x,y,z)) return;
418     
419 //     double size = 10.0;
420     // ENF_VER_X_COLUMN
421     mySmpModel->setData(mySmpModel->index(row, ENF_VER_X_COLUMN),x);
422     mySmpModel->setItem( row, ENF_VER_X_COLUMN, new QStandardItem(QString::number(x)) );
423     mySmpModel->item( row, ENF_VER_X_COLUMN )->setFlags( Qt::ItemIsSelectable );
424     // ENF_VER_Y_COLUMN
425     mySmpModel->setData(mySmpModel->index(row, ENF_VER_Y_COLUMN),y);
426     mySmpModel->setItem( row, ENF_VER_Y_COLUMN, new QStandardItem(QString::number(y)) );
427     mySmpModel->item( row, ENF_VER_Y_COLUMN )->setFlags( Qt::ItemIsSelectable );
428     // ENF_VER_Z_COLUMN
429     mySmpModel->setData(mySmpModel->index(row, ENF_VER_Z_COLUMN),z);
430     mySmpModel->setItem( row, ENF_VER_Z_COLUMN, new QStandardItem(QString::number(z)) );
431     mySmpModel->item( row, ENF_VER_Z_COLUMN )->setFlags( Qt::ItemIsSelectable );
432     // ENF_VER_SIZE_COLUMN
433     mySmpModel->setData(mySmpModel->index(row, ENF_VER_SIZE_COLUMN),size);
434     mySmpModel->setItem( row, ENF_VER_SIZE_COLUMN, new QStandardItem(QString::number(size,'f')) );
435
436     myEnforcedTableView->clearSelection();
437     myEnforcedTableView->scrollTo( mySmpModel->item( row, ENF_VER_SIZE_COLUMN )->index() );
438     checkVertexIsDefined();
439 }
440
441 void HEXABLOCKPluginGUI_HypothesisCreator::onRemoveVertexBtnClicked()
442 {
443     QList<int> selectedRows;
444     QList<QModelIndex> selectedIndex = myEnforcedTableView->selectionModel()->selectedIndexes();
445     int row;
446     QModelIndex index;
447     foreach( index, selectedIndex ) {
448         row = index.row();
449         if ( !selectedRows.contains( row ) ) 
450         selectedRows.append( row );
451     }
452     qSort( selectedRows );
453     QListIterator<int> it( selectedRows );
454     it.toBack();
455     while ( it.hasPrevious() ) {
456         row = it.previous();
457         if (MYDEBUG) MESSAGE("delete row #"<< row);
458         mySmpModel->removeRow(row );
459     }
460     myEnforcedTableView->clearSelection();
461 }
462 void HEXABLOCKPluginGUI_HypothesisCreator::onDirBtnClicked()
463 {
464   QString dir = SUIT_FileDlg::getExistingDirectory( dlg(), myWorkingDir->text(), QString() );
465   if ( !dir.isEmpty() )
466     myWorkingDir->setText( dir );
467 }
468
469 void HEXABLOCKPluginGUI_HypothesisCreator::updateWidgets()
470 {
471   myMaximumMemorySpin->setEnabled( myMaximumMemoryCheck->isChecked() );
472   myInitialMemoryCheck->setEnabled( !myBoundaryRecoveryCheck->isChecked() );
473   myInitialMemorySpin->setEnabled( myInitialMemoryCheck->isChecked() && !myBoundaryRecoveryCheck->isChecked() );
474   myOptimizationLevelCombo->setEnabled( !myBoundaryRecoveryCheck->isChecked() );
475 }
476
477 bool HEXABLOCKPluginGUI_HypothesisCreator::checkParams(QString& msg) const
478 {
479   if (MYDEBUG) MESSAGE("HEXABLOCKPluginGUI_HypothesisCreator::checkParams");
480
481   if ( !QFileInfo( myWorkingDir->text().trimmed() ).isWritable() ) {
482     SUIT_MessageBox::warning( dlg(),
483                               tr( "SMESH_WRN_WARNING" ),
484                               tr( "HEXABLOCK_PERMISSION_DENIED" ) );
485     return false;
486   }
487
488   return true;
489 }
490
491 void HEXABLOCKPluginGUI_HypothesisCreator::retrieveParams() const
492 {
493   if (MYDEBUG) MESSAGE("HEXABLOCKPluginGUI_HypothesisCreator::retrieveParams");
494   HEXABLOCKHypothesisData data;
495   readParamsFromHypo( data );
496
497   if ( myName )
498     myName->setText( data.myName );
499   
500   myToMeshHolesCheck               ->setChecked    ( data.myToMeshHoles );
501   myOptimizationLevelCombo         ->setCurrentIndex( data.myOptimizationLevel );
502   myMaximumMemoryCheck             ->setChecked    ( data.myMaximumMemory > 0 );
503   myMaximumMemorySpin              ->setValue      ( qMax( data.myMaximumMemory,
504                                                            myMaximumMemorySpin->minimum() ));
505   myInitialMemoryCheck             ->setChecked    ( data.myInitialMemory > 0 );
506   myInitialMemorySpin              ->setValue      ( qMax( data.myInitialMemory,
507                                                            myInitialMemorySpin->minimum() ));
508   myWorkingDir                     ->setText       ( data.myWorkingDir );
509   myKeepFiles                      ->setChecked    ( data.myKeepFiles );
510   myVerboseLevelSpin               ->setValue      ( data.myVerboseLevel );
511   myToCreateNewNodesCheck          ->setChecked    ( data.myToCreateNewNodes );
512   myRemoveInitialCentralPointCheck ->setChecked    ( data.myRemoveInitialCentralPoint );
513   myBoundaryRecoveryCheck          ->setChecked    ( data.myBoundaryRecovery );
514   myFEMCorrectionCheck             ->setChecked    ( data.myFEMCorrection );
515   myTextOption                     ->setText       ( data.myTextOption );
516
517   TEnforcedVertexValues::const_iterator it;
518   int row = 0;
519   for(it = data.myEnforcedVertices.begin() ; it != data.myEnforcedVertices.end(); it++ )
520   {
521     double x = it->at(0);
522     double y = it->at(1);
523     double z = it->at(2);
524     double size = it->at(3);
525     // ENF_VER_X_COLUMN
526     mySmpModel->setData(mySmpModel->index(row, ENF_VER_X_COLUMN),x);
527     mySmpModel->setItem( row, ENF_VER_X_COLUMN, new QStandardItem(QString::number(x)) );
528     mySmpModel->item( row, ENF_VER_X_COLUMN )->setFlags( Qt::ItemIsSelectable );
529     // ENF_VER_Y_COLUMN
530     mySmpModel->setData(mySmpModel->index(row, ENF_VER_Y_COLUMN),y);
531     mySmpModel->setItem( row, ENF_VER_Y_COLUMN, new QStandardItem(QString::number(y)) );
532     mySmpModel->item( row, ENF_VER_Y_COLUMN )->setFlags( Qt::ItemIsSelectable );
533     // ENF_VER_Z_COLUMN
534     mySmpModel->setData(mySmpModel->index(row, ENF_VER_Z_COLUMN),z);
535     mySmpModel->setItem( row, ENF_VER_Z_COLUMN, new QStandardItem(QString::number(z)) );
536     mySmpModel->item( row, ENF_VER_Z_COLUMN )->setFlags( Qt::ItemIsSelectable );
537     // ENF_VER_SIZE_COLUMN
538     mySmpModel->setData(mySmpModel->index(row, ENF_VER_SIZE_COLUMN),size);
539     mySmpModel->setItem( row, ENF_VER_SIZE_COLUMN, new QStandardItem(QString::number(size)) );
540
541     if (MYDEBUG) MESSAGE("Row " << row << ": (" << x << ","<< y << ","<< z << ") ="<< size);
542     row++;
543   }
544   
545   HEXABLOCKPluginGUI_HypothesisCreator* that = (HEXABLOCKPluginGUI_HypothesisCreator*)this;
546   that->updateWidgets();
547 }
548
549 QString HEXABLOCKPluginGUI_HypothesisCreator::storeParams() const
550 {
551     if (MYDEBUG) MESSAGE("HEXABLOCKPluginGUI_HypothesisCreator::storeParams");
552     HEXABLOCKHypothesisData data;
553     readParamsFromWidgets( data );
554     storeParamsToHypo( data );
555     
556     QString valStr = "";
557     
558     if ( !data.myBoundaryRecovery )
559         valStr = "-c " + QString::number( !data.myToMeshHoles );
560     
561     if ( data.myOptimizationLevel >= 0 && data.myOptimizationLevel < 5 && !data.myBoundaryRecovery) {
562         const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" };
563         valStr += " -o ";
564         valStr += level[ data.myOptimizationLevel ];
565     }
566     if ( data.myMaximumMemory > 0 ) {
567         valStr += " -m ";
568         valStr += QString::number( data.myMaximumMemory );
569     }
570     if ( data.myInitialMemory > 0 && !data.myBoundaryRecovery ) {
571         valStr += " -M ";
572         valStr += QString::number( data.myInitialMemory );
573     }
574     valStr += " -v ";
575     valStr += QString::number( data.myVerboseLevel );
576     
577     if ( !data.myToCreateNewNodes )
578         valStr += " -p0";
579     
580     if ( data.myRemoveInitialCentralPoint )
581         valStr += " -no_initial_central_point";
582     
583     if ( data.myBoundaryRecovery )
584         valStr += " -C";
585     
586     if ( data.myFEMCorrection )
587         valStr += " -FEM";
588     
589     valStr += " ";
590     valStr += data.myTextOption;
591     
592     valStr += " #BEGIN ENFORCED VERTICES#";
593     // Add size map parameters storage
594     for (int i=0 ; i<mySmpModel->rowCount() ; i++) {
595         valStr += " (";
596         double x = mySmpModel->data(mySmpModel->index(i,ENF_VER_X_COLUMN)).toDouble();
597         double y = mySmpModel->data(mySmpModel->index(i,ENF_VER_Y_COLUMN)).toDouble();
598         double z = mySmpModel->data(mySmpModel->index(i,ENF_VER_Z_COLUMN)).toDouble();
599         double size = mySmpModel->data(mySmpModel->index(i,ENF_VER_SIZE_COLUMN)).toDouble();
600         valStr += QString::number( x );
601         valStr += ",";
602         valStr += QString::number( y );
603         valStr += ",";
604         valStr += QString::number( z );
605         valStr += ")=";
606         valStr += QString::number( size );
607         if (i!=mySmpModel->rowCount()-1)
608             valStr += ";";
609     }
610     valStr += " #END ENFORCED VERTICES#";
611     if (MYDEBUG) MESSAGE(valStr.toStdString());
612   return valStr;
613 }
614
615 bool HEXABLOCKPluginGUI_HypothesisCreator::readParamsFromHypo( HEXABLOCKHypothesisData& h_data ) const
616 {
617   if (MYDEBUG) MESSAGE("HEXABLOCKPluginGUI_HypothesisCreator::readParamsFromHypo");
618   HEXABLOCKPlugin::HEXABLOCKPlugin_Hypothesis_var h =
619     HEXABLOCKPlugin::HEXABLOCKPlugin_Hypothesis::_narrow( initParamsHypothesis() );
620
621   HypothesisData* data = SMESH::GetHypothesisData( hypType() );
622   h_data.myName = isCreation() && data ? hypName() : "";
623
624   /* fkl to update:
625   h_data.myToMeshHoles                = h->GetToMeshHoles();
626   h_data.myMaximumMemory              = h->GetMaximumMemory();
627   h_data.myInitialMemory              = h->GetInitialMemory();
628   h_data.myInitialMemory              = h->GetInitialMemory();
629   h_data.myOptimizationLevel          = h->GetOptimizationLevel();
630   h_data.myKeepFiles                  = h->GetKeepFiles();
631   h_data.myWorkingDir                 = h->GetWorkingDirectory();
632   h_data.myVerboseLevel               = h->GetVerboseLevel();
633   h_data.myToCreateNewNodes           = h->GetToCreateNewNodes();
634   h_data.myRemoveInitialCentralPoint  = h->GetToRemoveCentralPoint();
635   h_data.myBoundaryRecovery           = h->GetToUseBoundaryRecoveryVersion();
636   h_data.myFEMCorrection              = h->GetFEMCorrection();
637   h_data.myTextOption                 = h->GetTextOption();
638
639   HEXABLOCKPlugin::HEXABLOCKEnforcedVertexList_var vertices = h->GetEnforcedVertices();
640   MESSAGE("vertices->length(): " << vertices->length());
641   h_data.myEnforcedVertices.clear();
642   for (int i=0 ; i<vertices->length() ; i++) {
643     HEXABLOCKEnforcedVertex myVertex;
644     myVertex.push_back(vertices[i].x);
645     myVertex.push_back(vertices[i].y);
646     myVertex.push_back(vertices[i].z);
647     myVertex.push_back(vertices[i].size);
648     MESSAGE("Add enforced vertex ("<< myVertex[0] << ","<< myVertex[1] << ","<< myVertex[2] << ") ="<< myVertex[3]);
649     h_data.myEnforcedVertices.push_back(myVertex);
650   }
651   */
652
653   return true;
654 }
655
656 bool HEXABLOCKPluginGUI_HypothesisCreator::storeParamsToHypo( const HEXABLOCKHypothesisData& h_data ) const
657 {
658   if (MYDEBUG) MESSAGE("HEXABLOCKPluginGUI_HypothesisCreator::storeParamsToHypo");
659   HEXABLOCKPlugin::HEXABLOCKPlugin_Hypothesis_var h =
660     HEXABLOCKPlugin::HEXABLOCKPlugin_Hypothesis::_narrow( hypothesis() );
661
662   bool ok = true;
663   try
664   {
665     if( isCreation() )
666       SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().constData() );
667
668     /* fkl to update:
669     if ( h->GetToMeshHoles() != h_data.myToMeshHoles ) // avoid duplication of DumpPython commands
670       h->SetToMeshHoles      ( h_data.myToMeshHoles       );
671     if ( h->GetMaximumMemory() != h_data.myMaximumMemory )
672       h->SetMaximumMemory    ( h_data.myMaximumMemory     );
673     if ( h->GetInitialMemory() != h_data.myInitialMemory )
674       h->SetInitialMemory    ( h_data.myInitialMemory     );
675     if ( h->GetInitialMemory() != h_data.myInitialMemory )
676       h->SetInitialMemory    ( h_data.myInitialMemory     );
677     if ( h->GetOptimizationLevel() != h_data.myOptimizationLevel )
678       h->SetOptimizationLevel( h_data.myOptimizationLevel );
679     if ( h->GetKeepFiles() != h_data.myKeepFiles )
680       h->SetKeepFiles        ( h_data.myKeepFiles         );
681     if ( h->GetWorkingDirectory() != h_data.myWorkingDir )
682       h->SetWorkingDirectory ( h_data.myWorkingDir.toLatin1().constData() );
683     if ( h->GetVerboseLevel() != h_data.myVerboseLevel )
684       h->SetVerboseLevel     ( h_data.myVerboseLevel );
685     if ( h->GetToCreateNewNodes() != h_data.myToCreateNewNodes )
686       h->SetToCreateNewNodes( h_data.myToCreateNewNodes );
687     if ( h->GetToRemoveCentralPoint() != h_data.myRemoveInitialCentralPoint )
688       h->SetToRemoveCentralPoint( h_data.myRemoveInitialCentralPoint );
689     if ( h->GetToUseBoundaryRecoveryVersion() != h_data.myBoundaryRecovery )
690       h->SetToUseBoundaryRecoveryVersion( h_data.myBoundaryRecovery );
691     if ( h->GetFEMCorrection() != h_data.myFEMCorrection )
692       h->SetFEMCorrection( h_data.myFEMCorrection );
693     if ( h->GetTextOption() != h_data.myTextOption )
694       h->SetTextOption       ( h_data.myTextOption.toLatin1().constData() );
695     
696     int nbVertex = (int) h_data.myEnforcedVertices.size();
697     HEXABLOCKPlugin::HEXABLOCKEnforcedVertexList_var vertexHyp = h->GetEnforcedVertices();
698     int nbVertexHyp = vertexHyp->length();
699     
700     MESSAGE("Store params for size maps: " << nbVertex << " enforced vertices");
701     MESSAGE("h->GetEnforcedVertices()->length(): " << nbVertexHyp);
702     
703     // Some vertices were removed
704     if (nbVertex < nbVertexHyp) {
705 //        if (nbVertex == 0)
706 //            h->ClearEnforcedVertices();
707 //        else {
708             // iterate over vertices of hypo
709             for(int i = 0 ; i <nbVertexHyp ; i++) {
710                 double x = vertexHyp[i].x;
711                 double y = vertexHyp[i].y;
712                 double z = vertexHyp[i].z;
713                 // vertex is removed
714                 if (!smpVertexExists(x,y,z))
715                     h->RemoveEnforcedVertex(x,y,z);
716             }
717 //        }
718     }
719     
720     TEnforcedVertexValues::const_iterator it;
721     for(it = h_data.myEnforcedVertices.begin() ; it != h_data.myEnforcedVertices.end(); it++ ) {
722       double x = it->at(0);
723       double y = it->at(1);
724       double z = it->at(2);
725       double size = it->at(3);
726       MESSAGE("(" << x   << ", "
727                        << y   << ", "
728                        << z   << ") = "
729                        << size  );
730       double mySize;
731       try {
732         mySize = h->GetEnforcedVertex(x,y,z);
733         MESSAGE("Old size: " << mySize);
734         if (mySize != size) {
735           MESSAGE("Setting new size: " << size);
736           h->SetEnforcedVertex(x,y,z,size);
737         }
738       }
739       catch (...) {
740         MESSAGE("Setting new size: " << size);
741         h->SetEnforcedVertex(x,y,z,size);
742       }
743     }
744     */
745   }
746   catch ( const SALOME::SALOME_Exception& ex )
747   {
748     SalomeApp_Tools::QtCatchCorbaException( ex );
749     ok = false;
750   }
751   return ok;
752 }
753
754 bool HEXABLOCKPluginGUI_HypothesisCreator::readParamsFromWidgets( HEXABLOCKHypothesisData& h_data ) const
755 {
756   if (MYDEBUG) MESSAGE("HEXABLOCKPluginGUI_HypothesisCreator::readParamsFromWidgets");
757   h_data.myName                       = myName ? myName->text() : "";
758   h_data.myToMeshHoles                = myToMeshHolesCheck->isChecked();
759   h_data.myMaximumMemory              = myMaximumMemoryCheck->isChecked() ? myMaximumMemorySpin->value() : -1;
760   h_data.myInitialMemory              = myInitialMemoryCheck->isChecked() ? myInitialMemorySpin->value() : -1;
761   h_data.myOptimizationLevel          = myOptimizationLevelCombo->currentIndex();
762   h_data.myKeepFiles                  = myKeepFiles->isChecked();
763   h_data.myWorkingDir                 = myWorkingDir->text().trimmed();
764   h_data.myVerboseLevel               = myVerboseLevelSpin->value();
765   h_data.myToCreateNewNodes           = myToCreateNewNodesCheck->isChecked();
766   h_data.myRemoveInitialCentralPoint  = myRemoveInitialCentralPointCheck->isChecked();
767   h_data.myBoundaryRecovery           = myBoundaryRecoveryCheck->isChecked();
768   h_data.myFEMCorrection              = myFEMCorrectionCheck->isChecked();
769   h_data.myTextOption                 = myTextOption->text();
770   h_data.myEnforcedVertices.clear();
771
772   for (int i=0 ; i<mySmpModel->rowCount() ; i++) {
773     HEXABLOCKEnforcedVertex myVertex;
774     myVertex.push_back(mySmpModel->data(mySmpModel->index(i,ENF_VER_X_COLUMN)).toDouble());
775     myVertex.push_back(mySmpModel->data(mySmpModel->index(i,ENF_VER_Y_COLUMN)).toDouble());
776     myVertex.push_back(mySmpModel->data(mySmpModel->index(i,ENF_VER_Z_COLUMN)).toDouble());
777     myVertex.push_back(mySmpModel->data(mySmpModel->index(i,ENF_VER_SIZE_COLUMN)).toDouble());
778     if (MYDEBUG) MESSAGE("Add new enforced vertex (" << myVertex[0] << ", "
779                                              << myVertex[1] << ", "
780                                              << myVertex[2] << ") = "
781                                              << myVertex[3]);
782     h_data.myEnforcedVertices.push_back(myVertex);
783   }
784
785   return true;
786 }
787
788 QString HEXABLOCKPluginGUI_HypothesisCreator::caption() const
789 {
790   return tr( "HEXABLOCK_TITLE" );
791 }
792
793 QPixmap HEXABLOCKPluginGUI_HypothesisCreator::icon() const
794 {
795   return SUIT_Session::session()->resourceMgr()->loadPixmap( "HEXABLOCKPlugin", tr( "ICON_DLG_HEXABLOCK_PARAMETERS" ) );
796 }
797
798 QString HEXABLOCKPluginGUI_HypothesisCreator::type() const
799 {
800   return tr( "HEXABLOCK_HYPOTHESIS" );
801 }
802
803 QString HEXABLOCKPluginGUI_HypothesisCreator::helpPage() const
804 {
805   return "HEXABLOCK_hypo_page.html";
806 }
807
808 //=============================================================================
809 /*! GetHypothesisCreator
810  *
811  */
812 //=============================================================================
813 extern "C"
814 {
815   HEXABLOCKPLUGINGUI_EXPORT
816   SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator( const QString& aHypType )
817   {
818     if ( aHypType == "HEXABLOCK_Parameters" )
819       return new HEXABLOCKPluginGUI_HypothesisCreator( aHypType );
820     return 0;
821   }
822 }