1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, 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
22 // File : StdMeshersGUI_CartesianParamCreator.cxx
23 // Author : Open CASCADE S.A.S.
26 #include "StdMeshersGUI_CartesianParamCreator.h"
29 #include "SMESHGUI_Utils.h"
30 #include "SMESHGUI_VTKUtils.h"
31 #include "SMESHGUI_HypothesesUtils.h"
32 #include "SMESHGUI_SpinBox.h"
33 #include "SMESHGUI_MeshEditPreview.h"
36 #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
38 // SALOME GUI includes
39 #include <LightApp_SelectionMgr.h>
40 #include <QtxComboBox.h>
41 #include <SALOME_InteractiveObject.hxx>
42 #include <SALOME_ListIO.hxx>
43 #include <SALOME_ListIteratorOfListIO.hxx>
44 #include <SUIT_ResourceMgr.h>
45 #include <SalomeApp_IntSpinBox.h>
46 #include <SalomeApp_Tools.h>
50 #include <BRepBndLib.hxx>
51 #include <Bnd_Box.hxx>
52 #include <TopoDS_Iterator.hxx>
53 #include <TopoDS_Shape.hxx>
57 #include <QAbstractItemModel>
58 #include <QApplication>
59 #include <QButtonGroup>
61 #include <QFontMetrics>
62 #include <QGridLayout>
64 #include <QHBoxLayout>
67 #include <QListWidget>
68 #include <QModelIndex>
69 #include <QPushButton>
70 #include <QRadioButton>
72 #include <QStyleOptionViewItem>
74 #include <QTreeWidget>
75 #include <QTreeWidgetItem>
76 #include <QVBoxLayout>
81 namespace StdMeshersGUI
83 enum { COORD_BUT = 0, SPACING_BUT };
85 //================================================================================
87 * \brief get spacing definition from a tree item
89 //================================================================================
91 void getFromItem(QTreeWidgetItem * item, double& t0, double& t1, QString& fun )
95 t0 = item->text( 0 ).split(' ')[0].toDouble();
96 t1 = item->data( 0, Qt::UserRole ).toDouble();
97 fun = item->text( 1 );
101 //================================================================================
103 * \brief set spacing definition to a tree item
105 //================================================================================
107 QTreeWidgetItem* setToItem(double t0, double t1, const QString& fun, QTreeWidgetItem * item)
109 if ( !item ) item = new QTreeWidgetItem;
110 item->setText( 0, QString( "%1 - %2" ).arg( t0 ).arg( t1 ));
111 item->setData( 0, Qt::UserRole, t1 );
112 item->setText( 1, fun );
113 item->setFlags( item->flags() | Qt::ItemIsEditable );
117 //================================================================================
119 * \brief Retrieves coordinate value from a list item
121 //================================================================================
123 double coordFromItem( QListWidgetItem * item )
125 return item ? item->data( Qt::UserRole ).toDouble() : 0;
128 //================================================================================
130 * \brief Sets coordinate value to a list item
132 //================================================================================
134 QListWidgetItem* coordToItem( double coord, QListWidgetItem * item )
136 if ( !item ) item = new QListWidgetItem;
137 item->setText( QString::number( coord ));
138 item->setData( Qt::UserRole, coord );
139 item->setFlags( item->flags() | Qt::ItemIsEditable );
143 //================================================================================
146 * \param theParent - Parent widget for this tab
148 * Makes tab's look and feel
150 //================================================================================
152 GridAxisTab::GridAxisTab( QWidget* theParent,const int axisIndex ):
153 QFrame( theParent ), myAxisIndex( axisIndex )
155 // 1) Grid definition mode
156 myModeGroup = new QButtonGroup( this );
157 QGroupBox* modeBox = new QGroupBox( tr( "GRID_DEF_MODE" ), this );
158 QHBoxLayout* modeLay = new QHBoxLayout( modeBox );
159 modeLay->setMargin( MARGIN );
160 modeLay->setSpacing( SPACING );
162 QRadioButton* coordModeBtn = new QRadioButton( tr( "SMESH_COORDINATES" ), modeBox );
163 QRadioButton* spacModeBtn = new QRadioButton( tr( "SPACING" ), modeBox );
165 modeLay->addWidget( coordModeBtn );
166 modeLay->addWidget( spacModeBtn );
167 myModeGroup->addButton( coordModeBtn, COORD_BUT );
168 myModeGroup->addButton( spacModeBtn, SPACING_BUT );
171 myInsertBtn = new QPushButton( tr("INSERT"), this);
172 myDeleteBtn = new QPushButton( tr("SMESH_BUT_DELETE"), this);
174 myStepLabel = new QLabel( tr("COORD_STEP"));
175 myStepSpin = new SMESHGUI_SpinBox( this );
176 myStepSpin->setAcceptNames( false ); // No Notebook variables allowed
177 myStepSpin->RangeStepAndValidator();
178 myStepSpin->SetStep( 1. );
179 myStepSpin->SetValue( myStep = 1. );
181 // 3) Coodrinates/Spacing group
182 QFrame* csFrame = new QFrame( this );
183 QVBoxLayout* scLay = new QVBoxLayout( csFrame );
184 scLay->setMargin( 0 );
185 scLay->setSpacing( SPACING );
188 mySpacingTreeWdg = new QTreeWidget( csFrame );
189 mySpacingTreeWdg->setColumnCount(2);
190 mySpacingTreeWdg->setHeaderLabels( QStringList() << tr( "SMESH_RANGE" ) << QString( "f(t)" ));
191 mySpacingTreeWdg->setColumnWidth( 1, 40 );
192 mySpacingTreeWdg->setColumnWidth( 2, 30 );
193 mySpacingTreeWdg->setItemDelegate( new LineDelegate( mySpacingTreeWdg ));
194 scLay->addWidget( mySpacingTreeWdg );
197 myCoordList = new QListWidget( csFrame );
198 myCoordList->setItemDelegate( new LineDelegate( myCoordList ));
199 scLay->addWidget( myCoordList );
203 QGridLayout* axisTabLayout = new QGridLayout( this );
204 axisTabLayout->setMargin( MARGIN );
205 axisTabLayout->setSpacing( SPACING );
207 axisTabLayout->addWidget( modeBox , 0, 0, 1, 3 );
208 axisTabLayout->addWidget( myInsertBtn , 1, 0, 1, 2 );
209 axisTabLayout->addWidget( myDeleteBtn , 2, 0, 1, 2 );
210 axisTabLayout->addWidget( myStepLabel, 3, 0 );
211 axisTabLayout->addWidget( myStepSpin , 3, 1 );
212 axisTabLayout->addWidget( csFrame , 1, 2, 4, 1 );
214 axisTabLayout->setRowStretch( 4, 1 );
217 connect( myInsertBtn, SIGNAL( clicked() ), SLOT( onInsert() ));
218 connect( myDeleteBtn, SIGNAL( clicked() ), SLOT( onDelete() ));
219 connect( myModeGroup, SIGNAL( buttonClicked ( int )), SLOT( onMode(int)));
220 connect( myModeGroup, SIGNAL( buttonClicked ( int )), SIGNAL( gridModeChanged(int)));
221 connect( mySpacingTreeWdg, SIGNAL( itemSelectionChanged()), SLOT( updateButtons() ));
222 connect( myCoordList, SIGNAL( itemSelectionChanged()), SLOT( updateButtons() ));
223 connect( myStepSpin, SIGNAL( valueChanged(double)), SLOT( onStepChange() ));
226 //================================================================================
228 * \brief SLOT onInsert
230 //================================================================================
232 void GridAxisTab::onInsert()
234 if ( isGridBySpacing() )
236 QTreeWidgetItem * item = mySpacingTreeWdg->currentItem();
237 if ( !item ) item = mySpacingTreeWdg->topLevelItem( 0 );
238 int i = mySpacingTreeWdg->indexOfTopLevelItem( item );
240 double t0, t1; QString fun;
241 getFromItem( item, t0, t1, fun );
242 double t = 0.5 * ( t0 + t1 );
243 setToItem( t0, t, fun, item );
245 item = setToItem( t, t1, fun );
246 if ( i == mySpacingTreeWdg->topLevelItemCount()-1 )
247 mySpacingTreeWdg->addTopLevelItem( item );
249 mySpacingTreeWdg->insertTopLevelItem( i+1, item );
250 mySpacingTreeWdg->setCurrentItem( item );
254 if ( myCoordList->count() == 0 )
256 myCoordList->addItem( coordToItem( 0 ));
260 double coord = coordFromItem( myCoordList->currentItem() ) + myStep;
261 int i = myCoordList->currentRow();
262 while ( i > 0 && coordFromItem( myCoordList->item( i-1 )) > coord )
264 while ( i < myCoordList->count() && coordFromItem( myCoordList->item( i )) < coord )
266 const double tol = 1e-6;
268 ( i < myCoordList->count() && coordFromItem( myCoordList->item( i )) - coord < tol ) ||
269 ( i > 0 && coord - coordFromItem( myCoordList->item( i-1 )) < tol );
271 myCoordList->insertItem( i, coordToItem( coord ));
272 else if ( myStep < 0 )
274 myCoordList->setCurrentRow( i );
280 //================================================================================
282 * \brief SLOT onDelete
284 //================================================================================
286 void GridAxisTab::onDelete()
288 if ( isGridBySpacing() )
290 QList<QTreeWidgetItem *> selItems = mySpacingTreeWdg->selectedItems();
291 QTreeWidgetItem * item;
292 Q_FOREACH ( item, selItems )
294 int i = mySpacingTreeWdg->indexOfTopLevelItem( item );
295 if ( i == 0 ) continue;
296 QTreeWidgetItem* prevItem = mySpacingTreeWdg->topLevelItem( i-1 );
298 double t0, t1, t2; QString fun;
299 getFromItem( item, t1, t2, fun );
300 getFromItem( prevItem, t0, t1, fun );
303 setToItem( t0, t2, fun, prevItem );
308 if ( myCoordList->count() > 2 )
309 if ( QListWidgetItem * item = myCoordList->currentItem() )
315 //================================================================================
319 //================================================================================
321 void GridAxisTab::onMode(int isSpacing)
323 mySpacingTreeWdg->setShown( isSpacing );
324 myCoordList->setShown( !isSpacing );
325 myStepSpin->setShown( !isSpacing );
326 myStepLabel->setShown( !isSpacing );
329 if ( mySpacingTreeWdg->topLevelItemCount() == 0 )
331 QString spacing( "1" );
332 if ( myCoordList->count() > 1 )
334 double c1 = coordFromItem( myCoordList->item( 1 ));
335 double c0 = coordFromItem( myCoordList->item( 0 ));
336 spacing = QString::number( c1 - c0 );
338 mySpacingTreeWdg->addTopLevelItem( setToItem( 0., 1., spacing ) );
340 //myCoordList->clear();
344 //mySpacingTreeWdg->clear();
345 if ( myCoordList->count() == 0 )
346 myCoordList->addItem( coordToItem( 0 ));
351 //================================================================================
353 * \brief SLOT onStepChange
355 //================================================================================
357 void GridAxisTab::onStepChange()
359 if ( fabs( myStepSpin->GetValue() ) < 1e-100 )
361 double delta = myStepSpin->singleStep() * ( myStep > myStepSpin->GetValue() ? -1 : +1 );
362 myStepSpin->SetValue( myStepSpin->GetValue() + delta );
364 myStep = myStepSpin->GetValue();
367 //================================================================================
369 * \brief Enables/disables buttons
371 //================================================================================
373 void GridAxisTab::updateButtons()
375 bool insertEnable = false, deleteEnable = false;
376 if ( isGridBySpacing() )
379 const int nbSelected = mySpacingTreeWdg->selectedItems().count();
380 if ( nbSelected > 0 )
382 // we delete a current range by uniting it with the previous
383 int i = mySpacingTreeWdg->indexOfTopLevelItem( mySpacingTreeWdg->currentItem() );
384 deleteEnable = ( i > 0 );
389 const int nbSelected = myCoordList->selectedItems().count();
390 insertEnable = ( nbSelected || myCoordList->count() < 2 );
391 deleteEnable = ( nbSelected && myCoordList->count() > 2 );
393 myInsertBtn->setEnabled( insertEnable );
394 myDeleteBtn->setEnabled( deleteEnable );
397 //================================================================================
399 * \brief Inserts coordinates into myCoordList
401 //================================================================================
403 void GridAxisTab::setCoordinates( SMESH::double_array_var coords )
405 myCoordList->clear();
406 for ( size_t i = 0; i < coords->length(); ++i )
407 myCoordList->addItem( coordToItem( coords[i] ));
409 myModeGroup->button( COORD_BUT )->setChecked( true );
413 //================================================================================
415 * \brief Sets spacing got from hypothesis
417 //================================================================================
419 void GridAxisTab::setSpacing( SMESH::string_array_var funs, SMESH::double_array_var points )
421 mySpacingTreeWdg->clear();
422 if ( funs->length() == points->length() - 1 )
424 for ( size_t i = 1; i < points->length(); ++i )
425 mySpacingTreeWdg->addTopLevelItem
426 ( setToItem( points[i-1], points[i], (const char*) funs[i-1] ));
428 myModeGroup->button( SPACING_BUT )->setChecked( true );
429 onMode( SPACING_BUT );
432 //================================================================================
434 * \brief Checks grid definintion mode
436 //================================================================================
438 bool GridAxisTab::isGridBySpacing() const
440 return ( myModeGroup->checkedId() == SPACING_BUT );
443 //================================================================================
445 * \brief Returns coordinates to set to a hypothesis
447 //================================================================================
449 SMESH::double_array* GridAxisTab::getCoordinates()
451 SMESH::double_array_var coords = new SMESH::double_array;
452 coords->length( myCoordList->count() );
453 for ( size_t i = 0; i < coords->length(); ++i )
454 coords[i] = coordFromItem( myCoordList->item( i ) );
456 return coords._retn();
459 //================================================================================
461 * \brief Returms spacing to set to a hypothesis
463 //================================================================================
465 void GridAxisTab::getSpacing(SMESH::string_array_out funs,
466 SMESH::double_array_out points) const
468 funs = new SMESH::string_array();
469 points = new SMESH::double_array();
470 funs->length( mySpacingTreeWdg->topLevelItemCount() );
471 points->length( mySpacingTreeWdg->topLevelItemCount() + 1 );
472 double t0, t1; QString fun;
473 for ( size_t i = 0; i < funs->length(); ++i )
475 QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( i );
476 getFromItem( item, t0, t1, fun );
478 funs[i] = fun.toLatin1().constData();
480 points[ points->length()-1 ] = 1.0;
484 //================================================================================
486 * \brief Verifies parameters
488 //================================================================================
490 bool GridAxisTab::checkParams(QString& msg, SMESH::SMESH_Hypothesis_var& hyp) const
492 if ( isGridBySpacing() )
494 if ( mySpacingTreeWdg->topLevelItemCount() == 0 )
495 return false; // how could it be?
496 StdMeshers::StdMeshers_CartesianParameters3D_var h =
497 StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hyp );
498 SMESH::string_array_var funs;
499 SMESH::double_array_var points;
500 getSpacing( funs.out(), points.out() );
502 const char* axisName[3] = { "X", "Y", "Z" };
503 SMESH::double_array_var coords =
504 h->ComputeCoordinates(0.,1., funs, points, axisName[ myAxisIndex ]);
506 catch ( const SALOME::SALOME_Exception& ex ) {
507 msg = (const char*) ex.details.text;
513 return myCoordList->count() > 1;
518 //================================================================================
520 * \brief LineDelegate constructor
522 //================================================================================
524 LineDelegate::LineDelegate( QWidget* parent ):
525 QItemDelegate( parent ),
526 mySpacingTreeWdg( qobject_cast<QTreeWidget*>( parent )),
527 myCoordList( qobject_cast<QListWidget*>( parent ))
531 //================================================================================
533 * \brief Creates an editor depending on a current item
535 //================================================================================
537 QWidget* LineDelegate::createEditor( QWidget* parent,
538 const QStyleOptionViewItem& opt,
539 const QModelIndex& index) const
542 if ( mySpacingTreeWdg )
544 if ( index.column() == 0 &&
545 index.row() != mySpacingTreeWdg->topLevelItemCount()-1 )
547 SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent );
548 sb->setAcceptNames( false ); // No Notebook variables allowed
549 sb->setFrame( false );
552 if ( index.column() == 1 ) {
553 w = new QLineEdit( parent );
558 SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent );
559 sb->setAcceptNames( false ); // No Notebook variables allowed
560 sb->setFrame( false );
561 const double tol = 1e-5;
562 double from = index.row() ? coordFromItem( myCoordList->item( index.row()-1 ))+tol : -1e+6;
563 double to = index.row() == myCoordList->count()-1 ? 1e+6 : coordFromItem( myCoordList->item( index.row()+1 ))-tol;
564 sb->RangeStepAndValidator( from, to, 0.01 );
570 //================================================================================
572 * \brief Limit value range in the spin of a neighbor range
574 //================================================================================
576 void LineDelegate::setEditorData ( QWidget * editor, const QModelIndex & index ) const
578 if ( mySpacingTreeWdg && index.column() == 0 )
580 double t0, t1, t2=1.0; QString fun;
581 QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( index.row() );
582 getFromItem( item, t0, t1, fun );
583 if ( index.row() != mySpacingTreeWdg->topLevelItemCount()-1 )
585 item = mySpacingTreeWdg->topLevelItem( index.row()+1 );
586 getFromItem( item, t1, t2, fun );
588 const double tol = 1e-3;
589 SMESHGUI_SpinBox* sb = qobject_cast<SMESHGUI_SpinBox*>( editor );
590 sb->RangeStepAndValidator( t0 + tol, t2 - tol, 0.01 );
595 QItemDelegate::setEditorData( editor, index );
599 //================================================================================
603 //================================================================================
605 void LineDelegate::setModelData( QWidget* editor,
606 QAbstractItemModel* model,
607 const QModelIndex& index ) const
609 if ( mySpacingTreeWdg )
611 if ( index.column() == 0 )
613 if ( index.row() != mySpacingTreeWdg->topLevelItemCount()-1 )
615 SMESHGUI_SpinBox* sb = qobject_cast<SMESHGUI_SpinBox*>( editor );
616 double t0, t1, t = sb->GetValue(); QString fun;
618 QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( index.row() );
619 getFromItem( item, t0, t1, fun );
620 setToItem( t0, t, fun, item );
622 item = mySpacingTreeWdg->topLevelItem( index.row() + 1 );
623 getFromItem( item, t0, t1, fun );
624 setToItem( t, t1, fun, item );
627 else if ( !qobject_cast<QLineEdit*>(editor)->text().trimmed().isEmpty() )
629 QItemDelegate::setModelData( editor, model, index );
634 SMESHGUI_SpinBox* sb = qobject_cast<SMESHGUI_SpinBox*>( editor );
635 coordToItem( sb->GetValue(), myCoordList->item( index.row() ));
639 } // namespace StdMeshersGUI
643 const double theAngTol = M_PI / 180.;
645 //================================================================================
647 * \brief Set variables to groups of spin boxes
649 //================================================================================
651 void setText( const QString& vars, SMESHGUI_SpinBox** spins )
653 QStringList varList = vars.split( ':' );
654 for ( int i = 0; i < 3 && i < varList.count(); ++i )
655 if ( !varList[i].isEmpty() )
656 spins[i]->setText( varList[i] );
659 //================================================================================
661 * \brief Computes more 2 axes by one
662 * \param [in] iOk - index of a given axis
663 * \param [in,out] dirs - directions of 3 axes
665 //================================================================================
667 void get3Dirs( int iOk, gp_XYZ dirs[3] )
669 dirs[ ( iOk+1 ) % 3 ] = dirs[ iOk ];
671 if ( Abs( dirs[ iOk ].Y() ) < 1e-100 &&
672 Abs( dirs[ iOk ].Z() ) < 1e-100 )
674 dirs[ ( iOk+1 ) % 3 ].SetY( dirs[ iOk ].Y() + 1. );
676 dirs[ ( iOk+1 ) % 3 ].SetX( dirs[ iOk ].X() + 1. );
678 dirs[( iOk+2 ) % 3] = dirs[ iOk ] ^ dirs[ ( iOk+1 ) % 3 ];
679 dirs[( iOk+1 ) % 3] = dirs[ ( iOk+2 ) % 3 ] ^ dirs[ iOk ];
682 //================================================================================
684 * \brief Returns a minimal width of a SpinBox depending on a precision type
686 //================================================================================
688 int getMinWidth( const char* precisionType )
690 int nb = SMESHGUI::resourceMgr()->integerValue( "SMESH", precisionType, -3 );
692 s.fill('0', qAbs(nb)+7 );
694 QFontMetrics metrics( le.font() );
695 return metrics.width( s );
699 //================================================================================
701 * \brief StdMeshersGUI_CartesianParamCreator constructor
703 //================================================================================
705 StdMeshersGUI_CartesianParamCreator::StdMeshersGUI_CartesianParamCreator(const QString& aHypType)
706 : StdMeshersGUI_StdHypothesisCreator( aHypType ),
713 myAxesPreview = new SMESHGUI_MeshEditPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ));
714 myAxesPreview->SetArrowShapeAndNb( /*nbArrows=*/3,
720 myDirTic[0] = myDirTic[1] = myDirTic[2] = 0;
723 //================================================================================
725 * \brief StdMeshersGUI_CartesianParamCreator destructor
727 //================================================================================
729 StdMeshersGUI_CartesianParamCreator::~StdMeshersGUI_CartesianParamCreator()
731 if ( myAxisTabs[0] ) delete myAxisTabs[0];
732 if ( myAxisTabs[1] ) delete myAxisTabs[1];
733 if ( myAxisTabs[2] ) delete myAxisTabs[2];
738 delete myAxesPreview;
741 //================================================================================
743 * \brief Validate parameters
745 //================================================================================
747 bool StdMeshersGUI_CartesianParamCreator::checkParams( QString& msg ) const
749 if( !SMESHGUI_GenericHypothesisCreator::checkParams( msg ) )
752 if ( myName && myName->text().trimmed().isEmpty() )
754 msg = tr("SMESH_WRN_EMPTY_NAME");
757 if ( ! myThreshold->isValid( msg, true ))
760 SMESH::SMESH_Hypothesis_var hyp = hypothesis();
761 if ( !myAxisTabs[0]->checkParams( msg, hyp )) return false;
762 if ( !myAxisTabs[1]->checkParams( msg, hyp )) return false;
763 if ( !myAxisTabs[2]->checkParams( msg, hyp )) return false;
765 StdMeshersGUI_CartesianParamCreator* me = (StdMeshersGUI_CartesianParamCreator*) this;
766 if ( !me->updateAxesPreview() )
768 msg = tr("INVALID_AXES_DIR");
775 //================================================================================
777 * \brief Create widgets
779 //================================================================================
781 QFrame* StdMeshersGUI_CartesianParamCreator::buildFrame()
783 QFrame* fr = new QFrame();
784 //fr->setMinimumWidth(460);
786 QVBoxLayout* lay = new QVBoxLayout( fr );
788 lay->setSpacing( SPACING );
790 QGroupBox* GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), fr );
791 lay->addWidget( GroupC1 );
793 StdMeshers::StdMeshers_NumberOfSegments_var h =
794 StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
796 QGridLayout* argGroupLayout = new QGridLayout( GroupC1 );
797 argGroupLayout->setSpacing( SPACING );
798 argGroupLayout->setMargin( MARGIN );
799 argGroupLayout->setColumnStretch( 0, 0 );
800 argGroupLayout->setColumnStretch( 1, 1 );
807 myName = new QLineEdit( GroupC1 );
808 argGroupLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), GroupC1 ), row, 0 );
809 argGroupLayout->addWidget( myName, row, 1 );
814 argGroupLayout->addWidget( new QLabel( tr( "THRESHOLD" ), GroupC1 ), row, 0 );
815 myThreshold = new SMESHGUI_SpinBox( GroupC1 );
816 myThreshold->setAcceptNames( false ); // No Notebook variables allowed
817 myThreshold->RangeStepAndValidator( 1.00001, 1e+10, 1., "length_precision" );
818 argGroupLayout->addWidget( myThreshold, row, 1 );
821 // 2) "Implement edges"
822 myAddEdges = new QCheckBox( tr("ADD_EDGES"), GroupC1 );
823 argGroupLayout->addWidget( myAddEdges, row, 0, 1, 2 );
826 // 3) Grid definition
827 QTabWidget* tabWdg = new QTabWidget( fr );
828 myAxisTabs[ 0 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 0 );
829 myAxisTabs[ 1 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 1 );
830 myAxisTabs[ 2 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 2 );
831 tabWdg->addTab( myAxisTabs[ 0 ], tr( "AXIS_X" ) );
832 tabWdg->addTab( myAxisTabs[ 1 ], tr( "AXIS_Y" ) );
833 tabWdg->addTab( myAxisTabs[ 2 ], tr( "AXIS_Z" ) );
834 argGroupLayout->addWidget( tabWdg, row, 0, 1, 2 );
837 QPixmap aPix = SMESHGUI::resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT"));
840 myFixedPointGrp = new QGroupBox( tr("FIXED_POINT"), fr );
841 myFixedPointGrp->setCheckable( true );
842 //QPushButton* pointBtn = new QPushButton( QIcon(aPix), "", myFixedPointGrp );
843 QLabel* pXLbl = new QLabel( tr("SMESH_X"), myFixedPointGrp );
844 QLabel* pYLbl = new QLabel( tr("SMESH_Y"), myFixedPointGrp );
845 QLabel* pZLbl = new QLabel( tr("SMESH_Z"), myFixedPointGrp );
846 for ( int i = 0; i < 3; ++i )
848 myPointSpin[i] = new SMESHGUI_SpinBox( myFixedPointGrp );
849 myPointSpin[i]->RangeStepAndValidator( -1e20, 1e20, 10 );
850 myPointSpin[i]->SetValue( 0. );
852 QHBoxLayout* aFixedPointLay = new QHBoxLayout( myFixedPointGrp );
853 aFixedPointLay->addWidget( pXLbl, 0, Qt::AlignRight );
854 aFixedPointLay->addWidget( myPointSpin[0], 1 );
855 aFixedPointLay->addWidget( pYLbl, 0, Qt::AlignRight );
856 aFixedPointLay->addWidget( myPointSpin[1], 1 );
857 aFixedPointLay->addWidget( pZLbl, 0, Qt::AlignRight );
858 aFixedPointLay->addWidget( myPointSpin[2], 1 );
859 argGroupLayout->addWidget( myFixedPointGrp, row, 0, 1, 2 );
863 QGroupBox* axesDirGrp = new QGroupBox( tr("AXES_DIRECTION"), fr );
864 QGridLayout* axisDirLay = new QGridLayout( axesDirGrp );
865 axisDirLay->setSpacing( SPACING );
866 axisDirLay->setMargin( MARGIN );
867 axisDirLay->setColumnStretch( 0, 2 );
869 myOrthogonalChk = new QCheckBox( tr("ORTHOGONAL_AXES"), axesDirGrp );
870 axisDirLay->addWidget( myOrthogonalChk, 0, 0, 1, 7 );
873 axisLbl[0] = new QLabel( tr( "AXIS_X"), axesDirGrp );
874 axisLbl[1] = new QLabel( tr( "AXIS_Y"), axesDirGrp );
875 axisLbl[2] = new QLabel( tr( "AXIS_Z"), axesDirGrp );
877 myAxisBtnGrp = new QButtonGroup( axesDirGrp );
879 const char * const precisionType = "len_tol_precision";
880 int minWidth = getMinWidth( precisionType );
881 for ( int i = 0; i < 3; ++i )
883 QPushButton* axisBtn = new QPushButton( QIcon(aPix), "", axesDirGrp );
884 axisBtn->setCheckable( true );
885 myAxisBtnGrp->addButton( axisBtn, i );
886 myXDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
887 myYDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
888 myZDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
889 myXDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, precisionType );
890 myYDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, precisionType );
891 myZDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, precisionType );
892 myXDirSpin[i]->setMinimumWidth( minWidth );
893 myYDirSpin[i]->setMinimumWidth( minWidth );
894 myZDirSpin[i]->setMinimumWidth( minWidth );
895 dLbl[0] = new QLabel( tr("SMESH_DX"), axesDirGrp );
896 dLbl[1] = new QLabel( tr("SMESH_DY"), axesDirGrp );
897 dLbl[2] = new QLabel( tr("SMESH_DZ"), axesDirGrp );
898 axisDirLay->addWidget( axisLbl[i], i+1, 0 );
899 axisDirLay->addWidget( axisBtn, i+1, 1 );
900 axisDirLay->addWidget( dLbl[0], i+1, 2 );
901 axisDirLay->addWidget( dLbl[1], i+1, 4 );
902 axisDirLay->addWidget( dLbl[2], i+1, 6 );
903 axisDirLay->addWidget( myXDirSpin[i], 1, 3+i*2 );
904 axisDirLay->addWidget( myYDirSpin[i], 2, 3+i*2 );
905 axisDirLay->addWidget( myZDirSpin[i], 3, 3+i*2 );
907 axisDirLay->setColumnStretch( 3, 10 );
908 axisDirLay->setColumnStretch( 5, 10 );
909 axisDirLay->setColumnStretch( 7, 10 );
912 QPushButton* optimBtn = new QPushButton( tr("OPTIMAL_AXES"), axesDirGrp );
913 QPushButton* resetBtn = new QPushButton( tr("RESET_AXES"), axesDirGrp );
914 axisDirLay->addWidget( optimBtn, 4, 0, 1, 4 );
915 axisDirLay->addWidget( resetBtn, 4, 4, 1, 4 );
917 argGroupLayout->addWidget( axesDirGrp, row, 0, 1, 2 );
922 LightApp_SelectionMgr* selMgr = SMESH::GetSelectionMgr( SMESHGUI::GetSMESHGUI() );
924 connect( selMgr, SIGNAL( currentSelectionChanged()), SLOT( onSelectionChange()));
925 connect( myOrthogonalChk, SIGNAL( toggled(bool)), SLOT( onOrthogonalAxes(bool)));
926 connect( optimBtn, SIGNAL( clicked(bool)), SLOT( onOptimalAxes(bool)));
927 connect( resetBtn, SIGNAL( clicked(bool)), SLOT( onResetAxes(bool)));
928 for ( int i = 0; i < 3; ++i )
930 connect( myXDirSpin[i], SIGNAL(valueChanged (const QString&)),
931 this, SLOT (onAxisDirChange(const QString&)) );
932 connect( myYDirSpin[i], SIGNAL(valueChanged (const QString&)),
933 this, SLOT (onAxisDirChange(const QString&)) );
934 connect( myZDirSpin[i], SIGNAL(valueChanged (const QString&)),
935 this, SLOT (onAxisDirChange(const QString&)) );
936 connect( myAxisTabs[i], SIGNAL(gridModeChanged(int)),
937 this, SLOT (onGridModeChanged(int)));
941 myAxesLen = 120; // default trihedron size is 100
942 myOrigin[0] = myOrigin[1] = myOrigin[2] = 0.;
944 QString shapeEntry = getMainShapeEntry();
945 if ( !shapeEntry.isEmpty() )
948 Handle(SALOME_InteractiveObject) io =
949 new SALOME_InteractiveObject( shapeEntry.toStdString().c_str(), "GEOM" );
950 GEOM::GEOM_Object_var geomObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>( io );
951 if ( GEOMBase::GetShape( geomObj, shape ) && !shape.IsNull())
954 BRepBndLib::Add( shape, box );
958 box.Get( myOrigin[0], myOrigin[1], myOrigin[2], max[0], max[1], max[2] );
959 gp_Pnt o( myOrigin[0], myOrigin[1], myOrigin[2] );
960 gp_Pnt x( max[0], max[1], max[2] );
961 myAxesLen = o.Distance( x );
964 while ( step > myAxesLen / 5 )
966 myPointSpin[0]->SetStep( step );
967 myPointSpin[1]->SetStep( step );
968 myPointSpin[2]->SetStep( step );
972 myAxisBtnGrp->button(0)->setEnabled( !shape.IsNull() );
973 myAxisBtnGrp->button(1)->setEnabled( !shape.IsNull() );
974 myAxisBtnGrp->button(2)->setEnabled( !shape.IsNull() );
975 optimBtn->setEnabled( !shape.IsNull() );
982 //================================================================================
984 * \brief Tranfer parameters from hypothesis to widgets
986 //================================================================================
988 void StdMeshersGUI_CartesianParamCreator::retrieveParams() const
990 StdMeshers::StdMeshers_CartesianParameters3D_var h =
991 StdMeshers::StdMeshers_CartesianParameters3D::_narrow( initParamsHypothesis() );
994 myName->setText( hypName() );
996 QString varName = getVariableName( "SetSizeThreshold" );
997 if ( varName.isEmpty() )
998 myThreshold->setValue( h->GetSizeThreshold() );
1000 myThreshold->setText( varName );
1002 myAddEdges->setChecked( h->GetToAddEdges() );
1005 for ( int ax = 0; ax < 3; ++ax )
1007 if ( h->IsGridBySpacing( ax ))
1009 SMESH::string_array_var funs;
1010 SMESH::double_array_var intPoints;
1011 h->GetGridSpacing( funs.out(), intPoints.out(), ax );
1012 myAxisTabs[ax]->setSpacing( funs, intPoints );
1016 SMESH::double_array_var coords = h->GetGrid( ax );
1017 myAxisTabs[ax]->setCoordinates( coords );
1022 SMESH::PointStruct fp;
1023 StdMeshersGUI_CartesianParamCreator* me = (StdMeshersGUI_CartesianParamCreator*) this;
1024 if ( h->GetFixedPoint( fp ))
1026 me->myPointSpin[0]->SetValue( fp.x );
1027 me->myPointSpin[1]->SetValue( fp.y );
1028 me->myPointSpin[2]->SetValue( fp.z );
1029 setText( getVariableName("GetFixedPoint"), &me->myPointSpin[0] );
1030 myFixedPointGrp->setChecked( true );
1034 myFixedPointGrp->setChecked( false );
1038 SMESHGUI_SpinBox** spins[3] = { &me->myXDirSpin[0], &me->myYDirSpin[0], &me->myZDirSpin[0] };
1039 SMESH::DirStruct axisDir[3];
1040 h->GetAxesDirs( axisDir[0],
1043 QString vars = getVariableName("GetAxesDirs");
1044 for ( int i = 0; i < 3; ++i )
1046 spins[i][0]->SetValue( axisDir[i].PS.x );
1047 spins[i][1]->SetValue( axisDir[i].PS.y );
1048 spins[i][2]->SetValue( axisDir[i].PS.z );
1049 setText( vars, spins[i] );
1051 // cut off 3 used vars
1052 if ( !vars.isEmpty() )
1055 for ( int j = 0; j < 3; ++j )
1056 if (( ind = vars.indexOf(':', ind+1 )) < 0 )
1061 vars.remove( 0, ind+1 );
1066 dlg()->setMinimumSize( dlg()->minimumSizeHint().width(),
1067 dlg()->minimumSizeHint().height() );
1070 //================================================================================
1072 * \brief Tranfer parameters from widgets to hypothesis
1074 //================================================================================
1076 QString StdMeshersGUI_CartesianParamCreator::storeParams() const
1078 StdMeshers::StdMeshers_CartesianParameters3D_var h =
1079 StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hypothesis() );
1084 SMESH::SetName( SMESH::FindSObject( h ), myName->text().toLatin1().constData() );
1087 h->SetVarParameter( myThreshold->text().toLatin1().constData(), "SetSizeThreshold" );
1088 h->SetSizeThreshold( myThreshold->text().toDouble() );
1089 h->SetToAddEdges( myAddEdges->isChecked() );
1092 for ( int ax = 0; ax < 3; ++ax )
1094 if ( myAxisTabs[ax]->isGridBySpacing())
1096 SMESH::double_array_var intPoints;
1097 SMESH::string_array_var funs;
1098 myAxisTabs[ax]->getSpacing( funs.out(), intPoints.out() );
1099 h->SetGridSpacing( funs, intPoints, ax );
1103 SMESH::double_array_var coords = myAxisTabs[ax]->getCoordinates();
1104 h->SetGrid( coords, ax );
1110 params << myPointSpin[0]->text();
1111 params << myPointSpin[1]->text();
1112 params << myPointSpin[2]->text();
1113 h->SetVarParameter( params.join(":").toLatin1().constData(), "SetFixedPoint" );
1116 SMESH::PointStruct ps;
1117 ps.x = myPointSpin[0]->GetValue();
1118 ps.y = myPointSpin[1]->GetValue();
1119 ps.z = myPointSpin[2]->GetValue();
1120 h->SetFixedPoint( ps, !myFixedPointGrp->isEnabled() || !myFixedPointGrp->isChecked() );
1123 SMESHGUI_SpinBox* const * spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1124 for ( int ax = 0; ax < 3; ++ax )
1126 params << spins[ax][0]->text();
1127 params << spins[ax][1]->text();
1128 params << spins[ax][2]->text();
1130 h->SetVarParameter( params.join(":").toLatin1().constData(), "SetAxesDirs" );
1132 SMESH::DirStruct axDir[3];
1133 for ( int ax = 0; ax < 3; ++ax )
1135 axDir[ax].PS.x = spins[ax][0]->GetValue();
1136 axDir[ax].PS.y = spins[ax][1]->GetValue();
1137 axDir[ax].PS.z = spins[ax][2]->GetValue();
1139 h->SetAxesDirs( axDir[0], axDir[1], axDir[2] );
1142 catch(const SALOME::SALOME_Exception& ex)
1144 SalomeApp_Tools::QtCatchCorbaException(ex);
1149 //================================================================================
1151 * \brief Returns a name of help page
1153 //================================================================================
1155 QString StdMeshersGUI_CartesianParamCreator::helpPage() const
1157 return "cartesian_algo_page.html#cartesian_hyp_anchor";
1160 //================================================================================
1162 * \brief Show axes if they are OK
1164 //================================================================================
1166 bool StdMeshersGUI_CartesianParamCreator::updateAxesPreview()
1170 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1171 for ( int i = 0; i < 3 && isOk; ++i )
1173 gp_XYZ dir( spins[i][0]->GetValue(),
1174 spins[i][1]->GetValue(),
1175 spins[i][2]->GetValue());
1176 if (( isOk = ( dir.Modulus() > 1e-100 )))
1177 axes[i].SetDirection( gp_Dir( dir ));
1179 axes[i].SetLocation ( gp_Pnt( myOrigin[0],
1183 gp_Vec norm01 = axes[0].Direction().XYZ() ^ axes[1].Direction().XYZ();
1184 gp_Vec norm12 = axes[1].Direction().XYZ() ^ axes[2].Direction().XYZ();
1186 isOk = ( !axes[0].Direction().IsParallel( axes[1].Direction(), theAngTol ) &&
1187 !axes[1].Direction().IsParallel( axes[2].Direction(), theAngTol ) &&
1188 !axes[2].Direction().IsParallel( axes[0].Direction(), theAngTol ) &&
1189 !norm01.IsParallel( norm12, theAngTol ) );
1191 myAxesPreview->SetArrows( axes, myAxesLen );
1193 myAxesPreview->SetVisibility( isOk );
1198 //================================================================================
1200 * \brief Makes axes orthogonal if necessary
1202 //================================================================================
1204 void StdMeshersGUI_CartesianParamCreator::onOrthogonalAxes(bool isOrtho)
1208 updateAxesPreview();
1212 std::multimap< int, int > ageOfAxis;
1214 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1216 for ( int iAx = 0; iAx < 3; ++iAx )
1218 dirs[iAx].SetCoord( spins[iAx][0]->GetValue(),
1219 spins[iAx][1]->GetValue(),
1220 spins[iAx][2]->GetValue());
1221 if (( isOk = ( dirs[iAx].Modulus() > 1e-100 )))
1222 ageOfAxis.insert( std::make_pair( myDirTic[iAx], iAx ));
1224 ageOfAxis.insert( std::make_pair( -1, iAx ));
1231 dirs[0].SetCoord( 1, 0, 0 );
1232 dirs[1].SetCoord( 0, 1, 0 );
1233 dirs[2].SetCoord( 0, 0, 1 );
1238 int iOk = ageOfAxis.rbegin()->second;
1239 get3Dirs( iOk, dirs );
1243 std::multimap< int, int >::reverse_iterator ag2ax = ageOfAxis.rbegin();
1244 int iOk1 = ag2ax->second;
1245 int iOk2 = (++ag2ax)->second;
1246 int iKo = (++ag2ax)->second;
1247 if ( gp_Vec( dirs[ iOk1 ]).IsParallel( gp_Vec( dirs[ iOk2 ]), theAngTol ))
1248 std::swap( iOk2, iKo );
1249 if ( gp_Vec( dirs[ iOk1 ]).IsParallel( gp_Vec( dirs[ iOk2 ]), theAngTol ))
1251 get3Dirs( iOk1, dirs );
1255 dirs[ iKo ] = dirs[ iOk1 ] ^ dirs[ iOk2 ];
1256 dirs[ iOk2 ] = dirs[ iKo ] ^ dirs[ iOk1 ];
1257 if ( ( iOk1+1 ) % 3 != iOk2 )
1258 dirs[ iKo ].Reverse();
1262 for ( int iAx = 0; iAx < 3; ++iAx )
1264 double size = dirs[iAx].Modulus();
1265 if ( size > 1e-100 )
1267 for (int i = 0; i < 3; ++i )
1269 bool isBlocked = spins[iAx][i]->blockSignals( true );
1270 spins[iAx][i]->SetValue( dirs[iAx].Coord( i+1 ));
1271 spins[iAx][i]->blockSignals( isBlocked );
1275 updateAxesPreview();
1278 //================================================================================
1280 * \brief Increment myDirTic and update the preview of axes
1282 //================================================================================
1284 void StdMeshersGUI_CartesianParamCreator::onAxisDirChange(const QString&)
1286 QObject* changedSpin = sender();
1287 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1288 for ( int iAx = 0; iAx < 3; ++iAx )
1289 if ( spins[iAx][0] == changedSpin ||
1290 spins[iAx][1] == changedSpin ||
1291 spins[iAx][2] == changedSpin )
1293 myDirTic[ iAx ] = 1 + Max( Max( myDirTic[0], myDirTic[1] ), myDirTic[2] );
1297 onOrthogonalAxes( myOrthogonalChk->isChecked() );
1300 //================================================================================
1302 * \brief Sets axis direction by a selected EDGE
1304 //================================================================================
1306 void StdMeshersGUI_CartesianParamCreator::onSelectionChange()
1308 int iAxis = myAxisBtnGrp->checkedId();
1312 SALOME_ListIO aList;
1313 SMESHGUI::GetSMESHGUI()->selectionMgr()->selectedObjects(aList);
1315 TopoDS_Shape edge, shape;
1316 for( SALOME_ListIteratorOfListIO anIt( aList ); anIt.More(); anIt.Next() )
1318 GEOM::GEOM_Object_var go = SMESH::IObjectToInterface<GEOM::GEOM_Object>( anIt.Value() );
1319 if ( GEOMBase::GetShape( go, shape ) && shape.ShapeType() == TopAbs_EDGE )
1321 if ( !edge.IsNull() )
1322 return; // several EDGEs selected
1326 if ( edge.IsNull() )
1330 TopoDS_Iterator vIt( edge );
1331 for ( ; vIt.More() && vv[1].IsNull(); vIt.Next() )
1332 vv[ !vv[0].IsNull() ] = vIt.Value();
1335 if ( !GEOMBase::VertexToPoint( vv[0], pp[0] ) ||
1336 !GEOMBase::VertexToPoint( vv[1], pp[1] ))
1339 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1341 gp_Vec newDir( pp[0], pp[1] );
1342 gp_Vec curDir( spins[iAxis][0]->GetValue(),
1343 spins[iAxis][1]->GetValue(),
1344 spins[iAxis][2]->GetValue());
1345 if ( newDir * curDir < 0 )
1348 double size = newDir.Magnitude();
1349 if ( size < 1e-100 )
1353 for (int i = 0; i < 3; ++i )
1355 bool isBlocked = spins[iAxis][i]->blockSignals( true );
1356 spins[iAxis][i]->SetValue( newDir.Coord( i+1 ));
1357 spins[iAxis][i]->blockSignals( isBlocked );
1359 myDirTic[ iAxis ] = 1 + Max( Max( myDirTic[0], myDirTic[1] ), myDirTic[2] );
1361 onOrthogonalAxes( myOrthogonalChk->isChecked() );
1364 //================================================================================
1366 * \brief Sets axes at which number of hexahedra is maximal
1368 //================================================================================
1370 void StdMeshersGUI_CartesianParamCreator::onOptimalAxes(bool)
1372 StdMeshers::StdMeshers_CartesianParameters3D_var h =
1373 StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hypothesis() );
1377 QString shapeEntry = getMainShapeEntry();
1378 if ( shapeEntry.isEmpty() )
1381 Handle(SALOME_InteractiveObject) io =
1382 new SALOME_InteractiveObject( shapeEntry.toStdString().c_str(), "GEOM" );
1383 GEOM::GEOM_Object_var geomObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>( io );
1384 if ( geomObj->_is_nil() )
1387 SMESH::DirStruct axDirs[3];
1388 h->ComputeOptimalAxesDirs( geomObj,
1389 myOrthogonalChk->isChecked(),
1394 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1395 for ( int iAx = 0; iAx < 3; ++iAx )
1397 double coords[3] = { axDirs[iAx].PS.x, axDirs[iAx].PS.y, axDirs[iAx].PS.z };
1398 for (int i = 0; i < 3; ++i )
1400 bool isBlocked = spins[iAx][i]->blockSignals( true );
1401 spins[iAx][i]->SetValue( coords[ i ]);
1402 spins[iAx][i]->blockSignals( isBlocked );
1405 updateAxesPreview();
1408 //================================================================================
1410 * \brief Sets axes || to the axes of global CS
1412 //================================================================================
1414 void StdMeshersGUI_CartesianParamCreator::onResetAxes(bool)
1416 SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
1417 for ( int iAx = 0; iAx < 3; ++iAx )
1419 for (int i = 0; i < 3; ++i )
1421 bool isBlocked = spins[iAx][i]->blockSignals( true );
1422 spins[iAx][i]->SetValue( iAx == i ? 1. : 0. );
1423 spins[iAx][i]->blockSignals( isBlocked );
1427 updateAxesPreview();
1430 //================================================================================
1432 * \brief SLOT called when the grid definintion mode changes
1434 //================================================================================
1436 void StdMeshersGUI_CartesianParamCreator::onGridModeChanged(int)
1438 bool haveSpacing = ( myAxisTabs[0]->isGridBySpacing() ||
1439 myAxisTabs[1]->isGridBySpacing() ||
1440 myAxisTabs[2]->isGridBySpacing() );
1442 myFixedPointGrp->setEnabled( haveSpacing );