Salome HOME
0020206: EDF SMESH 987: Netgen1D2D3D +submesh
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_NbSegmentsCreator.cxx
1 //  Copyright (C) 2007-2008  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.
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 #include "StdMeshersGUI_NbSegmentsCreator.h"
23 #include "StdMeshersGUI_DistrTable.h"
24 #include "StdMeshersGUI_DistrPreview.h"
25
26 #include <SMESHGUI_Utils.h>
27 #include <SMESHGUI_HypothesesUtils.h>
28
29 #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
30
31 #include <SalomeApp_Tools.h>
32
33 #include <QtxIntSpinBox.h>
34 #include <QtxComboBox.h>
35 #include <QtxDblValidator.h>
36 #include <SMESHGUI_SpinBox.h>
37
38 #include <qlabel.h>
39 #include <qgroupbox.h>
40 #include <qframe.h>
41 #include <qlayout.h>
42 #include <qlineedit.h>
43 #include <qbuttongroup.h>
44 #include <qradiobutton.h>
45
46 StdMeshersGUI_NbSegmentsCreator::StdMeshersGUI_NbSegmentsCreator()
47 : StdMeshersGUI_StdHypothesisCreator( "NumberOfSegments" ),
48   myNbSeg( 0 ),
49   myDistr( 0 ),
50   myScale( 0 ),
51   myTable( 0 ),
52   myPreview( 0 ),
53   myExpr( 0 ),
54   myConv( 0 ),
55   myLScale( 0 ),
56   myLTable( 0 ),
57   myLExpr( 0 ),
58   myLConv( 0 ),
59   myInfo( 0 ),
60   myGroupLayout( 0 ),
61   myTableRow( 0 ),
62   myPreviewRow( 0 )
63 {
64 }
65
66 StdMeshersGUI_NbSegmentsCreator::~StdMeshersGUI_NbSegmentsCreator()
67 {
68 }
69
70 bool StdMeshersGUI_NbSegmentsCreator::checkParams() const
71 {
72   NbSegmentsHypothesisData data_old, data_new;
73   readParamsFromHypo( data_old );
74   readParamsFromWidgets( data_new );
75   bool res = storeParamsToHypo( data_new );
76   storeParamsToHypo( data_old );
77   return res;
78 }
79
80 QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
81 {
82   QFrame* fr = new QFrame( 0, "myframe" );
83   QVBoxLayout* lay = new QVBoxLayout( fr, 5, 0 );
84
85   QGroupBox* GroupC1 = new QGroupBox( fr, "GroupC1" );
86   lay->addWidget( GroupC1 );
87
88   StdMeshers::StdMeshers_NumberOfSegments_var h =
89     StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
90   myPreview = new StdMeshersGUI_DistrPreview( GroupC1, h.in() );
91
92   GroupC1->setTitle( tr( "SMESH_ARGUMENTS"  ) );
93   GroupC1->setColumnLayout(0, Qt::Vertical );
94   GroupC1->layout()->setSpacing( 0 );
95   GroupC1->layout()->setMargin( 0 );
96   myGroupLayout = new QGridLayout( GroupC1->layout() );
97   myGroupLayout->setAlignment( Qt::AlignTop );
98   myGroupLayout->setSpacing( 6 );
99   myGroupLayout->setMargin( 11 );
100   myGroupLayout->setColStretch( 0, 0 );
101   myGroupLayout->setColStretch( 1, 1 );
102
103   int row = 0;
104   // 0)  name
105   myName = 0;
106   if( isCreation() )
107   {
108     myName = new QLineEdit( GroupC1 );
109     myGroupLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), GroupC1 ), row, 0 );
110     myGroupLayout->addWidget( myName, row, 1 );
111     row++;
112   }
113
114   // 1)  number of segments
115   myGroupLayout->addWidget( new QLabel( tr( "SMESH_NB_SEGMENTS_PARAM" ), GroupC1 ), row, 0 );
116   myNbSeg = new QtxIntSpinBox( GroupC1 );
117   myNbSeg->setMinValue( 1 );
118   myNbSeg->setMaxValue( 9999 );
119   myGroupLayout->addWidget( myNbSeg, row, 1 );
120   row++;
121
122   // 2)  type of distribution
123   myGroupLayout->addWidget( new QLabel( tr( "SMESH_DISTR_TYPE" ), GroupC1 ), row, 0 );
124   myDistr = new QtxComboBox( GroupC1 );
125   QStringList types;
126   types.append( QObject::tr( "SMESH_DISTR_REGULAR" ) );
127   types.append( QObject::tr( "SMESH_DISTR_SCALE"   ) );
128   types.append( QObject::tr( "SMESH_DISTR_TAB"     ) );
129   types.append( QObject::tr( "SMESH_DISTR_EXPR"    ) );
130   myDistr->insertStringList( types );
131   myGroupLayout->addWidget( myDistr, row, 1 );
132   row++;
133
134   // 3)  scale
135   myGroupLayout->addWidget( myLScale = new QLabel( tr( "SMESH_NB_SEGMENTS_SCALE_PARAM" ), GroupC1 ), row, 0 );
136   myScale = new SMESHGUI_SpinBox( GroupC1 );
137   myScale->RangeStepAndValidator( 1E-5, 1E+5, 0.1, 6 );
138   myGroupLayout->addWidget( myScale, row, 1 );
139   row++;
140
141   myInfo = new QLabel( tr( "SMESH_FUNC_DOMAIN" ), GroupC1 );
142   myGroupLayout->addMultiCellWidget( myInfo, row, row, 0, 1 );
143   row++;
144   
145   // 4)  table
146   myGroupLayout->addWidget( myLTable = new QLabel( tr( "SMESH_TAB_FUNC" ), GroupC1 ), row, 0 );
147   myTable = new StdMeshersGUI_DistrTableFrame( GroupC1 );
148   myGroupLayout->addWidget( myTable, row, 1 );
149   myGroupLayout->setRowStretch( row, 1 );
150   myTableRow = row;
151   row++;
152
153   // 5)  expression
154   myGroupLayout->addWidget( myLExpr = new QLabel( tr( "SMESH_EXPR_FUNC" ), GroupC1 ), row, 0 );
155   myExpr = new QLineEdit( GroupC1 );
156   myGroupLayout->addWidget( myExpr, row, 1 );
157   row++;
158
159   // 6)  conversion (radiogroup)
160   myGroupLayout->addWidget( myLConv = new QLabel( tr( "SMESH_CONV_MODE" ), GroupC1 ), row, 0 );
161   myConv = new QButtonGroup( GroupC1 );
162   myConv->setExclusive( true );
163   myConv->setColumnLayout( 0, Qt::Vertical );
164   QGridLayout* convLay = new QGridLayout( myConv->layout() );
165   convLay->addWidget( new QRadioButton( tr( "SMESH_EXP_MODE" ), myConv ), 0, 0 );
166   convLay->addWidget( myCutNeg = new QRadioButton( tr( "SMESH_CUT_NEG_MODE" ), myConv ), 1, 0 );
167   myGroupLayout->addWidget( myConv, row, 1 );
168   row++;
169
170   // 7) distribution preview
171   myGroupLayout->addMultiCellWidget( myPreview, row, row, 0, 1 );
172   myGroupLayout->setRowStretch( row, 1 );
173   myPreviewRow = row;
174   row++;
175
176   connect( myNbSeg, SIGNAL( valueChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
177   connect( myDistr, SIGNAL( activated( int ) ), this, SLOT( onValueChanged() ) );
178   connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SLOT( onValueChanged() ) );
179   connect( myExpr,  SIGNAL( textChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
180   connect( myConv,  SIGNAL( clicked( int ) ), this, SLOT( onValueChanged() ) );
181
182   return fr;
183 }
184
185 void StdMeshersGUI_NbSegmentsCreator::retrieveParams() const
186 {
187   NbSegmentsHypothesisData data;
188   readParamsFromHypo( data );
189
190   if( myName )
191     myName->setText( data.myName );
192   myNbSeg->setValue( data.myNbSeg );
193   myDistr->setCurrentItem( data.myDistrType );
194   myScale->setValue( data.myScale );
195   myConv->setButton( data.myConv );
196   myTable->table()->funcValidator()->setBottom(myConv->id( myConv->selected() )==0 ? -1E20 : 0);
197   myTable->table()->setData( data.myTable );
198   myExpr->setText( data.myExpr );
199 }
200
201 QString StdMeshersGUI_NbSegmentsCreator::storeParams() const
202 {
203   NbSegmentsHypothesisData data;
204   readParamsFromWidgets( data );
205   storeParamsToHypo( data );
206
207   QString valStr = QString::number( data.myNbSeg ) += "; ";
208
209   enum DistrType
210   {
211     Regular, //!< equidistant distribution
212     Scale,   //!< scale distribution
213     TabFunc, //!< distribution with density function presented by table
214     ExprFunc //!< distribution with density function presented by expression
215   };
216   bool hasConv = false;
217   switch ( data.myDistrType ) {
218   case Regular :
219     valStr += tr("SMESH_DISTR_REGULAR");
220     break;
221   case Scale   :
222     valStr += tr("SMESH_NB_SEGMENTS_SCALE_PARAM") + " = " + QString::number( data.myScale );
223     break;
224   case TabFunc : {
225     //valStr += tr("SMESH_TAB_FUNC");
226     bool param = true;
227     for( int i=0; i < data.myTable.length(); i++, param = !param ) {
228       if ( param )
229         valStr += "[";
230       valStr += QString::number( data.myTable[ i ]);
231       valStr += ( param ? "," : "]" );
232     }
233     hasConv = true;
234     break;
235   }
236   case ExprFunc:
237     valStr += data.myExpr;
238     hasConv = true;
239     break;
240   }
241   if ( hasConv )
242     if ( data.myConv )
243       valStr += "; " + tr("SMESH_CUT_NEG_MODE");
244     else
245       valStr += "; " + tr("SMESH_EXP_MODE");
246
247   return valStr;
248 }
249
250 bool StdMeshersGUI_NbSegmentsCreator::readParamsFromHypo( NbSegmentsHypothesisData& h_data ) const
251 {
252   StdMeshers::StdMeshers_NumberOfSegments_var h =
253     StdMeshers::StdMeshers_NumberOfSegments::_narrow( initParamsHypothesis() );
254
255   h_data.myName = hypName();
256
257   h_data.myNbSeg = (int) h->GetNumberOfSegments();
258   int distr = (int) h->GetDistrType();
259   h_data.myDistrType = distr;
260   h_data.myScale = distr==1 ? h->GetScaleFactor() : 1.0;
261   if( distr==2 )
262   {
263     SMESH::double_array* a = h->GetTableFunction();
264     h_data.myTable = *a;
265     delete a;
266   }
267   else
268   {
269     SMESH::double_array& a = h_data.myTable;
270     // by default, constant table function f(t)=1
271     a.length( 4 );
272     a[0] = 0.0; a[1] = 1.0;
273     a[2] = 1.0; a[3] = 1.0; 
274   }
275
276   h_data.myExpr = distr==3 ? h->GetExpressionFunction() : "1";
277   h_data.myConv = distr==2 || distr==3 ? h->ConversionMode() : 1; /*cut negative by default*/
278
279   return true;
280 }
281
282 bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothesisData& h_data ) const
283 {
284   StdMeshers::StdMeshers_NumberOfSegments_var h =
285     StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
286
287   bool ok = true;
288   try
289   {
290     if( isCreation() )
291       SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.latin1() );
292
293     h->SetNumberOfSegments( h_data.myNbSeg );
294     int distr = h_data.myDistrType;
295     h->SetDistrType( distr );
296
297     if( distr==1 )
298       h->SetScaleFactor( h_data.myScale );
299
300     if( distr==2 || distr==3 )
301       h->SetConversionMode( h_data.myConv );
302
303     if( distr==2 )
304       h->SetTableFunction( h_data.myTable );
305
306     if( distr==3 )
307       h->SetExpressionFunction( h_data.myExpr.latin1() );
308     //setting of function must follow after setConversionMode, because otherwise
309     //the function will be checked with old conversion mode, so that it may occurs
310     //unexpected errors for user
311   }
312   catch(const SALOME::SALOME_Exception& ex)
313   {
314     SalomeApp_Tools::QtCatchCorbaException(ex);
315     ok = false;
316   }
317   return ok;
318 }
319
320 bool StdMeshersGUI_NbSegmentsCreator::readParamsFromWidgets( NbSegmentsHypothesisData& h_data ) const
321 {
322   h_data.myName      = myName ? myName->text() : "";
323   h_data.myNbSeg     = myNbSeg->value();
324   h_data.myDistrType = myDistr->currentItem();
325   h_data.myConv      = myConv->id( myConv->selected() );
326   h_data.myScale     = myScale->value();
327   myTable->table()->data( h_data.myTable );
328   h_data.myExpr      = myExpr->text();
329   return true;
330 }
331
332 void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
333 {
334   int distr = myDistr->currentItem();
335
336 /*  if( distr==2 ) //table func
337     myCutNeg->setText( tr( "SMESH_NO_CONV" ) );
338   else if( distr==3 )
339     myCutNeg->setText( tr( "SMESH_CUT_NEG_MODE" ) );*/
340
341   if( distr==2 && sender()==myConv ) //table func
342   {
343     myTable->table()->funcValidator()->setBottom( myConv->id( myConv->selected() )==0 ? -1E20 : 0 );
344     SMESH::double_array arr;
345     myTable->table()->data( arr );
346     myTable->table()->setData( arr ); //update data in table
347   }
348
349   myScale->setShown( distr==1 );
350   myLScale->setShown( distr==1 );
351
352   bool isFunc = distr==2 || distr==3;
353   myPreview->setShown( isFunc );
354   myGroupLayout->setRowStretch( myPreviewRow, isFunc ? 1 : 0 );
355
356   myConv->setShown( isFunc );
357   myLConv->setShown( isFunc );
358
359   if( distr==2 )
360     myTable->show();
361   else
362     myTable->hide();
363   myLTable->setShown( distr==2 );
364   myGroupLayout->setRowStretch( myTableRow, distr==2 ? 1 : 0 );
365
366   myExpr->setShown( distr==3 );
367   myLExpr->setShown( distr==3 );
368   myInfo->setShown( isFunc );
369
370   //change of preview
371   int nbSeg = myNbSeg->value();
372   if( distr==2 ) //preview for table-described function
373   {
374     SMESH::double_array a;
375     myTable->table()->data( a );
376     myPreview->setParams( a, nbSeg, false );
377   }
378   else if( distr==3 ) //preview for analytic-described function
379     myPreview->setParams( myExpr->text(), nbSeg, 100, false );
380
381   if( isFunc )
382     myPreview->setConversion( StdMeshersGUI_DistrPreview::Conversion( myConv->id( myConv->selected() ) ) );
383 }