Salome HOME
Netgen parametrization
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_NbSegmentsCreator.cxx
1 // Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
3 //
4 // This library is free software; you can redistribute it and/or 
5 // modify it under the terms of the GNU Lesser General Public 
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License. 
8 //
9 // This library is distributed in the hope that it will be useful, 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details. 
13 //
14 // You should have received a copy of the GNU Lesser General Public 
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 // File   : StdMeshersGUI_NbSegmentsCreator.cxx
21 // Author : Open CASCADE S.A.S.
22 //
23
24 // SMESH includes
25 #include "StdMeshersGUI_NbSegmentsCreator.h"
26 #include "StdMeshersGUI_DistrTable.h"
27 #include "StdMeshersGUI_DistrPreview.h"
28
29 #include <SMESHGUI.h>
30 #include <SMESHGUI_Utils.h>
31 #include <SMESHGUI_HypothesesUtils.h>
32 #include <SMESHGUI_SpinBox.h>
33
34 // IDL includes
35 #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
36
37 // SALOME GUI includes
38 #include <SalomeApp_Tools.h>
39 #include <SalomeApp_IntSpinBox.h>
40 #include <QtxComboBox.h>
41
42 // Qt includes
43 #include <QLabel>
44 #include <QGroupBox>
45 #include <QFrame>
46 #include <QLineEdit>
47 #include <QButtonGroup>
48 #include <QRadioButton>
49 #include <QGridLayout>
50 #include <QVBoxLayout>
51 #include <QHBoxLayout>
52 #include <QApplication>
53
54 #define SPACING 6
55 #define MARGIN  11
56
57 StdMeshersGUI_NbSegmentsCreator::StdMeshersGUI_NbSegmentsCreator()
58 : StdMeshersGUI_StdHypothesisCreator( "NumberOfSegments" ),
59   myNbSeg( 0 ),
60   myDistr( 0 ),
61   myScale( 0 ),
62   myTable( 0 ),
63   myPreview( 0 ),
64   myExpr( 0 ),
65   myConvBox( 0 ),
66   myConv( 0 ),
67   myLScale( 0 ),
68   myLTable( 0 ),
69   myLExpr( 0 ),
70   myInfo( 0 ),
71   myGroupLayout( 0 ),
72   myTableRow( 0 ),
73   myPreviewRow( 0 )
74 {
75 }
76
77 StdMeshersGUI_NbSegmentsCreator::~StdMeshersGUI_NbSegmentsCreator()
78 {
79 }
80
81 bool StdMeshersGUI_NbSegmentsCreator::checkParams( QString& msg ) const
82 {
83   if( !SMESHGUI_GenericHypothesisCreator::checkParams( msg ) )
84     return false;
85   NbSegmentsHypothesisData data_old, data_new;
86   readParamsFromHypo( data_old );
87   readParamsFromWidgets( data_new );
88   bool res = storeParamsToHypo( data_new );
89   storeParamsToHypo( data_old );
90   res = myNbSeg->isValid( msg, true ) && res;
91   res = myScale->isValid( msg, true ) && res;
92   return res;
93 }
94
95 QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
96 {
97   QFrame* fr = new QFrame();
98
99   QVBoxLayout* lay = new QVBoxLayout( fr );
100   lay->setMargin( 0 );
101   lay->setSpacing( 0 );
102
103   QGroupBox* GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), fr );
104   lay->addWidget( GroupC1 );
105
106   StdMeshers::StdMeshers_NumberOfSegments_var h =
107     StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
108   myPreview = new StdMeshersGUI_DistrPreview( GroupC1, h.in() );
109
110   myGroupLayout = new QGridLayout( GroupC1 );
111   myGroupLayout->setSpacing( SPACING );
112   myGroupLayout->setMargin( MARGIN );
113   myGroupLayout->setColumnStretch( 0, 0 );
114   myGroupLayout->setColumnStretch( 1, 1 );
115
116   int row = 0;
117   // 0)  name
118   myName = 0;
119   if( isCreation() )
120   {
121     myName = new QLineEdit( GroupC1 );
122     myGroupLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), GroupC1 ), row, 0 );
123     myGroupLayout->addWidget( myName, row, 1 );
124     row++;
125   }
126
127   // 1)  number of segments
128   myGroupLayout->addWidget( new QLabel( tr( "SMESH_NB_SEGMENTS_PARAM" ), GroupC1 ), row, 0 );
129   myNbSeg = new SalomeApp_IntSpinBox( GroupC1 );
130   myNbSeg->setMinimum( 1 );
131   myNbSeg->setMaximum( 9999 );
132   myGroupLayout->addWidget( myNbSeg, row, 1 );
133   row++;
134
135   // 2)  type of distribution
136   myGroupLayout->addWidget( new QLabel( tr( "SMESH_DISTR_TYPE" ), GroupC1 ), row, 0 );
137   myDistr = new QtxComboBox( GroupC1 );
138   QStringList types;
139   types.append( tr( "SMESH_DISTR_REGULAR" ) );
140   types.append( tr( "SMESH_DISTR_SCALE"   ) );
141   types.append( tr( "SMESH_DISTR_TAB"     ) );
142   types.append( tr( "SMESH_DISTR_EXPR"    ) );
143   myDistr->addItems( types );
144   myGroupLayout->addWidget( myDistr, row, 1 );
145   row++;
146
147   // 3)  scale
148   myGroupLayout->addWidget( myLScale = new QLabel( tr( "SMESH_NB_SEGMENTS_SCALE_PARAM" ), GroupC1 ), row, 0 );
149   myScale = new SMESHGUI_SpinBox( GroupC1 );
150   myScale->RangeStepAndValidator( 1E-5, 1E+5, 0.1, 6 );
151   myGroupLayout->addWidget( myScale, row, 1 );
152   row++;
153
154   myInfo = new QLabel( tr( "SMESH_FUNC_DOMAIN" ), GroupC1 );
155   myGroupLayout->addWidget( myInfo, row, 0, 1, 2 );
156   row++;
157   
158   // 4)  table
159   myGroupLayout->addWidget( myLTable = new QLabel( tr( "SMESH_TAB_FUNC" ), GroupC1 ), row, 0 );
160   myTable = new StdMeshersGUI_DistrTableFrame( GroupC1 );
161   myGroupLayout->addWidget( myTable, row, 1 );
162   myGroupLayout->setRowStretch( row, 1 );
163   myTableRow = row;
164   row++;
165
166   // 5)  expression
167   myGroupLayout->addWidget( myLExpr = new QLabel( tr( "SMESH_EXPR_FUNC" ), GroupC1 ), row, 0 );
168   myExpr = new QLineEdit( GroupC1 );
169   myGroupLayout->addWidget( myExpr, row, 1 );
170   row++;
171
172   // 6)  conversion (radiogroup)
173   myConvBox = new QGroupBox( tr( "SMESH_CONV_MODE" ), GroupC1 );
174   myConv = new QButtonGroup( GroupC1 );
175
176   QHBoxLayout* convLay = new QHBoxLayout( myConvBox );
177   convLay->setMargin( MARGIN );
178   convLay->setSpacing( SPACING );
179
180   QRadioButton* rbExp = new QRadioButton( tr( "SMESH_EXP_MODE" ), myConvBox );
181   QRadioButton* myCutNeg = new QRadioButton( tr( "SMESH_CUT_NEG_MODE" ), myConvBox );
182
183   convLay->addWidget( rbExp );
184   convLay->addWidget( myCutNeg );
185   myConv->addButton( rbExp, 0 );
186   myConv->addButton( myCutNeg, 1 );
187
188   myGroupLayout->addWidget( myConvBox, row, 0, 1, 2 );
189   row++;
190
191   // 7) distribution preview
192   myGroupLayout->addWidget( myPreview, row, 0, 1, 2 );
193   myGroupLayout->setRowStretch( row, 1 );
194   myPreviewRow = row;
195   row++;
196
197   connect( myNbSeg, SIGNAL( valueChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
198   connect( myDistr, SIGNAL( activated( int ) ), this, SLOT( onValueChanged() ) );
199   connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SLOT( onValueChanged() ) );
200   connect( myExpr,  SIGNAL( textChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
201   connect( myConv,  SIGNAL( cuttonClicked( int ) ), this, SLOT( onValueChanged() ) );
202
203   return fr;
204 }
205
206 void StdMeshersGUI_NbSegmentsCreator::retrieveParams() const
207 {
208   NbSegmentsHypothesisData data;
209   readParamsFromHypo( data );
210
211   if( myName )
212     myName->setText( data.myName );
213   if(data.myNbSegVarName.isEmpty())
214     myNbSeg->setValue( data.myNbSeg );
215   else
216     myNbSeg->setText( data.myNbSegVarName );
217   
218   myDistr->setCurrentIndex( data.myDistrType );
219   if(data.myScaleVarName.isEmpty())
220     myScale->setValue( data.myScale );
221   else
222     myScale->setText( data.myScaleVarName );
223   myConv->button( data.myConv )->setChecked( true );
224   myTable->setFuncMinValue(myConv->checkedId()==0 ? -1E20 : 0);
225   myTable->setData( data.myTable );
226   myExpr->setText( data.myExpr );
227
228   if ( dlg() )
229     dlg()->setMinimumSize( dlg()->minimumSizeHint().width(), dlg()->minimumSizeHint().height() );
230 }
231
232 QString StdMeshersGUI_NbSegmentsCreator::storeParams() const
233 {
234   NbSegmentsHypothesisData data;
235   readParamsFromWidgets( data );
236   storeParamsToHypo( data );
237     
238   QString valStr = QString::number( data.myNbSeg ) += "; ";
239
240   enum DistrType
241   {
242     Regular, //!< equidistant distribution
243     Scale,   //!< scale distribution
244     TabFunc, //!< distribution with density function presented by table
245     ExprFunc //!< distribution with density function presented by expression
246   };
247   bool hasConv = false;
248   switch ( data.myDistrType ) {
249   case Regular :
250     valStr += tr("SMESH_DISTR_REGULAR");
251     break;
252   case Scale   : 
253     valStr += tr("SMESH_NB_SEGMENTS_SCALE_PARAM") + " = " + QString::number( data.myScale );\
254     break;
255   case TabFunc : {
256     //valStr += tr("SMESH_TAB_FUNC");
257     bool param = true;
258     for( int i=0; i < data.myTable.length(); i++, param = !param ) {
259       if ( param )
260         valStr += "[";
261       valStr += QString::number( data.myTable[ i ]);
262       valStr += ( param ? "," : "]" );
263     }
264     hasConv = true;
265     break;
266   }
267   case ExprFunc:
268     valStr += data.myExpr;
269     hasConv = true;
270     break;
271   }
272   if ( hasConv )
273     if ( data.myConv )
274       valStr += "; " + tr("SMESH_CUT_NEG_MODE");
275     else
276       valStr += "; " + tr("SMESH_EXP_MODE");
277
278   return valStr;
279 }
280
281 bool StdMeshersGUI_NbSegmentsCreator::readParamsFromHypo( NbSegmentsHypothesisData& h_data ) const
282 {
283   StdMeshers::StdMeshers_NumberOfSegments_var h =
284     StdMeshers::StdMeshers_NumberOfSegments::_narrow( initParamsHypothesis() );
285
286   h_data.myName = hypName();
287
288   h_data.myNbSeg = (int) h->GetNumberOfSegments();
289   
290   SMESH::ListOfParameters_var aParameters = h->GetLastParameters();
291
292   h_data.myNbSegVarName  = (aParameters->length() > 0) ? QString(aParameters[0].in()) : QString("");
293
294   int distr = (int) h->GetDistrType();
295   h_data.myDistrType = distr;
296   h_data.myScale = distr==1 ? h->GetScaleFactor() : 1.0;
297   
298   if(distr==1){
299     h_data.myScaleVarName  = (aParameters->length() > 1) ? QString(aParameters[1].in()) : QString("");
300   }
301   else 
302     h_data.myScaleVarName = QString("");
303
304   if( distr==2 )
305   {
306     SMESH::double_array* a = h->GetTableFunction();
307     h_data.myTable = *a;
308     delete a;
309   }
310   else
311   {
312     SMESH::double_array& a = h_data.myTable;
313     // by default, constant table function f(t)=1
314     a.length( 4 );
315     a[0] = 0.0; a[1] = 1.0;
316     a[2] = 1.0; a[3] = 1.0; 
317   }
318
319   h_data.myExpr = distr==3 ? h->GetExpressionFunction() : "1";
320   h_data.myConv = distr==2 || distr==3 ? h->ConversionMode() : 1; /*cut negative by default*/
321
322   return true;
323 }
324
325 bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothesisData& h_data ) const
326 {
327   StdMeshers::StdMeshers_NumberOfSegments_var h =
328     StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
329
330   bool ok = true;
331   try
332   {
333     if( isCreation() )
334       SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().data() );
335
336     QStringList aVariablesList;
337     aVariablesList.append(h_data.myNbSegVarName);
338
339     h->SetNumberOfSegments( h_data.myNbSeg );
340     int distr = h_data.myDistrType;
341     h->SetDistrType( distr );
342     
343     if( distr==1 ) {
344       h->SetScaleFactor( h_data.myScale );
345       aVariablesList.append(h_data.myScaleVarName);
346     }
347     if( distr==2 || distr==3 )
348       h->SetConversionMode( h_data.myConv );
349
350     if( distr==2 )
351       h->SetTableFunction( h_data.myTable );
352
353     if( distr==3 )
354       h->SetExpressionFunction( h_data.myExpr.toLatin1().data() );
355     //setting of function must follow after setConversionMode, because otherwise
356     //the function will be checked with old conversion mode, so that it may occurs
357     //unexpected errors for user
358
359     h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
360   }
361   catch(const SALOME::SALOME_Exception& ex)
362   {
363     SalomeApp_Tools::QtCatchCorbaException(ex);
364     ok = false;
365   }
366   return ok;
367 }
368
369 bool StdMeshersGUI_NbSegmentsCreator::readParamsFromWidgets( NbSegmentsHypothesisData& h_data ) const
370 {
371   h_data.myName      = myName ? myName->text() : "";
372   h_data.myNbSeg     = myNbSeg->value();
373   h_data.myNbSegVarName =  myNbSeg->text();
374   h_data.myScaleVarName =  myScale->text();
375   h_data.myDistrType = myDistr->currentIndex();
376   h_data.myConv      = myConv->checkedId();
377   h_data.myScale     = myScale->value();
378   myTable->data( h_data.myTable );
379   h_data.myExpr      = myExpr->text();
380   return true;
381 }
382
383 void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
384 {
385   int distr = myDistr->currentIndex();
386
387 /*  if( distr==2 ) //table func
388     myCutNeg->setText( tr( "SMESH_NO_CONV" ) );
389   else if( distr==3 )
390     myCutNeg->setText( tr( "SMESH_CUT_NEG_MODE" ) );*/
391
392   if( distr==2 && sender()==myConv ) //table func
393   {
394     myTable->setFuncMinValue( myConv->checkedId()==0 ? -1E20 : 0 );
395     SMESH::double_array arr;
396     myTable->data( arr );
397     myTable->setData( arr ); //update data in table
398   }
399
400   myScale->setShown( distr==1 );
401   myLScale->setShown( distr==1 );
402
403   bool isFunc = distr==2 || distr==3;
404   myPreview->setShown( isFunc );
405   myGroupLayout->setRowStretch( myPreviewRow, isFunc ? 1 : 0 );
406
407   myConvBox->setShown( isFunc );
408
409   if( distr==2 )
410     myTable->show();
411   else
412     myTable->hide();
413   myLTable->setShown( distr==2 );
414   myGroupLayout->setRowStretch( myTableRow, distr==2 ? 1 : 0 );
415
416   myExpr->setShown( distr==3 );
417   myLExpr->setShown( distr==3 );
418   myInfo->setShown( isFunc );
419
420   //change of preview
421   int nbSeg = myNbSeg->value();
422   if( distr==2 ) //preview for table-described function
423   {
424     SMESH::double_array a;
425     myTable->data( a );
426     myPreview->setParams( a, nbSeg, false );
427   }
428   else if( distr==3 ) //preview for analytic-described function
429     myPreview->setParams( myExpr->text(), nbSeg, 100, false );
430
431   if( isFunc )
432     myPreview->setConversion( StdMeshersGUI_DistrPreview::Conversion( myConv->checkedId() ) );
433
434   if ( (QtxComboBox*)sender() == myDistr && dlg() ) {
435     QApplication::instance()->processEvents();
436     dlg()->updateGeometry();
437     dlg()->setMinimumSize( dlg()->minimumSizeHint().width(), dlg()->minimumSizeHint().height() );
438     dlg()->resize( dlg()->minimumSize() );
439   }
440 }