1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "SelectParams.h"
24 #include "MEDMEM_MedMeshDriver.hxx"
25 #include "MEDMEM_EnsightMeshDriver.hxx"
27 #include <SUIT_FileDlg.h>
29 #include "Utils_SALOME_Exception.hxx"
30 #include <SalomeApp_Tools.h>
33 #include <qgroupbox.h>
36 #include <qlineedit.h>
37 #include <qbuttongroup.h>
38 #include <qradiobutton.h>
39 #include <qpushbutton.h>
40 #include <qfiledialog.h>
41 #include <qmessagebox.h>
44 SelectParams::SelectParams(FilterGUI* theModule,SelectField *sel,
46 bool modal, WFlags fl) throw(SALOME_Exception)
47 : QDialog(FILTER::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose),_size(1024),_sel(sel)
49 MESSAGE("SelectParams constructor");
51 // read reference field values
52 _filter = sel->getFilter();
54 // Get reference field and time step
55 _inputFile = sel->getFile();
56 _inputMesh = sel->getMesh();
57 _inputField = sel->getField();
58 _inputTS = sel->getTimeStep();
60 if( _inputFile.isEmpty() || _inputMesh.isEmpty() || _inputField.isEmpty())
61 throw SALOME_Exception("Select an input Field in MED file before filtering!!");
63 _filter->readReferenceField(_inputMesh,_inputField,_inputTS);
68 // if no reference field selection: throw exception
70 throw SALOME_Exception("Select an input Field in MED file before filtering!!");
72 // Allocate histogram arrays
73 _x = new double[_size];
74 _y = new double[_size];
78 SelectParams::~SelectParams()
80 cout << "SelectParams: destructor called" << endl;
82 // destrcution of histogram arrays
86 // destruction of SelectField object and Filter object in it
90 void SelectParams::buildFrame()
92 // build widgets for select filtering parameters
93 QGridLayout* _lay = new QGridLayout( this, 1, 2 );
95 QGroupBox* _GroupC1 = new QGroupBox( this, "GroupC1" );
96 _lay->addWidget( _GroupC1,0,0 );
98 _GroupC1->setTitle( tr( "FILTER_PARAMS" ) );
99 _GroupC1->setColumnLayout(0, Qt::Vertical );
100 _GroupC1->layout()->setSpacing( 0 );
101 _GroupC1->layout()->setMargin( 0 );
102 _myGroupLayout = new QGridLayout( _GroupC1->layout() );
103 _myGroupLayout->setAlignment( Qt::AlignTop );
104 _myGroupLayout->setSpacing( 6 );
105 _myGroupLayout->setMargin( 11 );
106 _myGroupLayout->setColStretch( 0, 0 );
107 _myGroupLayout->setColStretch( 1, 1 );
111 QString qs1(tr("FILTER_INPUT_FILE"));
112 qs1.append(basename(_inputFile));
113 _myGroupLayout->addWidget( new QLabel( qs1, _GroupC1 ), row, 0 );
116 QString qs2(tr("FILTER_INPUT_MESH"));
117 qs2.append(_inputMesh);
118 _myGroupLayout->addWidget( new QLabel( qs2, _GroupC1 ), row, 0 );
121 QString qs3(tr("FILTER_INPUT_FIELD"));
122 qs3.append(_inputField);
123 _myGroupLayout->addWidget( new QLabel( qs3, _GroupC1 ), row, 0 );
126 QString qs4(tr("FILTER_INPUT_TS"));
128 sprintf(strTS,"%d\0",_inputTS);
130 _myGroupLayout->addWidget( new QLabel( qs4, _GroupC1 ), row, 0 );
133 // 0) field function to calculate histogram (radiogroup)
134 _myFunc = new QButtonGroup( tr("FILTER_SELECT_FUNC"), _GroupC1 );
135 _myFunc->setExclusive( true );
136 _myFunc->setColumnLayout( 0, Qt::Horizontal );
138 _myFieldB = new QRadioButton( tr("FILTER_FIELD"), _myFunc );
139 _myFieldB->setChecked(true);
141 QGridLayout* convLay = new QGridLayout( _myFunc->layout() );
142 convLay->addWidget( _myFieldB, 0, 0 );
143 convLay->addWidget( _myGradB = new QRadioButton( tr("FILTER_GRADIENT"), _myFunc ), 0, 1 );
144 _myGroupLayout->addWidget( _myFunc, row, 0 );
147 // 01) histogram size (line edit)
148 _myHSize = new QButtonGroup( tr(""), _GroupC1 );
149 _myHSize->setExclusive( true );
150 _myHSize->setColumnLayout( 0, Qt::Horizontal );
151 QGridLayout* shLay = new QGridLayout( _myHSize->layout() );
152 shLay->addWidget( _myLSH = new QLabel( tr("FILTER_SIZE_HISTO") , _myHSize ), 0, 0 );
153 shLay->addWidget( _myLESH = new QLineEdit( "1024", _myHSize ), 0, 1 );
154 _myGroupLayout->addWidget( _myHSize, row, 0 );
157 // 1) display histogram button (pushbutton)
158 _myHisto = new QPushButton( "", _GroupC1 );
159 _myHisto->setText(tr("FILTER_DISPLAY_HISTO"));
160 _myHisto->setAutoDefault(FALSE);
161 _myGroupLayout->addWidget( _myHisto, row, 0 );
164 // 2) scale of histogram (radiogroup)
165 _myFScale = new QButtonGroup( tr("FILTER_TYPE_DISPLAY"), _GroupC1 );
166 _myFScale->setExclusive( true );
167 _myFScale->setColumnLayout( 0, Qt::Horizontal );
169 _myLinear = new QRadioButton( tr("FILTER_LINEAR"), _myFScale );
170 _myLinear->setChecked(true);
171 _myLog = new QRadioButton( tr("FILTER_LOG"), _myFScale );
172 _myFScale->setDisabled(true);
174 QGridLayout* scaleLay = new QGridLayout( _myFScale->layout() );
175 scaleLay->addWidget( _myLinear, 0, 0 );
176 scaleLay->addWidget( _myLog, 0, 1 );
177 _myGroupLayout->addWidget( _myFScale, row, 0 );
180 // 3) number of thresholds (radiogroup)
181 _myNbThresh = new QButtonGroup( tr("FILTER_SEL_THRESH"), _GroupC1 );
182 _myNbThresh->setExclusive( true );
183 _myNbThresh->setColumnLayout( 0, Qt::Horizontal );
184 QGridLayout* nbtLay = new QGridLayout( _myNbThresh->layout() );
185 nbtLay->addWidget( _myOneThresh = new QRadioButton( tr("FILTER_ONE_THRESH"), _myNbThresh ), 0, 0 );
186 nbtLay->addWidget( _myTwoThresh = new QRadioButton( tr("FILTER_TWO_THRESH"), _myNbThresh ), 0, 1 );
187 _myGroupLayout->addWidget( _myNbThresh, row, 0 );
189 _myOneThresh->setChecked(true);
190 _myNbThresh->setDisabled(true);
193 // 4) reference area on thresholds (radiogroup)
194 _myArea = new QButtonGroup( tr("FILTER_REF_AREA"), _GroupC1 );
195 _myArea->setExclusive( true );
196 _myArea->setColumnLayout( 0, Qt::Horizontal );
197 QGridLayout* areaLay = new QGridLayout( _myArea->layout() );
198 areaLay->addWidget( _myInt = new QRadioButton( tr("FILTER_BOTTOM"), _myArea ), 0, 0 );
199 areaLay->addWidget( _myExt = new QRadioButton( tr("FILTER_UP"), _myArea ), 0, 1 );
200 _myGroupLayout->addWidget( _myArea, row, 0 );
202 _myExt->setChecked(true);
203 _myArea->setDisabled(true);
206 // 5) threshold values (line edit)
207 _myVThresh = new QButtonGroup( tr("FILTER_TRESH_VAL"), _GroupC1 );
208 _myVThresh->setExclusive( true );
209 _myVThresh->setColumnLayout( 0, Qt::Horizontal );
210 QGridLayout* ftLay = new QGridLayout( _myVThresh->layout() );
211 ftLay->addWidget( _myLFT = new QLabel( tr("FILTER_VAL_TRESH") , _myVThresh ), 0, 0 );
212 ftLay->addWidget( _myLEFT = new QLineEdit( "", _myVThresh ), 0, 1 );
213 ftLay->addWidget( _myLST = new QLabel( tr("FILTER_VAL_2_TRESH") , _myVThresh ), 1, 0 );
214 ftLay->addWidget( _myLEST = new QLineEdit( "", _myVThresh ), 1, 1 );
215 _myGroupLayout->addWidget( _myVThresh, row, 0 );
217 _myVThresh->setDisabled(true);
222 // 6) output file name (line edit)
223 _myOutFile = new QButtonGroup( tr("FILTER_OUT_FILE"), _GroupC1 );
224 _myOutFile->setExclusive( true );
225 _myOutFile->setColumnLayout( 0, Qt::Horizontal );
227 _myOFB = new QPushButton( "", _myOutFile );
228 _myOFB->setText(tr("FILTER_BROWSE"));
229 _myOFB->setAutoDefault(FALSE);
231 QGridLayout* outLay = new QGridLayout( _myOutFile->layout() );
232 outLay->addWidget( _myOFB, 0, 0 );
233 outLay->addWidget( _myOFN = new QLineEdit( "", _myOutFile ), 0, 1 );
234 _myGroupLayout->addWidget( _myOutFile, row, 0 );
236 _myOutFile->setDisabled(true);
239 // 8) buttons Process, Close and Help
240 _GroupButtons = new QGroupBox(_GroupC1, "GroupButtons");
241 _GroupButtons->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)7, (QSizePolicy::SizeType)0, 0, 0, _GroupButtons->sizePolicy().hasHeightForWidth()));
242 _GroupButtons->setTitle(tr("" ));
243 _GroupButtons->setColumnLayout(0, Qt::Vertical);
244 _GroupButtons->layout()->setSpacing(0);
245 _GroupButtons->layout()->setMargin(0);
246 _GroupButtonsLayout = new QGridLayout(_GroupButtons->layout());
247 _GroupButtonsLayout->setAlignment(Qt::AlignTop);
248 _GroupButtonsLayout->setSpacing(6);
249 _GroupButtonsLayout->setMargin(11);
250 _myProc = new QPushButton(_GroupButtons, "buttonProcess");
251 _myProc->setText(tr("FILTER_PROCESS"));
252 _myProc->setAutoDefault(FALSE);
253 _GroupButtonsLayout->addWidget(_myProc, 0, 0);
254 _buttonHelp = new QPushButton(_GroupButtons, "buttonHelp");
255 _buttonHelp->setText(tr("FILTER_BUT_HELP" ));
256 _buttonHelp->setAutoDefault(FALSE);
257 _GroupButtonsLayout->addWidget(_buttonHelp, 0, 2);
258 _buttonCancel = new QPushButton(_GroupButtons, "buttonCancel");
259 _buttonCancel->setText(tr("FILTER_BUT_CANCEL" ));
260 _buttonCancel->setAutoDefault(FALSE);
261 _GroupButtonsLayout->addWidget(_buttonCancel, 0, 1);
262 _myGroupLayout->addWidget( _GroupButtons, row, 0 );
263 _GroupButtons->setDisabled(true);
266 _GroupC2 = new QGroupBox( this, "GroupC2" );
267 _lay->addWidget( _GroupC2,0,1 );
269 _GroupC2->setTitle( tr( "FILTER_HISTO" ) );
270 _GroupC2->setColumnLayout(0, Qt::Vertical );
271 _GroupC2->layout()->setSpacing( 0 );
272 _GroupC2->layout()->setMargin( 0 );
273 _myGroupLayout2 = new QGridLayout( _GroupC2->layout() );
275 // 9) histogram curve
276 _myPlot = new QwtPlot(_GroupC2);
277 _myHistoCurve = _myPlot->insertCurve( QString() );
278 _myPlot->setCurvePen( _myHistoCurve, QPen( Qt::red, 1 ) );
279 _myPlot->setCurveTitle( _myHistoCurve, "Histogram" );
281 _myGroupLayout2->addWidget( _myPlot, 0, 0 );
283 // 10) reduction rate (label)
284 QString qs5(tr("FILTER_RED_RATE"));
285 qs5.append(" = 0.5");
286 _myLRR = new QLabel( qs5, _GroupC2 );
287 _myGroupLayout2->addWidget( _myLRR, 1, 0 );
291 _myHistoFThresh = _myPlot->insertCurve( QString() );
292 _myPlot->setCurvePen( _myHistoFThresh, QPen( Qt::black, 1 ) );
293 _myHistoSThresh = _myPlot->insertCurve( QString() );
294 _myPlot->setCurvePen( _myHistoSThresh, QPen( Qt::black, 1 ) );
296 connect( _myGradB, SIGNAL(clicked()), this, SLOT(gradSelected()));
297 connect( _myLESH, SIGNAL(returnPressed()), this, SLOT(enterSHisto()));
298 connect( _myHisto, SIGNAL(clicked()), this, SLOT(updateHisto()));
299 connect( _myLinear, SIGNAL(clicked()), this, SLOT(scaleSelected()));
300 connect( _myLog, SIGNAL(clicked()), this, SLOT(scaleSelected()));
301 connect( _myOneThresh, SIGNAL(clicked()), this, SLOT(nbThreshSelected()));
302 connect( _myTwoThresh, SIGNAL(clicked()), this, SLOT(nbThreshSelected()));
303 connect( _myInt, SIGNAL(clicked()), this, SLOT(areaSelected()));
304 connect( _myExt, SIGNAL(clicked()), this, SLOT(areaSelected()));
305 connect( _myLEFT, SIGNAL(returnPressed()), this, SLOT(enterFThresh()));
306 connect( _myLEST, SIGNAL(returnPressed()), this, SLOT(enterSThresh()));
307 connect( _myPlot, SIGNAL(plotMouseMoved(const QMouseEvent &)), this, SLOT(moveThresh(const QMouseEvent &)));
308 connect( _myOFB, SIGNAL(clicked()), this, SLOT(getOutFileName()));
309 connect( _myProc, SIGNAL(clicked()), this, SLOT(process()));
310 connect(_buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
311 connect(_buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
313 _GroupC2->setMinimumSize( 500, 500 );
314 _GroupC2->setMaximumSize( 500, 500 );
315 setMinimumSize( 750, 500 );
316 setMaximumSize( 750, 500 );
320 void SelectParams::gradSelected()
323 _filter->buildGradient();
325 catch(SALOME_FILTER::FILTER_Gen::FilterError){
326 _myFieldB->setChecked(true);
327 QMessageBox::information( this,
329 "Unable to calculate gradient on vector field.\n"
330 "You must select a reference scalar field." );
333 MESSAGE("unknownException");
337 void SelectParams::enterSHisto()
339 // Deallocate old histogram arrays
343 // get new histogram size
344 _size = atoi(_myLESH->text());
346 // Allocate new histogram arrays
347 _x = new double[_size];
348 _y = new double[_size];
351 void SelectParams::scaleSelected()
353 // draw linear or log Y scale depend on user
354 if( _myLinear->isChecked() ){
356 _myPlot->setAxisOptions(_myPlot->curveYAxis( _myHistoCurve ), QwtAutoScale::None );
359 // set min to 0.1 for log scale
361 _myPlot->setAxisOptions(_myPlot->curveYAxis( _myHistoCurve ), QwtAutoScale::Logarithmic );
363 _myPlot->setAxisScale( _myPlot->curveYAxis( _myHistoCurve ), _ymin, _ymax );
367 void SelectParams::nbThreshSelected()
369 if( _myOneThresh->isChecked() ){
370 // if one threshold choice between bottom and up for reference area
371 _myInt->setText(tr("FILTER_BOTTOM"));
372 _myExt->setText(tr("FILTER_UP"));
373 _myLFT->setText(tr("FILTER_VAL_TRESH"));
376 // draw first threshold
378 // erase second threshold
382 // if two thresholds choice between interior and exterior fir reference area
383 _myInt->setText(tr("FILTER_INT"));
384 _myExt->setText(tr("FILTER_EXT"));
385 _myLFT->setText(tr("FILTER_VAL_1_TRESH"));
386 if(_myLST->isHidden())
388 if(_myLEST->isHidden())
390 // draw two thresholds
397 void SelectParams::areaSelected()
399 // calculate reduction rate after thresholds selection
403 void SelectParams::enterFThresh()
409 void SelectParams::enterSThresh()
415 void SelectParams::calcHisto()
418 CORBA::Double min, max;
419 CORBA::Long size = _size;
420 SALOME_FILTER::LongSeq* histo;
422 if( _myFieldB->isChecked() ){
423 // calculate histogram values on field
424 _filter->getMinMax(min,max,SALOME_FILTER::F_FIELD);
425 histo = _filter->getHistogram(size,SALOME_FILTER::F_FIELD);
428 // calculate histogram values on gradient
429 _filter->getMinMax(min,max,SALOME_FILTER::F_GRAD);
430 histo = _filter->getHistogram(size,SALOME_FILTER::F_GRAD);
434 vector<int> myh(_size);
435 for(int i=0;i<_size;i++)
436 myh[i] = (*histo)[i];
438 if( _myLinear->isChecked() )
444 for(int i=0;i<_size;i++){
445 // calculate absisses for histogram values
446 _x[i]=_xmin+(i*(_xmax-_xmin))/_size;
447 // set zero to 0.01 because pb of zeros in log display with qwt
449 _y[i]=(double)myh[i];
456 // init thresholds values
457 _fthresh = (_xmin + _xmax)/2.0;
458 _sthresh = (_xmin + 3.*_xmax)/4.0;
459 sprintf(strth,"%g",_fthresh);
460 _myLEFT->setText(QString(strth));
461 sprintf(strth,"%g",_sthresh);
462 _myLEST->setText(QString(strth));
465 void SelectParams::displayHisto()
467 // associate values to curve
468 _myPlot->setCurveData( _myHistoCurve, _x, _y, _size );
469 // give extrema values for each axis
470 _myPlot->setAxisScale( _myPlot->curveXAxis( _myHistoCurve ), _xmin, _xmax );
471 _myPlot->setAxisScale( _myPlot->curveYAxis( _myHistoCurve ), _ymin, _ymax );
472 if( _myLinear->isChecked() )
473 _myPlot->setAxisOptions(_myPlot->curveYAxis( _myHistoCurve ), QwtAutoScale::None );
475 _myPlot->setAxisOptions(_myPlot->curveYAxis( _myHistoCurve ), QwtAutoScale::Logarithmic );
476 // associate mapping to plot to move thresholds on display
477 _qmap = _myPlot->canvasMap(_myPlot->curveXAxis( _myHistoCurve ));
478 _qmap.setDblRange(_xmin,_xmax);
482 void SelectParams::enableWidgets()
484 if(_GroupC2->isHidden()){
485 _myFScale->setEnabled(true);
486 _myNbThresh->setEnabled(true);
487 _myArea->setEnabled(true);
488 _myVThresh->setEnabled(true);
489 _myOutFile->setEnabled(true);
490 _GroupButtons->setEnabled(true);
495 void SelectParams::updateHisto()
500 if( _myTwoThresh->isChecked() )
506 void SelectParams::displayFThresh()
508 _fthresh = atof(_myLEFT->text());
510 // draw first threshold curve
511 for(int i=0;i<100;i++){
513 _yft[i]=((i-1)*_ymax)/100.0;
515 _myPlot->setCurveData( _myHistoFThresh, _xft, _yft, 100 );
519 void SelectParams::displaySThresh()
521 _sthresh = atof(_myLEST->text());
523 // draw second threshold curve
524 for(int i=0;i<100;i++){
526 _yst[i]=((i-1)*_ymax)/100.0;
528 _myPlot->setCurveData( _myHistoSThresh, _xst, _yst, 100 );
532 void SelectParams::clearSThresh()
534 _sthresh = atof(_myLEST->text());
536 // erase second threshold curve
537 for(int i=0;i<100;i++){
541 _myPlot->setCurveData( _myHistoSThresh, _xst, _yst, 100 );
545 void SelectParams::moveThresh(const QMouseEvent &e)
549 // move threshold curve with mouse
550 int delta = abs(e.x()-_qmap.transform(_fthresh));
552 // moving first threshold curve
553 sprintf(strth,"%g",_qmap.invTransform(e.x()));
554 _myLEFT->setText(QString(strth));
557 else if( _myTwoThresh->isChecked() ){
558 delta = abs(e.x()-_qmap.transform(_sthresh));
560 // moving second threshold curve
561 sprintf(strth,"%g",_qmap.invTransform(e.x()));
562 _myLEST->setText(QString(strth));
569 void SelectParams::getOutFileName()
571 // get output MED file name
572 QString file = QFileDialog::getSaveFileName("",
576 "Choose a file to save" );
578 _myOFN->setText(file);
580 // Selection du Fichier
581 // file = SUIT_FileDlg::getFileName(application()->desktop(),
584 // "Output MED file name",
588 void SelectParams::process() throw(SALOME_Exception)
593 MESSAGE("Input MED File : "<<_inputFile);
594 MESSAGE("Input Mesh : "<<_inputMesh);
595 MESSAGE("Input Field : "<<_inputField);
596 MESSAGE("Input Time Step : "<<_inputTS);
597 MESSAGE("Output file name: " << _myOFN->text() );
599 setCursor(QCursor(Qt::WaitCursor));
601 MESSAGE("Generate Criteria");
602 // generate MED integer field (0 or 1) for filtoo input
604 if( _myOneThresh->isChecked() )
608 SALOME_FILTER::ref_func rf;
609 if(_myFieldB->isChecked())
610 rf = SALOME_FILTER::F_FIELD;
612 rf = SALOME_FILTER::F_GRAD;
613 _filter->generateCriteria(nbthresh,_fthresh,_sthresh,_myExt->isChecked(),rf);
615 catch (SALOME_FILTER::FILTER_Gen::FilterError){
616 QMessageBox::information( this,
618 "Unable to process filtering.\n"
619 "You must select a reference field on nodes or on cells." );
624 // create ensight input files to filtoo
625 _filter->createEnsightInputFiles();
628 _filter->filtering();
630 // project input fields on new mesh
632 _filter->projectFieldsOnDecimateMesh();
634 catch (SALOME_FILTER::FILTER_Gen::FilterError& ex){
635 throw SALOME_Exception(ex.error_msg);
638 // create new MED file with new mesh and fields
639 _filter->createMedOutputFile(_myOFN->text());
646 void SelectParams::calcRateRed()
649 int atot=0, asel=0, atot1;
652 // calculate reduction rate depend on reference area defined by threshold values
653 i1 = (int)((double)_size * ( _fthresh - _xmin ) / ( _xmax - _xmin ));
654 if( _myOneThresh->isChecked() ){
658 for(i=i1;i<_size;i++)
660 if( _myExt->isChecked() )
664 i2 = (int)((double)_size * ( _sthresh - _xmin ) / ( _xmax - _xmin ));
676 for(i=i2;i<_size;i++)
678 if( _myExt->isChecked() )
681 rateRed = (double)asel / (double) atot;
683 // display reduction rate value
684 QString qs(tr("FILTER_RED_RATE"));
686 sprintf(str," = %4.2g",rateRed);
688 _myLRR->setText( qs );
692 void SelectParams::ClickOnCancel()
694 MESSAGE("click on Cancel");
698 void SelectParams::ClickOnHelp()
700 MESSAGE("click on Help");