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