1 // Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : StdMeshersGUI_NbSegmentsCreator.cxx
24 // Author : Open CASCADE S.A.S.
27 #include "StdMeshersGUI_NbSegmentsCreator.h"
28 #ifndef DISABLE_PLOT2DVIEWER
29 #include "StdMeshersGUI_DistrPreview.h"
31 #include "StdMeshersGUI_DistrTable.h"
32 #include "StdMeshersGUI_PropagationHelperWdg.h"
33 #include "StdMeshersGUI_SubShapeSelectorWdg.h"
36 #include <SMESHGUI_Utils.h>
37 #include <SMESHGUI_HypothesesUtils.h>
38 #include <SMESHGUI_SpinBox.h>
39 #include <SMESHGUI_SpinBoxForbiddendRange.h>
42 #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
44 // SALOME GUI includes
45 #include <SalomeApp_Tools.h>
46 #include <SalomeApp_IntSpinBox.h>
47 #include <QtxComboBox.h>
54 #include <QButtonGroup>
55 #include <QRadioButton>
56 #include <QGridLayout>
57 #include <QVBoxLayout>
58 #include <QHBoxLayout>
59 #include <QApplication>
64 StdMeshersGUI_NbSegmentsCreator::StdMeshersGUI_NbSegmentsCreator()
65 : StdMeshersGUI_StdHypothesisCreator( "NumberOfSegments" ),
71 #ifndef DISABLE_PLOT2DVIEWER
88 StdMeshersGUI_NbSegmentsCreator::~StdMeshersGUI_NbSegmentsCreator()
92 bool StdMeshersGUI_NbSegmentsCreator::checkParams( QString& msg ) const
94 if( !SMESHGUI_GenericHypothesisCreator::checkParams( msg ) )
96 NbSegmentsHypothesisData data_old, data_new;
97 readParamsFromHypo( data_old );
98 readParamsFromWidgets( data_new );
99 bool res = storeParamsToHypo( data_new );
100 res = myNbSeg->isValid( msg, true ) && res;
101 res = myScale->isValid( msg, true ) && res;
102 res = myBeta->isValid( msg, true ) && res;
104 storeParamsToHypo( data_old );
108 QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
110 QFrame* fr = new QFrame();
111 fr->setMinimumWidth(460);
113 QVBoxLayout* lay = new QVBoxLayout( fr );
115 lay->setSpacing( SPACING );
117 QGroupBox* GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), fr );
118 lay->addWidget( GroupC1 );
120 StdMeshers::StdMeshers_NumberOfSegments_var h =
121 StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
123 myGroupLayout = new QGridLayout( GroupC1 );
124 myGroupLayout->setSpacing( SPACING );
125 myGroupLayout->setMargin( MARGIN );
126 myGroupLayout->setColumnStretch( 0, 0 );
127 myGroupLayout->setColumnStretch( 1, 1 );
134 myName = new QLineEdit( GroupC1 );
135 myGroupLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), GroupC1 ), row, 0 );
136 myGroupLayout->addWidget( myName, row, 1 );
141 // 1) number of segments
142 myGroupLayout->addWidget( new QLabel( tr( "SMESH_NB_SEGMENTS_PARAM" ), GroupC1 ), row, 0 );
143 myNbSeg = new SalomeApp_IntSpinBox( GroupC1 );
144 myNbSeg->setMinimum( 1 );
145 myNbSeg->setMaximum( 9999 );
146 myGroupLayout->addWidget( myNbSeg, row, 1 );
150 // 2) type of distribution
151 myGroupLayout->addWidget( new QLabel( tr( "SMESH_DISTR_TYPE" ), GroupC1 ), row, 0 );
152 myDistr = new QtxComboBox( GroupC1 );
154 types.append( tr( "SMESH_DISTR_REGULAR" ) );
155 types.append( tr( "SMESH_DISTR_SCALE" ) );
156 types.append( tr( "SMESH_DISTR_TAB" ) );
157 types.append( tr( "SMESH_DISTR_EXPR" ) );
158 types.append( tr( "SMESH_DISTR_BETALAW" ) );
159 myDistr->addItems( types );
160 myGroupLayout->addWidget( myDistr, row, 1 );
165 myGroupLayout->addWidget( myLScale = new QLabel( tr( "SMESH_NB_SEGMENTS_SCALE_PARAM" ), GroupC1 ), row, 0 );
166 myScale = new SMESHGUI_SpinBox( GroupC1 );
167 myScale->RangeStepAndValidator( 1E-5, 1E+5, 0.1, "parametric_precision" );
168 myGroupLayout->addWidget( myScale, row, 1 );
172 // 4) Distribution definition
173 QGridLayout* myDistLayout = new QGridLayout(GroupC1);
174 myGroupLayout->addLayout( myDistLayout, row, 0, 1, 2 );
175 myGroupLayout->setRowStretch( row, 1 );
179 QHBoxLayout* myExprLayout = new QHBoxLayout(GroupC1);
180 myExprLayout->addWidget( myLExpr = new QLabel( "f(t)=", GroupC1 ), 0);
181 myExpr = new QLineEdit( GroupC1 );
182 myExprLayout->addWidget( myExpr,1);
183 myDistLayout->addLayout(myExprLayout,1 ,0);
184 myDistLayout->setRowStretch(2, 1);
187 myInfo = new QLabel( tr( "SMESH_FUNC_DOMAIN" ), GroupC1 );
188 myDistLayout->addWidget( myInfo, 0, 0, 1, 2);
191 myTable = new StdMeshersGUI_DistrTableFrame( GroupC1 );
192 myTable->setMinimumHeight(220);
193 myDistLayout->addWidget( myTable, 1, 0, 2, 1 );
195 #ifndef DISABLE_PLOT2DVIEWER
197 myPreview = new StdMeshersGUI_DistrPreview( GroupC1, h.in() );
198 myDistLayout->addWidget( myPreview, 1, 1, 2, 1 );
201 // 5) conversion (radiogroup)
202 myConvBox = new QGroupBox( tr( "SMESH_CONV_MODE" ), GroupC1 );
203 myConv = new QButtonGroup( GroupC1 );
205 QHBoxLayout* convLay = new QHBoxLayout( myConvBox );
206 convLay->setMargin( MARGIN );
207 convLay->setSpacing( SPACING );
209 QRadioButton* rbExp = new QRadioButton( tr( "SMESH_EXP_MODE" ), myConvBox );
210 QRadioButton* myCutNeg = new QRadioButton( tr( "SMESH_CUT_NEG_MODE" ), myConvBox );
212 convLay->addWidget( rbExp );
213 convLay->addWidget( myCutNeg );
214 myConv->addButton( rbExp, 0 );
215 myConv->addButton( myCutNeg, 1 );
217 myGroupLayout->addWidget( myConvBox, row, 0, 1, 2 );
221 // 6) reverse edge parameters
222 myReversedEdgesBox = new QGroupBox(tr( "SMESH_REVERSED_EDGES" ), fr);
223 QHBoxLayout* edgeLay = new QHBoxLayout( myReversedEdgesBox );
225 myDirectionWidget = new StdMeshersGUI_SubShapeSelectorWdg( myReversedEdgesBox );
226 QString aGeomEntry = getShapeEntry();
227 QString aMainEntry = getMainShapeEntry();
228 if ( aGeomEntry == "" )
229 aGeomEntry = h->GetObjectEntry();
230 myDirectionWidget->SetGeomShapeEntry( aGeomEntry, aMainEntry );
231 myDirectionWidget->SetListOfIDs( h->GetReversedEdges() );
232 edgeLay->addWidget( myDirectionWidget );
234 lay->addWidget( myReversedEdgesBox );
235 lay->setStretchFactor( GroupC1, 1);
236 lay->setStretchFactor( myReversedEdgesBox, 1);
238 myReversedEdgesHelper = 0;
239 if ( !aGeomEntry.isEmpty() || !aMainEntry.isEmpty() )
241 myReversedEdgesHelper = new StdMeshersGUI_PropagationHelperWdg( myDirectionWidget, fr, false );
242 lay->addWidget( myReversedEdgesHelper );
243 lay->setStretchFactor( myReversedEdgesHelper, 1 );
246 // 7) Beta Law distribution
247 myGroupLayout->addWidget(myLBeta = new QLabel(tr("SMESH_NB_SEGMENTS_BETA_PARAM"), GroupC1), row, 0);
248 myBeta = new SMESHGUI_SpinBoxForbiddendRange(GroupC1);
249 myBeta->RangeStepAndValidator(-1E+5, 1E+5, 0.00001, "parametric_precision");
250 myBeta->SetForbiddenRange(-1.0, 1.0);
251 myGroupLayout->addWidget(myBeta, row, 1);
254 connect( myNbSeg, SIGNAL( valueChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
255 connect( myDistr, SIGNAL( activated( int ) ), this, SLOT( onValueChanged() ) );
256 connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SLOT( onValueChanged() ) );
257 connect( myExpr, SIGNAL( textChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
258 connect( myConv, SIGNAL( buttonClicked( int ) ), this, SLOT( onValueChanged() ) );
265 void StdMeshersGUI_NbSegmentsCreator::retrieveParams() const
267 NbSegmentsHypothesisData data;
268 readParamsFromHypo( data );
271 myName->setText( data.myName );
272 if(data.myNbSegVarName.isEmpty())
273 myNbSeg->setValue( data.myNbSeg );
275 myNbSeg->setText( data.myNbSegVarName );
277 myDistr->setCurrentIndex( data.myDistrType );
278 if(data.myScaleVarName.isEmpty())
279 myScale->setValue( data.myScale );
281 myScale->setText( data.myScaleVarName );
282 myConv->button( data.myConv )->setChecked( true );
283 myTable->setFuncMinValue(myConv->checkedId()==0 ? -1E20 : 0);
284 myTable->setData( data.myTable );
285 myExpr->setText( data.myExpr );
287 myBeta->setValue(data.myBeta);
290 dlg()->setMinimumSize( dlg()->minimumSizeHint().width(), dlg()->minimumSizeHint().height() );
293 QString StdMeshersGUI_NbSegmentsCreator::storeParams() const
295 NbSegmentsHypothesisData data;
296 readParamsFromWidgets( data );
297 storeParamsToHypo( data );
299 QString valStr = QString::number( data.myNbSeg ) += "; ";
303 Regular, //!< equidistant distribution
304 Scale, //!< scale distribution
305 TabFunc, //!< distribution with density function presented by table
306 ExprFunc, //!< distribution with density function presented by expression
307 BetaLaw //!< distribution with density function presented by expression
309 bool hasConv = false;
310 switch ( data.myDistrType ) {
312 valStr += tr("SMESH_DISTR_REGULAR");
315 valStr += tr("SMESH_NB_SEGMENTS_SCALE_PARAM") + " = " + QString::number( data.myScale );
318 //valStr += tr("SMESH_TAB_FUNC");
320 for( CORBA::ULong i = 0; i < data.myTable.length(); i++, param = !param ) {
323 valStr += QString::number( data.myTable[ i ]);
324 valStr += ( param ? "," : "]" );
330 valStr += data.myExpr;
335 valStr += tr("SMESH_NB_SEGMENTS_BETA_PARAM") + " = " + QString::number(data.myBeta);
341 valStr += "; " + tr("SMESH_CUT_NEG_MODE");
343 valStr += "; " + tr("SMESH_EXP_MODE");
349 bool StdMeshersGUI_NbSegmentsCreator::readParamsFromHypo( NbSegmentsHypothesisData& h_data ) const
351 StdMeshers::StdMeshers_NumberOfSegments_var h =
352 StdMeshers::StdMeshers_NumberOfSegments::_narrow( initParamsHypothesis() );
354 h_data.myName = hypName();
356 h_data.myNbSeg = (int) h->GetNumberOfSegments();
358 CORBA::String_var aVaribaleName = h->GetVarParameter( "SetNumberOfSegments" );
359 h_data.myNbSegVarName = aVaribaleName.in();
361 int distr = (int) h->GetDistrType();
362 h_data.myDistrType = distr;
363 h_data.myScale = distr==1 ? h->GetScaleFactor() : 1.0;
366 aVaribaleName = h->GetVarParameter( "SetScaleFactor" );
367 h_data.myScaleVarName = aVaribaleName.in();
370 h_data.myScaleVarName = QString("");
374 SMESH::double_array* a = h->GetTableFunction();
380 SMESH::double_array& a = h_data.myTable;
381 // by default, constant table function f(t)=1
383 a[0] = 0.0; a[1] = 1.0;
384 a[2] = 1.0; a[3] = 1.0;
387 h_data.myExpr = distr==3 ? h->GetExpressionFunction() : "1";
388 h_data.myConv = distr==2 || distr==3 ? h->ConversionMode() : 1; /*cut negative by default*/
389 h_data.myBeta = distr==4 ? h->GetBeta() : 1.01;
394 bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothesisData& h_data ) const
396 StdMeshers::StdMeshers_NumberOfSegments_var h =
397 StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
403 SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toUtf8().data() );
405 h->SetVarParameter( h_data.myNbSegVarName.toUtf8().constData(), "SetNumberOfSegments" );
406 h->SetNumberOfSegments( h_data.myNbSeg );
408 int distr = h_data.myDistrType;
410 h->SetDistrType( distr ); // this is actually needed at non-uniform -> uniform switch
412 h->SetVarParameter( h_data.myScaleVarName.toUtf8().constData(), "SetScaleFactor" );
413 h->SetScaleFactor( h_data.myScale );
415 if( distr==2 || distr==3 )
416 h->SetConversionMode( h_data.myConv );
418 if( distr==1 || distr==2 || distr==3 || distr == 4) {
419 h->SetReversedEdges( myDirectionWidget->GetListOfIDs() );
420 h->SetObjectEntry( myDirectionWidget->GetMainShapeEntry() );
424 h->SetTableFunction( h_data.myTable );
427 h->SetExpressionFunction( h_data.myExpr.toUtf8().data() );
428 //setting of function must follow after setConversionMode, because otherwise
429 //the function will be checked with old conversion mode, so that it may occurs
430 //unexpected errors for user
434 h->SetDistrType(distr);
435 h->SetBeta(h_data.myBeta);
438 catch(const SALOME::SALOME_Exception& ex)
440 SalomeApp_Tools::QtCatchCorbaException(ex);
446 bool StdMeshersGUI_NbSegmentsCreator::readParamsFromWidgets( NbSegmentsHypothesisData& h_data ) const
448 h_data.myName = myName ? myName->text() : "";
449 h_data.myNbSeg = myNbSeg->value();
450 h_data.myNbSegVarName = myNbSeg->text();
451 h_data.myScaleVarName = myScale->text();
452 h_data.myDistrType = myDistr->currentIndex();
453 h_data.myConv = myConv->checkedId();
454 h_data.myScale = myScale->value();
455 h_data.myBeta = myBeta->value();
456 myTable->data( h_data.myTable );
457 h_data.myExpr = myExpr->text();
461 void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
463 int distr = myDistr->currentIndex();
465 /* if( distr==2 ) //table func
466 myCutNeg->setText( tr( "SMESH_NO_CONV" ) );
468 myCutNeg->setText( tr( "SMESH_CUT_NEG_MODE" ) );*/
470 if( distr==2 && sender()==myConv ) //table func
472 myTable->setFuncMinValue( myConv->checkedId()==0 ? -1E20 : 0 );
473 SMESH::double_array arr;
474 myTable->data( arr );
475 myTable->setData( arr ); //update data in table
478 myScale->setVisible( distr==1 );
479 myLScale->setVisible( distr==1 );
480 myReversedEdgesBox->setVisible( distr!=0 );
481 if ( myReversedEdgesHelper ) {
482 myReversedEdgesHelper->Clear();
483 myReversedEdgesHelper->setVisible( distr!=0 );
485 myDirectionWidget->ShowPreview( distr!=0 );
487 bool isFunc = distr==2 || distr==3;
488 #ifndef DISABLE_PLOT2DVIEWER
489 myPreview->setVisible( isFunc );
491 myConvBox->setVisible( isFunc );
493 myTable->setVisible( distr==2 );
494 myExpr->setVisible( distr==3 );
495 myLExpr->setVisible( distr==3 );
496 myInfo->setVisible( distr==3);
498 #ifndef DISABLE_PLOT2DVIEWER
500 int nbSeg = myNbSeg->value();
501 if( distr==2 ) //preview for table-described function
503 SMESH::double_array a;
505 myPreview->setParams( a, nbSeg, false );
507 else if( distr==3 ) //preview for analytic-described function
508 myPreview->setParams( myExpr->text(), nbSeg, 100, false );
511 myPreview->setConversion( StdMeshersGUI_DistrPreview::Conversion( myConv->checkedId() ) );
514 // Beta Law UI elements
515 const bool isBetaLaw = distr == 4;
516 myBeta->setVisible(isBetaLaw);
517 myLBeta->setVisible(isBetaLaw);
519 if ( (QtxComboBox*)sender() == myDistr && dlg() ) {
520 QApplication::instance()->processEvents();
521 myGroupLayout->invalidate();
522 dlg()->layout()->invalidate();
523 dlg()->updateGeometry();
524 dlg()->setMinimumSize( dlg()->minimumSizeHint() );
525 dlg()->resize( dlg()->minimumSize() );
526 QApplication::instance()->processEvents();